Im d4rk_gameserver-Panel bekommt jeder Server einen Schalter "Im Discord
anzeigen". Das Panel schreibt dafuer NICHTS hierher: es setzt nur ein
Haekchen, und das reist in dem Statusbericht mit, den der Monitor ohnehin
alle 30 Sekunden abholt. Der Bot legt den Eintrag dann selbst an.
Der umgekehrte Weg -- Panel ruft unsere API -- braeuchte dort ein
Zeichen mit Schreibrecht. So bleibt es bei einem, das nur lesen kann.
ZWEI FALLEN, beide beim Bauen aufgefallen:
Der Abgleich lief zu spaet. In monitorTick stand `if (servers.length ===
0) return` VOR dem Panel-Abruf; beim allerersten Server haette der
Schalter also nichts getan, und zwar stillschweigend. Der Abruf steht
jetzt davor.
Loeschen braucht einen Besitzvermerk. Ohne den nimmt ein Haekchen im
Panel den handgepflegten ATM10 mit -- die einzige verfuegbare Grundlage
waere der Name, und beim ersten Server, der in beiden Werkzeugen gleich
heisst, waere der Eintrag samt Bild, Links und Zugangs-Code weg. Neue
Spalte `panel_name`, leer heisst "von Hand". Die UPDATE-Anweisung fasst
sie nicht an, damit ein Bearbeiten im Webinterface die Herkunft behaelt.
Und der Abgleich ueberschreibt nichts: angelegt und geloescht wird, mehr
nicht.
tools/panel-abgleich-pruefen.mjs prueft das auf einer EIGENEN Datenbank
in /tmp und bricht ab, wenn sie es nicht ist -- eine Probe, die loeschen
kann, darf nicht dort loeschen, wo es zaehlt. Alles gruen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gamedig FRAGT einen Server. Ein startendes Modpack antwortet nicht, und
nach zwei Fehlversuchen stand im Alarm-Kanal eine Ausfallmeldung, obwohl
niemand etwas kaputtgemacht hat -- am ATM10 des Betreibers gemessen jedes
Mal 306 Sekunden Fehlalarm.
Das d4rk_gameserver-Panel SIEHT den Container, statt ihn zu fragen. Neu
ist deshalb `src/panel.js`: Zustand, Fertig-Merkmal, RAM und CPU kommen
als Zusatzauskunft dazu, einmal je Durchlauf abgerufen und 20 Sekunden
zwischengespeichert.
Was das im Alarm-Kanal aendert:
startet gerade kein Alarm, aber nur innerhalb einer Gnadenfrist von
15 Minuten. Ohne diese Grenze fraesse die Anbindung
genau den Alarm, fuer den es sie gibt -- `bereit`
wird nie von allein wahr, ein haengender Start bliebe
sonst fuer immer stumm.
im Panel gestoppt kein Alarm (Code 0/143/137)
abgestuerzt ALARM, mit Code im Embed
OOM-Kill ALARM, und beim Namen genannt statt als Absturz
getarnt -- bei Modpacks die haeufigste Ursache
Container weg ALARM
Der Zaehler wird beim Unterdruecken NICHT zurueckgesetzt: ein bereits
gemeldeter Ausfall bleibt gemeldet, sonst verschluckt ein Stopp im Panel
die spaetere "wieder online"-Entwarnung und im Kanal bliebe ein Alarm
ohne Aufloesung stehen.
ES IST DURCHGEHEND OPTIONAL. Adresse und Zeichen stehen im Webinterface
unter "Server" und NICHT in der .env; ohne Eintrag -- und ebenso, wenn
das Panel nicht antwortet -- verhaelt sich der Monitor exakt wie vorher.
Das Zeichen darf nur lesen, damit auch ein verlorenes niemandem einen
Server stoppen kann.
`tools/panel-pruefen.mjs` prueft die Logik ohne Discord und ohne
Datenbank; deshalb laedt panel.js die Einstellungen erst beim Aufruf.
Befund 1 aus docs/befunde-2026-08-12.md, der wichtigste: Datenbank und alle
vierzehn Sicherungen lagen im selben Volume. Geht das Volume verloren, geht
beides zusammen verloren -- das ist keine Sicherung, das ist eine Kopie.
tools/abholen.ps1 SICHERT NICHT. Das Archiv baut der Bot selbst; hier wird nur
abgeholt, und zwar so, dass am Ende feststeht, dass die Kopie heil ist und
nicht nur, dass ein Kopierbefehl keinen Fehler geworfen hat:
1. neuestes Archiv im Container finden (und meckern, wenn es aelter als
24 Stunden ist -- ein Skript, das treu das Archiv von vorletzter Woche
abholt und "fertig" sagt, ist schlimmer als eines, das gar nicht laeuft)
2. docker cp heraus
3. Pruefsumme IM CONTAINER gegen die Kopie hier -- nicht die Dateigroesse:
eine abgebrochene Kopie auf eine volle Platte hat oft genau die richtige
Laenge und trotzdem Nullen am Ende
4. auspacken und die Datenbank darin oeffnen, mit dem Bot-Abbild, weil dort
better-sqlite3 schon liegt; integrity_check plus Tabellen zaehlen
5. Bericht als last_zweitziel zurueck in die Einstellungen
6. ausduennen
Und es warnt, wenn es DIESELBE PLATTE ist. Verglichen wird die physische Platte
und nicht der Laufwerksbuchstabe: zwei Partitionen derselben NVMe sterben
zusammen.
Echter Lauf, kein Trockentest:
d4rkbot-2026-08-12.db.gz 993.332 Bytes
andere Platte: Nr. 1 statt Nr. 0
identisch (ff08516d293d...)
in der Sicherung: 55 Tabellen, 86 Einstellungen
DAZU EIN ZWEITER WACHHUND, pruefeZweitziel(). Ein Skript auf dem Wirt, das
still aufhoert zu laufen -- Aufgabe deaktiviert, Laufwerk weg, Pfad geaendert --
waere derselbe Schaden noch einmal, nur eine Ebene weiter aussen. Er meldet nur,
wenn die Abholung schon einmal lief: fehlt der Eintrag ganz, ist sie nicht
eingerichtet, und daraus taeglich eine Meldung zu machen waere Naergelei.
Gegen eine Kopie der Datenbank durchgespielt:
40 h alt -> "alt:17863965"
nochmal -> unveraendert (keine Wiederholung)
Fehlschlag -> "fehler:1786540570974"
wieder gut -> "" (Entwarnung)
Nebenbei gelernt, zum zweiten Mal in diesem Projekt: die Kopie der Datenbank
ohne -wal war leer an der Stelle, die zaehlte -- last_zweitziel stand noch im
Write-Ahead-Log. Dieselbe Falle wie beim Zurueckspielen von d4rk_media.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
devlog.py im EcoGame-Repo taugt für Bot-Devlogs nicht: es zählt
EcoGame-Commits, bricht ohne solche ganz ab, betitelt den Post als
„Devlog — EcoGame" und löscht die Bilder nach dem Senden.
Das Skript hier zählt die Commits von d4rkbot, nimmt einen Bilder-Ordner
(max. 4, wie der Endpoint), lässt die Bilder liegen und kann mit --dry
vorher zeigen, was rausginge. Die Webhook-Adresse kommt aus der Umgebung
oder einer Datei und wird nie ausgegeben — auch nicht im Fehlerfall.
Beim Testen gegen einen lokalen Bot ohne Discord gefunden: payload_json
als Blob anzuhängen kommt beim Endpoint als Datei-Teil an und wird
zusammen mit den Nicht-Bildern verworfen — der Post wäre mit „empty
devlog" abgelehnt worden. Muss ein Textfeld sein.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- docker-compose.yml: Variablen per Interpolation (lokal aus .env, in Portainer aus Stack-Env)
- tools/test-webhook.mjs: signierte Fake-Testzustellung gegen die lokale Instanz
- README: Portainer-Anleitung präzisiert (Git-Auth für privates Repo, Pull and redeploy)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>