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
|
// Parse the header
|
||||||
DataPacketHeader Header = new DataPacketHeader {
|
DataPacketHeader Header = new DataPacketHeader {
|
||||||
Type = headerBuffer[0],
|
Type = (ushort)((headerBuffer[0] << 8) | headerBuffer[1]),
|
||||||
DataLength = (ushort)((headerBuffer[1] << 8) | headerBuffer[2])
|
DataLength = (ushort)((headerBuffer[2] << 8) | headerBuffer[3])
|
||||||
};
|
};
|
||||||
|
|
||||||
// Make sure the data looks valid
|
// Make sure the data looks valid
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ namespace Mistox.Client {
|
|||||||
|
|
||||||
// Create the packet header
|
// Create the packet header
|
||||||
DataPacketHeader Header = new DataPacketHeader {
|
DataPacketHeader Header = new DataPacketHeader {
|
||||||
Type = dataPacket[0],
|
Type = (ushort)((dataPacket[0] << 8) | dataPacket[1]),
|
||||||
DataLength = (ushort)((dataPacket[1] << 8) | dataPacket[2])
|
DataLength = (ushort)((dataPacket[2] << 8) | dataPacket[3])
|
||||||
};
|
};
|
||||||
|
|
||||||
// Slice out the data part of the packet
|
// Slice out the data part of the packet
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ namespace Mistox.Server {
|
|||||||
|
|
||||||
// Pack the header variables for faster memory passing
|
// Pack the header variables for faster memory passing
|
||||||
DataPacketHeader Header = new DataPacketHeader {
|
DataPacketHeader Header = new DataPacketHeader {
|
||||||
Type = headerBuffer[0],
|
Type = (ushort)((headerBuffer[0] << 8) | headerBuffer[1]),
|
||||||
DataLength = (ushort)((headerBuffer[1] << 8) | headerBuffer[2])
|
DataLength = (ushort)((headerBuffer[2] << 8) | headerBuffer[3])
|
||||||
};
|
};
|
||||||
|
|
||||||
// Make sure the data looks valid
|
// Make sure the data looks valid
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace Mistox {
|
|||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
public struct DataPacketHeader {
|
public struct DataPacketHeader {
|
||||||
public byte Type { get; set; }
|
public ushort Type { get; set; }
|
||||||
public ushort DataLength { get; set; }
|
public ushort DataLength { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,12 +25,6 @@ namespace Mistox {
|
|||||||
// Helper classes
|
// Helper classes
|
||||||
public static byte[] Serialize<T>( T Object ) {
|
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
|
// Use an expandable buffer writer from the system stack
|
||||||
var writer = new ArrayBufferWriter<byte>(256);
|
var writer = new ArrayBufferWriter<byte>(256);
|
||||||
|
|
||||||
@@ -42,7 +36,7 @@ namespace Mistox {
|
|||||||
|
|
||||||
// Build our header struct on the stack
|
// Build our header struct on the stack
|
||||||
DataPacketHeader header = new DataPacketHeader {
|
DataPacketHeader header = new DataPacketHeader {
|
||||||
Type = attribute.ID,
|
Type = NetworkPacketDictionary.PacketIDTable[typeof(T)],
|
||||||
DataLength = (ushort)(writer.WrittenCount - HeaderLength)
|
DataLength = (ushort)(writer.WrittenCount - HeaderLength)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -59,7 +53,7 @@ namespace Mistox {
|
|||||||
public static object Deserialize( DataPacketHeader Header, ReadOnlyMemory<byte> Data ) {
|
public static object Deserialize( DataPacketHeader Header, ReadOnlyMemory<byte> Data ) {
|
||||||
|
|
||||||
// Get the type from the tag
|
// 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}");
|
throw new Exception($"Unknown packet type ID: {Header.Type}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,17 +7,38 @@ namespace Mistox.Attributes {
|
|||||||
public class NetworkPacketDictionary {
|
public class NetworkPacketDictionary {
|
||||||
|
|
||||||
// Fills out the NetworkPacket Lookup Dictionary
|
// Fills out the NetworkPacket Lookup Dictionary
|
||||||
public static readonly Dictionary<byte, Type> ClientToClientPackets = new();
|
public static readonly Dictionary<ushort, Type> PacketLookupTable = new();
|
||||||
public static readonly Dictionary<byte, Type> ServerToClientPackets = 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() {
|
public static void BuildNetworkPacketList() {
|
||||||
Type[] allClasses = Assembly.GetExecutingAssembly().GetTypes();
|
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||||
foreach( Type cur in allClasses) {
|
foreach (Assembly assembly in assemblies) {
|
||||||
mPacket attribute = cur.GetCustomAttribute<mPacket>(false);
|
Type[] allClasses = assembly.GetTypes();
|
||||||
if (attribute != null) {
|
foreach( Type cur in allClasses) {
|
||||||
if ( attribute.PacketUse.HasFlag(PacketUsage.ClientToClient) ) {
|
mPacket attribute = cur.GetCustomAttribute<mPacket>(false);
|
||||||
ClientToClientPackets[attribute.ID] = cur;
|
if (attribute != null) {
|
||||||
} else if ( attribute.PacketUse.HasFlag(PacketUsage.ClientToServer) ) {
|
|
||||||
ServerToClientPackets[attribute.ID] = cur;
|
// 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)]
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)]
|
||||||
public sealed class mPacket : Attribute {
|
public sealed class mPacket : Attribute {
|
||||||
public byte ID { get; }
|
public mPacket() {}
|
||||||
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,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -4,27 +4,32 @@ using Mistox.Attributes;
|
|||||||
|
|
||||||
namespace Mistox.ResevedPackets {
|
namespace Mistox.ResevedPackets {
|
||||||
|
|
||||||
[mPacket(0xFF)]
|
[mPacket]
|
||||||
public class UserConnectedPacket {
|
public class UserConnectedPacket {
|
||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
public IPAddress ClientIPAddress { get; set; }
|
public IPAddress ClientIPAddress { get; set; }
|
||||||
public int ClientPort { get; set; }
|
public int ClientPort { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[mPacket(0xFE)]
|
[mPacket]
|
||||||
public class UserAuthPacket {
|
public class UserAuthPacket {
|
||||||
public string UserName { get; set; } = "";
|
public string UserName { get; set; } = "";
|
||||||
public string ConnectionKey { get; set; } = "";
|
public string ConnectionKey { get; set; } = "";
|
||||||
public int AuthSuccessful { get; set; } = 0; // 0 is standard, -1 is auth failure, 1 is auth success
|
public int AuthSuccessful { get; set; } = 0; // 0 is standard, -1 is auth failure, 1 is auth success
|
||||||
}
|
}
|
||||||
|
|
||||||
[mPacket(0xFD)]
|
[mPacket]
|
||||||
public class EntityPacket {
|
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; }
|
public ushort ObjectId { get; set; }
|
||||||
|
|
||||||
|
// Packet payload data that im matching for in the dictionary
|
||||||
public byte[] InnerPayload { get; set; }
|
public byte[] InnerPayload { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[mPacket(0xFC)]
|
[mPacket]
|
||||||
public class UserDisconnectedPacket {
|
public class UserDisconnectedPacket {
|
||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ when the server connection closes
|
|||||||
|
|
||||||
Use the Server TCP connection to notify all clients when a user disconnects
|
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:
|
Connection Flow:
|
||||||
1. Connection to server is made working
|
1. Connection to server is made working
|
||||||
|
|||||||
Reference in new issue
Block a user