summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar jeff2014-09-01 20:40:11 -0400
committerGravatar jeff2014-09-01 20:40:11 -0400
commita146283291d5529eb9363b2fbc6fd5e643dee85a (patch)
tree79b6459bef4e8549e98d8e334e2582331f282339
parentadded checks to prevent renaming classes/fields/methods/arguments to the same... (diff)
downloadenigma-fork-a146283291d5529eb9363b2fbc6fd5e643dee85a.tar.gz
enigma-fork-a146283291d5529eb9363b2fbc6fd5e643dee85a.tar.xz
enigma-fork-a146283291d5529eb9363b2fbc6fd5e643dee85a.zip
made obfuscated/deobfuscated class selector a bit easier to use
-rw-r--r--src/cuchaz/enigma/Deobfuscator.java10
-rw-r--r--src/cuchaz/enigma/gui/ClassSelector.java181
-rw-r--r--src/cuchaz/enigma/gui/ClassSelectorClassNode.java38
-rw-r--r--src/cuchaz/enigma/gui/ClassSelectorPackageNode.java36
-rw-r--r--src/cuchaz/enigma/gui/Gui.java126
-rw-r--r--src/cuchaz/enigma/gui/GuiController.java4
6 files changed, 282 insertions, 113 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java
index 9a78f38..49aa1ff 100644
--- a/src/cuchaz/enigma/Deobfuscator.java
+++ b/src/cuchaz/enigma/Deobfuscator.java
@@ -151,12 +151,12 @@ public class Deobfuscator
151 return m_mappings.getTranslator( m_jarIndex.getAncestries(), direction ); 151 return m_mappings.getTranslator( m_jarIndex.getAncestries(), direction );
152 } 152 }
153 153
154 public void getSeparatedClasses( List<String> obfClasses, List<String> deobfClasses ) 154 public void getSeparatedClasses( List<ClassEntry> obfClasses, List<ClassEntry> deobfClasses )
155 { 155 {
156 for( ClassEntry obfClassEntry : m_jarIndex.getObfClassEntries() ) 156 for( ClassEntry obfClassEntry : m_jarIndex.getObfClassEntries() )
157 { 157 {
158 // skip inner classes 158 // skip inner classes
159 if( m_jarIndex.getOuterClass( obfClassEntry.getName() ) != null ) 159 if( obfClassEntry.isInnerClass() )
160 { 160 {
161 continue; 161 continue;
162 } 162 }
@@ -166,17 +166,17 @@ public class Deobfuscator
166 if( !deobfClassEntry.equals( obfClassEntry ) ) 166 if( !deobfClassEntry.equals( obfClassEntry ) )
167 { 167 {
168 // if the class has a mapping, clearly it's deobfuscated 168 // if the class has a mapping, clearly it's deobfuscated
169 deobfClasses.add( deobfClassEntry.getName() ); 169 deobfClasses.add( deobfClassEntry );
170 } 170 }
171 else if( !obfClassEntry.getPackageName().equals( Constants.NonePackage ) ) 171 else if( !obfClassEntry.getPackageName().equals( Constants.NonePackage ) )
172 { 172 {
173 // also call it deobufscated if it's not in the none package 173 // also call it deobufscated if it's not in the none package
174 deobfClasses.add( obfClassEntry.getName() ); 174 deobfClasses.add( obfClassEntry );
175 } 175 }
176 else 176 else
177 { 177 {
178 // otherwise, assume it's still obfuscated 178 // otherwise, assume it's still obfuscated
179 obfClasses.add( obfClassEntry.getName() ); 179 obfClasses.add( obfClassEntry );
180 } 180 }
181 } 181 }
182 } 182 }
diff --git a/src/cuchaz/enigma/gui/ClassSelector.java b/src/cuchaz/enigma/gui/ClassSelector.java
new file mode 100644
index 0000000..338ad80
--- /dev/null
+++ b/src/cuchaz/enigma/gui/ClassSelector.java
@@ -0,0 +1,181 @@
1package cuchaz.enigma.gui;
2
3import java.awt.event.MouseAdapter;
4import java.awt.event.MouseEvent;
5import java.util.Collection;
6import java.util.Collections;
7import java.util.Comparator;
8import java.util.List;
9import java.util.Map;
10
11import javax.swing.JTree;
12import javax.swing.tree.DefaultMutableTreeNode;
13import javax.swing.tree.DefaultTreeModel;
14import javax.swing.tree.TreePath;
15
16import com.beust.jcommander.internal.Lists;
17import com.beust.jcommander.internal.Maps;
18import com.google.common.collect.ArrayListMultimap;
19import com.google.common.collect.Multimap;
20
21import cuchaz.enigma.mapping.ClassEntry;
22
23public class ClassSelector extends JTree
24{
25 private static final long serialVersionUID = -7632046902384775977L;
26
27 public interface ClassSelectionListener
28 {
29 void onSelectClass( ClassEntry classEntry );
30 }
31
32 public static Comparator<ClassEntry> ObfuscatedClassEntryComparator;
33 public static Comparator<ClassEntry> DeobfuscatedClassEntryComparator;
34
35 static
36 {
37 ObfuscatedClassEntryComparator = new Comparator<ClassEntry>( )
38 {
39 @Override
40 public int compare( ClassEntry a, ClassEntry b )
41 {
42 if( a.getName().length() != b.getName().length() )
43 {
44 return a.getName().length() - b.getName().length();
45 }
46 return a.getName().compareTo( b.getName() );
47 }
48 };
49
50 DeobfuscatedClassEntryComparator = new Comparator<ClassEntry>( )
51 {
52 @Override
53 public int compare( ClassEntry a, ClassEntry b )
54 {
55 return a.getName().compareTo( b.getName() );
56 }
57 };
58 }
59
60 private ClassSelectionListener m_listener;
61 private Comparator<ClassEntry> m_comparator;
62
63 public ClassSelector( Comparator<ClassEntry> comparator )
64 {
65 m_comparator = comparator;
66
67 // configure the tree control
68 setRootVisible( false );
69 setShowsRootHandles( false );
70 setModel( null );
71
72 // hook events
73 addMouseListener( new MouseAdapter()
74 {
75 @Override
76 public void mouseClicked( MouseEvent event )
77 {
78 if( m_listener != null && event.getClickCount() == 2 )
79 {
80 // get the selected node
81 TreePath path = getSelectionPath();
82 if( path != null && path.getLastPathComponent() instanceof ClassSelectorClassNode )
83 {
84 ClassSelectorClassNode node = (ClassSelectorClassNode)path.getLastPathComponent();
85 m_listener.onSelectClass( node.getClassEntry() );
86 }
87 }
88 }
89 } );
90
91 // init defaults
92 m_listener = null;
93 }
94
95 public void setListener( ClassSelectionListener val )
96 {
97 m_listener = val;
98 }
99
100 public void setClasses( Collection<ClassEntry> classEntries )
101 {
102 if( classEntries == null )
103 {
104 setModel( null );
105 return;
106 }
107
108 // build the package names
109 Map<String,ClassSelectorPackageNode> packages = Maps.newHashMap();
110 for( ClassEntry classEntry : classEntries )
111 {
112 packages.put( classEntry.getPackageName(), null );
113 }
114
115 // sort the packages
116 List<String> sortedPackageNames = Lists.newArrayList( packages.keySet() );
117 Collections.sort( sortedPackageNames, new Comparator<String>( )
118 {
119 @Override
120 public int compare( String a, String b )
121 {
122 // I can never keep this rule straight when writing these damn things...
123 // a < b => -1, a == b => 0, a > b => +1
124
125 String[] aparts = a.split( "/" );
126 String[] bparts = b.split( "/" );
127 for( int i=0; true; i++ )
128 {
129 if( i >= aparts.length )
130 {
131 return -1;
132 }
133 else if( i >= bparts.length )
134 {
135 return 1;
136 }
137
138 int result = aparts[i].compareTo( bparts[i] );
139 if( result != 0 )
140 {
141 return result;
142 }
143 }
144 }
145 } );
146
147 // create the root node and the package nodes
148 DefaultMutableTreeNode root = new DefaultMutableTreeNode();
149 for( String packageName : sortedPackageNames )
150 {
151 ClassSelectorPackageNode node = new ClassSelectorPackageNode( packageName );
152 packages.put( packageName, node );
153 root.add( node );
154 }
155
156 // put the classes into packages
157 Multimap<String,ClassEntry> packagedClassEntries = ArrayListMultimap.create();
158 for( ClassEntry classEntry : classEntries )
159 {
160 packagedClassEntries.put( classEntry.getPackageName(), classEntry );
161 }
162
163 // build the class nodes
164 for( String packageName : packagedClassEntries.keySet() )
165 {
166 // sort the class entries
167 List<ClassEntry> classEntriesInPackage = Lists.newArrayList( packagedClassEntries.get( packageName ) );
168 Collections.sort( classEntriesInPackage, m_comparator );
169
170 // create the nodes in order
171 for( ClassEntry classEntry : classEntriesInPackage )
172 {
173 ClassSelectorPackageNode node = packages.get( packageName );
174 node.add( new ClassSelectorClassNode( classEntry ) );
175 }
176 }
177
178 // finally, update the tree control
179 setModel( new DefaultTreeModel( root ) );
180 }
181}
diff --git a/src/cuchaz/enigma/gui/ClassSelectorClassNode.java b/src/cuchaz/enigma/gui/ClassSelectorClassNode.java
new file mode 100644
index 0000000..cffa795
--- /dev/null
+++ b/src/cuchaz/enigma/gui/ClassSelectorClassNode.java
@@ -0,0 +1,38 @@
1/*******************************************************************************
2 * Copyright (c) 2014 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Public License v3.0
5 * which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/gpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.gui;
12
13import javax.swing.tree.DefaultMutableTreeNode;
14
15import cuchaz.enigma.mapping.ClassEntry;
16
17public class ClassSelectorClassNode extends DefaultMutableTreeNode
18{
19 private static final long serialVersionUID = -8956754339813257380L;
20
21 private ClassEntry m_classEntry;
22
23 public ClassSelectorClassNode( ClassEntry classEntry )
24 {
25 m_classEntry = classEntry;
26 }
27
28 public ClassEntry getClassEntry( )
29 {
30 return m_classEntry;
31 }
32
33 @Override
34 public String toString( )
35 {
36 return m_classEntry.getSimpleName();
37 }
38}
diff --git a/src/cuchaz/enigma/gui/ClassSelectorPackageNode.java b/src/cuchaz/enigma/gui/ClassSelectorPackageNode.java
new file mode 100644
index 0000000..ad88fb4
--- /dev/null
+++ b/src/cuchaz/enigma/gui/ClassSelectorPackageNode.java
@@ -0,0 +1,36 @@
1/*******************************************************************************
2 * Copyright (c) 2014 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Public License v3.0
5 * which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/gpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.gui;
12
13import javax.swing.tree.DefaultMutableTreeNode;
14
15public class ClassSelectorPackageNode extends DefaultMutableTreeNode
16{
17 private static final long serialVersionUID = -3730868701219548043L;
18
19 private String m_packageName;
20
21 public ClassSelectorPackageNode( String packageName )
22 {
23 m_packageName = packageName;
24 }
25
26 public String getPackageName( )
27 {
28 return m_packageName;
29 }
30
31 @Override
32 public String toString( )
33 {
34 return m_packageName;
35 }
36}
diff --git a/src/cuchaz/enigma/gui/Gui.java b/src/cuchaz/enigma/gui/Gui.java
index 46395ac..8ae16f4 100644
--- a/src/cuchaz/enigma/gui/Gui.java
+++ b/src/cuchaz/enigma/gui/Gui.java
@@ -31,7 +31,6 @@ import java.io.IOException;
31import java.lang.Thread.UncaughtExceptionHandler; 31import java.lang.Thread.UncaughtExceptionHandler;
32import java.util.Collection; 32import java.util.Collection;
33import java.util.Collections; 33import java.util.Collections;
34import java.util.Comparator;
35import java.util.List; 34import java.util.List;
36import java.util.Vector; 35import java.util.Vector;
37 36
@@ -79,6 +78,7 @@ import cuchaz.enigma.analysis.MethodImplementationsTreeNode;
79import cuchaz.enigma.analysis.MethodInheritanceTreeNode; 78import cuchaz.enigma.analysis.MethodInheritanceTreeNode;
80import cuchaz.enigma.analysis.ReferenceTreeNode; 79import cuchaz.enigma.analysis.ReferenceTreeNode;
81import cuchaz.enigma.analysis.Token; 80import cuchaz.enigma.analysis.Token;
81import cuchaz.enigma.gui.ClassSelector.ClassSelectionListener;
82import cuchaz.enigma.mapping.ArgumentEntry; 82import cuchaz.enigma.mapping.ArgumentEntry;
83import cuchaz.enigma.mapping.ClassEntry; 83import cuchaz.enigma.mapping.ClassEntry;
84import cuchaz.enigma.mapping.ConstructorEntry; 84import cuchaz.enigma.mapping.ConstructorEntry;
@@ -90,61 +90,12 @@ import cuchaz.enigma.mapping.MethodEntry;
90 90
91public class Gui 91public class Gui
92{ 92{
93 private static Comparator<String> m_obfClassSorter;
94 private static Comparator<String> m_deobfClassSorter;
95
96 static
97 {
98 m_obfClassSorter = new Comparator<String>( )
99 {
100 @Override
101 public int compare( String a, String b )
102 {
103 if( a.length() != b.length() )
104 {
105 return a.length() - b.length();
106 }
107 return a.compareTo( b );
108 }
109 };
110
111 m_deobfClassSorter = new Comparator<String>( )
112 {
113 @Override
114 public int compare( String a, String b )
115 {
116 // I can never keep this rule straight when writing these damn things...
117 // a < b => -1, a == b => 0, a > b => +1
118
119 String[] aparts = a.split( "\\." );
120 String[] bparts = b.split( "\\." );
121 for( int i=0; true; i++ )
122 {
123 if( i >= aparts.length )
124 {
125 return -1;
126 }
127 else if( i >= bparts.length )
128 {
129 return 1;
130 }
131
132 int result = aparts[i].compareTo( bparts[i] );
133 if( result != 0 )
134 {
135 return result;
136 }
137 }
138 }
139 };
140 }
141
142 private GuiController m_controller; 93 private GuiController m_controller;
143 94
144 // controls 95 // controls
145 private JFrame m_frame; 96 private JFrame m_frame;
146 private JList<String> m_obfClasses; 97 private ClassSelector m_obfClasses;
147 private JList<String> m_deobfClasses; 98 private ClassSelector m_deobfClasses;
148 private JEditorPane m_editor; 99 private JEditorPane m_editor;
149 private JPanel m_classesPanel; 100 private JPanel m_classesPanel;
150 private JSplitPane m_splitClasses; 101 private JSplitPane m_splitClasses;
@@ -205,27 +156,17 @@ public class Gui
205 m_exportFileChooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY ); 156 m_exportFileChooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY );
206 157
207 // init obfuscated classes list 158 // init obfuscated classes list
208 m_obfClasses = new JList<String>(); 159 m_obfClasses = new ClassSelector( ClassSelector.ObfuscatedClassEntryComparator );
209 m_obfClasses.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); 160 m_obfClasses.setListener( new ClassSelectionListener( )
210 m_obfClasses.setLayoutOrientation( JList.VERTICAL );
211 m_obfClasses.setCellRenderer( new ClassListCellRenderer() );
212 m_obfClasses.addMouseListener( new MouseAdapter()
213 { 161 {
214 @Override 162 @Override
215 public void mouseClicked( MouseEvent event ) 163 public void onSelectClass( ClassEntry classEntry )
216 { 164 {
217 if( event.getClickCount() == 2 ) 165 if( m_reference != null )
218 { 166 {
219 String selected = m_obfClasses.getSelectedValue(); 167 m_controller.savePreviousReference( m_reference );
220 if( selected != null )
221 {
222 if( m_reference != null )
223 {
224 m_controller.savePreviousReference( m_reference );
225 }
226 m_controller.openDeclaration( new ClassEntry( selected ) );
227 }
228 } 168 }
169 m_controller.openDeclaration( classEntry );
229 } 170 }
230 } ); 171 } );
231 JScrollPane obfScroller = new JScrollPane( m_obfClasses ); 172 JScrollPane obfScroller = new JScrollPane( m_obfClasses );
@@ -235,27 +176,17 @@ public class Gui
235 obfPanel.add( obfScroller, BorderLayout.CENTER ); 176 obfPanel.add( obfScroller, BorderLayout.CENTER );
236 177
237 // init deobfuscated classes list 178 // init deobfuscated classes list
238 m_deobfClasses = new JList<String>(); 179 m_deobfClasses = new ClassSelector( ClassSelector.DeobfuscatedClassEntryComparator );
239 m_deobfClasses.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); 180 m_deobfClasses.setListener( new ClassSelectionListener( )
240 m_deobfClasses.setLayoutOrientation( JList.VERTICAL );
241 m_deobfClasses.setCellRenderer( new ClassListCellRenderer() );
242 m_deobfClasses.addMouseListener( new MouseAdapter()
243 { 181 {
244 @Override 182 @Override
245 public void mouseClicked( MouseEvent event ) 183 public void onSelectClass( ClassEntry classEntry )
246 { 184 {
247 if( event.getClickCount() == 2 ) 185 if( m_reference != null )
248 { 186 {
249 String selected = m_deobfClasses.getSelectedValue(); 187 m_controller.savePreviousReference( m_reference );
250 if( selected != null )
251 {
252 if( m_reference != null )
253 {
254 m_controller.savePreviousReference( m_reference );
255 }
256 m_controller.openDeclaration( new ClassEntry( selected ) );
257 }
258 } 188 }
189 m_controller.openDeclaration( classEntry );
259 } 190 }
260 } ); 191 } );
261 JScrollPane deobfScroller = new JScrollPane( m_deobfClasses ); 192 JScrollPane deobfScroller = new JScrollPane( m_deobfClasses );
@@ -266,6 +197,7 @@ public class Gui
266 197
267 // set up classes panel (don't add the splitter yet) 198 // set up classes panel (don't add the splitter yet)
268 m_splitClasses = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, obfPanel, deobfPanel ); 199 m_splitClasses = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, obfPanel, deobfPanel );
200 m_splitClasses.setResizeWeight( 0.3 );
269 m_classesPanel = new JPanel(); 201 m_classesPanel = new JPanel();
270 m_classesPanel.setLayout( new BorderLayout() ); 202 m_classesPanel.setLayout( new BorderLayout() );
271 m_classesPanel.setPreferredSize( new Dimension( 250, 0 ) ); 203 m_classesPanel.setPreferredSize( new Dimension( 250, 0 ) );
@@ -847,32 +779,14 @@ public class Gui
847 redraw(); 779 redraw();
848 } 780 }
849 781
850 public void setObfClasses( List<String> obfClasses ) 782 public void setObfClasses( Collection<ClassEntry> obfClasses )
851 { 783 {
852 if( obfClasses != null ) 784 m_obfClasses.setClasses( obfClasses );
853 {
854 Vector<String> sortedClasses = new Vector<String>( obfClasses );
855 Collections.sort( sortedClasses, m_obfClassSorter );
856 m_obfClasses.setListData( sortedClasses );
857 }
858 else
859 {
860 m_obfClasses.setListData( new Vector<String>() );
861 }
862 } 785 }
863 786
864 public void setDeobfClasses( List<String> deobfClasses ) 787 public void setDeobfClasses( Collection<ClassEntry> deobfClasses )
865 { 788 {
866 if( deobfClasses != null ) 789 m_deobfClasses.setClasses( deobfClasses );
867 {
868 Vector<String> sortedClasses = new Vector<String>( deobfClasses );
869 Collections.sort( sortedClasses, m_deobfClassSorter );
870 m_deobfClasses.setListData( sortedClasses );
871 }
872 else
873 {
874 m_deobfClasses.setListData( new Vector<String>() );
875 }
876 } 790 }
877 791
878 public void setMappingsFile( File file ) 792 public void setMappingsFile( File file )
diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java
index 2879483..c0fb2e4 100644
--- a/src/cuchaz/enigma/gui/GuiController.java
+++ b/src/cuchaz/enigma/gui/GuiController.java
@@ -315,8 +315,8 @@ public class GuiController
315 315
316 private void refreshClasses( ) 316 private void refreshClasses( )
317 { 317 {
318 List<String> obfClasses = Lists.newArrayList(); 318 List<ClassEntry> obfClasses = Lists.newArrayList();
319 List<String> deobfClasses = Lists.newArrayList(); 319 List<ClassEntry> deobfClasses = Lists.newArrayList();
320 m_deobfuscator.getSeparatedClasses( obfClasses, deobfClasses ); 320 m_deobfuscator.getSeparatedClasses( obfClasses, deobfClasses );
321 m_gui.setObfClasses( obfClasses ); 321 m_gui.setObfClasses( obfClasses );
322 m_gui.setDeobfClasses( deobfClasses ); 322 m_gui.setDeobfClasses( deobfClasses );