Merge pull request #243 from karelpak1/fix-tank-icons-riff

fix: use RIFF sprite bounds for tank icon extraction
This commit is contained in:
TrèsAbhi authored and GitHub committed 2026-05-14 22:36:09 -05:00
commit 0ccd9e45d8
1 file changed
+48 -6
+48 -6
View File
@@ -1,6 +1,7 @@
import { NATION_IDS } from "@blitzkit/core"; import { NATION_IDS } from "@blitzkit/core";
import sharp from "sharp"; import sharp from "sharp";
import type { Vector3Tuple } from "three"; import type { Vector3Tuple } from "three";
import { parsePackedSpriteRect } from "../core/blitz/parsePackedSpriteRect";
import { AssetUploader } from "../core/github/assetUploader"; import { AssetUploader } from "../core/github/assetUploader";
import { vfs } from "./constants"; import { vfs } from "./constants";
import type { VehicleDefinitionList } from "./definitions"; import type { VehicleDefinitionList } from "./definitions";
@@ -37,6 +38,45 @@ export interface TankParameters {
}; };
} }
async function extractPackedTankIcon(packedBuffer: Buffer, context: string) {
const texture = sharp(packedBuffer);
const spriteRect = parsePackedSpriteRect(packedBuffer);
if (!spriteRect) {
throw new Error(`Missing RIFF sprite bounds for ${context}`);
}
const [left, top, width, height] = spriteRect;
const bounds = [left, top, width, height];
if (!bounds.every(Number.isInteger)) {
throw new Error(
`Invalid RIFF sprite bounds for ${context}: ${bounds.join(" ")}`,
);
}
const metadata = await texture.metadata();
if (metadata.width === undefined || metadata.height === undefined) {
throw new Error(`Failed to read image dimensions for ${context}`);
}
if (
left < 0 ||
top < 0 ||
width <= 0 ||
height <= 0 ||
left + width > metadata.width ||
top + height > metadata.height
) {
throw new Error(
`Out-of-bounds RIFF sprite for ${context}: ${bounds.join(" ")} in ${metadata.width}x${metadata.height}`,
);
}
return await texture.extract({ left, top, width, height }).toBuffer();
}
export async function tankIcons() { export async function tankIcons() {
console.log("Building tank icons..."); console.log("Building tank icons...");
@@ -67,12 +107,14 @@ export async function tankIcons() {
const bigPath = `Data/${parameters.resourcesPath.bigIconPath const bigPath = `Data/${parameters.resourcesPath.bigIconPath
.replace(/~res:\//, "") .replace(/~res:\//, "")
.replace(/\..+/, "")}.packed.webp`; .replace(/\..+/, "")}.packed.webp`;
const big = await sharp(await vfs.file(bigPath)) const big = await extractPackedTankIcon(
.trim() await vfs.file(bigPath),
.toBuffer(); `tank ${tankKey} big`,
const small = await sharp(await vfs.file(smallPath)) );
.trim() const small = await extractPackedTankIcon(
.toBuffer(); await vfs.file(smallPath),
`tank ${tankKey} small`,
);
if (big) { if (big) {
await uploader.add({ await uploader.add({