diff options
| author | 2019-01-24 14:48:32 +0200 | |
|---|---|---|
| committer | 2019-01-24 13:48:32 +0100 | |
| commit | 00fcd0550fcdda621c2e4662f6ddd55ce673b931 (patch) | |
| tree | 6f9e4c24dbcc6d118fceec56adf7bf9d747a485c /src/main/java/cuchaz/enigma/gui/Gui.java | |
| parent | mark as 0.13.0-SNAPSHOT for preliminary development (diff) | |
| download | enigma-fork-00fcd0550fcdda621c2e4662f6ddd55ce673b931.tar.gz enigma-fork-00fcd0550fcdda621c2e4662f6ddd55ce673b931.tar.xz enigma-fork-00fcd0550fcdda621c2e4662f6ddd55ce673b931.zip | |
[WIP] Mapping rework (#91)
* Move packages
* Mapping & entry refactor: first pass
* Fix deobf -> obf tree remapping
* Resolve various issues
* Give all entries the potential for parents and treat inner classes as children
* Deobf UI tree elements
* Tests pass
* Sort mapping output
* Fix delta tracking
* Index separation and first pass for #97
* Keep track of remapped jar index
* Fix child entries not being remapped
* Drop non-root entries
* Track dropped mappings
* Fix enigma mapping ordering
* EntryTreeNode interface
* Small tweaks
* Naive full index remap on rename
* Entries can resolve to more than one root entry
* Support alternative resolution strategies
* Bridge method resolution
* Tests pass
* Fix mappings being used where there are none
* Fix methods with different descriptors being considered unique. closes #89
Diffstat (limited to 'src/main/java/cuchaz/enigma/gui/Gui.java')
| -rw-r--r-- | src/main/java/cuchaz/enigma/gui/Gui.java | 80 |
1 files changed, 41 insertions, 39 deletions
diff --git a/src/main/java/cuchaz/enigma/gui/Gui.java b/src/main/java/cuchaz/enigma/gui/Gui.java index 53500aa..d119735 100644 --- a/src/main/java/cuchaz/enigma/gui/Gui.java +++ b/src/main/java/cuchaz/enigma/gui/Gui.java | |||
| @@ -29,9 +29,9 @@ import cuchaz.enigma.gui.panels.PanelDeobf; | |||
| 29 | import cuchaz.enigma.gui.panels.PanelEditor; | 29 | import cuchaz.enigma.gui.panels.PanelEditor; |
| 30 | import cuchaz.enigma.gui.panels.PanelIdentifier; | 30 | import cuchaz.enigma.gui.panels.PanelIdentifier; |
| 31 | import cuchaz.enigma.gui.panels.PanelObf; | 31 | import cuchaz.enigma.gui.panels.PanelObf; |
| 32 | import cuchaz.enigma.mapping.*; | ||
| 33 | import cuchaz.enigma.mapping.entry.*; | ||
| 34 | import cuchaz.enigma.throwables.IllegalNameException; | 32 | import cuchaz.enigma.throwables.IllegalNameException; |
| 33 | import cuchaz.enigma.translation.mapping.AccessModifier; | ||
| 34 | import cuchaz.enigma.translation.representation.entry.*; | ||
| 35 | import cuchaz.enigma.utils.Utils; | 35 | import cuchaz.enigma.utils.Utils; |
| 36 | import de.sciss.syntaxpane.DefaultSyntaxKit; | 36 | import de.sciss.syntaxpane.DefaultSyntaxKit; |
| 37 | 37 | ||
| @@ -44,8 +44,8 @@ import javax.swing.tree.TreeNode; | |||
| 44 | import javax.swing.tree.TreePath; | 44 | import javax.swing.tree.TreePath; |
| 45 | import java.awt.*; | 45 | import java.awt.*; |
| 46 | import java.awt.event.*; | 46 | import java.awt.event.*; |
| 47 | import java.io.File; | ||
| 48 | import java.io.IOException; | 47 | import java.io.IOException; |
| 48 | import java.nio.file.Path; | ||
| 49 | import java.util.*; | 49 | import java.util.*; |
| 50 | import java.util.List; | 50 | import java.util.List; |
| 51 | import java.util.function.Function; | 51 | import java.util.function.Function; |
| @@ -58,7 +58,7 @@ public class Gui { | |||
| 58 | 58 | ||
| 59 | private final MenuBar menuBar; | 59 | private final MenuBar menuBar; |
| 60 | // state | 60 | // state |
| 61 | public EntryReference<Entry, Entry> reference; | 61 | public EntryReference<Entry<?>, Entry<?>> reference; |
| 62 | public FileDialog jarFileChooser; | 62 | public FileDialog jarFileChooser; |
| 63 | public FileDialog tinyMappingsFileChooser; | 63 | public FileDialog tinyMappingsFileChooser; |
| 64 | public JFileChooser enigmaMappingsFileChooser; | 64 | public JFileChooser enigmaMappingsFileChooser; |
| @@ -222,7 +222,7 @@ public class Gui { | |||
| 222 | 222 | ||
| 223 | Object node = path.getLastPathComponent(); | 223 | Object node = path.getLastPathComponent(); |
| 224 | if (node instanceof ReferenceTreeNode) { | 224 | if (node instanceof ReferenceTreeNode) { |
| 225 | ReferenceTreeNode<Entry, Entry> referenceNode = ((ReferenceTreeNode<Entry, Entry>) node); | 225 | ReferenceTreeNode<Entry<?>, Entry<?>> referenceNode = ((ReferenceTreeNode<Entry<?>, Entry<?>>) node); |
| 226 | if (referenceNode.getReference() != null) { | 226 | if (referenceNode.getReference() != null) { |
| 227 | navigateTo(referenceNode.getReference()); | 227 | navigateTo(referenceNode.getReference()); |
| 228 | } else { | 228 | } else { |
| @@ -250,10 +250,10 @@ public class Gui { | |||
| 250 | tokens.setPreferredSize(new Dimension(0, 200)); | 250 | tokens.setPreferredSize(new Dimension(0, 200)); |
| 251 | tokens.setMinimumSize(new Dimension(0, 200)); | 251 | tokens.setMinimumSize(new Dimension(0, 200)); |
| 252 | JSplitPane callPanel = new JSplitPane( | 252 | JSplitPane callPanel = new JSplitPane( |
| 253 | JSplitPane.VERTICAL_SPLIT, | 253 | JSplitPane.VERTICAL_SPLIT, |
| 254 | true, | 254 | true, |
| 255 | new JScrollPane(callsTree), | 255 | new JScrollPane(callsTree), |
| 256 | new JScrollPane(tokens) | 256 | new JScrollPane(tokens) |
| 257 | ); | 257 | ); |
| 258 | callPanel.setResizeWeight(1); // let the top side take all the slack | 258 | callPanel.setResizeWeight(1); // let the top side take all the slack |
| 259 | callPanel.resetToPreferredSizes(); | 259 | callPanel.resetToPreferredSizes(); |
| @@ -368,9 +368,9 @@ public class Gui { | |||
| 368 | this.deobfPanel.deobfClasses.setClasses(deobfClasses); | 368 | this.deobfPanel.deobfClasses.setClasses(deobfClasses); |
| 369 | } | 369 | } |
| 370 | 370 | ||
| 371 | public void setMappingsFile(File file) { | 371 | public void setMappingsFile(Path path) { |
| 372 | this.enigmaMappingsFileChooser.setSelectedFile(file); | 372 | this.enigmaMappingsFileChooser.setSelectedFile(path != null ? path.toFile() : null); |
| 373 | this.menuBar.saveMappingsMenu.setEnabled(file != null); | 373 | this.menuBar.saveMappingsMenu.setEnabled(path != null); |
| 374 | } | 374 | } |
| 375 | 375 | ||
| 376 | public void setSource(String source) { | 376 | public void setSource(String source) { |
| @@ -427,7 +427,7 @@ public class Gui { | |||
| 427 | } | 427 | } |
| 428 | } | 428 | } |
| 429 | 429 | ||
| 430 | private void showReference(EntryReference<Entry, Entry> reference) { | 430 | private void showReference(EntryReference<Entry<?>, Entry<?>> reference) { |
| 431 | if (reference == null) { | 431 | if (reference == null) { |
| 432 | infoPanel.clearReference(); | 432 | infoPanel.clearReference(); |
| 433 | return; | 433 | return; |
| @@ -453,29 +453,29 @@ public class Gui { | |||
| 453 | 453 | ||
| 454 | private void showLocalVariableEntry(LocalVariableEntry entry) { | 454 | private void showLocalVariableEntry(LocalVariableEntry entry) { |
| 455 | addNameValue(infoPanel, "Variable", entry.getName()); | 455 | addNameValue(infoPanel, "Variable", entry.getName()); |
| 456 | addNameValue(infoPanel, "Class", entry.getOwnerClassEntry().getName()); | 456 | addNameValue(infoPanel, "Class", entry.getContainingClass().getFullName()); |
| 457 | addNameValue(infoPanel, "Method", entry.getOwnerEntry().getName()); | 457 | addNameValue(infoPanel, "Method", entry.getParent().getName()); |
| 458 | addNameValue(infoPanel, "Index", Integer.toString(entry.getIndex())); | 458 | addNameValue(infoPanel, "Index", Integer.toString(entry.getIndex())); |
| 459 | } | 459 | } |
| 460 | 460 | ||
| 461 | private void showClassEntry(ClassEntry entry) { | 461 | private void showClassEntry(ClassEntry entry) { |
| 462 | addNameValue(infoPanel, "Class", entry.getName()); | 462 | addNameValue(infoPanel, "Class", entry.getFullName()); |
| 463 | addModifierComboBox(infoPanel, "Modifier", entry); | 463 | addModifierComboBox(infoPanel, "Modifier", entry); |
| 464 | } | 464 | } |
| 465 | 465 | ||
| 466 | private void showFieldEntry(FieldEntry entry) { | 466 | private void showFieldEntry(FieldEntry entry) { |
| 467 | addNameValue(infoPanel, "Field", entry.getName()); | 467 | addNameValue(infoPanel, "Field", entry.getName()); |
| 468 | addNameValue(infoPanel, "Class", entry.getOwnerClassEntry().getName()); | 468 | addNameValue(infoPanel, "Class", entry.getParent().getFullName()); |
| 469 | addNameValue(infoPanel, "TypeDescriptor", entry.getDesc().toString()); | 469 | addNameValue(infoPanel, "TypeDescriptor", entry.getDesc().toString()); |
| 470 | addModifierComboBox(infoPanel, "Modifier", entry); | 470 | addModifierComboBox(infoPanel, "Modifier", entry); |
| 471 | } | 471 | } |
| 472 | 472 | ||
| 473 | private void showMethodEntry(MethodEntry entry) { | 473 | private void showMethodEntry(MethodEntry entry) { |
| 474 | if (entry.isConstructor()) { | 474 | if (entry.isConstructor()) { |
| 475 | addNameValue(infoPanel, "Constructor", entry.getOwnerClassEntry().getName()); | 475 | addNameValue(infoPanel, "Constructor", entry.getParent().getFullName()); |
| 476 | } else { | 476 | } else { |
| 477 | addNameValue(infoPanel, "Method", entry.getName()); | 477 | addNameValue(infoPanel, "Method", entry.getName()); |
| 478 | addNameValue(infoPanel, "Class", entry.getOwnerClassEntry().getName()); | 478 | addNameValue(infoPanel, "Class", entry.getParent().getFullName()); |
| 479 | } | 479 | } |
| 480 | addNameValue(infoPanel, "MethodDescriptor", entry.getDesc().toString()); | 480 | addNameValue(infoPanel, "MethodDescriptor", entry.getDesc().toString()); |
| 481 | addModifierComboBox(infoPanel, "Modifier", entry); | 481 | addModifierComboBox(infoPanel, "Modifier", entry); |
| @@ -494,7 +494,7 @@ public class Gui { | |||
| 494 | container.add(panel); | 494 | container.add(panel); |
| 495 | } | 495 | } |
| 496 | 496 | ||
| 497 | private JComboBox<Mappings.EntryModifier> addModifierComboBox(JPanel container, String name, Entry entry) { | 497 | private JComboBox<AccessModifier> addModifierComboBox(JPanel container, String name, Entry entry) { |
| 498 | if (!getController().entryIsInJar(entry)) | 498 | if (!getController().entryIsInJar(entry)) |
| 499 | return null; | 499 | return null; |
| 500 | JPanel panel = new JPanel(); | 500 | JPanel panel = new JPanel(); |
| @@ -502,7 +502,7 @@ public class Gui { | |||
| 502 | JLabel label = new JLabel(name + ":", JLabel.RIGHT); | 502 | JLabel label = new JLabel(name + ":", JLabel.RIGHT); |
| 503 | label.setPreferredSize(new Dimension(100, label.getPreferredSize().height)); | 503 | label.setPreferredSize(new Dimension(100, label.getPreferredSize().height)); |
| 504 | panel.add(label); | 504 | panel.add(label); |
| 505 | JComboBox<Mappings.EntryModifier> combo = new JComboBox<>(Mappings.EntryModifier.values()); | 505 | JComboBox<AccessModifier> combo = new JComboBox<>(AccessModifier.values()); |
| 506 | ((JLabel) combo.getRenderer()).setHorizontalAlignment(JLabel.LEFT); | 506 | ((JLabel) combo.getRenderer()).setHorizontalAlignment(JLabel.LEFT); |
| 507 | combo.setPreferredSize(new Dimension(100, label.getPreferredSize().height)); | 507 | combo.setPreferredSize(new Dimension(100, label.getPreferredSize().height)); |
| 508 | combo.setSelectedIndex(getController().getDeobfuscator().getModifier(entry).ordinal()); | 508 | combo.setSelectedIndex(getController().getDeobfuscator().getModifier(entry).ordinal()); |
| @@ -520,11 +520,13 @@ public class Gui { | |||
| 520 | boolean isToken = token != null; | 520 | boolean isToken = token != null; |
| 521 | 521 | ||
| 522 | reference = this.controller.getDeobfReference(token); | 522 | reference = this.controller.getDeobfReference(token); |
| 523 | boolean isClassEntry = isToken && reference.entry instanceof ClassEntry; | 523 | |
| 524 | boolean isFieldEntry = isToken && reference.entry instanceof FieldEntry; | 524 | Entry<?> referenceEntry = reference != null ? reference.entry : null; |
| 525 | boolean isMethodEntry = isToken && reference.entry instanceof MethodEntry && !((MethodEntry) reference.entry).isConstructor(); | 525 | boolean isClassEntry = isToken && referenceEntry instanceof ClassEntry; |
| 526 | boolean isConstructorEntry = isToken && reference.entry instanceof MethodEntry && ((MethodEntry) reference.entry).isConstructor(); | 526 | boolean isFieldEntry = isToken && referenceEntry instanceof FieldEntry; |
| 527 | boolean isInJar = isToken && this.controller.entryIsInJar(reference.entry); | 527 | boolean isMethodEntry = isToken && referenceEntry instanceof MethodEntry && !((MethodEntry) referenceEntry).isConstructor(); |
| 528 | boolean isConstructorEntry = isToken && referenceEntry instanceof MethodEntry && ((MethodEntry) referenceEntry).isConstructor(); | ||
| 529 | boolean isInJar = isToken && this.controller.entryIsInJar(referenceEntry); | ||
| 528 | boolean isRenameable = isToken && this.controller.referenceIsRenameable(reference); | 530 | boolean isRenameable = isToken && this.controller.referenceIsRenameable(reference); |
| 529 | 531 | ||
| 530 | if (isToken) { | 532 | if (isToken) { |
| @@ -542,14 +544,14 @@ public class Gui { | |||
| 542 | this.popupMenu.openPreviousMenu.setEnabled(this.controller.hasPreviousLocation()); | 544 | this.popupMenu.openPreviousMenu.setEnabled(this.controller.hasPreviousLocation()); |
| 543 | this.popupMenu.toggleMappingMenu.setEnabled(isRenameable); | 545 | this.popupMenu.toggleMappingMenu.setEnabled(isRenameable); |
| 544 | 546 | ||
| 545 | if (isToken && this.controller.entryHasDeobfuscatedName(reference.entry)) { | 547 | if (isToken && this.controller.entryHasDeobfuscatedName(referenceEntry)) { |
| 546 | this.popupMenu.toggleMappingMenu.setText("Reset to obfuscated"); | 548 | this.popupMenu.toggleMappingMenu.setText("Reset to obfuscated"); |
| 547 | } else { | 549 | } else { |
| 548 | this.popupMenu.toggleMappingMenu.setText("Mark as deobfuscated"); | 550 | this.popupMenu.toggleMappingMenu.setText("Mark as deobfuscated"); |
| 549 | } | 551 | } |
| 550 | } | 552 | } |
| 551 | 553 | ||
| 552 | public void navigateTo(Entry entry) { | 554 | public void navigateTo(Entry<?> entry) { |
| 553 | if (!this.controller.entryIsInJar(entry)) { | 555 | if (!this.controller.entryIsInJar(entry)) { |
| 554 | // entry is not in the jar. Ignore it | 556 | // entry is not in the jar. Ignore it |
| 555 | return; | 557 | return; |
| @@ -560,7 +562,7 @@ public class Gui { | |||
| 560 | this.controller.openDeclaration(entry); | 562 | this.controller.openDeclaration(entry); |
| 561 | } | 563 | } |
| 562 | 564 | ||
| 563 | private void navigateTo(EntryReference<Entry, Entry> reference) { | 565 | private void navigateTo(EntryReference<Entry<?>, Entry<?>> reference) { |
| 564 | if (!this.controller.entryIsInJar(reference.getLocationClassEntry())) { | 566 | if (!this.controller.entryIsInJar(reference.getLocationClassEntry())) { |
| 565 | return; | 567 | return; |
| 566 | } | 568 | } |
| @@ -613,7 +615,7 @@ public class Gui { | |||
| 613 | String newName = text.getText(); | 615 | String newName = text.getText(); |
| 614 | if (saveName && newName != null && !newName.isEmpty()) { | 616 | if (saveName && newName != null && !newName.isEmpty()) { |
| 615 | try { | 617 | try { |
| 616 | this.controller.rename(reference, newName); | 618 | this.controller.rename(reference, newName, true); |
| 617 | } catch (IllegalNameException ex) { | 619 | } catch (IllegalNameException ex) { |
| 618 | text.setBorder(BorderFactory.createLineBorder(Color.red, 1)); | 620 | text.setBorder(BorderFactory.createLineBorder(Color.red, 1)); |
| 619 | text.setToolTipText(ex.getReason()); | 621 | text.setToolTipText(ex.getReason()); |
| @@ -737,13 +739,13 @@ public class Gui { | |||
| 737 | 739 | ||
| 738 | public void showDiscardDiag(Function<Integer, Void> callback, String... options) { | 740 | public void showDiscardDiag(Function<Integer, Void> callback, String... options) { |
| 739 | int response = JOptionPane.showOptionDialog(this.frame, "Your mappings have not been saved yet. Do you want to save?", "Save your changes?", JOptionPane.YES_NO_CANCEL_OPTION, | 741 | int response = JOptionPane.showOptionDialog(this.frame, "Your mappings have not been saved yet. Do you want to save?", "Save your changes?", JOptionPane.YES_NO_CANCEL_OPTION, |
| 740 | JOptionPane.QUESTION_MESSAGE, null, options, options[2]); | 742 | JOptionPane.QUESTION_MESSAGE, null, options, options[2]); |
| 741 | callback.apply(response); | 743 | callback.apply(response); |
| 742 | } | 744 | } |
| 743 | 745 | ||
| 744 | public void saveMapping() throws IOException { | 746 | public void saveMapping() throws IOException { |
| 745 | if (this.enigmaMappingsFileChooser.getSelectedFile() != null || this.enigmaMappingsFileChooser.showSaveDialog(this.frame) == JFileChooser.APPROVE_OPTION) | 747 | if (this.enigmaMappingsFileChooser.getSelectedFile() != null || this.enigmaMappingsFileChooser.showSaveDialog(this.frame) == JFileChooser.APPROVE_OPTION) |
| 746 | this.controller.saveMappings(this.enigmaMappingsFileChooser.getSelectedFile()); | 748 | this.controller.saveMappings(this.enigmaMappingsFileChooser.getSelectedFile().toPath()); |
| 747 | } | 749 | } |
| 748 | 750 | ||
| 749 | public void close() { | 751 | public void close() { |
| @@ -782,7 +784,7 @@ public class Gui { | |||
| 782 | DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) node.getChildAt(i); | 784 | DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) node.getChildAt(i); |
| 783 | ClassEntry prevDataChild = (ClassEntry) childNode.getUserObject(); | 785 | ClassEntry prevDataChild = (ClassEntry) childNode.getUserObject(); |
| 784 | ClassEntry dataChild = new ClassEntry(data + "/" + prevDataChild.getSimpleName()); | 786 | ClassEntry dataChild = new ClassEntry(data + "/" + prevDataChild.getSimpleName()); |
| 785 | this.controller.rename(new EntryReference<>(prevDataChild, prevDataChild.getName()), dataChild.getName(), false, i + 1 == node.getChildCount()); | 787 | this.controller.rename(new EntryReference<>(prevDataChild, prevDataChild.getFullName()), dataChild.getFullName(), false); |
| 786 | childNode.setUserObject(dataChild); | 788 | childNode.setUserObject(dataChild); |
| 787 | } | 789 | } |
| 788 | node.setUserObject(data); | 790 | node.setUserObject(data); |
| @@ -791,19 +793,19 @@ public class Gui { | |||
| 791 | } | 793 | } |
| 792 | // class rename | 794 | // class rename |
| 793 | else if (data instanceof ClassEntry) | 795 | else if (data instanceof ClassEntry) |
| 794 | this.controller.rename(new EntryReference<>((ClassEntry) prevData, ((ClassEntry) prevData).getName()), ((ClassEntry) data).getName(), false, true); | 796 | this.controller.rename(new EntryReference<>((ClassEntry) prevData, ((ClassEntry) prevData).getFullName()), ((ClassEntry) data).getFullName(), false); |
| 795 | } | 797 | } |
| 796 | 798 | ||
| 797 | public void moveClassTree(EntryReference<Entry, Entry> deobfReference, String newName) { | 799 | public void moveClassTree(EntryReference<Entry<?>, Entry<?>> deobfReference, String newName) { |
| 798 | String oldEntry = deobfReference.entry.getOwnerClassEntry().getPackageName(); | 800 | String oldEntry = deobfReference.entry.getContainingClass().getPackageName(); |
| 799 | String newEntry = new ClassEntry(newName).getPackageName(); | 801 | String newEntry = new ClassEntry(newName).getPackageName(); |
| 800 | moveClassTree(deobfReference, newName, oldEntry == null, | 802 | moveClassTree(deobfReference, newName, oldEntry == null, |
| 801 | newEntry == null); | 803 | newEntry == null); |
| 802 | } | 804 | } |
| 803 | 805 | ||
| 804 | // TODO: getExpansionState will *not* actually update itself based on name changes! | 806 | // TODO: getExpansionState will *not* actually update itself based on name changes! |
| 805 | public void moveClassTree(EntryReference<Entry, Entry> deobfReference, String newName, boolean isOldOb, boolean isNewOb) { | 807 | public void moveClassTree(EntryReference<Entry<?>, Entry<?>> deobfReference, String newName, boolean isOldOb, boolean isNewOb) { |
| 806 | ClassEntry oldEntry = deobfReference.entry.getOwnerClassEntry(); | 808 | ClassEntry oldEntry = deobfReference.entry.getContainingClass(); |
| 807 | ClassEntry newEntry = new ClassEntry(newName); | 809 | ClassEntry newEntry = new ClassEntry(newName); |
| 808 | 810 | ||
| 809 | // Ob -> deob | 811 | // Ob -> deob |