diff --git a/CHANGELOG.md b/CHANGELOG.md index 091d1141..d4893959 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added Recaf Simple reader and writer - Added `OuterClassNameInheritingVisitor` - Added `MappingFormat#hasWriter` boolean +- Added CSRG detection via the path-based API ## [0.5.1] - 2023-11-30 - Improved documentation diff --git a/src/main/java/net/fabricmc/mappingio/MappingReader.java b/src/main/java/net/fabricmc/mappingio/MappingReader.java index d9aba106..c69eff93 100644 --- a/src/main/java/net/fabricmc/mappingio/MappingReader.java +++ b/src/main/java/net/fabricmc/mappingio/MappingReader.java @@ -48,15 +48,23 @@ private MappingReader() { public static MappingFormat detectFormat(Path file) throws IOException { if (Files.isDirectory(file)) { return MappingFormat.ENIGMA_DIR; - } else { - try (Reader reader = new InputStreamReader(Files.newInputStream(file), StandardCharsets.UTF_8)) { - return detectFormat(reader); - } + } + + try (Reader reader = new InputStreamReader(Files.newInputStream(file), StandardCharsets.UTF_8)) { + String fileName = file.getFileName().toString(); + int dotIdx = fileName.lastIndexOf('.'); + String fileExt = dotIdx >= 0 ? fileName.substring(dotIdx + 1) : null; + + return detectFormat(reader, fileExt); } } @Nullable public static MappingFormat detectFormat(Reader reader) throws IOException { + return detectFormat(reader, null); + } + + private static MappingFormat detectFormat(Reader reader, @Nullable String fileExt) throws IOException { char[] buffer = new char[DETECT_HEADER_LEN]; int pos = 0; int len; @@ -87,7 +95,7 @@ public static MappingFormat detectFormat(Reader reader) throws IOException { case "CL:": case "FD:": case "MD:": - return detectSrgOrXsrg(br); + return detectSrgOrXsrg(br, fileExt); case "CL ": case "FD ": case "MD ": @@ -109,31 +117,33 @@ public static MappingFormat detectFormat(Reader reader) throws IOException { return MappingFormat.TSRG_FILE; } - // TODO: CSRG, Recaf Simple + if (fileExt != null) { + if (fileExt.equals(MappingFormat.CSRG_FILE.fileExt)) return MappingFormat.CSRG_FILE; + } + + // TODO: Recaf Simple - return null; // unknown format or corrupted + return null; // format unknown, not easily detectable or corrupted } - private static MappingFormat detectSrgOrXsrg(BufferedReader reader) throws IOException { + private static MappingFormat detectSrgOrXsrg(BufferedReader reader, @Nullable String fileExt) throws IOException { String line; while ((line = reader.readLine()) != null) { if (line.startsWith("FD:")) { String[] parts = line.split(" "); - if (parts.length >= 5) { - if (isEmptyOrStartsWithHash(parts[3]) || isEmptyOrStartsWithHash(parts[4])) { - continue; - } - - return MappingFormat.XSRG_FILE; - } else { - break; + if (parts.length < 5 + || isEmptyOrStartsWithHash(parts[3]) + || isEmptyOrStartsWithHash(parts[4])) { + return MappingFormat.SRG_FILE; } + + return MappingFormat.XSRG_FILE; } } - return MappingFormat.SRG_FILE; + return MappingFormat.XSRG_FILE.fileExt.equals(fileExt) ? MappingFormat.XSRG_FILE : MappingFormat.SRG_FILE; } private static boolean isEmptyOrStartsWithHash(String string) { diff --git a/src/test/java/net/fabricmc/mappingio/read/DetectionTest.java b/src/test/java/net/fabricmc/mappingio/read/DetectionTest.java index c75e3a33..8635b75f 100644 --- a/src/test/java/net/fabricmc/mappingio/read/DetectionTest.java +++ b/src/test/java/net/fabricmc/mappingio/read/DetectionTest.java @@ -67,7 +67,7 @@ public void srgFile() throws Exception { } @Test - public void xrgFile() throws Exception { + public void xsrgFile() throws Exception { MappingFormat format = MappingFormat.XSRG_FILE; check(format); } @@ -81,7 +81,7 @@ public void jamFile() throws Exception { @Test public void csrgFile() throws Exception { MappingFormat format = MappingFormat.CSRG_FILE; - assertThrows(AssertionFailedError.class, () -> check(format)); + check(format); } @Test @@ -119,6 +119,7 @@ private void check(MappingFormat format) throws Exception { assertEquals(format, MappingReader.detectFormat(path)); if (!format.hasSingleFile()) return; + if (format == MappingFormat.CSRG_FILE) return; try (Reader reader = new InputStreamReader(Files.newInputStream(path), StandardCharsets.UTF_8)) { assertEquals(format, MappingReader.detectFormat(reader));