1
0
forked from noxious/server

#174: Refactor character manager into zoneManager for better DX, major refactor of time and weather system (data is stored in DB now instead of JSON file), npm update, npm format, many other improvements

This commit is contained in:
2024-11-13 13:21:01 +01:00
parent 628b3bf1fa
commit d4e0cbe398
43 changed files with 465 additions and 461 deletions

View File

@ -1,7 +1,7 @@
import { Server } from 'socket.io'
import { appLogger } from '../utilities/logger'
import { getRootPath } from '../utilities/storage'
import { readJsonValue, setJsonValue } from '../utilities/json'
import prisma from '../utilities/prisma'
import worldService from '../services/worldService'
interface WeatherState {
isRainEnabled: boolean
@ -37,46 +37,48 @@ class WeatherManager {
? Math.floor(Math.random() * 50) + 50 // 50-100%
: 0
// Save weather
await this.saveWeather()
// Emit weather
this.emitWeather()
}
public async toggleFog(): Promise<void> {
this.weatherState.isFogEnabled = !this.weatherState.isFogEnabled
this.weatherState.fogDensity = this.weatherState.isFogEnabled
? Math.random() * 0.7 + 0.3 // 0.3-1.0
? Math.floor((Math.random() * 0.7 + 0.3) * 100) // Convert 0.3-1.0 to 30-100
: 0
// Save weather
await this.saveWeather()
// Emit weather
this.emitWeather()
}
private async loadWeather(): Promise<void> {
try {
this.weatherState.isRainEnabled = await readJsonValue<boolean>(this.getWorldFilePath(), 'isRainEnabled')
this.weatherState.rainPercentage = await readJsonValue<number>(this.getWorldFilePath(), 'rainPercentage')
this.weatherState.isFogEnabled = await readJsonValue<boolean>(this.getWorldFilePath(), 'isFogEnabled')
this.weatherState.fogDensity = await readJsonValue<number>(this.getWorldFilePath(), 'fogDensity')
const world = await prisma.world.findFirst({
orderBy: { date: 'desc' }
})
if (world) {
this.weatherState = {
isRainEnabled: world.isRainEnabled,
rainPercentage: world.rainPercentage,
isFogEnabled: world.isFogEnabled,
fogDensity: world.fogDensity
}
}
} catch (error) {
appLogger.error(`Failed to load weather: ${error instanceof Error ? error.message : String(error)}`)
}
}
public async getWeatherState(): Promise<WeatherState> {
public getWeatherState(): WeatherState {
return this.weatherState
}
private startWeatherLoop(): void {
this.intervalId = setInterval(() => {
this.intervalId = setInterval(async () => {
this.updateWeather()
this.emitWeather()
this.saveWeather().catch((error) => {
await this.saveWeather().catch((error) => {
appLogger.error(`Failed to save weather: ${error instanceof Error ? error.message : String(error)}`)
})
}, WeatherManager.UPDATE_INTERVAL)
@ -95,7 +97,7 @@ class WeatherManager {
if (Math.random() < WeatherManager.FOG_CHANCE) {
this.weatherState.isFogEnabled = !this.weatherState.isFogEnabled
this.weatherState.fogDensity = this.weatherState.isFogEnabled
? Math.random() * 0.7 + 0.3 // 0.3-1.0
? Math.floor((Math.random() * 0.7 + 0.3) * 100) // Convert 0.3-1.0 to 30-100
: 0
}
}
@ -106,20 +108,21 @@ class WeatherManager {
private async saveWeather(): Promise<void> {
try {
const promises = [
await setJsonValue(this.getWorldFilePath(), 'isRainEnabled', this.weatherState.isRainEnabled),
await setJsonValue(this.getWorldFilePath(), 'rainPercentage', this.weatherState.rainPercentage),
await setJsonValue(this.getWorldFilePath(), 'isFogEnabled', this.weatherState.isFogEnabled),
await setJsonValue(this.getWorldFilePath(), 'fogDensity', this.weatherState.fogDensity)
]
await Promise.all(promises)
await worldService.update({
isRainEnabled: this.weatherState.isRainEnabled,
rainPercentage: this.weatherState.rainPercentage,
isFogEnabled: this.weatherState.isFogEnabled,
fogDensity: this.weatherState.fogDensity
})
} catch (error) {
appLogger.error(`Failed to save weather: ${error instanceof Error ? error.message : String(error)}`)
}
}
private getWorldFilePath(): string {
return getRootPath('data', 'world.json')
public cleanup(): void {
if (this.intervalId) {
clearInterval(this.intervalId)
}
}
}