mirror of
https://github.com/LCE-Hub/LCE-Emerald-Launcher.git
synced 2026-08-20 04:27:29 +00:00
110 lines
2.9 KiB
JavaScript
110 lines
2.9 KiB
JavaScript
#!/usr/bin/env node
|
|
import {
|
|
createWriteStream,
|
|
createReadStream,
|
|
existsSync,
|
|
unlinkSync,
|
|
} from "node:fs";
|
|
import { mkdir, rename } from "node:fs/promises";
|
|
import { createHash } from "node:crypto";
|
|
import { Readable } from "node:stream";
|
|
import { fileURLToPath } from "node:url";
|
|
import path from "node:path";
|
|
const RELEASE_TAG = "android-assets-v1";
|
|
const REPO = "LCE-Hub/LCE-Emerald-Launcher";
|
|
const ASSET_DIR = fileURLToPath(
|
|
new URL("../src-tauri/gen/android/app/src/main/assets/", import.meta.url),
|
|
);
|
|
|
|
const ASSETS = [
|
|
{
|
|
file: "imagefs.tar.zst",
|
|
sha256: "7838756e6a05c91afff68f4bf12aa2780f815877753f8dd354e203e99b9caf8a",
|
|
},
|
|
{
|
|
file: "proton-11.0-arm64ec.tar.zst",
|
|
sha256: "ceb768396c2d44256518f94ae236f0c1f40738cf050a52e990e2fef67ff161df",
|
|
},
|
|
];
|
|
|
|
function sha256File(file) {
|
|
return new Promise((resolve, reject) => {
|
|
const hash = createHash("sha256");
|
|
const stream = createReadStream(file);
|
|
stream.on("data", (chunk) => hash.update(chunk));
|
|
stream.on("end", () => resolve(hash.digest("hex")));
|
|
stream.on("error", reject);
|
|
});
|
|
}
|
|
|
|
async function download(url, dest) {
|
|
const res = await fetch(url, { redirect: "follow" });
|
|
if (!res.ok) {
|
|
throw new Error(`HTTP ${res.status} ${res.statusText} for ${url}`);
|
|
}
|
|
|
|
if (!res.body) {
|
|
throw new Error(`no response body for ${url}`);
|
|
}
|
|
|
|
const fileStream = createWriteStream(dest);
|
|
await new Promise((resolve, reject) => {
|
|
const body = Readable.fromWeb(res.body);
|
|
body.pipe(fileStream);
|
|
body.on("error", reject);
|
|
fileStream.on("finish", resolve);
|
|
fileStream.on("error", reject);
|
|
});
|
|
}
|
|
|
|
let failed = false;
|
|
for (const asset of ASSETS) {
|
|
const target = path.join(ASSET_DIR, asset.file);
|
|
if (existsSync(target)) {
|
|
const actual = await sha256File(target);
|
|
if (actual === asset.sha256) {
|
|
console.log(`okay ${asset.file} (up to date)`);
|
|
continue;
|
|
}
|
|
|
|
console.error(
|
|
`error ${asset.file}: sha256 mismatch (expected ${asset.sha256}, got ${actual}); delete it and rerun`,
|
|
);
|
|
|
|
failed = true;
|
|
continue;
|
|
}
|
|
|
|
const url = `https://github.com/${REPO}/releases/download/${RELEASE_TAG}/${asset.file}`;
|
|
console.log(`get ${asset.file} <- ${url}`);
|
|
await mkdir(path.dirname(target), { recursive: true });
|
|
const tmp = target + ".part";
|
|
try {
|
|
await download(url, tmp);
|
|
const actual = await sha256File(tmp);
|
|
if (actual !== asset.sha256) {
|
|
console.error(
|
|
`error ${asset.file}: downloaded sha256 mismatch (expected ${asset.sha256}, got ${actual})`,
|
|
);
|
|
|
|
failed = true;
|
|
if (existsSync(tmp)) {
|
|
unlinkSync(tmp);
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
await rename(tmp, target);
|
|
console.log(`okay ${asset.file} (downloaded)`);
|
|
} catch (error) {
|
|
console.error(`error ${asset.file}: ${error.message}`);
|
|
failed = true;
|
|
if (existsSync(tmp)) {
|
|
unlinkSync(tmp);
|
|
}
|
|
}
|
|
}
|
|
|
|
process.exit(failed ? 1 : 0);
|