From e73b11da1dbdfa34b9bec744d9425bc512ab6719 Mon Sep 17 00:00:00 2001 From: Juuz <6596629+Juuxel@users.noreply.github.com> Date: Tue, 18 Jan 2022 19:01:00 +0200 Subject: [PATCH] MinecraftPatchedProvider2 is now the actual thing --- .../configuration/CompileConfiguration.java | 4 +- .../forge/MinecraftPatchedProvider.java | 218 +++-- .../forge/MinecraftPatchedProvider2.java | 778 ------------------ .../minecraft/MinecraftJarConfiguration.java | 4 +- 4 files changed, 106 insertions(+), 898 deletions(-) delete mode 100644 src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider2.java diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index 19a109f4..7b483350 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -50,7 +50,7 @@ import net.fabricmc.loom.configuration.providers.forge.ForgeProvider; import net.fabricmc.loom.configuration.providers.forge.ForgeUniversalProvider; import net.fabricmc.loom.configuration.providers.forge.ForgeUserdevProvider; import net.fabricmc.loom.configuration.providers.forge.McpConfigProvider; -import net.fabricmc.loom.configuration.providers.forge.MinecraftPatchedProvider2; +import net.fabricmc.loom.configuration.providers.forge.MinecraftPatchedProvider; import net.fabricmc.loom.configuration.providers.forge.PatchProvider; import net.fabricmc.loom.configuration.providers.forge.SrgProvider; import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; @@ -266,7 +266,7 @@ public final class CompileConfiguration { // Provide the vanilla mc jars -- TODO share across projects. final MinecraftProvider minecraftProvider = jarConfiguration.getMinecraftProviderFunction().apply(project); - if (extension.isForge() && !(minecraftProvider instanceof MinecraftPatchedProvider2)) { + if (extension.isForge() && !(minecraftProvider instanceof MinecraftPatchedProvider)) { throw new UnsupportedOperationException("Using Forge with split or server-only jars is not currently supported!"); } 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 aef22063..29af2c5e 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 @@ -1,27 +1,3 @@ -/* - * This file is part of fabric-loom, licensed under the MIT License (MIT). - * - * Copyright (c) 2020-2021 FabricMC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - package net.fabricmc.loom.configuration.providers.forge; import java.io.ByteArrayInputStream; @@ -49,7 +25,6 @@ import java.util.Locale; import java.util.Objects; import java.util.Set; import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.jar.Attributes; @@ -78,6 +53,7 @@ import org.gradle.api.logging.Logger; import org.gradle.api.logging.configuration.ShowStacktrace; import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.tasks.SourceSet; +import org.jetbrains.annotations.Nullable; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; @@ -86,11 +62,12 @@ import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.ClassNode; -import net.fabricmc.loom.configuration.DependencyProvider; -import net.fabricmc.loom.configuration.providers.MinecraftProviderImpl; +import net.fabricmc.loom.LoomGradleExtension; +import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.DependencyDownloader; import net.fabricmc.loom.util.FileSystemUtil; +import net.fabricmc.loom.util.FunnyTodoException; import net.fabricmc.loom.util.MappingsProviderVerbose; import net.fabricmc.loom.util.ThreadingUtils; import net.fabricmc.loom.util.TinyRemapperHelper; @@ -100,7 +77,7 @@ import net.fabricmc.loom.util.srg.InnerClassRemapper; import net.fabricmc.loom.util.srg.SpecialSourceExecutor; import net.fabricmc.mappingio.tree.MemoryMappingTree; -public class MinecraftPatchedProvider extends DependencyProvider { +public class MinecraftPatchedProvider extends MergedMinecraftProvider { private static final String LOOM_PATCH_VERSION_KEY = "Loom-Patch-Version"; private static final String CURRENT_LOOM_PATCH_VERSION = "5"; private static final String NAME_MAPPING_SERVICE_PATH = "/inject/META-INF/services/cpw.mods.modlauncher.api.INameMappingService"; @@ -117,84 +94,50 @@ public class MinecraftPatchedProvider extends DependencyProvider { private File minecraftMergedPatchedSrgAtJar; // Step 5: Remap Patched AT & Forge to Official (global or project) private File minecraftMergedPatchedJar; + @Nullable private File forgeMergedJar; private File minecraftClientExtra; + private boolean dirty; private File projectAtHash; private Set projectAts = new HashSet<>(); private boolean atDirty = false; private boolean filesDirty = false; - private Path mcpConfigMappings; - private Path[] mergedMojangTsrg2Files; + + public static MergedMinecraftProvider getMergedMinecraftProvider(Project project) { + return LoomGradleExtension.get(project).isForge() ? new MinecraftPatchedProvider(project) : new MergedMinecraftProvider(project); + } public MinecraftPatchedProvider(Project project) { super(project); } - public void initFiles() throws IOException { - filesDirty = false; - projectAtHash = new File(getDirectories().getProjectPersistentCache(), "at.sha256"); - ConfigurableFileCollection accessTransformers = getExtension().getForge().getAccessTransformers(); - accessTransformers.finalizeValue(); - projectAts = accessTransformers.getFiles(); + @Override + protected void initFiles() { + super.initFiles(); - if (projectAts.isEmpty()) { - SourceSet main = getProject().getConvention().findPlugin(JavaPluginConvention.class).getSourceSets().getByName("main"); - - for (File srcDir : main.getResources().getSrcDirs()) { - File projectAt = new File(srcDir, Constants.Forge.ACCESS_TRANSFORMER_PATH); - - if (projectAt.exists()) { - this.projectAts.add(projectAt); - break; - } - } - } - - if (isRefreshDeps() || !projectAtHash.exists()) { - writeAtHash(); - atDirty = !projectAts.isEmpty(); - } else { - byte[] expected = com.google.common.io.Files.asByteSource(projectAtHash).read(); - byte[] current = getProjectAtsHash(); - boolean mismatched = !Arrays.equals(current, expected); - - if (mismatched) { - writeAtHash(); - } - - atDirty = mismatched; - } - - MinecraftProviderImpl minecraftProvider = getExtension().getMinecraftProvider(); PatchProvider patchProvider = getExtension().getPatchProvider(); - String minecraftVersion = minecraftProvider.minecraftVersion(); + String minecraftVersion = minecraftVersion(); String patchId = "forge-" + getExtension().getForgeProvider().getVersion().getCombined() + "-"; - if (getExtension().isForgeAndOfficial()) { - minecraftProvider.setJarPrefix(patchId); - } + FunnyTodoException.yes("jar prefix"); + //if (getExtension().isForgeAndOfficial()) { + // minecraftProvider.setJarPrefix(patchId); + //} File globalCache = getExtension().getForgeProvider().getGlobalCache(); File projectDir = usesProjectCache() ? getExtension().getForgeProvider().getProjectCache() : globalCache; projectDir.mkdirs(); - minecraftClientSrgJar = new File(globalCache, "minecraft-client-srg.jar"); - minecraftServerSrgJar = new File(globalCache, "minecraft-server-srg.jar"); - minecraftClientPatchedSrgJar = new File(globalCache, "client-srg-patched.jar"); - minecraftServerPatchedSrgJar = new File(globalCache, "server-srg-patched.jar"); - minecraftMergedPatchedSrgJar = new File(globalCache, "merged-srg-patched.jar"); - forgeMergedJar = getExtension().isForgeAndOfficial() ? null : new File(globalCache, "forge-official.jar"); - minecraftMergedPatchedSrgAtJar = new File(projectDir, "merged-srg-at-patched.jar"); - minecraftMergedPatchedJar = new File(projectDir, "merged-patched.jar"); - minecraftClientExtra = new File(globalCache, "forge-client-extra.jar"); - - if (isRefreshDeps() || Stream.of(getGlobalCaches()).anyMatch(((Predicate) File::exists).negate()) - || !isPatchedJarUpToDate(minecraftMergedPatchedJar)) { - cleanAllCache(); - } else if (atDirty || Stream.of(getProjectCache()).anyMatch(((Predicate) File::exists).negate())) { - cleanProjectCache(); - } + minecraftClientSrgJar = file("minecraft-client-srg.jar"); + minecraftServerSrgJar = file("minecraft-server-srg.jar"); + minecraftClientPatchedSrgJar = file("client-srg-patched.jar"); + minecraftServerPatchedSrgJar = file("server-srg-patched.jar"); + minecraftMergedPatchedSrgJar = file("merged-srg-patched.jar"); + forgeMergedJar = getExtension().isForgeAndOfficial() ? null : file("forge-official.jar"); + minecraftMergedPatchedSrgAtJar = file("merged-srg-at-patched.jar"); + minecraftMergedPatchedJar = file("merged-patched.jar"); + minecraftClientExtra = file("forge-client-extra.jar"); } private byte[] getProjectAtsHash() throws IOException { @@ -247,15 +190,52 @@ public class MinecraftPatchedProvider extends DependencyProvider { }; } - private boolean dirty; + private void checkAtAndCache() throws IOException { + filesDirty = false; + projectAtHash = new File(getExtension().getFiles().getProjectPersistentCache(), "at.sha256"); + ConfigurableFileCollection accessTransformers = getExtension().getForge().getAccessTransformers(); + accessTransformers.finalizeValue(); + projectAts = accessTransformers.getFiles(); + + if (projectAts.isEmpty()) { + SourceSet main = getProject().getConvention().findPlugin(JavaPluginConvention.class).getSourceSets().getByName("main"); + + for (File srcDir : main.getResources().getSrcDirs()) { + File projectAt = new File(srcDir, Constants.Forge.ACCESS_TRANSFORMER_PATH); + + if (projectAt.exists()) { + this.projectAts.add(projectAt); + break; + } + } + } + + if (isRefreshDeps() || !projectAtHash.exists()) { + writeAtHash(); + atDirty = !projectAts.isEmpty(); + } else { + byte[] expected = com.google.common.io.Files.asByteSource(projectAtHash).read(); + byte[] current = getProjectAtsHash(); + boolean mismatched = !Arrays.equals(current, expected); + + if (mismatched) { + writeAtHash(); + } + + atDirty = mismatched; + } + + if (isRefreshDeps() || Stream.of(getGlobalCaches()).anyMatch(((Predicate) File::exists).negate()) + || !isPatchedJarUpToDate(minecraftMergedPatchedJar)) { + cleanAllCache(); + } else if (atDirty || Stream.of(getProjectCache()).anyMatch(((Predicate) File::exists).negate())) { + cleanProjectCache(); + } + } @Override - public void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception { - initFiles(); - - if (atDirty) { - getProject().getLogger().lifecycle(":found dirty access transformers"); - } + public void provide() throws Exception { + super.provide(); this.dirty = false; @@ -269,9 +249,7 @@ public class MinecraftPatchedProvider extends DependencyProvider { this.dirty = true; patchJars(getProject().getLogger()); } - } - public void finishProvide() throws Exception { if (dirty || !minecraftMergedPatchedSrgJar.exists()) { mergeJars(getProject().getLogger()); } @@ -297,15 +275,20 @@ public class MinecraftPatchedProvider extends DependencyProvider { this.dirty = false; if (getExtension().isForgeAndOfficial()) { - addDependency(minecraftClientExtra, Constants.Configurations.FORGE_EXTRA); + DependencyProvider.addDependency(getProject(), minecraftClientExtra, Constants.Configurations.FORGE_EXTRA); } } + @Override + protected void mergeJars() throws IOException { + // Don't merge jars in the superclass + } + private void fillClientExtraJar() throws IOException { Files.deleteIfExists(minecraftClientExtra.toPath()); FileSystemUtil.getJarFileSystem(minecraftClientExtra, true).close(); - copyNonClassFiles(getExtension().getMinecraftProvider().minecraftClientJar, minecraftClientExtra); + copyNonClassFiles(getMinecraftClientJar(), minecraftClientExtra); } private TinyRemapper buildRemapper(Path input) throws IOException { @@ -338,8 +321,7 @@ public class MinecraftPatchedProvider extends DependencyProvider { } private void createSrgJars(Logger logger) throws Exception { - MinecraftProviderImpl minecraftProvider = getExtension().getMinecraftProvider(); - produceSrgJar(getExtension().isForgeAndOfficial(), minecraftProvider.minecraftClientJar.toPath(), MoreObjects.firstNonNull(minecraftProvider.minecraftExtractedServerJar, minecraftProvider.minecraftServerJar).toPath()); + produceSrgJar(getExtension().isForgeAndOfficial(), super.getMinecraftClientJar().toPath(), MoreObjects.firstNonNull(super.getMinecraftExtractedServerJar(), super.getMinecraftServerJar()).toPath()); } private void produceSrgJar(boolean official, Path clientJar, Path serverJar) throws IOException { @@ -349,8 +331,8 @@ public class MinecraftPatchedProvider extends DependencyProvider { ThreadingUtils.run(() -> { Files.copy(SpecialSourceExecutor.produceSrgJar(getExtension().getMcpConfigProvider().getRemapAction(), getProject(), "client", mcLibs, clientJar, tmpSrg), minecraftClientSrgJar.toPath()); }, () -> { - Files.copy(SpecialSourceExecutor.produceSrgJar(getExtension().getMcpConfigProvider().getRemapAction(), getProject(), "server", mcLibs, serverJar, tmpSrg), minecraftServerSrgJar.toPath()); - }); + Files.copy(SpecialSourceExecutor.produceSrgJar(getExtension().getMcpConfigProvider().getRemapAction(), getProject(), "server", mcLibs, serverJar, tmpSrg), minecraftServerSrgJar.toPath()); + }); } private Path getToSrgMappings() throws IOException { @@ -479,9 +461,8 @@ public class MinecraftPatchedProvider extends DependencyProvider { } private void accessTransformForge(Logger logger) throws Exception { - MinecraftProviderImpl minecraftProvider = getExtension().getMinecraftProvider(); List toDelete = new ArrayList<>(); - String atDependency = Constants.Dependencies.ACCESS_TRANSFORMERS + (minecraftProvider.serverBundleMetadata != null ? Constants.Dependencies.Versions.ACCESS_TRANSFORMERS_NEW : Constants.Dependencies.Versions.ACCESS_TRANSFORMERS); + String atDependency = Constants.Dependencies.ACCESS_TRANSFORMERS + (getServerBundleMetadata() != null ? Constants.Dependencies.Versions.ACCESS_TRANSFORMERS_NEW : Constants.Dependencies.Versions.ACCESS_TRANSFORMERS); FileCollection classpath = DependencyDownloader.download(getProject(), atDependency); Stopwatch stopwatch = Stopwatch.createStarted(); @@ -523,7 +504,7 @@ public class MinecraftPatchedProvider extends DependencyProvider { // if running with INFO or DEBUG logging if (getProject().getGradle().getStartParameter().getShowStacktrace() != ShowStacktrace.INTERNAL_EXCEPTIONS - || getProject().getGradle().getStartParameter().getLogLevel().compareTo(LogLevel.LIFECYCLE) < 0) { + || getProject().getGradle().getStartParameter().getLogLevel().compareTo(LogLevel.LIFECYCLE) < 0) { spec.setStandardOutput(System.out); spec.setErrorOutput(System.err); } else { @@ -551,7 +532,7 @@ public class MinecraftPatchedProvider extends DependencyProvider { final Function patchedSrgJar; Environment(Function srgJar, - Function patchedSrgJar) { + Function patchedSrgJar) { this.srgJar = srgJar; this.patchedSrgJar = patchedSrgJar; } @@ -579,8 +560,8 @@ public class MinecraftPatchedProvider extends DependencyProvider { TinyRemapper remapper = buildRemapper(mcInput); try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(mcOutput).build(); - Closeable outputConsumerForge = !splitJars ? () -> { - } : new OutputConsumerPath.Builder(forgeOutput).build()) { + Closeable outputConsumerForge = !splitJars ? () -> { + } : new OutputConsumerPath.Builder(forgeOutput).build()) { outputConsumer.addNonClassFiles(mcInput); InputTag mcTag = remapper.createInputTag(); @@ -608,7 +589,7 @@ public class MinecraftPatchedProvider extends DependencyProvider { patchJars(minecraftClientSrgJar, minecraftClientPatchedSrgJar, patchProvider.clientPatches); patchJars(minecraftServerSrgJar, minecraftServerPatchedSrgJar, patchProvider.serverPatches); - ThreadingUtils.run(Environment.values(), environment -> { + ThreadingUtils.run(MinecraftPatchedProvider.Environment.values(), environment -> { copyMissingClasses(environment.srgJar.apply(this), environment.patchedSrgJar.apply(this)); deleteParameterNames(environment.patchedSrgJar.apply(this)); @@ -652,16 +633,15 @@ public class MinecraftPatchedProvider extends DependencyProvider { // Copy resources if (getExtension().isForgeAndNotOfficial()) { // Copy resources - MinecraftProviderImpl minecraftProvider = getExtension().getMinecraftProvider(); - copyNonClassFiles(minecraftProvider.minecraftClientJar, minecraftMergedPatchedSrgJar); - copyNonClassFiles(MoreObjects.firstNonNull(minecraftProvider.minecraftExtractedServerJar, minecraftProvider.minecraftServerJar), minecraftMergedPatchedSrgJar); + copyNonClassFiles(super.getMinecraftClientJar(), minecraftMergedPatchedSrgJar); + copyNonClassFiles(MoreObjects.firstNonNull(super.getMinecraftExtractedServerJar(), super.getMinecraftServerJar()), minecraftMergedPatchedSrgJar); } } private void walkFileSystems(File source, File target, Predicate filter, Function> toWalk, FsPathConsumer action) throws IOException { try (FileSystemUtil.Delegate sourceFs = FileSystemUtil.getJarFileSystem(source, false); - FileSystemUtil.Delegate targetFs = FileSystemUtil.getJarFileSystem(target, false)) { + FileSystemUtil.Delegate targetFs = FileSystemUtil.getJarFileSystem(target, false)) { for (Path sourceDir : toWalk.apply(sourceFs.get())) { Path dir = sourceDir.toAbsolutePath(); if (!Files.exists(dir)) continue; @@ -764,8 +744,9 @@ public class MinecraftPatchedProvider extends DependencyProvider { } } - public File getMergedJar() { - return minecraftMergedPatchedJar; + @Override + public Path getMergedJar() { + return minecraftMergedPatchedJar.toPath(); } public File getForgeMergedJar() { @@ -773,7 +754,8 @@ public class MinecraftPatchedProvider extends DependencyProvider { } public boolean usesProjectCache() { - return !projectAts.isEmpty(); + if (!projectAts.isEmpty()) FunnyTodoException.yes("project ATs"); + return false; } public boolean isAtDirty() { @@ -781,7 +763,11 @@ public class MinecraftPatchedProvider extends DependencyProvider { } @Override - public String getTargetConfig() { - return Constants.Configurations.MINECRAFT; + public List getMinecraftJars() { + if (forgeMergedJar != null) { + return List.of(minecraftMergedPatchedJar.toPath(), forgeMergedJar.toPath()); + } else { + return List.of(minecraftMergedPatchedJar.toPath()); + } } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider2.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider2.java deleted file mode 100644 index 5ada3515..00000000 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/MinecraftPatchedProvider2.java +++ /dev/null @@ -1,778 +0,0 @@ -package net.fabricmc.loom.configuration.providers.forge; - -import java.io.ByteArrayInputStream; -import java.io.Closeable; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintStream; -import java.io.UncheckedIOException; -import java.net.URI; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import java.nio.file.StandardOpenOption; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.jar.Attributes; -import java.util.jar.Manifest; -import java.util.regex.Pattern; -import java.util.stream.Stream; - -import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; -import com.google.common.base.Stopwatch; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.hash.Hashing; -import com.google.common.io.ByteSource; -import de.oceanlabs.mcp.mcinjector.adaptors.ParameterAnnotationFixer; -import dev.architectury.tinyremapper.InputTag; -import dev.architectury.tinyremapper.OutputConsumerPath; -import dev.architectury.tinyremapper.TinyRemapper; -import net.minecraftforge.binarypatcher.ConsoleTool; -import org.apache.commons.io.output.NullOutputStream; -import org.gradle.api.Project; -import org.gradle.api.file.ConfigurableFileCollection; -import org.gradle.api.file.FileCollection; -import org.gradle.api.logging.LogLevel; -import org.gradle.api.logging.Logger; -import org.gradle.api.logging.configuration.ShowStacktrace; -import org.gradle.api.plugins.JavaPluginConvention; -import org.gradle.api.tasks.SourceSet; -import org.jetbrains.annotations.Nullable; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.Label; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.tree.ClassNode; - -import net.fabricmc.loom.LoomGradleExtension; -import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider; -import net.fabricmc.loom.util.Constants; -import net.fabricmc.loom.util.DependencyDownloader; -import net.fabricmc.loom.util.FileSystemUtil; -import net.fabricmc.loom.util.FunnyTodoException; -import net.fabricmc.loom.util.MappingsProviderVerbose; -import net.fabricmc.loom.util.ThreadingUtils; -import net.fabricmc.loom.util.TinyRemapperHelper; -import net.fabricmc.loom.util.ZipUtils; -import net.fabricmc.loom.util.function.FsPathConsumer; -import net.fabricmc.loom.util.srg.InnerClassRemapper; -import net.fabricmc.loom.util.srg.SpecialSourceExecutor; -import net.fabricmc.mappingio.tree.MemoryMappingTree; - -public class MinecraftPatchedProvider2 extends MergedMinecraftProvider { - private static final String LOOM_PATCH_VERSION_KEY = "Loom-Patch-Version"; - private static final String CURRENT_LOOM_PATCH_VERSION = "5"; - private static final String NAME_MAPPING_SERVICE_PATH = "/inject/META-INF/services/cpw.mods.modlauncher.api.INameMappingService"; - - // Step 1: Remap Minecraft to SRG (global) - private File minecraftClientSrgJar; - private File minecraftServerSrgJar; - // Step 2: Binary Patch (global) - private File minecraftClientPatchedSrgJar; - private File minecraftServerPatchedSrgJar; - // Step 3: Merge (global) - private File minecraftMergedPatchedSrgJar; - // Step 4: Access Transform (global or project) - private File minecraftMergedPatchedSrgAtJar; - // Step 5: Remap Patched AT & Forge to Official (global or project) - private File minecraftMergedPatchedJar; - @Nullable - private File forgeMergedJar; - private File minecraftClientExtra; - - private boolean dirty; - private File projectAtHash; - private Set projectAts = new HashSet<>(); - private boolean atDirty = false; - private boolean filesDirty = false; - - public static MergedMinecraftProvider getMergedMinecraftProvider(Project project) { - return LoomGradleExtension.get(project).isForge() ? new MinecraftPatchedProvider2(project) : new MergedMinecraftProvider(project); - } - - public MinecraftPatchedProvider2(Project project) { - super(project); - } - - @Override - protected void initFiles() { - super.initFiles(); - - PatchProvider patchProvider = getExtension().getPatchProvider(); - String minecraftVersion = minecraftVersion(); - String patchId = "forge-" + getExtension().getForgeProvider().getVersion().getCombined() + "-"; - - FunnyTodoException.yes("jar prefix"); - //if (getExtension().isForgeAndOfficial()) { - // minecraftProvider.setJarPrefix(patchId); - //} - - File globalCache = getExtension().getForgeProvider().getGlobalCache(); - File projectDir = usesProjectCache() ? getExtension().getForgeProvider().getProjectCache() : globalCache; - projectDir.mkdirs(); - - minecraftClientSrgJar = file("minecraft-client-srg.jar"); - minecraftServerSrgJar = file("minecraft-server-srg.jar"); - minecraftClientPatchedSrgJar = file("client-srg-patched.jar"); - minecraftServerPatchedSrgJar = file("server-srg-patched.jar"); - minecraftMergedPatchedSrgJar = file("merged-srg-patched.jar"); - forgeMergedJar = getExtension().isForgeAndOfficial() ? null : file("forge-official.jar"); - minecraftMergedPatchedSrgAtJar = file("merged-srg-at-patched.jar"); - minecraftMergedPatchedJar = file("merged-patched.jar"); - minecraftClientExtra = file("forge-client-extra.jar"); - } - - private byte[] getProjectAtsHash() throws IOException { - if (projectAts.isEmpty()) return ByteSource.empty().hash(Hashing.sha256()).asBytes(); - List currentBytes = new ArrayList<>(); - - for (File projectAt : projectAts) { - currentBytes.add(com.google.common.io.Files.asByteSource(projectAt)); - } - - return ByteSource.concat(currentBytes).hash(Hashing.sha256()).asBytes(); - } - - public void cleanAllCache() { - for (File file : getGlobalCaches()) { - file.delete(); - } - - cleanProjectCache(); - } - - private File[] getGlobalCaches() { - File[] files = { - minecraftClientSrgJar, - minecraftServerSrgJar, - minecraftClientPatchedSrgJar, - minecraftServerPatchedSrgJar, - minecraftMergedPatchedSrgJar, - minecraftClientExtra, - }; - - if (forgeMergedJar != null) { - Arrays.copyOf(files, files.length + 1); - files[files.length - 1] = forgeMergedJar; - } - - return files; - } - - public void cleanProjectCache() { - for (File file : getProjectCache()) { - file.delete(); - } - } - - private File[] getProjectCache() { - return new File[] { - minecraftMergedPatchedSrgAtJar, - minecraftMergedPatchedJar - }; - } - - private void checkAtAndCache() throws IOException { - filesDirty = false; - projectAtHash = new File(getExtension().getFiles().getProjectPersistentCache(), "at.sha256"); - ConfigurableFileCollection accessTransformers = getExtension().getForge().getAccessTransformers(); - accessTransformers.finalizeValue(); - projectAts = accessTransformers.getFiles(); - - if (projectAts.isEmpty()) { - SourceSet main = getProject().getConvention().findPlugin(JavaPluginConvention.class).getSourceSets().getByName("main"); - - for (File srcDir : main.getResources().getSrcDirs()) { - File projectAt = new File(srcDir, Constants.Forge.ACCESS_TRANSFORMER_PATH); - - if (projectAt.exists()) { - this.projectAts.add(projectAt); - break; - } - } - } - - if (isRefreshDeps() || !projectAtHash.exists()) { - writeAtHash(); - atDirty = !projectAts.isEmpty(); - } else { - byte[] expected = com.google.common.io.Files.asByteSource(projectAtHash).read(); - byte[] current = getProjectAtsHash(); - boolean mismatched = !Arrays.equals(current, expected); - - if (mismatched) { - writeAtHash(); - } - - atDirty = mismatched; - } - - if (isRefreshDeps() || Stream.of(getGlobalCaches()).anyMatch(((Predicate) File::exists).negate()) - || !isPatchedJarUpToDate(minecraftMergedPatchedJar)) { - cleanAllCache(); - } else if (atDirty || Stream.of(getProjectCache()).anyMatch(((Predicate) File::exists).negate())) { - cleanProjectCache(); - } - } - - @Override - public void provide() throws Exception { - super.provide(); - - this.dirty = false; - - if (!minecraftClientSrgJar.exists() || !minecraftServerSrgJar.exists()) { - this.dirty = true; - // Remap official jars to MCPConfig remapped srg jars - createSrgJars(getProject().getLogger()); - } - - if (!minecraftClientPatchedSrgJar.exists() || !minecraftServerPatchedSrgJar.exists()) { - this.dirty = true; - patchJars(getProject().getLogger()); - } - - if (dirty || !minecraftMergedPatchedSrgJar.exists()) { - mergeJars(getProject().getLogger()); - } - - if (atDirty || !minecraftMergedPatchedSrgAtJar.exists()) { - this.dirty = true; - accessTransformForge(getProject().getLogger()); - } - - if (forgeMergedJar != null && !forgeMergedJar.exists()) { - this.dirty = true; - } - - if (dirty) { - remapPatchedJar(getProject().getLogger()); - - if (getExtension().isForgeAndOfficial()) { - fillClientExtraJar(); - } - } - - this.filesDirty = dirty; - this.dirty = false; - - if (getExtension().isForgeAndOfficial()) { - DependencyProvider.addDependency(getProject(), minecraftClientExtra, Constants.Configurations.FORGE_EXTRA); - } - } - - @Override - protected void mergeJars() throws IOException { - // Don't merge jars in the superclass - } - - private void fillClientExtraJar() throws IOException { - Files.deleteIfExists(minecraftClientExtra.toPath()); - FileSystemUtil.getJarFileSystem(minecraftClientExtra, true).close(); - - copyNonClassFiles(getMinecraftClientJar(), minecraftClientExtra); - } - - private TinyRemapper buildRemapper(Path input) throws IOException { - Path[] libraries = TinyRemapperHelper.getMinecraftDependencies(getProject()); - MemoryMappingTree mappingsWithSrg = getExtension().getMappingsProvider().getMappingsWithSrg(); - - TinyRemapper remapper = TinyRemapper.newRemapper() - .logger(getProject().getLogger()::lifecycle) - .logUnknownInvokeDynamic(false) - .withMappings(TinyRemapperHelper.create(mappingsWithSrg, "srg", "official", true)) - .withMappings(InnerClassRemapper.of(InnerClassRemapper.readClassNames(input), mappingsWithSrg, "srg", "official")) - .renameInvalidLocals(true) - .rebuildSourceFilenames(true) - .fixPackageAccess(true) - .build(); - - if (getProject().getGradle().getStartParameter().getLogLevel().compareTo(LogLevel.LIFECYCLE) < 0) { - MappingsProviderVerbose.saveFile(remapper); - } - - remapper.readClassPath(libraries); - remapper.prepareClasses(); - return remapper; - } - - private void writeAtHash() throws IOException { - try (FileOutputStream out = new FileOutputStream(projectAtHash)) { - out.write(getProjectAtsHash()); - } - } - - private void createSrgJars(Logger logger) throws Exception { - produceSrgJar(getExtension().isForgeAndOfficial(), super.getMinecraftClientJar().toPath(), MoreObjects.firstNonNull(super.getMinecraftExtractedServerJar(), super.getMinecraftServerJar()).toPath()); - } - - private void produceSrgJar(boolean official, Path clientJar, Path serverJar) throws IOException { - Path tmpSrg = getToSrgMappings(); - Set mcLibs = getProject().getConfigurations().getByName(Constants.Configurations.MINECRAFT_DEPENDENCIES).resolve(); - - ThreadingUtils.run(() -> { - Files.copy(SpecialSourceExecutor.produceSrgJar(getExtension().getMcpConfigProvider().getRemapAction(), getProject(), "client", mcLibs, clientJar, tmpSrg), minecraftClientSrgJar.toPath()); - }, () -> { - Files.copy(SpecialSourceExecutor.produceSrgJar(getExtension().getMcpConfigProvider().getRemapAction(), getProject(), "server", mcLibs, serverJar, tmpSrg), minecraftServerSrgJar.toPath()); - }); - } - - private Path getToSrgMappings() throws IOException { - if (getExtension().getSrgProvider().isTsrgV2()) { - return getExtension().getSrgProvider().getMergedMojangRaw(); - } else { - return getExtension().getMcpConfigProvider().getMappings(); - } - } - - private void fixParameterAnnotation(File jarFile) throws Exception { - getProject().getLogger().info(":fixing parameter annotations for " + jarFile.getAbsolutePath()); - Stopwatch stopwatch = Stopwatch.createStarted(); - - try (FileSystem fs = FileSystems.newFileSystem(new URI("jar:" + jarFile.toURI()), ImmutableMap.of("create", false))) { - ThreadingUtils.TaskCompleter completer = ThreadingUtils.taskCompleter(); - - for (Path file : (Iterable) Files.walk(fs.getPath("/"))::iterator) { - if (!file.toString().endsWith(".class")) continue; - - completer.add(() -> { - byte[] bytes = Files.readAllBytes(file); - ClassReader reader = new ClassReader(bytes); - ClassNode node = new ClassNode(); - ClassVisitor visitor = new ParameterAnnotationFixer(node, null); - reader.accept(visitor, 0); - - ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); - node.accept(writer); - byte[] out = writer.toByteArray(); - - if (!Arrays.equals(bytes, out)) { - Files.delete(file); - Files.write(file, out); - } - }); - } - - completer.complete(); - } - - getProject().getLogger().info(":fixing parameter annotations for " + jarFile.getAbsolutePath() + " in " + stopwatch); - } - - private void deleteParameterNames(File jarFile) throws Exception { - getProject().getLogger().info(":deleting parameter names for " + jarFile.getAbsolutePath()); - Stopwatch stopwatch = Stopwatch.createStarted(); - - try (FileSystem fs = FileSystems.newFileSystem(new URI("jar:" + jarFile.toURI()), ImmutableMap.of("create", false))) { - ThreadingUtils.TaskCompleter completer = ThreadingUtils.taskCompleter(); - Pattern vignetteParameters = Pattern.compile("p_[0-9a-zA-Z]+_(?:[0-9a-zA-Z]+_)?"); - - for (Path file : (Iterable) Files.walk(fs.getPath("/"))::iterator) { - if (!file.toString().endsWith(".class")) continue; - - completer.add(() -> { - byte[] bytes = Files.readAllBytes(file); - ClassReader reader = new ClassReader(bytes); - ClassWriter writer = new ClassWriter(0); - - reader.accept(new ClassVisitor(Opcodes.ASM9, writer) { - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - return new MethodVisitor(Opcodes.ASM9, super.visitMethod(access, name, descriptor, signature, exceptions)) { - @Override - public void visitParameter(String name, int access) { - if (vignetteParameters.matcher(name).matches()) { - super.visitParameter(null, access); - } else { - super.visitParameter(name, access); - } - } - - @Override - public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) { - if (!vignetteParameters.matcher(name).matches()) { - super.visitLocalVariable(name, descriptor, signature, start, end, index); - } - } - }; - } - }, 0); - - byte[] out = writer.toByteArray(); - - if (!Arrays.equals(bytes, out)) { - Files.delete(file); - Files.write(file, out); - } - }); - } - - completer.complete(); - } - - getProject().getLogger().info(":deleting parameter names for " + jarFile.getAbsolutePath() + " in " + stopwatch); - } - - private File getForgeJar() { - return getExtension().getForgeUniversalProvider().getForge(); - } - - private File getForgeUserdevJar() { - return getExtension().getForgeUserdevProvider().getUserdevJar(); - } - - private boolean isPatchedJarUpToDate(File jar) throws IOException { - if (!jar.exists()) return false; - - byte[] manifestBytes = ZipUtils.unpackNullable(jar.toPath(), "META-INF/MANIFEST.MF"); - - if (manifestBytes == null) { - return false; - } - - Manifest manifest = new Manifest(new ByteArrayInputStream(manifestBytes)); - Attributes attributes = manifest.getMainAttributes(); - String value = attributes.getValue(LOOM_PATCH_VERSION_KEY); - - if (Objects.equals(value, CURRENT_LOOM_PATCH_VERSION)) { - return true; - } else { - getProject().getLogger().lifecycle(":forge patched jars not up to date. current version: " + value); - return false; - } - } - - private void accessTransformForge(Logger logger) throws Exception { - List toDelete = new ArrayList<>(); - String atDependency = Constants.Dependencies.ACCESS_TRANSFORMERS + (getServerBundleMetadata() != null ? Constants.Dependencies.Versions.ACCESS_TRANSFORMERS_NEW : Constants.Dependencies.Versions.ACCESS_TRANSFORMERS); - FileCollection classpath = DependencyDownloader.download(getProject(), atDependency); - Stopwatch stopwatch = Stopwatch.createStarted(); - - logger.lifecycle(":access transforming minecraft"); - - File input = minecraftMergedPatchedSrgJar; - File target = minecraftMergedPatchedSrgAtJar; - Files.deleteIfExists(target.toPath()); - - List args = new ArrayList<>(); - args.add("--inJar"); - args.add(input.getAbsolutePath()); - args.add("--outJar"); - args.add(target.getAbsolutePath()); - - for (File jar : ImmutableList.of(getForgeJar(), getForgeUserdevJar(), minecraftMergedPatchedSrgJar)) { - byte[] atBytes = ZipUtils.unpackNullable(jar.toPath(), Constants.Forge.ACCESS_TRANSFORMER_PATH); - - if (atBytes != null) { - File tmpFile = File.createTempFile("at-conf", ".cfg"); - toDelete.add(tmpFile); - Files.write(tmpFile.toPath(), atBytes, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); - args.add("--atFile"); - args.add(tmpFile.getAbsolutePath()); - } - } - - if (usesProjectCache()) { - for (File projectAt : projectAts) { - args.add("--atFile"); - args.add(projectAt.getAbsolutePath()); - } - } - - getProject().javaexec(spec -> { - spec.getMainClass().set("net.minecraftforge.accesstransformer.TransformerProcessor"); - spec.setArgs(args); - spec.setClasspath(classpath); - - // if running with INFO or DEBUG logging - if (getProject().getGradle().getStartParameter().getShowStacktrace() != ShowStacktrace.INTERNAL_EXCEPTIONS - || getProject().getGradle().getStartParameter().getLogLevel().compareTo(LogLevel.LIFECYCLE) < 0) { - spec.setStandardOutput(System.out); - spec.setErrorOutput(System.err); - } else { - spec.setStandardOutput(NullOutputStream.NULL_OUTPUT_STREAM); - spec.setErrorOutput(NullOutputStream.NULL_OUTPUT_STREAM); - } - }).rethrowFailure().assertNormalExitValue(); - - for (File file : toDelete) { - file.delete(); - } - - logger.lifecycle(":access transformed minecraft in " + stopwatch.stop()); - } - - public enum Environment { - CLIENT(provider -> provider.minecraftClientSrgJar, - provider -> provider.minecraftClientPatchedSrgJar - ), - SERVER(provider -> provider.minecraftServerSrgJar, - provider -> provider.minecraftServerPatchedSrgJar - ); - - final Function srgJar; - final Function patchedSrgJar; - - Environment(Function srgJar, - Function patchedSrgJar) { - this.srgJar = srgJar; - this.patchedSrgJar = patchedSrgJar; - } - - public String side() { - return name().toLowerCase(Locale.ROOT); - } - } - - private void remapPatchedJar(Logger logger) throws Exception { - getProject().getLogger().lifecycle(":remapping minecraft (TinyRemapper, srg -> official)"); - Path mcInput = minecraftMergedPatchedSrgAtJar.toPath(); - Path mcOutput = minecraftMergedPatchedJar.toPath(); - Path forgeJar = getForgeJar().toPath(); - Path forgeUserdevJar = getForgeUserdevJar().toPath(); - Path forgeOutput = null; - Files.deleteIfExists(mcOutput); - boolean splitJars = forgeMergedJar != null; - - if (splitJars) { - forgeOutput = forgeMergedJar.toPath(); - Files.deleteIfExists(forgeOutput); - } - - TinyRemapper remapper = buildRemapper(mcInput); - - try (OutputConsumerPath outputConsumer = new OutputConsumerPath.Builder(mcOutput).build(); - Closeable outputConsumerForge = !splitJars ? () -> { - } : new OutputConsumerPath.Builder(forgeOutput).build()) { - outputConsumer.addNonClassFiles(mcInput); - - InputTag mcTag = remapper.createInputTag(); - InputTag forgeTag = remapper.createInputTag(); - List> futures = new ArrayList<>(); - futures.add(remapper.readInputsAsync(mcTag, mcInput)); - futures.add(remapper.readInputsAsync(forgeTag, forgeJar, forgeUserdevJar)); - CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); - remapper.apply(outputConsumer, mcTag); - remapper.apply(splitJars ? (OutputConsumerPath) outputConsumerForge : outputConsumer, forgeTag); - } finally { - remapper.finish(); - } - - copyNonClassFiles(forgeJar.toFile(), splitJars ? forgeMergedJar : minecraftMergedPatchedJar); - copyUserdevFiles(forgeUserdevJar.toFile(), splitJars ? forgeMergedJar : minecraftMergedPatchedJar); - applyLoomPatchVersion(mcOutput); - } - - private void patchJars(Logger logger) throws IOException { - Stopwatch stopwatch = Stopwatch.createStarted(); - logger.lifecycle(":patching jars"); - - PatchProvider patchProvider = getExtension().getPatchProvider(); - patchJars(minecraftClientSrgJar, minecraftClientPatchedSrgJar, patchProvider.clientPatches); - patchJars(minecraftServerSrgJar, minecraftServerPatchedSrgJar, patchProvider.serverPatches); - - ThreadingUtils.run(MinecraftPatchedProvider2.Environment.values(), environment -> { - copyMissingClasses(environment.srgJar.apply(this), environment.patchedSrgJar.apply(this)); - deleteParameterNames(environment.patchedSrgJar.apply(this)); - - if (getExtension().isForgeAndNotOfficial()) { - fixParameterAnnotation(environment.patchedSrgJar.apply(this)); - } - }); - - logger.lifecycle(":patched jars in " + stopwatch.stop()); - } - - private void patchJars(File clean, File output, Path patches) throws IOException { - PrintStream previous = System.out; - - try { - System.setOut(new PrintStream(NullOutputStream.NULL_OUTPUT_STREAM)); - } catch (SecurityException ignored) { - // Failed to replace logger filter, just ignore - } - - ConsoleTool.main(new String[] { - "--clean", clean.getAbsolutePath(), - "--output", output.getAbsolutePath(), - "--apply", patches.toAbsolutePath().toString() - }); - - try { - System.setOut(previous); - } catch (SecurityException ignored) { - // Failed to replace logger filter, just ignore - } - } - - private void mergeJars(Logger logger) throws IOException { - // FIXME: Hack here: There are no server-only classes so we can just copy the client JAR. - // This will change if upstream Loom adds the possibility for separate projects/source sets per environment. - Files.copy(minecraftClientPatchedSrgJar.toPath(), minecraftMergedPatchedSrgJar.toPath()); - - logger.lifecycle(":copying resources"); - - // Copy resources - if (getExtension().isForgeAndNotOfficial()) { - // Copy resources - copyNonClassFiles(super.getMinecraftClientJar(), minecraftMergedPatchedSrgJar); - copyNonClassFiles(MoreObjects.firstNonNull(super.getMinecraftExtractedServerJar(), super.getMinecraftServerJar()), minecraftMergedPatchedSrgJar); - } - } - - private void walkFileSystems(File source, File target, Predicate filter, Function> toWalk, FsPathConsumer action) - throws IOException { - try (FileSystemUtil.Delegate sourceFs = FileSystemUtil.getJarFileSystem(source, false); - FileSystemUtil.Delegate targetFs = FileSystemUtil.getJarFileSystem(target, false)) { - for (Path sourceDir : toWalk.apply(sourceFs.get())) { - Path dir = sourceDir.toAbsolutePath(); - if (!Files.exists(dir)) continue; - Files.walk(dir) - .filter(Files::isRegularFile) - .filter(filter) - .forEach(it -> { - boolean root = dir.getParent() == null; - - try { - Path relativeSource = root ? it : dir.relativize(it); - Path targetPath = targetFs.get().getPath(relativeSource.toString()); - action.accept(sourceFs.get(), targetFs.get(), it, targetPath); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - }); - } - } - } - - private void walkFileSystems(File source, File target, Predicate filter, FsPathConsumer action) throws IOException { - walkFileSystems(source, target, filter, FileSystem::getRootDirectories, action); - } - - private void copyAll(File source, File target) throws IOException { - walkFileSystems(source, target, it -> true, this::copyReplacing); - } - - private void copyMissingClasses(File source, File target) throws IOException { - walkFileSystems(source, target, it -> it.toString().endsWith(".class"), (sourceFs, targetFs, sourcePath, targetPath) -> { - if (Files.exists(targetPath)) return; - Path parent = targetPath.getParent(); - - if (parent != null) { - Files.createDirectories(parent); - } - - Files.copy(sourcePath, targetPath); - }); - } - - private void copyNonClassFiles(File source, File target) throws IOException { - Predicate filter = getExtension().isForgeAndOfficial() ? file -> { - String s = file.toString(); - return !s.endsWith(".class"); - } : file -> { - String s = file.toString(); - return !s.endsWith(".class") || (s.startsWith("META-INF") && !s.startsWith("META-INF/services")); - }; - - walkFileSystems(source, target, filter, this::copyReplacing); - } - - private void copyReplacing(FileSystem sourceFs, FileSystem targetFs, Path sourcePath, Path targetPath) throws IOException { - Path parent = targetPath.getParent(); - - if (parent != null) { - Files.createDirectories(parent); - } - - Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING); - } - - private void copyUserdevFiles(File source, File target) throws IOException { - // Removes the Forge name mapping service definition so that our own is used. - // If there are multiple name mapping services with the same "understanding" pair - // (source -> target namespace pair), modlauncher throws a fit and will crash. - // To use our YarnNamingService instead of MCPNamingService, we have to remove this file. - Predicate filter = file -> !file.toString().endsWith(".class") && !file.toString().equals(NAME_MAPPING_SERVICE_PATH); - - walkFileSystems(source, target, filter, fs -> Collections.singleton(fs.getPath("inject")), (sourceFs, targetFs, sourcePath, targetPath) -> { - Path parent = targetPath.getParent(); - - if (parent != null) { - Files.createDirectories(parent); - } - - Files.copy(sourcePath, targetPath); - }); - } - - public void applyLoomPatchVersion(Path target) throws IOException { - try (FileSystemUtil.Delegate delegate = FileSystemUtil.getJarFileSystem(target, false)) { - Path manifestPath = delegate.get().getPath("META-INF/MANIFEST.MF"); - - Preconditions.checkArgument(Files.exists(manifestPath), "META-INF/MANIFEST.MF does not exist in patched srg jar!"); - Manifest manifest = new Manifest(); - - if (Files.exists(manifestPath)) { - try (InputStream stream = Files.newInputStream(manifestPath)) { - manifest.read(stream); - manifest.getMainAttributes().putValue(LOOM_PATCH_VERSION_KEY, CURRENT_LOOM_PATCH_VERSION); - } - } - - try (OutputStream stream = Files.newOutputStream(manifestPath, StandardOpenOption.CREATE)) { - manifest.write(stream); - } - } - } - - @Override - public Path getMergedJar() { - return minecraftMergedPatchedJar.toPath(); - } - - public File getForgeMergedJar() { - return forgeMergedJar; - } - - public boolean usesProjectCache() { - if (!projectAts.isEmpty()) FunnyTodoException.yes("project ATs"); - return false; - } - - public boolean isAtDirty() { - return atDirty || filesDirty; - } - - @Override - public String getTargetConfig() { - return Constants.Configurations.MINECRAFT; - } - - @Override - public List getMinecraftJars() { - if (forgeMergedJar != null) { - return List.of(minecraftMergedPatchedJar.toPath(), forgeMergedJar.toPath()); - } else { - return List.of(minecraftMergedPatchedJar.toPath()); - } - } -} diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJarConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJarConfiguration.java index 270a799d..2e65eaa6 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJarConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftJarConfiguration.java @@ -34,7 +34,7 @@ import net.fabricmc.loom.configuration.decompile.DecompileConfiguration; import net.fabricmc.loom.configuration.decompile.SingleJarDecompileConfiguration; import net.fabricmc.loom.configuration.decompile.SplitDecompileConfiguration; import net.fabricmc.loom.configuration.processors.JarProcessorManager; -import net.fabricmc.loom.configuration.providers.forge.MinecraftPatchedProvider2; +import net.fabricmc.loom.configuration.providers.forge.MinecraftPatchedProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.IntermediaryMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.MappedMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.NamedMinecraftProvider; @@ -42,7 +42,7 @@ import net.fabricmc.loom.configuration.providers.minecraft.mapped.ProcessedNamed public enum MinecraftJarConfiguration { MERGED( - MinecraftPatchedProvider2::getMergedMinecraftProvider, + MinecraftPatchedProvider::getMergedMinecraftProvider, IntermediaryMinecraftProvider.MergedImpl::new, NamedMinecraftProvider.MergedImpl::new, ProcessedNamedMinecraftProvider.MergedImpl::new,