public static Messaging.IEmbed BuildCommandHelpInfoEmbed(ICommandHelpInfo helpInfo, IBotConfiguration botConfiguration) { if (helpInfo is null) { return(BuildInfoEmbed("The given command does not exist, or is not yet documented.")); } else { Messaging.Embed embed = new Messaging.Embed { Title = string.Format("Help: {0}", helpInfo.Name) }; if (!string.IsNullOrEmpty(helpInfo.Summary)) { embed.AddField("Summary", (helpInfo.Summary ?? "No documentation available.").Replace("\\prefix", botConfiguration.Prefix)); } if (helpInfo.Aliases != null && helpInfo.Aliases.Count() > 0) { embed.AddField("Aliases", string.Join(", ", helpInfo.Aliases.OrderBy(x => x))); } if (helpInfo.Examples != null && helpInfo.Examples.Count() > 0) { embed.AddField("Example(s)", string.Join(Environment.NewLine, helpInfo.Examples .Select(i => string.Format("`{0}{1}{2}`", botConfiguration.Prefix, helpInfo.Group + (helpInfo.Group.Length > 0 ? " " : string.Empty), i)))); } return(embed); } }
public async Task <IEnumerable <ICommandHelpInfo> > GetCommandHelpInfoAsync() { List <ICommandHelpInfo> commandHelpInfos = new List <ICommandHelpInfo>(); // Get command information from the registered modules. foreach (CommandInfo commandInfo in _commandService.Commands) { commandHelpInfos.Add(new CommandHelpInfo { Name = GetFullCommandName(commandInfo), Aliases = commandInfo.Aliases.Where(a => !a.Equals(commandInfo.Name, StringComparison.OrdinalIgnoreCase)), Summary = commandInfo.Summary ?? "No documentation available." }); } // Match the commands to files in the help directory, adding/replacing any missing metadata. string helpDirectory = _botConfiguration.HelpDirectory; if (System.IO.Directory.Exists(helpDirectory)) { foreach (string helpInfoFilePath in System.IO.Directory.GetFiles(helpDirectory, "*.json", System.IO.SearchOption.AllDirectories)) { ICommandHelpInfo fileHelpInfo = JsonConvert.DeserializeObject <CommandHelpInfo>(System.IO.File.ReadAllText(helpInfoFilePath)); string group = string.Join(" ", helpInfoFilePath .After(_botConfiguration.HelpDirectory) .Split(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar) .Where(p => !string.IsNullOrWhiteSpace(p)) .SkipLast(1)); if (!string.IsNullOrEmpty(group)) { fileHelpInfo.Name = group + " " + fileHelpInfo.Name; } ICommandHelpInfo helpInfo = FindHelpInfo(commandHelpInfos, fileHelpInfo.Name); if (helpInfo != null) { helpInfo.Name = (fileHelpInfo.Name ?? helpInfo.Name).ToLower(); helpInfo.Aliases = helpInfo.Aliases .Union(fileHelpInfo.Aliases) .Where(i => !i.Equals(helpInfo.Name, StringComparison.OrdinalIgnoreCase)) .Distinct() .OrderBy(i => i); helpInfo.Summary = fileHelpInfo.Summary ?? helpInfo.Summary; helpInfo.Examples = fileHelpInfo.Examples; helpInfo.Category = fileHelpInfo.Category ?? helpInfo.Category; } } } // Return the result. return(await Task.FromResult(commandHelpInfos)); }
private ICommandHelpInfo FindHelpInfo(IEnumerable <ICommandHelpInfo> helpInfo, string commandName) { if (!string.IsNullOrEmpty(commandName)) { commandName = commandName.Trim(); } // Attempt to find an exact match for the name of the command. ICommandHelpInfo result = helpInfo .Where(i => i.Name.Equals(commandName, StringComparison.OrdinalIgnoreCase) || i.Aliases.Any(a => a.Equals(commandName, StringComparison.OrdinalIgnoreCase))) .FirstOrDefault(); // Attempt to find the command nested inside of a group. if (result is null) { result = helpInfo .Where(i => i.Name.Split(' ').Last().Equals(commandName, StringComparison.OrdinalIgnoreCase)) .FirstOrDefault(); } return(result); }
public async Task Help([Remainder] string commandName) { ICommandHelpInfo helpInfo = await HelpService.GetCommandHelpInfoAsync(commandName.Trim()); await ReplyAsync(embed : EmbedUtilities.BuildCommandHelpInfoEmbed(helpInfo, Config).ToDiscordEmbed()); }
protected async Task ShowCommandErrorAsync(Optional <CommandInfo> command, ICommandContext context, IResult result) { if (result is null) { await ShowGenericCommandErrorAsync(command, context, result); } else if (result.Error == CommandError.BadArgCount) { // Get the name of the command that the user attempted to use. string commandName = GetCommandName(context.Message); // If help documentation exists for this command, display it. ICommandHelpInfo commandHelpInfo = await helpService.GetCommandHelpInfoAsync(commandName); if (commandHelpInfo != null) { EmbedBuilder embed = new EmbedBuilder(); embed.WithColor(Color.Red); embed.WithTitle(string.Format("Incorrect use of \"{0}\" command", commandName.ToLower())); embed.WithDescription("❌ " + result.ErrorReason); if (commandHelpInfo.Examples.Any()) { embed.AddField("Example(s) of correct usage:", string.Join(Environment.NewLine, commandHelpInfo.Examples .Select(e => string.Format("`{0}{1}{2}`", configuration.Prefix, commandName, e.SkipWords(1))))); } await context.Channel.SendMessageAsync("", false, embed.Build()); } else { await ShowGenericCommandErrorAsync(command, context, result); } } else if (result.Error == CommandError.UnknownCommand) { // Suggest the most-similar command as a possible misspelling. string messageContent = context.Message.Content.Substring(GetCommmandArgumentsStartIndex(context.Message)); string commandName = messageContent.GetFirstWord(); if (!string.IsNullOrEmpty(commandName)) { string suggestedCommandName = StringUtilities.GetBestMatch(commandName, GetCommandNames().Where(name => helpService.IsCommandAvailableAsync(context, name).Result)); ICommandHelpInfo commandHelpInfo = await helpService.GetCommandHelpInfoAsync(suggestedCommandName); await DiscordUtilities.ReplyErrorAsync(context.Channel, string.Format($"Unknown command. Did you mean {commandHelpInfo.Name.ToBold()}?")); } else { await ShowGenericCommandErrorAsync(command, context, result); } } else { await ShowGenericCommandErrorAsync(command, context, result); } }