diff --git a/Server/Packets/Outgoing/LoginResponseReason.cs b/Server/Packets/Outgoing/LoginResponseReason.cs index 6ab1bb0..e58b5f6 100644 --- a/Server/Packets/Outgoing/LoginResponseReason.cs +++ b/Server/Packets/Outgoing/LoginResponseReason.cs @@ -18,7 +18,7 @@ public enum LoginResponseReason : byte NoMoreTries, XMLError12, XMLRPCError, - FileLoadFail, // Maybe more data :) + FileLoadFail, // arbitrary file load error (maybe we're able to load custom files) ThisIsNotAServiceArea, None } diff --git a/Server/Server.csproj b/Server/Server.csproj index ad6075d..20dead9 100644 --- a/Server/Server.csproj +++ b/Server/Server.csproj @@ -19,6 +19,9 @@ + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Server/Services/PacketDistributorService.cs b/Server/Services/PacketDistributorService.cs index cf91c73..93cf24c 100644 --- a/Server/Services/PacketDistributorService.cs +++ b/Server/Services/PacketDistributorService.cs @@ -1,7 +1,10 @@ namespace Server.Services; using System.Collections.Concurrent; +using System.Linq.Expressions; using System.Reflection; +using DotNext; +using DotNext.Metaprogramming; using MassTransit.Internals; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -10,13 +13,15 @@ using Microsoft.VisualBasic.CompilerServices; using Newtonsoft.Json; using PacketHandlers; using Packets; +using static DotNext.Metaprogramming.CodeGenerator; +using static DotNext.Linq.Expressions.ExpressionBuilder; public class PacketDistributorService : IHostedService { private readonly ConcurrentQueue concurrentQueue; private readonly ILogger logger; private readonly Dictionary packetHandlers; - private readonly Dictionary packetsTypes; + private readonly Dictionary> deserializationMap; private readonly IServiceProvider serviceProvider; public PacketDistributorService(ILogger logger, IServiceProvider serviceProvider) @@ -25,11 +30,28 @@ public class PacketDistributorService : IHostedService this.logger = logger; this.serviceProvider = serviceProvider; this.packetHandlers = new Dictionary(); - this.packetsTypes = new Dictionary(); + this.deserializationMap = new Dictionary>(); var executingAssembly = Assembly.GetExecutingAssembly(); - this.packetsTypes = this.GetPacketsWithId(executingAssembly); + var packetsTypes = this.GetPacketsWithId(executingAssembly); this.packetHandlers = this.GetAllPacketHandlersWithId(executingAssembly); + + foreach (var packetsType in packetsTypes) + { + var lambda = Lambda>(fun => + { + var arg = fun[0]; + var newPacket = packetsType.Value.New(); + + var packetVariable = DeclareVariable(packetsType.Value, "packet"); + Assign(packetVariable, newPacket); + Call(packetVariable, packetsType.Value.GetMethod("Deserialize"), arg); + + Return(packetVariable); + }).Compile(); + logger.LogInformation("Packet creation function created for {Opcode}", packetsType.Key); + this.deserializationMap.Add(packetsType.Key, lambda); + } } public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask; @@ -104,9 +126,7 @@ public class PacketDistributorService : IHostedService { this.logger.LogTrace("[{TempId}] Packet with ID: {MessageOperationCode} is being dequeued", item.Session.Id, item.OperationCode); - var packetType = this.packetsTypes[item.OperationCode]; - var packet = (IPacket)Activator.CreateInstance(packetType)!; - packet.Deserialize(item.MessageBody); + var packet = this.deserializationMap[item.OperationCode].Invoke(item.MessageBody); var packetHandler = ActivatorUtilities.GetServiceOrCreateInstance(this.serviceProvider, this.packetHandlers[item.OperationCode]);