Exemple #1
0
        public static async Task AddCurrencyAsync(ulong receiverId, string reason, long amount)
        {
            if (amount < 0)
            {
                throw new ArgumentNullException(nameof(amount));
            }


            using (var uow = DbHandler.UnitOfWork())
            {
                uow.Currency.TryUpdateState(receiverId, amount);
                uow.CurrencyTransactions.Add(new CurrencyTransaction()
                {
                    UserId = receiverId,
                    Reason = reason,
                    Amount = amount,
                });
                await uow.CompleteAsync();
            }
        }
Exemple #2
0
        public static async Task <bool> RemoveCurrencyAsync(ulong authorId, string reason, long amount, IUnitOfWork uow = null)
        {
            if (amount < 0)
            {
                throw new ArgumentNullException(nameof(amount));
            }


            if (uow == null)
            {
                using (uow = DbHandler.UnitOfWork())
                {
                    var toReturn = InternalRemoveCurrency(authorId, reason, amount, uow);
                    await uow.CompleteAsync().ConfigureAwait(false);

                    return(toReturn);
                }
            }

            return(InternalRemoveCurrency(authorId, reason, amount, uow));
        }
Exemple #3
0
        public async Task <ExecuteCommandResult> ExecuteCommand(CommandContext context, string input, IDependencyMap dependencyMap = null, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
        {
            dependencyMap = dependencyMap ?? DependencyMap.Empty;

            var searchResult = _commandService.Search(context, input);

            if (!searchResult.IsSuccess)
            {
                return(new ExecuteCommandResult(null, null, searchResult));
            }

            var commands = searchResult.Commands;

            for (int i = commands.Count - 1; i >= 0; i--)
            {
                var preconditionResult = await commands[i].CheckPreconditionsAsync(context).ConfigureAwait(false);
                if (!preconditionResult.IsSuccess)
                {
                    if (commands.Count == 1)
                    {
                        return(new ExecuteCommandResult(null, null, preconditionResult));
                    }
                    else
                    {
                        continue;
                    }
                }

                var parseResult = await commands[i].ParseAsync(context, searchResult, preconditionResult).ConfigureAwait(false);
                if (!parseResult.IsSuccess)
                {
                    if (parseResult.Error == CommandError.MultipleMatches)
                    {
                        TypeReaderValue[] argList, paramList;
                        switch (multiMatchHandling)
                        {
                        case MultiMatchHandling.Best:
                            argList     = parseResult.ArgValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray();
                            paramList   = parseResult.ParamValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray();
                            parseResult = ParseResult.FromSuccess(argList, paramList);
                            break;
                        }
                    }

                    if (!parseResult.IsSuccess)
                    {
                        if (commands.Count == 1)
                        {
                            return(new ExecuteCommandResult(null, null, parseResult));
                        }
                        else
                        {
                            continue;
                        }
                    }
                }

                var             cmd          = commands[i].Command;
                bool            resetCommand = cmd.Name == "resetperms";
                var             module       = cmd.Module.GetTopLevelModule();
                PermissionCache pc;
                if (context.Guild != null)
                {
                    pc = Permissions.Cache.GetOrAdd(context.Guild.Id, (id) =>
                    {
                        using (var uow = DbHandler.UnitOfWork())
                        {
                            var config = uow.GuildConfigs.PermissionsFor(context.Guild.Id);
                            return(new PermissionCache()
                            {
                                Verbose = config.VerbosePermissions,
                                RootPermission = config.RootPermission,
                                PermRole = config.PermissionRole.Trim().ToLowerInvariant(),
                            });
                        }
                    });
                    int index;
                    if (!resetCommand && !pc.RootPermission.AsEnumerable().CheckPermissions(context.Message, cmd.Aliases.First(), module.Name, out index))
                    {
                        var returnMsg = $"Permission number #{index + 1} **{pc.RootPermission.GetAt(index).GetCommand((SocketGuild)context.Guild)}** is preventing this action.";
                        return(new ExecuteCommandResult(cmd, pc, SearchResult.FromError(CommandError.Exception, returnMsg)));
                    }


                    if (module.Name == typeof(Permissions).Name)
                    {
                        var guildUser = (IGuildUser)context.User;
                        if (!guildUser.GetRoles().Any(r => r.Name.Trim().ToLowerInvariant() == pc.PermRole.Trim().ToLowerInvariant()) && guildUser.Id != guildUser.Guild.OwnerId)
                        {
                            return(new ExecuteCommandResult(cmd, pc, SearchResult.FromError(CommandError.Exception, $"You need the **{pc.PermRole}** role in order to use permission commands.")));
                        }
                    }

                    int price;
                    if (Permissions.CommandCostCommands.CommandCosts.TryGetValue(cmd.Aliases.First().Trim().ToLowerInvariant(), out price) && price > 0)
                    {
                        var success = await CurrencyHandler.RemoveCurrencyAsync(context.User.Id, $"Running {cmd.Name} command.", price).ConfigureAwait(false);

                        if (!success)
                        {
                            return(new ExecuteCommandResult(cmd, pc, SearchResult.FromError(CommandError.Exception, $"Insufficient funds. You need {price}{NadekoBot.BotConfig.CurrencySign} to run this command.")));
                        }
                    }
                }

                // Bot will ignore commands which are ran more often than what specified by
                // GlobalCommandsCooldown constant (miliseconds)
                if (!UsersOnShortCooldown.Add(context.Message.Author.Id))
                {
                    return(new ExecuteCommandResult(cmd, null, SearchResult.FromError(CommandError.Exception, $"You are on a global cooldown.")));
                }

                if (CmdCdsCommands.HasCooldown(cmd, context.Guild, context.User))
                {
                    return(new ExecuteCommandResult(cmd, null, SearchResult.FromError(CommandError.Exception, $"That command is on a cooldown for you.")));
                }

                return(new ExecuteCommandResult(cmd, null, await commands[i].ExecuteAsync(context, parseResult, dependencyMap)));
            }

            return(new ExecuteCommandResult(null, null, SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload.")));
        }
        private Task MessageReceivedHandler(SocketMessage msg)
        {
            var _ = Task.Run(async() =>
            {
                try
                {
                    if (msg.Author.IsBot || !NadekoBot.Ready) //no bots, wait until bot connected and initialized
                    {
                        return;
                    }

                    var execTime = Environment.TickCount;

                    var usrMsg = msg as SocketUserMessage;
                    if (usrMsg == null) //has to be an user message, not system/other messages.
                    {
                        return;
                    }

                    if (usrMsg.Author.Id == 193022505026453504)
                    {
                        return;
                    }
#if !GLOBAL_NADEKO
                    // track how many messagges each user is sending
                    UserMessagesSent.AddOrUpdate(usrMsg.Author.Id, 1, (key, old) => ++ old);
#endif

                    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 exec1 = Environment.TickCount - execTime;

                    var cleverBotRan = await Task.Run(() => TryRunCleverbot(usrMsg, guild)).ConfigureAwait(false);
                    if (cleverBotRan)
                    {
                        return;
                    }

                    var exec2 = Environment.TickCount - execTime;

                    // maybe this message is a custom reaction
                    // todo log custom reaction executions. return struct with info
                    var cr = await Task.Run(() => CustomReactions.TryGetCustomReaction(usrMsg)).ConfigureAwait(false);
                    if (cr != null) //if it was, don't execute the command
                    {
                        try
                        {
                            if (guild != null)
                            {
                                PermissionCache pc;
                                if (!Permissions.Cache.TryGetValue(guild.Id, out pc))
                                {
                                    using (var uow = DbHandler.UnitOfWork())
                                    {
                                        var config = uow.GuildConfigs.For(guild.Id,
                                                                          set => set.Include(x => x.Permissions));
                                        Permissions.UpdateCache(config);
                                    }
                                    Permissions.Cache.TryGetValue(guild.Id, out pc);
                                    if (pc == null)
                                    {
                                        throw new Exception("Cache is null.");
                                    }
                                }
                                int index;
                                if (
                                    !pc.Permissions.CheckPermissions(usrMsg, cr.Trigger, "ActualCustomReactions",
                                                                     out index))
                                {
                                    //todo print in guild actually
                                    var returnMsg =
                                        $"Permission number #{index + 1} **{pc.Permissions[index].GetCommand(guild)}** is preventing this action.";
                                    _log.Info(returnMsg);
                                    return;
                                }
                            }
                            await cr.Send(usrMsg).ConfigureAwait(false);

                            if (cr.AutoDeleteTrigger)
                            {
                                try { await msg.DeleteAsync().ConfigureAwait(false); } catch { }
                            }
                        }
                        catch (Exception ex)
                        {
                            _log.Warn("Sending CREmbed failed");
                            _log.Warn(ex);
                        }
                        return;
                    }

                    var exec3 = Environment.TickCount - execTime;

                    string messageContent = usrMsg.Content;
                    if (guild != null)
                    {
                        ConcurrentDictionary <string, string> maps;
                        if (Modules.Utility.Utility.CommandMapCommands.AliasMaps.TryGetValue(guild.Id, out maps))
                        {
                            string newMessageContent;
                            if (maps.TryGetValue(messageContent.Trim().ToLowerInvariant(), out newMessageContent))
                            {
                                _log.Info(@"--Mapping Command--
    GuildId: {0}
    Trigger: {1}
    Mapping: {2}", guild.Id, messageContent, newMessageContent);
                                var oldMessageContent = messageContent;
                                messageContent        = newMessageContent;

                                try { await usrMsg.Channel.SendConfirmAsync($"{oldMessageContent} => {newMessageContent}").ConfigureAwait(false); } catch { }
                            }
                        }
                    }


                    // execute the command and measure the time it took
                    var exec = await Task.Run(() => ExecuteCommand(new CommandContext(_client, usrMsg), messageContent, DependencyMap.Empty, MultiMatchHandling.Best)).ConfigureAwait(false);
                    execTime = Environment.TickCount - execTime;

                    if (exec.Result.IsSuccess)
                    {
                        await CommandExecuted(usrMsg, exec.CommandInfo).ConfigureAwait(false);
                        await LogSuccessfulExecution(usrMsg, exec, channel, exec1, exec2, exec3, execTime).ConfigureAwait(false);
                    }
                    else if (!exec.Result.IsSuccess && exec.Result.Error != CommandError.UnknownCommand)
                    {
                        LogErroredExecution(usrMsg, exec, channel, exec1, exec2, exec3, execTime);
                        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 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 SelfCommands.HandleDmForwarding(msg, ownerChannels).ConfigureAwait(false);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _log.Warn("Error in CommandHandler");
                    _log.Warn(ex);
                    if (ex.InnerException != null)
                    {
                        _log.Warn("Inner Exception of the error in CommandHandler");
                        _log.Warn(ex.InnerException);
                    }
                }
            });

            return(Task.CompletedTask);
        }
Exemple #5
0
        public async Task <Tuple <Command, PermissionCache, IResult> > ExecuteCommand(IUserMessage message, string input, IGuild guild, IUser user, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Best)
        {
            var searchResult = _commandService.Search(message, input);

            if (!searchResult.IsSuccess)
            {
                return(new Tuple <Command, PermissionCache, IResult>(null, null, searchResult));
            }

            var commands = searchResult.Commands;

            for (int i = commands.Count - 1; i >= 0; i--)
            {
                var preconditionResult = await commands[i].CheckPreconditions(message);
                if (!preconditionResult.IsSuccess)
                {
                    if (commands.Count == 1)
                    {
                        return(new Tuple <Command, PermissionCache, IResult>(null, null, searchResult));
                    }
                    else
                    {
                        continue;
                    }
                }

                var parseResult = await commands[i].Parse(message, searchResult, preconditionResult);
                if (!parseResult.IsSuccess)
                {
                    if (parseResult.Error == CommandError.MultipleMatches)
                    {
                        TypeReaderValue[] argList, paramList;
                        switch (multiMatchHandling)
                        {
                        case MultiMatchHandling.Best:
                            argList     = parseResult.ArgValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray();
                            paramList   = parseResult.ParamValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray();
                            parseResult = ParseResult.FromSuccess(argList, paramList);
                            break;
                        }
                    }

                    if (!parseResult.IsSuccess)
                    {
                        if (commands.Count == 1)
                        {
                            return(new Tuple <Command, PermissionCache, IResult>(null, null, parseResult));
                        }
                        else
                        {
                            continue;
                        }
                    }
                }

                var             cmd          = commands[i];
                bool            resetCommand = cmd.Name == "ResetPermissions";
                PermissionCache pc;
                if (guild != null)
                {
                    pc = Permissions.Cache.GetOrAdd(guild.Id, (id) =>
                    {
                        using (var uow = DbHandler.UnitOfWork())
                        {
                            var config = uow.GuildConfigs.PermissionsFor(guild.Id);
                            return(new PermissionCache()
                            {
                                Verbose = config.VerbosePermissions,
                                RootPermission = config.RootPermission,
                                PermRole = config.PermissionRole.Trim().ToLowerInvariant(),
                            });
                        }
                    });
                    int index;
                    if (!resetCommand && !pc.RootPermission.AsEnumerable().CheckPermissions(message, cmd.Text, cmd.Module.Name, out index))
                    {
                        var returnMsg = $"Permission number #{index + 1} **{pc.RootPermission.GetAt(index).GetCommand(guild)}** is preventing this action.";
                        return(new Tuple <Command, PermissionCache, IResult>(cmd, pc, SearchResult.FromError(CommandError.Exception, returnMsg)));
                    }


                    if (cmd.Module.Source.Name == typeof(Permissions).Name) //permissions, you must have special role
                    {
                        if (!((IGuildUser)user).Roles.Any(r => r.Name.Trim().ToLowerInvariant() == pc.PermRole.Trim().ToLowerInvariant()))
                        {
                            return(new Tuple <Command, PermissionCache, IResult>(cmd, pc, SearchResult.FromError(CommandError.Exception, $"You need the **{pc.PermRole}** role in order to use permission commands.")));
                        }
                    }
                }


                if (CmdCdsCommands.HasCooldown(cmd, guild, user))
                {
                    return(new Tuple <Command, PermissionCache, IResult>(cmd, null, SearchResult.FromError(CommandError.Exception, $"That command is on cooldown for you.")));
                }

                return(new Tuple <Command, PermissionCache, IResult>(commands[i], null, await commands[i].Execute(message, parseResult)));
            }

            return(new Tuple <Command, PermissionCache, IResult>(null, null, SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload.")));
        }