summaryrefslogtreecommitdiff
path: root/src/cuchaz
diff options
context:
space:
mode:
authorGravatar jeff2014-08-03 11:16:33 -0400
committerGravatar jeff2014-08-03 11:16:33 -0400
commit76be350b3c54ea88cc1a95b5cf0d1db153f2edb3 (patch)
tree91baffda41c4fcdcc69c646287e98d6d2a0f80d6 /src/cuchaz
parentstarted working on method parameter renaming (diff)
downloadenigma-fork-76be350b3c54ea88cc1a95b5cf0d1db153f2edb3.tar.gz
enigma-fork-76be350b3c54ea88cc1a95b5cf0d1db153f2edb3.tar.xz
enigma-fork-76be350b3c54ea88cc1a95b5cf0d1db153f2edb3.zip
fixed bugs with saving mappings
got argument renaming to work
Diffstat (limited to 'src/cuchaz')
-rw-r--r--src/cuchaz/enigma/TranslatingTypeLoader.java2
-rw-r--r--src/cuchaz/enigma/analysis/SourcedAst.java21
-rw-r--r--src/cuchaz/enigma/bytecode/MethodParameterWriter.java26
-rw-r--r--src/cuchaz/enigma/bytecode/MethodParametersAttribute.java46
-rw-r--r--src/cuchaz/enigma/gui/Gui.java54
-rw-r--r--src/cuchaz/enigma/gui/GuiController.java8
-rw-r--r--src/cuchaz/enigma/mapping/EntryPair.java30
-rw-r--r--src/cuchaz/enigma/mapping/MethodMapping.java2
8 files changed, 112 insertions, 77 deletions
diff --git a/src/cuchaz/enigma/TranslatingTypeLoader.java b/src/cuchaz/enigma/TranslatingTypeLoader.java
index cd36e8d..e57a09d 100644
--- a/src/cuchaz/enigma/TranslatingTypeLoader.java
+++ b/src/cuchaz/enigma/TranslatingTypeLoader.java
@@ -70,8 +70,8 @@ public class TranslatingTypeLoader implements ITypeLoader
70 try 70 try
71 { 71 {
72 CtClass c = classPool.get( name ); 72 CtClass c = classPool.get( name );
73 new ClassTranslator( m_deobfuscatingTranslator ).translate( c );
74 new MethodParameterWriter( m_deobfuscatingTranslator ).writeMethodArguments( c ); 73 new MethodParameterWriter( m_deobfuscatingTranslator ).writeMethodArguments( c );
74 new ClassTranslator( m_deobfuscatingTranslator ).translate( c );
75 buf = c.toBytecode(); 75 buf = c.toBytecode();
76 } 76 }
77 catch( Exception ex ) 77 catch( Exception ex )
diff --git a/src/cuchaz/enigma/analysis/SourcedAst.java b/src/cuchaz/enigma/analysis/SourcedAst.java
index 04c6f03..52a3453 100644
--- a/src/cuchaz/enigma/analysis/SourcedAst.java
+++ b/src/cuchaz/enigma/analysis/SourcedAst.java
@@ -13,7 +13,10 @@ package cuchaz.enigma.analysis;
13import java.io.IOException; 13import java.io.IOException;
14import java.util.HashMap; 14import java.util.HashMap;
15 15
16import javassist.bytecode.Descriptor;
17
16import com.google.common.collect.Maps; 18import com.google.common.collect.Maps;
19import com.sun.source.tree.ClassTree;
17import com.sun.source.tree.CompilationUnitTree; 20import com.sun.source.tree.CompilationUnitTree;
18import com.sun.source.tree.ImportTree; 21import com.sun.source.tree.ImportTree;
19import com.sun.source.tree.Tree; 22import com.sun.source.tree.Tree;
@@ -34,7 +37,7 @@ public class SourcedAst
34 m_positions = m_trees.getSourcePositions(); 37 m_positions = m_trees.getSourcePositions();
35 m_classNameIndex = Maps.newHashMap(); 38 m_classNameIndex = Maps.newHashMap();
36 39
37 // index all the class names 40 // index all the class names from package imports
38 for( ImportTree importTree : m_tree.getImports() ) 41 for( ImportTree importTree : m_tree.getImports() )
39 { 42 {
40 // ignore static imports for now 43 // ignore static imports for now
@@ -44,9 +47,9 @@ public class SourcedAst
44 } 47 }
45 48
46 // get the full and simple class names 49 // get the full and simple class names
47 String fullName = importTree.getQualifiedIdentifier().toString(); 50 String fullName = Descriptor.toJvmName( importTree.getQualifiedIdentifier().toString() );
48 String simpleName = fullName; 51 String simpleName = fullName;
49 String[] parts = fullName.split( "\\." ); 52 String[] parts = fullName.split( "/" );
50 if( parts.length > 0 ) 53 if( parts.length > 0 )
51 { 54 {
52 simpleName = parts[parts.length - 1]; 55 simpleName = parts[parts.length - 1];
@@ -54,6 +57,18 @@ public class SourcedAst
54 57
55 m_classNameIndex.put( simpleName, fullName ); 58 m_classNameIndex.put( simpleName, fullName );
56 } 59 }
60
61 // index the self class using the package name
62 String packageName = Descriptor.toJvmName( m_tree.getPackageName().toString() );
63 for( Tree typeTree : m_tree.getTypeDecls() )
64 {
65 if( typeTree instanceof ClassTree )
66 {
67 ClassTree classTree = (ClassTree)typeTree;
68 String className = classTree.getSimpleName().toString();
69 m_classNameIndex.put( className, packageName + "/" + className );
70 }
71 }
57 } 72 }
58 73
59 public int getStart( Tree node ) 74 public int getStart( Tree node )
diff --git a/src/cuchaz/enigma/bytecode/MethodParameterWriter.java b/src/cuchaz/enigma/bytecode/MethodParameterWriter.java
index 1e5d1f0..a8d3983 100644
--- a/src/cuchaz/enigma/bytecode/MethodParameterWriter.java
+++ b/src/cuchaz/enigma/bytecode/MethodParameterWriter.java
@@ -10,9 +10,15 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma.bytecode; 11package cuchaz.enigma.bytecode;
12 12
13import java.util.ArrayList;
14import java.util.List;
15
13import javassist.CtBehavior; 16import javassist.CtBehavior;
14import javassist.CtClass; 17import javassist.CtClass;
15import javassist.bytecode.AttributeInfo; 18import javassist.bytecode.Descriptor;
19import cuchaz.enigma.mapping.ArgumentEntry;
20import cuchaz.enigma.mapping.ClassEntry;
21import cuchaz.enigma.mapping.MethodEntry;
16import cuchaz.enigma.mapping.Translator; 22import cuchaz.enigma.mapping.Translator;
17 23
18public class MethodParameterWriter 24public class MethodParameterWriter
@@ -27,9 +33,25 @@ public class MethodParameterWriter
27 public void writeMethodArguments( CtClass c ) 33 public void writeMethodArguments( CtClass c )
28 { 34 {
29 // Procyon will read method arguments from the "MethodParameters" attribute, so write those 35 // Procyon will read method arguments from the "MethodParameters" attribute, so write those
36 ClassEntry classEntry = new ClassEntry( Descriptor.toJvmName( c.getName() ) );
30 for( CtBehavior behavior : c.getDeclaredBehaviors() ) 37 for( CtBehavior behavior : c.getDeclaredBehaviors() )
31 { 38 {
32 AttributeInfo attribute = behavior.getMethodInfo().getAttribute( "MethodParameter" ); 39 int numParams = Descriptor.numOfParameters( behavior.getMethodInfo().getDescriptor() );
40 if( numParams <= 0 )
41 {
42 continue;
43 }
44
45 // get the list of parameter names
46 MethodEntry methodEntry = new MethodEntry( classEntry, behavior.getMethodInfo().getName(), behavior.getSignature() );
47 List<String> names = new ArrayList<String>( numParams );
48 for( int i=0; i<numParams; i++ )
49 {
50 names.add( m_translator.translate( new ArgumentEntry( methodEntry, i, "" ) ) );
51 }
52
53 // save the mappings to the class
54 MethodParametersAttribute.updateClass( behavior.getMethodInfo(), names );
33 } 55 }
34 } 56 }
35} 57}
diff --git a/src/cuchaz/enigma/bytecode/MethodParametersAttribute.java b/src/cuchaz/enigma/bytecode/MethodParametersAttribute.java
index 0b29403..baf1ac1 100644
--- a/src/cuchaz/enigma/bytecode/MethodParametersAttribute.java
+++ b/src/cuchaz/enigma/bytecode/MethodParametersAttribute.java
@@ -13,24 +13,45 @@ package cuchaz.enigma.bytecode;
13import java.io.ByteArrayOutputStream; 13import java.io.ByteArrayOutputStream;
14import java.io.DataOutputStream; 14import java.io.DataOutputStream;
15import java.io.IOException; 15import java.io.IOException;
16import java.util.ArrayList;
16import java.util.List; 17import java.util.List;
17 18
18import javassist.bytecode.AttributeInfo; 19import javassist.bytecode.AttributeInfo;
19import javassist.bytecode.ConstPool; 20import javassist.bytecode.ConstPool;
21import javassist.bytecode.MethodInfo;
20 22
21public class MethodParametersAttribute extends AttributeInfo 23public class MethodParametersAttribute extends AttributeInfo
22{ 24{
23 public MethodParametersAttribute( ConstPool pool, int attributeNameIndex, List<Integer> parameterNameIndices ) 25 private MethodParametersAttribute( ConstPool pool, List<Integer> parameterNameIndices )
24 { 26 {
25 super( pool, "MethodParameters", writeStruct( attributeNameIndex, parameterNameIndices ) ); 27 super( pool, "MethodParameters", writeStruct( parameterNameIndices ) );
26 } 28 }
27 29
28 private static byte[] writeStruct( int attributeNameIndex, List<Integer> parameterNameIndices ) 30 public static void updateClass( MethodInfo info, List<String> names )
29 { 31 {
30 // JVM Spec says the struct looks like this: 32 // add the names to the class const pool
33 ConstPool constPool = info.getConstPool();
34 List<Integer> parameterNameIndices = new ArrayList<Integer>();
35 for( String name : names )
36 {
37 if( name != null )
38 {
39 parameterNameIndices.add( constPool.addUtf8Info( name ) );
40 }
41 else
42 {
43 parameterNameIndices.add( 0 );
44 }
45 }
46
47 // add the attribute to the method
48 info.addAttribute( new MethodParametersAttribute( constPool, parameterNameIndices ) );
49 }
50
51 private static byte[] writeStruct( List<Integer> parameterNameIndices )
52 {
53 // JVM 8 Spec says the struct looks like this:
31 // http://cr.openjdk.java.net/~mr/se/8/java-se-8-fr-spec-01/java-se-8-jvms-fr-diffs.pdf 54 // http://cr.openjdk.java.net/~mr/se/8/java-se-8-fr-spec-01/java-se-8-jvms-fr-diffs.pdf
32 // uint16 name_index -> points to UTF8 entry in constant pool that says "MethodParameters"
33 // uint32 length -> length of this struct, minus 6 bytes (ie, length of num_params and parameter array)
34 // uint8 num_params 55 // uint8 num_params
35 // for each param: 56 // for each param:
36 // uint16 name_index -> points to UTF8 entry in constant pool, or 0 for no entry 57 // uint16 name_index -> points to UTF8 entry in constant pool, or 0 for no entry
@@ -43,20 +64,13 @@ public class MethodParametersAttribute extends AttributeInfo
43 // the writeShort(), writeByte() methods will read 16,8 low-order bits from the int argument 64 // the writeShort(), writeByte() methods will read 16,8 low-order bits from the int argument
44 // as long as the int argument is in range of the unsigned short/byte type, it will be written as an unsigned short/byte 65 // as long as the int argument is in range of the unsigned short/byte type, it will be written as an unsigned short/byte
45 // if the int is out of range, the byte stream won't look the way we want and weird things will happen 66 // if the int is out of range, the byte stream won't look the way we want and weird things will happen
67 final int SIZEOF_UINT8 = 1;
46 final int SIZEOF_UINT16 = 2; 68 final int SIZEOF_UINT16 = 2;
47 final int MAX_UINT8 = ( 1 << 8 ) - 1; 69 final int MAX_UINT8 = ( 1 << 8 ) - 1;
48 final int MAX_UINT16 = ( 1 << 16 ) - 1; 70 final int MAX_UINT16 = ( 1 << 16 ) - 1;
49 final long MAX_UINT32 = ( 1 << 32 ) - 1;
50 71
51 try 72 try
52 { 73 {
53 assert( attributeNameIndex >= 0 && attributeNameIndex <= MAX_UINT16 );
54 out.writeShort( attributeNameIndex );
55
56 long length = SIZEOF_UINT16 + parameterNameIndices.size()*( SIZEOF_UINT16 + SIZEOF_UINT16 );
57 assert( length >= 0 && length <= MAX_UINT32 );
58 out.writeInt( (int)length );
59
60 assert( parameterNameIndices.size() >= 0 && parameterNameIndices.size() <= MAX_UINT8 ); 74 assert( parameterNameIndices.size() >= 0 && parameterNameIndices.size() <= MAX_UINT8 );
61 out.writeByte( parameterNameIndices.size() ); 75 out.writeByte( parameterNameIndices.size() );
62 76
@@ -70,7 +84,9 @@ public class MethodParametersAttribute extends AttributeInfo
70 } 84 }
71 85
72 out.close(); 86 out.close();
73 return buf.toByteArray(); 87 byte[] data = buf.toByteArray();
88 assert( data.length == SIZEOF_UINT8 + parameterNameIndices.size()*( SIZEOF_UINT16 + SIZEOF_UINT16 ) );
89 return data;
74 } 90 }
75 catch( IOException ex ) 91 catch( IOException ex )
76 { 92 {
diff --git a/src/cuchaz/enigma/gui/Gui.java b/src/cuchaz/enigma/gui/Gui.java
index d448dc2..3f46b6e 100644
--- a/src/cuchaz/enigma/gui/Gui.java
+++ b/src/cuchaz/enigma/gui/Gui.java
@@ -20,6 +20,7 @@ import java.awt.event.ActionEvent;
20import java.awt.event.ActionListener; 20import java.awt.event.ActionListener;
21import java.awt.event.MouseAdapter; 21import java.awt.event.MouseAdapter;
22import java.awt.event.MouseEvent; 22import java.awt.event.MouseEvent;
23import java.io.File;
23import java.io.IOException; 24import java.io.IOException;
24import java.util.Collections; 25import java.util.Collections;
25import java.util.Comparator; 26import java.util.Comparator;
@@ -54,6 +55,7 @@ import cuchaz.enigma.Constants;
54import cuchaz.enigma.analysis.SourceIndex; 55import cuchaz.enigma.analysis.SourceIndex;
55import cuchaz.enigma.mapping.ArgumentEntry; 56import cuchaz.enigma.mapping.ArgumentEntry;
56import cuchaz.enigma.mapping.ClassEntry; 57import cuchaz.enigma.mapping.ClassEntry;
58import cuchaz.enigma.mapping.Entry;
57import cuchaz.enigma.mapping.EntryPair; 59import cuchaz.enigma.mapping.EntryPair;
58import cuchaz.enigma.mapping.FieldEntry; 60import cuchaz.enigma.mapping.FieldEntry;
59import cuchaz.enigma.mapping.MethodEntry; 61import cuchaz.enigma.mapping.MethodEntry;
@@ -101,9 +103,9 @@ public class Gui
101 private JMenuItem m_closeMappingsMenu; 103 private JMenuItem m_closeMappingsMenu;
102 104
103 // state 105 // state
104 private EntryPair m_selectedEntryPair; 106 private EntryPair<Entry> m_selectedEntryPair;
105 private JFileChooser m_jarFileChooser; 107 private JFileChooser m_jarFileChooser;
106 private JFileChooser m_mappingFileChooser; 108 private JFileChooser m_mappingsFileChooser;
107 109
108 public Gui( ) 110 public Gui( )
109 { 111 {
@@ -111,7 +113,7 @@ public class Gui
111 113
112 // init file choosers 114 // init file choosers
113 m_jarFileChooser = new JFileChooser(); 115 m_jarFileChooser = new JFileChooser();
114 m_mappingFileChooser = new JFileChooser(); 116 m_mappingsFileChooser = new JFileChooser();
115 117
116 // init frame 118 // init frame
117 m_frame = new JFrame( Constants.Name ); 119 m_frame = new JFrame( Constants.Name );
@@ -279,11 +281,11 @@ public class Gui
279 @Override 281 @Override
280 public void actionPerformed( ActionEvent event ) 282 public void actionPerformed( ActionEvent event )
281 { 283 {
282 if( m_mappingFileChooser.showOpenDialog( m_frame ) == JFileChooser.APPROVE_OPTION ) 284 if( m_mappingsFileChooser.showOpenDialog( m_frame ) == JFileChooser.APPROVE_OPTION )
283 { 285 {
284 try 286 try
285 { 287 {
286 m_controller.openMappings( m_mappingFileChooser.getSelectedFile() ); 288 m_controller.openMappings( m_mappingsFileChooser.getSelectedFile() );
287 } 289 }
288 catch( IOException ex ) 290 catch( IOException ex )
289 { 291 {
@@ -304,7 +306,7 @@ public class Gui
304 { 306 {
305 try 307 try
306 { 308 {
307 m_controller.saveMappings( m_mappingFileChooser.getSelectedFile() ); 309 m_controller.saveMappings( m_mappingsFileChooser.getSelectedFile() );
308 } 310 }
309 catch( IOException ex ) 311 catch( IOException ex )
310 { 312 {
@@ -322,11 +324,11 @@ public class Gui
322 @Override 324 @Override
323 public void actionPerformed( ActionEvent event ) 325 public void actionPerformed( ActionEvent event )
324 { 326 {
325 if( m_mappingFileChooser.showSaveDialog( m_frame ) == JFileChooser.APPROVE_OPTION ) 327 if( m_mappingsFileChooser.showSaveDialog( m_frame ) == JFileChooser.APPROVE_OPTION )
326 { 328 {
327 try 329 try
328 { 330 {
329 m_controller.saveMappings( m_mappingFileChooser.getSelectedFile() ); 331 m_controller.saveMappings( m_mappingsFileChooser.getSelectedFile() );
330 m_saveMappingsMenu.setEnabled( true ); 332 m_saveMappingsMenu.setEnabled( true );
331 } 333 }
332 catch( IOException ex ) 334 catch( IOException ex )
@@ -440,9 +442,10 @@ public class Gui
440 } 442 }
441 } 443 }
442 444
443 public void setMappingsLoaded( boolean isLoaded ) 445 public void setMappingsFile( File file )
444 { 446 {
445 m_saveMappingsMenu.setEnabled( isLoaded ); 447 m_mappingsFileChooser.setSelectedFile( file );
448 m_saveMappingsMenu.setEnabled( file != null );
446 } 449 }
447 450
448 public void setSource( String source ) 451 public void setSource( String source )
@@ -493,7 +496,8 @@ public class Gui
493 redraw(); 496 redraw();
494 } 497 }
495 498
496 private void showEntryPair( EntryPair pair ) 499 @SuppressWarnings( "unchecked" )
500 private void showEntryPair( EntryPair<Entry> pair )
497 { 501 {
498 if( pair == null ) 502 if( pair == null )
499 { 503 {
@@ -514,19 +518,19 @@ public class Gui
514 m_actionPanel.add( dynamicPanel ); 518 m_actionPanel.add( dynamicPanel );
515 if( pair.deobf instanceof ClassEntry ) 519 if( pair.deobf instanceof ClassEntry )
516 { 520 {
517 showEntry( (ClassEntry)pair.deobf, dynamicPanel ); 521 showClassEntryPair( (EntryPair<? extends ClassEntry>)pair, dynamicPanel );
518 } 522 }
519 else if( pair.deobf instanceof FieldEntry ) 523 else if( pair.deobf instanceof FieldEntry )
520 { 524 {
521 showEntry( (FieldEntry)pair.deobf, dynamicPanel ); 525 showFieldEntryPair( (EntryPair<? extends FieldEntry>)pair, dynamicPanel );
522 } 526 }
523 else if( pair.deobf instanceof MethodEntry ) 527 else if( pair.deobf instanceof MethodEntry )
524 { 528 {
525 showEntry( (MethodEntry)pair.deobf, dynamicPanel ); 529 showMethodEntryPair( (EntryPair<? extends MethodEntry>)pair, dynamicPanel );
526 } 530 }
527 else if( pair.deobf instanceof ArgumentEntry ) 531 else if( pair.deobf instanceof ArgumentEntry )
528 { 532 {
529 showEntry( (ArgumentEntry)pair.deobf, dynamicPanel ); 533 showArgumentEntryPair( (EntryPair<? extends ArgumentEntry>)pair, dynamicPanel );
530 } 534 }
531 else 535 else
532 { 536 {
@@ -536,30 +540,30 @@ public class Gui
536 redraw(); 540 redraw();
537 } 541 }
538 542
539 private void showEntry( ClassEntry entry, JPanel panel ) 543 private void showClassEntryPair( EntryPair<? extends ClassEntry> pair, JPanel panel )
540 { 544 {
541 m_typeLabel.setText( "Class: " ); 545 m_typeLabel.setText( "Class: " );
542 } 546 }
543 547
544 private void showEntry( FieldEntry entry, JPanel panel ) 548 private void showFieldEntryPair( EntryPair<? extends FieldEntry> pair, JPanel panel )
545 { 549 {
546 m_typeLabel.setText( "Field: " ); 550 m_typeLabel.setText( "Field: " );
547 addNameValue( panel, "Class", entry.getClassEntry().getName() ); 551 addNameValue( panel, "Class", pair.obf.getClassEntry().getName() + " <-> " + pair.deobf.getClassEntry().getName() );
548 } 552 }
549 553
550 private void showEntry( MethodEntry entry, JPanel panel ) 554 private void showMethodEntryPair( EntryPair<? extends MethodEntry> pair, JPanel panel )
551 { 555 {
552 m_typeLabel.setText( "Method: " ); 556 m_typeLabel.setText( "Method: " );
553 addNameValue( panel, "Class", entry.getClassEntry().getName() ); 557 addNameValue( panel, "Class", pair.obf.getClassEntry().getName() + " <-> " + pair.deobf.getClassEntry().getName() );
554 addNameValue( panel, "Signature", entry.getSignature() ); 558 addNameValue( panel, "Signature", pair.obf.getSignature() + " <-> " + pair.deobf.getSignature() );
555 } 559 }
556 560
557 private void showEntry( ArgumentEntry entry, JPanel panel ) 561 private void showArgumentEntryPair( EntryPair<? extends ArgumentEntry> pair, JPanel panel )
558 { 562 {
559 m_typeLabel.setText( "Argument: " ); 563 m_typeLabel.setText( "Argument: " );
560 addNameValue( panel, "Class", entry.getMethodEntry().getClassEntry().getName() ); 564 addNameValue( panel, "Class", pair.obf.getClassEntry().getName() + " <-> " + pair.deobf.getClassEntry().getName() );
561 addNameValue( panel, "Method", entry.getMethodEntry().getName() ); 565 addNameValue( panel, "Method", pair.obf.getMethodEntry().getName() + " <-> " + pair.deobf.getMethodEntry().getName() );
562 addNameValue( panel, "Index", Integer.toString( entry.getIndex() ) ); 566 addNameValue( panel, "Index", Integer.toString( pair.obf.getIndex() ) );
563 } 567 }
564 568
565 private void addNameValue( JPanel container, String name, String value ) 569 private void addNameValue( JPanel container, String name, String value )
diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java
index ce1c31b..6704ef8 100644
--- a/src/cuchaz/enigma/gui/GuiController.java
+++ b/src/cuchaz/enigma/gui/GuiController.java
@@ -62,7 +62,7 @@ public class GuiController
62 FileReader in = new FileReader( file ); 62 FileReader in = new FileReader( file );
63 m_deobfuscator.setMappings( new MappingsReader().read( in ) ); 63 m_deobfuscator.setMappings( new MappingsReader().read( in ) );
64 in.close(); 64 in.close();
65 m_gui.setMappingsLoaded( true ); 65 m_gui.setMappingsFile( file );
66 refreshClasses(); 66 refreshClasses();
67 refreshOpenFiles(); 67 refreshOpenFiles();
68 } 68 }
@@ -78,7 +78,7 @@ public class GuiController
78 public void closeMappings( ) 78 public void closeMappings( )
79 { 79 {
80 m_deobfuscator.setMappings( null ); 80 m_deobfuscator.setMappings( null );
81 m_gui.setMappingsLoaded( false ); 81 m_gui.setMappingsFile( null );
82 refreshOpenFiles(); 82 refreshOpenFiles();
83 } 83 }
84 84
@@ -88,7 +88,7 @@ public class GuiController
88 deobfuscate( m_currentFile ); 88 deobfuscate( m_currentFile );
89 } 89 }
90 90
91 public EntryPair getEntryPair( int pos ) 91 public EntryPair<Entry> getEntryPair( int pos )
92 { 92 {
93 if( m_index == null ) 93 if( m_index == null )
94 { 94 {
@@ -100,7 +100,7 @@ public class GuiController
100 { 100 {
101 return null; 101 return null;
102 } 102 }
103 return new EntryPair( m_deobfuscator.obfuscate( deobfEntry ), deobfEntry ); 103 return new EntryPair<Entry>( m_deobfuscator.obfuscate( deobfEntry ), deobfEntry );
104 } 104 }
105 105
106 public void rename( Entry obfsEntry, String newName ) 106 public void rename( Entry obfsEntry, String newName )
diff --git a/src/cuchaz/enigma/mapping/EntryPair.java b/src/cuchaz/enigma/mapping/EntryPair.java
index e40e999..e3325b3 100644
--- a/src/cuchaz/enigma/mapping/EntryPair.java
+++ b/src/cuchaz/enigma/mapping/EntryPair.java
@@ -10,37 +10,15 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma.mapping; 11package cuchaz.enigma.mapping;
12 12
13import cuchaz.enigma.Util;
14 13
15public class EntryPair 14public class EntryPair<T extends Entry>
16{ 15{
17 public Entry obf; 16 public T obf;
18 public Entry deobf; 17 public T deobf;
19 18
20 public EntryPair( Entry obf, Entry deobf ) 19 public EntryPair( T obf, T deobf )
21 { 20 {
22 this.obf = obf; 21 this.obf = obf;
23 this.deobf = deobf; 22 this.deobf = deobf;
24 } 23 }
25
26 @Override
27 public int hashCode( )
28 {
29 return Util.combineHashesOrdered( obf, deobf );
30 }
31
32 @Override
33 public boolean equals( Object other )
34 {
35 if( other instanceof EntryPair )
36 {
37 return equals( (EntryPair)other );
38 }
39 return false;
40 }
41
42 public boolean equals( EntryPair other )
43 {
44 return obf.equals( other.obf ) && deobf.equals( other.deobf );
45 }
46} 24}
diff --git a/src/cuchaz/enigma/mapping/MethodMapping.java b/src/cuchaz/enigma/mapping/MethodMapping.java
index f2bc54d..1cdc38a 100644
--- a/src/cuchaz/enigma/mapping/MethodMapping.java
+++ b/src/cuchaz/enigma/mapping/MethodMapping.java
@@ -127,7 +127,7 @@ public class MethodMapping implements Serializable
127 { 127 {
128 buf.append( "\t\t" ); 128 buf.append( "\t\t" );
129 buf.append( argumentMapping.getIndex() ); 129 buf.append( argumentMapping.getIndex() );
130 buf.append( " <-> " ); 130 buf.append( " -> " );
131 buf.append( argumentMapping.getName() ); 131 buf.append( argumentMapping.getName() );
132 buf.append( "\n" ); 132 buf.append( "\n" );
133 } 133 }