From 97503cc389c27955b10e0cf9b63e13a0b616abb3 Mon Sep 17 00:00:00 2001 From: Robert Paciorek Date: Sat, 24 Feb 2024 18:47:04 +0000 Subject: [PATCH] rework game version managment now we use game and SoD version encoded in uint (instead of compare raw apiKey values), this allows for easy support for more versions ... --- .../Common/AuthenticationController.cs | 4 +- src/Controllers/Common/ContentController.cs | 25 +++++--- src/Controllers/Common/ProfileController.cs | 4 +- .../Common/RegistrationController.cs | 5 +- src/Services/MissionService.cs | 24 ++++---- src/Services/MissionStoreSingleton.cs | 20 +++---- src/Util/ClientVersion.cs | 60 ++++++++++--------- 7 files changed, 77 insertions(+), 65 deletions(-) diff --git a/src/Controllers/Common/AuthenticationController.cs b/src/Controllers/Common/AuthenticationController.cs index eff74bb..a4b9518 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 = !ClientVersion.IsOldSoD(apiKey), + MultiplayerEnabled = ClientVersion.IsMultiplayerSupported(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 = !ClientVersion.IsOldSoD(apiKey), + MultiplayerEnabled = ClientVersion.IsMultiplayerSupported(apiKey), IsApproved = true, Age = 24, OpenChatEnabled = true diff --git a/src/Controllers/Common/ContentController.cs b/src/Controllers/Common/ContentController.cs index 5dabbcf..cf482cd 100644 --- a/src/Controllers/Common/ContentController.cs +++ b/src/Controllers/Common/ContentController.cs @@ -646,9 +646,10 @@ public class ContentController : Controller { if (viking is null) return Ok("error"); + uint gameVersion = ClientVersion.GetVersion(apiKey); UserMissionStateResult result = new UserMissionStateResult { Missions = new List() }; foreach (var mission in viking.MissionStates.Where(x => x.MissionStatus == MissionStatus.Upcoming)) - result.Missions.Add(missionService.GetMissionWithProgress(mission.MissionId, viking.Id, apiKey)); + result.Missions.Add(missionService.GetMissionWithProgress(mission.MissionId, viking.Id, gameVersion)); result.UserID = viking.Uid; return Ok(result); @@ -662,9 +663,10 @@ public class ContentController : Controller { if (viking is null) return Ok("error"); + uint gameVersion = ClientVersion.GetVersion(apiKey); UserMissionStateResult result = new UserMissionStateResult { Missions = new List() }; foreach (var mission in viking.MissionStates.Where(x => x.MissionStatus == MissionStatus.Active)) { - Mission updatedMission = missionService.GetMissionWithProgress(mission.MissionId, viking.Id, apiKey); + Mission updatedMission = missionService.GetMissionWithProgress(mission.MissionId, viking.Id, gameVersion); if (mission.UserAccepted != null) updatedMission.Accepted = (bool)mission.UserAccepted; result.Missions.Add(updatedMission); @@ -682,9 +684,10 @@ public class ContentController : Controller { if (viking is null) return Ok("error"); + uint gameVersion = ClientVersion.GetVersion(apiKey); UserMissionStateResult result = new UserMissionStateResult { Missions = new List() }; foreach (var mission in viking.MissionStates.Where(x => x.MissionStatus == MissionStatus.Completed)) - result.Missions.Add(missionService.GetMissionWithProgress(mission.MissionId, viking.Id, apiKey)); + result.Missions.Add(missionService.GetMissionWithProgress(mission.MissionId, viking.Id, gameVersion)); result.UserID = viking.Uid; return Ok(result); @@ -716,9 +719,10 @@ public class ContentController : Controller { if (viking is null) return Ok("error"); + uint gameVersion = ClientVersion.GetVersion(apiKey); UserMissionStateResult result = new UserMissionStateResult { Missions = new List() }; foreach (var mission in viking.MissionStates.Where(x => x.MissionStatus != MissionStatus.Completed)) { - Mission updatedMission = missionService.GetMissionWithProgress(mission.MissionId, viking.Id, apiKey); + Mission updatedMission = missionService.GetMissionWithProgress(mission.MissionId, viking.Id, gameVersion); if (mission.MissionStatus == MissionStatus.Upcoming) { // NOTE: in old SoD job board mission must be send as non active and required accept @@ -748,19 +752,20 @@ public class ContentController : Controller { if (viking is null) return Ok("error"); + uint gameVersion = ClientVersion.GetVersion(apiKey); UserMissionStateResult result = new UserMissionStateResult { Missions = new List() }; if (filterV2.MissionPair.Count > 0) { foreach (var m in filterV2.MissionPair) if (m.MissionID != null) - result.Missions.Add(missionService.GetMissionWithProgress((int)m.MissionID, viking.Id, apiKey)); + result.Missions.Add(missionService.GetMissionWithProgress((int)m.MissionID, viking.Id, gameVersion)); // TODO: probably should also check for mission based on filterV2.ProductGroupID vs mission.GroupID } else { if (filterV2.GetCompletedMission ?? false) { foreach (var mission in viking.MissionStates.Where(x => x.MissionStatus == MissionStatus.Completed)) - result.Missions.Add(missionService.GetMissionWithProgress(mission.MissionId, viking.Id, apiKey)); + result.Missions.Add(missionService.GetMissionWithProgress(mission.MissionId, viking.Id, gameVersion)); } else { foreach (var mission in viking.MissionStates.Where(x => x.MissionStatus != MissionStatus.Completed)) - result.Missions.Add(missionService.GetMissionWithProgress(mission.MissionId, viking.Id, apiKey)); + result.Missions.Add(missionService.GetMissionWithProgress(mission.MissionId, viking.Id, gameVersion)); } } @@ -776,7 +781,8 @@ public class ContentController : Controller { if (viking.Uid != userId) return Unauthorized("Can't set not owned task"); - List results = missionService.UpdateTaskProgress(missionId, taskId, viking.Id, completed, xmlPayload, apiKey); + uint gameVersion = ClientVersion.GetVersion(apiKey); + List results = missionService.UpdateTaskProgress(missionId, taskId, viking.Id, completed, xmlPayload, gameVersion); SetTaskStateResult taskResult = new SetTaskStateResult { Success = true, @@ -797,7 +803,8 @@ public class ContentController : Controller { if (viking.Uid != userId) return Unauthorized("Can't set not owned task"); - List results = missionService.UpdateTaskProgress(missionId, taskId, viking.Id, completed, xmlPayload, apiKey); + uint gameVersion = ClientVersion.GetVersion(apiKey); + List results = missionService.UpdateTaskProgress(missionId, taskId, viking.Id, completed, xmlPayload, gameVersion); SetTaskStateResult taskResult = new SetTaskStateResult { Success = true, diff --git a/src/Controllers/Common/ProfileController.cs b/src/Controllers/Common/ProfileController.cs index 971d5fe..f414b65 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 && ClientVersion.Use2019SoDTutorial(apiKey)) { + if (avatarData != null && ClientVersion.GetVersion(apiKey) == 0xa3a12a0a) { // TODO adjust version number: we don't know for which versions it is required (for 3.12 it is, for 3.19 and 3.0 it's not) 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 = !ClientVersion.IsOldSoD(apiKey), + MultiplayerEnabled = ClientVersion.IsMultiplayerSupported(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 45882e8..97833ab 100644 --- a/src/Controllers/Common/RegistrationController.cs +++ b/src/Controllers/Common/RegistrationController.cs @@ -126,12 +126,13 @@ public class RegistrationController : Controller { Rooms = new List() }; - missionService.SetUpMissions(v, apiKey); + uint gameVersion = ClientVersion.GetVersion(apiKey); + missionService.SetUpMissions(v, gameVersion); ctx.Vikings.Add(v); ctx.SaveChanges(); - if (ClientVersion.Use2013SoDTutorial(apiKey)) { + if (gameVersion < 0xa2a09a0a) { 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 767d423..76d2358 100644 --- a/src/Services/MissionService.cs +++ b/src/Services/MissionService.cs @@ -17,20 +17,20 @@ public class MissionService { this.achievementService = achievementService; } - public Mission GetMissionWithProgress(int missionId, int userId, string apiKey) { + public Mission GetMissionWithProgress(int missionId, int userId, uint gameVersion) { Mission mission = null; if (missionId == 999) { // TODO This is not a pretty solution with hard-coded values. - if (ClientVersion.Use2013SoDTutorial(apiKey)) { + if (gameVersion < 0xa2a03a0a) { mission = missionStore.GetMission(30999); - } else if (ClientVersion.Use2016SoDTutorial(apiKey)) { + } else if (gameVersion < 0xa3a03a0a) { mission = missionStore.GetMission(20999); - } else if (ClientVersion.Use2019SoDTutorial(apiKey)) { + } else if (gameVersion <= 0xa3a23a0a) { mission = missionStore.GetMission(10999); } - } else if (missionId == 1044 && ClientVersion.IsMaM(apiKey)) { + } else if (missionId == 1044 && gameVersion == ClientVersion.MaM) { mission = missionStore.GetMission(11044); - } else if (missionId == 1074 && ClientVersion.IsMaM(apiKey)) { + } else if (missionId == 1074 && gameVersion == ClientVersion.MaM) { mission = missionStore.GetMission(11074); } @@ -45,7 +45,7 @@ public class MissionService { return mission; } - public List UpdateTaskProgress(int missionId, int taskId, int userId, bool completed, string xmlPayload, string apiKey) { + public List UpdateTaskProgress(int missionId, int taskId, int userId, bool completed, string xmlPayload, uint gameVersion) { SetTaskProgressDB(missionId, taskId, userId, completed, xmlPayload); // NOTE: This won't work if a mission can be completed by completing an inner mission @@ -59,7 +59,7 @@ public class MissionService { // I do know that outer missions have inner missions as RuleItems, and if the RuleItem is supposed to be "complete" and it isn't, the quest breaks when the player quits the game and loads the quest again List result = new(); if (completed) { - Mission mission = GetMissionWithProgress(missionId, userId, apiKey); + Mission mission = GetMissionWithProgress(missionId, userId, gameVersion); if (MissionCompleted(mission)) { // Update mission from active to completed Viking viking = ctx.Vikings.FirstOrDefault(x => x.Id == userId)!; @@ -74,7 +74,7 @@ public class MissionService { task.Payload = null; task.Completed = false; } - if (missionStore.GetActiveMissions(apiKey).Contains(missionId)) + if (missionStore.GetActiveMissions(gameVersion).Contains(missionId)) missionState.MissionStatus = MissionStatus.Active; else missionState.MissionStatus = MissionStatus.Upcoming; @@ -126,17 +126,17 @@ public class MissionService { mission.Completed = 1; } - public void SetUpMissions(Viking viking, string apiKey) { + public void SetUpMissions(Viking viking, uint gameVersion) { viking.MissionStates = new List(); - foreach (int m in missionStore.GetActiveMissions(apiKey)) { + foreach (int m in missionStore.GetActiveMissions(gameVersion)) { viking.MissionStates.Add(new MissionState { MissionId = m, MissionStatus = MissionStatus.Active }); } - foreach (int m in missionStore.GetUpcomingMissions(apiKey)) { + foreach (int m in missionStore.GetUpcomingMissions(gameVersion)) { viking.MissionStates.Add(new MissionState { MissionId = m, MissionStatus = MissionStatus.Upcoming diff --git a/src/Services/MissionStoreSingleton.cs b/src/Services/MissionStoreSingleton.cs index 6e294db..4e029c7 100644 --- a/src/Services/MissionStoreSingleton.cs +++ b/src/Services/MissionStoreSingleton.cs @@ -35,23 +35,23 @@ public class MissionStoreSingleton { return DeepCopy(missions[missionID]); } - public int[] GetActiveMissions(string apiKey) { - if (ClientVersion.Use2013SoDTutorial(apiKey)) { - return activeMissionsV1; - } - if (ClientVersion.IsMaM(apiKey)) { + public int[] GetActiveMissions(uint gameVersion) { + if (gameVersion == ClientVersion.MaM) { return activeMissionsMaM; } + if (gameVersion < 0xa2a00a0a) { + return activeMissionsV1; + } return activeMissions; } - public int[] GetUpcomingMissions(string apiKey) { - if (ClientVersion.Use2013SoDTutorial(apiKey)) { - return upcomingMissionsV1; - } - if (ClientVersion.IsMaM(apiKey)) { + public int[] GetUpcomingMissions(uint gameVersion) { + if (gameVersion == ClientVersion.MaM) { return upcomingMissionsMaM; } + if (gameVersion < 0xa2a00a0a) { + return upcomingMissionsV1; + } return upcomingMissions; } diff --git a/src/Util/ClientVersion.cs b/src/Util/ClientVersion.cs index 88e1697..d28c328 100644 --- a/src/Util/ClientVersion.cs +++ b/src/Util/ClientVersion.cs @@ -1,34 +1,38 @@ 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); + public const uint Min_SoD = 0xa0000000; + public const uint MaM = 0x00800000; + public const uint MB = 0x00700000; + public const uint WoJS = 0x00600000; + + public static uint GetVersion(string apiKey) { + if ( + apiKey == "b99f695c-7c6e-4e9b-b0f7-22034d799013" || // PC / Windows + apiKey == "515af675-bec7-4c42-ba64-7bfaf198d8ea" || // Android + apiKey == "1e7ccc3a-4adb-4736-b843-7b3da5140a43" // iOS + ) { + return 0xa3a31a0a; + } else if ( + apiKey.EndsWith("7c6e-4e9b-b0f7-22034d799013") + ) { + return Convert.ToUInt32(apiKey.Substring(0, 8), 16); + } else if ( + apiKey == "e20150cc-ff70-435c-90fd-341dc9161cc3" + ) { + return MaM; + } else if ( + apiKey == "6738196d-2a2c-4ef8-9b6e-1252c6ec7325" + ) { + return MB; + } else if ( + apiKey == "1552008f-4a95-46f5-80e2-58574da65875" + ) { + return WoJS; + } + return 0; } - public static bool IsMaM(string apiKey) { - return apiKey == "e20150cc-ff70-435c-90fd-341dc9161cc3"; + public static bool IsMultiplayerSupported(string apiKey) { + return GetVersion(apiKey) >= 0xa3a19a0a; } }