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.
This commit is contained in:
miniduikboot committed 2024-08-17 22:52:09 +02:00
1 parent ad18eda32f
commit aec3357e7b
4 files changed
+35

No files matched your search

@@ -510,6 +510,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))
@@ -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.ToList())
{
await DespawnPlayerInfoAsync(playerInfo);
}
await _eventManager.CallAsync(new GameEndedEvent(this, gameOverReason));
}
@@ -134,5 +134,14 @@ namespace Impostor.Server.Net.State
writer.EndMessage();
await FinishGameDataAsync(writer, targetClientId);
}
private ValueTask SendObjectDespawnAsync(InnerNetObject obj, int? targetClientId = null)
{
using var writer = StartGameData(targetClientId);
writer.StartMessage(GameDataTag.DespawnFlag);
writer.WritePacked(obj.NetId);
writer.EndMessage();
return FinishGameDataAsync(writer, targetClientId);
}
}
}
@@ -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;
}