Пример #1
0
 internal static void Initialize()
 {
     try
     {
         string basedir  = Path.Combine(Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CumLoader"), "Dependencies"), "SupportModules");
         string filepath = null;
         if (Imports.IsIl2CppGame())
         {
             filepath = Path.Combine(basedir, "CumLoader.Support.Il2Cpp.dll");
         }
         else
         {
             if (File.Exists(Path.Combine(Imports.GetAssemblyDirectory(), "UnityEngine.CoreModule.dll")))
             {
                 filepath = Path.Combine(basedir, "CumLoader.Support.Mono.dll");
             }
             else
             {
                 if (IsOldUnity())
                 {
                     filepath = Path.Combine(basedir, "CumLoader.Support.Mono.Pre2017.2.dll");
                 }
                 else
                 {
                     filepath = Path.Combine(basedir, "CumLoader.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("CumLoader.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
         {
             CumLogger.LogError("Unable to load Support Module! Support Module is Missing!");
             CumLogger.Log("------------------------------");
         }
     }
     catch (Exception e)
     {
         CumLogger.LogError("Unable to load Support Module!\n" + e.ToString());
         CumLogger.Log("------------------------------");
     }
 }
Пример #2
0
 public static bool GetBool(string section, string name)
 {
     if (prefs.TryGetValue(section, out Dictionary <string, CumPreference> prefsInSection) && prefsInSection.TryGetValue(name, out CumPreference pref))
     {
         return(pref.Value.Equals("true") || pref.Value.Equals("1"));
     }
     CumLogger.LogError("Trying to get unregistered Pref " + section + ":" + name);
     return(false);
 }
Пример #3
0
 public static string GetString(string section, string name)
 {
     if (prefs.TryGetValue(section, out Dictionary <string, CumPreference> prefsInSection) && prefsInSection.TryGetValue(name, out CumPreference pref))
     {
         return(pref.Value);
     }
     CumLogger.LogError("Trying to get unregistered Pref " + section + ":" + name);
     return("");
 }
Пример #4
0
 private static void Create()
 {
     Enabled = true;
     Allocate();
     Console.SetOut(new StreamWriter(new FileStream(new SafeFileHandle(CumLogger.Native_GetConsoleOutputHandle(), false), FileAccess.Write))
     {
         AutoFlush = true
     });
     Console.SetIn(new StreamReader(Console.OpenStandardInput()));
     SetTitle(BuildInfo.Name + " v" + BuildInfo.Version + " Open-Beta");
 }
Пример #5
0
 // 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) {
         CumLogger.LogError("Loading mod dependency failed: " + ex);
         return(false);
     }
 }
Пример #6
0
 public static float GetFloat(string section, string name)
 {
     if (prefs.TryGetValue(section, out Dictionary <string, CumPreference> prefsInSection) && prefsInSection.TryGetValue(name, out CumPreference pref))
     {
         if (float.TryParse(pref.Value, out float valueF))
         {
             return(valueF);
         }
     }
     CumLogger.LogError("Trying to get unregistered Pref " + section + ":" + name);
     return(0.0f);
 }
Пример #7
0
 public static void SetString(string section, string name, string value)
 {
     if (prefs.TryGetValue(section, out Dictionary <string, CumPreference> prefsInSection) && prefsInSection.TryGetValue(name, out CumPreference pref))
     {
         pref.Value = pref.ValueEdited = value;
         ConfigFile.SetString(section, name, value);
     }
     else
     {
         CumLogger.LogError("Trying to save unknown pref " + section + ":" + name);
     }
 }
Пример #8
0
 public static void SaveConfig()
 {
     foreach (KeyValuePair <string, Dictionary <string, CumPreference> > prefsInSection in prefs)
     {
         foreach (KeyValuePair <string, CumPreference> pref in prefsInSection.Value)
         {
             pref.Value.Value = pref.Value.ValueEdited;
             ConfigFile.SetString(prefsInSection.Key, pref.Key, pref.Value.Value);
         }
     }
     CumHandler.OnModSettingsApplied();
     CumLogger.Log("Config Saved!");
 }
Пример #9
0
        private static bool Initialize()
        {
            string GeneratorProcessPath = Path.Combine(Path.Combine(Path.Combine(Path.Combine(Imports.GetGameDirectory(), "CumLoader"), "Dependencies"), "AssemblyGenerator"), "CumLoader.AssemblyGenerator.exe");

            if (!File.Exists(GeneratorProcessPath))
            {
                CumLogger.LogError("CumLoader.AssemblyGenerator.exe does not Exist!");
                return(false);
            }
            var generatorProcessInfo = new ProcessStartInfo(GeneratorProcessPath);

            generatorProcessInfo.Arguments              = $"\"{CumLoaderBase.UnityVersion}\" {"\"" + Regex.Replace(Imports.GetGameDirectory(), @"(\\+)$", @"$1$1") + "\""} {"\"" + Regex.Replace(Imports.GetGameDataDirectory(), @"(\\+)$", @"$1$1") + "\""} {(Force_Regenerate() ? "true" : "false")} {(string.IsNullOrEmpty(Force_Version_Unhollower()) ? "" : Force_Version_Unhollower())}";
            generatorProcessInfo.UseShellExecute        = false;
            generatorProcessInfo.RedirectStandardOutput = true;
            generatorProcessInfo.CreateNoWindow         = true;
            Process process = null;

            try { process = Process.Start(generatorProcessInfo); } catch (Exception e) { CumLogger.LogError(e.ToString()); CumLogger.LogError("Unable to Start Assembly Generator!"); return(false); }
            var stdout = process.StandardOutput;

            while (!stdout.EndOfStream)
            {
                CumLogger.Log(stdout.ReadLine());
            }
            while (!process.HasExited)
            {
                Thread.Sleep(100);
            }
            if (process.ExitCode != 0)
            {
                CumLogger.Native_ThrowInternalError($"Assembly Generator exited with code {process.ExitCode}");
                return(false);
            }
            if (Imports.IsDebugMode())
            {
                CumLogger.Log($"Assembly Generator ran Successfully!");
            }
            return(true);
        }
Пример #10
0
 private static void Register(string section, string name, string defaultValue, string displayText, CumPreferenceType type, bool hideFromList)
 {
     if (prefs.TryGetValue(section, out Dictionary <string, CumPreference> prefsInSection))
     {
         if (prefsInSection.TryGetValue(name, out CumPreference pref))
         {
             CumLogger.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 CumPreference(toStoreValue, type, hideFromList, (displayText ?? "") == "" ? name : displayText));
         }
     }
     else
     {
         Dictionary <string, CumPreference> dic = new Dictionary <string, CumPreference>();
         string toStoreValue = defaultValue;
         if (ConfigFile.HasKey(section, name))
         {
             toStoreValue = ConfigFile.GetString(section, name, defaultValue);
         }
         else
         {
             ConfigFile.SetString(section, name, defaultValue);
         }
         dic.Add(name, new CumPreference(toStoreValue, type, hideFromList, (displayText ?? "") == "" ? name : displayText));
         prefs.Add(section, dic);
     }
 }
Пример #11
0
        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();

                CumOptionalDependenciesAttribute optionals = (CumOptionalDependenciesAttribute)Attribute.GetCustomAttribute(modAssembly, typeof(CumOptionalDependenciesAttribute));
                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
                CumLogger.LogWarning(BuildMissingDependencyMessage(modsWithMissingDeps));
            }
        }
Пример #12
0
        private void TopologicalSortInto(IList <T> loadedCumMods)
        {
            int[] unloadedDependencies = new int[vertices.Length];
            SortedList <string, Vertex> loadableCumMods = new SortedList <string, Vertex>();
            int skippedCumMods = 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)
                {
                    loadableCumMods.Add(vertex.name, vertex);
                }
            }

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

                if (!mod.skipLoading)
                {
                    loadedCumMods.Add(mod.mod);
                }
                else
                {
                    ++skippedCumMods;
                }

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

                    if (unloadedDependencies[dependent.index] == 0)
                    {
                        loadableCumMods.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 (loadedCumMods.Count + skippedCumMods < 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
                CumLogger.LogError(errorMessage.ToString());
            }
        }