Only utility left for basic changes
This commit is contained in:
		@@ -1,7 +1,5 @@
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Attributes
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,4 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Migrations;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Migrations;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Migrations
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,4 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Migrations;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Migrations;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Migrations
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,4 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Migrations;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Migrations;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Migrations
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,7 @@
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Infrastructure;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Metadata;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Migrations;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using NadekoBot.Modules.Music.Classes;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Migrations
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -16,8 +16,6 @@ using System.IO;
 | 
			
		||||
using static NadekoBot.Modules.Permissions.Permissions;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using NLog;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Administration
 | 
			
		||||
{
 | 
			
		||||
@@ -45,7 +43,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var channel = Context.Channel as SocketTextChannel;
 | 
			
		||||
                var channel = msg.Channel as SocketTextChannel;
 | 
			
		||||
                if (channel == null)
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
@@ -53,7 +51,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                bool shouldDelete;
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    shouldDelete = uow.GuildConfigs.For(Context.Guild.Id, set => set).DeleteMessageOnCommand;
 | 
			
		||||
                    shouldDelete = uow.GuildConfigs.For(channel.Guild.Id, set => set).DeleteMessageOnCommand;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (shouldDelete)
 | 
			
		||||
@@ -221,7 +219,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                var green = Convert.ToByte(rgb ? int.Parse(args[2]) : Convert.ToInt32(arg1.Substring(2, 2), 16));
 | 
			
		||||
                var blue = Convert.ToByte(rgb ? int.Parse(args[3]) : Convert.ToInt32(arg1.Substring(4, 2), 16));
 | 
			
		||||
                
 | 
			
		||||
                await role.ModifyAsync(r => r.Color = new Discord.Color(red, green, blue).RawValue).ConfigureAwait(false);
 | 
			
		||||
                await role.ModifyAsync(r => r.Color = new Color(red, green, blue)).ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendConfirmAsync($"☑️ Role **{role.Name}'s** color has been changed.").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception)
 | 
			
		||||
@@ -419,9 +417,10 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
        [RequireUserPermission(GuildPermission.ManageChannels)]
 | 
			
		||||
        public async Task SetTopic([Remainder] string topic = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            topic = topic ?? "";
 | 
			
		||||
            await Context.Channel.ModifyAsync(c => c.Topic = topic);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync("🆗 **New channel topic set.**").ConfigureAwait(false);
 | 
			
		||||
            await channel.ModifyAsync(c => c.Topic = topic);
 | 
			
		||||
            await channel.SendConfirmAsync("🆗 **New channel topic set.**").ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
@@ -429,8 +428,9 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
        [RequireUserPermission(GuildPermission.ManageChannels)]
 | 
			
		||||
        public async Task SetChanlName([Remainder] string name)
 | 
			
		||||
        {
 | 
			
		||||
            await Context.Channel.ModifyAsync(c => c.Name = name).ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync("🆗 **New channel name set.**").ConfigureAwait(false);
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            await channel.ModifyAsync(c => c.Name = name).ConfigureAwait(false);
 | 
			
		||||
            await channel.SendConfirmAsync("🆗 **New channel name set.**").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -452,8 +452,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
        [RequireUserPermission(ChannelPermission.ManageMessages)]
 | 
			
		||||
        public async Task Prune(int count)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            await (Context.Message as IUserMessage).DeleteAsync();
 | 
			
		||||
            await Context.Message.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
            int limit = (count < 100) ? count : 100;
 | 
			
		||||
            var enumerable = (await Context.Channel.GetMessagesAsync(limit: limit).Flatten().ConfigureAwait(false));
 | 
			
		||||
            await Context.Channel.DeleteMessagesAsync(enumerable).ConfigureAwait(false);
 | 
			
		||||
@@ -507,7 +506,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                    await sr.CopyToAsync(imgStream);
 | 
			
		||||
                    imgStream.Position = 0;
 | 
			
		||||
 | 
			
		||||
                    await NadekoBot.Client.CurrentUser().ModifyAsync(u => u.Avatar = imgStream).ConfigureAwait(false);
 | 
			
		||||
                    await NadekoBot.Client.CurrentUser().ModifyAsync(u => u.Avatar = new Image(imgStream)).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -67,7 +67,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class AntiRaidCommands
 | 
			
		||||
        public class AntiRaidCommands : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            private static ConcurrentDictionary<ulong, AntiRaidSetting> antiRaidGuilds =
 | 
			
		||||
                    new ConcurrentDictionary<ulong, AntiRaidSetting>();
 | 
			
		||||
@@ -84,10 +84,10 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                NadekoBot.Client.MessageReceived += (imsg) =>
 | 
			
		||||
                {
 | 
			
		||||
                    var msg = imsg as IUserMessage;
 | 
			
		||||
                    if (msg == null || Context.User.IsBot)
 | 
			
		||||
                    if (msg == null || imsg.Author.IsBot)
 | 
			
		||||
                        return Task.CompletedTask;
 | 
			
		||||
 | 
			
		||||
                    //var channel = Context.Channel as ITextChannel;
 | 
			
		||||
                    var channel = imsg.Channel as ITextChannel;
 | 
			
		||||
                    if (channel == null)
 | 
			
		||||
                        return Task.CompletedTask;
 | 
			
		||||
 | 
			
		||||
@@ -96,17 +96,17 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            AntiSpamSetting spamSettings;
 | 
			
		||||
                            if (!antiSpamGuilds.TryGetValue(Context.Guild.Id, out spamSettings))
 | 
			
		||||
                            if (!antiSpamGuilds.TryGetValue(channel.Guild.Id, out spamSettings))
 | 
			
		||||
                                return;
 | 
			
		||||
 | 
			
		||||
                            var stats = spamSettings.UserStats.AddOrUpdate(Context.User.Id, new UserSpamStats(msg.Content),
 | 
			
		||||
                            var stats = spamSettings.UserStats.AddOrUpdate(imsg.Author.Id, new UserSpamStats(msg.Content),
 | 
			
		||||
                                (id, old) => { old.ApplyNextMessage(msg.Content); return old; });
 | 
			
		||||
 | 
			
		||||
                            if (stats.Count >= spamSettings.MessageThreshold)
 | 
			
		||||
                            {
 | 
			
		||||
                                if (spamSettings.UserStats.TryRemove(Context.User.Id, out stats))
 | 
			
		||||
                                if (spamSettings.UserStats.TryRemove(imsg.Author.Id, out stats))
 | 
			
		||||
                                {
 | 
			
		||||
                                    await PunishUsers(spamSettings.Action, ProtectionType.Spamming, (IGuildUser)Context.User)
 | 
			
		||||
                                    await PunishUsers(spamSettings.Action, ProtectionType.Spamming, (IGuildUser)imsg.Author)
 | 
			
		||||
                                        .ConfigureAwait(false);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@@ -199,8 +199,6 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.Administrator)]
 | 
			
		||||
            public async Task AntiRaid(IUserMessage imsg, int userThreshold, int seconds, PunishmentAction action)
 | 
			
		||||
            {
 | 
			
		||||
                ////var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                if (userThreshold < 2 || userThreshold > 30)
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("❗️User threshold must be between **2** and **30**.").ConfigureAwait(false);
 | 
			
		||||
@@ -243,8 +241,6 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.Administrator)]
 | 
			
		||||
            public async Task AntiSpam(IUserMessage imsg, int messageCount=3, PunishmentAction action = PunishmentAction.Mute)
 | 
			
		||||
            {
 | 
			
		||||
                ////var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                if (messageCount < 2 || messageCount > 10)
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
    public partial class Administration
 | 
			
		||||
    {
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class AutoAssignRoleCommands
 | 
			
		||||
        public class AutoAssignRoleCommands : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            private static Logger _log { get; }
 | 
			
		||||
 | 
			
		||||
@@ -48,8 +48,6 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageRoles)]
 | 
			
		||||
            public async Task AutoAssignRole(IUserMessage umsg, [Remainder] IRole role = null)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                GuildConfig conf;
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
 
 | 
			
		||||
@@ -14,35 +14,35 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
    public partial class Administration
 | 
			
		||||
    {
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class CrossServerTextChannel
 | 
			
		||||
        public class CrossServerTextChannel : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            static CrossServerTextChannel()
 | 
			
		||||
            {
 | 
			
		||||
                _log = LogManager.GetCurrentClassLogger();
 | 
			
		||||
                NadekoBot.Client.MessageReceived += (imsg) =>
 | 
			
		||||
                {
 | 
			
		||||
                    if (Context.User.IsBot)
 | 
			
		||||
                    if (imsg.Author.IsBot)
 | 
			
		||||
                        return Task.CompletedTask;
 | 
			
		||||
 | 
			
		||||
                    var msg = imsg as IUserMessage;
 | 
			
		||||
                    if (msg == null)
 | 
			
		||||
                        return Task.CompletedTask;
 | 
			
		||||
 | 
			
		||||
                    //var channel = Context.Channel as ITextChannel;
 | 
			
		||||
                    var channel = imsg.Channel as ITextChannel;
 | 
			
		||||
                    if (channel == null)
 | 
			
		||||
                        return Task.CompletedTask;
 | 
			
		||||
 | 
			
		||||
                    Task.Run(async () =>
 | 
			
		||||
                    {
 | 
			
		||||
                        if (Context.User.Id == NadekoBot.Client.CurrentUser().Id) return;
 | 
			
		||||
                        if (imsg.Author.Id == NadekoBot.Client.CurrentUser().Id) return;
 | 
			
		||||
                        foreach (var subscriber in Subscribers)
 | 
			
		||||
                        {
 | 
			
		||||
                            var set = subscriber.Value;
 | 
			
		||||
                            if (!set.Contains(Context.Channel))
 | 
			
		||||
                            if (!set.Contains(channel))
 | 
			
		||||
                                continue;
 | 
			
		||||
                            foreach (var chan in set.Except(new[] { channel }))
 | 
			
		||||
                            {
 | 
			
		||||
                                try { await chan.SendMessageAsync(GetText(Context.Guild, channel, (IGuildUser)Context.User, msg)).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                                try { await chan.SendMessageAsync(GetText(channel.Guild, channel, (IGuildUser)msg.Author, msg)).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
@@ -61,12 +61,11 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [OwnerOnly]
 | 
			
		||||
            public async Task Scsc()
 | 
			
		||||
            {
 | 
			
		||||
                ////var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
                var token = new NadekoRandom().Next();
 | 
			
		||||
                var set = new ConcurrentHashSet<ITextChannel>();
 | 
			
		||||
                if (Subscribers.TryAdd(token, set))
 | 
			
		||||
                {
 | 
			
		||||
                    set.Add(channel);
 | 
			
		||||
                    set.Add((ITextChannel)Context.Channel);
 | 
			
		||||
                    await ((IGuildUser)Context.User).SendConfirmAsync("This is your CSC token", token.ToString()).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -76,12 +75,10 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageGuild)]
 | 
			
		||||
            public async Task Jcsc(IUserMessage imsg, int token)
 | 
			
		||||
            {
 | 
			
		||||
                ////var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                ConcurrentHashSet<ITextChannel> set;
 | 
			
		||||
                if (!Subscribers.TryGetValue(token, out set))
 | 
			
		||||
                    return;
 | 
			
		||||
                set.Add(channel);
 | 
			
		||||
                set.Add((ITextChannel)Context.Channel);
 | 
			
		||||
                await Context.Channel.SendConfirmAsync("Joined cross server channel.").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -90,11 +87,9 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageGuild)]
 | 
			
		||||
            public async Task Lcsc()
 | 
			
		||||
            {
 | 
			
		||||
                ////var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                foreach (var subscriber in Subscribers)
 | 
			
		||||
                {
 | 
			
		||||
                    subscriber.Value.TryRemove(channel);
 | 
			
		||||
                    subscriber.Value.TryRemove((ITextChannel)Context.Channel);
 | 
			
		||||
                }
 | 
			
		||||
                await Context.Channel.SendMessageAsync("Left cross server channel.").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
@@ -12,7 +13,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
    public partial class Administration
 | 
			
		||||
    {
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class DMForwardCommands
 | 
			
		||||
        public class DMForwardCommands : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            private static bool ForwardDMs { get; set; }
 | 
			
		||||
            private static bool ForwardDMsToAllOwners { get; set; }
 | 
			
		||||
@@ -31,8 +32,6 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [OwnerOnly]
 | 
			
		||||
            public async Task ForwardMessages()
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = Context.Channel;
 | 
			
		||||
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    var config = uow.BotConfig.GetOrCreate();
 | 
			
		||||
@@ -49,8 +48,6 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [OwnerOnly]
 | 
			
		||||
            public async Task ForwardToAll()
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = Context.Channel;
 | 
			
		||||
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    var config = uow.BotConfig.GetOrCreate();
 | 
			
		||||
@@ -64,20 +61,20 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public static async Task HandleDMForwarding(IMessage msg, List<IDMChannel> ownerChannels)
 | 
			
		||||
            public static async Task HandleDMForwarding(SocketMessage msg, List<IDMChannel> ownerChannels)
 | 
			
		||||
            {
 | 
			
		||||
                if (ForwardDMs && ownerChannels.Any())
 | 
			
		||||
                {
 | 
			
		||||
                    var title = $"DM from [{Context.User}]({Context.User.Id})";
 | 
			
		||||
                    var title = $"DM from [{msg.Author}]({msg.Author.Id})";
 | 
			
		||||
                    if (ForwardDMsToAllOwners)
 | 
			
		||||
                    {
 | 
			
		||||
                        var msgs = await Task.WhenAll(ownerChannels.Where(ch => ch.Recipient.Id != Context.User.Id)
 | 
			
		||||
                        var msgs = await Task.WhenAll(ownerChannels.Where(ch => ch.Recipient.Id != msg.Author.Id)
 | 
			
		||||
                                                                   .Select(ch => ch.SendConfirmAsync(title, msg.Content))).ConfigureAwait(false);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        var firstOwnerChannel = ownerChannels.First();
 | 
			
		||||
                        if (firstOwnerChannel.Recipient.Id != Context.User.Id)
 | 
			
		||||
                        if (firstOwnerChannel.Recipient.Id != msg.Author.Id)
 | 
			
		||||
                            try { await firstOwnerChannel.SendConfirmAsync(title, msg.Content).ConfigureAwait(false); } catch { }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
@@ -65,7 +64,6 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
            public LogCommands()
 | 
			
		||||
            {
 | 
			
		||||
                //_client.MessageReceived += _client_MessageReceived;
 | 
			
		||||
                _client.MessageUpdated += _client_MessageUpdated;
 | 
			
		||||
                _client.MessageDeleted += _client_MessageDeleted;
 | 
			
		||||
                _client.UserBanned += _client_UserBanned;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
@@ -17,7 +16,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
    public partial class Administration
 | 
			
		||||
    {
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class RepeatCommands
 | 
			
		||||
        public class RepeatCommands : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            public static ConcurrentDictionary<ulong, RepeatRunner> repeaters { get; }
 | 
			
		||||
 | 
			
		||||
@@ -53,7 +52,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                            await Task.Delay(Repeater.Interval, token).ConfigureAwait(false);
 | 
			
		||||
                            if (oldMsg != null)
 | 
			
		||||
                                try { await oldMsg.DeleteAsync(); } catch { }
 | 
			
		||||
                            try { oldMsg = await Context.Channel.SendMessageAsync("🔄 " + Repeater.Message).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); try { source.Cancel(); } catch { } }
 | 
			
		||||
                            try { oldMsg = await Channel.SendMessageAsync("🔄 " + Repeater.Message).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); try { source.Cancel(); } catch { } }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (OperationCanceledException) { }
 | 
			
		||||
@@ -84,10 +83,8 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageMessages)]
 | 
			
		||||
            public async Task RepeatInvoke()
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                RepeatRunner rep;
 | 
			
		||||
                if (!repeaters.TryGetValue(channel.Id, out rep))
 | 
			
		||||
                if (!repeaters.TryGetValue(Context.Channel.Id, out rep))
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("ℹ️ **No repeating message found on this server.**").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
@@ -101,9 +98,8 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageMessages)]
 | 
			
		||||
            public async Task Repeat()
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
                RepeatRunner rep;
 | 
			
		||||
                if (repeaters.TryRemove(channel.Id, out rep))
 | 
			
		||||
                if (repeaters.TryRemove(Context.Channel.Id, out rep))
 | 
			
		||||
                {
 | 
			
		||||
                    using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                    {
 | 
			
		||||
@@ -122,8 +118,6 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageMessages)]
 | 
			
		||||
            public async Task Repeat(IUserMessage imsg, int minutes, [Remainder] string message)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                if (minutes < 1 || minutes > 10080)
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
@@ -132,20 +126,20 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
                RepeatRunner rep;
 | 
			
		||||
 | 
			
		||||
                rep = repeaters.AddOrUpdate(channel.Id, (cid) =>
 | 
			
		||||
                rep = repeaters.AddOrUpdate(Context.Channel.Id, (cid) =>
 | 
			
		||||
                {
 | 
			
		||||
                    using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                    {
 | 
			
		||||
                        var localRep = new Repeater
 | 
			
		||||
                        {
 | 
			
		||||
                            ChannelId = channel.Id,
 | 
			
		||||
                            ChannelId = Context.Channel.Id,
 | 
			
		||||
                            GuildId = Context.Guild.Id,
 | 
			
		||||
                            Interval = TimeSpan.FromMinutes(minutes),
 | 
			
		||||
                            Message = message,
 | 
			
		||||
                        };
 | 
			
		||||
                        uow.Repeaters.Add(localRep);
 | 
			
		||||
                        uow.Complete();
 | 
			
		||||
                        return new RepeatRunner(localRep, channel);
 | 
			
		||||
                        return new RepeatRunner(localRep, (ITextChannel)Context.Channel);
 | 
			
		||||
                    }
 | 
			
		||||
                }, (cid, old) =>
 | 
			
		||||
                {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
@@ -21,7 +20,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
    public partial class Administration
 | 
			
		||||
    {
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class Migration
 | 
			
		||||
        public class Migration : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            private const int CURRENT_VERSION = 1;
 | 
			
		||||
 | 
			
		||||
@@ -36,8 +35,6 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [OwnerOnly]
 | 
			
		||||
            public async Task MigrateData()
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                var version = 0;
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
@@ -8,9 +7,7 @@ using NadekoBot.Services;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Administration
 | 
			
		||||
@@ -18,7 +15,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
    public partial class Administration
 | 
			
		||||
    {
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class MuteCommands
 | 
			
		||||
        public class MuteCommands : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            private static ConcurrentDictionary<ulong, string> GuildMuteRoles { get; } = new ConcurrentDictionary<ulong, string>();
 | 
			
		||||
 | 
			
		||||
@@ -59,11 +56,11 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                if (muted == null || !muted.Contains(usr.Id))
 | 
			
		||||
                    return;
 | 
			
		||||
                else
 | 
			
		||||
                    await Mute(usr).ConfigureAwait(false);
 | 
			
		||||
                    await MuteCommands.MuteUser(usr).ConfigureAwait(false);
 | 
			
		||||
                    
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public static async Task Mute(IGuildUser usr)
 | 
			
		||||
            public static async Task MuteUser(IGuildUser usr)
 | 
			
		||||
            {
 | 
			
		||||
                await usr.ModifyAsync(x => x.Mute = true).ConfigureAwait(false);
 | 
			
		||||
                await usr.AddRolesAsync(await GetMuteRole(usr.Guild)).ConfigureAwait(false);
 | 
			
		||||
@@ -83,7 +80,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                await UserMuted(usr, MuteType.All).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public static async Task Unmute(IGuildUser usr)
 | 
			
		||||
            public static async Task UnmuteUser(IGuildUser usr)
 | 
			
		||||
            {
 | 
			
		||||
                await usr.ModifyAsync(x => x.Mute = false).ConfigureAwait(false);
 | 
			
		||||
                await usr.RemoveRolesAsync(await GetMuteRole(usr.Guild)).ConfigureAwait(false);
 | 
			
		||||
@@ -160,20 +157,18 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageRoles)]
 | 
			
		||||
            [Priority(0)]
 | 
			
		||||
            public Task SetMuteRole(IUserMessage imsg, [Remainder] IRole role)
 | 
			
		||||
                => SetMuteRole(imsg, role.Name);
 | 
			
		||||
            public Task SetMuteRole([Remainder] IRole role)
 | 
			
		||||
                => SetMuteRole(Context.Message, role.Name);
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageRoles)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.MuteMembers)]
 | 
			
		||||
            public async Task Mute(IUserMessage umsg, IGuildUser user)
 | 
			
		||||
            public async Task Mute(IGuildUser user)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    await Mute(user).ConfigureAwait(false);                    
 | 
			
		||||
                    await MuteUser(user).ConfigureAwait(false);                    
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync($"🔇 **{user}** has been **muted** from text and voice chat.").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                catch
 | 
			
		||||
@@ -186,13 +181,11 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageRoles)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.MuteMembers)]
 | 
			
		||||
            public async Task Unmute(IUserMessage umsg, IGuildUser user)
 | 
			
		||||
            public async Task Unmute(IGuildUser user)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    await Unmute(user).ConfigureAwait(false);
 | 
			
		||||
                    await UnmuteUser(user).ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync($"🔉 **{user}** has been **unmuted** from text and voice chat.").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                catch
 | 
			
		||||
@@ -204,10 +197,8 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageRoles)]
 | 
			
		||||
            public async Task ChatMute(IUserMessage umsg, IGuildUser user)
 | 
			
		||||
            public async Task ChatMute(IGuildUser user)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    await user.AddRolesAsync(await GetMuteRole(Context.Guild).ConfigureAwait(false)).ConfigureAwait(false);
 | 
			
		||||
@@ -223,10 +214,8 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageRoles)]
 | 
			
		||||
            public async Task ChatUnmute(IUserMessage umsg, IGuildUser user)
 | 
			
		||||
            public async Task ChatUnmute(IGuildUser user)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    await user.RemoveRolesAsync(await GetMuteRole(Context.Guild).ConfigureAwait(false)).ConfigureAwait(false);
 | 
			
		||||
@@ -242,10 +231,8 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.MuteMembers)]
 | 
			
		||||
            public async Task VoiceMute(IUserMessage umsg, IGuildUser user)
 | 
			
		||||
            public async Task VoiceMute(IGuildUser user)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    await user.ModifyAsync(usr => usr.Mute = true).ConfigureAwait(false);
 | 
			
		||||
@@ -261,9 +248,8 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.MuteMembers)]
 | 
			
		||||
            public async Task VoiceUnmute(IUserMessage umsg, IGuildUser user)
 | 
			
		||||
            public async Task VoiceUnmute(IGuildUser user)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    await user.ModifyAsync(usr => usr.Mute = false).ConfigureAwait(false);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
@@ -16,7 +15,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
    public partial class Administration
 | 
			
		||||
    {
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class PlayingRotateCommands
 | 
			
		||||
        public class PlayingRotateCommands : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            private static Logger _log { get; }
 | 
			
		||||
            public static List<PlayingStatus> RotatingStatusMessages { get; }
 | 
			
		||||
@@ -70,7 +69,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            public static Dictionary<string, Func<string>> PlayingPlaceholders { get; } =
 | 
			
		||||
                new Dictionary<string, Func<string>> {
 | 
			
		||||
                    {"%servers%", () => NadekoBot.Client.GetGuilds().Count().ToString()},
 | 
			
		||||
                    {"%users%", () => NadekoBot.Client.GetGuilds().Select(s => s.GetUsers().Count).Sum().ToString()},
 | 
			
		||||
                    {"%users%", () => NadekoBot.Client.GetGuilds().Select(s => s.Users.Count).Sum().ToString()},
 | 
			
		||||
                    {"%playing%", () => {
 | 
			
		||||
                            var cnt = Music.Music.MusicPlayers.Count(kvp => kvp.Value.CurrentSong != null);
 | 
			
		||||
                            if (cnt != 1) return cnt.ToString();
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
    public partial class Administration
 | 
			
		||||
    {
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class RatelimitCommand
 | 
			
		||||
        public class RatelimitCommand : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            public static ConcurrentDictionary<ulong, Ratelimiter> RatelimitingChannels = new ConcurrentDictionary<ulong, Ratelimiter>();
 | 
			
		||||
            private static Logger _log { get; }
 | 
			
		||||
@@ -68,7 +68,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                    var t = Task.Run(async () =>
 | 
			
		||||
                    {
 | 
			
		||||
                        var usrMsg = umsg as IUserMessage;
 | 
			
		||||
                        //var channel = usrContext.Channel as ITextChannel;
 | 
			
		||||
                        var channel = umsg.Channel as ITextChannel;
 | 
			
		||||
 | 
			
		||||
                        if (channel == null || usrMsg.IsAuthor())
 | 
			
		||||
                            return;
 | 
			
		||||
@@ -76,7 +76,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                        if (!RatelimitingChannels.TryGetValue(channel.Id, out limiter))
 | 
			
		||||
                            return;
 | 
			
		||||
 | 
			
		||||
                        if (limiter.CheckUserRatelimit(usrContext.User.Id))
 | 
			
		||||
                        if (limiter.CheckUserRatelimit(umsg.Author.Id))
 | 
			
		||||
                            try { await usrMsg.DeleteAsync(); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
                    });
 | 
			
		||||
                    return Task.CompletedTask;
 | 
			
		||||
@@ -88,10 +88,8 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageMessages)]
 | 
			
		||||
            public async Task Slowmode()
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                Ratelimiter throwaway;
 | 
			
		||||
                if (RatelimitingChannels.TryRemove(channel.Id, out throwaway))
 | 
			
		||||
                if (RatelimitingChannels.TryRemove(Context.Channel.Id, out throwaway))
 | 
			
		||||
                {
 | 
			
		||||
                    throwaway.cancelSource.Cancel();
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync("ℹ️ Slow mode disabled.").ConfigureAwait(false);
 | 
			
		||||
@@ -102,10 +100,9 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageMessages)]
 | 
			
		||||
            public async Task Slowmode(IUserMessage umsg, int msg, int perSec)
 | 
			
		||||
            public async Task Slowmode(int msg, int perSec)
 | 
			
		||||
            {
 | 
			
		||||
                await Slowmode(umsg).ConfigureAwait(false); // disable if exists
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
                await Slowmode().ConfigureAwait(false); // disable if exists
 | 
			
		||||
                
 | 
			
		||||
                if (msg < 1 || perSec < 1 || msg > 100 || perSec > 3600)
 | 
			
		||||
                {
 | 
			
		||||
@@ -114,11 +111,11 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                }
 | 
			
		||||
                var toAdd = new Ratelimiter()
 | 
			
		||||
                {
 | 
			
		||||
                    ChannelId = channel.Id,
 | 
			
		||||
                    ChannelId = Context.Channel.Id,
 | 
			
		||||
                    MaxMessages = msg,
 | 
			
		||||
                    PerSeconds = perSec,
 | 
			
		||||
                };
 | 
			
		||||
                if(RatelimitingChannels.TryAdd(channel.Id, toAdd))
 | 
			
		||||
                if(RatelimitingChannels.TryAdd(Context.Channel.Id, toAdd))
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync("Slow mode initiated",
 | 
			
		||||
                                                $"Users can't send more than `{toAdd.MaxMessages} message(s)` every `{toAdd.PerSeconds} second(s)`.")
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
    public partial class Administration
 | 
			
		||||
    {
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class SelfAssignedRolesCommands
 | 
			
		||||
        public class SelfAssignedRolesCommands : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
@@ -24,7 +24,6 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageMessages)]
 | 
			
		||||
            public async Task AdSarm()
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
                bool newval;
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
@@ -40,17 +39,15 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageRoles)]
 | 
			
		||||
            public async Task Asar(IUserMessage umsg, [Remainder] IRole role)
 | 
			
		||||
            public async Task Asar([Remainder] IRole role)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                IEnumerable<SelfAssignedRole> roles;
 | 
			
		||||
 | 
			
		||||
                string msg;
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    roles = uow.SelfAssignedRoles.GetFromGuild(Context.Guild.Id);
 | 
			
		||||
                    if (roles.Any(s => s.RoleId == role.Id && s.GuildId == role.GuildId))
 | 
			
		||||
                    if (roles.Any(s => s.RoleId == role.Id && s.GuildId == role.Guild.Id))
 | 
			
		||||
                    {
 | 
			
		||||
                        await Context.Channel.SendMessageAsync($"💢 Role **{role.Name}** is already in the list.").ConfigureAwait(false);
 | 
			
		||||
                        return;
 | 
			
		||||
@@ -59,7 +56,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                    {
 | 
			
		||||
                        uow.SelfAssignedRoles.Add(new SelfAssignedRole {
 | 
			
		||||
                            RoleId = role.Id,
 | 
			
		||||
                            GuildId = role.GuildId
 | 
			
		||||
                            GuildId = role.Guild.Id
 | 
			
		||||
                        });
 | 
			
		||||
                        await uow.CompleteAsync();
 | 
			
		||||
                        msg = $"🆗 Role **{role.Name}** added to the list.";
 | 
			
		||||
@@ -71,14 +68,14 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageRoles)]
 | 
			
		||||
            public async Task Rsar(IUserMessage umsg, [Remainder] IRole role)
 | 
			
		||||
            public async Task Rsar([Remainder] IRole role)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                bool success;
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    success = uow.SelfAssignedRoles.DeleteByGuildAndRoleId(role.GuildId, role.Id);
 | 
			
		||||
                    success = uow.SelfAssignedRoles.DeleteByGuildAndRoleId(role.Guild.Id, role.Id);
 | 
			
		||||
                    await uow.CompleteAsync();
 | 
			
		||||
                }
 | 
			
		||||
                if (!success)
 | 
			
		||||
@@ -147,11 +144,10 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task Iam(IUserMessage umsg, [Remainder] IRole role)
 | 
			
		||||
            public async Task Iam([Remainder] IRole role)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
                var guildUser = (IGuildUser)Context.User;
 | 
			
		||||
                var usrMsg = (IUserMessage)umsg;
 | 
			
		||||
 | 
			
		||||
                GuildConfig conf;
 | 
			
		||||
                IEnumerable<SelfAssignedRole> roles;
 | 
			
		||||
@@ -166,7 +162,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("That role is not self-assignable.").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                if (guildUser.Roles.Contains(role))
 | 
			
		||||
                if (guildUser.RoleIds.Contains(role.Id))
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendErrorAsync($"You already have **{role.Name}** role.").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
@@ -174,8 +170,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
                if (conf.ExclusiveSelfAssignedRoles)
 | 
			
		||||
                {
 | 
			
		||||
                    var sameRoles = guildUser.Roles.Where(r => roles.Any(rm => rm.RoleId == r.Id));
 | 
			
		||||
                    if (sameRoles.Any())
 | 
			
		||||
                    if (guildUser.RoleIds.Contains(role.Id))
 | 
			
		||||
                    {
 | 
			
		||||
                        await Context.Channel.SendErrorAsync($"You already have **{sameRoles.FirstOrDefault().Name}** `exclusive self-assigned` role.").ConfigureAwait(false);
 | 
			
		||||
                        return;
 | 
			
		||||
@@ -199,16 +194,15 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                    {
 | 
			
		||||
                        await Task.Delay(3000).ConfigureAwait(false);
 | 
			
		||||
                        try { await msg.DeleteAsync().ConfigureAwait(false); } catch { } // if 502 or something, i don't want bot crashing
 | 
			
		||||
                        try { await usrMsg.DeleteAsync().ConfigureAwait(false); } catch { }
 | 
			
		||||
                        try { await Context.Message.DeleteAsync().ConfigureAwait(false); } catch { }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task Iamnot(IUserMessage umsg, [Remainder] IRole role)
 | 
			
		||||
            public async Task Iamnot([Remainder] IRole role)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
                var guildUser = (IGuildUser)Context.User;
 | 
			
		||||
 | 
			
		||||
                bool autoDeleteSelfAssignedRoleMessages;
 | 
			
		||||
@@ -224,7 +218,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("💢 That role is not self-assignable.").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                if (!guildUser.Roles.Contains(role))
 | 
			
		||||
                if (!guildUser.RoleIds.Contains(role.Id))
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendErrorAsync($"❎ You don't have **{role.Name}** role.").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
@@ -246,7 +240,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                    {
 | 
			
		||||
                        await Task.Delay(3000).ConfigureAwait(false);
 | 
			
		||||
                        try { await msg.DeleteAsync().ConfigureAwait(false); } catch { } // if 502 or something, i don't want bot crashing
 | 
			
		||||
                        try { await umsg.DeleteAsync().ConfigureAwait(false); } catch { }
 | 
			
		||||
                        try { await Context.Message.DeleteAsync().ConfigureAwait(false); } catch { }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
@@ -10,7 +9,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
    public partial class Administration
 | 
			
		||||
    {
 | 
			
		||||
        [Group]
 | 
			
		||||
        class SelfCommands
 | 
			
		||||
        class SelfCommands : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            private ShardedDiscordClient _client;
 | 
			
		||||
 | 
			
		||||
@@ -22,10 +21,8 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            [OwnerOnly]
 | 
			
		||||
            public async Task Leave(IUserMessage umsg, [Remainder] string guildStr)
 | 
			
		||||
            public async Task Leave([Remainder] string guildStr)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                guildStr = guildStr.Trim().ToUpperInvariant();
 | 
			
		||||
                var server = _client.GetGuilds().FirstOrDefault(g => g.Id.ToString().Trim().ToUpperInvariant() == guildStr) ?? 
 | 
			
		||||
                    _client.GetGuilds().FirstOrDefault(g => g.Name.Trim().ToUpperInvariant() == guildStr);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using NLog;
 | 
			
		||||
using System;
 | 
			
		||||
@@ -15,7 +15,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
    public partial class Administration
 | 
			
		||||
    {
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class ServerGreetCommands
 | 
			
		||||
        public class ServerGreetCommands : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            private static Logger _log { get; }
 | 
			
		||||
 | 
			
		||||
@@ -26,7 +26,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                _log = LogManager.GetCurrentClassLogger();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            private static Task UserLeft(IGuildUser user)
 | 
			
		||||
            private static Task UserLeft(SocketGuildUser user)
 | 
			
		||||
            {
 | 
			
		||||
                var leftTask = Task.Run(async () =>
 | 
			
		||||
                {
 | 
			
		||||
@@ -39,7 +39,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (!conf.SendChannelByeMessage) return;
 | 
			
		||||
                        //var channel = (await user.Guild.GetTextChannelsAsync()).SingleOrDefault(c => c.Id == conf.ByeMessageChannelId);
 | 
			
		||||
                        var channel = (await user.Guild.GetTextChannelsAsync()).FirstOrDefault(c => c.Id == conf.ByeMessageChannelId);
 | 
			
		||||
 | 
			
		||||
                        if (channel == null) //maybe warn the server owner that the channel is missing
 | 
			
		||||
                            return;
 | 
			
		||||
@@ -49,7 +49,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                            return;
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            var toDelete = await Context.Channel.SendMessageAsync(msg.SanitizeMentions()).ConfigureAwait(false);
 | 
			
		||||
                            var toDelete = await channel.SendMessageAsync(msg.SanitizeMentions()).ConfigureAwait(false);
 | 
			
		||||
                            if (conf.AutoDeleteByeMessagesTimer > 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                var t = Task.Run(async () =>
 | 
			
		||||
@@ -80,7 +80,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
                        if (conf.SendChannelGreetMessage)
 | 
			
		||||
                        {
 | 
			
		||||
                            //var channel = (await user.Guild.GetTextChannelsAsync()).SingleOrDefault(c => c.Id == conf.GreetMessageChannelId);
 | 
			
		||||
                            var channel = (await user.Guild.GetTextChannelsAsync()).FirstOrDefault(c => c.Id == conf.GreetMessageChannelId);
 | 
			
		||||
                            if (channel != null) //maybe warn the server owner that the channel is missing
 | 
			
		||||
                            {
 | 
			
		||||
                                var msg = conf.ChannelGreetMessageText.Replace("%user%", user.Mention).Replace("%id%", user.Id.ToString()).Replace("%server%", user.Guild.Name);
 | 
			
		||||
@@ -88,7 +88,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                                {
 | 
			
		||||
                                    try
 | 
			
		||||
                                    {
 | 
			
		||||
                                        var toDelete = await Context.Channel.SendMessageAsync(msg.SanitizeMentions()).ConfigureAwait(false);
 | 
			
		||||
                                        var toDelete = await channel.SendMessageAsync(msg.SanitizeMentions()).ConfigureAwait(false);
 | 
			
		||||
                                        if (conf.AutoDeleteGreetMessagesTimer > 0)
 | 
			
		||||
                                        {
 | 
			
		||||
                                            var t = Task.Run(async () =>
 | 
			
		||||
@@ -105,14 +105,14 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
 | 
			
		||||
                        if (conf.SendDmGreetMessage)
 | 
			
		||||
                        {
 | 
			
		||||
                            //var channel = await user.CreateDMChannelAsync();
 | 
			
		||||
                            var channel = await user.CreateDMChannelAsync();
 | 
			
		||||
 | 
			
		||||
                            if (channel != null)
 | 
			
		||||
                            {
 | 
			
		||||
                                var msg = conf.DmGreetMessageText.Replace("%user%", user.Username).Replace("%server%", user.Guild.Name);
 | 
			
		||||
                                if (!string.IsNullOrWhiteSpace(msg))
 | 
			
		||||
                                {
 | 
			
		||||
                                    await Context.Channel.SendConfirmAsync(msg).ConfigureAwait(false);
 | 
			
		||||
                                    await channel.SendConfirmAsync(msg).ConfigureAwait(false);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
@@ -125,9 +125,9 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageGuild)]
 | 
			
		||||
            public async Task GreetDel(IUserMessage umsg, int timer = 30)
 | 
			
		||||
            public async Task GreetDel(int timer = 30)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
                var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
                if (timer < 0 || timer > 600)
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
@@ -158,9 +158,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageGuild)]
 | 
			
		||||
            public async Task Greet()
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                var enabled = await ServerGreetCommands.SetGreet(Context.Guild.Id, channel.Id).ConfigureAwait(false);
 | 
			
		||||
                var enabled = await ServerGreetCommands.SetGreet(Context.Guild.Id, Context.Channel.Id).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
                if (enabled)
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync("✅ Greeting messages **enabled** on this channel.").ConfigureAwait(false);
 | 
			
		||||
@@ -185,10 +183,8 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageGuild)]
 | 
			
		||||
            public async Task GreetMsg(IUserMessage umsg, [Remainder] string text = null)
 | 
			
		||||
            public async Task GreetMsg([Remainder] string text = null)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                if (string.IsNullOrWhiteSpace(text))
 | 
			
		||||
                {
 | 
			
		||||
                    string channelGreetMessageText;
 | 
			
		||||
@@ -231,8 +227,6 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageGuild)]
 | 
			
		||||
            public async Task GreetDm()
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                var enabled = await ServerGreetCommands.SetGreetDm(Context.Guild.Id).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
                if (enabled)
 | 
			
		||||
@@ -257,10 +251,8 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageGuild)]
 | 
			
		||||
            public async Task GreetDmMsg(IUserMessage umsg, [Remainder] string text = null)
 | 
			
		||||
            public async Task GreetDmMsg([Remainder] string text = null)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                if (string.IsNullOrWhiteSpace(text))
 | 
			
		||||
                {
 | 
			
		||||
                    GuildConfig config;
 | 
			
		||||
@@ -303,9 +295,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageGuild)]
 | 
			
		||||
            public async Task Bye()
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                var enabled = await ServerGreetCommands.SetBye(Context.Guild.Id, channel.Id).ConfigureAwait(false);
 | 
			
		||||
                var enabled = await ServerGreetCommands.SetBye(Context.Guild.Id, Context.Channel.Id).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
                if (enabled)
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync("✅ Bye announcements **enabled** on this channel.").ConfigureAwait(false);
 | 
			
		||||
@@ -330,10 +320,8 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageGuild)]
 | 
			
		||||
            public async Task ByeMsg(IUserMessage umsg, [Remainder] string text = null)
 | 
			
		||||
            public async Task ByeMsg([Remainder] string text = null)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                if (string.IsNullOrWhiteSpace(text))
 | 
			
		||||
                {
 | 
			
		||||
                    string byeMessageText;
 | 
			
		||||
@@ -376,8 +364,6 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageGuild)]
 | 
			
		||||
            public async Task ByeDel(IUserMessage umsg, int timer = 30)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                await ServerGreetCommands.SetByeDel(Context.Guild.Id, timer).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
                if (timer > 0)
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
    public partial class Administration
 | 
			
		||||
    {
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class VoicePlusTextCommands
 | 
			
		||||
        public class VoicePlusTextCommands : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            private static Regex channelNameRegex = new Regex(@"[^a-zA-Z0-9 -]", RegexOptions.Compiled);
 | 
			
		||||
            
 | 
			
		||||
@@ -29,9 +29,9 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                NadekoBot.Client.UserVoiceStateUpdated += UserUpdatedEventHandler;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            private static Task UserUpdatedEventHandler(IUser iuser, IVoiceState before, IVoiceState after)
 | 
			
		||||
            private static Task UserUpdatedEventHandler(SocketUser iuser, SocketVoiceState before, SocketVoiceState after)
 | 
			
		||||
            {
 | 
			
		||||
                var user = (iuser as IGuildUser);
 | 
			
		||||
                var user = (iuser as SocketGuildUser);
 | 
			
		||||
                var guild = user?.Guild;
 | 
			
		||||
 | 
			
		||||
                if (guild == null)
 | 
			
		||||
@@ -40,7 +40,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        var botUserPerms = guild.GetCurrentUser().GuildPermissions;
 | 
			
		||||
                        var botUserPerms = guild.CurrentUser.GuildPermissions;
 | 
			
		||||
                    
 | 
			
		||||
                        if (before.VoiceChannel == after.VoiceChannel) return;
 | 
			
		||||
                        
 | 
			
		||||
@@ -69,7 +69,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                        var beforeVch = before.VoiceChannel;
 | 
			
		||||
                        if (beforeVch != null)
 | 
			
		||||
                        {
 | 
			
		||||
                            var textChannel = guild.GetTextChannels().Where(t => t.Name == GetChannelName(beforeVch.Name).ToLowerInvariant()).FirstOrDefault();
 | 
			
		||||
                            var textChannel = (await guild.GetTextChannelsAsync()).Where(t => t.Name == GetChannelName(beforeVch.Name).ToLowerInvariant()).FirstOrDefault();
 | 
			
		||||
                            if (textChannel != null)
 | 
			
		||||
                                await textChannel.AddPermissionOverwriteAsync(user,
 | 
			
		||||
                                    new OverwritePermissions(readMessages: PermValue.Deny,
 | 
			
		||||
@@ -78,7 +78,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                        var afterVch = after.VoiceChannel;
 | 
			
		||||
                        if (afterVch != null && guild.AFKChannelId != afterVch.Id)
 | 
			
		||||
                        {
 | 
			
		||||
                            var textChannel = guild.GetTextChannels()
 | 
			
		||||
                            var textChannel = (await guild.GetTextChannelsAsync())
 | 
			
		||||
                                                        .Where(t => t.Name ==  GetChannelName(afterVch.Name).ToLowerInvariant())
 | 
			
		||||
                                                        .FirstOrDefault();
 | 
			
		||||
                            if (textChannel == null)
 | 
			
		||||
@@ -110,7 +110,6 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageChannels)]
 | 
			
		||||
            public async Task VoicePlusText()
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
                var guild = Context.Guild;
 | 
			
		||||
 | 
			
		||||
                var botUser = await guild.GetCurrentUserAsync().ConfigureAwait(false);
 | 
			
		||||
@@ -141,7 +140,7 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                    if (!isEnabled)
 | 
			
		||||
                    {
 | 
			
		||||
                        voicePlusTextCache.TryRemove(guild.Id);
 | 
			
		||||
                        foreach (var textChannel in guild.GetTextChannels().Where(c => c.Name.EndsWith("-voice")))
 | 
			
		||||
                        foreach (var textChannel in (await guild.GetTextChannelsAsync().ConfigureAwait(false)).Where(c => c.Name.EndsWith("-voice")))
 | 
			
		||||
                        {
 | 
			
		||||
                            try { await textChannel.DeleteAsync().ConfigureAwait(false); } catch { }
 | 
			
		||||
                        }
 | 
			
		||||
@@ -163,7 +162,6 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
            [RequireUserPermission(GuildPermission.ManageRoles)]
 | 
			
		||||
            public async Task CleanVPlusT()
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
                var guild = Context.Guild;
 | 
			
		||||
                var botUser = await guild.GetCurrentUserAsync().ConfigureAwait(false);
 | 
			
		||||
                if (!botUser.GuildPermissions.Administrator)
 | 
			
		||||
@@ -172,8 +170,8 @@ namespace NadekoBot.Modules.Administration
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                var allTxtChannels = guild.GetTextChannels().Where(c => c.Name.EndsWith("-voice"));
 | 
			
		||||
                var validTxtChannelNames = guild.GetVoiceChannels().Select(c => GetChannelName(c.Name).ToLowerInvariant());
 | 
			
		||||
                var allTxtChannels = (await guild.GetTextChannelsAsync()).Where(c => c.Name.EndsWith("-voice"));
 | 
			
		||||
                var validTxtChannelNames = (await guild.GetVoiceChannelsAsync()).Select(c => GetChannelName(c.Name).ToLowerInvariant());
 | 
			
		||||
 | 
			
		||||
                var invalidTxtChannels = allTxtChannels.Where(c => !validTxtChannelNames.Contains(c.Name));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@ using System.Threading.Tasks;
 | 
			
		||||
using Discord;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
@@ -59,8 +58,6 @@ namespace NadekoBot.Modules.ClashOfClans
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task CreateWar(IUserMessage umsg, int size, [Remainder] string enemyClan = null)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            if (!(Context.User as IGuildUser).GuildPermissions.ManageChannels)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
@@ -73,18 +70,15 @@ namespace NadekoBot.Modules.ClashOfClans
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            List<ClashWar> wars;
 | 
			
		||||
            //if (!ClashWars.TryGetValue(channel.Guild.Id, out wars))
 | 
			
		||||
            if (!ClashWars.TryGetValue(Context.Guild.Id, out wars))
 | 
			
		||||
            {
 | 
			
		||||
                wars = new List<ClashWar>();
 | 
			
		||||
                if (!ClashWars.TryAdd(Context.Guild.Id, wars))
 | 
			
		||||
				//if (!ClashWars.TryAdd(channel.Guild.Id, wars))
 | 
			
		||||
                    return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            var cw = await CreateWar(enemyClan, size, Context.Guild.Id, Context.Channel.Id);
 | 
			
		||||
			//var cw = await CreateWar(enemyClan, size, channel.Guild.Id, Context.Channel.Id);
 | 
			
		||||
 | 
			
		||||
            wars.Add(cw);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"❗🔰**CREATED CLAN WAR AGAINST {cw.ShortPrint()}**").ConfigureAwait(false);
 | 
			
		||||
@@ -94,12 +88,10 @@ namespace NadekoBot.Modules.ClashOfClans
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task StartWar(IUserMessage umsg, [Remainder] string number = null)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            int num = 0;
 | 
			
		||||
            int.TryParse(number, out num);
 | 
			
		||||
 | 
			
		||||
            var warsInfo = GetWarInfo(umsg, num);
 | 
			
		||||
            var warsInfo = GetWarInfo(umsg, Context.Guild, num);
 | 
			
		||||
            if (warsInfo == null)
 | 
			
		||||
            {
 | 
			
		||||
                await Context.Channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false);
 | 
			
		||||
@@ -122,7 +114,6 @@ namespace NadekoBot.Modules.ClashOfClans
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task ListWar(IUserMessage umsg, [Remainder] string number = null)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            // if number is null, print all wars in a short way
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(number))
 | 
			
		||||
@@ -130,7 +121,6 @@ namespace NadekoBot.Modules.ClashOfClans
 | 
			
		||||
                //check if there are any wars
 | 
			
		||||
                List<ClashWar> wars = null;
 | 
			
		||||
                ClashWars.TryGetValue(Context.Guild.Id, out wars);
 | 
			
		||||
				//ClashWars.TryGetValue(channel.Guild.Id, out wars);
 | 
			
		||||
                if (wars == null || wars.Count == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("🔰 **No active wars.**").ConfigureAwait(false);
 | 
			
		||||
@@ -153,7 +143,7 @@ namespace NadekoBot.Modules.ClashOfClans
 | 
			
		||||
            var num = 0;
 | 
			
		||||
            int.TryParse(number, out num);
 | 
			
		||||
            //if number is not null, print the war needed
 | 
			
		||||
            var warsInfo = GetWarInfo(umsg, num);
 | 
			
		||||
            var warsInfo = GetWarInfo(umsg, Context.Guild, num);
 | 
			
		||||
            if (warsInfo == null)
 | 
			
		||||
            {
 | 
			
		||||
                await Context.Channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false);
 | 
			
		||||
@@ -166,8 +156,7 @@ namespace NadekoBot.Modules.ClashOfClans
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Claim(IUserMessage umsg, int number, int baseNumber, [Remainder] string other_name = null)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            var warsInfo = GetWarInfo(umsg, number);
 | 
			
		||||
            var warsInfo = GetWarInfo(umsg, Context.Guild, number);
 | 
			
		||||
            if (warsInfo == null || warsInfo.Item1.Count == 0)
 | 
			
		||||
            {
 | 
			
		||||
                await Context.Channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false);
 | 
			
		||||
@@ -192,35 +181,30 @@ namespace NadekoBot.Modules.ClashOfClans
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task ClaimFinish1(IUserMessage umsg, int number, int baseNumber = 0)
 | 
			
		||||
        public async Task ClaimFinish1(int number, int baseNumber = 0)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            await FinishClaim(umsg, number, baseNumber - 1, 1);
 | 
			
		||||
            await FinishClaim(number, baseNumber - 1, 1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task ClaimFinish2(IUserMessage umsg, int number, int baseNumber = 0)
 | 
			
		||||
        public async Task ClaimFinish2(int number, int baseNumber = 0)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            await FinishClaim(umsg, number, baseNumber - 1, 2);
 | 
			
		||||
            await FinishClaim(number, baseNumber - 1, 2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task ClaimFinish(IUserMessage umsg, int number, int baseNumber = 0)
 | 
			
		||||
        public async Task ClaimFinish(int number, int baseNumber = 0)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            await FinishClaim(umsg, number, baseNumber - 1);
 | 
			
		||||
            await FinishClaim(number, baseNumber - 1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task EndWar(IUserMessage umsg, int number)
 | 
			
		||||
        public async Task EndWar(int number)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            var warsInfo = GetWarInfo(umsg,number);
 | 
			
		||||
            var warsInfo = GetWarInfo(Context.Message, Context.Guild, number);
 | 
			
		||||
            if (warsInfo == null)
 | 
			
		||||
            {
 | 
			
		||||
                await Context.Channel.SendErrorAsync("🔰 That war does not exist.").ConfigureAwait(false);
 | 
			
		||||
@@ -239,9 +223,7 @@ namespace NadekoBot.Modules.ClashOfClans
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Unclaim(IUserMessage umsg, int number, [Remainder] string otherName = null)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            var warsInfo = GetWarInfo(umsg, number);
 | 
			
		||||
            var warsInfo = GetWarInfo(umsg, Context.Guild, number);
 | 
			
		||||
            if (warsInfo == null || warsInfo.Item1.Count == 0)
 | 
			
		||||
            {
 | 
			
		||||
                await Context.Channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false);
 | 
			
		||||
@@ -264,10 +246,9 @@ namespace NadekoBot.Modules.ClashOfClans
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task FinishClaim(IUserMessage umsg, int number, int baseNumber, int stars = 3)
 | 
			
		||||
        private async Task FinishClaim(int number, int baseNumber, int stars = 3)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            var warInfo = GetWarInfo(umsg, number);
 | 
			
		||||
            var warInfo = GetWarInfo(Context.Message, Context.Guild, number);
 | 
			
		||||
            if (warInfo == null || warInfo.Item1.Count == 0)
 | 
			
		||||
            {
 | 
			
		||||
                await Context.Channel.SendErrorAsync("🔰 **That war does not exist.**").ConfigureAwait(false);
 | 
			
		||||
@@ -293,12 +274,10 @@ namespace NadekoBot.Modules.ClashOfClans
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static Tuple<List<ClashWar>, int> GetWarInfo(IUserMessage umsg, int num)
 | 
			
		||||
        private static Tuple<List<ClashWar>, int> GetWarInfo(IUserMessage umsg, IGuild guild, int num)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            //check if there are any wars
 | 
			
		||||
            List<ClashWar> wars = null;
 | 
			
		||||
            ClashWars.TryGetValue(Context.Guild.Id, out wars);
 | 
			
		||||
            ClashWars.TryGetValue(guild.Id, out wars);
 | 
			
		||||
            if (wars == null || wars.Count == 0)
 | 
			
		||||
            {
 | 
			
		||||
                return null;
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ using System.Collections.Concurrent;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using Discord;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.CustomReactions
 | 
			
		||||
{
 | 
			
		||||
@@ -33,16 +34,16 @@ namespace NadekoBot.Modules.CustomReactions
 | 
			
		||||
 | 
			
		||||
        public void ClearStats() => ReactionStats.Clear();
 | 
			
		||||
 | 
			
		||||
        public static async Task<bool> TryExecuteCustomReaction()
 | 
			
		||||
        public static async Task<bool> TryExecuteCustomReaction(SocketUserMessage umsg)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = Context.Channel as ITextChannel;
 | 
			
		||||
            var channel = umsg.Channel as SocketTextChannel;
 | 
			
		||||
            if (channel == null)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            var content = umsg.Content.Trim().ToLowerInvariant();
 | 
			
		||||
            ConcurrentHashSet<CustomReaction> reactions;
 | 
			
		||||
            //GuildReactions.TryGetValue(channel.Guild.Id, out reactions);
 | 
			
		||||
			GuildReactions.TryGetValue(Context.Guild.Id, out reactions);
 | 
			
		||||
 | 
			
		||||
            GuildReactions.TryGetValue(channel.Guild.Id, out reactions);
 | 
			
		||||
            if (reactions != null && reactions.Any())
 | 
			
		||||
            {
 | 
			
		||||
                var reaction = reactions.Where(cr =>
 | 
			
		||||
@@ -54,7 +55,7 @@ namespace NadekoBot.Modules.CustomReactions
 | 
			
		||||
                if (reaction != null)
 | 
			
		||||
                {
 | 
			
		||||
                    if (reaction.Response != "-")
 | 
			
		||||
                        try { await Context.Channel.SendMessageAsync(reaction.ResponseWithContext(umsg)).ConfigureAwait(false); } catch { }
 | 
			
		||||
                        try { await channel.SendMessageAsync(reaction.ResponseWithContext(umsg)).ConfigureAwait(false); } catch { }
 | 
			
		||||
 | 
			
		||||
                    ReactionStats.AddOrUpdate(reaction.Trigger, 1, (k, old) => ++old);
 | 
			
		||||
                    return true;
 | 
			
		||||
@@ -69,7 +70,7 @@ namespace NadekoBot.Modules.CustomReactions
 | 
			
		||||
 | 
			
		||||
            if (greaction != null)
 | 
			
		||||
            {
 | 
			
		||||
                try { await Context.Channel.SendMessageAsync(greaction.ResponseWithContext(umsg)).ConfigureAwait(false); } catch { }
 | 
			
		||||
                try { await channel.SendMessageAsync(greaction.ResponseWithContext(umsg)).ConfigureAwait(false); } catch { }
 | 
			
		||||
                ReactionStats.AddOrUpdate(greaction.Trigger, 1, (k, old) => ++old);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
@@ -77,9 +78,9 @@ namespace NadekoBot.Modules.CustomReactions
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        public async Task AddCustReact(IUserMessage imsg, string key, [Remainder] string message)
 | 
			
		||||
        public async Task AddCustReact(string key, [Remainder] string message)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = Context.Channel as ITextChannel;
 | 
			
		||||
            var channel = Context.Channel as ITextChannel;
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(message) || string.IsNullOrWhiteSpace(key))
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
@@ -113,7 +114,6 @@ namespace NadekoBot.Modules.CustomReactions
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                var reactions = GuildReactions.GetOrAdd(Context.Guild.Id, new ConcurrentHashSet<CustomReaction>());
 | 
			
		||||
				//var reactions = GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<CustomReaction>());
 | 
			
		||||
                reactions.Add(cr);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -127,18 +127,15 @@ namespace NadekoBot.Modules.CustomReactions
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [Priority(0)]
 | 
			
		||||
        public async Task ListCustReact(IUserMessage imsg, int page = 1)
 | 
			
		||||
        public async Task ListCustReact(int page = 1)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = Context.Channel as ITextChannel;
 | 
			
		||||
 | 
			
		||||
            if (page < 1 || page > 1000)
 | 
			
		||||
                return;
 | 
			
		||||
            ConcurrentHashSet<CustomReaction> customReactions;
 | 
			
		||||
            if (channel == null)
 | 
			
		||||
            if (Context.Guild == null)
 | 
			
		||||
                customReactions = GlobalReactions;
 | 
			
		||||
            else
 | 
			
		||||
                customReactions = GuildReactions.GetOrAdd(Context.Guild.Id, new ConcurrentHashSet<CustomReaction>());
 | 
			
		||||
				//customReactions = GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<CustomReaction>());
 | 
			
		||||
 | 
			
		||||
            if (customReactions == null || !customReactions.Any())
 | 
			
		||||
                await Context.Channel.SendErrorAsync("No custom reactions found").ConfigureAwait(false);
 | 
			
		||||
@@ -159,16 +156,13 @@ namespace NadekoBot.Modules.CustomReactions
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [Priority(1)]
 | 
			
		||||
        public async Task ListCustReact(IUserMessage imsg, All x)
 | 
			
		||||
        public async Task ListCustReact(All x)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = Context.Channel as ITextChannel;
 | 
			
		||||
 | 
			
		||||
            ConcurrentHashSet<CustomReaction> customReactions;
 | 
			
		||||
            if (channel == null)
 | 
			
		||||
            if (Context.Guild == null)
 | 
			
		||||
                customReactions = GlobalReactions;
 | 
			
		||||
            else
 | 
			
		||||
                customReactions = GuildReactions.GetOrAdd(Context.Guild.Id, new ConcurrentHashSet<CustomReaction>());
 | 
			
		||||
				//customReactions = GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<CustomReaction>());
 | 
			
		||||
 | 
			
		||||
            if (customReactions == null || !customReactions.Any())
 | 
			
		||||
                await Context.Channel.SendErrorAsync("No custom reactions found").ConfigureAwait(false);
 | 
			
		||||
@@ -180,7 +174,7 @@ namespace NadekoBot.Modules.CustomReactions
 | 
			
		||||
                                                          .ToJson()
 | 
			
		||||
                                                          .ToStream()
 | 
			
		||||
                                                          .ConfigureAwait(false);
 | 
			
		||||
                if (channel == null) // its a private one, just send back
 | 
			
		||||
                if (Context.Guild == null) // its a private one, just send back
 | 
			
		||||
                    await Context.Channel.SendFileAsync(txtStream, "customreactions.txt", "List of all custom reactions").ConfigureAwait(false);
 | 
			
		||||
                else
 | 
			
		||||
                    await ((IGuildUser)Context.User).SendFileAsync(txtStream, "customreactions.txt", "List of all custom reactions").ConfigureAwait(false);
 | 
			
		||||
@@ -188,17 +182,15 @@ namespace NadekoBot.Modules.CustomReactions
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        public async Task ListCustReactG(IUserMessage imsg, int page = 1)
 | 
			
		||||
        public async Task ListCustReactG(int page = 1)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = Context.Channel as ITextChannel;
 | 
			
		||||
            if (page < 1 || page > 10000)
 | 
			
		||||
                return;
 | 
			
		||||
            ConcurrentHashSet<CustomReaction> customReactions;
 | 
			
		||||
            if (channel == null)
 | 
			
		||||
            if (Context.Guild == null)
 | 
			
		||||
                customReactions = GlobalReactions;
 | 
			
		||||
            else
 | 
			
		||||
                customReactions = GuildReactions.GetOrAdd(Context.Guild.Id, new ConcurrentHashSet<CustomReaction>());
 | 
			
		||||
				//customReactions = GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<CustomReaction>());
 | 
			
		||||
 | 
			
		||||
            if (customReactions == null || !customReactions.Any())
 | 
			
		||||
                await Context.Channel.SendErrorAsync("No custom reactions found").ConfigureAwait(false);
 | 
			
		||||
@@ -216,14 +208,11 @@ namespace NadekoBot.Modules.CustomReactions
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        public async Task ShowCustReact(IUserMessage imsg, int id)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = Context.Channel as ITextChannel;
 | 
			
		||||
 | 
			
		||||
            ConcurrentHashSet<CustomReaction> customReactions;
 | 
			
		||||
            if (channel == null)
 | 
			
		||||
            if (Context.Guild == null)
 | 
			
		||||
                customReactions = GlobalReactions;
 | 
			
		||||
            else
 | 
			
		||||
                customReactions = GuildReactions.GetOrAdd(Context.Guild.Id, new ConcurrentHashSet<CustomReaction>());
 | 
			
		||||
				//customReactions = GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<CustomReaction>());
 | 
			
		||||
 | 
			
		||||
            var found = customReactions.FirstOrDefault(cr => cr.Id == id);
 | 
			
		||||
 | 
			
		||||
@@ -242,9 +231,7 @@ namespace NadekoBot.Modules.CustomReactions
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        public async Task DelCustReact(IUserMessage imsg, int id)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = Context.Channel as ITextChannel;
 | 
			
		||||
 | 
			
		||||
            if ((channel == null && !NadekoBot.Credentials.IsOwner(Context.User)) || (channel != null && !((IGuildUser)Context.User).GuildPermissions.Administrator))
 | 
			
		||||
            if ((Context.Guild == null && !NadekoBot.Credentials.IsOwner(Context.User)) || (Context.Guild != null && !((IGuildUser)Context.User).GuildPermissions.Administrator))
 | 
			
		||||
            {
 | 
			
		||||
                try { await Context.Channel.SendErrorAsync("Insufficient permissions. Requires Bot ownership for global custom reactions, and Administrator for guild custom reactions."); } catch { }
 | 
			
		||||
                return;
 | 
			
		||||
@@ -258,17 +245,16 @@ namespace NadekoBot.Modules.CustomReactions
 | 
			
		||||
                if (toDelete == null) //not found
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                if ((toDelete.GuildId == null || toDelete.GuildId == 0) && channel == null)
 | 
			
		||||
                if ((toDelete.GuildId == null || toDelete.GuildId == 0) && Context.Guild == null)
 | 
			
		||||
                {
 | 
			
		||||
                    uow.CustomReactions.Remove(toDelete);
 | 
			
		||||
                    GlobalReactions.RemoveWhere(cr => cr.Id == toDelete.Id);
 | 
			
		||||
                    success = true;
 | 
			
		||||
                }
 | 
			
		||||
                else if ((toDelete.GuildId != null && toDelete.GuildId != 0) && channel?.Guild.Id == toDelete.GuildId)
 | 
			
		||||
                else if ((toDelete.GuildId != null && toDelete.GuildId != 0) && Context.Guild.Id == toDelete.GuildId)
 | 
			
		||||
                {
 | 
			
		||||
                    uow.CustomReactions.Remove(toDelete);
 | 
			
		||||
                    GuildReactions.GetOrAdd(Context.Guild.Id, new ConcurrentHashSet<CustomReaction>()).RemoveWhere(cr => cr.Id == toDelete.Id);
 | 
			
		||||
					//GuildReactions.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<CustomReaction>()).RemoveWhere(cr => cr.Id == toDelete.Id);
 | 
			
		||||
                    success = true;
 | 
			
		||||
                }
 | 
			
		||||
                if (success)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using NLog;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
@@ -16,7 +17,7 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
    public partial class Gambling
 | 
			
		||||
    {
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class AnimalRacing
 | 
			
		||||
        public class AnimalRacing : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            public static ConcurrentDictionary<ulong, AnimalRace> AnimalRaces { get; } = new ConcurrentDictionary<ulong, AnimalRace>();
 | 
			
		||||
 | 
			
		||||
@@ -24,9 +25,7 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task Race()
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                var ar = new AnimalRace(Context.Guild.Id, channel);
 | 
			
		||||
                var ar = new AnimalRace(Context.Guild.Id, (ITextChannel)Context.Channel);
 | 
			
		||||
 | 
			
		||||
                if (ar.Fail)
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("🏁 `Failed starting a race. Another race is probably running.`");
 | 
			
		||||
@@ -36,8 +35,6 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task JoinRace(IUserMessage umsg, int amount = 0)
 | 
			
		||||
            {
 | 
			
		||||
                //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                if (amount < 0)
 | 
			
		||||
                    amount = 0;
 | 
			
		||||
 | 
			
		||||
@@ -194,12 +191,12 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                private Task Client_MessageReceived(IMessage imsg)
 | 
			
		||||
                private Task Client_MessageReceived(SocketMessage imsg)
 | 
			
		||||
                {
 | 
			
		||||
                    var msg = imsg as IUserMessage;
 | 
			
		||||
                    if (msg == null)
 | 
			
		||||
                        return Task.CompletedTask;
 | 
			
		||||
                    if (msg.IsAuthor() || !(Context.Channel is ITextChannel) || Context.Channel != raceChannel)
 | 
			
		||||
                    if (msg.IsAuthor() || !(imsg.Channel is SocketTextChannel) || imsg.Channel != raceChannel)
 | 
			
		||||
                        return Task.CompletedTask;
 | 
			
		||||
                    messagesSinceGameStarted++;
 | 
			
		||||
                    return Task.CompletedTask;
 | 
			
		||||
@@ -233,7 +230,7 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (amount > 0)
 | 
			
		||||
                        if (!await CurrencyHandler.RemoveCurrencyAsync((IGuildUser)u, "BetRace", amount, true).ConfigureAwait(false))
 | 
			
		||||
                        if (!await CurrencyHandler.RemoveCurrencyAsync(u, "BetRace", amount, true).ConfigureAwait(false))
 | 
			
		||||
                        {
 | 
			
		||||
                            try { await raceChannel.SendErrorAsync($"{u.Mention} You don't have enough {Gambling.CurrencyName}s.").ConfigureAwait(false); } catch { }
 | 
			
		||||
                            return;
 | 
			
		||||
 
 | 
			
		||||
@@ -6,10 +6,8 @@ using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Gambling
 | 
			
		||||
{
 | 
			
		||||
@@ -42,11 +40,8 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Raffle(IUserMessage umsg, [Remainder] IRole role = null)
 | 
			
		||||
        public async Task Raffle([Remainder] IRole role = null)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            //role = role ?? channel.Guild.EveryoneRole;
 | 
			
		||||
            role = role ?? Context.Guild.EveryoneRole;
 | 
			
		||||
 | 
			
		||||
            var members = role.Members().Where(u => u.Status != UserStatus.Offline && u.Status != UserStatus.Unknown);
 | 
			
		||||
@@ -57,10 +52,8 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [Priority(0)]
 | 
			
		||||
        public async Task Cash(IUserMessage umsg, [Remainder] IUser user = null)
 | 
			
		||||
        public async Task Cash([Remainder] IUser user = null)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = Context.Channel;
 | 
			
		||||
 | 
			
		||||
            user = user ?? Context.User;
 | 
			
		||||
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"{user.Username} has {GetCurrency(user.Id)} {CurrencySign}").ConfigureAwait(false);
 | 
			
		||||
@@ -68,18 +61,15 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [Priority(1)]
 | 
			
		||||
        public async Task Cash(IUserMessage umsg, ulong userId)
 | 
			
		||||
        public async Task Cash(ulong userId)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = Context.Channel;
 | 
			
		||||
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"`{userId}` has {GetCurrency(userId)} {CurrencySign}").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Give(IUserMessage umsg, long amount, [Remainder] IGuildUser receiver)
 | 
			
		||||
        public async Task Give(long amount, [Remainder] IGuildUser receiver)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            if (amount <= 0 || Context.User.Id == receiver.Id)
 | 
			
		||||
                return;
 | 
			
		||||
            var success = await CurrencyHandler.RemoveCurrencyAsync((IGuildUser)Context.User, $"Gift to {receiver.Username} ({receiver.Id}).", amount, true).ConfigureAwait(false);
 | 
			
		||||
@@ -96,17 +86,15 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        [OwnerOnly]
 | 
			
		||||
        [Priority(2)]
 | 
			
		||||
        public Task Award(IUserMessage umsg, int amount, [Remainder] IGuildUser usr) =>
 | 
			
		||||
            Award(umsg, amount, usr.Id);
 | 
			
		||||
        public Task Award(int amount, [Remainder] IGuildUser usr) =>
 | 
			
		||||
            Award(amount, usr.Id);
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        [OwnerOnly]
 | 
			
		||||
        [Priority(1)]
 | 
			
		||||
        public async Task Award(IUserMessage umsg, int amount, ulong usrId)
 | 
			
		||||
        public async Task Award(int amount, ulong usrId)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            if (amount <= 0)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
@@ -119,11 +107,10 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        [OwnerOnly]
 | 
			
		||||
        [Priority(0)]
 | 
			
		||||
        public async Task Award(IUserMessage umsg, int amount, [Remainder] IRole role)
 | 
			
		||||
        public async Task Award(int amount, [Remainder] IRole role)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            var users = Context.Guild.GetUsers()
 | 
			
		||||
			//var users = channel.Guild.GetUsers()
 | 
			
		||||
                               .Where(u => u.Roles.Contains(role))
 | 
			
		||||
                               .ToList();
 | 
			
		||||
            await Task.WhenAll(users.Select(u => CurrencyHandler.AddCurrencyAsync(u.Id,
 | 
			
		||||
@@ -132,7 +119,6 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
                         .ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"Awarded `{amount}` {Gambling.CurrencyPluralName} to `{users.Count}` users from `{role.Name}` role.")
 | 
			
		||||
			//await channel.SendConfirmAsync($"Awarded `{amount}` {Gambling.CurrencyPluralName} to `{users.Count}` users from `{role.Name}` role.")
 | 
			
		||||
                         .ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
@@ -140,9 +126,8 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        [OwnerOnly]
 | 
			
		||||
        public async Task Take(IUserMessage umsg, long amount, [Remainder] IGuildUser user)
 | 
			
		||||
        public async Task Take(long amount, [Remainder] IGuildUser user)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            if (amount <= 0)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
@@ -156,9 +141,8 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        [OwnerOnly]
 | 
			
		||||
        public async Task Take(IUserMessage umsg, long amount, [Remainder] ulong usrId)
 | 
			
		||||
        public async Task Take(long amount, [Remainder] ulong usrId)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            if (amount <= 0)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
@@ -170,10 +154,8 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task BetRoll(IUserMessage umsg, long amount)
 | 
			
		||||
        public async Task BetRoll(long amount)
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            if (amount < 1)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
@@ -222,8 +204,6 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Leaderboard()
 | 
			
		||||
        {
 | 
			
		||||
            //var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            IEnumerable<Currency> richest = new List<Currency>();
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,6 @@ using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using NLog;
 | 
			
		||||
using Services.CleverBotApi;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
@@ -19,7 +18,8 @@ namespace NadekoBot.Modules.Games
 | 
			
		||||
        {
 | 
			
		||||
            private static Logger _log { get; }
 | 
			
		||||
 | 
			
		||||
            class CleverAnswer {
 | 
			
		||||
            class CleverAnswer
 | 
			
		||||
            {
 | 
			
		||||
                public string Status { get; set; }
 | 
			
		||||
                public string Response { get; set; }
 | 
			
		||||
            }
 | 
			
		||||
@@ -41,7 +41,8 @@ namespace NadekoBot.Modules.Games
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public static async Task<bool> TryAsk(IUserMessage msg) {
 | 
			
		||||
            public static async Task<bool> TryAsk(IUserMessage msg)
 | 
			
		||||
            {
 | 
			
		||||
                var channel = msg.Channel as ITextChannel;
 | 
			
		||||
 | 
			
		||||
                if (channel == null)
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,6 @@ using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Games.Commands.Hangman
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,4 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Games.Commands.Hangman
 | 
			
		||||
namespace NadekoBot.Modules.Games.Commands.Hangman
 | 
			
		||||
{
 | 
			
		||||
    public class HangmanObject
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,10 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Modules.Games.Commands.Hangman;
 | 
			
		||||
using NLog;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Games
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ namespace NadekoBot.Modules.Games
 | 
			
		||||
    {
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Leet(IUserMessage umsg, int level, [Remainder] string text = null)
 | 
			
		||||
        public async Task Leet(int level, [Remainder] string text = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
@@ -103,7 +102,7 @@ namespace NadekoBot.Modules.Games
 | 
			
		||||
            {
 | 
			
		||||
                var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                if (!channel.Guild.GetCurrentUser().GetPermissions(channel).ManageMessages)
 | 
			
		||||
                if (!(await channel.Guild.GetCurrentUserAsync()).GetPermissions(channel).ManageMessages)
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync("I need manage channel permissions in order to process this command.").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using System;
 | 
			
		||||
@@ -42,7 +43,7 @@ namespace NadekoBot.Modules.Games
 | 
			
		||||
                if (data.Length < 3)
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                var poll = new Poll(umsg, data[0], data.Skip(1), isPublic: isPublic);
 | 
			
		||||
                var poll = new Poll(Context.Message, data[0], data.Skip(1), isPublic: isPublic);
 | 
			
		||||
                if (ActivePolls.TryAdd(channel.Guild, poll))
 | 
			
		||||
                {
 | 
			
		||||
                    await poll.StartPoll().ConfigureAwait(false);
 | 
			
		||||
@@ -127,10 +128,10 @@ namespace NadekoBot.Modules.Games
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            private Task Vote(IMessage imsg)
 | 
			
		||||
            private Task Vote(SocketMessage imsg)
 | 
			
		||||
            {
 | 
			
		||||
                // has to be a user message
 | 
			
		||||
                var msg = imsg as IUserMessage;
 | 
			
		||||
                var msg = imsg as SocketUserMessage;
 | 
			
		||||
                if (msg == null || imsg.Author.IsBot)
 | 
			
		||||
                    return Task.CompletedTask;
 | 
			
		||||
 | 
			
		||||
@@ -156,25 +157,25 @@ namespace NadekoBot.Modules.Games
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            //if private, channel must be dm channel
 | 
			
		||||
                            if ((ch = Context.Channel as IDMChannel) == null)
 | 
			
		||||
                            if ((ch = msg.Channel as SocketDMChannel) == null)
 | 
			
		||||
                                return;
 | 
			
		||||
 | 
			
		||||
                            // user must be a member of the guild this poll is in
 | 
			
		||||
                            var guildUsers = await guild.GetUsersAsync().ConfigureAwait(false);
 | 
			
		||||
                            if (!guildUsers.Any(u => u.Id == Context.User.Id))
 | 
			
		||||
                            if (!guildUsers.Any(u => u.Id == msg.Author.Id))
 | 
			
		||||
                                return;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        //user can vote only once
 | 
			
		||||
                        if (participants.TryAdd(Context.User.Id, vote))
 | 
			
		||||
                        if (participants.TryAdd(msg.Author.Id, vote))
 | 
			
		||||
                        {
 | 
			
		||||
                            if (!isPublic)
 | 
			
		||||
                            {
 | 
			
		||||
                                await ch.SendConfirmAsync($"Thanks for voting **{Context.User.Username}**.").ConfigureAwait(false);
 | 
			
		||||
                                await ch.SendConfirmAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false);
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                            {
 | 
			
		||||
                                var toDelete = await ch.SendConfirmAsync($"{Context.User.Mention} cast their vote.").ConfigureAwait(false);
 | 
			
		||||
                                var toDelete = await ch.SendConfirmAsync($"{msg.Author.Mention} cast their vote.").ConfigureAwait(false);
 | 
			
		||||
                                await Task.Delay(5000);
 | 
			
		||||
                                await toDelete.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
                            }
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ namespace NadekoBot.Modules.Games
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class TriviaCommands : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            public static ConcurrentDictionary<ulong, TriviaGame> RunningTrivias = new ConcurrentDictionary<ulong, TriviaGame>();
 | 
			
		||||
            public static ConcurrentDictionary<ulong, TriviaGame> RunningTrivias { get; } = new ConcurrentDictionary<ulong, TriviaGame>();
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,8 @@ using System.Text.RegularExpressions;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Music
 | 
			
		||||
{
 | 
			
		||||
    [NadekoModule("Music", "!!", AutoLoad = false)]
 | 
			
		||||
    [NadekoModule("Music", "!!")]
 | 
			
		||||
    [DontAutoLoad]
 | 
			
		||||
    public partial class Music : DiscordModule
 | 
			
		||||
    {
 | 
			
		||||
        public static ConcurrentDictionary<ulong, MusicPlayer> MusicPlayers { get; } = new ConcurrentDictionary<ulong, MusicPlayer>();
 | 
			
		||||
@@ -37,7 +38,7 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
    
 | 
			
		||||
    private async Task Client_UserVoiceStateUpdated(SocketUser iusr, SocketVoiceState oldState, SocketVoiceState newState)
 | 
			
		||||
        {
 | 
			
		||||
            var usr = iusr as IGuildUser;
 | 
			
		||||
            var usr = iusr as SocketGuildUser;
 | 
			
		||||
            if (usr == null ||
 | 
			
		||||
                oldState.VoiceChannel == newState.VoiceChannel)
 | 
			
		||||
                return;
 | 
			
		||||
@@ -62,13 +63,11 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public Task Next(int skipCount = 1)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            if (skipCount < 1)
 | 
			
		||||
                return Task.CompletedTask;
 | 
			
		||||
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return Task.CompletedTask;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return Task.CompletedTask;
 | 
			
		||||
            if (musicPlayer.PlaybackVoiceChannel == ((IGuildUser)Context.User).VoiceChannel)
 | 
			
		||||
            {
 | 
			
		||||
                while (--skipCount > 0)
 | 
			
		||||
@@ -84,10 +83,8 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public Task Stop()
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return Task.CompletedTask;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return Task.CompletedTask;
 | 
			
		||||
            if (((IGuildUser)Context.User).VoiceChannel == musicPlayer.PlaybackVoiceChannel)
 | 
			
		||||
            {
 | 
			
		||||
                musicPlayer.Autoplay = false;
 | 
			
		||||
@@ -100,12 +97,10 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public Task Destroy()
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return Task.CompletedTask;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return Task.CompletedTask;
 | 
			
		||||
            if (((IGuildUser)Context.User).VoiceChannel == musicPlayer.PlaybackVoiceChannel)
 | 
			
		||||
                if(MusicPlayers.TryRemove(channel.Guild.Id, out musicPlayer))
 | 
			
		||||
                if(MusicPlayers.TryRemove(Context.Guild.Id, out musicPlayer))
 | 
			
		||||
                    musicPlayer.Destroy();
 | 
			
		||||
            return Task.CompletedTask;
 | 
			
		||||
        }
 | 
			
		||||
@@ -114,10 +109,8 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public Task Pause()
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return Task.CompletedTask;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return Task.CompletedTask;
 | 
			
		||||
            if (((IGuildUser)Context.User).VoiceChannel != musicPlayer.PlaybackVoiceChannel)
 | 
			
		||||
                return Task.CompletedTask;
 | 
			
		||||
            musicPlayer.TogglePause();
 | 
			
		||||
@@ -128,10 +121,8 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Queue([Remainder] string query)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            await QueueSong(((IGuildUser)Context.User), channel, ((IGuildUser)Context.User).VoiceChannel, query).ConfigureAwait(false);
 | 
			
		||||
            if (channel.Guild.GetCurrentUser().GetPermissions(channel).ManageMessages)
 | 
			
		||||
            await QueueSong(((IGuildUser)Context.User), (ITextChannel)Context.Channel, ((IGuildUser)Context.User).VoiceChannel, query).ConfigureAwait(false);
 | 
			
		||||
            if (Context.Guild.GetCurrentUser().GetPermissions(Context.Channel).ManageMessages)
 | 
			
		||||
            {
 | 
			
		||||
                await Task.Delay(10000).ConfigureAwait(false);
 | 
			
		||||
                await Context.Message.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
@@ -142,10 +133,8 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task SoundCloudQueue([Remainder] string query)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            await QueueSong(((IGuildUser)Context.User), channel, ((IGuildUser)Context.User).VoiceChannel, query, musicType: MusicType.Soundcloud).ConfigureAwait(false);
 | 
			
		||||
            if (channel.Guild.GetCurrentUser().GetPermissions(channel).ManageMessages)
 | 
			
		||||
            await QueueSong(((IGuildUser)Context.User), (ITextChannel)Context.Channel, ((IGuildUser)Context.User).VoiceChannel, query, musicType: MusicType.Soundcloud).ConfigureAwait(false);
 | 
			
		||||
            if (Context.Guild.GetCurrentUser().GetPermissions(Context.Channel).ManageMessages)
 | 
			
		||||
            {
 | 
			
		||||
                await Task.Delay(10000).ConfigureAwait(false);
 | 
			
		||||
                await Context.Message.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
@@ -156,11 +145,11 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task ListQueue(int page = 1)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("🎵 No active music player.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("🎵 No active music player.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (page <= 0)
 | 
			
		||||
@@ -189,17 +178,15 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
            const int itemsPerPage = 15;
 | 
			
		||||
            int startAt = itemsPerPage * (page - 1);
 | 
			
		||||
            var number = 1 + startAt;
 | 
			
		||||
            await channel.SendConfirmAsync(toSend + string.Join("\n", musicPlayer.Playlist.Skip(startAt).Take(15).Select(v => $"`{number++}.` {v.PrettyName}"))).ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync(toSend + string.Join("\n", musicPlayer.Playlist.Skip(startAt).Take(15).Select(v => $"`{number++}.` {v.PrettyName}"))).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task NowPlaying()
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
        
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
			
		||||
                return;
 | 
			
		||||
            var currentSong = musicPlayer.CurrentSong;
 | 
			
		||||
            if (currentSong == null)
 | 
			
		||||
@@ -225,98 +212,97 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        {
 | 
			
		||||
                embed.WithThumbnailUrl($"{currentSong.SongInfo.AlbumArt}");
 | 
			
		||||
        }
 | 
			
		||||
                await channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Volume(int val)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
			
		||||
                return;
 | 
			
		||||
            if (((IGuildUser)Context.User).VoiceChannel != musicPlayer.PlaybackVoiceChannel)
 | 
			
		||||
                return;
 | 
			
		||||
            if (val < 0)
 | 
			
		||||
                return;
 | 
			
		||||
            var volume = musicPlayer.SetVolume(val);
 | 
			
		||||
            await channel.SendConfirmAsync($"🎵 Volume set to {volume}%").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"🎵 Volume set to {volume}%").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Defvol([Remainder] int val)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            if (val < 0 || val > 100)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Volume number invalid. Must be between 0 and 100").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Volume number invalid. Must be between 0 and 100").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                uow.GuildConfigs.For(channel.Guild.Id, set => set).DefaultMusicVolume = val / 100.0f;
 | 
			
		||||
                uow.GuildConfigs.For(Context.Guild.Id, set => set).DefaultMusicVolume = val / 100.0f;
 | 
			
		||||
                uow.Complete();
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendConfirmAsync($"🎵 Default volume set to {val}%").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"🎵 Default volume set to {val}%").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task ShufflePlaylist()
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
			
		||||
                return;
 | 
			
		||||
            if (((IGuildUser)Context.User).VoiceChannel != musicPlayer.PlaybackVoiceChannel)
 | 
			
		||||
                return;
 | 
			
		||||
            if (musicPlayer.Playlist.Count < 2)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("💢 Not enough songs in order to perform the shuffle.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("💢 Not enough songs in order to perform the shuffle.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            musicPlayer.Shuffle();
 | 
			
		||||
            await channel.SendConfirmAsync("🎵 Songs shuffled.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync("🎵 Songs shuffled.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Playlist([Remainder] string playlist)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
            var arg = playlist;
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(arg))
 | 
			
		||||
                return;
 | 
			
		||||
            if (((IGuildUser)Context.User).VoiceChannel?.Guild != channel.Guild)
 | 
			
		||||
            if (((IGuildUser)Context.User).VoiceChannel?.Guild != Context.Guild)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("💢 You need to be in a **voice channel** on this server.\n If you are already in a voice channel, try rejoining it.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("💢 You need to be in a **voice channel** on this server.\n If you are already in a voice (ITextChannel)Context.Channel, try rejoining it.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var plId = (await NadekoBot.Google.GetPlaylistIdsByKeywordsAsync(arg).ConfigureAwait(false)).FirstOrDefault();
 | 
			
		||||
            if (plId == null)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("No search results for that query.");
 | 
			
		||||
                await Context.Channel.SendErrorAsync("No search results for that query.");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var ids = await NadekoBot.Google.GetPlaylistTracksAsync(plId, 500).ConfigureAwait(false);
 | 
			
		||||
            if (!ids.Any())
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync($"🎵 Failed to find any songs.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync($"🎵 Failed to find any songs.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var idArray = ids as string[] ?? ids.ToArray();
 | 
			
		||||
            var count = idArray.Length;
 | 
			
		||||
            var msg =
 | 
			
		||||
                await channel.SendMessageAsync($"🎵 Attempting to queue **{count}** songs".SnPl(count) + "...").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendMessageAsync($"🎵 Attempting to queue **{count}** songs".SnPl(count) + "...").ConfigureAwait(false);
 | 
			
		||||
            foreach (var id in idArray)
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    await QueueSong(((IGuildUser)Context.User), channel, ((IGuildUser)Context.User).VoiceChannel, id, true).ConfigureAwait(false);
 | 
			
		||||
                    await QueueSong(((IGuildUser)Context.User), (ITextChannel)Context.Channel, ((IGuildUser)Context.User).VoiceChannel, id, true).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                catch (SongNotFoundException) { }
 | 
			
		||||
                catch { break; }
 | 
			
		||||
@@ -328,7 +314,7 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task SoundCloudPl([Remainder] string pl)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
            pl = pl?.Trim();
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(pl))
 | 
			
		||||
@@ -337,10 +323,10 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
            using (var http = new HttpClient())
 | 
			
		||||
            {
 | 
			
		||||
                var scvids = JObject.Parse(await http.GetStringAsync($"http://api.soundcloud.com/resolve?url={pl}&client_id={NadekoBot.Credentials.SoundCloudClientId}").ConfigureAwait(false))["tracks"].ToObject<SoundCloudVideo[]>();
 | 
			
		||||
                await QueueSong(((IGuildUser)Context.User), channel, ((IGuildUser)Context.User).VoiceChannel, scvids[0].TrackLink).ConfigureAwait(false);
 | 
			
		||||
                await QueueSong(((IGuildUser)Context.User), (ITextChannel)Context.Channel, ((IGuildUser)Context.User).VoiceChannel, scvids[0].TrackLink).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
                MusicPlayer mp;
 | 
			
		||||
                if (!MusicPlayers.TryGetValue(channel.Guild.Id, out mp))
 | 
			
		||||
                if (!MusicPlayers.TryGetValue(Context.Guild.Id, out mp))
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                foreach (var svideo in scvids.Skip(1))
 | 
			
		||||
@@ -366,7 +352,7 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [OwnerOnly]
 | 
			
		||||
        public async Task LocalPl([Remainder] string directory)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
            var arg = directory;
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(arg))
 | 
			
		||||
                return;
 | 
			
		||||
@@ -379,7 +365,7 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        await QueueSong(((IGuildUser)Context.User), channel, ((IGuildUser)Context.User).VoiceChannel, file.FullName, true, MusicType.Local).ConfigureAwait(false);
 | 
			
		||||
                        await QueueSong(((IGuildUser)Context.User), (ITextChannel)Context.Channel, ((IGuildUser)Context.User).VoiceChannel, file.FullName, true, MusicType.Local).ConfigureAwait(false);
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (PlaylistFullException)
 | 
			
		||||
                    {
 | 
			
		||||
@@ -387,7 +373,7 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
                    }
 | 
			
		||||
                    catch { }
 | 
			
		||||
                }
 | 
			
		||||
                await channel.SendConfirmAsync("🎵 Directory queue complete.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendConfirmAsync("🎵 Directory queue complete.").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            catch { }
 | 
			
		||||
        }
 | 
			
		||||
@@ -396,14 +382,14 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Radio(string radio_link)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            if (((IGuildUser)Context.User).VoiceChannel?.Guild != channel.Guild)
 | 
			
		||||
            
 | 
			
		||||
            if (((IGuildUser)Context.User).VoiceChannel?.Guild != Context.Guild)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining it.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice (ITextChannel)Context.Channel, try rejoining it.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            await QueueSong(((IGuildUser)Context.User), channel, ((IGuildUser)Context.User).VoiceChannel, radio_link, musicType: MusicType.Radio).ConfigureAwait(false);
 | 
			
		||||
            if (channel.Guild.GetCurrentUser().GetPermissions(channel).ManageMessages)
 | 
			
		||||
            await QueueSong(((IGuildUser)Context.User), (ITextChannel)Context.Channel, ((IGuildUser)Context.User).VoiceChannel, radio_link, musicType: MusicType.Radio).ConfigureAwait(false);
 | 
			
		||||
            if (Context.Guild.GetCurrentUser().GetPermissions(Context.Channel).ManageMessages)
 | 
			
		||||
            {
 | 
			
		||||
                await Task.Delay(10000).ConfigureAwait(false);
 | 
			
		||||
                await Context.Message.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
@@ -415,11 +401,11 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [OwnerOnly]
 | 
			
		||||
        public async Task Local([Remainder] string path)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
            var arg = path;
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(arg))
 | 
			
		||||
                return;
 | 
			
		||||
            await QueueSong(((IGuildUser)Context.User), channel, ((IGuildUser)Context.User).VoiceChannel, path, musicType: MusicType.Local).ConfigureAwait(false);
 | 
			
		||||
            await QueueSong(((IGuildUser)Context.User), (ITextChannel)Context.Channel, ((IGuildUser)Context.User).VoiceChannel, path, musicType: MusicType.Local).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -427,10 +413,10 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Move()
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            var voiceChannel = ((IGuildUser)Context.User).VoiceChannel;
 | 
			
		||||
            if (voiceChannel == null || voiceChannel.Guild != channel.Guild || !MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
			
		||||
            if (voiceChannel == null || voiceChannel.Guild != Context.Guild || !MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
			
		||||
                return;
 | 
			
		||||
            await musicPlayer.MoveToVoiceChannel(voiceChannel);
 | 
			
		||||
        }
 | 
			
		||||
@@ -440,10 +426,10 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [Priority(0)]
 | 
			
		||||
        public async Task Remove(int num)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
@@ -453,7 +439,7 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
                return;
 | 
			
		||||
            var song = (musicPlayer.Playlist as List<Song>)?[num - 1];
 | 
			
		||||
            musicPlayer.RemoveSongAt(num - 1);
 | 
			
		||||
            await channel.SendConfirmAsync($"🎵 Track {song.PrettyName} at position `#{num}` has been **removed**.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"🎵 Track {song.PrettyName} at position `#{num}` has been **removed**.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
@@ -461,14 +447,14 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [Priority(1)]
 | 
			
		||||
        public async Task Remove(string all)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            if (all.Trim().ToUpperInvariant() != "ALL")
 | 
			
		||||
                return;
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer)) return;
 | 
			
		||||
            musicPlayer.ClearQueue();
 | 
			
		||||
            await channel.SendConfirmAsync($"🎵 Queue cleared!").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"🎵 Queue cleared!").ConfigureAwait(false);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -476,9 +462,9 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task MoveSong([Remainder] string fromto)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
@@ -494,7 +480,7 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
                !int.TryParse(fromtoArr[1], out n2) || n1 < 1 || n2 < 1 || n1 == n2 ||
 | 
			
		||||
                n1 > playlist.Count || n2 > playlist.Count)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Invalid input.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Invalid input.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -507,10 +493,10 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
                .WithTitle($"{s.SongInfo.Title.TrimTo(70)}")
 | 
			
		||||
            .WithUrl($"{s.SongInfo.Query}")
 | 
			
		||||
            .WithAuthor(eab => eab.WithName("Song Moved").WithIconUrl("https://cdn.discordapp.com/attachments/155726317222887425/258605269972549642/music1.png"))
 | 
			
		||||
        .AddField(fb => fb.WithName("**From Position**").WithValue($"#{n1}").WithIsInline(true))
 | 
			
		||||
        .AddField(fb => fb.WithName("**To Position**").WithValue($"#{n2}").WithIsInline(true))
 | 
			
		||||
            .AddField(fb => fb.WithName("**From**").WithValue($"#{n1}").WithIsInline(true))
 | 
			
		||||
            .AddField(fb => fb.WithName("**To**").WithValue($"#{n2}").WithIsInline(true))
 | 
			
		||||
            .WithColor(NadekoBot.OkColor);
 | 
			
		||||
            await channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
            //await channel.SendConfirmAsync($"🎵Moved {s.PrettyName} `from #{n1} to #{n2}`").ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
@@ -521,29 +507,28 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task SetMaxQueue(uint size)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            musicPlayer.MaxQueueSize = size;
 | 
			
		||||
            await channel.SendConfirmAsync($"🎵 Max queue set to {(size == 0 ? ("unlimited") : size + " tracks")}.");
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"🎵 Max queue set to {(size == 0 ? ("unlimited") : size + " tracks")}.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task ReptCurSong()
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
			
		||||
                return;
 | 
			
		||||
            var currentSong = musicPlayer.CurrentSong;
 | 
			
		||||
            if (currentSong == null)
 | 
			
		||||
                return;
 | 
			
		||||
            var currentValue = musicPlayer.ToggleRepeatSong();
 | 
			
		||||
            await channel.SendConfirmAsync(currentValue ?
 | 
			
		||||
            await Context.Channel.SendConfirmAsync(currentValue ?
 | 
			
		||||
                                        $"🔂 Repeating track: {currentSong.PrettyName}" :
 | 
			
		||||
                                        $"🔂 Current track repeat stopped.")
 | 
			
		||||
                                            .ConfigureAwait(false);
 | 
			
		||||
@@ -553,21 +538,21 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task RepeatPl()
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
			
		||||
                return;
 | 
			
		||||
            var currentValue = musicPlayer.ToggleRepeatPlaylist();
 | 
			
		||||
            await channel.SendConfirmAsync($"🔁 Repeat playlist {(currentValue ? "**enabled**." : "**disabled**.")}").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"🔁 Repeat playlist {(currentValue ? "**enabled**." : "**disabled**.")}").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Save([Remainder] string name)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            var curSong = musicPlayer.CurrentSong;
 | 
			
		||||
@@ -594,15 +579,13 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await channel.SendConfirmAsync(($"🎵 Saved playlist as **{name}**, ID: {playlist.Id}.")).ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync(($"🎵 Saved playlist as **{name}**, ID: {playlist.Id}.")).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Load([Remainder] int id)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            MusicPlaylist mpl;
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
@@ -611,17 +594,17 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
 | 
			
		||||
            if (mpl == null)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Can't find playlist with that ID.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Can't find playlist with that ID.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            IUserMessage msg = null;
 | 
			
		||||
            try { msg = await channel.SendMessageAsync($"🎶 Attempting to load **{mpl.Songs.Count}** songs...").ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
 | 
			
		||||
            try { msg = await Context.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)Context.User;
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    await QueueSong(usr, channel, usr.VoiceChannel, item.Query, true, item.ProviderType).ConfigureAwait(false);
 | 
			
		||||
                    await QueueSong(usr, (ITextChannel)Context.Channel, usr.VoiceChannel, item.Query, true, item.ProviderType).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                catch (SongNotFoundException) { }
 | 
			
		||||
                catch { break; }
 | 
			
		||||
@@ -634,7 +617,7 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Playlists([Remainder] int num = 1)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            if (num <= 0)
 | 
			
		||||
                return;
 | 
			
		||||
@@ -646,7 +629,7 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
                playlists = uow.MusicPlaylists.GetPlaylistsOnPage(num);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await channel.SendConfirmAsync($@"🎶 **Page {num} of saved playlists:**
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($@"🎶 **Page {num} of saved playlists:**
 | 
			
		||||
 | 
			
		||||
" + string.Join("\n", playlists.Select(r => $"`#{r.Id}` - **{r.Name}** by __{r.Author}__ ({r.Songs.Count} songs)"))).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
@@ -656,7 +639,7 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task DeletePlaylist([Remainder] int id)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            bool success = false;
 | 
			
		||||
            MusicPlaylist pl = null;
 | 
			
		||||
@@ -680,9 +663,9 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (!success)
 | 
			
		||||
                    await channel.SendErrorAsync("Failed to delete that playlist. It either doesn't exist, or you are not its author.").ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("Failed to delete that playlist. It either doesn't exist, or you are not its author.").ConfigureAwait(false);
 | 
			
		||||
                else
 | 
			
		||||
                    await channel.SendConfirmAsync("🗑 Playlist successfully **deleted**.").ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync("🗑 Playlist successfully **deleted**.").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
@@ -694,10 +677,10 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Goto(int time)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
			
		||||
                return;
 | 
			
		||||
            if (((IGuildUser)Context.User).VoiceChannel != musicPlayer.PlaybackVoiceChannel)
 | 
			
		||||
                return;
 | 
			
		||||
@@ -724,16 +707,16 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
            if (seconds.Length == 1)
 | 
			
		||||
                seconds = "0" + seconds;
 | 
			
		||||
 | 
			
		||||
            await channel.SendConfirmAsync($"Skipped to `{minutes}:{seconds}`").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"Skipped to `{minutes}:{seconds}`").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task GetLink(int index = 0)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            if (index < 0)
 | 
			
		||||
@@ -745,12 +728,12 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
                var selSong = musicPlayer.Playlist.DefaultIfEmpty(null).ElementAtOrDefault(index - 1);
 | 
			
		||||
                if (selSong == null)
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync("Could not select song, likely wrong index");
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("Could not select song, likely wrong index");
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendConfirmAsync($"🎶 Selected song **{selSong.SongInfo.Title}**: <{selSong.SongInfo.Query}>").ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync($"🎶 Selected song **{selSong.SongInfo.Title}**: <{selSong.SongInfo.Query}>").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
@@ -758,7 +741,7 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
                var curSong = musicPlayer.CurrentSong;
 | 
			
		||||
                if (curSong == null)
 | 
			
		||||
                    return;
 | 
			
		||||
                await channel.SendConfirmAsync($"🎶 Current song **{curSong.SongInfo.Title}**: <{curSong.SongInfo.Query}>").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendConfirmAsync($"🎶 Current song **{curSong.SongInfo.Title}**: <{curSong.SongInfo.Query}>").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -766,15 +749,14 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Autoplay()
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            MusicPlayer musicPlayer;
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer))
 | 
			
		||||
            if (!MusicPlayers.TryGetValue(Context.Guild.Id, out musicPlayer))
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            if (!musicPlayer.ToggleAutoplay())
 | 
			
		||||
                await channel.SendConfirmAsync("❌ Autoplay disabled.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendConfirmAsync("❌ Autoplay disabled.").ConfigureAwait(false);
 | 
			
		||||
            else
 | 
			
		||||
                await channel.SendConfirmAsync("✅ Autoplay enabled.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendConfirmAsync("✅ Autoplay enabled.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task QueueSong(IGuildUser queuer, ITextChannel textCh, IVoiceChannel voiceCh, string query, bool silent = false, MusicType musicType = MusicType.Normal)
 | 
			
		||||
@@ -782,7 +764,7 @@ namespace NadekoBot.Modules.Music
 | 
			
		||||
            if (voiceCh == null || voiceCh.Guild != textCh.Guild)
 | 
			
		||||
            {
 | 
			
		||||
                if (!silent)
 | 
			
		||||
                    await textCh.SendErrorAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining.").ConfigureAwait(false);
 | 
			
		||||
                    await textCh.SendErrorAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice (ITextChannel)Context.Channel, try rejoining.").ConfigureAwait(false);
 | 
			
		||||
                throw new ArgumentNullException(nameof(voiceCh));
 | 
			
		||||
            }
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(query) || query.Length < 3)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using Newtonsoft.Json.Linq;
 | 
			
		||||
using System;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 
 | 
			
		||||
@@ -48,13 +48,11 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Verbose(PermissionAction action)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                var config = uow.GuildConfigs.For(channel.Guild.Id, set => set);
 | 
			
		||||
                var config = uow.GuildConfigs.For(Context.Guild.Id, set => set);
 | 
			
		||||
                config.VerbosePermissions = action.Value;
 | 
			
		||||
                Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                {
 | 
			
		||||
                    PermRole = config.PermissionRole,
 | 
			
		||||
                    RootPermission = Permission.GetDefaultRoot(),
 | 
			
		||||
@@ -63,25 +61,24 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await channel.SendConfirmAsync("ℹ️ I will " + (action.Value ? "now" : "no longer") + " show permission warnings.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync("ℹ️ I will " + (action.Value ? "now" : "no longer") + " show permission warnings.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task PermRole([Remainder] IRole role = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                var config = uow.GuildConfigs.For(channel.Guild.Id, set => set);
 | 
			
		||||
                var config = uow.GuildConfigs.For(Context.Guild.Id, set => set);
 | 
			
		||||
                if (role == null)
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendConfirmAsync($"ℹ️ Current permission role is **{config.PermissionRole}**.").ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync($"ℹ️ Current permission role is **{config.PermissionRole}**.").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    config.PermissionRole = role.Name.Trim();
 | 
			
		||||
                    Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                    Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                    {
 | 
			
		||||
                        PermRole = config.PermissionRole,
 | 
			
		||||
                        RootPermission = Permission.GetDefaultRoot(),
 | 
			
		||||
@@ -91,40 +88,37 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await channel.SendConfirmAsync($"Users now require **{role.Name}** role in order to edit permissions.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"Users now require **{role.Name}** role in order to edit permissions.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task ListPerms(int page = 1)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            if (page < 1 || page > 4)
 | 
			
		||||
                return;
 | 
			
		||||
            string toSend = "";
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                var perms = uow.GuildConfigs.PermissionsFor(channel.Guild.Id).RootPermission;
 | 
			
		||||
                var perms = uow.GuildConfigs.PermissionsFor(Context.Guild.Id).RootPermission;
 | 
			
		||||
                var i = 1 + 20 * (page - 1);
 | 
			
		||||
                toSend = Format.Code($"📄 Permissions page {page}") + "\n\n" + String.Join("\n", perms.AsEnumerable().Skip((page - 1) * 20).Take(20).Select(p => $"`{(i++)}.` {(p.Next == null ? Format.Bold(p.GetCommand(channel.Guild) + " [uneditable]") : (p.GetCommand(channel.Guild)))}"));
 | 
			
		||||
                toSend = Format.Code($"📄 Permissions page {page}") + "\n\n" + String.Join("\n", perms.AsEnumerable().Skip((page - 1) * 20).Take(20).Select(p => $"`{(i++)}.` {(p.Next == null ? Format.Bold(p.GetCommand(Context.Guild) + " [uneditable]") : (p.GetCommand(Context.Guild)))}"));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await channel.SendMessageAsync(toSend).ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendMessageAsync(toSend).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task RemovePerm(IUserMessage imsg, int index)
 | 
			
		||||
        public async Task RemovePerm(int index)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            index -= 1;
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                Permission p;
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    var config = uow.GuildConfigs.PermissionsFor(channel.Guild.Id);
 | 
			
		||||
                    var config = uow.GuildConfigs.PermissionsFor(Context.Guild.Id);
 | 
			
		||||
                    var perms = config.RootPermission;
 | 
			
		||||
                    if (index == perms.Count() - 1)
 | 
			
		||||
                    {
 | 
			
		||||
@@ -139,7 +133,7 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    {
 | 
			
		||||
                        p = perms.RemoveAt(index);
 | 
			
		||||
                    }
 | 
			
		||||
                    Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                    Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                    {
 | 
			
		||||
                        PermRole = config.PermissionRole,
 | 
			
		||||
                        RootPermission = config.RootPermission,
 | 
			
		||||
@@ -154,21 +148,20 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    uow2._context.SaveChanges();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                await channel.SendConfirmAsync($"✅ {Context.User.Mention} removed permission **{p.GetCommand(channel.Guild)}** from position #{index + 1}.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendConfirmAsync($"✅ {Context.User.Mention} removed permission **{p.GetCommand(Context.Guild)}** from position #{index + 1}.").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            catch (ArgumentOutOfRangeException)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("❗️`No command on that index found.`").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("❗️`No command on that index found.`").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task MovePerm(IUserMessage imsg, int from, int to)
 | 
			
		||||
        public async Task MovePerm(int from, int to)
 | 
			
		||||
        {
 | 
			
		||||
            from -= 1;
 | 
			
		||||
            to -= 1;
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            if (!(from == to || from < 0 || to < 0))
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
@@ -177,7 +170,7 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    Permission toPerm = null;
 | 
			
		||||
                    using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                    {
 | 
			
		||||
                        var config = uow.GuildConfigs.PermissionsFor(channel.Guild.Id);
 | 
			
		||||
                        var config = uow.GuildConfigs.PermissionsFor(Context.Guild.Id);
 | 
			
		||||
                        var perms = config.RootPermission;
 | 
			
		||||
                        var root = perms;
 | 
			
		||||
                        var index = 0;
 | 
			
		||||
@@ -206,13 +199,13 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                        {
 | 
			
		||||
                            if (!fromFound)
 | 
			
		||||
                            {
 | 
			
		||||
                                await channel.SendErrorAsync($"Can't find permission at index `#{++from}`").ConfigureAwait(false);
 | 
			
		||||
                                await Context.Channel.SendErrorAsync($"Can't find permission at index `#{++from}`").ConfigureAwait(false);
 | 
			
		||||
                                return;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            if (!toFound)
 | 
			
		||||
                            {
 | 
			
		||||
                                await channel.SendErrorAsync($"Can't find permission at index `#{++to}`").ConfigureAwait(false);
 | 
			
		||||
                                await Context.Channel.SendErrorAsync($"Can't find permission at index `#{++to}`").ConfigureAwait(false);
 | 
			
		||||
                                return;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
@@ -254,7 +247,7 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        config.RootPermission = fromPerm.GetRoot();
 | 
			
		||||
                        Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                        Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                        {
 | 
			
		||||
                            PermRole = config.PermissionRole,
 | 
			
		||||
                            RootPermission = config.RootPermission,
 | 
			
		||||
@@ -262,22 +255,20 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                        }, (id, old) => { old.RootPermission = config.RootPermission; return old; });
 | 
			
		||||
                        await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
                    }
 | 
			
		||||
                    await channel.SendConfirmAsync($"`Moved permission:` \"{fromPerm.GetCommand(channel.Guild)}\" `from #{++from} to #{++to}.`").ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync($"`Moved permission:` \"{fromPerm.GetCommand(Context.Guild)}\" `from #{++from} to #{++to}.`").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception e) when (e is ArgumentOutOfRangeException || e is IndexOutOfRangeException)
 | 
			
		||||
                {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendErrorAsync("`Invalid index(es) specified.`").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendErrorAsync("`Invalid index(es) specified.`").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task SrvrCmd(IUserMessage imsg, CommandInfo command, PermissionAction action)
 | 
			
		||||
        public async Task SrvrCmd(CommandInfo command, PermissionAction action)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                var newPerm = new Permission
 | 
			
		||||
@@ -288,8 +279,8 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    SecondaryTargetName = command.Aliases.First().ToLowerInvariant(),
 | 
			
		||||
                    State = action.Value,
 | 
			
		||||
                };
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                {
 | 
			
		||||
                    PermRole = config.PermissionRole,
 | 
			
		||||
                    RootPermission = config.RootPermission,
 | 
			
		||||
@@ -298,15 +289,13 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Aliases.First()}` command on this server.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Aliases.First()}` command on this server.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task SrvrMdl(IUserMessage imsg, ModuleInfo module, PermissionAction action)
 | 
			
		||||
        public async Task SrvrMdl(ModuleInfo module, PermissionAction action)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                var newPerm = new Permission
 | 
			
		||||
@@ -317,8 +306,8 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    SecondaryTargetName = module.Name.ToLowerInvariant(),
 | 
			
		||||
                    State = action.Value,
 | 
			
		||||
                };
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                {
 | 
			
		||||
                    PermRole = config.PermissionRole,
 | 
			
		||||
                    RootPermission = config.RootPermission,
 | 
			
		||||
@@ -326,15 +315,13 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                }, (id, old) => { old.RootPermission = config.RootPermission; return old; });
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of **`{module.Name}`** module on this server.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of **`{module.Name}`** module on this server.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task UsrCmd(IUserMessage imsg, CommandInfo command, PermissionAction action, [Remainder] IGuildUser user)
 | 
			
		||||
        public async Task UsrCmd(CommandInfo command, PermissionAction action, [Remainder] IGuildUser user)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                var newPerm = new Permission
 | 
			
		||||
@@ -345,8 +332,8 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    SecondaryTargetName = command.Aliases.First().ToLowerInvariant(),
 | 
			
		||||
                    State = action.Value,
 | 
			
		||||
                };
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                {
 | 
			
		||||
                    PermRole = config.PermissionRole,
 | 
			
		||||
                    RootPermission = config.RootPermission,
 | 
			
		||||
@@ -354,15 +341,13 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                }, (id, old) => { old.RootPermission = config.RootPermission; return old; });
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Aliases.First()}` command for `{user}` user.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Aliases.First()}` command for `{user}` user.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task UsrMdl(IUserMessage imsg, ModuleInfo module, PermissionAction action, [Remainder] IGuildUser user)
 | 
			
		||||
        public async Task UsrMdl(ModuleInfo module, PermissionAction action, [Remainder] IGuildUser user)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                var newPerm = new Permission
 | 
			
		||||
@@ -373,8 +358,8 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    SecondaryTargetName = module.Name.ToLowerInvariant(),
 | 
			
		||||
                    State = action.Value,
 | 
			
		||||
                };
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                {
 | 
			
		||||
                    PermRole = config.PermissionRole,
 | 
			
		||||
                    RootPermission = config.RootPermission,
 | 
			
		||||
@@ -382,15 +367,13 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                }, (id, old) => { old.RootPermission = config.RootPermission; return old; });
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{module.Name}` module for `{user}` user.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{module.Name}` module for `{user}` user.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task RoleCmd(IUserMessage imsg, CommandInfo command, PermissionAction action, [Remainder] IRole role)
 | 
			
		||||
        public async Task RoleCmd(CommandInfo command, PermissionAction action, [Remainder] IRole role)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                var newPerm = new Permission
 | 
			
		||||
@@ -401,8 +384,8 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    SecondaryTargetName = command.Aliases.First().ToLowerInvariant(),
 | 
			
		||||
                    State = action.Value,
 | 
			
		||||
                };
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                {
 | 
			
		||||
                    PermRole = config.PermissionRole,
 | 
			
		||||
                    RootPermission = config.RootPermission,
 | 
			
		||||
@@ -410,15 +393,13 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                }, (id, old) => { old.RootPermission = config.RootPermission; return old; });
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Aliases.First()}` command for `{role}` role.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Aliases.First()}` command for `{role}` role.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task RoleMdl(IUserMessage imsg, ModuleInfo module, PermissionAction action, [Remainder] IRole role)
 | 
			
		||||
        public async Task RoleMdl(ModuleInfo module, PermissionAction action, [Remainder] IRole role)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                var newPerm = new Permission
 | 
			
		||||
@@ -429,8 +410,8 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    SecondaryTargetName = module.Name.ToLowerInvariant(),
 | 
			
		||||
                    State = action.Value,
 | 
			
		||||
                };
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                {
 | 
			
		||||
                    PermRole = config.PermissionRole,
 | 
			
		||||
                    RootPermission = config.RootPermission,
 | 
			
		||||
@@ -438,14 +419,13 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                }, (id, old) => { old.RootPermission = config.RootPermission; return old; });
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{module.Name}` module for `{role}` role.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{module.Name}` module for `{role}` role.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task ChnlCmd(IUserMessage imsg, CommandInfo command, PermissionAction action, [Remainder] ITextChannel chnl)
 | 
			
		||||
        public async Task ChnlCmd(CommandInfo command, PermissionAction action, [Remainder] ITextChannel chnl)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
@@ -458,8 +438,8 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                        SecondaryTargetName = command.Aliases.First().ToLowerInvariant(),
 | 
			
		||||
                        State = action.Value,
 | 
			
		||||
                    };
 | 
			
		||||
                    var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm);
 | 
			
		||||
                    Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                    var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm);
 | 
			
		||||
                    Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                    {
 | 
			
		||||
                        PermRole = config.PermissionRole,
 | 
			
		||||
                        RootPermission = config.RootPermission,
 | 
			
		||||
@@ -471,15 +451,13 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
            catch (Exception ex) {
 | 
			
		||||
                _log.Error(ex);
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Aliases.First()}` command for `{chnl}` channel.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Aliases.First()}` command for `{chnl}` channel.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task ChnlMdl(IUserMessage imsg, ModuleInfo module, PermissionAction action, [Remainder] ITextChannel chnl)
 | 
			
		||||
        public async Task ChnlMdl(ModuleInfo module, PermissionAction action, [Remainder] ITextChannel chnl)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                var newPerm = new Permission
 | 
			
		||||
@@ -490,8 +468,8 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    SecondaryTargetName = module.Name.ToLowerInvariant(),
 | 
			
		||||
                    State = action.Value,
 | 
			
		||||
                };
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                {
 | 
			
		||||
                    PermRole = config.PermissionRole,
 | 
			
		||||
                    RootPermission = config.RootPermission,
 | 
			
		||||
@@ -499,15 +477,13 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                }, (id, old) => { old.RootPermission = config.RootPermission; return old; });
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{module.Name}` module for `{chnl}` channel.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{module.Name}` module for `{chnl}` channel.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task AllChnlMdls(IUserMessage imsg, PermissionAction action, [Remainder] ITextChannel chnl)
 | 
			
		||||
        public async Task AllChnlMdls(PermissionAction action, [Remainder] ITextChannel chnl)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                var newPerm = new Permission
 | 
			
		||||
@@ -518,8 +494,8 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    SecondaryTargetName = "*",
 | 
			
		||||
                    State = action.Value,
 | 
			
		||||
                };
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                {
 | 
			
		||||
                    PermRole = config.PermissionRole,
 | 
			
		||||
                    RootPermission = config.RootPermission,
 | 
			
		||||
@@ -527,15 +503,13 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                }, (id, old) => { old.RootPermission = config.RootPermission; return old; });
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` for `{chnl}` channel.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` for `{chnl}` channel.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task AllRoleMdls(IUserMessage imsg, PermissionAction action, [Remainder] IRole role)
 | 
			
		||||
        public async Task AllRoleMdls(PermissionAction action, [Remainder] IRole role)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                var newPerm = new Permission
 | 
			
		||||
@@ -546,8 +520,8 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    SecondaryTargetName = "*",
 | 
			
		||||
                    State = action.Value,
 | 
			
		||||
                };
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                {
 | 
			
		||||
                    PermRole = config.PermissionRole,
 | 
			
		||||
                    RootPermission = config.RootPermission,
 | 
			
		||||
@@ -555,15 +529,13 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                }, (id, old) => { old.RootPermission = config.RootPermission; return old; });
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` for `{role}` role.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` for `{role}` role.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task AllUsrMdls(IUserMessage imsg, PermissionAction action, [Remainder] IUser user)
 | 
			
		||||
        public async Task AllUsrMdls(PermissionAction action, [Remainder] IUser user)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                var newPerm = new Permission
 | 
			
		||||
@@ -574,8 +546,8 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    SecondaryTargetName = "*",
 | 
			
		||||
                    State = action.Value,
 | 
			
		||||
                };
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm);
 | 
			
		||||
                Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                {
 | 
			
		||||
                    PermRole = config.PermissionRole,
 | 
			
		||||
                    RootPermission = config.RootPermission,
 | 
			
		||||
@@ -583,15 +555,13 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                }, (id, old) => { old.RootPermission = config.RootPermission; return old; });
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` for `{user}` user.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` for `{user}` user.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task AllSrvrMdls(IUserMessage imsg, PermissionAction action)
 | 
			
		||||
        public async Task AllSrvrMdls(PermissionAction action)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                var newPerm = new Permission
 | 
			
		||||
@@ -602,7 +572,7 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    SecondaryTargetName = "*",
 | 
			
		||||
                    State = action.Value,
 | 
			
		||||
                };
 | 
			
		||||
                uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm);
 | 
			
		||||
                uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, newPerm);
 | 
			
		||||
 | 
			
		||||
                var allowUser = new Permission
 | 
			
		||||
                {
 | 
			
		||||
@@ -613,8 +583,8 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    State = true,
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, allowUser);
 | 
			
		||||
                Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache()
 | 
			
		||||
                var config = uow.GuildConfigs.SetNewRootPermission(Context.Guild.Id, allowUser);
 | 
			
		||||
                Cache.AddOrUpdate(Context.Guild.Id, new PermissionCache()
 | 
			
		||||
                {
 | 
			
		||||
                    PermRole = config.PermissionRole,
 | 
			
		||||
                    RootPermission = config.RootPermission,
 | 
			
		||||
@@ -622,7 +592,7 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                }, (id, old) => { old.RootPermission = config.RootPermission; return old; });
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` on this server.").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `ALL MODULES` on this server.").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -96,9 +96,8 @@ namespace NadekoBot.Modules.Pokemon
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Attack(IUserMessage umsg, string move, IGuildUser targetUser = null)
 | 
			
		||||
        public async Task Attack(string move, IGuildUser targetUser = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            IGuildUser user = (IGuildUser)Context.User;
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(move)) {
 | 
			
		||||
@@ -107,12 +106,12 @@ namespace NadekoBot.Modules.Pokemon
 | 
			
		||||
 | 
			
		||||
            if (targetUser == null)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendMessageAsync("No such person.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendMessageAsync("No such person.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            else if (targetUser == user)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendMessageAsync("You can't attack yourself.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendMessageAsync("You can't attack yourself.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -126,17 +125,17 @@ namespace NadekoBot.Modules.Pokemon
 | 
			
		||||
            //User not able if HP < 0, has made more than 4 attacks
 | 
			
		||||
            if (userStats.Hp < 0)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendMessageAsync($"{user.Mention} has fainted and was not able to move!").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendMessageAsync($"{user.Mention} has fainted and was not able to move!").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (userStats.MovesMade >= 5)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendMessageAsync($"{user.Mention} has used too many moves in a row and was not able to move!").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendMessageAsync($"{user.Mention} has used too many moves in a row and was not able to move!").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (userStats.LastAttacked.Contains(targetUser.Id))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendMessageAsync($"{user.Mention} can't attack again without retaliation!").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendMessageAsync($"{user.Mention} can't attack again without retaliation!").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            //get target stats
 | 
			
		||||
@@ -146,7 +145,7 @@ namespace NadekoBot.Modules.Pokemon
 | 
			
		||||
            //If target's HP is below 0, no use attacking
 | 
			
		||||
            if (targetStats.Hp <= 0)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendMessageAsync($"{targetUser.Mention} has already fainted!").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendMessageAsync($"{targetUser.Mention} has already fainted!").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -156,7 +155,7 @@ namespace NadekoBot.Modules.Pokemon
 | 
			
		||||
            var enabledMoves = userType.Moves;
 | 
			
		||||
            if (!enabledMoves.Contains(move.ToLowerInvariant()))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendMessageAsync($"{user.Mention} is not able to use **{move}**. Type {NadekoBot.ModulePrefixes[typeof(Pokemon).Name]}ml to see moves").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendMessageAsync($"{user.Mention} is not able to use **{move}**. Type {NadekoBot.ModulePrefixes[typeof(Pokemon).Name]}ml to see moves").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -208,7 +207,7 @@ namespace NadekoBot.Modules.Pokemon
 | 
			
		||||
            Stats[user.Id] = userStats;
 | 
			
		||||
            Stats[targetUser.Id] = targetStats;
 | 
			
		||||
 | 
			
		||||
            await channel.SendMessageAsync(response).ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendMessageAsync(response).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -216,7 +215,6 @@ namespace NadekoBot.Modules.Pokemon
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Movelist()
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            IGuildUser user = (IGuildUser)Context.User;
 | 
			
		||||
 | 
			
		||||
            var userType = GetPokeType(user.Id);
 | 
			
		||||
@@ -226,18 +224,17 @@ namespace NadekoBot.Modules.Pokemon
 | 
			
		||||
            {
 | 
			
		||||
                str += $"\n{userType.Icon}{m}";
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendMessageAsync(str).ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendMessageAsync(str).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Heal(IUserMessage umsg, IGuildUser targetUser = null)
 | 
			
		||||
        public async Task Heal(IGuildUser targetUser = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            IGuildUser user = (IGuildUser)Context.User;
 | 
			
		||||
 | 
			
		||||
            if (targetUser == null) {
 | 
			
		||||
                await channel.SendMessageAsync("No such person.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendMessageAsync("No such person.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -246,7 +243,7 @@ namespace NadekoBot.Modules.Pokemon
 | 
			
		||||
                var targetStats = Stats[targetUser.Id];
 | 
			
		||||
                if (targetStats.Hp == targetStats.MaxHp)
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendMessageAsync($"{targetUser.Mention} already has full HP!").ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendMessageAsync($"{targetUser.Mention} already has full HP!").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                //Payment~
 | 
			
		||||
@@ -257,7 +254,7 @@ namespace NadekoBot.Modules.Pokemon
 | 
			
		||||
                {
 | 
			
		||||
                        if (!await CurrencyHandler.RemoveCurrencyAsync(user, $"Poke-Heal {target}", amount, true).ConfigureAwait(false))
 | 
			
		||||
                        {
 | 
			
		||||
                            try { await channel.SendMessageAsync($"{user.Mention} You don't have enough {CurrencyName}s.").ConfigureAwait(false); } catch { }
 | 
			
		||||
                            try { await Context.Channel.SendMessageAsync($"{user.Mention} You don't have enough {CurrencyName}s.").ConfigureAwait(false); } catch { }
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                }
 | 
			
		||||
@@ -270,29 +267,28 @@ namespace NadekoBot.Modules.Pokemon
 | 
			
		||||
                    Stats[targetUser.Id].Hp = (targetStats.MaxHp / 2);
 | 
			
		||||
                    if (target == "yourself")
 | 
			
		||||
                    {
 | 
			
		||||
                        await channel.SendMessageAsync($"You revived yourself with one {CurrencySign}").ConfigureAwait(false);
 | 
			
		||||
                        await Context.Channel.SendMessageAsync($"You revived yourself with one {CurrencySign}").ConfigureAwait(false);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        await channel.SendMessageAsync($"{user.Mention} revived {targetUser.Mention} with one {CurrencySign}").ConfigureAwait(false);
 | 
			
		||||
                        await Context.Channel.SendMessageAsync($"{user.Mention} revived {targetUser.Mention} with one {CurrencySign}").ConfigureAwait(false);
 | 
			
		||||
                    }
 | 
			
		||||
                   return;
 | 
			
		||||
                }
 | 
			
		||||
                await channel.SendMessageAsync($"{user.Mention} healed {targetUser.Mention} with one {CurrencySign}").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendMessageAsync($"{user.Mention} healed {targetUser.Mention} with one {CurrencySign}").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendMessageAsync($"{targetUser.Mention} already has full HP!").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendMessageAsync($"{targetUser.Mention} already has full HP!").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Type(IUserMessage umsg, IGuildUser targetUser = null)
 | 
			
		||||
        public async Task Type(IGuildUser targetUser = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            IGuildUser user = (IGuildUser)Context.User;
 | 
			
		||||
 | 
			
		||||
            if (targetUser == null)
 | 
			
		||||
@@ -301,26 +297,29 @@ namespace NadekoBot.Modules.Pokemon
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var pType = GetPokeType(targetUser.Id);
 | 
			
		||||
            await channel.SendMessageAsync($"Type of {targetUser.Mention} is **{pType.Name.ToLowerInvariant()}**{pType.Icon}").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendMessageAsync($"Type of {targetUser.Mention} is **{pType.Name.ToLowerInvariant()}**{pType.Icon}").ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Settype(IUserMessage umsg, [Remainder] string typeTargeted = null)
 | 
			
		||||
        public async Task Settype([Remainder] string typeTargeted = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            IGuildUser user = (IGuildUser)Context.User;
 | 
			
		||||
 | 
			
		||||
            var targetType = StringToPokemonType(typeTargeted);
 | 
			
		||||
            if (targetType == null)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.EmbedAsync(PokemonTypes.Aggregate(new EmbedBuilder().WithDescription("List of the available types:"), (eb, pt) => eb.AddField(efb => efb.WithName(pt.Name).WithValue(pt.Icon).WithIsInline(true))).WithColor(NadekoBot.OkColor)).ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.EmbedAsync(PokemonTypes.Aggregate(new EmbedBuilder().WithDescription("List of the available types:"), 
 | 
			
		||||
                        (eb, pt) => eb.AddField(efb => efb.WithName(pt.Name)
 | 
			
		||||
                                                          .WithValue(pt.Icon)
 | 
			
		||||
                                                          .WithIsInline(true)))
 | 
			
		||||
                            .WithColor(NadekoBot.OkColor)).ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (targetType == GetPokeType(user.Id))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendMessageAsync($"Your type is already {targetType.Name.ToLowerInvariant()}{targetType.Icon}").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendMessageAsync($"Your type is already {targetType.Name.ToLowerInvariant()}{targetType.Icon}").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -330,7 +329,7 @@ namespace NadekoBot.Modules.Pokemon
 | 
			
		||||
            {
 | 
			
		||||
                if (!await CurrencyHandler.RemoveCurrencyAsync(user, $"{user.Mention} change type to {typeTargeted}", amount, true).ConfigureAwait(false))
 | 
			
		||||
                {
 | 
			
		||||
                    try { await channel.SendMessageAsync($"{user.Mention} You don't have enough {CurrencyName}s.").ConfigureAwait(false); } catch { }
 | 
			
		||||
                    try { await Context.Channel.SendMessageAsync($"{user.Mention} You don't have enough {CurrencyName}s.").ConfigureAwait(false); } catch { }
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -363,7 +362,7 @@ namespace NadekoBot.Modules.Pokemon
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //Now for the response
 | 
			
		||||
            await channel.SendMessageAsync($"Set type of {user.Mention} to {typeTargeted}{targetType.Icon} for a {CurrencySign}").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendMessageAsync($"Set type of {user.Mention} to {typeTargeted}{targetType.Icon} for a {CurrencySign}").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,4 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Pokemon
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.API;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Modules.Searches.Models;
 | 
			
		||||
@@ -43,7 +42,6 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task Yomama()
 | 
			
		||||
            {
 | 
			
		||||
                using (var http = new HttpClient())
 | 
			
		||||
@@ -54,7 +52,6 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task Randjoke()
 | 
			
		||||
            {
 | 
			
		||||
                using (var http = new HttpClient())
 | 
			
		||||
@@ -65,7 +62,6 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task ChuckNorris()
 | 
			
		||||
            {
 | 
			
		||||
                using (var http = new HttpClient())
 | 
			
		||||
@@ -76,7 +72,6 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task WowJoke()
 | 
			
		||||
            {
 | 
			
		||||
                if (!wowJokes.Any())
 | 
			
		||||
@@ -89,7 +84,6 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task MagicItem()
 | 
			
		||||
            {
 | 
			
		||||
                if (!wowJokes.Any())
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
@@ -8,7 +7,6 @@ using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
//todo drawing
 | 
			
		||||
@@ -33,7 +31,6 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Lolban()
 | 
			
		||||
        {
 | 
			
		||||
            var showCount = 8;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,8 @@
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Discord;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
@@ -15,7 +13,6 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
    public partial class Searches
 | 
			
		||||
    {
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Memelist()
 | 
			
		||||
        {
 | 
			
		||||
            HttpClientHandler handler = new HttpClientHandler();
 | 
			
		||||
@@ -33,8 +30,7 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Memegen(IUserMessage umsg, string meme, string topText, string botText)
 | 
			
		||||
        public async Task Memegen(string meme, string topText, string botText)
 | 
			
		||||
        {
 | 
			
		||||
            var top = Uri.EscapeDataString(topText.Replace(' ', '-'));
 | 
			
		||||
            var bot = Uri.EscapeDataString(botText.Replace(' ', '-'));
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using System.Globalization;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Searches.Models
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Searches.Models
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.API;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
 
 | 
			
		||||
@@ -58,13 +58,11 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task Osub(IUserMessage umsg, [Remainder] string map)
 | 
			
		||||
            public async Task Osub([Remainder] string map)
 | 
			
		||||
            {
 | 
			
		||||
                var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey))
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync("An osu! API key is required.").ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("An osu! API key is required.").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@@ -83,19 +81,18 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                        var time = TimeSpan.FromSeconds(Double.Parse($"{obj["total_length"]}")).ToString(@"mm\:ss");
 | 
			
		||||
                        sb.AppendLine($"{obj["artist"]} - {obj["title"]}, mapped by {obj["creator"]}. https://osu.ppy.sh/s/{obj["beatmapset_id"]}");
 | 
			
		||||
                        sb.AppendLine($"{starRating} stars, {obj["bpm"]} BPM | AR{obj["diff_approach"]}, CS{obj["diff_size"]}, OD{obj["diff_overall"]} | Length: {time}");
 | 
			
		||||
                        await channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false);
 | 
			
		||||
                        await Context.Channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception ex)
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync("Something went wrong.");
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("Something went wrong.");
 | 
			
		||||
                    _log.Warn(ex, "Osub command failed");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task Osu5(IUserMessage umsg, string user, [Remainder] string mode = null)
 | 
			
		||||
            public async Task Osu5(string user, [Remainder] string mode = null)
 | 
			
		||||
            {
 | 
			
		||||
                var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
                if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey))
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,6 @@ using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Modules.Searches.Models;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using NLog;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
@@ -18,18 +15,12 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class OverwatchCommands : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            private Logger _log;
 | 
			
		||||
            public OverwatchCommands()
 | 
			
		||||
            {
 | 
			
		||||
                _log = LogManager.GetCurrentClassLogger();
 | 
			
		||||
            }
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task Overwatch(IUserMessage umsg, string region, [Remainder] string query = null)
 | 
			
		||||
            public async Task Overwatch(string region, [Remainder] string query = null)
 | 
			
		||||
            {
 | 
			
		||||
                if (string.IsNullOrWhiteSpace(query))
 | 
			
		||||
                    return;
 | 
			
		||||
                var battletag = Regex.Replace(query, "#", "-", RegexOptions.IgnoreCase);
 | 
			
		||||
                var battletag = query.Replace("#", "-");
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    var model = await GetProfile(region, battletag);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
@@ -32,7 +31,6 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task Placelist()
 | 
			
		||||
            {
 | 
			
		||||
                await Context.Channel.SendConfirmAsync(typesStr)
 | 
			
		||||
@@ -40,8 +38,7 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task Place(IUserMessage imsg, PlaceType placeType, uint width = 0, uint height = 0)
 | 
			
		||||
            public async Task Place(PlaceType placeType, uint width = 0, uint height = 0)
 | 
			
		||||
            {
 | 
			
		||||
                string url = "";
 | 
			
		||||
                switch (placeType)
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,6 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task Pokemon([Remainder] string pokemon = null)
 | 
			
		||||
            {
 | 
			
		||||
                pokemon = pokemon?.Trim().ToUpperInvariant();
 | 
			
		||||
@@ -67,7 +66,6 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task PokemonAbility([Remainder] string ability = null)
 | 
			
		||||
            {
 | 
			
		||||
                ability = ability?.Trim().ToUpperInvariant().Replace(" ", "");
 | 
			
		||||
 
 | 
			
		||||
@@ -1,22 +1,18 @@
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord;
 | 
			
		||||
using Newtonsoft.Json.Linq;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Discord;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using NLog;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Searches
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,7 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            var text = await TranslateInternal(umsg, langs, umsg.Resolve(userHandling: TagHandling.Ignore), true)
 | 
			
		||||
                            var text = await TranslateInternal(langs, umsg.Resolve(userHandling: TagHandling.Ignore), true)
 | 
			
		||||
                                                .ConfigureAwait(false);
 | 
			
		||||
                            if (autoDelete)
 | 
			
		||||
                                try { await umsg.DeleteAsync().ConfigureAwait(false); } catch { }
 | 
			
		||||
@@ -67,24 +67,21 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task Translate(IUserMessage umsg, string langs, [Remainder] string text = null)
 | 
			
		||||
            {
 | 
			
		||||
                var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
 | 
			
		||||
                    var translation = await TranslateInternal(umsg, langs, text);
 | 
			
		||||
                    await channel.SendConfirmAsync("Translation " + langs, translation).ConfigureAwait(false);
 | 
			
		||||
                    var translation = await TranslateInternal(langs, text);
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync("Translation " + langs, translation).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                catch
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync("Bad input format, or something went wrong...").ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("Bad input format, or something went wrong...").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            private static async Task<string> TranslateInternal(IUserMessage umsg, string langs, [Remainder] string text = null, bool silent = false)
 | 
			
		||||
            private static async Task<string> TranslateInternal(string langs, [Remainder] string text = null, bool silent = false)
 | 
			
		||||
            {
 | 
			
		||||
                var langarr = langs.ToLowerInvariant().Split('>');
 | 
			
		||||
                if (langarr.Length != 2)
 | 
			
		||||
 
 | 
			
		||||
@@ -25,9 +25,8 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
    {
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Weather(IUserMessage umsg, string city, string country)
 | 
			
		||||
        public async Task Weather(string city, string country)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            city = city.Replace(" ", "");
 | 
			
		||||
            country = city.Replace(" ", "");
 | 
			
		||||
            string response;
 | 
			
		||||
@@ -47,75 +46,63 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                .AddField(fb => fb.WithName("🌄 **Sunrise**").WithValue($"{obj["sunrise"]}").WithIsInline(true))
 | 
			
		||||
                .AddField(fb => fb.WithName("🌇 **Sunset**").WithValue($"{obj["sunset"]}").WithIsInline(true))
 | 
			
		||||
                .WithColor(NadekoBot.OkColor);
 | 
			
		||||
            await channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Youtube(IUserMessage umsg, [Remainder] string query = null)
 | 
			
		||||
        public async Task Youtube([Remainder] string query = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            if (!(await ValidateQuery(channel, query).ConfigureAwait(false))) return;
 | 
			
		||||
            if (!(await ValidateQuery(Context.Channel, query).ConfigureAwait(false))) return;
 | 
			
		||||
            var result = (await NadekoBot.Google.GetVideosByKeywordsAsync(query, 1)).FirstOrDefault();
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(result))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("No results found for that query.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("No results found for that query.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await channel.SendMessageAsync(result).ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendMessageAsync(result).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
            //await channel.EmbedAsync(new Discord.API.Embed() { Video = new Discord.API.EmbedVideo() { Url = result.Replace("watch?v=", "embed/") }, Color = NadekoBot.OkColor }).ConfigureAwait(false);
 | 
			
		||||
            //await Context.Channel.EmbedAsync(new Discord.API.Embed() { Video = new Discord.API.EmbedVideo() { Url = result.Replace("watch?v=", "embed/") }, Color = NadekoBot.OkColor }).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Imdb(IUserMessage umsg, [Remainder] string query = null)
 | 
			
		||||
        public async Task Imdb([Remainder] string query = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            if (!(await ValidateQuery(channel, query).ConfigureAwait(false))) return;
 | 
			
		||||
            if (!(await ValidateQuery(Context.Channel, query).ConfigureAwait(false))) return;
 | 
			
		||||
            await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
            var movie = await OmdbProvider.FindMovie(query);
 | 
			
		||||
            if (movie == null)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Failed to find that movie.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Failed to find that movie.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            await channel.EmbedAsync(movie.GetEmbed()).ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.EmbedAsync(movie.GetEmbed()).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task RandomCat()
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            using (var http = new HttpClient())
 | 
			
		||||
            {
 | 
			
		||||
                var res = JObject.Parse(await http.GetStringAsync("http://www.random.cat/meow").ConfigureAwait(false));
 | 
			
		||||
                await channel.SendMessageAsync(res["file"].ToString()).ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendMessageAsync(res["file"].ToString()).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task RandomDog()
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            using (var http = new HttpClient())
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendMessageAsync("http://random.dog/" + await http.GetStringAsync("http://random.dog/woof")
 | 
			
		||||
                await Context.Channel.SendMessageAsync("http://random.dog/" + await http.GetStringAsync("http://random.dog/woof")
 | 
			
		||||
                             .ConfigureAwait(false)).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task I(IUserMessage umsg, [Remainder] string query = null)
 | 
			
		||||
        public async Task I([Remainder] string query = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(query))
 | 
			
		||||
                return;
 | 
			
		||||
            try
 | 
			
		||||
@@ -124,29 +111,26 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                {
 | 
			
		||||
                    var reqString = $"https://www.googleapis.com/customsearch/v1?q={Uri.EscapeDataString(query)}&cx=018084019232060951019%3Ahs5piey28-e&num=1&searchType=image&fields=items%2Flink&key={NadekoBot.Credentials.GoogleApiKey}";
 | 
			
		||||
                    var obj = JObject.Parse(await http.GetStringAsync(reqString).ConfigureAwait(false));
 | 
			
		||||
                    await channel.SendMessageAsync(obj["items"][0]["link"].ToString()).ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendMessageAsync(obj["items"][0]["link"].ToString()).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (HttpRequestException exception)
 | 
			
		||||
            {
 | 
			
		||||
                if (exception.Message.Contains("403 (Forbidden)"))
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync("Daily limit reached!");
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("Daily limit reached!");
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync("Something went wrong.");
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("Something went wrong.");
 | 
			
		||||
                    _log.Error(exception);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Ir(IUserMessage umsg, [Remainder] string query = null)
 | 
			
		||||
        public async Task Ir([Remainder] string query = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(query))
 | 
			
		||||
                return;
 | 
			
		||||
            try
 | 
			
		||||
@@ -157,39 +141,34 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                    var reqString = $"https://www.googleapis.com/customsearch/v1?q={Uri.EscapeDataString(query)}&cx=018084019232060951019%3Ahs5piey28-e&num=1&searchType=image&start={ rng.Next(1, 50) }&fields=items%2Flink&key={NadekoBot.Credentials.GoogleApiKey}";
 | 
			
		||||
                    var obj = JObject.Parse(await http.GetStringAsync(reqString).ConfigureAwait(false));
 | 
			
		||||
                    var items = obj["items"] as JArray;
 | 
			
		||||
                    await channel.SendMessageAsync(items[0]["link"].ToString()).ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendMessageAsync(items[0]["link"].ToString()).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (HttpRequestException exception)
 | 
			
		||||
            {
 | 
			
		||||
                if (exception.Message.Contains("403 (Forbidden)"))
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync("Daily limit reached!");
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("Daily limit reached!");
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync("Something went wrong.");
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("Something went wrong.");
 | 
			
		||||
                    _log.Error(exception);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Lmgtfy(IUserMessage umsg, [Remainder] string ffs = null)
 | 
			
		||||
        public async Task Lmgtfy([Remainder] string ffs = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(ffs))
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            await channel.SendConfirmAsync(await NadekoBot.Google.ShortenUrl($"<http://lmgtfy.com/?q={ Uri.EscapeUriString(ffs) }>"))
 | 
			
		||||
            await Context.Channel.SendConfirmAsync(await NadekoBot.Google.ShortenUrl($"<http://lmgtfy.com/?q={ Uri.EscapeUriString(ffs) }>"))
 | 
			
		||||
                           .ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Shorten([Remainder] string arg)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(arg))
 | 
			
		||||
@@ -211,28 +190,23 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Google(IUserMessage umsg, [Remainder] string terms = null)
 | 
			
		||||
        public async Task Google([Remainder] string terms = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            
 | 
			
		||||
            terms = terms?.Trim();
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(terms))
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            await channel.SendConfirmAsync($"https://google.com/search?q={ WebUtility.UrlEncode(terms).Replace(' ', '+') }")
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"https://google.com/search?q={ WebUtility.UrlEncode(terms).Replace(' ', '+') }")
 | 
			
		||||
                           .ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task MagicTheGathering(IUserMessage umsg, [Remainder] string name = null)
 | 
			
		||||
        public async Task MagicTheGathering([Remainder] string name = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            var arg = name;
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(arg))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Please enter a card name to search for.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Please enter a card name to search for.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -263,30 +237,28 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                                    .AddField(efb => efb.WithName("Types").WithValue(types).WithIsInline(true));
 | 
			
		||||
                                    //.AddField(efb => efb.WithName("Store Url").WithValue(await NadekoBot.Google.ShortenUrl(items[0]["store_url"].ToString())).WithIsInline(true));
 | 
			
		||||
 | 
			
		||||
                    await channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                catch
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync($"Error could not find the card '{arg}'.").ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendErrorAsync($"Error could not find the card '{arg}'.").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Hearthstone(IUserMessage umsg, [Remainder] string name = null)
 | 
			
		||||
        public async Task Hearthstone([Remainder] string name = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            var arg = name;
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(arg))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Please enter a card name to search for.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Please enter a card name to search for.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -301,7 +273,7 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    var items = JArray.Parse(response).Shuffle().ToList();
 | 
			
		||||
                    var images = new List<Image>();
 | 
			
		||||
                    var images = new List<ImageSharp.Image>();
 | 
			
		||||
                    if (items == null)
 | 
			
		||||
                        throw new KeyNotFoundException("Cannot find a card by that name");
 | 
			
		||||
                    foreach (var item in items.Where(item => item.HasValues && item["img"] != null).Take(4))
 | 
			
		||||
@@ -311,7 +283,7 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                            var imgStream = new MemoryStream();
 | 
			
		||||
                            await sr.CopyToAsync(imgStream);
 | 
			
		||||
                            imgStream.Position = 0;
 | 
			
		||||
                            images.Add(new Image(imgStream));
 | 
			
		||||
                            images.Add(new ImageSharp.Image(imgStream));
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    string msg = null;
 | 
			
		||||
@@ -322,32 +294,29 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                    var ms = new MemoryStream();
 | 
			
		||||
                    images.AsEnumerable().Merge().SaveAsPng(ms);
 | 
			
		||||
                    ms.Position = 0;
 | 
			
		||||
                    await channel.SendFileAsync(ms, arg + ".png", msg).ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendFileAsync(ms, arg + ".png", msg).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception ex)
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync($"Error occured.").ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendErrorAsync($"Error occured.").ConfigureAwait(false);
 | 
			
		||||
                    _log.Error(ex);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Yodify(IUserMessage umsg, [Remainder] string query = null)
 | 
			
		||||
        public async Task Yodify([Remainder] string query = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var arg = query;
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(arg))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Please enter a sentence.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Please enter a sentence.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
 | 
			
		||||
@@ -364,31 +333,30 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                        .WithAuthor(au => au.WithName("Yoda").WithIconUrl("http://www.yodaspeak.co.uk/yoda-small1.gif"))
 | 
			
		||||
                        .WithDescription(res)
 | 
			
		||||
                        .WithColor(NadekoBot.OkColor);
 | 
			
		||||
                    await channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                catch
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync("Failed to yodify your sentence.").ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("Failed to yodify your sentence.").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task UrbanDict(IUserMessage umsg, [Remainder] string query = null)
 | 
			
		||||
        public async Task UrbanDict([Remainder] string query = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var arg = query;
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(arg))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Please enter a search term.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Please enter a search term.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
 | 
			
		||||
@@ -408,30 +376,27 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                                     .WithUrl(link)
 | 
			
		||||
                                     .WithAuthor(eab => eab.WithIconUrl("http://i.imgur.com/nwERwQE.jpg").WithName(word))
 | 
			
		||||
                                     .WithDescription(def);
 | 
			
		||||
                    await channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                catch
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync("Failed finding a definition for that term.").ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("Failed finding a definition for that term.").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Hashtag(IUserMessage umsg, [Remainder] string query = null)
 | 
			
		||||
        public async Task Hashtag([Remainder] string query = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            var arg = query;
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(arg))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Please enter a search term.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Please enter a search term.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.MashapeKey))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Bot owner didn't specify MashapeApiKey. You can't use this functionality.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -451,7 +416,7 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                var hashtag = item["hashtag"].ToString();
 | 
			
		||||
                var link = item["uri"].ToString();
 | 
			
		||||
                var desc = item["text"].ToString();
 | 
			
		||||
                await channel.EmbedAsync(new EmbedBuilder().WithColor(NadekoBot.OkColor)
 | 
			
		||||
                await Context.Channel.EmbedAsync(new EmbedBuilder().WithColor(NadekoBot.OkColor)
 | 
			
		||||
                                                                 .WithAuthor(eab => eab.WithUrl(link)
 | 
			
		||||
                                                                                       .WithIconUrl("http://res.cloudinary.com/urbandictionary/image/upload/a_exif,c_fit,h_200,w_200/v1394975045/b8oszuu3tbq7ebyo7vo1.jpg")
 | 
			
		||||
                                                                                       .WithName(query))
 | 
			
		||||
@@ -459,15 +424,13 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
            }
 | 
			
		||||
            catch
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Failed finding a definition for that tag.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Failed finding a definition for that tag.").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Catfact()
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            using (var http = new HttpClient())
 | 
			
		||||
            {
 | 
			
		||||
                var response = await http.GetStringAsync("http://catfacts-api.appspot.com/api/facts").ConfigureAwait(false);
 | 
			
		||||
@@ -475,53 +438,42 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                var fact = JObject.Parse(response)["facts"][0].ToString();
 | 
			
		||||
                await channel.SendConfirmAsync("🐈fact", fact).ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendConfirmAsync("🐈fact", fact).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Revav(IUserMessage umsg, [Remainder] IUser usr = null)
 | 
			
		||||
        public async Task Revav([Remainder] IUser usr = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            if (usr == null)
 | 
			
		||||
                usr = Context.User;
 | 
			
		||||
            await channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={usr.AvatarUrl}").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={usr.AvatarUrl}").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Revimg(IUserMessage umsg, [Remainder] string imageLink = null)
 | 
			
		||||
        public async Task Revimg([Remainder] string imageLink = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            imageLink = imageLink?.Trim() ?? "";
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(imageLink))
 | 
			
		||||
                return;
 | 
			
		||||
            await channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={imageLink}").ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendConfirmAsync($"https://images.google.com/searchbyimage?image_url={imageLink}").ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Safebooru(IUserMessage umsg, [Remainder] string tag = null)
 | 
			
		||||
        public async Task Safebooru([Remainder] string tag = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            tag = tag?.Trim() ?? "";
 | 
			
		||||
            var link = await GetSafebooruImageLink(tag).ConfigureAwait(false);
 | 
			
		||||
            if (link == null)
 | 
			
		||||
                await channel.SendErrorAsync("No results.");
 | 
			
		||||
                await Context.Channel.SendErrorAsync("No results.");
 | 
			
		||||
            else
 | 
			
		||||
                await channel.SendMessageAsync(link).ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendMessageAsync(link).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Wiki(IUserMessage umsg, [Remainder] string query = null)
 | 
			
		||||
        public async Task Wiki([Remainder] string query = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            query = query?.Trim();
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(query))
 | 
			
		||||
                return;
 | 
			
		||||
@@ -530,22 +482,19 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                var result = await http.GetStringAsync("https://en.wikipedia.org//w/api.php?action=query&format=json&prop=info&redirects=1&formatversion=2&inprop=url&titles=" + Uri.EscapeDataString(query));
 | 
			
		||||
                var data = JsonConvert.DeserializeObject<WikipediaApiModel>(result);
 | 
			
		||||
                if (data.Query.Pages[0].Missing)
 | 
			
		||||
                    await channel.SendErrorAsync("That page could not be found.");
 | 
			
		||||
                    await Context.Channel.SendErrorAsync("That page could not be found.");
 | 
			
		||||
                else
 | 
			
		||||
                    await channel.SendMessageAsync(data.Query.Pages[0].FullUrl);
 | 
			
		||||
                    await Context.Channel.SendMessageAsync(data.Query.Pages[0].FullUrl);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Color(IUserMessage umsg, [Remainder] string color = null)
 | 
			
		||||
        public async Task Color([Remainder] string color = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            color = color?.Trim().Replace("#", "");
 | 
			
		||||
            if (string.IsNullOrWhiteSpace((string)color))
 | 
			
		||||
                return;
 | 
			
		||||
            var img = new Image(50, 50);
 | 
			
		||||
            var img = new ImageSharp.Image(50, 50);
 | 
			
		||||
 | 
			
		||||
            var red = Convert.ToInt32(color.Substring(0, 2), 16);
 | 
			
		||||
            var green = Convert.ToInt32(color.Substring(2, 2), 16);
 | 
			
		||||
@@ -553,18 +502,15 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
 | 
			
		||||
            img.BackgroundColor(new ImageSharp.Color(color));
 | 
			
		||||
 | 
			
		||||
            await channel.SendFileAsync(img.ToStream(), $"{color}.png");
 | 
			
		||||
            await Context.Channel.SendFileAsync(img.ToStream(), $"{color}.png");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Videocall(IUserMessage umsg, [Remainder] string arg = null)
 | 
			
		||||
        public async Task Videocall([Remainder] string arg = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var allUsrs = umsg.MentionedUsers.Append(Context.User);
 | 
			
		||||
                var allUsrs = Context.Message.MentionedUsers.Append(Context.User);
 | 
			
		||||
                var allUsrsArray = allUsrs.ToArray();
 | 
			
		||||
                var str = allUsrsArray.Aggregate("http://appear.in/", (current, usr) => current + Uri.EscapeUriString(usr.Username[0].ToString()));
 | 
			
		||||
                str += new NadekoRandom().Next();
 | 
			
		||||
@@ -580,18 +526,15 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Avatar(IUserMessage umsg, [Remainder] string mention = null)
 | 
			
		||||
        public async Task Avatar([Remainder] string mention = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
            var usr = umsg.MentionedUsers().FirstOrDefault();
 | 
			
		||||
            var usr = Context.Message.MentionedUsers().FirstOrDefault();
 | 
			
		||||
            if (usr == null)
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Invalid user specified.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Invalid user specified.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            await channel.SendMessageAsync(await NadekoBot.Google.ShortenUrl(usr.AvatarUrl).ConfigureAwait(false)).ConfigureAwait(false);
 | 
			
		||||
            await Context.Channel.SendMessageAsync(await NadekoBot.Google.ShortenUrl(usr.AvatarUrl).ConfigureAwait(false)).ConfigureAwait(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task<string> GetSafebooruImageLink(string tag)
 | 
			
		||||
@@ -611,13 +554,11 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task Wikia(IUserMessage umsg, string target, [Remainder] string query = null)
 | 
			
		||||
        public async Task Wikia(string target, [Remainder] string query = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(target) || string.IsNullOrWhiteSpace(query))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Please enter a target wikia, followed by search query.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Please enter a target wikia, followed by search query.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
 | 
			
		||||
@@ -632,24 +573,22 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                    var response = $@"`Title:` {found["title"].ToString()}
 | 
			
		||||
`Quality:` {found["quality"]}
 | 
			
		||||
`URL:` {await NadekoBot.Google.ShortenUrl(found["url"].ToString()).ConfigureAwait(false)}";
 | 
			
		||||
                    await channel.SendMessageAsync(response);
 | 
			
		||||
                    await Context.Channel.SendMessageAsync(response);
 | 
			
		||||
                }
 | 
			
		||||
                catch
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync($"Failed finding `{query}`.").ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendErrorAsync($"Failed finding `{query}`.").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task MCPing(IUserMessage umsg, [Remainder] string query = null)
 | 
			
		||||
        public async Task MCPing([Remainder] string query = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            var arg = query;
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(arg))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("💢 Please enter a `ip:port`.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("💢 Please enter a `ip:port`.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
 | 
			
		||||
@@ -669,24 +608,22 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                    sb.AppendLine($"`Description:` {items["description"].ToString()}");
 | 
			
		||||
                    sb.AppendLine($"`Online Players:` {items["players"]["online"].ToString()}/{items["players"]["max"].ToString()}");
 | 
			
		||||
                    sb.Append($"`Latency:` {ping}");
 | 
			
		||||
                    await channel.SendMessageAsync(sb.ToString());
 | 
			
		||||
                    await Context.Channel.SendMessageAsync(sb.ToString());
 | 
			
		||||
                }
 | 
			
		||||
                catch
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync($"Failed finding `{arg}`.").ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendErrorAsync($"Failed finding `{arg}`.").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [RequireContext(ContextType.Guild)]
 | 
			
		||||
        public async Task MCQ(IUserMessage umsg, [Remainder] string query = null)
 | 
			
		||||
        public async Task MCQ([Remainder] string query = null)
 | 
			
		||||
        {
 | 
			
		||||
            var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
            var arg = query;
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(arg))
 | 
			
		||||
            {
 | 
			
		||||
                await channel.SendErrorAsync("Please enter `ip:port`.").ConfigureAwait(false);
 | 
			
		||||
                await Context.Channel.SendErrorAsync("Please enter `ip:port`.").ConfigureAwait(false);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            await Context.Channel.TriggerTypingAsync().ConfigureAwait(false);
 | 
			
		||||
@@ -709,16 +646,16 @@ namespace NadekoBot.Modules.Searches
 | 
			
		||||
                    sb.AppendLine($"`Online Players:` {items["Players"]} / {items["MaxPlayers"]}");
 | 
			
		||||
                    sb.AppendLine($"`Plugins:` {items["Plugins"]}");
 | 
			
		||||
                    sb.Append($"`Version:` {items["Version"]}");
 | 
			
		||||
                    await channel.SendMessageAsync(sb.ToString());
 | 
			
		||||
                    await Context.Channel.SendMessageAsync(sb.ToString());
 | 
			
		||||
                }
 | 
			
		||||
                catch
 | 
			
		||||
                {
 | 
			
		||||
                    await channel.SendErrorAsync($"Failed finding server `{arg}`.").ConfigureAwait(false);
 | 
			
		||||
                    await Context.Channel.SendErrorAsync($"Failed finding server `{arg}`.").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task<bool> ValidateQuery(ITextChannel ch, string query)
 | 
			
		||||
        public static async Task<bool> ValidateQuery(IMessageChannel ch, string query)
 | 
			
		||||
        {
 | 
			
		||||
            if (!string.IsNullOrEmpty(query.Trim())) return true;
 | 
			
		||||
            await ch.SendErrorAsync("Please specify search parameters.").ConfigureAwait(false);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,10 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Utility
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,6 @@ using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,6 @@ using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,17 +4,11 @@ using NadekoBot.Attributes;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Services.Impl;
 | 
			
		||||
using Discord.API;
 | 
			
		||||
using Embed = Discord.API.Embed;
 | 
			
		||||
using EmbedAuthor = Discord.API.EmbedAuthor;
 | 
			
		||||
using EmbedField = Discord.API.EmbedField;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Utility
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,4 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services.Database.Models
 | 
			
		||||
namespace NadekoBot.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class UserPokeTypes : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services.Database.Repositories
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,4 @@
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services.Database.Repositories.Impl
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,4 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 
 | 
			
		||||
@@ -66,7 +66,7 @@ namespace NadekoBot
 | 
			
		||||
        public ISelfUser[] GetAllCurrentUsers() =>
 | 
			
		||||
            Clients.Select(c => c.CurrentUser).ToArray();
 | 
			
		||||
 | 
			
		||||
        public IReadOnlyCollection<IGuild> GetGuilds() =>
 | 
			
		||||
        public IReadOnlyCollection<SocketGuild> GetGuilds() =>
 | 
			
		||||
            Clients.SelectMany(c => c.Guilds).ToList();
 | 
			
		||||
 | 
			
		||||
        public IGuild GetGuild(ulong id) =>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Discord;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.TypeReaders
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Discord;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.TypeReaders
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Discord;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.TypeReaders
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Discord;
 | 
			
		||||
using NadekoBot.Modules.Permissions;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.TypeReaders
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,4 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.API;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using ImageSharp;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using System;
 | 
			
		||||
@@ -10,7 +8,6 @@ using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@
 | 
			
		||||
    "CoreCLR-NCalc": "2.1.2",
 | 
			
		||||
    "Google.Apis.Urlshortener.v1": "1.19.0.138",
 | 
			
		||||
    "Google.Apis.YouTube.v3": "1.19.0.655",
 | 
			
		||||
    "ImageSharp": "1.0.0-alpha-000079",
 | 
			
		||||
    "ImageSharp": "1.0.0-alpha-*",
 | 
			
		||||
    "Microsoft.EntityFrameworkCore": "1.1.0",
 | 
			
		||||
    "Microsoft.EntityFrameworkCore.Design": "1.1.0",
 | 
			
		||||
    "Microsoft.EntityFrameworkCore.Sqlite": "1.1.0",
 | 
			
		||||
@@ -38,7 +38,9 @@
 | 
			
		||||
    "Newtonsoft.Json": "9.0.2-beta1",
 | 
			
		||||
    "NLog": "5.0.0-beta03",
 | 
			
		||||
    "System.Diagnostics.Contracts": "4.3.0",
 | 
			
		||||
    "System.Xml.XPath": "4.3.0"
 | 
			
		||||
    "System.Xml.XPath": "4.3.0",
 | 
			
		||||
    "Discord.Net.Commands": "1.0.0-beta2-*",
 | 
			
		||||
    "Discord.Net.WebSocket": "1.0.0-beta2-*"
 | 
			
		||||
  },
 | 
			
		||||
  "tools": {
 | 
			
		||||
    "Microsoft.EntityFrameworkCore.Tools.DotNet": "1.1.0-preview4-final",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user