From 835d3ce998cf65c46ebb9f83336c71ba69ad4a67 Mon Sep 17 00:00:00 2001 From: MrMaho Date: Fri, 2 Oct 2026 21:07:18 +0200 Subject: [PATCH] Panel: unticking 'web panel enabled' + restart panel really turns it off (2.9.5) The restart used to refuse when the panel was disabled, so it stayed reachable. Now it stops the panel (also the relay on the game port); 'panel on|off' in the console turns it on/off and saves server.json. Co-Authored-By: Claude Opus 5.5 --- AdminPanel.cs | 9 ++++++++- GameServer.cs | 6 ++++-- MSCO.Server.csproj | 2 +- Panel/app.js | 5 +++++ Panel/i18n.js | 3 +++ ServerHost.cs | 48 ++++++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 67 insertions(+), 6 deletions(-) diff --git a/AdminPanel.cs b/AdminPanel.cs index ce69613..42c575d 100644 --- a/AdminPanel.cs +++ b/AdminPanel.cs @@ -667,7 +667,14 @@ public sealed class AdminPanel { var fresh = host.LoadConfigForRestart(); if (fresh == null) return Error(500, "Could not read server.json"); - if (!fresh.PanelEnabled) return Error(400, "The panel is turned off in the settings - turn it on again or edit server.json by hand"); + if (!fresh.PanelEnabled) + { + // "Web-Panel an" abgehakt: das Panel wird wirklich ausgeschaltet + GameServer.Log($"[panel] {by} turns the web panel off"); + _ = Task.Run(async () => { await Task.Delay(700); host.RestartPanel(fresh, by); }); + return Results.Json(new { ok = true, disabled = true, + message = "The web panel is turned off - turn it on again with 'panel on' in the server console or PanelEnabled in server.json" }); + } bool shares = fresh.PanelPort <= 0 || fresh.PanelPort == fresh.Port; int port = shares ? fresh.Port : fresh.PanelPort; string basePath = (fresh.PanelBasePath ?? "").Trim().TrimEnd('/'); diff --git a/GameServer.cs b/GameServer.cs index 65f5f68..fddd126 100644 --- a/GameServer.cs +++ b/GameServer.cs @@ -1012,8 +1012,10 @@ public sealed class GameServer SaveWorld(); break; case "panel": - if (Panel != null) Panel.PrintInfo(); - else Log("The web panel is disabled (PanelEnabled in server.json)"); + if (args.Length > 1 && (args[1] == "on" || args[1] == "off") && Host != null) + Log(Host.SetPanelEnabled(args[1] == "on", "Console")); + else if (Panel != null) Panel.PrintInfo(); + else Log("The web panel is disabled - 'panel on' turns it on"); break; case "reset-world": ResetWorld("Console"); diff --git a/MSCO.Server.csproj b/MSCO.Server.csproj index 3328808..c413179 100644 --- a/MSCO.Server.csproj +++ b/MSCO.Server.csproj @@ -7,7 +7,7 @@ enable MSCO.Server MSCO.Server - 2.9.4 + 2.9.5 MBM MSCO Dedicated Server true diff --git a/Panel/app.js b/Panel/app.js index 483ac13..390a5ea 100644 --- a/Panel/app.js +++ b/Panel/app.js @@ -323,6 +323,11 @@ async function restartPanel() { if (!ok) return; const r = await act(api("POST", "server/restart-panel")); if (!r) return; + if (r.disabled) { + // Panel ausgeschaltet: nicht auf ein Neuladen warten + document.body.replaceChildren(h("div", { class: "empty" }, r.message)); + return; + } const target = r.url && r.url !== location.origin + location.pathname ? r.url : location.href; // Warten, bis das Panel wieder antwortet, dann neu laden const started = Date.now(); diff --git a/Panel/i18n.js b/Panel/i18n.js index 37f0151..863831a 100644 --- a/Panel/i18n.js +++ b/Panel/i18n.js @@ -13,6 +13,9 @@ window.MSCO_LANG = lang; const DE = { + "The web panel is turned off - turn it on again with 'panel on' in the server console or PanelEnabled in server.json": + "Das Web-Panel ist ausgeschaltet - wieder an mit 'panel on' in der Server-Konsole oder PanelEnabled in server.json", + // Neues Spiel "New game": "Neues Spiel", "Start a completely fresh My Summer Car game instead of an uploaded save. The current save game is backed up first. The first player to join creates the new world.": diff --git a/ServerHost.cs b/ServerHost.cs index e0c2853..1dea05b 100644 --- a/ServerHost.cs +++ b/ServerHost.cs @@ -111,7 +111,9 @@ public sealed class ServerHost { bool portChanged = fresh.Port != listenerPort; Config = fresh; - Panel?.RestartWeb(fresh); + if (!fresh.PanelEnabled) { StopPanel(by); return; } // "Web-Panel an" abgehakt: wirklich ausschalten + if (Panel == null) StartPanel(); + else Panel.RestartWeb(fresh); if (!portChanged) return; if (Server != null && State == HostState.Running) RequestRestart(by); // bindet beim Start den neuen Port else Listen(fresh.Port); @@ -132,6 +134,43 @@ public sealed class ServerHost RequestExit(); } + /// Web-Panel ausschalten (Einstellung abgehakt + "Panel neu starten" oder Konsole "panel off"). + public void StopPanel(string by) + { + if (Panel == null) return; + GameServer.Log($"Web panel turned off by {by} - turn it on again with 'panel on' in the console or PanelEnabled in server.json"); + var panel = Panel; + Panel = null; + if (Server != null) Server.Panel = null; + try { panel.Stop(); } catch { } + } + + void StartPanel() + { + Panel = AdminPanel.Start(this, Config, dataDir); + if (Server != null) Server.Panel = Panel; + } + + /// Konsole "panel on|off": Einstellung speichern und Panel starten bzw. stoppen. + public string SetPanelEnabled(bool enabled, string by) + { + if (!offline) + { + try + { + var fresh = ServerConfig.LoadOrCreate(configPath, out _); + fresh.PanelEnabled = enabled; + fresh.Save(configPath); + } + catch (Exception e) { return "Could not save server.json: " + e.Message; } + } + Config.PanelEnabled = enabled; + if (!enabled) { StopPanel(by); return "Web panel turned off"; } + if (Panel == null) StartPanel(); + Panel?.PrintInfo(); + return "Web panel turned on"; + } + /// Ganzes Programm beenden (Strg+C, docker stop, "exit"). public void RequestExit() { @@ -229,8 +268,13 @@ public sealed class ServerHost GameServer.Log("The server is not running ('exit' quits the program)"); break; case "panel": - if (Panel != null) Panel.PrintInfo(); else GameServer.Log("The web panel is disabled"); + { + string arg = cmd.Split(' ').Length > 1 ? cmd.Split(' ')[1].ToLowerInvariant() : ""; + if (arg == "on" || arg == "off") GameServer.Log(SetPanelEnabled(arg == "on", "Console")); + else if (Panel != null) Panel.PrintInfo(); + else GameServer.Log("The web panel is disabled - 'panel on' turns it on"); break; + } case "status": GameServer.Log($"Server {State.ToString().ToLower()}" + (LastError != null ? ": " + LastError : "")); break;