Skip to content

Commit 24ae1b6

Browse files
committed
Add --reverseSrg option to support Mapped2Obf maps.
Only support one mapping file, no reason to support multiple. Fix mapping issues
1 parent 432a408 commit 24ae1b6

2 files changed

Lines changed: 48 additions & 37 deletions

File tree

src/main/java/net/minecraftforge/binarypatcher/ConsoleTool.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ public static void main(String[] args) throws IOException {
3131
OptionSpec<File> createO = parser.acceptsAll(Arrays.asList("dirty", "create")).withRequiredArg().ofType(File.class);
3232
OptionSpec<File> patchesO = parser.accepts("patches").withRequiredArg().ofType(File.class);
3333
OptionSpec<File> srgO = parser.accepts("srg").withRequiredArg().ofType(File.class);
34+
OptionSpec<Void> reverseSrgO = parser.accepts("reverse-srg");
3435
OptionSpec<File> sasO = parser.accepts("sas").withRequiredArg().ofType(File.class);
35-
OptionSpec<?>[] createOptions = new OptionSpec[] { patchesO, srgO, sasO };
36+
OptionSpec<?>[] createOptions = new OptionSpec[] { patchesO, srgO, reverseSrgO, sasO };
3637

3738
// Apply arguments
3839
OptionSpec<File> applyO = parser.accepts("apply").withRequiredArg().ofType(File.class);
@@ -122,10 +123,10 @@ public static void main(String[] args) throws IOException {
122123
}
123124

124125
if (options.has(srgO)) {
125-
for (File file : options.valuesOf(srgO)) {
126-
log(" SRG: " + file);
127-
gen.loadMappings(file);
128-
}
126+
boolean reverse = options.has(reverseSrgO);
127+
File file = options.valueOf(srgO);
128+
log(" SRG: " + file + (reverse ? " (reversed)" : ""));
129+
gen.loadMappings(file, reverse);
129130
}
130131

131132
gen.create();

src/main/java/net/minecraftforge/binarypatcher/Generator.java

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import java.nio.file.Files;
1515
import java.util.ArrayList;
1616
import java.util.Arrays;
17-
import java.util.Collections;
17+
import java.util.Enumeration;
1818
import java.util.HashMap;
1919
import java.util.HashSet;
2020
import java.util.List;
@@ -39,14 +39,14 @@ public class Generator {
3939
public static final String EXTENSION = ".lzma";
4040
private static final byte[] EMPTY_DATA = new byte[0];
4141

42-
private final Map<String, String> o2m = new HashMap<>();
43-
private final Map<String, String> m2o = new HashMap<>();
4442
private final Set<String> patches = new TreeSet<>();
4543

4644
private final File output;
4745
private final List<PatchSet> sets = new ArrayList<>();
4846
private boolean pack200 = false;
4947
private boolean legacy = false;
48+
private IMappingFile o2m = null;
49+
private IMappingFile m2o = null;
5050

5151
public Generator(File output) {
5252
this.output = output;
@@ -85,12 +85,21 @@ public Generator legacy(boolean value) {
8585
return this;
8686
}
8787

88-
public void loadMappings(File srg) throws IOException {
88+
/*
89+
* This is used when we do obfed binary patches
90+
* This should be the obf2srg mapping
91+
* We only use the class names and this is only used
92+
* to map the patch file class names to the obfed class files
93+
*/
94+
public void loadMappings(File srg, boolean reverse) throws IOException {
8995
IMappingFile map = IMappingFile.load(srg);
90-
map.getClasses().forEach(cls -> {
91-
o2m.put(cls.getOriginal(), cls.getMapped());
92-
m2o.put(cls.getOriginal(), cls.getMapped());
93-
});
96+
if (reverse) {
97+
o2m = map.reverse();
98+
m2o = map;
99+
} else {
100+
o2m = map;
101+
m2o = map.reverse();
102+
}
94103
}
95104

96105
public void loadPatches(File root) throws IOException {
@@ -138,33 +147,39 @@ public void create() throws IOException {
138147
}
139148
}
140149

150+
private void gatherClasses(Map<String, Set<String>> entries, ZipFile archive) {
151+
for (Enumeration<? extends ZipEntry> itr = archive.entries(); itr.hasMoreElements();) {
152+
String name = itr.nextElement().getName();
153+
if (!name.endsWith(".class"))
154+
continue;
155+
name = name.substring(0, name.length() - 6);
156+
int idx = name.indexOf('$');
157+
String outer = idx == -1 ? name : name.substring(0, idx);
158+
entries.computeIfAbsent(outer, k -> new HashSet<>()).add(name);
159+
}
160+
}
161+
141162
private Map<String, byte[]> gatherPatches(File clean, File dirty) throws IOException {
142163
Map<String, byte[]> binpatches = new TreeMap<>();
143164
try (ZipFile zclean = new ZipFile(clean);
144165
ZipFile zdirty = new ZipFile(dirty)){
145166

167+
// This is a map of all classes to their 'sibling' classes.
168+
// Specifically all outer classes grouped with their inner classes.
169+
// This is done because when we modify a class, it could have durastic changes to the synthetic inner classes.
170+
// So we jus assume that if we patch one thing, we patch all inner classes
146171
Map<String, Set<String>> entries = new HashMap<>();
147-
Collections.list(zclean.entries()).stream().map(e -> e.getName()).filter(e -> e.endsWith(".class")).map(e -> e.substring(0, e.length() - 6)).forEach(e -> {
148-
int idx = e.indexOf('$');
149-
if (idx != -1)
150-
entries.computeIfAbsent(e.substring(0, idx), k -> new HashSet<>()).add(e);
151-
else
152-
entries.computeIfAbsent(e, k -> new HashSet<>()).add(e);
153-
});
154-
Collections.list(zdirty.entries()).stream().map(e -> e.getName()).filter(e -> e.endsWith(".class")).map(e -> e.substring(0, e.length() - 6)).forEach(e -> {
155-
int idx = e.indexOf('$');
156-
if (idx != -1)
157-
entries.computeIfAbsent(e.substring(0, idx), k -> new HashSet<>()).add(e);
158-
else
159-
entries.computeIfAbsent(e, k -> new HashSet<>()).add(e);
160-
});
172+
gatherClasses(entries, zclean);
173+
gatherClasses(entries, zdirty);
161174

162175
log("Creating patches:");
163176
log(" Clean: " + clean);
164177
log(" Dirty: " + dirty);
165178
if (patches.isEmpty()) { //No patches, assume full set!
166179
for (String cls : entries.keySet()) {
167-
String srg = m2o.getOrDefault(cls, cls);
180+
// We use the srg name to make the names in the archive readable.
181+
// Doesn't actually effect the functionality, so is optional
182+
String srg = o2m == null ? cls : o2m.remapClass(cls);
168183
byte[] cleanData = getData(zclean, cls);
169184
byte[] dirtyData = getData(zdirty, cls);
170185
if (!Arrays.equals(cleanData, dirtyData)) {
@@ -175,17 +190,12 @@ private Map<String, byte[]> gatherPatches(File clean, File dirty) throws IOExcep
175190
}
176191
} else {
177192
for (String path : patches) {
178-
String obf = o2m.getOrDefault(path, path);
193+
// Map the patch dev name, to prodution name
194+
String obf = m2o == null ? path : m2o.remapClass(path);
195+
179196
if (entries.containsKey(obf)) {
180197
for (String cls : entries.get(obf)) {
181-
String srg = m2o.get(cls);
182-
if (srg == null) {
183-
int idx = cls.indexOf('$');
184-
if (idx == -1)
185-
srg = path;
186-
else
187-
srg = path + '$' + cls.substring(idx + 1);
188-
}
198+
String srg = o2m == null ? cls : o2m.remapClass(cls);
189199

190200
byte[] cleanData = getData(zclean, cls);
191201
byte[] dirtyData = getData(zdirty, cls);

0 commit comments

Comments
 (0)