/// <summary> /// Builds a set of pre-formatted pages for the commands in the given module. /// </summary> /// <param name="module">The module that contains the commands.</param> /// <returns>A list of pages, where each page is a list of embed fields.</returns> private IReadOnlyList <IReadOnlyList <EmbedFieldBuilder> > BuildCommandListPages([NotNull] ModuleInfo module) { var pages = new List <IReadOnlyList <EmbedFieldBuilder> >(); var currentPage = new List <EmbedFieldBuilder>(); var currentContentLength = 0; var commandGroups = module .GetAllCommands() .GroupBy(c => c.Aliases.OrderByDescending(a => a).First()) .ToList(); foreach (var commandGroup in commandGroups) { var helpField = _help.CreateCommandInfoEmbedField(commandGroup.First()); var commandContentLength = helpField.Name.Length + ((string)helpField.Value).Length; if (commandGroup.Count() > 1) { var hint = "*This command has multiple variants.*"; helpField.WithValue((string)helpField.Value + "\n" + hint); commandContentLength += hint.Length; } if (currentPage.Count >= 5 || (currentContentLength + commandContentLength) > 1300) { pages.Add(currentPage); currentPage = new List <EmbedFieldBuilder>(); currentContentLength = 0; } currentPage.Add(helpField); currentContentLength += commandContentLength; if (commandGroup == commandGroups.Last() && !pages.Contains(currentPage)) { pages.Add(currentPage); } } return(pages); }
private async Task ConsumeCommandListInteractionAsync([NotNull] SocketReaction reaction) { var emote = reaction.Emote; if (!this.AcceptedEmotes.Contains(emote)) { return; } if (emote.Equals(Back)) { _state = HelpWizardState.ModuleListing; await UpdateAsync(); return; } if (emote.Equals(Next)) { // ReSharper disable once AssignNullToNotNullAttribute if (_commandListOffset + 1 > _commandListPages[_currentModule].Count - 1) { return; } _commandListOffset++; } else if (emote.Equals(Previous)) { if (_commandListOffset - 1 < 0) { return; } _commandListOffset--; } else if (emote.Equals(First)) { _commandListOffset = 0; } else if (emote.Equals(Last)) { // ReSharper disable once AssignNullToNotNullAttribute _commandListOffset = _commandListPages[_currentModule].Count - 1; } else if (emote.Equals(EnterModule)) { bool Filter(IUserMessage m) => m.Author.Id == reaction.UserId; // ReSharper disable once PossibleNullReferenceException if (!_currentModule.Commands.Any()) { await _feedback.SendWarningAndDeleteAsync ( this.MessageContext, "There aren't any commands available in the module.", TimeSpan.FromSeconds(10) ); return; } await _feedback.SendConfirmationAndDeleteAsync ( this.MessageContext, "Please enter a command name.", TimeSpan.FromSeconds(45) ); var messageResult = await this.Interactivity.GetNextMessageAsync ( this.Channel, Filter, TimeSpan.FromSeconds(45) ); if (messageResult.IsSuccess) { var searchText = messageResult.Entity.Content; var commandSearchTerms = _currentModule .GetAllCommands() .Select(c => c.GetFullCommand()); var findCommandResult = commandSearchTerms.BestLevenshteinMatch(searchText, 0.5); if (findCommandResult.IsSuccess) { var foundName = findCommandResult.Entity; var commandGroup = _currentModule.Commands .Where(c => c.GetFullCommand() == foundName) .GroupBy(c => c.Aliases.OrderByDescending(a => a).First()) .First(); var eb = _help.CreateDetailedCommandInfoEmbed(commandGroup); await _feedback.SendEmbedAndDeleteAsync ( this.Channel, eb.Build(), TimeSpan.FromSeconds(45) ); } else { var eb = _feedback.CreateEmbedBase(Color.Orange); eb.WithDescription("I couldn't find a sufficiently close command to that."); await _feedback.SendEmbedAndDeleteAsync ( this.Channel, eb.Build() ); } } } await UpdateAsync(); }
/// <summary> /// Gets all potential command names in the given module, including aliases and real names. /// </summary> /// <param name="module">The module to scan.</param> /// <returns>The names.</returns> public static IEnumerable <string> GetAllCommandNames([NotNull] this ModuleInfo module) { var allCommands = module.GetAllCommands().ToList(); return(allCommands.SelectMany(c => c.Aliases).Union(allCommands.Select(c => c.Name))); }