diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index 775a39a743..8976fb7ff8 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -6,6 +6,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com). +## [Unreleased] + +### Added + +### Fixed + +- Fixed issue where NetworkTransform could potentially attempt to "unregister" a named message prior to it being registered. (#2807) + +### Changed + +- Changed `CustomMessageManager` so it no longer attempts to register or "unregister" a null or empty string and will log an error if this condition occurs. (#2807) + + ## [1.8.0] - 2023-12-12 ### Added diff --git a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs index c463d3955a..7f8f0f7994 100644 --- a/com.unity.netcode.gameobjects/Components/NetworkTransform.cs +++ b/com.unity.netcode.gameobjects/Components/NetworkTransform.cs @@ -2763,7 +2763,7 @@ public override void OnNetworkSpawn() public override void OnNetworkDespawn() { // During destroy, use NetworkBehaviour.NetworkManager as opposed to m_CachedNetworkManager - if (!NetworkManager.ShutdownInProgress && NetworkManager.CustomMessagingManager != null) + if (!NetworkManager.ShutdownInProgress && NetworkManager.CustomMessagingManager != null && !string.IsNullOrEmpty(m_MessageName)) { NetworkManager.CustomMessagingManager.UnregisterNamedMessageHandler(m_MessageName); } diff --git a/com.unity.netcode.gameobjects/Runtime/Messaging/CustomMessageManager.cs b/com.unity.netcode.gameobjects/Runtime/Messaging/CustomMessageManager.cs index 4e15ec6496..1ae806a575 100644 --- a/com.unity.netcode.gameobjects/Runtime/Messaging/CustomMessageManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Messaging/CustomMessageManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Unity.Collections; +using UnityEngine; namespace Unity.Netcode { @@ -199,6 +200,14 @@ internal void InvokeNamedMessage(ulong hash, ulong sender, FastBufferReader read /// The callback to run when a named message is received. public void RegisterNamedMessageHandler(string name, HandleNamedMessageDelegate callback) { + if (string.IsNullOrEmpty(name)) + { + if (m_NetworkManager.LogLevel <= LogLevel.Error) + { + Debug.LogError($"[{nameof(CustomMessagingManager.RegisterNamedMessageHandler)}] Cannot register a named message of type null or empty!"); + } + return; + } var hash32 = XXHash.Hash32(name); var hash64 = XXHash.Hash64(name); @@ -215,6 +224,15 @@ public void RegisterNamedMessageHandler(string name, HandleNamedMessageDelegate /// The name of the message. public void UnregisterNamedMessageHandler(string name) { + if (string.IsNullOrEmpty(name)) + { + if (m_NetworkManager.LogLevel <= LogLevel.Error) + { + Debug.LogError($"[{nameof(CustomMessagingManager.UnregisterNamedMessageHandler)}] Cannot unregister a named message of type null or empty!"); + } + return; + } + var hash32 = XXHash.Hash32(name); var hash64 = XXHash.Hash64(name); diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/NamedMessageTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/NamedMessageTests.cs index 90eeb71cab..ae243cc517 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/NamedMessageTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Messaging/NamedMessageTests.cs @@ -86,6 +86,24 @@ public void NamedMessageIsReceivedOnHostWithContent() Assert.AreEqual(m_ServerNetworkManager.LocalClientId, receivedMessageSender); } + private void MockNamedMessageCallback(ulong sender, FastBufferReader reader) + { + + } + + [Test] + public void NullOrEmptyNamedMessageDoesNotThrowException() + { + LogAssert.Expect(UnityEngine.LogType.Error, $"[{nameof(CustomMessagingManager.RegisterNamedMessageHandler)}] Cannot register a named message of type null or empty!"); + m_ServerNetworkManager.CustomMessagingManager.RegisterNamedMessageHandler(string.Empty, MockNamedMessageCallback); + LogAssert.Expect(UnityEngine.LogType.Error, $"[{nameof(CustomMessagingManager.RegisterNamedMessageHandler)}] Cannot register a named message of type null or empty!"); + m_ServerNetworkManager.CustomMessagingManager.RegisterNamedMessageHandler(null, MockNamedMessageCallback); + LogAssert.Expect(UnityEngine.LogType.Error, $"[{nameof(CustomMessagingManager.UnregisterNamedMessageHandler)}] Cannot unregister a named message of type null or empty!"); + m_ServerNetworkManager.CustomMessagingManager.UnregisterNamedMessageHandler(string.Empty); + LogAssert.Expect(UnityEngine.LogType.Error, $"[{nameof(CustomMessagingManager.UnregisterNamedMessageHandler)}] Cannot unregister a named message of type null or empty!"); + m_ServerNetworkManager.CustomMessagingManager.UnregisterNamedMessageHandler(null); + } + [UnityTest] public IEnumerator NamedMessageIsReceivedOnMultipleClientsWithContent() {