/// <summary> /// Creates a new default help formatter. /// </summary> /// <param name="ctx">Context in which this formatter is being invoked.</param> /// <param name="localizationService">Localization service</param> public HelpCommandFormatter(CommandContext ctx, LocalizationService localizationService) : base(ctx) { _localizationGroup = localizationService.GetGroup(GetType().Name); _embedBuilder = new DiscordEmbedBuilder().WithTitle(_localizationGroup.GetText("Help", "Help")) .WithColor(DiscordColor.MidnightBlue); }
/// <summary> /// Execute the dialog element /// </summary> /// <returns>Result</returns> public override async Task <TData> Run() { var repeat = false; do { var currentBotMessage = await CommandContext.Channel .SendMessageAsync(GetMessage()) .ConfigureAwait(false); DialogContext.Messages.Add(currentBotMessage); var currentUserResponse = await CommandContext.Client .GetInteractivity() .WaitForMessageAsync(obj => obj.Author.Id == CommandContext.User.Id && obj.ChannelId == CommandContext.Channel.Id) .ConfigureAwait(false); if (currentUserResponse.TimedOut == false) { CommandContext.LastUserMessage = currentUserResponse.Result; DialogContext.Messages.Add(currentUserResponse.Result); try { return(await ConvertMessage(currentUserResponse.Result).ConfigureAwait(false)); } catch (Exception ex) when(ex is InvalidOperationException || ex is KeyNotFoundException) { var repeatMessage = await CommandContext.Channel .SendMessageAsync(_localizationService.GetGroup(nameof(DialogElementBase)) .GetText("PleaseTryAgain", "Your input was invalid. Please try again.")) .ConfigureAwait(false); DialogContext.Messages.Add(repeatMessage); repeat = true; } } }while (repeat); throw new TimeoutException(); }
/// <summary> /// Execution /// </summary> /// <param name="commandContext">Original command context</param> /// <param name="action">Action</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> protected async Task InvokeAsync(CommandContext commandContext, Func <CommandContextContainer, Task> action) { var commandContextContainer = new CommandContextContainer(commandContext, UserManagementService); try { await action(commandContextContainer).ConfigureAwait(false); } catch (TimeoutException) { } catch (OperationCanceledException) { } catch (ScruffyException ex) { await commandContextContainer.Channel .SendMessageAsync(ex.GetLocalizedMessage()) .ConfigureAwait(false); } catch (Exception ex) { var logEntryId = LoggingService.AddCommandLogEntry(LogEntryLevel.CriticalError, commandContext.Command?.QualifiedName, commandContextContainer.LastUserMessage?.Content, ex.Message, ex.ToString()); var client = HttpClientFactory.CreateClient(); using (var response = await client.GetAsync("https://g.tenor.com/v1/search?q=funny%20cat&key=RXM3VE2UGRU9&limit=50&contentfilter=high&ar_range=all") .ConfigureAwait(false)) { var jsonResult = await response.Content .ReadAsStringAsync() .ConfigureAwait(false); var searchResult = JsonConvert.DeserializeObject <SearchResultRoot>(jsonResult); var tenorEntry = searchResult.Results[new Random(DateTime.Now.Millisecond).Next(0, searchResult.Results.Count - 1)]; var gifUrl = tenorEntry.Media[0].Gif.Size < 8_388_608 ? tenorEntry.Media[0].Gif.Url : tenorEntry.Media[0].MediumGif.Size < 8_388_608 ? tenorEntry.Media[0].MediumGif.Url : tenorEntry.Media[0].NanoGif.Url; using (var downloadResponse = await client.GetAsync(gifUrl) .ConfigureAwait(false)) { var stream = await downloadResponse.Content .ReadAsStreamAsync() .ConfigureAwait(false); await using (stream.ConfigureAwait(false)) { var internalLocalizationGroup = LocalizationService.GetGroup(nameof(LocatedCommandModuleBase)); var builder = new DiscordMessageBuilder().WithContent(internalLocalizationGroup.GetFormattedText("CommandFailedMessage", "The command could not be executed. But I have an error code ({0}) and funny cat picture.", logEntryId ?? -1)) .WithFile("cat.gif", stream); await commandContextContainer.Channel .SendMessageAsync(builder) .ConfigureAwait(false); } } } } }
/// <summary> /// Overview /// </summary> /// <param name="commandContext">Current command context</param> /// <param name="filterExpression">Filtering the commands</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation</returns> public Task PostOverview(CommandContext commandContext, Func <Attribute, bool> filterExpression) { return(InvokeAsync(commandContext, async commandContextContainer => { var localizationGroup = LocalizationService.GetGroup(nameof(HelpCommandFormatter)); var builder = new DiscordEmbedBuilder() .WithTitle(LocalizationGroup.GetText("HelpCommandOverviewTitle", "Overview of the most important commands")) .WithDescription(LocalizationGroup.GetText("HelpCommandOverviewDescription", "The following message is an overview of the most important commands of the given category.")) .WithColor(DiscordColor.Green) .WithFooter("Scruffy", "https://cdn.discordapp.com/app-icons/838381119585648650/823930922cbe1e5a9fa8552ed4b2a392.png?size=64") .WithTimestamp(DateTime.Now); var formatter = new HelpCommandFormatter(commandContext, LocalizationService); var fieldCounter = 0; var builderCounter = 1; foreach (var topLevelCommandGroup in commandContext.CommandsNext .RegisteredCommands .Where(obj => obj.Key == obj.Value.Name) .Select(obj => obj.Value) .OfType <CommandGroup>() .Where(obj => obj.CustomAttributes.Any(filterExpression))) { var stringBuilder = new StringBuilder(); async Task AddField() { if (fieldCounter == 6) { if (builderCounter == 1) { builder.WithTitle(builder.Title + " #" + builderCounter); } builderCounter++; await commandContextContainer.Message .RespondAsync(builder) .ConfigureAwait(false); fieldCounter = 0; builder = new DiscordEmbedBuilder(); builder.WithTitle(LocalizationGroup.GetText("HelpCommandOverviewTitle", "Overview of the most important commands") + " #" + builderCounter) .WithColor(DiscordColor.Green) .WithFooter("Scruffy", "https://cdn.discordapp.com/app-icons/838381119585648650/823930922cbe1e5a9fa8552ed4b2a392.png?size=64") .WithTimestamp(DateTime.Now); } if (stringBuilder.Length > 0) { builder.AddField(localizationGroup.GetText(topLevelCommandGroup.Name, topLevelCommandGroup.Name + " commands"), stringBuilder.ToString()); stringBuilder = new StringBuilder(); } fieldCounter++; } async Task ProcessCommands(IEnumerable <Command> commands) { foreach (var command in commands.Where(obj => obj.CustomAttributes.Any(filterExpression))) { if (command is CommandGroup commandGroup) { await ProcessCommands(commandGroup.Children).ConfigureAwait(false); } else if ((await command.RunChecksAsync(commandContext, true).ConfigureAwait(false)).Any() == false) { await formatter.AddCommand(command, async sb => { var currentLine = sb.ToString(); if (currentLine.Length + stringBuilder.Length > 1024) { await AddField().ConfigureAwait(false); } stringBuilder.Append(sb); }) .ConfigureAwait(false); } } } await ProcessCommands(topLevelCommandGroup.Children).ConfigureAwait(false); await AddField().ConfigureAwait(false); } await commandContextContainer.Message .RespondAsync(builder) .ConfigureAwait(false); })); }
/// <summary> /// Constructor /// </summary> /// <param name="localizationService">Localization service</param> protected DialogElementBase(LocalizationService localizationService) { LocalizationGroup = localizationService.GetGroup(GetType().Name); }
/// <summary> /// Constructor /// </summary> /// <param name="localizationService">Localization service</param> public LocatedServiceBase(LocalizationService localizationService) { LocalizationGroup = localizationService.GetGroup(GetType().Name); }