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;