public async Task HelpAsync(CommandContext Context, int page) { var sender = Context.Sender; var server = (Server)Context.Server; var commandhandler = server.Commands; var allcommands = commandhandler.GetAllCommands(); var availablecommands = new List <Command>(); // filter available commands foreach (var cmd in allcommands) { var success = true; // check commands // only list commands the user may execute. foreach (var check in cmd.ExecutionChecks) { if (!await check.RunChecksAsync(Context)) { success = false; } } if (success) { availablecommands.Add(cmd); } } int commandcount = availablecommands.Count; var remainder = commandcount % CommandsPerPage; int pagecount = (commandcount - remainder) / CommandsPerPage; // all commands / page commands - remainder if (remainder > 0) { pagecount++; // if remainder, extra page } if (page < 1 || page > pagecount) { await sender.SendMessageAsync(ChatMessage.Simple($"{ChatColor.Red}Invalid help page.")); return; } var cmdsection = availablecommands.Skip((page - 1) * CommandsPerPage).Take(CommandsPerPage); var commands = ChatMessage.Simple("\n"); var header = new ChatMessage() { Underline = true, Text = $"List of available commands ({page}/{pagecount}):" }; commands.AddExtra(header); foreach (var cmd in cmdsection.Where(x => x.Parent == null)) { var commandName = new ChatMessage { Text = $"\n{ChatColor.Gold}{(cmd.Usage == "" ? $"/{cmd.Name}" : cmd.Usage)}", ClickEvent = new ClickComponent { Action = EClickAction.SuggestCommand, Value = $"{(cmd.Usage == "" ? $"/{cmd.Name}" : cmd.Usage.Contains(" ") ? $"{cmd.Usage.Split(" ")[0]} " : cmd.Usage)}" }, HoverEvent = new HoverComponent { Action = EHoverAction.ShowText, Contents = $"Click to suggest the command" } }; commands.AddExtra(commandName); var commandInfo = new ChatMessage { Text = $"{ChatColor.Gray}:{ChatColor.Reset} {cmd.Description}" }; commands.AddExtra(commandInfo); } await sender.SendMessageAsync(commands); }