From bdb4ee3d5143b64e44e68c13a02e692b8f29ea9b Mon Sep 17 00:00:00 2001 From: Kei-Luna Date: Sat, 9 May 2026 20:03:28 +0900 Subject: [PATCH] Implement saving settings --- GameServer/Game/Player/PlayerInstance.cs | 23 ++++++++++- .../Misc/PlayerSetting_ChangeShowCard.cs | 2 + .../Misc/PlayerSetting_SetProfileFace.cs | 5 ++- .../Misc/PlayerSetting_SetShowBadge.cs | 5 ++- .../Misc/PlayerSetting_SetShowBubble.cs | 5 ++- .../Misc/PlayerSetting_SetShowCover.cs | 5 ++- .../Misc/PlayerSetting_SetShowNameCard.cs | 5 ++- .../CallGS/Handlers/Misc/SettingChange.cs | 39 +++++++++++++++++++ .../Packet/Recv/Player/HandlerNtfSetAttr.cs | 10 ++++- .../Recv/Player/HandlerNtfSetStrAttr.cs | 19 +++++++++ version.txt | 2 +- 11 files changed, 110 insertions(+), 10 deletions(-) create mode 100644 GameServer/Server/CallGS/Handlers/Misc/SettingChange.cs create mode 100644 GameServer/Server/Packet/Recv/Player/HandlerNtfSetStrAttr.cs diff --git a/GameServer/Game/Player/PlayerInstance.cs b/GameServer/Game/Player/PlayerInstance.cs index 1b77b98..d73230c 100644 --- a/GameServer/Game/Player/PlayerInstance.cs +++ b/GameServer/Game/Player/PlayerInstance.cs @@ -1,4 +1,4 @@ -using Google.Protobuf; +using Google.Protobuf; using MikuSB.Data; using MikuSB.Database; using MikuSB.Database.Account; @@ -230,6 +230,11 @@ public class PlayerInstance(PlayerGameData data) proto.Attrs[ToShiftedAttrKey(gid, sid)] = val; } + foreach (var x in Data.StrAttrs) + { + proto.StrAttrs[ToShiftedAttrKey(x.Gid, x.Sid)] = x.Val; + } + proto.ShowItems.AddRange(Data.ShowItems); return proto; @@ -251,6 +256,22 @@ public class PlayerInstance(PlayerGameData data) Data.ShowItems[index - 1] = itemId; } + public void SetStrAttr(uint gid, uint sid, string value) + { + var attr = Data.StrAttrs.FirstOrDefault(x => x.Gid == gid && x.Sid == sid); + if (attr == null) + { + attr = new PlayerStrAttr + { + Gid = gid, + Sid = sid + }; + Data.StrAttrs.Add(attr); + } + + attr.Val = value; + } + public uint ToPackedAttrKey(uint gid, uint sid) { if (gid == 0) diff --git a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_ChangeShowCard.cs b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_ChangeShowCard.cs index 4347bbb..848b27d 100644 --- a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_ChangeShowCard.cs +++ b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_ChangeShowCard.cs @@ -1,3 +1,4 @@ +using MikuSB.Database; using MikuSB.Enums.Player; using MikuSB.Proto; using System.Text.Json; @@ -22,6 +23,7 @@ public class PlayerSetting_ChangeShowCard : ICallGSHandler return; } player.SetShowItem((int)ProfileShowItemTypeEnum.SHOWITEM_GIRL, card.Guid); + DatabaseHelper.SaveDatabaseType(player.Data); 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 index ed50134..752c435 100644 --- a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetProfileFace.cs +++ b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetProfileFace.cs @@ -1,4 +1,5 @@ -using MikuSB.Enums.Player; +using MikuSB.Database; +using MikuSB.Enums.Player; using MikuSB.Proto; using System.Text.Json; using System.Text.Json.Serialization; @@ -35,7 +36,7 @@ public class PlayerSetting_SetProfileFace : ICallGSHandler } player.SetShowItem((int)ProfileShowItemTypeEnum.SHOWITEM_FRAME, item.UniqueId); } - + DatabaseHelper.SaveDatabaseType(player.Data); var sync = new NtfSyncPlayer(); sync.ShowItems.AddRange(player.Data.ShowItems); await CallGSRouter.SendScript(connection, "PlayerSetting_SetProfileFace", "null", sync); diff --git a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowBadge.cs b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowBadge.cs index 4dab8bb..77ce43d 100644 --- a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowBadge.cs +++ b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowBadge.cs @@ -1,4 +1,5 @@ -using MikuSB.Enums.Player; +using MikuSB.Database; +using MikuSB.Enums.Player; using MikuSB.Proto; using System.Text.Json; using System.Text.Json.Serialization; @@ -30,6 +31,8 @@ public class PlayerSetting_SetShowBadge : ICallGSHandler player.SetShowItem((int)slots[i], uniqueId); } + DatabaseHelper.SaveDatabaseType(player.Data); + var sync = new NtfSyncPlayer(); sync.ShowItems.AddRange(player.Data.ShowItems); await CallGSRouter.SendScript(connection, "PlayerSetting_SetShowBadge", "null", sync); diff --git a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowBubble.cs b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowBubble.cs index 5922f5c..5b8db81 100644 --- a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowBubble.cs +++ b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowBubble.cs @@ -1,4 +1,5 @@ -using MikuSB.Enums.Player; +using MikuSB.Database; +using MikuSB.Enums.Player; using MikuSB.Proto; using System.Text.Json; using System.Text.Json.Serialization; @@ -23,6 +24,8 @@ public class PlayerSetting_SetShowBubble : ICallGSHandler } player.SetShowItem((int)ProfileShowItemTypeEnum.SHOWITEM_BUBBLE, item.UniqueId); + DatabaseHelper.SaveDatabaseType(player.Data); + var sync = new NtfSyncPlayer(); sync.ShowItems.AddRange(player.Data.ShowItems); await CallGSRouter.SendScript(connection, "PlayerSetting_SetShowBubble", "null", sync); diff --git a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowCover.cs b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowCover.cs index c1b7315..2daa2e1 100644 --- a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowCover.cs +++ b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowCover.cs @@ -1,4 +1,5 @@ -using MikuSB.Enums.Player; +using MikuSB.Database; +using MikuSB.Enums.Player; using MikuSB.Proto; using System.Text.Json; using System.Text.Json.Serialization; @@ -23,6 +24,8 @@ public class PlayerSetting_SetShowCover : ICallGSHandler } player.SetShowItem((int)ProfileShowItemTypeEnum.SHOWITEM_COVER, item.UniqueId); + DatabaseHelper.SaveDatabaseType(player.Data); + var sync = new NtfSyncPlayer(); sync.ShowItems.AddRange(player.Data.ShowItems); await CallGSRouter.SendScript(connection, "PlayerSetting_SetShowCover", "null", sync); diff --git a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowNameCard.cs b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowNameCard.cs index e1846ff..69cb60c 100644 --- a/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowNameCard.cs +++ b/GameServer/Server/CallGS/Handlers/Misc/PlayerSetting_SetShowNameCard.cs @@ -1,4 +1,5 @@ -using MikuSB.Enums.Player; +using MikuSB.Database; +using MikuSB.Enums.Player; using MikuSB.Proto; using System.Text.Json; using System.Text.Json.Serialization; @@ -23,6 +24,8 @@ public class PlayerSetting_SetShowNameCard : ICallGSHandler } player.SetShowItem((int)ProfileShowItemTypeEnum.SHOWITEM_NAMECARD, item.UniqueId); + DatabaseHelper.SaveDatabaseType(player.Data); + var sync = new NtfSyncPlayer(); sync.ShowItems.AddRange(player.Data.ShowItems); await CallGSRouter.SendScript(connection, "PlayerSetting_SetShowNameCard", "null", sync); diff --git a/GameServer/Server/CallGS/Handlers/Misc/SettingChange.cs b/GameServer/Server/CallGS/Handlers/Misc/SettingChange.cs new file mode 100644 index 0000000..05d2228 --- /dev/null +++ b/GameServer/Server/CallGS/Handlers/Misc/SettingChange.cs @@ -0,0 +1,39 @@ +using MikuSB.Proto; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace MikuSB.GameServer.Server.CallGS.Handlers.Misc; + +[CallGSApi("SettingChange")] +public class SettingChange : ICallGSHandler +{ + private const uint PlayerSettingGid = 44; + + public async Task Handle(Connection connection, string param, ushort seqNo) + { + var changes = JsonSerializer.Deserialize>(param) ?? []; + var player = connection.Player!; + var sync = new NtfSyncPlayer(); + + foreach (var change in changes) + { + var value = player.Data.StrAttrs + .FirstOrDefault(x => x.Gid == PlayerSettingGid && x.Sid == change.Id)? + .Val; + + if (value == null) + continue; + + sync.CustomStr[player.ToShiftedAttrKey(PlayerSettingGid, change.Id)] = value; + } + + if (sync.CustomStr.Count > 0) + await connection.SendPacket(CmdIds.NtfSyncAttr, sync); + } +} + +internal sealed class SettingChangeParam +{ + [JsonPropertyName("id")] + public uint Id { get; set; } +} diff --git a/GameServer/Server/Packet/Recv/Player/HandlerNtfSetAttr.cs b/GameServer/Server/Packet/Recv/Player/HandlerNtfSetAttr.cs index c041f8e..53573da 100644 --- a/GameServer/Server/Packet/Recv/Player/HandlerNtfSetAttr.cs +++ b/GameServer/Server/Packet/Recv/Player/HandlerNtfSetAttr.cs @@ -1,4 +1,5 @@ -using MikuSB.Database.Player; +using MikuSB.Database; +using MikuSB.Database.Player; using MikuSB.Proto; namespace MikuSB.GameServer.Server.Packet.Recv.Login; @@ -12,7 +13,11 @@ public class HandlerNtfSetAttr : Handler var player = connection.Player!; var attr = player.Data.Attrs .FirstOrDefault(x => x.Gid == req.Gid && x.Sid == req.Sid); - if (attr != null) attr.Val = req.Val; + + if (attr != null) + { + attr.Val = req.Val; + } else { player.Data.Attrs.Add(new PlayerAttr @@ -22,6 +27,7 @@ public class HandlerNtfSetAttr : Handler Val = req.Val }); } + DatabaseHelper.SaveDatabaseType(player.Data); await player.OnHeartBeat(); } } diff --git a/GameServer/Server/Packet/Recv/Player/HandlerNtfSetStrAttr.cs b/GameServer/Server/Packet/Recv/Player/HandlerNtfSetStrAttr.cs new file mode 100644 index 0000000..4444a05 --- /dev/null +++ b/GameServer/Server/Packet/Recv/Player/HandlerNtfSetStrAttr.cs @@ -0,0 +1,19 @@ +using MikuSB.Database; +using MikuSB.Proto; + +namespace MikuSB.GameServer.Server.Packet.Recv.Login; + +[Opcode(CmdIds.NtfSetStrAttr)] +public class HandlerNtfSetStrAttr : Handler +{ + public override async Task OnHandle(Connection connection, byte[] data, ushort seqNo) + { + var req = NtfSetStrAttr.Parser.ParseFrom(data); + var player = connection.Player!; + + player.SetStrAttr(req.Gid, req.Sid, req.Val); + DatabaseHelper.SaveDatabaseType(player.Data); + + await player.OnHeartBeat(); + } +} diff --git a/version.txt b/version.txt index 601e3a2..0705f05 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -v=2.0 \ No newline at end of file +v=2.1 \ No newline at end of file