Change manual packet numbering to a dictionary

This commit is contained in:
derek.holloway committed 2026-08-03 10:57:17 -07:00
1 parent 37a6b5d59b
commit b83887cb2a
8 files changed
+53 -44

No files matched your search

+2 -2
View File
@@ -34,8 +34,8 @@ namespace Mistox.Client {
// Parse the header
DataPacketHeader Header = new DataPacketHeader {
Type = headerBuffer[0],
DataLength = (ushort)((headerBuffer[1] << 8) | headerBuffer[2])
Type = (ushort)((headerBuffer[0] << 8) | headerBuffer[1]),
DataLength = (ushort)((headerBuffer[2] << 8) | headerBuffer[3])
};
// Make sure the data looks valid
+2 -2
View File
@@ -31,8 +31,8 @@ namespace Mistox.Client {
// Create the packet header
DataPacketHeader Header = new DataPacketHeader {
Type = dataPacket[0],
DataLength = (ushort)((dataPacket[1] << 8) | dataPacket[2])
Type = (ushort)((dataPacket[0] << 8) | dataPacket[1]),
DataLength = (ushort)((dataPacket[2] << 8) | dataPacket[3])
};
// Slice out the data part of the packet
+2 -2
View File
@@ -43,8 +43,8 @@ namespace Mistox.Server {
// Pack the header variables for faster memory passing
DataPacketHeader Header = new DataPacketHeader {
Type = headerBuffer[0],
DataLength = (ushort)((headerBuffer[1] << 8) | headerBuffer[2])
Type = (ushort)((headerBuffer[0] << 8) | headerBuffer[1]),
DataLength = (ushort)((headerBuffer[2] << 8) | headerBuffer[3])
};
// Make sure the data looks valid
+3 -9
View File
@@ -10,7 +10,7 @@ namespace Mistox {
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct DataPacketHeader {
public byte Type { get; set; }
public ushort Type { get; set; }
public ushort DataLength { get; set; }
}
@@ -25,12 +25,6 @@ namespace Mistox {
// Helper classes
public static byte[] Serialize<T>( T Object ) {
// 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");
}
// Use an expandable buffer writer from the system stack
var writer = new ArrayBufferWriter<byte>(256);
@@ -42,7 +36,7 @@ namespace Mistox {
// Build our header struct on the stack
DataPacketHeader header = new DataPacketHeader {
Type = attribute.ID,
Type = NetworkPacketDictionary.PacketIDTable[typeof(T)],
DataLength = (ushort)(writer.WrittenCount - HeaderLength)
};
@@ -59,7 +53,7 @@ namespace Mistox {
public static object Deserialize( DataPacketHeader Header, ReadOnlyMemory<byte> Data ) {
// Get the type from the tag
if (!NetworkPacketDictionary.ServerToClientPackets.TryGetValue(Header.Type, out Type resolvedType)) {
if (!NetworkPacketDictionary.PacketLookupTable.TryGetValue(Header.Type, out Type resolvedType)) {
throw new Exception($"Unknown packet type ID: {Header.Type}");
}
+31 -10
View File
@@ -7,17 +7,38 @@ namespace Mistox.Attributes {
public class NetworkPacketDictionary {
// Fills out the NetworkPacket Lookup Dictionary
public static readonly Dictionary<byte, Type> ClientToClientPackets = new();
public static readonly Dictionary<byte, Type> ServerToClientPackets = new();
public static readonly Dictionary<ushort, Type> PacketLookupTable = new();
public static readonly Dictionary<Type, ushort> PacketIDTable = new();
// Have a way to assign a number to the packet that will run the same ever time
static ushort GetDeterministicHashCode(string str) {
unchecked {
uint hash = 2166136261;
foreach (char c in str) {
hash = (hash ^ c) * 16777619;
}
return (ushort)(hash % 0xFFFF);
}
}
// Map all packets to a number [ Error on packet collisions ]
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;
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies) {
Type[] allClasses = assembly.GetTypes();
foreach( Type cur in allClasses) {
mPacket attribute = cur.GetCustomAttribute<mPacket>(false);
if (attribute != null) {
// Generate a deterministic 16-bit ID based on the Type's FullName
string identifier = cur.FullName ?? cur.Name;
ushort packetId = GetDeterministicHashCode(identifier);
if (PacketLookupTable.ContainsKey(packetId)) {
throw new Exception($"CRITICAL: Duplicate Packet ID detected! ID {packetId} is used by both {PacketLookupTable[packetId].Name} and {cur.Name}");
}
PacketLookupTable[packetId] = cur;
PacketIDTable[cur] = packetId;
}
}
}
+1 -15
View File
@@ -4,21 +4,7 @@ namespace Mistox.Attributes {
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)]
public sealed class mPacket : Attribute {
public byte ID { get; }
public PacketUsage PacketUse { get; }
public mPacket(byte id) {
ID = id;
PacketUse = PacketUsage.ClientToClient | PacketUsage.ClientToServer;
}
public mPacket(byte id, PacketUsage packetUse) {
ID = id;
PacketUse = packetUse;
}
}
public enum PacketUsage {
ClientToClient = 0x01,
ClientToServer = 0x10,
public mPacket() {}
}
}
+9 -4
View File
@@ -4,27 +4,32 @@ using Mistox.Attributes;
namespace Mistox.ResevedPackets {
[mPacket(0xFF)]
[mPacket]
public class UserConnectedPacket {
public string UserName { get; set; }
public IPAddress ClientIPAddress { get; set; }
public int ClientPort { get; set; }
}
[mPacket(0xFE)]
[mPacket]
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)]
[mPacket]
public class EntityPacket {
// Tag to make sure the object on the other side is the same object i want to update here
// Need to map these Object ID's to a dictionary to make sure I only send network updates when there is a change
public ushort ObjectId { get; set; }
// Packet payload data that im matching for in the dictionary
public byte[] InnerPayload { get; set; }
}
[mPacket(0xFC)]
[mPacket]
public class UserDisconnectedPacket {
public string UserName { get; set; }
}
+3
View File
@@ -25,6 +25,9 @@ when the server connection closes
Use the Server TCP connection to notify all clients when a user disconnects
Only send updates across the network. Dont send same state events
Need to setup a network buffer for Tagged Objects. ID
Connection Flow:
1. Connection to server is made working