Destroy objects owned by this connection when disconnecting (#1179)

* Destroy objects owned by this connection when disconnecting

* How did this get here?

* Simplify keeping track of owned objects
This commit is contained in:
Paul Pacheco 2019-10-27 08:55:12 -05:00 committed by vis2k
parent 4d9e5809ee
commit 8931944005
4 changed files with 34 additions and 61 deletions

View File

@ -204,7 +204,6 @@ public static void Disconnect()
if (connection != null)
{
connection.Disconnect();
connection.Dispose();
connection = null;
RemoveTransportHandlers();
}

View File

@ -16,7 +16,7 @@ namespace Mirror
/// <para>NetworkConnection objects can "own" networked game objects. Owned objects will be destroyed on the server by default when the connection is destroyed. A connection owns the player objects created by its client, and other objects with client-authority assigned to the corresponding client.</para>
/// <para>There are many virtual functions on NetworkConnection that allow its behaviour to be customized. NetworkClient and NetworkServer can both be made to instantiate custom classes derived from NetworkConnection by setting their networkConnectionClass member variable.</para>
/// </remarks>
public abstract class NetworkConnection : IDisposable
public abstract class NetworkConnection
{
public readonly HashSet<NetworkIdentity> visList = new HashSet<NetworkIdentity>();
@ -83,13 +83,6 @@ internal set
/// </summary>
public NetworkIdentity identity { get; internal set; }
/// <summary>
/// A list of the NetworkIdentity objects owned by this connection. This list is read-only.
/// <para>This includes the player object for the connection - if it has localPlayerAutority set, and any objects spawned with local authority or set with AssignLocalAuthority.</para>
/// <para>This list can be used to validate messages from clients, to ensure that clients are only trying to control objects that they own.</para>
/// </summary>
public readonly HashSet<uint> clientOwnedObjects = new HashSet<uint>();
/// <summary>
/// Setting this to true will log the contents of network message to the console.
/// </summary>
@ -130,35 +123,6 @@ internal NetworkConnection(int networkConnectionId)
#pragma warning restore 618
}
~NetworkConnection()
{
Dispose(false);
}
/// <summary>
/// Disposes of this connection, releasing channel buffers that it holds.
/// </summary>
public void Dispose()
{
Dispose(true);
// Take yourself off the Finalization queue
// to prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
foreach (uint netId in clientOwnedObjects)
{
if (NetworkIdentity.spawned.TryGetValue(netId, out NetworkIdentity identity))
{
identity.clientAuthorityOwner = null;
}
}
clientOwnedObjects.Clear();
}
/// <summary>
/// Disconnects this connection.
/// </summary>
@ -371,15 +335,5 @@ internal void TransportReceive(ArraySegment<byte> buffer, int channelId)
Disconnect();
}
}
internal void AddOwnedObject(NetworkIdentity obj)
{
clientOwnedObjects.Add(obj.netId);
}
internal void RemoveOwnedObject(NetworkIdentity obj)
{
clientOwnedObjects.Remove(obj.netId);
}
}
}

View File

@ -7,6 +7,13 @@ namespace Mirror
{
public class NetworkConnectionToClient : NetworkConnection
{
/// <summary>
/// A list of the NetworkIdentity objects owned by this connection. This list is read-only.
/// <para>This includes the player object for the connection - if it has localPlayerAutority set, and any objects spawned with local authority or set with AssignLocalAuthority.</para>
/// <para>This list can be used to validate messages from clients, to ensure that clients are only trying to control objects that they own.</para>
/// </summary>
public readonly HashSet<NetworkIdentity> clientOwnedObjects = new HashSet<NetworkIdentity>();
public NetworkConnectionToClient(int networkConnectionId) : base(networkConnectionId)
{
}
@ -56,6 +63,31 @@ public override void Disconnect()
isReady = false;
Transport.activeTransport.ServerDisconnect(connectionId);
RemoveObservers();
DestroyOwnedObjects();
}
internal void AddOwnedObject(NetworkIdentity obj)
{
clientOwnedObjects.Add(obj);
}
internal void RemoveOwnedObject(NetworkIdentity obj)
{
clientOwnedObjects.Remove(obj);
}
protected void DestroyOwnedObjects()
{
// work on copy because the list may be modified when we destroy the objects
HashSet<NetworkIdentity> objects = new HashSet<NetworkIdentity>(clientOwnedObjects);
foreach (NetworkIdentity netId in objects)
{
if (netId != null)
{
NetworkServer.Destroy(netId.gameObject);
}
}
clientOwnedObjects.Clear();
}
}
}
}

View File

@ -190,7 +190,6 @@ internal static void RemoveLocalConnection()
if (localConnection != null)
{
localConnection.Disconnect();
localConnection.Dispose();
localConnection = null;
}
localClientActive = false;
@ -445,7 +444,6 @@ public static void DisconnectAllConnections()
// call OnDisconnected unless local player in host mode
if (conn.connectionId != 0)
OnDisconnected(conn);
conn.Dispose();
}
connections.Clear();
}
@ -1178,16 +1176,6 @@ internal static void SendSpawnMessage(NetworkIdentity identity, NetworkConnectio
/// <param name="conn">The connections object to clean up for.</param>
public static void DestroyPlayerForConnection(NetworkConnection conn)
{
// => destroy what we can destroy.
HashSet<uint> tmp = new HashSet<uint>(conn.clientOwnedObjects);
foreach (uint netId in tmp)
{
if (NetworkIdentity.spawned.TryGetValue(netId, out NetworkIdentity identity))
{
Destroy(identity.gameObject);
}
}
if (conn.identity != null)
{
DestroyObject(conn.identity, true);