diff --git a/src/Controllers/Common/AchievementController.cs b/src/Controllers/Common/AchievementController.cs index dbd7a13..2999c65 100644 --- a/src/Controllers/Common/AchievementController.cs +++ b/src/Controllers/Common/AchievementController.cs @@ -40,7 +40,8 @@ public class AchievementController : Controller { //[Produces("application/xml")] [Route("AchievementWebService.asmx/GetAllRanks")] public IActionResult GetAllRanks([FromForm] string apiKey) { - if (ClientVersion.GetVersion(apiKey) == ClientVersion.WoJS) + uint gameVersion = ClientVersion.GetVersion(apiKey); + if (gameVersion <= ClientVersion.Max_OldJS && (gameVersion & ClientVersion.WoJS) != 0) return Ok(XmlUtil.ReadResourceXmlString("allranks_wojs")); // TODO, this is a placeholder diff --git a/src/Controllers/Common/AuthenticationController.cs b/src/Controllers/Common/AuthenticationController.cs index 07f678f..9fecc4d 100644 --- a/src/Controllers/Common/AuthenticationController.cs +++ b/src/Controllers/Common/AuthenticationController.cs @@ -43,7 +43,7 @@ public class AuthenticationController : Controller { // Authenticate the user User? user = null; uint gameVersion = ClientVersion.GetVersion(apiKey); - if (gameVersion == ClientVersion.WoJS || gameVersion == ClientVersion.MB) { + if (gameVersion <= ClientVersion.Max_OldJS) { user = ctx.Users.FirstOrDefault(e => e.Email == data.UserName); } else { user = ctx.Users.FirstOrDefault(e => e.Username == data.UserName); diff --git a/src/Controllers/Common/ContentController.cs b/src/Controllers/Common/ContentController.cs index c0af146..1e20d12 100644 --- a/src/Controllers/Common/ContentController.cs +++ b/src/Controllers/Common/ContentController.cs @@ -98,7 +98,7 @@ public class ContentController : Controller { public string GetCurrentPet(Viking viking) { string? ret = Util.SavedData.Get( viking, - ClientVersion.WoJS + 1 + Util.SavedData.Pet() ); if (ret is null) return XmlUtil.SerializeXml(null); @@ -112,7 +112,7 @@ public class ContentController : Controller { public bool SetCurrentPet(Viking viking, [FromForm] string? contentXml) { Util.SavedData.Set( viking, - ClientVersion.WoJS + 1, + Util.SavedData.Pet(), contentXml ); ctx.SaveChanges(); @@ -1634,23 +1634,20 @@ public class ContentController : Controller { [Route("ContentWebSerivce.asmx/GetHouse")] // used by World Of Jumpstart [VikingSession] public IActionResult GetHouse(Viking viking) { - if (viking.House is not null) return Ok(viking.House.XmlData); - else return Ok(""); + string? ret = Util.SavedData.Get( + viking, + Util.SavedData.House() + ); + if (ret != null) + return Ok(ret); + return Ok(""); } [HttpPost] [Route("ContentWebService.asmx/GetHouseByUserId")] // used by World Of Jumpstart public IActionResult GetHouseByUserId([FromForm] Guid userId) { - Viking? viking = ctx.Vikings.FirstOrDefault(e => e.Uid == userId); - - if (viking is not null) - { - if (viking.House is not null) return Ok(viking.House.XmlData); - else return Ok(""); - } - - return Ok(""); + return GetHouse(ctx.Vikings.FirstOrDefault(e => e.Uid == userId)); } [HttpPost] @@ -1694,20 +1691,13 @@ public class ContentController : Controller { [Route("ContentWebService.asmx/SetHouse")] // used by World Of Jumpstart [VikingSession] public IActionResult SetHouse(Viking viking, [FromForm] string contentXml) { - HouseData? house = viking.House; - - if(house is null) - { - HouseData newHouse = new HouseData{ XmlData = contentXml }; - viking.House = newHouse; - ctx.SaveChanges(); - return Ok(true); - } else - { - house.XmlData = contentXml; - ctx.SaveChanges(); - return Ok(true); - } + Util.SavedData.Set( + viking, + Util.SavedData.House(), + contentXml + ); + ctx.SaveChanges(); + return Ok(true); } [HttpPost] diff --git a/src/Controllers/Common/ItemStoreController.cs b/src/Controllers/Common/ItemStoreController.cs index 808f685..cf95119 100644 --- a/src/Controllers/Common/ItemStoreController.cs +++ b/src/Controllers/Common/ItemStoreController.cs @@ -49,8 +49,8 @@ public class ItemStoreController : Controller { [HttpPost] [Produces("application/xml")] [Route("ItemStoreWebService.asmx/GetItemsInStore")] // used by World Of Jumpstart - public IActionResult GetItemsInStore([FromForm] int storeId) { - return Ok(storeService.GetStore(storeId)); + public IActionResult GetItemsInStore([FromForm] int storeId, [FromForm] string apiKey) { + return Ok(storeService.GetStore(storeId, ClientVersion.GetVersion(apiKey))); } [HttpPost] diff --git a/src/Controllers/Common/RegistrationController.cs b/src/Controllers/Common/RegistrationController.cs index ff715ca..977da30 100644 --- a/src/Controllers/Common/RegistrationController.cs +++ b/src/Controllers/Common/RegistrationController.cs @@ -64,7 +64,7 @@ public class RegistrationController : Controller { // Check if user exists uint gameVersion = ClientVersion.GetVersion(apiKey); - if (gameVersion == ClientVersion.WoJS || gameVersion == ClientVersion.MB) { + if (gameVersion <= ClientVersion.Max_OldJS) { if (ctx.Users.Count(e => e.Email == u.Email) > 0) { return Ok(new RegistrationResult { Status = MembershipUserStatus.DuplicateEmail }); } @@ -74,23 +74,12 @@ public class RegistrationController : Controller { } ctx.Users.Add(u); - - if(gameVersion == ClientVersion.MB) { - Viking v = new Viking { - Uid = Guid.NewGuid(), - Name = data.ChildList[0].ChildName, - User = u, - InventoryItems = new List(), - AchievementPoints = new List(), - Rooms = new List(), - CreationDate = DateTime.UtcNow, - BirthDate = data.ChildList[0].BirthDate - }; - ctx.Vikings.Add(v); - } - ctx.SaveChanges(); + if (gameVersion <= ClientVersion.Max_OldJS) { + CreateViking(u, data.ChildList[0], gameVersion); + } + ParentLoginInfo pli = new ParentLoginInfo { UserName = u.Username, ApiToken = Guid.NewGuid().ToString(), @@ -134,9 +123,19 @@ public class RegistrationController : Controller { return Ok(new RegistrationResult { Status = MembershipUserStatus.DuplicateUserName }); } - List items = new() { - new InventoryItem { ItemId = 8977, Quantity = 1 } // DragonStableINTDO - Dragons Dragon Stable - }; + Viking v = CreateViking(user, data, ClientVersion.GetVersion(apiKey)); + + return Ok(new RegistrationResult { + UserID = v.Uid.ToString(), + Status = MembershipUserStatus.Success + }); + } + + private Viking CreateViking(User user, ChildRegistrationData data, uint gameVersion) { + List items = new(); + if (gameVersion >= ClientVersion.Min_SoD) { + items.Add( new InventoryItem { ItemId = 8977, Quantity = 1 } ); // DragonStableINTDO - Dragons Dragon Stable + } Viking v = new Viking { Uid = Guid.NewGuid(), @@ -145,11 +144,10 @@ public class RegistrationController : Controller { InventoryItems = items, AchievementPoints = new List(), Rooms = new List(), - CreationDate = DateTime.Now, + CreationDate = DateTime.UtcNow, BirthDate = data.BirthDate }; - uint gameVersion = ClientVersion.GetVersion(apiKey); missionService.SetUpMissions(v, gameVersion); if (data.Gender == "Boy") v.Gender = Gender.Male; @@ -158,7 +156,7 @@ public class RegistrationController : Controller { ctx.Vikings.Add(v); ctx.SaveChanges(); - if (gameVersion < 0xa2a09a0a) { + if (gameVersion >= ClientVersion.MaM && gameVersion < 0xa2a09a0a) { keyValueService.SetPairData(null, v, null, 2017, new Schema.PairData { Pairs = new Schema.Pair[]{ new Schema.Pair { @@ -172,9 +170,6 @@ public class RegistrationController : Controller { roomService.CreateRoom(v, "MyRoomINT"); - return Ok(new RegistrationResult { - UserID = v.Uid.ToString(), - Status = MembershipUserStatus.Success - }); + return v; } } diff --git a/src/Model/DBContext.cs b/src/Model/DBContext.cs index 82cc8ae..c05d864 100644 --- a/src/Model/DBContext.cs +++ b/src/Model/DBContext.cs @@ -16,7 +16,6 @@ public class DBContext : DbContext { public DbSet MissionStates { get; set; } = null!; public DbSet Rooms { get; set; } = null!; public DbSet SceneData { get; set; } = null!; - public DbSet Houses { get; set; } = null!; public DbSet RoomItems { get; set; } = null!; public DbSet GameData { get; set; } = null!; public DbSet GameDataPairs { get; set; } = null!; @@ -99,9 +98,6 @@ public class DBContext : DbContext { builder.Entity().HasMany(v => v.SceneData) .WithOne(e => e.Viking); - builder.Entity().HasOne(v => v.House) - .WithOne(e => e.Viking); - builder.Entity().HasMany(v => v.AchievementPoints) .WithOne(e => e.Viking); @@ -236,8 +232,5 @@ public class DBContext : DbContext { builder.Entity().HasOne(i => i.Viking) .WithMany(i => i.SceneData) .HasForeignKey(e => e.VikingId); - - builder.Entity().HasOne(i => i.Viking) - .WithOne(e => e.House); } } diff --git a/src/Model/HouseData.cs b/src/Model/HouseData.cs deleted file mode 100644 index daf8074..0000000 --- a/src/Model/HouseData.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace sodoff.Model -{ - public class HouseData - { - [Key] - public int Id { get; set; } - public int VikingId { get; set; } - public virtual Viking Viking { get; set; } = null!; - public string XmlData { get; set; } = null!; - } -} diff --git a/src/Model/Viking.cs b/src/Model/Viking.cs index baeee88..5aee21a 100644 --- a/src/Model/Viking.cs +++ b/src/Model/Viking.cs @@ -29,7 +29,6 @@ public class Viking { public virtual ICollection TaskStatuses { get; set; } = null!; public virtual ICollection Rooms { get; set; } = null!; public virtual ICollection SceneData { get; set; } = null!; - public virtual HouseData House { get; set; } = null!; public virtual ICollection AchievementPoints { get; set; } = null!; public virtual ICollection PairData { get; set; } = null!; public virtual ICollection InventoryItems { get; set; } = null!; diff --git a/src/Services/GameDataService.cs b/src/Services/GameDataService.cs index c0ff7e2..5c64e0e 100644 --- a/src/Services/GameDataService.cs +++ b/src/Services/GameDataService.cs @@ -45,7 +45,8 @@ public class GameDataService { var query2 = query.SelectMany(e => e.GameDataPairs) .Where(x => x.Name == key); - if (ClientVersion.GetVersion(apiKey) == ClientVersion.WoJS) { + uint gameVersion = ClientVersion.GetVersion(apiKey); + if (gameVersion <= ClientVersion.Max_OldJS) { // use DisplayName instead of Name if (AscendingOrder) selectedData = query2.OrderBy(e => e.Value).Select(e => new GameDataResponse( diff --git a/src/Services/MissionStoreSingleton.cs b/src/Services/MissionStoreSingleton.cs index 480b50e..48fc1be 100644 --- a/src/Services/MissionStoreSingleton.cs +++ b/src/Services/MissionStoreSingleton.cs @@ -46,29 +46,35 @@ public class MissionStoreSingleton { } public int[] GetActiveMissions(uint gameVersion) { + if (gameVersion >= 0xa2a00a0a) { + return activeMissions; + } + if (gameVersion >= ClientVersion.Min_SoD) { + return activeMissionsV1; + } if (gameVersion == ClientVersion.MaM) { return activeMissionsMaM; } - if (gameVersion == ClientVersion.WoJS) { + if ((gameVersion & ClientVersion.WoJS) != 0) { return activeMissionsWoJS; } - if (gameVersion < 0xa2a00a0a) { - return activeMissionsV1; - } - return activeMissions; + return new int[0]; } public int[] GetUpcomingMissions(uint gameVersion) { + if (gameVersion >= 0xa2a00a0a) { + return upcomingMissions; + } + if (gameVersion >= ClientVersion.Min_SoD) { + return upcomingMissionsV1; + } if (gameVersion == ClientVersion.MaM) { return upcomingMissionsMaM; } - if (gameVersion == ClientVersion.WoJS) { + if ((gameVersion & ClientVersion.WoJS) != 0) { return upcomingMissionsWoJS; } - if (gameVersion < 0xa2a00a0a) { - return upcomingMissionsV1; - } - return upcomingMissions; + return new int[0]; } private void SetUpRecursive(Mission mission) { diff --git a/src/Services/StoreService.cs b/src/Services/StoreService.cs index 7ce615d..e3e46a8 100644 --- a/src/Services/StoreService.cs +++ b/src/Services/StoreService.cs @@ -10,7 +10,7 @@ public class StoreService { StoreData[] storeArray = XmlUtil.DeserializeXml(XmlUtil.ReadResourceXmlString("store")); foreach (var s in storeArray) { ItemsInStoreData newStore = new() { - ID = s.Id, + ID = s.Id % 1000, // % 1000 for support store variants (for example 30123 and 123 is the same store but for different games / versions) StoreName = s.StoreName, Description = s.Description, SalesAtStore = s.SalesAtStore, @@ -39,6 +39,14 @@ public class StoreService { return stores[id]; } + public ItemsInStoreData GetStore(int id, uint gameVersion) { + if (gameVersion < ClientVersion.WoJS_NewAvatar) { + if (stores.ContainsKey(id+30000)) + return stores[id+30000]; + } + return stores[id]; + } + private bool IsSaleOutdated(ItemsInStoreDataSale sale) { if (sale.EndDate == null) return false; diff --git a/src/Util/ClientVersion.cs b/src/Util/ClientVersion.cs index dda10e7..052995b 100644 --- a/src/Util/ClientVersion.cs +++ b/src/Util/ClientVersion.cs @@ -1,9 +1,14 @@ namespace sodoff.Util; public class ClientVersion { - public const uint Min_SoD = 0xa0000000; - public const uint MaM = 0x00800000; - public const uint MB = 0x00700000; - public const uint WoJS = 0x00600000; + public const uint Min_SoD = 0xa0000000; + public const uint MaM = 0x80000000; + public const uint Max_OldJS = 0x0fffffff; // x <= Max_OldJS <=> x in [MB, EMD, SS, WoJS, Lands, ...] + public const uint MB = 0x08000000; + public const uint EMD = 0x04000000; + public const uint SS = 0x02000000; + public const uint WoJS = 0x01000000; + public const uint WoJS_AdvLand = 0x01000100; // World of JumpStart -- Adventureland + public const uint WoJS_NewAvatar = 0x01010000; // World of JumpStart with new avatars (e.g. 1.21) public static uint GetVersion(string apiKey) { if ( @@ -24,6 +29,14 @@ public class ClientVersion { apiKey == "6738196d-2a2c-4ef8-9b6e-1252c6ec7325" ) { return MB; + } else if ( + apiKey == "34b0ae13-eccc-4d64-b6d0-733d2562080e" + ) { + return SS; + } else if ( + apiKey == "15a1a21a-4a95-46f5-80e2-58574da65875" + ) { + return WoJS_NewAvatar; } else if ( apiKey == "1552008f-4a95-46f5-80e2-58574da65875" ) { @@ -31,8 +44,9 @@ public class ClientVersion { } else if ( apiKey == "b4e0f71a-1cda-462a-97b3-0b355e87e0c8" ) { - return WoJS+10; // WoJS--Adventureland + return WoJS_AdvLand; } + Console.WriteLine($"Unknown apiKey value: {apiKey}"); return 0; } } diff --git a/src/Util/SavedData.cs b/src/Util/SavedData.cs index 4cfa1ed..d111818 100644 --- a/src/Util/SavedData.cs +++ b/src/Util/SavedData.cs @@ -2,6 +2,14 @@ using sodoff.Model; namespace sodoff.Util; public class SavedData { + public static uint Pet(uint gameVersion = ClientVersion.WoJS) { + return gameVersion + 1; + } + + public static uint House(uint gameVersion = ClientVersion.WoJS) { + return gameVersion + 2; + } + public static string? Get(Viking? viking, uint saveId) { return viking?.SavedData.FirstOrDefault(s => s.SaveId == saveId)?.SerializedData; }