public override void OnApplicationStart() { AdvancedSafetySettings.RegisterSettings(); var matchingMethods = typeof(AssetManagement) .GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly).Where(it => it.Name.StartsWith("Method_Public_Static_Object_Object_Vector3_Quaternion_Boolean_Boolean_Boolean_") && it.GetParameters().Length == 6).ToList(); foreach (var matchingMethod in matchingMethods) { unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(matchingMethod).GetValue(null); ObjectInstantiateDelegate originalInstantiateDelegate = null; ObjectInstantiateDelegate replacement = (assetPtr, pos, rot, allowCustomShaders, isUI, validate, nativeMethodPointer) => ObjectInstantiatePatch(assetPtr, pos, rot, allowCustomShaders, isUI, validate, nativeMethodPointer, originalInstantiateDelegate); ourPinnedDelegates.Add(replacement); Imports.Hook((IntPtr)(&originalMethodPointer), Marshal.GetFunctionPointerForDelegate(replacement)); originalInstantiateDelegate = Marshal.GetDelegateForFunctionPointer <ObjectInstantiateDelegate>(originalMethodPointer); } } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumA).GetMethod( nameof(AMEnumA.MoveNext))) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchA), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextA = originalMethodPointer; } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumB).GetMethod( nameof(AMEnumB.MoveNext))) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchB), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextB = originalMethodPointer; } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumC).GetMethod( nameof(AMEnumC.MoveNext))) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchC), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextC = originalMethodPointer; } unsafe { var originalMethodInfo = (Il2CppMethodInfo *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumB).GetMethod( nameof(AMEnumB.MoveNext))) .GetValue(null); var methodInfoCopy = (Il2CppMethodInfo *)Marshal.AllocHGlobal(Marshal.SizeOf <Il2CppMethodInfo>()); * methodInfoCopy = *originalMethodInfo; ourInvokeMethodInfo = (IntPtr)methodInfoCopy; } PortalHiding.OnApplicationStart(); AvatarHiding.OnApplicationStart(harmonyInstance); if (MelonHandler.Mods.Any(it => it.Info.SystemType.Name == nameof(UiExpansionKitMod))) { typeof(UiExpansionKitSupport).GetMethod(nameof(UiExpansionKitSupport.OnApplicationStart), BindingFlags.Static | BindingFlags.Public) !.Invoke(null, new object[0]); } }
public override void OnApplicationStart() { if (!CheckWasSuccessful || !MustStayTrue || MustStayFalse) { return; } AdvancedSafetySettings.RegisterSettings(); ClassInjector.RegisterTypeInIl2Cpp <SortingOrderHammerer>(); try { BundleVerifierMod.OnApplicationStart(HarmonyInstance); } catch (Exception ex) { MelonLogger.Error($"Error initializing Bundle Verifier: {ex}"); } var matchingMethods = typeof(AssetManagement) .GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly).Where(it => it.Name.StartsWith("Method_Public_Static_Object_Object_Vector3_Quaternion_Boolean_Boolean_Boolean_") && it.GetParameters().Length == 6).ToList(); foreach (var matchingMethod in matchingMethods) { ObjectInstantiateDelegate originalInstantiateDelegate = null; ObjectInstantiateDelegate replacement = (assetPtr, pos, rot, allowCustomShaders, isUI, validate, nativeMethodPointer) => ObjectInstantiatePatch(assetPtr, pos, rot, allowCustomShaders, isUI, validate, nativeMethodPointer, originalInstantiateDelegate); NativePatchUtils.NativePatch(matchingMethod, out originalInstantiateDelegate, replacement); } foreach (var nestedType in typeof(VRCAvatarManager).GetNestedTypes()) { var moveNext = nestedType.GetMethod("MoveNext"); if (moveNext == null) { continue; } var avatarManagerField = nestedType.GetProperties().SingleOrDefault(it => it.PropertyType == typeof(VRCAvatarManager)); if (avatarManagerField == null) { continue; } MelonDebug.Msg($"Patching UniTask type {nestedType.FullName}"); var fieldOffset = (int)IL2CPP.il2cpp_field_get_offset((IntPtr)UnhollowerUtils .GetIl2CppFieldInfoPointerFieldForGeneratedFieldAccessor(avatarManagerField.GetMethod) .GetValue(null)); unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(moveNext).GetValue(null); originalMethodPointer = XrefScannerLowLevel.JumpTargets(originalMethodPointer).First(); VoidDelegate originalDelegate = null; void TaskMoveNextPatch(IntPtr taskPtr, IntPtr nativeMethodInfo) { var avatarManager = *(IntPtr *)(taskPtr + fieldOffset - 16); using (new AvatarManagerCookie(new VRCAvatarManager(avatarManager))) originalDelegate(taskPtr, nativeMethodInfo); } var patchDelegate = new VoidDelegate(TaskMoveNextPatch); NativePatchUtils.NativePatch(originalMethodPointer, out originalDelegate, patchDelegate); } } ReaderPatches.ApplyPatches(); SceneManager.add_sceneLoaded(new Action <Scene, LoadSceneMode>((s, _) => { if (s.buildIndex == -1) { CanReadAudioMixers = false; CanReadBadFloats = false; MelonDebug.Msg("No reading audio mixers anymore"); } })); SceneManager.add_sceneUnloaded(new Action <Scene>(s => { if (s.buildIndex == -1) { // allow loading mixers from world assetbundles CanReadAudioMixers = true; CanReadBadFloats = true; MelonDebug.Msg("Can read audio mixers now"); } })); PortalHiding.OnApplicationStart(); AvatarHiding.OnApplicationStart(HarmonyInstance); FinalIkPatches.ApplyPatches(HarmonyInstance); if (MelonHandler.Mods.Any(it => it.Info.Name == "UI Expansion Kit")) { typeof(UiExpansionKitSupport).GetMethod(nameof(UiExpansionKitSupport.OnApplicationStart), BindingFlags.Static | BindingFlags.Public) !.Invoke(null, new object[0]); } }
public override void OnApplicationStart() { AdvancedSafetySettings.RegisterSettings(); var matchingMethods = typeof(AssetManagement) .GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly).Where(it => it.Name.StartsWith("Method_Public_Static_Object_Object_Vector3_Quaternion_Boolean_Boolean_Boolean_") && it.GetParameters().Length == 6).ToList(); foreach (var matchingMethod in matchingMethods) { unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(matchingMethod).GetValue(null); ObjectInstantiateDelegate originalInstantiateDelegate = null; ObjectInstantiateDelegate replacement = (assetPtr, pos, rot, allowCustomShaders, isUI, validate, nativeMethodPointer) => ObjectInstantiatePatch(assetPtr, pos, rot, allowCustomShaders, isUI, validate, nativeMethodPointer, originalInstantiateDelegate); ourPinnedDelegates.Add(replacement); MelonUtils.NativeHookAttach((IntPtr)(&originalMethodPointer), Marshal.GetFunctionPointerForDelegate(replacement)); originalInstantiateDelegate = Marshal.GetDelegateForFunctionPointer <ObjectInstantiateDelegate>(originalMethodPointer); } } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumA).GetMethod( nameof(AMEnumA.MoveNext))) .GetValue(null); MelonUtils.NativeHookAttach((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchA), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextA = originalMethodPointer; } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumB).GetMethod( nameof(AMEnumB.MoveNext))) .GetValue(null); MelonUtils.NativeHookAttach((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchB), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextB = originalMethodPointer; } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumC).GetMethod( nameof(AMEnumC.MoveNext))) .GetValue(null); MelonUtils.NativeHookAttach((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchC), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextC = originalMethodPointer; } unsafe { var originalMethodInfo = (Il2CppMethodInfo *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumB).GetMethod( nameof(AMEnumB.MoveNext))) .GetValue(null); var methodInfoCopy = (Il2CppMethodInfo *)Marshal.AllocHGlobal(Marshal.SizeOf <Il2CppMethodInfo>()); * methodInfoCopy = *originalMethodInfo; ourInvokeMethodInfo = (IntPtr)methodInfoCopy; } foreach (ProcessModule module in Process.GetCurrentProcess().Modules) { if (!module.FileName.Contains("UnityPlayer")) { continue; } // ProduceHelper<AudioMixer,0>::Produce, thanks to Ben for finding an adjacent method ourAudioMixerReadPointer = module.BaseAddress + 0x4997C0; var patchDelegate = new AudioMixerReadDelegate(AudioMixerReadPatch); ourPinnedDelegates.Add(patchDelegate); unsafe { fixed(IntPtr *mixerReadAddress = &ourAudioMixerReadPointer) MelonUtils.NativeHookAttach((IntPtr)mixerReadAddress, Marshal.GetFunctionPointerForDelegate(patchDelegate)); ourAudioMixerReadDelegate = Marshal.GetDelegateForFunctionPointer <AudioMixerReadDelegate>(ourAudioMixerReadPointer); } break; } SceneManager.add_sceneLoaded(new Action <Scene, LoadSceneMode>((s, _) => { if (s.buildIndex == -1) { ourCanReadAudioMixers = false; MelonDebug.Msg("No reading audio mixers anymore"); } })); SceneManager.add_sceneUnloaded(new Action <Scene>(s => { if (s.buildIndex == -1) { // allow loading mixers from world assetbundles ourCanReadAudioMixers = true; MelonDebug.Msg("Can read audio mixers now"); } })); PortalHiding.OnApplicationStart(); AvatarHiding.OnApplicationStart(Harmony); if (MelonHandler.Mods.Any(it => it.Info.SystemType.Name == nameof(UiExpansionKitMod))) { typeof(UiExpansionKitSupport).GetMethod(nameof(UiExpansionKitSupport.OnApplicationStart), BindingFlags.Static | BindingFlags.Public) !.Invoke(null, new object[0]); } }
public override void OnApplicationStart() { AdvancedSafetySettings.RegisterSettings(); var matchingMethods = typeof(AssetManagement) .GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly).Where(it => it.Name.StartsWith("Method_Public_Static_Object_Object_Vector3_Quaternion_Boolean_Boolean_Boolean_") && it.GetParameters().Length == 6).ToList(); MethodBase patchTarget = null; foreach (var methodInfo in typeof(AssetManagement).GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)) { foreach (var it in XrefScanner.XrefScan(methodInfo)) { if (it.Type != XrefType.Method) { continue; } var methodBase = it.TryResolve(); if (methodBase == null) { continue; } if (matchingMethods.Contains(methodBase)) { patchTarget = methodBase; goto haveTarget; } } } haveTarget: if (patchTarget != null) { unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(patchTarget).GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(ObjectInstantiatePatch), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourOriginalInstantiate = Marshal.GetDelegateForFunctionPointer <ObjectInstantiateDelegate>(originalMethodPointer); } } else { MelonLogger.LogError("Patch target for object instantiation not found, avatar filtering will not work"); } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumA).GetMethod( nameof(AMEnumA.MoveNext))) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchA), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextA = originalMethodPointer; } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumB).GetMethod( nameof(AMEnumB.MoveNext))) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchB), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextB = originalMethodPointer; } unsafe { var originalMethodInfo = (Il2CppMethodInfo *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumB).GetMethod( nameof(AMEnumB.MoveNext))) .GetValue(null); var methodInfoCopy = (Il2CppMethodInfo *)Marshal.AllocHGlobal(Marshal.SizeOf <Il2CppMethodInfo>()); * methodInfoCopy = *originalMethodInfo; ourInvokeMethodInfo = (IntPtr)methodInfoCopy; } PortalHiding.OnApplicationStart(); AvatarHiding.OnApplicationStart(); if (MelonHandler.Mods.Any(it => it.Info.SystemType.Name == nameof(UiExpansionKitMod))) { typeof(UiExpansionKitSupport).GetMethod(nameof(UiExpansionKitSupport.OnApplicationStart), BindingFlags.Static | BindingFlags.Public) !.Invoke(null, new object[0]); } }