From 4855c8495d18d3dd73c67bd50f3587111756fd33 Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Fri, 27 May 2022 16:45:09 +0300 Subject: [PATCH 01/20] From 1ae48a100e1033a0ee0589946f5639c533b2148e Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Thu, 2 Jun 2022 13:48:40 +0300 Subject: [PATCH 02/20] Plugin Loader reworked --- PluginManager/BlankWindow1.xaml | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 PluginManager/BlankWindow1.xaml diff --git a/PluginManager/BlankWindow1.xaml b/PluginManager/BlankWindow1.xaml deleted file mode 100644 index c5e0d39..0000000 --- a/PluginManager/BlankWindow1.xaml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - From 3e01e75de3f5baa0a892ff9f3123e665ccda7f2a Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Thu, 2 Jun 2022 13:48:56 +0300 Subject: [PATCH 03/20] patch for UI --- .../.idea.DiscordBotWithAPI/.idea/.gitignore | 13 +++ .../.idea/avalonia.xml | 13 +++ .../.idea/encodings.xml | 4 + .../.idea/indexLayout.xml | 8 ++ .idea/.idea.DiscordBotWithAPI/.idea/vcs.xml | 6 ++ BUILDS/net6.0/EVE_LevelingSystem.dll | Bin 11776 -> 11776 bytes BUILDS/net6.0/PluginManager.dll | Bin 61952 -> 62976 bytes DiscordBot/App.config | 11 +- DiscordBot/Discord/Commands/Help.cs | 9 +- DiscordBot/Discord/Core/CommandHandler.cs | 2 +- DiscordBot/Program.cs | 69 +++++------- DiscordBotGUI/App.axaml.cs | 10 +- DiscordBotGUI/AppUpdater.axaml.cs | 56 +++++----- DiscordBotWithAPI.sln | 7 -- PluginManager/Loaders/CommandsLoader.cs | 99 ----------------- PluginManager/Loaders/EventsLoader.cs | 100 ------------------ PluginManager/Loaders/Loader.cs | 94 ++++++++++++++++ PluginManager/Loaders/PluginLoader.cs | 68 ++++++------ PluginManager/Others/Console Utilities.cs | 36 ++++--- PluginManager/Others/Functions.cs | 13 +-- PluginManager/PluginManager.csproj | 6 -- 21 files changed, 265 insertions(+), 359 deletions(-) create mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/.gitignore create mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml create mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/encodings.xml create mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml create mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/vcs.xml delete mode 100644 PluginManager/Loaders/CommandsLoader.cs delete mode 100644 PluginManager/Loaders/EventsLoader.cs create mode 100644 PluginManager/Loaders/Loader.cs diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/.gitignore b/.idea/.idea.DiscordBotWithAPI/.idea/.gitignore new file mode 100644 index 0000000..1e2399a --- /dev/null +++ b/.idea/.idea.DiscordBotWithAPI/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/modules.xml +/contentModel.xml +/.idea.DiscordBotWithAPI.iml +/projectSettingsUpdater.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml b/.idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml new file mode 100644 index 0000000..c0fdb9d --- /dev/null +++ b/.idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/encodings.xml b/.idea/.idea.DiscordBotWithAPI/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/.idea/.idea.DiscordBotWithAPI/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml b/.idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/vcs.xml b/.idea/.idea.DiscordBotWithAPI/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/.idea.DiscordBotWithAPI/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/BUILDS/net6.0/EVE_LevelingSystem.dll b/BUILDS/net6.0/EVE_LevelingSystem.dll index e44346107e2f2c1203421bedc78994df8fa0da88..58c77e5e96d071e9830f8b1b8a63fdbfe13f1d1d 100644 GIT binary patch delta 238 zcmZpOX^5H7!J@HqdgsI*8AhdvE5jKtOlD+MXWin=z#ubOkx6HAB%?Z`#^grEdPbJX zj7-9;4N?pYjFTPJ%r^%xX|r()Gcputh%zv66Ov2@C84pHo3;r#)0CkzNpeyb|Y$g-JJ cjg@J#1EauZK8;_@Oe!Xu1$EvtPBdT#00Y`Qx&QzG delta 250 zcmZpOX^5H7!IGcua(QBp45QJ+mEnvJCNnasvmS9~V33)t$fPqll2M(}Vsay6J)_8E zMkZm_2~rFUjFS!3%r^%xX|r)FGcputh%zv66?so?--lGI^hU{DSXW)Ki#U=UycvfV>HU4XR0=84=5A{v^>42cXm4EYSj3txn^7QZg<5Fst2@rq&owVEWn37w*+sF3g_i?l k9uz1|zN;$DD6;vdDl5}wK8;_@OeQ9q1$EvtPBdT#05}Rjwg3PC diff --git a/BUILDS/net6.0/PluginManager.dll b/BUILDS/net6.0/PluginManager.dll index 856115d475eef34cc74c0721d43092668387d9b8..484c585cfad2bab1d5678c0b02ae8e2c84a55d37 100644 GIT binary patch literal 62976 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 eM>lRG8vi8xG`$!M}B+TXi=kUW);J*ONy-Csl literal 61952 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 W_(XQF^ve(aGW6yD`|$Hp;J*P$&{(Jd diff --git a/DiscordBot/App.config b/DiscordBot/App.config index 2a5ff10..828bd34 100644 --- a/DiscordBot/App.config +++ b/DiscordBot/App.config @@ -1,4 +1,7 @@ - - - - \ No newline at end of file + + + + + + + diff --git a/DiscordBot/Discord/Commands/Help.cs b/DiscordBot/Discord/Commands/Help.cs index 67840a5..26a1c51 100644 --- a/DiscordBot/Discord/Commands/Help.cs +++ b/DiscordBot/Discord/Commands/Help.cs @@ -75,12 +75,11 @@ namespace DiscordBot.Discord.Commands string normalCommands = ""; string DMCommands = ""; - foreach (var cmd in PluginLoader.Plugins!) + foreach (var cmd in PluginLoader.Commands!) { - if (cmd.canUseDM) - DMCommands += cmd.Command + " "; + if (cmd.canUseDM) DMCommands += cmd.Command + " "; if (cmd.requireAdmin) - adminCommands += cmd.Command + " "; + adminCommands += cmd.Command + " "; else if (cmd.canUseServer) normalCommands += cmd.Command + " "; } @@ -94,7 +93,7 @@ namespace DiscordBot.Discord.Commands private EmbedBuilder GenerateHelpCommand(string command) { EmbedBuilder embedBuilder = new EmbedBuilder(); - DBCommand cmd = PluginLoader.Plugins.Find(p => p.Command == command); + DBCommand cmd = PluginLoader.Commands.Find(p => p.Command == command); if (cmd == null) return null; diff --git a/DiscordBot/Discord/Core/CommandHandler.cs b/DiscordBot/Discord/Core/CommandHandler.cs index 5ed266b..b877f79 100644 --- a/DiscordBot/Discord/Core/CommandHandler.cs +++ b/DiscordBot/Discord/Core/CommandHandler.cs @@ -80,7 +80,7 @@ namespace PluginManager.Core services: null ); - DBCommand plugin = PluginLoader.Plugins!.Where(p => p.Command == (message.Content.Split(' ')[0]).Substring(botPrefix.Length)).FirstOrDefault(); + DBCommand plugin = PluginLoader.Commands!.Where(p => p.Command == (message.Content.Split(' ')[0]).Substring(botPrefix.Length)).FirstOrDefault(); if (plugin != null) diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index 9c1a719..903d078 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -1,16 +1,14 @@ using Discord; - using System; using System.IO; using System.Threading.Tasks; - using PluginManager.Core; using PluginManager.Others; using PluginManager.LanguageSystem; using PluginManager.Online; - using System.Collections.Generic; using System.Linq; +using System.Threading; using PluginManager.Items; namespace DiscordBot @@ -20,21 +18,23 @@ namespace DiscordBot private static bool loadPluginsOnStartup = false; private static bool listPluginsAtStartup = false; private static bool listLanguagAtStartup = false; - - private static bool ShowStartupMessage = true; + //private static bool ShowStartupMessage = true; /// /// The main entry point for the application. /// [STAThread] [Obsolete] - public static void Main(string[] args) { Directory.CreateDirectory("./Data/Resources"); Directory.CreateDirectory("./Data/Languages"); Directory.CreateDirectory("./Data/Plugins/Commands"); Directory.CreateDirectory("./Data/Plugins/Events"); + Directory.CreateDirectory("./Data/runtime"); + + AppDomain.CurrentDomain.AppendPrivatePath("./Data/runtime"); + if (!File.Exists("./Data/Resources/DiscordBotCore.data") || (Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN", '=').Length != 59 && Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN", '=').Length != 70)) { File.WriteAllText("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN=token\nBOT_PREFIX=!\n"); @@ -45,13 +45,13 @@ namespace DiscordBot string botToken = Console.ReadLine(); if (botToken.Length == 59 || botToken.Length == 70) { - string prefix = Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_PREFIX", '='); - if (prefix == string.Empty || prefix == null) - prefix = "!"; + string prefix = Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_PREFIX", '='); + if (prefix == string.Empty || prefix == null) prefix = "!"; File.WriteAllText("./Data/Resources/DiscordBotCore.data", $"BOT_TOKEN={botToken}\nBOT_PREFIX={prefix}\n"); break; } - else Console.WriteLine("Invalid Token !"); + else + Console.WriteLine("Invalid Token !"); } } @@ -72,17 +72,14 @@ namespace DiscordBot /// The main loop for the discord bot /// /// The discord booter used to start the application - private static async Task NoGUI(Boot discordbooter) + private static Task NoGUI(Boot discordbooter) { Language.LoadLanguage(); ConsoleCommandsHandler consoleCommandsHandler = new ConsoleCommandsHandler(discordbooter.client); - if (loadPluginsOnStartup) - consoleCommandsHandler.HandleCommand("lp"); - if (listPluginsAtStartup) - consoleCommandsHandler.HandleCommand("listplugs"); - if (listLanguagAtStartup) - consoleCommandsHandler.HandleCommand("listlang"); + if (loadPluginsOnStartup) consoleCommandsHandler.HandleCommand("lp"); + if (listPluginsAtStartup) consoleCommandsHandler.HandleCommand("listplugs"); + if (listLanguagAtStartup) consoleCommandsHandler.HandleCommand("listlang"); while (true) { @@ -98,23 +95,14 @@ namespace DiscordBot /// Returns the boot loader for the Discord Bot private static async Task StartNoGUI() { - Console.Clear(); Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine("Discord BOT for Cross Platform"); Console.WriteLine("Created by: Wizzy\nDiscord: Wizzy#9181"); - if (ShowStartupMessage) - try - { - Console.WriteLine("Connecting to server ..."); - List text = await ServerCom.ReadTextFromFile("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/StartupMessage"); - foreach (var t in text) Console_Utilities.WriteColorText(t); - } - catch { Console.WriteLine("Failed to connect to server."); } Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("============================ Discord BOT - Cross Platform ============================"); - string token = Functions.readCodeFromFile(Functions.dataFolder + "DiscordBotCore.data", "BOT_TOKEN", '='); + string token = Functions.readCodeFromFile(Functions.dataFolder + "DiscordBotCore.data", "BOT_TOKEN", '='); string prefix = Functions.readCodeFromFile(Functions.dataFolder + "DiscordBotCore.data", "BOT_PREFIX", '='); var discordbooter = new Boot(token, prefix); @@ -128,8 +116,8 @@ namespace DiscordBot /// Directory path private static Task ClearFolder(string d) { - string[] files = Directory.GetFiles(d); - int fileNumb = files.Length; + string[] files = Directory.GetFiles(d); + int fileNumb = files.Length; for (var i = 0; i < fileNumb; i++) { File.Delete(files[i]); @@ -145,7 +133,6 @@ namespace DiscordBot /// The arguments private static async Task HandleInput(string[] args) { - if (args.Length == 0) { if (File.Exists("./ref/startupArguments.txt")) @@ -164,8 +151,12 @@ namespace DiscordBot if (len == 1 && args[0] == "--logout") { - File.Delete(Functions.dataFolder + "Login.dat"); - Console.WriteLine("Logged out. Please restart the application !"); + File.Delete(Functions.dataFolder + "DiscordBotCore.dat"); + await Task.Run(async () => + { + await Task.Delay(1000); + Environment.Exit(0x08); + }); return; } @@ -179,20 +170,14 @@ namespace DiscordBot if (len > 0 && (args.Contains("--cmd") || args.Contains("--args") || args.Contains("--nomessage"))) { - if (args.Contains("lp") || args.Contains("loadplugins")) - loadPluginsOnStartup = true; - if (args.Contains("listplugs")) - listPluginsAtStartup = true; - if (args.Contains("listlang")) - listLanguagAtStartup = true; - if (args.Contains("--nomessage")) - ShowStartupMessage = false; + if (args.Contains("lp") || args.Contains("loadplugins")) loadPluginsOnStartup = true; + if (args.Contains("listplugs")) listPluginsAtStartup = true; + if (args.Contains("listlang")) listLanguagAtStartup = true; + //if (args.Contains("--nomessage")) ShowStartupMessage = false; len = 0; } - - if (len == 0 || args[0] != "--exec" && args[0] != "--execute") { Boot b = await StartNoGUI(); diff --git a/DiscordBotGUI/App.axaml.cs b/DiscordBotGUI/App.axaml.cs index a3b2c89..456aca5 100644 --- a/DiscordBotGUI/App.axaml.cs +++ b/DiscordBotGUI/App.axaml.cs @@ -1,6 +1,8 @@ +using System.IO; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; +using PluginManager.Others; namespace DiscordBotGUI { @@ -13,13 +15,7 @@ namespace DiscordBotGUI public override void OnFrameworkInitializationCompleted() { - if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) - { - - - desktop.MainWindow = new AppUpdater() { Width = 300, Height = 50, WindowStartupLocation = Avalonia.Controls.WindowStartupLocation.CenterScreen }; - - } + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { desktop.MainWindow = new AppUpdater() { Width = 300, Height = 50, WindowStartupLocation = Avalonia.Controls.WindowStartupLocation.CenterScreen }; } base.OnFrameworkInitializationCompleted(); } diff --git a/DiscordBotGUI/AppUpdater.axaml.cs b/DiscordBotGUI/AppUpdater.axaml.cs index ecc5405..8c4dccc 100644 --- a/DiscordBotGUI/AppUpdater.axaml.cs +++ b/DiscordBotGUI/AppUpdater.axaml.cs @@ -21,42 +21,48 @@ namespace DiscordBotGUI InitializeComponent(); if (!File.Exists("./Version.txt")) { - textBox1.Text = "Checking ..."; File.WriteAllText("./Version.txt", "DiscordBotVersion=0"); - //DownloadDiscordBotClientNoGUIAsDLL(); + DownloadDiscordBotClientNoGUIAsDLL(); } + if (!File.Exists("./DiscordBot.exe")) DownloadDiscordBotClientNoGUIAsDLL(); Updates(); } - /* private async void DownloadDiscordBotClientNoGUIAsDLL() - { + private async void DownloadDiscordBotClientNoGUIAsDLL() + { + //await Task.Delay(5000); + string url_bot_dll = "https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Updates/DiscordBot.zip"; + int actiontype = 0; //0 - downolad, 1- extract + IProgress progress = new Progress((percent) => + { + if (actiontype == 0) + textBox1.Text = "Downloading DiscordBot ... " + MathF.Round(percent, 2) + "%"; + else + textBox1.Text = "Extracting package ..." + MathF.Round(percent, 2) + "%"; + this.progressBar1.Value = percent; + }); - //await Task.Delay(5000); - string url_bot_dll = "https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Updates/DiscordBot.dll"; - IProgress progress = new Progress((percent) => - { - textBox1.Text = "Downloading DiscordBot.dll ... " + (percent * 100).ToString() + "%"; - this.progressBar1.Value = percent * 100; - }); + this.progressBar1.IsIndeterminate = false; + try + { + await ServerCom.DownloadFileAsync(url_bot_dll, "./DiscordBot.zip", progress); - this.progressBar1.IsIndeterminate = false; - try - { - await ServerCom.DownloadFileAsync(url_bot_dll, "./DiscordBot.dll", progress); - } - catch - { - textBox1.Text = "Error downloading DiscordBot.dll. Server is not responding."; + actiontype++; - await Task.Delay(1000); - return; - } + await Functions.ExtractArchive("./DiscordBot.zip", "./", progress); + } + catch + { + textBox1.Text = "Error downloading DiscordBot.dll. Server is not responding."; - //new MainWindow() { Height = 425, Width = 500 }.Show(); - //Close(); - }*/ + await Task.Delay(1000); + + new MainWindow() { Height = 425, Width = 500 }.Show(); + Close(); + } + } private async void Updates() { diff --git a/DiscordBotWithAPI.sln b/DiscordBotWithAPI.sln index 3f9ab41..7bf0ffe 100644 --- a/DiscordBotWithAPI.sln +++ b/DiscordBotWithAPI.sln @@ -23,8 +23,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CMD_Utils", "CMD_Utils\CMD_ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MusicCommands", "MusicCommands\MusicCommands.csproj", "{B1B4976E-5112-4217-B57B-3A03C5207B6E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Games", "FreeGames\Games.csproj", "{7CC0819E-2BC0-44F0-8D92-EC442F36E1BB}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordBotGUI", "DiscordBotGUI\DiscordBotGUI.csproj", "{7B5899F0-0218-4537-8C74-6210ED2D3690}" EndProject Global @@ -61,10 +59,6 @@ Global {B1B4976E-5112-4217-B57B-3A03C5207B6E}.Debug|Any CPU.Build.0 = Debug|Any CPU {B1B4976E-5112-4217-B57B-3A03C5207B6E}.Release|Any CPU.ActiveCfg = Release|Any CPU {B1B4976E-5112-4217-B57B-3A03C5207B6E}.Release|Any CPU.Build.0 = Release|Any CPU - {7CC0819E-2BC0-44F0-8D92-EC442F36E1BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7CC0819E-2BC0-44F0-8D92-EC442F36E1BB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7CC0819E-2BC0-44F0-8D92-EC442F36E1BB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7CC0819E-2BC0-44F0-8D92-EC442F36E1BB}.Release|Any CPU.Build.0 = Release|Any CPU {7B5899F0-0218-4537-8C74-6210ED2D3690}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7B5899F0-0218-4537-8C74-6210ED2D3690}.Debug|Any CPU.Build.0 = Debug|Any CPU {7B5899F0-0218-4537-8C74-6210ED2D3690}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -81,7 +75,6 @@ Global {CE9DBF06-38A0-4192-8B3E-4009210D040D} = {A290C028-77C4-4D1D-AB43-DDFE6ABD9012} {E26C87A4-3DD6-4B58-B14B-C8E086B852F9} = {449FA364-0B72-43FF-B3A3-806E2916200E} {B1B4976E-5112-4217-B57B-3A03C5207B6E} = {449FA364-0B72-43FF-B3A3-806E2916200E} - {7CC0819E-2BC0-44F0-8D92-EC442F36E1BB} = {449FA364-0B72-43FF-B3A3-806E2916200E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3FB3C5DE-ED21-4D2E-ABDD-3A00EE4A2FFF} diff --git a/PluginManager/Loaders/CommandsLoader.cs b/PluginManager/Loaders/CommandsLoader.cs deleted file mode 100644 index 919fa6b..0000000 --- a/PluginManager/Loaders/CommandsLoader.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; - -using PluginManager.Interfaces; - -namespace PluginManager.Loaders -{ - internal class CommandsLoader - { - private readonly string CMDPath; - private readonly string CMDExtension; - - - internal delegate void onCommandLoaded(string name, bool success, DBCommand? command = null, Exception? exception = null); - internal delegate void onCommandFileLoaded(string path); - - /// - /// Event fired when a command is loaded - /// - internal onCommandLoaded? OnCommandLoaded; - - /// - /// Event fired when the file is loaded - /// - internal onCommandFileLoaded? OnCommandFileLoaded; - - /// - /// Command Loader contructor - /// - /// The path to the commands - /// The extension to search for in the - internal CommandsLoader(string CommandPath, string CommandExtension) - { - CMDPath = CommandPath; - CMDExtension = CommandExtension; - } - - /// - /// The method that loads all commands - /// - /// - internal List? LoadCommands() - { - if (!Directory.Exists(CMDPath)) - { - Directory.CreateDirectory(CMDPath); - return null; - } - string[] files = Directory.GetFiles(CMDPath, $"*{CMDExtension}", SearchOption.AllDirectories); - - foreach (var file in files) - { - Assembly.LoadFile(Path.GetFullPath(file)); - if (OnCommandFileLoaded != null) - OnCommandFileLoaded.Invoke(file); - } - - List plugins = new List(); - - try - { - Type interfaceType = typeof(DBCommand); - Type[] types = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(a => a.GetTypes()) - .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) - .ToArray(); - foreach (Type type in types) - { - try - { - DBCommand plugin = (DBCommand)Activator.CreateInstance(type)!; - plugins.Add(plugin); - - if (OnCommandLoaded != null) - OnCommandLoaded.Invoke(type.FullName!, true, plugin); - } - catch (Exception e) - { - if (OnCommandLoaded != null) - OnCommandLoaded.Invoke(type.FullName!, false, null, e); - } - - } - - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - return null; - } - - return plugins; - - } - } -} diff --git a/PluginManager/Loaders/EventsLoader.cs b/PluginManager/Loaders/EventsLoader.cs deleted file mode 100644 index 28c1766..0000000 --- a/PluginManager/Loaders/EventsLoader.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; - -using PluginManager.Interfaces; - -namespace PluginManager.Loaders -{ - internal class EventsLoader - { - - private readonly string EVPath; - private readonly string EVExtension; - - internal delegate void onEventLoad(string name, bool success, DBEvent? ev = null, Exception? e = null); - internal delegate void onEventFileLoaded(string path); - - /// - /// An event that is fired whenever a event is loaded in memory - /// - internal onEventLoad? EventLoad; - - /// - /// An event that is fired whenever a event file is loaded - /// - internal onEventFileLoaded? EventFileLoaded; - - /// - /// The Event Loader constructor - /// - /// The path to all events - /// The extension for events - internal EventsLoader(string path, string ext) - { - EVPath = path; - EVExtension = ext; - } - - /// - /// The method that loads all events - /// - /// - internal List? LoadEvents() - { - - if (!Directory.Exists(EVPath)) - { - Directory.CreateDirectory(EVPath); - return null; - } - - string[] files = Directory.GetFiles(EVPath, $"*{EVExtension}", SearchOption.AllDirectories); - - foreach (var file in files) - { - Assembly.LoadFile(Path.GetFullPath(file)); - if (EventFileLoaded != null) - EventFileLoaded.Invoke(file); - } - - List events = new List(); - - try - { - Type interfaceType = typeof(DBEvent); - Type[] types = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(a => a.GetTypes()) - .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) - .ToArray(); - foreach (Type type in types) - { - try - { - DBEvent ev = (DBEvent)Activator.CreateInstance(type)!; - events.Add(ev); - - if (EventLoad != null) - EventLoad.Invoke(type.FullName!, true, ev, null); - } - catch (Exception e) - { - if (EventLoad != null) - EventLoad.Invoke(type.FullName!, false, null, e); - } - - } - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - return null; - } - - return events; - - } - } -} \ No newline at end of file diff --git a/PluginManager/Loaders/Loader.cs b/PluginManager/Loaders/Loader.cs new file mode 100644 index 0000000..955bc9f --- /dev/null +++ b/PluginManager/Loaders/Loader.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.CompilerServices; +using PluginManager.Interfaces; +using PluginManager.Others; + +namespace PluginManager.Loaders +{ + 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 delegate void FileLoadedEventHandler(LoaderArgs args); + + internal event FileLoadedEventHandler? FileLoaded; + + internal delegate void PluginLoadedEventHandler(LoaderArgs args); + + internal event PluginLoadedEventHandler? PluginLoaded; + + + private string path { get; } + private string extension { get; } + + + internal Loader(string path, string extension) + { + this.path = path; + this.extension = extension; + } + + internal List? Load() + { + List list = new List(); + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + return null; + } + + string[] files = Directory.GetFiles(path, $"*.{extension}", SearchOption.AllDirectories); + foreach (var file in files) + { + Assembly.LoadFrom(file); + if (FileLoaded != null) + { + LoaderArgs args = new LoaderArgs() { Exception = null, TypeName = nameof(T), IsLoaded = false, PluginName = file, Plugin = null }; + FileLoaded.Invoke(args); + } + } + + try + { + Type interfaceType = typeof(T); + Type[] types = AppDomain.CurrentDomain.GetAssemblies() + .SelectMany(a => a.GetTypes()) + .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) + .ToArray(); + + + list.Clear(); + foreach (Type type in types) + { + try + { + T plugin = (T)(Activator.CreateInstance(type)!); + list.Add(plugin); + + + if (PluginLoaded != null) { PluginLoaded.Invoke(new() { Exception = null, IsLoaded = true, PluginName = type.FullName, TypeName = nameof(T), Plugin = plugin }); } + } + catch (Exception ex) + { + if (PluginLoaded != null) { PluginLoaded.Invoke(new() { Exception = ex, IsLoaded = false, PluginName = type.FullName, TypeName = nameof(T) }); } + } + } + } + catch (Exception ex) { Functions.WriteErrFile(ex.ToString()); } + + + return list; + } + } +} diff --git a/PluginManager/Loaders/PluginLoader.cs b/PluginManager/Loaders/PluginLoader.cs index 520112d..813ba1b 100644 --- a/PluginManager/Loaders/PluginLoader.cs +++ b/PluginManager/Loaders/PluginLoader.cs @@ -1,35 +1,32 @@ using Discord.WebSocket; - using PluginManager.Interfaces; using PluginManager.Others; - using System; using System.Collections.Generic; + namespace PluginManager.Loaders { public class PluginLoader { - private DiscordSocketClient client; + private readonly DiscordSocketClient _client; /// /// The Plugin Loader constructor /// /// The discord bot client where the plugins will pe attached to - public PluginLoader(DiscordSocketClient discordSocketClient) - { - this.client = discordSocketClient; - } + public PluginLoader(DiscordSocketClient discordSocketClient) { this._client = discordSocketClient; } private const string pluginCMDFolder = @"./Data/Plugins/Commands/"; private const string pluginEVEFolder = @"./Data/Plugins/Events/"; - private const string pluginCMDExtension = ".dll"; - private const string pluginEVEExtension = ".dll"; + private const string pluginCMDExtension = "dll"; + private const string pluginEVEExtension = "dll"; + /// /// A list of commands /// - public static List? Plugins { get; set; } + public static List? Commands { get; set; } /// /// A list of commands @@ -38,6 +35,7 @@ namespace PluginManager.Loaders public delegate void CMDLoaded(string name, string typeName, bool success, Exception? e = null); + public delegate void EVELoaded(string name, string typeName, bool success, Exception? e = null); /// @@ -55,11 +53,10 @@ namespace PluginManager.Loaders /// public void LoadPlugins() { + Commands = new List(); + Events = new List(); - Plugins = new List(); - Events = new List(); - - Functions.WriteLogFile("Starting plugin loader ... Client: " + client.CurrentUser.Username); + Functions.WriteLogFile("Starting plugin loader ... Client: " + _client.CurrentUser.Username); if (LanguageSystem.Language.ActiveLanguage != null) Console_Utilities.WriteColorText( LanguageSystem.Language.ActiveLanguage.FormatText( @@ -67,45 +64,40 @@ namespace PluginManager.Loaders ) ); - //Load commands - CommandsLoader CMDLoader = new CommandsLoader(pluginCMDFolder, pluginCMDExtension); - CMDLoader.OnCommandLoaded += OnCommandLoaded!; - CMDLoader.OnCommandFileLoaded += OnCommandFileLoaded; - Plugins = CMDLoader.LoadCommands(); + Loader commandsLoader = new Loader(pluginCMDFolder, pluginCMDExtension); + Loader eventsLoader = new Loader(pluginEVEFolder, pluginEVEExtension); - //Load Events - EventsLoader EVLoader = new EventsLoader(pluginEVEFolder, pluginEVEExtension); - EVLoader.EventLoad += OnEventLoaded!; - EVLoader.EventFileLoaded += EventFileLoaded; - Events = EVLoader.LoadEvents(); + commandsLoader.FileLoaded += OnCommandFileLoaded; + commandsLoader.PluginLoaded += OnCommandLoaded; + eventsLoader.FileLoaded += EventFileLoaded; + eventsLoader.PluginLoaded += OnEventLoaded; + + Commands = commandsLoader.Load(); + Events = eventsLoader.Load(); } - private void EventFileLoaded(string path) + private void EventFileLoaded(LoaderArgs e) { - if (path != null) - Functions.WriteLogFile($"[EVENT] Event from file [{path}] has been successfully created !"); + if (e.IsLoaded) Functions.WriteLogFile($"[EVENT] Event from file [{e.PluginName}] has been successfully created !"); } - private void OnCommandFileLoaded(string path) + private void OnCommandFileLoaded(LoaderArgs e) { - if (path != null) - Functions.WriteLogFile($"[CMD] Command from file [{path}] has been successfully loaded !"); + if (e.IsLoaded) Functions.WriteLogFile($"[CMD] Command from file [{e.PluginName}] has been successfully loaded !"); } - private void OnEventLoaded(string typename, bool success, DBEvent eve, Exception exception) + private void OnEventLoaded(LoaderArgs e) { - if (eve != null && success) - eve.Start(client); - if (onEVELoad != null) - onEVELoad.Invoke(eve!.name, typename, success, exception); + if (e.IsLoaded) { ((DBEvent)e.Plugin!).Start(_client); } + + if (onEVELoad != null) onEVELoad.Invoke(((DBEvent)e.Plugin!).name, e.TypeName!, e.IsLoaded, e.Exception); } - private void OnCommandLoaded(string name, bool success, DBCommand command, Exception exception) + private void OnCommandLoaded(LoaderArgs e) { - if (onCMDLoad != null) - onCMDLoad.Invoke(command.Command, name, success, exception); + if (onCMDLoad != null) onCMDLoad.Invoke(((DBCommand)e.Plugin!).Command, e.TypeName!, e.IsLoaded, e.Exception); } } } diff --git a/PluginManager/Others/Console Utilities.cs b/PluginManager/Others/Console Utilities.cs index 1cdf29a..cf710d8 100644 --- a/PluginManager/Others/Console Utilities.cs +++ b/PluginManager/Others/Console Utilities.cs @@ -1,9 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; namespace PluginManager.Others { @@ -14,17 +10,20 @@ namespace PluginManager.Others /// public class ProgressBar { - public int Progress { get; set; } - public int Max { get; set; } - public string Message { get; set; } + public int Max { get; set; } + public string Message { get; set; } + public ConsoleColor Color { get; init; } + public ProgressBar(int max, string message) { - Max = max; + Max = max; Message = message; + var consoleColors = Enum.GetValues(typeof(ConsoleColor)); + while ((Color = (ConsoleColor)consoleColors.GetValue(new Random().Next(consoleColors.Length))!) == ConsoleColor.White && Color != ConsoleColor.Black) ; } - public async void Update(int progress, double speed = -1, string? unit = null) + public void Update(int progress, double speed = -1, string? unit = null) { //progress bar @@ -39,8 +38,8 @@ namespace PluginManager.Others for (int i = 0; i < onechunk * progress; i++) { - Console.BackgroundColor = ConsoleColor.Green; - Console.CursorLeft = position++; + Console.BackgroundColor = this.Color; + Console.CursorLeft = position++; Console.Write(" "); } @@ -130,11 +129,12 @@ namespace PluginManager.Others ConsoleColor fg = Console.ForegroundColor; Dictionary colors = new Dictionary() { - {"&g", ConsoleColor.Green }, - {"&b", ConsoleColor.Blue }, - {"&r", ConsoleColor.Red }, - {"&m", ConsoleColor.Magenta }, - {"&c", fg } + { "&g", ConsoleColor.Green }, + { "&b", ConsoleColor.Blue }, + { "&r", ConsoleColor.Red }, + { "&m", ConsoleColor.Magenta }, + { "&y", ConsoleColor.Yellow }, + { "&c", fg } }; foreach (string word in words) { @@ -145,7 +145,9 @@ namespace PluginManager.Others Console.ForegroundColor = colors[prefix]; } - string m = word.Replace("&g", "").Replace("&b", "").Replace("&r", "").Replace("&c", "").Replace("&m", ""); + string m = word; + foreach (var key in colors.Keys) { m = m.Replace(key, ""); } + Console.Write(m + " "); } if (appendNewLine) diff --git a/PluginManager/Others/Functions.cs b/PluginManager/Others/Functions.cs index 9e8091b..a87d603 100644 --- a/PluginManager/Others/Functions.cs +++ b/PluginManager/Others/Functions.cs @@ -259,16 +259,13 @@ namespace PluginManager.Others foreach (ZipArchiveEntry entry in archive.Entries) { if (entry.FullName.EndsWith("/")) - { - currentZIPFile++; Directory.CreateDirectory(Path.Combine(folder, entry.FullName)); - } - else - { - entry.ExtractToFile(Path.Combine(folder, entry.FullName), true); - currentZIPFile++; - } + else + try { entry.ExtractToFile(Path.Combine(folder, entry.FullName), true); } + catch { } + + currentZIPFile++; await Task.Delay(10); progress.Report((float)currentZIPFile / totalZIPFiles * 100); } diff --git a/PluginManager/PluginManager.csproj b/PluginManager/PluginManager.csproj index 7d2d32a..7eafd1b 100644 --- a/PluginManager/PluginManager.csproj +++ b/PluginManager/PluginManager.csproj @@ -19,10 +19,4 @@ - - - MSBuild:Compile - - - From ab6f14e74c990e7eb4666baba323860d7688f2a3 Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Fri, 3 Jun 2022 22:28:22 +0300 Subject: [PATCH 04/20] --- .../.idea.DiscordBotWithAPI/.idea/.gitignore | 13 --- .../.idea/avalonia.xml | 13 --- .../.idea/encodings.xml | 4 - .../.idea/indexLayout.xml | 8 -- .idea/.idea.DiscordBotWithAPI/.idea/vcs.xml | 6 -- BUILDS/net6.0/EVE_LevelingSystem.dll | Bin 11776 -> 11776 bytes BUILDS/net6.0/PluginManager.dll | Bin 62976 -> 61952 bytes DiscordBot/App.config | 11 +- DiscordBot/Discord/Commands/Help.cs | 9 +- DiscordBot/Discord/Core/CommandHandler.cs | 2 +- DiscordBot/Program.cs | 69 +++++++----- DiscordBotGUI/App.axaml.cs | 10 +- DiscordBotGUI/AppUpdater.axaml.cs | 56 +++++----- DiscordBotWithAPI.sln | 7 ++ PluginManager/Loaders/CommandsLoader.cs | 99 +++++++++++++++++ PluginManager/Loaders/EventsLoader.cs | 100 ++++++++++++++++++ PluginManager/Loaders/Loader.cs | 94 ---------------- PluginManager/Loaders/PluginLoader.cs | 68 ++++++------ PluginManager/Others/Console Utilities.cs | 36 +++---- PluginManager/Others/Functions.cs | 11 +- PluginManager/PluginManager.csproj | 6 ++ 21 files changed, 358 insertions(+), 264 deletions(-) delete mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/.gitignore delete mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml delete mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/encodings.xml delete mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml delete mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/vcs.xml create mode 100644 PluginManager/Loaders/CommandsLoader.cs create mode 100644 PluginManager/Loaders/EventsLoader.cs delete mode 100644 PluginManager/Loaders/Loader.cs diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/.gitignore b/.idea/.idea.DiscordBotWithAPI/.idea/.gitignore deleted file mode 100644 index 1e2399a..0000000 --- a/.idea/.idea.DiscordBotWithAPI/.idea/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Rider ignored files -/modules.xml -/contentModel.xml -/.idea.DiscordBotWithAPI.iml -/projectSettingsUpdater.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml b/.idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml deleted file mode 100644 index c0fdb9d..0000000 --- a/.idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/encodings.xml b/.idea/.idea.DiscordBotWithAPI/.idea/encodings.xml deleted file mode 100644 index df87cf9..0000000 --- a/.idea/.idea.DiscordBotWithAPI/.idea/encodings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml b/.idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml deleted file mode 100644 index 7b08163..0000000 --- a/.idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/vcs.xml b/.idea/.idea.DiscordBotWithAPI/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/.idea.DiscordBotWithAPI/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/BUILDS/net6.0/EVE_LevelingSystem.dll b/BUILDS/net6.0/EVE_LevelingSystem.dll index 58c77e5e96d071e9830f8b1b8a63fdbfe13f1d1d..e44346107e2f2c1203421bedc78994df8fa0da88 100644 GIT binary patch delta 250 zcmZpOX^5H7!IGcua(QBp45QJ+mEnvJCNnasvmS9~V33)t$fPqll2M(}Vsay6J)_8E zMkZm_2~rFUjFS!3%r^%xX|r)FGcputh%zv66?so?--lGI^hU{DSXW)Ki#U=UycvfV>HU4XR0=84=5A{v^>42cXm4EYSj3txn^7QZg<5Fst2@rq&owVEWn37w*+sF3g_i?l k9uz1|zN;$DD6;vdDl5}wK8;_@OeQ9q1$EvtPBdT#05}Rjwg3PC delta 238 zcmZpOX^5H7!J@HqdgsI*8AhdvE5jKtOlD+MXWin=z#ubOkx6HAB%?Z`#^grEdPbJX zj7-9;4N?pYjFTPJ%r^%xX|r()Gcputh%zv66Ov2@C84pHo3;r#)0CkzNpeyb|Y$g-JJ cjg@J#1EauZK8;_@Oe!Xu1$EvtPBdT#00Y`Qx&QzG diff --git a/BUILDS/net6.0/PluginManager.dll b/BUILDS/net6.0/PluginManager.dll index 484c585cfad2bab1d5678c0b02ae8e2c84a55d37..856115d475eef34cc74c0721d43092668387d9b8 100644 GIT binary patch literal 61952 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 W_(XQF^ve(aGW6yD`|$Hp;J*P$&{(Jd literal 62976 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 eM>lRG8vi8xG`$!M}B+TXi=kUW);J*ONy-Csl diff --git a/DiscordBot/App.config b/DiscordBot/App.config index 828bd34..2a5ff10 100644 --- a/DiscordBot/App.config +++ b/DiscordBot/App.config @@ -1,7 +1,4 @@ - - - - - - - + + + + \ No newline at end of file diff --git a/DiscordBot/Discord/Commands/Help.cs b/DiscordBot/Discord/Commands/Help.cs index 26a1c51..67840a5 100644 --- a/DiscordBot/Discord/Commands/Help.cs +++ b/DiscordBot/Discord/Commands/Help.cs @@ -75,11 +75,12 @@ namespace DiscordBot.Discord.Commands string normalCommands = ""; string DMCommands = ""; - foreach (var cmd in PluginLoader.Commands!) + foreach (var cmd in PluginLoader.Plugins!) { - if (cmd.canUseDM) DMCommands += cmd.Command + " "; + if (cmd.canUseDM) + DMCommands += cmd.Command + " "; if (cmd.requireAdmin) - adminCommands += cmd.Command + " "; + adminCommands += cmd.Command + " "; else if (cmd.canUseServer) normalCommands += cmd.Command + " "; } @@ -93,7 +94,7 @@ namespace DiscordBot.Discord.Commands private EmbedBuilder GenerateHelpCommand(string command) { EmbedBuilder embedBuilder = new EmbedBuilder(); - DBCommand cmd = PluginLoader.Commands.Find(p => p.Command == command); + DBCommand cmd = PluginLoader.Plugins.Find(p => p.Command == command); if (cmd == null) return null; diff --git a/DiscordBot/Discord/Core/CommandHandler.cs b/DiscordBot/Discord/Core/CommandHandler.cs index b877f79..5ed266b 100644 --- a/DiscordBot/Discord/Core/CommandHandler.cs +++ b/DiscordBot/Discord/Core/CommandHandler.cs @@ -80,7 +80,7 @@ namespace PluginManager.Core services: null ); - DBCommand plugin = PluginLoader.Commands!.Where(p => p.Command == (message.Content.Split(' ')[0]).Substring(botPrefix.Length)).FirstOrDefault(); + DBCommand plugin = PluginLoader.Plugins!.Where(p => p.Command == (message.Content.Split(' ')[0]).Substring(botPrefix.Length)).FirstOrDefault(); if (plugin != null) diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index 903d078..9c1a719 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -1,14 +1,16 @@ using Discord; + using System; using System.IO; using System.Threading.Tasks; + using PluginManager.Core; using PluginManager.Others; using PluginManager.LanguageSystem; using PluginManager.Online; + using System.Collections.Generic; using System.Linq; -using System.Threading; using PluginManager.Items; namespace DiscordBot @@ -18,23 +20,21 @@ namespace DiscordBot private static bool loadPluginsOnStartup = false; private static bool listPluginsAtStartup = false; private static bool listLanguagAtStartup = false; - //private static bool ShowStartupMessage = true; + + private static bool ShowStartupMessage = true; /// /// The main entry point for the application. /// [STAThread] [Obsolete] + public static void Main(string[] args) { Directory.CreateDirectory("./Data/Resources"); Directory.CreateDirectory("./Data/Languages"); Directory.CreateDirectory("./Data/Plugins/Commands"); Directory.CreateDirectory("./Data/Plugins/Events"); - Directory.CreateDirectory("./Data/runtime"); - - AppDomain.CurrentDomain.AppendPrivatePath("./Data/runtime"); - if (!File.Exists("./Data/Resources/DiscordBotCore.data") || (Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN", '=').Length != 59 && Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN", '=').Length != 70)) { File.WriteAllText("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN=token\nBOT_PREFIX=!\n"); @@ -45,13 +45,13 @@ namespace DiscordBot string botToken = Console.ReadLine(); if (botToken.Length == 59 || botToken.Length == 70) { - string prefix = Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_PREFIX", '='); - if (prefix == string.Empty || prefix == null) prefix = "!"; + string prefix = Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_PREFIX", '='); + if (prefix == string.Empty || prefix == null) + prefix = "!"; File.WriteAllText("./Data/Resources/DiscordBotCore.data", $"BOT_TOKEN={botToken}\nBOT_PREFIX={prefix}\n"); break; } - else - Console.WriteLine("Invalid Token !"); + else Console.WriteLine("Invalid Token !"); } } @@ -72,14 +72,17 @@ namespace DiscordBot /// The main loop for the discord bot /// /// The discord booter used to start the application - private static Task NoGUI(Boot discordbooter) + private static async Task NoGUI(Boot discordbooter) { Language.LoadLanguage(); ConsoleCommandsHandler consoleCommandsHandler = new ConsoleCommandsHandler(discordbooter.client); - if (loadPluginsOnStartup) consoleCommandsHandler.HandleCommand("lp"); - if (listPluginsAtStartup) consoleCommandsHandler.HandleCommand("listplugs"); - if (listLanguagAtStartup) consoleCommandsHandler.HandleCommand("listlang"); + if (loadPluginsOnStartup) + consoleCommandsHandler.HandleCommand("lp"); + if (listPluginsAtStartup) + consoleCommandsHandler.HandleCommand("listplugs"); + if (listLanguagAtStartup) + consoleCommandsHandler.HandleCommand("listlang"); while (true) { @@ -95,14 +98,23 @@ namespace DiscordBot /// Returns the boot loader for the Discord Bot private static async Task StartNoGUI() { + Console.Clear(); Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine("Discord BOT for Cross Platform"); Console.WriteLine("Created by: Wizzy\nDiscord: Wizzy#9181"); + if (ShowStartupMessage) + try + { + Console.WriteLine("Connecting to server ..."); + List text = await ServerCom.ReadTextFromFile("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/StartupMessage"); + foreach (var t in text) Console_Utilities.WriteColorText(t); + } + catch { Console.WriteLine("Failed to connect to server."); } Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("============================ Discord BOT - Cross Platform ============================"); - string token = Functions.readCodeFromFile(Functions.dataFolder + "DiscordBotCore.data", "BOT_TOKEN", '='); + string token = Functions.readCodeFromFile(Functions.dataFolder + "DiscordBotCore.data", "BOT_TOKEN", '='); string prefix = Functions.readCodeFromFile(Functions.dataFolder + "DiscordBotCore.data", "BOT_PREFIX", '='); var discordbooter = new Boot(token, prefix); @@ -116,8 +128,8 @@ namespace DiscordBot /// Directory path private static Task ClearFolder(string d) { - string[] files = Directory.GetFiles(d); - int fileNumb = files.Length; + string[] files = Directory.GetFiles(d); + int fileNumb = files.Length; for (var i = 0; i < fileNumb; i++) { File.Delete(files[i]); @@ -133,6 +145,7 @@ namespace DiscordBot /// The arguments private static async Task HandleInput(string[] args) { + if (args.Length == 0) { if (File.Exists("./ref/startupArguments.txt")) @@ -151,12 +164,8 @@ namespace DiscordBot if (len == 1 && args[0] == "--logout") { - File.Delete(Functions.dataFolder + "DiscordBotCore.dat"); - await Task.Run(async () => - { - await Task.Delay(1000); - Environment.Exit(0x08); - }); + File.Delete(Functions.dataFolder + "Login.dat"); + Console.WriteLine("Logged out. Please restart the application !"); return; } @@ -170,14 +179,20 @@ namespace DiscordBot if (len > 0 && (args.Contains("--cmd") || args.Contains("--args") || args.Contains("--nomessage"))) { - if (args.Contains("lp") || args.Contains("loadplugins")) loadPluginsOnStartup = true; - if (args.Contains("listplugs")) listPluginsAtStartup = true; - if (args.Contains("listlang")) listLanguagAtStartup = true; - //if (args.Contains("--nomessage")) ShowStartupMessage = false; + if (args.Contains("lp") || args.Contains("loadplugins")) + loadPluginsOnStartup = true; + if (args.Contains("listplugs")) + listPluginsAtStartup = true; + if (args.Contains("listlang")) + listLanguagAtStartup = true; + if (args.Contains("--nomessage")) + ShowStartupMessage = false; len = 0; } + + if (len == 0 || args[0] != "--exec" && args[0] != "--execute") { Boot b = await StartNoGUI(); diff --git a/DiscordBotGUI/App.axaml.cs b/DiscordBotGUI/App.axaml.cs index 456aca5..a3b2c89 100644 --- a/DiscordBotGUI/App.axaml.cs +++ b/DiscordBotGUI/App.axaml.cs @@ -1,8 +1,6 @@ -using System.IO; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; -using PluginManager.Others; namespace DiscordBotGUI { @@ -15,7 +13,13 @@ namespace DiscordBotGUI public override void OnFrameworkInitializationCompleted() { - if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { desktop.MainWindow = new AppUpdater() { Width = 300, Height = 50, WindowStartupLocation = Avalonia.Controls.WindowStartupLocation.CenterScreen }; } + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + + + desktop.MainWindow = new AppUpdater() { Width = 300, Height = 50, WindowStartupLocation = Avalonia.Controls.WindowStartupLocation.CenterScreen }; + + } base.OnFrameworkInitializationCompleted(); } diff --git a/DiscordBotGUI/AppUpdater.axaml.cs b/DiscordBotGUI/AppUpdater.axaml.cs index 8c4dccc..ecc5405 100644 --- a/DiscordBotGUI/AppUpdater.axaml.cs +++ b/DiscordBotGUI/AppUpdater.axaml.cs @@ -21,48 +21,42 @@ namespace DiscordBotGUI InitializeComponent(); if (!File.Exists("./Version.txt")) { + textBox1.Text = "Checking ..."; File.WriteAllText("./Version.txt", "DiscordBotVersion=0"); - DownloadDiscordBotClientNoGUIAsDLL(); + //DownloadDiscordBotClientNoGUIAsDLL(); } - if (!File.Exists("./DiscordBot.exe")) DownloadDiscordBotClientNoGUIAsDLL(); Updates(); } - private async void DownloadDiscordBotClientNoGUIAsDLL() - { - //await Task.Delay(5000); - string url_bot_dll = "https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Updates/DiscordBot.zip"; - int actiontype = 0; //0 - downolad, 1- extract - IProgress progress = new Progress((percent) => - { - if (actiontype == 0) - textBox1.Text = "Downloading DiscordBot ... " + MathF.Round(percent, 2) + "%"; - else - textBox1.Text = "Extracting package ..." + MathF.Round(percent, 2) + "%"; - this.progressBar1.Value = percent; - }); + /* private async void DownloadDiscordBotClientNoGUIAsDLL() + { - this.progressBar1.IsIndeterminate = false; - try - { - await ServerCom.DownloadFileAsync(url_bot_dll, "./DiscordBot.zip", progress); + //await Task.Delay(5000); + string url_bot_dll = "https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Updates/DiscordBot.dll"; + IProgress progress = new Progress((percent) => + { + textBox1.Text = "Downloading DiscordBot.dll ... " + (percent * 100).ToString() + "%"; + this.progressBar1.Value = percent * 100; + }); - actiontype++; + this.progressBar1.IsIndeterminate = false; + try + { + await ServerCom.DownloadFileAsync(url_bot_dll, "./DiscordBot.dll", progress); + } + catch + { + textBox1.Text = "Error downloading DiscordBot.dll. Server is not responding."; - await Functions.ExtractArchive("./DiscordBot.zip", "./", progress); - } - catch - { - textBox1.Text = "Error downloading DiscordBot.dll. Server is not responding."; + await Task.Delay(1000); + return; + } - await Task.Delay(1000); - - new MainWindow() { Height = 425, Width = 500 }.Show(); - Close(); - } - } + //new MainWindow() { Height = 425, Width = 500 }.Show(); + //Close(); + }*/ private async void Updates() { diff --git a/DiscordBotWithAPI.sln b/DiscordBotWithAPI.sln index 7bf0ffe..3f9ab41 100644 --- a/DiscordBotWithAPI.sln +++ b/DiscordBotWithAPI.sln @@ -23,6 +23,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CMD_Utils", "CMD_Utils\CMD_ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MusicCommands", "MusicCommands\MusicCommands.csproj", "{B1B4976E-5112-4217-B57B-3A03C5207B6E}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Games", "FreeGames\Games.csproj", "{7CC0819E-2BC0-44F0-8D92-EC442F36E1BB}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordBotGUI", "DiscordBotGUI\DiscordBotGUI.csproj", "{7B5899F0-0218-4537-8C74-6210ED2D3690}" EndProject Global @@ -59,6 +61,10 @@ Global {B1B4976E-5112-4217-B57B-3A03C5207B6E}.Debug|Any CPU.Build.0 = Debug|Any CPU {B1B4976E-5112-4217-B57B-3A03C5207B6E}.Release|Any CPU.ActiveCfg = Release|Any CPU {B1B4976E-5112-4217-B57B-3A03C5207B6E}.Release|Any CPU.Build.0 = Release|Any CPU + {7CC0819E-2BC0-44F0-8D92-EC442F36E1BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7CC0819E-2BC0-44F0-8D92-EC442F36E1BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7CC0819E-2BC0-44F0-8D92-EC442F36E1BB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7CC0819E-2BC0-44F0-8D92-EC442F36E1BB}.Release|Any CPU.Build.0 = Release|Any CPU {7B5899F0-0218-4537-8C74-6210ED2D3690}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7B5899F0-0218-4537-8C74-6210ED2D3690}.Debug|Any CPU.Build.0 = Debug|Any CPU {7B5899F0-0218-4537-8C74-6210ED2D3690}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -75,6 +81,7 @@ Global {CE9DBF06-38A0-4192-8B3E-4009210D040D} = {A290C028-77C4-4D1D-AB43-DDFE6ABD9012} {E26C87A4-3DD6-4B58-B14B-C8E086B852F9} = {449FA364-0B72-43FF-B3A3-806E2916200E} {B1B4976E-5112-4217-B57B-3A03C5207B6E} = {449FA364-0B72-43FF-B3A3-806E2916200E} + {7CC0819E-2BC0-44F0-8D92-EC442F36E1BB} = {449FA364-0B72-43FF-B3A3-806E2916200E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3FB3C5DE-ED21-4D2E-ABDD-3A00EE4A2FFF} diff --git a/PluginManager/Loaders/CommandsLoader.cs b/PluginManager/Loaders/CommandsLoader.cs new file mode 100644 index 0000000..919fa6b --- /dev/null +++ b/PluginManager/Loaders/CommandsLoader.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; + +using PluginManager.Interfaces; + +namespace PluginManager.Loaders +{ + internal class CommandsLoader + { + private readonly string CMDPath; + private readonly string CMDExtension; + + + internal delegate void onCommandLoaded(string name, bool success, DBCommand? command = null, Exception? exception = null); + internal delegate void onCommandFileLoaded(string path); + + /// + /// Event fired when a command is loaded + /// + internal onCommandLoaded? OnCommandLoaded; + + /// + /// Event fired when the file is loaded + /// + internal onCommandFileLoaded? OnCommandFileLoaded; + + /// + /// Command Loader contructor + /// + /// The path to the commands + /// The extension to search for in the + internal CommandsLoader(string CommandPath, string CommandExtension) + { + CMDPath = CommandPath; + CMDExtension = CommandExtension; + } + + /// + /// The method that loads all commands + /// + /// + internal List? LoadCommands() + { + if (!Directory.Exists(CMDPath)) + { + Directory.CreateDirectory(CMDPath); + return null; + } + string[] files = Directory.GetFiles(CMDPath, $"*{CMDExtension}", SearchOption.AllDirectories); + + foreach (var file in files) + { + Assembly.LoadFile(Path.GetFullPath(file)); + if (OnCommandFileLoaded != null) + OnCommandFileLoaded.Invoke(file); + } + + List plugins = new List(); + + try + { + Type interfaceType = typeof(DBCommand); + Type[] types = AppDomain.CurrentDomain.GetAssemblies() + .SelectMany(a => a.GetTypes()) + .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) + .ToArray(); + foreach (Type type in types) + { + try + { + DBCommand plugin = (DBCommand)Activator.CreateInstance(type)!; + plugins.Add(plugin); + + if (OnCommandLoaded != null) + OnCommandLoaded.Invoke(type.FullName!, true, plugin); + } + catch (Exception e) + { + if (OnCommandLoaded != null) + OnCommandLoaded.Invoke(type.FullName!, false, null, e); + } + + } + + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + return null; + } + + return plugins; + + } + } +} diff --git a/PluginManager/Loaders/EventsLoader.cs b/PluginManager/Loaders/EventsLoader.cs new file mode 100644 index 0000000..28c1766 --- /dev/null +++ b/PluginManager/Loaders/EventsLoader.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; + +using PluginManager.Interfaces; + +namespace PluginManager.Loaders +{ + internal class EventsLoader + { + + private readonly string EVPath; + private readonly string EVExtension; + + internal delegate void onEventLoad(string name, bool success, DBEvent? ev = null, Exception? e = null); + internal delegate void onEventFileLoaded(string path); + + /// + /// An event that is fired whenever a event is loaded in memory + /// + internal onEventLoad? EventLoad; + + /// + /// An event that is fired whenever a event file is loaded + /// + internal onEventFileLoaded? EventFileLoaded; + + /// + /// The Event Loader constructor + /// + /// The path to all events + /// The extension for events + internal EventsLoader(string path, string ext) + { + EVPath = path; + EVExtension = ext; + } + + /// + /// The method that loads all events + /// + /// + internal List? LoadEvents() + { + + if (!Directory.Exists(EVPath)) + { + Directory.CreateDirectory(EVPath); + return null; + } + + string[] files = Directory.GetFiles(EVPath, $"*{EVExtension}", SearchOption.AllDirectories); + + foreach (var file in files) + { + Assembly.LoadFile(Path.GetFullPath(file)); + if (EventFileLoaded != null) + EventFileLoaded.Invoke(file); + } + + List events = new List(); + + try + { + Type interfaceType = typeof(DBEvent); + Type[] types = AppDomain.CurrentDomain.GetAssemblies() + .SelectMany(a => a.GetTypes()) + .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) + .ToArray(); + foreach (Type type in types) + { + try + { + DBEvent ev = (DBEvent)Activator.CreateInstance(type)!; + events.Add(ev); + + if (EventLoad != null) + EventLoad.Invoke(type.FullName!, true, ev, null); + } + catch (Exception e) + { + if (EventLoad != null) + EventLoad.Invoke(type.FullName!, false, null, e); + } + + } + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + return null; + } + + return events; + + } + } +} \ No newline at end of file diff --git a/PluginManager/Loaders/Loader.cs b/PluginManager/Loaders/Loader.cs deleted file mode 100644 index 955bc9f..0000000 --- a/PluginManager/Loaders/Loader.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.CompilerServices; -using PluginManager.Interfaces; -using PluginManager.Others; - -namespace PluginManager.Loaders -{ - 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 delegate void FileLoadedEventHandler(LoaderArgs args); - - internal event FileLoadedEventHandler? FileLoaded; - - internal delegate void PluginLoadedEventHandler(LoaderArgs args); - - internal event PluginLoadedEventHandler? PluginLoaded; - - - private string path { get; } - private string extension { get; } - - - internal Loader(string path, string extension) - { - this.path = path; - this.extension = extension; - } - - internal List? Load() - { - List list = new List(); - if (!Directory.Exists(path)) - { - Directory.CreateDirectory(path); - return null; - } - - string[] files = Directory.GetFiles(path, $"*.{extension}", SearchOption.AllDirectories); - foreach (var file in files) - { - Assembly.LoadFrom(file); - if (FileLoaded != null) - { - LoaderArgs args = new LoaderArgs() { Exception = null, TypeName = nameof(T), IsLoaded = false, PluginName = file, Plugin = null }; - FileLoaded.Invoke(args); - } - } - - try - { - Type interfaceType = typeof(T); - Type[] types = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(a => a.GetTypes()) - .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) - .ToArray(); - - - list.Clear(); - foreach (Type type in types) - { - try - { - T plugin = (T)(Activator.CreateInstance(type)!); - list.Add(plugin); - - - if (PluginLoaded != null) { PluginLoaded.Invoke(new() { Exception = null, IsLoaded = true, PluginName = type.FullName, TypeName = nameof(T), Plugin = plugin }); } - } - catch (Exception ex) - { - if (PluginLoaded != null) { PluginLoaded.Invoke(new() { Exception = ex, IsLoaded = false, PluginName = type.FullName, TypeName = nameof(T) }); } - } - } - } - catch (Exception ex) { Functions.WriteErrFile(ex.ToString()); } - - - return list; - } - } -} diff --git a/PluginManager/Loaders/PluginLoader.cs b/PluginManager/Loaders/PluginLoader.cs index 813ba1b..520112d 100644 --- a/PluginManager/Loaders/PluginLoader.cs +++ b/PluginManager/Loaders/PluginLoader.cs @@ -1,32 +1,35 @@ using Discord.WebSocket; + using PluginManager.Interfaces; using PluginManager.Others; + using System; using System.Collections.Generic; - namespace PluginManager.Loaders { public class PluginLoader { - private readonly DiscordSocketClient _client; + private DiscordSocketClient client; /// /// The Plugin Loader constructor /// /// The discord bot client where the plugins will pe attached to - public PluginLoader(DiscordSocketClient discordSocketClient) { this._client = discordSocketClient; } + public PluginLoader(DiscordSocketClient discordSocketClient) + { + this.client = discordSocketClient; + } private const string pluginCMDFolder = @"./Data/Plugins/Commands/"; private const string pluginEVEFolder = @"./Data/Plugins/Events/"; - private const string pluginCMDExtension = "dll"; - private const string pluginEVEExtension = "dll"; - + private const string pluginCMDExtension = ".dll"; + private const string pluginEVEExtension = ".dll"; /// /// A list of commands /// - public static List? Commands { get; set; } + public static List? Plugins { get; set; } /// /// A list of commands @@ -35,7 +38,6 @@ namespace PluginManager.Loaders public delegate void CMDLoaded(string name, string typeName, bool success, Exception? e = null); - public delegate void EVELoaded(string name, string typeName, bool success, Exception? e = null); /// @@ -53,10 +55,11 @@ namespace PluginManager.Loaders /// public void LoadPlugins() { - Commands = new List(); - Events = new List(); - Functions.WriteLogFile("Starting plugin loader ... Client: " + _client.CurrentUser.Username); + Plugins = new List(); + Events = new List(); + + Functions.WriteLogFile("Starting plugin loader ... Client: " + client.CurrentUser.Username); if (LanguageSystem.Language.ActiveLanguage != null) Console_Utilities.WriteColorText( LanguageSystem.Language.ActiveLanguage.FormatText( @@ -64,40 +67,45 @@ namespace PluginManager.Loaders ) ); + //Load commands + CommandsLoader CMDLoader = new CommandsLoader(pluginCMDFolder, pluginCMDExtension); + CMDLoader.OnCommandLoaded += OnCommandLoaded!; + CMDLoader.OnCommandFileLoaded += OnCommandFileLoaded; + Plugins = CMDLoader.LoadCommands(); - Loader commandsLoader = new Loader(pluginCMDFolder, pluginCMDExtension); - Loader eventsLoader = new Loader(pluginEVEFolder, pluginEVEExtension); - commandsLoader.FileLoaded += OnCommandFileLoaded; - commandsLoader.PluginLoaded += OnCommandLoaded; + //Load Events + EventsLoader EVLoader = new EventsLoader(pluginEVEFolder, pluginEVEExtension); + EVLoader.EventLoad += OnEventLoaded!; + EVLoader.EventFileLoaded += EventFileLoaded; + Events = EVLoader.LoadEvents(); - eventsLoader.FileLoaded += EventFileLoaded; - eventsLoader.PluginLoaded += OnEventLoaded; - - Commands = commandsLoader.Load(); - Events = eventsLoader.Load(); } - private void EventFileLoaded(LoaderArgs e) + private void EventFileLoaded(string path) { - if (e.IsLoaded) Functions.WriteLogFile($"[EVENT] Event from file [{e.PluginName}] has been successfully created !"); + if (path != null) + Functions.WriteLogFile($"[EVENT] Event from file [{path}] has been successfully created !"); } - private void OnCommandFileLoaded(LoaderArgs e) + private void OnCommandFileLoaded(string path) { - if (e.IsLoaded) Functions.WriteLogFile($"[CMD] Command from file [{e.PluginName}] has been successfully loaded !"); + if (path != null) + Functions.WriteLogFile($"[CMD] Command from file [{path}] has been successfully loaded !"); } - private void OnEventLoaded(LoaderArgs e) + private void OnEventLoaded(string typename, bool success, DBEvent eve, Exception exception) { - if (e.IsLoaded) { ((DBEvent)e.Plugin!).Start(_client); } - - if (onEVELoad != null) onEVELoad.Invoke(((DBEvent)e.Plugin!).name, e.TypeName!, e.IsLoaded, e.Exception); + if (eve != null && success) + eve.Start(client); + if (onEVELoad != null) + onEVELoad.Invoke(eve!.name, typename, success, exception); } - private void OnCommandLoaded(LoaderArgs e) + private void OnCommandLoaded(string name, bool success, DBCommand command, Exception exception) { - if (onCMDLoad != null) onCMDLoad.Invoke(((DBCommand)e.Plugin!).Command, e.TypeName!, e.IsLoaded, e.Exception); + if (onCMDLoad != null) + onCMDLoad.Invoke(command.Command, name, success, exception); } } } diff --git a/PluginManager/Others/Console Utilities.cs b/PluginManager/Others/Console Utilities.cs index cf710d8..1cdf29a 100644 --- a/PluginManager/Others/Console Utilities.cs +++ b/PluginManager/Others/Console Utilities.cs @@ -1,5 +1,9 @@ using System; using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; namespace PluginManager.Others { @@ -10,20 +14,17 @@ namespace PluginManager.Others /// public class ProgressBar { - public int Max { get; set; } - public string Message { get; set; } - public ConsoleColor Color { get; init; } - + public int Progress { get; set; } + public int Max { get; set; } + public string Message { get; set; } public ProgressBar(int max, string message) { - Max = max; + Max = max; Message = message; - var consoleColors = Enum.GetValues(typeof(ConsoleColor)); - while ((Color = (ConsoleColor)consoleColors.GetValue(new Random().Next(consoleColors.Length))!) == ConsoleColor.White && Color != ConsoleColor.Black) ; } - public void Update(int progress, double speed = -1, string? unit = null) + public async void Update(int progress, double speed = -1, string? unit = null) { //progress bar @@ -38,8 +39,8 @@ namespace PluginManager.Others for (int i = 0; i < onechunk * progress; i++) { - Console.BackgroundColor = this.Color; - Console.CursorLeft = position++; + Console.BackgroundColor = ConsoleColor.Green; + Console.CursorLeft = position++; Console.Write(" "); } @@ -129,12 +130,11 @@ namespace PluginManager.Others ConsoleColor fg = Console.ForegroundColor; Dictionary colors = new Dictionary() { - { "&g", ConsoleColor.Green }, - { "&b", ConsoleColor.Blue }, - { "&r", ConsoleColor.Red }, - { "&m", ConsoleColor.Magenta }, - { "&y", ConsoleColor.Yellow }, - { "&c", fg } + {"&g", ConsoleColor.Green }, + {"&b", ConsoleColor.Blue }, + {"&r", ConsoleColor.Red }, + {"&m", ConsoleColor.Magenta }, + {"&c", fg } }; foreach (string word in words) { @@ -145,9 +145,7 @@ namespace PluginManager.Others Console.ForegroundColor = colors[prefix]; } - string m = word; - foreach (var key in colors.Keys) { m = m.Replace(key, ""); } - + string m = word.Replace("&g", "").Replace("&b", "").Replace("&r", "").Replace("&c", "").Replace("&m", ""); Console.Write(m + " "); } if (appendNewLine) diff --git a/PluginManager/Others/Functions.cs b/PluginManager/Others/Functions.cs index a87d603..9e8091b 100644 --- a/PluginManager/Others/Functions.cs +++ b/PluginManager/Others/Functions.cs @@ -259,13 +259,16 @@ namespace PluginManager.Others foreach (ZipArchiveEntry entry in archive.Entries) { if (entry.FullName.EndsWith("/")) + { + currentZIPFile++; Directory.CreateDirectory(Path.Combine(folder, entry.FullName)); - + } else - try { entry.ExtractToFile(Path.Combine(folder, entry.FullName), true); } - catch { } + { + entry.ExtractToFile(Path.Combine(folder, entry.FullName), true); + currentZIPFile++; + } - currentZIPFile++; await Task.Delay(10); progress.Report((float)currentZIPFile / totalZIPFiles * 100); } diff --git a/PluginManager/PluginManager.csproj b/PluginManager/PluginManager.csproj index 7eafd1b..7d2d32a 100644 --- a/PluginManager/PluginManager.csproj +++ b/PluginManager/PluginManager.csproj @@ -19,4 +19,10 @@ + + + MSBuild:Compile + + + From 0d524cdf65d73ec28663ee205ec35ae344a8a5c0 Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Thu, 2 Jun 2022 13:48:56 +0300 Subject: [PATCH 05/20] patch for UI --- .../.idea.DiscordBotWithAPI/.idea/.gitignore | 13 +++ .../.idea/avalonia.xml | 13 +++ .../.idea/encodings.xml | 4 + .../.idea/indexLayout.xml | 8 ++ .idea/.idea.DiscordBotWithAPI/.idea/vcs.xml | 6 ++ BUILDS/net6.0/EVE_LevelingSystem.dll | Bin 11776 -> 11776 bytes BUILDS/net6.0/PluginManager.dll | Bin 61952 -> 62976 bytes DiscordBot/App.config | 11 +- DiscordBot/Discord/Commands/Help.cs | 9 +- DiscordBot/Discord/Core/CommandHandler.cs | 2 +- DiscordBot/Program.cs | 69 +++++------- DiscordBotGUI/App.axaml.cs | 10 +- DiscordBotGUI/AppUpdater.axaml.cs | 56 +++++----- DiscordBotWithAPI.sln | 7 -- PluginManager/Loaders/CommandsLoader.cs | 99 ----------------- PluginManager/Loaders/EventsLoader.cs | 100 ------------------ PluginManager/Loaders/Loader.cs | 94 ++++++++++++++++ PluginManager/Loaders/PluginLoader.cs | 68 ++++++------ PluginManager/Others/Console Utilities.cs | 36 ++++--- PluginManager/Others/Functions.cs | 13 +-- PluginManager/PluginManager.csproj | 6 -- 21 files changed, 265 insertions(+), 359 deletions(-) create mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/.gitignore create mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml create mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/encodings.xml create mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml create mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/vcs.xml delete mode 100644 PluginManager/Loaders/CommandsLoader.cs delete mode 100644 PluginManager/Loaders/EventsLoader.cs create mode 100644 PluginManager/Loaders/Loader.cs diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/.gitignore b/.idea/.idea.DiscordBotWithAPI/.idea/.gitignore new file mode 100644 index 0000000..1e2399a --- /dev/null +++ b/.idea/.idea.DiscordBotWithAPI/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/modules.xml +/contentModel.xml +/.idea.DiscordBotWithAPI.iml +/projectSettingsUpdater.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml b/.idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml new file mode 100644 index 0000000..c0fdb9d --- /dev/null +++ b/.idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/encodings.xml b/.idea/.idea.DiscordBotWithAPI/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/.idea/.idea.DiscordBotWithAPI/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml b/.idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/vcs.xml b/.idea/.idea.DiscordBotWithAPI/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/.idea.DiscordBotWithAPI/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/BUILDS/net6.0/EVE_LevelingSystem.dll b/BUILDS/net6.0/EVE_LevelingSystem.dll index e44346107e2f2c1203421bedc78994df8fa0da88..58c77e5e96d071e9830f8b1b8a63fdbfe13f1d1d 100644 GIT binary patch delta 238 zcmZpOX^5H7!J@HqdgsI*8AhdvE5jKtOlD+MXWin=z#ubOkx6HAB%?Z`#^grEdPbJX zj7-9;4N?pYjFTPJ%r^%xX|r()Gcputh%zv66Ov2@C84pHo3;r#)0CkzNpeyb|Y$g-JJ cjg@J#1EauZK8;_@Oe!Xu1$EvtPBdT#00Y`Qx&QzG delta 250 zcmZpOX^5H7!IGcua(QBp45QJ+mEnvJCNnasvmS9~V33)t$fPqll2M(}Vsay6J)_8E zMkZm_2~rFUjFS!3%r^%xX|r)FGcputh%zv66?so?--lGI^hU{DSXW)Ki#U=UycvfV>HU4XR0=84=5A{v^>42cXm4EYSj3txn^7QZg<5Fst2@rq&owVEWn37w*+sF3g_i?l k9uz1|zN;$DD6;vdDl5}wK8;_@OeQ9q1$EvtPBdT#05}Rjwg3PC diff --git a/BUILDS/net6.0/PluginManager.dll b/BUILDS/net6.0/PluginManager.dll index 856115d475eef34cc74c0721d43092668387d9b8..484c585cfad2bab1d5678c0b02ae8e2c84a55d37 100644 GIT binary patch literal 62976 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 eM>lRG8vi8xG`$!M}B+TXi=kUW);J*ONy-Csl literal 61952 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 W_(XQF^ve(aGW6yD`|$Hp;J*P$&{(Jd diff --git a/DiscordBot/App.config b/DiscordBot/App.config index 2a5ff10..828bd34 100644 --- a/DiscordBot/App.config +++ b/DiscordBot/App.config @@ -1,4 +1,7 @@ - - - - \ No newline at end of file + + + + + + + diff --git a/DiscordBot/Discord/Commands/Help.cs b/DiscordBot/Discord/Commands/Help.cs index 67840a5..26a1c51 100644 --- a/DiscordBot/Discord/Commands/Help.cs +++ b/DiscordBot/Discord/Commands/Help.cs @@ -75,12 +75,11 @@ namespace DiscordBot.Discord.Commands string normalCommands = ""; string DMCommands = ""; - foreach (var cmd in PluginLoader.Plugins!) + foreach (var cmd in PluginLoader.Commands!) { - if (cmd.canUseDM) - DMCommands += cmd.Command + " "; + if (cmd.canUseDM) DMCommands += cmd.Command + " "; if (cmd.requireAdmin) - adminCommands += cmd.Command + " "; + adminCommands += cmd.Command + " "; else if (cmd.canUseServer) normalCommands += cmd.Command + " "; } @@ -94,7 +93,7 @@ namespace DiscordBot.Discord.Commands private EmbedBuilder GenerateHelpCommand(string command) { EmbedBuilder embedBuilder = new EmbedBuilder(); - DBCommand cmd = PluginLoader.Plugins.Find(p => p.Command == command); + DBCommand cmd = PluginLoader.Commands.Find(p => p.Command == command); if (cmd == null) return null; diff --git a/DiscordBot/Discord/Core/CommandHandler.cs b/DiscordBot/Discord/Core/CommandHandler.cs index 5ed266b..b877f79 100644 --- a/DiscordBot/Discord/Core/CommandHandler.cs +++ b/DiscordBot/Discord/Core/CommandHandler.cs @@ -80,7 +80,7 @@ namespace PluginManager.Core services: null ); - DBCommand plugin = PluginLoader.Plugins!.Where(p => p.Command == (message.Content.Split(' ')[0]).Substring(botPrefix.Length)).FirstOrDefault(); + DBCommand plugin = PluginLoader.Commands!.Where(p => p.Command == (message.Content.Split(' ')[0]).Substring(botPrefix.Length)).FirstOrDefault(); if (plugin != null) diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index 9c1a719..903d078 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -1,16 +1,14 @@ using Discord; - using System; using System.IO; using System.Threading.Tasks; - using PluginManager.Core; using PluginManager.Others; using PluginManager.LanguageSystem; using PluginManager.Online; - using System.Collections.Generic; using System.Linq; +using System.Threading; using PluginManager.Items; namespace DiscordBot @@ -20,21 +18,23 @@ namespace DiscordBot private static bool loadPluginsOnStartup = false; private static bool listPluginsAtStartup = false; private static bool listLanguagAtStartup = false; - - private static bool ShowStartupMessage = true; + //private static bool ShowStartupMessage = true; /// /// The main entry point for the application. /// [STAThread] [Obsolete] - public static void Main(string[] args) { Directory.CreateDirectory("./Data/Resources"); Directory.CreateDirectory("./Data/Languages"); Directory.CreateDirectory("./Data/Plugins/Commands"); Directory.CreateDirectory("./Data/Plugins/Events"); + Directory.CreateDirectory("./Data/runtime"); + + AppDomain.CurrentDomain.AppendPrivatePath("./Data/runtime"); + if (!File.Exists("./Data/Resources/DiscordBotCore.data") || (Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN", '=').Length != 59 && Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN", '=').Length != 70)) { File.WriteAllText("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN=token\nBOT_PREFIX=!\n"); @@ -45,13 +45,13 @@ namespace DiscordBot string botToken = Console.ReadLine(); if (botToken.Length == 59 || botToken.Length == 70) { - string prefix = Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_PREFIX", '='); - if (prefix == string.Empty || prefix == null) - prefix = "!"; + string prefix = Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_PREFIX", '='); + if (prefix == string.Empty || prefix == null) prefix = "!"; File.WriteAllText("./Data/Resources/DiscordBotCore.data", $"BOT_TOKEN={botToken}\nBOT_PREFIX={prefix}\n"); break; } - else Console.WriteLine("Invalid Token !"); + else + Console.WriteLine("Invalid Token !"); } } @@ -72,17 +72,14 @@ namespace DiscordBot /// The main loop for the discord bot /// /// The discord booter used to start the application - private static async Task NoGUI(Boot discordbooter) + private static Task NoGUI(Boot discordbooter) { Language.LoadLanguage(); ConsoleCommandsHandler consoleCommandsHandler = new ConsoleCommandsHandler(discordbooter.client); - if (loadPluginsOnStartup) - consoleCommandsHandler.HandleCommand("lp"); - if (listPluginsAtStartup) - consoleCommandsHandler.HandleCommand("listplugs"); - if (listLanguagAtStartup) - consoleCommandsHandler.HandleCommand("listlang"); + if (loadPluginsOnStartup) consoleCommandsHandler.HandleCommand("lp"); + if (listPluginsAtStartup) consoleCommandsHandler.HandleCommand("listplugs"); + if (listLanguagAtStartup) consoleCommandsHandler.HandleCommand("listlang"); while (true) { @@ -98,23 +95,14 @@ namespace DiscordBot /// Returns the boot loader for the Discord Bot private static async Task StartNoGUI() { - Console.Clear(); Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine("Discord BOT for Cross Platform"); Console.WriteLine("Created by: Wizzy\nDiscord: Wizzy#9181"); - if (ShowStartupMessage) - try - { - Console.WriteLine("Connecting to server ..."); - List text = await ServerCom.ReadTextFromFile("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/StartupMessage"); - foreach (var t in text) Console_Utilities.WriteColorText(t); - } - catch { Console.WriteLine("Failed to connect to server."); } Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("============================ Discord BOT - Cross Platform ============================"); - string token = Functions.readCodeFromFile(Functions.dataFolder + "DiscordBotCore.data", "BOT_TOKEN", '='); + string token = Functions.readCodeFromFile(Functions.dataFolder + "DiscordBotCore.data", "BOT_TOKEN", '='); string prefix = Functions.readCodeFromFile(Functions.dataFolder + "DiscordBotCore.data", "BOT_PREFIX", '='); var discordbooter = new Boot(token, prefix); @@ -128,8 +116,8 @@ namespace DiscordBot /// Directory path private static Task ClearFolder(string d) { - string[] files = Directory.GetFiles(d); - int fileNumb = files.Length; + string[] files = Directory.GetFiles(d); + int fileNumb = files.Length; for (var i = 0; i < fileNumb; i++) { File.Delete(files[i]); @@ -145,7 +133,6 @@ namespace DiscordBot /// The arguments private static async Task HandleInput(string[] args) { - if (args.Length == 0) { if (File.Exists("./ref/startupArguments.txt")) @@ -164,8 +151,12 @@ namespace DiscordBot if (len == 1 && args[0] == "--logout") { - File.Delete(Functions.dataFolder + "Login.dat"); - Console.WriteLine("Logged out. Please restart the application !"); + File.Delete(Functions.dataFolder + "DiscordBotCore.dat"); + await Task.Run(async () => + { + await Task.Delay(1000); + Environment.Exit(0x08); + }); return; } @@ -179,20 +170,14 @@ namespace DiscordBot if (len > 0 && (args.Contains("--cmd") || args.Contains("--args") || args.Contains("--nomessage"))) { - if (args.Contains("lp") || args.Contains("loadplugins")) - loadPluginsOnStartup = true; - if (args.Contains("listplugs")) - listPluginsAtStartup = true; - if (args.Contains("listlang")) - listLanguagAtStartup = true; - if (args.Contains("--nomessage")) - ShowStartupMessage = false; + if (args.Contains("lp") || args.Contains("loadplugins")) loadPluginsOnStartup = true; + if (args.Contains("listplugs")) listPluginsAtStartup = true; + if (args.Contains("listlang")) listLanguagAtStartup = true; + //if (args.Contains("--nomessage")) ShowStartupMessage = false; len = 0; } - - if (len == 0 || args[0] != "--exec" && args[0] != "--execute") { Boot b = await StartNoGUI(); diff --git a/DiscordBotGUI/App.axaml.cs b/DiscordBotGUI/App.axaml.cs index a3b2c89..456aca5 100644 --- a/DiscordBotGUI/App.axaml.cs +++ b/DiscordBotGUI/App.axaml.cs @@ -1,6 +1,8 @@ +using System.IO; using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; +using PluginManager.Others; namespace DiscordBotGUI { @@ -13,13 +15,7 @@ namespace DiscordBotGUI public override void OnFrameworkInitializationCompleted() { - if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) - { - - - desktop.MainWindow = new AppUpdater() { Width = 300, Height = 50, WindowStartupLocation = Avalonia.Controls.WindowStartupLocation.CenterScreen }; - - } + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { desktop.MainWindow = new AppUpdater() { Width = 300, Height = 50, WindowStartupLocation = Avalonia.Controls.WindowStartupLocation.CenterScreen }; } base.OnFrameworkInitializationCompleted(); } diff --git a/DiscordBotGUI/AppUpdater.axaml.cs b/DiscordBotGUI/AppUpdater.axaml.cs index ecc5405..8c4dccc 100644 --- a/DiscordBotGUI/AppUpdater.axaml.cs +++ b/DiscordBotGUI/AppUpdater.axaml.cs @@ -21,42 +21,48 @@ namespace DiscordBotGUI InitializeComponent(); if (!File.Exists("./Version.txt")) { - textBox1.Text = "Checking ..."; File.WriteAllText("./Version.txt", "DiscordBotVersion=0"); - //DownloadDiscordBotClientNoGUIAsDLL(); + DownloadDiscordBotClientNoGUIAsDLL(); } + if (!File.Exists("./DiscordBot.exe")) DownloadDiscordBotClientNoGUIAsDLL(); Updates(); } - /* private async void DownloadDiscordBotClientNoGUIAsDLL() - { + private async void DownloadDiscordBotClientNoGUIAsDLL() + { + //await Task.Delay(5000); + string url_bot_dll = "https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Updates/DiscordBot.zip"; + int actiontype = 0; //0 - downolad, 1- extract + IProgress progress = new Progress((percent) => + { + if (actiontype == 0) + textBox1.Text = "Downloading DiscordBot ... " + MathF.Round(percent, 2) + "%"; + else + textBox1.Text = "Extracting package ..." + MathF.Round(percent, 2) + "%"; + this.progressBar1.Value = percent; + }); - //await Task.Delay(5000); - string url_bot_dll = "https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Updates/DiscordBot.dll"; - IProgress progress = new Progress((percent) => - { - textBox1.Text = "Downloading DiscordBot.dll ... " + (percent * 100).ToString() + "%"; - this.progressBar1.Value = percent * 100; - }); + this.progressBar1.IsIndeterminate = false; + try + { + await ServerCom.DownloadFileAsync(url_bot_dll, "./DiscordBot.zip", progress); - this.progressBar1.IsIndeterminate = false; - try - { - await ServerCom.DownloadFileAsync(url_bot_dll, "./DiscordBot.dll", progress); - } - catch - { - textBox1.Text = "Error downloading DiscordBot.dll. Server is not responding."; + actiontype++; - await Task.Delay(1000); - return; - } + await Functions.ExtractArchive("./DiscordBot.zip", "./", progress); + } + catch + { + textBox1.Text = "Error downloading DiscordBot.dll. Server is not responding."; - //new MainWindow() { Height = 425, Width = 500 }.Show(); - //Close(); - }*/ + await Task.Delay(1000); + + new MainWindow() { Height = 425, Width = 500 }.Show(); + Close(); + } + } private async void Updates() { diff --git a/DiscordBotWithAPI.sln b/DiscordBotWithAPI.sln index 3f9ab41..7bf0ffe 100644 --- a/DiscordBotWithAPI.sln +++ b/DiscordBotWithAPI.sln @@ -23,8 +23,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CMD_Utils", "CMD_Utils\CMD_ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MusicCommands", "MusicCommands\MusicCommands.csproj", "{B1B4976E-5112-4217-B57B-3A03C5207B6E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Games", "FreeGames\Games.csproj", "{7CC0819E-2BC0-44F0-8D92-EC442F36E1BB}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordBotGUI", "DiscordBotGUI\DiscordBotGUI.csproj", "{7B5899F0-0218-4537-8C74-6210ED2D3690}" EndProject Global @@ -61,10 +59,6 @@ Global {B1B4976E-5112-4217-B57B-3A03C5207B6E}.Debug|Any CPU.Build.0 = Debug|Any CPU {B1B4976E-5112-4217-B57B-3A03C5207B6E}.Release|Any CPU.ActiveCfg = Release|Any CPU {B1B4976E-5112-4217-B57B-3A03C5207B6E}.Release|Any CPU.Build.0 = Release|Any CPU - {7CC0819E-2BC0-44F0-8D92-EC442F36E1BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7CC0819E-2BC0-44F0-8D92-EC442F36E1BB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7CC0819E-2BC0-44F0-8D92-EC442F36E1BB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7CC0819E-2BC0-44F0-8D92-EC442F36E1BB}.Release|Any CPU.Build.0 = Release|Any CPU {7B5899F0-0218-4537-8C74-6210ED2D3690}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7B5899F0-0218-4537-8C74-6210ED2D3690}.Debug|Any CPU.Build.0 = Debug|Any CPU {7B5899F0-0218-4537-8C74-6210ED2D3690}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -81,7 +75,6 @@ Global {CE9DBF06-38A0-4192-8B3E-4009210D040D} = {A290C028-77C4-4D1D-AB43-DDFE6ABD9012} {E26C87A4-3DD6-4B58-B14B-C8E086B852F9} = {449FA364-0B72-43FF-B3A3-806E2916200E} {B1B4976E-5112-4217-B57B-3A03C5207B6E} = {449FA364-0B72-43FF-B3A3-806E2916200E} - {7CC0819E-2BC0-44F0-8D92-EC442F36E1BB} = {449FA364-0B72-43FF-B3A3-806E2916200E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3FB3C5DE-ED21-4D2E-ABDD-3A00EE4A2FFF} diff --git a/PluginManager/Loaders/CommandsLoader.cs b/PluginManager/Loaders/CommandsLoader.cs deleted file mode 100644 index 919fa6b..0000000 --- a/PluginManager/Loaders/CommandsLoader.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; - -using PluginManager.Interfaces; - -namespace PluginManager.Loaders -{ - internal class CommandsLoader - { - private readonly string CMDPath; - private readonly string CMDExtension; - - - internal delegate void onCommandLoaded(string name, bool success, DBCommand? command = null, Exception? exception = null); - internal delegate void onCommandFileLoaded(string path); - - /// - /// Event fired when a command is loaded - /// - internal onCommandLoaded? OnCommandLoaded; - - /// - /// Event fired when the file is loaded - /// - internal onCommandFileLoaded? OnCommandFileLoaded; - - /// - /// Command Loader contructor - /// - /// The path to the commands - /// The extension to search for in the - internal CommandsLoader(string CommandPath, string CommandExtension) - { - CMDPath = CommandPath; - CMDExtension = CommandExtension; - } - - /// - /// The method that loads all commands - /// - /// - internal List? LoadCommands() - { - if (!Directory.Exists(CMDPath)) - { - Directory.CreateDirectory(CMDPath); - return null; - } - string[] files = Directory.GetFiles(CMDPath, $"*{CMDExtension}", SearchOption.AllDirectories); - - foreach (var file in files) - { - Assembly.LoadFile(Path.GetFullPath(file)); - if (OnCommandFileLoaded != null) - OnCommandFileLoaded.Invoke(file); - } - - List plugins = new List(); - - try - { - Type interfaceType = typeof(DBCommand); - Type[] types = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(a => a.GetTypes()) - .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) - .ToArray(); - foreach (Type type in types) - { - try - { - DBCommand plugin = (DBCommand)Activator.CreateInstance(type)!; - plugins.Add(plugin); - - if (OnCommandLoaded != null) - OnCommandLoaded.Invoke(type.FullName!, true, plugin); - } - catch (Exception e) - { - if (OnCommandLoaded != null) - OnCommandLoaded.Invoke(type.FullName!, false, null, e); - } - - } - - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - return null; - } - - return plugins; - - } - } -} diff --git a/PluginManager/Loaders/EventsLoader.cs b/PluginManager/Loaders/EventsLoader.cs deleted file mode 100644 index 28c1766..0000000 --- a/PluginManager/Loaders/EventsLoader.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; - -using PluginManager.Interfaces; - -namespace PluginManager.Loaders -{ - internal class EventsLoader - { - - private readonly string EVPath; - private readonly string EVExtension; - - internal delegate void onEventLoad(string name, bool success, DBEvent? ev = null, Exception? e = null); - internal delegate void onEventFileLoaded(string path); - - /// - /// An event that is fired whenever a event is loaded in memory - /// - internal onEventLoad? EventLoad; - - /// - /// An event that is fired whenever a event file is loaded - /// - internal onEventFileLoaded? EventFileLoaded; - - /// - /// The Event Loader constructor - /// - /// The path to all events - /// The extension for events - internal EventsLoader(string path, string ext) - { - EVPath = path; - EVExtension = ext; - } - - /// - /// The method that loads all events - /// - /// - internal List? LoadEvents() - { - - if (!Directory.Exists(EVPath)) - { - Directory.CreateDirectory(EVPath); - return null; - } - - string[] files = Directory.GetFiles(EVPath, $"*{EVExtension}", SearchOption.AllDirectories); - - foreach (var file in files) - { - Assembly.LoadFile(Path.GetFullPath(file)); - if (EventFileLoaded != null) - EventFileLoaded.Invoke(file); - } - - List events = new List(); - - try - { - Type interfaceType = typeof(DBEvent); - Type[] types = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(a => a.GetTypes()) - .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) - .ToArray(); - foreach (Type type in types) - { - try - { - DBEvent ev = (DBEvent)Activator.CreateInstance(type)!; - events.Add(ev); - - if (EventLoad != null) - EventLoad.Invoke(type.FullName!, true, ev, null); - } - catch (Exception e) - { - if (EventLoad != null) - EventLoad.Invoke(type.FullName!, false, null, e); - } - - } - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - return null; - } - - return events; - - } - } -} \ No newline at end of file diff --git a/PluginManager/Loaders/Loader.cs b/PluginManager/Loaders/Loader.cs new file mode 100644 index 0000000..955bc9f --- /dev/null +++ b/PluginManager/Loaders/Loader.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.CompilerServices; +using PluginManager.Interfaces; +using PluginManager.Others; + +namespace PluginManager.Loaders +{ + 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 delegate void FileLoadedEventHandler(LoaderArgs args); + + internal event FileLoadedEventHandler? FileLoaded; + + internal delegate void PluginLoadedEventHandler(LoaderArgs args); + + internal event PluginLoadedEventHandler? PluginLoaded; + + + private string path { get; } + private string extension { get; } + + + internal Loader(string path, string extension) + { + this.path = path; + this.extension = extension; + } + + internal List? Load() + { + List list = new List(); + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + return null; + } + + string[] files = Directory.GetFiles(path, $"*.{extension}", SearchOption.AllDirectories); + foreach (var file in files) + { + Assembly.LoadFrom(file); + if (FileLoaded != null) + { + LoaderArgs args = new LoaderArgs() { Exception = null, TypeName = nameof(T), IsLoaded = false, PluginName = file, Plugin = null }; + FileLoaded.Invoke(args); + } + } + + try + { + Type interfaceType = typeof(T); + Type[] types = AppDomain.CurrentDomain.GetAssemblies() + .SelectMany(a => a.GetTypes()) + .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) + .ToArray(); + + + list.Clear(); + foreach (Type type in types) + { + try + { + T plugin = (T)(Activator.CreateInstance(type)!); + list.Add(plugin); + + + if (PluginLoaded != null) { PluginLoaded.Invoke(new() { Exception = null, IsLoaded = true, PluginName = type.FullName, TypeName = nameof(T), Plugin = plugin }); } + } + catch (Exception ex) + { + if (PluginLoaded != null) { PluginLoaded.Invoke(new() { Exception = ex, IsLoaded = false, PluginName = type.FullName, TypeName = nameof(T) }); } + } + } + } + catch (Exception ex) { Functions.WriteErrFile(ex.ToString()); } + + + return list; + } + } +} diff --git a/PluginManager/Loaders/PluginLoader.cs b/PluginManager/Loaders/PluginLoader.cs index 520112d..813ba1b 100644 --- a/PluginManager/Loaders/PluginLoader.cs +++ b/PluginManager/Loaders/PluginLoader.cs @@ -1,35 +1,32 @@ using Discord.WebSocket; - using PluginManager.Interfaces; using PluginManager.Others; - using System; using System.Collections.Generic; + namespace PluginManager.Loaders { public class PluginLoader { - private DiscordSocketClient client; + private readonly DiscordSocketClient _client; /// /// The Plugin Loader constructor /// /// The discord bot client where the plugins will pe attached to - public PluginLoader(DiscordSocketClient discordSocketClient) - { - this.client = discordSocketClient; - } + public PluginLoader(DiscordSocketClient discordSocketClient) { this._client = discordSocketClient; } private const string pluginCMDFolder = @"./Data/Plugins/Commands/"; private const string pluginEVEFolder = @"./Data/Plugins/Events/"; - private const string pluginCMDExtension = ".dll"; - private const string pluginEVEExtension = ".dll"; + private const string pluginCMDExtension = "dll"; + private const string pluginEVEExtension = "dll"; + /// /// A list of commands /// - public static List? Plugins { get; set; } + public static List? Commands { get; set; } /// /// A list of commands @@ -38,6 +35,7 @@ namespace PluginManager.Loaders public delegate void CMDLoaded(string name, string typeName, bool success, Exception? e = null); + public delegate void EVELoaded(string name, string typeName, bool success, Exception? e = null); /// @@ -55,11 +53,10 @@ namespace PluginManager.Loaders /// public void LoadPlugins() { + Commands = new List(); + Events = new List(); - Plugins = new List(); - Events = new List(); - - Functions.WriteLogFile("Starting plugin loader ... Client: " + client.CurrentUser.Username); + Functions.WriteLogFile("Starting plugin loader ... Client: " + _client.CurrentUser.Username); if (LanguageSystem.Language.ActiveLanguage != null) Console_Utilities.WriteColorText( LanguageSystem.Language.ActiveLanguage.FormatText( @@ -67,45 +64,40 @@ namespace PluginManager.Loaders ) ); - //Load commands - CommandsLoader CMDLoader = new CommandsLoader(pluginCMDFolder, pluginCMDExtension); - CMDLoader.OnCommandLoaded += OnCommandLoaded!; - CMDLoader.OnCommandFileLoaded += OnCommandFileLoaded; - Plugins = CMDLoader.LoadCommands(); + Loader commandsLoader = new Loader(pluginCMDFolder, pluginCMDExtension); + Loader eventsLoader = new Loader(pluginEVEFolder, pluginEVEExtension); - //Load Events - EventsLoader EVLoader = new EventsLoader(pluginEVEFolder, pluginEVEExtension); - EVLoader.EventLoad += OnEventLoaded!; - EVLoader.EventFileLoaded += EventFileLoaded; - Events = EVLoader.LoadEvents(); + commandsLoader.FileLoaded += OnCommandFileLoaded; + commandsLoader.PluginLoaded += OnCommandLoaded; + eventsLoader.FileLoaded += EventFileLoaded; + eventsLoader.PluginLoaded += OnEventLoaded; + + Commands = commandsLoader.Load(); + Events = eventsLoader.Load(); } - private void EventFileLoaded(string path) + private void EventFileLoaded(LoaderArgs e) { - if (path != null) - Functions.WriteLogFile($"[EVENT] Event from file [{path}] has been successfully created !"); + if (e.IsLoaded) Functions.WriteLogFile($"[EVENT] Event from file [{e.PluginName}] has been successfully created !"); } - private void OnCommandFileLoaded(string path) + private void OnCommandFileLoaded(LoaderArgs e) { - if (path != null) - Functions.WriteLogFile($"[CMD] Command from file [{path}] has been successfully loaded !"); + if (e.IsLoaded) Functions.WriteLogFile($"[CMD] Command from file [{e.PluginName}] has been successfully loaded !"); } - private void OnEventLoaded(string typename, bool success, DBEvent eve, Exception exception) + private void OnEventLoaded(LoaderArgs e) { - if (eve != null && success) - eve.Start(client); - if (onEVELoad != null) - onEVELoad.Invoke(eve!.name, typename, success, exception); + if (e.IsLoaded) { ((DBEvent)e.Plugin!).Start(_client); } + + if (onEVELoad != null) onEVELoad.Invoke(((DBEvent)e.Plugin!).name, e.TypeName!, e.IsLoaded, e.Exception); } - private void OnCommandLoaded(string name, bool success, DBCommand command, Exception exception) + private void OnCommandLoaded(LoaderArgs e) { - if (onCMDLoad != null) - onCMDLoad.Invoke(command.Command, name, success, exception); + if (onCMDLoad != null) onCMDLoad.Invoke(((DBCommand)e.Plugin!).Command, e.TypeName!, e.IsLoaded, e.Exception); } } } diff --git a/PluginManager/Others/Console Utilities.cs b/PluginManager/Others/Console Utilities.cs index 1cdf29a..cf710d8 100644 --- a/PluginManager/Others/Console Utilities.cs +++ b/PluginManager/Others/Console Utilities.cs @@ -1,9 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; namespace PluginManager.Others { @@ -14,17 +10,20 @@ namespace PluginManager.Others /// public class ProgressBar { - public int Progress { get; set; } - public int Max { get; set; } - public string Message { get; set; } + public int Max { get; set; } + public string Message { get; set; } + public ConsoleColor Color { get; init; } + public ProgressBar(int max, string message) { - Max = max; + Max = max; Message = message; + var consoleColors = Enum.GetValues(typeof(ConsoleColor)); + while ((Color = (ConsoleColor)consoleColors.GetValue(new Random().Next(consoleColors.Length))!) == ConsoleColor.White && Color != ConsoleColor.Black) ; } - public async void Update(int progress, double speed = -1, string? unit = null) + public void Update(int progress, double speed = -1, string? unit = null) { //progress bar @@ -39,8 +38,8 @@ namespace PluginManager.Others for (int i = 0; i < onechunk * progress; i++) { - Console.BackgroundColor = ConsoleColor.Green; - Console.CursorLeft = position++; + Console.BackgroundColor = this.Color; + Console.CursorLeft = position++; Console.Write(" "); } @@ -130,11 +129,12 @@ namespace PluginManager.Others ConsoleColor fg = Console.ForegroundColor; Dictionary colors = new Dictionary() { - {"&g", ConsoleColor.Green }, - {"&b", ConsoleColor.Blue }, - {"&r", ConsoleColor.Red }, - {"&m", ConsoleColor.Magenta }, - {"&c", fg } + { "&g", ConsoleColor.Green }, + { "&b", ConsoleColor.Blue }, + { "&r", ConsoleColor.Red }, + { "&m", ConsoleColor.Magenta }, + { "&y", ConsoleColor.Yellow }, + { "&c", fg } }; foreach (string word in words) { @@ -145,7 +145,9 @@ namespace PluginManager.Others Console.ForegroundColor = colors[prefix]; } - string m = word.Replace("&g", "").Replace("&b", "").Replace("&r", "").Replace("&c", "").Replace("&m", ""); + string m = word; + foreach (var key in colors.Keys) { m = m.Replace(key, ""); } + Console.Write(m + " "); } if (appendNewLine) diff --git a/PluginManager/Others/Functions.cs b/PluginManager/Others/Functions.cs index 9e8091b..a87d603 100644 --- a/PluginManager/Others/Functions.cs +++ b/PluginManager/Others/Functions.cs @@ -259,16 +259,13 @@ namespace PluginManager.Others foreach (ZipArchiveEntry entry in archive.Entries) { if (entry.FullName.EndsWith("/")) - { - currentZIPFile++; Directory.CreateDirectory(Path.Combine(folder, entry.FullName)); - } - else - { - entry.ExtractToFile(Path.Combine(folder, entry.FullName), true); - currentZIPFile++; - } + else + try { entry.ExtractToFile(Path.Combine(folder, entry.FullName), true); } + catch { } + + currentZIPFile++; await Task.Delay(10); progress.Report((float)currentZIPFile / totalZIPFiles * 100); } diff --git a/PluginManager/PluginManager.csproj b/PluginManager/PluginManager.csproj index 7d2d32a..7eafd1b 100644 --- a/PluginManager/PluginManager.csproj +++ b/PluginManager/PluginManager.csproj @@ -19,10 +19,4 @@ - - - MSBuild:Compile - - - From 8fcd33e734e9b2ef22915c3e8e0d868e61eb16b2 Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Fri, 3 Jun 2022 22:38:20 +0300 Subject: [PATCH 06/20] --- DiscordBotGUI/AppUpdater.axaml.cs | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/DiscordBotGUI/AppUpdater.axaml.cs b/DiscordBotGUI/AppUpdater.axaml.cs index 8c4dccc..785e1d4 100644 --- a/DiscordBotGUI/AppUpdater.axaml.cs +++ b/DiscordBotGUI/AppUpdater.axaml.cs @@ -1,7 +1,6 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; - using PluginManager.Online; using PluginManager.Others; using System.Threading.Tasks; @@ -16,6 +15,7 @@ namespace DiscordBotGUI public partial class AppUpdater : Window { private string _version; + public AppUpdater() { InitializeComponent(); @@ -27,7 +27,6 @@ namespace DiscordBotGUI if (!File.Exists("./DiscordBot.exe")) DownloadDiscordBotClientNoGUIAsDLL(); Updates(); - } private async void DownloadDiscordBotClientNoGUIAsDLL() @@ -88,31 +87,27 @@ namespace DiscordBotGUI return; } - IProgress progress = new Progress((percent) => - { - this.progressBar1.Value = percent; - }); + IProgress progress = new Progress((percent) => { this.progressBar1.Value = percent; }); textBox1.Text = "Extracting update files ..."; await Functions.ExtractArchive(file, "./", progress); progressBar1.IsIndeterminate = true; - textBox1.Text = "Setting up the new version ..."; + textBox1.Text = "Setting up the new version ..."; File.Delete(file); File.WriteAllText("./Version.txt", "DiscordBotVersion=" + _version); await Task.Delay(5000); new MainWindow() { Height = 425, Width = 650 }.Show(); this.Close(); - } private async Task DownloadNewUpdate() { string urlNewUpdateZip = (await ServerCom.ReadTextFromFile("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Updates/Version"))[1]; - int secondsPast = 0; + int secondsPast = 0; bool isDownloading = true; this.progressBar1.IsIndeterminate = true; - textBox1.Text = "Downloading update ..."; + textBox1.Text = "Downloading update ..."; IProgress downloaded = new Progress((bytes) => @@ -123,14 +118,13 @@ namespace DiscordBotGUI IProgress progress = new Progress((percent) => { progressBar1.IsIndeterminate = false; - this.progressBar1.Value = percent; + this.progressBar1.Value = percent; }); string FileName = $"{urlNewUpdateZip.Split('/')[urlNewUpdateZip.Split('/').Length - 1]}"; try { - new Thread(new Task(() => { while (isDownloading) @@ -148,6 +142,7 @@ namespace DiscordBotGUI await Task.Delay(1000); return null; } + isDownloading = false; return FileName; } @@ -156,14 +151,10 @@ namespace DiscordBotGUI { try { - string current_version = Functions.readCodeFromFile("Version.txt", "DiscordBotVersion", '=') ?? "0"; - string latest_version = (await ServerCom.ReadTextFromFile("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Updates/Version"))[0]; + string latest_version = (await ServerCom.ReadTextFromFile("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Updates/Version"))[0]; _version = latest_version; - if (current_version != latest_version) - { - return true; - } + if (current_version != latest_version) { return true; } return false; } From 0b6b57cc84d7223187c56d01f49733e091659268 Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Sat, 4 Jun 2022 18:55:29 +0300 Subject: [PATCH 07/20] Moved to json file format --- BUILDS/net6.0/CMD_LevelingSystem.deps.json | 268 ------------------ BUILDS/net6.0/CMD_LevelingSystem.dll | Bin 10752 -> 0 bytes BUILDS/net6.0/EVE_LevelingSystem.deps.json | 268 ------------------ BUILDS/net6.0/EVE_LevelingSystem.dll | Bin 11776 -> 0 bytes BUILDS/net6.0/PluginManager.dll | Bin 62976 -> 63488 bytes BUILDS/net6.0/StartupEvents.deps.json | 268 ------------------ BUILDS/net6.0/StartupEvents.dll | Bin 12800 -> 0 bytes CMD_LevelingSystem/CMD_LevelingSystem.csproj | 13 +- CMD_LevelingSystem/Commands/level.cs | 61 ---- .../Items/Leveling System/Core.cs | 62 ---- .../Items/Leveling System/Data.cs | 24 -- CMD_LevelingSystem/Level.cs | 48 ++++ CMD_LevelingSystem/User.cs | 16 ++ DiscordBot/Discord/Commands/Settings.cs | 4 +- DiscordBot/Discord/Core/Boot.cs | 18 +- DiscordBot/Discord/Core/CommandHandler.cs | 2 +- DiscordBot/Program.cs | 97 +++---- DiscordBotGUI/AppUpdater.axaml.cs | 2 - DiscordBotGUI/MainWindow.axaml.cs | 10 +- DiscordBotWithAPI.sln | 37 +-- EVE_LevelingSystem/Core.cs | 62 ---- EVE_LevelingSystem/Data.cs | 24 -- EVE_LevelingSystem/EVE_LevelingSystem.csproj | 27 +- EVE_LevelingSystem/Level.cs | 42 +++ EVE_LevelingSystem/LevelingSystem.cs | 56 ---- .../LevelingSystemCore/LevelCalculator.cs | 56 ++++ EVE_LevelingSystem/LevelingSystemCore/User.cs | 16 ++ FreeGames/Game.cs | 32 --- FreeGames/Games.csproj | 19 -- FreeGames/Objects/GameData.cs | 24 -- PluginManager/Config.cs | 87 ++++++ PluginManager/Items/ConsoleCommandsHandler.cs | 120 +++----- PluginManager/Language System/Language.cs | 161 ----------- PluginManager/Loaders/Loader.cs | 40 ++- PluginManager/Loaders/PluginLoader.cs | 8 +- PluginManager/Others/Functions.cs | 119 ++++---- StartupEvents/OnUserJoin.cs | 57 ---- StartupEvents/SetGameOnLogin.cs | 48 ---- StartupEvents/StartupEvents.csproj | 17 -- 39 files changed, 501 insertions(+), 1712 deletions(-) delete mode 100644 BUILDS/net6.0/CMD_LevelingSystem.deps.json delete mode 100644 BUILDS/net6.0/CMD_LevelingSystem.dll delete mode 100644 BUILDS/net6.0/EVE_LevelingSystem.deps.json delete mode 100644 BUILDS/net6.0/EVE_LevelingSystem.dll delete mode 100644 BUILDS/net6.0/StartupEvents.deps.json delete mode 100644 BUILDS/net6.0/StartupEvents.dll delete mode 100644 CMD_LevelingSystem/Commands/level.cs delete mode 100644 CMD_LevelingSystem/Items/Leveling System/Core.cs delete mode 100644 CMD_LevelingSystem/Items/Leveling System/Data.cs create mode 100644 CMD_LevelingSystem/Level.cs create mode 100644 CMD_LevelingSystem/User.cs delete mode 100644 EVE_LevelingSystem/Core.cs delete mode 100644 EVE_LevelingSystem/Data.cs create mode 100644 EVE_LevelingSystem/Level.cs delete mode 100644 EVE_LevelingSystem/LevelingSystem.cs create mode 100644 EVE_LevelingSystem/LevelingSystemCore/LevelCalculator.cs create mode 100644 EVE_LevelingSystem/LevelingSystemCore/User.cs delete mode 100644 FreeGames/Game.cs delete mode 100644 FreeGames/Games.csproj delete mode 100644 FreeGames/Objects/GameData.cs create mode 100644 PluginManager/Config.cs delete mode 100644 PluginManager/Language System/Language.cs delete mode 100644 StartupEvents/OnUserJoin.cs delete mode 100644 StartupEvents/SetGameOnLogin.cs delete mode 100644 StartupEvents/StartupEvents.csproj diff --git a/BUILDS/net6.0/CMD_LevelingSystem.deps.json b/BUILDS/net6.0/CMD_LevelingSystem.deps.json deleted file mode 100644 index ab0049d..0000000 --- a/BUILDS/net6.0/CMD_LevelingSystem.deps.json +++ /dev/null @@ -1,268 +0,0 @@ -{ - "runtimeTarget": { - "name": ".NETCoreApp,Version=v6.0", - "signature": "" - }, - "compilationOptions": {}, - "targets": { - ".NETCoreApp,Version=v6.0": { - "CMD_LevelingSystem/1.0.0": { - "dependencies": { - "PluginManager": "1.0.0" - }, - "runtime": { - "CMD_LevelingSystem.dll": {} - } - }, - "Discord.Net/3.6.1": { - "dependencies": { - "Discord.Net.Commands": "3.6.1", - "Discord.Net.Core": "3.6.1", - "Discord.Net.Interactions": "3.6.1", - "Discord.Net.Rest": "3.6.1", - "Discord.Net.WebSocket": "3.6.1", - "Discord.Net.Webhook": "3.6.1" - } - }, - "Discord.Net.Commands/3.6.1": { - "dependencies": { - "Discord.Net.Core": "3.6.1" - }, - "runtime": { - "lib/net6.0/Discord.Net.Commands.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Discord.Net.Core/3.6.1": { - "dependencies": { - "Newtonsoft.Json": "13.0.1", - "System.Collections.Immutable": "5.0.0", - "System.Interactive.Async": "5.0.0", - "System.ValueTuple": "4.5.0" - }, - "runtime": { - "lib/net6.0/Discord.Net.Core.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Discord.Net.Interactions/3.6.1": { - "dependencies": { - "Discord.Net.Core": "3.6.1", - "Discord.Net.Rest": "3.6.1", - "Discord.Net.WebSocket": "3.6.1", - "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0", - "System.Collections.Immutable": "5.0.0", - "System.Reactive": "5.0.0" - }, - "runtime": { - "lib/net6.0/Discord.Net.Interactions.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Discord.Net.Rest/3.6.1": { - "dependencies": { - "Discord.Net.Core": "3.6.1" - }, - "runtime": { - "lib/net6.0/Discord.Net.Rest.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Discord.Net.Webhook/3.6.1": { - "dependencies": { - "Discord.Net.Core": "3.6.1", - "Discord.Net.Rest": "3.6.1" - }, - "runtime": { - "lib/net6.0/Discord.Net.Webhook.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Discord.Net.WebSocket/3.6.1": { - "dependencies": { - "Discord.Net.Core": "3.6.1", - "Discord.Net.Rest": "3.6.1" - }, - "runtime": { - "lib/net6.0/Discord.Net.WebSocket.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { - "runtime": { - "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { - "assemblyVersion": "5.0.0.0", - "fileVersion": "5.0.20.51904" - } - } - }, - "Newtonsoft.Json/13.0.1": { - "runtime": { - "lib/netstandard2.0/Newtonsoft.Json.dll": { - "assemblyVersion": "13.0.0.0", - "fileVersion": "13.0.1.25517" - } - } - }, - "System.Collections.Immutable/5.0.0": {}, - "System.Interactive.Async/5.0.0": { - "dependencies": { - "System.Linq.Async": "5.0.0" - }, - "runtime": { - "lib/netcoreapp3.1/System.Interactive.Async.dll": { - "assemblyVersion": "5.0.0.0", - "fileVersion": "5.0.0.1" - } - } - }, - "System.Linq.Async/5.0.0": { - "runtime": { - "lib/netcoreapp3.1/System.Linq.Async.dll": { - "assemblyVersion": "5.0.0.0", - "fileVersion": "5.0.0.1" - } - } - }, - "System.Reactive/5.0.0": { - "runtime": { - "lib/net5.0/System.Reactive.dll": { - "assemblyVersion": "5.0.0.0", - "fileVersion": "5.0.0.1" - } - } - }, - "System.ValueTuple/4.5.0": {}, - "PluginManager/1.0.0": { - "dependencies": { - "Discord.Net": "3.6.1" - }, - "runtime": { - "PluginManager.dll": {} - } - } - } - }, - "libraries": { - "CMD_LevelingSystem/1.0.0": { - "type": "project", - "serviceable": false, - "sha512": "" - }, - "Discord.Net/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-TfcL/HG57fVt//WVJ2XyF2PlytY9IYkkwwkPLIhvu5FW4wf9rm7+N8RPh4qtELLfsa5ES0FK2RbgYjABRR9AjA==", - "path": "discord.net/3.6.1", - "hashPath": "discord.net.3.6.1.nupkg.sha512" - }, - "Discord.Net.Commands/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-kK7m571yzSzPd93o+n8Z+TfvX62BT1HtOEZIWXKwXWO8itP/sgqBNExjWK/6DOpkbD6+khc2f3rp+TA0rJD88g==", - "path": "discord.net.commands/3.6.1", - "hashPath": "discord.net.commands.3.6.1.nupkg.sha512" - }, - "Discord.Net.Core/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-ibVjQiWzgqh0GyP/GXE2kv3TA/9ysmmNFG/WmRE7GepQQAXXGxVUO9IMJ8h14EvIXMQ0m0DktMe5DkUnilo3Ag==", - "path": "discord.net.core/3.6.1", - "hashPath": "discord.net.core.3.6.1.nupkg.sha512" - }, - "Discord.Net.Interactions/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-WGOxz6SMUu4WS5b/JdrhlwQletcplBIYqvjFBBDfnqE+uNJqcNGtAdyjLqIILfXGx8aSSSSYZSCeAUa7FZ8Yew==", - "path": "discord.net.interactions/3.6.1", - "hashPath": "discord.net.interactions.3.6.1.nupkg.sha512" - }, - "Discord.Net.Rest/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-T7RRThIS23roFEJwTL1l7aawjVyn7ZB5yH3tMge0d6TiCzzp4V4FAZ+ArTt19LHRFhPly90v8V3sWqmTMN+5Zg==", - "path": "discord.net.rest/3.6.1", - "hashPath": "discord.net.rest.3.6.1.nupkg.sha512" - }, - "Discord.Net.Webhook/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-xikKHIGAIMz0BzHkaTKb48DNpFjKW8mvJjLJSezJ1xQOu+laHNk/hav4qxVtyZz7HSI/vGTkmlq9hKVhWzpaUA==", - "path": "discord.net.webhook/3.6.1", - "hashPath": "discord.net.webhook.3.6.1.nupkg.sha512" - }, - "Discord.Net.WebSocket/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-hF22Xy7URlVEDQZ69INOgzPvFUsIDfd+r6U+1yF9HWdBn3d4THnvAAhkv1TraSx/T/MKS7g+jvk/HZ3mh5S3aw==", - "path": "discord.net.websocket/3.6.1", - "hashPath": "discord.net.websocket.3.6.1.nupkg.sha512" - }, - "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-ORj7Zh81gC69TyvmcUm9tSzytcy8AVousi+IVRAI8nLieQjOFryRusSFh7+aLk16FN9pQNqJAiMd7BTKINK0kA==", - "path": "microsoft.extensions.dependencyinjection.abstractions/5.0.0", - "hashPath": "microsoft.extensions.dependencyinjection.abstractions.5.0.0.nupkg.sha512" - }, - "Newtonsoft.Json/13.0.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", - "path": "newtonsoft.json/13.0.1", - "hashPath": "newtonsoft.json.13.0.1.nupkg.sha512" - }, - "System.Collections.Immutable/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g==", - "path": "system.collections.immutable/5.0.0", - "hashPath": "system.collections.immutable.5.0.0.nupkg.sha512" - }, - "System.Interactive.Async/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-QaqhQVDiULcu4vm6o89+iP329HcK44cETHOYgy/jfEjtzeFy0ZxmuM7nel9ocjnKxEM4yh1mli7hgh8Q9o+/Iw==", - "path": "system.interactive.async/5.0.0", - "hashPath": "system.interactive.async.5.0.0.nupkg.sha512" - }, - "System.Linq.Async/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-cPtIuuH8TIjVHSi2ewwReWGW1PfChPE0LxPIDlfwVcLuTM9GANFTXiMB7k3aC4sk3f0cQU25LNKzx+jZMxijqw==", - "path": "system.linq.async/5.0.0", - "hashPath": "system.linq.async.5.0.0.nupkg.sha512" - }, - "System.Reactive/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==", - "path": "system.reactive/5.0.0", - "hashPath": "system.reactive.5.0.0.nupkg.sha512" - }, - "System.ValueTuple/4.5.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==", - "path": "system.valuetuple/4.5.0", - "hashPath": "system.valuetuple.4.5.0.nupkg.sha512" - }, - "PluginManager/1.0.0": { - "type": "project", - "serviceable": false, - "sha512": "" - } - } -} \ No newline at end of file diff --git a/BUILDS/net6.0/CMD_LevelingSystem.dll b/BUILDS/net6.0/CMD_LevelingSystem.dll deleted file mode 100644 index c69f2b33b1717b0f7fc59f69c53fe577b4019727..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10752 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 diff --git a/BUILDS/net6.0/EVE_LevelingSystem.deps.json b/BUILDS/net6.0/EVE_LevelingSystem.deps.json deleted file mode 100644 index 1b99176..0000000 --- a/BUILDS/net6.0/EVE_LevelingSystem.deps.json +++ /dev/null @@ -1,268 +0,0 @@ -{ - "runtimeTarget": { - "name": ".NETCoreApp,Version=v6.0", - "signature": "" - }, - "compilationOptions": {}, - "targets": { - ".NETCoreApp,Version=v6.0": { - "EVE_LevelingSystem/1.0.0": { - "dependencies": { - "PluginManager": "1.0.0" - }, - "runtime": { - "EVE_LevelingSystem.dll": {} - } - }, - "Discord.Net/3.6.1": { - "dependencies": { - "Discord.Net.Commands": "3.6.1", - "Discord.Net.Core": "3.6.1", - "Discord.Net.Interactions": "3.6.1", - "Discord.Net.Rest": "3.6.1", - "Discord.Net.WebSocket": "3.6.1", - "Discord.Net.Webhook": "3.6.1" - } - }, - "Discord.Net.Commands/3.6.1": { - "dependencies": { - "Discord.Net.Core": "3.6.1" - }, - "runtime": { - "lib/net6.0/Discord.Net.Commands.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Discord.Net.Core/3.6.1": { - "dependencies": { - "Newtonsoft.Json": "13.0.1", - "System.Collections.Immutable": "5.0.0", - "System.Interactive.Async": "5.0.0", - "System.ValueTuple": "4.5.0" - }, - "runtime": { - "lib/net6.0/Discord.Net.Core.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Discord.Net.Interactions/3.6.1": { - "dependencies": { - "Discord.Net.Core": "3.6.1", - "Discord.Net.Rest": "3.6.1", - "Discord.Net.WebSocket": "3.6.1", - "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0", - "System.Collections.Immutable": "5.0.0", - "System.Reactive": "5.0.0" - }, - "runtime": { - "lib/net6.0/Discord.Net.Interactions.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Discord.Net.Rest/3.6.1": { - "dependencies": { - "Discord.Net.Core": "3.6.1" - }, - "runtime": { - "lib/net6.0/Discord.Net.Rest.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Discord.Net.Webhook/3.6.1": { - "dependencies": { - "Discord.Net.Core": "3.6.1", - "Discord.Net.Rest": "3.6.1" - }, - "runtime": { - "lib/net6.0/Discord.Net.Webhook.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Discord.Net.WebSocket/3.6.1": { - "dependencies": { - "Discord.Net.Core": "3.6.1", - "Discord.Net.Rest": "3.6.1" - }, - "runtime": { - "lib/net6.0/Discord.Net.WebSocket.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { - "runtime": { - "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { - "assemblyVersion": "5.0.0.0", - "fileVersion": "5.0.20.51904" - } - } - }, - "Newtonsoft.Json/13.0.1": { - "runtime": { - "lib/netstandard2.0/Newtonsoft.Json.dll": { - "assemblyVersion": "13.0.0.0", - "fileVersion": "13.0.1.25517" - } - } - }, - "System.Collections.Immutable/5.0.0": {}, - "System.Interactive.Async/5.0.0": { - "dependencies": { - "System.Linq.Async": "5.0.0" - }, - "runtime": { - "lib/netcoreapp3.1/System.Interactive.Async.dll": { - "assemblyVersion": "5.0.0.0", - "fileVersion": "5.0.0.1" - } - } - }, - "System.Linq.Async/5.0.0": { - "runtime": { - "lib/netcoreapp3.1/System.Linq.Async.dll": { - "assemblyVersion": "5.0.0.0", - "fileVersion": "5.0.0.1" - } - } - }, - "System.Reactive/5.0.0": { - "runtime": { - "lib/net5.0/System.Reactive.dll": { - "assemblyVersion": "5.0.0.0", - "fileVersion": "5.0.0.1" - } - } - }, - "System.ValueTuple/4.5.0": {}, - "PluginManager/1.0.0": { - "dependencies": { - "Discord.Net": "3.6.1" - }, - "runtime": { - "PluginManager.dll": {} - } - } - } - }, - "libraries": { - "EVE_LevelingSystem/1.0.0": { - "type": "project", - "serviceable": false, - "sha512": "" - }, - "Discord.Net/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-TfcL/HG57fVt//WVJ2XyF2PlytY9IYkkwwkPLIhvu5FW4wf9rm7+N8RPh4qtELLfsa5ES0FK2RbgYjABRR9AjA==", - "path": "discord.net/3.6.1", - "hashPath": "discord.net.3.6.1.nupkg.sha512" - }, - "Discord.Net.Commands/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-kK7m571yzSzPd93o+n8Z+TfvX62BT1HtOEZIWXKwXWO8itP/sgqBNExjWK/6DOpkbD6+khc2f3rp+TA0rJD88g==", - "path": "discord.net.commands/3.6.1", - "hashPath": "discord.net.commands.3.6.1.nupkg.sha512" - }, - "Discord.Net.Core/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-ibVjQiWzgqh0GyP/GXE2kv3TA/9ysmmNFG/WmRE7GepQQAXXGxVUO9IMJ8h14EvIXMQ0m0DktMe5DkUnilo3Ag==", - "path": "discord.net.core/3.6.1", - "hashPath": "discord.net.core.3.6.1.nupkg.sha512" - }, - "Discord.Net.Interactions/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-WGOxz6SMUu4WS5b/JdrhlwQletcplBIYqvjFBBDfnqE+uNJqcNGtAdyjLqIILfXGx8aSSSSYZSCeAUa7FZ8Yew==", - "path": "discord.net.interactions/3.6.1", - "hashPath": "discord.net.interactions.3.6.1.nupkg.sha512" - }, - "Discord.Net.Rest/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-T7RRThIS23roFEJwTL1l7aawjVyn7ZB5yH3tMge0d6TiCzzp4V4FAZ+ArTt19LHRFhPly90v8V3sWqmTMN+5Zg==", - "path": "discord.net.rest/3.6.1", - "hashPath": "discord.net.rest.3.6.1.nupkg.sha512" - }, - "Discord.Net.Webhook/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-xikKHIGAIMz0BzHkaTKb48DNpFjKW8mvJjLJSezJ1xQOu+laHNk/hav4qxVtyZz7HSI/vGTkmlq9hKVhWzpaUA==", - "path": "discord.net.webhook/3.6.1", - "hashPath": "discord.net.webhook.3.6.1.nupkg.sha512" - }, - "Discord.Net.WebSocket/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-hF22Xy7URlVEDQZ69INOgzPvFUsIDfd+r6U+1yF9HWdBn3d4THnvAAhkv1TraSx/T/MKS7g+jvk/HZ3mh5S3aw==", - "path": "discord.net.websocket/3.6.1", - "hashPath": "discord.net.websocket.3.6.1.nupkg.sha512" - }, - "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-ORj7Zh81gC69TyvmcUm9tSzytcy8AVousi+IVRAI8nLieQjOFryRusSFh7+aLk16FN9pQNqJAiMd7BTKINK0kA==", - "path": "microsoft.extensions.dependencyinjection.abstractions/5.0.0", - "hashPath": "microsoft.extensions.dependencyinjection.abstractions.5.0.0.nupkg.sha512" - }, - "Newtonsoft.Json/13.0.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", - "path": "newtonsoft.json/13.0.1", - "hashPath": "newtonsoft.json.13.0.1.nupkg.sha512" - }, - "System.Collections.Immutable/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g==", - "path": "system.collections.immutable/5.0.0", - "hashPath": "system.collections.immutable.5.0.0.nupkg.sha512" - }, - "System.Interactive.Async/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-QaqhQVDiULcu4vm6o89+iP329HcK44cETHOYgy/jfEjtzeFy0ZxmuM7nel9ocjnKxEM4yh1mli7hgh8Q9o+/Iw==", - "path": "system.interactive.async/5.0.0", - "hashPath": "system.interactive.async.5.0.0.nupkg.sha512" - }, - "System.Linq.Async/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-cPtIuuH8TIjVHSi2ewwReWGW1PfChPE0LxPIDlfwVcLuTM9GANFTXiMB7k3aC4sk3f0cQU25LNKzx+jZMxijqw==", - "path": "system.linq.async/5.0.0", - "hashPath": "system.linq.async.5.0.0.nupkg.sha512" - }, - "System.Reactive/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==", - "path": "system.reactive/5.0.0", - "hashPath": "system.reactive.5.0.0.nupkg.sha512" - }, - "System.ValueTuple/4.5.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==", - "path": "system.valuetuple/4.5.0", - "hashPath": "system.valuetuple.4.5.0.nupkg.sha512" - }, - "PluginManager/1.0.0": { - "type": "project", - "serviceable": false, - "sha512": "" - } - } -} \ No newline at end of file diff --git a/BUILDS/net6.0/EVE_LevelingSystem.dll b/BUILDS/net6.0/EVE_LevelingSystem.dll deleted file mode 100644 index 58c77e5e96d071e9830f8b1b8a63fdbfe13f1d1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11776 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 diff --git a/BUILDS/net6.0/PluginManager.dll b/BUILDS/net6.0/PluginManager.dll index 484c585cfad2bab1d5678c0b02ae8e2c84a55d37..58b27717a2233aaec05de06d981fca39f72b7025 100644 GIT binary patch literal 63488 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 Gf&T+*I>g%m literal 62976 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 eM>lRG8vi8xG`$!M}B+TXi=kUW);J*ONy-Csl diff --git a/BUILDS/net6.0/StartupEvents.deps.json b/BUILDS/net6.0/StartupEvents.deps.json deleted file mode 100644 index 429d030..0000000 --- a/BUILDS/net6.0/StartupEvents.deps.json +++ /dev/null @@ -1,268 +0,0 @@ -{ - "runtimeTarget": { - "name": ".NETCoreApp,Version=v6.0", - "signature": "" - }, - "compilationOptions": {}, - "targets": { - ".NETCoreApp,Version=v6.0": { - "StartupEvents/1.0.0": { - "dependencies": { - "PluginManager": "1.0.0" - }, - "runtime": { - "StartupEvents.dll": {} - } - }, - "Discord.Net/3.6.1": { - "dependencies": { - "Discord.Net.Commands": "3.6.1", - "Discord.Net.Core": "3.6.1", - "Discord.Net.Interactions": "3.6.1", - "Discord.Net.Rest": "3.6.1", - "Discord.Net.WebSocket": "3.6.1", - "Discord.Net.Webhook": "3.6.1" - } - }, - "Discord.Net.Commands/3.6.1": { - "dependencies": { - "Discord.Net.Core": "3.6.1" - }, - "runtime": { - "lib/net6.0/Discord.Net.Commands.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Discord.Net.Core/3.6.1": { - "dependencies": { - "Newtonsoft.Json": "13.0.1", - "System.Collections.Immutable": "5.0.0", - "System.Interactive.Async": "5.0.0", - "System.ValueTuple": "4.5.0" - }, - "runtime": { - "lib/net6.0/Discord.Net.Core.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Discord.Net.Interactions/3.6.1": { - "dependencies": { - "Discord.Net.Core": "3.6.1", - "Discord.Net.Rest": "3.6.1", - "Discord.Net.WebSocket": "3.6.1", - "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0", - "System.Collections.Immutable": "5.0.0", - "System.Reactive": "5.0.0" - }, - "runtime": { - "lib/net6.0/Discord.Net.Interactions.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Discord.Net.Rest/3.6.1": { - "dependencies": { - "Discord.Net.Core": "3.6.1" - }, - "runtime": { - "lib/net6.0/Discord.Net.Rest.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Discord.Net.Webhook/3.6.1": { - "dependencies": { - "Discord.Net.Core": "3.6.1", - "Discord.Net.Rest": "3.6.1" - }, - "runtime": { - "lib/net6.0/Discord.Net.Webhook.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Discord.Net.WebSocket/3.6.1": { - "dependencies": { - "Discord.Net.Core": "3.6.1", - "Discord.Net.Rest": "3.6.1" - }, - "runtime": { - "lib/net6.0/Discord.Net.WebSocket.dll": { - "assemblyVersion": "3.6.1.0", - "fileVersion": "3.6.1.0" - } - } - }, - "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { - "runtime": { - "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { - "assemblyVersion": "5.0.0.0", - "fileVersion": "5.0.20.51904" - } - } - }, - "Newtonsoft.Json/13.0.1": { - "runtime": { - "lib/netstandard2.0/Newtonsoft.Json.dll": { - "assemblyVersion": "13.0.0.0", - "fileVersion": "13.0.1.25517" - } - } - }, - "System.Collections.Immutable/5.0.0": {}, - "System.Interactive.Async/5.0.0": { - "dependencies": { - "System.Linq.Async": "5.0.0" - }, - "runtime": { - "lib/netcoreapp3.1/System.Interactive.Async.dll": { - "assemblyVersion": "5.0.0.0", - "fileVersion": "5.0.0.1" - } - } - }, - "System.Linq.Async/5.0.0": { - "runtime": { - "lib/netcoreapp3.1/System.Linq.Async.dll": { - "assemblyVersion": "5.0.0.0", - "fileVersion": "5.0.0.1" - } - } - }, - "System.Reactive/5.0.0": { - "runtime": { - "lib/net5.0/System.Reactive.dll": { - "assemblyVersion": "5.0.0.0", - "fileVersion": "5.0.0.1" - } - } - }, - "System.ValueTuple/4.5.0": {}, - "PluginManager/1.0.0": { - "dependencies": { - "Discord.Net": "3.6.1" - }, - "runtime": { - "PluginManager.dll": {} - } - } - } - }, - "libraries": { - "StartupEvents/1.0.0": { - "type": "project", - "serviceable": false, - "sha512": "" - }, - "Discord.Net/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-TfcL/HG57fVt//WVJ2XyF2PlytY9IYkkwwkPLIhvu5FW4wf9rm7+N8RPh4qtELLfsa5ES0FK2RbgYjABRR9AjA==", - "path": "discord.net/3.6.1", - "hashPath": "discord.net.3.6.1.nupkg.sha512" - }, - "Discord.Net.Commands/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-kK7m571yzSzPd93o+n8Z+TfvX62BT1HtOEZIWXKwXWO8itP/sgqBNExjWK/6DOpkbD6+khc2f3rp+TA0rJD88g==", - "path": "discord.net.commands/3.6.1", - "hashPath": "discord.net.commands.3.6.1.nupkg.sha512" - }, - "Discord.Net.Core/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-ibVjQiWzgqh0GyP/GXE2kv3TA/9ysmmNFG/WmRE7GepQQAXXGxVUO9IMJ8h14EvIXMQ0m0DktMe5DkUnilo3Ag==", - "path": "discord.net.core/3.6.1", - "hashPath": "discord.net.core.3.6.1.nupkg.sha512" - }, - "Discord.Net.Interactions/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-WGOxz6SMUu4WS5b/JdrhlwQletcplBIYqvjFBBDfnqE+uNJqcNGtAdyjLqIILfXGx8aSSSSYZSCeAUa7FZ8Yew==", - "path": "discord.net.interactions/3.6.1", - "hashPath": "discord.net.interactions.3.6.1.nupkg.sha512" - }, - "Discord.Net.Rest/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-T7RRThIS23roFEJwTL1l7aawjVyn7ZB5yH3tMge0d6TiCzzp4V4FAZ+ArTt19LHRFhPly90v8V3sWqmTMN+5Zg==", - "path": "discord.net.rest/3.6.1", - "hashPath": "discord.net.rest.3.6.1.nupkg.sha512" - }, - "Discord.Net.Webhook/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-xikKHIGAIMz0BzHkaTKb48DNpFjKW8mvJjLJSezJ1xQOu+laHNk/hav4qxVtyZz7HSI/vGTkmlq9hKVhWzpaUA==", - "path": "discord.net.webhook/3.6.1", - "hashPath": "discord.net.webhook.3.6.1.nupkg.sha512" - }, - "Discord.Net.WebSocket/3.6.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-hF22Xy7URlVEDQZ69INOgzPvFUsIDfd+r6U+1yF9HWdBn3d4THnvAAhkv1TraSx/T/MKS7g+jvk/HZ3mh5S3aw==", - "path": "discord.net.websocket/3.6.1", - "hashPath": "discord.net.websocket.3.6.1.nupkg.sha512" - }, - "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-ORj7Zh81gC69TyvmcUm9tSzytcy8AVousi+IVRAI8nLieQjOFryRusSFh7+aLk16FN9pQNqJAiMd7BTKINK0kA==", - "path": "microsoft.extensions.dependencyinjection.abstractions/5.0.0", - "hashPath": "microsoft.extensions.dependencyinjection.abstractions.5.0.0.nupkg.sha512" - }, - "Newtonsoft.Json/13.0.1": { - "type": "package", - "serviceable": true, - "sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", - "path": "newtonsoft.json/13.0.1", - "hashPath": "newtonsoft.json.13.0.1.nupkg.sha512" - }, - "System.Collections.Immutable/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g==", - "path": "system.collections.immutable/5.0.0", - "hashPath": "system.collections.immutable.5.0.0.nupkg.sha512" - }, - "System.Interactive.Async/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-QaqhQVDiULcu4vm6o89+iP329HcK44cETHOYgy/jfEjtzeFy0ZxmuM7nel9ocjnKxEM4yh1mli7hgh8Q9o+/Iw==", - "path": "system.interactive.async/5.0.0", - "hashPath": "system.interactive.async.5.0.0.nupkg.sha512" - }, - "System.Linq.Async/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-cPtIuuH8TIjVHSi2ewwReWGW1PfChPE0LxPIDlfwVcLuTM9GANFTXiMB7k3aC4sk3f0cQU25LNKzx+jZMxijqw==", - "path": "system.linq.async/5.0.0", - "hashPath": "system.linq.async.5.0.0.nupkg.sha512" - }, - "System.Reactive/5.0.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==", - "path": "system.reactive/5.0.0", - "hashPath": "system.reactive.5.0.0.nupkg.sha512" - }, - "System.ValueTuple/4.5.0": { - "type": "package", - "serviceable": true, - "sha512": "sha512-okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==", - "path": "system.valuetuple/4.5.0", - "hashPath": "system.valuetuple.4.5.0.nupkg.sha512" - }, - "PluginManager/1.0.0": { - "type": "project", - "serviceable": false, - "sha512": "" - } - } -} \ No newline at end of file diff --git a/BUILDS/net6.0/StartupEvents.dll b/BUILDS/net6.0/StartupEvents.dll deleted file mode 100644 index c289609ec6f5af27cb7480f0b36a16c567c12531..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12800 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 T_osX#?Y{!P{Mv>8bp-w!FT8p2 diff --git a/CMD_LevelingSystem/CMD_LevelingSystem.csproj b/CMD_LevelingSystem/CMD_LevelingSystem.csproj index 61313a8..5058233 100644 --- a/CMD_LevelingSystem/CMD_LevelingSystem.csproj +++ b/CMD_LevelingSystem/CMD_LevelingSystem.csproj @@ -2,16 +2,9 @@ net6.0 - - - - ..\BUILDS\ - DEBUG;TRACE - prompt - none - false - false - + enable + enable + ..\DiscordBot\bin\Debug\net6.0\Data\Plugins\Commands\LevelingSystem diff --git a/CMD_LevelingSystem/Commands/level.cs b/CMD_LevelingSystem/Commands/level.cs deleted file mode 100644 index d709e67..0000000 --- a/CMD_LevelingSystem/Commands/level.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Discord; -using Discord.Commands; -using Discord.WebSocket; - -using PluginManager.Interfaces; -using PluginManager.LanguageSystem; - -using System; - - -public class level : DBCommand -{ - public string Command => "rank"; - - public string Description => "Display your current level"; - - public string Usage => "rank"; - - public bool canUseDM => false; - - public bool canUseServer => true; - - public bool requireAdmin => false; - - public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) - { - - try - { - int cLv = Data.GetLevel(message.Author.Id); - Int64 cEXP = Data.GetExp(message.Author.Id); - Int64 rEXP = Data.GetReqEXP(message.Author.Id); - - var embed = new EmbedBuilder() - { - Title = "Leveling System", - Description = message.Author.Mention - }; - Random r = new Random(); - int _r = r.Next(0, 256); - int _g = r.Next(0, 256); - int _b = r.Next(0, 256); - embed.WithColor(new Color(_r, _g, _b)); - embed.AddField("Level", cLv); - embed.AddField("Current EXP", cEXP); - embed.AddField("Required Exp to Level up", rEXP); - embed.WithCurrentTimestamp(); - await message.Channel.SendMessageAsync(embed: embed.Build()); - } - catch - { - if (Language.ActiveLanguage != null) - await message.Channel.SendMessageAsync(Language.ActiveLanguage.LanguageWords["DB_COMMAND_RANK_NO_RANK"]); - else await message.Channel.SendMessageAsync("You are unranked now. Please type a message in chat that is not a command and try again this command"); - return; - } - - - } -} - diff --git a/CMD_LevelingSystem/Items/Leveling System/Core.cs b/CMD_LevelingSystem/Items/Leveling System/Core.cs deleted file mode 100644 index 10314f4..0000000 --- a/CMD_LevelingSystem/Items/Leveling System/Core.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading.Tasks; - -public class Core -{ - - public static Dictionary playerMessages = new Dictionary(); - - private static readonly string folder = @".\Data\Resources\LevelingSystem\"; - - public static int GetLevel(ulong id) => int.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[0].Split('=')[1]); - - - public static Int64 GetExp(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[1].Split('=')[1]); - - - public static Int64 GetReqEXP(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[2].Split('=')[1]); - public static void SaveData(ulong id, int lv, Int64 cexp, Int64 rexp) - { - Directory.CreateDirectory(folder); - File.WriteAllText(Path.Combine(folder, id.ToString() + ".data"), $"Level={lv},EXP={cexp},REXP={rexp}"); - } - private static Int64 NextLevelXP(int level) - { - return (level * level) + 2 * level + 75; - } - - public static (bool, int) MessageSent(ulong id, int messageLength) - { - WaitForTimeToRemoveFromList(id, 60); - - if (!File.Exists(Path.Combine(folder, id.ToString() + ".data"))) - { - SaveData(id, 0, 0, 0); - } - Int64 cEXp = GetExp(id); - Int64 rExp = GetReqEXP(id); - int random = new System.Random().Next(3, 6) + messageLength; - cEXp += random; - if (cEXp >= rExp) - { - cEXp = cEXp - rExp; - int lv = GetLevel(id); - rExp = NextLevelXP(lv); - lv++; - SaveData(id, lv, cEXp, rExp); - return (true, lv); - } - - SaveData(id, GetLevel(id), cEXp, rExp); - return (false, -1); - } - - public static async void WaitForTimeToRemoveFromList(ulong id, int time_seconds) - { - await Task.Delay(time_seconds * 1000); - playerMessages.Remove(id); - } - -} \ No newline at end of file diff --git a/CMD_LevelingSystem/Items/Leveling System/Data.cs b/CMD_LevelingSystem/Items/Leveling System/Data.cs deleted file mode 100644 index 44ffb76..0000000 --- a/CMD_LevelingSystem/Items/Leveling System/Data.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Discord.WebSocket; - -using System; -using System.IO; -public static class Data -{ - private static readonly string folder = @".\Data\Resources\LevelingSystem\"; - public static void registerPlayer(SocketGuildUser user) - { - ulong id = user.Id; - Directory.CreateDirectory(folder); - File.WriteAllText(Path.Combine(folder, id.ToString() + ".data"), "Level=0,EXP=0,REXP=100"); - } - - public static int GetLevel(ulong id) => int.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[0].Split('=')[1]); - - - public static Int64 GetExp(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[1].Split('=')[1]); - - - public static Int64 GetReqEXP(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[2].Split('=')[1]); - - -} diff --git a/CMD_LevelingSystem/Level.cs b/CMD_LevelingSystem/Level.cs new file mode 100644 index 0000000..85b341f --- /dev/null +++ b/CMD_LevelingSystem/Level.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Discord; +using Discord.Commands; +using Discord.WebSocket; +using PluginManager; +using PluginManager.Interfaces; +using PluginManager.Others; + +namespace CMD_LevelingSystem +{ + internal class Level : DBCommand + { + public string Command => "level"; + + public string Description => "Display tour current level"; + + public string Usage => "level"; + + public bool canUseDM => false; + + public bool canUseServer => true; + + public bool requireAdmin => false; + + public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) + { + User user = await Functions.ConvertFromJson(Config.GetValue("LevelingSystemPath") + $"/{message.Author.Id}.dat"); + if (user == null) + { + await context.Channel.SendMessageAsync("You are now unranked !"); + return; + } + + var builder = new EmbedBuilder(); + Random r = new Random(); + builder.WithColor(r.Next(256), r.Next(256), r.Next(256)); + builder.AddField("Current Level", user.CurrentLevel, true) + .AddField("Current EXP", user.CurrentEXP, true) + .AddField("Required Exp", user.RequiredEXPToLevelUp, true); + builder.WithTimestamp(DateTimeOffset.Now); + await context.Channel.SendMessageAsync(embed: builder.Build()); + } + } +} diff --git a/CMD_LevelingSystem/User.cs b/CMD_LevelingSystem/User.cs new file mode 100644 index 0000000..679a5d5 --- /dev/null +++ b/CMD_LevelingSystem/User.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CMD_LevelingSystem +{ + public class User + { + public string userID { get; set; } + public int CurrentLevel { get; set; } + public Int64 CurrentEXP { get; set; } + public Int64 RequiredEXPToLevelUp { get; set; } + } +} diff --git a/DiscordBot/Discord/Commands/Settings.cs b/DiscordBot/Discord/Commands/Settings.cs index 4b867f3..aaea6a5 100644 --- a/DiscordBot/Discord/Commands/Settings.cs +++ b/DiscordBot/Discord/Commands/Settings.cs @@ -3,12 +3,10 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; - using Discord; using Discord.Commands; using Discord.WebSocket; - -using PluginManager.Core; +using DiscordBot.Discord.Core; using PluginManager.Interfaces; using PluginManager.Others; using PluginManager.Others.Permissions; diff --git a/DiscordBot/Discord/Core/Boot.cs b/DiscordBot/Discord/Core/Boot.cs index af12058..b7a56b1 100644 --- a/DiscordBot/Discord/Core/Boot.cs +++ b/DiscordBot/Discord/Core/Boot.cs @@ -1,13 +1,14 @@ using Discord; using Discord.Commands; using Discord.WebSocket; - using System; +using System.Threading; using System.Threading.Tasks; - +using PluginManager; +using PluginManager.Others; using static PluginManager.Others.Functions; -namespace PluginManager.Core +namespace DiscordBot.Discord.Core { internal class Boot { @@ -107,6 +108,17 @@ namespace PluginManager.Core { Console.Title = "ONLINE"; isReady = true; + + new Thread(async () => + { + while (true) + { + Config.SaveDictionary(); + Thread.Sleep(10000); + } + } + ).Start(); + return Task.CompletedTask; } diff --git a/DiscordBot/Discord/Core/CommandHandler.cs b/DiscordBot/Discord/Core/CommandHandler.cs index b877f79..16ed690 100644 --- a/DiscordBot/Discord/Core/CommandHandler.cs +++ b/DiscordBot/Discord/Core/CommandHandler.cs @@ -13,7 +13,7 @@ using System.Linq; using Discord; using System; -namespace PluginManager.Core +namespace DiscordBot.Discord.Core { internal class CommandHandler { diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index 903d078..ad8ef96 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -1,15 +1,12 @@ -using Discord; -using System; -using System.IO; -using System.Threading.Tasks; -using PluginManager.Core; -using PluginManager.Others; -using PluginManager.LanguageSystem; -using PluginManager.Online; -using System.Collections.Generic; -using System.Linq; -using System.Threading; +using DiscordBot.Discord.Core; +using PluginManager; using PluginManager.Items; +using PluginManager.Others; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; namespace DiscordBot { @@ -17,8 +14,8 @@ namespace DiscordBot { private static bool loadPluginsOnStartup = false; private static bool listPluginsAtStartup = false; + private static bool listLanguagAtStartup = false; - //private static bool ShowStartupMessage = true; /// /// The main entry point for the application. @@ -31,28 +28,38 @@ namespace DiscordBot Directory.CreateDirectory("./Data/Languages"); Directory.CreateDirectory("./Data/Plugins/Commands"); Directory.CreateDirectory("./Data/Plugins/Events"); - Directory.CreateDirectory("./Data/runtime"); - - AppDomain.CurrentDomain.AppendPrivatePath("./Data/runtime"); - - if (!File.Exists("./Data/Resources/DiscordBotCore.data") || (Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN", '=').Length != 59 && Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN", '=').Length != 70)) + if (File.Exists(Functions.dataFolder + "var.dat")) + Config.LoadDictionary(); + else if (Config.GetValue("token") == null || Config.GetValue("token")?.Length != 70) { - File.WriteAllText("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN=token\nBOT_PREFIX=!\n"); + Dictionary d = new Dictionary(); while (true) { - Console.WriteLine("Please insert your token: "); - Console.Write("TOKEN: "); - string botToken = Console.ReadLine(); - if (botToken.Length == 59 || botToken.Length == 70) - { - string prefix = Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_PREFIX", '='); - if (prefix == string.Empty || prefix == null) prefix = "!"; - File.WriteAllText("./Data/Resources/DiscordBotCore.data", $"BOT_TOKEN={botToken}\nBOT_PREFIX={prefix}\n"); - break; - } + Console.WriteLine("Please insert your token"); + Console.Write("Token = "); + string token = Console.ReadLine(); + if (token?.Length == 59 || token?.Length == 70) + d.Add("token", token); else - Console.WriteLine("Invalid Token !"); + { + Console.WriteLine("Invalid token"); + continue; + } + + Console.WriteLine("Please insert your prefix (max. 1 character long):"); + Console.WriteLine("For a prefix longer then one character, the first character will be saved and the others will be ignored. No spaces or numbers allowed"); + Console.Write("Prefix = "); + char prefix = Console.ReadLine()[0]; + + if (prefix == ' ' || char.IsDigit(prefix)) continue; + + d.Add("prefix", prefix.ToString()); + + break; } + + Config.AppendToDictionary(d); + d.Clear(); } HandleInput(args).Wait(); @@ -61,11 +68,10 @@ namespace DiscordBot /// /// Reset all settings for the bot /// - private static Task ResetSettings() + private static async Task ResetSettings() { string[] files = Directory.GetFiles(@"./Data/Resources"); foreach (string file in files) File.Delete(file); - return Task.CompletedTask; } /// @@ -74,13 +80,11 @@ namespace DiscordBot /// The discord booter used to start the application private static Task NoGUI(Boot discordbooter) { - Language.LoadLanguage(); - ConsoleCommandsHandler consoleCommandsHandler = new ConsoleCommandsHandler(discordbooter.client); if (loadPluginsOnStartup) consoleCommandsHandler.HandleCommand("lp"); if (listPluginsAtStartup) consoleCommandsHandler.HandleCommand("listplugs"); if (listLanguagAtStartup) consoleCommandsHandler.HandleCommand("listlang"); - + Config.SaveDictionary(); while (true) { Console.ForegroundColor = ConsoleColor.White; @@ -102,8 +106,8 @@ namespace DiscordBot Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("============================ Discord BOT - Cross Platform ============================"); - string token = Functions.readCodeFromFile(Functions.dataFolder + "DiscordBotCore.data", "BOT_TOKEN", '='); - string prefix = Functions.readCodeFromFile(Functions.dataFolder + "DiscordBotCore.data", "BOT_PREFIX", '='); + string token = Config.GetValue("token"); + string prefix = Config.GetValue("prefix"); var discordbooter = new Boot(token, prefix); await discordbooter.Awake(); @@ -133,15 +137,6 @@ namespace DiscordBot /// The arguments private static async Task HandleInput(string[] args) { - if (args.Length == 0) - { - if (File.Exists("./ref/startupArguments.txt")) - { - var lines = await File.ReadAllLinesAsync("./ref/startupArguments.txt"); - args = lines; - } - } - int len = args.Length; if (len == 1 && args[0] == "--help") { @@ -151,12 +146,13 @@ namespace DiscordBot if (len == 1 && args[0] == "--logout") { - File.Delete(Functions.dataFolder + "DiscordBotCore.dat"); + File.Delete(Functions.dataFolder + "var.dat"); await Task.Run(async () => - { - await Task.Delay(1000); - Environment.Exit(0x08); - }); + { + await Task.Delay(1000); + Environment.Exit(0x08); + } + ); return; } @@ -226,7 +222,6 @@ namespace DiscordBot await ClearFolder("./Output/Logs/"); await ClearFolder("./Output/Errors"); await ClearFolder("./Data/Languages/"); - await ClearFolder("./Data/Plugins/Addons"); await ClearFolder("./Data/Plugins/Commands"); await ClearFolder("./Data/Plugins/Events"); Console.WriteLine("Successfully cleared all folders"); diff --git a/DiscordBotGUI/AppUpdater.axaml.cs b/DiscordBotGUI/AppUpdater.axaml.cs index 785e1d4..f6eaf5c 100644 --- a/DiscordBotGUI/AppUpdater.axaml.cs +++ b/DiscordBotGUI/AppUpdater.axaml.cs @@ -7,8 +7,6 @@ using System.Threading.Tasks; using System; using System.IO; using System.Threading; -using System.Drawing; -using Avalonia.Media; namespace DiscordBotGUI { diff --git a/DiscordBotGUI/MainWindow.axaml.cs b/DiscordBotGUI/MainWindow.axaml.cs index 00490b6..081a81e 100644 --- a/DiscordBotGUI/MainWindow.axaml.cs +++ b/DiscordBotGUI/MainWindow.axaml.cs @@ -1,13 +1,12 @@ using Avalonia.Controls; - using System.Threading.Tasks; - using PluginManager.Others; using System.IO; using System; using System.Diagnostics; using DiscordBotGUI.Settings; using Avalonia.Themes.Fluent; +using PluginManager; namespace DiscordBotGUI { @@ -27,8 +26,7 @@ namespace DiscordBotGUI textBox3.Watermark = "Insert start arguments"; - if (File.Exists("./Version.txt")) - label5.Content = Functions.readCodeFromFile("./Version.txt", "DiscordBotVersion", '='); + if (File.Exists("./Version.txt")) label5.Content = Config.ApplicationVariables["Version"] as string; button1.Click += async (sender, e) => { @@ -58,8 +56,8 @@ namespace DiscordBotGUI Directory.CreateDirectory(Functions.dataFolder); try { - string? botToken = Functions.readCodeFromFile(folder, "BOT_TOKEN", '='); - string? botPrefix = Functions.readCodeFromFile(folder, "BOT_PREFIX", '='); + string? botToken = Config.ApplicationVariables["token"] as string; + string? botPrefix = Config.ApplicationVariables["prefix"] as string; if (botToken == null || botPrefix == null) { textBox1.IsReadOnly = false; diff --git a/DiscordBotWithAPI.sln b/DiscordBotWithAPI.sln index 7bf0ffe..d88b05a 100644 --- a/DiscordBotWithAPI.sln +++ b/DiscordBotWithAPI.sln @@ -13,17 +13,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Events", "Events", "{A290C0 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Commands", "Commands", "{449FA364-0B72-43FF-B3A3-806E2916200E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CMD_LevelingSystem", "CMD_LevelingSystem\CMD_LevelingSystem.csproj", "{A48E8DC6-DBA2-4B47-9D59-46F4835F82CC}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EVE_LevelingSystem", "EVE_LevelingSystem\EVE_LevelingSystem.csproj", "{1C1E7F3D-E05A-4A87-9789-62D98904C200}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StartupEvents", "StartupEvents\StartupEvents.csproj", "{CE9DBF06-38A0-4192-8B3E-4009210D040D}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CMD_Utils", "CMD_Utils\CMD_Utils.csproj", "{E26C87A4-3DD6-4B58-B14B-C8E086B852F9}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MusicCommands", "MusicCommands\MusicCommands.csproj", "{B1B4976E-5112-4217-B57B-3A03C5207B6E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordBotGUI", "DiscordBotGUI\DiscordBotGUI.csproj", "{7B5899F0-0218-4537-8C74-6210ED2D3690}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DiscordBotGUI", "DiscordBotGUI\DiscordBotGUI.csproj", "{7B5899F0-0218-4537-8C74-6210ED2D3690}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EVE_LevelingSystem", "EVE_LevelingSystem\EVE_LevelingSystem.csproj", "{EEC445DC-0C4B-43EA-8694-606BA0390B77}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CMD_LevelingSystem", "CMD_LevelingSystem\CMD_LevelingSystem.csproj", "{1A4E49FF-9A0A-4C54-AF35-CFFBA64353D9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -39,18 +37,6 @@ Global {EDD4D9B3-98DD-4367-A09F-D1C5ACB61132}.Debug|Any CPU.Build.0 = Debug|Any CPU {EDD4D9B3-98DD-4367-A09F-D1C5ACB61132}.Release|Any CPU.ActiveCfg = Release|Any CPU {EDD4D9B3-98DD-4367-A09F-D1C5ACB61132}.Release|Any CPU.Build.0 = Release|Any CPU - {A48E8DC6-DBA2-4B47-9D59-46F4835F82CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A48E8DC6-DBA2-4B47-9D59-46F4835F82CC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A48E8DC6-DBA2-4B47-9D59-46F4835F82CC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A48E8DC6-DBA2-4B47-9D59-46F4835F82CC}.Release|Any CPU.Build.0 = Release|Any CPU - {1C1E7F3D-E05A-4A87-9789-62D98904C200}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1C1E7F3D-E05A-4A87-9789-62D98904C200}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1C1E7F3D-E05A-4A87-9789-62D98904C200}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1C1E7F3D-E05A-4A87-9789-62D98904C200}.Release|Any CPU.Build.0 = Release|Any CPU - {CE9DBF06-38A0-4192-8B3E-4009210D040D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CE9DBF06-38A0-4192-8B3E-4009210D040D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CE9DBF06-38A0-4192-8B3E-4009210D040D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CE9DBF06-38A0-4192-8B3E-4009210D040D}.Release|Any CPU.Build.0 = Release|Any CPU {E26C87A4-3DD6-4B58-B14B-C8E086B852F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E26C87A4-3DD6-4B58-B14B-C8E086B852F9}.Debug|Any CPU.Build.0 = Debug|Any CPU {E26C87A4-3DD6-4B58-B14B-C8E086B852F9}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -63,6 +49,14 @@ Global {7B5899F0-0218-4537-8C74-6210ED2D3690}.Debug|Any CPU.Build.0 = Debug|Any CPU {7B5899F0-0218-4537-8C74-6210ED2D3690}.Release|Any CPU.ActiveCfg = Release|Any CPU {7B5899F0-0218-4537-8C74-6210ED2D3690}.Release|Any CPU.Build.0 = Release|Any CPU + {EEC445DC-0C4B-43EA-8694-606BA0390B77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EEC445DC-0C4B-43EA-8694-606BA0390B77}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EEC445DC-0C4B-43EA-8694-606BA0390B77}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EEC445DC-0C4B-43EA-8694-606BA0390B77}.Release|Any CPU.Build.0 = Release|Any CPU + {1A4E49FF-9A0A-4C54-AF35-CFFBA64353D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1A4E49FF-9A0A-4C54-AF35-CFFBA64353D9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1A4E49FF-9A0A-4C54-AF35-CFFBA64353D9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1A4E49FF-9A0A-4C54-AF35-CFFBA64353D9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -70,11 +64,10 @@ Global GlobalSection(NestedProjects) = preSolution {A290C028-77C4-4D1D-AB43-DDFE6ABD9012} = {1862ABD5-7C30-4F15-A561-45AC8A9CA10E} {449FA364-0B72-43FF-B3A3-806E2916200E} = {1862ABD5-7C30-4F15-A561-45AC8A9CA10E} - {A48E8DC6-DBA2-4B47-9D59-46F4835F82CC} = {449FA364-0B72-43FF-B3A3-806E2916200E} - {1C1E7F3D-E05A-4A87-9789-62D98904C200} = {A290C028-77C4-4D1D-AB43-DDFE6ABD9012} - {CE9DBF06-38A0-4192-8B3E-4009210D040D} = {A290C028-77C4-4D1D-AB43-DDFE6ABD9012} {E26C87A4-3DD6-4B58-B14B-C8E086B852F9} = {449FA364-0B72-43FF-B3A3-806E2916200E} {B1B4976E-5112-4217-B57B-3A03C5207B6E} = {449FA364-0B72-43FF-B3A3-806E2916200E} + {EEC445DC-0C4B-43EA-8694-606BA0390B77} = {A290C028-77C4-4D1D-AB43-DDFE6ABD9012} + {1A4E49FF-9A0A-4C54-AF35-CFFBA64353D9} = {449FA364-0B72-43FF-B3A3-806E2916200E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3FB3C5DE-ED21-4D2E-ABDD-3A00EE4A2FFF} diff --git a/EVE_LevelingSystem/Core.cs b/EVE_LevelingSystem/Core.cs deleted file mode 100644 index 10314f4..0000000 --- a/EVE_LevelingSystem/Core.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading.Tasks; - -public class Core -{ - - public static Dictionary playerMessages = new Dictionary(); - - private static readonly string folder = @".\Data\Resources\LevelingSystem\"; - - public static int GetLevel(ulong id) => int.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[0].Split('=')[1]); - - - public static Int64 GetExp(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[1].Split('=')[1]); - - - public static Int64 GetReqEXP(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[2].Split('=')[1]); - public static void SaveData(ulong id, int lv, Int64 cexp, Int64 rexp) - { - Directory.CreateDirectory(folder); - File.WriteAllText(Path.Combine(folder, id.ToString() + ".data"), $"Level={lv},EXP={cexp},REXP={rexp}"); - } - private static Int64 NextLevelXP(int level) - { - return (level * level) + 2 * level + 75; - } - - public static (bool, int) MessageSent(ulong id, int messageLength) - { - WaitForTimeToRemoveFromList(id, 60); - - if (!File.Exists(Path.Combine(folder, id.ToString() + ".data"))) - { - SaveData(id, 0, 0, 0); - } - Int64 cEXp = GetExp(id); - Int64 rExp = GetReqEXP(id); - int random = new System.Random().Next(3, 6) + messageLength; - cEXp += random; - if (cEXp >= rExp) - { - cEXp = cEXp - rExp; - int lv = GetLevel(id); - rExp = NextLevelXP(lv); - lv++; - SaveData(id, lv, cEXp, rExp); - return (true, lv); - } - - SaveData(id, GetLevel(id), cEXp, rExp); - return (false, -1); - } - - public static async void WaitForTimeToRemoveFromList(ulong id, int time_seconds) - { - await Task.Delay(time_seconds * 1000); - playerMessages.Remove(id); - } - -} \ No newline at end of file diff --git a/EVE_LevelingSystem/Data.cs b/EVE_LevelingSystem/Data.cs deleted file mode 100644 index 44ffb76..0000000 --- a/EVE_LevelingSystem/Data.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Discord.WebSocket; - -using System; -using System.IO; -public static class Data -{ - private static readonly string folder = @".\Data\Resources\LevelingSystem\"; - public static void registerPlayer(SocketGuildUser user) - { - ulong id = user.Id; - Directory.CreateDirectory(folder); - File.WriteAllText(Path.Combine(folder, id.ToString() + ".data"), "Level=0,EXP=0,REXP=100"); - } - - public static int GetLevel(ulong id) => int.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[0].Split('=')[1]); - - - public static Int64 GetExp(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[1].Split('=')[1]); - - - public static Int64 GetReqEXP(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[2].Split('=')[1]); - - -} diff --git a/EVE_LevelingSystem/EVE_LevelingSystem.csproj b/EVE_LevelingSystem/EVE_LevelingSystem.csproj index 0f762e8..ce1a63c 100644 --- a/EVE_LevelingSystem/EVE_LevelingSystem.csproj +++ b/EVE_LevelingSystem/EVE_LevelingSystem.csproj @@ -1,17 +1,20 @@ - + - - net6.0 - + + net6.0 + enable + enable + ..\DiscordBot\bin\Debug\net6.0\Data\Plugins\Events\LevelingSystem + - - ..\BUILDS\ - none - false - + + + + + - - - + + + diff --git a/EVE_LevelingSystem/Level.cs b/EVE_LevelingSystem/Level.cs new file mode 100644 index 0000000..2d9b6bd --- /dev/null +++ b/EVE_LevelingSystem/Level.cs @@ -0,0 +1,42 @@ +using Discord.WebSocket; +using EVE_LevelingSystem.LevelingSystemCore; +using PluginManager; +using PluginManager.Interfaces; +using PluginManager.Others; + +namespace EVE_LevelingSystem +{ + internal class Level : DBEvent + { + public string name => "Leveling System Event Handler"; + public string description => "The Leveling System Event Handler"; + + + public void Start(DiscordSocketClient client) + { + Directory.CreateDirectory("./Data/Resources/LevelingSystem"); + Config.AddValueToVariables("LevelingSystemPath", "./Data/Resources/LevelingSystem"); + + client.MessageReceived += ClientOnMessageReceived; + } + + private async Task ClientOnMessageReceived(SocketMessage arg) + { + if (arg.Author.IsBot || arg.IsTTS || arg.Content.StartsWith(Config.GetValue("prefix"))) return; + string userID = arg.Author.Id.ToString(); + User user; + if (File.Exists($"{Config.GetValue("LevelingSystemPath")}/{userID}.dat")) + { + user = await Functions.ConvertFromJson(Config.GetValue("LevelingSystemPath")! + $"/{userID}.dat"); + Console.WriteLine(Config.GetValue("LevelingSystemPath")); + if (user.AddEXP()) await arg.Channel.SendMessageAsync($"{arg.Author.Mention} is now level {user.CurrentLevel}"); + await Functions.SaveToJsonFile(Config.GetValue("LevelingSystemPath") + $"/{userID}.dat", user); + return; + } + + user = new User() { CurrentEXP = 0, CurrentLevel = 1, RequiredEXPToLevelUp = LevelCalculator.GetNextLevelRequiredEXP(1), userID = userID }; + if (user.AddEXP()) await arg.Channel.SendMessageAsync($"{arg.Author.Mention} is now level {user.CurrentLevel}"); + await Functions.SaveToJsonFile($"{Config.GetValue("LevelingSystemPath")}/{userID}.dat", user); + } + } +} diff --git a/EVE_LevelingSystem/LevelingSystem.cs b/EVE_LevelingSystem/LevelingSystem.cs deleted file mode 100644 index 674da2a..0000000 --- a/EVE_LevelingSystem/LevelingSystem.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Threading.Tasks; - -using Discord.WebSocket; - -using PluginManager.Others; -using PluginManager.Interfaces; -using PluginManager.LanguageSystem; -using PluginManager.Items; -using System; - -public class LevelingSystem : DBEvent -{ - public string name => "Leveling System"; - - public string description => "Leveling System Event"; - - public void Start(DiscordSocketClient client) - { - - ConsoleCommandsHandler.AddCommand("lvl", "Test command", async (args) => - { - Console.WriteLine("Leveling system command"); - - }); - - client.MessageReceived += Client_MessageReceived; - } - - private async Task Client_MessageReceived(SocketMessage arg) - { - if (arg.Author.IsBot || arg.Attachments.Count > 0 || - arg.Content.StartsWith - ( - Functions.readCodeFromFile - ( - fileName: System.IO.Path.Combine(Functions.dataFolder, "DiscordBotCore.data"), - Code: "BOT_PREFIX", - separator: '=' - ) - ) - ) - return; - //Console_Utilities.WriteColorText("Message from : " + arg.Author.Username); - if (Core.playerMessages.ContainsKey(arg.Author.Id)) - return; - - (bool x, int lv) = Core.MessageSent(arg.Author.Id, arg.Content.Length); - Core.playerMessages.Add(arg.Author.Id, arg.Content); - if (x) - if (Language.ActiveLanguage != null) - await arg.Channel.SendMessageAsync(Language.ActiveLanguage.LanguageWords["DB_EVENT_LEVEL_SYSTEM_LEVEL_UP"].Replace("{0}", lv.ToString())); - else await arg.Channel.SendMessageAsync("You've successfully leveled up to level " + lv); - - } -} - diff --git a/EVE_LevelingSystem/LevelingSystemCore/LevelCalculator.cs b/EVE_LevelingSystem/LevelingSystemCore/LevelCalculator.cs new file mode 100644 index 0000000..9df66dc --- /dev/null +++ b/EVE_LevelingSystem/LevelingSystemCore/LevelCalculator.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EVE_LevelingSystem.LevelingSystemCore +{ + internal static class LevelCalculator + { + internal static List OnWaitingList = new(); + + internal static Int64 GetNextLevelRequiredEXP(int currentLevel) + { + return currentLevel * 8 + 24; + } + + internal static void LevelUp(this User user) + { + user.CurrentEXP = 0; + user.RequiredEXPToLevelUp = GetNextLevelRequiredEXP(user.CurrentLevel); + user.CurrentLevel++; + } + + internal static bool AddEXP(this User user) + { + if (OnWaitingList.Contains(user.userID)) return false; + Random r = new Random(); + int exp = r.Next(2, 12); + Int64 userXP = user.CurrentEXP; + Int64 reqEXP = user.RequiredEXPToLevelUp; + if (userXP + exp >= reqEXP) + { + user.LevelUp(); + user.CurrentEXP = exp - (reqEXP - userXP); + Console.WriteLine("Level up"); + return true; + } + + user.CurrentEXP += exp; + + OnWaitingList.Add(user.userID); + + + new Thread(() => + { + int minutesToWait = 0; + Thread.Sleep(60000 * minutesToWait); + OnWaitingList.Remove(user.userID); + } + ); + + return false; + } + } +} diff --git a/EVE_LevelingSystem/LevelingSystemCore/User.cs b/EVE_LevelingSystem/LevelingSystemCore/User.cs new file mode 100644 index 0000000..0ccb094 --- /dev/null +++ b/EVE_LevelingSystem/LevelingSystemCore/User.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EVE_LevelingSystem.LevelingSystemCore +{ + public class User + { + public string userID { get; set; } + public int CurrentLevel { get; set; } + public Int64 CurrentEXP { get; set; } + public Int64 RequiredEXPToLevelUp { get; set; } + } +} diff --git a/FreeGames/Game.cs b/FreeGames/Game.cs deleted file mode 100644 index 7080383..0000000 --- a/FreeGames/Game.cs +++ /dev/null @@ -1,32 +0,0 @@ -using PluginManager.Interfaces; -using PluginManager.Items; -using Games.Objects; -using PluginManager.Others; - -namespace Games; - -public class Game : DBCommand -{ - public string Command => "game"; - public string Description => "Display info about the specified game"; - public string Usage => "game "; - - public bool canUseDM => false; - public bool canUseServer => true; - public bool requireAdmin => false; - - public async void Execute(Discord.Commands.SocketCommandContext context, Discord.WebSocket.SocketMessage message, - Discord.WebSocket.DiscordSocketClient client, bool isDM) - { - - string game_name = Functions.MergeStrings(message.Content.Split(' '), 1); - string game_url = await GameData.GetSteamLinkFromGame(game_name); - if (game_url is null || game_url == null) - { - await message.Channel.SendMessageAsync("Could not find the game. Try to be more specific or check for spelling errors."); - return; - } - await context.Channel.SendMessageAsync(game_url); - } - -} diff --git a/FreeGames/Games.csproj b/FreeGames/Games.csproj deleted file mode 100644 index 7afa3af..0000000 --- a/FreeGames/Games.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - net6.0 - enable - enable - - - - - - - - - - - - - diff --git a/FreeGames/Objects/GameData.cs b/FreeGames/Objects/GameData.cs deleted file mode 100644 index 1156127..0000000 --- a/FreeGames/Objects/GameData.cs +++ /dev/null @@ -1,24 +0,0 @@ -using PluginManager.Online; -namespace Games.Objects; - -public class GameData -{ - internal async static Task GetSteamLinkFromGame(string GameName) - { - string URL = $"https://store.steampowered.com/search?term={GameName.Replace(" ", "+")}"; - List lines = await ServerCom.ReadTextFromFile(URL); - - string? gameData = ( - from s in lines - where s.Contains(GameName.Replace(" ", "_"), StringComparison.OrdinalIgnoreCase) - select s).FirstOrDefault(); - if (gameData is null) return null; - string GameURL = gameData.Split('\"')[1].Split('?')[0]; - - if (GameURL == "menuitem") - return null; - - return GameURL; - - } -} diff --git a/PluginManager/Config.cs b/PluginManager/Config.cs new file mode 100644 index 0000000..3dac456 --- /dev/null +++ b/PluginManager/Config.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using PluginManager.Others; + +namespace PluginManager +{ + public static class Config + { + private static readonly Dictionary ApplicationVariables = new(); + private static readonly List ConstantTokens = new() { "token" }; + + public static void AppendToDictionary(Dictionary dictionary) + { + foreach (var kvp in dictionary) ApplicationVariables.TryAdd(kvp.Key, kvp.Value); + } + + public static bool AddValueToVariables(string key, string value, bool constant) + { + bool req = AddValueToVariables(key, value); + if (constant) ConstantTokens.Add(key); + + return req; + } + + public static bool AddValueToVariables(string key, string value) + { + if (ApplicationVariables.ContainsKey(key)) + { + return false; + } + + ApplicationVariables.Add(key, value); + return true; + } + + public static string? GetValue(string key) + { + if (!ApplicationVariables.ContainsKey(key)) + { + if (key != "token") Console.WriteLine("The key is not present in the dictionary"); + return null; + } + + return ApplicationVariables[key]; + } + + public static bool SetValue(string key, string value) + { + if (!ApplicationVariables.ContainsKey(key)) return false; + + if (ConstantTokens.Contains(key)) return false; + ApplicationVariables[key] = value; + return true; + } + + public static bool RemoveKey(string key) + { + if (ConstantTokens.Contains(key)) return false; + + + ApplicationVariables.Remove(key); + return true; + } + + public static async void SaveDictionary() + { + string path = Functions.dataFolder + "var.dat"; + await Functions.SaveToJsonFile(path, ApplicationVariables); + } + + public static async void LoadDictionary() + { + string path = Functions.dataFolder + "var.dat"; + var d = await Functions.ConvertFromJson>(path); + ApplicationVariables.Clear(); + AppendToDictionary(d); + } + + public static string GetKey(string value) => ApplicationVariables.Keys.FirstOrDefault(x => ApplicationVariables[x] == value); + public static bool ContainsValue(string value) => ApplicationVariables.ContainsValue(value); + public static bool ContainsKey(string key) => ApplicationVariables.ContainsKey(key); + } +} diff --git a/PluginManager/Items/ConsoleCommandsHandler.cs b/PluginManager/Items/ConsoleCommandsHandler.cs index 30a8c7a..95841b8 100644 --- a/PluginManager/Items/ConsoleCommandsHandler.cs +++ b/PluginManager/Items/ConsoleCommandsHandler.cs @@ -1,16 +1,12 @@ using Discord.WebSocket; - using PluginManager.Loaders; using PluginManager.Online; using PluginManager.Others; - - using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; using System.Threading; -using PluginManager.LanguageSystem; using System.Linq; using System.Reflection.Metadata.Ecma335; @@ -18,13 +14,10 @@ namespace PluginManager.Items { public class ConsoleCommandsHandler { - - private static PluginsManager manager = new PluginsManager("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Plugins"); - private static LanguageManager languageManager = new LanguageManager("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Languages"); - + private static PluginsManager manager = new("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Plugins"); public static List>>? commandList = new List>>(); - private DiscordSocketClient client; + private DiscordSocketClient client; public ConsoleCommandsHandler(DiscordSocketClient client) { @@ -73,14 +66,9 @@ namespace PluginManager.Items if (name == null || name.Length < 2) name = typeName; if (success) - if (LanguageSystem.Language.ActiveLanguage == null) - Console.WriteLine("[CMD] Successfully loaded command : " + name); - else Console.WriteLine(LanguageSystem.Language.ActiveLanguage.FormatText(LanguageSystem.Language.ActiveLanguage.LanguageWords["COMMAND_LOAD_SUCCESS"], name)); + Console.WriteLine("[CMD] Successfully loaded command : " + name); else - if (LanguageSystem.Language.ActiveLanguage == null) Console.WriteLine("[CMD] Failed to load command : " + name + " because " + exception.Message); - else - Console.WriteLine(LanguageSystem.Language.ActiveLanguage.FormatText(LanguageSystem.Language.ActiveLanguage.LanguageWords["COMMAND_LOAD_FAIL"], name, exception.Message)); Console.ForegroundColor = ConsoleColor.Red; }; loader.onEVELoad += (name, typeName, success, exception) => @@ -89,15 +77,9 @@ namespace PluginManager.Items name = typeName; Console.ForegroundColor = ConsoleColor.Green; if (success) - if (LanguageSystem.Language.ActiveLanguage == null) - Console.WriteLine("[EVENT] Successfully loaded event : " + name); - else - Console.WriteLine(LanguageSystem.Language.ActiveLanguage.FormatText(LanguageSystem.Language.ActiveLanguage.LanguageWords["EVENT_LOAD_SUCCESS"], name)); + Console.WriteLine("[EVENT] Successfully loaded event : " + name); else - if (LanguageSystem.Language.ActiveLanguage == null) Console.WriteLine("[EVENT] Failed to load event : " + name + " because " + exception.Message); - else - Console.WriteLine(LanguageSystem.Language.ActiveLanguage.FormatText(LanguageSystem.Language.ActiveLanguage.LanguageWords["EVENT_LOAD_FAIL"], name, exception.Message)); Console.ForegroundColor = ConsoleColor.Red; }; loader.LoadPlugins(); @@ -205,75 +187,47 @@ namespace PluginManager.Items }); - AddCommand("setlang", "set language", (args) => - { - if (args.Length == 1) + + AddCommand("value", "read value from VariableStack", (args) => { - Console.WriteLine("Please specify language"); - return; + if (args.Length != 2) return; + if (!Config.ContainsKey(args[1])) return; + + string data = Config.GetValue(args[1]); + Console.WriteLine($"{args[1]} => {data}"); } - Language.SetLanguage(args[0]); - }); + ); - AddCommand("listlang", "List all available languages", async () => - { - await languageManager.ListAllLanguages(); - }); - - AddCommand("dwlang", "Download language", async (args) => - { - if (args.Length == 1) + AddCommand("addv", "add variable to the system variables", async (args) => { - Console.WriteLine("Please specify language"); - return; + if (args.Length < 3) return; + string in1 = args[1]; + if (!Config.ContainsKey(in1)) + Config.AddValueToVariables(in1, Functions.MergeStrings(args, 2)); + else + Config.SetValue(in1, Functions.MergeStrings(args, 2)); + + Console.WriteLine($"Updated config file with the following command: {in1} => {Config.GetValue(in1)}"); + Config.SaveDictionary(); } - string Lname = args.MergeStrings(1); - string[] link = await languageManager!.GetDownloadLink(Lname); - try + ); + + AddCommand("remv", "remove variable from system variables", (args) => { - if (link[0] is null || link is null) - { - if (Lname == "") - { - Console_Utilities.WriteColorText($"Name is invalid"); - return; - } - Console_Utilities.WriteColorText("Failed to find language &b" + Lname + " &c! Use &glistlang &ccommand to display all available languages !"); - return; - } - if (link[1].Contains("CrossPlatform") || link[1].Contains("cp")) - { - - string path2 = Functions.langFolder + Lname + ".lng"; - - await ServerCom.DownloadFileAsync(link[0], path2); - Console.WriteLine("\n"); - } - else Console_Utilities.WriteColorText("The language you are trying to download (&b" + Lname + "&c) is not compatible with the version of this bot. User &glistlang &ccommand in order to see all available languages for your current version !\n" + link[1]); - return; + if (args.Length < 2) return; + Config.RemoveKey(args[1]); + Config.SaveDictionary(); } - catch + ); + + AddCommand("sd", "Shuts down the discord bot", async () => { - if (Lname == "") - { - Console_Utilities.WriteColorText($"Name is invalid"); - return; - } - Console_Utilities.WriteColorText("Failed to find language &b" + Lname + " &c! Use &glistlang &ccommand to display all available languages !"); - return; + await client.StopAsync(); + await client.DisposeAsync(); + Config.SaveDictionary(); + Environment.Exit(0); } - }); - - - AddCommand("token", "Display the token used by the bot", () => - { - if (System.IO.File.Exists("./Data/Resources/DiscordBotCore.data")) - Console.WriteLine("Token: " + Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN", '=')); - else Console.WriteLine("File could not be found. Please register token"); - }); - - - + ); } public static void AddCommand(string command, string description, Action action) @@ -286,8 +240,6 @@ namespace PluginManager.Items public static void AddCommand(string command, string description, Action action) { AddCommand(command, description, (args) => action()); - - /* Console.WriteLine("Added command: " + command);*/ } public static void RemoveCommand(string command) diff --git a/PluginManager/Language System/Language.cs b/PluginManager/Language System/Language.cs deleted file mode 100644 index 732c4ae..0000000 --- a/PluginManager/Language System/Language.cs +++ /dev/null @@ -1,161 +0,0 @@ -using PluginManager.Others; -using System.Collections.Generic; - -using System; -using System.IO; -using System.Threading.Tasks; - -namespace PluginManager.LanguageSystem -{ - public class Language - { - /// - /// The active language - /// - public static Language? ActiveLanguage = null; - - private static readonly string LanguageFileExtension = ".lng"; - - /// - /// The name of the language - /// - public string LanguageName { get; } - - /// - /// The file where the language is imported from - /// - public string fileName { get; } - - /// - /// The dictionary of the language - /// - public Dictionary LanguageWords { get; } - - /// - /// The Language constructor - /// - /// The file to import the language from - /// The dictionary of the language - /// The name of the language - private Language(string fileName, Dictionary words, string LanguageName) - { - this.fileName = fileName; - this.LanguageName = LanguageName; - LanguageWords = words; - } - - /// - /// Load language from file - /// - /// The file path - /// - public static Language? CreateLanguageFromFile(string LanguageFileLocation) - { - if (!LanguageFileLocation.EndsWith(LanguageFileExtension)) - { - Console.WriteLine("Failed to load language from file: " + LanguageFileLocation + - "\nFile extension is not " + LanguageFileExtension); - return null; - } - - string[] lines = File.ReadAllLines(LanguageFileLocation); - var languageName = "Unknown"; - var words = new Dictionary(); - - foreach (string line in lines) - { - if (line.StartsWith("#") || line.Length < 4) - continue; - string[] sLine = line.Split('='); - - if (sLine[0] == "LANGUAGE_NAME") - { - languageName = sLine[1]; - continue; - } - - words.Add(sLine[0], sLine[1]); - } - - Functions.WriteLogFile("Successfully loaded language: " + languageName + " from file : " + - LanguageFileLocation.Replace('\\', '/')); - return new Language(LanguageFileLocation, words, languageName); - } - - /// - /// Format text by inserting parameters - /// - /// The raw text - /// The arguments - /// - public string FormatText(string text, params string[] args) - { - if (ActiveLanguage == null) return text; - int l = args.Length; - for (var i = 0; i < l; i++) text = text.Replace($"{i}", args[i]); - return text; - } - - - public static bool LoadLanguage() - { - string folder = Functions.langFolder; - string langSettings = "./Data/Resources/Language.txt"; - if (!File.Exists(langSettings)) - File.WriteAllText(langSettings, "Language=English"); - //Load language from the specified file ... - Language.ActiveLanguage = null; - - string langname = Functions.readCodeFromFile(langSettings, "Language", '='); - if (langname == "English") - { - Language.ActiveLanguage = null; - return true; - } - foreach (var file in Directory.GetFiles(folder)) - { - if (Functions.readCodeFromFile(file, "LANGUAGE_NAME", '=') == langname) - { - Language.ActiveLanguage = Language.CreateLanguageFromFile(file); - - return true; - } - } - - if (Language.ActiveLanguage == null) - { - File.WriteAllText(langSettings, "Language=English"); - Console_Utilities.WriteColorText($"Failed to find language &r{langname} &c! Check available languages using command: &glistlang"); - - return false; - } - - return false; - } - - public static void SetLanguage(string LanguageName) - { - string langSettings = Functions.dataFolder + "Language.txt"; - File.WriteAllText(langSettings, "Language=" + LanguageName); - - try - { - bool success = LoadLanguage(); - if (success) - { - Console_Utilities.WriteColorText($"Language has been setted to: &g{LanguageName}"); - return; - } - } - catch (Exception ex) - { - Console_Utilities.WriteColorText($"Could not find language &r{LanguageName}."); - Functions.WriteErrFile(ex.ToString()); - File.WriteAllText(langSettings, "Language=English"); - LoadLanguage(); - } - } - - - } -} \ No newline at end of file diff --git a/PluginManager/Loaders/Loader.cs b/PluginManager/Loaders/Loader.cs index 955bc9f..1b80c5d 100644 --- a/PluginManager/Loaders/Loader.cs +++ b/PluginManager/Loaders/Loader.cs @@ -41,7 +41,7 @@ namespace PluginManager.Loaders internal List? Load() { - List list = new List(); + List list = new List(); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); @@ -54,7 +54,14 @@ namespace PluginManager.Loaders Assembly.LoadFrom(file); if (FileLoaded != null) { - LoaderArgs args = new LoaderArgs() { Exception = null, TypeName = nameof(T), IsLoaded = false, PluginName = file, Plugin = null }; + LoaderArgs args = new LoaderArgs() + { + Exception = null, + TypeName = nameof(T), + IsLoaded = false, + PluginName = file, + Plugin = null + }; FileLoaded.Invoke(args); } } @@ -63,9 +70,9 @@ namespace PluginManager.Loaders { Type interfaceType = typeof(T); Type[] types = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(a => a.GetTypes()) - .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) - .ToArray(); + .SelectMany(a => a.GetTypes()) + .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) + .ToArray(); list.Clear(); @@ -77,15 +84,32 @@ namespace PluginManager.Loaders list.Add(plugin); - if (PluginLoaded != null) { PluginLoaded.Invoke(new() { Exception = null, IsLoaded = true, PluginName = type.FullName, TypeName = nameof(T), Plugin = plugin }); } + if (PluginLoaded != null) + { + PluginLoaded.Invoke(new() + { + Exception = null, + IsLoaded = true, + PluginName = type.FullName, + TypeName = nameof(T), + Plugin = plugin + } + ); + } } catch (Exception ex) { - if (PluginLoaded != null) { PluginLoaded.Invoke(new() { Exception = ex, IsLoaded = false, PluginName = type.FullName, TypeName = nameof(T) }); } + if (PluginLoaded != null) + { + PluginLoaded.Invoke(new() { Exception = ex, IsLoaded = false, PluginName = type.FullName, TypeName = nameof(T) }); + } } } } - catch (Exception ex) { Functions.WriteErrFile(ex.ToString()); } + catch (Exception ex) + { + Functions.WriteErrFile(ex.ToString()); + } return list; diff --git a/PluginManager/Loaders/PluginLoader.cs b/PluginManager/Loaders/PluginLoader.cs index 813ba1b..1236ddb 100644 --- a/PluginManager/Loaders/PluginLoader.cs +++ b/PluginManager/Loaders/PluginLoader.cs @@ -57,13 +57,7 @@ namespace PluginManager.Loaders Events = new List(); Functions.WriteLogFile("Starting plugin loader ... Client: " + _client.CurrentUser.Username); - if (LanguageSystem.Language.ActiveLanguage != null) - Console_Utilities.WriteColorText( - LanguageSystem.Language.ActiveLanguage.FormatText( - LanguageSystem.Language.ActiveLanguage.LanguageWords["PLUGIN_LOADING_START"] - ) - ); - + Console.WriteLine("Loading plugins"); Loader commandsLoader = new Loader(pluginCMDFolder, pluginCMDExtension); Loader eventsLoader = new Loader(pluginEVEFolder, pluginEVEExtension); diff --git a/PluginManager/Others/Functions.cs b/PluginManager/Others/Functions.cs index a87d603..6eef7e0 100644 --- a/PluginManager/Others/Functions.cs +++ b/PluginManager/Others/Functions.cs @@ -7,6 +7,8 @@ using System.Collections.Generic; using Discord.WebSocket; using PluginManager.Items; using System.Threading; +using System.Text.Json; +using System.Text; namespace PluginManager.Others { @@ -40,22 +42,6 @@ namespace PluginManager.Others /// public static readonly string pakFolder = @"./Data/Resources/PAKS/"; - /// - /// The mark that the line is a comment - /// - private static readonly char commentMark = '#'; - - /// - /// Read data from file - /// - /// File name - /// Setting name - /// Separator between setting key code and its value - /// The value of the specified setting key code in the specified file () - public static string? readCodeFromFile(string fileName, string Code, char separator) - => File.ReadAllLines(fileName) - .Where(p => p.StartsWith(Code) && !p.StartsWith(commentMark.ToString())) - .First().Split(separator)[1] ?? null; /// /// Read data from a file that is inside an archive (ZIP format) @@ -67,17 +53,16 @@ namespace PluginManager.Others { archFile = pakFolder + archFile; Directory.CreateDirectory(pakFolder); - if (!File.Exists(archFile)) - throw new FileNotFoundException("Failed to load file !"); + if (!File.Exists(archFile)) throw new FileNotFoundException("Failed to load file !"); string? textValue = null; - var fs = new FileStream(archFile, FileMode.Open); - var zip = new ZipArchive(fs, ZipArchiveMode.Read); + var fs = new FileStream(archFile, FileMode.Open); + var zip = new ZipArchive(fs, ZipArchiveMode.Read); foreach (var entry in zip.Entries) { if (entry.Name == FileName || entry.FullName == FileName) { - Stream s = entry.Open(); + Stream s = entry.Open(); StreamReader reader = new StreamReader(s); textValue = await reader.ReadToEndAsync(); reader.Close(); @@ -86,6 +71,7 @@ namespace PluginManager.Others break; } } + return textValue; } @@ -96,8 +82,7 @@ namespace PluginManager.Others public static void WriteLogFile(string LogMessage) { string logsPath = logFolder + "Log.txt"; - if (!Directory.Exists(logFolder)) - Directory.CreateDirectory(logFolder); + if (!Directory.Exists(logFolder)) Directory.CreateDirectory(logFolder); File.AppendAllText(logsPath, LogMessage + " \n"); } @@ -108,8 +93,7 @@ namespace PluginManager.Others public static void WriteErrFile(string ErrMessage) { string errPath = errFolder + "Error.txt"; - if (!Directory.Exists(errFolder)) - Directory.CreateDirectory(errFolder); + if (!Directory.Exists(errFolder)) Directory.CreateDirectory(errFolder); File.AppendAllText(errPath, ErrMessage + " \n"); } @@ -132,10 +116,10 @@ namespace PluginManager.Others File.AppendAllText(file, Code + separator + newValue + "\n"); ok = true; } - else File.AppendAllText(file, line + "\n"); + else + File.AppendAllText(file, line + "\n"); - if (!ok) - File.AppendAllText(file, Code + separator + newValue + "\n"); + if (!ok) File.AppendAllText(file, Code + separator + newValue + "\n"); } /// @@ -146,8 +130,8 @@ namespace PluginManager.Others /// A string built based on the array public static string MergeStrings(this string[] s, int indexToStart) { - string r = ""; - int len = s.Length; + string r = ""; + int len = s.Length; if (len <= indexToStart) return ""; for (int i = indexToStart; i < len - 1; ++i) { @@ -192,8 +176,7 @@ namespace PluginManager.Others int len = args.Length; if (len < 2) return; - for (int i = 0; i < len - 2; i++) - path += args[i] + "/"; + for (int i = 0; i < len - 2; i++) path += args[i] + "/"; path += args[len - 2] + ".txt"; @@ -215,20 +198,15 @@ namespace PluginManager.Others /// Triggered in is not writable 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)); - if (bufferSize <= 0) - throw new ArgumentOutOfRangeException(nameof(bufferSize)); - if (!stream.CanRead) - throw new InvalidOperationException("The stream is not readable."); - if (!destination.CanWrite) - throw new ArgumentException("Destination stream is not writable", nameof(destination)); + if (stream == null) throw new ArgumentNullException(nameof(stream)); + if (destination == null) throw new ArgumentNullException(nameof(destination)); + if (bufferSize <= 0) throw new ArgumentOutOfRangeException(nameof(bufferSize)); + if (!stream.CanRead) throw new InvalidOperationException("The stream is not readable."); + if (!destination.CanWrite) throw new ArgumentException("Destination stream is not writable", nameof(destination)); - byte[] buffer = new byte[bufferSize]; - long totalBytesRead = 0; - int bytesRead; + byte[] buffer = new byte[bufferSize]; + long totalBytesRead = 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); @@ -246,15 +224,12 @@ namespace PluginManager.Others /// public static async Task ExtractArchive(string zip, string folder, IProgress progress) { - if (!Directory.Exists(folder)) - Directory.CreateDirectory(folder); - - + if (!Directory.Exists(folder)) Directory.CreateDirectory(folder); using (ZipArchive archive = ZipFile.OpenRead(zip)) { - int totalZIPFiles = archive.Entries.Count(); + int totalZIPFiles = archive.Entries.Count(); int currentZIPFile = 0; foreach (ZipArchiveEntry entry in archive.Entries) { @@ -262,8 +237,13 @@ namespace PluginManager.Others Directory.CreateDirectory(Path.Combine(folder, entry.FullName)); else - try { entry.ExtractToFile(Path.Combine(folder, entry.FullName), true); } - catch { } + try + { + entry.ExtractToFile(Path.Combine(folder, entry.FullName), true); + } + catch + { + } currentZIPFile++; await Task.Delay(10); @@ -281,5 +261,40 @@ namespace PluginManager.Others return (bytes / 1024.0 / 1024.0 / 1024.0, "GB"); } + + public static async Task SaveToJsonFile(string file, T Data) + { + string jsonText = JsonSerializer.Serialize(Data, typeof(T)); + await File.WriteAllTextAsync(file, jsonText); + } + + public static async Task ConvertFromJson(string input) + { + Stream text; + if (File.Exists(input)) + text = File.Open(input, FileMode.OpenOrCreate); + + else + text = new MemoryStream(Encoding.ASCII.GetBytes(input)); + text.Position = 0; + var obj = await JsonSerializer.DeserializeAsync(text); + text.Close(); + return obj; + } + + public static bool TryReadValueFromJson(string input, string codeName, out JsonElement element) + { + Stream text; + if (File.Exists(input)) + text = File.OpenRead(input); + + else + text = new MemoryStream(Encoding.ASCII.GetBytes(input)); + + var jsonObject = JsonDocument.Parse(text); + + var data = jsonObject.RootElement.TryGetProperty(codeName, out element); + return data; + } } } diff --git a/StartupEvents/OnUserJoin.cs b/StartupEvents/OnUserJoin.cs deleted file mode 100644 index bb4ff5f..0000000 --- a/StartupEvents/OnUserJoin.cs +++ /dev/null @@ -1,57 +0,0 @@ -using PluginManager.Others; -using PluginManager.Interfaces; -using Discord; - -public class OnUserJoin : DBEvent -{ - public string name => "OnPlayerJoin"; - - public string description => "An event that is triggered when an user joins the server"; - - private string UtilsPath = Functions.dataFolder + "/StartupEvents"; - private string ConfigFile = Functions.dataFolder + "/StartupEvents/" + "UserJoinEvent.txt"; - - public async void Start(Discord.WebSocket.DiscordSocketClient client) - { - - System.IO.Directory.CreateDirectory(UtilsPath); - - if (!System.IO.File.Exists(ConfigFile)) - { - await System.IO.File.WriteAllTextAsync(ConfigFile, - "Enabled=True\nEmbed=True\n" + - "#Available placeholders:\n" + - "#{user.Name} => Username of the user\n" + - "#{time.date} => Current Date\n" + - "#{time.time} => Current time (hh:mm::ss)\n" + - "MessageTitle = Welcome {user.Name}\n" + - "MessageDescription=Embed description\n" + - "MessageField1Title=Custom Title\n" + - "MessageFiled1Text=Custom Filed 1 text\n" + - "MessageField2Title=Custom Title\n" + - "MessageFiled2Text=Custom Filed 2 text\n" + - "MessageFooter=Today: {time.date} at {time.time}\n"); - } - - if (Functions.readCodeFromFile(ConfigFile, "Enabled", '=') != "True") return; - //System.Console.WriteLine("Awaiting user join event ..."); - - client.UserJoined += Client_UserJoined; - - } - - private async System.Threading.Tasks.Task Client_UserJoined(Discord.WebSocket.SocketGuildUser user) - { - Console_Utilities.WriteColorText("A new user joins: " + user.Username); - EmbedBuilder embed = new EmbedBuilder - { - Title = Functions.readCodeFromFile(ConfigFile, "MessageTitle", '='), - Description = Functions.readCodeFromFile(ConfigFile, "MessageDescription", '=') - }; - embed - .AddField(Functions.readCodeFromFile(ConfigFile, "MessageField1Title", '=').Replace("{user.Name}", user.Username).Replace("{time.date}", System.DateTime.Now.ToShortDateString()).Replace("{time.time}", System.DateTime.Now.ToShortTimeString()), Functions.readCodeFromFile(ConfigFile, "MessageField1Text", '=').Replace("{user.Name}", user.Username).Replace("{time.date}", System.DateTime.Now.ToShortDateString()).Replace("{time.time}", System.DateTime.Now.ToShortTimeString())) - .AddField(Functions.readCodeFromFile(ConfigFile, "MessageField2Title", '=').Replace("{user.Name}", user.Username).Replace("{time.date}", System.DateTime.Now.ToShortDateString()).Replace("{time.time}", System.DateTime.Now.ToShortTimeString()), Functions.readCodeFromFile(ConfigFile, "MessageField2Text", '=').Replace("{user.Name}", user.Username).Replace("{time.date}", System.DateTime.Now.ToShortDateString()).Replace("{time.time}", System.DateTime.Now.ToShortTimeString())) - .WithFooter(Functions.readCodeFromFile(ConfigFile, "MessageFooter", '=').Replace("{user.Name}", user.Username).Replace("{time.date}", System.DateTime.Now.ToShortDateString()).Replace("{time.time}", System.DateTime.Now.ToShortTimeString())); - await user.Guild.DefaultChannel.SendMessageAsync(embed: embed.Build()); - } -} \ No newline at end of file diff --git a/StartupEvents/SetGameOnLogin.cs b/StartupEvents/SetGameOnLogin.cs deleted file mode 100644 index 4a2d2d9..0000000 --- a/StartupEvents/SetGameOnLogin.cs +++ /dev/null @@ -1,48 +0,0 @@ -public class SetGameOnLogin : PluginManager.Interfaces.DBEvent -{ - public string name => "Set Game on Startup"; - public string description => "Set Custom Game to the bot at initialization"; - public async void Start(Discord.WebSocket.DiscordSocketClient client) - { - string UtilsPath = PluginManager.Others.Functions.dataFolder + "StartupEvents/"; - string ConfigFile = UtilsPath + "LoginEvent.txt"; - - System.IO.Directory.CreateDirectory(UtilsPath); - if (!System.IO.File.Exists(ConfigFile)) - { - System.Console.WriteLine($"First time setup. Open file: {ConfigFile} to change settings or use the following commands\nNote: For space ( ) use underline (_). Example: 'Hello_World' will output 'Hello World'"); - System.Console.WriteLine($"set-setting StartupEvents.LoginEvent.Title [Custom_Title(s)]"); - System.Console.WriteLine($"set-setting StartupEvents.LoginEvent.Dynamic_Title [True/False]"); - System.Console.WriteLine($"set-setting StartupEvents.LoginEvent.Dynamic_Title_Change_Rate [interval in milliseconds]"); - await System.IO.File.WriteAllTextAsync(ConfigFile, "Enabled=True\n\nDynamic Title=False\n#For dynamic title add titles like this:\n#Title=Hello,World,Test,Test2\nTitle=!help\nDynamic Title Change Rate=3500\n"); - } - - if (PluginManager.Others.Functions.readCodeFromFile(ConfigFile, "Enabled", '=') != "True") - return; - - bool isDynamic = PluginManager.Others.Functions.readCodeFromFile(ConfigFile, "Dynamic Title", '=') == "True"; - string Title = PluginManager.Others.Functions.readCodeFromFile(ConfigFile, "Title", '='); - if (Title == null || Title.Length < 2) return; - if (!isDynamic) - await client.SetGameAsync(Title, null, Discord.ActivityType.Playing); - else - { - string[] Titles = Title.Split(','); - int delayMS = 3500; - try - { - delayMS = int.Parse(PluginManager.Others.Functions.readCodeFromFile(ConfigFile, "Dynamic Title Change Rate", '=')); - } - catch { } - while (true) - { - foreach (var title in Titles) - { - await client.SetGameAsync(title, null, Discord.ActivityType.Playing); - await System.Threading.Tasks.Task.Delay(delayMS); - } - } - } - - } -} \ No newline at end of file diff --git a/StartupEvents/StartupEvents.csproj b/StartupEvents/StartupEvents.csproj deleted file mode 100644 index aaabc01..0000000 --- a/StartupEvents/StartupEvents.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - net6.0 - - - - ..\BUILDS\ - none - false - - - - - - - From e88d654da1f3c0dab7180ddf253673eec46c8861 Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Sat, 4 Jun 2022 18:58:14 +0300 Subject: [PATCH 08/20] --- DiscordBotGUI/AppUpdater.axaml.cs | 7 ++++++- DiscordBotGUI/MainWindow.axaml.cs | 6 +++--- PluginManager/Config.cs | 1 - 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/DiscordBotGUI/AppUpdater.axaml.cs b/DiscordBotGUI/AppUpdater.axaml.cs index f6eaf5c..2295319 100644 --- a/DiscordBotGUI/AppUpdater.axaml.cs +++ b/DiscordBotGUI/AppUpdater.axaml.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using System; using System.IO; using System.Threading; +using PluginManager; namespace DiscordBotGUI { @@ -149,7 +150,10 @@ namespace DiscordBotGUI { try { - string current_version = Functions.readCodeFromFile("Version.txt", "DiscordBotVersion", '=') ?? "0"; + string current_version = Config.GetValue("Version"); + if (current_version == null) + if (!Config.SetValue("Version", "0")) + Config.AddValueToVariables("Version", "0"); string latest_version = (await ServerCom.ReadTextFromFile("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Updates/Version"))[0]; _version = latest_version; if (current_version != latest_version) { return true; } @@ -159,6 +163,7 @@ namespace DiscordBotGUI catch (Exception ex) { textBox1.Text = "Error while checking for updates. Server is not responding."; + Functions.WriteErrFile(ex.Message); return false; } } diff --git a/DiscordBotGUI/MainWindow.axaml.cs b/DiscordBotGUI/MainWindow.axaml.cs index 081a81e..52f379f 100644 --- a/DiscordBotGUI/MainWindow.axaml.cs +++ b/DiscordBotGUI/MainWindow.axaml.cs @@ -26,7 +26,7 @@ namespace DiscordBotGUI textBox3.Watermark = "Insert start arguments"; - if (File.Exists("./Version.txt")) label5.Content = Config.ApplicationVariables["Version"] as string; + if (File.Exists("./Version.txt")) label5.Content = Config.GetValue("Version"); button1.Click += async (sender, e) => { @@ -56,8 +56,8 @@ namespace DiscordBotGUI Directory.CreateDirectory(Functions.dataFolder); try { - string? botToken = Config.ApplicationVariables["token"] as string; - string? botPrefix = Config.ApplicationVariables["prefix"] as string; + string? botToken = Config.GetValue("token") as string; + string? botPrefix = Config.GetValue("prefix") as string; if (botToken == null || botPrefix == null) { textBox1.IsReadOnly = false; diff --git a/PluginManager/Config.cs b/PluginManager/Config.cs index 3dac456..5cbcee5 100644 --- a/PluginManager/Config.cs +++ b/PluginManager/Config.cs @@ -51,7 +51,6 @@ namespace PluginManager public static bool SetValue(string key, string value) { if (!ApplicationVariables.ContainsKey(key)) return false; - if (ConstantTokens.Contains(key)) return false; ApplicationVariables[key] = value; return true; From 690b7fe5f1296bd16318664a85cf6da734f9ebd5 Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Sat, 4 Jun 2022 19:30:08 +0300 Subject: [PATCH 09/20] --- EVE_LevelingSystem/Level.cs | 19 +++++++++++++++---- .../LevelingSystemCore/LevelCalculator.cs | 3 ++- EVE_LevelingSystem/Settings.cs | 13 +++++++++++++ PluginManager/Others/Functions.cs | 2 +- 4 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 EVE_LevelingSystem/Settings.cs diff --git a/EVE_LevelingSystem/Level.cs b/EVE_LevelingSystem/Level.cs index 2d9b6bd..e4d6376 100644 --- a/EVE_LevelingSystem/Level.cs +++ b/EVE_LevelingSystem/Level.cs @@ -8,15 +8,26 @@ namespace EVE_LevelingSystem { internal class Level : DBEvent { - public string name => "Leveling System Event Handler"; - public string description => "The Leveling System Event Handler"; + public string name => "Leveling System Event Handler"; + public string description => "The Leveling System Event Handler"; + internal static Settings globalSettings = new(); - public void Start(DiscordSocketClient client) + public async void Start(DiscordSocketClient client) { Directory.CreateDirectory("./Data/Resources/LevelingSystem"); Config.AddValueToVariables("LevelingSystemPath", "./Data/Resources/LevelingSystem"); + Config.AddValueToVariables("LevelingSystemSettingsFile", "./Data/Resources/LevelingSystemSettings.txt"); + if (!File.Exists(Config.GetValue("LevelingSystemSettingsFile"))) + { + globalSettings = new Settings { TimeToWaitBetweenMessages = 5 }; + await Functions.SaveToJsonFile(Config.GetValue("LevelingSystemSettingsFile"), globalSettings); + } + else + globalSettings = await Functions.ConvertFromJson(Config.GetValue("LevelingSystemSettingsFile")); + + // Console.WriteLine(globalSettings.TimeToWaitBetweenMessages); client.MessageReceived += ClientOnMessageReceived; } @@ -28,7 +39,7 @@ namespace EVE_LevelingSystem if (File.Exists($"{Config.GetValue("LevelingSystemPath")}/{userID}.dat")) { user = await Functions.ConvertFromJson(Config.GetValue("LevelingSystemPath")! + $"/{userID}.dat"); - Console.WriteLine(Config.GetValue("LevelingSystemPath")); + // Console.WriteLine(Config.GetValue("LevelingSystemPath")); if (user.AddEXP()) await arg.Channel.SendMessageAsync($"{arg.Author.Mention} is now level {user.CurrentLevel}"); await Functions.SaveToJsonFile(Config.GetValue("LevelingSystemPath") + $"/{userID}.dat", user); return; diff --git a/EVE_LevelingSystem/LevelingSystemCore/LevelCalculator.cs b/EVE_LevelingSystem/LevelingSystemCore/LevelCalculator.cs index 9df66dc..62c6d1c 100644 --- a/EVE_LevelingSystem/LevelingSystemCore/LevelCalculator.cs +++ b/EVE_LevelingSystem/LevelingSystemCore/LevelCalculator.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using PluginManager; namespace EVE_LevelingSystem.LevelingSystemCore { @@ -44,7 +45,7 @@ namespace EVE_LevelingSystem.LevelingSystemCore new Thread(() => { - int minutesToWait = 0; + int minutesToWait = Level.globalSettings.TimeToWaitBetweenMessages; Thread.Sleep(60000 * minutesToWait); OnWaitingList.Remove(user.userID); } diff --git a/EVE_LevelingSystem/Settings.cs b/EVE_LevelingSystem/Settings.cs new file mode 100644 index 0000000..38a8caa --- /dev/null +++ b/EVE_LevelingSystem/Settings.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EVE_LevelingSystem +{ + public class Settings + { + public int TimeToWaitBetweenMessages { get; set; } + } +} diff --git a/PluginManager/Others/Functions.cs b/PluginManager/Others/Functions.cs index 6eef7e0..5f6fb5f 100644 --- a/PluginManager/Others/Functions.cs +++ b/PluginManager/Others/Functions.cs @@ -264,7 +264,7 @@ namespace PluginManager.Others public static async Task SaveToJsonFile(string file, T Data) { - string jsonText = JsonSerializer.Serialize(Data, typeof(T)); + string jsonText = JsonSerializer.Serialize(Data, typeof(T), new JsonSerializerOptions() { WriteIndented = true }); await File.WriteAllTextAsync(file, jsonText); } From 4fbea983dadcd36d39cc673cae2d9fba9e7ea875 Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Sun, 5 Jun 2022 13:21:46 +0300 Subject: [PATCH 10/20] --- BUILDS/net6.0/PluginManager.dll | Bin 63488 -> 63488 bytes DiscordBot/Discord/Commands/Settings.cs | 17 ++-- DiscordBot/Discord/Core/Boot.cs | 2 +- DiscordBot/Program.cs | 15 ++- EVE_LevelingSystem/Level.cs | 4 +- PluginManager/Config.cs | 90 ++++++++---------- PluginManager/Items/ConsoleCommandsHandler.cs | 21 +++- PluginManager/Others/Console Utilities.cs | 4 +- PluginManager/Others/Functions.cs | 68 ++++--------- 9 files changed, 97 insertions(+), 124 deletions(-) diff --git a/BUILDS/net6.0/PluginManager.dll b/BUILDS/net6.0/PluginManager.dll index 58b27717a2233aaec05de06d981fca39f72b7025..7cc60a0e43966b72d2dc8aafab2c8c98d36c5ba5 100644 GIT binary patch delta 25993 zcma)l31CxY*7mvgCO2uCq*>Z@NtdK+XbV!=_tv&5`>uj0t!$!TphZPXO$%-yE_e|I zQCk6*5l0!+K}Degj;P~4DvC%2cRt5$98tvoIp?OdxP1SI)90S;J?Fgpd+$v$O~faWAySJ=<7|MgHqPOT)_5UbQX1#-WeKZ%6mbxh zm`ubB&(ZrMdOG_;_0S%Xi*ae3$Hmmf`Fu%fyo4`HSOzDF;$&V7Tx0>D*xys5ad46W zC!|IeLgq>+O;96spd2OMNIkAJ6SL*(S8aJg9S?Z25g<4zcQWaVdYeLeNx&a`Y5ZO|99#cV3NJu3Q5(48@ zql-DDkF*E|l%u$>8od%%ErNkqf*#`Jhrl+ITi^ldAg%FMcroqtIOfTS{ojjNO>Y(nQ2a{V?f)rSyv*NzUncgaDHeb9d+R?n zRxQzGTwl&c`UJHnRNhN<_oGeJ=+)3h&R_^}1Ju35(nwECC%vn5 zokc`^tUB3;YWi4Z%nt-(zqJq_9Tq5Ow?#0gOB}kb*N4T~Y6GUBgRcf(&yUxbRGFU+ z)zT<(WFPElq5klLns}*xHD{nkZo?%q1rRu{U`%7FOmiwnCSO(3E=g5ONX8m!0U-O z@QFtKU4(dm=wFPl((a8FqaIZM5Zp(maT4{LnLMA#x+3oJ23T04SR)+Kzp{$^K9VE) zDD?4F>1L31ZGiempm)^mJ;7t%I}&yExL%7g^;^J2{{|oy&EW3lg~JhjjAb^+YS`>? z7Cq4+x`0K0XVEqm=}{~O@pNs`r+S`?Y4=H5oW2Mhr^XvDX8b!NBX&X>ZG>Kn4j1J7 zG~V*{=m!8^r>wHiO8#m?8Co9W2vz7|GI95q|0*8_{>afjafJ1tH*YApSO-8D*9S|3 zrO35&d5AuZHfZbxBQ3h!cr}<2!z!)kgaXllP}D!eEi{XLl{nRU6peGL9$1$eeU|w- ztYtnB?aTaJiM*mSMB@N>S0nRSUiUFKVF-5SzG0zyteoAEQvDau;}{idOj5`~dZ5vb z>s8nnEYTfoUsqx$(L-=#@SsW zx+v?Gv8#lWU44v$nQ2+j#HzUc7PjAEC|Um4C!N6@oxwh2gD=@(;>iv_?KEdiJhvh% z%*y~*IZrnKtkaw|aq|W?zlP0Sv6JmT@3hA)L5Kb8Z2t}bRX@TOomDS>gQQJW%~Jmy z8YH@l+cqaDQo+|cmyW4kmj{%|ks1l0I1fk*Z@<(76V+S)HDnIm(&$G->@W!OO-CAL z!scYc9!jTh&weZRYGX3nOLP?Zj*IN(46qS93bDHItnG#}J-N*H@iHl0%lrpNPrd$m z*hjK3yUqIw-qJLhiGpRu!`T^qUw}HXq{OF0_JVSfJ^CW97@v`saK&Le38I%-6#XX< z~OMVm^B7zUKyu zyaq@0{fwXo>nMCaLP3dEJbJN}L!z#KT;Pk1H4~+h~!<7$>rMdZO2O*;aDQeE~#?z68x&*7B#TIEd zp3Ob$T+G`pOG0ENT7XmwA8d4bEyAbsJ5fA>d4^jQ1(Uu05J)|G7#RJS0kgufi7gA9 zkz2T!JtwJGq8ho`h~}kFL2G&`5W!r)5bJBh;KH=Vs0+nK15b!jO-U}%*A;5y26(#o zTt{kRz*!Q(`Qv8r5lj*65Cy5{Bt||p+VdjLlLRUG5xc|*L_RaB^TRRraa@tZM|zSH z!Gv+t4dr-f0Ed}JNot2;!pRCM85`I5>^X^P5iC&-pWPBE;H|}HufxK)Ac6_z0Ar2( zk4eBD80n*Ljl~6{mG6z`3-Xlz7+(}D z&iR4e9LVIJ!Wqe;CO3|k4#VDo4*RdsTsTJ=V0>Pfqx@(j6#dTKIYsR5z9M$_V$n(N z&Nkgm6?f;v-PK0s%*KGmXg!L+GFq+u@5ZdadEzHXgPj( zWLTYepu6A3tt|1A&7_yGCSF7m@!BFbE^{FA|24Hm>_%>Ju`_J^ba;$n z#TPXW!lj;k8*1rTCBv9dT9F-ukPZa79p)fA3`}gMSV=AfMly{prTvt_ z#^SIKo^GMHh7>-*~)x$jO$Gd_ZcXz-aHDlT-*g%FCqR;o;#ry0|lA(sWOKZdt?we=`-F8_wkxgE^7kE zQEiQbafzvz_d~dpf|-s3MF}0a0DCJWiRu!*98bx{&Lax~mxHJG;E4`|{TA+6@s(^Q zA&&4Qt;<;cojQ^UCseF>coDRb`oJSbMz4(Y5^N+mNXH)~@TtQ}xHF<*#^_!}ZXBQV z=ui~ojdz%_wAU!5!g#e;o^qP;U9UymDxoPYQ5)_;gQu^no6Q5f3bO9WCuH+PX57;I z8t3&O)dnoWmgv<+xX*yJYR<^qy$wj!C98q9$mvF1pD{|g(blI+0^E|rj34@N0+oI9 zVyB^O<3=u3e+HAAm~3E7yKy$}*nzr_5bxfCRP!1=lY{-n;*+?AngGi`wDaZ-K%g3xG#czw_9cZzbRaYMfmNx$)69PZaU-V)dXxFz!Y_v<=gTeu=iT7j6b zb^XVnzHR+;{e$_C@SE=Vp}(}o0Pc=C14iSJ_V|DX-*8m)-oy`(57h-wvHGRPX#*!X zmw;3o{%*!>88}p_Ha;8}P);{~7&r#ys|WS?O$@WeuN}lO-W-&dDlPsDXJ@wfvrI;E z4cFjM>|Jg^Zfd!v)%_&b^g5pd^2Ro{Y+(D0KkS==w0K{opWIgxp@BKck@giar5BfJDi|i|7~t4_F-KEoo_i`mx66x=8W@l36S>4BhRJ})Spd`wxxxY~DUdxSM@~Dr3fYxhg^Mb?q2*Rr z_D5U(v$7a%`6K9RqpT{|jr#*#b`W05%8c5o(bzy9sXAXd$8cBYD^rYK)g#KMBHYF2 z;++1%X;Y)Jzp4$NAzlOS1aNPz6_(hvC~n@ckak%!WzpQE5uI*4Qyo&CGY(V_aGwjS z=rjPg@p(qU>7$hMjk?qOD!YsaPcP~|oz*oAwSdM?rE0jPv_wU70c&Oe_*6O5_ywhB z86(aZqs%teo{^O_ht+Z@zzY)`3ig~aI$L&!53rMRf8$0Ijk%lK`9j#%&oz3US(udH z(P(mB+Gor&Zp0}cL*ok|hDOcs3j=4! z(7*}$q!DTy7@qCEh%@Dl+iZ5nh~a4VNh5}&nR~L_x^Y2u$uS^r&JT_#D!&*7np!YG zI-5CLi_U|zQ*eRWupSm#bUwtTb}f1dt|dyKxJP}v;Tf5E?wQDnw43Ip%2^bH_5!Lq z9Wyl&LNPLL*`t_$C*4=qT>=a9=DMy<$SB-K7BHCQ(4DUs*NqHM zjhvJz$*TK|MRj=Zw!n?m0>((lSTd@*XfQ;-vAvc>zqS2rRHi;0?NNW!aE$J&k6`kc zar)?iSYw(;mxZ54A>Dj(C^7k2hf263p;2u5D;aN&9-x#Mt}(ro(MH9X9A&CeJ0|Eo z#3Kv?Q7>q+@spaHj2p+~4>`f%jE2|C3>>6uMmoafdhdKIN9iMG9ItTM( ztntm*OQ!H~Jkp;VzNAR@oj8+G_Zk`_&baE{>SQQVhg4FhMDTRa5n04(g?>WbkrQWh zo~`?gZR3VxF;d6(z@v<^@hNzeamM&Q$~dEOe42Y0sxC9vTzWT*Kl2osfd|rDe5%7C z4O0QP8kU3zmRcN-e&31zJMsLt)A1@XsY9~`yf1knQm(?MMg z$ga=NK6n=fYC{2>2iDbn%vyHEhrhV&KOHi>9QEs7y>yrw>^K1^E;%x&4X2pKyn%;B zmTtzow;-dghy{_wNV*YiY$@rZ)|DBSNfk-h6U}Cny?mcBY0_xBv}0XAm+|1FOl7$7 z{G>eGw0^ zG1fIlq%#!XI_@(H&KliYLPap5d2?c8G{6>=l-oOhqBn7Xf-|&Q|3BOjSduMN_q1`} zSykpfi91%_3t4_#{|Y8u_DS6Mpu*X$0h8DAL+!K$?0?APQ;jd z_NYop-i*<}spQPe!yv}LuXiLzZ$$~zi4zDk`hcO&w5}uE@AA3O2tS@ZI`;qfgU;v} zpuf*E(!djl?_W6>E@stvtk%8B6q% zrn*EoN?iqEVIYDh%5X03xqsjux2~94#lT3D@#{IWZ07vxW(=K@r(#;&GG&}H!Dyc{ zS_vDcOihTyfR;L5C`~eAhmP0b1ydt&UqPdJY6|;$VrsE6(P*FA z!`+NLy3F^ib4QxDacTo@87&QXmSJhYII={S!ccB*mx17QyCl?0y zMC0>mePTbSL44@vH;V!B!8IWryE184W)QebxI3RP^bG-7-tGL3w|Q_ zdNRw;OXjlGfidYimFF`qPG;N++Ckr0w>TVhzGaJJBt4!Z?^6#$q|-V-8+|5)wUiHY zbgJ^RqrMi#)J)c9XE8lMwEMH?hupL-?JSR*-c35oqtoZw=V3QpCX&muSw3Ir7d@;^ zgP*Y+l6-Vy&Y1L(Xi1Ohb0c70KRjstbNGkr{Y2Bmo0@^u=N_IX&R2^RMAj&)3WHvLb*$jofYDr7t* zZ)Bz(qcW-AVdSpU67T$wO=-*K27gwYA4-bTeUL;h-5D64fmT7&#p-tMD^g_D1;OWdl`qJ}srcSYmlHHSG&QX(o zsw!Z*J(ck_WQ}4)+^>&nTO1j*u7DjK)mi>E-0Adf#+Y;;HA@G*gHA!0q23v!6@7~q zog(94ftM{C;L}IrePhy#X_oh;OgC+dp@($3OOnXUW20ChLOtlsj4=pyRMPr9iPLhT0;kfYt`7n_O%AgCY6<)XIz^|Q==BVG4i(6t zThS^yy{pB>q`PUM43^3~PGvq!`_kle?#uO_N=G*3<#2E5+*|ZUkR3fC_?ci5>OGKr zKJJd6v@vNq-IH4B7)VQUS#n>_pkV-CX@~}kDs&ovclINpo7>uV;_k13tUbN8Z)L3v+Ay3@rvBKeT3H~EI8XB4W zMtHypZX;$BbC~VW{fenQ0JMdg!Mz=LBdeNX8a}4S?E3|K^Qu96VeX-SgiJ0)xI2nW zE{zmKsZQUU_W>-kgIjS&elT*g$vPO;bx?>E=(2F1gAgb9)Qy@RioA(`fGS=-ee_A*yzC} zS++t~NE4)-H;cJq`S_rR`g?2$-wSW#I6_)BbNwiGv9QyH9Z2=m3P=A*>J!4+NtX#X zrqJXXNke#?#}IlDH3_!`jbDv4mkKvjxYOtw;a1{sRgDi0UXLdC&^wvTjiehyH&b+D z$cPF19EN%|olR@Zg4nOCsfN}Hca)o)=FocKVix8W(LKWLurU{-dxcvh65gzi<=ke3E_H6h=0NQ)u-C~^8Ty+BqdPQmIoMNyTP zggZUXy-HfxLl5IbP)(}xrnvd1gs>=YLqhbBlgn9^cZGXA&h76~&Z-=gaxGHMt$YD4 z=Aqt_n@9N{Q63VdU-??NAB9U+z7@_Td8a7f3-^T7KA`*{+&=8^7~RTI;f@IxQjQ6i zgJi1dROMIUP7|&ls#u8r53finq}KyCC6&>>&?;bM?%E_>ztd5roz=9=(UNpl(`|xF z1p5Lzv{M}$p?x)h@k7DUBJl`b2<))@I^hA>40SO6N9YTLwmD)CB=x21vW94V=`O)7 zg0~9Z4-8Xr5@WV|b5fW#xrb;9Mba4G10AO2f>FWGT#v)1Drp<=zwYfg8YQ?6;rLPN zDzb)Yx7Z|!w>JxRB#m#HlQkr!jc>XfVa7LQWia*xdg-#H-AP`0DCy-StozQlfa{$5 zfPHfg!09bXYk?Es4lA4c5G?oS-=s>|DQA`}L4dOb~nR#@{4VB;GbSxb|;|H#6il8LPWk zt_A&fUyK945WW}go>F;Om0Rxv{iV+IC>zt?NbP&rIoMTpmh?#22JL+9FJ0VmOZ?u? zCjD{PkFv41Z^YZ>c5anx#hX9jz8KWk{ee5q&f_hmz2Y~^7U(_aFf zZ2uYpo6FJp($gK?*EuqHNSc9ldNFlB=&0o|&`dNoHH$;ORnP{JE1fenCq~y|_h<0D zIHDc~+O3}hztkD4ZC?SewegU=Tn6S}?cYH%U;7!j*J{Dd`L}x4>hWMVqnJJ)j!9EI zXYI(hFHKE&-Ws6C>2a%0%l+%EEOB`QbUFEeU)bNmN_T$3KHvsR5R#zI@}DA9P3sKw}##?nhfs8IQLa(x>u$AFyY@C`YQA!PQ~ZMxn+UbUK>3S=T-)u zqy+jt&dn*>tR_+<7sX;I_;S%Bij$@>3+@@=Zi#b^MYFw5+7st44Qy6j^hTUp2sdu} zP`FiTujM?VB$1M5dU-SLVs8>T;@kt^yp$a0n$s3}{dA6Su{HEU+EQ;a)x?$Ky*GGM z=wN~A=KI3iFs%9)F=sYg8dV9mh9;!W_NLJtac&;Cbox5ZO|;$V&7j_Rc)?Zr5nPZK z3%7~}q;B$N(xbv%8lwq17fr_umuT zG+zas+JnP$H_g_oX!Z%tgPRcJ1UJ`r2EA-@bXFnO|KT(RpI$Hvdce&yIa(k3RUJW( z#-6r2zfSXNgg=@BNOs!GpP-~p4%wX<8(^7hS4(&EMy2tsT zK9>gfWuF}WN8d#>TDUcKE%dAJVwx1^JR!S(9>u1`*(>vX{`oW`&Rvrq^j|{rgu9l` z%~dE$<$UW)&17*cvqouAocr3j%({Rch;y~jEu`fBrsWRk>gYV-uCbpIl)czH&EsvtpBXc_w1mnXxt!^JJmDIAEWDqyOshT z4{B{6%sO-4FQq);%>G?Uy-kj;z$=cWv>?tsfpT?jyhdWUk_ow?aJByFt~4pGi$$`j>UCsxttCT?X+A@9|>n# zuAn1v9b2xTZNp$0i#uIGPce&waj2+Oxq+UGa}j(b{RVm|&b^6tT1julxew7XD`|h6 z89`%*@T8!@`>NHE3HUE6w^E z^ptR>1hh zc&F(adP+Fc>Fu;Tu4BvFY1*hx%iHOE;Y`ar=)$;;E$^UXV>&JGpyR?_n-=4v&|0#O zHI;0-mOSG+P1h3EWc)LouA`uE%kce(wf=R~t&8qX>K!k~Uhbsz6FR-zNp}lpdRb2o z#C5O7V7i{xPwq5bPj?Gvn%+eZ#C7cSE()E~X?Yjr3TIm0O{H-iTi#8c^Exf>CZBMo zZW-k&u@?V5@>OD<2j8g*wNOJB(-yiq?uMPVQ19uTPFtw2aHi8%Dv#^fvXz{* zotCZS7S6Q1m(t=oSn{*G{ugwb-b(|8Gfg*8IS-_i*6%r6wVw$;AVIF z+(`EcXZqYkkH&SJXlxU0pVMi&iAj8Ih)u1^eR1x2WrTN`^??&ywRe;M!4upd?-u{& zIA@l7_=JwjJ#vEMa*v+ixZKtlJuBhOh4nFdQ8+Wx$LLMrmf?}&tJcTp{VuvE=x|(@ zs3q%9oD}}=Cqj(yZu38Rf~)qn`JXw#arj-l{&m)O_X#BzeEtN-1z$YDalzN<7YT2s z{W>LF$Z9j~*C|=JWq3yXnjhR;)?swnxB1_orZ_hzVVnPLIueVsoAH?JJ&Igpn&#`T z`QM`p<6N@sHUIncSe%;;Za;k==iK(!{2x%(#azw|e}MSg-yAT2+n59NTAbU14{{u! zgn3;pef$k@Hcg`z{{ae#av8mc$NV4CRb5O!r0e3kfy!(C59zipx`T9gTsKmA+kcR@ zbkVibQ*qsN=-TO@U34GOyEuO!yg6n+qH`|cWXwhPBbq9lS*JrZGp^$?dx%2OPRm1- zE1YS0m`dY1wmeMRFYB~COwS5uT7FC~fJ1yU{KvHY@=nu_=~>}S(@*GyxQ?BELi{cC zjzm8JrO;PJj8_9yJaps{HLu`g376=Qbg_)Zi(!L6u?}QM_<4mKcIWZ`mfntM;tJ(? z86R*k28%o%m3oNf;#8KrgR(5|#J}X5DX`=QAA8;d4>S2*X+_8~Lb%iW319VGg z$tM|Hr|mcjS@4X{5lHyC^lToFmJ{9%}EQwLI z7+r$^3Ldbsnk5}{r`(j7X{pp5?`}2v1U0r$i`13V?U3IpRqB*fbTw%>L$j;3+5? z5Z|#!?`m{Za{psVM=;i!r4&k&S-{>jX%!2V$p|n#50)W0M_L!iEGxSjaaMD zEb;b#wKT^ciajJvv=$f11k4rPy1{ z92zGp{x^4Ky?<{Xmel`D-q~7staqa2F!FlJ_%uc4(8xY{fc&<1jaOqcJm77Cq7f6JMKA9E;<70#wo8dbCycz&P}@3c2MmqPJ+;R@=eJ?~fWxy$>V>mXlP zv^C2qJ3L;O^04?9Y1CpNUyJ0gSm$d`Z9|Are*hKAg3@3|r+(-Tkk`4La;LS3h z!z#2s1&K-~T^h&-zLDz-=}wn!?rO6=DHZ&qUqk-LW$YHRV$u;ohM;2QM`?Uww_ zz@tT5)aBYIh1=9JZFBxV)K%K;`ERRhwVTrSgYI4QHt zmV`D-LXU~$F_Anbk_T1pg6;B>c8fOHf5h^nR^t89vPFA5aKy4*UfXV$*S6bS=|Xll65`ntL(eTmgceA<6mjJD8y-qoP_1;*>z{`3~$!=d}E`{l*P zetF5UUyk*MVb8VvThS5N^I`r-TvAmO(Rb5#c#5)5yVTPcG|#DIM2Ri4elKB;3ASsS zv#01+sCGOdwV;t_>rTOBpjELb{MaosPV-Z?e4(8pFOAbIw;rK$hadn-sNMuVl;Q8b`csRFIqdMljWD3SM8zDX;!O%l37+g5l7v^*83 zDLfUclvx&@km*)>y0$za$KOPemogPDukJ_(L z-gP|zEXUJdrWrrOL#GFoWB#}7UQ1=-d-kg({7MOr53QgED#ynpnjJ9U4mETh}~3<;#J4T(7cZ+*A=eA;`6d2!Lc2tA;)fHcdFxMsq4#58##^G!^BiUB)1jG;3azFv>UaxdVufSBjEM@BCvcheZt7i*TFYR6SeWIF3l; ze=iB4?=WzdTev-rNh2RqcwOrTcM5g0Jnt$<3|syYC{8@4@H_Kk3a@?3wdWFhL&9&+ zj-jRdYZkP}PcfTQ8f3Hds8eOvz42aXd19GHxpz6ruzua;*et!fS$cPrOw>^_gUhsD zks(@dnpW7Vtg_sl`H+1TlE!lRmlXN?c9qocL9)}vBtI_ zYby%Bm^0V8%EF?@B$dY`W?mDWDz+1xs+UNNR?g82ZnT(Y|mwTE7n<>F&N-(xx z8Tg-8eHQzEcb|Ufux*L zfM<%$D6ttQHj`pvbPkMEI*(#WK5B)L4<9@`=62I&%1CnKvt%QIkI`b_HlUA2D{M1M zaIWBd!ApTIs#cp}GhAhxZv+dpW9|ZcSa$?o*JY3;*n<+0L=VDELrHQE{4iW^U>;2b zme4d{FS->th&BN$=~3WFdImUAQ0xW5H`gVTij8luLT*29azM+$!>2BHtyFU6T7Aq2ClO9$TQ)A(0#w z$;U!}C$y%pR#Uk4RzW{-MS6kIv0lPd3sa-i(+kNpN&{*$OC(K@{5QEtB+JCnGLbJ+ zxB;&bdbyH8Nx==G-5`<;qTM9)gQDF9?TYkWBH1H&NbC>Ag!x!dQzcVXG8GKr-L{gH zC-OXz6bP1!yi(+qBB>Nfwa_(cJr$JS37sLVql1)i}jGjmws6coCISu5qwRk<>u4KBYz^Gc+C_&2hYwe$H4XbZZ>% zj6t+Pn2lNn?F{Zj;kQ$EO5rw;)AQ&{M*$n%7*h$CB8 z3SApVmdpShQ<9o2_2dmSS-1vG;;31Sn#IvFp<7@xG0-A5ts-d^?FOOSEIg^&;p{ywTn%=$lImtA*N$VWUZ&Y0kU#<#VR$kO3j3}Sb405g$|26Pv}a)8Y|a( zhR{tyFB7^&=nX<|v}RCcaHmLiiR7Tr?T{x0W9=ep7uSb`CcIchDmtr`I4ubY9TE)d zoK~LD<$@I=sT8_K=aEq>k{Kdt5=pbr%{qHq2FVC-OH354qG%Px22t!3d7H@FM7~St zgCaj9v|`JkjG$&?M|pzfwt8}=mfK`7+PE4ukc>{P5lO9$hwTiJHwiAY#n`Atm<@t$ zVzf)>-Jn;bAB2k=QxA%Zc7!Yr9uh6t>*@7WvP;L=S+3dHTL|*xw2;WdkoOIiLozn4 zTqIR?_E`hT4QVy@20XM$YK90+0ntCwTEwWu&i%SkOm{-=P2VZ?uLIDS^v| zgboW`E_8*^RS6mNQm{rOwQ=OeZxXs0i1FW?z@iorwZ@SpJB2qKAtCYWp(DIu z!E%vQ2wfv|tQNOlWdi*0#?x5-^k=cPBr+&p~R zMAR;*VDCor3N|NkJz9l64Emj*;$dyb!(%=ybcJB8V3Wt-nhD)1*oH5!R0a=)U zSNsc>dt+RnLYNw_G%`MHR2gg%x;$xq! zB5xCHhrBXKewHhKro)02{)`xy8c{U+*-@(~c8a7;B<+wC2Sdq{XfoT>CQFJUX%@N_ zSR8B<`k=_$g$|`iJEd@`e4w6Mf!_+M4AzRIDaDZS4-pCjrvwi|q$IVAS_yD53s6rD z2e?>yK#~x;S@3G$C&3nxw~3@(N-3%AvnG}8Yg5@zGbEM4t3j_wZxwnYXg!v?Q;gcA zz-|_$TGH4kl*Wa_X%kxIDiM5M@GFYT!hzr3A!CJv)!4}wz@NNW+HBo3K$o8QimkkS@55&|Jx>m4R zutjXzgWSeSrbH2}h-Gs9s=y#e5jBgXC9@u1O=`*H+0iQUosfK*zEdP^BB88$8k#{_ zvH)kX(^|nM$ZyMN5_z*oS_Rt#+XchfY+sQblVZX&3$|o)En9_d6Kofx9Bxb{htmxU z)`+Azhds0k?i5M8&`OBqp^$W9NIFp@wV-DOn?&9m^2NBYDB7SX4z>%egt>57up-Rz zTES+)R>5}DCRZvT*euv8*oH4Up?>&!7DjtM)6IgdB54!49rW1Bpi&@p608ucEsz32 zw+h`R*bYf?FkHyk48+n@$d+w_VZ5UnVbrcEh`pj7QvXM_YF@2S8?RlZZPUKc23o2u z<1Mo+3oVV7)s_~^X3I9qZcCDNpmnhRH~k6y4c&t;_dxn`N7Zd$p3oJ5#YOirZdwR5BeB43660606I1EC*UvXzXBgfW$hUmjHMwh znP_>w6SyEh1$dd1TJ6dL-QUADr(`nj7CPc!Z%H|f_E-jAJQ8@A7?l=A@huSUCKEvq zCl}}uKo$3B_|z&sK9~f0G{yM)XJhaUG8I2N?*}~&sM1;ZJ!utRkV*xfi--OS9z>^u zK97Q+&j+e_4xI&h7Eq*VGLT7=F;0F=%P={%tyV3cei|GQ;#WWLi30(-fgf0Tzofd)a zPM3l1L05wAK}$fNg0IzuflEQ3I*wL?IhAe#gZpXFz3`+h56=R=0$omDgRY?OL08ZZ zpiiTpK%a(ZN_n{FCN&IH)jWLpSO;B2cEhzUCzh@C)XvprXkTlmTF$mCv+TEAY+Y_$ zWqsJX-Qbce~oPyPy7@UAz0GKaf54`?9m$AIOX0lO0|h{(azMcx!udGVSig z&fm*2q#`G`%$-Kk`n?Hb=?1*YBpPqDuOAlMLr2v;c&fjL&d@%jMcRMqu=X=0TYkac z9vW#$Ql{g2F|L6FqCmQLNS+rKj}_#i{>HdHQH2PoGFNwwsk2 z+h}^hHjX~F-LItE$H;Yv{Tby_`#Z`r_D_|g_{)za{H!cVu&SFAiqxa{t8@%g8yrRI z-yEMRln6etS-le14Yo550>nu_iI3H1Oa^9?jlp=LM_zYK(+SB!^GTk+r_TcYz z{2jvIe_Zz~e)s)KA^tAJ-<9}Viof0Xd)H00HFWn+it*x?!L6w+^@^o;O&J-@M^f;k zs2f`kBv&t9R98D=QAOR13+G-oYv|1B)5}iX+H~*ricz@n>#e1mp3>d*vldN1yKe5H zS;H@xIqQ()L`Kdf#&@=R1QF5Izpt9R!?%U0{2 zrxl~^`5jwt{l{fCRXb&?{_3yzzbJ5Q)!sT!!B~Cpy~+1IFtVWf{>EN^z4-BY!?!N@ z*R!fI`rRzwUJP~B+q^fyruxoF@r_p8#>#gOE3X?1_f5eM!M?O_k8Pi?ng3_p{@yaB z-3Y#)llZZw`=(fle9fO5)$eb^4}2bf|CzL-N{X-fQqAqg;BbSH3CV8v5a&vZ|+ZtNYuZG}SqDtM`Y0gSY)ZC~IsZ delta 26603 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 d = new Dictionary(); while (true) { Console.WriteLine("Please insert your token"); Console.Write("Token = "); string token = Console.ReadLine(); if (token?.Length == 59 || token?.Length == 70) - d.Add("token", token); + Config.AddValueToVariables("token", token, true); else { Console.WriteLine("Invalid token"); @@ -53,13 +51,12 @@ namespace DiscordBot if (prefix == ' ' || char.IsDigit(prefix)) continue; - d.Add("prefix", prefix.ToString()); + Config.AddValueToVariables("prefix", prefix.ToString(), false); break; } - Config.AppendToDictionary(d); - d.Clear(); + Config.SaveConfig(); } HandleInput(args).Wait(); @@ -84,7 +81,7 @@ namespace DiscordBot if (loadPluginsOnStartup) consoleCommandsHandler.HandleCommand("lp"); if (listPluginsAtStartup) consoleCommandsHandler.HandleCommand("listplugs"); if (listLanguagAtStartup) consoleCommandsHandler.HandleCommand("listlang"); - Config.SaveDictionary(); + Config.SaveConfig(); while (true) { Console.ForegroundColor = ConsoleColor.White; diff --git a/EVE_LevelingSystem/Level.cs b/EVE_LevelingSystem/Level.cs index e4d6376..dd8329f 100644 --- a/EVE_LevelingSystem/Level.cs +++ b/EVE_LevelingSystem/Level.cs @@ -16,8 +16,8 @@ namespace EVE_LevelingSystem public async void Start(DiscordSocketClient client) { Directory.CreateDirectory("./Data/Resources/LevelingSystem"); - Config.AddValueToVariables("LevelingSystemPath", "./Data/Resources/LevelingSystem"); - Config.AddValueToVariables("LevelingSystemSettingsFile", "./Data/Resources/LevelingSystemSettings.txt"); + Config.AddValueToVariables("LevelingSystemPath", "./Data/Resources/LevelingSystem", true); + Config.AddValueToVariables("LevelingSystemSettingsFile", "./Data/Resources/LevelingSystemSettings.txt", true); if (!File.Exists(Config.GetValue("LevelingSystemSettingsFile"))) { diff --git a/PluginManager/Config.cs b/PluginManager/Config.cs index 5cbcee5..dee04ae 100644 --- a/PluginManager/Config.cs +++ b/PluginManager/Config.cs @@ -1,86 +1,76 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; using PluginManager.Others; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; namespace PluginManager { + internal class AppConfig + { + public Dictionary ApplicationVariables { get; set; } + public List ProtectedKeyWords { get; set; } + } + public static class Config { - private static readonly Dictionary ApplicationVariables = new(); - private static readonly List ConstantTokens = new() { "token" }; + private static AppConfig appConfig = null; - public static void AppendToDictionary(Dictionary dictionary) + public static bool AddValueToVariables(string key, string value, bool isReadOnly) { - foreach (var kvp in dictionary) ApplicationVariables.TryAdd(kvp.Key, kvp.Value); - } - - public static bool AddValueToVariables(string key, string value, bool constant) - { - bool req = AddValueToVariables(key, value); - if (constant) ConstantTokens.Add(key); - - return req; - } - - public static bool AddValueToVariables(string key, string value) - { - if (ApplicationVariables.ContainsKey(key)) - { - return false; - } - - ApplicationVariables.Add(key, value); + if (appConfig.ApplicationVariables.ContainsKey(key)) return false; + appConfig.ApplicationVariables.Add(key, value); + if (isReadOnly) appConfig.ProtectedKeyWords.Add(key); + SaveConfig(); return true; } public static string? GetValue(string key) { - if (!ApplicationVariables.ContainsKey(key)) - { - if (key != "token") Console.WriteLine("The key is not present in the dictionary"); - return null; - } - - return ApplicationVariables[key]; + if (!appConfig.ApplicationVariables.ContainsKey(key)) return null; + return appConfig.ApplicationVariables[key]; } public static bool SetValue(string key, string value) { - if (!ApplicationVariables.ContainsKey(key)) return false; - if (ConstantTokens.Contains(key)) return false; - ApplicationVariables[key] = value; + if (!appConfig.ApplicationVariables.ContainsKey(key)) return false; + if (appConfig.ProtectedKeyWords.Contains(key)) return false; + appConfig.ApplicationVariables[key] = value; + SaveConfig(); return true; } public static bool RemoveKey(string key) { - if (ConstantTokens.Contains(key)) return false; - - - ApplicationVariables.Remove(key); + appConfig.ApplicationVariables.Remove(key); + appConfig.ProtectedKeyWords.Remove(key); return true; } - public static async void SaveDictionary() + public static async void SaveConfig() { string path = Functions.dataFolder + "var.dat"; - await Functions.SaveToJsonFile(path, ApplicationVariables); + await Functions.SaveToJsonFile(path, appConfig); } - public static async void LoadDictionary() + public static async Task LoadConfig() { string path = Functions.dataFolder + "var.dat"; - var d = await Functions.ConvertFromJson>(path); - ApplicationVariables.Clear(); - AppendToDictionary(d); + if (File.Exists(path)) + { + appConfig = await Functions.ConvertFromJson(path); + Functions.WriteLogFile($"Loaded {appConfig.ApplicationVariables.Keys.Count} application variables.\nLoaded {appConfig.ProtectedKeyWords.Count} readonly variables."); + //Console.WriteLine($"Loaded {appConfig.ApplicationVariables.Count} application variables !"); + } + else + appConfig = new() { ApplicationVariables = new Dictionary(), ProtectedKeyWords = new List() }; } - public static string GetKey(string value) => ApplicationVariables.Keys.FirstOrDefault(x => ApplicationVariables[x] == value); - public static bool ContainsValue(string value) => ApplicationVariables.ContainsValue(value); - public static bool ContainsKey(string key) => ApplicationVariables.ContainsKey(key); + public static string? GetKey(string value) => appConfig.ApplicationVariables.Keys.FirstOrDefault(x => appConfig.ApplicationVariables[x] == value); + public static bool ContainsValue(string value) => appConfig.ApplicationVariables.ContainsValue(value); + public static bool ContainsKey(string key) => appConfig.ApplicationVariables.ContainsKey(key); + + public static Dictionary GetAllVariables() => new Dictionary(appConfig.ApplicationVariables); } } diff --git a/PluginManager/Items/ConsoleCommandsHandler.cs b/PluginManager/Items/ConsoleCommandsHandler.cs index 95841b8..b6109a8 100644 --- a/PluginManager/Items/ConsoleCommandsHandler.cs +++ b/PluginManager/Items/ConsoleCommandsHandler.cs @@ -203,12 +203,12 @@ namespace PluginManager.Items if (args.Length < 3) return; string in1 = args[1]; if (!Config.ContainsKey(in1)) - Config.AddValueToVariables(in1, Functions.MergeStrings(args, 2)); + Config.AddValueToVariables(in1, Functions.MergeStrings(args, 2), false); else Config.SetValue(in1, Functions.MergeStrings(args, 2)); Console.WriteLine($"Updated config file with the following command: {in1} => {Config.GetValue(in1)}"); - Config.SaveDictionary(); + Config.SaveConfig(); } ); @@ -216,7 +216,20 @@ namespace PluginManager.Items { if (args.Length < 2) return; Config.RemoveKey(args[1]); - Config.SaveDictionary(); + Config.SaveConfig(); + } + ); + + AddCommand("vars", "Display all variables", () => + { + var d = Config.GetAllVariables(); + List data = new List(); + data.Add(new string[] { "-", "-" }); + data.Add(new string[] { "Key", "Value" }); + data.Add(new string[] { "-", "-" }); + foreach (var kvp in d) data.Add(new string[] { kvp.Key, kvp.Value }); + data.Add(new string[] { "-", "-" }); + Console_Utilities.FormatAndAlignTable(data); } ); @@ -224,7 +237,7 @@ namespace PluginManager.Items { await client.StopAsync(); await client.DisposeAsync(); - Config.SaveDictionary(); + Config.SaveConfig(); Environment.Exit(0); } ); diff --git a/PluginManager/Others/Console Utilities.cs b/PluginManager/Others/Console Utilities.cs index cf710d8..0b8ba5c 100644 --- a/PluginManager/Others/Console Utilities.cs +++ b/PluginManager/Others/Console Utilities.cs @@ -71,9 +71,9 @@ namespace PluginManager.Others /// The List of arrays of strings that represent the rows. public static void FormatAndAlignTable(List data) { - char tableLine = '-'; + char tableLine = '-'; char tableCross = '+'; - char tableWall = '|'; + char tableWall = '|'; int[] len = new int[data[0].Length]; foreach (var line in data) diff --git a/PluginManager/Others/Functions.cs b/PluginManager/Others/Functions.cs index 5f6fb5f..0baf0c1 100644 --- a/PluginManager/Others/Functions.cs +++ b/PluginManager/Others/Functions.cs @@ -97,31 +97,6 @@ namespace PluginManager.Others File.AppendAllText(errPath, ErrMessage + " \n"); } - /// - /// Write to settings file - /// - /// The settings file path - /// The Key value of the setting - /// The new value of the settings - /// The separator between the key and the value - public static void WriteToSettings(string file, string Code, string newValue, char separator) - { - - string[] lines = File.ReadAllLines(file); - File.Delete(file); - bool ok = false; - foreach (var line in lines) - if (line.StartsWith(Code)) - { - File.AppendAllText(file, Code + separator + newValue + "\n"); - ok = true; - } - else - File.AppendAllText(file, line + "\n"); - - if (!ok) File.AppendAllText(file, Code + separator + newValue + "\n"); - } - /// /// Merge one array of strings into one string /// @@ -161,29 +136,6 @@ namespace PluginManager.Others return command.Arguments; } - - /// - /// Write setting - /// - /// The full path to the setting - /// The new Value - public static void WriteToSettingsFast(string SettingName, string NewValue) - { - - string path = dataFolder; // Resources/ - - string[] args = SettingName.Split('.'); - - int len = args.Length; - if (len < 2) return; - for (int i = 0; i < len - 2; i++) path += args[i] + "/"; - path += args[len - 2] + ".txt"; - - - WriteToSettings(path, args[len - 1].Replace('_', ' '), NewValue, '='); - - } - /// /// Copy one Stream to another /// @@ -253,6 +205,11 @@ namespace PluginManager.Others } + /// + /// Convert Bytes to highest measurement unit possible + /// + /// The amount of bytes + /// public static (double, string) ConvertBytes(long bytes) { if (bytes < 1024) return (bytes, "B"); @@ -262,12 +219,25 @@ namespace PluginManager.Others } + /// + /// Save to JSON file + /// + /// The class type + /// The file path + /// The values + /// public static async Task SaveToJsonFile(string file, T Data) { - string jsonText = JsonSerializer.Serialize(Data, typeof(T), new JsonSerializerOptions() { WriteIndented = true }); + string jsonText = JsonSerializer.Serialize(Data, typeof(T), new JsonSerializerOptions { WriteIndented = true }); await File.WriteAllTextAsync(file, jsonText); } + /// + /// Convert json text or file to some kind of data + /// + /// The data type + /// The file or json text + /// public static async Task ConvertFromJson(string input) { Stream text; From fd28a166f7d3f74cc3b2f652511f99f877e27ef8 Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Sun, 5 Jun 2022 18:25:30 +0300 Subject: [PATCH 11/20] --- DiscordBot/Discord/Core/Boot.cs | 12 ------------ DiscordBot/DiscordBot.csproj | 10 ++++++++++ DiscordBot/Program.cs | 2 -- DiscordBotGUI/AppUpdater.axaml.cs | 2 +- DiscordBotGUI/MainWindow.axaml.cs | 4 ++-- PluginManager/Config.cs | 5 ++--- 6 files changed, 15 insertions(+), 20 deletions(-) diff --git a/DiscordBot/Discord/Core/Boot.cs b/DiscordBot/Discord/Core/Boot.cs index 14f30c8..942178f 100644 --- a/DiscordBot/Discord/Core/Boot.cs +++ b/DiscordBot/Discord/Core/Boot.cs @@ -5,7 +5,6 @@ using System; using System.Threading; using System.Threading.Tasks; using PluginManager; -using PluginManager.Others; using static PluginManager.Others.Functions; namespace DiscordBot.Discord.Core @@ -77,17 +76,6 @@ namespace DiscordBot.Discord.Core } - /// - /// The method that stops the bot from running - /// - /// - public async Task ShutDown() - { - if (client == null) return; - await client.LogoutAsync(); - await client.StopAsync(); - } - private void CommonTasks() { if (client == null) return; diff --git a/DiscordBot/DiscordBot.csproj b/DiscordBot/DiscordBot.csproj index 37fb607..f83d305 100644 --- a/DiscordBot/DiscordBot.csproj +++ b/DiscordBot/DiscordBot.csproj @@ -6,6 +6,16 @@ disable + False + True + + + + none + + + + none diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index f31fda2..c14a884 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -50,9 +50,7 @@ namespace DiscordBot char prefix = Console.ReadLine()[0]; if (prefix == ' ' || char.IsDigit(prefix)) continue; - Config.AddValueToVariables("prefix", prefix.ToString(), false); - break; } diff --git a/DiscordBotGUI/AppUpdater.axaml.cs b/DiscordBotGUI/AppUpdater.axaml.cs index 2295319..bf06532 100644 --- a/DiscordBotGUI/AppUpdater.axaml.cs +++ b/DiscordBotGUI/AppUpdater.axaml.cs @@ -153,7 +153,7 @@ namespace DiscordBotGUI string current_version = Config.GetValue("Version"); if (current_version == null) if (!Config.SetValue("Version", "0")) - Config.AddValueToVariables("Version", "0"); + Config.AddValueToVariables("Version", "0", false); string latest_version = (await ServerCom.ReadTextFromFile("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Updates/Version"))[0]; _version = latest_version; if (current_version != latest_version) { return true; } diff --git a/DiscordBotGUI/MainWindow.axaml.cs b/DiscordBotGUI/MainWindow.axaml.cs index 52f379f..43ad182 100644 --- a/DiscordBotGUI/MainWindow.axaml.cs +++ b/DiscordBotGUI/MainWindow.axaml.cs @@ -42,8 +42,8 @@ namespace DiscordBotGUI return; } - Functions.WriteToSettings(Functions.dataFolder + "DiscordBotCore.data", "BOT_TOKEN", token, '='); - Functions.WriteToSettings(Functions.dataFolder + "DiscordBotCore.data", "BOT_PREFIX", prefix, '='); + Config.SetValue("token", token); + Config.SetValue("prefix", prefix); RunDiscordBot(args); }; diff --git a/PluginManager/Config.cs b/PluginManager/Config.cs index dee04ae..4c35991 100644 --- a/PluginManager/Config.cs +++ b/PluginManager/Config.cs @@ -17,11 +17,11 @@ namespace PluginManager { private static AppConfig appConfig = null; - public static bool AddValueToVariables(string key, string value, bool isReadOnly) + public static bool AddValueToVariables(string key, string value, bool isProtected) { if (appConfig.ApplicationVariables.ContainsKey(key)) return false; appConfig.ApplicationVariables.Add(key, value); - if (isReadOnly) appConfig.ProtectedKeyWords.Add(key); + if (isProtected) appConfig.ProtectedKeyWords.Add(key); SaveConfig(); return true; } @@ -61,7 +61,6 @@ namespace PluginManager { appConfig = await Functions.ConvertFromJson(path); Functions.WriteLogFile($"Loaded {appConfig.ApplicationVariables.Keys.Count} application variables.\nLoaded {appConfig.ProtectedKeyWords.Count} readonly variables."); - //Console.WriteLine($"Loaded {appConfig.ApplicationVariables.Count} application variables !"); } else appConfig = new() { ApplicationVariables = new Dictionary(), ProtectedKeyWords = new List() }; From c15f7b48741c173f17c2b99f998639a1e9717e8c Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Sun, 5 Jun 2022 20:50:01 +0300 Subject: [PATCH 12/20] --- DiscordBotGUI/AppUpdater.axaml.cs | 2 -- README.md | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DiscordBotGUI/AppUpdater.axaml.cs b/DiscordBotGUI/AppUpdater.axaml.cs index bf06532..f678f47 100644 --- a/DiscordBotGUI/AppUpdater.axaml.cs +++ b/DiscordBotGUI/AppUpdater.axaml.cs @@ -1,6 +1,4 @@ -using Avalonia; using Avalonia.Controls; -using Avalonia.Markup.Xaml; using PluginManager.Online; using PluginManager.Others; using System.Threading.Tasks; diff --git a/README.md b/README.md index 1c1fd58..ff155a7 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ Plugin Types: 1. Commands 2. Events +Project Structure +![Image](../../blob/gh-pages/Pictures/architecture.png) ### How to create a plugin From 16005ef30d7ab4f546d769fb9c918a256a970dd4 Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Sun, 5 Jun 2022 20:55:33 +0300 Subject: [PATCH 13/20] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ff155a7..507cb1f 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Plugin Types: 2. Events Project Structure -![Image](../../blob/gh-pages/Pictures/architecture.png) +![Image](../../blob/gh-pages/Pictures/architecture2.png) ### How to create a plugin From 195c082cd756f00a65afd739ffb495cb7f8df802 Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Sun, 5 Jun 2022 21:02:04 +0300 Subject: [PATCH 14/20] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 507cb1f..5aee53e 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Plugin Types: 2. Events Project Structure + ![Image](../../blob/gh-pages/Pictures/architecture2.png) ### How to create a plugin From c66ff52d94dc30af5a3fbc25d9a5cc8472905353 Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Tue, 7 Jun 2022 11:13:03 +0300 Subject: [PATCH 15/20] --- DiscordBot/Program.cs | 14 ++++-- DiscordBotGUI/AppUpdater.axaml.cs | 1 + DiscordBotGUI/MainWindow.axaml | 3 +- DiscordBotGUI/MainWindow.axaml.cs | 8 ++-- .../Settings/ApplicationVariables.axaml | 23 ++++++++++ .../Settings/ApplicationVariables.axaml.cs | 44 ++++++++++++++++++ PluginManager/Config.cs | 24 ++++++---- PluginManager/Items/ConsoleCommandsHandler.cs | 45 ++++++++++++++----- 8 files changed, 131 insertions(+), 31 deletions(-) create mode 100644 DiscordBotGUI/Settings/ApplicationVariables.axaml create mode 100644 DiscordBotGUI/Settings/ApplicationVariables.axaml.cs diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index c14a884..28d6370 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -3,7 +3,6 @@ using PluginManager; using PluginManager.Items; using PluginManager.Others; using System; -using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -29,7 +28,14 @@ namespace DiscordBot Directory.CreateDirectory("./Data/Plugins/Commands"); Directory.CreateDirectory("./Data/Plugins/Events"); Config.LoadConfig().Wait(); - if (!Config.ContainsKey("token") || Config.GetValue("token") == null || Config.GetValue("token")?.Length != 70) + + if (Config.ContainsKey("DeleteLogsAtStartup")) + if (Config.GetValue("DeleteLogsAtStartup")) + foreach (string file in Directory.GetFiles("./Output/Logs/")) + File.Delete(file); + + + if (!Config.ContainsKey("token") || Config.GetValue("token") == null || Config.GetValue("token")?.Length != 70) { while (true) { @@ -101,8 +107,8 @@ namespace DiscordBot Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("============================ Discord BOT - Cross Platform ============================"); - string token = Config.GetValue("token"); - string prefix = Config.GetValue("prefix"); + string token = Config.GetValue("token"); + string prefix = Config.GetValue("prefix"); var discordbooter = new Boot(token, prefix); await discordbooter.Awake(); diff --git a/DiscordBotGUI/AppUpdater.axaml.cs b/DiscordBotGUI/AppUpdater.axaml.cs index f678f47..662e2c8 100644 --- a/DiscordBotGUI/AppUpdater.axaml.cs +++ b/DiscordBotGUI/AppUpdater.axaml.cs @@ -16,6 +16,7 @@ namespace DiscordBotGUI public AppUpdater() { InitializeComponent(); + Config.LoadConfig().Wait(); if (!File.Exists("./Version.txt")) { File.WriteAllText("./Version.txt", "DiscordBotVersion=0"); diff --git a/DiscordBotGUI/MainWindow.axaml b/DiscordBotGUI/MainWindow.axaml index 43854e9..b3f98c7 100644 --- a/DiscordBotGUI/MainWindow.axaml +++ b/DiscordBotGUI/MainWindow.axaml @@ -14,7 +14,8 @@ - + + public class ProgressBar { - public int Max { get; set; } - public string Message { get; set; } + public int Max { get; init; } public ConsoleColor Color { get; init; } + public bool NoColor { get; init; } - public ProgressBar(int max, string message) - { - Max = max; - Message = message; - var consoleColors = Enum.GetValues(typeof(ConsoleColor)); - while ((Color = (ConsoleColor)consoleColors.GetValue(new Random().Next(consoleColors.Length))!) == ConsoleColor.White && Color != ConsoleColor.Black) ; - } - public void Update(int progress, double speed = -1, string? unit = null) { - - //progress bar Console.CursorLeft = 0; Console.Write("["); Console.CursorLeft = 32; @@ -38,15 +28,21 @@ namespace PluginManager.Others for (int i = 0; i < onechunk * progress; i++) { - Console.BackgroundColor = this.Color; + if (NoColor) + Console.BackgroundColor = ConsoleColor.Black; //this.Color + else + Console.BackgroundColor = this.Color; Console.CursorLeft = position++; - Console.Write(" "); + Console.Write("#"); } for (int i = position; i <= 31; i++) { - Console.BackgroundColor = ConsoleColor.Gray; - Console.CursorLeft = position++; + if (NoColor) + Console.BackgroundColor = ConsoleColor.Black; // background of empty bar + else + Console.BackgroundColor = ConsoleColor.DarkGray; + Console.CursorLeft = position++; Console.Write(" "); } diff --git a/PluginManager/Others/Cryptography.cs b/PluginManager/Others/Cryptography.cs index e2c13de..04864ae 100644 --- a/PluginManager/Others/Cryptography.cs +++ b/PluginManager/Others/Cryptography.cs @@ -1,91 +1,88 @@ using System; +using System.IO; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; -namespace PluginManager.Others +namespace PluginManager.Others; + +public class Cryptography { - public class Cryptography + /// + /// Translate hex to string + /// + /// The encrypted string + /// + public static string FromHexToString(string hexString) { + var bytes = new byte[hexString.Length / 2]; + for (var i = 0; i < bytes.Length; i++) bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); - /// - /// Translate hex to string - /// - /// The encrypted string - /// - public static string FromHexToString(string hexString) - { - var bytes = new byte[hexString.Length / 2]; - for (var i = 0; i < bytes.Length; i++) - { - bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); - } - - return System.Text.Encoding.Unicode.GetString(bytes); - } - - /// - /// Translate string to hex - /// - /// The string to encrypt - /// - public static string ToHexString(string str) - { - var sb = new System.Text.StringBuilder(); - - var bytes = System.Text.Encoding.Unicode.GetBytes(str); - foreach (var t in bytes) - { - sb.Append(t.ToString("X2")); - } - - return sb.ToString(); - } - - /// - /// Create MD5 hash - /// - /// The text to encrypt - /// - public static async System.Threading.Tasks.Task CreateMD5(string text) - { - string output = ""; - using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create()) - { - using (var s = GenerateStreamFromString(text)) - { - byte[] t = await md5.ComputeHashAsync(s); - output = System.Convert.ToBase64String(t); - } - } - - return output; - } - - /// - /// Create SHA256 hash - /// - /// The text to encrypt - /// - public static async System.Threading.Tasks.Task CreateSHA256(string text) - { - string output = ""; - using (System.Security.Cryptography.SHA256 sha = System.Security.Cryptography.SHA256.Create()) - { - using (var s = GenerateStreamFromString(text)) - { - byte[] t = await sha.ComputeHashAsync(s); - output = System.Convert.ToBase64String(t); - } - } - return output; - } - - private static System.IO.Stream GenerateStreamFromString(string s) - { - var stream = new System.IO.MemoryStream(); - var writer = new System.IO.StreamWriter(stream); - writer.Write(s); - writer.Flush(); - stream.Position = 0; - return stream; - } + return Encoding.Unicode.GetString(bytes); } -} \ No newline at end of file + + /// + /// Translate string to hex + /// + /// The string to encrypt + /// + public static string ToHexString(string str) + { + var sb = new StringBuilder(); + + var bytes = Encoding.Unicode.GetBytes(str); + foreach (var t in bytes) sb.Append(t.ToString("X2")); + + return sb.ToString(); + } + + /// + /// Create MD5 hash + /// + /// The text to encrypt + /// + public static async Task CreateMD5(string text) + { + var output = ""; + using (var md5 = MD5.Create()) + { + using (var s = GenerateStreamFromString(text)) + { + var t = await md5.ComputeHashAsync(s); + output = Convert.ToBase64String(t); + } + } + + return output; + } + + /// + /// Create SHA256 hash + /// + /// The text to encrypt + /// + public static async Task CreateSHA256(string text) + { + var output = ""; + using (var sha = SHA256.Create()) + { + using (var s = GenerateStreamFromString(text)) + { + var t = await sha.ComputeHashAsync(s); + output = Convert.ToBase64String(t); + } + } + + return output; + } + + private static Stream GenerateStreamFromString(string s) + { + var stream = new MemoryStream(); + var writer = new StreamWriter(stream); + writer.Write(s); + writer.Flush(); + stream.Position = 0; + return stream; + } +} diff --git a/PluginManager/Others/Enums.cs b/PluginManager/Others/Enums.cs index 222e169..d8b22fb 100644 --- a/PluginManager/Others/Enums.cs +++ b/PluginManager/Others/Enums.cs @@ -1,20 +1,22 @@ -namespace PluginManager.Others +namespace PluginManager.Others; + +/// +/// A list of operating systems +/// +public enum OperatingSystem { + WINDOWS, LINUX, MAC_OS, UNKNOWN +} - /// - /// A list of operating systems - /// - public enum OperatingSystem - { WINDOWS, LINUX, MAC_OS, UNKNOWN } +/// +/// A list with all errors +/// +public enum Error +{ + UNKNOWN_ERROR, GUILD_NOT_FOUND, STREAM_NOT_FOUND, INVALID_USER, INVALID_CHANNEL, INVALID_PERMISSIONS +} - /// - /// A list with all errors - /// - public enum Error - { UNKNOWN_ERROR, GUILD_NOT_FOUND, STREAM_NOT_FOUND, INVALID_USER, INVALID_CHANNEL, INVALID_PERMISSIONS } - - /// - /// The output log type - /// - public enum OutputLogLevel { NONE, INFO, WARNING, ERROR, CRITICAL } -} \ No newline at end of file +/// +/// The output log type +/// +public enum OutputLogLevel { NONE, INFO, WARNING, ERROR, CRITICAL } diff --git a/PluginManager/Others/Exceptions/APIException.cs b/PluginManager/Others/Exceptions/APIException.cs index 990704f..37264c1 100644 --- a/PluginManager/Others/Exceptions/APIException.cs +++ b/PluginManager/Others/Exceptions/APIException.cs @@ -1,94 +1,91 @@ using System; -namespace PluginManager.Others.Exceptions +namespace PluginManager.Others.Exceptions; + +/// +/// Custom Exception for PluginManager +/// +[Serializable] +public class APIException : Exception { /// - /// Custom Exception for PluginManager + /// The APIException contructor /// - [Serializable] - - public class APIException : Exception + /// The error message + /// The function where the message was triggered + /// The possible cause of the error + /// The error code + public APIException(string message, string? function, string possible_cause, Error error) : base(message) { - /// - /// The function where the error occurred - /// - public string? Function { get; } = "not specified"; - - /// - /// The error code - /// - public Error? ErrorCode { get; } = Error.UNKNOWN_ERROR; - - /// - /// The possible cause that determined the error - /// - public string? PossibleCause { get; } = "not specified"; - - /// - /// The APIException contructor - /// - /// The error message - /// The function where the message was triggered - /// The possible cause of the error - /// The error code - public APIException(string message, string? function, string possible_cause, Error error) : base(message) - { - ErrorCode = error; - Function = function; - PossibleCause = possible_cause; - } - - /// - /// The APIException contructor - /// - /// The error message - /// The function where the message was triggered - /// The error code - public APIException(string message, string? function, Error? errorCode) : base(message) - { - ErrorCode = errorCode; - Function = function; - } - /// - /// The APIException contructor - /// - /// The error message - /// The function where the message was triggered - public APIException(string message, string? function) : base(message) - { - Function = function; - } - /// - /// The APIException contructor - /// - /// The error message - public APIException(string message) : base(message) - { - - } - - /// - /// The APIException constructor - /// - /// The error message - /// The class where the error was thrown - public APIException(string message, Type errorLocation) : base(message) - { - Function = errorLocation.FullName; - } - - /// - /// Method to print the error to - /// - public void Print() - { - Console.WriteLine("Message Content: " + Message); - Console.WriteLine("Function: " + Function); - Console.WriteLine("Error Code: " + ErrorCode.ToString()); - Console.WriteLine("Possible cause: " + PossibleCause); - if (this.StackTrace != null) - Functions.WriteErrFile(this.StackTrace); - } + ErrorCode = error; + Function = function; + PossibleCause = possible_cause; } -} \ No newline at end of file + /// + /// The APIException contructor + /// + /// The error message + /// The function where the message was triggered + /// The error code + public APIException(string message, string? function, Error? errorCode) : base(message) + { + ErrorCode = errorCode; + Function = function; + } + + /// + /// The APIException contructor + /// + /// The error message + /// The function where the message was triggered + public APIException(string message, string? function) : base(message) + { + Function = function; + } + + /// + /// The APIException contructor + /// + /// The error message + public APIException(string message) : base(message) + { + } + + /// + /// The APIException constructor + /// + /// The error message + /// The class where the error was thrown + public APIException(string message, Type errorLocation) : base(message) + { + Function = errorLocation.FullName; + } + + /// + /// The function where the error occurred + /// + public string? Function { get; } = "not specified"; + + /// + /// The error code + /// + public Error? ErrorCode { get; } = Error.UNKNOWN_ERROR; + + /// + /// The possible cause that determined the error + /// + public string? PossibleCause { get; } = "not specified"; + + /// + /// Method to print the error to + /// + public void Print() + { + Console.WriteLine("Message Content: " + Message); + Console.WriteLine("Function: " + Function); + Console.WriteLine("Error Code: " + ErrorCode); + Console.WriteLine("Possible cause: " + PossibleCause); + if (StackTrace != null) Functions.WriteErrFile(StackTrace); + } +} diff --git a/PluginManager/Others/Functions.cs b/PluginManager/Others/Functions.cs index 0baf0c1..93e85d9 100644 --- a/PluginManager/Others/Functions.cs +++ b/PluginManager/Others/Functions.cs @@ -212,11 +212,22 @@ namespace PluginManager.Others /// public static (double, string) ConvertBytes(long bytes) { - if (bytes < 1024) return (bytes, "B"); - if (bytes < 1024 * 1024) return (bytes / 1024.0, "KB"); - if (bytes < 1024 * 1024 * 1024) return (bytes / 1024.0 / 1024.0, "MB"); - return (bytes / 1024.0 / 1024.0 / 1024.0, "GB"); + List units = new List() + { + "B", + "KB", + "MB", + "GB", + "TB" + }; + int i = 0; + while (bytes >= 1024) + { + i++; + bytes /= 1024; + } + return (bytes, units[i]); } /// diff --git a/PluginManager/Others/Permissions/DiscordPermissions.cs b/PluginManager/Others/Permissions/DiscordPermissions.cs index be55780..e8fae3b 100644 --- a/PluginManager/Others/Permissions/DiscordPermissions.cs +++ b/PluginManager/Others/Permissions/DiscordPermissions.cs @@ -1,55 +1,64 @@ -using Discord; +using System.Linq; +using Discord; using Discord.WebSocket; -using System.Linq; +namespace PluginManager.Others.Permissions; -namespace PluginManager.Others.Permissions +/// +/// A class whith all discord permissions +/// +public static class DiscordPermissions { /// - /// A class whith all discord permissions + /// Checks if the role has the specified permission /// - public static class DiscordPermissions + /// The role + /// The permission + /// + public static bool hasPermission(this IRole role, GuildPermission permission) { - /// - /// Checks if the role has the specified permission - /// - /// The role - /// The permission - /// - public static bool hasPermission(this IRole role, GuildPermission permission) => role.Permissions.Has(permission); - - /// - /// Check if user has the specified role - /// - /// The user - /// The role - /// - public static bool hasRole(this SocketGuildUser user, IRole role) => user.Roles.Contains(role); - - /// - /// Check if user has the specified permission - /// - /// The user - /// The permission - /// - public static bool hasPermission(this SocketGuildUser user, GuildPermission permission) - => user.Roles.Where(role => role.hasPermission(permission)).Any() || user.Guild.Owner == user; - /// - /// Check if user is administrator of server - /// - /// The user - /// - public static bool isAdmin(this SocketGuildUser user) => user.hasPermission(GuildPermission.Administrator); - - /// - /// Check if user is administrator of server - /// - /// The user - /// - public static bool isAdmin(this SocketUser user) => isAdmin((SocketGuildUser)user); + return role.Permissions.Has(permission); } + /// + /// Check if user has the specified role + /// + /// The user + /// The role + /// + public static bool hasRole(this SocketGuildUser user, IRole role) + { + return user.Roles.Contains(role); + } + /// + /// Check if user has the specified permission + /// + /// The user + /// The permission + /// + public static bool hasPermission(this SocketGuildUser user, GuildPermission permission) + { + return user.Roles.Where(role => role.hasPermission(permission)).Any() || user.Guild.Owner == user; + } + /// + /// Check if user is administrator of server + /// + /// The user + /// + public static bool isAdmin(this SocketGuildUser user) + { + return user.hasPermission(GuildPermission.Administrator); + } -} \ No newline at end of file + /// + /// Check if user is administrator of server + /// + /// The user + /// + public static bool isAdmin(this SocketUser user) + { + return isAdmin((SocketGuildUser)user); + } +} From 51324f6dca1a80e87a16ffd4ee36871bd607882f Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Wed, 8 Jun 2022 19:59:58 +0300 Subject: [PATCH 17/20] --- CMD_LevelingSystem/Level.cs | 6 +++++ CMD_LevelingSystem/User.cs | 19 ++++++++++---- DiscordBot/Program.cs | 1 - EVE_LevelingSystem/Level.cs | 7 +++--- .../LevelingSystemCore/LevelCalculator.cs | 6 ++--- EVE_LevelingSystem/LevelingSystemCore/User.cs | 25 +++++++++++++------ PluginManager/Config.cs | 1 + PluginManager/Others/Functions.cs | 3 +-- 8 files changed, 47 insertions(+), 21 deletions(-) diff --git a/CMD_LevelingSystem/Level.cs b/CMD_LevelingSystem/Level.cs index 22f30e3..e11fd3f 100644 --- a/CMD_LevelingSystem/Level.cs +++ b/CMD_LevelingSystem/Level.cs @@ -23,6 +23,12 @@ internal class Level : DBCommand public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) { + if (!File.Exists(Config.GetValue("LevelingSystemPath") + $"/{message.Author.Id}.dat")) + { + await context.Channel.SendMessageAsync("You are now unranked !"); + return; + } + var user = await Functions.ConvertFromJson(Config.GetValue("LevelingSystemPath") + $"/{message.Author.Id}.dat"); if (user == null) { diff --git a/CMD_LevelingSystem/User.cs b/CMD_LevelingSystem/User.cs index 1b0736a..bf26b87 100644 --- a/CMD_LevelingSystem/User.cs +++ b/CMD_LevelingSystem/User.cs @@ -1,9 +1,18 @@ -namespace CMD_LevelingSystem; +using Discord.WebSocket; + +namespace CMD_LevelingSystem; + +public class DiscordUser +{ + public string Username { get; set; } + public ushort DiscordTag { get; set; } + public ulong userID { get; set; } +} public class User { - public string userID { get; set; } - public int CurrentLevel { get; set; } - public long CurrentEXP { get; set; } - public long RequiredEXPToLevelUp { get; set; } + public DiscordUser user { get; set; } + public int CurrentLevel { get; set; } + public long CurrentEXP { get; set; } + public long RequiredEXPToLevelUp { get; set; } } diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index 909558e..1414f89 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -23,7 +23,6 @@ namespace DiscordBot public static void Main(string[] args) { Directory.CreateDirectory("./Data/Resources"); - Directory.CreateDirectory("./Data/Languages"); Directory.CreateDirectory("./Data/Plugins/Commands"); Directory.CreateDirectory("./Data/Plugins/Events"); PreLoadComponents(); diff --git a/EVE_LevelingSystem/Level.cs b/EVE_LevelingSystem/Level.cs index 202ae2a..f4a9c6b 100644 --- a/EVE_LevelingSystem/Level.cs +++ b/EVE_LevelingSystem/Level.cs @@ -1,4 +1,5 @@ -using Discord.WebSocket; +using Discord; +using Discord.WebSocket; using EVE_LevelingSystem.LevelingSystemCore; using PluginManager; using PluginManager.Interfaces; @@ -45,9 +46,9 @@ namespace EVE_LevelingSystem return; } - user = new User() { CurrentEXP = 0, CurrentLevel = 1, RequiredEXPToLevelUp = LevelCalculator.GetNextLevelRequiredEXP(1), userID = userID }; + user = new User { CurrentEXP = 0, CurrentLevel = 1, RequiredEXPToLevelUp = LevelCalculator.GetNextLevelRequiredEXP(1), user = new DiscordUser { DiscordTag = arg.Author.DiscriminatorValue, userID = arg.Author.Id, Username = arg.Author.Username } }; if (user.AddEXP()) await arg.Channel.SendMessageAsync($"{arg.Author.Mention} is now level {user.CurrentLevel}"); - await Functions.SaveToJsonFile($"{Config.GetValue("LevelingSystemPath")}/{userID}.dat", user); + await Functions.SaveToJsonFile($"{Config.GetValue("LevelingSystemPath")}/{userID}.dat", user); } } } diff --git a/EVE_LevelingSystem/LevelingSystemCore/LevelCalculator.cs b/EVE_LevelingSystem/LevelingSystemCore/LevelCalculator.cs index 62c6d1c..733adac 100644 --- a/EVE_LevelingSystem/LevelingSystemCore/LevelCalculator.cs +++ b/EVE_LevelingSystem/LevelingSystemCore/LevelCalculator.cs @@ -25,7 +25,7 @@ namespace EVE_LevelingSystem.LevelingSystemCore internal static bool AddEXP(this User user) { - if (OnWaitingList.Contains(user.userID)) return false; + if (OnWaitingList.Contains(user.user.userID.ToString())) return false; Random r = new Random(); int exp = r.Next(2, 12); Int64 userXP = user.CurrentEXP; @@ -40,14 +40,14 @@ namespace EVE_LevelingSystem.LevelingSystemCore user.CurrentEXP += exp; - OnWaitingList.Add(user.userID); + OnWaitingList.Add(user.user.userID.ToString()); new Thread(() => { int minutesToWait = Level.globalSettings.TimeToWaitBetweenMessages; Thread.Sleep(60000 * minutesToWait); - OnWaitingList.Remove(user.userID); + OnWaitingList.Remove(user.user.userID.ToString()); } ); diff --git a/EVE_LevelingSystem/LevelingSystemCore/User.cs b/EVE_LevelingSystem/LevelingSystemCore/User.cs index 3a11227..b857392 100644 --- a/EVE_LevelingSystem/LevelingSystemCore/User.cs +++ b/EVE_LevelingSystem/LevelingSystemCore/User.cs @@ -1,9 +1,20 @@ -namespace EVE_LevelingSystem.LevelingSystemCore; +using Discord; +using Discord.WebSocket; -public class User +namespace EVE_LevelingSystem.LevelingSystemCore { - public string userID { get; set; } - public int CurrentLevel { get; set; } - public long CurrentEXP { get; set; } - public long RequiredEXPToLevelUp { get; set; } -} + public class DiscordUser + { + public string Username { get; set; } + public ushort DiscordTag { get; set; } + public ulong userID { get; set; } + } + + public class User + { + public DiscordUser user { get; set; } + public int CurrentLevel { get; set; } + public long CurrentEXP { get; set; } + public long RequiredEXPToLevelUp { get; set; } + } +} \ No newline at end of file diff --git a/PluginManager/Config.cs b/PluginManager/Config.cs index 981e791..04193ed 100644 --- a/PluginManager/Config.cs +++ b/PluginManager/Config.cs @@ -61,6 +61,7 @@ namespace PluginManager } public static async Task LoadConfig() + { string path = Functions.dataFolder + "var.dat"; if (File.Exists(path)) diff --git a/PluginManager/Others/Functions.cs b/PluginManager/Others/Functions.cs index 93e85d9..0857eb1 100644 --- a/PluginManager/Others/Functions.cs +++ b/PluginManager/Others/Functions.cs @@ -239,8 +239,7 @@ namespace PluginManager.Others /// public static async Task SaveToJsonFile(string file, T Data) { - string jsonText = JsonSerializer.Serialize(Data, typeof(T), new JsonSerializerOptions { WriteIndented = true }); - await File.WriteAllTextAsync(file, jsonText); + using (var s = File.OpenWrite(file)) await JsonSerializer.SerializeAsync(s, Data, typeof(T), new JsonSerializerOptions { WriteIndented = true }); } /// From 17122052222f4de3901f6e2a4c3d81261f369145 Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Wed, 8 Jun 2022 20:45:25 +0300 Subject: [PATCH 18/20] --- .../.idea.DiscordBotWithAPI/.idea/.gitignore | 13 ------ .../.idea/avalonia.xml | 13 ------ .../.idea/encodings.xml | 4 -- .../.idea/indexLayout.xml | 8 ---- .idea/.idea.DiscordBotWithAPI/.idea/vcs.xml | 6 --- DiscordBot/Program.cs | 42 ++++++++----------- PluginManager/Config.cs | 18 +++++--- 7 files changed, 30 insertions(+), 74 deletions(-) delete mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/.gitignore delete mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml delete mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/encodings.xml delete mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml delete mode 100644 .idea/.idea.DiscordBotWithAPI/.idea/vcs.xml diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/.gitignore b/.idea/.idea.DiscordBotWithAPI/.idea/.gitignore deleted file mode 100644 index 1e2399a..0000000 --- a/.idea/.idea.DiscordBotWithAPI/.idea/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Rider ignored files -/modules.xml -/contentModel.xml -/.idea.DiscordBotWithAPI.iml -/projectSettingsUpdater.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml b/.idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml deleted file mode 100644 index c0fdb9d..0000000 --- a/.idea/.idea.DiscordBotWithAPI/.idea/avalonia.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/encodings.xml b/.idea/.idea.DiscordBotWithAPI/.idea/encodings.xml deleted file mode 100644 index df87cf9..0000000 --- a/.idea/.idea.DiscordBotWithAPI/.idea/encodings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml b/.idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml deleted file mode 100644 index 7b08163..0000000 --- a/.idea/.idea.DiscordBotWithAPI/.idea/indexLayout.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/.idea.DiscordBotWithAPI/.idea/vcs.xml b/.idea/.idea.DiscordBotWithAPI/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/.idea.DiscordBotWithAPI/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index 1414f89..00aadb4 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -25,7 +25,7 @@ namespace DiscordBot Directory.CreateDirectory("./Data/Resources"); Directory.CreateDirectory("./Data/Plugins/Commands"); Directory.CreateDirectory("./Data/Plugins/Events"); - PreLoadComponents(); + PreLoadComponents().Wait(); if (!Config.ContainsKey("token") || Config.GetValue("token") == null || Config.GetValue("token")?.Length != 70) { @@ -45,7 +45,7 @@ namespace DiscordBot Console.WriteLine("Please insert your prefix (max. 1 character long):"); Console.WriteLine("For a prefix longer then one character, the first character will be saved and the others will be ignored. No spaces or numbers allowed"); Console.Write("Prefix = "); - char prefix = Console.ReadLine()[0]; + char prefix = Console.ReadLine()![0]; if (prefix == ' ' || char.IsDigit(prefix)) continue; Config.AddValueToVariables("prefix", prefix.ToString(), false); @@ -58,15 +58,6 @@ namespace DiscordBot HandleInput(args).Wait(); } - /// - /// Reset all settings for the bot - /// - private static async Task ResetSettings() - { - string[] files = Directory.GetFiles(@"./Data/Resources"); - foreach (string file in files) File.Delete(file); - } - /// /// The main loop for the discord bot /// @@ -98,12 +89,21 @@ namespace DiscordBot Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("============================ Discord BOT - Cross Platform ============================"); - string token = Config.GetValue("token"); - string prefix = Config.GetValue("prefix"); - var discordbooter = new Boot(token, prefix); - await discordbooter.Awake(); - return discordbooter; + try + { + string token = Config.GetValue("token"); + string prefix = Config.GetValue("prefix"); + + var discordbooter = new Boot(token, prefix); + await discordbooter.Awake(); + return discordbooter; + } + catch (Exception ex) + { + Console.WriteLine(ex); + return null; + } } /// @@ -138,7 +138,7 @@ namespace DiscordBot if (len == 1 && args[0] == "--logout") { - File.Delete(Functions.dataFolder + "var.dat"); + File.Delete(Functions.dataFolder + "config.json"); await Task.Run(async () => { await Task.Delay(1000); @@ -188,7 +188,6 @@ namespace DiscordBot "\tCommand name\t\t\t\tDescription\n" + "-- help | -help\t\t ------ \tDisplay the help message\n" + "--reset-full\t\t ------ \tReset all files (clear files)\n" + - "--reset-settings\t ------ \tReset only bot settings\n" + "--reset-logs\t\t ------ \tClear up the output folder\n" + "--start\t\t ------ \tStart the bot\n" + "exit\t\t\t ------ \tClose the application" @@ -201,10 +200,6 @@ namespace DiscordBot switch (message[0]) { - case "--reset-settings": - await ResetSettings(); - Console.WriteLine("Successfully reseted all settings !"); - break; case "--help": case "-help": Console.ForegroundColor = ConsoleColor.DarkYellow; @@ -250,8 +245,7 @@ namespace DiscordBot private static async Task PreLoadComponents() { - Config.LoadConfig().Wait(); - + await Config.LoadConfig(); if (Config.ContainsKey("DeleteLogsAtStartup")) if (Config.GetValue("DeleteLogsAtStartup")) foreach (string file in Directory.GetFiles("./Output/Logs/")) diff --git a/PluginManager/Config.cs b/PluginManager/Config.cs index 04193ed..d6cb269 100644 --- a/PluginManager/Config.cs +++ b/PluginManager/Config.cs @@ -1,5 +1,4 @@ -using System; -using PluginManager.Others; +using PluginManager.Others; using System.Collections.Generic; using System.IO; using System.Linq; @@ -31,8 +30,15 @@ namespace PluginManager public static T? GetValue(string key) { if (!appConfig.ApplicationVariables.ContainsKey(key)) return default; - JsonElement element = (JsonElement)appConfig.ApplicationVariables[key]; - return element.Deserialize(); + try + { + JsonElement element = (JsonElement)appConfig.ApplicationVariables[key]; + return element.Deserialize(); + } + catch + { + return (T)appConfig.ApplicationVariables[key]; + } } public static bool SetValue(string key, T value) @@ -56,14 +62,14 @@ namespace PluginManager public static async void SaveConfig() { - string path = Functions.dataFolder + "var.dat"; + string path = Functions.dataFolder + "config.json"; await Functions.SaveToJsonFile(path, appConfig); } public static async Task LoadConfig() { - string path = Functions.dataFolder + "var.dat"; + string path = Functions.dataFolder + "config.json"; if (File.Exists(path)) { appConfig = await Functions.ConvertFromJson(path); From 781bb489bdfb1a9d8698d65703df1ca5d3bace5e Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Wed, 8 Jun 2022 21:00:48 +0300 Subject: [PATCH 19/20] --- DiscordBot/Program.cs | 13 +++++++++++-- PluginManager/Config.cs | 3 +-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index 00aadb4..7a9f374 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -43,7 +43,7 @@ namespace DiscordBot } Console.WriteLine("Please insert your prefix (max. 1 character long):"); - Console.WriteLine("For a prefix longer then one character, the first character will be saved and the others will be ignored. No spaces or numbers allowed"); + Console.WriteLine("For a prefix longer then one character, the first character will be saved and the others will be ignored.\n No spaces or numbers allowed"); Console.Write("Prefix = "); char prefix = Console.ReadLine()![0]; @@ -51,8 +51,17 @@ namespace DiscordBot Config.AddValueToVariables("prefix", prefix.ToString(), false); break; } + } - Config.SaveConfig(); + if (!Config.ContainsKey("prefix")) + { + Console.WriteLine("Please insert your prefix (max. 1 character long):"); + Console.WriteLine("For a prefix longer then one character, the first character will be saved and the others will be ignored.\n No spaces or numbers allowed"); + Console.Write("Prefix = "); + char prefix = Console.ReadLine()![0]; + + if (prefix == ' ' || char.IsDigit(prefix)) return; + Config.AddValueToVariables("prefix", prefix.ToString(), false); } HandleInput(args).Wait(); diff --git a/PluginManager/Config.cs b/PluginManager/Config.cs index d6cb269..e00cb5d 100644 --- a/PluginManager/Config.cs +++ b/PluginManager/Config.cs @@ -1,9 +1,9 @@ using PluginManager.Others; -using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.Json; using System.Threading.Tasks; +using System.Collections.Generic; namespace PluginManager { @@ -67,7 +67,6 @@ namespace PluginManager } public static async Task LoadConfig() - { string path = Functions.dataFolder + "config.json"; if (File.Exists(path)) From 97888626b6a5c77aa70ada839fbceb0c9a334801 Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Thu, 9 Jun 2022 17:19:51 +0300 Subject: [PATCH 20/20] --- DiscordBot/Discord/Core/Boot.cs | 2 +- PluginManager/Config.cs | 5 ++--- PluginManager/Items/ConsoleCommandsHandler.cs | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/DiscordBot/Discord/Core/Boot.cs b/DiscordBot/Discord/Core/Boot.cs index af38879..ce2ad4c 100644 --- a/DiscordBot/Discord/Core/Boot.cs +++ b/DiscordBot/Discord/Core/Boot.cs @@ -96,7 +96,7 @@ internal class Boot Console.Title = "ONLINE"; isReady = true; - new Thread(async () => + new Thread(() => { while (true) { diff --git a/PluginManager/Config.cs b/PluginManager/Config.cs index e00cb5d..686fee4 100644 --- a/PluginManager/Config.cs +++ b/PluginManager/Config.cs @@ -78,9 +78,8 @@ namespace PluginManager appConfig = new() { ApplicationVariables = new Dictionary(), ProtectedKeyWords = new List() }; } - public static string? GetKey(string value) => appConfig.ApplicationVariables.Keys.FirstOrDefault(x => appConfig.ApplicationVariables[x] == value); - public static bool ContainsValue(string value) => appConfig.ApplicationVariables.ContainsValue(value); - public static bool ContainsKey(string key) => appConfig.ApplicationVariables.ContainsKey(key); + public static bool ContainsValue(T value) => appConfig.ApplicationVariables.ContainsValue(value!); + public static bool ContainsKey(string key) => appConfig.ApplicationVariables.ContainsKey(key); public static Dictionary GetAllVariables() => new(appConfig.ApplicationVariables); } diff --git a/PluginManager/Items/ConsoleCommandsHandler.cs b/PluginManager/Items/ConsoleCommandsHandler.cs index 3e18caf..5ac5947 100644 --- a/PluginManager/Items/ConsoleCommandsHandler.cs +++ b/PluginManager/Items/ConsoleCommandsHandler.cs @@ -188,7 +188,7 @@ public class ConsoleCommandsHandler } ); - AddCommand("add", "add variable to the system variables\nadd [key] [value] [isReadOnly=true/false]", async args => + AddCommand("add", "add variable to the system variables\nadd [key] [value] [isReadOnly=true/false]", args => { if (args.Length < 4) return; var key = args[1];