diff --git a/prisma/migrations/20240711171341_add_tiles_model/migration.sql b/prisma/migrations/20240711171341_add_tiles_model/migration.sql new file mode 100644 index 0000000..6203e65 --- /dev/null +++ b/prisma/migrations/20240711171341_add_tiles_model/migration.sql @@ -0,0 +1,19 @@ +/* + Warnings: + + - You are about to drop the `TileTag` table. If the table is not empty, all the data it contains will be lost. + +*/ +-- DropTable +DROP TABLE `TileTag`; + +-- CreateTable +CREATE TABLE `Tile` ( + `id` VARCHAR(191) NOT NULL, + `name` VARCHAR(191) NOT NULL, + `tags` JSON 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; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index c479de2..b4fb851 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -19,6 +19,14 @@ datasource db { url = env("DATABASE_URL") } +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 @@ -74,11 +82,6 @@ model CharacterItem { quantity Int } -model TileTag { - tile String @id - tags Json -} - model Zone { id Int @id @default(autoincrement()) name String diff --git a/src/app/events/gm/object/GmObjectRemove.ts b/src/app/events/gm/object/GmObjectRemove.ts index 12005c8..8b5cb69 100644 --- a/src/app/events/gm/object/GmObjectRemove.ts +++ b/src/app/events/gm/object/GmObjectRemove.ts @@ -1,7 +1,5 @@ import { Server } from "socket.io"; import {TSocket} from "../../../utilities/Types"; -import {writeFile} from "node:fs"; -import {randomUUID} from "node:crypto"; import path from "path"; import fs from "fs"; import ObjectRepository from '../../../repositories/ObjectRepository' diff --git a/src/app/events/gm/object/GmObjectUpload.ts b/src/app/events/gm/object/GmObjectUpload.ts index 3dcc128..1b7ed04 100644 --- a/src/app/events/gm/object/GmObjectUpload.ts +++ b/src/app/events/gm/object/GmObjectUpload.ts @@ -3,7 +3,6 @@ import { TSocket } from "../../../utilities/Types"; import { writeFile } from "node:fs/promises"; import path from "path"; import fs from "fs/promises"; -import { randomUUID } from 'node:crypto'; import objectRepository from '../../../repositories/ObjectRepository' interface IObjectData { diff --git a/src/app/events/gm/tile/GmTileList.ts b/src/app/events/gm/tile/GmTileList.ts index c48baa6..c87f54d 100644 --- a/src/app/events/gm/tile/GmTileList.ts +++ b/src/app/events/gm/tile/GmTileList.ts @@ -1,42 +1,26 @@ import { Server } from "socket.io"; import {TSocket} from "../../../utilities/Types"; -import fs from 'fs'; -import path from "path"; +import { Tile } from '@prisma/client' +import TileRepository from '../../../repositories/TileRepository' interface IPayload { } /** - * Handle game master list object event + * Handle game master list tile event * @param socket * @param io */ export default function (socket: TSocket, io: Server) { - socket.on('gm:tile:list', async (data: any, callback: (response: string[]) => void) => { + socket.on('gm:tile:list', async (data: any, callback: (response: Tile[]) => void) => { if (socket.character?.role !== 'gm') { console.log(`---Character #${socket.character?.id} is not a game master.`); return; } - // get root path - const folder = path.join(process.cwd(), 'public', 'tiles'); - - // list the files in the folder - let tiles: string[] = []; - - fs.readdir(folder, (err, files) => { - if (err) { - console.log(err); - return; - } - - files.forEach(file => { - tiles.push(file.replace('.png', '')); - }); - - // send over the list of object to the socket - callback(tiles); - }); + // get all tiles + const tiles = await TileRepository.getAll(); + callback(tiles); }); } \ No newline at end of file diff --git a/src/app/events/gm/tile/GmTileRemove.ts b/src/app/events/gm/tile/GmTileRemove.ts index 6b2bc33..3013a72 100644 --- a/src/app/events/gm/tile/GmTileRemove.ts +++ b/src/app/events/gm/tile/GmTileRemove.ts @@ -1,9 +1,8 @@ import { Server } from "socket.io"; import {TSocket} from "../../../utilities/Types"; -import {writeFile} from "node:fs"; -import {randomUUID} from "node:crypto"; import path from "path"; import fs from "fs"; +import TileRepository from '../../../repositories/TileRepository' interface IPayload { tile: string; @@ -21,19 +20,26 @@ export default function (socket: TSocket, io: Server) { return; } - // get root path - const public_folder = path.join(process.cwd(), 'public', 'tiles'); - - // remove the tile from the disk - const finalFilePath = path.join(public_folder, data.tile); - fs.unlink(finalFilePath, (err) => { - if (err) { - console.log(err); - callback(false); - return; - } + try { + await TileRepository.delete(data.tile); - callback(true); - }); + // get root path + const public_folder = path.join(process.cwd(), 'public', 'tiles'); + + // remove the tile from the disk + const finalFilePath = path.join(public_folder, data.tile + '.png'); + fs.unlink(finalFilePath, (err) => { + if (err) { + console.log(err); + callback(false); + return; + } + + callback(true); + }); + } catch (e) { + console.log(e); + callback(false); + } }); } \ No newline at end of file diff --git a/src/app/events/gm/tile/GmTileTags.ts b/src/app/events/gm/tile/GmTileTags.ts deleted file mode 100644 index c5c2579..0000000 --- a/src/app/events/gm/tile/GmTileTags.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Server } from "socket.io"; -import {TSocket} from "../../../utilities/Types"; -import TileTagRepository from "../../../repositories/TileTagRepository"; - -interface IPayload { - tile: string; -} - -/** - * Handle game master tile tags update event - * @param socket - * @param io - */ -export default function (socket: TSocket, io: Server) { - socket.on('gm:tile:tags', async (data: IPayload, callback: (response: string[]) => void) => { - - if (socket.character?.role !== 'gm') { - return; - } - - // update the tile tags - try { - const tileTag = await TileTagRepository.getTileTag(data.tile); - callback(tileTag ? tileTag.tags as string[] : []); - } catch (error) { - console.log(error); - callback([]); - } - }); -} \ No newline at end of file diff --git a/src/app/events/gm/tile/GmTileTagsUpdate.ts b/src/app/events/gm/tile/GmTileUpdate.ts similarity index 51% rename from src/app/events/gm/tile/GmTileTagsUpdate.ts rename to src/app/events/gm/tile/GmTileUpdate.ts index 426e0af..1bc4716 100644 --- a/src/app/events/gm/tile/GmTileTagsUpdate.ts +++ b/src/app/events/gm/tile/GmTileUpdate.ts @@ -1,30 +1,31 @@ import { Server } from "socket.io"; import {TSocket} from "../../../utilities/Types"; -import TileTagRepository from "../../../repositories/TileTagRepository"; +import TileRepository from '../../../repositories/TileRepository' interface IPayload { - tile: string; + id: string; + name: string; tags: string[]; } /** - * Handle game master tile tags update event + * Handle game master tile update event * @param socket * @param io */ export default function (socket: TSocket, io: Server) { - socket.on('gm:tile:tags:update', async (data: IPayload, callback: (response: boolean) => void) => { + socket.on('gm:tile:update', async (data: IPayload, callback: (success: boolean) => void) => { if (socket.character?.role !== 'gm') { return; } - // update the tile tags try { - await TileTagRepository.upsertTileTag(data.tile, data.tags); + const Tile = await TileRepository.update(data.id, data.name, data.tags); + callback(true); } catch (error) { - console.log(error); + console.error(error); callback(false); } }); diff --git a/src/app/events/gm/tile/GmTileUpload.ts b/src/app/events/gm/tile/GmTileUpload.ts index 671e0fc..0c9cff1 100644 --- a/src/app/events/gm/tile/GmTileUpload.ts +++ b/src/app/events/gm/tile/GmTileUpload.ts @@ -3,7 +3,7 @@ import { TSocket } from "../../../utilities/Types"; import { writeFile } from "node:fs/promises"; import path from "path"; import fs from "fs/promises"; -import { randomUUID } from 'node:crypto'; +import tileRepository from '../../../repositories/TileRepository' interface ITileData { [key: string]: Buffer; @@ -28,7 +28,8 @@ export default function (socket: TSocket, io: Server) { await fs.mkdir(public_folder, { recursive: true }); const uploadPromises = Object.entries(data).map(async ([key, tileData]) => { - const uuid = randomUUID(); + const tile = await tileRepository.create('New tile'); + const uuid = tile.id; const filename = `${uuid}.png`; const finalFilePath = path.join(public_folder, filename); await writeFile(finalFilePath, tileData); @@ -38,7 +39,7 @@ export default function (socket: TSocket, io: Server) { callback(true); } catch (error) { - console.error('Error uploading object:', error); + console.error('Error uploading tile:', error); callback(false); } }); diff --git a/src/app/repositories/TileRepository.ts b/src/app/repositories/TileRepository.ts new file mode 100644 index 0000000..53e11f1 --- /dev/null +++ b/src/app/repositories/TileRepository.ts @@ -0,0 +1,47 @@ +import prisma from '../utilities/Prisma'; // Import the global Prisma instance +import { Tile } from '@prisma/client' + +class TileRepository { + async getById(id: string): Promise { + return prisma.tile.findUnique({ + where: { id }, + }); + } + + async getAll(): Promise { + return prisma.tile.findMany(); + } + + async create(name: string): Promise { + return prisma.tile.create({ + data: { + name, + tags: [] + }, + }); + } + + async update(id: string, name: string, tags: string[]): Promise { + return prisma.tile.update({ + where: { id }, + data: { + name, + tags + }, + }); + } + + async delete(id: string): Promise { + try { + await prisma.tile.delete({ + where: { id }, + }); + return true; + } catch (error) { + console.log('Error deleting tile:', error) + return false; + } + } +} + +export default new TileRepository(); \ No newline at end of file