Redesigned the DiscordBotCore by splitting it into multiple projects. Created a WebUI and preparing to remove the DiscordBot application

This commit is contained in:
2025-04-04 22:07:30 +03:00
parent 62ba5ec63d
commit a4afb28f36
2290 changed files with 76694 additions and 17052 deletions

View File

@@ -0,0 +1,81 @@
using System.Reflection;
using DiscordBotCore.PluginCore;
using DiscordBotCore.PluginCore.Interfaces;
using DiscordBotCore.PluginManagement.Loading.Exceptions;
namespace DiscordBotCore.PluginManagement.Loading;
internal class Loader
{
internal delegate void FileLoadedHandler(string fileName, Exception exception);
internal delegate void PluginLoadedHandler(PluginLoaderResult result);
internal event FileLoadedHandler? OnFileLoadedException;
internal event PluginLoadedHandler? OnPluginLoaded;
private readonly IPluginManager _pluginManager;
internal Loader(IPluginManager manager)
{
_pluginManager = manager;
}
internal async Task Load()
{
var installedPlugins = await _pluginManager.GetInstalledPlugins();
var files = installedPlugins.Where(plugin => plugin.IsEnabled).Select(plugin => plugin.FilePath).ToArray();
foreach (var file in files)
{
try
{
Assembly.LoadFrom(file);
}
catch
{
OnFileLoadedException?.Invoke(file, new Exception($"Failed to load plugin from file {file}"));
}
}
await LoadEverythingOfType<IDbEvent>();
await LoadEverythingOfType<IDbCommand>();
await LoadEverythingOfType<IDbSlashCommand>();
}
private Task LoadEverythingOfType<T>()
{
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => typeof(T).IsAssignableFrom(p) && !p.IsInterface);
foreach (var type in types)
{
try
{
var plugin = (T?)Activator.CreateInstance(type);
if (plugin is null)
{
throw new Exception($"Failed to create instance of plugin with type {type.FullName} [{type.Assembly}]");
}
PluginLoaderResult result = plugin switch
{
IDbEvent @event => PluginLoaderResult.FromIDbEvent(@event),
IDbCommand command => PluginLoaderResult.FromIDbCommand(command),
IDbSlashCommand command => PluginLoaderResult.FromIDbSlashCommand(command),
_ => PluginLoaderResult.FromException(new PluginNotFoundException($"Unknown plugin type {plugin.GetType().FullName}"))
};
OnPluginLoaded?.Invoke(result);
}
catch (Exception ex)
{
OnPluginLoaded?.Invoke(PluginLoaderResult.FromException(ex));
}
}
return Task.CompletedTask;
}
}