From 248823959850c8eae5ecf43b89694f0265e7670b Mon Sep 17 00:00:00 2001 From: WatDuhHekBro <44940783+WatDuhHekBro@users.noreply.github.com> Date: Sat, 25 Jul 2020 21:35:53 -0500 Subject: [PATCH] Modularized command resolution --- src/commands/help.ts | 111 +++++++++++++++++++----------------------- src/core/command.ts | 40 ++++++++++++--- src/events/message.ts | 22 +++------ 3 files changed, 88 insertions(+), 85 deletions(-) diff --git a/src/commands/help.ts b/src/commands/help.ts index 9c3e33a..2bfa6e2 100644 --- a/src/commands/help.ts +++ b/src/commands/help.ts @@ -40,76 +40,65 @@ export default new Command({ let command = commands.get(header); if(!command || header === "test") - $.channel.send(`No command found by the name \`${header}\`!`); - else + return $.channel.send(`No command found by the name \`${header}\`!`); + + let usage = command.usage; + let invalid = false; + + for(const param of $.args) { - let usage = command.usage; + const type = command.resolve(param); - for(const param of $.args) + switch(type) { - header += ` ${param}`; - - if(/<\w+>/g.test(param)) - { - const type = param.match(/\w+/g)[0]; - command = command[type]; - - if(types.includes(type) && command?.usage) - usage = command.usage; - else - { - command = undefined; - break; - } - } - else if(command?.subcommands?.[param]) - { - command = command.subcommands[param]; - - if(command.usage !== "") - usage = command.usage; - } - else - { - command = undefined; - break; - } + case Command.TYPES.SUBCOMMAND: header += ` ${param}`; break; + case Command.TYPES.USER: header += " " ; break; + case Command.TYPES.NUMBER: header += " " ; break; + case Command.TYPES.ANY: header += " " ; break; + default: header += ` ${param}`; break; } - if(!command) - return $.channel.send(`No command found by the name \`${header}\`!`); - - let append = ""; - - if(usage === "") + if(type === Command.TYPES.NONE) { - const list: string[] = []; - - for(const subtag in command.subcommands) - { - const subcmd = command.subcommands[subtag]; - const customUsage = subcmd.usage ? ` ${subcmd.usage}` : ""; - list.push(`- \`${header} ${subtag}${customUsage}\` - ${subcmd.description}`); - } - - for(const type of types) - { - if(command[type]) - { - const cmd = command[type]; - const customUsage = cmd.usage ? ` ${cmd.usage}` : ""; - list.push(`- \`${header} <${type}>${customUsage}\` - ${cmd.description}`); - } - } - - - append = "Usages:" + (list.length > 0 ? `\n${list.join('\n')}` : " None."); + invalid = true; + break; } - else - append = `Usage: \`${header} ${usage}\``; - $.channel.send(`Command: \`${header}\`\nDescription: ${command.description}\n${append}`, {split: true}); + command = command.get(param); } + + if(invalid) + return $.channel.send(`No command found by the name \`${header}\`!`); + + let append = ""; + + if(usage === "") + { + const list: string[] = []; + + for(const subtag in command.subcommands) + { + const subcmd = command.subcommands[subtag]; + const customUsage = subcmd.usage ? ` ${subcmd.usage}` : ""; + list.push(`- \`${header} ${subtag}${customUsage}\` - ${subcmd.description}`); + } + + for(const type of types) + { + if(command[type]) + { + const cmd = command[type]; + const customUsage = cmd.usage ? ` ${cmd.usage}` : ""; + list.push(`- \`${header} <${type}>${customUsage}\` - ${cmd.description}`); + } + } + + append = "Usages:" + (list.length > 0 ? `\n${list.join('\n')}` : " None."); + } + else + append = `Usage: \`${header} ${usage}\``; + + $.channel.send(`Command: \`${header}\`\nDescription: ${command.description}\n${append}`, {split: true}); } }) }); \ No newline at end of file diff --git a/src/core/command.ts b/src/core/command.ts index 5618ca9..cab89e1 100644 --- a/src/core/command.ts +++ b/src/core/command.ts @@ -21,6 +21,8 @@ interface CommandOptions any?: Command; } +export enum TYPES {SUBCOMMAND, USER, NUMBER, ANY, NONE}; + export default class Command { public readonly description: string; @@ -34,6 +36,7 @@ export default class Command public any: Command|null; //public static readonly PERMISSIONS = PERMISSIONS; [key: string]: any; // Allow for dynamic indexing. The CommandOptions interface will still prevent users from adding unused properties though. + public static readonly TYPES = TYPES; constructor(options?: CommandOptions) { @@ -78,17 +81,38 @@ export default class Command this.subcommands[key] = command; } - /** See if a subcommand exists for the command. */ - /*public has(type: string): boolean + public resolve(param: string): TYPES { - return this.subcommands && (type in this.subcommands) || false; - }*/ + if(this.subcommands?.[param]) + return TYPES.SUBCOMMAND; + // Any Discord ID format will automatically format to a user ID. + else if(this.user && (/\d{17,19}/.test(param))) + return TYPES.USER; + // Disallow infinity and allow for 0. + else if(this.number && (Number(param) || param === "0") && !param.includes("Infinity")) + return TYPES.NUMBER; + else if(this.any) + return TYPES.ANY; + else + return TYPES.NONE; + } - /** Get the requested subcommand if it exists. */ - /*public get(type: string): Command|null + public get(param: string): Command { - return this.subcommands && this.subcommands[type] || null; - }*/ + const type = this.resolve(param); + let command; + + switch(type) + { + case TYPES.SUBCOMMAND: command = this.subcommands![param]; break; + case TYPES.USER: command = this.user as Command; break; + case TYPES.NUMBER: command = this.number as Command; break; + case TYPES.ANY: command = this.any as Command; break; + default: command = this; break; + } + + return command; + } } /*export function hasPermission(member: GuildMember, permission: number): boolean diff --git a/src/events/message.ts b/src/events/message.ts index 613e602..28252e4 100644 --- a/src/events/message.ts +++ b/src/events/message.ts @@ -58,28 +58,18 @@ export default new Event({ break; } - if(command.subcommands?.[param]) - command = command.subcommands[param]; - // Any Discord ID format will automatically format to a user ID. - else if(command.user && (/\d{17,19}/.test(param))) + const type = command.resolve(param); + command = command.get(param); + + if(type === Command.TYPES.USER) { const id = param.match(/\d+/g)![0]; - command = command.user; try {params.push(await message.client.users.fetch(id))} catch(error) {return message.channel.send(`No user found by the ID \`${id}\`!`)} } - // Disallow infinity and allow for 0. - else if(command.number && (Number(param) || param === "0") && !param.includes("Infinity")) - { - command = command.number; + else if(type === Command.TYPES.NUMBER) params.push(Number(param)); - } - else if(command.any) - { - command = command.any; - params.push(param); - } - else + else if(type !== Command.TYPES.SUBCOMMAND) params.push(param); }