From 4b6f782e219719303dc454d56a9ee7c490b782d8 Mon Sep 17 00:00:00 2001 From: Hipposgrumm <60556345+Hipposgrumm@users.noreply.github.com> Date: Sun, 29 Dec 2024 09:00:21 -0700 Subject: [PATCH] Eat My Dust support (#12) DB MODEL CHANGES! I don't know how to deal with those. Support for EMD's MMO rooms and API token. Groundwork for group/clan system (hence schema changes). Only functional for EMD right now (if I implemented it correctly). * Removed debug logged messages. * Update comments in GroupController.cs * Fixed position of parenthesis in ConfigurationController.cs * Noted changes in README * Amendment to previous commit, these are supposed to be alphabetical. * Changed unnecessary extra check for EMD ClientVersion. --- README.md | 2 + src/Controllers/Common/GroupController.cs | 104 ++++++++++++++++++++ src/Controllers/Common/ProfileController.cs | 19 +++- src/Model/DBContext.cs | 8 ++ src/Model/Group.cs | 25 +++++ src/Model/Viking.cs | 1 + src/Resources/mmo.xml | 9 +- src/Schema/Group.cs | 52 ++++++++++ src/Schema/GroupMembershipStatus.cs | 18 ++++ src/Schema/GroupType.cs | 20 ++++ src/Schema/JoinGroupResult.cs | 9 ++ src/Util/ClientVersion.cs | 4 + 12 files changed, 269 insertions(+), 2 deletions(-) create mode 100644 src/Controllers/Common/GroupController.cs create mode 100644 src/Model/Group.cs create mode 100644 src/Schema/Group.cs create mode 100644 src/Schema/GroupMembershipStatus.cs create mode 100644 src/Schema/GroupType.cs create mode 100644 src/Schema/JoinGroupResult.cs diff --git a/README.md b/README.md index 8515af4..68b092f 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,7 @@ Almost everything: #### Implemented enough (probably) - GetCommonInventory (V1 - returns the viking's inventory if it is called with a viking; otherwise returns 8 viking slots) +- GetGroupsByGroupType (only useful for Eat My Dust at the moment) - GetQuestions (doesn't return all questions, probably doesn't need to) - GetRules (doesn't return any rules, probably doesn't need to) - GetSubscriptionInfo (always returns member, with end date 10 years from now) @@ -168,6 +169,7 @@ Almost everything: - GetTopAchievementPointUsers (ignores type [all, buddy, hall of fame, ...] and mode [overall, monthly, weekly] properties) - GetUserAchievements (used by Magic & Mythies) - GetUserRoomList (room categories are not implemented, but it's enough for SoD) +- JoinGroup (for Eat My Dust only) - ProcessRewardedItems (gives gems, but doesn't give gold, gold is not yet implemented) - SellItems (gives gems, but doesn't give gold, gold is not yet implemented) - SetUserAchievementTask (returns a real reward but still use task placeholder) diff --git a/src/Controllers/Common/GroupController.cs b/src/Controllers/Common/GroupController.cs new file mode 100644 index 0000000..8ee0d9c --- /dev/null +++ b/src/Controllers/Common/GroupController.cs @@ -0,0 +1,104 @@ +using Microsoft.AspNetCore.Mvc; +using sodoff.Attributes; +using sodoff.Model; +using sodoff.Schema; +using sodoff.Util; + +namespace sodoff.Controllers.Common; +public class GroupController : Controller { + public static readonly Schema.Group EMD_Dragons = new Schema.Group { + GroupID = "8e68214a-c801-4759-8461-d01f28484134", + Name = "Dragons", + Color = "234,57,23", + Logo = "RS_DATA/Content/PlayerData/EMD/IcoEMDTeamDragons.png" + }; + public static readonly Schema.Group EMD_Scorpions = new Schema.Group { + GroupID = "db0aa225-2f0e-424c-83a7-73783fe63fef", + Name = "Scorpions", + Color = "120,183,53", + Logo = "RS_DATA/Content/PlayerData/EMD/IcoEMDTeamScorpions.png" + }; + + + private readonly DBContext ctx; + + public GroupController(DBContext ctx) { + this.ctx = ctx; + } + + [HttpPost] + [Produces("application/xml")] + [Route("GroupWebService.asmx/JoinGroup")] + [VikingSession] + public IActionResult JoinGroup(Viking viking, [FromForm] string apiKey, [FromForm] string groupID) { + AddEMDGroups(); + uint version = ClientVersion.GetVersion(apiKey); + + // Only implemented for EMD so far. + if (version == ClientVersion.EMD) { + if (viking.Groups.Any(g => { + // Check for loyalty. + string id = g.GroupID.ToString(); + return id == EMD_Dragons.GroupID || id == EMD_Scorpions.GroupID; + })) { + return Ok(new JoinGroupResult { GroupStatus = GroupMembershipStatus.ALREADY_MEMBER }); + } + groupID = groupID.ToUpper(); + Model.Group? group = ctx.Groups.FirstOrDefault(g => g.GroupID.ToString() == groupID); + if (group != null) { + group.Vikings.Add(viking); + ctx.SaveChanges(); + return Ok(new JoinGroupResult { GroupStatus = GroupMembershipStatus.APPROVED }); + } + } + return Ok(new JoinGroupResult { GroupStatus = GroupMembershipStatus.REJECTED }); + } + + [HttpPost] + [Produces("application/xml")] + [Route("GroupWebService.asmx/GetGroupsByGroupType")] + [VikingSession] + public Schema.Group[] GetGroupsByGroupType([FromForm] string apiKey, [FromForm] string groupType) { + AddEMDGroups(); + List groups = new List(); + foreach (Model.Group group in ctx.Groups) { + if (group.ApiKey == apiKey && group.Type.ToString() == groupType) groups.Add(new Schema.Group { + GroupID = group.GroupID.ToString(), + Name = group.Name, + Color = group.Color, + Logo = group.Logo, + Type = group.Type + }); + } + return groups.ToArray(); + } + + private void AddEMDGroups() { + bool changed = false; + Guid DragonString = new Guid(EMD_Dragons.GroupID); + Guid ScorpionString = new Guid(EMD_Scorpions.GroupID); + if (!ctx.Groups.Any(g => g.GroupID == DragonString)) { + ctx.Groups.Add(new Model.Group { + GroupID = DragonString, + Name = EMD_Dragons.Name, + Color = EMD_Dragons.Color, + Logo = EMD_Dragons.Logo, + Type = GroupType.System, + ApiKey = "dd602cf1-cc98-4738-9a0a-56dde3026947" + }); + changed = true; + } + if (!ctx.Groups.Any(g => g.GroupID == ScorpionString)) { + ctx.Groups.Add(new Model.Group { + GroupID = ScorpionString, + Name = EMD_Scorpions.Name, + Color = EMD_Scorpions.Color, + Logo = EMD_Scorpions.Logo, + Type = GroupType.System, + ApiKey = "dd602cf1-cc98-4738-9a0a-56dde3026947" + }); + changed = true; + } + if (changed) ctx.SaveChanges(); + } +} diff --git a/src/Controllers/Common/ProfileController.cs b/src/Controllers/Common/ProfileController.cs index 5503070..c6928c2 100644 --- a/src/Controllers/Common/ProfileController.cs +++ b/src/Controllers/Common/ProfileController.cs @@ -152,6 +152,22 @@ public class ProfileController : Controller { UserGameCurrency currency = achievementService.GetUserCurrency(viking); + ICollection groups = viking.Groups; + + UserProfileGroupData[] groupData = new UserProfileGroupData[groups.Count]; + int i = 0; + foreach (Model.Group group in groups) { + groupData[i] = new UserProfileGroupData { + GroupID = group.GroupID.ToString(), + Name = group.Name, + Color = group.Color, + Logo = group.Logo, + TypeID = (int)group.Type, + RoleID = 0 + }; + i++; + } + return new UserProfileData { ID = viking.Uid.ToString(), AvatarInfo = avatar, @@ -169,7 +185,8 @@ public class ProfileController : Controller { ProfileTags = new List(), UserID = viking.Uid, UserProfileTagID = 1 - } + }, + Groups = groupData }; } } diff --git a/src/Model/DBContext.cs b/src/Model/DBContext.cs index c72f7c0..0d287df 100644 --- a/src/Model/DBContext.cs +++ b/src/Model/DBContext.cs @@ -25,6 +25,7 @@ public class DBContext : DbContext { public DbSet Parties { get; set; } = null!; public DbSet Neighborhoods { get; set; } = null!; // we had a brief debate on whether it's neighborhoods or neighborheed + public DbSet Groups { get; set; } = null!; private readonly IOptions config; @@ -136,6 +137,9 @@ public class DBContext : DbContext { builder.Entity().HasOne(v => v.Neighborhood) .WithOne(e => e.Viking); + builder.Entity().HasMany(v => v.Groups) + .WithMany(e => e.Vikings); + // Dragons builder.Entity().HasOne(d => d.Viking) .WithMany(e => e.Dragons) @@ -252,5 +256,9 @@ public class DBContext : DbContext { builder.Entity().HasOne(r => r.Viking) .WithOne(e => e.Neighborhood) .HasForeignKey(e => e.VikingId); + + // Groups + builder.Entity().HasMany(r => r.Vikings) + .WithMany(e => e.Groups); } } diff --git a/src/Model/Group.cs b/src/Model/Group.cs new file mode 100644 index 0000000..c06d450 --- /dev/null +++ b/src/Model/Group.cs @@ -0,0 +1,25 @@ +using sodoff.Schema; +using System.ComponentModel.DataAnnotations; + +namespace sodoff.Model; + +// Implementation for EMD, add whatever else if needed +public class Group { + [Key] + public int Id { get; set; } + + [Required] + public Guid GroupID { get; set; } + + public string Name { get; set; } + + public GroupType Type { get; set; } + + public string Color { get; set; } + + public string Logo { get; set; } + + public string ApiKey { get; set; } + + public virtual ICollection Vikings { get; set; } = null!; +} diff --git a/src/Model/Viking.cs b/src/Model/Viking.cs index ff8bc93..67b188f 100644 --- a/src/Model/Viking.cs +++ b/src/Model/Viking.cs @@ -38,6 +38,7 @@ public class Viking { public virtual ICollection Parties { get; set; } = null!; public virtual ICollection MMORoles { get; set; } = null!; public virtual Neighborhood? Neighborhood { get; set; } = null!; + public virtual ICollection Groups { get; set; } = null!; public virtual Dragon? SelectedDragon { get; set; } public DateTime? CreationDate { get; set; } diff --git a/src/Resources/mmo.xml b/src/Resources/mmo.xml index 9945ec9..b2a086a 100644 --- a/src/Resources/mmo.xml +++ b/src/Resources/mmo.xml @@ -35,7 +35,14 @@ - + 0x04000000 + 0x04ffffff + BadlandsEMD RoadSideAttractionEMD JunkYardEMD PitRowEMD RacingCircuitEMD MyGarageEMDInt DragonHomeEMD ScorpionHomeEMD + + +