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 Object ) { // Get your custom packet attribute to find the ID mPacket attribute = typeof(T).GetCustomAttribute(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 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 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; } } }