summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/gui/MatchingGui.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cuchaz/enigma/gui/MatchingGui.java')
-rw-r--r--src/cuchaz/enigma/gui/MatchingGui.java157
1 files changed, 128 insertions, 29 deletions
diff --git a/src/cuchaz/enigma/gui/MatchingGui.java b/src/cuchaz/enigma/gui/MatchingGui.java
index e9dff16..e2d517e 100644
--- a/src/cuchaz/enigma/gui/MatchingGui.java
+++ b/src/cuchaz/enigma/gui/MatchingGui.java
@@ -7,6 +7,7 @@ import java.awt.FlowLayout;
7import java.awt.event.ActionEvent; 7import java.awt.event.ActionEvent;
8import java.awt.event.ActionListener; 8import java.awt.event.ActionListener;
9import java.util.ArrayList; 9import java.util.ArrayList;
10import java.util.Arrays;
10import java.util.Collection; 11import java.util.Collection;
11import java.util.Collections; 12import java.util.Collections;
12import java.util.List; 13import java.util.List;
@@ -25,6 +26,7 @@ import javax.swing.WindowConstants;
25 26
26import com.beust.jcommander.internal.Lists; 27import com.beust.jcommander.internal.Lists;
27import com.google.common.collect.ArrayListMultimap; 28import com.google.common.collect.ArrayListMultimap;
29import com.google.common.collect.BiMap;
28import com.google.common.collect.Multimap; 30import com.google.common.collect.Multimap;
29 31
30import cuchaz.enigma.Constants; 32import cuchaz.enigma.Constants;
@@ -33,6 +35,7 @@ import cuchaz.enigma.convert.ClassIdentifier;
33import cuchaz.enigma.convert.ClassIdentity; 35import cuchaz.enigma.convert.ClassIdentity;
34import cuchaz.enigma.convert.ClassMatch; 36import cuchaz.enigma.convert.ClassMatch;
35import cuchaz.enigma.convert.ClassNamer; 37import cuchaz.enigma.convert.ClassNamer;
38import cuchaz.enigma.convert.MappingsConverter;
36import cuchaz.enigma.convert.Matches; 39import cuchaz.enigma.convert.Matches;
37import cuchaz.enigma.gui.ClassSelector.ClassSelectionListener; 40import cuchaz.enigma.gui.ClassSelector.ClassSelectionListener;
38import cuchaz.enigma.mapping.ClassEntry; 41import cuchaz.enigma.mapping.ClassEntry;
@@ -79,6 +82,10 @@ public class MatchingGui {
79 } 82 }
80 } 83 }
81 84
85 public static interface SaveListener {
86 public void save(Matches matches);
87 }
88
82 // controls 89 // controls
83 private JFrame m_frame; 90 private JFrame m_frame;
84 private ClassSelector m_sourceClasses; 91 private ClassSelector m_sourceClasses;
@@ -94,6 +101,8 @@ public class MatchingGui {
94 private Deobfuscator m_destDeobfuscator; 101 private Deobfuscator m_destDeobfuscator;
95 private ClassEntry m_sourceClass; 102 private ClassEntry m_sourceClass;
96 private ClassEntry m_destClass; 103 private ClassEntry m_destClass;
104 private SourceType m_sourceType;
105 private SaveListener m_saveListener;
97 106
98 public MatchingGui(Matches matches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) { 107 public MatchingGui(Matches matches, Deobfuscator sourceDeobfuscator, Deobfuscator destDeobfuscator) {
99 108
@@ -179,17 +188,13 @@ public class MatchingGui {
179 bottomPanel.setLayout(new FlowLayout()); 188 bottomPanel.setLayout(new FlowLayout());
180 189
181 m_sourceClassLabel = new JLabel(); 190 m_sourceClassLabel = new JLabel();
182 m_sourceClassLabel.setPreferredSize(new Dimension(300, 0)); 191 m_sourceClassLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
192 m_sourceClassLabel.setPreferredSize(new Dimension(300, 24));
183 m_destClassLabel = new JLabel(); 193 m_destClassLabel = new JLabel();
184 m_destClassLabel.setPreferredSize(new Dimension(300, 0)); 194 m_destClassLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
195 m_destClassLabel.setPreferredSize(new Dimension(300, 24));
185 196
186 m_matchButton = new JButton(); 197 m_matchButton = new JButton();
187 m_matchButton.addActionListener(new ActionListener() {
188 @Override
189 public void actionPerformed(ActionEvent event) {
190 onMatchClick();
191 }
192 });
193 m_matchButton.setPreferredSize(new Dimension(140, 24)); 198 m_matchButton.setPreferredSize(new Dimension(140, 24));
194 199
195 bottomPanel.add(m_sourceClassLabel); 200 bottomPanel.add(m_sourceClassLabel);
@@ -205,13 +210,29 @@ public class MatchingGui {
205 m_frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 210 m_frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
206 211
207 // init state 212 // init state
213 updateMappings();
208 setSourceType(SourceType.getDefault()); 214 setSourceType(SourceType.getDefault());
209 updateMatchButton(); 215 updateMatchButton();
216 m_saveListener = null;
217 }
218
219 public void setSaveListener(SaveListener val) {
220 m_saveListener = val;
221 }
222
223 private void updateMappings() {
224 m_destDeobfuscator.setMappings(MappingsConverter.newMappings(
225 m_matches,
226 m_sourceDeobfuscator.getMappings(),
227 m_sourceDeobfuscator,
228 m_destDeobfuscator
229 ));
210 } 230 }
211 231
212 protected void setSourceType(SourceType val) { 232 protected void setSourceType(SourceType val) {
213 // show the source classes 233 // show the source classes
214 m_sourceClasses.setClasses(deobfuscateClasses(val.getSourceClasses(m_matches), m_sourceDeobfuscator)); 234 m_sourceType = val;
235 m_sourceClasses.setClasses(deobfuscateClasses(m_sourceType.getSourceClasses(m_matches), m_sourceDeobfuscator));
215 } 236 }
216 237
217 private Collection<ClassEntry> deobfuscateClasses(Collection<ClassEntry> in, Deobfuscator deobfuscator) { 238 private Collection<ClassEntry> deobfuscateClasses(Collection<ClassEntry> in, Deobfuscator deobfuscator) {
@@ -234,11 +255,24 @@ public class MatchingGui {
234 ClassMatch match = m_matches.getMatchBySource(m_sourceDeobfuscator.obfuscateEntry(m_sourceClass)); 255 ClassMatch match = m_matches.getMatchBySource(m_sourceDeobfuscator.obfuscateEntry(m_sourceClass));
235 assert(match != null); 256 assert(match != null);
236 if (match.destClasses.isEmpty()) { 257 if (match.destClasses.isEmpty()) {
237 m_destClasses.setClasses(deobfuscateClasses(getLikelyMatches(m_sourceClass), m_destDeobfuscator)); 258
259 m_destClasses.setClasses(null);
260
261 // run in a separate thread to keep ui responsive
262 new Thread() {
263 @Override
264 public void run() {
265 m_destClasses.setClasses(deobfuscateClasses(getLikelyMatches(m_sourceClass), m_destDeobfuscator));
266 m_destClasses.expandRow(0);
267 }
268 }.start();
269
238 } else { 270 } else {
271
239 m_destClasses.setClasses(deobfuscateClasses(match.destClasses, m_destDeobfuscator)); 272 m_destClasses.setClasses(deobfuscateClasses(match.destClasses, m_destDeobfuscator));
273 m_destClasses.expandRow(0);
274
240 } 275 }
241 m_destClasses.expandRow(0);
242 } 276 }
243 277
244 setDestClass(null); 278 setDestClass(null);
@@ -309,7 +343,7 @@ public class MatchingGui {
309 343
310 reader.setText("(decompiling...)"); 344 reader.setText("(decompiling...)");
311 345
312 // run decompiler in a separate thread to keep ui responsive 346 // run in a separate thread to keep ui responsive
313 new Thread() { 347 new Thread() {
314 @Override 348 @Override
315 public void run() { 349 public void run() {
@@ -327,33 +361,98 @@ public class MatchingGui {
327 361
328 private void updateMatchButton() { 362 private void updateMatchButton() {
329 363
364 ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass);
365 ClassEntry obfDest = m_destDeobfuscator.obfuscateEntry(m_destClass);
366
367 BiMap<ClassEntry,ClassEntry> uniqueMatches = m_matches.getUniqueMatches();
330 boolean twoSelected = m_sourceClass != null && m_destClass != null; 368 boolean twoSelected = m_sourceClass != null && m_destClass != null;
331 boolean isMatched = twoSelected && m_matches.getUniqueMatches().containsKey(m_sourceDeobfuscator.obfuscateEntry(m_sourceClass)); 369 boolean isMatched = uniqueMatches.containsKey(obfSource) && uniqueMatches.containsValue(obfDest);
370 boolean canMatch = !uniqueMatches.containsKey(obfSource) && ! uniqueMatches.containsValue(obfDest);
332 371
333 m_matchButton.setEnabled(twoSelected); 372 deactivateButton(m_matchButton);
334 if (twoSelected) { 373 if (twoSelected) {
335 if (isMatched) { 374 if (isMatched) {
336 m_matchButton.setText("Unmatch"); 375 activateButton(m_matchButton, "Unmatch", new ActionListener() {
337 } else { 376 @Override
338 m_matchButton.setText("Match"); 377 public void actionPerformed(ActionEvent event) {
378 onUnmatchClick();
379 }
380 });
381 } else if (canMatch) {
382 activateButton(m_matchButton, "Match", new ActionListener() {
383 @Override
384 public void actionPerformed(ActionEvent event) {
385 onMatchClick();
386 }
387 });
339 } 388 }
340 } else {
341 m_matchButton.setText("");
342 } 389 }
343 } 390 }
344 391
345 protected void onMatchClick() { 392 private void deactivateButton(JButton button) {
346 // TODO 393 button.setEnabled(false);
394 button.setText("");
395 for (ActionListener listener : Arrays.asList(button.getActionListeners())) {
396 button.removeActionListener(listener);
397 }
347 } 398 }
348 399
349 /* 400 private void activateButton(JButton button, String text, ActionListener newListener) {
350 private static List<String> getClassNames(Collection<ClassEntry> classes) { 401 button.setText(text);
351 List<String> out = Lists.newArrayList(); 402 button.setEnabled(true);
352 for (ClassEntry c : classes) { 403 for (ActionListener listener : Arrays.asList(button.getActionListeners())) {
353 out.add(c.getName()); 404 button.removeActionListener(listener);
405 }
406 button.addActionListener(newListener);
407 }
408
409 private void onMatchClick() {
410 // precondition: source and dest classes are set correctly
411
412 ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass);
413 ClassEntry obfDest = m_destDeobfuscator.obfuscateEntry(m_destClass);
414
415 // remove the classes from their match
416 m_matches.removeSource(obfSource);
417 m_matches.removeDest(obfDest);
418
419 // add them as matched classes
420 m_matches.add(new ClassMatch(obfSource, obfDest));
421
422 // TEMP
423 System.out.println("Match: " + obfSource + " <-> " + obfDest);
424
425 //save();
426 updateMappings();
427 setDestClass(null);
428 m_destClasses.setClasses(null);
429 updateMatchButton();
430 setSourceType(m_sourceType);
431 }
432
433 private void onUnmatchClick() {
434 // precondition: source and dest classes are set to a unique match
435
436 ClassEntry obfSource = m_sourceDeobfuscator.obfuscateEntry(m_sourceClass);
437
438 // remove the source to break the match, then add the source back as unmatched
439 m_matches.removeSource(obfSource);
440 m_matches.add(new ClassMatch(obfSource, null));
441
442 // TEMP
443 System.out.println("Unmatch: " + obfSource + " <-> " + m_destDeobfuscator.obfuscateEntry(m_destClass));
444
445 //save();
446 updateMappings();
447 setDestClass(null);
448 m_destClasses.setClasses(null);
449 updateMatchButton();
450 setSourceType(m_sourceType);
451 }
452
453 private void save() {
454 if (m_saveListener != null) {
455 m_saveListener.save(m_matches);
354 } 456 }
355 Collections.sort(out);
356 return out;
357 } 457 }
358 */
359} 458}