diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index 5cd304969a..72765d9252 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -19,12 +19,12 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Fixed +- Custom messages are now properly received by the local client when they're sent while running in host mode. (#2296) - Fixed issue where the host would receive more than one event completed notification when loading or unloading a scene only when no clients were connected. (#2292) - Fixed an issue in `UnityTransport` where an error would be logged if the 'Use Encryption' flag was enabled with a Relay configuration that used a secure protocol. (#2289) - Fixed issue where in-scene placed `NetworkObjects` were not honoring the `AutoObjectParentSync` property. (#2281) - Fixed the issue where `NetworkManager.OnClientConnectedCallback` was being invoked before in-scene placed `NetworkObject`s had been spawned when starting `NetworkManager` as a host. (#2277) - Creating a `FastBufferReader` with `Allocator.None` will not result in extra memory being allocated for the buffer (since it's owned externally in that scenario). (#2265) - ### Removed - Removed the `NetworkObject` auto-add and Multiplayer Tools install reminder settings from the Menu interface. (#2285) diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/CustomMessageManager.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/CustomMessageManager.cs index aa69ba73fc..573d645b42 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/CustomMessageManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/CustomMessageManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Unity.Collections; namespace Unity.Netcode { @@ -68,9 +69,23 @@ public void SendUnnamedMessage(IReadOnlyList clientIds, FastBufferWriter if (clientIds == null) { - throw new ArgumentNullException("You must pass in a valid clientId List"); + throw new ArgumentNullException(nameof(clientIds), "You must pass in a valid clientId List"); } + if (m_NetworkManager.IsHost) + { + for (var i = 0; i < clientIds.Count; ++i) + { + if (clientIds[i] == m_NetworkManager.LocalClientId) + { + InvokeUnnamedMessage( + m_NetworkManager.LocalClientId, + new FastBufferReader(messageBuffer, Allocator.None), + 0 + ); + } + } + } var message = new UnnamedMessage { SendData = messageBuffer @@ -92,6 +107,18 @@ public void SendUnnamedMessage(IReadOnlyList clientIds, FastBufferWriter /// The delivery type (QoS) to send data with public void SendUnnamedMessage(ulong clientId, FastBufferWriter messageBuffer, NetworkDelivery networkDelivery = NetworkDelivery.ReliableSequenced) { + if (m_NetworkManager.IsHost) + { + if (clientId == m_NetworkManager.LocalClientId) + { + InvokeUnnamedMessage( + m_NetworkManager.LocalClientId, + new FastBufferReader(messageBuffer, Allocator.None), + 0 + ); + return; + } + } var message = new UnnamedMessage { SendData = messageBuffer @@ -220,6 +247,20 @@ public void SendNamedMessage(string messageName, ulong clientId, FastBufferWrite hash = XXHash.Hash64(messageName); break; } + if (m_NetworkManager.IsHost) + { + if (clientId == m_NetworkManager.LocalClientId) + { + InvokeNamedMessage( + hash, + m_NetworkManager.LocalClientId, + new FastBufferReader(messageStream, Allocator.None), + 0 + ); + + return; + } + } var message = new NamedMessage { @@ -251,7 +292,7 @@ public void SendNamedMessage(string messageName, IReadOnlyList clientIds, if (clientIds == null) { - throw new ArgumentNullException("You must pass in a valid clientId List"); + throw new ArgumentNullException(nameof(clientIds), "You must pass in a valid clientId List"); } ulong hash = 0; @@ -264,6 +305,21 @@ public void SendNamedMessage(string messageName, IReadOnlyList clientIds, hash = XXHash.Hash64(messageName); break; } + if (m_NetworkManager.IsHost) + { + for (var i = 0; i < clientIds.Count; ++i) + { + if (clientIds[i] == m_NetworkManager.LocalClientId) + { + InvokeNamedMessage( + hash, + m_NetworkManager.LocalClientId, + new FastBufferReader(messageStream, Allocator.None), + 0 + ); + } + } + } var message = new NamedMessage { Hash = hash, diff --git a/com.unity.netcode.gameobjects/TestHelpers/Runtime/MessageHooksConditional.cs b/com.unity.netcode.gameobjects/TestHelpers/Runtime/MessageHooksConditional.cs index f16978ef95..80b2dd84a0 100644 --- a/com.unity.netcode.gameobjects/TestHelpers/Runtime/MessageHooksConditional.cs +++ b/com.unity.netcode.gameobjects/TestHelpers/Runtime/MessageHooksConditional.cs @@ -39,7 +39,10 @@ protected override bool OnHasConditionBeenReached() if (AllMessagesReceived) { - return AllMessagesReceived; + foreach (var entry in m_MessageHookEntries) + { + entry.RemoveHook(); + } } return AllMessagesReceived; @@ -110,6 +113,11 @@ internal void AssignMessageType() where T : INetworkMessage Initialize(); } + internal void RemoveHook() + { + m_NetworkManager.MessagingSystem.Unhook(MessageHooks); + } + internal void AssignMessageType(Type type) { MessageType = type.Name; diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/NamedMessageTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/NamedMessageTests.cs index f2cde70626..b96c63d9fb 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/NamedMessageTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/NamedMessageTests.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using NUnit.Framework; using Unity.Collections; -using UnityEngine; using UnityEngine.TestTools; using Unity.Netcode.TestHelpers.Runtime; @@ -27,6 +26,18 @@ protected override NetworkManagerInstatiationMode OnSetIntegrationTestMode() public IEnumerator NamedMessageIsReceivedOnClientWithContent() { var messageName = Guid.NewGuid().ToString(); + + ulong receivedMessageSender = 0; + var receivedMessageContent = new ForceNetworkSerializeByMemcpy(new Guid()); + FirstClient.CustomMessagingManager.RegisterNamedMessageHandler( + messageName, + (ulong sender, FastBufferReader reader) => + { + receivedMessageSender = sender; + + reader.ReadValueSafe(out receivedMessageContent); + }); + var messageContent = new ForceNetworkSerializeByMemcpy(Guid.NewGuid()); var writer = new FastBufferWriter(1300, Allocator.Temp); using (writer) @@ -38,9 +49,20 @@ public IEnumerator NamedMessageIsReceivedOnClientWithContent() writer); } + yield return WaitForMessageReceived(new List { FirstClient }); + + Assert.AreEqual(messageContent.Value, receivedMessageContent.Value); + Assert.AreEqual(m_ServerNetworkManager.LocalClientId, receivedMessageSender); + } + + [Test] + public void NamedMessageIsReceivedOnHostWithContent() + { + var messageName = Guid.NewGuid().ToString(); + ulong receivedMessageSender = 0; var receivedMessageContent = new ForceNetworkSerializeByMemcpy(new Guid()); - FirstClient.CustomMessagingManager.RegisterNamedMessageHandler( + m_ServerNetworkManager.CustomMessagingManager.RegisterNamedMessageHandler( messageName, (ulong sender, FastBufferReader reader) => { @@ -49,16 +71,6 @@ public IEnumerator NamedMessageIsReceivedOnClientWithContent() reader.ReadValueSafe(out receivedMessageContent); }); - yield return new WaitForSeconds(0.2f); - - Assert.AreEqual(messageContent.Value, receivedMessageContent.Value); - Assert.AreEqual(m_ServerNetworkManager.LocalClientId, receivedMessageSender); - } - - [UnityTest] - public IEnumerator NamedMessageIsReceivedOnMultipleClientsWithContent() - { - var messageName = Guid.NewGuid().ToString(); var messageContent = new ForceNetworkSerializeByMemcpy(Guid.NewGuid()); var writer = new FastBufferWriter(1300, Allocator.Temp); using (writer) @@ -66,10 +78,19 @@ public IEnumerator NamedMessageIsReceivedOnMultipleClientsWithContent() writer.WriteValueSafe(messageContent); m_ServerNetworkManager.CustomMessagingManager.SendNamedMessage( messageName, - new List { FirstClient.LocalClientId, SecondClient.LocalClientId }, + m_ServerNetworkManager.LocalClientId, writer); } + Assert.AreEqual(messageContent.Value, receivedMessageContent.Value); + Assert.AreEqual(m_ServerNetworkManager.LocalClientId, receivedMessageSender); + } + + [UnityTest] + public IEnumerator NamedMessageIsReceivedOnMultipleClientsWithContent() + { + var messageName = Guid.NewGuid().ToString(); + ulong firstReceivedMessageSender = 0; var firstReceivedMessageContent = new ForceNetworkSerializeByMemcpy(new Guid()); FirstClient.CustomMessagingManager.RegisterNamedMessageHandler( @@ -92,26 +113,44 @@ public IEnumerator NamedMessageIsReceivedOnMultipleClientsWithContent() reader.ReadValueSafe(out secondReceivedMessageContent); }); - yield return new WaitForSeconds(0.2f); + ulong thirdReceivedMessageSender = 0; + var thirdReceivedMessageContent = new ForceNetworkSerializeByMemcpy(new Guid()); + m_ServerNetworkManager.CustomMessagingManager.RegisterNamedMessageHandler( + messageName, + (ulong sender, FastBufferReader reader) => + { + thirdReceivedMessageSender = sender; + + reader.ReadValueSafe(out thirdReceivedMessageContent); + }); + + var messageContent = new ForceNetworkSerializeByMemcpy(Guid.NewGuid()); + var writer = new FastBufferWriter(1300, Allocator.Temp); + using (writer) + { + writer.WriteValueSafe(messageContent); + m_ServerNetworkManager.CustomMessagingManager.SendNamedMessage( + messageName, + new List { m_ServerNetworkManager.LocalClientId, FirstClient.LocalClientId, SecondClient.LocalClientId }, + writer); + } + + yield return WaitForMessageReceived(new List { FirstClient, SecondClient }); Assert.AreEqual(messageContent.Value, firstReceivedMessageContent.Value); Assert.AreEqual(m_ServerNetworkManager.LocalClientId, firstReceivedMessageSender); Assert.AreEqual(messageContent.Value, secondReceivedMessageContent.Value); Assert.AreEqual(m_ServerNetworkManager.LocalClientId, secondReceivedMessageSender); + + Assert.AreEqual(messageContent.Value, thirdReceivedMessageContent.Value); + Assert.AreEqual(m_ServerNetworkManager.LocalClientId, thirdReceivedMessageSender); } [UnityTest] public IEnumerator WhenSendingNamedMessageToAll_AllClientsReceiveIt() { var messageName = Guid.NewGuid().ToString(); - var messageContent = new ForceNetworkSerializeByMemcpy(Guid.NewGuid()); - var writer = new FastBufferWriter(1300, Allocator.Temp); - using (writer) - { - writer.WriteValueSafe(messageContent); - m_ServerNetworkManager.CustomMessagingManager.SendNamedMessageToAll(messageName, writer); - } ulong firstReceivedMessageSender = 0; var firstReceivedMessageContent = new ForceNetworkSerializeByMemcpy(new Guid()); @@ -135,13 +174,35 @@ public IEnumerator WhenSendingNamedMessageToAll_AllClientsReceiveIt() reader.ReadValueSafe(out secondReceivedMessageContent); }); - yield return new WaitForSeconds(0.2f); + ulong thirdReceivedMessageSender = 0; + var thirdReceivedMessageContent = new ForceNetworkSerializeByMemcpy(new Guid()); + m_ServerNetworkManager.CustomMessagingManager.RegisterNamedMessageHandler( + messageName, + (ulong sender, FastBufferReader reader) => + { + thirdReceivedMessageSender = sender; + + reader.ReadValueSafe(out thirdReceivedMessageContent); + }); + + var messageContent = new ForceNetworkSerializeByMemcpy(Guid.NewGuid()); + var writer = new FastBufferWriter(1300, Allocator.Temp); + using (writer) + { + writer.WriteValueSafe(messageContent); + m_ServerNetworkManager.CustomMessagingManager.SendNamedMessageToAll(messageName, writer); + } + + yield return WaitForMessageReceived(new List { FirstClient, SecondClient }); Assert.AreEqual(messageContent.Value, firstReceivedMessageContent.Value); Assert.AreEqual(m_ServerNetworkManager.LocalClientId, firstReceivedMessageSender); Assert.AreEqual(messageContent.Value, secondReceivedMessageContent.Value); Assert.AreEqual(m_ServerNetworkManager.LocalClientId, secondReceivedMessageSender); + + Assert.AreEqual(messageContent.Value, thirdReceivedMessageContent.Value); + Assert.AreEqual(m_ServerNetworkManager.LocalClientId, thirdReceivedMessageSender); } [Test] diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/UnnamedMessageTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/UnnamedMessageTests.cs index 711e7cf137..5c88696c85 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/UnnamedMessageTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/UnnamedMessageTests.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using NUnit.Framework; using Unity.Collections; -using UnityEngine; using UnityEngine.TestTools; using Unity.Netcode.TestHelpers.Runtime; @@ -19,6 +18,16 @@ public class UnnamedMessageTests : NetcodeIntegrationTest [UnityTest] public IEnumerator UnnamedMessageIsReceivedOnClientWithContent() { + ulong receivedMessageSender = 0; + var receivedMessageContent = new ForceNetworkSerializeByMemcpy(new Guid()); + FirstClient.CustomMessagingManager.OnUnnamedMessage += + (ulong sender, FastBufferReader reader) => + { + receivedMessageSender = sender; + + reader.ReadValueSafe(out receivedMessageContent); + }; + var messageContent = new ForceNetworkSerializeByMemcpy(Guid.NewGuid()); var writer = new FastBufferWriter(1300, Allocator.Temp); using (writer) @@ -29,9 +38,18 @@ public IEnumerator UnnamedMessageIsReceivedOnClientWithContent() writer); } + yield return WaitForMessageReceived(new List { FirstClient }); + + Assert.AreEqual(messageContent.Value, receivedMessageContent.Value); + Assert.AreEqual(m_ServerNetworkManager.LocalClientId, receivedMessageSender); + } + + [Test] + public void UnnamedMessageIsReceivedOnHostWithContent() + { ulong receivedMessageSender = 0; var receivedMessageContent = new ForceNetworkSerializeByMemcpy(new Guid()); - FirstClient.CustomMessagingManager.OnUnnamedMessage += + m_ServerNetworkManager.CustomMessagingManager.OnUnnamedMessage += (ulong sender, FastBufferReader reader) => { receivedMessageSender = sender; @@ -39,25 +57,23 @@ public IEnumerator UnnamedMessageIsReceivedOnClientWithContent() reader.ReadValueSafe(out receivedMessageContent); }; - yield return new WaitForSeconds(0.2f); - - Assert.AreEqual(messageContent.Value, receivedMessageContent.Value); - Assert.AreEqual(m_ServerNetworkManager.LocalClientId, receivedMessageSender); - } - - [UnityTest] - public IEnumerator UnnamedMessageIsReceivedOnMultipleClientsWithContent() - { var messageContent = new ForceNetworkSerializeByMemcpy(Guid.NewGuid()); var writer = new FastBufferWriter(1300, Allocator.Temp); using (writer) { writer.WriteValueSafe(messageContent); m_ServerNetworkManager.CustomMessagingManager.SendUnnamedMessage( - new List { FirstClient.LocalClientId, SecondClient.LocalClientId }, + m_ServerNetworkManager.LocalClientId, writer); } + Assert.AreEqual(messageContent.Value, receivedMessageContent.Value); + Assert.AreEqual(m_ServerNetworkManager.LocalClientId, receivedMessageSender); + } + + [UnityTest] + public IEnumerator UnnamedMessageIsReceivedOnMultipleClientsWithContent() + { ulong firstReceivedMessageSender = 0; var firstReceivedMessageContent = new ForceNetworkSerializeByMemcpy(new Guid()); FirstClient.CustomMessagingManager.OnUnnamedMessage += @@ -78,26 +94,41 @@ public IEnumerator UnnamedMessageIsReceivedOnMultipleClientsWithContent() reader.ReadValueSafe(out secondReceivedMessageContent); }; - yield return new WaitForSeconds(0.2f); + ulong thirdReceivedMessageSender = 0; + var thirdReceivedMessageContent = new ForceNetworkSerializeByMemcpy(new Guid()); + m_ServerNetworkManager.CustomMessagingManager.OnUnnamedMessage += + (ulong sender, FastBufferReader reader) => + { + thirdReceivedMessageSender = sender; + + reader.ReadValueSafe(out thirdReceivedMessageContent); + }; + + var messageContent = new ForceNetworkSerializeByMemcpy(Guid.NewGuid()); + var writer = new FastBufferWriter(1300, Allocator.Temp); + using (writer) + { + writer.WriteValueSafe(messageContent); + m_ServerNetworkManager.CustomMessagingManager.SendUnnamedMessage( + new List { m_ServerNetworkManager.LocalClientId, FirstClient.LocalClientId, SecondClient.LocalClientId }, + writer); + } + + yield return WaitForMessageReceived(new List { FirstClient, SecondClient }); Assert.AreEqual(messageContent.Value, firstReceivedMessageContent.Value); Assert.AreEqual(m_ServerNetworkManager.LocalClientId, firstReceivedMessageSender); Assert.AreEqual(messageContent.Value, secondReceivedMessageContent.Value); Assert.AreEqual(m_ServerNetworkManager.LocalClientId, secondReceivedMessageSender); + + Assert.AreEqual(messageContent.Value, thirdReceivedMessageContent.Value); + Assert.AreEqual(m_ServerNetworkManager.LocalClientId, thirdReceivedMessageSender); } [UnityTest] public IEnumerator WhenSendingUnnamedMessageToAll_AllClientsReceiveIt() { - var messageContent = new ForceNetworkSerializeByMemcpy(Guid.NewGuid()); - var writer = new FastBufferWriter(1300, Allocator.Temp); - using (writer) - { - writer.WriteValueSafe(messageContent); - m_ServerNetworkManager.CustomMessagingManager.SendUnnamedMessageToAll(writer); - } - ulong firstReceivedMessageSender = 0; var firstReceivedMessageContent = new ForceNetworkSerializeByMemcpy(new Guid()); FirstClient.CustomMessagingManager.OnUnnamedMessage += @@ -118,13 +149,34 @@ public IEnumerator WhenSendingUnnamedMessageToAll_AllClientsReceiveIt() reader.ReadValueSafe(out secondReceivedMessageContent); }; - yield return new WaitForSeconds(0.2f); + ulong thirdReceivedMessageSender = 0; + var thirdReceivedMessageContent = new ForceNetworkSerializeByMemcpy(new Guid()); + m_ServerNetworkManager.CustomMessagingManager.OnUnnamedMessage += + (ulong sender, FastBufferReader reader) => + { + thirdReceivedMessageSender = sender; + + reader.ReadValueSafe(out thirdReceivedMessageContent); + }; + + var messageContent = new ForceNetworkSerializeByMemcpy(Guid.NewGuid()); + var writer = new FastBufferWriter(1300, Allocator.Temp); + using (writer) + { + writer.WriteValueSafe(messageContent); + m_ServerNetworkManager.CustomMessagingManager.SendUnnamedMessageToAll(writer); + } + + yield return WaitForMessageReceived(new List { FirstClient, SecondClient }); Assert.AreEqual(messageContent.Value, firstReceivedMessageContent.Value); Assert.AreEqual(m_ServerNetworkManager.LocalClientId, firstReceivedMessageSender); Assert.AreEqual(messageContent.Value, secondReceivedMessageContent.Value); Assert.AreEqual(m_ServerNetworkManager.LocalClientId, secondReceivedMessageSender); + + Assert.AreEqual(messageContent.Value, thirdReceivedMessageContent.Value); + Assert.AreEqual(m_ServerNetworkManager.LocalClientId, thirdReceivedMessageSender); } [Test]