From 2ffe3fc0064d61ad45f15be3f94fe401beb4ff41 Mon Sep 17 00:00:00 2001 From: tresabhi <43380238+tresabhi@users.noreply.github.com> Date: Mon, 22 Jun 2026 19:28:02 -0500 Subject: [PATCH] set up patches --- .github/workflows/assets.yml | 4 ++ docs/changelogs/1.30.4.md | 5 ++ package.json | 4 +- packages/scripts/src/applyPatches.ts | 31 ++++++------ packages/scripts/src/buildAssets/constants.ts | 5 ++ packages/scripts/src/core/vfs/mixed.ts | 49 +++++++++++++++++++ 6 files changed, 80 insertions(+), 18 deletions(-) create mode 100644 docs/changelogs/1.30.4.md create mode 100644 packages/scripts/src/core/vfs/mixed.ts diff --git a/.github/workflows/assets.yml b/.github/workflows/assets.yml index 222b45e9d..1cb21a5a1 100644 --- a/.github/workflows/assets.yml +++ b/.github/workflows/assets.yml @@ -73,10 +73,14 @@ jobs: with: repo-token: ${{ secrets.GH_TOKEN }} - uses: oven-sh/setup-bun@v2 + - run: bun run setup - name: AppArmor hack run: echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns + - name: Install patches + run: bun run setup:patches + - name: Build assets run: bun run build:assets --all-targets --source=${{ github.event.inputs.asset_source || 'steam:444200/444202' }} diff --git a/docs/changelogs/1.30.4.md b/docs/changelogs/1.30.4.md new file mode 100644 index 000000000..166a121cb --- /dev/null +++ b/docs/changelogs/1.30.4.md @@ -0,0 +1,5 @@ +# BlitzKit 1.30.3 + +## Fixes + +- BlitzKit now correctly implements minor WoTB updates diff --git a/package.json b/package.json index 3fa646324..4445a6b58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blitzkit", - "version": "1.30.3", + "version": "1.30.4", "license": "BlitzKit License", "private": true, "scripts": { @@ -21,7 +21,7 @@ "dev": "bun run dev:website", "dev:api": "bun --filter=@blitzkit/api run dev", "setup:depotdownloader": "bun --filter=@blitzkit/scripts run setup:depotdownloader", - "setup:patches": "bun --filter=@blitzkit/scripts run setup:patches", + "setup:patches": "cd packages/scripts && bun run setup:patches", "start:website": "bun --filter=@blitzkit/website run start", "host:docs": "vitepress preview docs", "lint": "tsc", diff --git a/packages/scripts/src/applyPatches.ts b/packages/scripts/src/applyPatches.ts index 7064ce932..5128b3e2d 100644 --- a/packages/scripts/src/applyPatches.ts +++ b/packages/scripts/src/applyPatches.ts @@ -4,7 +4,7 @@ import { mkdir, writeFile } from "fs/promises"; import { parse as parsePath } from "path"; import ProgressBar from "progress"; import { parse as parseYaml, stringify as stringifyYaml } from "yaml"; -import { vfs } from "./buildAssets/constants"; +import { PATCHES_ROOT, vfs } from "./buildAssets/constants"; import { writeDVPL } from "./core/blitz/writeDVPL"; const versionTextFile = await vfs.text(`Data/version.txt`); @@ -20,8 +20,8 @@ let patchIndex = 1; while (true) { const response = await fetch( `${assertSecret( - import.meta.env.WOTB_DLC_CDN - )}/dlc/s${currentVersion}_${patchIndex}.yaml` + import.meta.env.WOTB_DLC_CDN, + )}/dlc/s${currentVersion}_${patchIndex}.yaml`, ); if (response.status === 200) { @@ -29,18 +29,18 @@ while (true) { const data = parseYaml(await response.text()); const dvpm = await fetch( - `${assertSecret(import.meta.env.WOTB_DLC_CDN)}/dlc/${data.dx11}` + `${assertSecret(import.meta.env.WOTB_DLC_CDN)}/dlc/${data.dx11}`, ).then((response) => response.arrayBuffer()); const dvpd = await fetch( `${assertSecret(import.meta.env.WOTB_DLC_CDN)}/dlc/${data.dx11.replace( ".dvpm", - ".dvpd" - )}` + ".dvpd", + )}`, ).then((response) => response.arrayBuffer()); const files = await dvp(dvpm, dvpd); const bar = new ProgressBar( `Patching ${files.length} files :bar`, - files.length + files.length, ); for (const { path, data } of files) { @@ -49,7 +49,7 @@ while (true) { const { dir } = parsePath(path); try { - await mkdir(`Data/${dir}`, { recursive: true }); + await mkdir(`${PATCHES_ROOT}/Data/${dir}`, { recursive: true }); } catch (error) { console.warn(`Failed to make directory "${dir}"`); } @@ -58,8 +58,8 @@ while (true) { const buffer = Buffer.from(data); await writeFile( - `Data/${path}${isDvpl ? "" : ".dvpl"}`, - new Uint8Array(isDvpl ? buffer : writeDVPL(buffer)) + `${PATCHES_ROOT}/Data/${path}${isDvpl ? "" : ".dvpl"}`, + new Uint8Array(isDvpl ? buffer : writeDVPL(buffer)), ); bar.tick(); @@ -71,18 +71,17 @@ while (true) { const localizationsResponse = await fetch( `${assertSecret(import.meta.env.WOTB_DLC_CDN)}/dlc/${ data.dynamicContentLocalizationsDir - }/en.yaml` + }/en.yaml`, ); const newStrings = parseYaml(await localizationsResponse.text()); - const oldStrings = await vfs.yaml>( - `Data/Strings/en.yaml` - ); + const oldStrings = + await vfs.yaml>(`Data/Strings/en.yaml`); const patchedStrings = { ...oldStrings, ...newStrings }; const patchedContent = stringifyYaml(patchedStrings); await writeFile( - `Data/Strings/en.yaml`, - new Uint8Array(writeDVPL(Buffer.from(patchedContent))) + `${PATCHES_ROOT}/Data/Strings/en.yaml`, + new Uint8Array(writeDVPL(Buffer.from(patchedContent))), ); } diff --git a/packages/scripts/src/buildAssets/constants.ts b/packages/scripts/src/buildAssets/constants.ts index 7516210da..e6c37836e 100644 --- a/packages/scripts/src/buildAssets/constants.ts +++ b/packages/scripts/src/buildAssets/constants.ts @@ -3,6 +3,9 @@ import { AbstractVFS } from "../core/vfs/abstract"; import { LocalVFS } from "../core/vfs/local"; import { SteamVFS } from "../core/vfs/steam"; import { ZipVFS } from "../core/vfs/zip"; +import { MixedVFS } from "../core/vfs/mixed"; + +export const PATCHES_ROOT = "../../temp/patches"; const steamPattern = /steam:(\d+)\/(\d+)/; const zipPattern = /zip:(.+)/; @@ -35,4 +38,6 @@ if (!source) { throw new Error("No valid source specified"); } +resolved = new MixedVFS([new LocalVFS(PATCHES_ROOT), resolved]); + export const vfs = resolved; diff --git a/packages/scripts/src/core/vfs/mixed.ts b/packages/scripts/src/core/vfs/mixed.ts new file mode 100644 index 000000000..1d3358ddb --- /dev/null +++ b/packages/scripts/src/core/vfs/mixed.ts @@ -0,0 +1,49 @@ +import { AbstractVFS } from "./abstract"; + +export class MixedVFS extends AbstractVFS { + constructor(private vfses: AbstractVFS[]) { + super(); + } + + async init() { + for (const vfs of this.vfses) { + await vfs.init(); + } + + return this; + } + + dispose() { + for (const vfs of this.vfses) { + vfs.dispose(); + } + } + + async has(path: string) { + for (const vfs of this.vfses) { + if (await vfs.has(path)) return true; + } + + return false; + } + + async raw(path: string) { + for (const vfs of this.vfses) { + if (await vfs.has(path)) return await vfs.raw(path); + } + + throw new Error(`File not found: ${path}`); + } + + async dir(path: string) { + const files = new Set(); + + for (const vfs of this.vfses) { + for (const file of await vfs.dir(path)) { + files.add(file); + } + } + + return Array.from(files); + } +}