Safety
This commit is contained in:
		@@ -42,14 +42,14 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (shouldDelete)
 | 
			
		||||
                    await e.Message.DeleteAsync();
 | 
			
		||||
                    await e.Message.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                _log.Warn(ex, "Delmsgoncmd errored...");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        [OwnerOnly]
 | 
			
		||||
@@ -57,9 +57,10 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)umsg.Channel;
 | 
			
		||||
 | 
			
		||||
            await channel.SendMessageAsync("`Restarting in 2 seconds...`");
 | 
			
		||||
            await Task.Delay(2000);
 | 
			
		||||
            System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo {
 | 
			
		||||
            await channel.SendMessageAsync("`Restarting in 2 seconds...`").ConfigureAwait(false);
 | 
			
		||||
            await Task.Delay(2000).ConfigureAwait(false);
 | 
			
		||||
            System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
 | 
			
		||||
            {
 | 
			
		||||
                Arguments = "dotnet " + System.Reflection.Assembly.GetEntryAssembly().Location
 | 
			
		||||
            });
 | 
			
		||||
            Environment.Exit(0);
 | 
			
		||||
@@ -80,9 +81,9 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                await uow.CompleteAsync();
 | 
			
		||||
            }
 | 
			
		||||
            if (conf.DeleteMessageOnCommand)
 | 
			
		||||
                await channel.SendMessageAsync("❗`Now automatically deleting successfull command invokations.`");
 | 
			
		||||
                await channel.SendMessageAsync("❗`Now automatically deleting successfull command invokations.`").ConfigureAwait(false);
 | 
			
		||||
            else
 | 
			
		||||
                await channel.SendMessageAsync("❗`Stopped automatic deletion of successfull command invokations.`");
 | 
			
		||||
                await channel.SendMessageAsync("❗`Stopped automatic deletion of successfull command invokations.`").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
@@ -504,7 +505,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)umsg.Channel;
 | 
			
		||||
 | 
			
		||||
            await channel.SendMessageAsync("`Shutting down.`").ConfigureAwait(false);
 | 
			
		||||
            try { await channel.SendMessageAsync("`Shutting down.`").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
            await Task.Delay(2000).ConfigureAwait(false);
 | 
			
		||||
            Environment.Exit(0);
 | 
			
		||||
        }
 | 
			
		||||
@@ -589,7 +590,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                await ch.SendMessageAsync(msg);
 | 
			
		||||
                await ch.SendMessageAsync(msg).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            else if (ids[1].ToUpperInvariant().StartsWith("U:"))
 | 
			
		||||
            {
 | 
			
		||||
@@ -599,11 +600,11 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                await user.SendMessageAsync(msg);
 | 
			
		||||
                await user.SendMessageAsync(msg).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendMessageAsync("`Invalid format.`");
 | 
			
		||||
                await channel.SendMessageAsync("`Invalid format.`").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -618,7 +619,8 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                g.GetDefaultChannelAsync()
 | 
			
		||||
            )).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
            await Task.WhenAll(channels.Select(c => c.SendMessageAsync($"`Message from {umsg.Author} (Bot Owner):` " + message)));
 | 
			
		||||
            await Task.WhenAll(channels.Select(c => c.SendMessageAsync($"`Message from {umsg.Author} (Bot Owner):` " + message)))
 | 
			
		||||
                    .ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
            await channel.SendMessageAsync(":ok:").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using NLog;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
@@ -19,6 +20,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
        {
 | 
			
		||||
            public CrossServerTextChannel()
 | 
			
		||||
            {
 | 
			
		||||
                _log = LogManager.GetCurrentClassLogger();
 | 
			
		||||
                NadekoBot.Client.MessageReceived += (imsg) =>
 | 
			
		||||
                {
 | 
			
		||||
                    var msg = imsg as IUserMessage;
 | 
			
		||||
@@ -31,8 +33,6 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
                    Task.Run(async () =>
 | 
			
		||||
                    {
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            if (msg.Author.Id == NadekoBot.Client.GetCurrentUser().Id) return;
 | 
			
		||||
                            foreach (var subscriber in Subscribers)
 | 
			
		||||
                            {
 | 
			
		||||
@@ -41,11 +41,9 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                                    continue;
 | 
			
		||||
                                foreach (var chan in set.Except(new[] { channel }))
 | 
			
		||||
                                {
 | 
			
		||||
                                    await chan.SendMessageAsync(GetText(channel.Guild, channel, (IGuildUser)msg.Author, msg)).ConfigureAwait(false);
 | 
			
		||||
                                    try { await chan.SendMessageAsync(GetText(channel.Guild, channel, (IGuildUser)msg.Author, msg)).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        catch { }
 | 
			
		||||
                    });
 | 
			
		||||
                    return Task.CompletedTask;
 | 
			
		||||
                };
 | 
			
		||||
@@ -55,6 +53,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                $"**{server.Name} | {channel.Name}** `{user.Username}`: " + message.Content;
 | 
			
		||||
            
 | 
			
		||||
            public static readonly ConcurrentDictionary<int, HashSet<ITextChannel>> Subscribers = new ConcurrentDictionary<int, HashSet<ITextChannel>>();
 | 
			
		||||
            private Logger _log { get; }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
 
 | 
			
		||||
@@ -168,7 +168,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
                var task = Task.Run(async () =>
 | 
			
		||||
                {
 | 
			
		||||
                    await logChannel.SendMessageAsync($"❗`{prettyCurrentTime}` `{(ch is IVoiceChannel ? "Voice" : "Text")} Channel Deleted:` **#{ch.Name}** ({ch.Id})").ConfigureAwait(false);
 | 
			
		||||
                    try { await logChannel.SendMessageAsync($"❗`{prettyCurrentTime}` `{(ch is IVoiceChannel ? "Voice" : "Text")} Channel Deleted:` **#{ch.Name}** ({ch.Id})").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                return Task.CompletedTask;
 | 
			
		||||
@@ -192,7 +192,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
                var task = Task.Run(async () =>
 | 
			
		||||
                {
 | 
			
		||||
                    await logChannel.SendMessageAsync($"`{prettyCurrentTime}`🆕`{(ch is IVoiceChannel ? "Voice" : "Text")} Channel Created:` **#{ch.Name}** ({ch.Id})").ConfigureAwait(false);
 | 
			
		||||
                    try { await logChannel.SendMessageAsync($"`{prettyCurrentTime}`🆕`{(ch is IVoiceChannel ? "Voice" : "Text")} Channel Created:` **#{ch.Name}** ({ch.Id})").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                return Task.CompletedTask;
 | 
			
		||||
@@ -275,7 +275,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
                var task = Task.Run(async () =>
 | 
			
		||||
                {
 | 
			
		||||
                    await logChannel.SendMessageAsync($"`{prettyCurrentTime}`❗`User left:` **{usr.Username}** ({usr.Id})").ConfigureAwait(false);
 | 
			
		||||
                    try { await logChannel.SendMessageAsync($"`{prettyCurrentTime}`❗`User left:` **{usr.Username}** ({usr.Id})").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                return Task.CompletedTask;
 | 
			
		||||
@@ -295,7 +295,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
                var task = Task.Run(async () =>
 | 
			
		||||
                {
 | 
			
		||||
                    await logChannel.SendMessageAsync($"`{prettyCurrentTime}`❗`User joined:` **{usr.Username}** ({usr.Id})").ConfigureAwait(false);
 | 
			
		||||
                    try { await logChannel.SendMessageAsync($"`{prettyCurrentTime}`❗`User joined:` **{usr.Username}** ({usr.Id})").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                return Task.CompletedTask;
 | 
			
		||||
@@ -315,7 +315,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
                var task = Task.Run(async () =>
 | 
			
		||||
                {
 | 
			
		||||
                    await logChannel.SendMessageAsync($"`{prettyCurrentTime}`♻`User unbanned:` **{usr.Username}** ({usr.Id})").ConfigureAwait(false);
 | 
			
		||||
                   try { await logChannel.SendMessageAsync($"`{prettyCurrentTime}`♻`User unbanned:` **{usr.Username}** ({usr.Id})").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                return Task.CompletedTask;
 | 
			
		||||
@@ -335,7 +335,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
                var task = Task.Run(async () =>
 | 
			
		||||
                {
 | 
			
		||||
                    await logChannel.SendMessageAsync($"❗`{prettyCurrentTime}`❌`User banned:` **{usr.Username}** ({usr.Id})").ConfigureAwait(false);
 | 
			
		||||
                    try { await logChannel.SendMessageAsync($"❗`{prettyCurrentTime}`❌`User banned:` **{usr.Username}** ({usr.Id})").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                return Task.CompletedTask;
 | 
			
		||||
@@ -399,10 +399,10 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
                var task = Task.Run(async () =>
 | 
			
		||||
                {
 | 
			
		||||
                    await logChannel.SendMessageAsync($@"🕔`{prettyCurrentTime}` **Message** 📝 `#{channel.Name}`
 | 
			
		||||
                    try { await logChannel.SendMessageAsync($@"🕔`{prettyCurrentTime}` **Message** 📝 `#{channel.Name}`
 | 
			
		||||
👤`{before.Author.Username}`
 | 
			
		||||
        `Old:` {before.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator)}
 | 
			
		||||
        `New:` {after.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator)}").ConfigureAwait(false);
 | 
			
		||||
        `New:` {after.Resolve(userHandling: UserMentionHandling.NameAndDiscriminator)}").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                return Task.CompletedTask;
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using NLog;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
@@ -23,6 +24,8 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
            public class RepeatRunner
 | 
			
		||||
            {
 | 
			
		||||
                private Logger _log { get; }
 | 
			
		||||
 | 
			
		||||
                private CancellationTokenSource source { get; set; }
 | 
			
		||||
                private CancellationToken token { get; set; }
 | 
			
		||||
                public Repeater Repeater { get; }
 | 
			
		||||
@@ -30,6 +33,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
                public RepeatRunner(Repeater repeater, ITextChannel channel = null)
 | 
			
		||||
                {
 | 
			
		||||
                    _log = LogManager.GetCurrentClassLogger();
 | 
			
		||||
                    this.Repeater = repeater;
 | 
			
		||||
                    this.Channel = channel ?? NadekoBot.Client.GetGuild(repeater.GuildId)?.GetTextChannel(repeater.ChannelId);
 | 
			
		||||
                    if (Channel == null)
 | 
			
		||||
@@ -47,7 +51,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                        while (!token.IsCancellationRequested)
 | 
			
		||||
                        {
 | 
			
		||||
                            await Task.Delay(Repeater.Interval, token).ConfigureAwait(false);
 | 
			
		||||
                            await Channel.SendMessageAsync("🔄 " + Repeater.Message).ConfigureAwait(false);
 | 
			
		||||
                            try { await Channel.SendMessageAsync("🔄 " + Repeater.Message).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (OperationCanceledException) { }
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using NLog;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
@@ -44,16 +45,19 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                    var msg = conf.ChannelByeMessageText.Replace("%user%", "**" + user.Username + "**");
 | 
			
		||||
                    if (string.IsNullOrWhiteSpace(msg))
 | 
			
		||||
                        return;
 | 
			
		||||
 | 
			
		||||
                    var toDelete = await channel.SendMessageAsync(msg).ConfigureAwait(false);
 | 
			
		||||
                    if (conf.AutoDeleteByeMessages)
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        var t = Task.Run(async () =>
 | 
			
		||||
                        var toDelete = await channel.SendMessageAsync(msg).ConfigureAwait(false);
 | 
			
		||||
                        if (conf.AutoDeleteByeMessages)
 | 
			
		||||
                        {
 | 
			
		||||
                            await Task.Delay(conf.AutoDeleteGreetMessagesTimer * 1000).ConfigureAwait(false); // 5 minutes
 | 
			
		||||
                            await toDelete.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
                        });
 | 
			
		||||
                            var t = Task.Run(async () =>
 | 
			
		||||
                            {
 | 
			
		||||
                                await Task.Delay(conf.AutoDeleteGreetMessagesTimer * 1000).ConfigureAwait(false); // 5 minutes
 | 
			
		||||
                                await toDelete.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
                            });
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                });
 | 
			
		||||
                return Task.CompletedTask;
 | 
			
		||||
            }
 | 
			
		||||
@@ -76,15 +80,19 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                            var msg = conf.ChannelGreetMessageText.Replace("%user%", user.Username).Replace("%server%", user.Guild.Name);
 | 
			
		||||
                            if (!string.IsNullOrWhiteSpace(msg))
 | 
			
		||||
                            {
 | 
			
		||||
                                var toDelete = await channel.SendMessageAsync(msg).ConfigureAwait(false);
 | 
			
		||||
                                if (conf.AutoDeleteGreetMessages)
 | 
			
		||||
                                try
 | 
			
		||||
                                {
 | 
			
		||||
                                    var t = Task.Run(async () =>
 | 
			
		||||
                                    var toDelete = await channel.SendMessageAsync(msg).ConfigureAwait(false);
 | 
			
		||||
                                    if (conf.AutoDeleteGreetMessages)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        await Task.Delay(conf.AutoDeleteGreetMessagesTimer * 1000).ConfigureAwait(false); // 5 minutes
 | 
			
		||||
                                        var t = Task.Run(async () =>
 | 
			
		||||
                                        {
 | 
			
		||||
                                            await Task.Delay(conf.AutoDeleteGreetMessagesTimer * 1000).ConfigureAwait(false); // 5 minutes
 | 
			
		||||
                                        await toDelete.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
                                    });
 | 
			
		||||
                                        });
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                                catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 
 | 
			
		||||
@@ -148,7 +148,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                var guild = channel.Guild;
 | 
			
		||||
                if (!guild.GetCurrentUser().GuildPermissions.ManageChannels)
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendMessageAsync("`I have insufficient permission to do that.`");
 | 
			
		||||
                    await channel.SendMessageAsync("`I have insufficient permission to do that.`").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@@ -163,7 +163,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                    await Task.Delay(500);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                await channel.SendMessageAsync("`Done.`");
 | 
			
		||||
                await channel.SendMessageAsync("`Done.`").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -45,9 +45,9 @@ namespace NadekoBot.Modules.ClashOfClans
 | 
			
		||||
                if (Bases[i] == null) continue;
 | 
			
		||||
                if (!Bases[i].BaseDestroyed && DateTime.UtcNow - Bases[i].TimeAdded >= callExpire)
 | 
			
		||||
                {
 | 
			
		||||
                    await war.Channel.SendMessageAsync($"❗🔰**Claim from @{Bases[i].CallUser} for a war against {war.ShortPrint()} has expired.**").ConfigureAwait(false);
 | 
			
		||||
                    Bases[i] = null;
 | 
			
		||||
                }
 | 
			
		||||
                    try { await war.Channel.SendMessageAsync($"❗🔰**Claim from @{Bases[i].CallUser} for a war against {war.ShortPrint()} has expired.**").ConfigureAwait(false); } catch { }
 | 
			
		||||
            }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
using NLog;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
@@ -47,7 +48,7 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
 | 
			
		||||
                if (amount > 0)
 | 
			
		||||
                    if(!await CurrencyHandler.RemoveCurrencyAsync((IGuildUser)umsg.Author, "BetRace", amount, true).ConfigureAwait(false))
 | 
			
		||||
                        await channel.SendMessageAsync($"{umsg.Author.Mention} You don't have enough {Gambling.CurrencyName}s.").ConfigureAwait(false);
 | 
			
		||||
                        try { await channel.SendMessageAsync($"{umsg.Author.Mention} You don't have enough {Gambling.CurrencyName}s.").ConfigureAwait(false); } catch { }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                AnimalRace ar;
 | 
			
		||||
@@ -69,12 +70,14 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
                public List<Participant> participants = new List<Participant>();
 | 
			
		||||
                private ulong serverId;
 | 
			
		||||
                private int messagesSinceGameStarted = 0;
 | 
			
		||||
                private Logger _log { get; }
 | 
			
		||||
 | 
			
		||||
                public ITextChannel raceChannel { get; set; }
 | 
			
		||||
                public bool Started { get; private set; } = false;
 | 
			
		||||
 | 
			
		||||
                public AnimalRace(ulong serverId, ITextChannel ch)
 | 
			
		||||
                {
 | 
			
		||||
                    this._log = LogManager.GetCurrentClassLogger();
 | 
			
		||||
                    this.serverId = serverId;
 | 
			
		||||
                    this.raceChannel = ch;
 | 
			
		||||
                    if (!AnimalRaces.TryAdd(serverId, this))
 | 
			
		||||
@@ -85,7 +88,7 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
 | 
			
		||||
                    using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                    {
 | 
			
		||||
                        animals = new ConcurrentQueue<string>(uow.BotConfig.GetOrCreate().RaceAnimals.Select(ra=>ra.Icon).Shuffle());
 | 
			
		||||
                        animals = new ConcurrentQueue<string>(uow.BotConfig.GetOrCreate().RaceAnimals.Select(ra => ra.Icon).Shuffle());
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -96,23 +99,23 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
                    {
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            await raceChannel.SendMessageAsync($"🏁`Race is starting in 20 seconds or when the room is full. Type {NadekoBot.ModulePrefixes[typeof(Gambling).Name]}jr to join the race.`");
 | 
			
		||||
                            try { await raceChannel.SendMessageAsync($"🏁`Race is starting in 20 seconds or when the room is full. Type {NadekoBot.ModulePrefixes[typeof(Gambling).Name]}jr to join the race.`"); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                            var t = await Task.WhenAny(Task.Delay(20000, token), fullgame);
 | 
			
		||||
                            Started = true;
 | 
			
		||||
                            cancelSource.Cancel();
 | 
			
		||||
                            if (t == fullgame)
 | 
			
		||||
                            {
 | 
			
		||||
                                await raceChannel.SendMessageAsync("🏁`Race full, starting right now!`");
 | 
			
		||||
                                try { await raceChannel.SendMessageAsync("🏁`Race full, starting right now!`"); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (participants.Count > 1)
 | 
			
		||||
                            {
 | 
			
		||||
                                await raceChannel.SendMessageAsync("🏁`Game starting with " + participants.Count + " participants.`");
 | 
			
		||||
                                try { await raceChannel.SendMessageAsync("🏁`Game starting with " + participants.Count + " participants.`"); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                            {
 | 
			
		||||
                                await raceChannel.SendMessageAsync("🏁`Race failed to start since there was not enough participants.`");
 | 
			
		||||
                                try { await raceChannel.SendMessageAsync("🏁`Race failed to start since there was not enough participants.`"); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                                var p = participants.FirstOrDefault();
 | 
			
		||||
                                
 | 
			
		||||
 | 
			
		||||
                                if (p != null)
 | 
			
		||||
                                    await CurrencyHandler.AddCurrencyAsync(p.User, "BetRace", p.AmountBet, true).ConfigureAwait(false);
 | 
			
		||||
                                End();
 | 
			
		||||
@@ -169,11 +172,13 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
                            {
 | 
			
		||||
                                if (msg != null)
 | 
			
		||||
                                    try { await msg.DeleteAsync(); } catch { }
 | 
			
		||||
                                msg = await raceChannel.SendMessageAsync(text).ConfigureAwait(false);
 | 
			
		||||
                                messagesSinceGameStarted = 0;
 | 
			
		||||
                                try { msg = await raceChannel.SendMessageAsync(text).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                                await msg.ModifyAsync(m => m.Content = text).ConfigureAwait(false);
 | 
			
		||||
                            {
 | 
			
		||||
                                try { await msg.ModifyAsync(m => m.Content = text).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            await Task.Delay(2500);
 | 
			
		||||
                        }
 | 
			
		||||
 
 | 
			
		||||
@@ -89,7 +89,6 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
                if (num < 1 || num > 30)
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendMessageAsync("Invalid number specified. You can roll up to 1-30 dice at a time.").ConfigureAwait(false);
 | 
			
		||||
                    num = 30;
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@@ -173,7 +172,7 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
                if (num < 1 || num > 30)
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendMessageAsync("Invalid number specified. You can roll up to 1-30 dice at a time.").ConfigureAwait(false);
 | 
			
		||||
                    num = 30;
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                var rng = new NadekoRandom();
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ using ImageProcessorCore;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Modules.Gambling.Models;
 | 
			
		||||
using NLog;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
@@ -12,59 +13,70 @@ using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Gambling
 | 
			
		||||
{
 | 
			
		||||
    [Group]
 | 
			
		||||
    public class DrawCommands
 | 
			
		||||
    public partial class Gambling
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ConcurrentDictionary<IGuild, Cards> AllDecks = new ConcurrentDictionary<IGuild, Cards>();
 | 
			
		||||
 | 
			
		||||
        private const string cardsPath = "data/images/cards";
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Draw(IUserMessage msg)
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class DrawCommands
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)msg.Channel;
 | 
			
		||||
            var cards = AllDecks.GetOrAdd(channel.Guild, (s) => new Cards());
 | 
			
		||||
            
 | 
			
		||||
            var num = 1;
 | 
			
		||||
            var images = new List<Image>();
 | 
			
		||||
            var cardObjects = new List<Cards.Card>();
 | 
			
		||||
            for (var i = 0; i < num; i++)
 | 
			
		||||
            private static readonly ConcurrentDictionary<IGuild, Cards> AllDecks = new ConcurrentDictionary<IGuild, Cards>();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            public DrawCommands()
 | 
			
		||||
            {
 | 
			
		||||
                if (cards.CardPool.Count == 0 && i != 0)
 | 
			
		||||
                _log = LogManager.GetCurrentClassLogger();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            private const string cardsPath = "data/images/cards";
 | 
			
		||||
            private Logger _log { get; }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task Draw(IUserMessage msg)
 | 
			
		||||
            {
 | 
			
		||||
                var channel = (ITextChannel)msg.Channel;
 | 
			
		||||
                var cards = AllDecks.GetOrAdd(channel.Guild, (s) => new Cards());
 | 
			
		||||
 | 
			
		||||
                var num = 1;
 | 
			
		||||
                var images = new List<Image>();
 | 
			
		||||
                var cardObjects = new List<Cards.Card>();
 | 
			
		||||
                for (var i = 0; i < num; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendMessageAsync("No more cards in a deck.").ConfigureAwait(false);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                var currentCard = cards.DrawACard();
 | 
			
		||||
                cardObjects.Add(currentCard);
 | 
			
		||||
                using (var stream = File.OpenRead(Path.Combine(cardsPath, currentCard.GetName())))
 | 
			
		||||
                    images.Add(new Image(stream));
 | 
			
		||||
            }
 | 
			
		||||
            MemoryStream bitmapStream = new MemoryStream();
 | 
			
		||||
            images.Merge().SaveAsPng(bitmapStream);
 | 
			
		||||
            bitmapStream.Position = 0;
 | 
			
		||||
            await channel.SendFileAsync(bitmapStream, images.Count + " cards.jpg", $"{msg.Author.Mention} drew (TODO: CARD NAMES HERE)").ConfigureAwait(false);
 | 
			
		||||
            if (cardObjects.Count == 5)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendMessageAsync($"{msg.Author.Mention} `{Cards.GetHandValue(cardObjects)}`").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Shuffle(IUserMessage imsg)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)imsg.Channel;
 | 
			
		||||
 | 
			
		||||
            AllDecks.AddOrUpdate(channel.Guild,
 | 
			
		||||
                    (g) => new Cards(),
 | 
			
		||||
                    (g, c) =>
 | 
			
		||||
                    if (cards.CardPool.Count == 0 && i != 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        c.Restart();
 | 
			
		||||
                        return c;
 | 
			
		||||
                    });
 | 
			
		||||
                        try { await channel.SendMessageAsync("No more cards in a deck.").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                    var currentCard = cards.DrawACard();
 | 
			
		||||
                    cardObjects.Add(currentCard);
 | 
			
		||||
                    using (var stream = File.OpenRead(Path.Combine(cardsPath, currentCard.GetName())))
 | 
			
		||||
                        images.Add(new Image(stream));
 | 
			
		||||
                }
 | 
			
		||||
                MemoryStream bitmapStream = new MemoryStream();
 | 
			
		||||
                images.Merge().SaveAsPng(bitmapStream);
 | 
			
		||||
                bitmapStream.Position = 0;
 | 
			
		||||
                await channel.SendFileAsync(bitmapStream, images.Count + " cards.jpg", $"{msg.Author.Mention} drew (TODO: CARD NAMES HERE)").ConfigureAwait(false);
 | 
			
		||||
                if (cardObjects.Count == 5)
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendMessageAsync($"{msg.Author.Mention} `{Cards.GetHandValue(cardObjects)}`").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await channel.SendMessageAsync("`Deck reshuffled.`").ConfigureAwait(false);
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task Shuffle(IUserMessage imsg)
 | 
			
		||||
            {
 | 
			
		||||
                var channel = (ITextChannel)imsg.Channel;
 | 
			
		||||
 | 
			
		||||
                AllDecks.AddOrUpdate(channel.Guild,
 | 
			
		||||
                        (g) => new Cards(),
 | 
			
		||||
                        (g, c) =>
 | 
			
		||||
                        {
 | 
			
		||||
                            c.Restart();
 | 
			
		||||
                            return c;
 | 
			
		||||
                        });
 | 
			
		||||
 | 
			
		||||
                await channel.SendMessageAsync("`Deck reshuffled.`").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@@ -5,6 +5,7 @@ using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
using NLog;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
@@ -40,9 +41,11 @@ namespace NadekoBot.Modules.Games
 | 
			
		||||
 | 
			
		||||
            private float chance;
 | 
			
		||||
            private int cooldown;
 | 
			
		||||
            private Logger _log { get; }
 | 
			
		||||
 | 
			
		||||
            public PlantPickCommands()
 | 
			
		||||
            {
 | 
			
		||||
                _log = LogManager.GetCurrentClassLogger();
 | 
			
		||||
                NadekoBot.Client.MessageReceived += PotentialFlowerGeneration;
 | 
			
		||||
                rng = new NadekoRandom();
 | 
			
		||||
 | 
			
		||||
@@ -121,14 +124,10 @@ namespace NadekoBot.Modules.Games
 | 
			
		||||
                await CurrencyHandler.AddCurrencyAsync((IGuildUser)imsg.Author, "Picked flower(s).", msgs.Count, false).ConfigureAwait(false);
 | 
			
		||||
                var msg = await channel.SendMessageAsync($"**{imsg.Author.Username}** picked {msgs.Count}{Gambling.Gambling.CurrencySign}!").ConfigureAwait(false);
 | 
			
		||||
                var t = Task.Run(async () =>
 | 
			
		||||
                 {
 | 
			
		||||
                     try
 | 
			
		||||
                     {
 | 
			
		||||
                         await Task.Delay(10000).ConfigureAwait(false);
 | 
			
		||||
                         await msg.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
                     }
 | 
			
		||||
                     catch { }
 | 
			
		||||
                 });
 | 
			
		||||
                {
 | 
			
		||||
                    await Task.Delay(10000).ConfigureAwait(false);
 | 
			
		||||
                    try { await msg.DeleteAsync().ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
 
 | 
			
		||||
@@ -124,17 +124,12 @@ namespace NadekoBot.Modules.Games
 | 
			
		||||
 | 
			
		||||
            var t = Task.Run(async () =>
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                if (vote < 1 || vote > answers.Length)
 | 
			
		||||
                    return;
 | 
			
		||||
                if (participants.TryAdd(msg.Author, vote))
 | 
			
		||||
                {
 | 
			
		||||
                    
 | 
			
		||||
                    if (vote < 1 || vote > answers.Length)
 | 
			
		||||
                        return;
 | 
			
		||||
                    if (participants.TryAdd(msg.Author, vote))
 | 
			
		||||
                    {
 | 
			
		||||
                        await (ch as ITextChannel).SendMessageAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false);
 | 
			
		||||
                    }
 | 
			
		||||
                    try { await (ch as ITextChannel).SendMessageAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                }
 | 
			
		||||
                catch { }
 | 
			
		||||
            });
 | 
			
		||||
            return Task.CompletedTask;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
using NLog;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
@@ -24,9 +25,11 @@ namespace NadekoBot.Modules.Games
 | 
			
		||||
            public bool IsActive;
 | 
			
		||||
            private readonly Stopwatch sw;
 | 
			
		||||
            private readonly List<ulong> finishedUserIds;
 | 
			
		||||
            private Logger _log { get; }
 | 
			
		||||
 | 
			
		||||
            public TypingGame(ITextChannel channel)
 | 
			
		||||
            {
 | 
			
		||||
                _log = LogManager.GetCurrentClassLogger();
 | 
			
		||||
                this.channel = channel;
 | 
			
		||||
                IsActive = false;
 | 
			
		||||
                sw = new Stopwatch();
 | 
			
		||||
@@ -43,41 +46,43 @@ namespace NadekoBot.Modules.Games
 | 
			
		||||
                IsActive = false;
 | 
			
		||||
                sw.Stop();
 | 
			
		||||
                sw.Reset();
 | 
			
		||||
                await channel.SendMessageAsync("Typing contest stopped").ConfigureAwait(false);
 | 
			
		||||
                try { await channel.SendMessageAsync("Typing contest stopped").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public async Task Start()
 | 
			
		||||
            {
 | 
			
		||||
                while (true)
 | 
			
		||||
                if (IsActive) return; // can't start running game
 | 
			
		||||
                IsActive = true;
 | 
			
		||||
                CurrentSentence = GetRandomSentence();
 | 
			
		||||
                var i = (int)(CurrentSentence.Length / WORD_VALUE * 1.7f);
 | 
			
		||||
                await channel.SendMessageAsync($@":clock2: Next contest will last for {i} seconds. Type the bolded text as fast as you can.").ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                var msg = await channel.SendMessageAsync("Starting new typing contest in **3**...").ConfigureAwait(false);
 | 
			
		||||
                await Task.Delay(1000).ConfigureAwait(false);
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    if (IsActive) return; // can't start running game
 | 
			
		||||
                    IsActive = true;
 | 
			
		||||
                    CurrentSentence = GetRandomSentence();
 | 
			
		||||
                    var i = (int)(CurrentSentence.Length / WORD_VALUE * 1.7f);
 | 
			
		||||
                    await channel.SendMessageAsync($":clock2: Next contest will last for {i} seconds. Type the bolded text as fast as you can.").ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    var msg = await channel.SendMessageAsync("Starting new typing contest in **3**...").ConfigureAwait(false);
 | 
			
		||||
                    await Task.Delay(1000).ConfigureAwait(false);
 | 
			
		||||
                    await msg.ModifyAsync(m => m.Content = "Starting new typing contest in **2**...").ConfigureAwait(false);
 | 
			
		||||
                    await Task.Delay(1000).ConfigureAwait(false);
 | 
			
		||||
                    await msg.ModifyAsync(m => m.Content = "Starting new typing contest in **1**...").ConfigureAwait(false);
 | 
			
		||||
                    await Task.Delay(1000).ConfigureAwait(false);
 | 
			
		||||
                    await msg.ModifyAsync(m => m.Content = $":book:**{CurrentSentence.Replace(" ", " \x200B")}**:book:").ConfigureAwait(false);
 | 
			
		||||
                    sw.Start();
 | 
			
		||||
                    HandleAnswers();
 | 
			
		||||
 | 
			
		||||
                    while (i > 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        await Task.Delay(1000).ConfigureAwait(false);
 | 
			
		||||
                        i--;
 | 
			
		||||
                        if (!IsActive)
 | 
			
		||||
                            return;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    await Stop().ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
 | 
			
		||||
                await msg.ModifyAsync(m => m.Content = $":book:**{CurrentSentence.Replace(" ", " \x200B")}**:book:").ConfigureAwait(false);
 | 
			
		||||
                sw.Start();
 | 
			
		||||
                HandleAnswers();
 | 
			
		||||
 | 
			
		||||
                while (i > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    await Task.Delay(1000).ConfigureAwait(false);
 | 
			
		||||
                    i--;
 | 
			
		||||
                    if (!IsActive)
 | 
			
		||||
                        return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                await Stop().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public string GetRandomSentence()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NLog;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
@@ -12,6 +14,7 @@ namespace NadekoBot.Modules.Games.Trivia
 | 
			
		||||
    public class TriviaGame
 | 
			
		||||
    {
 | 
			
		||||
        private readonly SemaphoreSlim _guessLock = new SemaphoreSlim(1, 1);
 | 
			
		||||
        private Logger _log { get; }
 | 
			
		||||
 | 
			
		||||
        public IGuild guild { get; }
 | 
			
		||||
        public ITextChannel channel { get; }
 | 
			
		||||
@@ -33,6 +36,7 @@ namespace NadekoBot.Modules.Games.Trivia
 | 
			
		||||
 | 
			
		||||
        public TriviaGame(IGuild guild, ITextChannel channel, bool showHints, int winReq = 10)
 | 
			
		||||
        {
 | 
			
		||||
            _log = LogManager.GetCurrentClassLogger();
 | 
			
		||||
            ShowHints = showHints;
 | 
			
		||||
            this.guild = guild;
 | 
			
		||||
            this.channel = channel;
 | 
			
		||||
@@ -51,13 +55,13 @@ namespace NadekoBot.Modules.Games.Trivia
 | 
			
		||||
                CurrentQuestion = TriviaQuestionPool.Instance.GetRandomQuestion(oldQuestions);
 | 
			
		||||
                if (CurrentQuestion == null)
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendMessageAsync($":exclamation: Failed loading a trivia question").ConfigureAwait(false);
 | 
			
		||||
                    try { await channel.SendMessageAsync($":exclamation: Failed loading a trivia question").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                    await End().ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                oldQuestions.Add(CurrentQuestion); //add it to exclusion list so it doesn't show up again
 | 
			
		||||
                                                   //sendquestion
 | 
			
		||||
                await channel.SendMessageAsync($":question: **{CurrentQuestion.Question}**").ConfigureAwait(false);
 | 
			
		||||
                try { await channel.SendMessageAsync($":question: **{CurrentQuestion.Question}**").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
 | 
			
		||||
                //receive messages
 | 
			
		||||
                NadekoBot.Client.MessageReceived += PotentialGuess;
 | 
			
		||||
@@ -70,7 +74,7 @@ namespace NadekoBot.Modules.Games.Trivia
 | 
			
		||||
                    //hint
 | 
			
		||||
                    await Task.Delay(HintTimeoutMiliseconds, token).ConfigureAwait(false);
 | 
			
		||||
                    if (ShowHints)
 | 
			
		||||
                        await channel.SendMessageAsync($":exclamation:**Hint:** {CurrentQuestion.GetHint()}").ConfigureAwait(false);
 | 
			
		||||
                        try { await channel.SendMessageAsync($":exclamation:**Hint:** {CurrentQuestion.GetHint()}").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
 | 
			
		||||
                    //timeout
 | 
			
		||||
                    await Task.Delay(QuestionDurationMiliseconds - HintTimeoutMiliseconds, token).ConfigureAwait(false);
 | 
			
		||||
@@ -79,7 +83,7 @@ namespace NadekoBot.Modules.Games.Trivia
 | 
			
		||||
                catch (TaskCanceledException) { } //means someone guessed the answer
 | 
			
		||||
                GameActive = false;
 | 
			
		||||
                if (!triviaCancelSource.IsCancellationRequested)
 | 
			
		||||
                    await channel.SendMessageAsync($":clock2: :question: **Time's up!** The correct answer was **{CurrentQuestion.Answer}**").ConfigureAwait(false);
 | 
			
		||||
                    try { await channel.SendMessageAsync($":clock2: :question: **Time's up!** The correct answer was **{CurrentQuestion.Answer}**").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                NadekoBot.Client.MessageReceived -= PotentialGuess;
 | 
			
		||||
                // load next question if game is still running
 | 
			
		||||
                await Task.Delay(2000).ConfigureAwait(false);
 | 
			
		||||
@@ -96,7 +100,7 @@ namespace NadekoBot.Modules.Games.Trivia
 | 
			
		||||
        public async Task StopGame()
 | 
			
		||||
        {
 | 
			
		||||
            if (!ShouldStopGame)
 | 
			
		||||
                await channel.SendMessageAsync(":exclamation: Trivia will stop after this question.").ConfigureAwait(false);
 | 
			
		||||
                try { await channel.SendMessageAsync(":exclamation: Trivia will stop after this question.").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
            ShouldStopGame = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -128,13 +132,13 @@ namespace NadekoBot.Modules.Games.Trivia
 | 
			
		||||
                    finally { _guessLock.Release(); }
 | 
			
		||||
                    if (!guess) return;
 | 
			
		||||
                    triviaCancelSource.Cancel();
 | 
			
		||||
                    await channel.SendMessageAsync($"☑️ {guildUser.Mention} guessed it! The answer was: **{CurrentQuestion.Answer}**").ConfigureAwait(false);
 | 
			
		||||
                    try { await channel.SendMessageAsync($"☑️ {guildUser.Mention} guessed it! The answer was: **{CurrentQuestion.Answer}**").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                    if (Users[guildUser] != WinRequirement) return;
 | 
			
		||||
                    ShouldStopGame = true;
 | 
			
		||||
                    await channel.SendMessageAsync($":exclamation: We have a winner! It's {guildUser.Mention}.").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                catch { }
 | 
			
		||||
            });
 | 
			
		||||
                catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
        });
 | 
			
		||||
            return Task.CompletedTask;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -574,19 +574,19 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
                await channel.SendMessageAsync("`Can't find playlist with that ID`").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var msg = await channel.SendMessageAsync($"`Attempting to load {mpl.Songs.Count} songs...`").ConfigureAwait(false);
 | 
			
		||||
            IUserMessage msg = null;
 | 
			
		||||
            try { msg = await channel.SendMessageAsync($"`Attempting to load {mpl.Songs.Count} songs...`").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
            foreach (var item in mpl.Songs)
 | 
			
		||||
            {
 | 
			
		||||
                var usr = (IGuildUser)umsg.Author;
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    var usr = (IGuildUser)umsg.Author;
 | 
			
		||||
                    await QueueSong(usr, channel, usr.VoiceChannel, item.Query, true, item.ProviderType).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                catch { break; }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await msg.ModifyAsync(m => m.Content = $"`Done loading playlist {mpl.Name}.`").ConfigureAwait(false);
 | 
			
		||||
            if (msg != null)
 | 
			
		||||
                await msg.ModifyAsync(m => m.Content = $"`Done loading playlist {mpl.Name}.`").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
@@ -769,16 +769,13 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
                                await lastFinishedMessage.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
                            if (playingMessage != null)
 | 
			
		||||
                                await playingMessage.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
                            lastFinishedMessage = await textCh.SendMessageAsync($"🎵`Finished`{song.PrettyName}").ConfigureAwait(false);
 | 
			
		||||
                            try { lastFinishedMessage = await textCh.SendMessageAsync($"🎵`Finished`{song.PrettyName}").ConfigureAwait(false); } catch { }
 | 
			
		||||
                            if (mp.Autoplay && mp.Playlist.Count == 0 && song.SongInfo.Provider == "YouTube")
 | 
			
		||||
                            {
 | 
			
		||||
                                await QueueSong(queuer.Guild.GetCurrentUser(), textCh, voiceCh, (await NadekoBot.Google.GetRelatedVideosAsync(song.SongInfo.Query, 4)).ToList().Shuffle().FirstOrDefault(), silent, musicType).ConfigureAwait(false);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        catch (Exception e)
 | 
			
		||||
                        {
 | 
			
		||||
                            Console.WriteLine(e);
 | 
			
		||||
                        }
 | 
			
		||||
                        catch { }
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
                mp.OnStarted += async (s, song) =>
 | 
			
		||||
@@ -789,13 +786,8 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
                        if (sender == null)
 | 
			
		||||
                            return;
 | 
			
		||||
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
 | 
			
		||||
                            var msgTxt = $"🎵`Playing`{song.PrettyName} `Vol: {(int)(sender.Volume * 100)}%`";
 | 
			
		||||
                            playingMessage = await textCh.SendMessageAsync(msgTxt).ConfigureAwait(false);
 | 
			
		||||
                        }
 | 
			
		||||
                        catch { }
 | 
			
		||||
                        try { playingMessage = await textCh.SendMessageAsync(msgTxt).ConfigureAwait(false); } catch { }
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
                return mp;
 | 
			
		||||
@@ -810,23 +802,25 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
            }
 | 
			
		||||
            catch (PlaylistFullException)
 | 
			
		||||
            {
 | 
			
		||||
                await textCh.SendMessageAsync($"🎵 `Queue is full at {musicPlayer.MaxQueueSize}/{musicPlayer.MaxQueueSize}.` ");
 | 
			
		||||
                try { await textCh.SendMessageAsync($"🎵 `Queue is full at {musicPlayer.MaxQueueSize}/{musicPlayer.MaxQueueSize}.` "); } catch { }
 | 
			
		||||
                throw;
 | 
			
		||||
            }
 | 
			
		||||
            if (!silent)
 | 
			
		||||
            {
 | 
			
		||||
                var queuedMessage = await textCh.SendMessageAsync($"🎵`Queued`{resolvedSong.PrettyName} **at** `#{musicPlayer.Playlist.Count + 1}`").ConfigureAwait(false);
 | 
			
		||||
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
 | 
			
		||||
                Task.Run(async () =>
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    await Task.Delay(10000).ConfigureAwait(false);
 | 
			
		||||
                    try
 | 
			
		||||
                    var queuedMessage = await textCh.SendMessageAsync($"🎵`Queued`{resolvedSong.PrettyName} **at** `#{musicPlayer.Playlist.Count + 1}`").ConfigureAwait(false);
 | 
			
		||||
                    var t = Task.Run(async () =>
 | 
			
		||||
                    {
 | 
			
		||||
                        await queuedMessage.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
                    }
 | 
			
		||||
                    catch { }
 | 
			
		||||
                }).ConfigureAwait(false);
 | 
			
		||||
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
 | 
			
		||||
                        await Task.Delay(10000).ConfigureAwait(false);
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            await queuedMessage.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
                        }
 | 
			
		||||
                        catch { }
 | 
			
		||||
                    }).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                catch { } // if queued message sending fails, don't attempt to delete it
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -40,6 +40,11 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
            public Task UserBlacklist(IUserMessage imsg, AddRemove action, ulong id)
 | 
			
		||||
                => Blacklist(imsg, action, id, BlacklistType.User);
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [OwnerOnly]
 | 
			
		||||
            public Task UserBlacklist(IUserMessage imsg, AddRemove action, IUser usr)
 | 
			
		||||
                => Blacklist(imsg, action, usr.Id, BlacklistType.User);
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [OwnerOnly]
 | 
			
		||||
            public Task ChannelBlacklist(IUserMessage imsg, AddRemove action, ulong id)
 | 
			
		||||
@@ -50,6 +55,11 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
            public Task ServerBlacklist(IUserMessage imsg, AddRemove action, ulong id)
 | 
			
		||||
                => Blacklist(imsg, action, id, BlacklistType.Server);
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [OwnerOnly]
 | 
			
		||||
            public Task ServerBlacklist(IUserMessage imsg, AddRemove action, IGuild guild)
 | 
			
		||||
                => Blacklist(imsg, action, guild.Id, BlacklistType.Server);
 | 
			
		||||
 | 
			
		||||
            private async Task Blacklist(IUserMessage imsg, AddRemove action, ulong id, BlacklistType type)
 | 
			
		||||
            {
 | 
			
		||||
                var channel = imsg.Channel;
 | 
			
		||||
 
 | 
			
		||||
@@ -47,8 +47,7 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                        var res = await http.GetStreamAsync(new Uri($"http://lemmmy.pw/osusig/sig.php?uname={ usr }&flagshadow&xpbar&xpbarhex&pp=2&mode={m}")).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
                        res.Position = 0;
 | 
			
		||||
                        await channel.SendFileAsync(res, $"{usr}.png").ConfigureAwait(false);
 | 
			
		||||
                        await channel.SendMessageAsync($"`Profile Link:`https://osu.ppy.sh/u/{Uri.EscapeDataString(usr)}\n`Image provided by https://lemmmy.pw/osusig`").ConfigureAwait(false);
 | 
			
		||||
                        await channel.SendFileAsync(res, $"{usr}.png", $"`Profile Link:`https://osu.ppy.sh/u/{Uri.EscapeDataString(usr)}\n`Image provided by https://lemmmy.pw/osusig`").ConfigureAwait(false);
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception ex)
 | 
			
		||||
                    {
 | 
			
		||||
 
 | 
			
		||||
@@ -68,9 +68,9 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                                        msg += $"\n`Here is the Link:`【 http://www.twitch.tv/{stream.Username}/ 】";
 | 
			
		||||
                                    else if (stream.Type == FollowedStream.FollowedStreamType.Beam)
 | 
			
		||||
                                        msg += $"\n`Here is the Link:`【 http://www.beam.pro/{stream.Username}/ 】";
 | 
			
		||||
                                    //else if (stream.Type == FollowedStream.FollowedStreamType.YoutubeGaming)
 | 
			
		||||
                                    //    msg += $"\n`Here is the Link:`【 not implemented yet - {stream.Username} 】";
 | 
			
		||||
                                await channel.SendMessageAsync(msg).ConfigureAwait(false);
 | 
			
		||||
                                //else if (stream.Type == FollowedStream.FollowedStreamType.YoutubeGaming)
 | 
			
		||||
                                //    msg += $"\n`Here is the Link:`【 not implemented yet - {stream.Username} 】";
 | 
			
		||||
                                try { await channel.SendMessageAsync(msg).ConfigureAwait(false); } catch { }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        FirstPass = false;
 | 
			
		||||
 
 | 
			
		||||
@@ -59,8 +59,8 @@ namespace NadekoBot.Modules.Utility
 | 
			
		||||
                    Text = text,
 | 
			
		||||
                });
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
                await channel.SendMessageAsync("`Quote added.`").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendMessageAsync("`Quote added.`").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
@@ -73,21 +73,22 @@ namespace NadekoBot.Modules.Utility
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            keyword = keyword.ToUpperInvariant();
 | 
			
		||||
 | 
			
		||||
            string response;
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                var q = await uow.Quotes.GetRandomQuoteByKeywordAsync(channel.Guild.Id, keyword);
 | 
			
		||||
                var q = await uow.Quotes.GetRandomQuoteByKeywordAsync(channel.Guild.Id, keyword).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
                if (q == null)
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendMessageAsync("`No quotes found.`");
 | 
			
		||||
                    response = "`No quotes found.`";
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                uow.Quotes.Remove(q);
 | 
			
		||||
                await uow.CompleteAsync();
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
                response = "`Deleted a random quote`";
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendMessageAsync("`Deleted a random quote.`");
 | 
			
		||||
            await channel.SendMessageAsync(response);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using NLog;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
@@ -31,9 +32,11 @@ namespace NadekoBot.Modules.Utility
 | 
			
		||||
                { "%user%", (r) => $"<@!{r.UserId}>" },
 | 
			
		||||
                { "%target%", (r) =>  r.IsPrivate ? "Direct Message" : $"<#{r.ChannelId}>"}
 | 
			
		||||
            };
 | 
			
		||||
            private Logger _log { get; }
 | 
			
		||||
 | 
			
		||||
            public RemindCommands()
 | 
			
		||||
            {
 | 
			
		||||
                _log = LogManager.GetCurrentClassLogger();
 | 
			
		||||
                List<Reminder> reminders;
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
@@ -52,7 +55,7 @@ namespace NadekoBot.Modules.Utility
 | 
			
		||||
            {
 | 
			
		||||
                var now = DateTime.Now;
 | 
			
		||||
                var twoMins = new TimeSpan(0, 2, 0);
 | 
			
		||||
                TimeSpan time = r.When - now; 
 | 
			
		||||
                TimeSpan time = r.When - now;
 | 
			
		||||
 | 
			
		||||
                if (time.TotalMilliseconds > int.MaxValue)
 | 
			
		||||
                    return;
 | 
			
		||||
@@ -76,12 +79,8 @@ namespace NadekoBot.Modules.Utility
 | 
			
		||||
                        replacements.Aggregate(RemindMessageFormat,
 | 
			
		||||
                        (cur, replace) => cur.Replace(replace.Key, replace.Value(r)))
 | 
			
		||||
                            ).ConfigureAwait(false); //it works trust me
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception ex)
 | 
			
		||||
                {
 | 
			
		||||
                    Console.WriteLine($"Timer error! {ex}");
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                finally
 | 
			
		||||
                {
 | 
			
		||||
                    using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
@@ -180,7 +179,7 @@ namespace NadekoBot.Modules.Utility
 | 
			
		||||
                    await uow.CompleteAsync();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                await channel.SendMessageAsync($"⏰ I will remind \"{(ch is ITextChannel ? ((ITextChannel)ch).Name : umsg.Author.Username)}\" to \"{message.ToString()}\" in {output}. ({time:d.M.yyyy.} at {time:HH:mm})").ConfigureAwait(false);
 | 
			
		||||
                try { await channel.SendMessageAsync($"⏰ I will remind \"{(ch is ITextChannel ? ((ITextChannel)ch).Name : umsg.Author.Username)}\" to \"{message.ToString()}\" in {output}. ({time:d.M.yyyy.} at {time:HH:mm})").ConfigureAwait(false); } catch { }
 | 
			
		||||
                await StartReminder(rem);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1201,52 +1201,34 @@
 | 
			
		||||
    <value>ubl</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="userblacklist_desc" xml:space="preserve">
 | 
			
		||||
    <value>Blacklists a mentioned user.  </value>
 | 
			
		||||
    <value>Either [add]s or [rem]oves a user specified by a mention or ID from a blacklist.</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="userblacklist_usage" xml:space="preserve">
 | 
			
		||||
    <value>`;ubl [user_mention]`</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="uubl_cmd" xml:space="preserve">
 | 
			
		||||
    <value>uubl</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="uubl_desc" xml:space="preserve">
 | 
			
		||||
    <value>Unblacklists a mentioned user.  </value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="uubl_usage" xml:space="preserve">
 | 
			
		||||
    <value>`;uubl [user_mention]`</value>
 | 
			
		||||
    <value>`;ubl add @SomeUser` or `;ubl rem 12312312313`</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="channelblacklist_cmd" xml:space="preserve">
 | 
			
		||||
    <value>cbl</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="channelblacklist_desc" xml:space="preserve">
 | 
			
		||||
    <value>Blacklists a mentioned channel (#general for example).</value>
 | 
			
		||||
    <value>Either [add]s or [rem]oves a channel specified by an ID from a blacklist.</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="channelblacklist_usage" xml:space="preserve">
 | 
			
		||||
    <value>`;cbl #some_channel`</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="cubl_cmd" xml:space="preserve">
 | 
			
		||||
    <value>cubl</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="cubl_desc" xml:space="preserve">
 | 
			
		||||
    <value>Unblacklists a mentioned channel (#general for example).</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="cubl_usage" xml:space="preserve">
 | 
			
		||||
    <value>`;cubl #some_channel`</value>
 | 
			
		||||
    <value>`;cbl rem 12312312312`</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="serverblacklist_cmd" xml:space="preserve">
 | 
			
		||||
    <value>sbl</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="serverblacklist_desc" xml:space="preserve">
 | 
			
		||||
    <value>Blacklists a server by a name or id (#general for example).</value>
 | 
			
		||||
    <value>Either [add]s or [rem]oves a server specified by a Name or ID from a blacklist.</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="serverblacklist_usage" xml:space="preserve">
 | 
			
		||||
    <value>`;sbl [servername/serverid]`</value>
 | 
			
		||||
    <value>`;sbl add 12312321312` or `;sbl rem SomeTrashServer`</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="cmdcooldown_cmd" xml:space="preserve">
 | 
			
		||||
    <value>cmdcooldown cmdcd</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="cmdcooldown_desc" xml:space="preserve">
 | 
			
		||||
    <value>Sets a cooldown per user for a command. Set 0 to clear.  </value>
 | 
			
		||||
    <value>Sets a cooldown per user for a command. Set 0 to clear.</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="cmdcooldown_usage" xml:space="preserve">
 | 
			
		||||
    <value>`;cmdcd "some cmd" 5`</value>
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@ namespace NadekoBot.Services
 | 
			
		||||
                var success = uow.Currency.TryUpdateState(authorId, -amount);
 | 
			
		||||
                if (!success)
 | 
			
		||||
                    return false;
 | 
			
		||||
                await uow.CompleteAsync();
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
@@ -44,7 +44,7 @@ namespace NadekoBot.Services
 | 
			
		||||
            await AddCurrencyAsync(author.Id, reason, amount);
 | 
			
		||||
 | 
			
		||||
            if (sendMessage)
 | 
			
		||||
                await author.SendMessageAsync($"`You received:` {amount} {Gambling.CurrencySign}\n`Reason:` {reason}").ConfigureAwait(false);
 | 
			
		||||
                try { await author.SendMessageAsync($"`You received:` {amount} {Gambling.CurrencySign}\n`Reason:` {reason}").ConfigureAwait(false); } catch { }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task AddCurrencyAsync(ulong receiverId, string reason, long amount)
 | 
			
		||||
 
 | 
			
		||||
@@ -14,8 +14,9 @@ namespace NadekoBot.TypeReaders
 | 
			
		||||
        public override Task<TypeReaderResult> Read(IUserMessage context, string input)
 | 
			
		||||
        {
 | 
			
		||||
            input = input.Trim().ToLowerInvariant();
 | 
			
		||||
            var guild = NadekoBot.Client.GetGuilds().FirstOrDefault(g => g.Id.ToString().Trim().ToLowerInvariant() == input) ?? //by id
 | 
			
		||||
                NadekoBot.Client.GetGuilds().FirstOrDefault(g => g.Name.Trim().ToLowerInvariant() == input);//by name
 | 
			
		||||
            var guilds = NadekoBot.Client.GetGuilds();
 | 
			
		||||
            var guild = guilds.FirstOrDefault(g => g.Id.ToString().Trim().ToLowerInvariant() == input) ?? //by id
 | 
			
		||||
                        guilds.FirstOrDefault(g => g.Name.Trim().ToLowerInvariant() == input); //by name
 | 
			
		||||
 | 
			
		||||
            if (guild != null)
 | 
			
		||||
                return Task.FromResult(TypeReaderResult.FromSuccess(guild));
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user