diff options
| author | 2014-08-20 01:21:52 -0400 | |
|---|---|---|
| committer | 2014-08-20 01:21:52 -0400 | |
| commit | a85529d1ce6ec533809575ec84572de855464b36 (patch) | |
| tree | 8f1894c272edf0e7eb22aec2f3af41f6bd19c092 /src/cuchaz/enigma/gui | |
| parent | started new reference navigation system (diff) | |
| download | enigma-fork-a85529d1ce6ec533809575ec84572de855464b36.tar.gz enigma-fork-a85529d1ce6ec533809575ec84572de855464b36.tar.xz enigma-fork-a85529d1ce6ec533809575ec84572de855464b36.zip | |
finished reference navigation system. Still need to debug and polish it, but the basic idea seems to work. =)
Diffstat (limited to 'src/cuchaz/enigma/gui')
| -rw-r--r-- | src/cuchaz/enigma/gui/Gui.java | 158 | ||||
| -rw-r--r-- | src/cuchaz/enigma/gui/GuiController.java | 106 |
2 files changed, 147 insertions, 117 deletions
diff --git a/src/cuchaz/enigma/gui/Gui.java b/src/cuchaz/enigma/gui/Gui.java index 43a0cda..341c149 100644 --- a/src/cuchaz/enigma/gui/Gui.java +++ b/src/cuchaz/enigma/gui/Gui.java | |||
| @@ -68,6 +68,7 @@ import com.google.common.collect.Lists; | |||
| 68 | import cuchaz.enigma.Constants; | 68 | import cuchaz.enigma.Constants; |
| 69 | import cuchaz.enigma.analysis.BehaviorReferenceTreeNode; | 69 | import cuchaz.enigma.analysis.BehaviorReferenceTreeNode; |
| 70 | import cuchaz.enigma.analysis.ClassInheritanceTreeNode; | 70 | import cuchaz.enigma.analysis.ClassInheritanceTreeNode; |
| 71 | import cuchaz.enigma.analysis.EntryReference; | ||
| 71 | import cuchaz.enigma.analysis.FieldReferenceTreeNode; | 72 | import cuchaz.enigma.analysis.FieldReferenceTreeNode; |
| 72 | import cuchaz.enigma.analysis.MethodInheritanceTreeNode; | 73 | import cuchaz.enigma.analysis.MethodInheritanceTreeNode; |
| 73 | import cuchaz.enigma.analysis.ReferenceTreeNode; | 74 | import cuchaz.enigma.analysis.ReferenceTreeNode; |
| @@ -76,7 +77,6 @@ import cuchaz.enigma.mapping.ArgumentEntry; | |||
| 76 | import cuchaz.enigma.mapping.ClassEntry; | 77 | import cuchaz.enigma.mapping.ClassEntry; |
| 77 | import cuchaz.enigma.mapping.ConstructorEntry; | 78 | import cuchaz.enigma.mapping.ConstructorEntry; |
| 78 | import cuchaz.enigma.mapping.Entry; | 79 | import cuchaz.enigma.mapping.Entry; |
| 79 | import cuchaz.enigma.mapping.EntryPair; | ||
| 80 | import cuchaz.enigma.mapping.FieldEntry; | 80 | import cuchaz.enigma.mapping.FieldEntry; |
| 81 | import cuchaz.enigma.mapping.IllegalNameException; | 81 | import cuchaz.enigma.mapping.IllegalNameException; |
| 82 | import cuchaz.enigma.mapping.MappingParseException; | 82 | import cuchaz.enigma.mapping.MappingParseException; |
| @@ -160,7 +160,7 @@ public class Gui | |||
| 160 | private JMenuItem m_showCallsMenu; | 160 | private JMenuItem m_showCallsMenu; |
| 161 | 161 | ||
| 162 | // state | 162 | // state |
| 163 | private EntryPair<? extends Entry> m_selectedEntryPair; | 163 | private EntryReference<Entry,Entry> m_reference; |
| 164 | private JFileChooser m_jarFileChooser; | 164 | private JFileChooser m_jarFileChooser; |
| 165 | private JFileChooser m_mappingsFileChooser; | 165 | private JFileChooser m_mappingsFileChooser; |
| 166 | 166 | ||
| @@ -192,6 +192,10 @@ public class Gui | |||
| 192 | String selected = m_obfClasses.getSelectedValue(); | 192 | String selected = m_obfClasses.getSelectedValue(); |
| 193 | if( selected != null ) | 193 | if( selected != null ) |
| 194 | { | 194 | { |
| 195 | if( m_reference != null ) | ||
| 196 | { | ||
| 197 | m_controller.savePreviousReference( m_reference ); | ||
| 198 | } | ||
| 195 | m_controller.openDeclaration( new ClassEntry( selected ) ); | 199 | m_controller.openDeclaration( new ClassEntry( selected ) ); |
| 196 | } | 200 | } |
| 197 | } | 201 | } |
| @@ -218,6 +222,10 @@ public class Gui | |||
| 218 | String selected = m_deobfClasses.getSelectedValue(); | 222 | String selected = m_deobfClasses.getSelectedValue(); |
| 219 | if( selected != null ) | 223 | if( selected != null ) |
| 220 | { | 224 | { |
| 225 | if( m_reference != null ) | ||
| 226 | { | ||
| 227 | m_controller.savePreviousReference( m_reference ); | ||
| 228 | } | ||
| 221 | m_controller.openDeclaration( new ClassEntry( selected ) ); | 229 | m_controller.openDeclaration( new ClassEntry( selected ) ); |
| 222 | } | 230 | } |
| 223 | } | 231 | } |
| @@ -234,7 +242,7 @@ public class Gui | |||
| 234 | m_infoPanel.setLayout( new GridLayout( 4, 1, 0, 0 ) ); | 242 | m_infoPanel.setLayout( new GridLayout( 4, 1, 0, 0 ) ); |
| 235 | m_infoPanel.setPreferredSize( new Dimension( 0, 100 ) ); | 243 | m_infoPanel.setPreferredSize( new Dimension( 0, 100 ) ); |
| 236 | m_infoPanel.setBorder( BorderFactory.createTitledBorder( "Identifier Info" ) ); | 244 | m_infoPanel.setBorder( BorderFactory.createTitledBorder( "Identifier Info" ) ); |
| 237 | clearEntryPair(); | 245 | clearReference(); |
| 238 | 246 | ||
| 239 | // init editor | 247 | // init editor |
| 240 | DefaultSyntaxKit.initKit(); | 248 | DefaultSyntaxKit.initKit(); |
| @@ -273,7 +281,7 @@ public class Gui | |||
| 273 | break; | 281 | break; |
| 274 | 282 | ||
| 275 | case KeyEvent.VK_P: | 283 | case KeyEvent.VK_P: |
| 276 | m_controller.openPreviousLocation(); | 284 | m_controller.openPreviousReference(); |
| 277 | break; | 285 | break; |
| 278 | 286 | ||
| 279 | case KeyEvent.VK_C: | 287 | case KeyEvent.VK_C: |
| @@ -357,7 +365,7 @@ public class Gui | |||
| 357 | @Override | 365 | @Override |
| 358 | public void actionPerformed( ActionEvent event ) | 366 | public void actionPerformed( ActionEvent event ) |
| 359 | { | 367 | { |
| 360 | m_controller.openPreviousLocation(); | 368 | m_controller.openPreviousReference(); |
| 361 | } | 369 | } |
| 362 | } ); | 370 | } ); |
| 363 | menu.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_P, 0 ) ); | 371 | menu.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_P, 0 ) ); |
| @@ -386,6 +394,10 @@ public class Gui | |||
| 386 | Object node = path.getLastPathComponent(); | 394 | Object node = path.getLastPathComponent(); |
| 387 | if( node instanceof ClassInheritanceTreeNode ) | 395 | if( node instanceof ClassInheritanceTreeNode ) |
| 388 | { | 396 | { |
| 397 | if( m_reference != null ) | ||
| 398 | { | ||
| 399 | m_controller.savePreviousReference( m_reference ); | ||
| 400 | } | ||
| 389 | m_controller.openDeclaration( new ClassEntry( ((ClassInheritanceTreeNode)node).getObfClassName() ) ); | 401 | m_controller.openDeclaration( new ClassEntry( ((ClassInheritanceTreeNode)node).getObfClassName() ) ); |
| 390 | } | 402 | } |
| 391 | else if( node instanceof MethodInheritanceTreeNode ) | 403 | else if( node instanceof MethodInheritanceTreeNode ) |
| @@ -393,6 +405,10 @@ public class Gui | |||
| 393 | MethodInheritanceTreeNode methodNode = (MethodInheritanceTreeNode)node; | 405 | MethodInheritanceTreeNode methodNode = (MethodInheritanceTreeNode)node; |
| 394 | if( methodNode.isImplemented() ) | 406 | if( methodNode.isImplemented() ) |
| 395 | { | 407 | { |
| 408 | if( m_reference != null ) | ||
| 409 | { | ||
| 410 | m_controller.savePreviousReference( m_reference ); | ||
| 411 | } | ||
| 396 | m_controller.openDeclaration( methodNode.getMethodEntry() ); | 412 | m_controller.openDeclaration( methodNode.getMethodEntry() ); |
| 397 | } | 413 | } |
| 398 | } | 414 | } |
| @@ -424,7 +440,11 @@ public class Gui | |||
| 424 | Object node = path.getLastPathComponent(); | 440 | Object node = path.getLastPathComponent(); |
| 425 | if( node instanceof ReferenceTreeNode ) | 441 | if( node instanceof ReferenceTreeNode ) |
| 426 | { | 442 | { |
| 427 | ReferenceTreeNode<Entry> referenceNode = ((ReferenceTreeNode<Entry>)node); | 443 | if( m_reference != null ) |
| 444 | { | ||
| 445 | m_controller.savePreviousReference( m_reference ); | ||
| 446 | } | ||
| 447 | ReferenceTreeNode<Entry,Entry> referenceNode = ((ReferenceTreeNode<Entry,Entry>)node); | ||
| 428 | if( referenceNode.getReference() != null ) | 448 | if( referenceNode.getReference() != null ) |
| 429 | { | 449 | { |
| 430 | m_controller.openReference( referenceNode.getReference() ); | 450 | m_controller.openReference( referenceNode.getReference() ); |
| @@ -715,6 +735,10 @@ public class Gui | |||
| 715 | 735 | ||
| 716 | public void showToken( Token token ) | 736 | public void showToken( Token token ) |
| 717 | { | 737 | { |
| 738 | if( token == null ) | ||
| 739 | { | ||
| 740 | throw new IllegalArgumentException( "Token cannot be null!" ); | ||
| 741 | } | ||
| 718 | m_editor.setCaretPosition( token.start ); | 742 | m_editor.setCaretPosition( token.start ); |
| 719 | m_editor.grabFocus(); | 743 | m_editor.grabFocus(); |
| 720 | } | 744 | } |
| @@ -752,7 +776,7 @@ public class Gui | |||
| 752 | } | 776 | } |
| 753 | } | 777 | } |
| 754 | 778 | ||
| 755 | private void clearEntryPair( ) | 779 | private void clearReference( ) |
| 756 | { | 780 | { |
| 757 | m_infoPanel.removeAll(); | 781 | m_infoPanel.removeAll(); |
| 758 | JLabel label = new JLabel( "No identifier selected" ); | 782 | JLabel label = new JLabel( "No identifier selected" ); |
| @@ -763,76 +787,75 @@ public class Gui | |||
| 763 | redraw(); | 787 | redraw(); |
| 764 | } | 788 | } |
| 765 | 789 | ||
| 766 | @SuppressWarnings( "unchecked" ) | 790 | private void showReference( EntryReference<Entry,Entry> reference ) |
| 767 | private void showEntryPair( EntryPair<? extends Entry> pair ) | ||
| 768 | { | 791 | { |
| 769 | if( pair == null ) | 792 | if( reference == null ) |
| 770 | { | 793 | { |
| 771 | clearEntryPair(); | 794 | clearReference(); |
| 772 | return; | 795 | return; |
| 773 | } | 796 | } |
| 774 | 797 | ||
| 775 | m_selectedEntryPair = pair; | 798 | m_reference = reference; |
| 776 | 799 | ||
| 777 | m_infoPanel.removeAll(); | 800 | m_infoPanel.removeAll(); |
| 778 | if( pair.deobf instanceof ClassEntry ) | 801 | if( reference.entry instanceof ClassEntry ) |
| 779 | { | 802 | { |
| 780 | showClassEntryPair( (EntryPair<ClassEntry>)pair ); | 803 | showClassEntry( (ClassEntry)m_reference.entry ); |
| 781 | } | 804 | } |
| 782 | else if( pair.deobf instanceof FieldEntry ) | 805 | else if( m_reference.entry instanceof FieldEntry ) |
| 783 | { | 806 | { |
| 784 | showFieldEntryPair( (EntryPair<FieldEntry>)pair ); | 807 | showFieldEntry( (FieldEntry)m_reference.entry ); |
| 785 | } | 808 | } |
| 786 | else if( pair.deobf instanceof MethodEntry ) | 809 | else if( m_reference.entry instanceof MethodEntry ) |
| 787 | { | 810 | { |
| 788 | showMethodEntryPair( (EntryPair<MethodEntry>)pair ); | 811 | showMethodEntry( (MethodEntry)m_reference.entry ); |
| 789 | } | 812 | } |
| 790 | else if( pair.deobf instanceof ConstructorEntry ) | 813 | else if( m_reference.entry instanceof ConstructorEntry ) |
| 791 | { | 814 | { |
| 792 | showConstructorEntryPair( (EntryPair<ConstructorEntry>)pair ); | 815 | showConstructorEntry( (ConstructorEntry)m_reference.entry ); |
| 793 | } | 816 | } |
| 794 | else if( pair.deobf instanceof ArgumentEntry ) | 817 | else if( m_reference.entry instanceof ArgumentEntry ) |
| 795 | { | 818 | { |
| 796 | showArgumentEntryPair( (EntryPair<ArgumentEntry>)pair ); | 819 | showArgumentEntry( (ArgumentEntry)m_reference.entry ); |
| 797 | } | 820 | } |
| 798 | else | 821 | else |
| 799 | { | 822 | { |
| 800 | throw new Error( "Unknown entry type: " + pair.deobf.getClass().getName() ); | 823 | throw new Error( "Unknown entry type: " + m_reference.entry.getClass().getName() ); |
| 801 | } | 824 | } |
| 802 | 825 | ||
| 803 | redraw(); | 826 | redraw(); |
| 804 | } | 827 | } |
| 805 | 828 | ||
| 806 | private void showClassEntryPair( EntryPair<ClassEntry> pair ) | 829 | private void showClassEntry( ClassEntry entry ) |
| 807 | { | 830 | { |
| 808 | addNameValue( m_infoPanel, "Class", pair.deobf.getName() ); | 831 | addNameValue( m_infoPanel, "Class", entry.getName() ); |
| 809 | } | 832 | } |
| 810 | 833 | ||
| 811 | private void showFieldEntryPair( EntryPair<FieldEntry> pair ) | 834 | private void showFieldEntry( FieldEntry entry ) |
| 812 | { | 835 | { |
| 813 | addNameValue( m_infoPanel, "Field", pair.deobf.getName() ); | 836 | addNameValue( m_infoPanel, "Field", entry.getName() ); |
| 814 | addNameValue( m_infoPanel, "Class", pair.deobf.getClassEntry().getName() ); | 837 | addNameValue( m_infoPanel, "Class", entry.getClassEntry().getName() ); |
| 815 | } | 838 | } |
| 816 | 839 | ||
| 817 | private void showMethodEntryPair( EntryPair<MethodEntry> pair ) | 840 | private void showMethodEntry( MethodEntry entry ) |
| 818 | { | 841 | { |
| 819 | addNameValue( m_infoPanel, "Method", pair.deobf.getName() ); | 842 | addNameValue( m_infoPanel, "Method", entry.getName() ); |
| 820 | addNameValue( m_infoPanel, "Class", pair.deobf.getClassEntry().getName() ); | 843 | addNameValue( m_infoPanel, "Class", entry.getClassEntry().getName() ); |
| 821 | addNameValue( m_infoPanel, "Signature", pair.deobf.getSignature() ); | 844 | addNameValue( m_infoPanel, "Signature", entry.getSignature() ); |
| 822 | } | 845 | } |
| 823 | 846 | ||
| 824 | private void showConstructorEntryPair( EntryPair<ConstructorEntry> pair ) | 847 | private void showConstructorEntry( ConstructorEntry entry ) |
| 825 | { | 848 | { |
| 826 | addNameValue( m_infoPanel, "Constructor", pair.deobf.getClassEntry().getName() ); | 849 | addNameValue( m_infoPanel, "Constructor", entry.getClassEntry().getName() ); |
| 827 | addNameValue( m_infoPanel, "Signature", pair.deobf.getSignature() ); | 850 | addNameValue( m_infoPanel, "Signature", entry.getSignature() ); |
| 828 | } | 851 | } |
| 829 | 852 | ||
| 830 | private void showArgumentEntryPair( EntryPair<ArgumentEntry> pair ) | 853 | private void showArgumentEntry( ArgumentEntry entry ) |
| 831 | { | 854 | { |
| 832 | addNameValue( m_infoPanel, "Argument", pair.deobf.getName() ); | 855 | addNameValue( m_infoPanel, "Argument", entry.getName() ); |
| 833 | addNameValue( m_infoPanel, "Class", pair.deobf.getClassEntry().getName() ); | 856 | addNameValue( m_infoPanel, "Class", entry.getClassEntry().getName() ); |
| 834 | addNameValue( m_infoPanel, "Method", pair.deobf.getMethodEntry().getName() ); | 857 | addNameValue( m_infoPanel, "Method", entry.getMethodEntry().getName() ); |
| 835 | addNameValue( m_infoPanel, "Index", Integer.toString( pair.deobf.getIndex() ) ); | 858 | addNameValue( m_infoPanel, "Index", Integer.toString( entry.getIndex() ) ); |
| 836 | } | 859 | } |
| 837 | 860 | ||
| 838 | private void addNameValue( JPanel container, String name, String value ) | 861 | private void addNameValue( JPanel container, String name, String value ) |
| @@ -853,19 +876,19 @@ public class Gui | |||
| 853 | Token token = m_controller.getToken( pos ); | 876 | Token token = m_controller.getToken( pos ); |
| 854 | boolean isToken = token != null; | 877 | boolean isToken = token != null; |
| 855 | 878 | ||
| 856 | m_selectedEntryPair = m_controller.getEntryPair( token ); | 879 | m_reference = m_controller.getDeobfReference( token ); |
| 857 | boolean isClassEntry = isToken && m_selectedEntryPair.obf instanceof ClassEntry; | 880 | boolean isClassEntry = isToken && m_reference.entry instanceof ClassEntry; |
| 858 | boolean isFieldEntry = isToken && m_selectedEntryPair.obf instanceof FieldEntry; | 881 | boolean isFieldEntry = isToken && m_reference.entry instanceof FieldEntry; |
| 859 | boolean isMethodEntry = isToken && m_selectedEntryPair.obf instanceof MethodEntry; | 882 | boolean isMethodEntry = isToken && m_reference.entry instanceof MethodEntry; |
| 860 | boolean isConstructorEntry = isToken && m_selectedEntryPair.obf instanceof ConstructorEntry; | 883 | boolean isConstructorEntry = isToken && m_reference.entry instanceof ConstructorEntry; |
| 861 | 884 | ||
| 862 | if( isToken ) | 885 | if( isToken ) |
| 863 | { | 886 | { |
| 864 | showEntryPair( m_selectedEntryPair ); | 887 | showReference( m_reference ); |
| 865 | } | 888 | } |
| 866 | else | 889 | else |
| 867 | { | 890 | { |
| 868 | clearEntryPair(); | 891 | clearReference(); |
| 869 | } | 892 | } |
| 870 | 893 | ||
| 871 | m_renameMenu.setEnabled( isToken ); | 894 | m_renameMenu.setEnabled( isToken ); |
| @@ -878,11 +901,11 @@ public class Gui | |||
| 878 | private void startRename( ) | 901 | private void startRename( ) |
| 879 | { | 902 | { |
| 880 | // get the class name | 903 | // get the class name |
| 881 | String className = m_selectedEntryPair.deobf.getName(); | 904 | ClassEntry classEntry = m_reference.entry.getClassEntry(); |
| 882 | int pos = className.lastIndexOf( '$' ); | 905 | String className = classEntry.getName(); |
| 883 | if( pos >= 0 ) | 906 | if( classEntry.isInnerClass() ) |
| 884 | { | 907 | { |
| 885 | className = className.substring( pos + 1 ); | 908 | className = classEntry.getInnerClassName(); |
| 886 | } | 909 | } |
| 887 | 910 | ||
| 888 | // init the text box | 911 | // init the text box |
| @@ -924,7 +947,7 @@ public class Gui | |||
| 924 | { | 947 | { |
| 925 | try | 948 | try |
| 926 | { | 949 | { |
| 927 | m_controller.rename( m_selectedEntryPair.obf, newName ); | 950 | m_controller.rename( m_reference, newName ); |
| 928 | } | 951 | } |
| 929 | catch( IllegalNameException ex ) | 952 | catch( IllegalNameException ex ) |
| 930 | { | 953 | { |
| @@ -937,7 +960,7 @@ public class Gui | |||
| 937 | // abort the rename | 960 | // abort the rename |
| 938 | JPanel panel = (JPanel)m_infoPanel.getComponent( 0 ); | 961 | JPanel panel = (JPanel)m_infoPanel.getComponent( 0 ); |
| 939 | panel.remove( panel.getComponentCount() - 1 ); | 962 | panel.remove( panel.getComponentCount() - 1 ); |
| 940 | panel.add( unboldLabel( new JLabel( m_selectedEntryPair.deobf.getName(), JLabel.LEFT ) ) ); | 963 | panel.add( unboldLabel( new JLabel( m_reference.entry.getName(), JLabel.LEFT ) ) ); |
| 941 | 964 | ||
| 942 | m_editor.grabFocus(); | 965 | m_editor.grabFocus(); |
| 943 | 966 | ||
| @@ -946,15 +969,15 @@ public class Gui | |||
| 946 | 969 | ||
| 947 | private void showInheritance( ) | 970 | private void showInheritance( ) |
| 948 | { | 971 | { |
| 949 | if( m_selectedEntryPair == null ) | 972 | if( m_reference == null ) |
| 950 | { | 973 | { |
| 951 | return; | 974 | return; |
| 952 | } | 975 | } |
| 953 | 976 | ||
| 954 | if( m_selectedEntryPair.obf instanceof ClassEntry ) | 977 | if( m_reference.entry instanceof ClassEntry ) |
| 955 | { | 978 | { |
| 956 | // get the class inheritance | 979 | // get the class inheritance |
| 957 | ClassInheritanceTreeNode classNode = m_controller.getClassInheritance( (ClassEntry)m_selectedEntryPair.obf ); | 980 | ClassInheritanceTreeNode classNode = m_controller.getClassInheritance( (ClassEntry)m_reference.entry ); |
| 958 | 981 | ||
| 959 | // show the tree at the root | 982 | // show the tree at the root |
| 960 | TreePath path = getPathToRoot( classNode ); | 983 | TreePath path = getPathToRoot( classNode ); |
| @@ -962,10 +985,10 @@ public class Gui | |||
| 962 | m_inheritanceTree.expandPath( path ); | 985 | m_inheritanceTree.expandPath( path ); |
| 963 | m_inheritanceTree.setSelectionRow( m_inheritanceTree.getRowForPath( path ) ); | 986 | m_inheritanceTree.setSelectionRow( m_inheritanceTree.getRowForPath( path ) ); |
| 964 | } | 987 | } |
| 965 | else if( m_selectedEntryPair.obf instanceof MethodEntry ) | 988 | else if( m_reference.entry instanceof MethodEntry ) |
| 966 | { | 989 | { |
| 967 | // get the method inheritance | 990 | // get the method inheritance |
| 968 | MethodInheritanceTreeNode classNode = m_controller.getMethodInheritance( (MethodEntry)m_selectedEntryPair.obf ); | 991 | MethodInheritanceTreeNode classNode = m_controller.getMethodInheritance( (MethodEntry)m_reference.entry ); |
| 969 | 992 | ||
| 970 | // show the tree at the root | 993 | // show the tree at the root |
| 971 | TreePath path = getPathToRoot( classNode ); | 994 | TreePath path = getPathToRoot( classNode ); |
| @@ -980,24 +1003,24 @@ public class Gui | |||
| 980 | 1003 | ||
| 981 | private void showCalls( ) | 1004 | private void showCalls( ) |
| 982 | { | 1005 | { |
| 983 | if( m_selectedEntryPair == null ) | 1006 | if( m_reference == null ) |
| 984 | { | 1007 | { |
| 985 | return; | 1008 | return; |
| 986 | } | 1009 | } |
| 987 | 1010 | ||
| 988 | if( m_selectedEntryPair.obf instanceof FieldEntry ) | 1011 | if( m_reference.entry instanceof FieldEntry ) |
| 989 | { | 1012 | { |
| 990 | FieldReferenceTreeNode node = m_controller.getFieldReferences( (FieldEntry)m_selectedEntryPair.obf ); | 1013 | FieldReferenceTreeNode node = m_controller.getFieldReferences( (FieldEntry)m_reference.entry ); |
| 991 | m_callsTree.setModel( new DefaultTreeModel( node ) ); | 1014 | m_callsTree.setModel( new DefaultTreeModel( node ) ); |
| 992 | } | 1015 | } |
| 993 | else if( m_selectedEntryPair.obf instanceof MethodEntry ) | 1016 | else if( m_reference.entry instanceof MethodEntry ) |
| 994 | { | 1017 | { |
| 995 | BehaviorReferenceTreeNode node = m_controller.getMethodReferences( (MethodEntry)m_selectedEntryPair.obf ); | 1018 | BehaviorReferenceTreeNode node = m_controller.getMethodReferences( (MethodEntry)m_reference.entry ); |
| 996 | m_callsTree.setModel( new DefaultTreeModel( node ) ); | 1019 | m_callsTree.setModel( new DefaultTreeModel( node ) ); |
| 997 | } | 1020 | } |
| 998 | else if( m_selectedEntryPair.obf instanceof ConstructorEntry ) | 1021 | else if( m_reference.entry instanceof ConstructorEntry ) |
| 999 | { | 1022 | { |
| 1000 | BehaviorReferenceTreeNode node = m_controller.getMethodReferences( (ConstructorEntry)m_selectedEntryPair.obf ); | 1023 | BehaviorReferenceTreeNode node = m_controller.getMethodReferences( (ConstructorEntry)m_reference.entry ); |
| 1001 | m_callsTree.setModel( new DefaultTreeModel( node ) ); | 1024 | m_callsTree.setModel( new DefaultTreeModel( node ) ); |
| 1002 | } | 1025 | } |
| 1003 | 1026 | ||
| @@ -1021,11 +1044,12 @@ public class Gui | |||
| 1021 | 1044 | ||
| 1022 | private void openDeclaration( ) | 1045 | private void openDeclaration( ) |
| 1023 | { | 1046 | { |
| 1024 | if( m_selectedEntryPair == null ) | 1047 | if( m_reference == null ) |
| 1025 | { | 1048 | { |
| 1026 | return; | 1049 | return; |
| 1027 | } | 1050 | } |
| 1028 | m_controller.openDeclaration( m_selectedEntryPair.obf ); | 1051 | m_controller.savePreviousReference( m_reference ); |
| 1052 | m_controller.openDeclaration( m_reference.entry ); | ||
| 1029 | } | 1053 | } |
| 1030 | 1054 | ||
| 1031 | private void close( ) | 1055 | private void close( ) |
diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java index f80bec7..dfa2557 100644 --- a/src/cuchaz/enigma/gui/GuiController.java +++ b/src/cuchaz/enigma/gui/GuiController.java | |||
| @@ -14,10 +14,11 @@ import java.io.File; | |||
| 14 | import java.io.FileReader; | 14 | import java.io.FileReader; |
| 15 | import java.io.FileWriter; | 15 | import java.io.FileWriter; |
| 16 | import java.io.IOException; | 16 | import java.io.IOException; |
| 17 | import java.util.Deque; | ||
| 17 | import java.util.List; | 18 | import java.util.List; |
| 18 | import java.util.Stack; | ||
| 19 | 19 | ||
| 20 | import com.google.common.collect.Lists; | 20 | import com.google.common.collect.Lists; |
| 21 | import com.google.common.collect.Queues; | ||
| 21 | 22 | ||
| 22 | import cuchaz.enigma.Deobfuscator; | 23 | import cuchaz.enigma.Deobfuscator; |
| 23 | import cuchaz.enigma.analysis.BehaviorReferenceTreeNode; | 24 | import cuchaz.enigma.analysis.BehaviorReferenceTreeNode; |
| @@ -30,7 +31,6 @@ import cuchaz.enigma.analysis.Token; | |||
| 30 | import cuchaz.enigma.mapping.BehaviorEntry; | 31 | import cuchaz.enigma.mapping.BehaviorEntry; |
| 31 | import cuchaz.enigma.mapping.ClassEntry; | 32 | import cuchaz.enigma.mapping.ClassEntry; |
| 32 | import cuchaz.enigma.mapping.Entry; | 33 | import cuchaz.enigma.mapping.Entry; |
| 33 | import cuchaz.enigma.mapping.EntryPair; | ||
| 34 | import cuchaz.enigma.mapping.FieldEntry; | 34 | import cuchaz.enigma.mapping.FieldEntry; |
| 35 | import cuchaz.enigma.mapping.MappingParseException; | 35 | import cuchaz.enigma.mapping.MappingParseException; |
| 36 | import cuchaz.enigma.mapping.MappingsReader; | 36 | import cuchaz.enigma.mapping.MappingsReader; |
| @@ -43,18 +43,18 @@ public class GuiController | |||
| 43 | private Deobfuscator m_deobfuscator; | 43 | private Deobfuscator m_deobfuscator; |
| 44 | private Gui m_gui; | 44 | private Gui m_gui; |
| 45 | private SourceIndex m_index; | 45 | private SourceIndex m_index; |
| 46 | private ClassEntry m_currentClass; | 46 | private ClassEntry m_currentObfClass; |
| 47 | private boolean m_isDirty; | 47 | private boolean m_isDirty; |
| 48 | private Stack<Entry> m_locationStack; // TODO: make a location class, can be either Entry or EntryReference | 48 | private Deque<EntryReference<Entry,Entry>> m_referenceStack; // TODO: make a location class, can be either Entry or EntryReference |
| 49 | 49 | ||
| 50 | public GuiController( Gui gui ) | 50 | public GuiController( Gui gui ) |
| 51 | { | 51 | { |
| 52 | m_gui = gui; | 52 | m_gui = gui; |
| 53 | m_deobfuscator = null; | 53 | m_deobfuscator = null; |
| 54 | m_index = null; | 54 | m_index = null; |
| 55 | m_currentClass = null; | 55 | m_currentObfClass = null; |
| 56 | m_isDirty = false; | 56 | m_isDirty = false; |
| 57 | m_locationStack = new Stack<Entry>(); | 57 | m_referenceStack = Queues.newArrayDeque(); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | public boolean isDirty( ) | 60 | public boolean isDirty( ) |
| @@ -112,22 +112,16 @@ public class GuiController | |||
| 112 | return null; | 112 | return null; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | return m_index.getToken( pos ); | 115 | return m_index.getReferenceToken( pos ); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | public EntryPair<Entry> getEntryPair( Token token ) | 118 | public EntryReference<Entry,Entry> getDeobfReference( Token token ) |
| 119 | { | 119 | { |
| 120 | if( m_index == null ) | 120 | if( m_index == null ) |
| 121 | { | 121 | { |
| 122 | return null; | 122 | return null; |
| 123 | } | 123 | } |
| 124 | 124 | return m_index.getDeobfReference( token ); | |
| 125 | Entry deobfEntry = m_index.getEntry( token ); | ||
| 126 | if( deobfEntry == null ) | ||
| 127 | { | ||
| 128 | return null; | ||
| 129 | } | ||
| 130 | return new EntryPair<Entry>( m_deobfuscator.obfuscateEntry( deobfEntry ), deobfEntry ); | ||
| 131 | } | 125 | } |
| 132 | 126 | ||
| 133 | public boolean entryHasMapping( Entry deobfEntry ) | 127 | public boolean entryHasMapping( Entry deobfEntry ) |
| @@ -178,54 +172,63 @@ public class GuiController | |||
| 178 | return rootNode; | 172 | return rootNode; |
| 179 | } | 173 | } |
| 180 | 174 | ||
| 181 | public void rename( Entry obfEntry, String newName ) | 175 | public void rename( EntryReference<Entry,Entry> deobfReference, String newName ) |
| 182 | { | 176 | { |
| 183 | m_deobfuscator.rename( obfEntry, newName ); | 177 | EntryReference<Entry,Entry> obfReference = m_deobfuscator.obfuscateReference( deobfReference ); |
| 178 | m_deobfuscator.rename( obfReference.entry, newName ); | ||
| 184 | m_isDirty = true; | 179 | m_isDirty = true; |
| 185 | refreshClasses(); | 180 | refreshClasses(); |
| 186 | refreshCurrentClass( obfEntry ); | 181 | refreshCurrentClass( obfReference ); |
| 187 | } | 182 | } |
| 188 | 183 | ||
| 189 | public void openDeclaration( Entry entry ) | 184 | public void openDeclaration( Entry entry ) |
| 190 | { | 185 | { |
| 191 | // go to the entry | 186 | if( entry == null ) |
| 192 | Entry obfEntry = m_deobfuscator.obfuscateEntry( entry ); | ||
| 193 | if( m_currentClass == null || !m_currentClass.equals( obfEntry.getClassEntry() ) ) | ||
| 194 | { | 187 | { |
| 195 | m_currentClass = new ClassEntry( obfEntry.getClassEntry() ); | 188 | throw new IllegalArgumentException( "Entry cannot be null!" ); |
| 196 | deobfuscate( m_currentClass, obfEntry ); | ||
| 197 | } | 189 | } |
| 198 | else | 190 | openReference( new EntryReference<Entry,Entry>( entry ) ); |
| 191 | } | ||
| 192 | |||
| 193 | public void openReference( EntryReference<Entry,Entry> deobfReference ) | ||
| 194 | { | ||
| 195 | if( deobfReference == null ) | ||
| 199 | { | 196 | { |
| 200 | m_gui.showToken( m_index.getDeclarationToken( m_deobfuscator.deobfuscateEntry( obfEntry ) ) ); | 197 | throw new IllegalArgumentException( "Reference cannot be null!" ); |
| 201 | } | 198 | } |
| 202 | 199 | ||
| 203 | if( m_locationStack.isEmpty() || !m_locationStack.peek().equals( obfEntry ) ) | 200 | // get the reference target class |
| 201 | EntryReference<Entry,Entry> obfReference = m_deobfuscator.obfuscateReference( deobfReference ); | ||
| 202 | ClassEntry obfClassEntry = obfReference.getClassEntry().getOuterClassEntry(); | ||
| 203 | if( m_currentObfClass == null || !m_currentObfClass.equals( obfClassEntry ) ) | ||
| 204 | { | ||
| 205 | // deobfuscate the class, then navigate to the reference | ||
| 206 | m_currentObfClass = obfClassEntry; | ||
| 207 | deobfuscate( m_currentObfClass, obfReference ); | ||
| 208 | } | ||
| 209 | else | ||
| 204 | { | 210 | { |
| 205 | // update the stack | 211 | // the class file is already open, just navigate to the reference |
| 206 | m_locationStack.push( obfEntry ); | 212 | m_gui.showToken( m_index.getReferenceToken( deobfReference ) ); |
| 207 | } | 213 | } |
| 208 | } | 214 | } |
| 209 | 215 | ||
| 210 | public void openReference( EntryReference<Entry> reference ) | 216 | public void savePreviousReference( EntryReference<Entry,Entry> deobfReference ) |
| 211 | { | 217 | { |
| 212 | // TODO: find out how to load the n-th reference in a caller | 218 | m_referenceStack.push( m_deobfuscator.obfuscateReference( deobfReference ) ); |
| 213 | // TEMP: just go to the caller for now | ||
| 214 | openDeclaration( reference.caller ); | ||
| 215 | } | 219 | } |
| 216 | 220 | ||
| 217 | public void openPreviousLocation( ) | 221 | public void openPreviousReference( ) |
| 218 | { | 222 | { |
| 219 | if( hasPreviousLocation() ) | 223 | if( hasPreviousLocation() ) |
| 220 | { | 224 | { |
| 221 | m_locationStack.pop(); | 225 | openReference( m_deobfuscator.deobfuscateReference( m_referenceStack.pop() ) ); |
| 222 | openDeclaration( m_locationStack.peek() ); | ||
| 223 | } | 226 | } |
| 224 | } | 227 | } |
| 225 | 228 | ||
| 226 | public boolean hasPreviousLocation( ) | 229 | public boolean hasPreviousLocation( ) |
| 227 | { | 230 | { |
| 228 | return m_locationStack.size() > 1; | 231 | return !m_referenceStack.isEmpty(); |
| 229 | } | 232 | } |
| 230 | 233 | ||
| 231 | private void refreshClasses( ) | 234 | private void refreshClasses( ) |
| @@ -242,15 +245,15 @@ public class GuiController | |||
| 242 | refreshCurrentClass( null ); | 245 | refreshCurrentClass( null ); |
| 243 | } | 246 | } |
| 244 | 247 | ||
| 245 | private void refreshCurrentClass( Entry obfEntryToShow ) | 248 | private void refreshCurrentClass( EntryReference<Entry,Entry> obfReferenceToShow ) |
| 246 | { | 249 | { |
| 247 | if( m_currentClass != null ) | 250 | if( m_currentObfClass != null ) |
| 248 | { | 251 | { |
| 249 | deobfuscate( m_currentClass, obfEntryToShow ); | 252 | deobfuscate( m_currentObfClass, obfReferenceToShow ); |
| 250 | } | 253 | } |
| 251 | } | 254 | } |
| 252 | 255 | ||
| 253 | private void deobfuscate( final ClassEntry classEntry, final Entry obfEntryToShow ) | 256 | private void deobfuscate( final ClassEntry classEntry, final EntryReference<Entry,Entry> obfReferenceToShow ) |
| 254 | { | 257 | { |
| 255 | m_gui.setSource( "(deobfuscating...)" ); | 258 | m_gui.setSource( "(deobfuscating...)" ); |
| 256 | 259 | ||
| @@ -263,29 +266,32 @@ public class GuiController | |||
| 263 | // decompile,deobfuscate the bytecode | 266 | // decompile,deobfuscate the bytecode |
| 264 | m_index = m_deobfuscator.getSource( classEntry.getClassName() ); | 267 | m_index = m_deobfuscator.getSource( classEntry.getClassName() ); |
| 265 | m_gui.setSource( m_index.getSource() ); | 268 | m_gui.setSource( m_index.getSource() ); |
| 266 | if( obfEntryToShow != null ) | 269 | if( obfReferenceToShow != null ) |
| 267 | { | 270 | { |
| 268 | Entry deobfEntryToShow = m_deobfuscator.deobfuscateEntry( obfEntryToShow ); | 271 | EntryReference<Entry,Entry> deobfReferenceToShow = m_deobfuscator.deobfuscateReference( obfReferenceToShow ); |
| 269 | Token token = m_index.getDeclarationToken( deobfEntryToShow ); | 272 | Token token = m_index.getReferenceToken( deobfReferenceToShow ); |
| 270 | if( token == null ) | 273 | if( token == null ) |
| 271 | { | 274 | { |
| 272 | // TEMP | 275 | // DEBUG |
| 273 | System.out.println( "WARNING: can't find token for " + obfEntryToShow + " -> " + deobfEntryToShow ); | 276 | System.out.println( "WARNING: can't find token for " + obfReferenceToShow + " -> " + deobfReferenceToShow ); |
| 277 | } | ||
| 278 | else | ||
| 279 | { | ||
| 280 | m_gui.showToken( token ); | ||
| 274 | } | 281 | } |
| 275 | m_gui.showToken( token ); | ||
| 276 | } | 282 | } |
| 277 | 283 | ||
| 278 | // set the highlighted tokens | 284 | // set the highlighted tokens |
| 279 | List<Token> obfuscatedTokens = Lists.newArrayList(); | 285 | List<Token> obfuscatedTokens = Lists.newArrayList(); |
| 280 | List<Token> deobfuscatedTokens = Lists.newArrayList(); | 286 | List<Token> deobfuscatedTokens = Lists.newArrayList(); |
| 281 | for( Token token : m_index.tokens() ) | 287 | for( Token token : m_index.referenceTokens() ) |
| 282 | { | 288 | { |
| 283 | Entry entry = m_index.getEntry( token ); | 289 | EntryReference<Entry,Entry> reference = m_index.getDeobfReference( token ); |
| 284 | if( entryHasMapping( entry ) ) | 290 | if( entryHasMapping( reference.entry ) ) |
| 285 | { | 291 | { |
| 286 | deobfuscatedTokens.add( token ); | 292 | deobfuscatedTokens.add( token ); |
| 287 | } | 293 | } |
| 288 | else if( entryIsObfuscatedIdenfitier( entry ) ) | 294 | else if( entryIsObfuscatedIdenfitier( reference.entry ) ) |
| 289 | { | 295 | { |
| 290 | obfuscatedTokens.add( token ); | 296 | obfuscatedTokens.add( token ); |
| 291 | } | 297 | } |