diff --git a/Barotrauma/BarotraumaShared/Source/Characters/CharacterNetworking.cs b/Barotrauma/BarotraumaShared/Source/Characters/CharacterNetworking.cs index 81a5d9e98..794ab3e4e 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/CharacterNetworking.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/CharacterNetworking.cs @@ -79,11 +79,16 @@ namespace Barotrauma private List memState = new List(); private List memLocalState = new List(); - + private bool networkUpdateSent; public bool isSynced = false; - + + public string OwnerClientIP; + public string OwnerClientName; + public bool ClientDisconnected; + public float KillDisconnectedTimer; + public List MemState { get { return memState; } diff --git a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs index 2e948319a..6d65e1ded 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs @@ -368,6 +368,28 @@ namespace Barotrauma.Networking entityEventManager.Update(connectedClients); + foreach (Character character in Character.CharacterList) + { + if (character.IsDead || !character.ClientDisconnected) continue; + + character.KillDisconnectedTimer += deltaTime; + character.SetStun(1.0f); + if (character.KillDisconnectedTimer > KillDisconnectedTime) + { + character.Kill(CauseOfDeath.Disconnected); + continue; + } + + Client owner = connectedClients.Find(c => + c.InGame && !c.NeedsMidRoundSync && + c.Name == character.OwnerClientName && + c.Connection.RemoteEndPoint.Address.ToString() == character.OwnerClientIP); + if (owner != null) + { + SetClientCharacter(owner, character); + } + } + bool isCrewDead = connectedClients.All(c => c.Character == null || c.Character.IsDead || c.Character.IsUnconscious) && (myCharacter == null || myCharacter.IsDead || myCharacter.IsUnconscious); @@ -1313,6 +1335,8 @@ namespace Barotrauma.Networking spawnedCharacter.GiveJobItems(assignedWayPoints[i]); teamClients[i].Character = spawnedCharacter; + spawnedCharacter.OwnerClientIP = teamClients[i].Connection.RemoteEndPoint.Address.ToString(); + spawnedCharacter.OwnerClientName = teamClients[i].Name; #if CLIENT GameMain.GameSession.CrewManager.AddCharacter(spawnedCharacter); @@ -1610,8 +1634,8 @@ namespace Barotrauma.Networking if (gameStarted && client.Character != null) { + client.Character.ClientDisconnected = true; client.Character.ClearInputs(); - client.Character.Kill(CauseOfDeath.Disconnected, true); } client.Character = null; @@ -2006,6 +2030,8 @@ namespace Barotrauma.Networking if (client.Character != null) { client.Character.IsRemotePlayer = false; + client.Character.OwnerClientIP = null; + client.Character.OwnerClientName = null; } if (newCharacter == null) @@ -2015,16 +2041,19 @@ namespace Barotrauma.Networking CreateEntityEvent(client.Character, new object[] { NetEntityEvent.Type.Control, null }); client.Character = null; } - } else //taking control of a new character { + newCharacter.ClientDisconnected = false; + newCharacter.KillDisconnectedTimer = 0.0f; newCharacter.ResetNetState(); if (client.Character != null) { newCharacter.LastNetworkUpdateID = client.Character.LastNetworkUpdateID; } + newCharacter.OwnerClientIP = client.Connection.RemoteEndPoint.Address.ToString(); + newCharacter.OwnerClientName = client.Name; newCharacter.IsRemotePlayer = true; newCharacter.Enabled = true; client.Character = newCharacter; diff --git a/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs b/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs index 63af136a5..fdc1d8a48 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/GameServerSettings.cs @@ -219,6 +219,13 @@ namespace Barotrauma.Networking private set; } + [Serialize(30.0f, true)] + public bool KillDisconnectedTime + { + get; + private set; + } + [Serialize(true, true)] public bool TraitorUseRatio {