# fuesse.sexy — „Wanted!" 🦶 Ein kleines Arcade-Spiel nach dem Vorbild des **„Wanted!"-Minispiels aus New Super Mario Bros.**: Oben ein Fahndungsplakat mit *einem* gesuchten Fuß, unten wuseln viele Füße (in verschiedenen Farben) + etwas Deko herum. **Schnapp dir den gesuchten Fuß, bevor die Zeit abläuft** — dann kommt sofort ein neues Plakat mit einer anderen Farbe. - **Zeitdruck:** Countdown; jeder Treffer gibt Zeit dazu, Fehlklick zieht Zeit ab. Bei 0 → Game-Over. - **Wird schwerer:** erst ordentliches **Raster**, dann **wild verteilt**, dann **Bewegung** (erst in 2–3 Gruppen, später einzeln) — und je weiter, desto **schneller** und **mehr** Füße. - **Gesucht ist immer ein Fuß, aber die Farbe wechselt jede Runde** — nicht auf Autopilot klicken! - **Rangliste:** die Top 10 auf der Startseite, serverseitig gespeichert. Nach dem Spiel wird **einmal** nach dem Namen gefragt (danach gecacht). ## Installation ```sh ./install.sh ``` Das Skript installiert alles Nötige, startet den Server **im Hintergrund** und zeigt die URL. Dann im Browser öffnen: **http://:3000** (lokal: http://localhost:3000). Manuell: `npm install && npm start`. ## Die Füße & Deko erweitern Alle Bildchen liegen in `library/`: ``` library/ feet/ ← die Füße (= die gesuchten Figuren). Farbe = Dateiname. props/ ← Deko ("andere Bildchen") als Zusatz-Ablenker. ``` Neue Bildchen einfach in den passenden Ordner legen und **Server neu starten** — fertig. Formate: `.svg`, `.png`, `.webp`, `.jpg`. Für Füße gilt: **mind. 2** in `library/feet/` (mehr = mehr Farb-Vielfalt). Am besten freigestellt (transparenter Hintergrund), grob quadratisch. ### Woher Bildchen nehmen? openclipart.org (CC0), svgrepo.com (CC0-Filter), kenney.nl (CC0), pixabay.com. Bei Flaticon/Freepik Namensnennung beachten. ## Feintuning In `public/js/app.js` oben: - `START_TIME`, `MAX_TIME`, `BONUS`, `PENALTY` — Timer/Balance. - `difficulty(score)` — Anzahl, Bewegungs-Stufen (`grid`/`scatter`/`groups`/`individual`) und Tempo je Score. ## Rangliste - Zwei Boards: **Hall of Fame** (Allzeit-Top-5) + **Heute** (Top-10). Gespeichert in `data/leaderboard.json` (wird automatisch angelegt, überlebt Neustarts). - **Anti-Cheat:** **server-autoritative Runden.** Der Server bestimmt pro Runde das Ziel und alle Items (mit zufälligen IDs) und validiert jeden Treffer gegen die Ziel-ID der *aktuellen* Runde (`/api/game/hit` mit `nonce` + `itemId`). Blindes „Treffer-Spam" bringt dadurch nichts mehr; zusätzlich Reaktionszeit-Untergrenze, Mindestabstand und Deckelung nach echter Spielzeit. Beim Eintragen (`/api/score`) zählt **nur** die server-gezählte Trefferzahl. Namen werden beim Anzeigen escaped (kein XSS). > Hinweis: In einem Browserspiel bekommt der Client zwangsläufig die Renderdaten — > ein eigens gebauter Solver-Bot bleibt theoretisch möglich, 100 % dicht geht nicht. ## Verwaltung per CLI Auf dem Server (im Projektordner): ```sh # Rangliste node server/admin.js list # beide Boards anzeigen node server/admin.js delete "Name" # einen bestimmten Spieler löschen node server/admin.js clear-today # nur die heutige Rangliste leeren node server/admin.js clear-all # komplette Rangliste leeren # Bannen (namensbasiert, case-insensitiv) node server/admin.js ban "Name" # sperren (+ vorhandene Einträge entfernen) node server/admin.js unban "Name" # Sperre aufheben node server/admin.js bans # gebannte Namen anzeigen # Betriebsmodus (wirkt SOFORT, ohne Neustart) node server/admin.js mode # aktuellen Modus anzeigen node server/admin.js mode public # Spiel öffentlich unter "/" node server/admin.js mode private geheim # "/" gesperrt, Spiel nur unter "/geheim" # Admin-Panel-Passwort node server/admin.js password # Passwort anzeigen (Login unter /admin) node server/admin.js password reset # neues Passwort erzeugen ``` (Kurzform via npm: `npm run lb -- `.) - **public** (Default): `/` ist das Spiel. - **private**: `/` zeigt „You are not allowed to play", das Spiel läuft nur unter dem gewählten Pfad (`/`) — praktisch zum Testen im Live-Betrieb. ## Admin-Panel (`/admin`) Passwortgeschütztes Web-Panel. Passwort wird beim ersten Start automatisch generiert (20 Zeichen) und liegt in `data/admin.json` — anzeigen mit `node server/admin.js password`. Funktionen: - **Spieler**: approximative Zuordnung (IP, grober Ort via `geoip-lite` offline, Gerät, Browser) aus den Spiel-Logs; einzelne Spieler direkt **bannen/entbannen**. - **Einstellungen**: Timer (Start/Max/Bonus/Strafe) **und** Schwierigkeitskurve (Objekt-Anzahl, Stufen, Tempo) **live** einstellen — wirkt sofort beim nächsten Spielstart. - **Bilder**: Füße & Deko **hochladen/löschen** (kein Neustart). Empfehlung: **quadratische** Bilder, 256×256 oder 512×512 PNG (transparent) bzw. SVG mit quadratischem `viewBox`; nicht-quadratische werden per `object-fit: contain` eingepasst statt verzerrt. - **Rangliste**: heute/alles zurücksetzen. > Datenschutz: IP + grober Ort + Gerät/Browser sind personenbezogen (nur für Moderation). > Für den öffentlichen Betrieb einen kurzen Datenschutz-Hinweis ergänzen. ## Deployment (Ausblick) Normaler Node-Server. Auf einen Node-Host bringen (VPS/LXC/Railway/Render), `./install.sh`, Domain **fuesse.sexy** per Reverse-Proxy (z.B. Nginx Proxy Manager) darauf zeigen. Für HTTPS hinter Cloudflare: DNS-Challenge (Cloudflare-Token) im Proxy nutzen. ## Projektstruktur ``` server/index.js schlanker Express-Server (Bildchen-Liste + Rangliste) public/ Frontend (Startseite, Spiel, Game-Over) — Vanilla JS library/feet/ die Füße (gesuchte Figuren) library/props/ Deko-Ablenker data/ Rangliste (leaderboard.json, zur Laufzeit) install.sh Ein-Befehl-Setup + detached Start ```