From 273352db087b62a24c59f6ee52140e4e18cace6a Mon Sep 17 00:00:00 2001 From: Alexa <53471801+Alexa-RR@users.noreply.github.com> Date: Fri, 26 Jun 2026 11:03:14 +0300 Subject: [PATCH] feat: Add DorkNet.DebugMod for optional diagnostic features and improved debugging capabilities --- DorkNet.ClientMod/Mod.cs | 44 +++++++++++++++++++-- DorkNet.DebugMod/DebugMod.cs | 31 +++++++++++++++ DorkNet.DebugMod/DorkNet.DebugMod.csproj | 40 +++++++++++++++++++ DorkNet.Server/admin-ui/src/pages/Rooms.tsx | 11 +++++- 4 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 DorkNet.DebugMod/DebugMod.cs create mode 100644 DorkNet.DebugMod/DorkNet.DebugMod.csproj diff --git a/DorkNet.ClientMod/Mod.cs b/DorkNet.ClientMod/Mod.cs index df00d0e..cdb6a3a 100644 --- a/DorkNet.ClientMod/Mod.cs +++ b/DorkNet.ClientMod/Mod.cs @@ -90,6 +90,15 @@ public class Mod : MelonMod public static string[] DevCommands = Array.Empty(); public static bool DiagnoseDevMenu = false; public static bool EnableBuiltInDevDebugTools = false; + // Master switch for the verbose, non-essential DIAGNOSTIC patches + // (HTTP header tracing, join/quit traces, studio traces, the deep + // RegisterDiagnostics path). OFF by default so the shipping client + // mod installs only the patches needed to connect + survive + // anti-cheat — the safest possible footprint. Turned ON automatically + // when DorkNet.DebugMod.dll is present in the Mods folder (drop it in + // to debug, remove it to ship), or by "EnableDiagnostics": true in + // the config. Core connectivity/anti-cheat patches are NEVER gated. + public static bool EnableDiagnostics = false; // ── Desktop Screen Sharing gadget FPS ── // RecRoom.Tools.Productivity.DesktopScreenSharingDisplay broadcasts @@ -167,7 +176,11 @@ public class Mod : MelonMod "NotifyServerCertificate", prefix: nameof(TlsPatches.NotifyServerCertificate_Prefix)); } - RegisterQuitTracePatches(logMisses: true); + // Anti-tamper / ToxMod / file-hash-checker are anti-cheat BYPASS + // patches — core, always on, or the modded client gets kicked. + // Quit-trace is pure diagnostics, so it's gated. + if (Cfg.EnableDiagnostics) + RegisterQuitTracePatches(logMisses: true); RegisterAntiTamperCallbackPatches(logMisses: true); RegisterToxModPatches(logMisses: true); PatchFileHashCheckerCallback(); @@ -206,7 +219,8 @@ public class Mod : MelonMod Log.Msg($"[questsize] armed: target {Cfg.QuestMaxTeamSize} for [{string.Join(", ", Cfg.QuestMaxTeamSizeRooms)}]"); } - RegisterStudioTracePatches(); + if (Cfg.EnableDiagnostics) + RegisterStudioTracePatches(); if (Cfg.EnableBuiltInDevDebugTools) RegisterBuiltInDevDebugTools(); @@ -525,7 +539,10 @@ public class Mod : MelonMod args: new[] { ResolveType("BestHTTP.HTTPRequest") ?? typeof(object) }, prefix: nameof(UriPatches.HttpManagerSendRequestObject_Prefix)); - RegisterHttpDiagnostics(); + // HTTP header/callback tracing is pure diagnostics (and the noisiest + // thing in the log) — only install it when diagnostics are enabled. + if (Cfg.EnableDiagnostics) + RegisterHttpDiagnostics(); _networkPatchesRegistered = complete; } @@ -697,7 +714,7 @@ public class Mod : MelonMod Log.Msg("[lifecycle] first OnUpdate tick (Unity frame loop is live)"); } - if (!_quitTraceGameComplete && ++_quitTraceRetryFrame >= 300) + if (Cfg.EnableDiagnostics && !_quitTraceGameComplete && ++_quitTraceRetryFrame >= 300) { _quitTraceRetryFrame = 0; RegisterQuitTracePatches(logMisses: false); @@ -734,6 +751,22 @@ public class Mod : MelonMod var userData = ResolveUserDataDirectory(); Directory.CreateDirectory(userData); DiagnosticsLogPath = Path.Combine(userData, "dorknet-diagnostics.log"); + + // Auto-enable diagnostics when the separate DorkNet.DebugMod.dll is + // dropped in alongside this mod. Done before the config read (and + // before the no-config-file early return) so presence alone is + // enough — no config edit required to debug. + try + { + var modsDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + if (modsDir != null && File.Exists(Path.Combine(modsDir, "DorkNet.DebugMod.dll"))) + { + Cfg.EnableDiagnostics = true; + Log.Msg("[config] DorkNet.DebugMod.dll present → diagnostics ENABLED"); + } + } + catch { /* presence detection is best-effort */ } + var path = Path.Combine(userData, "dorknet-clientmod.json"); if (!File.Exists(path)) { @@ -749,6 +782,9 @@ public class Mod : MelonMod if (TryGetConfigValue(r, "DebugConsoleToggleKey", out v)) Cfg.DebugConsoleToggleKey = v.GetString() ?? Cfg.DebugConsoleToggleKey; if (TryGetConfigValue(r, "DiagnoseDevMenu", out v)) Cfg.DiagnoseDevMenu = v.GetBoolean(); if (TryGetConfigValue(r, "EnableBuiltInDevDebugTools", out v)) Cfg.EnableBuiltInDevDebugTools = v.GetBoolean(); + // Config can also enable diagnostics; OR with the debug-mod + // presence check above so either path turns them on. + if (TryGetConfigValue(r, "EnableDiagnostics", out v)) Cfg.EnableDiagnostics |= v.GetBoolean(); if (TryGetConfigValue(r, "DevCommands", out v) && v.ValueKind == JsonValueKind.Array) { var commands = new List(); diff --git a/DorkNet.DebugMod/DebugMod.cs b/DorkNet.DebugMod/DebugMod.cs new file mode 100644 index 0000000..59decb7 --- /dev/null +++ b/DorkNet.DebugMod/DebugMod.cs @@ -0,0 +1,31 @@ +// DorkNet.DebugMod — opt-in debugging switch for DorkNet.ClientMod. +// +// This mod intentionally does almost nothing on its own. Its job is to +// EXIST: when its DLL sits in the Mods folder next to DorkNet.ClientMod.dll, +// the ClientMod detects it at startup (Cfg.EnableDiagnostics) and installs +// its verbose diagnostic patches — HTTP header/callback tracing, join/quit +// /studio traces, and the deep RegisterDiagnostics probes. Remove this DLL +// to ship a quiet, minimal client that only carries the connect + anti-cheat +// patches. +// +// Keeping the switch as a separate assembly (rather than a config flag baked +// into the shipping mod) means the diagnostics literally cannot turn +// themselves on in a normal install — you have to deliberately drop this +// file in. That is the "as safe as possible" default the main mod wants. + +using MelonLoader; + +[assembly: MelonInfo(typeof(DorkNet.DebugMod.DebugMod), "DorkNet DebugMod", "1.0.0", "Dork Squad")] +[assembly: MelonGame(null, null)] + +namespace DorkNet.DebugMod; + +public class DebugMod : MelonMod +{ + public override void OnInitializeMelon() + { + LoggerInstance.Msg( + "=== DorkNet DebugMod present — DorkNet.ClientMod diagnostics are ENABLED. " + + "Remove DorkNet.DebugMod.dll from Mods to ship a quiet client. ==="); + } +} diff --git a/DorkNet.DebugMod/DorkNet.DebugMod.csproj b/DorkNet.DebugMod/DorkNet.DebugMod.csproj new file mode 100644 index 0000000..efb98d3 --- /dev/null +++ b/DorkNet.DebugMod/DorkNet.DebugMod.csproj @@ -0,0 +1,40 @@ + + + + + + net6.0 + latest + enable + DorkNet.DebugMod + DorkNet.DebugMod + false + false + $(NoWarn);CS8602;CS8604;CS0436 + + + + + $(MSBuildThisFileDirectory)..\DorkNet.ClientMod\build\melonloader\MelonLoader\net6 + + + + + $(MelonLoaderDir)\MelonLoader.dll + false + + + + diff --git a/DorkNet.Server/admin-ui/src/pages/Rooms.tsx b/DorkNet.Server/admin-ui/src/pages/Rooms.tsx index 2a56b50..5d71948 100644 --- a/DorkNet.Server/admin-ui/src/pages/Rooms.tsx +++ b/DorkNet.Server/admin-ui/src/pages/Rooms.tsx @@ -172,9 +172,18 @@ export function Rooms() { {r.blobCount} Manage - + {!r.isDormRoom && ( + + )} ))}