#140 : Individual log files

This commit is contained in:
Dennis Postma 2024-09-21 15:39:50 +02:00
parent 90ac7728d9
commit 798bfac643
24 changed files with 136 additions and 135 deletions

20
package-lock.json generated
View File

@ -1141,9 +1141,9 @@
}
},
"node_modules/engine.io": {
"version": "6.5.5",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz",
"integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==",
"version": "6.6.1",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.1.tgz",
"integrity": "sha512-NEpDCw9hrvBW+hVEOK4T7v0jFJ++KgtPl4jKFwsZVfG1XhS0dCrSb3VMb9gPAd7VAdW52VT1EnaNiU2vM8C0og==",
"license": "MIT",
"dependencies": {
"@types/cookie": "^0.4.1",
@ -1789,9 +1789,9 @@
}
},
"node_modules/nodemon": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.6.tgz",
"integrity": "sha512-C8ymJbXpTTinxjWuMfMxw0rZhTn/r7ypSGldQyqPEgDEaVwAthqC0aodsMwontnAInN9TuPwRLeBoyhmfv+iSA==",
"version": "3.1.7",
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.7.tgz",
"integrity": "sha512-hLj7fuMow6f0lbB0cD14Lz2xNjwsyruH251Pk4t/yIitCFJbmY1myuLlHm/q06aST4jg6EgAh74PIBBrRqpVAQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -2317,16 +2317,16 @@
}
},
"node_modules/socket.io": {
"version": "4.7.5",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz",
"integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==",
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz",
"integrity": "sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA==",
"license": "MIT",
"dependencies": {
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"cors": "~2.8.5",
"debug": "~4.3.2",
"engine.io": "~6.5.2",
"engine.io": "~6.6.0",
"socket.io-adapter": "~2.5.2",
"socket.io-parser": "~4.2.4"
},

View File

@ -4,7 +4,7 @@ import { Character } from '@prisma/client'
import CharacterRepository from '../../repositories/characterRepository'
import { ZCharacterCreate } from '../../utilities/zodTypes'
import prisma from '../../utilities/prisma'
import logger from '../../utilities/logger'
import { gameLogger } from '../../utilities/logger'
export default function (socket: TSocket, io: Server) {
socket.on('character:create', async (data: any) => {
@ -41,10 +41,10 @@ export default function (socket: TSocket, io: Server) {
socket.emit('character:create:success')
socket.emit('character:list', characters)
logger.info('character:create success')
gameLogger.info('character:create success')
} catch (error: any) {
console.log(error)
logger.error(`character:create error: ${error.message}`)
gameLogger.error(`character:create error: ${error.message}`)
return socket.emit('notification', { message: 'Could not create character. Please try again (later).' })
}
})

View File

@ -1,11 +1,9 @@
import { Server } from 'socket.io'
import { ExtendedCharacter, TSocket } from '../../../utilities/types'
import { TSocket } from '../../../utilities/types'
import { getArgs, isCommand } from '../../../utilities/chat'
import CharacterRepository from '../../../repositories/characterRepository'
import ZoneRepository from '../../../repositories/zoneRepository'
import CharacterManager from '../../../managers/characterManager'
import logger from '../../../utilities/logger'
import prisma from '../../../utilities/prisma'
import { gameMasterLogger } from '../../../utilities/logger'
type TypePayload = {
message: string
@ -76,11 +74,11 @@ export default class TeleportCommandEvent {
})
this.socket.emit('notification', { title: 'Server message', message: `You have been teleported to ${zone.name}` })
logger.info('teleport', `Character ${character.id} teleported to zone ${zone.id}`)
gameMasterLogger.info('teleport', `Character ${character.id} teleported to zone ${zone.id}`)
callback(true)
} catch (error: any) {
logger.error(`Error in teleport command: ${error.message}`)
gameMasterLogger.error(`Error in teleport command: ${error.message}`)
this.socket.emit('notification', { title: 'Server message', message: 'An error occurred while teleporting' })
}
}

View File

@ -3,8 +3,7 @@ import { TSocket } from '../../utilities/types'
import CharacterRepository from '../../repositories/characterRepository'
import ZoneRepository from '../../repositories/zoneRepository'
import { isCommand } from '../../utilities/chat'
import logger from '../../utilities/logger'
import CharacterManager from '../../managers/characterManager'
import { gameLogger } from '../../utilities/logger'
type TypePayload = {
message: string
@ -29,14 +28,14 @@ export default class ChatMessageEvent {
const character = await CharacterRepository.getByUserAndId(this.socket.user?.id as number, this.socket.characterId as number)
if (!character) {
logger.error('chat:send_message error', 'Character not found')
gameLogger.error('chat:send_message error', 'Character not found')
callback(false)
return
}
const zone = await ZoneRepository.getById(character.zoneId)
if (!zone) {
logger.error('chat:send_message error', 'Zone not found')
gameLogger.error('chat:send_message error', 'Zone not found')
callback(false)
return
}
@ -48,7 +47,7 @@ export default class ChatMessageEvent {
message: data.message
})
} catch (error: any) {
logger.error('chat:send_message error', error.message)
gameLogger.error('chat:send_message error', error.message)
callback(false)
}
}

View File

@ -5,9 +5,8 @@ import path from 'path'
import fs from 'fs/promises'
import prisma from '../../../../utilities/prisma'
import sharp from 'sharp'
import logger from '../../../../utilities/logger'
import CharacterManager from '../../../../managers/characterManager'
import characterRepository from '../../../../repositories/characterRepository'
import { gameMasterLogger } from '../../../../utilities/logger'
interface IObjectData {
[key: string]: Buffer
@ -58,14 +57,14 @@ export default class ObjectUploadEvent {
const finalFilePath = path.join(public_folder, filename)
await writeFile(finalFilePath, objectData)
logger.info('gm:object:upload', `Object ${key} uploaded with id ${uuid}`)
gameMasterLogger.info('gm:object:upload', `Object ${key} uploaded with id ${uuid}`)
})
await Promise.all(uploadPromises)
callback(true)
} catch (error: any) {
logger.error('gm:object:upload error', error.message)
gameMasterLogger.error('gm:object:upload error', error.message)
callback(false)
}
}

View File

@ -3,8 +3,8 @@ import { TSocket } from '../../../../utilities/types'
import fs from 'fs'
import path from 'path'
import prisma from '../../../../utilities/prisma'
import logger from '../../../../utilities/logger'
import CharacterManager from '../../../../managers/characterManager'
import { gameMasterLogger } from '../../../../utilities/logger'
type Payload = {
id: string
@ -34,10 +34,10 @@ export default class GMSpriteDeleteEvent {
await this.deleteSpriteFolder(data.id)
await this.deleteSpriteFromDatabase(data.id)
logger.info(`Sprite ${data.id} deleted.`)
gameMasterLogger.info(`Sprite ${data.id} deleted.`)
callback(true)
} catch (error: any) {
logger.error('gm:sprite:delete error', error.message)
gameMasterLogger.error('gm:sprite:delete error', error.message)
callback(false)
}
}

View File

@ -3,9 +3,8 @@ import fs from 'fs/promises'
import { Server } from 'socket.io'
import { TSocket } from '../../../../utilities/types'
import prisma from '../../../../utilities/prisma'
import logger from '../../../../utilities/logger'
import CharacterManager from '../../../../managers/characterManager'
import characterRepository from '../../../../repositories/characterRepository'
import { gameMasterLogger } from '../../../../utilities/logger'
type Payload = {
id: string
@ -34,14 +33,14 @@ export default class GMTileDeleteEvent {
}
try {
logger.info(`Deleting tile ${data.id}`)
gameMasterLogger.info(`Deleting tile ${data.id}`)
await this.deleteTileFromDatabase(data.id)
await this.deleteTileFile(data.id)
logger.info(`Tile ${data.id} deleted successfully.`)
gameMasterLogger.info(`Tile ${data.id} deleted successfully.`)
callback(true)
} catch (error: any) {
logger.error('gm:tile:delete error', error.message)
gameMasterLogger.error('gm:tile:delete error', error.message)
callback(false)
}
}
@ -62,7 +61,7 @@ export default class GMTileDeleteEvent {
if (error.code !== 'ENOENT') {
throw error
}
logger.warn(`File ${finalFilePath} does not exist.`)
gameMasterLogger.warn(`File ${finalFilePath} does not exist.`)
}
}
}

View File

@ -4,9 +4,8 @@ import { writeFile } from 'node:fs/promises'
import path from 'path'
import fs from 'fs/promises'
import prisma from '../../../../utilities/prisma'
import CharacterManager from '../../../../managers/characterManager'
import characterRepository from '../../../../repositories/characterRepository'
import logger from '../../../../utilities/logger'
import { gameMasterLogger } from '../../../../utilities/logger'
interface ITileData {
[key: string]: Buffer
@ -48,7 +47,7 @@ export default function (socket: TSocket, io: Server) {
callback(true)
} catch (error) {
console.error('Error uploading tile:', error)
gameMasterLogger.error('Error uploading tile:', error)
callback(false)
}
})

View File

@ -3,9 +3,8 @@ import { TSocket } from '../../../utilities/types'
import ZoneRepository from '../../../repositories/zoneRepository'
import { Zone } from '@prisma/client'
import prisma from '../../../utilities/prisma'
import CharacterManager from '../../../managers/characterManager'
import characterRepository from '../../../repositories/characterRepository'
import logger from '../../../utilities/logger'
import { gameMasterLogger } from '../../../utilities/logger'
type Payload = {
name: string
@ -24,11 +23,11 @@ export default function (socket: TSocket, io: Server) {
if (!character) return
if (character.role !== 'gm') {
logger.info(`User ${character.id} tried to create zone but is not a game master.`)
gameMasterLogger.info(`User ${character.id} tried to create zone but is not a game master.`)
return
}
logger.info(`User ${character.id} has created a new zone via zone editor.`)
gameMasterLogger.info(`User ${character.id} has created a new zone via zone editor.`)
let zoneList: Zone[] = []
try {

View File

@ -2,9 +2,8 @@ import { Server } from 'socket.io'
import { TSocket } from '../../../utilities/types'
import ZoneRepository from '../../../repositories/zoneRepository'
import prisma from '../../../utilities/prisma'
import CharacterManager from '../../../managers/characterManager'
import characterRepository from '../../../repositories/characterRepository'
import logger from '../../../utilities/logger'
import { gameMasterLogger } from '../../../utilities/logger'
type Payload = {
zoneId: number
@ -21,11 +20,11 @@ export default function (socket: TSocket, io: Server) {
if (!character) return
if (character.role !== 'gm') {
logger.info(`User ${character.id} tried to delete zone but is not a game master.`)
gameMasterLogger.info(`User ${character.id} tried to delete zone but is not a game master.`)
return
}
logger.info(`User ${character.id} has deleted a zone via zone editor.`)
gameMasterLogger.info(`User ${character.id} has deleted a zone via zone editor.`)
try {
const zone = await ZoneRepository.getById(data.zoneId)

View File

@ -2,9 +2,8 @@ import { Server } from 'socket.io'
import { TSocket } from '../../../utilities/types'
import { Zone } from '@prisma/client'
import ZoneRepository from '../../../repositories/zoneRepository'
import CharacterManager from '../../../managers/characterManager'
import characterRepository from '../../../repositories/characterRepository'
import logger from '../../../utilities/logger'
import { gameMasterLogger } from '../../../utilities/logger'
interface IPayload {}
@ -19,11 +18,11 @@ export default function (socket: TSocket, io: Server) {
if (!character) return
if (character.role !== 'gm') {
logger.info(`User ${character.id} tried to list zones but is not a game master.`)
gameMasterLogger.info(`User ${character.id} tried to list zones but is not a game master.`)
return
}
logger.info(`User ${character.id} has requested zone list via zone editor.`)
gameMasterLogger.info(`User ${character.id} has requested zone list via zone editor.`)
try {
const zones = await ZoneRepository.getAll()

View File

@ -1,10 +1,9 @@
import { Server } from 'socket.io'
import { TSocket } from '../../../utilities/types'
import ZoneRepository from '../../../repositories/zoneRepository'
import { Character, Zone } from '@prisma/client'
import CharacterManager from '../../../managers/characterManager'
import { Zone } from '@prisma/client'
import characterRepository from '../../../repositories/characterRepository'
import logger from '../../../utilities/logger'
import { gameMasterLogger } from '../../../utilities/logger'
interface IPayload {
zoneId: number
@ -21,14 +20,14 @@ export default function (socket: TSocket, io: Server) {
if (!character) return
if (character.role !== 'gm') {
logger.info(`User ${character!.id} tried to request zone but is not a game master.`)
gameMasterLogger.info(`User ${character!.id} tried to request zone but is not a game master.`)
return
}
logger.info(`User ${character.id} has requested zone via zone editor.`)
gameMasterLogger.info(`User ${character.id} has requested zone via zone editor.`)
if (!data.zoneId) {
logger.info(`User ${character.id} tried to request zone but did not provide a zone id.`)
gameMasterLogger.info(`User ${character.id} tried to request zone but did not provide a zone id.`)
return
}
@ -36,7 +35,7 @@ export default function (socket: TSocket, io: Server) {
const zone = await ZoneRepository.getById(data.zoneId)
if (!zone) {
logger.info(`User ${character.id} tried to request zone ${data.zoneId} but it does not exist.`)
gameMasterLogger.info(`User ${character.id} tried to request zone ${data.zoneId} but it does not exist.`)
return
}

View File

@ -1,12 +1,11 @@
import { Server } from 'socket.io'
import { TSocket } from '../../../utilities/types'
import ZoneRepository from '../../../repositories/zoneRepository'
import { Zone, ZoneEventTile, ZoneEventTileType, ZoneObject } from '@prisma/client'
import { Zone, ZoneEventTileType, ZoneObject } from '@prisma/client'
import prisma from '../../../utilities/prisma'
import zoneManager from '../../../managers/zoneManager'
import logger from '../../../utilities/logger'
import CharacterManager from '../../../managers/characterManager'
import characterRepository from '../../../repositories/characterRepository'
import { gameMasterLogger } from '../../../utilities/logger'
interface IPayload {
zoneId: number
@ -39,14 +38,14 @@ export default function (socket: TSocket, io: Server) {
if (!character) return
if (character.role !== 'gm') {
logger.info(`User ${character.id} tried to update zone but is not a game master.`)
gameMasterLogger.info(`User ${character.id} tried to update zone but is not a game master.`)
return
}
logger.info(`User ${character.id} has updated zone via zone editor.`)
gameMasterLogger.info(`User ${character.id} has updated zone via zone editor.`)
if (!data.zoneId) {
logger.info(`User ${character.id} tried to update zone but did not provide a zone id.`)
gameMasterLogger.info(`User ${character.id} tried to update zone but did not provide a zone id.`)
return
}
@ -54,7 +53,7 @@ export default function (socket: TSocket, io: Server) {
let zone = await ZoneRepository.getById(data.zoneId)
if (!zone) {
logger.info(`User ${character.id} tried to update zone ${data.zoneId} but it does not exist.`)
gameMasterLogger.info(`User ${character.id} tried to update zone ${data.zoneId} but it does not exist.`)
return
}
@ -108,7 +107,7 @@ export default function (socket: TSocket, io: Server) {
zone = await ZoneRepository.getById(data.zoneId)
if (!zone) {
logger.info(`User ${character.id} tried to update zone ${data.zoneId} but it does not exist.`)
gameMasterLogger.info(`User ${character.id} tried to update zone ${data.zoneId} but it does not exist.`)
return
}
@ -117,7 +116,7 @@ export default function (socket: TSocket, io: Server) {
zoneManager.unloadZone(data.zoneId)
await zoneManager.loadZone(zone)
} catch (error: any) {
logger.error(`Error updating zone: ${error.message}`)
gameMasterLogger.error(`Error updating zone: ${error.message}`)
}
})
}

View File

@ -1,10 +1,9 @@
import { Server } from 'socket.io'
import { ExtendedCharacter, TSocket } from '../../utilities/types'
import { TSocket } from '../../utilities/types'
import ZoneRepository from '../../repositories/zoneRepository'
import ZoneManager from '../../managers/zoneManager'
import { Character, Zone } from '@prisma/client'
import logger from '../../utilities/logger'
import CharacterManager from '../../managers/characterManager'
import { gameLogger } from '../../utilities/logger'
interface IPayload {
zoneId: number
@ -58,7 +57,7 @@ export default function (socket: TSocket, io: Server) {
// send over zone and characters to socket
callback({ zone, characters: CharacterManager.getCharactersInZone(zone) })
} catch (error: any) {
logger.error(`Error requesting zone: ${error.message}`)
gameLogger.error(`Error requesting zone: ${error.message}`)
socket.disconnect()
}
})

View File

@ -2,7 +2,7 @@ import { Server } from 'socket.io'
import { TSocket } from '../../utilities/types'
import ZoneRepository from '../../repositories/zoneRepository'
import CharacterManager from '../../managers/characterManager'
import logger from '../../utilities/logger'
import { gameLogger } from '../../utilities/logger'
export default class ZoneLeaveEvent {
constructor(
@ -18,19 +18,19 @@ export default class ZoneLeaveEvent {
try {
const character = CharacterManager.getCharacterFromSocket(this.socket);
if (!character) {
logger.error('zone:character:leave error', 'Character not found')
gameLogger.error('zone:character:leave error', 'Character not found')
return
}
if (!character.zoneId) {
logger.error('zone:character:leave error', 'Character not in a zone')
gameLogger.error('zone:character:leave error', 'Character not in a zone')
return
}
const zone = await ZoneRepository.getById(character.zoneId)
if (!zone) {
logger.error('zone:character:leave error', 'Zone not found')
gameLogger.error('zone:character:leave error', 'Zone not found')
return
}
@ -42,9 +42,9 @@ export default class ZoneLeaveEvent {
// remove character from zone manager
await CharacterManager.removeCharacter(character)
logger.info('zone:character:leave', `Character ${character.id} left zone ${zone.id}`)
gameLogger.info('zone:character:leave', `Character ${character.id} left zone ${zone.id}`)
} catch (error: any) {
logger.error('zone:character:leave error', error.message)
gameLogger.error('zone:character:leave error', error.message)
}
}
}

View File

@ -5,10 +5,8 @@ import { ZoneEventTileService } from '../../services/zoneEventTileService'
import prisma from '../../utilities/prisma'
import { ZoneEventTile, ZoneEventTileTeleport } from '@prisma/client'
import Rotation from '../../utilities/character/rotation'
import logger from '../../utilities/logger'
import CharacterManager from '../../managers/characterManager'
import zoneManager from '../../managers/zoneManager'
import ZoneManager from '../../managers/zoneManager'
import { gameLogger } from '../../utilities/logger'
export type ZoneEventTileWithTeleport = ZoneEventTile & {
teleport: ZoneEventTileTeleport
@ -35,12 +33,12 @@ export default class CharacterMove {
private async handleCharacterMove({ positionX, positionY }: { positionX: number; positionY: number }): Promise<void> {
let character = CharacterManager.getCharacterFromSocket(this.socket)
if (!character) {
logger.error('character:move error', 'Character not found')
gameLogger.error('character:move error', 'Character not found')
return
}
if (!character) {
logger.error('character:move error', 'character has not been initialized?')
gameLogger.error('character:move error', 'character has not been initialized?')
return
}
@ -127,7 +125,7 @@ export default class CharacterMove {
private async handleZoneEventTile(zoneEventTile: ZoneEventTileWithTeleport): Promise<void> {
const character = CharacterManager.getCharacterFromSocket(this.socket)
if (!character) {
logger.error('character:move error', 'Character not found')
gameLogger.error('character:move error', 'Character not found')
return
}

View File

@ -1,5 +1,5 @@
import { User } from '@prisma/client'
import logger from '../utilities/logger'
import { appLogger } from '../utilities/logger'
type TLoggedInUsers = {
users: User[]
@ -10,7 +10,7 @@ class UserManager {
// Method to initialize user manager
public async boot() {
logger.info('User manager loaded')
appLogger.info('User manager loaded')
}
// Function that adds user to logged in users

View File

@ -1,11 +1,9 @@
import { Zone, ZoneEventTileTeleport, ZoneEventTileType } from '@prisma/client'
import { Zone } from '@prisma/client'
import ZoneRepository from '../repositories/zoneRepository'
import ZoneService from '../services/zoneService'
import logger from '../utilities/logger'
import LoadedZone from '../models/loadedZone'
import zoneRepository from '../repositories/zoneRepository'
import { beforeEach } from 'node:test'
import prisma from '../utilities/prisma'
import { gameMasterLogger } from '../utilities/logger'
class ZoneManager {
private loadedZones: LoadedZone[] = []
@ -23,7 +21,7 @@ class ZoneManager {
await this.loadZone(zone)
}
logger.info('Zone manager loaded')
gameMasterLogger.info('Zone manager loaded')
}
public async getZoneAssets(zone: Zone): Promise<ZoneAssets> {
@ -46,13 +44,13 @@ class ZoneManager {
const loadedZone = new LoadedZone(zone)
this.loadedZones.push(loadedZone)
await this.getZoneAssets(zone)
logger.info(`Zone ID ${zone.id} loaded`)
gameMasterLogger.info(`Zone ID ${zone.id} loaded`)
}
// Method to handle individual zoneEditor unloading
public unloadZone(zoneId: number) {
this.loadedZones = this.loadedZones.filter((loadedZone) => loadedZone.getZone().id !== zoneId)
logger.info(`Zone ID ${zoneId} unloaded`)
gameMasterLogger.info(`Zone ID ${zoneId} unloaded`)
}
// Getter for loaded zones

View File

@ -3,7 +3,7 @@ import { TSocket } from '../utilities/types'
import config from '../utilities/config'
import UserRepository from '../repositories/userRepository'
import { User } from '@prisma/client'
import logger from '../utilities/logger'
import { gameLogger } from '../utilities/logger'
/**
* Socket io jwt auth middleware
@ -12,7 +12,7 @@ import logger from '../utilities/logger'
*/
export async function Authentication(socket: TSocket, next: any) {
if (!socket.request.headers.cookie) {
logger.warn('No cookie provided')
gameLogger.warn('No cookie provided')
return next(new Error('Authentication error'))
}
@ -33,7 +33,7 @@ export async function Authentication(socket: TSocket, next: any) {
if (token) {
verify(token, config.JWT_SECRET, async (err: any, decoded: any) => {
if (err) {
logger.error('Invalid token')
gameLogger.error('Invalid token')
return next(new Error('Authentication error'))
}
@ -41,7 +41,7 @@ export async function Authentication(socket: TSocket, next: any) {
next()
})
} else {
logger.warn('No token provided')
gameLogger.warn('No token provided')
return next(new Error('Authentication error'))
}
}

View File

@ -1,14 +1,14 @@
import { Zone, ZoneEventTile, ZoneEventTileTeleport, ZoneEventTileType, ZoneObject } from '@prisma/client'
import { Zone, ZoneEventTile, ZoneEventTileType, ZoneObject } from '@prisma/client'
import prisma from '../utilities/prisma'
import logger from '../utilities/logger'
import { ZoneEventTileWithTeleport } from '../events/zone/characterMove'
import { appLogger } from '../utilities/logger'
class ZoneRepository {
async getFirst(): Promise<Zone | null> {
try {
return await prisma.zone.findFirst()
} catch (error: any) {
logger.error(`Failed to get first zone: ${error.message}`)
appLogger.error(`Failed to get first zone: ${error.message}`)
return null
}
}
@ -17,7 +17,7 @@ class ZoneRepository {
try {
return await prisma.zone.findMany()
} catch (error: any) {
logger.error(`Failed to get all zone: ${error.message}`)
appLogger.error(`Failed to get all zone: ${error.message}`)
return []
}
}
@ -43,7 +43,7 @@ class ZoneRepository {
}
})
} catch (error: any) {
logger.error(`Failed to get zone by id: ${error.message}`)
appLogger.error(`Failed to get zone by id: ${error.message}`)
return null
}
}
@ -56,7 +56,7 @@ class ZoneRepository {
}
})
} catch (error: any) {
logger.error(`Failed to get zone event tiles: ${error.message}`)
appLogger.error(`Failed to get zone event tiles: ${error.message}`)
return []
}
}
@ -71,7 +71,7 @@ class ZoneRepository {
include: { teleport: true }
})) as unknown as ZoneEventTileWithTeleport[]
} catch (error: any) {
logger.error(`Failed to get zone event tiles: ${error.message}`)
appLogger.error(`Failed to get zone event tiles: ${error.message}`)
return []
}
}
@ -84,7 +84,7 @@ class ZoneRepository {
}
})
} catch (error: any) {
logger.error(`Failed to get zone objects: ${error.message}`)
appLogger.error(`Failed to get zone objects: ${error.message}`)
return []
}
}

View File

@ -13,7 +13,7 @@ import UserManager from './managers/userManager'
import { Authentication } from './middleware/authentication'
// import CommandManager from './managers/CommandManager'
import { Dirent } from 'node:fs'
import logger from './utilities/logger'
import { appLogger, watchLogs } from './utilities/logger'
import CharacterManager from './managers/characterManager'
export class Server {
@ -39,31 +39,22 @@ export class Server {
*/
public async start() {
// Read log file and print to console for debugging
const logFile = path.join(__dirname, '../logs/app.log')
fs.watchFile(logFile, (curr, prev) => {
if (curr.size > prev.size) {
const stream = fs.createReadStream(logFile, { start: prev.size, end: curr.size })
stream.on('data', (chunk) => {
console.log(chunk.toString())
})
}
})
watchLogs()
// Check prisma connection
try {
await prisma.$connect()
logger.info('Database connected')
appLogger.info('Database connected')
} catch (error: any) {
logger.error(`Database connection failed: ${error.message}`)
appLogger.error(`Database connection failed: ${error.message}`)
}
// Start the server
try {
this.http.listen(config.PORT, config.HOST)
logger.info(`Socket.IO running on port ${config.PORT}`)
appLogger.info(`Socket.IO running on port ${config.PORT}`)
} catch (error: any) {
logger.error(`Socket.IO failed to start: ${error.message}`)
appLogger.error(`Socket.IO failed to start: ${error.message}`)
}
// Add http API routes
@ -95,7 +86,7 @@ export class Server {
try {
await this.loadEventHandlers(eventsPath, socket)
} catch (error: any) {
logger.error(`Failed to load event handlers: ${error.message}`)
appLogger.error(`Failed to load event handlers: ${error.message}`)
}
}
@ -121,10 +112,10 @@ export class Server {
module.default(socket, this.io)
}
} else {
logger.warn(`Unrecognized export in ${file.name}`)
appLogger.warn(`Unrecognized export in ${file.name}`)
}
} catch (error: any) {
logger.error(`Error loading event handler ${file.name}: ${error.message}`)
appLogger.error(`Error loading event handler ${file.name}: ${error.message}`)
}
}
}
@ -135,4 +126,4 @@ export class Server {
const server = new Server()
server.start()
console.log('Server started')
appLogger.info('Server started')

View File

@ -1,9 +1,8 @@
import { ExtendedCharacter } from '../../utilities/types'
import { AStar } from '../../utilities/character/aStar'
import ZoneManager from '../../managers/zoneManager'
import prisma from '../../utilities/prisma'
import Rotation from '../../utilities/character/rotation'
import logger from '../../utilities/logger'
import { gameLogger } from '../../utilities/logger'
export class CharacterMoveService {
public updatePosition(character: ExtendedCharacter, position: { x: number; y: number }, newZoneId?: number) {
@ -28,7 +27,7 @@ export class CharacterMoveService {
public async calculatePath(character: ExtendedCharacter, targetX: number, targetY: number): Promise<Array<{ x: number; y: number }> | null> {
const grid = await ZoneManager.getZoneById(character.zoneId)?.getGrid()
if (!grid?.length) {
logger.error('character:move error', 'Grid not found or empty')
gameLogger.error('character:move error', 'Grid not found or empty')
return null
}

View File

@ -9,9 +9,9 @@ import tileRepository from '../repositories/tileRepository'
import objectRepository from '../repositories/objectRepository'
import spriteRepository from '../repositories/spriteRepository'
import fs from 'fs'
import logger from './logger'
import zoneRepository from '../repositories/zoneRepository'
import zoneManager from '../managers/zoneManager'
import { httpLogger } from './logger'
async function addHttpRoutes(app: Application) {
/**
@ -118,13 +118,13 @@ async function addHttpRoutes(app: Application) {
}
if (!fs.existsSync(assetPath)) {
logger.error(`File not found: ${assetPath}`)
httpLogger.error(`File not found: ${assetPath}`)
return res.status(404).send('Asset not found')
}
res.sendFile(assetPath, (err) => {
if (err) {
logger.error('Error sending file:', err)
httpLogger.error('Error sending file:', err)
res.status(500).send('Error downloading the asset')
}
})
@ -179,7 +179,7 @@ async function addHttpRoutes(app: Application) {
return res.status(400).json({ message: 'Failed to register user' })
})
logger.info('Web routes added')
httpLogger.info('Web routes added')
}
export { addHttpRoutes }

View File

@ -1,11 +1,17 @@
import pino from 'pino'
import fs from 'fs'
import path from 'path'
const logger = pino({
// Array of log types
const LOG_TYPES = ['http', 'game', 'gameMaster', 'app'] as const
type LogType = typeof LOG_TYPES[number]
const createLogger = (name: LogType) => pino({
level: process.env.LOG_LEVEL || 'debug',
transport: {
target: 'pino/file',
options: {
destination: './logs/app.log',
destination: `./logs/${name}.log`,
mkdir: true
}
},
@ -15,7 +21,28 @@ const logger = pino({
}
},
timestamp: pino.stdTimeFunctions.isoTime,
base: null // This will prevent hostname and pid from being included
base: null
})
export default logger
// Create logger instances
const loggers = Object.fromEntries(
LOG_TYPES.map(type => [type, createLogger(type)])
) as Record<LogType, ReturnType<typeof createLogger>>
const watchLogs = () => {
LOG_TYPES.forEach(type => {
const logFile = path.join(__dirname, '../../logs', `${type}.log`)
fs.watchFile(logFile, (curr, prev) => {
if (curr.size > prev.size) {
const stream = fs.createReadStream(logFile, { start: prev.size, end: curr.size })
stream.on('data', (chunk) => {
console.log(`[${type}] \n ${chunk.toString()}`)
})
}
})
})
}
export const { http: httpLogger, game: gameLogger, gameMaster: gameMasterLogger, app: appLogger } = loggers
export { watchLogs }