import { Server } from 'socket.io' import { ZodError } from 'zod' import { gameLogger } from '#application/logger' import { TSocket } from '#application/types' 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 ) {} public listen(): void { this.socket.on('character:create', this.handleCharacterCreate.bind(this)) } private async handleCharacterCreate(data: any): Promise { // zod validate try { data = ZCharacterCreate.parse(data) const user = await UserRepository.getById(this.socket.userId!) if (!user) { return this.socket.emit('notification', { message: 'User not found' }) } // Check if character name already exists const characterExists = await CharacterRepository.getByName(data.name) if (characterExists) { return this.socket.emit('notification', { message: 'Character name already exists' }) } let characters: Character[] = (await CharacterRepository.getByUserId(user.getId())) if (characters.length >= 4) { return this.socket.emit('notification', { message: 'You can only have 4 characters' }) } const newCharacter = new Character() await newCharacter .setName(data.name) .setUser(user) .save() if (!newCharacter) return this.socket.emit('notification', { message: 'Failed to create character. Please try again (later).' }) characters = [...characters, newCharacter] this.socket.emit('character:create:success') this.socket.emit('character:list', characters) gameLogger.info('character:create success') } catch (error: any) { gameLogger.error(`character:create error: ${error.message}`) if (error instanceof ZodError) { return this.socket.emit('notification', { message: error.issues[0].message }) } return this.socket.emit('notification', { message: 'Could not create character. Please try again (later).' }) } } }