Files
fuesse-sexy/server/modeStore.js
Guido ecdbd2ee0d Treffer-Toleranz, 2 Ranglisten, Anti-Cheat, CLI-Modi & Icons
- Treffer-Toleranz: Ziel wird geometrisch + bevorzugt getroffen, auch wenn verdeckt
- Zwei Ranglisten: Hall of Fame (Allzeit-Top-5) + Heute (Top-10)
- Anti-Cheat: server-autoritative Sessions (start/hit), Score = Server-Zahl,
  Mindestabstand gegen Auto-Klicker, Deckelung nach Spielzeit; Score ohne Session -> 400
- CLI (server/admin.js): list / delete <name> / clear-today / clear-all
- Zwei Betriebsmodi per CLI (live, ohne Neustart): public (/ = Spiel) und
  private (/ gesperrt, Spiel unter geheimem /pfad) + "not allowed to play"-Seite
- Board-Icons von Emojis auf echte SVG-Icons, Board heisst "Hall of Fame"

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 11:23:30 +02:00

44 lines
1.4 KiB
JavaScript

// Betriebsmodus des Spiels, per CLI umschaltbar, persistent in data/mode.json.
// public -> "/" ist das Spiel (Default)
// private -> "/" zeigt "nicht erlaubt", Spiel nur unter "/<path>" erreichbar (zum Testen)
// Wird pro Request frisch gelesen -> CLI-Umschaltung wirkt SOFORT, ohne Serverneustart.
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 MODE_FILE = join(DATA_DIR, 'mode.json');
const DEFAULT = { mode: 'public', path: 'play' };
function sanitizeSlug(slug) {
const s = String(slug || '').trim().replace(/^\/+/, '').replace(/[^a-zA-Z0-9_-]/g, '');
return s || 'play';
}
export function getMode() {
try {
if (!existsSync(MODE_FILE)) return { ...DEFAULT };
const data = JSON.parse(readFileSync(MODE_FILE, 'utf8'));
return {
mode: data.mode === 'private' ? 'private' : 'public',
path: sanitizeSlug(data.path),
};
} catch {
return { ...DEFAULT };
}
}
export function setMode(mode, path) {
if (!existsSync(DATA_DIR)) mkdirSync(DATA_DIR, { recursive: true });
const current = getMode();
const next = {
mode: mode === 'private' ? 'private' : 'public',
path: sanitizeSlug(path || current.path),
};
writeFileSync(MODE_FILE, JSON.stringify(next, null, 2));
return next;
}