mirror of
https://github.com/EggLinks/DanhengServer-OpenSource.git
synced 2026-01-03 04:36:03 +08:00
Feature:Asynchronous Operation & Formatting Code
- Now the async operation is enabled! - Code formatted by Resharper plugin <3
This commit is contained in:
@@ -1,14 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
namespace EggLink.DanhengServer.Plugin.Constructor;
|
||||
|
||||
namespace EggLink.DanhengServer.Plugin.Constructor
|
||||
public interface IPlugin
|
||||
{
|
||||
public interface IPlugin
|
||||
{
|
||||
public void OnLoad();
|
||||
public void OnUnload();
|
||||
}
|
||||
}
|
||||
public void OnLoad();
|
||||
public void OnUnload();
|
||||
}
|
||||
@@ -1,16 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
namespace EggLink.DanhengServer.Plugin.Constructor;
|
||||
|
||||
namespace EggLink.DanhengServer.Plugin.Constructor
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class PluginInfo(string name, string description, string version) : Attribute
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class PluginInfo(string name, string description, string version) : Attribute
|
||||
{
|
||||
public string Name { get; } = name;
|
||||
public string Description { get; } = description;
|
||||
public string Version { get; } = version;
|
||||
}
|
||||
}
|
||||
public string Name { get; } = name;
|
||||
public string Description { get; } = description;
|
||||
public string Version { get; } = version;
|
||||
}
|
||||
@@ -1,70 +1,68 @@
|
||||
using EggLink.DanhengServer.Game.Player;
|
||||
using EggLink.DanhengServer.Game.Scene.Entity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace EggLink.DanhengServer.Plugin.Event
|
||||
namespace EggLink.DanhengServer.Plugin.Event;
|
||||
|
||||
public static class PluginEvent
|
||||
{
|
||||
public static class PluginEvent
|
||||
public static void InvokeOnPlayerHeartBeat(PlayerInstance player)
|
||||
{
|
||||
#region Player
|
||||
|
||||
public delegate void OnPlayerHeartBeatHandler(PlayerInstance player);
|
||||
public delegate void OnPlayerLoginHandler(PlayerInstance player);
|
||||
public delegate void OnPlayerLogoutHandler(PlayerInstance player);
|
||||
public delegate void OnPlayerFinishSubMissionHandler(PlayerInstance player, int missionId);
|
||||
public delegate void OnPlayerFinishMainMissionHandler(PlayerInstance player, int missionId);
|
||||
public delegate void OnPlayerInteractHandler(PlayerInstance player, EntityProp prop);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Common
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event
|
||||
|
||||
public static event OnPlayerHeartBeatHandler? OnPlayerHeartBeat;
|
||||
public static event OnPlayerLoginHandler? OnPlayerLogin;
|
||||
public static event OnPlayerLogoutHandler? OnPlayerLogout;
|
||||
public static event OnPlayerFinishSubMissionHandler? OnPlayerFinishSubMission;
|
||||
public static event OnPlayerFinishMainMissionHandler? OnPlayerFinishMainMission;
|
||||
public static event OnPlayerInteractHandler? OnPlayerInteract;
|
||||
|
||||
#endregion
|
||||
|
||||
public static void InvokeOnPlayerHeartBeat(PlayerInstance player)
|
||||
{
|
||||
OnPlayerHeartBeat?.Invoke(player);
|
||||
}
|
||||
|
||||
public static void InvokeOnPlayerLogin(PlayerInstance player)
|
||||
{
|
||||
OnPlayerLogin?.Invoke(player);
|
||||
}
|
||||
|
||||
public static void InvokeOnPlayerLogout(PlayerInstance player)
|
||||
{
|
||||
OnPlayerLogout?.Invoke(player);
|
||||
}
|
||||
|
||||
public static void InvokeOnPlayerFinishSubMission(PlayerInstance player, int missionId)
|
||||
{
|
||||
OnPlayerFinishSubMission?.Invoke(player, missionId);
|
||||
}
|
||||
|
||||
public static void InvokeOnPlayerFinishMainMission(PlayerInstance player, int missionId)
|
||||
{
|
||||
OnPlayerFinishMainMission?.Invoke(player, missionId);
|
||||
}
|
||||
|
||||
public static void InvokeOnPlayerInteract(PlayerInstance player, EntityProp prop)
|
||||
{
|
||||
OnPlayerInteract?.Invoke(player, prop);
|
||||
}
|
||||
OnPlayerHeartBeat?.Invoke(player);
|
||||
}
|
||||
}
|
||||
|
||||
public static void InvokeOnPlayerLogin(PlayerInstance player)
|
||||
{
|
||||
OnPlayerLogin?.Invoke(player);
|
||||
}
|
||||
|
||||
public static void InvokeOnPlayerLogout(PlayerInstance player)
|
||||
{
|
||||
OnPlayerLogout?.Invoke(player);
|
||||
}
|
||||
|
||||
public static void InvokeOnPlayerFinishSubMission(PlayerInstance player, int missionId)
|
||||
{
|
||||
OnPlayerFinishSubMission?.Invoke(player, missionId);
|
||||
}
|
||||
|
||||
public static void InvokeOnPlayerFinishMainMission(PlayerInstance player, int missionId)
|
||||
{
|
||||
OnPlayerFinishMainMission?.Invoke(player, missionId);
|
||||
}
|
||||
|
||||
public static void InvokeOnPlayerInteract(PlayerInstance player, EntityProp prop)
|
||||
{
|
||||
OnPlayerInteract?.Invoke(player, prop);
|
||||
}
|
||||
|
||||
#region Player
|
||||
|
||||
public delegate void OnPlayerHeartBeatHandler(PlayerInstance player);
|
||||
|
||||
public delegate void OnPlayerLoginHandler(PlayerInstance player);
|
||||
|
||||
public delegate void OnPlayerLogoutHandler(PlayerInstance player);
|
||||
|
||||
public delegate void OnPlayerFinishSubMissionHandler(PlayerInstance player, int missionId);
|
||||
|
||||
public delegate void OnPlayerFinishMainMissionHandler(PlayerInstance player, int missionId);
|
||||
|
||||
public delegate void OnPlayerInteractHandler(PlayerInstance player, EntityProp prop);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Common
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event
|
||||
|
||||
public static event OnPlayerHeartBeatHandler? OnPlayerHeartBeat;
|
||||
public static event OnPlayerLoginHandler? OnPlayerLogin;
|
||||
public static event OnPlayerLogoutHandler? OnPlayerLogout;
|
||||
public static event OnPlayerFinishSubMissionHandler? OnPlayerFinishSubMission;
|
||||
public static event OnPlayerFinishMainMissionHandler? OnPlayerFinishMainMission;
|
||||
public static event OnPlayerInteractHandler? OnPlayerInteract;
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -1,160 +1,137 @@
|
||||
using EggLink.DanhengServer.Internationalization;
|
||||
using System.Reflection;
|
||||
using EggLink.DanhengServer.Internationalization;
|
||||
using EggLink.DanhengServer.Plugin.Constructor;
|
||||
using EggLink.DanhengServer.Util;
|
||||
using McMaster.NETCore.Plugins;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace EggLink.DanhengServer.Plugin
|
||||
namespace EggLink.DanhengServer.Plugin;
|
||||
|
||||
public class PluginManager
|
||||
{
|
||||
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()
|
||||
{
|
||||
private readonly static Logger logger = new("PluginManager");
|
||||
public readonly static Dictionary<IPlugin, PluginInfo> Plugins = [];
|
||||
var assemblies = new List<Type>();
|
||||
foreach (var plugin in Plugins.Keys)
|
||||
if (PluginAssemblies.TryGetValue(plugin, out var value))
|
||||
assemblies.AddRange(value);
|
||||
|
||||
public readonly static Dictionary<IPlugin, List<Type>> PluginAssemblies = [];
|
||||
return assemblies;
|
||||
}
|
||||
|
||||
#region Plugin Manager
|
||||
#region Plugin Manager
|
||||
|
||||
public static void LoadPlugins()
|
||||
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);
|
||||
|
||||
if (!Directory.Exists(ConfigManager.Config.Path.PluginConfigPath))
|
||||
Directory.CreateDirectory(ConfigManager.Config.Path.PluginConfigPath);
|
||||
|
||||
var plugins = Directory.GetFiles(ConfigManager.Config.Path.PluginPath, "*.dll");
|
||||
var loaders = new List<PluginLoader>();
|
||||
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
|
||||
{
|
||||
// get all the plugins in the plugin directory
|
||||
if (!Directory.Exists(ConfigManager.Config.Path.PluginPath))
|
||||
{
|
||||
Directory.CreateDirectory(ConfigManager.Config.Path.PluginPath);
|
||||
}
|
||||
var assemblyName = new AssemblyName(args.Name).Name + ".dll";
|
||||
var assemblyPath = Path.Combine(ConfigManager.Config.Path.PluginPath, assemblyName);
|
||||
|
||||
if (!Directory.Exists(ConfigManager.Config.Path.PluginConfigPath))
|
||||
{
|
||||
Directory.CreateDirectory(ConfigManager.Config.Path.PluginConfigPath);
|
||||
}
|
||||
if (File.Exists(assemblyPath)) return Assembly.LoadFrom(assemblyPath);
|
||||
|
||||
var plugins = Directory.GetFiles(ConfigManager.Config.Path.PluginPath, "*.dll");
|
||||
var loaders = new List<PluginLoader>();
|
||||
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
|
||||
{
|
||||
var assemblyName = new AssemblyName(args.Name).Name + ".dll";
|
||||
var assemblyPath = Path.Combine(ConfigManager.Config.Path.PluginPath, assemblyName);
|
||||
|
||||
if (File.Exists(assemblyPath))
|
||||
{
|
||||
return Assembly.LoadFrom(assemblyPath);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
foreach (var plugin in plugins)
|
||||
{
|
||||
var fileInfo = new FileInfo(plugin);
|
||||
LoadPlugin(fileInfo.FullName);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
foreach (var plugin in plugins)
|
||||
{
|
||||
var fileInfo = new FileInfo(plugin);
|
||||
LoadPlugin(fileInfo.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadPlugin(string plugin)
|
||||
public static void LoadPlugin(string plugin)
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
var config = new PluginConfig(plugin)
|
||||
{
|
||||
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))
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (Activator.CreateInstance(type) is IPlugin pluginInstance)
|
||||
var pluginInfo = type.GetCustomAttribute<PluginInfo>();
|
||||
if (pluginInfo != null)
|
||||
{
|
||||
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);
|
||||
|
||||
pluginInstance.OnLoad();
|
||||
logger.Info(
|
||||
$"Loaded plugin {pluginInfo.Name} v{pluginInfo.Version}: {pluginInfo.Description}");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error($"Failed to load plugin {plugin}: Plugin instance is null");
|
||||
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);
|
||||
|
||||
pluginInstance.OnLoad();
|
||||
}
|
||||
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)
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (Plugins.TryGetValue(plugin, out PluginInfo? value))
|
||||
{
|
||||
plugin.OnUnload();
|
||||
Plugins.Remove(plugin);
|
||||
PluginAssemblies.Remove(plugin);
|
||||
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
|
||||
|
||||
public static List<Type> GetPluginAssemblies()
|
||||
{
|
||||
var assemblies = new List<Type>();
|
||||
foreach (var plugin in Plugins.Keys)
|
||||
{
|
||||
if (PluginAssemblies.TryGetValue(plugin, out List<Type>? value))
|
||||
{
|
||||
assemblies.AddRange(value);
|
||||
}
|
||||
}
|
||||
|
||||
return assemblies;
|
||||
logger.Error($"Failed to load plugin {plugin}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void UnloadPlugin(IPlugin plugin)
|
||||
{
|
||||
if (Plugins.TryGetValue(plugin, out var value))
|
||||
{
|
||||
plugin.OnUnload();
|
||||
Plugins.Remove(plugin);
|
||||
PluginAssemblies.Remove(plugin);
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user