summaryrefslogtreecommitdiff
path: root/enigma
diff options
context:
space:
mode:
authorGravatar modmuss2023-11-28 09:00:33 +0000
committerGravatar GitHub2023-11-28 09:00:33 +0000
commit7622b753d2a99bd8f2bbb4568fd84ca9458ffba5 (patch)
treee3a5a6d2006787f2668e47bca34fb46beb40250c /enigma
parentUpdate deps (#535) (diff)
parentMerge branch 'upstream' into mapping-io (diff)
downloadenigma-fork-7622b753d2a99bd8f2bbb4568fd84ca9458ffba5.tar.gz
enigma-fork-7622b753d2a99bd8f2bbb4568fd84ca9458ffba5.tar.xz
enigma-fork-7622b753d2a99bd8f2bbb4568fd84ca9458ffba5.zip
Merge pull request #463 from NebelNidas/mapping-io
Initial Mapping-IO support
Diffstat (limited to 'enigma')
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java127
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java279
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java8
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java6
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/srg/SrgMappingsWriter.java4
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsReader.java2
-rw-r--r--enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Reader.java2
-rw-r--r--enigma/src/main/resources/lang/en_us.json16
-rw-r--r--enigma/src/main/resources/lang/fr_fr.json14
-rw-r--r--enigma/src/main/resources/lang/ja_jp.json13
-rw-r--r--enigma/src/main/resources/lang/zh_cn.json13
-rw-r--r--enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java8
12 files changed, 428 insertions, 64 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 367af3b..4521591 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 @@
1package cuchaz.enigma.translation.mapping.serde; 1package cuchaz.enigma.translation.mapping.serde;
2 2
3import java.io.IOException; 3import java.io.IOException;
4import java.io.UncheckedIOException;
4import java.nio.file.Path; 5import java.nio.file.Path;
6import java.util.Arrays;
7import java.util.List;
5 8
6import javax.annotation.Nullable; 9import javax.annotation.Nullable;
7 10
11import net.fabricmc.mappingio.MappingReader;
12import net.fabricmc.mappingio.MappingWriter;
13import net.fabricmc.mappingio.tree.MemoryMappingTree;
14import net.fabricmc.mappingio.tree.VisitOrder;
15import net.fabricmc.mappingio.tree.VisitableMappingTree;
16import org.jetbrains.annotations.ApiStatus;
17
8import cuchaz.enigma.ProgressListener; 18import cuchaz.enigma.ProgressListener;
19import cuchaz.enigma.analysis.index.JarIndex;
9import cuchaz.enigma.translation.mapping.EntryMapping; 20import cuchaz.enigma.translation.mapping.EntryMapping;
10import cuchaz.enigma.translation.mapping.MappingDelta; 21import cuchaz.enigma.translation.mapping.MappingDelta;
11import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader; 22import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader;
@@ -19,23 +30,33 @@ import cuchaz.enigma.translation.mapping.serde.tiny.TinyMappingsWriter;
19import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Reader; 30import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Reader;
20import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer; 31import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer;
21import cuchaz.enigma.translation.mapping.tree.EntryTree; 32import cuchaz.enigma.translation.mapping.tree.EntryTree;
33import cuchaz.enigma.utils.I18n;
22 34
23public enum MappingFormat { 35public 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 0000000..3843d8e
--- /dev/null
+++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java
@@ -0,0 +1,279 @@
1package cuchaz.enigma.translation.mapping.serde;
2
3import java.io.IOException;
4import java.io.UncheckedIOException;
5import java.util.Deque;
6import java.util.LinkedList;
7import java.util.List;
8import java.util.stream.StreamSupport;
9
10import javax.annotation.Nullable;
11
12import org.jetbrains.annotations.ApiStatus;
13import net.fabricmc.mappingio.MappedElementKind;
14import net.fabricmc.mappingio.tree.MemoryMappingTree;
15import net.fabricmc.mappingio.tree.VisitableMappingTree;
16import net.fabricmc.mappingio.tree.MappingTree.ClassMapping;
17import net.fabricmc.mappingio.tree.MappingTree.FieldMapping;
18import net.fabricmc.mappingio.tree.MappingTree.MethodArgMapping;
19import net.fabricmc.mappingio.tree.MappingTree.MethodMapping;
20import net.fabricmc.mappingio.tree.MappingTree.MethodVarMapping;
21
22import cuchaz.enigma.ProgressListener;
23import cuchaz.enigma.analysis.index.JarIndex;
24import cuchaz.enigma.translation.mapping.EntryMap;
25import cuchaz.enigma.translation.mapping.EntryMapping;
26import cuchaz.enigma.translation.mapping.tree.EntryTree;
27import cuchaz.enigma.translation.mapping.tree.EntryTreeNode;
28import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
29import cuchaz.enigma.translation.representation.MethodDescriptor;
30import cuchaz.enigma.translation.representation.TypeDescriptor;
31import cuchaz.enigma.translation.representation.entry.ClassEntry;
32import cuchaz.enigma.translation.representation.entry.Entry;
33import cuchaz.enigma.translation.representation.entry.FieldEntry;
34import cuchaz.enigma.translation.representation.entry.LocalVariableEntry;
35import cuchaz.enigma.translation.representation.entry.MethodEntry;
36import cuchaz.enigma.utils.I18n;
37
38@ApiStatus.Internal
39public 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 5461342..d5570e9 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 df1af91..73f29a1 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 4621efe..5addcad 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 534a567..1575f46 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 eecbc35..28185f5 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 421620e..2a3cfb2 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 d3d0c29..520dd32 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 09e7ee0..b4d5199 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 fe806fb..dbc6dd3 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 681fd3f..25f11fb 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;
4import java.io.IOException; 4import java.io.IOException;
5 5
6import org.junit.Assert; 6import org.junit.Assert;
7import org.junit.BeforeClass;
7import org.junit.Test; 8import org.junit.Test;
8 9
9import cuchaz.enigma.ProgressListener; 10import 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");