1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
package cuchaz.enigma.mapping;
import com.google.common.base.Charsets;
import com.google.common.collect.Maps;
import cuchaz.enigma.throwables.MappingConflict;
import cuchaz.enigma.throwables.MappingParseException;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class MappingsTinyReader {
public ClassMapping readClass(String[] parts) {
// Extract the inner naming of the deob form if it have one
String deobName = parts[2].contains("$") ? parts[2].substring(parts[2].lastIndexOf('$') + 1) : parts[2];
return new ClassMapping(parts[1], deobName).setDeobInner(parts[2]);
}
public FieldMapping readField(String[] parts) {
return new FieldMapping(parts[3], new Type(parts[2]), parts[4], Mappings.EntryModifier.UNCHANGED);
}
public MethodMapping readMethod(String[] parts) {
return new MethodMapping(parts[3], new Signature(parts[2]), parts[4]);
}
public Mappings read(File file) throws IOException, MappingParseException {
Mappings mappings = new Mappings(Mappings.FormatType.TINY_FILE);
System.out.println(file);
List<String> lines = Files.readAllLines(file.toPath(), Charsets.UTF_8);
Map<String, ClassMapping> classMappingMap = Maps.newHashMap();
String header = lines.remove(0);
for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) {
String line = lines.get(lineNumber);
String[] parts = line.split("\\s");
try {
String token = parts[0];
ClassMapping classMapping;
switch (token) {
case "CLASS":
if (classMappingMap.containsKey(parts[1])) {
classMapping = classMappingMap.get(parts[1]);
String deobName = parts[2].contains("$") ?
parts[2].substring(parts[2].lastIndexOf('$') + 1) :
parts[2];
classMappingMap.put(parts[2], classMapping.setDeobInner(parts[2]));
classMapping.setDeobfName(deobName);
classMapping.resetDirty();
} else
classMapping = readClass(parts);
classMappingMap.put(parts[1], classMapping);
break;
case "FIELD":
classMapping = classMappingMap.computeIfAbsent(parts[1], k -> new ClassMapping(parts[1]));
//throw new MappingParseException(file, lineNumber, "Cannot find class '" + parts[1] + "' declaration!");
classMapping.addFieldMapping(readField(parts));
break;
case "METHOD":
classMapping = classMappingMap.computeIfAbsent(parts[1], k -> new ClassMapping(parts[1]));
//throw new MappingParseException(file, lineNumber, "Cannot find class '" + parts[1] + "' declaration!");
classMapping.addMethodMapping(readMethod(parts));
break;
default:
throw new MappingParseException(file, lineNumber, "Unknown token '" + token + "' !");
}
} catch (ArrayIndexOutOfBoundsException | IllegalArgumentException ex) {
throw new MappingParseException(file, lineNumber, "Malformed line:\n" + line);
}
}
List<ClassMapping> toRegister = new ArrayList<>(classMappingMap.values());
for (ClassMapping classMapping : toRegister) {
ClassEntry obEntry = classMapping.getObfEntry();
ClassEntry deobEntry = classMapping.getDeObfEntry();
try {
if (obEntry.isInnerClass()) {
ClassMapping parent = classMappingMap.get(obEntry.getOuterClassName());
if (parent == null) {
parent = new ClassMapping(obEntry.getOuterClassName());
classMappingMap.put(obEntry.getOuterClassName(), parent);
mappings.addClassMapping(parent);
}
parent.addInnerClassMapping(classMapping);
} else if (deobEntry != null && deobEntry.isInnerClass())
classMappingMap.get(deobEntry.getOuterClassName()).addInnerClassMapping(classMapping);
else
mappings.addClassMapping(classMapping);
} catch (MappingConflict e) {
throw new MappingParseException(file, -1, e.getMessage());
}
}
lines.clear();
classMappingMap.clear();
return mappings;
}
}
|