forked from noxious/server
85 lines
3.1 KiB
TypeScript
85 lines
3.1 KiB
TypeScript
import { BaseEvent } from '@/application/base/baseEvent'
|
|
import { SocketEvent } from '@/application/enums'
|
|
import { ZCharacterCreate } from '@/application/zodTypes'
|
|
import { Character } from '@/entities/character'
|
|
import CharacterRepository from '@/repositories/characterRepository'
|
|
import CharacterTypeRepository from '@/repositories/characterTypeRepository'
|
|
import MapRepository from '@/repositories/mapRepository'
|
|
import UserRepository from '@/repositories/userRepository'
|
|
import { z, ZodError } from 'zod'
|
|
|
|
const MAX_CHARACTERS = 4
|
|
|
|
export default class CharacterCreateEvent extends BaseEvent {
|
|
private readonly userRepository: UserRepository = new UserRepository()
|
|
private readonly characterRepository: CharacterRepository = new CharacterRepository()
|
|
private readonly characterTypeRepository: CharacterTypeRepository = new CharacterTypeRepository()
|
|
private readonly mapRepository: MapRepository = new MapRepository()
|
|
|
|
public listen(): void {
|
|
this.socket.on(SocketEvent.CHARACTER_CREATE, this.handleEvent.bind(this))
|
|
}
|
|
|
|
private async handleEvent(data: z.infer<typeof ZCharacterCreate>, callback: (success: boolean) => void): Promise<void> {
|
|
try {
|
|
const validatedData = ZCharacterCreate.parse(data)
|
|
await this.createCharacter(validatedData)
|
|
callback(true)
|
|
} catch (error: unknown) {
|
|
this.returnError(error)
|
|
callback(false)
|
|
}
|
|
}
|
|
|
|
private async createCharacter(data: z.infer<typeof ZCharacterCreate>): Promise<void> {
|
|
const user = await this.userRepository.getById(this.socket.userId)
|
|
if (!user) {
|
|
throw new Error('You are not logged in')
|
|
}
|
|
|
|
const characterExists = await this.characterRepository.getByName(data.name)
|
|
if (characterExists) {
|
|
throw new Error('Character name already exists')
|
|
}
|
|
|
|
let characters = await this.characterRepository.getByUserId(user.getId())
|
|
if (characters.length >= MAX_CHARACTERS) {
|
|
throw new Error(`You can only create ${MAX_CHARACTERS} characters`)
|
|
}
|
|
|
|
const map = await this.mapRepository.getFirst()
|
|
if (!map) {
|
|
throw new Error('No default map found')
|
|
}
|
|
|
|
const characterType = await this.characterTypeRepository.getFirst()
|
|
if (!characterType) {
|
|
throw new Error('No character type found')
|
|
}
|
|
|
|
const newCharacter = new Character()
|
|
await newCharacter.setName(data.name).setUser(user).setMap(map).setCharacterType(characterType).save()
|
|
characters = await this.characterRepository.getByUserId(user.getId())
|
|
|
|
this.socket.emit(SocketEvent.CHARACTER_LIST, characters)
|
|
this.logger.info('character:create success')
|
|
}
|
|
|
|
private returnError(error: unknown): void {
|
|
this.logger.error(`character:create error: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
|
|
let errorMessage = 'Could not create character. Please try again later.'
|
|
|
|
if (error instanceof ZodError) {
|
|
errorMessage = error.issues[0]?.message || errorMessage
|
|
} else if (error instanceof Error) {
|
|
errorMessage = error.message
|
|
}
|
|
|
|
this.socket.emit(SocketEvent.NOTIFICATION, {
|
|
title: 'Error',
|
|
message: errorMessage
|
|
})
|
|
}
|
|
}
|