diff --git a/package-lock.json b/package-lock.json index a24acda..2959efe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,9 @@ "license": "AGPL-3.0", "dependencies": { "@pretendonetwork/grpc": "^1.0.3", + "@types/bmp-js": "^0.1.2", "aws-sdk": "^2.1204.0", + "bmp-js": "^0.1.0", "colors": "^1.4.0", "crc": "^4.3.2", "dotenv": "^16.0.3", @@ -1562,6 +1564,14 @@ "node": ">=14.0.0" } }, + "node_modules/@types/bmp-js": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/bmp-js/-/bmp-js-0.1.2.tgz", + "integrity": "sha512-BF6u+M+KySDBKfr1DQOT3+z42n4/tq62uf9ong4i2SLLpa7mJqPwEmKbNgMzlVliT/jtE6elxyD/0X1mja8jLg==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/body-parser": { "version": "1.19.2", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", @@ -2300,6 +2310,11 @@ "integrity": "sha512-UfFSr22dmHPQqPP9XWHRhq+gWnHCYguQGkXQlbyPtW5qTnhFWA8/iXg765tH0cAjy7l/zPJ1aBTO0g5XgA7kvQ==", "dev": true }, + "node_modules/bmp-js": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", + "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==" + }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", diff --git a/package.json b/package.json index 8dabcd7..56aaf47 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,9 @@ "license": "AGPL-3.0", "dependencies": { "@pretendonetwork/grpc": "^1.0.3", + "@types/bmp-js": "^0.1.2", "aws-sdk": "^2.1204.0", + "bmp-js": "^0.1.0", "colors": "^1.4.0", "crc": "^4.3.2", "dotenv": "^16.0.3", diff --git a/src/util.ts b/src/util.ts index d636227..6258cf4 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,6 +1,7 @@ import crypto from 'node:crypto'; import { IncomingHttpHeaders } from 'node:http'; import TGA from 'tga'; +import BMP from 'bmp-js'; import pako from 'pako'; import { PNG } from 'pngjs'; import aws from 'aws-sdk'; @@ -104,15 +105,32 @@ export function processPainting(painting: string): Buffer | null { return null; } - const tga = new TGA(Buffer.from(output)); - const png = new PNG({ - width: tga.width, - height: tga.height - }); + // 3DS is a BMP, Wii U is a TGA. God isn't real so we need to edit the + // alpha layer of the BMP to covert it to a PNG for the web app + if (output[0] === 66) { + const bitmap = BMP.decode(Buffer.from(output)); + const png = new PNG({ + width: bitmap.width, + height: bitmap.height + }); - png.data = Buffer.from(tga.pixels); + const bpmBuffer = bitmap.getData(); + bpmBuffer.swap32(); + png.data = bpmBuffer; + for (let i = 3; i < bpmBuffer.length; i += 4) { + bpmBuffer[i] = 255; + } + return PNG.sync.write(png); + } else { + const tga = new TGA(Buffer.from(output)); + const png = new PNG({ + width: tga.width, + height: tga.height + }); - return PNG.sync.write(png); + png.data = Buffer.from(tga.pixels); + return PNG.sync.write(png); + } } export async function uploadCDNAsset(bucket: string, key: string, data: Buffer, acl: string): Promise {