Files
blitzkit/packages/scripts/src/downloadClient/index.ts
T
2026-09-30 13:51:13 -05:00

100 lines
3.0 KiB
TypeScript

import { assertSecret } from "@blitzkit/core";
import { $ } from "bun";
import { mkdir, rm } from "node:fs/promises";
import {
DEPOT_DOWNLOADER_EXECUTABLE,
DEPOT_DOWNLOADER_MAX_DOWNLOADS,
DEPOT_DOWNLOADER_OUTPUT,
WGPKG_DIR,
} from "./constants";
import { QuickGitHubRelease } from "./types";
const provider = assertSecret(import.meta.env.CLIENT_PROVIDER);
const source = assertSecret(import.meta.env.CLIENT_SOURCE);
const dir = assertSecret(import.meta.env.CLIENT_DIR);
await rm(dir, { recursive: true, force: true });
await mkdir(dir, { recursive: true });
if (provider === "steam") {
const [id, platform] = source.split("/");
console.log("Downloading Depot Downloader...");
const releases = await fetch(
"https://api.github.com/repos/SteamRE/DepotDownloader/releases/latest",
).then((response) => response.json() as Promise<QuickGitHubRelease>);
const asset = releases.assets.find((asset) =>
asset.name.includes("linux-x64"),
);
if (!asset) {
throw new Error("No linux-x64 asset found for Steam DepotDownloader");
}
await rm(DEPOT_DOWNLOADER_OUTPUT, { recursive: true, force: true });
await $`curl -L "${asset.browser_download_url}" -o "${DEPOT_DOWNLOADER_OUTPUT}.zip"`;
await $`unzip "${DEPOT_DOWNLOADER_OUTPUT}.zip" -d "${DEPOT_DOWNLOADER_OUTPUT}"`;
await $`chmod +x "${DEPOT_DOWNLOADER_EXECUTABLE}"`;
console.log("Downloading client...");
const username = assertSecret(import.meta.env.STEAM_USERNAME);
const password = assertSecret(import.meta.env.STEAM_PASSWORD);
await $`${DEPOT_DOWNLOADER_EXECUTABLE} -os ${
platform
} -app ${id} -username ${username} -password ${
password
} -dir ${dir} -max-downloads ${DEPOT_DOWNLOADER_MAX_DOWNLOADS}`;
} else if (provider === "zip") {
const url = assertSecret(import.meta.env.CLIENT_SOURCE);
console.log("Downloading and extracting zipped client...");
await mkdir(dir, { recursive: true });
await $`curl -L "${url}" | bsdtar -xf- --strip-components=1 -C ${dir}`;
} else if (provider === "wgpkg") {
let index = 1;
const urls: string[] = [];
console.log("Discovering packages...");
while (true) {
const url = `${source}.${index.toString().padStart(3, "0")}`;
const response = await fetch(url);
if (response.status === 200) {
urls.push(url);
} else if (response.status === 404) {
break;
} else {
throw new Error(`Wargaming response error status: ${response.status}`);
}
index++;
}
console.log(`Downloading ${urls.length} packages...`);
await rm(WGPKG_DIR, { recursive: true, force: true });
await mkdir(WGPKG_DIR, { recursive: true });
const inputContent = urls
.map((url) => {
const name = url.split("/").pop()!;
return `${url}\n out=${name}\n dir=${WGPKG_DIR}`;
})
.join("\n");
await $`echo ${inputContent} | aria2c -j ${urls.length} -x 2 -s 2 -i -`;
const firstChunk = `${WGPKG_DIR}/${urls[0].split("/").pop()!}`;
await $`7z x "${firstChunk}" -o${dir} -y`;
await rm(WGPKG_DIR, { recursive: true });
} else {
throw new Error(`Unknown provider: ${provider}`);
}