import fs from "fs"; import path from "path"; import { CharacterMap, Character, ClassKey, Nation, AccountMap, AccountData } from "../types"; const CHARS_PATH = path.join(__dirname, "../../data/characters.json"); const ACCOUNTS_PATH = path.join(__dirname, "../../data/accounts.json"); let _chars: CharacterMap = {}; let _accounts: AccountMap = {}; export function loadCharacters(): void { try { _chars = JSON.parse(fs.readFileSync(CHARS_PATH, "utf8")); } catch { _chars = {}; } try { _accounts = JSON.parse(fs.readFileSync(ACCOUNTS_PATH, "utf8")); } catch { _accounts = {}; } } function saveCharacters(): void { fs.writeFileSync(CHARS_PATH, JSON.stringify(_chars, null, 2)); } function saveAccounts(): void { fs.writeFileSync(ACCOUNTS_PATH, JSON.stringify(_accounts, null, 2)); } export function getCharacters(usermapKey: string): Character[] { return _chars[usermapKey]?.characters ?? []; } export function getActiveCharacter(usermapKey: string): Character | null { return getCharacters(usermapKey).find((c) => c.active) ?? null; } export function getCharacterByName(usermapKey: string, name: string): Character | null { return getCharacters(usermapKey).find((c) => c.name.toLowerCase() === name.toLowerCase()) ?? null; } export function getCharacterByClass(usermapKey: string, cls: ClassKey): Character | null { // Returns the active character of that class, or first found const chars = getCharacters(usermapKey).filter((c) => c.class === cls); return chars.find((c) => c.active) ?? chars[0] ?? null; } export function addCharacter(usermapKey: string, char: Omit): boolean { if (!_chars[usermapKey]) _chars[usermapKey] = { characters: [] }; const exists = _chars[usermapKey].characters.some((c) => c.name.toLowerCase() === char.name.toLowerCase()); if (exists) return false; // If no active character, set this one as active const hasActive = _chars[usermapKey].characters.some((c) => c.active); _chars[usermapKey].characters.push({ ...char, active: !hasActive }); saveCharacters(); return true; } export function removeCharacter(usermapKey: string, name: string): boolean { if (!_chars[usermapKey]) return false; const before = _chars[usermapKey].characters.length; _chars[usermapKey].characters = _chars[usermapKey].characters.filter( (c) => c.name.toLowerCase() !== name.toLowerCase() ); if (_chars[usermapKey].characters.length === before) return false; // If we removed the active one, set the first remaining as active if (!_chars[usermapKey].characters.some((c) => c.active) && _chars[usermapKey].characters.length > 0) { _chars[usermapKey].characters[0].active = true; } saveCharacters(); return true; } export function setActiveCharacter(usermapKey: string, name: string): boolean { const chars = _chars[usermapKey]?.characters; if (!chars) return false; const target = chars.find((c) => c.name.toLowerCase() === name.toLowerCase()); if (!target) return false; chars.forEach((c) => (c.active = false)); target.active = true; saveCharacters(); return true; } export function setCharacterNation(usermapKey: string, name: string, nation: Nation): boolean { const char = getCharacterByName(usermapKey, name); if (!char) return false; char.nation = nation; saveCharacters(); return true; } export function setCharacterStats( usermapKey: string, name: string, stats: { atk?: number; def?: number; heal?: number } ): boolean { const char = getCharacterByName(usermapKey, name); if (!char) return false; if (!char.stats) char.stats = {}; Object.assign(char.stats, stats); saveCharacters(); return true; } // ─── Account data ───────────────────────────────────────────────────────────── export function getAccountData(usermapKey: string): AccountData { return _accounts[usermapKey] ?? {}; } export function setAccountData(usermapKey: string, data: Partial): void { if (!_accounts[usermapKey]) _accounts[usermapKey] = {}; Object.assign(_accounts[usermapKey], data); saveAccounts(); }