2022-11-16 13:53:42 -05:00
import Discord from 'discord.js' ;
2023-04-14 06:47:58 -04:00
import TClient from './client.js' ;
2022-11-11 19:58:11 -05:00
const client = new TClient ;
client . init ( ) ;
2023-09-29 17:27:32 -04:00
import Logger from './helpers/Logger.js' ;
2023-12-24 10:21:40 -05:00
import YTModule from './modules/YTModule.js' ;
2024-02-03 21:09:33 -05:00
import CacheServer from './components/CacheServer.js' ;
2023-12-24 10:21:40 -05:00
import MPModule , { refreshTimerSecs } from './modules/MPModule.js' ;
2023-10-08 18:03:17 -04:00
import UsernameHelper from './helpers/UsernameHelper.js' ;
2024-01-22 16:57:07 -05:00
import { Punishment , RawGatewayPacket , RawMessageDelete , RawMessageUpdate } from 'src/interfaces' ;
2023-12-24 10:21:40 -05:00
import { readFileSync } from 'node:fs' ;
2024-01-22 16:57:07 -05:00
export const disabledChannels = [ '548032776830582794' , '541677709487505408' , '949380187668242483' ] ;
2022-11-11 19:58:11 -05:00
2023-06-24 13:47:42 -04:00
// Error handler
2023-12-24 10:21:40 -05:00
function _ ( error :Error , type : string ) {
2023-10-08 18:03:17 -04:00
if ( JSON . parse ( readFileSync ( 'src/errorBlocklist.json' , 'utf8' ) ) . includes ( error . message ) ) return ;
2023-08-11 08:19:13 -04:00
console . error ( error ) ;
2024-02-17 13:54:55 -05:00
( client . channels . resolve ( client . config . dcServer . channels . errors ) as Discord . TextChannel | null ) ? . send ( { embeds : [ new client . embed ( ) . setColor ( '#560000' ) . setTitle ( 'Error caught!' ) . setFooter ( { text : ` Error type: ${ type } ` } ) . setDescription ( ` **Error:** \ n \` \` \` ${ error . message } \` \` \` **Stack:** \ n \` \` \` ${ ` ${ UsernameHelper ( error . stack ) } ` . slice ( 0 , 2500 ) } \` \` \` ` ) ] } ) ;
2023-01-11 03:33:38 -05:00
}
2023-12-24 10:21:40 -05:00
process . on ( 'unhandledRejection' , ( error : Error ) = > _ ( error , 'unhandledRejection' ) ) ;
process . on ( 'uncaughtException' , ( error : Error ) = > _ ( error , 'uncaughtException' ) ) ;
process . on ( 'error' , ( error : Error ) = > _ ( error , 'processError' ) ) ;
client . on ( 'error' , ( error : Error ) = > _ ( error , 'clientError' ) ) ;
2024-02-25 04:01:04 -05:00
if ( ( typeof process . argv [ 4 ] === 'string' && process . argv [ 4 ] === 'true' ) ? ? null ) client . on ( 'debug' , console . log ) ;
2022-11-11 19:58:11 -05:00
2023-12-24 10:21:40 -05:00
// Interval timers for modules
2023-12-24 22:02:59 -05:00
setInterval ( async ( ) = > await MPModule ( client ) , refreshTimerSecs ) ;
2023-12-24 10:21:40 -05:00
setInterval ( ( ) = > YTModule ( client ) , 180000 ) ; // 3 minutes
2024-02-18 21:38:17 -05:00
setInterval ( async ( ) = > {
const forum = client . guilds . cache . get ( client . config . dcServer . id ) . channels . cache . get ( client . config . dcServer . channels . help_forum ) as Discord . ForumChannel ;
await forum . threads . fetch ( ) ;
for await ( const thread of forum . threads . cache . values ( ) ) {
await thread . messages . fetch ( ) ;
2024-02-19 00:29:01 -05:00
if ( ! thread . archived && thread . lastMessage . createdTimestamp <= Date . now ( ) - 1555200000 ) { // check if thread is inactive for over 18 days
2024-02-26 05:02:51 -05:00
await thread . delete ( ) ;
2024-02-25 04:01:04 -05:00
Logger . console ( 'log' , 'ThreadTimer' , ` "# ${ thread . name } " has been deleted due to inactivity for 18 days ` ) ;
2024-02-18 21:38:17 -05:00
}
}
} , 1200000 ) ; // 20 minutes
2022-11-11 19:58:11 -05:00
// Event loop for punishments and daily msgs
setInterval ( async ( ) = > {
2023-03-05 05:04:10 -05:00
const now = Date . now ( ) ;
2023-05-23 01:14:17 -04:00
2024-01-17 20:13:11 -05:00
const checkExpiration = await client . userLevels . fetchEveryone ( ) ;
checkExpiration . filter ( x = > x . isBlocked && x . time <= now ) . forEach ( async user = > {
Logger . console ( 'log' , 'LevelSystem' , ` ${ user . dataValues . id } 's block should expire now ` ) ;
user . update ( { isBlocked : false , time : null } , { where : { id : user.dataValues.id } } ) ;
client . users . send ( user . dataValues . id , ` Your rank block has expired, you can now continue to progress your level. ` ) ;
} ) ;
2023-10-02 18:40:03 -04:00
const punishments = await client . punishments . findInCache ( ) ;
2023-12-24 10:21:40 -05:00
punishments . filter ( ( x :Punishment ) = > x . endTime && x . endTime <= now && ! x . expired ) . forEach ( async ( punishment :Punishment ) = > {
2024-02-03 21:09:33 -05:00
let key = ` punishment_handled: ${ punishment . case_id } ` ;
if ( await CacheServer . get ( key , false ) ) return ;
await CacheServer . set ( key , true , false ) . then ( async ( ) = > await CacheServer . expiry ( key , 35 ) ) ;
2023-12-24 10:21:40 -05:00
Logger . console ( 'log' , 'Punishment' , ` ${ punishment . member } \ 's ${ punishment . type } should expire now ` ) ;
Logger . console ( 'log' , 'Punishment' , await client . punishments . punishmentRemove ( punishment . case_id , client . user . id , 'Time\'s up!' ) ) ;
2023-03-05 05:04:10 -05:00
} ) ;
2023-05-23 01:14:17 -04:00
2023-07-07 09:49:24 -04:00
const formattedDate = Math . floor ( ( now - client . config . LRSstart ) / 1000 / 60 / 60 / 24 ) ;
2023-12-24 10:21:40 -05:00
const dailyMsgs = await client . dailyMsgs . fetchDays ( ) ;
if ( client . config . botSwitches . dailyMsgsBackup && ! dailyMsgs . some ( x = > x [ 0 ] === formattedDate ) ) {
if ( ! dailyMsgs . find ( x = > x . dataValues . day === formattedDate ) ) {
let total = ( await client . userLevels . fetchEveryone ( ) ) . reduce ( ( a , b ) = > a + b . messages , 0 ) ; // Sum of all users
const yesterday = dailyMsgs . find ( x = > x . day === formattedDate - 1 )
if ( total < yesterday ? . total ) total = yesterday . total ; // Messages went down.
await client . dailyMsgs . newDay ( formattedDate , total ) ;
Logger . console ( 'log' , 'DailyMsgs' , ` Pushed [ ${ formattedDate } , ${ total } ] ` )
2023-10-05 07:56:29 -04:00
2023-12-31 02:12:44 -05:00
// Send notification to #bot-log that the data has been pushed to database.
2023-12-24 10:21:40 -05:00
const commands = await client . guilds . cache . get ( client . config . dcServer . id ) ? . commands . fetch ( ) ;
if ( commands ) ( client . channels . resolve ( client . config . dcServer . channels . logs ) as Discord . TextChannel ) . send ( { embeds : [
new client . embed ( ) . setDescription ( ` Pushed the following \ ndata to </rank leaderboard: ${ commands . find ( x = > x . name === 'rank' ) . id } > ` ) . setFields (
{ name : 'Day' , value : formattedDate.toString ( ) , inline : true } ,
{ name : 'Messages' , value : Intl.NumberFormat ( 'en-us' ) . format ( total ) . toString ( ) , inline : true }
) . setColor ( client . config . embedColor )
] } ) ;
else Logger . console ( 'log' , 'DailyMsgs' , 'Rank command not found, cannot send notification in channel' )
}
2023-03-05 05:04:10 -05:00
}
2022-11-22 16:29:02 -05:00
} , 5000 )
2023-12-24 10:21:40 -05:00
2024-01-16 01:26:26 -05:00
if ( client . config . botSwitches . dailyMsgsBackup ) {
client . userLevels . initSelfdestruct ( ) ;
client . userLevels . dataSweeper ( ) ;
}
// Cronjob tasks
2024-01-22 16:57:07 -05:00
// Raw gateway event receivers
export let rawSwitches = {
MESSAGE_UPDATE : false ,
MESSAGE_DELETE : false
} ;
2024-01-22 17:15:40 -05:00
if ( ! client . config . botSwitches . logs ) {
rawSwitches . MESSAGE_DELETE = true ;
rawSwitches . MESSAGE_UPDATE = true ;
} ;
2024-01-22 16:57:07 -05:00
client . on ( 'raw' , async ( packet :RawGatewayPacket < RawMessageUpdate > ) = > {
2024-02-25 04:01:04 -05:00
if ( rawSwitches [ packet . t ] || packet . t !== 'MESSAGE_UPDATE' ) return ;
if ( packet . d . guild_id != client . config . dcServer . id || disabledChannels . includes ( packet . d . channel_id ) || typeof packet . d . content === 'undefined' ) return ;
2024-01-22 16:57:07 -05:00
const channel = client . channels . cache . get ( packet . d . channel_id ) as Discord . TextBasedChannel ;
2024-01-26 12:33:59 -05:00
2024-02-25 04:01:04 -05:00
// Switched to console.log to prevent useless embed creation that has same content as the original message.
2024-02-25 07:18:33 -05:00
if ( ! rawSwitches . MESSAGE_UPDATE && ! packet . d . author . bot ) return Logger . console ( 'log' , 'RawEvent:Edit' , ` Message was edited in # ${ ( channel as Discord . TextChannel ) . name } ` ) ;
2024-01-22 16:57:07 -05:00
} ) ;
client . on ( 'raw' , async ( packet :RawGatewayPacket < RawMessageDelete > ) = > {
if ( rawSwitches [ packet . t ] ) return ;
if ( packet . t !== 'MESSAGE_DELETE' || packet . d . guild_id != client . config . dcServer . id || disabledChannels . includes ( packet . d . channel_id ) ) return ;
2024-02-17 13:54:55 -05:00
Logger . console ( 'log' , 'RawEvent:Del' , ` Message was deleted in # ${ ( client . channels . resolve ( packet . d . channel_id ) as Discord . TextChannel ) . name } ` ) ;
2024-01-22 16:57:07 -05:00
rawSwitches [ packet . t ] = true ;
} ) ;