mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-26 23:48:45 -07:00
feat: Enhance HttpTracePatches with detailed logging for RecNet requests and responses
This commit is contained in:
+140
-102
@@ -29,6 +29,7 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
@@ -50,7 +51,6 @@ public class Mod : MelonMod
|
|||||||
private bool _joinTracePatchesRegistered;
|
private bool _joinTracePatchesRegistered;
|
||||||
private bool _diagnosticCoreRegistered;
|
private bool _diagnosticCoreRegistered;
|
||||||
private bool _diagnosticGameComplete;
|
private bool _diagnosticGameComplete;
|
||||||
private int _diagnosticRetryFrame;
|
|
||||||
private bool _firstUpdateLogged;
|
private bool _firstUpdateLogged;
|
||||||
private bool _processExceptionHandlersRegistered;
|
private bool _processExceptionHandlersRegistered;
|
||||||
|
|
||||||
@@ -147,14 +147,11 @@ public class Mod : MelonMod
|
|||||||
Instance = this;
|
Instance = this;
|
||||||
Log.Msg("=== DorkNet ClientMod loading ===");
|
Log.Msg("=== DorkNet ClientMod loading ===");
|
||||||
LoadConfig();
|
LoadConfig();
|
||||||
RegisterProcessExceptionHandlers();
|
|
||||||
RegisterNetworkPatches();
|
RegisterNetworkPatches();
|
||||||
DiagnosticPatches.Write("[lifecycle] OnInitializeMelon");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnLateInitializeMelon()
|
public override void OnLateInitializeMelon()
|
||||||
{
|
{
|
||||||
DiagnosticPatches.Write("[lifecycle] OnLateInitializeMelon");
|
|
||||||
Log.Msg("=== Registering client patches ===");
|
Log.Msg("=== Registering client patches ===");
|
||||||
RegisterNetworkPatches();
|
RegisterNetworkPatches();
|
||||||
TryPatchByName("RecRoom.AntiCheat.EACManager",
|
TryPatchByName("RecRoom.AntiCheat.EACManager",
|
||||||
@@ -270,57 +267,6 @@ public class Mod : MelonMod
|
|||||||
args: new[] { typeof(string) },
|
args: new[] { typeof(string) },
|
||||||
prefix: nameof(ChatPatches.RpcChatEmote_Prefix));
|
prefix: nameof(ChatPatches.RpcChatEmote_Prefix));
|
||||||
|
|
||||||
// Diagnostic trace for the stuck first-dorm "Change Username?"
|
|
||||||
// dialog (new accounts can't get past it; "Okay" highlights but
|
|
||||||
// never dismisses the modal, on every device). This is LOG-ONLY —
|
|
||||||
// no behaviour change. It bisects the failure for a brand-new
|
|
||||||
// account that reproduces the freeze, writing to
|
|
||||||
// MelonLoader/UserData/dorknet-diagnostics.log:
|
|
||||||
//
|
|
||||||
// 1. RegistrationModel.IsFullyRegistered() return value — if
|
|
||||||
// false, the dorm prompt path runs; if true, no prompt (so a
|
|
||||||
// freeze here would be something else entirely).
|
|
||||||
// 2. DormroomSceneManager.<PromptForRegistration>b__6_* lambdas —
|
|
||||||
// which prompt branch executed (b__6_1 = a dialog was raised).
|
|
||||||
// 3. ConfirmUIDialog.Button_Affirmative/Negative/NotNow/Cancel —
|
|
||||||
// whether the click actually reaches the dialog's button
|
|
||||||
// handler when the user taps Okay. If these FIRE but the modal
|
|
||||||
// stays, the break is in the resolve/hide completer
|
|
||||||
// (UIDialog`1.KHKDGPHPIND's guard); if they DON'T fire, the
|
|
||||||
// click never routes to the button (input/raycast) and the fix
|
|
||||||
// is elsewhere. Either way the next step is unambiguous.
|
|
||||||
if (Cfg.TraceRegistrationDialog)
|
|
||||||
{
|
|
||||||
TryPatchByName("RRUI.Data.NUX.RegistrationModel",
|
|
||||||
"IsFullyRegistered",
|
|
||||||
args: Type.EmptyTypes,
|
|
||||||
postfix: nameof(RegistrationPatches.IsFullyRegistered_Postfix));
|
|
||||||
|
|
||||||
// The two registration dialogs are raised from
|
|
||||||
// DormroomSceneManager's PromptForRegistration via its
|
|
||||||
// compiler-generated <>c lambdas (b__6_0..b__6_3). Reuse the
|
|
||||||
// same nested-lambda patcher the join trace uses.
|
|
||||||
PatchNestedLambdas("DormroomSceneManager", "PromptForRegistration",
|
|
||||||
nameof(RegistrationPatches.PromptLambda_Prefix));
|
|
||||||
|
|
||||||
// The confirm-dialog buttons. Clean, non-generic, no-arg names
|
|
||||||
// on AGUI.StackedUI.Dialog.ConfirmUIDialog — Okay maps to
|
|
||||||
// Button_Affirmative, the screenshot's only button.
|
|
||||||
foreach (var (method, label) in new[]
|
|
||||||
{
|
|
||||||
("Button_Affirmative", nameof(RegistrationPatches.ButtonAffirmative_Prefix)),
|
|
||||||
("Button_Negative", nameof(RegistrationPatches.ButtonNegative_Prefix)),
|
|
||||||
("Button_NotNow", nameof(RegistrationPatches.ButtonNotNow_Prefix)),
|
|
||||||
("Button_Cancel", nameof(RegistrationPatches.ButtonCancel_Prefix)),
|
|
||||||
})
|
|
||||||
{
|
|
||||||
TryPatchByName("AGUI.StackedUI.Dialog.ConfirmUIDialog",
|
|
||||||
method, args: Type.EmptyTypes, prefix: label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RegisterJoinTracePatches();
|
|
||||||
|
|
||||||
// Desktop Screen Sharing FPS override. Only register when a target
|
// Desktop Screen Sharing FPS override. Only register when a target
|
||||||
// is set; the postfix on the gadget's Awake rewrites the baked
|
// is set; the postfix on the gadget's Awake rewrites the baked
|
||||||
// refresh-frequency field (and, if enabled, raises the Photon
|
// refresh-frequency field (and, if enabled, raises the Photon
|
||||||
@@ -360,8 +306,6 @@ public class Mod : MelonMod
|
|||||||
postfix: nameof(QuestTeamSize.RelaxEmptySpawnFilter_Postfix));
|
postfix: nameof(QuestTeamSize.RelaxEmptySpawnFilter_Postfix));
|
||||||
Log.Msg($"[questsize] armed: target {Cfg.QuestMaxTeamSize} for [{string.Join(", ", Cfg.QuestMaxTeamSizeRooms)}]");
|
Log.Msg($"[questsize] armed: target {Cfg.QuestMaxTeamSize} for [{string.Join(", ", Cfg.QuestMaxTeamSizeRooms)}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterDiagnostics();
|
|
||||||
Log.Msg("=== Client patches registered ===");
|
Log.Msg("=== Client patches registered ===");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,38 +520,10 @@ public class Mod : MelonMod
|
|||||||
prefix: nameof(UriPatches.HttpRequestPrepareUri_Prefix));
|
prefix: nameof(UriPatches.HttpRequestPrepareUri_Prefix));
|
||||||
complete &= TryPatchByName("BestHTTP.HTTPRequest", "Send",
|
complete &= TryPatchByName("BestHTTP.HTTPRequest", "Send",
|
||||||
prefix: nameof(UriPatches.HttpRequestSend_Prefix));
|
prefix: nameof(UriPatches.HttpRequestSend_Prefix));
|
||||||
TryPatchByName("BestHTTP.HTTPRequest", "SetHeader",
|
|
||||||
args: new[] { typeof(string), typeof(string) },
|
|
||||||
prefix: nameof(HttpTracePatches.HeaderSet_Prefix));
|
|
||||||
TryPatchByName("BestHTTP.HTTPRequest", "AddHeader",
|
|
||||||
args: new[] { typeof(string), typeof(string) },
|
|
||||||
prefix: nameof(HttpTracePatches.HeaderSet_Prefix));
|
|
||||||
TryPatchByName("BestHTTP.HTTPRequest", "CallCallback",
|
|
||||||
prefix: nameof(HttpTracePatches.CallCallback_Prefix),
|
|
||||||
postfix: nameof(HttpTracePatches.CallCallback_Postfix));
|
|
||||||
complete &= TryPatchHttpManagerStringSendRequestOverloads();
|
complete &= TryPatchHttpManagerStringSendRequestOverloads();
|
||||||
complete &= TryPatchByName("BestHTTP.HTTPManager", "SendRequest",
|
complete &= TryPatchByName("BestHTTP.HTTPManager", "SendRequest",
|
||||||
args: new[] { ResolveType("BestHTTP.HTTPRequest") ?? typeof(object) },
|
args: new[] { ResolveType("BestHTTP.HTTPRequest") ?? typeof(object) },
|
||||||
prefix: nameof(UriPatches.HttpManagerSendRequestObject_Prefix));
|
prefix: nameof(UriPatches.HttpManagerSendRequestObject_Prefix));
|
||||||
TryPatchByName("GFOGGHLDJFF", "JBFGGIJPOLC",
|
|
||||||
prefix: nameof(HttpTracePatches.RecNetRequestSend_Prefix));
|
|
||||||
TryPatchByName("DNKAJOCIFHA", "JBFGGIJPOLC",
|
|
||||||
prefix: nameof(HttpTracePatches.RecNetRequestSend_Prefix));
|
|
||||||
TryPatchByName("GFOGGHLDJFF", "GMFJNBANJJA",
|
|
||||||
args: new[] { typeof(string), typeof(string) },
|
|
||||||
prefix: nameof(HttpTracePatches.HeaderSet_Prefix));
|
|
||||||
TryPatchByName("DNKAJOCIFHA", "GMFJNBANJJA",
|
|
||||||
args: new[] { typeof(string), typeof(string) },
|
|
||||||
prefix: nameof(HttpTracePatches.HeaderSet_Prefix));
|
|
||||||
var httpMethodsType = ResolveType("BestHTTP.HTTPMethods") ?? typeof(object);
|
|
||||||
var recNetServiceType = ResolveType("GJDLNNLKDIJ") ?? typeof(object);
|
|
||||||
TryPatchByName("BNDIAONDFFF", "ctor",
|
|
||||||
args: new[] { httpMethodsType, recNetServiceType, typeof(string) },
|
|
||||||
prefix: nameof(HttpTracePatches.RecNetRequestBuilderCtor_Prefix),
|
|
||||||
postfix: nameof(HttpTracePatches.RecNetRequestBuilderCtor_Postfix));
|
|
||||||
TryPatchByName("BNDIAONDFFF", "FGHNOKLDOKO",
|
|
||||||
prefix: nameof(HttpTracePatches.RecNetResponseTuple_Prefix),
|
|
||||||
postfix: nameof(HttpTracePatches.RecNetResponseTuple_Postfix));
|
|
||||||
|
|
||||||
_networkPatchesRegistered = complete;
|
_networkPatchesRegistered = complete;
|
||||||
}
|
}
|
||||||
@@ -700,19 +616,10 @@ public class Mod : MelonMod
|
|||||||
Log.Msg("[lifecycle] first OnUpdate tick (Unity frame loop is live)");
|
Log.Msg("[lifecycle] first OnUpdate tick (Unity frame loop is live)");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_diagnosticGameComplete) return;
|
|
||||||
if (_diagnosticRetryFrame++ > 3600) return;
|
|
||||||
if ((_diagnosticRetryFrame % 60) != 0) return;
|
|
||||||
|
|
||||||
var logMisses = (_diagnosticRetryFrame % 300) == 0;
|
|
||||||
_diagnosticGameComplete = RegisterGameDiagnostics(logMisses);
|
|
||||||
if (_diagnosticGameComplete)
|
|
||||||
DiagnosticPatches.Write("[diagnostics] all game-side diagnostic hooks registered");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnApplicationQuit()
|
public override void OnApplicationQuit()
|
||||||
{
|
{
|
||||||
DiagnosticPatches.Write("[lifecycle] OnApplicationQuit");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Config ────────────────────────────────────────────────────────
|
// ── Config ────────────────────────────────────────────────────────
|
||||||
@@ -1072,9 +979,6 @@ public class Mod : MelonMod
|
|||||||
args: new[] { typeof(int), typeof(string) },
|
args: new[] { typeof(int), typeof(string) },
|
||||||
prefix: nameof(DiagnosticPatches.SessionManagerFatalApplicationQuit_Prefix),
|
prefix: nameof(DiagnosticPatches.SessionManagerFatalApplicationQuit_Prefix),
|
||||||
logMiss: logMisses);
|
logMiss: logMisses);
|
||||||
TryPatchDiagnosticAllOverloads("BNDIAONDFFF", "FGHNOKLDOKO",
|
|
||||||
finalizer: nameof(HttpTracePatches.RecNetResponseTuple_Finalizer),
|
|
||||||
logMiss: logMisses);
|
|
||||||
RegisterDeepRoomDiagnostics(logMisses);
|
RegisterDeepRoomDiagnostics(logMisses);
|
||||||
// SteamManager.Awake + SteamPlatformManager.*LoginInitialize were
|
// SteamManager.Awake + SteamPlatformManager.*LoginInitialize were
|
||||||
// pure-logging diagnostics that fired during Unity's very first
|
// pure-logging diagnostics that fired during Unity's very first
|
||||||
@@ -2299,9 +2203,14 @@ internal static class HttpTracePatches
|
|||||||
private static readonly Regex SensitiveHeaderRegex = new(
|
private static readonly Regex SensitiveHeaderRegex = new(
|
||||||
@"(?im)^(Authorization|Cookie|Set-Cookie|X-RNSIG):\s*[^\r\n]+",
|
@"(?im)^(Authorization|Cookie|Set-Cookie|X-RNSIG):\s*[^\r\n]+",
|
||||||
RegexOptions.Compiled);
|
RegexOptions.Compiled);
|
||||||
|
private static readonly Regex SensitiveJsonStringRegex = new(
|
||||||
|
@"(?i)""([^""]*(?:access_token|accessToken|refresh_token|refreshToken|authorization|token|secret|client_secret|key)[^""]*)""\s*:\s*""[^""]*""",
|
||||||
|
RegexOptions.Compiled);
|
||||||
|
private static readonly Dictionary<IntPtr, string> RecNetRequestInfoByPtr = new();
|
||||||
private static int _requestId;
|
private static int _requestId;
|
||||||
private static int _failureLogCount;
|
private static int _failureLogCount;
|
||||||
private static int _responseTupleLogCount;
|
private static int _responseTupleLogCount;
|
||||||
|
private static int _builderSendLogCount;
|
||||||
|
|
||||||
public static void RecNetRequestSend_Prefix(object __instance, MethodBase __originalMethod)
|
public static void RecNetRequestSend_Prefix(object __instance, MethodBase __originalMethod)
|
||||||
{
|
{
|
||||||
@@ -2316,6 +2225,63 @@ internal static class HttpTracePatches
|
|||||||
$"service={SanitizeInline(__1?.ToString() ?? "<null>")} path={SanitizeInline(__2?.ToString() ?? "<null>")}");
|
$"service={SanitizeInline(__1?.ToString() ?? "<null>")} path={SanitizeInline(__2?.ToString() ?? "<null>")}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void RecNetRequestBuilderCtor_Postfix(object __instance, object? __0, object? __1, object? __2)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var ptr = TryGetIl2CppPtr(__instance);
|
||||||
|
if (ptr == IntPtr.Zero) return;
|
||||||
|
|
||||||
|
var info =
|
||||||
|
$"ptr=0x{ptr.ToInt64():X} method={SanitizeInline(__0?.ToString() ?? "<null>")} " +
|
||||||
|
$"service={SanitizeInline(__1?.ToString() ?? "<null>")} path={SanitizeInline(__2?.ToString() ?? "<null>")}";
|
||||||
|
lock (RecNetRequestInfoByPtr)
|
||||||
|
{
|
||||||
|
RecNetRequestInfoByPtr[ptr] = info;
|
||||||
|
if (RecNetRequestInfoByPtr.Count > 256)
|
||||||
|
RecNetRequestInfoByPtr.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
DiagnosticPatches.Write($"[recnet-request-map] {info}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFailure("recnet-request-map", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RecNetBuilderSend_Prefix(object __instance, MethodBase __originalMethod)
|
||||||
|
{
|
||||||
|
if (System.Threading.Interlocked.Increment(ref _builderSendLogCount) > 120) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DiagnosticPatches.Write(
|
||||||
|
$"[recnet-send] ENTER {__originalMethod.DeclaringType?.FullName}.{__originalMethod.Name} " +
|
||||||
|
$"{LookupRecNetRequestInfo(__instance)} {DumpBndNativeFields(__instance)}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFailure("recnet-send-enter", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RecNetBuilderSend_Postfix(object __instance, MethodBase __originalMethod)
|
||||||
|
{
|
||||||
|
if (_builderSendLogCount > 120) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DiagnosticPatches.Write(
|
||||||
|
$"[recnet-send] EXIT {__originalMethod.DeclaringType?.FullName}.{__originalMethod.Name} " +
|
||||||
|
$"{LookupRecNetRequestInfo(__instance)} {DumpBndNativeFields(__instance)}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFailure("recnet-send-exit", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void RecNetResponseTuple_Prefix(object __instance, MethodBase __originalMethod)
|
public static void RecNetResponseTuple_Prefix(object __instance, MethodBase __originalMethod)
|
||||||
{
|
{
|
||||||
if (System.Threading.Interlocked.Increment(ref _responseTupleLogCount) > 80) return;
|
if (System.Threading.Interlocked.Increment(ref _responseTupleLogCount) > 80) return;
|
||||||
@@ -2324,7 +2290,7 @@ internal static class HttpTracePatches
|
|||||||
{
|
{
|
||||||
DiagnosticPatches.Write(
|
DiagnosticPatches.Write(
|
||||||
$"[recnet-response-map] ENTER {__originalMethod.DeclaringType?.FullName}.{__originalMethod.Name} " +
|
$"[recnet-response-map] ENTER {__originalMethod.DeclaringType?.FullName}.{__originalMethod.Name} " +
|
||||||
DumpObjectFields(__instance, 20, 600));
|
$"{LookupRecNetRequestInfo(__instance)} {DumpBndNativeFields(__instance)} {DumpObjectFields(__instance, 20, 600)}");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -2340,7 +2306,7 @@ internal static class HttpTracePatches
|
|||||||
{
|
{
|
||||||
DiagnosticPatches.Write(
|
DiagnosticPatches.Write(
|
||||||
$"[recnet-response-map] EXIT {__originalMethod.DeclaringType?.FullName}.{__originalMethod.Name} " +
|
$"[recnet-response-map] EXIT {__originalMethod.DeclaringType?.FullName}.{__originalMethod.Name} " +
|
||||||
DumpObjectFields(__instance, 20, 600));
|
$"{LookupRecNetRequestInfo(__instance)} {DumpBndNativeFields(__instance)} {DumpObjectFields(__instance, 20, 600)}");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -2354,7 +2320,8 @@ internal static class HttpTracePatches
|
|||||||
{
|
{
|
||||||
DiagnosticPatches.Write(
|
DiagnosticPatches.Write(
|
||||||
$"[recnet-response-map] EXCEPTION {__originalMethod.DeclaringType?.FullName}.{__originalMethod.Name} " +
|
$"[recnet-response-map] EXCEPTION {__originalMethod.DeclaringType?.FullName}.{__originalMethod.Name} " +
|
||||||
$"{RoomLoadDiagnostics.FormatException(__exception, __exception)} state={DumpObjectFields(__instance, 36, 1200)}");
|
$"{LookupRecNetRequestInfo(__instance)} {DumpBndNativeFields(__instance)} {RoomLoadDiagnostics.FormatException(__exception, __exception)} " +
|
||||||
|
$"state={DumpObjectFields(__instance, 36, 1200)}");
|
||||||
}
|
}
|
||||||
return __exception;
|
return __exception;
|
||||||
}
|
}
|
||||||
@@ -2823,6 +2790,78 @@ internal static class HttpTracePatches
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string LookupRecNetRequestInfo(object instance)
|
||||||
|
{
|
||||||
|
var ptr = TryGetIl2CppPtr(instance);
|
||||||
|
if (ptr == IntPtr.Zero) return "ptr=<unread>";
|
||||||
|
|
||||||
|
lock (RecNetRequestInfoByPtr)
|
||||||
|
{
|
||||||
|
return RecNetRequestInfoByPtr.TryGetValue(ptr, out var info)
|
||||||
|
? info
|
||||||
|
: $"ptr=0x{ptr.ToInt64():X} request=<unmapped>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string DumpBndNativeFields(object? instance)
|
||||||
|
{
|
||||||
|
var ptr = TryGetIl2CppPtr(instance);
|
||||||
|
if (ptr == IntPtr.Zero) return "native=<unread>";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var method = Marshal.ReadByte(ptr, 16);
|
||||||
|
var service = Marshal.ReadInt32(ptr, 20);
|
||||||
|
var pathPtr = Marshal.ReadIntPtr(ptr, 24);
|
||||||
|
var fieldsPtr = Marshal.ReadIntPtr(ptr, 32);
|
||||||
|
var filesPtr = Marshal.ReadIntPtr(ptr, 40);
|
||||||
|
var objectFieldsPtr = Marshal.ReadIntPtr(ptr, 48);
|
||||||
|
var bodyKind = Marshal.ReadInt32(ptr, 56);
|
||||||
|
var callbackPtr = Marshal.ReadIntPtr(ptr, 64);
|
||||||
|
var path = ReadIl2CppString(pathPtr);
|
||||||
|
|
||||||
|
return
|
||||||
|
"native={" +
|
||||||
|
$"method={method}; service={service}; path={SanitizeInline(path)}; " +
|
||||||
|
$"pathPtr=0x{pathPtr.ToInt64():X}; fieldsPtr=0x{fieldsPtr.ToInt64():X}; " +
|
||||||
|
$"filesPtr=0x{filesPtr.ToInt64():X}; objectFieldsPtr=0x{objectFieldsPtr.ToInt64():X}; " +
|
||||||
|
$"bodyKind={bodyKind}; callbackPtr=0x{callbackPtr.ToInt64():X}" +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return $"native=<dump failed {ex.GetType().Name}: {SanitizeInline(ex.Message)}>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ReadIl2CppString(IntPtr ptr)
|
||||||
|
{
|
||||||
|
if (ptr == IntPtr.Zero) return "<null>";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return IL2CPP.Il2CppStringToManaged(ptr) ?? "<null>";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return $"<string read failed 0x{ptr.ToInt64():X} {ex.GetType().Name}>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IntPtr TryGetIl2CppPtr(object? instance)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return instance is Il2CppObjectBase il2CppObject
|
||||||
|
? IL2CPP.Il2CppObjectBaseToPtrNotNull(il2CppObject)
|
||||||
|
: IntPtr.Zero;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static string RedactHeaderValue(string name, string? value)
|
private static string RedactHeaderValue(string name, string? value)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(value)) return "<empty>";
|
if (string.IsNullOrWhiteSpace(value)) return "<empty>";
|
||||||
@@ -2842,6 +2881,7 @@ internal static class HttpTracePatches
|
|||||||
var redacted = SensitivePairRegex.Replace(value, "$1=<redacted>");
|
var redacted = SensitivePairRegex.Replace(value, "$1=<redacted>");
|
||||||
redacted = BearerRegex.Replace(redacted, "Bearer <redacted>");
|
redacted = BearerRegex.Replace(redacted, "Bearer <redacted>");
|
||||||
redacted = SensitiveHeaderRegex.Replace(redacted, "$1: <redacted>");
|
redacted = SensitiveHeaderRegex.Replace(redacted, "$1: <redacted>");
|
||||||
|
redacted = SensitiveJsonStringRegex.Replace(redacted, "\"$1\":\"<redacted>\"");
|
||||||
redacted = redacted.Replace("\r", "\\r").Replace("\n", "\\n").Replace("\t", "\\t");
|
redacted = redacted.Replace("\r", "\\r").Replace("\n", "\\n").Replace("\t", "\\t");
|
||||||
return redacted.Length <= 1200 ? redacted : redacted[..1200] + "...<truncated>";
|
return redacted.Length <= 1200 ? redacted : redacted[..1200] + "...<truncated>";
|
||||||
}
|
}
|
||||||
@@ -2879,7 +2919,6 @@ internal static class UriPatches
|
|||||||
public static void HttpManagerSendRequestObject_Prefix(object request)
|
public static void HttpManagerSendRequestObject_Prefix(object request)
|
||||||
{
|
{
|
||||||
RewriteRequestUri(request, "httpmanager-request-rewrite");
|
RewriteRequestUri(request, "httpmanager-request-rewrite");
|
||||||
HttpTracePatches.TraceRequestObject(request, "BestHTTP.HTTPManager.SendRequest(HTTPRequest)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UriStringCtor_Prefix(ref string uriString)
|
public static void UriStringCtor_Prefix(ref string uriString)
|
||||||
@@ -2891,7 +2930,6 @@ internal static class UriPatches
|
|||||||
public static void HttpRequestSend_Prefix(object __instance)
|
public static void HttpRequestSend_Prefix(object __instance)
|
||||||
{
|
{
|
||||||
RewriteRequestUri(__instance, "http-rewrite");
|
RewriteRequestUri(__instance, "http-rewrite");
|
||||||
HttpTracePatches.TraceRequestObject(__instance, "BestHTTP.HTTPRequest.Send");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RewriteRequestUri(object request, string label)
|
private static void RewriteRequestUri(object request, string label)
|
||||||
|
|||||||
Reference in New Issue
Block a user