Favorites: heart toggle, Favorites tab with nicknames, /switch <nickname> quick server switch, fav command
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,12 @@ Server und Mod müssen beide 2.8 sein (Server: `git pull && docker compose up -d
|
||||
- **Backups** mit Datum/Uhrzeit, **RESTORE** holt einen älteren Stand zurück (der aktuelle wird vorher gesichert)
|
||||
- Jede Aktion mit Sicherheitsabfrage; nur für Admins (vom Server geprüft)
|
||||
|
||||
**Favoriten**
|
||||
- Herz neben jedem Server (Liste und Profil) merkt ihn als Favorit
|
||||
- Neuer Tab **Favorites**: jedem Server einen eigenen Kurznamen geben, beitreten, entfernen, per Adresse hinzufügen
|
||||
- Schnell wechseln: `/switch <kurzname>` im Chat oder `switch <kurzname>` in der F7-Konsole – trennt und verbindet
|
||||
direkt mit dem anderen Server; `fav` listet alle, `fav add <name>` merkt den aktuellen Server
|
||||
|
||||
**Pro Spieler**
|
||||
- Hunger, Durst, Stress, Harndrang, Müdigkeit und Schmutz werden für jeden Spieler einzeln auf dem Server gespeichert
|
||||
und beim Beitreten zurückgegeben (nicht mehr die Werte aus dem gemeinsamen Spielstand)
|
||||
|
||||
+44
@@ -10,6 +10,10 @@ namespace MSCO
|
||||
{
|
||||
public const string Help =
|
||||
"connect <host[:port]> - join a dedicated server\n" +
|
||||
"switch <nickname> - quickly switch to a favorite server (also /switch in chat)\n" +
|
||||
"fav - list your favorite servers\n" +
|
||||
"fav add <nick> [host:port] - add a favorite (without address: the server you are on)\n" +
|
||||
"fav remove <nick> - remove a favorite\n" +
|
||||
"disconnect - leave the server / game\n" +
|
||||
"host [port] / join <ip> [port] - direct LAN game (no Steam)\n" +
|
||||
"save - save the game (host / singleplayer)\n" +
|
||||
@@ -19,6 +23,37 @@ namespace MSCO
|
||||
"debug - toggle sync debug output\n" +
|
||||
"clear - clear this console";
|
||||
|
||||
static void Favorite(MultiplayerManager mp, string[] args, Action<string> print)
|
||||
{
|
||||
string sub = args.Length > 1 ? args[1].ToLower() : "list";
|
||||
if (sub == "list")
|
||||
{
|
||||
if (Favorites.All.Count == 0) { print("No favorites yet - open a server in the browser and press FAVORITE, or: fav add <nick>"); return; }
|
||||
foreach (Favorites.Favorite f in Favorites.All)
|
||||
print(" " + f.Nickname + " -> " + f.Address + (string.IsNullOrEmpty(f.ServerName) ? "" : " (" + f.ServerName + ")"));
|
||||
print("switch <nickname> to join one");
|
||||
return;
|
||||
}
|
||||
if (sub == "add" || sub == "set")
|
||||
{
|
||||
if (args.Length < 3) { print("fav add <nickname> [host:port]"); return; }
|
||||
string host = mp.CurrentServerHost, name = mp.CurrentServerName;
|
||||
int port = mp.CurrentServerPort;
|
||||
if (args.Length > 3 && !ServerBrowser.TryParseAddress(args[3], out host, out port)) { print("Invalid address: " + args[3]); return; }
|
||||
if (host == null) { print("You are not on a server - use: fav add <nickname> <host:port>"); return; }
|
||||
string error = Favorites.Set(args[2], host, port, name);
|
||||
print(error ?? "Favorite '" + Favorites.CleanNickname(args[2]) + "' saved (" + host + ":" + port + ")");
|
||||
return;
|
||||
}
|
||||
if (sub == "remove" || sub == "del" || sub == "delete")
|
||||
{
|
||||
Favorites.Favorite f = args.Length > 2 ? Favorites.Find(args[2]) : null;
|
||||
print(f != null && Favorites.Remove(f) ? "Favorite '" + f.Nickname + "' removed" : "No such favorite");
|
||||
return;
|
||||
}
|
||||
print("fav | fav add <nick> [host:port] | fav remove <nick>");
|
||||
}
|
||||
|
||||
public static void Execute(string[] args, Action<string> print)
|
||||
{
|
||||
var mp = MultiplayerManager.Instance;
|
||||
@@ -59,6 +94,15 @@ namespace MSCO
|
||||
mp.JoinServer(host, serverPort);
|
||||
break;
|
||||
}
|
||||
case "switch":
|
||||
case "sw":
|
||||
print(mp.SwitchServer(args.Length > 1 ? args[1] : ""));
|
||||
break;
|
||||
case "fav":
|
||||
case "favs":
|
||||
case "favorites":
|
||||
Favorite(mp, args, print);
|
||||
break;
|
||||
case "save":
|
||||
mp.SaveGame();
|
||||
break;
|
||||
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MSCO
|
||||
{
|
||||
/// <summary>
|
||||
/// Lieblings-Server mit eigenem Kurznamen (z.B. "mbm"). Gespeichert in den PlayerPrefs, eine Zeile pro Server:
|
||||
/// Kurzname, Adresse, Port, Servername (Tab-getrennt). Mit "switch <kurzname>" wechselt man schnell den Server.
|
||||
/// </summary>
|
||||
public static class Favorites
|
||||
{
|
||||
public class Favorite
|
||||
{
|
||||
public string Nickname;
|
||||
public string Host;
|
||||
public int Port;
|
||||
public string ServerName;
|
||||
public string Address { get { return Host + ":" + Port; } }
|
||||
}
|
||||
|
||||
const string Pref = "MSCO_Favorites";
|
||||
const int MaxFavorites = 30;
|
||||
static List<Favorite> list;
|
||||
|
||||
public static List<Favorite> All { get { Load(); return list; } }
|
||||
|
||||
static void Load()
|
||||
{
|
||||
if (list != null) return;
|
||||
list = new List<Favorite>();
|
||||
string raw = PlayerPrefs.GetString(Pref, "");
|
||||
foreach (string line in raw.Split('\n'))
|
||||
{
|
||||
string[] p = line.Split('\t');
|
||||
int port;
|
||||
if (p.Length < 3 || p[0].Length == 0 || p[1].Length == 0 || !int.TryParse(p[2], out port)) continue;
|
||||
list.Add(new Favorite { Nickname = p[0], Host = p[1], Port = port, ServerName = p.Length > 3 ? p[3] : "" });
|
||||
}
|
||||
}
|
||||
|
||||
static void Save()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (Favorite f in list)
|
||||
sb.Append(Clean(f.Nickname)).Append('\t').Append(Clean(f.Host)).Append('\t').Append(f.Port).Append('\t').Append(Clean(f.ServerName)).Append('\n');
|
||||
PlayerPrefs.SetString(Pref, sb.ToString());
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
|
||||
static string Clean(string s) { return (s ?? "").Replace("\t", " ").Replace("\n", " ").Trim(); }
|
||||
|
||||
/// <summary>Kurzname: Buchstaben, Zahlen, - und _ (ohne Leerzeichen, damit "switch name" eindeutig ist).</summary>
|
||||
public static string CleanNickname(string nickname)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (char c in (nickname ?? "").Trim())
|
||||
if (char.IsLetterOrDigit(c) || c == '-' || c == '_') sb.Append(c);
|
||||
string s = sb.ToString();
|
||||
return s.Length > 20 ? s.Substring(0, 20) : s;
|
||||
}
|
||||
|
||||
public static Favorite Find(string nickname)
|
||||
{
|
||||
Load();
|
||||
return list.Find(f => string.Equals(f.Nickname, nickname, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
public static Favorite FindByAddress(string host, int port)
|
||||
{
|
||||
Load();
|
||||
return list.Find(f => f.Port == port && string.Equals(f.Host, host, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
/// <summary>Hinzufügen oder (gleiche Adresse) umbenennen. Gibt einen Fehler zurück oder null.</summary>
|
||||
public static string Set(string nickname, string host, int port, string serverName)
|
||||
{
|
||||
Load();
|
||||
nickname = CleanNickname(nickname);
|
||||
if (nickname.Length == 0) return "Nickname: letters, numbers, - and _";
|
||||
if (string.IsNullOrEmpty(host) || port <= 0 || port > 65535) return "Invalid server address";
|
||||
Favorite sameName = Find(nickname);
|
||||
Favorite existing = FindByAddress(host, port);
|
||||
if (sameName != null && sameName != existing) return "The nickname '" + nickname + "' is already used for " + sameName.Address;
|
||||
if (existing == null)
|
||||
{
|
||||
if (list.Count >= MaxFavorites) return "Too many favorites (max " + MaxFavorites + ")";
|
||||
existing = new Favorite { Host = host, Port = port };
|
||||
list.Add(existing);
|
||||
}
|
||||
existing.Nickname = nickname;
|
||||
if (!string.IsNullOrEmpty(serverName)) existing.ServerName = serverName;
|
||||
Save();
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool Remove(Favorite f)
|
||||
{
|
||||
Load();
|
||||
if (f == null || !list.Remove(f)) return false;
|
||||
Save();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>Vorschlag für den Kurznamen aus dem Servernamen (erstes Wort, klein).</summary>
|
||||
public static string SuggestNickname(string serverName)
|
||||
{
|
||||
string first = (serverName ?? "").Trim().Split(' ')[0];
|
||||
string nick = CleanNickname(first).ToLower();
|
||||
return nick.Length > 0 ? nick : "server";
|
||||
}
|
||||
}
|
||||
}
|
||||
+183
-2
@@ -10,7 +10,7 @@ namespace MSCO
|
||||
/// </summary>
|
||||
public class LobbyUI
|
||||
{
|
||||
enum Page { P2P, ServerBrowser }
|
||||
enum Page { P2P, ServerBrowser, Favorites }
|
||||
|
||||
const float Width = 760f;
|
||||
const float Height = 460f;
|
||||
@@ -40,6 +40,10 @@ namespace MSCO
|
||||
string selectedServer; // "adresse:port" des geöffneten Server-Profils
|
||||
string searchInput = "";
|
||||
bool showSteam = true, showNonSteam = true, hideFull;
|
||||
readonly Dictionary<string, string> nicknameEdits = new Dictionary<string, string>(); // Favoriten-Tab: Adresse -> bearbeiteter Kurzname
|
||||
string favoriteAddInput = "";
|
||||
Vector2 favoritesScroll;
|
||||
Texture2D texHeartOn, texHeartOff;
|
||||
string nameInput;
|
||||
string directInput;
|
||||
const string PrefDirect = "MSCO_LastServer";
|
||||
@@ -92,6 +96,7 @@ namespace MSCO
|
||||
else if (pendingJoin) DrawJoinConfirm(mp);
|
||||
else if (mp.IsInSession) DrawSession(mp);
|
||||
else if (page == Page.P2P) DrawP2P(mp);
|
||||
else if (page == Page.Favorites) DrawFavorites(mp);
|
||||
else DrawServerBrowser(mp);
|
||||
GUILayout.EndArea();
|
||||
|
||||
@@ -118,6 +123,9 @@ namespace MSCO
|
||||
if (NavButton(new Rect(r.x, y, r.width, 42), "P2P", page == Page.P2P)) page = Page.P2P;
|
||||
y += 44;
|
||||
if (NavButton(new Rect(r.x, y, r.width, 42), "Server Browser", page == Page.ServerBrowser)) page = Page.ServerBrowser;
|
||||
y += 44;
|
||||
int favCount = Favorites.All.Count;
|
||||
if (NavButton(new Rect(r.x, y, r.width, 42), "Favorites" + (favCount > 0 ? " (" + favCount + ")" : ""), page == Page.Favorites)) page = Page.Favorites;
|
||||
|
||||
// Eigenes Hauptmenü: Spiel beenden (die Knöpfe des Spiel-Menüs sind ausgeblendet)
|
||||
if (quitConfirm)
|
||||
@@ -232,12 +240,17 @@ namespace MSCO
|
||||
Rect row = GUILayoutUtility.GetRect(10, 34, GUILayout.ExpandWidth(true));
|
||||
GUI.Box(new Rect(row.x, row.y + 2, row.width, row.height - 4), GUIContent.none, rowBox);
|
||||
|
||||
// Herz: als Favorit merken / entfernen (vor dem Zeilen-Knopf, damit es den Klick bekommt)
|
||||
Heart(new Rect(row.xMax - 58, row.y + 7, 20, 20), s);
|
||||
|
||||
// Klick auf die Zeile öffnet das Server-Profil (dort wird verbunden)
|
||||
if (GUI.Button(new Rect(row.x, row.y, row.width, row.height), GUIContent.none, GUIStyle.none))
|
||||
selectedServer = s.Address + ":" + s.Port;
|
||||
|
||||
GUI.DrawTexture(new Rect(row.x + 10, row.y + 13, 8, 8), s.Ping < 0 ? texPending : texOnline);
|
||||
float nameX = row.x + 26;
|
||||
Favorites.Favorite fav = Favorites.FindByAddress(s.Address, s.Port);
|
||||
if (fav != null) nameX += Pill(nameX, row, fav.Nickname, pillMutedStyle);
|
||||
if (s.IsLocal)
|
||||
{
|
||||
// Server auf diesem PC (localhost)
|
||||
@@ -302,6 +315,168 @@ namespace MSCO
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------- Favoriten
|
||||
|
||||
/// <summary>Herz: gefüllt = Favorit. Klick merkt den Server (Kurzname aus dem Namen) bzw. entfernt ihn.</summary>
|
||||
void Heart(Rect r, ServerListEntry s)
|
||||
{
|
||||
EnsureHearts();
|
||||
Favorites.Favorite fav = Favorites.FindByAddress(s.Address, s.Port);
|
||||
bool hover = r.Contains(Event.current.mousePosition);
|
||||
GUI.DrawTexture(r, fav != null || hover ? texHeartOn : texHeartOff);
|
||||
if (GUI.Button(r, GUIContent.none, GUIStyle.none))
|
||||
{
|
||||
if (fav != null) Favorites.Remove(fav);
|
||||
else AddFavorite(s.Name, s.Address, s.Port);
|
||||
}
|
||||
}
|
||||
|
||||
static void AddFavorite(string serverName, string host, int port)
|
||||
{
|
||||
// Kurzname aus dem Servernamen; ist er schon vergeben, eine Zahl anhängen
|
||||
string baseNick = Favorites.SuggestNickname(serverName), nick = baseNick;
|
||||
for (int i = 2; Favorites.Find(nick) != null && i < 100; i++) nick = baseNick + i;
|
||||
string error = Favorites.Set(nick, host, port, serverName);
|
||||
if (error != null) MscoLog.Warning(error);
|
||||
}
|
||||
|
||||
/// <summary>Tab "Favorites": Kurznamen setzen, beitreten, entfernen, per Adresse hinzufügen.</summary>
|
||||
void DrawFavorites(MultiplayerManager mp)
|
||||
{
|
||||
EnsureHearts();
|
||||
GUILayout.Label("Favorites", titleStyle);
|
||||
GUILayout.Label("Give each server a nickname - switch in the game with /switch <nickname> in the chat or F7 console.", textStyle);
|
||||
GUILayout.Space(8);
|
||||
|
||||
List<Favorites.Favorite> favs = Favorites.All;
|
||||
favoritesScroll = GUILayout.BeginScrollView(favoritesScroll, GUILayout.Height(220));
|
||||
if (favs.Count == 0)
|
||||
GUILayout.Label("No favorites yet. Click the heart next to a server in the Server Browser, or add one by address below.", textStyle);
|
||||
Favorites.Favorite remove = null;
|
||||
foreach (Favorites.Favorite f in favs)
|
||||
{
|
||||
ServerListEntry live = mp.Browser.Servers.Find(x => x.Port == f.Port && string.Equals(x.Address, f.Host, System.StringComparison.OrdinalIgnoreCase));
|
||||
GUILayout.BeginHorizontal(rowBox, GUILayout.Height(44));
|
||||
GUILayout.Space(6);
|
||||
|
||||
// Herz (entfernen)
|
||||
Rect heart = GUILayoutUtility.GetRect(22, 22, GUILayout.Width(22), GUILayout.Height(40));
|
||||
Rect heartIcon = new Rect(heart.x, heart.y + 10, 20, 20);
|
||||
GUI.DrawTexture(heartIcon, texHeartOn);
|
||||
if (GUI.Button(heartIcon, GUIContent.none, GUIStyle.none)) remove = f;
|
||||
GUILayout.Space(8);
|
||||
|
||||
// Kurzname bearbeiten
|
||||
string edit;
|
||||
if (!nicknameEdits.TryGetValue(f.Address, out edit)) edit = f.Nickname;
|
||||
GUILayout.BeginVertical(GUILayout.Width(150));
|
||||
GUILayout.Space(7);
|
||||
edit = GUILayout.TextField(edit, 20, fieldStyle, GUILayout.Height(28), GUILayout.Width(150));
|
||||
GUILayout.EndVertical();
|
||||
nicknameEdits[f.Address] = edit;
|
||||
GUILayout.Space(6);
|
||||
bool changed = Favorites.CleanNickname(edit) != f.Nickname;
|
||||
GUILayout.BeginVertical(GUILayout.Width(64));
|
||||
GUILayout.Space(7);
|
||||
GUI.enabled = changed;
|
||||
if (GUILayout.Button("SAVE", tabStyle, GUILayout.Height(28), GUILayout.Width(64)))
|
||||
{
|
||||
string error = Favorites.Set(edit, f.Host, f.Port, f.ServerName);
|
||||
if (error != null) MscoLog.Warning(error);
|
||||
nicknameEdits.Remove(f.Address);
|
||||
}
|
||||
GUI.enabled = true;
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.Space(10);
|
||||
|
||||
// Server + Status
|
||||
GUILayout.BeginVertical();
|
||||
GUILayout.Space(4);
|
||||
GUILayout.Label(string.IsNullOrEmpty(f.ServerName) ? f.Address : f.ServerName, rowNameStyle);
|
||||
GUILayout.Label(live == null ? f.Address + " · not listed / offline"
|
||||
: f.Address + " · " + live.Players + "/" + live.MaxPlayers + " · " + (live.Ping < 0 ? "..." : live.Ping + " ms"), textStyle);
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.FlexibleSpace();
|
||||
|
||||
GUILayout.BeginVertical(GUILayout.Width(90));
|
||||
GUILayout.Space(7);
|
||||
if (GUILayout.Button("JOIN", primaryStyle, GUILayout.Height(30), GUILayout.Width(90))) mp.SwitchServer(f.Nickname);
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.Space(6);
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.Space(4);
|
||||
}
|
||||
if (remove != null) { Favorites.Remove(remove); nicknameEdits.Remove(remove.Address); }
|
||||
GUILayout.EndScrollView();
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Label("ADD BY ADDRESS", captionStyle);
|
||||
GUILayout.BeginHorizontal();
|
||||
favoriteAddInput = GUILayout.TextField(favoriteAddInput ?? "", 60, fieldStyle, GUILayout.Height(34));
|
||||
if (string.IsNullOrEmpty(favoriteAddInput))
|
||||
{
|
||||
Rect field = GUILayoutUtility.GetLastRect();
|
||||
GUI.Label(new Rect(field.x + 10, field.y, field.width, field.height), "host:port", placeholderStyle);
|
||||
}
|
||||
GUILayout.Space(10);
|
||||
if (GUILayout.Button("ADD", secondaryStyle, GUILayout.Height(34), GUILayout.Width(110)))
|
||||
{
|
||||
string host;
|
||||
int port;
|
||||
if (ServerBrowser.TryParseAddress(favoriteAddInput, out host, out port))
|
||||
{
|
||||
ServerListEntry live = mp.Browser.Servers.Find(x => x.Port == port && x.Address == host);
|
||||
AddFavorite(live != null ? live.Name : host, host, port);
|
||||
favoriteAddInput = "";
|
||||
}
|
||||
else MscoLog.Warning("Enter an address like 1.2.3.4:7777");
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
void EnsureHearts()
|
||||
{
|
||||
if (texHeartOn != null && texHeartOff != null) return;
|
||||
texHeartOn = HeartTexture(new Color(0.93f, 0.28f, 0.33f), true);
|
||||
texHeartOff = HeartTexture(new Color(1f, 1f, 1f, 0.35f), false);
|
||||
}
|
||||
|
||||
/// <summary>Herz als Textur (gefüllt oder nur Umriss), weich geglättet.</summary>
|
||||
static Texture2D HeartTexture(Color color, bool filled)
|
||||
{
|
||||
const int size = 48;
|
||||
var tex = new Texture2D(size, size, TextureFormat.ARGB32, false);
|
||||
for (int py = 0; py < size; py++)
|
||||
for (int px = 0; px < size; px++)
|
||||
{
|
||||
// Herz-Kurve (x² + y² - 1)³ - x² y³ <= 0, mehrfach abgetastet für glatte Kanten
|
||||
int inside = 0, samples = 0;
|
||||
for (int sy = 0; sy < 3; sy++)
|
||||
for (int sx = 0; sx < 3; sx++)
|
||||
{
|
||||
float x = ((px + (sx + 0.5f) / 3f) / size - 0.5f) * 2.6f;
|
||||
float y = ((py + (sy + 0.5f) / 3f) / size - 0.55f) * 2.6f;
|
||||
float a = x * x + y * y - 1f;
|
||||
bool inHeart = a * a * a - x * x * y * y * y <= 0f;
|
||||
if (!filled && inHeart)
|
||||
{
|
||||
// Umriss: innen ein kleineres Herz aussparen
|
||||
float x2 = x * 1.28f, y2 = (y + 0.08f) * 1.28f;
|
||||
float b = x2 * x2 + y2 * y2 - 1f;
|
||||
if (b * b * b - x2 * x2 * y2 * y2 * y2 <= 0f) inHeart = false;
|
||||
}
|
||||
if (inHeart) inside++;
|
||||
samples++;
|
||||
}
|
||||
tex.SetPixel(px, py, new Color(color.r, color.g, color.b, color.a * inside / samples));
|
||||
}
|
||||
tex.filterMode = FilterMode.Bilinear;
|
||||
tex.wrapMode = TextureWrapMode.Clamp;
|
||||
tex.Apply();
|
||||
tex.hideFlags = HideFlags.HideAndDontSave;
|
||||
return tex;
|
||||
}
|
||||
|
||||
/// <summary>Server-Profil: wem der Server gehört, Version, Spieler, Laufzeit ...</summary>
|
||||
void DrawServerProfile(MultiplayerManager mp, ServerListEntry s)
|
||||
{
|
||||
@@ -332,6 +507,10 @@ namespace MSCO
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.Space(12);
|
||||
Rect heartSlot = GUILayoutUtility.GetRect(44, 44, GUILayout.Width(44), GUILayout.Height(44));
|
||||
GUI.Box(heartSlot, GUIContent.none, rowBox);
|
||||
Heart(new Rect(heartSlot.x + 11, heartSlot.y + 11, 22, 22), s);
|
||||
GUILayout.Space(8);
|
||||
GUI.enabled = CanJoin(mp, s);
|
||||
if (GUILayout.Button(s.Players >= s.MaxPlayers ? "SERVER FULL" : "JOIN SERVER", primaryStyle, GUILayout.Height(44), GUILayout.Width(180)))
|
||||
mp.JoinServer(s.Address, s.Port, s.Name, s.MaxPlayers);
|
||||
@@ -511,7 +690,9 @@ namespace MSCO
|
||||
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;
|
||||
string title = reconnecting
|
||||
? ((mp.ReconnectMessage ?? "").StartsWith("Switching") ? "SWITCHING SERVER" : "RECONNECTING")
|
||||
: mp.DisconnectTitle;
|
||||
bool bad = !reconnecting && title != "DISCONNECTED";
|
||||
GUI.DrawTexture(new Rect(r.x, r.y, r.width, 4), bad ? texDanger : texAccent);
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
<Compile Include="ControlSync.cs" />
|
||||
<Compile Include="Toasts.cs" />
|
||||
<Compile Include="PlayerNeeds.cs" />
|
||||
<Compile Include="Favorites.cs" />
|
||||
<Compile Include="MpCommand.cs" />
|
||||
<Compile Include="Commands.cs" />
|
||||
<Compile Include="MscoLog.cs" />
|
||||
|
||||
@@ -1021,6 +1021,53 @@ namespace MSCO
|
||||
public int ReconnectAttempt { get { return reconnectAttempts; } }
|
||||
public int ReconnectMaxAttempts { get { return MaxReconnectAttempts; } }
|
||||
|
||||
/// <summary>Server, mit dem man gerade verbunden ist (dedizierter Server), sonst null.</summary>
|
||||
public string CurrentServerHost { get { return session != null && dedicated ? lastServerHost : null; } }
|
||||
public int CurrentServerPort { get { return lastServerPort; } }
|
||||
public string CurrentServerName { get { return lastServerName; } }
|
||||
|
||||
/// <summary>
|
||||
/// Schnell den Server wechseln: Favorit per Kurzname (oder host:port). Ist man gerade verbunden, wird wie beim
|
||||
/// Neu-Verbinden nach einem Welt-Reset getrennt und danach automatisch mit dem neuen Server verbunden.
|
||||
/// </summary>
|
||||
public string SwitchServer(string target)
|
||||
{
|
||||
target = (target ?? "").Trim();
|
||||
if (target.Length == 0) return "switch <nickname> (see 'fav')";
|
||||
Favorites.Favorite fav = Favorites.Find(target);
|
||||
string host, name;
|
||||
int port;
|
||||
if (fav != null) { host = fav.Host; port = fav.Port; name = string.IsNullOrEmpty(fav.ServerName) ? fav.Nickname : fav.ServerName; }
|
||||
else if (ServerBrowser.TryParseAddress(target, out host, out port)) name = null;
|
||||
else return "No favorite called '" + target + "' - type 'fav' to see yours";
|
||||
|
||||
if (session != null && dedicated && string.Equals(lastServerHost, host, System.StringComparison.OrdinalIgnoreCase) && lastServerPort == port)
|
||||
return "You are already on " + (fav != null ? fav.Nickname : host + ":" + port);
|
||||
|
||||
string label = fav != null ? fav.Nickname : host + ":" + port;
|
||||
if (session == null)
|
||||
{
|
||||
if (!MenuHelper.InMenu) return "Go to the main menu first (or join a server) to switch";
|
||||
JoinServer(host, port, name);
|
||||
return "Connecting to " + label + " ...";
|
||||
}
|
||||
|
||||
// Verbunden: trennen und danach automatisch mit dem neuen Server verbinden (übersteht das Neuladen der Mods)
|
||||
lastServerHost = host;
|
||||
lastServerPort = port;
|
||||
lastServerName = name;
|
||||
lastServerMax = 0;
|
||||
serverReason = null;
|
||||
reconnectAttempts = 0;
|
||||
reconnectMessage = "Switching to " + label + " ...";
|
||||
centerMessage = reconnectMessage;
|
||||
centerMessageUntil = Time.realtimeSinceStartup + 2f;
|
||||
session.Close("Switching server");
|
||||
if (MenuHelper.InGame) reconnectHoldUntil = Time.realtimeSinceStartup + 0.8f; // kurz die Meldung zeigen
|
||||
else OnSessionEnded("Switching server");
|
||||
return reconnectMessage;
|
||||
}
|
||||
|
||||
/// <summary>Automatisches Neu-Verbinden abbrechen (Knopf im Reconnect-Fenster).</summary>
|
||||
public void CancelReconnect()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user