Server browser: featured servers (gold row + FEATURED badge, pinned to the top by the master) and key tags in the server profile; search matches tags

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Nico Meister
2026-09-27 23:55:46 +02:00
co-authored by Claude Opus 5.5
parent 8e00640732
commit 33a415139b
3 changed files with 26 additions and 3 deletions
+8
View File
@@ -1,5 +1,13 @@
# Changelog
## Nächste Version
**Server-Browser**
- **Hervorgehobene Server**: vom Keymaster-Admin markierte Server (Tag `featured`) stehen ganz oben, mit goldener
Zeile und **FEATURED**-Abzeichen (Liste und Profil)
- **Tags** der Server (z.B. `OFFICIAL`) erscheinen im Server-Profil; die Suche findet auch Tags
- Braucht keinen neuen Server: die Infos kommen vom Master (msco.mbm.wtf) und funktionieren mit 2.8-Servern
## 2.8
Server und Mod müssen beide 2.8 sein (Server: `git pull && docker compose up -d --build`).
+16 -3
View File
@@ -29,6 +29,7 @@ namespace MSCO
static readonly Color Muted = Hex(0x8e, 0x8e, 0x99);
static readonly Color Online = Hex(0x3d, 0xd6, 0x8c);
static readonly Color Pending = Hex(0xf2, 0xc2, 0x1d);
static readonly Color Gold = Hex(0xff, 0xb4, 0x5a); // hervorgehobene (featured) Server
Page page = Page.P2P;
Vector2 profileScroll;
@@ -54,6 +55,7 @@ namespace MSCO
string layoutError;
GUIStyle dangerStyle;
GUIStyle windowBox, sidebarBox, rowBox, accentBox, pillStyle, pillMutedStyle, chipOnStyle, chipOffStyle;
GUIStyle featuredRowBox, pillFeaturedStyle;
GUIStyle logoStyle, taglineStyle, navStyle, navActiveStyle, titleStyle, textStyle, captionStyle,
fieldStyle, primaryStyle, secondaryStyle, statusStyle, tabStyle, headerCellStyle,
rowNameStyle, rowTagStyle, badgeStyle, toggleStyle, placeholderStyle;
@@ -219,7 +221,8 @@ namespace MSCO
shownServers = all.FindAll(s =>
(s.RequireSteam ? showSteam : showNonSteam) &&
(!hideFull || s.Players < s.MaxPlayers) &&
(search.Length == 0 || (s.Name ?? "").ToLower().Contains(search) || (s.Owner ?? "").ToLower().Contains(search)));
(search.Length == 0 || (s.Name ?? "").ToLower().Contains(search) || (s.Owner ?? "").ToLower().Contains(search) ||
(s.Tags != null && s.Tags.Exists(t => (t ?? "").Contains(search)))));
List<ServerListEntry> servers = shownServers;
string shownError = Event.current.type == EventType.Layout ? (layoutError = browser.Error) : layoutError;
@@ -238,7 +241,8 @@ namespace MSCO
foreach (ServerListEntry s in servers)
{
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);
// Hervorgehobene Server (Keymaster-Admin) stehen oben - der Master liefert sie zuerst
GUI.Box(new Rect(row.x, row.y + 2, row.width, row.height - 4), GUIContent.none, s.Featured ? featuredRowBox : 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);
@@ -250,6 +254,7 @@ namespace MSCO
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 (s.Featured) nameX += Pill(nameX, row, "FEATURED", pillFeaturedStyle);
if (fav != null) nameX += Pill(nameX, row, fav.Nickname, pillMutedStyle);
if (s.IsLocal)
{
@@ -501,9 +506,13 @@ namespace MSCO
GUILayout.BeginHorizontal();
Rect badgeRow = GUILayoutUtility.GetRect(10, 20, GUILayout.ExpandWidth(true));
float bx = badgeRow.x;
if (s.Featured) bx += Pill(bx, badgeRow, "FEATURED", pillFeaturedStyle);
bx += Pill(bx, badgeRow, s.RequireSteam ? "STEAM" : "NON-STEAM", s.RequireSteam ? pillStyle : pillMutedStyle);
if (s.IsLocal) bx += Pill(bx, badgeRow, "LOCAL", pillStyle);
if (s.Version != MSCO.ModVersion) Pill(bx, badgeRow, "v" + s.Version, pillStyle);
if (s.Version != MSCO.ModVersion) bx += Pill(bx, badgeRow, "v" + s.Version, pillStyle);
if (s.Tags != null)
foreach (string tag in s.Tags)
if (!string.IsNullOrEmpty(tag) && tag != "featured") bx += Pill(bx, badgeRow, tag.ToUpper(), pillMutedStyle);
GUILayout.EndHorizontal();
GUILayout.EndVertical();
GUILayout.Space(12);
@@ -815,6 +824,10 @@ namespace MSCO
pillMutedStyle = new GUIStyle(pillStyle);
pillMutedStyle.normal.background = UiTheme.Rounded(new Color(1f, 1f, 1f, 0.08f), 4);
pillMutedStyle.normal.textColor = Muted;
pillFeaturedStyle = new GUIStyle(pillStyle);
pillFeaturedStyle.normal.background = UiTheme.Rounded(Gold, 4);
pillFeaturedStyle.normal.textColor = Hex(0x1a, 0x12, 0x06);
featuredRowBox = UiTheme.Panel9(Color.Lerp(Field, Gold, 0.16f), UiTheme.Radius);
chipOnStyle = Button(new Color(Accent.r, Accent.g, Accent.b, 0.22f), new Color(Accent.r, Accent.g, Accent.b, 0.32f), AccentHover, 11, FontStyle.Bold);
chipOffStyle = Button(Field, FieldFocus, Muted, 11, FontStyle.Bold);
+2
View File
@@ -23,6 +23,8 @@ namespace MSCO
public string Version;
public bool RequireSteam = true; // false = Non-Steam-Server
public string Owner; // Besitzer des Lizenzschlüssels
public bool Featured; // vom Keymaster-Admin hervorgehoben (steht in der Liste oben)
public List<string> Tags = new List<string>(); // Tags des Lizenzschlüssels (Keymaster-Admin), z.B. "official"
[JsonIgnore] public int UptimeSeconds = -1;
[JsonIgnore] public List<string> PlayerNames = new List<string>();