# Project Map – helldivers ## Files | File | Purpose | |---|---| | `server.js` | Express + WebSocket (ws) + SQLite (better-sqlite3) – Auth, Scores, Matchmaking | | `public/app.js` | Gesamte Client-Logik (WebSocket-Client, Practice/Match/Lobby) | | `public/styles.css` | Alle Styles | | `public/index.html` | App-Shell | | `data/helldivers.db` | SQLite-Datenbank (Scores, Users, Sessions, History) | | `scripts/` | Migrations / Seed-Skripte | --- ## app.js ### State Object ```js state = { user, currentView, stratagems, settings: { timerDuration, difficulty }, practice: { active, mode, current, queue, progress, timeLeft, timerHandle, startTime, score, streak, selectedCats, dailyTarget, lives, // Endless mode drillPool, drillCompleted, drillTotal, // Drill mode speedrunStart, speedrunPool, speedrunElapsed, // Speedrun mode sessionStats: { completed, missed, bestTime, stratagems, mistakes, maxStreak } }, lobby: { online, incoming, pendingChallenge }, match: { roomId, opponent, matchScores, current, myProgress, oppProgress, roundActive, roundHistory }, leaderboard: { activeTab }, history: { page, total }, ws, wsReconnectTimer } ``` ### Constants | Constant | Purpose | |---|---| | `RING_CIRCUMFERENCE` | `219.9` – Kreis-Umfang für Timer-Ring-Canvas (r=35) | | `ELO_RANKS` | Array `{ min, label, color }` – ELO-Rangstufen | | `STRATAGEMS` | Array aller Stratagems mit `name`, `category`, `icon`, `sequence` | ### Key Functions – Settings & Navigation | Function | Purpose | |---|---| | `loadSettings() / saveSettings()` | localStorage-Persistenz für Settings | | `applySettingsToUI()` | Settings auf UI-Elemente anwenden | | `showView(name)` | Ansicht wechseln (login/dashboard/practice/leaderboard/history/admin) | | `connectWS() / wsSend(type, payload)` | WebSocket-Verbindung + Nachrichten senden | | `handleWSMessage({ type, payload })` | Eingehende WS-Nachrichten dispatchen | ### Key Functions – Practice | Function | Purpose | |---|---| | `initPracticeView()` | Practice-View initialisieren | | `getPool()` | Stratagem-Pool nach Filter + Modus aufbauen | | `buildQueue() / renderQueue(queue)` | Warteschlange aufbauen und rendern | | `nextStratagem()` | Nächstes Stratagem anzeigen | | `handlePracticeInput(dir)` | Pfeilrichtung auswerten (Treffer/Fehler) | | `startPracticeTimer() / stopPracticeTimer()` | Timer für Timed-Modus | | `startSpeedrunTimer()` | Timer für Speedrun-Modus | | `renderPracticeStratagem()` | Aktuelles Stratagem + Pfeile rendern | | `renderArrows(containerId, sequence, progress)` | Pfeil-Sequenz rendern | | `updateScoreDisplay() / updateStreakDisplay() / updateLivesDisplay()` | Score-UI | | `openSessionSummary() / closeSessionSummary()` | Sitzungs-Zusammenfassung Modal | ### Key Functions – Lobby & Match | Function | Purpose | |---|---| | `updateLobbyView()` | Online-Nutzer-Liste aktualisieren | | `sendChallenge(target) / acceptChallenge(from) / declineChallenge(from)` | Herausforderungen verwalten | | `openChallengeModal(from, elo) / closeChallengeModal()` | Challenge-Dialog | | `renderMatchRound()` | Aktive Match-Runde rendern | | `handleMatchInput(dir)` | Match-Eingabe auswerten | | `renderRoundResult(winner)` | Rundensieger anzeigen | | `openMatchResultModal({ winner, eloChanges, roundHistory })` | Match-Ergebnis-Modal | ### Key Functions – Admin & History | Function | Purpose | |---|---| | `renderAdminOverview(data)` | Admin-Dashboard: Nutzer, Scores, Aktivität | | `renderAdminUsers(users)` | Nutzertabelle im Admin-Bereich | | `renderAdminActivity(data)` | Aktivitätslog rendern | | `renderHistoryChart(sessions)` | Verlaufs-Diagramm (Canvas) | | `renderHistoryPagination(limit)` | Pagination-Buttons | | `renderDashboard({ stats, rank, elo, ... })` | Haupt-Dashboard-Kacheln | --- ## server.js ### Besonderheiten - **SQLite** (better-sqlite3) statt JSON-Dateien - **WebSocket** (ws-Library) für Multiplayer: Lobby, Challenges, Live-Matches - **ELO-Rating-System** für 1v1-Matches ### Server-Side State | Variable | Purpose | |---|---| | `userSockets` | `Map` – aktive WebSocket-Verbindungen | | `pendingChallenges` | `Map` | | `rooms` | `Map` – aktive Match-Räume | ### API Routes | Route | Purpose | |---|---| | `POST /api/login` | Login (rate-limited) | | `POST /api/logout` | Logout | | `GET /api/me` | Session-Info | | `POST /api/change-password` | Passwort ändern | | `GET /api/users` | Alle Nutzer (Admin) | | `POST /api/users` | Nutzer erstellen (Admin) | | `DELETE /api/users/:username` | Nutzer löschen (Admin) | | `POST /api/users/:username/reset-password` | Temp-Passwort (Admin) | | `PATCH /api/users/:username` | Nutzerdaten ändern (Admin) | | `GET /api/admin/overview` | Admin-Dashboard-Daten | | `GET /api/admin/activity` | Aktivitätslog (Admin) | | `GET /api/dashboard` | Dashboard-Daten (Stats, Rank, ELO, Daily) | | `POST /api/scores/practice` | Practice-Session speichern | | `GET /api/scores/leaderboard` | Gesamt-Leaderboard | | `GET /api/scores/leaderboard/elo` | ELO-Rangliste | | `GET /api/scores/leaderboard/speedrun` | Speedrun-Rangliste | | `GET /api/scores/me` | Eigene Statistiken | | `GET /api/history` | Session-Verlauf (paginiert) | | `GET /api/stats/stratagems` | Stratagem-Trefferquoten | | `GET /api/stratagems` | Stratagem-Liste (für Client-Sync) | ### WebSocket Message Types (Client → Server) `join`, `challenge`, `accept_challenge`, `decline_challenge`, `ready`, `input`, `leave_match` ### WebSocket Message Types (Server → Client) `lobby_update`, `challenge_received`, `challenge_declined`, `match_start`, `round_start`, `round_result`, `match_end`, `opponent_progress`, `error` ## Release Automation - Version source of truth: `package.json` - `scripts/release-sync.cjs`: synchronisiert lokale CSS/JS-Referenzen in HTML-Dateien auf die aktuelle Paketversion - `scripts/release-verify.cjs`: prüft Version-Parameter sowie Pflichtdateien wie `CHANGELOG.md` und `PROJECT_MAP.md` vor Commits - `.githooks/pre-commit`: führt Release-Sync und Verify automatisch aus