Skip to content

Commit bf40c5d

Browse files
fix: networklog can throw exception when no networkmanager exists (#3917)
* fix Fixing exception that could be thrown in NetworkLog if there is no NetworkManager instance. Adding additional check in NetworkObject.OnNetworkBehaviourDestroyed to assure nothing is ever logged about destroying a NetworkBehaviour when shutting down and the NetworkObject is still considered spawned. * test The test that validates the NetworkLog fix. * update Adding change log entry for this fix.
1 parent 60471ae commit bf40c5d

File tree

7 files changed

+71
-5
lines changed

7 files changed

+71
-5
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
2323

2424
### Fixed
2525

26+
- Fixed issue where attempts to use `NetworkLog` when there is no `NetworkManager` instance would result in an exception. (#3917)
2627

2728
### Security
2829

com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,14 @@ private void OnTransformParentChanged()
10201020
NetworkManagerCheckForParent();
10211021
}
10221022

1023+
/// <summary>
1024+
/// For testing purposes when you need the singleton to be null
1025+
/// </summary>
1026+
internal static void ResetSingleton()
1027+
{
1028+
Singleton = null;
1029+
}
1030+
10231031
/// <summary>
10241032
/// Set this NetworkManager instance as the static NetworkManager singleton
10251033
/// </summary>

com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3647,7 +3647,8 @@ internal void OnNetworkBehaviourDestroyed(NetworkBehaviour networkBehaviour)
36473647
{
36483648
if (networkBehaviour.IsSpawned && IsSpawned)
36493649
{
3650-
if (NetworkManagerOwner.LogLevel <= LogLevel.Developer)
3650+
// Only log this warning if we are not shutting down.
3651+
if (!NetworkManagerOwner.ShutdownInProgress && NetworkManagerOwner.LogLevel <= LogLevel.Developer)
36513652
{
36523653
NetworkLog.LogWarning($"{nameof(NetworkBehaviour)}-{networkBehaviour.name} is being destroyed while {nameof(NetworkObject)}-{name} is still spawned! (could break state synchronization)");
36533654
}

com.unity.netcode.gameobjects/Runtime/Logging/NetworkLog.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,21 @@ private static void LogServer(string message, LogType logType)
113113
}
114114
}
115115

116+
private const string k_HeaderStart = "Netcode";
116117
private static string Header()
117118
{
118119
var networkManager = NetworkManagerOverride ??= NetworkManager.Singleton;
119-
if (networkManager.DistributedAuthorityMode)
120+
if (networkManager != null)
120121
{
121-
return "Session-Owner";
122+
if (networkManager.DistributedAuthorityMode)
123+
{
124+
return $"{k_HeaderStart}-Session-Owner";
125+
}
126+
return $"{k_HeaderStart}-Server";
122127
}
123-
return "Netcode-Server";
128+
129+
// If NetworkManager no longer exists, then return the generic header
130+
return k_HeaderStart;
124131
}
125132

126133
internal static void LogInfoServerLocal(string message, ulong sender) => Debug.Log($"[{Header()} Sender={sender}] {message}");

com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/OwnershipPermissionsTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ public IEnumerator ChangeOwnershipWithoutObservers()
445445
authorityInstance.ChangeOwnership(otherClient.LocalClientId);
446446
var senderId = authority.LocalClientId;
447447
var receiverId = otherClient.LocalClientId;
448-
LogAssert.Expect(LogType.Warning, $"[Session-Owner Sender={senderId}] [Invalid Owner] Cannot send Ownership change as client-{receiverId} cannot see {authorityInstance.name}! Use NetworkShow first.");
448+
LogAssert.Expect(LogType.Warning, $"[Netcode-Session-Owner Sender={senderId}] [Invalid Owner] Cannot send Ownership change as client-{receiverId} cannot see {authorityInstance.name}! Use NetworkShow first.");
449449
Assert.True(authorityInstance.IsOwner, $"[Ownership Check] Client-{senderId} should still own this object!");
450450

451451
// Now re-add the client to the Observers list and try to change ownership
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System.Collections;
2+
using Unity.Netcode.TestHelpers.Runtime;
3+
using UnityEngine.TestTools;
4+
5+
namespace Unity.Netcode.RuntimeTests
6+
{
7+
/// <summary>
8+
/// Validates edge cases with <see cref="NetworkLog"/>
9+
/// </summary>
10+
internal class NetworkLogTests : NetcodeIntegrationTest
11+
{
12+
protected override int NumberOfClients => 0;
13+
private bool m_ServerStopped;
14+
15+
/// <summary>
16+
/// Validates that if no <see cref="NetworkManager"/> exists,
17+
/// you can still use NetworkLog with the caveat when one does
18+
/// not exist it will only log locally.
19+
/// (is topology agnostic)
20+
/// </summary>
21+
[UnityTest]
22+
public IEnumerator UseNetworkLogWithNoNetworkManager()
23+
{
24+
m_ServerStopped = false;
25+
var authority = GetAuthorityNetworkManager();
26+
authority.OnServerStopped += OnServerStopped;
27+
authority.Shutdown();
28+
yield return WaitForConditionOrTimeOut(() => m_ServerStopped);
29+
AssertOnTimeout($"Timed out waiting for {nameof(NetworkManager)} to stop!");
30+
// Assure it is destroyed.
31+
UnityEngine.Object.Destroy(authority);
32+
authority = null;
33+
34+
// Clear out the singleton to assure NetworkLog has no references to a NetworkManager
35+
NetworkManager.ResetSingleton();
36+
37+
// Validate you can use NetworkLog without any NetworkManager instance.
38+
NetworkLog.LogInfoServer($"Test a message to the server with no {nameof(NetworkManager)}.");
39+
// No exceptions thrown is considered passing.
40+
}
41+
42+
private void OnServerStopped(bool obj)
43+
{
44+
m_ServerStopped = true;
45+
}
46+
}
47+
}

com.unity.netcode.gameobjects/Tests/Runtime/NetworkLogTests.cs.meta

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)