From 5a3500c586ff219bf396255dfa7b0fd0815757d7 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Thu, 28 May 2026 13:28:10 +0200 Subject: [PATCH] Fix js-dos ZIP extraction: add explicit directory entries to bundles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit js-dos uses Emscripten's virtual filesystem which requires explicit ZIP directory entries (names ending with '/') to create directories. Java's ZipOutputStream only writes file entries, so subdirectories like NAS50TH/TRACKS/WILKES/ were never created — causing Emscripten 'No such file or directory' errors for any path inside them. - createBundle: before writing each file entry, add its parent directory as an explicit ZIP entry if not already added - Affects all games with subdirectory structures (NASCAR Racing 2, Gus Goes to Cyberopolis, etc.) - Use a HashSet to track already-added directories (no duplicates) --- src/main/java/com/dostalgia/UploadResource.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/dostalgia/UploadResource.java b/src/main/java/com/dostalgia/UploadResource.java index a66647a..1e5c8c9 100644 --- a/src/main/java/com/dostalgia/UploadResource.java +++ b/src/main/java/com/dostalgia/UploadResource.java @@ -289,9 +289,20 @@ public class UploadResource { // ZIP it up directly from extractDir (no temp copy) try (var zos = new java.util.zip.ZipOutputStream(Files.newOutputStream(bundlePath))) { + var addedDirs = new java.util.HashSet(); Files.walk(extractDir).filter(Files::isRegularFile).forEach(f -> { try { String entryName = extractDir.relativize(f).toString().replace('\\', '/'); + // Ensure all parent directories have explicit entries + // (js-dos Emscripten FS requires explicit directory entries) + int idx = entryName.lastIndexOf('/'); + if (idx >= 0) { + String parent = entryName.substring(0, idx + 1); + if (addedDirs.add(parent)) { + zos.putNextEntry(new java.util.zip.ZipEntry(parent)); + zos.closeEntry(); + } + } zos.putNextEntry(new java.util.zip.ZipEntry(entryName)); Files.copy(f, zos); zos.closeEntry();