From fd41caff0b70606f001a0352dc6253d3515ccb17 Mon Sep 17 00:00:00 2001 From: AeonLucid Date: Fri, 23 Oct 2020 19:18:01 +0200 Subject: [PATCH] Ensure thread safety for joining a game --- .../Net/State/Game.Incoming.cs | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/Impostor.Server/Net/State/Game.Incoming.cs b/src/Impostor.Server/Net/State/Game.Incoming.cs index 0f2b9fc..7fa778d 100644 --- a/src/Impostor.Server/Net/State/Game.Incoming.cs +++ b/src/Impostor.Server/Net/State/Game.Incoming.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System; +using System.Threading; +using System.Threading.Tasks; using Impostor.Api.Games; using Impostor.Api.Innersloth.Data; using Impostor.Api.Net; @@ -10,6 +12,8 @@ namespace Impostor.Server.Net.State { internal partial class Game { + private readonly SemaphoreSlim _clientAddLock = new SemaphoreSlim(1, 1); + public async ValueTask HandleStartGame(IMessageReader message) { GameState = GameStates.Started; @@ -20,6 +24,30 @@ namespace Impostor.Server.Net.State } public async ValueTask AddClientAsync(ClientBase client) + { + var hasLock = false; + + try + { + hasLock = await _clientAddLock.WaitAsync(TimeSpan.FromMinutes(1)); + + if (hasLock) + { + return await AddClientSafeAsync(client); + } + } + finally + { + if (hasLock) + { + _clientAddLock.Release(); + } + } + + return GameJoinResult.FromError(GameJoinError.InvalidClient); + } + + private async ValueTask AddClientSafeAsync(ClientBase client) { // Check if the IP of the player is banned. if (client.Connection != null && _bannedIps.Contains(client.Connection.EndPoint.Address)) -- 2.39.5