fix(server): game completion pipeline — stats recording + dict iteration safety
Three bugs prevented game stats from recording: 1. broadcast_game_state had game_over processing (log_game_end + stats) inside the per-player loop — if all players disconnected before the loop ran, stats never processed. Moved to run once before the loop. 2. room.broadcast and broadcast_game_state iterated players.items() without snapshotting, causing RuntimeError when concurrent player disconnects mutated the dict. Fixed with list(). 3. stats_service.process_game_from_state passed avg_round_score to a CASE expression without a type hint, causing asyncpg to fail with "could not determine data type of parameter $6". Added ::integer casts. Also wrapped per-player send_json calls in try/except so a single disconnected player doesn't abort the broadcast to remaining players. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -232,7 +232,7 @@ class Room:
|
||||
message: JSON-serializable message dict.
|
||||
exclude: Optional player ID to skip.
|
||||
"""
|
||||
for player_id, player in self.players.items():
|
||||
for player_id, player in list(self.players.items()):
|
||||
if player_id != exclude and player.websocket and not player.is_cpu:
|
||||
try:
|
||||
await player.websocket.send_json(message)
|
||||
|
||||
Reference in New Issue
Block a user