84 lines
3.3 KiB
C#
84 lines
3.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using MessagePack;
|
|
using Mistox.Attributes;
|
|
|
|
namespace Mistox {
|
|
public class DataPacket {
|
|
|
|
// The length of the packet header in bytes
|
|
public static readonly int HeaderLength = 3;
|
|
|
|
// 8b. 16b. value of datalength
|
|
// Data Packet [ Type | DataLength | Data ]
|
|
|
|
|
|
// Helper classes
|
|
public static byte[] Serialize<T>( T Object ) {
|
|
|
|
// Get your custom packet attribute to find the ID
|
|
mPacket attribute = typeof(T).GetCustomAttribute<mPacket>(false);
|
|
if (attribute == null) {
|
|
throw new Exception($"The datastructure {typeof(T).Name} is not an mPacket");
|
|
}
|
|
|
|
// Serialize the payload directly to a temporary byte array.
|
|
byte[] payloadData = MessagePackSerializer.Serialize(Object);
|
|
ushort dataLength = (ushort)payloadData.Length;
|
|
|
|
// Allocate an array for the final output (1 byte Type + 2 bytes Length + Payload)
|
|
byte[] finalPacket = new byte[HeaderLength + dataLength];
|
|
|
|
// Write the 3-byte header directly into the final array
|
|
finalPacket[0] = attribute.ID;
|
|
finalPacket[1] = (byte)((dataLength >> 8) & 0xFF); // High byte of ushort
|
|
finalPacket[2] = (byte)(dataLength & 0xFF); // Low byte of ushort
|
|
|
|
// Copy the payload directly into the final array right after the header
|
|
// This replaces all your .Join() allocations with a single ultra-fast CPU copy
|
|
Buffer.BlockCopy(payloadData, 0, finalPacket, HeaderLength, dataLength);
|
|
|
|
return finalPacket;
|
|
|
|
}
|
|
|
|
public static object Deserialize( Type PacketType, ushort DataLength, ReadOnlyMemory<byte> Data ) {
|
|
|
|
// Sanity check: Ensure the packet we received actually has the payload bytes it claims to have
|
|
if ( DataLength <= Data.Length ) {
|
|
throw new Exception("Malformed packet: Payload size mismatch.");
|
|
}
|
|
|
|
// 4. Create the low-level reader struct directly over the memory slice
|
|
var reader = new MessagePackReader(Data);
|
|
|
|
// Extract the object
|
|
dynamic obj = MessagePackSerializer.Deserialize( PacketType, ref reader, MessagePackSerializerOptions.Standard );
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fills out the NetworkPacket Lookup Dictionary
|
|
public static readonly Dictionary<byte, Type> ClientToClientPackets = new();
|
|
public static readonly Dictionary<byte, Type> ServerToClientPackets = new();
|
|
public static void BuildNetworkPacketList() {
|
|
Type[] allClasses = Assembly.GetExecutingAssembly().GetTypes();
|
|
foreach( Type cur in allClasses) {
|
|
mPacket attribute = cur.GetCustomAttribute<mPacket>(false);
|
|
if (attribute != null) {
|
|
if ( attribute.PacketUse.HasFlag(PacketUsage.ClientToClient) ) {
|
|
ClientToClientPackets[attribute.ID] = cur;
|
|
} else if ( attribute.PacketUse.HasFlag(PacketUsage.ClientToServer) ) {
|
|
ServerToClientPackets[attribute.ID] = cur;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
} |