From a9caee632394045591e7d759d92553f459fab218 Mon Sep 17 00:00:00 2001 From: Evan Date: Thu, 27 Feb 2025 20:10:45 -0800 Subject: [PATCH] make GameManager more efficient --- src/server/GameManager.ts | 66 ++++++++++++++++++--------------------- src/server/GameServer.ts | 2 +- src/server/Worker.ts | 2 +- 3 files changed, 33 insertions(+), 37 deletions(-) diff --git a/src/server/GameManager.ts b/src/server/GameManager.ts index 624ee16d2..56b7032d4 100644 --- a/src/server/GameManager.ts +++ b/src/server/GameManager.ts @@ -5,20 +5,18 @@ import { GamePhase, GameServer } from "./GameServer"; import { Difficulty, GameMapType, GameType } from "../core/game/Game"; export class GameManager { - private games: GameServer[] = []; + private games: Map = new Map(); - constructor(private config: ServerConfig) {} - - public game(id: GameID): GameServer | null { - return this.games.find((g) => g.id == id); + constructor(private config: ServerConfig) { + setInterval(() => this.tick(), 1000); } - gamesByPhase(phase: GamePhase): GameServer[] { - return this.games.filter((g) => g.phase() == phase); + public game(id: GameID): GameServer | null { + return this.games.get(id); } addClient(client: Client, gameID: GameID, lastTurn: number): boolean { - const game = this.games.find((g) => g.id == gameID); + const game = this.games.get(gameID); if (game) { game.addClient(client, lastTurn); return true; @@ -36,38 +34,36 @@ export class GameManager { infiniteTroops: false, instantBuild: false, bots: 400, - ...gameConfig, // TODO: make sure this works + ...gameConfig, }); - this.games.push(game); + this.games.set(id, game); return game; } - hasActiveGame(gameID: GameID): boolean { - const game = this.games - .filter((g) => g.id == gameID) - .filter( - (g) => g.phase() == GamePhase.Lobby || g.phase() == GamePhase.Active, - ); - return game.length > 0; - } - tick() { - const lobbies = this.gamesByPhase(GamePhase.Lobby); - const active = this.gamesByPhase(GamePhase.Active); - const finished = this.gamesByPhase(GamePhase.Finished); - - active - .filter((g) => !g.hasStarted() && g.isPublic) - .forEach((g) => { - g.start(); - }); - finished.forEach((g) => { - try { - g.endGame(); - } catch (error) { - console.log(`error ending game ${g.id}: `, error); + const active = new Map(); + for (const [id, game] of this.games) { + const phase = game.phase(); + if (phase == GamePhase.Active) { + if (game.isPublic && !game.hasStarted()) { + try { + game.start(); + } catch (error) { + console.log(`error starting game ${id}: ${error}`); + } + } } - }); - this.games = [...lobbies, ...active]; + + if (phase == GamePhase.Finished) { + try { + game.end(); + } catch (error) { + console.log(`error ending game ${id}: ${error}`); + } + } else { + active.set(id, game); + } + } + this.games = active; } } diff --git a/src/server/GameServer.ts b/src/server/GameServer.ts index c724630aa..9544419a7 100644 --- a/src/server/GameServer.ts +++ b/src/server/GameServer.ts @@ -274,7 +274,7 @@ export class GameServer { }); } - async endGame() { + async end() { // Close all WebSocket connections clearInterval(this.endTurnIntervalID); this.allClients.forEach((client) => { diff --git a/src/server/Worker.ts b/src/server/Worker.ts index f9a407cd9..e9258cc74 100644 --- a/src/server/Worker.ts +++ b/src/server/Worker.ts @@ -192,7 +192,7 @@ export function startWorker() { asyncHandler(async (req, res) => { const lobbyId = req.params.id; console.log(`checking if game ${lobbyId} exists`); - let gameExists = gm.hasActiveGame(lobbyId); + let gameExists = gm.game(lobbyId); res.json({ exists: gameExists, });