diff --git a/src/socketEvents/gameMaster/assetManager/tile/upload.ts b/src/socketEvents/gameMaster/assetManager/tile/upload.ts index 69f1f40..6d292b8 100644 --- a/src/socketEvents/gameMaster/assetManager/tile/upload.ts +++ b/src/socketEvents/gameMaster/assetManager/tile/upload.ts @@ -1,11 +1,11 @@ import { Server } from 'socket.io' import { TSocket } from '../../../../utilities/types' -import { writeFile } from 'node:fs/promises' import path from 'path' import fs from 'fs/promises' import prisma from '../../../../utilities/prisma' import characterRepository from '../../../../repositories/characterRepository' import { gameMasterLogger } from '../../../../utilities/logger' +import sharp from 'sharp'; interface ITileData { [key: string]: Buffer @@ -44,7 +44,9 @@ export default class TileUploadEvent { const uuid = tile.id const filename = `${uuid}.png` const finalFilePath = path.join(public_folder, filename) - await writeFile(finalFilePath, tileData) + + // Process the image + await this.processAndSaveTile(tileData, finalFilePath) }) await Promise.all(uploadPromises) @@ -55,4 +57,49 @@ export default class TileUploadEvent { callback(false) } } + + private async processAndSaveTile(tileData: Buffer, outputPath: string): Promise { + const image = sharp(tileData); + const metadata = await image.metadata(); + + if (metadata.width !== 64 || metadata.height !== 32) { + throw new Error('Input tile must be 64x32 pixels'); + } + + const resizedImage = await image + .resize(66, 34, { + kernel: sharp.kernel.nearest, + fit: 'contain', + position: 'center', + background: { r: 0, g: 0, b: 0, alpha: 0 } + }) + .raw() + .toBuffer({ resolveWithObject: true }); + + const { data, info } = resizedImage; + const { width, height, channels } = info; + + // Add 1px lines on each side + for (let y = 0; y < height; y++) { + for (let x = 0; x < width; x++) { + if (x === 0 || x === width - 1 || y === 0 || y === height - 1) { + const idx = (y * width + x) * channels; + const nearestIdx = ( + y === 0 ? width + x : + y === height - 1 ? (height - 2) * width + x : + x === 0 ? y * width + 1 : + y * width + width - 2 + ) * channels; + + for (let c = 0; c < channels; c++) { + data[idx + c] = data[nearestIdx + c]; + } + } + } + } + + await sharp(data, { raw: { width, height, channels } }) + .png() + .toFile(outputPath); + } }