using System; using System.Reflection; using System.Threading.Tasks; using BestHTTP; using BestHTTP.Forms; using HarmonyLib; using undead_universal_patch_il2cpp.Core; using undead_universal_patch_il2cpp.Core.Config; using UnityEngine; namespace undead_universal_patch_il2cpp.Patches { [HarmonyPatch] public class BestHTTPProxy { static PatchTypesResult patchResult = Util.PreparePatchSpecificTypes( "BestHTTP request URL rewrite patch", "BestHTTP.HTTPManager", "SendRequest", [ "BestHTTP.HTTPRequest", ] ); static readonly Type requestType = AccessTools.TypeByName("BestHTTP.HTTPRequest"); static readonly MethodInfo getHeaderMethod = requestType?.GetMethod("GetFirstHeaderValue"); static readonly MethodInfo addHeaderMethod = requestType?.GetMethod("AddHeader"); static readonly MethodInfo getFormFields = requestType?.GetMethod("GetFormFields"); static readonly PropertyInfo formImplProp = requestType?.GetProperty("FormImpl"); static readonly PropertyInfo methodTypeProp = requestType?.GetProperty("MethodType"); static readonly PropertyInfo uriProp = requestType?.GetProperty("Uri"); static readonly PropertyInfo customCertProp = requestType?.GetProperty("CustomCertificateVerifyer"); static bool Prepare() => Util.PostRequireTypes(patchResult, [ getHeaderMethod, addHeaderMethod, methodTypeProp, getFormFields, formImplProp, uriProp, customCertProp ]).Success; static MethodBase TargetMethod() => patchResult.Method; static void Prefix(ref object request) { if (PatchConfig.CertificatePatch.Value) customCertProp.GetSetMethod().Invoke(request, [null]); var contentType = (string)getHeaderMethod.Invoke(request, ["Content-Type"]); HTTPMethods method = (HTTPMethods)methodTypeProp.GetGetMethod().Invoke(request, []); var uriInstance = (Il2CppSystem.Uri)uriProp.GetValue(request, null); if (uriInstance == null) { UniversalPatchPlugin.Log.LogFatal("BestHTTPProxy failed: uriInstance was null."); return; } string beforeUrl = uriInstance.ToString(); Il2CppSystem.Uri newUri = new(uriInstance.ToString()); // Start request changes if (newUri.Host.Contains("ns.rec.net")) newUri = new Il2CppSystem.Uri(NameserverConfig.NewUrl.Value); bool isAccCreate = newUri.PathAndQuery.Contains("account/create"); if (isAccCreate && SteamPlatform.AuthTicket != null) { HTTPFormBase form = (HTTPFormBase)formImplProp.GetValue(request, null); form.AddField("x-steam-ticket", SteamPlatform.AuthTicket); Util.ConditionalDebug("Added Steam ticket to create request"); } else if (isAccCreate) UniversalPatchPlugin.Log.LogError("The Steam auth ticket has not yet been fetched, account creation might fail!"); // Finish request changes string afterUrl = newUri.ToString(); uriProp.SetValue(request, NameserverConfig.Rewrite.Value ? newUri : uriInstance, null); if (GenericConfig.LogAllRequests.Value) { if (GenericConfig.VerboseRequestLogs.Value) UniversalPatchPlugin.Log.LogInfo($"BestHTTP Request Log{(customCertProp.GetGetMethod().Invoke(request, []) == null ? "" : " (verify)")}\n" + $" URL Before : {beforeUrl}\n" + $" URL After : {(beforeUrl == afterUrl ? "(unmodified)" : afterUrl)}\n" + $" Method : {method}\n" + $" Content-Type : {contentType ?? "(not set)"}"); else UniversalPatchPlugin.Log.LogInfo("BestHTTPProxy Request\n" + $" {method} {afterUrl}"); } } } }