Author SHA1 Message Date
D4rkst3randClaude Opus 5 90fefb2865 feat(zutritt): die Rollen werden gelesen, nicht abgeschrieben
Deploy / deploy (push) Canceled after 0s
Deploy / check (push) Canceled after 0s
GEMESSEN am 04.09.2026 an der Serverkonsole:

    "d4rk_discord:role" is "1439019849664696460,1544029550802108437"

ZWEI Rollen. Im Adminpanel stand seit heute frueh ein Eingabefeld, in
dem EINE davon stand. Wer nur die andere hat, kommt auf den Server -
und /whitelist status haette ihm "Whitelist-Rolle: nein" gesagt.

Das ist die Sorte Fehler, vor der der Kommentar an genau dieser Stelle
gewarnt hat, waehrend der Code daneben sie gebaut hat: zwei Orte fuer
dieselbe Wahrheit.

Was sich aendert
----------------
d4rk_lib exportiert `ZutrittRollen` - DIESELBE Parsung, die auch die
Zutrittspruefung benutzt, nicht eine zweite. Sie gibt Zutrittsrollen,
Sperrrollen, den ACE-Notausgang und ob der Discord-Token gesetzt ist
(nur ob, nie den Wert).

d4rk_web reicht das als /zutritt heraus. Nur lesend: setzen kann das
Panel es nicht, die Convar steht in secrets.cfg und wirkt erst nach
einem Serverstart. Ein Feld, das sich speichern laesst und nichts
aendert, ist schlimmer als keines.

Das Panel zeigt es an, statt es abzufragen. Das Eingabefeld ist weg;
ein bereits gespeicherter Wert bleibt unbeachtet liegen, statt beim
Start still geloescht zu werden.

Der Bot prueft gegen die MENGE, nicht gegen eine ID, und nennt die
Zahl ("ja (1 von 2)"). Die Sperrrolle wird ZUERST geprueft - sie
schlaegt jede Zutrittsrolle, und sie danach zu pruefen liesse ein "ja"
stehen fuer jemanden, der nicht hereinkommt.

KEIN RUECKFALL AUF EINE GESPEICHERTE ID mehr. Eine veraltete Liste
antwortet selbstbewusst falsch; "nicht pruefbar" ist die richtige
Antwort auf eine Frage, die man gerade nicht beantworten kann.

Gemessen nach dem Neustart:
  /zutritt -> rollen: 2, sperrrollen: 0, aceKnoten d4rk.whitelist,
              tokenGesetzt true  - deckt sich mit der Konsole

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 12:11:27 +02:00
2 changed files with 46 additions and 22 deletions
+36 -19
View File
@@ -27,23 +27,29 @@ import { SlashCommandBuilder, MessageFlags } from 'discord.js';
import { person, panelBereit, darfWhitelist, konfig } from '../../panel.js'; import { person, panelBereit, darfWhitelist, konfig } from '../../panel.js';
/* /*
DIE ROLLEN-ID STEHT IM PANEL, NICHT HIER. DIE ROLLEN WERDEN GELESEN, NICHT GEPFLEGT.
Sie ist kein Geheimnis, aber sie muss zu der passen, die der Spielserver Sie sind kein Geheimnis, aber sie müssen zu denen passen, die der
prüft (`d4rk_discord:role`) — stimmen sie nicht überein, zeigt dieser Befehl Spielserver prüft (`d4rk_discord:role`) — sonst zeigt dieser Befehl „hat die
„hat die Rolle" für eine Rolle, die den Zutritt gar nicht öffnet. Genau Rolle" für eine Rolle, die den Zutritt gar nicht öffnet.
deshalb wird sie an EINEM Ort eingetragen: auf der Einstellungsseite des
Adminpanels.
Die Umgebungsvariable bleibt als Rückfall, damit der Bot auch dann läuft, Am 04.09.2026 gemessen: die Convar enthielt ZWEI Rollen, eingetragen war
wenn das Panel gerade nicht antwortet. eine. Deshalb kommt die Menge jetzt vom Spielserver.
ES SIND MEHRERE, UND EINE REICHT. Wer eine davon hat, kommt herein — außer
er hat eine Sperrrolle, die schlägt alles. Das ist dieselbe Regel wie in
d4rk_lib; sie hier zu vereinfachen hieße, sie ein zweites Mal zu schreiben.
KEIN RÜCKFALL AUF EINE GESPEICHERTE ID. Eine veraltete Liste würde
selbstbewusst falsch antworten; „nicht prüfbar" ist die richtige Antwort auf
eine Frage, die man gerade nicht beantworten kann.
*/ */
async function whitelistRolle() { async function zutritt() {
const k = await konfig(); const k = await konfig();
if (k.ok && k.whitelistRolle) return k.whitelistRolle; if (!k.ok || k.zutrittGelesen !== true || !k.zutritt) return null;
return process.env.WHITELIST_ROLE_ID || ''; return k.zutritt;
} }
const GRUENDE = { const GRUENDE = {
@@ -113,20 +119,31 @@ export async function execute(interaction) {
Verbindung. Wer sie hier vom Server erwartet, bekommt eine Antwort, die Verbindung. Wer sie hier vom Server erwartet, bekommt eine Antwort, die
geraten wäre. geraten wäre.
*/ */
const rolle = await whitelistRolle(); const z = await zutritt();
let rolleText = 'nicht prüfbar — im Adminpanel ist keine Whitelist-Rolle eingetragen'; let rolleText = 'nicht prüfbar — der Spielserver sagt gerade nicht, welche Rollen gelten';
if (rolle) { if (z && z.rollen.length === 0) {
rolleText = 'keine Zutrittsrolle konfiguriert — die Whitelist ist offen';
} else if (z) {
const mitglied = await interaction.guild?.members const mitglied = await interaction.guild?.members
.fetch(ziel.id) .fetch(ziel.id)
.catch(() => null); .catch(() => null);
rolleText = !mitglied if (!mitglied) {
? 'nicht auf diesem Discord' rolleText = 'nicht auf diesem Discord';
: mitglied.roles.cache.has(rolle) } else {
? '**ja**' const hat = z.rollen.filter((r) => mitglied.roles.cache.has(r));
: '**nein**'; const gesperrt = (z.sperrrollen ?? []).some((r) => mitglied.roles.cache.has(r));
// DIE SPERRE ZUERST: sie schlägt die Zutrittsrolle. Sie danach zu
// nennen ließe „ja" stehen für jemanden, der nicht hereinkommt.
rolleText = gesperrt
? '**gesperrt** — eine Sperrrolle schlägt jede Zutrittsrolle'
: hat.length > 0
? `**ja** (${hat.length} von ${z.rollen.length} Zutrittsrollen)`
: `**nein** (keine von ${z.rollen.length})`;
}
} }
const k = p.konto; const k = p.konto;
+10 -3
View File
@@ -108,9 +108,16 @@ export async function darfWhitelist(discordId) {
* Die Einstellungen, die im Panel eingetragen sind. * Die Einstellungen, die im Panel eingetragen sind.
* *
* WARUM DER BOT SIE NICHT SELBST FUEHRT: sonst stuende die Whitelist-Rolle an * WARUM DER BOT SIE NICHT SELBST FUEHRT: sonst stuende die Whitelist-Rolle an
* zwei Orten — hier in der Umgebung und dort auf der Seite. Zwei Orte fuer * zwei Orten. Genau daran ist die erste Fassung gescheitert — am 04.09.2026 an
* dieselbe Wahrheit heisst, dass eine Aenderung eine der beiden vergisst, und * der Serverkonsole gemessen:
* der Fehler sieht dann aus wie „die Rolle wird nicht erkannt". *
* d4rk_discord:role = "1439019849664696460,1544029550802108437"
*
* ZWEI Rollen; eingetragen war eine. Wer nur die andere hatte, kam auf den
* Server und haette hier trotzdem „Whitelist-Rolle: nein" gelesen.
*
* Der Wert kommt deshalb aus der Convar des Spielservers, durchgereicht vom
* Panel — dieselbe Quelle, die auch ueber den Zutritt entscheidet.
* *
* Kurz gepuffert, damit nicht jeder Befehl eine Runde ueber das Netz macht. * Kurz gepuffert, damit nicht jeder Befehl eine Runde ueber das Netz macht.
* Ein Fehlschlag wird NICHT gepuffert — sonst bliebe eine Stoerung eine Minute * Ein Fehlschlag wird NICHT gepuffert — sonst bliebe eine Stoerung eine Minute