From 9d8a2a2b41d9c5dcf0a7c673676c3ecc83a4e80c Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Thu, 8 May 2025 15:55:03 -0400 Subject: [PATCH] bugfix: Joining game fails (#680) ## Description: Restore the necessary fields to the join message. ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced - [x] I understand that submitting code with bugs that could have been caught through manual testing blocks releases and new features for all contributors Co-authored-by: Scott Anderson <662325+scottanderson@users.noreply.github.com> --- src/core/Schemas.ts | 19 +++++++++---------- src/server/Worker.ts | 6 ++++-- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts index 392ce7f99..8f202d9d0 100644 --- a/src/core/Schemas.ts +++ b/src/core/Schemas.ts @@ -371,42 +371,41 @@ export const ServerMessageSchema = z.union([ // Client -const ClientBaseMessageSchema = z.object({ - type: z.enum(["winner", "join", "intent", "ping", "log", "hash"]), -}); - -export const ClientSendWinnerSchema = ClientBaseMessageSchema.extend({ +export const ClientSendWinnerSchema = z.object({ type: z.literal("winner"), winner: z.union([ID, TeamSchema]).nullable(), allPlayersStats: AllPlayersStatsSchema, winnerType: z.enum(["player", "team"]), }); -export const ClientHashSchema = ClientBaseMessageSchema.extend({ +export const ClientHashSchema = z.object({ type: z.literal("hash"), hash: z.number(), turnNumber: z.number(), }); -export const ClientLogMessageSchema = ClientBaseMessageSchema.extend({ +export const ClientLogMessageSchema = z.object({ type: z.literal("log"), severity: z.nativeEnum(LogSeverity), log: ID, persistentID: SafeString, }); -export const ClientPingMessageSchema = ClientBaseMessageSchema.extend({ +export const ClientPingMessageSchema = z.object({ type: z.literal("ping"), }); -export const ClientIntentMessageSchema = ClientBaseMessageSchema.extend({ +export const ClientIntentMessageSchema = z.object({ type: z.literal("intent"), intent: IntentSchema, }); // WARNING: never send this message to clients. -export const ClientJoinMessageSchema = ClientBaseMessageSchema.extend({ +export const ClientJoinMessageSchema = z.object({ type: z.literal("join"), + clientID: ID, + persistentID: SafeString, // WARNING: PII + gameID: ID, lastTurn: z.number(), // The last turn the client saw. username: SafeString, flag: SafeString.nullable().optional(), diff --git a/src/server/Worker.ts b/src/server/Worker.ts index 880dca263..0ce554f16 100644 --- a/src/server/Worker.ts +++ b/src/server/Worker.ts @@ -7,7 +7,7 @@ import { WebSocket, WebSocketServer } from "ws"; import { GameEnv } from "../core/configuration/Config"; import { getServerConfigFromServer } from "../core/configuration/ConfigLoader"; import { GameType } from "../core/game/Game"; -import { GameConfig, GameRecord } from "../core/Schemas"; +import { ClientMessageSchema, GameConfig, GameRecord } from "../core/Schemas"; import { archive, readGameRecord } from "./Archive"; import { Client } from "./Client"; import { GameManager } from "./GameManager"; @@ -263,7 +263,9 @@ export function startWorker() { try { // Process WebSocket messages as in your original code // Parse and handle client messages - const clientMsg = JSON.parse(message.toString()); + const clientMsg = ClientMessageSchema.parse( + JSON.parse(message.toString()), + ); if (clientMsg.type == "join") { // Verify this worker should handle this game