using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; namespace BepInEx { public static class TypeLoader { /// /// 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 IEnumerable 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; } public static BepInPlugin GetMetadata(object plugin) { return GetMetadata(plugin.GetType()); } public static BepInPlugin GetMetadata(Type pluginType) { object[] attributes = pluginType.GetCustomAttributes(typeof(BepInPlugin), false); if (attributes.Length == 0) return null; return (BepInPlugin)attributes[0]; } public static IEnumerable GetAttributes(object plugin) where T : Attribute { return GetAttributes(plugin.GetType()); } public static IEnumerable GetAttributes(Type pluginType) where T : Attribute { return pluginType.GetCustomAttributes(typeof(T), true).Cast(); } public static IEnumerable GetDependencies(Type Plugin, IEnumerable AllPlugins) { object[] attributes = Plugin.GetCustomAttributes(typeof(BepInDependency), true); List dependencyTypes = new List(); foreach (BepInDependency dependency in attributes) { Type dependencyType = AllPlugins.FirstOrDefault(x => GetMetadata(x)?.GUID == dependency.DependencyGUID); if (dependencyType == null) { if ((dependency.Flags & BepInDependency.DependencyFlags.SoftDependency) != 0) continue; //skip on soft dependencies throw new MissingDependencyException("Cannot find dependency type."); } dependencyTypes.Add(dependencyType); } return dependencyTypes; } } public class MissingDependencyException : Exception { public MissingDependencyException() : base() { } public MissingDependencyException(string message) : base(message) { } } }