diff --git a/BLHX.Server.Game/Connection.cs b/BLHX.Server.Game/Connection.cs index 069b641..f5dedf1 100644 --- a/BLHX.Server.Game/Connection.cs +++ b/BLHX.Server.Game/Connection.cs @@ -7,6 +7,7 @@ using ProtoBuf; using System.Buffers.Binary; using System.Net; using System.Net.Sockets; +using System.Reflection; using System.Text; namespace BLHX.Server.Game @@ -67,11 +68,15 @@ namespace BLHX.Server.Game var packet = new Packet(buf[readLen..]); c.Log(packet.command.ToString()); - var handler = PacketFactory.GetPacketHandler(packet.command); - if (handler is not null) + (PacketHandlerDelegate? handler, PacketHandlerAttribute? attr) = PacketFactory.GetPacketHandler(packet.command); + if (handler is not null && attr is not null) { handler(this, packet); - packetIdx++; + + if (!attr.IsNotifyHandler) + packetIdx++; + if (!attr.SaveDataAfterRun) + DBManager.PlayerContext.SaveChanges(); } else { @@ -120,6 +125,7 @@ namespace BLHX.Server.Game void SendPacket(Packet packet) { + c.Log(packet.command.ToString()); var ns = tcpClient.GetStream(); byte[] sendBuf = GC.AllocateUninitializedArray(Packet.LENGTH_SIZE + Packet.HEADER_SIZE + packet.bytes.Length); diff --git a/BLHX.Server.Game/GameServer.cs b/BLHX.Server.Game/GameServer.cs index c17554c..32d2ac0 100644 --- a/BLHX.Server.Game/GameServer.cs +++ b/BLHX.Server.Game/GameServer.cs @@ -2,6 +2,7 @@ using System.Net.Sockets; using BLHX.Server.Common.Data; using BLHX.Server.Common.Utils; +using BLHX.Server.Game.Managers; namespace BLHX.Server.Game { @@ -11,6 +12,7 @@ namespace BLHX.Server.Game public static readonly Dictionary connections = new(); public static readonly Logger c = new(nameof(GameServer), ConsoleColor.Magenta); public static IPEndPoint EndPoint { get; } + public static ChatManager ChatManager { get; } = new ChatManager(); static GameServer() { diff --git a/BLHX.Server.Game/Handlers/P11.cs b/BLHX.Server.Game/Handlers/P11.cs index 00363c4..b6cf15a 100644 --- a/BLHX.Server.Game/Handlers/P11.cs +++ b/BLHX.Server.Game/Handlers/P11.cs @@ -18,12 +18,11 @@ namespace BLHX.Server.Game.Handlers }); } - [PacketHandler(Command.Cs11009)] + [PacketHandler(Command.Cs11009, SaveDataAfterRun = true)] static void ChangeManifestoHandler(Connection connection, Packet packet) { var req = packet.Decode(); connection.player.Adv = req.Adv; - DBManager.PlayerContext.SaveChanges(); connection.Send(new Sc11010()); } diff --git a/BLHX.Server.Game/Handlers/P50.cs b/BLHX.Server.Game/Handlers/P50.cs index 2bc4374..02fd4b3 100644 --- a/BLHX.Server.Game/Handlers/P50.cs +++ b/BLHX.Server.Game/Handlers/P50.cs @@ -16,5 +16,23 @@ namespace BLHX.Server.Game.Handlers { connection.Send(new Sc50017()); } + + [PacketHandler(Command.Cs50102, IsNotifyHandler = true)] + static void SendMsgHandler(Connection connection, Packet packet) + { + var req = packet.Decode(); + + GameServer.ChatManager.SendChat(new() + { + Content = req.Content, + Player = new() + { + Id = connection.player.Uid, + Lv = connection.player.Level, + Name = connection.player.Name, + Display = connection.player.DisplayInfo + } + }); + } } } diff --git a/BLHX.Server.Game/Managers/ChatManager.cs b/BLHX.Server.Game/Managers/ChatManager.cs new file mode 100644 index 0000000..6a57073 --- /dev/null +++ b/BLHX.Server.Game/Managers/ChatManager.cs @@ -0,0 +1,30 @@ +using BLHX.Server.Common.Proto.p50; + +namespace BLHX.Server.Game.Managers +{ + public class ChatManager + { + List messages = []; + + public void SendChat(MsgInfo msgInfo) + { + msgInfo.Timestamp = (uint)DateTimeOffset.Now.ToUnixTimeSeconds(); + + messages.Add(msgInfo); + BroadcastChat(msgInfo); + } + + void BroadcastChat(MsgInfo msgInfo) + { + var ntf = new Sc50101() + { + Content = msgInfo.Content, + Player = msgInfo.Player, + Type = 1 + }; + + foreach (var conn in GameServer.connections.Values) + conn.Send(ntf); + } + } +} diff --git a/BLHX.Server.Game/Packet.cs b/BLHX.Server.Game/Packet.cs index f3962db..8f349f9 100644 --- a/BLHX.Server.Game/Packet.cs +++ b/BLHX.Server.Game/Packet.cs @@ -32,7 +32,7 @@ namespace BLHX.Server.Game static class PacketFactory { static readonly Logger c = new(nameof(PacketFactory), ConsoleColor.DarkGreen); - static readonly Dictionary handlers = []; + static readonly Dictionary handlers = []; static PacketFactory() { @@ -47,24 +47,37 @@ namespace BLHX.Server.Game if (handlers.ContainsKey(attr.command)) continue; - handlers.Add(attr.command, (PacketHandlerDelegate)Delegate.CreateDelegate(typeof(PacketHandlerDelegate), method)); + handlers.Add(attr.command, ((PacketHandlerDelegate)Delegate.CreateDelegate(typeof(PacketHandlerDelegate), method), attr)); c.Log($"Loaded {method.Name} for {attr.command}"); } c.Log($"{handlers.Count} packet handlers loaded!"); } - public static PacketHandlerDelegate? GetPacketHandler(Command command) + public static (PacketHandlerDelegate?, PacketHandlerAttribute?) GetPacketHandler(Command command) { handlers.TryGetValue(command, out var handler); - return handler; + return ((PacketHandlerDelegate, PacketHandlerAttribute)?)handler ?? (null, null)!; } } delegate void PacketHandlerDelegate(Connection connection, Packet packet); + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] - class PacketHandlerAttribute(Command command) : Attribute + class PacketHandlerAttribute : Attribute { - public Command command = command; + public Command command; + + /// + /// Some packets that sent by the client doensn't need a reply. + /// It's important for such packet doesnt increment the packet id counter, example for such packet is Cs12299 & Cs50102 + /// + public bool IsNotifyHandler { get; init; } + public bool SaveDataAfterRun { get; init; } + + public PacketHandlerAttribute(Command command) + { + this.command = command; + } } }