diff options
| author | 2023-11-28 09:00:33 +0000 | |
|---|---|---|
| committer | 2023-11-28 09:00:33 +0000 | |
| commit | 7622b753d2a99bd8f2bbb4568fd84ca9458ffba5 (patch) | |
| tree | e3a5a6d2006787f2668e47bca34fb46beb40250c | |
| parent | Update deps (#535) (diff) | |
| parent | Merge branch 'upstream' into mapping-io (diff) | |
| download | enigma-7622b753d2a99bd8f2bbb4568fd84ca9458ffba5.tar.gz enigma-7622b753d2a99bd8f2bbb4568fd84ca9458ffba5.tar.xz enigma-7622b753d2a99bd8f2bbb4568fd84ca9458ffba5.zip | |
Merge pull request #463 from NebelNidas/mapping-io
Initial Mapping-IO support
19 files changed, 556 insertions, 122 deletions
diff --git a/build.gradle b/build.gradle index 58cb0bad..b89f1b59 100644 --- a/build.gradle +++ b/build.gradle | |||
| @@ -17,6 +17,9 @@ subprojects { | |||
| 17 | dependencies { | 17 | dependencies { |
| 18 | implementation 'com.google.guava:guava:32.1.2-jre' | 18 | implementation 'com.google.guava:guava:32.1.2-jre' |
| 19 | implementation 'com.google.code.gson:gson:2.10.1' | 19 | implementation 'com.google.code.gson:gson:2.10.1' |
| 20 | implementation 'net.fabricmc:mapping-io:0.5.0' | ||
| 21 | |||
| 22 | compileOnly 'org.jetbrains:annotations:24.0.1' | ||
| 20 | 23 | ||
| 21 | testImplementation 'junit:junit:4.13.2' | 24 | testImplementation 'junit:junit:4.13.2' |
| 22 | testImplementation 'org.hamcrest:hamcrest:2.2' | 25 | testImplementation 'org.hamcrest:hamcrest:2.2' |
diff --git a/enigma-cli/src/main/java/cuchaz/enigma/command/CheckMappingsCommand.java b/enigma-cli/src/main/java/cuchaz/enigma/command/CheckMappingsCommand.java index 922d6688..5e64b2c1 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/CheckMappingsCommand.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/CheckMappingsCommand.java | |||
| @@ -10,7 +10,6 @@ import cuchaz.enigma.ProgressListener; | |||
| 10 | import cuchaz.enigma.analysis.index.JarIndex; | 10 | import cuchaz.enigma.analysis.index.JarIndex; |
| 11 | import cuchaz.enigma.classprovider.ClasspathClassProvider; | 11 | import cuchaz.enigma.classprovider.ClasspathClassProvider; |
| 12 | import cuchaz.enigma.translation.mapping.EntryMapping; | 12 | import cuchaz.enigma.translation.mapping.EntryMapping; |
| 13 | import cuchaz.enigma.translation.mapping.serde.MappingFormat; | ||
| 14 | import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; | 13 | import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; |
| 15 | import cuchaz.enigma.translation.mapping.tree.EntryTree; | 14 | import cuchaz.enigma.translation.mapping.tree.EntryTree; |
| 16 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | 15 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| @@ -38,15 +37,12 @@ public class CheckMappingsCommand extends Command { | |||
| 38 | Enigma enigma = Enigma.create(); | 37 | Enigma enigma = Enigma.create(); |
| 39 | 38 | ||
| 40 | System.out.println("Reading JAR..."); | 39 | System.out.println("Reading JAR..."); |
| 41 | |||
| 42 | EnigmaProject project = enigma.openJar(fileJarIn, new ClasspathClassProvider(), ProgressListener.none()); | 40 | EnigmaProject project = enigma.openJar(fileJarIn, new ClasspathClassProvider(), ProgressListener.none()); |
| 43 | 41 | ||
| 44 | System.out.println("Reading mappings..."); | 42 | System.out.println("Reading mappings..."); |
| 45 | |||
| 46 | MappingFormat format = chooseEnigmaFormat(fileMappings); | ||
| 47 | MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); | 43 | MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); |
| 48 | 44 | ||
| 49 | EntryTree<EntryMapping> mappings = format.read(fileMappings, ProgressListener.none(), saveParameters); | 45 | EntryTree<EntryMapping> mappings = readMappings(fileMappings, ProgressListener.none(), saveParameters); |
| 50 | project.setMappings(mappings); | 46 | project.setMappings(mappings); |
| 51 | 47 | ||
| 52 | JarIndex idx = project.getJarIndex(); | 48 | JarIndex idx = project.getJarIndex(); |
diff --git a/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java b/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java index 04d49f2f..de06fa6e 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java | |||
| @@ -1,11 +1,15 @@ | |||
| 1 | package cuchaz.enigma.command; | 1 | package cuchaz.enigma.command; |
| 2 | 2 | ||
| 3 | import java.io.File; | 3 | import java.io.File; |
| 4 | import java.io.IOException; | ||
| 4 | import java.nio.file.Files; | 5 | import java.nio.file.Files; |
| 5 | import java.nio.file.Path; | 6 | import java.nio.file.Path; |
| 6 | import java.nio.file.Paths; | 7 | import java.nio.file.Paths; |
| 7 | 8 | ||
| 8 | import com.google.common.io.MoreFiles; | 9 | import com.google.common.io.MoreFiles; |
| 10 | import net.fabricmc.mappingio.MappingReader; | ||
| 11 | import net.fabricmc.mappingio.tree.MemoryMappingTree; | ||
| 12 | import net.fabricmc.mappingio.tree.VisitableMappingTree; | ||
| 9 | 13 | ||
| 10 | import cuchaz.enigma.Enigma; | 14 | import cuchaz.enigma.Enigma; |
| 11 | import cuchaz.enigma.EnigmaProject; | 15 | import cuchaz.enigma.EnigmaProject; |
| @@ -13,6 +17,8 @@ import cuchaz.enigma.ProgressListener; | |||
| 13 | import cuchaz.enigma.classprovider.ClasspathClassProvider; | 17 | import cuchaz.enigma.classprovider.ClasspathClassProvider; |
| 14 | import cuchaz.enigma.translation.mapping.EntryMapping; | 18 | import cuchaz.enigma.translation.mapping.EntryMapping; |
| 15 | import cuchaz.enigma.translation.mapping.serde.MappingFormat; | 19 | import cuchaz.enigma.translation.mapping.serde.MappingFormat; |
| 20 | import cuchaz.enigma.translation.mapping.serde.MappingIoConverter; | ||
| 21 | import cuchaz.enigma.translation.mapping.serde.MappingParseException; | ||
| 16 | import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; | 22 | import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; |
| 17 | import cuchaz.enigma.translation.mapping.tree.EntryTree; | 23 | import cuchaz.enigma.translation.mapping.tree.EntryTree; |
| 18 | 24 | ||
| @@ -41,7 +47,7 @@ public abstract class Command { | |||
| 41 | System.out.println("Reading mappings..."); | 47 | System.out.println("Reading mappings..."); |
| 42 | 48 | ||
| 43 | MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); | 49 | MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); |
| 44 | EntryTree<EntryMapping> mappings = chooseEnigmaFormat(fileMappings).read(fileMappings, progress, saveParameters); | 50 | EntryTree<EntryMapping> mappings = readMappings(fileMappings, progress, saveParameters); |
| 45 | 51 | ||
| 46 | project.setMappings(mappings); | 52 | project.setMappings(mappings); |
| 47 | } | 53 | } |
| @@ -49,14 +55,18 @@ public abstract class Command { | |||
| 49 | return project; | 55 | return project; |
| 50 | } | 56 | } |
| 51 | 57 | ||
| 52 | protected static MappingFormat chooseEnigmaFormat(Path path) { | 58 | protected static EntryTree<EntryMapping> readMappings(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException { |
| 53 | if (Files.isDirectory(path)) { | 59 | // Legacy |
| 54 | return MappingFormat.ENIGMA_DIRECTORY; | 60 | if ("zip".equalsIgnoreCase(MoreFiles.getFileExtension(path))) { |
| 55 | } else if ("zip".equalsIgnoreCase(MoreFiles.getFileExtension(path))) { | 61 | return MappingFormat.ENIGMA_ZIP.read(path, progress, saveParameters, null); |
| 56 | return MappingFormat.ENIGMA_ZIP; | ||
| 57 | } else { | ||
| 58 | return MappingFormat.ENIGMA_FILE; | ||
| 59 | } | 62 | } |
| 63 | |||
| 64 | net.fabricmc.mappingio.format.MappingFormat format = MappingReader.detectFormat(path); | ||
| 65 | if (format == null) throw new IllegalArgumentException("Unknown mapping format!"); | ||
| 66 | |||
| 67 | VisitableMappingTree tree = new MemoryMappingTree(); | ||
| 68 | MappingReader.read(path, format, tree); | ||
| 69 | return MappingIoConverter.fromMappingIo(tree, progress, null); | ||
| 60 | } | 70 | } |
| 61 | 71 | ||
| 62 | protected static File getWritableFile(String path) { | 72 | protected static File getWritableFile(String path) { |
diff --git a/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java b/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java index 787625b6..e1e216a5 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java | |||
| @@ -1,17 +1,19 @@ | |||
| 1 | package cuchaz.enigma.command; | 1 | package cuchaz.enigma.command; |
| 2 | 2 | ||
| 3 | import java.io.IOException; | 3 | import java.io.IOException; |
| 4 | import java.io.UncheckedIOException; | ||
| 4 | import java.nio.file.Files; | 5 | import java.nio.file.Files; |
| 5 | import java.nio.file.Path; | 6 | import java.nio.file.Path; |
| 6 | 7 | ||
| 8 | import net.fabricmc.mappingio.MappingWriter; | ||
| 9 | import net.fabricmc.mappingio.tree.VisitableMappingTree; | ||
| 10 | |||
| 7 | import cuchaz.enigma.ProgressListener; | 11 | import cuchaz.enigma.ProgressListener; |
| 8 | import cuchaz.enigma.translation.mapping.EntryMapping; | 12 | import cuchaz.enigma.translation.mapping.EntryMapping; |
| 9 | import cuchaz.enigma.translation.mapping.serde.MappingFormat; | 13 | import cuchaz.enigma.translation.mapping.serde.MappingFormat; |
| 14 | import cuchaz.enigma.translation.mapping.serde.MappingIoConverter; | ||
| 10 | import cuchaz.enigma.translation.mapping.serde.MappingParseException; | 15 | import cuchaz.enigma.translation.mapping.serde.MappingParseException; |
| 11 | import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; | 16 | import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; |
| 12 | import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader; | ||
| 13 | import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsWriter; | ||
| 14 | import cuchaz.enigma.translation.mapping.serde.tiny.TinyMappingsReader; | ||
| 15 | import cuchaz.enigma.translation.mapping.serde.tiny.TinyMappingsWriter; | 17 | import cuchaz.enigma.translation.mapping.serde.tiny.TinyMappingsWriter; |
| 16 | import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer; | 18 | import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer; |
| 17 | import cuchaz.enigma.translation.mapping.tree.EntryTree; | 19 | import cuchaz.enigma.translation.mapping.tree.EntryTree; |
| @@ -22,11 +24,11 @@ public final class MappingCommandsUtil { | |||
| 22 | 24 | ||
| 23 | public static EntryTree<EntryMapping> read(String type, Path path, MappingSaveParameters saveParameters) throws MappingParseException, IOException { | 25 | public static EntryTree<EntryMapping> read(String type, Path path, MappingSaveParameters saveParameters) throws MappingParseException, IOException { |
| 24 | if (type.equals("enigma")) { | 26 | if (type.equals("enigma")) { |
| 25 | return (Files.isDirectory(path) ? EnigmaMappingsReader.DIRECTORY : EnigmaMappingsReader.ZIP).read(path, ProgressListener.none(), saveParameters); | 27 | return (Files.isDirectory(path) ? MappingFormat.ENIGMA_DIRECTORY : MappingFormat.ENIGMA_ZIP).read(path, ProgressListener.none(), saveParameters, null); |
| 26 | } | 28 | } |
| 27 | 29 | ||
| 28 | if (type.equals("tiny")) { | 30 | if (type.equals("tiny")) { |
| 29 | return TinyMappingsReader.INSTANCE.read(path, ProgressListener.none(), saveParameters); | 31 | return MappingFormat.TINY_FILE.read(path, ProgressListener.none(), saveParameters, null); |
| 30 | } | 32 | } |
| 31 | 33 | ||
| 32 | MappingFormat format = null; | 34 | MappingFormat format = null; |
| @@ -40,7 +42,7 @@ public final class MappingCommandsUtil { | |||
| 40 | } | 42 | } |
| 41 | 43 | ||
| 42 | if (format != null) { | 44 | if (format != null) { |
| 43 | return format.getReader().read(path, ProgressListener.none(), saveParameters); | 45 | return format.read(path, ProgressListener.none(), saveParameters, null); |
| 44 | } | 46 | } |
| 45 | 47 | ||
| 46 | throw new IllegalArgumentException("no reader for " + type); | 48 | throw new IllegalArgumentException("no reader for " + type); |
| @@ -48,7 +50,7 @@ public final class MappingCommandsUtil { | |||
| 48 | 50 | ||
| 49 | public static void write(EntryTree<EntryMapping> mappings, String type, Path path, MappingSaveParameters saveParameters) { | 51 | public static void write(EntryTree<EntryMapping> mappings, String type, Path path, MappingSaveParameters saveParameters) { |
| 50 | if (type.equals("enigma")) { | 52 | if (type.equals("enigma")) { |
| 51 | EnigmaMappingsWriter.DIRECTORY.write(mappings, path, ProgressListener.none(), saveParameters); | 53 | MappingFormat.ENIGMA_DIRECTORY.write(mappings, path, ProgressListener.none(), saveParameters); |
| 52 | return; | 54 | return; |
| 53 | } | 55 | } |
| 54 | 56 | ||
| @@ -59,7 +61,18 @@ public final class MappingCommandsUtil { | |||
| 59 | throw new IllegalArgumentException("specify column names as 'tinyv2:from_namespace:to_namespace'"); | 61 | throw new IllegalArgumentException("specify column names as 'tinyv2:from_namespace:to_namespace'"); |
| 60 | } | 62 | } |
| 61 | 63 | ||
| 62 | new TinyV2Writer(split[1], split[2]).write(mappings, path, ProgressListener.none(), saveParameters); | 64 | if (!System.getProperty("enigma.use_mappingio", "true").equals("true")) { |
| 65 | new TinyV2Writer(split[1], split[2]).write(mappings, path, ProgressListener.none(), saveParameters); | ||
| 66 | return; | ||
| 67 | } | ||
| 68 | |||
| 69 | try { | ||
| 70 | VisitableMappingTree tree = MappingIoConverter.toMappingIo(mappings, ProgressListener.none(), split[1], split[2]); | ||
| 71 | tree.accept(MappingWriter.create(path, net.fabricmc.mappingio.format.MappingFormat.TINY_2_FILE)); | ||
| 72 | } catch (IOException e) { | ||
| 73 | throw new UncheckedIOException(e); | ||
| 74 | } | ||
| 75 | |||
| 63 | return; | 76 | return; |
| 64 | } | 77 | } |
| 65 | 78 | ||
| @@ -70,7 +83,18 @@ public final class MappingCommandsUtil { | |||
| 70 | throw new IllegalArgumentException("specify column names as 'tiny:from_column:to_column'"); | 83 | throw new IllegalArgumentException("specify column names as 'tiny:from_column:to_column'"); |
| 71 | } | 84 | } |
| 72 | 85 | ||
| 73 | new TinyMappingsWriter(split[1], split[2]).write(mappings, path, ProgressListener.none(), saveParameters); | 86 | if (!System.getProperty("enigma.use_mappingio", "true").equals("true")) { |
| 87 | new TinyMappingsWriter(split[1], split[2]).write(mappings, path, ProgressListener.none(), saveParameters); | ||
| 88 | return; | ||
| 89 | } | ||
| 90 | |||
| 91 | try { | ||
| 92 | VisitableMappingTree tree = MappingIoConverter.toMappingIo(mappings, ProgressListener.none(), split[1], split[2]); | ||
| 93 | tree.accept(MappingWriter.create(path, net.fabricmc.mappingio.format.MappingFormat.TINY_FILE)); | ||
| 94 | } catch (IOException e) { | ||
| 95 | throw new UncheckedIOException(e); | ||
| 96 | } | ||
| 97 | |||
| 74 | return; | 98 | return; |
| 75 | } | 99 | } |
| 76 | 100 | ||
| @@ -83,7 +107,7 @@ public final class MappingCommandsUtil { | |||
| 83 | } | 107 | } |
| 84 | 108 | ||
| 85 | if (format != null) { | 109 | if (format != null) { |
| 86 | format.getWriter().write(mappings, path, ProgressListener.none(), saveParameters); | 110 | format.write(mappings, path, ProgressListener.none(), saveParameters); |
| 87 | return; | 111 | return; |
| 88 | } | 112 | } |
| 89 | 113 | ||
diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java b/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java index eb22a506..fbee40d0 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java | |||
| @@ -108,7 +108,7 @@ public class DedicatedEnigmaServer extends EnigmaServer { | |||
| 108 | mappingFormat = MappingFormat.ENIGMA_FILE; | 108 | mappingFormat = MappingFormat.ENIGMA_FILE; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | mappings = EntryRemapper.mapped(project.getJarIndex(), mappingFormat.read(mappingsFile, ProgressListener.none(), profile.getMappingSaveParameters())); | 111 | mappings = EntryRemapper.mapped(project.getJarIndex(), mappingFormat.read(mappingsFile, ProgressListener.none(), profile.getMappingSaveParameters(), project.getJarIndex())); |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | PrintWriter log = new PrintWriter(Files.newBufferedWriter(logFile)); | 114 | PrintWriter log = new PrintWriter(Files.newBufferedWriter(logFile)); |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java index 91037b00..c5799019 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java | |||
| @@ -29,6 +29,7 @@ import javax.swing.JOptionPane; | |||
| 29 | import javax.swing.SwingUtilities; | 29 | import javax.swing.SwingUtilities; |
| 30 | 30 | ||
| 31 | import com.google.common.collect.Lists; | 31 | import com.google.common.collect.Lists; |
| 32 | import org.jetbrains.annotations.ApiStatus; | ||
| 32 | 33 | ||
| 33 | import cuchaz.enigma.Enigma; | 34 | import cuchaz.enigma.Enigma; |
| 34 | import cuchaz.enigma.EnigmaProfile; | 35 | import cuchaz.enigma.EnigmaProfile; |
| @@ -139,6 +140,12 @@ public class GuiController implements ClientPacketHandler { | |||
| 139 | this.gui.onCloseJar(); | 140 | this.gui.onCloseJar(); |
| 140 | } | 141 | } |
| 141 | 142 | ||
| 143 | @ApiStatus.Internal | ||
| 144 | public CompletableFuture<Void> openMappings(MappingFormat format, Path path, boolean useMappingIo) { | ||
| 145 | System.getProperties().setProperty("enigma.use_mappingio", useMappingIo ? "true" : "false"); | ||
| 146 | return openMappings(format, path); | ||
| 147 | } | ||
| 148 | |||
| 142 | public CompletableFuture<Void> openMappings(MappingFormat format, Path path) { | 149 | public CompletableFuture<Void> openMappings(MappingFormat format, Path path) { |
| 143 | if (project == null) { | 150 | if (project == null) { |
| 144 | return CompletableFuture.completedFuture(null); | 151 | return CompletableFuture.completedFuture(null); |
| @@ -149,9 +156,7 @@ public class GuiController implements ClientPacketHandler { | |||
| 149 | return ProgressDialog.runOffThread(gui.getFrame(), progress -> { | 156 | return ProgressDialog.runOffThread(gui.getFrame(), progress -> { |
| 150 | try { | 157 | try { |
| 151 | MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); | 158 | MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); |
| 152 | 159 | project.setMappings(format.read(path, progress, saveParameters, project.getJarIndex())); | |
| 153 | EntryTree<EntryMapping> mappings = format.read(path, progress, saveParameters); | ||
| 154 | project.setMappings(mappings); | ||
| 155 | 160 | ||
| 156 | loadedMappingFormat = format; | 161 | loadedMappingFormat = format; |
| 157 | loadedMappingPath = path; | 162 | loadedMappingPath = path; |
| @@ -179,6 +184,12 @@ public class GuiController implements ClientPacketHandler { | |||
| 179 | return saveMappings(path, loadedMappingFormat); | 184 | return saveMappings(path, loadedMappingFormat); |
| 180 | } | 185 | } |
| 181 | 186 | ||
| 187 | @ApiStatus.Internal | ||
| 188 | public CompletableFuture<Void> saveMappings(Path path, MappingFormat format, boolean useMappingIo) { | ||
| 189 | System.getProperties().setProperty("enigma.use_mappingio", useMappingIo ? "true" : "false"); | ||
| 190 | return saveMappings(path, format); | ||
| 191 | } | ||
| 192 | |||
| 182 | /** | 193 | /** |
| 183 | * Saves the mappings, with a dialog popping up, showing the progress. | 194 | * Saves the mappings, with a dialog popping up, showing the progress. |
| 184 | * | 195 | * |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java index 1cfad504..30e35861 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java | |||
| @@ -45,7 +45,7 @@ public class MenuBar { | |||
| 45 | private final JMenu fileMenu = new JMenu(); | 45 | private final JMenu fileMenu = new JMenu(); |
| 46 | private final JMenuItem jarOpenItem = new JMenuItem(); | 46 | private final JMenuItem jarOpenItem = new JMenuItem(); |
| 47 | private final JMenuItem jarCloseItem = new JMenuItem(); | 47 | private final JMenuItem jarCloseItem = new JMenuItem(); |
| 48 | private final JMenu openMenu = new JMenu(); | 48 | private final JMenu openMappingsMenu = new JMenu(); |
| 49 | private final JMenuItem saveMappingsItem = new JMenuItem(); | 49 | private final JMenuItem saveMappingsItem = new JMenuItem(); |
| 50 | private final JMenu saveMappingsAsMenu = new JMenu(); | 50 | private final JMenu saveMappingsAsMenu = new JMenu(); |
| 51 | private final JMenuItem closeMappingsItem = new JMenuItem(); | 51 | private final JMenuItem closeMappingsItem = new JMenuItem(); |
| @@ -88,7 +88,7 @@ public class MenuBar { | |||
| 88 | 88 | ||
| 89 | this.retranslateUi(); | 89 | this.retranslateUi(); |
| 90 | 90 | ||
| 91 | prepareOpenMenu(this.openMenu, gui); | 91 | prepareOpenMappingsMenu(this.openMappingsMenu, gui); |
| 92 | prepareSaveMappingsAsMenu(this.saveMappingsAsMenu, this.saveMappingsItem, gui); | 92 | prepareSaveMappingsAsMenu(this.saveMappingsAsMenu, this.saveMappingsItem, gui); |
| 93 | prepareDecompilerMenu(this.decompilerMenu, gui); | 93 | prepareDecompilerMenu(this.decompilerMenu, gui); |
| 94 | prepareThemesMenu(this.themesMenu, gui); | 94 | prepareThemesMenu(this.themesMenu, gui); |
| @@ -98,7 +98,7 @@ public class MenuBar { | |||
| 98 | this.fileMenu.add(this.jarOpenItem); | 98 | this.fileMenu.add(this.jarOpenItem); |
| 99 | this.fileMenu.add(this.jarCloseItem); | 99 | this.fileMenu.add(this.jarCloseItem); |
| 100 | this.fileMenu.addSeparator(); | 100 | this.fileMenu.addSeparator(); |
| 101 | this.fileMenu.add(this.openMenu); | 101 | this.fileMenu.add(this.openMappingsMenu); |
| 102 | this.fileMenu.add(this.saveMappingsItem); | 102 | this.fileMenu.add(this.saveMappingsItem); |
| 103 | this.fileMenu.add(this.saveMappingsAsMenu); | 103 | this.fileMenu.add(this.saveMappingsAsMenu); |
| 104 | this.fileMenu.add(this.closeMappingsItem); | 104 | this.fileMenu.add(this.closeMappingsItem); |
| @@ -174,7 +174,7 @@ public class MenuBar { | |||
| 174 | this.startServerItem.setText(I18n.translate(connectionState != ConnectionState.HOSTING ? "menu.collab.server.start" : "menu.collab.server.stop")); | 174 | this.startServerItem.setText(I18n.translate(connectionState != ConnectionState.HOSTING ? "menu.collab.server.start" : "menu.collab.server.stop")); |
| 175 | 175 | ||
| 176 | this.jarCloseItem.setEnabled(jarOpen); | 176 | this.jarCloseItem.setEnabled(jarOpen); |
| 177 | this.openMenu.setEnabled(jarOpen); | 177 | this.openMappingsMenu.setEnabled(jarOpen); |
| 178 | this.saveMappingsItem.setEnabled(jarOpen && this.gui.enigmaMappingsFileChooser.getSelectedFile() != null && connectionState != ConnectionState.CONNECTED); | 178 | this.saveMappingsItem.setEnabled(jarOpen && this.gui.enigmaMappingsFileChooser.getSelectedFile() != null && connectionState != ConnectionState.CONNECTED); |
| 179 | this.saveMappingsAsMenu.setEnabled(jarOpen); | 179 | this.saveMappingsAsMenu.setEnabled(jarOpen); |
| 180 | this.closeMappingsItem.setEnabled(jarOpen); | 180 | this.closeMappingsItem.setEnabled(jarOpen); |
| @@ -189,7 +189,7 @@ public class MenuBar { | |||
| 189 | this.fileMenu.setText(I18n.translate("menu.file")); | 189 | this.fileMenu.setText(I18n.translate("menu.file")); |
| 190 | this.jarOpenItem.setText(I18n.translate("menu.file.jar.open")); | 190 | this.jarOpenItem.setText(I18n.translate("menu.file.jar.open")); |
| 191 | this.jarCloseItem.setText(I18n.translate("menu.file.jar.close")); | 191 | this.jarCloseItem.setText(I18n.translate("menu.file.jar.close")); |
| 192 | this.openMenu.setText(I18n.translate("menu.file.mappings.open")); | 192 | this.openMappingsMenu.setText(I18n.translate("menu.file.mappings.open")); |
| 193 | this.saveMappingsItem.setText(I18n.translate("menu.file.mappings.save")); | 193 | this.saveMappingsItem.setText(I18n.translate("menu.file.mappings.save")); |
| 194 | this.saveMappingsAsMenu.setText(I18n.translate("menu.file.mappings.save_as")); | 194 | this.saveMappingsAsMenu.setText(I18n.translate("menu.file.mappings.save_as")); |
| 195 | this.closeMappingsItem.setText(I18n.translate("menu.file.mappings.close")); | 195 | this.closeMappingsItem.setText(I18n.translate("menu.file.mappings.close")); |
| @@ -402,45 +402,71 @@ public class MenuBar { | |||
| 402 | GuiUtil.openUrl("https://github.com/FabricMC/Enigma"); | 402 | GuiUtil.openUrl("https://github.com/FabricMC/Enigma"); |
| 403 | } | 403 | } |
| 404 | 404 | ||
| 405 | private static void prepareOpenMenu(JMenu openMenu, Gui gui) { | 405 | private static void prepareOpenMappingsMenu(JMenu openMappingsMenu, Gui gui) { |
| 406 | // Mapping-IO readers | ||
| 407 | MappingFormat.getReadableFormats().stream() | ||
| 408 | .filter(format -> format.getMappingIoCounterpart() != null) | ||
| 409 | .forEach(format -> addOpenMappingsMenuEntry(I18n.translate(format.getMappingIoCounterpart().name), | ||
| 410 | format, true, openMappingsMenu, gui)); | ||
| 411 | openMappingsMenu.addSeparator(); | ||
| 412 | |||
| 413 | // Enigma's own readers | ||
| 406 | for (MappingFormat format : MappingFormat.values()) { | 414 | for (MappingFormat format : MappingFormat.values()) { |
| 407 | if (format.getReader() != null) { | 415 | if (format.getReader() != null) { |
| 408 | JMenuItem item = new JMenuItem(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT))); | 416 | addOpenMappingsMenuEntry(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)) + " (legacy)", |
| 409 | item.addActionListener(event -> { | 417 | format, false, openMappingsMenu, gui); |
| 410 | gui.enigmaMappingsFileChooser.setCurrentDirectory(new File(UiConfig.getLastSelectedDir())); | ||
| 411 | |||
| 412 | if (gui.enigmaMappingsFileChooser.showOpenDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) { | ||
| 413 | File selectedFile = gui.enigmaMappingsFileChooser.getSelectedFile(); | ||
| 414 | gui.getController().openMappings(format, selectedFile.toPath()); | ||
| 415 | UiConfig.setLastSelectedDir(gui.enigmaMappingsFileChooser.getCurrentDirectory().toString()); | ||
| 416 | } | ||
| 417 | }); | ||
| 418 | openMenu.add(item); | ||
| 419 | } | 418 | } |
| 420 | } | 419 | } |
| 421 | } | 420 | } |
| 422 | 421 | ||
| 422 | private static void addOpenMappingsMenuEntry(String text, MappingFormat format, boolean mappingIo, JMenu openMappingsMenu, Gui gui) { | ||
| 423 | JMenuItem item = new JMenuItem(text); | ||
| 424 | item.addActionListener(event -> { | ||
| 425 | gui.enigmaMappingsFileChooser.setCurrentDirectory(new File(UiConfig.getLastSelectedDir())); | ||
| 426 | |||
| 427 | if (gui.enigmaMappingsFileChooser.showOpenDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) { | ||
| 428 | File selectedFile = gui.enigmaMappingsFileChooser.getSelectedFile(); | ||
| 429 | gui.getController().openMappings(format, selectedFile.toPath(), mappingIo); | ||
| 430 | UiConfig.setLastSelectedDir(gui.enigmaMappingsFileChooser.getCurrentDirectory().toString()); | ||
| 431 | } | ||
| 432 | }); | ||
| 433 | openMappingsMenu.add(item); | ||
| 434 | } | ||
| 435 | |||
| 423 | private static void prepareSaveMappingsAsMenu(JMenu saveMappingsAsMenu, JMenuItem saveMappingsItem, Gui gui) { | 436 | private static void prepareSaveMappingsAsMenu(JMenu saveMappingsAsMenu, JMenuItem saveMappingsItem, Gui gui) { |
| 437 | // Mapping-IO writers | ||
| 438 | MappingFormat.getWritableFormats().stream() | ||
| 439 | .filter(format -> format.hasMappingIoWriter()) | ||
| 440 | .forEach(format -> addSaveMappingsAsMenuEntry(format.getMappingIoCounterpart().name, | ||
| 441 | format, true, saveMappingsAsMenu, saveMappingsItem, gui)); | ||
| 442 | saveMappingsAsMenu.addSeparator(); | ||
| 443 | |||
| 444 | // Enigma's own writers | ||
| 424 | for (MappingFormat format : MappingFormat.values()) { | 445 | for (MappingFormat format : MappingFormat.values()) { |
| 425 | if (format.getWriter() != null) { | 446 | if (format.getWriter() != null) { |
| 426 | JMenuItem item = new JMenuItem(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT))); | 447 | addSaveMappingsAsMenuEntry(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)) + " (legacy)", |
| 427 | item.addActionListener(event -> { | 448 | format, false, saveMappingsAsMenu, saveMappingsItem, gui); |
| 428 | // TODO: Use a specific file chooser for it | ||
| 429 | if (gui.enigmaMappingsFileChooser.getCurrentDirectory() == null) { | ||
| 430 | gui.enigmaMappingsFileChooser.setCurrentDirectory(new File(UiConfig.getLastSelectedDir())); | ||
| 431 | } | ||
| 432 | |||
| 433 | if (gui.enigmaMappingsFileChooser.showSaveDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) { | ||
| 434 | gui.getController().saveMappings(gui.enigmaMappingsFileChooser.getSelectedFile().toPath(), format); | ||
| 435 | saveMappingsItem.setEnabled(true); | ||
| 436 | UiConfig.setLastSelectedDir(gui.enigmaMappingsFileChooser.getCurrentDirectory().toString()); | ||
| 437 | } | ||
| 438 | }); | ||
| 439 | saveMappingsAsMenu.add(item); | ||
| 440 | } | 449 | } |
| 441 | } | 450 | } |
| 442 | } | 451 | } |
| 443 | 452 | ||
| 453 | private static void addSaveMappingsAsMenuEntry(String text, MappingFormat format, boolean mappingIo, JMenu saveMappingsAsMenu, JMenuItem saveMappingsItem, Gui gui) { | ||
| 454 | JMenuItem item = new JMenuItem(text); | ||
| 455 | item.addActionListener(event -> { | ||
| 456 | // TODO: Use a specific file chooser for it | ||
| 457 | if (gui.enigmaMappingsFileChooser.getCurrentDirectory() == null) { | ||
| 458 | gui.enigmaMappingsFileChooser.setCurrentDirectory(new File(UiConfig.getLastSelectedDir())); | ||
| 459 | } | ||
| 460 | |||
| 461 | if (gui.enigmaMappingsFileChooser.showSaveDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) { | ||
| 462 | gui.getController().saveMappings(gui.enigmaMappingsFileChooser.getSelectedFile().toPath(), format, mappingIo); | ||
| 463 | saveMappingsItem.setEnabled(true); | ||
| 464 | UiConfig.setLastSelectedDir(gui.enigmaMappingsFileChooser.getCurrentDirectory().toString()); | ||
| 465 | } | ||
| 466 | }); | ||
| 467 | saveMappingsAsMenu.add(item); | ||
| 468 | } | ||
| 469 | |||
| 444 | private static void prepareDecompilerMenu(JMenu decompilerMenu, Gui gui) { | 470 | private static void prepareDecompilerMenu(JMenu decompilerMenu, Gui gui) { |
| 445 | ButtonGroup decompilerGroup = new ButtonGroup(); | 471 | ButtonGroup decompilerGroup = new ButtonGroup(); |
| 446 | 472 | ||
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java index 367af3b3..4521591e 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java | |||
| @@ -1,11 +1,22 @@ | |||
| 1 | package cuchaz.enigma.translation.mapping.serde; | 1 | package cuchaz.enigma.translation.mapping.serde; |
| 2 | 2 | ||
| 3 | import java.io.IOException; | 3 | import java.io.IOException; |
| 4 | import java.io.UncheckedIOException; | ||
| 4 | import java.nio.file.Path; | 5 | import java.nio.file.Path; |
| 6 | import java.util.Arrays; | ||
| 7 | import java.util.List; | ||
| 5 | 8 | ||
| 6 | import javax.annotation.Nullable; | 9 | import javax.annotation.Nullable; |
| 7 | 10 | ||
| 11 | import net.fabricmc.mappingio.MappingReader; | ||
| 12 | import net.fabricmc.mappingio.MappingWriter; | ||
| 13 | import net.fabricmc.mappingio.tree.MemoryMappingTree; | ||
| 14 | import net.fabricmc.mappingio.tree.VisitOrder; | ||
| 15 | import net.fabricmc.mappingio.tree.VisitableMappingTree; | ||
| 16 | import org.jetbrains.annotations.ApiStatus; | ||
| 17 | |||
| 8 | import cuchaz.enigma.ProgressListener; | 18 | import cuchaz.enigma.ProgressListener; |
| 19 | import cuchaz.enigma.analysis.index.JarIndex; | ||
| 9 | import cuchaz.enigma.translation.mapping.EntryMapping; | 20 | import cuchaz.enigma.translation.mapping.EntryMapping; |
| 10 | import cuchaz.enigma.translation.mapping.MappingDelta; | 21 | import cuchaz.enigma.translation.mapping.MappingDelta; |
| 11 | import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader; | 22 | import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader; |
| @@ -19,23 +30,33 @@ import cuchaz.enigma.translation.mapping.serde.tiny.TinyMappingsWriter; | |||
| 19 | import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Reader; | 30 | import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Reader; |
| 20 | import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer; | 31 | import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer; |
| 21 | import cuchaz.enigma.translation.mapping.tree.EntryTree; | 32 | import cuchaz.enigma.translation.mapping.tree.EntryTree; |
| 33 | import cuchaz.enigma.utils.I18n; | ||
| 22 | 34 | ||
| 23 | public enum MappingFormat { | 35 | public enum MappingFormat { |
| 24 | ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE), | 36 | ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_FILE, true), |
| 25 | ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY), | 37 | ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_DIR, true), |
| 26 | ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP), | 38 | ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP, null, false), |
| 27 | TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader()), | 39 | TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader(), net.fabricmc.mappingio.format.MappingFormat.TINY_2_FILE, true), |
| 28 | TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE), | 40 | TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.TINY_FILE, true), |
| 29 | SRG_FILE(SrgMappingsWriter.INSTANCE, null), | 41 | SRG_FILE(SrgMappingsWriter.INSTANCE, null, net.fabricmc.mappingio.format.MappingFormat.SRG_FILE, true), |
| 30 | PROGUARD(null, ProguardMappingsReader.INSTANCE), | 42 | XSRG_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.XSRG_FILE, true), |
| 31 | RECAF(RecafMappingsWriter.INSTANCE, RecafMappingsReader.INSTANCE); | 43 | CSRG_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.CSRG_FILE, false), |
| 44 | TSRG_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG_FILE, false), | ||
| 45 | TSRG_2_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG_2_FILE, false), | ||
| 46 | PROGUARD(null, ProguardMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.PROGUARD_FILE, true), | ||
| 47 | RECAF(RecafMappingsWriter.INSTANCE, RecafMappingsReader.INSTANCE, null, false); | ||
| 32 | 48 | ||
| 33 | private final MappingsWriter writer; | 49 | private final MappingsWriter writer; |
| 34 | private final MappingsReader reader; | 50 | private final MappingsReader reader; |
| 51 | private final net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart; | ||
| 52 | private final boolean hasMappingIoWriter; | ||
| 53 | private boolean lastUsedMappingIoWriter; | ||
| 35 | 54 | ||
| 36 | MappingFormat(MappingsWriter writer, MappingsReader reader) { | 55 | MappingFormat(MappingsWriter writer, MappingsReader reader, net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart, boolean hasMappingIoWriter) { |
| 37 | this.writer = writer; | 56 | this.writer = writer; |
| 38 | this.reader = reader; | 57 | this.reader = reader; |
| 58 | this.mappingIoCounterpart = mappingIoCounterpart; | ||
| 59 | this.hasMappingIoWriter = hasMappingIoWriter; | ||
| 39 | } | 60 | } |
| 40 | 61 | ||
| 41 | public void write(EntryTree<EntryMapping> mappings, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { | 62 | public void write(EntryTree<EntryMapping> mappings, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { |
| @@ -43,19 +64,56 @@ public enum MappingFormat { | |||
| 43 | } | 64 | } |
| 44 | 65 | ||
| 45 | public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { | 66 | public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { |
| 46 | if (writer == null) { | 67 | if (!hasMappingIoWriter || !useMappingIo()) { |
| 47 | throw new IllegalStateException(name() + " does not support writing"); | 68 | if (writer == null) { |
| 69 | throw new IllegalStateException(name() + " does not support writing"); | ||
| 70 | } | ||
| 71 | |||
| 72 | writer.write(mappings, lastUsedMappingIoWriter ? MappingDelta.added(mappings) : delta, path, progressListener, saveParameters); | ||
| 73 | lastUsedMappingIoWriter = false; | ||
| 74 | return; | ||
| 48 | } | 75 | } |
| 49 | 76 | ||
| 50 | writer.write(mappings, delta, path, progressListener, saveParameters); | 77 | try { |
| 78 | VisitableMappingTree tree = MappingIoConverter.toMappingIo(mappings, progressListener); | ||
| 79 | progressListener.init(1, I18n.translate("progress.mappings.writing")); | ||
| 80 | progressListener.step(1, null); // Reset message | ||
| 81 | |||
| 82 | tree.accept(MappingWriter.create(path, mappingIoCounterpart), VisitOrder.createByName()); | ||
| 83 | progressListener.step(1, I18n.translate("progress.done")); | ||
| 84 | lastUsedMappingIoWriter = true; | ||
| 85 | } catch (IOException e) { | ||
| 86 | throw new UncheckedIOException(e); | ||
| 87 | } | ||
| 51 | } | 88 | } |
| 52 | 89 | ||
| 90 | @Deprecated | ||
| 53 | public EntryTree<EntryMapping> read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) throws IOException, MappingParseException { | 91 | public EntryTree<EntryMapping> read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) throws IOException, MappingParseException { |
| 54 | if (reader == null) { | 92 | return read(path, progressListener, saveParameters, null); |
| 55 | throw new IllegalStateException(name() + " does not support reading"); | 93 | } |
| 94 | |||
| 95 | public EntryTree<EntryMapping> read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters, JarIndex index) throws IOException, MappingParseException { | ||
| 96 | if (!useMappingIo()) { | ||
| 97 | if (reader == null) { | ||
| 98 | throw new IllegalStateException(name() + " does not support reading"); | ||
| 99 | } | ||
| 100 | |||
| 101 | return reader.read(path, progressListener, saveParameters); | ||
| 56 | } | 102 | } |
| 57 | 103 | ||
| 58 | return reader.read(path, progressListener, saveParameters); | 104 | String loadingMessage; |
| 105 | |||
| 106 | if (mappingIoCounterpart.hasSingleFile()) { | ||
| 107 | loadingMessage = I18n.translate("progress.mappings.loading_file"); | ||
| 108 | } else { | ||
| 109 | loadingMessage = I18n.translate("progress.mappings.loading_directory"); | ||
| 110 | } | ||
| 111 | |||
| 112 | progressListener.init(1, loadingMessage); | ||
| 113 | |||
| 114 | VisitableMappingTree mappingTree = new MemoryMappingTree(); | ||
| 115 | MappingReader.read(path, mappingIoCounterpart, mappingTree); | ||
| 116 | return MappingIoConverter.fromMappingIo(mappingTree, progressListener, index); | ||
| 59 | } | 117 | } |
| 60 | 118 | ||
| 61 | @Nullable | 119 | @Nullable |
| @@ -67,4 +125,43 @@ public enum MappingFormat { | |||
| 67 | public MappingsReader getReader() { | 125 | public MappingsReader getReader() { |
| 68 | return reader; | 126 | return reader; |
| 69 | } | 127 | } |
| 128 | |||
| 129 | @Nullable | ||
| 130 | @ApiStatus.Internal | ||
| 131 | public net.fabricmc.mappingio.format.MappingFormat getMappingIoCounterpart() { | ||
| 132 | return mappingIoCounterpart; | ||
| 133 | } | ||
| 134 | |||
| 135 | @ApiStatus.Internal | ||
| 136 | public boolean hasMappingIoWriter() { | ||
| 137 | return hasMappingIoWriter; | ||
| 138 | } | ||
| 139 | |||
| 140 | public boolean isReadable() { | ||
| 141 | return reader != null || mappingIoCounterpart != null; | ||
| 142 | } | ||
| 143 | |||
| 144 | public boolean isWritable() { | ||
| 145 | return writer != null || hasMappingIoWriter; | ||
| 146 | } | ||
| 147 | |||
| 148 | @ApiStatus.Internal | ||
| 149 | private boolean useMappingIo() { | ||
| 150 | if (mappingIoCounterpart == null) return false; | ||
| 151 | return System.getProperty("enigma.use_mappingio", "true").equals("true"); | ||
| 152 | } | ||
| 153 | |||
| 154 | public static List<MappingFormat> getReadableFormats() { | ||
| 155 | return Arrays.asList(values()) | ||
| 156 | .stream() | ||
| 157 | .filter(MappingFormat::isReadable) | ||
| 158 | .toList(); | ||
| 159 | } | ||
| 160 | |||
| 161 | public static List<MappingFormat> getWritableFormats() { | ||
| 162 | return Arrays.asList(values()) | ||
| 163 | .stream() | ||
| 164 | .filter(MappingFormat::isWritable) | ||
| 165 | .toList(); | ||
| 166 | } | ||
| 70 | } | 167 | } |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java new file mode 100644 index 00000000..3843d8e4 --- /dev/null +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java | |||
| @@ -0,0 +1,279 @@ | |||
| 1 | package cuchaz.enigma.translation.mapping.serde; | ||
| 2 | |||
| 3 | import java.io.IOException; | ||
| 4 | import java.io.UncheckedIOException; | ||
| 5 | import java.util.Deque; | ||
| 6 | import java.util.LinkedList; | ||
| 7 | import java.util.List; | ||
| 8 | import java.util.stream.StreamSupport; | ||
| 9 | |||
| 10 | import javax.annotation.Nullable; | ||
| 11 | |||
| 12 | import org.jetbrains.annotations.ApiStatus; | ||
| 13 | import net.fabricmc.mappingio.MappedElementKind; | ||
| 14 | import net.fabricmc.mappingio.tree.MemoryMappingTree; | ||
| 15 | import net.fabricmc.mappingio.tree.VisitableMappingTree; | ||
| 16 | import net.fabricmc.mappingio.tree.MappingTree.ClassMapping; | ||
| 17 | import net.fabricmc.mappingio.tree.MappingTree.FieldMapping; | ||
| 18 | import net.fabricmc.mappingio.tree.MappingTree.MethodArgMapping; | ||
| 19 | import net.fabricmc.mappingio.tree.MappingTree.MethodMapping; | ||
| 20 | import net.fabricmc.mappingio.tree.MappingTree.MethodVarMapping; | ||
| 21 | |||
| 22 | import cuchaz.enigma.ProgressListener; | ||
| 23 | import cuchaz.enigma.analysis.index.JarIndex; | ||
| 24 | import cuchaz.enigma.translation.mapping.EntryMap; | ||
| 25 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 26 | import cuchaz.enigma.translation.mapping.tree.EntryTree; | ||
| 27 | import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; | ||
| 28 | import cuchaz.enigma.translation.mapping.tree.HashEntryTree; | ||
| 29 | import cuchaz.enigma.translation.representation.MethodDescriptor; | ||
| 30 | import cuchaz.enigma.translation.representation.TypeDescriptor; | ||
| 31 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | ||
| 32 | import cuchaz.enigma.translation.representation.entry.Entry; | ||
| 33 | import cuchaz.enigma.translation.representation.entry.FieldEntry; | ||
| 34 | import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; | ||
| 35 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | ||
| 36 | import cuchaz.enigma.utils.I18n; | ||
| 37 | |||
| 38 | @ApiStatus.Internal | ||
| 39 | public class MappingIoConverter { | ||
| 40 | public static VisitableMappingTree toMappingIo(EntryTree<EntryMapping> mappings, ProgressListener progress) { | ||
| 41 | return toMappingIo(mappings, progress, "intermediary", "named"); | ||
| 42 | } | ||
| 43 | |||
| 44 | public static VisitableMappingTree toMappingIo(EntryTree<EntryMapping> mappings, ProgressListener progress, String fromNs, String toNs) { | ||
| 45 | try { | ||
| 46 | List<EntryTreeNode<EntryMapping>> classes = StreamSupport.stream(mappings.spliterator(), false) | ||
| 47 | .filter(node -> node.getEntry() instanceof ClassEntry) | ||
| 48 | .toList(); | ||
| 49 | |||
| 50 | progress.init(classes.size(), I18n.translate("progress.mappings.converting.to_mappingio")); | ||
| 51 | int stepsDone = 0; | ||
| 52 | |||
| 53 | MemoryMappingTree mappingTree = new MemoryMappingTree(); | ||
| 54 | mappingTree.visitNamespaces(fromNs, List.of(toNs)); | ||
| 55 | |||
| 56 | for (EntryTreeNode<EntryMapping> classNode : classes) { | ||
| 57 | progress.step(++stepsDone, classNode.getEntry().getFullName()); | ||
| 58 | writeClass(classNode, mappings, mappingTree); | ||
| 59 | } | ||
| 60 | |||
| 61 | mappingTree.visitEnd(); | ||
| 62 | return mappingTree; | ||
| 63 | } catch (IOException e) { | ||
| 64 | throw new UncheckedIOException(e); | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | private static void writeClass(EntryTreeNode<EntryMapping> classNode, EntryMap<EntryMapping> oldMappingTree, VisitableMappingTree newMappingTree) throws IOException { | ||
| 69 | ClassEntry classEntry = (ClassEntry) classNode.getEntry(); | ||
| 70 | EntryMapping mapping = oldMappingTree.get(classEntry); | ||
| 71 | Deque<String> parts = new LinkedList<>(); | ||
| 72 | |||
| 73 | newMappingTree.visitClass(classEntry.getFullName()); | ||
| 74 | newMappingTree.visitComment(MappedElementKind.CLASS, mapping.javadoc()); | ||
| 75 | |||
| 76 | do { | ||
| 77 | mapping = oldMappingTree.get(classEntry); | ||
| 78 | |||
| 79 | if (mapping != null && mapping.targetName() != null) { | ||
| 80 | parts.addFirst(mapping.targetName()); | ||
| 81 | } else { | ||
| 82 | parts.addFirst(classEntry.getName()); | ||
| 83 | } | ||
| 84 | |||
| 85 | classEntry = classEntry.getOuterClass(); | ||
| 86 | } while (classEntry != null); | ||
| 87 | |||
| 88 | String mappedName = String.join("$", parts); | ||
| 89 | newMappingTree.visitDstName(MappedElementKind.CLASS, 0, mappedName); | ||
| 90 | |||
| 91 | for (EntryTreeNode<EntryMapping> child : classNode.getChildNodes()) { | ||
| 92 | Entry<?> entry = child.getEntry(); | ||
| 93 | |||
| 94 | if (entry instanceof FieldEntry) { | ||
| 95 | writeField(child, newMappingTree); | ||
| 96 | } else if (entry instanceof MethodEntry) { | ||
| 97 | writeMethod(child, newMappingTree); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | private static void writeField(EntryTreeNode<EntryMapping> fieldNode, VisitableMappingTree mappingTree) throws IOException { | ||
| 103 | if (fieldNode.getValue() == null || fieldNode.getValue().equals(EntryMapping.DEFAULT)) { | ||
| 104 | return; // Shortcut | ||
| 105 | } | ||
| 106 | |||
| 107 | FieldEntry fieldEntry = ((FieldEntry) fieldNode.getEntry()); | ||
| 108 | mappingTree.visitField(fieldEntry.getName(), fieldEntry.getDesc().toString()); | ||
| 109 | |||
| 110 | EntryMapping fieldMapping = fieldNode.getValue(); | ||
| 111 | |||
| 112 | if (fieldMapping == null) { | ||
| 113 | fieldMapping = EntryMapping.DEFAULT; | ||
| 114 | } | ||
| 115 | |||
| 116 | mappingTree.visitDstName(MappedElementKind.FIELD, 0, fieldMapping.targetName()); | ||
| 117 | mappingTree.visitComment(MappedElementKind.FIELD, fieldMapping.javadoc()); | ||
| 118 | } | ||
| 119 | |||
| 120 | private static void writeMethod(EntryTreeNode<EntryMapping> methodNode, VisitableMappingTree mappingTree) throws IOException { | ||
| 121 | MethodEntry methodEntry = ((MethodEntry) methodNode.getEntry()); | ||
| 122 | mappingTree.visitMethod(methodEntry.getName(), methodEntry.getDesc().toString()); | ||
| 123 | |||
| 124 | EntryMapping methodMapping = methodNode.getValue(); | ||
| 125 | |||
| 126 | if (methodMapping == null) { | ||
| 127 | methodMapping = EntryMapping.DEFAULT; | ||
| 128 | } | ||
| 129 | |||
| 130 | mappingTree.visitDstName(MappedElementKind.METHOD, 0, methodMapping.targetName()); | ||
| 131 | mappingTree.visitComment(MappedElementKind.METHOD, methodMapping.javadoc()); | ||
| 132 | |||
| 133 | for (EntryTreeNode<EntryMapping> child : methodNode.getChildNodes()) { | ||
| 134 | Entry<?> entry = child.getEntry(); | ||
| 135 | |||
| 136 | if (entry instanceof LocalVariableEntry local) { | ||
| 137 | if (local.isArgument()) { | ||
| 138 | writeMethodArg(child, mappingTree); | ||
| 139 | } else { | ||
| 140 | writeMethodVar(child, mappingTree); | ||
| 141 | } | ||
| 142 | } | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 146 | private static void writeMethodArg(EntryTreeNode<EntryMapping> argNode, VisitableMappingTree mappingTree) throws IOException { | ||
| 147 | if (argNode.getValue() == null || argNode.getValue().equals(EntryMapping.DEFAULT)) { | ||
| 148 | return; // Shortcut | ||
| 149 | } | ||
| 150 | |||
| 151 | LocalVariableEntry argEntry = ((LocalVariableEntry) argNode.getEntry()); | ||
| 152 | mappingTree.visitMethodArg(-1, argEntry.getIndex(), argEntry.getName()); | ||
| 153 | |||
| 154 | EntryMapping argMapping = argNode.getValue(); | ||
| 155 | |||
| 156 | if (argMapping == null) { | ||
| 157 | argMapping = EntryMapping.DEFAULT; | ||
| 158 | } | ||
| 159 | |||
| 160 | mappingTree.visitDstName(MappedElementKind.METHOD_ARG, 0, argMapping.targetName()); | ||
| 161 | mappingTree.visitComment(MappedElementKind.METHOD_ARG, argMapping.javadoc()); | ||
| 162 | } | ||
| 163 | |||
| 164 | private static void writeMethodVar(EntryTreeNode<EntryMapping> varNode, VisitableMappingTree mappingTree) throws IOException { | ||
| 165 | if (varNode.getValue() == null || varNode.getValue().equals(EntryMapping.DEFAULT)) { | ||
| 166 | return; // Shortcut | ||
| 167 | } | ||
| 168 | |||
| 169 | LocalVariableEntry varEntry = ((LocalVariableEntry) varNode.getEntry()); | ||
| 170 | mappingTree.visitMethodVar(-1, varEntry.getIndex(), -1, -1, varEntry.getName()); | ||
| 171 | |||
| 172 | EntryMapping varMapping = varNode.getValue(); | ||
| 173 | |||
| 174 | if (varMapping == null) { | ||
| 175 | varMapping = EntryMapping.DEFAULT; | ||
| 176 | } | ||
| 177 | |||
| 178 | mappingTree.visitDstName(MappedElementKind.METHOD_VAR, 0, varMapping.targetName()); | ||
| 179 | mappingTree.visitComment(MappedElementKind.METHOD_VAR, varMapping.javadoc()); | ||
| 180 | } | ||
| 181 | |||
| 182 | public static EntryTree<EntryMapping> fromMappingIo(VisitableMappingTree mappingTree, ProgressListener progress, @Nullable JarIndex index) { | ||
| 183 | EntryTree<EntryMapping> dstMappingTree = new HashEntryTree<>(); | ||
| 184 | progress.init(mappingTree.getClasses().size(), I18n.translate("progress.mappings.converting.from_mappingio")); | ||
| 185 | int steps = 0; | ||
| 186 | |||
| 187 | for (ClassMapping classMapping : mappingTree.getClasses()) { | ||
| 188 | progress.step(steps++, classMapping.getDstName(0) != null ? classMapping.getDstName(0) : classMapping.getSrcName()); | ||
| 189 | readClass(classMapping, dstMappingTree, index); | ||
| 190 | } | ||
| 191 | |||
| 192 | return dstMappingTree; | ||
| 193 | } | ||
| 194 | |||
| 195 | private static void readClass(ClassMapping classMapping, EntryTree<EntryMapping> mappingTree, JarIndex index) { | ||
| 196 | ClassEntry currentClass = new ClassEntry(classMapping.getSrcName()); | ||
| 197 | String dstName = classMapping.getDstName(0); | ||
| 198 | |||
| 199 | if (dstName != null) { | ||
| 200 | dstName = dstName.substring(dstName.lastIndexOf('$') + 1); | ||
| 201 | } | ||
| 202 | |||
| 203 | mappingTree.insert(currentClass, new EntryMapping(dstName, classMapping.getComment())); | ||
| 204 | |||
| 205 | for (FieldMapping fieldMapping : classMapping.getFields()) { | ||
| 206 | readField(fieldMapping, currentClass, mappingTree, index); | ||
| 207 | } | ||
| 208 | |||
| 209 | for (MethodMapping methodMapping : classMapping.getMethods()) { | ||
| 210 | readMethod(methodMapping, currentClass, mappingTree); | ||
| 211 | } | ||
| 212 | } | ||
| 213 | |||
| 214 | private static void readField(FieldMapping fieldMapping, ClassEntry parent, EntryTree<EntryMapping> mappingTree, JarIndex index) { | ||
| 215 | String srcDesc = fieldMapping.getSrcDesc(); | ||
| 216 | FieldEntry[] fieldEntries; | ||
| 217 | |||
| 218 | if (srcDesc != null) { | ||
| 219 | fieldEntries = new FieldEntry[] { new FieldEntry(parent, fieldMapping.getSrcName(), new TypeDescriptor(fieldMapping.getSrcDesc())) }; | ||
| 220 | } else { | ||
| 221 | if (index == null) return; // Enigma requires source descriptors, and without an index we can't look them up | ||
| 222 | |||
| 223 | fieldEntries = index.getChildrenByClass().get(parent).stream() | ||
| 224 | .filter(entry -> entry instanceof FieldEntry) | ||
| 225 | .filter(entry -> entry.getName().equals(fieldMapping.getSrcName())) | ||
| 226 | .toArray(FieldEntry[]::new); | ||
| 227 | |||
| 228 | if (fieldEntries.length == 0) { // slow path for synthetics | ||
| 229 | fieldEntries = index.getEntryIndex().getFields().stream() | ||
| 230 | .filter(entry -> entry.getParent().getFullName().equals(parent.getFullName())) | ||
| 231 | .filter(entry -> { | ||
| 232 | if (entry.getName().equals(fieldMapping.getSrcName())) { | ||
| 233 | return true; | ||
| 234 | } else { | ||
| 235 | System.out.println("Entry name: " + entry.getName() + ", mapping name: " + fieldMapping.getSrcName()); | ||
| 236 | return false; | ||
| 237 | } | ||
| 238 | }) | ||
| 239 | .toArray(FieldEntry[]::new); | ||
| 240 | } | ||
| 241 | |||
| 242 | if (fieldEntries.length == 0) return; // No target found, invalid mapping | ||
| 243 | } | ||
| 244 | |||
| 245 | for (FieldEntry fieldEntry : fieldEntries) { | ||
| 246 | mappingTree.insert(fieldEntry, new EntryMapping(fieldMapping.getDstName(0), fieldMapping.getComment())); | ||
| 247 | } | ||
| 248 | } | ||
| 249 | |||
| 250 | private static void readMethod(MethodMapping methodMapping, ClassEntry parent, EntryTree<EntryMapping> mappingTree) { | ||
| 251 | MethodEntry currentMethod; | ||
| 252 | mappingTree.insert(currentMethod = new MethodEntry(parent, methodMapping.getSrcName(), new MethodDescriptor(methodMapping.getSrcDesc())), | ||
| 253 | new EntryMapping(methodMapping.getDstName(0), methodMapping.getComment())); | ||
| 254 | |||
| 255 | for (MethodArgMapping argMapping : methodMapping.getArgs()) { | ||
| 256 | readMethodArg(argMapping, currentMethod, mappingTree); | ||
| 257 | } | ||
| 258 | |||
| 259 | for (MethodVarMapping varMapping : methodMapping.getVars()) { | ||
| 260 | readMethodVar(varMapping, currentMethod, mappingTree); | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | private static void readMethodArg(MethodArgMapping argMapping, MethodEntry parent, EntryTree<EntryMapping> mappingTree) { | ||
| 265 | String srcName = argMapping.getSrcName() != null ? argMapping.getSrcName() : ""; | ||
| 266 | |||
| 267 | mappingTree.insert( | ||
| 268 | new LocalVariableEntry(parent, argMapping.getLvIndex(), srcName, true, null), | ||
| 269 | new EntryMapping(argMapping.getDstName(0), argMapping.getComment())); | ||
| 270 | } | ||
| 271 | |||
| 272 | private static void readMethodVar(MethodVarMapping varMapping, MethodEntry parent, EntryTree<EntryMapping> mappingTree) { | ||
| 273 | String srcName = varMapping.getSrcName() != null ? varMapping.getSrcName() : ""; | ||
| 274 | |||
| 275 | mappingTree.insert( | ||
| 276 | new LocalVariableEntry(parent, varMapping.getLvIndex(), srcName, false, null), | ||
| 277 | new EntryMapping(varMapping.getDstName(0), varMapping.getComment())); | ||
| 278 | } | ||
| 279 | } | ||
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java index 54613426..d5570e98 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java | |||
| @@ -40,12 +40,12 @@ public enum EnigmaMappingsReader implements MappingsReader { | |||
| 40 | FILE { | 40 | FILE { |
| 41 | @Override | 41 | @Override |
| 42 | public EntryTree<EntryMapping> read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException { | 42 | public EntryTree<EntryMapping> read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException { |
| 43 | progress.init(1, I18n.translate("progress.mappings.enigma_file.loading")); | 43 | progress.init(1, I18n.translate("progress.mappings.loading_file")); |
| 44 | 44 | ||
| 45 | EntryTree<EntryMapping> mappings = new HashEntryTree<>(); | 45 | EntryTree<EntryMapping> mappings = new HashEntryTree<>(); |
| 46 | readFile(path, mappings); | 46 | readFile(path, mappings); |
| 47 | 47 | ||
| 48 | progress.step(1, I18n.translate("progress.mappings.enigma_file.done")); | 48 | progress.step(1, I18n.translate("progress.done")); |
| 49 | 49 | ||
| 50 | return mappings; | 50 | return mappings; |
| 51 | } | 51 | } |
| @@ -60,7 +60,7 @@ public enum EnigmaMappingsReader implements MappingsReader { | |||
| 60 | EntryTree<EntryMapping> mappings = new HashEntryTree<>(); | 60 | EntryTree<EntryMapping> mappings = new HashEntryTree<>(); |
| 61 | List<Path> files = Files.walk(root).filter(f -> !Files.isDirectory(f)).filter(f -> f.toString().endsWith(".mapping")).toList(); | 61 | List<Path> files = Files.walk(root).filter(f -> !Files.isDirectory(f)).filter(f -> f.toString().endsWith(".mapping")).toList(); |
| 62 | 62 | ||
| 63 | progress.init(files.size(), I18n.translate("progress.mappings.enigma_directory.loading")); | 63 | progress.init(files.size(), I18n.translate("progress.mappings.loading_directory")); |
| 64 | int step = 0; | 64 | int step = 0; |
| 65 | 65 | ||
| 66 | for (Path file : files) { | 66 | for (Path file : files) { |
| @@ -102,7 +102,7 @@ public enum EnigmaMappingsReader implements MappingsReader { | |||
| 102 | throw new IllegalArgumentException("No paths to read mappings from"); | 102 | throw new IllegalArgumentException("No paths to read mappings from"); |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | progress.init(paths.length, I18n.translate("progress.mappings.enigma_directory.loading")); | 105 | progress.init(paths.length, I18n.translate("progress.mappings.loading_directory")); |
| 106 | int step = 0; | 106 | int step = 0; |
| 107 | 107 | ||
| 108 | for (Path file : paths) { | 108 | for (Path file : paths) { |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java index df1af912..73f29a16 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java | |||
| @@ -58,7 +58,7 @@ public enum EnigmaMappingsWriter implements MappingsWriter { | |||
| 58 | public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters) { | 58 | public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters) { |
| 59 | Collection<ClassEntry> classes = mappings.getRootNodes().filter(entry -> entry.getEntry() instanceof ClassEntry).map(entry -> (ClassEntry) entry.getEntry()).toList(); | 59 | Collection<ClassEntry> classes = mappings.getRootNodes().filter(entry -> entry.getEntry() instanceof ClassEntry).map(entry -> (ClassEntry) entry.getEntry()).toList(); |
| 60 | 60 | ||
| 61 | progress.init(classes.size(), I18n.translate("progress.mappings.enigma_file.writing")); | 61 | progress.init(classes.size(), I18n.translate("progress.mappings.writing")); |
| 62 | 62 | ||
| 63 | int steps = 0; | 63 | int steps = 0; |
| 64 | 64 | ||
| @@ -78,11 +78,9 @@ public enum EnigmaMappingsWriter implements MappingsWriter { | |||
| 78 | Collection<ClassEntry> changedClasses = delta.getChangedRoots().filter(entry -> entry instanceof ClassEntry).map(entry -> (ClassEntry) entry).toList(); | 78 | Collection<ClassEntry> changedClasses = delta.getChangedRoots().filter(entry -> entry instanceof ClassEntry).map(entry -> (ClassEntry) entry).toList(); |
| 79 | 79 | ||
| 80 | applyDeletions(path, changedClasses, mappings, delta.getBaseMappings(), saveParameters.getFileNameFormat()); | 80 | applyDeletions(path, changedClasses, mappings, delta.getBaseMappings(), saveParameters.getFileNameFormat()); |
| 81 | |||
| 82 | changedClasses = changedClasses.stream().filter(entry -> !isClassEmpty(mappings, entry)).collect(Collectors.toList()); | 81 | changedClasses = changedClasses.stream().filter(entry -> !isClassEmpty(mappings, entry)).collect(Collectors.toList()); |
| 83 | 82 | ||
| 84 | progress.init(changedClasses.size(), I18n.translate("progress.mappings.enigma_directory.writing")); | 83 | progress.init(changedClasses.size(), I18n.translate("progress.mappings.writing")); |
| 85 | |||
| 86 | AtomicInteger steps = new AtomicInteger(); | 84 | AtomicInteger steps = new AtomicInteger(); |
| 87 | 85 | ||
| 88 | Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE); | 86 | Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE); |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/srg/SrgMappingsWriter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/srg/SrgMappingsWriter.java index 4621efef..5addcade 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/srg/SrgMappingsWriter.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/srg/SrgMappingsWriter.java | |||
| @@ -45,7 +45,7 @@ public enum SrgMappingsWriter implements MappingsWriter { | |||
| 45 | List<String> methodLines = new ArrayList<>(); | 45 | List<String> methodLines = new ArrayList<>(); |
| 46 | 46 | ||
| 47 | List<? extends Entry<?>> rootEntries = Lists.newArrayList(mappings).stream().map(EntryTreeNode::getEntry).toList(); | 47 | List<? extends Entry<?>> rootEntries = Lists.newArrayList(mappings).stream().map(EntryTreeNode::getEntry).toList(); |
| 48 | progress.init(rootEntries.size(), I18n.translate("progress.mappings.srg_file.generating")); | 48 | progress.init(rootEntries.size(), I18n.translate("progress.mappings.converting")); |
| 49 | 49 | ||
| 50 | int steps = 0; | 50 | int steps = 0; |
| 51 | 51 | ||
| @@ -54,7 +54,7 @@ public enum SrgMappingsWriter implements MappingsWriter { | |||
| 54 | writeEntry(classLines, fieldLines, methodLines, mappings, entry); | 54 | writeEntry(classLines, fieldLines, methodLines, mappings, entry); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | progress.init(3, I18n.translate("progress.mappings.srg_file.writing")); | 57 | progress.init(3, I18n.translate("progress.mappings.writing")); |
| 58 | 58 | ||
| 59 | try (PrintWriter writer = new LfPrintWriter(Files.newBufferedWriter(path))) { | 59 | try (PrintWriter writer = new LfPrintWriter(Files.newBufferedWriter(path))) { |
| 60 | progress.step(0, I18n.translate("type.classes")); | 60 | progress.step(0, I18n.translate("type.classes")); |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsReader.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsReader.java index 534a567c..1575f468 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsReader.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsReader.java | |||
| @@ -35,7 +35,7 @@ public enum TinyMappingsReader implements MappingsReader { | |||
| 35 | EntryTree<EntryMapping> mappings = new HashEntryTree<>(); | 35 | EntryTree<EntryMapping> mappings = new HashEntryTree<>(); |
| 36 | lines.remove(0); | 36 | lines.remove(0); |
| 37 | 37 | ||
| 38 | progress.init(lines.size(), I18n.translate("progress.mappings.tiny_file.loading")); | 38 | progress.init(lines.size(), I18n.translate("progress.mappings.loading_file")); |
| 39 | 39 | ||
| 40 | for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { | 40 | for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { |
| 41 | progress.step(lineNumber, ""); | 41 | progress.step(lineNumber, ""); |
diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Reader.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Reader.java index eecbc35b..28185f58 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Reader.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Reader.java | |||
| @@ -46,7 +46,7 @@ public final class TinyV2Reader implements MappingsReader { | |||
| 46 | private EntryTree<EntryMapping> read(Path path, List<String> lines, ProgressListener progress) throws MappingParseException { | 46 | private EntryTree<EntryMapping> read(Path path, List<String> lines, ProgressListener progress) throws MappingParseException { |
| 47 | EntryTree<EntryMapping> mappings = new HashEntryTree<>(); | 47 | EntryTree<EntryMapping> mappings = new HashEntryTree<>(); |
| 48 | 48 | ||
| 49 | progress.init(lines.size(), "progress.mappings.tiny_v2.loading"); | 49 | progress.init(lines.size(), "progress.mappings.loading_file"); |
| 50 | 50 | ||
| 51 | BitSet state = new BitSet(STATE_SIZE); | 51 | BitSet state = new BitSet(STATE_SIZE); |
| 52 | @SuppressWarnings({"unchecked", "rawtypes"}) MappingPair<? extends Entry<?>, RawEntryMapping>[] holds = new MappingPair[STATE_SIZE]; | 52 | @SuppressWarnings({"unchecked", "rawtypes"}) MappingPair<? extends Entry<?>, RawEntryMapping>[] holds = new MappingPair[STATE_SIZE]; |
diff --git a/enigma/src/main/resources/lang/en_us.json b/enigma/src/main/resources/lang/en_us.json index 421620e9..2a3cfb2d 100644 --- a/enigma/src/main/resources/lang/en_us.json +++ b/enigma/src/main/resources/lang/en_us.json | |||
| @@ -137,6 +137,7 @@ | |||
| 137 | "log_panel.messages": "Messages", | 137 | "log_panel.messages": "Messages", |
| 138 | "log_panel.users": "Users", | 138 | "log_panel.users": "Users", |
| 139 | 139 | ||
| 140 | "progress.done": "Done!", | ||
| 140 | "progress.operation": "%s - Operation in progress", | 141 | "progress.operation": "%s - Operation in progress", |
| 141 | "progress.jar.indexing": "Indexing jar", | 142 | "progress.jar.indexing": "Indexing jar", |
| 142 | "progress.jar.indexing.entries": "Entries...", | 143 | "progress.jar.indexing.entries": "Entries...", |
| @@ -147,15 +148,12 @@ | |||
| 147 | "progress.sources.writing": "Writing sources...", | 148 | "progress.sources.writing": "Writing sources...", |
| 148 | "progress.classes.deobfuscating": "Deobfuscating classes...", | 149 | "progress.classes.deobfuscating": "Deobfuscating classes...", |
| 149 | "progress.classes.decompiling": "Decompiling classes...", | 150 | "progress.classes.decompiling": "Decompiling classes...", |
| 150 | "progress.mappings.enigma_file.loading": "Loading mapping file", | 151 | "progress.mappings.loading_file": "Loading mapping file", |
| 151 | "progress.mappings.enigma_file.done": "Done!", | 152 | "progress.mappings.loading_directory": "Loading mapping files", |
| 152 | "progress.mappings.enigma_file.writing": "Writing classes", | 153 | "progress.mappings.writing": "Writing classes", |
| 153 | "progress.mappings.enigma_directory.loading": "Loading mapping files", | 154 | "progress.mappings.converting": "Converting mappings", |
| 154 | "progress.mappings.enigma_directory.writing": "Writing classes", | 155 | "progress.mappings.converting.to_mappingio": "Converting to Mapping-IO", |
| 155 | "progress.mappings.tiny_file.loading": "Loading mapping file", | 156 | "progress.mappings.converting.from_mappingio": "Converting from Mapping-IO", |
| 156 | "progress.mappings.tiny_v2.loading": "Loading mapping file", | ||
| 157 | "progress.mappings.srg_file.generating": "Generating mappings", | ||
| 158 | "progress.mappings.srg_file.writing": "Writing mappings", | ||
| 159 | "progress.stats": "Generating stats", | 157 | "progress.stats": "Generating stats", |
| 160 | "progress.stats.data": "Generating data", | 158 | "progress.stats.data": "Generating data", |
| 161 | 159 | ||
diff --git a/enigma/src/main/resources/lang/fr_fr.json b/enigma/src/main/resources/lang/fr_fr.json index d3d0c297..520dd32e 100644 --- a/enigma/src/main/resources/lang/fr_fr.json +++ b/enigma/src/main/resources/lang/fr_fr.json | |||
| @@ -131,6 +131,7 @@ | |||
| 131 | "log_panel.messages": "Messages", | 131 | "log_panel.messages": "Messages", |
| 132 | "log_panel.users": "Utilisateurs", | 132 | "log_panel.users": "Utilisateurs", |
| 133 | 133 | ||
| 134 | "progress.done": "Terminé !", | ||
| 134 | "progress.operation": "%s - Opération en cours", | 135 | "progress.operation": "%s - Opération en cours", |
| 135 | "progress.jar.indexing": "Indexation du jar", | 136 | "progress.jar.indexing": "Indexation du jar", |
| 136 | "progress.jar.indexing.entries": "Entrées...", | 137 | "progress.jar.indexing.entries": "Entrées...", |
| @@ -141,15 +142,10 @@ | |||
| 141 | "progress.sources.writing": "Écriture des sources...", | 142 | "progress.sources.writing": "Écriture des sources...", |
| 142 | "progress.classes.deobfuscating": "Déobfuscation des classes...", | 143 | "progress.classes.deobfuscating": "Déobfuscation des classes...", |
| 143 | "progress.classes.decompiling": "Décompilation des classes...", | 144 | "progress.classes.decompiling": "Décompilation des classes...", |
| 144 | "progress.mappings.enigma_file.loading": "Chargement du fichier de mappings", | 145 | "progress.mappings.loading_file": "Chargement du fichier de mappings", |
| 145 | "progress.mappings.enigma_file.done": "Terminé !", | 146 | "progress.mappings.loading_directory": "Chargement des fichiers de mappings", |
| 146 | "progress.mappings.enigma_file.writing": "Écriture des classes", | 147 | "progress.mappings.writing": "Écriture des mappings", |
| 147 | "progress.mappings.enigma_directory.loading": "Chargement des fichiers de mappings", | 148 | "progress.mappings.converting": "Conversion des mappings", |
| 148 | "progress.mappings.enigma_directory.writing": "Écriture des classes", | ||
| 149 | "progress.mappings.tiny_file.loading": "Chargement du fichier de mappings", | ||
| 150 | "progress.mappings.tiny_v2.loading": "Chargement du fichier de mappings", | ||
| 151 | "progress.mappings.srg_file.generating": "Génération des mappings", | ||
| 152 | "progress.mappings.srg_file.writing": "Écriture des mappings", | ||
| 153 | "progress.stats": "Génération des statistiques", | 149 | "progress.stats": "Génération des statistiques", |
| 154 | "progress.stats.data": "Génération des données", | 150 | "progress.stats.data": "Génération des données", |
| 155 | 151 | ||
diff --git a/enigma/src/main/resources/lang/ja_jp.json b/enigma/src/main/resources/lang/ja_jp.json index 09e7ee08..b4d51998 100644 --- a/enigma/src/main/resources/lang/ja_jp.json +++ b/enigma/src/main/resources/lang/ja_jp.json | |||
| @@ -132,6 +132,7 @@ | |||
| 132 | "log_panel.messages": "メッセージ", | 132 | "log_panel.messages": "メッセージ", |
| 133 | "log_panel.users": "ユーザー", | 133 | "log_panel.users": "ユーザー", |
| 134 | 134 | ||
| 135 | "progress.done": "完了しました!", | ||
| 135 | "progress.operation": "%s - 処理中", | 136 | "progress.operation": "%s - 処理中", |
| 136 | "progress.jar.indexing": "jarのインデックス中", | 137 | "progress.jar.indexing": "jarのインデックス中", |
| 137 | "progress.jar.indexing.entries": "エントリー...", | 138 | "progress.jar.indexing.entries": "エントリー...", |
| @@ -142,15 +143,9 @@ | |||
| 142 | "progress.sources.writing": "ソースコードを書き出し中...", | 143 | "progress.sources.writing": "ソースコードを書き出し中...", |
| 143 | "progress.classes.deobfuscating": "クラスを難読化解除中...", | 144 | "progress.classes.deobfuscating": "クラスを難読化解除中...", |
| 144 | "progress.classes.decompiling": "クラスのデコンパイル中...", | 145 | "progress.classes.decompiling": "クラスのデコンパイル中...", |
| 145 | "progress.mappings.enigma_file.loading": "マッピングファイルをロード", | 146 | "progress.mappings.loading_file": "マッピングファイルをロード", |
| 146 | "progress.mappings.enigma_file.done": "完了しました!", | 147 | "progress.mappings.loading_directory": "マッピングファイルの読込中", |
| 147 | "progress.mappings.enigma_file.writing": "クラスの書き出し中", | 148 | "progress.mappings.writing": "マッピングの書き出し中", |
| 148 | "progress.mappings.enigma_directory.loading": "マッピングファイルの読込中", | ||
| 149 | "progress.mappings.enigma_directory.writing": "クラスの書き出し中", | ||
| 150 | "progress.mappings.tiny_file.loading": "マッピングファイルの読込中", | ||
| 151 | "progress.mappings.tiny_v2.loading": "マッピングファイルの読込中", | ||
| 152 | "progress.mappings.srg_file.generating": "マッピングの作成中", | ||
| 153 | "progress.mappings.srg_file.writing": "マッピングの書き出し中", | ||
| 154 | "progress.stats": "統計情報を作成中", | 149 | "progress.stats": "統計情報を作成中", |
| 155 | "progress.stats.data": "データの作成中", | 150 | "progress.stats.data": "データの作成中", |
| 156 | 151 | ||
diff --git a/enigma/src/main/resources/lang/zh_cn.json b/enigma/src/main/resources/lang/zh_cn.json index fe806fb3..dbc6dd33 100644 --- a/enigma/src/main/resources/lang/zh_cn.json +++ b/enigma/src/main/resources/lang/zh_cn.json | |||
| @@ -75,6 +75,7 @@ | |||
| 75 | "info_panel.tree.implementations": "实现", | 75 | "info_panel.tree.implementations": "实现", |
| 76 | "info_panel.tree.calls": "调用图", | 76 | "info_panel.tree.calls": "调用图", |
| 77 | 77 | ||
| 78 | "progress.done": "完成!", | ||
| 78 | "progress.operation": "%s - 进行中", | 79 | "progress.operation": "%s - 进行中", |
| 79 | "progress.jar.indexing": "索引 Jar", | 80 | "progress.jar.indexing": "索引 Jar", |
| 80 | "progress.jar.indexing.entries": "条目...", | 81 | "progress.jar.indexing.entries": "条目...", |
| @@ -85,15 +86,9 @@ | |||
| 85 | "progress.sources.writing": "写出源码中...", | 86 | "progress.sources.writing": "写出源码中...", |
| 86 | "progress.classes.deobfuscating": "反混淆类中...", | 87 | "progress.classes.deobfuscating": "反混淆类中...", |
| 87 | "progress.classes.decompiling": "反编译类中...", | 88 | "progress.classes.decompiling": "反编译类中...", |
| 88 | "progress.mappings.enigma_file.loading": "加载映射文件", | 89 | "progress.mappings.loading_file": "加载映射文件", |
| 89 | "progress.mappings.enigma_file.done": "完成!", | 90 | "progress.mappings.loading_directory": "加载映射文件", |
| 90 | "progress.mappings.enigma_file.writing": "写入类", | 91 | "progress.mappings.writing": "写出映射", |
| 91 | "progress.mappings.enigma_directory.loading": "加载映射文件", | ||
| 92 | "progress.mappings.enigma_directory.writing": "写入类", | ||
| 93 | "progress.mappings.tiny_file.loading": "加载映射文件", | ||
| 94 | "progress.mappings.tiny_v2.loading": "加载映射文件", | ||
| 95 | "progress.mappings.srg_file.generating": "生成映射", | ||
| 96 | "progress.mappings.srg_file.writing": "写出映射", | ||
| 97 | "progress.stats": "生成统计范围", | 92 | "progress.stats": "生成统计范围", |
| 98 | "progress.stats.data": "生成数据", | 93 | "progress.stats.data": "生成数据", |
| 99 | 94 | ||
diff --git a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java b/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java index 681fd3f2..25f11fbc 100644 --- a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java +++ b/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java | |||
| @@ -4,6 +4,7 @@ import java.io.File; | |||
| 4 | import java.io.IOException; | 4 | import java.io.IOException; |
| 5 | 5 | ||
| 6 | import org.junit.Assert; | 6 | import org.junit.Assert; |
| 7 | import org.junit.BeforeClass; | ||
| 7 | import org.junit.Test; | 8 | import org.junit.Test; |
| 8 | 9 | ||
| 9 | import cuchaz.enigma.ProgressListener; | 10 | import cuchaz.enigma.ProgressListener; |
| @@ -62,7 +63,7 @@ public class TestReadWriteCycle { | |||
| 62 | mappingFormat.write(testMappings, tempFile.toPath(), ProgressListener.none(), parameters); | 63 | mappingFormat.write(testMappings, tempFile.toPath(), ProgressListener.none(), parameters); |
| 63 | Assert.assertTrue("Written file not created", tempFile.exists()); | 64 | Assert.assertTrue("Written file not created", tempFile.exists()); |
| 64 | 65 | ||
| 65 | EntryTree<EntryMapping> loadedMappings = mappingFormat.read(tempFile.toPath(), ProgressListener.none(), parameters); | 66 | EntryTree<EntryMapping> loadedMappings = mappingFormat.read(tempFile.toPath(), ProgressListener.none(), parameters, null); |
| 66 | 67 | ||
| 67 | Assert.assertTrue("Loaded mappings don't contain testClazz", loadedMappings.contains(testClazz.a)); | 68 | Assert.assertTrue("Loaded mappings don't contain testClazz", loadedMappings.contains(testClazz.a)); |
| 68 | Assert.assertTrue("Loaded mappings don't contain testField1", loadedMappings.contains(testField1.a)); | 69 | Assert.assertTrue("Loaded mappings don't contain testField1", loadedMappings.contains(testField1.a)); |
| @@ -87,6 +88,11 @@ public class TestReadWriteCycle { | |||
| 87 | tempFile.delete(); | 88 | tempFile.delete(); |
| 88 | } | 89 | } |
| 89 | 90 | ||
| 91 | @BeforeClass | ||
| 92 | public static void setup() { | ||
| 93 | System.getProperties().setProperty("enigma.use_mappingio", "false"); | ||
| 94 | } | ||
| 95 | |||
| 90 | @Test | 96 | @Test |
| 91 | public void testEnigmaFile() throws IOException, MappingParseException { | 97 | public void testEnigmaFile() throws IOException, MappingParseException { |
| 92 | testReadWriteCycle(MappingFormat.ENIGMA_FILE, true, ".enigma"); | 98 | testReadWriteCycle(MappingFormat.ENIGMA_FILE, true, ".enigma"); |