]> git.deb.at Git - rhonda/impostor.git/commitdiff
Add endpoint to find games by code
authorminiduikboot <mini@duikbo.at>
Tue, 25 Mar 2025 23:50:24 +0000 (00:50 +0100)
committerminiduikboot <mini@duikbo.at>
Sun, 30 Mar 2025 18:34:18 +0000 (20:34 +0200)
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

index e64a498aeb92ad16a1d215445659e3e6f4767a41..58c3abb7cb783a5c716549c45ff5aa7b601ca3bd 100644 (file)
@@ -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",
+            };
+        }
+    }
 }