From: AeonLucid Date: Fri, 23 Oct 2020 17:18:01 +0000 (+0200) Subject: Ensure thread safety for joining a game X-Git-Tag: v1.2.2~96^2~41 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=fd41caff0b70606f001a0352dc6253d3515ccb17;p=rhonda%2Fimpostor.git Ensure thread safety for joining a game --- 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))