68 lines
2.0 KiB
TypeScript
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() |