Improved entities, ran formatting, utilise getters and setters
This commit is contained in:
parent
691abb7c4f
commit
4a963b4359
@ -1,6 +1,6 @@
|
||||
import { Migration } from '@mikro-orm/migrations';
|
||||
|
||||
export class Migration20241226031358 extends Migration {
|
||||
export class Migration20241226153149 extends Migration {
|
||||
|
||||
override async up(): Promise<void> {
|
||||
this.addSql(`create table \`map_object\` (\`id\` varchar(255) not null, \`name\` varchar(255) not null, \`tags\` json null, \`origin_x\` int not null default 0, \`origin_y\` int not null default 0, \`is_animated\` tinyint(1) not null default false, \`frame_rate\` int not null default 0, \`frame_width\` int not null default 0, \`frame_height\` int not null default 0, \`created_at\` datetime not null, \`updated_at\` datetime not null, primary key (\`id\`)) default character set utf8mb4 engine = InnoDB;`);
|
@ -42,17 +42,17 @@ export class Character extends BaseEntity {
|
||||
rotation = 0
|
||||
|
||||
// Customization
|
||||
@ManyToOne(() => CharacterType, { nullable: true })
|
||||
@ManyToOne()
|
||||
characterType?: CharacterType
|
||||
|
||||
@ManyToOne(() => CharacterHair, { nullable: true })
|
||||
@ManyToOne()
|
||||
characterHair?: CharacterHair
|
||||
|
||||
// Inventory
|
||||
@OneToMany(() => CharacterItem, (item) => item.character)
|
||||
@OneToMany({ mappedBy: 'character' })
|
||||
items = new Collection<CharacterItem>(this)
|
||||
|
||||
@OneToMany(() => CharacterEquipment, (equipment) => equipment.character)
|
||||
@OneToMany({ mappedBy: 'character' })
|
||||
equipment = new Collection<CharacterEquipment>(this)
|
||||
|
||||
// Stats
|
||||
|
@ -2,9 +2,6 @@ import { randomUUID } from 'node:crypto'
|
||||
import { Collection, Entity, OneToMany, PrimaryKey, Property } from '@mikro-orm/core'
|
||||
import { BaseEntity } from '#application/bases/baseEntity'
|
||||
import { SpriteAction } from './spriteAction'
|
||||
import { CharacterType } from './characterType'
|
||||
import { CharacterHair } from './characterHair'
|
||||
import { Item } from './item'
|
||||
import { UUID } from '#application/types'
|
||||
|
||||
@Entity()
|
||||
@ -15,24 +12,15 @@ export class Sprite extends BaseEntity {
|
||||
@Property()
|
||||
name!: string
|
||||
|
||||
@OneToMany(() => SpriteAction, (action) => action.sprite)
|
||||
spriteActions = new Collection<SpriteAction>(this)
|
||||
|
||||
@Property()
|
||||
createdAt = new Date()
|
||||
|
||||
@Property()
|
||||
updatedAt = new Date()
|
||||
|
||||
@OneToMany(() => SpriteAction, (action) => action.sprite)
|
||||
spriteActions = new Collection<SpriteAction>(this)
|
||||
|
||||
@OneToMany(() => CharacterType, (type) => type.sprite)
|
||||
characterTypes = new Collection<CharacterType>(this)
|
||||
|
||||
@OneToMany(() => CharacterHair, (hair) => hair.sprite)
|
||||
characterHairs = new Collection<CharacterHair>(this)
|
||||
|
||||
@OneToMany(() => Item, (item) => item.sprite)
|
||||
items = new Collection<Item>(this)
|
||||
|
||||
setId(id: UUID) {
|
||||
this.id = id
|
||||
return this
|
||||
@ -51,6 +39,15 @@ export class Sprite extends BaseEntity {
|
||||
return this.name
|
||||
}
|
||||
|
||||
setSpriteActions(spriteActions: Collection<SpriteAction>) {
|
||||
this.spriteActions = spriteActions
|
||||
return this
|
||||
}
|
||||
|
||||
getSpriteActions() {
|
||||
return this.spriteActions
|
||||
}
|
||||
|
||||
setCreatedAt(createdAt: Date) {
|
||||
this.createdAt = createdAt
|
||||
return this
|
||||
|
@ -20,7 +20,7 @@ router.post('/login', async (req: Request, res: Response) => {
|
||||
const user = await userService.login(username, password)
|
||||
|
||||
if (user && typeof user !== 'boolean') {
|
||||
const token = jwt.sign({ id: user.id }, config.JWT_SECRET, { expiresIn: '4h' })
|
||||
const token = jwt.sign({ id: user.getId() }, config.JWT_SECRET, { expiresIn: '4h' })
|
||||
return res.status(200).json({ token })
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ class CharacterHairRepository extends BaseRepository {
|
||||
async getFirst() {
|
||||
try {
|
||||
const repository = this.em.getRepository(CharacterHair)
|
||||
return await repository.findOne({ id: { $exists: true } })
|
||||
return await repository.findOne({ id: { $exists: true } }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get first character hair: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return null
|
||||
@ -16,7 +16,7 @@ class CharacterHairRepository extends BaseRepository {
|
||||
async getAll() {
|
||||
try {
|
||||
const repository = this.em.getRepository(CharacterHair)
|
||||
return await repository.findAll()
|
||||
return await repository.findAll({ populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get all character hair: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return null
|
||||
@ -26,9 +26,7 @@ class CharacterHairRepository extends BaseRepository {
|
||||
async getAllSelectable() {
|
||||
try {
|
||||
const repository = this.em.getRepository(CharacterHair)
|
||||
return await repository.find({
|
||||
isSelectable: true
|
||||
})
|
||||
return await repository.find({ isSelectable: true }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get selectable character hair: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return null
|
||||
@ -38,12 +36,7 @@ class CharacterHairRepository extends BaseRepository {
|
||||
async getById(id: number) {
|
||||
try {
|
||||
const repository = this.em.getRepository(CharacterHair)
|
||||
return await repository.findOne(
|
||||
{ id },
|
||||
{
|
||||
populate: ['sprite.spriteActions']
|
||||
}
|
||||
)
|
||||
return await repository.findOne({ id }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get character hair by ID: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return null
|
||||
|
@ -6,9 +6,7 @@ class CharacterRepository extends BaseRepository {
|
||||
async getByUserId(userId: number): Promise<Character[]> {
|
||||
try {
|
||||
const repository = this.em.getRepository(Character)
|
||||
return await repository.find({
|
||||
user: userId
|
||||
})
|
||||
return await repository.find({ user: userId }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get character by user ID: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return []
|
||||
@ -18,10 +16,7 @@ class CharacterRepository extends BaseRepository {
|
||||
async getByUserAndId(userId: number, characterId: number): Promise<Character | null> {
|
||||
try {
|
||||
const repository = this.em.getRepository(Character)
|
||||
return await repository.findOne({
|
||||
user: userId,
|
||||
id: characterId
|
||||
})
|
||||
return await repository.findOne({ user: userId, id: characterId }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get character by user ID and character ID: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return null
|
||||
@ -31,7 +26,7 @@ class CharacterRepository extends BaseRepository {
|
||||
async getById(id: number): Promise<Character | null> {
|
||||
try {
|
||||
const repository = this.em.getRepository(Character)
|
||||
return await repository.findOne({ id })
|
||||
return await repository.findOne({ id }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get character by ID: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return null
|
||||
@ -41,7 +36,7 @@ class CharacterRepository extends BaseRepository {
|
||||
async getByName(name: string): Promise<Character | null> {
|
||||
try {
|
||||
const repository = this.em.getRepository(Character)
|
||||
return await repository.findOne({ name })
|
||||
return await repository.findOne({ name }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get character by name: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return null
|
||||
|
@ -6,7 +6,7 @@ class CharacterTypeRepository extends BaseRepository {
|
||||
async getFirst() {
|
||||
try {
|
||||
const repository = this.em.getRepository(CharacterType)
|
||||
return await repository.findOne({ id: { $exists: true } })
|
||||
return await repository.findOne({ id: { $exists: true } }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get first character type: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return null
|
||||
@ -16,7 +16,7 @@ class CharacterTypeRepository extends BaseRepository {
|
||||
async getAll() {
|
||||
try {
|
||||
const repository = this.em.getRepository(CharacterType)
|
||||
return await repository.findAll()
|
||||
return await repository.findAll({ populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get all character types: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return null
|
||||
@ -26,7 +26,7 @@ class CharacterTypeRepository extends BaseRepository {
|
||||
async getById(id: number) {
|
||||
try {
|
||||
const repository = this.em.getRepository(CharacterType)
|
||||
return await repository.findOne({ id })
|
||||
return await repository.findOne({ id }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get character type by ID: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return null
|
||||
|
@ -6,9 +6,12 @@ class ChatRepository extends BaseRepository {
|
||||
async getById(id: number): Promise<Chat[]> {
|
||||
try {
|
||||
const repository = this.em.getRepository(Chat)
|
||||
return await repository.find({
|
||||
id
|
||||
})
|
||||
return await repository.find(
|
||||
{
|
||||
id
|
||||
},
|
||||
{ populate: ['*'] }
|
||||
)
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get chat by ID: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return []
|
||||
@ -18,7 +21,7 @@ class ChatRepository extends BaseRepository {
|
||||
async getAll(): Promise<Chat[]> {
|
||||
try {
|
||||
const repository = this.em.getRepository(Chat)
|
||||
return await repository.findAll()
|
||||
return await repository.findAll({ populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get all chats: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return []
|
||||
@ -28,9 +31,7 @@ class ChatRepository extends BaseRepository {
|
||||
async getByCharacterId(characterId: number): Promise<Chat[]> {
|
||||
try {
|
||||
const repository = this.em.getRepository(Chat)
|
||||
return await repository.find({
|
||||
character: characterId
|
||||
})
|
||||
return await repository.find({ character: characterId }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get chats by character ID: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return []
|
||||
@ -40,9 +41,7 @@ class ChatRepository extends BaseRepository {
|
||||
async getByZoneId(zoneId: number): Promise<Chat[]> {
|
||||
try {
|
||||
const repository = this.em.getRepository(Chat)
|
||||
return await repository.find({
|
||||
zone: zoneId
|
||||
})
|
||||
return await repository.find({ zone: zoneId }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get chats by zone ID: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return []
|
||||
|
@ -6,7 +6,7 @@ class SpriteRepository extends BaseRepository {
|
||||
async getById(id: FilterValue<`${string}-${string}-${string}-${string}-${string}`>) {
|
||||
try {
|
||||
const repository = this.em.getRepository(Sprite)
|
||||
return await repository.findOne({ id })
|
||||
return await repository.findOne({ id }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
return null
|
||||
}
|
||||
@ -15,7 +15,7 @@ class SpriteRepository extends BaseRepository {
|
||||
async getAll(): Promise<any> {
|
||||
try {
|
||||
const repository = this.em.getRepository(Sprite)
|
||||
return await repository.findAll()
|
||||
return await repository.findAll({ populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
return null
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ class UserRepository extends BaseRepository {
|
||||
async getById(id: number) {
|
||||
try {
|
||||
const repository = this.em.getRepository(User)
|
||||
return await repository.findOne({ id })
|
||||
return await repository.findOne({ id }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get user by ID: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return null
|
||||
@ -16,7 +16,7 @@ class UserRepository extends BaseRepository {
|
||||
async getByUsername(username: string) {
|
||||
try {
|
||||
const repository = this.em.getRepository(User)
|
||||
return await repository.findOne({ username })
|
||||
return await repository.findOne({ username }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get user by username: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return null
|
||||
@ -26,7 +26,7 @@ class UserRepository extends BaseRepository {
|
||||
async getByEmail(email: string) {
|
||||
try {
|
||||
const repository = this.em.getRepository(User)
|
||||
return await repository.findOne({ email })
|
||||
return await repository.findOne({ email }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get user by email: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return null
|
||||
|
@ -8,7 +8,7 @@ class ZoneRepository extends BaseRepository {
|
||||
async getFirst(): Promise<Zone | null> {
|
||||
try {
|
||||
const repository = this.em.getRepository(Zone)
|
||||
return await repository.findOne({ id: { $exists: true } })
|
||||
return await repository.findOne({ id: { $exists: true } }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get first zone: ${error instanceof Error ? error.message : String(error)}`)
|
||||
return null
|
||||
@ -18,7 +18,7 @@ class ZoneRepository extends BaseRepository {
|
||||
async getAll(): Promise<Zone[]> {
|
||||
try {
|
||||
const repository = this.em.getRepository(Zone)
|
||||
return await repository.findAll()
|
||||
return await repository.findAll({ populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get all zone: ${error.message}`)
|
||||
return []
|
||||
@ -28,7 +28,7 @@ class ZoneRepository extends BaseRepository {
|
||||
async getById(id: number) {
|
||||
try {
|
||||
const repository = this.em.getRepository(Zone)
|
||||
return await repository.findOne({ id })
|
||||
return await repository.findOne({ id }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get zone by id: ${error.message}`)
|
||||
return null
|
||||
@ -38,9 +38,7 @@ class ZoneRepository extends BaseRepository {
|
||||
async getEventTiles(id: number): Promise<ZoneEventTile[]> {
|
||||
try {
|
||||
const repository = this.em.getRepository(ZoneEventTile)
|
||||
return await repository.find({
|
||||
zone: id
|
||||
})
|
||||
return await repository.find({ zone: id }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get zone event tiles: ${error.message}`)
|
||||
return []
|
||||
@ -50,11 +48,14 @@ class ZoneRepository extends BaseRepository {
|
||||
async getFirstEventTile(zoneId: number, positionX: number, positionY: number): Promise<ZoneEventTile | null> {
|
||||
try {
|
||||
const repository = this.em.getRepository(ZoneEventTile)
|
||||
return await repository.findOne({
|
||||
zone: zoneId,
|
||||
positionX: positionX,
|
||||
positionY: positionY
|
||||
})
|
||||
return await repository.findOne(
|
||||
{
|
||||
zone: zoneId,
|
||||
positionX: positionX,
|
||||
positionY: positionY
|
||||
},
|
||||
{ populate: ['*'] }
|
||||
)
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get zone event tile: ${error.message}`)
|
||||
return null
|
||||
@ -64,9 +65,7 @@ class ZoneRepository extends BaseRepository {
|
||||
async getZoneObjects(id: number): Promise<ZoneObject[]> {
|
||||
try {
|
||||
const repository = this.em.getRepository(ZoneObject)
|
||||
return await repository.find({
|
||||
zone: id
|
||||
})
|
||||
return await repository.find({ zone: id }, { populate: ['*'] })
|
||||
} catch (error: any) {
|
||||
appLogger.error(`Failed to get zone objects: ${error.message}`)
|
||||
return []
|
||||
|
@ -74,7 +74,7 @@ export class Server {
|
||||
await UserManager.boot()
|
||||
|
||||
// Load date manager
|
||||
await DateManager.boot(this.io)
|
||||
// await DateManager.boot(this.io)
|
||||
|
||||
// Load weather manager
|
||||
await WeatherManager.boot(this.io)
|
||||
|
@ -17,10 +17,7 @@ class ChatService {
|
||||
|
||||
const newChat = new Chat()
|
||||
|
||||
newChat
|
||||
.setCharacter(character)
|
||||
.setZone(zone)
|
||||
.setMessage(message)
|
||||
newChat.setCharacter(character).setZone(zone).setMessage(message)
|
||||
|
||||
await newChat.save()
|
||||
|
||||
|
@ -48,10 +48,7 @@ class UserService {
|
||||
const hashedPassword = await bcrypt.hash(password, 10)
|
||||
|
||||
const newUser = new User()
|
||||
newUser
|
||||
.setUsername(username)
|
||||
.setEmail(email)
|
||||
.setPassword(hashedPassword)
|
||||
newUser.setUsername(username).setEmail(email).setPassword(hashedPassword)
|
||||
await newUser.save()
|
||||
|
||||
return newUser
|
||||
@ -82,9 +79,7 @@ class UserService {
|
||||
|
||||
// Create new token using MikroORM
|
||||
const passwordResetToken = new PasswordResetToken()
|
||||
passwordResetToken
|
||||
.setUser(user)
|
||||
.setToken(token)
|
||||
passwordResetToken.setUser(user).setToken(token)
|
||||
await passwordResetToken.save()
|
||||
|
||||
const transporter = NodeMailer.createTransport({
|
||||
|
@ -21,11 +21,7 @@ export class ZoneEventTileService {
|
||||
|
||||
character.isMoving = false
|
||||
// Update local character object
|
||||
character
|
||||
.setZone(teleport.toZone)
|
||||
.setRotation(teleport.toRotation)
|
||||
.setPositionX(teleport.toPositionX)
|
||||
.setPositionY(teleport.toPositionY)
|
||||
character.setZone(teleport.toZone).setRotation(teleport.toRotation).setPositionX(teleport.toPositionX).setPositionY(teleport.toPositionY)
|
||||
|
||||
await character.save()
|
||||
|
||||
|
@ -16,7 +16,7 @@ export default class CharacterListEvent {
|
||||
|
||||
private async handleCharacterList(data: any): Promise<void> {
|
||||
try {
|
||||
const characters: Character[] = (await CharacterRepository.getByUserId(this.socket.userId!)) as Character[]
|
||||
const characters: Character[] = await CharacterRepository.getByUserId(this.socket.userId!)
|
||||
this.socket.emit('character:list', characters)
|
||||
} catch (error: any) {
|
||||
gameLogger.error('character:list error', error.message)
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '#application/types'
|
||||
import ZoneRepository from '#repositories/zoneRepository'
|
||||
import { Zone } from '@prisma/client'
|
||||
import { gameLogger } from '#application/logger'
|
||||
import CharacterRepository from '#repositories/characterRepository'
|
||||
import ZoneManager from '#managers/zoneManager'
|
||||
import zoneCharacter from '#models/zoneCharacter'
|
||||
import zoneManager from '#managers/zoneManager'
|
||||
import { Zone } from '#entities/zone'
|
||||
|
||||
interface IResponse {
|
||||
zone: Zone
|
||||
@ -39,7 +39,7 @@ export default class CharacterJoinEvent {
|
||||
/**
|
||||
* @TODO: If zone is not found, spawn back to the start
|
||||
*/
|
||||
const zone = await ZoneRepository.getById(character.zoneId)
|
||||
const zone = await ZoneRepository.getById(character.zone!.id)
|
||||
if (!zone) {
|
||||
gameLogger.error('zone:character:join error', 'Zone not found')
|
||||
return
|
||||
|
@ -36,7 +36,7 @@ export default class CharacterMove {
|
||||
|
||||
const path = await this.characterService.calculatePath(zoneCharacter.character, positionX, positionY)
|
||||
if (!path) {
|
||||
this.io.in(zoneCharacter.character.zoneId.toString()).emit('character:moveError', 'No valid path found')
|
||||
this.io.in(zoneCharacter.character.zone!.id.toString()).emit('character:moveError', 'No valid path found')
|
||||
return
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ export default class CharacterMove {
|
||||
const [start, end] = [path[i], path[i + 1]]
|
||||
character.rotation = Rotation.calculate(start.x, start.y, end.x, end.y)
|
||||
|
||||
const zoneEventTile = await zoneEventTileRepository.getEventTileByZoneIdAndPosition(character.zoneId, Math.floor(end.x), Math.floor(end.y))
|
||||
const zoneEventTile = await zoneEventTileRepository.getEventTileByZoneIdAndPosition(character.zone!.id, Math.floor(end.x), Math.floor(end.y))
|
||||
|
||||
if (zoneEventTile?.type === 'BLOCK') break
|
||||
if (zoneEventTile?.type === 'TELEPORT' && zoneEventTile.teleport) {
|
||||
@ -67,7 +67,7 @@ export default class CharacterMove {
|
||||
}
|
||||
|
||||
this.characterService.updatePosition(character, end)
|
||||
this.io.in(character.zoneId.toString()).emit('character:move', zoneCharacter)
|
||||
this.io.in(character.zone!.id.toString()).emit('character:move', zoneCharacter)
|
||||
await this.characterService.applyMovementDelay()
|
||||
}
|
||||
|
||||
@ -91,6 +91,6 @@ export default class CharacterMove {
|
||||
|
||||
private finalizeMovement(zoneCharacter: ZoneCharacter): void {
|
||||
zoneCharacter.isMoving = false
|
||||
this.io.in(zoneCharacter.character.zoneId.toString()).emit('character:move', zoneCharacter)
|
||||
this.io.in(zoneCharacter.character.zone!.id.toString()).emit('character:move', zoneCharacter)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user