Panel: warn before changing the game/panel port (needs a full program restart, Docker port mapping, how to undo) so nobody locks themselves out

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Nico Meister
2026-09-29 19:26:31 +02:00
co-authored by Claude Opus 5.5
parent 1ff37065d0
commit ad2dac21ba
4 changed files with 58 additions and 4 deletions
+37 -1
View File
@@ -356,6 +356,9 @@ function renderSettings(page) {
if (typeof v === "number" && isNaN(v)) continue;
body[k] = v;
}
// Port geändert? Vorher warnen - sonst sperrt man sich aus (vor allem in Docker, wo der Port nicht freigegeben ist)
const warning = portChangeWarning(c, body);
if (warning && !(await modal({ title: warning.title, text: warning.text, confirm: warning.confirm }))) return;
if (await act(api("POST", "config", body))) load();
};
@@ -378,7 +381,8 @@ function renderSettings(page) {
h("div", { class: "section-head" }, h("h2", {}, "Network & panel"), h("span", { class: "muted" }, "needs a restart")),
h("div", { class: "section-body form-grid wide" },
number("port", "Game port", c.port, { min: 1, max: 65535, restart: true }),
number("panelPort", "Panel port", c.panelPort, { min: 0, max: 65535, restart: true, hint: "0 = same port as the game (recommended)" }),
number("panelPort", "Panel port", c.panelPort, { min: 0, max: 65535, restart: true,
hint: c.inDocker ? "0 = same port as the game (recommended). Docker: another port must also be published in docker-compose.yml" : "0 = same port as the game (recommended)" }),
text("panelBindAddress", "Panel bind address", c.panelBindAddress, { max: 60, restart: true, hint: "only with an own panel port - 127.0.0.1 = only via a local reverse proxy" }),
text("panelBasePath", "Panel sub path", c.panelBasePath, { max: 60, restart: true, placeholder: "/", hint: "e.g. /panel when the proxy serves it there" }),
toggle("panelTrustProxy", "Behind a reverse proxy", c.panelTrustProxy, "Trust X-Forwarded-For / -Proto / -Prefix", true),
@@ -396,6 +400,38 @@ function renderSettings(page) {
}
}
/**
* Warnung, wenn Spiel- oder Panel-Port geändert werden: Ports übernimmt erst ein Neustart des ganzen Programms
* (der Restart-Knopf startet nur den Gameserver neu), danach ist das Panel nur noch am neuen Port - in Docker nur,
* wenn der Port in docker-compose.yml freigegeben ist. Text direkt in beiden Sprachen (enthält Zahlen).
*/
function portChangeWarning(c, body) {
const panelAt = (port, panelPort) => (panelPort > 0 ? panelPort : port);
const port = body.port ?? c.port, panelPort = body.panelPort ?? c.panelPort;
const oldPanel = panelAt(c.port, c.panelPort), newPanel = panelAt(port, panelPort);
if (port === c.port && newPanel === oldPanel) return null;
const de = window.MSCO_LANG === "de";
const lines = [];
if (newPanel !== oldPanel)
lines.push(de
? `Das Panel ist danach nur noch unter Port ${newPanel} erreichbar (http://<server>:${newPanel}/), nicht mehr unter ${oldPanel}.`
: `Afterwards the panel is only reachable on port ${newPanel} (http://<server>:${newPanel}/), no longer on ${oldPanel}.`);
if (port !== c.port)
lines.push(de ? `Spieler verbinden sich dann über Port ${port}.` : `Players then connect on port ${port}.`);
lines.push(de
? "Das gilt erst nach einem Neustart des ganzen Programms (docker compose restart) - der Neustart-Knopf startet nur den Gameserver neu."
: "This only applies after the whole program restarts (docker compose restart) - the Restart button only restarts the game server.");
const ports = [...new Set([port, newPanel])].map((p) => `"${p}:${p}/tcp"`).join(", ");
lines.push(c.inDocker
? (de ? `Docker: trag vorher unter ports in docker-compose.yml ${ports} ein, sonst sperrst du dich aus.`
: `Docker: first add ${ports} under ports in docker-compose.yml, otherwise you lock yourself out.`)
: (de ? "Gib den Port in der Firewall frei." : "Open the port in your firewall."));
lines.push(de
? 'Rückgängig: in data/server.json "PanelPort": 0 setzen und neu starten.'
: 'To undo: set "PanelPort": 0 in data/server.json and restart.');
return { title: de ? "Port ändern?" : "Change the port?", text: lines.join(" "), confirm: de ? "Trotzdem speichern" : "Save anyway" };
}
// ------------------------------------------------------------------ Spieler
function renderPlayers(page) {