Class commands, improved sharding, and many other changes (#88)
* Load commands recursively
* Sort commands
* Missed a couple of spots
* missed even more spots apparently
* Ported commands in "fun" category to new class-based format, added babel eslint plugin
* Ported general commands, removed old/unneeded stuff, replaced moment with day, many more fixes I lost track of
* Missed a spot
* Removed unnecessary abort-controller package, add deprecation warning for mongo database
* Added imagereload, clarified premature end message
* Fixed docker-compose path issue, added total bot uptime to stats, more fixes for various parts
* Converted image commands into classes, fixed reload, ignore another WS event, cleaned up command handler and image runner
* Converted music/soundboard commands to class format
* Cleanup unnecessary logs
* awful tag command class port
* I literally somehow just learned that you can leave out the constructor in classes
* Pass client directly to commands/events, cleaned up command handler
* Migrated bot to eris-sharder, fixed some error handling stuff
* Remove unused modules
* Fixed type returning
* Switched back to Eris stable
* Some fixes and cleanup
* might wanna correct this
* Implement image command ratelimiting
* Added Bot token prefix, added imagestats, added running endpoint to API
2021-04-12 16:16:12 +00:00
if ( process . platform === "win32" ) console . error ( "\x1b[1m\x1b[31m\x1b[40m" + ` WIN32 IS NOT OFFICIALLY SUPPORTED!
2020-12-03 16:30:33 +00:00
Although there ' s a ( very ) slim chance of it working , multiple aspects of the bot are built with UNIX - like systems in mind and could break on Win32 - based systems . If you want to run the bot on Windows , using Windows Subsystem for Linux is highly recommended .
The bot will continue to run past this message , but keep in mind that it could break at any time . Continue running at your own risk ; alternatively , stop the bot using Ctrl + C and install WSL . ` + " \x 1b[0m");
2022-01-07 17:44:18 +00:00
if ( process . versions . node . split ( "." ) [ 0 ] < 15 ) {
console . error ( ` You are currently running Node.js version ${ process . version } .
esmBot requires Node . js version 15 or above .
Please refer to step 3 of the setup guide . ` );
process . exit ( 1 ) ;
}
2020-12-03 16:30:33 +00:00
2019-11-13 00:09:06 +00:00
// load config from .env file
2022-03-12 02:28:35 +00:00
import { resolve , dirname } from "path" ;
import { fileURLToPath } from "url" ;
2021-08-19 14:19:14 +00:00
import { config } from "dotenv" ;
2022-03-12 02:28:35 +00:00
config ( { path : resolve ( dirname ( fileURLToPath ( import . meta . url ) ) , ".env" ) } ) ;
2019-11-13 00:09:06 +00:00
2021-04-21 18:35:06 +00:00
// main sharding manager
2021-08-19 14:19:14 +00:00
import { Fleet } from "eris-fleet" ;
import { isMaster } from "cluster" ;
2021-11-12 23:21:43 +00:00
// main services
import Shard from "./shard.js" ;
import ImageWorker from "./utils/services/image.js" ;
import PrometheusWorker from "./utils/services/prometheus.js" ;
2021-07-05 13:14:52 +00:00
// some utils
2022-03-10 21:24:24 +00:00
import { promises , readFileSync } from "fs" ;
2021-08-19 14:19:14 +00:00
import winston from "winston" ;
2022-08-04 01:54:07 +00:00
import "winston-daily-rotate-file" ;
2021-09-17 02:37:36 +00:00
import { exec as baseExec } from "child_process" ;
import { promisify } from "util" ;
2022-03-10 21:24:24 +00:00
2021-09-17 02:37:36 +00:00
const exec = promisify ( baseExec ) ;
2022-02-22 00:55:25 +00:00
// database stuff
import database from "./utils/database.js" ;
2021-04-21 18:35:06 +00:00
// dbl posting
2021-08-19 14:19:14 +00:00
import { Api } from "@top-gg/sdk" ;
2022-01-15 05:26:38 +00:00
const dbl = process . env . NODE _ENV === "production" && process . env . DBL ? new Api ( process . env . DBL ) : null ;
Class commands, improved sharding, and many other changes (#88)
* Load commands recursively
* Sort commands
* Missed a couple of spots
* missed even more spots apparently
* Ported commands in "fun" category to new class-based format, added babel eslint plugin
* Ported general commands, removed old/unneeded stuff, replaced moment with day, many more fixes I lost track of
* Missed a spot
* Removed unnecessary abort-controller package, add deprecation warning for mongo database
* Added imagereload, clarified premature end message
* Fixed docker-compose path issue, added total bot uptime to stats, more fixes for various parts
* Converted image commands into classes, fixed reload, ignore another WS event, cleaned up command handler and image runner
* Converted music/soundboard commands to class format
* Cleanup unnecessary logs
* awful tag command class port
* I literally somehow just learned that you can leave out the constructor in classes
* Pass client directly to commands/events, cleaned up command handler
* Migrated bot to eris-sharder, fixed some error handling stuff
* Remove unused modules
* Fixed type returning
* Switched back to Eris stable
* Some fixes and cleanup
* might wanna correct this
* Implement image command ratelimiting
* Added Bot token prefix, added imagestats, added running endpoint to API
2021-04-12 16:16:12 +00:00
2021-07-05 13:14:52 +00:00
if ( isMaster ) {
2021-08-19 14:19:14 +00:00
const esmBotVersion = JSON . parse ( readFileSync ( new URL ( "./package.json" , import . meta . url ) ) ) . version ;
const erisFleetVersion = JSON . parse ( readFileSync ( new URL ( "./node_modules/eris-fleet/package.json" , import . meta . url ) ) ) . version ; // a bit of a hacky way to get the eris-fleet version
2021-07-05 13:14:52 +00:00
console . log ( `
, * \ ` $ z \` "v
F zBw \ ` % A ,W "W
, \ ` ,EBBBWp"%. ,-=~~==-,+* 4BBE T
M BBBBBBBB * , w = # # # # Wpw 4 BBBBB # 1
F BBBBBBBMwBBBBBBBBBBBBB # wXBBBBBH E
F BBBBBBkBBBBBBBBBBBBBBBBBBBBE4BL k
# BFBBBBBBBBBBBBF " " RBBBW F
V ' 4 BBBBBBBBBBM TBBL F
F BBBBBBBBBBF JBB L
F FBBBBBBBEB BBL 4
E [ BB4BBBBEBL BBL 4
I # BBBBBBBEB 4 BBH * w
A 4 BBBBBBBBBEW , , BBBB W [
. A , k 4 BBBBBBBBBBBEBW # # # # BBBBBBM BF F
k < BBBw BBBBEBBBBBBBBBBBBBBBBBQ4BM #
5 , REBBB4BBBBB # BBBBBBBBBBBBP5BFF , F
* w \ ` *4BBW \` "FF#F##FFFF" \` , * +"
* + , " F'" ' * ^ ~ ~ ~ ^ " ^ \ ` V+*^
\ ` """
2022-02-18 16:39:40 +00:00
esmBot $ { esmBotVersion } ( $ { ( await exec ( "git rev-parse HEAD" ) . then ( output => output . stdout . substring ( 0 , 7 ) , ( ) => "unknown commit" ) ) } ) , powered by eris - fleet $ { erisFleetVersion }
2021-07-05 13:14:52 +00:00
` );
}
2021-07-05 04:15:27 +00:00
const Admiral = new Fleet ( {
2021-11-12 23:21:43 +00:00
BotWorker : Shard ,
2021-07-05 04:15:27 +00:00
token : ` Bot ${ process . env . TOKEN } ` ,
2021-11-12 23:21:43 +00:00
fetchTimeout : 900000 ,
2022-08-13 17:40:22 +00:00
maxConcurrencyOverride : 1 ,
2021-07-05 04:15:27 +00:00
startingStatus : {
status : "idle" ,
game : {
name : "Starting esmBot..."
}
} ,
2021-07-06 00:20:21 +00:00
whatToLog : {
blacklist : [ "stats_update" ]
} ,
Class commands, improved sharding, and many other changes (#88)
* Load commands recursively
* Sort commands
* Missed a couple of spots
* missed even more spots apparently
* Ported commands in "fun" category to new class-based format, added babel eslint plugin
* Ported general commands, removed old/unneeded stuff, replaced moment with day, many more fixes I lost track of
* Missed a spot
* Removed unnecessary abort-controller package, add deprecation warning for mongo database
* Added imagereload, clarified premature end message
* Fixed docker-compose path issue, added total bot uptime to stats, more fixes for various parts
* Converted image commands into classes, fixed reload, ignore another WS event, cleaned up command handler and image runner
* Converted music/soundboard commands to class format
* Cleanup unnecessary logs
* awful tag command class port
* I literally somehow just learned that you can leave out the constructor in classes
* Pass client directly to commands/events, cleaned up command handler
* Migrated bot to eris-sharder, fixed some error handling stuff
* Remove unused modules
* Fixed type returning
* Switched back to Eris stable
* Some fixes and cleanup
* might wanna correct this
* Implement image command ratelimiting
* Added Bot token prefix, added imagestats, added running endpoint to API
2021-04-12 16:16:12 +00:00
clientOptions : {
allowedMentions : {
everyone : false ,
roles : false ,
users : true ,
repliedUser : true
} ,
2021-12-13 23:09:05 +00:00
restMode : true ,
2021-10-23 18:58:19 +00:00
messageLimit : 50 ,
2021-04-15 00:57:35 +00:00
intents : [
"guilds" ,
"guildVoiceStates" ,
"guildMessages" ,
2021-08-14 02:36:13 +00:00
"directMessages"
2021-06-26 20:56:02 +00:00
] ,
stats : {
requestTimeout : 30000
2022-06-09 20:17:33 +00:00
} ,
connectionTimeout : 30000
2021-07-06 00:20:21 +00:00
} ,
2022-03-31 05:42:03 +00:00
useCentralRequestHandler : process . env . DEBUG _LOG ? false : true , // workaround for eris-fleet weirdness
2021-07-06 00:20:21 +00:00
services : [
2021-11-12 23:21:43 +00:00
{ name : "prometheus" , ServiceWorker : PrometheusWorker } ,
{ name : "image" , ServiceWorker : ImageWorker }
2021-07-06 00:20:21 +00:00
]
2021-04-21 18:35:06 +00:00
} ) ;
2021-07-05 04:15:27 +00:00
if ( isMaster ) {
2021-07-05 13:14:52 +00:00
const logger = winston . createLogger ( {
2021-08-14 21:15:21 +00:00
levels : {
2021-07-05 13:14:52 +00:00
error : 0 ,
warn : 1 ,
info : 2 ,
main : 3 ,
debug : 4
} ,
transports : [
2021-08-09 15:54:56 +00:00
new winston . transports . Console ( { format : winston . format . colorize ( { all : true } ) , stderrLevels : [ "error" , "warn" ] } ) ,
2022-08-04 01:54:07 +00:00
new winston . transports . DailyRotateFile ( { filename : "logs/error-%DATE%.log" , level : "error" , zippedArchive : true , maxSize : 4194304 , maxFiles : 8 } ) ,
new winston . transports . DailyRotateFile ( { filename : "logs/main-%DATE%.log" , zippedArchive : true , maxSize : 4194304 , maxFiles : 8 } )
2021-07-05 13:14:52 +00:00
] ,
2022-03-10 20:24:03 +00:00
level : process . env . DEBUG _LOG ? "debug" : "main" ,
2021-07-05 13:14:52 +00:00
format : winston . format . combine (
winston . format . timestamp ( { format : "YYYY-MM-DD HH:mm:ss" } ) ,
winston . format . printf ( ( info ) => {
const {
timestamp , level , message , ... args
} = info ;
2021-08-14 21:15:21 +00:00
2021-07-05 13:14:52 +00:00
return ` [ ${ timestamp } ]: [ ${ level . toUpperCase ( ) } ] - ${ message } ${ Object . keys ( args ) . length ? JSON . stringify ( args , null , 2 ) : "" } ` ;
} ) ,
)
} ) ;
2021-08-14 21:15:21 +00:00
2021-07-05 13:14:52 +00:00
winston . addColors ( {
info : "green" ,
main : "gray" ,
2022-03-10 20:24:03 +00:00
debug : "magenta" ,
2021-07-05 13:14:52 +00:00
warn : "yellow" ,
error : "red"
} ) ;
2021-07-06 00:20:21 +00:00
2022-02-22 15:20:52 +00:00
database . upgrade ( logger ) . then ( result => {
if ( result === 1 ) return process . exit ( 1 ) ;
} ) ;
2022-02-22 00:55:25 +00:00
2021-07-05 13:14:52 +00:00
Admiral . on ( "log" , ( m ) => logger . main ( m ) ) ;
2021-07-06 00:20:21 +00:00
Admiral . on ( "info" , ( m ) => logger . info ( m ) ) ;
2021-07-05 13:14:52 +00:00
Admiral . on ( "debug" , ( m ) => logger . debug ( m ) ) ;
Admiral . on ( "warn" , ( m ) => logger . warn ( m ) ) ;
Admiral . on ( "error" , ( m ) => logger . error ( m ) ) ;
2021-07-05 04:15:27 +00:00
2021-04-27 02:53:27 +00:00
if ( dbl ) {
2021-07-05 04:15:27 +00:00
Admiral . on ( "stats" , async ( m ) => {
await dbl . postStats ( {
serverCount : m . guilds ,
shardCount : m . shardCount
} ) ;
2021-04-27 02:53:27 +00:00
} ) ;
2021-04-21 18:35:06 +00:00
}
2022-03-10 21:24:24 +00:00
2022-06-11 19:30:04 +00:00
// process the threshold into bytes early
if ( process . env . TEMPDIR && process . env . THRESHOLD ) {
2022-03-10 21:24:24 +00:00
const matched = process . env . THRESHOLD . match ( /(\d+)([KMGT])/ ) ;
const sizes = {
2022-06-11 19:30:04 +00:00
K : 1024 ,
M : 1048576 ,
G : 1073741824 ,
T : 1099511627776
2022-03-10 21:24:24 +00:00
} ;
2022-06-11 19:30:04 +00:00
if ( matched && matched [ 1 ] && matched [ 2 ] ) {
process . env . THRESHOLD = matched [ 1 ] * sizes [ matched [ 2 ] ] ;
2022-03-10 21:24:24 +00:00
} else {
logger . error ( "Invalid THRESHOLD config." ) ;
process . env . THRESHOLD = undefined ;
}
2022-07-17 17:46:52 +00:00
const dirstat = ( await promises . readdir ( process . env . TEMPDIR ) ) . map ( ( file ) => {
return promises . stat ( ` ${ process . env . TEMPDIR } / ${ file } ` ) . then ( ( stats ) => stats . size ) ;
2022-06-11 19:30:04 +00:00
} ) ;
const size = await Promise . all ( dirstat ) ;
2022-07-20 04:27:43 +00:00
const reduced = size . reduce ( ( a , b ) => {
2022-06-11 19:30:04 +00:00
return a + b ;
} , 0 ) ;
2022-07-20 04:27:43 +00:00
Admiral . centralStore . set ( "dirSizeCache" , reduced ) ;
2022-03-10 21:24:24 +00:00
}
2021-12-13 23:09:05 +00:00
}