From: miniduikboot Date: Tue, 17 Dec 2024 21:05:27 +0000 (+0100) Subject: Prevent clients from creating a second game X-Git-Tag: v1.10.2~3 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=792c9626e4169665fecf17a2edaaea1bfeb52a0c;p=rhonda%2Fimpostor.git Prevent clients from creating a second game Legitimate clients will never create a second game using the same connection. Co-Authored-By: js6pak --- diff --git a/src/Impostor.Api/Net/IClient.cs b/src/Impostor.Api/Net/IClient.cs index e4f8100..0732c0c 100644 --- a/src/Impostor.Api/Net/IClient.cs +++ b/src/Impostor.Api/Net/IClient.cs @@ -8,7 +8,7 @@ namespace Impostor.Api.Net /// /// Represents a connected game client. /// - public interface IClient + public interface IClient : IEquatable { /// /// Gets or sets the unique ID of the client. diff --git a/src/Impostor.Server/Net/ClientBase.cs b/src/Impostor.Server/Net/ClientBase.cs index b52d512..a8945fa 100644 --- a/src/Impostor.Server/Net/ClientBase.cs +++ b/src/Impostor.Server/Net/ClientBase.cs @@ -59,5 +59,20 @@ namespace Impostor.Server.Net { await Connection.CustomDisconnectAsync(reason, message); } + + public bool Equals(IClient? other) + { + return other != null && Id == other.Id; + } + + public override bool Equals(object? obj) + { + return Equals(obj as ClientBase); + } + + public override int GetHashCode() + { + return Id; + } } } diff --git a/src/Impostor.Server/Net/Manager/GameManager.cs b/src/Impostor.Server/Net/Manager/GameManager.cs index 4e98521..7de311a 100644 --- a/src/Impostor.Server/Net/Manager/GameManager.cs +++ b/src/Impostor.Server/Net/Manager/GameManager.cs @@ -31,6 +31,7 @@ namespace Impostor.Server.Net.Manager private readonly IEventManager _eventManager; private readonly IGameCodeFactory _gameCodeFactory; private readonly ICompatibilityManager _compatibilityManager; + private readonly ConcurrentDictionary _gamesCreatedBy; public GameManager( ILogger logger, @@ -49,6 +50,7 @@ namespace Impostor.Server.Net.Manager _games = new ConcurrentDictionary(); _compatibilityConfig = compatibilityConfig.Value; _compatibilityManager = compatibilityManager; + _gamesCreatedBy = new ConcurrentDictionary(); } IEnumerable IGameManager.Games => _games.Select(kv => kv.Value); @@ -85,6 +87,12 @@ namespace Impostor.Server.Net.Manager public async ValueTask CreateAsync(IClient? owner, IGameOptions options, GameFilterOptions filterOptions) { + if (owner != null && !_gamesCreatedBy.TryAdd(owner, null)) + { + _logger.LogWarning("Connection {Name}({ClientId}) has tried to create a second game, blocked", owner.Name, owner.Id); + return null; + } + var @event = new GameCreationEvent(this, owner); await _eventManager.CallAsync(@event); @@ -100,6 +108,11 @@ namespace Impostor.Server.Net.Manager (success, game) = await TryCreateAsync(options, filterOptions, owner); } + if (owner != null) + { + _gamesCreatedBy[owner] = game; + } + if (!success || game == null) { throw new ImpostorException("Could not create new game"); // TODO: Fix generic exception.