From 1da5e3bb5951ec2172d8a1b00fe80afac57c3699 Mon Sep 17 00:00:00 2001 From: MrMaho Date: Fri, 23 Oct 2026 21:10:07 +0200 Subject: [PATCH] 2.10.13: mods draw with the dynamic font (no font warning flood), mod time in PerfStats, PERF report every 5 min in game, redesigned announcement cards in the MSCO menu Co-Authored-By: Claude Opus 5.5 --- Bootstrap.cs | 29 ++++++++++++++++++++++++++--- CHANGELOG.md | 9 +++++++++ LobbyUI.cs | 48 ++++++++++++++++++++++++++++++++++++------------ MSCO.cs | 2 +- PerfStats.cs | 5 ++++- 5 files changed, 76 insertions(+), 17 deletions(-) diff --git a/Bootstrap.cs b/Bootstrap.cs index 7aa2231..a716ba5 100644 --- a/Bootstrap.cs +++ b/Bootstrap.cs @@ -179,9 +179,26 @@ namespace MSCO catch (Exception e) { Bootstrap.Log("FSM dump failed: " + e); } } + readonly System.Diagnostics.Stopwatch modWatch = new System.Diagnostics.Stopwatch(); + + /// Zeit der Mods messen (PERF-Bericht, Konsole "perf"). + void MeasureMods(string part, Action call) + { + modWatch.Reset(); + modWatch.Start(); + try { call(); } + finally + { + modWatch.Stop(); + PerfStats.Add(part, modWatch.Elapsed.TotalMilliseconds); + } + } + + static readonly Action modFixedUpdate = ModLoader.FixedUpdate, modUpdate = ModLoader.Update, modOnGui = ModLoader.OnGUI; + void FixedUpdate() { - ModLoader.FixedUpdate(); + MeasureMods("mods (physics)", modFixedUpdate); } bool skipping, loadingScreen; @@ -191,7 +208,7 @@ namespace MSCO void Update() { - ModLoader.Update(); + MeasureMods("mods", modUpdate); if (!skipping || Time.frameCount < skipFrame + 2) return; skipping = false; loadingScreen = true; @@ -202,7 +219,13 @@ namespace MSCO { if (!skipping && !loadingScreen) { - ModLoader.OnGUI(); + // Mods zeichnen mit der dynamischen Schrift: Schriftgröße/Fett gehen sonst nicht, und Unity schreibt bei jedem + // Zeichnen eine Warnung samt Stacktrace ins Log (z.B. Show Bolt Size: hunderte pro Minute, kostet FPS) + GUISkin skin = GUI.skin; + Font previous = skin.font, font = UiTheme.DynamicFont; + if (font != null) skin.font = font; + try { MeasureMods("mods (interface)", modOnGui); } + finally { skin.font = previous; } return; } GUI.depth = -10000; diff --git a/CHANGELOG.md b/CHANGELOG.md index 408ec93..f28e798 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 2.10.13 + +- **Mehr FPS mit Mods:** Mods (z.B. Show Bolt Size) zeichnen jetzt mit der richtigen Schrift. Vorher schrieb Unity bei + jedem Zeichnen eine Warnung samt Stacktrace ins Log – in einer Sitzung über 400-mal, spürbar als Ruckeln +- **Leistungsbericht:** Im Spiel schreibt MSCO alle 5 Minuten eine Zeile nach `MSCO\MSCO_Loader.txt` (FPS, schlimmstes + Bild, Zeit von MSCO und den Mods). Die Mods stehen jetzt auch in `perf` (Konsole F7) +- **Ankündigungen im MSCO-Menü** neu gestaltet: Abstand innen, farbiger Balken je nach Art, Abzeichen und Titel auf + einer Linie, gut lesbarer Text + ## 2.10.12 - **Fix:** Das MSCO-Menü wurde in 2.10.11 nicht angezeigt (Fehler beim Anlegen der Schrift für Ankündigungen) diff --git a/LobbyUI.cs b/LobbyUI.cs index f92b0e0..526b2a4 100644 --- a/LobbyUI.cs +++ b/LobbyUI.cs @@ -72,7 +72,8 @@ namespace MSCO string layoutError; GUIStyle dangerStyle; GUIStyle windowBox, sidebarBox, rowBox, accentBox, pillStyle, pillMutedStyle, chipOnStyle, chipOffStyle; - GUIStyle featuredRowBox, pillFeaturedStyle, pillDangerStyle, newsTitleStyle; + GUIStyle featuredRowBox, pillFeaturedStyle, pillDangerStyle, newsTitleStyle, newsBoxStyle, newsTextStyle, newsCloseStyle; + Texture2D texNewsInfo, texNewsWarning, texNewsCritical; // Ankündigungen/Wartung vom Keymaster - nur im Layout-Durchgang übernehmen (Liste kann sich im Hintergrund ändern) List shownNews; bool shownMaintenance; @@ -432,26 +433,35 @@ namespace MSCO shownMaintenanceText = SiteStatus.MaintenanceMessage; } if (shownMaintenance) - NewsBox("MAINTENANCE", pillFeaturedStyle, "MSCO is in maintenance right now", + NewsBox("MAINTENANCE", pillDangerStyle, texNewsCritical, "MSCO is in maintenance right now", string.IsNullOrEmpty(shownMaintenanceText) ? "Some things may not work for a while." : shownMaintenanceText, null); foreach (Announcement a in shownNews) NewsBox(a.Level == "critical" ? "IMPORTANT" : a.Level == "warning" ? "NOTICE" : "INFO", - a.Level == "critical" ? pillDangerStyle : a.Level == "warning" ? pillFeaturedStyle : pillMutedStyle, a.Title, a.Text, a.Id); + a.Level == "critical" ? pillDangerStyle : a.Level == "warning" ? pillFeaturedStyle : pillMutedStyle, + a.Level == "critical" ? texNewsCritical : a.Level == "warning" ? texNewsWarning : texNewsInfo, a.Title, a.Text, a.Id); if (shownMaintenance || shownNews.Count > 0) GUILayout.Space(S(10)); } - void NewsBox(string label, GUIStyle pill, string title, string text, string id) + void NewsBox(string label, GUIStyle pill, Texture2D stripe, string title, string text, string id) { - GUILayout.BeginVertical(rowBox); + GUILayout.BeginVertical(newsBoxStyle); GUILayout.BeginHorizontal(); - GUILayout.Label(label, pill, GUILayout.Height(S(20)), GUILayout.ExpandWidth(false)); - GUILayout.Space(S(8)); - GUILayout.Label(title, newsTitleStyle, GUILayout.ExpandWidth(true)); - if (id != null && GUILayout.Button("×", tabStyle, GUILayout.Width(S(28)), GUILayout.Height(S(22)))) dismissedNews.Add(id); + // Abzeichen und Titel gleich hoch und mittig - sonst sitzt der Titel tiefer als das Abzeichen + GUILayout.Label(label, pill, GUILayout.Height(S(22)), GUILayout.ExpandWidth(false)); + GUILayout.Space(S(10)); + GUILayout.Label(title, newsTitleStyle, GUILayout.MinHeight(S(22)), GUILayout.ExpandWidth(true)); + if (id != null && GUILayout.Button(new GUIContent("×", "Hide"), newsCloseStyle, GUILayout.Width(S(24)), GUILayout.Height(S(22)))) + dismissedNews.Add(id); GUILayout.EndHorizontal(); - if (!string.IsNullOrEmpty(text)) GUILayout.Label(text, textStyle); + if (!string.IsNullOrEmpty(text)) GUILayout.Label(text, newsTextStyle); GUILayout.EndVertical(); - GUILayout.Space(S(6)); + // Farbiger Balken links (Art der Ankündigung) + if (Event.current.type == EventType.Repaint) + { + Rect box = GUILayoutUtility.GetLastRect(); + GUI.DrawTexture(new Rect(box.x, box.y + S(10), S(3), box.height - S(20)), stripe); + } + GUILayout.Space(S(8)); } void DrawNameField(MultiplayerManager mp, float width) @@ -1195,7 +1205,6 @@ namespace MSCO headerCellStyle = Label(P(11), Muted, FontStyle.Bold); headerCellStyle.alignment = TextAnchor.MiddleLeft; rowNameStyle = Label(P(14), Color.white, FontStyle.Normal); - newsTitleStyle = new GUIStyle(rowNameStyle) { wordWrap = true }; // erst nach rowNameStyle (Kopie davon) rowNameStyle.alignment = TextAnchor.MiddleLeft; pingGoodStyle = new GUIStyle(rowNameStyle); pingGoodStyle.normal.textColor = Online; @@ -1238,6 +1247,21 @@ namespace MSCO fieldStyle.focused.background = UiTheme.RoundedEx(Hex(0x19, 0x19, 0x1e), Hex(0x19, 0x19, 0x1e), Accent, true, P(10), P(10) * 2 + 4); fieldStyle.border = new RectOffset(P(10) + 2, P(10) + 2, P(10) + 2, P(10) + 2); + // Ankündigungen: Karte mit Innenabstand, Titel fett auf Höhe des Abzeichens, Text gut lesbar + newsBoxStyle = UiTheme.Card(Field, P(10)); + newsBoxStyle.padding = new RectOffset(P(18), P(12), P(12), P(12)); + newsTitleStyle = Label(P(15), Color.white, FontStyle.Bold); + newsTitleStyle.alignment = TextAnchor.MiddleLeft; + newsTitleStyle.wordWrap = true; + newsTextStyle = Label(P(13), new Color(0.86f, 0.86f, 0.9f), FontStyle.Normal); + newsTextStyle.wordWrap = true; + newsTextStyle.margin = new RectOffset(0, 0, P(6), 0); + newsCloseStyle = Label(P(18), Muted, FontStyle.Normal); + newsCloseStyle.alignment = TextAnchor.MiddleCenter; + newsCloseStyle.hover.textColor = Color.white; + texNewsInfo = Solid(Hex(0x5a, 0xa0, 0xff)); + texNewsWarning = Solid(Gold); + texNewsCritical = Solid(UiTheme.Danger); stylesReady = true; } diff --git a/MSCO.cs b/MSCO.cs index 00deb0b..2b4b379 100644 --- a/MSCO.cs +++ b/MSCO.cs @@ -11,7 +11,7 @@ namespace MSCO /// Version der Mod. Kleine Updates: nur die dritte Stelle erhöhen (2.9.1, 2.9.2 ...) - sie bleiben mit /// Servern und Mitspielern derselben ersten zwei Stellen kompatibel. /// - public const string ModVersion = "2.10.12"; + public const string ModVersion = "2.10.13"; /// /// Netzwerk-Version (die ersten beiden Stellen). Nur erhöhen, wenn sich das Protokoll inkompatibel ändert - dann /// auch GameServer.ModVersion im Server. diff --git a/PerfStats.cs b/PerfStats.cs index e16cba1..6b30578 100644 --- a/PerfStats.cs +++ b/PerfStats.cs @@ -34,7 +34,10 @@ namespace MSCO frames++; frameSeconds += dt; if (dt > worstFrame) worstFrame = dt; - if (autoLog && Time.realtimeSinceStartup - started >= 30f) + // Mit -msco-perf alle 30 s, sonst im Spiel alle 5 Minuten ein Bericht in MSCO_Loader.txt - so lässt sich bei + // "wenig FPS" nachsehen, ob MSCO, eine Mod oder das Spiel selbst die Zeit braucht + float every = autoLog ? 30f : 300f; + if ((autoLog || MenuHelper.InGame) && Time.realtimeSinceStartup - started >= every) { Bootstrap.Log(Report()); Reset();