mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: update all
This commit is contained in:
1 parent
3efe807e35
commit
a0bccc7973
21 files changed
+160
-306
No files matched your search
@@ -4,12 +4,10 @@ import { mkdir, writeFile } from "fs/promises";
|
|||||||
import { parse as parsePath } from "path";
|
import { parse as parsePath } from "path";
|
||||||
import ProgressBar from "progress";
|
import ProgressBar from "progress";
|
||||||
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
||||||
import { readStringDVPL } from "../src/core/blitz/readStringDVPL";
|
import { vfs } from "./buildAssets/constants";
|
||||||
import { DATA } from "./buildAssets/constants";
|
|
||||||
import { readYAMLDVPL } from "./core/blitz/readYAMLDVPL";
|
|
||||||
import { writeDVPL } from "./core/blitz/writeDVPL";
|
import { writeDVPL } from "./core/blitz/writeDVPL";
|
||||||
|
|
||||||
const versionTextFile = await readStringDVPL(`${DATA}/version.txt`);
|
const versionTextFile = await vfs.text(`Data/version.txt`);
|
||||||
const currentVersion = versionTextFile
|
const currentVersion = versionTextFile
|
||||||
.split(" ")[0]
|
.split(" ")[0]
|
||||||
.split(".")
|
.split(".")
|
||||||
@@ -51,7 +49,7 @@ while (true) {
|
|||||||
const { dir } = parsePath(path);
|
const { dir } = parsePath(path);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await mkdir(`${DATA}/${dir}`, { recursive: true });
|
await mkdir(`Data/${dir}`, { recursive: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`Failed to make directory "${dir}"`);
|
console.warn(`Failed to make directory "${dir}"`);
|
||||||
}
|
}
|
||||||
@@ -60,7 +58,7 @@ while (true) {
|
|||||||
const buffer = Buffer.from(data);
|
const buffer = Buffer.from(data);
|
||||||
|
|
||||||
await writeFile(
|
await writeFile(
|
||||||
`${DATA}/${path}${isDvpl ? "" : ".dvpl"}`,
|
`Data/${path}${isDvpl ? "" : ".dvpl"}`,
|
||||||
new Uint8Array(isDvpl ? buffer : writeDVPL(buffer))
|
new Uint8Array(isDvpl ? buffer : writeDVPL(buffer))
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -76,14 +74,14 @@ while (true) {
|
|||||||
}/en.yaml`
|
}/en.yaml`
|
||||||
);
|
);
|
||||||
const newStrings = parseYaml(await localizationsResponse.text());
|
const newStrings = parseYaml(await localizationsResponse.text());
|
||||||
const oldStrings = await readYAMLDVPL<Record<string, string>>(
|
const oldStrings = await vfs.yaml<Record<string, string>>(
|
||||||
`${DATA}/Strings/en.yaml`
|
`Data/Strings/en.yaml`
|
||||||
);
|
);
|
||||||
const patchedStrings = { ...oldStrings, ...newStrings };
|
const patchedStrings = { ...oldStrings, ...newStrings };
|
||||||
const patchedContent = stringifyYaml(patchedStrings);
|
const patchedContent = stringifyYaml(patchedStrings);
|
||||||
|
|
||||||
await writeFile(
|
await writeFile(
|
||||||
`${DATA}/Strings/en.yaml`,
|
`Data/Strings/en.yaml`,
|
||||||
new Uint8Array(writeDVPL(Buffer.from(patchedContent)))
|
new Uint8Array(writeDVPL(Buffer.from(patchedContent)))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,16 @@
|
|||||||
import { readdir } from "fs/promises";
|
|
||||||
import sharp from "sharp";
|
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 { AssetUploader } from "../core/github/assetUploader";
|
||||||
import { DATA } from "./constants";
|
import { vfs } from "./constants";
|
||||||
|
|
||||||
export async function boosterIcons() {
|
export async function boosterIcons() {
|
||||||
console.log("Building booster icons...");
|
console.log("Building booster icons...");
|
||||||
|
|
||||||
using uploader = new AssetUploader("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")
|
(file) => !file.includes("@2x.txt") && !file.startsWith("texture0")
|
||||||
);
|
);
|
||||||
const image = sharp(
|
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) {
|
for (const file of boosterFiles) {
|
||||||
@@ -21,7 +18,7 @@ export async function boosterIcons() {
|
|||||||
|
|
||||||
if (name === undefined) continue;
|
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("\n")[4]
|
||||||
.split(" ")
|
.split(" ")
|
||||||
.map(Number);
|
.map(Number);
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import { readDVPLFile } from "../../src/core/blitz/readDVPLFile";
|
|
||||||
import { AssetUploader } from "../core/github/assetUploader";
|
import { AssetUploader } from "../core/github/assetUploader";
|
||||||
import { DATA } from "./constants";
|
import { vfs } from "./constants";
|
||||||
|
|
||||||
export async function camouflageIcons() {
|
export async function camouflageIcons() {
|
||||||
console.log("Building camouflage icons...");
|
console.log("Building camouflage icons...");
|
||||||
|
|
||||||
using uploader = new AssetUploader("camo icons");
|
using uploader = new AssetUploader("camo icons");
|
||||||
const content = await readDVPLFile(
|
const content = await vfs.file(
|
||||||
`${DATA}/Gfx/UI/Hangar/IconCamouflage.packed.webp`
|
`Data/Gfx/UI/Hangar/IconCamouflage.packed.webp`
|
||||||
);
|
);
|
||||||
|
|
||||||
await uploader.add({ content, path: "icons/camo.webp" });
|
await uploader.add({ content, path: "icons/camo.webp" });
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
import { existsSync } from "fs";
|
|
||||||
import sharp from "sharp";
|
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 { AssetUploader } from "../core/github/assetUploader";
|
||||||
import { DATA } from "./constants";
|
import { vfs } from "./constants";
|
||||||
import { ConsumablesCommon, ProvisionsCommon } from "./definitions";
|
import { ConsumablesCommon, ProvisionsCommon } from "./definitions";
|
||||||
|
|
||||||
interface Mappings {
|
interface Mappings {
|
||||||
@@ -33,20 +28,20 @@ export async function consumableProvisionIcons() {
|
|||||||
styles.map(async (path) =>
|
styles.map(async (path) =>
|
||||||
Object.values(
|
Object.values(
|
||||||
(
|
(
|
||||||
await readYAMLDVPL<Mappings>(`${DATA}/${path}`)
|
await vfs.yaml<Mappings>(`Data/${path}`)
|
||||||
).StyleSheets
|
).StyleSheets
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
).then((array) => array.flat());
|
).then((array) => array.flat());
|
||||||
|
|
||||||
for (const match of (
|
for (const match of (
|
||||||
await readStringDVPL(
|
await vfs.text(
|
||||||
`${DATA}/XML/item_defs/vehicles/common/consumables/list.xml`
|
`Data/XML/item_defs/vehicles/common/consumables/list.xml`
|
||||||
)
|
)
|
||||||
).matchAll(listItemsPattern)) {
|
).matchAll(listItemsPattern)) {
|
||||||
const consumablesCommon = await readXMLDVPL<{
|
const consumablesCommon = await vfs.xml<{
|
||||||
root: ConsumablesCommon;
|
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)) {
|
for (const consumable of Object.values(consumablesCommon.root)) {
|
||||||
const styleSheet = styleSheets.find((styleSheet) =>
|
const styleSheet = styleSheets.find((styleSheet) =>
|
||||||
@@ -67,9 +62,9 @@ export async function consumableProvisionIcons() {
|
|||||||
.replace(".psd", "")
|
.replace(".psd", "")
|
||||||
.replace(".txt", "");
|
.replace(".txt", "");
|
||||||
|
|
||||||
if (existsSync(`${DATA}/${configPath}.packed.webp`)) {
|
if (vfs.has(`Data/${configPath}.packed.webp`)) {
|
||||||
const image = sharp(
|
const image = sharp(
|
||||||
await readDVPLFile(`${DATA}/${configPath}.packed.webp`)
|
await vfs.file(`Data/${configPath}.packed.webp`)
|
||||||
);
|
);
|
||||||
const content = await image.trim({ threshold: 100 }).toBuffer();
|
const content = await image.trim({ threshold: 100 }).toBuffer();
|
||||||
|
|
||||||
@@ -79,14 +74,14 @@ export async function consumableProvisionIcons() {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const consumablesTexture = sharp(
|
const consumablesTexture = sharp(
|
||||||
await readDVPLFile(
|
await vfs.file(
|
||||||
`${`${DATA}/${configPath}`
|
`${`Data/${configPath}`
|
||||||
.split("/")
|
.split("/")
|
||||||
.slice(0, -1)
|
.slice(0, -1)
|
||||||
.join("/")}/texture0.packed.webp`
|
.join("/")}/texture0.packed.webp`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
const sizes = (await readStringDVPL(`${DATA}/${configPath}.txt`))
|
const sizes = (await vfs.text(`Data/${configPath}.txt`))
|
||||||
.split("\n")[4]
|
.split("\n")[4]
|
||||||
.split(" ")
|
.split(" ")
|
||||||
.map(Number);
|
.map(Number);
|
||||||
@@ -109,13 +104,13 @@ export async function consumableProvisionIcons() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const match of (
|
for (const match of (
|
||||||
await readStringDVPL(
|
await vfs.text(
|
||||||
`${DATA}/XML/item_defs/vehicles/common/provisions/list.xml`
|
`Data/XML/item_defs/vehicles/common/provisions/list.xml`
|
||||||
)
|
)
|
||||||
).matchAll(listItemsPattern)) {
|
).matchAll(listItemsPattern)) {
|
||||||
const provisionsCommon = await readXMLDVPL<{
|
const provisionsCommon = await vfs.xml<{
|
||||||
root: ProvisionsCommon;
|
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)) {
|
for (const provision of Object.values(provisionsCommon.root)) {
|
||||||
const styleSheet = styleSheets.find((styleSheet) =>
|
const styleSheet = styleSheets.find((styleSheet) =>
|
||||||
@@ -136,9 +131,9 @@ export async function consumableProvisionIcons() {
|
|||||||
.replace(".psd", "")
|
.replace(".psd", "")
|
||||||
.replace(".txt", "");
|
.replace(".txt", "");
|
||||||
|
|
||||||
if (existsSync(`${DATA}/${configPath}.packed.webp`)) {
|
if (vfs.has(`Data/${configPath}.packed.webp`)) {
|
||||||
const image = sharp(
|
const image = sharp(
|
||||||
await readDVPLFile(`${DATA}/${configPath}.packed.webp`)
|
await vfs.file(`Data/${configPath}.packed.webp`)
|
||||||
);
|
);
|
||||||
const content = await image.trim({ threshold: 100 }).toBuffer();
|
const content = await image.trim({ threshold: 100 }).toBuffer();
|
||||||
|
|
||||||
@@ -148,14 +143,14 @@ export async function consumableProvisionIcons() {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const provisionsTexture = sharp(
|
const provisionsTexture = sharp(
|
||||||
await readDVPLFile(
|
await vfs.file(
|
||||||
`${`${DATA}/${configPath}`
|
`${`Data/${configPath}`
|
||||||
.split("/")
|
.split("/")
|
||||||
.slice(0, -1)
|
.slice(0, -1)
|
||||||
.join("/")}/texture0.packed.webp`
|
.join("/")}/texture0.packed.webp`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
const sizes = (await readStringDVPL(`${DATA}/${configPath}.txt`))
|
const sizes = (await vfs.text(`Data/${configPath}.txt`))
|
||||||
.split("\n")[4]
|
.split("\n")[4]
|
||||||
.split(" ")
|
.split(" ")
|
||||||
.map(Number);
|
.map(Number);
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { assertSecret, BlitzGlossary } from "@blitzkit/core";
|
import { assertSecret, BlitzGlossary } from "@blitzkit/core";
|
||||||
import sharp from "sharp";
|
import sharp from "sharp";
|
||||||
import { readDVPLFile } from "../../src/core/blitz/readDVPLFile";
|
|
||||||
import { AssetUploader } from "../core/github/assetUploader";
|
import { AssetUploader } from "../core/github/assetUploader";
|
||||||
import { DATA } from "./constants";
|
import { vfs } from "./constants";
|
||||||
|
|
||||||
const ICONS = [
|
const ICONS = [
|
||||||
["currency_silver_m.packed.webp", "silver"],
|
["currency_silver_m.packed.webp", "silver"],
|
||||||
@@ -21,7 +20,7 @@ export async function currencies() {
|
|||||||
|
|
||||||
for (const [file, name] of ICONS) {
|
for (const [file, name] of ICONS) {
|
||||||
const content = await sharp(
|
const content = await sharp(
|
||||||
await readDVPLFile(`${DATA}/Gfx/Lobby/currency/${file}`)
|
await vfs.file(`Data/Gfx/Lobby/currency/${file}`)
|
||||||
)
|
)
|
||||||
.trim()
|
.trim()
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
import sharp from "sharp";
|
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 { AssetUploader } from "../core/github/assetUploader";
|
||||||
import { DATA } from "./constants";
|
import { vfs } from "./constants";
|
||||||
import { OptionalDevices } from "./definitions";
|
import { OptionalDevices } from "./definitions";
|
||||||
|
|
||||||
interface Mappings {
|
interface Mappings {
|
||||||
@@ -20,15 +16,15 @@ export async function equipmentIcons() {
|
|||||||
console.log("Building equipment icons...");
|
console.log("Building equipment icons...");
|
||||||
|
|
||||||
using uploader = new AssetUploader("equipment icons");
|
using uploader = new AssetUploader("equipment icons");
|
||||||
const optionalDevices = await readXMLDVPL<{ root: OptionalDevices }>(
|
const optionalDevices = await vfs.xml<{ root: OptionalDevices }>(
|
||||||
`${DATA}/XML/item_defs/vehicles/common/optional_devices.xml`
|
`Data/XML/item_defs/vehicles/common/optional_devices.xml`
|
||||||
);
|
);
|
||||||
const mappings = await readYAMLDVPL<Mappings>(
|
const mappings = await vfs.yaml<Mappings>(
|
||||||
`${DATA}/UI/Screens3/Lobby/Inventory/OptionalDevices/OptionalDevicesItemImage.style.yaml`
|
`Data/UI/Screens3/Lobby/Inventory/OptionalDevices/OptionalDevicesItemImage.style.yaml`
|
||||||
);
|
);
|
||||||
const image = sharp(
|
const image = sharp(
|
||||||
await readDVPLFile(
|
await vfs.file(
|
||||||
`${DATA}/Gfx/UI/InventoryIcons/Big/OptionalDevices/texture0.packed.webp`
|
`Data/Gfx/UI/InventoryIcons/Big/OptionalDevices/texture0.packed.webp`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -54,7 +50,7 @@ export async function equipmentIcons() {
|
|||||||
if (configPath.startsWith("Gfx/Lobby")) {
|
if (configPath.startsWith("Gfx/Lobby")) {
|
||||||
const configPathWebp = configPath.replace(".txt", "");
|
const configPathWebp = configPath.replace(".txt", "");
|
||||||
const image = sharp(
|
const image = sharp(
|
||||||
await readDVPLFile(`${DATA}/${configPathWebp}.packed.webp`)
|
await vfs.file(`Data/${configPathWebp}.packed.webp`)
|
||||||
);
|
);
|
||||||
const content = await image.trim().toBuffer();
|
const content = await image.trim().toBuffer();
|
||||||
|
|
||||||
@@ -63,7 +59,7 @@ export async function equipmentIcons() {
|
|||||||
content,
|
content,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const config = await readStringDVPL(`${DATA}/${configPath}`);
|
const config = await vfs.text(`Data/${configPath}`);
|
||||||
const sizes = config.split("\n")[4].split(" ").map(Number);
|
const sizes = config.split("\n")[4].split(" ").map(Number);
|
||||||
const content = await image
|
const content = await image
|
||||||
.clone()
|
.clone()
|
||||||
|
|||||||
@@ -1,37 +1,28 @@
|
|||||||
import { readdir } from "fs/promises";
|
|
||||||
import sharp from "sharp";
|
import sharp from "sharp";
|
||||||
import { readDVPLFile } from "../core/blitz/readDVPLFile";
|
|
||||||
import { AssetUploader } from "../core/github/assetUploader";
|
import { AssetUploader } from "../core/github/assetUploader";
|
||||||
import { DATA } from "./constants";
|
import { vfs } from "./constants";
|
||||||
|
|
||||||
export async function flags() {
|
export async function flags() {
|
||||||
console.log("Building flags...");
|
console.log("Building flags...");
|
||||||
|
|
||||||
using uploader = new AssetUploader("flags");
|
using uploader = new AssetUploader("flags");
|
||||||
const circleFiles = await readdir(`${DATA}/Gfx/Lobby/flags`).then((files) =>
|
const circleFiles = vfs.dir(`Data/Gfx/Lobby/flags`).filter(
|
||||||
files.filter(
|
|
||||||
(flag) =>
|
(flag) =>
|
||||||
flag.startsWith("flag_profile-stat_") &&
|
flag.startsWith("flag_profile-stat_") &&
|
||||||
!flag.endsWith("@2x.packed.webp")
|
!flag.endsWith("@2x.packed.webp")
|
||||||
)
|
);
|
||||||
);
|
const scratchedFiles = vfs.dir(`Data/Gfx/Lobby/flags`).filter(
|
||||||
const scratchedFiles = await readdir(`${DATA}/Gfx/Lobby/flags`).then(
|
|
||||||
(files) =>
|
|
||||||
files.filter(
|
|
||||||
(flag) =>
|
(flag) =>
|
||||||
flag.startsWith("flag_tutor-tank_") &&
|
flag.startsWith("flag_tutor-tank_") &&
|
||||||
!flag.endsWith("@2x.packed.webp")
|
!flag.endsWith("@2x.packed.webp")
|
||||||
)
|
)
|
||||||
);
|
const fadedFiles = vfs.dir(`Data/Gfx/Lobby/flags`).filter(
|
||||||
const fadedFiles = await readdir(`${DATA}/Gfx/Lobby/flags`).then((files) =>
|
|
||||||
files.filter(
|
|
||||||
(flag) =>
|
(flag) =>
|
||||||
flag.startsWith("flag_filter_") && flag.endsWith("@2x.packed.webp")
|
flag.startsWith("flag_filter_") && flag.endsWith("@2x.packed.webp")
|
||||||
)
|
)
|
||||||
);
|
|
||||||
|
|
||||||
for (const flag of circleFiles) {
|
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 content = await image.trim({ threshold: 100 }).toBuffer();
|
||||||
const name = flag.match(/flag_profile-stat_(.+)\.packed\.webp/)![1];
|
const name = flag.match(/flag_profile-stat_(.+)\.packed\.webp/)![1];
|
||||||
|
|
||||||
@@ -42,7 +33,7 @@ export async function flags() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const flag of scratchedFiles) {
|
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];
|
const name = flag.match(/flag_tutor-tank_(.+)\.packed\.webp/)![1];
|
||||||
|
|
||||||
uploader.add({
|
uploader.add({
|
||||||
@@ -53,7 +44,7 @@ export async function flags() {
|
|||||||
|
|
||||||
for (const flag of fadedFiles) {
|
for (const flag of fadedFiles) {
|
||||||
const content = await sharp(
|
const content = await sharp(
|
||||||
await readDVPLFile(`${DATA}/Gfx/Lobby/flags/${flag}`)
|
await vfs.file(`Data/Gfx/Lobby/flags/${flag}`)
|
||||||
)
|
)
|
||||||
.trim({
|
.trim({
|
||||||
threshold: 100,
|
threshold: 100,
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
import sharp from "sharp";
|
import sharp from "sharp";
|
||||||
import { readDVPLFile } from "../../src/core/blitz/readDVPLFile";
|
|
||||||
import { readYAMLDVPL } from "../core/blitz/readYAMLDVPL";
|
|
||||||
import { AssetUploader } from "../core/github/assetUploader";
|
import { AssetUploader } from "../core/github/assetUploader";
|
||||||
import { DATA } from "./constants";
|
import { vfs } from "./constants";
|
||||||
import { SquadBattleTypeStyles } from "./definitions";
|
import { SquadBattleTypeStyles } from "./definitions";
|
||||||
|
|
||||||
export async function gameModeBanners() {
|
export async function gameModeBanners() {
|
||||||
console.log("Building game mode banners...");
|
console.log("Building game mode banners...");
|
||||||
|
|
||||||
using uploader = new AssetUploader("game mode banners");
|
using uploader = new AssetUploader("game mode banners");
|
||||||
const gameTypeSelectorStyles = await readYAMLDVPL<SquadBattleTypeStyles>(
|
const gameTypeSelectorStyles = await vfs.yaml<SquadBattleTypeStyles>(
|
||||||
`${DATA}/UI/Screens/Lobby/Hangar/GameTypeSelector.yaml`
|
`Data/UI/Screens/Lobby/Hangar/GameTypeSelector.yaml`
|
||||||
);
|
);
|
||||||
const squadBattleTypeStyles = await readYAMLDVPL<SquadBattleTypeStyles>(
|
const squadBattleTypeStyles = await vfs.yaml<SquadBattleTypeStyles>(
|
||||||
`${DATA}/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml`
|
`Data/UI/Screens3/Lobby/Hangar/Squad/SquadBattleType.yaml`
|
||||||
);
|
);
|
||||||
const bannerMatches: { name: string; path: string }[] = [];
|
const bannerMatches: { name: string; path: string }[] = [];
|
||||||
|
|
||||||
@@ -37,7 +35,7 @@ export async function gameModeBanners() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const content = await sharp(
|
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 } })
|
.trim({ background: { r: 0, g: 0, b: 0, alpha: 0 } })
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { toUniqueId } from "@blitzkit/core";
|
import { toUniqueId } from "@blitzkit/core";
|
||||||
import { readdir } from "fs/promises";
|
|
||||||
import { readXMLDVPL } from "../core/blitz/readXMLDVPL";
|
|
||||||
import { AssetUploader } from "../core/github/assetUploader";
|
import { AssetUploader } from "../core/github/assetUploader";
|
||||||
import { DATA } from "./constants";
|
import { vfs } from "./constants";
|
||||||
import { VehicleDefinitionList } from "./definitions";
|
import { VehicleDefinitionList } from "./definitions";
|
||||||
|
|
||||||
export async function migration() {
|
export async function migration() {
|
||||||
@@ -10,13 +8,11 @@ export async function migration() {
|
|||||||
|
|
||||||
using uploader = new AssetUploader("migration map");
|
using uploader = new AssetUploader("migration map");
|
||||||
const map: Record<string, number> = {};
|
const map: Record<string, number> = {};
|
||||||
const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then(
|
const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common");
|
||||||
(nations) => nations.filter((nation) => nation !== "common")
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const nation of nations) {
|
for (const nation of nations) {
|
||||||
const tankList = await readXMLDVPL<{ root: VehicleDefinitionList }>(
|
const tankList = await vfs.xml<{ root: VehicleDefinitionList }>(
|
||||||
`${DATA}/XML/item_defs/vehicles/${nation}/list.xml`
|
`Data/XML/item_defs/vehicles/${nation}/list.xml`
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const tankKey in tankList.root) {
|
for (const tankKey in tankList.root) {
|
||||||
|
|||||||
@@ -1,24 +1,20 @@
|
|||||||
import { readdir } from "fs/promises";
|
|
||||||
import sharp from "sharp";
|
import sharp from "sharp";
|
||||||
import { readDVPLFile } from "../../src/core/blitz/readDVPLFile";
|
|
||||||
import { AssetUploader } from "../core/github/assetUploader";
|
import { AssetUploader } from "../core/github/assetUploader";
|
||||||
import { DATA } from "./constants";
|
import { vfs } from "./constants";
|
||||||
|
|
||||||
export async function moduleIcons() {
|
export async function moduleIcons() {
|
||||||
console.log("Building module icons...");
|
console.log("Building module icons...");
|
||||||
|
|
||||||
using uploader = new AssetUploader("module icons");
|
using uploader = new AssetUploader("module icons");
|
||||||
const files = await readdir(`${DATA}/Gfx/UI/ModulesTechTree`).then((dir) =>
|
const files = vfs.dir(`Data/Gfx/UI/ModulesTechTree`).filter(
|
||||||
dir.filter(
|
|
||||||
(file) => !file.endsWith("@2x.packed.webp") && file.startsWith("vehicle")
|
(file) => !file.endsWith("@2x.packed.webp") && file.startsWith("vehicle")
|
||||||
)
|
)
|
||||||
);
|
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const nameRaw = file.match(/vehicle(.+)\.packed\.webp/)![1];
|
const nameRaw = file.match(/vehicle(.+)\.packed\.webp/)![1];
|
||||||
const name = nameRaw[0].toLowerCase() + nameRaw.slice(1);
|
const name = nameRaw[0].toLowerCase() + nameRaw.slice(1);
|
||||||
const content = await sharp(
|
const content = await sharp(
|
||||||
await readDVPLFile(`${DATA}/Gfx/UI/ModulesTechTree/${file}`)
|
await vfs.file(`Data/Gfx/UI/ModulesTechTree/${file}`)
|
||||||
)
|
)
|
||||||
.trim()
|
.trim()
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|||||||
@@ -1,28 +1,25 @@
|
|||||||
import { readdir } from "fs/promises";
|
|
||||||
import sharp from "sharp";
|
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 { AssetUploader } from "../core/github/assetUploader";
|
||||||
import { DATA } from "./constants";
|
import { vfs } from "./constants";
|
||||||
|
|
||||||
export async function shellIcons() {
|
export async function shellIcons() {
|
||||||
console.log("Building shell icons...");
|
console.log("Building shell icons...");
|
||||||
|
|
||||||
using uploader = new AssetUploader("shell icons");
|
using uploader = new AssetUploader("shell icons");
|
||||||
const image = sharp(
|
const image = sharp(
|
||||||
await readDVPLFile(
|
await vfs.file(
|
||||||
`${DATA}/Gfx/Shared/tank-supply/ammunition/big/texture0.packed.webp`
|
`Data/Gfx/Shared/tank-supply/ammunition/big/texture0.packed.webp`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
const files = await readdir(
|
const files = vfs.dir(
|
||||||
`${DATA}/Gfx/Shared/tank-supply/ammunition/big`
|
`Data/Gfx/Shared/tank-supply/ammunition/big`
|
||||||
).then((files) => files.filter((file) => file.endsWith("_l.txt")));
|
).filter((file) => file.endsWith("_l.txt"))
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const name = file.match(/(.+)_l\.txt/)![1];
|
const name = file.match(/(.+)_l\.txt/)![1];
|
||||||
const sizes = (
|
const sizes = (
|
||||||
await readStringDVPL(
|
await vfs.text(
|
||||||
`${DATA}/Gfx/Shared/tank-supply/ammunition/big/${file}`
|
`Data/Gfx/Shared/tank-supply/ammunition/big/${file}`
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.split("\n")[4]
|
.split("\n")[4]
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { TankClass } from "@blitzkit/core";
|
import { TankClass } from "@blitzkit/core";
|
||||||
import sharp from "sharp";
|
import sharp from "sharp";
|
||||||
import { readDVPLFile } from "../core/blitz/readDVPLFile";
|
|
||||||
import { readXMLDVPL } from "../core/blitz/readXMLDVPL";
|
|
||||||
import { AssetUploader } from "../core/github/assetUploader";
|
import { AssetUploader } from "../core/github/assetUploader";
|
||||||
import { DATA } from "./constants";
|
import { vfs } from "./constants";
|
||||||
|
|
||||||
interface SkillIcon {
|
interface SkillIcon {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -27,8 +25,8 @@ export interface Avatar {
|
|||||||
export async function skillIcons() {
|
export async function skillIcons() {
|
||||||
console.log("Building skill icons...");
|
console.log("Building skill icons...");
|
||||||
|
|
||||||
const avatar = await readXMLDVPL<{ root: Avatar }>(
|
const avatar = await vfs.xml<{ root: Avatar }>(
|
||||||
`${DATA}/XML/item_defs/tankmen/avatar.xml`
|
`Data/XML/item_defs/tankmen/avatar.xml`
|
||||||
);
|
);
|
||||||
using uploader = new AssetUploader("skill icons");
|
using uploader = new AssetUploader("skill icons");
|
||||||
|
|
||||||
@@ -36,8 +34,8 @@ export async function skillIcons() {
|
|||||||
const skill = avatar.root.skills[key];
|
const skill = avatar.root.skills[key];
|
||||||
const icon = Array.isArray(skill.icon) ? skill.icon[0] : skill.icon;
|
const icon = Array.isArray(skill.icon) ? skill.icon[0] : skill.icon;
|
||||||
const name = icon.name.split("/").at(-1)!.replace(/_\d$/, "");
|
const name = icon.name.split("/").at(-1)!.replace(/_\d$/, "");
|
||||||
const path = `${DATA}${icon.name.replace("~res:", "")}.packed.webp`;
|
const path = `Data${icon.name.replace("~res:", "")}.packed.webp`;
|
||||||
const image = sharp(await readDVPLFile(path)).trim();
|
const image = sharp(await vfs.file(path)).trim();
|
||||||
const content = await image.toBuffer();
|
const content = await image.toBuffer();
|
||||||
|
|
||||||
await uploader.add({ content, path: `icons/skills/${name}.webp` });
|
await uploader.add({ content, path: `icons/skills/${name}.webp` });
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import { toUniqueId } from "@blitzkit/core";
|
import { toUniqueId } from "@blitzkit/core";
|
||||||
import { NodeIO } from "@gltf-transform/core";
|
import { NodeIO } from "@gltf-transform/core";
|
||||||
import { readdir } from "fs/promises";
|
|
||||||
import { extractArmor } from "../core/blitz/extractArmor";
|
import { extractArmor } from "../core/blitz/extractArmor";
|
||||||
import { readXMLDVPL } from "../core/blitz/readXMLDVPL";
|
|
||||||
import { AssetUploader } from "../core/github/assetUploader";
|
import { AssetUploader } from "../core/github/assetUploader";
|
||||||
import { DATA } from "./constants";
|
import { vfs } from "./constants";
|
||||||
import { VehicleDefinitionList } from "./definitions";
|
import { VehicleDefinitionList } from "./definitions";
|
||||||
|
|
||||||
export async function tankArmors() {
|
export async function tankArmors() {
|
||||||
@@ -12,13 +10,11 @@ export async function tankArmors() {
|
|||||||
|
|
||||||
using uploader = new AssetUploader("tank armors");
|
using uploader = new AssetUploader("tank armors");
|
||||||
const nodeIO = new NodeIO();
|
const nodeIO = new NodeIO();
|
||||||
const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then(
|
const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common");
|
||||||
(nations) => nations.filter((nation) => nation !== "common")
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const nation of nations) {
|
for (const nation of nations) {
|
||||||
const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>(
|
const tanks = await vfs.xml<{ root: VehicleDefinitionList }>(
|
||||||
`${DATA}/XML/item_defs/vehicles/${nation}/list.xml`
|
`Data/XML/item_defs/vehicles/${nation}/list.xml`
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const tankKey in tanks.root) {
|
for (const tankKey in tanks.root) {
|
||||||
@@ -27,7 +23,7 @@ export async function tankArmors() {
|
|||||||
if (tankKey.includes("tutorial_bot")) continue;
|
if (tankKey.includes("tutorial_bot")) continue;
|
||||||
|
|
||||||
const id = toUniqueId(nation, tank.id);
|
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);
|
const content = await nodeIO.writeBinary(model);
|
||||||
|
|
||||||
await uploader.add({ path: `3d/tanks/armor/${id}.glb`, content });
|
await uploader.add({ path: `3d/tanks/armor/${id}.glb`, content });
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
import { NATION_IDS } from "@blitzkit/core";
|
import { NATION_IDS } from "@blitzkit/core";
|
||||||
import { readdir } from "fs/promises";
|
|
||||||
import sharp from "sharp";
|
import sharp from "sharp";
|
||||||
import type { Vector3Tuple } from "three";
|
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 { AssetUploader } from "../core/github/assetUploader";
|
||||||
import { DATA } from "./constants";
|
import { vfs } from "./constants";
|
||||||
import type { VehicleDefinitionList } from "./definitions";
|
import type { VehicleDefinitionList } from "./definitions";
|
||||||
|
|
||||||
export interface TankParameters {
|
export interface TankParameters {
|
||||||
@@ -45,13 +41,11 @@ export async function tankIcons() {
|
|||||||
console.log("Building tank icons...");
|
console.log("Building tank icons...");
|
||||||
|
|
||||||
using uploader = new AssetUploader("tank icons");
|
using uploader = new AssetUploader("tank icons");
|
||||||
const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then(
|
const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common")
|
||||||
(nations) => nations.filter((nation) => nation !== "common")
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const nation of nations) {
|
for (const nation of nations) {
|
||||||
const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>(
|
const tanks = await vfs.xml<{ root: VehicleDefinitionList }>(
|
||||||
`${DATA}/XML/item_defs/vehicles/${nation}/list.xml`
|
`Data/XML/item_defs/vehicles/${nation}/list.xml`
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const tankKey in tanks.root) {
|
for (const tankKey in tanks.root) {
|
||||||
@@ -62,19 +56,19 @@ export async function tankIcons() {
|
|||||||
const nationVehicleId = tank.id;
|
const nationVehicleId = tank.id;
|
||||||
const id = (nationVehicleId << 8) + (NATION_IDS[nation] << 4) + 1;
|
const id = (nationVehicleId << 8) + (NATION_IDS[nation] << 4) + 1;
|
||||||
|
|
||||||
const parameters = await readYAMLDVPL<TankParameters>(
|
const parameters = await vfs.yaml<TankParameters>(
|
||||||
`${DATA}/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`
|
`Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`
|
||||||
);
|
);
|
||||||
const smallPath = `${DATA}/${parameters.resourcesPath.smallIconPath
|
const smallPath = `Data/${parameters.resourcesPath.smallIconPath
|
||||||
.replace(/~res:\//, "")
|
.replace(/~res:\//, "")
|
||||||
.replace(/\..+/, "")}.packed.webp`;
|
.replace(/\..+/, "")}.packed.webp`;
|
||||||
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 readDVPLFile(bigPath))
|
const big = await sharp(await vfs.file(bigPath))
|
||||||
.trim()
|
.trim()
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
const small = await sharp(await readDVPLFile(smallPath))
|
const small = await sharp(await vfs.file(smallPath))
|
||||||
.trim()
|
.trim()
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
import { toUniqueId } from "@blitzkit/core";
|
import { toUniqueId } from "@blitzkit/core";
|
||||||
import { NodeIO } from "@gltf-transform/core";
|
import { NodeIO } from "@gltf-transform/core";
|
||||||
import { ALL_EXTENSIONS } from "@gltf-transform/extensions";
|
import { ALL_EXTENSIONS } from "@gltf-transform/extensions";
|
||||||
import { readdir } from "fs/promises";
|
|
||||||
import { extractModel } from "../core/blitz/extractModel";
|
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 { AssetUploader } from "../core/github/assetUploader";
|
||||||
import { DATA } from "./constants";
|
import { vfs } from "./constants";
|
||||||
import { VehicleDefinitionList } from "./definitions";
|
import { VehicleDefinitionList } from "./definitions";
|
||||||
import { TankParameters } from "./tankIcons";
|
import { TankParameters } from "./tankIcons";
|
||||||
|
|
||||||
@@ -15,14 +12,12 @@ export async function tankModels() {
|
|||||||
|
|
||||||
using uploader = new AssetUploader("tank models");
|
using uploader = new AssetUploader("tank models");
|
||||||
const nodeIO = new NodeIO().registerExtensions(ALL_EXTENSIONS);
|
const nodeIO = new NodeIO().registerExtensions(ALL_EXTENSIONS);
|
||||||
const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then(
|
const nations = vfs.dir(`Data/XML/item_defs/vehicles`).filter((nation) => nation !== "common")
|
||||||
(nations) => nations.filter((nation) => nation !== "common")
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const nationIndex in nations) {
|
for (const nationIndex in nations) {
|
||||||
const nation = nations[nationIndex];
|
const nation = nations[nationIndex];
|
||||||
const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>(
|
const tanks = await vfs.xml<{ root: VehicleDefinitionList }>(
|
||||||
`${DATA}/XML/item_defs/vehicles/${nation}/list.xml`
|
`Data/XML/item_defs/vehicles/${nation}/list.xml`
|
||||||
);
|
);
|
||||||
const entries = Object.entries(tanks.root);
|
const entries = Object.entries(tanks.root);
|
||||||
|
|
||||||
@@ -30,11 +25,11 @@ export async function tankModels() {
|
|||||||
if (tankKey.includes("tutorial_bot")) continue;
|
if (tankKey.includes("tutorial_bot")) continue;
|
||||||
|
|
||||||
const id = toUniqueId(nation, tank.id);
|
const id = toUniqueId(nation, tank.id);
|
||||||
const parameters = await readYAMLDVPL<TankParameters>(
|
const parameters = await vfs.yaml<TankParameters>(
|
||||||
`${DATA}/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`
|
`Data/3d/Tanks/Parameters/${nation}/${tankKey}.yaml`
|
||||||
);
|
);
|
||||||
const model = await extractModel(
|
const model = await extractModel(
|
||||||
DATA,
|
vfs,
|
||||||
parameters.resourcesPath.blitzModelPath.replace(/\.sc2$/, "")
|
parameters.resourcesPath.blitzModelPath.replace(/\.sc2$/, "")
|
||||||
);
|
);
|
||||||
const content = Buffer.from(await nodeIO.writeBinary(model));
|
const content = Buffer.from(await nodeIO.writeBinary(model));
|
||||||
|
|||||||
@@ -2,24 +2,24 @@ import {
|
|||||||
Hierarchy,
|
Hierarchy,
|
||||||
Sc2ReadStream,
|
Sc2ReadStream,
|
||||||
ScgReadStream,
|
ScgReadStream,
|
||||||
|
SteamVFS,
|
||||||
VertexAttribute,
|
VertexAttribute,
|
||||||
} from '@blitzkit/core';
|
} from "@blitzkit/core";
|
||||||
import { Accessor, Document, Node, Scene } from '@gltf-transform/core';
|
import { Accessor, Document, Node, Scene } from "@gltf-transform/core";
|
||||||
import { times } from 'lodash-es';
|
import { times } from "lodash-es";
|
||||||
import {
|
import {
|
||||||
vertexAttributeGLTFName,
|
vertexAttributeGLTFName,
|
||||||
vertexAttributeGltfVectorSizes,
|
vertexAttributeGltfVectorSizes,
|
||||||
} from './extractModel/constants';
|
} from "./extractModel/constants";
|
||||||
import { readDVPLFile } from './readDVPLFile';
|
|
||||||
|
|
||||||
export async function extractArmor(data: string, fileName: string) {
|
export async function extractArmor(vfs: SteamVFS, fileName: string) {
|
||||||
const sc2Path = `${data}/3d/Tanks/CollisionMeshes/${fileName}.sc2`;
|
const sc2Path = `Data/3d/Tanks/CollisionMeshes/${fileName}.sc2`;
|
||||||
const scgPath = `${data}/3d/Tanks/CollisionMeshes/${fileName}.scg`;
|
const scgPath = `Data/3d/Tanks/CollisionMeshes/${fileName}.scg`;
|
||||||
const sc2 = new Sc2ReadStream(
|
const sc2 = new Sc2ReadStream(
|
||||||
(await readDVPLFile(sc2Path)).buffer as ArrayBuffer,
|
(await vfs.file(sc2Path)).buffer as ArrayBuffer
|
||||||
).sc2();
|
).sc2();
|
||||||
const scg = new ScgReadStream(
|
const scg = new ScgReadStream(
|
||||||
(await readDVPLFile(scgPath)).buffer as ArrayBuffer,
|
(await vfs.file(scgPath)).buffer as ArrayBuffer
|
||||||
).scg();
|
).scg();
|
||||||
const document = new Document();
|
const document = new Document();
|
||||||
const scene = document.createScene();
|
const scene = document.createScene();
|
||||||
@@ -29,21 +29,21 @@ export async function extractArmor(data: string, fileName: string) {
|
|||||||
hierarchies.forEach((hierarchy) => {
|
hierarchies.forEach((hierarchy) => {
|
||||||
const components = times(
|
const components = times(
|
||||||
hierarchy.components.count,
|
hierarchy.components.count,
|
||||||
(index) => hierarchy.components[index.toString().padStart(4, '0')],
|
(index) => hierarchy.components[index.toString().padStart(4, "0")]
|
||||||
);
|
);
|
||||||
|
|
||||||
components.forEach((component) => {
|
components.forEach((component) => {
|
||||||
switch (component['comp.typename']) {
|
switch (component["comp.typename"]) {
|
||||||
case 'TransformComponent':
|
case "TransformComponent":
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'RenderComponent': {
|
case "RenderComponent": {
|
||||||
const batch = component['rc.renderObj']['ro.batches']['0000'];
|
const batch = component["rc.renderObj"]["ro.batches"]["0000"];
|
||||||
const polygonGroup = scg.get(batch['rb.datasource']);
|
const polygonGroup = scg.get(batch["rb.datasource"]);
|
||||||
|
|
||||||
if (!polygonGroup) {
|
if (!polygonGroup) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`Missing polygon group ${batch['rb.datasource']} (${hierarchy.name}); skipping...`,
|
`Missing polygon group ${batch["rb.datasource"]} (${hierarchy.name}); skipping...`
|
||||||
);
|
);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -73,7 +73,7 @@ export async function extractArmor(data: string, fileName: string) {
|
|||||||
VertexAttribute.TANGENT,
|
VertexAttribute.TANGENT,
|
||||||
attributes
|
attributes
|
||||||
.get(VertexAttribute.TANGENT)!
|
.get(VertexAttribute.TANGENT)!
|
||||||
.map((tangent) => [...tangent, 1]),
|
.map((tangent) => [...tangent, 1])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ export async function extractArmor(data: string, fileName: string) {
|
|||||||
const vertexSize = vertexAttributeGltfVectorSizes[attribute];
|
const vertexSize = vertexAttributeGltfVectorSizes[attribute];
|
||||||
const accessor = document
|
const accessor = document
|
||||||
.createAccessor(name)
|
.createAccessor(name)
|
||||||
.setType(vertexSize === 1 ? 'SCALAR' : `VEC${vertexSize}`)
|
.setType(vertexSize === 1 ? "SCALAR" : `VEC${vertexSize}`)
|
||||||
.setArray(new Float32Array(value.flat()))
|
.setArray(new Float32Array(value.flat()))
|
||||||
.setBuffer(buffer);
|
.setBuffer(buffer);
|
||||||
|
|
||||||
@@ -94,19 +94,19 @@ export async function extractArmor(data: string, fileName: string) {
|
|||||||
|
|
||||||
hardJointIndices.forEach((hardJointIndex) => {
|
hardJointIndices.forEach((hardJointIndex) => {
|
||||||
const node = document.createNode(
|
const node = document.createNode(
|
||||||
`${hierarchy.name}_armor_${hardJointIndex}`,
|
`${hierarchy.name}_armor_${hardJointIndex}`
|
||||||
);
|
);
|
||||||
const mesh = document.createMesh(batch['##name']);
|
const mesh = document.createMesh(batch["##name"]);
|
||||||
const indicesAccessor = document
|
const indicesAccessor = document
|
||||||
.createAccessor()
|
.createAccessor()
|
||||||
.setType('SCALAR')
|
.setType("SCALAR")
|
||||||
.setArray(
|
.setArray(
|
||||||
new Uint16Array(
|
new Uint16Array(
|
||||||
polygonGroup.indices.filter(
|
polygonGroup.indices.filter(
|
||||||
(index) =>
|
(index) =>
|
||||||
vertexHardJointIndices.get(index) === hardJointIndex,
|
vertexHardJointIndices.get(index) === hardJointIndex
|
||||||
),
|
)
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
.setBuffer(buffer);
|
.setBuffer(buffer);
|
||||||
const primitive = document
|
const primitive = document
|
||||||
@@ -127,18 +127,18 @@ export async function extractArmor(data: string, fileName: string) {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
throw new TypeError(
|
throw new TypeError(
|
||||||
`Unhandled component type: ${component['comp.typename']}`,
|
`Unhandled component type: ${component["comp.typename"]}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (hierarchy['#hierarchy']) {
|
if (hierarchy["#hierarchy"]) {
|
||||||
parseHierarchies(hierarchy['#hierarchy'], parent);
|
parseHierarchies(hierarchy["#hierarchy"], parent);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
parseHierarchies(sc2['#hierarchy'], scene);
|
parseHierarchies(sc2["#hierarchy"], scene);
|
||||||
|
|
||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
Hierarchy,
|
Hierarchy,
|
||||||
Sc2ReadStream,
|
Sc2ReadStream,
|
||||||
ScgReadStream,
|
ScgReadStream,
|
||||||
|
SteamVFS,
|
||||||
Textures,
|
Textures,
|
||||||
VertexAttribute,
|
VertexAttribute,
|
||||||
} from "@blitzkit/core";
|
} from "@blitzkit/core";
|
||||||
@@ -10,7 +11,6 @@ import { dedup, prune } from "@gltf-transform/functions";
|
|||||||
import { times } from "lodash-es";
|
import { times } from "lodash-es";
|
||||||
import { dirname } from "path";
|
import { dirname } from "path";
|
||||||
import { readBaseColor } from "../readBaseColor";
|
import { readBaseColor } from "../readBaseColor";
|
||||||
import { readDVPLFile } from "../readDVPLFile";
|
|
||||||
import { readNormal } from "../readNormal";
|
import { readNormal } from "../readNormal";
|
||||||
import { readRoughnessMetallic } from "../readRoughnessMetallic";
|
import { readRoughnessMetallic } from "../readRoughnessMetallic";
|
||||||
import {
|
import {
|
||||||
@@ -25,14 +25,14 @@ const omitMeshNames = {
|
|||||||
end: ["_POINT"],
|
end: ["_POINT"],
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function extractModel(data: string, path: string) {
|
export async function extractModel(vfs: SteamVFS, path: string) {
|
||||||
const sc2Path = `${data}/3d/${path}.sc2`;
|
const sc2Path = `Data/3d/${path}.sc2`;
|
||||||
const scgPath = `${data}/3d/${path}.scg`;
|
const scgPath = `Data/3d/${path}.scg`;
|
||||||
const sc2 = new Sc2ReadStream(
|
const sc2 = new Sc2ReadStream(
|
||||||
(await readDVPLFile(sc2Path)).buffer as ArrayBuffer
|
(await vfs.file(sc2Path)).buffer as ArrayBuffer
|
||||||
).sc2();
|
).sc2();
|
||||||
const scg = new ScgReadStream(
|
const scg = new ScgReadStream(
|
||||||
(await readDVPLFile(scgPath)).buffer as ArrayBuffer
|
(await vfs.file(scgPath)).buffer as ArrayBuffer
|
||||||
).scg();
|
).scg();
|
||||||
const document = new Document();
|
const document = new Document();
|
||||||
const scene = document.createScene();
|
const scene = document.createScene();
|
||||||
@@ -67,11 +67,11 @@ export async function extractModel(data: string, path: string) {
|
|||||||
.setMimeType("image/webp")
|
.setMimeType("image/webp")
|
||||||
.setImage(
|
.setImage(
|
||||||
await readBaseColor(
|
await readBaseColor(
|
||||||
`${data}/3d/${dirname(path)}/${
|
`Data/3d/${dirname(path)}/${
|
||||||
textures.baseColorMap ?? textures.albedo
|
textures.baseColorMap ?? textures.albedo
|
||||||
}`,
|
}`,
|
||||||
textures.miscMap
|
textures.miscMap
|
||||||
? `${data}/3d/${dirname(path)}/${textures.miscMap}`
|
? `Data/3d/${dirname(path)}/${textures.miscMap}`
|
||||||
: undefined
|
: undefined
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -103,7 +103,7 @@ export async function extractModel(data: string, path: string) {
|
|||||||
.setMimeType("image/webp")
|
.setMimeType("image/webp")
|
||||||
.setImage(
|
.setImage(
|
||||||
await readRoughnessMetallic(
|
await readRoughnessMetallic(
|
||||||
`${data}/3d/${dirname(path)}/${textures.baseRMMap}`
|
`Data/3d/${dirname(path)}/${textures.baseRMMap}`
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -118,7 +118,7 @@ export async function extractModel(data: string, path: string) {
|
|||||||
.setMimeType("image/webp")
|
.setMimeType("image/webp")
|
||||||
.setImage(
|
.setImage(
|
||||||
await readNormal(
|
await readNormal(
|
||||||
`${data}/3d/${dirname(path)}/${
|
`Data/3d/${dirname(path)}/${
|
||||||
textures.baseNormalMap ?? textures.normalmap
|
textures.baseNormalMap ?? textures.normalmap
|
||||||
}`,
|
}`,
|
||||||
isBase
|
isBase
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
import { readDVPLFile } from './readDVPLFile';
|
|
||||||
|
|
||||||
export async function readBase64DVPL(file: string) {
|
|
||||||
const buffer = await readDVPLFile(file);
|
|
||||||
return buffer.toString('base64');
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import { readFile } from 'fs/promises';
|
|
||||||
import { DATA_COMPRESSED } from '../../buildAssets/constants';
|
|
||||||
import { readDVPL } from './readDVPL';
|
|
||||||
|
|
||||||
export async function readDVPLFile(file: string) {
|
|
||||||
let path: string;
|
|
||||||
|
|
||||||
if (DATA_COMPRESSED) {
|
|
||||||
path = file.endsWith('.dvpl') ? file : `${file}.dvpl`;
|
|
||||||
} else {
|
|
||||||
path = file.replace('.dvpl', '');
|
|
||||||
}
|
|
||||||
|
|
||||||
const content = await readFile(path);
|
|
||||||
|
|
||||||
if (!DATA_COMPRESSED) return content;
|
|
||||||
|
|
||||||
const dvpl = readDVPL(content);
|
|
||||||
|
|
||||||
return dvpl;
|
|
||||||
}
|
|
||||||
@@ -1,81 +1,17 @@
|
|||||||
import { DdsReadStream, PvrReadStream } from "@blitzkit/core";
|
import { DdsReadStream, PvrReadStream } from "@blitzkit/core";
|
||||||
import { existsSync } from "fs";
|
import { vfs } from "../../../buildAssets/constants";
|
||||||
import { DATA_COMPRESSED } from "../../../buildAssets/constants";
|
|
||||||
import { readDVPLFile } from "../readDVPLFile";
|
|
||||||
|
|
||||||
export async function readTexture(path: string) {
|
export async function readTexture(path: string) {
|
||||||
const ddsTexturePath = path.replace(".tex", ".dx11.dds");
|
const ddsTexturePath = path.replace(".tex", ".dx11.dds");
|
||||||
const isDds = existsSync(
|
const isDds = vfs.has(ddsTexturePath);
|
||||||
`${ddsTexturePath}${DATA_COMPRESSED ? ".dvpl" : ""}`
|
|
||||||
);
|
|
||||||
const resolvedTexturePath = isDds
|
const resolvedTexturePath = isDds
|
||||||
? ddsTexturePath
|
? ddsTexturePath
|
||||||
: ddsTexturePath.replace(".dds", ".pvr");
|
: ddsTexturePath.replace(".dds", ".pvr");
|
||||||
const decompressedDvpl = await readDVPLFile(`${resolvedTexturePath}.dvpl`);
|
const decompressedDvpl = await vfs.file(`${resolvedTexturePath}.dvpl`);
|
||||||
|
|
||||||
const raw = isDds
|
const raw = isDds
|
||||||
? await new DdsReadStream(decompressedDvpl.buffer as ArrayBuffer).dds()
|
? await new DdsReadStream(decompressedDvpl.buffer as ArrayBuffer).dds()
|
||||||
: new PvrReadStream(decompressedDvpl.buffer as ArrayBuffer).pvr();
|
: new PvrReadStream(decompressedDvpl.buffer as ArrayBuffer).pvr();
|
||||||
|
|
||||||
return raw;
|
return raw;
|
||||||
|
|
||||||
// switch (mutation) {
|
|
||||||
// case TextureMutation.Normal: {
|
|
||||||
// const bytes = 4 * raw.width * raw.height;
|
|
||||||
// for (let index = 0; index < bytes; index += 4) {
|
|
||||||
// /**
|
|
||||||
// * Red is always 255 and blue is always 0. Only alpha and green contain any
|
|
||||||
// * sort of information.
|
|
||||||
// */
|
|
||||||
// let x = raw.data[index + 3] * (2 / 255) - 1;
|
|
||||||
// let y = raw.data[index + 1] * (2 / 255) - 1;
|
|
||||||
// const underSqrt = 1 - x ** 2 - y ** 2;
|
|
||||||
// let z = underSqrt > 0 ? Math.sqrt(underSqrt) : -Math.sqrt(-underSqrt);
|
|
||||||
|
|
||||||
// raw.data[index] = Math.round((x + 1) * (255 / 2));
|
|
||||||
// raw.data[index + 1] = Math.round((y + 1) * (255 / 2));
|
|
||||||
// raw.data[index + 2] = Math.round((z + 1) * (255 / 2));
|
|
||||||
// raw.data[index + 3] = 255;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return await sharp(raw.data, { raw }).jpeg().toBuffer();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// case TextureMutation.RoughnessMetallicness: {
|
|
||||||
// const newImage = sharp(Buffer.alloc(raw.width * raw.height), {
|
|
||||||
// raw: { ...raw, channels: 1 },
|
|
||||||
// });
|
|
||||||
// const metallicness = sharp(raw.data, { raw })
|
|
||||||
// .extractChannel("green")
|
|
||||||
// .jpeg()
|
|
||||||
// .toBuffer();
|
|
||||||
// const roughness = sharp(raw.data, { raw })
|
|
||||||
// .extractChannel("alpha")
|
|
||||||
// .jpeg()
|
|
||||||
// .toBuffer();
|
|
||||||
|
|
||||||
// return await newImage
|
|
||||||
// .joinChannel(await Promise.all([roughness, metallicness]))
|
|
||||||
// .jpeg()
|
|
||||||
// .toBuffer();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// case TextureMutation.Miscellaneous: {
|
|
||||||
// /**
|
|
||||||
// * Alpha is ambient occlusion and green is emissive. But very few tanks
|
|
||||||
// * use emissive so I am ignoring it for now.
|
|
||||||
// */
|
|
||||||
// return await sharp(raw.data, { raw })
|
|
||||||
// .extractChannel("alpha")
|
|
||||||
// .jpeg()
|
|
||||||
// .toBuffer();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// case TextureMutation.Albedo: {
|
|
||||||
// return await sharp(raw.data, { raw }).removeAlpha().jpeg().toBuffer();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// default:
|
|
||||||
// return await sharp(raw.data, { raw }).jpeg().toBuffer();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
@@ -1,39 +1,39 @@
|
|||||||
import decompress from 'decompress';
|
import decompress from "decompress";
|
||||||
import { existsSync } from 'fs';
|
import { existsSync } from "fs";
|
||||||
import { mkdir, readdir, writeFile } from 'fs/promises';
|
import { mkdir, readdir, writeFile } from "fs/promises";
|
||||||
|
|
||||||
if (!existsSync('../../temp')) {
|
if (!existsSync("../../temp")) {
|
||||||
console.log('Creating temp directory...');
|
console.log("Creating temp directory...");
|
||||||
await mkdir('../../temp');
|
await mkdir("../../temp");
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Downloading depot downloader...');
|
console.log("Downloading depot downloader...");
|
||||||
await fetch(
|
await fetch(
|
||||||
'https://api.github.com/repos/SteamRE/DepotDownloader/releases/latest',
|
"https://api.github.com/repos/SteamRE/DepotDownloader/releases/latest"
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
(response) =>
|
(response) =>
|
||||||
response.json() as Promise<{
|
response.json() as Promise<{
|
||||||
assets: { browser_download_url: string; name: string }[];
|
assets: { browser_download_url: string; name: string }[];
|
||||||
}>,
|
}>
|
||||||
)
|
)
|
||||||
.then(({ assets }) => {
|
.then(({ assets }) => {
|
||||||
const asset = assets.find(({ name }) => name.includes('linux-x64'));
|
const asset = assets.find(({ name }) => name.includes("linux-x64"));
|
||||||
if (!asset) throw new Error('No asset found');
|
if (!asset) throw new Error("No asset found");
|
||||||
return fetch(asset.browser_download_url);
|
return fetch(asset.browser_download_url);
|
||||||
})
|
})
|
||||||
.then((response) => response.arrayBuffer())
|
.then((response) => response.arrayBuffer())
|
||||||
.then((arrayBuffer) =>
|
.then((arrayBuffer) =>
|
||||||
writeFile('../../temp/depotDownloader.zip', new Uint8Array(arrayBuffer)),
|
writeFile("../../temp/depotDownloader.zip", new Uint8Array(arrayBuffer))
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log('Unzipping...');
|
console.log("Unzipping...");
|
||||||
await decompress(
|
await decompress(
|
||||||
'../../temp/depotDownloader.zip',
|
"../../temp/depotDownloader.zip",
|
||||||
'../../temp/depotDownloader',
|
"../../temp/depotDownloader"
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
'Download complete; files:',
|
"Download complete; files:",
|
||||||
await readdir('../../temp/depotDownloader'),
|
await readdir("../../temp/depotDownloader")
|
||||||
);
|
);
|
||||||
Reference in new issue
Block a user