make GameManager more efficient

This commit is contained in:
Evan
2025-03-02 09:39:36 -08:00
parent 38365fd9d0
commit a9caee6323
3 changed files with 33 additions and 37 deletions
+31 -35
View File
@@ -5,20 +5,18 @@ import { GamePhase, GameServer } from "./GameServer";
import { Difficulty, GameMapType, GameType } from "../core/game/Game"; import { Difficulty, GameMapType, GameType } from "../core/game/Game";
export class GameManager { export class GameManager {
private games: GameServer[] = []; private games: Map<GameID, GameServer> = new Map();
constructor(private config: ServerConfig) {} constructor(private config: ServerConfig) {
setInterval(() => this.tick(), 1000);
public game(id: GameID): GameServer | null {
return this.games.find((g) => g.id == id);
} }
gamesByPhase(phase: GamePhase): GameServer[] { public game(id: GameID): GameServer | null {
return this.games.filter((g) => g.phase() == phase); return this.games.get(id);
} }
addClient(client: Client, gameID: GameID, lastTurn: number): boolean { 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) { if (game) {
game.addClient(client, lastTurn); game.addClient(client, lastTurn);
return true; return true;
@@ -36,38 +34,36 @@ export class GameManager {
infiniteTroops: false, infiniteTroops: false,
instantBuild: false, instantBuild: false,
bots: 400, bots: 400,
...gameConfig, // TODO: make sure this works ...gameConfig,
}); });
this.games.push(game); this.games.set(id, game);
return 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() { tick() {
const lobbies = this.gamesByPhase(GamePhase.Lobby); const active = new Map<GameID, GameServer>();
const active = this.gamesByPhase(GamePhase.Active); for (const [id, game] of this.games) {
const finished = this.gamesByPhase(GamePhase.Finished); const phase = game.phase();
if (phase == GamePhase.Active) {
active if (game.isPublic && !game.hasStarted()) {
.filter((g) => !g.hasStarted() && g.isPublic) try {
.forEach((g) => { game.start();
g.start(); } catch (error) {
}); console.log(`error starting game ${id}: ${error}`);
finished.forEach((g) => { }
try { }
g.endGame();
} catch (error) {
console.log(`error ending game ${g.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;
} }
} }
+1 -1
View File
@@ -274,7 +274,7 @@ export class GameServer {
}); });
} }
async endGame() { async end() {
// Close all WebSocket connections // Close all WebSocket connections
clearInterval(this.endTurnIntervalID); clearInterval(this.endTurnIntervalID);
this.allClients.forEach((client) => { this.allClients.forEach((client) => {
+1 -1
View File
@@ -192,7 +192,7 @@ export function startWorker() {
asyncHandler(async (req, res) => { asyncHandler(async (req, res) => {
const lobbyId = req.params.id; const lobbyId = req.params.id;
console.log(`checking if game ${lobbyId} exists`); console.log(`checking if game ${lobbyId} exists`);
let gameExists = gm.hasActiveGame(lobbyId); let gameExists = gm.game(lobbyId);
res.json({ res.json({
exists: gameExists, exists: gameExists,
}); });