From 5a611baefc363f1afaec03dc04f17b3c2aadf4f5 Mon Sep 17 00:00:00 2001 From: James Frowen Date: Sat, 23 Mar 2024 17:38:38 +0000 Subject: [PATCH] feat: adding public OwnedObjects list and RemoveAllOwnedObject helper method to NetworkPlayer --- Assets/Mirage/Runtime/INetworkPlayer.cs | 20 ++++++++++++- Assets/Mirage/Runtime/NetworkPlayer.cs | 39 +++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/Assets/Mirage/Runtime/INetworkPlayer.cs b/Assets/Mirage/Runtime/INetworkPlayer.cs index bf2ae6bdbf..f0a309081a 100644 --- a/Assets/Mirage/Runtime/INetworkPlayer.cs +++ b/Assets/Mirage/Runtime/INetworkPlayer.cs @@ -89,10 +89,28 @@ public interface IVisibilityTracker public interface IObjectOwner { event Action OnIdentityChanged; + /// + /// The main object owned by this player, normally the player's character + /// NetworkIdentity Identity { get; set; } bool HasCharacter { get; } - void RemoveOwnedObject(NetworkIdentity networkIdentity); + + /// + /// All the objects owned by the player + /// + IReadOnlyCollection OwnedObjects { get; } void AddOwnedObject(NetworkIdentity networkIdentity); + void RemoveOwnedObject(NetworkIdentity networkIdentity); + /// + /// Removes all owned objects. This is useful to call when player disconnects to avoid objects being destroyed + /// + /// Should message be send to owner client? If player is disconnecting you should set this false + void RemoveAllOwnedObject(bool sendAuthorityChangeEvent); + /// + /// Destroys or unspawns all owned objects. + /// This is called when the player is disconnects. + /// It will be called after , so Disconnected can be used to remove any owned objects from the list before they are destroyed. + /// void DestroyOwnedObjects(); } diff --git a/Assets/Mirage/Runtime/NetworkPlayer.cs b/Assets/Mirage/Runtime/NetworkPlayer.cs index 773714feee..b8053d0a41 100644 --- a/Assets/Mirage/Runtime/NetworkPlayer.cs +++ b/Assets/Mirage/Runtime/NetworkPlayer.cs @@ -96,6 +96,7 @@ public void SetAuthentication(PlayerAuthentication authentication, bool allowRep /// public IReadOnlyCollection VisList => _visList; + public IReadOnlyCollection OwnedObjects => _ownedObjects; /// /// Disconnects the player. @@ -289,6 +290,44 @@ public void RemoveOwnedObject(NetworkIdentity identity) } } + public void RemoveAllOwnedObject(bool sendAuthorityChangeEvent) + { + if (logger.LogEnabled()) logger.Log($"Removing all Player[{Address}] OwnedObjects"); + + // create a copy because the list might be modified when destroying + var ownedObjects = new HashSet(_ownedObjects); + var mainIdentity = Identity; + + foreach (var netIdentity in ownedObjects) + { + // remove main object last + if (netIdentity == mainIdentity) + continue; + + if (netIdentity == null) + continue; + + // code from Identity.RemoveClientAuthority, but without the safety checks, we dont need them here + netIdentity.SetOwner(null); + + if (sendAuthorityChangeEvent && netIdentity.ServerObjectManager != null) + Send(new RemoveAuthorityMessage { NetId = netIdentity.NetId }); + } + + if (mainIdentity != null) + { + // code from ServerObjectManager.RemoveCharacter, but without the safety checks, we dont need them here + mainIdentity.SetOwner(null); + + if (sendAuthorityChangeEvent && mainIdentity.ServerObjectManager != null) + Send(new RemoveCharacterMessage { KeepAuthority = false }); + + } + + // clear the hashset because we destroyed them all + _ownedObjects.Clear(); + } + /// /// Destroy all objects owned by this player /// NOTE: only destroyed objects that are currently spawned