GenerateForgePatchedSourcesTask: Apply AT and SAS before decompiling

This makes the patches not get rejected, and the output actually looks like
it should now.
This commit is contained in:
Juuz
2023-04-30 02:41:57 +03:00
parent 2d6218686e
commit 5fb322a83d
3 changed files with 86 additions and 10 deletions

View File

@@ -0,0 +1,5 @@
package dev.architectury.loom.forge;
public final class ForgeTools {
public static final String SIDE_STRIPPER = "net.minecraftforge:mergetool:1.1.6:fatjar";
}

View File

@@ -51,7 +51,6 @@ import java.util.stream.Stream;
import com.google.common.base.Preconditions;
import com.google.common.base.Stopwatch;
import com.google.common.collect.ImmutableList;
import de.oceanlabs.mcp.mcinjector.adaptors.ParameterAnnotationFixer;
import dev.architectury.loom.util.TempFiles;
import dev.architectury.tinyremapper.InputTag;
@@ -360,17 +359,30 @@ public class MinecraftPatchedProvider {
}
private void accessTransformForge() throws IOException {
Stopwatch stopwatch = Stopwatch.createStarted();
logger.lifecycle(":access transforming minecraft");
Path input = minecraftPatchedSrgJar;
Path target = minecraftPatchedSrgAtJar;
accessTransform(project, input, target);
}
public static void accessTransform(Project project, Path input, Path target) throws IOException {
Stopwatch stopwatch = Stopwatch.createStarted();
project.getLogger().lifecycle(":access transforming minecraft");
LoomGradleExtension extension = LoomGradleExtension.get(project);
List<Path> atSources = List.of(
extension.getForgeUniversalProvider().getForge().toPath(),
extension.getForgeUserdevProvider().getUserdevJar().toPath(),
((ForgeMinecraftProvider) extension.getMinecraftProvider())
.getPatchedProvider()
.getMinecraftPatchedSrgJar()
);
Files.deleteIfExists(target);
try (var tempFiles = new TempFiles()) {
AccessTransformerJarProcessor.executeAt(project, input, target, args -> {
for (Path jar : ImmutableList.of(getForgeJar().toPath(), getExtension().getForgeUserdevProvider().getUserdevJar().toPath(), minecraftPatchedSrgJar)) {
for (Path jar : atSources) {
byte[] atBytes = ZipUtils.unpackNullable(jar, Constants.Forge.ACCESS_TRANSFORMER_PATH);
if (atBytes != null) {
@@ -383,7 +395,7 @@ public class MinecraftPatchedProvider {
});
}
logger.lifecycle(":access transformed minecraft in " + stopwatch.stop());
project.getLogger().lifecycle(":access transformed minecraft in " + stopwatch.stop());
}
private void remapPatchedJar(SharedServiceManager serviceManager) throws Exception {

View File

@@ -27,13 +27,21 @@ package net.fabricmc.loom.task;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import codechicken.diffpatch.cli.CliOperation;
import codechicken.diffpatch.cli.PatchOperation;
import codechicken.diffpatch.util.LoggingOutputStream;
import codechicken.diffpatch.util.PatchMode;
import com.google.common.base.Stopwatch;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import dev.architectury.loom.forge.ForgeTools;
import dev.architectury.loom.util.TempFiles;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.logging.LogLevel;
import org.gradle.api.tasks.InputFile;
@@ -47,6 +55,9 @@ import net.fabricmc.loom.configuration.providers.forge.MinecraftPatchedProvider;
import net.fabricmc.loom.configuration.providers.forge.mcpconfig.McpExecutor;
import net.fabricmc.loom.configuration.providers.forge.mcpconfig.steplogic.ConstantLogic;
import net.fabricmc.loom.configuration.sources.ForgeSourcesRemapper;
import net.fabricmc.loom.util.DependencyDownloader;
import net.fabricmc.loom.util.FileSystemUtil;
import net.fabricmc.loom.util.ForgeToolExecutor;
import net.fabricmc.loom.util.SourceRemapper;
import net.fabricmc.loom.util.service.ScopedSharedServiceManager;
import net.fabricmc.loom.util.service.SharedServiceManager;
@@ -86,8 +97,15 @@ public abstract class GenerateForgePatchedSourcesTask extends AbstractLoomTask {
try (var tempFiles = new TempFiles(); var serviceManager = new ScopedSharedServiceManager()) {
Path cache = tempFiles.directory("loom-decompilation");
// Transform game jar before decompiling
Path accessTransformed = cache.resolve("access-transformed.jar");
MinecraftPatchedProvider.accessTransform(getProject(), getInputJar().get().getAsFile().toPath(), accessTransformed);
Path sideAnnotationStripped = cache.resolve("side-annotation-stripped.jar");
stripSideAnnotations(accessTransformed, sideAnnotationStripped);
// Step 1: decompile and patch with MCP patches
Path rawDecompiled = decompileAndPatch(cache);
Path rawDecompiled = decompileAndPatch(cache, sideAnnotationStripped);
// Step 2: patch with Forge patches
getLogger().lifecycle(":applying Forge patches");
Path patched = sourcePatch(cache, rawDecompiled);
@@ -98,7 +116,7 @@ public abstract class GenerateForgePatchedSourcesTask extends AbstractLoomTask {
}
}
private Path decompileAndPatch(Path cache) throws IOException {
private Path decompileAndPatch(Path cache, Path gameJar) throws IOException {
Path mcpCache = cache.resolve("mcp");
Files.createDirectory(mcpCache);
@@ -106,7 +124,7 @@ public abstract class GenerateForgePatchedSourcesTask extends AbstractLoomTask {
McpExecutor mcp = patchedProvider.createMcpExecutor(mcpCache);
mcp.setStepLogicProvider((name, type) -> {
if (name.equals("rename")) {
return Optional.of(new ConstantLogic(() -> getInputJar().get().getAsFile().toPath()));
return Optional.of(new ConstantLogic(() -> gameJar));
}
return Optional.empty();
@@ -148,4 +166,45 @@ public abstract class GenerateForgePatchedSourcesTask extends AbstractLoomTask {
});
remapper.remapAll();
}
private void stripSideAnnotations(Path input, Path output) throws IOException {
final Stopwatch stopwatch = Stopwatch.createStarted();
getLogger().lifecycle(":stripping side annotations");
try (var tempFiles = new TempFiles()) {
final ForgeUserdevProvider userdevProvider = getExtension().getForgeUserdevProvider();
final JsonArray sass = userdevProvider.getJson().getAsJsonArray("sass");
final List<Path> sasPaths = new ArrayList<>();
try (FileSystemUtil.Delegate fs = FileSystemUtil.getJarFileSystem(userdevProvider.getUserdevJar(), false)) {
for (JsonElement sasPath : sass) {
try {
final Path from = fs.getPath(sasPath.getAsString());
final Path to = tempFiles.file(null, ".sas");
Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING);
sasPaths.add(to);
} catch (IOException e) {
throw new IOException("Could not extract SAS " + sasPath.getAsString());
}
}
}
final FileCollection classpath = DependencyDownloader.download(getProject(), ForgeTools.SIDE_STRIPPER, false, true);
ForgeToolExecutor.exec(getProject(), spec -> {
spec.setClasspath(classpath);
spec.args(
"--strip",
"--input", input.toAbsolutePath().toString(),
"--output", output.toAbsolutePath().toString()
);
for (Path sasPath : sasPaths) {
spec.args("--data", sasPath.toAbsolutePath().toString());
}
});
}
getLogger().lifecycle(":side annotations stripped in " + stopwatch.stop());
}
}