From 7e85419b82b14e7a437674d44846d85a285d9d09 Mon Sep 17 00:00:00 2001 From: miniduikboot Date: Wed, 26 Mar 2025 00:50:24 +0100 Subject: [PATCH] Add endpoint to find games by code This is used in the new "Enter Code" flow 3 extra fields are added to GameListing, including a Base 64 serialization method for game options --- src/Impostor.Server/Http/GamesController.cs | 104 ++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/src/Impostor.Server/Http/GamesController.cs b/src/Impostor.Server/Http/GamesController.cs index e64a498..58c3abb 100644 --- a/src/Impostor.Server/Http/GamesController.cs +++ b/src/Impostor.Server/Http/GamesController.cs @@ -97,6 +97,21 @@ public sealed class GamesController : ControllerBase return Ok(_hostServer); } + [HttpGet("{gameId}")] + public IActionResult Show([FromRoute] int gameId) + { + var code = new GameCode(gameId); + var game = _gameManager.Find(code); + + // If the game was not found, print an error message. + if (game == null) + { + return NotFound(new FindGameByCodeResponse(new MatchmakerError(DisconnectReason.GameNotFound))); + } + + return Ok(new FindGameByCodeResponse(GameListingV2.From(game))); + } + private static uint ConvertAddressToNumber(IPAddress address) { #pragma warning disable CS0618 // Among Us only supports IPv4 @@ -210,4 +225,93 @@ public sealed class GamesController : ControllerBase }; } } + + private class FindGameByCodeResponse + { + [SetsRequiredMembers] + public FindGameByCodeResponse(MatchmakerError error) => (Errors, Game) = (new[] { error }, null); + + [SetsRequiredMembers] + public FindGameByCodeResponse(GameListingV2 game) => (Errors, Game) = (null, game); + + [JsonPropertyName("Errors")] + public required MatchmakerError[]? Errors { get; init; } + + [JsonPropertyName("Game")] + public required GameListingV2? Game { get; init; } + } + + private class GameListingV2 + { + [JsonPropertyName("IP")] + public required uint Ip { get; init; } + + [JsonPropertyName("Port")] + public required ushort Port { get; init; } + + [JsonPropertyName("GameId")] + public required int GameId { get; init; } + + [JsonPropertyName("PlayerCount")] + public required int PlayerCount { get; init; } + + [JsonPropertyName("HostName")] + public required string HostName { get; init; } + + [JsonPropertyName("TrueHostName")] + public required string TrueHostName { get; init; } + + [JsonPropertyName("HostPlatformName")] + public required string HostPlatformName { get; init; } + + [JsonPropertyName("Platform")] + public required Platforms Platform { get; init; } + + [JsonPropertyName("QuickChat")] + public required QuickChatModes QuickChat { get; init; } + + [JsonPropertyName("Age")] + public required int Age { get; init; } + + [JsonPropertyName("MaxPlayers")] + public required int MaxPlayers { get; init; } + + [JsonPropertyName("NumImpostors")] + public required int NumImpostors { get; init; } + + [JsonPropertyName("MapId")] + public required MapTypes MapId { get; init; } + + [JsonPropertyName("Language")] + public required GameKeywords Language { get; init; } + + [JsonPropertyName("Options")] + public required string Options { get; init; } + + public static GameListingV2 From(IGame game) + { + var platform = game.Host?.Client.PlatformSpecificData; + + return new GameListingV2 + { + Ip = ConvertAddressToNumber(game.PublicIp.Address), + Port = (ushort)game.PublicIp.Port, + GameId = game.Code, + PlayerCount = game.PlayerCount, + HostName = game.DisplayName ?? game.Host?.Client.Name ?? "Unknown host", + TrueHostName = game.DisplayName ?? game.Host?.Client.Name ?? "Unknown host", + HostPlatformName = platform?.PlatformName ?? string.Empty, + Platform = platform?.Platform ?? Platforms.Unknown, + QuickChat = game.Host?.Client.ChatMode ?? QuickChatModes.QuickChatOnly, + Age = 0, + MaxPlayers = game.Options.MaxPlayers, + NumImpostors = game.Options.NumImpostors, + MapId = game.Options.Map, + Language = game.Options.Keywords, + + // TODO don't hardcode + Options = "CXQAAAEAAA8AAQAAAgAAwD8AAEA/AAAAQAAAoEECAgQCAAAAAgEtAAAALQAAAAAPAAABAQAHBQABZAMAAAAKHgIAAWQCAAAKDwQAAkYDAAAjDwADAAFkAgAADw8IAAJkAgAACgEJAAFkAgAACh4KAAFkAwAADxQB", + }; + } + } } -- 2.39.5