using BepInEx.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
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;
if (bool.Parse(Config.GetEntry("console", "false")))
{
UnityInjector.ConsoleUtil.ConsoleWindow.Attach();
if (bool.Parse(Config.GetEntry("console-shiftjis", "false")))
UnityInjector.ConsoleUtil.ConsoleEncoding.ConsoleCodePage = 932;
}
try
{
BepInLogger.Log($"Chainloader started");
UnityEngine.Object.DontDestroyOnLoad(ManagerObject);
if (Directory.Exists(Utility.PluginsDirectory))
{
var pluginTypes = LoadTypes(Utility.PluginsDirectory);
BepInLogger.Log($"{pluginTypes.Count} plugins found");
foreach (Type t in pluginTypes)
{
try
{
var plugin = (BaseUnityPlugin)ManagerObject.AddComponent(t);
Plugins.Add(plugin);
BepInLogger.Log($"Loaded [{plugin.Name}]");
}
catch (Exception ex)
{
BepInLogger.Log($"Error loading [{t.Name}] : {ex.Message}");
}
}
}
}
catch (Exception ex)
{
UnityInjector.ConsoleUtil.ConsoleWindow.Attach();
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;
}
}
}