mirror of
				https://github.com/keanuplayz/TravBot-v3.git
				synced 2024-08-15 02:33:12 +00:00 
			
		
		
		
	Removed lenient command handling
This commit is contained in:
		
							parent
							
								
									15012c7d17
								
							
						
					
					
						commit
						3798c27df9
					
				
					 14 changed files with 228 additions and 201 deletions
				
			
		|  | @ -11,7 +11,8 @@ | ||||||
| - Various changes to core | - Various changes to core | ||||||
| 	- Added `guild` subcommand type (only accessible when `id: "guild"`) | 	- Added `guild` subcommand type (only accessible when `id: "guild"`) | ||||||
| 	- Further reduced `channel.send()` to `send()` because it's used in *every, single, command* | 	- Further reduced `channel.send()` to `send()` because it's used in *every, single, command* | ||||||
| 	- Added `rest` subcommand type (only available when `endpoint: true`), declaratively states that the following command will do `args.join(" ")`, preventing any other subcommands from being added | 	- Added a `RestCommand` type, declaratively states that the following command will do `args.join(" ")`, preventing any other subcommands from being added | ||||||
|  | 	- Is no longer lenient to arguments when no proper subcommand fits (now it doesn't silently fail anymore), you now have to explicitly declare a `RestCommand` to get an arbitrary number of arguments | ||||||
| 
 | 
 | ||||||
| # 3.2.0 - Internal refactor, more subcommand types, and more command type guards (2021-04-09) | # 3.2.0 - Internal refactor, more subcommand types, and more command type guards (2021-04-09) | ||||||
| - The custom logger changed: `$.log` no longer exists, it's just `console.log`. Now you don't have to do `import $ from "../core/lib"` at the top of every file that uses the custom logger. | - The custom logger changed: `$.log` no longer exists, it's just `console.log`. Now you don't have to do `import $ from "../core/lib"` at the top of every file that uses the custom logger. | ||||||
|  |  | ||||||
|  | @ -26,7 +26,6 @@ const responses = [ | ||||||
| 
 | 
 | ||||||
| export default new NamedCommand({ | export default new NamedCommand({ | ||||||
|     description: "Answers your question in an 8-ball manner.", |     description: "Answers your question in an 8-ball manner.", | ||||||
|     endpoint: false, |  | ||||||
|     usage: "<question>", |     usage: "<question>", | ||||||
|     run: "Please provide a question.", |     run: "Please provide a question.", | ||||||
|     any: new Command({ |     any: new Command({ | ||||||
|  |  | ||||||
|  | @ -62,7 +62,7 @@ export const BetCommand = new NamedCommand({ | ||||||
| 
 | 
 | ||||||
|                         // handle invalid target
 |                         // handle invalid target
 | ||||||
|                         if (target.id == author.id) return send("You can't bet Mons with yourself!"); |                         if (target.id == author.id) return send("You can't bet Mons with yourself!"); | ||||||
|                         else if (target.bot && process.argv[2] !== "dev") return send("You can't bet Mons with a bot!"); |                         else if (target.bot && !IS_DEV_MODE) return send("You can't bet Mons with a bot!"); | ||||||
| 
 | 
 | ||||||
|                         // handle invalid amount
 |                         // handle invalid amount
 | ||||||
|                         if (amount <= 0) return send("You must bet at least one Mon!"); |                         if (amount <= 0) return send("You must bet at least one Mon!"); | ||||||
|  |  | ||||||
|  | @ -128,7 +128,7 @@ export const PayCommand = new NamedCommand({ | ||||||
|                     else if (sender.money < amount) |                     else if (sender.money < amount) | ||||||
|                         return send("You don't have enough Mons for that.", getMoneyEmbed(author)); |                         return send("You don't have enough Mons for that.", getMoneyEmbed(author)); | ||||||
|                     else if (target.id === author.id) return send("You can't send Mons to yourself!"); |                     else if (target.id === author.id) return send("You can't send Mons to yourself!"); | ||||||
|                     else if (target.bot && process.argv[2] !== "dev") return send("You can't send Mons to a bot!"); |                     else if (target.bot && !IS_DEV_MODE) return send("You can't send Mons to a bot!"); | ||||||
| 
 | 
 | ||||||
|                     sender.money -= amount; |                     sender.money -= amount; | ||||||
|                     receiver.money += amount; |                     receiver.money += amount; | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| import {Command, NamedCommand} from "../../core"; | import {Command, NamedCommand, RestCommand} from "../../core"; | ||||||
| 
 | 
 | ||||||
| const letters: {[letter: string]: string[]} = { | const letters: {[letter: string]: string[]} = { | ||||||
|     a: "aáàảãạâấầẩẫậăắằẳẵặ".split(""), |     a: "aáàảãạâấầẩẫậăắằẳẵặ".split(""), | ||||||
|  | @ -35,7 +35,6 @@ export default new NamedCommand({ | ||||||
|     description: "Transforms your text into vietnamese.", |     description: "Transforms your text into vietnamese.", | ||||||
|     usage: "thonk ([text])", |     usage: "thonk ([text])", | ||||||
|     async run({send, message, channel, guild, author, member, client, args}) { |     async run({send, message, channel, guild, author, member, client, args}) { | ||||||
|         if (args.length > 0) phrase = args.join(" "); |  | ||||||
|         const msg = await send(transform(phrase)); |         const msg = await send(transform(phrase)); | ||||||
|         msg.createReactionCollector( |         msg.createReactionCollector( | ||||||
|             (reaction, user) => { |             (reaction, user) => { | ||||||
|  | @ -44,5 +43,17 @@ export default new NamedCommand({ | ||||||
|             }, |             }, | ||||||
|             {time: 60000} |             {time: 60000} | ||||||
|         ); |         ); | ||||||
|  |     }, | ||||||
|  |     any: new RestCommand({ | ||||||
|  |         async run({send, message, channel, guild, author, member, client, args, combined}) { | ||||||
|  |             const msg = await send(transform(combined)); | ||||||
|  |             msg.createReactionCollector( | ||||||
|  |                 (reaction, user) => { | ||||||
|  |                     if (user.id === author.id && reaction.emoji.name === "❌") msg.delete(); | ||||||
|  |                     return false; | ||||||
|  |                 }, | ||||||
|  |                 {time: 60000} | ||||||
|  |             ); | ||||||
|         } |         } | ||||||
|  |     }) | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -293,7 +293,7 @@ export default new NamedCommand({ | ||||||
|                 }); |                 }); | ||||||
|                 send("Activity set to default."); |                 send("Activity set to default."); | ||||||
|             }, |             }, | ||||||
|             any: new Command({ |             any: new RestCommand({ | ||||||
|                 description: `Select an activity type to set. Available levels: \`[${activities.join(", ")}]\``, |                 description: `Select an activity type to set. Available levels: \`[${activities.join(", ")}]\``, | ||||||
|                 async run({send, message, channel, guild, author, member, client, args}) { |                 async run({send, message, channel, guild, author, member, client, args}) { | ||||||
|                     const type = args[0]; |                     const type = args[0]; | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| import {Command, NamedCommand} from "../core"; | import {Command, NamedCommand, RestCommand} from "../core"; | ||||||
| 
 | 
 | ||||||
| export default new NamedCommand({ | export default new NamedCommand({ | ||||||
|     async run({send, message, channel, guild, author, member, client, args}) { |     async run({send, message, channel, guild, author, member, client, args}) { | ||||||
|  |  | ||||||
|  | @ -1,11 +1,11 @@ | ||||||
| import {Command, NamedCommand} from "../../core"; | import {Command, NamedCommand, RestCommand} from "../../core"; | ||||||
| import {processEmoteQueryFormatted} from "./modules/emote-utils"; | import {processEmoteQueryFormatted} from "./modules/emote-utils"; | ||||||
| 
 | 
 | ||||||
| export default new NamedCommand({ | export default new NamedCommand({ | ||||||
|     description: |     description: | ||||||
|         "Send the specified emote list. Enter + to move an emote list to the next line, - to add a space, and _ to add a zero-width space.", |         "Send the specified emote list. Enter + to move an emote list to the next line, - to add a space, and _ to add a zero-width space.", | ||||||
|     run: "Please provide a list of emotes.", |     run: "Please provide a list of emotes.", | ||||||
|     any: new Command({ |     any: new RestCommand({ | ||||||
|         description: "The emote(s) to send.", |         description: "The emote(s) to send.", | ||||||
|         usage: "<emotes...>", |         usage: "<emotes...>", | ||||||
|         async run({send, guild, channel, message, args}) { |         async run({send, guild, channel, message, args}) { | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| import {GuildEmoji, MessageEmbed, User} from "discord.js"; | import {GuildEmoji, MessageEmbed, User} from "discord.js"; | ||||||
| import {Command, NamedCommand, paginate, SendFunction} from "../../core"; | import {Command, NamedCommand, RestCommand, paginate, SendFunction} from "../../core"; | ||||||
| import {split} from "../../lib"; | import {split} from "../../lib"; | ||||||
| import vm from "vm"; | import vm from "vm"; | ||||||
| 
 | 
 | ||||||
|  | @ -11,7 +11,7 @@ export default new NamedCommand({ | ||||||
|     async run({send, message, channel, guild, author, member, client, args}) { |     async run({send, message, channel, guild, author, member, client, args}) { | ||||||
|         displayEmoteList(client.emojis.cache.array(), send, author); |         displayEmoteList(client.emojis.cache.array(), send, author); | ||||||
|     }, |     }, | ||||||
|     any: new Command({ |     any: new RestCommand({ | ||||||
|         description: |         description: | ||||||
|             "Filters emotes by via a regular expression. Flags can be added by adding a dash at the end. For example, to do a case-insensitive search, do %prefix%lsemotes somepattern -i", |             "Filters emotes by via a regular expression. Flags can be added by adding a dash at the end. For example, to do a case-insensitive search, do %prefix%lsemotes somepattern -i", | ||||||
|         async run({send, message, channel, guild, author, member, client, args}) { |         async run({send, message, channel, guild, author, member, client, args}) { | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| import {Command, NamedCommand} from "../../core"; | import {Command, NamedCommand, RestCommand} from "../../core"; | ||||||
| import {Message, Channel, TextChannel} from "discord.js"; | import {Message, Channel, TextChannel} from "discord.js"; | ||||||
| import {processEmoteQueryArray} from "./modules/emote-utils"; | import {processEmoteQueryArray} from "./modules/emote-utils"; | ||||||
| 
 | 
 | ||||||
|  | @ -6,6 +6,8 @@ export default new NamedCommand({ | ||||||
|     description: |     description: | ||||||
|         "Reacts to the a previous message in your place. You have to react with the same emote before the bot removes that reaction.", |         "Reacts to the a previous message in your place. You have to react with the same emote before the bot removes that reaction.", | ||||||
|     usage: 'react <emotes...> (<distance / message ID / "Copy ID" / "Copy Message Link">)', |     usage: 'react <emotes...> (<distance / message ID / "Copy ID" / "Copy Message Link">)', | ||||||
|  |     run: "You need to enter some emotes first.", | ||||||
|  |     any: new RestCommand({ | ||||||
|         async run({send, message, channel, guild, author, member, client, args}) { |         async run({send, message, channel, guild, author, member, client, args}) { | ||||||
|             let target: Message | undefined; |             let target: Message | undefined; | ||||||
|             let distance = 1; |             let distance = 1; | ||||||
|  | @ -111,4 +113,5 @@ export default new NamedCommand({ | ||||||
| 
 | 
 | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |     }) | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| import {Command, NamedCommand} from "../../core"; | import {Command, NamedCommand, RestCommand} from "../../core"; | ||||||
| import {streamList} from "../../modules/streamNotifications"; | import {streamList} from "../../modules/streamNotifications"; | ||||||
| 
 | 
 | ||||||
| export default new NamedCommand({ | export default new NamedCommand({ | ||||||
|  | @ -8,12 +8,30 @@ export default new NamedCommand({ | ||||||
| 
 | 
 | ||||||
|         if (streamList.has(userID)) { |         if (streamList.has(userID)) { | ||||||
|             const stream = streamList.get(userID)!; |             const stream = streamList.get(userID)!; | ||||||
|             const description = args.join(" ") || "No description set."; |             stream.description = "No description set."; | ||||||
|             stream.description = description; |  | ||||||
|             stream.update(); |             stream.update(); | ||||||
|             send(`Successfully set the stream description to:`, { |             send(`Successfully set the stream description to:`, { | ||||||
|                 embed: { |                 embed: { | ||||||
|                     description, |                     description: "No description set.", | ||||||
|  |                     color: member!.displayColor | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  |         } else { | ||||||
|  |             // Alternatively, I could make descriptions last outside of just one stream.
 | ||||||
|  |             send("You can only use this command when streaming."); | ||||||
|  |         } | ||||||
|  |     }, | ||||||
|  |     any: new RestCommand({ | ||||||
|  |         async run({send, message, channel, guild, author, member, client, args, combined}) { | ||||||
|  |             const userID = author.id; | ||||||
|  | 
 | ||||||
|  |             if (streamList.has(userID)) { | ||||||
|  |                 const stream = streamList.get(userID)!; | ||||||
|  |                 stream.description = combined; | ||||||
|  |                 stream.update(); | ||||||
|  |                 send(`Successfully set the stream description to:`, { | ||||||
|  |                     embed: { | ||||||
|  |                         description: stream.description, | ||||||
|                         color: member!.displayColor |                         color: member!.displayColor | ||||||
|                     } |                     } | ||||||
|                 }); |                 }); | ||||||
|  | @ -22,4 +40,5 @@ export default new NamedCommand({ | ||||||
|                 send("You can only use this command when streaming."); |                 send("You can only use this command when streaming."); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |     }) | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -1,9 +1,13 @@ | ||||||
| import {Command, NamedCommand} from "../../core"; | import {Command, NamedCommand, RestCommand} from "../../core"; | ||||||
| import translate from "translate-google"; | import translate from "translate-google"; | ||||||
| 
 | 
 | ||||||
| export default new NamedCommand({ | export default new NamedCommand({ | ||||||
|     description: "Translates your input.", |     description: "Translates your input.", | ||||||
|     usage: "<lang ID> <input>", |     usage: "<lang ID> <input>", | ||||||
|  |     run: "You need to specify a language to translate to.", | ||||||
|  |     any: new Command({ | ||||||
|  |         run: "You need to enter some text to translate.", | ||||||
|  |         any: new RestCommand({ | ||||||
|             async run({send, message, channel, guild, author, member, client, args}) { |             async run({send, message, channel, guild, author, member, client, args}) { | ||||||
|                 const lang = args[0]; |                 const lang = args[0]; | ||||||
|                 const input = args.slice(1).join(" "); |                 const input = args.slice(1).join(" "); | ||||||
|  | @ -29,7 +33,11 @@ export default new NamedCommand({ | ||||||
|                     }) |                     }) | ||||||
|                     .catch((error) => { |                     .catch((error) => { | ||||||
|                         console.error(error); |                         console.error(error); | ||||||
|                 send(`${error}\nPlease use the following list: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes`); |                         send( | ||||||
|  |                             `${error}\nPlease use the following list: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes` | ||||||
|  |                         ); | ||||||
|                     }); |                     }); | ||||||
|             } |             } | ||||||
|  |         }) | ||||||
|  |     }) | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -73,23 +73,15 @@ interface CommandMenu { | ||||||
| 
 | 
 | ||||||
| interface CommandOptionsBase { | interface CommandOptionsBase { | ||||||
|     readonly description?: string; |     readonly description?: string; | ||||||
|     readonly endpoint?: boolean; |  | ||||||
|     readonly usage?: string; |     readonly usage?: string; | ||||||
|     readonly permission?: number; |     readonly permission?: number; | ||||||
|     readonly nsfw?: boolean; |     readonly nsfw?: boolean; | ||||||
|     readonly channelType?: CHANNEL_TYPE; |     readonly channelType?: CHANNEL_TYPE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| interface CommandOptionsEndpoint { |  | ||||||
|     readonly endpoint: true; |  | ||||||
|     readonly run?: (($: CommandMenu) => Promise<any>) | string; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Prevents subcommands from being added by compile-time.
 |  | ||||||
| // Also, contrary to what you might think, channel pings do still work in DM channels.
 | // Also, contrary to what you might think, channel pings do still work in DM channels.
 | ||||||
| // Role pings, maybe not, but it's not a big deal.
 | // Role pings, maybe not, but it's not a big deal.
 | ||||||
| interface CommandOptionsNonEndpoint { | interface CommandOptions extends CommandOptionsBase { | ||||||
|     readonly endpoint?: false; |  | ||||||
|     readonly run?: (($: CommandMenu) => Promise<any>) | string; |     readonly run?: (($: CommandMenu) => Promise<any>) | string; | ||||||
|     readonly subcommands?: {[key: string]: NamedCommand}; |     readonly subcommands?: {[key: string]: NamedCommand}; | ||||||
|     readonly channel?: Command; |     readonly channel?: Command; | ||||||
|  | @ -103,11 +95,14 @@ interface CommandOptionsNonEndpoint { | ||||||
|     readonly any?: Command | RestCommand; |     readonly any?: Command | RestCommand; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type CommandOptions = CommandOptionsBase & (CommandOptionsEndpoint | CommandOptionsNonEndpoint); | interface NamedCommandOptions extends CommandOptions { | ||||||
| type NamedCommandOptions = CommandOptions & {aliases?: string[]; nameOverride?: string}; |     readonly aliases?: string[]; | ||||||
| type RestCommandOptions = CommandOptionsBase & { |     readonly nameOverride?: string; | ||||||
|     run?: (($: CommandMenu & {readonly combined: string}) => Promise<any>) | string; | } | ||||||
| }; | 
 | ||||||
|  | interface RestCommandOptions extends CommandOptionsBase { | ||||||
|  |     readonly run?: (($: CommandMenu & {readonly combined: string}) => Promise<any>) | string; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| interface ExecuteCommandMetadata { | interface ExecuteCommandMetadata { | ||||||
|     readonly header: string; |     readonly header: string; | ||||||
|  | @ -164,7 +159,6 @@ abstract class BaseCommand { | ||||||
| 
 | 
 | ||||||
| // Each Command instance represents a block that links other Command instances under it.
 | // Each Command instance represents a block that links other Command instances under it.
 | ||||||
| export class Command extends BaseCommand { | export class Command extends BaseCommand { | ||||||
|     public readonly endpoint: boolean; |  | ||||||
|     // The execute and subcommand properties are restricted to the class because subcommand recursion could easily break when manually handled.
 |     // The execute and subcommand properties are restricted to the class because subcommand recursion could easily break when manually handled.
 | ||||||
|     // The class will handle checking for null fields.
 |     // The class will handle checking for null fields.
 | ||||||
|     private run: (($: CommandMenu) => Promise<any>) | string; |     private run: (($: CommandMenu) => Promise<any>) | string; | ||||||
|  | @ -182,31 +176,20 @@ export class Command extends BaseCommand { | ||||||
| 
 | 
 | ||||||
|     constructor(options?: CommandOptions) { |     constructor(options?: CommandOptions) { | ||||||
|         super(options); |         super(options); | ||||||
|         this.endpoint = !!options?.endpoint; |  | ||||||
|         this.run = options?.run || "No action was set on this command!"; |         this.run = options?.run || "No action was set on this command!"; | ||||||
|         this.subcommands = new Collection(); // Populate this collection after setting subcommands.
 |         this.subcommands = new Collection(); // Populate this collection after setting subcommands.
 | ||||||
|         this.channel = null; |         this.channel = options?.channel || null; | ||||||
|         this.role = null; |         this.role = options?.role || null; | ||||||
|         this.emote = null; |         this.emote = options?.emote || null; | ||||||
|         this.message = null; |         this.message = options?.message || null; | ||||||
|         this.user = null; |         this.user = options?.user || null; | ||||||
|         this.guild = null; |         this.guild = options?.guild || null; | ||||||
|         this.id = null; |         this.id = null; | ||||||
|         this.idType = null; |         this.idType = options?.id || null; | ||||||
|         this.number = null; |         this.number = options?.number || null; | ||||||
|         this.any = null; |         this.any = options?.any || null; | ||||||
| 
 |  | ||||||
|         if (options && !options.endpoint) { |  | ||||||
|             if (options.channel) this.channel = options.channel; |  | ||||||
|             if (options.role) this.role = options.role; |  | ||||||
|             if (options.emote) this.emote = options.emote; |  | ||||||
|             if (options.message) this.message = options.message; |  | ||||||
|             if (options.user) this.user = options.user; |  | ||||||
|             if (options.guild) this.guild = options.guild; |  | ||||||
|             if (options.number) this.number = options.number; |  | ||||||
|             if (options.any) this.any = options.any; |  | ||||||
|             if (options.id) this.idType = options.id; |  | ||||||
| 
 | 
 | ||||||
|  |         if (options) | ||||||
|             switch (options.id) { |             switch (options.id) { | ||||||
|                 case "channel": |                 case "channel": | ||||||
|                     this.id = this.channel; |                     this.id = this.channel; | ||||||
|  | @ -232,7 +215,7 @@ export class Command extends BaseCommand { | ||||||
|                     requireAllCasesHandledFor(options.id); |                     requireAllCasesHandledFor(options.id); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (options.subcommands) { |         if (options?.subcommands) { | ||||||
|             const baseSubcommands = Object.keys(options.subcommands); |             const baseSubcommands = Object.keys(options.subcommands); | ||||||
| 
 | 
 | ||||||
|             // Loop once to set the base subcommands.
 |             // Loop once to set the base subcommands.
 | ||||||
|  | @ -259,7 +242,6 @@ export class Command extends BaseCommand { | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     // Go through the arguments provided and find the right subcommand, then execute with the given arguments.
 |     // Go through the arguments provided and find the right subcommand, then execute with the given arguments.
 | ||||||
|     // Will return null if it successfully executes, SingleMessageOptions if there's an error (to let the user know what it is).
 |     // Will return null if it successfully executes, SingleMessageOptions if there's an error (to let the user know what it is).
 | ||||||
|  | @ -319,9 +301,6 @@ export class Command extends BaseCommand { | ||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // If the current command is an endpoint but there are still some arguments left, don't continue unless there's a RestCommand.
 |  | ||||||
|         if (this.endpoint) return {content: "Too many arguments!"}; |  | ||||||
| 
 |  | ||||||
|         // 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),
 | ||||||
|         // then pass the thread of execution to whichever subcommand is valid (if any).
 |         // then pass the thread of execution to whichever subcommand is valid (if any).
 | ||||||
|         const isMessageLink = patterns.messageLink.test(param); |         const isMessageLink = patterns.messageLink.test(param); | ||||||
|  | @ -506,11 +485,15 @@ export class Command extends BaseCommand { | ||||||
|         } else if (this.any instanceof RestCommand) { |         } else if (this.any instanceof RestCommand) { | ||||||
|             metadata.symbolicArgs.push("<...>"); |             metadata.symbolicArgs.push("<...>"); | ||||||
|             args.unshift(param); |             args.unshift(param); | ||||||
|  |             menu.args.push(...args); | ||||||
|             return this.any.execute(args.join(" "), menu, metadata); |             return this.any.execute(args.join(" "), menu, metadata); | ||||||
|         } else { |         } else { | ||||||
|             // Continue adding on the rest of the arguments if there's no valid subcommand.
 |             metadata.symbolicArgs.push(`"${param}"`); | ||||||
|             menu.args.push(param); |             return { | ||||||
|             return this.execute(args, menu, metadata); |                 content: `No valid command sequence matching \`${metadata.header} ${metadata.symbolicArgs.join( | ||||||
|  |                     " " | ||||||
|  |                 )}\` found.` | ||||||
|  |             }; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // 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
 | ||||||
|  | @ -726,7 +709,9 @@ export class RestCommand extends BaseCommand { | ||||||
|         } else { |         } else { | ||||||
|             // Then capture any potential errors.
 |             // Then capture any potential errors.
 | ||||||
|             try { |             try { | ||||||
|                 await this.run({...menu, combined}); |                 // Args will still be kept intact. A common pattern is popping some parameters off the end then doing some branching.
 | ||||||
|  |                 // That way, you can still declaratively mark an argument list as continuing while also handling the individual args.
 | ||||||
|  |                 await this.run({...menu, args: menu.args, combined}); | ||||||
|             } catch (error) { |             } catch (error) { | ||||||
|                 const errorMessage = error.stack ?? error; |                 const errorMessage = error.stack ?? error; | ||||||
|                 console.error(`Command Error: ${metadata.header} (${metadata.args.join(", ")})\n${errorMessage}`); |                 console.error(`Command Error: ${metadata.header} (${metadata.args.join(", ")})\n${errorMessage}`); | ||||||
|  |  | ||||||
|  | @ -21,8 +21,7 @@ const lastCommandInfo: { | ||||||
| const defaultMetadata = { | const defaultMetadata = { | ||||||
|     permission: 0, |     permission: 0, | ||||||
|     nsfw: false, |     nsfw: false, | ||||||
|     channelType: 0, // CHANNEL_TYPE.ANY, apparently isn't initialized at this point yet
 |     channelType: 0 // CHANNEL_TYPE.ANY, apparently isn't initialized at this point yet
 | ||||||
|     symbolicArgs: [] |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // 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.
 | ||||||
|  | @ -67,7 +66,8 @@ export function attachMessageHandlerToClient(client: Client) { | ||||||
|                 const result = await command.execute(args, menu, { |                 const result = await command.execute(args, menu, { | ||||||
|                     header, |                     header, | ||||||
|                     args: [...args], |                     args: [...args], | ||||||
|                     ...defaultMetadata |                     ...defaultMetadata, | ||||||
|  |                     symbolicArgs: [] | ||||||
|                 }); |                 }); | ||||||
| 
 | 
 | ||||||
|                 // If something went wrong, let the user know (like if they don't have permission to use a command).
 |                 // If something went wrong, let the user know (like if they don't have permission to use a command).
 | ||||||
|  | @ -104,7 +104,8 @@ export function attachMessageHandlerToClient(client: Client) { | ||||||
|                     const result = await command.execute(args, menu, { |                     const result = await command.execute(args, menu, { | ||||||
|                         header, |                         header, | ||||||
|                         args: [...args], |                         args: [...args], | ||||||
|                         ...defaultMetadata |                         ...defaultMetadata, | ||||||
|  |                         symbolicArgs: [] | ||||||
|                     }); |                     }); | ||||||
| 
 | 
 | ||||||
|                     // If something went wrong, let the user know (like if they don't have permission to use a command).
 |                     // If something went wrong, let the user know (like if they don't have permission to use a command).
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue