using System.Collections.Immutable; using System.Reflection; namespace Server.Packets; public class PacketForwardingService { private ImmutableDictionary _packets = null!; public PacketForwardingService() { InitializePackets(typeof(IPacket).Assembly); } private void InitializePackets(Assembly assembly) { // Get all types that implement IPacket and have a PacketIdAttribute _packets = assembly.GetTypes() .Select(x => (attr: x.GetCustomAttribute(), ctor: x.GetConstructor(Type.EmptyTypes))) .Where(x => x.GetType().IsAssignableTo(typeof(IPacket)) && x.GetType().IsClass) .Where(x => x.attr != null && x.ctor != null) .ToImmutableDictionary(x => x.attr!.PacketId, x => x.ctor)!; } public IPacket Dispatch(Span bytes) { // Get constructor according to packet id IPacket packet = _packets[GetPacketId(bytes)].Invoke(Array.Empty()) as IPacket ?? throw new InvalidOperationException(); // Slice off packet id packet.Deserialize(bytes.Slice(2)); return packet; } private PacketId GetPacketId(Span bytes) { var id = (PacketId)BitConverter.ToUInt16(new[] { bytes[0], bytes[1] }); return id; } }