From 55cba1bdac07358634dec70f620547f779820ead Mon Sep 17 00:00:00 2001 From: Scott Anderson <662325+scottanderson@users.noreply.github.com> Date: Tue, 24 Jun 2025 15:40:31 -0400 Subject: [PATCH] Cleanup public_lobbies endpoint --- src/client/PublicLobby.ts | 15 ++++++++++----- src/core/Schemas.ts | 34 +++++++++++++++++++++++----------- src/server/Master.ts | 4 ++-- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/client/PublicLobby.ts b/src/client/PublicLobby.ts index d6a92dd85..30ed02455 100644 --- a/src/client/PublicLobby.ts +++ b/src/client/PublicLobby.ts @@ -3,7 +3,12 @@ import { customElement, state } from "lit/decorators.js"; import { translateText } from "../client/Utils"; import { GameMapType, GameMode } from "../core/game/Game"; import { terrainMapFileLoader } from "../core/game/TerrainMapFileLoader"; -import { GameID, GameInfo } from "../core/Schemas"; +import { + GameID, + GameInfo, + PublicLobbies, + PublicLobbiesSchema, +} from "../core/Schemas"; import { generateID } from "../core/Util"; import { JoinLobbyEvent } from "./Main"; @@ -41,7 +46,8 @@ export class PublicLobby extends LitElement { private async fetchAndUpdateLobbies(): Promise { try { - this.lobbies = await this.fetchLobbies(); + const publicLobbies = await this.fetchPublicLobbies(); + this.lobbies = publicLobbies.lobbies; this.lobbies.forEach((l) => { // Store the start time on first fetch because endpoint is cached, causing // the time to appear irregular. @@ -72,13 +78,12 @@ export class PublicLobby extends LitElement { } } - async fetchLobbies(): Promise { + async fetchPublicLobbies(): Promise { try { const response = await fetch(`/api/public_lobbies`); if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); - const data = await response.json(); - return data.lobbies; + return response.json().then(PublicLobbiesSchema.parse); } catch (error) { console.error("Error fetching lobbies:", error); throw error; diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts index 85e6ddd49..f3f23ac0a 100644 --- a/src/core/Schemas.ts +++ b/src/core/Schemas.ts @@ -106,17 +106,6 @@ export type Player = z.infer; export type GameStartInfo = z.infer; const PlayerTypeSchema = z.enum(PlayerType); -export interface GameInfo { - gameID: GameID; - clients?: ClientInfo[]; - numClients?: number; - msUntilStart?: number; - gameConfig?: GameConfig; -} -export interface ClientInfo { - clientID: ClientID; - username: string; -} export enum LogSeverity { Debug = "DEBUG", Info = "INFO", @@ -205,6 +194,21 @@ export const QuickChatKeySchema = z.enum( ) as [string, ...string[]], ); +export const ClientInfoSchema = z.object({ + clientID: ID, + username: UsernameSchema, +}); +export type ClientInfo = z.infer; + +export const GameInfoSchema = z.object({ + gameID: ID, + clients: ClientInfoSchema.array().optional(), + numClients: z.number().optional(), + msUntilStart: z.number().optional(), + gameConfig: GameConfigSchema.optional(), +}); +export type GameInfo = z.infer; + // // Intents // @@ -521,3 +525,11 @@ export const GameRecordSchema = AnalyticsRecordSchema.extend({ turns: TurnSchema.array(), }); export type GameRecord = z.infer; + +// +// Game server API calls +// +export const PublicLobbiesSchema = z.object({ + lobbies: GameInfoSchema.array(), +}); +export type PublicLobbies = z.infer; diff --git a/src/server/Master.ts b/src/server/Master.ts index 388aba19c..888c8c144 100644 --- a/src/server/Master.ts +++ b/src/server/Master.ts @@ -5,7 +5,7 @@ import http from "http"; import path from "path"; import { fileURLToPath } from "url"; import { getServerConfigFromServer } from "../core/configuration/ConfigLoader"; -import { GameInfo } from "../core/Schemas"; +import { GameInfo, PublicLobbies } from "../core/Schemas"; import { generateID } from "../core/Util"; import { gatekeeper, LimiterType } from "./Gatekeeper"; import { logger } from "./Logger"; @@ -260,7 +260,7 @@ async function fetchLobbies(): Promise { // Update the JSON string publicLobbiesJsonStr = JSON.stringify({ lobbies: lobbyInfos, - }); + } satisfies PublicLobbies); return publicLobbyIDs.size; }