]> git.deb.at Git - rhonda/impostor.git/commitdiff
Clean up owned playerinfo's when disconnecting
authorminiduikboot <mini@duikbo.at>
Thu, 20 Jun 2024 20:26:16 +0000 (22:26 +0200)
committerminiduikboot <mini@duikbo.at>
Tue, 20 Aug 2024 19:41:38 +0000 (21:41 +0200)
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.

src/Impostor.Server/Net/State/Game.Data.cs
src/Impostor.Server/Net/State/Game.Incoming.cs
src/Impostor.Server/Net/State/Game.Outgoing.cs
src/Impostor.Server/Net/State/Game.State.cs

index 1ae179ca105ed8914b881128af39bbf7a3ca46a2..9d0fb550d88cb4224697ffc79391c93fb9f232ff 100644 (file)
@@ -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))
index 3d637e4de337cea8d94f8eb07d6df48a055277a6..a8efd3b4bcdfdf0a418acd8b9897726d2402eb1b 100644 (file)
@@ -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));
         }
 
index 1ab0086e6c80bb33340060db3449eaaccc1c7553..f30271f8816267b24caa8841a96ac333cbb5d58c 100644 (file)
@@ -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);
+        }
     }
 }
index e570c98fc6b96d193ecfb9f9734f75c448d90af4..fcd2c879f47fd1f060003861199d433f2ce378d4 100644 (file)
@@ -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;
         }