From 9d08073fa88b3f81e1b1581a3a5891dbd3af9875 Mon Sep 17 00:00:00 2001 From: Dennis Postma Date: Fri, 25 Oct 2024 22:21:06 +0200 Subject: [PATCH] npm update, http asset endpoint changes --- package-lock.json | 18 ++-- src/managers/zoneManager.ts | 25 +---- src/repositories/zoneRepository.ts | 52 +++++++++- src/utilities/http.ts | 149 +++++++++++++---------------- 4 files changed, 128 insertions(+), 116 deletions(-) diff --git a/package-lock.json b/package-lock.json index 45eab9e..42cbff6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -719,9 +719,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.16.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.13.tgz", - "integrity": "sha512-GjQ7im10B0labo8ZGXDGROUl9k0BNyDgzfGpb4g/cl+4yYDWVKcozANF4FGr4/p0O/rAkQClM6Wiwkije++1Tg==", + "version": "20.17.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.1.tgz", + "integrity": "sha512-j2VlPv1NnwPJbaCNv69FO/1z4lId0QmGvpT41YxitRtWlg96g/j8qcv2RKsLKe2F6OJgyXhupN1Xo17b2m139Q==", "license": "MIT", "dependencies": { "undici-types": "~6.19.2" @@ -926,9 +926,9 @@ "license": "BSD-3-Clause" }, "node_modules/bullmq": { - "version": "5.21.1", - "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.21.1.tgz", - "integrity": "sha512-+yvsd5LkbWkTW2K5C/1s8h1+gGK4F9wVfKM6AJUBSWGsbfWHXnni0Se7xHj1dieVkx6XEsfCzFtO6kZnD+mtHQ==", + "version": "5.21.2", + "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.21.2.tgz", + "integrity": "sha512-LPuNoGaDc5CON2X6h4cJ2iVfd+B+02xubFU+IB/fyJHd+/HqUZRqnlYryUCAuhVHBhUKtA6oyVdJxqSa62i+og==", "license": "MIT", "dependencies": { "cron-parser": "^4.6.0", @@ -2479,9 +2479,9 @@ } }, "node_modules/socket.io": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz", - "integrity": "sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", "license": "MIT", "dependencies": { "accepts": "~1.3.4", diff --git a/src/managers/zoneManager.ts b/src/managers/zoneManager.ts index 3d41afd..85f7dce 100644 --- a/src/managers/zoneManager.ts +++ b/src/managers/zoneManager.ts @@ -2,8 +2,7 @@ import { Zone } from '@prisma/client' import ZoneRepository from '../repositories/zoneRepository' import ZoneService from '../services/zoneService' import LoadedZone from '../models/loadedZone' -import zoneRepository from '../repositories/zoneRepository' -import { gameMasterLogger } from '../utilities/logger' +import { gameLogger } from '../utilities/logger' class ZoneManager { private loadedZones: LoadedZone[] = [] @@ -21,36 +20,20 @@ class ZoneManager { await this.loadZone(zone) } - gameMasterLogger.info('Zone manager loaded') - } - - public async getZoneAssets(zone: Zone): Promise { - const tiles: string[] = this.getUnique((JSON.parse(JSON.stringify(zone.tiles)) as string[][]).reduce((acc, val) => [...acc, ...val])) - const objects = await zoneRepository.getObjects(zone.id) - const mappedObjects = this.getUnique(objects.map((x) => x.objectId)) - - return { - tiles: tiles, - objects: mappedObjects - } as ZoneAssets - } - - private getUnique(array: T[]) { - return [...new Set(array)] + gameLogger.info('Zone manager loaded') } // Method to handle individual zoneEditor loading public async loadZone(zone: Zone) { const loadedZone = new LoadedZone(zone) this.loadedZones.push(loadedZone) - await this.getZoneAssets(zone) - gameMasterLogger.info(`Zone ID ${zone.id} loaded`) + gameLogger.info(`Zone ID ${zone.id} loaded`) } // Method to handle individual zoneEditor unloading public unloadZone(zoneId: number) { this.loadedZones = this.loadedZones.filter((loadedZone) => loadedZone.getZone().id !== zoneId) - gameMasterLogger.info(`Zone ID ${zoneId} unloaded`) + gameLogger.info(`Zone ID ${zoneId} unloaded`) } // Getter for loaded zones diff --git a/src/repositories/zoneRepository.ts b/src/repositories/zoneRepository.ts index e4dea08..c596027 100644 --- a/src/repositories/zoneRepository.ts +++ b/src/repositories/zoneRepository.ts @@ -2,6 +2,8 @@ import { Zone, ZoneEventTile, ZoneEventTileType, ZoneObject } from '@prisma/clie import prisma from '../utilities/prisma' import { ZoneEventTileWithTeleport } from '../socketEvents/zone/characterMove' import { appLogger } from '../utilities/logger' +import { TAsset } from '../utilities/types' +import tileRepository from './tileRepository' class ZoneRepository { async getFirst(): Promise { @@ -22,7 +24,7 @@ class ZoneRepository { } } - async getById(id: number): Promise { + async getById(id: number) { try { return await prisma.zone.findUnique({ where: { @@ -77,7 +79,7 @@ class ZoneRepository { } } - async getObjects(id: number): Promise { + async getZoneObjects(id: number): Promise { try { return await prisma.zoneObject.findMany({ where: { @@ -89,6 +91,52 @@ class ZoneRepository { return [] } } + + async getZoneAssets(zone_id: number): Promise { + const zone = await this.getById(zone_id) + if (!zone) return [] + + const assets: TAsset[] = [] + + // zone.tiles is prisma jsonvalue + let tiles = JSON.parse(JSON.stringify(zone.tiles)) + tiles = [...new Set(tiles.flat())] + + // Add tile assets + for (const tile of tiles) { + const tileInfo = await tileRepository.getById(tile) + if (!tileInfo) continue + + assets.push({ + key: tileInfo.id, + url: '/assets/tiles/' + tileInfo.id + '.png', + group: 'tiles', + updatedAt: tileInfo?.updatedAt || new Date() + }) + } + + // Add object assets + for (const zoneObject of zone.zoneObjects) { + if (!zoneObject.object) continue + + assets.push({ + key: zoneObject.object.id, + url: '/assets/objects/' + zoneObject.object.id + '.png', + group: 'objects', + updatedAt: zoneObject.object.updatedAt || new Date() + }) + } + + // Filter out duplicate assets + return assets.reduce((acc: TAsset[], current) => { + const x = acc.find((item) => item.key === current.key && item.group === current.group) + if (!x) { + return acc.concat([current]) + } else { + return acc + } + }, []) + } } export default new ZoneRepository() diff --git a/src/utilities/http.ts b/src/utilities/http.ts index 2022b45..6cf19d8 100644 --- a/src/utilities/http.ts +++ b/src/utilities/http.ts @@ -3,95 +3,12 @@ import UserService from '../services/userService' import jwt from 'jsonwebtoken' import config from './config' import { loginAccountSchema, registerAccountSchema } from './zodTypes' -import { TAsset } from './types' -import tileRepository from '../repositories/tileRepository' -import objectRepository from '../repositories/objectRepository' -import spriteRepository from '../repositories/spriteRepository' import fs from 'fs' import { httpLogger } from './logger' import { getPublicPath } from './storage' +import zoneRepository from '../repositories/zoneRepository' async function addHttpRoutes(app: Application) { - /** - * Get all base sprite, assets - * @param req - * @param res - */ - app.get('/assets', async (req: Request, res: Response) => { - let assets: TAsset[] = [] - - const sprites = await spriteRepository.getAll() - const tiles = await tileRepository.getAll() - const objects = await objectRepository.getAll() - - // sprites all contain spriteActions, loop through these - sprites.forEach((sprite) => { - sprite.spriteActions.forEach((spriteAction) => { - assets.push({ - key: sprite.id + '-' + spriteAction.action, - url: '/assets/sprites/' + sprite.id + '/' + spriteAction.action + '.png', - group: spriteAction.isAnimated ? 'sprite_animations' : 'sprites', - updatedAt: sprite.updatedAt, - frameCount: JSON.parse(JSON.stringify(spriteAction.sprites)).length, - frameWidth: spriteAction.frameWidth, - frameHeight: spriteAction.frameHeight, - }) - }) - }) - - // Get all tiles - tiles.forEach((tile) => { - assets.push({ - key: tile.id, - url: '/assets/tiles/' + tile.id + '.png', - group: 'tiles', - updatedAt: tile.updatedAt - }) - }) - - // Get all objects - objects.forEach((object) => { - assets.push({ - key: object.id, - url: '/assets/objects/' + object.id + '.png', - group: 'objects', - updatedAt: object.updatedAt - }) - }) - - res.json(assets) - }) - - /** - * Get a specific asset - * @param req - * @param res - */ - app.get('/assets/:type/:spriteId?/:file', (req: Request, res: Response) => { - const assetType = req.params.type - const spriteId = req.params.spriteId - const fileName = req.params.file - - let assetPath - if (assetType === 'sprites' && spriteId) { - assetPath = getPublicPath(assetType, spriteId, fileName) - } else { - assetPath = getPublicPath(assetType, fileName) - } - - if (!fs.existsSync(assetPath)) { - httpLogger.error(`File not found: ${assetPath}`) - return res.status(404).send('Asset not found') - } - - res.sendFile(assetPath, (err) => { - if (err) { - httpLogger.error('Error sending file:', err) - res.status(500).send('Error downloading the asset') - } - }) - }) - /** * Login * @param req @@ -141,6 +58,70 @@ async function addHttpRoutes(app: Application) { return res.status(400).json({ message: 'Failed to register user' }) }) + /** + * Get all tiles from a zone as an array of ids + * @param req + * @param res + */ + app.get('/assets/tiles/:zoneId', async (req: Request, res: Response) => { + const zoneId = req.params.zoneId + + // Check if zoneId is valid number + if (!zoneId || parseInt(zoneId) === 0) { + return res.status(400).json({ message: 'Invalid zone ID' }) + } + + // Get zone by id + const zone = await zoneRepository.getById(parseInt(zoneId)) + if (!zone) { + return res.status(404).json({ message: 'Zone not found' }) + } + + let tiles = zone.tiles; + + // Convert to array + tiles = JSON.parse(JSON.stringify(tiles)) as string[] + + // Flatten the array + tiles = [...new Set(tiles.flat())] + + // Remove duplicates + tiles = tiles.filter((value, index, self) => self.indexOf(value) === index); + + // Return the array + res.json(tiles) + }) + + /** + * Get a specific asset + * @param req + * @param res + */ + app.get('/assets/:type/:spriteId?/:file', (req: Request, res: Response) => { + const assetType = req.params.type + const spriteId = req.params.spriteId + const fileName = req.params.file + + let assetPath + if (assetType === 'sprites' && spriteId) { + assetPath = getPublicPath(assetType, spriteId, fileName) + } else { + assetPath = getPublicPath(assetType, fileName) + } + + if (!fs.existsSync(assetPath)) { + httpLogger.error(`File not found: ${assetPath}`) + return res.status(404).send('Asset not found') + } + + res.sendFile(assetPath, (err) => { + if (err) { + httpLogger.error('Error sending file:', err) + res.status(500).send('Error downloading the asset') + } + }) + }) + httpLogger.info('Web routes added') }