fix: rewrite .cue FILE references that point to non-existent data files
Build & Deploy / build-and-deploy (push) Successful in 12s
Build & Deploy / build-and-deploy (push) Successful in 12s
CloneCD rips generate a .cue that references DOTT.bin but the actual data file is DOTT.img. DOSBox fails to mount the CD when the referenced file doesn't exist, causing 'Illegal command' for executables on the CD. Now before bundle creation, we scan all .cue files and fix any FILE line that points to a missing data file by rewriting it to reference .img or .bin files actually present in the same directory.
This commit is contained in:
@@ -80,6 +80,13 @@ public class UploadResource {
|
|||||||
+ " — continuing (cd in autoexec handles subdirs)");
|
+ " — continuing (cd in autoexec handles subdirs)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fix .cue files that reference non-existent data files (e.g. CloneCD)
|
||||||
|
try {
|
||||||
|
fixCueReferences(extractDir);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.warning("Failed to fix cue references: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
// Find main executable
|
// Find main executable
|
||||||
String mainExe = findMainExe(extractDir);
|
String mainExe = findMainExe(extractDir);
|
||||||
|
|
||||||
@@ -404,6 +411,66 @@ public class UploadResource {
|
|||||||
".iso", ".cue", ".img", ".ccd", ".bin"
|
".iso", ".cue", ".img", ".ccd", ".bin"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fix .cue files that reference non-existent data files.
|
||||||
|
* CloneCD rips often generate a .cue that says FILE "DOTT.bin" BINARY
|
||||||
|
* but the actual data file is DOTT.img. DOSBox can't load the .cue
|
||||||
|
* when the referenced file doesn't exist.
|
||||||
|
*/
|
||||||
|
private static void fixCueReferences(Path extractDir) throws IOException {
|
||||||
|
try (var walk = Files.walk(extractDir)) {
|
||||||
|
walk.filter(Files::isRegularFile)
|
||||||
|
.filter(f -> f.getFileName().toString().toLowerCase().endsWith(".cue"))
|
||||||
|
.forEach(f -> {
|
||||||
|
try {
|
||||||
|
fixOneCue(f);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.warning("Failed to fix cue file " + f + ": " + e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void fixOneCue(Path cueFile) throws IOException {
|
||||||
|
String content = Files.readString(cueFile);
|
||||||
|
Path dir = cueFile.getParent();
|
||||||
|
|
||||||
|
// Find the FILE line: FILE "somefile.bin" BINARY
|
||||||
|
// The pattern: FILE "..." (anything between quotes)
|
||||||
|
java.util.regex.Matcher m = java.util.regex.Pattern
|
||||||
|
.compile("FILE\\s+\"([^\"]+)\"", java.util.regex.Pattern.CASE_INSENSITIVE)
|
||||||
|
.matcher(content);
|
||||||
|
if (!m.find()) return; // no FILE line, nothing to fix
|
||||||
|
|
||||||
|
String referenced = m.group(1);
|
||||||
|
Path refPath = dir.resolve(referenced);
|
||||||
|
if (Files.exists(refPath)) return; // referenced file exists, cue is fine
|
||||||
|
|
||||||
|
// Referenced file doesn't exist — look for .img or .bin in same directory
|
||||||
|
Path replacement = findDataFile(dir);
|
||||||
|
if (replacement == null) return; // nothing to replace with
|
||||||
|
|
||||||
|
// Rewrite the FILE line with the actual file
|
||||||
|
String actualName = replacement.getFileName().toString();
|
||||||
|
content = content.substring(0, m.start(1)) + actualName + content.substring(m.end(1));
|
||||||
|
Files.writeString(cueFile, content);
|
||||||
|
LOG.info("Fixed cue " + cueFile.getFileName() + ": referenced '" + referenced
|
||||||
|
+ "' → '" + actualName + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Find a .img or .bin file in the directory that could be the data file. */
|
||||||
|
private static Path findDataFile(Path dir) throws IOException {
|
||||||
|
try (var files = Files.list(dir)) {
|
||||||
|
return files.filter(Files::isRegularFile)
|
||||||
|
.filter(f -> {
|
||||||
|
String n = f.getFileName().toString().toLowerCase();
|
||||||
|
return n.endsWith(".img") || n.endsWith(".bin");
|
||||||
|
})
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Find mountable CD image files in the extracted game directory.
|
/** Find mountable CD image files in the extracted game directory.
|
||||||
* Returns relative paths (with forward slashes) sorted alphabetically. */
|
* Returns relative paths (with forward slashes) sorted alphabetically. */
|
||||||
private List<String> findCdImages(Path dir) throws IOException {
|
private List<String> findCdImages(Path dir) throws IOException {
|
||||||
|
|||||||
Reference in New Issue
Block a user