Example #1
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]);
            }
        }