diff --git a/TODO.txt b/TODO.txt index 76e7665fb..10996c5fe 100644 --- a/TODO.txt +++ b/TODO.txt @@ -239,6 +239,11 @@ * add capture alert DONE 12/13/2024 * better emojis 🏳️🤦‍♂️🖕☮️🫡😡😈🤡 DONE 12/13/2024 * store ips in bigquery table DONE 12/14/2024 +* better error logging in server +* store and archive player cookies +* send client logs back to server +* right click brings up player info menu +* give naval units health * bug: player names not updating sometimes * make player editeable configs * games disconnects on multplayer after some time @@ -246,13 +251,14 @@ * UI/test too big on mobile * bug: build city 25k bump doesn't match troop/worker ratio * bug: mobile: if you don't have enough money can't get rid of build menu -* give naval units health +* highlight player spawn * show players joined username in private lobby * have bots build cities & defense posts * allow longer names and allow them to be displayed in the Rank UI not be cut * make boats work on lakes * record game winner * repaint canvas after tab away to prevent blank screen +* have nation spawn with irl territory * on mobile can't click away from build menu * replay storedgames * record commit hash of game diff --git a/src/core/configuration/DevConfig.ts b/src/core/configuration/DevConfig.ts index f5d47b323..d7ca21282 100644 --- a/src/core/configuration/DevConfig.ts +++ b/src/core/configuration/DevConfig.ts @@ -8,7 +8,7 @@ export const devConfig = new class extends DefaultConfig { unitInfo(type: UnitType): UnitInfo { const info = super.unitInfo(type) const oldCost = info.cost - info.cost = (p: Player) => oldCost(p) / 1000000 + info.cost = (p: Player) => oldCost(p) / 20 return info } diff --git a/src/server/Archive.ts b/src/server/Archive.ts index ebc9f0666..2271d94b7 100644 --- a/src/server/Archive.ts +++ b/src/server/Archive.ts @@ -42,6 +42,6 @@ export async function archive(gameRecord: GameRecord) { }); } } catch (error) { - console.log(`error archiving game record: ${error}`) + console.error(`error archiving game record: ${error}`) } } \ No newline at end of file diff --git a/src/server/GameServer.ts b/src/server/GameServer.ts index b3a11fe47..08259a3fe 100644 --- a/src/server/GameServer.ts +++ b/src/server/GameServer.ts @@ -3,7 +3,6 @@ import { Config } from "../core/configuration/Config"; import { Client } from "./Client"; import WebSocket from 'ws'; import { slog } from "./StructuredLog"; -import { Storage } from '@google-cloud/storage'; import { CreateGameRecord } from "../core/Util"; import { archive } from "./Archive"; import { arc } from "d3"; @@ -51,7 +50,7 @@ export class GameServer { } public addClient(client: Client, lastTurn: number) { - console.log(`game ${this.id} adding client ${client.id}`) + console.log(`${this.id}: adding client ${client.id}`) slog('client_joined_game', `client ${client.id} (re)joining game ${this.id}`, { clientID: client.id, clientIP: client.ip, @@ -75,7 +74,7 @@ export class GameServer { if (clientMsg.gameID == this.id) { this.addIntent(clientMsg.intent) } else { - console.warn(`client ${clientMsg.clientID} sent to wrong game`) + console.warn(`${this.id}: client ${clientMsg.clientID} sent to wrong game`) } } if (clientMsg.type == "ping") { @@ -84,7 +83,7 @@ export class GameServer { } }) client.ws.on('close', () => { - console.log(`client ${client.id} disconnected`) + console.log(`${this.id}: client ${client.id} disconnected`) this.activeClients = this.activeClients.filter(c => c.id != client.id) }) @@ -113,7 +112,7 @@ export class GameServer { this.endTurnIntervalID = setInterval(() => this.endTurn(), this.config.turnIntervalMs()); this.activeClients.forEach(c => { - console.log(`game ${this.id} sending start message to ${c.id}`) + console.log(`${this.id}: sending start message to ${c.id}`) this.sendStartGameMsg(c.ws, 0) }) } @@ -161,7 +160,7 @@ export class GameServer { client.ws.close(1000, "game has ended"); } }); - console.log(`ending game ${this.id} with ${this.turns.length} turns`) + console.log(`${this.id}: ending game ${this.id} with ${this.turns.length} turns`) try { if (this.allClients.size > 0) { const playerRecords: PlayerRecord[] = Array.from(this.allClients.values()).map(client => ({ @@ -171,10 +170,30 @@ export class GameServer { const record = CreateGameRecord(this.id, this.gameConfig, playerRecords, this.turns, this._startTime, Date.now()) archive(record) } else { - console.log(`game ${this.id} no clients joined, not archiving game`) + console.log(`${this.id}: no clients joined, not archiving game`) } } catch (error) { - console.log('error writing game to gcs: ' + error) + let errorDetails; + if (error instanceof Error) { + errorDetails = { + message: error.message, + stack: error.stack + }; + } else if (Array.isArray(error)) { + errorDetails = error; // Now we'll actually see the array contents + } else { + try { + errorDetails = JSON.stringify(error, null, 2); + } catch (e) { + errorDetails = String(error); + } + } + + console.error("Error archiving game record details:", { + gameId: this.id, + errorType: typeof error, + error: errorDetails + }); } } @@ -183,7 +202,7 @@ export class GameServer { const alive = [] for (const client of this.activeClients) { if (now - client.lastPing > 60_000) { - console.log(`no pings from ${client.id}, terminating connection`) + console.log(`${this.id}: no pings from ${client.id}, terminating connection`) if (client.ws.readyState === WebSocket.OPEN) { client.ws.close(1000, "no heartbeats received, closing connection"); } @@ -193,7 +212,7 @@ export class GameServer { } this.activeClients = alive if (now > this.createdAt + this.config.lobbyLifetime() + this.maxGameDuration) { - console.warn(`game past max duration ${this.id}`) + console.warn(`${this.id}: game past max duration ${this.id}`) return GamePhase.Finished } @@ -203,7 +222,7 @@ export class GameServer { if (!this.isPublic) { if (this._hasStarted) { if (noActive && noRecentPings) { - console.log(`private game: ${this.id} complete`) + console.log(`${this.id}: private game: ${this.id} complete`) return GamePhase.Finished } else { return GamePhase.Active @@ -227,4 +246,6 @@ export class GameServer { hasStarted(): boolean { return this._hasStarted } + + } \ No newline at end of file