fix: detect game start for Pack 7+ titles that don't use state: "Gameplay"
Pack 7 games (Quiplash 3, Blather Round) transition room state from "Lobby" to "Logo" instead of "Gameplay". Even newer titles (Doominate, Big Survey) have no room entity at all — the only signals are room/lock and room/exit opcodes. - parseRoomEntity: detect game started as any non-Lobby state - handleMessage: add room/lock and room/exit opcode handling - handleRoomLock: emit game.started as fallback for room-entity-less games - handleRoomExit: emit game.ended on explicit room close - Tests: 6 new tests covering Logo state, room/lock, room/exit Verified against live rooms: quiplash3, blanky-blank, you-ruined-it, bigsurvey. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -36,7 +36,7 @@ class EcastShardClient {
|
||||
lobbyState: roomVal.lobbyState ?? null,
|
||||
gameCanStart: !!roomVal.gameCanStart,
|
||||
gameIsStarting: !!roomVal.gameIsStarting,
|
||||
gameStarted: roomVal.state === 'Gameplay',
|
||||
gameStarted: roomVal.state != null && roomVal.state !== 'Lobby',
|
||||
gameFinished: !!roomVal.gameFinished,
|
||||
};
|
||||
}
|
||||
@@ -213,6 +213,12 @@ class EcastShardClient {
|
||||
break;
|
||||
case 'client/disconnected':
|
||||
break;
|
||||
case 'room/lock':
|
||||
this.handleRoomLock();
|
||||
break;
|
||||
case 'room/exit':
|
||||
this.handleRoomExit(message.result);
|
||||
break;
|
||||
case 'error':
|
||||
this.handleError(message.result);
|
||||
break;
|
||||
@@ -363,6 +369,44 @@ class EcastShardClient {
|
||||
}
|
||||
}
|
||||
|
||||
handleRoomLock() {
|
||||
if (!this.gameStarted) {
|
||||
console.log(`[Shard Monitor] Room ${this.roomCode} locked (game starting)`);
|
||||
this.gameStarted = true;
|
||||
this.gameState = this.gameState || 'Gameplay';
|
||||
this.onEvent('game.started', {
|
||||
sessionId: this.sessionId,
|
||||
gameId: this.gameId,
|
||||
roomCode: this.roomCode,
|
||||
playerCount: this.playerCount,
|
||||
players: [...this.playerNames],
|
||||
maxPlayers: this.maxPlayers,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleRoomExit() {
|
||||
if (this.gameFinished) return;
|
||||
console.log(`[Shard Monitor] Room ${this.roomCode} exited`);
|
||||
this.gameFinished = true;
|
||||
this.onEvent('game.ended', {
|
||||
sessionId: this.sessionId,
|
||||
gameId: this.gameId,
|
||||
roomCode: this.roomCode,
|
||||
playerCount: this.playerCount,
|
||||
players: [...this.playerNames],
|
||||
});
|
||||
this.onEvent('room.disconnected', {
|
||||
sessionId: this.sessionId,
|
||||
gameId: this.gameId,
|
||||
roomCode: this.roomCode,
|
||||
reason: 'room_closed',
|
||||
finalPlayerCount: this.playerCount,
|
||||
});
|
||||
activeShards.delete(`${this.sessionId}-${this.gameId}`);
|
||||
this.disconnect();
|
||||
}
|
||||
|
||||
handleError(result) {
|
||||
console.error(`[Shard Monitor] Ecast error ${result?.code}: ${result?.msg}`);
|
||||
if (result?.code === 2027) {
|
||||
|
||||
Reference in New Issue
Block a user