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); }
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()); }
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; } } }