summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/gui/ClassMatchingGui.java
diff options
context:
space:
mode:
authorGravatar jeff2015-03-09 12:53:11 -0400
committerGravatar jeff2015-03-09 12:53:11 -0400
commitd6b2a223a7973941e5e4fb45c8ceec4885891496 (patch)
tree5728ab513d0b4ed85a720da7eb48c6591dd3f8b0 /src/cuchaz/enigma/gui/ClassMatchingGui.java
parentadd tracking for mismatched fields/methods (diff)
downloadenigma-fork-d6b2a223a7973941e5e4fb45c8ceec4885891496.tar.gz
enigma-fork-d6b2a223a7973941e5e4fb45c8ceec4885891496.tar.xz
enigma-fork-d6b2a223a7973941e5e4fb45c8ceec4885891496.zip
starting on field matching gui
Diffstat (limited to 'src/cuchaz/enigma/gui/ClassMatchingGui.java')
-rw-r--r--src/cuchaz/enigma/gui/ClassMatchingGui.java145
1 files changed, 42 insertions, 103 deletions
diff --git a/src/cuchaz/enigma/gui/ClassMatchingGui.java b/src/cuchaz/enigma/gui/ClassMatchingGui.java
index ff7cda9..b674451 100644
--- a/src/cuchaz/enigma/gui/ClassMatchingGui.java
+++ b/src/cuchaz/enigma/gui/ClassMatchingGui.java
@@ -15,7 +15,6 @@ import javax.swing.BoxLayout;
15import javax.swing.ButtonGroup; 15import javax.swing.ButtonGroup;
16import javax.swing.JButton; 16import javax.swing.JButton;
17import javax.swing.JCheckBox; 17import javax.swing.JCheckBox;
18import javax.swing.JEditorPane;
19import javax.swing.JFrame; 18import javax.swing.JFrame;
20import javax.swing.JLabel; 19import javax.swing.JLabel;
21import javax.swing.JPanel; 20import javax.swing.JPanel;
@@ -28,22 +27,18 @@ import javax.swing.WindowConstants;
28import com.beust.jcommander.internal.Lists; 27import com.beust.jcommander.internal.Lists;
29import com.beust.jcommander.internal.Maps; 28import com.beust.jcommander.internal.Maps;
30import com.google.common.collect.BiMap; 29import com.google.common.collect.BiMap;
31import com.strobel.decompiler.languages.java.ast.CompilationUnit;
32 30
33import cuchaz.enigma.Constants; 31import cuchaz.enigma.Constants;
34import cuchaz.enigma.Deobfuscator; 32import cuchaz.enigma.Deobfuscator;
35import cuchaz.enigma.analysis.SourceIndex;
36import cuchaz.enigma.analysis.Token;
37import cuchaz.enigma.convert.ClassIdentifier; 33import cuchaz.enigma.convert.ClassIdentifier;
38import cuchaz.enigma.convert.ClassIdentity; 34import cuchaz.enigma.convert.ClassIdentity;
39import cuchaz.enigma.convert.ClassMatch; 35import cuchaz.enigma.convert.ClassMatch;
36import cuchaz.enigma.convert.ClassMatches;
40import cuchaz.enigma.convert.ClassMatching; 37import cuchaz.enigma.convert.ClassMatching;
41import cuchaz.enigma.convert.ClassNamer; 38import cuchaz.enigma.convert.ClassNamer;
42import cuchaz.enigma.convert.MappingsConverter; 39import cuchaz.enigma.convert.MappingsConverter;
43import cuchaz.enigma.convert.Matches;
44import cuchaz.enigma.gui.ClassSelector.ClassSelectionListener; 40import cuchaz.enigma.gui.ClassSelector.ClassSelectionListener;
45import cuchaz.enigma.mapping.ClassEntry; 41import cuchaz.enigma.mapping.ClassEntry;
46import cuchaz.enigma.mapping.Entry;
47import cuchaz.enigma.mapping.Mappings; 42import cuchaz.enigma.mapping.Mappings;
48import cuchaz.enigma.mapping.MappingsChecker; 43import cuchaz.enigma.mapping.MappingsChecker;
49import de.sciss.syntaxpane.DefaultSyntaxKit; 44import de.sciss.syntaxpane.DefaultSyntaxKit;
@@ -55,21 +50,21 @@ public class ClassMatchingGui {
55 Matched { 50 Matched {
56 51
57 @Override 52 @Override
58 public Collection<ClassEntry> getSourceClasses(Matches matches) { 53 public Collection<ClassEntry> getSourceClasses(ClassMatches matches) {
59 return matches.getUniqueMatches().keySet(); 54 return matches.getUniqueMatches().keySet();
60 } 55 }
61 }, 56 },
62 Unmatched { 57 Unmatched {
63 58
64 @Override 59 @Override
65 public Collection<ClassEntry> getSourceClasses(Matches matches) { 60 public Collection<ClassEntry> getSourceClasses(ClassMatches matches) {
66 return matches.getUnmatchedSourceClasses(); 61 return matches.getUnmatchedSourceClasses();
67 } 62 }
68 }, 63 },
69 Ambiguous { 64 Ambiguous {
70 65
71 @Override 66 @Override
72 public Collection<ClassEntry> getSourceClasses(Matches matches) { 67 public Collection<ClassEntry> getSourceClasses(ClassMatches matches) {
73 return matches.getAmbiguouslyMatchedSourceClasses(); 68 return matches.getAmbiguouslyMatchedSourceClasses();
74 } 69 }
75 }; 70 };
@@ -82,7 +77,7 @@ public class ClassMatchingGui {
82 return button; 77 return button;
83 } 78 }
84 79
85 public abstract Collection<ClassEntry> getSourceClasses(Matches matches); 80 public abstract Collection<ClassEntry> getSourceClasses(ClassMatches matches);
86 81
87 public static SourceType getDefault() { 82 public static SourceType getDefault() {
88 return values()[0]; 83 return values()[0];
@@ -90,23 +85,22 @@ public class ClassMatchingGui {
90 } 85 }
91 86
92 public static interface SaveListener { 87 public static interface SaveListener {
93 public void save(Matches matches); 88 public void save(ClassMatches matches);
94 } 89 }
95 90
96 // controls 91 // controls
97 private JFrame m_frame; 92 private JFrame m_frame;
98 private ClassSelector m_sourceClasses; 93 private ClassSelector m_sourceClasses;
99 private ClassSelector m_destClasses; 94 private ClassSelector m_destClasses;
100 private JEditorPane m_sourceReader; 95 private CodeReader m_sourceReader;
101 private JEditorPane m_destReader; 96 private CodeReader m_destReader;
102 private JLabel m_sourceClassLabel; 97 private JLabel m_sourceClassLabel;
103 private JLabel m_destClassLabel; 98 private JLabel m_destClassLabel;
104 private JButton m_matchButton; 99 private JButton m_matchButton;
105 private Map<SourceType,JRadioButton> m_sourceTypeButtons; 100 private Map<SourceType,JRadioButton> m_sourceTypeButtons;
106 private JCheckBox m_advanceCheck; 101 private JCheckBox m_advanceCheck;
107 private SelectionHighlightPainter m_selectionHighlightPainter;
108 102
109 private Matches m_matches; 103 private ClassMatches m_classMatches;
110 private Deobfuscator m_sourceDeobfuscator; 104 private Deobfuscator m_sourceDeobfuscator;
111 private Deobfuscator m_destDeobfuscator; 105 private Deobfuscator m_destDeobfuscator;
112 private ClassEntry m_sourceClass; 106 private ClassEntry m_sourceClass;
@@ -114,14 +108,14 @@ public class ClassMatchingGui {
114 private SourceType m_sourceType; 108 private SourceType m_sourceType;
115 private SaveListener m_saveListener; 109 private SaveListener m_saveListener;
116 110
117 public ClassMatchingGui(Matches matches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) { 111 public ClassMatchingGui(ClassMatches matches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) {
118 112
119 m_matches = matches; 113 m_classMatches = matches;
120 m_sourceDeobfuscator = sourceDeobfuscator; 114 m_sourceDeobfuscator = sourceDeobfuscator;
121 m_destDeobfuscator = destDeobfuscator; 115 m_destDeobfuscator = destDeobfuscator;
122 116
123 // init frame 117 // init frame
124 m_frame = new JFrame(Constants.Name); 118 m_frame = new JFrame(Constants.Name + " - Class Matcher");
125 final Container pane = m_frame.getContentPane(); 119 final Container pane = m_frame.getContentPane();
126 pane.setLayout(new BorderLayout()); 120 pane.setLayout(new BorderLayout());
127 121
@@ -188,8 +182,8 @@ public class ClassMatchingGui {
188 182
189 // init source panels 183 // init source panels
190 DefaultSyntaxKit.initKit(); 184 DefaultSyntaxKit.initKit();
191 m_sourceReader = makeReader(); 185 m_sourceReader = new CodeReader();
192 m_destReader = makeReader(); 186 m_destReader = new CodeReader();
193 187
194 // init all the splits 188 // init all the splits
195 JSplitPane splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, sourcePanel, new JScrollPane(m_sourceReader)); 189 JSplitPane splitLeft = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, sourcePanel, new JScrollPane(m_sourceReader));
@@ -238,8 +232,6 @@ public class ClassMatchingGui {
238 m_frame.setVisible(true); 232 m_frame.setVisible(true);
239 m_frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 233 m_frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
240 234
241 m_selectionHighlightPainter = new SelectionHighlightPainter();
242
243 // init state 235 // init state
244 updateDestMappings(); 236 updateDestMappings();
245 setSourceType(SourceType.getDefault()); 237 setSourceType(SourceType.getDefault());
@@ -247,19 +239,6 @@ public class ClassMatchingGui {
247 m_saveListener = null; 239 m_saveListener = null;
248 } 240 }
249 241
250 private JEditorPane makeReader() {
251
252 JEditorPane reader = new JEditorPane();
253 reader.setEditable(false);
254 reader.setContentType("text/java");
255
256 // turn off token highlighting (it's wrong most of the time anyway...)
257 DefaultSyntaxKit kit = (DefaultSyntaxKit)reader.getEditorKit();
258 kit.toggleComponent(reader, "de.sciss.syntaxpane.components.TokenMarker");
259
260 return reader;
261 }
262
263 public void setSaveListener(SaveListener val) { 242 public void setSaveListener(SaveListener val) {
264 m_saveListener = val; 243 m_saveListener = val;
265 } 244 }
@@ -267,7 +246,7 @@ public class ClassMatchingGui {
267 private void updateDestMappings() { 246 private void updateDestMappings() {
268 247
269 Mappings newMappings = MappingsConverter.newMappings( 248 Mappings newMappings = MappingsConverter.newMappings(
270 m_matches, 249 m_classMatches,
271 m_sourceDeobfuscator.getMappings(), 250 m_sourceDeobfuscator.getMappings(),
272 m_sourceDeobfuscator, 251 m_sourceDeobfuscator,
273 m_destDeobfuscator 252 m_destDeobfuscator
@@ -294,13 +273,13 @@ public class ClassMatchingGui {
294 273
295 // show the source classes 274 // show the source classes
296 m_sourceType = val; 275 m_sourceType = val;
297 m_sourceClasses.setClasses(deobfuscateClasses(m_sourceType.getSourceClasses(m_matches), m_sourceDeobfuscator)); 276 m_sourceClasses.setClasses(deobfuscateClasses(m_sourceType.getSourceClasses(m_classMatches), m_sourceDeobfuscator));
298 277
299 // update counts 278 // update counts
300 for (SourceType sourceType : SourceType.values()) { 279 for (SourceType sourceType : SourceType.values()) {
301 m_sourceTypeButtons.get(sourceType).setText(String.format("%s (%d)", 280 m_sourceTypeButtons.get(sourceType).setText(String.format("%s (%d)",
302 sourceType.name(), 281 sourceType.name(),
303 sourceType.getSourceClasses(m_matches).size() 282 sourceType.getSourceClasses(m_classMatches).size()
304 )); 283 ));
305 } 284 }
306 } 285 }
@@ -345,7 +324,7 @@ public class ClassMatchingGui {
345 if (m_sourceClass != null) { 324 if (m_sourceClass != null) {
346 325
347 // show the dest class(es) 326 // show the dest class(es)
348 ClassMatch match = m_matches.getMatchBySource(m_sourceDeobfuscator.obfuscateEntry(m_sourceClass)); 327 ClassMatch match = m_classMatches.getMatchBySource(m_sourceDeobfuscator.obfuscateEntry(m_sourceClass));
349 assert(match != null); 328 assert(match != null);
350 if (match.destClasses.isEmpty()) { 329 if (match.destClasses.isEmpty()) {
351 330
@@ -376,7 +355,12 @@ public class ClassMatchingGui {
376 } 355 }
377 356
378 setDestClass(null); 357 setDestClass(null);
379 decompileClass(m_sourceClass, m_sourceDeobfuscator, m_sourceReader); 358 m_sourceReader.decompileClass(m_sourceClass, m_sourceDeobfuscator, new Runnable() {
359 @Override
360 public void run() {
361 m_sourceReader.navigateToClassDeclaration(m_sourceClass);
362 }
363 });
380 364
381 updateMatchButton(); 365 updateMatchButton();
382 } 366 }
@@ -386,7 +370,7 @@ public class ClassMatchingGui {
386 ClassEntry obfSourceClass = m_sourceDeobfuscator.obfuscateEntry(sourceClass); 370 ClassEntry obfSourceClass = m_sourceDeobfuscator.obfuscateEntry(sourceClass);
387 371
388 // set up identifiers 372 // set up identifiers
389 ClassNamer namer = new ClassNamer(m_matches.getUniqueMatches()); 373 ClassNamer namer = new ClassNamer(m_classMatches.getUniqueMatches());
390 ClassIdentifier sourceIdentifier = new ClassIdentifier( 374 ClassIdentifier sourceIdentifier = new ClassIdentifier(
391 m_sourceDeobfuscator.getJar(), m_sourceDeobfuscator.getJarIndex(), 375 m_sourceDeobfuscator.getJar(), m_sourceDeobfuscator.getJarIndex(),
392 namer.getSourceNamer(), true 376 namer.getSourceNamer(), true
@@ -401,7 +385,7 @@ public class ClassMatchingGui {
401 // rank all the unmatched dest classes against the source class 385 // rank all the unmatched dest classes against the source class
402 ClassIdentity sourceIdentity = sourceIdentifier.identify(obfSourceClass); 386 ClassIdentity sourceIdentity = sourceIdentifier.identify(obfSourceClass);
403 List<ClassEntry> scoredDestClasses = Lists.newArrayList(); 387 List<ClassEntry> scoredDestClasses = Lists.newArrayList();
404 for (ClassEntry unmatchedDestClass : m_matches.getUnmatchedDestClasses()) { 388 for (ClassEntry unmatchedDestClass : m_classMatches.getUnmatchedDestClasses()) {
405 ClassIdentity destIdentity = destIdentifier.identify(unmatchedDestClass); 389 ClassIdentity destIdentity = destIdentifier.identify(unmatchedDestClass);
406 float score = 100.0f*(sourceIdentity.getMatchScore(destIdentity) + destIdentity.getMatchScore(sourceIdentity)) 390 float score = 100.0f*(sourceIdentity.getMatchScore(destIdentity) + destIdentity.getMatchScore(sourceIdentity))
407 /(sourceIdentity.getMaxMatchScore() + destIdentity.getMaxMatchScore()); 391 /(sourceIdentity.getMaxMatchScore() + destIdentity.getMaxMatchScore());
@@ -420,59 +404,14 @@ public class ClassMatchingGui {
420 m_destClass = classEntry; 404 m_destClass = classEntry;
421 m_destClassLabel.setText(m_destClass != null ? m_destClass.getName() : ""); 405 m_destClassLabel.setText(m_destClass != null ? m_destClass.getName() : "");
422 406
423 decompileClass(m_destClass, m_destDeobfuscator, m_destReader); 407 m_destReader.decompileClass(m_destClass, m_destDeobfuscator, new Runnable() {
424
425 updateMatchButton();
426 }
427
428 protected void decompileClass(final ClassEntry classEntry, final Deobfuscator deobfuscator, final JEditorPane reader) {
429
430 if (classEntry == null) {
431 reader.setText(null);
432 return;
433 }
434
435 reader.setText("(decompiling...)");
436
437 // run in a separate thread to keep ui responsive
438 new Thread() {
439 @Override 408 @Override
440 public void run() { 409 public void run() {
441 410 m_destReader.navigateToClassDeclaration(m_destClass);
442 // get the outermost class
443 ClassEntry outermostClassEntry = classEntry;
444 while (outermostClassEntry.isInnerClass()) {
445 outermostClassEntry = outermostClassEntry.getOuterClassEntry();
446 }
447
448 // decompile it
449 CompilationUnit sourceTree = deobfuscator.getSourceTree(outermostClassEntry.getName());
450 String source = deobfuscator.getSource(sourceTree);
451 reader.setText(source);
452 SourceIndex sourceIndex = deobfuscator.getSourceIndex(sourceTree, source);
453
454 // navigate to the class declaration
455 Token token = sourceIndex.getDeclarationToken(classEntry);
456 if (token == null) {
457 // couldn't find the class declaration token, might be an anonymous class
458 // look for any declaration in that class instead
459 for (Entry entry : sourceIndex.declarations()) {
460 if (entry.getClassEntry().equals(classEntry)) {
461 token = sourceIndex.getDeclarationToken(entry);
462 break;
463 }
464 }
465 }
466
467 if (token != null) {
468 GuiTricks.navigateToToken(reader, token, m_selectionHighlightPainter);
469 } else {
470 // couldn't find anything =(
471 System.out.println("Unable to find declaration in source for " + classEntry);
472 }
473
474 } 411 }
475 }.start(); 412 });
413
414 updateMatchButton();
476 } 415 }
477 416
478 private void updateMatchButton() { 417 private void updateMatchButton() {
@@ -480,7 +419,7 @@ public class ClassMatchingGui {
480 ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass); 419 ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass);
481 ClassEntry obfDest = m_destDeobfuscator.obfuscateEntry(m_destClass); 420 ClassEntry obfDest = m_destDeobfuscator.obfuscateEntry(m_destClass);
482 421
483 BiMap<ClassEntry,ClassEntry> uniqueMatches = m_matches.getUniqueMatches(); 422 BiMap<ClassEntry,ClassEntry> uniqueMatches = m_classMatches.getUniqueMatches();
484 boolean twoSelected = m_sourceClass != null && m_destClass != null; 423 boolean twoSelected = m_sourceClass != null && m_destClass != null;
485 boolean isMatched = uniqueMatches.containsKey(obfSource) && uniqueMatches.containsValue(obfDest); 424 boolean isMatched = uniqueMatches.containsKey(obfSource) && uniqueMatches.containsValue(obfDest);
486 boolean canMatch = !uniqueMatches.containsKey(obfSource) && ! uniqueMatches.containsValue(obfDest); 425 boolean canMatch = !uniqueMatches.containsKey(obfSource) && ! uniqueMatches.containsValue(obfDest);
@@ -529,11 +468,11 @@ public class ClassMatchingGui {
529 ClassEntry obfDest = m_destDeobfuscator.obfuscateEntry(m_destClass); 468 ClassEntry obfDest = m_destDeobfuscator.obfuscateEntry(m_destClass);
530 469
531 // remove the classes from their match 470 // remove the classes from their match
532 m_matches.removeSource(obfSource); 471 m_classMatches.removeSource(obfSource);
533 m_matches.removeDest(obfDest); 472 m_classMatches.removeDest(obfDest);
534 473
535 // add them as matched classes 474 // add them as matched classes
536 m_matches.add(new ClassMatch(obfSource, obfDest)); 475 m_classMatches.add(new ClassMatch(obfSource, obfDest));
537 476
538 ClassEntry nextClass = null; 477 ClassEntry nextClass = null;
539 if (m_advanceCheck.isSelected()) { 478 if (m_advanceCheck.isSelected()) {
@@ -554,8 +493,8 @@ public class ClassMatchingGui {
554 ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass); 493 ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass);
555 494
556 // remove the source to break the match, then add the source back as unmatched 495 // remove the source to break the match, then add the source back as unmatched
557 m_matches.removeSource(obfSource); 496 m_classMatches.removeSource(obfSource);
558 m_matches.add(new ClassMatch(obfSource, null)); 497 m_classMatches.add(new ClassMatch(obfSource, null));
559 498
560 save(); 499 save();
561 updateMatches(); 500 updateMatches();
@@ -577,7 +516,7 @@ public class ClassMatchingGui {
577 516
578 private void save() { 517 private void save() {
579 if (m_saveListener != null) { 518 if (m_saveListener != null) {
580 m_saveListener.save(m_matches); 519 m_saveListener.save(m_classMatches);
581 } 520 }
582 } 521 }
583 522
@@ -589,15 +528,15 @@ public class ClassMatchingGui {
589 ClassMatching matching = MappingsConverter.computeMatching( 528 ClassMatching matching = MappingsConverter.computeMatching(
590 m_sourceDeobfuscator.getJar(), m_sourceDeobfuscator.getJarIndex(), 529 m_sourceDeobfuscator.getJar(), m_sourceDeobfuscator.getJarIndex(),
591 m_destDeobfuscator.getJar(), m_destDeobfuscator.getJarIndex(), 530 m_destDeobfuscator.getJar(), m_destDeobfuscator.getJarIndex(),
592 m_matches.getUniqueMatches() 531 m_classMatches.getUniqueMatches()
593 ); 532 );
594 Matches newMatches = new Matches(matching.matches()); 533 ClassMatches newMatches = new ClassMatches(matching.matches());
595 System.out.println(String.format("Automatch found %d new matches", 534 System.out.println(String.format("Automatch found %d new matches",
596 newMatches.getUniqueMatches().size() - m_matches.getUniqueMatches().size() 535 newMatches.getUniqueMatches().size() - m_classMatches.getUniqueMatches().size()
597 )); 536 ));
598 537
599 // update the current matches 538 // update the current matches
600 m_matches = newMatches; 539 m_classMatches = newMatches;
601 save(); 540 save();
602 updateMatches(); 541 updateMatches();
603 } 542 }