diff --git a/Common/Configuration/ConfigContainer.cs b/Common/Configuration/ConfigContainer.cs index 457e576..7746237 100644 --- a/Common/Configuration/ConfigContainer.cs +++ b/Common/Configuration/ConfigContainer.cs @@ -14,6 +14,7 @@ public class HttpServerConfig public string BindAddress { get; set; } = "0.0.0.0"; public string PublicAddress { get; set; } = "127.0.0.1"; public int Port { get; set; } = 21500; + public bool EnableLog { get; set; } = true; public string GetDisplayAddress() { diff --git a/Common/Data/Excel/CardExcel.cs b/Common/Data/Excel/CardExcel.cs new file mode 100644 index 0000000..5ddbf79 --- /dev/null +++ b/Common/Data/Excel/CardExcel.cs @@ -0,0 +1,31 @@ +using Newtonsoft.Json; + +namespace MikuSB.Data.Excel; + +[ResourceEntity("card.json")] +public class CardExcel : ExcelResource +{ + public uint Genre { get; set; } + public uint Detail { get; set; } + public uint Particular { get; set; } + public uint Level { get; set; } + public uint Icon { get; set; } + public uint InitBreak { get; set; } + public int BreakMatID { get; set; } + public int LevelLimitID { get; set; } + public int GrowupID { get; set; } + public int AppearID { get; set; } + public List DefaultWeaponGPDL { get; set; } = []; + [JsonProperty("profile")] public List> Profile { get; set; } = []; + public List> Pieces { get; set; } = []; + public List Attribute { get; set; } = []; + public override uint GetId() + { + return Icon; + } + + public override void Loaded() + { + GameData.CardData.Add(Icon, this); + } +} \ No newline at end of file diff --git a/Common/Data/Excel/CardSkinExcel.cs b/Common/Data/Excel/CardSkinExcel.cs new file mode 100644 index 0000000..ee0d8fe --- /dev/null +++ b/Common/Data/Excel/CardSkinExcel.cs @@ -0,0 +1,24 @@ +using Newtonsoft.Json; + +namespace MikuSB.Data.Excel; + +[ResourceEntity("card_skin.json")] +public class CardSkinExcel : ExcelResource +{ + public uint Genre { get; set; } + public uint Detail { get; set; } + public uint Particular { get; set; } + public uint Level { get; set; } + public uint Icon { get; set; } + public int AppearID { get; set; } + [JsonProperty("profile")] public List> Profile { get; set; } = []; + public override uint GetId() + { + return Icon; + } + + public override void Loaded() + { + GameData.CardSkinData.Add(Icon, this); + } +} \ No newline at end of file diff --git a/Common/Data/Excel/WeaponExcel.cs b/Common/Data/Excel/WeaponExcel.cs new file mode 100644 index 0000000..f9d2113 --- /dev/null +++ b/Common/Data/Excel/WeaponExcel.cs @@ -0,0 +1,29 @@ +namespace MikuSB.Data.Excel; + +[ResourceEntity("weapon.json")] +public class WeaponExcel : ExcelResource +{ + public uint Genre { get; set; } + public uint Detail { get; set; } + public uint Particular { get; set; } + public uint Level { get; set; } + public int Class { get; set; } + public uint Icon { get; set; } + public int EvolutionMatID { get; set; } + public int BreakMatID { get; set; } + public int LevelLimitID { get; set; } + public int BreakLimitID { get; set; } + public int AppearID { get; set; } + public List DefaultSkillID { get; set; } = []; + public List WeaponPartsLimit { get; set; } = []; + public string I18n { get; set; } = ""; + public override uint GetId() + { + return (uint)I18n.GetHashCode(); + } + + public override void Loaded() + { + GameData.WeaponData.Add(GetId(), this); + } +} \ No newline at end of file diff --git a/Common/Data/GameData.cs b/Common/Data/GameData.cs index a0fc47d..b923995 100644 --- a/Common/Data/GameData.cs +++ b/Common/Data/GameData.cs @@ -1,5 +1,19 @@ -namespace MikuSB.Data; +using MikuSB.Data.Excel; + +namespace MikuSB.Data; public static class GameData { + public static Dictionary CardData { get; private set; } = []; + public static Dictionary WeaponData { get; private set; } = []; + public static Dictionary CardSkinData { get; private set; } = []; +} + +public static class GameResourceTemplateId +{ + public static ulong FromGdpl(uint genre, uint detail, uint particular, uint level) => + ((ulong)genre << 48) | ((ulong)detail << 32) | ((ulong)particular << 16) | level; + + public static ulong FromGdpl(IReadOnlyList gdpl) => + gdpl.Count >= 4 ? FromGdpl(gdpl[0], gdpl[1], gdpl[2], gdpl[3]) : 0; } \ No newline at end of file diff --git a/Common/Database/Character/CharacterData.cs b/Common/Database/Character/CharacterData.cs new file mode 100644 index 0000000..2d1bf24 --- /dev/null +++ b/Common/Database/Character/CharacterData.cs @@ -0,0 +1,50 @@ +using MikuSB.Proto; +using SqlSugar; + +namespace MikuSB.Database.Character; + +[SugarTable("character_data")] +public class CharacterData : BaseDatabaseDataHelper +{ + [SugarColumn(IsJson = true)] public List Characters { get; set; } = []; + public uint NextCharacterGuid { get; set; } = 0; +} + +public class CharacterInfo +{ + public uint Guid { get; set; } + public ulong TemplateId { get; set; } + public uint Level { get; set; } + public int Exp { get; set; } + public uint Break { get; set; } + public int Evolue { get; set; } + public int Trust { get; set; } + public uint WeaponUniqueId { get; set; } + public uint SkinId { get; set; } + [SugarColumn(IsJson = true)] public List UnlockedSkin { get; set; } = []; + [SugarColumn(IsJson = true)] public List Spines { get; set; } = []; + [SugarColumn(IsJson = true)] public List Affixs { get; set; } = []; + public long Timestamp { get; set; } + public uint Count { get; set; } = 1; + + public Item ToProto() + { + var proto = new Item + { + Id = Guid, + Template = TemplateId, + Count = Count, + Enhance = new Enhance + { + Level = Level, + Break = Break + } + }; + + proto.Slots[4] = WeaponUniqueId; + proto.Slots[5] = SkinId; + + return proto; + } + +} \ No newline at end of file diff --git a/Common/Database/Inventory/InventoryData.cs b/Common/Database/Inventory/InventoryData.cs new file mode 100644 index 0000000..6ef1959 --- /dev/null +++ b/Common/Database/Inventory/InventoryData.cs @@ -0,0 +1,71 @@ +using MikuSB.Proto; +using SqlSugar; + +namespace MikuSB.Database.Inventory; + +[SugarTable("inventory_data")] +public class InventoryData : BaseDatabaseDataHelper +{ + public uint NextUniqueUid { get; set; } = 100000; + + [SugarColumn(IsJson = true)] + public Dictionary Items { get; set; } = []; // Key: UniqueId + + [SugarColumn(IsJson = true)] + public Dictionary Weapons { get; set; } = []; // Key: UniqueId + + [SugarColumn(IsJson = true)] + public Dictionary Skins { get; set; } = []; // Key: UniqueId +} + +public abstract class BaseGameItemInfo +{ + public uint UniqueId { get; set; } + public ulong TemplateId { get; set; } + public uint ItemCount { get; set; } +} + +public abstract class GrowableItemInfo : BaseGameItemInfo +{ + public bool IsLocked { get; set; } + public uint Level { get; set; } + public uint Exp { get; set; } + public uint EquipAvatarId { get; set; } +} + +public class GameWeaponInfo : GrowableItemInfo +{ + public Item ToProto() + { + var proto = new Item + { + Id = UniqueId, + Template = TemplateId, + Count = ItemCount, + Enhance = new Enhance + { + Level = Level + } + }; + return proto; + } +} + +public class GameSkinInfo : BaseGameItemInfo +{ + public uint Level { get; set; } + public Item ToProto() + { + var proto = new Item + { + Id = UniqueId, + Template = TemplateId, + Count = ItemCount, + Enhance = new Enhance + { + Level = Level + } + }; + return proto; + } +} \ No newline at end of file diff --git a/Common/Database/Player/PlayerGameData.cs b/Common/Database/Player/PlayerGameData.cs index 7decd6d..6e3ed02 100644 --- a/Common/Database/Player/PlayerGameData.cs +++ b/Common/Database/Player/PlayerGameData.cs @@ -1,5 +1,6 @@ using MikuSB.Util.Extensions; using SqlSugar; +using MikuSB.Proto; namespace MikuSB.Database.Player; @@ -12,61 +13,18 @@ public class PlayerGameData : BaseDatabaseDataHelper public int Exp { get; set; } = 0; public long RegisterTime { get; set; } = Extensions.GetUnixSec(); public long LastActiveTime { get; set; } - [SugarColumn(IsJson = true)] public List Attrs { get; set; } = []; + public Sex Gender { get; set; } = Sex.Female; + [SugarColumn(IsJson = true)] public List Attrs { get; set; } = []; public static PlayerGameData? GetPlayerByUid(long uid) { var result = DatabaseHelper.GetInstance((int)uid); return result; } - - public Proto.Player ToProto() - { - var proto = new Proto.Player - { - Pid = (ulong)Uid, - Account = Name, - Name = Name, - Level = Level, - }; - - foreach (var x in Attrs) - { - uint gid = x.Gid; - uint sid = x.Sid; - uint val = x.Val; - - if (gid == 0) - { - proto.Attrs[sid] = val; - continue; - } - - proto.Attrs[ToPackedAttrKey(gid, sid)] = val; - proto.Attrs[ToShiftedAttrKey(gid, sid)] = val; - } - - return proto; - } - - private static uint ToPackedAttrKey(uint gid, uint sid) - { - if (gid == 0) - return sid; - - return (gid * 10000) + sid; - } - - private static uint ToShiftedAttrKey(uint gid, uint sid) - { - if (gid == 0) - return sid; - - return (gid << 16) | sid; - } + } -public class PlayerAttrs +public class PlayerAttr { public uint Gid { get; set; } public uint Sid { get; set; } diff --git a/Common/Enums/Item/ItemTypeEnum.cs b/Common/Enums/Item/ItemTypeEnum.cs new file mode 100644 index 0000000..8e7be17 --- /dev/null +++ b/Common/Enums/Item/ItemTypeEnum.cs @@ -0,0 +1,28 @@ +namespace MikuSB.Enums.Item; + +public enum ItemTypeEnum +{ + TYPE_CARD = 1, // 角色卡 + TYPE_WEAPON = 2, // 武器卡 + TYPE_SUPPORT = 3, // 后勤卡 + TYPE_USEABLE = 4, // 可使用道具 + TYPE_SUPPLIES = 5, // 消耗类道具 + TYPE_WEAPON_PART = 6, // 武器配件 + TYPE_CARD_SKIN = 7, // 角色皮肤 + TYPE_HOUSE = 8, // 宿舍家具 + TYPE_PROFILE = 9, // 头像 + TYPE_FRAME = 10, // 头像框 + TYPE_BADGE = 11, // 勋章 + TYPE_COVER = 12, // 封面 + TYPE_NAMECARD = 13, // 名片 + TYPE_EXPRESSION = 14, // 表情 + TYPE_BUBBLE = 15, // 聊天气泡 + TYPE_ANALYST = 16, // 墨镜分析员 + TYPE_WEAPON_SKIN = 17, //武器皮肤 + TYPE_MONSTER_CARD = 18, //怪物卡 + TYPE_MANIFESTATION = 19, //角色皮肤互动场景道具 + TYPE_CARD_SKIN_PART = 20, //角色皮肤部件 + TYPE_MAIN_SCENE = 21, //主界面场景道具 + TYPE_AR = 24, //AR道具 + TYPE_CALL = 25, //电话陪伴道具 +} \ No newline at end of file diff --git a/GameServer/Game/Character/CharacterManager.cs b/GameServer/Game/Character/CharacterManager.cs new file mode 100644 index 0000000..a253b55 --- /dev/null +++ b/GameServer/Game/Character/CharacterManager.cs @@ -0,0 +1,54 @@ +using MikuSB.Data; +using MikuSB.Data.Excel; +using MikuSB.Database; +using MikuSB.Database.Character; +using MikuSB.Enums.Item; +using MikuSB.GameServer.Game.Player; +using MikuSB.Util.Extensions; + +namespace MikuSB.GameServer.Game.Character; + +public class CharacterManager(PlayerInstance player) : BasePlayerManager(player) +{ + public CharacterData CharacterData { get; } = DatabaseHelper.GetInstanceOrCreateNew(player.Uid); + public async ValueTask AddCharacter(ItemTypeEnum genre, uint detail, uint particular, uint level = 1) + { + var characterId = GameResourceTemplateId.FromGdpl((uint)genre,detail,particular,level); + if (CharacterData.Characters.Any(a => a.TemplateId == characterId)) return null; + var CharacterExcel = GameData.CardData.Values.FirstOrDefault(x => x.Genre == (int)genre && x.Detail == detail && x.Particular == particular); + if (CharacterExcel == null) return null; + + var character = new CharacterInfo + { + Guid = CharacterData.NextCharacterGuid++, + TemplateId = characterId, + Level = level, + Break = CharacterExcel.InitBreak, + Timestamp = Extensions.GetUnixSec(), + }; + + var weaponInfo = await Player.InventoryManager!.AddWeaponItem((ItemTypeEnum)CharacterExcel.DefaultWeaponGPDL[0], CharacterExcel.DefaultWeaponGPDL[1], CharacterExcel.DefaultWeaponGPDL[2], (uint)CharacterExcel.DefaultWeaponGPDL[3]); + if (weaponInfo != null) character.WeaponUniqueId = weaponInfo.UniqueId; + + var skinInfo = await Player.InventoryManager!.AddSkinItem(ItemTypeEnum.TYPE_CARD_SKIN,detail,particular,level); + if (skinInfo != null) + { + character.SkinId = skinInfo.UniqueId; + character.UnlockedSkin.Add(skinInfo.UniqueId); + } + + CharacterData.Characters.Add(character); + return CharacterExcel; + } + + public CharacterInfo? GetCharacter(ulong TemplateId) + { + return CharacterData.Characters.Find(Character => Character.TemplateId == TemplateId); + } + + public CharacterInfo? GetCharacterGDPL(ItemTypeEnum genre, int detail, int particular) + { + var templateId = GameResourceTemplateId.FromGdpl((uint)genre,(uint)detail,(uint)particular,1); + return CharacterData.Characters.Find(Character => Character.TemplateId == templateId); + } +} \ No newline at end of file diff --git a/GameServer/Game/Inventory/InventoryManager.cs b/GameServer/Game/Inventory/InventoryManager.cs new file mode 100644 index 0000000..6d42cc8 --- /dev/null +++ b/GameServer/Game/Inventory/InventoryManager.cs @@ -0,0 +1,82 @@ +using MikuSB.Data; +using MikuSB.Database; +using MikuSB.Database.Inventory; +using MikuSB.Enums.Item; +using MikuSB.GameServer.Game.Player; + +namespace MikuSB.GameServer.Game.Inventory; + +public class InventoryManager(PlayerInstance player) : BasePlayerManager(player) +{ + public InventoryData InventoryData { get; } = DatabaseHelper.GetInstanceOrCreateNew(player.Uid); + + public async ValueTask AddWeaponItem(ItemTypeEnum genre, uint detail, uint particular, uint level = 1) + { + if (genre != ItemTypeEnum.TYPE_WEAPON) return null; + var weaponData = GameData.WeaponData.Values.FirstOrDefault(x => x.Genre == (int)genre && x.Detail == detail && x.Particular == particular); + if (weaponData == null) return null; + + var templateId = GameResourceTemplateId.FromGdpl((uint)genre,detail,particular,level); + var weaponInfo = new GameWeaponInfo + { + TemplateId = templateId, + UniqueId = InventoryData.NextUniqueUid++, + Level = level, + ItemCount = 1 + }; + InventoryData.Weapons[weaponInfo.UniqueId] = weaponInfo; + + return weaponInfo; + } + + public GameWeaponInfo? GetWeaponItem(uint uniqueId) + { + return InventoryData.Weapons.GetValueOrDefault(uniqueId); + } + + public GameWeaponInfo? GetWeaponItemByTemplateId(ulong templateId) + { + return InventoryData.Weapons.Values.FirstOrDefault(x => x.TemplateId == templateId); + } + + public GameWeaponInfo? GetWeaponItemGDPL(ItemTypeEnum genre, int detail, int particular) + { + var templateId = GameResourceTemplateId.FromGdpl((uint)genre, (uint)detail, (uint)particular, 1); + return InventoryData.Weapons.Values.FirstOrDefault(x => x.TemplateId == templateId); + } + + public async ValueTask AddSkinItem(ItemTypeEnum genre, uint detail, uint particular, uint level = 1) + { + 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); + if (skinData == null) return null; + + var templateId = GameResourceTemplateId.FromGdpl((uint)genre,detail,particular,level); + var skinInfo = new GameSkinInfo + { + TemplateId = templateId, + UniqueId = InventoryData.NextUniqueUid++, + Level = level, + ItemCount = 1 + }; + InventoryData.Skins[skinInfo.UniqueId] = skinInfo; + + return skinInfo; + } + + public GameSkinInfo? GetSkinItem(uint uniqueId) + { + return InventoryData.Skins.GetValueOrDefault(uniqueId); + } + + public GameSkinInfo? GetSkinItemByTemplateId(ulong templateId) + { + return InventoryData.Skins.Values.FirstOrDefault(x => x.TemplateId == templateId); + } + + public GameSkinInfo? GetSkinItemGDPL(ItemTypeEnum genre, int detail, int particular) + { + var templateId = GameResourceTemplateId.FromGdpl((uint)genre, (uint)detail, (uint)particular, 1); + return InventoryData.Skins.Values.FirstOrDefault(x => x.TemplateId == templateId); + } +} \ No newline at end of file diff --git a/GameServer/Game/Player/PlayerInstance.cs b/GameServer/Game/Player/PlayerInstance.cs index 30d3613..48228a2 100644 --- a/GameServer/Game/Player/PlayerInstance.cs +++ b/GameServer/Game/Player/PlayerInstance.cs @@ -1,7 +1,12 @@ -using MikuSB.Database; +using MikuSB.Data; +using MikuSB.Database; using MikuSB.Database.Account; using MikuSB.Database.Player; +using MikuSB.Enums.Item; +using MikuSB.GameServer.Game.Character; +using MikuSB.GameServer.Game.Inventory; using MikuSB.GameServer.Server; +using MikuSB.Proto; using MikuSB.TcpSharp; using MikuSB.Util.Extensions; @@ -22,6 +27,8 @@ public class PlayerInstance(PlayerGameData data) #region Data & Manager public PlayerGameData Data { get; set; } = data; + public CharacterManager CharacterManager { get; set; } = null!; + public InventoryManager InventoryManager { get; set; } = null!; #endregion @@ -37,16 +44,47 @@ public class PlayerInstance(PlayerGameData data) var t = Task.Run(async () => { await InitialPlayerManager(); + foreach (var card in GameData.CardData.Values) await CharacterManager.AddCharacter((ItemTypeEnum)card.Genre, card.Detail, card.Particular, card.Level); + + var bootstrapAttrs = BuildLobbyBootstrapAttrs(); + var existingAttrs = Data.Attrs + .ToDictionary(x => (x.Gid, x.Sid)); + var seenAttrs = new HashSet<(uint Gid, uint Sid)>(); + + foreach (var (gid, sid, value) in bootstrapAttrs) + { + if (!seenAttrs.Add((gid, sid))) + continue; + + if (existingAttrs.TryGetValue((gid, sid), out var attr)) + { + if (attr.Val < value) + attr.Val = value; + + continue; + } + + var newAttr = new PlayerAttr + { + Gid = gid, + Sid = sid, + Val = value + }; + + Data.Attrs.Add(newAttr); + existingAttrs[(gid, sid)] = newAttr; + } }); t.Wait(); Initialized = true; - } private async ValueTask InitialPlayerManager() { Uid = Data.Uid; Data.LastActiveTime = Extensions.GetUnixSec(); + InventoryManager = new InventoryManager(this); + CharacterManager = new CharacterManager(this); await Task.CompletedTask; } @@ -94,5 +132,113 @@ public class PlayerInstance(PlayerGameData data) #region Serialization + public Proto.Player ToPlayerProto() + { + var proto = new Proto.Player + { + Pid = (ulong)Data.Uid, + Account = Data.Name, + Provider = Data.Name, + Name = Data.Name, + Level = Data.Level, + Sex = Data.Gender, + Solutions = + { + new Lineup // TODO Lineup Manager + { + Index = 1, + Name = "Default", + Member1 = 1, + Member2 = 2, + Member3 = 3 + } + }, + }; + + foreach(var weapon in InventoryManager.InventoryData.Weapons.Values) proto.Items.Add(weapon.ToProto()); + foreach (var skin in InventoryManager.InventoryData.Skins.Values) proto.Items.Add(skin.ToProto()); + foreach (var chara in CharacterManager.CharacterData.Characters) proto.Items.Add(chara.ToProto()); + + foreach (var x in Data.Attrs) + { + uint gid = x.Gid; + uint sid = x.Sid; + uint val = x.Val; + + if (gid == 0) + { + proto.Attrs[sid] = val; + continue; + } + + proto.Attrs[ToPackedAttrKey(gid, sid)] = val; + proto.Attrs[ToShiftedAttrKey(gid, sid)] = val; + } + + return proto; + } + + private static uint ToPackedAttrKey(uint gid, uint sid) + { + if (gid == 0) + return sid; + + return (gid * 10000) + sid; + } + + private static uint ToShiftedAttrKey(uint gid, uint sid) + { + if (gid == 0) + return sid; + + return (gid << 16) | sid; + } + + private static IEnumerable<(uint Gid, uint Sid, uint Value)> BuildLobbyBootstrapAttrs() + { + // GuideLogic uses group 4. Value 999 is safely above every configured step count, + // so the client treats these guides as already completed. + yield return (4, 0, 5); + yield return (11, 1, 1); + yield return (57, 0, 1); + yield return (99, 3, 30); + yield return (110, 1, 1); + yield return (178, 1, 1_700_000_000); + yield return (187, 1, 2); + + for (uint guideId = 1; guideId <= 150; guideId++) + yield return (4, guideId, 999); + + for (uint guideId = 10_000; guideId <= 10_300; guideId++) + yield return (4, guideId, 999); + + for (uint guideId = 11_000; guideId <= 11_300; guideId++) + yield return (4, guideId, 999); + + for (uint guideId = 12_000; guideId <= 12_100; guideId++) + yield return (4, guideId, 999); + + for (uint guideId = 22_000; guideId <= 22_100; guideId++) + yield return (4, guideId, 999); + + // Additional guide ids referenced directly by the Lua scripts and observed client logs. + foreach (var guideId in new uint[] { 10_031, 10_041, 10_061, 10_081, 10_101, 10_224, 11_006, 11_202, 11_210, 22_002 }) + yield return (4, guideId, 999); + + // Launch.GPASSID = 22 stores pass counts. ChapterLevel.GID = 21 stores star flags. + // Completing the prologue/early chapter range prevents function conditions from + // treating the account as a fresh tutorial player. + for (uint levelId = 10_000; levelId <= 10_160; levelId++) + { + yield return (21, levelId, 7); + yield return (22, levelId, 1); + } + + foreach (var levelId in new uint[] { 10_121, 10_122, 10_123, 50_000, 50_151 }) + { + yield return (21, levelId, 7); + yield return (22, levelId, 1); + } + } #endregion } \ No newline at end of file diff --git a/GameServer/Server/Packet/Recv/Player/HandlerNtfReadItem.cs b/GameServer/Server/Packet/Recv/Player/HandlerNtfReadItem.cs new file mode 100644 index 0000000..fd29d23 --- /dev/null +++ b/GameServer/Server/Packet/Recv/Player/HandlerNtfReadItem.cs @@ -0,0 +1,17 @@ +using Google.Protobuf; +using MikuSB.Database.Player; +using MikuSB.Proto; +using MikuSB.Util; + +namespace MikuSB.GameServer.Server.Packet.Recv.Login; + +[Opcode(CmdIds.NtfReadItem)] +public class HandlerNtfReadItem : Handler +{ + public override async Task OnHandle(Connection connection, byte[] data, ushort seqNo) + { + var req = IDArray.Parser.ParseFrom(data); + var json = JsonFormatter.Default.Format(req); + Logger.GetByClassName().Debug($"{json}"); + } +} diff --git a/GameServer/Server/Packet/Recv/Player/HandlerNtfSetAttr.cs b/GameServer/Server/Packet/Recv/Player/HandlerNtfSetAttr.cs index dbda7ac..c041f8e 100644 --- a/GameServer/Server/Packet/Recv/Player/HandlerNtfSetAttr.cs +++ b/GameServer/Server/Packet/Recv/Player/HandlerNtfSetAttr.cs @@ -15,7 +15,7 @@ public class HandlerNtfSetAttr : Handler if (attr != null) attr.Val = req.Val; else { - player.Data.Attrs.Add(new PlayerAttrs + player.Data.Attrs.Add(new PlayerAttr { Gid = req.Gid, Sid = req.Sid, diff --git a/GameServer/Server/Packet/Send/Login/PacketRspLogin.cs b/GameServer/Server/Packet/Send/Login/PacketRspLogin.cs index b683285..4c74820 100644 --- a/GameServer/Server/Packet/Send/Login/PacketRspLogin.cs +++ b/GameServer/Server/Packet/Send/Login/PacketRspLogin.cs @@ -14,7 +14,7 @@ public class PacketRspLogin : BasePacket Timestamp = (uint)Extensions.GetUnixSec(), WorldChannel = 1, AreaId = 1, - Data = player.Data.ToProto(), + Data = player.ToPlayerProto(), NeedRename = false }; diff --git a/SdkServer/Utils/LoggingMiddleware.cs b/SdkServer/Utils/LoggingMiddleware.cs index 922b7ee..6c253bd 100644 --- a/SdkServer/Utils/LoggingMiddleware.cs +++ b/SdkServer/Utils/LoggingMiddleware.cs @@ -17,7 +17,7 @@ public class RequestLoggingMiddleware(RequestDelegate next) if (path.StartsWith("/report") || path.Contains("/log/") || path == "/alive") return; - + if (!ConfigManager.Config.HttpServer.EnableLog) return; if (statusCode == 200) { logger.Info($"{method} {path} => {statusCode}");