2022-11-16 13:53:42 -05:00
import Discord from 'discord.js' ;
2022-11-13 19:18:15 -05:00
import { TClient } from './client' ;
2022-11-11 19:58:11 -05:00
const client = new TClient ;
client . init ( ) ;
2022-11-16 13:53:42 -05:00
import fs from 'node:fs' ;
import MPDB from './models/MPServer' ;
2022-12-18 23:06:00 -05:00
import { Punishment , UserLevels , FSData , FSCareerSavegame } from './typings/interfaces' ;
2022-11-11 19:58:11 -05:00
client . on ( 'ready' , async ( ) = > {
2022-11-22 16:47:48 -05:00
client . guilds . cache . forEach ( async ( e ) = > { await e . members . fetch ( ) } ) ;
2022-11-11 19:58:11 -05:00
setInterval ( async ( ) = > {
2023-01-01 20:09:03 -05:00
client . user . setPresence ( { activities : [ { name : '#general-chat' , type : 1 , url : 'https://www.youtube.com/watch?v=nhB5WoUYQbc' } ] , status : 'idle' } ) ;
2022-11-11 19:58:11 -05:00
// Playing: 0, Streaming (Requires YT/Twitch URL to work): 1, Listening to: 2, Watching: 3, Competing in: 5
} , 60000 ) ;
2023-01-01 20:09:03 -05:00
// ['929807948748832798', '468835415093411861', '1058183358267543552', '549114074273677314'] - 0=Dev Server, 1=Main Server, 2=Throne, 3=Toast's test server
if ( client . config . botSwitches . registerCommands ) {
2023-01-02 05:15:49 -05:00
[ '929807948748832798' , '468835415093411861' , '1058183358267543552' , '549114074273677314' ] . forEach ( ( guildId ) = > ( client . guilds . cache . get ( guildId ) as Discord . Guild ) . commands . set ( client . registry ) . catch ( ( e :Error ) = > {
2023-01-01 20:09:03 -05:00
console . log ( ` Couldn't register slash commands for ${ guildId } because ` , e . stack ) ;
( client . channels . resolve ( client . config . mainServer . channels . errors ) as Discord . TextChannel ) . send ( ` Cannot register slash commands for ** ${ client . guilds . cache . get ( guildId ) . name } ** ( \` ${ guildId } \` ): \ n \` \` \` ${ e . message } \` \` \` ` )
} ) ) ;
} ;
2022-11-11 19:58:11 -05:00
setInterval ( ( ) = > {
2022-11-13 19:18:15 -05:00
const guild = client . guilds . cache . get ( client . config . mainServer . id ) as Discord . Guild ;
guild . invites . fetch ( ) . then ( ( invs ) = > {
invs . forEach ( async ( inv ) = > {
client . invites . set ( inv . code , { uses : inv.uses , creator : inv.inviterId } )
2022-11-11 19:58:11 -05:00
} )
} )
} , 500000 ) ;
2022-11-13 19:18:15 -05:00
console . log ( ` ${ client . user . tag } has logged into Discord API and now ready for operation ` ) ;
console . log ( client . config . botSwitches ) ;
2022-11-22 16:29:02 -05:00
( client . channels . resolve ( client . config . mainServer . channels . bot_status ) as Discord . TextChannel ) . send ( ` ${ client . user . username } is active \ n \` \` \` json \ n ${ Object . entries ( client . config . botSwitches ) . map ( ( hi ) = > ` ${ hi [ 0 ] } : ${ hi [ 1 ] } ` ) . join ( '\n' ) } \` \` \` ` ) ;
2022-11-11 19:58:11 -05:00
// Event handler
2023-01-02 04:45:05 -05:00
fs . readdirSync ( 'src/events' ) . forEach ( ( file ) = > {
const eventFile = require ( ` ./events/ ${ file } ` ) ;
client . on ( file . replace ( '.ts' , '' ) , async ( . . . args ) = > eventFile . default . run ( client , . . . args ) ) ;
} ) ;
/ * c o n s t e v e n t F i l e s = f s . r e a d d i r S y n c ( ' s r c / e v e n t s ' ) . f i l t e r ( f i l e = > f i l e . e n d s W i t h ( ' . t s ' ) ) ;
2022-11-11 19:58:11 -05:00
eventFiles . forEach ( ( file ) = > {
const event = require ( ` ./events/ ${ file } ` ) ;
2022-11-16 13:53:42 -05:00
client . on ( event . default . name , async ( . . . args ) = > event . default . execute ( client , . . . args ) ) ;
2023-01-02 04:45:05 -05:00
} ) ; * /
2022-11-11 19:58:11 -05:00
} )
// Handle errors
2022-11-13 08:46:50 -05:00
process . on ( 'unhandledRejection' , async ( error : Error ) = > {
2022-11-13 19:18:15 -05:00
console . log ( error ) ;
2022-11-25 22:31:08 -05:00
( client . channels . resolve ( client . config . mainServer . channels . errors ) as Discord . TextChannel ) . send ( { embeds : [ new client . embed ( ) . setColor ( '#420420' ) . setTitle ( 'Error caught!' ) . setDescription ( ` **Error:** \` ${ error . message } \` \ n \ n**Stack:** \` ${ ` ${ error . stack } ` . slice ( 0 , 2500 ) } \` ` ) ] } )
2022-11-11 19:58:11 -05:00
} ) ;
2022-11-13 08:46:50 -05:00
process . on ( 'uncaughtException' , async ( error : Error ) = > {
2022-11-13 19:18:15 -05:00
console . log ( error ) ;
2022-11-18 22:23:33 -05:00
( client . channels . resolve ( client . config . mainServer . channels . errors ) as Discord . TextChannel ) . send ( { embeds : [ new client . embed ( ) . setColor ( '#420420' ) . setTitle ( 'Error caught!' ) . setDescription ( ` **Error:** \` ${ error . message } \` \ n \ n**Stack:** \` ${ ` ${ error . stack } ` . slice ( 0 , 2500 ) } \` ` ) ] } )
2022-11-11 19:58:11 -05:00
} ) ;
2022-11-13 08:46:50 -05:00
process . on ( 'error' , async ( error : Error ) = > {
2022-11-13 19:18:15 -05:00
console . log ( error ) ;
2022-11-18 22:23:33 -05:00
( client . channels . resolve ( client . config . mainServer . channels . errors ) as Discord . TextChannel ) . send ( { embeds : [ new client . embed ( ) . setColor ( '#420420' ) . setTitle ( 'Error caught!' ) . setDescription ( ` **Error:** \` ${ error . message } \` \ n \ n**Stack:** \` ${ ` ${ error . stack } ` . slice ( 0 , 2500 ) } \` ` ) ] } )
2022-11-11 19:58:11 -05:00
} ) ;
// Daggerwin MP loop
setInterval ( async ( ) = > {
if ( ! client . config . botSwitches . mpstats ) return ;
2022-11-22 16:31:55 -05:00
const msg = await ( client . channels . resolve ( '543494084363288637' ) as Discord . TextChannel ) . messages . fetch ( '1023699243183112192' )
2022-11-11 19:58:11 -05:00
const embed = new client . embed ( ) ;
let Players = [ ] ;
2022-12-18 23:06:00 -05:00
let error ;
2022-11-11 19:58:11 -05:00
// Connect to DB to retrieve the Gameserver info to fetch data.
2022-11-16 13:53:42 -05:00
MPDB . sync ( ) ;
2022-11-11 19:58:11 -05:00
const newServerId = client . config . mainServer . id
2022-11-16 13:53:42 -05:00
const ServerURL = MPDB . findOne ( { where : { serverId : newServerId } } )
const DBURL = ( await ServerURL ) . ip
2022-11-19 05:17:04 -05:00
const DBCode = ( await ServerURL ) . code
const verifyURL = DBURL . match ( /http/ ) ;
2022-11-11 19:58:11 -05:00
const completedURL_DSS = DBURL + '/feed/dedicated-server-stats.json?code=' + DBCode
const completedURL_CSG = DBURL + '/feed/dedicated-server-savegame.html?code=' + DBCode + '&file=careerSavegame'
2022-12-18 23:06:00 -05:00
const FSdss = {
data : { } as FSData ,
fetchResult : '' as string
} ;
const FScsg = {
data : { } as FSCareerSavegame ,
fetchResult : '' as string
} ;
2022-11-19 05:17:04 -05:00
if ( ! verifyURL ) return msg . edit ( { content : 'Invalid gameserver IP, please update!' , embeds : null } )
2022-12-18 23:06:00 -05:00
async function serverData ( client :TClient , URL : string ) {
2022-12-18 23:22:28 -05:00
return await client . axios . get ( URL , { timeout : 4000 , headers : { 'User-Agent' : ` Daggerbot/axios ${ client . axios . VERSION } ` } } ) . catch ( ( error :Error ) = > error . message )
2022-11-11 19:58:11 -05:00
}
2022-12-18 23:06:00 -05:00
await Promise . all ( [ serverData ( client , completedURL_DSS ) , serverData ( client , completedURL_CSG ) ] ) . then ( function ( results ) {
if ( typeof results [ 0 ] == 'string' ) {
FSdss . fetchResult = ` dag mp dss fail, ${ results [ 0 ] } ` ;
} else if ( results [ 0 ] . status != 200 ) {
FSdss . fetchResult = ` dag mp dss fail with ${ results [ 0 ] . status + ' ' + results [ 0 ] . statusText } ` ;
2022-11-16 13:53:42 -05:00
} else {
2022-12-18 23:06:00 -05:00
FSdss . data = results [ 0 ] . data as FSData
2022-11-16 13:53:42 -05:00
}
2022-12-18 23:06:00 -05:00
if ( typeof results [ 1 ] == 'string' ) {
FScsg . fetchResult = ` dag mp csg fail, ${ results [ 1 ] } ` ;
} else if ( results [ 1 ] . status != 200 ) {
FScsg . fetchResult = ` dag mp csg fail with ${ results [ 1 ] . status + ' ' + results [ 1 ] . statusText } ` ;
2022-11-16 13:53:42 -05:00
} else {
2022-12-18 23:06:00 -05:00
FScsg . data = client . xjs . xml2js ( results [ 1 ] . data , { compact :true , spaces :2 } ) . careerSavegame as FSCareerSavegame ;
2022-11-16 13:53:42 -05:00
}
2022-12-18 23:06:00 -05:00
} ) . catch ( ( error ) = > console . log ( error ) )
if ( FSdss . fetchResult . length != 0 ) {
error = true ;
console . log ( ` [ ${ client . moment ( ) . format ( 'DD/MM/YY HH:mm:ss' ) } ] ` , FSdss . fetchResult ) ;
}
if ( FScsg . fetchResult . length != 0 ) {
error = true ;
console . log ( ` [ ${ client . moment ( ) . format ( 'DD/MM/YY HH:mm:ss' ) } ] ` , FScsg . fetchResult ) ;
}
if ( error ) { // Blame RedRover and Nawdic
embed . setTitle ( 'Host is not responding' ) . setColor ( client . config . embedColorRed ) ;
msg . edit ( { content : null , embeds : [ embed ] } )
return ;
2022-11-11 19:58:11 -05:00
}
const DB = require ( ` ./database/MPPlayerData.json ` ) ;
2022-12-18 23:06:00 -05:00
DB . push ( FSdss . data . slots . used )
2022-11-16 13:53:42 -05:00
fs . writeFileSync ( __dirname + ` /database/MPPlayerData.json ` , JSON . stringify ( DB ) )
2022-11-11 19:58:11 -05:00
// Number format function
function formatNumber ( number : any , digits : any , icon : any ) {
var n = Number ( number )
return n . toLocaleString ( undefined , { minimumFractionDigits : digits } ) + icon
}
2022-12-18 23:06:00 -05:00
if ( FSdss . data . server . name . length == 0 ) {
2022-11-11 19:58:11 -05:00
embed . setTitle ( 'The server seems to be offline.' ) . setColor ( client . config . embedColorRed ) ;
2022-11-16 13:53:42 -05:00
msg . edit ( { content : 'This embed will resume when server is back online.' , embeds : [ embed ] } )
2022-11-11 19:58:11 -05:00
} else {
const embed1 = new client . embed ( ) . setColor ( client . config . embedColor ) . setTitle ( 'Server details' ) . addFields (
2022-12-18 23:06:00 -05:00
{ name : 'Current Map' , value : ` ${ FSdss . data . server . mapName . length == 0 ? '\u200b' : FSdss . data . server . mapName } ` , inline : true } ,
{ name : 'Version' , value : ` ${ FSdss . data . server . version . length == 0 ? '\u200b' : FSdss . data . server . version } ` , inline : true } ,
{ name : 'In-game Time' , value : ` ${ ( '0' + Math . floor ( ( FSdss . data . server . dayTime / 3600 / 1000 ) ) ) . slice ( - 2 ) } : ${ ( '0' + Math . floor ( ( FSdss . data . server . dayTime / 60 / 1000 ) % 60 ) ) . slice ( - 2 ) } ` , inline : true } ,
{ name : 'Slot Usage' , value : ` ${ Number ( FScsg . data . slotSystem . _attributes . slotUsage ) . toLocaleString ( 'en-US' ) } ` , inline : true } ,
{ name : 'Timescale' , value : ` ${ formatNumber ( Number ( FScsg . data . settings . timeScale . _text ) , 0 , 'x' ) } ` , inline : true }
2022-11-11 19:58:11 -05:00
) ;
2022-12-18 23:06:00 -05:00
FSdss . data . slots . players . filter ( ( x ) = > x . isUsed !== false ) . forEach ( player = > {
2022-11-16 13:53:42 -05:00
Players . push ( ` ** ${ player . name } ${ player . isAdmin ? '| admin' : '' } ** \ nFarming for ${ ( Math . floor ( player . uptime / 60 ) ) } hr & ${ ( '0' + ( player . uptime % 60 ) ) . slice ( - 2 ) } min ` )
2022-11-11 19:58:11 -05:00
} )
2022-12-18 23:06:00 -05:00
embed . setDescription ( ` ${ FSdss . data . slots . used == 0 ? '*No players online*' : Players . join ( '\n\n' ) } ` ) . setTitle ( FSdss . data . server . name ) . setColor ( client . config . embedColor )
embed . setAuthor ( { name : ` ${ FSdss . data . slots . used } / ${ FSdss . data . slots . capacity } ` } ) ;
2022-11-16 13:53:42 -05:00
msg . edit ( { content : 'This embed updates every minute.' , embeds : [ embed1 , embed ] } )
2022-11-11 19:58:11 -05:00
}
} , 60000 )
// YouTube Upload notification
setInterval ( async ( ) = > {
2022-11-22 16:47:48 -05:00
client . YTLoop ( 'UCQ8k8yTDLITldfWYKDs3xFg' , 'Daggerwin' , '528967918772551702' ) ; // 528967918772551702 = #videos-and-streams
2022-11-16 13:53:42 -05:00
client . YTLoop ( 'UCguI73--UraJpso4NizXNzA' , 'Machinery Restorer' , '767444045520961567' ) // 767444045520961567 = #machinery-restorer
2022-11-11 19:58:11 -05:00
} , 300000 )
// Event loop for punishments and daily msgs
setInterval ( async ( ) = > {
2022-11-21 17:37:23 -05:00
const now = Date . now ( ) ;
2022-11-11 19:58:11 -05:00
const lrsStart = client . config . LRSstart ;
2022-11-13 08:46:50 -05:00
2022-11-15 09:06:18 -05:00
client . punishments . _content . filter ( ( x :Punishment ) = > x . endTime <= now && ! x . expired ) . forEach ( async ( punishment :Punishment ) = > {
2022-11-24 19:28:46 -05:00
console . log ( ` [ ${ client . moment ( ) . format ( 'DD/MM/YY HH:mm:ss' ) } ] ` + ` ${ punishment . member } \ 's ${ punishment . type } should expire now ` ) ;
2022-11-13 08:46:50 -05:00
const unpunishResult = await client . punishments . removePunishment ( punishment . id , client . user . id , 'Time\'s up!' ) ;
2022-11-24 19:28:46 -05:00
console . log ( ` [ ${ client . moment ( ) . format ( 'DD/MM/YY HH:mm:ss' ) } ] ` + unpunishResult ) ;
2022-11-11 19:58:11 -05:00
} ) ;
2022-11-13 08:46:50 -05:00
2022-11-11 19:58:11 -05:00
const formattedDate = Math . floor ( ( now - lrsStart ) / 1000 / 60 / 60 / 24 ) ;
const dailyMsgs = require ( './database/dailyMsgs.json' ) ;
2022-11-21 17:37:23 -05:00
if ( ! dailyMsgs . some ( ( x :Array < number > ) = > x [ 0 ] === formattedDate ) ) {
2022-11-13 08:46:50 -05:00
let total = Object . values < UserLevels > ( client . userLevels . _content ) . reduce ( ( a , b ) = > a + b . messages , 0 ) ; // sum of all users
2022-11-15 09:06:18 -05:00
const yesterday = dailyMsgs . find ( ( x :Array < number > ) = > x [ 0 ] === formattedDate - 1 ) ;
2022-11-11 19:58:11 -05:00
if ( total < yesterday ) { // messages went down.
total = yesterday
}
dailyMsgs . push ( [ formattedDate , total ] ) ;
2022-11-17 12:58:19 -05:00
fs . writeFileSync ( __dirname + '/database/dailyMsgs.json' , JSON . stringify ( dailyMsgs ) )
2022-12-22 23:27:02 -05:00
console . log ( ` [ ${ client . moment ( ) . format ( 'DD/MM/YY HH:mm:ss' ) } ] ` , ` Pushed [ ${ formattedDate } , ${ total } ] to dailyMsgs ` ) ;
2023-01-02 01:40:19 -05:00
client . guilds . cache . get ( client . config . mainServer . id ) . commands . fetch ( ) . then ( ( commands ) = > ( client . channels . resolve ( client . config . mainServer . channels . logs ) as Discord . TextChannel ) . send ( ` :pencil: Pushed \` [ ${ formattedDate } , ${ total } ] \` to </rank leaderboard: ${ commands . find ( x = > x . name == 'rank' ) . id } > ` ) )
2022-11-11 19:58:11 -05:00
}
2022-11-22 16:29:02 -05:00
} , 5000 )