Skip to content

Commit 8aa4e5f

Browse files
committed
Support injecting userdev specific files
1 parent 7e8f9bc commit 8aa4e5f

2 files changed

Lines changed: 98 additions & 11 deletions

File tree

src/main/java/net/minecraftforge/mcmaven/impl/repo/forge/InjectTask.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,13 @@
2222
public final class InjectTask implements Task {
2323
private final File build;
2424
private final Artifact name;
25-
private final Cache cache;
2625
private final Patcher patcher;
2726
private final Mappings mappings;
2827
private final Task task;
2928

3029
InjectTask(File build, Cache cache, Artifact name, Patcher patcher, Task input, Mappings mappings) {
3130
this.build = mappings.getFolder(build);
3231
this.name = name;
33-
this.cache = cache;
3432
this.patcher = patcher;
3533
this.mappings = mappings;
3634
this.task = this.injectData(input);
@@ -53,7 +51,7 @@ public String name() {
5351

5452
private Task injectData(Task input) {
5553
return Task.named("injectData[" + this.name.getName() + "][" + mappings + ']',
56-
Task.deps(input),
54+
Task.deps(input, this.patcher.filterBinaryInjections()),
5755
() -> injectDataImpl(input, new File(this.build, "injected.jar"))
5856
);
5957
}
@@ -65,13 +63,10 @@ private File injectDataImpl(Task inputTask, File outputJar) {
6563
cache.add("recompiled", recompiledJar);
6664

6765
var universals = new ArrayList<File>();
68-
for (var p : this.patcher.getStack()) {
69-
if (p.config.universal != null) {
70-
var universal = this.cache.maven().download(Artifact.from(p.config.universal));
71-
universals.add(universal);
72-
cache.add(universal);
73-
}
74-
}
66+
var injectTask = this.patcher.filterBinaryInjections();
67+
var inject = injectTask != null ? injectTask.execute() : null;
68+
if (inject != null)
69+
cache.add("inject", inject);
7570

7671
if (Mavenizer.checkCache(outputJar, cache))
7772
return outputJar;
@@ -80,8 +75,10 @@ private File injectDataImpl(Task inputTask, File outputJar) {
8075
var jars = new ArrayList<>(universals);
8176

8277
jars.add(recompiledJar);
78+
if (inject != null)
79+
jars.add(inject);
8380

84-
FileUtils.mergeJars(outputJar, true, (file, name) -> file == recompiledJar || !name.endsWith(".class"), jars.toArray(File[]::new));
81+
FileUtils.mergeJars(outputJar, true, (file, name) -> (file == recompiledJar || file == inject) || !name.endsWith(".class"), jars.toArray(File[]::new));
8582
} catch (IOException e) {
8683
return Util.sneak(e);
8784
}

src/main/java/net/minecraftforge/mcmaven/impl/repo/forge/Patcher.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
package net.minecraftforge.mcmaven.impl.repo.forge;
66

77
import java.io.File;
8+
import java.io.FileInputStream;
89
import java.io.FileNotFoundException;
910
import java.io.FileOutputStream;
1011
import java.io.IOException;
12+
import java.nio.charset.StandardCharsets;
1113
import java.util.ArrayList;
1214
import java.util.Collections;
1315
import java.util.HashMap;
@@ -19,7 +21,10 @@
1921
import java.util.function.Predicate;
2022
import java.util.function.Supplier;
2123
import java.util.stream.Collectors;
24+
import java.util.zip.ZipEntry;
2225
import java.util.zip.ZipFile;
26+
import java.util.zip.ZipInputStream;
27+
import java.util.zip.ZipOutputStream;
2328

2429
import io.codechicken.diffpatch.cli.PatchOperation;
2530
import io.codechicken.diffpatch.util.LogLevel;
@@ -70,6 +75,7 @@ public class Patcher implements Supplier<Task> {
7075
private final Task downloadSources;
7176
private final Task predecomp;
7277
private final Task last;
78+
private final Task filterBinaryInjections;
7379

7480
/**
7581
* Creates a new Patcher for the given Forge repo.
@@ -162,6 +168,15 @@ public class Patcher implements Supplier<Task> {
162168
}
163169

164170
this.last = last;
171+
172+
var binaryInjections = new ArrayList<Patcher>();
173+
for (var p : this.getStack()) {
174+
if (p.config.inject != null)
175+
binaryInjections.add(p);
176+
}
177+
178+
this.filterBinaryInjections = binaryInjections.isEmpty() ? null :
179+
Task.named("filterBinaryInjections[" + this.name.getName() + ']', this::filterBinaryInjectionsImpl);
165180
}
166181

167182
private RuntimeException except(String message) {
@@ -215,6 +230,14 @@ public MCPSide getMCPSide() {
215230
return this.mcpSide == null ? this.parent.getMCPSide() : this.mcpSide;
216231
}
217232

233+
public String getName() {
234+
return this.name.getName();
235+
}
236+
237+
public Artifact getArtifact() {
238+
return this.name;
239+
}
240+
218241
public String getDataHash() {
219242
return this.dataHash;
220243
}
@@ -675,4 +698,71 @@ private File injectSourcesImpl(Task inputTask, File output) {
675698
cache.save();
676699
return output;
677700
}
701+
702+
public @Nullable Task filterBinaryInjections() {
703+
return this.filterBinaryInjections;
704+
}
705+
706+
private File filterBinaryInjectionsImpl() {
707+
var output = new File(this.build, "binary-injections.jar");
708+
var cache = Util.cache(output);
709+
cache.addKnown("data", this.getDataHash());
710+
for (var p : getStack(false)) {
711+
if (p.config.inject != null)
712+
cache.addKnown("parent-" + p.getName(), p.getDataHash());
713+
}
714+
715+
if (Mavenizer.checkCache(output, cache))
716+
return output;
717+
718+
if (output.getParentFile() != null)
719+
output.getParentFile().mkdirs();
720+
721+
try (var zos = new ZipOutputStream(new FileOutputStream(output))) {
722+
var servicesLists = new HashMap<String, List<String>>();
723+
var seen = new HashSet<String>();
724+
for (var patcher : this.getStack()) {
725+
try (var zin = new ZipInputStream(new FileInputStream(this.data))) {
726+
ZipEntry entry;
727+
var prefix = config.inject;
728+
while ((entry = zin.getNextEntry()) != null) {
729+
if (!entry.getName().startsWith(prefix) || entry.getName().length() <= prefix.length())
730+
continue;
731+
732+
String name = entry.getName().substring(prefix.length());
733+
734+
if (name.startsWith("META-INF/services/") && !entry.isDirectory()) {
735+
var existing = servicesLists.computeIfAbsent(name, _ -> new ArrayList<>());
736+
if (existing.size() > 0) {
737+
existing.add("");
738+
existing.add("# " + patcher.getArtifact());
739+
}
740+
existing.add(new String(zin.readAllBytes(), StandardCharsets.UTF_8));
741+
} else if (seen.add(name)) {
742+
var _new = new ZipEntry(name);
743+
_new.setTime(0);
744+
zos.putNextEntry(_new);
745+
zin.transferTo(zos);
746+
}
747+
}
748+
}
749+
}
750+
751+
for(var kv : servicesLists.entrySet()) {
752+
String name = kv.getKey();
753+
ZipEntry _new = new ZipEntry(name);
754+
_new.setTime(0);
755+
zos.putNextEntry(_new);
756+
for (var line : kv.getValue()) {
757+
zos.write(line.getBytes(StandardCharsets.UTF_8));
758+
zos.write('\n');
759+
}
760+
}
761+
} catch (IOException e) {
762+
return Util.sneak(e);
763+
}
764+
765+
cache.save();
766+
return output;
767+
}
678768
}

0 commit comments

Comments
 (0)