Skip to content

fix: networkmanager prefab validation and no scene management manual test #1073

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Aug 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
5a32663
fix
NoelStephensUnity Aug 20, 2021
35f4ffd
test
NoelStephensUnity Aug 20, 2021
0edd910
fix
NoelStephensUnity Aug 20, 2021
6a42869
Merge branch 'develop' into fix/prefabValidationNoSceneManagement
NoelStephensUnity Aug 20, 2021
b4886a3
refactor and style
NoelStephensUnity Aug 21, 2021
e1339bf
test and style
NoelStephensUnity Aug 21, 2021
8841bd9
Merge branch 'fix/prefabValidationNoSceneManagement' of https://githu…
NoelStephensUnity Aug 23, 2021
ecc7982
Merge branch 'develop' into fix/prefabValidationNoSceneManagement
NoelStephensUnity Aug 23, 2021
beecc47
Merge branch 'develop' into fix/prefabValidationNoSceneManagement
NoelStephensUnity Aug 23, 2021
fa7eaba
fix
NoelStephensUnity Aug 23, 2021
f98fce9
Merge branch 'develop' into fix/prefabValidationNoSceneManagement
0xFA11 Aug 24, 2021
bce33c8
Update com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
NoelStephensUnity Aug 24, 2021
a587c39
Update com.unity.netcode.gameobjects/Tests/Runtime/NetworkPrefabHandl…
NoelStephensUnity Aug 24, 2021
fd263d5
Update com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
NoelStephensUnity Aug 24, 2021
7fb0aeb
Update com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
NoelStephensUnity Aug 24, 2021
d02bad2
Update com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
NoelStephensUnity Aug 24, 2021
df56d7e
Merge branch 'develop' into fix/prefabValidationNoSceneManagement
0xFA11 Aug 24, 2021
9163f16
Merge branch 'develop' into fix/prefabValidationNoSceneManagement
NoelStephensUnity Aug 24, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 122 additions & 35 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,10 @@ private void Initialize(bool server)
// Build the NetworkPrefabOverrideLinks dictionary
for (int i = 0; i < NetworkConfig.NetworkPrefabs.Count; i++)
{
if (NetworkConfig.NetworkPrefabs[i] == null || NetworkConfig.NetworkPrefabs[i].Prefab == null)
var sourcePrefabGlobalObjectIdHash = (uint)0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

last but not least, I'd suggest to run ./standards.py --check and maybe ./standards.py --fix locally to check & fix spaces/namings locally — just in case :P

var targetPrefabGlobalObjectIdHash = (uint)0;
var networkObject = (NetworkObject)null;
if (NetworkConfig.NetworkPrefabs[i] == null || (NetworkConfig.NetworkPrefabs[i].Prefab == null && NetworkConfig.NetworkPrefabs[i].Override == NetworkPrefabOverride.None))
{
if (NetworkLog.CurrentLogLevel <= LogLevel.Error)
{
Expand All @@ -474,60 +477,144 @@ private void Initialize(bool server)
}

removeEmptyPrefabs.Add(i);

continue;
}
else if (NetworkConfig.NetworkPrefabs[i].Prefab.GetComponent<NetworkObject>() == null)
else if (NetworkConfig.NetworkPrefabs[i].Override == NetworkPrefabOverride.None)
{
if (NetworkLog.CurrentLogLevel <= LogLevel.Error)
networkObject = NetworkConfig.NetworkPrefabs[i].Prefab.GetComponent<NetworkObject>();
if (networkObject == null)
{
NetworkLog.LogWarning(
$"{nameof(NetworkPrefab)} (\"{NetworkConfig.NetworkPrefabs[i].Prefab.name}\") is missing a {nameof(NetworkObject)} component");
if (NetworkLog.CurrentLogLevel <= LogLevel.Error)
{
NetworkLog.LogWarning($"{nameof(NetworkPrefab)} (\"{NetworkConfig.NetworkPrefabs[i].Prefab.name}\") is missing " +
$"a {nameof(NetworkObject)} component (entry will be ignored).");
}
removeEmptyPrefabs.Add(i);
continue;
}

// Provide the name of the prefab with issues so the user can more easily find the prefab and fix it
Debug.LogWarning($"{nameof(NetworkPrefab)} (\"{NetworkConfig.NetworkPrefabs[i].Prefab.name}\") will be removed and ignored.");
removeEmptyPrefabs.Add(i);

continue;
// Otherwise get the GlobalObjectIdHash value
sourcePrefabGlobalObjectIdHash = networkObject.GlobalObjectIdHash;
}

var networkObject = NetworkConfig.NetworkPrefabs[i].Prefab.GetComponent<NetworkObject>();

// Assign the appropriate GlobalObjectIdHash to the appropriate NetworkPrefab
if (!NetworkConfig.NetworkPrefabOverrideLinks.ContainsKey(networkObject.GlobalObjectIdHash))
else // Validate Overrides
{
// Validate source prefab override values first
switch (NetworkConfig.NetworkPrefabs[i].Override)
{
default:
case NetworkPrefabOverride.None:
NetworkConfig.NetworkPrefabOverrideLinks.Add(networkObject.GlobalObjectIdHash,
NetworkConfig.NetworkPrefabs[i]);
break;
case NetworkPrefabOverride.Prefab:
case NetworkPrefabOverride.Hash:
{
var sourcePrefabGlobalObjectIdHash = NetworkConfig.NetworkPrefabs[i].SourcePrefabToOverride.GetComponent<NetworkObject>().GlobalObjectIdHash;
NetworkConfig.NetworkPrefabOverrideLinks.Add(sourcePrefabGlobalObjectIdHash, NetworkConfig.NetworkPrefabs[i]);

var targetPrefabGlobalObjectIdHash = NetworkConfig.NetworkPrefabs[i].OverridingTargetPrefab.GetComponent<NetworkObject>().GlobalObjectIdHash;
NetworkConfig.OverrideToNetworkPrefab.Add(targetPrefabGlobalObjectIdHash, sourcePrefabGlobalObjectIdHash);
if (NetworkConfig.NetworkPrefabs[i].SourceHashToOverride == 0)
{
if (NetworkLog.CurrentLogLevel <= LogLevel.Error)
{
NetworkLog.LogWarning($"{nameof(NetworkPrefab)} {nameof(NetworkPrefab.SourceHashToOverride)} is zero (entry will be ignored).");
}
removeEmptyPrefabs.Add(i);
continue;
}
sourcePrefabGlobalObjectIdHash = NetworkConfig.NetworkPrefabs[i].SourceHashToOverride;
break;
}
break;
case NetworkPrefabOverride.Hash:
case NetworkPrefabOverride.Prefab:
{
var sourcePrefabGlobalObjectIdHash = NetworkConfig.NetworkPrefabs[i].SourceHashToOverride;
NetworkConfig.NetworkPrefabOverrideLinks.Add(sourcePrefabGlobalObjectIdHash, NetworkConfig.NetworkPrefabs[i]);
if (NetworkConfig.NetworkPrefabs[i].SourcePrefabToOverride == null)
{
if (NetworkLog.CurrentLogLevel <= LogLevel.Error)
{
NetworkLog.LogWarning($"{nameof(NetworkPrefab)} {nameof(NetworkPrefab.SourcePrefabToOverride)} is null (entry will be ignored).");
}
Debug.LogWarning($"{nameof(NetworkPrefab)} override entry {NetworkConfig.NetworkPrefabs[i].SourceHashToOverride} will be removed and ignored.");
removeEmptyPrefabs.Add(i);
continue;
}
else
{
networkObject = NetworkConfig.NetworkPrefabs[i].SourcePrefabToOverride.GetComponent<NetworkObject>();
if (networkObject == null)
{
if (NetworkLog.CurrentLogLevel <= LogLevel.Error)
{
NetworkLog.LogWarning($"{nameof(NetworkPrefab)} ({NetworkConfig.NetworkPrefabs[i].SourcePrefabToOverride.name}) " +
$"is missing a {nameof(NetworkObject)} component (entry will be ignored).");
}
Debug.LogWarning($"{nameof(NetworkPrefab)} override entry (\"{NetworkConfig.NetworkPrefabs[i].SourcePrefabToOverride.name}\") will be removed and ignored.");
removeEmptyPrefabs.Add(i);
continue;
}
sourcePrefabGlobalObjectIdHash = networkObject.GlobalObjectIdHash;
}
break;
}
}

var targetPrefabGlobalObjectIdHash = NetworkConfig.NetworkPrefabs[i].OverridingTargetPrefab.GetComponent<NetworkObject>().GlobalObjectIdHash;
NetworkConfig.OverrideToNetworkPrefab.Add(targetPrefabGlobalObjectIdHash, sourcePrefabGlobalObjectIdHash);
// Validate target prefab override values next
if (NetworkConfig.NetworkPrefabs[i].OverridingTargetPrefab == null)
{
if (NetworkLog.CurrentLogLevel <= LogLevel.Error)
{
NetworkLog.LogWarning($"{nameof(NetworkPrefab)} {nameof(NetworkPrefab.OverridingTargetPrefab)} is null!");
}
removeEmptyPrefabs.Add(i);
switch (NetworkConfig.NetworkPrefabs[i].Override)
{
case NetworkPrefabOverride.Hash:
{
Debug.LogWarning($"{nameof(NetworkPrefab)} override entry {NetworkConfig.NetworkPrefabs[i].SourceHashToOverride} will be removed and ignored.");
break;
}
case NetworkPrefabOverride.Prefab:
{
Debug.LogWarning($"{nameof(NetworkPrefab)} override entry ({NetworkConfig.NetworkPrefabs[i].SourcePrefabToOverride.name}) will be removed and ignored.");
break;
}
}
continue;
}
else
{
targetPrefabGlobalObjectIdHash = NetworkConfig.NetworkPrefabs[i].OverridingTargetPrefab.GetComponent<NetworkObject>().GlobalObjectIdHash;
}
}

// Assign the appropriate GlobalObjectIdHash to the appropriate NetworkPrefab
if (!NetworkConfig.NetworkPrefabOverrideLinks.ContainsKey(sourcePrefabGlobalObjectIdHash))
{
if (NetworkConfig.NetworkPrefabs[i].Override == NetworkPrefabOverride.None)
{
NetworkConfig.NetworkPrefabOverrideLinks.Add(sourcePrefabGlobalObjectIdHash, NetworkConfig.NetworkPrefabs[i]);
}
else
{
if (!NetworkConfig.OverrideToNetworkPrefab.ContainsKey(targetPrefabGlobalObjectIdHash))
{
switch (NetworkConfig.NetworkPrefabs[i].Override)
{
case NetworkPrefabOverride.Prefab:
{
NetworkConfig.NetworkPrefabOverrideLinks.Add(sourcePrefabGlobalObjectIdHash, NetworkConfig.NetworkPrefabs[i]);
NetworkConfig.OverrideToNetworkPrefab.Add(targetPrefabGlobalObjectIdHash, sourcePrefabGlobalObjectIdHash);
}
break;
case NetworkPrefabOverride.Hash:
{
NetworkConfig.NetworkPrefabOverrideLinks.Add(sourcePrefabGlobalObjectIdHash, NetworkConfig.NetworkPrefabs[i]);
NetworkConfig.OverrideToNetworkPrefab.Add(targetPrefabGlobalObjectIdHash, sourcePrefabGlobalObjectIdHash);
}
break;
}
break;
}
else
{
// This can happen if a user tries to make several GlobalObjectIdHash values point to the same target
Debug.LogError($"{nameof(NetworkPrefab)} (\"{networkObject.name}\") has a duplicate {nameof(NetworkObject.GlobalObjectIdHash)} target entry value of: {targetPrefabGlobalObjectIdHash}! Removing entry from list!");
removeEmptyPrefabs.Add(i);
}
}
}
else
{
// This should never happen, but in the case it somehow does log an error and remove the duplicate entry
Debug.LogError($"{nameof(NetworkPrefab)} (\"{NetworkConfig.NetworkPrefabs[i].Prefab.name}\") has a duplicate {nameof(NetworkObject.GlobalObjectIdHash)} {networkObject.GlobalObjectIdHash} entry! Removing entry from list!");
Debug.LogError($"{nameof(NetworkPrefab)} ({networkObject.name}) has a duplicate {nameof(NetworkObject.GlobalObjectIdHash)} source entry value of: {sourcePrefabGlobalObjectIdHash}! Removing entry from list!");
removeEmptyPrefabs.Add(i);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,56 @@ namespace Unity.Netcode.RuntimeTests
/// </summary>
public class NetworkPrefabHandlerTests
{

private const string k_TestPrefabObjectName = "NetworkPrefabTestObject";
private uint m_GlobalObjectIdHashBase = 123456;
private GameObject MakeValidNetworkPrefab()
{
Guid baseObjectID = NetworkManagerHelper.AddGameNetworkObject(k_TestPrefabObjectName + m_GlobalObjectIdHashBase.ToString());
NetworkObject validPrefab = NetworkManagerHelper.InstantiatedNetworkObjects[baseObjectID];
MultiInstanceHelpers.MakeNetworkedObjectTestPrefab(validPrefab, m_GlobalObjectIdHashBase);
m_GlobalObjectIdHashBase++;
return validPrefab.gameObject;
}

/// <summary>
/// Tests the NetwokConfig NetworkPrefabs initialization during NetworkManager's Init method
/// Tests the NetwokConfig NetworkPrefabs initialization during NetworkManager's Init method to make sure that
/// it will still initialize but remove the invalid prefabs
/// </summary>
[Test]
public void NetworkConfigInvalidNetworkPrefabTest()
{
var testPrefabObjectName = "NetworkPrefabHandlerTestObject";
Guid baseObjectID = NetworkManagerHelper.AddGameNetworkObject(testPrefabObjectName);
NetworkObject baseObject = NetworkManagerHelper.InstantiatedNetworkObjects[baseObjectID];

// Add null entry
NetworkManagerHelper.NetworkManagerObject.NetworkConfig.NetworkPrefabs.Add(null);

// Add a NetworkPrefab with no prefab
NetworkManagerHelper.NetworkManagerObject.NetworkConfig.NetworkPrefabs.Add(new NetworkPrefab());

var validNetworkPrefab = new NetworkPrefab();
validNetworkPrefab.Prefab = baseObject.gameObject;
// Add a NetworkPrefab override with an invalid hash
NetworkManagerHelper.NetworkManagerObject.NetworkConfig.NetworkPrefabs.Add(new NetworkPrefab() { Override = NetworkPrefabOverride.Hash, SourceHashToOverride = 0 });

// Add a NetworkPrefab override with a valid hash but an invalid target prefab
NetworkManagerHelper.NetworkManagerObject.NetworkConfig.NetworkPrefabs.Add(new NetworkPrefab() { Override = NetworkPrefabOverride.Hash, SourceHashToOverride = 654321, OverridingTargetPrefab = null });

// Add a NetworkPrefab override with a valid hash to override but an invalid target prefab
NetworkManagerHelper.NetworkManagerObject.NetworkConfig.NetworkPrefabs.Add(new NetworkPrefab() { Override = NetworkPrefabOverride.Prefab, SourceHashToOverride = 654321, OverridingTargetPrefab = null });

// Add a NetworkPrefab override with an invalid source prefab to override
NetworkManagerHelper.NetworkManagerObject.NetworkConfig.NetworkPrefabs.Add(new NetworkPrefab() { Override = NetworkPrefabOverride.Prefab, SourcePrefabToOverride = null });

// Add a NetworkPrefab override with a valid source prefab to override but an invalid target prefab
NetworkManagerHelper.NetworkManagerObject.NetworkConfig.NetworkPrefabs.Add(new NetworkPrefab() { Override = NetworkPrefabOverride.Prefab, SourcePrefabToOverride = MakeValidNetworkPrefab(), OverridingTargetPrefab = null });

// Add a valid prefab
NetworkManagerHelper.NetworkManagerObject.NetworkConfig.NetworkPrefabs.Add(new NetworkPrefab() { Prefab = MakeValidNetworkPrefab() });

// Add a NetworkPrefab override with a valid hash and valid target prefab
NetworkManagerHelper.NetworkManagerObject.NetworkConfig.NetworkPrefabs.Add(new NetworkPrefab() { Override = NetworkPrefabOverride.Hash, SourceHashToOverride = 11111111, OverridingTargetPrefab = MakeValidNetworkPrefab() });

// Add a NetworkPrefab override with a valid prefab and valid target prefab
NetworkManagerHelper.NetworkManagerObject.NetworkConfig.NetworkPrefabs.Add(new NetworkPrefab() { Override = NetworkPrefabOverride.Prefab, SourcePrefabToOverride = MakeValidNetworkPrefab(), OverridingTargetPrefab = MakeValidNetworkPrefab() });

//Add a valid prefab
NetworkManagerHelper.NetworkManagerObject.NetworkConfig.NetworkPrefabs.Add(validNetworkPrefab);
var exceptionOccurred = false;
try
{
Expand All @@ -47,6 +76,9 @@ public void NetworkConfigInvalidNetworkPrefabTest()
}

Assert.False(exceptionOccurred);

// In the end we should only have 3 valid registered network prefabs
Assert.True(NetworkManagerHelper.NetworkManagerObject.NetworkConfig.NetworkPrefabOverrideLinks.Count == 3);
}

private const string k_PrefabObjectName = "NetworkPrefabHandlerTestObject";
Expand Down
Loading