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>
This commit is contained in:
@@ -986,6 +986,40 @@ const playerHistoryStmt = db.prepare(`
|
||||
WHERE server_id = ? AND ts >= datetime('now', ?) ORDER BY ts
|
||||
`);
|
||||
const prunePlayerHistoryStmt = db.prepare(`DELETE FROM player_history WHERE ts < datetime('now', '-7 days')`);
|
||||
|
||||
// LS-Modul: das gepflegte Karten-Embed und der letzte Besitzstand je Server.
|
||||
// Der Besitzstand ist nur da, um Käufe zu erkennen — ohne ihn müsste beim
|
||||
// Start jede bereits gekaufte Parzelle als „neu gekauft" gemeldet werden.
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS ls_state (
|
||||
server_id INTEGER PRIMARY KEY,
|
||||
message_id TEXT,
|
||||
besitz TEXT,
|
||||
geprueft TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
`);
|
||||
const lsStateStmt = db.prepare('SELECT * FROM ls_state WHERE server_id = ?');
|
||||
const lsMessageStmt = db.prepare(`
|
||||
INSERT INTO ls_state (server_id, message_id) VALUES (?, ?)
|
||||
ON CONFLICT(server_id) DO UPDATE SET message_id = excluded.message_id
|
||||
`);
|
||||
const lsBesitzStmt = db.prepare(`
|
||||
INSERT INTO ls_state (server_id, besitz, geprueft) VALUES (?, ?, datetime('now'))
|
||||
ON CONFLICT(server_id) DO UPDATE SET besitz = excluded.besitz, geprueft = datetime('now')
|
||||
`);
|
||||
const lsVergessenStmt = db.prepare('DELETE FROM ls_state WHERE server_id = ?');
|
||||
export const lsState = (serverId) => {
|
||||
const r = lsStateStmt.get(serverId);
|
||||
if (!r) return null;
|
||||
// Kaputtes JSON darf den Durchlauf nicht anhalten — dann gilt eben
|
||||
// "noch nichts bekannt" und beim nächsten Mal steht wieder etwas drin.
|
||||
let besitz = null;
|
||||
try { besitz = r.besitz ? JSON.parse(r.besitz) : null; } catch { besitz = null; }
|
||||
return { ...r, besitz };
|
||||
};
|
||||
export const setLsMessage = (serverId, messageId) => lsMessageStmt.run(serverId, messageId);
|
||||
export const setLsBesitz = (serverId, besitz) => lsBesitzStmt.run(serverId, JSON.stringify(besitz));
|
||||
export const forgetLsState = (serverId) => lsVergessenStmt.run(serverId).changes > 0;
|
||||
// Erreichbarkeit stundenweise zusammengefasst — für den Uptime-Balken.
|
||||
// Die Rohdaten (alle 2 min) wären über eine Woche rund 5000 Zeilen pro Server;
|
||||
// als Stundeneimer sind es höchstens 168 und die Seite bleibt schlank.
|
||||
|
||||
Reference in New Issue
Block a user