mirror of
https://github.com/EggLinks/DanhengServer-OpenSource.git
synced 2026-01-03 04:36:03 +08:00
146 lines
5.1 KiB
C#
146 lines
5.1 KiB
C#
using System.Reflection;
|
|
using EggLink.DanhengServer.GameServer.Plugin.Constructor;
|
|
using EggLink.DanhengServer.Internationalization;
|
|
using EggLink.DanhengServer.Util;
|
|
using McMaster.NETCore.Plugins;
|
|
|
|
namespace EggLink.DanhengServer.GameServer.Plugin;
|
|
|
|
public class PluginManager
|
|
{
|
|
private static readonly Logger Logger = new("PluginManager");
|
|
public static readonly Dictionary<IPlugin, PluginInfo> Plugins = [];
|
|
|
|
public static readonly Dictionary<IPlugin, List<Type>> PluginAssemblies = [];
|
|
|
|
public static List<Type> GetPluginAssemblies()
|
|
{
|
|
var assemblies = new List<Type>();
|
|
foreach (var plugin in Plugins.Keys)
|
|
if (PluginAssemblies.TryGetValue(plugin, out var value))
|
|
assemblies.AddRange(value);
|
|
|
|
return assemblies;
|
|
}
|
|
|
|
#region Plugin Manager
|
|
|
|
public static void LoadPlugins()
|
|
{
|
|
// get all the plugins in the plugin directory
|
|
if (!Directory.Exists(ConfigManager.Config.Path.PluginPath))
|
|
Directory.CreateDirectory(ConfigManager.Config.Path.PluginPath);
|
|
|
|
var plugins = Directory.GetFiles(ConfigManager.Config.Path.PluginPath, "*.dll");
|
|
AppDomain.CurrentDomain.AssemblyResolve += (_, args) =>
|
|
{
|
|
var assemblyName = new AssemblyName(args.Name).Name + ".dll";
|
|
var assemblyPath = Path.Combine(ConfigManager.Config.Path.PluginPath, assemblyName);
|
|
|
|
return File.Exists(assemblyPath) ? Assembly.LoadFrom(assemblyPath) : null;
|
|
};
|
|
foreach (var plugin in plugins)
|
|
{
|
|
var fileInfo = new FileInfo(plugin);
|
|
LoadPlugin(fileInfo.FullName);
|
|
}
|
|
|
|
//var dict = PluginAssemblies.ToDictionary(pluginAssembly => Plugins[pluginAssembly.Key].Name, pluginAssembly => pluginAssembly.Value);
|
|
|
|
//I18NManager.LoadPluginLanguage(dict);
|
|
}
|
|
|
|
public static void LoadPlugin(string plugin)
|
|
{
|
|
try
|
|
{
|
|
var config = new PluginConfig(plugin)
|
|
{
|
|
PreferSharedTypes = true,
|
|
LoadInMemory = true
|
|
};
|
|
|
|
var loader = new PluginLoader(config);
|
|
|
|
var assembly = loader.LoadDefaultAssembly();
|
|
var types = assembly.GetTypes();
|
|
|
|
foreach (var type in types)
|
|
if (typeof(IPlugin).IsAssignableFrom(type))
|
|
{
|
|
if (Activator.CreateInstance(type) is IPlugin pluginInstance)
|
|
{
|
|
var pluginInfo = type.GetCustomAttribute<PluginInfo>();
|
|
if (pluginInfo != null)
|
|
{
|
|
Logger.Info(
|
|
$"Loaded plugin {pluginInfo.Name} v{pluginInfo.Version}: {pluginInfo.Description}");
|
|
}
|
|
else
|
|
{
|
|
Logger.Info($"Loaded plugin {plugin}: No plugin info");
|
|
continue;
|
|
}
|
|
|
|
if (Plugins.Values.Any(p => p.Name == pluginInfo.Name))
|
|
{
|
|
Logger.Error($"Failed to load plugin {plugin}: Plugin already loaded");
|
|
continue;
|
|
}
|
|
|
|
Plugins.Add(pluginInstance, pluginInfo);
|
|
|
|
if (!PluginAssemblies.TryGetValue(pluginInstance, out var pluginTypes))
|
|
{
|
|
pluginTypes = [];
|
|
PluginAssemblies[pluginInstance] = pluginTypes;
|
|
}
|
|
|
|
pluginTypes.AddRange(types);
|
|
|
|
try
|
|
{
|
|
var dict = new Dictionary<string, List<Type>> { { pluginInfo.Name, pluginTypes } };
|
|
|
|
I18NManager.LoadPluginLanguage(dict);
|
|
pluginInstance.OnLoad();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.Error($"Failed to load plugin {plugin}: {e.Message}");
|
|
// unload the plugin
|
|
UnloadPlugin(pluginInstance);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Logger.Error($"Failed to load plugin {plugin}: Plugin instance is null");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Error($"Failed to load plugin {plugin}: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public static void UnloadPlugin(IPlugin plugin)
|
|
{
|
|
if (!Plugins.TryGetValue(plugin, out var value)) return;
|
|
plugin.OnUnload();
|
|
Plugins.Remove(plugin);
|
|
PluginAssemblies.Remove(plugin);
|
|
I18NManager.PluginLanguages.Remove(value.Name);
|
|
Logger.Info($"Unloaded plugin {value.Name}");
|
|
}
|
|
|
|
|
|
public static void UnloadPlugins()
|
|
{
|
|
foreach (var plugin in Plugins.Keys) UnloadPlugin(plugin);
|
|
|
|
Logger.Info(I18NManager.Translate("Server.ServerInfo.UnloadedItems", I18NManager.Translate("Word.Plugin")));
|
|
}
|
|
|
|
#endregion
|
|
} |