From b9dad022fc3ddf5901c962e36363bd647e977b04 Mon Sep 17 00:00:00 2001 From: Ilan Schemoul Date: Fri, 14 Mar 2025 01:03:38 +0100 Subject: [PATCH] fix timer (#239) - **improve and fix dynamic lobby** - **Revert "Change BorderTiles from Array to Set (#230)"** I'm obviously forced to include the revert patch otherwise I can't compile. but you should first merge PR dedicated to revert before tthis --- src/core/configuration/Config.ts | 4 +-- src/core/configuration/DefaultConfig.ts | 15 ++++++++-- src/core/configuration/DevConfig.ts | 2 +- src/server/Master.ts | 39 ++++++++++++------------- src/server/Worker.ts | 1 - 5 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/core/configuration/Config.ts b/src/core/configuration/Config.ts index b23234f90..c0bbd0309 100644 --- a/src/core/configuration/Config.ts +++ b/src/core/configuration/Config.ts @@ -1,7 +1,7 @@ import { Difficulty, Game, - GameType, + GameMapType, Gold, Player, PlayerID, @@ -91,7 +91,7 @@ export interface ServerConfig { turnIntervalMs(): number; gameCreationRate(highTraffic: boolean): number; lobbyLifetime(highTraffic: boolean): number; - lobbyMaxPlayers(): number; + lobbyMaxPlayers(map: GameMapType): number; discordRedirectURI(): string; numWorkers(): number; workerIndex(gameID: GameID): number; diff --git a/src/core/configuration/DefaultConfig.ts b/src/core/configuration/DefaultConfig.ts index d11971df0..bc97c5cf6 100644 --- a/src/core/configuration/DefaultConfig.ts +++ b/src/core/configuration/DefaultConfig.ts @@ -1,6 +1,7 @@ import { Difficulty, Game, + GameMapType, GameType, Gold, Player, @@ -12,7 +13,7 @@ import { UnitInfo, UnitType, } from "../game/Game"; -import { TileRef } from "../game/GameMap"; +import { GameMap, TileRef } from "../game/GameMap"; import { PlayerView } from "../game/GameView"; import { UserSettings } from "../game/UserSettings"; import { GameConfig, GameID } from "../Schemas"; @@ -54,8 +55,16 @@ export abstract class DefaultServerConfig implements ServerConfig { return 50 * 1000; } } - lobbyMaxPlayers(): number { - return Math.random() < 0.1 ? 100 : 35; + lobbyMaxPlayers(map: GameMapType): number { + if (map == GameMapType.World) { + return Math.random() < 0.3 ? 150 : 60; + } + if ( + [GameMapType.Mars, GameMapType.Africa, GameMapType.BlackSea].includes(map) + ) { + return Math.random() < 0.3 ? 70 : 50; + } + return Math.random() < 0.3 ? 60 : 40; } lobbyLifetime(highTraffic: boolean): number { return this.gameCreationRate(highTraffic) * 2; diff --git a/src/core/configuration/DevConfig.ts b/src/core/configuration/DevConfig.ts index f88184a5f..af460461f 100644 --- a/src/core/configuration/DevConfig.ts +++ b/src/core/configuration/DevConfig.ts @@ -1,4 +1,4 @@ -import { GameType, Player, PlayerInfo, UnitInfo, UnitType } from "../game/Game"; +import { GameType, UnitInfo, UnitType } from "../game/Game"; import { UserSettings } from "../game/UserSettings"; import { GameConfig } from "../Schemas"; import { GameEnv, ServerConfig } from "./Config"; diff --git a/src/server/Master.ts b/src/server/Master.ts index 930149ec8..f98e2289a 100644 --- a/src/server/Master.ts +++ b/src/server/Master.ts @@ -90,27 +90,21 @@ export async function startMaster() { if (readyWorkers.size === config.numWorkers()) { console.log("All workers ready, starting game scheduling"); - // Safe implementation of dynamic interval - let timeoutId = null; - const scheduleLobbies = () => { - schedulePublicGame() - .catch((error) => { - console.error("Error scheduling public game:", error); - }) - .finally(() => { - // Schedule next run with the current config value - const currentLifetime = - config.gameCreationRate(isHighTrafficTime()); - timeoutId = setTimeout(scheduleLobbies, currentLifetime); - }); + schedulePublicGame().catch((error) => { + console.error("Error scheduling public game:", error); + }); }; - // Run first execution immediately - scheduleLobbies(); - - // Regular interval for fetching lobbies - setInterval(() => fetchLobbies(), 250); + setInterval( + () => + fetchLobbies().then((lobbies) => { + if (lobbies == 0) { + scheduleLobbies(); + } + }), + 100, + ); } } }); @@ -162,7 +156,7 @@ app.get( }), ); -async function fetchLobbies(): Promise { +async function fetchLobbies(): Promise { const fetchPromises = []; for (const gameID of publicLobbyIDs) { @@ -208,16 +202,19 @@ async function fetchLobbies(): Promise { publicLobbiesJsonStr = JSON.stringify({ lobbies: lobbyInfos, }); + + return publicLobbyIDs.size; } // Function to schedule a new public game async function schedulePublicGame() { const gameID = generateID(); + const map = getNextMap(); publicLobbyIDs.add(gameID); // Create the default public game config (from your GameManager) const defaultGameConfig = { - gameMap: getNextMap(), - maxPlayers: config.lobbyMaxPlayers(), + gameMap: map, + maxPlayers: config.lobbyMaxPlayers(map), gameType: GameType.Public, difficulty: Difficulty.Medium, infiniteGold: false, diff --git a/src/server/Worker.ts b/src/server/Worker.ts index db0516bea..2c2be4fa6 100644 --- a/src/server/Worker.ts +++ b/src/server/Worker.ts @@ -70,7 +70,6 @@ export function startWorker() { }), ); - // Endpoint to create a private lobby app.post( "/api/create_game/:id", gatekeeper.httpHandler(LimiterType.Post, async (req, res) => {