diff --git a/src/server.ts b/src/server.ts index 8082e73..adf006c 100644 --- a/src/server.ts +++ b/src/server.ts @@ -54,6 +54,7 @@ import { GAME_SERVER_PORT } from "./game/udp"; import { sscRouter } from "./ssc/routes"; import { getCurrentCRC, LoadConfig, MATCHMAKING_CRC } from "./data/config"; import { PlayerTester, PlayerTesterModel } from "./database/PlayerTester"; +import { PlayerStatsModel } from "./database/PlayerStats"; import { Types } from "mongoose"; import { RegExpMatcher, TextCensor, englishDataset, englishRecommendedTransformers, asteriskCensorStrategy } from "obscenity"; import env from "./env/env"; @@ -239,6 +240,10 @@ const homeFilePath = path.join(__dirname, "static/home.html"); const homeSource = fs.readFileSync(homeFilePath, "utf8"); const homeTemplate = handlebars.compile(homeSource); +const myStatsFilePath = path.join(__dirname, "static/my_stats.html"); +const myStatsSource = fs.readFileSync(myStatsFilePath, "utf8"); +const myStatsTemplate = handlebars.compile(myStatsSource); + const adminBannerFilePath = path.join(__dirname, "static/admin.html"); const adminBannerSource = fs.readFileSync(adminBannerFilePath, "utf8"); const adminBannerTemplate = handlebars.compile(adminBannerSource); @@ -253,6 +258,47 @@ app.get("/home", async (req, res) => { } }); +// ── /stats — career-stats page for the caller's IP-resolved account ── +// Mirrors the /namechange flow: caller's IP → resolvePlayerForWeb → PlayerStats. +// If multiple accounts at the IP, the account picker is shown. +// Public, no auth. +app.get("/stats", async (req, res) => { + try { + const { player, pickerShown } = await resolvePlayerForWeb(req, res, "/stats"); + if (pickerShown) return; + + if (!player) { + const html = myStatsTemplate({ hasStats: false }); + res.send(html); + return; + } + + const accountId = String((player as any)._id); + const stats = await PlayerStatsModel.findOne({ account_id: accountId }).lean(); + + if (!stats || !stats.aggregate || Object.keys(stats.aggregate).length === 0) { + const html = myStatsTemplate({ hasStats: false, playerName: (player as any).name || "" }); + res.send(html); + return; + } + + // Stringify the aggregate as JSON for the inline + + {{/if}} + +