protected override void ProcessStatusChanged(NetIncomingMessage msg, NetConnectionStatus status) { base.ProcessStatusChanged(msg, status); if (status == NetConnectionStatus.Connected) { Log("New client connected from {0}", msg.SenderConnection.RemoteEndPoint); // Send currently tracked objects, if not host. if (msg.SenderConnection != LocalClientConnection) { SendAllObjects(msg.SenderConnection); } RemoteClient c = GetClient(msg); UponConnection?.Invoke(c); } if (status == NetConnectionStatus.Disconnected) { string reason = msg.ReadString(); Log("Client has disconnected: {0}", reason); if (msg.SenderConnection == LocalClientConnection) { Log("(Was local client)"); LocalClientConnection = null; } var client = GetClient(msg); if (client != null) { // Remove net object from this client's ownership. int loop = 0; int max = client.OwnedObjectsList.Count; while (client.OwnedObjectsList.Count > 0) { JNet.SetOwner(client.OwnedObjectsList[0], null); loop++; if (loop > max) { JNet.Error($"Infinite loop?! Looped {loop}, expected {max}."); break; } } // Remove client. this.Clients.Remove(client); this.dictClients.Remove(client.ConnectionID); UponDisconnection?.Invoke(client, reason); } else { LogError("Client with Id {0} from {1} did not have a valid RemoteClient to remove.", msg.SenderConnection.RemoteUniqueIdentifier, msg.SenderConnection.RemoteEndPoint); } } }