From 9c001379044bc992e184182fa0a8e8eb8ea2fe94 Mon Sep 17 00:00:00 2001 From: Timothy Schenk Date: Thu, 10 Aug 2023 22:07:58 +0200 Subject: [PATCH] feat: rewrite & revert back to manual serialization & deserialization --- Continuity.sln | 6 +++ Server/ChannelSession.cs | 1 - Server/PacketHandlers/LoginInfoHandler.cs | 5 +- Server/Packets/IPacket.cs | 4 +- Server/Packets/Incoming/LoginInfoPacket.cs | 35 ++++++++++++ Server/Packets/LoginInfoPacket.cs | 11 ---- Server/Packets/OperationCode.cs | 3 +- Server/Packets/Outgoing/LoginResponse.cs | 53 +++++++++++++++++++ .../Packets/Outgoing/LoginResponseReason.cs | 19 +++++++ Server/Packets/Outgoing/ServerChannelData.cs | 8 +++ .../{SerializationUtilities => }/PacketId.cs | 2 +- .../FieldOffsetAttribute.cs | 13 ----- .../TextEncodingAttribute.cs | 13 ----- Server/Program.cs | 1 - Server/Services/PacketDistributorService.cs | 33 +----------- global.json | 4 +- 16 files changed, 133 insertions(+), 78 deletions(-) create mode 100644 Server/Packets/Incoming/LoginInfoPacket.cs delete mode 100644 Server/Packets/LoginInfoPacket.cs create mode 100644 Server/Packets/Outgoing/LoginResponse.cs create mode 100644 Server/Packets/Outgoing/LoginResponseReason.cs create mode 100644 Server/Packets/Outgoing/ServerChannelData.cs rename Server/Packets/{SerializationUtilities => }/PacketId.cs (74%) delete mode 100644 Server/Packets/SerializationUtilities/FieldOffsetAttribute.cs delete mode 100644 Server/Packets/SerializationUtilities/TextEncodingAttribute.cs diff --git a/Continuity.sln b/Continuity.sln index 0ceae62..86836c8 100644 --- a/Continuity.sln +++ b/Continuity.sln @@ -2,6 +2,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Server", "Server\Server.csproj", "{7EDA8B31-3E03-4CA3-87D1-CFEB05C277D6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmarks", "Benchmarks\Benchmarks.csproj", "{7D560FA1-A61C-4B67-8300-835CA5814621}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -12,5 +14,9 @@ Global {7EDA8B31-3E03-4CA3-87D1-CFEB05C277D6}.Debug|Any CPU.Build.0 = Debug|Any CPU {7EDA8B31-3E03-4CA3-87D1-CFEB05C277D6}.Release|Any CPU.ActiveCfg = Release|Any CPU {7EDA8B31-3E03-4CA3-87D1-CFEB05C277D6}.Release|Any CPU.Build.0 = Release|Any CPU + {7D560FA1-A61C-4B67-8300-835CA5814621}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D560FA1-A61C-4B67-8300-835CA5814621}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D560FA1-A61C-4B67-8300-835CA5814621}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D560FA1-A61C-4B67-8300-835CA5814621}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/Server/ChannelSession.cs b/Server/ChannelSession.cs index eb5c127..c29b67c 100644 --- a/Server/ChannelSession.cs +++ b/Server/ChannelSession.cs @@ -1,6 +1,5 @@ using System.Security.Cryptography; using System.Text; -using MassTransit; using MassTransit.Mediator; using Microsoft.Extensions.Logging; using NetCoreServer; diff --git a/Server/PacketHandlers/LoginInfoHandler.cs b/Server/PacketHandlers/LoginInfoHandler.cs index aa5faac..d90ac7c 100644 --- a/Server/PacketHandlers/LoginInfoHandler.cs +++ b/Server/PacketHandlers/LoginInfoHandler.cs @@ -1,10 +1,9 @@ -using CouchDB.Driver.Query.Extensions; -using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Server.DB; using Server.DB.Documents; -using Server.Packets; +using Server.Packets.Incoming; namespace Server.PacketHandlers; diff --git a/Server/Packets/IPacket.cs b/Server/Packets/IPacket.cs index 3c9d2c0..8a2c68c 100644 --- a/Server/Packets/IPacket.cs +++ b/Server/Packets/IPacket.cs @@ -2,4 +2,6 @@ public interface IPacket { -} + public void Deserialize( byte[] data); + public byte[] Serialize(); +} \ No newline at end of file diff --git a/Server/Packets/Incoming/LoginInfoPacket.cs b/Server/Packets/Incoming/LoginInfoPacket.cs new file mode 100644 index 0000000..a79f48f --- /dev/null +++ b/Server/Packets/Incoming/LoginInfoPacket.cs @@ -0,0 +1,35 @@ +using System.Text; + +namespace Server.Packets.Incoming; + +[PacketId(OperationCode.LoginInfo)] +public class LoginInfoPacket : IPacket +{ + public string Username; + + public string Password; + + public void Deserialize(byte[] data) + { + Username = Encoding.ASCII.GetString(data, 0, 20); + Password = Encoding.ASCII.GetString(data, 20, 31); + } + + public byte[] Serialize() + { + Span dataSpan = stackalloc byte[20 + 31]; + var usernameBytes = Encoding.ASCII.GetBytes(Username); + var passwordBytes = Encoding.ASCII.GetBytes(Password); + for (int i = 0; i < 20 || i < Username.Length; i++) + { + dataSpan[i] = usernameBytes[i]; + } + + for (int i = 0; i < 31 || i < Password.Length; i++) + { + dataSpan[20 + i] = passwordBytes[i]; + } + + return dataSpan.ToArray(); + } +} \ No newline at end of file diff --git a/Server/Packets/LoginInfoPacket.cs b/Server/Packets/LoginInfoPacket.cs deleted file mode 100644 index 73aceff..0000000 --- a/Server/Packets/LoginInfoPacket.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Server.Packets.SerializationUtilities; - -namespace Server.Packets; - -[PacketId(OperationCode.LoginInfo)] -public class LoginInfoPacket : IPacket -{ - [SerializationUtilities.FieldOffset(0, 20)] public string Username; - - [SerializationUtilities.FieldOffset(20, 31)] public string Password; -} \ No newline at end of file diff --git a/Server/Packets/OperationCode.cs b/Server/Packets/OperationCode.cs index a08669c..483628f 100644 --- a/Server/Packets/OperationCode.cs +++ b/Server/Packets/OperationCode.cs @@ -2,5 +2,6 @@ public enum OperationCode : ushort { - LoginInfo = 11 + LoginInfo = 11, + LoginResponse = 12 } \ No newline at end of file diff --git a/Server/Packets/Outgoing/LoginResponse.cs b/Server/Packets/Outgoing/LoginResponse.cs new file mode 100644 index 0000000..d05df53 --- /dev/null +++ b/Server/Packets/Outgoing/LoginResponse.cs @@ -0,0 +1,53 @@ +namespace Server.Packets.Outgoing; + +[PacketId(OperationCode.LoginResponse)] +public class LoginResponse : IPacket +{ + public LoginResponseReason LoginResponseReason; + public byte UnknownFlag = 1; + public bool IsGameMaster; + public ushort ChannelAmount; + + private ServerChannelData[] ChannelData; + + public void Deserialize(byte[] data) + { + LoginResponseReason = (LoginResponseReason)data[0]; + UnknownFlag = data[1]; + IsGameMaster = BitConverter.ToBoolean(data, 2); + ChannelAmount = BitConverter.ToUInt16(data, 3); + var sizeOfServerChannelData = 5; + ChannelData = Enumerable.Repeat(0, ChannelAmount).Select(i => new ServerChannelData + { + ServerId = BitConverter.ToUInt16(data, 5 + 0 + i * sizeOfServerChannelData), + ChannelId = BitConverter.ToUInt16(data, 5 + 2 + i * sizeOfServerChannelData), + LoadPercentage = data[5 + 4 + i * sizeOfServerChannelData] + }).ToArray(); + } + + public byte[] Serialize() + { + var sizeOfServerChannelData = 5; + Span dataSpan = stackalloc byte[5 + ChannelAmount * sizeOfServerChannelData]; + dataSpan.Fill(0); + dataSpan[0] = (byte)LoginResponseReason; + dataSpan[1] = UnknownFlag; + dataSpan[2] = BitConverter.GetBytes(IsGameMaster)[0]; + var bytesOfChannelAmount = BitConverter.GetBytes(ChannelAmount); + dataSpan[3] = bytesOfChannelAmount[0]; + dataSpan[4] = bytesOfChannelAmount[1]; + + for (var i = 0; i < ChannelAmount; i++) + { + var bytesOfServerId = BitConverter.GetBytes(ChannelData[i].ServerId); + var bytesOfChannelId = BitConverter.GetBytes(ChannelData[i].ChannelId); + dataSpan[5 + 0 + i * sizeOfServerChannelData] = bytesOfServerId[0]; + dataSpan[5 + 1 + i * sizeOfServerChannelData] = bytesOfServerId[1]; + dataSpan[5 + 2 + i * sizeOfServerChannelData] = bytesOfChannelId[0]; + dataSpan[5 + 3 + i * sizeOfServerChannelData] = bytesOfChannelId[1]; + dataSpan[5 + 4 + i * sizeOfServerChannelData] = ChannelData[i].LoadPercentage; + } + + return dataSpan.ToArray(); + } +} \ No newline at end of file diff --git a/Server/Packets/Outgoing/LoginResponseReason.cs b/Server/Packets/Outgoing/LoginResponseReason.cs new file mode 100644 index 0000000..65731b9 --- /dev/null +++ b/Server/Packets/Outgoing/LoginResponseReason.cs @@ -0,0 +1,19 @@ +namespace Server.Packets.Outgoing; + +public enum LoginResponseReason : byte +{ + OK, + AcountNotExist, + WrongPassword, + Error, + DuplicateConnection, + Suspended, + PleaseSignUp, + Suspended2, + EmailVerify, + NotCBTUser, + ServerNotFoundOrDBProblem, + LockedDuePayment, + UserDeletedBigpoint, + NoMoreTries, +} \ No newline at end of file diff --git a/Server/Packets/Outgoing/ServerChannelData.cs b/Server/Packets/Outgoing/ServerChannelData.cs new file mode 100644 index 0000000..0e61d0b --- /dev/null +++ b/Server/Packets/Outgoing/ServerChannelData.cs @@ -0,0 +1,8 @@ +namespace Server.Packets.Outgoing; + +public struct ServerChannelData +{ + public ushort ServerId; + public ushort ChannelId; + public byte LoadPercentage; +} \ No newline at end of file diff --git a/Server/Packets/SerializationUtilities/PacketId.cs b/Server/Packets/PacketId.cs similarity index 74% rename from Server/Packets/SerializationUtilities/PacketId.cs rename to Server/Packets/PacketId.cs index 0d266c3..46a3874 100644 --- a/Server/Packets/SerializationUtilities/PacketId.cs +++ b/Server/Packets/PacketId.cs @@ -1,4 +1,4 @@ -namespace Server.Packets.SerializationUtilities; +namespace Server.Packets; public class PacketId : Attribute diff --git a/Server/Packets/SerializationUtilities/FieldOffsetAttribute.cs b/Server/Packets/SerializationUtilities/FieldOffsetAttribute.cs deleted file mode 100644 index eb39015..0000000 --- a/Server/Packets/SerializationUtilities/FieldOffsetAttribute.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Server.Packets.SerializationUtilities; - -public class FieldOffsetAttribute : Attribute -{ - public int Offset { get; set; } - public int Size { get; set; } - - public FieldOffsetAttribute(int offset, int size) - { - Offset = offset; - Size = size; - } -} \ No newline at end of file diff --git a/Server/Packets/SerializationUtilities/TextEncodingAttribute.cs b/Server/Packets/SerializationUtilities/TextEncodingAttribute.cs deleted file mode 100644 index b2953e5..0000000 --- a/Server/Packets/SerializationUtilities/TextEncodingAttribute.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text; - -namespace Server.Packets.SerializationUtilities; - -public class TextEncodingAttribute : Attribute -{ - public Encoding Encoding { get; set; } - - public TextEncodingAttribute(Encoding encoding) - { - Encoding = encoding; - } -} \ No newline at end of file diff --git a/Server/Program.cs b/Server/Program.cs index 02a8d73..f414f2b 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -6,7 +6,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using Server; using Server.DB; using Server.Services; diff --git a/Server/Services/PacketDistributorService.cs b/Server/Services/PacketDistributorService.cs index 66e0264..cfb1d8a 100644 --- a/Server/Services/PacketDistributorService.cs +++ b/Server/Services/PacketDistributorService.cs @@ -1,6 +1,5 @@ using System.Collections.Concurrent; using System.Reflection; -using System.Text; using MassTransit.Internals; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -9,8 +8,6 @@ using Microsoft.VisualBasic.CompilerServices; using Newtonsoft.Json; using Server.PacketHandlers; using Server.Packets; -using Server.Packets.SerializationUtilities; -using FieldAccessException = System.FieldAccessException; namespace Server.Services; @@ -95,34 +92,8 @@ public class PacketDistributorService : IHostedService _logger.LogTrace("[{TempId}] Packet with ID: {MessageOperationCode} is being dequeued", item.Session.Id, item.OperationCode); var packetType = _packetsTypes[item.OperationCode]; - var packet = Activator.CreateInstance(packetType); - packetType.GetFields().AsParallel().ForAll(field => - { - var typeOfField = field.FieldType; - var fieldOffsetAttribute = field.GetCustomAttribute(); - if (fieldOffsetAttribute == null) - throw new FieldAccessException(); - object value; - _logger.LogDebug("Type of field of {fieldName}: {Name}", field.Name, typeOfField.Name); - value = typeOfField.Name switch - { - nameof(String) => Encoding.ASCII.GetString(item.MessageBody, fieldOffsetAttribute.Offset, - fieldOffsetAttribute.Size).TrimEnd('\0'), - "Byte[]" => new ArraySegment(item.MessageBody, fieldOffsetAttribute.Offset, - fieldOffsetAttribute.Size).ToArray(), - nameof(Boolean) => BitConverter.ToBoolean(item.MessageBody, fieldOffsetAttribute.Offset), - nameof(Byte) => item.MessageBody[fieldOffsetAttribute.Offset], - nameof(Int16) => BitConverter.ToInt16(item.MessageBody, fieldOffsetAttribute.Offset), - nameof(UInt16) => BitConverter.ToUInt16(item.MessageBody, fieldOffsetAttribute.Offset), - nameof(Int32) => BitConverter.ToInt32(item.MessageBody, fieldOffsetAttribute.Offset), - nameof(UInt32) => BitConverter.ToUInt32(item.MessageBody, fieldOffsetAttribute.Offset), - nameof(Double) => BitConverter.ToDouble(item.MessageBody, fieldOffsetAttribute.Offset), - nameof(Single) => BitConverter.ToSingle(item.MessageBody, fieldOffsetAttribute.Offset), - _ => throw new InvalidOperationException() - }; - - field.SetValue(packet, value); - }); + var packet = (IPacket)Activator.CreateInstance(packetType)!; + packet.Deserialize(item.MessageBody); var packetHandler = ActivatorUtilities.GetServiceOrCreateInstance(_serviceProvider, _packetHandlers[item.OperationCode]); diff --git a/global.json b/global.json index 4858d37..3d90901 100644 --- a/global.json +++ b/global.json @@ -1,7 +1,7 @@ { "sdk": { - "version": "7.0.306", + "version": "7.0.0", "rollForward": "latestMinor", - "allowPrerelease": false + "allowPrerelease": true } } \ No newline at end of file