From dee37b3f0158907071cf44201df4914629ed50f7 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Fri, 29 May 2026 09:34:57 +0200 Subject: [PATCH] Prefer DOS executables over Windows in findMainExe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a ZIP contains both a DOS version (FALLOUT.EXE) and a Windows version (FALLOUTW.EXE), the sort now prefers DOS executables. This reads the EXE header during candidate collection and ranks: non-installer → DOS platform → depth → size Fixes Fallout being mis-detected as a Windows game. --- src/main/java/com/dostalgia/UploadResource.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/dostalgia/UploadResource.java b/src/main/java/com/dostalgia/UploadResource.java index 58ca640..67374f8 100644 --- a/src/main/java/com/dostalgia/UploadResource.java +++ b/src/main/java/com/dostalgia/UploadResource.java @@ -235,7 +235,7 @@ public class UploadResource { // ─── Executable Detection ──────────────────────────────────── private String findMainExe(Path dir) throws IOException { - record Candidate(int depth, boolean isInstaller, long size, String path) {} + record Candidate(int depth, boolean isInstaller, long size, String path, String platform) {} List candidates = new ArrayList<>(); Files.walkFileTree(dir, new SimpleFileVisitor<>() { @@ -253,17 +253,25 @@ public class UploadResource { boolean installer = name.contains("install") || name.contains("setup") || name.contains("config"); int depth = f.getNameCount() - dir.getNameCount(); - candidates.add(new Candidate(depth, installer, a.size(), f.toString())); + String platform = detectPlatform(f); + candidates.add(new Candidate(depth, installer, a.size(), f.toString(), platform)); return FileVisitResult.CONTINUE; } }); if (candidates.isEmpty()) return null; + // Prefer: non-installer → DOS platform → shallow depth → larger file candidates.sort(Comparator - .comparingInt((Candidate c) -> c.isInstaller() ? 1 : 0) // non-installer first + .comparingInt((Candidate c) -> c.isInstaller() ? 1 : 0) + .thenComparingInt(c -> { + // Prefer DOS over unknown over Windows + if ("dos".equals(c.platform())) return 0; + if (c.platform() == null) return 1; + return 2; // "windows" + }) .thenComparingInt(Candidate::depth) - .thenComparingLong(c -> -c.size())); // larger files first + .thenComparingLong(c -> -c.size())); return candidates.getFirst().path(); }