From 5fb322a83d2e8a7b200becf616b0400034140067 Mon Sep 17 00:00:00 2001 From: Juuz <6596629+Juuxel@users.noreply.github.com> Date: Sun, 30 Apr 2023 02:41:57 +0300 Subject: [PATCH] GenerateForgePatchedSourcesTask: Apply AT and SAS before decompiling This makes the patches not get rejected, and the output actually looks like it should now. --- .../architectury/loom/forge/ForgeTools.java | 5 ++ .../forge/MinecraftPatchedProvider.java | 26 ++++++-- .../task/GenerateForgePatchedSourcesTask.java | 65 ++++++++++++++++++- 3 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 src/main/java/dev/architectury/loom/forge/ForgeTools.java diff --git a/src/main/java/dev/architectury/loom/forge/ForgeTools.java b/src/main/java/dev/architectury/loom/forge/ForgeTools.java new file mode 100644 index 00000000..5a943029 --- /dev/null +++ b/src/main/java/dev/architectury/loom/forge/ForgeTools.java @@ -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"; +} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java index c892e68a..b388d8ac 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider.java @@ -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 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 { diff --git a/src/main/java/net/fabricmc/loom/task/GenerateForgePatchedSourcesTask.java b/src/main/java/net/fabricmc/loom/task/GenerateForgePatchedSourcesTask.java index 160aada3..d1d61951 100644 --- a/src/main/java/net/fabricmc/loom/task/GenerateForgePatchedSourcesTask.java +++ b/src/main/java/net/fabricmc/loom/task/GenerateForgePatchedSourcesTask.java @@ -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 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()); + } }