import "dotenv/config"; import { createServer } from "http"; import { loadConfigFile, getConfig } from "./configLoader.js"; import { initGameSchema, ensureSeedEpoch } from "./db/gameDb.js"; import { initUsersSchema } from "./db/usersDb.js"; import app from "./app.js"; import { startEconTick } from "./econTick.js"; import { initWebSocketHub, broadcast } from "./ws/hub.js"; const PORT = Number(process.env.PORT ?? 8080); let lastConfigSignature = ""; function makeConfigSignature(cfg) { return JSON.stringify({ dailyActionQuota: cfg.dailyActionQuota, teamActionQuota: cfg.teamActionQuota, databaseWipeoutIntervalSeconds: cfg.databaseWipeoutIntervalSeconds, configReloadIntervalSeconds: cfg.configReloadIntervalSeconds, elementWorth: cfg.elementWorth ?? {}, resourceWorth: cfg.resourceWorth ?? { common: {}, rare: {} }, militaryPower: cfg.militaryPower ?? {}, }); } // ── Config-file poll ────────────────────────────────────────────────────────── // Periodically re-reads game.settings.json and checks for a seed-epoch change. function scheduleConfigPoll() { loadConfigFile(); const ms = Math.max(5_000, getConfig().configReloadIntervalSeconds * 1_000); setTimeout(async () => { try { const beforeSig = lastConfigSignature; loadConfigFile(); const worldSeed = await ensureSeedEpoch(); const cfg = getConfig(); const nextSig = makeConfigSignature(cfg); if (beforeSig && nextSig !== beforeSig) { broadcast("config-updated", { worldSeed, config: { dailyActionQuota: cfg.dailyActionQuota, teamActionQuota: cfg.teamActionQuota, databaseWipeoutIntervalSeconds: cfg.databaseWipeoutIntervalSeconds, configReloadIntervalSeconds: cfg.configReloadIntervalSeconds, elementWorth: cfg.elementWorth ?? {}, resourceWorth: cfg.resourceWorth ?? { common: {}, rare: {} }, militaryPower: cfg.militaryPower ?? {}, }, }); } lastConfigSignature = nextSig; } catch (e) { console.error("[config poll]", e.message); } scheduleConfigPoll(); }, ms); } // ── Boot ────────────────────────────────────────────────────────────────────── async function main() { loadConfigFile(); await initGameSchema(); await initUsersSchema(); await ensureSeedEpoch(); lastConfigSignature = makeConfigSignature(getConfig()); const httpServer = createServer(app); initWebSocketHub(httpServer); httpServer.listen(PORT, () => { const cfg = getConfig(); console.log( `[server] Listening on :${PORT} dailyQuota=${cfg.dailyActionQuota} wipe=${cfg.databaseWipeoutIntervalSeconds}s` ); }); scheduleConfigPoll(); startEconTick(); } main().catch((e) => { console.error(e); process.exit(1); });