From 9b8fa5d7c8cd41a9e4ce89923783716789623eec Mon Sep 17 00:00:00 2001 From: Naruse <71993948+DevilProMT@users.noreply.github.com> Date: Wed, 29 Apr 2026 11:02:11 +0800 Subject: [PATCH] add profile item --- Common/Data/Excel/ProfileExcel.cs | 22 +++++++++ Common/Data/GameData.cs | 2 +- Common/Enums/Player/ProfileTypeEnum.cs | 24 +++++++++ .../Message/LanguageCHS.cs | 4 +- .../Message/LanguageCHT.cs | 4 +- .../Message/LanguageEN.cs | 4 +- GameServer/Command/Commands/CommandGiveAll.cs | 38 +++++++++++++- GameServer/Game/Inventory/InventoryManager.cs | 33 ++++++++++--- .../Handlers/Daily/Daily_SetSelectSuit.cs | 2 +- .../Handlers/Girl/GirlWeaponSkin_Change.cs | 4 +- .../Misc/PlayerSetting_ChangeShowCard.cs | 10 +--- .../Misc/PlayerSetting_SetProfileFace.cs | 49 +++++++++++++++++++ .../Misc/PlayerSetting_SetShowBubble.cs | 36 ++++++++++++++ .../Misc/PlayerSetting_SetShowCover.cs | 36 ++++++++++++++ .../Misc/PlayerSetting_SetShowNameCard.cs | 36 ++++++++++++++ 15 files changed, 282 insertions(+), 22 deletions(-) create mode 100644 Common/Data/Excel/ProfileExcel.cs create mode 100644 Common/Enums/Player/ProfileTypeEnum.cs create mode 100644 GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetProfileFace.cs create mode 100644 GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowBubble.cs create mode 100644 GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowCover.cs create mode 100644 GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowNameCard.cs diff --git a/Common/Data/Excel/ProfileExcel.cs b/Common/Data/Excel/ProfileExcel.cs new file mode 100644 index 0000000..8084e13 --- /dev/null +++ b/Common/Data/Excel/ProfileExcel.cs @@ -0,0 +1,22 @@ +namespace MikuSB.Data.Excel; + +[ResourceEntity("profile.json")] +public class ProfileExcel : ExcelResource +{ + public uint Genre { get; set; } + public uint Detail { get; set; } + public uint Particular { get; set; } + public uint Level { get; set; } + public string I18n { get; set; } = ""; + public string LuaType { get; set; } = ""; + + public override uint GetId() + { + return (uint)I18n.GetHashCode(); + } + + public override void Loaded() + { + GameData.ProfileData.Add(GetId(), this); + } +} diff --git a/Common/Data/GameData.cs b/Common/Data/GameData.cs index 80d94b3..0a23bd9 100644 --- a/Common/Data/GameData.cs +++ b/Common/Data/GameData.cs @@ -22,7 +22,7 @@ public static class GameData public static List SupportCardData { get; private set; } = []; public static Dictionary WeaponSkinData { get; private set; } = []; public static Dictionary DailyLevelData { get; private set; } = []; - + public static Dictionary ProfileData { get; private set; } = []; } public static class GameResourceTemplateId diff --git a/Common/Enums/Player/ProfileTypeEnum.cs b/Common/Enums/Player/ProfileTypeEnum.cs new file mode 100644 index 0000000..bed54fa --- /dev/null +++ b/Common/Enums/Player/ProfileTypeEnum.cs @@ -0,0 +1,24 @@ +namespace MikuSB.Enums.Player; + +public enum ProfileShowItemTypeEnum +{ + SHOWITEM_CARD1 = 1, //第1个展示卡 + SHOWITEM_CARD2 = 2, //第2个展示卡 + SHOWITEM_CARD3 = 3, //第3个展示卡 + SHOWITEM_GIRL = 4, //看板娘 + SHOWITEM_FACE = 5, //头像 + SHOWITEM_FRAME = 6, //头像框 + SHOWITEM_CARD4 = 7, //第4个展示卡 + SHOWITEM_CARD5 = 8, //第5个展示卡 + SHOWITEM_SKIN1 = 9, //第1个展示皮肤 + SHOWITEM_SKIN2 = 10, //第2个展示皮肤 + SHOWITEM_SKIN3 = 11, //第3个展示皮肤 + SHOWITEM_SKIN4 = 12, //第4个展示皮肤 + SHOWITEM_SKIN5 = 13, //第5个展示皮肤 + SHOWITEM_BADGE1 = 14, //第一个展示勋章 + SHOWITEM_BADGE2 = 15, //第二个展示勋章 + SHOWITEM_BADGE3 = 16, //第三个展示勋章 + SHOWITEM_COVER = 17, //展示封面 + SHOWITEM_NAMECARD = 18, //展示名片 + SHOWITEM_BUBBLE = 19, //聊天气泡 +} \ No newline at end of file diff --git a/Common/Internationalization/Message/LanguageCHS.cs b/Common/Internationalization/Message/LanguageCHS.cs index 3c9fd14..48c5a50 100644 --- a/Common/Internationalization/Message/LanguageCHS.cs +++ b/Common/Internationalization/Message/LanguageCHS.cs @@ -35,6 +35,7 @@ public class ServerTextCHS /// public class WordTextCHS { + public string Profile => "个人资料"; public string WeaponSkin => "武器皮肤"; public string SupportCard => "支援卡"; public string Weapon => "武器"; @@ -240,7 +241,8 @@ public class GiveAllTextCHS "注意:-1 表示全部"; public string Usage => "用法:/giveall weapon -p<特定> -l<等級>\n" + "用法:/giveall weaponskin -p<特定>\n" + - "用法:/giveall card -p<特定> -l<等級>"; + "用法:/giveall card -p<特定> -l<等級>" + + "用法:/giveall profile -g<类型> -p<特定> -l<等级>"; public string NotFound => "未找到 {0}!"; public string GiveAllItems => "已向玩家添加 {0} 个 {1}!"; } diff --git a/Common/Internationalization/Message/LanguageCHT.cs b/Common/Internationalization/Message/LanguageCHT.cs index 03d7eb1..e025fb6 100644 --- a/Common/Internationalization/Message/LanguageCHT.cs +++ b/Common/Internationalization/Message/LanguageCHT.cs @@ -35,6 +35,7 @@ public class ServerTextCHT /// public class WordTextCHT { + public string Profile => "個人資料"; public string WeaponSkin => "武器外觀"; public string SupportCard => "支援卡"; public string Weapon => "武器"; @@ -240,7 +241,8 @@ public class GiveAllTextCHT "注意:-1 表示全部"; public string Usage => "用法:/giveall weapon -p<特定> -l<等級>\n" + "用法:/giveall weaponskin -p<特定>\n" + - "用法:/giveall card -p<特定> -l<等級>"; + "用法:/giveall card -p<特定> -l<等級>" + + "用法:/giveall profile -g<類型> -p<特定> -l<等級>"; public string NotFound => "未找到 {0}!"; public string GiveAllItems => "已向玩家添加 {0} 個 {1}!"; } diff --git a/Common/Internationalization/Message/LanguageEN.cs b/Common/Internationalization/Message/LanguageEN.cs index 302cc30..a0121b6 100644 --- a/Common/Internationalization/Message/LanguageEN.cs +++ b/Common/Internationalization/Message/LanguageEN.cs @@ -35,6 +35,7 @@ public class ServerTextEN /// public class WordTextEN { + public string Profile => "Profile"; public string WeaponSkin => "Weapon Skin"; public string Valk => "Valkyrie"; public string Material => "Material"; @@ -206,7 +207,8 @@ public class GiveAllTextEN "Note: -1 means all"; public string Usage => "Usage: /giveall weapon -p -l\n" + "Usage: /giveall weaponskin -p\n" + - "Usage: /giveall card -p -l"; + "Usage: /giveall card -p -l" + + "Usage: /giveall profile -g -p -l"; public string NotFound => "{0} not found!"; public string GiveAllItems => "Added {0} {1} to player!"; } diff --git a/GameServer/Command/Commands/CommandGiveAll.cs b/GameServer/Command/Commands/CommandGiveAll.cs index fb4a8bd..65977d3 100644 --- a/GameServer/Command/Commands/CommandGiveAll.cs +++ b/GameServer/Command/Commands/CommandGiveAll.cs @@ -96,7 +96,7 @@ public class CommandGiveAll : ICommands foreach (var config in GameData.WeaponSkinData.Values) { var weaponSkin = await player.InventoryManager! - .AddWeaponSkinItem((ItemTypeEnum)config.Genre, config.Detail, config.Particular, 1, false); + .AddWeaponSkinItem((ItemTypeEnum)config.Genre, config.Detail, config.Particular, config.Level, false); if (weaponSkin != null) weaponSkins.Add(weaponSkin); } } @@ -114,4 +114,40 @@ public class CommandGiveAll : ICommands await arg.SendMsg(I18NManager.Translate("Game.Command.GiveAll.GiveAllItems", I18NManager.Translate("Word.WeaponSkin"), weaponSkins.Count.ToString())); } + + [CommandMethod("profile")] + public async ValueTask GiveAllProfile(CommandArg arg) + { + if (!await arg.CheckOnlineTarget()) return; + if (await arg.GetOption('p') is not int particular) return; + if (await arg.GetOption('l') is not int level) return; + if (await arg.GetOption('g') is not int genre) return; + + var detail = arg.GetInt(0); + var player = arg.Target!.Player!; + List profileItems = []; + if (detail == -1) + { + // add all + foreach (var config in GameData.ProfileData.Values) + { + var profile = await player.InventoryManager! + .AddProfileItem((ItemTypeEnum)config.Genre, config.Detail, config.Particular, config.Level, false); + if (profile != null) profileItems.Add(profile); + } + } + else + { + var profile = await player.InventoryManager!.AddProfileItem((ItemTypeEnum)genre, (uint)detail, (uint)particular, (uint)level, false); + if (profile == null) + { + await arg.SendMsg(I18NManager.Translate("Game.Command.GiveAll.NotFound", I18NManager.Translate("Word.Profile"))); + return; + } + profileItems.Add(profile); + } + if (profileItems.Count > 0) await player.SendPacket(new PacketNtfCallScript(profileItems)); + await arg.SendMsg(I18NManager.Translate("Game.Command.GiveAll.GiveAllItems", + I18NManager.Translate("Word.Profile"), profileItems.Count.ToString())); + } } \ No newline at end of file diff --git a/GameServer/Game/Inventory/InventoryManager.cs b/GameServer/Game/Inventory/InventoryManager.cs index fc9b088..f83d094 100644 --- a/GameServer/Game/Inventory/InventoryManager.cs +++ b/GameServer/Game/Inventory/InventoryManager.cs @@ -25,7 +25,7 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) UniqueId = InventoryData.NextUniqueUid++, Level = weaponLevel, Break = GetWeaponBreak(weaponLevel), - ItemType = ItemTypeEnum.TYPE_WEAPON, + ItemType = genre, ItemCount = 1 }; InventoryData.Weapons[weaponInfo.UniqueId] = weaponInfo; @@ -67,13 +67,13 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) if (genre != ItemTypeEnum.TYPE_CARD_SKIN) return null; var skinData = GameData.CardSkinData.Values.FirstOrDefault(x => x.Genre == (int)genre && x.Detail == detail && x.Particular == particular && x.Level == level); if (skinData == null) return null; - var templateId = GameResourceTemplateId.FromGdpl((uint)genre,detail,particular,level); + if (InventoryData.Items.Values.Any(x => x.TemplateId == templateId)) return null; var skinInfo = new GameSkinInfo { TemplateId = templateId, UniqueId = InventoryData.NextUniqueUid++, - ItemType = ItemTypeEnum.TYPE_CARD_SKIN, + ItemType = genre, ItemCount = 1 }; InventoryData.Skins[skinInfo.UniqueId] = skinInfo; @@ -111,7 +111,7 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) { TemplateId = templateId, UniqueId = InventoryData.NextUniqueUid++, - ItemType = ItemTypeEnum.TYPE_AR, + ItemType = genre, ItemCount = 1 }; InventoryData.Items[arInfo.UniqueId] = arInfo; @@ -171,7 +171,7 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) { TemplateId = templateId, UniqueId = InventoryData.NextUniqueUid++, - ItemType = ItemTypeEnum.TYPE_MANIFESTATION, + ItemType = genre, ItemCount = 1 }; InventoryData.Items[manifestInfo.UniqueId] = manifestInfo; @@ -240,7 +240,7 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) { TemplateId = templateId, UniqueId = InventoryData.NextUniqueUid++, - ItemType = ItemTypeEnum.TYPE_WEAPON_SKIN, + ItemType = genre, ItemCount = 1 }; InventoryData.Items[skinInfo.UniqueId] = skinInfo; @@ -249,4 +249,25 @@ public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) return skinInfo; } + + public async ValueTask AddProfileItem(ItemTypeEnum genre, uint detail, uint particular, uint level = 1, bool sendPacket = true) + { + if (genre < ItemTypeEnum.TYPE_PROFILE || genre > ItemTypeEnum.TYPE_ANALYST) return null; + var profileData = GameData.ProfileData.Values.FirstOrDefault(x => x.Genre == (int)genre && x.Detail == detail && x.Particular == particular && x.Level == level); + if (profileData == null) return null; + var templateId = GameResourceTemplateId.FromGdpl((uint)genre, detail, particular, level); + if (InventoryData.Items.Values.Any(x => x.TemplateId == templateId)) return null; + var profileInfo = new BaseGameItemInfo + { + TemplateId = templateId, + UniqueId = InventoryData.NextUniqueUid++, + ItemType = genre, + ItemCount = 1 + }; + InventoryData.Items[profileInfo.UniqueId] = profileInfo; + + if (sendPacket) await Player.SendPacket(new PacketNtfCallScript([profileInfo])); + + return profileInfo; + } } \ No newline at end of file diff --git a/GameServer/Server/CallGS/Handlers/Daily/Daily_SetSelectSuit.cs b/GameServer/Server/CallGS/Handlers/Daily/Daily_SetSelectSuit.cs index 2d51857..d233aba 100644 --- a/GameServer/Server/CallGS/Handlers/Daily/Daily_SetSelectSuit.cs +++ b/GameServer/Server/CallGS/Handlers/Daily/Daily_SetSelectSuit.cs @@ -11,7 +11,7 @@ public class Daily_SetSelectSuit : ICallGSHandler var req = JsonSerializer.Deserialize(param); if (req == null) { - await CallGSRouter.SendScript(connection, "GirlWeaponSkin_Change", "{}"); + await CallGSRouter.SendScript(connection, "Daily_SetSelectSuit", "{}"); return; } var rsp = $"{{\"SuitId\":{req.Suit}}}"; diff --git a/GameServer/Server/CallGS/Handlers/Girl/GirlWeaponSkin_Change.cs b/GameServer/Server/CallGS/Handlers/Girl/GirlWeaponSkin_Change.cs index 01708fe..14bac71 100644 --- a/GameServer/Server/CallGS/Handlers/Girl/GirlWeaponSkin_Change.cs +++ b/GameServer/Server/CallGS/Handlers/Girl/GirlWeaponSkin_Change.cs @@ -13,7 +13,7 @@ public class GirlWeaponSkin_Change : ICallGSHandler var req = JsonSerializer.Deserialize(param); if (req == null) { - await CallGSRouter.SendScript(connection, "GirlWeaponSkin_Change", "{}"); + await CallGSRouter.SendScript(connection, "GirlWeaponSkin_Change", "{\"err\":\"error.BadParam\"}"); return; } @@ -33,7 +33,7 @@ public class GirlWeaponSkin_Change : ICallGSHandler Items = { cardData.ToProto() } }; - await CallGSRouter.SendScript(connection, "GirlWeaponSkin_Change", "{}", sync); + await CallGSRouter.SendScript(connection, "GirlWeaponSkin_Change", "null", sync); } } diff --git a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_ChangeShowCard.cs b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_ChangeShowCard.cs index 1c2957f..4347bbb 100644 --- a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_ChangeShowCard.cs +++ b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_ChangeShowCard.cs @@ -1,4 +1,4 @@ -using MikuSB.Database; +using MikuSB.Enums.Player; using MikuSB.Proto; using System.Text.Json; using System.Text.Json.Serialization; @@ -8,8 +8,6 @@ namespace MikuSB.GameServer.Server.CallGS.Handlers.Misc; [CallGSApi("PlayerSetting_ChangeShowCard")] public class PlayerSetting_ChangeShowCard : ICallGSHandler { - private const int ShowItemGirlIndex = 4; - public async Task Handle(Connection connection, string param, ushort seqNo) { var player = connection.Player!; @@ -23,13 +21,9 @@ public class PlayerSetting_ChangeShowCard : ICallGSHandler await CallGSRouter.SendScript(connection, "PlayerSetting_ChangeShowCard", "{}"); return; } - - player.SetShowItem(ShowItemGirlIndex, card.Guid); - DatabaseHelper.SaveDatabaseType(player.Data); - + player.SetShowItem((int)ProfileShowItemTypeEnum.SHOWITEM_GIRL, card.Guid); var sync = new NtfSyncPlayer(); sync.ShowItems.AddRange(player.Data.ShowItems); - await CallGSRouter.SendScript(connection, "PlayerSetting_ChangeShowCard", "{}", sync); } } diff --git a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetProfileFace.cs b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetProfileFace.cs new file mode 100644 index 0000000..ed50134 --- /dev/null +++ b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetProfileFace.cs @@ -0,0 +1,49 @@ +using MikuSB.Enums.Player; +using MikuSB.Proto; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace MikuSB.GameServer.Server.CallGS.Handlers.Misc; + +[CallGSApi("PlayerSetting_SetProfileFace")] +public class PlayerSetting_SetProfileFace : ICallGSHandler +{ + public async Task Handle(Connection connection, string param, ushort seqNo) + { + var player = connection.Player!; + var req = JsonSerializer.Deserialize(param); + if (req == null) + return; + + if (req.HeadItemId > 0) + { + var item = player.InventoryManager.GetNormalItem(req.HeadItemId); + if (item == null) + { + await CallGSRouter.SendScript(connection, "PlayerSetting_SetProfileFace", "{\"err\":\"error.BadParam\"}"); + return; + } + player.SetShowItem((int)ProfileShowItemTypeEnum.SHOWITEM_FACE, item.UniqueId); + } + if (req.FrameItemId > 0) + { + var item = player.InventoryManager.GetNormalItem(req.FrameItemId); + if (item == null) + { + await CallGSRouter.SendScript(connection, "PlayerSetting_SetProfileFace", "{\"err\":\"error.BadParam\"}"); + return; + } + player.SetShowItem((int)ProfileShowItemTypeEnum.SHOWITEM_FRAME, item.UniqueId); + } + + var sync = new NtfSyncPlayer(); + sync.ShowItems.AddRange(player.Data.ShowItems); + await CallGSRouter.SendScript(connection, "PlayerSetting_SetProfileFace", "null", sync); + } +} + +internal sealed class SetProfileFaceParam +{ + [JsonPropertyName("nHeadItemID")] public uint HeadItemId { get; set; } + [JsonPropertyName("nFrameItemID")] public uint FrameItemId { get; set; } +} diff --git a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowBubble.cs b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowBubble.cs new file mode 100644 index 0000000..5922f5c --- /dev/null +++ b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowBubble.cs @@ -0,0 +1,36 @@ +using MikuSB.Enums.Player; +using MikuSB.Proto; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace MikuSB.GameServer.Server.CallGS.Handlers.Misc; + +[CallGSApi("PlayerSetting_SetShowBubble")] +public class PlayerSetting_SetShowBubble : ICallGSHandler +{ + public async Task Handle(Connection connection, string param, ushort seqNo) + { + var player = connection.Player!; + var req = JsonSerializer.Deserialize(param); + if (req == null) + return; + + var item = player.InventoryManager.GetNormalItem(req.Id); + if (item == null) + { + await CallGSRouter.SendScript(connection, "PlayerSetting_SetShowBubble", "{\"err\":\"error.BadParam\"}"); + return; + } + + player.SetShowItem((int)ProfileShowItemTypeEnum.SHOWITEM_BUBBLE, item.UniqueId); + var sync = new NtfSyncPlayer(); + sync.ShowItems.AddRange(player.Data.ShowItems); + await CallGSRouter.SendScript(connection, "PlayerSetting_SetShowBubble", "null", sync); + } +} + +internal sealed class SetShowBubbleParam +{ + [JsonPropertyName("nID")] + public uint Id { get; set; } +} diff --git a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowCover.cs b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowCover.cs new file mode 100644 index 0000000..c1b7315 --- /dev/null +++ b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowCover.cs @@ -0,0 +1,36 @@ +using MikuSB.Enums.Player; +using MikuSB.Proto; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace MikuSB.GameServer.Server.CallGS.Handlers.Misc; + +[CallGSApi("PlayerSetting_SetShowCover")] +public class PlayerSetting_SetShowCover : ICallGSHandler +{ + public async Task Handle(Connection connection, string param, ushort seqNo) + { + var player = connection.Player!; + var req = JsonSerializer.Deserialize(param); + if (req == null) + return; + + var item = player.InventoryManager.GetNormalItem(req.Id); + if (item == null) + { + await CallGSRouter.SendScript(connection, "PlayerSetting_SetShowCover", "{\"err\":\"error.BadParam\"}"); + return; + } + + player.SetShowItem((int)ProfileShowItemTypeEnum.SHOWITEM_COVER, item.UniqueId); + var sync = new NtfSyncPlayer(); + sync.ShowItems.AddRange(player.Data.ShowItems); + await CallGSRouter.SendScript(connection, "PlayerSetting_SetShowCover", "null", sync); + } +} + +internal sealed class SetShowCoverParam +{ + [JsonPropertyName("nID")] + public uint Id { get; set; } +} diff --git a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowNameCard.cs b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowNameCard.cs new file mode 100644 index 0000000..e1846ff --- /dev/null +++ b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowNameCard.cs @@ -0,0 +1,36 @@ +using MikuSB.Enums.Player; +using MikuSB.Proto; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace MikuSB.GameServer.Server.CallGS.Handlers.Misc; + +[CallGSApi("PlayerSetting_SetShowNameCard")] +public class PlayerSetting_SetShowNameCard : ICallGSHandler +{ + public async Task Handle(Connection connection, string param, ushort seqNo) + { + var player = connection.Player!; + var req = JsonSerializer.Deserialize(param); + if (req == null) + return; + + var item = player.InventoryManager.GetNormalItem(req.Id); + if (item == null) + { + await CallGSRouter.SendScript(connection, "PlayerSetting_SetShowNameCard", "{\"err\":\"error.BadParam\"}"); + return; + } + + player.SetShowItem((int)ProfileShowItemTypeEnum.SHOWITEM_NAMECARD, item.UniqueId); + var sync = new NtfSyncPlayer(); + sync.ShowItems.AddRange(player.Data.ShowItems); + await CallGSRouter.SendScript(connection, "PlayerSetting_SetShowNameCard", "null", sync); + } +} + +internal sealed class SetShowNameCardParam +{ + [JsonPropertyName("nID")] + public uint Id { get; set; } +}