using BepInEx.Common; using System; using System.Collections.Generic; using System.IO; using System.Reflection; using UnityEngine; namespace BepInEx { /// /// The manager and loader for all plugins, and the entry point for BepInEx. /// public class Chainloader { /// /// The loaded and initialized list of plugins. /// public static List Plugins { get; protected set; } = new List(); /// /// The GameObject that all plugins are attached to as components. /// public static GameObject ManagerObject { get; protected set; } = new GameObject("BepInEx_Manager"); static bool loaded = false; /// /// The entry point for BepInEx, called on the very first LoadScene() from UnityEngine. /// public static void Initialize() { if (loaded) return; try { UnityEngine.Object.DontDestroyOnLoad(ManagerObject); if (Directory.Exists(Utility.PluginsDirectory)) { var pluginTypes = LoadTypes(Utility.PluginsDirectory); //Log($"{pluginTypes.Count()} plugins found"); foreach (Type t in pluginTypes) { var plugin = (BaseUnityPlugin)ManagerObject.AddComponent(t); Plugins.Add(plugin); //Log($"Loaded [{plugin.Name}]"); } } } catch (Exception ex) { UnityInjector.ConsoleUtil.ConsoleWindow.Attach(); //UnityInjector.ConsoleUtil.ConsoleEncoding.ConsoleCodePage = 932; Console.WriteLine("Error occurred starting the game"); Console.WriteLine(ex.ToString()); } loaded = true; } /// /// Checks all plugins to see if a plugin with a certain ID is loaded. /// /// The ID to check for. /// public static bool IsIDLoaded(string ID) { foreach (var plugin in Plugins) if (plugin != null && plugin.enabled && plugin.ID == ID) return true; return false; } /// /// Loads a list of types from a directory containing assemblies, that derive from a base type. /// /// The specfiic base type to search for. /// The directory to search for assemblies. /// Returns a list of found derivative types. public static List LoadTypes(string directory) { List types = new List(); Type pluginType = typeof(T); foreach (string dll in Directory.GetFiles(Path.GetFullPath(directory), "*.dll")) { try { AssemblyName an = AssemblyName.GetAssemblyName(dll); Assembly assembly = Assembly.Load(an); foreach (Type type in assembly.GetTypes()) { if (type.IsInterface || type.IsAbstract) { continue; } else { if (type.BaseType == pluginType) types.Add(type); } } } catch (BadImageFormatException) { } } return types; } } }