Disconnect/kick prompt with reason, reconnect after world reset with retries; stop mass 'consumed' deletes on scene reload

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-27 16:31:40 +02:00
co-authored by Claude Opus 5.5
parent 90c1af4513
commit 31e630dccb
4 changed files with 137 additions and 38 deletions
+51 -25
View File
@@ -73,7 +73,10 @@ namespace MSCO
bool pendingJoin = mp.PendingJoinHost != null && !mp.IsInSession;
bool versionWarning = mp.PendingVersionWarning != null && !mp.IsInSession;
bool disconnected = mp.DisconnectNotice != null && !mp.IsInSession;
if (pendingJoin || versionWarning || disconnected) minimized = false; // JOIN-Link / Warnung / Trennung: Fenster zeigen
// Getrennt / Neu-Verbinden: eigenes Fenster in der Bildmitte, alles andere gesperrt
if (disconnected) { DrawPrompt(mp, false); return; }
if (mp.IsReconnecting) { DrawPrompt(mp, true); return; }
if (pendingJoin || versionWarning) minimized = false; // JOIN-Link / Warnung: Fenster zeigen
if (minimized) { DrawMinimized(mp); return; }
var window = new Rect((Screen.width - Width) / 2f, (Screen.height - Height) / 2f, Width, Height);
@@ -85,10 +88,8 @@ namespace MSCO
var content = new Rect(window.x + SidebarWidth + 32, window.y + 28,
Width - SidebarWidth - 64, Height - StatusHeight - 52);
GUILayout.BeginArea(content);
if (disconnected) DrawDisconnectNotice(mp);
else if (versionWarning) DrawVersionWarning(mp);
if (versionWarning) DrawVersionWarning(mp);
else if (pendingJoin) DrawJoinConfirm(mp);
else if (mp.IsReconnecting) DrawReconnecting(mp);
else if (mp.IsInSession) DrawSession(mp);
else if (page == Page.P2P) DrawP2P(mp);
else DrawServerBrowser(mp);
@@ -486,29 +487,54 @@ namespace MSCO
GUILayout.EndHorizontal();
}
/// <summary>Nach dem Trennen (Kick, Ban, Shutdown, Timeout ...): Grund anzeigen.</summary>
void DrawDisconnectNotice(MultiplayerManager mp)
{
GUILayout.Label("Disconnected", titleStyle);
GUILayout.Space(8);
GUILayout.BeginVertical(rowBox);
GUILayout.Space(6);
GUILayout.Label("REASON", captionStyle);
GUILayout.Label(mp.DisconnectNotice, rowNameStyle);
GUILayout.Space(6);
GUILayout.EndVertical();
GUILayout.Space(8);
GUILayout.Label("Your own save game has been restored.", textStyle);
GUILayout.FlexibleSpace();
if (GUILayout.Button("OK", primaryStyle, GUILayout.Height(42), GUILayout.Width(170))) mp.ClearDisconnectNotice();
}
const float PromptWidth = 540f;
const float PromptHeight = 270f;
Texture2D texDim, texDanger;
GUIStyle promptTextStyle;
void DrawReconnecting(MultiplayerManager mp)
/// <summary>
/// Fenster in der Bildmitte über abgedunkeltem Hintergrund: nach dem Trennen (Kick, Ban, Shutdown, Timeout ...)
/// mit Grund und OK, bzw. beim automatischen Neu-Verbinden nach reset-world mit Versuch-Anzeige und CANCEL.
/// </summary>
void DrawPrompt(MultiplayerManager mp, bool reconnecting)
{
GUILayout.Label("Reconnecting", titleStyle);
GUILayout.Space(8);
GUILayout.Label(mp.ReconnectMessage, rowNameStyle);
GUILayout.Label("You will be connected to the server again in a moment.", textStyle);
if (texDim == null) texDim = Solid(new Color(0f, 0f, 0f, 0.6f));
if (texDanger == null) texDanger = Solid(Hex(0xe5, 0x48, 0x4d));
if (promptTextStyle == null)
{
promptTextStyle = new GUIStyle(rowNameStyle);
promptTextStyle.wordWrap = true;
promptTextStyle.fontSize = 15;
}
GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), texDim);
var r = new Rect((Screen.width - PromptWidth) / 2f, (Screen.height - PromptHeight) / 2f, PromptWidth, PromptHeight);
ScreenRect = new Rect(0, 0, Screen.width, Screen.height); // Spielmenü dahinter komplett sperren
GUI.Box(r, GUIContent.none, windowBox);
string title = reconnecting ? "RECONNECTING" : mp.DisconnectTitle;
bool bad = !reconnecting && title != "DISCONNECTED";
GUI.DrawTexture(new Rect(r.x, r.y, r.width, 4), bad ? texDanger : texAccent);
float x = r.x + 32, w = r.width - 64, y = r.y + 28;
GUI.Label(new Rect(x, y, w, 34), title, titleStyle);
y += 50;
GUI.Label(new Rect(x, y, w, 20), "REASON", captionStyle);
if (reconnecting)
{
GUI.Label(new Rect(x, y + 22, w, 44), mp.ReconnectMessage ?? "", promptTextStyle);
string attempt = mp.ReconnectAttempt == 0
? "Connecting again in a moment..."
: "Attempt " + mp.ReconnectAttempt + " of " + mp.ReconnectMaxAttempts +
(string.IsNullOrEmpty(mp.Status) ? "" : " - " + mp.Status);
GUI.Label(new Rect(x, y + 74, w, 40), attempt, textStyle);
if (GUI.Button(new Rect(r.xMax - 32 - 170, r.yMax - 28 - 42, 170, 42), "CANCEL", secondaryStyle)) mp.CancelReconnect();
return;
}
GUI.Label(new Rect(x, y + 22, w, 60), mp.DisconnectNotice ?? "", promptTextStyle);
GUI.Label(new Rect(x, y + 88, w, 20), "Your own save game has been restored.", textStyle);
if (GUI.Button(new Rect(r.xMax - 32 - 170, r.yMax - 28 - 42, 170, 42), "OK", primaryStyle)) mp.ClearDisconnectNotice();
}
void DrawSession(MultiplayerManager mp)