forked from noxious/server
Improved folder and file structure, separated prisma schema into multiple ones, removed obsolete functions, worked on dynamic character sprite logics, general enhancements
This commit is contained in:
parent
7531385912
commit
4b81d7ff67
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- Added the required column `characterTypeId` to the `Character` table without a default value. This is not possible if the table is not empty.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE `Character` ADD COLUMN `characterTypeId` INTEGER NOT NULL;
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE `Sprite` ADD COLUMN `isAnimated` BOOLEAN NOT NULL DEFAULT false;
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE `CharacterSprite` (
|
||||||
|
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||||
|
`characterTypeId` INTEGER NOT NULL,
|
||||||
|
`spriteId` VARCHAR(191) NOT NULL,
|
||||||
|
`action` ENUM('IDLE_LEFT', 'IDLE_DOWN', 'SIT_LEFT', 'SIT_DOWN', 'WALK_LEFT', 'WALK_DOWN', 'ATTACK_LEFT', 'ATTACK_DOWN') NOT NULL,
|
||||||
|
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE `CharacterType` (
|
||||||
|
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||||
|
`name` VARCHAR(191) NOT NULL,
|
||||||
|
`gender` ENUM('MALE', 'FEMALE') NOT NULL,
|
||||||
|
`race` ENUM('HUMAN', 'ELF', 'DWARF', 'ORC', 'GOBLIN') NOT NULL,
|
||||||
|
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||||
|
`updatedAt` DATETIME(3) NOT NULL,
|
||||||
|
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE `CharacterSprite` ADD CONSTRAINT `CharacterSprite_characterTypeId_fkey` FOREIGN KEY (`characterTypeId`) REFERENCES `CharacterType`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE `CharacterSprite` ADD CONSTRAINT `CharacterSprite_spriteId_fkey` FOREIGN KEY (`spriteId`) REFERENCES `Sprite`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE `Character` ADD CONSTRAINT `Character_characterTypeId_fkey` FOREIGN KEY (`characterTypeId`) REFERENCES `CharacterType`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE `Character` MODIFY `characterTypeId` INTEGER NULL;
|
@ -1,153 +0,0 @@
|
|||||||
// CHEAT SHEET
|
|
||||||
// 1. Create a new Prisma project
|
|
||||||
// npx prisma init
|
|
||||||
// 2. Create a new database schema
|
|
||||||
// npx prisma db push
|
|
||||||
// 3. Generate Prisma Client and type-safe models based on schema
|
|
||||||
// npx prisma generate
|
|
||||||
// 4. Create a new migration
|
|
||||||
// npx prisma migrate dev --name [migration-name]
|
|
||||||
// 5. Apply the migration
|
|
||||||
// npx prisma migrate deploy
|
|
||||||
|
|
||||||
generator client {
|
|
||||||
provider = "prisma-client-js"
|
|
||||||
}
|
|
||||||
|
|
||||||
datasource db {
|
|
||||||
provider = "mysql"
|
|
||||||
url = env("DATABASE_URL")
|
|
||||||
}
|
|
||||||
|
|
||||||
model Sprite {
|
|
||||||
id String @id @default(uuid())
|
|
||||||
name String
|
|
||||||
origin_x Decimal @default(0)
|
|
||||||
origin_y Decimal @default(0)
|
|
||||||
frameSpeed Int @default(0)
|
|
||||||
frameWidth Int @default(0)
|
|
||||||
frameHeight Int @default(0)
|
|
||||||
isLooping Boolean @default(false)
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @updatedAt
|
|
||||||
}
|
|
||||||
|
|
||||||
model Tile {
|
|
||||||
id String @id @default(uuid())
|
|
||||||
name String
|
|
||||||
tags Json?
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @updatedAt
|
|
||||||
}
|
|
||||||
|
|
||||||
model Object {
|
|
||||||
id String @id @default(uuid())
|
|
||||||
name String
|
|
||||||
tags Json?
|
|
||||||
origin_x Decimal @default(0)
|
|
||||||
origin_y Decimal @default(0)
|
|
||||||
isAnimated Boolean @default(false)
|
|
||||||
frameSpeed Int @default(0)
|
|
||||||
frameWidth Int @default(0)
|
|
||||||
frameHeight Int @default(0)
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @updatedAt
|
|
||||||
ZoneObject ZoneObject[]
|
|
||||||
}
|
|
||||||
|
|
||||||
model Item {
|
|
||||||
id String @id @default(uuid())
|
|
||||||
name String
|
|
||||||
description String?
|
|
||||||
stackable Boolean @default(false)
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @updatedAt
|
|
||||||
characters CharacterItem[]
|
|
||||||
}
|
|
||||||
|
|
||||||
model User {
|
|
||||||
id Int @id @default(autoincrement())
|
|
||||||
username String @unique
|
|
||||||
password String
|
|
||||||
characters Character[]
|
|
||||||
}
|
|
||||||
|
|
||||||
model Character {
|
|
||||||
id Int @id @default(autoincrement())
|
|
||||||
userId Int
|
|
||||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
||||||
name String @unique
|
|
||||||
hitpoints Int @default(100)
|
|
||||||
mana Int @default(100)
|
|
||||||
level Int @default(1)
|
|
||||||
experience Int @default(0)
|
|
||||||
role String @default("player")
|
|
||||||
position_x Int @default(0)
|
|
||||||
position_y Int @default(0)
|
|
||||||
rotation Int @default(0)
|
|
||||||
zoneId Int @default(1)
|
|
||||||
zone Zone @relation(fields: [zoneId], references: [id], onDelete: Cascade)
|
|
||||||
chats Chat[]
|
|
||||||
items CharacterItem[]
|
|
||||||
}
|
|
||||||
|
|
||||||
model CharacterItem {
|
|
||||||
id Int @id @default(autoincrement())
|
|
||||||
characterId Int
|
|
||||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
|
||||||
itemId String
|
|
||||||
item Item @relation(fields: [itemId], references: [id], onDelete: Cascade)
|
|
||||||
quantity Int
|
|
||||||
}
|
|
||||||
|
|
||||||
model Zone {
|
|
||||||
id Int @id @default(autoincrement())
|
|
||||||
name String
|
|
||||||
width Int @default(10)
|
|
||||||
height Int @default(10)
|
|
||||||
tiles Json?
|
|
||||||
pvp Boolean @default(false)
|
|
||||||
zoneEventTiles ZoneEventTile[]
|
|
||||||
zoneObjects ZoneObject[]
|
|
||||||
characters Character[]
|
|
||||||
chats Chat[]
|
|
||||||
createdAt DateTime @default(now())
|
|
||||||
updatedAt DateTime @updatedAt
|
|
||||||
}
|
|
||||||
|
|
||||||
model ZoneObject {
|
|
||||||
id String @id @default(uuid())
|
|
||||||
zoneId Int
|
|
||||||
zone Zone @relation(fields: [zoneId], references: [id], onDelete: Cascade)
|
|
||||||
objectId String
|
|
||||||
object Object @relation(fields: [objectId], references: [id], onDelete: Cascade)
|
|
||||||
depth Int @default(0)
|
|
||||||
position_x Int @default(0)
|
|
||||||
position_y Int @default(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ZoneEventTileType {
|
|
||||||
BLOCK
|
|
||||||
WARP
|
|
||||||
NPC
|
|
||||||
ITEM
|
|
||||||
}
|
|
||||||
|
|
||||||
model ZoneEventTile {
|
|
||||||
id String @id @default(uuid())
|
|
||||||
zoneId Int
|
|
||||||
zone Zone @relation(fields: [zoneId], references: [id], onDelete: Cascade)
|
|
||||||
type ZoneEventTileType
|
|
||||||
position_x Int
|
|
||||||
position_y Int
|
|
||||||
}
|
|
||||||
|
|
||||||
model Chat {
|
|
||||||
id Int @id @default(autoincrement())
|
|
||||||
characterId Int
|
|
||||||
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
|
||||||
zoneId Int
|
|
||||||
zone Zone @relation(fields: [zoneId], references: [id], onDelete: Cascade)
|
|
||||||
message String
|
|
||||||
createdAt DateTime
|
|
||||||
}
|
|
31
prisma/schema/schema.prisma
Normal file
31
prisma/schema/schema.prisma
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// CHEAT SHEET
|
||||||
|
// 1. Create a new Prisma project
|
||||||
|
// npx prisma init
|
||||||
|
// 2. Create a new database schema
|
||||||
|
// npx prisma db push
|
||||||
|
// 3. Generate Prisma Client and type-safe models based on schema
|
||||||
|
// npx prisma generate
|
||||||
|
// 4. Create a new migration
|
||||||
|
// npx prisma migrate dev --name [migration-name]
|
||||||
|
// 5. Apply the migration
|
||||||
|
// npx prisma migrate deploy
|
||||||
|
|
||||||
|
generator client {
|
||||||
|
provider = "prisma-client-js"
|
||||||
|
previewFeatures = ["prismaSchemaFolder"]
|
||||||
|
}
|
||||||
|
|
||||||
|
datasource db {
|
||||||
|
provider = "mysql"
|
||||||
|
url = env("DATABASE_URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Chat {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
characterId Int
|
||||||
|
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||||
|
zoneId Int
|
||||||
|
zone Zone @relation(fields: [zoneId], references: [id], onDelete: Cascade)
|
||||||
|
message String
|
||||||
|
createdAt DateTime
|
||||||
|
}
|
34
prisma/schema/sprite.prisma
Normal file
34
prisma/schema/sprite.prisma
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
model Sprite {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
name String
|
||||||
|
origin_x Decimal @default(0)
|
||||||
|
origin_y Decimal @default(0)
|
||||||
|
isAnimated Boolean @default(false)
|
||||||
|
frameSpeed Int @default(0)
|
||||||
|
frameWidth Int @default(0)
|
||||||
|
frameHeight Int @default(0)
|
||||||
|
isLooping Boolean @default(false)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
characterSprites CharacterSprite[]
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SpriteAction {
|
||||||
|
IDLE_LEFT
|
||||||
|
IDLE_DOWN
|
||||||
|
SIT_LEFT
|
||||||
|
SIT_DOWN
|
||||||
|
WALK_LEFT
|
||||||
|
WALK_DOWN
|
||||||
|
ATTACK_LEFT
|
||||||
|
ATTACK_DOWN
|
||||||
|
}
|
||||||
|
|
||||||
|
model CharacterSprite {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
characterTypeId Int
|
||||||
|
spriteId String
|
||||||
|
action SpriteAction
|
||||||
|
characterType CharacterType @relation(fields: [characterTypeId], references: [id], onDelete: Cascade)
|
||||||
|
sprite Sprite @relation(fields: [spriteId], references: [id], onDelete: Cascade)
|
||||||
|
}
|
60
prisma/schema/user.prisma
Normal file
60
prisma/schema/user.prisma
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
model User {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
username String @unique
|
||||||
|
password String
|
||||||
|
characters Character[]
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CharacterGender {
|
||||||
|
MALE
|
||||||
|
FEMALE
|
||||||
|
}
|
||||||
|
|
||||||
|
enum CharacterRace {
|
||||||
|
HUMAN
|
||||||
|
ELF
|
||||||
|
DWARF
|
||||||
|
ORC
|
||||||
|
GOBLIN
|
||||||
|
}
|
||||||
|
|
||||||
|
model CharacterType {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
name String
|
||||||
|
gender CharacterGender
|
||||||
|
race CharacterRace
|
||||||
|
characters Character[]
|
||||||
|
characterSprites CharacterSprite[]
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model Character {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
userId Int
|
||||||
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
|
name String @unique
|
||||||
|
hitpoints Int @default(100)
|
||||||
|
mana Int @default(100)
|
||||||
|
level Int @default(1)
|
||||||
|
experience Int @default(0)
|
||||||
|
role String @default("player")
|
||||||
|
position_x Int @default(0)
|
||||||
|
position_y Int @default(0)
|
||||||
|
rotation Int @default(0)
|
||||||
|
zoneId Int @default(1)
|
||||||
|
zone Zone @relation(fields: [zoneId], references: [id], onDelete: Cascade)
|
||||||
|
characterTypeId Int?
|
||||||
|
characterType CharacterType? @relation(fields: [characterTypeId], references: [id], onDelete: Cascade)
|
||||||
|
chats Chat[]
|
||||||
|
items CharacterItem[]
|
||||||
|
}
|
||||||
|
|
||||||
|
model CharacterItem {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
characterId Int
|
||||||
|
character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)
|
||||||
|
itemId String
|
||||||
|
item Item @relation(fields: [itemId], references: [id], onDelete: Cascade)
|
||||||
|
quantity Int
|
||||||
|
}
|
74
prisma/schema/zone.prisma
Normal file
74
prisma/schema/zone.prisma
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
model Tile {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
name String
|
||||||
|
tags Json?
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model Object {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
name String
|
||||||
|
tags Json?
|
||||||
|
origin_x Decimal @default(0)
|
||||||
|
origin_y Decimal @default(0)
|
||||||
|
isAnimated Boolean @default(false)
|
||||||
|
frameSpeed Int @default(0)
|
||||||
|
frameWidth Int @default(0)
|
||||||
|
frameHeight Int @default(0)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
ZoneObject ZoneObject[]
|
||||||
|
}
|
||||||
|
|
||||||
|
model Item {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
name String
|
||||||
|
description String?
|
||||||
|
stackable Boolean @default(false)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
characters CharacterItem[]
|
||||||
|
}
|
||||||
|
|
||||||
|
model Zone {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
name String
|
||||||
|
width Int @default(10)
|
||||||
|
height Int @default(10)
|
||||||
|
tiles Json?
|
||||||
|
pvp Boolean @default(false)
|
||||||
|
zoneEventTiles ZoneEventTile[]
|
||||||
|
zoneObjects ZoneObject[]
|
||||||
|
characters Character[]
|
||||||
|
chats Chat[]
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
model ZoneObject {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
zoneId Int
|
||||||
|
zone Zone @relation(fields: [zoneId], references: [id], onDelete: Cascade)
|
||||||
|
objectId String
|
||||||
|
object Object @relation(fields: [objectId], references: [id], onDelete: Cascade)
|
||||||
|
depth Int @default(0)
|
||||||
|
position_x Int @default(0)
|
||||||
|
position_y Int @default(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ZoneEventTileType {
|
||||||
|
BLOCK
|
||||||
|
WARP
|
||||||
|
NPC
|
||||||
|
ITEM
|
||||||
|
}
|
||||||
|
|
||||||
|
model ZoneEventTile {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
zoneId Int
|
||||||
|
zone Zone @relation(fields: [zoneId], references: [id], onDelete: Cascade)
|
||||||
|
type ZoneEventTileType
|
||||||
|
position_x Int
|
||||||
|
position_y Int
|
||||||
|
}
|
@ -29,7 +29,8 @@ export default function (socket: TSocket, io: Server) {
|
|||||||
const character: Character = await prisma.character.create({
|
const character: Character = await prisma.character.create({
|
||||||
data: {
|
data: {
|
||||||
name: data.name,
|
name: data.name,
|
||||||
userId: user_id
|
userId: user_id,
|
||||||
|
// characterTypeId: 1 // @TODO set to chosen character type
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -38,7 +39,8 @@ export default function (socket: TSocket, io: Server) {
|
|||||||
socket.emit('character:create:success')
|
socket.emit('character:create:success')
|
||||||
socket.emit('character:list', characters)
|
socket.emit('character:list', characters)
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
return socket.emit('notification', { message: error.errors[0]?.message ?? 'Invalid data' })
|
console.log('character:create error', error)
|
||||||
|
return socket.emit('notification', { message: 'Could not create character. Please try again (later).' })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import { Server } from 'socket.io'
|
import { Server } from 'socket.io'
|
||||||
import { TSocket } from '../../../utilities/Types'
|
import { TSocket } from '../../../utilities/Types'
|
||||||
import path from 'path'
|
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
import path from 'path'
|
||||||
import prisma from '../../../utilities/Prisma'
|
import prisma from '../../../utilities/Prisma'
|
||||||
|
|
||||||
type Payload = {
|
type Payload = {
|
||||||
|
@ -42,7 +42,7 @@ export default function (socket: TSocket, io: Server) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(data);
|
console.log(data)
|
||||||
|
|
||||||
await prisma.zone.update({
|
await prisma.zone.update({
|
||||||
where: {
|
where: {
|
||||||
|
@ -45,25 +45,6 @@ class CharacterRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(userId: number, name: string, role: 'player'): Promise<Character | null> {
|
|
||||||
try {
|
|
||||||
return await prisma.character.create({
|
|
||||||
data: {
|
|
||||||
userId,
|
|
||||||
name,
|
|
||||||
role,
|
|
||||||
position_x: 0, // @TODO Set default registration values in the database
|
|
||||||
position_y: 0, // @TODO Set default registration values in the database
|
|
||||||
rotation: 0, // @TODO Set default registration values in the database
|
|
||||||
zoneId: 1 // @TODO Set default registration values in the database
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} catch (error: any) {
|
|
||||||
// Handle error
|
|
||||||
throw new Error(`Failed to create character: ${error.message}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async updatePosition(id: number, position_x: number, position_y: number): Promise<Character | null> {
|
async updatePosition(id: number, position_x: number, position_y: number): Promise<Character | null> {
|
||||||
try {
|
try {
|
||||||
return await prisma.character.update({
|
return await prisma.character.update({
|
||||||
@ -81,19 +62,6 @@ class CharacterRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(id: number): Promise<Character | null> {
|
|
||||||
try {
|
|
||||||
return await prisma.character.delete({
|
|
||||||
where: {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} catch (error: any) {
|
|
||||||
// Handle error
|
|
||||||
throw new Error(`Failed to delete character: ${error.message}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async deleteByUserIdAndId(userId: number, characterId: number): Promise<Character | null> {
|
async deleteByUserIdAndId(userId: number, characterId: number): Promise<Character | null> {
|
||||||
try {
|
try {
|
||||||
return await prisma.character.delete({
|
return await prisma.character.delete({
|
||||||
|
Loading…
x
Reference in New Issue
Block a user