summaryrefslogtreecommitdiff
path: root/src/cuchaz
diff options
context:
space:
mode:
authorGravatar jeff2015-03-09 20:08:15 -0400
committerGravatar jeff2015-03-09 20:08:15 -0400
commit1ad33bfe0a96b1b4a1f3c02cf2c054e8a101dfd8 (patch)
tree86ce734a5bb32a7b205c096118faf41996521a43 /src/cuchaz
parentstarting on field matching gui (diff)
downloadenigma-fork-1ad33bfe0a96b1b4a1f3c02cf2c054e8a101dfd8.tar.gz
enigma-fork-1ad33bfe0a96b1b4a1f3c02cf2c054e8a101dfd8.tar.xz
enigma-fork-1ad33bfe0a96b1b4a1f3c02cf2c054e8a101dfd8.zip
field matcher is starting to be useful
Diffstat (limited to 'src/cuchaz')
-rw-r--r--src/cuchaz/enigma/ConvertMain.java135
-rw-r--r--src/cuchaz/enigma/analysis/JarIndex.java28
-rw-r--r--src/cuchaz/enigma/convert/FieldMatches.java69
-rw-r--r--src/cuchaz/enigma/convert/MatchesReader.java40
-rw-r--r--src/cuchaz/enigma/convert/MatchesWriter.java38
-rw-r--r--src/cuchaz/enigma/gui/ClassMatchingGui.java3
-rw-r--r--src/cuchaz/enigma/gui/CodeReader.java56
-rw-r--r--src/cuchaz/enigma/gui/FieldMatchingGui.java212
-rw-r--r--src/cuchaz/enigma/mapping/EntryFactory.java16
9 files changed, 525 insertions, 72 deletions
diff --git a/src/cuchaz/enigma/ConvertMain.java b/src/cuchaz/enigma/ConvertMain.java
index 624eb40..a5a00e8 100644
--- a/src/cuchaz/enigma/ConvertMain.java
+++ b/src/cuchaz/enigma/ConvertMain.java
@@ -4,8 +4,12 @@ import java.io.File;
4import java.io.FileReader; 4import java.io.FileReader;
5import java.io.FileWriter; 5import java.io.FileWriter;
6import java.io.IOException; 6import java.io.IOException;
7import java.util.Set;
7import java.util.jar.JarFile; 8import java.util.jar.JarFile;
8 9
10import com.google.common.collect.BiMap;
11import com.google.common.collect.Sets;
12
9import cuchaz.enigma.convert.ClassMatches; 13import cuchaz.enigma.convert.ClassMatches;
10import cuchaz.enigma.convert.FieldMatches; 14import cuchaz.enigma.convert.FieldMatches;
11import cuchaz.enigma.convert.MappingsConverter; 15import cuchaz.enigma.convert.MappingsConverter;
@@ -13,11 +17,18 @@ import cuchaz.enigma.convert.MatchesReader;
13import cuchaz.enigma.convert.MatchesWriter; 17import cuchaz.enigma.convert.MatchesWriter;
14import cuchaz.enigma.gui.ClassMatchingGui; 18import cuchaz.enigma.gui.ClassMatchingGui;
15import cuchaz.enigma.gui.FieldMatchingGui; 19import cuchaz.enigma.gui.FieldMatchingGui;
20import cuchaz.enigma.mapping.ClassEntry;
21import cuchaz.enigma.mapping.ClassMapping;
22import cuchaz.enigma.mapping.ClassNameReplacer;
23import cuchaz.enigma.mapping.EntryFactory;
24import cuchaz.enigma.mapping.FieldEntry;
25import cuchaz.enigma.mapping.FieldMapping;
16import cuchaz.enigma.mapping.MappingParseException; 26import cuchaz.enigma.mapping.MappingParseException;
17import cuchaz.enigma.mapping.Mappings; 27import cuchaz.enigma.mapping.Mappings;
18import cuchaz.enigma.mapping.MappingsChecker; 28import cuchaz.enigma.mapping.MappingsChecker;
19import cuchaz.enigma.mapping.MappingsReader; 29import cuchaz.enigma.mapping.MappingsReader;
20import cuchaz.enigma.mapping.MappingsWriter; 30import cuchaz.enigma.mapping.MappingsWriter;
31import cuchaz.enigma.mapping.Type;
21 32
22 33
23public class ConvertMain { 34public class ConvertMain {
@@ -32,13 +43,14 @@ public class ConvertMain {
32 File inMappingsFile = new File("../Enigma Mappings/1.8.mappings"); 43 File inMappingsFile = new File("../Enigma Mappings/1.8.mappings");
33 File outMappingsFile = new File("../Enigma Mappings/1.8.3.mappings"); 44 File outMappingsFile = new File("../Enigma Mappings/1.8.3.mappings");
34 Mappings mappings = new MappingsReader().read(new FileReader(inMappingsFile)); 45 Mappings mappings = new MappingsReader().read(new FileReader(inMappingsFile));
35 File classMatchingFile = new File(inMappingsFile.getName() + ".class.matching"); 46 File classMatchesFile = new File(inMappingsFile.getName() + ".class.matches");
36 File fieldMatchingFile = new File(inMappingsFile.getName() + ".field.matching"); 47 File fieldMatchesFile = new File(inMappingsFile.getName() + ".field.matches");
37 48
38 //computeMatches(classMatchingFile, sourceJar, destJar, mappings); 49 //computeClassMatches(classMatchingFile, sourceJar, destJar, mappings);
39 //editClasssMatches(classMatchingFile, sourceJar, destJar, mappings); 50 //editClasssMatches(classMatchingFile, sourceJar, destJar, mappings);
40 //convertMappings(outMappingsFile, sourceJar, destJar, mappings, classMatchingFile); 51 //convertMappings(outMappingsFile, sourceJar, destJar, mappings, classMatchingFile);
41 editFieldMatches(sourceJar, destJar, outMappingsFile, mappings, classMatchingFile, fieldMatchingFile); 52 //computeFieldMatches(fieldMatchesFile, destJar, outMappingsFile, classMatchesFile);
53 editFieldMatches(sourceJar, destJar, outMappingsFile, mappings, classMatchesFile, fieldMatchesFile);
42 54
43 /* TODO 55 /* TODO
44 // write out the converted mappings 56 // write out the converted mappings
@@ -49,17 +61,17 @@ public class ConvertMain {
49 */ 61 */
50 } 62 }
51 63
52 private static void computeMatches(File classMatchingFile, JarFile sourceJar, JarFile destJar, Mappings mappings) 64 private static void computeClassMatches(File classMatchesFile, JarFile sourceJar, JarFile destJar, Mappings mappings)
53 throws IOException { 65 throws IOException {
54 ClassMatches classMatches = MappingsConverter.computeMatches(sourceJar, destJar, mappings); 66 ClassMatches classMatches = MappingsConverter.computeMatches(sourceJar, destJar, mappings);
55 MatchesWriter.writeClasses(classMatches, classMatchingFile); 67 MatchesWriter.writeClasses(classMatches, classMatchesFile);
56 System.out.println("Wrote:\n\t" + classMatchingFile.getAbsolutePath()); 68 System.out.println("Wrote:\n\t" + classMatchesFile.getAbsolutePath());
57 } 69 }
58 70
59 private static void editClasssMatches(final File classMatchingFile, JarFile sourceJar, JarFile destJar, Mappings mappings) 71 private static void editClasssMatches(final File classMatchesFile, JarFile sourceJar, JarFile destJar, Mappings mappings)
60 throws IOException { 72 throws IOException {
61 System.out.println("Reading matches..."); 73 System.out.println("Reading class matches...");
62 ClassMatches classMatches = MatchesReader.readClasses(classMatchingFile); 74 ClassMatches classMatches = MatchesReader.readClasses(classMatchesFile);
63 Deobfuscators deobfuscators = new Deobfuscators(sourceJar, destJar); 75 Deobfuscators deobfuscators = new Deobfuscators(sourceJar, destJar);
64 deobfuscators.source.setMappings(mappings); 76 deobfuscators.source.setMappings(mappings);
65 System.out.println("Starting GUI..."); 77 System.out.println("Starting GUI...");
@@ -67,7 +79,7 @@ public class ConvertMain {
67 @Override 79 @Override
68 public void save(ClassMatches matches) { 80 public void save(ClassMatches matches) {
69 try { 81 try {
70 MatchesWriter.writeClasses(matches, classMatchingFile); 82 MatchesWriter.writeClasses(matches, classMatchesFile);
71 } catch (IOException ex) { 83 } catch (IOException ex) {
72 throw new Error(ex); 84 throw new Error(ex);
73 } 85 }
@@ -75,10 +87,10 @@ public class ConvertMain {
75 }); 87 });
76 } 88 }
77 89
78 private static void convertMappings(File outMappingsFile, JarFile sourceJar, JarFile destJar, Mappings mappings, File classMatchingFile) 90 private static void convertMappings(File outMappingsFile, JarFile sourceJar, JarFile destJar, Mappings mappings, File classMatchesFile)
79 throws IOException { 91 throws IOException {
80 System.out.println("Reading matches..."); 92 System.out.println("Reading class matches...");
81 ClassMatches classMatches = MatchesReader.readClasses(classMatchingFile); 93 ClassMatches classMatches = MatchesReader.readClasses(classMatchesFile);
82 Deobfuscators deobfuscators = new Deobfuscators(sourceJar, destJar); 94 Deobfuscators deobfuscators = new Deobfuscators(sourceJar, destJar);
83 deobfuscators.source.setMappings(mappings); 95 deobfuscators.source.setMappings(mappings);
84 96
@@ -90,19 +102,90 @@ public class ConvertMain {
90 System.out.println("Write converted mappings to: " + outMappingsFile.getAbsolutePath()); 102 System.out.println("Write converted mappings to: " + outMappingsFile.getAbsolutePath());
91 } 103 }
92 104
93 private static void editFieldMatches(JarFile sourceJar, JarFile destJar, File destMappingsFile, Mappings sourceMappings, File classMatchingFile, final File fieldMatchingFile) 105 private static void computeFieldMatches(File fieldMatchesFile, JarFile destJar, File destMappingsFile, File classMatchesFile)
94 throws IOException, MappingParseException { 106 throws IOException, MappingParseException {
95 107
96 System.out.println("Reading matches..."); 108 System.out.println("Reading class matches...");
97 ClassMatches classMatches = MatchesReader.readClasses(classMatchingFile); 109 ClassMatches classMatches = MatchesReader.readClasses(classMatchesFile);
98 FieldMatches fieldMatches; 110 System.out.println("Reading mappings...");
99 if (fieldMatchingFile.exists() /* TEMP */ && false) { 111 Mappings destMappings = new MappingsReader().read(new FileReader(destMappingsFile));
100 // TODO 112 System.out.println("Indexing dest jar...");
101 //fieldMatches = MatchesReader.readFields(fieldMatchingFile); 113 Deobfuscator destDeobfuscator = new Deobfuscator(destJar);
102 } else { 114
103 fieldMatches = new FieldMatches(); 115 System.out.println("Writing field matches...");
116
117 // get the matched and unmatched field mappings
118 FieldMatches fieldMatches = new FieldMatches();
119
120 // unmatched source fields are easy
121 MappingsChecker checker = new MappingsChecker(destDeobfuscator.getJarIndex());
122 checker.dropBrokenMappings(destMappings);
123 for (FieldEntry destObfField : checker.getDroppedFieldMappings().keySet()) {
124 FieldEntry srcObfField = translate(destObfField, classMatches.getUniqueMatches().inverse());
125 fieldMatches.addUnmatchedSourceField(srcObfField);
126 }
127
128 // get matched fields (anything that's left after the checks/drops is matched(
129 for (ClassMapping classMapping : destMappings.classes()) {
130 collectMatchedFields(fieldMatches, classMapping, classMatches);
131 }
132
133 // get unmatched dest fields
134 Set<FieldEntry> unmatchedDestFields = Sets.newHashSet();
135 for (FieldEntry destFieldEntry : destDeobfuscator.getJarIndex().getObfFieldEntries()) {
136 if (!fieldMatches.isDestMatched(destFieldEntry)) {
137 unmatchedDestFields.add(destFieldEntry);
138 }
139 }
140 fieldMatches.addUnmatchedDestFields(unmatchedDestFields);
141
142 MatchesWriter.writeFields(fieldMatches, fieldMatchesFile);
143 System.out.println("Wrote:\n\t" + fieldMatchesFile.getAbsolutePath());
144 }
145
146 private static void collectMatchedFields(FieldMatches fieldMatches, ClassMapping destClassMapping, ClassMatches classMatches) {
147
148 // get the fields for this class
149 for (FieldMapping destFieldMapping : destClassMapping.fields()) {
150 FieldEntry destObfField = EntryFactory.getObfFieldEntry(destClassMapping, destFieldMapping);
151 FieldEntry srcObfField = translate(destObfField, classMatches.getUniqueMatches().inverse());
152 fieldMatches.addMatch(srcObfField, destObfField);
104 } 153 }
105 154
155 // recurse
156 for (ClassMapping destInnerClassMapping : destClassMapping.innerClasses()) {
157 collectMatchedFields(fieldMatches, destInnerClassMapping, classMatches);
158 }
159 }
160
161 private static FieldEntry translate(FieldEntry in, BiMap<ClassEntry,ClassEntry> map) {
162 return new FieldEntry(
163 map.get(in.getClassEntry()),
164 in.getName(),
165 translate(in.getType(), map)
166 );
167 }
168
169 private static Type translate(Type type, final BiMap<ClassEntry,ClassEntry> map) {
170 return new Type(type, new ClassNameReplacer() {
171 @Override
172 public String replace(String inClassName) {
173 ClassEntry outClassEntry = map.get(new ClassEntry(inClassName));
174 if (outClassEntry == null) {
175 return null;
176 }
177 return outClassEntry.getName();
178 }
179 });
180 }
181
182 private static void editFieldMatches(JarFile sourceJar, JarFile destJar, File destMappingsFile, Mappings sourceMappings, File classMatchesFile, final File fieldMatchesFile)
183 throws IOException, MappingParseException {
184
185 System.out.println("Reading matches...");
186 ClassMatches classMatches = MatchesReader.readClasses(classMatchesFile);
187 FieldMatches fieldMatches = MatchesReader.readFields(fieldMatchesFile);
188
106 // prep deobfuscators 189 // prep deobfuscators
107 Deobfuscators deobfuscators = new Deobfuscators(sourceJar, destJar); 190 Deobfuscators deobfuscators = new Deobfuscators(sourceJar, destJar);
108 deobfuscators.source.setMappings(sourceMappings); 191 deobfuscators.source.setMappings(sourceMappings);
@@ -111,16 +194,14 @@ public class ConvertMain {
111 checker.dropBrokenMappings(destMappings); 194 checker.dropBrokenMappings(destMappings);
112 deobfuscators.dest.setMappings(destMappings); 195 deobfuscators.dest.setMappings(destMappings);
113 196
114 new FieldMatchingGui(classMatches, fieldMatches, checker.getDroppedFieldMappings(), deobfuscators.source, deobfuscators.dest).setSaveListener(new FieldMatchingGui.SaveListener() { 197 new FieldMatchingGui(classMatches, fieldMatches, deobfuscators.source, deobfuscators.dest).setSaveListener(new FieldMatchingGui.SaveListener() {
115 @Override 198 @Override
116 public void save(FieldMatches matches) { 199 public void save(FieldMatches matches) {
117 /* TODO
118 try { 200 try {
119 MatchesWriter.writeFields(matches, fieldMatchingFile); 201 MatchesWriter.writeFields(matches, fieldMatchesFile);
120 } catch (IOException ex) { 202 } catch (IOException ex) {
121 throw new Error(ex); 203 throw new Error(ex);
122 } 204 }
123 */
124 } 205 }
125 }); 206 });
126 } 207 }
diff --git a/src/cuchaz/enigma/analysis/JarIndex.java b/src/cuchaz/enigma/analysis/JarIndex.java
index e0a8bf5..7ebbd97 100644
--- a/src/cuchaz/enigma/analysis/JarIndex.java
+++ b/src/cuchaz/enigma/analysis/JarIndex.java
@@ -60,6 +60,8 @@ public class JarIndex {
60 private TranslationIndex m_translationIndex; 60 private TranslationIndex m_translationIndex;
61 private Multimap<String,String> m_interfaces; 61 private Multimap<String,String> m_interfaces;
62 private Map<Entry,Access> m_access; 62 private Map<Entry,Access> m_access;
63 private Multimap<ClassEntry,FieldEntry> m_fields;
64 private Multimap<ClassEntry,BehaviorEntry> m_behaviors;
63 private Multimap<String,MethodEntry> m_methodImplementations; 65 private Multimap<String,MethodEntry> m_methodImplementations;
64 private Multimap<BehaviorEntry,EntryReference<BehaviorEntry,BehaviorEntry>> m_behaviorReferences; 66 private Multimap<BehaviorEntry,EntryReference<BehaviorEntry,BehaviorEntry>> m_behaviorReferences;
65 private Multimap<FieldEntry,EntryReference<FieldEntry,BehaviorEntry>> m_fieldReferences; 67 private Multimap<FieldEntry,EntryReference<FieldEntry,BehaviorEntry>> m_fieldReferences;
@@ -73,6 +75,8 @@ public class JarIndex {
73 m_translationIndex = new TranslationIndex(); 75 m_translationIndex = new TranslationIndex();
74 m_interfaces = HashMultimap.create(); 76 m_interfaces = HashMultimap.create();
75 m_access = Maps.newHashMap(); 77 m_access = Maps.newHashMap();
78 m_fields = HashMultimap.create();
79 m_behaviors = HashMultimap.create();
76 m_methodImplementations = HashMultimap.create(); 80 m_methodImplementations = HashMultimap.create();
77 m_behaviorReferences = HashMultimap.create(); 81 m_behaviorReferences = HashMultimap.create();
78 m_fieldReferences = HashMultimap.create(); 82 m_fieldReferences = HashMultimap.create();
@@ -97,10 +101,14 @@ public class JarIndex {
97 for (CtClass c : JarClassIterator.classes(jar)) { 101 for (CtClass c : JarClassIterator.classes(jar)) {
98 ClassRenamer.moveAllClassesOutOfDefaultPackage(c, Constants.NonePackage); 102 ClassRenamer.moveAllClassesOutOfDefaultPackage(c, Constants.NonePackage);
99 for (CtField field : c.getDeclaredFields()) { 103 for (CtField field : c.getDeclaredFields()) {
100 m_access.put(EntryFactory.getFieldEntry(field), Access.get(field)); 104 FieldEntry fieldEntry = EntryFactory.getFieldEntry(field);
105 m_access.put(fieldEntry, Access.get(field));
106 m_fields.put(fieldEntry.getClassEntry(), fieldEntry);
101 } 107 }
102 for (CtBehavior behavior : c.getDeclaredBehaviors()) { 108 for (CtBehavior behavior : c.getDeclaredBehaviors()) {
103 m_access.put(EntryFactory.getBehaviorEntry(behavior), Access.get(behavior)); 109 BehaviorEntry behaviorEntry = EntryFactory.getBehaviorEntry(behavior);
110 m_access.put(behaviorEntry, Access.get(behavior));
111 m_behaviors.put(behaviorEntry.getClassEntry(), behaviorEntry);
104 } 112 }
105 } 113 }
106 114
@@ -520,6 +528,22 @@ public class JarIndex {
520 return m_obfClassEntries; 528 return m_obfClassEntries;
521 } 529 }
522 530
531 public Collection<FieldEntry> getObfFieldEntries() {
532 return m_fields.values();
533 }
534
535 public Collection<FieldEntry> getObfFieldEntries(ClassEntry classEntry) {
536 return m_fields.get(classEntry);
537 }
538
539 public Collection<BehaviorEntry> getObfBehaviorEntries() {
540 return m_behaviors.values();
541 }
542
543 public Collection<BehaviorEntry> getObfBehaviorEntries(ClassEntry classEntry) {
544 return m_behaviors.get(classEntry);
545 }
546
523 public TranslationIndex getTranslationIndex() { 547 public TranslationIndex getTranslationIndex() {
524 return m_translationIndex; 548 return m_translationIndex;
525 } 549 }
diff --git a/src/cuchaz/enigma/convert/FieldMatches.java b/src/cuchaz/enigma/convert/FieldMatches.java
index f78a8f5..6335974 100644
--- a/src/cuchaz/enigma/convert/FieldMatches.java
+++ b/src/cuchaz/enigma/convert/FieldMatches.java
@@ -5,7 +5,8 @@ import java.util.Set;
5 5
6import com.google.common.collect.BiMap; 6import com.google.common.collect.BiMap;
7import com.google.common.collect.HashBiMap; 7import com.google.common.collect.HashBiMap;
8import com.google.common.collect.Sets; 8import com.google.common.collect.HashMultimap;
9import com.google.common.collect.Multimap;
9 10
10import cuchaz.enigma.mapping.ClassEntry; 11import cuchaz.enigma.mapping.ClassEntry;
11import cuchaz.enigma.mapping.FieldEntry; 12import cuchaz.enigma.mapping.FieldEntry;
@@ -14,22 +15,70 @@ import cuchaz.enigma.mapping.FieldEntry;
14public class FieldMatches { 15public class FieldMatches {
15 16
16 private BiMap<FieldEntry,FieldEntry> m_matches; 17 private BiMap<FieldEntry,FieldEntry> m_matches;
17 private Set<FieldEntry> m_unmatchedSourceFields; 18 private Multimap<ClassEntry,FieldEntry> m_unmatchedSourceFields;
19 private Multimap<ClassEntry,FieldEntry> m_unmatchedDestFields;
18 20
19 public FieldMatches() { 21 public FieldMatches() {
20 m_matches = HashBiMap.create(); 22 m_matches = HashBiMap.create();
21 m_unmatchedSourceFields = Sets.newHashSet(); 23 m_unmatchedSourceFields = HashMultimap.create();
24 m_unmatchedDestFields = HashMultimap.create();
22 } 25 }
23 26
24 public void addUnmatchedSourceFields(Set<FieldEntry> fieldEntries) { 27 public void addMatch(FieldEntry srcField, FieldEntry destField) {
25 m_unmatchedSourceFields.addAll(fieldEntries); 28 m_matches.put(srcField, destField);
26 } 29 }
27 30
28 public Collection<ClassEntry> getSourceClassesWithUnmatchedFields() { 31 public void addUnmatchedSourceField(FieldEntry fieldEntry) {
29 Set<ClassEntry> classEntries = Sets.newHashSet(); 32 m_unmatchedSourceFields.put(fieldEntry.getClassEntry(), fieldEntry);
30 for (FieldEntry fieldEntry : m_unmatchedSourceFields) { 33 }
31 classEntries.add(fieldEntry.getClassEntry()); 34
35 public void addUnmatchedSourceFields(Iterable<FieldEntry> fieldEntries) {
36 for (FieldEntry fieldEntry : fieldEntries) {
37 addUnmatchedSourceField(fieldEntry);
38 }
39 }
40
41 public void addUnmatchedDestField(FieldEntry fieldEntry) {
42 m_unmatchedDestFields.put(fieldEntry.getClassEntry(), fieldEntry);
43 }
44
45 public void addUnmatchedDestFields(Iterable<FieldEntry> fieldEntries) {
46 for (FieldEntry fieldEntry : fieldEntries) {
47 addUnmatchedDestField(fieldEntry);
32 } 48 }
33 return classEntries; 49 }
50
51 public Set<ClassEntry> getSourceClassesWithUnmatchedFields() {
52 return m_unmatchedSourceFields.keySet();
53 }
54
55 public Collection<FieldEntry> getUnmatchedSourceFields() {
56 return m_unmatchedSourceFields.values();
57 }
58
59 public Collection<FieldEntry> getUnmatchedSourceFields(ClassEntry sourceClass) {
60 return m_unmatchedSourceFields.get(sourceClass);
61 }
62
63 public Collection<FieldEntry> getUnmatchedDestFields() {
64 return m_unmatchedDestFields.values();
65 }
66
67 public Collection<FieldEntry> getUnmatchedDestFields(ClassEntry sourceClass) {
68 return m_unmatchedDestFields.get(sourceClass);
69 }
70
71 public BiMap<FieldEntry,FieldEntry> matches() {
72 return m_matches;
73 }
74
75 public boolean isDestMatched(FieldEntry destFieldEntry) {
76 return m_matches.containsValue(destFieldEntry);
77 }
78
79 public void makeMatch(FieldEntry sourceField, FieldEntry destField) {
80 m_unmatchedSourceFields.remove(sourceField.getClassEntry(), sourceField);
81 m_unmatchedDestFields.remove(destField.getClassEntry(), destField);
82 m_matches.put(sourceField, destField);
34 } 83 }
35} 84}
diff --git a/src/cuchaz/enigma/convert/MatchesReader.java b/src/cuchaz/enigma/convert/MatchesReader.java
index b43535c..1dd042d 100644
--- a/src/cuchaz/enigma/convert/MatchesReader.java
+++ b/src/cuchaz/enigma/convert/MatchesReader.java
@@ -10,6 +10,8 @@ import java.util.List;
10import com.beust.jcommander.internal.Lists; 10import com.beust.jcommander.internal.Lists;
11 11
12import cuchaz.enigma.mapping.ClassEntry; 12import cuchaz.enigma.mapping.ClassEntry;
13import cuchaz.enigma.mapping.FieldEntry;
14import cuchaz.enigma.mapping.Type;
13 15
14 16
15public class MatchesReader { 17public class MatchesReader {
@@ -42,4 +44,42 @@ public class MatchesReader {
42 } 44 }
43 return entries; 45 return entries;
44 } 46 }
47
48 public static FieldMatches readFields(File file)
49 throws IOException {
50 try (BufferedReader in = new BufferedReader(new FileReader(file))) {
51 FieldMatches matches = new FieldMatches();
52 String line = null;
53 while ((line = in.readLine()) != null) {
54 readFieldMatch(matches, line);
55 }
56 return matches;
57 }
58 }
59
60 private static void readFieldMatch(FieldMatches matches, String line) {
61 String[] parts = line.split(":", 2);
62 FieldEntry source = readField(parts[0]);
63 FieldEntry dest = readField(parts[1]);
64 if (source != null && dest != null) {
65 matches.addMatch(source, dest);
66 } else if (source != null) {
67 matches.addUnmatchedSourceField(source);
68 } else if (dest != null) {
69 matches.addUnmatchedDestField(dest);
70 }
71 }
72
73 private static FieldEntry readField(String in) {
74 if (in.length() <= 0) {
75 return null;
76 }
77 String[] parts = in.split(" ");
78 assert(parts.length == 3);
79 return new FieldEntry(
80 new ClassEntry(parts[0]),
81 parts[1],
82 new Type(parts[2])
83 );
84 }
45} 85}
diff --git a/src/cuchaz/enigma/convert/MatchesWriter.java b/src/cuchaz/enigma/convert/MatchesWriter.java
index 6658e2a..6e371bc 100644
--- a/src/cuchaz/enigma/convert/MatchesWriter.java
+++ b/src/cuchaz/enigma/convert/MatchesWriter.java
@@ -3,8 +3,10 @@ package cuchaz.enigma.convert;
3import java.io.File; 3import java.io.File;
4import java.io.FileWriter; 4import java.io.FileWriter;
5import java.io.IOException; 5import java.io.IOException;
6import java.util.Map;
6 7
7import cuchaz.enigma.mapping.ClassEntry; 8import cuchaz.enigma.mapping.ClassEntry;
9import cuchaz.enigma.mapping.FieldEntry;
8 10
9 11
10public class MatchesWriter { 12public class MatchesWriter {
@@ -38,4 +40,40 @@ public class MatchesWriter {
38 out.write(entry.toString()); 40 out.write(entry.toString());
39 } 41 }
40 } 42 }
43
44 public static void writeFields(FieldMatches fieldMatches, File file)
45 throws IOException {
46 try (FileWriter out = new FileWriter(file)) {
47 for (Map.Entry<FieldEntry,FieldEntry> match : fieldMatches.matches().entrySet()) {
48 writeFieldMatch(out, match.getKey(), match.getValue());
49 }
50 for (FieldEntry fieldEntry : fieldMatches.getUnmatchedSourceFields()) {
51 writeFieldMatch(out, fieldEntry, null);
52 }
53 for (FieldEntry fieldEntry : fieldMatches.getUnmatchedDestFields()) {
54 writeFieldMatch(out, null, fieldEntry);
55 }
56 }
57 }
58
59 private static void writeFieldMatch(FileWriter out, FieldEntry source, FieldEntry dest)
60 throws IOException {
61 if (source != null) {
62 writeField(out, source);
63 }
64 out.write(":");
65 if (dest != null) {
66 writeField(out, dest);
67 }
68 out.write("\n");
69 }
70
71 private static void writeField(FileWriter out, FieldEntry fieldEntry)
72 throws IOException {
73 out.write(fieldEntry.getClassName());
74 out.write(" ");
75 out.write(fieldEntry.getName());
76 out.write(" ");
77 out.write(fieldEntry.getType().toString());
78 }
41} 79}
diff --git a/src/cuchaz/enigma/gui/ClassMatchingGui.java b/src/cuchaz/enigma/gui/ClassMatchingGui.java
index b674451..6943c3e 100644
--- a/src/cuchaz/enigma/gui/ClassMatchingGui.java
+++ b/src/cuchaz/enigma/gui/ClassMatchingGui.java
@@ -201,13 +201,10 @@ public class ClassMatchingGui {
201 201
202 m_sourceClassLabel = new JLabel(); 202 m_sourceClassLabel = new JLabel();
203 m_sourceClassLabel.setHorizontalAlignment(SwingConstants.RIGHT); 203 m_sourceClassLabel.setHorizontalAlignment(SwingConstants.RIGHT);
204 m_sourceClassLabel.setPreferredSize(new Dimension(300, 24));
205 m_destClassLabel = new JLabel(); 204 m_destClassLabel = new JLabel();
206 m_destClassLabel.setHorizontalAlignment(SwingConstants.LEFT); 205 m_destClassLabel.setHorizontalAlignment(SwingConstants.LEFT);
207 m_destClassLabel.setPreferredSize(new Dimension(300, 24));
208 206
209 m_matchButton = new JButton(); 207 m_matchButton = new JButton();
210 m_matchButton.setPreferredSize(new Dimension(140, 24));
211 208
212 m_advanceCheck = new JCheckBox("Advance to next likely match"); 209 m_advanceCheck = new JCheckBox("Advance to next likely match");
213 m_advanceCheck.addActionListener(new ActionListener() { 210 m_advanceCheck.addActionListener(new ActionListener() {
diff --git a/src/cuchaz/enigma/gui/CodeReader.java b/src/cuchaz/enigma/gui/CodeReader.java
index 05feb59..aa7e2db 100644
--- a/src/cuchaz/enigma/gui/CodeReader.java
+++ b/src/cuchaz/enigma/gui/CodeReader.java
@@ -7,12 +7,15 @@ import java.awt.event.ActionListener;
7import javax.swing.JEditorPane; 7import javax.swing.JEditorPane;
8import javax.swing.SwingUtilities; 8import javax.swing.SwingUtilities;
9import javax.swing.Timer; 9import javax.swing.Timer;
10import javax.swing.event.CaretEvent;
11import javax.swing.event.CaretListener;
10import javax.swing.text.BadLocationException; 12import javax.swing.text.BadLocationException;
11import javax.swing.text.Highlighter.HighlightPainter; 13import javax.swing.text.Highlighter.HighlightPainter;
12 14
13import com.strobel.decompiler.languages.java.ast.CompilationUnit; 15import com.strobel.decompiler.languages.java.ast.CompilationUnit;
14 16
15import cuchaz.enigma.Deobfuscator; 17import cuchaz.enigma.Deobfuscator;
18import cuchaz.enigma.analysis.EntryReference;
16import cuchaz.enigma.analysis.SourceIndex; 19import cuchaz.enigma.analysis.SourceIndex;
17import cuchaz.enigma.analysis.Token; 20import cuchaz.enigma.analysis.Token;
18import cuchaz.enigma.mapping.ClassEntry; 21import cuchaz.enigma.mapping.ClassEntry;
@@ -26,8 +29,13 @@ public class CodeReader extends JEditorPane {
26 29
27 private static final Object m_lock = new Object(); 30 private static final Object m_lock = new Object();
28 31
29 private SelectionHighlightPainter m_highlightPainter; 32 public static interface SelectionListener {
33 void onSelect(EntryReference<Entry,Entry> reference);
34 }
35
36 private SelectionHighlightPainter m_selectionHighlightPainter;
30 private SourceIndex m_sourceIndex; 37 private SourceIndex m_sourceIndex;
38 private SelectionListener m_selectionListener;
31 39
32 public CodeReader() { 40 public CodeReader() {
33 41
@@ -38,8 +46,28 @@ public class CodeReader extends JEditorPane {
38 DefaultSyntaxKit kit = (DefaultSyntaxKit)getEditorKit(); 46 DefaultSyntaxKit kit = (DefaultSyntaxKit)getEditorKit();
39 kit.toggleComponent(this, "de.sciss.syntaxpane.components.TokenMarker"); 47 kit.toggleComponent(this, "de.sciss.syntaxpane.components.TokenMarker");
40 48
41 m_highlightPainter = new SelectionHighlightPainter(); 49 // hook events
50 addCaretListener(new CaretListener() {
51 @Override
52 public void caretUpdate(CaretEvent event) {
53 if (m_selectionListener != null && m_sourceIndex != null) {
54 Token token = m_sourceIndex.getReferenceToken(event.getDot());
55 if (token != null) {
56 m_selectionListener.onSelect(m_sourceIndex.getDeobfReference(token));
57 } else {
58 m_selectionListener.onSelect(null);
59 }
60 }
61 }
62 });
63
64 m_selectionHighlightPainter = new SelectionHighlightPainter();
42 m_sourceIndex = null; 65 m_sourceIndex = null;
66 m_selectionListener = null;
67 }
68
69 public void setSelectionListener(SelectionListener val) {
70 m_selectionListener = val;
43 } 71 }
44 72
45 public void setCode(String code) { 73 public void setCode(String code) {
@@ -49,6 +77,10 @@ public class CodeReader extends JEditorPane {
49 } 77 }
50 } 78 }
51 79
80 public SourceIndex getSourceIndex() {
81 return m_sourceIndex;
82 }
83
52 public void decompileClass(ClassEntry classEntry, Deobfuscator deobfuscator) { 84 public void decompileClass(ClassEntry classEntry, Deobfuscator deobfuscator) {
53 decompileClass(classEntry, deobfuscator, null); 85 decompileClass(classEntry, deobfuscator, null);
54 } 86 }
@@ -110,7 +142,7 @@ public class CodeReader extends JEditorPane {
110 } 142 }
111 143
112 public void navigateToToken(final Token token) { 144 public void navigateToToken(final Token token) {
113 navigateToToken(this, token, m_highlightPainter); 145 navigateToToken(this, token, m_selectionHighlightPainter);
114 } 146 }
115 147
116 // HACKHACK: someday we can update the main GUI to use this code reader 148 // HACKHACK: someday we can update the main GUI to use this code reader
@@ -161,4 +193,22 @@ public class CodeReader extends JEditorPane {
161 }); 193 });
162 timer.start(); 194 timer.start();
163 } 195 }
196
197 public void setHighlightedTokens(Iterable<Token> tokens, HighlightPainter painter) {
198 for (Token token : tokens) {
199 setHighlightedToken(token, painter);
200 }
201 }
202
203 public void setHighlightedToken(Token token, HighlightPainter painter) {
204 try {
205 getHighlighter().addHighlight(token.start, token.end, painter);
206 } catch (BadLocationException ex) {
207 throw new IllegalArgumentException(ex);
208 }
209 }
210
211 public void clearHighlights() {
212 getHighlighter().removeAllHighlights();
213 }
164} 214}
diff --git a/src/cuchaz/enigma/gui/FieldMatchingGui.java b/src/cuchaz/enigma/gui/FieldMatchingGui.java
index de9ba14..ef374c8 100644
--- a/src/cuchaz/enigma/gui/FieldMatchingGui.java
+++ b/src/cuchaz/enigma/gui/FieldMatchingGui.java
@@ -4,24 +4,34 @@ import java.awt.BorderLayout;
4import java.awt.Container; 4import java.awt.Container;
5import java.awt.Dimension; 5import java.awt.Dimension;
6import java.awt.FlowLayout; 6import java.awt.FlowLayout;
7import java.util.Map; 7import java.awt.event.ActionEvent;
8import java.awt.event.ActionListener;
9import java.util.Collection;
10import java.util.Set;
8 11
9import javax.swing.BoxLayout; 12import javax.swing.BoxLayout;
13import javax.swing.JButton;
10import javax.swing.JFrame; 14import javax.swing.JFrame;
11import javax.swing.JLabel; 15import javax.swing.JLabel;
12import javax.swing.JPanel; 16import javax.swing.JPanel;
13import javax.swing.JScrollPane; 17import javax.swing.JScrollPane;
14import javax.swing.JSplitPane; 18import javax.swing.JSplitPane;
15import javax.swing.WindowConstants; 19import javax.swing.WindowConstants;
20import javax.swing.text.Highlighter.HighlightPainter;
21
22import com.google.common.collect.Sets;
16 23
17import cuchaz.enigma.Constants; 24import cuchaz.enigma.Constants;
18import cuchaz.enigma.Deobfuscator; 25import cuchaz.enigma.Deobfuscator;
26import cuchaz.enigma.analysis.EntryReference;
27import cuchaz.enigma.analysis.SourceIndex;
28import cuchaz.enigma.analysis.Token;
19import cuchaz.enigma.convert.ClassMatches; 29import cuchaz.enigma.convert.ClassMatches;
20import cuchaz.enigma.convert.FieldMatches; 30import cuchaz.enigma.convert.FieldMatches;
21import cuchaz.enigma.gui.ClassSelector.ClassSelectionListener; 31import cuchaz.enigma.gui.ClassSelector.ClassSelectionListener;
22import cuchaz.enigma.mapping.ClassEntry; 32import cuchaz.enigma.mapping.ClassEntry;
33import cuchaz.enigma.mapping.Entry;
23import cuchaz.enigma.mapping.FieldEntry; 34import cuchaz.enigma.mapping.FieldEntry;
24import cuchaz.enigma.mapping.FieldMapping;
25import de.sciss.syntaxpane.DefaultSyntaxKit; 35import de.sciss.syntaxpane.DefaultSyntaxKit;
26 36
27 37
@@ -36,19 +46,28 @@ public class FieldMatchingGui {
36 private ClassSelector m_sourceClasses; 46 private ClassSelector m_sourceClasses;
37 private CodeReader m_sourceReader; 47 private CodeReader m_sourceReader;
38 private CodeReader m_destReader; 48 private CodeReader m_destReader;
49 private JButton m_matchButton;
50 private JLabel m_sourceLabel;
51 private JLabel m_destLabel;
52 private HighlightPainter m_unmatchedHighlightPainter;
53 private HighlightPainter m_matchedHighlightPainter;
39 54
40 private ClassMatches m_classMatches; 55 private ClassMatches m_classMatches;
41 private FieldMatches m_fieldMatches; 56 private FieldMatches m_fieldMatches;
42 private Map<FieldEntry,FieldMapping> m_droppedFieldMappings;
43 private Deobfuscator m_sourceDeobfuscator; 57 private Deobfuscator m_sourceDeobfuscator;
44 private Deobfuscator m_destDeobfuscator; 58 private Deobfuscator m_destDeobfuscator;
45 private SaveListener m_saveListener; 59 private SaveListener m_saveListener;
60 private ClassEntry m_obfSourceClass;
61 private ClassEntry m_obfDestClass;
62 private FieldEntry m_obfSourceField;
63 private FieldEntry m_obfDestField;
64 private Set<FieldEntry> m_obfUnmatchedSourceFields;
65 private Set<FieldEntry> m_obfUnmatchedDestFields;
46 66
47 public FieldMatchingGui(ClassMatches classMatches, FieldMatches fieldMatches, Map<FieldEntry,FieldMapping> droppedFieldMappings, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) { 67 public FieldMatchingGui(ClassMatches classMatches, FieldMatches fieldMatches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) {
48 68
49 m_classMatches = classMatches; 69 m_classMatches = classMatches;
50 m_fieldMatches = fieldMatches; 70 m_fieldMatches = fieldMatches;
51 m_droppedFieldMappings = droppedFieldMappings;
52 m_sourceDeobfuscator = sourceDeobfuscator; 71 m_sourceDeobfuscator = sourceDeobfuscator;
53 m_destDeobfuscator = destDeobfuscator; 72 m_destDeobfuscator = destDeobfuscator;
54 73
@@ -74,31 +93,57 @@ public class FieldMatchingGui {
74 JScrollPane sourceScroller = new JScrollPane(m_sourceClasses); 93 JScrollPane sourceScroller = new JScrollPane(m_sourceClasses);
75 classesPanel.add(sourceScroller); 94 classesPanel.add(sourceScroller);
76 95
77 // init fields side
78 JPanel fieldsPanel = new JPanel();
79 fieldsPanel.setLayout(new BoxLayout(fieldsPanel, BoxLayout.PAGE_AXIS));
80 fieldsPanel.setPreferredSize(new Dimension(200, 0));
81 pane.add(fieldsPanel, BorderLayout.WEST);
82 fieldsPanel.add(new JLabel("Destination Fields"));
83
84 // init readers 96 // init readers
85 DefaultSyntaxKit.initKit(); 97 DefaultSyntaxKit.initKit();
86 m_sourceReader = new CodeReader(); 98 m_sourceReader = new CodeReader();
99 m_sourceReader.setSelectionListener(new CodeReader.SelectionListener() {
100 @Override
101 public void onSelect(EntryReference<Entry,Entry> reference) {
102 if (reference != null) {
103 onSelectSource(reference.entry);
104 } else {
105 onSelectSource(null);
106 }
107 }
108 });
87 m_destReader = new CodeReader(); 109 m_destReader = new CodeReader();
110 m_destReader.setSelectionListener(new CodeReader.SelectionListener() {
111 @Override
112 public void onSelect(EntryReference<Entry,Entry> reference) {
113 if (reference != null) {
114 onSelectDest(reference.entry);
115 } else {
116 onSelectDest(null);
117 }
118 }
119 });
88 120
89 // init all the splits 121 // init all the splits
90 JSplitPane splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, classesPanel, new JScrollPane(m_sourceReader)); 122 JSplitPane splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JScrollPane(m_sourceReader), new JScrollPane(m_destReader));
123 splitRight.setResizeWeight(0.5); // resize 50:50
124 JSplitPane splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, classesPanel, splitRight);
91 splitLeft.setResizeWeight(0); // let the right side take all the slack 125 splitLeft.setResizeWeight(0); // let the right side take all the slack
92 JSplitPane splitRight = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JScrollPane(m_destReader), fieldsPanel); 126 pane.add(splitLeft, BorderLayout.CENTER);
93 splitRight.setResizeWeight(1); // let the left side take all the slack 127 splitLeft.resetToPreferredSizes();
94 JSplitPane splitCenter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, splitLeft, splitRight);
95 splitCenter.setResizeWeight(0.5); // resize 50:50
96 pane.add(splitCenter, BorderLayout.CENTER);
97 splitCenter.resetToPreferredSizes();
98 128
99 // init bottom panel 129 // init bottom panel
100 JPanel bottomPanel = new JPanel(); 130 JPanel bottomPanel = new JPanel();
101 bottomPanel.setLayout(new FlowLayout()); 131 bottomPanel.setLayout(new FlowLayout());
132 pane.add(bottomPanel, BorderLayout.SOUTH);
133
134 m_matchButton = new JButton("Match");
135 m_matchButton.addActionListener(new ActionListener() {
136 @Override
137 public void actionPerformed(ActionEvent event) {
138 match();
139 }
140 });
141
142 m_sourceLabel = new JLabel();
143 bottomPanel.add(m_sourceLabel);
144 bottomPanel.add(m_matchButton);
145 m_destLabel = new JLabel();
146 bottomPanel.add(m_destLabel);
102 147
103 // show the frame 148 // show the frame
104 pane.doLayout(); 149 pane.doLayout();
@@ -106,26 +151,139 @@ public class FieldMatchingGui {
106 m_frame.setMinimumSize(new Dimension(640, 480)); 151 m_frame.setMinimumSize(new Dimension(640, 480));
107 m_frame.setVisible(true); 152 m_frame.setVisible(true);
108 m_frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 153 m_frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
154
155 m_unmatchedHighlightPainter = new ObfuscatedHighlightPainter();
156 m_matchedHighlightPainter = new DeobfuscatedHighlightPainter();
109 157
110 // init state 158 // init state
111 m_saveListener = null; 159 m_saveListener = null;
112 m_fieldMatches.addUnmatchedSourceFields(droppedFieldMappings.keySet()); 160 m_obfSourceClass = null;
113 m_sourceClasses.setClasses(m_fieldMatches.getSourceClassesWithUnmatchedFields()); 161 m_obfDestClass = null;
162 m_obfSourceField = null;
163 m_obfDestField = null;
164 m_obfUnmatchedSourceFields = null;
165 m_obfUnmatchedDestFields = null;
166 updateSourceClasses();
167 updateMatchButton();
114 } 168 }
115 169
116 public void setSaveListener(SaveListener val) { 170 public void setSaveListener(SaveListener val) {
117 m_saveListener = val; 171 m_saveListener = val;
118 } 172 }
119 173
174 private void updateSourceClasses() {
175 m_sourceClasses.setClasses(m_fieldMatches.getSourceClassesWithUnmatchedFields());
176 m_sourceClasses.expandAll();
177 }
178
120 protected void setSourceClass(ClassEntry obfSourceClass) { 179 protected void setSourceClass(ClassEntry obfSourceClass) {
121 180
122 // get the matched dest class 181 m_obfSourceClass = obfSourceClass;
123 final ClassEntry obfDestClass = m_classMatches.getUniqueMatches().get(obfSourceClass); 182 m_obfDestClass = m_classMatches.getUniqueMatches().get(obfSourceClass);
124 if (obfDestClass == null) { 183 if (m_obfDestClass == null) {
125 throw new Error("No matching dest class for source class: " + obfSourceClass); 184 throw new Error("No matching dest class for source class: " + m_obfSourceClass);
126 } 185 }
186
187 updateUnmatchedFields();
188 m_sourceReader.decompileClass(m_obfSourceClass, m_sourceDeobfuscator, new Runnable() {
189 @Override
190 public void run() {
191 updateSourceHighlights();
192 }
193 });
194 m_destReader.decompileClass(m_obfDestClass, m_destDeobfuscator, new Runnable() {
195 @Override
196 public void run() {
197 updateDestHighlights();
198 }
199 });
200 }
201
202 private void updateUnmatchedFields() {
203 m_obfUnmatchedSourceFields = Sets.newHashSet(m_fieldMatches.getUnmatchedSourceFields(m_obfSourceClass));
204 m_obfUnmatchedDestFields = Sets.newHashSet();
205 for (FieldEntry destFieldEntry : m_destDeobfuscator.getJarIndex().getObfFieldEntries(m_obfDestClass)) {
206 if (!m_fieldMatches.isDestMatched(destFieldEntry)) {
207 m_obfUnmatchedDestFields.add(destFieldEntry);
208 }
209 }
210 }
211
212 protected void updateSourceHighlights() {
213 highlightFields(m_sourceReader, m_sourceDeobfuscator, m_obfUnmatchedSourceFields, m_fieldMatches.matches().keySet());
214 }
215
216 protected void updateDestHighlights() {
217 highlightFields(m_destReader, m_destDeobfuscator, m_obfUnmatchedDestFields, m_fieldMatches.matches().values());
218 }
219
220 private void highlightFields(CodeReader reader, Deobfuscator deobfuscator, Collection<FieldEntry> obfFieldEntries, Collection<FieldEntry> obfMatchedFieldEntries) {
221 reader.clearHighlights();
222 SourceIndex index = reader.getSourceIndex();
223 for (FieldEntry obfFieldEntry : obfFieldEntries) {
224 FieldEntry deobfFieldEntry = deobfuscator.deobfuscateEntry(obfFieldEntry);
225 Token token = index.getDeclarationToken(deobfFieldEntry);
226 if (token == null) {
227 System.err.println("WARNING: Can't find declaration token for " + deobfFieldEntry);
228 } else {
229 reader.setHighlightedToken(
230 token,
231 obfMatchedFieldEntries.contains(obfFieldEntry) ? m_matchedHighlightPainter : m_unmatchedHighlightPainter
232 );
233 }
234 }
235 }
236
237 protected void onSelectSource(Entry entry) {
238 m_sourceLabel.setText("");
239 m_obfSourceField = null;
240 if (entry != null && entry instanceof FieldEntry) {
241 FieldEntry fieldEntry = (FieldEntry)entry;
242 FieldEntry obfFieldEntry = m_sourceDeobfuscator.obfuscateEntry(fieldEntry);
243 if (m_obfUnmatchedSourceFields.contains(obfFieldEntry)) {
244 m_obfSourceField = obfFieldEntry;
245 m_sourceLabel.setText(fieldEntry.getName() + " " + fieldEntry.getType().toString());
246 }
247 }
248 updateMatchButton();
249 }
127 250
128 m_sourceReader.decompileClass(obfSourceClass, m_sourceDeobfuscator); 251 protected void onSelectDest(Entry entry) {
129 m_destReader.decompileClass(obfDestClass, m_destDeobfuscator); 252 m_destLabel.setText("");
253 m_obfDestField = null;
254 if (entry != null && entry instanceof FieldEntry) {
255 FieldEntry fieldEntry = (FieldEntry)entry;
256 FieldEntry obfFieldEntry = m_destDeobfuscator.obfuscateEntry(fieldEntry);
257 if (m_obfUnmatchedDestFields.contains(obfFieldEntry)) {
258 m_obfDestField = obfFieldEntry;
259 m_destLabel.setText(fieldEntry.getName() + " " + fieldEntry.getType().toString());
260 }
261 }
262 updateMatchButton();
263 }
264
265 private void updateMatchButton() {
266 m_matchButton.setEnabled(m_obfSourceField != null && m_obfDestField != null);
267 }
268
269 protected void match() {
270
271 // update the field matches
272 m_fieldMatches.makeMatch(m_obfSourceField, m_obfDestField);
273 save();
274
275 // update the ui
276 onSelectSource(null);
277 onSelectDest(null);
278 updateUnmatchedFields();
279 updateSourceHighlights();
280 updateDestHighlights();
281 updateSourceClasses();
282 }
283
284 private void save() {
285 if (m_saveListener != null) {
286 m_saveListener.save(m_fieldMatches);
287 }
130 } 288 }
131} 289}
diff --git a/src/cuchaz/enigma/mapping/EntryFactory.java b/src/cuchaz/enigma/mapping/EntryFactory.java
index f4d62c8..333bb09 100644
--- a/src/cuchaz/enigma/mapping/EntryFactory.java
+++ b/src/cuchaz/enigma/mapping/EntryFactory.java
@@ -26,6 +26,10 @@ public class EntryFactory {
26 return obfClassEntry.buildClassEntry(jarIndex.getObfClassChain(obfClassEntry)); 26 return obfClassEntry.buildClassEntry(jarIndex.getObfClassChain(obfClassEntry));
27 } 27 }
28 28
29 private static ClassEntry getObfClassEntry(ClassMapping classMapping) {
30 return new ClassEntry(classMapping.getObfFullName());
31 }
32
29 public static ClassEntry getDeobfClassEntry(ClassMapping classMapping) { 33 public static ClassEntry getDeobfClassEntry(ClassMapping classMapping) {
30 return new ClassEntry(classMapping.getDeobfName()); 34 return new ClassEntry(classMapping.getDeobfName());
31 } 35 }
@@ -50,6 +54,14 @@ public class EntryFactory {
50 ); 54 );
51 } 55 }
52 56
57 public static FieldEntry getObfFieldEntry(ClassMapping classMapping, FieldMapping fieldMapping) {
58 return new FieldEntry(
59 getObfClassEntry(classMapping),
60 fieldMapping.getObfName(),
61 fieldMapping.getObfType()
62 );
63 }
64
53 public static MethodEntry getMethodEntry(CtMethod method) { 65 public static MethodEntry getMethodEntry(CtMethod method) {
54 return new MethodEntry( 66 return new MethodEntry(
55 getClassEntry(method.getDeclaringClass()), 67 getClassEntry(method.getDeclaringClass()),
@@ -148,4 +160,8 @@ public class EntryFactory {
148 public static BehaviorEntry getObfBehaviorEntry(ClassEntry classEntry, MethodMapping methodMapping) { 160 public static BehaviorEntry getObfBehaviorEntry(ClassEntry classEntry, MethodMapping methodMapping) {
149 return getBehaviorEntry(classEntry, methodMapping.getObfName(), methodMapping.getObfSignature()); 161 return getBehaviorEntry(classEntry, methodMapping.getObfName(), methodMapping.getObfSignature());
150 } 162 }
163
164 public static BehaviorEntry getObfBehaviorEntry(ClassMapping classMapping, MethodMapping methodMapping) {
165 return getObfBehaviorEntry(getObfClassEntry(classMapping), methodMapping);
166 }
151} 167}