Der Mitschnitt von 12:33 hat es benannt:
Netzteil: Websocket auf -> Anmeldung -> zu -> Websocket zu (4017) -> zu
4017 heisst DAVE. Discord erzwingt seit dem 01.03.2026 Ende-zu-Ende-
Verschluesselung in allen Nicht-Stage-Sprachkanaelen und weist Gegenstellen,
die das nicht koennen, sofort nach der Anmeldung ab -- lange bevor irgendein
UDP-Paket fliegt. Nachgeschlagen bei Discord, nicht gedeutet.
Gemessen, warum es uns traf: @discordjs/voice 0.18.0 kennt DAVE ueberhaupt
nicht (null Fundstellen im Bundle) und spricht Sprach-Gateway v4. Es meldet
deshalb max_dave_protocol_version: 0. 0.19.2 spricht v8, bringt
@snazzah/davey als feste Abhaengigkeit mit und hat 48 Fundstellen.
Also hochgezogen. Im gebauten Abbild gegengeprueft, weil das native Modul
plattformabhaengig ist und der Lock auf Windows entstanden ist:
DAVE Libraries
- @snazzah/davey: 0.1.12
@snazzah/davey-linux-x64-gnu steht im Lock, node:22-slim ist Debian/glibc,
das Modul laedt im Abbild. engines steht jetzt auf >=22.12.0 -- das verlangt
0.19.2, und ">=20" waere ab jetzt gelogen.
Und ein Fehler in der frischen Diagnose selbst, den erst der Ernstfall zeigte:
sie hat den Schritt nicht benannt, obwohl der Mitschnitt ihn enthielt. Das
Netzteil schliesst sich erst und meldet dann den Code, also endet jeder
Mitschnitt auf "zu" -- und genau den nahm die Auswertung als letzten Schritt.
Damit lief alles in "Ursache offen". Jetzt wird "zu" uebersprungen; die
Gegenprobe mit 4009 landet wieder beim UDP-Handschlag statt im Nichts.
Nebenbei stand "zu" zweimal im Mitschnitt, einmal vor und einmal nach dem
Schliesscode: die Entdopplung verglich mit dem letzten Eintrag statt mit dem
letzten Schritt.
Der Weg hierher gehoert zur Sache: erst hiess es "ausgehendes UDP dicht" --
geraten. Dann wurde gemessen, dass UDP rauskommt, und die Meldung sagte
ehrlich "Ursache offen". Diese eine ehrliche Meldung hat den Schliesscode
sichtbar gemacht, und der war die Antwort. Eine Pruefung, die nichts sehen
kann, meldet nicht "sauber" und auch nicht "UDP".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
/radio holt den Bot in den Sprachkanal und postet eine Tafel: Auswahlmenue
mit allen Sendern, Stopp, und ein Embed mit dem laufenden Titel, das sich
alle 30 Sekunden selbst nachfuehrt.
Der Titel kommt aus dem Icecast-Strom selbst (Icy-MetaData). Bewusst so und
nicht ueber eine Sender-API: das funktioniert bei jedem Strom, den jemand
eintraegt, und nicht nur bei den drei, die ich kenne. Leere Titel-Bloecke
heissen "unveraendert", deshalb werden bis zu drei gelesen.
Die Tonkette braucht keine Opus-Bibliothek: ffmpeg holt das MP3 und gibt
direkt Ogg/Opus aus, prism-media packt nur noch aus. Gemessen: 600 Pakete in
fuenf Sekunden. Sonst muesste @discordjs/opus mit ins Image, und das will
gebaut werden. Neu im Image ist nur ffmpeg.
44 RauteMusik-Sender sind ab Werk eingetragen — dieselben, die im LS25 und
ETS als Bordradio laufen. Die Liste ist nicht abgeschrieben, sondern
gemessen: jede Adresse einzeln angefragt, der Name kommt aus icy-name.
Doppelgaenger sind raus (deutschrap-charts und wackenradio liefern denselben
Strom wie deutschrap und metal). Eingetragen wird einmal, solange die Liste
leer ist — wer loescht, behaelt es geloescht.
Ein Auswahlmenue fasst nur 25 Eintraege. Bei 44 Sendern haette ein Deckel
die letzten 19 stillschweigend verschluckt; stattdessen mehrere Menues,
benannt nach ihrem ersten und letzten Sender.
Der Bot geht raus, wenn der Kanal leer ist, und kommt nach einem Neustart in
den Kanal zurueck — sonst beendet jeder Deploy die Musik endgueltig.
Kein YouTube. Genau daran sind Groovy und Rythm gestorben, und was davon
uebrig ist, ist ein Dauerlauf gegen kaputte Extraktoren.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Willkommens-Karten: gerendertes PNG (SVG → sharp) mit Avatar im
Neon-Ring, Willkommens-Schriftzug und Member-Nummer; Fallback aufs
bisherige Embed wenn das Rendering scheitert; Dockerfile installiert
fonts-dejavu-core für die Text-Darstellung
- Geburtstags-System: /geburtstag setzen|entfernen (birthdays-Tabelle),
tägliche Runde ab 09:00 Europe/Berlin (Doppel-Post-Schutz über
last_birthday_run), Gratulations-Embed + Tages-Rolle (wird am
nächsten Morgen wieder abgeräumt); Kanal + Rolle im Community-Tab
- Devlog-Permalinks: /devlogs/:id als eigene Seite (GET /api/devlogs/:id),
Link-Symbol an jeder Karte, Link-kopieren-Button; der Server injiziert
Open-Graph-Tags ins SPA-HTML — Devlog-Links zeigen Titel, Anriss und
Bild, alle anderen Seiten bekommen Default-Tags (auch die Startseite)
- Auto-Publish: maybeCrosspost() veröffentlicht Devlog-, Release-,
Composer- und geplante Posts automatisch in Ankündigungs-Kanälen
- brandEmbed: leere Avatar-URL crasht nicht mehr die Footer-Validierung
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- POST /webhooks/devlog/<secret> — Discord-Webhook-kompatibel (JSON + Multipart),
devlog.py braucht nur die neue URL in tools/.devlog_webhook
- Bot postet Embed in Brand-Gelb mit 'D4RKST3R // DEVLOG'-Footer, bis zu 4 Bilder
als Grid (Embed-Gruppierung über gemeinsame URL)
- Direkt-Archivierung inkl. Bilder (kein Umweg über den Live-Listener)
- Neue Env-Var DEVLOG_POST_SECRET, README-Abschnitt neu geschrieben
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Discord-OAuth2-Login (identify-Scope, CSRF-State, signierte Session-Cookies, keine Token-Speicherung)
- REST-API: /api/devlogs (öffentlich), /api/commits (nur ADMIN_DISCORD_ID), /api/me
- React + Vite Frontend: Devlog-Archiv mit Mini-Markdown-Renderer, Commit-Tabelle, dunkles EcoGame-Theme
- Fastify liefert frontend/dist mit SPA-Fallback aus; Vite-Dev-Proxy für lokale Entwicklung
- Multi-Stage-Dockerfile (Frontend-Build im Image), neue Env-Vars in Compose + .env.example
- README: OAuth2-Setup (Redirect-URLs, Client Secret) und Frontend-Workflow
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Fastify-Webserver mit /health und /webhooks/gitea (HMAC-SHA256-Signaturprüfung, timing-safe)
- Push-Commits werden in SQLite gespeichert (Dedupe per SHA) und als Embed gepostet
- Dockerfile auf node:22-slim (glibc-Prebuilds für better-sqlite3), Port 3080 published
- README: Anleitung für Cloudflare-DNS, Nginx Proxy Manager (bot.d4rkst3r.de) und Gitea-Webhook
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- discord.js v14 Bot mit Slash-Command-Registry (Guild oder global)
- Konfiguration über .env mit Validierung (config.js)
- Dockerfile + docker-compose.yml für Portainer-Deployment
- README mit Schritt-für-Schritt-Anleitung (Discord Developer Portal)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>