Completely rework the network stack for faster lower latency messages
This commit is contained in:
1 parent
a689f2656f
commit
ca39e184ed
7 files changed
+133
-129
No files matched your search
@@ -1,9 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using MessagePack;
|
||||
using Mistox.Attributes;
|
||||
using MsgPack.Serialization;
|
||||
|
||||
namespace Mistox {
|
||||
public class DataPacket {
|
||||
@@ -11,52 +10,72 @@ namespace Mistox {
|
||||
// The length of the packet header in bytes
|
||||
public static readonly int HeaderLength = 3;
|
||||
|
||||
// Data Packet Properties
|
||||
public byte PacketType { get; set; } = 0x00;
|
||||
public ushort DataLength { get; set; } = 0;
|
||||
public byte[] PacketData { get; set; } = [];
|
||||
|
||||
|
||||
|
||||
|
||||
// 8b. 16b. ?
|
||||
// Data Packet [ Type | DataLength | Data ]
|
||||
// 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);
|
||||
DataPacket packet = new DataPacket();
|
||||
if (attribute != null) {
|
||||
using ( MemoryStream stream = new MemoryStream() ) {
|
||||
MessagePackSerializer serializer = MessagePackSerializer.Get<T>();
|
||||
serializer.Pack( stream, Object );
|
||||
packet.PacketData = stream.ToArray();
|
||||
packet.DataLength = (ushort)packet.PacketData.Length;
|
||||
return new byte[]{ packet.PacketType }.Join( BitConverter.GetBytes( packet.DataLength )).Join(packet.PacketData);
|
||||
}
|
||||
if (attribute == null) {
|
||||
throw new Exception($"The datastructure {typeof(T).Name} is not an mPacket");
|
||||
}
|
||||
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 object Deserialize() {
|
||||
Type type = Type.GetType( NetworkPackets[PacketType] );
|
||||
MessagePackSerializer Serilizer = MessagePackSerializer.Get(type);
|
||||
using( MemoryStream ms = new MemoryStream( PacketData ) ) {
|
||||
return Serilizer.Unpack( ms );
|
||||
public static object Deserialize( byte 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.");
|
||||
}
|
||||
|
||||
// Get the type from the tag
|
||||
if (!NetworkPackets.TryGetValue(PacketType, out Type resolvedType)) {
|
||||
throw new Exception($"Unknown packet type ID: {PacketType}");
|
||||
}
|
||||
|
||||
// 4. Create the low-level reader struct directly over the memory slice
|
||||
var reader = new MessagePackReader(Data);
|
||||
|
||||
// Extract the object
|
||||
dynamic obj = MessagePackSerializer.Deserialize( resolvedType, ref reader, MessagePackSerializerOptions.Standard );
|
||||
|
||||
return obj;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Fills out the NetworkPacket Lookup Dictionary
|
||||
public static readonly Dictionary<byte, string> NetworkPackets = new();
|
||||
public static readonly Dictionary<byte, Type> NetworkPackets = new();
|
||||
public static void BuildNetworkPacketList() {
|
||||
Type[] allClasses = Assembly.GetExecutingAssembly().GetTypes();
|
||||
foreach( Type cur in allClasses) {
|
||||
mPacket attribute = cur.GetCustomAttribute<mPacket>(false);
|
||||
if (attribute != null) {
|
||||
NetworkPackets[attribute.ID] = cur.FullName + "," + cur.Assembly.FullName;
|
||||
NetworkPackets[attribute.ID] = cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user