Guido 221cba417f Anti-Cheat: server-autoritative Runden (blindes Treffer-Spam wirkungslos)
Der Server bestimmt pro Runde Ziel + alle Items (mit zufaelligen IDs) und validiert
jeden Treffer gegen die Ziel-ID der aktuellen Runde (nonce + itemId). Blindes Spammen
von /api/game/hit bringt damit 0 Punkte. Zusaetzlich Reaktionszeit-Untergrenze und
Mindestabstand; Score weiterhin nach Spielzeit gedeckelt.

- Server: makeRound() + /api/game/start liefert erste Runde, /api/game/hit erwartet
  {nonce,itemId} und gibt bei korrektem Treffer die naechste Runde zurueck
- Client: rendert server-gelieferte Runden, sendet geklickte itemId, Vorschub nur bei
  Server-Bestaetigung (Sofort-Flash fuers Gefuehl)
- README: Ban-Befehle dokumentiert, Anti-Cheat-Abschnitt aktualisiert

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-05 12:39:19 +02:00
2026-08-04 21:57:13 +02:00
2026-08-04 21:57:13 +02:00
2026-08-04 21:57:13 +02:00

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 23 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

./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):

# 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"

(Kurzform via npm: npm run lb -- <befehl>.)

  • public (Default): / ist das Spiel.
  • private: / zeigt „You are not allowed to play", das Spiel läuft nur unter dem gewählten Pfad (/<pfad>) — praktisch zum Testen im Live-Betrieb.

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
Description
No description provided
Readme 810 KiB
Languages
JavaScript 73.7%
HTML 13%
CSS 9.2%
Shell 4.1%