feature: NetworkConnection.owned objects are now available on server AND on client

This commit is contained in:
vis2k 2022-10-13 11:20:16 +02:00
parent 6bb42e9e81
commit e647df8fa3
5 changed files with 47 additions and 10 deletions

View File

@ -1036,6 +1036,7 @@ internal static void ApplySpawnPayload(NetworkIdentity identity, SpawnMessage me
}
spawned[message.netId] = identity;
if (identity.isOwned) connection?.owned.Add(identity);
// the initial spawn with OnObjectSpawnStarted/Finished calls all
// object's OnStartClient/OnStartLocalPlayer after they were all
@ -1233,6 +1234,11 @@ static void ClearNullFromSpawned()
static void OnHostClientObjectDestroy(ObjectDestroyMessage message)
{
//Debug.Log($"NetworkClient.OnLocalObjectObjDestroy netId:{message.netId}");
// remove from owned (if any)
if (spawned.TryGetValue(message.netId, out NetworkIdentity identity))
connection.owned.Remove(identity);
spawned.Remove(message.netId);
}
@ -1254,6 +1260,7 @@ internal static void OnHostClientSpawn(SpawnMessage message)
if (NetworkServer.spawned.TryGetValue(message.netId, out NetworkIdentity localObject) && localObject != null)
{
spawned[message.netId] = localObject;
if (message.isOwner) connection.owned.Add(localObject);
// now do the actual 'spawning' on host mode
if (message.isLocalPlayer)
@ -1394,6 +1401,7 @@ static void DestroyObject(uint netId)
}
// remove from dictionary no matter how it is unspawned
connection.owned.Remove(localObject); // if any
spawned.Remove(netId);
}
//else Debug.LogWarning($"Did not find target for destroy message for {netId}");
@ -1497,6 +1505,7 @@ public static void DestroyAllClientObjects()
}
}
spawned.Clear();
connection?.owned.Clear();
}
catch (InvalidOperationException e)
{
@ -1521,6 +1530,7 @@ public static void Shutdown()
DestroyAllClientObjects();
spawned.Clear();
connection?.owned.Clear();
handlers.Clear();
spawnableObjects.Clear();

View File

@ -41,14 +41,17 @@ public abstract class NetworkConnection
/// <summary>This connection's main object (usually the player object).</summary>
public NetworkIdentity identity { get; internal set; }
// DEPRECATED 2022-02-05
[Obsolete("Cast to NetworkConnectionToClient to access .owned")]
public HashSet<NetworkIdentity> clientOwnedObjects => owned;
/// <summary>All NetworkIdentities owned by this connection. Can be main player, pets, etc.</summary>
// .owned is now valid both on server and on client.
// IMPORTANT: this needs to be <NetworkIdentity>, not <uint netId>.
// fixes a bug where DestroyOwnedObjects wouldn't find the
// netId anymore: https://github.com/vis2k/Mirror/issues/1380
// Works fine with NetworkIdentity pointers though.
// DEPRECATED 2022-02-05
[Obsolete("Cast to NetworkConnectionToClient to access .owned")]
public HashSet<NetworkIdentity> clientOwnedObjects => ((NetworkConnectionToClient)this).owned;
public readonly HashSet<NetworkIdentity> owned = new HashSet<NetworkIdentity>();
// batching from server to client & client to server.
// fewer transport calls give us significantly better performance/scale.

View File

@ -13,13 +13,6 @@ public class NetworkConnectionToClient : NetworkConnection
// TODO move to server's NetworkConnectionToClient?
public new readonly HashSet<NetworkIdentity> observing = new HashSet<NetworkIdentity>();
/// <summary>All NetworkIdentities owned by this connection. Can be main player, pets, etc.</summary>
// IMPORTANT: this needs to be <NetworkIdentity>, not <uint netId>.
// fixes a bug where DestroyOwnedObjects wouldn't find the
// netId anymore: https://github.com/vis2k/Mirror/issues/1380
// Works fine with NetworkIdentity pointers though.
public readonly HashSet<NetworkIdentity> owned = new HashSet<NetworkIdentity>();
[Obsolete(".clientOwnedObjects was renamed to .owned :)")] // 2022-10-13
public new HashSet<NetworkIdentity> clientOwnedObjects => owned;

View File

@ -1364,6 +1364,7 @@ static void DestroyObject(NetworkIdentity identity, DestroyMode mode)
identity.NotifyAuthority();
// remove from NetworkClient dictionary
NetworkClient.connection.owned.Remove(identity);
NetworkClient.spawned.Remove(identity.netId);
}

View File

@ -97,6 +97,36 @@ public void DisconnectCallsOnClientDisconnected_HostMode()
Assert.That(called, Is.True);
}
[Test]
public void OwnedObjects()
{
// create a scene object and set inactive before spawning
// CreateNetworked(out GameObject go, out NetworkIdentity identity);
// listen & connect
NetworkServer.Listen(1);
ConnectHostClientBlockingAuthenticatedAndReady();
// spawn main player. should be added to .owned.
CreateNetworkedAndSpawnPlayer(out _, out NetworkIdentity player, NetworkServer.localConnection);
Assert.That(NetworkClient.connection.owned.Count, Is.EqualTo(1));
Assert.That(NetworkClient.connection.owned.Contains(NetworkClient.localPlayer));
// spawn an object which is not owned. shouldn't add anything.
CreateNetworkedAndSpawn(out _, out NetworkIdentity other);
Assert.That(NetworkClient.connection.owned.Count, Is.EqualTo(1));
// spawn an owned object. should add to client's .owned.
CreateNetworkedAndSpawn(out _, out NetworkIdentity pet, NetworkServer.localConnection);
Assert.That(NetworkClient.connection.owned.Count, Is.EqualTo(2));
// despawn should remove from .owned
NetworkServer.Destroy(pet.gameObject);
ProcessMessages();
Assert.That(NetworkClient.connection.owned.Count, Is.EqualTo(1));
Assert.That(NetworkClient.connection.owned.Contains(NetworkClient.localPlayer));
}
[Test]
public void ShutdownCleanup()
{