From 46834c1f75dd633933846510c0fe293db8886275 Mon Sep 17 00:00:00 2001 From: std-external <201375710+std-external@users.noreply.github.com> Date: Sun, 1 Nov 2026 15:41:24 +0800 Subject: [PATCH] miaonet: drop the off-screen name suppression option MiaoNet already owns this behaviour: GhostNameTag clamps names for players outside the camera onto the screen edge and fades them to OffScreenPlayerNameOpacity, which players can set to 0 if they want them gone. Keeping a second switch in mbqol meant coupling it to the minimap options and silently swallowing the labels when the plugin was enabled. Removes the GhostNameTag.Render detour (and its reflection/IL plumbing), the setting, the options row and the README lines. --- README.en.md | 1 - README.md | 1 - Source/MiaoNetBridge.cs | 76 ------------------------------------ Source/QolSettings.cs | 3 -- Source/QolSettingsOverlay.cs | 4 +- 5 files changed, 1 insertion(+), 84 deletions(-) diff --git a/README.en.md b/README.en.md index f01fa5d..182328b 100644 --- a/README.en.md +++ b/README.en.md @@ -71,7 +71,6 @@ active, disable it when visual artifacts or added latency appear. for strawberries in nearby rooms. - Optional MiaoNet players, avatars, off-screen players, and names on the minimap. Names can be hidden, limited to watched players, or shown for everyone. -- Optional suppression of MiaoNet's native off-screen name labels. ### MiaoNet watching and notifications diff --git a/README.md b/README.md index 8bc70cb..62dad81 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,6 @@ Present hook 只会重复这张最终图像,无法提供帧生成所需的深 - 根据存档显示收集状态;可选在边缘显示附近房间的草莓。 - 可选显示 MiaoNet 同地图玩家、头像、越界玩家和玩家名称;玩家名称可以设置为 不显示、仅显示关注玩家或显示所有人。 -- 可隐藏 MiaoNet 原生的越界名字标签。 ### MiaoNet 关注与通知 diff --git a/Source/MiaoNetBridge.cs b/Source/MiaoNetBridge.cs index 8f32e09..552ec08 100644 --- a/Source/MiaoNetBridge.cs +++ b/Source/MiaoNetBridge.cs @@ -1,11 +1,9 @@ using System.Collections; using System.Linq.Expressions; using System.Reflection; -using System.Reflection.Emit; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Monocle; -using MonoMod.RuntimeDetour; namespace Celeste.Mod.MicroblocksQolUtils; @@ -28,10 +26,6 @@ public static class MiaoNetBridge { private static Assembly? assembly; private static bool commandInstalled; private static int retryFrames; - private static Hook? offscreenNameHook; - private static bool offscreenNameHookAttempted; - private static PropertyInfo? ghostNameTagEntityProperty; - private static PropertyInfo? ghostNameTagIsOnSelfProperty; private static PixelFont? avatarFont; private static float avatarBaseSize; private static Type? emojiType; @@ -63,16 +57,10 @@ public static void Update(Level? level) { retryFrames = 0; TryInstallChatCommand(); } - TryInstallOffscreenNameHook(); ReadPlayers(level); } public static void Unload() { - offscreenNameHook?.Dispose(); - offscreenNameHook = null; - offscreenNameHookAttempted = false; - ghostNameTagEntityProperty = null; - ghostNameTagIsOnSelfProperty = null; CurrentPlayers.Clear(); LocalPlayer = null; LoggedIn = false; @@ -303,70 +291,6 @@ private static void ObserveRoomChange(int id, string name, string room) { LastRooms[id] = room; } - private static void TryInstallOffscreenNameHook() { - if (offscreenNameHook is not null || offscreenNameHookAttempted || assembly is null) return; - offscreenNameHookAttempted = true; - try { - Type nameTagType = assembly.GetType("Celeste.Mod.MiaoNet.GhostNameTag", throwOnError: true)!; - MethodInfo render = nameTagType.GetMethod( - nameof(Entity.Render), - BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, - binder: null, - Type.EmptyTypes, - modifiers: null - ) ?? throw new MissingMethodException(nameTagType.FullName, nameof(Entity.Render)); - - ghostNameTagEntityProperty = nameTagType.GetProperty("Entity", BindingFlags.Public | BindingFlags.Instance) - ?? throw new MissingMemberException(nameTagType.FullName, "Entity"); - ghostNameTagIsOnSelfProperty = nameTagType.GetProperty("IsOnSelf", BindingFlags.Public | BindingFlags.Instance); - - Type originalDelegateType = Expression.GetDelegateType(nameTagType, typeof(void)); - Type detourDelegateType = Expression.GetDelegateType(originalDelegateType, nameTagType, typeof(void)); - MethodInfo shouldRender = typeof(MiaoNetBridge).GetMethod( - nameof(ShouldRenderGhostNameTag), - BindingFlags.NonPublic | BindingFlags.Static - )!; - DynamicMethod detourMethod = new( - "MicroblocksQolUtils_MiaoNetGhostNameTagRender", - typeof(void), - [originalDelegateType, nameTagType], - typeof(MiaoNetBridge).Module, - skipVisibility: true - ); - ILGenerator il = detourMethod.GetILGenerator(); - Label done = il.DefineLabel(); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Call, shouldRender); - il.Emit(OpCodes.Brfalse_S, done); - il.Emit(OpCodes.Ldarg_0); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Callvirt, originalDelegateType.GetMethod(nameof(Action.Invoke))!); - il.MarkLabel(done); - il.Emit(OpCodes.Ret); - Delegate detour = detourMethod.CreateDelegate(detourDelegateType); - - offscreenNameHook = new Hook(render, detour); - Logger.Log(LogLevel.Info, "MicroblocksQolUtils", "MiaoNet off-screen name filtering enabled"); - } catch (Exception exception) { - ghostNameTagEntityProperty = null; - ghostNameTagIsOnSelfProperty = null; - Logger.Log(LogLevel.Warn, "MicroblocksQolUtils/MiaoNet", $"Cannot hook off-screen names: {exception.Message}"); - } - } - - private static bool ShouldRenderGhostNameTag(object nameTag) { - if (!MicroblocksQolUtilsModule.Settings.HideMiaoNetOffscreenNames) return true; - try { - if (ghostNameTagIsOnSelfProperty?.GetValue(nameTag) is true) return true; - if (ghostNameTagEntityProperty?.GetValue(nameTag) is not Entity player - || player.Scene is not Level level) return true; - return level.InsideCamera(player.Position); - } catch { - // A MiaoNet update should never make its normal name rendering disappear. - return true; - } - } - private static bool TryResolveAvatarFont() { if (avatarFont is not null && emojiType is not null) return true; Type? fontType = assembly?.GetType("Celeste.Mod.MiaoNet.MiaoNetFont"); diff --git a/Source/QolSettings.cs b/Source/QolSettings.cs index 3cb0083..573006a 100644 --- a/Source/QolSettings.cs +++ b/Source/QolSettings.cs @@ -221,9 +221,6 @@ public void CreateFontFamilyEntry(TextMenu menu, bool inGame) { [DefaultValue(MiniMapNameMode.WatchedOnly)] public MiniMapNameMode MiniMapNames { get; set; } = MiniMapNameMode.WatchedOnly; - [DefaultValue(true)] - public bool HideMiaoNetOffscreenNames { get; set; } = true; - [DefaultValue(true)] public bool ShowRoomsRemaining { get; set; } = true; diff --git a/Source/QolSettingsOverlay.cs b/Source/QolSettingsOverlay.cs index ceeebe9..f011470 100644 --- a/Source/QolSettingsOverlay.cs +++ b/Source/QolSettingsOverlay.cs @@ -1638,9 +1638,7 @@ private List BuildTabs() { value => settings.MiniMapShowOffscreenPlayers = value), EnumRow("头像裁剪形状", () => settings.MiniMapAvatarShape, value => settings.MiniMapAvatarShape = value), - EnumRow("玩家名字", () => settings.MiniMapNames, value => settings.MiniMapNames = value), - Toggle("隐藏原生越界名字", () => settings.HideMiaoNetOffscreenNames, - value => settings.HideMiaoNetOffscreenNames = value) + EnumRow("玩家名字", () => settings.MiniMapNames, value => settings.MiniMapNames = value) ]), new SettingsTab("录制", "videocam", BuildRecorderRows(settings), RecorderPage: true), new SettingsTab("界面与系统", "settings", [