Prevent clients from creating a second game

Legitimate clients will never create a second game using the same
connection.

Co-Authored-By: js6pak <me@6pak.dev>
This commit is contained in:
miniduikbootandjs6pak committed 2024-12-22 17:02:56 +01:00
1 parent e4f81b4a30
commit 792c9626e4
3 files changed
+29 -1

No files matched your search

+1 -1
View File
@@ -8,7 +8,7 @@ namespace Impostor.Api.Net
/// <summary>
/// Represents a connected game client.
/// </summary>
public interface IClient
public interface IClient : IEquatable<IClient>
{
/// <summary>
/// Gets or sets the unique ID of the client.
+15
View File
@@ -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;
}
}
}
@@ -31,6 +31,7 @@ namespace Impostor.Server.Net.Manager
private readonly IEventManager _eventManager;
private readonly IGameCodeFactory _gameCodeFactory;
private readonly ICompatibilityManager _compatibilityManager;
private readonly ConcurrentDictionary<IClient, Game?> _gamesCreatedBy;
public GameManager(
ILogger<GameManager> logger,
@@ -49,6 +50,7 @@ namespace Impostor.Server.Net.Manager
_games = new ConcurrentDictionary<int, Game>();
_compatibilityConfig = compatibilityConfig.Value;
_compatibilityManager = compatibilityManager;
_gamesCreatedBy = new ConcurrentDictionary<IClient, Game?>();
}
IEnumerable<IGame> IGameManager.Games => _games.Select(kv => kv.Value);
@@ -85,6 +87,12 @@ namespace Impostor.Server.Net.Manager
public async ValueTask<IGame?> 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.