From: miniduikboot Date: Thu, 20 Jun 2024 20:26:16 +0000 (+0200) Subject: Clean up owned playerinfo's when disconnecting X-Git-Tag: v1.10.0~7^2~3 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=219b72a3d1eccac57a66084463d0df7577a9fdc2;p=rhonda%2Fimpostor.git Clean up owned playerinfo's when disconnecting This commit does what official servers do: - despawn the PlayerInfo if someone disconnects while in the lobby - despawn all PlayerInfos at the end of a game when the EndGame screen is shown. At this point a lot of other netobjects are destroyed as well, with the PlayerInfos generally done first. --- diff --git a/src/Impostor.Server/Net/State/Game.Data.cs b/src/Impostor.Server/Net/State/Game.Data.cs index 1ae179c..9d0fb55 100644 --- a/src/Impostor.Server/Net/State/Game.Data.cs +++ b/src/Impostor.Server/Net/State/Game.Data.cs @@ -511,6 +511,18 @@ namespace Impostor.Server.Net.State await SendObjectSpawnAsync(playerInfo); } + private async ValueTask DespawnPlayerInfoAsync(InnerPlayerInfo playerInfo) + { + if (playerInfo.OwnerId == ServerOwned) + { + _logger.LogDebug("Despawning PlayerInfo {nid}", playerInfo.NetId); + GameNet.GameData.RemovePlayer(playerInfo.PlayerId); + RemoveNetObject(playerInfo); + + await SendObjectDespawnAsync(playerInfo); + } + } + private bool AddNetObject(InnerNetObject obj) { if (_allObjectsFast.ContainsKey(obj.NetId)) diff --git a/src/Impostor.Server/Net/State/Game.Incoming.cs b/src/Impostor.Server/Net/State/Game.Incoming.cs index 3d637e4..a8efd3b 100644 --- a/src/Impostor.Server/Net/State/Game.Incoming.cs +++ b/src/Impostor.Server/Net/State/Game.Incoming.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Impostor.Api.Games; @@ -43,6 +44,12 @@ namespace Impostor.Server.Net.State player.Value.Limbo = LimboStates.PreSpawn; } + // Delete all PlayerInfo objects + foreach (var playerInfo in GameNet.GameData.Players.Values.ToArray()) + { + await DespawnPlayerInfoAsync(playerInfo); + } + await _eventManager.CallAsync(new GameEndedEvent(this, gameOverReason)); } diff --git a/src/Impostor.Server/Net/State/Game.Outgoing.cs b/src/Impostor.Server/Net/State/Game.Outgoing.cs index 1ab0086..f30271f 100644 --- a/src/Impostor.Server/Net/State/Game.Outgoing.cs +++ b/src/Impostor.Server/Net/State/Game.Outgoing.cs @@ -134,5 +134,14 @@ namespace Impostor.Server.Net.State writer.EndMessage(); await FinishGameDataAsync(writer, targetClientId); } + + private async ValueTask SendObjectDespawnAsync(InnerNetObject obj, int? targetClientId = null) + { + using var writer = StartGameData(targetClientId); + writer.StartMessage(GameDataTag.DespawnFlag); + writer.WritePacked(obj.NetId); + writer.EndMessage(); + await FinishGameDataAsync(writer, targetClientId); + } } } diff --git a/src/Impostor.Server/Net/State/Game.State.cs b/src/Impostor.Server/Net/State/Game.State.cs index e570c98..fcd2c87 100644 --- a/src/Impostor.Server/Net/State/Game.State.cs +++ b/src/Impostor.Server/Net/State/Game.State.cs @@ -85,6 +85,13 @@ namespace Impostor.Server.Net.State } }); + // Clean up the PlayerInfo if we own it and we're still in the lobby + if (GameState == GameStates.NotStarted) + { + var playerInfo = GameNet.GameData.PlayersByClientId[playerId]; + await DespawnPlayerInfoAsync(playerInfo); + } + return true; }