Skip to content

Commit daffc3e

Browse files
committed
Fixed reobfuscation
1 parent fbe4a8c commit daffc3e

File tree

4 files changed

+222
-166
lines changed

4 files changed

+222
-166
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.mcphackers.mcp;
2+
3+
@FunctionalInterface
4+
public interface TriFunction<E, T, U, R> {
5+
6+
R apply(E e, T t, U u);
7+
}

src/main/java/org/mcphackers/mcp/tasks/TaskDecompile.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public void doTask() throws Exception {
7777
case REMAP:
7878
if (Files.exists(mappings)) {
7979
MappingUtil.readMappings(mappings, mappingTree);
80-
MappingUtil.modifyMappings(mappingTree, FileSystems.newFileSystem(originalJar, null).getPath("/"), className -> {
80+
MappingUtil.modifyClasses(mappingTree, FileSystems.newFileSystem(originalJar, null).getPath("/"), className -> {
8181
if (mappingTree.getClass(className) == null) {
8282
if(className.lastIndexOf("/") < 0) {
8383
return "net/minecraft/src/" + className;
@@ -86,7 +86,7 @@ public void doTask() throws Exception {
8686
return null;
8787
});
8888
MappingUtil.writeMappings(deobfMappings, mappingTree);
89-
MappingUtil.remap(mappings, originalJar, Paths.get(tinyOut), true, getLibraryPaths(side));
89+
MappingUtil.remap(deobfMappings, originalJar, Paths.get(tinyOut), getLibraryPaths(side), "official", "named");
9090
}
9191
else {
9292
Files.copy(originalJar, Paths.get(tinyOut));

src/main/java/org/mcphackers/mcp/tasks/TaskReobfuscate.java

Lines changed: 144 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -20,148 +20,148 @@
2020
import java.util.Map;
2121

2222
public class TaskReobfuscate extends Task {
23-
private final Map<String, String> recompHashes = new HashMap<>();
24-
private final Map<String, String> originalHashes = new HashMap<>();
25-
26-
private MemoryMappingTree mappingTree = new MemoryMappingTree();
27-
28-
private final Map<String, String> reobfPackages = new HashMap<>();
29-
30-
private final TaskUpdateMD5 md5Task = new TaskUpdateMD5(side, info);
31-
32-
public TaskReobfuscate(int side, TaskInfo info) {
33-
super(side, info);
34-
}
35-
36-
@Override
37-
public void doTask() throws Exception {
38-
39-
Path reobfJar = Paths.get(chooseFromSide(MCPConfig.CLIENT_REOBF_JAR, MCPConfig.SERVER_REOBF_JAR));
40-
Path reobfBin = Paths.get(chooseFromSide(MCPConfig.CLIENT_BIN, MCPConfig.SERVER_BIN));
41-
Path reobfDir = Paths.get(chooseFromSide(MCPConfig.CLIENT_REOBF, MCPConfig.SERVER_REOBF));
42-
Path reobfMappings = Paths.get(chooseFromSide(MCPConfig.CLIENT_MAPPINGS_RO, MCPConfig.SERVER_MAPPINGS_RO));
43-
Path deobfMappings = Paths.get(chooseFromSide(MCPConfig.CLIENT_MAPPINGS_DO, MCPConfig.SERVER_MAPPINGS_DO));
44-
45-
step();
46-
md5Task.updateMD5(true);
47-
48-
if (Files.exists(reobfBin)) {
49-
boolean hasMappings = Files.exists(deobfMappings);
50-
FileUtil.deleteDirectoryIfExists(reobfDir);
51-
step();
52-
gatherMD5Hashes(true);
53-
gatherMD5Hashes(false);
54-
55-
step();
56-
if (hasMappings) {
57-
MappingUtil.readMappings(deobfMappings, mappingTree);
58-
flipMappingTree();
59-
MappingUtil.modifyMappings(mappingTree, reobfBin, className -> {
60-
if (mappingTree.getClass(className) == null) { // Class isn't present in original mappings
61-
String packageName = className.lastIndexOf("/") >= 0 ? className.substring(0, className.lastIndexOf("/") + 1) : null;
62-
String obfPackage = reobfPackages.get(packageName);
63-
if (obfPackage == null) {
64-
obfPackage = "";
65-
}
66-
return obfPackage + (className.lastIndexOf("/") >= 0 ? className.substring(className.lastIndexOf("/") + 1) : className);
67-
}
68-
return null; // Returning null skips remapping this class
69-
});
70-
MappingUtil.writeMappings(reobfMappings, mappingTree);
71-
72-
}
73-
74-
Files.deleteIfExists(reobfJar);
75-
if (hasMappings) {
76-
MappingUtil.remap(reobfMappings, reobfBin, reobfJar, TaskDecompile.getLibraryPaths(side));
77-
} else {
78-
FileUtil.compress(reobfBin, reobfJar);
79-
}
80-
step();
81-
unpack(reobfJar, reobfDir);
82-
} else {
83-
throw new IOException(chooseFromSide("Client", "Server") + " classes not found!");
84-
}
85-
}
86-
87-
private void flipMappingTree() throws IOException {
88-
((MappingTree) mappingTree).getClasses().forEach(classEntry -> {
89-
String obfName = classEntry.getName("official");
90-
String deobfName = classEntry.getName("named");
91-
if (deobfName != null) {
92-
String obfPackage = obfName.lastIndexOf("/") >= 0 ? obfName.substring(0, obfName.lastIndexOf("/") + 1) : "";
93-
String deobfPackage = deobfName.lastIndexOf("/") >= 0 ? deobfName.substring(0, deobfName.lastIndexOf("/") + 1) : "";
94-
if (!reobfPackages.containsKey(deobfPackage)) {
95-
reobfPackages.put(deobfPackage, obfPackage);
96-
}
97-
}
98-
});
99-
100-
Map<String, String> namespaces = new HashMap<>();
101-
namespaces.put("named", "official");
102-
MemoryMappingTree namedTree = new MemoryMappingTree();
103-
MappingNsCompleter nsCompleter = new MappingNsCompleter(namedTree, namespaces);
104-
MappingSourceNsSwitch nsSwitch = new MappingSourceNsSwitch(nsCompleter, "named");
105-
mappingTree.accept(nsSwitch);
106-
mappingTree = namedTree;
107-
}
108-
109-
@Override
110-
public ProgressInfo getProgress() {
111-
int total = 100;
112-
int current;
113-
switch (step) {
114-
case 1: {
115-
current = 1;
116-
ProgressInfo info = md5Task.getProgress();
117-
int percent = info.getCurrent() / info.getTotal() * 50;
118-
return new ProgressInfo(info.getMessage(), current + percent, total);
119-
}
120-
case 2:
121-
current = 51;
122-
return new ProgressInfo("Gathering MD5 hashes...", current, total);
123-
case 3:
124-
current = 52;
125-
return new ProgressInfo("Reobfuscating...", current, total);
126-
case 4:
127-
current = 54;
128-
return new ProgressInfo("Unpacking...", current, total);
129-
default:
130-
return super.getProgress();
131-
}
132-
}
133-
134-
private void gatherMD5Hashes(boolean reobf) throws IOException {
135-
Path md5 = Paths.get(reobf ? chooseFromSide(MCPConfig.CLIENT_MD5_RO, MCPConfig.SERVER_MD5_RO)
136-
: chooseFromSide(MCPConfig.CLIENT_MD5, MCPConfig.SERVER_MD5));
137-
138-
try (BufferedReader reader = Files.newBufferedReader(md5)) {
139-
String line = reader.readLine();
140-
while (line != null) {
141-
String[] tokens = line.split(" ");
142-
if (reobf) {
143-
recompHashes.put(tokens[0], tokens[1]);
144-
} else {
145-
originalHashes.put(tokens[0], tokens[1]);
146-
}
147-
148-
// Read next line
149-
line = reader.readLine();
150-
}
151-
}
152-
}
153-
154-
private void unpack(final Path src, final Path destDir) throws IOException {
155-
Map<String, String> reobfClasses = new HashMap<>();
156-
((MappingTree) mappingTree).getClasses().forEach(classEntry -> {
157-
reobfClasses.put(classEntry.getName("named"), classEntry.getDstName(0));
158-
});
159-
FileUtil.unzip(src, destDir, entry -> {
160-
String name = entry.getName().replace(".class", "");
161-
String deobfName = Util.getKey(reobfClasses, name);
162-
if (deobfName == null) deobfName = name.replace("\\", "/");
163-
String hash = originalHashes.get(deobfName);
164-
return !entry.isDirectory() && (hash == null || !hash.equals(recompHashes.get(deobfName)));
165-
});
166-
}
23+
private final Map<String, String> recompHashes = new HashMap<>();
24+
private final Map<String, String> originalHashes = new HashMap<>();
25+
26+
private MemoryMappingTree mappingTree = new MemoryMappingTree();
27+
28+
private final Map<String, String> reobfPackages = new HashMap<>();
29+
30+
private final TaskUpdateMD5 md5Task = new TaskUpdateMD5(side, info);
31+
32+
public TaskReobfuscate(int side, TaskInfo info) {
33+
super(side, info);
34+
}
35+
36+
@Override
37+
public void doTask() throws Exception {
38+
39+
Path reobfJar = Paths.get(chooseFromSide(MCPConfig.CLIENT_REOBF_JAR, MCPConfig.SERVER_REOBF_JAR));
40+
Path reobfBin = Paths.get(chooseFromSide(MCPConfig.CLIENT_BIN, MCPConfig.SERVER_BIN));
41+
Path reobfDir = Paths.get(chooseFromSide(MCPConfig.CLIENT_REOBF, MCPConfig.SERVER_REOBF));
42+
Path reobfMappings = Paths.get(chooseFromSide(MCPConfig.CLIENT_MAPPINGS_RO, MCPConfig.SERVER_MAPPINGS_RO));
43+
Path deobfMappings = Paths.get(chooseFromSide(MCPConfig.CLIENT_MAPPINGS_DO, MCPConfig.SERVER_MAPPINGS_DO));
44+
45+
step();
46+
md5Task.updateMD5(true);
47+
48+
if (Files.exists(reobfBin)) {
49+
boolean hasMappings = Files.exists(deobfMappings);
50+
FileUtil.deleteDirectoryIfExists(reobfDir);
51+
step();
52+
gatherMD5Hashes(true);
53+
gatherMD5Hashes(false);
54+
55+
step();
56+
if (hasMappings) {
57+
MappingUtil.readMappings(deobfMappings, mappingTree);
58+
flipMappingTree();
59+
MappingUtil.modifyClasses(mappingTree, reobfBin, className -> {
60+
if (mappingTree.getClass(className) == null) { // Class isn't present in original mappings
61+
String packageName = className.lastIndexOf("/") >= 0 ? className.substring(0, className.lastIndexOf("/") + 1) : null;
62+
String obfPackage = reobfPackages.get(packageName);
63+
if (obfPackage == null) {
64+
obfPackage = "";
65+
}
66+
return obfPackage + (className.lastIndexOf("/") >= 0 ? className.substring(className.lastIndexOf("/") + 1) : className);
67+
}
68+
return null; // Returning null skips remapping this class
69+
});
70+
MappingUtil.writeMappings(reobfMappings, mappingTree);
71+
72+
}
73+
74+
Files.deleteIfExists(reobfJar);
75+
if (hasMappings) {
76+
MappingUtil.remap(reobfMappings, reobfBin, reobfJar, TaskDecompile.getLibraryPaths(side), "named", "official");
77+
} else {
78+
FileUtil.compress(reobfBin, reobfJar);
79+
}
80+
step();
81+
unpack(reobfJar, reobfDir);
82+
} else {
83+
throw new IOException(chooseFromSide("Client", "Server") + " classes not found!");
84+
}
85+
}
86+
87+
private void flipMappingTree() throws IOException {
88+
((MappingTree) mappingTree).getClasses().forEach(classEntry -> {
89+
String obfName = classEntry.getName("official");
90+
String deobfName = classEntry.getName("named");
91+
if (deobfName != null) {
92+
String obfPackage = obfName.lastIndexOf("/") >= 0 ? obfName.substring(0, obfName.lastIndexOf("/") + 1) : "";
93+
String deobfPackage = deobfName.lastIndexOf("/") >= 0 ? deobfName.substring(0, deobfName.lastIndexOf("/") + 1) : "";
94+
if (!reobfPackages.containsKey(deobfPackage) && deobfPackage != obfPackage) {
95+
reobfPackages.put(deobfPackage, obfPackage);
96+
}
97+
}
98+
});
99+
100+
Map<String, String> namespaces = new HashMap<>();
101+
namespaces.put("named", "official");
102+
MemoryMappingTree namedTree = new MemoryMappingTree();
103+
MappingNsCompleter nsCompleter = new MappingNsCompleter(namedTree, namespaces);
104+
MappingSourceNsSwitch nsSwitch = new MappingSourceNsSwitch(nsCompleter, "named");
105+
mappingTree.accept(nsSwitch);
106+
mappingTree = namedTree;
107+
}
108+
109+
@Override
110+
public ProgressInfo getProgress() {
111+
int total = 100;
112+
int current;
113+
switch (step) {
114+
case 1: {
115+
current = 1;
116+
ProgressInfo info = md5Task.getProgress();
117+
int percent = info.getCurrent() / info.getTotal() * 50;
118+
return new ProgressInfo(info.getMessage(), current + percent, total);
119+
}
120+
case 2:
121+
current = 51;
122+
return new ProgressInfo("Gathering MD5 hashes...", current, total);
123+
case 3:
124+
current = 52;
125+
return new ProgressInfo("Reobfuscating...", current, total);
126+
case 4:
127+
current = 54;
128+
return new ProgressInfo("Unpacking...", current, total);
129+
default:
130+
return super.getProgress();
131+
}
132+
}
133+
134+
private void gatherMD5Hashes(boolean reobf) throws IOException {
135+
Path md5 = Paths.get(reobf ? chooseFromSide(MCPConfig.CLIENT_MD5_RO, MCPConfig.SERVER_MD5_RO)
136+
: chooseFromSide(MCPConfig.CLIENT_MD5, MCPConfig.SERVER_MD5));
137+
138+
try (BufferedReader reader = Files.newBufferedReader(md5)) {
139+
String line = reader.readLine();
140+
while (line != null) {
141+
String[] tokens = line.split(" ");
142+
if (reobf) {
143+
recompHashes.put(tokens[0], tokens[1]);
144+
} else {
145+
originalHashes.put(tokens[0], tokens[1]);
146+
}
147+
148+
// Read next line
149+
line = reader.readLine();
150+
}
151+
}
152+
}
153+
154+
private void unpack(final Path src, final Path destDir) throws IOException {
155+
Map<String, String> reobfClasses = new HashMap<>();
156+
((MappingTree) mappingTree).getClasses().forEach(classEntry -> {
157+
reobfClasses.put(classEntry.getName("named"), classEntry.getDstName(0));
158+
});
159+
FileUtil.unzip(src, destDir, entry -> {
160+
String name = entry.getName().replace(".class", "");
161+
String deobfName = Util.getKey(reobfClasses, name);
162+
if (deobfName == null) deobfName = name.replace("\\", "/");
163+
String hash = originalHashes.get(deobfName);
164+
return !entry.isDirectory() && (hash == null || !hash.equals(recompHashes.get(deobfName)));
165+
});
166+
}
167167
}

0 commit comments

Comments
 (0)