Continuation of refactor
This commit is contained in:
parent
6dda79f8b2
commit
e1a6f650fb
@ -1,5 +1,8 @@
|
||||
import { Server } from 'socket.io'
|
||||
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
|
||||
export abstract class BaseCommand {
|
||||
protected readonly logger = Logger.type(LoggerType.COMMAND)
|
||||
constructor(readonly io: Server) {}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
import { Logger } from '#application/logger'
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
|
||||
export abstract class BaseController {
|
||||
protected readonly logger: Logger = new Logger('http')
|
||||
protected readonly logger = Logger.type(LoggerType.HTTP)
|
||||
|
||||
protected sendSuccess(res: Response, data?: any, message?: string, status: number = 200) {
|
||||
return res.status(status).json({
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { EntityManager } from '@mikro-orm/core'
|
||||
|
||||
import Database from '#application/database'
|
||||
import { Logger } from '#application/logger'
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
|
||||
export abstract class BaseEntity {
|
||||
protected readonly logger: Logger = new Logger('entity')
|
||||
protected readonly logger = Logger.type(LoggerType.ENTITY)
|
||||
|
||||
private getEntityManager(): EntityManager {
|
||||
return Database.getEntityManager()
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Server } from 'socket.io'
|
||||
|
||||
import { Logger } from '#application/logger'
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
import { TSocket } from '#application/types'
|
||||
|
||||
export abstract class BaseEvent {
|
||||
protected readonly logger: Logger = new Logger('game')
|
||||
protected readonly logger = Logger.type(LoggerType.GAME)
|
||||
|
||||
constructor(
|
||||
readonly io: Server,
|
||||
|
@ -2,10 +2,10 @@ import { EntityManager } from '@mikro-orm/core'
|
||||
|
||||
import Database from '../database'
|
||||
|
||||
import { Logger } from '#application/logger'
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
|
||||
export abstract class BaseRepository {
|
||||
protected readonly logger: Logger = new Logger('repository')
|
||||
protected readonly logger = Logger.type(LoggerType.REPOSITORY)
|
||||
|
||||
protected get em(): EntityManager {
|
||||
return Database.getEntityManager()
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Logger } from '#application/logger'
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
|
||||
export abstract class BaseService {
|
||||
protected readonly logger: Logger = new Logger('game')
|
||||
protected readonly logger = Logger.type(LoggerType.GAME)
|
||||
}
|
||||
|
@ -1,20 +1,21 @@
|
||||
import { EntityManager } from '@mikro-orm/core'
|
||||
import { MikroORM } from '@mikro-orm/mysql'
|
||||
|
||||
import { appLogger } from './logger'
|
||||
import Logger, { LoggerType } from './logger'
|
||||
import config from '../../mikro-orm.config'
|
||||
|
||||
class Database {
|
||||
private static orm: MikroORM
|
||||
private static em: EntityManager
|
||||
private static logger = Logger.type(LoggerType.APP)
|
||||
|
||||
public static async initialize(): Promise<void> {
|
||||
try {
|
||||
Database.orm = await MikroORM.init(config)
|
||||
Database.em = Database.orm.em.fork()
|
||||
appLogger.info('Database connection initialized')
|
||||
this.logger.info('Database connection initialized')
|
||||
} catch (error) {
|
||||
appLogger.error(`MikroORM connection failed: ${error}`)
|
||||
this.logger.error(`MikroORM connection failed: ${error}`)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
@ -1,73 +1,51 @@
|
||||
import pino from 'pino'
|
||||
|
||||
import { getRootPath } from './storage'
|
||||
export enum LoggerType {
|
||||
HTTP = 'http',
|
||||
GAME = 'game',
|
||||
GAME_MASTER = 'gameMaster',
|
||||
APP = 'app',
|
||||
QUEUE = 'queue',
|
||||
COMMAND = 'command',
|
||||
REPOSITORY = 'repository',
|
||||
ENTITY = 'entity'
|
||||
}
|
||||
|
||||
export class Logger {
|
||||
private static readonly LOG_TYPES = ['http', 'game', 'gameMaster', 'app', 'queue', 'command', 'repository', 'entity'] as const
|
||||
private readonly logger: ReturnType<typeof pino>
|
||||
class Logger {
|
||||
private instances: Map<LoggerType, ReturnType<typeof pino>> = new Map()
|
||||
|
||||
constructor(type: (typeof Logger.LOG_TYPES)[number]) {
|
||||
this.logger = pino({
|
||||
level: process.env.LOG_LEVEL || 'debug',
|
||||
transport: {
|
||||
target: 'pino/file',
|
||||
options: {
|
||||
destination: `./logs/${type}.log`,
|
||||
mkdir: true
|
||||
}
|
||||
},
|
||||
formatters: {
|
||||
level: (label) => ({ level: label.toUpperCase() })
|
||||
},
|
||||
timestamp: pino.stdTimeFunctions.isoTime,
|
||||
base: null
|
||||
})
|
||||
}
|
||||
|
||||
info(message: string) {
|
||||
this.logger.info(message)
|
||||
}
|
||||
|
||||
error(message: string) {
|
||||
this.logger.error(message)
|
||||
}
|
||||
|
||||
warn(message: string) {
|
||||
this.logger.warn(message)
|
||||
}
|
||||
|
||||
debug(message: string) {
|
||||
this.logger.debug(message)
|
||||
}
|
||||
|
||||
static watch() {
|
||||
const fs = require('fs')
|
||||
|
||||
this.LOG_TYPES.forEach((type) => {
|
||||
const logFile = getRootPath('logs', `${type}.log`)
|
||||
const stats = fs.statSync(logFile)
|
||||
let lastPosition = stats.size
|
||||
|
||||
fs.watch(logFile, (eventType: string) => {
|
||||
if (eventType !== 'change') return
|
||||
|
||||
fs.stat(logFile, (err: Error, stats: { size: number }) => {
|
||||
if (err) return
|
||||
|
||||
if (stats.size > lastPosition) {
|
||||
const stream = fs.createReadStream(logFile, {
|
||||
start: lastPosition,
|
||||
end: stats.size
|
||||
})
|
||||
|
||||
stream.on('data', (chunk: Buffer) => {
|
||||
console.log(`[${type}]\n${chunk.toString()}`)
|
||||
})
|
||||
|
||||
lastPosition = stats.size
|
||||
}
|
||||
private getLogger(type: LoggerType): ReturnType<typeof pino> {
|
||||
if (!this.instances.has(type)) {
|
||||
this.instances.set(
|
||||
type,
|
||||
pino({
|
||||
level: process.env.LOG_LEVEL || 'debug',
|
||||
transport: {
|
||||
target: 'pino/file',
|
||||
options: {
|
||||
destination: `./logs/${type}.log`,
|
||||
mkdir: true
|
||||
}
|
||||
},
|
||||
formatters: {
|
||||
level: (label) => ({ level: label.toUpperCase() })
|
||||
},
|
||||
timestamp: pino.stdTimeFunctions.isoTime,
|
||||
base: null
|
||||
})
|
||||
})
|
||||
})
|
||||
)
|
||||
}
|
||||
return this.instances.get(type)!
|
||||
}
|
||||
|
||||
type(type: LoggerType) {
|
||||
return {
|
||||
info: (message: string, ...args: any[]) => this.getLogger(type).info(message, ...args),
|
||||
error: (message: string, ...args: any[]) => this.getLogger(type).error(message, ...args),
|
||||
warn: (message: string, ...args: any[]) => this.getLogger(type).warn(message, ...args),
|
||||
debug: (message: string, ...args: any[]) => this.getLogger(type).debug(message, ...args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new Logger()
|
||||
|
@ -7,13 +7,6 @@ import { loginAccountSchema, registerAccountSchema, resetPasswordSchema, newPass
|
||||
import UserService from '#services/userService'
|
||||
|
||||
export class AuthController extends BaseController {
|
||||
private userService: UserService
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.userService = new UserService()
|
||||
}
|
||||
|
||||
/**
|
||||
* Login user
|
||||
* @param req
|
||||
@ -24,7 +17,7 @@ export class AuthController extends BaseController {
|
||||
|
||||
try {
|
||||
loginAccountSchema.parse({ username, password })
|
||||
const user = await this.userService.login(username, password)
|
||||
const user = await UserService.login(username, password)
|
||||
|
||||
if (user && typeof user !== 'boolean') {
|
||||
const token = jwt.sign({ id: user.getId() }, config.JWT_SECRET, { expiresIn: '4h' })
|
||||
@ -47,7 +40,7 @@ export class AuthController extends BaseController {
|
||||
|
||||
try {
|
||||
registerAccountSchema.parse({ username, email, password })
|
||||
const user = await this.userService.register(username, email, password)
|
||||
const user = await UserService.register(username, email, password)
|
||||
|
||||
if (user) {
|
||||
return this.sendSuccess(res, null, 'User registered successfully')
|
||||
@ -69,7 +62,7 @@ export class AuthController extends BaseController {
|
||||
|
||||
try {
|
||||
resetPasswordSchema.parse({ email })
|
||||
const sentEmail = await this.userService.requestPasswordReset(email)
|
||||
const sentEmail = await UserService.requestPasswordReset(email)
|
||||
|
||||
if (sentEmail) {
|
||||
return this.sendSuccess(res, null, 'Password reset email sent')
|
||||
@ -91,7 +84,7 @@ export class AuthController extends BaseController {
|
||||
|
||||
try {
|
||||
newPasswordSchema.parse({ urlToken, password })
|
||||
const resetPassword = await this.userService.resetPassword(urlToken, password)
|
||||
const resetPassword = await UserService.resetPassword(urlToken, password)
|
||||
|
||||
if (resetPassword) {
|
||||
return this.sendSuccess(res, null, 'Password has been reset')
|
||||
|
@ -4,10 +4,11 @@ import * as readline from 'readline'
|
||||
|
||||
import { Server } from 'socket.io'
|
||||
|
||||
import { commandLogger } from '#application/logger'
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
import { getAppPath } from '#application/storage'
|
||||
|
||||
class CommandManager {
|
||||
private logger = Logger.type(LoggerType.COMMAND)
|
||||
private commands: Map<string, any> = new Map()
|
||||
private rl: readline.Interface
|
||||
private io: Server | null = null
|
||||
@ -27,7 +28,7 @@ class CommandManager {
|
||||
public async boot(io: Server) {
|
||||
this.io = io
|
||||
await this.loadCommands()
|
||||
commandLogger.info('Command manager loaded')
|
||||
this.logger.info('Command manager loaded')
|
||||
this.startPrompt()
|
||||
}
|
||||
|
||||
@ -64,7 +65,7 @@ class CommandManager {
|
||||
|
||||
private async loadCommands() {
|
||||
const directory = getAppPath('commands')
|
||||
commandLogger.info(`Loading commands from: ${directory}`)
|
||||
this.logger.info(`Loading commands from: ${directory}`)
|
||||
|
||||
try {
|
||||
const files = await fs.promises.readdir(directory, { withFileTypes: true })
|
||||
@ -80,26 +81,26 @@ class CommandManager {
|
||||
try {
|
||||
const module = await import(fullPath)
|
||||
if (typeof module.default !== 'function') {
|
||||
commandLogger.warn(`Unrecognized export in ${file.name}`)
|
||||
this.logger.warn(`Unrecognized export in ${file.name}`)
|
||||
continue
|
||||
}
|
||||
|
||||
this.registerCommand(commandName, module.default)
|
||||
} catch (error) {
|
||||
commandLogger.error(`Error loading command ${file.name}: ${error instanceof Error ? error.message : String(error)}`)
|
||||
this.logger.error(`Error loading command ${file.name}: ${error instanceof Error ? error.message : String(error)}`)
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
commandLogger.error(`Failed to read commands directory: ${error instanceof Error ? error.message : String(error)}`)
|
||||
this.logger.error(`Failed to read commands directory: ${error instanceof Error ? error.message : String(error)}`)
|
||||
}
|
||||
}
|
||||
|
||||
private registerCommand(name: string, CommandClass: any) {
|
||||
if (this.commands.has(name)) {
|
||||
commandLogger.warn(`Command '${name}' is already registered. Overwriting...`)
|
||||
this.logger.warn(`Command '${name}' is already registered. Overwriting...`)
|
||||
}
|
||||
this.commands.set(name, CommandClass)
|
||||
commandLogger.info(`Registered command: ${name}`)
|
||||
this.logger.info(`Registered command: ${name}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Server } from 'socket.io'
|
||||
|
||||
import { appLogger } from '#application/logger'
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
import worldRepository from '#repositories/worldRepository'
|
||||
import worldService from '#services/worldService'
|
||||
|
||||
@ -11,12 +11,13 @@ class DateManager {
|
||||
private io: Server | null = null
|
||||
private intervalId: NodeJS.Timeout | null = null
|
||||
private currentDate: Date = new Date()
|
||||
private logger = Logger.type(LoggerType.APP)
|
||||
|
||||
public async boot(io: Server): Promise<void> {
|
||||
this.io = io
|
||||
await this.loadDate()
|
||||
this.startDateLoop()
|
||||
appLogger.info('Date manager loaded')
|
||||
this.logger.info('Date manager loaded')
|
||||
}
|
||||
|
||||
public async setTime(time: string): Promise<void> {
|
||||
@ -38,7 +39,7 @@ class DateManager {
|
||||
this.emitDate()
|
||||
await this.saveDate()
|
||||
} catch (error) {
|
||||
appLogger.error(`Failed to set time: ${error instanceof Error ? error.message : String(error)}`)
|
||||
this.logger.error(`Failed to set time: ${error instanceof Error ? error.message : String(error)}`)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
@ -51,7 +52,7 @@ class DateManager {
|
||||
this.currentDate = world.date
|
||||
}
|
||||
} catch (error) {
|
||||
appLogger.error(`Failed to load date: ${error instanceof Error ? error.message : String(error)}`)
|
||||
this.logger.error(`Failed to load date: ${error instanceof Error ? error.message : String(error)}`)
|
||||
this.currentDate = new Date() // Use current date as fallback
|
||||
}
|
||||
}
|
||||
@ -82,7 +83,7 @@ class DateManager {
|
||||
date: this.currentDate
|
||||
})
|
||||
} catch (error) {
|
||||
appLogger.error(`Failed to save date: ${error instanceof Error ? error.message : String(error)}`)
|
||||
this.logger.error(`Failed to save date: ${error instanceof Error ? error.message : String(error)}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ import IORedis from 'ioredis'
|
||||
import { Server as SocketServer } from 'socket.io'
|
||||
|
||||
import config from '#application/config'
|
||||
import { queueLogger } from '#application/logger'
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
import { getAppPath } from '#application/storage'
|
||||
import { TSocket } from '#application/types'
|
||||
|
||||
@ -14,6 +14,7 @@ class QueueManager {
|
||||
private queue!: Queue
|
||||
private worker!: Worker
|
||||
private io!: SocketServer
|
||||
private logger = Logger.type(LoggerType.QUEUE)
|
||||
|
||||
public async boot(io: SocketServer) {
|
||||
this.io = io
|
||||
@ -24,9 +25,9 @@ class QueueManager {
|
||||
|
||||
try {
|
||||
await this.connection.ping()
|
||||
queueLogger.info('Successfully connected to Redis')
|
||||
this.logger.info('Successfully connected to Redis')
|
||||
} catch (error) {
|
||||
queueLogger.error('Failed to connect to Redis:', error)
|
||||
this.logger.error('Failed to connect to Redis:', error)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
@ -40,14 +41,14 @@ class QueueManager {
|
||||
})
|
||||
|
||||
this.worker.on('completed', (job) => {
|
||||
queueLogger.info(`Job ${job?.id} has completed`)
|
||||
this.logger.info(`Job ${job?.id} has completed`)
|
||||
})
|
||||
|
||||
this.worker.on('failed', (job, err) => {
|
||||
queueLogger.error(`Job ${job?.id} failed with error: ${err}`)
|
||||
this.logger.error(`Job ${job?.id} failed with error: ${err}`)
|
||||
})
|
||||
|
||||
queueLogger.info('Queue manager loaded')
|
||||
this.logger.info('Queue manager loaded')
|
||||
}
|
||||
|
||||
private async processJob(job: Job) {
|
||||
@ -59,7 +60,7 @@ class QueueManager {
|
||||
const jobPath = getAppPath('jobs', `${jobName}${extension}`)
|
||||
|
||||
if (!fs.existsSync(jobPath)) {
|
||||
queueLogger.warn(`Job file not found: ${jobPath}`)
|
||||
this.logger.warn(`Job file not found: ${jobPath}`)
|
||||
return
|
||||
}
|
||||
|
||||
@ -67,7 +68,7 @@ class QueueManager {
|
||||
const JobClass = JobModule.default
|
||||
|
||||
if (!JobClass || typeof JobClass !== 'function') {
|
||||
queueLogger.warn(`Invalid job class in file: ${jobPath}`)
|
||||
this.logger.warn(`Invalid job class in file: ${jobPath}`)
|
||||
return
|
||||
}
|
||||
|
||||
@ -78,14 +79,14 @@ class QueueManager {
|
||||
if (socket) {
|
||||
await jobInstance.execute(this.io, socket)
|
||||
} else {
|
||||
queueLogger.warn(`Socket not found for job: ${socketId}`)
|
||||
this.logger.warn(`Socket not found for job: ${socketId}`)
|
||||
await jobInstance.execute(this.io)
|
||||
}
|
||||
} else {
|
||||
await jobInstance.execute(this.io)
|
||||
}
|
||||
} catch (error: any) {
|
||||
queueLogger.error(`Error processing job ${jobName}: ${error.message}`)
|
||||
this.logger.error(`Error processing job ${jobName}: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { User } from '@prisma/client'
|
||||
|
||||
import { appLogger } from '#application/logger'
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
|
||||
type TLoggedInUsers = {
|
||||
users: User[]
|
||||
@ -8,10 +8,11 @@ type TLoggedInUsers = {
|
||||
|
||||
class UserManager {
|
||||
private loggedInUsers: TLoggedInUsers[] = []
|
||||
private logger = Logger.type(LoggerType.APP)
|
||||
|
||||
// Method to initialize user manager
|
||||
public async boot() {
|
||||
appLogger.info('User manager loaded')
|
||||
this.logger.info('User manager loaded')
|
||||
}
|
||||
|
||||
// Function that adds user to logged in users
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { gameLogger } from '#application/logger'
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
import { Zone } from '#entities/zone'
|
||||
import LoadedZone from '#models/loadedZone'
|
||||
import ZoneCharacter from '#models/zoneCharacter'
|
||||
@ -6,23 +6,24 @@ import ZoneRepository from '#repositories/zoneRepository'
|
||||
|
||||
class ZoneManager {
|
||||
private readonly zones = new Map<number, LoadedZone>()
|
||||
private logger = Logger.type(LoggerType.GAME)
|
||||
|
||||
public async boot(): Promise<void> {
|
||||
const zones = await ZoneRepository.getAll()
|
||||
await Promise.all(zones.map((zone) => this.loadZone(zone)))
|
||||
|
||||
gameLogger.info(`Zone manager loaded with ${this.zones.size} zones`)
|
||||
this.logger.info(`Zone manager loaded with ${this.zones.size} zones`)
|
||||
}
|
||||
|
||||
public async loadZone(zone: Zone): Promise<void> {
|
||||
const loadedZone = new LoadedZone(zone)
|
||||
this.zones.set(zone.id, loadedZone)
|
||||
gameLogger.info(`Zone ID ${zone.id} loaded`)
|
||||
this.logger.info(`Zone ID ${zone.id} loaded`)
|
||||
}
|
||||
|
||||
public unloadZone(zoneId: number): void {
|
||||
this.zones.delete(zoneId)
|
||||
gameLogger.info(`Zone ID ${zoneId} unloaded`)
|
||||
this.logger.info(`Zone ID ${zoneId} unloaded`)
|
||||
}
|
||||
|
||||
public getLoadedZones(): LoadedZone[] {
|
||||
|
@ -7,7 +7,7 @@ import { Server as SocketServer } from 'socket.io'
|
||||
|
||||
import config from '#application/config'
|
||||
import Database from '#application/database'
|
||||
import { Logger } from '#application/logger'
|
||||
import Logger, { LoggerType } from '#application/logger'
|
||||
import { getAppPath } from '#application/storage'
|
||||
import { TSocket } from '#application/types'
|
||||
import { HttpRouter } from '#http/router'
|
||||
@ -23,7 +23,7 @@ export class Server {
|
||||
private readonly app: Application
|
||||
private readonly http: HTTPServer
|
||||
private readonly io: SocketServer
|
||||
private readonly logger: Logger = new Logger('app')
|
||||
private readonly logger = Logger.type(LoggerType.APP)
|
||||
|
||||
/**
|
||||
* Creates an instance of GameServer.
|
||||
@ -50,7 +50,6 @@ export class Server {
|
||||
*/
|
||||
public async start() {
|
||||
// Read log file and print to console for debugging
|
||||
Logger.watch()
|
||||
|
||||
// Connect to database
|
||||
try {
|
||||
|
@ -1,19 +1,12 @@
|
||||
import { Server } from 'socket.io'
|
||||
import { ZodError } from 'zod'
|
||||
|
||||
import { gameLogger } from '#application/logger'
|
||||
import { TSocket } from '#application/types'
|
||||
import { BaseEvent } from '#application/base/baseEvent'
|
||||
import { ZCharacterCreate } from '#application/zodTypes'
|
||||
import { Character } from '#entities/character'
|
||||
import CharacterRepository from '#repositories/characterRepository'
|
||||
import UserRepository from '#repositories/userRepository'
|
||||
|
||||
export default class CharacterCreateEvent {
|
||||
constructor(
|
||||
private readonly io: Server,
|
||||
private readonly socket: TSocket
|
||||
) {}
|
||||
|
||||
export default class CharacterCreateEvent extends BaseEvent {
|
||||
public listen(): void {
|
||||
this.socket.on('character:create', this.handleCharacterCreate.bind(this))
|
||||
}
|
||||
@ -52,9 +45,9 @@ export default class CharacterCreateEvent {
|
||||
this.socket.emit('character:create:success')
|
||||
this.socket.emit('character:list', characters)
|
||||
|
||||
gameLogger.info('character:create success')
|
||||
this.logger.info('character:create success')
|
||||
} catch (error: any) {
|
||||
gameLogger.error(`character:create error: ${error.message}`)
|
||||
this.logger.error(`character:create error: ${error.message}`)
|
||||
if (error instanceof ZodError) {
|
||||
return this.socket.emit('notification', { message: error.issues[0].message })
|
||||
}
|
||||
|
@ -1,44 +1,36 @@
|
||||
import { Server } from 'socket.io'
|
||||
|
||||
import { getArgs, isCommand } from '#application/chat'
|
||||
import { gameLogger } from '#application/logger'
|
||||
import { TSocket } from '#application/types'
|
||||
import { BaseEvent } from '#application/base/baseEvent'
|
||||
import CharacterRepository from '#repositories/characterRepository'
|
||||
import ChatService from '#services/chatService'
|
||||
|
||||
type TypePayload = {
|
||||
message: string
|
||||
}
|
||||
|
||||
export default class AlertCommandEvent {
|
||||
constructor(
|
||||
private readonly io: Server,
|
||||
private readonly socket: TSocket
|
||||
) {}
|
||||
|
||||
export default class AlertCommandEvent extends BaseEvent {
|
||||
public listen(): void {
|
||||
this.socket.on('chat:message', this.handleAlertCommand.bind(this))
|
||||
}
|
||||
|
||||
private async handleAlertCommand(data: TypePayload, callback: (response: boolean) => void): Promise<void> {
|
||||
try {
|
||||
if (!isCommand(data.message, 'alert')) {
|
||||
if (!ChatService.isCommand(data.message, 'alert')) {
|
||||
return
|
||||
}
|
||||
|
||||
// Check if character exists
|
||||
const character = await CharacterRepository.getByUserAndId(this.socket.userId!, this.socket.characterId!)
|
||||
if (!character) {
|
||||
gameLogger.error('chat:alert_command error', 'Character not found')
|
||||
this.logger.error('chat:alert_command error', 'Character not found')
|
||||
return callback(false)
|
||||
}
|
||||
|
||||
// Check if the user is the GM
|
||||
if (character.role !== 'gm') {
|
||||
gameLogger.info(`User ${character.id} tried to set time but is not a game master.`)
|
||||
this.logger.info(`User ${character.id} tried to set time but is not a game master.`)
|
||||
return callback(false)
|
||||
}
|
||||
|
||||
const args = getArgs('alert', data.message)
|
||||
const args = ChatService.getArgs('alert', data.message)
|
||||
|
||||
if (!args) {
|
||||
return callback(false)
|
||||
@ -47,7 +39,7 @@ export default class AlertCommandEvent {
|
||||
this.io.emit('notification', { title: 'Message from GM', message: args.join(' ') })
|
||||
return callback(true)
|
||||
} catch (error: any) {
|
||||
gameLogger.error('chat:alert_command error', error.message)
|
||||
this.logger.error('chat:alert_command error', error.message)
|
||||
callback(false)
|
||||
}
|
||||
}
|
||||
|
@ -1,46 +1,38 @@
|
||||
import { Server } from 'socket.io'
|
||||
|
||||
import { getArgs, isCommand } from '#application/chat'
|
||||
import { gameLogger } from '#application/logger'
|
||||
import { TSocket } from '#application/types'
|
||||
import { BaseEvent } from '#application/base/baseEvent'
|
||||
import DateManager from '#managers/dateManager'
|
||||
import CharacterRepository from '#repositories/characterRepository'
|
||||
import ChatService from '#services/chatService'
|
||||
|
||||
type TypePayload = {
|
||||
message: string
|
||||
}
|
||||
|
||||
export default class SetTimeCommand {
|
||||
constructor(
|
||||
private readonly io: Server,
|
||||
private readonly socket: TSocket
|
||||
) {}
|
||||
|
||||
export default class SetTimeCommand extends BaseEvent {
|
||||
public listen(): void {
|
||||
this.socket.on('chat:message', this.handleAlertCommand.bind(this))
|
||||
}
|
||||
|
||||
private async handleAlertCommand(data: TypePayload, callback: (response: boolean) => void): Promise<void> {
|
||||
try {
|
||||
if (!isCommand(data.message, 'time')) {
|
||||
if (!ChatService.isCommand(data.message, 'time')) {
|
||||
return
|
||||
}
|
||||
|
||||
// Check if character exists
|
||||
const character = await CharacterRepository.getByUserAndId(this.socket.userId!, this.socket.characterId!)
|
||||
if (!character) {
|
||||
gameLogger.error('chat:alert_command error', 'Character not found')
|
||||
this.logger.error('chat:alert_command error', 'Character not found')
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the user is the GM
|
||||
if (character.role !== 'gm') {
|
||||
gameLogger.info(`User ${character.id} tried to set time but is not a game master.`)
|
||||
this.logger.info(`User ${character.id} tried to set time but is not a game master.`)
|
||||
return
|
||||
}
|
||||
|
||||
// Get arguments
|
||||
const args = getArgs('time', data.message)
|
||||
const args = ChatService.getArgs('time', data.message)
|
||||
|
||||
if (!args) {
|
||||
return
|
||||
@ -54,7 +46,7 @@ export default class SetTimeCommand {
|
||||
|
||||
await DateManager.setTime(time)
|
||||
} catch (error: any) {
|
||||
gameLogger.error('command error', error.message)
|
||||
this.logger.error('command error', error.message)
|
||||
callback(false)
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,15 @@
|
||||
import { Server } from 'socket.io'
|
||||
|
||||
import { getArgs, isCommand } from '#application/chat'
|
||||
import { gameLogger, gameMasterLogger } from '#application/logger'
|
||||
import { TSocket } from '#application/types'
|
||||
import { BaseEvent } from '#application/base/baseEvent'
|
||||
import ZoneManager from '#managers/zoneManager'
|
||||
import zoneManager from '#managers/zoneManager'
|
||||
import ZoneCharacter from '#models/zoneCharacter'
|
||||
import ZoneRepository from '#repositories/zoneRepository'
|
||||
import ChatService from '#services/chatService'
|
||||
|
||||
type TypePayload = {
|
||||
message: string
|
||||
}
|
||||
|
||||
export default class TeleportCommandEvent {
|
||||
constructor(
|
||||
private readonly io: Server,
|
||||
private readonly socket: TSocket
|
||||
) {}
|
||||
|
||||
export default class TeleportCommandEvent extends BaseEvent {
|
||||
public listen(): void {
|
||||
this.socket.on('chat:message', this.handleTeleportCommand.bind(this))
|
||||
}
|
||||
@ -27,7 +19,7 @@ export default class TeleportCommandEvent {
|
||||
// Check if character exists
|
||||
const zoneCharacter = ZoneManager.getCharacterById(this.socket.characterId!)
|
||||
if (!zoneCharacter) {
|
||||
gameLogger.error('chat:message error', 'Character not found')
|
||||
this.logger.error('chat:message error', 'Character not found')
|
||||
return
|
||||
}
|
||||
|
||||
@ -35,13 +27,13 @@ export default class TeleportCommandEvent {
|
||||
|
||||
// Check if the user is the GM
|
||||
if (character.role !== 'gm') {
|
||||
gameLogger.info(`User ${character.id} tried to set time but is not a game master.`)
|
||||
this.logger.info(`User ${character.id} tried to set time but is not a game master.`)
|
||||
return
|
||||
}
|
||||
|
||||
if (!isCommand(data.message, 'teleport')) return
|
||||
if (!ChatService.isCommand(data.message, 'teleport')) return
|
||||
|
||||
const args = getArgs('teleport', data.message)
|
||||
const args = ChatService.getArgs('teleport', data.message)
|
||||
|
||||
if (!args || args.length !== 1) {
|
||||
this.socket.emit('notification', { title: 'Server message', message: 'Usage: /teleport <zoneId>' })
|
||||
@ -87,9 +79,9 @@ export default class TeleportCommandEvent {
|
||||
})
|
||||
|
||||
this.socket.emit('notification', { title: 'Server message', message: `You have been teleported to ${zone.name}` })
|
||||
gameMasterLogger.info('teleport', `Character ${character.id} teleported to zone ${zone.id}`)
|
||||
this.logger.info('teleport', `Character ${character.id} teleported to zone ${zone.id}`)
|
||||
} catch (error: any) {
|
||||
gameMasterLogger.error(`Error in teleport command: ${error.message}`)
|
||||
this.logger.error(`Error in teleport command: ${error.message}`)
|
||||
this.socket.emit('notification', { title: 'Server message', message: 'An error occurred while teleporting' })
|
||||
}
|
||||
}
|
||||
|
@ -1,47 +1,39 @@
|
||||
import { Server } from 'socket.io'
|
||||
|
||||
import { isCommand } from '#application/chat'
|
||||
import { gameLogger } from '#application/logger'
|
||||
import { TSocket } from '#application/types'
|
||||
import { BaseEvent } from '#application/base/baseEvent'
|
||||
import WeatherManager from '#managers/weatherManager'
|
||||
import CharacterRepository from '#repositories/characterRepository'
|
||||
import ChatService from '#services/chatService'
|
||||
|
||||
type TypePayload = {
|
||||
message: string
|
||||
}
|
||||
|
||||
export default class ToggleFogCommand {
|
||||
constructor(
|
||||
private readonly io: Server,
|
||||
private readonly socket: TSocket
|
||||
) {}
|
||||
|
||||
export default class ToggleFogCommand extends BaseEvent {
|
||||
public listen(): void {
|
||||
this.socket.on('chat:message', this.handleAlertCommand.bind(this))
|
||||
}
|
||||
|
||||
private async handleAlertCommand(data: TypePayload, callback: (response: boolean) => void): Promise<void> {
|
||||
try {
|
||||
if (!isCommand(data.message, 'fog')) {
|
||||
if (!ChatService.isCommand(data.message, 'fog')) {
|
||||
return
|
||||
}
|
||||
|
||||
// Check if character exists
|
||||
const character = await CharacterRepository.getByUserAndId(this.socket.userId!, this.socket.characterId!)
|
||||
if (!character) {
|
||||
gameLogger.error('chat:alert_command error', 'Character not found')
|
||||
this.logger.error('chat:alert_command error', 'Character not found')
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the user is the GM
|
||||
if (character.role !== 'gm') {
|
||||
gameLogger.info(`User ${character.id} tried to set time but is not a game master.`)
|
||||
this.logger.info(`User ${character.id} tried to set time but is not a game master.`)
|
||||
return
|
||||
}
|
||||
|
||||
await WeatherManager.toggleFog()
|
||||
} catch (error: any) {
|
||||
gameLogger.error('command error', error.message)
|
||||
this.logger.error('command error', error.message)
|
||||
callback(false)
|
||||
}
|
||||
}
|
||||
|
@ -1,47 +1,39 @@
|
||||
import { Server } from 'socket.io'
|
||||
|
||||
import { isCommand } from '#application/chat'
|
||||
import { gameLogger } from '#application/logger'
|
||||
import { TSocket } from '#application/types'
|
||||
import { BaseEvent } from '#application/base/baseEvent'
|
||||
import WeatherManager from '#managers/weatherManager'
|
||||
import CharacterRepository from '#repositories/characterRepository'
|
||||
import ChatService from '#services/chatService'
|
||||
|
||||
type TypePayload = {
|
||||
message: string
|
||||
}
|
||||
|
||||
export default class ToggleRainCommand {
|
||||
constructor(
|
||||
private readonly io: Server,
|
||||
private readonly socket: TSocket
|
||||
) {}
|
||||
|
||||
export default class ToggleRainCommand extends BaseEvent {
|
||||
public listen(): void {
|
||||
this.socket.on('chat:message', this.handleAlertCommand.bind(this))
|
||||
}
|
||||
|
||||
private async handleAlertCommand(data: TypePayload, callback: (response: boolean) => void): Promise<void> {
|
||||
try {
|
||||
if (!isCommand(data.message, 'rain')) {
|
||||
if (!ChatService.isCommand(data.message, 'rain')) {
|
||||
return
|
||||
}
|
||||
|
||||
// Check if character exists
|
||||
const character = await CharacterRepository.getByUserAndId(this.socket.userId!, this.socket.characterId!)
|
||||
if (!character) {
|
||||
gameLogger.error('chat:alert_command error', 'Character not found')
|
||||
this.logger.error('chat:alert_command error', 'Character not found')
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the user is the GM
|
||||
if (character.role !== 'gm') {
|
||||
gameLogger.info(`User ${character.id} tried to set time but is not a game master.`)
|
||||
this.logger.info(`User ${character.id} tried to set time but is not a game master.`)
|
||||
return
|
||||
}
|
||||
|
||||
await WeatherManager.toggleRain()
|
||||
} catch (error: any) {
|
||||
gameLogger.error('command error', error.message)
|
||||
this.logger.error('command error', error.message)
|
||||
callback(false)
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,4 @@
|
||||
import { Server } from 'socket.io'
|
||||
|
||||
import { isCommand } from '#application/chat'
|
||||
import { gameLogger } from '#application/logger'
|
||||
import { TSocket } from '#application/types'
|
||||
import { BaseEvent } from '#application/base/baseEvent'
|
||||
import ZoneManager from '#managers/zoneManager'
|
||||
import ZoneRepository from '#repositories/zoneRepository'
|
||||
import ChatService from '#services/chatService'
|
||||
@ -11,44 +7,38 @@ type TypePayload = {
|
||||
message: string
|
||||
}
|
||||
|
||||
export default class ChatMessageEvent {
|
||||
constructor(
|
||||
private readonly io: Server,
|
||||
private readonly socket: TSocket
|
||||
) {}
|
||||
|
||||
export default class ChatMessageEvent extends BaseEvent {
|
||||
public listen(): void {
|
||||
this.socket.on('chat:message', this.handleEvent.bind(this))
|
||||
}
|
||||
|
||||
private async handleEvent(data: TypePayload, callback: (response: boolean) => void): Promise<void> {
|
||||
try {
|
||||
if (!data.message || isCommand(data.message)) {
|
||||
if (!data.message || ChatService.isCommand(data.message)) {
|
||||
return callback(false)
|
||||
}
|
||||
|
||||
const zoneCharacter = ZoneManager.getCharacterById(this.socket.characterId!)
|
||||
if (!zoneCharacter) {
|
||||
gameLogger.error('chat:message error', 'Character not found')
|
||||
this.logger.error('chat:message error', 'Character not found')
|
||||
return callback(false)
|
||||
}
|
||||
|
||||
const character = zoneCharacter.character
|
||||
|
||||
const zone = await ZoneRepository.getById(character.zoneId)
|
||||
const zone = await ZoneRepository.getById(character.zone?.id!)
|
||||
if (!zone) {
|
||||
gameLogger.error('chat:message error', 'Zone not found')
|
||||
this.logger.error('chat:message error', 'Zone not found')
|
||||
return callback(false)
|
||||
}
|
||||
|
||||
const chatService = new ChatService()
|
||||
if (await chatService.sendZoneMessage(this.io, this.socket, data.message, character.id, zone.id)) {
|
||||
if (await ChatService.sendZoneMessage(this.io, this.socket, data.message, character.id, zone.id)) {
|
||||
return callback(true)
|
||||
}
|
||||
|
||||
callback(false)
|
||||
} catch (error: any) {
|
||||
gameLogger.error('chat:message error', error.message)
|
||||
this.logger.error('chat:message error', error.message)
|
||||
callback(false)
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import ZoneManager from '#managers/zoneManager'
|
||||
import { BaseEvent } from '#application/base/baseEvent'
|
||||
import ZoneManager from '#managers/zoneManager'
|
||||
|
||||
export default class DisconnectEvent extends BaseEvent {
|
||||
public listen(): void {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import UserRepository from '#repositories/userRepository'
|
||||
import { BaseEvent } from '#application/base/baseEvent'
|
||||
import UserRepository from '#repositories/userRepository'
|
||||
|
||||
export default class LoginEvent extends BaseEvent {
|
||||
public listen(): void {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { BaseEvent } from '#application/base/baseEvent'
|
||||
import ZoneManager from '#managers/zoneManager'
|
||||
import CharacterRepository from '#repositories/characterRepository'
|
||||
import { BaseEvent } from '#application/base/baseEvent'
|
||||
|
||||
export default class ZoneLeaveEvent extends BaseEvent {
|
||||
public listen(): void {
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { BaseEvent } from '#application/base/baseEvent'
|
||||
import { ZoneEventTileWithTeleport } from '#application/types'
|
||||
import ZoneManager from '#managers/zoneManager'
|
||||
import ZoneCharacter from '#models/zoneCharacter'
|
||||
import zoneEventTileRepository from '#repositories/zoneEventTileRepository'
|
||||
import CharacterService from '#services/characterService'
|
||||
import ZoneEventTileService from '#services/zoneEventTileService'
|
||||
import { BaseEvent } from '#application/base/baseEvent'
|
||||
|
||||
export default class CharacterMove extends BaseEvent {
|
||||
private readonly characterService = CharacterService
|
||||
|
@ -1,5 +1,5 @@
|
||||
import WeatherManager from '#managers/weatherManager'
|
||||
import { BaseEvent } from '#application/base/baseEvent'
|
||||
import WeatherManager from '#managers/weatherManager'
|
||||
|
||||
export default class Weather extends BaseEvent {
|
||||
public listen(): void {
|
||||
|
Loading…
x
Reference in New Issue
Block a user