Add audience.joined and game.started WebSocket events, reduce poll interval
Broadcast audience.joined when the audience client receives its first client/welcome frame. Broadcast game.started when the room lock is detected. Reduced initial wait and poll interval from 30s to 10s for faster feedback. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -67,6 +67,7 @@ async function watchGameAsAudience(sessionId, gameId, roomCode, maxPlayers) {
|
|||||||
let bestPlayerCount = null;
|
let bestPlayerCount = null;
|
||||||
let startPlayerCount = null; // Authoritative count from 'start' action
|
let startPlayerCount = null; // Authoritative count from 'start' action
|
||||||
let gameEnded = false;
|
let gameEnded = false;
|
||||||
|
let audienceJoined = false; // Track whether we've confirmed audience join
|
||||||
let frameCount = 0;
|
let frameCount = 0;
|
||||||
|
|
||||||
// Enable CDP and listen for WebSocket frames BEFORE navigating
|
// Enable CDP and listen for WebSocket frames BEFORE navigating
|
||||||
@@ -91,6 +92,22 @@ async function watchGameAsAudience(sessionId, gameId, roomCode, maxPlayers) {
|
|||||||
if (process.env.DEBUG) {
|
if (process.env.DEBUG) {
|
||||||
console.log(`[Frame ${frameCount}] Found bc:room in client/welcome`);
|
console.log(`[Frame ${frameCount}] Found bc:room in client/welcome`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// First client/welcome means Jackbox accepted our audience join
|
||||||
|
if (!audienceJoined) {
|
||||||
|
audienceJoined = true;
|
||||||
|
console.log(`[Audience] Successfully joined room ${roomCode} as audience`);
|
||||||
|
|
||||||
|
// Broadcast audience.joined event via WebSocket
|
||||||
|
const wsManager = getWebSocketManager();
|
||||||
|
if (wsManager) {
|
||||||
|
wsManager.broadcastEvent('audience.joined', {
|
||||||
|
sessionId,
|
||||||
|
gameId,
|
||||||
|
roomCode
|
||||||
|
}, parseInt(sessionId));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.opcode === 'object' && data.result?.key === 'bc:room') {
|
if (data.opcode === 'object' && data.result?.key === 'bc:room') {
|
||||||
@@ -285,6 +302,26 @@ async function watchGameAsAudience(sessionId, gameId, roomCode, maxPlayers) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcast game.started event when room becomes locked
|
||||||
|
*/
|
||||||
|
function broadcastGameStarted(sessionId, gameId, roomCode, maxPlayers) {
|
||||||
|
try {
|
||||||
|
const wsManager = getWebSocketManager();
|
||||||
|
if (wsManager) {
|
||||||
|
wsManager.broadcastEvent('game.started', {
|
||||||
|
sessionId,
|
||||||
|
gameId,
|
||||||
|
roomCode,
|
||||||
|
maxPlayers
|
||||||
|
}, parseInt(sessionId));
|
||||||
|
}
|
||||||
|
console.log(`[Player Count] Broadcasted game.started for room ${roomCode} (max: ${maxPlayers})`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[Player Count] Failed to broadcast game.started:', error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update player count in database
|
* Update player count in database
|
||||||
*/
|
*/
|
||||||
@@ -315,12 +352,13 @@ function updatePlayerCount(sessionId, gameId, playerCount, status) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Start checking player count for a game
|
* Start checking player count for a game
|
||||||
* New strategy:
|
* Strategy:
|
||||||
* 1. Wait 30 seconds
|
* 1. Wait 10 seconds for initial room setup
|
||||||
* 2. Check if game is locked - if not, wait another 30 seconds
|
* 2. Poll every 10 seconds until game is locked (started)
|
||||||
* 3. Once locked, join audience and watch entire game
|
* 3. Broadcast game.started event when locked detected
|
||||||
* 4. Update UI as we learn more
|
* 4. Join audience and watch entire game
|
||||||
* 5. Finalize when game ends
|
* 5. Update UI as we learn more
|
||||||
|
* 6. Finalize when game ends
|
||||||
*/
|
*/
|
||||||
async function startPlayerCountCheck(sessionId, gameId, roomCode, maxPlayers = 8) {
|
async function startPlayerCountCheck(sessionId, gameId, roomCode, maxPlayers = 8) {
|
||||||
const checkKey = `${sessionId}-${gameId}`;
|
const checkKey = `${sessionId}-${gameId}`;
|
||||||
@@ -388,7 +426,7 @@ async function startPlayerCountCheck(sessionId, gameId, roomCode, maxPlayers = 8
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Wait 30 seconds before first check
|
// Wait 10 seconds before first check
|
||||||
const initialTimeout = setTimeout(async () => {
|
const initialTimeout = setTimeout(async () => {
|
||||||
try {
|
try {
|
||||||
// Update status to checking
|
// Update status to checking
|
||||||
@@ -398,16 +436,17 @@ async function startPlayerCountCheck(sessionId, gameId, roomCode, maxPlayers = 8
|
|||||||
WHERE session_id = ? AND id = ?
|
WHERE session_id = ? AND id = ?
|
||||||
`).run(sessionId, gameId);
|
`).run(sessionId, gameId);
|
||||||
|
|
||||||
console.log(`[Player Count] Initial check after 30s for ${checkKey}`);
|
console.log(`[Player Count] Initial check after 10s for ${checkKey}`);
|
||||||
const result = await waitForGameStart();
|
const result = await waitForGameStart();
|
||||||
|
|
||||||
if (result && result.ready === true) {
|
if (result && result.ready === true) {
|
||||||
// Game is locked, start watching with REAL maxPlayers from Jackbox
|
// Game is locked, broadcast game.started and start watching
|
||||||
const realMaxPlayers = result.maxPlayers;
|
const realMaxPlayers = result.maxPlayers;
|
||||||
|
broadcastGameStarted(sessionId, gameId, roomCode, realMaxPlayers);
|
||||||
console.log(`[Player Count] Using real maxPlayers from Jackbox: ${realMaxPlayers} (database had: ${maxPlayers})`);
|
console.log(`[Player Count] Using real maxPlayers from Jackbox: ${realMaxPlayers} (database had: ${maxPlayers})`);
|
||||||
await watchGameAsAudience(sessionId, gameId, roomCode, realMaxPlayers);
|
await watchGameAsAudience(sessionId, gameId, roomCode, realMaxPlayers);
|
||||||
} else if (result === null) {
|
} else if (result === null) {
|
||||||
// Not ready yet, check every 30 seconds
|
// Not ready yet, poll every 10 seconds
|
||||||
const checkInterval = setInterval(async () => {
|
const checkInterval = setInterval(async () => {
|
||||||
// Check if we should stop
|
// Check if we should stop
|
||||||
const game = db.prepare(`
|
const game = db.prepare(`
|
||||||
@@ -424,11 +463,12 @@ async function startPlayerCountCheck(sessionId, gameId, roomCode, maxPlayers = 8
|
|||||||
|
|
||||||
const result = await waitForGameStart();
|
const result = await waitForGameStart();
|
||||||
if (result && result.ready === true) {
|
if (result && result.ready === true) {
|
||||||
// Game is now locked, stop interval and start watching with REAL maxPlayers
|
// Game is now locked, stop interval, broadcast game.started, and start watching
|
||||||
clearInterval(checkInterval);
|
clearInterval(checkInterval);
|
||||||
const check = activeChecks.get(checkKey);
|
const check = activeChecks.get(checkKey);
|
||||||
if (check) check.interval = null;
|
if (check) check.interval = null;
|
||||||
const realMaxPlayers = result.maxPlayers;
|
const realMaxPlayers = result.maxPlayers;
|
||||||
|
broadcastGameStarted(sessionId, gameId, roomCode, realMaxPlayers);
|
||||||
console.log(`[Player Count] Using real maxPlayers from Jackbox: ${realMaxPlayers} (database had: ${maxPlayers})`);
|
console.log(`[Player Count] Using real maxPlayers from Jackbox: ${realMaxPlayers} (database had: ${maxPlayers})`);
|
||||||
await watchGameAsAudience(sessionId, gameId, roomCode, realMaxPlayers);
|
await watchGameAsAudience(sessionId, gameId, roomCode, realMaxPlayers);
|
||||||
} else if (result === false) {
|
} else if (result === false) {
|
||||||
@@ -436,7 +476,7 @@ async function startPlayerCountCheck(sessionId, gameId, roomCode, maxPlayers = 8
|
|||||||
clearInterval(checkInterval);
|
clearInterval(checkInterval);
|
||||||
stopPlayerCountCheck(sessionId, gameId);
|
stopPlayerCountCheck(sessionId, gameId);
|
||||||
}
|
}
|
||||||
}, 30000); // Check every 30 seconds
|
}, 10000); // Poll every 10 seconds
|
||||||
|
|
||||||
// Store the interval
|
// Store the interval
|
||||||
const check = activeChecks.get(checkKey);
|
const check = activeChecks.get(checkKey);
|
||||||
@@ -449,7 +489,7 @@ async function startPlayerCountCheck(sessionId, gameId, roomCode, maxPlayers = 8
|
|||||||
updatePlayerCount(sessionId, gameId, null, 'failed');
|
updatePlayerCount(sessionId, gameId, null, 'failed');
|
||||||
stopPlayerCountCheck(sessionId, gameId);
|
stopPlayerCountCheck(sessionId, gameId);
|
||||||
}
|
}
|
||||||
}, 30000); // Wait 30 seconds before first check
|
}, 10000); // Wait 10 seconds before first check
|
||||||
|
|
||||||
// Store the check references
|
// Store the check references
|
||||||
activeChecks.set(checkKey, {
|
activeChecks.set(checkKey, {
|
||||||
|
|||||||
Reference in New Issue
Block a user