import mongoose = require ( 'mongoose' ) ; import { pActionDoc , pActionSchema , pActionObject , pActionActions , caseActions } from './schemas' ; import { Bot } from '..' ; import { pActionsInterval , YTResubInterval } from '../bot-config.json' ; import { Guild , GuildMember , TextChannel } from 'discord.js' ; import { durationToString } from '../utils/parsers' ; import { durations } from '../utils/time' ; import { databaseUnmute } from '../commands/Moderation/unmute' ; export class export class PActions { type { mongoose . Connection } memberof connection : mongoose . Connection ; type { mongoose . Model < pActionDoc > } memberof pActions : mongoose . Model < pActionDoc > ; param { { url : string , suffix : string } } clusterInfo memberof constructor ( clusterInfo ) { this . connection = mongoose . createConnection ( clusterInfo . url + '/main' + clusterInfo . suffix , { useNewUrlParser : true } ) ; this . connection . on ( 'error' , error => { console . error ( 'connection error:' , error ) ; Bot . mStats . logError ( error ) ; } ) ; this . connection . once ( 'open' , async ( ) => { console . log ( 'pActions connected to /main database' ) ; Bot . pActions . pActions = Bot . pActions . connection . model ( 'pAction' , pActionSchema , 'pActions' ) ; setInterval ( ( ) => { Bot . pActions . executeActions ( ) ; } , pActionsInterval ) ; if ( ! ( await Bot . pActions . pActions . findOne ( { action : pActionActions . resubWebhook , 'info.service' : 'youtube' } ) . exec ( ) ) ) { let resubTimestamp = Date . now ( ) + pActionsInterval ; Bot . pActions . addWebhookResub ( 'youtube' , resubTimestamp ) ; console . info ( `Added YouTube Webhook Resub task for ${ new Date ( resubTimestamp ) . toISOString ( ) }` ) ; } } ) ; } memberof async executeActions ( ) { if ( Bot . client . status != 0 ) return ; let actions = await this . pActions . find ( { to : { $lte : Date . now ( ) } } ) ; for ( const action of actions ) { let actionObject = action . toObject ( ) ; let guild ; switch ( actionObject . action ) { case pActionActions . mute : { guild = Bot . client . guilds . get ( actionObject . info . guild ) ; if ( ! guild ) break ; if ( ! guild . me . hasPermission ( 'MANAGE_ROLES' ) ) break ; databaseUnmute ( guild . id , actionObject . info . user ) ; let member ; try { member = await guild . fetchMember ( actionObject . info . user ) ; } catch ( e ) { break ; } if ( ! member ) break ; let durationString = durationToString ( actionObject . to - actionObject . from ) ; let role = member . roles . find ( role => role . name . toLowerCase ( ) == 'muted' ) ; if ( role ) member . removeRole ( role , `Auto unmute for case ${ actionObject . info . case } after ${ durationString }` ) ; let guildDoc = await Bot . database . findGuildDoc ( guild . id , [ 'caseChannel' ] ) ; if ( ! guildDoc || ! guildDoc . caseChannel ) break ; let caseChannel = guild . channels . get ( guildDoc . caseChannel ) ; if ( ! caseChannel || ! ( caseChannel instanceof TextChannel ) ) break ; caseChannel . send ( Bot . caseLogger . createCaseEmbed ( member . user , guild . me , actionObject . info . case , caseActions . unmute , Bot . database . settingsDB . cache . embedColors . positive , null , `Auto unmute for case ${ actionObject . info . case } after ${ durationString }` ) ) ; break ; } case pActionActions . ban : { guild = Bot . client . guilds . get ( actionObject . info . guild ) ; if ( ! guild ) break ; if ( ! guild . me . hasPermission ( 'BAN_MEMBERS' ) ) break ; let banInfo = await guild . fetchBan ( actionObject . info . user ) ; if ( ! banInfo ) break ; let durationString = durationToString ( actionObject . to - actionObject . from ) ; guild . unban ( actionObject . info . user , `Auto unban for case ${ actionObject . info . case } after ${ durationString }` ) . catch ( reason => { } ) ; let guildDoc = await Bot . database . findGuildDoc ( guild . id , [ 'caseChannel' ] ) ; if ( ! guildDoc || ! guildDoc . caseChannel ) break ; let caseChannel = guild . channels . get ( guildDoc . caseChannel ) ; if ( ! caseChannel || ! ( caseChannel instanceof TextChannel ) ) break ; caseChannel . send ( Bot . caseLogger . createCaseEmbed ( banInfo . user , guild . me , actionObject . info . case , caseActions . unban , Bot . database . settingsDB . cache . embedColors . positive , null , `Auto unban for case ${ actionObject . info . case } after ${ durationString }` ) ) ; break ; } case pActionActions . lockChannel : { guild = Bot . client . guilds . get ( actionObject . info . guild ) ; if ( ! guild ) break ; if ( ! guild . me . hasPermission ( 'MANAGE_CHANNELS' ) ) break ; let channel = guild . channels . get ( actionObject . info . channel ) ; if ( ! channel || ! ( channel instanceof TextChannel ) ) break ; let durationString = durationToString ( actionObject . to - actionObject . from ) ; for ( const id of actionObject . info . allowOverwrites ) await channel . overwritePermissions ( id , { SEND_MESSAGES : true } , `Auto unlock after ${ durationString }` ) ; for ( const id of actionObject . info . neutralOverwrites ) { let permOverwrite = channel . permissionOverwrites . get ( id ) ; if ( permOverwrite ) if ( ( permOverwrite . allow == 0 && permOverwrite . deny == 2048 ) || ( permOverwrite . deny == 0 && permOverwrite . allow == 2048 ) ) { permOverwrite . delete ( ) ; } else { channel . overwritePermissions ( id , { SEND_MESSAGES : null } , `Auto unlock after ${ durationString }` ) ; } } channel . send ( 'Channel is unlocked now' ) ; Bot . mStats . logMessageSend ( ) ; let updateDoc = { } ; updateDoc [ '$unset' ] = { } ; updateDoc [ '$unset' ] [ `locks.${ channel . id }` ] = "" ; Bot . database . mainDB . guilds . updateOne ( { guild : actionObject . info . guild } , updateDoc ) . exec ( ) ; break ; } case pActionActions . resubWebhook : { switch ( actionObject . info . service ) { case 'youtube' : Bot . youtube . resubWebhooks ( ) ; this . addWebhookResub ( 'youtube' , actionObject . to + YTResubInterval ) ; } break ; } } action . remove ( ) ; } } param { string } guildID param { string } userID param { number } until param { string } caseID param { number } requestTime returns memberof async addMute ( guildID , userID , until , caseID , requestTime ? ) { let pMute = await this . pActions . findOne ( { action : pActionActions . mute , 'info.guild' : guildID , 'info.user' : userID } ) . exec ( ) ; if ( pMute ) { pMute . to = until ; pMute . info . case = caseID ; pMute . markModified ( 'info.case' ) ; pMute . markModified ( 'to' ) ; } else { pMute = new this . pActions ( { from : requestTime || Date . now ( ) , to : until , action : pActionActions . mute , info : { guild : guildID , user : userID , case : caseID } } ) ; } return pMute . save ( ) ; } param { string } guildID param { string } userID returns memberof removeMute ( guildID , userID ) { return this . pActions . deleteOne ( { action : pActionActions . mute , 'info.guild' : guildID , 'info.user' : userID } ) . exec ( ) ; } param { string } guildID param { string } userID param { number } until param { number } caseID param { number } requestTime returns memberof addBan ( guildID , userID , until , caseID , requestTime ? ) { let pBan = new this . pActions ( { from : requestTime || Date . now ( ) , to : until , action : pActionActions . ban , info : { guild : guildID , user : userID , case : caseID } } ) ; return pBan . save ( ) ; } param { string } guildID param { string } userID returns memberof removeBan ( guildID , userID ) { return this . pActions . deleteOne ( { action : pActionActions . ban , 'info.guild' : guildID , 'info.user' : userID } ) . exec ( ) ; } param { string } guildID param { string } channelID param { string [ ] } allowOverwrites param { string [ ] } neutralOverwrites param { number } until param { number } requestTime returns memberof async addLockChannel ( guildID , channelID , allowOverwrites , neutralOverwrites , until , requestTime ? ) { let pLock = await this . pActions . findOne ( { action : pActionActions . lockChannel , 'info.guild' : guildID , 'info.channel' : channelID } ) . exec ( ) ; if ( ! pLock ) { pLock = new this . pActions ( { from : requestTime || Date . now ( ) , to : until , action : pActionActions . lockChannel , info : { guild : guildID , channel : channelID , allowOverwrites : allowOverwrites , neutralOverwrites : neutralOverwrites } } ) ; } else { pLock . to = until ; pLock . markModified ( 'to' ) ; } return pLock . save ( ) ; } param { string } guildID param { string } channelID returns memberof removeLockChannel ( guildID , channelID ) { return this . pActions . deleteOne ( { action : pActionActions . lockChannel , 'info.guild' : guildID , 'info.channel' : channelID } ) . exec ( ) ; } param { 'youtube' } service param { number } timestamp returns memberof addWebhookResub ( service , timestamp ) { let pResub = new this . pActions ( { from : Date . now ( ) , to : timestamp , action : pActionActions . resubWebhook , info : { service : service } } ) ; return pResub . save ( ) ; } }