diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..f84d614be --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Launch Program", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}/src/server/GameManager.ts", + "outFiles": [ + "${workspaceFolder}/**/*.js" + ] + } + ] +} \ No newline at end of file diff --git a/TODO.txt b/TODO.txt index af488b6bb..3a70005fb 100644 --- a/TODO.txt +++ b/TODO.txt @@ -15,7 +15,9 @@ * improve front page DONE 8/12/2024 * attacks cancel out DONE 8/13/2024 * upload and start server DONE 8/13/2024 -* fix multiplayer +* fix multiplayer DONE 8/14/2024 +* fix server resource leak +* balance attacks/expansions better * better algorithm for name render placement * make boats larger * have boats not get close to shore diff --git a/src/server/GameManager.ts b/src/server/GameManager.ts index e00fef40b..919deedb9 100644 --- a/src/server/GameManager.ts +++ b/src/server/GameManager.ts @@ -43,12 +43,6 @@ export class GameManager { this.games.set(game.id, game) } - startGame(lobby: Lobby) { - const gs = new GameServer(this.random.nextID(), lobby.clients, defaultConfig) - this.games.set(gs.id, gs) - gs.start() - } - tick() { const now = Date.now() @@ -56,7 +50,7 @@ export class GameManager { const expired = this.lobbies().filter(l => l.isExpired(now - 2000)) this._lobbies = new Map(active.map(lobby => [lobby.id, lobby])); expired.forEach(lobby => { - const game = new GameServer(lobby.id, lobby.clients, this.settings) + const game = new GameServer(lobby.id, now, lobby.clients, this.settings) this.games.set(game.id, game) game.start() }) @@ -65,5 +59,15 @@ export class GameManager { this.lastNewLobby = now this.addLobby(new Lobby(this.random.nextID(), this.settings.lobbyLifetime())) } + + const activeGames: Map = new Map() + for (const [id, game] of this.games) { + if (game.isActive()) { + activeGames.set(id, game) + } else { + game.endGame() + } + } + //this.games = activeGames } } \ No newline at end of file diff --git a/src/server/GameServer.ts b/src/server/GameServer.ts index a1ff20b84..80c93b6bb 100644 --- a/src/server/GameServer.ts +++ b/src/server/GameServer.ts @@ -12,6 +12,7 @@ export class GameServer { constructor( public readonly id: GameID, + private startTime: number, private clients: Map, private settings: Config, ) { @@ -67,8 +68,18 @@ export class GameServer { }) } - private tick(event: TickEvent) { + public isActive(): boolean { + return Date.now() - this.startTime < 1000 * 60 * 60 // 1 hour + } + endGame() { + // Close all WebSocket connections + this.clients.forEach(client => { + client.ws.removeAllListeners('message'); + if (client.ws.readyState === WebSocket.OPEN) { + client.ws.close(); + } + }); } } \ No newline at end of file