import { Zone, ZoneEventTile, ZoneEventTileType, ZoneObject } from '@prisma/client' 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 { try { return await prisma.zone.findFirst() } catch (error: any) { appLogger.error(`Failed to get first zone: ${error.message}`) return null } } async getAll(): Promise { try { return await prisma.zone.findMany() } catch (error: any) { appLogger.error(`Failed to get all zone: ${error.message}`) return [] } } async getById(id: number) { try { return await prisma.zone.findUnique({ where: { id: id }, include: { zoneEventTiles: { include: { zone: true, teleport: true } }, zoneObjects: { include: { object: true } }, zoneEffects: true } }) } catch (error: any) { appLogger.error(`Failed to get zone by id: ${error.message}`) return null } } async getEventTiles(id: number): Promise { try { return await prisma.zoneEventTile.findMany({ where: { zoneId: id } }) } catch (error: any) { appLogger.error(`Failed to get zone event tiles: ${error.message}`) return [] } } async getEventTeleportTiles(id: number): Promise { try { return (await prisma.zoneEventTile.findMany({ where: { zoneId: id, type: ZoneEventTileType.TELEPORT }, include: { teleport: true } })) as unknown as ZoneEventTileWithTeleport[] } catch (error: any) { appLogger.error(`Failed to get zone event tiles: ${error.message}`) return [] } } async getZoneObjects(id: number): Promise { try { return await prisma.zoneObject.findMany({ where: { zoneId: id } }) } catch (error: any) { appLogger.error(`Failed to get zone objects: ${error.message}`) 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()