diff --git a/src/bot/server-monitor.js b/src/bot/server-monitor.js index 78bceb2..728da0c 100644 --- a/src/bot/server-monitor.js +++ b/src/bot/server-monitor.js @@ -392,10 +392,14 @@ export async function monitorTick(client) { // gibt ohne eingetragene Adresse sofort null zurück. const panelItems = await panelStatus(); if (panelItems) { - const { angelegt, entfernt } = abgleichen(panelItems); + const { angelegt, uebernommen, entfernt } = abgleichen(panelItems); if (entfernt.length > 0) await embedWegraeumen(client, entfernt); - if (angelegt.length > 0 || entfernt.length > 0) { - console.log(`[panel] übernommen: ${angelegt.join(', ') || '—'} | entfernt: ${entfernt.map((e) => e.name).join(', ') || '—'}`); + if (angelegt.length + uebernommen.length + entfernt.length > 0) { + console.log( + `[panel] neu: ${angelegt.join(', ') || '—'}` + + ` | uebernommen: ${uebernommen.join(', ') || '—'}` + + ` | entfernt: ${entfernt.map((e) => e.name).join(', ') || '—'}`, + ); } } diff --git a/src/panel-abgleich.js b/src/panel-abgleich.js index 0c320d8..8d9979e 100644 --- a/src/panel-abgleich.js +++ b/src/panel-abgleich.js @@ -12,12 +12,19 @@ // Schalters dazu, wie lange es dauert. Ein Knopf, der scheinbar nichts tut, // wird dreimal gedrückt. // -// WAS HIER NICHT PASSIERT: ein bestehender Eintrag wird nicht angefasst. Wer -// im Webinterface ein Bild, einen Verbinden-Link oder Regeln ergänzt hat, soll -// das nicht beim nächsten Durchlauf verlieren. Angelegt und gelöscht wird, -// mehr nicht. +// WAS HIER NICHT PASSIERT: kein Feld eines bestehenden Eintrags wird +// überschrieben. Wer im Webinterface ein Bild, einen Verbinden-Link oder Regeln +// ergänzt hat, soll das nicht beim nächsten Durchlauf verlieren. Angelegt, +// übernommen und gelöscht wird — mehr nicht. +// +// „Übernommen" heißt: gab es den Server schon von Hand, bekommt er nur den +// Herkunftsvermerk. Sonst täte der Schalter im Panel sichtbar nichts, und +// genau das ist dem Betreiber passiert. -import { listGameservers, createGameserver, deleteGameserver, getSetting } from './db.js'; +import { listGameservers, createGameserver, deleteGameserver, getSetting, db } from './db.js'; + +/** Einen bestehenden Eintrag dem Panel zuschreiben -- ohne ihn sonst anzufassen. */ +const uebernehmenStmt = db.prepare('UPDATE gameservers SET panel_name = ? WHERE id = ?'); /** * Taugt dieser Panel-Eintrag für einen Monitor-Eintrag? @@ -34,12 +41,13 @@ export function taugt(x) { /** * Einmal abgleichen. * - * @returns {{angelegt: string[], entfernt: Array<{id: number, name: string, message_id: string|null}>}} + * @returns {{angelegt: string[], uebernommen: string[], + * entfernt: Array<{id: number, name: string, message_id: string|null}>}} * Die Entfernten kommen mit ihrer Nachrichten-Kennung zurück, damit * der Aufrufer das Embed löschen kann — hier gibt es keinen Client. */ export function abgleichen(items) { - const ergebnis = { angelegt: [], entfernt: [] }; + const ergebnis = { angelegt: [], uebernommen: [], entfernt: [] }; if (!Array.isArray(items)) return ergebnis; const vorhanden = listGameservers(); @@ -48,13 +56,33 @@ export function abgleichen(items) { for (const x of items) { if (!taugt(x) || ausPanel.has(x.name)) continue; - // Ein von Hand angelegter Server auf demselben Port ist schon da — - // dann NICHT noch einmal. Sonst stünde derselbe Server zweimal im - // Kanal, und niemand wüsste, welches Embed das richtige ist. + // Ein Server auf derselben Adresse und demselben Port ist schon da — + // dann NICHT noch einmal anlegen. Sonst stünde derselbe Server zweimal + // im Kanal, und niemand wüsste, welches Embed das richtige ist. + // + // ABER AUCH NICHT EINFACH ÜBERGEHEN. Vorher stand hier `continue`, und + // damit tat der Schalter im Panel sichtbar nichts, sobald der Server + // schon von Hand eingetragen war — keine Meldung, kein Embed, keine + // Spur. Genau so ist es dem Betreiber gegangen, und er hat den Fehler + // erst bei sich gesucht. + // + // Wer den Schalter umlegt, sagt „dieser Server gehört ans Panel". Also + // wird der bestehende Eintrag übernommen statt ignoriert. + // + // Der Preis gehört benannt: ab dann nimmt ein Ausschalten den Eintrag + // mit, samt Bild und Links, die von Hand daran hängen. Das ist der Sinn + // des Schalters — aber es ist eine Übertragung von Besitz und keine + // Kleinigkeit. const dasselbe = vorhanden.find( (s) => Number(s.port) === Number(x.port) && String(s.host) === String(x.adresse), ); - if (dasselbe) continue; + if (dasselbe) { + if (!dasselbe.panel_name) { + uebernehmenStmt.run(x.name, dasselbe.id); + ergebnis.uebernommen.push(x.name); + } + continue; + } createGameserver({ name: x.name, diff --git a/tools/panel-abgleich-pruefen.mjs b/tools/panel-abgleich-pruefen.mjs index 3c34b6b..c4c4707 100644 --- a/tools/panel-abgleich-pruefen.mjs +++ b/tools/panel-abgleich-pruefen.mjs @@ -79,10 +79,25 @@ zeig(a.entfernt.length === 1 && a.entfernt[0].name === 'p1', 'entfernt wird nur, zeig(!db.listGameservers().some((s) => s.name === 'p1'), 'und der ist wirklich weg'); console.log(''); -console.log('=== Ein bestehender Eintrag wird nicht verdoppelt'); -// Derselbe Server, den es von Hand schon gibt: gleiche Adresse, gleicher Port. -a = abgleichen([panel({ name: 'ATM10 im Panel', adresse: '9.9.9.9', port: 25565 })]); +console.log('=== Ein bestehender Eintrag wird UEBERNOMMEN, nicht verdoppelt'); +// Der Fall aus dem Betrieb: der Server stand schon von Hand im Monitor, und +// dann wurde im Panel der Schalter umgelegt. Vorher passierte sichtbar nichts +// -- kein Embed, keine Meldung, keine Spur -- und der Betreiber hat den Fehler +// bei sich gesucht. +a = abgleichen([panel({ name: 'ATM10', adresse: '9.9.9.9', port: 25565 })]); zeig(a.angelegt.length === 0, 'gleiche Adresse und gleicher Port -> kein zweites Embed im Kanal'); +zeig(a.uebernommen.includes('ATM10'), 'sondern uebernommen -- der Schalter tut sichtbar etwas', a.uebernommen.join()); +const nun = db.getGameserver(handId); +zeig(nun.panel_name === 'ATM10', 'die Herkunft steht jetzt auf dem Panel', nun.panel_name); +zeig(nun.image_url === 'https://bild' && nun.links?.length === 1, 'Bild und Links bleiben dabei unangetastet'); +a = abgleichen([panel({ name: 'ATM10', adresse: '9.9.9.9', port: 25565 })]); +zeig(a.uebernommen.length === 0, 'ein zweiter Durchlauf uebernimmt ihn nicht noch einmal'); +// Und ab jetzt raeumt das Panel ihn auch wieder weg -- das ist der Preis der +// Uebernahme, und er gehoert geprueft. +a = abgleichen([]); +zeig(a.entfernt.some((e) => e.name === 'ATM10'), 'ausgeschaltet -> jetzt raeumt das Panel ihn weg'); +// Fuer die folgenden Abschnitte wieder von Hand anlegen. +db.createGameserver({ name: 'ATM10', type: 'minecraft', host: '9.9.9.9', port: 25565, address: '9.9.9.9:25565' }); console.log(''); console.log('=== Bearbeiten im Webinterface nimmt die Herkunft nicht');