CommandHandler refactor
This commit is contained in:
		@@ -23,13 +23,18 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class BlacklistCommands : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            public static ConcurrentHashSet<BlacklistItem> BlacklistedItems { get; set; } = new ConcurrentHashSet<BlacklistItem>();
 | 
			
		||||
            public static ConcurrentHashSet<ulong> BlacklistedUsers { get; set; } = new ConcurrentHashSet<ulong>();
 | 
			
		||||
            public static ConcurrentHashSet<ulong> BlacklistedGuilds { get; set; } = new ConcurrentHashSet<ulong>();
 | 
			
		||||
            public static ConcurrentHashSet<ulong> BlacklistedChannels { get; set; } = new ConcurrentHashSet<ulong>();
 | 
			
		||||
 | 
			
		||||
            static BlacklistCommands()
 | 
			
		||||
            {
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    BlacklistedItems = new ConcurrentHashSet<BlacklistItem>(uow.BotConfig.GetOrCreate().Blacklist);
 | 
			
		||||
                    var blacklist = uow.BotConfig.GetOrCreate().Blacklist;
 | 
			
		||||
                    BlacklistedUsers = new ConcurrentHashSet<ulong>(blacklist.Where(bi => bi.Type == BlacklistType.User).Select(c => c.ItemId));
 | 
			
		||||
                    BlacklistedGuilds = new ConcurrentHashSet<ulong>(blacklist.Where(bi => bi.Type == BlacklistType.Server).Select(c => c.ItemId));
 | 
			
		||||
                    BlacklistedChannels = new ConcurrentHashSet<ulong>(blacklist.Where(bi => bi.Type == BlacklistType.Channel).Select(c => c.ItemId));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -66,12 +71,34 @@ namespace NadekoBot.Modules.Permissions
 | 
			
		||||
                    {
 | 
			
		||||
                        var item = new BlacklistItem { ItemId = id, Type = type };
 | 
			
		||||
                        uow.BotConfig.GetOrCreate().Blacklist.Add(item);
 | 
			
		||||
                        BlacklistedItems.Add(item);
 | 
			
		||||
                        if (type == BlacklistType.Server)
 | 
			
		||||
                        {
 | 
			
		||||
                            BlacklistedGuilds.Add(id);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (type == BlacklistType.Channel)
 | 
			
		||||
                        {
 | 
			
		||||
                            BlacklistedChannels.Add(id);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (type == BlacklistType.User)
 | 
			
		||||
                        {
 | 
			
		||||
                            BlacklistedUsers.Add(id);
 | 
			
		||||
                        }                        
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        uow.BotConfig.GetOrCreate().Blacklist.RemoveWhere(bi => bi.ItemId == id && bi.Type == type);
 | 
			
		||||
                        BlacklistedItems.RemoveWhere(bi => bi.ItemId == id && bi.Type == type);
 | 
			
		||||
                        if (type == BlacklistType.Server)
 | 
			
		||||
                        {
 | 
			
		||||
                            BlacklistedGuilds.TryRemove(id);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (type == BlacklistType.Channel)
 | 
			
		||||
                        {
 | 
			
		||||
                            BlacklistedChannels.TryRemove(id);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (type == BlacklistType.User)
 | 
			
		||||
                        {
 | 
			
		||||
                            BlacklistedUsers.TryRemove(id);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ using NadekoBot.Modules.CustomReactions;
 | 
			
		||||
using NadekoBot.Modules.Games;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using NadekoBot.DataStructures;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services
 | 
			
		||||
{
 | 
			
		||||
@@ -29,6 +30,8 @@ namespace NadekoBot.Services
 | 
			
		||||
    }
 | 
			
		||||
    public class CommandHandler
 | 
			
		||||
    {
 | 
			
		||||
        public const int GlobalCommandsCooldown = 1500;
 | 
			
		||||
 | 
			
		||||
        private ShardedDiscordClient _client;
 | 
			
		||||
        private CommandService _commandService;
 | 
			
		||||
        private Logger _log;
 | 
			
		||||
@@ -52,7 +55,7 @@ namespace NadekoBot.Services
 | 
			
		||||
            clearUsersOnShortCooldown = new Timer((_) =>
 | 
			
		||||
            {
 | 
			
		||||
                UsersOnShortCooldown.Clear();
 | 
			
		||||
            }, null, 1500, 1500);
 | 
			
		||||
            }, null, GlobalCommandsCooldown, GlobalCommandsCooldown);
 | 
			
		||||
        }
 | 
			
		||||
        public async Task StartHandling()
 | 
			
		||||
        {
 | 
			
		||||
@@ -71,153 +74,187 @@ namespace NadekoBot.Services
 | 
			
		||||
            _client.MessageReceived += MessageReceivedHandler;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async void MessageReceivedHandler(SocketMessage msg)
 | 
			
		||||
        private async Task<bool> TryRunCleverbot(SocketUserMessage usrMsg, IGuild guild)
 | 
			
		||||
        {
 | 
			
		||||
            if (guild == null)
 | 
			
		||||
                return false;
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var usrMsg = msg as SocketUserMessage;
 | 
			
		||||
                if (usrMsg == null)
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                if (!usrMsg.IsAuthor())
 | 
			
		||||
                    UserMessagesSent.AddOrUpdate(usrMsg.Author.Id, 1, (key, old) => ++old);
 | 
			
		||||
 | 
			
		||||
                if (!UsersOnShortCooldown.Add(usrMsg.Author.Id))
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                if (msg.Author.IsBot || !NadekoBot.Ready) //no bots
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                var guild = (msg.Channel as SocketTextChannel)?.Guild;
 | 
			
		||||
 | 
			
		||||
                if (guild != null && guild.OwnerId != msg.Author.Id)
 | 
			
		||||
                var cleverbotExecuted = await Games.CleverBotCommands.TryAsk(usrMsg).ConfigureAwait(false);
 | 
			
		||||
                if (cleverbotExecuted)
 | 
			
		||||
                {
 | 
			
		||||
                    //todo split checks into their own modules
 | 
			
		||||
                    if (Permissions.FilterCommands.InviteFilteringChannels.Contains(msg.Channel.Id) ||
 | 
			
		||||
                        Permissions.FilterCommands.InviteFilteringServers.Contains(guild.Id))
 | 
			
		||||
                    {
 | 
			
		||||
                        if (usrMsg.Content.IsDiscordInvite())
 | 
			
		||||
                        {
 | 
			
		||||
                            try
 | 
			
		||||
                            {
 | 
			
		||||
                                await usrMsg.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
                                return;
 | 
			
		||||
                            }
 | 
			
		||||
                            catch (HttpException ex)
 | 
			
		||||
                            {
 | 
			
		||||
                                _log.Warn("I do not have permission to filter invites in channel with id " + msg.Channel.Id, ex);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    var filteredWords = Permissions.FilterCommands.FilteredWordsForChannel(msg.Channel.Id, guild.Id).Concat(Permissions.FilterCommands.FilteredWordsForServer(guild.Id));
 | 
			
		||||
                    var wordsInMessage = usrMsg.Content.ToLowerInvariant().Split(' ');
 | 
			
		||||
                    if (filteredWords.Any(w => wordsInMessage.Contains(w)))
 | 
			
		||||
                    {
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            await usrMsg.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                        catch (HttpException ex)
 | 
			
		||||
                        {
 | 
			
		||||
                            _log.Warn("I do not have permission to filter words in channel with id " + msg.Channel.Id, ex);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                BlacklistItem blacklistedItem;
 | 
			
		||||
                if ((blacklistedItem = Permissions.BlacklistCommands.BlacklistedItems.FirstOrDefault(bi =>
 | 
			
		||||
                     (bi.Type == BlacklistItem.BlacklistType.Server && bi.ItemId == guild?.Id) ||
 | 
			
		||||
                     (bi.Type == BlacklistItem.BlacklistType.Channel && bi.ItemId == msg.Channel.Id) ||
 | 
			
		||||
                     (bi.Type == BlacklistItem.BlacklistType.User && bi.ItemId == msg.Author.Id))) != null)
 | 
			
		||||
                {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    var cleverbotExecuted = await Games.CleverBotCommands.TryAsk(usrMsg);
 | 
			
		||||
                    if (cleverbotExecuted)
 | 
			
		||||
                    {
 | 
			
		||||
                        _log.Info($@"CleverBot Executed
 | 
			
		||||
                    _log.Info($@"CleverBot Executed
 | 
			
		||||
        Server: {guild.Name} [{guild.Id}]
 | 
			
		||||
        Channel: {usrMsg.Channel?.Name} [{usrMsg.Channel?.Id}]
 | 
			
		||||
        UserId: {usrMsg.Author} [{usrMsg.Author.Id}]
 | 
			
		||||
        Message: {usrMsg.Content}");
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception ex) { _log.Warn(ex, "Error in cleverbot"); }
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex) { _log.Warn(ex, "Error in cleverbot"); }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    // maybe this message is a custom reaction
 | 
			
		||||
                    var crExecuted = await CustomReactions.TryExecuteCustomReaction(usrMsg).ConfigureAwait(false);
 | 
			
		||||
        private bool IsBlacklisted(IGuild guild, SocketUserMessage usrMsg) =>
 | 
			
		||||
            (guild != null && BlacklistCommands.BlacklistedGuilds.Contains(guild.Id)) ||
 | 
			
		||||
            BlacklistCommands.BlacklistedChannels.Contains(usrMsg.Channel.Id) ||
 | 
			
		||||
            BlacklistCommands.BlacklistedUsers.Contains(usrMsg.Author.Id);
 | 
			
		||||
 | 
			
		||||
                    //if it was, don't execute the command
 | 
			
		||||
                    if (crExecuted)
 | 
			
		||||
                        return;
 | 
			
		||||
                }
 | 
			
		||||
                catch { }
 | 
			
		||||
 | 
			
		||||
                string messageContent = usrMsg.Content;
 | 
			
		||||
        private async Task LogSuccessfulExecution(SocketUserMessage usrMsg, ExecuteCommandResult exec, SocketTextChannel channel, Stopwatch sw)
 | 
			
		||||
        {
 | 
			
		||||
            await CommandExecuted(usrMsg, exec.CommandInfo).ConfigureAwait(false);
 | 
			
		||||
            _log.Info("Command Executed after {4}s\n\t" +
 | 
			
		||||
                        "User: {0}\n\t" +
 | 
			
		||||
                        "Server: {1}\n\t" +
 | 
			
		||||
                        "Channel: {2}\n\t" +
 | 
			
		||||
                        "Message: {3}",
 | 
			
		||||
                        usrMsg.Author + " [" + usrMsg.Author.Id + "]", // {0}
 | 
			
		||||
                        (channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1}
 | 
			
		||||
                        (channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2}
 | 
			
		||||
                        usrMsg.Content, // {3}
 | 
			
		||||
                        sw.Elapsed.TotalSeconds);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
                var sw = new Stopwatch();
 | 
			
		||||
                sw.Start();
 | 
			
		||||
                var exec = await ExecuteCommand(new CommandContext(_client.MainClient, usrMsg), messageContent, DependencyMap.Empty, MultiMatchHandling.Best);
 | 
			
		||||
                var command = exec.CommandInfo;
 | 
			
		||||
                var permCache = exec.PermissionCache;
 | 
			
		||||
                var result = exec.Result;
 | 
			
		||||
                sw.Stop();
 | 
			
		||||
                var channel = (msg.Channel as ITextChannel);
 | 
			
		||||
                if (result.IsSuccess)
 | 
			
		||||
                {
 | 
			
		||||
                    await CommandExecuted(usrMsg, command);
 | 
			
		||||
                    _log.Info("Command Executed after {4}s\n\t" +
 | 
			
		||||
                                "User: {0}\n\t" +
 | 
			
		||||
                                "Server: {1}\n\t" +
 | 
			
		||||
                                "Channel: {2}\n\t" +
 | 
			
		||||
                                "Message: {3}",
 | 
			
		||||
                                msg.Author + " [" + msg.Author.Id + "]", // {0}
 | 
			
		||||
                                (channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1}
 | 
			
		||||
                                (channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2}
 | 
			
		||||
                                usrMsg.Content, // {3}
 | 
			
		||||
                                sw.Elapsed.TotalSeconds // {4}
 | 
			
		||||
                                );
 | 
			
		||||
                }
 | 
			
		||||
                else if (!result.IsSuccess && result.Error != CommandError.UnknownCommand)
 | 
			
		||||
                {
 | 
			
		||||
                    _log.Warn("Command Errored after {5}s\n\t" +
 | 
			
		||||
        private void LogErroredExecution(SocketUserMessage usrMsg, ExecuteCommandResult exec, SocketTextChannel channel, Stopwatch sw)
 | 
			
		||||
        {
 | 
			
		||||
            _log.Warn("Command Errored after {5}s\n\t" +
 | 
			
		||||
                                "User: {0}\n\t" +
 | 
			
		||||
                                "Server: {1}\n\t" +
 | 
			
		||||
                                "Channel: {2}\n\t" +
 | 
			
		||||
                                "Message: {3}\n\t" +
 | 
			
		||||
                                "Error: {4}",
 | 
			
		||||
                                msg.Author + " [" + msg.Author.Id + "]", // {0}
 | 
			
		||||
                                usrMsg.Author + " [" + usrMsg.Author.Id + "]", // {0}
 | 
			
		||||
                                (channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1}
 | 
			
		||||
                                (channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2}
 | 
			
		||||
                                usrMsg.Content,// {3}
 | 
			
		||||
                                result.ErrorReason, // {4}
 | 
			
		||||
                                exec.Result.ErrorReason, // {4}
 | 
			
		||||
                                sw.Elapsed.TotalSeconds // {5}
 | 
			
		||||
                                );
 | 
			
		||||
                    if (guild != null && command != null && result.Error == CommandError.Exception)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task<bool> InviteFiltered(IGuild guild, SocketUserMessage usrMsg)
 | 
			
		||||
        {
 | 
			
		||||
            if ((Permissions.FilterCommands.InviteFilteringChannels.Contains(usrMsg.Channel.Id) ||
 | 
			
		||||
                Permissions.FilterCommands.InviteFilteringServers.Contains(guild.Id)) &&
 | 
			
		||||
                    usrMsg.Content.IsDiscordInvite())
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    await usrMsg.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                catch (HttpException ex)
 | 
			
		||||
                {
 | 
			
		||||
                    _log.Warn("I do not have permission to filter invites in channel with id " + usrMsg.Channel.Id, ex);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task<bool> WordFiltered(IGuild guild, SocketUserMessage usrMsg)
 | 
			
		||||
        {
 | 
			
		||||
            var filteredChannelWords = Permissions.FilterCommands.FilteredWordsForChannel(usrMsg.Channel.Id, guild.Id);
 | 
			
		||||
            var filteredServerWords = Permissions.FilterCommands.FilteredWordsForServer(guild.Id);
 | 
			
		||||
            var wordsInMessage = usrMsg.Content.ToLowerInvariant().Split(' ');
 | 
			
		||||
            if (filteredChannelWords.Count != 0 || filteredServerWords.Count != 0)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (var word in wordsInMessage)
 | 
			
		||||
                {
 | 
			
		||||
                    if (filteredChannelWords.Contains(word) ||
 | 
			
		||||
                        filteredServerWords.Contains(word))
 | 
			
		||||
                    {
 | 
			
		||||
                        if (permCache != null && permCache.Verbose)
 | 
			
		||||
                            try { await msg.Channel.SendMessageAsync("⚠️ " + result.ErrorReason).ConfigureAwait(false); } catch { }
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            await usrMsg.DeleteAsync().ConfigureAwait(false);
 | 
			
		||||
                        }
 | 
			
		||||
                        catch (HttpException ex)
 | 
			
		||||
                        {
 | 
			
		||||
                            _log.Warn("I do not have permission to filter words in channel with id " + usrMsg.Channel.Id, ex);
 | 
			
		||||
                        }
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async void MessageReceivedHandler(SocketMessage msg)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                if (msg.Author.IsBot || !NadekoBot.Ready) //no bots, wait until bot connected and initialized
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                var usrMsg = msg as SocketUserMessage;
 | 
			
		||||
                if (usrMsg == null) //has to be an user message, not system/other messages.
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                // track how many messagges each user is sending
 | 
			
		||||
                UserMessagesSent.AddOrUpdate(usrMsg.Author.Id, 1, (key, old) => ++old);
 | 
			
		||||
 | 
			
		||||
                // Bot will ignore commands which are ran more often than what specified by
 | 
			
		||||
                // GlobalCommandsCooldown constant (miliseconds)
 | 
			
		||||
                if (!UsersOnShortCooldown.Add(usrMsg.Author.Id))
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                var channel = msg.Channel as SocketTextChannel;
 | 
			
		||||
                var guild = channel?.Guild;
 | 
			
		||||
 | 
			
		||||
                if (guild != null && guild.OwnerId != msg.Author.Id)
 | 
			
		||||
                {
 | 
			
		||||
                    if (await InviteFiltered(guild, usrMsg).ConfigureAwait(false))
 | 
			
		||||
                        return;
 | 
			
		||||
 | 
			
		||||
                    if (await WordFiltered(guild, usrMsg).ConfigureAwait(false))
 | 
			
		||||
                        return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (IsBlacklisted(guild, usrMsg))
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                var cleverBotRan = await TryRunCleverbot(usrMsg, guild).ConfigureAwait(false);
 | 
			
		||||
                if (cleverBotRan)
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                // maybe this message is a custom reaction
 | 
			
		||||
                var crExecuted = await CustomReactions.TryExecuteCustomReaction(usrMsg).ConfigureAwait(false);
 | 
			
		||||
                if (crExecuted) //if it was, don't execute the command
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                string messageContent = usrMsg.Content;
 | 
			
		||||
 | 
			
		||||
                // execute the command and measure the time it took
 | 
			
		||||
                var sw = Stopwatch.StartNew();
 | 
			
		||||
                var exec = await ExecuteCommand(new CommandContext(_client.MainClient, usrMsg), messageContent, DependencyMap.Empty, MultiMatchHandling.Best);
 | 
			
		||||
                sw.Stop();
 | 
			
		||||
 | 
			
		||||
                if (exec.Result.IsSuccess)
 | 
			
		||||
                {
 | 
			
		||||
                    await LogSuccessfulExecution(usrMsg, exec, channel, sw).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                else if (!exec.Result.IsSuccess && exec.Result.Error != CommandError.UnknownCommand)
 | 
			
		||||
                {
 | 
			
		||||
                    LogErroredExecution(usrMsg, exec, channel, sw);
 | 
			
		||||
                    if (guild != null && exec.CommandInfo != null && exec.Result.Error == CommandError.Exception)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (exec.PermissionCache != null && exec.PermissionCache.Verbose)
 | 
			
		||||
                            try { await msg.Channel.SendMessageAsync("⚠️ " + exec.Result.ErrorReason).ConfigureAwait(false); } catch { }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    if (msg.Channel is IPrivateChannel)
 | 
			
		||||
                    {
 | 
			
		||||
                        //rofl, gotta do this to prevent this message from occuring on polls
 | 
			
		||||
                        // rofl, gotta do this to prevent dm help message being sent to 
 | 
			
		||||
                        // users who are voting on private polls (sending a number in a DM)
 | 
			
		||||
                        int vote;
 | 
			
		||||
                        if (int.TryParse(msg.Content, out vote)) return;
 | 
			
		||||
 | 
			
		||||
                        
 | 
			
		||||
                        await msg.Channel.SendMessageAsync(Help.DMHelpString).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
                        await DMForwardCommands.HandleDMForwarding(msg, ownerChannels);
 | 
			
		||||
                        await DMForwardCommands.HandleDMForwarding(msg, ownerChannels).ConfigureAwait(false);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -231,9 +268,8 @@ namespace NadekoBot.Services
 | 
			
		||||
                    _log.Warn(ex.InnerException);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Task<ExecuteCommandResult> ExecuteCommandAsync(CommandContext context, int argPos, IDependencyMap dependencyMap = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
 | 
			
		||||
            => ExecuteCommand(context, context.Message.Content.Substring(argPos), dependencyMap, multiMatchHandling);
 | 
			
		||||
 | 
			
		||||
@@ -328,19 +364,5 @@ namespace NadekoBot.Services
 | 
			
		||||
 | 
			
		||||
            return new ExecuteCommandResult(null, null, SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload."));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public struct ExecuteCommandResult
 | 
			
		||||
        {
 | 
			
		||||
            public readonly CommandInfo CommandInfo;
 | 
			
		||||
            public readonly PermissionCache PermissionCache;
 | 
			
		||||
            public readonly IResult Result;
 | 
			
		||||
 | 
			
		||||
            public ExecuteCommandResult(CommandInfo commandInfo, PermissionCache cache, IResult result)
 | 
			
		||||
            {
 | 
			
		||||
                this.CommandInfo = commandInfo;
 | 
			
		||||
                this.PermissionCache = cache;
 | 
			
		||||
                this.Result = result;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user