2025-04-05 06:50:57 -07:00
import fs from "fs" ;
import fsPromises from "fs/promises" ;
import { logger } from "../utils/logger" ;
import { config , configPath , loadConfig } from "./configService" ;
2025-06-20 14:00:55 -07:00
import { getWebPorts , sendWsBroadcast , startWebServer , stopWebServer } from "./webService" ;
2025-06-25 08:04:03 -07:00
import { Inbox } from "../models/inboxModel" ;
2025-04-05 06:50:57 -07:00
let amnesia = false ;
2025-06-22 19:58:48 -07:00
fs . watchFile ( configPath , ( now , then ) = > {
// https://github.com/oven-sh/bun/issues/20542
if ( process . versions . bun && now . mtimeMs == then . mtimeMs ) {
return ;
}
2025-04-05 06:50:57 -07:00
if ( amnesia ) {
amnesia = false ;
} else {
2025-06-18 11:34:12 -07:00
logger . info ( "Detected a change to config file, reloading its contents." ) ;
2025-04-05 06:50:57 -07:00
try {
loadConfig ( ) ;
} catch ( e ) {
2025-06-15 18:51:32 -07:00
logger . error ( "FATAL ERROR: Config failed to be reloaded: " + ( e as Error ) . message ) ;
2025-04-05 06:50:57 -07:00
process . exit ( 1 ) ;
}
validateConfig ( ) ;
2025-06-25 08:04:03 -07:00
syncConfigWithDatabase ( ) ;
2025-05-24 01:48:25 -07:00
const webPorts = getWebPorts ( ) ;
if ( config . httpPort != webPorts . http || config . httpsPort != webPorts . https ) {
logger . info ( ` Restarting web server to apply port changes. ` ) ;
2025-06-20 14:00:55 -07:00
// Tell webui clients to reload with new port
sendWsBroadcast ( { ports : { http : config.httpPort , https : config.httpsPort } } ) ;
2025-05-24 01:48:25 -07:00
void stopWebServer ( ) . then ( startWebServer ) ;
2025-06-20 14:00:55 -07:00
} else {
sendWsBroadcast ( { config_reloaded : true } ) ;
2025-05-24 01:48:25 -07:00
}
2025-04-05 06:50:57 -07:00
}
} ) ;
export const validateConfig = ( ) : void = > {
2025-06-07 02:15:35 -07:00
let modified = false ;
if ( config . administratorNames ) {
if ( ! Array . isArray ( config . administratorNames ) ) {
config . administratorNames = [ config . administratorNames ] ;
modified = true ;
}
for ( let i = 0 ; i != config . administratorNames . length ; ++ i ) {
if ( typeof config . administratorNames [ i ] != "string" ) {
config . administratorNames [ i ] = String ( config . administratorNames [ i ] ) ;
modified = true ;
}
}
}
2025-06-25 08:04:03 -07:00
if (
config . worldState ? . galleonOfGhouls &&
config . worldState . galleonOfGhouls != 1 &&
config . worldState . galleonOfGhouls != 2 &&
config . worldState . galleonOfGhouls != 3
) {
config . worldState . galleonOfGhouls = 0 ;
modified = true ;
}
2025-06-07 02:15:35 -07:00
if ( modified ) {
2025-06-18 11:34:12 -07:00
logger . info ( ` Updating config file to fix some issues with it. ` ) ;
2025-04-05 06:50:57 -07:00
void saveConfig ( ) ;
}
} ;
export const saveConfig = async ( ) : Promise < void > = > {
amnesia = true ;
await fsPromises . writeFile ( configPath , JSON . stringify ( config , null , 2 ) ) ;
} ;
2025-06-25 08:04:03 -07:00
export const syncConfigWithDatabase = ( ) : void = > {
// Event messages are deleted after endDate. Since we don't use beginDate/endDate and instead have config toggles, we need to delete the messages once those bools are false.
if ( ! config . worldState ? . galleonOfGhouls ) {
void Inbox . deleteMany ( { goalTag : "GalleonRobbery" } ) . then ( ( ) = > { } ) ; // For some reason, I can't just do `Inbox.deleteMany(...)`; it needs this whole circus.
}
} ;