import { Server } from 'socket.io' import { TSocket } from '#application/types' import { getArgs, isCommand } from '#application/chat' import ZoneRepository from '#repositories/zoneRepository' import { gameLogger, gameMasterLogger } from '#application/logger' import ZoneManager from '#managers/zoneManager' import ZoneCharacter from '#models/zoneCharacter' import zoneManager from '#managers/zoneManager' type TypePayload = { message: string } export default class TeleportCommandEvent { constructor( private readonly io: Server, private readonly socket: TSocket ) {} public listen(): void { this.socket.on('chat:message', this.handleTeleportCommand.bind(this)) } private async handleTeleportCommand(data: TypePayload, callback: (response: boolean) => void): Promise<void> { try { // Check if character exists const zoneCharacter = ZoneManager.getCharacter(this.socket.characterId!) if (!zoneCharacter) { gameLogger.error('chat:message error', 'Character not found') return } const character = zoneCharacter.character // 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.`) return } if (!isCommand(data.message, 'teleport')) return const args = getArgs('teleport', data.message) if (!args || args.length !== 1) { this.socket.emit('notification', { title: 'Server message', message: 'Usage: /teleport <zoneId>' }) return } const zoneId = parseInt(args[0], 10) if (isNaN(zoneId)) { this.socket.emit('notification', { title: 'Server message', message: 'Invalid zone ID' }) return } const zone = await ZoneRepository.getById(zoneId) if (!zone) { this.socket.emit('notification', { title: 'Server message', message: 'Zone not found' }) return } if (character.zoneId === zone.id) { this.socket.emit('notification', { title: 'Server message', message: 'You are already in that zone' }) return } // Remove character from current zone zoneManager.removeCharacter(character.id) this.io.to(character.zoneId.toString()).emit('zone:character:leave', character.id) this.socket.leave(character.zoneId.toString()) // Add character to new zone zoneManager.getZoneById(zone.id)?.addCharacter(character) this.io.to(zone.id.toString()).emit('zone:character:join', character) this.socket.join(zone.id.toString()) character.zoneId = zone.id character.positionX = 0 character.positionY = 0 zoneCharacter.isMoving = false this.socket.emit('zone:character:teleport', { zone, characters: ZoneManager.getZoneById(zone.id)?.getCharactersInZone() }) 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}`) } catch (error: any) { gameMasterLogger.error(`Error in teleport command: ${error.message}`) this.socket.emit('notification', { title: 'Server message', message: 'An error occurred while teleporting' }) } } }