diff --git a/packages/server/src/ws/handler.ts b/packages/server/src/ws/handler.ts index ce33126..91475db 100644 --- a/packages/server/src/ws/handler.ts +++ b/packages/server/src/ws/handler.ts @@ -46,9 +46,8 @@ function sendGameState(ws: WSContext, roomCode: string, sessionId: string) { const playerId = roomManager.getPlayerIdBySession(roomCode, sessionId) if (!gm || !playerId) return - const playerLookup = roomManager.getPlayerLookup(roomCode) - const isHost = roomManager.isHost(roomCode, sessionId) - const gameState = gm.getGameStateForPlayer(playerId, playerLookup, isHost) + const allPlayerIds = roomManager.getAllPlayerIds(roomCode) + const gameState = gm.getGameStateForPlayer(playerId, allPlayerIds) sendTo(ws, { type: "game_state", gameState }) } @@ -56,11 +55,27 @@ function sendDisplayGameState(ws: WSContext, roomCode: string) { const gm = roomManager.getGameManager(roomCode) if (!gm) return - const playerLookup = roomManager.getPlayerLookup(roomCode) - const gameState = gm.getGameStateForDisplay(playerLookup) + const allPlayerIds = roomManager.getAllPlayerIds(roomCode) + const gameState = gm.getGameStateForDisplay(allPlayerIds) sendTo(ws, { type: "game_state", gameState }) } +function broadcastGameStateToAll(roomCode: string) { + const conns = roomConnections.get(roomCode) + if (!conns) return + for (const conn of conns) { + try { + if (conn.sessionId) { + sendGameState(conn.ws, roomCode, conn.sessionId) + } else { + sendDisplayGameState(conn.ws, roomCode) + } + } catch { + // Connection may be closed + } + } +} + let registered = false export function registerWebSocketRoutes() { @@ -86,7 +101,6 @@ export function registerWebSocketRoutes() { connection = { ws, sessionId } getConnections(roomCode).add(connection) - // If sessionId provided, attempt reconnect if (sessionId) { const result = roomManager.reconnectPlayer(roomCode, sessionId) if ("error" in result) { @@ -106,7 +120,6 @@ export function registerWebSocketRoutes() { }) } } else { - // Passive viewer (display) or player about to send join_room sendTo(ws, { type: "room_state", room: roomManager.getRoom(roomCode)!, @@ -147,7 +160,6 @@ export function registerWebSocketRoutes() { if (connection) connection.sessionId = sessionId roomManager.setPlayerConnected(roomCode, sessionId, true) - // Send room state with session ID to the new player sendTo(ws, { type: "room_state", room: roomManager.getRoom(roomCode)!, @@ -155,7 +167,6 @@ export function registerWebSocketRoutes() { }) sendGameState(ws, roomCode, result.sessionId) - // Broadcast player joined to everyone const room = roomManager.getRoom(roomCode)! const newPlayer = room.players.find((p) => p.sessionId === sessionId)! broadcast(roomCode, { @@ -200,7 +211,8 @@ export function registerWebSocketRoutes() { type: "act_changed", newAct: result.newAct, }) - if (result.newAct === "act2") { + // Lock predictions when moving from pre-show to live-event + if (result.newAct === "live-event") { const gm = roomManager.getGameManager(roomCode) if (gm) { gm.lockPredictions() @@ -236,104 +248,14 @@ export function registerWebSocketRoutes() { return } - const result = gm.submitPrediction(playerId, msg.predictedWinner, msg.top3, msg.nulPointsPick) + const result = gm.submitPrediction(playerId, msg.first, msg.second, msg.third, msg.last) if ("error" in result) { sendError(ws, result.error) return } - // Send updated game state back to this player only - sendGameState(ws, roomCode, sessionId) - break - } - - case "add_dish": { - if (!sessionId) { - sendError(ws, "Not joined") - return - } - if (!roomManager.isHost(roomCode, sessionId)) { - sendError(ws, "Only the host can add dishes") - return - } - const room = roomManager.getRoom(roomCode) - if (room && room.currentAct !== "lobby" && room.currentAct !== "act1") { - sendError(ws, "Dishes can only be added during lobby or Act 1") - return - } - const gm = roomManager.getGameManager(roomCode) - if (!gm) { - sendError(ws, "Room not found") - return - } - - const result = gm.addDish(msg.name, msg.correctCountry) - if ("error" in result) { - sendError(ws, result.error) - return - } - - broadcast(roomCode, { - type: "dish_added", - dish: { - id: result.dish.id, - name: result.dish.name, - correctCountry: "", - revealed: false, - }, - }) - break - } - - case "submit_dish_guess": { - if (!sessionId) { - sendError(ws, "Not joined") - return - } - const playerId = roomManager.getPlayerIdBySession(roomCode, sessionId) - const gm = roomManager.getGameManager(roomCode) - if (!playerId || !gm) { - sendError(ws, "Room not found") - return - } - - const result = gm.submitDishGuess(playerId, msg.dishId, msg.guessedCountry) - if ("error" in result) { - sendError(ws, result.error) - return - } - - sendTo(ws, { - type: "dish_guess_recorded", - dishId: msg.dishId, - guessedCountry: msg.guessedCountry, - }) - break - } - - case "reveal_dishes": { - if (!sessionId) { - sendError(ws, "Not joined") - return - } - if (!roomManager.isHost(roomCode, sessionId)) { - sendError(ws, "Only the host can reveal dishes") - return - } - const gm = roomManager.getGameManager(roomCode) - if (!gm) { - sendError(ws, "Room not found") - return - } - - gm.revealDishes() - const playerLookup = roomManager.getPlayerLookup(roomCode) - const results = gm.getDishResults(playerLookup) - - broadcast(roomCode, { - type: "dishes_revealed", - results, - }) + // Broadcast game state to all so everyone sees the checkmark update + broadcastGameStateToAll(roomCode) break } }