server/src/managers/dateManager.ts

68 lines
2.0 KiB
TypeScript

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<void> {
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<void> {
try {
const dateString = await readJsonValue<string>(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<void> {
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()