diff --git a/DiscordBot/Bot/Actions/Clear.cs b/DiscordBot/Bot/Actions/Clear.cs new file mode 100644 index 0000000..b024c75 --- /dev/null +++ b/DiscordBot/Bot/Actions/Clear.cs @@ -0,0 +1,20 @@ +using System; +using System.Threading.Tasks; +using PluginManager.Interfaces; +using PluginManager.Others; + +namespace DiscordBot.Bot.Actions; + +public class Clear : ICommandAction +{ + public string ActionName => "clear"; + public string Description => "Clears the console"; + public string Usage => "clear"; + public InternalActionRunType RunType => InternalActionRunType.ON_CALL; + + public Task Execute(string[] args) + { + Console.Clear(); + return Task.CompletedTask; + } +} diff --git a/DiscordBot/Bot/Actions/Exit.cs b/DiscordBot/Bot/Actions/Exit.cs index 69230f5..511b540 100644 --- a/DiscordBot/Bot/Actions/Exit.cs +++ b/DiscordBot/Bot/Actions/Exit.cs @@ -8,15 +8,16 @@ namespace DiscordBot.Bot.Actions; public class Exit : ICommandAction { - public string ActionName => "exit"; - public string Description => "Exits the bot and saves the config. Use exit help for more info."; - public string Usage => "exit [help|force]"; - public InternalActionRunType RunType => InternalActionRunType.ON_CALL; + public string ActionName => "exit"; + public string Description => "Exits the bot and saves the config. Use exit help for more info."; + public string Usage => "exit [help|force]"; + public InternalActionRunType RunType => InternalActionRunType.ON_CALL; + public async Task Execute(string[] args) { if (args is null || args.Length == 0) { - Config.Logger.Log("Exiting...", "Exit", LogLevel.INFO); + Config.Logger.Log("Exiting...", "Exit"); Config.Data.Save(); Environment.Exit(0); } @@ -29,12 +30,12 @@ public class Exit : ICommandAction Console.WriteLine("help : Displays this message"); Console.WriteLine("force : Exits the bot without saving the config"); break; - + case "force": - Config.Logger.Log("Exiting...", "Exit", LogLevel.INFO); + Config.Logger.Log("Exiting...", "Exit"); Environment.Exit(0); break; - + default: Console.WriteLine("Invalid argument !"); break; diff --git a/DiscordBot/Bot/Actions/Help.cs b/DiscordBot/Bot/Actions/Help.cs index 441fff6..efcb4e2 100644 --- a/DiscordBot/Bot/Actions/Help.cs +++ b/DiscordBot/Bot/Actions/Help.cs @@ -1,62 +1,60 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; - -using PluginManager.Others; +using DiscordBot.Utilities; using PluginManager.Interfaces; +using PluginManager.Others; -namespace DiscordBot.Bot.Actions +namespace DiscordBot.Bot.Actions; + +public class Help : ICommandAction { - public class Help : ICommandAction + public string ActionName => "help"; + + public string Description => "Shows the list of commands and their usage"; + + public string Usage => "help [command]"; + + public InternalActionRunType RunType => InternalActionRunType.ON_CALL; + + public async Task Execute(string[] args) { - public string ActionName => "help"; - - public string Description => "Shows the list of commands and their usage"; - - public string Usage => "help [command]"; - - public InternalActionRunType RunType => InternalActionRunType.ON_CALL; - - public async Task Execute(string[] args) + if (args == null || args.Length == 0) { - if (args == null || args.Length == 0) + var items = new List { - var items = new List - { - new[] { "-", "-", "-" }, - new[] { "Command", "Usage", "Description" }, - new[] { "-", "-", "-" } - }; + new[] { "-", "-", "-" }, + new[] { "Command", "Usage", "Description" }, + new[] { "-", "-", "-" } + }; - foreach (var a in Program.internalActionManager.Actions) - { - items.Add(new[] { a.Key, a.Value.Usage, a.Value.Description }); - } + foreach (var a in Program.internalActionManager.Actions) + items.Add(new[] { a.Key, a.Value.Usage, a.Value.Description }); - items.Add(new[] { "-", "-", "-" }); + items.Add(new[] { "-", "-", "-" }); - DiscordBot.Utilities.Utilities.FormatAndAlignTable(items, Utilities.TableFormat.CENTER_EACH_COLUMN_BASED); - return; - } - - if (!Program.internalActionManager.Actions.ContainsKey(args[0])) - { - Console.WriteLine("Command not found"); - return; - } - - var action = Program.internalActionManager.Actions[args[0]]; - var actionData = new List - { - new[] { "-", "-", "-" }, - new[] { "Command", "Usage", "Description" }, - new[] { "-", "-", "-"}, - new[] { action.ActionName, action.Usage, action.Description }, - new[] { "-", "-", "-" } - }; - - DiscordBot.Utilities.Utilities.FormatAndAlignTable(actionData, Utilities.TableFormat.CENTER_EACH_COLUMN_BASED); + Utilities.Utilities.FormatAndAlignTable(items, + TableFormat.CENTER_EACH_COLUMN_BASED); + return; } + + if (!Program.internalActionManager.Actions.ContainsKey(args[0])) + { + Console.WriteLine("Command not found"); + return; + } + + var action = Program.internalActionManager.Actions[args[0]]; + var actionData = new List + { + new[] { "-", "-", "-" }, + new[] { "Command", "Usage", "Description" }, + new[] { "-", "-", "-" }, + new[] { action.ActionName, action.Usage, action.Description }, + new[] { "-", "-", "-" } + }; + + Utilities.Utilities.FormatAndAlignTable(actionData, + TableFormat.CENTER_EACH_COLUMN_BASED); } -} \ No newline at end of file +} diff --git a/DiscordBot/Bot/Actions/Plugin.cs b/DiscordBot/Bot/Actions/Plugin.cs index 26b568b..1d4228a 100644 --- a/DiscordBot/Bot/Actions/Plugin.cs +++ b/DiscordBot/Bot/Actions/Plugin.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using DiscordBot.Utilities; +using PluginManager; using PluginManager.Interfaces; using PluginManager.Loaders; using PluginManager.Online; @@ -10,12 +12,11 @@ namespace DiscordBot.Bot.Actions; public class Plugin : ICommandAction { - public string ActionName => "plugin"; - public string Description => "Manages plugins. Use plugin help for more info."; - public string Usage => "plugin [help|list|load|install]"; - public InternalActionRunType RunType => InternalActionRunType.ON_CALL; - - private bool pluginsLoaded = false; + private bool pluginsLoaded; + public string ActionName => "plugin"; + public string Description => "Manages plugins. Use plugin help for more info."; + public string Usage => "plugin [help|list|load|install]"; + public InternalActionRunType RunType => InternalActionRunType.ON_CALL; public async Task Execute(string[] args) { @@ -33,32 +34,30 @@ public class Plugin : ICommandAction switch (args[0]) { case "list": - var manager = new PluginManager.Online.PluginsManager(Program.URLs["PluginList"], Program.URLs["PluginVersions"]); + var manager = + new PluginsManager(Program.URLs["PluginList"], Program.URLs["PluginVersions"]); var data = await manager.GetAvailablePlugins(); var items = new List { new[] { "-", "-", "-", "-" }, - new[] { "Name", "Type", "Description", "Required" }, + new[] { "Name", "Description", "Type", "Version" }, new[] { "-", "-", "-", "-" } }; - foreach (var plugin in data) - { - items.Add(new[] { plugin[0], plugin[1], plugin[2], plugin[3] }); - } + foreach (var plugin in data) items.Add(new[] { plugin[0], plugin[1], plugin[2], plugin[3] }); items.Add(new[] { "-", "-", "-", "-" }); - Utilities.Utilities.FormatAndAlignTable(items, Utilities.TableFormat.DEFAULT); + Utilities.Utilities.FormatAndAlignTable(items, TableFormat.DEFAULT); break; - - + + case "load": if (pluginsLoaded) break; - var loader = new PluginLoader(PluginManager.Config.DiscordBot.client); - var cc = Console.ForegroundColor; + var loader = new PluginLoader(Config.DiscordBot.client); + var cc = Console.ForegroundColor; loader.onCMDLoad += (name, typeName, success, exception) => { if (name == null || name.Length < 2) @@ -122,33 +121,34 @@ public class Plugin : ICommandAction loader.LoadPlugins(); Console.ForegroundColor = cc; - pluginsLoaded = true; + pluginsLoaded = true; break; - + case "install": - string pluginName = string.Join(' ', args, 1, args.Length-1); - if (string.IsNullOrEmpty(pluginName)|| pluginName.Length < 2) + var pluginName = string.Join(' ', args, 1, args.Length - 1); + if (string.IsNullOrEmpty(pluginName) || pluginName.Length < 2) { Console.WriteLine("Please specify a plugin name"); break; } - - var pluginManager = new PluginManager.Online.PluginsManager(Program.URLs["PluginList"], Program.URLs["PluginVersions"]); - string[] pluginData = await pluginManager.GetPluginLinkByName(pluginName); + + var pluginManager = + new PluginsManager(Program.URLs["PluginList"], Program.URLs["PluginVersions"]); + var pluginData = await pluginManager.GetPluginLinkByName(pluginName); if (pluginData == null || pluginData.Length == 0) { Console.WriteLine("Plugin not found"); break; } - string pluginType = pluginData[0]; - string pluginLink = pluginData[1]; - string pluginRequirements = pluginData[2]; - - + var pluginType = pluginData[0]; + var pluginLink = pluginData[1]; + var pluginRequirements = pluginData[2]; + + Console.WriteLine("Downloading plugin..."); //download plugin progress bar for linux and windows terminals - Utilities.Utilities.Spinner spinner = new Utilities.Utilities.Spinner(); + var spinner = new Utilities.Utilities.Spinner(); spinner.Start(); await ServerCom.DownloadFileAsync(pluginLink, $"./Data/{pluginType}s/{pluginName}.dll", null); spinner.Stop(); @@ -159,18 +159,18 @@ public class Plugin : ICommandAction Console.WriteLine("Plugin installed successfully"); break; } - + Console.WriteLine("Downloading plugin requirements..."); - List requirementsURLs = await ServerCom.ReadTextFromURL(pluginRequirements); + var requirementsURLs = await ServerCom.ReadTextFromURL(pluginRequirements); foreach (var requirement in requirementsURLs) { - if(requirement.Length < 2) + if (requirement.Length < 2) continue; - string[] reqdata = requirement.Split(','); - string url = reqdata[0]; - string filename = reqdata[1]; - + var reqdata = requirement.Split(','); + var url = reqdata[0]; + var filename = reqdata[1]; + Console.WriteLine($"Downloading {filename}... "); spinner.Start(); @@ -179,7 +179,7 @@ public class Plugin : ICommandAction await Task.Delay(1000); Console.WriteLine("Downloaded " + filename + " successfully"); } - + Console.WriteLine("Finished installing " + pluginName + " successfully"); break; diff --git a/DiscordBot/Bot/Commands/NormalCommands/Help.cs b/DiscordBot/Bot/Commands/NormalCommands/Help.cs index 2434521..d472837 100644 --- a/DiscordBot/Bot/Commands/NormalCommands/Help.cs +++ b/DiscordBot/Bot/Commands/NormalCommands/Help.cs @@ -1,7 +1,5 @@ using System.Collections.Generic; - using Discord; - using PluginManager; using PluginManager.Interfaces; using PluginManager.Loaders; @@ -56,7 +54,7 @@ internal class Help : DBCommand var embedBuilder = new EmbedBuilder(); - var adminCommands = ""; + var adminCommands = ""; var normalCommands = ""; foreach (var cmd in PluginLoader.Commands) @@ -77,7 +75,7 @@ internal class Help : DBCommand { var embedBuilder = new EmbedBuilder(); var cmd = PluginLoader.Commands.Find(p => p.Command == command || - (p.Aliases is not null && p.Aliases.Contains(command))); + (p.Aliases is not null && p.Aliases.Contains(command))); if (cmd == null) return null; embedBuilder.AddField("Usage", Config.Data["prefix"] + cmd.Usage); diff --git a/DiscordBot/Bot/Commands/SlashCommands/Help.cs b/DiscordBot/Bot/Commands/SlashCommands/Help.cs index f31c91f..7f1599d 100644 --- a/DiscordBot/Bot/Commands/SlashCommands/Help.cs +++ b/DiscordBot/Bot/Commands/SlashCommands/Help.cs @@ -1,30 +1,28 @@ -using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using Discord; using Discord.WebSocket; using PluginManager.Interfaces; +using PluginManager.Loaders; using PluginManager.Others; - - namespace DiscordBot.Bot.Commands.SlashCommands; public class Help : DBSlashCommand { - public string Name => "help"; + 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 List Options => new() - { - new SlashCommandOptionBuilder() - .WithName("command") - .WithDescription("The command you want to get help for") - .WithRequired(false) - .WithType(ApplicationCommandOptionType.String) - }; + public List Options => + new() + { + new SlashCommandOptionBuilder() + .WithName("command") + .WithDescription("The command you want to get help for") + .WithRequired(false) + .WithType(ApplicationCommandOptionType.String) + }; public async void ExecuteServer(SocketSlashCommand context) { @@ -32,31 +30,28 @@ public class Help : DBSlashCommand embedBuilder.WithTitle("Help Command"); embedBuilder.WithColor(Functions.RandomColor); - var slashCommands = PluginManager.Loaders.PluginLoader.SlashCommands; - var options = context.Data.Options; - + var slashCommands = PluginLoader.SlashCommands; + var options = context.Data.Options; + //Console.WriteLine("Options: " + options.Count); if (options is null || options.Count == 0) - { foreach (var slashCommand in slashCommands) - { embedBuilder.AddField(slashCommand.Name, slashCommand.Description, true); - } - } if (options.Count > 0) { - string commandName = options.First().Name; + var commandName = options.First().Name; var slashCommand = slashCommands.FirstOrDefault(x => x.Name == commandName); if (slashCommand is null) { await context.RespondAsync("Unknown Command " + commandName); return; } - - embedBuilder.AddField(slashCommand.Name, slashCommand.canUseDM,true).WithDescription(slashCommand.Description); + + embedBuilder.AddField(slashCommand.Name, slashCommand.canUseDM, true) + .WithDescription(slashCommand.Description); } await context.RespondAsync(embed: embedBuilder.Build()); } -} \ No newline at end of file +} diff --git a/DiscordBot/DiscordBot.csproj b/DiscordBot/DiscordBot.csproj index 81fe610..a460a06 100644 --- a/DiscordBot/DiscordBot.csproj +++ b/DiscordBot/DiscordBot.csproj @@ -1,39 +1,39 @@ - - Exe - net6.0 - disable - - - False - True - 1.0.2.2 - - - none - - - none - - - - - - - - - - - - - - - - - - - - - - + + Exe + net6.0 + disable + + + False + True + 1.0.2.2 + + + none + + + none + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DiscordBot/Entry.cs b/DiscordBot/Entry.cs index 43219bb..d5df92f 100644 --- a/DiscordBot/Entry.cs +++ b/DiscordBot/Entry.cs @@ -1,32 +1,27 @@ -using PluginManager.Others; -using System; +using System; using System.IO; -using System.Linq; using System.Reflection; -using System.Threading.Tasks; -namespace DiscordBot +namespace DiscordBot; + +public class Entry { - - public class Entry + public static void Main(string[] args) { - public static void Main(string[] args) + var currentDomain = AppDomain.CurrentDomain; + currentDomain.AssemblyResolve += LoadFromSameFolder; + + static Assembly LoadFromSameFolder(object sender, ResolveEventArgs args) { - AppDomain currentDomain = AppDomain.CurrentDomain; - currentDomain.AssemblyResolve += new ResolveEventHandler(LoadFromSameFolder); - - static Assembly LoadFromSameFolder(object sender, ResolveEventArgs args) - { - string folderPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "./Libraries"); - string assemblyPath = Path.Combine(folderPath, new AssemblyName(args.Name).Name + ".dll"); - if (!File.Exists(assemblyPath)) return null; - Assembly assembly = Assembly.LoadFrom(assemblyPath); - - return assembly; - } - - Program.Startup(args); + var folderPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + "./Libraries"); + var assemblyPath = Path.Combine(folderPath, new AssemblyName(args.Name).Name + ".dll"); + if (!File.Exists(assemblyPath)) return null; + var assembly = Assembly.LoadFrom(assemblyPath); + return assembly; } + + Program.Startup(args); } } diff --git a/DiscordBot/Installer.cs b/DiscordBot/Installer.cs index f480d66..74c3aa6 100644 --- a/DiscordBot/Installer.cs +++ b/DiscordBot/Installer.cs @@ -1,96 +1,89 @@ -using System.Diagnostics; -using System.IO; using System; -using System.Collections.Generic; -using System.Linq; +using System.IO; using System.Threading.Tasks; using PluginManager; -using PluginManager.Others; using PluginManager.Online; -namespace DiscordBot +namespace DiscordBot; + +public static class Installer { - public static class Installer + public static void GenerateStartupConfig() { + Console.WriteLine("Welcome to the SethBot installer !"); + Console.WriteLine("First, we need to configure the bot. Don't worry, it will be quick !"); + Console.WriteLine("The following information will be stored in the config.json file in the ./Data/Resources folder. You can change it later from there."); + Console.WriteLine("The bot token is required to run the bot. You can get it from the Discord Developer Portal. (https://discord.com/developers/applications)"); - public static void GenerateStartupConfig() + if (!Config.Data.ContainsKey("token")) { - Console.WriteLine("Welcome to the SethBot installer !"); - Console.WriteLine("First, we need to configure the bot. Don't worry, it will be quick !"); - Console.WriteLine("The following information will be stored in the config.json file in the ./Data/Resources folder. You can change it later from there."); - Console.WriteLine("The bot token is required to run the bot. You can get it from the Discord Developer Portal. (https://discord.com/developers/applications)"); - - if (!Config.Data.ContainsKey("token")) - { - Console.WriteLine("Please enter the bot token :"); - var token = Console.ReadLine(); - Config.Data.Add("token", token); - } - - if (!Config.Data.ContainsKey("prefix")) - { - Console.WriteLine("Please enter the bot prefix :"); - var prefix = Console.ReadLine(); - Config.Data.Add("prefix", prefix); - } - - if (!Config.Data.ContainsKey("ServerID")) - { - Console.WriteLine("Please enter the Server ID :"); - var serverId = Console.ReadLine(); - Config.Data.Add("ServerID", serverId); - } - - Config.Logger.Log("Config Saved", "Installer", LogLevel.INFO); - - Config.Data.Save(); - - Console.WriteLine("Config saved !"); - - + Console.WriteLine("Please enter the bot token :"); + var token = Console.ReadLine(); + Config.Data.Add("token", token); } - public static async Task SetupPluginDatabase() + if (!Config.Data.ContainsKey("prefix")) { - Console.WriteLine("The plugin database is required to run the bot but there is nothing configured yet."); - Console.WriteLine("Please select one option : "); - Console.WriteLine("1. Download the official database file"); - Console.WriteLine("2. Create a new (CUSTOM) database file"); - int choice = 0; - Console.Write("Choice : "); - choice = int.Parse(Console.ReadLine()); - if (choice != 1 && choice != 2) + Console.WriteLine("Please enter the bot prefix :"); + var prefix = Console.ReadLine(); + Config.Data.Add("prefix", prefix); + } + + if (!Config.Data.ContainsKey("ServerID")) + { + Console.WriteLine("Please enter the Server ID :"); + var serverId = Console.ReadLine(); + Config.Data.Add("ServerID", serverId); + } + + Config.Logger.Log("Config Saved", "Installer"); + + Config.Data.Save(); + + Console.WriteLine("Config saved !"); + } + + public static async Task SetupPluginDatabase() + { + Console.WriteLine("The plugin database is required to run the bot but there is nothing configured yet."); + Console.WriteLine("Please select one option : "); + Console.WriteLine("1. Download the official database file"); + Console.WriteLine("2. Create a new (CUSTOM) database file"); + var choice = 0; + Console.Write("Choice : "); + choice = int.Parse(Console.ReadLine()); + if (choice != 1 && choice != 2) + { + Console.WriteLine("Invalid choice !"); + Console.WriteLine("Please restart the installer !"); + Console.ReadKey(); + Environment.Exit(0); + } + + if (choice == 1) + await DownloadPluginDatabase(); + + if (choice == 2) + { + Console.WriteLine("Do you have a url to a valid database file ? (y/n)"); + var answer = Console.ReadLine(); + if (answer == "y") { - Console.WriteLine("Invalid choice !"); - Console.WriteLine("Please restart the installer !"); - Console.ReadKey(); - Environment.Exit(0); + Console.WriteLine("Please enter the url :"); + var url = Console.ReadLine(); + await DownloadPluginDatabase(url); + return; } - if (choice == 1) - await DownloadPluginDatabase(); - - if (choice == 2) + Console.WriteLine("Do you want to create a new database file ? (y/n)"); + answer = Console.ReadLine(); + if (answer == "y") { - Console.WriteLine("Do you have a url to a valid database file ? (y/n)"); - var answer = Console.ReadLine(); - if (answer == "y") - { - Console.WriteLine("Please enter the url :"); - var url = Console.ReadLine(); - await DownloadPluginDatabase(url); - return; - } - - Console.WriteLine("Do you want to create a new database file ? (y/n)"); - answer = Console.ReadLine(); - if (answer == "y") - { - Console.WriteLine("A new file will be generated at ./Data/Resources/URLs.json"); - System.Console.WriteLine("Please edit the file and restart the bot !"); - Directory.CreateDirectory("./Data/Resources"); - await File.WriteAllTextAsync("./Data/Resources/URLs.json", - @" + Console.WriteLine("A new file will be generated at ./Data/Resources/URLs.json"); + Console.WriteLine("Please edit the file and restart the bot !"); + Directory.CreateDirectory("./Data/Resources"); + await File.WriteAllTextAsync("./Data/Resources/URLs.json", + @" { ""PluginList"": """", ""PluginVersions"": """", @@ -102,21 +95,20 @@ namespace DiscordBot ""WindowsLauncher"": """", } ".Replace(" ", "")); - Environment.Exit(0); - return; - } + Environment.Exit(0); } } + } - private static async Task DownloadPluginDatabase(string url = "https://raw.githubusercontent.com/Wizzy69/SethDiscordBot/gh-pages/defaultURLs.json") - { - string path = "./Data/Resources/URLs.json"; + private static async Task DownloadPluginDatabase( + string url = "https://raw.githubusercontent.com/andreitdr/SethDiscordBot/gh-pages/defaultURLs.json") + { + var path = "./Data/Resources/URLs.json"; - Directory.CreateDirectory("./Data/Resources"); - Utilities.Utilities.Spinner spinner = new Utilities.Utilities.Spinner(); - spinner.Start(); - await ServerCom.DownloadFileAsync(url, path, null); - spinner.Stop(); - } + Directory.CreateDirectory("./Data/Resources"); + var spinner = new Utilities.Utilities.Spinner(); + spinner.Start(); + await ServerCom.DownloadFileAsync(url, path, null); + spinner.Stop(); } } diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index 37b730f..cd0cd89 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -1,26 +1,22 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Reflection; using System.Threading.Tasks; -using System.Linq; - -using PluginManager; using PluginManager.Bot; using PluginManager.Online; using PluginManager.Online.Helpers; using PluginManager.Others; - -using DiscordBot.Utilities; +using PluginManager.Others.Actions; using static PluginManager.Config; -using PluginManager.Interfaces; namespace DiscordBot; public class Program { - public static Json URLs; - public static PluginManager.Others.Actions.InternalActionManager internalActionManager; + public static Json URLs; + public static InternalActionManager internalActionManager; /// /// The main entry point for the application. @@ -30,17 +26,15 @@ public class Program { PreLoadComponents(args).Wait(); - if (!Config.Data.ContainsKey("ServerID") || !Config.Data.ContainsKey("token") || - Config.Data["token"] == null || - (Config.Data["token"]?.Length != 70 && Config.Data["token"]?.Length != 59) || - !Config.Data.ContainsKey("prefix") || Config.Data["prefix"] == null || - Config.Data["prefix"]?.Length != 1 || + if (!Data.ContainsKey("ServerID") || !Data.ContainsKey("token") || + Data["token"] == null || + (Data["token"]?.Length != 70 && Data["token"]?.Length != 59) || + !Data.ContainsKey("prefix") || Data["prefix"] == null || + Data["prefix"]?.Length != 1 || (args.Length == 1 && args[0] == "/reset")) - { Installer.GenerateStartupConfig(); - } - - HandleInput(args.ToList()).Wait(); + + HandleInput(args.ToList()).Wait(); } /// @@ -55,11 +49,11 @@ public class Program while (true) { - var cmd = Console.ReadLine(); - string[] args = cmd.Split(' '); - string command = args[0]; + string cmd = Console.ReadLine(); + string[] args = cmd.Split(' '); + string command = args[0]; args = args.Skip(1).ToArray(); - if(args.Length == 0) + if (args.Length == 0) args = null; internalActionManager.Execute(command, args).Wait(); // Execute the command @@ -82,40 +76,40 @@ public class Program Console.WriteLine(message); Console.WriteLine( - $"Running on version: {Assembly.GetExecutingAssembly().GetName().Version}"); - Console.WriteLine($"Git URL: {Config.Data["GitURL"]}"); + $"Running on version: {Assembly.GetExecutingAssembly().GetName().Version}"); + Console.WriteLine($"Git URL: {Data["GitURL"]}"); Utilities.Utilities.WriteColorText( - "&rRemember to close the bot using the ShutDown command (&ysd&r) or some settings won't be saved\n"); + "&rRemember to close the bot using the ShutDown command (&ysd&r) or some settings won't be saved\n"); Console.ForegroundColor = ConsoleColor.White; - if (Config.Data.ContainsKey("LaunchMessage")) - Utilities.Utilities.WriteColorText(Config.Data["LaunchMessage"]); + if (Data.ContainsKey("LaunchMessage")) + Utilities.Utilities.WriteColorText(Data["LaunchMessage"]); Utilities.Utilities.WriteColorText( - "Please note that the bot saves a backup save file every time you are using the shudown command (&ysd&c)"); + "Please note that the bot saves a backup save file every time you are using the shudown command (&ysd&c)"); - Console.WriteLine("Running on " + Functions.GetOperatingSystem().ToString()); + Console.WriteLine("Running on " + Functions.GetOperatingSystem()); Console.WriteLine("============================ LOG ============================"); try { - string token = ""; + var token = ""; #if DEBUG if (File.Exists("./Data/Resources/token.txt")) token = File.ReadAllText("./Data/Resources/token.txt"); - else token = Config.Data["token"]; + else token = Data["token"]; #else token = Config.Data["token"]; #endif - var prefix = Config.Data["prefix"]; + var prefix = Data["prefix"]; var discordbooter = new Boot(token, prefix); await discordbooter.Awake(); return discordbooter; } catch (Exception ex) { - Config.Logger.Log(ex.ToString(), "Bot", LogLevel.ERROR); + Logger.Log(ex.ToString(), "Bot", LogLevel.ERROR); return null; } } @@ -126,24 +120,23 @@ public class Program /// The arguments private static async Task HandleInput(List args) { - Console.WriteLine("Loading Core ..."); - + //Handle arguments here: - - if(args.Contains("--gui")) + + if (args.Contains("--gui")) { // GUI not implemented yet Console.WriteLine("GUI not implemented yet"); return; } - + // Starting bot after all arguments are handled - + var b = await StartNoGui(); try { - internalActionManager = new PluginManager.Others.Actions.InternalActionManager("./Data/Actions", "*.dll"); + internalActionManager = new InternalActionManager("./Data/Actions", "*.dll"); await internalActionManager.Initialize(); NoGUI(); @@ -152,42 +145,40 @@ public class Program { if (ex.Message == "No process is on the other end of the pipe." || (uint)ex.HResult == 0x800700E9) { - if (Config.Data.ContainsKey("LaunchMessage")) - Config.Data.Add("LaunchMessage", - "An error occured while closing the bot last time. Please consider closing the bot using the &rsd&c method !\nThere is a risk of losing all data or corruption of the save file, which in some cases requires to reinstall the bot !"); - Config.Logger.Log("An error occured while closing the bot last time. Please consider closing the bot using the &rsd&c method !\nThere is a risk of losing all data or corruption of the save file, which in some cases requires to reinstall the bot !", "Bot", LogLevel.ERROR); + if (Data.ContainsKey("LaunchMessage")) + Data.Add("LaunchMessage", + "An error occured while closing the bot last time. Please consider closing the bot using the &rsd&c method !\nThere is a risk of losing all data or corruption of the save file, which in some cases requires to reinstall the bot !"); + Logger + .Log("An error occured while closing the bot last time. Please consider closing the bot using the &rsd&c method !\nThere is a risk of losing all data or corruption of the save file, which in some cases requires to reinstall the bot !", + "Bot", LogLevel.ERROR); } } - return; } private static async Task PreLoadComponents(string[] args) { - - await Config.Initialize(); + await Initialize(); if (!Directory.Exists("./Data/Resources") || !File.Exists("./Data/Resources/URLs.json")) - { await Installer.SetupPluginDatabase(); - } URLs = new Json("./Data/Resources/URLs.json"); - Config.Logger.LogEvent += (message, type) => { Console.WriteLine(message); }; + Logger.LogEvent += (message, type) => { Console.WriteLine(message); }; Console.WriteLine("Loading resources ..."); - if (Config.Data.ContainsKey("DeleteLogsAtStartup")) - if (Config.Data["DeleteLogsAtStartup"] == "true") + if (Data.ContainsKey("DeleteLogsAtStartup")) + if (Data["DeleteLogsAtStartup"] == "true") foreach (var file in Directory.GetFiles("./Output/Logs/")) File.Delete(file); var OnlineDefaultKeys = await ServerCom.ReadTextFromURL(URLs["SetupKeys"]); - Config.Data["Version"] = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + Data["Version"] = Assembly.GetExecutingAssembly().GetName().Version.ToString(); foreach (var key in OnlineDefaultKeys) { @@ -195,11 +186,11 @@ public class Program var s = key.Split(' '); try { - Config.Data[s[0]] = s[1]; + Data[s[0]] = s[1]; } catch (Exception ex) { - Config.Logger.Log(ex.ToString(), "Bot", LogLevel.ERROR); + Logger.Log(ex.ToString(), "Bot", LogLevel.ERROR); } } @@ -213,27 +204,27 @@ public class Program switch (s[0]) { case "CurrentVersion": - var currentVersion = Config.Data["Version"]; - var newVersion = s[1]; - if(new VersionString(newVersion) != new VersionString(newVersion)) + var currentVersion = Data["Version"]; + var newVersion = s[1]; + if (new VersionString(newVersion) != new VersionString(newVersion)) { Console.WriteLine("A new updated was found. Check the changelog for more information."); - List changeLog = await ServerCom.ReadTextFromURL(URLs["Changelog"]); + var changeLog = await ServerCom.ReadTextFromURL(URLs["Changelog"]); foreach (var item in changeLog) Utilities.Utilities.WriteColorText(item); Console.WriteLine("Current version: " + currentVersion); Console.WriteLine("Latest version: " + newVersion); - Console.WriteLine($"Download from here: https://github.com/andreitdr/SethDiscordBot/releases"); + Console.WriteLine("Download from here: https://github.com/andreitdr/SethDiscordBot/releases"); Console.WriteLine("Press any key to continue ..."); Console.ReadKey(); } - break; - } + + break; + } } Console.Clear(); - } } diff --git a/DiscordBot/Utilities/Console Utilities.cs b/DiscordBot/Utilities/Console Utilities.cs index 65393db..9f5182d 100644 --- a/DiscordBot/Utilities/Console Utilities.cs +++ b/DiscordBot/Utilities/Console Utilities.cs @@ -1,25 +1,21 @@ using System; using System.Collections.Generic; -using System.Text; using System.Threading; -using System.Threading.Tasks; - -using PluginManager; namespace DiscordBot.Utilities; public static class Utilities { - private static Dictionary Colors = new() + private static readonly Dictionary Colors = new() { - { 'g', ConsoleColor.Green }, - { 'b', ConsoleColor.Blue }, - { 'r', ConsoleColor.Red }, - { 'm', ConsoleColor.Magenta }, - { 'y', ConsoleColor.Yellow } + { 'g', ConsoleColor.Green }, + { 'b', ConsoleColor.Blue }, + { 'r', ConsoleColor.Red }, + { 'm', ConsoleColor.Magenta }, + { 'y', ConsoleColor.Yellow } }; - private static char ColorPrefix = '&'; + private static readonly char ColorPrefix = '&'; private static bool CanAproximateTo(this float f, float y) @@ -36,9 +32,9 @@ public static class Utilities { if (format == TableFormat.CENTER_EACH_COLUMN_BASED) { - var tableLine = '-'; + var tableLine = '-'; var tableCross = '+'; - var tableWall = '|'; + var tableWall = '|'; var len = new int[data[0].Length]; foreach (var line in data) @@ -144,7 +140,7 @@ public static class Utilities if (format == TableFormat.DEFAULT) { - var widths = new int[data[0].Length]; + var widths = new int[data[0].Length]; var space_between_columns = 3; for (var i = 0; i < data.Count; i++) for (var j = 0; j < data[i].Length; j++) @@ -174,7 +170,7 @@ public static class Utilities public static void WriteColorText(string text, bool appendNewLineAtEnd = true) { var initialForeGround = Console.ForegroundColor; - var input = text.ToCharArray(); + var input = text.ToCharArray(); for (var i = 0; i < input.Length; i++) if (input[i] == ColorPrefix) { @@ -201,27 +197,27 @@ public static class Utilities if (appendNewLineAtEnd) Console.WriteLine(); } - - + public class Spinner { - private Thread thread; - private bool isRunning; private readonly string[] Sequence; - private int position; + private bool isRunning; + private int position; + private Thread thread; public Spinner() { - Sequence = new[] {"|", "/", "-", "\\"}; + Sequence = new[] { "|", "/", "-", "\\" }; position = 0; } public void Start() { Console.CursorVisible = false; - isRunning=true; - thread = new Thread(() => { + isRunning = true; + thread = new Thread(() => + { while (isRunning) { Console.Write("\r" + Sequence[position]); @@ -233,14 +229,12 @@ public static class Utilities }); thread.Start(); - } public void Stop() { - isRunning=false; + isRunning = false; Console.CursorVisible = true; } } - } diff --git a/DiscordBot/Utilities/Enums.cs b/DiscordBot/Utilities/Enums.cs index 2b0808d..371ac6c 100644 --- a/DiscordBot/Utilities/Enums.cs +++ b/DiscordBot/Utilities/Enums.cs @@ -1,15 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace DiscordBot.Utilities; -namespace DiscordBot.Utilities +public enum TableFormat { - public enum TableFormat - { - CENTER_EACH_COLUMN_BASED, - CENTER_OVERALL_LENGTH, - DEFAULT - } + CENTER_EACH_COLUMN_BASED, + CENTER_OVERALL_LENGTH, + DEFAULT } diff --git a/PluginManager/Bot/Boot.cs b/PluginManager/Bot/Boot.cs index 66cb76e..4e432af 100644 --- a/PluginManager/Bot/Boot.cs +++ b/PluginManager/Bot/Boot.cs @@ -1,11 +1,9 @@ -using System.Net.Mime; using System; -using System.Collections.Generic; using System.Threading.Tasks; - using Discord; using Discord.Commands; using Discord.WebSocket; +using PluginManager.Others; namespace PluginManager.Bot; @@ -44,35 +42,37 @@ public class Boot public Boot(string botToken, string botPrefix) { this.botPrefix = botPrefix; - this.botToken = botToken; + this.botToken = botToken; } /// /// Checks if the bot is ready /// - /// true if the bot is ready, othwerwise false + /// true if the bot is ready, otherwise false public bool isReady { get; private set; } /// /// The start method for the bot. This method is used to load the bot /// - /// The discord socket config. If null then the default one will be applied (AlwaysDownloadUsers=true, UseInteractionSnowflakeDate=false, GatewayIntents=GatewayIntents.All) + /// + /// The discord socket config. If null then the default one will be applied (AlwaysDownloadUsers=true, + /// UseInteractionSnowflakeDate=false, GatewayIntents=GatewayIntents.All) + /// /// Task public async Task Awake(DiscordSocketConfig? config = null) { if (config is null) config = new DiscordSocketConfig { - AlwaysDownloadUsers = true, //Disable system clock checkup (for responses at slash commands) UseInteractionSnowflakeDate = false, - GatewayIntents = GatewayIntents.All + GatewayIntents = GatewayIntents.All }; - client = new DiscordSocketClient(config); + client = new DiscordSocketClient(config); service = new CommandService(); CommonTasks(); @@ -86,7 +86,6 @@ public class Boot await commandServiceHandler.InstallCommandsAsync(); - await Task.Delay(2000); Config._DiscordBotClient = this; @@ -97,10 +96,10 @@ public class Boot private void CommonTasks() { if (client == null) return; - client.LoggedOut += Client_LoggedOut; - client.Log += Log; - client.LoggedIn += LoggedIn; - client.Ready += Ready; + client.LoggedOut += Client_LoggedOut; + client.Log += Log; + client.LoggedIn += LoggedIn; + client.Ready += Ready; client.Disconnected += Client_Disconnected; } @@ -109,7 +108,8 @@ public class Boot if (arg.Message.Contains("401")) { Config.Data.Remove("token"); - Config.Logger.Log("The token is invalid. Please restart the bot and enter a valid token.", this, Others.LogLevel.ERROR); + Config.Logger.Log("The token is invalid. Please restart the bot and enter a valid token.", this, + LogLevel.ERROR); Config.Data.Save(); await Task.Delay(4000); Environment.Exit(0); @@ -140,7 +140,7 @@ public class Boot { case LogSeverity.Error: case LogSeverity.Critical: - Config.Logger.Log(message.Message, this, Others.LogLevel.ERROR); + Config.Logger.Log(message.Message, this, LogLevel.ERROR); break; diff --git a/PluginManager/Bot/CommandHandler.cs b/PluginManager/Bot/CommandHandler.cs index c456863..4f1b727 100644 --- a/PluginManager/Bot/CommandHandler.cs +++ b/PluginManager/Bot/CommandHandler.cs @@ -2,7 +2,6 @@ using System; using System.Linq; using System.Reflection; using System.Threading.Tasks; - using Discord.Commands; using Discord.WebSocket; using PluginManager.Interfaces; @@ -14,9 +13,9 @@ namespace PluginManager.Bot; internal class CommandHandler { - private readonly string botPrefix; + private readonly string botPrefix; private readonly DiscordSocketClient client; - private readonly CommandService commandService; + private readonly CommandService commandService; /// /// Command handler constructor @@ -26,10 +25,9 @@ internal class CommandHandler /// The prefix to watch for public CommandHandler(DiscordSocketClient client, CommandService commandService, string botPrefix) { - this.client = client; + this.client = client; this.commandService = commandService; - this.botPrefix = botPrefix; - + this.botPrefix = botPrefix; } /// @@ -38,7 +36,7 @@ internal class CommandHandler /// public async Task InstallCommandsAsync() { - client.MessageReceived += MessageHandler; + client.MessageReceived += MessageHandler; client.SlashCommandExecuted += Client_SlashCommandExecuted; await commandService.AddModulesAsync(Assembly.GetEntryAssembly(), null); } @@ -63,7 +61,6 @@ internal class CommandHandler } return Task.CompletedTask; - } /// @@ -73,10 +70,9 @@ internal class CommandHandler /// private async Task MessageHandler(SocketMessage Message) { - try { - if (Message.Author.IsBot) + if (Message.Author.IsBot) return; if (Message as SocketUserMessage == null) @@ -97,18 +93,22 @@ internal class CommandHandler await commandService.ExecuteAsync(context, argPos, null); DBCommand? plugin; - string cleanMessage = ""; + var cleanMessage = ""; if (message.HasMentionPrefix(client.CurrentUser, ref argPos)) { - string mentionPrefix = "<@" + client.CurrentUser.Id + ">"; + var mentionPrefix = "<@" + client.CurrentUser.Id + ">"; plugin = PluginLoader.Commands! - .FirstOrDefault(plug => plug.Command == message.Content.Substring(mentionPrefix.Length+1).Split(' ')[0] || - ( - plug.Aliases is not null && - plug.Aliases.Contains(message.CleanContent.Substring(mentionPrefix.Length+1).Split(' ')[0]) - )); + .FirstOrDefault(plug => plug.Command == + message.Content.Substring(mentionPrefix.Length + 1) + .Split(' ')[0] || + ( + plug.Aliases is not null && + plug.Aliases.Contains(message.CleanContent + .Substring(mentionPrefix.Length + 1) + .Split(' ')[0]) + )); cleanMessage = message.Content.Substring(mentionPrefix.Length + 1); } @@ -116,23 +116,27 @@ internal class CommandHandler else { plugin = PluginLoader.Commands! - .FirstOrDefault(p => p.Command == message.Content.Split(' ')[0].Substring(botPrefix.Length) || - (p.Aliases is not null && - p.Aliases.Contains( - message.Content.Split(' ')[0].Substring(botPrefix.Length)))); + .FirstOrDefault(p => p.Command == + message.Content.Split(' ')[0].Substring(botPrefix.Length) || + (p.Aliases is not null && + p.Aliases.Contains( + message.Content.Split(' ')[0] + .Substring(botPrefix.Length)))); cleanMessage = message.Content.Substring(botPrefix.Length); } - if (plugin is null) - throw new Exception($"Failed to run command ! " + message.CleanContent + " (user: " + context.Message.Author.Username + " - " + context.Message.Author.Id + ")"); + + if (plugin is null) + throw new Exception("Failed to run command ! " + message.CleanContent + " (user: " + + context.Message.Author.Username + " - " + context.Message.Author.Id + ")"); if (plugin.requireAdmin && !context.Message.Author.isAdmin()) return; - string[] split = cleanMessage.Split(' '); + var split = cleanMessage.Split(' '); string[]? argsClean = null; - if(split.Length > 1) - argsClean = string.Join(' ', split, 1, split.Length-1).Split(' '); + if (split.Length > 1) + argsClean = string.Join(' ', split, 1, split.Length - 1).Split(' '); DBCommandExecutingArguments cmd = new(context, cleanMessage, split[0], argsClean); diff --git a/PluginManager/Config.cs b/PluginManager/Config.cs index 1ac8332..fa7d00e 100644 --- a/PluginManager/Config.cs +++ b/PluginManager/Config.cs @@ -1,27 +1,24 @@ using System; -using System.Threading.Tasks; -using System.IO; - -using System.Collections.Generic; -using PluginManager.Others; using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using PluginManager.Bot; +using PluginManager.Others; using PluginManager.Others.Logger; namespace PluginManager; public class Config { - private static bool IsLoaded = false; - public static DBLogger Logger; - public static Json Data; - public static Json Plugins; + private static bool IsLoaded; + public static DBLogger Logger; + public static Json? Data; + public static Json? Plugins; - internal static Bot.Boot? _DiscordBotClient; + internal static Boot? _DiscordBotClient; - public static Bot.Boot? DiscordBot - { - get => _DiscordBotClient; - } + public static Boot? DiscordBot => _DiscordBotClient; public static async Task Initialize() { @@ -34,14 +31,14 @@ public class Config Directory.CreateDirectory("./Data/Logs/Logs"); Directory.CreateDirectory("./Data/Logs/Errors"); - Data = new Json("./Data/Resources/config.json"); + Data = new Json("./Data/Resources/config.json"); Plugins = new Json("./Data/Resources/Plugins.json"); - Config.Data["LogFolder"] = "./Data/Logs/Logs"; - Config.Data["ErrorFolder"] = "./Data/Logs/Errors"; + Data["LogFolder"] = "./Data/Logs/Logs"; + Data["ErrorFolder"] = "./Data/Logs/Errors"; Logger = new DBLogger(); - + ArchiveManager.Initialize(); IsLoaded = true; @@ -51,11 +48,11 @@ public class Config public class Json : IDictionary { - protected IDictionary _dictionary; - private readonly string _file = ""; - + private readonly string _file = ""; + private readonly IDictionary? _dictionary; + /// - /// Empty constructor + /// Empty constructor /// public Json() { @@ -65,13 +62,7 @@ public class Config public Json(string file) { _dictionary = PrivateReadConfig(file).GetAwaiter().GetResult(); - this._file = file; - } - - public async void Save() - { - if(!string.IsNullOrEmpty(_file)) - await Functions.SaveToJsonFile(_file, _dictionary); + _file = file; } public virtual void Add(TKey key, TValue value) @@ -101,9 +92,9 @@ public class Config { get { - if (_dictionary.TryGetValue(key, out TValue value)) return value; - throw new Exception("Key not found in dictionary " + key.ToString() + " (Json )" + this.GetType().Name + ")"); - + if (_dictionary.TryGetValue(key, out var value)) return value; + throw new Exception("Key not found in dictionary " + key + " (Json )" + GetType().Name + + ")"); } set { @@ -118,30 +109,6 @@ public class Config return _dictionary.TryGetValue(key, out value); } - private async Task> PrivateReadConfig(string file) - { - if (!File.Exists(file)) - { - var dictionary = new Dictionary(); - await Functions.SaveToJsonFile(file, _dictionary); - return dictionary; - } - - try - { - var d = await Functions.ConvertFromJson>(file); - if (d is null) - throw new Exception("Failed to read config file"); - - return d; - }catch (Exception ex) - { - File.Delete(file); - return new Dictionary(); - } - - } - public bool Remove(TKey key) { return _dictionary.Remove(key); @@ -176,6 +143,35 @@ public class Config { return ((IEnumerable)_dictionary).GetEnumerator(); } - } + public async void Save() + { + if (!string.IsNullOrEmpty(_file)) + await Functions.SaveToJsonFile(_file, _dictionary); + } + + private async Task> PrivateReadConfig(string file) + { + if (!File.Exists(file)) + { + var dictionary = new Dictionary(); + await Functions.SaveToJsonFile(file, _dictionary); + return dictionary; + } + + try + { + var d = await Functions.ConvertFromJson>(file); + if (d is null) + throw new Exception("Failed to read config file"); + + return d; + } + catch (Exception ex) + { + File.Delete(file); + return new Dictionary(); + } + } + } } diff --git a/PluginManager/Database/SqlDatabase.cs b/PluginManager/Database/SqlDatabase.cs index 383b2c2..ce47e86 100644 --- a/PluginManager/Database/SqlDatabase.cs +++ b/PluginManager/Database/SqlDatabase.cs @@ -1,489 +1,483 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Data; using System.Data.SQLite; using System.IO; using System.Threading.Tasks; -namespace PluginManager.Database +namespace PluginManager.Database; + +public class SqlDatabase { - public class SqlDatabase + private readonly SQLiteConnection Connection; + private readonly string ConnectionString; + + /// + /// Initialize a SQL connection by specifing its private path + /// + /// The path to the database (it is starting from ./Data/Resources/) + public SqlDatabase(string fileName) { - private string ConnectionString; - private SQLiteConnection Connection; - - /// - /// Initialize a SQL connection by specifing its private path - /// - /// The path to the database (it is starting from ./Data/Resources/) - public SqlDatabase(string fileName) - { - if (!fileName.StartsWith("./Data/Resources/")) - fileName = Path.Combine("./Data/Resources", fileName); - if (!File.Exists(fileName)) - SQLiteConnection.CreateFile(fileName); - ConnectionString = $"URI=file:{fileName}"; - Connection = new SQLiteConnection(ConnectionString); - } - - - /// - /// Open the SQL Connection. To close use the Stop() method - /// - /// - public async Task Open() - { - await Connection.OpenAsync(); - } - - /// - /// - /// Insert into a specified table some values - /// - /// - /// The table name - /// The values to be inserted (in the correct order and number) - /// - public async Task InsertAsync(string tableName, params string[] values) - { - string query = $"INSERT INTO {tableName} VALUES ("; - for (int i = 0; i < values.Length; i++) - { - query += $"'{values[i]}'"; - if (i != values.Length - 1) - query += ", "; - } - - query += ")"; - - SQLiteCommand command = new SQLiteCommand(query, Connection); - await command.ExecuteNonQueryAsync(); - } - - /// - /// - /// Insert into a specified table some values - /// - /// - /// The table name - /// The values to be inserted (in the correct order and number) - /// - public void Insert(string tableName, params string[] values) - { - string query = $"INSERT INTO {tableName} VALUES ("; - for (int i = 0; i < values.Length; i++) - { - query += $"'{values[i]}'"; - if (i != values.Length - 1) - query += ", "; - } - - query += ")"; - - SQLiteCommand command = new SQLiteCommand(query, Connection); - command.ExecuteNonQuery(); - } - - /// - /// Remove every row in a table that has a certain propery - /// - /// The table name - /// The column name that the search is made by - /// The value that is searched in the specified column - /// - public async Task RemoveKeyAsync(string tableName, string KeyName, string KeyValue) - { - string query = $"DELETE FROM {tableName} WHERE {KeyName} = '{KeyValue}'"; - - SQLiteCommand command = new SQLiteCommand(query, Connection); - await command.ExecuteNonQueryAsync(); - } - - /// - /// Remove every row in a table that has a certain propery - /// - /// The table name - /// The column name that the search is made by - /// The value that is searched in the specified column - /// - public void RemoveKey(string tableName, string KeyName, string KeyValue) - { - string query = $"DELETE FROM {tableName} WHERE {KeyName} = '{KeyValue}'"; - - SQLiteCommand command = new SQLiteCommand(query, Connection); - command.ExecuteNonQuery(); - } - - /// - /// Check if the key exists in the table - /// - /// The table name - /// The column that the search is made by - /// The value that is searched in the specified column - /// - public async Task KeyExistsAsync(string tableName, string keyName, string KeyValue) - { - string query = $"SELECT * FROM {tableName} where {keyName} = '{KeyValue}'"; - - if (await ReadDataAsync(query) is not null) - return true; - - return false; - } - - /// - /// Check if the key exists in the table - /// - /// The table name - /// The column that the search is made by - /// The value that is searched in the specified column - /// - public bool KeyExists(string tableName, string keyName, string KeyValue) - { - string query = $"SELECT * FROM {tableName} where {keyName} = '{KeyValue}'"; - - if (ReadData(query) is not null) - return true; - - return false; - } - - /// - /// Set value of a column in a table - /// - /// The table name - /// The column that the search is made by - /// The value that is searched in the column specified - /// The column that has to be modified - /// The new value that will replace the old value from the column specified - - public async Task SetValueAsync(string tableName, string keyName, string KeyValue, string ResultColumnName, - string ResultColumnValue) - { - if (!await TableExistsAsync(tableName)) - throw new System.Exception($"Table {tableName} does not exist"); - - await ExecuteAsync( - $"UPDATE {tableName} SET {ResultColumnName}='{ResultColumnValue}' WHERE {keyName}='{KeyValue}'"); - } - - /// - /// Set value of a column in a table - /// - /// The table name - /// The column that the search is made by - /// The value that is searched in the column specified - /// The column that has to be modified - /// The new value that will replace the old value from the column specified - - public void SetValue(string tableName, string keyName, string KeyValue, string ResultColumnName, - string ResultColumnValue) - { - if (!TableExists(tableName)) - throw new System.Exception($"Table {tableName} does not exist"); - - Execute($"UPDATE {tableName} SET {ResultColumnName}='{ResultColumnValue}' WHERE {keyName}='{KeyValue}'"); - } - - /// - /// Get value from a column in a table - /// - /// The table name - /// The column that the search is made by - /// The value that is searched in the specified column - /// The column that has the result - /// A string that has the requested value (can be null if nothing found) - public async Task GetValueAsync(string tableName, string keyName, string KeyValue, - string ResultColumnName) - { - if (!await TableExistsAsync(tableName)) - throw new System.Exception($"Table {tableName} does not exist"); - - return await ReadDataAsync($"SELECT {ResultColumnName} FROM {tableName} WHERE {keyName}='{KeyValue}'"); - } - - /// - /// Get value from a column in a table - /// - /// The table name - /// The column that the search is made by - /// The value that is searched in the specified column - /// The column that has the result - /// A string that has the requested value (can be null if nothing found) - - public string? GetValue(string tableName, string keyName, string KeyValue, string ResultColumnName) - { - if (!TableExists(tableName)) - throw new System.Exception($"Table {tableName} does not exist"); - - return ReadData($"SELECT {ResultColumnName} FROM {tableName} WHERE {keyName}='{KeyValue}'"); - } - - /// - /// Stop the connection to the SQL Database - /// - /// - public async void Stop() - { - await Connection.CloseAsync(); - } - - /// - /// Change the structure of a table by adding new columns - /// - /// The table name - /// The columns to be added - /// The type of the columns (TEXT, INTEGER, FLOAT, etc) - /// - public async Task AddColumnsToTableAsync(string tableName, string[] columns, string TYPE = "TEXT") - { - var command = Connection.CreateCommand(); - command.CommandText = $"SELECT * FROM {tableName}"; - var reader = await command.ExecuteReaderAsync(); - var tableColumns = new List(); - for (int i = 0; i < reader.FieldCount; i++) - tableColumns.Add(reader.GetName(i)); - - foreach (var column in columns) - { - if (!tableColumns.Contains(column)) - { - command.CommandText = $"ALTER TABLE {tableName} ADD COLUMN {column} {TYPE}"; - await command.ExecuteNonQueryAsync(); - } - } - } - - /// - /// Change the structure of a table by adding new columns - /// - /// The table name - /// The columns to be added - /// The type of the columns (TEXT, INTEGER, FLOAT, etc) - /// - - public void AddColumnsToTable(string tableName, string[] columns, string TYPE = "TEXT") - { - var command = Connection.CreateCommand(); - command.CommandText = $"SELECT * FROM {tableName}"; - var reader = command.ExecuteReader(); - var tableColumns = new List(); - for (int i = 0; i < reader.FieldCount; i++) - tableColumns.Add(reader.GetName(i)); - - foreach (var column in columns) - { - if (!tableColumns.Contains(column)) - { - command.CommandText = $"ALTER TABLE {tableName} ADD COLUMN {column} {TYPE}"; - command.ExecuteNonQuery(); - } - } - } - - /// - /// Check if a table exists - /// - /// The table name - /// True if the table exists, false if not - public async Task TableExistsAsync(string tableName) - { - var cmd = Connection.CreateCommand(); - cmd.CommandText = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{tableName}'"; - var result = await cmd.ExecuteScalarAsync(); - - if (result == null) - return false; - return true; - } - - /// - /// Check if a table exists - /// - /// The table name - /// True if the table exists, false if not - public bool TableExists(string tableName) - { - var cmd = Connection.CreateCommand(); - cmd.CommandText = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{tableName}'"; - var result = cmd.ExecuteScalar(); - - if (result == null) - return false; - return true; - } - - /// - /// Create a table - /// - /// The table name - /// The columns of the table - /// - - public async Task CreateTableAsync(string tableName, params string[] columns) - { - var cmd = Connection.CreateCommand(); - cmd.CommandText = $"CREATE TABLE IF NOT EXISTS {tableName} ({string.Join(", ", columns)})"; - await cmd.ExecuteNonQueryAsync(); - } - - /// - /// Create a table - /// - /// The table name - /// The columns of the table - /// - - public void CreateTable(string tableName, params string[] columns) - { - var cmd = Connection.CreateCommand(); - cmd.CommandText = $"CREATE TABLE IF NOT EXISTS {tableName} ({string.Join(", ", columns)})"; - cmd.ExecuteNonQuery(); - } - - /// - /// Execute a custom query - /// - /// The query - /// The number of rows that the query modified - public async Task ExecuteAsync(string query) - { - if (!Connection.State.HasFlag(System.Data.ConnectionState.Open)) - await Connection.OpenAsync(); - var command = new SQLiteCommand(query, Connection); - int answer = await command.ExecuteNonQueryAsync(); - return answer; - } - - /// - /// Execute a custom query - /// - /// The query - /// The number of rows that the query modified - public int Execute(string query) - { - if (!Connection.State.HasFlag(System.Data.ConnectionState.Open)) - Connection.Open(); - var command = new SQLiteCommand(query, Connection); - int r = command.ExecuteNonQuery(); - - return r; - } - - /// - /// Read data from the result table and return the first row - /// - /// The query - /// The result is a string that has all values separated by space character - public async Task ReadDataAsync(string query) - { - if (!Connection.State.HasFlag(System.Data.ConnectionState.Open)) - await Connection.OpenAsync(); - var command = new SQLiteCommand(query, Connection); - var reader = await command.ExecuteReaderAsync(); - - object[] values = new object[reader.FieldCount]; - if (reader.Read()) - { - reader.GetValues(values); - return string.Join(" ", values); - } - - return null; - } - - /// - /// Read data from the result table and return the first row - /// - /// The query - /// The result is a string that has all values separated by space character - public string? ReadData(string query) - { - if (!Connection.State.HasFlag(System.Data.ConnectionState.Open)) - Connection.Open(); - var command = new SQLiteCommand(query, Connection); - var reader = command.ExecuteReader(); - - object[] values = new object[reader.FieldCount]; - if (reader.Read()) - { - reader.GetValues(values); - return string.Join(" ", values); - } - - return null; - } - - /// - /// Read data from the result table and return the first row - /// - /// The query - /// The first row as separated items - public async Task ReadDataArrayAsync(string query) - { - if (!Connection.State.HasFlag(System.Data.ConnectionState.Open)) - await Connection.OpenAsync(); - var command = new SQLiteCommand(query, Connection); - var reader = await command.ExecuteReaderAsync(); - - object[] values = new object[reader.FieldCount]; - if (reader.Read()) - { - reader.GetValues(values); - return values; - } - - return null; - } - - - /// - /// Read data from the result table and return the first row - /// - /// The query - /// The first row as separated items - public object[]? ReadDataArray(string query) - { - if (!Connection.State.HasFlag(System.Data.ConnectionState.Open)) - Connection.Open(); - var command = new SQLiteCommand(query, Connection); - var reader = command.ExecuteReader(); - - object[] values = new object[reader.FieldCount]; - if (reader.Read()) - { - reader.GetValues(values); - return values; - } - - return null; - } - - /// - /// Read all rows from the result table and return them as a list of string arrays. The string arrays contain the values of each row - /// - /// The query - /// A list of string arrays representing the values that the query returns - - public async Task?> ReadAllRowsAsync(string query) - { - if (!Connection.State.HasFlag(System.Data.ConnectionState.Open)) - await Connection.OpenAsync(); - var command = new SQLiteCommand(query, Connection); - var reader = await command.ExecuteReaderAsync(); - - if (!reader.HasRows) - return null; - - List rows = new(); - while (await reader.ReadAsync()) - { - string[] values = new string[reader.FieldCount]; - reader.GetValues(values); - rows.Add(values); - } - - if (rows.Count == 0) return null; - - return rows; - } + if (!fileName.StartsWith("./Data/Resources/")) + fileName = Path.Combine("./Data/Resources", fileName); + if (!File.Exists(fileName)) + SQLiteConnection.CreateFile(fileName); + ConnectionString = $"URI=file:{fileName}"; + Connection = new SQLiteConnection(ConnectionString); } -} \ No newline at end of file + + + /// + /// Open the SQL Connection. To close use the Stop() method + /// + /// + public async Task Open() + { + await Connection.OpenAsync(); + } + + /// + /// + /// Insert into a specified table some values + /// + /// + /// The table name + /// The values to be inserted (in the correct order and number) + /// + public async Task InsertAsync(string tableName, params string[] values) + { + var query = $"INSERT INTO {tableName} VALUES ("; + for (var i = 0; i < values.Length; i++) + { + query += $"'{values[i]}'"; + if (i != values.Length - 1) + query += ", "; + } + + query += ")"; + + var command = new SQLiteCommand(query, Connection); + await command.ExecuteNonQueryAsync(); + } + + /// + /// + /// Insert into a specified table some values + /// + /// + /// The table name + /// The values to be inserted (in the correct order and number) + /// + public void Insert(string tableName, params string[] values) + { + var query = $"INSERT INTO {tableName} VALUES ("; + for (var i = 0; i < values.Length; i++) + { + query += $"'{values[i]}'"; + if (i != values.Length - 1) + query += ", "; + } + + query += ")"; + + var command = new SQLiteCommand(query, Connection); + command.ExecuteNonQuery(); + } + + /// + /// Remove every row in a table that has a certain propery + /// + /// The table name + /// The column name that the search is made by + /// The value that is searched in the specified column + /// + public async Task RemoveKeyAsync(string tableName, string KeyName, string KeyValue) + { + var query = $"DELETE FROM {tableName} WHERE {KeyName} = '{KeyValue}'"; + + var command = new SQLiteCommand(query, Connection); + await command.ExecuteNonQueryAsync(); + } + + /// + /// Remove every row in a table that has a certain propery + /// + /// The table name + /// The column name that the search is made by + /// The value that is searched in the specified column + /// + public void RemoveKey(string tableName, string KeyName, string KeyValue) + { + var query = $"DELETE FROM {tableName} WHERE {KeyName} = '{KeyValue}'"; + + var command = new SQLiteCommand(query, Connection); + command.ExecuteNonQuery(); + } + + /// + /// Check if the key exists in the table + /// + /// The table name + /// The column that the search is made by + /// The value that is searched in the specified column + /// + public async Task KeyExistsAsync(string tableName, string keyName, string KeyValue) + { + var query = $"SELECT * FROM {tableName} where {keyName} = '{KeyValue}'"; + + if (await ReadDataAsync(query) is not null) + return true; + + return false; + } + + /// + /// Check if the key exists in the table + /// + /// The table name + /// The column that the search is made by + /// The value that is searched in the specified column + /// + public bool KeyExists(string tableName, string keyName, string KeyValue) + { + var query = $"SELECT * FROM {tableName} where {keyName} = '{KeyValue}'"; + + if (ReadData(query) is not null) + return true; + + return false; + } + + /// + /// Set value of a column in a table + /// + /// The table name + /// The column that the search is made by + /// The value that is searched in the column specified + /// The column that has to be modified + /// The new value that will replace the old value from the column specified + public async Task SetValueAsync( + string tableName, string keyName, string KeyValue, string ResultColumnName, + string ResultColumnValue) + { + if (!await TableExistsAsync(tableName)) + throw new Exception($"Table {tableName} does not exist"); + + await ExecuteAsync( + $"UPDATE {tableName} SET {ResultColumnName}='{ResultColumnValue}' WHERE {keyName}='{KeyValue}'"); + } + + /// + /// Set value of a column in a table + /// + /// The table name + /// The column that the search is made by + /// The value that is searched in the column specified + /// The column that has to be modified + /// The new value that will replace the old value from the column specified + public void SetValue( + string tableName, string keyName, string KeyValue, string ResultColumnName, + string ResultColumnValue) + { + if (!TableExists(tableName)) + throw new Exception($"Table {tableName} does not exist"); + + Execute($"UPDATE {tableName} SET {ResultColumnName}='{ResultColumnValue}' WHERE {keyName}='{KeyValue}'"); + } + + /// + /// Get value from a column in a table + /// + /// The table name + /// The column that the search is made by + /// The value that is searched in the specified column + /// The column that has the result + /// A string that has the requested value (can be null if nothing found) + public async Task GetValueAsync( + string tableName, string keyName, string KeyValue, + string ResultColumnName) + { + if (!await TableExistsAsync(tableName)) + throw new Exception($"Table {tableName} does not exist"); + + return await ReadDataAsync($"SELECT {ResultColumnName} FROM {tableName} WHERE {keyName}='{KeyValue}'"); + } + + /// + /// Get value from a column in a table + /// + /// The table name + /// The column that the search is made by + /// The value that is searched in the specified column + /// The column that has the result + /// A string that has the requested value (can be null if nothing found) + public string? GetValue(string tableName, string keyName, string KeyValue, string ResultColumnName) + { + if (!TableExists(tableName)) + throw new Exception($"Table {tableName} does not exist"); + + return ReadData($"SELECT {ResultColumnName} FROM {tableName} WHERE {keyName}='{KeyValue}'"); + } + + /// + /// Stop the connection to the SQL Database + /// + /// + public async void Stop() + { + await Connection.CloseAsync(); + } + + /// + /// Change the structure of a table by adding new columns + /// + /// The table name + /// The columns to be added + /// The type of the columns (TEXT, INTEGER, FLOAT, etc) + /// + public async Task AddColumnsToTableAsync(string tableName, string[] columns, string TYPE = "TEXT") + { + var command = Connection.CreateCommand(); + command.CommandText = $"SELECT * FROM {tableName}"; + var reader = await command.ExecuteReaderAsync(); + var tableColumns = new List(); + for (var i = 0; i < reader.FieldCount; i++) + tableColumns.Add(reader.GetName(i)); + + foreach (var column in columns) + if (!tableColumns.Contains(column)) + { + command.CommandText = $"ALTER TABLE {tableName} ADD COLUMN {column} {TYPE}"; + await command.ExecuteNonQueryAsync(); + } + } + + /// + /// Change the structure of a table by adding new columns + /// + /// The table name + /// The columns to be added + /// The type of the columns (TEXT, INTEGER, FLOAT, etc) + /// + public void AddColumnsToTable(string tableName, string[] columns, string TYPE = "TEXT") + { + var command = Connection.CreateCommand(); + command.CommandText = $"SELECT * FROM {tableName}"; + var reader = command.ExecuteReader(); + var tableColumns = new List(); + for (var i = 0; i < reader.FieldCount; i++) + tableColumns.Add(reader.GetName(i)); + + foreach (var column in columns) + if (!tableColumns.Contains(column)) + { + command.CommandText = $"ALTER TABLE {tableName} ADD COLUMN {column} {TYPE}"; + command.ExecuteNonQuery(); + } + } + + /// + /// Check if a table exists + /// + /// The table name + /// True if the table exists, false if not + public async Task TableExistsAsync(string tableName) + { + var cmd = Connection.CreateCommand(); + cmd.CommandText = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{tableName}'"; + var result = await cmd.ExecuteScalarAsync(); + + if (result == null) + return false; + return true; + } + + /// + /// Check if a table exists + /// + /// The table name + /// True if the table exists, false if not + public bool TableExists(string tableName) + { + var cmd = Connection.CreateCommand(); + cmd.CommandText = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{tableName}'"; + var result = cmd.ExecuteScalar(); + + if (result == null) + return false; + return true; + } + + /// + /// Create a table + /// + /// The table name + /// The columns of the table + /// + public async Task CreateTableAsync(string tableName, params string[] columns) + { + var cmd = Connection.CreateCommand(); + cmd.CommandText = $"CREATE TABLE IF NOT EXISTS {tableName} ({string.Join(", ", columns)})"; + await cmd.ExecuteNonQueryAsync(); + } + + /// + /// Create a table + /// + /// The table name + /// The columns of the table + /// + public void CreateTable(string tableName, params string[] columns) + { + var cmd = Connection.CreateCommand(); + cmd.CommandText = $"CREATE TABLE IF NOT EXISTS {tableName} ({string.Join(", ", columns)})"; + cmd.ExecuteNonQuery(); + } + + /// + /// Execute a custom query + /// + /// The query + /// The number of rows that the query modified + public async Task ExecuteAsync(string query) + { + if (!Connection.State.HasFlag(ConnectionState.Open)) + await Connection.OpenAsync(); + var command = new SQLiteCommand(query, Connection); + var answer = await command.ExecuteNonQueryAsync(); + return answer; + } + + /// + /// Execute a custom query + /// + /// The query + /// The number of rows that the query modified + public int Execute(string query) + { + if (!Connection.State.HasFlag(ConnectionState.Open)) + Connection.Open(); + var command = new SQLiteCommand(query, Connection); + var r = command.ExecuteNonQuery(); + + return r; + } + + /// + /// Read data from the result table and return the first row + /// + /// The query + /// The result is a string that has all values separated by space character + public async Task ReadDataAsync(string query) + { + if (!Connection.State.HasFlag(ConnectionState.Open)) + await Connection.OpenAsync(); + var command = new SQLiteCommand(query, Connection); + var reader = await command.ExecuteReaderAsync(); + + var values = new object[reader.FieldCount]; + if (reader.Read()) + { + reader.GetValues(values); + return string.Join(" ", values); + } + + return null; + } + + /// + /// Read data from the result table and return the first row + /// + /// The query + /// The result is a string that has all values separated by space character + public string? ReadData(string query) + { + if (!Connection.State.HasFlag(ConnectionState.Open)) + Connection.Open(); + var command = new SQLiteCommand(query, Connection); + var reader = command.ExecuteReader(); + + var values = new object[reader.FieldCount]; + if (reader.Read()) + { + reader.GetValues(values); + return string.Join(" ", values); + } + + return null; + } + + /// + /// Read data from the result table and return the first row + /// + /// The query + /// The first row as separated items + public async Task ReadDataArrayAsync(string query) + { + if (!Connection.State.HasFlag(ConnectionState.Open)) + await Connection.OpenAsync(); + var command = new SQLiteCommand(query, Connection); + var reader = await command.ExecuteReaderAsync(); + + var values = new object[reader.FieldCount]; + if (reader.Read()) + { + reader.GetValues(values); + return values; + } + + return null; + } + + + /// + /// Read data from the result table and return the first row + /// + /// The query + /// The first row as separated items + public object[]? ReadDataArray(string query) + { + if (!Connection.State.HasFlag(ConnectionState.Open)) + Connection.Open(); + var command = new SQLiteCommand(query, Connection); + var reader = command.ExecuteReader(); + + var values = new object[reader.FieldCount]; + if (reader.Read()) + { + reader.GetValues(values); + return values; + } + + return null; + } + + /// + /// Read all rows from the result table and return them as a list of string arrays. The string arrays contain the + /// values of each row + /// + /// The query + /// A list of string arrays representing the values that the query returns + public async Task?> ReadAllRowsAsync(string query) + { + if (!Connection.State.HasFlag(ConnectionState.Open)) + await Connection.OpenAsync(); + var command = new SQLiteCommand(query, Connection); + var reader = await command.ExecuteReaderAsync(); + + if (!reader.HasRows) + return null; + + List rows = new(); + while (await reader.ReadAsync()) + { + var values = new string[reader.FieldCount]; + reader.GetValues(values); + rows.Add(values); + } + + if (rows.Count == 0) return null; + + return rows; + } +} diff --git a/PluginManager/Interfaces/DBCommand.cs b/PluginManager/Interfaces/DBCommand.cs index 67a7c09..251f103 100644 --- a/PluginManager/Interfaces/DBCommand.cs +++ b/PluginManager/Interfaces/DBCommand.cs @@ -47,4 +47,4 @@ public interface DBCommand void ExecuteDM(DBCommandExecutingArguments args) { } -} \ No newline at end of file +} diff --git a/PluginManager/Interfaces/DBEvent.cs b/PluginManager/Interfaces/DBEvent.cs index 5458636..4c7e06a 100644 --- a/PluginManager/Interfaces/DBEvent.cs +++ b/PluginManager/Interfaces/DBEvent.cs @@ -19,4 +19,4 @@ public interface DBEvent /// /// The discord bot client void Start(DiscordSocketClient client); -} \ No newline at end of file +} diff --git a/PluginManager/Interfaces/DBSlashCommand.cs b/PluginManager/Interfaces/DBSlashCommand.cs index a1c3ab0..eb2df8a 100644 --- a/PluginManager/Interfaces/DBSlashCommand.cs +++ b/PluginManager/Interfaces/DBSlashCommand.cs @@ -1,25 +1,21 @@ using System.Collections.Generic; - using Discord; using Discord.WebSocket; -namespace PluginManager.Interfaces +namespace PluginManager.Interfaces; + +public interface DBSlashCommand { - public interface DBSlashCommand + string Name { get; } + string Description { get; } + + bool canUseDM { get; } + + List Options { get; } + + void ExecuteServer(SocketSlashCommand context) { - string Name { get; } - string Description { get; } - - bool canUseDM { get; } - - List Options { get; } - - void ExecuteServer(SocketSlashCommand context) - { - - } - - void ExecuteDM(SocketSlashCommand context) { } - } + + void ExecuteDM(SocketSlashCommand context) { } } diff --git a/PluginManager/Interfaces/IInternalAction.cs b/PluginManager/Interfaces/IInternalAction.cs index 83f98c7..785bdf1 100644 --- a/PluginManager/Interfaces/IInternalAction.cs +++ b/PluginManager/Interfaces/IInternalAction.cs @@ -1,23 +1,17 @@ -using System; -using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; - using PluginManager.Others; -namespace PluginManager.Interfaces +namespace PluginManager.Interfaces; + +public interface ICommandAction { - public interface ICommandAction - { - public string ActionName { get; } + public string ActionName { get; } - public string? Description { get; } + public string? Description { get; } - public string? Usage { get; } + public string? Usage { get; } - public InternalActionRunType RunType { get; } + public InternalActionRunType RunType { get; } - public Task Execute(string[]? args); - - } -} \ No newline at end of file + public Task Execute(string[]? args); +} diff --git a/PluginManager/Loaders/ActionsLoader.cs b/PluginManager/Loaders/ActionsLoader.cs index c938627..ded77b7 100644 --- a/PluginManager/Loaders/ActionsLoader.cs +++ b/PluginManager/Loaders/ActionsLoader.cs @@ -1,76 +1,72 @@ -using System.IO; using System; using System.Collections.Generic; +using System.IO; using System.Linq; -using System.Threading.Tasks; using System.Reflection; -using PluginManager.Others.Actions; +using System.Threading.Tasks; using PluginManager.Interfaces; -using System.Collections; +using PluginManager.Others; -namespace PluginManager.Loaders +namespace PluginManager.Loaders; + +public class ActionsLoader { - public class ActionsLoader + public delegate void ActionLoaded(string name, string typeName, bool success, Exception? e = null); + + private readonly string actionExtension = "dll"; + + private readonly string actionFolder = @"./Data/Actions/"; + + public ActionsLoader(string path, string extension) { - public delegate void ActionLoaded(string name, string typeName, bool success, Exception? e = null); - public event ActionLoaded? ActionLoadedEvent; - - private string actionFolder = @"./Data/Actions/"; - private string actionExtension = "dll"; - - public ActionsLoader(string path, string extension) - { - actionFolder = path; - actionExtension = extension; - } - - public async Task?> Load() - { - Directory.CreateDirectory(actionFolder); - var files = Directory.GetFiles(actionFolder, $"*.{actionExtension}", SearchOption.AllDirectories); - - List actions = new List(); - - foreach (var file in files) - { - try - { - Assembly.LoadFrom(file); - } - catch (Exception e) - { - ActionLoadedEvent?.Invoke(file, "", false, e); - } - } - - var types = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(s => s.GetTypes()) - .Where(p => typeof(ICommandAction).IsAssignableFrom(p) && !p.IsInterface); - - foreach (var type in types) - { - try - { - var action = (ICommandAction) Activator.CreateInstance(type); - if (action.ActionName == null) - { - ActionLoadedEvent?.Invoke(action.ActionName, type.Name, false); - continue; - } - - if(action.RunType == PluginManager.Others.InternalActionRunType.ON_STARTUP) - await action.Execute(null); - - ActionLoadedEvent?.Invoke(action.ActionName, type.Name, true); - actions.Add(action); - } - catch (Exception e) - { - ActionLoadedEvent?.Invoke(type.Name, type.Name, false, e); - } - } - - return actions; - } + actionFolder = path; + actionExtension = extension; } -} \ No newline at end of file + + public event ActionLoaded? ActionLoadedEvent; + + public async Task?> Load() + { + Directory.CreateDirectory(actionFolder); + var files = Directory.GetFiles(actionFolder, $"*.{actionExtension}", SearchOption.AllDirectories); + + var actions = new List(); + + foreach (var file in files) + try + { + Assembly.LoadFrom(file); + } + catch (Exception e) + { + ActionLoadedEvent?.Invoke(file, "", false, e); + } + + var types = AppDomain.CurrentDomain.GetAssemblies() + .SelectMany(s => s.GetTypes()) + .Where(p => typeof(ICommandAction).IsAssignableFrom(p) && !p.IsInterface); + + foreach (var type in types) + try + { + var action = (ICommandAction)Activator.CreateInstance(type); + if (action.ActionName == null) + { + ActionLoadedEvent?.Invoke(action.ActionName, type.Name, false); + continue; + } + + if (action.RunType == InternalActionRunType.ON_STARTUP) + await action.Execute(null); + + ActionLoadedEvent?.Invoke(action.ActionName, type.Name, true); + actions.Add(action); + } + catch (Exception e) + { + ActionLoadedEvent?.Invoke(type.Name, type.Name, false, e); + } + + return actions; + } +} diff --git a/PluginManager/Loaders/Loader.cs b/PluginManager/Loaders/Loader.cs index 5196f70..054370b 100644 --- a/PluginManager/Loaders/Loader.cs +++ b/PluginManager/Loaders/Loader.cs @@ -3,143 +3,143 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; - using PluginManager.Interfaces; +using PluginManager.Others; -namespace PluginManager.Loaders +namespace PluginManager.Loaders; + +internal class LoaderArgs : EventArgs { - internal class LoaderArgs : EventArgs + internal string? PluginName { get; init; } + internal string? TypeName { get; init; } + internal bool IsLoaded { get; init; } + internal Exception? Exception { get; init; } + internal object? Plugin { get; init; } +} + +internal class Loader +{ + internal Loader(string path, string extension) { - internal string? PluginName { get; init; } - internal string? TypeName { get; init; } - internal bool IsLoaded { get; init; } - internal Exception? Exception { get; init; } - internal object? Plugin { get; init; } + this.path = path; + this.extension = extension; } - internal class Loader + + + private string path { get; } + private string extension { get; } + + internal event FileLoadedEventHandler? FileLoaded; + + internal event PluginLoadedEventHandler? PluginLoaded; + + + internal (List?, List?, List?) Load() { - internal Loader(string path, string extension) + List events = new(); + List slashCommands = new(); + List commands = new(); + + if (!Directory.Exists(path)) { - this.path = path; - this.extension = extension; + Directory.CreateDirectory(path); + return (null, null, null); } - - private string path { get; } - private string extension { get; } - - internal event FileLoadedEventHandler? FileLoaded; - - internal event PluginLoadedEventHandler? PluginLoaded; - - - internal delegate void FileLoadedEventHandler(LoaderArgs args); - - internal delegate void PluginLoadedEventHandler(LoaderArgs args); - - - internal (List?, List?, List?) Load() + var files = Directory.GetFiles(path, $"*.{extension}", SearchOption.AllDirectories); + foreach (var file in files) { - - List events = new(); - List slashCommands = new(); - List commands = new(); - - if (!Directory.Exists(path)) - { - Directory.CreateDirectory(path); - return (null, null, null); - } - - var files = Directory.GetFiles(path, $"*.{extension}", SearchOption.AllDirectories); - foreach (var file in files) - { - try - { - Assembly.LoadFrom(file); - } - catch (Exception ex) - { - Config.Logger.Log("PluginName: " + new FileInfo(file).Name.Split('.')[0] + " not loaded", this, Others.LogLevel.ERROR); - continue; - } - if (FileLoaded != null) - { - var args = new LoaderArgs - { - Exception = null, - TypeName = null, - IsLoaded = false, - PluginName = new FileInfo(file).Name.Split('.')[0], - Plugin = null - }; - FileLoaded.Invoke(args); - } - } - - - - return (LoadItems(), LoadItems(), LoadItems()); - } - - internal List LoadItems() - { - List list = new(); - - try { - var interfaceType = typeof(T); - var types = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(a => a.GetTypes()) - .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) - .ToArray(); - - - list.Clear(); - foreach (var type in types) - try - { - var plugin = (T)Activator.CreateInstance(type)!; - list.Add(plugin); - - - if (PluginLoaded != null) - PluginLoaded.Invoke(new LoaderArgs - { - Exception = null, - IsLoaded = true, - PluginName = type.FullName, - TypeName = typeof(T) == typeof(DBCommand) ? "DBCommand" : - typeof(T) == typeof(DBEvent) ? "DBEvent" : - typeof(T) == typeof(DBSlashCommand) ? "DBSlashCommand" : - null, - Plugin = plugin - } - ); - } - catch (Exception ex) - { - if (PluginLoaded != null) - PluginLoaded.Invoke(new LoaderArgs - { - Exception = ex, - IsLoaded = false, - PluginName = type.FullName, - TypeName = nameof(T) - }); - } - - return list; + Assembly.LoadFrom(file); } catch (Exception ex) { - Config.Logger.Log(ex.Message, this, Others.LogLevel.ERROR); - - return null; + Config.Logger.Log("PluginName: " + new FileInfo(file).Name.Split('.')[0] + " not loaded", this, + LogLevel.ERROR); + continue; } + + if (FileLoaded != null) + { + var args = new LoaderArgs + { + Exception = null, + TypeName = null, + IsLoaded = false, + PluginName = new FileInfo(file).Name.Split('.')[0], + Plugin = null + }; + FileLoaded.Invoke(args); + } + } + + + return (LoadItems(), LoadItems(), LoadItems()); + } + + internal List LoadItems() + { + List list = new(); + + + try + { + var interfaceType = typeof(T); + var types = AppDomain.CurrentDomain.GetAssemblies() + .SelectMany(a => a.GetTypes()) + .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) + .ToArray(); + + + list.Clear(); + foreach (var type in types) + try + { + var plugin = (T)Activator.CreateInstance(type)!; + list.Add(plugin); + + + if (PluginLoaded != null) + PluginLoaded.Invoke(new LoaderArgs + { + Exception = null, + IsLoaded = true, + PluginName = type.FullName, + TypeName = typeof(T) == typeof(DBCommand) ? "DBCommand" : + typeof(T) == typeof(DBEvent) ? "DBEvent" : + typeof(T) == typeof(DBSlashCommand) ? "DBSlashCommand" : + null, + Plugin = plugin + } + ); + } + catch (Exception ex) + { + if (PluginLoaded != null) + PluginLoaded.Invoke(new LoaderArgs + { + Exception = ex, + IsLoaded = false, + PluginName = type.FullName, + TypeName = nameof(T) + }); + } + + return list; + } + catch (Exception ex) + { + Config.Logger.Log(ex.Message, this, LogLevel.ERROR); + return null; } + return null; } + + + internal delegate void FileLoadedEventHandler(LoaderArgs args); + + internal delegate void PluginLoadedEventHandler(LoaderArgs args); } diff --git a/PluginManager/Loaders/PluginLoader.cs b/PluginManager/Loaders/PluginLoader.cs index 6b0cad0..1079f52 100644 --- a/PluginManager/Loaders/PluginLoader.cs +++ b/PluginManager/Loaders/PluginLoader.cs @@ -1,14 +1,10 @@ using System; using System.Collections.Generic; -using System.IO; using System.Reflection; using System.Threading.Tasks; - using Discord; using Discord.WebSocket; - using PluginManager.Interfaces; -using PluginManager.Online; using PluginManager.Others; namespace PluginManager.Loaders; @@ -23,7 +19,7 @@ public class PluginLoader private const string pluginFolder = @"./Data/Plugins/"; - internal const string pluginExtension = "dll"; + internal const string pluginExtension = "dll"; private readonly DiscordSocketClient _client; /// @@ -62,20 +58,24 @@ public class PluginLoader public static List? Events { get; set; } /// - /// A list of commands + /// A list of commands /// public static List? SlashCommands { get; set; } - public static int PluginsLoaded { get { - var count = 0; - if (Commands is not null) - count += Commands.Count; - if (Events is not null) - count += Events.Count; - if (SlashCommands is not null) - count += SlashCommands.Count; - return count; - }} + public static int PluginsLoaded + { + get + { + var count = 0; + if (Commands is not null) + count += Commands.Count; + if (Events is not null) + count += Events.Count; + if (SlashCommands is not null) + count += SlashCommands.Count; + return count; + } + } /// /// The main mathod that is called to load all events @@ -84,24 +84,24 @@ public class PluginLoader { //Load all plugins - Commands = new List(); - Events = new List(); + Commands = new List(); + Events = new List(); SlashCommands = new List(); - Config.Logger.Log("Starting plugin loader ... Client: " + _client.CurrentUser.Username, this, Others.LogLevel.INFO); + Config.Logger.Log("Starting plugin loader ... Client: " + _client.CurrentUser.Username, this, + LogLevel.INFO); var loader = new Loader("./Data/Plugins", "dll"); - loader.FileLoaded += (args) => Config.Logger.Log($"{args.PluginName} file Loaded", this , Others.LogLevel.INFO); + loader.FileLoaded += args => Config.Logger.Log($"{args.PluginName} file Loaded", this, LogLevel.INFO); loader.PluginLoaded += Loader_PluginLoaded; var res = loader.Load(); - Events = res.Item1; - Commands = res.Item2; + Events = res.Item1; + Commands = res.Item2; SlashCommands = res.Item3; } private async void Loader_PluginLoaded(LoaderArgs args) { - switch (args.TypeName) { case "DBCommand": @@ -117,27 +117,29 @@ public class PluginLoader } catch (Exception ex) { - Config.Logger.Log(ex.Message, this, Others.LogLevel.ERROR); + Config.Logger.Log(ex.Message, this, LogLevel.ERROR); } + break; case "DBSlashCommand": if (args.IsLoaded) { - var slash = (DBSlashCommand)args.Plugin; - SlashCommandBuilder builder = new SlashCommandBuilder(); + var slash = (DBSlashCommand)args.Plugin; + var builder = new SlashCommandBuilder(); builder.WithName(slash.Name); builder.WithDescription(slash.Description); builder.WithDMPermission(slash.canUseDM); builder.Options = slash.Options; - onSLSHLoad?.Invoke(((DBSlashCommand)args.Plugin!).Name, args.TypeName, args.IsLoaded, args.Exception); + onSLSHLoad?.Invoke(((DBSlashCommand)args.Plugin!).Name, args.TypeName, args.IsLoaded, + args.Exception); await _client.CreateGlobalApplicationCommandAsync(builder.Build()); - - } + break; } } + public static async Task LoadPluginFromAssembly(Assembly asmb, DiscordSocketClient client) { var types = asmb.GetTypes(); @@ -146,28 +148,27 @@ public class PluginLoader { var instance = (DBEvent)Activator.CreateInstance(type); instance.Start(client); - PluginLoader.Events.Add(instance); - Config.Logger.Log($"[EVENT] Loaded external {type.FullName}!", Others.LogLevel.INFO); + Events.Add(instance); + Config.Logger.Log($"[EVENT] Loaded external {type.FullName}!", LogLevel.INFO); } else if (type.IsClass && typeof(DBCommand).IsAssignableFrom(type)) { var instance = (DBCommand)Activator.CreateInstance(type); - PluginLoader.Commands.Add(instance); - Config.Logger.Log($"[CMD] Instance: {type.FullName} loaded !", Others.LogLevel.INFO); + Commands.Add(instance); + Config.Logger.Log($"[CMD] Instance: {type.FullName} loaded !", LogLevel.INFO); } else if (type.IsClass && typeof(DBSlashCommand).IsAssignableFrom(type)) { var instance = (DBSlashCommand)Activator.CreateInstance(type); - SlashCommandBuilder builder = new SlashCommandBuilder(); + var builder = new SlashCommandBuilder(); builder.WithName(instance.Name); builder.WithDescription(instance.Description); builder.WithDMPermission(instance.canUseDM); builder.Options = instance.Options; await client.CreateGlobalApplicationCommandAsync(builder.Build()); - PluginLoader.SlashCommands.Add(instance); - Config.Logger.Log($"[SLASH] Instance: {type.FullName} loaded !", Others.LogLevel.INFO); - + SlashCommands.Add(instance); + Config.Logger.Log($"[SLASH] Instance: {type.FullName} loaded !", LogLevel.INFO); } } -} \ No newline at end of file +} diff --git a/PluginManager/Online/Helpers/OnlineFunctions.cs b/PluginManager/Online/Helpers/OnlineFunctions.cs index 52c887d..36407cd 100644 --- a/PluginManager/Online/Helpers/OnlineFunctions.cs +++ b/PluginManager/Online/Helpers/OnlineFunctions.cs @@ -3,7 +3,6 @@ using System.IO; using System.Net.Http; using System.Threading; using System.Threading.Tasks; - using PluginManager.Others; namespace PluginManager.Online.Helpers; @@ -19,10 +18,11 @@ internal static class OnlineFunctions /// The that is used to track the download progress /// The cancellation token /// - internal static async Task DownloadFileAsync(this HttpClient client, string url, Stream destination, - IProgress? progress = null, - IProgress? downloadedBytes = null, int bufferSize = 81920, - CancellationToken cancellation = default) + internal static async Task DownloadFileAsync( + this HttpClient client, string url, Stream destination, + IProgress? progress = null, + IProgress? downloadedBytes = null, int bufferSize = 81920, + CancellationToken cancellation = default) { using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cancellation)) { @@ -40,11 +40,12 @@ internal static class OnlineFunctions // Convert absolute progress (bytes downloaded) into relative progress (0% - 100%) var relativeProgress = new Progress(totalBytes => - { - progress?.Report((float)totalBytes / contentLength.Value * 100); - downloadedBytes?.Report(totalBytes); - } - ); + { + progress?.Report((float)totalBytes / contentLength.Value * + 100); + downloadedBytes?.Report(totalBytes); + } + ); // Use extension method to report progress while downloading await download.CopyToOtherStreamAsync(destination, bufferSize, relativeProgress, cancellation); @@ -64,4 +65,4 @@ internal static class OnlineFunctions using var client = new HttpClient(); return await client.GetStringAsync(url, cancellation); } -} \ No newline at end of file +} diff --git a/PluginManager/Online/Helpers/VersionString.cs b/PluginManager/Online/Helpers/VersionString.cs index 760b962..15812d9 100644 --- a/PluginManager/Online/Helpers/VersionString.cs +++ b/PluginManager/Online/Helpers/VersionString.cs @@ -4,24 +4,6 @@ namespace PluginManager.Online.Helpers; public class VersionString { - private bool Equals(VersionString other) - { - return PackageCheckVersion == other.PackageCheckVersion && PackageMainVersion == other.PackageMainVersion && PackageVersionID == other.PackageVersionID; - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((VersionString)obj); - } - - public override int GetHashCode() - { - return HashCode.Combine(PackageCheckVersion, PackageMainVersion, PackageVersionID); - } - public int PackageCheckVersion; public int PackageMainVersion; public int PackageVersionID; @@ -33,20 +15,21 @@ public class VersionString { if (data.Length == 3) { - PackageVersionID = int.Parse(data[0]); - PackageMainVersion = int.Parse(data[1]); + PackageVersionID = int.Parse(data[0]); + PackageMainVersion = int.Parse(data[1]); PackageCheckVersion = int.Parse(data[2]); } else if (data.Length == 4) { // ignore the first item data[0] - PackageVersionID = int.Parse(data[1]); - PackageMainVersion = int.Parse(data[2]); + PackageVersionID = int.Parse(data[1]); + PackageMainVersion = int.Parse(data[2]); PackageCheckVersion = int.Parse(data[3]); } - else + else + { throw new Exception("Invalid version string"); - + } } catch (Exception ex) { @@ -55,6 +38,25 @@ public class VersionString } } + private bool Equals(VersionString other) + { + return PackageCheckVersion == other.PackageCheckVersion && PackageMainVersion == other.PackageMainVersion && + PackageVersionID == other.PackageVersionID; + } + + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals((VersionString)obj); + } + + public override int GetHashCode() + { + return HashCode.Combine(PackageCheckVersion, PackageMainVersion, PackageVersionID); + } + public override string ToString() { return "{PackageID: " + PackageVersionID + ", PackageVersion: " + PackageMainVersion + @@ -112,4 +114,4 @@ public class VersionString } #endregion -} \ No newline at end of file +} diff --git a/PluginManager/Online/PluginsManager.cs b/PluginManager/Online/PluginsManager.cs index 41a926e..4dbf17c 100644 --- a/PluginManager/Online/PluginsManager.cs +++ b/PluginManager/Online/PluginsManager.cs @@ -1,10 +1,8 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; - using PluginManager.Online.Helpers; using PluginManager.Others; - using OperatingSystem = PluginManager.Others.OperatingSystem; namespace PluginManager.Online; @@ -18,7 +16,7 @@ public class PluginsManager /// The link to the file where all plugin versions are stored public PluginsManager(string plink, string vlink) { - PluginsLink = plink; + PluginsLink = plink; VersionsLink = vlink; } @@ -26,7 +24,8 @@ public class PluginsManager /// The URL of the server /// public string PluginsLink { get; } - public string VersionsLink {get; } + + public string VersionsLink { get; } /// /// The method to load all plugins @@ -36,11 +35,11 @@ public class PluginsManager { try { - var list = await ServerCom.ReadTextFromURL(PluginsLink); + var list = await ServerCom.ReadTextFromURL(PluginsLink); var lines = list.ToArray(); var data = new List(); - var op = Functions.GetOperatingSystem(); + var op = Functions.GetOperatingSystem(); var len = lines.Length; for (var i = 0; i < len; i++) @@ -58,7 +57,7 @@ public class PluginsManager display[2] = content[2]; display[3] = (await GetVersionOfPackageFromWeb(content[0]) ?? new VersionString("0.0.0")) - .ToShortString(); + .ToShortString(); data.Add(display); } } @@ -71,7 +70,7 @@ public class PluginsManager display[2] = content[2]; display[3] = (await GetVersionOfPackageFromWeb(content[0]) ?? new VersionString("0.0.0")) - .ToShortString(); + .ToShortString(); data.Add(display); } } @@ -83,7 +82,8 @@ public class PluginsManager } catch (Exception exception) { - Config.Logger.Log("Failed to execute command: listplugs\nReason: " + exception.Message, this, LogLevel.ERROR); + Config.Logger.Log("Failed to execute command: listplugs\nReason: " + exception.Message, this, + LogLevel.ERROR); } return null; @@ -97,14 +97,15 @@ public class PluginsManager if (item.StartsWith("#")) continue; - string[] split = item.Split(','); + var split = item.Split(','); if (split[0] == pakName) { - Console.WriteLine("Searched for " + pakName + " and found " + split[1] + " as version.\nUsed url: " + VersionsLink); + Console.WriteLine("Searched for " + pakName + " and found " + split[1] + " as version.\nUsed url: " + + VersionsLink); return new VersionString(split[1]); } - } + return null; } @@ -117,9 +118,9 @@ public class PluginsManager { try { - var list = await ServerCom.ReadTextFromURL(PluginsLink); + var list = await ServerCom.ReadTextFromURL(PluginsLink); var lines = list.ToArray(); - var len = lines.Length; + var len = lines.Length; for (var i = 0; i < len; i++) { var contents = lines[i].Split(','); @@ -135,7 +136,8 @@ public class PluginsManager } catch (Exception exception) { - Config.Logger.Log("Failed to execute command: listplugs\nReason: " + exception.Message, this, LogLevel.ERROR); + Config.Logger.Log("Failed to execute command: listplugs\nReason: " + exception.Message, this, + LogLevel.ERROR); } return null; diff --git a/PluginManager/Online/ServerCom.cs b/PluginManager/Online/ServerCom.cs index b28fd4e..8c99abb 100644 --- a/PluginManager/Online/ServerCom.cs +++ b/PluginManager/Online/ServerCom.cs @@ -1,13 +1,10 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; -using System.Threading; using System.Threading.Tasks; -using System.Collections.Generic; - using PluginManager.Online.Helpers; -using PluginManager.Others; namespace PluginManager.Online; @@ -21,7 +18,7 @@ public static class ServerCom public static async Task> ReadTextFromURL(string link) { var response = await OnlineFunctions.DownloadStringAsync(link); - var lines = response.Split('\n'); + var lines = response.Split('\n'); return lines.ToList(); } @@ -32,8 +29,9 @@ public static class ServerCom /// The location where to store the downloaded data /// The to track the download /// - public static async Task DownloadFileAsync(string URL, string location, IProgress progress, - IProgress? downloadedBytes) + public static async Task DownloadFileAsync( + string URL, string location, IProgress progress, + IProgress? downloadedBytes) { using (var client = new HttpClient()) { @@ -50,4 +48,4 @@ public static class ServerCom { await DownloadFileAsync(URl, location, progress, null); } -} \ No newline at end of file +} diff --git a/PluginManager/Others/Actions/InternalActionsManager.cs b/PluginManager/Others/Actions/InternalActionsManager.cs index fb8667c..0020793 100644 --- a/PluginManager/Others/Actions/InternalActionsManager.cs +++ b/PluginManager/Others/Actions/InternalActionsManager.cs @@ -1,57 +1,58 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using PluginManager.Interfaces; using PluginManager.Loaders; -namespace PluginManager.Others.Actions +namespace PluginManager.Others.Actions; + +public class InternalActionManager { - public class InternalActionManager + public Dictionary Actions = new(); + public ActionsLoader loader; + + public InternalActionManager(string path, string extension) { - public ActionsLoader loader; - public Dictionary Actions = new Dictionary(); + loader = new ActionsLoader(path, extension); + } - public InternalActionManager(string path, string extension) + public async Task Initialize() + { + loader.ActionLoadedEvent += OnActionLoaded; + var m_actions = await loader.Load(); + if (m_actions == null) return; + foreach (var action in m_actions) + Actions.Add(action.ActionName, action); + } + + private void OnActionLoaded(string name, string typeName, bool success, Exception? e) + { + if (!success) { - loader = new ActionsLoader(path, extension); + Config.Logger.Error(e); + return; } - public async Task Initialize() + Config.Logger.Log($"Action {name} loaded successfully", typeName); + } + + public async Task Execute(string actionName, params string[]? args) + { + if (!Actions.ContainsKey(actionName)) { - loader.ActionLoadedEvent += OnActionLoaded; - var m_actions = await loader.Load(); - if(m_actions == null) return; - foreach(var action in m_actions) - Actions.Add(action.ActionName, action); + Config.Logger.Log($"Action {actionName} not found", "InternalActionManager", LogLevel.WARNING); + return "Action not found"; } - private void OnActionLoaded(string name, string typeName, bool success, Exception? e) + try { - if (!success) - { - Config.Logger.Error(e); - return; - } - - Config.Logger.Log($"Action {name} loaded successfully", typeName, LogLevel.INFO); + await Actions[actionName].Execute(args); + return "Action executed"; } - - public async Task Execute(string actionName, params string[]? args) + catch (Exception e) { - if (!Actions.ContainsKey(actionName)) - { - Config.Logger.Log($"Action {actionName} not found", "InternalActionManager", LogLevel.WARNING); - return "Action not found"; - } - - try{ - await Actions[actionName].Execute(args); - return "Action executed"; - }catch(Exception e){ - Config.Logger.Log(e.Message, "InternalActionManager", LogLevel.ERROR); - return e.Message; - } + Config.Logger.Log(e.Message, "InternalActionManager", LogLevel.ERROR); + return e.Message; } } } diff --git a/PluginManager/Others/ArchiveManager.cs b/PluginManager/Others/ArchiveManager.cs index 6197f6b..c4a77cb 100644 --- a/PluginManager/Others/ArchiveManager.cs +++ b/PluginManager/Others/ArchiveManager.cs @@ -4,136 +4,138 @@ using System.IO.Compression; using System.Linq; using System.Threading.Tasks; -namespace PluginManager.Others +namespace PluginManager.Others; + +public static class ArchiveManager { - public static class ArchiveManager + private static string? archiveFolder; + public static bool isInitialized { get; private set; } + + public static void Initialize() { - public static bool isInitialized { get; private set; } - private static string? archiveFolder; + if (isInitialized) throw new Exception("ArchiveManager is already initialized"); - public static void Initialize() + if (!Config.Data.ContainsKey("ArchiveFolder")) + Config.Data["ArchiveFolder"] = "./Data/PAKS/"; + + archiveFolder = Config.Data["ArchiveFolder"]; + + isInitialized = true; + } + + /// + /// Read data from a file that is inside an archive (ZIP format) + /// + /// The file name that is inside the archive or its full path + /// The archive location from the PAKs folder + /// A string that represents the content of the file or null if the file does not exists or it has no content + public static async Task ReadFromPakAsync(string FileName, string archFile) + { + if (!isInitialized) throw new Exception("ArchiveManager is not initialized"); + archFile = archiveFolder + archFile; + if (!File.Exists(archFile)) + throw new Exception("Failed to load file !"); + + try { - if (isInitialized) throw new Exception("ArchiveManager is already initialized"); - - if (!Config.Data.ContainsKey("ArchiveFolder")) - Config.Data["ArchiveFolder"] = "./Data/PAKS/"; - - archiveFolder = Config.Data["ArchiveFolder"]; - - isInitialized = true; - - } - /// - /// Read data from a file that is inside an archive (ZIP format) - /// - /// The file name that is inside the archive or its full path - /// The archive location from the PAKs folder - /// A string that represents the content of the file or null if the file does not exists or it has no content - public static async Task ReadFromPakAsync(string FileName, string archFile) - { - if (!isInitialized) throw new Exception("ArchiveManager is not initialized"); - archFile = archiveFolder + archFile; - if (!File.Exists(archFile)) - throw new Exception("Failed to load file !"); - - try - { - string? textValue = null; - using (var fs = new FileStream(archFile, FileMode.Open)) + string? textValue = null; + using (var fs = new FileStream(archFile, FileMode.Open)) using (var zip = new ZipArchive(fs, ZipArchiveMode.Read)) { foreach (var entry in zip.Entries) if (entry.Name == FileName || entry.FullName == FileName) using (var s = entry.Open()) - using (var reader = new StreamReader(s)) - { - textValue = await reader.ReadToEndAsync(); - reader.Close(); - s.Close(); - fs.Close(); - } + using (var reader = new StreamReader(s)) + { + textValue = await reader.ReadToEndAsync(); + reader.Close(); + s.Close(); + fs.Close(); + } } - return textValue; - } - catch (Exception ex) - { - Config.Logger.Log(ex.Message, "Archive Manager", LogLevel.ERROR); // Write the error to a file - await Task.Delay(100); - return await ReadFromPakAsync(FileName, archFile); - } + return textValue; } - - /// - /// Extract zip to location - /// - /// The zip location - /// The target location - /// The progress that is updated as a file is processed - /// The type of progress - /// - public static async Task ExtractArchive(string zip, string folder, IProgress progress, - UnzipProgressType type) + catch (Exception ex) { - if (!isInitialized) throw new Exception("ArchiveManager is not initialized"); - Directory.CreateDirectory(folder); - using (var archive = ZipFile.OpenRead(zip)) + Config.Logger.Log(ex.Message, "Archive Manager", LogLevel.ERROR); // Write the error to a file + await Task.Delay(100); + return await ReadFromPakAsync(FileName, archFile); + } + } + + /// + /// Extract zip to location + /// + /// The zip location + /// The target location + /// The progress that is updated as a file is processed + /// The type of progress + /// + public static async Task ExtractArchive( + string zip, string folder, IProgress progress, + UnzipProgressType type) + { + if (!isInitialized) throw new Exception("ArchiveManager is not initialized"); + Directory.CreateDirectory(folder); + using (var archive = ZipFile.OpenRead(zip)) + { + if (type == UnzipProgressType.PERCENTAGE_FROM_NUMBER_OF_FILES) { - if (type == UnzipProgressType.PERCENTAGE_FROM_NUMBER_OF_FILES) + var totalZIPFiles = archive.Entries.Count(); + var currentZIPFile = 0; + foreach (var entry in archive.Entries) { - var totalZIPFiles = archive.Entries.Count(); - var currentZIPFile = 0; - foreach (var entry in archive.Entries) - { - if (entry.FullName.EndsWith("/")) // it is a folder - Directory.CreateDirectory(Path.Combine(folder, entry.FullName)); - - else - try - { - entry.ExtractToFile(Path.Combine(folder, entry.FullName), true); - } - catch (Exception ex) - { - Config.Logger.Log($"Failed to extract {entry.Name}. Exception: {ex.Message}", "Archive Manager", LogLevel.ERROR); - } - - currentZIPFile++; - await Task.Delay(10); - if (progress != null) - progress.Report((float)currentZIPFile / totalZIPFiles * 100); - } - } - else if (type == UnzipProgressType.PERCENTAGE_FROM_TOTAL_SIZE) - { - ulong zipSize = 0; - - foreach (var entry in archive.Entries) - zipSize += (ulong)entry.CompressedLength; - - ulong currentSize = 0; - foreach (var entry in archive.Entries) - { - if (entry.FullName.EndsWith("/")) - { - Directory.CreateDirectory(Path.Combine(folder, entry.FullName)); - continue; - } + if (entry.FullName.EndsWith("/")) // it is a folder + Directory.CreateDirectory(Path.Combine(folder, entry.FullName)); + else try { entry.ExtractToFile(Path.Combine(folder, entry.FullName), true); - currentSize += (ulong)entry.CompressedLength; } catch (Exception ex) { - Config.Logger.Log($"Failed to extract {entry.Name}. Exception: {ex.Message}", "Archive Manager", LogLevel.ERROR); + Config.Logger.Log($"Failed to extract {entry.Name}. Exception: {ex.Message}", + "Archive Manager", LogLevel.ERROR); } - await Task.Delay(10); - if (progress != null) - progress.Report((float)currentSize / zipSize * 100); + currentZIPFile++; + await Task.Delay(10); + if (progress != null) + progress.Report((float)currentZIPFile / totalZIPFiles * 100); + } + } + else if (type == UnzipProgressType.PERCENTAGE_FROM_TOTAL_SIZE) + { + ulong zipSize = 0; + + foreach (var entry in archive.Entries) + zipSize += (ulong)entry.CompressedLength; + + ulong currentSize = 0; + foreach (var entry in archive.Entries) + { + if (entry.FullName.EndsWith("/")) + { + Directory.CreateDirectory(Path.Combine(folder, entry.FullName)); + continue; } + + try + { + entry.ExtractToFile(Path.Combine(folder, entry.FullName), true); + currentSize += (ulong)entry.CompressedLength; + } + catch (Exception ex) + { + Config.Logger.Log($"Failed to extract {entry.Name}. Exception: {ex.Message}", + "Archive Manager", LogLevel.ERROR); + } + + await Task.Delay(10); + if (progress != null) + progress.Report((float)currentSize / zipSize * 100); } } } diff --git a/PluginManager/Others/DBCommandExecutingArguments.cs b/PluginManager/Others/DBCommandExecutingArguments.cs index 4604abc..75141c5 100644 --- a/PluginManager/Others/DBCommandExecutingArguments.cs +++ b/PluginManager/Others/DBCommandExecutingArguments.cs @@ -1,27 +1,20 @@ using Discord.Commands; -using Discord.WebSocket; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace PluginManager.Others +namespace PluginManager.Others; + +public class DBCommandExecutingArguments { - public class DBCommandExecutingArguments + public DBCommandExecutingArguments( + SocketCommandContext context, string cleanContent, string commandUsed, string[]? arguments) { - public SocketCommandContext context { get; init; } - public string cleanContent { get; init; } - public string commandUsed { get;init; } - public string[]? arguments { get;init; } - - public DBCommandExecutingArguments(SocketCommandContext context, string cleanContent, string commandUsed, string[]? arguments) - { - this.context = context; - this.cleanContent = cleanContent; - this.commandUsed = commandUsed; - this.arguments = arguments; - } - + this.context = context; + this.cleanContent = cleanContent; + this.commandUsed = commandUsed; + this.arguments = arguments; } + + public SocketCommandContext context { get; init; } + public string cleanContent { get; init; } + public string commandUsed { get; init; } + public string[]? arguments { get; init; } } diff --git a/PluginManager/Others/Enums.cs b/PluginManager/Others/Enums.cs index bace71c..65952ef 100644 --- a/PluginManager/Others/Enums.cs +++ b/PluginManager/Others/Enums.cs @@ -39,4 +39,4 @@ public enum InternalActionRunType { ON_STARTUP, ON_CALL -} \ No newline at end of file +} diff --git a/PluginManager/Others/Functions.cs b/PluginManager/Others/Functions.cs index 5e2bfab..5c6ad0c 100644 --- a/PluginManager/Others/Functions.cs +++ b/PluginManager/Others/Functions.cs @@ -19,6 +19,15 @@ public static class Functions /// public static readonly string dataFolder = @"./Data/Resources/"; + public static Color RandomColor + { + get + { + var random = new Random(); + return new Color(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255)); + } + } + /// /// Get the Operating system you are runnin on /// @@ -43,9 +52,10 @@ public static class Functions /// Triggered if is less then or equal to 0 /// Triggered if is not readable /// Triggered in is not writable - public static async Task CopyToOtherStreamAsync(this Stream stream, Stream destination, int bufferSize, - IProgress? progress = null, - CancellationToken cancellationToken = default) + public static async Task CopyToOtherStreamAsync( + this Stream stream, Stream destination, int bufferSize, + IProgress? progress = null, + CancellationToken cancellationToken = default) { if (stream == null) throw new ArgumentNullException(nameof(stream)); if (destination == null) throw new ArgumentNullException(nameof(destination)); @@ -54,10 +64,11 @@ public static class Functions if (!destination.CanWrite) throw new ArgumentException("Destination stream is not writable", nameof(destination)); - var buffer = new byte[bufferSize]; + var buffer = new byte[bufferSize]; long totalBytesRead = 0; - int bytesRead; - while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0) + int bytesRead; + while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken) + .ConfigureAwait(false)) != 0) { await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false); totalBytesRead += bytesRead; @@ -102,9 +113,9 @@ public static class Functions return (obj ?? default)!; } - public static T SelectRandomValueOf () + public static T SelectRandomValueOf() { - var enums = Enum.GetValues(typeof(T)); + var enums = Enum.GetValues(typeof(T)); var random = new Random(); return (T)enums.GetValue(random.Next(enums.Length)); } @@ -114,13 +125,4 @@ public static class Functions Random random = new(); return values[random.Next(values.Length)]; } - - public static Discord.Color RandomColor - { - get - { - Random random = new Random(); - return new Discord.Color(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255)); - } - } -} \ No newline at end of file +} diff --git a/PluginManager/Others/Logger/DBLogger.cs b/PluginManager/Others/Logger/DBLogger.cs index cc7d768..9c5b0a8 100644 --- a/PluginManager/Others/Logger/DBLogger.cs +++ b/PluginManager/Others/Logger/DBLogger.cs @@ -1,53 +1,60 @@ using System; using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace PluginManager.Others.Logger +namespace PluginManager.Others.Logger; + +public class DBLogger { - public class DBLogger + public delegate void LogHandler(string message, LogLevel logType); + + private readonly string _errFolder; + + private readonly string _logFolder; + private readonly List ErrorHistory = new(); + private readonly List LogHistory = new(); + + public DBLogger() { - - private List LogHistory = new List(); - private List ErrorHistory = new List(); + _logFolder = Config.Data["LogFolder"]; + _errFolder = Config.Data["ErrorFolder"]; + } - public IReadOnlyList Logs => LogHistory; - public IReadOnlyList Errors => ErrorHistory; + public IReadOnlyList Logs => LogHistory; + public IReadOnlyList Errors => ErrorHistory; - public delegate void LogHandler(string message, LogLevel logType); - public event LogHandler LogEvent; + public event LogHandler LogEvent; - private string _logFolder; - private string _errFolder; + public void Log(string message, string sender = "unknown", LogLevel type = LogLevel.INFO) + { + Log(new LogMessage(message, type, sender)); + } - public DBLogger() - { - _logFolder = Config.Data["LogFolder"]; - _errFolder = Config.Data["ErrorFolder"]; - } + public void Error(Exception? e) + { + Log(e.Message, e.Source, LogLevel.ERROR); + } - public void Log(string message, string sender = "unknown", LogLevel type = LogLevel.INFO) => Log(new LogMessage(message, type, sender)); - public void Error(Exception? e) => Log(e.Message, e.Source, LogLevel.ERROR); + public void Log(LogMessage message) + { + if (LogEvent is not null) + LogEvent?.Invoke(message.Message, message.Type); - public void Log(LogMessage message) - { - if(LogEvent is not null) - LogEvent?.Invoke(message.Message, message.Type); + if (message.Type != LogLevel.ERROR && message.Type != LogLevel.CRITICAL) + LogHistory.Add(message); + else + ErrorHistory.Add(message); + } - if (message.Type != LogLevel.ERROR && message.Type != LogLevel.CRITICAL) - LogHistory.Add(message); - else - ErrorHistory.Add(message); - } + public void Log(string message, object sender, LogLevel type = LogLevel.NONE) + { + Log(message, sender.GetType().Name, type); + } - public void Log(string message, object sender, LogLevel type = LogLevel.NONE) => Log(message, sender.GetType().Name, type); - - public async void SaveToFile() - { - await Functions.SaveToJsonFile(_logFolder + "/" + DateTime.Now.ToString("yyyy-MM-dd") + ".json", LogHistory); - await Functions.SaveToJsonFile(_errFolder + "/" + DateTime.Now.ToString("yyyy-MM-dd") + ".json", ErrorHistory); - } + public async void SaveToFile() + { + await Functions.SaveToJsonFile(_logFolder + "/" + DateTime.Now.ToString("yyyy-MM-dd") + ".json", + LogHistory); + await Functions.SaveToJsonFile(_errFolder + "/" + DateTime.Now.ToString("yyyy-MM-dd") + ".json", + ErrorHistory); } } diff --git a/PluginManager/Others/Logger/LogMessage.cs b/PluginManager/Others/Logger/LogMessage.cs index bc9b0a7..1dd75e0 100644 --- a/PluginManager/Others/Logger/LogMessage.cs +++ b/PluginManager/Others/Logger/LogMessage.cs @@ -1,47 +1,43 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace PluginManager.Others.Logger +namespace PluginManager.Others.Logger; + +public class LogMessage { - public class LogMessage + public LogMessage(string message, LogLevel type) { - public string Message { get; set; } - public LogLevel Type { get; set; } - public string Time { get; set; } - public string Sender { get; set; } - public LogMessage(string message, LogLevel type) - { - Message = message; - Type = type; - Time = DateTime.Now.ToString("HH:mm:ss"); - } + Message = message; + Type = type; + Time = DateTime.Now.ToString("HH:mm:ss"); + } - public LogMessage(string message, LogLevel type, string sender) : this(message, type) - { - Sender = sender; - } + public LogMessage(string message, LogLevel type, string sender) : this(message, type) + { + Sender = sender; + } - public override string ToString() - { - return $"[{Time}] {Message}"; - } + public string Message { get; set; } + public LogLevel Type { get; set; } + public string Time { get; set; } + public string Sender { get; set; } - public static explicit operator LogMessage(string message) - { - return new LogMessage(message, LogLevel.INFO); - } + public override string ToString() + { + return $"[{Time}] {Message}"; + } - public static explicit operator LogMessage((string message, LogLevel type) tuple) - { - return new LogMessage(tuple.message, tuple.type); - } + public static explicit operator LogMessage(string message) + { + return new LogMessage(message, LogLevel.INFO); + } - public static explicit operator LogMessage((string message, LogLevel type, string sender) tuple) - { - return new LogMessage(tuple.message, tuple.type, tuple.sender); - } + public static explicit operator LogMessage((string message, LogLevel type) tuple) + { + return new LogMessage(tuple.message, tuple.type); + } + + public static explicit operator LogMessage((string message, LogLevel type, string sender) tuple) + { + return new LogMessage(tuple.message, tuple.type, tuple.sender); } } diff --git a/PluginManager/Others/Permissions/DiscordPermissions.cs b/PluginManager/Others/Permissions/DiscordPermissions.cs index 9cafe83..e8fae3b 100644 --- a/PluginManager/Others/Permissions/DiscordPermissions.cs +++ b/PluginManager/Others/Permissions/DiscordPermissions.cs @@ -1,5 +1,4 @@ using System.Linq; - using Discord; using Discord.WebSocket; @@ -62,4 +61,4 @@ public static class DiscordPermissions { return isAdmin((SocketGuildUser)user); } -} \ No newline at end of file +} diff --git a/PluginManager/PluginManager.csproj b/PluginManager/PluginManager.csproj index 74b68cc..93e5a4a 100644 --- a/PluginManager/PluginManager.csproj +++ b/PluginManager/PluginManager.csproj @@ -1,18 +1,18 @@ - - net6.0 - enable - - - 512 - none - false - - - - - - - - + + net6.0 + enable + + + 512 + none + false + + + + + + + + \ No newline at end of file