From 97fe2f7b3c509693ba99e532b303b275a5989e33 Mon Sep 17 00:00:00 2001 From: Mikhail Date: Wed, 25 Dec 2024 17:04:01 -0500 Subject: [PATCH] Add basic badge support --- EpinelPS/Database/JsonDb.cs | 128 +++++++++++++++------- EpinelPS/LobbyServer/Badge/DeleteBadge.cs | 11 +- EpinelPS/LobbyServer/Badge/SyncBadge.cs | 8 ++ EpinelPS/LobbyServer/Gacha/ExecGacha.cs | 3 + 4 files changed, 112 insertions(+), 38 deletions(-) diff --git a/EpinelPS/Database/JsonDb.cs b/EpinelPS/Database/JsonDb.cs index 3341a62..4a5cafb 100644 --- a/EpinelPS/Database/JsonDb.cs +++ b/EpinelPS/Database/JsonDb.cs @@ -4,6 +4,7 @@ using EpinelPS.Utils; using Newtonsoft.Json; using Paseto.Builder; using Paseto; +using Google.Protobuf; namespace EpinelPS.Database { @@ -62,8 +63,8 @@ namespace EpinelPS.Database public class EventData { public List CompletedScenarios = new(); - public int Diff = 0; // Default value for Diff - public int LastStage = 0; // Default value for LastStage + public int Diff = 0; // Default value for Diff + public int LastStage = 0; // Default value for LastStage } public class SynchroSlot @@ -132,7 +133,7 @@ namespace EpinelPS.Database public bool ButtonAnimationPlayed = false; public bool PopupAnimationPlayed = false; - public UnlockData() {} + public UnlockData() { } public UnlockData(bool button, bool popup) { ButtonAnimationPlayed = button; @@ -144,6 +145,33 @@ namespace EpinelPS.Database { public List CompletedScenarios = []; } + public class Badge + { + public string Location = ""; + public long Seq; + public BadgeContents BadgeContent; + public string BadgeGuid; + + public Badge() {} + public Badge(NetBadge badge) + { + Location = badge.Location; + Seq = badge.Seq; + BadgeContent = badge.BadgeContent; + BadgeGuid = new Guid(badge.BadgeGuid.ToArray()).ToString(); + } + + public NetBadge ToNet() + { + return new NetBadge() + { + BadgeContent = BadgeContent, + BadgeGuid = ByteString.CopyFrom(new Guid(BadgeGuid).ToByteArray()), + Location = Location, + Seq = Seq + }; + } + } public class User { // User info @@ -161,7 +189,7 @@ namespace EpinelPS.Database public bool IsAdmin = false; public bool sickpulls = false; public bool IsBanned = false; - public int TitleId = 1; + public int TitleId = 1; public DateTime BanStart; public DateTime BanEnd; public int BanId = 0; @@ -218,10 +246,36 @@ namespace EpinelPS.Database public List StageClearHistorys = []; + public List Badges = []; + // Event data public Dictionary EventInfo = new(); public MogMinigameInfo MogInfo = new(); + public Badge AddBadge(BadgeContents type, string location) + { + // generate unique badge SEQ + var num = Rng.RandomId(); + + while (Badges.Any(x => x.Seq == num)) + { + num = Rng.RandomId(); + } + + var badge = new Badge() + { + BadgeContent = type, + Location = location, + BadgeGuid = Guid.NewGuid().ToString(), + Seq = num + }; + + Badges.Add(badge); + + return badge; + } + + public void SetQuest(int tid, bool recievedReward) { if (MainQuestData.ContainsKey(tid)) @@ -313,43 +367,43 @@ namespace EpinelPS.Database } } - public bool HasCharacter(int c) - { - // Step 1: Get the 'name_code' of the input character with Tid 'c' - if (GameData.Instance.characterTable.TryGetValue(c, out var inputCharacterRecord)) - { - int targetNameCode = inputCharacterRecord.name_code; - // Step 2: Find all character IDs in 'characterTable' that have the same 'name_code' - var matchingCharacterIds = GameData.Instance.characterTable.Where(kvp => kvp.Value.name_code == targetNameCode).Select(kvp => kvp.Key).ToHashSet(); + public bool HasCharacter(int c) + { + // Step 1: Get the 'name_code' of the input character with Tid 'c' + if (GameData.Instance.characterTable.TryGetValue(c, out var inputCharacterRecord)) + { + int targetNameCode = inputCharacterRecord.name_code; + // Step 2: Find all character IDs in 'characterTable' that have the same 'name_code' + var matchingCharacterIds = GameData.Instance.characterTable.Where(kvp => kvp.Value.name_code == targetNameCode).Select(kvp => kvp.Key).ToHashSet(); - // Step 3: Check if any of your owned characters have a 'Tid' in the set of matching IDs - return Characters.Any(ownedCharacter => matchingCharacterIds.Contains(ownedCharacter.Tid)); - - } - else - { // The character with Tid 'c' does not exist in 'characterTable' - return false; - } - } + // Step 3: Check if any of your owned characters have a 'Tid' in the set of matching IDs + return Characters.Any(ownedCharacter => matchingCharacterIds.Contains(ownedCharacter.Tid)); + + } + else + { // The character with Tid 'c' does not exist in 'characterTable' + return false; + } + } public Character? GetCharacter(int c) - { - // Step 1: Get the 'name_code' of the input character with Tid 'c' - if (GameData.Instance.characterTable.TryGetValue(c, out var inputCharacterRecord)) - { - int targetNameCode = inputCharacterRecord.name_code; - // Step 2: Find all character IDs in 'characterTable' that have the same 'name_code' - var matchingCharacterIds = GameData.Instance.characterTable.Where(kvp => kvp.Value.name_code == targetNameCode).Select(kvp => kvp.Key).ToHashSet(); + { + // Step 1: Get the 'name_code' of the input character with Tid 'c' + if (GameData.Instance.characterTable.TryGetValue(c, out var inputCharacterRecord)) + { + int targetNameCode = inputCharacterRecord.name_code; + // Step 2: Find all character IDs in 'characterTable' that have the same 'name_code' + var matchingCharacterIds = GameData.Instance.characterTable.Where(kvp => kvp.Value.name_code == targetNameCode).Select(kvp => kvp.Key).ToHashSet(); - // Step 3: Check if any of your owned characters have a 'Tid' in the set of matching IDs - return Characters.Where(ownedCharacter => matchingCharacterIds.Contains(ownedCharacter.Tid)).First(); - - } - else - { // The character with Tid 'c' does not exist in 'characterTable' - return null; - } - } + // Step 3: Check if any of your owned characters have a 'Tid' in the set of matching IDs + return Characters.Where(ownedCharacter => matchingCharacterIds.Contains(ownedCharacter.Tid)).First(); + + } + else + { // The character with Tid 'c' does not exist in 'characterTable' + return null; + } + } public Character? GetCharacterBySerialNumber(long value) { diff --git a/EpinelPS/LobbyServer/Badge/DeleteBadge.cs b/EpinelPS/LobbyServer/Badge/DeleteBadge.cs index 366ff40..85fd234 100644 --- a/EpinelPS/LobbyServer/Badge/DeleteBadge.cs +++ b/EpinelPS/LobbyServer/Badge/DeleteBadge.cs @@ -1,4 +1,5 @@ -using EpinelPS.Utils; +using EpinelPS.Database; +using EpinelPS.Utils; namespace EpinelPS.LobbyServer.Badge { @@ -8,9 +9,17 @@ namespace EpinelPS.LobbyServer.Badge protected override async Task HandleAsync() { var req = await ReadData(); + var user = GetUser(); var response = new ResDeleteBadge(); + foreach (var badgeId in req.BadgeSeqList) + { + user.Badges.RemoveAll(x => x.Seq == badgeId); + } + + JsonDb.Save(); + await WriteDataAsync(response); } } diff --git a/EpinelPS/LobbyServer/Badge/SyncBadge.cs b/EpinelPS/LobbyServer/Badge/SyncBadge.cs index 88463a5..d1e6ef1 100644 --- a/EpinelPS/LobbyServer/Badge/SyncBadge.cs +++ b/EpinelPS/LobbyServer/Badge/SyncBadge.cs @@ -1,4 +1,5 @@ using EpinelPS.Utils; +using Google.Protobuf; namespace EpinelPS.LobbyServer.Badge { @@ -8,8 +9,15 @@ namespace EpinelPS.LobbyServer.Badge protected override async Task HandleAsync() { var req = await ReadData(); + var user = GetUser(); var response = new ResSyncBadge(); + + foreach (var item in user.Badges) + { + response.BadgeList.Add(item.ToNet()); + } + await WriteDataAsync(response); } } diff --git a/EpinelPS/LobbyServer/Gacha/ExecGacha.cs b/EpinelPS/LobbyServer/Gacha/ExecGacha.cs index da59921..7a290ba 100644 --- a/EpinelPS/LobbyServer/Gacha/ExecGacha.cs +++ b/EpinelPS/LobbyServer/Gacha/ExecGacha.cs @@ -196,6 +196,9 @@ namespace EpinelPS.LobbyServer.Gacha Tid = characterData.id, UltimateLevel = 1 }); + + // Add "New Character" Badge + user.AddBadge(BadgeContents.BadgeContentsNikkeNew, characterData.name_code.ToString()); } response.Gacha.Add(gacha);