diff options
Diffstat (limited to 'src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java')
| -rw-r--r-- | src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java | 633 |
1 files changed, 315 insertions, 318 deletions
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java b/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java index e1428ea..7126d2b 100644 --- a/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java +++ b/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java | |||
| @@ -8,8 +8,14 @@ | |||
| 8 | * Contributors: | 8 | * Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | |||
| 11 | package cuchaz.enigma.mapping; | 12 | package cuchaz.enigma.mapping; |
| 12 | 13 | ||
| 14 | import com.google.common.collect.Lists; | ||
| 15 | import cuchaz.enigma.analysis.JarIndex; | ||
| 16 | import cuchaz.enigma.throwables.IllegalNameException; | ||
| 17 | import cuchaz.enigma.throwables.MappingConflict; | ||
| 18 | |||
| 13 | import java.io.IOException; | 19 | import java.io.IOException; |
| 14 | import java.io.ObjectOutputStream; | 20 | import java.io.ObjectOutputStream; |
| 15 | import java.io.OutputStream; | 21 | import java.io.OutputStream; |
| @@ -17,324 +23,315 @@ import java.util.List; | |||
| 17 | import java.util.Set; | 23 | import java.util.Set; |
| 18 | import java.util.zip.GZIPOutputStream; | 24 | import java.util.zip.GZIPOutputStream; |
| 19 | 25 | ||
| 20 | import com.google.common.collect.Lists; | ||
| 21 | import cuchaz.enigma.analysis.JarIndex; | ||
| 22 | import cuchaz.enigma.throwables.IllegalNameException; | ||
| 23 | import cuchaz.enigma.throwables.MappingConflict; | ||
| 24 | |||
| 25 | public class MappingsRenamer { | 26 | public class MappingsRenamer { |
| 26 | 27 | ||
| 27 | private JarIndex index; | 28 | private JarIndex index; |
| 28 | private Mappings mappings; | 29 | private Mappings mappings; |
| 29 | 30 | ||
| 30 | public MappingsRenamer(JarIndex index, Mappings mappings) { | 31 | public MappingsRenamer(JarIndex index, Mappings mappings) { |
| 31 | this.index = index; | 32 | this.index = index; |
| 32 | this.mappings = mappings; | 33 | this.mappings = mappings; |
| 33 | } | 34 | } |
| 34 | 35 | ||
| 35 | public void setMappings(Mappings mappings) | 36 | public void setMappings(Mappings mappings) { |
| 36 | { | 37 | this.mappings = mappings; |
| 37 | this.mappings = mappings; | 38 | } |
| 38 | } | 39 | |
| 39 | 40 | public void setClassName(ClassEntry obf, String deobfName) { | |
| 40 | public void setClassName(ClassEntry obf, String deobfName) { | 41 | |
| 41 | 42 | deobfName = NameValidator.validateClassName(deobfName, !obf.isInnerClass()); | |
| 42 | deobfName = NameValidator.validateClassName(deobfName, !obf.isInnerClass()); | 43 | |
| 43 | 44 | List<ClassMapping> mappingChain = getOrCreateClassMappingChain(obf); | |
| 44 | List<ClassMapping> mappingChain = getOrCreateClassMappingChain(obf); | 45 | if (mappingChain.size() == 1) { |
| 45 | if (mappingChain.size() == 1) { | 46 | |
| 46 | 47 | if (deobfName != null) { | |
| 47 | if (deobfName != null) { | 48 | // make sure we don't rename to an existing obf or deobf class |
| 48 | // make sure we don't rename to an existing obf or deobf class | 49 | if (mappings.containsDeobfClass(deobfName) || index.containsObfClass(new ClassEntry(deobfName))) { |
| 49 | if (mappings.containsDeobfClass(deobfName) || index.containsObfClass(new ClassEntry(deobfName))) { | 50 | throw new IllegalNameException(deobfName, "There is already a class with that name"); |
| 50 | throw new IllegalNameException(deobfName, "There is already a class with that name"); | 51 | } |
| 51 | } | 52 | } |
| 52 | } | 53 | |
| 53 | 54 | ClassMapping classMapping = mappingChain.get(0); | |
| 54 | ClassMapping classMapping = mappingChain.get(0); | 55 | mappings.setClassDeobfName(classMapping, deobfName); |
| 55 | mappings.setClassDeobfName(classMapping, deobfName); | 56 | |
| 56 | 57 | } else { | |
| 57 | } else { | 58 | |
| 58 | 59 | ClassMapping outerClassMapping = mappingChain.get(mappingChain.size() - 2); | |
| 59 | ClassMapping outerClassMapping = mappingChain.get(mappingChain.size() - 2); | 60 | |
| 60 | 61 | if (deobfName != null) { | |
| 61 | if (deobfName != null) { | 62 | // make sure we don't rename to an existing obf or deobf inner class |
| 62 | // make sure we don't rename to an existing obf or deobf inner class | 63 | if (outerClassMapping.hasInnerClassByDeobf(deobfName) || outerClassMapping.hasInnerClassByObfSimple(deobfName)) { |
| 63 | if (outerClassMapping.hasInnerClassByDeobf(deobfName) || outerClassMapping.hasInnerClassByObfSimple(deobfName)) { | 64 | throw new IllegalNameException(deobfName, "There is already a class with that name"); |
| 64 | throw new IllegalNameException(deobfName, "There is already a class with that name"); | 65 | } |
| 65 | } | 66 | } |
| 66 | } | 67 | |
| 67 | 68 | outerClassMapping.setInnerClassName(obf, deobfName); | |
| 68 | outerClassMapping.setInnerClassName(obf, deobfName); | 69 | } |
| 69 | } | 70 | } |
| 70 | } | 71 | |
| 71 | 72 | public void removeClassMapping(ClassEntry obf) { | |
| 72 | public void removeClassMapping(ClassEntry obf) { | 73 | setClassName(obf, null); |
| 73 | setClassName(obf, null); | 74 | } |
| 74 | } | 75 | |
| 75 | 76 | public void markClassAsDeobfuscated(ClassEntry obf) { | |
| 76 | public void markClassAsDeobfuscated(ClassEntry obf) { | 77 | String deobfName = obf.isInnerClass() ? obf.getInnermostClassName() : obf.getName(); |
| 77 | String deobfName = obf.isInnerClass() ? obf.getInnermostClassName() : obf.getName(); | 78 | List<ClassMapping> mappingChain = getOrCreateClassMappingChain(obf); |
| 78 | List<ClassMapping> mappingChain = getOrCreateClassMappingChain(obf); | 79 | if (mappingChain.size() == 1) { |
| 79 | if (mappingChain.size() == 1) { | 80 | ClassMapping classMapping = mappingChain.get(0); |
| 80 | ClassMapping classMapping = mappingChain.get(0); | 81 | mappings.setClassDeobfName(classMapping, deobfName); |
| 81 | mappings.setClassDeobfName(classMapping, deobfName); | 82 | } else { |
| 82 | } else { | 83 | ClassMapping outerClassMapping = mappingChain.get(mappingChain.size() - 2); |
| 83 | ClassMapping outerClassMapping = mappingChain.get(mappingChain.size() - 2); | 84 | outerClassMapping.setInnerClassName(obf, deobfName); |
| 84 | outerClassMapping.setInnerClassName(obf, deobfName); | 85 | } |
| 85 | } | 86 | } |
| 86 | } | 87 | |
| 87 | 88 | public void setFieldName(FieldEntry obf, String deobfName) { | |
| 88 | public void setFieldName(FieldEntry obf, String deobfName) { | 89 | deobfName = NameValidator.validateFieldName(deobfName); |
| 89 | deobfName = NameValidator.validateFieldName(deobfName); | 90 | FieldEntry targetEntry = new FieldEntry(obf.getClassEntry(), deobfName, obf.getType()); |
| 90 | FieldEntry targetEntry = new FieldEntry(obf.getClassEntry(), deobfName, obf.getType()); | 91 | ClassEntry definedClass = null; |
| 91 | ClassEntry definedClass = null; | 92 | if (mappings.containsDeobfField(obf.getClassEntry(), deobfName) || index.containsEntryWithSameName(targetEntry)) |
| 92 | if (mappings.containsDeobfField(obf.getClassEntry(), deobfName) || index.containsEntryWithSameName(targetEntry)) | 93 | definedClass = obf.getClassEntry(); |
| 93 | definedClass = obf.getClassEntry(); | 94 | else { |
| 94 | else { | 95 | for (ClassEntry ancestorEntry : this.index.getTranslationIndex().getAncestry(obf.getClassEntry())) { |
| 95 | for (ClassEntry ancestorEntry : this.index.getTranslationIndex().getAncestry(obf.getClassEntry())) { | 96 | if (mappings.containsDeobfField(ancestorEntry, deobfName) || index.containsEntryWithSameName(targetEntry.cloneToNewClass(ancestorEntry))) { |
| 96 | if (mappings.containsDeobfField(ancestorEntry, deobfName) || index.containsEntryWithSameName(targetEntry.cloneToNewClass(ancestorEntry))) { | 97 | definedClass = ancestorEntry; |
| 97 | definedClass = ancestorEntry; | 98 | break; |
| 98 | break; | 99 | } |
| 99 | } | 100 | } |
| 100 | } | 101 | } |
| 101 | } | 102 | |
| 102 | 103 | if (definedClass != null) { | |
| 103 | if (definedClass != null) { | 104 | String className = mappings.getTranslator(TranslationDirection.Deobfuscating, index.getTranslationIndex()).translateClass(definedClass.getClassName()); |
| 104 | String className = mappings.getTranslator(TranslationDirection.Deobfuscating, index.getTranslationIndex()).translateClass(definedClass.getClassName()); | 105 | if (className == null) |
| 105 | if (className == null) | 106 | className = definedClass.getClassName(); |
| 106 | className = definedClass.getClassName(); | 107 | throw new IllegalNameException(deobfName, "There is already a field with that name in " + className); |
| 107 | throw new IllegalNameException(deobfName, "There is already a field with that name in " + className); | 108 | } |
| 108 | } | 109 | |
| 109 | 110 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); | |
| 110 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); | 111 | classMapping.setFieldName(obf.getName(), obf.getType(), deobfName); |
| 111 | classMapping.setFieldName(obf.getName(), obf.getType(), deobfName); | 112 | } |
| 112 | } | 113 | |
| 113 | 114 | public void removeFieldMapping(FieldEntry obf) { | |
| 114 | public void removeFieldMapping(FieldEntry obf) { | 115 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 115 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); | 116 | classMapping.removeFieldMapping(classMapping.getFieldByObf(obf.getName(), obf.getType())); |
| 116 | classMapping.removeFieldMapping(classMapping.getFieldByObf(obf.getName(), obf.getType())); | 117 | } |
| 117 | } | 118 | |
| 118 | 119 | public void markFieldAsDeobfuscated(FieldEntry obf) { | |
| 119 | public void markFieldAsDeobfuscated(FieldEntry obf) { | 120 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 120 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); | 121 | classMapping.setFieldName(obf.getName(), obf.getType(), obf.getName()); |
| 121 | classMapping.setFieldName(obf.getName(), obf.getType(), obf.getName()); | 122 | } |
| 122 | } | 123 | |
| 123 | 124 | private void validateMethodTreeName(MethodEntry entry, String deobfName) { | |
| 124 | private void validateMethodTreeName(MethodEntry entry, String deobfName) { | 125 | MethodEntry targetEntry = new MethodEntry(entry.getClassEntry(), deobfName, entry.getSignature()); |
| 125 | MethodEntry targetEntry = new MethodEntry(entry.getClassEntry(), deobfName, entry.getSignature()); | 126 | |
| 126 | 127 | // TODO: Verify if I don't break things | |
| 127 | // TODO: Verify if I don't break things | 128 | ClassMapping classMapping = mappings.getClassByObf(entry.getClassEntry()); |
| 128 | ClassMapping classMapping = mappings.getClassByObf(entry.getClassEntry()); | 129 | if ((classMapping != null && classMapping.containsDeobfMethod(deobfName, entry.getSignature()) && classMapping.getMethodByObf(entry.getName(), entry.getSignature()) != classMapping.getMethodByDeobf(deobfName, entry.getSignature())) |
| 129 | if ((classMapping != null && classMapping.containsDeobfMethod(deobfName, entry.getSignature()) && classMapping.getMethodByObf(entry.getName(), entry.getSignature()) != classMapping.getMethodByDeobf(deobfName, entry.getSignature())) | 130 | || index.containsObfBehavior(targetEntry)) { |
| 130 | || index.containsObfBehavior(targetEntry)) { | 131 | String deobfClassName = mappings.getTranslator(TranslationDirection.Deobfuscating, index.getTranslationIndex()).translateClass(entry.getClassName()); |
| 131 | String deobfClassName = mappings.getTranslator(TranslationDirection.Deobfuscating, index.getTranslationIndex()).translateClass(entry.getClassName()); | 132 | if (deobfClassName == null) { |
| 132 | if (deobfClassName == null) { | 133 | deobfClassName = entry.getClassName(); |
| 133 | deobfClassName = entry.getClassName(); | 134 | } |
| 134 | } | 135 | throw new IllegalNameException(deobfName, "There is already a method with that name and signature in class " + deobfClassName); |
| 135 | throw new IllegalNameException(deobfName, "There is already a method with that name and signature in class " + deobfClassName); | 136 | } |
| 136 | } | 137 | |
| 137 | 138 | for (ClassEntry child : index.getTranslationIndex().getSubclass(entry.getClassEntry())) { | |
| 138 | for (ClassEntry child : index.getTranslationIndex().getSubclass(entry.getClassEntry())) { | 139 | validateMethodTreeName(entry.cloneToNewClass(child), deobfName); |
| 139 | validateMethodTreeName(entry.cloneToNewClass(child), deobfName); | 140 | } |
| 140 | } | 141 | } |
| 141 | } | 142 | |
| 142 | 143 | public void setMethodTreeName(MethodEntry obf, String deobfName) { | |
| 143 | public void setMethodTreeName(MethodEntry obf, String deobfName) { | 144 | Set<MethodEntry> implementations = index.getRelatedMethodImplementations(obf); |
| 144 | Set<MethodEntry> implementations = index.getRelatedMethodImplementations(obf); | 145 | |
| 145 | 146 | deobfName = NameValidator.validateMethodName(deobfName); | |
| 146 | deobfName = NameValidator.validateMethodName(deobfName); | 147 | for (MethodEntry entry : implementations) { |
| 147 | for (MethodEntry entry : implementations) { | 148 | validateMethodTreeName(entry, deobfName); |
| 148 | validateMethodTreeName(entry, deobfName); | 149 | } |
| 149 | } | 150 | |
| 150 | 151 | for (MethodEntry entry : implementations) { | |
| 151 | for (MethodEntry entry : implementations) { | 152 | setMethodName(entry, deobfName); |
| 152 | setMethodName(entry, deobfName); | 153 | } |
| 153 | } | 154 | } |
| 154 | } | 155 | |
| 155 | 156 | public void setMethodName(MethodEntry obf, String deobfName) { | |
| 156 | public void setMethodName(MethodEntry obf, String deobfName) { | 157 | deobfName = NameValidator.validateMethodName(deobfName); |
| 157 | deobfName = NameValidator.validateMethodName(deobfName); | 158 | MethodEntry targetEntry = new MethodEntry(obf.getClassEntry(), deobfName, obf.getSignature()); |
| 158 | MethodEntry targetEntry = new MethodEntry(obf.getClassEntry(), deobfName, obf.getSignature()); | 159 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 159 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); | 160 | |
| 160 | 161 | // TODO: Verify if I don't break things | |
| 161 | // TODO: Verify if I don't break things | 162 | if ((mappings.containsDeobfMethod(obf.getClassEntry(), deobfName, obf.getSignature()) && classMapping.getMethodByObf(obf.getName(), obf.getSignature()) != classMapping.getMethodByDeobf(deobfName, obf.getSignature())) |
| 162 | if ((mappings.containsDeobfMethod(obf.getClassEntry(), deobfName, obf.getSignature()) && classMapping.getMethodByObf(obf.getName(), obf.getSignature()) != classMapping.getMethodByDeobf(deobfName, obf.getSignature())) | 163 | || index.containsObfBehavior(targetEntry)) { |
| 163 | || index.containsObfBehavior(targetEntry)) { | 164 | String deobfClassName = mappings.getTranslator(TranslationDirection.Deobfuscating, index.getTranslationIndex()).translateClass(obf.getClassName()); |
| 164 | String deobfClassName = mappings.getTranslator(TranslationDirection.Deobfuscating, index.getTranslationIndex()).translateClass(obf.getClassName()); | 165 | if (deobfClassName == null) { |
| 165 | if (deobfClassName == null) { | 166 | deobfClassName = obf.getClassName(); |
| 166 | deobfClassName = obf.getClassName(); | 167 | } |
| 167 | } | 168 | throw new IllegalNameException(deobfName, "There is already a method with that name and signature in class " + deobfClassName); |
| 168 | throw new IllegalNameException(deobfName, "There is already a method with that name and signature in class " + deobfClassName); | 169 | } |
| 169 | } | 170 | |
| 170 | 171 | classMapping.setMethodName(obf.getName(), obf.getSignature(), deobfName); | |
| 171 | classMapping.setMethodName(obf.getName(), obf.getSignature(), deobfName); | 172 | } |
| 172 | } | 173 | |
| 173 | 174 | public void removeMethodTreeMapping(MethodEntry obf) { | |
| 174 | public void removeMethodTreeMapping(MethodEntry obf) { | 175 | index.getRelatedMethodImplementations(obf).forEach(this::removeMethodMapping); |
| 175 | index.getRelatedMethodImplementations(obf).forEach(this::removeMethodMapping); | 176 | } |
| 176 | } | 177 | |
| 177 | 178 | public void removeMethodMapping(MethodEntry obf) { | |
| 178 | public void removeMethodMapping(MethodEntry obf) { | 179 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 179 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); | 180 | classMapping.setMethodName(obf.getName(), obf.getSignature(), null); |
| 180 | classMapping.setMethodName(obf.getName(), obf.getSignature(), null); | 181 | } |
| 181 | } | 182 | |
| 182 | 183 | public void markMethodTreeAsDeobfuscated(MethodEntry obf) { | |
| 183 | public void markMethodTreeAsDeobfuscated(MethodEntry obf) { | 184 | index.getRelatedMethodImplementations(obf).forEach(this::markMethodAsDeobfuscated); |
| 184 | index.getRelatedMethodImplementations(obf).forEach(this::markMethodAsDeobfuscated); | 185 | } |
| 185 | } | 186 | |
| 186 | 187 | public void markMethodAsDeobfuscated(MethodEntry obf) { | |
| 187 | public void markMethodAsDeobfuscated(MethodEntry obf) { | 188 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 188 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); | 189 | classMapping.setMethodName(obf.getName(), obf.getSignature(), obf.getName()); |
| 189 | classMapping.setMethodName(obf.getName(), obf.getSignature(), obf.getName()); | 190 | } |
| 190 | } | 191 | |
| 191 | 192 | public void setArgumentTreeName(ArgumentEntry obf, String deobfName) { | |
| 192 | public void setArgumentTreeName(ArgumentEntry obf, String deobfName) { | 193 | if (!(obf.getBehaviorEntry() instanceof MethodEntry)) { |
| 193 | if (!(obf.getBehaviorEntry() instanceof MethodEntry)) { | 194 | setArgumentName(obf, deobfName); |
| 194 | setArgumentName(obf, deobfName); | 195 | return; |
| 195 | return; | 196 | } |
| 196 | } | 197 | |
| 197 | 198 | MethodEntry obfMethod = (MethodEntry) obf.getBehaviorEntry(); | |
| 198 | MethodEntry obfMethod = (MethodEntry) obf.getBehaviorEntry(); | 199 | |
| 199 | 200 | Set<MethodEntry> implementations = index.getRelatedMethodImplementations(obfMethod); | |
| 200 | Set<MethodEntry> implementations = index.getRelatedMethodImplementations(obfMethod); | 201 | for (MethodEntry entry : implementations) { |
| 201 | for (MethodEntry entry : implementations) { | 202 | ClassMapping classMapping = mappings.getClassByObf(entry.getClassEntry()); |
| 202 | ClassMapping classMapping = mappings.getClassByObf(entry.getClassEntry()); | 203 | if (classMapping != null) { |
| 203 | if (classMapping != null) { | 204 | MethodMapping mapping = classMapping.getMethodByObf(entry.getName(), entry.getSignature()); |
| 204 | MethodMapping mapping = classMapping.getMethodByObf(entry.getName(), entry.getSignature()); | 205 | // NOTE: don't need to check arguments for name collisions with names determined by Procyon |
| 205 | // NOTE: don't need to check arguments for name collisions with names determined by Procyon | 206 | // TODO: Verify if I don't break things |
| 206 | // TODO: Verify if I don't break things | 207 | if (mapping != null) { |
| 207 | if (mapping != null) { | 208 | for (ArgumentMapping argumentMapping : Lists.newArrayList(mapping.arguments())) { |
| 208 | for (ArgumentMapping argumentMapping : Lists.newArrayList(mapping.arguments())) { | 209 | if (argumentMapping.getIndex() != obf.getIndex()) { |
| 209 | if (argumentMapping.getIndex() != obf.getIndex()) { | 210 | if (mapping.getDeobfArgumentName(argumentMapping.getIndex()).equals(deobfName) |
| 210 | if (mapping.getDeobfArgumentName(argumentMapping.getIndex()).equals(deobfName) | 211 | || argumentMapping.getName().equals(deobfName)) { |
| 211 | || argumentMapping.getName().equals(deobfName)) { | 212 | throw new IllegalNameException(deobfName, "There is already an argument with that name"); |
| 212 | throw new IllegalNameException(deobfName, "There is already an argument with that name"); | 213 | } |
| 213 | } | 214 | } |
| 214 | } | 215 | } |
| 215 | } | 216 | } |
| 216 | } | 217 | } |
| 217 | } | 218 | } |
| 218 | } | 219 | |
| 219 | 220 | for (MethodEntry entry : implementations) { | |
| 220 | for (MethodEntry entry : implementations) { | 221 | setArgumentName(new ArgumentEntry(obf, entry), deobfName); |
| 221 | setArgumentName(new ArgumentEntry(obf, entry), deobfName); | 222 | } |
| 222 | } | 223 | } |
| 223 | } | 224 | |
| 224 | 225 | public void setArgumentName(ArgumentEntry obf, String deobfName) { | |
| 225 | public void setArgumentName(ArgumentEntry obf, String deobfName) { | 226 | deobfName = NameValidator.validateArgumentName(deobfName); |
| 226 | deobfName = NameValidator.validateArgumentName(deobfName); | 227 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 227 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); | 228 | MethodMapping mapping = classMapping.getMethodByObf(obf.getMethodName(), obf.getMethodSignature()); |
| 228 | MethodMapping mapping = classMapping.getMethodByObf(obf.getMethodName(), obf.getMethodSignature()); | 229 | // NOTE: don't need to check arguments for name collisions with names determined by Procyon |
| 229 | // NOTE: don't need to check arguments for name collisions with names determined by Procyon | 230 | // TODO: Verify if I don't break things |
| 230 | // TODO: Verify if I don't break things | 231 | if (mapping != null) { |
| 231 | if (mapping != null) { | 232 | for (ArgumentMapping argumentMapping : Lists.newArrayList(mapping.arguments())) { |
| 232 | for (ArgumentMapping argumentMapping : Lists.newArrayList(mapping.arguments())) { | 233 | if (argumentMapping.getIndex() != obf.getIndex()) { |
| 233 | if (argumentMapping.getIndex() != obf.getIndex()) { | 234 | if (mapping.getDeobfArgumentName(argumentMapping.getIndex()).equals(deobfName) |
| 234 | if (mapping.getDeobfArgumentName(argumentMapping.getIndex()).equals(deobfName) | 235 | || argumentMapping.getName().equals(deobfName)) { |
| 235 | || argumentMapping.getName().equals(deobfName)) { | 236 | throw new IllegalNameException(deobfName, "There is already an argument with that name"); |
| 236 | throw new IllegalNameException(deobfName, "There is already an argument with that name"); | 237 | } |
| 237 | } | 238 | } |
| 238 | } | 239 | } |
| 239 | } | 240 | } |
| 240 | } | 241 | |
| 241 | 242 | classMapping.setArgumentName(obf.getMethodName(), obf.getMethodSignature(), obf.getIndex(), deobfName); | |
| 242 | classMapping.setArgumentName(obf.getMethodName(), obf.getMethodSignature(), obf.getIndex(), deobfName); | 243 | } |
| 243 | } | 244 | |
| 244 | 245 | public void removeArgumentMapping(ArgumentEntry obf) { | |
| 245 | public void removeArgumentMapping(ArgumentEntry obf) { | 246 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 246 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); | 247 | classMapping.removeArgumentName(obf.getMethodName(), obf.getMethodSignature(), obf.getIndex()); |
| 247 | classMapping.removeArgumentName(obf.getMethodName(), obf.getMethodSignature(), obf.getIndex()); | 248 | } |
| 248 | } | 249 | |
| 249 | 250 | public void markArgumentAsDeobfuscated(ArgumentEntry obf) { | |
| 250 | public void markArgumentAsDeobfuscated(ArgumentEntry obf) { | 251 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); |
| 251 | ClassMapping classMapping = getOrCreateClassMapping(obf.getClassEntry()); | 252 | classMapping.setArgumentName(obf.getMethodName(), obf.getMethodSignature(), obf.getIndex(), obf.getName()); |
| 252 | classMapping.setArgumentName(obf.getMethodName(), obf.getMethodSignature(), obf.getIndex(), obf.getName()); | 253 | } |
| 253 | } | 254 | |
| 254 | 255 | public boolean moveFieldToObfClass(ClassMapping classMapping, FieldMapping fieldMapping, ClassEntry obfClass) { | |
| 255 | public boolean moveFieldToObfClass(ClassMapping classMapping, FieldMapping fieldMapping, ClassEntry obfClass) { | 256 | classMapping.removeFieldMapping(fieldMapping); |
| 256 | classMapping.removeFieldMapping(fieldMapping); | 257 | ClassMapping targetClassMapping = getOrCreateClassMapping(obfClass); |
| 257 | ClassMapping targetClassMapping = getOrCreateClassMapping(obfClass); | 258 | if (!targetClassMapping.containsObfField(fieldMapping.getObfName(), fieldMapping.getObfType())) { |
| 258 | if (!targetClassMapping.containsObfField(fieldMapping.getObfName(), fieldMapping.getObfType())) { | 259 | if (!targetClassMapping.containsDeobfField(fieldMapping.getDeobfName(), fieldMapping.getObfType())) { |
| 259 | if (!targetClassMapping.containsDeobfField(fieldMapping.getDeobfName(), fieldMapping.getObfType())) { | 260 | targetClassMapping.addFieldMapping(fieldMapping); |
| 260 | targetClassMapping.addFieldMapping(fieldMapping); | 261 | return true; |
| 261 | return true; | 262 | } else { |
| 262 | } else { | 263 | System.err.println("WARNING: deobf field was already there: " + obfClass + "." + fieldMapping.getDeobfName()); |
| 263 | System.err.println("WARNING: deobf field was already there: " + obfClass + "." + fieldMapping.getDeobfName()); | 264 | } |
| 264 | } | 265 | } |
| 265 | } | 266 | return false; |
| 266 | return false; | 267 | } |
| 267 | } | 268 | |
| 268 | 269 | public boolean moveMethodToObfClass(ClassMapping classMapping, MethodMapping methodMapping, ClassEntry obfClass) { | |
| 269 | public boolean moveMethodToObfClass(ClassMapping classMapping, MethodMapping methodMapping, ClassEntry obfClass) { | 270 | classMapping.removeMethodMapping(methodMapping); |
| 270 | classMapping.removeMethodMapping(methodMapping); | 271 | ClassMapping targetClassMapping = getOrCreateClassMapping(obfClass); |
| 271 | ClassMapping targetClassMapping = getOrCreateClassMapping(obfClass); | 272 | if (!targetClassMapping.containsObfMethod(methodMapping.getObfName(), methodMapping.getObfSignature())) { |
| 272 | if (!targetClassMapping.containsObfMethod(methodMapping.getObfName(), methodMapping.getObfSignature())) { | 273 | if (!targetClassMapping.containsDeobfMethod(methodMapping.getDeobfName(), methodMapping.getObfSignature())) { |
| 273 | if (!targetClassMapping.containsDeobfMethod(methodMapping.getDeobfName(), methodMapping.getObfSignature())) { | 274 | targetClassMapping.addMethodMapping(methodMapping); |
| 274 | targetClassMapping.addMethodMapping(methodMapping); | 275 | return true; |
| 275 | return true; | 276 | } else { |
| 276 | } else { | 277 | System.err.println("WARNING: deobf method was already there: " + obfClass + "." + methodMapping.getDeobfName() + methodMapping.getObfSignature()); |
| 277 | System.err.println("WARNING: deobf method was already there: " + obfClass + "." + methodMapping.getDeobfName() + methodMapping.getObfSignature()); | 278 | } |
| 278 | } | 279 | } |
| 279 | } | 280 | return false; |
| 280 | return false; | 281 | } |
| 281 | } | 282 | |
| 282 | 283 | public void write(OutputStream out) throws IOException { | |
| 283 | public void write(OutputStream out) throws IOException { | 284 | // TEMP: just use the object output for now. We can find a more efficient storage format later |
| 284 | // TEMP: just use the object output for now. We can find a more efficient storage format later | 285 | GZIPOutputStream gzipout = new GZIPOutputStream(out); |
| 285 | GZIPOutputStream gzipout = new GZIPOutputStream(out); | 286 | ObjectOutputStream oout = new ObjectOutputStream(gzipout); |
| 286 | ObjectOutputStream oout = new ObjectOutputStream(gzipout); | 287 | oout.writeObject(this); |
| 287 | oout.writeObject(this); | 288 | gzipout.finish(); |
| 288 | gzipout.finish(); | 289 | } |
| 289 | } | 290 | |
| 290 | 291 | private ClassMapping getOrCreateClassMapping(ClassEntry obfClassEntry) { | |
| 291 | private ClassMapping getOrCreateClassMapping(ClassEntry obfClassEntry) { | 292 | List<ClassMapping> mappingChain = getOrCreateClassMappingChain(obfClassEntry); |
| 292 | List<ClassMapping> mappingChain = getOrCreateClassMappingChain(obfClassEntry); | 293 | return mappingChain.get(mappingChain.size() - 1); |
| 293 | return mappingChain.get(mappingChain.size() - 1); | 294 | } |
| 294 | } | 295 | |
| 295 | 296 | private List<ClassMapping> getOrCreateClassMappingChain(ClassEntry obfClassEntry) { | |
| 296 | private List<ClassMapping> getOrCreateClassMappingChain(ClassEntry obfClassEntry) { | 297 | List<ClassEntry> classChain = obfClassEntry.getClassChain(); |
| 297 | List<ClassEntry> classChain = obfClassEntry.getClassChain(); | 298 | List<ClassMapping> mappingChain = mappings.getClassMappingChain(obfClassEntry); |
| 298 | List<ClassMapping> mappingChain = mappings.getClassMappingChain(obfClassEntry); | 299 | for (int i = 0; i < classChain.size(); i++) { |
| 299 | for (int i = 0; i < classChain.size(); i++) { | 300 | ClassEntry classEntry = classChain.get(i); |
| 300 | ClassEntry classEntry = classChain.get(i); | 301 | ClassMapping classMapping = mappingChain.get(i); |
| 301 | ClassMapping classMapping = mappingChain.get(i); | 302 | if (classMapping == null) { |
| 302 | if (classMapping == null) { | 303 | |
| 303 | 304 | // create it | |
| 304 | // create it | 305 | classMapping = new ClassMapping(classEntry.getName()); |
| 305 | classMapping = new ClassMapping(classEntry.getName()); | 306 | mappingChain.set(i, classMapping); |
| 306 | mappingChain.set(i, classMapping); | 307 | |
| 307 | 308 | // add it to the right parent | |
| 308 | // add it to the right parent | 309 | try { |
| 309 | try { | 310 | if (i == 0) { |
| 310 | if (i == 0) { | 311 | mappings.addClassMapping(classMapping); |
| 311 | mappings.addClassMapping(classMapping); | 312 | } else { |
| 312 | } else { | 313 | mappingChain.get(i - 1).addInnerClassMapping(classMapping); |
| 313 | mappingChain.get(i - 1).addInnerClassMapping(classMapping); | 314 | } |
| 314 | } | 315 | } catch (MappingConflict mappingConflict) { |
| 315 | } catch (MappingConflict mappingConflict) { | 316 | mappingConflict.printStackTrace(); |
| 316 | mappingConflict.printStackTrace(); | 317 | } |
| 317 | } | 318 | } |
| 318 | } | 319 | } |
| 319 | } | 320 | return mappingChain; |
| 320 | return mappingChain; | 321 | } |
| 321 | } | 322 | |
| 322 | 323 | public void setClassModifier(ClassEntry obEntry, Mappings.EntryModifier modifier) { | |
| 323 | public void setClassModifier(ClassEntry obEntry, Mappings.EntryModifier modifier) | 324 | ClassMapping classMapping = getOrCreateClassMapping(obEntry); |
| 324 | { | 325 | classMapping.setModifier(modifier); |
| 325 | ClassMapping classMapping = getOrCreateClassMapping(obEntry); | 326 | } |
| 326 | classMapping.setModifier(modifier); | 327 | |
| 327 | } | 328 | public void setFieldModifier(FieldEntry obEntry, Mappings.EntryModifier modifier) { |
| 328 | 329 | ClassMapping classMapping = getOrCreateClassMapping(obEntry.getClassEntry()); | |
| 329 | public void setFieldModifier(FieldEntry obEntry, Mappings.EntryModifier modifier) | 330 | classMapping.setFieldModifier(obEntry.getName(), obEntry.getType(), modifier); |
| 330 | { | 331 | } |
| 331 | ClassMapping classMapping = getOrCreateClassMapping(obEntry.getClassEntry()); | 332 | |
| 332 | classMapping.setFieldModifier(obEntry.getName(), obEntry.getType(), modifier); | 333 | public void setMethodModifier(BehaviorEntry obEntry, Mappings.EntryModifier modifier) { |
| 333 | } | 334 | ClassMapping classMapping = getOrCreateClassMapping(obEntry.getClassEntry()); |
| 334 | 335 | classMapping.setMethodModifier(obEntry.getName(), obEntry.getSignature(), modifier); | |
| 335 | public void setMethodModifier(BehaviorEntry obEntry, Mappings.EntryModifier modifier) | 336 | } |
| 336 | { | ||
| 337 | ClassMapping classMapping = getOrCreateClassMapping(obEntry.getClassEntry()); | ||
| 338 | classMapping.setMethodModifier(obEntry.getName(), obEntry.getSignature(), modifier); | ||
| 339 | } | ||
| 340 | } | 337 | } |