From ab0f44f1a3cec46f03addd7eb2e8058f0fff4d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20T=C3=B6rcsv=C3=A1ri?= Date: Thu, 21 Apr 2016 23:57:35 +0200 Subject: [PATCH 01/21] added .mono for heroku build --- .mono | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .mono diff --git a/.mono b/.mono new file mode 100644 index 00000000..2a3e39d9 --- /dev/null +++ b/.mono @@ -0,0 +1,6 @@ +# specify the build you want, either minimal (default) or full +# see below for explanation +MONO_TYPE=full +# if this is set, the cache is not used/cleaned. +# the cache is used to 1) store mono builds and 2) store nuget packages +MONO_CACHE=nope \ No newline at end of file From de3e8f80ff5398818576f16194247e5dc67a5e9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20T=C3=B6rcsv=C3=A1ri?= Date: Tue, 26 Apr 2016 23:17:40 +0200 Subject: [PATCH 02/21] fixed some conversion bug --- .../Modules/Searches/Commands/ConverterCommand.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/NadekoBot/Modules/Searches/Commands/ConverterCommand.cs b/NadekoBot/Modules/Searches/Commands/ConverterCommand.cs index 8d820df4..2383e718 100644 --- a/NadekoBot/Modules/Searches/Commands/ConverterCommand.cs +++ b/NadekoBot/Modules/Searches/Commands/ConverterCommand.cs @@ -92,6 +92,8 @@ namespace NadekoBot.Modules.Searches.Commands } else { + CultureInfo ci = new CultureInfo("en-US"); + Thread.CurrentThread.CurrentCulture = ci; reInitCurrencyConverterTable(); Unit inUnit = currTable.CreateUnit(quantity, from.ToUpperInvariant()); Unit outUnit = inUnit.Convert(currTable.CurrencyCode(to.ToUpperInvariant())); @@ -109,9 +111,16 @@ namespace NadekoBot.Modules.Searches.Commands { if (lastChanged == null || lastChanged.DayOfYear != DateTime.Now.DayOfYear) { - exchangeRateProvider = new WebExchangeRatesProvider(); - currTable = new CurrencyExchangeTable(exchangeRateProvider); - lastChanged = DateTime.Now; + try + { + exchangeRateProvider = new WebExchangeRatesProvider(); + currTable = new CurrencyExchangeTable(exchangeRateProvider); + lastChanged = DateTime.Now; + } + catch + { + Console.WriteLine("Error with the currency download."); + } } } From a15bb3c4a92a6dd2148858e49dd27330b2311787 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 27 Apr 2016 20:58:36 +0200 Subject: [PATCH 03/21] Fixed ~e621, closes #242 #243 --- NadekoBot/Classes/SearchHelper.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/NadekoBot/Classes/SearchHelper.cs b/NadekoBot/Classes/SearchHelper.cs index b8b7a8b5..ad78466f 100644 --- a/NadekoBot/Classes/SearchHelper.cs +++ b/NadekoBot/Classes/SearchHelper.cs @@ -263,12 +263,19 @@ namespace NadekoBot.Classes { try { - XDocument doc = await Task.Run(() => XDocument.Load(" http://e621.net/post/index.xml?tags=" + Uri.EscapeUriString(tags) + "%20order:random&limit=1")); - int id = Convert.ToInt32(doc.Root.Element("post").Element("id").Value); - return (doc.Root.Element("post").Element("file_url").Value); + var headers = new Dictionary() { + {"User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1"}, + {"Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" }, + }; + var data = await GetResponseStreamAsync( + "http://e621.net/post/index.xml?tags=" + Uri.EscapeUriString(tags) + "%20order:random&limit=1", + headers); + var doc = XDocument.Load(data); + return doc.Descendants("file_url").FirstOrDefault().Value; } - catch (Exception) + catch (Exception ex) { + Console.WriteLine("Error in e621 search: \n" + ex); return "Error, do you have too many tags?"; } } From b389d4429f0b5b7951a2039021725c2f642a7bdb Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 27 Apr 2016 21:01:00 +0200 Subject: [PATCH 04/21] removed .mono --- .mono | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .mono diff --git a/.mono b/.mono deleted file mode 100644 index 2a3e39d9..00000000 --- a/.mono +++ /dev/null @@ -1,6 +0,0 @@ -# specify the build you want, either minimal (default) or full -# see below for explanation -MONO_TYPE=full -# if this is set, the cache is not used/cleaned. -# the cache is used to 1) store mono builds and 2) store nuget packages -MONO_CACHE=nope \ No newline at end of file From 99c5c2e92fcfe6763e8a2876967d0a26da22f28c Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 27 Apr 2016 22:42:28 +0200 Subject: [PATCH 05/21] `.revimg` to reverse image search any link --- NadekoBot.sln | 2 +- NadekoBot/Modules/Searches/SearchesModule.cs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/NadekoBot.sln b/NadekoBot.sln index 5e8a3b96..e7681a7d 100644 --- a/NadekoBot.sln +++ b/NadekoBot.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25008.0 +VisualStudioVersion = 14.0.25123.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NadekoBot", "NadekoBot\NadekoBot.csproj", "{27A886F5-CDDA-4F4A-81EE-6DAFCCE9DE46}" EndProject diff --git a/NadekoBot/Modules/Searches/SearchesModule.cs b/NadekoBot/Modules/Searches/SearchesModule.cs index 4f7a3fb4..2c707255 100644 --- a/NadekoBot/Modules/Searches/SearchesModule.cs +++ b/NadekoBot/Modules/Searches/SearchesModule.cs @@ -409,6 +409,18 @@ $@"🌍 **Weather for** 【{obj["target"]}】 return; await e.Channel.SendMessage($"https://images.google.com/searchbyimage?image_url={usr.AvatarUrl}").ConfigureAwait(false); }); + + cgb.CreateCommand(Prefix + "revimg") + .Description("Returns a google reverse image search for an image from a link.") + .Parameter("image", ParameterType.Unparsed) + .Do(async e => + { + var imgLink = e.GetArg("image")?.Trim(); + + if (string.IsNullOrWhiteSpace(imgLink)) + return; + await e.Channel.SendMessage($"https://images.google.com/searchbyimage?image_url={imgLink}").ConfigureAwait(false); + }); }); } } From 673a476f5febf40a2b8214979acda67a4315d878 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 27 Apr 2016 23:38:15 +0200 Subject: [PATCH 06/21] moved safebooru to searches (from nsfw) --- NadekoBot/Modules/NSFW/NSFWModule.cs | 9 +-------- NadekoBot/Modules/Searches/SearchesModule.cs | 9 +++++++++ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/NadekoBot/Modules/NSFW/NSFWModule.cs b/NadekoBot/Modules/NSFW/NSFWModule.cs index d75ad531..c18d6d09 100644 --- a/NadekoBot/Modules/NSFW/NSFWModule.cs +++ b/NadekoBot/Modules/NSFW/NSFWModule.cs @@ -48,14 +48,7 @@ namespace NadekoBot.Modules.NSFW var tag = e.GetArg("tag")?.Trim() ?? ""; await e.Channel.SendMessage(await SearchHelper.GetGelbooruImageLink(tag).ConfigureAwait(false)).ConfigureAwait(false); }); - cgb.CreateCommand(Prefix + "safebooru") - .Description("Shows a random image from safebooru with a given tag. Tag is optional but preffered. (multiple tags are appended with +)\n**Usage**: ~safebooru yuri+kissing") - .Parameter("tag", ParameterType.Unparsed) - .Do(async e => - { - var tag = e.GetArg("tag")?.Trim() ?? ""; - await e.Channel.SendMessage(await SearchHelper.GetSafebooruImageLink(tag).ConfigureAwait(false)).ConfigureAwait(false); - }); + cgb.CreateCommand(Prefix + "rule34") .Description("Shows a random image from rule34.xx with a given tag. Tag is optional but preffered. (multiple tags are appended with +)\n**Usage**: ~gelbooru yuri+kissing") .Parameter("tag", ParameterType.Unparsed) diff --git a/NadekoBot/Modules/Searches/SearchesModule.cs b/NadekoBot/Modules/Searches/SearchesModule.cs index 2c707255..0d0429d1 100644 --- a/NadekoBot/Modules/Searches/SearchesModule.cs +++ b/NadekoBot/Modules/Searches/SearchesModule.cs @@ -421,6 +421,15 @@ $@"🌍 **Weather for** 【{obj["target"]}】 return; await e.Channel.SendMessage($"https://images.google.com/searchbyimage?image_url={imgLink}").ConfigureAwait(false); }); + + cgb.CreateCommand(Prefix + "safebooru") + .Description("Shows a random image from safebooru with a given tag. Tag is optional but preffered. (multiple tags are appended with +)\n**Usage**: ~safebooru yuri+kissing") + .Parameter("tag", ParameterType.Unparsed) + .Do(async e => + { + var tag = e.GetArg("tag")?.Trim() ?? ""; + await e.Channel.SendMessage(await SearchHelper.GetSafebooruImageLink(tag).ConfigureAwait(false)).ConfigureAwait(false); + }); }); } } From 3d3ecec7c860b73f304bfd3399a534143139a72f Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 27 Apr 2016 23:54:09 +0200 Subject: [PATCH 07/21] `-h command name` works with aliasses too now. --- .../Modules/Help/Commands/HelpCommand.cs | 38 +++---------------- 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/NadekoBot/Modules/Help/Commands/HelpCommand.cs b/NadekoBot/Modules/Help/Commands/HelpCommand.cs index 8aedcea9..ca5ad29d 100644 --- a/NadekoBot/Modules/Help/Commands/HelpCommand.cs +++ b/NadekoBot/Modules/Help/Commands/HelpCommand.cs @@ -11,45 +11,19 @@ namespace NadekoBot.Classes.Help.Commands { internal class HelpCommand : DiscordCommand { - public Func DoFunc() => async e => + public Func HelpFunc() => async e => { - #region OldHelp - /* - string helpstr = "**COMMANDS DO NOT WORK IN PERSONAL MESSAGES**\nOfficial repo: **github.com/Kwoth/NadekoBot/**"; - - string lastCategory = ""; - foreach (var com in client.GetService().AllCommands) - { - if (com.Category != lastCategory) - { - helpstr += "\n`----`**`" + com.Category + "`**`----`\n"; - lastCategory = com.Category; - } - helpstr += PrintCommandHelp(com); - } - helpstr += "\nBot Creator's server: https://discord.gg/0ehQwTK2RBhxEi0X"; - helpstr = helpstr.Replace(NadekoBot.botMention, "@BotName"); - while (helpstr.Length > 2000) - { - var curstr = helpstr.Substring(0, 2000); - await e.User.Send(curstr.Substring(0, curstr.LastIndexOf("\n") + 1)).ConfigureAwait(false); - helpstr = curstr.Substring(curstr.LastIndexOf("\n") + 1) + helpstr.Substring(2000); - await Task.Delay(200).ConfigureAwait(false); - } - */ - #endregion OldHelp - - if (string.IsNullOrWhiteSpace(e.GetArg("command"))) + var comToFind = e.GetArg("command")?.ToLowerInvariant(); + if (string.IsNullOrWhiteSpace(comToFind)) { await e.User.Send(HelpString).ConfigureAwait(false); return; } await Task.Run(async () => { - var comToFind = e.GetArg("command"); - var com = NadekoBot.Client.GetService().AllCommands - .FirstOrDefault(c => c.Text.ToLower().Equals(comToFind)); + .FirstOrDefault(c => c.Text.ToLowerInvariant().Equals(comToFind) || + c.Aliases.Select(a => a.ToLowerInvariant()).Contains(comToFind)); if (com != null) await e.Channel.SendMessage($"`Help for '{com.Text}':` **{com.Description}**").ConfigureAwait(false); }).ConfigureAwait(false); @@ -102,7 +76,7 @@ Version: `{NadekoStats.Instance.BotVersion}`"; .Alias(Module.Prefix + "help", NadekoBot.BotMention + " help", NadekoBot.BotMention + " h", "~h") .Description("Either shows a help for a single command, or PMs you help link if no arguments are specified.\n**Usage**: '-h !m q' or just '-h' ") .Parameter("command", ParameterType.Unparsed) - .Do(DoFunc()); + .Do(HelpFunc()); cgb.CreateCommand(Module.Prefix + "hgit") .Description("Generates the commandlist.md file. **Owner Only!**") .AddCheck(SimpleCheckers.OwnerOnly()) From 869c1e54237cb447a9659324ebf95bf0b8b5c7c8 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Wed, 27 Apr 2016 23:54:30 +0200 Subject: [PATCH 08/21] `!m getlink`/`!m gl` shows a link to the currently playing song --- NadekoBot/Modules/Music/MusicModule.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/NadekoBot/Modules/Music/MusicModule.cs b/NadekoBot/Modules/Music/MusicModule.cs index bb0acd11..b7724429 100644 --- a/NadekoBot/Modules/Music/MusicModule.cs +++ b/NadekoBot/Modules/Music/MusicModule.cs @@ -589,6 +589,20 @@ namespace NadekoBot.Modules.Music await e.Channel.SendMessage($"`Skipped to {minutes}:{seconds}`").ConfigureAwait(false); }); + + cgb.CreateCommand("getlink") + .Alias("gl") + .Description("Shows a link to the currently playing song.") + .Do(async e => + { + MusicPlayer musicPlayer; + if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer)) + return; + var curSong = musicPlayer.CurrentSong; + if (curSong == null) + return; + await e.Channel.SendMessage($"🎶`Current song:` <{curSong.SongInfo.Query}>"); + }); }); } From 4dc47a461e0d1995a0c237b4710ae44145ccb17c Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Fri, 29 Apr 2016 15:47:59 +0200 Subject: [PATCH 09/21] closes #248 --- NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs b/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs index 2865b1b2..55ac9c20 100644 --- a/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs +++ b/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs @@ -130,7 +130,7 @@ namespace NadekoBot.Modules.Games.Commands.Trivia await channel.SendMessage($"☑️ {e.User.Mention} guessed it! The answer was: **{CurrentQuestion.Answer}**").ConfigureAwait(false); if (Users[e.User] != WinRequirement) return; ShouldStopGame = true; - await channel.Send($":exclamation: We have a winner! Its {e.User.Mention}.").ConfigureAwait(false); + await channel.Send($":exclamation: We have a winner! It's {e.User.Mention}.").ConfigureAwait(false); // add points to the winner await FlowersHandler.AddFlowersAsync(e.User, "Won Trivia", 2).ConfigureAwait(false); } From b789ed9adf355af7a42f102e5704ba6584039b9f Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Sat, 30 Apr 2016 17:05:02 +0200 Subject: [PATCH 10/21] leftover line from debugging --- NadekoBot/NadekoBot.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/NadekoBot/NadekoBot.cs b/NadekoBot/NadekoBot.cs index ac61d96d..9414f21b 100644 --- a/NadekoBot/NadekoBot.cs +++ b/NadekoBot/NadekoBot.cs @@ -198,7 +198,6 @@ namespace NadekoBot await Client.Connect(Creds.Token).ConfigureAwait(false); IsBot = true; } - Console.WriteLine(NadekoBot.Client.CurrentUser.Id); } catch (Exception ex) { From caa2a456f83f63683360c6028ef75d4aada7528e Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Sun, 1 May 2016 02:53:09 +0200 Subject: [PATCH 11/21] started work hs execution --- .../Programming/Commands/HaskellRepl.cs | 60 +++++++++++++++++++ .../Modules/Programming/ProgrammingModule.cs | 26 ++++++++ 2 files changed, 86 insertions(+) create mode 100644 NadekoBot/Modules/Programming/Commands/HaskellRepl.cs create mode 100644 NadekoBot/Modules/Programming/ProgrammingModule.cs diff --git a/NadekoBot/Modules/Programming/Commands/HaskellRepl.cs b/NadekoBot/Modules/Programming/Commands/HaskellRepl.cs new file mode 100644 index 00000000..567d9b84 --- /dev/null +++ b/NadekoBot/Modules/Programming/Commands/HaskellRepl.cs @@ -0,0 +1,60 @@ +using Discord; +using Discord.Commands; +using NadekoBot.Classes; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; + +/// +/// I have no idea what am i doing +/// +namespace NadekoBot.Modules.Programming.Commands +{ + class HaskellRepl : DiscordCommand + { + Queue> commandQueue = new Queue>(); + + Thread haskellThread; + + public HaskellRepl(DiscordModule module) : base(module) + { + //start haskell interpreter + + haskellThread = new Thread(new ThreadStart(() => + { + Process.Start(new ProcessStartInfo + { + FileName = "stack", //shouldn't use repl, but a Language.Haskell.Interpreter somehow + Arguments = "repl" + }); + + })); + + + Task.Run(() => + { + //read from queue + + //send the command to the process + + //wait 50 ms for execution + + //read everything from the output + + //send to chanenl + }); + + } + + internal override void Init(CommandGroupBuilder cgb) + { + cgb.CreateCommand(Module.Prefix + "hs") + .Description("Executes a haskell express with LAMBDABOT") + .Do(async e => + { + //send a command and a channel to the queue + }); + } + } +} diff --git a/NadekoBot/Modules/Programming/ProgrammingModule.cs b/NadekoBot/Modules/Programming/ProgrammingModule.cs new file mode 100644 index 00000000..feb3c4e2 --- /dev/null +++ b/NadekoBot/Modules/Programming/ProgrammingModule.cs @@ -0,0 +1,26 @@ +using Discord.Modules; +using NadekoBot.Extensions; +using NadekoBot.Modules.Permissions.Classes; +using NadekoBot.Modules.Programming.Commands; + +namespace NadekoBot.Modules.Programming +{ + class ProgrammingModule : DiscordModule + { + public override string Prefix => NadekoBot.Config.CommandPrefixes.Programming; + + public ProgrammingModule() + { + commands.Add(new HaskellRepl(this)); + } + + public override void Install(ModuleManager manager) + { + manager.CreateCommands("", cgb => + { + cgb.AddCheck(PermissionChecker.Instance); + commands.ForEach(c => c.Init(cgb)); + }); + } + } +} From 6da4c3db11d64b85edd71ec61c754a4bb4053f1b Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Sun, 1 May 2016 16:21:36 +0200 Subject: [PATCH 12/21] it sorta works, still need to actually use interpreter --- .../Programming/Commands/HaskellRepl.cs | 68 ++++++++++++++----- NadekoBot/NadekoBot.cs | 2 + NadekoBot/NadekoBot.csproj | 2 + 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/NadekoBot/Modules/Programming/Commands/HaskellRepl.cs b/NadekoBot/Modules/Programming/Commands/HaskellRepl.cs index 567d9b84..f8c1f78d 100644 --- a/NadekoBot/Modules/Programming/Commands/HaskellRepl.cs +++ b/NadekoBot/Modules/Programming/Commands/HaskellRepl.cs @@ -1,8 +1,10 @@ using Discord; using Discord.Commands; using NadekoBot.Classes; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; +using System.Text; using System.Threading; using System.Threading.Tasks; @@ -13,7 +15,7 @@ namespace NadekoBot.Modules.Programming.Commands { class HaskellRepl : DiscordCommand { - Queue> commandQueue = new Queue>(); + ConcurrentQueue> commandQueue = new ConcurrentQueue>(); Thread haskellThread; @@ -23,27 +25,51 @@ namespace NadekoBot.Modules.Programming.Commands haskellThread = new Thread(new ThreadStart(() => { - Process.Start(new ProcessStartInfo + var p = Process.Start(new ProcessStartInfo { FileName = "stack", //shouldn't use repl, but a Language.Haskell.Interpreter somehow - Arguments = "repl" + Arguments = "repl", + UseShellExecute = false, + RedirectStandardInput = true, + RedirectStandardOutput = true, + CreateNoWindow = true, + }); + + Task.Run(async () => + { + while (true) + { + while (commandQueue.Count == 0) + await Task.Delay(100); + + //read from queue + KeyValuePair com; + if (!commandQueue.TryDequeue(out com)) + { + await Task.Delay(100); + continue; + } + //var bytes = Encoding.ASCII.GetBytes(com.Key); + + //send the command to the process + p.StandardInput.WriteLine(com.Key); + + //wait 50 ms for execution + await Task.Delay(50); + + //read everything from the output + var outBuffer = new byte[1500]; + + p.StandardOutput.BaseStream.Read(outBuffer, 0, 1500); + + var outStr = Encoding.ASCII.GetString(outBuffer); + //send to channel + await com.Value.SendMessage($"```hs\nPrelude> {com.Key}\n" + outStr + "\n```"); + } }); })); - - - Task.Run(() => - { - //read from queue - - //send the command to the process - - //wait 50 ms for execution - - //read everything from the output - - //send to chanenl - }); + haskellThread.Start(); } @@ -51,9 +77,15 @@ namespace NadekoBot.Modules.Programming.Commands { cgb.CreateCommand(Module.Prefix + "hs") .Description("Executes a haskell express with LAMBDABOT") - .Do(async e => + .Parameter("command", ParameterType.Unparsed) + .Do(e => { + var com = e.GetArg("command")?.Trim(); + if (string.IsNullOrWhiteSpace(com)) + return; + //send a command and a channel to the queue + commandQueue.Enqueue(new KeyValuePair(com, e.Channel)); }); } } diff --git a/NadekoBot/NadekoBot.cs b/NadekoBot/NadekoBot.cs index 9414f21b..2e7ffe7f 100644 --- a/NadekoBot/NadekoBot.cs +++ b/NadekoBot/NadekoBot.cs @@ -16,6 +16,7 @@ using NadekoBot.Modules.NSFW; using NadekoBot.Modules.Permissions; using NadekoBot.Modules.Permissions.Classes; using NadekoBot.Modules.Pokemon; +using NadekoBot.Modules.Programming; using NadekoBot.Modules.Searches; using NadekoBot.Modules.Translator; using NadekoBot.Modules.Trello; @@ -183,6 +184,7 @@ namespace NadekoBot modules.Add(new ClashOfClansModule(), "ClashOfClans", ModuleFilter.None); modules.Add(new PokemonModule(), "Pokegame", ModuleFilter.None); modules.Add(new TranslatorModule(), "Translator", ModuleFilter.None); + modules.Add(new ProgrammingModule(), "Programming", ModuleFilter.None); if (!string.IsNullOrWhiteSpace(Creds.TrelloAppKey)) modules.Add(new TrelloModule(), "Trello", ModuleFilter.None); diff --git a/NadekoBot/NadekoBot.csproj b/NadekoBot/NadekoBot.csproj index 8660d194..f8d39b81 100644 --- a/NadekoBot/NadekoBot.csproj +++ b/NadekoBot/NadekoBot.csproj @@ -123,6 +123,8 @@ + + From e17a32030134d4f5da68411e7c33098586aa2d10 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Sun, 1 May 2016 18:13:12 +0200 Subject: [PATCH 13/21] Shuffling stuff larger than 256 will work properly now. Thanks to Joe4evr for finding the bug --- NadekoBot/Classes/Extensions.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/NadekoBot/Classes/Extensions.cs b/NadekoBot/Classes/Extensions.cs index fea6b61a..c3062c5f 100644 --- a/NadekoBot/Classes/Extensions.cs +++ b/NadekoBot/Classes/Extensions.cs @@ -138,14 +138,21 @@ namespace NadekoBot.Extensions /// public static void Shuffle(this IList list) { + + // Thanks to @Joe4Evr for finding a bug in the old version of the shuffle var provider = new RNGCryptoServiceProvider(); var n = list.Count; while (n > 1) { - var box = new byte[1]; - do provider.GetBytes(box); - while (!(box[0] < n * (byte.MaxValue / n))); - var k = (box[0] % n); + var box = new byte[(n / Byte.MaxValue) + 1]; + int boxSum; + do + { + provider.GetBytes(box); + boxSum = box.Sum(b => b); + } + while (!(boxSum < n * ((Byte.MaxValue * box.Length) / n))); + var k = (boxSum % n); n--; var value = list[k]; list[k] = list[n]; From 6f067f219b64fcadf58487c55a65fe20d30d1d80 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Mon, 2 May 2016 00:45:44 +0200 Subject: [PATCH 14/21] !m pls added, thanks to Keskitariv for the suggestion --- NadekoBot/Classes/DBHandler.cs | 26 +++++++++++++++++++++++++ NadekoBot/Classes/NadekoStats.cs | 5 +++-- NadekoBot/Modules/Music/MusicModule.cs | 27 ++++++++++++++++---------- 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/NadekoBot/Classes/DBHandler.cs b/NadekoBot/Classes/DBHandler.cs index b6b85c9c..caf1cd22 100644 --- a/NadekoBot/Classes/DBHandler.cs +++ b/NadekoBot/Classes/DBHandler.cs @@ -158,9 +158,35 @@ namespace NadekoBot.Classes return conn.Table().Where(p).ToList().OrderBy(x => r.Next()).FirstOrDefault(); } } + /// + /// + /// + /// Page number (0+) + /// + internal List GetPlaylistData(int num) + { + using (var conn = new SQLiteConnection(FilePath)) + { + return conn.Query( +@"SELECT mp.Name as 'Name',mp.Id as 'Id', mp.CreatorName as 'Creator', Count(*) as 'SongCnt' FROM MusicPlaylist as mp +INNER JOIN PlaylistSongInfo as psi +ON mp.Id = psi.PlaylistId +Group BY mp.Name +Order By mp.DateAdded desc +Limit 20 OFFSET ?", num * 20); + } + } } } +public class PlaylistData +{ + public string Name { get; set; } + public int Id { get; set; } + public string Creator { get; set; } + public int SongCnt { get; set; } +} + public static class Queries { public static string TransactionTriggerQuery = @" diff --git a/NadekoBot/Classes/NadekoStats.cs b/NadekoBot/Classes/NadekoStats.cs index 69dcdf70..483e2214 100644 --- a/NadekoBot/Classes/NadekoStats.cs +++ b/NadekoBot/Classes/NadekoStats.cs @@ -219,9 +219,10 @@ namespace NadekoBot DateAdded = DateTime.Now }); } - catch + catch (Exception ex) { - Console.WriteLine("Error in ran command DB write."); + Console.WriteLine("Probably unimportant error in ran command DB write."); + Console.WriteLine(ex); } }).ConfigureAwait(false); } diff --git a/NadekoBot/Modules/Music/MusicModule.cs b/NadekoBot/Modules/Music/MusicModule.cs index b7724429..8b1bb252 100644 --- a/NadekoBot/Modules/Music/MusicModule.cs +++ b/NadekoBot/Modules/Music/MusicModule.cs @@ -488,16 +488,6 @@ namespace NadekoBot.Modules.Music }); - //cgb.CreateCommand("info") - // .Description("Prints music info (queued/finished/playing) only to this channel") - // .Do(async e => - // { - // MusicPlayer musicPlayer; - // if (!MusicPlayers.TryGetValue(e.Server, out musicPlayer)) - // return; - // musicPlayer - // }); - cgb.CreateCommand("load") .Description("Loads a playlist under a certain name. \n**Usage**: `!m load classical-1`") .Parameter("name", ParameterType.Unparsed) @@ -553,6 +543,23 @@ namespace NadekoBot.Modules.Music } }); + cgb.CreateCommand("playlists") + .Alias("pls") + .Description("Lists all playlists. Paginated. 20 per page. Default page is 0.\n**Usage**:`!m pls 1`") + .Parameter("num", ParameterType.Optional) + .Do(e => + { + int num = 0; + int.TryParse(e.GetArg("num"), out num); + if (num < 0) + return; + var result = DbHandler.Instance.GetPlaylistData(num); + if (result.Count == 0) + e.Channel.SendMessage($"`No saved playlists found on page {num}`"); + else + e.Channel.SendMessage($"```js\n--- List of saved playlists ---\n\n" + string.Join("\n", result.Select(r => $"'{r.Name}-{r.Id}' by {r.Creator} ({r.SongCnt} songs)")) + $"\n\n --- Page {num} ---```"); + }); + cgb.CreateCommand("goto") .Description("Goes to a specific time in seconds in a song.") .Parameter("time") From d8953e7db4c3a9816e6f9d2624870b5ed21c5b13 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Mon, 2 May 2016 00:59:58 +0200 Subject: [PATCH 15/21] hardcoded 2 seconds delay in order to make .stats work --- NadekoBot/NadekoBot.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NadekoBot/NadekoBot.cs b/NadekoBot/NadekoBot.cs index 2e7ffe7f..7c789a56 100644 --- a/NadekoBot/NadekoBot.cs +++ b/NadekoBot/NadekoBot.cs @@ -212,7 +212,7 @@ namespace NadekoBot return; } - //await Task.Delay(90000).ConfigureAwait(false); + await Task.Delay(2000).ConfigureAwait(false); Console.WriteLine("-----------------"); Console.WriteLine(await NadekoStats.Instance.GetStats().ConfigureAwait(false)); Console.WriteLine("-----------------"); From 9321fcdc8a108df14f6f0117dadd1694a14dde39 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Mon, 2 May 2016 01:08:44 +0200 Subject: [PATCH 16/21] Programming module was crashing people with no stack - disabled --- NadekoBot/NadekoBot.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/NadekoBot/NadekoBot.cs b/NadekoBot/NadekoBot.cs index 7c789a56..8f071035 100644 --- a/NadekoBot/NadekoBot.cs +++ b/NadekoBot/NadekoBot.cs @@ -16,7 +16,6 @@ using NadekoBot.Modules.NSFW; using NadekoBot.Modules.Permissions; using NadekoBot.Modules.Permissions.Classes; using NadekoBot.Modules.Pokemon; -using NadekoBot.Modules.Programming; using NadekoBot.Modules.Searches; using NadekoBot.Modules.Translator; using NadekoBot.Modules.Trello; @@ -184,7 +183,7 @@ namespace NadekoBot modules.Add(new ClashOfClansModule(), "ClashOfClans", ModuleFilter.None); modules.Add(new PokemonModule(), "Pokegame", ModuleFilter.None); modules.Add(new TranslatorModule(), "Translator", ModuleFilter.None); - modules.Add(new ProgrammingModule(), "Programming", ModuleFilter.None); + //modules.Add(new ProgrammingModule(), "Programming", ModuleFilter.None); if (!string.IsNullOrWhiteSpace(Creds.TrelloAppKey)) modules.Add(new TrelloModule(), "Trello", ModuleFilter.None); From d9f1988be5cfdf6e8d236f0c650f3c2de449b932 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Mon, 2 May 2016 01:31:35 +0200 Subject: [PATCH 17/21] Added toggle-able deletion of greet/bye messages --- .../Commands/ServerGreetCommand.cs | 34 ++++++++++++++++--- .../_Models/DataModels/AnnouncementModel.cs | 1 + 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs b/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs index de915b73..96cfbe2a 100644 --- a/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs +++ b/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs @@ -69,9 +69,9 @@ namespace NadekoBot.Modules.Administration.Commands if (channel == null) return; Greeted++; var toDelete = await channel.SendMessage(msg).ConfigureAwait(false); - if (e.Server.CurrentUser.GetPermissions(channel).ManageMessages) + if (e.Server.CurrentUser.GetPermissions(channel).ManageMessages && controls.DeleteGreetMessages) { - await Task.Delay(300000).ConfigureAwait(false); // 5 minutes + await Task.Delay(30000).ConfigureAwait(false); // 5 minutes await toDelete.Delete().ConfigureAwait(false); } } @@ -102,9 +102,9 @@ namespace NadekoBot.Modules.Administration.Commands if (channel == null) return; Greeted++; var toDelete = await channel.SendMessage(msg).ConfigureAwait(false); - if (e.Server.CurrentUser.GetPermissions(channel).ManageMessages) + if (e.Server.CurrentUser.GetPermissions(channel).ManageMessages && controls.DeleteGreetMessages) { - await Task.Delay(300000).ConfigureAwait(false); // 5 minutes + await Task.Delay(30000).ConfigureAwait(false); // 5 minutes await toDelete.Delete().ConfigureAwait(false); } } @@ -160,6 +160,15 @@ namespace NadekoBot.Modules.Administration.Commands set { _model.ServerId = (long)value; } } + public bool DeleteGreetMessages { + get { + return _model.DeleteGreetMessages; + } + set { + _model.DeleteGreetMessages = value; Save(); + } + } + public AnnounceControls(DataModels.Announcement model) { this._model = model; @@ -196,6 +205,8 @@ namespace NadekoBot.Modules.Administration.Commands return Greet = true; } } + + internal bool ToggleDelete() => DeleteGreetMessages = !DeleteGreetMessages; internal bool ToggleGreetPM() => GreetPM = !GreetPM; internal bool ToggleByePM() => ByePM = !ByePM; @@ -207,6 +218,21 @@ namespace NadekoBot.Modules.Administration.Commands internal override void Init(CommandGroupBuilder cgb) { + cgb.CreateCommand(Module.Prefix + "grdel") + .Description("Enables or Disables automatic deletion of greet and bye messages.") + .Do(async e => + { + if (!e.User.ServerPermissions.ManageServer) return; + if (!AnnouncementsDictionary.ContainsKey(e.Server.Id)) + AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id)); + + var controls = AnnouncementsDictionary[e.Server.Id]; + + if (controls.ToggleDelete()) + await e.Channel.SendMessage("`Automatic deletion of greet and bye messages has been enabled.`").ConfigureAwait(false); + else + await e.Channel.SendMessage("`Automatic deletion of greet and bye messages has been disabled.`").ConfigureAwait(false); + }); cgb.CreateCommand(Module.Prefix + "greet") .Description("Enables or Disables anouncements on the current channel when someone joins the server.") diff --git a/NadekoBot/_Models/DataModels/AnnouncementModel.cs b/NadekoBot/_Models/DataModels/AnnouncementModel.cs index 534daf24..c4103dad 100644 --- a/NadekoBot/_Models/DataModels/AnnouncementModel.cs +++ b/NadekoBot/_Models/DataModels/AnnouncementModel.cs @@ -15,5 +15,6 @@ namespace NadekoBot.DataModels [JsonProperty("byeChannel")] public long ByeChannelId { get; set; } = 0; public string ByeText { get; set; } = "%user% has left the server."; + public bool DeleteGreetMessages { get; set; } = true; } } From 6c55e68c620957bae5df8f5252066a5eef778959 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Mon, 2 May 2016 01:40:53 +0200 Subject: [PATCH 18/21] greet/bye small cleanup, code is still disgusting --- .../Commands/ServerGreetCommand.cs | 53 +++++++------------ 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs b/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs index 96cfbe2a..398ce975 100644 --- a/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs +++ b/NadekoBot/Modules/Administration/Commands/ServerGreetCommand.cs @@ -223,12 +223,9 @@ namespace NadekoBot.Modules.Administration.Commands .Do(async e => { if (!e.User.ServerPermissions.ManageServer) return; - if (!AnnouncementsDictionary.ContainsKey(e.Server.Id)) - AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id)); + var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id)); - var controls = AnnouncementsDictionary[e.Server.Id]; - - if (controls.ToggleDelete()) + if (ann.ToggleDelete()) await e.Channel.SendMessage("`Automatic deletion of greet and bye messages has been enabled.`").ConfigureAwait(false); else await e.Channel.SendMessage("`Automatic deletion of greet and bye messages has been disabled.`").ConfigureAwait(false); @@ -239,12 +236,9 @@ namespace NadekoBot.Modules.Administration.Commands .Do(async e => { if (!e.User.ServerPermissions.ManageServer) return; - if (!AnnouncementsDictionary.ContainsKey(e.Server.Id)) - AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id)); + var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id)); - var controls = AnnouncementsDictionary[e.Server.Id]; - - if (controls.ToggleGreet(e.Channel.Id)) + if (ann.ToggleGreet(e.Channel.Id)) await e.Channel.SendMessage("Greet announcements enabled on this channel.").ConfigureAwait(false); else await e.Channel.SendMessage("Greet announcements disabled.").ConfigureAwait(false); @@ -257,12 +251,11 @@ namespace NadekoBot.Modules.Administration.Commands { if (!e.User.ServerPermissions.ManageServer) return; if (e.GetArg("msg") == null) return; - if (!AnnouncementsDictionary.ContainsKey(e.Server.Id)) - AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id)); + var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id)); - AnnouncementsDictionary[e.Server.Id].GreetText = e.GetArg("msg"); + ann.GreetText = e.GetArg("msg"); await e.Channel.SendMessage("New greet message set.").ConfigureAwait(false); - if (!AnnouncementsDictionary[e.Server.Id].Greet) + if (!ann.Greet) await e.Channel.SendMessage("Enable greet messsages by typing `.greet`").ConfigureAwait(false); }); @@ -271,12 +264,9 @@ namespace NadekoBot.Modules.Administration.Commands .Do(async e => { if (!e.User.ServerPermissions.ManageServer) return; - if (!AnnouncementsDictionary.ContainsKey(e.Server.Id)) - AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id)); + var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id)); - var controls = AnnouncementsDictionary[e.Server.Id]; - - if (controls.ToggleBye(e.Channel.Id)) + if (ann.ToggleBye(e.Channel.Id)) await e.Channel.SendMessage("Bye announcements enabled on this channel.").ConfigureAwait(false); else await e.Channel.SendMessage("Bye announcements disabled.").ConfigureAwait(false); @@ -289,12 +279,11 @@ namespace NadekoBot.Modules.Administration.Commands { if (!e.User.ServerPermissions.ManageServer) return; if (e.GetArg("msg") == null) return; - if (!AnnouncementsDictionary.ContainsKey(e.Server.Id)) - AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id)); + var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id)); - AnnouncementsDictionary[e.Server.Id].ByeText = e.GetArg("msg"); + ann.ByeText = e.GetArg("msg"); await e.Channel.SendMessage("New bye message set.").ConfigureAwait(false); - if (!AnnouncementsDictionary[e.Server.Id].Bye) + if (!ann.Bye) await e.Channel.SendMessage("Enable bye messsages by typing `.bye`.").ConfigureAwait(false); }); @@ -303,15 +292,14 @@ namespace NadekoBot.Modules.Administration.Commands .Do(async e => { if (!e.User.ServerPermissions.ManageServer) return; - if (!AnnouncementsDictionary.ContainsKey(e.Server.Id)) - AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id)); + var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id)); - AnnouncementsDictionary[e.Server.Id].ToggleByePM(); - if (AnnouncementsDictionary[e.Server.Id].ByePM) + + if (ann.ToggleByePM()) await e.Channel.SendMessage("Bye messages will be sent in a PM from now on.\n ⚠ Keep in mind this might fail if the user and the bot have no common servers after the user leaves.").ConfigureAwait(false); else await e.Channel.SendMessage("Bye messages will be sent in a bound channel from now on.").ConfigureAwait(false); - if (!AnnouncementsDictionary[e.Server.Id].Bye) + if (!ann.Bye) await e.Channel.SendMessage("Enable bye messsages by typing `.bye`, and set the bye message using `.byemsg`").ConfigureAwait(false); }); @@ -320,15 +308,14 @@ namespace NadekoBot.Modules.Administration.Commands .Do(async e => { if (!e.User.ServerPermissions.ManageServer) return; - if (!AnnouncementsDictionary.ContainsKey(e.Server.Id)) - AnnouncementsDictionary.TryAdd(e.Server.Id, new AnnounceControls(e.Server.Id)); - AnnouncementsDictionary[e.Server.Id].ToggleGreetPM(); - if (AnnouncementsDictionary[e.Server.Id].GreetPM) + var ann = AnnouncementsDictionary.GetOrAdd(e.Server.Id, new AnnounceControls(e.Server.Id)); + + if (ann.ToggleGreetPM()) await e.Channel.SendMessage("Greet messages will be sent in a PM from now on.").ConfigureAwait(false); else await e.Channel.SendMessage("Greet messages will be sent in a bound channel from now on.").ConfigureAwait(false); - if (!AnnouncementsDictionary[e.Server.Id].Greet) + if (!ann.Greet) await e.Channel.SendMessage("Enable greet messsages by typing `.greet`, and set the greet message using `.greetmsg`").ConfigureAwait(false); }); } From c966a0a34f1826a39d09ceadd103d5df4927e47d Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Mon, 2 May 2016 02:01:09 +0200 Subject: [PATCH 19/21] Update ComprehensiveGuide.md --- ComprehensiveGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ComprehensiveGuide.md b/ComprehensiveGuide.md index 02be077f..1f80dbb9 100644 --- a/ComprehensiveGuide.md +++ b/ComprehensiveGuide.md @@ -10,7 +10,7 @@ ________________________________________________________________________________ - Go to (https://discordapp.com/developers/applications/me). Log in if you have to with your Discord account. Press "New Application" and fill out an App Name and, optionally, an app description and icon. Afterwards, create the application. Once the application is created, click on "Create a Bot User" and confirm it. You will then see the bot's username, ID and token. Reveal and copy the token and the bot ID. - Open up credentials.json. Paste the token into the Token field, between the quotes. Paste the ID into the BotID field. Leave email and password fields empty. Save and close credentials.json. - Go into data folder and make sure you have config.json file. If there is no config.json, rename the config_example.json to config.json. -- Copy your CLIENT ID (that's in the same Developer page where you brought your token) and replace `12345678` in the this link: +- Copy your CLIENT ID (that's in the same Developer page where you brought your token) and replace `12345678` in this link: https://discordapp.com/oauth2/authorize?client_id=12345678&scope=bot&permissions=66186303 with it. Go to that link and you will be able to add your bot to your server. - Start NadekoBot.exe. In a text channel, **not a direct message**, type in [.uid @______] without the brackets, filling in the underlined portion with your name and send the message. Your bot will reply with a number; this is your ID. Copy this ID and close NadekoBot.exe. - Reopen credentials.json. Paste your ID into the square brackets ("OwnerIds": [1231312313]). You can add multiple owners by separating IDs with a comma. Close and save credentials.json. From dbe7dd9c1bdd479e87d157bdc6ad571280cf8f2f Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Mon, 2 May 2016 02:40:22 +0200 Subject: [PATCH 20/21] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f68895ed..69af3760 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,8 @@ When you clone the project, make sure to run `git submodule init` and `git submo **This is how the credentials.json should look like:** ```json { - "Username":"bot_email", "BotId": 123123123123, - "Password":"bot_password", + "Token":"Bot.Token", "GoogleAPIKey":"google_api_key", "OwnerIds":[123123123123, 123123123123], "TrelloAppKey": "your_trello_app_key (optional)", @@ -52,6 +51,7 @@ Next to your exe you must also have a data folder in which there is config.json "UserBlacklist": [] } ``` +- http://discord.kongslien.net/guide.html <- to make a bot account and get the `Token` - BotId and OwnerIds are **NOT** names of the owner and the bot. If you do not know the id of your bot, put 2 random numbers in those fields, run the bot and do `.uid @MyBotName` - that will give you your bot\_id, do the same for yourself `.uid @MyName` and copy the numbers in their respective fields. - For google api key, you need to enable URL shortner, Youtube video search **and custom search** in the [dev console](https://console.developers.google.com/). - For the Soundcloud Api key you need a Soundcloud account. You need to create a new app on http://soundcloud.com/you/apps/new and after that go here http://soundcloud.com/you/apps click on the name of your created your app and copy the Client ID. Paste it into credentials.json. From d62ff049fee8b30f336121a5cf5daa3c8c82805b Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Mon, 2 May 2016 02:59:46 +0200 Subject: [PATCH 21/21] small help formatting fix --- NadekoBot/Modules/Help/Commands/HelpCommand.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NadekoBot/Modules/Help/Commands/HelpCommand.cs b/NadekoBot/Modules/Help/Commands/HelpCommand.cs index ca5ad29d..4458eb77 100644 --- a/NadekoBot/Modules/Help/Commands/HelpCommand.cs +++ b/NadekoBot/Modules/Help/Commands/HelpCommand.cs @@ -25,7 +25,7 @@ namespace NadekoBot.Classes.Help.Commands .FirstOrDefault(c => c.Text.ToLowerInvariant().Equals(comToFind) || c.Aliases.Select(a => a.ToLowerInvariant()).Contains(comToFind)); if (com != null) - await e.Channel.SendMessage($"`Help for '{com.Text}':` **{com.Description}**").ConfigureAwait(false); + await e.Channel.SendMessage($"`Help for '{com.Text}':` {com.Description}").ConfigureAwait(false); }).ConfigureAwait(false); }; public static string HelpString => (NadekoBot.IsBot