fix: bypass js-dos bundleUpdateConfig by providing config + initFs separately
Build & Deploy / build-and-deploy (push) Successful in 1m16s
Build & Deploy / build-and-deploy (push) Successful in 1m16s
js-dos v8.3.8 calls bundleUpdateConfig which uses libzip WASM to
re-add .jsdos/jsdos.json into the downloaded bundle. This fails on
our bundles (Unable to add .jsdos/jsdos.json into bundle.zip).
Fix: Instead of using { url } option (which triggers bundleUpdateConfig),
fetch the config from a new API endpoint (/api/games/{id}/config) and
pass it directly via { dosboxConf, jsdosConf, initFs }. This bypasses
the broken bundleUpdateConfig entirely.
Changes:
- New GET /api/games/{id}/config endpoint (GameResource + GameService)
- Exposed resolveCdImages/pickBestCdImage as package-private
- Frontend Play.svelte: fetch config + bundle separately, use new API
- Frontend api.js: new getGameConfig() function
This commit is contained in:
@@ -111,6 +111,16 @@ export function bundleUrl(game) {
|
||||
return `/games/${game.bundle_file}`;
|
||||
}
|
||||
|
||||
/** Get game config (dosbox.conf + jsdos.json) */
|
||||
export async function getGameConfig(id) {
|
||||
const res = await fetch(`${BASE}/api/games/${id}/config`);
|
||||
if (!res.ok) {
|
||||
const err = await res.json().catch(() => ({ error: res.statusText }));
|
||||
throw new Error(err.error || `HTTP ${res.status}`);
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
/** Get game bundle URL for setup mode (runs SETUP.EXE instead) */
|
||||
export function setupBundleUrl(game) {
|
||||
if (!game) return null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import { getGame, bundleUrl, setupBundleUrl } from "../lib/api.js";
|
||||
import { getGame, getGameConfig, bundleUrl, setupBundleUrl } from "../lib/api.js";
|
||||
import { push } from "../lib/router.js";
|
||||
|
||||
let { id } = $props();
|
||||
@@ -68,9 +68,27 @@
|
||||
|
||||
// Start the DOS emulator
|
||||
try {
|
||||
const url = isSetup ? setupBundleUrl(game) : bundleUrl(game);
|
||||
if (!url || !window.Dos) throw new Error("Failed to resolve game bundle");
|
||||
dosCI = await window.Dos(dosContainer, { url });
|
||||
if (isSetup) {
|
||||
// Setup mode: use the streaming setup-bundle endpoint
|
||||
const url = setupBundleUrl(game);
|
||||
if (!url || !window.Dos) throw new Error("Failed to resolve game bundle");
|
||||
dosCI = await window.Dos(dosContainer, { url });
|
||||
} else {
|
||||
// Normal mode: fetch config + bundle separately, use dosboxConf + initFs
|
||||
// This bypasses js-dos's bundleUpdateConfig which fails on our bundles
|
||||
const [config, bundleResp] = await Promise.all([
|
||||
getGameConfig(game.id),
|
||||
fetch(bundleUrl(game)),
|
||||
]);
|
||||
if (!bundleResp.ok) throw new Error("Failed to download game bundle");
|
||||
const bundle = new Uint8Array(await bundleResp.arrayBuffer());
|
||||
const jsdosConf = config.jsdos_conf ? JSON.parse(config.jsdos_conf) : undefined;
|
||||
dosCI = await window.Dos(dosContainer, {
|
||||
dosboxConf: config.dosbox_conf,
|
||||
jsdosConf,
|
||||
initFs: bundle,
|
||||
});
|
||||
}
|
||||
running = true;
|
||||
} catch (e) {
|
||||
error = e.message;
|
||||
|
||||
Reference in New Issue
Block a user