import { Server } from 'socket.io' import { gameLogger } from '#application/logger' import { TSocket } from '#application/types' import ZoneManager from '#managers/zoneManager' import CharacterRepository from '#repositories/characterRepository' import ZoneRepository from '#repositories/zoneRepository' export default class ZoneLeaveEvent { constructor(private readonly io: Server, private readonly socket: TSocket) {} public listen(): void { this.socket.on('zone:character:leave', this.handleZoneLeave.bind(this)) } private async handleZoneLeave(): Promise { try { if (!this.socket.characterId) { gameLogger.error('zone:character:join error', 'Zone requested but no character id set') return } const character = await CharacterRepository.getById(this.socket.characterId) if (!character) { gameLogger.error('zone:character:join error', 'Character not found') return } /** * @TODO: If zone is not found, spawn back to the start */ const zone = character.zone if (!zone) { gameLogger.error('zone:character:join error', 'Zone not found') return } const loadedZone = ZoneManager.getZoneById(zone.id) if (!loadedZone) { gameLogger.error('zone:character:join error', 'Loaded zone not found') return } this.socket.leave(zone.id.toString()) // let other clients know of character leaving this.io.to(zone.id.toString()).emit('zone:character:leave', character.id) // remove character from zone manager await loadedZone.removeCharacter(character.id) gameLogger.info('zone:character:leave', `Character ${character.id} left zone ${zone.id}`) } catch (error: any) { gameLogger.error('zone:character:leave error', error.message) } } }