From 4b41633cbdb736fe1bef852d01ad92618da038d0 Mon Sep 17 00:00:00 2001 From: DJ Daemonix Date: Sun, 30 Jun 2019 15:31:33 +0200 Subject: [PATCH 1/5] Update Dependencies Discord.NET : 2.1.0 > 2.1.1 --- src/Nodsoft.YumeChan.Core/Nodsoft.YumeChan.Core.csproj | 4 ++-- src/Nodsoft.YumeChan.Modules/Nodsoft.YumeChan.Modules.csproj | 4 ++-- .../Nodsoft.YumeChan.NetRunner.csproj | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Nodsoft.YumeChan.Core/Nodsoft.YumeChan.Core.csproj b/src/Nodsoft.YumeChan.Core/Nodsoft.YumeChan.Core.csproj index bb6929f..ea943c5 100644 --- a/src/Nodsoft.YumeChan.Core/Nodsoft.YumeChan.Core.csproj +++ b/src/Nodsoft.YumeChan.Core/Nodsoft.YumeChan.Core.csproj @@ -14,8 +14,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Nodsoft.YumeChan.Modules/Nodsoft.YumeChan.Modules.csproj b/src/Nodsoft.YumeChan.Modules/Nodsoft.YumeChan.Modules.csproj index 6d3983d..f7faafc 100644 --- a/src/Nodsoft.YumeChan.Modules/Nodsoft.YumeChan.Modules.csproj +++ b/src/Nodsoft.YumeChan.Modules/Nodsoft.YumeChan.Modules.csproj @@ -14,8 +14,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Nodsoft.YumeChan.NetRunner/Nodsoft.YumeChan.NetRunner.csproj b/src/Nodsoft.YumeChan.NetRunner/Nodsoft.YumeChan.NetRunner.csproj index 9743307..86958c1 100644 --- a/src/Nodsoft.YumeChan.NetRunner/Nodsoft.YumeChan.NetRunner.csproj +++ b/src/Nodsoft.YumeChan.NetRunner/Nodsoft.YumeChan.NetRunner.csproj @@ -20,7 +20,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 8f74d8b5e131201f764d20055257ce2fd943d475 Mon Sep 17 00:00:00 2001 From: DJ Daemonix Date: Tue, 2 Jul 2019 10:59:44 +0200 Subject: [PATCH 2/5] Implement Plugin System Allows loading External DLLs for external Command implementation --- .gitignore | 3 +- YumeChan.sln | 18 +++++ .../Nodsoft.YumeChan.ConsoleRunner.csproj | 4 + src/Nodsoft.YumeChan.ConsoleRunner/Program.cs | 10 ++- src/Nodsoft.YumeChan.Core/IPlugin.cs | 19 +++++ .../Modules/InternalModule.cs | 30 +++++++ .../Modules/Status/Status.cs | 33 ++++++++ src/Nodsoft.YumeChan.Core/ModulesLoader.cs | 65 +++++++++++++++ .../Nodsoft.YumeChan.Core.csproj | 8 +- src/Nodsoft.YumeChan.Core/YumeCore.cs | 80 +++++++++++++------ .../ModuleProperties.cs | 29 +++++++ src/Nodsoft.YumeChan.Modules/ModulesIndex.cs | 12 --- .../Nodsoft.YumeChan.Modules.csproj | 52 +++++++----- src/Nodsoft.YumeChan.Modules/Status/Status.cs | 26 ------ src/Nodsoft.YumeChan.NetRunner/Services.cs | 2 +- src/Nodsoft.YumeChan.NetRunner/Startup.cs | 5 +- .../YumeCoreSingleton.cs | 14 ---- 17 files changed, 307 insertions(+), 103 deletions(-) create mode 100644 src/Nodsoft.YumeChan.Core/IPlugin.cs create mode 100644 src/Nodsoft.YumeChan.Core/Modules/InternalModule.cs create mode 100644 src/Nodsoft.YumeChan.Core/Modules/Status/Status.cs create mode 100644 src/Nodsoft.YumeChan.Core/ModulesLoader.cs create mode 100644 src/Nodsoft.YumeChan.Modules/ModuleProperties.cs delete mode 100644 src/Nodsoft.YumeChan.Modules/ModulesIndex.cs delete mode 100644 src/Nodsoft.YumeChan.Modules/Status/Status.cs delete mode 100644 src/Nodsoft.YumeChan.NetRunner/YumeCoreSingleton.cs diff --git a/.gitignore b/.gitignore index 3e759b7..a2bac91 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ bld/ [Bb]in/ [Oo]bj/ [Ll]og/ +[Bb]uild/ # Visual Studio 2015/2017 cache/options directory .vs/ @@ -327,4 +328,4 @@ ASALocalRun/ *.nvuser # MFractors (Xamarin productivity tool) working folder -.mfractor/ +.mfractor/ \ No newline at end of file diff --git a/YumeChan.sln b/YumeChan.sln index 2dbc36e..1f2a459 100644 --- a/YumeChan.sln +++ b/YumeChan.sln @@ -14,25 +14,43 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {B4E6E6B5-B495-4668-BB0D-1107B457C420}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B4E6E6B5-B495-4668-BB0D-1107B457C420}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B4E6E6B5-B495-4668-BB0D-1107B457C420}.Debug|x64.ActiveCfg = Debug|Any CPU + {B4E6E6B5-B495-4668-BB0D-1107B457C420}.Debug|x64.Build.0 = Debug|Any CPU {B4E6E6B5-B495-4668-BB0D-1107B457C420}.Release|Any CPU.ActiveCfg = Release|Any CPU {B4E6E6B5-B495-4668-BB0D-1107B457C420}.Release|Any CPU.Build.0 = Release|Any CPU + {B4E6E6B5-B495-4668-BB0D-1107B457C420}.Release|x64.ActiveCfg = Release|Any CPU + {B4E6E6B5-B495-4668-BB0D-1107B457C420}.Release|x64.Build.0 = Release|Any CPU {58155AE6-D0DF-45E3-9B38-64ED0ACA8AC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {58155AE6-D0DF-45E3-9B38-64ED0ACA8AC0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {58155AE6-D0DF-45E3-9B38-64ED0ACA8AC0}.Debug|x64.ActiveCfg = Debug|Any CPU + {58155AE6-D0DF-45E3-9B38-64ED0ACA8AC0}.Debug|x64.Build.0 = Debug|Any CPU {58155AE6-D0DF-45E3-9B38-64ED0ACA8AC0}.Release|Any CPU.ActiveCfg = Release|Any CPU {58155AE6-D0DF-45E3-9B38-64ED0ACA8AC0}.Release|Any CPU.Build.0 = Release|Any CPU + {58155AE6-D0DF-45E3-9B38-64ED0ACA8AC0}.Release|x64.ActiveCfg = Release|Any CPU + {58155AE6-D0DF-45E3-9B38-64ED0ACA8AC0}.Release|x64.Build.0 = Release|Any CPU {FD4B7EFA-7B34-4544-AD4A-EA67F006A1E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FD4B7EFA-7B34-4544-AD4A-EA67F006A1E8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FD4B7EFA-7B34-4544-AD4A-EA67F006A1E8}.Debug|x64.ActiveCfg = Debug|Any CPU + {FD4B7EFA-7B34-4544-AD4A-EA67F006A1E8}.Debug|x64.Build.0 = Debug|Any CPU {FD4B7EFA-7B34-4544-AD4A-EA67F006A1E8}.Release|Any CPU.ActiveCfg = Release|Any CPU {FD4B7EFA-7B34-4544-AD4A-EA67F006A1E8}.Release|Any CPU.Build.0 = Release|Any CPU + {FD4B7EFA-7B34-4544-AD4A-EA67F006A1E8}.Release|x64.ActiveCfg = Release|Any CPU + {FD4B7EFA-7B34-4544-AD4A-EA67F006A1E8}.Release|x64.Build.0 = Release|Any CPU {AD328D2F-1AD0-414A-96A0-456820765C37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AD328D2F-1AD0-414A-96A0-456820765C37}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD328D2F-1AD0-414A-96A0-456820765C37}.Debug|x64.ActiveCfg = Debug|Any CPU + {AD328D2F-1AD0-414A-96A0-456820765C37}.Debug|x64.Build.0 = Debug|Any CPU {AD328D2F-1AD0-414A-96A0-456820765C37}.Release|Any CPU.ActiveCfg = Release|Any CPU {AD328D2F-1AD0-414A-96A0-456820765C37}.Release|Any CPU.Build.0 = Release|Any CPU + {AD328D2F-1AD0-414A-96A0-456820765C37}.Release|x64.ActiveCfg = Release|Any CPU + {AD328D2F-1AD0-414A-96A0-456820765C37}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Nodsoft.YumeChan.ConsoleRunner/Nodsoft.YumeChan.ConsoleRunner.csproj b/src/Nodsoft.YumeChan.ConsoleRunner/Nodsoft.YumeChan.ConsoleRunner.csproj index 3fb580b..98c4603 100644 --- a/src/Nodsoft.YumeChan.ConsoleRunner/Nodsoft.YumeChan.ConsoleRunner.csproj +++ b/src/Nodsoft.YumeChan.ConsoleRunner/Nodsoft.YumeChan.ConsoleRunner.csproj @@ -13,6 +13,10 @@ Git + + $(SolutionDir)\build + + all diff --git a/src/Nodsoft.YumeChan.ConsoleRunner/Program.cs b/src/Nodsoft.YumeChan.ConsoleRunner/Program.cs index 312d4ef..3433789 100644 --- a/src/Nodsoft.YumeChan.ConsoleRunner/Program.cs +++ b/src/Nodsoft.YumeChan.ConsoleRunner/Program.cs @@ -1,10 +1,14 @@ -using Nodsoft.YumeChan.Core; -using System.Threading.Tasks; +using System; +using static Nodsoft.YumeChan.Core.YumeCore; namespace Nodsoft.YumeChan.ConsoleRunner { static class Program { - static void Main(string[] args) => new YumeCore(new Logger()).RunBot(); + static void Main(string[] _) + { + Instance.Logger = new Logger(); + Instance.RunBot(); + } } } diff --git a/src/Nodsoft.YumeChan.Core/IPlugin.cs b/src/Nodsoft.YumeChan.Core/IPlugin.cs new file mode 100644 index 0000000..c5002a7 --- /dev/null +++ b/src/Nodsoft.YumeChan.Core/IPlugin.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections; +using System.Threading.Tasks; + +namespace Nodsoft.YumeChan.Core +{ + public interface IPlugin + { + public Version PluginVersion { get; } + + public string PluginDisplayName { get; } + + public bool PluginStealth { get; } + public bool PluginLoaded { get; } + + public Task LoadPlugin(); + public Task UnloadPlugin(); + } +} diff --git a/src/Nodsoft.YumeChan.Core/Modules/InternalModule.cs b/src/Nodsoft.YumeChan.Core/Modules/InternalModule.cs new file mode 100644 index 0000000..3d20fbf --- /dev/null +++ b/src/Nodsoft.YumeChan.Core/Modules/InternalModule.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace Nodsoft.YumeChan.Core.Modules +{ + internal class InternalModule : IPlugin + { + public Version PluginVersion { get; } = typeof(InternalModule).Assembly.GetName().Version; + + public string PluginDisplayName { get; } = "YumeCore Internals"; + + public bool PluginStealth { get; } = false; + + public bool PluginLoaded { get; set; } + + public Task LoadPlugin() + { + PluginLoaded = true; + return Task.CompletedTask; + } + + public Task UnloadPlugin() + { + PluginLoaded = false; + return Task.CompletedTask; + } + } +} diff --git a/src/Nodsoft.YumeChan.Core/Modules/Status/Status.cs b/src/Nodsoft.YumeChan.Core/Modules/Status/Status.cs new file mode 100644 index 0000000..18f3a45 --- /dev/null +++ b/src/Nodsoft.YumeChan.Core/Modules/Status/Status.cs @@ -0,0 +1,33 @@ +using Discord; +using Discord.Commands; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using System.ComponentModel.Design; + +using static Nodsoft.YumeChan.Core.YumeCore; + +namespace Nodsoft.YumeChan.Core.Modules.Status +{ + [Group("status")] + public class Status : ModuleBase + { + public static string MissingVersionSubstitute { get; } = "Unknown"; + + [Command] + public async Task DefaultAsync() + { + EmbedBuilder embed = new EmbedBuilder() + .WithTitle("Yume-Chan") + .WithDescription($"Status : {Instance.CoreState.ToString()}") + .AddField("Core", $"Version : {(CoreVersion != null ? CoreVersion.ToString() : MissingVersionSubstitute)}", true) + .AddField("Loaded Modules", $"Count : {(Instance.Modules != null ? Instance.Modules.Count.ToString() : "None")}", true); +#if DEBUG + embed.AddField("Debug", "Debug Build Active."); +#endif + + await ReplyAsync(embed: embed.Build()); + } + } +} diff --git a/src/Nodsoft.YumeChan.Core/ModulesLoader.cs b/src/Nodsoft.YumeChan.Core/ModulesLoader.cs new file mode 100644 index 0000000..d02f4df --- /dev/null +++ b/src/Nodsoft.YumeChan.Core/ModulesLoader.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Threading.Tasks; + +namespace Nodsoft.YumeChan.Core +{ + internal class ModulesLoader + { + internal List ModuleAssemblies { get; set; } + internal List ModuleFiles { get; set; } + + internal DirectoryInfo ModulesLoadDirectory { get; set; } + internal string ModulesLoadDiscriminator { get; set; } = string.Empty; + + public ModulesLoader(string modulesLoadDirectoryPath) + { + ModulesLoadDirectory = string.IsNullOrEmpty(modulesLoadDirectoryPath) + ? SetDefaultModulesDirectoryEnvironmentVariable() + : Directory.Exists(modulesLoadDirectoryPath) + ? new DirectoryInfo(modulesLoadDirectoryPath) + : Directory.CreateDirectory(modulesLoadDirectoryPath); + } + + internal DirectoryInfo SetDefaultModulesDirectoryEnvironmentVariable() + { + ModulesLoadDirectory = Directory.CreateDirectory(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "Modules" + Path.DirectorySeparatorChar); + + Environment.SetEnvironmentVariable("YumeChan.ModulesLocation", ModulesLoadDirectory.FullName); + return ModulesLoadDirectory; + } + + public Task LoadModuleAssemblies() + { + ModuleFiles = new List(ModulesLoadDirectory.GetFiles($"*{ModulesLoadDiscriminator}*.dll")); + + if (ModuleAssemblies is null) + { + ModuleAssemblies = new List(); + } + + foreach (FileInfo file in ModuleFiles) + { + ModuleAssemblies.Add(Assembly.LoadFile(file.ToString())); + } + + return Task.CompletedTask; + } + + public Task> LoadModuleManifests() + { + List manifestsList = new List(); + + foreach (Assembly assembly in ModuleAssemblies) + { + foreach (Type type in assembly.ExportedTypes) + { + manifestsList.Add(type as IPlugin); + } + } + return Task.FromResult(manifestsList); + } + } +} diff --git a/src/Nodsoft.YumeChan.Core/Nodsoft.YumeChan.Core.csproj b/src/Nodsoft.YumeChan.Core/Nodsoft.YumeChan.Core.csproj index ea943c5..315e8a9 100644 --- a/src/Nodsoft.YumeChan.Core/Nodsoft.YumeChan.Core.csproj +++ b/src/Nodsoft.YumeChan.Core/Nodsoft.YumeChan.Core.csproj @@ -2,7 +2,7 @@ netstandard2.1 - 0.1.3 + 0.2.0 DJ Daemonix Nodsoft ES YumeChan @@ -11,6 +11,8 @@ https://github.com/DJDaemonix/YumeChan Git false + 0.2.0.0 + 0.2.0.0 @@ -23,7 +25,9 @@ - + + ..\..\..\..\..\..\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.0.0-preview5-27626-15\ref\netcoreapp3.0\System.Runtime.Loader.dll + diff --git a/src/Nodsoft.YumeChan.Core/YumeCore.cs b/src/Nodsoft.YumeChan.Core/YumeCore.cs index ae6d6bf..0787aa1 100644 --- a/src/Nodsoft.YumeChan.Core/YumeCore.cs +++ b/src/Nodsoft.YumeChan.Core/YumeCore.cs @@ -7,7 +7,7 @@ using System.Reflection; using System.Threading.Tasks; -using Nodsoft.YumeChan.Modules; +using System.Collections.Generic; namespace Nodsoft.YumeChan.Core { @@ -16,39 +16,51 @@ public enum YumeCoreState Offline = 0, Online = 1, Starting = 2, Stopping = 3, Reloading = 4 } - public class YumeCore + public sealed class YumeCore { - //Properties + // Properties - public YumeCoreState CoreState { get; protected set; } + public static YumeCore Instance { get => lazyInstance.Value; } + + public YumeCoreState CoreState { get; private set; } + + public static Version CoreVersion { get; } = typeof(YumeCore).Assembly.GetName().Version; public DiscordSocketClient Client { get; set; } public CommandService Commands { get; set; } public IServiceProvider Services { get; set; } - // Remember to keep token private or to read it from an - // external source! In this case, we are reading the token - // from an environment variable. If you do not know how to set-up - // environment variables, you may find more information on the - // Internet or by using other methods such as reading from - // a configuration. + internal ModulesLoader ExternalModulesLoader { get; set; } = new ModulesLoader(string.Empty); + public List Modules { get; set; } + + /** + * Remember to keep token private or to read it from an + * external source! In this case, we are reading the token + * from an environment variable. If you do not know how to set- + * environment variables, you may find more information on + * Internet or by using other methods such as reading + * a configuration. + **/ private string BotToken { get; } = Environment.GetEnvironmentVariable("YumeChan.Token"); - public ILogger Logger { get; protected set; } + public ILogger Logger { get; set; } - //Constructors + // Fields + private static readonly Lazy lazyInstance = new Lazy(() => new YumeCore()); - public YumeCore(ILogger logger) => Logger = logger; + // Constructors + private YumeCore() { /* Use this ctor when assigning Logger berore running. */ } + static YumeCore() { /* Static ctor for Singleton implementation */ } - //Destructor + // Destructor ~YumeCore() { StopBotAsync().Wait(); } - //Methods + // Methods public void RunBot() { @@ -58,6 +70,11 @@ public void RunBot() public async Task StartBotAsync() { + if (Logger is null) + { + throw new ApplicationException(); + } + CoreState = YumeCoreState.Starting; Client = new DiscordSocketClient(); @@ -69,7 +86,7 @@ public async Task StartBotAsync() .BuildServiceProvider(); - //Event Subscriptions + // Event Subscriptions Client.Log += Logger.Log; Commands.Log += Logger.Log; @@ -109,11 +126,27 @@ public async Task RegisterCommandsAsync() { Client.MessageReceived += HandleCommandAsync; - ModulesIndex.CoreVersion = typeof(YumeCore).Assembly.GetName().Version; + Modules = new List { new Modules.InternalModule() }; // Add YumeCore internal commands + + await ExternalModulesLoader.LoadModuleAssemblies(); + Modules.AddRange(await ExternalModulesLoader.LoadModuleManifests()); - await Commands.AddModulesAsync(Assembly.GetEntryAssembly(), Services); //Add possible Commands from Entry Assembly (contextual) - await Commands.AddModulesAsync(typeof(YumeCore).Assembly, Services); //Add Local Commands (if any) - await Commands.AddModulesAsync(typeof(ModulesIndex).Assembly, Services); //Add Commands from Nodsoft.YumeChan.Modules + List modulesCopy = new List(Modules); + + foreach (IPlugin module in modulesCopy) + { + if (module is null) + { + Modules.Remove(module); + } + else + { + await module.LoadPlugin(); + await Commands.AddModulesAsync(module.GetType().Assembly, Services); + } + } + + await Commands.AddModulesAsync(Assembly.GetEntryAssembly(), Services); // Add possible Commands from Entry Assembly (contextual) } public Task ReleaseCommands() @@ -137,9 +170,7 @@ public async Task ReloadCommandsAsync() private async Task HandleCommandAsync(SocketMessage arg) { - SocketUserMessage message = arg as SocketUserMessage; - - if (message != null && !message.Author.IsBot) + if (arg is SocketUserMessage message && !message.Author.IsBot) { int argPosition = 0; @@ -155,5 +186,8 @@ private async Task HandleCommandAsync(SocketMessage arg) } } } + + // Fluent Assignments + public void SetLogger(ILogger logger) => Logger = logger; } } diff --git a/src/Nodsoft.YumeChan.Modules/ModuleProperties.cs b/src/Nodsoft.YumeChan.Modules/ModuleProperties.cs new file mode 100644 index 0000000..efda899 --- /dev/null +++ b/src/Nodsoft.YumeChan.Modules/ModuleProperties.cs @@ -0,0 +1,29 @@ +using Nodsoft.YumeChan.Core; +using System; +using System.Threading.Tasks; + +namespace Nodsoft.YumeChan.Modules +{ + public class ModuleProperties : IPlugin + { + public Version PluginVersion { get; } = typeof(ModuleProperties).Assembly.GetName().Version; + + public string PluginDisplayName { get; } = "Yume-Chan Essentials"; + + public bool PluginStealth { get; } = false; + + public bool PluginLoaded { get; set; } + + public Task LoadPlugin() + { + PluginLoaded = true; + return Task.CompletedTask; + } + + public Task UnloadPlugin() + { + PluginLoaded = false; + return Task.CompletedTask; + } + } +} diff --git a/src/Nodsoft.YumeChan.Modules/ModulesIndex.cs b/src/Nodsoft.YumeChan.Modules/ModulesIndex.cs deleted file mode 100644 index b16e427..0000000 --- a/src/Nodsoft.YumeChan.Modules/ModulesIndex.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Nodsoft.YumeChan.Modules -{ - public static class ModulesIndex - { - public static Version CoreVersion { get; set; } - public static Version ModulesVersion { get; } = typeof(ModulesIndex).Assembly.GetName().Version; - - public static string MissingVersionSubstitute { get; } = "Unknown"; - } -} diff --git a/src/Nodsoft.YumeChan.Modules/Nodsoft.YumeChan.Modules.csproj b/src/Nodsoft.YumeChan.Modules/Nodsoft.YumeChan.Modules.csproj index f7faafc..70cfadb 100644 --- a/src/Nodsoft.YumeChan.Modules/Nodsoft.YumeChan.Modules.csproj +++ b/src/Nodsoft.YumeChan.Modules/Nodsoft.YumeChan.Modules.csproj @@ -1,25 +1,37 @@  - - netstandard2.1 - 0.1.3 - DJ Daemonix - Nodsoft ES - YumeChan Modules - GNU LGPLv3 - en - - https://github.com/DJDaemonix/YumeChan - Git - + + netstandard2.1 + $(BIN_PATH)\Modules\ + 0.2.0 + DJ Daemonix + Nodsoft ES + YumeChan Modules + GNU LGPLv3 + en + + https://github.com/DJDaemonix/YumeChan + Git + AnyCPU + 0.2.0.0 + 0.2.0.0 + - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + + $(SolutionDir)\build\Modules + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + diff --git a/src/Nodsoft.YumeChan.Modules/Status/Status.cs b/src/Nodsoft.YumeChan.Modules/Status/Status.cs deleted file mode 100644 index b9d1aae..0000000 --- a/src/Nodsoft.YumeChan.Modules/Status/Status.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Discord; -using Discord.Commands; -using System.Threading.Tasks; -using static Nodsoft.YumeChan.Modules.ModulesIndex; - -namespace Nodsoft.YumeChan.Modules.Status -{ - [Group("status")] - public class Status : ModuleBase - { - [Command] - public async Task DefaultAsync() - { - EmbedBuilder embed = new EmbedBuilder() - .WithTitle("Yume-Chan") - .WithDescription("Status : Online") - .AddField("Core", $"Version : {(CoreVersion != null ? CoreVersion.ToString() : MissingVersionSubstitute)}", true) - .AddField("Modules", $"Version : {ModulesVersion}", true); -#if DEBUG - embed.AddField("Debug", "Debug Build Active."); -#endif - - await ReplyAsync(embed: embed.Build()); - } - } -} diff --git a/src/Nodsoft.YumeChan.NetRunner/Services.cs b/src/Nodsoft.YumeChan.NetRunner/Services.cs index fe69d9e..c82ff4d 100644 --- a/src/Nodsoft.YumeChan.NetRunner/Services.cs +++ b/src/Nodsoft.YumeChan.NetRunner/Services.cs @@ -8,6 +8,6 @@ internal static class Services { internal static IServiceProvider AppServiceProvider { get; set; } internal static Logger LoggerService { get; set; } = new Logger(); - internal static YumeCoreSingleton BotService { get; set; } = new YumeCoreSingleton(LoggerService); + internal static YumeCore BotService { get; set; } = YumeCore.Instance; } } \ No newline at end of file diff --git a/src/Nodsoft.YumeChan.NetRunner/Startup.cs b/src/Nodsoft.YumeChan.NetRunner/Startup.cs index a95ba55..74cf038 100644 --- a/src/Nodsoft.YumeChan.NetRunner/Startup.cs +++ b/src/Nodsoft.YumeChan.NetRunner/Startup.cs @@ -18,8 +18,11 @@ public static void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); services.AddServerSideBlazor(); - services.AddSingleton(BotService); + + BotService.Logger = LoggerService; + services.AddSingleton(LoggerService); + services.AddSingleton(BotService); AppServiceProvider = services.BuildServiceProvider(); } diff --git a/src/Nodsoft.YumeChan.NetRunner/YumeCoreSingleton.cs b/src/Nodsoft.YumeChan.NetRunner/YumeCoreSingleton.cs deleted file mode 100644 index 5cdbadb..0000000 --- a/src/Nodsoft.YumeChan.NetRunner/YumeCoreSingleton.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using Nodsoft.YumeChan.Core; - -namespace Nodsoft.YumeChan.NetRunner -{ - public sealed class YumeCoreSingleton : YumeCore - { - private static readonly Lazy lazy = new Lazy(() => new YumeCoreSingleton()); - public static YumeCoreSingleton Instance { get => lazy.Value; } - - public YumeCoreSingleton() : base(new Logger()) { /* Calls the base class with local Logger */ } - public YumeCoreSingleton(ILogger logger) : base(logger) { /* Calls the base class with specified logger */ } - } -} \ No newline at end of file From 5b7b8bf22ceb4d568907b3189618c9e826c2045b Mon Sep 17 00:00:00 2001 From: DJ Daemonix Date: Tue, 2 Jul 2019 17:51:19 +0200 Subject: [PATCH 3/5] Complete Plugin System Plugin System is now ready for NetRunner Implementation, and has its manifest Interface Segregated from YumeCore, so to not bloat any Plugin development. --- YumeChan.sln | 13 ++++ .../Nodsoft.YumeChan.ConsoleRunner.csproj | 4 +- src/Nodsoft.YumeChan.Core/IPlugin.cs | 19 ----- .../Modules/InternalModule.cs | 7 +- src/Nodsoft.YumeChan.Core/ModulesLoader.cs | 78 ++++++++++++------- .../Nodsoft.YumeChan.Core.csproj | 52 ++++++------- src/Nodsoft.YumeChan.Core/Utilities.cs | 22 ++++++ src/Nodsoft.YumeChan.Core/YumeCore.cs | 6 +- .../ModuleProperties.cs | 4 +- .../Nodsoft.YumeChan.Modules.csproj | 6 +- .../Controls/YumeCoreController.cs | 6 +- .../Nodsoft.YumeChan.NetRunner.csproj | 52 +++++++------ src/Nodsoft.YumeChan.PluginBase/IPlugin.cs | 18 +++++ .../Nodsoft.YumeChan.PluginBase.csproj | 12 +++ 14 files changed, 188 insertions(+), 111 deletions(-) delete mode 100644 src/Nodsoft.YumeChan.Core/IPlugin.cs create mode 100644 src/Nodsoft.YumeChan.Core/Utilities.cs create mode 100644 src/Nodsoft.YumeChan.PluginBase/IPlugin.cs create mode 100644 src/Nodsoft.YumeChan.PluginBase/Nodsoft.YumeChan.PluginBase.csproj diff --git a/YumeChan.sln b/YumeChan.sln index 1f2a459..b90fa70 100644 --- a/YumeChan.sln +++ b/YumeChan.sln @@ -6,11 +6,16 @@ MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nodsoft.YumeChan.ConsoleRunner", "src\Nodsoft.YumeChan.ConsoleRunner\Nodsoft.YumeChan.ConsoleRunner.csproj", "{B4E6E6B5-B495-4668-BB0D-1107B457C420}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nodsoft.YumeChan.Core", "src\Nodsoft.YumeChan.Core\Nodsoft.YumeChan.Core.csproj", "{58155AE6-D0DF-45E3-9B38-64ED0ACA8AC0}" + ProjectSection(ProjectDependencies) = postProject + {FD4B7EFA-7B34-4544-AD4A-EA67F006A1E8} = {FD4B7EFA-7B34-4544-AD4A-EA67F006A1E8} + EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nodsoft.YumeChan.Modules", "src\Nodsoft.YumeChan.Modules\Nodsoft.YumeChan.Modules.csproj", "{FD4B7EFA-7B34-4544-AD4A-EA67F006A1E8}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nodsoft.YumeChan.NetRunner", "src\Nodsoft.YumeChan.NetRunner\Nodsoft.YumeChan.NetRunner.csproj", "{AD328D2F-1AD0-414A-96A0-456820765C37}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nodsoft.YumeChan.PluginBase", "src\Nodsoft.YumeChan.PluginBase\Nodsoft.YumeChan.PluginBase.csproj", "{BA3AB42C-6875-4F32-9476-89EB8432716C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -51,6 +56,14 @@ Global {AD328D2F-1AD0-414A-96A0-456820765C37}.Release|Any CPU.Build.0 = Release|Any CPU {AD328D2F-1AD0-414A-96A0-456820765C37}.Release|x64.ActiveCfg = Release|Any CPU {AD328D2F-1AD0-414A-96A0-456820765C37}.Release|x64.Build.0 = Release|Any CPU + {BA3AB42C-6875-4F32-9476-89EB8432716C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BA3AB42C-6875-4F32-9476-89EB8432716C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA3AB42C-6875-4F32-9476-89EB8432716C}.Debug|x64.ActiveCfg = Debug|Any CPU + {BA3AB42C-6875-4F32-9476-89EB8432716C}.Debug|x64.Build.0 = Debug|Any CPU + {BA3AB42C-6875-4F32-9476-89EB8432716C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BA3AB42C-6875-4F32-9476-89EB8432716C}.Release|Any CPU.Build.0 = Release|Any CPU + {BA3AB42C-6875-4F32-9476-89EB8432716C}.Release|x64.ActiveCfg = Release|Any CPU + {BA3AB42C-6875-4F32-9476-89EB8432716C}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Nodsoft.YumeChan.ConsoleRunner/Nodsoft.YumeChan.ConsoleRunner.csproj b/src/Nodsoft.YumeChan.ConsoleRunner/Nodsoft.YumeChan.ConsoleRunner.csproj index 98c4603..59b36e1 100644 --- a/src/Nodsoft.YumeChan.ConsoleRunner/Nodsoft.YumeChan.ConsoleRunner.csproj +++ b/src/Nodsoft.YumeChan.ConsoleRunner/Nodsoft.YumeChan.ConsoleRunner.csproj @@ -3,7 +3,7 @@ Exe netcoreapp3.0 - 8.0 + preview 0.1.3 DJ Daemonix Nodsoft ES @@ -14,7 +14,7 @@ - $(SolutionDir)\build + $(SolutionDir)build diff --git a/src/Nodsoft.YumeChan.Core/IPlugin.cs b/src/Nodsoft.YumeChan.Core/IPlugin.cs deleted file mode 100644 index c5002a7..0000000 --- a/src/Nodsoft.YumeChan.Core/IPlugin.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections; -using System.Threading.Tasks; - -namespace Nodsoft.YumeChan.Core -{ - public interface IPlugin - { - public Version PluginVersion { get; } - - public string PluginDisplayName { get; } - - public bool PluginStealth { get; } - public bool PluginLoaded { get; } - - public Task LoadPlugin(); - public Task UnloadPlugin(); - } -} diff --git a/src/Nodsoft.YumeChan.Core/Modules/InternalModule.cs b/src/Nodsoft.YumeChan.Core/Modules/InternalModule.cs index 3d20fbf..48e5d4d 100644 --- a/src/Nodsoft.YumeChan.Core/Modules/InternalModule.cs +++ b/src/Nodsoft.YumeChan.Core/Modules/InternalModule.cs @@ -1,6 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Text; +using Nodsoft.YumeChan.PluginBase; +using System; using System.Threading.Tasks; namespace Nodsoft.YumeChan.Core.Modules @@ -13,7 +12,7 @@ internal class InternalModule : IPlugin public bool PluginStealth { get; } = false; - public bool PluginLoaded { get; set; } + public bool PluginLoaded { get; internal set; } public Task LoadPlugin() { diff --git a/src/Nodsoft.YumeChan.Core/ModulesLoader.cs b/src/Nodsoft.YumeChan.Core/ModulesLoader.cs index d02f4df..ac413f9 100644 --- a/src/Nodsoft.YumeChan.Core/ModulesLoader.cs +++ b/src/Nodsoft.YumeChan.Core/ModulesLoader.cs @@ -1,48 +1,55 @@ -using System; +using Nodsoft.YumeChan.PluginBase; +using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Threading.Tasks; +using System.Linq; namespace Nodsoft.YumeChan.Core { internal class ModulesLoader { - internal List ModuleAssemblies { get; set; } - internal List ModuleFiles { get; set; } + internal List PluginAssemblies { get; set; } + internal List PluginFiles { get; set; } + internal List PluginManifests { get; set; } - internal DirectoryInfo ModulesLoadDirectory { get; set; } - internal string ModulesLoadDiscriminator { get; set; } = string.Empty; + internal DirectoryInfo PluginsLoadDirectory { get; set; } + internal string PluginsLoadDiscriminator { get; set; } = string.Empty; - public ModulesLoader(string modulesLoadDirectoryPath) + public ModulesLoader(string pluginsLoadDirectoryPath) { - ModulesLoadDirectory = string.IsNullOrEmpty(modulesLoadDirectoryPath) - ? SetDefaultModulesDirectoryEnvironmentVariable() - : Directory.Exists(modulesLoadDirectoryPath) - ? new DirectoryInfo(modulesLoadDirectoryPath) - : Directory.CreateDirectory(modulesLoadDirectoryPath); + PluginsLoadDirectory = string.IsNullOrEmpty(pluginsLoadDirectoryPath) + ? SetDefaultPluginsDirectoryEnvironmentVariable() + : Directory.Exists(pluginsLoadDirectoryPath) + ? new DirectoryInfo(pluginsLoadDirectoryPath) + : Directory.CreateDirectory(pluginsLoadDirectoryPath); } - internal DirectoryInfo SetDefaultModulesDirectoryEnvironmentVariable() + internal DirectoryInfo SetDefaultPluginsDirectoryEnvironmentVariable() { - ModulesLoadDirectory = Directory.CreateDirectory(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "Modules" + Path.DirectorySeparatorChar); + FileInfo file = new FileInfo(Assembly.GetExecutingAssembly().Location); + PluginsLoadDirectory = Directory.CreateDirectory(file.DirectoryName + Path.DirectorySeparatorChar + "Modules" + Path.DirectorySeparatorChar); - Environment.SetEnvironmentVariable("YumeChan.ModulesLocation", ModulesLoadDirectory.FullName); - return ModulesLoadDirectory; + Environment.SetEnvironmentVariable("YumeChan.PluginsLocation", PluginsLoadDirectory.FullName); + return PluginsLoadDirectory; } public Task LoadModuleAssemblies() { - ModuleFiles = new List(ModulesLoadDirectory.GetFiles($"*{ModulesLoadDiscriminator}*.dll")); + PluginFiles = new List(PluginsLoadDirectory.GetFiles($"*{PluginsLoadDiscriminator}*.dll")); - if (ModuleAssemblies is null) + if (PluginAssemblies is null) { - ModuleAssemblies = new List(); + PluginAssemblies = new List(); } - foreach (FileInfo file in ModuleFiles) + foreach (FileInfo file in PluginFiles) { - ModuleAssemblies.Add(Assembly.LoadFile(file.ToString())); + if (file !is null || file.Name != "Nodsoft.YumeChan.PluginBase.dll") + { + PluginAssemblies.Add(Assembly.LoadFile(file.ToString())); + } } return Task.CompletedTask; @@ -51,15 +58,34 @@ public Task LoadModuleAssemblies() public Task> LoadModuleManifests() { List manifestsList = new List(); - - foreach (Assembly assembly in ModuleAssemblies) + List pluginTypes = new List(); + foreach (Assembly assembly in PluginAssemblies) { - foreach (Type type in assembly.ExportedTypes) - { - manifestsList.Add(type as IPlugin); - } + pluginTypes.AddRange + ( + from Type t in assembly.ExportedTypes + where t.ImplementsInterface(typeof(IPlugin)) + select t + ); + } + foreach (Type pluginType in pluginTypes) + { + manifestsList.Add(InstantiateManifest(pluginType).GetAwaiter().GetResult()); } + return Task.FromResult(manifestsList); } + + internal Task InstantiateManifest(Type typePlugin) + { + object obj = Activator.CreateInstance(typePlugin); + IPlugin pluginManifest = obj as IPlugin; + + if (pluginManifest is null) + { + throw new InvalidCastException(); + } + return Task.FromResult(pluginManifest); + } } } diff --git a/src/Nodsoft.YumeChan.Core/Nodsoft.YumeChan.Core.csproj b/src/Nodsoft.YumeChan.Core/Nodsoft.YumeChan.Core.csproj index 315e8a9..a61080c 100644 --- a/src/Nodsoft.YumeChan.Core/Nodsoft.YumeChan.Core.csproj +++ b/src/Nodsoft.YumeChan.Core/Nodsoft.YumeChan.Core.csproj @@ -1,33 +1,31 @@  - - netstandard2.1 - 0.2.0 - DJ Daemonix - Nodsoft ES - YumeChan - GNU GPLv3 - en - https://github.com/DJDaemonix/YumeChan - Git - false - 0.2.0.0 - 0.2.0.0 - + + netstandard2.1 + 0.2.0 + DJ Daemonix + Nodsoft ES + YumeChan + GNU GPLv3 + en + https://github.com/DJDaemonix/YumeChan + Git + false + 0.2.0.0 + 0.2.0.0 + - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + - - - ..\..\..\..\..\..\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.0.0-preview5-27626-15\ref\netcoreapp3.0\System.Runtime.Loader.dll - - + + + diff --git a/src/Nodsoft.YumeChan.Core/Utilities.cs b/src/Nodsoft.YumeChan.Core/Utilities.cs new file mode 100644 index 0000000..2b6f986 --- /dev/null +++ b/src/Nodsoft.YumeChan.Core/Utilities.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Nodsoft.YumeChan.Core +{ + public static class Utilities + { + public static bool ImplementsInterface(this Type type, Type interfaceType) + { + Type[] intf = type.GetInterfaces(); + foreach (Type t in intf) + { + if (t == interfaceType) + { + return true; + } + } + return false; + } + } +} diff --git a/src/Nodsoft.YumeChan.Core/YumeCore.cs b/src/Nodsoft.YumeChan.Core/YumeCore.cs index 0787aa1..171a452 100644 --- a/src/Nodsoft.YumeChan.Core/YumeCore.cs +++ b/src/Nodsoft.YumeChan.Core/YumeCore.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using System.Collections.Generic; +using Nodsoft.YumeChan.PluginBase; namespace Nodsoft.YumeChan.Core { @@ -30,7 +31,7 @@ public sealed class YumeCore public CommandService Commands { get; set; } public IServiceProvider Services { get; set; } - internal ModulesLoader ExternalModulesLoader { get; set; } = new ModulesLoader(string.Empty); + internal ModulesLoader ExternalModulesLoader { get; set; } public List Modules { get; set; } /** @@ -124,6 +125,8 @@ public async Task RestartBotAsync() public async Task RegisterCommandsAsync() { + ExternalModulesLoader = new ModulesLoader(string.Empty); + Client.MessageReceived += HandleCommandAsync; Modules = new List { new Modules.InternalModule() }; // Add YumeCore internal commands @@ -151,6 +154,7 @@ public async Task RegisterCommandsAsync() public Task ReleaseCommands() { + Client.MessageReceived -= HandleCommandAsync; Commands = new CommandService(); Commands.Log += Logger.Log; diff --git a/src/Nodsoft.YumeChan.Modules/ModuleProperties.cs b/src/Nodsoft.YumeChan.Modules/ModuleProperties.cs index efda899..2882573 100644 --- a/src/Nodsoft.YumeChan.Modules/ModuleProperties.cs +++ b/src/Nodsoft.YumeChan.Modules/ModuleProperties.cs @@ -1,4 +1,4 @@ -using Nodsoft.YumeChan.Core; +using Nodsoft.YumeChan.PluginBase; using System; using System.Threading.Tasks; @@ -12,7 +12,7 @@ public class ModuleProperties : IPlugin public bool PluginStealth { get; } = false; - public bool PluginLoaded { get; set; } + public bool PluginLoaded { get; internal set; } public Task LoadPlugin() { diff --git a/src/Nodsoft.YumeChan.Modules/Nodsoft.YumeChan.Modules.csproj b/src/Nodsoft.YumeChan.Modules/Nodsoft.YumeChan.Modules.csproj index 70cfadb..a734f59 100644 --- a/src/Nodsoft.YumeChan.Modules/Nodsoft.YumeChan.Modules.csproj +++ b/src/Nodsoft.YumeChan.Modules/Nodsoft.YumeChan.Modules.csproj @@ -18,7 +18,7 @@ - $(SolutionDir)\build\Modules + $(SolutionDir)build\Modules @@ -29,9 +29,9 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + - + diff --git a/src/Nodsoft.YumeChan.NetRunner/Controls/YumeCoreController.cs b/src/Nodsoft.YumeChan.NetRunner/Controls/YumeCoreController.cs index 5341c8c..082c658 100644 --- a/src/Nodsoft.YumeChan.NetRunner/Controls/YumeCoreController.cs +++ b/src/Nodsoft.YumeChan.NetRunner/Controls/YumeCoreController.cs @@ -8,8 +8,8 @@ namespace Nodsoft.YumeChan.NetRunner.Controls { - public static class YumeCoreController - { + public static class YumeCoreController + { public static Task DisplayStatusAlert() { switch (BotService.CoreState) @@ -60,5 +60,5 @@ public static async Task ReloadModulesButton() await BotService.ReloadCommandsAsync(); } } - } + } } \ No newline at end of file diff --git a/src/Nodsoft.YumeChan.NetRunner/Nodsoft.YumeChan.NetRunner.csproj b/src/Nodsoft.YumeChan.NetRunner/Nodsoft.YumeChan.NetRunner.csproj index 86958c1..375bbf4 100644 --- a/src/Nodsoft.YumeChan.NetRunner/Nodsoft.YumeChan.NetRunner.csproj +++ b/src/Nodsoft.YumeChan.NetRunner/Nodsoft.YumeChan.NetRunner.csproj @@ -1,30 +1,34 @@  - - netcoreapp3.0 - preview - 0.1.3 - DJ Daemonix - Nodsoft ES - YumeChan - GNU GPLv3 - Anglais - Nodsoft.YumeChan.NetRunner.Program - https://github.com/DJDaemonix/YumeChan - Git - + + netcoreapp3.0 + preview + 0.1.3 + DJ Daemonix + Nodsoft ES + YumeChan + GNU GPLv3 + Anglais + Nodsoft.YumeChan.NetRunner.Program + https://github.com/DJDaemonix/YumeChan + Git + - - - + + $(SolutionDir)build + + + + + - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/src/Nodsoft.YumeChan.PluginBase/IPlugin.cs b/src/Nodsoft.YumeChan.PluginBase/IPlugin.cs new file mode 100644 index 0000000..eae9350 --- /dev/null +++ b/src/Nodsoft.YumeChan.PluginBase/IPlugin.cs @@ -0,0 +1,18 @@ +using System; +using System.Threading.Tasks; + +namespace Nodsoft.YumeChan.PluginBase +{ + public interface IPlugin + { + Version PluginVersion { get; } + + string PluginDisplayName { get; } + + bool PluginStealth { get; } + bool PluginLoaded { get; } + + Task LoadPlugin(); + Task UnloadPlugin(); + } +} diff --git a/src/Nodsoft.YumeChan.PluginBase/Nodsoft.YumeChan.PluginBase.csproj b/src/Nodsoft.YumeChan.PluginBase/Nodsoft.YumeChan.PluginBase.csproj new file mode 100644 index 0000000..c516deb --- /dev/null +++ b/src/Nodsoft.YumeChan.PluginBase/Nodsoft.YumeChan.PluginBase.csproj @@ -0,0 +1,12 @@ + + + + netstandard2.0 + default + 0.1 + DJ Daemonix + Nodsoft ES + YumeChan PluginBase + + + From 6df64a6d9c3da9b380dae2d8ed9c96790a433e9b Mon Sep 17 00:00:00 2001 From: DJ Daemonix Date: Tue, 2 Jul 2019 18:15:53 +0200 Subject: [PATCH 4/5] Implement "==status plugins" No stealth load yet --- .../Modules/Status/Status.cs | 22 +++++++++++++++++-- src/Nodsoft.YumeChan.Core/YumeCore.cs | 10 ++++----- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/Nodsoft.YumeChan.Core/Modules/Status/Status.cs b/src/Nodsoft.YumeChan.Core/Modules/Status/Status.cs index 18f3a45..8f4aa07 100644 --- a/src/Nodsoft.YumeChan.Core/Modules/Status/Status.cs +++ b/src/Nodsoft.YumeChan.Core/Modules/Status/Status.cs @@ -7,6 +7,7 @@ using System.ComponentModel.Design; using static Nodsoft.YumeChan.Core.YumeCore; +using Nodsoft.YumeChan.PluginBase; namespace Nodsoft.YumeChan.Core.Modules.Status { @@ -16,18 +17,35 @@ public class Status : ModuleBase public static string MissingVersionSubstitute { get; } = "Unknown"; [Command] - public async Task DefaultAsync() + public async Task CoreStatusAsync() { EmbedBuilder embed = new EmbedBuilder() .WithTitle("Yume-Chan") .WithDescription($"Status : {Instance.CoreState.ToString()}") .AddField("Core", $"Version : {(CoreVersion != null ? CoreVersion.ToString() : MissingVersionSubstitute)}", true) - .AddField("Loaded Modules", $"Count : {(Instance.Modules != null ? Instance.Modules.Count.ToString() : "None")}", true); + .AddField("Loaded Modules", $"Count : {(Instance.Plugins != null ? Instance.Plugins.Count.ToString() : "None")}", true); #if DEBUG embed.AddField("Debug", "Debug Build Active."); #endif await ReplyAsync(embed: embed.Build()); } + + [Command("plugins")] + public async Task PluginsStatusAsync() + { + EmbedBuilder embed = new EmbedBuilder() + .WithTitle("Plugins") + .WithDescription($"Currently Loaded : **{Instance.Plugins.Count}** Plugins."); + + foreach (IPlugin pluginManifest in Instance.Plugins) + { + embed.AddField(pluginManifest.PluginDisplayName, + $"Version : {(pluginManifest.PluginVersion != null ? pluginManifest.PluginVersion.ToString() : MissingVersionSubstitute)}\n" + + $"Loaded : {(pluginManifest.PluginLoaded ? "Yes" : "No")}", true); + } + + await ReplyAsync(embed: embed.Build()); + } } } diff --git a/src/Nodsoft.YumeChan.Core/YumeCore.cs b/src/Nodsoft.YumeChan.Core/YumeCore.cs index 171a452..c430b88 100644 --- a/src/Nodsoft.YumeChan.Core/YumeCore.cs +++ b/src/Nodsoft.YumeChan.Core/YumeCore.cs @@ -32,7 +32,7 @@ public sealed class YumeCore public IServiceProvider Services { get; set; } internal ModulesLoader ExternalModulesLoader { get; set; } - public List Modules { get; set; } + public List Plugins { get; set; } /** * Remember to keep token private or to read it from an @@ -129,18 +129,18 @@ public async Task RegisterCommandsAsync() Client.MessageReceived += HandleCommandAsync; - Modules = new List { new Modules.InternalModule() }; // Add YumeCore internal commands + Plugins = new List { new Modules.InternalModule() }; // Add YumeCore internal commands await ExternalModulesLoader.LoadModuleAssemblies(); - Modules.AddRange(await ExternalModulesLoader.LoadModuleManifests()); + Plugins.AddRange(await ExternalModulesLoader.LoadModuleManifests()); - List modulesCopy = new List(Modules); + List modulesCopy = new List(Plugins); foreach (IPlugin module in modulesCopy) { if (module is null) { - Modules.Remove(module); + Plugins.Remove(module); } else { From 906121c447a5995a4d26b1a40ae6709909d07672 Mon Sep 17 00:00:00 2001 From: DJ Daemonix Date: Wed, 10 Jul 2019 19:47:23 +0200 Subject: [PATCH 5/5] Renaming in Code --- .../Modules/{InternalModule.cs => InternalPlugin.cs} | 4 ++-- src/Nodsoft.YumeChan.Core/Modules/Status/Status.cs | 4 ---- src/Nodsoft.YumeChan.Core/ModulesLoader.cs | 2 +- src/Nodsoft.YumeChan.Core/YumeCore.cs | 2 +- 4 files changed, 4 insertions(+), 8 deletions(-) rename src/Nodsoft.YumeChan.Core/Modules/{InternalModule.cs => InternalPlugin.cs} (82%) diff --git a/src/Nodsoft.YumeChan.Core/Modules/InternalModule.cs b/src/Nodsoft.YumeChan.Core/Modules/InternalPlugin.cs similarity index 82% rename from src/Nodsoft.YumeChan.Core/Modules/InternalModule.cs rename to src/Nodsoft.YumeChan.Core/Modules/InternalPlugin.cs index 48e5d4d..15d4672 100644 --- a/src/Nodsoft.YumeChan.Core/Modules/InternalModule.cs +++ b/src/Nodsoft.YumeChan.Core/Modules/InternalPlugin.cs @@ -4,9 +4,9 @@ namespace Nodsoft.YumeChan.Core.Modules { - internal class InternalModule : IPlugin + internal class InternalPlugin : IPlugin { - public Version PluginVersion { get; } = typeof(InternalModule).Assembly.GetName().Version; + public Version PluginVersion { get; } = typeof(InternalPlugin).Assembly.GetName().Version; public string PluginDisplayName { get; } = "YumeCore Internals"; diff --git a/src/Nodsoft.YumeChan.Core/Modules/Status/Status.cs b/src/Nodsoft.YumeChan.Core/Modules/Status/Status.cs index 8f4aa07..9e5f373 100644 --- a/src/Nodsoft.YumeChan.Core/Modules/Status/Status.cs +++ b/src/Nodsoft.YumeChan.Core/Modules/Status/Status.cs @@ -1,10 +1,6 @@ using Discord; using Discord.Commands; -using System; -using System.Collections.Generic; -using System.Text; using System.Threading.Tasks; -using System.ComponentModel.Design; using static Nodsoft.YumeChan.Core.YumeCore; using Nodsoft.YumeChan.PluginBase; diff --git a/src/Nodsoft.YumeChan.Core/ModulesLoader.cs b/src/Nodsoft.YumeChan.Core/ModulesLoader.cs index ac413f9..b664b9d 100644 --- a/src/Nodsoft.YumeChan.Core/ModulesLoader.cs +++ b/src/Nodsoft.YumeChan.Core/ModulesLoader.cs @@ -76,7 +76,7 @@ select t return Task.FromResult(manifestsList); } - internal Task InstantiateManifest(Type typePlugin) + internal static Task InstantiateManifest(Type typePlugin) { object obj = Activator.CreateInstance(typePlugin); IPlugin pluginManifest = obj as IPlugin; diff --git a/src/Nodsoft.YumeChan.Core/YumeCore.cs b/src/Nodsoft.YumeChan.Core/YumeCore.cs index c430b88..84ec594 100644 --- a/src/Nodsoft.YumeChan.Core/YumeCore.cs +++ b/src/Nodsoft.YumeChan.Core/YumeCore.cs @@ -129,7 +129,7 @@ public async Task RegisterCommandsAsync() Client.MessageReceived += HandleCommandAsync; - Plugins = new List { new Modules.InternalModule() }; // Add YumeCore internal commands + Plugins = new List { new Modules.InternalPlugin() }; // Add YumeCore internal commands await ExternalModulesLoader.LoadModuleAssemblies(); Plugins.AddRange(await ExternalModulesLoader.LoadModuleManifests());