Пример #1
0
        private async Task Client_ClientError(ClientErrorEventArgs e)
        {
            e.Client.DebugLogger.LogMessage(LogLevel.Error, this.Bot.LogName, $"Exception occured: {e.Exception.GetType()}: {e.Exception.Message}", DateTime.Now);


            var chn = this.Bot.ErrorChannel;

            var ex = e.Exception;

            while (ex is AggregateException || ex.InnerException != null)
            {
                ex = ex.InnerException;
            }

            await chn.SendMessageAsync(embed : EmbedTemplates.ErrorEmbed()
                                       .WithTitle("Exception")
                                       .WithDescription($"Exception occured: {ex.GetType()}: {e.Exception.Message}")).ConfigureAwait(false);
        }
Пример #2
0
        public async Task Evaluate(CommandContext context, [RemainingText, Description("С# код")] string code)
        {
            var codeStart = code.IndexOf("```") + 3;

            codeStart = code.IndexOf("\n", codeStart) + 1;
            var codeEnd = code.LastIndexOf("```");

            if (codeStart == -1 || codeEnd == -1)
            {
                throw new DiscordUserInputException("Код должен находиться внутри в блоке кода", nameof(code));
            }

            code = code.Substring(codeStart, codeEnd - codeStart);

            var embed = EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember)
                        .WithTitle("Код компилируется и выполняется");

            var msg = await context.RespondAsync(embed : embed);

            var globals = new Globals()
            {
                Bot = this.Bot, Context = context, Database = this.Database
            };

            var scriptsOptions = ScriptOptions.Default
                                 .WithImports("System", "System.Diagnostics", "System.Reflection", "System.Text", "System.Collections.Generic", "System.Linq", "System.Threading.Tasks", "DSharpPlus", "DSharpPlus.CommandsNext",
                                              "DSharpPlus.Entities", "JazzBot.Data", "JazzBot.Enums", "JazzBot.Services", "JazzBot.Utilities", "Microsoft.EntityFrameworkCore")
                                 .WithReferences(AppDomain.CurrentDomain.GetAssemblies().Where(x => !x.IsDynamic && !string.IsNullOrWhiteSpace(x.Location)));

            var compileSW      = Stopwatch.StartNew();
            var codeScript     = CSharpScript.Create(code, scriptsOptions, typeof(Globals));
            var compiledScript = codeScript.Compile();

            compileSW.Stop();

            if (compiledScript.Any(x => x.Severity == DiagnosticSeverity.Error))
            {
                embed = EmbedTemplates.ErrorEmbed()
                        .WithDescription(compiledScript.Length > 1 ? $"Произошло {compiledScript.Length} ошибки/ошибок времени компиляции" : "Произошла ошибка компиляции");

                foreach (var error in compiledScript.Take(5))
                {
                    var ls = error.Location.GetLineSpan();
                    embed.AddField($"Ошибка в {ls.StartLinePosition.Line}", Formatter.InlineCode(error.GetMessage()));
                }

                await msg.ModifyAsync(embed : embed.Build());

                return;
            }

            Exception runtimeException = null;

            ScriptState <object> css = null;

            var runtimeSW = Stopwatch.StartNew();

            try
            {
                css = await codeScript.RunAsync(globals).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                runtimeException = ex;
            }
            runtimeSW.Stop();

            if (runtimeException != null)
            {
                embed = EmbedTemplates.ErrorEmbed().WithDescription($"Произошла ошибка времени выполнения после {runtimeSW.ElapsedMilliseconds} мс");

                await msg.ModifyAsync(embed : embed.Build());

                return;
            }

            embed = EmbedTemplates.ExecutedByEmbed(context.Member, context.Guild.CurrentMember).WithDescription("Команда выполнена успешно");

            embed.AddField("Результат выполнения", css.ReturnValue == null ? "Значения не возвращено" : Formatter.InlineCode(css.ReturnValue.ToString()))
            .AddField("Время компиляции", compileSW.ElapsedMilliseconds.ToString("#,##0") + "мс", true)
            .AddField("Время выполнения", runtimeSW.ElapsedMilliseconds.ToString("#,##0") + "мс", true);

            if (css.ReturnValue != null)
            {
                embed.AddField("Тип результата", css.ReturnValue.GetType().ToString());
            }

            await msg.ModifyAsync(embed : embed.Build());
        }
Пример #3
0
        private async Task Commands_CommandErrored(CommandErrorEventArgs e)
        {
            e.Context.Client.DebugLogger.LogMessage(LogLevel.Error, this.Bot.LogName, $"{e.Context.User.Username} tried executing '{e.Command?.QualifiedName ?? "<unknown command>"}' but it errored: {e.Exception.GetType()}: {e.Exception.Message ?? "<no message>"}", DateTime.Now);


            var ex = e.Exception;

            while (ex is AggregateException || ex.InnerException != null)
            {
                ex = ex.InnerException;
            }

            // Check if exception is result of command prechecks.
            switch (ex)
            {
            case ChecksFailedException exep:
            {
                var failedchecks = exep.FailedChecks.First();
                switch (failedchecks)
                {
                // Bot is lacking permissions.
                case RequireBotPermissionsAttribute reqbotperm:
                {
                    string permissionsLacking = reqbotperm.Permissions.ToPermissionString();
                    var    emoji = DiscordEmoji.FromName(e.Context.Client, ":no_entry:");
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithTitle($"{emoji} Боту не хватает прав")
                                                 .WithDescription(permissionsLacking)).ConfigureAwait(false);

                    break;
                }

                // User is lacking permissions.
                case RequireUserPermissionsAttribute requserperm:
                {
                    string permissionsLacking = requserperm.Permissions.ToPermissionString();
                    var    emoji = DiscordEmoji.FromName(e.Context.Client, ":no_entry:");

                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithTitle($"{emoji} Вам не хватает прав")
                                                 .WithDescription(permissionsLacking)).ConfigureAwait(false);

                    break;
                }

                // User is not owner of the bot.
                case RequireOwnerAttribute reqowner:
                {
                    var emoji = DiscordEmoji.FromName(e.Context.Client, ":no_entry:");
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithTitle($"{emoji} Команда доступна только владельцу")).ConfigureAwait(false);

                    break;
                }

                // User is not owner or don't have permissions.
                case OwnerOrPermissionAttribute ownerOrPermission:
                {
                    string permissionsLacking = ownerOrPermission.Permissions.ToPermissionString();
                    var    emoji = DiscordEmoji.FromName(e.Context.Client, ":no_entry:");
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithTitle($"{emoji} Вы не являетесь владельцем или вам не хватает прав")
                                                 .WithDescription(permissionsLacking)).ConfigureAwait(false);

                    break;
                }

                // Command shouldn't be executed so fast.
                case CooldownAttribute cooldown:
                {
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithDescription("Вы пытаетесь использовать команду слишком часто, таймер - " +
                                                                  $"не больше {cooldown.MaxUses} раз в {cooldown.Reset.TotalMinutes} минут")).ConfigureAwait(false);

                    break;
                }

                // User wasn't connected to voice channel. Optionally to the same voice channel as bot
                case RequireVoiceConnectionAttribute requireVoice:
                {
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithDescription($"Вы должны быть подключены к {(requireVoice.SameVoiceChannelAsBot ? "тому же голосовому каналу что и бот" : "голосовому каналу")}")).ConfigureAwait(false);

                    break;
                }

                default:
                {
                    await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                                 .WithDescription($"Вам не хватает прав, чтобы узнать каких используйте {Formatter.InlineCode($"{this.Bot.Config.Discord.Prefixes.RandomElement()}help {e.Command.QualifiedName}")}"));

                    break;
                }
                }

                break;
            }

            case DatabaseException dbEx:
            {
                var description = new StringBuilder("Произошла ошибка в работе БД, возможно стоит попробовать чуть позже.");
                description.AppendLine(string.IsNullOrWhiteSpace(dbEx.Message)
                                                ? $"Тип действия: {dbEx.ActionType.ToString()}"
                                                : $"Сообщение - {Formatter.InlineCode(dbEx.Message)}. Тип действия: {dbEx.ActionType.ToString()}");

                await e.Context.RespondAsync(embed : EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                                             .WithDescription(description.ToString())).ConfigureAwait(false);

                break;
            }

            case DiscordUserInputException inputEx:
            {
                await e.Context.RespondAsync($"{inputEx.Message}. Название параметра {inputEx.ArgumentName}").ConfigureAwait(false);

                break;
            }

            case CommandNotFoundException commandNotFoundException:
            {
                var cmdName           = commandNotFoundException.CommandName;
                var suggestedCommands = new List <Command>();
                var nL = new NormalizedLevenshtein();

                // Let's assumme that 0.33 is good Levenshtein distance

                foreach (var cmd in this.Commands.RegisteredCommands.Values.Distinct())
                {
                    if (cmd is CommandGroup cmdGroup)
                    {
                        foreach (var children in cmdGroup.Children)
                        {
                            if (Helpers.IsCommandSimilar(children, cmdName, nL))
                            {
                                suggestedCommands.Add(children);
                            }
                        }
                        if (cmdGroup.IsExecutableWithoutSubcommands && Helpers.IsCommandSimilar(cmdGroup, cmdName, nL))
                        {
                            suggestedCommands.Add(cmdGroup);
                        }
                    }
                    else
                    {
                        if (Helpers.IsCommandSimilar(cmd, cmdName, nL))
                        {
                            suggestedCommands.Add(cmd);
                        }
                    }
                }

                if (suggestedCommands.Any())
                {
                    suggestedCommands.OrderBy(x => x.QualifiedName);
                    var description = new StringBuilder();
                    description.AppendLine($"Команды с названием {Formatter.InlineCode(cmdName)} не найдено. Вот возможные варианты того, что вы имели в виду:");
                    foreach (var cmd in suggestedCommands)
                    {
                        description.AppendLine(Formatter.InlineCode(cmd.QualifiedName));
                    }

                    await e.Context.RespondAsync(embed : EmbedTemplates.ErrorEmbed()
                                                 .WithDescription(description.ToString())).ConfigureAwait(false);
                }
                break;
            }

            case InvalidOperationException invOpEx when invOpEx.Message == "No matching subcommands were found, and this group is not executable.":
            {
                //Ignore.
                break;
            }

            default:
            {
                var embed = EmbedTemplates.CommandErrorEmbed(e.Context.Member, e.Command)
                            .WithTitle("Произошла непредвиденная ошибка в работе команды")
                            .WithDescription($"Message: \n{Formatter.InlineCode(ex.Message)}\n в \n{Formatter.InlineCode(ex.Source)}");
                await e.Context.RespondAsync(embed : embed).ConfigureAwait(false);

                await this.Bot.ErrorChannel.SendMessageAsync(embed : embed).ConfigureAwait(false);

                break;
            }
            }
        }