2020-05-21 12:47:58 +02:00
const { Setting } = require ( '../../../../interfaces/' ) ;
2020-08-17 22:26:57 +02:00
const { Emojis } = require ( '../../../../../util/' ) ;
const { PermissionNames , EmbedLimits } = require ( '../../../../../util/Constants.js' ) ;
const Constants = {
Types : {
role : [
'muteRole' ,
'mutedRole'
] ,
create : [
'createMute' ,
'createMuted' ,
'createMuteRole' ,
'createMutedRole'
] ,
type : [
'muteType' ,
'mutedType'
] ,
permanent : [
'permaMute' ,
'permanentMute'
] ,
duration : [
'defaultMuteDuration' ,
'muteDuration'
]
} ,
MuteTypes : [ 0 , 1 , 2 ] ,
MaxCharacters : 98 ,
MaxIssues : 6
} ;
2020-05-21 12:47:58 +02:00
2020-06-02 12:09:28 +02:00
const { stripIndents } = require ( 'common-tags' ) ;
2020-05-21 12:47:58 +02:00
class MuteSetting extends Setting {
constructor ( client ) {
super ( client , {
name : 'mute' ,
module : 'moderation' ,
aliases : [
'muted' ,
'muteType' ,
'mutedType' ,
'muteRole' ,
'mutedRole' ,
2020-05-24 23:45:47 +02:00
'createMute' ,
'createMuteRole' ,
'createMuted' ,
2020-06-16 00:15:13 +02:00
'createMutedRole' ,
'permaMute' ,
'permanentMute' ,
2020-07-29 21:01:39 +02:00
'defaultMuteDuration'
2020-06-16 00:15:13 +02:00
] ,
2020-08-17 22:26:57 +02:00
// arguments: [
// {
// name: 'text',
// type: 'BOOLEAN',
// types: ['FLAG'],
// default: true
// },
// {
// name: 'voice',
// type: 'BOOLEAN',
// types: ['FLAG'],
// default: true
// }
// ],
usage : "<'create'|'type'|'permanent'|'default'|role> <value..>" ,
2020-05-21 12:47:58 +02:00
examples : [
2020-08-17 22:26:57 +02:00
"mute muted-role" ,
"mute create Muted" ,
"mute type 1" ,
"mute permanent true" ,
"mute default 1 day"
2020-05-21 12:47:58 +02:00
] ,
resolve : 'GUILD' ,
default : {
mute : {
role : null ,
2020-06-16 00:15:13 +02:00
type : 0 ,
defaultDuration : 3600 ,
permanent : false
2020-05-21 12:47:58 +02:00
}
}
} ) ;
}
2020-08-17 22:26:57 +02:00
async handle ( message , args ) {
const { params , parsedArguments } = await this . _parseArguments ( args , message . guild ) ;
if ( params . length === 0 ) {
return {
msg : message . format ( 'S_MUTE_MISSINGARGUMENTS' ) ,
error : true
} ;
}
let type = 'role' ;
let parameters = params . join ( ' ' ) ;
if ( ! [ 'mute' , 'muted' ] . includes ( message . _settingCaller ) ) {
for ( const [ key , values ] of Object . entries ( Constants . Types ) ) {
if ( values . map ( ( v ) => v . toLowerCase ( ) ) . includes ( message . _settingCaller . toLowerCase ( ) ) ) {
type = key ;
break ;
}
}
} else {
const key = params [ 0 ] . toLowerCase ( ) ;
if ( [ 'create' , 'createrole' ] . includes ( key ) ) type = 'create' , parameters = params . splice ( 1 ) . join ( ' ' ) ; //eslint-disable-line no-unused-expressions, no-sequences
if ( [ 'type' ] . includes ( key ) ) type = 'type' , parameters = params . splice ( 1 ) . join ( ' ' ) ; //eslint-disable-line no-unused-expressions, no-sequences
if ( [ 'duration' , 'defaultduration' ] . includes ( key ) ) type = 'duration' , parameters = params . splice ( 1 ) . join ( ' ' ) ; //eslint-disable-line no-unused-expressions, no-sequences
if ( [ 'perma' , 'permamute' , 'permanent' ] . includes ( key ) ) type = 'permanent' , parameters = params . splice ( 1 ) . join ( ' ' ) ; //eslint-disable-line no-unused-expressions, no-sequences
}
if ( type === 'role' ) {
const role = await this . client . resolver . resolveRole ( parameters , true , message . guild ) ;
if ( ! role ) return {
msg : message . format ( 'S_MUTE_ROLEMISSING' ) ,
error : true
} ;
await message . guild . _updateSettings ( {
[ this . index ] : {
... message . guild . _settings [ this . index ] ,
role : role . id
}
} ) ;
message . respond ( message . format ( 'S_MUTE_ROLESUCCESS' ) , {
emoji : 'success'
} ) ;
} else if ( type === 'create' ) {
const response = await this . _createRole ( message , parameters , parsedArguments ) ;
if ( response . error ) return response ;
const { role , issues , created , updatedPermissions } = response ;
await message . guild . _updateSettings ( {
[ this . index ] : {
... message . guild . _settings [ this . index ] ,
role : role . id
}
} ) ;
const sorted = issues ? issues . sort ( ( a , b ) => a . position - b . position ) : [ ] ;
const embed = {
author : {
name : ` ${ Emojis . warning } Warning `
} ,
color : 0xffe15c ,
description : message . format ( 'S_MUTE_CREATESUCCESSWARNING' ) ,
fields : [ ]
} ;
const addField = ( array , type ) => {
const field = {
name : type === 'text' ? 'Text Channels' : 'Voice Channels' ,
value : ''
} ;
const sorted = array . sort ( ( a , b ) => a . position - b . position ) || [ ] ;
for ( const i of sorted ) {
const text = ` ${ Emojis . role } ** ${ i . role } ** has ${ i . permissions . map ( ( p ) => ` \` ${ PermissionNames [ p ] } \` ` ) . join ( ', ' ) } in ${ Emojis [ i . type === 'text' ? 'text-channel' : 'voice-channel' ] } ** ${ i . channel } ** \n ` ;
if ( field . value . length + text . length <= EmbedLimits . fieldValue ) field . value += text ;
}
return field ;
} ;
const textIssues = issues . filter ( ( i ) => i . type === 'text' ) ;
if ( textIssues . length > 0 ) embed . fields . push ( addField ( textIssues , 'text' ) ) ;
const voiceIssues = issues . filter ( ( i ) => i . type === 'voice' ) ;
if ( voiceIssues . length > 0 ) embed . fields . push ( addField ( voiceIssues , 'voice' ) ) ;
message . respond ( message . format ( 'S_MUTE_CREATESUCCESS' , {
created : created ? message . format ( 'S_MUTE_CREATESUCCESSALT' ) : ' ' ,
permissions : message . format ( updatedPermissions ? 'S_MUTE_GENERATEDPERMISSIONS' : 'S_MUTE_UNGENERATEDPERMISSIONS' ) ,
role : role . name
} ) , {
emoji : 'success' ,
embed : issues . length > 0 ? embed : null
} ) ;
} else if ( type === 'type' ) {
const number = parseInt ( num ) ;
if ( Number . isNaN ( number ) ) return {
msg : message . format ( 'S_MUTE_TYPENAN' ) ,
error : true
} ;
if ( ! Constants . MuteTypes . includes ( number ) ) return {
msg : message . format ( 'S_MUTE_TYPEINVALID' ) ,
error : true
} ;
await message . guild . _updateSettings ( {
[ this . index ] : {
... message . guild . _settings [ this . index ] ,
type : number
}
} ) ;
return {
msg : ` ${ message . format ( 'S_MUTE_TYPESUCCESS' , { type : number } )} ${ message . format ( 'S_MUTE_TYPESWITCH' , { type : number } , true)} ` ,
error : false
} ;
} else if ( type === 'duration' ) {
} else if ( type === 'permanent' ) {
}
return {
error : false ,
ignore : true
} ;
}
async _createRole ( message , name = 'Muted' , args ) {
const createRole = async ( name ) => {
let role = null ;
if ( name . length > Constants . MaxCharacters ) name = name . slice ( 0 , Constants . MaxCharacters ) ;
try {
role = await message . guild . roles . create ( {
data : {
name
} ,
reason : super . reason ( message . author )
} ) ;
} catch ( error ) {
return {
msg : message . format ( 'S_MUTE_ROLECREATEERROR' ) ,
error : true
} ;
}
return role ;
} ;
const hasPermission = message . guild . me . hasPermission ( 'MANAGE_ROLES' ) ;
if ( ! hasPermission ) return {
msg : message . format ( 'S_MUTE_ROLEMISSINGPERMISSION' ) ,
error : true
} ;
let role = null ;
const existing = await this . client . resolver . resolveRole ( name , true , message . guild ) ;
if ( existing ) {
const prompt = await message . prompt ( message . format ( 'S_MUTE_ROLEPROMPT' , {
name : existing . name ,
id : existing . id
} ) , { emoji : 'loading' } ) ;
const boolean = this . client . resolver . resolveBoolean ( prompt . content . toLowerCase ( ) ) ;
if ( boolean === null ) return {
msg : message . format ( 'S_MUTE_ROLEPROMPTERROR' ) ,
error : true
} ;
if ( boolean ) {
role = existing ;
}
}
let created = false ;
if ( ! role ) {
role = await createRole ( name ) ;
if ( role . error ) return role ;
created = true ;
}
const issues = [ ] ;
let updatedPermissions = false ;
for ( const channel of message . guild . channels . cache . values ( ) ) {
const configuration = channel . type === 'text'
? { permissions : { SEND _MESSAGES : false , ADD _REACTIONS : false } , bitwise : 0x800 }
: { permissions : { CONNECT : false } , bitwise : 0x100000 } ;
try {
if ( channel . type === 'text' || channel . type === 'voice' ) {
await channel . createOverwrite ( role , configuration . permissions , super . reason ( message . author ) ) ;
for ( const permission of channel . permissionOverwrites . values ( ) ) {
if ( permission . type !== 'role' ) continue ;
const permissionRole = await this . client . resolver . resolveRole ( permission . id , true , message . guild ) ;
if ( ( permission . allow & configuration . bitwise ) === configuration . bitwise ) { //eslint-disable-line no-bitwise
const issue = {
role : permissionRole . name ,
permissions : Object . keys ( configuration . permissions ) ,
channel : channel . name ,
type : channel . type ,
position : permissionRole . rawPosition
} ;
issues . push ( issue ) ;
}
}
}
updatedPermissions = true ;
} catch ( error ) { } //eslint-disable-line no-empty
}
return {
error : false ,
updatedPermissions ,
created ,
issues ,
role
} ;
}
/ *
2020-05-21 12:47:58 +02:00
async handle ( message , args ) {
2020-08-16 09:27:49 +02:00
let { params , parsedArguments } = await this . _parseArguments ( args , message . guild ) ; //eslint-disable-line prefer-const
2020-06-16 00:15:13 +02:00
2020-05-24 00:11:42 +02:00
if ( [ 'mutetype' , 'mutedtype' ] . includes ( message . _settingCaller ) || parsedArguments . type ) {
2020-06-16 00:15:13 +02:00
if ( ! params [ 0 ] ) return { error : true , msg : message . format ( 'S_MUTE_TYPENAN' ) } ;
const num = params [ 0 ] ;
2020-05-21 12:47:58 +02:00
const number = parseInt ( num ) ;
2020-06-16 00:15:13 +02:00
if ( Number . isNaN ( number ) ) return {
2020-05-21 12:47:58 +02:00
msg : message . format ( 'S_MUTE_TYPENAN' ) ,
error : true
} ;
if ( ! [ 0 , 1 , 2 ] . includes ( number ) ) return {
msg : message . format ( 'S_MUTE_TYPEINVALID' ) ,
error : true
} ;
await message . guild . _updateSettings ( {
[ this . index ] : {
... message . guild . _settings [ this . index ] ,
type : number
}
} ) ;
2020-06-16 00:15:13 +02:00
2020-05-21 12:47:58 +02:00
return {
msg : ` ${ message . format ( 'S_MUTE_TYPESUCCESS' , { type : number } )} ${ message . format ( 'S_MUTE_TYPESWITCH' , { type : number } , true)} ` ,
error : false
} ;
2020-06-16 00:15:13 +02:00
} else if ( [ 'permamute' , 'permanentmute' ] . includes ( message . _settingCaller ) || parsedArguments . permanent ) {
if ( ! params [ 0 ] ) return { error : true , msg : message . format ( 'S_MUTE_PERMANENTINVALID' ) } ;
const boolean = this . client . resolver . resolveBoolean ( params [ 0 ] ) ;
if ( boolean === null ) {
return {
msg : message . format ( 'S_MUTE_PERMANENTINVALID' ) ,
error : true
2020-07-29 21:01:39 +02:00
} ;
2020-06-16 00:15:13 +02:00
}
await message . guild . _updateSettings ( {
[ this . index ] : {
... message . guild . _settings [ this . index ] ,
permanent : boolean
}
} ) ;
return {
msg : message . format ( 'S_MUTE_PERMANENTSUCCESS' , { boolean } ) ,
error : false
} ;
} else if ( [ 'defaultMuteDuration' ] . includes ( message . _settingCaller ) || parsedArguments . defaultDuration ) {
if ( ! params . length ) return { error : true , msg : message . format ( 'S_MUTE_PERMANENTINVALID' ) } ;
const time = this . client . resolver . resolveTime ( params . join ( ' ' ) ) ;
if ( ! time ) {
return {
msg : message . format ( 'S_MUTE_DEFAULTINVALID' ) ,
error : true
2020-07-29 21:01:39 +02:00
} ;
2020-06-16 00:15:13 +02:00
}
await message . guild . _updateSettings ( {
[ this . index ] : {
... message . guild . _settings [ this . index ] ,
defaultDuration : time
}
} ) ;
return {
msg : message . format ( 'S_MUTE_DEFAULTSUCCESS' , { time } ) ,
error : false
} ;
2020-05-21 12:47:58 +02:00
}
2020-06-02 12:09:28 +02:00
let role = null ,
updatedPermissions = false ,
2020-08-16 09:27:49 +02:00
created = false ;
const issues = [ ] ;
2020-05-24 23:45:47 +02:00
if ( parsedArguments . create || [ 'createmute' , 'createmuted' , 'createmutedrole' , 'createmuterole' ] . includes ( message . _settingCaller ) ) {
2020-05-21 12:47:58 +02:00
const missing = message . channel . permissionsFor ( message . guild . me ) . missing ( 'MANAGE_ROLES' ) ;
if ( missing . length > 0 ) return {
msg : message . format ( 'S_MUTE_ROLEMISSINGPERMISSION' ) ,
error : true
} ;
2020-06-16 00:15:13 +02:00
const foundRole = await message . guild . resolveRole ( params . join ( ' ' ) , true ) ;
2020-05-21 12:47:58 +02:00
if ( foundRole ) {
const prompt = await message . prompt ( message . format ( 'S_MUTE_ROLEPROMPT' , { name : foundRole . name , id : foundRole . id } ) , { emoji : 'loading' } ) ;
const response = prompt . content . toLowerCase ( ) ;
const bool = this . client . resolver . resolveBoolean ( response ) ;
if ( bool === null ) return { msg : message . format ( 'S_MUTE_ROLEPROMPTERROR' ) , error : true } ;
if ( ! bool ) {
2020-06-16 00:15:13 +02:00
role = await this . _createRole ( message , params ) ;
2020-05-21 12:47:58 +02:00
if ( role . error ) return role ;
created = true ;
} else {
role = foundRole ;
}
} else {
2020-06-16 00:15:13 +02:00
role = await this . _createRole ( message , params ) ;
2020-05-21 12:47:58 +02:00
if ( role . error ) return role ;
created = true ;
}
2020-06-02 12:09:28 +02:00
const channels = message . guild . channels . cache ;
2020-05-21 12:47:58 +02:00
for ( const channel of channels . values ( ) ) {
2020-06-02 12:09:28 +02:00
const configuration = channel . type === 'text'
? { permissions : { SEND _MESSAGES : false , ADD _REACTIONS : false } , bitwise : 0x800 }
: { permissions : { CONNECT : false } , bitwise : 0x100000 } ;
2020-05-21 12:47:58 +02:00
try {
2020-06-16 00:15:13 +02:00
// console.log(channel.type)
2020-07-29 21:01:39 +02:00
if ( channel . type === 'text' && ! parsedArguments . voice || channel . type === 'voice' && ! parsedArguments . text || ! parsedArguments . text && ! parsedArguments . voice ) {
2020-06-02 12:09:28 +02:00
if ( channel . type === 'category' ) continue ;
await channel . createOverwrite ( role , configuration . permissions , super . reason ( message . author ) ) ;
for ( const permission of channel . permissionOverwrites . values ( ) ) {
if ( permission . type !== 'role' ) continue ;
const r = await this . client . resolver . resolveRole ( permission . id , true , message . guild ) ;
2020-08-16 09:27:49 +02:00
if ( ( permission . allow & configuration . bitwise ) === configuration . bitwise ) { //eslint-disable-line no-bitwise
2020-06-02 12:09:28 +02:00
const info = {
role : r . name ,
permission : channel . type === 'text' ? 'SEND_MESSAGES' : 'CONNECT' ,
channel : channel . name ,
type : channel . type ,
emoji : channel . type === 'text' ? emojis [ 'text-channel' ] : emojis [ 'voice-channel' ]
2020-07-29 21:01:39 +02:00
} ;
2020-06-02 12:09:28 +02:00
issues . push ( info ) ;
}
}
}
2020-05-21 12:47:58 +02:00
} catch ( err ) { } //eslint-disable-line no-empty
}
updatedPermissions = true ;
} else {
2020-08-16 09:27:49 +02:00
if ( params . length > 1 && params [ 0 ] . toLowerCase ( ) === 'role' ) params = params . splice ( 1 ) ;
2020-06-16 00:15:13 +02:00
const search = params . join ( ' ' ) ;
2020-06-02 12:09:28 +02:00
role = await this . client . resolver . resolveRole ( search , true , message . guild ) ;
2020-05-21 12:47:58 +02:00
}
if ( ! role ) return {
msg : message . format ( 'S_MUTE_ROLEMISSING' ) ,
error : true
} ;
await message . guild . _updateSettings ( {
[ this . index ] : {
... message . guild . _settings [ this . index ] ,
role : role . id
}
} ) ;
return {
2020-06-02 12:09:28 +02:00
msg : stripIndents ` ${ message . format ( 'S_MUTE_ROLESUCCESS' , { role : role . name , type : created ? 'created' : 'set' } )} ${ updatedPermissions ? message . format ( 'S_MUTE_GENERATEDPERMISSIONS' ) : message . format ( 'S_MUTE_UNGENERATEDPERMISSIONS' ) }
2020-07-29 21:01:39 +02:00
$ { issues . length > 0 ? message . format ( 'S_MUTE_ISSUES' , { issues : issues . map ( ( i ) => ` ** \` ${ i . role } \` :** Has the \` ${ i . permission } \` permission in ** ${ i . emoji } ${ i . channel } **. ` ) . join ( '\n' ) } ) : '' } ` ,
2020-05-21 12:47:58 +02:00
error : false
} ;
}
2020-08-17 22:26:57 +02:00
* /
/ *
2020-05-21 12:47:58 +02:00
async _createRole ( message , args ) {
let role = null ;
let name = args . join ( ' ' ) || 'Muted' ;
if ( name . length > maxCharacters ) name = name . slice ( 0 , maxCharacters ) ;
try {
role = await message . guild . roles . create ( {
data : {
name
} ,
reason : super . reason ( message . author )
} ) ;
} catch ( error ) {
return {
msg : message . format ( 'S_MUTE_ROLECREATEERROR' ) ,
error : true
} ;
}
return role ;
}
2020-08-17 22:26:57 +02:00
* /
2020-05-21 12:47:58 +02:00
fields ( guild ) {
2020-06-16 00:15:13 +02:00
const setting = guild . _settings [ this . index ] ;
2020-05-21 12:47:58 +02:00
return [
{
2020-08-16 09:27:49 +02:00
name : '》 Muted Role' ,
2020-06-16 00:15:13 +02:00
value : setting ? . role ? ` <@& ${ guild . _settings [ this . index ] . role } > ` : '`N/A`' ,
2020-05-21 12:47:58 +02:00
inline : true
} ,
{
2020-08-16 09:27:49 +02:00
name : '》 Mute Type' ,
2020-06-16 00:15:13 +02:00
value : ` \` ${ setting ? . type || 0 } \` ` ,
2020-05-21 12:47:58 +02:00
inline : true
2020-06-16 00:15:13 +02:00
} ,
{ name : '\u200b' , value : '\u200b' , inline : true } , //zero width spaces, not necessary, but could make things look nicer.
{
2020-08-16 09:27:49 +02:00
name : '》 Permanent Mutes' ,
value : guild . format ( 'SETTING_STATUS' , { bool : Boolean ( setting ? . permanent ) } , true ) ,
2020-06-16 00:15:13 +02:00
inline : true
} ,
{
2020-08-16 09:27:49 +02:00
name : '》 Default Duration' ,
2020-06-16 00:15:13 +02:00
value : ` \` ${ setting . defaultDuration ? ` ${ setting . defaultDuration } seconds ` : 'N/A' } \` ` ,
inline : true
} ,
{ name : '\u200b' , value : '\u200b' , inline : true } //zero width spaces, not necessary, but could make things look nicer.
2020-05-21 12:47:58 +02:00
] ;
}
}
module . exports = MuteSetting ;