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)
{
}
}
}