fix: pin js-dos to v8.3.14 (emulators 8.3.3) — the last working CDN version
Build & Deploy / build-and-deploy (push) Successful in 1m0s
Build & Deploy / build-and-deploy (push) Successful in 1m0s
The js-dos CDN 'latest' was upgraded to 8.3.20 (emulators 8.3.8) which ships a rebuilt wlibzip.wasm (113,081 bytes vs 112,732 in 8.3.3). The _zipfile_add WASM function in this newer libzip binary fails on our bundles with 'Unable to add .jsdos/jsdos.json into bundle.zip', breaking ALL games. Pinning to 8.3.14 (emulators 8.3.3, wlibzip.wasm 112,732 bytes) restores the working libzip WASM. The JavaScript wrapper code is identical between versions — only the compiled WASM binary differs. Also restored .jsdos/ config files in bundles (no longer need to strip them) and reverted the autoStart workaround.
This commit is contained in:
@@ -44,7 +44,7 @@
|
|||||||
// Load js-dos CSS
|
// Load js-dos CSS
|
||||||
const link = document.createElement("link");
|
const link = document.createElement("link");
|
||||||
link.rel = "stylesheet";
|
link.rel = "stylesheet";
|
||||||
link.href = "https://v8.js-dos.com/latest/js-dos.css";
|
link.href = "https://v8.js-dos.com/8.xx/8.3.14/js-dos.css";
|
||||||
document.head.appendChild(link);
|
document.head.appendChild(link);
|
||||||
injectedLink = link;
|
injectedLink = link;
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
try {
|
try {
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
const s = document.createElement("script");
|
const s = document.createElement("script");
|
||||||
s.src = "https://v8.js-dos.com/latest/js-dos.js";
|
s.src = "https://v8.js-dos.com/8.xx/8.3.14/js-dos.js";
|
||||||
s.onload = resolve;
|
s.onload = resolve;
|
||||||
s.onerror = reject;
|
s.onerror = reject;
|
||||||
document.head.appendChild(s);
|
document.head.appendChild(s);
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
try {
|
try {
|
||||||
const url = isSetup ? setupBundleUrl(game) : bundleUrl(game);
|
const url = isSetup ? setupBundleUrl(game) : bundleUrl(game);
|
||||||
if (!url || !window.Dos) throw new Error("Failed to resolve game bundle");
|
if (!url || !window.Dos) throw new Error("Failed to resolve game bundle");
|
||||||
dosCI = await window.Dos(dosContainer, { url, autoStart: true, countDownStart: 0 });
|
dosCI = await window.Dos(dosContainer, { url });
|
||||||
running = true;
|
running = true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = e.message;
|
error = e.message;
|
||||||
|
|||||||
@@ -512,6 +512,19 @@ public class UploadResource {
|
|||||||
);
|
);
|
||||||
|
|
||||||
private void createBundle(Path extractDir, String exePath, List<String> cdImages, Path bundlePath) throws IOException {
|
private void createBundle(Path extractDir, String exePath, List<String> cdImages, Path bundlePath) throws IOException {
|
||||||
|
// Write .jsdos config directly into the extract directory
|
||||||
|
Path jsdos = extractDir.resolve(".jsdos");
|
||||||
|
Files.createDirectories(jsdos);
|
||||||
|
if (exePath != null) {
|
||||||
|
String relExe = extractDir.relativize(Path.of(exePath)).toString();
|
||||||
|
Files.writeString(jsdos.resolve("dosbox.conf"), buildDosboxConf(relExe, cdImages));
|
||||||
|
Files.write(jsdos.resolve("jsdos.json"), buildJsdosJson(relExe));
|
||||||
|
} else {
|
||||||
|
// CD-only game — no executable, mount CD and show a DOS prompt
|
||||||
|
Files.writeString(jsdos.resolve("dosbox.conf"), buildCdOnlyDosboxConf(cdImages));
|
||||||
|
Files.write(jsdos.resolve("jsdos.json"), buildCdOnlyJsdosJson());
|
||||||
|
}
|
||||||
|
|
||||||
// ZIP it up directly from extractDir (no temp copy)
|
// ZIP it up directly from extractDir (no temp copy)
|
||||||
try (var zos = new java.util.zip.ZipOutputStream(Files.newOutputStream(bundlePath))) {
|
try (var zos = new java.util.zip.ZipOutputStream(Files.newOutputStream(bundlePath))) {
|
||||||
|
|
||||||
@@ -537,9 +550,26 @@ public class UploadResource {
|
|||||||
zos.closeEntry();
|
zos.closeEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Phase 3: All game files ──
|
// ── Phase 3: .jsdos config files (must come before game files) ──
|
||||||
|
try (var walk = Files.walk(jsdos)) {
|
||||||
|
walk.filter(Files::isRegularFile)
|
||||||
|
.sorted()
|
||||||
|
.forEach(f -> {
|
||||||
|
try {
|
||||||
|
String entryName = extractDir.relativize(f).toString().replace('\\', '/');
|
||||||
|
zos.putNextEntry(new java.util.zip.ZipEntry(entryName));
|
||||||
|
Files.copy(f, zos);
|
||||||
|
zos.closeEntry();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new UncheckedIOException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Phase 4: All other game files ──
|
||||||
try (var walk = Files.walk(extractDir)) {
|
try (var walk = Files.walk(extractDir)) {
|
||||||
walk.filter(Files::isRegularFile)
|
walk.filter(Files::isRegularFile)
|
||||||
|
.filter(f -> !f.startsWith(jsdos))
|
||||||
.filter(f -> {
|
.filter(f -> {
|
||||||
String n = f.getFileName().toString().toLowerCase();
|
String n = f.getFileName().toString().toLowerCase();
|
||||||
int dot = n.lastIndexOf('.');
|
int dot = n.lastIndexOf('.');
|
||||||
@@ -558,6 +588,11 @@ public class UploadResource {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clean up .jsdos config files from the extract dir
|
||||||
|
Files.walk(jsdos).sorted(Comparator.reverseOrder()).forEach(p -> {
|
||||||
|
try { Files.deleteIfExists(p); } catch (IOException ignored) {}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Configuration Helpers ──────────────────────────────────
|
// ─── Configuration Helpers ──────────────────────────────────
|
||||||
|
|||||||
Reference in New Issue
Block a user