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("------------------------------"); } }
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); }
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(""); }
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"); }
// 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); } }
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); }
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); } }
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!"); }
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); }
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); } }
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)); } }
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()); } }