From 20213153ab14206ee76f615afaed1e51a67d58cf Mon Sep 17 00:00:00 2001 From: Mikhail Date: Fri, 12 Jul 2024 16:22:01 -0400 Subject: [PATCH] Fix inventory system crash Forgot to assign position value --- .../Msgs/Inventory/WearEquipment.cs | 1 + .../Msgs/Inventory/WearEquipmentList.cs | 2 +- .../LobbyServer/Msgs/User/EnterLobbyServer.cs | 8 ++- nksrv/LobbyServer/Msgs/User/GetUser.cs | 2 +- nksrv/StaticInfo/StaticDataParser.cs | 32 +++++++++- nksrv/Utils/JsonDb.cs | 16 ++++- nksrv/Utils/NetUtils.cs | 61 +++++++++++++++++++ 7 files changed, 113 insertions(+), 9 deletions(-) diff --git a/nksrv/LobbyServer/Msgs/Inventory/WearEquipment.cs b/nksrv/LobbyServer/Msgs/Inventory/WearEquipment.cs index fe79373..313e85e 100644 --- a/nksrv/LobbyServer/Msgs/Inventory/WearEquipment.cs +++ b/nksrv/LobbyServer/Msgs/Inventory/WearEquipment.cs @@ -23,6 +23,7 @@ namespace nksrv.LobbyServer.Msgs.Inventory { // update character id item.Csn = req.Csn; + item.Position = NetUtils.GetItemPos(user, item.Isn); } } diff --git a/nksrv/LobbyServer/Msgs/Inventory/WearEquipmentList.cs b/nksrv/LobbyServer/Msgs/Inventory/WearEquipmentList.cs index 5dad0fa..08dd133 100644 --- a/nksrv/LobbyServer/Msgs/Inventory/WearEquipmentList.cs +++ b/nksrv/LobbyServer/Msgs/Inventory/WearEquipmentList.cs @@ -24,7 +24,7 @@ namespace nksrv.LobbyServer.Msgs.Inventory if (item2 == item.Isn) { item.Csn = req.Csn; - + item.Position = NetUtils.GetItemPos(user, item.Isn); response.Items.Add(NetUtils.ToNet(item)); } } diff --git a/nksrv/LobbyServer/Msgs/User/EnterLobbyServer.cs b/nksrv/LobbyServer/Msgs/User/EnterLobbyServer.cs index 6756b5e..4d7ef7f 100644 --- a/nksrv/LobbyServer/Msgs/User/EnterLobbyServer.cs +++ b/nksrv/LobbyServer/Msgs/User/EnterLobbyServer.cs @@ -47,13 +47,15 @@ namespace nksrv.LobbyServer.Msgs.User { response.Currency.Add(new NetUserCurrencyData() { Type = (int)item.Key, Value = item.Value }); } + foreach (var item in user.Characters) { response.Character.Add(new NetUserCharacterData() { Default = new() { Csn = item.Csn, Skill1Lv = item.Skill1Lvl, Skill2Lv = item.Skill2Lvl, CostumeId = item.CostumeId, Lv = item.Level, Grade = item.Grade, Tid = item.Tid, UltiSkillLv = item.UltimateLevel } }); } - foreach (var item in user.Items) + + foreach (var item in NetUtils.GetUserItems(user)) { - response.Items.Add(new NetUserItemData() { Count = item.Count, Tid = item.ItemType, Csn = item.Csn, Lv = item.Level, Exp = item.Exp, Corporation = item.Corp, Isn = item.Isn, Position = item.Position }); + response.Items.Add(item); } // Add squad data if there are characters @@ -85,7 +87,7 @@ namespace nksrv.LobbyServer.Msgs.User response.LastClearedNormalMainStageId = user.LastNormalStageCleared; - await WriteDataAsync(response); + await WriteDataAsync(response); } } } diff --git a/nksrv/LobbyServer/Msgs/User/GetUser.cs b/nksrv/LobbyServer/Msgs/User/GetUser.cs index b764571..f0b7d21 100644 --- a/nksrv/LobbyServer/Msgs/User/GetUser.cs +++ b/nksrv/LobbyServer/Msgs/User/GetUser.cs @@ -32,7 +32,7 @@ namespace nksrv.LobbyServer.Msgs.User response.RepresentationTeam = user.RepresentationTeamData; response.LastClearedNormalMainStageId = user.LastNormalStageCleared; - + // Restore completed tutorials. GroupID is the first 4 digits of the Table ID. foreach (var item in user.ClearedTutorialData) { diff --git a/nksrv/StaticInfo/StaticDataParser.cs b/nksrv/StaticInfo/StaticDataParser.cs index c1ce170..aedc83a 100644 --- a/nksrv/StaticInfo/StaticDataParser.cs +++ b/nksrv/StaticInfo/StaticDataParser.cs @@ -54,6 +54,7 @@ namespace nksrv.StaticInfo private JArray characterCostumeTable; private JArray characterTable; private JArray tutorialTable; + private JArray itemEquipTable; public byte[] Sha256Hash; public int Size; @@ -83,7 +84,7 @@ namespace nksrv.StaticInfo characterTable = new(); ZipStream = new(); tutorialTable = new(); - + itemEquipTable = new(); var rawBytes = File.ReadAllBytes(filePath); Sha256Hash = SHA256.HashData(rawBytes); @@ -152,13 +153,14 @@ namespace nksrv.StaticInfo ZipStream = new MemoryStream(); AesCtrTransform(decryptionKey2, iv2, dataMs, ZipStream); + ZipStream.Position = 0; + File.WriteAllBytes("descrpytredlatest.zip", ZipStream.ToArray()); ZipStream.Position = 0; MainZip = new ZipFile(ZipStream, false); } - public static void AesCtrTransform( - byte[] key, byte[] salt, Stream inputStream, Stream outputStream) + public static void AesCtrTransform(byte[] key, byte[] salt, Stream inputStream, Stream outputStream) { SymmetricAlgorithm aes = Aes.Create(); aes.Mode = CipherMode.ECB; @@ -244,6 +246,7 @@ namespace nksrv.StaticInfo characterCostumeTable = await LoadZip("CharacterCostumeTable.json"); characterTable = await LoadZip("CharacterTable.json"); tutorialTable = await LoadZip("ContentsTutorialTable.json"); + itemEquipTable = await LoadZip("ItemEquipTable.json"); } public MainQuestCompletionData? GetMainQuestForStageClearCondition(int stage) @@ -418,5 +421,28 @@ namespace nksrv.StaticInfo throw new Exception("tutorial not found: " + TableId); } + + public string? GetItemSubType(int itemType) + { + foreach (JObject item in itemEquipTable) + { + var id = item["id"]; + if (id == null) throw new Exception("expected id field in reward data"); + + int? idValue = id.ToObject(); + if (idValue == itemType) + { + var subtype = item["item_sub_type"]; + if (subtype == null) + { + throw new Exception("expected item_sub_type field in item equip data"); + } + + return subtype.ToObject(); + } + } + + return null; + } } } diff --git a/nksrv/Utils/JsonDb.cs b/nksrv/Utils/JsonDb.cs index 3840272..3e22203 100644 --- a/nksrv/Utils/JsonDb.cs +++ b/nksrv/Utils/JsonDb.cs @@ -137,7 +137,7 @@ namespace nksrv.Utils } public class CoreInfo { - public int DbVersion = 0; + public int DbVersion = 2; public List Users = []; public List LauncherAccessTokens = []; @@ -187,6 +187,20 @@ namespace nksrv.Utils } Console.WriteLine("Database update completed"); } + else if (Instance.DbVersion == 1) + { + Console.WriteLine("Starting database update..."); + // there was a bug where equipment position was not saved, so remove all items from each characters + Instance.DbVersion = 2; + foreach (var user in Instance.Users) + { + foreach (var f in user.Items.ToList()) + { + f.Csn = 0; + } + } + Console.WriteLine("Database update completed"); + } Save(); } else diff --git a/nksrv/Utils/NetUtils.cs b/nksrv/Utils/NetUtils.cs index c4cd804..fd1745a 100644 --- a/nksrv/Utils/NetUtils.cs +++ b/nksrv/Utils/NetUtils.cs @@ -1,4 +1,9 @@  + +using nksrv.StaticInfo; +using Swan.Logging; +using System.Reflection; + namespace nksrv.Utils { public class NetUtils @@ -17,5 +22,61 @@ namespace nksrv.Utils Tid = item.ItemType }; } + + public static List GetUserItems(User user) + { + List ret = new(); + Dictionary itemDictionary = new Dictionary(); + + foreach (var item in user.Items.ToList()) + { + if (item.Csn == 0) + { + if (itemDictionary.ContainsKey(item.ItemType)) + { + itemDictionary[item.ItemType].Count++; + } + else + { + itemDictionary[item.ItemType] = new NetUserItemData() { Count = item.Count, Tid = item.ItemType, Csn = item.Csn, Lv = item.Level, Exp = item.Exp, Corporation = item.Corp, Isn = item.Isn, Position = item.Position }; + } + } + else + { + var newItem = new NetUserItemData() { Count = item.Count, Tid = item.ItemType, Csn = item.Csn, Lv = item.Level, Exp = item.Exp, Corporation = item.Corp, Isn = item.Isn, Position = item.Position }; + itemDictionary[item.ItemType] = newItem; + } + } + + return ret; + } + + public static int GetItemPos(User user, long isn) + { + foreach (var item in user.Items) + { + if (item.Isn == isn) + { + var subType = StaticDataParser.Instance.GetItemSubType(item.ItemType); + switch(subType) + { + case "Module_A": + return 0; + case "Module_B": + return 1; + case "Module_C": + return 2; + case "Module_D": + return 3; + default: + Logger.Warn("Unknown item subtype: " + subType); + break; + } + break; + } + } + + return 0; + } } } \ No newline at end of file