diff --git a/DiscordBot/Bot/Actions/AddPlugin.cs b/DiscordBot/Bot/Actions/AddPlugin.cs index 0ad9fc5..dbebc65 100644 --- a/DiscordBot/Bot/Actions/AddPlugin.cs +++ b/DiscordBot/Bot/Actions/AddPlugin.cs @@ -49,7 +49,7 @@ namespace DiscordBot.Bot.Actions } PluginInfo pluginInfo = new PluginInfo(args[^1], new(1, 0, 0), [], false, true, args.Contains("-enabled")); - Application.CurrentApplication.Logger.Log("Adding plugin: " + args[^1]); + Application.Logger.Log("Adding plugin: " + args[^1]); await Application.CurrentApplication.PluginManager.AppendPluginToDatabase(pluginInfo); } } diff --git a/DiscordBot/Bot/Actions/Exit.cs b/DiscordBot/Bot/Actions/Exit.cs index 4b9c1e3..0b8e361 100644 --- a/DiscordBot/Bot/Actions/Exit.cs +++ b/DiscordBot/Bot/Actions/Exit.cs @@ -26,7 +26,7 @@ public class Exit: ICommandAction { if (args is null || args.Length == 0) { - Application.CurrentApplication.Logger.Log("Exiting...", this, LogType.Warning); + Application.Logger.Log("Exiting...", this, LogType.Warning); await Application.CurrentApplication.ApplicationEnvironmentVariables.SaveToFile(); Environment.Exit(0); } @@ -42,7 +42,7 @@ public class Exit: ICommandAction case "-f": case "force": - Application.CurrentApplication.Logger.Log("Exiting (FORCE)...", this, LogType.Warning); + Application.Logger.Log("Exiting (FORCE)...", this, LogType.Warning); Environment.Exit(0); break; diff --git a/DiscordBot/Bot/Actions/Extra/PluginMethods.cs b/DiscordBot/Bot/Actions/Extra/PluginMethods.cs index dacb43a..936f387 100644 --- a/DiscordBot/Bot/Actions/Extra/PluginMethods.cs +++ b/DiscordBot/Bot/Actions/Extra/PluginMethods.cs @@ -86,7 +86,7 @@ internal static class PluginMethods }catch(Exception ex) { - Application.CurrentApplication.Logger.LogException(ex, typeof(PluginMethods), false); + Application.Logger.LogException(ex, typeof(PluginMethods), false); } finally { await Application.CurrentApplication.InternalActionManager.Initialize(); @@ -226,12 +226,12 @@ internal static class PluginMethods { if (data.IsSuccess) { - Application.CurrentApplication.Logger.Log("Successfully loaded command : " + data.PluginName, LogType.Info, "\t\t > {Message}"); + Application.Logger.Log("Successfully loaded command : " + data.PluginName, LogType.Info, "\t\t > {Message}"); } else { - Application.CurrentApplication.Logger.Log("Failed to load command : " + data.PluginName + " because " + data.ErrorMessage, + Application.Logger.Log("Failed to load command : " + data.PluginName + " because " + data.ErrorMessage, typeof(PluginMethods), LogType.Error ); } @@ -242,11 +242,11 @@ internal static class PluginMethods { if (data.IsSuccess) { - Application.CurrentApplication.Logger.Log("Successfully loaded event : " + data.PluginName, LogType.Info, "\t\t > {Message}"); + Application.Logger.Log("Successfully loaded event : " + data.PluginName, LogType.Info, "\t\t > {Message}"); } else { - Application.CurrentApplication.Logger.Log("Failed to load event : " + data.PluginName + " because " + data.ErrorMessage, + Application.Logger.Log("Failed to load event : " + data.PluginName + " because " + data.ErrorMessage, typeof(PluginMethods), LogType.Error ); } @@ -258,11 +258,11 @@ internal static class PluginMethods { if (data.IsSuccess) { - Application.CurrentApplication.Logger.Log("Successfully loaded slash command : " + data.PluginName, LogType.Info, "\t\t > {Message}"); + Application.Logger.Log("Successfully loaded slash command : " + data.PluginName, LogType.Info, "\t\t > {Message}"); } else { - Application.CurrentApplication.Logger.Log("Failed to load slash command : " + data.PluginName + " because " + data.ErrorMessage, + Application.Logger.Log("Failed to load slash command : " + data.PluginName + " because " + data.ErrorMessage, typeof(PluginMethods), LogType.Error ); } @@ -274,11 +274,11 @@ internal static class PluginMethods { if (data.IsSuccess) { - Application.CurrentApplication.Logger.Log("Successfully loaded action : " + data.PluginName, LogType.Info, "\t\t > {Message}"); + Application.Logger.Log("Successfully loaded action : " + data.PluginName, LogType.Info, "\t\t > {Message}"); } else { - Application.CurrentApplication.Logger.Log("Failed to load action : " + data.PluginName + " because " + data.ErrorMessage, + Application.Logger.Log("Failed to load action : " + data.PluginName + " because " + data.ErrorMessage, typeof(PluginMethods), LogType.Error ); } diff --git a/DiscordBot/Bot/Actions/Module.cs b/DiscordBot/Bot/Actions/Module.cs index ed47832..ec2d688 100644 --- a/DiscordBot/Bot/Actions/Module.cs +++ b/DiscordBot/Bot/Actions/Module.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; - +using DiscordBotCore; using DiscordBotCore.Interfaces; +using DiscordBotCore.Interfaces.Modules; +using DiscordBotCore.Modules; using DiscordBotCore.Others; using DiscordBotCore.Others.Actions; @@ -45,15 +47,7 @@ namespace DiscordBot.Bot.Actions var modules = DiscordBotCore.Application.CurrentApplication.GetLoadedCoreModules(); foreach (var module in modules) { - Type moduleType = module.Key; - List moduleList = module.Value; - - Console.WriteLine($"Module Type: {moduleType.Name}"); - - foreach (dynamic mod in moduleList) - { - Console.WriteLine($"Module: {mod.Name}"); - } + Application.Logger.Log("Module: " + module.Key.ModuleName, this, LogType.Info); } } diff --git a/DiscordBot/Bot/Actions/Plugin.cs b/DiscordBot/Bot/Actions/Plugin.cs index e0a7ec4..efcfd85 100644 --- a/DiscordBot/Bot/Actions/Plugin.cs +++ b/DiscordBot/Bot/Actions/Plugin.cs @@ -128,13 +128,7 @@ public class Plugin: ICommandAction case "load": if (pluginsLoaded) { - Application.CurrentApplication.Logger.Log("Plugins already loaded", this, LogType.Warning); - break; - } - - if (Application.CurrentApplication.DiscordBotClient is null) - { - Application.CurrentApplication.Logger.Log("DiscordBot is null", this, LogType.Warning); + Application.Logger.Log("Plugins already loaded", this, LogType.Warning); break; } diff --git a/DiscordBot/Bot/Commands/NormalCommands/Help.cs b/DiscordBot/Bot/Commands/NormalCommands/Help.cs index 4c5ffc6..0b9e31f 100644 --- a/DiscordBot/Bot/Commands/NormalCommands/Help.cs +++ b/DiscordBot/Bot/Commands/NormalCommands/Help.cs @@ -10,7 +10,7 @@ namespace DiscordBot.Bot.Commands; /// /// The help command /// -internal class Help: DBCommand +internal class Help: IDbCommand { /// /// Command name @@ -32,7 +32,7 @@ internal class Help: DBCommand /// /// Check if the command require administrator to be executed /// - public bool requireAdmin => false; + public bool RequireAdmin => false; /// /// The main body of the command @@ -58,7 +58,7 @@ internal class Help: DBCommand var normalCommands = ""; foreach (var cmd in PluginLoader.Commands) - if (cmd.requireAdmin) + if (cmd.RequireAdmin) adminCommands += cmd.Command + " "; else normalCommands += cmd.Command + " "; diff --git a/DiscordBot/Bot/Commands/SlashCommands/Help.cs b/DiscordBot/Bot/Commands/SlashCommands/Help.cs index 56bf646..724ec29 100644 --- a/DiscordBot/Bot/Commands/SlashCommands/Help.cs +++ b/DiscordBot/Bot/Commands/SlashCommands/Help.cs @@ -9,11 +9,11 @@ using DiscordBotCore.Others; namespace DiscordBot.Bot.Commands.SlashCommands; -public class Help: DBSlashCommand +public class Help: IDbSlashCommand { public string Name => "help"; public string Description => "This command allows you to check all loaded commands"; - public bool canUseDM => true; + public bool CanUseDm => true; public bool HasInteraction => false; @@ -55,7 +55,7 @@ public class Help: DBSlashCommand return; } - embedBuilder.AddField("DM Usable:", slashCommand.canUseDM, true) + embedBuilder.AddField("DM Usable:", slashCommand.CanUseDm, true) .WithDescription(slashCommand.Description); } diff --git a/DiscordBot/Installer.cs b/DiscordBot/Installer.cs index ed19c28..27ce25b 100644 --- a/DiscordBot/Installer.cs +++ b/DiscordBot/Installer.cs @@ -44,6 +44,6 @@ public static class Installer await Application.CurrentApplication.ApplicationEnvironmentVariables.SaveToFile(); - Application.CurrentApplication.Logger.Log("Config Saved", typeof(Installer)); + Application.Logger.Log("Config Saved", typeof(Installer)); } } diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index a7df45c..6dc7d00 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -71,7 +71,7 @@ public class Program } catch (Exception ex) { - Application.CurrentApplication.Logger.Log(ex.ToString(), typeof(Program), LogType.Critical); + Application.Logger.Log(ex.ToString(), typeof(Program), LogType.Critical); } } @@ -91,7 +91,7 @@ public class Program return; } - Application.CurrentApplication.Logger.SetOutFunction(AnsiConsole.MarkupLine); + Application.Logger.SetOutFunction(AnsiConsole.MarkupLine); if (!Application.CurrentApplication.ApplicationEnvironmentVariables.ContainsKey("ServerID") || diff --git a/DiscordBotCore/Application.cs b/DiscordBotCore/Application.cs index f55a1d1..897a3d7 100644 --- a/DiscordBotCore/Application.cs +++ b/DiscordBotCore/Application.cs @@ -6,12 +6,12 @@ using DiscordBotCore.Plugin; using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.IO; using System.Threading.Tasks; using DiscordBotCore.Others.Exceptions; -using DiscordBotCore.Interfaces.Logger; using DiscordBotCore.Modules; -using System.Diagnostics; +using DiscordBotCore.Interfaces.Modules; using DiscordBotCore.Online.Helpers; using DiscordBotCore.Others.Settings; @@ -39,32 +39,6 @@ namespace DiscordBotCore public CustomSettingsDictionary ApplicationEnvironmentVariables { get; private set; } public InternalActionManager InternalActionManager { get; private set; } - - public ILogger Logger - { - get - { - try - { - return _ModuleManager.GetModule(); - } - catch (ModuleNotFoundException ex) - { - Console.WriteLine("No logger found"); - Console.WriteLine("Not having a valid logger is NOT an option. The default module will be downloaded from the official repo."); - Console.WriteLine("Install the default one ? [y/n]"); - ConsoleKey response = Console.ReadKey().Key; - if (response is ConsoleKey.Y) - { - Process.Start("DiscordBot", "--module-install LoggerModule"); - } - - Environment.Exit(0); - return null!; - } - } - } - public IPluginManager PluginManager { get; private set; } public Bot.App DiscordBotClient { get; internal set; } @@ -88,9 +62,9 @@ namespace DiscordBotCore CurrentApplication.ApplicationEnvironmentVariables = await CustomSettingsDictionary.CreateFromFile(_ConfigFile, true); - CurrentApplication.ApplicationEnvironmentVariables.Set("PluginFolder", _PluginsFolder); - CurrentApplication.ApplicationEnvironmentVariables.Set("ResourceFolder", _ResourcesFolder); - CurrentApplication.ApplicationEnvironmentVariables.Set("LogsFolder", _LogsFolder); + CurrentApplication.ApplicationEnvironmentVariables.Add("PluginFolder", _PluginsFolder); + CurrentApplication.ApplicationEnvironmentVariables.Add("ResourceFolder", _ResourcesFolder); + CurrentApplication.ApplicationEnvironmentVariables.Add("LogsFolder", _LogsFolder); CurrentApplication._ModuleManager = new ModuleManager(); @@ -117,7 +91,52 @@ namespace DiscordBotCore } - public IReadOnlyDictionary> GetLoadedCoreModules() => _ModuleManager.LoadedModules.AsReadOnly(); + public static class Logger + { + public static async void LogException(Exception ex, object sender, bool fullStackTrace = false) + { + var loggerModule = CurrentApplication._ModuleManager.GetModule(ModuleType.Logger); + await CurrentApplication._ModuleManager.InvokeMethod(loggerModule.Value, loggerModule.Key.MethodMapping["BaseLogException"], [ex, sender, fullStackTrace]); + } + + public static async void Log(string message) + { + var loggerModule = CurrentApplication._ModuleManager.GetModule(ModuleType.Logger); + await CurrentApplication._ModuleManager.InvokeMethod(loggerModule.Value, loggerModule.Key.MethodMapping["BaseLog"], [message]); + } + + public static async void Log(string message, LogType logType, string format) + { + var loggerModule = CurrentApplication._ModuleManager.GetModule(ModuleType.Logger); + await CurrentApplication._ModuleManager.InvokeMethod(loggerModule.Value, loggerModule.Key.MethodMapping["LogWithTypeAndFormat"], [message, logType, format]); + } + + public static async void Log(string message, LogType logType) + { + var loggerModule = CurrentApplication._ModuleManager.GetModule(ModuleType.Logger); + await CurrentApplication._ModuleManager.InvokeMethod(loggerModule.Value, loggerModule.Key.MethodMapping["LogWithType"], [message, logType]); + } + + public static async void Log(string message, object sender) + { + var loggerModule = CurrentApplication._ModuleManager.GetModule(ModuleType.Logger); + await CurrentApplication._ModuleManager.InvokeMethod(loggerModule.Value, loggerModule.Key.MethodMapping["LogWithSender"], [message, sender]); + } + + public static async void Log(string message, object sender, LogType type) + { + var loggerModule = CurrentApplication._ModuleManager.GetModule(ModuleType.Logger); + await CurrentApplication._ModuleManager.InvokeMethod(loggerModule.Value, loggerModule.Key.MethodMapping["LogWithTypeAndSender"], [message, sender, type]); + } + + public static async void SetOutFunction(Action outFunction) + { + var loggerModule = CurrentApplication._ModuleManager.GetModule(ModuleType.Logger); + await CurrentApplication._ModuleManager.InvokeMethod(loggerModule.Value, loggerModule.Key.MethodMapping["SetPrintFunction"], [outFunction]); + } + } + + public ReadOnlyDictionary GetLoadedCoreModules() => _ModuleManager.Modules.AsReadOnly(); public static string GetResourceFullPath(string path) { diff --git a/DiscordBotCore/Bot/App.cs b/DiscordBotCore/Bot/App.cs index 5751162..a349f20 100644 --- a/DiscordBotCore/Bot/App.cs +++ b/DiscordBotCore/Bot/App.cs @@ -107,7 +107,7 @@ public class App if (arg.Message.Contains("401")) { Application.CurrentApplication.ApplicationEnvironmentVariables.Remove("token"); - Application.CurrentApplication.Logger.Log("The token is invalid.", this, LogType.Critical); + Application.Logger.Log("The token is invalid.", this, LogType.Critical); await Application.CurrentApplication.ApplicationEnvironmentVariables.SaveToFile(); await Task.Delay(3000); @@ -124,7 +124,7 @@ public class App private Task LoggedIn() { - Application.CurrentApplication.Logger.Log("Successfully Logged In", this); + Application.Logger.Log("Successfully Logged In", this); return Task.CompletedTask; } @@ -134,12 +134,12 @@ public class App { case LogSeverity.Error: case LogSeverity.Critical: - Application.CurrentApplication.Logger.Log(message.Message, this, LogType.Error); + Application.Logger.Log(message.Message, this, LogType.Error); break; case LogSeverity.Info: case LogSeverity.Debug: - Application.CurrentApplication.Logger.Log(message.Message, this, LogType.Info); + Application.Logger.Log(message.Message, this, LogType.Info); break; diff --git a/DiscordBotCore/Bot/CommandHandler.cs b/DiscordBotCore/Bot/CommandHandler.cs index dec06e8..b428c7a 100644 --- a/DiscordBotCore/Bot/CommandHandler.cs +++ b/DiscordBotCore/Bot/CommandHandler.cs @@ -51,12 +51,12 @@ internal class CommandHandler throw new Exception("Failed to run command !"); if (arg.Channel is SocketDMChannel) - plugin.ExecuteDM(arg); + plugin.ExecuteDm(arg); else plugin.ExecuteServer(arg); } catch (Exception ex) { - Application.CurrentApplication.Logger.LogException(ex, this); + Application.Logger.LogException(ex, this); } return Task.CompletedTask; @@ -91,7 +91,7 @@ internal class CommandHandler await _commandService.ExecuteAsync(context, argPos, null); - DBCommand? plugin; + IDbCommand? plugin; var cleanMessage = ""; if (message.HasMentionPrefix(_client.CurrentUser, ref argPos)) @@ -129,7 +129,7 @@ internal class CommandHandler if (plugin is null) return; - if (plugin.requireAdmin && !context.Message.Author.IsAdmin()) + if (plugin.RequireAdmin && !context.Message.Author.IsAdmin()) return; var split = cleanMessage.Split(' '); @@ -140,19 +140,19 @@ internal class CommandHandler DbCommandExecutingArguments cmd = new(context, cleanMessage, split[0], argsClean); - Application.CurrentApplication.Logger.Log( + Application.Logger.Log( $"User ({context.User.Username}) from Guild \"{context.Guild.Name}\" executed command \"{cmd.CleanContent}\"", this, LogType.Info ); if (context.Channel is SocketDMChannel) - plugin.ExecuteDM(cmd); + plugin.ExecuteDm(cmd); else plugin.ExecuteServer(cmd); } catch (Exception ex) { - Application.CurrentApplication.Logger.LogException(ex, this); + Application.Logger.LogException(ex, this); } } } diff --git a/DiscordBotCore/Interfaces/DBCommand.cs b/DiscordBotCore/Interfaces/IDbCommand.cs similarity index 91% rename from DiscordBotCore/Interfaces/DBCommand.cs rename to DiscordBotCore/Interfaces/IDbCommand.cs index 1c5f1e5..0e60dc6 100644 --- a/DiscordBotCore/Interfaces/DBCommand.cs +++ b/DiscordBotCore/Interfaces/IDbCommand.cs @@ -3,7 +3,7 @@ using DiscordBotCore.Others; namespace DiscordBotCore.Interfaces; -public interface DBCommand +public interface IDbCommand { /// /// Command to be executed @@ -30,7 +30,7 @@ public interface DBCommand /// /// true if the command requre admin, otherwise false /// - bool requireAdmin { get; } + bool RequireAdmin { get; } /// /// The main body of the command. This is what is executed when user calls the command in Server @@ -44,7 +44,7 @@ public interface DBCommand /// The main body of the command. This is what is executed when user calls the command in DM /// /// The disocrd Context - void ExecuteDM(DbCommandExecutingArguments args) + void ExecuteDm(DbCommandExecutingArguments args) { } } diff --git a/DiscordBotCore/Interfaces/DBEvent.cs b/DiscordBotCore/Interfaces/IDbEvent.cs similarity index 95% rename from DiscordBotCore/Interfaces/DBEvent.cs rename to DiscordBotCore/Interfaces/IDbEvent.cs index 80bb93e..76a4908 100644 --- a/DiscordBotCore/Interfaces/DBEvent.cs +++ b/DiscordBotCore/Interfaces/IDbEvent.cs @@ -2,7 +2,7 @@ namespace DiscordBotCore.Interfaces; -public interface DBEvent +public interface IDbEvent { /// /// The name of the event diff --git a/DiscordBotCore/Interfaces/DBSlashCommand.cs b/DiscordBotCore/Interfaces/IDbSlashCommand.cs similarity index 79% rename from DiscordBotCore/Interfaces/DBSlashCommand.cs rename to DiscordBotCore/Interfaces/IDbSlashCommand.cs index e8e0d3f..7682fa6 100644 --- a/DiscordBotCore/Interfaces/DBSlashCommand.cs +++ b/DiscordBotCore/Interfaces/IDbSlashCommand.cs @@ -6,11 +6,11 @@ using Discord.WebSocket; namespace DiscordBotCore.Interfaces; -public interface DBSlashCommand +public interface IDbSlashCommand { string Name { get; } string Description { get; } - bool canUseDM { get; } + bool CanUseDm { get; } bool HasInteraction { get; } List Options { get; } @@ -18,7 +18,7 @@ public interface DBSlashCommand void ExecuteServer(SocketSlashCommand context) { } - void ExecuteDM(SocketSlashCommand context) { } + void ExecuteDm(SocketSlashCommand context) { } Task ExecuteInteraction(SocketInteraction interaction) => Task.CompletedTask; } diff --git a/DiscordBotCore/Interfaces/Logger/ILogMessage.cs b/DiscordBotCore/Interfaces/Logger/ILogMessage.cs deleted file mode 100644 index 1408939..0000000 --- a/DiscordBotCore/Interfaces/Logger/ILogMessage.cs +++ /dev/null @@ -1,15 +0,0 @@ -using DiscordBotCore.Others; - -using System; - -namespace DiscordBotCore.Interfaces.Logger -{ - public interface ILogMessage - { - public string Message { get; protected set; } - public DateTime ThrowTime { get; protected set; } - public string SenderName { get; protected set; } - public LogType LogMessageType { get; protected set; } - - } -} diff --git a/DiscordBotCore/Interfaces/Logger/ILogger.cs b/DiscordBotCore/Interfaces/Logger/ILogger.cs deleted file mode 100644 index e73d13f..0000000 --- a/DiscordBotCore/Interfaces/Logger/ILogger.cs +++ /dev/null @@ -1,26 +0,0 @@ -using DiscordBotCore.Interfaces.Modules; -using DiscordBotCore.Others; - -using System; - -namespace DiscordBotCore.Interfaces.Logger -{ - public interface ILogger : IBaseModule - { - public struct FormattedMessage { - public string Message; - public LogType Type; - } - - string LogMessageFormat { get; set; } - - void Log(string message); - void Log(string message, LogType logType); - void Log(string message, LogType logType, string format); - void Log(string message, object Sender); - void Log(string message, object Sender, LogType type); - void LogException(Exception exception, object Sender, bool logFullStack = false); - - void SetOutFunction(Action outFunction); - } -} diff --git a/DiscordBotCore/Interfaces/Modules/IBaseModule.cs b/DiscordBotCore/Interfaces/Modules/IBaseModule.cs deleted file mode 100644 index bbebd30..0000000 --- a/DiscordBotCore/Interfaces/Modules/IBaseModule.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace DiscordBotCore.Interfaces.Modules -{ - public interface IBaseModule - { - } -} diff --git a/DiscordBotCore/Interfaces/Modules/IModule.cs b/DiscordBotCore/Interfaces/Modules/IModule.cs index 06dbdbf..60e9c9e 100644 --- a/DiscordBotCore/Interfaces/Modules/IModule.cs +++ b/DiscordBotCore/Interfaces/Modules/IModule.cs @@ -2,10 +2,20 @@ namespace DiscordBotCore.Interfaces.Modules { - public interface IModule where T : IBaseModule + + public enum ModuleType { + Logger, + Other + } + + /// + /// Define a module. + /// + public interface IModule + { + public ModuleType ModuleType { get; } public string Name { get; } - public T Module { get; } public Task Initialize(); } } diff --git a/DiscordBotCore/Interfaces/PluginManager/IPluginManager.cs b/DiscordBotCore/Interfaces/PluginManager/IPluginManager.cs index 31e30d0..1b2fd2c 100644 --- a/DiscordBotCore/Interfaces/PluginManager/IPluginManager.cs +++ b/DiscordBotCore/Interfaces/PluginManager/IPluginManager.cs @@ -9,7 +9,6 @@ namespace DiscordBotCore.Interfaces.PluginManager { public string BaseUrl { get; set; } public string Branch { get; set; } - Task AppendPluginToDatabase(PluginInfo pluginData); Task CheckForUpdates(); Task ExecutePluginInstallScripts(List listOfDependencies); @@ -24,7 +23,6 @@ namespace DiscordBotCore.Interfaces.PluginManager Task MarkPluginToUninstall(string pluginName); Task RemovePluginFromDatabase(string pluginName); Task UninstallMarkedPlugins(); - Task SetEnabledStatus(string pluginName, bool status); } } \ No newline at end of file diff --git a/DiscordBotCore/Loaders/Loader.cs b/DiscordBotCore/Loaders/Loader.cs index 4610514..5b14e8e 100644 --- a/DiscordBotCore/Loaders/Loader.cs +++ b/DiscordBotCore/Loaders/Loader.cs @@ -35,9 +35,9 @@ internal class Loader } } - await LoadEverythingOfType(); - await LoadEverythingOfType(); - await LoadEverythingOfType(); + await LoadEverythingOfType(); + await LoadEverythingOfType(); + await LoadEverythingOfType(); await LoadEverythingOfType(); } @@ -60,9 +60,9 @@ internal class Loader var pluginType = plugin switch { - DBEvent => PluginType.EVENT, - DBCommand => PluginType.COMMAND, - DBSlashCommand => PluginType.SLASH_COMMAND, + IDbEvent => PluginType.EVENT, + IDbCommand => PluginType.COMMAND, + IDbSlashCommand => PluginType.SLASH_COMMAND, ICommandAction => PluginType.ACTION, _ => PluginType.UNKNOWN }; diff --git a/DiscordBotCore/Loaders/ModuleLoader.cs b/DiscordBotCore/Loaders/ModuleLoader.cs index 95a2fed..acdf330 100644 --- a/DiscordBotCore/Loaders/ModuleLoader.cs +++ b/DiscordBotCore/Loaders/ModuleLoader.cs @@ -6,23 +6,24 @@ using System.Threading.Tasks; using DiscordBotCore.Interfaces.Modules; using System.Reflection; +using DiscordBotCore.Modules; namespace DiscordBotCore.Loaders { internal class ModuleLoader { - private readonly string _ModuleFolder; + private readonly List _ModuleData; - public ModuleLoader(string moduleFolder) + public ModuleLoader(List moduleFolder) { - _ModuleFolder = moduleFolder; - Directory.CreateDirectory(moduleFolder); + _ModuleData = moduleFolder; } public Task LoadFileModules() { - var files = Directory.GetFiles(_ModuleFolder, "*.dll"); - foreach (var file in files) + var paths = _ModuleData.Select(module => module.ModulePath); + + foreach (var file in paths) { try { @@ -37,20 +38,20 @@ namespace DiscordBotCore.Loaders return Task.CompletedTask; } - public Task>> LoadModules() where T : IBaseModule + public Task> LoadModules() { - var moduleType = typeof(IModule); + var moduleType = typeof(IModule); var moduleTypes = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(s => s.GetTypes()) .Where(p => moduleType.IsAssignableFrom(p) && !p.IsInterface); - var modules = new List>(); + var modules = new List(); foreach (var module in moduleTypes) { try { - var instance = (IModule?)Activator.CreateInstance(module); - if (instance == null) + var instance = (IModule?)Activator.CreateInstance(module); + if (instance is null) { Console.WriteLine($"Error loading module {module.Name}: Could not create instance"); continue; diff --git a/DiscordBotCore/Loaders/PluginLoader.cs b/DiscordBotCore/Loaders/PluginLoader.cs index e8a7dfd..2511fbb 100644 --- a/DiscordBotCore/Loaders/PluginLoader.cs +++ b/DiscordBotCore/Loaders/PluginLoader.cs @@ -26,9 +26,9 @@ public class PluginLoader public SlashCommandLoaded? OnSlashCommandLoaded; public ActionLoaded? OnActionLoaded; - public static List Commands { get; private set; } = new List(); - public static List Events { get; private set; } = new List(); - public static List SlashCommands { get; private set; } = new List(); + public static List Commands { get; private set; } = new List(); + public static List Events { get; private set; } = new List(); + public static List SlashCommands { get; private set; } = new List(); public static List Actions { get; private set; } = new List(); public PluginLoader(DiscordSocketClient discordSocketClient) @@ -41,7 +41,7 @@ public class PluginLoader if (_Client == null) { - Application.CurrentApplication.Logger.Log("Discord client is null", this, LogType.Error); + Application.Logger.Log("Discord client is null", this, LogType.Error); return; } @@ -50,7 +50,7 @@ public class PluginLoader SlashCommands.Clear(); Actions.Clear(); - Application.CurrentApplication.Logger.Log("Loading plugins...", this); + Application.Logger.Log("Loading plugins...", this); var loader = new Loader(); @@ -62,7 +62,7 @@ public class PluginLoader private void FileLoadedException(FileLoaderResult result) { - Application.CurrentApplication.Logger.Log(result.ErrorMessage, this, LogType.Error); + Application.Logger.Log(result.ErrorMessage, this, LogType.Error); } private async void OnPluginLoaded(PluginLoadResultData result) @@ -81,31 +81,31 @@ public class PluginLoader break; case PluginType.COMMAND: - Commands.Add((DBCommand)result.Plugin); + Commands.Add((IDbCommand)result.Plugin); OnCommandLoaded?.Invoke(result); break; case PluginType.EVENT: - if (this.TryStartEvent((DBEvent)result.Plugin)) + if (this.TryStartEvent((IDbEvent)result.Plugin)) { - Events.Add((DBEvent)result.Plugin); + Events.Add((IDbEvent)result.Plugin); OnEventLoaded?.Invoke(result); } break; case PluginType.SLASH_COMMAND: - if (await this.TryStartSlashCommand((DBSlashCommand)result.Plugin)) + if (await this.TryStartSlashCommand((IDbSlashCommand)result.Plugin)) { - if(((DBSlashCommand)result.Plugin).HasInteraction) - _Client.InteractionCreated += ((DBSlashCommand)result.Plugin).ExecuteInteraction; - SlashCommands.Add((DBSlashCommand)result.Plugin); + if(((IDbSlashCommand)result.Plugin).HasInteraction) + _Client.InteractionCreated += ((IDbSlashCommand)result.Plugin).ExecuteInteraction; + SlashCommands.Add((IDbSlashCommand)result.Plugin); OnSlashCommandLoaded?.Invoke(result); } else - Application.CurrentApplication.Logger.Log($"Failed to start slash command {result.PluginName}", this, LogType.Error); + Application.Logger.Log($"Failed to start slash command {result.PluginName}", this, LogType.Error); break; case PluginType.UNKNOWN: default: - Application.CurrentApplication.Logger.Log("Unknown plugin type", this, LogType.Error); + Application.Logger.Log("Unknown plugin type", this, LogType.Error); break; } } diff --git a/DiscordBotCore/Loaders/PluginLoaderExtensions.cs b/DiscordBotCore/Loaders/PluginLoaderExtensions.cs index 39a9341..6adde1b 100644 --- a/DiscordBotCore/Loaders/PluginLoaderExtensions.cs +++ b/DiscordBotCore/Loaders/PluginLoaderExtensions.cs @@ -14,7 +14,7 @@ namespace DiscordBotCore.Loaders; internal static class PluginLoaderExtensions { - internal static bool TryStartEvent(this PluginLoader pluginLoader, DBEvent? dbEvent) + internal static bool TryStartEvent(this PluginLoader pluginLoader, IDbEvent? dbEvent) { try { @@ -28,13 +28,13 @@ internal static class PluginLoaderExtensions } catch (Exception e) { - Application.CurrentApplication.Logger.Log($"Error starting event {dbEvent.Name}: {e.Message}", typeof(PluginLoader), LogType.Error); - Application.CurrentApplication.Logger.LogException(e, typeof(PluginLoader)); + Application.Logger.Log($"Error starting event {dbEvent.Name}: {e.Message}", typeof(PluginLoader), LogType.Error); + Application.Logger.LogException(e, typeof(PluginLoader)); return false; } } - internal static async Task TryStartSlashCommand(this PluginLoader pluginLoader, DBSlashCommand? dbSlashCommand) + internal static async Task TryStartSlashCommand(this PluginLoader pluginLoader, IDbSlashCommand? dbSlashCommand) { try { @@ -53,7 +53,7 @@ internal static class PluginLoaderExtensions builder.WithDescription(dbSlashCommand.Description); builder.Options = dbSlashCommand.Options; - if (dbSlashCommand.canUseDM) + if (dbSlashCommand.CanUseDm) builder.WithContextTypes(InteractionContextType.BotDm, InteractionContextType.Guild); else builder.WithContextTypes(InteractionContextType.Guild); @@ -64,7 +64,7 @@ internal static class PluginLoaderExtensions if (!result) { - Application.CurrentApplication.Logger.Log($"Failed to enable slash command {dbSlashCommand.Name} for guild {guildId}", typeof(PluginLoader), LogType.Error); + Application.Logger.Log($"Failed to enable slash command {dbSlashCommand.Name} for guild {guildId}", typeof(PluginLoader), LogType.Error); } } @@ -74,7 +74,7 @@ internal static class PluginLoaderExtensions } catch (Exception e) { - Application.CurrentApplication.Logger.Log($"Error starting slash command {dbSlashCommand.Name}: {e.Message}", typeof(PluginLoader), LogType.Error); + Application.Logger.Log($"Error starting slash command {dbSlashCommand.Name}: {e.Message}", typeof(PluginLoader), LogType.Error); return false; } } @@ -84,7 +84,7 @@ internal static class PluginLoaderExtensions SocketGuild? guild = pluginLoader._Client.GetGuild(guildId); if (guild is null) { - Application.CurrentApplication.Logger.Log("Failed to get guild with ID " + guildId, typeof(PluginLoader), LogType.Error); + Application.Logger.Log("Failed to get guild with ID " + guildId, typeof(PluginLoader), LogType.Error); return false; } diff --git a/DiscordBotCore/Modules/ModuleData.cs b/DiscordBotCore/Modules/ModuleData.cs new file mode 100644 index 0000000..155ca1a --- /dev/null +++ b/DiscordBotCore/Modules/ModuleData.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; + +namespace DiscordBotCore.Modules; + +public class ModuleData +{ + public string ModuleName { get; set; } + public string ModulePath { get; set; } + public bool IsEnabled { get; set; } = true; + public IDictionary MethodMapping { get; set; } + + public ModuleData(string moduleName, string modulePath, IDictionary methodMapping, bool isEnabled) + { + ModuleName = moduleName; + ModulePath = modulePath; + MethodMapping = methodMapping; + IsEnabled = isEnabled; + } +} diff --git a/DiscordBotCore/Modules/ModuleDownloader.cs b/DiscordBotCore/Modules/ModuleDownloader.cs index fec41a0..443481c 100644 --- a/DiscordBotCore/Modules/ModuleDownloader.cs +++ b/DiscordBotCore/Modules/ModuleDownloader.cs @@ -1,8 +1,5 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; using System.Threading.Tasks; using DiscordBotCore.Online; @@ -11,20 +8,24 @@ namespace DiscordBotCore.Modules { public class ModuleDownloader { - private string _moduleName; - private readonly string _baseUrl = "https://raw.githubusercontent.com/andreitdr/SethPlugins/tests/Modules/"; - private readonly string _moduleFolder = "./Data/Modules"; + private readonly string _ModuleName; + private const string _BaseUrl = "https://raw.githubusercontent.com/andreitdr/SethPlugins/tests/Modules/"; public ModuleDownloader(string moduleName) { - _moduleName = moduleName; + _ModuleName = moduleName; } public async Task DownloadModule(IProgress progressToWrite) { - Directory.CreateDirectory(_moduleFolder); - string url = _baseUrl + _moduleName + ".dll"; - await ServerCom.DownloadFileAsync(url, _moduleFolder + "/" + _moduleName + ".dll", progressToWrite); + string? moduleFolder = Application.CurrentApplication.ApplicationEnvironmentVariables.Get("ModuleFolder"); + + if(moduleFolder is null) + throw new DirectoryNotFoundException("Module folder not found"); // Should never happen + + Directory.CreateDirectory(moduleFolder); + string url = _BaseUrl + _ModuleName + ".dll"; + await ServerCom.DownloadFileAsync(url, moduleFolder + "/" + _ModuleName + ".dll", progressToWrite); } } } diff --git a/DiscordBotCore/Modules/ModuleManager.cs b/DiscordBotCore/Modules/ModuleManager.cs index 45e7d31..73e5eaf 100644 --- a/DiscordBotCore/Modules/ModuleManager.cs +++ b/DiscordBotCore/Modules/ModuleManager.cs @@ -1,61 +1,98 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading.Tasks; -using DiscordBotCore.Interfaces.Logger; using DiscordBotCore.Interfaces.Modules; using DiscordBotCore.Loaders; -using DiscordBotCore.Others.Exceptions; +using Newtonsoft.Json; namespace DiscordBotCore.Modules { internal class ModuleManager { private static readonly string _BaseModuleFolder = "./Data/Modules"; - - private readonly string _ModuleFolder; - internal Dictionary> LoadedModules { get; } - - public ModuleManager(string moduleFolder) - { - _ModuleFolder = moduleFolder; - LoadedModules = new Dictionary>(); - } + private static readonly string _BaseModuleConfig = "./Data/Resources/modules.json"; + internal Dictionary Modules { get; set; } public ModuleManager() { - _ModuleFolder = Application.CurrentApplication.ApplicationEnvironmentVariables.Get("ModuleFolder", _BaseModuleFolder); - LoadedModules = new Dictionary>(); + Application.CurrentApplication.ApplicationEnvironmentVariables.Get("ModuleFolder", _BaseModuleFolder); + Modules = new Dictionary(); } - public T GetModule() where T : IBaseModule + public KeyValuePair GetModule(string moduleName) { - if(!LoadedModules.ContainsKey(typeof(T))) - throw new ModuleNotFoundException(); - - if (!LoadedModules[typeof(T)].Any()) - throw new ModuleNotFoundException(); - - IModule module = (IModule)LoadedModules[typeof(T)][0]; - return module.Module; + return Modules.FirstOrDefault(module => module.Key.ModuleName == moduleName); + } + + public KeyValuePair GetModule(ModuleType moduleType) + { + return Modules.First(module => module.Value.ModuleType == moduleType); } public async Task LoadModules() { - ModuleLoader loader = new ModuleLoader(_ModuleFolder); - await loader.LoadFileModules(); - + string moduleConfigPath = Application.CurrentApplication.ApplicationEnvironmentVariables + .Get("ModuleConfig", _BaseModuleConfig); - var loggers = await loader.LoadModules(); - foreach (var logger in loggers) + string moduleConfigFile = await File.ReadAllTextAsync(moduleConfigPath); + List? listOfModuleData = JsonConvert.DeserializeObject>(moduleConfigFile); + + if(listOfModuleData is null) + return; + + if (!listOfModuleData.Any()) { - await logger.Initialize(); - Console.WriteLine("Module Loaded: " + logger.Name); + return; + } + + ModuleLoader moduleLoader = new ModuleLoader(listOfModuleData); + await moduleLoader.LoadFileModules(); + var modules = await moduleLoader.LoadModules(); + + foreach (var module in modules) + { + + ModuleData? moduleData = listOfModuleData.FirstOrDefault(data => data.ModuleName == module.Name); + + if (moduleData is null) + { + continue; + } + + if (moduleData.IsEnabled) + { + await module.Initialize(); // TODO: Add error handling + Modules.Add(moduleData, module); + } + } + } + + public async Task InvokeMethod(string moduleName, string methodName, object[] parameters) + { + IModule module = GetModule(moduleName).Value; + var method = module.GetType().GetMethod(methodName); + + if (method is null) + { + throw new Exception("Method not found"); // TODO: Add custom exception } - LoadedModules.Add(typeof(ILogger), loggers.Cast().ToList()); + await Task.Run(() => method.Invoke(module, parameters)); + } + public async Task InvokeMethod(IModule module, string methodName, object[] parameters) + { + var method = module.GetType().GetMethod(methodName); + + if (method is null) + { + throw new Exception($"Method not found {methodName}"); + } + + await Task.Run(() => method.Invoke(module, parameters)); } diff --git a/DiscordBotCore/Online/PluginManager.cs b/DiscordBotCore/Online/PluginManager.cs index 18acec6..2e4aa68 100644 --- a/DiscordBotCore/Online/PluginManager.cs +++ b/DiscordBotCore/Online/PluginManager.cs @@ -119,7 +119,7 @@ public class PluginManager : IPluginManager { if (await pluginUpdater.HasUpdate(plugin.PluginName)) { - Application.CurrentApplication.Logger.Log("Updating plugin: " + plugin.PluginName, this, LogType.Info); + Application.Logger.Log("Updating plugin: " + plugin.PluginName, this, LogType.Info); await pluginUpdater.UpdatePlugin(plugin.PluginName); } } diff --git a/DiscordBotCore/Others/Actions/InternalActionsManager.cs b/DiscordBotCore/Others/Actions/InternalActionsManager.cs index 5a93883..33ee1d6 100644 --- a/DiscordBotCore/Others/Actions/InternalActionsManager.cs +++ b/DiscordBotCore/Others/Actions/InternalActionsManager.cs @@ -22,7 +22,7 @@ public class InternalActionManager if (this.Actions.ContainsKey(action.ActionName)) { // This should never happen. If it does, log it and return - Application.CurrentApplication.Logger.Log($"Action {action.ActionName} already exists", this, LogType.Error); + Application.Logger.Log($"Action {action.ActionName} already exists", this, LogType.Error); return; } @@ -50,7 +50,7 @@ public class InternalActionManager { if (!Actions.ContainsKey(actionName)) { - Application.CurrentApplication.Logger.Log($"Action {actionName} not found", this, LogType.Error); + Application.Logger.Log($"Action {actionName} not found", this, LogType.Error); return false; } @@ -58,7 +58,7 @@ public class InternalActionManager { if (Actions[actionName].RunType == InternalActionRunType.OnStartup) { - Application.CurrentApplication.Logger.Log($"Action {actionName} is not executable", this, LogType.Error); + Application.Logger.Log($"Action {actionName} is not executable", this, LogType.Error); return false; } @@ -67,7 +67,7 @@ public class InternalActionManager } catch (Exception e) { - Application.CurrentApplication.Logger.Log(e.Message, type: LogType.Error, Sender: this); + Application.Logger.Log(e.Message, type: LogType.Error, sender: this); return false; } } diff --git a/DiscordBotCore/Others/ArchiveManager.cs b/DiscordBotCore/Others/ArchiveManager.cs index 3bbfa47..52730ab 100644 --- a/DiscordBotCore/Others/ArchiveManager.cs +++ b/DiscordBotCore/Others/ArchiveManager.cs @@ -105,7 +105,7 @@ public static class ArchiveManager } catch (Exception ex) { - Application.CurrentApplication.Logger.Log(ex.Message, typeof(ArchiveManager), LogType.Error); // Write the error to a file + Application.Logger.Log(ex.Message, typeof(ArchiveManager), LogType.Error); // Write the error to a file await Task.Delay(100); return await ReadFromPakAsync(fileName, archFile); } @@ -141,7 +141,7 @@ public static class ArchiveManager } catch (Exception ex) { - Application.CurrentApplication.Logger.Log(ex.Message, typeof(ArchiveManager), LogType.Error); + Application.Logger.Log(ex.Message, typeof(ArchiveManager), LogType.Error); } currentZipFile++; @@ -176,7 +176,7 @@ public static class ArchiveManager } catch (Exception ex) { - Application.CurrentApplication.Logger.Log(ex.Message, typeof(ArchiveManager), LogType.Error); + Application.Logger.Log(ex.Message, typeof(ArchiveManager), LogType.Error); } await Task.Delay(10); diff --git a/DiscordBotCore/Others/Settings/CustomSettingsDictionary.cs b/DiscordBotCore/Others/Settings/CustomSettingsDictionary.cs index 1fba782..32a5791 100644 --- a/DiscordBotCore/Others/Settings/CustomSettingsDictionary.cs +++ b/DiscordBotCore/Others/Settings/CustomSettingsDictionary.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +using System; +using System.Collections; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -35,14 +37,14 @@ public class CustomSettingsDictionary : CustomSettingsDictionaryBase GetList(string key, List defaultValue) { - List result = base.GetList(key, defaultValue); - - if (_EnableAutoAddOnGetWithDefault && defaultValue.All(result.Contains)) + List value = base.GetList(key, defaultValue); + + if (_EnableAutoAddOnGetWithDefault && value.All(defaultValue.Contains)) { - Add(key,defaultValue); + Add(key, defaultValue); } - return result; + return value; } public override async Task LoadFromFile() @@ -71,11 +73,21 @@ public class CustomSettingsDictionary : CustomSettingsDictionaryBase>(); - } else { - dict[kvp.Key] = kvp.Value; + if (kvp.Value.Type == JTokenType.Integer) + dict[kvp.Key] = kvp.Value.Value(); + else if (kvp.Value.Type == JTokenType.Float) + dict[kvp.Key] = kvp.Value.Value(); + else if (kvp.Value.Type == JTokenType.Boolean) + dict[kvp.Key] = kvp.Value.Value(); + else if (kvp.Value.Type == JTokenType.String) + dict[kvp.Key] = kvp.Value.Value(); + else if (kvp.Value.Type == JTokenType.Date) + dict[kvp.Key] = kvp.Value.Value(); + else + dict[kvp.Key] = kvp.Value; } } diff --git a/DiscordBotCore/Others/Settings/CustomSettingsDictionaryBase.cs b/DiscordBotCore/Others/Settings/CustomSettingsDictionaryBase.cs index abe20cf..42264c0 100644 --- a/DiscordBotCore/Others/Settings/CustomSettingsDictionaryBase.cs +++ b/DiscordBotCore/Others/Settings/CustomSettingsDictionaryBase.cs @@ -56,6 +56,27 @@ public abstract class CustomSettingsDictionaryBase : ICustomSetting return default; } + + public virtual IDictionary GetDictionary(TKey key) + { + if (_InternalDictionary.TryGetValue(key, out var value)) + { + if (value is not IDictionary) + { + throw new Exception("The value is not a dictionary"); + } + + var dictionary = new Dictionary(); + foreach (DictionaryEntry item in (IDictionary)value) + { + dictionary.Add((TSubKey)Convert.ChangeType(item.Key, typeof(TSubKey)), (TSubValue)Convert.ChangeType(item.Value, typeof(TSubValue))); + } + + return dictionary; + } + + return new Dictionary(); + } public virtual List GetList(TKey key, List defaultValue) { @@ -67,9 +88,9 @@ public abstract class CustomSettingsDictionaryBase : ICustomSetting } var list = new List(); - foreach (var item in (IList)value) + foreach (object? item in (IList)value) { - list.Add(ConvertValue(item)); + list.Add((T)Convert.ChangeType(item, typeof(T))); } return list; @@ -141,20 +162,4 @@ public abstract class CustomSettingsDictionaryBase : ICustomSetting public abstract Task SaveToFile(); public abstract Task LoadFromFile(); - - protected virtual T? ConvertValue(object value) - { - - if (typeof(T) == typeof(ulong) && value is long longValue) - { - return (T)(object)Convert.ToUInt64(longValue); - } - - if (typeof(T).IsEnum && value is string stringValue) - { - return (T)Enum.Parse(typeof(T), stringValue); - } - - return (T)Convert.ChangeType(value, typeof(T)); - } } diff --git a/Modules/LoggerModule/Entry.cs b/Modules/LoggerModule/Entry.cs index 10c3d94..5159342 100644 --- a/Modules/LoggerModule/Entry.cs +++ b/Modules/LoggerModule/Entry.cs @@ -1,16 +1,17 @@ -using DiscordBotCore; -using DiscordBotCore.Interfaces.Logger; -using DiscordBotCore.Interfaces.Modules; +using DiscordBotCore.Interfaces.Modules; +using DiscordBotCore.Others; namespace LoggerModule { - public class Entry : IModule + public class Entry : IModule { - public string Name => "Logger Module"; + public string Name => "LoggerModule"; + public ModuleType ModuleType => ModuleType.Logger; + const string _LogFolder = "./Data/Logs/"; const string _LogFormat = "{ThrowTime} {SenderName} {Message}"; - - public ILogger Module { get; private set; } + + public ILogger Module { get; private set; } = null!; public Task Initialize() { @@ -18,5 +19,20 @@ namespace LoggerModule Module = logger; return Task.CompletedTask; } + + public void SetOutFunction(Action outFunction) + { + Module.SetOutFunction(outFunction); + } + + + + public void LogMessage(string message) => Module.Log(message); + public void LogMessageWithTypeAndFormat(string message, LogType logType, string format) => Module.Log(message, logType, format); + public void LogMessageWithType(string message, LogType logType) => Module.Log(message, logType); + public void LogMessageWithSender(string message, object Sender) => Module.Log(message, Sender); + public void LogMessageWithTypeAndSender(string message, object Sender, LogType type) => Module.Log(message, Sender, type); + public void LogExceptionWithSenderAndFullStack(Exception exception, object Sender, bool logFullStack = false) => Module.LogException(exception, Sender, logFullStack); + } } diff --git a/Modules/LoggerModule/ILogMessage.cs b/Modules/LoggerModule/ILogMessage.cs new file mode 100644 index 0000000..00bc3a9 --- /dev/null +++ b/Modules/LoggerModule/ILogMessage.cs @@ -0,0 +1,12 @@ +using DiscordBotCore.Others; + +namespace LoggerModule; + +public interface ILogMessage +{ + public string Message { get; protected set; } + public DateTime ThrowTime { get; protected set; } + public string SenderName { get; protected set; } + public LogType LogMessageType { get; protected set; } + +} \ No newline at end of file diff --git a/Modules/LoggerModule/ILogger.cs b/Modules/LoggerModule/ILogger.cs new file mode 100644 index 0000000..1cb5f10 --- /dev/null +++ b/Modules/LoggerModule/ILogger.cs @@ -0,0 +1,22 @@ +using DiscordBotCore.Others; + +namespace LoggerModule; + +public interface ILogger +{ + public struct FormattedMessage { + public string Message; + public LogType Type; + } + + string LogMessageFormat { get; set; } + + void Log(string message); + void Log(string message, LogType logType); + void Log(string message, LogType logType, string format); + void Log(string message, object Sender); + void Log(string message, object Sender, LogType type); + void LogException(Exception exception, object Sender, bool logFullStack = false); + + void SetOutFunction(Action outFunction); +} \ No newline at end of file diff --git a/Modules/LoggerModule/LogMessage.cs b/Modules/LoggerModule/LogMessage.cs index d408544..5ab1052 100644 --- a/Modules/LoggerModule/LogMessage.cs +++ b/Modules/LoggerModule/LogMessage.cs @@ -1,5 +1,4 @@ -using DiscordBotCore.Interfaces.Logger; -using DiscordBotCore.Others; +using DiscordBotCore.Others; namespace LoggerModule { diff --git a/Modules/LoggerModule/Logger.cs b/Modules/LoggerModule/Logger.cs index ea50420..0f04d36 100644 --- a/Modules/LoggerModule/Logger.cs +++ b/Modules/LoggerModule/Logger.cs @@ -1,5 +1,4 @@ -using DiscordBotCore.Interfaces.Logger; -using DiscordBotCore.Others; +using DiscordBotCore.Others; namespace LoggerModule; diff --git a/Plugins/CppWrapper/LibraryManagement/ExternLibrary.cs b/Plugins/CppWrapper/LibraryManagement/ExternLibrary.cs index 58845b6..37984d8 100644 --- a/Plugins/CppWrapper/LibraryManagement/ExternLibrary.cs +++ b/Plugins/CppWrapper/LibraryManagement/ExternLibrary.cs @@ -21,7 +21,7 @@ namespace CppWrapper.LibraryManagement return; } - Application.CurrentApplication.Logger.Log($"Loading library {LibraryPath}"); + Application.Logger.Log($"Loading library {LibraryPath}"); if(!NativeLibrary.TryLoad(LibraryPath, out IntPtr hModule)) @@ -29,7 +29,7 @@ namespace CppWrapper.LibraryManagement throw new DllNotFoundException($"Unable to load library {LibraryPath}"); } - Application.CurrentApplication.Logger.Log($"Library {LibraryPath} loaded successfully [{hModule}]"); + Application.Logger.Log($"Library {LibraryPath} loaded successfully [{hModule}]"); LibraryHandle = hModule; } @@ -44,7 +44,7 @@ namespace CppWrapper.LibraryManagement NativeLibrary.Free(LibraryHandle); LibraryHandle = IntPtr.Zero; - Application.CurrentApplication.Logger.Log($"Library {LibraryPath} freed successfully"); + Application.Logger.Log($"Library {LibraryPath} freed successfully"); } private IntPtr GetFunctionPointer(string functionName) @@ -66,11 +66,11 @@ namespace CppWrapper.LibraryManagement { IntPtr functionPointer = GetFunctionPointer(methodName); - Application.CurrentApplication.Logger.Log($"Function pointer for {methodName} obtained successfully [address: {functionPointer}]"); + Application.Logger.Log($"Function pointer for {methodName} obtained successfully [address: {functionPointer}]"); T result = (T)Marshal.GetDelegateForFunctionPointer(functionPointer, typeof(T)); - Application.CurrentApplication.Logger.Log($"Delegate for {methodName} created successfully"); + Application.Logger.Log($"Delegate for {methodName} created successfully"); return result; } @@ -79,7 +79,7 @@ namespace CppWrapper.LibraryManagement { IntPtr functionPointer = Marshal.GetFunctionPointerForDelegate(functionDelegate); - Application.CurrentApplication.Logger.Log($"Function pointer for delegate {functionDelegate.Method.Name} obtained successfully [address: {functionPointer}]"); + Application.Logger.Log($"Function pointer for delegate {functionDelegate.Method.Name} obtained successfully [address: {functionPointer}]"); return functionPointer; } @@ -104,7 +104,7 @@ namespace CppWrapper.LibraryManagement var result = setterDelegate.DynamicInvoke(executableFunctionPtr); - Application.CurrentApplication.Logger.Log($"Function {setterExternFunctionName} bound to local action successfully"); + Application.Logger.Log($"Function {setterExternFunctionName} bound to local action successfully"); return result; } diff --git a/Plugins/DiscordBotUI/Entry.cs b/Plugins/DiscordBotUI/Entry.cs index 645d012..c71745c 100644 --- a/Plugins/DiscordBotUI/Entry.cs +++ b/Plugins/DiscordBotUI/Entry.cs @@ -48,7 +48,7 @@ public class Entry : ICommandAction externalLibrary.FreeLibrary(); } catch (Exception dllException) { - Application.CurrentApplication.Logger.LogException(dllException, this); + Application.Logger.LogException(dllException, this); } } } diff --git a/Plugins/LevelingSystem/LevelCommand.cs b/Plugins/LevelingSystem/LevelCommand.cs index e04feff..b60144f 100644 --- a/Plugins/LevelingSystem/LevelCommand.cs +++ b/Plugins/LevelingSystem/LevelCommand.cs @@ -5,7 +5,7 @@ using DiscordBotCore.Others; namespace LevelingSystem; -internal class LevelCommand: DBCommand +internal class LevelCommand: IDbCommand { public string Command => "level"; @@ -15,13 +15,13 @@ internal class LevelCommand: DBCommand public string Usage => "level"; - public bool requireAdmin => false; + public bool RequireAdmin => false; public async void ExecuteServer(DbCommandExecutingArguments args) { if(Variables.Database is null) { - Application.CurrentApplication.Logger.Log("Database is not initialized", this, LogType.Warning); + Application.Logger.Log("Database is not initialized", this, LogType.Warning); return; } diff --git a/Plugins/LevelingSystem/LevelEvent.cs b/Plugins/LevelingSystem/LevelEvent.cs index 8eec510..a1c0126 100644 --- a/Plugins/LevelingSystem/LevelEvent.cs +++ b/Plugins/LevelingSystem/LevelEvent.cs @@ -7,7 +7,7 @@ using static LevelingSystem.Variables; namespace LevelingSystem; -internal class LevelEvent : DBEvent +internal class LevelEvent : IDbEvent { public string Name => "Leveling System Event Handler"; public string Description => "The Leveling System Event Handler"; diff --git a/Plugins/MusicPlayer/Commands/AddMelody.cs b/Plugins/MusicPlayer/Commands/AddMelody.cs index ccfe5b0..2eadc6f 100644 --- a/Plugins/MusicPlayer/Commands/AddMelody.cs +++ b/Plugins/MusicPlayer/Commands/AddMelody.cs @@ -7,7 +7,7 @@ using DiscordBotCore.Others; namespace MusicPlayer.Commands; -public class AddMelody: DBCommand +public class AddMelody: IDbCommand { public string Command => "add_melody"; @@ -18,7 +18,7 @@ public class AddMelody: DBCommand public string Description => "Add a custom melody to the database"; public string Usage => "add_melody [title],[description?],[aliases],[byteSize]"; - public bool requireAdmin => false; + public bool RequireAdmin => false; public async void ExecuteServer(DbCommandExecutingArguments args) { diff --git a/Plugins/MusicPlayer/Commands/AddMelodyYoutube.cs b/Plugins/MusicPlayer/Commands/AddMelodyYoutube.cs index 7c5982f..e1f20bb 100644 --- a/Plugins/MusicPlayer/Commands/AddMelodyYoutube.cs +++ b/Plugins/MusicPlayer/Commands/AddMelodyYoutube.cs @@ -6,7 +6,7 @@ using DiscordBotCore.Others; namespace MusicPlayer.Commands; -public class AddMelodyYoutube: DBCommand +public class AddMelodyYoutube: IDbCommand { public string Command => "add_melody_youtube"; @@ -17,7 +17,7 @@ public class AddMelodyYoutube: DBCommand public string Description => "Add melody to the database from a youtube link"; public string Usage => "add_melody_youtube [URL] "; - public bool requireAdmin => true; + public bool RequireAdmin => true; public async void ExecuteServer(DbCommandExecutingArguments args) { diff --git a/Plugins/MusicPlayer/Commands/SearchMelody.cs b/Plugins/MusicPlayer/Commands/SearchMelody.cs index ea4e279..66f1044 100644 --- a/Plugins/MusicPlayer/Commands/SearchMelody.cs +++ b/Plugins/MusicPlayer/Commands/SearchMelody.cs @@ -4,14 +4,14 @@ using DiscordBotCore.Others; namespace MusicPlayer.Commands; -public class SearchMelody: DBCommand +public class SearchMelody: IDbCommand { public string Command => "search_melody"; public List? Aliases => null; public string Description => "Search for a melody in the database"; public string Usage => "search_melody [melody name OR one of its aliases]"; - public bool requireAdmin => false; + public bool RequireAdmin => false; public void ExecuteServer(DbCommandExecutingArguments args) { diff --git a/Plugins/MusicPlayer/Events/OnLoad.cs b/Plugins/MusicPlayer/Events/OnLoad.cs index 8d05a16..6b55388 100644 --- a/Plugins/MusicPlayer/Events/OnLoad.cs +++ b/Plugins/MusicPlayer/Events/OnLoad.cs @@ -5,7 +5,7 @@ using DiscordBotCore.Interfaces; namespace MusicPlayer.Events; -public class OnLoad: DBEvent +public class OnLoad: IDbEvent { private static readonly string _DefaultMusicPath = "Music/"; private static readonly string _DefaultSaveLocation = "Music/Melodies/"; diff --git a/Plugins/MusicPlayer/Events/OnVoiceRemoved.cs b/Plugins/MusicPlayer/Events/OnVoiceRemoved.cs index d3fbb3f..7dbfbdc 100644 --- a/Plugins/MusicPlayer/Events/OnVoiceRemoved.cs +++ b/Plugins/MusicPlayer/Events/OnVoiceRemoved.cs @@ -5,7 +5,7 @@ using DiscordBotCore.Others; namespace MusicPlayer.Events; -public class OnVoiceRemoved: DBEvent +public class OnVoiceRemoved: IDbEvent { public string Name => "Event: OnVoiceRemoved"; @@ -24,7 +24,7 @@ public class OnVoiceRemoved: DBEvent Variables.audioClient = null; Variables._MusicPlayer = null; - Application.CurrentApplication.Logger.Log("Bot left voice channel.", this, LogType.Info); + Application.Logger.Log("Bot left voice channel.", this, LogType.Info); } }; diff --git a/Plugins/MusicPlayer/MusicPlayer.cs b/Plugins/MusicPlayer/MusicPlayer.cs index ed7ddd2..11f8767 100644 --- a/Plugins/MusicPlayer/MusicPlayer.cs +++ b/Plugins/MusicPlayer/MusicPlayer.cs @@ -29,13 +29,13 @@ public class MusicPlayer { if (isQueueRunning) { - Application.CurrentApplication.Logger.Log("Another queue is running !", typeof(MusicPlayer), LogType.Warning); + Application.Logger.Log("Another queue is running !", typeof(MusicPlayer), LogType.Warning); return; } if (Variables.audioClient is null) { - Application.CurrentApplication.Logger.Log("Audio Client is null", typeof(MusicPlayer), LogType.Warning); + Application.Logger.Log("Audio Client is null", typeof(MusicPlayer), LogType.Warning); return; } @@ -44,7 +44,7 @@ public class MusicPlayer string? ffmpegPath = await Application.CurrentApplication.PluginManager.GetDependencyLocation("FFMPEG"); if(ffmpegPath is null) { - Application.CurrentApplication.Logger.Log("FFMPEG is missing. Please install it and try again.", typeof(MusicPlayer), LogType.Error); + Application.Logger.Log("FFMPEG is missing. Please install it and try again.", typeof(MusicPlayer), LogType.Error); isQueueRunning = false; return; } @@ -61,7 +61,7 @@ public class MusicPlayer using var ffmpeg = CreateStream(ffmpegPath, CurrentlyPlaying.Location); if (ffmpeg is null) { - Application.CurrentApplication.Logger.Log($"Failed to start ffmpeg process. FFMPEG is missing or the {CurrentlyPlaying.Location} has an invalid format.", typeof(MusicPlayer), LogType.Error); + Application.Logger.Log($"Failed to start ffmpeg process. FFMPEG is missing or the {CurrentlyPlaying.Location} has an invalid format.", typeof(MusicPlayer), LogType.Error); continue; } await using var ffmpegOut = ffmpeg.StandardOutput.BaseStream; @@ -111,7 +111,7 @@ public class MusicPlayer } catch (Exception ex) { - Application.CurrentApplication.Logger.LogException(ex, this); + Application.Logger.LogException(ex, this); break; } } diff --git a/Plugins/MusicPlayer/SlashCommands/Loop.cs b/Plugins/MusicPlayer/SlashCommands/Loop.cs index d16bfe6..6e5249e 100644 --- a/Plugins/MusicPlayer/SlashCommands/Loop.cs +++ b/Plugins/MusicPlayer/SlashCommands/Loop.cs @@ -4,12 +4,12 @@ using DiscordBotCore.Interfaces; namespace MusicPlayer.SlashCommands; -public class Loop: DBSlashCommand +public class Loop: IDbSlashCommand { public string Name => "loop"; public string Description => "Loop the current song for a certain amount of times. If no times are specified, it will loop once"; - public bool canUseDM => false; + public bool CanUseDm => false; public bool HasInteraction => false; public List Options => new() diff --git a/Plugins/MusicPlayer/SlashCommands/Play.cs b/Plugins/MusicPlayer/SlashCommands/Play.cs index 3547cbc..4118727 100644 --- a/Plugins/MusicPlayer/SlashCommands/Play.cs +++ b/Plugins/MusicPlayer/SlashCommands/Play.cs @@ -7,11 +7,11 @@ using DiscordBotCore.Others; namespace MusicPlayer.SlashCommands; -public class Play: DBSlashCommand +public class Play: IDbSlashCommand { public string Name => "play"; public string Description => "Play music command"; - public bool canUseDM => false; + public bool CanUseDm => false; public bool HasInteraction => false; public List Options => new() @@ -55,7 +55,7 @@ public class Play: DBSlashCommand if (user is null) { await context.RespondAsync("Failed to get user data from channel ! Check error log at " + DateTime.Now.ToLongTimeString()); - Application.CurrentApplication.Logger.Log("User is null while trying to convert from context.User to IGuildUser.", typeof(Play), LogType.Error); + Application.Logger.Log("User is null while trying to convert from context.User to IGuildUser.", typeof(Play), LogType.Error); return; } diff --git a/Plugins/MusicPlayer/SlashCommands/Queue.cs b/Plugins/MusicPlayer/SlashCommands/Queue.cs index 601e235..48aa72d 100644 --- a/Plugins/MusicPlayer/SlashCommands/Queue.cs +++ b/Plugins/MusicPlayer/SlashCommands/Queue.cs @@ -4,11 +4,11 @@ using DiscordBotCore.Interfaces; namespace MusicPlayer.SlashCommands; -public class Queue: DBSlashCommand +public class Queue: IDbSlashCommand { public string Name => "queue"; public string Description => "Queue a melody to play"; - public bool canUseDM => false; + public bool CanUseDm => false; public bool HasInteraction => false; public List Options => null; diff --git a/Plugins/MusicPlayer/SlashCommands/Skip.cs b/Plugins/MusicPlayer/SlashCommands/Skip.cs index 2cbea24..fcb1448 100644 --- a/Plugins/MusicPlayer/SlashCommands/Skip.cs +++ b/Plugins/MusicPlayer/SlashCommands/Skip.cs @@ -4,11 +4,11 @@ using DiscordBotCore.Interfaces; namespace MusicPlayer.SlashCommands; -public class Skip: DBSlashCommand +public class Skip: IDbSlashCommand { public string Name => "skip"; public string Description => "Skip the current melody"; - public bool canUseDM => false; + public bool CanUseDm => false; public bool HasInteraction => false; public List Options => null;