111 lines
4.1 KiB
TypeScript
111 lines
4.1 KiB
TypeScript
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<Character, "active">): 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<AccountData>): void {
|
|
if (!_accounts[usermapKey]) _accounts[usermapKey] = {};
|
|
Object.assign(_accounts[usermapKey], data);
|
|
saveAccounts();
|
|
}
|