From eabb39ba86968286e6351ad703d019d2df5c4e01 Mon Sep 17 00:00:00 2001 From: Jon Kazama Date: Tue, 12 May 2026 13:55:04 +0200 Subject: [PATCH] fix(font): fall back to system font if embedded resource missing (F10.2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GetHellionFontBytes used to throw a FileNotFoundException when the embedded Hellion font resource was missing — only possible on a broken csproj or a hand-rolled dev build, never on a signed release, but the throw bubbled up and broke the entire UiBuilder font atlas. Replaced with a nullable TryGetHellionFontBytes that logs a warning and returns null on miss. The RegularFont delegate now falls back to the same system-font path that UseHellionFont=false already uses, so the plugin still loads and the issue surfaces in /xllog instead of as a crash. --- HellionChat/FontManager.cs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/HellionChat/FontManager.cs b/HellionChat/FontManager.cs index 6a86efa..17daf5d 100644 --- a/HellionChat/FontManager.cs +++ b/HellionChat/FontManager.cs @@ -44,16 +44,26 @@ public class FontManager // Hellion font bytes (Exo 2, OFL-1.1); lazily loaded from manifest resources private static byte[]? HellionFontBytes; - private static byte[] GetHellionFontBytes() + // Returns null when the embedded font resource is missing. Should never + // happen on a signed release build, but a broken csproj or hand-rolled + // dev build can land here. Caller falls back to the system font path so + // the plugin still loads instead of crashing the whole UiBuilder. + private static byte[]? TryGetHellionFontBytes() { if (HellionFontBytes is not null) return HellionFontBytes; - using var stream = - typeof(FontManager).Assembly.GetManifestResourceStream("HellionFont.ttf") - ?? throw new FileNotFoundException( - "Hellion font resource not embedded in the assembly" + using var stream = typeof(FontManager).Assembly.GetManifestResourceStream( + "HellionFont.ttf" + ); + if (stream is null) + { + Plugin.Log.Warning( + "Hellion font resource missing — falling back to system default font." ); + return null; + } + using var ms = new MemoryStream(); stream.CopyTo(ms); HellionFontBytes = ms.ToArray(); @@ -146,8 +156,11 @@ public class FontManager ? Plugin.Config.FontSizeV2 : Plugin.Config.GlobalFontV2.SizePt; var config = new SafeFontConfig { SizePt = basePt, GlyphRanges = Ranges }; - config.MergeFont = Plugin.Config.UseHellionFont - ? tk.AddFontFromMemory(GetHellionFontBytes(), config, "Hellion-Exo2") + // F10.2: if the embedded font is missing, drop to the system font + // path rather than letting the UiBuilder throw. + var hellionBytes = Plugin.Config.UseHellionFont ? TryGetHellionFontBytes() : null; + config.MergeFont = hellionBytes is not null + ? tk.AddFontFromMemory(hellionBytes, config, "Hellion-Exo2") : AddFontWithFallback(tk, Plugin.Config.GlobalFontV2.FontId, config, "global"); config.SizePt = Plugin.Config.JapaneseFontV2.SizePt;