add WS handlers for predictions, dishes game messages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 11:15:31 +01:00
parent 1b0348de23
commit 448c6ee8e6

View File

@@ -41,6 +41,25 @@ function sendError(ws: WSContext, message: string) {
sendTo(ws, { type: "error", message })
}
function sendGameState(ws: WSContext, roomCode: string, sessionId: string) {
const gm = roomManager.getGameManager(roomCode)
const playerId = roomManager.getPlayerIdBySession(roomCode, sessionId)
if (!gm || !playerId) return
const playerLookup = roomManager.getPlayerLookup(roomCode)
const gameState = gm.getGameStateForPlayer(playerId, playerLookup)
sendTo(ws, { type: "game_state", gameState })
}
function sendDisplayGameState(ws: WSContext, roomCode: string) {
const gm = roomManager.getGameManager(roomCode)
if (!gm) return
const playerLookup = roomManager.getPlayerLookup(roomCode)
const gameState = gm.getGameStateForDisplay(playerLookup)
sendTo(ws, { type: "game_state", gameState })
}
let registered = false
export function registerWebSocketRoutes() {
@@ -79,6 +98,7 @@ export function registerWebSocketRoutes() {
type: "room_state",
room: roomManager.getRoom(roomCode)!,
})
sendGameState(ws, roomCode, sessionId)
broadcast(roomCode, {
type: "player_reconnected",
playerId: result.playerId,
@@ -90,6 +110,7 @@ export function registerWebSocketRoutes() {
type: "room_state",
room: roomManager.getRoom(roomCode)!,
})
sendDisplayGameState(ws, roomCode)
}
},
@@ -131,6 +152,7 @@ export function registerWebSocketRoutes() {
room: roomManager.getRoom(roomCode)!,
sessionId: result.sessionId,
})
sendGameState(ws, roomCode, result.sessionId)
// Broadcast player joined to everyone
const room = roomManager.getRoom(roomCode)!
@@ -155,6 +177,7 @@ export function registerWebSocketRoutes() {
type: "room_state",
room: roomManager.getRoom(roomCode)!,
})
sendGameState(ws, roomCode, msg.sessionId)
broadcast(roomCode, {
type: "player_reconnected",
playerId: result.playerId,
@@ -176,6 +199,13 @@ export function registerWebSocketRoutes() {
type: "act_changed",
newAct: result.newAct,
})
if (result.newAct === "act2") {
const gm = roomManager.getGameManager(roomCode)
if (gm) {
gm.lockPredictions()
broadcast(roomCode, { type: "predictions_locked" })
}
}
break
}
@@ -192,6 +222,119 @@ export function registerWebSocketRoutes() {
broadcast(roomCode, { type: "room_ended" })
break
}
case "submit_prediction": {
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.submitPrediction(playerId, msg.predictedWinner, msg.top3, msg.nulPointsPick)
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,
})
break
}
}
},