public async Task <bool> TryExecuteCommandAsync(SocketUserMessage userMessage)
        {
            if (userMessage.Source != MessageSource.User || string.IsNullOrWhiteSpace(userMessage.Content))
            {
                return(false);
            }

            var prefixes = new List <string>
            {
                _config.DefaultPrefix, $"<@{_client.CurrentUser.Id}> ", $"<@!{_client.CurrentUser.Id}> "
            };

            LocalizedLanguage language;

            using (var ctx = new AdminDatabaseContext(_provider))
            {
                if (userMessage.Channel is IGuildChannel guildChannel)
                {
                    var guild = await ctx.GetOrCreateGuildAsync(guildChannel.GuildId);

                    prefixes.AddRange(guild.CustomPrefixes);
                    language = guild.Language;
                }
                else
                {
                    var user = await ctx.GetOrCreateGlobalUserAsync(userMessage.Author.Id);

                    language = user.Language;
                }
            }

            if (!CommandUtilities.HasAnyPrefix(userMessage.Content, prefixes, StringComparison.OrdinalIgnoreCase,
                                               out var prefix, out var input))
            {
                return(false);
            }

            var context = new AdminCommandContext(userMessage, prefix, language, _provider);
            var result  = await _commands.ExecuteAsync(input, context, _provider);

            if (!(result is FailedResult failedResult))
            {
                return(true);
            }

            // TODO: localized error messages, log
            var error = new StringBuilder()
                        .Append(failedResult switch
            {
                ParameterChecksFailedResult parameterChecksResult => string.Join('\n', parameterChecksResult.FailedChecks.Select(x => x.Error)),
                ChecksFailedResult checkResult => string.Join('\n', checkResult.FailedChecks.Select(x => x.Error)),
                ExecutionFailedResult execResult => GenerateException(execResult.Exception),
                CommandNotFoundResult _ => string.Empty,
                _ => failedResult.Reason
            }).ToString();
Esempio n. 2
0
        private async Task OnCommandFailureAsync(CommandFailedEventArgs args)
        {
            var reason = args.Result switch
            {
                CommandNotFoundResult _ => "Unknown command.",
                ChecksFailedResult cfr => cfr.FailureReason,
                ParameterChecksFailedResult pcfr => $"One or more checks failed on parameter **{pcfr.Parameter.Name}**: ```css\n{pcfr.FailedChecks.Select(x => x.Result.FailureReason).Join('\n')}```",
                ArgumentParseFailedResult apfr => $"Parsing for arguments failed for **{apfr.Command}**.",
                TypeParseFailedResult tpfr => tpfr.FailureReason,
                OverloadsFailedResult _ => "A suitable overload could not be found for the given parameter type/order.",
                ExecutionFailedResult efr => ExecutionFailed(efr),
                _ => Unknown(args.Result)
            };

            string Unknown(FailedResult result)
            {
                _logger.Verbose(LogSource.Service, $"A command returned an unknown error. Please screenshot this message and show it to my developers: {result.GetType().Name}");
                return("Unknown error.");
            }

            string ExecutionFailed(ExecutionFailedResult result)
            {
                _logger.Exception(result.Exception);
                return($"Execution of this command failed. Exception: {result.Exception.GetType()}");
            }

            if (!reason.IsNullOrEmpty())
            {
                await args.Context.CreateEmbedBuilder()
                .AddField("Error in Command", args.Context.Command.Name)
                .AddField("Error Reason", reason)
                .AddField("Correct Usage", args.Context.Command.GetUsage(args.Context))
                .WithErrorColor()
                .SendToAsync(args.Context.Channel);

                if (!Config.LogAllCommands)
                {
                    return;
                }

                _logger.Error(LogSource.Module, new StringBuilder()
                              .AppendLine(CommandFrom(args))
                              .AppendLine(CommandIssued(args))
                              .AppendLine(ArgsPassed(args))
                              .AppendLine(InGuild(args))
                              .AppendLine(InChannel(args))
                              .AppendLine(TimeIssued(args))
                              .AppendLine(args.ExecutedLogMessage(reason))
                              .AppendLine(After(args))
                              .Append(_separator).ToString());
            }
        }
Esempio n. 3
0
        private async Task OnCommandFailureAsync(CommandFailedEventArgs args)
        {
            FailedCommandCalls += 1;
            var reason = args.Result switch
            {
                CommandNotFoundResult _ => "Unknown command.",
                ExecutionFailedResult efr => $"Execution of this command failed. Exception: {efr.Exception.GetType()}",
                ChecksFailedResult cfr => cfr.Reason,
                ParameterChecksFailedResult pcfr => $"One or more checks failed on parameter **{pcfr.Parameter.Name}**: ```css\n{pcfr.FailedChecks.Select(x => x.Result.Reason).Join('\n')}```",
                ArgumentParseFailedResult apfr => $"Parsing for arguments failed for **{apfr.Command}**.",
                TypeParseFailedResult tpfr => tpfr.Reason,
                OverloadsFailedResult _ => "A suitable overload could not be found for the given parameter type/order.",
                _ => "Unknown error."
            };

            if (args.Result is ExecutionFailedResult e)
            {
                _logger.Exception(e.Exception);
            }

            if (!(args.Result is ChecksFailedResult) && !reason.IsNullOrEmpty())
            {
                await args.Context.CreateEmbedBuilder()
                .AddField("Error in Command", args.Context.Command.Name)
                .AddField("Error Reason", reason)
                .AddField("Correct Usage", args.Context.Command.GetUsage(args.Context))
                .WithErrorColor()
                .SendToAsync(args.Context.Channel);

                if (!Config.LogAllCommands)
                {
                    return;
                }

                Executor.Execute(() =>
                {
                    _logger.Error(LogSource.Module, new StringBuilder()
                                  .AppendLine($"|  -Command from user: {args.Context.User} ({args.Context.User.Id})") //yes, the spaces in front of each string are indeed intentional on all lines after this
                                  .AppendLine($"                    |     -Command Issued: {args.Context.Command.Name}")
                                  .AppendLine($"                    |        -Args Passed: {args.Arguments.Trim()}")
                                  .AppendLine($"                    |           -In Guild: {args.Context.Guild.Name} ({args.Context.Guild.Id})")
                                  .AppendLine($"                    |         -In Channel: #{args.Context.Channel.Name} ({args.Context.Channel.Id})")
                                  .AppendLine($"                    |        -Time Issued: {args.Context.Now.FormatFullTime()}, {args.Context.Now.FormatDate()}")
                                  .AppendLine($"                    |           -Executed: {args.Result.IsSuccessful} | Reason: {reason}")
                                  .AppendLine($"                    |              -After: {args.Stopwatch.Elapsed.Humanize()}")
                                  .Append("                    -------------------------------------------------").ToString());
                });
            }
        }
Esempio n. 4
0
 private async Task OnCommandFailureAsync(CommandFailedEventArgs args)
 {
     var reason = args.Result switch
     {
         CommandNotFoundResult _ => "Unknown command.",
         ChecksFailedResult cfr =>
         $"One or more checks failed for command **{cfr.Command.Name}**: {Format.Code(cfr.FailedChecks.Select(x => x.Result.FailureReason).Join('\n'), "css")}",
         ParameterChecksFailedResult pcfr =>
         $"One or more checks failed on parameter **{pcfr.Parameter.Name}**: {Format.Code(pcfr.FailedChecks.Select(x => x.Result.FailureReason).Join('\n'), "css")}",
         ArgumentParseFailedResult apfr => $"Parsing for arguments failed for {Format.Bold(apfr.Command.Name)}.",
         TypeParseFailedResult tpfr => tpfr.FailureReason,
         OverloadsFailedResult _ => "A suitable overload could not be found for the given parameter type/order.",
         CommandExecutionFailedResult cefr => ExecutionFailed(cefr),
         _ => Unknown(args.Result)
     };
Esempio n. 5
0
        public async Task InvokeAsync(CommandContext context, CommandDelegate next)
        {
            context.NotNull(nameof(context));

            if (context.Command.HasContent() || context.Result.HasContent())
            {
                await next(context);

                return;
            }

            context.RawArgs.NotNullOrWhiteSpace(nameof(context.RawArgs));
            var input = context.RawArgs;

            var matches = await _moduleCache.SearchCommandsAsync(input);

            matches = matches
                      .Where(a => a.Command.IsEnabled)
                      .ToList();

            _logger.LogDebug($"Total matches: {matches.Count}.");

            if (matches.HasNoContent())
            {
                _logger.LogInformation($"Don't find any commands that matches the input {input}.");
                context.Result = CommandNotFoundResult.FromInput(input);

                return;
            }

            context.Features.Set <ICommandMatchesFeature>(new CommandMatchesFeature());
            var matchesFeature = context.Features.Get <ICommandMatchesFeature>();

            matchesFeature.CommandMatches = matches;

            await next(context);

            return;
        }