mirror of
				https://github.com/keanuplayz/TravBot-v3.git
				synced 2024-08-15 02:33:12 +00:00 
			
		
		
		
	Implemented rough draft of info resolver method
This commit is contained in:
		
							parent
							
								
									2a4d08d0bc
								
							
						
					
					
						commit
						6ed4c0988f
					
				
					 4 changed files with 184 additions and 125 deletions
				
			
		|  | @ -1,9 +1,9 @@ | ||||||
| import Command from "../../core/command"; | import {Command, NamedCommand} from "../../core/command"; | ||||||
| import {toTitleCase} from "../../core/lib"; | import {toTitleCase} from "../../core/lib"; | ||||||
| import {loadableCommands, categories} from "../../core/loader"; | import {loadableCommands, categories} from "../../core/loader"; | ||||||
| import {getPermissionName} from "../../core/permissions"; | import {getPermissionName} from "../../core/permissions"; | ||||||
| 
 | 
 | ||||||
| export default new Command({ | export default new NamedCommand({ | ||||||
|     description: "Lists all commands. If a command is specified, their arguments are listed as well.", |     description: "Lists all commands. If a command is specified, their arguments are listed as well.", | ||||||
|     usage: "([command, [subcommand/type], ...])", |     usage: "([command, [subcommand/type], ...])", | ||||||
|     aliases: ["h"], |     aliases: ["h"], | ||||||
|  | @ -16,13 +16,7 @@ export default new Command({ | ||||||
| 
 | 
 | ||||||
|             for (const header of headers) { |             for (const header of headers) { | ||||||
|                 if (header !== "test") { |                 if (header !== "test") { | ||||||
|                     const command = commands.get(header); |                     const command = commands.get(header)!; | ||||||
| 
 |  | ||||||
|                     if (!command) |  | ||||||
|                         return console.warn( |  | ||||||
|                             `Command "${header}" of category "${category}" unexpectedly doesn't exist!` |  | ||||||
|                         ); |  | ||||||
| 
 |  | ||||||
|                     output += `\n- \`${header}\`: ${command.description}`; |                     output += `\n- \`${header}\`: ${command.description}`; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | @ -32,44 +26,63 @@ export default new Command({ | ||||||
|     }, |     }, | ||||||
|     any: new Command({ |     any: new Command({ | ||||||
|         async run($) { |         async run($) { | ||||||
|             // [category, commandName, command, subcommandInfo] = resolveCommandInfo();
 |             // Setup the root command
 | ||||||
|  |             const commands = await loadableCommands; | ||||||
|  |             let header = $.args.shift() as string; | ||||||
|  |             let command = commands.get(header); | ||||||
|  |             if (!command || header === "test") return $.channel.send(`No command found by the name \`${header}\`.`); | ||||||
|  |             if (!(command instanceof NamedCommand)) | ||||||
|  |                 return $.channel.send(`Command is not a proper instance of NamedCommand.`); | ||||||
|  |             if (command.name) header = command.name; | ||||||
|  | 
 | ||||||
|  |             // Search categories
 | ||||||
|  |             let category = "Unknown"; | ||||||
|  |             for (const [referenceCategory, headers] of categories) { | ||||||
|  |                 if (headers.includes(header)) { | ||||||
|  |                     category = toTitleCase(referenceCategory); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // Gather info
 | ||||||
|  |             const result = await command.resolveInfo($.args); | ||||||
|  | 
 | ||||||
|  |             if (result.type === "error") return $.channel.send(result.message); | ||||||
| 
 | 
 | ||||||
|             let append = ""; |             let append = ""; | ||||||
|  |             command = result.command; | ||||||
| 
 | 
 | ||||||
|             if (usage === "") { |             if (command.usage === "") { | ||||||
|                 const list: string[] = []; |                 const list: string[] = []; | ||||||
| 
 | 
 | ||||||
|                 command.subcommands.forEach((subcmd, subtag) => { |                 for (const [tag, subcommand] of result.keyedSubcommandInfo) { | ||||||
|                     // Don't capture duplicates generated from aliases.
 |                     const customUsage = subcommand.usage ? ` ${subcommand.usage}` : ""; | ||||||
|                     if (subcmd.originalCommandName === subtag) { |                     list.push(`- \`${header} ${tag}${customUsage}\` - ${subcommand.description}`); | ||||||
|                         const customUsage = subcmd.usage ? ` ${subcmd.usage}` : ""; |                 } | ||||||
|                         list.push(`- \`${header} ${subtag}${customUsage}\` - ${subcmd.description}`); |  | ||||||
|                     } |  | ||||||
|                 }); |  | ||||||
| 
 | 
 | ||||||
|                 const addDynamicType = (cmd: Command | null, type: string) => { |                 for (const [type, subcommand] of result.subcommandInfo) { | ||||||
|                     if (cmd) { |                     const customUsage = subcommand.usage ? ` ${subcommand.usage}` : ""; | ||||||
|                         const customUsage = cmd.usage ? ` ${cmd.usage}` : ""; |                     list.push(`- \`${header} ${type}${customUsage}\` - ${subcommand.description}`); | ||||||
|                         list.push(`- \`${header} <${type}>${customUsage}\` - ${cmd.description}`); |                 } | ||||||
|                     } |  | ||||||
|                 }; |  | ||||||
| 
 |  | ||||||
|                 addDynamicType(command.user, "user"); |  | ||||||
|                 addDynamicType(command.number, "number"); |  | ||||||
|                 addDynamicType(command.any, "any"); |  | ||||||
| 
 | 
 | ||||||
|                 append = "Usages:" + (list.length > 0 ? `\n${list.join("\n")}` : " None."); |                 append = "Usages:" + (list.length > 0 ? `\n${list.join("\n")}` : " None."); | ||||||
|             } else append = `Usage: \`${header} ${usage}\``; |             } else { | ||||||
|  |                 append = `Usage: \`${header} ${command.usage}\``; | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             const formattedAliases: string[] = []; |             let aliases = "N/A"; | ||||||
|             for (const alias of command.aliases) formattedAliases.push(`\`${alias}\``); |  | ||||||
|             // Short circuit an empty string, in this case, if there are no aliases.
 |  | ||||||
|             const aliases = formattedAliases.join(", ") || "None"; |  | ||||||
| 
 | 
 | ||||||
|             $.channel.send( |             if (command instanceof NamedCommand) { | ||||||
|                 `Command: \`${header}\`\nAliases: ${aliases}\nCategory: \`${selectedCategory}\`\nPermission Required: \`${getPermissionName( |                 const formattedAliases: string[] = []; | ||||||
|                     permLevel |                 for (const alias of command.aliases) formattedAliases.push(`\`${alias}\``); | ||||||
|                 )}\` (${permLevel})\nDescription: ${command.description}\n${append}`, |                 // Short circuit an empty string, in this case, if there are no aliases.
 | ||||||
|  |                 aliases = formattedAliases.join(", ") || "None"; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return $.channel.send( | ||||||
|  |                 `Command: \`${header}\`\nAliases: ${aliases}\nCategory: \`${category}\`\nPermission Required: \`${getPermissionName( | ||||||
|  |                     result.permission | ||||||
|  |                 )}\` (${result.permission})\nDescription: ${command.description}\n${append}`, | ||||||
|                 {split: true} |                 {split: true} | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| import {parseVars, requireAllCasesHandledFor} from "./lib"; | import {parseVars} from "./lib"; | ||||||
| import {Collection} from "discord.js"; | import {Collection} from "discord.js"; | ||||||
| import {Client, Message, TextChannel, DMChannel, NewsChannel, Guild, User, GuildMember, GuildChannel} from "discord.js"; | import {Client, Message, TextChannel, DMChannel, NewsChannel, Guild, User, GuildMember, GuildChannel} from "discord.js"; | ||||||
| import {getPrefix} from "../core/structures"; | import {getPrefix} from "../core/structures"; | ||||||
|  | @ -82,6 +82,36 @@ interface ExecuteCommandMetadata { | ||||||
|     channelType: CHANNEL_TYPE; |     channelType: CHANNEL_TYPE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | interface CommandInfo { | ||||||
|  |     readonly type: "info"; | ||||||
|  |     readonly command: Command; | ||||||
|  |     readonly subcommandInfo: Collection<string, Command>; | ||||||
|  |     readonly keyedSubcommandInfo: Collection<string, NamedCommand>; | ||||||
|  |     readonly permission: number; | ||||||
|  |     readonly nsfw: boolean; | ||||||
|  |     readonly channelType: CHANNEL_TYPE; | ||||||
|  |     readonly args: string[]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | interface CommandInfoError { | ||||||
|  |     readonly type: "error"; | ||||||
|  |     readonly message: string; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | interface CommandInfoMetadata { | ||||||
|  |     permission: number; | ||||||
|  |     nsfw: boolean; | ||||||
|  |     channelType: CHANNEL_TYPE; | ||||||
|  |     args: string[]; | ||||||
|  |     usage: string; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export const defaultMetadata = { | ||||||
|  |     permission: 0, | ||||||
|  |     nsfw: false, | ||||||
|  |     channelType: CHANNEL_TYPE.ANY | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| export class Command { | export class Command { | ||||||
|     public readonly description: string; |     public readonly description: string; | ||||||
|     public readonly endpoint: boolean; |     public readonly endpoint: boolean; | ||||||
|  | @ -90,7 +120,7 @@ export class Command { | ||||||
|     public readonly nsfw: boolean | null; // null (default) indicates to inherit
 |     public readonly nsfw: boolean | null; // null (default) indicates to inherit
 | ||||||
|     public readonly channelType: CHANNEL_TYPE | null; // null (default) indicates to inherit
 |     public readonly channelType: CHANNEL_TYPE | null; // null (default) indicates to inherit
 | ||||||
|     protected run: (($: CommandMenu) => Promise<any>) | string; |     protected run: (($: CommandMenu) => Promise<any>) | string; | ||||||
|     protected readonly subcommands: Collection<string, Command>; // This is the final data structure you'll actually use to work with the commands the aliases point to.
 |     protected readonly subcommands: Collection<string, NamedCommand>; // This is the final data structure you'll actually use to work with the commands the aliases point to.
 | ||||||
|     protected user: Command | null; |     protected user: Command | null; | ||||||
|     protected number: Command | null; |     protected number: Command | null; | ||||||
|     protected any: Command | null; |     protected any: Command | null; | ||||||
|  | @ -124,7 +154,7 @@ export class Command { | ||||||
|                 // This shouldn't be a problem because I'm hoping that JS stores these as references that point to the same object.
 |                 // This shouldn't be a problem because I'm hoping that JS stores these as references that point to the same object.
 | ||||||
|                 for (const name in options.subcommands) { |                 for (const name in options.subcommands) { | ||||||
|                     const subcmd = options.subcommands[name]; |                     const subcmd = options.subcommands[name]; | ||||||
|                     subcmd.originalCommandName = name; |                     subcmd.name = name; | ||||||
|                     const aliases = subcmd.aliases; |                     const aliases = subcmd.aliases; | ||||||
| 
 | 
 | ||||||
|                     for (const alias of aliases) { |                     for (const alias of aliases) { | ||||||
|  | @ -153,7 +183,7 @@ export class Command { | ||||||
|         const param = args.shift(); |         const param = args.shift(); | ||||||
| 
 | 
 | ||||||
|         // If there are no arguments left, execute the current command. Otherwise, continue on.
 |         // If there are no arguments left, execute the current command. Otherwise, continue on.
 | ||||||
|         if (!param) { |         if (param === undefined) { | ||||||
|             // See if there is anything that'll prevent the user from executing the command.
 |             // See if there is anything that'll prevent the user from executing the command.
 | ||||||
| 
 | 
 | ||||||
|             // 1. Does this command specify a required channel type? If so, does the channel type match?
 |             // 1. Does this command specify a required channel type? If so, does the channel type match?
 | ||||||
|  | @ -218,13 +248,9 @@ export class Command { | ||||||
|         // If the current command is an endpoint but there are still some arguments left, don't continue.
 |         // If the current command is an endpoint but there are still some arguments left, don't continue.
 | ||||||
|         if (this.endpoint) return {content: "Too many arguments!"}; |         if (this.endpoint) return {content: "Too many arguments!"}; | ||||||
| 
 | 
 | ||||||
|         // If the current command's permission level isn't -1 (inherit), then set the permission metadata equal to that.
 |         // Update inherited properties if the current command specifies a property.
 | ||||||
|         if (this.permission !== -1) metadata.permission = this.permission; |         if (this.permission !== -1) metadata.permission = this.permission; | ||||||
| 
 |  | ||||||
|         // If the current command has an NSFW setting specified, set it.
 |  | ||||||
|         if (this.nsfw !== null) metadata.nsfw = this.nsfw; |         if (this.nsfw !== null) metadata.nsfw = this.nsfw; | ||||||
| 
 |  | ||||||
|         // If the current command doesn't inherit its channel type, set it.
 |  | ||||||
|         if (this.channelType !== null) metadata.channelType = this.channelType; |         if (this.channelType !== null) metadata.channelType = this.channelType; | ||||||
| 
 | 
 | ||||||
|         // Resolve the value of the current command's argument (adding it to the resolved args),
 |         // Resolve the value of the current command's argument (adding it to the resolved args),
 | ||||||
|  | @ -257,11 +283,97 @@ export class Command { | ||||||
|         // Note: Do NOT add a return statement here. In case one of the other sections is missing
 |         // Note: Do NOT add a return statement here. In case one of the other sections is missing
 | ||||||
|         // a return statement, there'll be a compile error to catch that.
 |         // a return statement, there'll be a compile error to catch that.
 | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     // What this does is resolve the resulting subcommand as well as the inherited properties and the available subcommands.
 | ||||||
|  |     public async resolveInfo(args: string[]): Promise<CommandInfo | CommandInfoError> { | ||||||
|  |         return this.resolveInfoInternal(args, {...defaultMetadata, args: [], usage: ""}); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private async resolveInfoInternal( | ||||||
|  |         args: string[], | ||||||
|  |         metadata: CommandInfoMetadata | ||||||
|  |     ): Promise<CommandInfo | CommandInfoError> { | ||||||
|  |         const param = args.shift(); | ||||||
|  | 
 | ||||||
|  |         // If there are no arguments left, return the data or an error message.
 | ||||||
|  |         if (param === undefined) { | ||||||
|  |             const keyedSubcommandInfo = new Collection<string, NamedCommand>(); | ||||||
|  |             const subcommandInfo = new Collection<string, Command>(); | ||||||
|  | 
 | ||||||
|  |             // Get all the subcommands of the current command but without aliases.
 | ||||||
|  |             for (const [tag, command] of this.subcommands.entries()) { | ||||||
|  |                 // Don't capture duplicates generated from aliases.
 | ||||||
|  |                 if (tag === command.name) { | ||||||
|  |                     keyedSubcommandInfo.set(tag, command); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // Then get all the generic subcommands.
 | ||||||
|  |             if (this.user) subcommandInfo.set("<user>", this.user); | ||||||
|  |             if (this.number) subcommandInfo.set("<number>", this.number); | ||||||
|  |             if (this.any) subcommandInfo.set("<any>", this.any); | ||||||
|  | 
 | ||||||
|  |             return { | ||||||
|  |                 type: "info", | ||||||
|  |                 command: this, | ||||||
|  |                 keyedSubcommandInfo, | ||||||
|  |                 subcommandInfo, | ||||||
|  |                 ...metadata | ||||||
|  |             }; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Update inherited properties if the current command specifies a property.
 | ||||||
|  |         if (this.permission !== -1) metadata.permission = this.permission; | ||||||
|  |         if (this.nsfw !== null) metadata.nsfw = this.nsfw; | ||||||
|  |         if (this.channelType !== null) metadata.channelType = this.channelType; | ||||||
|  |         if (this.usage !== "") metadata.usage = this.usage; | ||||||
|  | 
 | ||||||
|  |         // Then test if anything fits any hardcoded values, otherwise check if it's a valid keyed subcommand.
 | ||||||
|  |         if (param === "<user>") { | ||||||
|  |             if (this.user) { | ||||||
|  |                 metadata.args.push("<user>"); | ||||||
|  |                 return this.user.resolveInfoInternal(args, metadata); | ||||||
|  |             } else { | ||||||
|  |                 return { | ||||||
|  |                     type: "error", | ||||||
|  |                     message: `No subcommand found by the argument list: \`${metadata.args.join(" ")}\`` | ||||||
|  |                 }; | ||||||
|  |             } | ||||||
|  |         } else if (param === "<number>") { | ||||||
|  |             if (this.number) { | ||||||
|  |                 metadata.args.push("<number>"); | ||||||
|  |                 return this.number.resolveInfoInternal(args, metadata); | ||||||
|  |             } else { | ||||||
|  |                 return { | ||||||
|  |                     type: "error", | ||||||
|  |                     message: `No subcommand found by the argument list: \`${metadata.args.join(" ")}\`` | ||||||
|  |                 }; | ||||||
|  |             } | ||||||
|  |         } else if (param === "<any>") { | ||||||
|  |             if (this.any) { | ||||||
|  |                 metadata.args.push("<any>"); | ||||||
|  |                 return this.any.resolveInfoInternal(args, metadata); | ||||||
|  |             } else { | ||||||
|  |                 return { | ||||||
|  |                     type: "error", | ||||||
|  |                     message: `No subcommand found by the argument list: \`${metadata.args.join(" ")}\`` | ||||||
|  |                 }; | ||||||
|  |             } | ||||||
|  |         } else if (this.subcommands?.has(param)) { | ||||||
|  |             metadata.args.push(param); | ||||||
|  |             return this.subcommands.get(param)!.resolveInfoInternal(args, metadata); | ||||||
|  |         } else { | ||||||
|  |             return { | ||||||
|  |                 type: "error", | ||||||
|  |                 message: `No subcommand found by the argument list: \`${metadata.args.join(" ")}\`` | ||||||
|  |             }; | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export class NamedCommand extends Command { | export class NamedCommand extends Command { | ||||||
|     public readonly aliases: string[]; // This is to keep the array intact for parent Command instances to use. It'll also be used when loading top-level aliases.
 |     public readonly aliases: string[]; // This is to keep the array intact for parent Command instances to use. It'll also be used when loading top-level aliases.
 | ||||||
|     public originalCommandName: string | null; // If the command is an alias, what's the original name?
 |     private originalCommandName: string | null; // If the command is an alias, what's the original name?
 | ||||||
| 
 | 
 | ||||||
|     constructor(options?: NamedCommandOptions) { |     constructor(options?: NamedCommandOptions) { | ||||||
|         super(options); |         super(options); | ||||||
|  | @ -269,74 +381,14 @@ export class NamedCommand extends Command { | ||||||
|         this.originalCommandName = null; |         this.originalCommandName = null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Returns: [category, command name, command, available subcommands: [type, subcommand]]
 |     public get name(): string { | ||||||
|     public async resolveInfo(args: string[]): [string, string, Command, Collection<string, Command>] | null { |         if (this.originalCommandName === null) throw new Error("originalCommandName must be set before accessing it!"); | ||||||
|         // For debug info, use this.originalCommandName? (if it exists?)
 |         else return this.originalCommandName; | ||||||
|         const commands = await loadableCommands; |     } | ||||||
|         let header = args.shift(); |  | ||||||
|         let command = commands.get(header); |  | ||||||
| 
 | 
 | ||||||
|         if (!command || header === "test") { |     public set name(value: string) { | ||||||
|             $.channel.send(`No command found by the name \`${header}\`!`); |         if (this.originalCommandName !== null) | ||||||
|             return; |             throw new Error(`originalCommandName cannot be set twice! Attempted to set the value to "${value}".`); | ||||||
|         } |         else this.originalCommandName = value; | ||||||
| 
 |  | ||||||
|         if (command.originalCommandName) header = command.originalCommandName; |  | ||||||
|         else console.warn(`originalCommandName isn't defined for ${header}?!`); |  | ||||||
| 
 |  | ||||||
|         let permLevel = command.permission ?? 0; |  | ||||||
|         let usage = command.usage; |  | ||||||
|         let invalid = false; |  | ||||||
| 
 |  | ||||||
|         let selectedCategory = "Unknown"; |  | ||||||
| 
 |  | ||||||
|         for (const [category, headers] of categories) { |  | ||||||
|             if (headers.includes(header)) { |  | ||||||
|                 if (selectedCategory !== "Unknown") |  | ||||||
|                     console.warn( |  | ||||||
|                         `Command "${header}" is somehow in multiple categories. This means that the command loading stage probably failed in properly adding categories.` |  | ||||||
|                     ); |  | ||||||
|                 else selectedCategory = toTitleCase(category); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         for (const param of args) { |  | ||||||
|             const type = command.resolve(param); |  | ||||||
|             command = command.get(param); |  | ||||||
|             permLevel = command.permission ?? permLevel; |  | ||||||
| 
 |  | ||||||
|             if (permLevel === -1) permLevel = command.permission; |  | ||||||
| 
 |  | ||||||
|             // Switch over to doing `$help info <user>`
 |  | ||||||
|             switch (type) { |  | ||||||
|                 case TYPES.SUBCOMMAND: |  | ||||||
|                     header += ` ${command.originalCommandName}`; |  | ||||||
|                     break; |  | ||||||
|                 case TYPES.USER: |  | ||||||
|                     header += " <user>"; |  | ||||||
|                     break; |  | ||||||
|                 case TYPES.NUMBER: |  | ||||||
|                     header += " <number>"; |  | ||||||
|                     break; |  | ||||||
|                 case TYPES.ANY: |  | ||||||
|                     header += " <any>"; |  | ||||||
|                     break; |  | ||||||
|                 case TYPES.NONE: |  | ||||||
|                     header += ` ${param}`; |  | ||||||
|                     break; |  | ||||||
|                 default: |  | ||||||
|                     requireAllCasesHandledFor(type); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if (type === TYPES.NONE) { |  | ||||||
|                 invalid = true; |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (invalid) { |  | ||||||
|             $.channel.send(`No command found by the name \`${header}\`!`); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ import {loadableCommands} from "./loader"; | ||||||
| import {Permissions, Message} from "discord.js"; | import {Permissions, Message} from "discord.js"; | ||||||
| import {getPrefix} from "./structures"; | import {getPrefix} from "./structures"; | ||||||
| import {Config} from "./structures"; | import {Config} from "./structures"; | ||||||
| import {CHANNEL_TYPE} from "./command"; | import {defaultMetadata} from "./command"; | ||||||
| 
 | 
 | ||||||
| // For custom message events that want to cancel the command handler on certain conditions.
 | // For custom message events that want to cancel the command handler on certain conditions.
 | ||||||
| const interceptRules: ((message: Message) => boolean)[] = [(message) => message.author.bot]; | const interceptRules: ((message: Message) => boolean)[] = [(message) => message.author.bot]; | ||||||
|  | @ -12,12 +12,6 @@ export function addInterceptRule(handler: (message: Message) => boolean) { | ||||||
|     interceptRules.push(handler); |     interceptRules.push(handler); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const defaultMetadata = { |  | ||||||
|     permission: 0, |  | ||||||
|     nsfw: false, |  | ||||||
|     channelType: CHANNEL_TYPE.ANY |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| // Note: client.user is only undefined before the bot logs in, so by this point, client.user cannot be undefined.
 | // Note: client.user is only undefined before the bot logs in, so by this point, client.user cannot be undefined.
 | ||||||
| // Note: guild.available will never need to be checked because the message starts in either a DM channel or an already-available guild.
 | // Note: guild.available will never need to be checked because the message starts in either a DM channel or an already-available guild.
 | ||||||
| client.on("message", async (message) => { | client.on("message", async (message) => { | ||||||
|  | @ -51,7 +45,7 @@ client.on("message", async (message) => { | ||||||
|             // Send the arguments to the command to resolve and execute.
 |             // Send the arguments to the command to resolve and execute.
 | ||||||
|             const result = await command.execute(args, menu, { |             const result = await command.execute(args, menu, { | ||||||
|                 header, |                 header, | ||||||
|                 args, |                 args: [...args], | ||||||
|                 ...defaultMetadata |                 ...defaultMetadata | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|  | @ -83,7 +77,7 @@ client.on("message", async (message) => { | ||||||
|                 // Send the arguments to the command to resolve and execute.
 |                 // Send the arguments to the command to resolve and execute.
 | ||||||
|                 const result = await command.execute(args, menu, { |                 const result = await command.execute(args, menu, { | ||||||
|                     header, |                     header, | ||||||
|                     args, |                     args: [...args], | ||||||
|                     ...defaultMetadata |                     ...defaultMetadata | ||||||
|                 }); |                 }); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -31,7 +31,7 @@ export const loadableCommands = (async () => { | ||||||
|             const command = (await import(`../commands/${commandID}`)).default as unknown; |             const command = (await import(`../commands/${commandID}`)).default as unknown; | ||||||
| 
 | 
 | ||||||
|             if (command instanceof NamedCommand) { |             if (command instanceof NamedCommand) { | ||||||
|                 command.originalCommandName = commandName; |                 command.name = commandName; | ||||||
| 
 | 
 | ||||||
|                 if (commands.has(commandName)) { |                 if (commands.has(commandName)) { | ||||||
|                     console.warn( |                     console.warn( | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue