diff --git a/TODO.txt b/TODO.txt index 4c4eb7a8f..d1349cf20 100644 --- a/TODO.txt +++ b/TODO.txt @@ -20,8 +20,10 @@ * fix bug where game stops after 10s (websocket disconnection) DONE 8/16/2024 * fix server memory leak * balance attacks/expansions better -* Bug: boats not going to destination, coast not being recognized +* BUG: boats not going to destination, coast not being recognized +* BUG: boats freeze game on path calculation * double attack add troops +* Create separate game config dev vs prod * Have some time for spawning before game starts * delete players when territories too small * better algorithm for name render placement diff --git a/src/client/ClientGame.ts b/src/client/ClientGame.ts index 508cb288d..0eab10379 100644 --- a/src/client/ClientGame.ts +++ b/src/client/ClientGame.ts @@ -76,7 +76,9 @@ export class ClientGame { const message: ServerMessage = ServerMessageSchema.parse(JSON.parse(event.data)) if (message.type == "start") { console.log("starting game!") - this.start() + if (!this.isActive) { + this.start() + } } if (message.type == "turn") { this.addTurn(message.turn) @@ -88,14 +90,15 @@ export class ClientGame { }; this.socket.onclose = (event: CloseEvent) => { console.log(`WebSocket closed. Code: ${event.code}, Reason: ${event.reason}`); - this.join() + if (event.code != 1000) { + this.join() + } }; } public start() { this.isActive = true - console.log('starting game!') // TODO: make each class do this, or maybe have client intercept all requests? //this.eventBus.on(TickEvent, (e) => this.tick(e)) this.eventBus.on(TileEvent, (e) => this.renderer.tileUpdate(e)) diff --git a/src/server/GameManager.ts b/src/server/GameManager.ts index 29cb320a8..3cd8d5adb 100644 --- a/src/server/GameManager.ts +++ b/src/server/GameManager.ts @@ -38,7 +38,6 @@ export class GameManager { if (now > this.lastNewLobby + this.config.gameCreationRate()) { this.lastNewLobby = now const id = this.random.nextID() - console.log(`creating game ${id}`) lobbies.push(new GameServer(id, now, this.config)) } diff --git a/src/server/GameServer.ts b/src/server/GameServer.ts index 920951a3b..ad12bb41d 100644 --- a/src/server/GameServer.ts +++ b/src/server/GameServer.ts @@ -1,6 +1,8 @@ import {ClientMessage, ClientMessageSchema, Intent, ServerStartGameMessage, ServerStartGameMessageSchema, ServerTurnMessageSchema, Turn} from "../core/Schemas"; import {Config} from "../core/configuration/Config"; import {Client} from "./Client"; +import WebSocket from 'ws'; + export enum GamePhase { Lobby = 'LOBBY', @@ -18,6 +20,8 @@ export class GameServer { private clients: Client[] = [] private _hasStarted = false + private endTurnIntervalID + constructor( public readonly id: string, public readonly createdAt: number, @@ -39,32 +43,34 @@ export class GameServer { } } }) + + // In case a client joined the game late and missed the start message. + if (this._hasStarted) { + this.sendStartGameMsg(client.ws) + } } public start() { this._hasStarted = true - const startGame = JSON.stringify(ServerStartGameMessageSchema.parse( - { - type: "start" - } - )) this.clients.forEach(c => { console.log(`game ${this.id} sending start message to ${c.id}`) - c.ws.send(startGame) + this.sendStartGameMsg(c.ws) }) - setInterval(() => this.endTurn(), this.settings.turnIntervalMs()); - - // setInterval(() => { - // this.clients.forEach(c => { - // c.ws.close(1011, 'Intentional error for testing'); - // }) - // }, 1000) + this.endTurnIntervalID = setInterval(() => this.endTurn(), this.settings.turnIntervalMs()); } private addIntent(intent: Intent) { this.intents.push(intent) } + private sendStartGameMsg(ws: WebSocket) { + ws.send(JSON.stringify(ServerStartGameMessageSchema.parse( + { + type: "start" + } + ))) + } + private endTurn() { const pastTurn: Turn = { turnNumber: this.turns.length, @@ -88,6 +94,7 @@ export class GameServer { endGame() { // Close all WebSocket connections + clearInterval(this.endTurnIntervalID); this.clients.forEach(client => { client.ws.removeAllListeners('message'); if (client.ws.readyState === WebSocket.OPEN) {