2.10.11: security levels (no joining servers/hosts below the required level, OUTDATED in the browser), announcements and maintenance notice from the keymaster in the MSCO menu

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 20:26:52 +02:00
co-authored by Claude Opus 5.5
parent ceaa2e29aa
commit 8bac7d194a
6 changed files with 263 additions and 4 deletions
+35
View File
@@ -71,6 +71,10 @@ namespace MSCO
const float NeedsInterval = 10f;
void ToastJoined(string name) { toasts.Add(name, "joined the game", UiTheme.Online); }
const string OutdatedServerText = "This server is outdated - it is missing MSCO security updates. You can join again once its owner has updated it (web panel -> Update).";
const string OutdatedHostText = "The host uses an outdated MSCO version that is missing security updates. Ask them to update " +
"MSCO (start the game once through the MSCO Launcher), then join again.";
void ToastLeft(string name) { toasts.Add(name, "left the game", UiTheme.Muted); }
readonly Overlays overlays = new Overlays();
bool isAdmin; // Server hat uns als Admin gemeldet
@@ -108,6 +112,13 @@ namespace MSCO
{
Application.runInBackground = true;
playerName = PlayerPrefs.GetString(PrefName, System.Environment.UserName);
// Neue Ankündigung der MSCO-Admins, während man spielt: kurz einblenden und in die Konsole (F7)
SiteStatus.NewAnnouncement += a =>
{
toasts.Add(a.Title, a.Level == "critical" ? "Important announcement" : "MSCO announcement",
a.Level == "critical" ? UiTheme.Danger : a.Level == "warning" ? UiTheme.Gold : UiTheme.Accent);
MscoLog.Info("[MSCO] Announcement: " + a.Title + (string.IsNullOrEmpty(a.Text) ? "" : " - " + a.Text));
};
objects.Send = SendGame;
// Einkäufe / verbrauchte Items bei uns: allen melden
objects.ItemAppeared = b =>
@@ -755,6 +766,13 @@ namespace MSCO
}
string name = string.IsNullOrEmpty(displayName) ? info.Name : displayName;
int max = info.MaxPlayers > 0 ? info.MaxPlayers : maxPlayers;
// Fehlen dem Server Sicherheitsupdates, nicht beitreten (auch nicht nach Rückfrage)
if (info.Security < SiteStatus.RequiredServerSecurity)
{
DisconnectNotice = OutdatedServerText;
SetStatus("Server " + name + " is outdated (security level " + info.Security + ", required " + SiteStatus.RequiredServerSecurity + ")");
yield break;
}
if (!MSCO.Compatible(info.Version))
{
@@ -1045,6 +1063,7 @@ namespace MSCO
void Update()
{
CheckHitch();
SiteStatus.Tick(); // Ankündigungen, Wartung, Mindest-Sicherheitsstufe vom Keymaster
CheckJoinRequest();
// JOIN im Server-Browser (Launcher/Website): ohne Rückfrage verbinden, sobald das Hauptmenü steht.
// Server-Mods fragen weiterhin extra nach (das sind Programme).
@@ -1319,6 +1338,7 @@ namespace MSCO
if (r.Contains("kick")) return "KICKED";
if (r.Contains("shutting down") || r.Contains("server stopped") || r.Contains("shut down")) return "SERVER CLOSED";
if (r.Contains("could not reconnect")) return "RECONNECT FAILED";
if (r.Contains("outdated")) return "UPDATE REQUIRED"; // Server/Host ohne Sicherheitsupdates
return "DISCONNECTED";
}
}
@@ -1509,6 +1529,9 @@ namespace MSCO
w.Write(false); // kein dedizierter Server
w.Write(list.Count);
foreach (PlayerInfo p in list) { w.Write(p.Id); w.Write(p.Name); }
// Unsere Sicherheitsstufe (aktuelle Mods treten veralteten Hosts nicht bei)
w.Write(MSCO.SecurityLevel);
w.Write(MSCO.ModVersion);
}));
session.SendToAll(MsgType.PlayerJoined, NetSession.Build(w => { w.Write(peerId); w.Write(name); }), peerId);
ToastJoined(name);
@@ -1548,6 +1571,18 @@ namespace MSCO
int id = r.ReadInt32();
AddPlayer(id, r.ReadString(), id == localId);
}
// Sicherheitsstufe des Servers/Hosts (ältere schicken sie nicht = 0): darunter gleich wieder gehen
int level = r.BaseStream.Position < r.BaseStream.Length ? r.ReadInt32() : 0;
if (level < SiteStatus.RequiredServerSecurity)
{
MscoLog.Warning("[MSCO] " + (dedicated ? "Server" : "Host") + " has security level " + level + ", required " +
SiteStatus.RequiredServerSecurity + " - leaving");
serverReason = dedicated ? OutdatedServerText : OutdatedHostText;
reconnectMessage = null; // nicht immer wieder versuchen
session.Close("Outdated " + (dedicated ? "server" : "host"));
OnSessionEnded(session.CloseReason);
return;
}
handshakeDone = true;
reconnectMessage = null; // (wieder) verbunden
reconnectAttempts = 0;