feat: update all

This commit is contained in:
TrèsAbhi committed 2025-11-26 13:18:44 -06:00
1 parent 3efe807e35
commit a0bccc7973
21 files changed
+160 -306

No files matched your search

@@ -1,19 +1,16 @@
import { readdir } from "fs/promises";
import sharp from "sharp";
import { readDVPLFile } from "../../src/core/blitz/readDVPLFile";
import { readStringDVPL } from "../../src/core/blitz/readStringDVPL";
import { AssetUploader } from "../core/github/assetUploader";
import { DATA } from "./constants";
import { vfs } from "./constants";
export async function boosterIcons() {
console.log("Building booster icons...");
using uploader = new AssetUploader("booster icons");
const boosterFiles = (await readdir(`${DATA}/Gfx/Shared/boosters`)).filter(
const boosterFiles = (vfs.dir(`Data/Gfx/Shared/boosters`)).filter(
(file) => !file.includes("@2x.txt") && !file.startsWith("texture0")
);
const image = sharp(
await readDVPLFile(`${DATA}/Gfx/Shared/boosters/texture0.packed.webp`)
await vfs.file(`Data/Gfx/Shared/boosters/texture0.packed.webp`)
);
for (const file of boosterFiles) {
@@ -21,7 +18,7 @@ export async function boosterIcons() {
if (name === undefined) continue;
const sizes = (await readStringDVPL(`${DATA}/Gfx/Shared/boosters/${file}`))
const sizes = (await vfs.text(`Data/Gfx/Shared/boosters/${file}`))
.split("\n")[4]
.split(" ")
.map(Number);
@@ -1,13 +1,12 @@
import { readDVPLFile } from "../../src/core/blitz/readDVPLFile";
import { AssetUploader } from "../core/github/assetUploader";
import { DATA } from "./constants";
import { vfs } from "./constants";
export async function camouflageIcons() {
console.log("Building camouflage icons...");
using uploader = new AssetUploader("camo icons");
const content = await readDVPLFile(
`${DATA}/Gfx/UI/Hangar/IconCamouflage.packed.webp`
const content = await vfs.file(
`Data/Gfx/UI/Hangar/IconCamouflage.packed.webp`
);
await uploader.add({ content, path: "icons/camo.webp" });
@@ -1,11 +1,6 @@
import { existsSync } from "fs";
import sharp from "sharp";
import { readDVPLFile } from "../../src/core/blitz/readDVPLFile";
import { readStringDVPL } from "../../src/core/blitz/readStringDVPL";
import { readXMLDVPL } from "../core/blitz/readXMLDVPL";
import { readYAMLDVPL } from "../core/blitz/readYAMLDVPL";
import { AssetUploader } from "../core/github/assetUploader";
import { DATA } from "./constants";
import { vfs } from "./constants";
import { ConsumablesCommon, ProvisionsCommon } from "./definitions";
interface Mappings {
@@ -33,20 +28,20 @@ export async function consumableProvisionIcons() {
styles.map(async (path) =>
Object.values(
(
await readYAMLDVPL<Mappings>(`${DATA}/${path}`)
await vfs.yaml<Mappings>(`Data/${path}`)
).StyleSheets
)
)
).then((array) => array.flat());
for (const match of (
await readStringDVPL(
`${DATA}/XML/item_defs/vehicles/common/consumables/list.xml`
await vfs.text(
`Data/XML/item_defs/vehicles/common/consumables/list.xml`
)
).matchAll(listItemsPattern)) {
const consumablesCommon = await readXMLDVPL<{
const consumablesCommon = await vfs.xml<{
root: ConsumablesCommon;
}>(`${DATA}/XML/item_defs/vehicles/common/consumables/${match[1]}.xml`);
}>(`Data/XML/item_defs/vehicles/common/consumables/${match[1]}.xml`);
for (const consumable of Object.values(consumablesCommon.root)) {
const styleSheet = styleSheets.find((styleSheet) =>
@@ -67,9 +62,9 @@ export async function consumableProvisionIcons() {
.replace(".psd", "")
.replace(".txt", "");
if (existsSync(`${DATA}/${configPath}.packed.webp`)) {
if (vfs.has(`Data/${configPath}.packed.webp`)) {
const image = sharp(
await readDVPLFile(`${DATA}/${configPath}.packed.webp`)
await vfs.file(`Data/${configPath}.packed.webp`)
);
const content = await image.trim({ threshold: 100 }).toBuffer();
@@ -79,14 +74,14 @@ export async function consumableProvisionIcons() {
});
} else {
const consumablesTexture = sharp(
await readDVPLFile(
`${`${DATA}/${configPath}`
await vfs.file(
`${`Data/${configPath}`
.split("/")
.slice(0, -1)
.join("/")}/texture0.packed.webp`
)
);
const sizes = (await readStringDVPL(`${DATA}/${configPath}.txt`))
const sizes = (await vfs.text(`Data/${configPath}.txt`))
.split("\n")[4]
.split(" ")
.map(Number);
@@ -109,13 +104,13 @@ export async function consumableProvisionIcons() {
}
for (const match of (
await readStringDVPL(
`${DATA}/XML/item_defs/vehicles/common/provisions/list.xml`
await vfs.text(
`Data/XML/item_defs/vehicles/common/provisions/list.xml`
)
).matchAll(listItemsPattern)) {
const provisionsCommon = await readXMLDVPL<{
const provisionsCommon = await vfs.xml<{
root: ProvisionsCommon;
}>(`${DATA}/XML/item_defs/vehicles/common/provisions/${match[1]}.xml`);
}>(`Data/XML/item_defs/vehicles/common/provisions/${match[1]}.xml`);
for (const provision of Object.values(provisionsCommon.root)) {
const styleSheet = styleSheets.find((styleSheet) =>
@@ -136,9 +131,9 @@ export async function consumableProvisionIcons() {
.replace(".psd", "")
.replace(".txt", "");
if (existsSync(`${DATA}/${configPath}.packed.webp`)) {
if (vfs.has(`Data/${configPath}.packed.webp`)) {
const image = sharp(
await readDVPLFile(`${DATA}/${configPath}.packed.webp`)
await vfs.file(`Data/${configPath}.packed.webp`)
);
const content = await image.trim({ threshold: 100 }).toBuffer();
@@ -148,14 +143,14 @@ export async function consumableProvisionIcons() {
});
} else {
const provisionsTexture = sharp(
await readDVPLFile(
`${`${DATA}/${configPath}`
await vfs.file(
`${`Data/${configPath}`
.split("/")
.slice(0, -1)
.join("/")}/texture0.packed.webp`
)
);
const sizes = (await readStringDVPL(`${DATA}/${configPath}.txt`))
const sizes = (await vfs.text(`Data/${configPath}.txt`))
.split("\n")[4]
.split(" ")
.map(Number);
@@ -1,8 +1,7 @@
import { assertSecret, BlitzGlossary } from "@blitzkit/core";
import sharp from "sharp";
import { readDVPLFile } from "../../src/core/blitz/readDVPLFile";
import { AssetUploader } from "../core/github/assetUploader";
import { DATA } from "./constants";
import { vfs } from "./constants";
const ICONS = [
["currency_silver_m.packed.webp", "silver"],
@@ -21,7 +20,7 @@ export async function currencies() {
for (const [file, name] of ICONS) {
const content = await sharp(
await readDVPLFile(`${DATA}/Gfx/Lobby/currency/${file}`)
await vfs.file(`Data/Gfx/Lobby/currency/${file}`)
)
.trim()
.toBuffer();
@@ -1,10 +1,6 @@
import sharp from "sharp";
import { readDVPLFile } from "../../src/core/blitz/readDVPLFile";
import { readStringDVPL } from "../../src/core/blitz/readStringDVPL";
import { readXMLDVPL } from "../core/blitz/readXMLDVPL";
import { readYAMLDVPL } from "../core/blitz/readYAMLDVPL";
import { AssetUploader } from "../core/github/assetUploader";
import { DATA } from "./constants";
import { vfs } from "./constants";
import { OptionalDevices } from "./definitions";
interface Mappings {
@@ -20,15 +16,15 @@ export async function equipmentIcons() {
console.log("Building equipment icons...");
using uploader = new AssetUploader("equipment icons");
const optionalDevices = await readXMLDVPL<{ root: OptionalDevices }>(
`${DATA}/XML/item_defs/vehicles/common/optional_devices.xml`
const optionalDevices = await vfs.xml<{ root: OptionalDevices }>(
`Data/XML/item_defs/vehicles/common/optional_devices.xml`
);
const mappings = await readYAMLDVPL<Mappings>(
`${DATA}/UI/Screens3/Lobby/Inventory/OptionalDevices/OptionalDevicesItemImage.style.yaml`
const mappings = await vfs.yaml<Mappings>(
`Data/UI/Screens3/Lobby/Inventory/OptionalDevices/OptionalDevicesItemImage.style.yaml`
);
const image = sharp(
await readDVPLFile(
`${DATA}/Gfx/UI/InventoryIcons/Big/OptionalDevices/texture0.packed.webp`
await vfs.file(
`Data/Gfx/UI/InventoryIcons/Big/OptionalDevices/texture0.packed.webp`
)
);
@@ -54,7 +50,7 @@ export async function equipmentIcons() {
if (configPath.startsWith("Gfx/Lobby")) {
const configPathWebp = configPath.replace(".txt", "");
const image = sharp(
await readDVPLFile(`${DATA}/${configPathWebp}.packed.webp`)
await vfs.file(`Data/${configPathWebp}.packed.webp`)
);
const content = await image.trim().toBuffer();
@@ -63,7 +59,7 @@ export async function equipmentIcons() {
content,
});
} else {
const config = await readStringDVPL(`${DATA}/${configPath}`);
const config = await vfs.text(`Data/${configPath}`);
const sizes = config.split("\n")[4].split(" ").map(Number);
const content = await image
.clone()
+8 -17
View File
@@ -1,37 +1,28 @@
import { readdir } from "fs/promises";
import sharp from "sharp";
import { readDVPLFile } from "../core/blitz/readDVPLFile";
import { AssetUploader } from "../core/github/assetUploader";
import { DATA } from "./constants";
import { vfs } from "./constants";
export async function flags() {
console.log("Building flags...");
using uploader = new AssetUploader("flags");
const circleFiles = await readdir(`${DATA}/Gfx/Lobby/flags`).then((files) =>
files.filter(
const circleFiles = vfs.dir(`Data/Gfx/Lobby/flags`).filter(
(flag) =>
flag.startsWith("flag_profile-stat_") &&
!flag.endsWith("@2x.packed.webp")
)
);
const scratchedFiles = await readdir(`${DATA}/Gfx/Lobby/flags`).then(
(files) =>
files.filter(
);
const scratchedFiles = vfs.dir(`Data/Gfx/Lobby/flags`).filter(
(flag) =>
flag.startsWith("flag_tutor-tank_") &&
!flag.endsWith("@2x.packed.webp")
)
);
const fadedFiles = await readdir(`${DATA}/Gfx/Lobby/flags`).then((files) =>
files.filter(
const fadedFiles = vfs.dir(`Data/Gfx/Lobby/flags`).filter(
(flag) =>
flag.startsWith("flag_filter_") && flag.endsWith("@2x.packed.webp")
)
);
for (const flag of circleFiles) {
const image = sharp(await readDVPLFile(`${DATA}/Gfx/Lobby/flags/${flag}`));
const image = sharp(await vfs.file(`Data/Gfx/Lobby/flags/${flag}`));
const content = await image.trim({ threshold: 100 }).toBuffer();
const name = flag.match(/flag_profile-stat_(.+)\.packed\.webp/)![1];
@@ -42,7 +33,7 @@ export async function flags() {
}
for (const flag of scratchedFiles) {
const content = await readDVPLFile(`${DATA}/Gfx/Lobby/flags/${flag}`);
const content = await vfs.file(`Data/Gfx/Lobby/flags/${flag}`);
const name = flag.match(/flag_tutor-tank_(.+)\.packed\.webp/)![1];
uploader.add({
@@ -53,7 +44,7 @@ export async function flags() {
for (const flag of fadedFiles) {
const content = await sharp(
await readDVPLFile(`${DATA}/Gfx/Lobby/flags/${flag}`)
await vfs.file(`Data/Gfx/Lobby/flags/${flag}`)
)
.trim({
threshold: 100,
@@ -1,19 +1,17 @@
import sharp from "sharp";
import { readDVPLFile } from "../../src/core/blitz/readDVPLFile";
import { readYAMLDVPL } from "../core/blitz/readYAMLDVPL";
import { AssetUploader } from "../core/github/assetUploader";
import { DATA } from "./constants";
import { vfs } from "./constants";
import { SquadBattleTypeStyles } from "./definitions";
export async function gameModeBanners() {
console.log("Building game mode banners...");
using uploader = new AssetUploader("game mode banners");
const gameTypeSelectorStyles = await readYAMLDVPL<SquadBattleTypeStyles>(
`${DATA}/UI/Screens/Lobby/Hangar/GameTypeSelector.yaml`
const gameTypeSelectorStyles = await vfs.yaml<SquadBattleTypeStyles>(
`Data/UI/Screens/Lobby/Hangar/GameTypeSelector.yaml`
);
const squadBattleTypeStyles = await readYAMLDVPL<SquadBattleTypeStyles>(
`${DATA}/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml`
const squadBattleTypeStyles = await vfs.yaml<SquadBattleTypeStyles>(
`Data/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml`
);
const bannerMatches: { name: string; path: string }[] = [];
@@ -37,7 +35,7 @@ export async function gameModeBanners() {
}
const content = await sharp(
await readDVPLFile(`${DATA}${path}.packed.webp`)
await vfs.file(`Data${path}.packed.webp`)
)
.trim({ background: { r: 0, g: 0, b: 0, alpha: 0 } })
.toBuffer();
@@ -1,8 +1,6 @@
import { toUniqueId } from "@blitzkit/core";
import { readdir } from "fs/promises";
import { readXMLDVPL } from "../core/blitz/readXMLDVPL";
import { AssetUploader } from "../core/github/assetUploader";
import { DATA } from "./constants";
import { vfs } from "./constants";
import { VehicleDefinitionList } from "./definitions";
export async function migration() {
@@ -10,13 +8,11 @@ export async function migration() {
using uploader = new AssetUploader("migration map");
const map: Record<string, number> = {};
const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then(
(nations) => nations.filter((nation) => nation !== "common")
);
const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common");
for (const nation of nations) {
const tankList = await readXMLDVPL<{ root: VehicleDefinitionList }>(
`${DATA}/XML/item_defs/vehicles/${nation}/list.xml`
const tankList = await vfs.xml<{ root: VehicleDefinitionList }>(
`Data/XML/item_defs/vehicles/${nation}/list.xml`
);
for (const tankKey in tankList.root) {
@@ -1,24 +1,20 @@
import { readdir } from "fs/promises";
import sharp from "sharp";
import { readDVPLFile } from "../../src/core/blitz/readDVPLFile";
import { AssetUploader } from "../core/github/assetUploader";
import { DATA } from "./constants";
import { vfs } from "./constants";
export async function moduleIcons() {
console.log("Building module icons...");
using uploader = new AssetUploader("module icons");
const files = await readdir(`${DATA}/Gfx/UI/ModulesTechTree`).then((dir) =>
dir.filter(
const files = vfs.dir(`Data/Gfx/UI/ModulesTechTree`).filter(
(file) => !file.endsWith("@2x.packed.webp") && file.startsWith("vehicle")
)
);
for (const file of files) {
const nameRaw = file.match(/vehicle(.+)\.packed\.webp/)![1];
const name = nameRaw[0].toLowerCase() + nameRaw.slice(1);
const content = await sharp(
await readDVPLFile(`${DATA}/Gfx/UI/ModulesTechTree/${file}`)
await vfs.file(`Data/Gfx/UI/ModulesTechTree/${file}`)
)
.trim()
.toBuffer();
+8 -11
View File
@@ -1,28 +1,25 @@
import { readdir } from "fs/promises";
import sharp from "sharp";
import { readDVPLFile } from "../../src/core/blitz/readDVPLFile";
import { readStringDVPL } from "../../src/core/blitz/readStringDVPL";
import { AssetUploader } from "../core/github/assetUploader";
import { DATA } from "./constants";
import { vfs } from "./constants";
export async function shellIcons() {
console.log("Building shell icons...");
using uploader = new AssetUploader("shell icons");
const image = sharp(
await readDVPLFile(
`${DATA}/Gfx/Shared/tank-supply/ammunition/big/texture0.packed.webp`
await vfs.file(
`Data/Gfx/Shared/tank-supply/ammunition/big/texture0.packed.webp`
)
);
const files = await readdir(
`${DATA}/Gfx/Shared/tank-supply/ammunition/big`
).then((files) => files.filter((file) => file.endsWith("_l.txt")));
const files = vfs.dir(
`Data/Gfx/Shared/tank-supply/ammunition/big`
).filter((file) => file.endsWith("_l.txt"))
for (const file of files) {
const name = file.match(/(.+)_l\.txt/)![1];
const sizes = (
await readStringDVPL(
`${DATA}/Gfx/Shared/tank-supply/ammunition/big/${file}`
await vfs.text(
`Data/Gfx/Shared/tank-supply/ammunition/big/${file}`
)
)
.split("\n")[4]
@@ -1,9 +1,7 @@
import { TankClass } from "@blitzkit/core";
import sharp from "sharp";
import { readDVPLFile } from "../core/blitz/readDVPLFile";
import { readXMLDVPL } from "../core/blitz/readXMLDVPL";
import { AssetUploader } from "../core/github/assetUploader";
import { DATA } from "./constants";
import { vfs } from "./constants";
interface SkillIcon {
name: string;
@@ -27,8 +25,8 @@ export interface Avatar {
export async function skillIcons() {
console.log("Building skill icons...");
const avatar = await readXMLDVPL<{ root: Avatar }>(
`${DATA}/XML/item_defs/tankmen/avatar.xml`
const avatar = await vfs.xml<{ root: Avatar }>(
`Data/XML/item_defs/tankmen/avatar.xml`
);
using uploader = new AssetUploader("skill icons");
@@ -36,8 +34,8 @@ export async function skillIcons() {
const skill = avatar.root.skills[key];
const icon = Array.isArray(skill.icon) ? skill.icon[0] : skill.icon;
const name = icon.name.split("/").at(-1)!.replace(/_\d$/, "");
const path = `${DATA}${icon.name.replace("~res:", "")}.packed.webp`;
const image = sharp(await readDVPLFile(path)).trim();
const path = `Data${icon.name.replace("~res:", "")}.packed.webp`;
const image = sharp(await vfs.file(path)).trim();
const content = await image.toBuffer();
await uploader.add({ content, path: `icons/skills/${name}.webp` });
@@ -1,10 +1,8 @@
import { toUniqueId } from "@blitzkit/core";
import { NodeIO } from "@gltf-transform/core";
import { readdir } from "fs/promises";
import { extractArmor } from "../core/blitz/extractArmor";
import { readXMLDVPL } from "../core/blitz/readXMLDVPL";
import { AssetUploader } from "../core/github/assetUploader";
import { DATA } from "./constants";
import { vfs } from "./constants";
import { VehicleDefinitionList } from "./definitions";
export async function tankArmors() {
@@ -12,13 +10,11 @@ export async function tankArmors() {
using uploader = new AssetUploader("tank armors");
const nodeIO = new NodeIO();
const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then(
(nations) => nations.filter((nation) => nation !== "common")
);
const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common");
for (const nation of nations) {
const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>(
`${DATA}/XML/item_defs/vehicles/${nation}/list.xml`
const tanks = await vfs.xml<{ root: VehicleDefinitionList }>(
`Data/XML/item_defs/vehicles/${nation}/list.xml`
);
for (const tankKey in tanks.root) {
@@ -27,7 +23,7 @@ export async function tankArmors() {
if (tankKey.includes("tutorial_bot")) continue;
const id = toUniqueId(nation, tank.id);
const model = await extractArmor(DATA, `${nation}-${tankKey}`);
const model = await extractArmor(vfs, `${nation}-${tankKey}`);
const content = await nodeIO.writeBinary(model);
await uploader.add({ path: `3d/tanks/armor/${id}.glb`, content });
+10 -16
View File
@@ -1,12 +1,8 @@
import { NATION_IDS } from "@blitzkit/core";
import { readdir } from "fs/promises";
import sharp from "sharp";
import type { Vector3Tuple } from "three";
import { readDVPLFile } from "../core/blitz/readDVPLFile";
import { readXMLDVPL } from "../core/blitz/readXMLDVPL";
import { readYAMLDVPL } from "../core/blitz/readYAMLDVPL";
import { AssetUploader } from "../core/github/assetUploader";
import { DATA } from "./constants";
import { vfs } from "./constants";
import type { VehicleDefinitionList } from "./definitions";
export interface TankParameters {
@@ -45,13 +41,11 @@ export async function tankIcons() {
console.log("Building tank icons...");
using uploader = new AssetUploader("tank icons");
const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then(
(nations) => nations.filter((nation) => nation !== "common")
);
const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common")
for (const nation of nations) {
const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>(
`${DATA}/XML/item_defs/vehicles/${nation}/list.xml`
const tanks = await vfs.xml<{ root: VehicleDefinitionList }>(
`Data/XML/item_defs/vehicles/${nation}/list.xml`
);
for (const tankKey in tanks.root) {
@@ -62,19 +56,19 @@ export async function tankIcons() {
const nationVehicleId = tank.id;
const id = (nationVehicleId << 8) + (NATION_IDS[nation] << 4) + 1;
const parameters = await readYAMLDVPL<TankParameters>(
`${DATA}/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`
const parameters = await vfs.yaml<TankParameters>(
`Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`
);
const smallPath = `${DATA}/${parameters.resourcesPath.smallIconPath
const smallPath = `Data/${parameters.resourcesPath.smallIconPath
.replace(/~res:\//, "")
.replace(/\..+/, "")}.packed.webp`;
const bigPath = `${DATA}/${parameters.resourcesPath.bigIconPath
const bigPath = `Data/${parameters.resourcesPath.bigIconPath
.replace(/~res:\//, "")
.replace(/\..+/, "")}.packed.webp`;
const big = await sharp(await readDVPLFile(bigPath))
const big = await sharp(await vfs.file(bigPath))
.trim()
.toBuffer();
const small = await sharp(await readDVPLFile(smallPath))
const small = await sharp(await vfs.file(smallPath))
.trim()
.toBuffer();
+7 -12
View File
@@ -1,12 +1,9 @@
import { toUniqueId } from "@blitzkit/core";
import { NodeIO } from "@gltf-transform/core";
import { ALL_EXTENSIONS } from "@gltf-transform/extensions";
import { readdir } from "fs/promises";
import { extractModel } from "../core/blitz/extractModel";
import { readXMLDVPL } from "../core/blitz/readXMLDVPL";
import { readYAMLDVPL } from "../core/blitz/readYAMLDVPL";
import { AssetUploader } from "../core/github/assetUploader";
import { DATA } from "./constants";
import { vfs } from "./constants";
import { VehicleDefinitionList } from "./definitions";
import { TankParameters } from "./tankIcons";
@@ -15,14 +12,12 @@ export async function tankModels() {
using uploader = new AssetUploader("tank models");
const nodeIO = new NodeIO().registerExtensions(ALL_EXTENSIONS);
const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then(
(nations) => nations.filter((nation) => nation !== "common")
);
const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common")
for (const nationIndex in nations) {
const nation = nations[nationIndex];
const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>(
`${DATA}/XML/item_defs/vehicles/${nation}/list.xml`
const tanks = await vfs.xml<{ root: VehicleDefinitionList }>(
`Data/XML/item_defs/vehicles/${nation}/list.xml`
);
const entries = Object.entries(tanks.root);
@@ -30,11 +25,11 @@ export async function tankModels() {
if (tankKey.includes("tutorial_bot")) continue;
const id = toUniqueId(nation, tank.id);
const parameters = await readYAMLDVPL<TankParameters>(
`${DATA}/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`
const parameters = await vfs.yaml<TankParameters>(
`Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`
);
const model = await extractModel(
DATA,
vfs,
parameters.resourcesPath.blitzModelPath.replace(/\.sc2$/, "")
);
const content = Buffer.from(await nodeIO.writeBinary(model));