diff --git a/src/Syroot.Worms.OnlineWorms.Server/Client.cs b/src/Syroot.Worms.OnlineWorms.Server/Client.cs index a05c3ce..20a424b 100644 --- a/src/Syroot.Worms.OnlineWorms.Server/Client.cs +++ b/src/Syroot.Worms.OnlineWorms.Server/Client.cs @@ -20,34 +20,25 @@ namespace Syroot.Worms.OnlineWorms.Server /// /// The representing the connection to the client. /// The instance with which this client communicates. - public Client(TcpClient tcpClient, Server server) + internal Client(TcpClient tcpClient, Server server) : base(tcpClient) { _server = server; } - // ---- METHODS (PROTECTED) ------------------------------------------------------------------------------------ + // ---- METHODS (PUBLIC) --------------------------------------------------------------------------------------- - protected override void OnPrePacketHandle(Packet packet) + public void HandleConnect(ConnectQueryPacket inPacket) { - _server.Log.Write(LogCategory.Client, $"{TcpClient.Client.RemoteEndPoint} >> {packet}"); + SendPacket(new ConnectReplyPacket + { + Unknown = _server.Name, + Unknown2 = _server.RegionName, + Version = _server.Version + }); } - protected override void OnPrePacketSend(Packet packet) - { - _server.Log.Write(LogCategory.Server, $"{TcpClient.Client.RemoteEndPoint} << {packet}"); - } - - // ---- METHODS (PRIVATE) -------------------------------------------------------------------------------------- - - private Packet HandleConnect(ConnectQueryPacket inPacket) => new ConnectReplyPacket - { - Unknown = _server.Name, - Unknown2 = _server.RegionName, - Version = _server.Version - }; - - private Packet HandleLogin(LoginQueryPacket inPacket) + public void HandleLogin(LoginQueryPacket inPacket) { LoginPlayerInfo[] playerInfos = new LoginPlayerInfo[inPacket.Logins.Length]; for (int i = 0; i < inPacket.Logins.Length; i++) @@ -60,16 +51,36 @@ namespace Syroot.Worms.OnlineWorms.Server }; } - return new LoginReplyPacket + // Send login result. + SendPacket(new LoginReplyPacket { Unknown1 = 1, LoginResult = LoginResult.Success, PlayerInfos = playerInfos - }; + }); + // Send info text. + SendPacket(new ServerInfoReplyPacket { Text = @"Welcome to the Online Worms Server. +Encoding tests are following: +Direct Sound Error로 게임 사운드가 +지원되지 않습니다. +%s님을 목록에서 삭제 \t하시겠습니까? +01234567890" }); } #if DEBUG - private Packet HandleRaw(RawQueryPacket inPacket) => null; + public void HandleRaw(RawQueryPacket inPacket) { } #endif + + // ---- METHODS (PROTECTED) ------------------------------------------------------------------------------------ + + protected override void OnPrePacketHandle(Packet packet) + { + _server.Log.Write(LogCategory.Client, $"{ TcpClient.Client.RemoteEndPoint } >> { packet }"); + } + + protected override void OnPrePacketSend(Packet packet) + { + _server.Log.Write(LogCategory.Server, $"{TcpClient.Client.RemoteEndPoint} << {packet}"); + } } } \ No newline at end of file diff --git a/src/Syroot.Worms.OnlineWorms.Server/Net/GameConnection.cs b/src/Syroot.Worms.OnlineWorms.Server/Net/GameConnection.cs index c50bd1a..4f24b49 100644 --- a/src/Syroot.Worms.OnlineWorms.Server/Net/GameConnection.cs +++ b/src/Syroot.Worms.OnlineWorms.Server/Net/GameConnection.cs @@ -102,11 +102,11 @@ namespace Syroot.Worms.OnlineWorms.Server.Net if (!_connectionClassesCache.TryGetValue(classType, out Dictionary handlerMethods)) { handlerMethods = new Dictionary(); - // Find all packet handling methods which are methods accepting and returning a specific packet. - foreach (MethodInfo method in classType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)) + // Find all packet handling methods which are methods accepting a specific packet and returning nothing. + foreach (MethodInfo method in classType.GetMethods(BindingFlags.Public | BindingFlags.Instance)) { Type inPacket = method.GetParameters().FirstOrDefault()?.ParameterType; - if (typeof(Packet).IsAssignableFrom(inPacket) && typeof(Packet).IsAssignableFrom(method.ReturnType)) + if (method.ReturnType == typeof(void) && typeof(Packet).IsAssignableFrom(inPacket)) handlerMethods.Add(inPacket, method); } _connectionClassesCache.Add(classType, handlerMethods); @@ -117,14 +117,7 @@ namespace Syroot.Worms.OnlineWorms.Server.Net private void HandlePacket(Packet inPacket) { OnPrePacketHandle(inPacket); - Type packetType = inPacket.GetType(); - - // Invoke the handler and send back any packet resulting from it. - if (_handlers[packetType].Invoke(this, new[] { inPacket }) is Packet outPacket) - { - OnPrePacketSend(outPacket); - SendPacket(outPacket); - } + _handlers[inPacket.GetType()].Invoke(this, new[] { inPacket }); } private Packet ReceivePacket() @@ -148,8 +141,10 @@ namespace Syroot.Worms.OnlineWorms.Server.Net return packet; } - private bool SendPacket(Packet packet) + protected bool SendPacket(Packet packet) { + OnPrePacketSend(packet); + // Serialize the raw packet data. _sendStream.Position = 0; packet.Serialize(_sendStream); diff --git a/src/Syroot.Worms.OnlineWorms.Server/Net/Packet.cs b/src/Syroot.Worms.OnlineWorms.Server/Net/Packet.cs index d28c03b..7f6bee9 100644 --- a/src/Syroot.Worms.OnlineWorms.Server/Net/Packet.cs +++ b/src/Syroot.Worms.OnlineWorms.Server/Net/Packet.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Linq; +using System.Net; using System.Reflection; using System.Text; @@ -76,9 +77,13 @@ namespace Syroot.Worms.OnlineWorms.Server.Net sb.Append(indent); sb.Append(enumValue.ToString()); break; + case IPAddress ipAddress: + sb.Append(indent); + sb.Append(ipAddress.ToString()); + break; default: foreach (PropertyInfo property in obj.GetType().GetProperties( - BindingFlags.Instance | BindingFlags.NonPublic)) + BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)) { // Ignore indexers. if (property.GetIndexParameters().Length > 0) diff --git a/src/Syroot.Worms.OnlineWorms.Server/Net/PacketStream.cs b/src/Syroot.Worms.OnlineWorms.Server/Net/PacketStream.cs index f91b9fb..30c50e7 100644 --- a/src/Syroot.Worms.OnlineWorms.Server/Net/PacketStream.cs +++ b/src/Syroot.Worms.OnlineWorms.Server/Net/PacketStream.cs @@ -90,6 +90,10 @@ namespace Syroot.Worms.OnlineWorms.Server.Net } } + /// + /// Reads a 2-byte length-prefixed, Windows-949 enoded string. + /// + /// The read value. internal string ReadString() { return _baseStream.ReadString(StringCoding.Int16CharCount, _win949Encoding); @@ -100,6 +104,10 @@ namespace Syroot.Worms.OnlineWorms.Server.Net return _baseStream.ReadBytes((int)(Length - Position)); } + /// + /// Writes a 2-byte length-prefixed, Windows-949 encoded string. + /// + /// The value to write. internal void WriteString(string value) { _baseStream.WriteString(value, StringCoding.Int16CharCount, _win949Encoding); diff --git a/src/Syroot.Worms.OnlineWorms.Server/Net/Packets/ServerInfoReplyPacket.cs b/src/Syroot.Worms.OnlineWorms.Server/Net/Packets/ServerInfoReplyPacket.cs new file mode 100644 index 0000000..0d10354 --- /dev/null +++ b/src/Syroot.Worms.OnlineWorms.Server/Net/Packets/ServerInfoReplyPacket.cs @@ -0,0 +1,28 @@ +using System; + +namespace Syroot.Worms.OnlineWorms.Server.Net +{ + /// + /// Represents an additional server response to a , providing informational server + /// screen text. + /// + [Packet(0x8033)] + internal class ServerInfoReplyPacket : Packet + { + // ---- PROPERTIES --------------------------------------------------------------------------------------------- + + /// + /// Gets or sets the text to display in the information box. Only the first 10 lines are read by the server. + /// + internal string Text { get; set; } + + // ---- METHODS (INTERNAL) ------------------------------------------------------------------------------------- + + internal override void Deserialize(PacketStream stream) => throw new NotImplementedException(); + + internal override void Serialize(PacketStream stream) + { + stream.WriteString(Text.Replace(Environment.NewLine, "\n")); + } + } +}