More fixes to the new config. Module loader reworked

This commit is contained in:
2024-08-06 22:47:59 +03:00
parent 27e25a9166
commit 18a059af0e
51 changed files with 390 additions and 301 deletions

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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
);
}

View File

@@ -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<object> 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);
}
}

View File

@@ -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;
}

View File

@@ -10,7 +10,7 @@ namespace DiscordBot.Bot.Commands;
/// <summary>
/// The help command
/// </summary>
internal class Help: DBCommand
internal class Help: IDbCommand
{
/// <summary>
/// Command name
@@ -32,7 +32,7 @@ internal class Help: DBCommand
/// <summary>
/// Check if the command require administrator to be executed
/// </summary>
public bool requireAdmin => false;
public bool RequireAdmin => false;
/// <summary>
/// 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 + " ";

View File

@@ -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);
}

View File

@@ -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));
}
}

View File

@@ -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") ||

View File

@@ -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<ILogger>();
}
catch (ModuleNotFoundException<ILogger> 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<Type, List<object>> 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<string> outFunction)
{
var loggerModule = CurrentApplication._ModuleManager.GetModule(ModuleType.Logger);
await CurrentApplication._ModuleManager.InvokeMethod(loggerModule.Value, loggerModule.Key.MethodMapping["SetPrintFunction"], [outFunction]);
}
}
public ReadOnlyDictionary<ModuleData, IModule> GetLoadedCoreModules() => _ModuleManager.Modules.AsReadOnly();
public static string GetResourceFullPath(string path)
{

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -3,7 +3,7 @@ using DiscordBotCore.Others;
namespace DiscordBotCore.Interfaces;
public interface DBCommand
public interface IDbCommand
{
/// <summary>
/// Command to be executed
@@ -30,7 +30,7 @@ public interface DBCommand
/// <summary>
/// true if the command requre admin, otherwise false
/// </summary>
bool requireAdmin { get; }
bool RequireAdmin { get; }
/// <summary>
/// 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
/// </summary>
/// <param name="args">The disocrd Context</param>
void ExecuteDM(DbCommandExecutingArguments args)
void ExecuteDm(DbCommandExecutingArguments args)
{
}
}

View File

@@ -2,7 +2,7 @@
namespace DiscordBotCore.Interfaces;
public interface DBEvent
public interface IDbEvent
{
/// <summary>
/// The name of the event

View File

@@ -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<SlashCommandOptionBuilder> 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;
}

View File

@@ -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; }
}
}

View File

@@ -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<string> outFunction);
}
}

View File

@@ -1,8 +0,0 @@
using System;
namespace DiscordBotCore.Interfaces.Modules
{
public interface IBaseModule
{
}
}

View File

@@ -2,10 +2,20 @@
namespace DiscordBotCore.Interfaces.Modules
{
public interface IModule<T> where T : IBaseModule
public enum ModuleType
{
Logger,
Other
}
/// <summary>
/// Define a module.
/// </summary>
public interface IModule
{
public ModuleType ModuleType { get; }
public string Name { get; }
public T Module { get; }
public Task Initialize();
}
}

View File

@@ -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<OnlineScriptDependencyInfo> listOfDependencies);
@@ -24,7 +23,6 @@ namespace DiscordBotCore.Interfaces.PluginManager
Task<bool> MarkPluginToUninstall(string pluginName);
Task RemovePluginFromDatabase(string pluginName);
Task UninstallMarkedPlugins();
Task SetEnabledStatus(string pluginName, bool status);
}
}

View File

@@ -35,9 +35,9 @@ internal class Loader
}
}
await LoadEverythingOfType<DBEvent>();
await LoadEverythingOfType<DBCommand>();
await LoadEverythingOfType<DBSlashCommand>();
await LoadEverythingOfType<IDbEvent>();
await LoadEverythingOfType<IDbCommand>();
await LoadEverythingOfType<IDbSlashCommand>();
await LoadEverythingOfType<ICommandAction>();
}
@@ -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
};

View File

@@ -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> _ModuleData;
public ModuleLoader(string moduleFolder)
public ModuleLoader(List<ModuleData> 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<List<IModule<T>>> LoadModules<T>() where T : IBaseModule
public Task<List<IModule>> LoadModules()
{
var moduleType = typeof(IModule<T>);
var moduleType = typeof(IModule);
var moduleTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => moduleType.IsAssignableFrom(p) && !p.IsInterface);
var modules = new List<IModule<T>>();
var modules = new List<IModule>();
foreach (var module in moduleTypes)
{
try
{
var instance = (IModule<T>?)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;

View File

@@ -26,9 +26,9 @@ public class PluginLoader
public SlashCommandLoaded? OnSlashCommandLoaded;
public ActionLoaded? OnActionLoaded;
public static List<DBCommand> Commands { get; private set; } = new List<DBCommand>();
public static List<DBEvent> Events { get; private set; } = new List<DBEvent>();
public static List<DBSlashCommand> SlashCommands { get; private set; } = new List<DBSlashCommand>();
public static List<IDbCommand> Commands { get; private set; } = new List<IDbCommand>();
public static List<IDbEvent> Events { get; private set; } = new List<IDbEvent>();
public static List<IDbSlashCommand> SlashCommands { get; private set; } = new List<IDbSlashCommand>();
public static List<ICommandAction> Actions { get; private set; } = new List<ICommandAction>();
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;
}
}

View File

@@ -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<bool> TryStartSlashCommand(this PluginLoader pluginLoader, DBSlashCommand? dbSlashCommand)
internal static async Task<bool> 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;
}

View File

@@ -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<string, string> MethodMapping { get; set; }
public ModuleData(string moduleName, string modulePath, IDictionary<string, string> methodMapping, bool isEnabled)
{
ModuleName = moduleName;
ModulePath = modulePath;
MethodMapping = methodMapping;
IsEnabled = isEnabled;
}
}

View File

@@ -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<float> progressToWrite)
{
Directory.CreateDirectory(_moduleFolder);
string url = _baseUrl + _moduleName + ".dll";
await ServerCom.DownloadFileAsync(url, _moduleFolder + "/" + _moduleName + ".dll", progressToWrite);
string? moduleFolder = Application.CurrentApplication.ApplicationEnvironmentVariables.Get<string>("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);
}
}
}

View File

@@ -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<Type, List<object>> LoadedModules { get; }
public ModuleManager(string moduleFolder)
{
_ModuleFolder = moduleFolder;
LoadedModules = new Dictionary<Type, List<object>>();
}
private static readonly string _BaseModuleConfig = "./Data/Resources/modules.json";
internal Dictionary<ModuleData, IModule> Modules { get; set; }
public ModuleManager()
{
_ModuleFolder = Application.CurrentApplication.ApplicationEnvironmentVariables.Get<string>("ModuleFolder", _BaseModuleFolder);
LoadedModules = new Dictionary<Type, List<object>>();
Application.CurrentApplication.ApplicationEnvironmentVariables.Get<string>("ModuleFolder", _BaseModuleFolder);
Modules = new Dictionary<ModuleData, IModule>();
}
public T GetModule<T>() where T : IBaseModule
public KeyValuePair<ModuleData, IModule> GetModule(string moduleName)
{
if(!LoadedModules.ContainsKey(typeof(T)))
throw new ModuleNotFoundException<T>();
if (!LoadedModules[typeof(T)].Any())
throw new ModuleNotFoundException<T>();
IModule<T> module = (IModule<T>)LoadedModules[typeof(T)][0];
return module.Module;
return Modules.FirstOrDefault(module => module.Key.ModuleName == moduleName);
}
public KeyValuePair<ModuleData, IModule> 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<string>("ModuleConfig", _BaseModuleConfig);
var loggers = await loader.LoadModules<ILogger>();
foreach (var logger in loggers)
string moduleConfigFile = await File.ReadAllTextAsync(moduleConfigPath);
List<ModuleData>? listOfModuleData = JsonConvert.DeserializeObject<List<ModuleData>>(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<object>().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));
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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<string, obj
public override List<T> GetList<T>(string key, List<T> defaultValue)
{
List<T> result = base.GetList(key, defaultValue);
if (_EnableAutoAddOnGetWithDefault && defaultValue.All(result.Contains))
List<T> 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<string, obj
else if (kvp.Value is JArray nestedJArray)
{
dict[kvp.Key] = nestedJArray.ToObject<List<object>>();
}
else
{
dict[kvp.Key] = kvp.Value;
if (kvp.Value.Type == JTokenType.Integer)
dict[kvp.Key] = kvp.Value.Value<int>();
else if (kvp.Value.Type == JTokenType.Float)
dict[kvp.Key] = kvp.Value.Value<float>();
else if (kvp.Value.Type == JTokenType.Boolean)
dict[kvp.Key] = kvp.Value.Value<bool>();
else if (kvp.Value.Type == JTokenType.String)
dict[kvp.Key] = kvp.Value.Value<string>();
else if (kvp.Value.Type == JTokenType.Date)
dict[kvp.Key] = kvp.Value.Value<DateTime>();
else
dict[kvp.Key] = kvp.Value;
}
}

View File

@@ -56,6 +56,27 @@ public abstract class CustomSettingsDictionaryBase<TKey,TValue> : ICustomSetting
return default;
}
public virtual IDictionary<TSubKey, TSubValue> GetDictionary<TSubKey, TSubValue>(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<TSubKey, TSubValue>();
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<TSubKey, TSubValue>();
}
public virtual List<T> GetList<T>(TKey key, List<T> defaultValue)
{
@@ -67,9 +88,9 @@ public abstract class CustomSettingsDictionaryBase<TKey,TValue> : ICustomSetting
}
var list = new List<T>();
foreach (var item in (IList)value)
foreach (object? item in (IList)value)
{
list.Add(ConvertValue<T>(item));
list.Add((T)Convert.ChangeType(item, typeof(T)));
}
return list;
@@ -141,20 +162,4 @@ public abstract class CustomSettingsDictionaryBase<TKey,TValue> : ICustomSetting
public abstract Task SaveToFile();
public abstract Task LoadFromFile();
protected virtual T? ConvertValue<T>(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));
}
}

View File

@@ -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<ILogger>
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<string> 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);
}
}

View File

@@ -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; }
}

View File

@@ -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<string> outFunction);
}

View File

@@ -1,5 +1,4 @@
using DiscordBotCore.Interfaces.Logger;
using DiscordBotCore.Others;
using DiscordBotCore.Others;
namespace LoggerModule
{

View File

@@ -1,5 +1,4 @@
using DiscordBotCore.Interfaces.Logger;
using DiscordBotCore.Others;
using DiscordBotCore.Others;
namespace LoggerModule;

View File

@@ -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;
}

View File

@@ -48,7 +48,7 @@ public class Entry : ICommandAction
externalLibrary.FreeLibrary();
} catch (Exception dllException) {
Application.CurrentApplication.Logger.LogException(dllException, this);
Application.Logger.LogException(dllException, this);
}
}
}

View File

@@ -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;
}

View File

@@ -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";

View File

@@ -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)
{

View File

@@ -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] <alias1|alias2|...>";
public bool requireAdmin => true;
public bool RequireAdmin => true;
public async void ExecuteServer(DbCommandExecutingArguments args)
{

View File

@@ -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<string>? 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)
{

View File

@@ -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/";

View File

@@ -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);
}
};

View File

@@ -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;
}
}

View File

@@ -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<SlashCommandOptionBuilder> Options => new()

View File

@@ -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<SlashCommandOptionBuilder> 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;
}

View File

@@ -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<SlashCommandOptionBuilder> Options => null;

View File

@@ -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<SlashCommandOptionBuilder> Options => null;