From 898069140987b5fdd66eb6b7d319ef77cf79085b Mon Sep 17 00:00:00 2001 From: Dennis Postma Date: Tue, 24 Dec 2024 22:08:08 +0100 Subject: [PATCH] Added ORM entities --- src/entities/character.ts | 84 ++++++++++++++++++++++++++++++ src/entities/characterEquipment.ts | 19 +++++++ src/entities/characterHair.ts | 25 +++++++++ src/entities/characterItem.ts | 22 ++++++++ src/entities/characterType.ts | 34 ++++++++++++ src/entities/chat.ts | 21 ++++++++ src/entities/item.ts | 37 +++++++++++++ src/entities/passwordResetToken.ts | 17 ++++++ src/entities/sprite.ts | 33 ++++++++++++ src/entities/spriteAction.ts | 39 ++++++++++++++ src/entities/user.ts | 27 ++++++++++ src/entities/world.ts | 19 +++++++ src/entities/zone.ts | 15 ++++++ src/server.ts | 9 ++++ tsconfig.json | 3 +- 15 files changed, 403 insertions(+), 1 deletion(-) create mode 100644 src/entities/character.ts create mode 100644 src/entities/characterEquipment.ts create mode 100644 src/entities/characterHair.ts create mode 100644 src/entities/characterItem.ts create mode 100644 src/entities/characterType.ts create mode 100644 src/entities/chat.ts create mode 100644 src/entities/item.ts create mode 100644 src/entities/passwordResetToken.ts create mode 100644 src/entities/sprite.ts create mode 100644 src/entities/spriteAction.ts create mode 100644 src/entities/user.ts create mode 100644 src/entities/world.ts create mode 100644 src/entities/zone.ts diff --git a/src/entities/character.ts b/src/entities/character.ts new file mode 100644 index 0000000..fc0e75a --- /dev/null +++ b/src/entities/character.ts @@ -0,0 +1,84 @@ +import { Collection, Entity, ManyToOne, OneToMany, PrimaryKey, Property } from '@mikro-orm/core'; +import { User } from './user'; +import { Zone } from './zone'; +import { CharacterType } from './characterType'; +import { CharacterHair } from './characterHair'; +import { CharacterItem } from './characterItem'; +import { CharacterEquipment } from './characterEquipment'; +import { Chat } from './chat'; + +@Entity() +export class Character { + @PrimaryKey() + id!: number; + + @ManyToOne(() => User) + user!: User; + + @Property({ unique: true }) + name!: string; + + @Property() + online = false; + + @Property() + role = 'player'; + + @OneToMany(() => Chat, chat => chat.character) + chats = new Collection(this); + + // Position + @ManyToOne(() => Zone) + zone!: Zone; + + @Property() + positionX = 0; + + @Property() + positionY = 0; + + @Property() + rotation = 0; + + // Customization + @ManyToOne(() => CharacterType, { nullable: true }) + characterType?: CharacterType; + + @ManyToOne(() => CharacterHair, { nullable: true }) + characterHair?: CharacterHair; + + // Inventory + @OneToMany(() => CharacterItem, item => item.character) + items = new Collection(this); + + @OneToMany(() => CharacterEquipment, equipment => equipment.character) + equipment = new Collection(this); + + // Stats + @Property() + alignment = 50; + + @Property() + hitpoints = 100; + + @Property() + mana = 100; + + @Property() + level = 1; + + @Property() + experience = 0; + + @Property() + strength = 10; + + @Property() + dexterity = 10; + + @Property() + intelligence = 10; + + @Property() + wisdom = 10; +} \ No newline at end of file diff --git a/src/entities/characterEquipment.ts b/src/entities/characterEquipment.ts new file mode 100644 index 0000000..7dd3e58 --- /dev/null +++ b/src/entities/characterEquipment.ts @@ -0,0 +1,19 @@ +import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core'; +import { Character } from './character'; +import { CharacterItem } from './characterItem'; +import { CharacterEquipmentSlotType } from '../utilities/enums'; + +@Entity() +export class CharacterEquipment { + @PrimaryKey() + id!: number; + + @Property() + slot!: CharacterEquipmentSlotType; + + @ManyToOne(() => Character) + character!: Character; + + @ManyToOne(() => CharacterItem) + characterItem!: CharacterItem; +} \ No newline at end of file diff --git a/src/entities/characterHair.ts b/src/entities/characterHair.ts new file mode 100644 index 0000000..3a45aca --- /dev/null +++ b/src/entities/characterHair.ts @@ -0,0 +1,25 @@ +import { Collection, Entity, ManyToOne, OneToMany, PrimaryKey, Property } from '@mikro-orm/core'; +import { Character } from './character'; +import { Sprite } from './sprite'; +import { CharacterGender } from '../utilities/enums'; + +@Entity() +export class CharacterHair { + @PrimaryKey() + id!: number; + + @Property() + name!: string; + + @Property() + gender: CharacterGender = CharacterGender.MALE; + + @Property() + isSelectable = false; + + @ManyToOne(() => Sprite, { nullable: true }) + sprite?: Sprite; + + @OneToMany(() => Character, character => character.characterHair) + characters = new Collection(this); +} \ No newline at end of file diff --git a/src/entities/characterItem.ts b/src/entities/characterItem.ts new file mode 100644 index 0000000..7c772ba --- /dev/null +++ b/src/entities/characterItem.ts @@ -0,0 +1,22 @@ +import { Collection, Entity, ManyToOne, OneToMany, PrimaryKey, Property } from '@mikro-orm/core'; +import { Character } from './character'; +import { Item } from './item'; +import { CharacterEquipment } from './characterEquipment'; + +@Entity() +export class CharacterItem { + @PrimaryKey() + id!: number; + + @ManyToOne(() => Character) + character!: Character; + + @ManyToOne(() => Item) + item!: Item; + + @Property() + quantity!: number; + + @OneToMany(() => CharacterEquipment, equipment => equipment.characterItem) + characterEquipment = new Collection(this); +} \ No newline at end of file diff --git a/src/entities/characterType.ts b/src/entities/characterType.ts new file mode 100644 index 0000000..ab89ddc --- /dev/null +++ b/src/entities/characterType.ts @@ -0,0 +1,34 @@ +import { Collection, Entity, ManyToOne, OneToMany, PrimaryKey, Property } from '@mikro-orm/core'; +import { Character } from './character'; +import { Sprite } from './sprite'; +import { CharacterGender, CharacterRace } from '../utilities/enums'; + +@Entity() +export class CharacterType { + @PrimaryKey() + id!: number; + + @Property() + name!: string; + + @Property() + gender!: CharacterGender; + + @Property() + race!: CharacterRace; + + @Property() + isSelectable = false; + + @OneToMany(() => Character, character => character.characterType) + characters = new Collection(this); + + @ManyToOne(() => Sprite, { nullable: true }) + sprite?: Sprite; + + @Property() + createdAt = new Date(); + + @Property() + updatedAt = new Date(); +} \ No newline at end of file diff --git a/src/entities/chat.ts b/src/entities/chat.ts new file mode 100644 index 0000000..58e9289 --- /dev/null +++ b/src/entities/chat.ts @@ -0,0 +1,21 @@ +import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core'; +import { Character } from './character'; +import { Zone } from './zone'; + +@Entity() +export class Chat { + @PrimaryKey() + id!: number; + + @ManyToOne(() => Character) + character!: Character; + + @ManyToOne(() => Zone) + zone!: Zone; + + @Property() + message!: string; + + @Property() + createdAt = new Date(); +} \ No newline at end of file diff --git a/src/entities/item.ts b/src/entities/item.ts new file mode 100644 index 0000000..324400f --- /dev/null +++ b/src/entities/item.ts @@ -0,0 +1,37 @@ +import { Collection, Entity, ManyToOne, OneToMany, PrimaryKey, Property } from '@mikro-orm/core'; +import { Sprite } from './sprite'; +import { CharacterItem } from './characterItem'; +import { ItemType, ItemRarity } from '../utilities/enums'; + +@Entity() +export class Item { + @PrimaryKey() + id!: string; + + @Property() + name!: string; + + @Property({ nullable: true }) + description?: string; + + @Property() + itemType!: ItemType; + + @Property() + stackable = false; + + @Property() + rarity: ItemRarity = ItemRarity.COMMON; + + @ManyToOne(() => Sprite, { nullable: true }) + sprite?: Sprite; + + @Property() + createdAt = new Date(); + + @Property() + updatedAt = new Date(); + + @OneToMany(() => CharacterItem, characterItem => characterItem.item) + characters = new Collection(this); +} \ No newline at end of file diff --git a/src/entities/passwordResetToken.ts b/src/entities/passwordResetToken.ts new file mode 100644 index 0000000..1149d0a --- /dev/null +++ b/src/entities/passwordResetToken.ts @@ -0,0 +1,17 @@ +import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core'; +import { User } from './user'; + +@Entity() +export class PasswordResetToken { + @PrimaryKey() + id!: number; + + @ManyToOne(() => User) + user!: User; + + @Property({ unique: true }) + token!: string; + + @Property() + createdAt = new Date(); +} \ No newline at end of file diff --git a/src/entities/sprite.ts b/src/entities/sprite.ts new file mode 100644 index 0000000..0d1988c --- /dev/null +++ b/src/entities/sprite.ts @@ -0,0 +1,33 @@ +import { randomUUID } from 'node:crypto'; +import { Collection, Entity, OneToMany, PrimaryKey, Property } from '@mikro-orm/core'; +import { SpriteAction } from './spriteAction'; +import { CharacterType } from './characterType'; +import { CharacterHair } from './characterHair'; +import { Item } from './item'; + +@Entity() +export class Sprite { + @PrimaryKey() + id = randomUUID(); + + @Property() + name!: string; + + @Property() + createdAt = new Date(); + + @Property() + updatedAt = new Date(); + + @OneToMany(() => SpriteAction, action => action.sprite) + spriteActions = new Collection(this); + + @OneToMany(() => CharacterType, type => type.sprite) + characterTypes = new Collection(this); + + @OneToMany(() => CharacterHair, hair => hair.sprite) + characterHairs = new Collection(this); + + @OneToMany(() => Item, item => item.sprite) + items = new Collection(this); +} \ No newline at end of file diff --git a/src/entities/spriteAction.ts b/src/entities/spriteAction.ts new file mode 100644 index 0000000..5c8c86b --- /dev/null +++ b/src/entities/spriteAction.ts @@ -0,0 +1,39 @@ +import { randomUUID } from 'node:crypto' +import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core'; +import { Sprite } from './sprite'; + +@Entity() +export class SpriteAction { + @PrimaryKey() + id = randomUUID(); + + @ManyToOne(() => Sprite) + sprite!: Sprite; + + @Property() + action!: string; + + @Property({ type: 'json', nullable: true }) + sprites?: any; + + @Property() + originX = 0; + + @Property() + originY = 0; + + @Property() + isAnimated = false; + + @Property() + isLooping = false; + + @Property() + frameWidth = 0; + + @Property() + frameHeight = 0; + + @Property() + frameRate = 0; +} \ No newline at end of file diff --git a/src/entities/user.ts b/src/entities/user.ts new file mode 100644 index 0000000..9691400 --- /dev/null +++ b/src/entities/user.ts @@ -0,0 +1,27 @@ +import { Collection, Entity, OneToMany, PrimaryKey, Property } from '@mikro-orm/core'; +import { Character } from './character'; +import { PasswordResetToken } from './passwordResetToken'; + +@Entity() +export class User { + @PrimaryKey() + id!: number; + + @Property({ unique: true }) + username!: string; + + @Property({ unique: true }) + email!: string; + + @Property() + password!: string; + + @Property() + online = false; + + @OneToMany(() => Character, character => character.user) + characters = new Collection(this); + + @OneToMany(() => PasswordResetToken, token => token.user) + passwordResetTokens = new Collection(this); +} \ No newline at end of file diff --git a/src/entities/world.ts b/src/entities/world.ts new file mode 100644 index 0000000..265b08d --- /dev/null +++ b/src/entities/world.ts @@ -0,0 +1,19 @@ +import { Entity, PrimaryKey, Property } from '@mikro-orm/core'; + +@Entity() +export class World { + @PrimaryKey() + date = new Date(); + + @Property() + isRainEnabled = false; + + @Property() + rainPercentage = 0; + + @Property() + isFogEnabled = false; + + @Property() + fogDensity = 0; +} \ No newline at end of file diff --git a/src/entities/zone.ts b/src/entities/zone.ts new file mode 100644 index 0000000..7a43385 --- /dev/null +++ b/src/entities/zone.ts @@ -0,0 +1,15 @@ +import { Collection, Entity, OneToMany, PrimaryKey, Property } from '@mikro-orm/core'; +import { Character } from './character'; +import { Chat } from './chat'; + +@Entity() +export class Zone { + @PrimaryKey() + id!: number; + + @OneToMany(() => Character, character => character.zone) + characters = new Collection(this); + + @OneToMany(() => Chat, chat => chat.zone) + chats = new Collection(this); +} \ No newline at end of file diff --git a/src/server.ts b/src/server.ts index 8354301..db95433 100644 --- a/src/server.ts +++ b/src/server.ts @@ -8,6 +8,7 @@ import cors from 'cors' import { Server as SocketServer } from 'socket.io' import { Authentication } from './middleware/authentication' import { TSocket } from './utilities/types' +import { MikroORM } from '@mikro-orm/mariadb' import prisma from './utilities/prisma' import { appLogger, watchLogs } from './utilities/logger' import ZoneManager from './managers/zoneManager' @@ -57,6 +58,14 @@ export class Server { appLogger.error(`Database connection failed: ${error.message}`) } + // MikroORM + try { + const orm = await MikroORM.init(); + appLogger.info('Database 2 connected') + } catch (error: any) { + appLogger.error(`Database 2 connection failed: ${error.message}`) + } + // Start the server try { this.http.listen(config.PORT, config.HOST) diff --git a/tsconfig.json b/tsconfig.json index 6baea3d..e022d97 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,8 @@ // Enable latest features "lib": ["ESNext"], "target": "ESNext", - "module": "ESNext", + "module": "NodeNext", + "moduleResolution": "NodeNext", "moduleDetection": "force", "allowJs": true, "declaration": true,