Change manual packet numbering to a dictionary
This commit is contained in:
1 parent
37a6b5d59b
commit
b83887cb2a
8 files changed
+53
-44
No files matched your search
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
@@ -24,12 +24,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}");
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user