/// <summary> /// Loads the mod by searching for assemblies in hollow_knight_Data\Managed\Mods\ /// </summary> public static void LoadMods() { if (Loaded) { return; } Logger.Log("[API] - Trying to load mods"); string path = string.Empty; if (SystemInfo.operatingSystem.Contains("Windows")) { path = Application.dataPath + "\\Managed\\Mods"; } else if (SystemInfo.operatingSystem.Contains("Mac")) { path = Application.dataPath + "/Resources/Data/Managed/Mods/"; } else if (SystemInfo.operatingSystem.Contains("Linux")) { path = Application.dataPath + "/Managed/Mods"; } else { Logger.LogWarn($"Operating system of {SystemInfo.operatingSystem} is not known. Unable to load mods."); } if (string.IsNullOrEmpty(path)) { Loaded = true; return; } foreach (string text2 in Directory.GetFiles(path, "*.dll")) { Logger.LogDebug("[API] - Loading assembly: " + text2); try { foreach (Type type in Assembly.LoadFile(text2).GetExportedTypes()) { if (IsSubclassOfRawGeneric(typeof(Mod <>), type)) { Logger.LogDebug("[API] - Trying to instantiate mod<T>: " + type); IMod mod = Activator.CreateInstance(type) as IMod; if (mod == null) { continue; } LoadedMods.Add((Mod)mod); } else if (!type.IsGenericType && type.IsClass && type.IsSubclassOf(typeof(Mod))) { Logger.LogDebug("[API] - Trying to instantiate mod: " + type); Mod mod2 = type.GetConstructor(new Type[0])?.Invoke(new object[0]) as Mod; if (mod2 == null) { continue; } LoadedMods.Add(mod2); } } } catch (Exception ex) { Logger.LogError("[API] - Error: " + ex); Errors.Add(string.Concat(text2, ": FAILED TO LOAD! Check ModLog.txt.")); } } ModHooks.Instance.LoadGlobalSettings(); foreach (IMod mod in LoadedMods.OrderBy(x => x.LoadPriority())) { try { LoadMod(mod, false, false); } catch (Exception ex) { Errors.Add(string.Concat(mod.GetName(), ": FAILED TO LOAD! Check ModLog.txt.")); Logger.LogError("[API] - Error: " + ex); } } //Clean out the ModEnabledSettings for any mods that don't exist. //Calling ToList means we are not working with the dictionary keys directly, preventing an out of sync error foreach (string modName in ModHooks.Instance.GlobalSettings.ModEnabledSettings.Keys.ToList()) { if (LoadedMods.All(x => x.GetName() != modName)) { ModHooks.Instance.GlobalSettings.ModEnabledSettings.Remove(modName); } } // Get previously disabled mods and disable them. foreach (KeyValuePair <string, bool> modPair in ModHooks.Instance.GlobalSettings.ModEnabledSettings.Where(x => !x.Value)) { IMod mod = LoadedMods.FirstOrDefault(x => x.GetName() == modPair.Key); if (!(mod is ITogglableMod togglable)) { continue; } togglable.Unload(); Logger.LogDebug($"Mod {modPair.Key} was unloaded."); } GameObject gameObject = new GameObject(); _draw = gameObject.AddComponent <ModVersionDraw>(); UnityEngine.Object.DontDestroyOnLoad(gameObject); UpdateModText(); Loaded = true; ModHooks.Instance.SaveGlobalSettings(); }