From 319b169bfaa49d165394c8101bd46bb8a0484b81 Mon Sep 17 00:00:00 2001 From: Mikhail Date: Sun, 22 Sep 2024 13:33:14 -0400 Subject: [PATCH] Fully fix limit breaks --- EpinelPS/Database/JsonDb.cs | 61 ++++++++----- .../Msgs/Character/DoLimitBreak.cs | 28 +++++- .../Msgs/Character/GetCharacterData.cs | 1 - .../LobbyServer/Msgs/Character/UpgradeCore.cs | 88 +++++++++++++++---- 4 files changed, 137 insertions(+), 41 deletions(-) diff --git a/EpinelPS/Database/JsonDb.cs b/EpinelPS/Database/JsonDb.cs index 23e50f9..c0f84da 100644 --- a/EpinelPS/Database/JsonDb.cs +++ b/EpinelPS/Database/JsonDb.cs @@ -337,6 +337,47 @@ namespace EpinelPS.Database return 1; } } + + /// + /// Removes the specified amount of items by their ID. Returns the amount of items removed. + /// + /// + /// + /// + public int RemoveItemBySerialNumber(long isn, int count) + { + int removed = 0; + foreach (var item in Items.ToList()) + { + if (count == 0) + break; + + if (item.Isn == isn) + { + if (item.Count == 1) + { + Items.Remove(item); + count--; + } + else + { + // TODO test this + if (item.Count >= count) + { + removed++; + item.Count -= count; + } + else + { + removed += item.Count; + Items.Remove(item); + } + } + } + } + + return removed; + } } public class CoreInfo { @@ -468,26 +509,6 @@ namespace EpinelPS.Database c.Level = 1000; } } - - // Check if RepresentationTeamData exists and has slots - if (user.RepresentationTeamData != null && user.RepresentationTeamData.Slots != null) - { - // Iterate through RepresentationTeamData slots - foreach (var slot in user.RepresentationTeamData.Slots) - { - // Find the character in user's character list that matches the slot's Tid - var correspondingCharacter = user.Characters.FirstOrDefault(c => c.Tid == slot.Tid); - - if (correspondingCharacter != null) - { - // Update the CSN value if it differs - if (slot.Csn != correspondingCharacter.Csn) - { - slot.Csn = correspondingCharacter.Csn; - } - } - } - } } } diff --git a/EpinelPS/LobbyServer/Msgs/Character/DoLimitBreak.cs b/EpinelPS/LobbyServer/Msgs/Character/DoLimitBreak.cs index e78f58b..2b564d5 100644 --- a/EpinelPS/LobbyServer/Msgs/Character/DoLimitBreak.cs +++ b/EpinelPS/LobbyServer/Msgs/Character/DoLimitBreak.cs @@ -32,11 +32,13 @@ namespace EpinelPS.LobbyServer.Msgs.Character } // Find a new CSN based on the `name_code` of the current character and `grade_core_id + 1` + // For some reason, there is a seperate character for each limit/core break value. var newCharacter = fullchardata.FirstOrDefault(c => c.name_code == currentCharacter.name_code && c.grade_core_id == currentCharacter.grade_core_id + 1); if (newCharacter != null) { + // replace character in DB with new character targetCharacter.Grade++; targetCharacter.Tid = newCharacter.id; @@ -52,15 +54,37 @@ namespace EpinelPS.LobbyServer.Msgs.Character UltiSkillLv = targetCharacter.UltimateLevel }; - // TODO: remove spare body + // remove spare body item + user.RemoveItemBySerialNumber(req.Isn, 1); + foreach (var item in user.Items) { response.Items.Add(NetUtils.ToNet(item)); } + // replace any reference to the old character to the new TID + // Check if RepresentationTeamData exists and has slots + if (user.RepresentationTeamData != null && user.RepresentationTeamData.Slots != null) + { + // Iterate through RepresentationTeamData slots + foreach (var slot in user.RepresentationTeamData.Slots) + { + // Find the character in user's character list that matches the slot's Tid + var correspondingCharacter = user.Characters.FirstOrDefault(c => c.Tid == slot.Tid); + + if (correspondingCharacter != null) + { + // Update the CSN value if it differs + if (slot.Csn != correspondingCharacter.Csn) + { + slot.Csn = correspondingCharacter.Csn; + } + } + } + } + JsonDb.Save(); } - } // Send the response back to the client diff --git a/EpinelPS/LobbyServer/Msgs/Character/GetCharacterData.cs b/EpinelPS/LobbyServer/Msgs/Character/GetCharacterData.cs index 4097f84..37624ef 100644 --- a/EpinelPS/LobbyServer/Msgs/Character/GetCharacterData.cs +++ b/EpinelPS/LobbyServer/Msgs/Character/GetCharacterData.cs @@ -11,7 +11,6 @@ namespace EpinelPS.LobbyServer.Msgs.Character var user = GetUser(); var response = new ResGetCharacterData(); - // TODO: When Squad view opens in the game, or this request is sent, all character levels reset to 1 as well as costume IDs 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, Level = user.GetCharacterLevel(item.Csn, item.Level), Grade = item.Grade, Tid = item.Tid, UltiSkillLv = item.UltimateLevel }, IsSynchro = user.GetSynchro(item.Csn) }); diff --git a/EpinelPS/LobbyServer/Msgs/Character/UpgradeCore.cs b/EpinelPS/LobbyServer/Msgs/Character/UpgradeCore.cs index 7ec9efa..a167cd8 100644 --- a/EpinelPS/LobbyServer/Msgs/Character/UpgradeCore.cs +++ b/EpinelPS/LobbyServer/Msgs/Character/UpgradeCore.cs @@ -1,7 +1,7 @@ using EpinelPS.Database; using EpinelPS.Utils; using EpinelPS.StaticInfo; -//this file is work in progress and currently its fucked + namespace EpinelPS.LobbyServer.Msgs.Character { [PacketPath("/character/coreupgrade")] @@ -13,29 +13,81 @@ namespace EpinelPS.LobbyServer.Msgs.Character var req = await ReadData(); // Contains csn and isn (read-only) var response = new ResCharacterCoreUpgrade(); + var user = GetUser(); + // Get all character data from the game's character table var fullchardata = GameData.Instance.characterTable.Values.ToList(); - - // Find the element with the current csn from the request - var currentCharacter = fullchardata.FirstOrDefault(c => c.id == req.Csn); - - if (currentCharacter != null) - { - // Find a new CSN based on the `name_code` of the current character and `grade_core_id + 1` - var newCharacter = fullchardata.FirstOrDefault(c => c.name_code == currentCharacter.name_code && c.grade_core_id == currentCharacter.grade_core_id + 1); - - if (newCharacter != null) - { - // Update the characterData with the new CSN - var characterData = new NetUserCharacterDefaultData - { - Csn = newCharacter.id - // Add any other required data here - }; + var targetCharacter = user.GetCharacterBySerialNumber(req.Csn); + + // Find the element with the current csn from the request + var currentCharacter = fullchardata.FirstOrDefault(c => c.id == targetCharacter.Tid); + + if (currentCharacter != null && targetCharacter != null) + { + if (currentCharacter.grade_core_id == 103 || currentCharacter.grade_core_id == 11 || currentCharacter.grade_core_id == 201) + { + Console.WriteLine("warning: cannot upgrade code any further!"); + await WriteDataAsync(response); + return; } + // Find a new CSN based on the `name_code` of the current character and `grade_core_id + 1` + // For some reason, there is a seperate character for each limit/core break value. + var newCharacter = fullchardata.FirstOrDefault(c => c.name_code == currentCharacter.name_code && c.grade_core_id == currentCharacter.grade_core_id + 1); + + + if (newCharacter != null) + { + // replace character in DB with new character + targetCharacter.Grade++; + targetCharacter.Tid = newCharacter.id; + + response.Character = new NetUserCharacterDefaultData() + { + Csn = req.Csn, + CostumeId = targetCharacter.CostumeId, + Grade = targetCharacter.Grade, + Level = user.GetSynchroLevel(), + Skill1Lv = targetCharacter.Skill1Lvl, + Skill2Lv = targetCharacter.Skill2Lvl, + Tid = targetCharacter.Tid, + UltiSkillLv = targetCharacter.UltimateLevel + }; + + // remove spare body item + user.RemoveItemBySerialNumber(req.Isn, 1); + + foreach (var item in user.Items) + { + response.Items.Add(NetUtils.ToNet(item)); + } + + // replace any reference to the old character to the new TID + // Check if RepresentationTeamData exists and has slots + if (user.RepresentationTeamData != null && user.RepresentationTeamData.Slots != null) + { + // Iterate through RepresentationTeamData slots + foreach (var slot in user.RepresentationTeamData.Slots) + { + // Find the character in user's character list that matches the slot's Tid + var correspondingCharacter = user.Characters.FirstOrDefault(c => c.Tid == slot.Tid); + + if (correspondingCharacter != null) + { + // Update the CSN value if it differs + if (slot.Csn != correspondingCharacter.Csn) + { + slot.Csn = correspondingCharacter.Csn; + } + } + } + } + + JsonDb.Save(); + } } + // Send the response back to the client await WriteDataAsync(response); }