Improved readability of weather and date managers

This commit is contained in:
2025-01-01 22:09:44 +01:00
parent 0464538b1c
commit 2d6831b4ef
3 changed files with 113 additions and 101 deletions

View File

@ -1,75 +1,83 @@
import { Server } from 'socket.io'
import Logger, { LoggerType } from '#application/logger'
import worldRepository from '#repositories/worldRepository'
import worldService from '#services/worldService'
import SocketManager from '#managers/socketManager'
class DateManager {
private static readonly GAME_SPEED = 8 // 24 game hours / 3 real hours
private static readonly UPDATE_INTERVAL = 1000 // 1 second
private static readonly CONFIG = {
GAME_SPEED: 8, // 24 game hours / 3 real hours
UPDATE_INTERVAL: 1000, // 1 second
} as const
private io: Server | null = null
private intervalId: NodeJS.Timeout | null = null
private currentDate: Date = new Date()
private logger = Logger.type(LoggerType.APP)
private currentDate = new Date()
private readonly logger = Logger.type(LoggerType.APP)
public async boot(io: Server): Promise<void> {
this.io = io
public async boot(): Promise<void> {
this.io = SocketManager.getIO()
await this.loadDate()
this.startDateLoop()
this.logger.info('Date manager loaded')
}
public async setTime(time: string): Promise<void> {
try {
let newDate: Date
public getCurrentDate(): Date {
return this.currentDate
}
// Check if it's just a time (HH:mm or HH:mm:ss format)
if (/^\d{1,2}:\d{2}(:\d{2})?$/.test(time)) {
const [hours, minutes] = time.split(':').map(Number)
newDate = new Date(this.currentDate) // Clone current date
newDate.setHours(hours, minutes)
} else {
// Treat as full datetime string
newDate = new Date(time)
if (isNaN(newDate.getTime())) return
}
public async setTime(timeString: string): Promise<void> {
try {
const newDate = this.parseTimeString(timeString)
if (!newDate) return
this.currentDate = newDate
this.emitDate()
await this.saveDate()
} catch (error) {
this.logger.error(`Failed to set time: ${error instanceof Error ? error.message : String(error)}`)
this.handleError('Failed to set time', error)
throw error
}
}
public cleanup(): void {
this.intervalId && clearInterval(this.intervalId)
}
private async loadDate(): Promise<void> {
try {
const world = await worldRepository.getFirst()
if (world) {
this.currentDate = world.date
}
this.currentDate = world?.date ?? new Date()
} catch (error) {
this.logger.error(`Failed to load date: ${error instanceof Error ? error.message : String(error)}`)
this.currentDate = new Date() // Use current date as fallback
this.handleError('Failed to load date', error)
this.currentDate = new Date()
}
}
private parseTimeString(timeString: string): Date | null {
const timeOnlyPattern = /^\d{1,2}:\d{2}(:\d{2})?$/
if (timeOnlyPattern.test(timeString)) {
const [hours, minutes] = timeString.split(':').map(Number)
const newDate = new Date(this.currentDate)
newDate.setHours(hours, minutes)
return newDate
}
const fullDate = new Date(timeString)
return isNaN(fullDate.getTime()) ? null : fullDate
}
private startDateLoop(): void {
this.intervalId = setInterval(() => {
this.advanceGameTime()
this.emitDate()
void this.saveDate()
}, DateManager.UPDATE_INTERVAL)
}, DateManager.CONFIG.UPDATE_INTERVAL)
}
private advanceGameTime(): void {
if (!this.currentDate) {
this.currentDate = new Date()
}
const advanceMilliseconds = DateManager.GAME_SPEED * DateManager.UPDATE_INTERVAL
const advanceMilliseconds = DateManager.CONFIG.GAME_SPEED * DateManager.CONFIG.UPDATE_INTERVAL
this.currentDate = new Date(this.currentDate.getTime() + advanceMilliseconds)
}
@ -79,23 +87,15 @@ class DateManager {
private async saveDate(): Promise<void> {
try {
await worldService.update({
date: this.currentDate
})
await worldService.update({ date: this.currentDate })
} catch (error) {
this.logger.error(`Failed to save date: ${error instanceof Error ? error.message : String(error)}`)
this.handleError('Failed to save date', error)
}
}
public cleanup(): void {
if (this.intervalId) {
clearInterval(this.intervalId)
}
}
public getCurrentDate(): Date {
return this.currentDate
private handleError(message: string, error: unknown): void {
this.logger.error(`${message}: ${error instanceof Error ? error.message : String(error)}`)
}
}
export default new DateManager()
export default new DateManager()