From 6c903077541f9eb2cc00f68daf47c3740f72d857 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Thu, 2 Dec 2021 14:09:05 +0000 Subject: [PATCH] Migrate help command --- commands/help.js | 150 ------------------------------------- src/commands/help.ts | 118 +++++++++++++++++++++++++++++ src/helpers/StringTools.ts | 15 ++++ 3 files changed, 133 insertions(+), 150 deletions(-) delete mode 100644 commands/help.js create mode 100644 src/commands/help.ts create mode 100644 src/helpers/StringTools.ts diff --git a/commands/help.js b/commands/help.js deleted file mode 100644 index 71d7946..0000000 --- a/commands/help.js +++ /dev/null @@ -1,150 +0,0 @@ -// Required Components -const { command } = require('vylbot-core'); -const { MessageEmbed } = require('discord.js'); -const { readdirSync } = require('fs'); - -const embedColor = "0x3050ba"; - -// Command Class -class help extends command { - constructor() { - // Set the execute method, description, category, and example usage - super("help"); - super.description = "Gives a list of commands available in the bot"; - super.category = "General"; - super.usage = "[command]"; - } - - // Execute method - help(context) { - // Get the list of command folders the bot has been setup to check - const commandFolders = context.client.config.commands; - - // Empty arrays for commands - // allCommands: Will contain objects of all commands with their related info - // categories: Will contain strings of all the categories the commands are set to, unique - const allCommands = []; - const categories = []; - - // Loop through all the command folders set - // i = folder index - for (let i = 0; i < commandFolders.length; i++) { - // The current folder the bot is looking through - const folder = commandFolders[i]; - - // Read the directory of the current folder - const contents = readdirSync(`${process.cwd()}/${folder}`); - - // Loop through the contents of the folder - // j = file index in folder i - for (let j = 0; j < contents.length; j++) { - // Get command in the current folder to read - const file = require(`${process.cwd()}/${folder}/${contents[j]}`); - - // Initialise the command - const obj = new file(); - - // Data object containing the command information - const data = { - "name": contents[j].replace(".js", ""), - "description": obj.description, - "category": obj.category, - "usage": obj.usage, - "roles": obj.roles - }; - - // Push the command data to the allCommands Array - allCommands.push(data); - } - } - - // Loop through all the commands discovered by the previous loop - for (let i = 0; i < allCommands.length; i++) { - // Get the current command category name, otherwise "none" - const category = allCommands[i].category || "none"; - - // If the command isn't already set, set it. - // This will then make the categories array be an array of all categories which have been used but only one of each. - if (!categories.includes(category)) categories.push(category); - } - - // If an command name has been passed as an argument - // If so, send information about that command - // If not, send the help embed of all commands - if (context.arguments[0]) { - sendCommand(context, allCommands, context.arguments[0]); - } else { - sendAll(context, categories, allCommands); - } - } -} - -// Send embed of all commands -// context: The command context json string -// categories: The array of categories found -// allCommands: The array of the commands found -function sendAll(context, categories, allCommands) { - // Embed to be sent - const embed = new MessageEmbed() - .setColor(embedColor) - .setTitle("Commands"); - - // Loop through each command - for (let i = 0; i < categories.length; i++) { - // The category name of the current one to check - const category = categories[i]; - - // Empty Array for the next loop to filter out the current category - const commandsFilter = []; - - // Loop through allCommands - // If the command is set to the current category being checked, add it to the filter array - for (let j = 0; j < allCommands.length; j++) { - if (allCommands[j].category == category) commandsFilter.push(`\`${allCommands[j].name}\``); - } - - // Add a field to the embed which contains the category name and all the commands in that category - embed.addField(category, commandsFilter.join(", ")); - } - - // Send the embed - context.message.channel.send(embed); -} - -// Send information about a specific command -// context: The command context json string -// allCommands: The array of categories found -// name: The command name to check -function sendCommand(context, allCommands, name) { - let command = {}; - - // Loop through all commands, if the command name is the same as the one we're looking for, select it - for (let i = 0; i < allCommands.length; i++) { - if (allCommands[i].name == name) command = allCommands[i]; - } - - // If a matching command has been found - if (command.name) { - // Create an embed containing the related information of the command - // The title is the command name but sets the first letter to be capitalised - // If a set of information isn't set, set it to say "none" - const embed = new MessageEmbed() - .setColor(embedColor) - .setTitle(command.name[0].toUpperCase() + command.name.substring(1)) - .setDescription(command.description || "*none*") - .addField("Category", command.category || "*none*", true) - .addField("Usage", command.usage || "*none*", true) - .addField("Required Roles", command.roles.join(", ") || "*none*"); - - // Send the embed - context.message.channel.send(embed); - } else { // If no command has been found, then send an embed which says this - const embed = new MessageEmbed() - .setColor(embedColor) - .setDescription("Command does not exist"); - - context.message.channel.send(embed); - } -} - -module.exports = help; diff --git a/src/commands/help.ts b/src/commands/help.ts new file mode 100644 index 0000000..dc56258 --- /dev/null +++ b/src/commands/help.ts @@ -0,0 +1,118 @@ +import { existsSync, readdirSync } from "fs"; +import { Command, ICommandContext } from "vylbot-core"; +import ErrorEmbed from "../helpers/ErrorEmbed"; +import PublicEmbed from "../helpers/PublicEmbed"; +import StringTools from "../helpers/StringTools"; + +interface ICommandData { + Exists: boolean; + Name?: string; + Category?: string; + Roles?: string[]; +} + +export default class Help extends Command { + constructor() { + super(); + + super._category = "General"; + } + + public override execute(context: ICommandContext) { + if (context.args.length == 0) { + this.SendAll(context); + } else { + this.SendSingle(context); + } + } + + private SendAll(context: ICommandContext) { + const allCommands = this.GetAllCommandData(); + const cateogries = this.DetermineCategories(allCommands); + + const embed = new PublicEmbed(context, "Commands", ""); + + cateogries.forEach(category => { + let filtered = allCommands.filter(x => x.Category == category); + + embed.addField(StringTools.Capitalise(category), filtered.flatMap(x => x.Name).join(", ")); + }); + + embed.SendToCurrentChannel(); + } + + private SendSingle(context: ICommandContext) { + const command = this.GetCommandData(context.args[0]); + + if (!command.Exists) { + const errorEmbed = new ErrorEmbed(context, "Command does not exist"); + errorEmbed.SendToCurrentChannel(); + return; + } + + const embed = new PublicEmbed(context, StringTools.Capitalise(command.Name!), ""); + embed.addField("Category", StringTools.Capitalise(command.Category!)); + embed.addField("Required Roles", StringTools.Capitalise(command.Roles!.join(", ")) || "*none*"); + + embed.SendToCurrentChannel(); + } + + private GetAllCommandData(): ICommandData[] { + const result: ICommandData[] = []; + + const folder = process.env.FOLDERS_COMMANDS!; + + const contents = readdirSync(`${process.cwd()}/${folder}`); + + contents.forEach(name => { + const file = require(`${process.cwd()}/${folder}/${name}`).default; + const command = new file() as Command; + + const data: ICommandData = { + Exists: true, + Name: name.replace(".ts", ""), + Category: command._category || "none", + Roles: command._roles, + }; + + result.push(data); + }); + + return result; + } + + private GetCommandData(name: string): ICommandData { + const folder = process.env.FOLDERS_COMMANDS!; + const path = `${process.cwd()}/${folder}/${name}.ts`; + + if (!existsSync(path)) { + return { + Exists: false + }; + } + + const file = require(path).default; + const command = new file() as Command; + + const data: ICommandData = { + Exists: true, + Name: name, + Category: command._category || "none", + Roles: command._roles + }; + + return data; + } + + private DetermineCategories(commands: ICommandData[]): string[] { + const result: string[] = []; + + commands.forEach(cmd => { + if (!result.includes(cmd.Category!)) { + result.push(cmd.Category!); + } + }); + + return result; + } +} \ No newline at end of file diff --git a/src/helpers/StringTools.ts b/src/helpers/StringTools.ts new file mode 100644 index 0000000..b42eb90 --- /dev/null +++ b/src/helpers/StringTools.ts @@ -0,0 +1,15 @@ +export default class StringTools { + public static Capitalise(str: string): string { + const words = str.split(" "); + let result: string[] = []; + + words.forEach(word => { + const firstLetter = word.substring(0, 1).toUpperCase(); + const rest = word.substring(1); + + result.push(firstLetter + rest); + }); + + return result.join(" "); + } +} \ No newline at end of file