2023-02-24 19:55:11 -05:00
import Discord from 'discord.js' ;
2023-04-14 06:47:58 -04:00
import TClient from '../client.js' ;
2023-12-24 10:21:40 -05:00
import MessageTool from '../helpers/MessageTool.js' ;
import DatabaseServer from '../components/DatabaseServer.js' ;
import { Model , DataTypes } from 'sequelize' ;
2023-12-31 19:14:17 -05:00
import { writeFileSync } from 'node:fs' ;
2023-10-05 07:56:29 -04:00
import cron from 'node-cron' ;
2023-09-29 17:27:32 -04:00
import Logger from '../helpers/Logger.js' ;
2023-02-24 19:55:11 -05:00
2023-12-24 10:21:40 -05:00
class userLevels extends Model {
declare public id : string ;
declare public messages : number ;
declare public level : number ;
declare public pingToggle : boolean ;
}
export class UserLevelsSvc {
private client : TClient ;
private model : typeof userLevels ;
2023-02-24 19:55:11 -05:00
2023-12-24 10:21:40 -05:00
constructor ( client :TClient ) {
2023-02-24 19:55:11 -05:00
this . client = client ;
2023-12-24 10:21:40 -05:00
this . model = userLevels ;
this . model . init ( {
id : {
type : DataTypes . STRING ,
unique : true ,
primaryKey : true
} ,
messages : {
type : DataTypes . INTEGER ,
allowNull : false ,
} ,
level : {
type : DataTypes . INTEGER ,
allowNull : false ,
} ,
pingToggle : {
type : DataTypes . BOOLEAN ,
allowNull : true ,
}
} , {
tableName : 'userlevels' ,
createdAt : false ,
updatedAt : false ,
sequelize : DatabaseServer.seq
} ) ;
this . model . sync ( ) ;
}
async fetchEveryone() {
return await this . model . findAll ( ) ;
}
async fetchUser ( userId :string ) {
return await this . model . findByPk ( userId ) ;
}
async deleteUser ( userId :string ) {
return await this . model . destroy ( { where : { id : userId } } ) ;
2023-02-24 19:55:11 -05:00
}
2024-01-07 19:37:20 -05:00
async modifyUser ( userId :string , updatedMessages :number ) {
await this . model . update ( { messages : updatedMessages } , { where : { id : userId } } ) ;
return ( await this . model . findByPk ( userId ) ) . dataValues ;
}
2024-01-14 00:31:26 -05:00
async getActiveUsers() {
const members = ( await this . model . findAll ( ) ) . sort ( ( a , b ) = > b . dataValues . messages - a . dataValues . messages ) ;
return members . slice ( 0 , 5 ) ;
}
2023-12-24 10:21:40 -05:00
async messageIncremental ( userId :string ) {
const data = await this . model . findByPk ( userId ) ;
if ( data ) {
await this . model . update ( { messages : data.dataValues.messages + 1 } , { where : { id : userId } } ) ;
if ( data . messages >= this . algorithm ( data . dataValues . level + 2 ) ) {
const oldLevel = data . dataValues . level ;
while ( data . messages > this . algorithm ( data . dataValues . level + 1 ) ) await this . model . update ( { level : data.dataValues.level ++ } , { where : { id : userId } } ) ;
const updatedUser = await this . model . findByPk ( userId ) ;
Logger . console ( 'log' , 'LevelSystem' , ` ${ userId } superseded to level ${ updatedUser . dataValues . level } from ${ oldLevel } ` ) ;
} else if ( data . dataValues . messages >= this . algorithm ( data . dataValues . level + 1 ) ) {
await this . model . update ( { level : data.dataValues.level + 1 } , { where : { id : userId } } ) ;
const getUser = await this . model . findByPk ( userId ) ;
const levelUpMsg = ` ${ getUser . pingToggle === true ? ` <@ ${ userId } > ` : ` ** ${ ( await this . client . users . fetch ( userId ) ) . displayName } ** ` } has reached level ** ${ getUser . level } **. Well done! ` ;
( this . client . channels . resolve ( this . client . config . dcServer . channels . botcommands ) as Discord . TextChannel ) . send ( { content : levelUpMsg , allowedMentions : { parse : [ 'users' ] } } ) ;
}
} else await this . model . create ( { id : userId , messages : 1 , level : 0 , pingToggle : true } ) ;
}
async initSelfdestruct() {
// Every 1st of January at 11:00 (Midnight in London, Middayish in Sydney)
2023-10-06 19:57:14 -04:00
cron . schedule ( '0 11 1 1 *' , async ( ) = > {
2023-12-24 10:21:40 -05:00
Logger . console ( 'log' , 'Cron' , 'Running job "resetAllData", this is activated every 1st of January' ) ;
const performCountBeforeReset = await this . model . count ( ) ;
2024-01-14 00:31:26 -05:00
const topMembers = await this . getActiveUsers ( ) ;
2023-12-31 02:30:10 -05:00
Logger . console ( 'log' , 'Cron:resetAllData' , ` Counted ${ performCountBeforeReset . toLocaleString ( ) } members before reset ` ) ;
2023-12-24 10:21:40 -05:00
await this . client . dailyMsgs . nukeDays ( ) ;
await this . model . drop ( ) . then ( async ( ) = > await this . model . sync ( ) ) ;
2024-01-14 00:31:26 -05:00
try {
// Send notification to dcServer's logs channel after cronjob is complete.
( this . client . channels . resolve ( this . client . config . dcServer . channels . logs ) as Discord . TextChannel ) . send ( { embeds : [ new this . client . embed ( )
. setColor ( '#A3FFE3' )
. setTitle ( 'Yearly data reset has begun!' )
. setDescription ( MessageTool . concatMessage (
'I have gone ahead and reset everyone\'s rank data.' ,
` There was ${ Intl . NumberFormat ( 'en-US' ) . format ( performCountBeforeReset ) } members in database before reset. \ n ` ,
'Top 5 most active members:' ,
. . . topMembers . map ( ( m , i ) = > ` ${ i + 1 } . ** ${ ( this . client . users . resolve ( m . dataValues . id ) ? this . client . users . resolve ( m . dataValues . id ) . displayName : '*Unknown User*' ) } ** - ** ${ m . dataValues . messages . toLocaleString ( ) } ** messages ` )
) )
] } ) ;
} catch ( why ) {
Logger . console ( 'error' , 'Cron:resetAllData:DEBUG' , why )
}
2023-10-05 07:56:29 -04:00
2023-12-24 10:21:40 -05:00
// Reset LRSstart to current Epoch and save it to config file
2023-10-05 07:56:29 -04:00
const newEpoch = new Date ( ) . getTime ( ) ;
this . client . config . LRSstart = newEpoch ;
const logText = ` Resetting LRSstart to \` ${ newEpoch } \` , saved to config file ` ;
2023-12-24 10:21:40 -05:00
Logger . console ( 'log' , 'DailyMsgs' , logText ) ;
( this . client . channels . resolve ( this . client . config . dcServer . channels . logs ) as Discord . TextChannel ) . send ( { embeds : [ new this . client . embed ( )
2023-12-31 10:10:17 -05:00
. setColor ( this . client . config . embedColorXmas )
. setTitle ( 'Happy New Years! Level System is clean!' )
. setDescription ( logText )
2023-12-24 10:21:40 -05:00
] } ) . catch ( err = > console . log ( err ) ) ;
writeFileSync ( 'src/config.json' , JSON . stringify ( this . client . config , null , 2 ) ) ;
Logger . console ( 'log' , 'Cron:resetAllData' , 'Job completed' ) ;
2023-10-05 07:56:29 -04:00
} )
}
2023-12-25 12:00:17 -05:00
algorithm = ( level :number ) = > level * level * 15 ;
2023-12-24 10:21:40 -05:00
// Algorithm for determining levels. If adjusting, recommended to only change the integer at the end of equation.
2023-12-31 19:14:17 -05:00
// Requires rank data to be reset if changed as it causes unexpected results.
2023-02-24 19:55:11 -05:00
}