Files
GameServer/MistoxServer/mPacket/DataPacket.cs
T

71 lines
2.8 KiB
C#

using System;
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( byte PacketByte, ushort DataLength, ReadOnlyMemory<byte> Data ) {
// Get the type from the tag
if (!NetworkPacketDictionary.ServerToClientPackets.TryGetValue(PacketByte, out Type resolvedType)) {
throw new Exception($"Unknown packet type ID: {PacketByte}");
}
// 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.");
}
// Make sure the data is exactly the size requested
ReadOnlyMemory<byte> payloadSlice = Data.Slice(0, DataLength);
// Create the low-level reader struct directly over the memory slice
var reader = new MessagePackReader(payloadSlice);
// Extract the object
dynamic obj = MessagePackSerializer.Deserialize( resolvedType, ref reader, MessagePackSerializerOptions.Standard );
return obj;
}
}
}