diff --git a/src/core/configuration/DefaultConfig.ts b/src/core/configuration/DefaultConfig.ts index d1139198f..b63d980d5 100644 --- a/src/core/configuration/DefaultConfig.ts +++ b/src/core/configuration/DefaultConfig.ts @@ -832,12 +832,13 @@ export class DefaultConfig implements Config { if (nukeType !== UnitType.MIRVWarhead) { return (5 * humans) / Math.max(1, tilesOwned); } - - const targetPop = 0.05 * maxPop; + const targetPop = 0.03 * maxPop; const excessPop = Math.max(0, humans - targetPop); - const scalingFactor = 20000; + const scalingFactor = 500; - return (scalingFactor * excessPop * excessPop) / (maxPop * maxPop); + const steepness = 2; + const normalizedExcess = excessPop / maxPop; + return scalingFactor * (1 - Math.exp(-steepness * normalizedExcess)); } structureMinDist(): number { diff --git a/src/core/execution/TransportShipExecution.ts b/src/core/execution/TransportShipExecution.ts index 3681dbaae..543dac9ea 100644 --- a/src/core/execution/TransportShipExecution.ts +++ b/src/core/execution/TransportShipExecution.ts @@ -64,7 +64,7 @@ export class TransportShipExecution implements Execution { this.lastMove = ticks; this.mg = mg; - this.pathFinder = PathFinder.Mini(mg, 10_000, true, 10); + this.pathFinder = PathFinder.Mini(mg, 10_000, true, 100); if ( this.attacker.unitCount(UnitType.TransportShip) >= diff --git a/src/core/execution/WarshipExecution.ts b/src/core/execution/WarshipExecution.ts index d11e97c57..f573a8a47 100644 --- a/src/core/execution/WarshipExecution.ts +++ b/src/core/execution/WarshipExecution.ts @@ -27,7 +27,7 @@ export class WarshipExecution implements Execution { init(mg: Game, ticks: number): void { this.mg = mg; - this.pathfinder = PathFinder.Mini(mg, 5000); + this.pathfinder = PathFinder.Mini(mg, 10_000, true, 100); this.random = new PseudoRandom(mg.ticks()); if (isUnit(this.input)) { this.warship = this.input; diff --git a/src/core/game/TransportShipUtils.ts b/src/core/game/TransportShipUtils.ts index d9ec739ad..b457ad94a 100644 --- a/src/core/game/TransportShipUtils.ts +++ b/src/core/game/TransportShipUtils.ts @@ -148,7 +148,7 @@ export function bestShoreDeploymentSource( if (t === null) return false; const candidates = candidateShoreTiles(gm, player, t); - const aStar = new MiniAStar(gm, gm.miniMap(), candidates, t, 500_000, 1); + const aStar = new MiniAStar(gm, gm.miniMap(), candidates, t, 1_000_000, 1); const result = aStar.compute(); if (result !== PathFindResultType.Completed) { console.warn(`bestShoreDeploymentSource: path not found: ${result}`); diff --git a/src/server/GameServer.ts b/src/server/GameServer.ts index 73d44195c..42524faee 100644 --- a/src/server/GameServer.ts +++ b/src/server/GameServer.ts @@ -176,7 +176,6 @@ export class GameServer { client.isDisconnected = existing.isDisconnected; client.lastPing = existing.lastPing; - existing.ws.removeAllListeners(); this.activeClients = this.activeClients.filter((c) => c !== existing); } @@ -186,7 +185,7 @@ export class GameServer { this.allClients.set(client.clientID, client); - client.ws.removeAllListeners(); + client.ws.removeAllListeners("message"); client.ws.on( "message", gatekeeper.wsHandler(client.ip, async (message: string) => { @@ -205,7 +204,6 @@ export class GameServer { } satisfies ServerErrorMessage), ); client.ws.close(1002, "ClientMessageSchema"); - client.ws.removeAllListeners(); return; } const clientMsg = parsed.data; @@ -263,7 +261,6 @@ export class GameServer { }); client.ws.on("error", (error: Error) => { if ((error as any).code === "WS_ERR_UNEXPECTED_RSV_1") { - client.ws.removeAllListeners(); client.ws.close(1002, "WS_ERR_UNEXPECTED_RSV_1"); } }); @@ -405,7 +402,6 @@ export class GameServer { // Close all WebSocket connections clearInterval(this.endTurnIntervalID); this.websockets.forEach((ws) => { - ws.removeAllListeners(); if (ws.readyState === WebSocket.OPEN) { ws.close(1000, "game has ended"); } @@ -463,7 +459,6 @@ export class GameServer { }); if (client.ws.readyState === WebSocket.OPEN) { client.ws.close(1000, "no heartbeats received, closing connection"); - client.ws.removeAllListeners(); } } else { alive.push(client); @@ -558,7 +553,6 @@ export class GameServer { this.activeClients = this.activeClients.filter( (c) => c.clientID !== clientID, ); - client.ws.removeAllListeners(); this.kickedClients.add(clientID); } else { this.log.warn(`cannot kick client, not found in game`, { diff --git a/src/server/Worker.ts b/src/server/Worker.ts index 96efde652..bad56d0a5 100644 --- a/src/server/Worker.ts +++ b/src/server/Worker.ts @@ -316,7 +316,6 @@ export function startWorker() { error: error.toString(), } satisfies ServerErrorMessage), ); - ws.removeAllListeners(); ws.close(1002, "ClientJoinMessageSchema"); return; } @@ -334,7 +333,6 @@ export function startWorker() { error, } satisfies ServerErrorMessage), ); - ws.removeAllListeners(); ws.close(1002, "ClientJoinMessageSchema"); return; } @@ -352,7 +350,6 @@ export function startWorker() { const result = await verifyClientToken(clientMsg.token, config); if (result === false) { log.warn("Unauthorized: Invalid token"); - ws.removeAllListeners(); ws.close(1002, "Unauthorized"); return; } @@ -365,7 +362,6 @@ export function startWorker() { if (claims === null) { if (allowedFlares !== undefined) { log.warn("Unauthorized: Anonymous user attempted to join game"); - ws.removeAllListeners(); ws.close(1002, "Unauthorized"); return; } @@ -374,7 +370,6 @@ export function startWorker() { const result = await getUserMe(clientMsg.token, config); if (result === false) { log.warn("Unauthorized: Invalid session"); - ws.removeAllListeners(); ws.close(1002, "Unauthorized"); return; } @@ -389,7 +384,6 @@ export function startWorker() { log.warn( "Forbidden: player without an allowed flare attempted to join game", ); - ws.removeAllListeners(); ws.close(1002, "Forbidden"); return; } @@ -406,7 +400,6 @@ export function startWorker() { ); if (allowed !== true) { log.warn(`Custom flag ${allowed}: ${clientMsg.flag}`); - ws.removeAllListeners(); ws.close(1002, `Custom flag ${allowed}`); return; } @@ -422,7 +415,6 @@ export function startWorker() { ); if (allowed !== true) { log.warn(`Pattern ${allowed}: ${clientMsg.pattern}`); - ws.removeAllListeners(); ws.close(1002, `Pattern ${allowed}`); return; } @@ -457,7 +449,6 @@ export function startWorker() { // Handle other message types } catch (error) { - ws.removeAllListeners(); ws.close(1011, "Internal server error"); log.warn( `error handling websocket message for ${ipAnonymize(ip)}: ${error}`.substring( @@ -470,7 +461,6 @@ export function startWorker() { ); ws.on("error", (error: Error) => { - ws.removeAllListeners(); if ((error as any).code === "WS_ERR_UNEXPECTED_RSV_1") { ws.close(1002, "WS_ERR_UNEXPECTED_RSV_1"); }