2021-04-10 17:07:55 +00:00
import {
Command ,
NamedCommand ,
botHasPermission ,
getPermissionLevel ,
getPermissionName ,
CHANNEL_TYPE ,
RestCommand
} from "../../core" ;
2021-04-05 04:35:12 +00:00
import { clean } from "../../lib" ;
import { Config , Storage } from "../../structures" ;
2021-04-12 17:43:13 +00:00
import { Permissions , TextChannel , User , Role } from "discord.js" ;
2021-03-31 07:00:03 +00:00
import { logs } from "../../modules/globals" ;
2020-12-15 01:44:28 +00:00
function getLogBuffer ( type : string ) {
return {
files : [
{
attachment : Buffer.alloc ( logs [ type ] . length , logs [ type ] ) ,
name : ` ${ Date . now ( ) } . ${ type } .log `
}
]
} ;
}
const activities = [ "playing" , "listening" , "streaming" , "watching" ] ;
const statuses = [ "online" , "idle" , "dnd" , "invisible" ] ;
2021-04-05 04:35:12 +00:00
export default new NamedCommand ( {
2020-12-15 01:44:28 +00:00
description :
"An all-in-one command to do admin stuff. You need to be either an admin of the server or one of the bot's mechanics to use this command." ,
2021-04-12 07:44:23 +00:00
async run ( { send , author , member } ) {
2021-04-05 04:35:12 +00:00
const permLevel = getPermissionLevel ( author , member ) ;
2021-04-10 13:34:55 +00:00
return send ( ` ${ author } , your permission level is \` ${ getPermissionName ( permLevel ) } \` ( ${ permLevel } ). ` ) ;
2020-12-15 01:44:28 +00:00
} ,
subcommands : {
2021-04-05 04:35:12 +00:00
set : new NamedCommand ( {
2020-12-15 01:44:28 +00:00
description : "Set different per-guild settings for the bot." ,
run : "You have to specify the option you want to set." ,
2021-03-30 10:54:52 +00:00
permission : PERMISSIONS.ADMIN ,
2021-04-06 06:15:17 +00:00
channelType : CHANNEL_TYPE.GUILD ,
2020-12-15 01:44:28 +00:00
subcommands : {
2021-04-05 04:35:12 +00:00
prefix : new NamedCommand ( {
2020-12-15 07:56:09 +00:00
description : "Set a custom prefix for your guild. Removes your custom prefix if none is provided." ,
2021-04-08 11:37:49 +00:00
usage : "(<prefix>) (<@bot>)" ,
2021-04-12 07:44:23 +00:00
async run ( { send , guild } ) {
2021-04-06 06:15:17 +00:00
Storage . getGuild ( guild ! . id ) . prefix = null ;
2020-12-15 01:44:28 +00:00
Storage . save ( ) ;
2021-04-10 13:34:55 +00:00
send (
2020-12-15 01:44:28 +00:00
` The custom prefix for this guild has been removed. My prefix is now back to \` ${ Config . prefix } \` . `
) ;
} ,
any : new Command ( {
2021-04-12 07:44:23 +00:00
async run ( { send , guild , args } ) {
2021-04-06 06:15:17 +00:00
Storage . getGuild ( guild ! . id ) . prefix = args [ 0 ] ;
2020-12-15 01:44:28 +00:00
Storage . save ( ) ;
2021-04-10 13:34:55 +00:00
send ( ` The custom prefix for this guild is now \` ${ args [ 0 ] } \` . ` ) ;
2021-04-08 11:37:49 +00:00
} ,
user : new Command ( {
description : "Specifies the bot in case of conflicting prefixes." ,
2021-04-12 07:44:23 +00:00
async run ( { send , guild , client , args } ) {
2021-04-08 11:37:49 +00:00
if ( ( args [ 1 ] as User ) . id === client . user ! . id ) {
Storage . getGuild ( guild ! . id ) . prefix = args [ 0 ] ;
Storage . save ( ) ;
2021-04-10 13:34:55 +00:00
send ( ` The custom prefix for this guild is now \` ${ args [ 0 ] } \` . ` ) ;
2021-04-08 11:37:49 +00:00
}
}
} )
2020-12-15 01:44:28 +00:00
} )
2021-04-05 12:21:27 +00:00
} ) ,
welcome : new NamedCommand ( {
description : "Configure your server's welcome settings for the bot." ,
usage : "type/channel <...>" ,
run : "You need to specify which part to modify, `type`/`channel`." ,
subcommands : {
type : new NamedCommand ( {
description :
"Sets how welcome messages are displayed for your server. Removes welcome messages if unspecified." ,
usage : "`none`/`text`/`graphical`" ,
2021-04-12 07:44:23 +00:00
async run ( { send , guild } ) {
2021-04-06 06:15:17 +00:00
Storage . getGuild ( guild ! . id ) . welcomeType = "none" ;
Storage . save ( ) ;
2021-04-10 13:34:55 +00:00
send ( "Set this server's welcome type to `none`." ) ;
2021-04-05 12:21:27 +00:00
} ,
// I should probably make this a bit more dynamic... Oh well.
subcommands : {
text : new NamedCommand ( {
2021-04-12 07:44:23 +00:00
async run ( { send , guild } ) {
2021-04-06 06:15:17 +00:00
Storage . getGuild ( guild ! . id ) . welcomeType = "text" ;
Storage . save ( ) ;
2021-04-10 13:34:55 +00:00
send ( "Set this server's welcome type to `text`." ) ;
2021-04-05 12:21:27 +00:00
}
} ) ,
graphical : new NamedCommand ( {
2021-04-12 07:44:23 +00:00
async run ( { send , guild } ) {
2021-04-06 06:15:17 +00:00
Storage . getGuild ( guild ! . id ) . welcomeType = "graphical" ;
Storage . save ( ) ;
2021-04-10 13:34:55 +00:00
send ( "Set this server's welcome type to `graphical`." ) ;
2021-04-05 12:21:27 +00:00
}
} )
}
} ) ,
channel : new NamedCommand ( {
description : "Sets the welcome channel for your server. Type `#` to reference the channel." ,
usage : "(<channel mention>)" ,
2021-04-12 07:44:23 +00:00
async run ( { send , channel , guild } ) {
2021-04-06 06:15:17 +00:00
Storage . getGuild ( guild ! . id ) . welcomeChannel = channel . id ;
Storage . save ( ) ;
2021-04-10 13:34:55 +00:00
send ( ` Successfully set ${ channel } as the welcome channel for this server. ` ) ;
2021-04-05 12:21:27 +00:00
} ,
2021-04-06 06:15:17 +00:00
id : "channel" ,
channel : new Command ( {
2021-04-12 07:44:23 +00:00
async run ( { send , guild , args } ) {
2021-04-06 06:15:17 +00:00
const result = args [ 0 ] as TextChannel ;
Storage . getGuild ( guild ! . id ) . welcomeChannel = result . id ;
Storage . save ( ) ;
2021-04-10 13:34:55 +00:00
send ( ` Successfully set this server's welcome channel to ${ result } . ` ) ;
2021-04-05 12:21:27 +00:00
}
} )
} ) ,
message : new NamedCommand ( {
description :
"Sets a custom welcome message for your server. Use `%user%` as the placeholder for the user." ,
usage : "(<message>)" ,
2021-04-12 07:44:23 +00:00
async run ( { send , guild } ) {
2021-04-06 06:15:17 +00:00
Storage . getGuild ( guild ! . id ) . welcomeMessage = null ;
Storage . save ( ) ;
2021-04-10 13:34:55 +00:00
send ( "Reset your server's welcome message to the default." ) ;
2021-04-05 12:21:27 +00:00
} ,
2021-04-10 17:07:55 +00:00
any : new RestCommand ( {
2021-04-12 07:44:23 +00:00
async run ( { send , guild , combined } ) {
2021-04-10 17:07:55 +00:00
Storage . getGuild ( guild ! . id ) . welcomeMessage = combined ;
2021-04-06 06:15:17 +00:00
Storage . save ( ) ;
2021-04-10 17:07:55 +00:00
send ( ` Set your server's welcome message to \` ${ combined } \` . ` ) ;
2021-04-05 12:21:27 +00:00
}
} )
} )
}
2021-04-07 06:43:39 +00:00
} ) ,
stream : new NamedCommand ( {
description : "Set a channel to send stream notifications. Type `#` to reference the channel." ,
usage : "(<channel mention>)" ,
2021-04-12 07:44:23 +00:00
async run ( { send , channel , guild } ) {
2021-04-07 06:43:39 +00:00
const targetGuild = Storage . getGuild ( guild ! . id ) ;
if ( targetGuild . streamingChannel ) {
targetGuild . streamingChannel = null ;
2021-04-10 13:34:55 +00:00
send ( "Removed your server's stream notifications channel." ) ;
2021-04-07 06:43:39 +00:00
} else {
targetGuild . streamingChannel = channel . id ;
2021-04-10 13:34:55 +00:00
send ( ` Set your server's stream notifications channel to ${ channel } . ` ) ;
2021-04-07 06:43:39 +00:00
}
Storage . save ( ) ;
} ,
id : "channel" ,
channel : new Command ( {
2021-04-12 07:44:23 +00:00
async run ( { send , guild , args } ) {
2021-04-07 06:43:39 +00:00
const result = args [ 0 ] as TextChannel ;
Storage . getGuild ( guild ! . id ) . streamingChannel = result . id ;
Storage . save ( ) ;
2021-04-10 13:34:55 +00:00
send ( ` Successfully set this server's stream notifications channel to ${ result } . ` ) ;
2021-04-07 06:43:39 +00:00
}
} )
2021-04-12 17:43:13 +00:00
} ) ,
streamrole : new NamedCommand ( {
description : "Sets/removes a stream notification role (and the corresponding category name)" ,
usage : "set/remove <...>" ,
run : "You need to enter in a role." ,
subcommands : {
set : new NamedCommand ( {
usage : "<role> <category>" ,
id : "role" ,
role : new Command ( {
run : "You need to enter a category name." ,
any : new RestCommand ( {
async run ( { send , guild , args , combined } ) {
const role = args [ 0 ] as Role ;
Storage . getGuild ( guild ! . id ) . streamingRoles [ role . id ] = combined ;
Storage . save ( ) ;
send (
` Successfully set the category \` ${ combined } \` to notify \` ${ role . name } \` . `
) ;
}
} )
} )
} ) ,
remove : new NamedCommand ( {
usage : "<role>" ,
id : "role" ,
role : new Command ( {
async run ( { send , guild , args } ) {
const role = args [ 0 ] as Role ;
const guildStorage = Storage . getGuild ( guild ! . id ) ;
const category = guildStorage . streamingRoles [ role . id ] ;
delete guildStorage . streamingRoles [ role . id ] ;
Storage . save ( ) ;
send (
` Successfully removed the category \` ${ category } \` to notify \` ${ role . name } \` . `
) ;
}
} )
} )
}
2020-12-15 01:44:28 +00:00
} )
}
} ) ,
2021-04-05 04:35:12 +00:00
diag : new NamedCommand ( {
2020-12-15 07:56:09 +00:00
description : 'Requests a debug log with the "info" verbosity level.' ,
2021-03-30 10:54:52 +00:00
permission : PERMISSIONS.BOT_SUPPORT ,
2021-04-12 07:44:23 +00:00
async run ( { send } ) {
2021-04-10 13:34:55 +00:00
send ( getLogBuffer ( "info" ) ) ;
2020-12-15 01:44:28 +00:00
} ,
any : new Command ( {
2020-12-15 07:56:09 +00:00
description : ` Select a verbosity to listen to. Available levels: \` [ ${ Object . keys ( logs ) . join ( ", " ) } ] \` ` ,
2021-04-12 07:44:23 +00:00
async run ( { send , args } ) {
2021-04-05 04:35:12 +00:00
const type = args [ 0 ] ;
2020-12-15 01:44:28 +00:00
2021-04-10 13:34:55 +00:00
if ( type in logs ) send ( getLogBuffer ( type ) ) ;
2020-12-15 01:44:28 +00:00
else
2021-04-10 13:34:55 +00:00
send (
2020-12-15 01:44:28 +00:00
` Couldn't find a verbosity level named \` ${ type } \` ! The available types are \` [ ${ Object . keys (
logs
) . join ( ", " ) } ] \ ` . `
) ;
}
} )
} ) ,
2021-04-05 04:35:12 +00:00
status : new NamedCommand ( {
2020-12-15 01:44:28 +00:00
description : "Changes the bot's status." ,
2021-03-30 10:54:52 +00:00
permission : PERMISSIONS.BOT_SUPPORT ,
2021-04-12 07:44:23 +00:00
async run ( { send } ) {
2021-04-10 13:34:55 +00:00
send ( "Setting status to `online`..." ) ;
2020-12-15 01:44:28 +00:00
} ,
any : new Command ( {
2020-12-15 07:56:09 +00:00
description : ` Select a status to set to. Available statuses: \` [ ${ statuses . join ( ", " ) } ] \` . ` ,
2021-04-12 07:44:23 +00:00
async run ( { send , client , args } ) {
2021-04-05 04:35:12 +00:00
if ( ! statuses . includes ( args [ 0 ] ) ) {
2021-04-10 13:34:55 +00:00
return send ( "That status doesn't exist!" ) ;
2021-03-30 10:25:07 +00:00
} else {
2021-04-05 04:35:12 +00:00
client . user ? . setStatus ( args [ 0 ] ) ;
2021-04-10 13:34:55 +00:00
return send ( ` Setting status to \` ${ args [ 0 ] } \` ... ` ) ;
2020-12-15 01:44:28 +00:00
}
}
} )
} ) ,
2021-04-05 04:35:12 +00:00
purge : new NamedCommand ( {
2021-03-30 23:14:15 +00:00
description : "Purges the bot's own messages." ,
2021-03-30 10:54:52 +00:00
permission : PERMISSIONS.BOT_SUPPORT ,
2021-04-06 06:15:17 +00:00
channelType : CHANNEL_TYPE.GUILD ,
2021-04-12 07:44:23 +00:00
async run ( { send , message , channel , guild , client } ) {
2021-03-30 23:14:15 +00:00
// It's probably better to go through the bot's own messages instead of calling bulkDelete which requires MANAGE_MESSAGES.
2021-04-06 06:15:17 +00:00
if ( botHasPermission ( guild , Permissions . FLAGS . MANAGE_MESSAGES ) ) {
2021-04-05 04:35:12 +00:00
message . delete ( ) ;
const msgs = await channel . messages . fetch ( {
2021-03-30 23:14:15 +00:00
limit : 100
} ) ;
2021-04-05 04:35:12 +00:00
const travMessages = msgs . filter ( ( m ) = > m . author . id === client . user ? . id ) ;
2020-12-15 01:44:28 +00:00
2021-04-10 13:34:55 +00:00
await send ( ` Found ${ travMessages . size } messages to delete. ` ) . then ( ( m ) = >
2021-03-30 23:14:15 +00:00
m . delete ( {
timeout : 5000
} )
) ;
2021-04-06 06:15:17 +00:00
await ( channel as TextChannel ) . bulkDelete ( travMessages ) ;
2021-03-30 23:14:15 +00:00
} else {
2021-04-10 13:34:55 +00:00
send ( "This command must be executed in a guild where I have the `MANAGE_MESSAGES` permission." ) ;
2021-03-30 23:14:15 +00:00
}
2020-12-15 01:44:28 +00:00
}
} ) ,
2021-04-05 04:35:12 +00:00
clear : new NamedCommand ( {
2020-12-15 01:44:28 +00:00
description : "Clears a given amount of messages." ,
usage : "<amount>" ,
2021-04-06 06:15:17 +00:00
channelType : CHANNEL_TYPE.GUILD ,
2020-12-15 01:44:28 +00:00
run : "A number was not provided." ,
number : new Command ( {
description : "Amount of messages to delete." ,
2021-04-12 07:44:23 +00:00
async run ( { message , channel , args } ) {
2021-04-05 04:35:12 +00:00
message . delete ( ) ;
const fetched = await channel . messages . fetch ( {
limit : args [ 0 ]
2020-12-15 01:44:28 +00:00
} ) ;
2021-04-06 06:15:17 +00:00
return await ( channel as TextChannel ) . bulkDelete ( fetched ) ;
2020-12-15 01:44:28 +00:00
}
} )
} ) ,
2021-04-05 04:35:12 +00:00
eval : new NamedCommand ( {
2020-12-15 01:44:28 +00:00
description : "Evaluate code." ,
usage : "<code>" ,
2021-03-30 10:54:52 +00:00
permission : PERMISSIONS.BOT_OWNER ,
2021-04-10 17:07:55 +00:00
run : "You have to enter some code to execute first." ,
any : new RestCommand ( {
// You have to bring everything into scope to use them. AFAIK, there isn't a more maintainable way to do this, but at least TS will let you know if anything gets removed.
2021-04-12 17:43:13 +00:00
async run ( { send , message , channel , guild , author , member , client , args , combined } ) {
2021-04-10 17:07:55 +00:00
try {
let evaled = eval ( combined ) ;
if ( typeof evaled !== "string" ) evaled = require ( "util" ) . inspect ( evaled ) ;
send ( clean ( evaled ) , { code : "js" , split : true } ) ;
} catch ( err ) {
send ( clean ( err ) , { code : "js" , split : true } ) ;
}
2020-12-15 01:44:28 +00:00
}
2021-04-10 17:07:55 +00:00
} )
2020-12-15 01:44:28 +00:00
} ) ,
2021-04-05 04:35:12 +00:00
nick : new NamedCommand ( {
2020-12-15 01:44:28 +00:00
description : "Change the bot's nickname." ,
2021-03-30 10:54:52 +00:00
permission : PERMISSIONS.BOT_SUPPORT ,
2021-04-06 06:15:17 +00:00
channelType : CHANNEL_TYPE.GUILD ,
2021-04-10 17:07:55 +00:00
run : "You have to specify a nickname to set for the bot" ,
any : new RestCommand ( {
2021-04-12 07:44:23 +00:00
async run ( { send , message , guild , combined } ) {
2021-04-10 17:07:55 +00:00
await guild ! . me ? . setNickname ( combined ) ;
if ( botHasPermission ( guild , Permissions . FLAGS . MANAGE_MESSAGES ) ) message . delete ( { timeout : 5000 } ) ;
send ( ` Nickname set to \` ${ combined } \` ` ) . then ( ( m ) = > m . delete ( { timeout : 5000 } ) ) ;
}
} )
2020-12-15 01:44:28 +00:00
} ) ,
2021-04-05 04:35:12 +00:00
guilds : new NamedCommand ( {
2020-12-15 01:44:28 +00:00
description : "Shows a list of all guilds the bot is a member of." ,
2021-03-30 10:54:52 +00:00
permission : PERMISSIONS.BOT_SUPPORT ,
2021-04-12 07:44:23 +00:00
async run ( { send , client } ) {
2021-04-05 04:35:12 +00:00
const guildList = client . guilds . cache . array ( ) . map ( ( e ) = > e . name ) ;
2021-04-10 13:34:55 +00:00
send ( guildList , { split : true } ) ;
2020-12-15 01:44:28 +00:00
}
} ) ,
2021-04-05 04:35:12 +00:00
activity : new NamedCommand ( {
2020-12-15 01:44:28 +00:00
description : "Set the activity of the bot." ,
2021-03-30 10:54:52 +00:00
permission : PERMISSIONS.BOT_SUPPORT ,
2020-12-15 01:44:28 +00:00
usage : "<type> <string>" ,
2021-04-12 07:44:23 +00:00
async run ( { send , client } ) {
2021-04-05 04:35:12 +00:00
client . user ? . setActivity ( ".help" , {
2020-12-15 01:44:28 +00:00
type : "LISTENING"
} ) ;
2021-04-10 13:34:55 +00:00
send ( "Activity set to default." ) ;
2020-12-15 01:44:28 +00:00
} ,
2021-04-10 19:08:36 +00:00
any : new RestCommand ( {
2020-12-15 07:56:09 +00:00
description : ` Select an activity type to set. Available levels: \` [ ${ activities . join ( ", " ) } ] \` ` ,
2021-04-12 07:44:23 +00:00
async run ( { send , client , args } ) {
2021-04-05 04:35:12 +00:00
const type = args [ 0 ] ;
2020-12-15 01:44:28 +00:00
if ( activities . includes ( type ) ) {
2021-04-05 04:35:12 +00:00
client . user ? . setActivity ( args . slice ( 1 ) . join ( " " ) , {
type : args [ 0 ] . toUpperCase ( )
2020-12-15 01:44:28 +00:00
} ) ;
2021-04-10 13:34:55 +00:00
send ( ` Set activity to \` ${ args [ 0 ] . toUpperCase ( ) } \` \` ${ args . slice ( 1 ) . join ( " " ) } \` . ` ) ;
2020-12-15 01:44:28 +00:00
} else
2021-04-10 13:34:55 +00:00
send (
2020-12-15 01:44:28 +00:00
` Couldn't find an activity type named \` ${ type } \` ! The available types are \` [ ${ activities . join (
", "
) } ] \ ` . `
) ;
}
} )
2021-04-05 12:21:27 +00:00
} ) ,
syslog : new NamedCommand ( {
description : "Sets up the current channel to receive system logs." ,
permission : PERMISSIONS.BOT_ADMIN ,
2021-04-06 06:15:17 +00:00
channelType : CHANNEL_TYPE.GUILD ,
2021-04-12 07:44:23 +00:00
async run ( { send , channel } ) {
2021-04-06 06:15:17 +00:00
Config . systemLogsChannel = channel . id ;
Config . save ( ) ;
2021-04-10 13:34:55 +00:00
send ( ` Successfully set ${ channel } as the system logs channel. ` ) ;
2021-04-06 06:15:17 +00:00
} ,
channel : new Command ( {
2021-04-12 07:44:23 +00:00
async run ( { send , args } ) {
2021-04-06 06:15:17 +00:00
const targetChannel = args [ 0 ] as TextChannel ;
Config . systemLogsChannel = targetChannel . id ;
2021-04-05 12:21:27 +00:00
Config . save ( ) ;
2021-04-10 13:34:55 +00:00
send ( ` Successfully set ${ targetChannel } as the system logs channel. ` ) ;
2021-04-05 12:21:27 +00:00
}
2021-04-06 06:15:17 +00:00
} )
2020-12-15 01:44:28 +00:00
} )
}
} ) ;