continuity/Server.Packets/PacketForwardingService.cs

40 lines
No EOL
1.2 KiB
C#

using System.Collections.Immutable;
using System.Reflection;
namespace Server.Packets;
public class PacketForwardingService
{
private ImmutableDictionary<PacketId, System.Reflection.ConstructorInfo> _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<PacketIdAttribute>(), ctor: x.GetConstructor(Type.EmptyTypes)))
.Where(x => x.attr != null && x.ctor != null && x.GetType().IsAssignableFrom(typeof(IPacket)))
.ToImmutableDictionary(x => x.attr!.PacketId, x => x.ctor)!;
}
public IPacket Dispatch(Span<Byte> bytes)
{
// Get constructor according to packet id
IPacket packet = _packets[GetPacketId(bytes)].Invoke(Array.Empty<object>()) as IPacket ??
throw new InvalidOperationException();
// Slice off packet id
packet.Deserialize(bytes.Slice(2));
return packet;
}
private PacketId GetPacketId(Span<Byte> bytes)
{
PacketId id = 0;
id = (PacketId)BitConverter.ToUInt16(new[] { bytes[0], bytes[1] });
return id;
}
}