2020-04-19 12:12:10 +02:00
const escapeRegex = require ( 'escape-string-regexp' ) ;
2020-08-17 22:24:57 +02:00
const { Structures , WebhookClient } = require ( 'discord.js' ) ;
2020-06-19 20:28:49 +02:00
const { Collection , Emojis } = require ( '../../util' ) ;
2020-04-08 18:08:46 +02:00
2020-07-28 22:40:15 +02:00
const safeCommands = [ 'command:settings' , 'command:grant' , 'command:revoke' ] ;
2020-04-08 18:08:46 +02:00
const Guild = Structures . extend ( 'Guild' , ( Guild ) => {
class ExtendedGuild extends Guild {
constructor ( ... args ) {
super ( ... args ) ;
this . _settings = null ; //internal cache of current guild's settings; should ALWAYS stay the same as database.
2020-05-07 01:26:16 +02:00
this . _permissions = null ; //internal cache, should always match database.
2020-06-04 19:59:09 +02:00
2020-05-24 23:43:47 +02:00
this . callbacks = [ ] ;
2020-06-18 16:07:39 +02:00
this . webhooks = new Collection ( ) ;
2020-04-08 18:08:46 +02:00
}
2020-05-07 17:08:07 +02:00
//Fetch and cache settings
2020-04-19 10:27:13 +02:00
async settings ( ) {
2020-08-08 00:21:28 +02:00
if ( ! this . _settings ) this . _settings = this . client . storageManager . mongodb . guilds . findOne ( { guildId : this . id } ) ;
2020-05-08 08:50:54 +02:00
if ( this . _settings instanceof Promise ) this . _settings = await this . _settings || null ;
2020-07-28 05:00:24 +02:00
if ( ! this . _settings ) this . _settings = { guildId : this . id , ... this . defaultConfig } ;
// else this._settings = Object.assign({}, { ...this.defaultConfig, ...this._settings }); //eslint-disable-line prefer-object-spread
else this . _settings = { ... this . defaultConfig , ... this . _settings } ; //eslint-disable-line prefer-object-spread
2020-04-19 10:27:13 +02:00
return this . _settings ;
2020-05-07 01:26:16 +02:00
}
2020-04-19 10:27:13 +02:00
2020-05-07 17:08:07 +02:00
//Fetch and cache perms
2020-05-08 08:50:54 +02:00
async permissions ( ) {
2020-08-08 00:21:28 +02:00
if ( ! this . _permissions ) this . _permissions = this . client . storageManager . mongodb . permissions . findOne ( { guildId : this . id } ) ;
2020-05-08 08:50:54 +02:00
if ( this . _permissions instanceof Promise ) this . _permissions = await this . _permissions || null ;
if ( ! this . _permissions ) this . _permissions = { guildId : this . id } ;
2020-05-07 01:26:16 +02:00
return this . _permissions ;
2020-04-19 10:27:13 +02:00
}
2020-04-19 12:12:10 +02:00
2020-06-04 19:59:09 +02:00
async caseId ( ) {
if ( ! this . _settings ) await this . settings ( ) ;
return this . _caseId = this . _settings . caseId ; //eslint-disable-line no-return-assign
}
2020-08-17 22:24:57 +02:00
/ * *
* Update a webhook entry in the database
*
* @ param { string } feature Which feature webhook to update , e . g . messagelog
* @ param { Webhook } hook The webhook object , omitting this will nullify the hook data
* @ memberof ExtendedGuild
* /
async updateWebhook ( feature , hook ) {
if ( ! feature ) return false ;
if ( ! hook ) {
this . client . logger . debug ( ` Removing webhook in ${ this . name } ( ${ this . id } ) ` ) ;
const hook = this . webhooks . get ( feature ) ;
if ( hook ) await hook . delete ( 'Removing old webhook' ) . catch ( ( err ) => {
if ( err . code !== 10015 ) this . client . logger . error ( err . stack ) ;
} ) ;
this . webhooks . delete ( feature ) ;
return this . client . storage . mongodb . webhooks . deleteOne ( { feature , guild : this . id } ) ;
}
this . webhooks . set ( feature , hook ) ;
return this . client . storage . mongodb . webhooks . updateOne ( { feature , guild : this . id } , { hookID : hook . id , token : hook . token } ) ;
}
/ * *
* Retrieves a cached webhook for a feature if it exists , gets it from the database if not cached
*
* @ param { string } feature
* @ returns { Webhook }
* @ memberof ExtendedGuild
* /
async getWebhook ( feature ) {
if ( ! feature ) return false ;
if ( this . webhooks . has ( feature ) ) return this . webhooks . get ( feature ) ;
const result = await this . client . storage . mongodb . webhooks . findOne ( { feature , guild : this . id } ) ;
if ( ! result ) return false ;
const hook = new WebhookClient ( result . hookID , result . token , {
disableMentions : 'everyone'
} ) ;
this . webhooks . set ( feature , hook ) ;
return hook ;
}
2020-05-07 01:26:16 +02:00
/* Settings Wrapper */
2020-05-06 01:40:46 +02:00
2020-05-17 15:27:35 +02:00
async _deleteSettings ( ) { //Delete whole entry - remove
2020-05-06 01:40:46 +02:00
try {
2020-08-08 00:21:28 +02:00
await this . client . storageManager . guilds . deleteOne ( { guildId : this . id } ) ;
2020-07-28 05:00:24 +02:00
this . _settings = { ... { } , ... this . defaultConfig } ; //Create a new object so settings that change the _settings value won't replicate it towards the defaultConfig.
2020-05-06 01:40:46 +02:00
this . _storageLog ( ` Database Delete (guild: ${ this . id } ). ` ) ;
} catch ( error ) {
this . _storageError ( error ) ;
}
2020-05-21 12:47:58 +02:00
return true ;
2020-05-06 01:40:46 +02:00
}
2020-07-20 00:42:21 +02:00
async _resetSettings ( ) {
if ( ! this . _settings ) await this . settings ( ) ;
try {
2020-08-08 00:21:28 +02:00
await this . client . storageManager . mongodb . guilds . updateOne (
{ guildId : this . id } ,
{ caseId : this . _settings . caseId , guildId : this . id } ,
false //No upsert
) ;
2020-07-20 00:42:21 +02:00
this . _settings = {
2020-07-28 05:00:24 +02:00
... this . defaultConfig ,
... { caseId : this . _settings . caseId }
2020-07-20 00:42:21 +02:00
} ;
this . _storageLog ( ` Database Reset (guild: ${ this . id } ). ` ) ;
} catch ( error ) {
this . _storageError ( error ) ;
}
}
2020-05-17 15:27:35 +02:00
async _updateSettings ( data ) { //Update property (upsert true) - updateOne
2020-07-04 12:23:10 +02:00
if ( ! this . _settings ) await this . settings ( ) ;
2020-05-06 01:40:46 +02:00
try {
2020-08-08 00:21:28 +02:00
await this . client . storageManager . mongodb . guilds . updateOne (
{ guildId : this . id } ,
data
) ;
2020-05-17 15:27:35 +02:00
this . _settings = {
... this . _settings ,
2020-05-06 01:40:46 +02:00
... data
} ;
this . _storageLog ( ` Database Update (guild: ${ this . id } ). ` ) ;
} catch ( error ) {
this . _storageError ( error ) ;
}
2020-05-21 12:47:58 +02:00
return true ;
2020-05-06 01:40:46 +02:00
}
2020-05-21 12:47:58 +02:00
async _removeSettings ( value ) { //Remove property
2020-07-04 12:23:10 +02:00
if ( ! this . _settings ) await this . settings ( ) ;
2020-07-28 05:00:24 +02:00
if ( this . defaultConfig [ value ] ) {
await this . _updateSettings ( { [ value ] : this . defaultConfig [ value ] } ) ;
2020-05-06 01:40:46 +02:00
return undefined ;
}
try {
2020-08-08 00:21:28 +02:00
await this . client . storageManager . mongodb . guilds . removeProperty (
{ guildId : this . id } ,
[ value ]
) ;
2020-05-06 01:40:46 +02:00
this . _storageLog ( ` Database Remove (guild: ${ this . id } ). ` ) ;
2020-05-21 12:47:58 +02:00
delete this . _settings [ value ] ;
2020-05-06 01:40:46 +02:00
} catch ( error ) {
this . _storageError ( error ) ;
}
2020-05-21 12:47:58 +02:00
return true ;
2020-07-28 22:40:15 +02:00
}
2020-05-06 01:40:46 +02:00
/* Language Formatting */
2020-05-24 23:43:47 +02:00
format ( index , parameters = { } , code = false ) {
2020-04-19 21:54:50 +02:00
2020-05-24 23:43:47 +02:00
let language = 'en_us' ;
if ( this . _settings . locale ) language = this . _settings . locale ;
2020-04-19 12:12:10 +02:00
2020-05-24 23:43:47 +02:00
parameters . prefix = this . prefix ;
2020-07-04 12:23:10 +02:00
let template = this . client . localeLoader . template ( language , index ) ; //.languages[language][index];
2020-05-24 23:43:47 +02:00
2020-06-19 20:28:49 +02:00
for ( const emoji of Object . keys ( Emojis ) ) {
parameters [ ` emoji_ ${ emoji } ` ] = Emojis [ emoji ] ;
}
2020-07-04 12:23:10 +02:00
if ( ! template ) {
2020-05-24 23:43:47 +02:00
return ` **Missing language index \` ${ language } [ ${ index } ] \` in languages. Contact a bot developer about this.** ` ;
}
for ( const [ param , val ] of Object . entries ( parameters ) ) {
2020-07-29 21:01:39 +02:00
template = template . replace ( new RegExp ( ` { ${ escapeRegex ( param . toLowerCase ( ) ) } } ` , 'gi' ) , val ) ; //eslint-disable-line require-unicode-regexp
2020-04-19 12:12:10 +02:00
}
2020-05-24 23:43:47 +02:00
2020-07-04 12:23:10 +02:00
if ( code ) {
2020-05-24 23:43:47 +02:00
try {
2020-07-04 12:23:10 +02:00
template = eval ( template ) ; //eslint-disable-line no-eval
} catch ( error ) {
this . command . client . logger . error ( ` Error in locale ${ language } : ${ index } while executing code. \n ${ error . stack || error } ` ) ;
2020-05-24 23:43:47 +02:00
}
}
return template ;
2020-04-19 21:54:50 +02:00
2020-04-19 12:12:10 +02:00
}
2020-05-06 01:40:46 +02:00
/* Resolver Shortcuts */
2020-06-02 12:09:28 +02:00
async resolveMembers ( members , strict ) {
2020-04-11 10:06:39 +02:00
2020-06-02 12:09:28 +02:00
return this . client . resolver . resolveMembers ( members , strict , this ) ;
2020-04-17 17:23:13 +02:00
}
async resolveMember ( member , strict ) {
2020-06-02 12:09:28 +02:00
return this . client . resolver . resolveMembers ( member , strict , this ) ;
2020-04-17 17:23:13 +02:00
2020-04-11 10:06:39 +02:00
}
2020-06-19 15:38:56 +02:00
async resolveChannels ( channels , strict ) {
2020-04-11 10:06:39 +02:00
2020-06-02 12:09:28 +02:00
return this . client . resolver . resolveChannels ( channels , strict , this ) ;
2020-04-11 10:06:39 +02:00
}
2020-06-19 15:38:56 +02:00
async resolveChannel ( channel , strict ) {
2020-04-17 17:23:13 +02:00
2020-06-02 12:09:28 +02:00
return this . client . resolver . resolveChannel ( channel , strict , this ) ;
2020-04-17 17:23:13 +02:00
}
2020-06-02 12:09:28 +02:00
async resolveRoles ( roles , strict ) {
2020-04-11 10:06:39 +02:00
2020-06-02 12:09:28 +02:00
return this . client . resolver . resolveRoles ( roles , strict , this ) ;
2020-04-11 10:06:39 +02:00
}
2020-04-17 17:23:13 +02:00
async resolveRole ( role , strict ) {
2020-05-22 22:13:47 +02:00
2020-06-02 12:09:28 +02:00
return this . client . resolver . resolveRole ( role , strict , this ) ;
2020-04-17 17:23:13 +02:00
}
2020-05-06 01:40:46 +02:00
/* Logging */
_storageLog ( log ) {
2020-05-07 17:08:07 +02:00
this . client . logger . debug ( log ) ;
2020-05-06 01:40:46 +02:00
}
_storageError ( error ) {
2020-05-07 17:08:07 +02:00
this . client . logger . error ( ` Database Error (guild: ${ this . id } ) : \n ${ error . stack || error } ` ) ;
2020-05-06 01:40:46 +02:00
}
2020-07-04 12:23:10 +02:00
_debugLog ( log ) {
this . client . logger . debug ( ` [ ${ this . name } ]( ${ this . id } ): ${ log } ` ) ;
}
/* Lazy Developer Getters */
2020-07-28 05:00:24 +02:00
get defaultConfig ( ) {
return JSON . parse ( JSON . stringify ( this . client . defaultConfig ) ) ;
}
2020-05-06 01:40:46 +02:00
get prefix ( ) {
2020-05-24 05:50:35 +02:00
return this . _settings . prefix
|| this . client . _options . bot . prefix ;
2020-05-06 01:40:46 +02:00
}
2020-05-25 13:13:34 +02:00
get premium ( ) { //GUILD SETTINGS MUST BE FETCHED
return this . _settings . premium ;
}
2020-05-06 01:40:46 +02:00
2020-07-04 12:23:10 +02:00
get debug ( ) { //GUILD SETTINGS MUST BE FETCHED
return this . _settings . debug ;
}
2020-04-08 18:08:46 +02:00
}
return ExtendedGuild ;
} ) ;
module . exports = Guild ;