summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar jeff2014-07-30 23:43:09 -0400
committerGravatar jeff2014-07-30 23:43:09 -0400
commit4349d22cc8abf5ec74075dde1b45c5f2f8679bbf (patch)
tree6200f39f3539e2def5010078200592141498be33
parentforgot to apply copyright notices (diff)
downloadenigma-fork-4349d22cc8abf5ec74075dde1b45c5f2f8679bbf.tar.gz
enigma-fork-4349d22cc8abf5ec74075dde1b45c5f2f8679bbf.tar.xz
enigma-fork-4349d22cc8abf5ec74075dde1b45c5f2f8679bbf.zip
switched to line-by-line mergable, human-readable file format for mappings
-rw-r--r--src/cuchaz/enigma/Deobfuscator.java31
-rw-r--r--src/cuchaz/enigma/gui/GuiController.java17
-rw-r--r--src/cuchaz/enigma/mapping/ArgumentMapping.java42
-rw-r--r--src/cuchaz/enigma/mapping/ClassMapping.java (renamed from src/cuchaz/enigma/mapping/ClassIndex.java)110
-rw-r--r--src/cuchaz/enigma/mapping/DeobfuscatedAncestries.java8
-rw-r--r--src/cuchaz/enigma/mapping/FieldEntry.java1
-rw-r--r--src/cuchaz/enigma/mapping/FieldMapping.java (renamed from src/cuchaz/enigma/mapping/ArgumentIndex.java)4
-rw-r--r--src/cuchaz/enigma/mapping/Mappings.java128
-rw-r--r--src/cuchaz/enigma/mapping/MappingsReader.java129
-rw-r--r--src/cuchaz/enigma/mapping/MappingsWriter.java75
-rw-r--r--src/cuchaz/enigma/mapping/MethodMapping.java (renamed from src/cuchaz/enigma/mapping/MethodIndex.java)49
-rw-r--r--src/cuchaz/enigma/mapping/Renamer.java125
-rw-r--r--src/cuchaz/enigma/mapping/TranslationMappings.java187
-rw-r--r--src/cuchaz/enigma/mapping/Translator.java16
14 files changed, 655 insertions, 267 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java
index bc7065f..7be5706 100644
--- a/src/cuchaz/enigma/Deobfuscator.java
+++ b/src/cuchaz/enigma/Deobfuscator.java
@@ -32,9 +32,10 @@ import cuchaz.enigma.mapping.ArgumentEntry;
32import cuchaz.enigma.mapping.ClassEntry; 32import cuchaz.enigma.mapping.ClassEntry;
33import cuchaz.enigma.mapping.Entry; 33import cuchaz.enigma.mapping.Entry;
34import cuchaz.enigma.mapping.FieldEntry; 34import cuchaz.enigma.mapping.FieldEntry;
35import cuchaz.enigma.mapping.Mappings;
35import cuchaz.enigma.mapping.MethodEntry; 36import cuchaz.enigma.mapping.MethodEntry;
37import cuchaz.enigma.mapping.Renamer;
36import cuchaz.enigma.mapping.TranslationDirection; 38import cuchaz.enigma.mapping.TranslationDirection;
37import cuchaz.enigma.mapping.TranslationMappings;
38import cuchaz.enigma.mapping.Translator; 39import cuchaz.enigma.mapping.Translator;
39 40
40public class Deobfuscator 41public class Deobfuscator
@@ -43,7 +44,8 @@ public class Deobfuscator
43 private JarFile m_jar; 44 private JarFile m_jar;
44 private DecompilerSettings m_settings; 45 private DecompilerSettings m_settings;
45 private Ancestries m_ancestries; 46 private Ancestries m_ancestries;
46 private TranslationMappings m_mappings; 47 private Mappings m_mappings;
48 private Renamer m_renamer;
47 49
48 private static Comparator<ClassFile> m_obfuscatedClassSorter; 50 private static Comparator<ClassFile> m_obfuscatedClassSorter;
49 51
@@ -89,7 +91,7 @@ public class Deobfuscator
89 m_settings.setShowSyntheticMembers( true ); 91 m_settings.setShowSyntheticMembers( true );
90 92
91 // init mappings 93 // init mappings
92 setMappings( new TranslationMappings( m_ancestries ) ); 94 setMappings( new Mappings() );
93 } 95 }
94 96
95 public String getJarName( ) 97 public String getJarName( )
@@ -97,23 +99,24 @@ public class Deobfuscator
97 return m_file.getName(); 99 return m_file.getName();
98 } 100 }
99 101
100 public TranslationMappings getMappings( ) 102 public Mappings getMappings( )
101 { 103 {
102 return m_mappings; 104 return m_mappings;
103 } 105 }
104 public void setMappings( TranslationMappings val ) 106 public void setMappings( Mappings val )
105 { 107 {
106 if( val == null ) 108 if( val == null )
107 { 109 {
108 val = new TranslationMappings( m_ancestries ); 110 val = new Mappings();
109 } 111 }
110 m_mappings = val; 112 m_mappings = val;
113 m_renamer = new Renamer( m_ancestries, m_mappings );
111 114
112 // update decompiler options 115 // update decompiler options
113 m_settings.setTypeLoader( new TranslatingTypeLoader( 116 m_settings.setTypeLoader( new TranslatingTypeLoader(
114 m_jar, 117 m_jar,
115 m_mappings.getTranslator( TranslationDirection.Deobfuscating ), 118 m_mappings.getTranslator( m_ancestries, TranslationDirection.Deobfuscating ),
116 m_mappings.getTranslator( TranslationDirection.Obfuscating ) 119 m_mappings.getTranslator( m_ancestries, TranslationDirection.Obfuscating )
117 ) ); 120 ) );
118 } 121 }
119 122
@@ -168,19 +171,19 @@ public class Deobfuscator
168 { 171 {
169 if( entry instanceof ClassEntry ) 172 if( entry instanceof ClassEntry )
170 { 173 {
171 m_mappings.setClassName( (ClassEntry)entry, newName ); 174 m_renamer.setClassName( (ClassEntry)entry, newName );
172 } 175 }
173 else if( entry instanceof FieldEntry ) 176 else if( entry instanceof FieldEntry )
174 { 177 {
175 m_mappings.setFieldName( (FieldEntry)entry, newName ); 178 m_renamer.setFieldName( (FieldEntry)entry, newName );
176 } 179 }
177 else if( entry instanceof MethodEntry ) 180 else if( entry instanceof MethodEntry )
178 { 181 {
179 m_mappings.setMethodName( (MethodEntry)entry, newName ); 182 m_renamer.setMethodName( (MethodEntry)entry, newName );
180 } 183 }
181 else if( entry instanceof ArgumentEntry ) 184 else if( entry instanceof ArgumentEntry )
182 { 185 {
183 m_mappings.setArgumentName( (ArgumentEntry)entry, newName ); 186 m_renamer.setArgumentName( (ArgumentEntry)entry, newName );
184 } 187 }
185 else 188 else
186 { 189 {
@@ -190,7 +193,7 @@ public class Deobfuscator
190 193
191 public Entry obfuscate( Entry in ) 194 public Entry obfuscate( Entry in )
192 { 195 {
193 Translator translator = m_mappings.getTranslator( TranslationDirection.Obfuscating ); 196 Translator translator = m_mappings.getTranslator( m_ancestries, TranslationDirection.Obfuscating );
194 if( in instanceof ClassEntry ) 197 if( in instanceof ClassEntry )
195 { 198 {
196 return translator.translateEntry( (ClassEntry)in ); 199 return translator.translateEntry( (ClassEntry)in );
@@ -215,7 +218,7 @@ public class Deobfuscator
215 218
216 public Entry deobfuscate( Entry in ) 219 public Entry deobfuscate( Entry in )
217 { 220 {
218 Translator translator = m_mappings.getTranslator( TranslationDirection.Deobfuscating ); 221 Translator translator = m_mappings.getTranslator( m_ancestries, TranslationDirection.Deobfuscating );
219 if( in instanceof ClassEntry ) 222 if( in instanceof ClassEntry )
220 { 223 {
221 return translator.translateEntry( (ClassEntry)in ); 224 return translator.translateEntry( (ClassEntry)in );
diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java
index 5df2d43..fb22b96 100644
--- a/src/cuchaz/enigma/gui/GuiController.java
+++ b/src/cuchaz/enigma/gui/GuiController.java
@@ -11,8 +11,8 @@
11package cuchaz.enigma.gui; 11package cuchaz.enigma.gui;
12 12
13import java.io.File; 13import java.io.File;
14import java.io.FileInputStream; 14import java.io.FileReader;
15import java.io.FileOutputStream; 15import java.io.FileWriter;
16import java.io.IOException; 16import java.io.IOException;
17 17
18import cuchaz.enigma.ClassFile; 18import cuchaz.enigma.ClassFile;
@@ -22,7 +22,8 @@ import cuchaz.enigma.analysis.SourceIndex;
22import cuchaz.enigma.mapping.ClassEntry; 22import cuchaz.enigma.mapping.ClassEntry;
23import cuchaz.enigma.mapping.Entry; 23import cuchaz.enigma.mapping.Entry;
24import cuchaz.enigma.mapping.EntryPair; 24import cuchaz.enigma.mapping.EntryPair;
25import cuchaz.enigma.mapping.TranslationMappings; 25import cuchaz.enigma.mapping.MappingsReader;
26import cuchaz.enigma.mapping.MappingsWriter;
26 27
27public class GuiController 28public class GuiController
28{ 29{
@@ -56,17 +57,19 @@ public class GuiController
56 public void openMappings( File file ) 57 public void openMappings( File file )
57 throws IOException 58 throws IOException
58 { 59 {
59 FileInputStream in = new FileInputStream( file ); 60 FileReader in = new FileReader( file );
60 m_deobfuscator.setMappings( TranslationMappings.newFromStream( in ) ); 61 m_deobfuscator.setMappings( new MappingsReader().read( in ) );
61 in.close(); 62 in.close();
63 // TEMP
64 System.out.println( m_deobfuscator.getMappings() );
62 refreshOpenFiles(); 65 refreshOpenFiles();
63 } 66 }
64 67
65 public void saveMappings( File file ) 68 public void saveMappings( File file )
66 throws IOException 69 throws IOException
67 { 70 {
68 FileOutputStream out = new FileOutputStream( file ); 71 FileWriter out = new FileWriter( file );
69 m_deobfuscator.getMappings().write( out ); 72 new MappingsWriter().write( out, m_deobfuscator.getMappings() );
70 out.close(); 73 out.close();
71 } 74 }
72 75
diff --git a/src/cuchaz/enigma/mapping/ArgumentMapping.java b/src/cuchaz/enigma/mapping/ArgumentMapping.java
new file mode 100644
index 0000000..d5e020a
--- /dev/null
+++ b/src/cuchaz/enigma/mapping/ArgumentMapping.java
@@ -0,0 +1,42 @@
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.mapping;
12
13import java.io.Serializable;
14
15public class ArgumentMapping implements Serializable
16{
17 private static final long serialVersionUID = 8610742471440861315L;
18
19 private int m_index;
20 private String m_name;
21
22 // NOTE: this argument order is important for the MethodReader/MethodWriter
23 public ArgumentMapping( int index, String name )
24 {
25 m_index = index;
26 m_name = name;
27 }
28
29 public int getIndex( )
30 {
31 return m_index;
32 }
33
34 public String getName( )
35 {
36 return m_name;
37 }
38 public void setName( String val )
39 {
40 m_name = val;
41 }
42}
diff --git a/src/cuchaz/enigma/mapping/ClassIndex.java b/src/cuchaz/enigma/mapping/ClassMapping.java
index 699807b..3ba3569 100644
--- a/src/cuchaz/enigma/mapping/ClassIndex.java
+++ b/src/cuchaz/enigma/mapping/ClassMapping.java
@@ -14,24 +14,25 @@ import java.io.Serializable;
14import java.util.Map; 14import java.util.Map;
15 15
16import com.beust.jcommander.internal.Maps; 16import com.beust.jcommander.internal.Maps;
17import com.google.common.collect.BiMap;
18import com.google.common.collect.HashBiMap;
19 17
20public class ClassIndex implements Serializable 18public class ClassMapping implements Serializable
21{ 19{
22 private static final long serialVersionUID = -5148491146902340107L; 20 private static final long serialVersionUID = -5148491146902340107L;
23 21
24 private String m_obfName; 22 private String m_obfName;
25 private String m_deobfName; 23 private String m_deobfName;
26 private BiMap<String,String> m_fieldsObfToDeobf; 24 private Map<String,FieldMapping> m_fieldsByObf;
27 private Map<String,MethodIndex> m_methodsByObf; 25 private Map<String,FieldMapping> m_fieldsByDeobf;
28 private Map<String,MethodIndex> m_methodsByDeobf; 26 private Map<String,MethodMapping> m_methodsByObf;
27 private Map<String,MethodMapping> m_methodsByDeobf;
29 28
30 public ClassIndex( String obfName, String deobfName ) 29 // NOTE: this argument order is important for the MethodReader/MethodWriter
30 public ClassMapping( String obfName, String deobfName )
31 { 31 {
32 m_obfName = obfName; 32 m_obfName = obfName;
33 m_deobfName = deobfName; 33 m_deobfName = deobfName;
34 m_fieldsObfToDeobf = HashBiMap.create(); 34 m_fieldsByObf = Maps.newHashMap();
35 m_fieldsByDeobf = Maps.newHashMap();
35 m_methodsByObf = Maps.newHashMap(); 36 m_methodsByObf = Maps.newHashMap();
36 m_methodsByDeobf = Maps.newHashMap(); 37 m_methodsByDeobf = Maps.newHashMap();
37 } 38 }
@@ -49,34 +50,91 @@ public class ClassIndex implements Serializable
49 { 50 {
50 m_deobfName = val; 51 m_deobfName = val;
51 } 52 }
53
54 public Iterable<FieldMapping> fields( )
55 {
56 assert( m_fieldsByObf.size() == m_fieldsByDeobf.size() );
57 return m_fieldsByObf.values();
58 }
59
60 protected void addFieldMapping( FieldMapping fieldMapping )
61 {
62 m_fieldsByObf.put( fieldMapping.getObfName(), fieldMapping );
63 m_fieldsByDeobf.put( fieldMapping.getDeobfName(), fieldMapping );
64 }
65
66 public Iterable<MethodMapping> methods( )
67 {
68 assert( m_methodsByObf.size() == m_methodsByDeobf.size() );
69 return m_methodsByObf.values();
70 }
71
72 protected void addMethodMapping( MethodMapping methodMapping )
73 {
74 m_methodsByObf.put( getMethodKey( methodMapping.getObfName(), methodMapping.getObfSignature() ), methodMapping );
75 m_methodsByDeobf.put( getMethodKey( methodMapping.getDeobfName(), methodMapping.getDeobfSignature() ), methodMapping );
76 }
52 77
53 public String getObfFieldName( String deobfName ) 78 public String getObfFieldName( String deobfName )
54 { 79 {
55 return m_fieldsObfToDeobf.inverse().get( deobfName ); 80 FieldMapping fieldMapping = m_fieldsByDeobf.get( deobfName );
81 if( fieldMapping != null )
82 {
83 return fieldMapping.getObfName();
84 }
85 return null;
56 } 86 }
57 87
58 public String getDeobfFieldName( String obfName ) 88 public String getDeobfFieldName( String obfName )
59 { 89 {
60 return m_fieldsObfToDeobf.get( obfName ); 90 FieldMapping fieldMapping = m_fieldsByObf.get( obfName );
91 if( fieldMapping != null )
92 {
93 return fieldMapping.getDeobfName();
94 }
95 return null;
61 } 96 }
62 97
63 public void setFieldName( String obfName, String deobfName ) 98 public void setFieldName( String obfName, String deobfName )
64 { 99 {
65 m_fieldsObfToDeobf.put( obfName, deobfName ); 100 if( deobfName == null )
101 {
102 throw new IllegalArgumentException( "deobf name cannot be null!" );
103 }
104
105 FieldMapping fieldMapping = m_fieldsByObf.get( obfName );
106 if( fieldMapping == null )
107 {
108 fieldMapping = new FieldMapping( obfName, deobfName );
109 m_fieldsByObf.put( obfName, fieldMapping );
110 m_fieldsByDeobf.put( deobfName, fieldMapping );
111 }
112
113 m_fieldsByDeobf.remove( fieldMapping.getDeobfName() );
114 fieldMapping.setDeobfName( deobfName );
115 m_fieldsByDeobf.put( deobfName, fieldMapping );
66 } 116 }
67 117
68 public MethodIndex getMethodByObf( String obfName, String signature ) 118 public MethodMapping getMethodByObf( String obfName, String signature )
69 { 119 {
70 return m_methodsByObf.get( getMethodKey( obfName, signature ) ); 120 return m_methodsByObf.get( getMethodKey( obfName, signature ) );
71 } 121 }
72 122
73 public MethodIndex getMethodByDeobf( String deobfName, String signature ) 123 public MethodMapping getMethodByDeobf( String deobfName, String signature )
74 { 124 {
75 return m_methodsByDeobf.get( getMethodKey( deobfName, signature ) ); 125 return m_methodsByDeobf.get( getMethodKey( deobfName, signature ) );
76 } 126 }
77 127
78 private String getMethodKey( String name, String signature ) 128 private String getMethodKey( String name, String signature )
79 { 129 {
130 if( name == null )
131 {
132 throw new IllegalArgumentException( "name cannot be null!" );
133 }
134 if( signature == null )
135 {
136 throw new IllegalArgumentException( "signature cannot be null!" );
137 }
80 return name + signature; 138 return name + signature;
81 } 139 }
82 140
@@ -87,7 +145,7 @@ public class ClassIndex implements Serializable
87 throw new IllegalArgumentException( "deobf name cannot be null!" ); 145 throw new IllegalArgumentException( "deobf name cannot be null!" );
88 } 146 }
89 147
90 MethodIndex methodIndex = m_methodsByObf.get( getMethodKey( obfName, obfSignature ) ); 148 MethodMapping methodIndex = m_methodsByObf.get( getMethodKey( obfName, obfSignature ) );
91 if( methodIndex == null ) 149 if( methodIndex == null )
92 { 150 {
93 methodIndex = createMethodIndex( obfName, obfSignature ); 151 methodIndex = createMethodIndex( obfName, obfSignature );
@@ -101,30 +159,30 @@ public class ClassIndex implements Serializable
101 159
102 public void updateDeobfMethodSignatures( Translator translator ) 160 public void updateDeobfMethodSignatures( Translator translator )
103 { 161 {
104 for( MethodIndex methodIndex : m_methodsByObf.values() ) 162 for( MethodMapping methodIndex : m_methodsByObf.values() )
105 { 163 {
106 methodIndex.setDeobfSignature( translator.translateSignature( methodIndex.getObfSignature() ) ); 164 methodIndex.setDeobfSignature( translator.translateSignature( methodIndex.getObfSignature() ) );
107 } 165 }
108 } 166 }
109 167
110 public void setArgumentName( String obfMethodName, String obfMethodSignature, int index, String obfName, String deobfName ) 168 public void setArgumentName( String obfMethodName, String obfMethodSignature, int argumentIndex, String argumentName )
111 { 169 {
112 if( deobfName == null ) 170 if( argumentName == null )
113 { 171 {
114 throw new IllegalArgumentException( "deobf name cannot be null!" ); 172 throw new IllegalArgumentException( "argument name cannot be null!" );
115 } 173 }
116 174
117 MethodIndex methodIndex = m_methodsByObf.get( getMethodKey( obfMethodName, obfMethodSignature ) ); 175 MethodMapping methodIndex = m_methodsByObf.get( getMethodKey( obfMethodName, obfMethodSignature ) );
118 if( methodIndex == null ) 176 if( methodIndex == null )
119 { 177 {
120 methodIndex = createMethodIndex( obfMethodName, obfMethodSignature ); 178 methodIndex = createMethodIndex( obfMethodName, obfMethodSignature );
121 } 179 }
122 methodIndex.setArgumentName( index, obfName, deobfName ); 180 methodIndex.setArgumentName( argumentIndex, argumentName );
123 } 181 }
124 182
125 private MethodIndex createMethodIndex( String obfName, String obfSignature ) 183 private MethodMapping createMethodIndex( String obfName, String obfSignature )
126 { 184 {
127 MethodIndex methodIndex = new MethodIndex( obfName, obfSignature, obfName, obfSignature ); 185 MethodMapping methodIndex = new MethodMapping( obfName, obfName, obfSignature, obfSignature );
128 String key = getMethodKey( obfName, obfSignature ); 186 String key = getMethodKey( obfName, obfSignature );
129 m_methodsByObf.put( key, methodIndex ); 187 m_methodsByObf.put( key, methodIndex );
130 m_methodsByDeobf.put( key, methodIndex ); 188 m_methodsByDeobf.put( key, methodIndex );
@@ -140,16 +198,16 @@ public class ClassIndex implements Serializable
140 buf.append( m_deobfName ); 198 buf.append( m_deobfName );
141 buf.append( "\n" ); 199 buf.append( "\n" );
142 buf.append( "Fields:\n" ); 200 buf.append( "Fields:\n" );
143 for( Map.Entry<String,String> entry : m_fieldsObfToDeobf.entrySet() ) 201 for( FieldMapping fieldMapping : fields() )
144 { 202 {
145 buf.append( "\t" ); 203 buf.append( "\t" );
146 buf.append( entry.getKey() ); 204 buf.append( fieldMapping.getObfName() );
147 buf.append( " <-> " ); 205 buf.append( " <-> " );
148 buf.append( entry.getValue() ); 206 buf.append( fieldMapping.getDeobfName() );
149 buf.append( "\n" ); 207 buf.append( "\n" );
150 } 208 }
151 buf.append( "Methods:\n" ); 209 buf.append( "Methods:\n" );
152 for( MethodIndex methodIndex : m_methodsByObf.values() ) 210 for( MethodMapping methodIndex : m_methodsByObf.values() )
153 { 211 {
154 buf.append( methodIndex.toString() ); 212 buf.append( methodIndex.toString() );
155 buf.append( "\n" ); 213 buf.append( "\n" );
diff --git a/src/cuchaz/enigma/mapping/DeobfuscatedAncestries.java b/src/cuchaz/enigma/mapping/DeobfuscatedAncestries.java
index 5320f11..dcb0741 100644
--- a/src/cuchaz/enigma/mapping/DeobfuscatedAncestries.java
+++ b/src/cuchaz/enigma/mapping/DeobfuscatedAncestries.java
@@ -17,10 +17,10 @@ public class DeobfuscatedAncestries extends Ancestries
17 private static final long serialVersionUID = 8316248774892618324L; 17 private static final long serialVersionUID = 8316248774892618324L;
18 18
19 private Ancestries m_ancestries; 19 private Ancestries m_ancestries;
20 private Map<String,ClassIndex> m_classesByObf; 20 private Map<String,ClassMapping> m_classesByObf;
21 private Map<String,ClassIndex> m_classesByDeobf; 21 private Map<String,ClassMapping> m_classesByDeobf;
22 22
23 protected DeobfuscatedAncestries( Ancestries ancestries, Map<String,ClassIndex> classesByObf, Map<String,ClassIndex> classesByDeobf ) 23 protected DeobfuscatedAncestries( Ancestries ancestries, Map<String,ClassMapping> classesByObf, Map<String,ClassMapping> classesByDeobf )
24 { 24 {
25 m_ancestries = ancestries; 25 m_ancestries = ancestries;
26 m_classesByObf = classesByObf; 26 m_classesByObf = classesByObf;
@@ -31,7 +31,7 @@ public class DeobfuscatedAncestries extends Ancestries
31 public String getSuperclassName( String deobfClassName ) 31 public String getSuperclassName( String deobfClassName )
32 { 32 {
33 // obfuscate the class name 33 // obfuscate the class name
34 ClassIndex classIndex = m_classesByDeobf.get( deobfClassName ); 34 ClassMapping classIndex = m_classesByDeobf.get( deobfClassName );
35 if( classIndex == null ) 35 if( classIndex == null )
36 { 36 {
37 return null; 37 return null;
diff --git a/src/cuchaz/enigma/mapping/FieldEntry.java b/src/cuchaz/enigma/mapping/FieldEntry.java
index b9f4239..eefc4c4 100644
--- a/src/cuchaz/enigma/mapping/FieldEntry.java
+++ b/src/cuchaz/enigma/mapping/FieldEntry.java
@@ -21,6 +21,7 @@ public class FieldEntry implements Entry, Serializable
21 private ClassEntry m_classEntry; 21 private ClassEntry m_classEntry;
22 private String m_name; 22 private String m_name;
23 23
24 // NOTE: this argument order is important for the MethodReader/MethodWriter
24 public FieldEntry( ClassEntry classEntry, String name ) 25 public FieldEntry( ClassEntry classEntry, String name )
25 { 26 {
26 if( classEntry == null ) 27 if( classEntry == null )
diff --git a/src/cuchaz/enigma/mapping/ArgumentIndex.java b/src/cuchaz/enigma/mapping/FieldMapping.java
index 57488d1..618f45c 100644
--- a/src/cuchaz/enigma/mapping/ArgumentIndex.java
+++ b/src/cuchaz/enigma/mapping/FieldMapping.java
@@ -12,14 +12,14 @@ package cuchaz.enigma.mapping;
12 12
13import java.io.Serializable; 13import java.io.Serializable;
14 14
15public class ArgumentIndex implements Serializable 15public class FieldMapping implements Serializable
16{ 16{
17 private static final long serialVersionUID = 8610742471440861315L; 17 private static final long serialVersionUID = 8610742471440861315L;
18 18
19 private String m_obfName; 19 private String m_obfName;
20 private String m_deobfName; 20 private String m_deobfName;
21 21
22 public ArgumentIndex( String obfName, String deobfName ) 22 public FieldMapping( String obfName, String deobfName )
23 { 23 {
24 m_obfName = obfName; 24 m_obfName = obfName;
25 m_deobfName = deobfName; 25 m_deobfName = deobfName;
diff --git a/src/cuchaz/enigma/mapping/Mappings.java b/src/cuchaz/enigma/mapping/Mappings.java
new file mode 100644
index 0000000..2a39057
--- /dev/null
+++ b/src/cuchaz/enigma/mapping/Mappings.java
@@ -0,0 +1,128 @@
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.mapping;
12
13import java.io.IOException;
14import java.io.InputStream;
15import java.io.ObjectInputStream;
16import java.io.Serializable;
17import java.util.Map;
18import java.util.zip.GZIPInputStream;
19
20import com.beust.jcommander.internal.Maps;
21
22import cuchaz.enigma.Util;
23
24public class Mappings implements Serializable
25{
26 private static final long serialVersionUID = 4649790259460259026L;
27
28 protected Map<String,ClassMapping> m_classesByObf;
29 protected Map<String,ClassMapping> m_classesByDeobf;
30
31 public Mappings( )
32 {
33 m_classesByObf = Maps.newHashMap();
34 m_classesByDeobf = Maps.newHashMap();
35 }
36
37 public Mappings( Iterable<ClassMapping> classes )
38 {
39 this();
40
41 for( ClassMapping classMapping : classes )
42 {
43 m_classesByObf.put( classMapping.getObfName(), classMapping );
44 m_classesByDeobf.put( classMapping.getDeobfName(), classMapping );
45 }
46 }
47
48 public static Mappings newFromResource( String resource )
49 throws IOException
50 {
51 InputStream in = null;
52 try
53 {
54 in = Mappings.class.getResourceAsStream( resource );
55 return newFromStream( in );
56 }
57 finally
58 {
59 Util.closeQuietly( in );
60 }
61 }
62
63 public Iterable<ClassMapping> classes( )
64 {
65 assert( m_classesByObf.size() == m_classesByDeobf.size() );
66 return m_classesByObf.values();
67 }
68
69 protected void addClassMapping( ClassMapping classMapping )
70 {
71 m_classesByObf.put( classMapping.getObfName(), classMapping );
72 m_classesByDeobf.put( classMapping.getDeobfName(), classMapping );
73 }
74
75 public ClassMapping getClassByObf( ClassEntry entry )
76 {
77 return getClassByObf( entry.getName() );
78 }
79
80 public ClassMapping getClassByObf( String obfName )
81 {
82 return m_classesByObf.get( obfName );
83 }
84
85 public ClassMapping getClassByDeobf( ClassEntry entry )
86 {
87 return getClassByObf( entry.getName() );
88 }
89
90 public ClassMapping getClassByDeobf( String deobfName )
91 {
92 return m_classesByDeobf.get( deobfName );
93 }
94
95 public Translator getTranslator( Ancestries ancestries, TranslationDirection direction )
96 {
97 return new Translator(
98 direction,
99 direction.choose( m_classesByObf, m_classesByDeobf ),
100 direction.choose( ancestries, new DeobfuscatedAncestries( ancestries, m_classesByObf, m_classesByDeobf ) )
101 );
102 }
103
104 public static Mappings newFromStream( InputStream in )
105 throws IOException
106 {
107 try
108 {
109 return (Mappings)new ObjectInputStream( new GZIPInputStream( in ) ).readObject();
110 }
111 catch( ClassNotFoundException ex )
112 {
113 throw new Error( ex );
114 }
115 }
116
117 @Override
118 public String toString( )
119 {
120 StringBuilder buf = new StringBuilder();
121 for( ClassMapping classMapping : m_classesByObf.values() )
122 {
123 buf.append( classMapping.toString() );
124 buf.append( "\n" );
125 }
126 return buf.toString();
127 }
128}
diff --git a/src/cuchaz/enigma/mapping/MappingsReader.java b/src/cuchaz/enigma/mapping/MappingsReader.java
new file mode 100644
index 0000000..b039409
--- /dev/null
+++ b/src/cuchaz/enigma/mapping/MappingsReader.java
@@ -0,0 +1,129 @@
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.mapping;
12
13import java.io.BufferedReader;
14import java.io.IOException;
15import java.io.Reader;
16import java.util.NoSuchElementException;
17import java.util.Scanner;
18
19import cuchaz.enigma.Util;
20
21public class MappingsReader
22{
23 public Mappings read( Reader in )
24 throws IOException
25 {
26 return read( new BufferedReader( in ) );
27 }
28
29 public Mappings read( BufferedReader in )
30 throws IOException
31 {
32 Mappings mappings = new Mappings();
33 ClassMapping classMapping = null;
34 MethodMapping methodMapping = null;
35
36 int lineNumber = 0;
37 String line = null;
38 while( ( line = in.readLine() ) != null )
39 {
40 lineNumber++;
41
42 // strip comments
43 int commentPos = line.indexOf( '#' );
44 if( commentPos >= 0 )
45 {
46 line = line.substring( 0, commentPos );
47 }
48
49 // skip blank lines
50 line = line.trim();
51 if( line.length() <= 0 )
52 {
53 continue;
54 }
55
56 Scanner scanner = new Scanner( line );
57 try
58 {
59 while( scanner.hasNext() )
60 {
61 // read the first token
62 String token = scanner.next();
63
64 if( token.equalsIgnoreCase( "CLASS" ) )
65 {
66 classMapping = readClass( scanner );
67 mappings.addClassMapping( classMapping );
68 methodMapping = null;
69 }
70 else if( token.equalsIgnoreCase( "FIELD" ) )
71 {
72 if( classMapping == null )
73 {
74 throw new IllegalArgumentException( "Line " + lineNumber + ": Unexpected FIELD entry here!" );
75 }
76 classMapping.addFieldMapping( readField( scanner ) );
77 }
78 else if( token.equalsIgnoreCase( "METHOD" ) )
79 {
80 if( classMapping == null )
81 {
82 throw new IllegalArgumentException( "Line " + lineNumber + ": Unexpected METHOD entry here!" );
83 }
84 methodMapping = readMethod( scanner );
85 classMapping.addMethodMapping( methodMapping );
86 }
87 else if( token.equalsIgnoreCase( "ARG" ) )
88 {
89 if( classMapping == null || methodMapping == null )
90 {
91 throw new IllegalArgumentException( "Line " + lineNumber + ": Unexpected ARG entry here!" );
92 }
93 methodMapping.addArgumentMapping( readArgument( scanner ) );
94 }
95 }
96 }
97 catch( NoSuchElementException ex )
98 {
99 throw new IllegalArgumentException( "Line " + lineNumber + ": malformed line!" );
100 }
101 finally
102 {
103 Util.closeQuietly( scanner );
104 }
105 }
106
107 return mappings;
108 }
109
110 private ArgumentMapping readArgument( Scanner scanner )
111 {
112 return new ArgumentMapping( scanner.nextInt(), scanner.next() );
113 }
114
115 private ClassMapping readClass( Scanner scanner )
116 {
117 return new ClassMapping( scanner.next(), scanner.next() );
118 }
119
120 private FieldMapping readField( Scanner scanner )
121 {
122 return new FieldMapping( scanner.next(), scanner.next() );
123 }
124
125 private MethodMapping readMethod( Scanner scanner )
126 {
127 return new MethodMapping( scanner.next(), scanner.next(), scanner.next(), scanner.next() );
128 }
129}
diff --git a/src/cuchaz/enigma/mapping/MappingsWriter.java b/src/cuchaz/enigma/mapping/MappingsWriter.java
new file mode 100644
index 0000000..2086368
--- /dev/null
+++ b/src/cuchaz/enigma/mapping/MappingsWriter.java
@@ -0,0 +1,75 @@
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.mapping;
12
13import java.io.IOException;
14import java.io.PrintWriter;
15import java.io.Writer;
16
17public class MappingsWriter
18{
19 public void write( Writer out, Mappings mappings )
20 throws IOException
21 {
22 write( new PrintWriter( out ), mappings );
23 }
24
25 public void write( PrintWriter out, Mappings mappings )
26 throws IOException
27 {
28 for( ClassMapping classMapping : mappings.classes() )
29 {
30 write( out, classMapping );
31 }
32 }
33
34 public void write( PrintWriter out, ClassMapping classMapping )
35 throws IOException
36 {
37 out.format( "CLASS %s %s\n", classMapping.getObfName(), classMapping.getDeobfName() );
38
39 for( FieldMapping fieldMapping : classMapping.fields() )
40 {
41 write( out, fieldMapping );
42 }
43
44 for( MethodMapping methodMapping : classMapping.methods() )
45 {
46 write( out, methodMapping );
47 }
48 }
49
50 public void write( PrintWriter out, FieldMapping fieldMapping )
51 throws IOException
52 {
53 out.format( "\tFIELD %s %s\n", fieldMapping.getObfName(), fieldMapping.getDeobfName() );
54 }
55
56 public void write( PrintWriter out, MethodMapping methodMapping )
57 throws IOException
58 {
59 out.format( "\tMETHOD %s %s %s %s\n",
60 methodMapping.getObfName(), methodMapping.getDeobfName(),
61 methodMapping.getObfSignature(), methodMapping.getDeobfSignature()
62 );
63
64 for( ArgumentMapping argumentMapping : methodMapping.arguments() )
65 {
66 write( out, argumentMapping );
67 }
68 }
69
70 public void write( PrintWriter out, ArgumentMapping argumentMapping )
71 throws IOException
72 {
73 out.format( "\t\tARG %d %s\n", argumentMapping.getIndex(), argumentMapping.getName() );
74 }
75}
diff --git a/src/cuchaz/enigma/mapping/MethodIndex.java b/src/cuchaz/enigma/mapping/MethodMapping.java
index f965355..f2bc54d 100644
--- a/src/cuchaz/enigma/mapping/MethodIndex.java
+++ b/src/cuchaz/enigma/mapping/MethodMapping.java
@@ -14,7 +14,7 @@ import java.io.Serializable;
14import java.util.Map; 14import java.util.Map;
15import java.util.TreeMap; 15import java.util.TreeMap;
16 16
17public class MethodIndex implements Serializable 17public class MethodMapping implements Serializable
18{ 18{
19 private static final long serialVersionUID = -4409570216084263978L; 19 private static final long serialVersionUID = -4409570216084263978L;
20 20
@@ -22,15 +22,16 @@ public class MethodIndex implements Serializable
22 private String m_deobfName; 22 private String m_deobfName;
23 private String m_obfSignature; 23 private String m_obfSignature;
24 private String m_deobfSignature; 24 private String m_deobfSignature;
25 private Map<Integer,ArgumentIndex> m_arguments; 25 private Map<Integer,ArgumentMapping> m_arguments;
26 26
27 public MethodIndex( String obfName, String obfSignature, String deobfName, String deobfSignature ) 27 // NOTE: this argument order is important for the MethodReader/MethodWriter
28 public MethodMapping( String obfName, String deobfName, String obfSignature, String deobfSignature )
28 { 29 {
29 m_obfName = obfName; 30 m_obfName = obfName;
30 m_deobfName = deobfName; 31 m_deobfName = deobfName;
31 m_obfSignature = obfSignature; 32 m_obfSignature = obfSignature;
32 m_deobfSignature = deobfSignature; 33 m_deobfSignature = deobfSignature;
33 m_arguments = new TreeMap<Integer,ArgumentIndex>(); 34 m_arguments = new TreeMap<Integer,ArgumentMapping>();
34 } 35 }
35 36
36 public String getObfName( ) 37 public String getObfName( )
@@ -61,12 +62,22 @@ public class MethodIndex implements Serializable
61 m_deobfSignature = val; 62 m_deobfSignature = val;
62 } 63 }
63 64
65 public Iterable<ArgumentMapping> arguments( )
66 {
67 return m_arguments.values();
68 }
69
70 protected void addArgumentMapping( ArgumentMapping argumentMapping )
71 {
72 m_arguments.put( argumentMapping.getIndex(), argumentMapping );
73 }
74
64 public String getObfArgumentName( int index ) 75 public String getObfArgumentName( int index )
65 { 76 {
66 ArgumentIndex argumentIndex = m_arguments.get( index ); 77 ArgumentMapping argumentMapping = m_arguments.get( index );
67 if( argumentIndex != null ) 78 if( argumentMapping != null )
68 { 79 {
69 return argumentIndex.getObfName(); 80 return argumentMapping.getName();
70 } 81 }
71 82
72 return null; 83 return null;
@@ -74,26 +85,26 @@ public class MethodIndex implements Serializable
74 85
75 public String getDeobfArgumentName( int index ) 86 public String getDeobfArgumentName( int index )
76 { 87 {
77 ArgumentIndex argumentIndex = m_arguments.get( index ); 88 ArgumentMapping argumentMapping = m_arguments.get( index );
78 if( argumentIndex != null ) 89 if( argumentMapping != null )
79 { 90 {
80 return argumentIndex.getDeobfName(); 91 return argumentMapping.getName();
81 } 92 }
82 93
83 return null; 94 return null;
84 } 95 }
85 96
86 public void setArgumentName( int index, String obfName, String deobfName ) 97 public void setArgumentName( int index, String name )
87 { 98 {
88 ArgumentIndex argumentIndex = m_arguments.get( index ); 99 ArgumentMapping argumentMapping = m_arguments.get( index );
89 if( argumentIndex == null ) 100 if( argumentMapping == null )
90 { 101 {
91 argumentIndex = new ArgumentIndex( obfName, deobfName ); 102 argumentMapping = new ArgumentMapping( index, name );
92 m_arguments.put( index, argumentIndex ); 103 m_arguments.put( index, argumentMapping );
93 } 104 }
94 else 105 else
95 { 106 {
96 argumentIndex.setDeobfName( deobfName ); 107 argumentMapping.setName( name );
97 } 108 }
98 } 109 }
99 110
@@ -112,12 +123,12 @@ public class MethodIndex implements Serializable
112 buf.append( m_deobfSignature ); 123 buf.append( m_deobfSignature );
113 buf.append( "\n" ); 124 buf.append( "\n" );
114 buf.append( "\tArguments:\n" ); 125 buf.append( "\tArguments:\n" );
115 for( ArgumentIndex argumentIndex : m_arguments.values() ) 126 for( ArgumentMapping argumentMapping : m_arguments.values() )
116 { 127 {
117 buf.append( "\t\t" ); 128 buf.append( "\t\t" );
118 buf.append( argumentIndex.getObfName() ); 129 buf.append( argumentMapping.getIndex() );
119 buf.append( " <-> " ); 130 buf.append( " <-> " );
120 buf.append( argumentIndex.getDeobfName() ); 131 buf.append( argumentMapping.getName() );
121 buf.append( "\n" ); 132 buf.append( "\n" );
122 } 133 }
123 return buf.toString(); 134 return buf.toString();
diff --git a/src/cuchaz/enigma/mapping/Renamer.java b/src/cuchaz/enigma/mapping/Renamer.java
new file mode 100644
index 0000000..4a648ad
--- /dev/null
+++ b/src/cuchaz/enigma/mapping/Renamer.java
@@ -0,0 +1,125 @@
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.mapping;
12
13import java.io.IOException;
14import java.io.ObjectOutputStream;
15import java.io.OutputStream;
16import java.util.zip.GZIPOutputStream;
17
18public class Renamer
19{
20 private Ancestries m_ancestries;
21 private Mappings m_mappings;
22
23 public Renamer( Ancestries ancestries, Mappings mappings )
24 {
25 m_ancestries = ancestries;
26 m_mappings = mappings;
27 }
28
29 public void setClassName( ClassEntry obf, String deobfName )
30 {
31 ClassMapping classMapping = m_mappings.m_classesByObf.get( obf.getName() );
32 if( classMapping == null )
33 {
34 classMapping = createClassMapping( obf );
35 }
36
37 m_mappings.m_classesByDeobf.remove( classMapping.getDeobfName() );
38 classMapping.setDeobfName( deobfName );
39 m_mappings.m_classesByDeobf.put( deobfName, classMapping );
40
41 updateDeobfMethodSignatures();
42
43 // TEMP
44 String translatedName = m_mappings.getTranslator( m_ancestries, TranslationDirection.Deobfuscating ).translate( obf );
45 assert( translatedName != null && translatedName.equals( deobfName ) );
46 }
47
48 public void setFieldName( FieldEntry obf, String deobfName )
49 {
50 ClassMapping classMapping = m_mappings.m_classesByObf.get( obf.getClassName() );
51 if( classMapping == null )
52 {
53 classMapping = createClassMapping( obf.getClassEntry() );
54 }
55
56 classMapping.setFieldName( obf.getName(), deobfName );
57
58 // TEMP
59 System.out.println( classMapping );
60 String translatedName = m_mappings.getTranslator( m_ancestries, TranslationDirection.Deobfuscating ).translate( obf );
61 assert( translatedName != null && translatedName.equals( deobfName ) );
62 }
63
64 public void setMethodName( MethodEntry obf, String deobfName )
65 {
66 ClassMapping classMapping = m_mappings.m_classesByObf.get( obf.getClassName() );
67 if( classMapping == null )
68 {
69 classMapping = createClassMapping( obf.getClassEntry() );
70 }
71
72 String deobfSignature = m_mappings.getTranslator( m_ancestries, TranslationDirection.Deobfuscating ).translateSignature( obf.getSignature() );
73 classMapping.setMethodNameAndSignature( obf.getName(), obf.getSignature(), deobfName, deobfSignature );
74
75 // TODO: update ancestor/descendant methods in other classes in the inheritance hierarchy too
76
77 // TEMP
78 System.out.println( classMapping );
79 String translatedName = m_mappings.getTranslator( m_ancestries, TranslationDirection.Deobfuscating ).translate( obf );
80 assert( translatedName != null && translatedName.equals( deobfName ) );
81 }
82
83 public void setArgumentName( ArgumentEntry obf, String deobfName )
84 {
85 ClassMapping classMapping = m_mappings.m_classesByObf.get( obf.getClassName() );
86 if( classMapping == null )
87 {
88 classMapping = createClassMapping( obf.getClassEntry() );
89 }
90
91 classMapping.setArgumentName( obf.getMethodName(), obf.getMethodSignature(), obf.getIndex(), deobfName );
92
93 // TEMP
94 System.out.println( classMapping );
95 String translatedName = m_mappings.getTranslator( m_ancestries, TranslationDirection.Deobfuscating ).translate( obf );
96 assert( translatedName != null && translatedName.equals( deobfName ) );
97 }
98
99 public void write( OutputStream out )
100 throws IOException
101 {
102 // TEMP: just use the object output for now. We can find a more efficient storage format later
103 GZIPOutputStream gzipout = new GZIPOutputStream( out );
104 ObjectOutputStream oout = new ObjectOutputStream( gzipout );
105 oout.writeObject( this );
106 gzipout.finish();
107 }
108
109 private ClassMapping createClassMapping( ClassEntry obf )
110 {
111 ClassMapping classMapping = new ClassMapping( obf.getName(), obf.getName() );
112 m_mappings.m_classesByObf.put( classMapping.getObfName(), classMapping );
113 m_mappings.m_classesByDeobf.put( classMapping.getDeobfName(), classMapping );
114 return classMapping;
115 }
116
117 private void updateDeobfMethodSignatures( )
118 {
119 Translator translator = m_mappings.getTranslator( m_ancestries, TranslationDirection.Deobfuscating );
120 for( ClassMapping classMapping : m_mappings.m_classesByObf.values() )
121 {
122 classMapping.updateDeobfMethodSignatures( translator );
123 }
124 }
125}
diff --git a/src/cuchaz/enigma/mapping/TranslationMappings.java b/src/cuchaz/enigma/mapping/TranslationMappings.java
deleted file mode 100644
index d6cd449..0000000
--- a/src/cuchaz/enigma/mapping/TranslationMappings.java
+++ /dev/null
@@ -1,187 +0,0 @@
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.mapping;
12
13import java.io.IOException;
14import java.io.InputStream;
15import java.io.ObjectInputStream;
16import java.io.ObjectOutputStream;
17import java.io.OutputStream;
18import java.io.Serializable;
19import java.util.Map;
20import java.util.zip.GZIPInputStream;
21import java.util.zip.GZIPOutputStream;
22
23import com.beust.jcommander.internal.Maps;
24
25import cuchaz.enigma.Util;
26
27public class TranslationMappings implements Serializable
28{
29 private static final long serialVersionUID = 4649790259460259026L;
30
31 private Map<String,ClassIndex> m_classesByObf;
32 private Map<String,ClassIndex> m_classesByDeobf;
33 private Ancestries m_ancestries;
34
35 public TranslationMappings( Ancestries ancestries )
36 {
37 m_classesByObf = Maps.newHashMap();
38 m_classesByDeobf = Maps.newHashMap();
39 m_ancestries = ancestries;
40 }
41
42 public static TranslationMappings newFromResource( String resource )
43 throws IOException
44 {
45 InputStream in = null;
46 try
47 {
48 in = TranslationMappings.class.getResourceAsStream( resource );
49 return newFromStream( in );
50 }
51 finally
52 {
53 Util.closeQuietly( in );
54 }
55 }
56
57 public Translator getTranslator( TranslationDirection direction )
58 {
59 return new Translator(
60 direction,
61 direction.choose( m_classesByObf, m_classesByDeobf ),
62 direction.choose( m_ancestries, new DeobfuscatedAncestries( m_ancestries, m_classesByObf, m_classesByDeobf ) )
63 );
64 }
65
66 public void setClassName( ClassEntry obf, String deobfName )
67 {
68 ClassIndex classIndex = m_classesByObf.get( obf.getName() );
69 if( classIndex == null )
70 {
71 classIndex = createClassIndex( obf );
72 }
73
74 m_classesByDeobf.remove( classIndex.getDeobfName() );
75 classIndex.setDeobfName( deobfName );
76 m_classesByDeobf.put( deobfName, classIndex );
77
78 updateDeobfMethodSignatures();
79
80 // TEMP
81 String translatedName = getTranslator( TranslationDirection.Deobfuscating ).translate( obf );
82 assert( translatedName != null && translatedName.equals( deobfName ) );
83 }
84
85 public void setFieldName( FieldEntry obf, String deobfName )
86 {
87 ClassIndex classIndex = m_classesByObf.get( obf.getClassName() );
88 if( classIndex == null )
89 {
90 classIndex = createClassIndex( obf.getClassEntry() );
91 }
92
93 classIndex.setFieldName( obf.getName(), deobfName );
94
95 // TEMP
96 System.out.println( classIndex );
97 String translatedName = getTranslator( TranslationDirection.Deobfuscating ).translate( obf );
98 assert( translatedName != null && translatedName.equals( deobfName ) );
99 }
100
101 public void setMethodName( MethodEntry obf, String deobfName )
102 {
103 ClassIndex classIndex = m_classesByObf.get( obf.getClassName() );
104 if( classIndex == null )
105 {
106 classIndex = createClassIndex( obf.getClassEntry() );
107 }
108
109 String deobfSignature = getTranslator( TranslationDirection.Deobfuscating ).translateSignature( obf.getSignature() );
110 classIndex.setMethodNameAndSignature( obf.getName(), obf.getSignature(), deobfName, deobfSignature );
111
112 // TODO: update ancestor/descendant methods in other classes in the inheritance hierarchy too
113
114 // TEMP
115 System.out.println( classIndex );
116 String translatedName = getTranslator( TranslationDirection.Deobfuscating ).translate( obf );
117 assert( translatedName != null && translatedName.equals( deobfName ) );
118 }
119
120 public void setArgumentName( ArgumentEntry obf, String deobfName )
121 {
122 ClassIndex classIndex = m_classesByObf.get( obf.getClassName() );
123 if( classIndex == null )
124 {
125 classIndex = createClassIndex( obf.getClassEntry() );
126 }
127
128 classIndex.setArgumentName( obf.getMethodName(), obf.getMethodSignature(), obf.getIndex(), obf.getName(), deobfName );
129
130 // TEMP
131 System.out.println( classIndex );
132 String translatedName = getTranslator( TranslationDirection.Deobfuscating ).translate( obf );
133 assert( translatedName != null && translatedName.equals( deobfName ) );
134 }
135
136 public void write( OutputStream out )
137 throws IOException
138 {
139 // TEMP: just use the object output for now. We can find a more efficient storage format later
140 GZIPOutputStream gzipout = new GZIPOutputStream( out );
141 ObjectOutputStream oout = new ObjectOutputStream( gzipout );
142 oout.writeObject( this );
143 gzipout.finish();
144 }
145
146 public static TranslationMappings newFromStream( InputStream in )
147 throws IOException
148 {
149 try
150 {
151 return (TranslationMappings)new ObjectInputStream( new GZIPInputStream( in ) ).readObject();
152 }
153 catch( ClassNotFoundException ex )
154 {
155 throw new Error( ex );
156 }
157 }
158
159 private ClassIndex createClassIndex( ClassEntry obf )
160 {
161 ClassIndex classIndex = new ClassIndex( obf.getName(), obf.getName() );
162 m_classesByObf.put( classIndex.getObfName(), classIndex );
163 m_classesByDeobf.put( classIndex.getDeobfName(), classIndex );
164 return classIndex;
165 }
166
167 private void updateDeobfMethodSignatures( )
168 {
169 Translator translator = getTranslator( TranslationDirection.Deobfuscating );
170 for( ClassIndex classIndex : m_classesByObf.values() )
171 {
172 classIndex.updateDeobfMethodSignatures( translator );
173 }
174 }
175
176 @Override
177 public String toString( )
178 {
179 StringBuilder buf = new StringBuilder();
180 for( ClassIndex classIndex : m_classesByObf.values() )
181 {
182 buf.append( classIndex.toString() );
183 buf.append( "\n" );
184 }
185 return buf.toString();
186 }
187}
diff --git a/src/cuchaz/enigma/mapping/Translator.java b/src/cuchaz/enigma/mapping/Translator.java
index bae0dce..3dbc103 100644
--- a/src/cuchaz/enigma/mapping/Translator.java
+++ b/src/cuchaz/enigma/mapping/Translator.java
@@ -19,10 +19,10 @@ import cuchaz.enigma.mapping.SignatureUpdater.ClassNameUpdater;
19public class Translator 19public class Translator
20{ 20{
21 private TranslationDirection m_direction; 21 private TranslationDirection m_direction;
22 private Map<String,ClassIndex> m_classes; 22 private Map<String,ClassMapping> m_classes;
23 private Ancestries m_ancestries; 23 private Ancestries m_ancestries;
24 24
25 protected Translator( TranslationDirection direction, Map<String,ClassIndex> classes, Ancestries ancestries ) 25 protected Translator( TranslationDirection direction, Map<String,ClassMapping> classes, Ancestries ancestries )
26 { 26 {
27 m_direction = direction; 27 m_direction = direction;
28 m_classes = classes; 28 m_classes = classes;
@@ -36,7 +36,7 @@ public class Translator
36 36
37 public String translateClass( String in ) 37 public String translateClass( String in )
38 { 38 {
39 ClassIndex classIndex = m_classes.get( in ); 39 ClassMapping classIndex = m_classes.get( in );
40 if( classIndex != null ) 40 if( classIndex != null )
41 { 41 {
42 return m_direction.choose( 42 return m_direction.choose(
@@ -63,7 +63,7 @@ public class Translator
63 for( String className : getSelfAndAncestors( in.getClassName() ) ) 63 for( String className : getSelfAndAncestors( in.getClassName() ) )
64 { 64 {
65 // look for the class 65 // look for the class
66 ClassIndex classIndex = m_classes.get( className ); 66 ClassMapping classIndex = m_classes.get( className );
67 if( classIndex != null ) 67 if( classIndex != null )
68 { 68 {
69 // look for the field 69 // look for the field
@@ -99,11 +99,11 @@ public class Translator
99 for( String className : getSelfAndAncestors( in.getClassName() ) ) 99 for( String className : getSelfAndAncestors( in.getClassName() ) )
100 { 100 {
101 // look for the class 101 // look for the class
102 ClassIndex classIndex = m_classes.get( className ); 102 ClassMapping classIndex = m_classes.get( className );
103 if( classIndex != null ) 103 if( classIndex != null )
104 { 104 {
105 // look for the method 105 // look for the method
106 MethodIndex methodIndex = m_direction.choose( 106 MethodMapping methodIndex = m_direction.choose(
107 classIndex.getMethodByObf( in.getName(), in.getSignature() ), 107 classIndex.getMethodByObf( in.getName(), in.getSignature() ),
108 classIndex.getMethodByDeobf( in.getName(), in.getSignature() ) 108 classIndex.getMethodByDeobf( in.getName(), in.getSignature() )
109 ); 109 );
@@ -139,11 +139,11 @@ public class Translator
139 for( String className : getSelfAndAncestors( in.getClassName() ) ) 139 for( String className : getSelfAndAncestors( in.getClassName() ) )
140 { 140 {
141 // look for the class 141 // look for the class
142 ClassIndex classIndex = m_classes.get( className ); 142 ClassMapping classIndex = m_classes.get( className );
143 if( classIndex != null ) 143 if( classIndex != null )
144 { 144 {
145 // look for the method 145 // look for the method
146 MethodIndex methodIndex = m_direction.choose( 146 MethodMapping methodIndex = m_direction.choose(
147 classIndex.getMethodByObf( in.getMethodName(), in.getMethodSignature() ), 147 classIndex.getMethodByObf( in.getMethodName(), in.getMethodSignature() ),
148 classIndex.getMethodByDeobf( in.getMethodName(), in.getMethodSignature() ) 148 classIndex.getMethodByDeobf( in.getMethodName(), in.getMethodSignature() )
149 ); 149 );