internal static void Initialize()
 {
     try
     {
         string basedir  = Path.Combine(Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "MelonLoader"), "Dependencies"), "SupportModules");
         string filepath = null;
         if (Imports.IsIl2CppGame())
         {
             filepath = Path.Combine(basedir, "MelonLoader.Support.Il2Cpp.dll");
         }
         else
         {
             if (File.Exists(Path.Combine(Imports.GetAssemblyDirectory(), "UnityEngine.CoreModule.dll")))
             {
                 filepath = Path.Combine(basedir, "MelonLoader.Support.Mono.dll");
             }
             else
             {
                 if (IsOldUnity())
                 {
                     filepath = Path.Combine(basedir, "MelonLoader.Support.Mono.Pre2017.2.dll");
                 }
                 else
                 {
                     filepath = Path.Combine(basedir, "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
         {
             MelonLogger.LogError("Unable to load Support Module! Support Module is Missing!");
             MelonLogger.Log("------------------------------");
         }
     }
     catch (Exception e)
     {
         MelonLogger.LogError("Unable to load Support Module!\n" + e.ToString());
         MelonLogger.Log("------------------------------");
     }
 }
Example #2
0
 public static bool GetBool(string section, string name)
 {
     if (prefs.TryGetValue(section, out Dictionary <string, MelonPreference> prefsInSection) && prefsInSection.TryGetValue(name, out MelonPreference pref))
     {
         return(pref.Value.Equals("true") || pref.Value.Equals("1"));
     }
     MelonLogger.LogError("Trying to get unregistered Pref " + section + ":" + name);
     return(false);
 }
Example #3
0
 public static string GetString(string section, string name)
 {
     if (prefs.TryGetValue(section, out Dictionary <string, MelonPreference> prefsInSection) && prefsInSection.TryGetValue(name, out MelonPreference pref))
     {
         return(pref.Value);
     }
     MelonLogger.LogError("Trying to get unregistered Pref " + section + ":" + name);
     return("");
 }
 // 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.LogError("Loading mod dependency failed: " + ex);
         return(false);
     }
 }
Example #5
0
 public static float GetFloat(string section, string name)
 {
     if (prefs.TryGetValue(section, out Dictionary <string, MelonPreference> prefsInSection) && prefsInSection.TryGetValue(name, out MelonPreference pref))
     {
         if (float.TryParse(pref.Value, out float valueF))
         {
             return(valueF);
         }
     }
     MelonLogger.LogError("Trying to get unregistered Pref " + section + ":" + name);
     return(0.0f);
 }
Example #6
0
 public static void SetString(string section, string name, string value)
 {
     if (prefs.TryGetValue(section, out Dictionary <string, MelonPreference> prefsInSection) && prefsInSection.TryGetValue(name, out MelonPreference pref))
     {
         pref.Value = pref.ValueEdited = value;
         ConfigFile.SetString(section, name, value);
     }
     else
     {
         MelonLogger.LogError("Trying to save unknown pref " + section + ":" + name);
     }
 }
Example #7
0
        private static bool Initialize()
        {
            string GeneratorProcessPath = Path.Combine(Path.Combine(Path.Combine(Path.Combine(Imports.GetGameDirectory(), "MelonLoader"), "Dependencies"), "AssemblyGenerator"), "MelonLoader.AssemblyGenerator.exe");

            if (File.Exists(GeneratorProcessPath))
            {
                var generatorProcessInfo = new ProcessStartInfo(GeneratorProcessPath);
                generatorProcessInfo.Arguments              = $"\"{MelonLoaderBase.UnityVersion}\" \"{Imports.GetGameDirectory()}\" \"{Imports.GetGameDataDirectory()}\" {(Force_Regenerate() ? "true" : "false")} {(string.IsNullOrEmpty(Force_Version_Unhollower()) ? "" : Force_Version_Unhollower())}";
                generatorProcessInfo.UseShellExecute        = false;
                generatorProcessInfo.RedirectStandardOutput = true;
                generatorProcessInfo.CreateNoWindow         = true;
                var process = Process.Start(generatorProcessInfo);
                if (process == null)
                {
                    MelonLogger.LogError("Unable to Start Assembly Generator!");
                }
                else
                {
                    var stdout = process.StandardOutput;
                    while (!stdout.EndOfStream)
                    {
                        var line = stdout.ReadLine();
                        MelonLogger.Log(line);
                    }
                    while (!process.HasExited)
                    {
                        Thread.Sleep(100);
                    }
                    if (process.ExitCode == 0)
                    {
                        if (Imports.IsDebugMode())
                        {
                            MelonLogger.Log($"Assembly Generator ran Successfully!");
                        }
                        return(true);
                    }
                    MelonLogger.Native_ThrowInternalError($"Assembly Generator exited with code {process.ExitCode}");
                }
            }
            else
            {
                MelonLogger.LogError("MelonLoader.AssemblyGenerator.exe does not Exist!");
            }
            return(false);
        }
Example #8
0
 private static void Register(string section, string name, string defaultValue, string displayText, MelonPreferenceType type, bool hideFromList)
 {
     if (prefs.TryGetValue(section, out Dictionary <string, MelonPreference> prefsInSection))
     {
         if (prefsInSection.TryGetValue(name, out MelonPreference pref))
         {
             MelonLogger.LogError("Trying to registered Pref " + section + ":" + name + " more than one time");
         }
         else
         {
             string toStoreValue = defaultValue;
             if (ConfigFile.HasKey(section, name))
             {
                 toStoreValue = ConfigFile.GetString(section, name, defaultValue);
             }
             else
             {
                 ConfigFile.SetString(section, name, defaultValue);
             }
             prefsInSection.Add(name, new MelonPreference(toStoreValue, type, hideFromList, (displayText ?? "") == "" ? name : displayText));
         }
     }
     else
     {
         Dictionary <string, MelonPreference> dic = new Dictionary <string, MelonPreference>();
         string toStoreValue = defaultValue;
         if (ConfigFile.HasKey(section, name))
         {
             toStoreValue = ConfigFile.GetString(section, name, defaultValue);
         }
         else
         {
             ConfigFile.SetString(section, name, defaultValue);
         }
         dic.Add(name, new MelonPreference(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
                MelonLogger.LogError(errorMessage.ToString());
            }
        }
Example #10
0
        public override void OnApplicationStart()
        {
            Instance = this;
            base.OnApplicationStart();
            ClassInjector.RegisterTypeInIl2Cpp <Grenade>();
            ClassInjector.RegisterTypeInIl2Cpp <PinScript>();
            ClassInjector.RegisterTypeInIl2Cpp <HandleScript>();

            var folder = new DirectoryInfo(Path.Combine(Path.GetDirectoryName(Application.dataPath), "UserData", "Grenades"));

            if (!folder.Exists)
            {
                folder.Create();
            }
            else
            {
                foreach (var file in folder.EnumerateFiles("*.grenade"))
                {
                    try
                    {
                        var bundle = AssetBundle.LoadFromFile(file.FullName);
                        bundle.hideFlags = HideFlags.DontUnloadUnusedAsset;
                        TextAsset text = bundle.LoadAsset <TextAsset>("Grenades.xml");
                        var       xml  = XDocument.Parse(text.text);

                        foreach (var grenadeXml in xml.Root.Elements("Grenade"))
                        {
                            var prefab = bundle.LoadAsset <GameObject>((string)grenadeXml.Attribute("prefab"));
                            prefab.hideFlags = HideFlags.DontUnloadUnusedAsset;
                            Shaders.ReplaceDummyShaders(prefab);
                            var guid = Guid.NewGuid();
                            prefab.name            = guidPrefix + guid.ToString();
                            this.definitions[guid] = grenadeXml;
                            var g = prefab.AddComponent <Grenade>();
                            SpawnMenu.AddItem(prefab,
                                              (string)grenadeXml.Attribute("name") ?? "[Grenade]",
                                              (int?)grenadeXml.Attribute("pool") ?? 4,
                                              (CategoryFilters)Enum.Parse(typeof(CategoryFilters), (string)grenadeXml.Attribute("category") ?? "GADGETS", true));
                        }
                    }
                    catch (Exception e)
                    {
                        Log.LogError($"Failed when loading grenade bundle: {file.Name}\n{e.Message}\n{e.StackTrace}");
                    }
                }
            }

            CustomMapIntegration.Init();
            if (Environment.GetCommandLineArgs().Contains("--grenades.debug"))
            {
                void ExportXml()
                {
                    foreach (var def in Instance.definitions.Values)
                    {
                        var file = Path.Combine(folder.FullName, $"exported_{(string)def.Attribute("name") ?? "noname"}.xml");
                        def.Save(file);
                    }
                }

                var i = Interfaces.AddNewInterface("Grenades Debug", Color.green);
                i.CreateFunctionElement("Output all xml", Color.green, null, null, ExportXml);
            }
        }