From 57db9abf2678b14a2d65f563024ab21634193906 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Fri, 17 May 2024 14:05:27 -0500 Subject: [PATCH 1/7] update Added the MessageTypeDefines ordering class that orders messages based on the NetworkMessageType. --- .../Messaging/Messages/MessageTypes.cs | 121 ++++++++++++++++++ .../Messaging/Messages/MessageTypes.cs.meta | 2 + .../Messaging/NetworkMessageManager.cs | 5 +- 3 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs create mode 100644 com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs.meta diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs new file mode 100644 index 0000000000..3778ff0630 --- /dev/null +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; + +namespace Unity.Netcode +{ + internal class MessageTypeDefines + { + /// + /// Enum representing the different types of messages that can be sent over the network. + /// The values cannot be changed, as they are used to serialize and deserialize messages. + /// Adding new messages should be done by adding new values to the end of the enum + /// (using the next free value). + /// + /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + /// Add any new Message types to this table at the END + /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + internal enum NetworkMessageTypes : uint + { + ConnectionApproved = 0, + ConnectionRequest = 1, + ChangeOwnership = 2, + ClientConnected = 3, + ClientDisconnected = 4, + ClientRpc = 5, + CreateObject = 6, + DestroyObject = 7, + DisconnectReason = 8, + ForwardClientRpc = 9, + ForwardServerRpc = 10, + NamedMessage = 11, + NetworkTransformMessage = 12, + NetworkVariableDelta = 13, + ParentSync = 14, + Proxy = 15, + Rpc = 16, + SceneEvent = 17, + ServerLog = 18, + ServerRpc = 19, + TimeSync = 20, + Unnamed = 21, + SessionOwner = 22 + } + + internal static Dictionary MessageTypes; + + /// + /// Orders messages based on + /// + /// + /// + /// + internal static List Initialize(INetworkMessageProvider networkMessageProvider) + { + var allowedTypes = networkMessageProvider.GetMessages(); + var messageTypeCount = Enum.GetValues(typeof(NetworkMessageTypes)).Length; + // Assure the allowed types count is the same as our NetworkMessageType enum count + if (allowedTypes.Count != messageTypeCount) + { + throw new Exception($"Allowed types is not equal to the number of message type indices! Allowed Count: {allowedTypes.Count} | Index Count: {messageTypeCount}"); + } + + // Populate with blanks to be replaced later + var adjustedMessageTypes = new List(); + var blank = new NetworkMessageManager.MessageWithHandler(); + for (int i = 0; i < messageTypeCount; i++) + { + adjustedMessageTypes.Add(blank); + } + + // Create a type to index lookup table + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Add any new Message types to this table + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + MessageTypes = new Dictionary + { + { typeof(ConnectionApprovedMessage), NetworkMessageTypes.ConnectionApproved }, + { typeof(ConnectionRequestMessage), NetworkMessageTypes.ConnectionRequest }, + { typeof(ChangeOwnershipMessage), NetworkMessageTypes.ChangeOwnership }, + { typeof(ClientConnectedMessage), NetworkMessageTypes.ClientConnected }, + { typeof(ClientDisconnectedMessage), NetworkMessageTypes.ClientDisconnected }, + { typeof(ClientRpcMessage), NetworkMessageTypes.ClientRpc }, + { typeof(CreateObjectMessage), NetworkMessageTypes.CreateObject }, + { typeof(DestroyObjectMessage), NetworkMessageTypes.DestroyObject }, + { typeof(DisconnectReasonMessage), NetworkMessageTypes.DisconnectReason }, + { typeof(ForwardClientRpcMessage), NetworkMessageTypes.ForwardClientRpc }, + { typeof(ForwardServerRpcMessage), NetworkMessageTypes.ForwardServerRpc }, + { typeof(NamedMessage), NetworkMessageTypes.NamedMessage }, + { typeof(NetworkTransformMessage), NetworkMessageTypes.NetworkTransformMessage }, + { typeof(NetworkVariableDeltaMessage), NetworkMessageTypes.NetworkVariableDelta }, + { typeof(ParentSyncMessage), NetworkMessageTypes.ParentSync }, + { typeof(ProxyMessage), NetworkMessageTypes.Proxy }, + { typeof(RpcMessage), NetworkMessageTypes.Rpc }, + { typeof(SceneEventMessage), NetworkMessageTypes.SceneEvent }, + { typeof(ServerLogMessage), NetworkMessageTypes.ServerLog }, + { typeof(ServerRpcMessage), NetworkMessageTypes.ServerRpc }, + { typeof(TimeSyncMessage), NetworkMessageTypes.TimeSync }, + { typeof(UnnamedMessage), NetworkMessageTypes.Unnamed }, + { typeof(SessionOwnerMessage), NetworkMessageTypes.SessionOwner } + }; + + // Assure the type to lookup table count and NetworkMessageType enum count matches (i.e. to catch human error when adding new messages) + if (MessageTypes.Count != messageTypeCount) + { + throw new Exception($"Message type to Message type index count mistmatch! Table Count: {MessageTypes.Count} | Index Count: {messageTypeCount}"); + } + + // Now order the allowed types list based on the order of the NetworkMessageType enum + foreach (var messageHandler in allowedTypes) + { + if (!MessageTypes.ContainsKey(messageHandler.MessageType)) + { + throw new Exception($"Missing message type from lookup table: {messageHandler.MessageType}"); + } + adjustedMessageTypes[(int)MessageTypes[messageHandler.MessageType]] = messageHandler; + } + + // return the NetworkMessageType enum ordered list + return adjustedMessageTypes; + } + } +} diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs.meta b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs.meta new file mode 100644 index 0000000000..836e78c882 --- /dev/null +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 1fbafb5a0a1ab924eb0bdb1870f45d97 \ No newline at end of file diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs index 7dd4dae2f0..6f171654a8 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs @@ -159,10 +159,9 @@ public NetworkMessageManager(INetworkMessageSender sender, object owner, INetwor provider = new ILPPMessageProvider(); } - var allowedTypes = provider.GetMessages(); + // This orders the message types by the NetworkMessageType enum order + var allowedTypes = MessageTypeDefines.Initialize(provider); - allowedTypes.Sort((a, b) => string.CompareOrdinal(a.MessageType.FullName, b.MessageType.FullName)); - allowedTypes = PrioritizeMessageOrder(allowedTypes); foreach (var type in allowedTypes) { RegisterMessageType(type); From ad39ef53dd39c8accae5261bff7d3fe8724d5ccf Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Fri, 17 May 2024 14:11:37 -0500 Subject: [PATCH 2/7] update Adding changelog entry --- com.unity.netcode.gameobjects/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index 305e08edc2..3829a2f098 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -22,6 +22,8 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Changed +- Changed messages are now sorted by enum values as opposed to ordinally sorting the messages by their type name. (#2929) + ## [2.0.0-exp.2] - 2024-04-02 From 89b8a729823973191c6fbad08e83d9d14162867d Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Fri, 17 May 2024 14:13:20 -0500 Subject: [PATCH 3/7] style Adding additional comment about two of the required enum positions --- .../Runtime/Messaging/Messages/MessageTypes.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs index 3778ff0630..59e5bd784d 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs @@ -73,8 +73,8 @@ internal enum NetworkMessageTypes : uint // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MessageTypes = new Dictionary { - { typeof(ConnectionApprovedMessage), NetworkMessageTypes.ConnectionApproved }, - { typeof(ConnectionRequestMessage), NetworkMessageTypes.ConnectionRequest }, + { typeof(ConnectionApprovedMessage), NetworkMessageTypes.ConnectionApproved }, // This MUST be first + { typeof(ConnectionRequestMessage), NetworkMessageTypes.ConnectionRequest }, // This MUST be second { typeof(ChangeOwnershipMessage), NetworkMessageTypes.ChangeOwnership }, { typeof(ClientConnectedMessage), NetworkMessageTypes.ClientConnected }, { typeof(ClientDisconnectedMessage), NetworkMessageTypes.ClientDisconnected }, From 87e1133e9f5f745ac5ce9c1a55ebd1869827d0a8 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Fri, 17 May 2024 14:24:22 -0500 Subject: [PATCH 4/7] style whitespaace fixes --- .../Runtime/Messaging/Messages/MessageTypes.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs index 59e5bd784d..0650b46343 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs @@ -62,7 +62,7 @@ internal enum NetworkMessageTypes : uint // Populate with blanks to be replaced later var adjustedMessageTypes = new List(); var blank = new NetworkMessageManager.MessageWithHandler(); - for (int i = 0; i < messageTypeCount; i++) + for (int i = 0; i < messageTypeCount; i++) { adjustedMessageTypes.Add(blank); } @@ -105,8 +105,8 @@ internal enum NetworkMessageTypes : uint } // Now order the allowed types list based on the order of the NetworkMessageType enum - foreach (var messageHandler in allowedTypes) - { + foreach (var messageHandler in allowedTypes) + { if (!MessageTypes.ContainsKey(messageHandler.MessageType)) { throw new Exception($"Missing message type from lookup table: {messageHandler.MessageType}"); From 6090bbe88b207fde2eeddd3c265d814187500200 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Fri, 17 May 2024 15:09:52 -0500 Subject: [PATCH 5/7] fix Fixing issue with tests using their own message provider. --- .../Runtime/Messaging/Messages/MessageTypes.cs | 6 +++++- .../Runtime/Messaging/NetworkMessageManager.cs | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs index 0650b46343..793ce6dbeb 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs @@ -49,9 +49,13 @@ internal enum NetworkMessageTypes : uint /// /// /// - internal static List Initialize(INetworkMessageProvider networkMessageProvider) + internal static List Initialize(INetworkMessageProvider networkMessageProvider, bool usingDefault) { var allowedTypes = networkMessageProvider.GetMessages(); + if (!usingDefault) + { + return allowedTypes; + } var messageTypeCount = Enum.GetValues(typeof(NetworkMessageTypes)).Length; // Assure the allowed types count is the same as our NetworkMessageType enum count if (allowedTypes.Count != messageTypeCount) diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs index 6f171654a8..3b34698df2 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs @@ -153,14 +153,15 @@ public NetworkMessageManager(INetworkMessageSender sender, object owner, INetwor { m_Sender = sender; m_Owner = owner; - + var usingDefault = false; if (provider == null) { provider = new ILPPMessageProvider(); + usingDefault = true; } // This orders the message types by the NetworkMessageType enum order - var allowedTypes = MessageTypeDefines.Initialize(provider); + var allowedTypes = MessageTypeDefines.Initialize(provider, usingDefault); foreach (var type in allowedTypes) { From a1e977ac7da5f9acc428c310749e9b7deec5611f Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Fri, 17 May 2024 15:54:28 -0500 Subject: [PATCH 6/7] test fix Fixing a few more tests that don't need the message ordering or count verification stuff to be running. --- .../Messaging/Messages/MessageTypes.cs | 33 ++++++++++++++++++- .../Messaging/NetworkMessageManager.cs | 4 ++- .../NetworkManagerConfigurationTests.cs | 12 +++++++ .../Editor/Transports/UnityTransportTests.cs | 12 +++++++ 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs index 793ce6dbeb..66203c70fc 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs @@ -43,17 +43,48 @@ internal enum NetworkMessageTypes : uint internal static Dictionary MessageTypes; + internal static List PrioritizeMessageOrder(List allowedTypes) + { + var prioritizedTypes = new List(); + + // First pass puts the priority message in the first indices + // Those are the messages that must be delivered in order to allow re-ordering the others later + foreach (var t in allowedTypes) + { + if (t.MessageType.FullName == typeof(ConnectionRequestMessage).FullName || + t.MessageType.FullName == typeof(ConnectionApprovedMessage).FullName) + { + prioritizedTypes.Add(t); + } + } + + foreach (var t in allowedTypes) + { + if (t.MessageType.FullName != typeof(ConnectionRequestMessage).FullName && + t.MessageType.FullName != typeof(ConnectionApprovedMessage).FullName) + { + prioritizedTypes.Add(t); + } + } + + return prioritizedTypes; + } + /// /// Orders messages based on /// - /// + /// + /// /// /// + /// internal static List Initialize(INetworkMessageProvider networkMessageProvider, bool usingDefault) { var allowedTypes = networkMessageProvider.GetMessages(); if (!usingDefault) { + allowedTypes.Sort((a, b) => string.CompareOrdinal(a.MessageType.FullName, b.MessageType.FullName)); + allowedTypes = PrioritizeMessageOrder(allowedTypes); return allowedTypes; } var messageTypeCount = Enum.GetValues(typeof(NetworkMessageTypes)).Length; diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs index 3b34698df2..98673aec8d 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs @@ -147,6 +147,8 @@ internal List PrioritizeMessageOrder(List /// Does a simple check to make sure the nested network manager will /// notify the user when in the editor. This is just a unit test to diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs index fb61c053a1..6f43e56a33 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs @@ -7,6 +7,18 @@ namespace Unity.Netcode.EditorTests { public class UnityTransportTests { + [SetUp] + public void OnSetup() + { + NetworkMessageManager.IntegrationTest = true; + } + + [TearDown] + public void OnTearDown() + { + NetworkMessageManager.IntegrationTest = false; + } + // Check that starting an IPv4 server succeeds. [Test] public void UnityTransport_BasicInitServer_IPv4() From 263396ae5ac0e012a8a0470acb2a67868b4b1a54 Mon Sep 17 00:00:00 2001 From: NoelStephensUnity Date: Sun, 19 May 2024 15:26:51 -0500 Subject: [PATCH 7/7] update Decided that we don't need an extra class to handle this and to migrate the NetworkMessageTypes and type to NetworkMessageTypes enum index value table creation within the GetMessages method. Removed the message ordering related tests since this it was no longer needed. Adjusted name of integration test ILPPMessageProvider.IntegrationTestNoMessages to better reflect what it is used for and also removed it from the NetworkMessageManager. --- .../Runtime/Messaging/ILPPMessageProvider.cs | 111 ++++++++++++- .../Messaging/Messages/MessageTypes.cs | 156 ------------------ .../Messaging/Messages/MessageTypes.cs.meta | 2 - .../Messaging/NetworkMessageManager.cs | 35 +--- .../Messaging/MessageRegistrationTests.cs | 72 -------- .../NetworkManagerConfigurationTests.cs | 4 +- .../Editor/Transports/UnityTransportTests.cs | 4 +- 7 files changed, 116 insertions(+), 268 deletions(-) delete mode 100644 com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs delete mode 100644 com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs.meta diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/ILPPMessageProvider.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/ILPPMessageProvider.cs index 4424550e9a..609cadf3ec 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/ILPPMessageProvider.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/ILPPMessageProvider.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; #if UNITY_EDITOR using UnityEditor; @@ -12,9 +13,117 @@ internal struct ILPPMessageProvider : INetworkMessageProvider internal static readonly List __network_message_types = new List(); #pragma warning restore IDE1006 // restore naming rule violation check + /// + /// Enum representing the different types of messages that can be sent over the network. + /// The values cannot be changed, as they are used to serialize and deserialize messages. + /// Adding new messages should be done by adding new values to the end of the enum + /// using the next free value. + /// + /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + /// Add any new Message types to this table at the END with incremented index value + /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + internal enum NetworkMessageTypes : uint + { + ConnectionApproved = 0, + ConnectionRequest = 1, + ChangeOwnership = 2, + ClientConnected = 3, + ClientDisconnected = 4, + ClientRpc = 5, + CreateObject = 6, + DestroyObject = 7, + DisconnectReason = 8, + ForwardClientRpc = 9, + ForwardServerRpc = 10, + NamedMessage = 11, + NetworkTransformMessage = 12, + NetworkVariableDelta = 13, + ParentSync = 14, + Proxy = 15, + Rpc = 16, + SceneEvent = 17, + ServerLog = 18, + ServerRpc = 19, + TimeSync = 20, + Unnamed = 21, + SessionOwner = 22 + } + + + // Enable this for integration tests that need no message types defined + internal static bool IntegrationTestNoMessages; + public List GetMessages() { - return __network_message_types; + // return no message types when defined for integration tests + if (IntegrationTestNoMessages) + { + return new List(); + } + var messageTypeCount = Enum.GetValues(typeof(NetworkMessageTypes)).Length; + // Assure the allowed types count is the same as our NetworkMessageType enum count + if (__network_message_types.Count != messageTypeCount) + { + throw new Exception($"Allowed types is not equal to the number of message type indices! Allowed Count: {__network_message_types.Count} | Index Count: {messageTypeCount}"); + } + + // Populate with blanks to be replaced later + var adjustedMessageTypes = new List(); + var blank = new NetworkMessageManager.MessageWithHandler(); + for (int i = 0; i < messageTypeCount; i++) + { + adjustedMessageTypes.Add(blank); + } + + // Create a type to enum index lookup table + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + // Add new Message types to this table paired with its new NetworkMessageTypes enum + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + var messageTypes = new Dictionary + { + { typeof(ConnectionApprovedMessage), NetworkMessageTypes.ConnectionApproved }, // This MUST be first + { typeof(ConnectionRequestMessage), NetworkMessageTypes.ConnectionRequest }, // This MUST be second + { typeof(ChangeOwnershipMessage), NetworkMessageTypes.ChangeOwnership }, + { typeof(ClientConnectedMessage), NetworkMessageTypes.ClientConnected }, + { typeof(ClientDisconnectedMessage), NetworkMessageTypes.ClientDisconnected }, + { typeof(ClientRpcMessage), NetworkMessageTypes.ClientRpc }, + { typeof(CreateObjectMessage), NetworkMessageTypes.CreateObject }, + { typeof(DestroyObjectMessage), NetworkMessageTypes.DestroyObject }, + { typeof(DisconnectReasonMessage), NetworkMessageTypes.DisconnectReason }, + { typeof(ForwardClientRpcMessage), NetworkMessageTypes.ForwardClientRpc }, + { typeof(ForwardServerRpcMessage), NetworkMessageTypes.ForwardServerRpc }, + { typeof(NamedMessage), NetworkMessageTypes.NamedMessage }, + { typeof(NetworkTransformMessage), NetworkMessageTypes.NetworkTransformMessage }, + { typeof(NetworkVariableDeltaMessage), NetworkMessageTypes.NetworkVariableDelta }, + { typeof(ParentSyncMessage), NetworkMessageTypes.ParentSync }, + { typeof(ProxyMessage), NetworkMessageTypes.Proxy }, + { typeof(RpcMessage), NetworkMessageTypes.Rpc }, + { typeof(SceneEventMessage), NetworkMessageTypes.SceneEvent }, + { typeof(ServerLogMessage), NetworkMessageTypes.ServerLog }, + { typeof(ServerRpcMessage), NetworkMessageTypes.ServerRpc }, + { typeof(TimeSyncMessage), NetworkMessageTypes.TimeSync }, + { typeof(UnnamedMessage), NetworkMessageTypes.Unnamed }, + { typeof(SessionOwnerMessage), NetworkMessageTypes.SessionOwner } + }; + + // Assure the type to lookup table count and NetworkMessageType enum count matches (i.e. to catch human error when adding new messages) + if (messageTypes.Count != messageTypeCount) + { + throw new Exception($"Message type to Message type index count mistmatch! Table Count: {messageTypes.Count} | Index Count: {messageTypeCount}"); + } + + // Now order the allowed types list based on the order of the NetworkMessageType enum + foreach (var messageHandler in __network_message_types) + { + if (!messageTypes.ContainsKey(messageHandler.MessageType)) + { + throw new Exception($"Missing message type from lookup table: {messageHandler.MessageType}"); + } + adjustedMessageTypes[(int)messageTypes[messageHandler.MessageType]] = messageHandler; + } + + // return the NetworkMessageType enum ordered list + return adjustedMessageTypes; } #if UNITY_EDITOR diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs deleted file mode 100644 index 66203c70fc..0000000000 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs +++ /dev/null @@ -1,156 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Unity.Netcode -{ - internal class MessageTypeDefines - { - /// - /// Enum representing the different types of messages that can be sent over the network. - /// The values cannot be changed, as they are used to serialize and deserialize messages. - /// Adding new messages should be done by adding new values to the end of the enum - /// (using the next free value). - /// - /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - /// Add any new Message types to this table at the END - /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - internal enum NetworkMessageTypes : uint - { - ConnectionApproved = 0, - ConnectionRequest = 1, - ChangeOwnership = 2, - ClientConnected = 3, - ClientDisconnected = 4, - ClientRpc = 5, - CreateObject = 6, - DestroyObject = 7, - DisconnectReason = 8, - ForwardClientRpc = 9, - ForwardServerRpc = 10, - NamedMessage = 11, - NetworkTransformMessage = 12, - NetworkVariableDelta = 13, - ParentSync = 14, - Proxy = 15, - Rpc = 16, - SceneEvent = 17, - ServerLog = 18, - ServerRpc = 19, - TimeSync = 20, - Unnamed = 21, - SessionOwner = 22 - } - - internal static Dictionary MessageTypes; - - internal static List PrioritizeMessageOrder(List allowedTypes) - { - var prioritizedTypes = new List(); - - // First pass puts the priority message in the first indices - // Those are the messages that must be delivered in order to allow re-ordering the others later - foreach (var t in allowedTypes) - { - if (t.MessageType.FullName == typeof(ConnectionRequestMessage).FullName || - t.MessageType.FullName == typeof(ConnectionApprovedMessage).FullName) - { - prioritizedTypes.Add(t); - } - } - - foreach (var t in allowedTypes) - { - if (t.MessageType.FullName != typeof(ConnectionRequestMessage).FullName && - t.MessageType.FullName != typeof(ConnectionApprovedMessage).FullName) - { - prioritizedTypes.Add(t); - } - } - - return prioritizedTypes; - } - - /// - /// Orders messages based on - /// - /// - /// - /// - /// - /// - internal static List Initialize(INetworkMessageProvider networkMessageProvider, bool usingDefault) - { - var allowedTypes = networkMessageProvider.GetMessages(); - if (!usingDefault) - { - allowedTypes.Sort((a, b) => string.CompareOrdinal(a.MessageType.FullName, b.MessageType.FullName)); - allowedTypes = PrioritizeMessageOrder(allowedTypes); - return allowedTypes; - } - var messageTypeCount = Enum.GetValues(typeof(NetworkMessageTypes)).Length; - // Assure the allowed types count is the same as our NetworkMessageType enum count - if (allowedTypes.Count != messageTypeCount) - { - throw new Exception($"Allowed types is not equal to the number of message type indices! Allowed Count: {allowedTypes.Count} | Index Count: {messageTypeCount}"); - } - - // Populate with blanks to be replaced later - var adjustedMessageTypes = new List(); - var blank = new NetworkMessageManager.MessageWithHandler(); - for (int i = 0; i < messageTypeCount; i++) - { - adjustedMessageTypes.Add(blank); - } - - // Create a type to index lookup table - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - // Add any new Message types to this table - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - MessageTypes = new Dictionary - { - { typeof(ConnectionApprovedMessage), NetworkMessageTypes.ConnectionApproved }, // This MUST be first - { typeof(ConnectionRequestMessage), NetworkMessageTypes.ConnectionRequest }, // This MUST be second - { typeof(ChangeOwnershipMessage), NetworkMessageTypes.ChangeOwnership }, - { typeof(ClientConnectedMessage), NetworkMessageTypes.ClientConnected }, - { typeof(ClientDisconnectedMessage), NetworkMessageTypes.ClientDisconnected }, - { typeof(ClientRpcMessage), NetworkMessageTypes.ClientRpc }, - { typeof(CreateObjectMessage), NetworkMessageTypes.CreateObject }, - { typeof(DestroyObjectMessage), NetworkMessageTypes.DestroyObject }, - { typeof(DisconnectReasonMessage), NetworkMessageTypes.DisconnectReason }, - { typeof(ForwardClientRpcMessage), NetworkMessageTypes.ForwardClientRpc }, - { typeof(ForwardServerRpcMessage), NetworkMessageTypes.ForwardServerRpc }, - { typeof(NamedMessage), NetworkMessageTypes.NamedMessage }, - { typeof(NetworkTransformMessage), NetworkMessageTypes.NetworkTransformMessage }, - { typeof(NetworkVariableDeltaMessage), NetworkMessageTypes.NetworkVariableDelta }, - { typeof(ParentSyncMessage), NetworkMessageTypes.ParentSync }, - { typeof(ProxyMessage), NetworkMessageTypes.Proxy }, - { typeof(RpcMessage), NetworkMessageTypes.Rpc }, - { typeof(SceneEventMessage), NetworkMessageTypes.SceneEvent }, - { typeof(ServerLogMessage), NetworkMessageTypes.ServerLog }, - { typeof(ServerRpcMessage), NetworkMessageTypes.ServerRpc }, - { typeof(TimeSyncMessage), NetworkMessageTypes.TimeSync }, - { typeof(UnnamedMessage), NetworkMessageTypes.Unnamed }, - { typeof(SessionOwnerMessage), NetworkMessageTypes.SessionOwner } - }; - - // Assure the type to lookup table count and NetworkMessageType enum count matches (i.e. to catch human error when adding new messages) - if (MessageTypes.Count != messageTypeCount) - { - throw new Exception($"Message type to Message type index count mistmatch! Table Count: {MessageTypes.Count} | Index Count: {messageTypeCount}"); - } - - // Now order the allowed types list based on the order of the NetworkMessageType enum - foreach (var messageHandler in allowedTypes) - { - if (!MessageTypes.ContainsKey(messageHandler.MessageType)) - { - throw new Exception($"Missing message type from lookup table: {messageHandler.MessageType}"); - } - adjustedMessageTypes[(int)MessageTypes[messageHandler.MessageType]] = messageHandler; - } - - // return the NetworkMessageType enum ordered list - return adjustedMessageTypes; - } - } -} diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs.meta b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs.meta deleted file mode 100644 index 836e78c882..0000000000 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageTypes.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 1fbafb5a0a1ab924eb0bdb1870f45d97 \ No newline at end of file diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs index 98673aec8d..b455c9bfa1 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs @@ -120,50 +120,19 @@ internal struct MessageWithHandler public VersionGetter GetVersion; } - internal List PrioritizeMessageOrder(List allowedTypes) - { - var prioritizedTypes = new List(); - - // First pass puts the priority message in the first indices - // Those are the messages that must be delivered in order to allow re-ordering the others later - foreach (var t in allowedTypes) - { - if (t.MessageType.FullName == typeof(ConnectionRequestMessage).FullName || - t.MessageType.FullName == typeof(ConnectionApprovedMessage).FullName) - { - prioritizedTypes.Add(t); - } - } - - foreach (var t in allowedTypes) - { - if (t.MessageType.FullName != typeof(ConnectionRequestMessage).FullName && - t.MessageType.FullName != typeof(ConnectionApprovedMessage).FullName) - { - prioritizedTypes.Add(t); - } - } - - return prioritizedTypes; - } - - // Enable this to bypass the default message count and ordering in MessageTypes - internal static bool IntegrationTest; public NetworkMessageManager(INetworkMessageSender sender, object owner, INetworkMessageProvider provider = null) { try { m_Sender = sender; m_Owner = owner; - var usingDefault = false; if (provider == null) { provider = new ILPPMessageProvider(); - usingDefault = !IntegrationTest; } - // This orders the message types by the NetworkMessageType enum order - var allowedTypes = MessageTypeDefines.Initialize(provider, usingDefault); + // Get the presorted message types returned by the provider + var allowedTypes = provider.GetMessages(); foreach (var type in allowedTypes) { diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Messaging/MessageRegistrationTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/Messaging/MessageRegistrationTests.cs index bb7ab651d7..2b601a16fd 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/Messaging/MessageRegistrationTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Editor/Messaging/MessageRegistrationTests.cs @@ -191,77 +191,5 @@ public void WhenCreatingMessageSystem_BoundTypeMessageHandlersAreRegistered() Assert.AreEqual(handlerFour, systemThree.MessageHandlers[systemThree.GetMessageType(typeof(TestMessageFour))]); } } - - internal class AAAEarlyLexicographicNetworkMessage : INetworkMessage - { - public void Serialize(FastBufferWriter writer, int targetVersion) - { - } - - public bool Deserialize(FastBufferReader reader, ref NetworkContext context, int receivedMessageVersion) - { - return true; - } - - public void Handle(ref NetworkContext context) - { - } - - public int Version => 0; - } - -#pragma warning disable IDE1006 - internal class zzzLateLexicographicNetworkMessage : AAAEarlyLexicographicNetworkMessage - { - } -#pragma warning restore IDE1006 - - internal class OrderingMessageProvider : INetworkMessageProvider - { - public List GetMessages() - { - var listMessages = new List(); - - var messageWithHandler = new NetworkMessageManager.MessageWithHandler - { - MessageType = typeof(zzzLateLexicographicNetworkMessage), - GetVersion = NetworkMessageManager.CreateMessageAndGetVersion - }; - listMessages.Add(messageWithHandler); - - messageWithHandler.MessageType = typeof(ConnectionRequestMessage); - messageWithHandler.GetVersion = NetworkMessageManager.CreateMessageAndGetVersion; - listMessages.Add(messageWithHandler); - - messageWithHandler.MessageType = typeof(ConnectionApprovedMessage); - messageWithHandler.GetVersion = NetworkMessageManager.CreateMessageAndGetVersion; - listMessages.Add(messageWithHandler); - - messageWithHandler.MessageType = typeof(AAAEarlyLexicographicNetworkMessage); - messageWithHandler.GetVersion = NetworkMessageManager.CreateMessageAndGetVersion; - listMessages.Add(messageWithHandler); - - return listMessages; - } - } - - [Test] - public void MessagesGetPrioritizedCorrectly() - { - var sender = new NopMessageSender(); - var provider = new OrderingMessageProvider(); - using var messageManager = new NetworkMessageManager(sender, null, provider); - - // the 2 priority messages should appear first, in lexicographic order - Assert.AreEqual(messageManager.MessageTypes[0], typeof(ConnectionApprovedMessage)); - Assert.AreEqual(messageManager.MessageTypes[1], typeof(ConnectionRequestMessage)); - - // the other should follow after - Assert.AreEqual(messageManager.MessageTypes[2], typeof(AAAEarlyLexicographicNetworkMessage)); - Assert.AreEqual(messageManager.MessageTypes[3], typeof(zzzLateLexicographicNetworkMessage)); - - // there should not be any extras - Assert.AreEqual(messageManager.MessageHandlerCount, 4); - } } } diff --git a/com.unity.netcode.gameobjects/Tests/Editor/NetworkManagerConfigurationTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/NetworkManagerConfigurationTests.cs index fc33c761a9..b57a13c974 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/NetworkManagerConfigurationTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Editor/NetworkManagerConfigurationTests.cs @@ -14,13 +14,13 @@ public class NetworkManagerConfigurationTests [SetUp] public void OnSetup() { - NetworkMessageManager.IntegrationTest = true; + ILPPMessageProvider.IntegrationTestNoMessages = true; } [TearDown] public void OnTearDown() { - NetworkMessageManager.IntegrationTest = false; + ILPPMessageProvider.IntegrationTestNoMessages = false; } /// diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs index 6f43e56a33..f5caa6195e 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs @@ -10,13 +10,13 @@ public class UnityTransportTests [SetUp] public void OnSetup() { - NetworkMessageManager.IntegrationTest = true; + ILPPMessageProvider.IntegrationTestNoMessages = true; } [TearDown] public void OnTearDown() { - NetworkMessageManager.IntegrationTest = false; + ILPPMessageProvider.IntegrationTestNoMessages = false; } // Check that starting an IPv4 server succeeds.