From b19625014a128cb853c120568f93c05bcdb64fdf Mon Sep 17 00:00:00 2001
From: Dennis Postma <dennis@directonline.io>
Date: Fri, 31 May 2024 01:15:54 +0200
Subject: [PATCH] npm update, removed player store and merged it with socket
 store, worked on character creation & selection (partially works)

---
 package-lock.json                             | 12 ++---
 .../migration.sql                             | 24 ++++++++-
 prisma/schema.prisma                          | 51 ++++++++++++-------
 src/app/events/CharacterConnect.ts            | 16 +++++-
 src/app/events/Login.ts                       |  8 +--
 src/app/repositories/CharacterRepository.ts   | 13 +++++
 src/app/types/TSocket.ts                      |  3 +-
 7 files changed, 97 insertions(+), 30 deletions(-)
 rename prisma/migrations/{20240512163859_init => 20240530223506_init}/migration.sql (59%)

diff --git a/package-lock.json b/package-lock.json
index 4844d1a..8c0c7aa 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -213,9 +213,9 @@
       }
     },
     "node_modules/@types/express-serve-static-core": {
-      "version": "4.19.1",
-      "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.1.tgz",
-      "integrity": "sha512-ej0phymbFLoCB26dbbq5PGScsf2JAJ4IJHjG10LalgUV36XKTmA4GdA+PVllKvRk0sEKt64X8975qFnkSi0hqA==",
+      "version": "4.19.3",
+      "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.3.tgz",
+      "integrity": "sha512-KOzM7MhcBFlmnlr/fzISFF5vGWVSvN6fTd4T+ExOt08bA/dA5kpSzY52nMsI1KDFmUREpJelPYyuslLRSjjgCg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -250,9 +250,9 @@
       "license": "MIT"
     },
     "node_modules/@types/node": {
-      "version": "20.12.12",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz",
-      "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==",
+      "version": "20.12.13",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.13.tgz",
+      "integrity": "sha512-gBGeanV41c1L171rR7wjbMiEpEI/l5XFQdLLfhr/REwpgDy/4U8y89+i8kRiLzDyZdOkXh+cRaTetUnCYutoXA==",
       "license": "MIT",
       "dependencies": {
         "undici-types": "~5.26.4"
diff --git a/prisma/migrations/20240512163859_init/migration.sql b/prisma/migrations/20240530223506_init/migration.sql
similarity index 59%
rename from prisma/migrations/20240512163859_init/migration.sql
rename to prisma/migrations/20240530223506_init/migration.sql
index f5b3316..da9eb3d 100644
--- a/prisma/migrations/20240512163859_init/migration.sql
+++ b/prisma/migrations/20240530223506_init/migration.sql
@@ -11,11 +11,16 @@ CREATE TABLE `User` (
 -- CreateTable
 CREATE TABLE `Character` (
     `id` INTEGER NOT NULL AUTO_INCREMENT,
+    `userId` INTEGER NOT NULL,
     `name` VARCHAR(191) NOT NULL,
+    `hitpoints` INTEGER NOT NULL DEFAULT 100,
+    `mana` INTEGER NOT NULL DEFAULT 100,
+    `level` INTEGER NOT NULL DEFAULT 1,
+    `experience` INTEGER NOT NULL DEFAULT 0,
+    `role` VARCHAR(191) NOT NULL DEFAULT 'player',
     `position_x` INTEGER NOT NULL,
     `position_y` INTEGER NOT NULL,
     `rotation` INTEGER NOT NULL,
-    `userId` INTEGER NOT NULL,
     `zoneId` INTEGER NOT NULL,
 
     PRIMARY KEY (`id`)
@@ -32,8 +37,25 @@ CREATE TABLE `Zone` (
     PRIMARY KEY (`id`)
 ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
 
+-- CreateTable
+CREATE TABLE `Chat` (
+    `id` INTEGER NOT NULL AUTO_INCREMENT,
+    `characterId` INTEGER NOT NULL,
+    `zoneId` INTEGER NOT NULL,
+    `message` VARCHAR(191) NOT NULL,
+    `createdAt` DATETIME(3) NOT NULL,
+
+    PRIMARY KEY (`id`)
+) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+
 -- AddForeignKey
 ALTER TABLE `Character` ADD CONSTRAINT `Character_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
 
 -- AddForeignKey
 ALTER TABLE `Character` ADD CONSTRAINT `Character_zoneId_fkey` FOREIGN KEY (`zoneId`) REFERENCES `Zone`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE `Chat` ADD CONSTRAINT `Chat_characterId_fkey` FOREIGN KEY (`characterId`) REFERENCES `Character`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE `Chat` ADD CONSTRAINT `Chat_zoneId_fkey` FOREIGN KEY (`zoneId`) REFERENCES `Zone`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index a42cb02..a12a3cf 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -20,29 +20,46 @@ datasource db {
 }
 
 model User {
-  id       Int     @id @default(autoincrement())
-  username String  @unique
-  password String
+  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])
-  name     String
+  id         Int    @id @default(autoincrement())
+  userId     Int
+  user       User   @relation(fields: [userId], references: [id])
+  name       String
+  hitpoints  Int    @default(100)
+  mana       Int    @default(100)
+  level      Int    @default(1)
+  experience Int    @default(0)
+  role       String @default("player")
   position_x Int
   position_y Int
-  rotation Int
-  zoneId    Int
-  zone      Zone    @relation(fields: [zoneId], references: [id])
+  rotation   Int
+  zoneId     Int
+  zone       Zone   @relation(fields: [zoneId], references: [id])
+  chats      Chat[]
 }
 
 model Zone {
-  id          Int     @id @default(autoincrement())
-  name        String
-  width       Int
-  height      Int
-  tiles       Json
-  characters  Character[]
-}
\ No newline at end of file
+  id         Int         @id @default(autoincrement())
+  name       String
+  width      Int
+  height     Int
+  tiles      Json
+  characters Character[]
+  chats      Chat[]
+}
+
+model Chat {
+  id          Int       @id @default(autoincrement())
+  characterId Int
+  character   Character @relation(fields: [characterId], references: [id])
+  zoneId      Int
+  zone        Zone      @relation(fields: [zoneId], references: [id])
+  message     String
+  createdAt   DateTime
+}
diff --git a/src/app/events/CharacterConnect.ts b/src/app/events/CharacterConnect.ts
index f005674..b89b735 100644
--- a/src/app/events/CharacterConnect.ts
+++ b/src/app/events/CharacterConnect.ts
@@ -1,8 +1,20 @@
 import { Socket, Server } from "socket.io";
 import {TSocket} from "../types/TSocket";
+import CharacterRepository from "../repositories/CharacterRepository";
+import {Character} from "@prisma/client";
+
+type SocketResponseT = {
+    character_id: number
+}
 
 export default function CharacterConnect(socket: TSocket, io: Server) {
-    socket.on('character:connect', (data: any) => {
-        console.log(`---User ${socket.user?.id} has joined.`);
+    socket.on('character:connect', async (data: SocketResponseT) => {
+        try {
+            console.log('character:connect', data.character_id);
+            socket.character = await CharacterRepository.getById(data.character_id) as Character;
+            socket.emit('character:connect', socket.character)
+        } catch (error: any) {
+            console.log('character:connect error', error);
+        }
     });
 }
\ No newline at end of file
diff --git a/src/app/events/Login.ts b/src/app/events/Login.ts
index 1edc23e..9e7f4dc 100644
--- a/src/app/events/Login.ts
+++ b/src/app/events/Login.ts
@@ -1,7 +1,9 @@
 import { Socket, Server } from "socket.io";
+import {TSocket} from "../types/TSocket";
 
-export default function Login(socket: Socket, io: Server) {
-    socket.on('login', (data: any) => {
-        console.log(`---User ${socket.id} has logged in.`);
+export default function Login(socket: TSocket, io: Server) {
+    socket.on('login', () => {
+        // return user data
+        socket.emit('login', {user: socket.user});
     });
 }
\ No newline at end of file
diff --git a/src/app/repositories/CharacterRepository.ts b/src/app/repositories/CharacterRepository.ts
index 074dc3f..643ae09 100644
--- a/src/app/repositories/CharacterRepository.ts
+++ b/src/app/repositories/CharacterRepository.ts
@@ -16,6 +16,19 @@ class CharacterRepository {
         }
     }
 
+    async getById(id: number): Promise<Character | null> {
+        try {
+            return await prisma.character.findUnique({
+                where: {
+                    id,
+                },
+            });
+        } catch (error: any) {
+            // Handle error
+            throw new Error(`Failed to get character by ID: ${error.message}`);
+        }
+    }
+
     async create(userId: number, name: string): Promise<Character | null> {
         try {
             return await prisma.character.create({
diff --git a/src/app/types/TSocket.ts b/src/app/types/TSocket.ts
index 8a4e8d8..8d85275 100644
--- a/src/app/types/TSocket.ts
+++ b/src/app/types/TSocket.ts
@@ -1,8 +1,9 @@
 import {Socket} from "socket.io";
-import { User } from '@prisma/client';
+import {Character, User} from '@prisma/client';
 
 export type TSocket = Socket & {
     user?: User
+    character?: Character
     handshake?: {
         query?: {
             token?: any