6fab87122537969e1adc65dad011d5ffb2f85939
22
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
dbec4e9775 |
Panel: die volle Fernbedienung ueber der Senderliste
Was laeuft, wo, aus welcher Quelle, mit Fortschrittsbalken. Sprachkanal waehlen, Sender abspielen, Ueberspringen, Zum Radio, Stopp, Lautstaerke-Schieber. Einreihen per Link oder Suchbegriff, Warteschlange mit Hoch/Runter/Weg und Leeren. Darunter ein aufklappbarer yt-dlp-Block: Zustand, Fassung, cookies.txt, eigene Argumente, Aktualisieren -- und die letzte Fehlerzeile im Klartext. Steht ueber der Senderliste, weil man oefter etwas abspielt als die Liste pflegt. Die Abfrage laeuft nur, solange der Community-Reiter offen ist. Sonst ginge alle fuenf Sekunden eine Anfrage gegen eine Ansicht raus, die niemand ansieht. Der Balken erscheint nur bei bekannter Dauer. Bei einem Livestream gaebe er einen Stand vor, den niemand kennt -- dort steht stattdessen "live". Die Kanalauswahl graut aus, wo der Bot nicht rein darf. Ein Kanal, den das Panel anbietet und in den der Bot dann nicht kommt, sieht aus wie ein kaputter Knopf. Geprueft: der Vite-Build laeuft durch, und ein Abgleich stellt alle 30 Feldpfade, die die Oberflaeche vom Stand liest, gegen die echte API-Antwort -- 0 fehlen. Der Abgleich hat eine Gegenprobe mit bekanntem Ausgang (ein Feld, das es nicht gibt, muss als fehlend erkannt werden) und prueft vorher, ob die sonst leeren Zweige (Warteschlange, Cookies, letzter Fehler) ueberhaupt besetzt sind -- sonst meldet er "ungueltig" statt "in Ordnung". Seine erste Fassung hatte Fehlalarm geschlagen (?. und .map als fehlende Felder gelesen); das ist behoben. NICHT geprueft: das tatsaechliche Rendern im Browser -- hier ist weder Browser noch DOM-Werkzeug vorhanden. |
||
|
|
19010e9fde |
Die Panel-Anbindung entfaellt -- das Panel postet jetzt selbst
Entscheidung des Betreibers am 19.08.2026: das d4rk_gameserver-Panel
baut und stellt seine Status-Embeds ab sofort selbst in den Discord.
Damit hat diese Anbindung keinen Zweck mehr.
WARUM SIE UEBERHAUPT WEG SOLL, und nicht bloss ungenutzt liegenbleibt:
sie war die zweite Meinung ueber denselben Zustand. `zustandText()` gab
`null` zurueck, wenn ein Server LIEF UND BEREIT war -- also im
Normalfall -- und der Monitor fiel dann auf seine gamedig-Abfrage
zurueck. Erreichte die den Server nicht, stand im Kanal "Offline",
waehrend dasselbe Embed RAM und CPU aus dem Panel anzeigte. Ein
Widerspruch, den man von keiner der beiden Seiten aufloesen konnte.
ENTFERNT:
src/panel.js die Anbindung
src/panel-abgleich.js das Anlegen/Wegraeumen von Eintraegen
tools/panel-pruefen.mjs die zugehoerigen Proben
tools/panel-abgleich-pruefen.mjs
panelUrl/panelZeichen in runtime-settings.js
panel_url/panel_zeichen als Einstellung und im Formular
Servertyp `panel` er fragte nicht selbst, sondern las ab
WAS DER MONITOR DAMIT VERLIERT, und es gehoert dazugesagt: die
Schonfrist beim Hochfahren. Ein startendes Modpack antwortet minutenlang
nicht -- am ATM10 gemessen 306 Sekunden -- und meldet dadurch wieder
einen Ausfall, wo vorher "startet gerade" stand. Die
Zwei-Fehlschlaege-Schwelle federt das teilweise ab, nicht ganz.
Fuer Server im Panel ist das kein Verlust: dort postet das Panel und
kennt den Unterschied. Fuer FiveM und LS25 hat es ihn nie gegeben.
Geprueft: alle 281 relativen Importe loesen auf, die geaenderten Dateien
sind syntaktisch in Ordnung, das Frontend baut. Der Bot selbst ist NICHT
neu gestartet worden -- das ist eine Entscheidung des Betreibers.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
e39d4b33b6 |
Protokoll: melden, was Moderation ist -- nicht alles, was passiert
Der Betreiber bekam "fuer alles einen Alert". Zu Recht: sechs verschiedene
Meldungen liefen in denselben Kanal, und dahinter stand ein einziger
Modulschalter -- entweder alles oder nichts.
geloescht / bearbeitet / Nick+Rollen / beigetreten / gegangen / AutoMod
Zwei davon waren der eigentliche Laerm, und beide sind gar keine
Moderationsvorgaenge:
1. Jede selbst zurueckgenommene Nachricht wurde gemeldet. Wer seinen eigenen
Tippfehler loescht, ist kein Vorfall.
2. Jede Rollenaenderung, die der Bot selbst ausgeloest hat -- Rollenmenue-Klick,
Level-Aufstieg, Sticky-Restore nach Wiedereintritt, Playtester-Knopf. Der
Bot hat sich selbst bei der Arbeit zugesehen und darueber Protokoll gefuehrt.
Beides wird jetzt gefiltert. Erkannt ueber Discords Audit-Log und nicht ueber
Merker an den vier Stellen, die Rollen vergeben -- so ist auch die fuenfte
erfasst, die jemand spaeter baut.
Dafuer musste werHatGeloescht() zuerst repariert werden. Sie gab fuer VIER
verschiedene Lagen dasselbe `null` zurueck: kein Server, kein Recht aufs
Audit-Log, Abfrage fehlgeschlagen, und "der Verfasser war es selbst". Zum
Anzeigen reichte das ("dann eben ohne Angabe"). Als Filter waere es die
schlimmste Sorte Fehler gewesen: fehlt dem Bot das Recht, saehe "selbst
geloescht" genauso aus wie "konnte nicht nachsehen" -- und das Protokoll
haette stillschweigend alles verschluckt, ohne dass es jemandem auffaellt.
Jetzt drei unterscheidbare Antworten: { wer } / { selbst } / { unklar, Grund }.
Verschwiegen wird nur, was sicher selbst geloescht wurde. Unklares wird
gemeldet, und der Grund steht im Embed, damit niemand die Zeile fuer "von
einem Mod geloescht" haelt. Fehlt das Recht, sagt das Log es einmal und dann
nicht wieder -- sonst waere die Meldung selbst wieder Rauschen.
Dazu vier Einzelschalter im Panel, weil "alles oder nichts" die Ursache war.
Vorgabe an: ein Protokoll, das nach einem Update stillschweigend aufhoert zu
protokollieren, waere die schlechtere Ueberraschung. Gelesen wird mit
!== '0', geschrieben werden sie einmalig als '1' -- das Panel liest
Feld-Schalter naemlich mit === '1', und ein Formular, das das Gegenteil
dessen zeigt, was gilt, ist schlimmer als gar keins.
Aufgepasst bei den Schaltern: an drei der Handler haengt mehr als nur die
Meldung. Begruessung und Auto-Rollen beim Beitritt, das Sichern der Rollen
beim Austritt, und das Nachfuehren des Nachrichten-Gedaechtnisses beim
Bearbeiten laufen weiter, auch wenn niemand die Meldung sehen will. Sonst
haette ein Protokoll-Schalter das Verhalten des Servers geaendert.
Geprueft mit gestellten Objekten, zwoelf Faelle: kein Server, kein Recht,
Abfrage wirft, kein Eintrag, Eintrag vom Autor selbst, Eintrag zu alt, Mod
war es -- und fuer die Rollen: Bot war es, Mensch war es, kein Eintrag, kein
Recht, Abfrage wirft. Im Zweifel wird immer gemeldet. Dazu die Schalter gegen
die Panel-Anzeige: beide sagen dasselbe.
Ungeprueft: der Lauf gegen ein echtes Audit-Log. Ob der Bot das Recht
"Audit-Log ansehen" hier ueberhaupt hat, steht nach dem Ausrollen im Log.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
89f6dfcd29 |
Radio: Webradio im Sprachkanal, 44 Sender zum Durchschalten
/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> |
||
|
|
d6124fc2cd |
feat: der Monitor fragt das Panel, wenn eine Abfrage nicht ausreicht
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.
|
||
|
|
9b681754fa |
Ein Embed je Hof, das sich selbst aktualisiert
Der Fuhrpark stand bisher nur als Gesamtzahl im Karten-Embed. Jetzt bekommt jeder Hof eine eigene Nachricht im selben Kanal, die bei jedem Durchlauf bearbeitet statt neu gepostet wird: Land, Fahrzeuge mit Wert und Betriebsstunden, was in die Werkstatt muss, was gewaschen gehoert und was geladen ist. Die Fahrzeuge kommen aus vehicles.xml, blockweise gelesen — Verschleiss und Schmutz stehen in Kindelementen und gehoeren sonst dem falschen Fahrzeug. Gemietete Missionsfahrzeuge bleiben draussen, sie verfaelschen Anzahl und Wert. Faellt die Datei einmal aus, bleiben die Embeds stehen, statt dass ein Hof verschwindet und gleich darauf doppelt gepostet wird. Damit tauchen auch Hoefe auf, die noch kein Land gekauft haben: die Liste der Hoefe kommt aus Parzellen und Fuhrpark zusammen. Dazu raus, was nur den Kanal vollgeschrieben hat: die Meldung zum Monatswechsel und die zum Landkauf. Der Monat wird still weitergestellt — er steht ohnehin im Embed. Damit faellt der Ereignis-Kanal weg und mit ihm die gespeicherte Besitzliste. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
5de172f862 |
LS bekommt einen festen Platz unter Gaming
Das Modul stand nur unter "Meine Funktionen" — also solange, wie du es angeheftet laesst. Loest man die Nadel, ist es nur noch uebers Modul-Raster erreichbar. Fuer die groesste Seite im Panel zu wenig. Jetzt kann ein Modul `nav: true` setzen und bekommt damit einen Eintrag in der Seitenleiste, unter seiner eigenen Gruppe. Kein Sonderfall fuer LS: jedes Modul, das eine ganze Seite fuellt, kann sich so einsortieren. Dabei aufgefallen und mitgenommen: eine halbe Antwort von /api/modules/:id hat die ganze Config weiss gemacht. Der Ladepfad ist zwar sauber abgesichert — `fehler` und `!detail` fangen ab —, aber ein Objekt OHNE die Listen kommt durch beide Wachen und laesst dann `detail.werte.some(...)` werfen, was React mit dem gesamten Baum quittiert. Vier Listen mit `?? []` kosten nichts und machen aus dem Weissbild schlimmstenfalls eine leere Sektion. Zwei Werkzeug-Fallen nebenbei: `npx vite build` zieht mal das lokale Vite 6, mal ein gecachtes Vite 8 aus dem npx-Ordner — ab jetzt nur noch `npm --prefix frontend run build`. Und der laufende Preview-Server haelt dist/assets fest, was den Build mit EPERM abbricht; vorher stoppen. Geprueft: Seitenleiste zeigt Gaming mit Game-Server und LS, Klick oeffnet die Modulseite und markiert den Eintrag, kein Fehler in der Konsole. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
9f929fe0e4 |
Eigene Kategorie Gaming fuer Game-Server und LS
Der Game-Server-Monitor stand unter "Server & Technik" zwischen DB-Sicherung, Repo-Sicherung und Member-Gate. Technisch nicht falsch — dort laeuft alles, was der Bot an Infrastruktur anfasst. Nur sucht niemand seinen LS-Server neben dem Datenbank-Backup. Mit dem LS-Modul waren es zwei Eintraege in der falschen Schublade, und das reicht fuer eine eigene. Getrennt wird nach dem, worum es geht: "Server & Technik" ist der Bot selbst, "Gaming" sind die Spiele-Server drumherum. Beide Ebenen ziehen mit — die Modul-Kacheln ueber MODULE_GROUPS, die Seitenleiste ueber TAB_SECTIONS —, und der Tab heisst jetzt "Game-Server" statt "Server", weil "Server" im selben Panel schon zweierlei bedeutete. Nebenbei: das Modul hiess "Server-Monitor" und ueberwacht Game-Server; jetzt steht das auch dran. Die Suche im Panel findet den Tab zusaetzlich ueber "ls", "landwirtschaft", "farming", "hof", "karte" und "preise". Geprueft: kein Modul ohne Gruppe, keine leere Gruppe, Seitenleiste und Modul-Kacheln im laufenden Panel angesehen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
1075b91121 |
Kanaele werden auch angezeigt, Monate statt Schluessel, Sorten auf Deutsch
Die Kanalauswahl blieb leer, obwohl "einsatzbereit" gruen daneben stand — ein Widerspruch, der die Ursache schon verraet: der Wert lag in der Datenbank, das Formular bekam ihn nur nie zu sehen. Ich hatte beim letzten Mal das Speichern repariert und uebersehen, dass currentSettings() dieselbe von Hand gepflegte Liste fuehrt. Jetzt holt auch sie die Schluessel aus dem Modul-Register. Geheimes bleibt aussen vor: gitea_api_token steht unter requires, faellt aber durch die Namenspruefung und wird weiterhin nur als "ist gesetzt" gemeldet. Dazu die Uebersetzung. Im Embed standen wheat, clover_windrow und seeds, weil der Feed nun mal Englisch spricht. Jetzt Weizen, Rotklee (Schwad) und Saatgut, mit lesbarem Rueckfall fuer alles, was nicht in der Liste steht — 371 Sorten uebersetzt niemand von Hand. Und der Monat. Die zwoelf Perioden sind schlicht Monate, EARLY_SPRING ist Maerz. Also nimmt das Feld jetzt "September", "sept" oder "9" statt EARLY_AUTUMN; Mehrdeutiges wie "Ju" wird abgelehnt statt geraten. Weiterzaehlen kann der Bot selbst, seit klar ist, dass ein Monat ueber einen Tag laeuft. Nicht ueber playTime — die steht im Savegame und wird nur beim Autosave geschrieben: ueber zwei Stunden gemessen stieg sie um 50, waehrend die Spieluhr 18,7 Stunden weiterlief. dayTime in der Statusabfrage ist dagegen live, und jeder Ruecksprung um Mitternacht ist ein Monatswechsel. Steht der Server leer, steht die Spielzeit — und der Monat bleibt richtigerweise stehen. Geprueft: alle zwoelf Monate hin und zurueck, Abkuerzungen, Monatszahlen, Mehrdeutiges, acht Sorten Unsinn, der Jahreswechsel von Februar auf Maerz, der Ruecksprung um Mitternacht samt Erstlauf, und dass jede Sorte der Standardauswahl einen deutschen Namen hat. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
c5e13182c0 |
Modul-Felder speichern wieder, und die Feed-Adresse ist einstellbar
Die LS-Kanaele liessen sich im Panel waehlen und waren nach dem Speichern wieder leer. Der Grund: PUT /api/settings fuehrt fuer jede Feldart eine von Hand gepflegte Liste erlaubter Schluessel, und ein Schluessel, der nirgends steht, faellt still durch. Keine Fehlermeldung, kein Log — das Feld sieht funktionsfaehig aus und vergisst. Das ist keine Einzelheit, sondern eine Falle fuer jedes kuenftige Modul: wer eins ergaenzt und diese Listen nicht mitpflegt, baut denselben Fehler nach. Die Modulliste weiss laengst, welche Felder es gibt und welcher Art sie sind — also holt der Handler sie jetzt von dort, statt sie ein zweites Mal aufzuzaehlen. Beim Bauen des Helfers ware ich fast in die naechste Falle gelaufen: ich hatte alle requires-Eintraege als Kanaele eingestuft. Dort stehen aber auch gitea_api_token und watchdog_urls, und die haetten dann die Kanal-Pruefung durchlaufen — Speichern waere mit "Kanal nicht gefunden" gescheitert, sobald jemand seinen Gitea-Token aendert. Uebernommen wird jetzt nur, was der Namenskonvention folgt. Dazu die fest verdrahtete Feed-Adresse. http://host:port/feed war eine Wette auf drei Annahmen gleichzeitig: dass jeder Hoster http nimmt, den Feed unter /feed ablegt und keinen Pfad davorsetzt. Aendern konnte das niemand. Jetzt gibt es ein Feld dafuer, und wer die ganze Abfrage-URL ins Host-Feld einfuegt, bekommt es mitsamt Schema und Pfad automatisch ausgefuellt. Was dahinter kommt (dedicated-server-stats.xml und Geschwister) gibt Giants vor und bleibt im Code. Geprueft: jedes Feld jedes Moduls landet in einem Eimer — der Test faellt kuenftig aus, sobald jemand ein Feld ergaenzt, das nicht speicherbar waere. Dazu, dass nichts faelschlich in die Kanal- oder Rollenpruefung geraet, keine Dubletten, und die Feed-Basis mit eigenem Pfad, https, ueberzaehligen Schraegstrichen sowie sechs Sorten Unbrauchbarem. Das Einfuegen einer https-URL mit Pfad im laufenden Panel angesehen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e215cd4c7c |
LS-Modul: Besitzkarte auf dem Luftbild und Preiskurven
Der Feed eines LS-Servers gibt viel mehr her als die Spielerzahl, die der Monitor bisher davon benutzt hat: in denselben 49 KB stehen 163 Parzellen mit Besitzer und Hektar, 130 Felder, jedes Fahrzeug samt Ladung und die Position jedes Spielers. Und das Luftbild liefert der Server auch, in jeder Groesse bis 4096. Also eine Karte: gekaufte Parzellen nach Hof eingefaerbt, Kreisflaeche gleich Hektar, Fahrzeuge und Spieler live, dazu eine Hof-Uebersicht mit Flaeche und Wert. Wechselt Land den Besitzer, kommt eine Meldung — beim allerersten Durchlauf bewusst nicht, sonst haette der Botstart eine Meldung pro bereits gekaufter Parzelle abgesetzt. Dazu die Preiskurven aus der economy.xml: je Fruchtart, was sie in welcher der zwoelf Perioden bringt, als Balkenzeile mit "jetzt verkaufen" oder "+43 Prozent im Hochwinter". Was NICHT geht, und zwar grundsaetzlich: welche Frucht auf welchem Feld steht und wie weit sie ist. Das liegt in einer binaeren Density-Map, die kein Endpunkt herausgibt. Ich habe 18 Dateinamen durchprobiert, es gibt genau drei. Die Mods, die das anzeigen, sind reine HUD-Overlays ohne Ausgang. Und keiner der fuenf anderen LS-Bots kann es, obwohl einer davon Geld kostet. Das steht mit allen Belegen in docs/ls-feed.md, damit die Frage nicht dreimal kommt. Beim Bauen aufgefallen: - istLsServer() gab den Zugangs-Code zurueck statt true — die &&-Kette liefert den letzten wahren Wert. Beim ersten Log-Aufruf haette der Code im Klartext im Protokoll gestanden. - Die Karte als PNG war 2,5 MB, als JPEG 268 KB. Es ist ein Luftbild. - Nach Preisschwankung sortiert gewinnt Spargel: 26 bis 7540 Euro, und Weizen taucht gar nicht mehr auf. Die Liste arbeitet jetzt mit einer Auswahl. - Die Jahreszeit steht in keinem Endpunkt. Schaetzbar waere sie, aber nur solange niemand die Zeitskala aendert — also eine Einstellung. Geprueft gegen echte Serverdaten: Zerlegen der Statusabfrage inklusive Vollstaendigkeit aller 163 Parzellen, Ladung ohne Diesel und leere Slots, Hof-Uebersicht ohne verlorene Parzellen, Preiskurve mit vollem und leerem Balken an der richtigen Stelle, flache Kurve ohne Division durch Null, Besitzwechsel inklusive Erstlauf und neu hinzugekommener Parzelle, Hof-Namen aus der Einstellung, SVG ohne NaN und mit maskierten Namen, und der Merker in der Datenbank inklusive kaputtem JSON. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
ddd7610d6c |
Playtester bekommen einen eigenen Bereich, Module ziehen um
Playtester und Alpha-Keys standen als zwei Kaesten mitten im Community-Bereich zwischen Geburtstagen und Starboard. Die Liste war reine Anzeige: Namen und Datum, sonst nichts. Wer einem Einzelnen einen Schluessel geben wollte, konnte nur "an alle verteilen" druecken, und wer jemanden wieder rausnehmen wollte, musste an die Datenbank. Jetzt ist es ein eigener Bereich mit drei Zahlen oben und einer Liste, in der neben jedem Namen sein Schluessel steht. Daneben, je nach Zustand, "Schluessel geben" oder "Zurueckziehen", und ein ✕ zum Entfernen — die Rolle geht dabei mit, denn nur aus der Liste zu streichen und die Rolle stehen zu lassen waere eine Halbwahrheit. Der Vorrat ist jetzt sichtbar, nicht nur seine Groesse: einen vertippten Schluessel findet man sonst nie wieder. Nachlegen und "wer bekommt einen?" laufen ueber Dialoge, damit der Bereich nicht zumuellt — dafuer gibt es jetzt eine kleine Dialog-Komponente, gebaut wie die Lightbox (Portal, Escape, Hintergrund festhalten). Zurueckziehen legt den Schluessel zurueck in den Vorrat. Die Person hat ihn per DM natuerlich weiterhin — das ist eine Buchhaltung, keine Sperre. Loeschen geht absichtlich nur bei freien Schluesseln. ## Module dorthin, wo man sie sucht Ein paar Module standen im falschen Bereich, teils seit Langem: - Willkommens-Karte: Support → Brand. Sie ist Aussehen, kein Support-Fall, und im Brand-Bereich steht der Rest vom Auftritt. Der Block ist woertlich umgezogen, nur in eine eigene Konstante — so kann sich beim Umzug nichts am Inhalt geaendert haben. - Twitch & YouTube: System → Feeds. Es ist ein Feed. - Events: System → Community. - Auto-Rolle und Rollen merken: Ihre Felder standen laengst im Rollen-Bereich, nur das Register sagte "Community" — dadurch sprang "Einrichten" woanders hin als die Einstellung liegt. - Playtester und Alpha-Keys: Community → eigener Bereich. Damit ist System kein Sammelbecken mehr, sondern nur noch Technik: Waechter, Sprachkanaele, Erinnerungen, Sicherungen, Member-Gate. Geprueft: Routen (alle vier neuen bewacht), SQL gegen das Schema, und im Browser beide Dialoge (Escape schliesst, Hintergrund wird wieder freigegeben, Hinzufuegen bleibt bei leerem Feld aus), die Liste in allen drei Zustaenden, und die Suche — "willkommen" fuehrt jetzt nach Brand, "twitch" zu Feeds, "sticky" zu Rollen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
3080f52e71 |
AutoMod sichtbar machen: Treffer ins Protokoll, Regeln ins Panel
Discords eigener Filter arbeitet serverseitig und ohne Latenz — daran ist nichts zu verbessern. Was fehlte, war die Sicht darauf: Treffer landeten nur in Discords eigenem Kanal, und die Regeln pflegte man in einer ganz anderen Oberflaeche als alles andere. Jetzt spiegelt der Bot jeden Treffer als Embed ins Mod-Log — mit Nutzer, Regel, Ausloeser, Massnahme, getroffenem Wort und gekuerztem Wortlaut, ohne Erwaehnungen, die den Kanal anpingen. Im Panel steht unter Support jede Regel mit Ausloeser, Massnahmen und der Zahl ausgenommener Rollen und Kanaele — letzteres oft der Grund, warum eine Regel scheinbar nicht greift. Schalten geht dort direkt. Das Bearbeiten der Wortlisten bleibt bewusst in Discord; dort ist es gut geloest, und ein zweiter Ort dafuer waere nur eine weitere Stelle, an der etwas auseinanderlaeuft. Dazu noetig: der Gateway-Intent AutoModerationExecution. Nicht privilegiert, aber Discord schickt die Ereignisse nur an Bots mit "Server verwalten" — fehlt das Recht, sagt das Panel es statt still leer zu bleiben. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
c8b1f604f0 |
Umfragen: /umfrage als native Discord-Abstimmung
Bewusst Discords eigenes Poll-Objekt statt einer Nachbildung mit Knoepfen — Oberflaeche, Auszaehlen und Ergebnisanzeige macht Discord dann selbst, auch auf dem Handy. Wir bauen nur die Frage zusammen. Bis zu vier Antworten (Discord erlaubt zehn, vier halten den Befehl uebersichtlich), Laufzeit von einer Stunde bis einer Woche, Mehrfachauswahl optional. Rechte: ManageMessages. Zwei gleiche Antworten werden abgefangen. Discord stoert das nicht, aber abstimmen kann darauf niemand sinnvoll. Nicht zu verwechseln mit /wunsch: das sammelt Feature-Wuensche dauerhaft und zeigt sie auf der Roadmap. /umfrage ist die schnelle Frage zwischendurch und laeuft von selbst ab. Steht so auch als Kommentar im Befehl. Geprueft gegen die installierte discord.js-Fassung (14.27) statt gegen die Dokumentation: Feldnamen aus den Typdefinitionen gelesen, und die fertige Nutzlast durch discord.js' eigene Serialisierung gejagt. Kommt als poll_media / allow_multiselect / layout_type 1 raus, genau wie Discords API es erwartet. Dazu: 18 Befehle laden ohne Namenskollision, Befehl steht auf der oeffentlichen Liste in beiden Sprachen, Zahl auf der Produktseite von 17 auf 18. Nutzungsbedingungen als Entwurf unter docs/ — Text fuer den Seiten-Editor, keine Rechtsberatung. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
137452da11 |
Linked Roles: Rollen, die an geprueften Werten haengen
Neues Modul, standardmaessig aus. Ein Mitglied klickt in Discord auf "Rolle holen", landet auf /linked-roles, bestaetigt den OAuth-Dialog — und der Bot schiebt ihm drei Kennzahlen zu, die Discord dann gegen die Rollen-Einstellung prueft: level Zahl >= eingestelltem Wert dabei_seit Datum <= "vor X Tagen", also Mitglied seit mindestens X Tagen playtester Wahrheitswert Der Bot vergibt dabei keine Rollen. Er liefert nur die Zahlen; was daraus wird, entscheidet die Rollen-Einstellung im Server. Die Daten kommen aus dem, was ohnehin da ist: Level-Tabelle, Playtester-Liste, Discords Beitrittsdatum. Eigener OAuth-Weg statt /auth/login, weil die Berechtigungen andere sind — role_connections.write hat der normale Login nicht. Die Tokens werden gespeichert, und das ist keine Bequemlichkeit: ohne Refresh-Token bliebe jede Rolle auf dem Stand des Verknuepfungs-Tages stehen, ein Level-Up kaeme nie an. Discords eigene Anleitung sagt dasselbe. Der Umfang ist eng (nur identify + role_connections.write), beim Widerruf oder Entkoppeln fliegt der Datensatz sofort raus. Steht so auch als Kommentar an der Tabelle. Abgeglichen wird alle 6 Stunden, einstellbar. Dafuer kann everyTuned jetzt auch Stunden — und wirft bei einer unbekannten Einheit, statt den Abstand still um Faktor 60 oder 3600 danebenzulegen. Beim Bauen gefunden: moduleEnabled fehlte im Import von client.js. Der Bot waere beim ClientReady mit ReferenceError gestorben. Geprueft: alle drei Kennzahlen gegen Discords Formatgrenzen (Schluessel-Regex, Laengen, gueltige Typ-Codes), Modul- und Stellwert-Register, die Stunden-Umrechnung (6 h = 21600000 ms), Speichern und Loeschen einer Verknuepfung, dazu 186 SQL-Abfragen und alle Routen auf Rechtepruefung. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
aef708c405 |
Raid-Schutz: erkennt Beitritts-Wellen und sperrt voruebergehend
Neues Modul anti_raid, standardmaessig AUS. Zaehlt Beitritte in einem Zeitfenster; reisst es, geht der Server dicht: Verifizierung auf Hoch, Einladungen gesperrt, DM an den Owner und Eintrag ins Protokoll. Bewusst zurueckhaltend — es wird niemand gekickt oder gebannt. Bei einem Fehlalarm, etwa nach einem Stream-Shoutout, waere ein Massenkick schlimmer als der Raid. Beide Massnahmen sind reversibel und treffen niemanden, der schon drin ist. Der Sperrzustand liegt in den Einstellungen, nicht nur im Speicher: startet der Bot mitten in einer Sperre neu, waere der Timer sonst weg und der Server bliebe fuer immer dicht. Beim Start wird die Restzeit abgesessen oder, wenn laengst abgelaufen, sofort aufgehoben. Drei Werte im Panel: Schwelle (8), Fenster (20 s), Sperrdauer (15 min). disableInvites() gibt es erst ab discord.js 14.4 und nur mit ManageGuild — beides wird geprueft, statt im Ernstfall einen Fehler zu werfen. Die Fenster-Logik ist als reine Funktion herausgezogen und mit neun Faellen geprueft: langsame Beitritte loesen nicht aus, die Welle schon, der Rand des Zeitfensters zaehlt nicht mehr mit, und nach Ruhe faengt das Fenster von vorn. Offen: ein Befehl zum sofortigen Aufheben. Bis dahin laeuft die Sperre aus oder man setzt die Verifizierung in Discord selbst zurueck. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
c0a56c1eb5 |
Logo auf der Willkommens-Karte und in geteilten Links
Zwei Stellen, an denen die Marke bisher fehlte. Willkommens-Karte: Das Wasserzeichen war der Markenname als Text mit 5 % Deckkraft — jetzt der Katzenkopf. Die Datei wird einmal beim Start gelesen statt bei jedem Beitritt, und fehlt sie, rendert die Karte wie bisher ohne Wasserzeichen. Der Schalter heisst entsprechend "Logo im Hintergrund". Link-Vorschau: og:image war nur gesetzt, wenn ein Devlog einen Screenshot hatte. Startseite, Roadmap, Funktionen und jedes Devlog ohne Bild kamen in Discord als graue Textzeile. Jetzt faellt alles ohne eigenes Bild auf og-default.png zurueck (1200x630, Lockup auf Schwarz mit Akzentstreifen), und twitter:card ist durchgehend summary_large_image. Die Laufzeit-Datei liegt unter src/bot/assets/, nicht in docs/ — das Dockerfile kopiert nur src/ und frontend/dist/. Geprueft: librsvg zeichnet das eingebettete <image> wirklich (42726 Pixel unterscheiden sich gegen eine Fassung ohne), das OG-Bild landet im dist. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
c026b2a603 |
Wichtige Funktionen direkt in der Seitenleiste
Nach dem Umbau lagen alle Funktionen hinter dem Raster — für die vier, fünf, die man dauernd anfasst, ist das ein Umweg zu viel. Oben in der Seitenleiste steht jetzt „Meine Funktionen": ein Klick öffnet die Seite direkt. Welche dort stehen, entscheidet der Stern auf der Modul-Karte oder auf der Seite selbst. Bewusst nicht alle 35: Deckel bei acht, sonst ist der Gewinn gegenüber dem Raster wieder weg. Der Standard ist eine Vermutung (Devlogs, Willkommen, Tickets, Starboard, Galerie) und ausdrücklich zum Ändern gedacht. Die Auswahl liegt als Einstellung in der Datenbank, nicht im Browser — sie gilt damit auf jedem Gerät und fürs ganze Team. Eine geleerte Auswahl wird als solche gespeichert, sonst käme beim nächsten Laden der Standard zurück. Der Stern ist ungeheftet nur angedeutet und wird erst beim Überfahren deutlich — 35 Karten mit vollen Sternen sähen aus wie ein Sternenhimmel. Nebenbei: bei geöffneter Modul-Seite war sowohl „Module" als auch die Funktion in der Leiste hervorgehoben. Jetzt nur noch die Funktion. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
c88926aba0 |
Modul-Seiten: alles zu einer Funktion an einem Ort
Bisher war eine Funktion über vier Bereiche verteilt: Schalter unter Module, Kanal unter Support, Texte unter Texte, Werte unter Werte. Wer die Begrüßung ändern wollte, brauchte drei Bereiche. Jetzt öffnet ein Klick auf die Karte die Seite dieser Funktion — mit Schalter, ihren Kanälen und Feldern, ihren Texten, ihren Werten und dem Weg zum passenden Werkzeug. Für „Willkommen" also Kanal, Karte, Farben, Vorschau und beide Texte untereinander. Bewusst keine 35 Einträge in der Seitenleiste: das Modul-Raster ist die Navigation, wie bei MEE6. Die Seitenleiste bleibt so lang wie vorher. Die Seite wird aus den Registern gebaut, nicht von Hand: modules.js kennt die Felder (neu: `fields` für alles jenseits der Pflichtkanäle, `tool` für den Verweis auf einen Editor), templates.js hatte die Zuordnung schon, tuning.js hat sie bekommen. Eine neue Funktion bekommt ihre Seite dadurch geschenkt — es gibt keinen Ort, an dem man sie vergessen könnte. Was ein eigenes Werkzeug hat — Rollen-Menüs, Bewerbungen, Composer, Server-Monitor —, bleibt in seinem Bereich; die Modul-Seite verlinkt nur dorthin. Dort ist mehr Platz, und die Editoren lassen sich nicht sinnvoll aus Registern erzeugen. Texte und Werte bleiben zusätzlich als flache Übersicht: wer alle Texte am Stück durchgehen will, soll dafür nicht 27 Seiten öffnen müssen. Beim Umbau ist mir ein Skript in die Quelldatei gelaufen — der Schreibvorgang scheiterte an einem Emoji und hinterließ modules.js leer. Wiederhergestellt aus dem letzten Commit; die Skripte schreiben jetzt erst in eine Zwischendatei und benennen danach um. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
bea35234c6 |
„Einrichten" zeigt jetzt, was fehlt — und Env-Werte gelten als gesetzt
Zwei Fehler, die zusammen für Ratlosigkeit gesorgt haben. In der Liste stand „Fehlermeldungen — Gitea-Token", obwohl das Token über GITEA_API_TOKEN längst gesetzt war und /bug lief. Grund: die Voraussetzungs-Prüfung las die Einstellung roh statt den wirksamen Wert, sah also nur in die Datenbank und nicht in die Umgebung. Betraf außerdem Devlog-Kanal, Commit-Kanal und Guild-ID. runtime-settings hat dafür jetzt effectiveSetting(), das beides zusammenführt. Und wer dann auf „Einrichten" drückte, landete im System-Bereich — dort gibt es gar kein Token-Feld, das steht bei Brand. Das Modul zeigte auf den falschen Bereich. Jetzt springt „Einrichten" auf das konkrete Feld und hebt es kurz hervor, statt nur den Bereich zu wechseln. Der Bereich kommt dabei aus dem Einstellungs-Register, das ohnehin weiß, wo jedes Feld liegt — damit kann die Zuordnung am Modul nicht mehr auseinanderlaufen. Dieselbe Logik hängt an „Einstellungen →" auf den Modul-Karten. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
684573b88c |
Fehlende Kanäle und Rollen aus dem Panel anlegen
Die Status-Seite listet Module, denen ein Kanal oder eine Rolle fehlt. Bisher hieß das: rüber zu Discord, Kanal anlegen, Rechte setzen, zurück ins Panel, auswählen, speichern. Jetzt steht daneben ein Knopf, der genau das in einem Schritt macht — inklusive Eintragen der Einstellung. Die Vorlagen hängen bei den Modulen (modules.js): Name, Thema und ob der Kanal privat sein soll. Private Kanäle bekommen @everyone entzogen und Bot plus alle Rollen mit Moderationsrecht eingetragen — sonst legt man einen Modmail-Kanal an, den das Team nicht sieht. Gibt es Kanal oder Rolle schon (bei Rollen unabhängig von Groß- und Kleinschreibung), werden sie verknüpft statt doppelt angelegt. Beim Temp-Voice-Hub entsteht ein Sprachkanal statt eines Textkanals. Fehlen dem Bot die Rechte, steht das im Panel im Klartext („Dem Bot fehlt das Recht Kanäle verwalten") statt einer Discord-Fehlernummer. Bewusst nur Anlegen: kein Löschen, kein Umbenennen. Ein Fehlklick beim Anlegen kostet einen überflüssigen Kanal, einer beim Löschen dessen Verlauf. Umbenennen wäre zusätzlich eine Falle, weil Discord es auf zwei Änderungen pro zehn Minuten und Kanal begrenzt. moduleMissing liefert dafür Objekte statt Beschriftungen, damit das Panel weiß, was sich anlegen lässt. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
59aad27534 |
Modul-System: alle 35 Funktionen im Panel ein- und ausschaltbar
Bisher waren die Schalter über die Oberfläche verstreut: fünf Funktionen
hatten einen Haken, 22 weitere gingen nur über den Umweg „Kanal leeren".
Für jeden außer dem Owner war das nicht auffindbar.
Jetzt steht in src/modules.js ein zentrales Register aller Funktionen mit
Beschreibung, Standard-Zustand und den Einstellungen, die sie brauchen.
Daraus entsteht ein neuer Setup-Tab mit Karten: Schiebeschalter, kurze
Erklärung, Hinweis was noch fehlt ("Fehlt noch: Release-Kanal") und ein
Sprung zu den Einstellungen.
Damit die Schalter keine Attrappen sind, prüfen die Bot-Module jetzt an
18 Stellen zentral, ob sie laufen dürfen — Starboard, Galerie, Modmail,
Willkommen, Protokoll, Auto-Antworten, Sprachkanäle, Erinnerungen,
Events, Twitch/YouTube, Monitor, Wächter, Releases, Rückblick,
Geburtstage, Verlosungen und geplante Beiträge.
Funktionen mit vorhandenem Schalter (Level-System, Backups, Member-Gate …)
nutzen weiterhin dieselbe Einstellung, damit keine zweite Wahrheit
entsteht und bestehende Konfigurationen unverändert weiterlaufen.
Nebenbei gefunden und behoben: Beim Anlegen eines Modmail-Threads wurde
`member.client` benutzt, obwohl es an der Stelle kein `member` gibt — der
erste Modmail-Thread wäre mit einem Fehler abgebrochen.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|