summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java
diff options
context:
space:
mode:
authorGravatar Thog2017-03-08 08:17:04 +0100
committerGravatar Thog2017-03-08 08:17:04 +0100
commit6e464ea251cab63c776ece0b2a356f1498ffa294 (patch)
tree5ed30c03f5ac4cd2d6877874f5ede576049954f7 /src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java
parentDrop unix case style and implement hashCode when equals is overrided (diff)
downloadenigma-fork-6e464ea251cab63c776ece0b2a356f1498ffa294.tar.gz
enigma-fork-6e464ea251cab63c776ece0b2a356f1498ffa294.tar.xz
enigma-fork-6e464ea251cab63c776ece0b2a356f1498ffa294.zip
Follow Fabric guidelines
Diffstat (limited to 'src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java')
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsRenamer.java633
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
11package cuchaz.enigma.mapping; 12package cuchaz.enigma.mapping;
12 13
14import com.google.common.collect.Lists;
15import cuchaz.enigma.analysis.JarIndex;
16import cuchaz.enigma.throwables.IllegalNameException;
17import cuchaz.enigma.throwables.MappingConflict;
18
13import java.io.IOException; 19import java.io.IOException;
14import java.io.ObjectOutputStream; 20import java.io.ObjectOutputStream;
15import java.io.OutputStream; 21import java.io.OutputStream;
@@ -17,324 +23,315 @@ import java.util.List;
17import java.util.Set; 23import java.util.Set;
18import java.util.zip.GZIPOutputStream; 24import java.util.zip.GZIPOutputStream;
19 25
20import com.google.common.collect.Lists;
21import cuchaz.enigma.analysis.JarIndex;
22import cuchaz.enigma.throwables.IllegalNameException;
23import cuchaz.enigma.throwables.MappingConflict;
24
25public class MappingsRenamer { 26public 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}