2021-04-10 04:33:22 +00:00
|
|
|
|
import {
|
|
|
|
|
Command,
|
|
|
|
|
NamedCommand,
|
|
|
|
|
CHANNEL_TYPE,
|
|
|
|
|
getPermissionName,
|
|
|
|
|
getCommandList,
|
|
|
|
|
getCommandInfo,
|
|
|
|
|
paginate
|
|
|
|
|
} from "../../core";
|
2021-04-10 04:06:16 +00:00
|
|
|
|
import {requireAllCasesHandledFor} from "../../lib";
|
2021-04-10 04:33:22 +00:00
|
|
|
|
import {MessageEmbed} from "discord.js";
|
|
|
|
|
|
|
|
|
|
const EMBED_COLOR = "#158a28";
|
2021-04-12 07:44:23 +00:00
|
|
|
|
const LEGEND = "Legend: `<type>`, `[list/of/stuff]`, `(optional)`, `(<optional type>)`, `([optional/list/...])`\n";
|
2020-07-25 08:15:26 +00:00
|
|
|
|
|
2021-04-05 03:40:31 +00:00
|
|
|
|
export default new NamedCommand({
|
2020-12-15 07:56:09 +00:00
|
|
|
|
description: "Lists all commands. If a command is specified, their arguments are listed as well.",
|
2020-12-15 01:44:28 +00:00
|
|
|
|
usage: "([command, [subcommand/type], ...])",
|
|
|
|
|
aliases: ["h"],
|
2021-04-12 07:44:23 +00:00
|
|
|
|
async run({send, author}) {
|
2021-04-10 04:06:16 +00:00
|
|
|
|
const commands = await getCommandList();
|
2021-04-12 07:44:23 +00:00
|
|
|
|
const helpMenuPages: [string, string][] = []; // An array of (category, description) tuples.
|
2020-10-15 09:23:24 +00:00
|
|
|
|
|
2021-04-12 07:44:23 +00:00
|
|
|
|
// Prevent the description of one category from overflowing by splitting it into multiple pages if needed.
|
|
|
|
|
for (const category of commands.keyArray()) {
|
2021-04-11 10:45:50 +00:00
|
|
|
|
const commandList = commands.get(category)!;
|
2021-04-12 07:44:23 +00:00
|
|
|
|
let output = LEGEND;
|
|
|
|
|
|
|
|
|
|
for (const command of commandList) {
|
|
|
|
|
const field = `\n❯ \`${command.name}\`: ${command.description}`.repeat(2);
|
|
|
|
|
const newOutput = output + field;
|
|
|
|
|
|
|
|
|
|
// Push then reset the output if it overflows, otherwise, continue as normal.
|
|
|
|
|
if (newOutput.length > 2048) {
|
|
|
|
|
helpMenuPages.push([category, output]);
|
|
|
|
|
output = LEGEND + field;
|
|
|
|
|
} else {
|
|
|
|
|
output = newOutput;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Then push whatever's remaining.
|
|
|
|
|
helpMenuPages.push([category, output]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
paginate(send, author.id, helpMenuPages.length, (page, hasMultiplePages) => {
|
|
|
|
|
const [category, output] = helpMenuPages[page];
|
2021-04-11 10:45:50 +00:00
|
|
|
|
return new MessageEmbed()
|
2021-04-12 07:44:23 +00:00
|
|
|
|
.setTitle(hasMultiplePages ? `${category} (Page ${page + 1} of ${helpMenuPages.length})` : category)
|
2021-04-11 10:45:50 +00:00
|
|
|
|
.setDescription(output)
|
|
|
|
|
.setColor(EMBED_COLOR);
|
|
|
|
|
});
|
2020-12-15 01:44:28 +00:00
|
|
|
|
},
|
|
|
|
|
any: new Command({
|
2021-04-12 07:44:23 +00:00
|
|
|
|
async run({send, args}) {
|
2021-04-10 16:30:27 +00:00
|
|
|
|
const resultingBlob = await getCommandInfo(args);
|
|
|
|
|
if (typeof resultingBlob === "string") return send(resultingBlob);
|
|
|
|
|
const [result, category] = resultingBlob;
|
2020-12-15 01:44:28 +00:00
|
|
|
|
let append = "";
|
2021-04-10 04:06:16 +00:00
|
|
|
|
const command = result.command;
|
|
|
|
|
const header = result.args.length > 0 ? `${result.header} ${result.args.join(" ")}` : result.header;
|
2021-04-05 08:46:50 +00:00
|
|
|
|
|
2021-04-05 03:40:31 +00:00
|
|
|
|
if (command.usage === "") {
|
2020-12-15 01:44:28 +00:00
|
|
|
|
const list: string[] = [];
|
|
|
|
|
|
2021-04-05 03:40:31 +00:00
|
|
|
|
for (const [tag, subcommand] of result.keyedSubcommandInfo) {
|
|
|
|
|
const customUsage = subcommand.usage ? ` ${subcommand.usage}` : "";
|
2021-04-10 04:33:22 +00:00
|
|
|
|
list.push(`❯ \`${header} ${tag}${customUsage}\` - ${subcommand.description}`);
|
2021-04-05 03:40:31 +00:00
|
|
|
|
}
|
2020-12-15 01:44:28 +00:00
|
|
|
|
|
2021-04-05 03:40:31 +00:00
|
|
|
|
for (const [type, subcommand] of result.subcommandInfo) {
|
|
|
|
|
const customUsage = subcommand.usage ? ` ${subcommand.usage}` : "";
|
2021-04-10 04:33:22 +00:00
|
|
|
|
list.push(`❯ \`${header} ${type}${customUsage}\` - ${subcommand.description}`);
|
2021-04-05 03:40:31 +00:00
|
|
|
|
}
|
2020-12-15 01:44:28 +00:00
|
|
|
|
|
2021-04-10 04:33:22 +00:00
|
|
|
|
append = list.length > 0 ? list.join("\n") : "None";
|
2021-04-05 03:40:31 +00:00
|
|
|
|
} else {
|
2021-04-10 04:33:22 +00:00
|
|
|
|
append = `\`${header} ${command.usage}\``;
|
2021-04-05 03:40:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let aliases = "N/A";
|
2020-12-15 01:44:28 +00:00
|
|
|
|
|
2021-04-05 03:40:31 +00:00
|
|
|
|
if (command instanceof NamedCommand) {
|
|
|
|
|
const formattedAliases: string[] = [];
|
|
|
|
|
for (const alias of command.aliases) formattedAliases.push(`\`${alias}\``);
|
|
|
|
|
// Short circuit an empty string, in this case, if there are no aliases.
|
|
|
|
|
aliases = formattedAliases.join(", ") || "None";
|
|
|
|
|
}
|
2020-12-15 01:44:28 +00:00
|
|
|
|
|
2021-04-10 13:34:55 +00:00
|
|
|
|
return send(
|
2021-04-10 04:33:22 +00:00
|
|
|
|
new MessageEmbed()
|
|
|
|
|
.setTitle(header)
|
|
|
|
|
.setDescription(command.description)
|
|
|
|
|
.setColor(EMBED_COLOR)
|
|
|
|
|
.addFields(
|
|
|
|
|
{
|
|
|
|
|
name: "Aliases",
|
|
|
|
|
value: aliases,
|
|
|
|
|
inline: true
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Category",
|
|
|
|
|
value: category,
|
|
|
|
|
inline: true
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Permission Required",
|
|
|
|
|
value: `\`${getPermissionName(result.permission)}\` (Level ${result.permission})`,
|
|
|
|
|
inline: true
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Channel Type",
|
|
|
|
|
value: getChannelTypeName(result.channelType),
|
|
|
|
|
inline: true
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "NSFW Only?",
|
|
|
|
|
value: result.nsfw ? "Yes" : "No",
|
|
|
|
|
inline: true
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "Usages",
|
|
|
|
|
value: append
|
|
|
|
|
}
|
|
|
|
|
)
|
2020-10-15 09:23:24 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
2020-12-15 01:44:28 +00:00
|
|
|
|
})
|
2020-10-15 09:23:24 +00:00
|
|
|
|
});
|
2021-04-05 08:46:50 +00:00
|
|
|
|
|
|
|
|
|
function getChannelTypeName(type: CHANNEL_TYPE): string {
|
|
|
|
|
switch (type) {
|
|
|
|
|
case CHANNEL_TYPE.ANY:
|
|
|
|
|
return "Any";
|
|
|
|
|
case CHANNEL_TYPE.GUILD:
|
|
|
|
|
return "Guild Only";
|
|
|
|
|
case CHANNEL_TYPE.DM:
|
|
|
|
|
return "DM Only";
|
|
|
|
|
default:
|
|
|
|
|
requireAllCasesHandledFor(type);
|
|
|
|
|
}
|
|
|
|
|
}
|