Tons of minor fixes

This commit is contained in:
derek.holloway committed 2026-08-03 10:01:31 -07:00
1 parent 873a6fa455
commit 37a6b5d59b
12 files changed
+219 -147

No files matched your search

+40 -28
View File
@@ -1,69 +1,81 @@
using System;
using System.Buffers;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using MessagePack;
using Mistox.Attributes;
namespace Mistox {
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DataPacketHeader {
public byte Type { get; set; }
public ushort DataLength { get; set; }
}
public class DataPacket {
// The length of the packet header in bytes
public static readonly int HeaderLength = 3;
public static int HeaderLength => Unsafe.SizeOf<DataPacketHeader>();
// 8b. 16b. value of datalength
// Data Packet [ Type | DataLength | Data ]
public DataPacketHeader Header { get; set; }
public dynamic Data { get; set; }
// Helper classes
public static byte[] Serialize<T>( T Object ) {
// Get your custom packet attribute to find the ID
// Get the attribute 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;
// Use an expandable buffer writer from the system stack
var writer = new ArrayBufferWriter<byte>(256);
// Allocate an array for the final output (1 byte Type + 2 bytes Length + Payload)
byte[] finalPacket = new byte[HeaderLength + dataLength];
// Advance the writer past the 3-byte header slot so MessagePack doesn't overwrite it
writer.Advance(HeaderLength);
// 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
// Serialize the payload DIRECTLY into the final buffer memory
MessagePackSerializer.Serialize(writer, Object);
// 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);
// Build our header struct on the stack
DataPacketHeader header = new DataPacketHeader {
Type = attribute.ID,
DataLength = (ushort)(writer.WrittenCount - HeaderLength)
};
return finalPacket;
// Map the struct directly onto the 3-byte reservation we left at the front
writer.WrittenMemory.Slice(0, HeaderLength);
MemoryMarshal.Write(writer.GetSpan(HeaderLength).Slice(0, HeaderLength), in header);
// 7. Extract the finished byte array.
// Note: In a production socket pipeline, you would pass writer.WrittenMemory directly
// to the socket instead of converting it to an array here!
return writer.WrittenSpan.ToArray();
}
public static object Deserialize( byte PacketByte, ushort DataLength, ReadOnlyMemory<byte> Data ) {
public static object Deserialize( DataPacketHeader Header, 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}");
if (!NetworkPacketDictionary.ServerToClientPackets.TryGetValue(Header.Type, out Type resolvedType)) {
throw new Exception($"Unknown packet type ID: {Header.Type}");
}
// Sanity check: Ensure the packet we received actually has the payload bytes it claims to have
if ( DataLength < Data.Length ) {
// Ensure the packet we received actually has the payload bytes it claims to have
if ( Header.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);
ReadOnlyMemory<byte> payloadSlice = Data.Slice(0, Header.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;
return MessagePackSerializer.Deserialize( resolvedType, ref reader, MessagePackSerializerOptions.Standard );
}
+14 -7
View File
@@ -5,21 +5,28 @@ using Mistox.Attributes;
namespace Mistox.ResevedPackets {
[mPacket(0xFF)]
public class EntityPacket {
public ushort ObjectId { get; set; }
public byte[] InnerPayload { get; set; }
}
[mPacket(0xFE)]
public class UserConnectedPacket {
public string UserName { get; set; }
public IPAddress ClientIPAddress { get; set; }
public int ClientPort { get; set; }
}
[mPacket(0xFE)]
public class UserAuthPacket {
public string UserName { get; set; } = "";
public string ConnectionKey { get; set; } = "";
public int AuthSuccessful { get; set; } = 0; // 0 is standard, -1 is auth failure, 1 is auth success
}
[mPacket(0xFD)]
public class EntityPacket {
public ushort ObjectId { get; set; }
public byte[] InnerPayload { get; set; }
}
[mPacket(0xFC)]
public class UserDisconnectedPacket {
public UInt128 ConnectionKey { get; set; }
public string UserName { get; set; }
}
}