feat: rewrite & revert back to manual serialization & deserialization

This commit is contained in:
Timothy Schenk 2023-08-10 22:07:58 +02:00
parent d54e2504a0
commit 9c00137904
16 changed files with 133 additions and 78 deletions

View file

@ -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

View file

@ -1,6 +1,5 @@
using System.Security.Cryptography;
using System.Text;
using MassTransit;
using MassTransit.Mediator;
using Microsoft.Extensions.Logging;
using NetCoreServer;

View file

@ -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;

View file

@ -2,4 +2,6 @@
public interface IPacket
{
}
public void Deserialize( byte[] data);
public byte[] Serialize();
}

View file

@ -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<byte> 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();
}
}

View file

@ -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;
}

View file

@ -2,5 +2,6 @@
public enum OperationCode : ushort
{
LoginInfo = 11
LoginInfo = 11,
LoginResponse = 12
}

View file

@ -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<byte> 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();
}
}

View file

@ -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,
}

View file

@ -0,0 +1,8 @@
namespace Server.Packets.Outgoing;
public struct ServerChannelData
{
public ushort ServerId;
public ushort ChannelId;
public byte LoadPercentage;
}

View file

@ -1,4 +1,4 @@
namespace Server.Packets.SerializationUtilities;
namespace Server.Packets;
public class PacketId : Attribute

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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<FieldOffsetAttribute>();
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<byte>(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]);

View file

@ -1,7 +1,7 @@
{
"sdk": {
"version": "7.0.306",
"version": "7.0.0",
"rollForward": "latestMinor",
"allowPrerelease": false
"allowPrerelease": true
}
}