import { TGScore, Nation, ClassKey } from "../types"; import { cfg } from "./config"; import { upsertScore, todayString } from "./history"; import { recordScore } from "./wrank"; // Normalize a slot string to a 24h integer hour // Accepts: "20", "8", "8pm", "20:00", "midnight", "midday", "noon" export function normalizeSlot(input: string): number | null { const s = input.trim().toLowerCase(); if (s === "midnight") return 0; if (s === "midday" || s === "noon") return 12; const pmMatch = s.match(/^(\d{1,2})pm$/); if (pmMatch) { const h = parseInt(pmMatch[1]); return h === 12 ? 12 : h + 12; } const amMatch = s.match(/^(\d{1,2})am$/); if (amMatch) { const h = parseInt(amMatch[1]); return h === 12 ? 0 : h; } const colonMatch = s.match(/^(\d{1,2}):\d{2}$/); if (colonMatch) return parseInt(colonMatch[1]); const numMatch = s.match(/^(\d{1,2})$/); if (numMatch) return parseInt(numMatch[1]); return null; } // Detect which slot a submission belongs to based on current time export function detectSlot(): number | null { const slots = cfg("slots").filter((s) => s.active); const windowMs = cfg("scoreWindowHours") * 60 * 60 * 1000; const durationMs = cfg("tgDurationMinutes") * 60 * 1000; const now = Date.now(); for (const slot of slots) { const today = new Date(); const tgTime = new Date(today); tgTime.setHours(slot.tgHour, 0, 0, 0); const closeTime = tgTime.getTime() + durationMs; const windowEnd = closeTime + windowMs; if (now >= closeTime && now <= windowEnd) { return slot.tgHour; } } return null; } export interface ScoreSubmission { usermapKey: string; characterName: string; cls: ClassKey; nation: Nation; pts: number; slot: number; date?: string; atk?: number; def?: number; heal?: number; submittedByOfficer: boolean; } export function submitScore(sub: ScoreSubmission): void { const date = sub.date ?? todayString(); const historyKey = `${date}-${String(sub.slot).padStart(2, "0")}`; const score: TGScore = { usermapKey: sub.usermapKey, characterName: sub.characterName, class: sub.cls, nation: sub.nation, pts: sub.pts, atk: sub.atk, def: sub.def, heal: sub.heal, submittedAt: new Date().toISOString(), slot: sub.slot, date, submittedByOfficer: sub.submittedByOfficer, }; upsertScore(score); recordScore(sub.usermapKey, sub.characterName, sub.cls, sub.nation, sub.pts, historyKey); }