import { Server } from 'socket.io' import { appLogger } from '../utilities/logger' import { getRootPath } from '../utilities/storage' import { readJsonValue, setJsonValue } from '../utilities/json' class DateManager { private static readonly GAME_SPEED = 8 // 24 game hours / 3 real hours private static readonly UPDATE_INTERVAL = 1000 // 1 second private io: Server | null = null private intervalId: NodeJS.Timeout | null = null private currentDate: Date = new Date() public async boot(io: Server): Promise { this.io = io await this.loadDate() this.startDateLoop() appLogger.info('Date manager loaded') } public stop(): void { if (this.intervalId) { clearInterval(this.intervalId) this.intervalId = null } } private async loadDate(): Promise { try { const dateString = await readJsonValue(this.getWorldFilePath(), 'date') this.currentDate = new Date(dateString) } catch (error) { appLogger.error(`Failed to load date: ${error instanceof Error ? error.message : String(error)}`) this.currentDate = new Date() // Use current date as fallback } } private startDateLoop(): void { this.intervalId = setInterval(() => { this.advanceGameTime() this.emitDate() this.saveDate() }, DateManager.UPDATE_INTERVAL) } private advanceGameTime(): void { const advanceMilliseconds = DateManager.GAME_SPEED * DateManager.UPDATE_INTERVAL this.currentDate = new Date(this.currentDate.getTime() + advanceMilliseconds) } private emitDate(): void { this.io?.emit('date', this.currentDate) } private async saveDate(): Promise { try { await setJsonValue(this.getWorldFilePath(), 'date', this.currentDate) } catch (error) { appLogger.error(`Failed to save date: ${error instanceof Error ? error.message : String(error)}`) } } private getWorldFilePath(): string { return getRootPath('data', 'world.json') } } export default new DateManager()