diff options
Diffstat (limited to 'src/cuchaz/enigma/mapping/Mappings.java')
| -rw-r--r-- | src/cuchaz/enigma/mapping/Mappings.java | 230 |
1 files changed, 91 insertions, 139 deletions
diff --git a/src/cuchaz/enigma/mapping/Mappings.java b/src/cuchaz/enigma/mapping/Mappings.java index 3a39d10..c5e38f4 100644 --- a/src/cuchaz/enigma/mapping/Mappings.java +++ b/src/cuchaz/enigma/mapping/Mappings.java | |||
| @@ -26,230 +26,182 @@ import com.google.common.collect.Sets; | |||
| 26 | import cuchaz.enigma.Util; | 26 | import cuchaz.enigma.Util; |
| 27 | import cuchaz.enigma.mapping.SignatureUpdater.ClassNameUpdater; | 27 | import cuchaz.enigma.mapping.SignatureUpdater.ClassNameUpdater; |
| 28 | 28 | ||
| 29 | public class Mappings implements Serializable | 29 | public class Mappings implements Serializable { |
| 30 | { | 30 | |
| 31 | private static final long serialVersionUID = 4649790259460259026L; | 31 | private static final long serialVersionUID = 4649790259460259026L; |
| 32 | 32 | ||
| 33 | protected Map<String,ClassMapping> m_classesByObf; | 33 | protected Map<String,ClassMapping> m_classesByObf; |
| 34 | protected Map<String,ClassMapping> m_classesByDeobf; | 34 | protected Map<String,ClassMapping> m_classesByDeobf; |
| 35 | 35 | ||
| 36 | public Mappings( ) | 36 | public Mappings() { |
| 37 | { | ||
| 38 | m_classesByObf = Maps.newHashMap(); | 37 | m_classesByObf = Maps.newHashMap(); |
| 39 | m_classesByDeobf = Maps.newHashMap(); | 38 | m_classesByDeobf = Maps.newHashMap(); |
| 40 | } | 39 | } |
| 41 | 40 | ||
| 42 | public Mappings( Iterable<ClassMapping> classes ) | 41 | public Mappings(Iterable<ClassMapping> classes) { |
| 43 | { | ||
| 44 | this(); | 42 | this(); |
| 45 | 43 | ||
| 46 | for( ClassMapping classMapping : classes ) | 44 | for (ClassMapping classMapping : classes) { |
| 47 | { | 45 | m_classesByObf.put(classMapping.getObfName(), classMapping); |
| 48 | m_classesByObf.put( classMapping.getObfName(), classMapping ); | 46 | if (classMapping.getDeobfName() != null) { |
| 49 | if( classMapping.getDeobfName() != null ) | 47 | m_classesByDeobf.put(classMapping.getDeobfName(), classMapping); |
| 50 | { | ||
| 51 | m_classesByDeobf.put( classMapping.getDeobfName(), classMapping ); | ||
| 52 | } | 48 | } |
| 53 | } | 49 | } |
| 54 | } | 50 | } |
| 55 | 51 | ||
| 56 | public static Mappings newFromResource( String resource ) | 52 | public static Mappings newFromResource(String resource) throws IOException { |
| 57 | throws IOException | ||
| 58 | { | ||
| 59 | InputStream in = null; | 53 | InputStream in = null; |
| 60 | try | 54 | try { |
| 61 | { | 55 | in = Mappings.class.getResourceAsStream(resource); |
| 62 | in = Mappings.class.getResourceAsStream( resource ); | 56 | return newFromStream(in); |
| 63 | return newFromStream( in ); | 57 | } finally { |
| 64 | } | 58 | Util.closeQuietly(in); |
| 65 | finally | ||
| 66 | { | ||
| 67 | Util.closeQuietly( in ); | ||
| 68 | } | 59 | } |
| 69 | } | 60 | } |
| 70 | 61 | ||
| 71 | public Collection<ClassMapping> classes( ) | 62 | public Collection<ClassMapping> classes() { |
| 72 | { | 63 | assert (m_classesByObf.size() >= m_classesByDeobf.size()); |
| 73 | assert( m_classesByObf.size() >= m_classesByDeobf.size() ); | ||
| 74 | return m_classesByObf.values(); | 64 | return m_classesByObf.values(); |
| 75 | } | 65 | } |
| 76 | 66 | ||
| 77 | public void addClassMapping( ClassMapping classMapping ) | 67 | public void addClassMapping(ClassMapping classMapping) { |
| 78 | { | 68 | if (m_classesByObf.containsKey(classMapping.getObfName())) { |
| 79 | if( m_classesByObf.containsKey( classMapping.getObfName() ) ) | 69 | throw new Error("Already have mapping for " + classMapping.getObfName()); |
| 80 | { | ||
| 81 | throw new Error( "Already have mapping for " + classMapping.getObfName() ); | ||
| 82 | } | 70 | } |
| 83 | boolean obfWasAdded = m_classesByObf.put( classMapping.getObfName(), classMapping ) == null; | 71 | boolean obfWasAdded = m_classesByObf.put(classMapping.getObfName(), classMapping) == null; |
| 84 | assert( obfWasAdded ); | 72 | assert (obfWasAdded); |
| 85 | if( classMapping.getDeobfName() != null ) | 73 | if (classMapping.getDeobfName() != null) { |
| 86 | { | 74 | if (m_classesByDeobf.containsKey(classMapping.getDeobfName())) { |
| 87 | if( m_classesByDeobf.containsKey( classMapping.getDeobfName() ) ) | 75 | throw new Error("Already have mapping for " + classMapping.getDeobfName()); |
| 88 | { | ||
| 89 | throw new Error( "Already have mapping for " + classMapping.getDeobfName() ); | ||
| 90 | } | 76 | } |
| 91 | boolean deobfWasAdded = m_classesByDeobf.put( classMapping.getDeobfName(), classMapping ) == null; | 77 | boolean deobfWasAdded = m_classesByDeobf.put(classMapping.getDeobfName(), classMapping) == null; |
| 92 | assert( deobfWasAdded ); | 78 | assert (deobfWasAdded); |
| 93 | } | 79 | } |
| 94 | } | 80 | } |
| 95 | 81 | ||
| 96 | public void removeClassMapping( ClassMapping classMapping ) | 82 | public void removeClassMapping(ClassMapping classMapping) { |
| 97 | { | 83 | boolean obfWasRemoved = m_classesByObf.remove(classMapping.getObfName()) != null; |
| 98 | boolean obfWasRemoved = m_classesByObf.remove( classMapping.getObfName() ) != null; | 84 | assert (obfWasRemoved); |
| 99 | assert( obfWasRemoved ); | 85 | if (classMapping.getDeobfName() != null) { |
| 100 | if( classMapping.getDeobfName() != null ) | 86 | boolean deobfWasRemoved = m_classesByDeobf.remove(classMapping.getDeobfName()) != null; |
| 101 | { | 87 | assert (deobfWasRemoved); |
| 102 | boolean deobfWasRemoved = m_classesByDeobf.remove( classMapping.getDeobfName() ) != null; | ||
| 103 | assert( deobfWasRemoved ); | ||
| 104 | } | 88 | } |
| 105 | } | 89 | } |
| 106 | 90 | ||
| 107 | public ClassMapping getClassByObf( ClassEntry entry ) | 91 | public ClassMapping getClassByObf(ClassEntry entry) { |
| 108 | { | 92 | return getClassByObf(entry.getName()); |
| 109 | return getClassByObf( entry.getName() ); | ||
| 110 | } | 93 | } |
| 111 | 94 | ||
| 112 | public ClassMapping getClassByObf( String obfName ) | 95 | public ClassMapping getClassByObf(String obfName) { |
| 113 | { | 96 | return m_classesByObf.get(obfName); |
| 114 | return m_classesByObf.get( obfName ); | ||
| 115 | } | 97 | } |
| 116 | 98 | ||
| 117 | public ClassMapping getClassByDeobf( ClassEntry entry ) | 99 | public ClassMapping getClassByDeobf(ClassEntry entry) { |
| 118 | { | 100 | return getClassByDeobf(entry.getName()); |
| 119 | return getClassByDeobf( entry.getName() ); | ||
| 120 | } | 101 | } |
| 121 | 102 | ||
| 122 | public ClassMapping getClassByDeobf( String deobfName ) | 103 | public ClassMapping getClassByDeobf(String deobfName) { |
| 123 | { | 104 | return m_classesByDeobf.get(deobfName); |
| 124 | return m_classesByDeobf.get( deobfName ); | ||
| 125 | } | 105 | } |
| 126 | 106 | ||
| 127 | public Translator getTranslator( TranslationDirection direction ) | 107 | public Translator getTranslator(TranslationDirection direction) { |
| 128 | { | 108 | switch (direction) { |
| 129 | switch( direction ) | ||
| 130 | { | ||
| 131 | case Deobfuscating: | 109 | case Deobfuscating: |
| 132 | 110 | ||
| 133 | return new Translator( direction, m_classesByObf ); | 111 | return new Translator(direction, m_classesByObf); |
| 134 | 112 | ||
| 135 | case Obfuscating: | 113 | case Obfuscating: |
| 136 | 114 | ||
| 137 | // fill in the missing deobf class entries with obf entries | 115 | // fill in the missing deobf class entries with obf entries |
| 138 | Map<String,ClassMapping> classes = Maps.newHashMap(); | 116 | Map<String,ClassMapping> classes = Maps.newHashMap(); |
| 139 | for( ClassMapping classMapping : classes() ) | 117 | for (ClassMapping classMapping : classes()) { |
| 140 | { | 118 | if (classMapping.getDeobfName() != null) { |
| 141 | if( classMapping.getDeobfName() != null ) | 119 | classes.put(classMapping.getDeobfName(), classMapping); |
| 142 | { | 120 | } else { |
| 143 | classes.put( classMapping.getDeobfName(), classMapping ); | 121 | classes.put(classMapping.getObfName(), classMapping); |
| 144 | } | ||
| 145 | else | ||
| 146 | { | ||
| 147 | classes.put( classMapping.getObfName(), classMapping ); | ||
| 148 | } | 122 | } |
| 149 | } | 123 | } |
| 150 | 124 | ||
| 151 | return new Translator( direction, classes ); | 125 | return new Translator(direction, classes); |
| 152 | 126 | ||
| 153 | default: | 127 | default: |
| 154 | throw new Error( "Invalid translation direction!" ); | 128 | throw new Error("Invalid translation direction!"); |
| 155 | } | 129 | } |
| 156 | } | 130 | } |
| 157 | 131 | ||
| 158 | public static Mappings newFromStream( InputStream in ) | 132 | public static Mappings newFromStream(InputStream in) throws IOException { |
| 159 | throws IOException | 133 | try { |
| 160 | { | 134 | return (Mappings)new ObjectInputStream(new GZIPInputStream(in)).readObject(); |
| 161 | try | 135 | } catch (ClassNotFoundException ex) { |
| 162 | { | 136 | throw new Error(ex); |
| 163 | return (Mappings)new ObjectInputStream( new GZIPInputStream( in ) ).readObject(); | ||
| 164 | } | ||
| 165 | catch( ClassNotFoundException ex ) | ||
| 166 | { | ||
| 167 | throw new Error( ex ); | ||
| 168 | } | 137 | } |
| 169 | } | 138 | } |
| 170 | 139 | ||
| 171 | @Override | 140 | @Override |
| 172 | public String toString( ) | 141 | public String toString() { |
| 173 | { | ||
| 174 | StringBuilder buf = new StringBuilder(); | 142 | StringBuilder buf = new StringBuilder(); |
| 175 | for( ClassMapping classMapping : m_classesByObf.values() ) | 143 | for (ClassMapping classMapping : m_classesByObf.values()) { |
| 176 | { | 144 | buf.append(classMapping.toString()); |
| 177 | buf.append( classMapping.toString() ); | 145 | buf.append("\n"); |
| 178 | buf.append( "\n" ); | ||
| 179 | } | 146 | } |
| 180 | return buf.toString(); | 147 | return buf.toString(); |
| 181 | } | 148 | } |
| 182 | 149 | ||
| 183 | public void renameObfClass( String oldObfName, String newObfName ) | 150 | public void renameObfClass(String oldObfName, String newObfName) { |
| 184 | { | 151 | for (ClassMapping classMapping : new ArrayList<ClassMapping>(classes())) { |
| 185 | for( ClassMapping classMapping : new ArrayList<ClassMapping>( classes() ) ) | 152 | if (classMapping.renameObfClass(oldObfName, newObfName)) { |
| 186 | { | 153 | boolean wasRemoved = m_classesByObf.remove(oldObfName) != null; |
| 187 | if( classMapping.renameObfClass( oldObfName, newObfName ) ) | 154 | assert (wasRemoved); |
| 188 | { | 155 | boolean wasAdded = m_classesByObf.put(newObfName, classMapping) == null; |
| 189 | boolean wasRemoved = m_classesByObf.remove( oldObfName ) != null; | 156 | assert (wasAdded); |
| 190 | assert( wasRemoved ); | ||
| 191 | boolean wasAdded = m_classesByObf.put( newObfName, classMapping ) == null; | ||
| 192 | assert( wasAdded ); | ||
| 193 | } | 157 | } |
| 194 | } | 158 | } |
| 195 | } | 159 | } |
| 196 | 160 | ||
| 197 | public Set<String> getAllObfClassNames( ) | 161 | public Set<String> getAllObfClassNames() { |
| 198 | { | ||
| 199 | final Set<String> classNames = Sets.newHashSet(); | 162 | final Set<String> classNames = Sets.newHashSet(); |
| 200 | for( ClassMapping classMapping : classes() ) | 163 | for (ClassMapping classMapping : classes()) { |
| 201 | { | ||
| 202 | // add the class name | 164 | // add the class name |
| 203 | classNames.add( classMapping.getObfName() ); | 165 | classNames.add(classMapping.getObfName()); |
| 204 | 166 | ||
| 205 | // add classes from method signatures | 167 | // add classes from method signatures |
| 206 | for( MethodMapping methodMapping : classMapping.methods() ) | 168 | for (MethodMapping methodMapping : classMapping.methods()) { |
| 207 | { | 169 | SignatureUpdater.update(methodMapping.getObfSignature(), new ClassNameUpdater() { |
| 208 | SignatureUpdater.update( methodMapping.getObfSignature(), new ClassNameUpdater( ) | ||
| 209 | { | ||
| 210 | @Override | 170 | @Override |
| 211 | public String update( String className ) | 171 | public String update(String className) { |
| 212 | { | 172 | classNames.add(className); |
| 213 | classNames.add( className ); | ||
| 214 | return className; | 173 | return className; |
| 215 | } | 174 | } |
| 216 | } ); | 175 | }); |
| 217 | } | 176 | } |
| 218 | } | 177 | } |
| 219 | return classNames; | 178 | return classNames; |
| 220 | } | 179 | } |
| 221 | 180 | ||
| 222 | public boolean containsDeobfClass( String deobfName ) | 181 | public boolean containsDeobfClass(String deobfName) { |
| 223 | { | 182 | return m_classesByDeobf.containsKey(deobfName); |
| 224 | return m_classesByDeobf.containsKey( deobfName ); | ||
| 225 | } | 183 | } |
| 226 | 184 | ||
| 227 | public boolean containsDeobfField( ClassEntry obfClassEntry, String deobfName ) | 185 | public boolean containsDeobfField(ClassEntry obfClassEntry, String deobfName) { |
| 228 | { | 186 | ClassMapping classMapping = m_classesByObf.get(obfClassEntry.getName()); |
| 229 | ClassMapping classMapping = m_classesByObf.get( obfClassEntry.getName() ); | 187 | if (classMapping != null) { |
| 230 | if( classMapping != null ) | 188 | return classMapping.containsDeobfField(deobfName); |
| 231 | { | ||
| 232 | return classMapping.containsDeobfField( deobfName ); | ||
| 233 | } | 189 | } |
| 234 | return false; | 190 | return false; |
| 235 | } | 191 | } |
| 236 | 192 | ||
| 237 | public boolean containsDeobfMethod( ClassEntry obfClassEntry, String deobfName, String deobfSignature ) | 193 | public boolean containsDeobfMethod(ClassEntry obfClassEntry, String deobfName, String deobfSignature) { |
| 238 | { | 194 | ClassMapping classMapping = m_classesByObf.get(obfClassEntry.getName()); |
| 239 | ClassMapping classMapping = m_classesByObf.get( obfClassEntry.getName() ); | 195 | if (classMapping != null) { |
| 240 | if( classMapping != null ) | 196 | return classMapping.containsDeobfMethod(deobfName, deobfSignature); |
| 241 | { | ||
| 242 | return classMapping.containsDeobfMethod( deobfName, deobfSignature ); | ||
| 243 | } | 197 | } |
| 244 | return false; | 198 | return false; |
| 245 | } | 199 | } |
| 246 | 200 | ||
| 247 | public boolean containsArgument( BehaviorEntry obfBehaviorEntry, String name ) | 201 | public boolean containsArgument(BehaviorEntry obfBehaviorEntry, String name) { |
| 248 | { | 202 | ClassMapping classMapping = m_classesByObf.get(obfBehaviorEntry.getClassName()); |
| 249 | ClassMapping classMapping = m_classesByObf.get( obfBehaviorEntry.getClassName() ); | 203 | if (classMapping != null) { |
| 250 | if( classMapping != null ) | 204 | return classMapping.containsArgument(obfBehaviorEntry, name); |
| 251 | { | ||
| 252 | return classMapping.containsArgument( obfBehaviorEntry, name ); | ||
| 253 | } | 205 | } |
| 254 | return false; | 206 | return false; |
| 255 | } | 207 | } |