import { Command , CommandContext , SlashCommandContext , } from "../../base/Command" ; import { ApplicationCommandOption , MessageEmbed , PermissionResolvable , Permissions , } from "discord.js" ; import { sendReply } from "../../utils/functions" ; import { stripIndents } from "common-tags" ; export default class Help implements Command { name = "help" ; aliases = [ "h" , "commands" ] ; category = "info" ; description = "Displays all commands, or detailed info about a specific command." ; usage = "help [command | alias]" ; enabled = true ; slashCommandEnabled = true ; guildOnly = false ; botPermissions : PermissionResolvable [ ] = [ Permissions . FLAGS . EMBED_LINKS ] ; memberPermissions = [ ] ; ownerOnly = false ; premiumOnly = false ; cooldown = 5000 ; slashDescription = "Displays all commands, or detailed info about a specific command" ; commandOptions : ApplicationCommandOption [ ] = [ { name : "command" , type : "STRING" , description : "The command to get info about" , required : false , } , ] ; async execute ( ctx , args ) { if ( args [ 0 ] ) { const embedMsg = this . getCommand ( ctx , args [ 0 ] ) ; sendReply ( ctx . client , { embeds : [ embedMsg ] } , ctx . msg ) ; return ; } else { const embedMsg = this . getAll ( ctx ) ; sendReply ( ctx . client , { embeds : [ embedMsg ] } , ctx . msg ) ; return ; } } async slashCommandExecute ( ctx ) { const command = ctx . commandInteraction . options . getString ( "command" ) ; if ( command ) { const embedMsg = this . getCommand ( ctx , command ) ; ctx . commandInteraction . reply ( { embeds : [ embedMsg ] } ) ; return ; } else { const embedMsg = this . getAll ( ctx ) ; ctx . commandInteraction . reply ( { embeds : [ embedMsg ] } ) ; return ; } } getAll ( ctx ) { const embedMsg = new MessageEmbed ( ) . setColor ( "RANDOM" ) . setDescription ( "**Commands**" ) ; const commands = ( category ) => { let commands = ctx . client . commands ; if ( ctx instanceof CommandContext ) { commands = commands . filter ( ( cmd ) => cmd . enabled ) ; } else if ( ctx instanceof SlashCommandContext ) { commands = commands . filter ( ( cmd ) => cmd . slashCommandEnabled ) ; } commands = commands . filter ( ( cmd ) => cmd . category === category ) ; if ( ! ctx . guild ) { commands = commands . filter ( ( cmd ) => ! cmd . guildOnly ) ; } if ( ctx . author . id != process . env . OWNERID ) { commands = commands . filter ( ( cmd ) => ! cmd . ownerOnly ) ; } return commands . map ( ( cmd ) => `- \`${ cmd . name }\`` ) . join ( "\n" ) ; } ; ctx . client . categories . sort ( ( a , b ) => { const catgeoryOrder = [ "info" , "moderation" , "music" , "utility" , "fun" , "owner" , ] ; if ( ! catgeoryOrder . includes ( a ) ) return 1 ; else if ( ! catgeoryOrder . includes ( b ) ) return - 1 ; return catgeoryOrder . indexOf ( a ) - catgeoryOrder . indexOf ( b ) ; } ) ; ctx . client . categories . forEach ( ( category ) => { if ( ! commands ( category ) ) return ; embedMsg . addField ( stripIndents `**${ category [ 0 ] . toUpperCase ( ) + category . slice ( 1 ) }**` , commands ( category ) , true ) ; } ) ; embedMsg . addField ( "Detailed usage" , `Type \`${ ctx instanceof CommandContext ? ctx . guildSettings . prefix : "/" }help <command>\` to get detailed information about the given command.` ) ; return embedMsg ; } getCommand ( ctx , input ) { const embedMsg = new MessageEmbed ( ) ; let cmd ; if ( ctx instanceof CommandContext ) { cmd = ctx . client . commands . get ( input . toLowerCase ( ) ) ; if ( ! cmd ) { cmd = ctx . client . commands . get ( ctx . client . aliases . get ( input . toLowerCase ( ) ) ) ; } } else if ( ctx instanceof SlashCommandContext ) { cmd = ctx . client . interactiveCommands . get ( input . toLowerCase ( ) ) ; } if ( ! cmd ) { let info ; if ( ctx instanceof CommandContext && ctx . client . interactiveCommands . get ( input . toLowerCase ( ) ) ) { info = `\`${ input . toLowerCase ( ) }\` is disabled as a regular command` ; } else if ( ctx instanceof SlashCommandContext && ( ctx . client . commands . get ( input . toLowerCase ( ) ) || ctx . client . aliases . get ( input . toLowerCase ( ) ) ) ) { info = `\`${ input . toLowerCase ( ) }\` is disabled as a slash command` ; } else { info = `No information found for command \`${ input . toLowerCase ( ) }\`` ; } embedMsg . setColor ( "RED" ) . setDescription ( info ) ; return embedMsg ; } if ( ! ctx . guild && cmd . guildOnly ) { const info = `\`${ input . toLowerCase ( ) }\` can't be used in a DM` ; embedMsg . setColor ( "RED" ) . setDescription ( info ) ; return embedMsg ; } if ( cmd . ownerOnly && ctx . author . id != process . env . OWNERID ) { const info = `\`${ input . toLowerCase ( ) }\` can only be used by my owners` ; embedMsg . setColor ( "RED" ) . setDescription ( info ) ; return embedMsg ; } let info ; if ( cmd . name ) info = `**Command name**: \`${ cmd . name }\`` ; if ( ctx instanceof CommandContext && cmd . aliases ) info += `\n**Aliases**: ${ cmd . aliases . map ( ( a ) => `\`${ a }\`` ) . join ( ", " ) }` ; if ( cmd . description ) info += `\n**Description**: ${ cmd . description }` ; if ( cmd . usage ) { info += `\n**Usage**: ${ cmd . usage }` ; embedMsg . setFooter ( "Syntax: <> = required, [] = optional" ) ; } if ( cmd . examples ) { info += "\n**Examples**:" ; for ( const example of cmd . examples ) { info += `\n\`${ example }\`` ; } } embedMsg . setColor ( "GREEN" ) . setDescription ( info ) ; return embedMsg ; } }