Beispiel #1
0
 internal static void OnApplicationQuit()
 {
     if (IsInitialized && (Mods.Count() > 0))
     {
         foreach (MelonMod mod in Mods)
         {
             try { mod.OnApplicationQuit(); } catch (Exception ex) { MelonModLogger.LogModError(ex.ToString(), mod.InfoAttribute.Name); }
         }
     }
     ModPrefs.SaveConfig();
     NET_SDK.Harmony.Manager.UnpatchAll();
 }
 // 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) {
         MelonModLogger.LogError("Loading mod dependency failed: " + ex);
         return(false);
     }
 }
Beispiel #3
0
 public static float GetFloat(string section, string name)
 {
     if (prefs.TryGetValue(section, out Dictionary <string, PrefDesc> prefsInSection) && prefsInSection.TryGetValue(name, out PrefDesc pref))
     {
         if (float.TryParse(pref.Value, out float valueF))
         {
             return(valueF);
         }
     }
     MelonModLogger.LogError("Trying to get unregistered Pref " + section + ":" + name);
     return(0.0f);
 }
Beispiel #4
0
 public static void SetString(string section, string name, string value)
 {
     if (prefs.TryGetValue(section, out Dictionary <string, PrefDesc> prefsInSection) && prefsInSection.TryGetValue(name, out PrefDesc pref))
     {
         pref.Value = value;
         ModPrefsController.SetString(section, name, value);
     }
     else
     {
         MelonModLogger.LogError("Trying to save unknown pref " + section + ":" + name);
     }
 }
Beispiel #5
0
 internal static void OnGUI()
 {
     if (IsInitialized)
     {
         if (Mods.Count() > 0)
         {
             foreach (MelonMod mod in Mods)
             {
                 try { mod.OnGUI(); } catch (Exception ex) { MelonModLogger.LogModError(ex.ToString(), mod.InfoAttribute.Name); }
             }
         }
     }
 }
Beispiel #6
0
        private static void LoadAssembly(byte[] data, bool preload = false)
        {
            Assembly asm = Assembly.Load(data);

            if (!asm.Equals(null))
            {
                LoadModFromAssembly(asm, preload);
            }
            else
            {
                MelonModLogger.LogError("Unable to load " + asm);
            }
        }
Beispiel #7
0
 public static void SaveConfig()
 {
     foreach (KeyValuePair <string, Dictionary <string, PrefDesc> > prefsInSection in prefs)
     {
         foreach (KeyValuePair <string, PrefDesc> pref in prefsInSection.Value)
         {
             pref.Value.Value = pref.Value.ValueEdited;
             ModPrefsController.SetString(prefsInSection.Key, pref.Key, pref.Value.Value);
         }
     }
     Main.OnModSettingsApplied();
     MelonModLogger.Log("Config Saved!");
 }
Beispiel #8
0
 public static void OnGUI()
 {
     if (Mods.Count() > 0)
     {
         for (int i = 0; i < Mods.Count; i++)
         {
             MelonMod mod = Mods[i];
             if (mod != null)
             {
                 try { mod.OnGUI(); } catch (Exception ex) { MelonModLogger.LogDLLError(ex.ToString(), mod.InfoAttribute.Name); }
             }
         }
     }
 }
Beispiel #9
0
 internal static void OnModSettingsApplied()
 {
     if (Mods.Count() > 0)
     {
         for (int i = 0; i < Mods.Count; i++)
         {
             MelonMod mod = Mods[i];
             if (mod != null)
             {
                 try { mod.OnModSettingsApplied(); } catch (Exception ex) { MelonModLogger.LogModError(ex.ToString(), mod.InfoAttribute.Name); }
             }
         }
     }
 }
Beispiel #10
0
 internal static void OnLevelWasLoaded(int level)
 {
     if (Mods.Count() > 0)
     {
         for (int i = 0; i < Mods.Count; i++)
         {
             MelonMod mod = Mods[i];
             if (mod != null)
             {
                 try { mod.OnLevelWasLoaded(level); } catch (Exception ex) { MelonModLogger.LogDLLError(ex.ToString(), mod.InfoAttribute.Name); }
             }
         }
     }
 }
Beispiel #11
0
 internal static void OnLevelWasLoaded(int level)
 {
     if (IsInitialized)
     {
         if (Mods.Count() > 0)
         {
             foreach (MelonMod mod in Mods)
             {
                 try { mod.OnLevelWasLoaded(level); } catch (Exception ex) { MelonModLogger.LogModError(ex.ToString(), mod.InfoAttribute.Name); }
             }
         }
         was_level_loaded   = true;
         level_loaded_index = level;
     }
 }
Beispiel #12
0
 private static void OnApplicationQuit()
 {
     if (Mods.Count() > 0)
     {
         for (int i = 0; i < Mods.Count; i++)
         {
             MelonMod mod = Mods[i];
             if (mod != null)
             {
                 try { mod.OnApplicationQuit(); } catch (Exception ex) { MelonModLogger.LogModError(ex.ToString(), mod.InfoAttribute.Name); }
             }
         }
     }
     ModPrefs.SaveConfig();
     Harmony.HarmonyInstance.UnpatchAllInstances();
 }
Beispiel #13
0
 internal static void OnFixedUpdate()
 {
     if (IsInitialized)
     {
         if (Mods.Count() > 0)
         {
             foreach (MelonMod mod in Mods)
             {
                 try { mod.OnFixedUpdate(); } catch (Exception ex) { MelonModLogger.LogModError(ex.ToString(), mod.InfoAttribute.Name); }
             }
         }
         if (Imports.IsIl2CppGame() && !Imports.IsMUPOTMode())
         {
             MelonCoroutines.ProcessWaitForFixedUpdate();
         }
     }
 }
Beispiel #14
0
 public static void OnUpdate()
 {
     SceneHandler.CheckForSceneChange();
     if (Imports.IsIl2CppGame() && IsVRChat)
     {
         VRChat_CheckUiManager();
     }
     if (Mods.Count() > 0)
     {
         for (int i = 0; i < Mods.Count; i++)
         {
             MelonMod mod = Mods[i];
             if (mod != null)
             {
                 try { mod.OnUpdate(); } catch (Exception ex) { MelonModLogger.LogDLLError(ex.ToString(), mod.InfoAttribute.Name); }
             }
         }
     }
 }
Beispiel #15
0
 public static void OnApplicationQuit()
 {
     if (Mods.Count() > 0)
     {
         for (int i = 0; i < Mods.Count; i++)
         {
             MelonMod mod = Mods[i];
             if (mod != null)
             {
                 try { mod.OnApplicationQuit(); } catch (Exception ex) { MelonModLogger.LogModError(ex.ToString(), mod.InfoAttribute.Name); }
             }
         }
         ModPrefs.SaveConfig();
     }
     Harmony.HarmonyInstance.UnpatchAllInstances();
     Imports.UNLOAD_MELONLOADER();
     if (Imports.IsQuitFix())
     {
         Process.GetCurrentProcess().Kill();
     }
 }
Beispiel #16
0
 internal static void Initialize()
 {
     try
     {
         string filepath = Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "MelonLoader"), (Imports.IsIl2CppGame() ? "MelonLoader.Support.Il2Cpp.dll"
             : (File.Exists(Path.Combine(Imports.GetAssemblyDirectory(), "UnityEngine.CoreModule.dll")) ? "MelonLoader.Support.Mono.dll" : "MelonLoader.Support.Mono.Pre2017.dll")));
         if (File.Exists(filepath))
         {
             byte[] data = File.ReadAllBytes(filepath);
             if (data.Length > 0)
             {
                 assembly = Assembly.Load(data);
                 if (!assembly.Equals(null))
                 {
                     type = assembly.GetType("MelonLoader.Support.Main");
                     if (!type.Equals(null))
                     {
                         MethodInfo method = type.GetMethod("Initialize", BindingFlags.NonPublic | BindingFlags.Static);
                         if (!method.Equals(null))
                         {
                             supportModule = (ISupportModule)method.Invoke(null, new object[0]);
                         }
                     }
                 }
             }
         }
         else
         {
             MelonModLogger.LogError("Unable to load Support Module! Support Module is Missing!");
             MelonModLogger.Log("------------------------------");
         }
     }
     catch (Exception e)
     {
         MelonModLogger.LogError("Unable to load Support Module!\n" + e.ToString());
         MelonModLogger.Log("------------------------------");
     }
 }
Beispiel #17
0
 private static void RegisterPref(string section, string name, string defaultValue, string displayText, PrefType type, bool hideFromList)
 {
     if (prefs.TryGetValue(section, out Dictionary <string, PrefDesc> prefsInSection))
     {
         if (prefsInSection.TryGetValue(name, out PrefDesc pref))
         {
             MelonModLogger.LogError("Trying to registered Pref " + section + ":" + name + " more than one time");
         }
         else
         {
             string toStoreValue = defaultValue;
             if (ModPrefsController.HasKey(section, name))
             {
                 toStoreValue = ModPrefsController.GetString(section, name, defaultValue);
             }
             else
             {
                 ModPrefsController.SetString(section, name, defaultValue);
             }
             prefsInSection.Add(name, new PrefDesc(toStoreValue, type, hideFromList, (displayText ?? "") == "" ? name : displayText));
         }
     }
     else
     {
         Dictionary <string, PrefDesc> dic = new Dictionary <string, PrefDesc>();
         string toStoreValue = defaultValue;
         if (ModPrefsController.HasKey(section, name))
         {
             toStoreValue = ModPrefsController.GetString(section, name, defaultValue);
         }
         else
         {
             ModPrefsController.SetString(section, name, defaultValue);
         }
         dic.Add(name, new PrefDesc(toStoreValue, type, hideFromList, (displayText ?? "") == "" ? name : displayText));
         prefs.Add(section, dic);
     }
 }
        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
                MelonModLogger.LogError(errorMessage.ToString());
            }
        }
Beispiel #19
0
 public static void OnModSettingsApplied()
 {
     if (Plugins.Count > 0)
     {
         for (int i = 0; i < Plugins.Count; i++)
         {
             MelonPlugin plugin = Plugins[i];
             if (plugin != null)
             {
                 try { plugin.OnModSettingsApplied(); } catch (Exception ex) { MelonModLogger.LogDLLError(ex.ToString(), plugin.InfoAttribute.Name); }
             }
         }
     }
     if (Mods.Count() > 0)
     {
         for (int i = 0; i < Mods.Count; i++)
         {
             MelonMod mod = Mods[i];
             if (mod != null)
             {
                 try { mod.OnModSettingsApplied(); } catch (Exception ex) { MelonModLogger.LogDLLError(ex.ToString(), mod.InfoAttribute.Name); }
             }
         }
     }
 }
Beispiel #20
0
        private static void Initialize()
        {
            if (string.IsNullOrEmpty(AppDomain.CurrentDomain.BaseDirectory))
            {
                ((AppDomainSetup)typeof(AppDomain).GetProperty("SetupInformationNoCopy", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(AppDomain.CurrentDomain, new object[0])).ApplicationBase = Imports.GetGameDirectory();
            }
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
            AppDomain.CurrentDomain.UnhandledException += ExceptionHandler;

            CurrentGameAttribute = new MelonModGameAttribute(Imports.GetCompanyName(), Imports.GetProductName());
            UnityVersion         = GetUnityFileVersion();

            if (Imports.IsIl2CppGame())
            {
                IsVRChat    = CurrentGameAttribute.IsGame("VRChat", "VRChat");
                IsBoneworks = CurrentGameAttribute.IsGame("Stress Level Zero", "BONEWORKS");
            }

            if (!Imports.IsDebugMode()
#if !DEBUG
                && Imports.IsConsoleEnabled()
#endif
                )
            {
                Console.Enabled = true;
                Console.Create();
            }

            if (!Imports.IsIl2CppGame() || AssemblyGenerator.Main.Initialize())
            {
                HasGeneratedAssembly = true;
            }
            else
            {
                Imports.UNLOAD_MELONLOADER();
            }

            if (HasGeneratedAssembly)
            {
                LoadDLLs(true);
                if (Plugins.Count > 0)
                {
                    HashSet <MelonPlugin> failedPlugins = new HashSet <MelonPlugin>();
                    TempPlugins = Plugins.Where(plugin => (plugin.Compatibility < MelonBase.MelonCompatibility.INCOMPATIBLE)).ToList();
                    DependencyGraph <MelonPlugin> .TopologicalSort(TempPlugins, plugin => plugin.InfoAttribute.Name);

                    for (int i = 0; i < TempPlugins.Count; i++)
                    {
                        MelonPlugin plugin = TempPlugins[i];
                        if (plugin != null)
                        {
                            try { plugin.OnPreInitialization(); } catch (Exception ex) { MelonModLogger.LogDLLError(ex.ToString(), plugin.InfoAttribute.Name); failedPlugins.Add(plugin); }
                        }
                    }
                    TempPlugins.RemoveAll(plugin => failedPlugins.Contains(plugin));
                }
            }
        }
        private DependencyGraph(IList <T> mods, Func <T, string> modNameGetter)
        {
            int size = mods.Count;

            vertices = new Vertex[size];
            IDictionary <string, Vertex> nameLookup = new Dictionary <string, Vertex>(size);

            // Create a vertex in the dependency graph for each mod to load
            for (int i = 0; i < size; ++i)
            {
                Assembly modAssembly = mods[i].Assembly;
                string   modName     = modNameGetter(mods[i]);

                Vertex modVertex = new Vertex(i, mods[i], modName);
                vertices[i] = modVertex;
                nameLookup[modAssembly.GetName().Name] = modVertex;
            }

            // Add an edge for each dependency between mods
            IDictionary <string, IList <AssemblyName> > modsWithMissingDeps = new SortedDictionary <string, IList <AssemblyName> >();
            List <AssemblyName> missingDependencies  = new List <AssemblyName>();
            HashSet <string>    optionalDependencies = new HashSet <string>();

            foreach (Vertex modVertex in vertices)
            {
                Assembly modAssembly = modVertex.mod.Assembly;
                missingDependencies.Clear();
                optionalDependencies.Clear();

                MelonOptionalDependenciesAttribute optionals = (MelonOptionalDependenciesAttribute)Attribute.GetCustomAttribute(modAssembly, typeof(MelonOptionalDependenciesAttribute));
                if (optionals != null && optionals.AssemblyNames != null)
                {
                    optionalDependencies.UnionWith(optionals.AssemblyNames);
                }

                foreach (AssemblyName dependency in modAssembly.GetReferencedAssemblies())
                {
                    if (nameLookup.TryGetValue(dependency.Name, out Vertex dependencyVertex))
                    {
                        modVertex.dependencies.Add(dependencyVertex);
                        dependencyVertex.dependents.Add(modVertex);
                    }
                    else if (!TryLoad(dependency) && !optionalDependencies.Contains(dependency.Name))
                    {
                        missingDependencies.Add(dependency);
                    }
                }

                if (missingDependencies.Count > 0)
                {
                    // modVertex.skipLoading = true;
                    modsWithMissingDeps.Add(modNameGetter(modVertex.mod), missingDependencies.ToArray());
                }
            }

            if (modsWithMissingDeps.Count > 0)
            {
                // Some mods are missing dependencies. Don't load these mods and show an error message
                MelonModLogger.LogWarning(BuildMissingDependencyMessage(modsWithMissingDeps));
            }
        }
Beispiel #22
0
 private static void VRChat_CheckUiManager()
 {
     if (IsInitialized && ShouldCheckForUiManager)
     {
         if (VRCUiManager == null)
         {
             VRCUiManager = NET_SDK.SDK.GetClass("VRCUiManager");
         }
         if (VRCUiManager != null)
         {
             if (VRCUiManager_GetInstance == null)
             {
                 NET_SDK.Reflection.IL2CPP_Method[] methods = VRCUiManager.GetMethods();
                 foreach (NET_SDK.Reflection.IL2CPP_Method method in methods)
                 {
                     NET_SDK.Reflection.IL2CPP_Type returntype = method.GetReturnType();
                     if ((returntype != null) && !string.IsNullOrEmpty(returntype.Name) && returntype.Name.Equals("VRCUiManager"))
                     {
                         if (method.HasFlag(NET_SDK.Reflection.IL2CPP_BindingFlags.METHOD_STATIC))
                         {
                             VRCUiManager_GetInstance = method;
                             break;
                         }
                     }
                 }
             }
             if (VRCUiManager_GetInstance != null)
             {
                 NET_SDK.Reflection.IL2CPP_Object returnval = VRCUiManager_GetInstance.Invoke();
                 if (returnval != null)
                 {
                     ShouldCheckForUiManager = false;
                     if (Mods.Count() > 0)
                     {
                         foreach (MelonMod mod in Mods)
                         {
                             try { mod.VRChat_OnUiManagerInit(); } catch (Exception ex) { MelonModLogger.LogModError(ex.ToString(), mod.InfoAttribute.Name); }
                         }
                     }
                 }
             }
         }
     }
 }
Beispiel #23
0
 private static void ExceptionHandler(object sender, UnhandledExceptionEventArgs e) => MelonModLogger.LogError((e.ExceptionObject as Exception).ToString());
Beispiel #24
0
 private static void VRChat_CheckUiManager()
 {
     if (ShouldCheckForUiManager)
     {
         if (VRCUiManager == null)
         {
             VRCUiManager = Assembly_CSharp.GetType("VRCUiManager");
         }
         if (VRCUiManager != null)
         {
             if (VRCUiManager_Instance == null)
             {
                 VRCUiManager_Instance = VRCUiManager.GetProperty("field_Protected_Static_VRCUiManager_0");
             }
             if (VRCUiManager_Instance != null)
             {
                 object returnval = VRCUiManager_Instance.GetValue(null, new object[0]);
                 if (returnval != null)
                 {
                     ShouldCheckForUiManager = false;
                     if (Mods.Count() > 0)
                     {
                         for (int i = 0; i < Mods.Count; i++)
                         {
                             MelonMod mod = Mods[i];
                             if (mod != null)
                             {
                                 try { mod.VRChat_OnUiManagerInit(); } catch (Exception ex) { MelonModLogger.LogDLLError(ex.ToString(), mod.InfoAttribute.Name); }
                             }
                         }
                     }
                 }
             }
         }
     }
 }
Beispiel #25
0
        private static void LoadMods(bool preload = false)
        {
            string modDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.Combine("Mods", (preload ? "PRELOAD" : "")));

            if (!Directory.Exists(modDirectory))
            {
                Directory.CreateDirectory(modDirectory);
            }
            else
            {
                // DLL
                string[] files = Directory.GetFiles(modDirectory, "*.dll", SearchOption.TopDirectoryOnly);
                if (files.Length > 0)
                {
                    for (int i = 0; i < files.Count(); i++)
                    {
                        string file = files[i];
                        if (!string.IsNullOrEmpty(file))
                        {
                            try
                            {
                                byte[] data = File.ReadAllBytes(file);
                                if (data.Length > 0)
                                {
                                    LoadAssembly(data, preload);
                                }
                                else
                                {
                                    MelonModLogger.LogError("Unable to load " + file);
                                    MelonModLogger.Log("------------------------------");
                                }
                            }
                            catch (Exception e)
                            {
                                MelonModLogger.LogError("Unable to load " + file + ":\n" + e.ToString());
                                MelonModLogger.Log("------------------------------");
                            }
                        }
                    }
                }

                // ZIP

                /*
                 * string[] zippedFiles = Directory.GetFiles(modDirectory, "*.zip", SearchOption.TopDirectoryOnly);
                 * if (zippedFiles.Length > 0)
                 * {
                 *  for (int i = 0; i < zippedFiles.Count(); i++)
                 *  {
                 *      string file = zippedFiles[i];
                 *      if (!string.IsNullOrEmpty(file))
                 *      {
                 *          try
                 *          {
                 *              using (var fileStream = File.OpenRead(file))
                 *              {
                 *                  using (var zipInputStream = new ZipInputStream(fileStream))
                 *                  {
                 *                      ZipEntry entry;
                 *                      while ((entry = zipInputStream.GetNextEntry()) != null)
                 *                      {
                 *                          if ((Path.GetFileName(entry.Name).Length <= 0) || !Path.GetFileName(entry.Name).EndsWith(".dll"))
                 *                              continue;
                 *
                 *                          using (var unzippedFileStream = new MemoryStream())
                 *                          {
                 *                              int size = 0;
                 *                              byte[] buffer = new byte[4096];
                 *                              while (true)
                 *                              {
                 *                                  size = zipInputStream.Read(buffer, 0, buffer.Length);
                 *                                  if (size > 0)
                 *                                      unzippedFileStream.Write(buffer, 0, size);
                 *                                  else
                 *                                      break;
                 *                              }
                 *                              LoadAssembly(unzippedFileStream.ToArray(), preload);
                 *                          }
                 *                      }
                 *                  }
                 *              }
                 *          }
                 *          catch (Exception e)
                 *          {
                 *              MelonModLogger.LogError("Unable to load " + file + ":\n" + e.ToString());
                 *              MelonModLogger.Log("------------------------------");
                 *          }
                 *      }
                 *  }
                 * }
                 */
            }
        }
Beispiel #26
0
        private static void Initialize()
        {
            if (string.IsNullOrEmpty(AppDomain.CurrentDomain.BaseDirectory))
            {
                ((AppDomainSetup)typeof(AppDomain).GetProperty("SetupInformationNoCopy", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(AppDomain.CurrentDomain, new object[0])).ApplicationBase = Imports.GetGameDirectory();
            }
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
            AppDomain.CurrentDomain.UnhandledException += ExceptionHandler;

            CurrentGameAttribute = new MelonModGameAttribute(Imports.GetCompanyName(), Imports.GetProductName());
            UnityVersion         = GetUnityFileVersion();

            if (Imports.IsIl2CppGame())
            {
                IsVRChat    = CurrentGameAttribute.IsGame("VRChat", "VRChat");
                IsBoneworks = CurrentGameAttribute.IsGame("Stress Level Zero", "BONEWORKS");
            }

            if (!Imports.IsDebugMode())
            {
                Console.Enabled = true;
                Console.Create();
            }

            if (Imports.IsIl2CppGame() && !AssemblyGenerator.Main.Initialize())
            {
                Imports.UNLOAD_MELONLOADER(true);
            }
            else
            {
                LoadMods(true);
                if (Mods.Count > 0)
                {
                    for (int i = 0; i < Mods.Count; i++)
                    {
                        MelonMod mod = Mods[i];
                        if (mod != null)
                        {
                            try { mod.OnPreInitialization(); } catch (Exception ex) { MelonModLogger.LogModError(ex.ToString(), mod.InfoAttribute.Name); }
                        }
                    }
                }
            }
        }
Beispiel #27
0
        private static void LoadDLLs(bool plugins = false)
        {
            string searchdir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, (plugins ? "Plugins" : "Mods"));

            if (!Directory.Exists(searchdir))
            {
                Directory.CreateDirectory(searchdir);
            }
            else
            {
                // DLL
                string[] files = Directory.GetFiles(searchdir, "*.dll");
                if (files.Length > 0)
                {
                    for (int i = 0; i < files.Count(); i++)
                    {
                        string file = files[i];
                        if (!string.IsNullOrEmpty(file))
                        {
                            if (plugins)
                            {
                                if ((Imports.IsDevPluginsOnly() && !file.EndsWith("-dev.dll")) || (!Imports.IsDevPluginsOnly() && file.EndsWith("-dev.dll")))
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                if ((Imports.IsDevModsOnly() && !file.EndsWith("-dev.dll")) || (!Imports.IsDevModsOnly() && file.EndsWith("-dev.dll")))
                                {
                                    continue;
                                }
                            }
                            try
                            {
                                LoadAssembly(File.ReadAllBytes(file), plugins, file);
                            }
                            catch (Exception e)
                            {
                                MelonModLogger.LogError("Unable to load " + file + ":\n" + e.ToString());
                                MelonModLogger.Log("------------------------------");
                            }
                        }
                    }
                }

                // ZIP
                string[] zippedFiles = Directory.GetFiles(searchdir, "*.zip");
                if (zippedFiles.Length > 0)
                {
                    for (int i = 0; i < zippedFiles.Count(); i++)
                    {
                        string file = zippedFiles[i];
                        if (!string.IsNullOrEmpty(file))
                        {
                            try
                            {
                                using (var fileStream = File.OpenRead(file))
                                {
                                    using (var zipInputStream = new ZipInputStream(fileStream))
                                    {
                                        ZipEntry entry;
                                        while ((entry = zipInputStream.GetNextEntry()) != null)
                                        {
                                            string filename = Path.GetFileName(entry.Name);
                                            if (string.IsNullOrEmpty(filename) || !filename.EndsWith(".dll"))
                                            {
                                                continue;
                                            }

                                            if (plugins)
                                            {
                                                if ((Imports.IsDevPluginsOnly() && !filename.EndsWith("-dev.dll")) || (!Imports.IsDevPluginsOnly() && filename.EndsWith("-dev.dll")))
                                                {
                                                    continue;
                                                }
                                            }
                                            else
                                            {
                                                if ((Imports.IsDevModsOnly() && !filename.EndsWith("-dev.dll")) || (!Imports.IsDevModsOnly() && filename.EndsWith("-dev.dll")))
                                                {
                                                    continue;
                                                }
                                            }

                                            using (var unzippedFileStream = new MemoryStream())
                                            {
                                                int    size   = 0;
                                                byte[] buffer = new byte[4096];
                                                while (true)
                                                {
                                                    size = zipInputStream.Read(buffer, 0, buffer.Length);
                                                    if (size > 0)
                                                    {
                                                        unzippedFileStream.Write(buffer, 0, size);
                                                    }
                                                    else
                                                    {
                                                        break;
                                                    }
                                                }
                                                LoadAssembly(unzippedFileStream.ToArray(), plugins, (file + "/" + filename));
                                            }
                                        }
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                MelonModLogger.LogError("Unable to load " + file + ":\n" + e.ToString());
                                MelonModLogger.Log("------------------------------");
                            }
                        }
                    }
                }
            }
        }
Beispiel #28
0
        private static void LoadModFromAssembly(Assembly assembly, bool isPlugin = false)
        {
            MelonModInfoAttribute modInfoAttribute = assembly.GetCustomAttributes(false).FirstOrDefault(x => (x.GetType() == typeof(MelonModInfoAttribute))) as MelonModInfoAttribute;

            if ((modInfoAttribute != null) && (modInfoAttribute.ModType != null) && modInfoAttribute.ModType.IsSubclassOf(typeof(MelonMod)))
            {
                bool should_continue = false;
                bool isUniversal     = false;
                MelonModGameAttribute[] modGameAttributes = assembly.GetCustomAttributes(typeof(MelonModGameAttribute), true) as MelonModGameAttribute[];
                int modGameAttributes_Count = modGameAttributes.Length;
                if (modGameAttributes_Count > 0)
                {
                    for (int i = 0; i < modGameAttributes_Count; i++)
                    {
                        MelonModGameAttribute modGameAttribute = modGameAttributes[i];
                        if (CurrentGameAttribute.IsCompatible(modGameAttribute))
                        {
                            isUniversal     = CurrentGameAttribute.IsCompatibleBecauseUniversal(modGameAttribute);
                            should_continue = true;
                            break;
                        }
                    }
                }
                else
                {
                    isUniversal     = true;
                    should_continue = true;
                }
                if (should_continue)
                {
                    try
                    {
                        MelonMod modInstance = Activator.CreateInstance(modInfoAttribute.ModType) as MelonMod;
                        if (modInstance != null)
                        {
                            modInstance.IsUniversal   = isUniversal;
                            modInstance.IsPlugin      = isPlugin;
                            modInstance.InfoAttribute = modInfoAttribute;
                            if (modGameAttributes_Count > 0)
                            {
                                modInstance.GameAttributes = modGameAttributes;
                            }
                            else
                            {
                                modInstance.GameAttributes = null;
                            }
                            modInstance.ModAssembly = assembly;
                            Harmony.HarmonyInstance.Create(assembly.FullName).PatchAll(assembly);
                            Mods.Add(modInstance);
                        }
                        else
                        {
                            MelonModLogger.LogError("Unable to load Mod in " + assembly.GetName() + "! Failed to Create Instance!");
                        }
                    }
                    catch (Exception e) { MelonModLogger.LogError("Unable to load Mod in " + assembly.GetName() + "! " + e.ToString()); }
                }
                else
                {
                    MelonModLogger.LogModStatus(3);
                }
            }
        }
Beispiel #29
0
        private static void OnApplicationStart()
        {
            if (!HasGeneratedAssembly)
            {
                return;
            }

            if (Imports.IsIl2CppGame())
            {
                if (IsVRChat)
                {
                    Assembly_CSharp = Assembly.Load("Assembly-CSharp");
                }
                UnhollowerSupport.Initialize();
            }
            SupportModule.Initialize();

            MelonModLogger.Log("------------------------------");
            MelonModLogger.Log("Unity " + UnityVersion);
            MelonModLogger.Log("------------------------------");
            MelonModLogger.Log("Name: " + CurrentGameAttribute.GameName);
            MelonModLogger.Log("Developer: " + CurrentGameAttribute.Developer);
            MelonModLogger.Log("Type: " + (Imports.IsIl2CppGame() ? "Il2Cpp" : (Imports.IsOldMono() ? "Mono" : "MonoBleedingEdge")));
            MelonModLogger.Log("------------------------------");
            MelonModLogger.Log("Using v" + BuildInfo.Version + " Open-Beta");
            MelonModLogger.Log("------------------------------");

            LoadDLLs();
            if (Plugins.Count > 0)
            {
                for (int i = 0; i < Plugins.Count; i++)
                {
                    MelonPlugin plugin = Plugins[i];
                    if (plugin != null)
                    {
                        MelonModLogger.Log(plugin.InfoAttribute.Name
                                           + (!string.IsNullOrEmpty(plugin.InfoAttribute.Version)
                            ? (" v" + plugin.InfoAttribute.Version) : "")
                                           + (!string.IsNullOrEmpty(plugin.InfoAttribute.Author)
                            ? (" by " + plugin.InfoAttribute.Author) : "")
                                           + (!string.IsNullOrEmpty(plugin.InfoAttribute.DownloadLink)
                            ? (" (" + plugin.InfoAttribute.DownloadLink + ")")
                            : "")
                                           );
                        MelonModLogger.LogDLLStatus(plugin.Compatibility);
                        MelonModLogger.Log("------------------------------");
                    }
                }
                Plugins = TempPlugins;
            }
            if (Plugins.Count <= 0)
            {
                MelonModLogger.Log("No Plugins Loaded!");
                MelonModLogger.Log("------------------------------");
            }

            if (Mods.Count > 0)
            {
                for (int i = 0; i < Mods.Count; i++)
                {
                    MelonMod mod = Mods[i];
                    if (mod != null)
                    {
                        MelonModLogger.Log(mod.InfoAttribute.Name
                                           + (!string.IsNullOrEmpty(mod.InfoAttribute.Version)
                            ? (" v" + mod.InfoAttribute.Version) : "")
                                           + (!string.IsNullOrEmpty(mod.InfoAttribute.Author)
                            ? (" by " + mod.InfoAttribute.Author) : "")
                                           + (!string.IsNullOrEmpty(mod.InfoAttribute.DownloadLink)
                            ? (" (" + mod.InfoAttribute.DownloadLink + ")")
                            : "")
                                           );
                        MelonModLogger.LogDLLStatus(mod.Compatibility);
                        MelonModLogger.Log("------------------------------");
                    }
                }
                Mods.RemoveAll((MelonMod mod) => (mod.Compatibility >= MelonBase.MelonCompatibility.INCOMPATIBLE));
                DependencyGraph <MelonMod> .TopologicalSort(Mods, mod => mod.InfoAttribute.Name);
            }
            if (Mods.Count <= 0)
            {
                MelonModLogger.Log("No Mods Loaded!");
                MelonModLogger.Log("------------------------------");
            }

            if ((Plugins.Count > 0) || (Mods.Count > 0))
            {
                AddUnityDebugLog();
            }

            if (Plugins.Count > 0)
            {
                HashSet <MelonPlugin> failedPlugins = new HashSet <MelonPlugin>();
                for (int i = 0; i < Plugins.Count; i++)
                {
                    MelonPlugin plugin = Plugins[i];
                    if (plugin != null)
                    {
                        try { InitializeModOrPlugin(plugin); } catch (Exception ex) { MelonModLogger.LogDLLError(ex.ToString(), plugin.InfoAttribute.Name); failedPlugins.Add(plugin); }
                    }
                }
                Plugins.RemoveAll(plugin => failedPlugins.Contains(plugin));
            }

            if (Mods.Count > 0)
            {
                HashSet <MelonMod> failedMods = new HashSet <MelonMod>();
                for (int i = 0; i < Mods.Count; i++)
                {
                    MelonMod mod = Mods[i];
                    if (mod != null)
                    {
                        try { InitializeModOrPlugin(mod); } catch (Exception ex) { MelonModLogger.LogDLLError(ex.ToString(), mod.InfoAttribute.Name); failedMods.Add(mod); }
                    }
                }
                Mods.RemoveAll(mod => failedMods.Contains(mod));
            }

            if ((Plugins.Count <= 0) && (Mods.Count <= 0))
            {
                SupportModule.Destroy();
            }
        }
Beispiel #30
0
        private static void OnApplicationStart()
        {
            if (!HasGeneratedAssembly)
            {
                return;
            }

            if (Imports.IsIl2CppGame())
            {
                if (IsVRChat)
                {
                    Assembly_CSharp = Assembly.Load("Assembly-CSharp");
                }
                UnhollowerSupport.Initialize();
            }
            SupportModule.Initialize();

            MelonModLogger.Log("------------------------------");
            MelonModLogger.Log("Unity " + UnityVersion);
            MelonModLogger.Log("------------------------------");
            MelonModLogger.Log("Name: " + CurrentGameAttribute.GameName);
            MelonModLogger.Log("Developer: " + CurrentGameAttribute.Developer);
            MelonModLogger.Log("Type: " + (Imports.IsIl2CppGame() ? "Il2Cpp" : (Imports.IsOldMono() ? "Mono" : "MonoBleedingEdge")));
            MelonModLogger.Log("------------------------------");
            MelonModLogger.Log("Using v" + BuildInfo.Version + " Open-Beta");
            MelonModLogger.Log("------------------------------");

            LoadMods();
            if (Mods.Count > 0)
            {
                AddUnityDebugLog();

                for (int i = 0; i < Mods.Count; i++)
                {
                    MelonMod mod = Mods[i];
                    if (mod != null)
                    {
                        MelonModLogger.Log(mod.InfoAttribute.Name
                                           + (!string.IsNullOrEmpty(mod.InfoAttribute.Version)
                            ? (" v" + mod.InfoAttribute.Version) : "")
                                           + (!string.IsNullOrEmpty(mod.InfoAttribute.Author)
                            ? (" by " + mod.InfoAttribute.Author) : "")
                                           + (!string.IsNullOrEmpty(mod.InfoAttribute.DownloadLink)
                            ? (" (" + mod.InfoAttribute.DownloadLink + ")")
                            : "")
                                           );
                        if (Imports.IsDebugMode())
                        {
                            MelonModLogger.Log("Plugin: " + mod.IsPlugin.ToString());
                        }
                        MelonModLogger.LogModStatus((mod.GameAttributes.Any()) ? (mod.IsUniversal ? 0 : 1) : 2);
                        MelonModLogger.Log("------------------------------");
                    }
                }

                for (int i = 0; i < Mods.Count; i++)
                {
                    MelonMod mod = Mods[i];
                    if (mod != null)
                    {
                        try { mod.OnApplicationStart(); } catch (Exception ex) { MelonModLogger.LogModError(ex.ToString(), mod.InfoAttribute.Name); }
                    }
                }
            }
            else
            {
                MelonModLogger.Log("No Mods Loaded!");
                MelonModLogger.Log("------------------------------");
            }
        }