summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java
diff options
context:
space:
mode:
authorGravatar Runemoro2019-06-25 08:37:35 -0400
committerGravatar Gegy2019-06-25 14:37:35 +0200
commita4346a90701f3041d264edd428de000e3c8ff95a (patch)
tree13a679d86e7039a334336ad09810796df1ccac68 /src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java
parentMerge pull request #151 from Runemoro/master (diff)
downloadenigma-fork-a4346a90701f3041d264edd428de000e3c8ff95a.tar.gz
enigma-fork-a4346a90701f3041d264edd428de000e3c8ff95a.tar.xz
enigma-fork-a4346a90701f3041d264edd428de000e3c8ff95a.zip
Add compose, convert, and invert commands (#152)
* Add compose and invert commands and add support for conversion to tiny mappings * Improvements suggested by liach * Use Translator to get right entries
Diffstat (limited to 'src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java')
-rw-r--r--src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java152
1 files changed, 152 insertions, 0 deletions
diff --git a/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java b/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java
new file mode 100644
index 0000000..4679575
--- /dev/null
+++ b/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java
@@ -0,0 +1,152 @@
1package cuchaz.enigma.command;
2
3import cuchaz.enigma.ProgressListener;
4import cuchaz.enigma.throwables.MappingParseException;
5import cuchaz.enigma.translation.MappingTranslator;
6import cuchaz.enigma.translation.Translator;
7import cuchaz.enigma.translation.mapping.EntryMapping;
8import cuchaz.enigma.translation.mapping.VoidEntryResolver;
9import cuchaz.enigma.translation.mapping.serde.*;
10import cuchaz.enigma.translation.mapping.tree.EntryTree;
11import cuchaz.enigma.translation.mapping.tree.EntryTreeNode;
12import cuchaz.enigma.translation.mapping.tree.HashEntryTree;
13import cuchaz.enigma.translation.representation.entry.ClassEntry;
14import cuchaz.enigma.translation.representation.entry.Entry;
15import cuchaz.enigma.translation.representation.entry.FieldEntry;
16import cuchaz.enigma.translation.representation.entry.MethodEntry;
17
18import java.io.IOException;
19import java.nio.file.Path;
20import java.util.HashMap;
21import java.util.HashSet;
22import java.util.Map;
23import java.util.Set;
24
25public final class MappingCommandsUtil {
26 public static void main(String[] args) throws Exception {
27 new InvertMappingsCommand().run(
28 "enigma",
29 "D:\\IdeaProjects\\yarn\\mappings",
30 "enigma",
31 "D:\\IdeaProjects\\Enigma\\converted");
32 }
33
34 private MappingCommandsUtil() {}
35
36 public static EntryTree<EntryMapping> invert(EntryTree<EntryMapping> mappings) {
37 Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE);
38 EntryTree<EntryMapping> result = new HashEntryTree<>();
39
40 for (EntryTreeNode<EntryMapping> node : mappings) {
41 Entry<?> leftEntry = node.getEntry();
42 EntryMapping leftMapping = node.getValue();
43
44 if (!(leftEntry instanceof ClassEntry || leftEntry instanceof MethodEntry || leftEntry instanceof FieldEntry)) {
45 result.insert(translator.translate(leftEntry), leftMapping);
46 continue;
47 }
48
49 Entry<?> rightEntry = translator.translate(leftEntry);
50
51 result.insert(rightEntry, leftMapping == null ? null : new EntryMapping(leftEntry.getName())); // TODO: leftMapping.withName once javadoc PR is merged
52 }
53
54 return result;
55 }
56
57 @SuppressWarnings("unchecked")
58 public static EntryTree<EntryMapping> compose(EntryTree<EntryMapping> left, EntryTree<EntryMapping> right, boolean keepLeftOnly, boolean keepRightOnly) {
59 Translator leftTranslator = new MappingTranslator(left, VoidEntryResolver.INSTANCE);
60 EntryTree<EntryMapping> result = new HashEntryTree<>();
61 Map<Entry<?>, Entry<?>> rightToLeft = new HashMap<>();
62 Set<Entry<?>> addedMappings = new HashSet<>();
63
64 for (EntryTreeNode<EntryMapping> node : left) {
65 Entry<?> leftEntry = node.getEntry();
66 EntryMapping leftMapping = node.getValue();
67
68 Entry<?> rightEntry = leftTranslator.translate(leftEntry);
69 rightToLeft.put(rightEntry, leftEntry);
70
71 EntryMapping rightMapping = right.get(rightEntry);
72 if (rightMapping != null) {
73 result.insert(leftEntry, rightMapping);
74 addedMappings.add(rightEntry);
75 } else if (keepLeftOnly) {
76 result.insert(leftEntry, leftMapping);
77 }
78 }
79
80 if (keepRightOnly) {
81 for (EntryTreeNode<EntryMapping> node : right) {
82 Entry<?> rightEntry = node.getEntry();
83 EntryMapping rightMapping = node.getValue();
84
85 if (addedMappings.contains(rightEntry)) {
86 continue;
87 }
88
89 Entry<?> parent = rightEntry.getParent();
90 Entry<?> correctEntry = rightEntry;
91 if (rightToLeft.containsKey(parent)) {
92 correctEntry = ((Entry<Entry<?>>) rightEntry).withParent(rightToLeft.get(parent));
93 }
94
95 result.insert(correctEntry, rightMapping);
96 rightToLeft.put(rightEntry, correctEntry);
97 }
98 }
99 return result;
100 }
101
102 public static EntryTree<EntryMapping> read(String type, Path path) throws MappingParseException, IOException {
103 if (type.equals("enigma")) {
104 return EnigmaMappingsReader.DIRECTORY.read(path, ProgressListener.none());
105 }
106
107 if (type.equals("tiny")) {
108 return TinyMappingsReader.INSTANCE.read(path, ProgressListener.none());
109 }
110
111 MappingFormat format = null;
112 try {
113 format = MappingFormat.valueOf(type.toUpperCase());
114 } catch (IllegalArgumentException ignored) {}
115
116 if (format != null) {
117 return format.getReader().read(path, ProgressListener.none());
118 }
119
120 throw new IllegalArgumentException("no reader for " + type);
121 }
122
123 public static void write(EntryTree<EntryMapping> mappings, String type, Path path) {
124 if (type.equals("enigma")) {
125 EnigmaMappingsWriter.DIRECTORY.write(mappings, path, ProgressListener.none());
126 return;
127 }
128
129 if (type.startsWith("tiny")) {
130 String[] split = type.split(":");
131
132 if (split.length != 3) {
133 throw new IllegalArgumentException("specify column names as 'tiny:from_column:to_column'");
134 }
135
136 new TinyMappingsWriter(split[1], split[2]).write(mappings, path, ProgressListener.none());
137 return;
138 }
139
140 MappingFormat format = null;
141 try {
142 format = MappingFormat.valueOf(type.toUpperCase());
143 } catch (IllegalArgumentException ignored) {}
144
145 if (format != null) {
146 format.getWriter().write(mappings, path, ProgressListener.none());
147 return;
148 }
149
150 throw new IllegalArgumentException("no writer for " + type);
151 }
152}