Implement base level packet interface

This commit is contained in:
Timothy Schenk 2022-12-29 11:23:24 +01:00
parent 9e448f8aea
commit efda5ec265
4 changed files with 65 additions and 0 deletions

View file

@ -0,0 +1,7 @@
namespace Server.Packets;
public interface IPacket
{
Span<Byte> Serialize();
void Deserialize(Span<Byte> bytes);
}

View file

@ -0,0 +1,40 @@
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;
}
}

View file

@ -0,0 +1,6 @@
namespace Server.Packets;
public enum PacketId : ushort
{
}

View file

@ -0,0 +1,12 @@
namespace Server.Packets;
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
[JetBrains.Annotations.BaseTypeRequiredAttribute(typeof(IPacket))]
public class PacketIdAttribute : Attribute
{
public PacketIdAttribute(PacketId packetId)
{
PacketId = packetId;
}
public PacketId PacketId { get; private set; }
}