diff --git a/com.unity.netcode.gameobjects/Runtime/Connection/NetworkConnectionManager.cs b/com.unity.netcode.gameobjects/Runtime/Connection/NetworkConnectionManager.cs index 722fbb24b5..6f90e98984 100644 --- a/com.unity.netcode.gameobjects/Runtime/Connection/NetworkConnectionManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Connection/NetworkConnectionManager.cs @@ -544,10 +544,9 @@ internal void TransportFailureEventHandler(bool duringStart = false) } /// - /// Client-Side: - /// Upon transport connecting, the client will send a connection request + /// Generates the connection request message /// - private void SendConnectionRequest() + internal ConnectionRequestMessage GenerateConnectionRequestMessage() { var message = new ConnectionRequestMessage { @@ -567,14 +566,29 @@ private void SendConnectionRequest() if (MessageManager.MessageTypes[index] != null) { var type = MessageManager.MessageTypes[index]; - message.MessageVersions[index] = new MessageVersionData + var messageVersionData = new MessageVersionData { Hash = XXHash.Hash32(type.FullName), - Version = MessageManager.GetLocalVersion(type) + Version = MessageManager.GetLocalVersion(type), + SendMessageType = NetworkManager.DistributedAuthorityMode, }; + if (messageVersionData.SendMessageType) + { + messageVersionData.NetworkMessageType = (uint)ILPPMessageProvider.TypeToNetworkMessageType[type]; + } + message.MessageVersions[index] = messageVersionData; } } + return message; + } + /// + /// Client-Side: + /// Upon transport connecting, the client will send a connection request + /// + private void SendConnectionRequest() + { + var message = GenerateConnectionRequestMessage(); SendMessage(ref message, NetworkDelivery.ReliableSequenced, NetworkManager.ServerClientId); message.MessageVersions.Dispose(); } @@ -807,11 +821,17 @@ internal void HandleConnectionApproval(ulong ownerClientId, NetworkManager.Conne if (MessageManager.MessageTypes[index] != null) { var type = MessageManager.MessageTypes[index]; - message.MessageVersions[index] = new MessageVersionData + var messageVersionData = new MessageVersionData { Hash = XXHash.Hash32(type.FullName), - Version = MessageManager.GetLocalVersion(type) + Version = MessageManager.GetLocalVersion(type), + SendMessageType = NetworkManager.DistributedAuthorityMode, }; + if (messageVersionData.SendMessageType) + { + messageVersionData.NetworkMessageType = (uint)ILPPMessageProvider.TypeToNetworkMessageType[type]; + } + message.MessageVersions[index] = messageVersionData; } } if (!MockSkippingApproval) diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/ILPPMessageProvider.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/ILPPMessageProvider.cs index b7f90f658f..8378f2b711 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/ILPPMessageProvider.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/ILPPMessageProvider.cs @@ -54,6 +54,7 @@ internal enum NetworkMessageTypes : uint // Enable this for integration tests that need no message types defined internal static bool IntegrationTestNoMessages; + internal static Dictionary TypeToNetworkMessageType; public List GetMessages() { @@ -81,7 +82,7 @@ internal enum NetworkMessageTypes : uint // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Add new Message types to this table paired with its new NetworkMessageTypes enum // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - var messageTypes = new Dictionary + TypeToNetworkMessageType = new Dictionary { { typeof(ConnectionApprovedMessage), NetworkMessageTypes.ConnectionApproved }, // This MUST be first { typeof(ConnectionRequestMessage), NetworkMessageTypes.ConnectionRequest }, // This MUST be second @@ -111,19 +112,19 @@ internal enum NetworkMessageTypes : uint }; // 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) + if (TypeToNetworkMessageType.Count != messageTypeCount) { - throw new Exception($"Message type to Message type index count mistmatch! Table Count: {messageTypes.Count} | Index Count: {messageTypeCount}"); + throw new Exception($"Message type to Message type index count mistmatch! Table Count: {TypeToNetworkMessageType.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)) + if (!TypeToNetworkMessageType.ContainsKey(messageHandler.MessageType)) { throw new Exception($"Missing message type from lookup table: {messageHandler.MessageType}"); } - adjustedMessageTypes[(int)messageTypes[messageHandler.MessageType]] = messageHandler; + adjustedMessageTypes[(int)TypeToNetworkMessageType[messageHandler.MessageType]] = messageHandler; } // return the NetworkMessageType enum ordered list diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs index bb3e446817..2797b5e3b4 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs @@ -104,7 +104,10 @@ public bool Deserialize(FastBufferReader reader, ref NetworkContext context, int var messageHashesInOrder = new NativeArray(length, Allocator.Temp); for (var i = 0; i < length; ++i) { - var messageVersion = new MessageVersionData(); + var messageVersion = new MessageVersionData() + { + SendMessageType = networkManager.DistributedAuthorityMode, + }; messageVersion.Deserialize(reader); networkManager.ConnectionManager.MessageManager.SetVersion(context.SenderId, messageVersion.Hash, messageVersion.Version); messageHashesInOrder[i] = messageVersion.Hash; diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionRequestMessage.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionRequestMessage.cs index 790791dd24..cd785c4250 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionRequestMessage.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionRequestMessage.cs @@ -30,6 +30,7 @@ public void Serialize(FastBufferWriter writer, int targetVersion) { messageVersion.Serialize(writer); } + // ============================================================ // END FORBIDDEN SEGMENT // ============================================================ @@ -65,9 +66,13 @@ public bool Deserialize(FastBufferReader reader, ref NetworkContext context, int // must go AFTER the message version header. // ============================================================ ByteUnpacker.ReadValueBitPacked(reader, out int length); + for (var i = 0; i < length; ++i) { - var messageVersion = new MessageVersionData(); + var messageVersion = new MessageVersionData() + { + SendMessageType = networkManager.DistributedAuthorityMode, + }; messageVersion.Deserialize(reader); networkManager.ConnectionManager.MessageManager.SetVersion(context.SenderId, messageVersion.Hash, messageVersion.Version); @@ -79,6 +84,7 @@ public bool Deserialize(FastBufferReader reader, ref NetworkContext context, int receivedMessageVersion = messageVersion.Version; } } + // ============================================================ // END FORBIDDEN SEGMENT // ============================================================ diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageMetadata.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageMetadata.cs index 964428030b..a1054b6b0f 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageMetadata.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/Messages/MessageMetadata.cs @@ -7,17 +7,27 @@ internal struct MessageVersionData { public uint Hash; public int Version; + public uint NetworkMessageType; + internal bool SendMessageType; public void Serialize(FastBufferWriter writer) { writer.WriteValueSafe(Hash); BytePacker.WriteValueBitPacked(writer, Version); + if (SendMessageType) + { + BytePacker.WriteValueBitPacked(writer, NetworkMessageType); + } } public void Deserialize(FastBufferReader reader) { reader.ReadValueSafe(out Hash); ByteUnpacker.ReadValueBitPacked(reader, out Version); + if (SendMessageType) + { + ByteUnpacker.ReadValueBitPacked(reader, out NetworkMessageType); + } } } } diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs index d42251e794..ec1cea6c8a 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/NetworkMessageManager.cs @@ -68,8 +68,8 @@ public SendQueueItem(NetworkDelivery delivery, int writerSize, Allocator writerA private NativeList m_IncomingMessageQueue = new NativeList(16, Allocator.Persistent); // These array will grow as we need more message handlers. 4 is just a starting size. - private MessageHandler[] m_MessageHandlers = new MessageHandler[4]; - private Type[] m_ReverseTypeMap = new Type[4]; + private MessageHandler[] m_MessageHandlers = new MessageHandler[Enum.GetValues(typeof(ILPPMessageProvider.NetworkMessageTypes)).Length]; + private Type[] m_ReverseTypeMap = new Type[Enum.GetValues(typeof(ILPPMessageProvider.NetworkMessageTypes)).Length]; private Dictionary m_MessageTypes = new Dictionary(); private Dictionary> m_SendQueues = new Dictionary>(); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/MessageVersionDataTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/MessageVersionDataTests.cs new file mode 100644 index 0000000000..7c8af3272d --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/MessageVersionDataTests.cs @@ -0,0 +1,50 @@ +using System.Collections; +using NUnit.Framework; +using Unity.Netcode.TestHelpers.Runtime; +using UnityEngine.TestTools; + +namespace Unity.Netcode.RuntimeTests +{ + [TestFixture(HostOrServer.DAHost)] + [TestFixture(HostOrServer.Host)] + [TestFixture(HostOrServer.Server)] + internal class MessageVersionDataTests : NetcodeIntegrationTest + { + protected override int NumberOfClients => 2; + + private NetworkManager m_SessionOwner; + + public MessageVersionDataTests(HostOrServer hostOrServer) : base(hostOrServer) { } + + private void ValidateConnectionRequest(NetworkManager networkManager) + { + var message = networkManager.ConnectionManager.GenerateConnectionRequestMessage(); + + foreach (var messageVersionData in message.MessageVersions) + { + Assert.True(messageVersionData.SendMessageType == m_DistributedAuthority, $"Include {nameof(MessageVersionData.SendMessageType)} is {messageVersionData.SendMessageType} and distributed authority is {m_DistributedAuthority}!"); + if (m_DistributedAuthority) + { + var type = networkManager.ConnectionManager.MessageManager.GetMessageForHash(messageVersionData.Hash); + var networkMessageType = ILPPMessageProvider.TypeToNetworkMessageType[type]; + Assert.True(messageVersionData.NetworkMessageType == (uint)networkMessageType, $"{nameof(MessageVersionData.NetworkMessageType)} is {messageVersionData.NetworkMessageType} but the hash type derived value is {networkMessageType}!"); + } + } + } + + [UnityTest] + public IEnumerator MessageVersionDataTest() + { + m_SessionOwner = UseCMBService() ? m_ClientNetworkManagers[0] : m_ServerNetworkManager; + + ValidateConnectionRequest(m_SessionOwner); + + foreach (var client in m_ClientNetworkManagers) + { + ValidateConnectionRequest(client); + } + + yield return null; + } + } +} diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/MessageVersionDataTests.cs.meta b/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/MessageVersionDataTests.cs.meta new file mode 100644 index 0000000000..93e50efec9 --- /dev/null +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/MessageVersionDataTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: b0666f7fceaeafa42b6f3f9514fb4778 \ No newline at end of file