Commit Graph
7 Commits
Author SHA1 Message Date
D4rkst3randClaude Opus 5 484f2edc62 Radio: den Schliesscode festhalten, statt UDP zu behaupten
Deploy / check (push) Canceled after 0s
Deploy / deploy (push) Canceled after 0s
Die Meldung "ausgehendes UDP dicht" war geraten. Am 14.08.2026 im laufenden
Container gegengemessen, und sie stimmt nicht:

  UDP raus (DNS)              1.1.1.1:53                 4 ms
  UDP auf hohem Port (STUN)   stun.l.google.com:19302    9 ms
  TCP zum Sprachserver        c-fra13-...discord.media:2096  offen
  Verschluesselung            libsodium-wrappers 0.8.4 geladen

UDP kommt also raus, auch auf hohen Ports und mit Rueckweg durchs NAT. Der
Satz stand trotzdem da, weil "Weg enthaelt connecting" als Beweis genommen
wurde. Ist es nicht: in @discordjs/voice 0.18 faellt die Verbindung bei
*jedem* Websocket-Schluss ausser 4014 stumm nach "signalling" zurueck
(onNetworkingClose) und wirft den Schliesscode dabei weg. Ob der UDP-Teil je
begonnen hat, steht nirgends -- die Pruefung konnte den Unterschied nicht
sehen und hat trotzdem geurteilt.

Jetzt wird das Netzteil selbst mitgeschrieben: seine Schrittnummer
(NetworkingStatusCode, nachgeschlagen -- Websocket auf / Anmeldung /
UDP-Handschlag / Protokollwahl) und der Schliesscode. Nicht ueber `debug`,
denn das druckt Token und Sitzungsschluessel mit. Daraus folgt die Diagnose:

  stehen bei UDP-Handschlag  -> jetzt darf sie UDP sagen
  zu vor dem UDP-Teil        -> Sitzung (4006/4009), kein Netzproblem
  stehen bei Protokollwahl   -> Verschluesselung
  kein Mitschnitt            -> "Ursache offen". Nicht mehr "UDP".

Warum der UDP-Fall so aussieht, als haenge er: performIPDiscovery hat in
0.18 keine Zeitschranke, und die UDP-Keepalives werden nicht mehr
ausgewertet. Bleibt die Antwort aus, steht der Schritt, bis Discord den
Websocket zumacht.

Drei Sachen noch, die beim Nachsehen auffielen:

- Ein Fehler aus dem Netzteil hat den ganzen Prozess beendet. VoiceConnection
  reicht ihn als 'error' weiter, und ein EventEmitter ohne 'error'-Hoerer
  wirft. Genau dieser Weg ist im Fehlerfall offen -- die UDP-Erkennung meldet
  sich darueber. Jetzt gibt es einen Hoerer.
- schritte.endpunkt wurde bei jedem VOICE_SERVER_UPDATE ueberschrieben. Bei
  einem Rueckfall nennt Discord den Server erneut, also verdeckte die zweite
  Meldung den Endpunkt, an dem es scheiterte. Jetzt gesammelt, und fuer die
  Diagnose zaehlt der erste echte.
- tools/ landete nie im Abbild (COPY src ./src). Der Aufruf im Kopf von
  udp-pruefen.mjs -- "docker exec ... node tools/udp-pruefen.mjs" -- lief ins
  Leere. Jetzt kopiert das Dockerfile es mit.

Die neun Diagnose-Zweige sind gegen die exportierten Funktionen im Container
durchgespielt, nicht gegen eine Kopie.

Was weiter offen bleibt: eine Sperre speziell auf Zielports 50000-65535 ist
nicht widerlegt -- dafuer fehlt eine Gegenstelle, die dort antwortet. Der
naechste Fehlversuch sagt es von selbst.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 12:31:27 +02:00
D4rkst3randClaude Opus 5 89f6dfcd29 Radio: Webradio im Sprachkanal, 44 Sender zum Durchschalten
Deploy / check (push) Canceled after 0s
Deploy / deploy (push) Canceled after 0s
/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>
2026-08-14 11:40:15 +02:00
D4rkst3randClaude Fable 5 b5617a9d18 Repo-Backups, Gitea-Theme und Auto-Deploy
Deploy / check (push) Has been cancelled
Deploy / deploy (push) Has been cancelled
- Repo-Backups: nachts um 04:00 werden alle Gitea-Repos als git-Bundle
  gesichert — eine Datei pro Repo mit kompletter Historie, aus der sich
  direkt wieder klonen lässt. 14 Tage Rotation wie beim DB-Backup,
  Schalter und "Repos jetzt sichern" im System-Tab. Nutzt den bereits
  vorhandenen Gitea-Token; Dockerfile installiert dafür git mit.
- Gitea-Theme im D4RKST3R-Look (docs/gitea-theme/): Neon-Gelb/Orange auf
  Schwarz, gebaut gegen die Variablen von Gitea 1.26, Diff-Farben bleiben
  lesbar. Einbau-Anleitung liegt daneben.
- Auto-Deploy statt manuellem "Pull and redeploy": Workflow für Gitea
  Actions (prüft Server-Syntax und Frontend-Build, bevor deployed wird)
  plus dokumentierter Runner-loser Weg über den Portainer-Webhook.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 14:01:31 +02:00
D4rkst3randClaude Fable 5 676fc45bb1 Willkommens-Karten, Geburtstage, Devlog-Permalinks mit OG-Vorschau, Auto-Publish
- 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>
2026-07-30 22:43:15 +02:00
D4rkst3randClaude Opus 4.8 a70eac08d7 Feature 4: Webinterface — React-Frontend, Discord-OAuth2, REST-API
- 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>
2026-07-23 00:31:39 +02:00
D4rkst3randClaude Opus 4.8 46d6a3f927 Feature 2: Commit-Feed — Gitea-Webhook, Discord-Embeds, SQLite-Archiv
- 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>
2026-07-22 23:27:33 +02:00
D4rkst3randClaude Opus 4.8 2b3fa3eb69 Initiales Setup: minimaler Discord-Bot mit /ping, Docker-Deployment und README
- 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>
2026-07-22 23:10:19 +02:00