From 531edcd3cc90783b940ca2e4571336b76d6ee814 Mon Sep 17 00:00:00 2001 From: Wizzy69 Date: Wed, 8 Jun 2022 18:54:58 +0300 Subject: [PATCH] patch --- BUILDS/net6.0/MusicCommands.dll | Bin 18432 -> 17920 bytes BUILDS/net6.0/PluginManager.dll | Bin 63488 -> 65024 bytes CMD_LevelingSystem/Level.cs | 66 ++-- CMD_LevelingSystem/User.cs | 19 +- CMD_Utils/Echo.cs | 5 +- CMD_Utils/FlipCoin.cs | 53 ++- CMD_Utils/Poll.cs | 76 ++-- CMD_Utils/Random.cs | 12 +- DiscordBot/App.config | 11 +- DiscordBot/Discord/Commands/Help.cs | 166 ++++---- DiscordBot/Discord/Commands/Restart.cs | 183 +++++---- DiscordBot/Discord/Commands/Settings.cs | 164 ++++---- DiscordBot/Discord/Core/Boot.cs | 251 ++++++------ DiscordBot/Discord/Core/CommandHandler.cs | 198 +++++----- DiscordBot/Program.cs | 40 +- DiscordBotGUI/App.axaml | 8 +- DiscordBotGUI/App.axaml.cs | 24 +- DiscordBotGUI/AppUpdater.axaml | 17 +- DiscordBotGUI/AppUpdater.axaml.cs | 4 +- DiscordBotGUI/MainWindow.axaml | 53 +-- DiscordBotGUI/MainWindow.axaml.cs | 147 ++++--- DiscordBotGUI/Program.cs | 40 +- .../Settings/ApplicationVariables.axaml | 28 +- .../Settings/ApplicationVariables.axaml.cs | 61 ++- DiscordBotGUI/Settings/Commands.axaml | 29 +- DiscordBotGUI/Settings/Commands.axaml.cs | 204 +++++----- DiscordBotGUI/Settings/Events.axaml | 29 +- DiscordBotGUI/Settings/Events.axaml.cs | 200 +++++----- EVE_LevelingSystem/Level.cs | 16 +- EVE_LevelingSystem/LevelingSystemCore/User.cs | 19 +- MusicCommands/Data.cs | 16 +- MusicCommands/Leave.cs | 48 +-- MusicCommands/MusicPlayer.cs | 197 +++++----- MusicCommands/Pause.cs | 36 +- MusicCommands/Play.cs | 99 +++-- MusicCommands/Unpause.cs | 41 +- MusicCommands/lplay.cs | 76 ++-- PluginManager/Config.cs | 2 +- PluginManager/Interfaces/DBCommand.cs | 86 +++-- PluginManager/Interfaces/DBEvent.cs | 33 +- PluginManager/Items/Command.cs | 81 ++-- PluginManager/Items/ConsoleCommandsHandler.cs | 359 +++++++++--------- PluginManager/Items/Spinner.cs | 92 +++-- PluginManager/Loaders/Loader.cs | 207 +++++----- PluginManager/Loaders/PluginLoader.cs | 152 ++++---- PluginManager/Online/LanguageManager.cs | 134 ++++--- PluginManager/Online/PluginsManager.cs | 196 +++++----- PluginManager/Online/ServerCom.cs | 35 +- PluginManager/Others/Channels.cs | 86 +++-- PluginManager/Others/Console Utilities.cs | 28 +- PluginManager/Others/Cryptography.cs | 167 ++++---- PluginManager/Others/Enums.cs | 36 +- .../Others/Exceptions/APIException.cs | 169 ++++----- PluginManager/Others/Functions.cs | 19 +- .../Others/Permissions/DiscordPermissions.cs | 95 ++--- 55 files changed, 2253 insertions(+), 2360 deletions(-) diff --git a/BUILDS/net6.0/MusicCommands.dll b/BUILDS/net6.0/MusicCommands.dll index c9f76616c157f3f3e06c823a3b19e24b6412ccb7..dac55ebd46e8cbd30c19db1342debe3c2522b214 100644 GIT binary patch delta 4283 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 XVat+iV%%v%9Uh&{n|P8shuHrH6ruV? delta 4349 zcmb`Ldvp}l9ml`FJF~Mpvzx~zyBju;WH%wnh6s7cD={V^gtrx`_(VaBMX4y5RI8>k z8z>K>Mbe>^!|{O@TCqN=dqR8EDimswQz=ogQaLp!MXgo~^(c6-?eE?h1bb>v|8R5m zGr#Ze{_gL0@7eBaLAF~DCYY?T0Ak_k`>@Zws^W45iE~XD0qDtSs zD}iB7Qk>;nMwM23Ge;!&-RksGHMKe0sFEf-f2PuSVy@eHDqjSAcy%mrvH~Dypk(?mod>LqlBy#MRyysE9*-$SRBnf8X2uO9_GwtOMwf*z-(T^vJ1b{ zx$wqoySNZG7Xg=Q?7QefoJ;^5in1veO>5_CDCrc&$0nzwVVPL$`5HK+4le|yyX~h!dFH-hVD>q=_CT%BY zSfuB2p0U7m)Umz(F&Hr~I;Y1t&G|a~>$)R?0R5e!&XDNhRZn{{6(+jJFwX56+`m&%72(v*wC zqzkEvRofavs(`0@byroumK_^It{er8J3hf3Wav1h3Y3bXQ7JiyIt)RRQunc}<9n>- zjDDlgc7_^@NlLBar>zc?F_nj2qBUxSCPjZpYhiIYGapl&3-R;=GF>bmKRq8gC zp@)0PzI|u({i;dY?kw+BCC@DORUO>;O&q^it;#ONB+0cILz|fwlU(qd>A$bjsmaLv zj|Y0?LX}%`9<#BPIjHDYDcTgLkzB5CtC{uE<81ffN#;AwM@4b!bj;!^`$jWFgzFQ0 zyWogf5Rht#tEk)9$V8Fju^I_0yJH%}U-u2p! zahrjoZX0LWulW&7f?u4|Huq{K%3T@QBSK_hq^I@^o4=jLD%BI{=b;7B?5XDiHgA_x z+(`U_AJPzJd+NCHrWV2`PdykopEuLPN*yt~wQa24_f%)VmhzYt)Gp4v?z%EC!c z$#u%YzdR+^DGNew&N!mhDGOnx+;s}0&}~x%!$^9nGq4R|q&&s-Y?d{ilm)}6_mnIc z#u!h@f?dP>%_qj^XOr)0gjjdwjM3&!z*t5m@_ z+RNku_h5_vh*ktgDYtwv?){Q_SgAu42^qX|?&B|a;1JE!hq8KEDYst<4l1=ABk?z_ z1op6$40Rh5NGau}Nua6vbeaU3m2xAKnCi93f=TQebviPM7nE`%OR>*ulaZxpsy!W9 zie_6$H?#~>y+#>YhSt%iL(9;nlp8r5=Xq^1aya(!8SvD6#ba9CMWFnI>HtC>A?#2^V{kZe$M7Yt}r`jv1kw!~hMkzAM7w zZELBJeV2{NbR#sBZV|5wb!uOX2$wK8R!$l+(!Vha8)4znF% z3fB2-=Q0KBDBF2V!Kd8m-MWlff^ud8mCPhR|AIHp zYGxVl+5#1*VOH|9$Cnh&W>#Sga|EA+1qU`TN8uc14bElO^0`-V^aN%-CNj_F)2@jn zT;4<{mkZ){wuAT{+aaXc4q+MFSy;(-7XR2OK{oDYI~!}*&cP4iE8@#K=i1ar>UVyW zDz8e)!#(e}2G97^%i=xuKYhEMw^Nl-_cw$0p8yqJr#ivS|Ko6Bo_z>Z)tV3|7r2XI^#EnOU7h4VjhI1qO9FYw8lzmASv}YCS_^ zFVS*;`Oio8Zx5xXudkYXYj4xjzsg+Kuvg1A5=43F6=p)nOQ!wY6j6h7L-X09zSeoD zd4;cGUTt-g(^@^mX>X~`i+KNSkOLeg?L=QPCK7X<`&*V|678!glim86CR&>_;r5TH Huh#!>uoU~k diff --git a/BUILDS/net6.0/PluginManager.dll b/BUILDS/net6.0/PluginManager.dll index 7cc60a0e43966b72d2dc8aafab2c8c98d36c5ba5..6be9c729bc3d518f26449ae0a210b19c72c1c3f9 100644 GIT binary patch literal 65024 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�e(;0iGYzC!8ZEx*P&H=fXBl&YE)=bfV7& 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�)>mo-H>~u3oY%ew(L9DbR$@BHFu%5)4Jg< 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 G!2bp{+i7J0 literal 63488 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 diff --git a/CMD_LevelingSystem/Level.cs b/CMD_LevelingSystem/Level.cs index 85b341f..22f30e3 100644 --- a/CMD_LevelingSystem/Level.cs +++ b/CMD_LevelingSystem/Level.cs @@ -1,48 +1,42 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Discord; +using Discord; using Discord.Commands; using Discord.WebSocket; using PluginManager; using PluginManager.Interfaces; using PluginManager.Others; -namespace CMD_LevelingSystem +namespace CMD_LevelingSystem; + +internal class Level : DBCommand { - 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) { - 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) + var user = await Functions.ConvertFromJson(Config.GetValue("LevelingSystemPath") + $"/{message.Author.Id}.dat"); + if (user == null) { - 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()); + await context.Channel.SendMessageAsync("You are now unranked !"); + return; } + + var builder = new EmbedBuilder(); + var 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 index 679a5d5..1b0736a 100644 --- a/CMD_LevelingSystem/User.cs +++ b/CMD_LevelingSystem/User.cs @@ -1,16 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace CMD_LevelingSystem; -namespace CMD_LevelingSystem +public class User { - public class User - { - public string userID { get; set; } - public int CurrentLevel { get; set; } - public Int64 CurrentEXP { get; set; } - public Int64 RequiredEXPToLevelUp { get; set; } - } + public string userID { get; set; } + public int CurrentLevel { get; set; } + public long CurrentEXP { get; set; } + public long RequiredEXPToLevelUp { get; set; } } diff --git a/CMD_Utils/Echo.cs b/CMD_Utils/Echo.cs index fdf7fe1..83ec899 100644 --- a/CMD_Utils/Echo.cs +++ b/CMD_Utils/Echo.cs @@ -1,6 +1,5 @@ using Discord.Commands; using Discord.WebSocket; - using PluginManager.Interfaces; internal class Echo : DBCommand @@ -11,14 +10,14 @@ internal class Echo : DBCommand public string Usage => "echo [message]"; - public bool canUseDM => true; + public bool canUseDM => true; public bool canUseServer => true; public bool requireAdmin => false; public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) { - string m = message.Content.Substring(6); + var m = message.Content.Substring(6); await message.Channel.SendMessageAsync(m); } } diff --git a/CMD_Utils/FlipCoin.cs b/CMD_Utils/FlipCoin.cs index e84f83b..0057f33 100644 --- a/CMD_Utils/FlipCoin.cs +++ b/CMD_Utils/FlipCoin.cs @@ -1,37 +1,30 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Discord.Commands; +using Discord.Commands; using Discord.WebSocket; - using PluginManager.Interfaces; -namespace CMD_Utils +namespace CMD_Utils; + +internal class FlipCoin : DBCommand { - class FlipCoin : DBCommand + public string Command => "flip"; + + public string Description => "Flip a coin"; + + public string Usage => "flip"; + + public bool canUseDM => true; + + public bool canUseServer => true; + + public bool requireAdmin => false; + + public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) { - public string Command => "flip"; - - public string Description => "Flip a coin"; - - public string Usage => "flip"; - - public bool canUseDM => true; - - public bool canUseServer => true; - - public bool requireAdmin => false; - - public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) - { - System.Random random = new System.Random(); - int r = random.Next(1, 3); - if (r == 1) - await message.Channel.SendMessageAsync("Heads"); - else await message.Channel.SendMessageAsync("Tails"); - } + var random = new System.Random(); + var r = random.Next(1, 3); + if (r == 1) + await message.Channel.SendMessageAsync("Heads"); + else + await message.Channel.SendMessageAsync("Tails"); } } diff --git a/CMD_Utils/Poll.cs b/CMD_Utils/Poll.cs index bf81df5..c3624c6 100644 --- a/CMD_Utils/Poll.cs +++ b/CMD_Utils/Poll.cs @@ -1,53 +1,45 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - +using System.Collections.Generic; using Discord; using Discord.Commands; using Discord.WebSocket; - using PluginManager.Interfaces; +using PluginManager.Others; -namespace CMD_Utils +namespace CMD_Utils; + +public class Poll : DBCommand { - public class Poll : DBCommand + public string Command => "poll"; + + public string Description => "Create a poll with options"; + + public string Usage => "poll [This-is-question] [This-is-answer-1] [This-is-answer-2] ... "; + + public bool canUseDM => false; + + public bool canUseServer => true; + + public bool requireAdmin => true; + + public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) { - public string Command => "poll"; + if (isDM) return; + var question = message.Content.Split(' ')[1].Replace('-', ' '); + var answers = Functions.MergeStrings(message.Content.Split(' '), 2).Split(' '); + var embedBuilder = new EmbedBuilder(); + embedBuilder.Title = question; + var len = answers.Length; + for (var i = 0; i < len; i++) embedBuilder.AddField($"Answer {i + 1}", answers[i].Replace('-', ' '), true); + var msg = await context.Channel.SendMessageAsync(embed: embedBuilder.Build()); - public string Description => "Create a poll with options"; + var emotes = new List(); + emotes.Add(Emoji.Parse(":one:")); + emotes.Add(Emoji.Parse(":two:")); + emotes.Add(Emoji.Parse(":three:")); + emotes.Add(Emoji.Parse(":four:")); + emotes.Add(Emoji.Parse(":five:")); + emotes.Add(Emoji.Parse(":six:")); - public string Usage => "poll [This-is-question] [This-is-answer-1] [This-is-answer-2] ... "; - - public bool canUseDM => false; - - public bool canUseServer => true; - - public bool requireAdmin => true; - - public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) - { - if (isDM) return; - string question = message.Content.Split(' ')[1].Replace('-', ' '); - string[] answers = PluginManager.Others.Functions.MergeStrings(message.Content.Split(' '), 2).Split(' '); - EmbedBuilder embedBuilder = new EmbedBuilder(); - embedBuilder.Title = question; - int len = answers.Length; - for (int i = 0; i < len; i++) - embedBuilder.AddField($"Answer {i + 1}", answers[i].Replace('-', ' '), true); - var msg = await context.Channel.SendMessageAsync(embed: embedBuilder.Build()); - - List emotes = new List(); - emotes.Add(Emoji.Parse(":one:")); - emotes.Add(Emoji.Parse(":two:")); - emotes.Add(Emoji.Parse(":three:")); - emotes.Add(Emoji.Parse(":four:")); - emotes.Add(Emoji.Parse(":five:")); - emotes.Add(Emoji.Parse(":six:")); - - for (int i = 0; i < len; i++) - await msg.AddReactionAsync(emotes[i]); - } + for (var i = 0; i < len; i++) await msg.AddReactionAsync(emotes[i]); } } diff --git a/CMD_Utils/Random.cs b/CMD_Utils/Random.cs index 4075588..2cbc564 100644 --- a/CMD_Utils/Random.cs +++ b/CMD_Utils/Random.cs @@ -1,6 +1,5 @@ using Discord.Commands; using Discord.WebSocket; - using PluginManager.Interfaces; public class Random : DBCommand @@ -11,7 +10,7 @@ public class Random : DBCommand public string Usage => "random [number1] [number2]"; - public bool canUseDM => true; + public bool canUseDM => true; public bool canUseServer => true; public bool requireAdmin => false; @@ -19,19 +18,18 @@ public class Random : DBCommand { try { - string msg = message.Content; - int a = int.Parse(msg.Split(' ')[1]); - int b = int.Parse(msg.Split(' ')[2]); + var msg = message.Content; + var a = int.Parse(msg.Split(' ')[1]); + var b = int.Parse(msg.Split(' ')[2]); if (a > b) { - int x = a; + var x = a; a = b; b = x; } await message.Channel.SendMessageAsync("Your random generated number is " + new System.Random().Next(a, b)); - } catch { diff --git a/DiscordBot/App.config b/DiscordBot/App.config index 828bd34..d78bbbb 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..11fb0f9 100644 --- a/DiscordBot/Discord/Commands/Help.cs +++ b/DiscordBot/Discord/Commands/Help.cs @@ -1,106 +1,100 @@ using Discord; using Discord.Commands; using Discord.WebSocket; - -using PluginManager.Loaders; using PluginManager.Interfaces; -using PluginManager.Others.Permissions; +using PluginManager.Loaders; using PluginManager.Others; -using System.Collections.Generic; +namespace DiscordBot.Discord.Commands; -namespace DiscordBot.Discord.Commands +/// +/// The help command +/// +internal class Help : DBCommand { /// - /// The help command + /// Command name /// - internal class Help : DBCommand + public string Command => "help"; + + /// + /// Command Description + /// + public string Description => "This command allows you to check all loadded commands"; + + /// + /// Command usage + /// + 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 + /// + public bool requireAdmin => false; + + /// + /// 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) { - /// - /// Command name - /// - public string Command => "help"; - - /// - /// Command Description - /// - public string Description => "This command allows you to check all loadded commands"; - - /// - /// Command usage - /// - 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 - /// - public bool requireAdmin => false; - - /// - /// 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) + var args = Functions.GetArguments(message); + if (args.Count != 0) { - List args = Functions.GetArguments(message); - if (args.Count != 0) + foreach (var item in args) { - - foreach (var item in args) - { - var e = GenerateHelpCommand(item); - if (e != null) - context.Channel.SendMessageAsync(embed: e.Build()); - else - context.Channel.SendMessageAsync("Unknown Command " + item); - } - return; - } - EmbedBuilder embedBuilder = new EmbedBuilder(); - - string adminCommands = ""; - string normalCommands = ""; - string DMCommands = ""; - - foreach (var cmd in PluginLoader.Commands!) - { - if (cmd.canUseDM) DMCommands += cmd.Command + " "; - if (cmd.requireAdmin) - adminCommands += cmd.Command + " "; - else if (cmd.canUseServer) normalCommands += cmd.Command + " "; + var e = GenerateHelpCommand(item); + if (e != null) + context.Channel.SendMessageAsync(embed: e.Build()); + else + context.Channel.SendMessageAsync("Unknown Command " + item); } - embedBuilder.AddField("Admin Commands", adminCommands); - embedBuilder.AddField("Normal Commands", normalCommands); - embedBuilder.AddField("DM Commands", DMCommands); - context.Channel.SendMessageAsync(embed: embedBuilder.Build()); - + return; } - private EmbedBuilder GenerateHelpCommand(string command) + var embedBuilder = new EmbedBuilder(); + + var adminCommands = ""; + var normalCommands = ""; + var DMCommands = ""; + + foreach (var cmd in PluginLoader.Commands!) { - EmbedBuilder embedBuilder = new EmbedBuilder(); - DBCommand cmd = PluginLoader.Commands.Find(p => p.Command == command); - if (cmd == null) - return null; - - embedBuilder.AddField("Usage", cmd.Usage); - embedBuilder.AddField("Description", cmd.Description); - - return embedBuilder; + if (cmd.canUseDM) DMCommands += cmd.Command + " "; + if (cmd.requireAdmin) + adminCommands += cmd.Command + " "; + else if (cmd.canUseServer) normalCommands += cmd.Command + " "; } + + embedBuilder.AddField("Admin Commands", adminCommands); + embedBuilder.AddField("Normal Commands", normalCommands); + embedBuilder.AddField("DM Commands", DMCommands); + context.Channel.SendMessageAsync(embed: embedBuilder.Build()); } -} \ No newline at end of file + + private EmbedBuilder GenerateHelpCommand(string command) + { + var embedBuilder = new EmbedBuilder(); + var cmd = PluginLoader.Commands.Find(p => p.Command == command); + if (cmd == null) return null; + + embedBuilder.AddField("Usage", cmd.Usage); + embedBuilder.AddField("Description", cmd.Description); + + return embedBuilder; + } +} diff --git a/DiscordBot/Discord/Commands/Restart.cs b/DiscordBot/Discord/Commands/Restart.cs index 3808118..a567783 100644 --- a/DiscordBot/Discord/Commands/Restart.cs +++ b/DiscordBot/Discord/Commands/Restart.cs @@ -1,114 +1,113 @@ using System; using System.Diagnostics; - using Discord.WebSocket; +using PluginManager.Interfaces; +using PluginManager.Others; +using PluginManager.Others.Permissions; using DiscordLibCommands = Discord.Commands; using DiscordLib = Discord; +using OperatingSystem = PluginManager.Others.OperatingSystem; -using PluginManager.Interfaces; -using PluginManager.Others.Permissions; -using PluginManager.Others; +namespace DiscordBot.Discord.Commands; -namespace DiscordBot.Discord.Commands +internal class Restart : DBCommand { - internal class Restart : DBCommand + /// + /// Command name + /// + public string Command => "restart"; + + /// + /// Command Description + /// + public string Description => "Restart the bot"; + + /// + /// Command usage + /// + 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; + + /// + /// 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) { - /// - /// Command name - /// - public string Command => "restart"; - - /// - /// Command Description - /// - public string Description => "Restart the bot"; - - /// - /// Command usage - /// - 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; - /// - /// 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) + if (!(message.Author as SocketGuildUser).hasPermission(DiscordLib.GuildPermission.Administrator)) return; + var args = Functions.GetArguments(message); + var OS = Functions.GetOperatingSystem(); + if (args.Count == 0) { - if (!DiscordPermissions.hasPermission(message.Author as SocketGuildUser, DiscordLib.GuildPermission.Administrator)) return; - var args = Functions.GetArguments(message); - var OS = Functions.GetOperatingSystem(); - if (args.Count == 0) + switch (OS) { + case OperatingSystem.WINDOWS: + Process.Start("./DiscordBot.exe"); + break; + case OperatingSystem.LINUX: + case OperatingSystem.MAC_OS: + Process.Start("./DiscordBot"); + break; + default: + return; + } + + return; + } + + switch (args[0]) + { + case "-p": + case "-poweroff": + case "-c": + case "-close": + Environment.Exit(0); + break; + case "-cmd": + case "-args": + var cmd = "--args"; + + if (args.Count > 1) + for (var i = 1; i < args.Count; i++) + cmd += $" {args[i]}"; + + switch (OS) { - case PluginManager.Others.OperatingSystem.WINDOWS: - Process.Start("./DiscordBot.exe"); + case OperatingSystem.WINDOWS: + Functions.WriteLogFile("Restarting the bot with the following arguments: \"" + cmd + "\""); + Process.Start("./DiscordBot.exe", cmd); break; - case PluginManager.Others.OperatingSystem.LINUX: - case PluginManager.Others.OperatingSystem.MAC_OS: - Process.Start("./DiscordBot"); + case OperatingSystem.LINUX: + //case PluginManager.Others.OperatingSystem.MAC_OS: ?? - not tested + Process.Start("./DiscordBot", cmd); break; default: return; } - return; - } - switch (args[0]) - { - case "-p": - case "-poweroff": - case "-c": - case "-close": - Environment.Exit(0); - break; - case "-cmd": - case "-args": - string cmd = "--args"; - - if (args.Count > 1) - for (int i = 1; i < args.Count; i++) - cmd += $" {args[i]}"; - - - switch (OS) - { - case PluginManager.Others.OperatingSystem.WINDOWS: - Functions.WriteLogFile("Restarting the bot with the following arguments: \"" + cmd + "\""); - Process.Start("./DiscordBot.exe", cmd); - break; - case PluginManager.Others.OperatingSystem.LINUX: - //case PluginManager.Others.OperatingSystem.MAC_OS: ?? - not tested - Process.Start("./DiscordBot", cmd); - break; - default: - return; - } - Environment.Exit(0); - break; - default: - await context.Channel.SendMessageAsync("Invalid argument. Use `help restart` to see the usage."); - break; - - - } + Environment.Exit(0); + break; + default: + await context.Channel.SendMessageAsync("Invalid argument. Use `help restart` to see the usage."); + break; } } } diff --git a/DiscordBot/Discord/Commands/Settings.cs b/DiscordBot/Discord/Commands/Settings.cs index a432c96..044a2fd 100644 --- a/DiscordBot/Discord/Commands/Settings.cs +++ b/DiscordBot/Discord/Commands/Settings.cs @@ -1,107 +1,97 @@ 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 DiscordBot.Discord.Core; using PluginManager; using PluginManager.Interfaces; -using PluginManager.Others; -using PluginManager.Others.Permissions; -namespace DiscordBot.Discord.Commands +namespace DiscordBot.Discord.Commands; + +internal class Settings : DBCommand { - class Settings : DBCommand + /// + /// Command name + /// + public string Command => "set"; + + /// + /// Command Description + /// + public string Description => "This command allows you change all settings. Use \"set help\" to show details"; + + /// + /// Command usage + /// + 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 + /// + 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(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) { - - /// - /// Command name - /// - public string Command => "set"; - - /// - /// Command Description - /// - public string Description => "This command allows you change all settings. Use \"set help\" to show details"; - - /// - /// Command usage - /// - 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 - /// - 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(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) + var channel = message.Channel; + try { - var channel = message.Channel; - try + var content = message.Content; + var data = content.Split(' '); + var keyword = data[1]; + if (keyword.ToLower() == "help") { - string content = message.Content; - string[] data = content.Split(' '); - string keyword = data[1]; - if (keyword.ToLower() == "help") - { - await channel.SendMessageAsync("set token [new value] -- set the value of the new token (require restart)"); - await channel.SendMessageAsync("set prefix [new value] -- set the value of the new preifx (require restart)"); + await channel.SendMessageAsync("set token [new value] -- set the value of the new token (require restart)"); + await channel.SendMessageAsync("set prefix [new value] -- set the value of the new preifx (require restart)"); - return; - } + return; + } - switch (keyword.ToLower()) - { - case "token": - if (data.Length != 3) - { - await channel.SendMessageAsync("Invalid token !"); - return; - } - - Config.SetValue("token", data[2]); - break; - case "prefix": - if (data.Length != 3) - { - await channel.SendMessageAsync("Invalid token !"); - return; - } - - Config.SetValue("token", data[2]); - break; - default: + switch (keyword.ToLower()) + { + case "token": + if (data.Length != 3) + { + await channel.SendMessageAsync("Invalid token !"); return; - } + } - await channel.SendMessageAsync("Restart required ..."); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - await channel.SendMessageAsync("Unknown usage to this command !\nUsage: " + Usage); + Config.SetValue("token", data[2]); + break; + case "prefix": + if (data.Length != 3) + { + await channel.SendMessageAsync("Invalid token !"); + return; + } + + Config.SetValue("token", data[2]); + break; + default: + return; } + await channel.SendMessageAsync("Restart required ..."); + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + await channel.SendMessageAsync("Unknown usage to this command !\nUsage: " + Usage); } } } diff --git a/DiscordBot/Discord/Core/Boot.cs b/DiscordBot/Discord/Core/Boot.cs index 942178f..af38879 100644 --- a/DiscordBot/Discord/Core/Boot.cs +++ b/DiscordBot/Discord/Core/Boot.cs @@ -1,150 +1,149 @@ -using Discord; -using Discord.Commands; -using Discord.WebSocket; -using System; +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 +namespace DiscordBot.Discord.Core; + +internal class Boot { - internal class Boot + /// + /// The bot prefix + /// + public readonly string botPrefix; + + /// + /// The bot token + /// + public readonly string botToken; + + /// + /// The bot client + /// + public DiscordSocketClient client; + + /// + /// The bot command handler + /// + private CommandHandler commandServiceHandler; + + /// + /// The command service + /// + private CommandService service; + + /// + /// The main Boot constructor + /// + /// The bot token + /// The bot prefix + public Boot(string botToken, string botPrefix) { - /// - /// The bot prefix - /// - public readonly string botPrefix; - - /// - /// The bot token - /// - public readonly string botToken; + this.botPrefix = botPrefix; + this.botToken = botToken; + } - /// - /// Checks if the bot is ready - /// - /// true if the bot is ready, othwerwise false - public bool isReady { get; private set; } = false; + /// + /// Checks if the bot is ready + /// + /// true if the bot is ready, othwerwise false + public bool isReady { get; private set; } - /// - /// The bot client - /// - public DiscordSocketClient client; + /// + /// The start method for the bot. This method is used to load the bot + /// + /// Task + public async Task Awake() + { + client = new DiscordSocketClient(); + service = new CommandService(); - /// - /// The bot command handler - /// - private CommandHandler commandServiceHandler; + CommonTasks(); - /// - /// The command service - /// - private CommandService service; + await client.LoginAsync(TokenType.Bot, botToken); + await client.StartAsync(); - /// - /// The main Boot constructor - /// - /// The bot token - /// The bot prefix - public Boot(string botToken, string botPrefix) - { - this.botPrefix = botPrefix; - this.botToken = botToken; - } + commandServiceHandler = new CommandHandler(client, service, botPrefix); + await commandServiceHandler.InstallCommandsAsync(); - /// - /// The start method for the bot. This method is used to load the bot - /// - /// Task - public async Task Awake() - { - client = new DiscordSocketClient(); - service = new CommandService(); + await Task.Delay(2000); + while (!isReady) ; + } - CommonTasks(); + private void CommonTasks() + { + if (client == null) return; + client.LoggedOut += Client_LoggedOut; + client.Log += Log; + client.LoggedIn += LoggedIn; + client.Ready += Ready; + } - await client.LoginAsync(TokenType.Bot, botToken); - await client.StartAsync(); + private Task Client_LoggedOut() + { + WriteLogFile("Successfully Logged Out"); + Log(new LogMessage(LogSeverity.Info, "Boot", "Successfully logged out from discord !")); + return Task.CompletedTask; + } - commandServiceHandler = new CommandHandler(client, service, botPrefix); - await commandServiceHandler.InstallCommandsAsync(); + private Task Ready() + { + Console.Title = "ONLINE"; + isReady = true; - await Task.Delay(2000); - while (!isReady) ; - - } - - private void CommonTasks() - { - if (client == null) return; - client.LoggedOut += Client_LoggedOut; - client.Log += Log; - client.LoggedIn += LoggedIn; - client.Ready += Ready; - } - - private Task Client_LoggedOut() - { - WriteLogFile("Successfully Logged Out"); - Log(new LogMessage(LogSeverity.Info, "Boot", "Successfully logged out from discord !")); - return Task.CompletedTask; - } - - private Task Ready() - { - Console.Title = "ONLINE"; - isReady = true; - - new Thread(async () => - { - while (true) - { - Config.SaveConfig(); - Thread.Sleep(10000); - } - } - ).Start(); - - return Task.CompletedTask; - } - - private Task LoggedIn() - { - Console.Title = "CONNECTED"; - WriteLogFile("The bot has been logged in at " + DateTime.Now.ToShortDateString() + " (" + - DateTime.Now.ToShortTimeString() + ")"); - return Task.CompletedTask; - } - - private Task Log(LogMessage message) - { - switch (message.Severity) + new Thread(async () => { - case LogSeverity.Error: - case LogSeverity.Critical: - WriteErrFile(message.Message); - - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine("[ERROR] " + message.Message); - Console.ForegroundColor = ConsoleColor.White; - - break; - - case LogSeverity.Info: - case LogSeverity.Debug: - WriteLogFile(message.Message); - - Console.ForegroundColor = ConsoleColor.Cyan; - Console.WriteLine("[INFO] " + message.Message); - Console.ForegroundColor = ConsoleColor.White; - - - break; + while (true) + { + Config.SaveConfig(); + Thread.Sleep(10000); + } } + ).Start(); - return Task.CompletedTask; + return Task.CompletedTask; + } + + private Task LoggedIn() + { + Console.Title = "CONNECTED"; + WriteLogFile("The bot has been logged in at " + DateTime.Now.ToShortDateString() + " (" + + DateTime.Now.ToShortTimeString() + ")" + ); + return Task.CompletedTask; + } + + private Task Log(LogMessage message) + { + switch (message.Severity) + { + case LogSeverity.Error: + case LogSeverity.Critical: + WriteErrFile(message.Message); + + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("[ERROR] " + message.Message); + Console.ForegroundColor = ConsoleColor.White; + + break; + + case LogSeverity.Info: + case LogSeverity.Debug: + WriteLogFile(message.Message); + + Console.ForegroundColor = ConsoleColor.Cyan; + Console.WriteLine("[INFO] " + message.Message); + Console.ForegroundColor = ConsoleColor.White; + + + break; } + + return Task.CompletedTask; } } diff --git a/DiscordBot/Discord/Core/CommandHandler.cs b/DiscordBot/Discord/Core/CommandHandler.cs index 16ed690..b876858 100644 --- a/DiscordBot/Discord/Core/CommandHandler.cs +++ b/DiscordBot/Discord/Core/CommandHandler.cs @@ -1,136 +1,132 @@ -using Discord.Commands; -using Discord.WebSocket; - -using PluginManager.Interfaces; - +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; -using PluginManager.Loaders; -using System.Threading.Tasks; -using System.Linq; -using Discord; -using System; +namespace DiscordBot.Discord.Core; -namespace DiscordBot.Discord.Core +internal class CommandHandler { - internal class CommandHandler + private readonly string botPrefix; + private readonly DiscordSocketClient client; + private readonly CommandService commandService; + + /// + /// Command handler constructor + /// + /// The discord bot client + /// The discord bot command service + /// The prefix to watch for + public CommandHandler(DiscordSocketClient client, CommandService commandService, string botPrefix) { - private readonly DiscordSocketClient client; - private readonly CommandService commandService; - private readonly string botPrefix; + this.client = client; + this.commandService = commandService; + this.botPrefix = botPrefix; + } - /// - /// Command handler constructor - /// - /// The discord bot client - /// The discord bot command service - /// The prefix to watch for - public CommandHandler(DiscordSocketClient client, CommandService commandService, string botPrefix) - { - this.client = client; - this.commandService = commandService; - this.botPrefix = botPrefix; - } + /// + /// The method to initialize all commands + /// + /// + public async Task InstallCommandsAsync() + { + client.MessageReceived += MessageHandler; + await commandService.AddModulesAsync(Assembly.GetEntryAssembly(), null); + } - /// - /// The method to initialize all commands - /// - /// - public async Task InstallCommandsAsync() + /// + /// The message handler for the bot + /// + /// The message got from the user in discord chat + /// + private async Task MessageHandler(SocketMessage Message) + { + try { - client.MessageReceived += MessageHandler; - await commandService.AddModulesAsync(assembly: Assembly.GetEntryAssembly(), services: null); - } + if (Message as SocketUserMessage == null) return; - /// - /// The message handler for the bot - /// - /// The message got from the user in discord chat - /// - private async Task MessageHandler(SocketMessage Message) - { - try + var message = Message as SocketUserMessage; + + if (message == null) return; + + if (!message.Content.StartsWith(botPrefix)) return; + + var argPos = 0; + + if (message.HasMentionPrefix(client.CurrentUser, ref argPos)) { - if (Message as SocketUserMessage == null) - return; + await message.Channel.SendMessageAsync("Can not exec mentioned commands !"); + return; + } - var message = Message as SocketUserMessage; + if (message.Author.IsBot) return; - if (message == null) return; + var context = new SocketCommandContext(client, message); - if (!message.Content.StartsWith(botPrefix)) return; + await commandService.ExecuteAsync( + context, + argPos, + null + ); - int argPos = 0; + var plugin = PluginLoader.Commands!.Where(p => p.Command == message.Content.Split(' ')[0].Substring(botPrefix.Length)).FirstOrDefault(); - if (message.HasMentionPrefix(client.CurrentUser, ref argPos)) + + if (plugin != null) + { + if (message.Channel == await message.Author.CreateDMChannelAsync()) { - await message.Channel.SendMessageAsync("Can not exec mentioned commands !"); - return; - } - - if (message.Author.IsBot) return; - - var context = new SocketCommandContext(client, message); - - await commandService.ExecuteAsync( - context: context, - argPos: argPos, - services: null - ); - - DBCommand plugin = PluginLoader.Commands!.Where(p => p.Command == (message.Content.Split(' ')[0]).Substring(botPrefix.Length)).FirstOrDefault(); - - - 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; - } - await message.Channel.SendMessageAsync("This command is for administrators only !"); - return; - } - 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.canUseDM) { if (plugin.requireAdmin) { if (message.Author.isAdmin()) { - plugin.Execute(context, message, client, false); - Functions.WriteLogFile($"[{message.Author.Id}] Executed command : " + plugin.Command); + plugin.Execute(context, message, client, true); + Functions.WriteLogFile($"[{message.Author.Id}] Executed command (DM) : " + 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); + + plugin.Execute(context, message, client, true); + Functions.WriteLogFile($"[{message.Author.Id}] Executed command (DM) : " + plugin.Command); return; } - 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); + return; } } - catch { } - + } + catch + { } } -} \ No newline at end of file +} diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index 28d6370..909558e 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -6,15 +6,14 @@ using System; using System.IO; using System.Linq; using System.Threading.Tasks; +using PluginManager.Online; namespace DiscordBot { public class Program { - private static bool loadPluginsOnStartup = false; - private static bool listPluginsAtStartup = false; - - private static bool listLanguagAtStartup = false; + private static bool loadPluginsOnStartup = false; + private static bool listPluginsAtStartup = false; /// /// The main entry point for the application. @@ -27,13 +26,7 @@ namespace DiscordBot Directory.CreateDirectory("./Data/Languages"); Directory.CreateDirectory("./Data/Plugins/Commands"); Directory.CreateDirectory("./Data/Plugins/Events"); - Config.LoadConfig().Wait(); - - if (Config.ContainsKey("DeleteLogsAtStartup")) - if (Config.GetValue("DeleteLogsAtStartup")) - foreach (string file in Directory.GetFiles("./Output/Logs/")) - File.Delete(file); - + PreLoadComponents(); if (!Config.ContainsKey("token") || Config.GetValue("token") == null || Config.GetValue("token")?.Length != 70) { @@ -84,7 +77,6 @@ namespace DiscordBot ConsoleCommandsHandler consoleCommandsHandler = new ConsoleCommandsHandler(discordbooter.client); if (loadPluginsOnStartup) consoleCommandsHandler.HandleCommand("lp"); if (listPluginsAtStartup) consoleCommandsHandler.HandleCommand("listplugs"); - if (listLanguagAtStartup) consoleCommandsHandler.HandleCommand("listlang"); Config.SaveConfig(); while (true) { @@ -165,12 +157,20 @@ namespace DiscordBot return; } + if (len == 3 && args[0] == "/download") + { + string url = args[1]; + string location = args[2]; + + await ServerCom.DownloadFileAsync(url, location); + + return; + } + 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; len = 0; } @@ -182,6 +182,7 @@ namespace DiscordBot return; } + Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine("Execute command interface noGUI\n\n"); Console.WriteLine( @@ -240,11 +241,22 @@ namespace DiscordBot Boot booter = await StartNoGUI(); await NoGUI(booter); return; + default: Console.WriteLine("Failed to execute command " + message[0]); break; } } } + + private static async Task PreLoadComponents() + { + Config.LoadConfig().Wait(); + + if (Config.ContainsKey("DeleteLogsAtStartup")) + if (Config.GetValue("DeleteLogsAtStartup")) + foreach (string file in Directory.GetFiles("./Output/Logs/")) + File.Delete(file); + } } } diff --git a/DiscordBotGUI/App.axaml b/DiscordBotGUI/App.axaml index 7d4aeba..49aa2e5 100644 --- a/DiscordBotGUI/App.axaml +++ b/DiscordBotGUI/App.axaml @@ -1,7 +1,7 @@ - - - - + + + + \ No newline at end of file diff --git a/DiscordBotGUI/App.axaml.cs b/DiscordBotGUI/App.axaml.cs index 456aca5..983b886 100644 --- a/DiscordBotGUI/App.axaml.cs +++ b/DiscordBotGUI/App.axaml.cs @@ -1,23 +1,21 @@ -using System.IO; using Avalonia; +using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; -using PluginManager.Others; -namespace DiscordBotGUI +namespace DiscordBotGUI; + +public class App : Application { - public partial class App : Application + public override void Initialize() { - public override void Initialize() - { - AvaloniaXamlLoader.Load(this); - } + AvaloniaXamlLoader.Load(this); + } - public override void OnFrameworkInitializationCompleted() - { - if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { desktop.MainWindow = new AppUpdater() { Width = 300, Height = 50, WindowStartupLocation = Avalonia.Controls.WindowStartupLocation.CenterScreen }; } + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) desktop.MainWindow = new AppUpdater { Width = 300, Height = 50, WindowStartupLocation = WindowStartupLocation.CenterScreen }; - base.OnFrameworkInitializationCompleted(); - } + base.OnFrameworkInitializationCompleted(); } } diff --git a/DiscordBotGUI/AppUpdater.axaml b/DiscordBotGUI/AppUpdater.axaml index c20c2e5..939c0d6 100644 --- a/DiscordBotGUI/AppUpdater.axaml +++ b/DiscordBotGUI/AppUpdater.axaml @@ -5,12 +5,13 @@ mc:Ignorable="d" d:DesignWidth="250" d:DesignHeight="50" x:Class="DiscordBotGUI.AppUpdater" Title="AppUpdater" - Background="Transparent" - TransparencyLevelHint="AcrylicBlur" - HasSystemDecorations="False"> + Background="Transparent" + TransparencyLevelHint="AcrylicBlur" + SystemDecorations="BorderOnly"> - - - - - + + + + + \ No newline at end of file diff --git a/DiscordBotGUI/AppUpdater.axaml.cs b/DiscordBotGUI/AppUpdater.axaml.cs index 662e2c8..fcf519f 100644 --- a/DiscordBotGUI/AppUpdater.axaml.cs +++ b/DiscordBotGUI/AppUpdater.axaml.cs @@ -11,7 +11,7 @@ namespace DiscordBotGUI { public partial class AppUpdater : Window { - private string _version; + private string _version = ""; public AppUpdater() { @@ -149,7 +149,7 @@ namespace DiscordBotGUI { try { - string current_version = Config.GetValue("Version"); + string current_version = Config.GetValue("Version"); if (current_version == null) if (!Config.SetValue("Version", "0")) Config.AddValueToVariables("Version", "0", false); diff --git a/DiscordBotGUI/MainWindow.axaml b/DiscordBotGUI/MainWindow.axaml index b3f98c7..c011ce7 100644 --- a/DiscordBotGUI/MainWindow.axaml +++ b/DiscordBotGUI/MainWindow.axaml @@ -5,32 +5,35 @@ mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="425" x:Class="DiscordBotGUI.MainWindow" Title="DiscordBotGUI" - Background="Transparent" - TransparencyLevelHint="AcrylicBlur" - ExtendClientAreaToDecorationsHint="True" > + Background="Transparent" + TransparencyLevelHint="AcrylicBlur" + ExtendClientAreaToDecorationsHint="True"> - - - - - + + + + + - - - + 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); + } +}