diff --git a/DiscordBot/Discord/Commands/Help.cs b/DiscordBot/Discord/Commands/Help.cs index 570dd05..0944c6a 100644 --- a/DiscordBot/Discord/Commands/Help.cs +++ b/DiscordBot/Discord/Commands/Help.cs @@ -1,8 +1,11 @@ using System.Collections.Generic; using System.Linq; + using Discord; using Discord.Commands; using Discord.WebSocket; + +using PluginManager; using PluginManager.Interfaces; using PluginManager.Loaders; using PluginManager.Others; @@ -31,16 +34,6 @@ internal class Help : DBCommand /// public string Usage => "help "; - /// - /// Check if the command can be used /> - /// - public bool canUseDM => true; - - /// - /// Check if the command can be used in a server - /// - public bool canUseServer => true; - /// /// Check if the command require administrator to be executed /// @@ -50,12 +43,9 @@ internal class Help : DBCommand /// The main body of the command /// /// The command context - /// The command message - /// The discord bot client - /// True if the message was sent from a DM channel, false otherwise - public void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) + public void ExecuteServer(SocketCommandContext context) { - var args = Functions.GetArguments(message); + var args = Functions.GetArguments(context.Message); if (args.Count != 0) { foreach (var item in args) @@ -72,33 +62,29 @@ internal class Help : DBCommand var embedBuilder = new EmbedBuilder(); - var adminCommands = ""; + var adminCommands = ""; var normalCommands = ""; - var DMCommands = ""; foreach (var cmd in PluginLoader.Commands!) { - if (cmd.canUseDM) - DMCommands += cmd.Command + " "; if (cmd.requireAdmin) adminCommands += cmd.Command + " "; - if (cmd.canUseServer) + else normalCommands += cmd.Command + " "; } embedBuilder.AddField("Admin Commands", adminCommands); embedBuilder.AddField("Normal Commands", normalCommands); - embedBuilder.AddField("DM Commands", DMCommands); context.Channel.SendMessageAsync(embed: embedBuilder.Build()); } private EmbedBuilder GenerateHelpCommand(string command) { var embedBuilder = new EmbedBuilder(); - var cmd = PluginLoader.Commands!.Find(p => p.Command == command || (p.Aliases is not null && p.Aliases.Contains(command))); + var cmd = PluginLoader.Commands!.Find(p => p.Command == command || (p.Aliases is not null && p.Aliases.Contains(command))); if (cmd == null) return null; - embedBuilder.AddField("Usage", cmd.Usage); + embedBuilder.AddField("Usage", Config.GetValue("prefix") + cmd.Usage); embedBuilder.AddField("Description", cmd.Description); if (cmd.Aliases is null) return embedBuilder; diff --git a/DiscordBot/Discord/Commands/Restart.cs b/DiscordBot/Discord/Commands/Restart.cs index d9a7019..3d8d1aa 100644 --- a/DiscordBot/Discord/Commands/Restart.cs +++ b/DiscordBot/Discord/Commands/Restart.cs @@ -30,33 +30,19 @@ internal class Restart : DBCommand /// public string Usage => "restart [-p | -c | -args | -cmd] "; - /// - /// Check if the command can be used /> - /// - public bool canUseDM => false; - - /// - /// Check if the command can be used in a server - /// - public bool canUseServer => true; - /// /// Check if the command require administrator to be executed /// - public bool requireAdmin => false; + public bool requireAdmin => true; /// /// The main body of the command /// /// The command context - /// The command message - /// The discord bot client - /// True if the message was sent from a DM channel, false otherwise - public async void Execute(DiscordLibCommands.SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) + public async void ExecuteServer(DiscordLibCommands.SocketCommandContext context) { - if (!(message.Author as SocketGuildUser).hasPermission(DiscordLib.GuildPermission.Administrator)) return; - var args = Functions.GetArguments(message); - var OS = Functions.GetOperatingSystem(); + var args = Functions.GetArguments(context.Message); + var OS = Functions.GetOperatingSystem(); if (args.Count == 0) { switch (OS) diff --git a/DiscordBot/Discord/Commands/Settings.cs b/DiscordBot/Discord/Commands/Settings.cs index 866a91f..c034702 100644 --- a/DiscordBot/Discord/Commands/Settings.cs +++ b/DiscordBot/Discord/Commands/Settings.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; + using Discord; using Discord.Commands; using Discord.WebSocket; + using PluginManager; using PluginManager.Interfaces; @@ -27,16 +29,6 @@ internal class Settings : DBCommand /// public string Usage => "set [keyword] [new Value]"; - /// - /// Check if the command can be used /> - /// - public bool canUseDM => true; - - /// - /// Check if the command can be used in a server - /// - public bool canUseServer => true; - /// /// Check if the command require administrator to be executed /// @@ -46,16 +38,13 @@ internal class Settings : DBCommand /// The main body of the command /// /// The command context - /// The command message - /// The discord bot client - /// True if the message was sent from a DM channel, false otherwise - public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) + public async void Execute(SocketCommandContext context) { - var channel = message.Channel; + var channel = context.Message.Channel; try { - var content = message.Content; - var data = content.Split(' '); + var content = context.Message.Content; + var data = content.Split(' '); var keyword = data[1]; if (keyword.ToLower() == "help") { diff --git a/DiscordBot/Discord/Core/Boot.cs b/DiscordBot/Discord/Core/Boot.cs index e32a198..32d82b0 100644 --- a/DiscordBot/Discord/Core/Boot.cs +++ b/DiscordBot/Discord/Core/Boot.cs @@ -1,10 +1,13 @@ using System; using System.Threading; using System.Threading.Tasks; + using Discord; using Discord.Commands; using Discord.WebSocket; + using PluginManager; + using static PluginManager.Others.Functions; namespace DiscordBot.Discord.Core; @@ -44,7 +47,7 @@ internal class Boot public Boot(string botToken, string botPrefix) { this.botPrefix = botPrefix; - this.botToken = botToken; + this.botToken = botToken; } @@ -62,7 +65,7 @@ internal class Boot { DiscordSocketConfig config = new DiscordSocketConfig { AlwaysDownloadUsers = true }; - client = new DiscordSocketClient(config); + client = new DiscordSocketClient(config); service = new CommandService(); CommonTasks(); @@ -81,9 +84,9 @@ internal class Boot { if (client == null) return; client.LoggedOut += Client_LoggedOut; - client.Log += Log; - client.LoggedIn += LoggedIn; - client.Ready += Ready; + client.Log += Log; + client.LoggedIn += LoggedIn; + client.Ready += Ready; } private Task Client_LoggedOut() @@ -96,7 +99,7 @@ internal class Boot private Task Ready() { Console.Title = "ONLINE"; - isReady = true; + isReady = true; return Task.CompletedTask; } @@ -138,4 +141,5 @@ internal class Boot return Task.CompletedTask; } + } diff --git a/DiscordBot/Discord/Core/CommandHandler.cs b/DiscordBot/Discord/Core/CommandHandler.cs index c89d84b..3ba47c1 100644 --- a/DiscordBot/Discord/Core/CommandHandler.cs +++ b/DiscordBot/Discord/Core/CommandHandler.cs @@ -1,8 +1,10 @@ using System.Linq; using System.Reflection; using System.Threading.Tasks; + using Discord.Commands; using Discord.WebSocket; + using PluginManager.Loaders; using PluginManager.Others; using PluginManager.Others.Permissions; @@ -11,9 +13,9 @@ namespace DiscordBot.Discord.Core; internal class CommandHandler { - private readonly string botPrefix; + private readonly string botPrefix; private readonly DiscordSocketClient client; - private readonly CommandService commandService; + private readonly CommandService commandService; /// /// Command handler constructor @@ -23,9 +25,9 @@ internal class CommandHandler /// The prefix to watch for public CommandHandler(DiscordSocketClient client, CommandService commandService, string botPrefix) { - this.client = client; + this.client = client; this.commandService = commandService; - this.botPrefix = botPrefix; + this.botPrefix = botPrefix; } /// @@ -75,57 +77,19 @@ internal class CommandHandler var plugin = PluginLoader.Commands!.Where(p => p.Command == message.Content.Split(' ')[0].Substring(botPrefix.Length) || (p.Aliases is not null && p.Aliases.Contains(message.Content.Split(' ')[0].Substring(botPrefix.Length)))).FirstOrDefault(); + if (plugin is null) throw new System.Exception("Failed to run command. !"); - if (plugin != null) - { - if (message.Channel == await message.Author.CreateDMChannelAsync()) - { - if (plugin.canUseDM) - { - if (plugin.requireAdmin) - { - if (message.Author.isAdmin()) - { - plugin.Execute(context, message, client, true); - Functions.WriteLogFile($"[{message.Author.Id}] Executed command (DM) : " + plugin.Command); - return; - } + if (plugin.requireAdmin && !context.Message.Author.isAdmin()) + return; - await message.Channel.SendMessageAsync("This command is for administrators only !"); - return; - } + if (context.Channel is SocketDMChannel) + plugin.ExecuteDM(context); + else plugin.ExecuteServer(context); - plugin.Execute(context, message, client, true); - Functions.WriteLogFile($"[{message.Author.Id}] Executed command (DM) : " + plugin.Command); - return; - } - - await message.Channel.SendMessageAsync("This command is not for DMs"); - return; - } - - if (plugin.canUseServer) - { - if (plugin.requireAdmin) - { - if (message.Author.isAdmin()) - { - plugin.Execute(context, message, client, false); - Functions.WriteLogFile($"[{message.Author.Id}] Executed command : " + plugin.Command); - return; - } - - await message.Channel.SendMessageAsync("This command is for administrators only !"); - return; - } - - plugin.Execute(context, message, client, false); - Functions.WriteLogFile($"[{message.Author.Id}] Executed command : " + plugin.Command); - } - } } - catch + catch (System.Exception ex) { + ex.WriteErrFile(); } } } diff --git a/DiscordBot/DiscordBot.csproj b/DiscordBot/DiscordBot.csproj index 5aa59c2..e4222d3 100644 --- a/DiscordBot/DiscordBot.csproj +++ b/DiscordBot/DiscordBot.csproj @@ -8,7 +8,7 @@ False True - 1.0.0.3 + 1.0.0.13 diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index a94ff80..d7b9388 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; @@ -30,18 +31,14 @@ public class Program [Obsolete] public static void Main(string[] args) { - - Directory.CreateDirectory("./Data/Resources"); - Directory.CreateDirectory("./Data/Plugins/Commands"); - Directory.CreateDirectory("./Data/Plugins/Events"); + Console.WriteLine("Loading resources ..."); PreLoadComponents().Wait(); - - - if (!Config.ContainsKey("ServerID")) + do { - do + if (!Config.ContainsKey("ServerID")) { - Console.Clear(); + + Console.WriteLine("Please enter the server ID: "); Console_Utilities.WriteColorText("You can find it in the Server Settings at &r\"Widget\"&c section"); Console.WriteLine("Example: 1234567890123456789"); @@ -56,49 +53,48 @@ public class Program string SID = key.KeyChar + Console.ReadLine(); if (SID.Length != 18) { - Console.WriteLine("Your server ID is not 18 characters long. Please try again."); + Console.Clear(); + Console_Utilities.WriteColorText("&rYour server ID is not 18 characters long. Please try again. \n"); + continue; } - - Config.AddValueToVariables("ServerID", SID, false); - } - break; - } while (true); + } - } + if (!Config.ContainsKey("token") || Config.GetValue("token") == null || (Config.GetValue("token")?.Length != 70 && Config.GetValue("token")?.Length != 59)) + { + Console.WriteLine("Please insert your token"); + Console.Write("Token = "); + var token = Console.ReadLine(); + if (token?.Length == 59 || token?.Length == 70) + Config.AddValueToVariables("token", token, true); + else + { + Console.Clear(); + Console_Utilities.WriteColorText("&rThe token length is invalid !"); + continue; + } + } - if (!Config.ContainsKey("token") || Config.GetValue("token") == null || Config.GetValue("token")?.Length != 70) - { - Console.WriteLine("Please insert your token"); - Console.Write("Token = "); - var token = Console.ReadLine(); - if (token?.Length == 59 || token?.Length == 70) - Config.AddValueToVariables("token", token, true); - else - Console.WriteLine("Invalid token"); + if (!Config.ContainsKey("prefix") || Config.GetValue("prefix") == null || Config.GetValue("prefix")?.Length != 1) + { + 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, numbers, '/' or '\\' allowed"); + Console.Write("Prefix = "); + var prefix = Console.ReadLine()![0]; - 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 = "); - var prefix = Console.ReadLine()![0]; - - if (prefix == ' ' || char.IsDigit(prefix)) - return; - Config.AddValueToVariables("prefix", prefix.ToString(), false); - } - - if (!Config.ContainsKey("prefix") || Config.GetValue("prefix") == default) - { - 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 = "); - var prefix = Console.ReadLine()![0]; - if (prefix == ' ') return; - Config.AddValueToVariables("prefix", prefix.ToString(), false); - } + if (prefix == ' ' || char.IsDigit(prefix) || prefix == '/' || prefix == '\\') + { + Console.Clear(); + Console_Utilities.WriteColorText("&rThe prefix is invalid"); + continue; + } + Config.AddValueToVariables("prefix", prefix.ToString(), false); + } + break; + } while (true); HandleInput(args).Wait(); } @@ -225,23 +221,6 @@ public class Program return; } - if (len > 0 && args[0] == "/test") - { - int p = 1; - bool allowed = true; - Console.CancelKeyPress += (sender, e) => allowed = false; - Console_Utilities.ProgressBar bar = new(ProgressBarType.NO_END);// { NoColor = false, Color = ConsoleColor.DarkRed }; - Console.WriteLine("Press Ctrl + C to stop."); - while (p <= int.MaxValue - 1 && allowed) - { - bar.Update(100 / p); - await Task.Delay(100); - p++; - } - - return; - } - if (len > 0 && (args.Contains("--cmd") || args.Contains("--args") || args.Contains("--nomessage"))) { if (args.Contains("lp") || args.Contains("loadplugins")) @@ -267,6 +246,13 @@ public class Program len = 0; } + if (len > 0 && args[0] == "/updateplug") + { + string plugName = args.MergeStrings(1); + Console.WriteLine("Updating " + plugName); + await ConsoleCommandsHandler.ExecuteCommad("dwplug" + plugName); + return; + } if (len == 0 || (args[0] != "--exec" && args[0] != "--execute")) { @@ -346,6 +332,12 @@ public class Program private static async Task PreLoadComponents() { + Console_Utilities.ProgressBar main = new Console_Utilities.ProgressBar(ProgressBarType.NO_END); + main.Start(); + Directory.CreateDirectory("./Data/Resources"); + Directory.CreateDirectory("./Data/Plugins/Commands"); + Directory.CreateDirectory("./Data/Plugins/Events"); + Directory.CreateDirectory("./Data/PAKS"); await Config.LoadConfig(); if (Config.ContainsKey("DeleteLogsAtStartup")) if (Config.GetValue("DeleteLogsAtStartup")) @@ -375,7 +367,11 @@ public class Program } } + + + List onlineSettingsList = await ServerCom.ReadTextFromURL("https://raw.githubusercontent.com/Wizzy69/installer/discord-bot-files/OnlineData"); + main.Stop("Loaded online settings. Loading updates ..."); foreach (var key in onlineSettingsList) { if (key.Length <= 3 || !key.Contains(' ')) continue; @@ -387,42 +383,47 @@ public class Program string newVersion = s[1]; if (!newVersion.Equals(Config.GetValue("Version"))) { - Console.WriteLine("A new version has been released on github page."); - Console.WriteLine("Download the new version using the following link wrote in yellow"); - Console_Utilities.WriteColorText("&y" + Config.GetValue("GitURL") + "&c"); - - Console.WriteLine(); - Console.WriteLine("Your product will work just fine on this outdated version, but an update is recommended.\n" + - "From now on, this version is no longer supported" - ); - Console_Utilities.WriteColorText("&rUse at your own risk&c"); - - Console_Utilities.WriteColorText("&mCurrent Version: " + Config.GetValue("Version") + "&c"); - Console_Utilities.WriteColorText("&gNew Version: " + newVersion + "&c"); - - Console.WriteLine("\n\n"); - await Task.Delay(1000); - - int waitTime = 10; //wait time to proceed - - Console.Write($"The bot will start in {waitTime} seconds"); - while (waitTime > 0) + if (Functions.GetOperatingSystem() == PluginManager.Others.OperatingSystem.WINDOWS) { - await Task.Delay(1000); - waitTime--; - Console.SetCursorPosition("The bot will start in ".Length, Console.CursorTop); - Console.Write(" "); - Console.SetCursorPosition("The bot will start in ".Length, Console.CursorTop); - Console.Write(waitTime + " seconds"); + + string url = $"https://github.com/Wizzy69/SethDiscordBot/releases/download/v{newVersion}/net6.0.zip"; + //string url2 = $"https://github.com/Wizzy69/SethDiscordBot/releases/download/v{newVersion}-preview/net6.0.zip"; + + Process.Start(".\\Updater\\Updater.exe", $"{newVersion} {url} {Process.GetCurrentProcess().ProcessName}"); + } + else + { + string url = $"https://github.com/Wizzy69/SethDiscordBot/releases/download/v{newVersion}/net6.0_linux.zip"; + Process.Start("./Updater/Updater", $"/update {url} ./DiscordBot ./"); + } + //Environment.Exit(0); } + break; + case "UpdaterVersion": + string updaternewversion = s[1]; + if (Config.UpdaterVersion != updaternewversion) + { + Console.Clear(); + Console.WriteLine("Installing updater ...\nDo NOT close the bot during update !"); + Console_Utilities.ProgressBar bar = new Console_Utilities.ProgressBar(ProgressBarType.NO_END); + bar.Start(); + await ServerCom.DownloadFileNoProgressAsync("https://github.com/Wizzy69/installer/releases/download/release-1-discordbot/Updater.zip", "./Updater.zip"); + await Functions.ExtractArchive("./Updater.zip", "./", null, UnzipProgressType.PercentageFromTotalSize); + Config.UpdaterVersion = updaternewversion; + File.Delete("Updater.zip"); + await Config.SaveConfig(SaveType.NORMAL); + bar.Stop("Updater has been updated !"); + Console.Clear(); + } break; } } - Console_Utilities.Initialize(); - Config.SaveConfig(SaveType.NORMAL); + Console_Utilities.Initialize(); + await Config.SaveConfig(SaveType.NORMAL); + Console.Clear(); } } diff --git a/PluginManager/Config.cs b/PluginManager/Config.cs index 9bb7140..3abeff9 100644 --- a/PluginManager/Config.cs +++ b/PluginManager/Config.cs @@ -11,6 +11,7 @@ namespace PluginManager { internal class AppConfig { + public string? UpdaterVersion { get; set; } public Dictionary? ApplicationVariables { get; init; } public List? ProtectedKeyWords { get; init; } public Dictionary? PluginVersions { get; init; } @@ -77,6 +78,8 @@ namespace PluginManager private static AppConfig? appConfig { get; set; } + public static string UpdaterVersion { get => appConfig.UpdaterVersion; set => appConfig.UpdaterVersion = value; } + public static string GetPluginVersion(string pluginName) => appConfig!.PluginVersions![pluginName]; public static void SetPluginVersion(string pluginName, string newVersion) { @@ -181,6 +184,11 @@ namespace PluginManager SaveConfig(SaveType.NORMAL); } + public static bool IsReadOnly(string key) + { + return appConfig.ProtectedKeyWords.Contains(key); + } + public static async Task SaveConfig(SaveType type) { if (type == SaveType.NORMAL) @@ -220,12 +228,12 @@ namespace PluginManager Functions.WriteLogFile($"Loaded {appConfig.ApplicationVariables!.Keys.Count} application variables.\nLoaded {appConfig.ProtectedKeyWords!.Count} readonly variables."); return; } - appConfig = new() { ApplicationVariables = new Dictionary(), ProtectedKeyWords = new List(), PluginVersions = new Dictionary() }; + appConfig = new() { ApplicationVariables = new Dictionary(), ProtectedKeyWords = new List(), PluginVersions = new Dictionary(), UpdaterVersion = "-1" }; } public static bool ContainsValue(T value) => appConfig!.ApplicationVariables!.ContainsValue(value!); public static bool ContainsKey(string key) => appConfig!.ApplicationVariables!.ContainsKey(key); - public static ReadOnlyDictionary GetAllVariables() => new(appConfig!.ApplicationVariables!); + public static IDictionary GetAllVariables() => appConfig.ApplicationVariables; } } diff --git a/PluginManager/Interfaces/DBCommand.cs b/PluginManager/Interfaces/DBCommand.cs index 7dc759d..6082113 100644 --- a/PluginManager/Interfaces/DBCommand.cs +++ b/PluginManager/Interfaces/DBCommand.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; + using Discord.Commands; using Discord.WebSocket; @@ -28,27 +29,20 @@ public interface DBCommand /// string Usage { get; } - /// - /// true if the command can be used in a DM channel, otherwise false - /// - bool canUseDM { get; } - - /// - /// true if the command can be used in a server, otherwise false - /// - bool canUseServer { get; } - /// /// true if the command requre admin, otherwise false /// bool requireAdmin { get; } /// - /// The main body of the command. This is what is executed when user calls the command + /// The main body of the command. This is what is executed when user calls the command in Server /// /// The disocrd Context - /// The message that the user types - /// The discord client of the bot - /// true if the message was sent from DM, otherwise false. It is always false if canUseDM is false - void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM); + void ExecuteServer(SocketCommandContext context) { } + + /// + /// The main body of the command. This is what is executed when user calls the command in DM + /// + /// The disocrd Context + void ExecuteDM(SocketCommandContext context) { } } diff --git a/PluginManager/Items/ConsoleCommandsHandler.cs b/PluginManager/Items/ConsoleCommandsHandler.cs index 4a31091..b44e1e7 100644 --- a/PluginManager/Items/ConsoleCommandsHandler.cs +++ b/PluginManager/Items/ConsoleCommandsHandler.cs @@ -14,9 +14,7 @@ using PluginManager.Interfaces; using PluginManager.Loaders; using PluginManager.Online; using PluginManager.Online.Helpers; -using PluginManager.Online.Updates; using PluginManager.Others; - namespace PluginManager.Items; public class ConsoleCommandsHandler @@ -162,13 +160,22 @@ public class ConsoleCommandsHandler path = "./Data/Plugins/" + info[0] + "s/" + name + "." + (info[0] == "Command" ? PluginLoader.pluginCMDExtension : PluginLoader.pluginEVEExtension); else path = $"./{info[1].Split('/')[info[1].Split('/').Length - 1]}"; - //Console.WriteLine("Downloading: " + path + " [" + info[1] + "]"); - await ServerCom.DownloadFileAsync(info[1], path); - if (info[0] == "Command" || info[0] == "Event") - if (info[0] == "Event") - Config.PluginConfig.InstalledPlugins.Add(new(name, PluginType.Event)); - else if (info[0] == "Command") - Config.PluginConfig.InstalledPlugins.Add(new(name, PluginType.Command)); + if (Others.OperatingSystem.WINDOWS == Functions.GetOperatingSystem()) + { + await ServerCom.DownloadFileAsync(info[1], path); + } + else if (Others.OperatingSystem.LINUX == Functions.GetOperatingSystem()) + { + Others.Console_Utilities.ProgressBar bar = new Console_Utilities.ProgressBar(ProgressBarType.NO_END); + bar.Start(); + await ServerCom.DownloadFileNoProgressAsync(info[1], path); + bar.Stop("Plugin Downloaded !"); + } + + if (info[0] == "Event") + Config.PluginConfig.InstalledPlugins.Add(new(name, PluginType.Event)); + else if (info[0] == "Command") + Config.PluginConfig.InstalledPlugins.Add(new(name, PluginType.Command)); Console.WriteLine("\n"); @@ -188,34 +195,26 @@ public class ConsoleCommandsHandler var split = line.Split(','); Console.WriteLine($"\nDownloading item: {split[1]}"); if (File.Exists("./" + split[1])) File.Delete("./" + split[1]); - await ServerCom.DownloadFileAsync(split[0], "./" + split[1]); - Console.WriteLine(); - - if (split[0].EndsWith(".zip") || split[0].EndsWith(".pak") || split[0].EndsWith(".pkg")) + if (Others.OperatingSystem.WINDOWS == Functions.GetOperatingSystem()) + await ServerCom.DownloadFileAsync(split[0], "./" + split[1]); + else if (Others.OperatingSystem.LINUX == Functions.GetOperatingSystem()) { - Console.WriteLine($"Extracting {split[1]}"); - var proc = 0f; - var isExtracting = true; - var bar = new Console_Utilities.ProgressBar(ProgressBarType.NORMAL) { Max = 100f, Color = ConsoleColor.Green }; + Others.Console_Utilities.ProgressBar bar = new Console_Utilities.ProgressBar(ProgressBarType.NO_END); + bar.Start(); + await ServerCom.DownloadFileNoProgressAsync(split[0], "./" + split[1]); + bar.Stop("Item downloaded !"); - IProgress extractProgress = new Progress(value => { proc = value; }); - new Thread(new Task(() => - { - while (isExtracting) - { - bar.Update(proc); - if (proc >= 99.9f) - isExtracting = false; - Thread.Sleep(500); - } - } - ).Start - ).Start(); - await Functions.ExtractArchive("./" + split[1], "./", extractProgress, UnzipProgressType.PercentageFromTotalSize); - bar.Update(100f); - isExtracting = false; - await Task.Delay(1000); - bar.Update(100); + } + Console.WriteLine(); + if (split[0].EndsWith(".pak")) + File.Move("./" + split[1], "./Data/PAKS/" + split[1], true); + else if (split[0].EndsWith(".zip") || split[0].EndsWith(".pkg")) + { + Console.WriteLine($"Extracting {split[1]} ..."); + var bar = new Console_Utilities.ProgressBar(ProgressBarType.NO_END);// { Max = 100f, Color = ConsoleColor.Green }; + bar.Start(); + await Functions.ExtractArchive("./" + split[1], "./", null, UnzipProgressType.PercentageFromTotalSize); + bar.Stop("Extracted"); Console.WriteLine("\n"); File.Delete("./" + split[1]); } @@ -226,10 +225,12 @@ public class ConsoleCommandsHandler VersionString? ver = await VersionString.GetVersionOfPackageFromWeb(name); if (ver is null) throw new Exception("Incorrect version"); Config.SetPluginVersion(name, $"{ver.PackageVersionID}.{ver.PackageMainVersion}.{ver.PackageCheckVersion}"); - // Console.WriteLine(); isDownloading = false; + + } + ); @@ -277,30 +278,23 @@ public class ConsoleCommandsHandler { if (client is null) return; - bool run = true; - var t = new Thread(() => - { - Console_Utilities.ProgressBar bar = new Console_Utilities.ProgressBar(ProgressBarType.NO_END); - while (run) - { - bar.Update(1); - Thread.Sleep(50); - } - }); - t.Start(); + Console_Utilities.ProgressBar bar = new Console_Utilities.ProgressBar(ProgressBarType.NO_END); + + bar.Start(); await Config.SaveConfig(SaveType.NORMAL); await Config.SaveConfig(SaveType.BACKUP); - await Task.Delay(4000); - run = false; + bar.Stop("Saved config !"); Console.WriteLine(); await client.StopAsync(); await client.DisposeAsync(); + + await Task.Delay(1000); Environment.Exit(0); } ); - AddCommand("extern", "Load an external command", "extern [pluginName]", async (args) => + AddCommand("import", "Load an external command", "import [pluginName]", async (args) => { if (args.Length <= 1) return; string pName = Functions.MergeStrings(args, 1); diff --git a/PluginManager/Online/ServerCom.cs b/PluginManager/Online/ServerCom.cs index 925bbf5..6151e61 100644 --- a/PluginManager/Online/ServerCom.cs +++ b/PluginManager/Online/ServerCom.cs @@ -79,5 +79,11 @@ namespace PluginManager.Online pbar.Update(100f); isDownloading = false; } + public static async Task DownloadFileNoProgressAsync(string URL, string location) + { + IProgress progress = new Progress(); + await DownloadFileAsync(URL, location, progress); + } + } } diff --git a/PluginManager/Others/Console Utilities.cs b/PluginManager/Others/Console Utilities.cs index c1277f0..818042e 100644 --- a/PluginManager/Others/Console Utilities.cs +++ b/PluginManager/Others/Console Utilities.cs @@ -42,24 +42,95 @@ namespace PluginManager.Others public bool NoColor { get; init; } public ProgressBarType type { get; set; } + public int TotalLength { get; private set; } + private int BarLength = 32; private int position = 1; private bool positive = true; + private bool isRunning; + + + public async void Start() + { + if (type != ProgressBarType.NO_END) + throw new Exception("Only NO_END progress bar can use this method"); + if (isRunning) + throw new Exception("This progress bar is already running"); + + isRunning = true; + while (isRunning) + { + UpdateNoEnd(); + await System.Threading.Tasks.Task.Delay(100); + } + } + + public async void Start(string message) + { + if (type != ProgressBarType.NO_END) + throw new Exception("Only NO_END progress bar can use this method"); + if (isRunning) + throw new Exception("This progress bar is already running"); + + isRunning = true; + + TotalLength = message.Length + BarLength + 5; + while (isRunning) + { + UpdateNoEnd(message); + await System.Threading.Tasks.Task.Delay(100); + } + } + + public void Stop() + { + if (type != ProgressBarType.NO_END) + throw new Exception("Only NO_END progress bar can use this method"); + if (!isRunning) + throw new Exception("Can not stop a progressbar that did not start"); + isRunning = false; + } + + public void Stop(string message) + { + Stop(); + + if (message is not null) + { + Console.CursorLeft = 0; + for (int i = 0; i < BarLength + message.Length + 1; i++) + Console.Write(" "); + Console.CursorLeft = 0; + Console.WriteLine(message); + } + } + public void Update(float progress) { - switch (type) - { - case ProgressBarType.NORMAL: - UpdateNormal(progress); - return; - case ProgressBarType.NO_END: - if (progress <= 99.9f) - UpdateNoEnd(); - return; - default: - return; - } + if (type == ProgressBarType.NO_END) + throw new Exception("This function is for progress bars with end"); + + UpdateNormal(progress); + } + + private void UpdateNoEnd(string message) + { + Console.CursorLeft = 0; + Console.Write("["); + for (int i = 1; i <= position; i++) + Console.Write(" "); + Console.Write("<==()==>"); + position += positive ? 1 : -1; + for (int i = position; i <= BarLength - 1 - (positive ? 0 : 2); i++) + Console.Write(" "); + Console.Write("] " + message); + + + + + if (position == BarLength - 1 || position == 1) + positive = !positive; } private void UpdateNoEnd() @@ -75,6 +146,8 @@ namespace PluginManager.Others Console.Write("]"); + + if (position == BarLength - 1 || position == 1) positive = !positive; } diff --git a/PluginManager/Others/Functions.cs b/PluginManager/Others/Functions.cs index 2f26f9e..f512f1e 100644 --- a/PluginManager/Others/Functions.cs +++ b/PluginManager/Others/Functions.cs @@ -50,21 +50,42 @@ namespace PluginManager.Others /// The file name that is inside the archive or its full path /// The archive location from the PAKs folder /// A string that represents the content of the file or null if the file does not exists or it has no content - public static async Task ReadFromPakAsync(string FileName, string archFile) + public static async Task ReadFromPakAsync(string FileName, string archFile) { archFile = pakFolder + archFile; - Directory.CreateDirectory(pakFolder); - if (!File.Exists(archFile)) throw new FileNotFoundException("Failed to load file !"); + if (!File.Exists(archFile)) + throw new Exception("Failed to load file !"); - using ZipArchive archive = ZipFile.OpenRead(archFile); - ZipArchiveEntry? entry = archive.GetEntry(FileName); - if (entry is null) return Stream.Null; - MemoryStream stream = new MemoryStream(); - await (entry?.Open()!).CopyToAsync(stream); + try + { + string textValue = null; + using (var fs = new FileStream(archFile, FileMode.Open)) + using (var zip = new ZipArchive(fs, ZipArchiveMode.Read)) + foreach (var entry in zip.Entries) + { + if (entry.Name == FileName || entry.FullName == FileName) + { + using (Stream s = entry.Open()) + using (StreamReader reader = new StreamReader(s)) + { + textValue = await reader.ReadToEndAsync(); + reader.Close(); + s.Close(); + fs.Close(); + } + } + } + return textValue; + } + catch + { + await Task.Delay(100); + return await ReadFromPakAsync(FileName, archFile); + } - return stream; } + /// /// Write logs to file /// @@ -87,6 +108,11 @@ namespace PluginManager.Others File.AppendAllText(errPath, ErrMessage + " \n"); } + public static void WriteErrFile(this Exception ex) + { + WriteErrFile(ex.ToString()); + } + /// /// Merge one array of strings into one string /// @@ -168,9 +194,7 @@ namespace PluginManager.Others /// public static async Task ExtractArchive(string zip, string folder, IProgress progress, UnzipProgressType type) { - if (!Directory.Exists(folder)) Directory.CreateDirectory(folder); - - + Directory.CreateDirectory(folder); using (ZipArchive archive = ZipFile.OpenRead(zip)) { if (type == UnzipProgressType.PercentageFromNumberOfFiles) @@ -194,7 +218,8 @@ namespace PluginManager.Others currentZIPFile++; await Task.Delay(10); - progress.Report((float)currentZIPFile / totalZIPFiles * 100); + if (progress != null) + progress.Report((float)currentZIPFile / totalZIPFiles * 100); } } else if (type == UnzipProgressType.PercentageFromTotalSize) @@ -224,7 +249,8 @@ namespace PluginManager.Others } await Task.Delay(10); - progress.Report((float)currentSize / zipSize * 100); + if (progress != null) + progress.Report((float)currentSize / zipSize * 100); } } }