import fs from 'fs/promises' import { writeFile } from 'node:fs/promises' import sharp from 'sharp' import Storage from '#application/storage' import { BaseEvent } from '#application/base/baseEvent' import { MapObject } from '#entities/mapObject' interface IObjectData { [key: string]: Buffer } export default class MapObjectUploadEvent extends BaseEvent { public listen(): void { this.socket.on('gm:mapObject:upload', this.handleEvent.bind(this)) } private async handleEvent(data: IObjectData, callback: (response: boolean) => void): Promise { try { if (!(await this.isCharacterGM())) return const public_folder = Storage.getPublicPath('map_objects') // Ensure the folder exists await fs.mkdir(public_folder, { recursive: true }) const uploadPromises = Object.entries(data).map(async ([key, objectData]) => { // Get image dimensions const metadata = await sharp(objectData).metadata() const width = metadata.width || 0 const height = metadata.height || 0 // Create new map object and save it to database const mapObject = new MapObject() await mapObject.setName(key).setTags([]).setOriginX(0).setOriginY(0).setFrameWidth(width).setFrameHeight(height).save() // Save image to disk const uuid = mapObject.getId() const filename = `${uuid}.png` const finalFilePath = Storage.getPublicPath('map_objects', filename) await writeFile(finalFilePath, objectData) this.logger.info('gm:mapObject:upload', `Object ${key} uploaded with id ${uuid}`) }) await Promise.all(uploadPromises) return callback(true) } catch (error: any) { this.logger.error('gm:mapObject:upload error', error.message) return callback(false) } } }