66 lines
2.3 KiB
JavaScript
66 lines
2.3 KiB
JavaScript
'use strict';
|
||
|
||
/*
|
||
* modschalter.js – Mods im laufenden Spiel an- und abschalten
|
||
* ------------------------------------------------------------
|
||
* Im Pausemenü wird „Feedback geben“ zu „Mods verwalten“ (siehe
|
||
* agent/ModsUmbau.java). Ein Klick ruft eine Adresse dieses kleinen, nur lokal
|
||
* erreichbaren Empfängers auf; der Launcher öffnet daraufhin das Mod-Fenster
|
||
* über dem Spiel.
|
||
*
|
||
* Solange Minecraft läuft, sind die Mod-Dateien gesperrt und geladene Mods
|
||
* lassen sich ohnehin nicht entladen. Änderungen werden deshalb vorgemerkt
|
||
* (instance.json -> modsAusstehend) und beim Beenden umgesetzt – das Spiel
|
||
* läuft weiter, beim nächsten Start gilt der neue Stand.
|
||
*/
|
||
|
||
const http = require('http');
|
||
const crypto = require('crypto');
|
||
|
||
let server = null;
|
||
let port = 0;
|
||
const sitzungen = new Map(); // token -> { instanceId, pid }
|
||
let beimKlick = null; // (sitzung) => void
|
||
|
||
function starteServer() {
|
||
if (server) return Promise.resolve(port);
|
||
return new Promise((resolve, reject) => {
|
||
server = http.createServer((req, res) => {
|
||
const m = /^\/mods\/([a-f0-9]{32})$/.exec(req.url || '');
|
||
const s = m && sitzungen.get(m[1]);
|
||
if (!s) { res.writeHead(404); res.end(); return; }
|
||
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||
res.end('ok');
|
||
if (beimKlick) { try { beimKlick(s); } catch (err) { console.error('Mod-Schalter:', err); } }
|
||
});
|
||
server.on('error', (err) => { server = null; reject(err); });
|
||
server.listen(0, '127.0.0.1', () => { port = server.address().port; resolve(port); });
|
||
});
|
||
}
|
||
|
||
/** Neue Sitzung für einen Spielstart -> { token, adresse } (für das Agent-Argument) */
|
||
async function neueSitzung(instanceId) {
|
||
await starteServer();
|
||
const token = crypto.randomBytes(16).toString('hex');
|
||
sitzungen.set(token, { instanceId, pid: null, token });
|
||
return { token, adresse: `http://127.0.0.1:${port}/mods/${token}` };
|
||
}
|
||
|
||
function setzePid(token, pid) {
|
||
const s = sitzungen.get(token);
|
||
if (s) s.pid = pid;
|
||
}
|
||
|
||
function beende(token) {
|
||
sitzungen.delete(token);
|
||
}
|
||
|
||
function sitzungFuer(instanceId) {
|
||
for (const s of sitzungen.values()) if (s.instanceId === instanceId && s.pid) return s;
|
||
return null;
|
||
}
|
||
|
||
function beiKlick(fn) { beimKlick = fn; }
|
||
|
||
module.exports = { neueSitzung, setzePid, beende, sitzungFuer, beiKlick };
|