private static void SetupSupportModule(AppDomain domain)
 {
     try
     {
         string BaseDirectory = Path.Combine(Path.Combine(Path.Combine(MelonUtils.GameDirectory, "MelonLoader"), "Dependencies"), "SupportModules");
         if (!Directory.Exists(BaseDirectory))
         {
             MelonLogger.Error("Failed to Find SupportModules Directory!");
             return;
         }
         Assembly CompatibilityLayerAssembly = Assembly.LoadFrom(Path.Combine(BaseDirectory, "CompatibilityLayer.dll"));
         if (CompatibilityLayerAssembly == null)
         {
             MelonLogger.Error("Failed to Load Assembly for CompatibilityLayer!");
             return;
         }
         Type CompatibilityLayerType = CompatibilityLayerAssembly.GetType("MelonLoader.Support.CompatibilityLayer");
         if (CompatibilityLayerType == null)
         {
             MelonLogger.Error("Failed to Get Type for CompatibilityLayer!");
             return;
         }
         MethodInfo CompatibilityLayerSetupMethod = CompatibilityLayerType.GetMethod("Setup", BindingFlags.NonPublic | BindingFlags.Static);
         if (CompatibilityLayerType == null)
         {
             MelonLogger.Error("Failed to Get Setup Method for CompatibilityLayer!");
             return;
         }
         CompatibilityLayerSetupMethod.Invoke(null, new object[] { domain });
     }
     catch (Exception ex) { MelonLogger.Error(ex.ToString()); }
 }
        public override DynamicMethodDefinition CopyOriginal()
        {
            DynamicMethodDefinition method = Original.ToNewDynamicMethodDefinition();

            method.Definition.Name += "_wrapper";
            ILContext      ilcontext          = new ILContext(method.Definition);
            ILCursor       ilcursor           = new ILCursor(ilcontext);
            FieldReference tempfieldreference = null;

            if (ilcursor.TryGotoNext(x => x.MatchLdsfld(out tempfieldreference), x => x.MatchCall(UnhollowerSupport.IL2CPPType, "il2cpp_object_get_virtual_method")))
            {
                // Virtual method: Replace the sequence
                // - ldarg.0
                // - call native int[UnhollowerBaseLib] UnhollowerBaseLib.IL2CPP::Il2CppObjectBaseToPtr(class [UnhollowerBaseLib] UnhollowerBaseLib.Il2CppObjectBase)
                // - ldsfld native int SomeClass::NativeMethodInfoPtr_Etc
                // - call native int[UnhollowerBaseLib] UnhollowerBaseLib.IL2CPP::il2cpp_object_get_virtual_method(native int, native int)

                ilcursor.Index -= 2;
                ilcursor.RemoveRange(4);
            }
            else if (ilcursor.TryGotoNext(x => x.MatchLdsfld(UnhollowerSupport.MethodBaseToIl2CppFieldInfo(Original))))
            {
                ilcursor.Remove();
            }
            else
            {
                MelonLogger.Error("Harmony Patcher could not rewrite Il2Cpp Unhollowed Method. Expect a stack overflow.");
                return(method);
            }
            ilcursor.Emit(Mono.Cecil.Cil.OpCodes.Ldc_I8, copiedMethodInfoPointer.ToInt64());
            ilcursor.Emit(Mono.Cecil.Cil.OpCodes.Conv_I);
            return(method);
        }
Esempio n. 3
0
 public void SaveToFile(bool printmsg = true)
 {
     Preferences.IO.File currentfile = File;
     if (currentfile == null)
     {
         currentfile = MelonPreferences.DefaultFile;
     }
     foreach (MelonPreferences_Entry entry in Entries)
     {
         if (!(entry.DontSaveDefault && entry.GetValueAsString() == entry.GetDefaultValueAsString()) && entry.GetValueAsString() != null)
         {
             currentfile.InsertIntoDocument(Identifier, entry.Identifier, entry.Save());
         }
     }
     try
     {
         currentfile.Save();
     }
     catch (Exception ex)
     {
         MelonLogger.Error($"Error while Saving Preferences to {currentfile.FilePath}: {ex}");
         currentfile.WasError = true;
     }
     if (printmsg)
     {
         MelonLogger.Msg($"MelonPreferences Saved to {currentfile.FilePath}");
     }
     MelonHandler.OnPreferencesSaved();
 }
Esempio n. 4
0
        internal static bool Setup()
        {
            UnityEngine_CoreModule_Path = Path.Combine(MelonUtils.GetManagedDirectory(), "UnityEngine.CoreModule.dll");

            BaseDirectory = Path.Combine(Path.Combine(Path.Combine(MelonUtils.BaseDirectory, "MelonLoader"), "Dependencies"), "SupportModules");
            if (!Directory.Exists(BaseDirectory))
            {
                MelonLogger.Error("Failed to Find SupportModules Directory!");
                return(false);
            }

            LemonEnumerator <ModuleListing> enumerator = new LemonEnumerator <ModuleListing>(Modules);

            while (enumerator.MoveNext())
            {
                string ModulePath = Path.Combine(BaseDirectory, enumerator.Current.FileName);
                if (!File.Exists(ModulePath))
                {
                    continue;
                }

                try
                {
                    if (enumerator.Current.LoadSpecifier != null)
                    {
                        if (!enumerator.Current.LoadSpecifier())
                        {
                            File.Delete(ModulePath);
                            continue;
                        }
                    }

                    if (Interface != null)
                    {
                        continue;
                    }

                    if (!LoadInterface(ModulePath))
                    {
                        continue;
                    }
                }
                catch (Exception ex)
                {
                    MelonDebug.Error($"Support Module [{enumerator.Current.FileName}] threw an Exception: {ex}");
                    continue;
                }
            }

            if (Interface == null)
            {
                MelonLogger.Error("No Support Module Loaded!");
                return(false);
            }
            return(true);
        }
 // Returns true if 'assembly' was already loaded or could be loaded, false if the required assembly was missing.
 private static bool TryLoad(AssemblyName assembly)
 {
     try {
         Assembly.Load(assembly);
         return(true);
     } catch (FileNotFoundException) {
         return(false);
     } catch (Exception ex) {
         MelonLogger.Error("Loading mod dependency failed: " + ex);
         return(false);
     }
 }
Esempio n. 6
0
 internal static void Quit()
 {
     MelonHandler.OnApplicationQuit();
     try { MelonPreferences.Save(); } catch (Exception ex) { MelonLogger.Error("MelonPreferences.Save Exception: " + ex.ToString()); MelonPreferences.WasError = true; }
     Harmony.HarmonyInstance.UnpatchAllInstances();
     try { bHaptics.Quit(); } catch (Exception ex) { MelonLogger.Error("bHaptics.Quit Exception: " + ex.ToString()); bHaptics.WasError = true; }
     MelonLogger.Flush();
     if (QuitFix())
     {
         System.Diagnostics.Process.GetCurrentProcess().Kill();
     }
 }
Esempio n. 7
0
 private static void Start()
 {
     if (!SupportModule.Initialize())
     {
         return;
     }
     AddUnityDebugLog();
     try { bHaptics.Start(); } catch (Exception ex) { MelonLogger.Error("bHaptics.Start Exception: " + ex.ToString()); bHaptics.WasError = true; }
     MelonHandler.OnApplicationStart_Plugins();
     MelonHandler.LoadMods();
     Main.LegacySupport();
     MelonHandler.OnApplicationStart_Mods();
 }
        internal static bool Initialize()
        {
            MelonLogger.Msg("Loading Support Module...");
            string BaseDirectory = Path.Combine(Path.Combine(Path.Combine(MelonUtils.GameDirectory, "MelonLoader"), "Dependencies"), "SupportModules");

            if (!Directory.Exists(BaseDirectory))
            {
                MelonLogger.Error("Failed to Find SupportModules Directory!");
                return(false);
            }
            string ModuleName = (MelonUtils.IsGameIl2Cpp() ? "Il2Cpp.dll"
                : (File.Exists(Path.Combine(MelonUtils.GetManagedDirectory(), "UnityEngine.CoreModule.dll")) ? "Mono.dll"
                : (IsOldUnity() ? "Mono.Pre-5.dll"
                : "Mono.Pre-2017.dll")));
            string ModulePath = Path.Combine(BaseDirectory, ModuleName);

            if (!File.Exists(ModulePath))
            {
                MelonLogger.Error("Failed to Find Support Module " + ModuleName + "!");
                return(false);
            }
            try
            {
                Assembly assembly = Assembly.LoadFrom(ModulePath);
                if (assembly == null)
                {
                    MelonLogger.Error("Failed to Load Assembly from " + ModuleName + "!");
                    return(false);
                }
                Type type = assembly.GetType("MelonLoader.Support.Main");
                if (type == null)
                {
                    MelonLogger.Error("Failed to Get Type MelonLoader.Support.Main!");
                    return(false);
                }
                MethodInfo method = type.GetMethod("Initialize", BindingFlags.NonPublic | BindingFlags.Static);
                if (method == null)
                {
                    MelonLogger.Error("Failed to Get Method Initialize!");
                    return(false);
                }
                Interface = (ISupportModule_To)method.Invoke(null, new object[] { new SupportModule_From() });
                if (Interface == null)
                {
                    MelonLogger.Error("Failed to Initialize Interface!");
                    return(false);
                }
            }
            catch (Exception ex) { MelonLogger.Error(ex.ToString()); return(false); }
            return(true);
        }
Esempio n. 9
0
        internal static int Initialize(ConfigFile configFile)
        {
            AppDomain curDomain = AppDomain.CurrentDomain;

            HarmonyInstance = new HarmonyLib.Harmony(BuildInfo.Name);

            if (MelonLaunchOptions.Core.EnableFixes)
            {
                Fixes.UnhandledException.Run(curDomain);
                Fixes.InvariantCurrentCulture.Install();
            }

            try { MelonUtils.Setup(); } catch (Exception ex) { MelonLogger.Error($"MelonUtils.Setup Exception: {ex}"); throw; }

            if (MelonLaunchOptions.Core.EnableFixes)
            {
                Fixes.ApplicationBase.Run(curDomain);
                Fixes.ExtraCleanup.Run();
            }

            MelonPreferences.Load();
            MelonLaunchOptions.Load(configFile);

            if (MelonLaunchOptions.Core.EnableCompatibilityLayers)
            {
                MelonCompatibilityLayer.Setup();
            }

            if (MelonLaunchOptions.Core.EnablePatchShield)
            {
                PatchShield.Install();
            }

            if (MelonLaunchOptions.Core.EnableBHapticsIntegration)
            {
                bHaptics.Load();
            }

            if (MelonLaunchOptions.Core.EnableCompatibilityLayers)
            {
                MelonCompatibilityLayer.SetupModules(MelonCompatibilityLayer.SetupType.OnPreInitialization);
            }

            MelonHandler.LoadPlugins();
            MelonHandler.OnPreInitialization();

            return(0);
        }
        internal static void Load()
        {
            if (!MelonUtils.IsGameIl2Cpp())
            {
                return;
            }

            MelonLogger.Msg("Loading Il2CppAssemblyGenerator...");

            string BaseDirectory = Path.Combine(Path.Combine(Path.Combine(MelonUtils.GameDirectory, "MelonLoader"), "Dependencies"), "Il2CppAssemblyGenerator");

            if (!Directory.Exists(BaseDirectory))
            {
                MelonLogger.Error("Failed to Find Il2CppAssemblyGenerator Directory!");
                return;
            }

            string AssemblyPath = Path.Combine(BaseDirectory, FileNameWithExtension);

            if (!File.Exists(AssemblyPath))
            {
                MelonLogger.Error($"Failed to Find {FileNameWithExtension}!");
                return;
            }

            try
            {
                asm = Assembly.LoadFrom(AssemblyPath);
                if (asm == null)
                {
                    MelonLogger.ThrowInternalFailure($"Failed to Load Assembly for {FileNameWithExtension}!");
                    return;
                }

                AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolver;

                Type type = asm.GetType("MelonLoader.Il2CppAssemblyGenerator.Core");
                if (type == null)
                {
                    MelonLogger.ThrowInternalFailure($"Failed to Get Type for MelonLoader.Il2CppAssemblyGenerator.Core!");
                    return;
                }

                RunMethod = type.GetMethod("Run", BindingFlags.NonPublic | BindingFlags.Static);
            }
            catch (Exception ex) { MelonLogger.ThrowInternalFailure($"Il2CppAssemblyGenerator Exception: {ex}"); }
        }
Esempio n. 11
0
        static Core()
        {
            AppDomain curDomain = AppDomain.CurrentDomain;

            HarmonyInstance = new HarmonyLib.Harmony(BuildInfo.Name);

            Fixes.UnhandledException.Run(curDomain);
            Fixes.InvariantCurrentCulture.Install();

            try { MelonUtils.Setup(); } catch (Exception ex) { MelonLogger.Error("MelonUtils.Setup Exception: " + ex.ToString()); throw ex; }

            Fixes.ApplicationBase.Run(curDomain);
            Fixes.ExtraCleanup.Run();

            MelonPreferences.Load();
            MelonLaunchOptions.Load();
            MelonCompatibilityLayer.Setup(curDomain);

            //PatchShield.Install();
        }
Esempio n. 12
0
 static Core()
 {
     try { MelonUtils.Setup(); } catch (Exception ex) { MelonLogger.Error("MelonUtils.Setup Exception: " + ex.ToString()); throw ex; }
     Harmony.HarmonyInstance harmonyInstance = Harmony.HarmonyInstance.Create("MelonLoader");
     try { harmonyInstance.Patch(typeof(Thread).GetProperty("CurrentCulture", BindingFlags.Public | BindingFlags.Instance).GetGetMethod(), new Harmony.HarmonyMethod(typeof(Core).GetMethod("GetCurrentCulturePrefix", BindingFlags.NonPublic | BindingFlags.Static))); } catch (Exception ex) { MelonLogger.Warning("Thread.CurrentCulture Exception: " + ex.ToString()); }
     try { harmonyInstance.Patch(typeof(Thread).GetProperty("CurrentUICulture", BindingFlags.Public | BindingFlags.Instance).GetGetMethod(), new Harmony.HarmonyMethod(typeof(Core).GetMethod("GetCurrentCulturePrefix", BindingFlags.NonPublic | BindingFlags.Static))); } catch (Exception ex) { MelonLogger.Warning("Thread.CurrentUICulture Exception: " + ex.ToString()); }
     try { ((AppDomainSetup)typeof(AppDomain).GetProperty("SetupInformationNoCopy", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(AppDomain.CurrentDomain, new object[0])).ApplicationBase = MelonUtils.GameDirectory; } catch (Exception ex) { MelonLogger.Warning("AppDomainSetup.ApplicationBase Exception: " + ex.ToString()); }
     Directory.SetCurrentDirectory(MelonUtils.GameDirectory);
     AppDomain.CurrentDomain.UnhandledException            += UnhandledExceptionHandler;
     AppDomain.CurrentDomain.AssemblyResolve               += AssemblyResolveHandler;
     AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += AssemblyResolveHandler;
     try { MelonPreferences.LegacyCheck(); } catch (Exception ex) { MelonLogger.Error("MelonPreferences.LegacyCheck Exception: " + ex.ToString()); MelonPreferences.WasError = true; }
     try { MelonPreferences.Load_Internal(); } catch (Exception ex) { MelonLogger.Error("MelonPreferences.Load_Internal Exception: " + ex.ToString()); MelonPreferences.WasError = true; }
     if (MelonPreferences.WasLegacyLoaded)
     {
         try { MelonPreferences.Save_Internal(); } catch (Exception ex) { MelonLogger.Error("MelonPreferences.Save_Internal Exception: " + ex.ToString()); MelonPreferences.WasError = true; }
     }
     MelonPreferences.SaveAfterEntryCreation = true;
     try { bHaptics_NativeLibrary.Load(); } catch (Exception ex) { MelonLogger.Error("bHaptics_NativeLibrary.Load Exception: " + ex.ToString()); bHaptics.WasError = true; }
 }
Esempio n. 13
0
        private static bool LoadInterface(string ModulePath)
        {
            Assembly assembly = Assembly.LoadFrom(ModulePath);

            if (assembly == null)
            {
                return(false);
            }

            Type type = assembly.GetType("MelonLoader.Support.Main");

            if (type == null)
            {
                MelonLogger.Error("Failed to Get Type MelonLoader.Support.Main!");
                return(false);
            }

            MethodInfo method = type.GetMethod("Initialize", BindingFlags.NonPublic | BindingFlags.Static);

            if (method == null)
            {
                MelonLogger.Error("Failed to Get Method Initialize!");
                return(false);
            }

            Interface = (ISupportModule_To)method.Invoke(null, new object[] { new SupportModule_From() });
            if (Interface == null)
            {
                MelonLogger.Error("Failed to Initialize Interface!");
                return(false);
            }

            MelonDebug.Msg($"Support Module Loaded: {ModulePath}");

            return(true);
        }
        private void TopologicalSortInto(IList <T> loadedMods)
        {
            int[] unloadedDependencies = new int[vertices.Length];
            SortedList <string, Vertex> loadableMods = new SortedList <string, Vertex>();
            int skippedMods = 0;

            // Find all sinks in the dependency graph, i.e. mods without any dependencies on other mods
            for (int i = 0; i < vertices.Length; ++i)
            {
                Vertex vertex          = vertices[i];
                int    dependencyCount = vertex.dependencies.Count;

                unloadedDependencies[i] = dependencyCount;
                if (dependencyCount == 0)
                {
                    loadableMods.Add(vertex.name, vertex);
                }
            }

            // Perform the (reverse) topological sorting
            while (loadableMods.Count > 0)
            {
                Vertex mod = loadableMods.Values[0];
                loadableMods.RemoveAt(0);

                if (!mod.skipLoading)
                {
                    loadedMods.Add(mod.mod);
                }
                else
                {
                    ++skippedMods;
                }

                foreach (Vertex dependent in mod.dependents)
                {
                    unloadedDependencies[dependent.index] -= 1;
                    dependent.skipLoading |= mod.skipLoading;

                    if (unloadedDependencies[dependent.index] == 0)
                    {
                        loadableMods.Add(dependent.name, dependent);
                    }
                }
            }

            // Check if all mods were either loaded or skipped. If this is not the case, there is a cycle in the dependency graph
            if (loadedMods.Count + skippedMods < vertices.Length)
            {
                StringBuilder errorMessage = new StringBuilder("Some mods could not be loaded due to a cyclic dependency:\n");
                for (int i = 0; i < vertices.Length; ++i)
                {
                    if (unloadedDependencies[i] > 0)
                    {
                        errorMessage.Append($"- '{vertices[i].name}'\n");
                    }
                }
                errorMessage.Length -= 1;                 // Remove trailing newline
                MelonLogger.Error(errorMessage.ToString());
            }
        }
Esempio n. 15
0
 private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e) => MelonLogger.Error((e.ExceptionObject as Exception).ToString());