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 | |
| 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')
10 files changed, 172 insertions, 322 deletions
diff --git a/src/main/java/cuchaz/enigma/gui/ClassSelector.java b/src/main/java/cuchaz/enigma/gui/ClassSelector.java index 8863386..c3b7288 100644 --- a/src/main/java/cuchaz/enigma/gui/ClassSelector.java +++ b/src/main/java/cuchaz/enigma/gui/ClassSelector.java | |||
| @@ -17,14 +17,13 @@ import com.google.common.collect.Maps; | |||
| 17 | import com.google.common.collect.Multimap; | 17 | import com.google.common.collect.Multimap; |
| 18 | import cuchaz.enigma.gui.node.ClassSelectorClassNode; | 18 | import cuchaz.enigma.gui.node.ClassSelectorClassNode; |
| 19 | import cuchaz.enigma.gui.node.ClassSelectorPackageNode; | 19 | import cuchaz.enigma.gui.node.ClassSelectorPackageNode; |
| 20 | import cuchaz.enigma.mapping.entry.ClassEntry; | 20 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| 21 | import cuchaz.enigma.throwables.IllegalNameException; | 21 | import cuchaz.enigma.throwables.IllegalNameException; |
| 22 | 22 | ||
| 23 | import javax.swing.*; | 23 | import javax.swing.*; |
| 24 | import javax.swing.event.CellEditorListener; | 24 | import javax.swing.event.CellEditorListener; |
| 25 | import javax.swing.event.ChangeEvent; | 25 | import javax.swing.event.ChangeEvent; |
| 26 | import javax.swing.tree.*; | 26 | import javax.swing.tree.*; |
| 27 | import java.awt.*; | ||
| 28 | import java.awt.event.MouseAdapter; | 27 | import java.awt.event.MouseAdapter; |
| 29 | import java.awt.event.MouseEvent; | 28 | import java.awt.event.MouseEvent; |
| 30 | import java.util.*; | 29 | import java.util.*; |
| @@ -32,7 +31,7 @@ import java.util.List; | |||
| 32 | 31 | ||
| 33 | public class ClassSelector extends JTree { | 32 | public class ClassSelector extends JTree { |
| 34 | 33 | ||
| 35 | public static final Comparator<ClassEntry> DEOBF_CLASS_COMPARATOR = Comparator.comparing(ClassEntry::getName); | 34 | public static final Comparator<ClassEntry> DEOBF_CLASS_COMPARATOR = Comparator.comparing(ClassEntry::getFullName); |
| 36 | private DefaultMutableTreeNode rootNodes; | 35 | private DefaultMutableTreeNode rootNodes; |
| 37 | private ClassSelectionListener selectionListener; | 36 | private ClassSelectionListener selectionListener; |
| 38 | private RenameSelectionListener renameSelectionListener; | 37 | private RenameSelectionListener renameSelectionListener; |
diff --git a/src/main/java/cuchaz/enigma/gui/CodeReader.java b/src/main/java/cuchaz/enigma/gui/CodeReader.java index 137c730..0810043 100644 --- a/src/main/java/cuchaz/enigma/gui/CodeReader.java +++ b/src/main/java/cuchaz/enigma/gui/CodeReader.java | |||
| @@ -16,9 +16,8 @@ import cuchaz.enigma.Deobfuscator; | |||
| 16 | import cuchaz.enigma.analysis.EntryReference; | 16 | import cuchaz.enigma.analysis.EntryReference; |
| 17 | import cuchaz.enigma.analysis.SourceIndex; | 17 | import cuchaz.enigma.analysis.SourceIndex; |
| 18 | import cuchaz.enigma.analysis.Token; | 18 | import cuchaz.enigma.analysis.Token; |
| 19 | import cuchaz.enigma.gui.highlight.SelectionHighlightPainter; | 19 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| 20 | import cuchaz.enigma.mapping.entry.ClassEntry; | 20 | import cuchaz.enigma.translation.representation.entry.Entry; |
| 21 | import cuchaz.enigma.mapping.entry.Entry; | ||
| 22 | import de.sciss.syntaxpane.DefaultSyntaxKit; | 21 | import de.sciss.syntaxpane.DefaultSyntaxKit; |
| 23 | 22 | ||
| 24 | import javax.swing.*; | 23 | import javax.swing.*; |
| @@ -33,7 +32,6 @@ public class CodeReader extends JEditorPane { | |||
| 33 | private static final long serialVersionUID = 3673180950485748810L; | 32 | private static final long serialVersionUID = 3673180950485748810L; |
| 34 | 33 | ||
| 35 | private static final Object lock = new Object(); | 34 | private static final Object lock = new Object(); |
| 36 | private SelectionHighlightPainter selectionHighlightPainter; | ||
| 37 | private SourceIndex sourceIndex; | 35 | private SourceIndex sourceIndex; |
| 38 | private SelectionListener selectionListener; | 36 | private SelectionListener selectionListener; |
| 39 | 37 | ||
| @@ -58,8 +56,6 @@ public class CodeReader extends JEditorPane { | |||
| 58 | } | 56 | } |
| 59 | } | 57 | } |
| 60 | }); | 58 | }); |
| 61 | |||
| 62 | selectionHighlightPainter = new SelectionHighlightPainter(); | ||
| 63 | } | 59 | } |
| 64 | 60 | ||
| 65 | // HACKHACK: someday we can update the main GUI to use this code reader | 61 | // HACKHACK: someday we can update the main GUI to use this code reader |
| @@ -144,7 +140,7 @@ public class CodeReader extends JEditorPane { | |||
| 144 | 140 | ||
| 145 | // decompile it | 141 | // decompile it |
| 146 | 142 | ||
| 147 | CompilationUnit sourceTree = deobfuscator.getSourceTree(classEntry.getOutermostClassName()); | 143 | CompilationUnit sourceTree = deobfuscator.getSourceTree(classEntry.getName()); |
| 148 | String source = deobfuscator.getSource(sourceTree); | 144 | String source = deobfuscator.getSource(sourceTree); |
| 149 | setCode(source); | 145 | setCode(source); |
| 150 | sourceIndex = deobfuscator.getSourceIndex(sourceTree, source, ignoreBadTokens); | 146 | sourceIndex = deobfuscator.getSourceIndex(sourceTree, source, ignoreBadTokens); |
| @@ -155,52 +151,7 @@ public class CodeReader extends JEditorPane { | |||
| 155 | }).start(); | 151 | }).start(); |
| 156 | } | 152 | } |
| 157 | 153 | ||
| 158 | public void navigateToClassDeclaration(ClassEntry classEntry) { | ||
| 159 | |||
| 160 | // navigate to the class declaration | ||
| 161 | Token token = sourceIndex.getDeclarationToken(classEntry); | ||
| 162 | if (token == null) { | ||
| 163 | // couldn't find the class declaration token, might be an anonymous class | ||
| 164 | // look for any declaration in that class instead | ||
| 165 | for (Entry entry : sourceIndex.declarations()) { | ||
| 166 | if (entry.getOwnerClassEntry().equals(classEntry)) { | ||
| 167 | token = sourceIndex.getDeclarationToken(entry); | ||
| 168 | break; | ||
| 169 | } | ||
| 170 | } | ||
| 171 | } | ||
| 172 | |||
| 173 | if (token != null) { | ||
| 174 | navigateToToken(token); | ||
| 175 | } else { | ||
| 176 | // couldn't find anything =( | ||
| 177 | System.out.println("Unable to find declaration in source for " + classEntry); | ||
| 178 | } | ||
| 179 | } | ||
| 180 | |||
| 181 | public void navigateToToken(final Token token) { | ||
| 182 | navigateToToken(this, token, selectionHighlightPainter); | ||
| 183 | } | ||
| 184 | |||
| 185 | public void setHighlightedTokens(Iterable<Token> tokens, HighlightPainter painter) { | ||
| 186 | for (Token token : tokens) { | ||
| 187 | setHighlightedToken(token, painter); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | public void setHighlightedToken(Token token, HighlightPainter painter) { | ||
| 192 | try { | ||
| 193 | getHighlighter().addHighlight(token.start, token.end, painter); | ||
| 194 | } catch (BadLocationException ex) { | ||
| 195 | throw new IllegalArgumentException(ex); | ||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 199 | public void clearHighlights() { | ||
| 200 | getHighlighter().removeAllHighlights(); | ||
| 201 | } | ||
| 202 | |||
| 203 | public interface SelectionListener { | 154 | public interface SelectionListener { |
| 204 | void onSelect(EntryReference<Entry, Entry> reference); | 155 | void onSelect(EntryReference<Entry<?>, Entry<?>> reference); |
| 205 | } | 156 | } |
| 206 | } | 157 | } |
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 |
diff --git a/src/main/java/cuchaz/enigma/gui/GuiController.java b/src/main/java/cuchaz/enigma/gui/GuiController.java index 69aefe5..06cb33e 100644 --- a/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/src/main/java/cuchaz/enigma/gui/GuiController.java | |||
| @@ -20,19 +20,25 @@ import cuchaz.enigma.analysis.*; | |||
| 20 | import cuchaz.enigma.api.EnigmaPlugin; | 20 | import cuchaz.enigma.api.EnigmaPlugin; |
| 21 | import cuchaz.enigma.config.Config; | 21 | import cuchaz.enigma.config.Config; |
| 22 | import cuchaz.enigma.gui.dialog.ProgressDialog; | 22 | import cuchaz.enigma.gui.dialog.ProgressDialog; |
| 23 | import cuchaz.enigma.mapping.*; | ||
| 24 | import cuchaz.enigma.mapping.entry.ClassEntry; | ||
| 25 | import cuchaz.enigma.mapping.entry.Entry; | ||
| 26 | import cuchaz.enigma.mapping.entry.FieldEntry; | ||
| 27 | import cuchaz.enigma.mapping.entry.MethodEntry; | ||
| 28 | import cuchaz.enigma.throwables.MappingParseException; | 23 | import cuchaz.enigma.throwables.MappingParseException; |
| 24 | import cuchaz.enigma.translation.Translator; | ||
| 25 | import cuchaz.enigma.translation.mapping.*; | ||
| 26 | import cuchaz.enigma.translation.mapping.serde.MappingFormat; | ||
| 27 | import cuchaz.enigma.translation.mapping.tree.EntryTree; | ||
| 28 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | ||
| 29 | import cuchaz.enigma.translation.representation.entry.Entry; | ||
| 30 | import cuchaz.enigma.translation.representation.entry.FieldEntry; | ||
| 31 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | ||
| 29 | import cuchaz.enigma.utils.ReadableToken; | 32 | import cuchaz.enigma.utils.ReadableToken; |
| 30 | 33 | ||
| 34 | import javax.annotation.Nullable; | ||
| 31 | import java.awt.event.ItemEvent; | 35 | import java.awt.event.ItemEvent; |
| 32 | import java.io.File; | 36 | import java.io.File; |
| 33 | import java.io.IOException; | 37 | import java.io.IOException; |
| 38 | import java.nio.file.Path; | ||
| 34 | import java.util.*; | 39 | import java.util.*; |
| 35 | import java.util.jar.JarFile; | 40 | import java.util.jar.JarFile; |
| 41 | import java.util.stream.Collectors; | ||
| 36 | 42 | ||
| 37 | public class GuiController { | 43 | public class GuiController { |
| 38 | 44 | ||
| @@ -40,27 +46,26 @@ public class GuiController { | |||
| 40 | private Gui gui; | 46 | private Gui gui; |
| 41 | private SourceIndex index; | 47 | private SourceIndex index; |
| 42 | private ClassEntry currentObfClass; | 48 | private ClassEntry currentObfClass; |
| 43 | private boolean isDirty; | 49 | private Deque<EntryReference<Entry<?>, Entry<?>>> referenceStack; |
| 44 | private Deque<EntryReference<Entry, Entry>> referenceStack; | 50 | |
| 51 | private Path loadedMappingPath; | ||
| 52 | private MappingFormat loadedMappingFormat; | ||
| 45 | 53 | ||
| 46 | public GuiController(Gui gui) { | 54 | public GuiController(Gui gui) { |
| 47 | this.gui = gui; | 55 | this.gui = gui; |
| 48 | this.deobfuscator = null; | 56 | this.deobfuscator = null; |
| 49 | this.index = null; | 57 | this.index = null; |
| 50 | this.currentObfClass = null; | 58 | this.currentObfClass = null; |
| 51 | this.isDirty = false; | ||
| 52 | this.referenceStack = Queues.newArrayDeque(); | 59 | this.referenceStack = Queues.newArrayDeque(); |
| 53 | } | 60 | } |
| 54 | 61 | ||
| 55 | public boolean isDirty() { | 62 | public boolean isDirty() { |
| 56 | return this.isDirty; | 63 | return deobfuscator.getMapper().isDirty(); |
| 57 | } | 64 | } |
| 58 | 65 | ||
| 59 | public void openJar(final JarFile jar) throws IOException { | 66 | public void openJar(final JarFile jar) throws IOException { |
| 60 | this.gui.onStartOpenJar("Loading JAR..."); | 67 | this.gui.onStartOpenJar("Loading JAR..."); |
| 61 | this.deobfuscator = new Deobfuscator(jar, (msg) -> { | 68 | this.deobfuscator = new Deobfuscator(jar, this.gui::onStartOpenJar); |
| 62 | this.gui.onStartOpenJar(msg); | ||
| 63 | }); | ||
| 64 | this.gui.onFinishOpenJar(jar.getName()); | 69 | this.gui.onFinishOpenJar(jar.getName()); |
| 65 | refreshClasses(); | 70 | refreshClasses(); |
| 66 | } | 71 | } |
| @@ -70,43 +75,37 @@ public class GuiController { | |||
| 70 | this.gui.onCloseJar(); | 75 | this.gui.onCloseJar(); |
| 71 | } | 76 | } |
| 72 | 77 | ||
| 73 | public void openEnigmaMappings(File file) throws IOException, MappingParseException { | 78 | public void openMappings(MappingFormat format, Path path) throws IOException, MappingParseException { |
| 74 | this.deobfuscator.setMappings(new MappingsEnigmaReader().read(file)); | 79 | EntryTree<EntryMapping> mappings = format.read(path); |
| 75 | this.isDirty = false; | 80 | deobfuscator.setMappings(mappings); |
| 76 | this.gui.setMappingsFile(file); | 81 | |
| 82 | gui.setMappingsFile(path); | ||
| 83 | loadedMappingFormat = format; | ||
| 84 | |||
| 77 | refreshClasses(); | 85 | refreshClasses(); |
| 78 | refreshCurrentClass(); | 86 | refreshCurrentClass(); |
| 79 | } | 87 | } |
| 80 | 88 | ||
| 81 | public void openTinyMappings(File file) throws IOException, MappingParseException { | 89 | public void saveMappings(Path path) { |
| 82 | this.deobfuscator.setMappings(new MappingsTinyReader().read(file)); | 90 | saveMappings(loadedMappingFormat, path); |
| 83 | this.isDirty = false; | ||
| 84 | this.gui.setMappingsFile(file); | ||
| 85 | refreshClasses(); | ||
| 86 | refreshCurrentClass(); | ||
| 87 | } | 91 | } |
| 88 | 92 | ||
| 89 | public void saveMappings(File file) throws IOException { | 93 | public void saveMappings(MappingFormat format, Path path) { |
| 90 | Mappings mappings = this.deobfuscator.getMappings(); | 94 | EntryRemapper mapper = deobfuscator.getMapper(); |
| 91 | switch (mappings.getOriginMappingFormat()) { | ||
| 92 | case SRG_FILE: | ||
| 93 | saveSRGMappings(file); | ||
| 94 | break; | ||
| 95 | default: | ||
| 96 | saveEnigmaMappings(file, Mappings.FormatType.ENIGMA_FILE != mappings.getOriginMappingFormat()); | ||
| 97 | break; | ||
| 98 | } | ||
| 99 | 95 | ||
| 100 | } | 96 | MappingDelta delta = mapper.takeMappingDelta(); |
| 97 | boolean saveAll = !path.equals(loadedMappingPath); | ||
| 101 | 98 | ||
| 102 | public void saveEnigmaMappings(File file, boolean isDirectoryFormat) throws IOException { | 99 | ProgressDialog.runInThread(this.gui.getFrame(), progress -> { |
| 103 | this.deobfuscator.getMappings().saveEnigmaMappings(file, isDirectoryFormat); | 100 | if (saveAll) { |
| 104 | this.isDirty = false; | 101 | format.write(mapper.getObfToDeobf(), path, progress); |
| 105 | } | 102 | } else { |
| 103 | format.write(mapper.getObfToDeobf(), delta, path, progress); | ||
| 104 | } | ||
| 105 | }); | ||
| 106 | 106 | ||
| 107 | public void saveSRGMappings(File file) throws IOException { | 107 | loadedMappingFormat = format; |
| 108 | this.deobfuscator.getMappings().saveSRGMappings(file); | 108 | loadedMappingPath = path; |
| 109 | this.isDirty = false; | ||
| 110 | } | 109 | } |
| 111 | 110 | ||
| 112 | public void closeMappings() { | 111 | public void closeMappings() { |
| @@ -116,11 +115,6 @@ public class GuiController { | |||
| 116 | refreshCurrentClass(); | 115 | refreshCurrentClass(); |
| 117 | } | 116 | } |
| 118 | 117 | ||
| 119 | public void rebuildMethodNames() { | ||
| 120 | ProgressDialog.runInThread(this.gui.getFrame(), progress -> this.deobfuscator.rebuildMethodNames(progress)); | ||
| 121 | this.isDirty = true; | ||
| 122 | } | ||
| 123 | |||
| 124 | public void exportSource(final File dirOut) { | 118 | public void exportSource(final File dirOut) { |
| 125 | ProgressDialog.runInThread(this.gui.getFrame(), progress -> this.deobfuscator.writeSources(dirOut, progress)); | 119 | ProgressDialog.runInThread(this.gui.getFrame(), progress -> this.deobfuscator.writeSources(dirOut, progress)); |
| 126 | } | 120 | } |
| @@ -136,7 +130,8 @@ public class GuiController { | |||
| 136 | return this.index.getReferenceToken(pos); | 130 | return this.index.getReferenceToken(pos); |
| 137 | } | 131 | } |
| 138 | 132 | ||
| 139 | public EntryReference<Entry, Entry> getDeobfReference(Token token) { | 133 | @Nullable |
| 134 | public EntryReference<Entry<?>, Entry<?>> getDeobfReference(Token token) { | ||
| 140 | if (this.index == null) { | 135 | if (this.index == null) { |
| 141 | return null; | 136 | return null; |
| 142 | } | 137 | } |
| @@ -148,44 +143,52 @@ public class GuiController { | |||
| 148 | return null; | 143 | return null; |
| 149 | } | 144 | } |
| 150 | return new ReadableToken( | 145 | return new ReadableToken( |
| 151 | this.index.getLineNumber(token.start), | 146 | this.index.getLineNumber(token.start), |
| 152 | this.index.getColumnNumber(token.start), | 147 | this.index.getColumnNumber(token.start), |
| 153 | this.index.getColumnNumber(token.end) | 148 | this.index.getColumnNumber(token.end) |
| 154 | ); | 149 | ); |
| 155 | } | 150 | } |
| 156 | 151 | ||
| 157 | public boolean entryHasDeobfuscatedName(Entry deobfEntry) { | 152 | public boolean entryHasDeobfuscatedName(Entry<?> deobfEntry) { |
| 158 | return this.deobfuscator.hasDeobfuscatedName(this.deobfuscator.obfuscateEntry(deobfEntry)); | 153 | EntryResolver resolver = this.deobfuscator.getMapper().getDeobfResolver(); |
| 154 | Entry<?> resolvedEntry = resolver.resolveFirstEntry(deobfEntry, ResolutionStrategy.RESOLVE_ROOT); | ||
| 155 | return this.deobfuscator.hasDeobfuscatedName(this.deobfuscator.getMapper().obfuscate(resolvedEntry)); | ||
| 159 | } | 156 | } |
| 160 | 157 | ||
| 161 | public boolean entryIsInJar(Entry deobfEntry) { | 158 | public boolean entryIsInJar(Entry<?> deobfEntry) { |
| 162 | return this.deobfuscator.isObfuscatedIdentifier(this.deobfuscator.obfuscateEntry(deobfEntry)); | 159 | if (deobfEntry == null) return false; |
| 160 | return this.deobfuscator.isObfuscatedIdentifier(this.deobfuscator.getMapper().obfuscate(deobfEntry)); | ||
| 163 | } | 161 | } |
| 164 | 162 | ||
| 165 | public boolean referenceIsRenameable(EntryReference<Entry, Entry> deobfReference) { | 163 | public boolean referenceIsRenameable(EntryReference<Entry<?>, Entry<?>> deobfReference) { |
| 166 | return this.deobfuscator.isRenameable(this.deobfuscator.obfuscateReference(deobfReference)); | 164 | if (deobfReference == null) return false; |
| 165 | return this.deobfuscator.isRenameable(this.deobfuscator.getMapper().obfuscate(deobfReference)); | ||
| 167 | } | 166 | } |
| 168 | 167 | ||
| 169 | public ClassInheritanceTreeNode getClassInheritance(ClassEntry deobfClassEntry) { | 168 | public ClassInheritanceTreeNode getClassInheritance(ClassEntry deobfClassEntry) { |
| 170 | ClassEntry obfClassEntry = this.deobfuscator.obfuscateEntry(deobfClassEntry); | 169 | ClassEntry obfClassEntry = this.deobfuscator.getMapper().obfuscate(deobfClassEntry); |
| 171 | ClassInheritanceTreeNode rootNode = this.deobfuscator.getJarIndex().getClassInheritance(this.deobfuscator.getTranslator(TranslationDirection.DEOBFUSCATING), obfClassEntry); | 170 | Translator translator = this.deobfuscator.getMapper().getDeobfuscator(); |
| 171 | ClassInheritanceTreeNode rootNode = this.deobfuscator.getIndexTreeBuilder().buildClassInheritance(translator, obfClassEntry); | ||
| 172 | return ClassInheritanceTreeNode.findNode(rootNode, obfClassEntry); | 172 | return ClassInheritanceTreeNode.findNode(rootNode, obfClassEntry); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | public ClassImplementationsTreeNode getClassImplementations(ClassEntry deobfClassEntry) { | 175 | public ClassImplementationsTreeNode getClassImplementations(ClassEntry deobfClassEntry) { |
| 176 | ClassEntry obfClassEntry = this.deobfuscator.obfuscateEntry(deobfClassEntry); | 176 | ClassEntry obfClassEntry = this.deobfuscator.getMapper().obfuscate(deobfClassEntry); |
| 177 | return this.deobfuscator.getJarIndex().getClassImplementations(this.deobfuscator.getTranslator(TranslationDirection.DEOBFUSCATING), obfClassEntry); | 177 | Translator translator = this.deobfuscator.getMapper().getDeobfuscator(); |
| 178 | return this.deobfuscator.getIndexTreeBuilder().buildClassImplementations(translator, obfClassEntry); | ||
| 178 | } | 179 | } |
| 179 | 180 | ||
| 180 | public MethodInheritanceTreeNode getMethodInheritance(MethodEntry deobfMethodEntry) { | 181 | public MethodInheritanceTreeNode getMethodInheritance(MethodEntry deobfMethodEntry) { |
| 181 | MethodEntry obfMethodEntry = this.deobfuscator.obfuscateEntry(deobfMethodEntry); | 182 | MethodEntry obfMethodEntry = this.deobfuscator.getMapper().obfuscate(deobfMethodEntry); |
| 182 | MethodInheritanceTreeNode rootNode = this.deobfuscator.getJarIndex().getMethodInheritance(this.deobfuscator.getTranslator(TranslationDirection.DEOBFUSCATING), obfMethodEntry); | 183 | Translator translator = this.deobfuscator.getMapper().getDeobfuscator(); |
| 184 | MethodInheritanceTreeNode rootNode = this.deobfuscator.getIndexTreeBuilder().buildMethodInheritance(translator, obfMethodEntry); | ||
| 183 | return MethodInheritanceTreeNode.findNode(rootNode, obfMethodEntry); | 185 | return MethodInheritanceTreeNode.findNode(rootNode, obfMethodEntry); |
| 184 | } | 186 | } |
| 185 | 187 | ||
| 186 | public MethodImplementationsTreeNode getMethodImplementations(MethodEntry deobfMethodEntry) { | 188 | public MethodImplementationsTreeNode getMethodImplementations(MethodEntry deobfMethodEntry) { |
| 187 | MethodEntry obfMethodEntry = this.deobfuscator.obfuscateEntry(deobfMethodEntry); | 189 | MethodEntry obfMethodEntry = this.deobfuscator.getMapper().obfuscate(deobfMethodEntry); |
| 188 | List<MethodImplementationsTreeNode> rootNodes = this.deobfuscator.getJarIndex().getMethodImplementations(this.deobfuscator.getTranslator(TranslationDirection.DEOBFUSCATING), obfMethodEntry); | 190 | Translator translator = this.deobfuscator.getMapper().getDeobfuscator(); |
| 191 | List<MethodImplementationsTreeNode> rootNodes = this.deobfuscator.getIndexTreeBuilder().buildMethodImplementations(translator, obfMethodEntry); | ||
| 189 | if (rootNodes.isEmpty()) { | 192 | if (rootNodes.isEmpty()) { |
| 190 | return null; | 193 | return null; |
| 191 | } | 194 | } |
| @@ -196,34 +199,32 @@ public class GuiController { | |||
| 196 | } | 199 | } |
| 197 | 200 | ||
| 198 | public ClassReferenceTreeNode getClassReferences(ClassEntry deobfClassEntry) { | 201 | public ClassReferenceTreeNode getClassReferences(ClassEntry deobfClassEntry) { |
| 199 | ClassEntry obfClassEntry = this.deobfuscator.obfuscateEntry(deobfClassEntry); | 202 | ClassEntry obfClassEntry = this.deobfuscator.getMapper().obfuscate(deobfClassEntry); |
| 200 | ClassReferenceTreeNode rootNode = new ClassReferenceTreeNode(this.deobfuscator.getTranslator(TranslationDirection.DEOBFUSCATING), obfClassEntry); | 203 | Translator deobfuscator = this.deobfuscator.getMapper().getDeobfuscator(); |
| 204 | ClassReferenceTreeNode rootNode = new ClassReferenceTreeNode(deobfuscator, obfClassEntry); | ||
| 201 | rootNode.load(this.deobfuscator.getJarIndex(), true); | 205 | rootNode.load(this.deobfuscator.getJarIndex(), true); |
| 202 | return rootNode; | 206 | return rootNode; |
| 203 | } | 207 | } |
| 204 | 208 | ||
| 205 | public FieldReferenceTreeNode getFieldReferences(FieldEntry deobfFieldEntry) { | 209 | public FieldReferenceTreeNode getFieldReferences(FieldEntry deobfFieldEntry) { |
| 206 | FieldEntry obfFieldEntry = this.deobfuscator.obfuscateEntry(deobfFieldEntry); | 210 | FieldEntry obfFieldEntry = this.deobfuscator.getMapper().obfuscate(deobfFieldEntry); |
| 207 | FieldReferenceTreeNode rootNode = new FieldReferenceTreeNode(this.deobfuscator.getTranslator(TranslationDirection.DEOBFUSCATING), obfFieldEntry); | 211 | Translator translator = this.deobfuscator.getMapper().getDeobfuscator(); |
| 212 | FieldReferenceTreeNode rootNode = new FieldReferenceTreeNode(translator, obfFieldEntry); | ||
| 208 | rootNode.load(this.deobfuscator.getJarIndex(), true); | 213 | rootNode.load(this.deobfuscator.getJarIndex(), true); |
| 209 | return rootNode; | 214 | return rootNode; |
| 210 | } | 215 | } |
| 211 | 216 | ||
| 212 | public MethodReferenceTreeNode getMethodReferences(MethodEntry deobfMethodEntry, boolean recursive) { | 217 | public MethodReferenceTreeNode getMethodReferences(MethodEntry deobfMethodEntry, boolean recursive) { |
| 213 | MethodEntry obfMethodEntry = this.deobfuscator.obfuscateEntry(deobfMethodEntry); | 218 | MethodEntry obfMethodEntry = this.deobfuscator.getMapper().obfuscate(deobfMethodEntry); |
| 214 | MethodReferenceTreeNode rootNode = new MethodReferenceTreeNode(this.deobfuscator.getTranslator(TranslationDirection.DEOBFUSCATING), obfMethodEntry); | 219 | Translator translator = this.deobfuscator.getMapper().getDeobfuscator(); |
| 220 | MethodReferenceTreeNode rootNode = new MethodReferenceTreeNode(translator, obfMethodEntry); | ||
| 215 | rootNode.load(this.deobfuscator.getJarIndex(), true, recursive); | 221 | rootNode.load(this.deobfuscator.getJarIndex(), true, recursive); |
| 216 | return rootNode; | 222 | return rootNode; |
| 217 | } | 223 | } |
| 218 | 224 | ||
| 219 | public void rename(EntryReference<Entry, Entry> deobfReference, String newName) { | 225 | public void rename(EntryReference<Entry<?>, Entry<?>> deobfReference, String newName, boolean refreshClassTree) { |
| 220 | rename(deobfReference, newName, true, true); | 226 | EntryReference<Entry<?>, Entry<?>> obfReference = this.deobfuscator.getMapper().obfuscate(deobfReference); |
| 221 | } | 227 | this.deobfuscator.rename(obfReference.getNameableEntry(), newName); |
| 222 | |||
| 223 | public void rename(EntryReference<Entry, Entry> deobfReference, String newName, boolean refreshClassTree, boolean clearTranslationCache) { | ||
| 224 | EntryReference<Entry, Entry> obfReference = this.deobfuscator.obfuscateReference(deobfReference); | ||
| 225 | this.deobfuscator.rename(obfReference.getNameableEntry(), newName, clearTranslationCache); | ||
| 226 | this.isDirty = true; | ||
| 227 | 228 | ||
| 228 | if (refreshClassTree && deobfReference.entry instanceof ClassEntry && !((ClassEntry) deobfReference.entry).isInnerClass()) | 229 | if (refreshClassTree && deobfReference.entry instanceof ClassEntry && !((ClassEntry) deobfReference.entry).isInnerClass()) |
| 229 | this.gui.moveClassTree(deobfReference, newName); | 230 | this.gui.moveClassTree(deobfReference, newName); |
| @@ -231,39 +232,37 @@ public class GuiController { | |||
| 231 | 232 | ||
| 232 | } | 233 | } |
| 233 | 234 | ||
| 234 | public void removeMapping(EntryReference<Entry, Entry> deobfReference) { | 235 | public void removeMapping(EntryReference<Entry<?>, Entry<?>> deobfReference) { |
| 235 | EntryReference<Entry, Entry> obfReference = this.deobfuscator.obfuscateReference(deobfReference); | 236 | EntryReference<Entry<?>, Entry<?>> obfReference = this.deobfuscator.getMapper().obfuscate(deobfReference); |
| 236 | this.deobfuscator.removeMapping(obfReference.getNameableEntry()); | 237 | this.deobfuscator.removeMapping(obfReference.getNameableEntry()); |
| 237 | this.isDirty = true; | ||
| 238 | if (deobfReference.entry instanceof ClassEntry) | 238 | if (deobfReference.entry instanceof ClassEntry) |
| 239 | this.gui.moveClassTree(deobfReference, obfReference.entry.getName(), false, true); | 239 | this.gui.moveClassTree(deobfReference, obfReference.entry.getName(), false, true); |
| 240 | refreshCurrentClass(obfReference); | 240 | refreshCurrentClass(obfReference); |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | public void markAsDeobfuscated(EntryReference<Entry, Entry> deobfReference) { | 243 | public void markAsDeobfuscated(EntryReference<Entry<?>, Entry<?>> deobfReference) { |
| 244 | EntryReference<Entry, Entry> obfReference = this.deobfuscator.obfuscateReference(deobfReference); | 244 | EntryReference<Entry<?>, Entry<?>> obfReference = this.deobfuscator.getMapper().obfuscate(deobfReference); |
| 245 | this.deobfuscator.markAsDeobfuscated(obfReference.getNameableEntry()); | 245 | this.deobfuscator.markAsDeobfuscated(obfReference.getNameableEntry()); |
| 246 | this.isDirty = true; | ||
| 247 | if (deobfReference.entry instanceof ClassEntry && !((ClassEntry) deobfReference.entry).isInnerClass()) | 246 | if (deobfReference.entry instanceof ClassEntry && !((ClassEntry) deobfReference.entry).isInnerClass()) |
| 248 | this.gui.moveClassTree(deobfReference, obfReference.entry.getName(), true, false); | 247 | this.gui.moveClassTree(deobfReference, obfReference.entry.getName(), true, false); |
| 249 | refreshCurrentClass(obfReference); | 248 | refreshCurrentClass(obfReference); |
| 250 | } | 249 | } |
| 251 | 250 | ||
| 252 | public void openDeclaration(Entry deobfEntry) { | 251 | public void openDeclaration(Entry<?> deobfEntry) { |
| 253 | if (deobfEntry == null) { | 252 | if (deobfEntry == null) { |
| 254 | throw new IllegalArgumentException("Entry cannot be null!"); | 253 | throw new IllegalArgumentException("Entry cannot be null!"); |
| 255 | } | 254 | } |
| 256 | openReference(new EntryReference<>(deobfEntry, deobfEntry.getName())); | 255 | openReference(new EntryReference<>(deobfEntry, deobfEntry.getName())); |
| 257 | } | 256 | } |
| 258 | 257 | ||
| 259 | public void openReference(EntryReference<Entry, Entry> deobfReference) { | 258 | public void openReference(EntryReference<Entry<?>, Entry<?>> deobfReference) { |
| 260 | if (deobfReference == null) { | 259 | if (deobfReference == null) { |
| 261 | throw new IllegalArgumentException("Reference cannot be null!"); | 260 | throw new IllegalArgumentException("Reference cannot be null!"); |
| 262 | } | 261 | } |
| 263 | 262 | ||
| 264 | // get the reference target class | 263 | // get the reference target class |
| 265 | EntryReference<Entry, Entry> obfReference = this.deobfuscator.obfuscateReference(deobfReference); | 264 | EntryReference<Entry<?>, Entry<?>> obfReference = this.deobfuscator.getMapper().obfuscate(deobfReference); |
| 266 | ClassEntry obfClassEntry = obfReference.getLocationClassEntry().getOutermostClassEntry(); | 265 | ClassEntry obfClassEntry = obfReference.getLocationClassEntry(); |
| 267 | if (!this.deobfuscator.isObfuscatedIdentifier(obfClassEntry)) { | 266 | if (!this.deobfuscator.isObfuscatedIdentifier(obfClassEntry)) { |
| 268 | throw new IllegalArgumentException("Obfuscated class " + obfClassEntry + " was not found in the jar!"); | 267 | throw new IllegalArgumentException("Obfuscated class " + obfClassEntry + " was not found in the jar!"); |
| 269 | } | 268 | } |
| @@ -276,24 +275,30 @@ public class GuiController { | |||
| 276 | } | 275 | } |
| 277 | } | 276 | } |
| 278 | 277 | ||
| 279 | private void showReference(EntryReference<Entry, Entry> obfReference) { | 278 | private void showReference(EntryReference<Entry<?>, Entry<?>> obfReference) { |
| 280 | EntryReference<Entry, Entry> deobfReference = this.deobfuscator.deobfuscateReference(obfReference); | 279 | EntryRemapper mapper = this.deobfuscator.getMapper(); |
| 281 | Collection<Token> tokens = this.index.getReferenceTokens(deobfReference); | 280 | |
| 281 | Collection<Token> tokens = mapper.getObfResolver().resolveReference(obfReference, ResolutionStrategy.RESOLVE_ROOT) | ||
| 282 | .stream() | ||
| 283 | .map(mapper::deobfuscate) | ||
| 284 | .flatMap(reference -> index.getReferenceTokens(reference).stream()) | ||
| 285 | .collect(Collectors.toList()); | ||
| 286 | |||
| 282 | if (tokens.isEmpty()) { | 287 | if (tokens.isEmpty()) { |
| 283 | // DEBUG | 288 | // DEBUG |
| 284 | System.err.println(String.format("WARNING: no tokens found for %s in %s", deobfReference, this.currentObfClass)); | 289 | System.err.println(String.format("WARNING: no tokens found for %s in %s", tokens, this.currentObfClass)); |
| 285 | } else { | 290 | } else { |
| 286 | this.gui.showTokens(tokens); | 291 | this.gui.showTokens(tokens); |
| 287 | } | 292 | } |
| 288 | } | 293 | } |
| 289 | 294 | ||
| 290 | public void savePreviousReference(EntryReference<Entry, Entry> deobfReference) { | 295 | public void savePreviousReference(EntryReference<Entry<?>, Entry<?>> deobfReference) { |
| 291 | this.referenceStack.push(this.deobfuscator.obfuscateReference(deobfReference)); | 296 | this.referenceStack.push(this.deobfuscator.getMapper().obfuscate(deobfReference)); |
| 292 | } | 297 | } |
| 293 | 298 | ||
| 294 | public void openPreviousReference() { | 299 | public void openPreviousReference() { |
| 295 | if (hasPreviousLocation()) { | 300 | if (hasPreviousLocation()) { |
| 296 | openReference(this.deobfuscator.deobfuscateReference(this.referenceStack.pop())); | 301 | openReference(this.deobfuscator.getMapper().deobfuscate(this.referenceStack.pop())); |
| 297 | } | 302 | } |
| 298 | } | 303 | } |
| 299 | 304 | ||
| @@ -313,13 +318,13 @@ public class GuiController { | |||
| 313 | refreshCurrentClass(null); | 318 | refreshCurrentClass(null); |
| 314 | } | 319 | } |
| 315 | 320 | ||
| 316 | private void refreshCurrentClass(EntryReference<Entry, Entry> obfReference) { | 321 | private void refreshCurrentClass(EntryReference<Entry<?>, Entry<?>> obfReference) { |
| 317 | if (this.currentObfClass != null) { | 322 | if (this.currentObfClass != null) { |
| 318 | deobfuscate(this.currentObfClass, obfReference); | 323 | deobfuscate(this.currentObfClass, obfReference); |
| 319 | } | 324 | } |
| 320 | } | 325 | } |
| 321 | 326 | ||
| 322 | private void deobfuscate(final ClassEntry classEntry, final EntryReference<Entry, Entry> obfReference) { | 327 | private void deobfuscate(final ClassEntry classEntry, final EntryReference<Entry<?>, Entry<?>> obfReference) { |
| 323 | 328 | ||
| 324 | this.gui.setSource("(deobfuscating...)"); | 329 | this.gui.setSource("(deobfuscating...)"); |
| 325 | 330 | ||
| @@ -327,7 +332,7 @@ public class GuiController { | |||
| 327 | new Thread(() -> | 332 | new Thread(() -> |
| 328 | { | 333 | { |
| 329 | // decompile,deobfuscate the bytecode | 334 | // decompile,deobfuscate the bytecode |
| 330 | CompilationUnit sourceTree = deobfuscator.getSourceTree(classEntry.getClassName()); | 335 | CompilationUnit sourceTree = deobfuscator.getSourceTree(classEntry.getFullName()); |
| 331 | if (sourceTree == null) { | 336 | if (sourceTree == null) { |
| 332 | // decompilation of this class is not supported | 337 | // decompilation of this class is not supported |
| 333 | gui.setSource("Unable to find class: " + classEntry); | 338 | gui.setSource("Unable to find class: " + classEntry); |
| @@ -349,17 +354,18 @@ public class GuiController { | |||
| 349 | boolean remapped = false; | 354 | boolean remapped = false; |
| 350 | 355 | ||
| 351 | for (Token inToken : index.referenceTokens()) { | 356 | for (Token inToken : index.referenceTokens()) { |
| 352 | EntryReference<Entry, Entry> reference = index.getDeobfReference(inToken); | ||
| 353 | Token token = inToken.move(offset); | 357 | Token token = inToken.move(offset); |
| 354 | 358 | ||
| 359 | EntryReference<Entry<?>, Entry<?>> reference = index.getDeobfReference(inToken); | ||
| 355 | if (referenceIsRenameable(reference)) { | 360 | if (referenceIsRenameable(reference)) { |
| 356 | boolean added = false; | 361 | boolean added = false; |
| 357 | 362 | ||
| 358 | if (!entryHasDeobfuscatedName(reference.getNameableEntry())) { | 363 | if (!entryHasDeobfuscatedName(reference.getNameableEntry())) { |
| 359 | Entry obfEntry = deobfuscator.obfuscateEntry(reference.getNameableEntry()); | 364 | Entry<?> obfEntry = deobfuscator.getMapper().obfuscate(reference.getNameableEntry()); |
| 360 | if (obfEntry instanceof FieldEntry) { | 365 | if (obfEntry instanceof FieldEntry) { |
| 361 | for (EnigmaPlugin plugin : deobfuscator.getPlugins()) { | 366 | for (EnigmaPlugin plugin : deobfuscator.getPlugins()) { |
| 362 | String proposal = plugin.proposeFieldName(obfEntry.getClassName(), obfEntry.getName(), ((FieldEntry) obfEntry).getDesc().toString()); | 367 | String owner = obfEntry.getContainingClass().getFullName(); |
| 368 | String proposal = plugin.proposeFieldName(owner, obfEntry.getName(), ((FieldEntry) obfEntry).getDesc().toString()); | ||
| 363 | if (proposal != null) { | 369 | if (proposal != null) { |
| 364 | proposedTokens.add(token); | 370 | proposedTokens.add(token); |
| 365 | offset += token.getRenameOffset(proposal); | 371 | offset += token.getRenameOffset(proposal); |
| @@ -411,8 +417,7 @@ public class GuiController { | |||
| 411 | 417 | ||
| 412 | public void modifierChange(ItemEvent event) { | 418 | public void modifierChange(ItemEvent event) { |
| 413 | if (event.getStateChange() == ItemEvent.SELECTED) { | 419 | if (event.getStateChange() == ItemEvent.SELECTED) { |
| 414 | deobfuscator.changeModifier(gui.reference.entry, (Mappings.EntryModifier) event.getItem()); | 420 | deobfuscator.changeModifier(gui.reference.entry, (AccessModifier) event.getItem()); |
| 415 | this.isDirty = true; | ||
| 416 | refreshCurrentClass(); | 421 | refreshCurrentClass(); |
| 417 | } | 422 | } |
| 418 | } | 423 | } |
diff --git a/src/main/java/cuchaz/enigma/gui/GuiTricks.java b/src/main/java/cuchaz/enigma/gui/GuiTricks.java deleted file mode 100644 index 9208455..0000000 --- a/src/main/java/cuchaz/enigma/gui/GuiTricks.java +++ /dev/null | |||
| @@ -1,42 +0,0 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Copyright (c) 2015 Jeff Martin. | ||
| 3 | * All rights reserved. This program and the accompanying materials | ||
| 4 | * are made available under the terms of the GNU Lesser General Public | ||
| 5 | * License v3.0 which accompanies this distribution, and is available at | ||
| 6 | * http://www.gnu.org/licenses/lgpl.html | ||
| 7 | * <p> | ||
| 8 | * Contributors: | ||
| 9 | * Jeff Martin - initial API and implementation | ||
| 10 | ******************************************************************************/ | ||
| 11 | |||
| 12 | package cuchaz.enigma.gui; | ||
| 13 | |||
| 14 | import javax.swing.*; | ||
| 15 | import java.awt.*; | ||
| 16 | import java.awt.event.ActionListener; | ||
| 17 | |||
| 18 | public class GuiTricks { | ||
| 19 | |||
| 20 | public static JLabel unboldLabel(JLabel label) { | ||
| 21 | Font font = label.getFont(); | ||
| 22 | label.setFont(font.deriveFont(font.getStyle() & ~Font.BOLD)); | ||
| 23 | return label; | ||
| 24 | } | ||
| 25 | |||
| 26 | public static void deactivateButton(JButton button) { | ||
| 27 | button.setEnabled(false); | ||
| 28 | button.setText(""); | ||
| 29 | for (ActionListener listener : button.getActionListeners()) { | ||
| 30 | button.removeActionListener(listener); | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | public static void activateButton(JButton button, String text, ActionListener newListener) { | ||
| 35 | button.setText(text); | ||
| 36 | button.setEnabled(true); | ||
| 37 | for (ActionListener listener : button.getActionListeners()) { | ||
| 38 | button.removeActionListener(listener); | ||
| 39 | } | ||
| 40 | button.addActionListener(newListener); | ||
| 41 | } | ||
| 42 | } | ||
diff --git a/src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java b/src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java deleted file mode 100644 index 34ec26e..0000000 --- a/src/main/java/cuchaz/enigma/gui/ScoredClassEntry.java +++ /dev/null | |||
| @@ -1,44 +0,0 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Copyright (c) 2015 Jeff Martin. | ||
| 3 | * All rights reserved. This program and the accompanying materials | ||
| 4 | * are made available under the terms of the GNU Lesser General Public | ||
| 5 | * License v3.0 which accompanies this distribution, and is available at | ||
| 6 | * http://www.gnu.org/licenses/lgpl.html | ||
| 7 | * <p> | ||
| 8 | * Contributors: | ||
| 9 | * Jeff Martin - initial API and implementation | ||
| 10 | ******************************************************************************/ | ||
| 11 | |||
| 12 | package cuchaz.enigma.gui; | ||
| 13 | |||
| 14 | import cuchaz.enigma.mapping.entry.ClassEntry; | ||
| 15 | |||
| 16 | public class ScoredClassEntry extends ClassEntry { | ||
| 17 | |||
| 18 | private static final long serialVersionUID = -8798725308554217105L; | ||
| 19 | |||
| 20 | private float score; | ||
| 21 | |||
| 22 | public ScoredClassEntry(ClassEntry other, float score) { | ||
| 23 | super(other); | ||
| 24 | this.score = score; | ||
| 25 | } | ||
| 26 | |||
| 27 | public float getScore() { | ||
| 28 | return score; | ||
| 29 | } | ||
| 30 | |||
| 31 | @Override | ||
| 32 | public int hashCode() { | ||
| 33 | return Float.hashCode(score) + super.hashCode(); | ||
| 34 | } | ||
| 35 | |||
| 36 | @Override | ||
| 37 | public boolean equals(Object other) { | ||
| 38 | return super.equals(other) && other instanceof ScoredClassEntry && equals((ScoredClassEntry) other); | ||
| 39 | } | ||
| 40 | |||
| 41 | public boolean equals(ScoredClassEntry other) { | ||
| 42 | return other != null && Float.compare(score, other.score) == 0; | ||
| 43 | } | ||
| 44 | } | ||
diff --git a/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java b/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java index 5f04833..84fe7c8 100644 --- a/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java +++ b/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | package cuchaz.enigma.gui.dialog; | 12 | package cuchaz.enigma.gui.dialog; |
| 13 | 13 | ||
| 14 | import cuchaz.enigma.Constants; | 14 | import cuchaz.enigma.Constants; |
| 15 | import cuchaz.enigma.Deobfuscator.ProgressListener; | 15 | import cuchaz.enigma.ProgressListener; |
| 16 | import cuchaz.enigma.utils.Utils; | 16 | import cuchaz.enigma.utils.Utils; |
| 17 | 17 | ||
| 18 | import javax.swing.*; | 18 | import javax.swing.*; |
| @@ -81,7 +81,7 @@ public class ProgressDialog implements ProgressListener, AutoCloseable { | |||
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | @Override | 83 | @Override |
| 84 | public void onProgress(int numDone, String message) { | 84 | public void step(int numDone, String message) { |
| 85 | this.labelText.setText(message); | 85 | this.labelText.setText(message); |
| 86 | this.progress.setValue(numDone); | 86 | this.progress.setValue(numDone); |
| 87 | 87 | ||
diff --git a/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java b/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java index 609aecb..f4f0277 100644 --- a/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java +++ b/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java | |||
| @@ -5,6 +5,7 @@ import cuchaz.enigma.config.Themes; | |||
| 5 | import cuchaz.enigma.gui.Gui; | 5 | import cuchaz.enigma.gui.Gui; |
| 6 | import cuchaz.enigma.gui.dialog.AboutDialog; | 6 | import cuchaz.enigma.gui.dialog.AboutDialog; |
| 7 | import cuchaz.enigma.throwables.MappingParseException; | 7 | import cuchaz.enigma.throwables.MappingParseException; |
| 8 | import cuchaz.enigma.translation.mapping.serde.MappingFormat; | ||
| 8 | 9 | ||
| 9 | import javax.swing.*; | 10 | import javax.swing.*; |
| 10 | import java.awt.event.InputEvent; | 11 | import java.awt.event.InputEvent; |
| @@ -23,7 +24,6 @@ public class MenuBar extends JMenuBar { | |||
| 23 | public final JMenuItem saveMappingEnigmaDirectoryMenu; | 24 | public final JMenuItem saveMappingEnigmaDirectoryMenu; |
| 24 | public final JMenuItem saveMappingsSrgMenu; | 25 | public final JMenuItem saveMappingsSrgMenu; |
| 25 | public final JMenuItem closeMappingsMenu; | 26 | public final JMenuItem closeMappingsMenu; |
| 26 | public final JMenuItem rebuildMethodNamesMenu; | ||
| 27 | public final JMenuItem exportSourceMenu; | 27 | public final JMenuItem exportSourceMenu; |
| 28 | public final JMenuItem exportJarMenu; | 28 | public final JMenuItem exportJarMenu; |
| 29 | private final Gui gui; | 29 | private final Gui gui; |
| @@ -68,7 +68,9 @@ public class MenuBar extends JMenuBar { | |||
| 68 | item.addActionListener(event -> { | 68 | item.addActionListener(event -> { |
| 69 | if (this.gui.enigmaMappingsFileChooser.showOpenDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { | 69 | if (this.gui.enigmaMappingsFileChooser.showOpenDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { |
| 70 | try { | 70 | try { |
| 71 | this.gui.getController().openEnigmaMappings(this.gui.enigmaMappingsFileChooser.getSelectedFile()); | 71 | File selectedFile = this.gui.enigmaMappingsFileChooser.getSelectedFile(); |
| 72 | MappingFormat format = selectedFile.isDirectory() ? MappingFormat.ENIGMA_DIRECTORY : MappingFormat.ENIGMA_FILE; | ||
| 73 | this.gui.getController().openMappings(format, selectedFile.toPath()); | ||
| 72 | } catch (IOException ex) { | 74 | } catch (IOException ex) { |
| 73 | throw new Error(ex); | 75 | throw new Error(ex); |
| 74 | } catch (MappingParseException ex) { | 76 | } catch (MappingParseException ex) { |
| @@ -85,7 +87,7 @@ public class MenuBar extends JMenuBar { | |||
| 85 | File file = new File(this.gui.tinyMappingsFileChooser.getDirectory() + File.separator + this.gui.tinyMappingsFileChooser.getFile()); | 87 | File file = new File(this.gui.tinyMappingsFileChooser.getDirectory() + File.separator + this.gui.tinyMappingsFileChooser.getFile()); |
| 86 | if (file.exists()) { | 88 | if (file.exists()) { |
| 87 | try { | 89 | try { |
| 88 | this.gui.getController().openTinyMappings(file); | 90 | this.gui.getController().openMappings(MappingFormat.TINY_FILE, file.toPath()); |
| 89 | } catch (IOException ex) { | 91 | } catch (IOException ex) { |
| 90 | throw new Error(ex); | 92 | throw new Error(ex); |
| 91 | } catch (MappingParseException ex) { | 93 | } catch (MappingParseException ex) { |
| @@ -99,11 +101,7 @@ public class MenuBar extends JMenuBar { | |||
| 99 | JMenuItem item = new JMenuItem("Save Mappings"); | 101 | JMenuItem item = new JMenuItem("Save Mappings"); |
| 100 | menu.add(item); | 102 | menu.add(item); |
| 101 | item.addActionListener(event -> { | 103 | item.addActionListener(event -> { |
| 102 | try { | 104 | this.gui.getController().saveMappings(this.gui.enigmaMappingsFileChooser.getSelectedFile().toPath()); |
| 103 | this.gui.getController().saveMappings(this.gui.enigmaMappingsFileChooser.getSelectedFile()); | ||
| 104 | } catch (IOException ex) { | ||
| 105 | throw new Error(ex); | ||
| 106 | } | ||
| 107 | }); | 105 | }); |
| 108 | item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK)); | 106 | item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK)); |
| 109 | this.saveMappingsMenu = item; | 107 | this.saveMappingsMenu = item; |
| @@ -116,12 +114,8 @@ public class MenuBar extends JMenuBar { | |||
| 116 | item.addActionListener(event -> { | 114 | item.addActionListener(event -> { |
| 117 | // TODO: Use a specific file chooser for it | 115 | // TODO: Use a specific file chooser for it |
| 118 | if (this.gui.enigmaMappingsFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { | 116 | if (this.gui.enigmaMappingsFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { |
| 119 | try { | 117 | this.gui.getController().saveMappings(MappingFormat.ENIGMA_FILE, this.gui.enigmaMappingsFileChooser.getSelectedFile().toPath()); |
| 120 | this.gui.getController().saveEnigmaMappings(this.gui.enigmaMappingsFileChooser.getSelectedFile(), false); | 118 | this.saveMappingsMenu.setEnabled(true); |
| 121 | this.saveMappingsMenu.setEnabled(true); | ||
| 122 | } catch (IOException ex) { | ||
| 123 | throw new Error(ex); | ||
| 124 | } | ||
| 125 | } | 119 | } |
| 126 | }); | 120 | }); |
| 127 | this.saveMappingEnigmaFileMenu = item; | 121 | this.saveMappingEnigmaFileMenu = item; |
| @@ -132,12 +126,8 @@ public class MenuBar extends JMenuBar { | |||
| 132 | item.addActionListener(event -> { | 126 | item.addActionListener(event -> { |
| 133 | // TODO: Use a specific file chooser for it | 127 | // TODO: Use a specific file chooser for it |
| 134 | if (this.gui.enigmaMappingsFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { | 128 | if (this.gui.enigmaMappingsFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { |
| 135 | try { | 129 | this.gui.getController().saveMappings(MappingFormat.ENIGMA_DIRECTORY, this.gui.enigmaMappingsFileChooser.getSelectedFile().toPath()); |
| 136 | this.gui.getController().saveEnigmaMappings(this.gui.enigmaMappingsFileChooser.getSelectedFile(), true); | 130 | this.saveMappingsMenu.setEnabled(true); |
| 137 | this.saveMappingsMenu.setEnabled(true); | ||
| 138 | } catch (IOException ex) { | ||
| 139 | throw new Error(ex); | ||
| 140 | } | ||
| 141 | } | 131 | } |
| 142 | }); | 132 | }); |
| 143 | item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK)); | 133 | item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK)); |
| @@ -149,12 +139,8 @@ public class MenuBar extends JMenuBar { | |||
| 149 | item.addActionListener(event -> { | 139 | item.addActionListener(event -> { |
| 150 | // TODO: Use a specific file chooser for it | 140 | // TODO: Use a specific file chooser for it |
| 151 | if (this.gui.enigmaMappingsFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { | 141 | if (this.gui.enigmaMappingsFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { |
| 152 | try { | 142 | this.gui.getController().saveMappings(MappingFormat.SRG_FILE, this.gui.enigmaMappingsFileChooser.getSelectedFile().toPath()); |
| 153 | this.gui.getController().saveSRGMappings(this.gui.enigmaMappingsFileChooser.getSelectedFile()); | 143 | this.saveMappingsMenu.setEnabled(true); |
| 154 | this.saveMappingsMenu.setEnabled(true); | ||
| 155 | } catch (IOException ex) { | ||
| 156 | throw new Error(ex); | ||
| 157 | } | ||
| 158 | } | 144 | } |
| 159 | }); | 145 | }); |
| 160 | this.saveMappingsSrgMenu = item; | 146 | this.saveMappingsSrgMenu = item; |
| @@ -184,13 +170,6 @@ public class MenuBar extends JMenuBar { | |||
| 184 | } | 170 | } |
| 185 | menu.addSeparator(); | 171 | menu.addSeparator(); |
| 186 | { | 172 | { |
| 187 | JMenuItem item = new JMenuItem("Rebuild Method Names"); | ||
| 188 | menu.add(item); | ||
| 189 | item.addActionListener(event -> this.gui.getController().rebuildMethodNames()); | ||
| 190 | this.rebuildMethodNamesMenu = item; | ||
| 191 | } | ||
| 192 | menu.addSeparator(); | ||
| 193 | { | ||
| 194 | JMenuItem item = new JMenuItem("Export Source..."); | 173 | JMenuItem item = new JMenuItem("Export Source..."); |
| 195 | menu.add(item); | 174 | menu.add(item); |
| 196 | item.addActionListener(event -> { | 175 | item.addActionListener(event -> { |
diff --git a/src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java b/src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java index a965a8f..bf6b178 100644 --- a/src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java +++ b/src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui.node; | 12 | package cuchaz.enigma.gui.node; |
| 13 | 13 | ||
| 14 | import cuchaz.enigma.mapping.entry.ClassEntry; | 14 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| 15 | 15 | ||
| 16 | import javax.swing.tree.DefaultMutableTreeNode; | 16 | import javax.swing.tree.DefaultMutableTreeNode; |
| 17 | 17 | ||
diff --git a/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java b/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java index 9eb8f8f..ccdc9f8 100644 --- a/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java +++ b/src/main/java/cuchaz/enigma/gui/panels/PanelObf.java | |||
| @@ -2,7 +2,7 @@ package cuchaz.enigma.gui.panels; | |||
| 2 | 2 | ||
| 3 | import cuchaz.enigma.gui.ClassSelector; | 3 | import cuchaz.enigma.gui.ClassSelector; |
| 4 | import cuchaz.enigma.gui.Gui; | 4 | import cuchaz.enigma.gui.Gui; |
| 5 | import cuchaz.enigma.mapping.entry.ClassEntry; | 5 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| 6 | 6 | ||
| 7 | import javax.swing.*; | 7 | import javax.swing.*; |
| 8 | import java.awt.*; | 8 | import java.awt.*; |
| @@ -17,8 +17,8 @@ public class PanelObf extends JPanel { | |||
| 17 | this.gui = gui; | 17 | this.gui = gui; |
| 18 | 18 | ||
| 19 | Comparator<ClassEntry> obfClassComparator = (a, b) -> { | 19 | Comparator<ClassEntry> obfClassComparator = (a, b) -> { |
| 20 | String aname = a.getName(); | 20 | String aname = a.getFullName(); |
| 21 | String bname = b.getName(); | 21 | String bname = b.getFullName(); |
| 22 | if (aname.length() != bname.length()) { | 22 | if (aname.length() != bname.length()) { |
| 23 | return aname.length() - bname.length(); | 23 | return aname.length() - bname.length(); |
| 24 | } | 24 | } |