internal static void Initialize() { if (Initialized) { return; } Initialized = true; try { CoreLogger = new GadgetLogger("GadgetCore", "Core"); CoreLogger.Log("GadgetCore v" + GadgetCoreAPI.FULL_VERSION + " Initializing!"); Debug.Log("GadgetCore v" + GadgetCoreAPI.FULL_VERSION); } catch (Exception e) { Debug.Log(e); GadgetCoreAPI.Quit(); return; } try { if (File.Exists(Application.persistentDataPath + "/PlayerPrefs.txt") && VerifySaveFile()) { if (GadgetCoreConfig.MaxBackups > 0) { File.Copy(Application.persistentDataPath + "/PlayerPrefs.txt", Path.Combine(GadgetPaths.SaveBackupsPath, "Save Backup - " + DateTime.Now.ToString("yyyy-dd-M_HH-mm-ss") + ".txt")); FileInfo[] backups = new DirectoryInfo(GadgetPaths.SaveBackupsPath).GetFiles().OrderByDescending(x => x.LastWriteTime.Year <= 1601 ? x.CreationTime : x.LastWriteTime).ToArray(); if (backups.Length > GadgetCoreConfig.MaxBackups) { for (int i = GadgetCoreConfig.MaxBackups; i < backups.Length; i++) { backups[i].Delete(); } } } } else { GadgetCoreAPI.Quit(); return; } HarmonyInstance = new Harmony("GadgetCore.core"); Type[] types; try { types = Assembly.GetExecutingAssembly().GetTypes(); } catch (ReflectionTypeLoadException e) { types = e.Types.Where(t => t != null).ToArray(); } types.Do(delegate(Type type) { object[] attributes = type.GetCustomAttributes(true); if (!attributes.Any(x => x.GetType() == typeof(HarmonyGadgetAttribute))) { HarmonyInstance.CreateClassProcessor(type).Patch(); } }); new Thread(new ThreadStart(() => { Thread.CurrentThread.Name = "GadgetCore Unity Engine Log Cloner"; Thread.CurrentThread.Priority = System.Threading.ThreadPriority.Lowest; Thread.CurrentThread.IsBackground = true; string logPath = Application.dataPath + "\\output_log.txt"; if (!File.Exists(logPath)) { logPath = Application.persistentDataPath + "\\output_log.txt"; } if (!File.Exists(logPath)) { logPath = "~/Library/Logs/Unity/Player.log"; } if (!File.Exists(logPath)) { logPath = "~/.config/unity3d/DefaultCompany/Roguelands/Player.log"; } if (!File.Exists(logPath)) { CoreLogger.LogWarning("Unable to find Unity log file!"); return; } string targetPath = Path.Combine(GadgetPaths.LogsPath, "Unity Output.log"); DateTime t = default; while (!Quitting) { if (File.Exists(logPath) && File.GetLastWriteTime(logPath) > t) { File.Copy(logPath, targetPath, true); t = DateTime.Now; } Thread.Sleep(100); } })).Start(); AppDomain.CurrentDomain.AssemblyResolve += (object sender, ResolveEventArgs args) => { string name = new AssemblyName(args.Name).Name; if (LoadedAssemblies.ContainsKey(name)) { return(LoadedAssemblies[name]); } foreach (string file in Directory.GetFiles(GadgetPaths.LibsPath)) { if (AssemblyName.GetAssemblyName(file).Name == name) { Assembly assembly = Assembly.LoadFrom(file); LoadedAssemblies[name] = assembly; return(assembly); } } return(null); }; AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += (object sender, ResolveEventArgs args) => { string name = new AssemblyName(args.Name).Name; if (LoadedAssemblies.ContainsKey("ReflectionOnly: " + name)) { return(LoadedAssemblies["ReflectionOnly: " + name]); } foreach (string file in Directory.GetFiles(GadgetPaths.LibsPath)) { if (AssemblyName.GetAssemblyName(file).Name == name) { Assembly assembly = Assembly.ReflectionOnlyLoadFrom(file); LoadedAssemblies["ReflectionOnly: " + name] = assembly; return(assembly); } } return(null); }; LoadMainMenu(); try { UMFAPI = new UMFAPI(); UMFAPI.GetModNames(); CoreLogger.Log("Enabling UMF API as UMF is installed."); } catch (Exception) { UMFAPI = null; CoreLogger.Log("Disabling UMF API as UMF is not installed."); } CoreLib = Activator.CreateInstance(Assembly.LoadFile(Path.Combine(Path.Combine(GadgetPaths.GadgetCorePath, "DependentLibs"), "GadgetCoreLib.dll")).GetTypes().First(x => typeof(IGadgetCoreLib).IsAssignableFrom(x))) as IGadgetCoreLib; CoreLib.ProvideLogger(CoreLogger); GadgetCoreConfig.Load(); CoreLogger.Log("Finished loading config."); RegisterKeys(); IniData coreManifest = new IniData(); coreManifest["Metadata"]["Name"] = "GadgetCore"; coreManifest["Metadata"]["Assembly"] = Path.Combine(GadgetPaths.ManagedPath, "GadgetCore.dll"); GadgetMod coreMod = new GadgetMod(GadgetPaths.GadgetCorePath, coreManifest, Assembly.GetExecutingAssembly()); GadgetMods.RegisterMod(coreMod); VanillaRegistration(); SceneManager.sceneLoaded += OnSceneLoaded; SceneInjector.InjectMainMenu(); GadgetLoader.LoadAllMods(); DontDestroyOnLoad(new GameObject("GadgetCore", typeof(GadgetCore))); CoreLogger.LogConsole("GadgetCore v" + GadgetCoreAPI.FULL_VERSION + " Initialized!"); #pragma warning disable CS0162 // Unreachable code detected if (GadgetCoreAPI.IS_BETA) { CoreLogger.LogWarning("You are currently running a beta version of GadgetCore! Be prepared for bugs!"); } #pragma warning restore CS0162 // Unreachable code detected } catch (Exception e) { CoreLogger.LogError("There was a fatal error loading GadgetCore: " + e); } }
private static void LoadModAssemblies() { Log("Identifying Gadget Mods"); nonGadgetMods = new List <string>(); disabledMods = new List <string>(); incompatibleMods = new List <string>(); List <string> libNames = Directory.GetFiles(UMFData.LibrariesPath).Select(x => Path.GetFileNameWithoutExtension(x)).ToList(); List <string> verifiedMods = new List <string>(); List <string> verifiedLibs = new List <string>(); foreach (string modName in UMFData.ModNames) { if (libNames.Contains(modName)) { verifiedLibs.Add(modName); } else { verifiedMods.Add(modName); } } GadgetCoreAPI.ModNames = new System.Collections.ObjectModel.ReadOnlyCollection <string>(verifiedMods); GadgetCoreAPI.LibNames = new System.Collections.ObjectModel.ReadOnlyCollection <string>(verifiedLibs); List <string> modNames = verifiedMods; int[] currentVersionNums = GadgetCoreAPI.VERSION.Split('.').Select(x => int.Parse(x)).ToArray(); if (currentVersionNums.Length != 4) { Array.Resize(ref currentVersionNums, 4); } for (int i = 0; i < modNames.Count; i++) { Assembly assembly = UMFMod.GetMod(modNames[i]); if (assembly != null) { bool foundGadgetMod = false; foreach (Type type in assembly.GetTypes()) { GadgetModAttribute attribute = (GadgetModAttribute)type.GetCustomAttributes(typeof(GadgetModAttribute), true).FirstOrDefault(); if (attribute != null && type.IsSubclassOf(typeof(GadgetMod))) { foundGadgetMod = true; int[] targetVersionNums = attribute.TargetGCVersion.Split('.').Select(x => int.Parse(x)).ToArray(); if (targetVersionNums.Length != 4) { Array.Resize(ref targetVersionNums, 4); } if ((attribute.GadgetVersionSpecificity == VersionSpecificity.MAJOR && currentVersionNums[0] == targetVersionNums[0] && (currentVersionNums[1] > targetVersionNums[1] || (currentVersionNums[1] == targetVersionNums[1] && (currentVersionNums[2] > targetVersionNums[2] || (currentVersionNums[2] == targetVersionNums[2] && currentVersionNums[3] >= targetVersionNums[3]))))) || (attribute.GadgetVersionSpecificity == VersionSpecificity.MINOR && currentVersionNums[0] == targetVersionNums[0] && currentVersionNums[1] == targetVersionNums[1] && (currentVersionNums[2] > targetVersionNums[2] || (currentVersionNums[2] == targetVersionNums[2] && currentVersionNums[3] >= targetVersionNums[3]))) || (attribute.GadgetVersionSpecificity == VersionSpecificity.NONBREAKING && currentVersionNums[0] == targetVersionNums[0] && currentVersionNums[1] == targetVersionNums[1] && currentVersionNums[2] == targetVersionNums[2] && currentVersionNums[3] >= targetVersionNums[3]) || (attribute.GadgetVersionSpecificity == VersionSpecificity.BUGFIX && currentVersionNums[0] == targetVersionNums[0] && currentVersionNums[1] == targetVersionNums[1] && currentVersionNums[2] == targetVersionNums[2] && currentVersionNums[3] == targetVersionNums[3])) { GadgetMod mod = null; try { mod = Activator.CreateInstance(type) as GadgetMod; if (mod != null) { Log("Found Gadget Mod to load: " + attribute.Name + ", in assembly: {" + assembly.FullName + "}"); GadgetMods.RegisterMod(new GadgetModInfo(mod, assembly, attribute, modNames[i])); } } catch (Exception) { } finally { if (mod == null) { Log("Found Gadget Mod without a parameterless constructor: " + attribute.Name + ", in assembly: {" + assembly.FullName + "}"); } } } else { incompatibleMods.Add(assembly.GetName().Name); int rD = (int)attribute.GadgetVersionSpecificity; Log("Found Gadget Mod with an incompatible version: " + attribute.Name + ", in assembly: {" + assembly.FullName + "}. Requires version: " + new string(attribute.TargetGCVersion.TakeWhile(x => (x == '.' ? --rD : rD) > 0).ToArray())); } } } if (!foundGadgetMod) { nonGadgetMods.Add(modNames[i]); } } else { disabledMods.Add(modNames[i]); } } GadgetMods.SortMods(); if (!Directory.Exists(Path.Combine(UMFData.ModsPath, "PackedMods"))) { Directory.CreateDirectory(Path.Combine(UMFData.ModsPath, "PackedMods")); } packedMods = Directory.GetFiles(UMFData.ModsPath, "*.zip").Where(x => !UMFData.Mods.Select(y => y.GetName().Name).Any(y => y == Path.GetFileNameWithoutExtension(x).Split('_')[0])).Union(Directory.GetFiles(Path.Combine(UMFData.ModsPath, "PackedMods"), "*.zip").Where(x => !UMFData.Mods.Select(y => y.GetName().Name).Any(y => y == Path.GetFileNameWithoutExtension(x).Split('_')[0]))).ToList(); dependencies = new Dictionary <string, List <string> >(); Assembly[] allMods = GadgetMods.ListAllModInfos().Select(x => x.Assembly).Concat(nonGadgetMods.Select(x => UMFMod.GetMod(x))).Concat(incompatibleMods.Select(x => UMFMod.GetMod(x))).ToArray(); for (int i = 0; i < allMods.Length; i++) { Assembly mod = allMods[i]; List <string> dependencies = new List <string>(); if (i < GadgetMods.CountMods()) { GadgetModInfo gadgetMod = GadgetMods.GetModInfo(i); int rD = (int)gadgetMod.Attribute.GadgetVersionSpecificity; dependencies.Add("GadgetCore v" + new string(gadgetMod.Attribute.TargetGCVersion.TakeWhile(x => (x == '.' ? --rD : rD) > 0).ToArray())); } dependencies.AddRange(mod.GetReferencedAssemblies().Where(x => !x.Name.Equals("GadgetCore") && allMods.Select(a => a.GetName().Name).Contains(x.Name)).Select(x => x.Name + " v" + x.Version)); if (dependencies.Count > 0) { GadgetCore.dependencies.Add(mod.GetName().Name, dependencies.ToList()); } } foreach (GadgetModInfo mod in GadgetMods.ListAllModInfos()) { foreach (string dependency in mod.Attribute.Dependencies) { string[] splitDependency = dependency.Split(' '); if (!dependencies[mod.UMFName].Select(x => { string[] split = x.Split(' '); return(string.Join("", split.Take(split.Length - 1).ToArray())); }).Contains(string.Join("", splitDependency.Take(splitDependency.Length - 1).ToArray()))) { dependencies[mod.UMFName].Add(dependency); } } } Log("Finished Identifying Gadget Mods, to load: " + GadgetMods.CountMods()); }