- Objekt-Anzahl waechst ab STEP_START zusaetzlich schrittweise (Deckel 100), Mindestgroesse leicht gesenkt fuer dichte Felder - Ban per CLI: ban/unban/bans (namensbasiert), gebannte Namen koennen keinen Score eintragen (/api/score -> 403) und werden beim Bannen aus der Rangliste entfernt - Privat-Modus bricht laufende Spiele ab: Client pollt /api/status und laedt neu, sobald Spielen auf dem Pfad nicht mehr erlaubt ist (geheimer Pfad wird nicht verraten) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
52 lines
1.5 KiB
JavaScript
52 lines
1.5 KiB
JavaScript
// Namensbasierte Sperrliste, persistent in data/bans.json.
|
|
// Ein gebannter Name kann keinen Score mehr eintragen (siehe /api/score) und seine
|
|
// bestehenden Eintraege werden beim Bannen entfernt. Vergleich case-insensitiv.
|
|
|
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
import { dirname, join } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
const DATA_DIR = join(__dirname, '..', 'data');
|
|
const BANS_FILE = join(DATA_DIR, 'bans.json');
|
|
|
|
const norm = (name) => String(name || '').trim().toLowerCase();
|
|
|
|
export function readBans() {
|
|
try {
|
|
if (!existsSync(BANS_FILE)) return [];
|
|
const data = JSON.parse(readFileSync(BANS_FILE, 'utf8'));
|
|
return Array.isArray(data) ? data : [];
|
|
} catch {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
function writeBans(list) {
|
|
if (!existsSync(DATA_DIR)) mkdirSync(DATA_DIR, { recursive: true });
|
|
writeFileSync(BANS_FILE, JSON.stringify(list, null, 2));
|
|
}
|
|
|
|
export function isBanned(name) {
|
|
return readBans().includes(norm(name));
|
|
}
|
|
|
|
export function banPlayer(name) {
|
|
const n = norm(name);
|
|
if (!n) return false;
|
|
const bans = readBans();
|
|
if (bans.includes(n)) return false; // schon gebannt
|
|
bans.push(n);
|
|
writeBans(bans);
|
|
return true;
|
|
}
|
|
|
|
export function unbanPlayer(name) {
|
|
const n = norm(name);
|
|
const bans = readBans();
|
|
const kept = bans.filter((b) => b !== n);
|
|
if (kept.length === bans.length) return false; // war nicht gebannt
|
|
writeBans(kept);
|
|
return true;
|
|
}
|