From a64506d3eece8ee4a498ea4f816afd613ea3bc09 Mon Sep 17 00:00:00 2001 From: Dennis Postma Date: Sun, 8 Sep 2024 03:14:55 +0200 Subject: [PATCH] Added online column to user and char. models, updated send chat message event to new format, removed unused code, fixed typo, replaced console.log()'s with logger --- .../migration.sql | 2 + prisma/schema/user.prisma | 26 ++++++----- src/events/chat/sendMessage.ts | 45 ++++++++++++++----- src/middleware/authentication.ts | 7 +-- .../character/characterMoveService.ts | 19 ++------ 5 files changed, 56 insertions(+), 43 deletions(-) rename prisma/migrations/{20240822164618_init => 20240907234541_init}/migration.sql (98%) diff --git a/prisma/migrations/20240822164618_init/migration.sql b/prisma/migrations/20240907234541_init/migration.sql similarity index 98% rename from prisma/migrations/20240822164618_init/migration.sql rename to prisma/migrations/20240907234541_init/migration.sql index d62640e..6e857f1 100644 --- a/prisma/migrations/20240822164618_init/migration.sql +++ b/prisma/migrations/20240907234541_init/migration.sql @@ -41,6 +41,7 @@ CREATE TABLE `User` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `username` VARCHAR(191) NOT NULL, `password` VARCHAR(191) NOT NULL, + `online` BOOLEAN NOT NULL DEFAULT false, UNIQUE INDEX `User_username_key`(`username`), PRIMARY KEY (`id`) @@ -64,6 +65,7 @@ CREATE TABLE `Character` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `userId` INTEGER NOT NULL, `name` VARCHAR(191) NOT NULL, + `online` BOOLEAN NOT NULL DEFAULT false, `hitpoints` INTEGER NOT NULL DEFAULT 100, `mana` INTEGER NOT NULL DEFAULT 100, `level` INTEGER NOT NULL DEFAULT 1, diff --git a/prisma/schema/user.prisma b/prisma/schema/user.prisma index 90e90be..1c007b2 100644 --- a/prisma/schema/user.prisma +++ b/prisma/schema/user.prisma @@ -2,6 +2,7 @@ model User { id Int @id @default(autoincrement()) username String @unique password String + online Boolean @default(false) characters Character[] } @@ -19,15 +20,15 @@ enum CharacterRace { } model CharacterType { - id Int @id @default(autoincrement()) - name String - gender CharacterGender - race CharacterRace - characters Character[] - spriteId String - sprite Sprite @relation(fields: [spriteId], references: [id], onDelete: Cascade) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt + id Int @id @default(autoincrement()) + name String + gender CharacterGender + race CharacterRace + characters Character[] + spriteId String + sprite Sprite @relation(fields: [spriteId], references: [id], onDelete: Cascade) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt } model Character { @@ -35,19 +36,20 @@ model Character { userId Int user User @relation(fields: [userId], references: [id], onDelete: Cascade) name String @unique + online Boolean @default(false) hitpoints Int @default(100) mana Int @default(100) level Int @default(1) experience Int @default(0) alignment Int @default(50) role String @default("player") - positionX Int @default(0) - positionY Int @default(0) + positionX Int @default(0) + positionY 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) + characterType CharacterType? @relation(fields: [characterTypeId], references: [id], onDelete: Cascade) chats Chat[] items CharacterItem[] } diff --git a/src/events/chat/sendMessage.ts b/src/events/chat/sendMessage.ts index 05601a8..0288439 100644 --- a/src/events/chat/sendMessage.ts +++ b/src/events/chat/sendMessage.ts @@ -3,31 +3,52 @@ import { TSocket } from '../../utilities/types' import CharacterRepository from '../../repositories/characterRepository' import ZoneRepository from '../../repositories/zoneRepository' import { isCommand } from '../../utilities/chat' +import logger from '../../utilities/logger' type TypePayload = { message: string } -export default function (socket: TSocket, io: Server) { - socket.on('chat:send_message', async (data: TypePayload, callback: (response: boolean) => void) => { - try { - if (!data.message) return - if (isCommand(data.message)) return +export default class ChatMessageEvent { + constructor( + private readonly io: Server, + private readonly socket: TSocket + ) {} - const character = await CharacterRepository.getByUserAndId(socket.user?.id as number, socket.character?.id as number) - if (!character) return + public listen(): void { + this.socket.on('chat:send_message', this.handleChatMessage.bind(this)) + } + + private async handleChatMessage(data: TypePayload, callback: (response: boolean) => void): Promise { + try { + if (!data.message || isCommand(data.message)) { + callback(false) + return + } + + const character = await CharacterRepository.getByUserAndId(this.socket.user?.id as number, this.socket.character?.id as number) + if (!character) { + logger.error('chat:send_message error', 'Character not found') + callback(false) + return + } const zone = await ZoneRepository.getById(character.zoneId) - if (!zone) return + if (!zone) { + logger.error('chat:send_message error', 'Zone not found') + callback(false) + return + } callback(true) - io.to(zone.id.toString()).emit('chat:message', { + this.io.to(zone.id.toString()).emit('chat:message', { character: character, message: data.message }) } catch (error: any) { - console.log(`---Error sending message: ${error.message}`) + logger.error('chat:send_message error', error.message) + callback(false) } - }) -} + } +} \ No newline at end of file diff --git a/src/middleware/authentication.ts b/src/middleware/authentication.ts index e3df21c..9744d5f 100644 --- a/src/middleware/authentication.ts +++ b/src/middleware/authentication.ts @@ -3,6 +3,7 @@ import { TSocket } from '../utilities/types' import config from '../utilities/config' import UserRepository from '../repositories/userRepository' import { User } from '@prisma/client' +import logger from '../utilities/logger' /** * Socket io jwt auth middleware @@ -11,7 +12,7 @@ import { User } from '@prisma/client' */ export async function Authentication(socket: TSocket, next: any) { if (!socket.request.headers.cookie) { - console.log('No cookie provided') + logger.warn('No cookie provided') return next(new Error('Authentication error')) } @@ -32,7 +33,7 @@ export async function Authentication(socket: TSocket, next: any) { if (token) { verify(token, config.JWT_SECRET, async (err: any, decoded: any) => { if (err) { - console.log('err') + logger.error('Invalid token') return next(new Error('Authentication error')) } @@ -40,7 +41,7 @@ export async function Authentication(socket: TSocket, next: any) { next() }) } else { - console.log('No token provided') + logger.warn('No token provided') next(new Error('Authentication error')) } } diff --git a/src/services/character/characterMoveService.ts b/src/services/character/characterMoveService.ts index d4eeb6d..e1352b3 100644 --- a/src/services/character/characterMoveService.ts +++ b/src/services/character/characterMoveService.ts @@ -3,10 +3,9 @@ import { AStar } from '../../utilities/character/aStar' import ZoneManager from '../../managers/zoneManager' import prisma from '../../utilities/prisma' import Rotation from '../../utilities/character/rotation' +import logger from '../../utilities/logger' export class CharacterMoveService { - private moveTokens: Map = new Map() - public async updatePosition(character: ExtendedCharacter, position: { x: number; y: number }, newZoneId?: number): Promise { Object.assign(character, { positionX: position.x, @@ -29,7 +28,7 @@ export class CharacterMoveService { public async calculatePath(character: ExtendedCharacter, targetX: number, targetY: number): Promise | null> { const grid = await ZoneManager.getGrid(character.zoneId) if (!grid?.length) { - console.error('character:move error', 'Grid not found or empty') + logger.error('character:move error', 'Grid not found or empty') return null } @@ -39,19 +38,7 @@ export class CharacterMoveService { return AStar.findPath(start, end, grid) } - public startMovement(characterId: number): void { - this.moveTokens.set(characterId, Symbol('moveToken')) - } - - public stopMovement(characterId: number): void { - this.moveTokens.delete(characterId) - } - - public isMoving(characterId: number): boolean { - return this.moveTokens.has(characterId) - } - public async applyMovementDelay(): Promise { - await new Promise((resolve) => setTimeout(resolve, 210)) // 50ms delay between steps + await new Promise((resolve) => setTimeout(resolve, 250)) // 250ms delay between steps } }