From e9ea621b93fbb58d9edfca8375918791637bbd52 Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 30 Dec 2020 20:59:04 +0800 Subject: +init --- .../Games/Extensions/GameExtensions.cs | 42 +++++++++++ .../Games/Extensions/GameManagerExtensions.cs | 14 ++++ Impostor-dev/src/Impostor.Api/Games/GameCode.cs | 74 ++++++++++++++++++ .../src/Impostor.Api/Games/GameJoinError.cs | 48 ++++++++++++ .../src/Impostor.Api/Games/GameJoinResult.cs | 48 ++++++++++++ Impostor-dev/src/Impostor.Api/Games/IGame.cs | 88 ++++++++++++++++++++++ .../src/Impostor.Api/Games/IGameCodeFactory.cs | 7 ++ .../Impostor.Api/Games/Managers/IGameManager.cs | 11 +++ 8 files changed, 332 insertions(+) create mode 100644 Impostor-dev/src/Impostor.Api/Games/Extensions/GameExtensions.cs create mode 100644 Impostor-dev/src/Impostor.Api/Games/Extensions/GameManagerExtensions.cs create mode 100644 Impostor-dev/src/Impostor.Api/Games/GameCode.cs create mode 100644 Impostor-dev/src/Impostor.Api/Games/GameJoinError.cs create mode 100644 Impostor-dev/src/Impostor.Api/Games/GameJoinResult.cs create mode 100644 Impostor-dev/src/Impostor.Api/Games/IGame.cs create mode 100644 Impostor-dev/src/Impostor.Api/Games/IGameCodeFactory.cs create mode 100644 Impostor-dev/src/Impostor.Api/Games/Managers/IGameManager.cs (limited to 'Impostor-dev/src/Impostor.Api/Games') diff --git a/Impostor-dev/src/Impostor.Api/Games/Extensions/GameExtensions.cs b/Impostor-dev/src/Impostor.Api/Games/Extensions/GameExtensions.cs new file mode 100644 index 0000000..a736978 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Games/Extensions/GameExtensions.cs @@ -0,0 +1,42 @@ +using System; +using System.Threading.Tasks; +using Impostor.Api.Net; +using Impostor.Api.Net.Messages; + +namespace Impostor.Api.Games +{ + public static class GameExtensions + { + public static ValueTask SendToAllExceptAsync(this IGame game, IMessageWriter writer, LimboStates states, int? id) + { + return id.HasValue + ? game.SendToAllExceptAsync(writer, id.Value, states) + : game.SendToAllAsync(writer, states); + } + + public static ValueTask SendToAllExceptAsync(this IGame game, IMessageWriter writer, LimboStates states, IClient client) + { + if (client == null) + { + throw new ArgumentNullException(nameof(client)); + } + + return game.SendToAllExceptAsync(writer, client.Id, states); + } + + public static ValueTask SendToAsync(this IGame game, IMessageWriter writer, IClient client) + { + if (client == null) + { + throw new ArgumentNullException(nameof(client)); + } + + return game.SendToAsync(writer, client.Id); + } + + public static ValueTask SendToAsync(this IGame game, IMessageWriter writer, IClientPlayer player) + { + return game.SendToAsync(writer, player.Client); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Games/Extensions/GameManagerExtensions.cs b/Impostor-dev/src/Impostor.Api/Games/Extensions/GameManagerExtensions.cs new file mode 100644 index 0000000..9a5a2b4 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Games/Extensions/GameManagerExtensions.cs @@ -0,0 +1,14 @@ +using System.Linq; +using Impostor.Api.Games.Managers; +using Impostor.Api.Innersloth; + +namespace Impostor.Api.Games +{ + public static class GameManagerExtensions + { + public static int GetGameCount(this IGameManager manager, MapFlags map) + { + return manager.Games.Count(game => map.HasFlag((MapFlags)(1 << game.Options.MapId))); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Games/GameCode.cs b/Impostor-dev/src/Impostor.Api/Games/GameCode.cs new file mode 100644 index 0000000..2c30e7e --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Games/GameCode.cs @@ -0,0 +1,74 @@ +using System; +using Impostor.Api.Innersloth; + +namespace Impostor.Api.Games +{ + public readonly struct GameCode : IEquatable + { + public GameCode(int value) + { + Value = value; + Code = GameCodeParser.IntToGameName(value); + } + + public GameCode(string code) + { + Value = GameCodeParser.GameNameToInt(code); + Code = code; + } + + public string Code { get; } + + public int Value { get; } + + public static implicit operator string(GameCode code) => code.Code; + + public static implicit operator int(GameCode code) => code.Value; + + public static implicit operator GameCode(string code) => From(code); + + public static implicit operator GameCode(int value) => From(value); + + public static bool operator ==(GameCode left, GameCode right) + { + return left.Equals(right); + } + + public static bool operator !=(GameCode left, GameCode right) + { + return !left.Equals(right); + } + + public static GameCode Create() + { + return new GameCode(GameCodeParser.GenerateCode(6)); + } + + public static GameCode From(int value) => new GameCode(value); + + public static GameCode From(string value) => new GameCode(value); + + /// + public bool Equals(GameCode other) + { + return Code == other.Code && Value == other.Value; + } + + /// + public override bool Equals(object? obj) + { + return obj is GameCode other && Equals(other); + } + + /// + public override int GetHashCode() + { + return HashCode.Combine(Code, Value); + } + + public override string ToString() + { + return Code; + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Games/GameJoinError.cs b/Impostor-dev/src/Impostor.Api/Games/GameJoinError.cs new file mode 100644 index 0000000..4889ea9 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Games/GameJoinError.cs @@ -0,0 +1,48 @@ +namespace Impostor.Api.Games +{ + public enum GameJoinError + { + /// + /// No error occured while joining the game. + /// + None, + + /// + /// The client is not registered in the client manager. + /// + InvalidClient, + + /// + /// The client has been banned from the game. + /// + Banned, + + /// + /// The game is full. + /// + GameFull, + + /// + /// The limbo state of the player is incorrect. + /// + InvalidLimbo, + + /// + /// The game is already started. + /// + GameStarted, + + /// + /// The game has been destroyed. + /// + GameDestroyed, + + /// + /// Custom error by a plugin. + /// + /// + /// A custom message can be set in . + /// + Custom, + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Games/GameJoinResult.cs b/Impostor-dev/src/Impostor.Api/Games/GameJoinResult.cs new file mode 100644 index 0000000..b33a2b6 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Games/GameJoinResult.cs @@ -0,0 +1,48 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using Impostor.Api.Net; + +namespace Impostor.Api.Games +{ + public readonly struct GameJoinResult + { + private GameJoinResult(GameJoinError error, string? message = null, IClientPlayer? player = null) + { + Error = error; + Message = message; + Player = player; + } + + public GameJoinError Error { get; } + + public bool IsSuccess => Error == GameJoinError.None; + + public bool IsCustomError => Error == GameJoinError.Custom; + + [MemberNotNullWhen(true, nameof(IsCustomError))] + public string? Message { get; } + + [MemberNotNullWhen(true, nameof(IsSuccess))] + public IClientPlayer? Player { get; } + + public static GameJoinResult CreateCustomError(string message) + { + return new GameJoinResult(GameJoinError.Custom, message); + } + + public static GameJoinResult CreateSuccess(IClientPlayer player) + { + return new GameJoinResult(GameJoinError.None, player: player); + } + + public static GameJoinResult FromError(GameJoinError error) + { + if (error == GameJoinError.Custom) + { + throw new InvalidOperationException($"Custom errors should provide a message, use {nameof(CreateCustomError)} instead."); + } + + return new GameJoinResult(error); + } + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Games/IGame.cs b/Impostor-dev/src/Impostor.Api/Games/IGame.cs new file mode 100644 index 0000000..ad71986 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Games/IGame.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using System.Net; +using System.Threading.Tasks; +using Impostor.Api.Innersloth; +using Impostor.Api.Net; +using Impostor.Api.Net.Inner; +using Impostor.Api.Net.Inner.Objects; +using Impostor.Api.Net.Messages; + +namespace Impostor.Api.Games +{ + public interface IGame + { + GameOptionsData Options { get; } + + GameCode Code { get; } + + GameStates GameState { get; } + + IGameNet GameNet { get; } + + IEnumerable Players { get; } + + IPEndPoint PublicIp { get; } + + int PlayerCount { get; } + + IClientPlayer Host { get; } + + bool IsPublic { get; } + + IDictionary Items { get; } + + int HostId { get; } + + IClientPlayer GetClientPlayer(int clientId); + + /// + /// Adds an to the ban list of this game. + /// Prevents all future joins from this . + /// + /// This does not kick the player with that from the lobby. + /// + /// + /// The to ban. + /// + void BanIp(IPAddress ipAddress); + + /// + /// Syncs the internal to all players. + /// Necessary to do if you modified it, otherwise it won't be used. + /// + /// A representing the asynchronous operation. + ValueTask SyncSettingsAsync(); + + /// + /// Sets the specified list as Impostor on all connected players. + /// + /// List of players to be Impostor. + /// A representing the asynchronous operation. + ValueTask SetInfectedAsync(IEnumerable players); + + /// + /// Send the message to all players. + /// + /// Message to send. + /// Required limbo state of the player. + /// A representing the asynchronous operation. + ValueTask SendToAllAsync(IMessageWriter writer, LimboStates states = LimboStates.NotLimbo); + + /// + /// Send the message to all players except one. + /// + /// Message to send. + /// The player to exclude from sending the message. + /// Required limbo state of the player. + /// A representing the asynchronous operation. + ValueTask SendToAllExceptAsync(IMessageWriter writer, int senderId, LimboStates states = LimboStates.NotLimbo); + + /// + /// Send a message to a specific player. + /// + /// Message to send. + /// ID of the client. + /// A representing the asynchronous operation. + ValueTask SendToAsync(IMessageWriter writer, int id); + } +} diff --git a/Impostor-dev/src/Impostor.Api/Games/IGameCodeFactory.cs b/Impostor-dev/src/Impostor.Api/Games/IGameCodeFactory.cs new file mode 100644 index 0000000..f264fe0 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Games/IGameCodeFactory.cs @@ -0,0 +1,7 @@ +namespace Impostor.Api.Games +{ + public interface IGameCodeFactory + { + GameCode Create(); + } +} \ No newline at end of file diff --git a/Impostor-dev/src/Impostor.Api/Games/Managers/IGameManager.cs b/Impostor-dev/src/Impostor.Api/Games/Managers/IGameManager.cs new file mode 100644 index 0000000..10a05f0 --- /dev/null +++ b/Impostor-dev/src/Impostor.Api/Games/Managers/IGameManager.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace Impostor.Api.Games.Managers +{ + public interface IGameManager + { + IEnumerable Games { get; } + + IGame? Find(GameCode code); + } +} \ No newline at end of file -- cgit v1.1-26-g67d0