diff options
Diffstat (limited to 'enigma')
3 files changed, 103 insertions, 20 deletions
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 f402c19..4d34720 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,10 +1,19 @@ | |||
| 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 | |||
| 8 | import cuchaz.enigma.ProgressListener; | 17 | import cuchaz.enigma.ProgressListener; |
| 9 | import cuchaz.enigma.translation.mapping.EntryMapping; | 18 | import cuchaz.enigma.translation.mapping.EntryMapping; |
| 10 | import cuchaz.enigma.translation.mapping.MappingDelta; | 19 | import cuchaz.enigma.translation.mapping.MappingDelta; |
| @@ -19,27 +28,30 @@ import cuchaz.enigma.translation.mapping.serde.tiny.TinyMappingsWriter; | |||
| 19 | import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Reader; | 28 | import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Reader; |
| 20 | import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer; | 29 | import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer; |
| 21 | import cuchaz.enigma.translation.mapping.tree.EntryTree; | 30 | import cuchaz.enigma.translation.mapping.tree.EntryTree; |
| 31 | import cuchaz.enigma.utils.I18n; | ||
| 22 | 32 | ||
| 23 | public enum MappingFormat { | 33 | public enum MappingFormat { |
| 24 | ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_FILE), | 34 | ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_FILE, true), |
| 25 | ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_DIR), | 35 | ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_DIR, true), |
| 26 | ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP, null), | 36 | ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP, null, false), |
| 27 | TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader(), net.fabricmc.mappingio.format.MappingFormat.TINY_2_FILE), | 37 | TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader(), net.fabricmc.mappingio.format.MappingFormat.TINY_2_FILE, true), |
| 28 | TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.TINY_FILE), | 38 | TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.TINY_FILE, true), |
| 29 | SRG_FILE(SrgMappingsWriter.INSTANCE, null, net.fabricmc.mappingio.format.MappingFormat.SRG_FILE), | 39 | SRG_FILE(SrgMappingsWriter.INSTANCE, null, net.fabricmc.mappingio.format.MappingFormat.SRG_FILE, false), |
| 30 | TSRG_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG_FILE), | 40 | TSRG_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG_FILE, false), |
| 31 | TSRG_2_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG_2_FILE), | 41 | TSRG_2_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG_2_FILE, false), |
| 32 | PROGUARD(null, ProguardMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.PROGUARD_FILE), | 42 | PROGUARD(null, ProguardMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.PROGUARD_FILE, true), |
| 33 | RECAF(RecafMappingsWriter.INSTANCE, RecafMappingsReader.INSTANCE, null); | 43 | RECAF(RecafMappingsWriter.INSTANCE, RecafMappingsReader.INSTANCE, null, false); |
| 34 | 44 | ||
| 35 | private final MappingsWriter writer; | 45 | private final MappingsWriter writer; |
| 36 | private final MappingsReader reader; | 46 | private final MappingsReader reader; |
| 37 | private final net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart; | 47 | private final net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart; |
| 48 | private final boolean hasMappingIoWriter; | ||
| 38 | 49 | ||
| 39 | MappingFormat(MappingsWriter writer, MappingsReader reader, net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart) { | 50 | MappingFormat(MappingsWriter writer, MappingsReader reader, net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart, boolean hasMappingIoWriter) { |
| 40 | this.writer = writer; | 51 | this.writer = writer; |
| 41 | this.reader = reader; | 52 | this.reader = reader; |
| 42 | this.mappingIoCounterpart = mappingIoCounterpart; | 53 | this.mappingIoCounterpart = mappingIoCounterpart; |
| 54 | this.hasMappingIoWriter = hasMappingIoWriter; | ||
| 43 | } | 55 | } |
| 44 | 56 | ||
| 45 | public void write(EntryTree<EntryMapping> mappings, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { | 57 | public void write(EntryTree<EntryMapping> mappings, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { |
| @@ -47,19 +59,49 @@ public enum MappingFormat { | |||
| 47 | } | 59 | } |
| 48 | 60 | ||
| 49 | public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { | 61 | public void write(EntryTree<EntryMapping> mappings, MappingDelta<EntryMapping> delta, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { |
| 50 | if (writer == null) { | 62 | if (!hasMappingIoWriter || !useMappingIo()) { |
| 51 | throw new IllegalStateException(name() + " does not support writing"); | 63 | if (writer == null) { |
| 64 | throw new IllegalStateException(name() + " does not support writing"); | ||
| 65 | } | ||
| 66 | |||
| 67 | writer.write(mappings, delta, path, progressListener, saveParameters); | ||
| 68 | return; | ||
| 52 | } | 69 | } |
| 53 | 70 | ||
| 54 | writer.write(mappings, delta, path, progressListener, saveParameters); | 71 | try { |
| 72 | VisitableMappingTree tree = MappingIoConverter.toMappingIo(mappings, progressListener); | ||
| 73 | progressListener.init(1, I18n.translate("progress.mappings.writing")); | ||
| 74 | progressListener.step(1, null); // Reset message | ||
| 75 | |||
| 76 | tree.accept(MappingWriter.create(path, mappingIoCounterpart), VisitOrder.createByName()); | ||
| 77 | progressListener.step(1, I18n.translate("progress.done")); | ||
| 78 | } catch (IOException e) { | ||
| 79 | throw new UncheckedIOException(e); | ||
| 80 | } | ||
| 55 | } | 81 | } |
| 56 | 82 | ||
| 57 | public EntryTree<EntryMapping> read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) throws IOException, MappingParseException { | 83 | public EntryTree<EntryMapping> read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) throws IOException, MappingParseException { |
| 58 | if (reader == null) { | 84 | if (!useMappingIo()) { |
| 59 | throw new IllegalStateException(name() + " does not support reading"); | 85 | if (reader == null) { |
| 86 | throw new IllegalStateException(name() + " does not support reading"); | ||
| 87 | } | ||
| 88 | |||
| 89 | return reader.read(path, progressListener, saveParameters); | ||
| 60 | } | 90 | } |
| 61 | 91 | ||
| 62 | return reader.read(path, progressListener, saveParameters); | 92 | String loadingMessage; |
| 93 | |||
| 94 | if (mappingIoCounterpart.hasSingleFile()) { | ||
| 95 | loadingMessage = I18n.translate("progress.mappings.loading_file"); | ||
| 96 | } else { | ||
| 97 | loadingMessage = I18n.translate("progress.mappings.loading_directory"); | ||
| 98 | } | ||
| 99 | |||
| 100 | progressListener.init(1, loadingMessage); | ||
| 101 | |||
| 102 | VisitableMappingTree mappingTree = new MemoryMappingTree(); | ||
| 103 | MappingReader.read(path, mappingIoCounterpart, mappingTree); | ||
| 104 | return MappingIoConverter.fromMappingIo(mappingTree, progressListener); | ||
| 63 | } | 105 | } |
| 64 | 106 | ||
| 65 | @Nullable | 107 | @Nullable |
| @@ -76,4 +118,35 @@ public enum MappingFormat { | |||
| 76 | public net.fabricmc.mappingio.format.MappingFormat getMappingIoCounterpart() { | 118 | public net.fabricmc.mappingio.format.MappingFormat getMappingIoCounterpart() { |
| 77 | return mappingIoCounterpart; | 119 | return mappingIoCounterpart; |
| 78 | } | 120 | } |
| 121 | |||
| 122 | public boolean hasMappingIoWriter() { | ||
| 123 | return hasMappingIoWriter; | ||
| 124 | } | ||
| 125 | |||
| 126 | public boolean isReadable() { | ||
| 127 | return reader != null || mappingIoCounterpart != null; | ||
| 128 | } | ||
| 129 | |||
| 130 | public boolean isWritable() { | ||
| 131 | return writer != null || hasMappingIoWriter; | ||
| 132 | } | ||
| 133 | |||
| 134 | private boolean useMappingIo() { | ||
| 135 | if (mappingIoCounterpart == null) return false; | ||
| 136 | return System.getProperty("enigma.use_mappingio", "true").equals("true"); | ||
| 137 | } | ||
| 138 | |||
| 139 | public static List<MappingFormat> getReadableFormats() { | ||
| 140 | return Arrays.asList(values()) | ||
| 141 | .stream() | ||
| 142 | .filter(MappingFormat::isReadable) | ||
| 143 | .toList(); | ||
| 144 | } | ||
| 145 | |||
| 146 | public static List<MappingFormat> getWritableFormats() { | ||
| 147 | return Arrays.asList(values()) | ||
| 148 | .stream() | ||
| 149 | .filter(MappingFormat::isWritable) | ||
| 150 | .toList(); | ||
| 151 | } | ||
| 79 | } | 152 | } |
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 index a0912fa..4372585 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java | |||
| @@ -33,19 +33,23 @@ import cuchaz.enigma.utils.I18n; | |||
| 33 | 33 | ||
| 34 | public class MappingIoConverter { | 34 | public class MappingIoConverter { |
| 35 | public static VisitableMappingTree toMappingIo(EntryTree<EntryMapping> mappings, ProgressListener progress) { | 35 | public static VisitableMappingTree toMappingIo(EntryTree<EntryMapping> mappings, ProgressListener progress) { |
| 36 | return toMappingIo(mappings, progress, "intermediary", "named"); | ||
| 37 | } | ||
| 38 | |||
| 39 | public static VisitableMappingTree toMappingIo(EntryTree<EntryMapping> mappings, ProgressListener progress, String fromNs, String toNs) { | ||
| 36 | try { | 40 | try { |
| 37 | List<EntryTreeNode<EntryMapping>> classes = StreamSupport.stream(mappings.spliterator(), false) | 41 | List<EntryTreeNode<EntryMapping>> classes = StreamSupport.stream(mappings.spliterator(), false) |
| 38 | .filter(node -> node.getEntry() instanceof ClassEntry) | 42 | .filter(node -> node.getEntry() instanceof ClassEntry) |
| 39 | .toList(); | 43 | .toList(); |
| 40 | 44 | ||
| 41 | progress.init(classes.size(), I18n.translate("progress.mappings.converting.to_mappingio")); | 45 | progress.init(classes.size(), I18n.translate("progress.mappings.converting.to_mappingio")); |
| 42 | int steps = 0; | 46 | int stepsDone = 0; |
| 43 | 47 | ||
| 44 | MemoryMappingTree mappingTree = new MemoryMappingTree(); | 48 | MemoryMappingTree mappingTree = new MemoryMappingTree(); |
| 45 | mappingTree.visitNamespaces("intermediary", List.of("named")); | 49 | mappingTree.visitNamespaces(fromNs, List.of(toNs)); |
| 46 | 50 | ||
| 47 | for (EntryTreeNode<EntryMapping> classNode : classes) { | 51 | for (EntryTreeNode<EntryMapping> classNode : classes) { |
| 48 | progress.step(steps++, classNode.getEntry().getFullName()); | 52 | progress.step(++stepsDone, classNode.getEntry().getFullName()); |
| 49 | writeClass(classNode, mappings, mappingTree); | 53 | writeClass(classNode, mappings, mappingTree); |
| 50 | } | 54 | } |
| 51 | 55 | ||
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 681fd3f..34d5a6e 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; |
| @@ -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"); |