From 47e1bfb065da940ff84ef51c63326de408adc6aa Mon Sep 17 00:00:00 2001 From: Robert Paciorek Date: Mon, 11 Dec 2023 00:10:31 +0000 Subject: [PATCH] SoD 1.6 fixes - CreateRaisedPet endpoint - support for 1.6 apiKey + util class for management apiKey version recognition --- .../Common/AuthenticationController.cs | 4 +- src/Controllers/Common/ContentController.cs | 47 +++++++++++++++++++ src/Controllers/Common/ProfileController.cs | 4 +- .../Common/RegistrationController.cs | 2 +- src/Services/MissionService.cs | 25 ++++++---- src/Services/MissionStoreSingleton.cs | 4 +- src/Util/ClientVersion.cs | 30 ++++++++++++ 7 files changed, 99 insertions(+), 17 deletions(-) create mode 100644 src/Util/ClientVersion.cs diff --git a/src/Controllers/Common/AuthenticationController.cs b/src/Controllers/Common/AuthenticationController.cs index cd14467..d7962b6 100644 --- a/src/Controllers/Common/AuthenticationController.cs +++ b/src/Controllers/Common/AuthenticationController.cs @@ -95,7 +95,7 @@ public class AuthenticationController : Controller { Username = user.Username, MembershipID = "ef84db9-59c6-4950-b8ea-bbc1521f899b", // placeholder FacebookUserID = 0, - MultiplayerEnabled = (apiKey != "a1a13a0a-7c6e-4e9b-b0f7-22034d799013" && apiKey != "a2a09a0a-7c6e-4e9b-b0f7-22034d799013" && apiKey != "a3a12a0a-7c6e-4e9b-b0f7-22034d799013"), + MultiplayerEnabled = !ClientVersion.IsOldSoD(apiKey), IsApproved = true, Age = 24, OpenChatEnabled = true @@ -110,7 +110,7 @@ public class AuthenticationController : Controller { UserID = viking.Uid.ToString(), Username = viking.Name, FacebookUserID = 0, - MultiplayerEnabled = (apiKey != "a1a13a0a-7c6e-4e9b-b0f7-22034d799013" && apiKey != "a2a09a0a-7c6e-4e9b-b0f7-22034d799013" && apiKey != "a3a12a0a-7c6e-4e9b-b0f7-22034d799013"), + MultiplayerEnabled = !ClientVersion.IsOldSoD(apiKey), IsApproved = true, Age = 24, OpenChatEnabled = true diff --git a/src/Controllers/Common/ContentController.cs b/src/Controllers/Common/ContentController.cs index 3a8abbf..44bc747 100644 --- a/src/Controllers/Common/ContentController.cs +++ b/src/Controllers/Common/ContentController.cs @@ -271,6 +271,53 @@ public class ContentController : Controller { }); } + [HttpPost] + [Produces("application/xml")] + [Route("ContentWebService.asmx/CreateRaisedPet")] // used by SoD 1.6 + [VikingSession] + public RaisedPetData? CreateRaisedPet(Viking viking, int petTypeID) { + // Update the RaisedPetData with the info + String dragonId = Guid.NewGuid().ToString(); + + var raisedPetData = new RaisedPetData(); + raisedPetData.IsPetCreated = true; + raisedPetData.PetTypeID = petTypeID; + raisedPetData.RaisedPetID = 0; // Initially make zero, so the db auto-fills + raisedPetData.EntityID = Guid.Parse(dragonId); + raisedPetData.Name = string.Concat("Dragon-", dragonId.AsSpan(0, 8)); // Start off with a random name + raisedPetData.IsSelected = false; // The api returns false, not sure why + raisedPetData.CreateDate = new DateTime(DateTime.Now.Ticks); + raisedPetData.UpdateDate = new DateTime(DateTime.Now.Ticks); + raisedPetData.GrowthState = new RaisedPetGrowthState { Name = "BABY" }; + int imageSlot = (viking.Images.Select(i => i.ImageSlot).DefaultIfEmpty(-1).Max() + 1); + raisedPetData.ImagePosition = imageSlot; + // NOTE: Placing an egg into a hatchery slot calls CreatePet, but doesn't SetImage. + // NOTE: We need to force create an image slot because hatching multiple eggs at once would create dragons with the same slot + Image image = new Image { + ImageType = "EggColor", // NOTE: The game doesn't seem to use anything other than EggColor. + ImageSlot = imageSlot, + Viking = viking, + }; + // Save the dragon in the db + Dragon dragon = new Dragon { + EntityId = Guid.NewGuid(), + Viking = viking, + RaisedPetData = XmlUtil.SerializeXml(raisedPetData), + }; + + ctx.Dragons.Add(dragon); + ctx.Images.Add(image); + + if (petTypeID != 2) { + // Minisaurs should not be set as active pet + viking.SelectedDragon = dragon; + ctx.Update(viking); + } + ctx.SaveChanges(); + + return GetRaisedPetDataFromDragon(dragon); + } + [HttpPost] [Produces("application/xml")] [Route("V2/ContentWebService.asmx/CreatePet")] diff --git a/src/Controllers/Common/ProfileController.cs b/src/Controllers/Common/ProfileController.cs index 8f45dfd..971d5fe 100644 --- a/src/Controllers/Common/ProfileController.cs +++ b/src/Controllers/Common/ProfileController.cs @@ -116,7 +116,7 @@ public class ProfileController : Controller { avatarData.Id = viking.Id; } - if (avatarData != null && (apiKey == "a3a12a0a-7c6e-4e9b-b0f7-22034d799013")) { + if (avatarData != null && ClientVersion.Use2019SoDTutorial(apiKey)) { if (avatarData.Part.FirstOrDefault(e => e.PartType == "Sword") is null) { var extraParts = new AvatarDataPart[] { new AvatarDataPart { @@ -139,7 +139,7 @@ public class ProfileController : Controller { ParentUserID = viking.UserId.ToString(), Username = viking.Name, FirstName = viking.Name, - MultiplayerEnabled = (apiKey != "a1a13a0a-7c6e-4e9b-b0f7-22034d799013" && apiKey != "a2a09a0a-7c6e-4e9b-b0f7-22034d799013" && apiKey != "a3a12a0a-7c6e-4e9b-b0f7-22034d799013"), + MultiplayerEnabled = !ClientVersion.IsOldSoD(apiKey), Locale = "en-US", // placeholder GenderID = Gender.Male, // placeholder OpenChatEnabled = true, diff --git a/src/Controllers/Common/RegistrationController.cs b/src/Controllers/Common/RegistrationController.cs index d19cff5..45882e8 100644 --- a/src/Controllers/Common/RegistrationController.cs +++ b/src/Controllers/Common/RegistrationController.cs @@ -131,7 +131,7 @@ public class RegistrationController : Controller { ctx.Vikings.Add(v); ctx.SaveChanges(); - if (apiKey == "a1a13a0a-7c6e-4e9b-b0f7-22034d799013") { + if (ClientVersion.Use2013SoDTutorial(apiKey)) { keyValueService.SetPairData(null, v, null, 2017, new Schema.PairData { Pairs = new Schema.Pair[]{ new Schema.Pair { diff --git a/src/Services/MissionService.cs b/src/Services/MissionService.cs index 3a28f01..82583c6 100644 --- a/src/Services/MissionService.cs +++ b/src/Services/MissionService.cs @@ -1,5 +1,6 @@ using sodoff.Model; using sodoff.Schema; +using sodoff.Util; using System.Runtime.Serialization.Formatters.Binary; using System.Threading.Tasks; @@ -17,19 +18,23 @@ public class MissionService { } public Mission GetMissionWithProgress(int missionId, int userId, string apiKey) { - Mission mission; - if (missionId == 999 && apiKey == "a3a12a0a-7c6e-4e9b-b0f7-22034d799013") { // TODO This is not a pretty solution with hard-coded values. - mission = missionStore.GetMission(10999); + Mission mission = null; + + if (missionId == 999) { // TODO This is not a pretty solution with hard-coded values. + if (ClientVersion.Use2013SoDTutorial(apiKey)) { + mission = missionStore.GetMission(30999); + } else if (ClientVersion.Use2016SoDTutorial(apiKey)) { + mission = missionStore.GetMission(20999); + } else if (ClientVersion.Use2019SoDTutorial(apiKey)) { + mission = missionStore.GetMission(10999); + } mission.MissionID = 999; - } else if (missionId == 999 && apiKey == "a2a09a0a-7c6e-4e9b-b0f7-22034d799013") { - mission = missionStore.GetMission(20999); - mission.MissionID = 999; - } else if (missionId == 999 && apiKey == "a1a13a0a-7c6e-4e9b-b0f7-22034d799013") { - mission = missionStore.GetMission(30999); - mission.MissionID = 999; - } else { + } + + if (mission is null) { mission = missionStore.GetMission(missionId); } + UpdateMissionRecursive(mission, userId); return mission; } diff --git a/src/Services/MissionStoreSingleton.cs b/src/Services/MissionStoreSingleton.cs index 4acadab..e44a6b7 100644 --- a/src/Services/MissionStoreSingleton.cs +++ b/src/Services/MissionStoreSingleton.cs @@ -30,14 +30,14 @@ public class MissionStoreSingleton { } public int[] GetActiveMissions(string apiKey) { - if (apiKey == "a1a13a0a-7c6e-4e9b-b0f7-22034d799013") { + if (ClientVersion.Use2013SoDTutorial(apiKey)) { return activeMissionsV1; } return activeMissions; } public int[] GetUpcomingMissions(string apiKey) { - if (apiKey == "a1a13a0a-7c6e-4e9b-b0f7-22034d799013") { + if (ClientVersion.Use2013SoDTutorial(apiKey)) { return upcomingMissionsV1; } return upcomingMissions; diff --git a/src/Util/ClientVersion.cs b/src/Util/ClientVersion.cs new file mode 100644 index 0000000..24f65c6 --- /dev/null +++ b/src/Util/ClientVersion.cs @@ -0,0 +1,30 @@ +namespace sodoff.Util; +public class ClientVersion { + public static bool IsOldSoD(string apiKey) { + return ( + apiKey == "a1a06a0a-7c6e-4e9b-b0f7-22034d799013" || + apiKey == "a1a13a0a-7c6e-4e9b-b0f7-22034d799013" || + apiKey == "a2a09a0a-7c6e-4e9b-b0f7-22034d799013" || + apiKey == "a3a12a0a-7c6e-4e9b-b0f7-22034d799013" + ); + } + public static bool Use2013SoDTutorial(string apiKey) { + return ( + apiKey == "a1a06a0a-7c6e-4e9b-b0f7-22034d799013" || + apiKey == "a1a13a0a-7c6e-4e9b-b0f7-22034d799013" + ); + } + public static bool Use2016SoDTutorial(string apiKey) { + return ( + apiKey == "a2a09a0a-7c6e-4e9b-b0f7-22034d799013" + ); + } + public static bool Use2019SoDTutorial(string apiKey) { + return ( + apiKey == "a3a12a0a-7c6e-4e9b-b0f7-22034d799013" + ); + } + public static bool Use2021SoDTutorial(string apiKey) { + return !IsOldSoD(apiKey); + } +}