2020-06-04 19:59:09 +02:00
const { Util } = require ( '../../../util/' ) ;
const Constants = {
MaxCharacters : 1024 // Max embed description is 2048 characters, however some of those description characters are going to usernames, types, filler text, etc.
} ;
2020-04-17 09:03:53 +02:00
class Infraction {
constructor ( client , opts = { } ) {
this . client = client ;
2020-06-02 12:09:28 +02:00
this . message = opts . message ;
this . arguments = opts . arguments ;
2020-04-17 09:03:53 +02:00
this . target = opts . target ; //User or channel being targeted.
2020-04-17 22:18:29 +02:00
this . targetType = opts . targetType ; // 'user' or 'channel'.
2020-04-17 09:03:53 +02:00
this . executor = opts . executor ; //Whoever executed the command.
this . guild = opts . guild ;
this . channel = opts . channel ;
this . case = null ;
this . type = opts . type ; //What type of infraction (mute, kick, etc.)
this . timestamp = new Date ( ) . getTime ( ) ;
2020-06-04 19:59:09 +02:00
this . duration = opts . duration || null ; //How long the action will last. Must be in milliseconds.
this . reason = opts . reason . length ? opts . reason : 'N/A' ;
this . silent = opts . silent ;
2020-06-02 12:09:28 +02:00
this . points = 0 ;
2020-06-04 19:59:09 +02:00
this . totalPoints = 0 ;
this . expiration = 0 ;
2020-04-17 09:03:53 +02:00
this . color = opts . color ; //Infraction-defined hexadecimal value to dictate what color the embed is.
2020-06-02 12:09:28 +02:00
this . dictionary = opts . dictionary || { } ; // { past: 'banned', present: 'ban' } Infraction-defined object for the correct spellings.
2020-06-04 19:59:09 +02:00
this . _logMessage = null ; //The message embed sent in the moderation-log. Full message, not the ID.
this . _dmMessage = null ; //The message embed sent in the target's direct messages. Full message, not the ID.
2020-04-17 09:03:53 +02:00
}
2020-06-04 19:59:09 +02:00
async log ( ) {
if ( this . silent ) {
try {
await this . message . delete ( ) ;
} catch ( e ) { } //eslint-disable-line no-empty
}
2020-04-17 09:03:53 +02:00
2020-06-02 12:09:28 +02:00
const { moderationLog , moderationPoints } = this . guild . _settings ;
2020-06-04 19:59:09 +02:00
/* Handling */
if ( moderationPoints . enabled ) {
if ( this . arguments . points ) {
this . points = parseInt ( this . arguments . points . value ) ;
} else {
this . points = moderationPoints . points [ this . type ] || 0 ;
}
if ( this . arguments . expiration ) {
this . expiration = parseInt ( this . arguments . expiration . value ) ;
} else {
this . expiration = moderationPoints . expirations [ this . type ] || 0 ;
}
if ( this . targetType === 'user' ) {
this . totalPoints = await this . target . totalPoints ( this . guild , this . points ) ;
}
}
this . guild . _settings . caseId ++ ;
this . case = this . guild . _settings . caseId ;
await this . guild . _updateSettings ( {
caseId : this . case
} ) ;
console . log ( ` points: ${ this . points } , total points: ${ this . totalPoints } , expiration: ${ this . expiration } ` ) ;
/* Logging */
2020-06-02 12:09:28 +02:00
if ( moderationLog . channel ) {
if ( moderationLog . infractions . includes ( this . type . toLowerCase ( ) ) ) {
const channel = this . client . resolver . resolveChannel ( moderationLog . channel , true , this . guild ) ;
2020-06-04 19:59:09 +02:00
if ( ! channel ) return undefined ;
2020-06-02 12:09:28 +02:00
this . _logMessage = await channel . send ( '' , { embed : this . embed ( ) } ) ;
} else {
this . client . logger . debug ( ` Did not log infraction ${ this . type } because it is not in the infractions. ` ) ;
}
}
2020-06-04 19:59:09 +02:00
if ( this . guild . _settings . dmInfraction . enabled
2020-06-02 12:09:28 +02:00
&& this . targetType === 'user' ) {
2020-06-04 19:59:09 +02:00
let message = this . guild . _settings . dmInfraction . custom [ this . type ] || this . guild . _settings . dmInfraction . custom . default ;
if ( ! message ) message = "" ;
message = message
. replace ( /\{(guild|server)\}/ugim , this . guild . name )
. replace ( /\{user\}/ugim , this . target . tag )
. replace ( /\{infraction\}/ugim , this . dictionary . past ) ; //add more if you want i should probably add a better system for this...
2020-06-02 12:09:28 +02:00
try {
2020-06-04 19:59:09 +02:00
this . _dmMessage = await this . target . send ( message , {
2020-06-02 12:09:28 +02:00
embed : this . embed ( )
} ) ;
} catch ( e ) { } //eslint-disable-line no-empty
}
2020-06-04 19:59:09 +02:00
//might be useful for automod related stuff
// this.client.emit('infractionUpdate', {
// action: 'new',
// infraction: this
// });
return this . save ( ) ;
2020-04-17 09:03:53 +02:00
}
2020-04-17 22:18:29 +02:00
async save ( ) {
2020-05-06 01:40:46 +02:00
await this . client . transactionHandler . send ( {
2020-04-17 22:18:29 +02:00
provider : 'mongodb' ,
request : {
type : 'insertOne' ,
2020-06-04 19:59:09 +02:00
collection : 'infractions' ,
2020-06-02 12:09:28 +02:00
data : this . json
2020-04-17 22:18:29 +02:00
}
2020-06-02 12:09:28 +02:00
} ) . catch ( ( error ) => {
this . client . logger . error ( ` There was an issue saving infraction data to the database. \n ${ error . stack || error } ` ) ;
} ) ;
}
2020-06-04 19:59:09 +02:00
embed ( ) {
2020-06-02 12:09:28 +02:00
let description = this . message . format ( 'INFRACTION_DESCRIPTION' , {
2020-06-04 19:59:09 +02:00
type : this . dictionary . past . toUpperCase ( ) ,
moderator : ` ${ Util . escapeMarkdown ( this . executor . tag ) } ` ,
reason : this . reason . length > Constants . MaxCharacters ? ` ${ this . reason . substring ( 0 , Constants . MaxCharacters - 3 ) } ... ` : this . reason
2020-06-02 12:09:28 +02:00
} ) ;
if ( this . duration ) {
2020-06-04 19:59:09 +02:00
description += ` \n ${ this . message . format ( 'INFRACTION_DESCRIPTIONDURATION' , { duration : this . _duration ( ) } )} ` ;
2020-06-02 12:09:28 +02:00
}
2020-06-04 19:59:09 +02:00
if ( this . points ) {
description += ` \n ${ this . message . format ( 'INFRACTION_DESCRIPTIONPOINTS' , { points : this . points , total : this . totalPoints } )} ` ;
}
if ( ! this . silent ) {
description += ` \n ${ this . message . format ( 'INFRACTION_DESCRIPTIONJUMPTO' , { name : 'Message' , link : ` https://discord.com/channels/ ${ this . guild . id } / ${ this . channel . id } / ${ this . message . id } ` } )} ` ;
2020-06-02 12:09:28 +02:00
}
return {
author : {
name : ` ${ this . targetName } ( ${ this . target . id } ) ` ,
icon _url : this . targetIcon //eslint-disable-line camelcase
} ,
timestamp : new Date ( ) ,
color : this . color ,
footer : {
text : ` 》 Case ${ this . case } `
} ,
description
} ;
2020-04-17 22:18:29 +02:00
}
2020-06-02 12:09:28 +02:00
get json ( ) {
2020-04-17 09:03:53 +02:00
return {
id : ` ${ this . guild . id } : ${ this . case } ` ,
guild : this . guild . id ,
channel : this . channel ? this . channel . id : null ,
message : this . message ? this . message . id : null ,
executor : this . executor . id ,
target : this . target . id ,
targetType : this . targetType ,
type : this . type ,
case : this . case ,
duration : this . duration ,
reason : this . reason ,
2020-06-04 19:59:09 +02:00
timestamp : this . timestamp ,
points : this . points ,
expiration : this . expiration
2020-04-17 22:18:29 +02:00
} ;
2020-04-17 09:03:53 +02:00
}
get targetName ( ) {
return this . targetType === 'user'
? this . target . tag
2020-04-17 22:18:29 +02:00
: ` # ${ this . target . name } ` ;
2020-04-17 09:03:53 +02:00
}
2020-06-02 12:09:28 +02:00
get targetIcon ( ) {
return this . targetType === 'user'
? this . target . displayAvatarURL ( )
: this . guild . iconURL ( ) ;
}
2020-06-04 19:59:09 +02:00
get _reason ( ) {
let str = ` [targetId: ${ this . target . id } ] Executed by ${ this . executor . tag } ( ${ this . executor . id } ) because: ${ this . reason } ` ;
if ( str . length > 512 ) str = ` ${ this . reason . substring ( 0 , 509 ) } ... ` ;
return str ;
}
2020-06-02 12:09:28 +02:00
//Super Functions
_succeed ( ) {
return {
error : false ,
infraction : this
} ;
}
_fail ( message , opts ) {
return {
error : true ,
infraction : this ,
reason : this . message . format ( message , opts )
} ;
}
2020-04-17 09:03:53 +02:00
}
module . exports = Infraction ;