diff options
author | shedaniel <daniel@shedaniel.me> | 2021-01-12 12:50:41 +0800 |
---|---|---|
committer | shedaniel <daniel@shedaniel.me> | 2021-01-12 12:50:41 +0800 |
commit | 3986279215804dfdb2e3cb4dbaabdeeaeda6a211 (patch) | |
tree | eb07bb31f1bf56592f6b83282a4f693541a34469 /src/main/java | |
parent | eb55ece3434a7c7ac1f0cd9404a4bcef78f08a7d (diff) | |
download | architectury-loom-3986279215804dfdb2e3cb4dbaabdeeaeda6a211.tar.gz architectury-loom-3986279215804dfdb2e3cb4dbaabdeeaeda6a211.tar.bz2 architectury-loom-3986279215804dfdb2e3cb4dbaabdeeaeda6a211.zip |
Properly reapply changed ATs, Improve ATs performance.
Diffstat (limited to 'src/main/java')
3 files changed, 124 insertions, 63 deletions
diff --git a/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java b/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java index 2f45c289..b6d537f7 100644 --- a/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java +++ b/src/main/java/net/fabricmc/loom/providers/MappingsProvider.java @@ -201,6 +201,7 @@ public class MappingsProvider extends DependencyProvider { if (extension.isForge()) { patchedProvider = new MinecraftPatchedProvider(this, getProject()); + patchedProvider.provide(dependency, postPopulationScheduler); } if (processorManager.active() || (extension.isForge() && patchedProvider.usesProjectCache())) { @@ -210,9 +211,6 @@ public class MappingsProvider extends DependencyProvider { mappedProvider = new MinecraftMappedProvider(getProject()); } - if (extension.isForge()) { - patchedProvider.provide(dependency, postPopulationScheduler); - } mappedProvider.initFiles(minecraftProvider, this); mappedProvider.provide(dependency, postPopulationScheduler); } diff --git a/src/main/java/net/fabricmc/loom/providers/MinecraftPatchedProvider.java b/src/main/java/net/fabricmc/loom/providers/MinecraftPatchedProvider.java index c88a0fc5..1e6ea739 100644 --- a/src/main/java/net/fabricmc/loom/providers/MinecraftPatchedProvider.java +++ b/src/main/java/net/fabricmc/loom/providers/MinecraftPatchedProvider.java @@ -24,6 +24,7 @@ package net.fabricmc.loom.providers; +import com.google.common.base.Predicates; import com.google.common.collect.ImmutableMap; import com.google.gson.JsonParser; import de.oceanlabs.mcp.mcinjector.adaptors.ParameterAnnotationFixer; @@ -34,7 +35,9 @@ import net.fabricmc.loom.util.srg.SpecialSourceExecutor; import net.fabricmc.mapping.tree.TinyTree; import net.fabricmc.tinyremapper.OutputConsumerPath; import net.fabricmc.tinyremapper.TinyRemapper; +import net.minecraftforge.accesstransformer.AccessTransformerEngine; import net.minecraftforge.accesstransformer.TransformerProcessor; +import net.minecraftforge.accesstransformer.parser.AccessTransformerList; import net.minecraftforge.binarypatcher.ConsoleTool; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; @@ -51,6 +54,7 @@ import org.objectweb.asm.tree.ClassNode; import org.zeroturnaround.zip.ZipUtil; import java.io.*; +import java.lang.reflect.Field; import java.net.URI; import java.net.URL; import java.nio.charset.StandardCharsets; @@ -59,18 +63,27 @@ import java.nio.file.*; import java.util.Arrays; import java.util.Collections; import java.util.Locale; +import java.util.Map; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; +import java.util.stream.Stream; public class MinecraftPatchedProvider extends DependencyProvider { private final MappingsProvider mappingsProvider; + // Step 1: Remap Minecraft to SRG private File minecraftClientSrgJar; private File minecraftServerSrgJar; + // Step 2: Binary Patch private File minecraftClientPatchedSrgJar; private File minecraftServerPatchedSrgJar; + // Step 3: Access Transform + private File minecraftClientPatchedSrgATJar; + private File minecraftServerPatchedSrgATJar; + // Step 4: Remap Patched AT to Official private File minecraftClientPatchedOfficialJar; private File minecraftServerPatchedOfficialJar; + // Step 5: Merge private File minecraftMergedPatchedJar; private File projectAtHash; @Nullable @@ -108,7 +121,7 @@ public class MinecraftPatchedProvider extends DependencyProvider { writeAtHash(); } - atDirty = mismatched && projectAt != null; + atDirty = mismatched; } MinecraftProvider minecraftProvider = getExtension().getMinecraftProvider(); @@ -117,44 +130,56 @@ public class MinecraftPatchedProvider extends DependencyProvider { String jarSuffix = "-patched-forge-" + patchProvider.forgeVersion; minecraftProvider.setJarSuffix(jarSuffix); - File cache = usesProjectCache() ? getExtension().getProjectPersistentCache() : getExtension().getUserCache(); + File globalCache = getExtension().getUserCache(); + File cache = usesProjectCache() ? getExtension().getProjectPersistentCache() : globalCache; + minecraftClientSrgJar = new File(globalCache, "minecraft-" + minecraftVersion + "-client-srg.jar"); + minecraftServerSrgJar = new File(globalCache, "minecraft-" + minecraftVersion + "-server-srg.jar"); + minecraftClientPatchedSrgJar = new File(globalCache, "minecraft-" + minecraftVersion + "-client-srg" + jarSuffix + ".jar"); + minecraftServerPatchedSrgJar = new File(globalCache, "minecraft-" + minecraftVersion + "-server-srg" + jarSuffix + ".jar"); + minecraftClientPatchedSrgATJar = new File(cache, "minecraft-" + minecraftVersion + "-client-srg-at" + jarSuffix + ".jar"); + minecraftServerPatchedSrgATJar = new File(cache, "minecraft-" + minecraftVersion + "-server-srg-at" + jarSuffix + ".jar"); minecraftClientPatchedOfficialJar = new File(cache, "minecraft-" + minecraftVersion + "-client" + jarSuffix + ".jar"); minecraftServerPatchedOfficialJar = new File(cache, "minecraft-" + minecraftVersion + "-server" + jarSuffix + ".jar"); - minecraftClientSrgJar = new File(cache, "minecraft-" + minecraftVersion + "-client-srg.jar"); - minecraftServerSrgJar = new File(cache, "minecraft-" + minecraftVersion + "-server-srg.jar"); - minecraftClientPatchedSrgJar = new File(cache, "minecraft-" + minecraftVersion + "-client-srg" + jarSuffix + ".jar"); - minecraftServerPatchedSrgJar = new File(cache, "minecraft-" + minecraftVersion + "-server-srg" + jarSuffix + ".jar"); minecraftMergedPatchedJar = new File(cache, "minecraft-" + minecraftVersion + "-merged" + jarSuffix + ".jar"); - if (isRefreshDeps()) { - cleanCache(); + if (isRefreshDeps() || Stream.of(getGlobalCaches()).anyMatch(Predicates.not(File::exists))) { + cleanAllCache(); + } else if (atDirty || Stream.of(getProjectCache()).anyMatch(Predicates.not(File::exists))) { + cleanProjectCache(); } + } - if (!minecraftClientSrgJar.exists() || !minecraftServerSrgJar.exists() - || !minecraftClientPatchedSrgJar.exists() || !minecraftServerPatchedSrgJar.exists() - || !minecraftMergedPatchedJar.exists()) { - minecraftClientSrgJar.delete(); - minecraftServerSrgJar.delete(); - minecraftClientPatchedSrgJar.delete(); - minecraftServerPatchedSrgJar.delete(); - minecraftMergedPatchedJar.delete(); + public void cleanAllCache() { + for (File file : getGlobalCaches()) { + file.delete(); } + cleanProjectCache(); } - public void cleanCache() { - for (File file : Arrays.asList( - projectAtHash, + private File[] getGlobalCaches() { + return new File[]{ minecraftClientSrgJar, minecraftServerSrgJar, minecraftClientPatchedSrgJar, - minecraftServerPatchedSrgJar, + minecraftServerPatchedSrgJar + }; + } + + public void cleanProjectCache() { + for (File file : getProjectCache()) { + file.delete(); + } + } + + private File[] getProjectCache() { + return new File[]{ + minecraftClientPatchedSrgATJar, + minecraftServerPatchedSrgATJar, minecraftClientPatchedOfficialJar, minecraftServerPatchedOfficialJar, minecraftMergedPatchedJar - )) { - file.delete(); - } + }; } @Override @@ -165,21 +190,30 @@ public class MinecraftPatchedProvider extends DependencyProvider { getProject().getLogger().lifecycle(":found dirty access transformers"); } - if (atDirty || !minecraftClientPatchedOfficialJar.exists() || !minecraftServerPatchedOfficialJar.exists()) { - if (!minecraftClientSrgJar.exists() || !minecraftServerSrgJar.exists()) { - // Remap official jars to MCPConfig remapped srg jars - createSrgJars(getProject().getLogger()); - } + boolean dirty = false; - if (atDirty || !minecraftClientPatchedSrgJar.exists() || !minecraftServerPatchedSrgJar.exists()) { - patchJars(getProject().getLogger()); - injectForgeClasses(getProject().getLogger()); - } + if (!minecraftClientSrgJar.exists() || !minecraftServerSrgJar.exists()) { + dirty = true; + // Remap official jars to MCPConfig remapped srg jars + createSrgJars(getProject().getLogger()); + } + + if (!minecraftClientPatchedSrgJar.exists() || !minecraftServerPatchedSrgJar.exists()) { + dirty = true; + patchJars(getProject().getLogger()); + injectForgeClasses(getProject().getLogger()); + } + + if (atDirty || !minecraftClientPatchedSrgATJar.exists() || !minecraftServerPatchedSrgATJar.exists()) { + dirty = true; + accessTransformForge(getProject().getLogger()); + } + if (dirty) { remapPatchedJars(getProject().getLogger()); } - if (atDirty || !minecraftMergedPatchedJar.exists()) { + if (dirty || !minecraftMergedPatchedJar.exists()) { mergeJars(getProject().getLogger()); } } @@ -252,12 +286,9 @@ public class MinecraftPatchedProvider extends DependencyProvider { private void injectForgeClasses(Logger logger) throws IOException { logger.lifecycle(":injecting forge classes into minecraft"); - ThreadingUtils.run(() -> { - copyAll(getExtension().getForgeUniversalProvider().getForge(), minecraftClientPatchedSrgJar); - copyUserdevFiles(getExtension().getForgeUserdevProvider().getUserdevJar(), minecraftClientPatchedSrgJar); - }, () -> { - copyAll(getExtension().getForgeUniversalProvider().getForge(), minecraftServerPatchedSrgJar); - copyUserdevFiles(getExtension().getForgeUserdevProvider().getUserdevJar(), minecraftServerPatchedSrgJar); + ThreadingUtils.run(Arrays.asList(Environment.values()), environment -> { + copyAll(getExtension().getForgeUniversalProvider().getForge(), environment.patchedSrgJar.apply(this)); + copyUserdevFiles(getExtension().getForgeUserdevProvider().getUserdevJar(), environment.patchedSrgJar.apply(this)); }); logger.lifecycle(":injecting loom classes into minecraft"); @@ -271,38 +302,73 @@ public class MinecraftPatchedProvider extends DependencyProvider { String side = environment.side(); File target = environment.patchedSrgJar.apply(this); walkFileSystems(injection, target, it -> !it.getFileName().toString().equals("MANIFEST.MF"), this::copyReplacing); + } + } + private void accessTransformForge(Logger logger) throws Exception { + for (Environment environment : Environment.values()) { + String side = environment.side(); logger.lifecycle(":access transforming minecraft (" + side + ")"); - File atJar = File.createTempFile("at" + side, ".jar"); + File input = environment.patchedSrgJar.apply(this); + File inputCopied = File.createTempFile("at" + side, ".jar"); + FileUtils.copyFile(input, inputCopied); + File target = environment.patchedSrgATJar.apply(this); + target.delete(); File at = File.createTempFile("at" + side, ".cfg"); - FileUtils.copyFile(target, atJar); - JarUtil.extractFile(atJar, "META-INF/accesstransformer.cfg", at); + JarUtil.extractFile(inputCopied, "META-INF/accesstransformer.cfg", at); String[] args = new String[]{ - "--inJar", atJar.getAbsolutePath(), + "--inJar", inputCopied.getAbsolutePath(), "--outJar", target.getAbsolutePath(), "--atFile", at.getAbsolutePath() }; - if (projectAt != null) { + if (usesProjectCache()) { args = Arrays.copyOf(args, args.length + 2); args[args.length - 2] = "--atFile"; args[args.length - 1] = projectAt.getAbsolutePath(); } + resetAccessTransformerEngine(); TransformerProcessor.main(args); - }; + inputCopied.delete(); + } } - private enum Environment { - CLIENT(provider -> provider.minecraftClientPatchedSrgJar, provider -> provider.minecraftClientPatchedOfficialJar), - SERVER(provider -> provider.minecraftServerPatchedSrgJar, provider -> provider.minecraftServerPatchedOfficialJar); - - Function<MinecraftPatchedProvider, File> patchedSrgJar; - Function<MinecraftPatchedProvider, File> patchedOfficialJar; + private void resetAccessTransformerEngine() throws Exception { + // Thank you Forge, I love you + Field field = AccessTransformerEngine.class.getDeclaredField("masterList"); + field.setAccessible(true); + AccessTransformerList list = (AccessTransformerList) field.get(AccessTransformerEngine.INSTANCE); + field = AccessTransformerList.class.getDeclaredField("accessTransformers"); + field.setAccessible(true); + ((Map<?, ?>) field.get(list)).clear(); + } - Environment(Function<MinecraftPatchedProvider, File> patchedSrgJar, Function<MinecraftPatchedProvider, File> patchedOfficialJar) { + private enum Environment { + CLIENT(provider -> provider.minecraftClientSrgJar, + provider -> provider.minecraftClientPatchedSrgJar, + provider -> provider.minecraftClientPatchedSrgATJar, + provider -> provider.minecraftClientPatchedOfficialJar + ), + SERVER(provider -> provider.minecraftServerSrgJar, + provider -> provider.minecraftServerPatchedSrgJar, + provider -> provider.minecraftServerPatchedSrgATJar, + provider -> provider.minecraftServerPatchedOfficialJar + ); + + final Function<MinecraftPatchedProvider, File> srgJar; + final Function<MinecraftPatchedProvider, File> patchedSrgJar; + final Function<MinecraftPatchedProvider, File> patchedSrgATJar; + final Function<MinecraftPatchedProvider, File> patchedOfficialJar; + + Environment(Function<MinecraftPatchedProvider, File> srgJar, + Function<MinecraftPatchedProvider, File> patchedSrgJar, + Function<MinecraftPatchedProvider, File> patchedSrgATJar, + Function<MinecraftPatchedProvider, File> patchedOfficialJar) { + this.srgJar = srgJar; this.patchedSrgJar = patchedSrgJar; + this.patchedSrgATJar = patchedSrgATJar; this.patchedOfficialJar = patchedOfficialJar; } @@ -324,7 +390,7 @@ public class MinecraftPatchedProvider extends DependencyProvider { logger.lifecycle(":remapping minecraft (TinyRemapper, " + environment.side() + ", srg -> official)"); TinyTree mappingsWithSrg = getExtension().getMappingsProvider().getMappingsWithSrg(); - Path input = environment.patchedSrgJar.apply(this).toPath(); + Path input = environment.patchedSrgATJar.apply(this).toPath(); Path output = environment.patchedOfficialJar.apply(this).toPath(); Files.deleteIfExists(output); @@ -356,12 +422,9 @@ public class MinecraftPatchedProvider extends DependencyProvider { PatchProvider patchProvider = getExtension().getPatchProvider(); patchJars(minecraftClientSrgJar, minecraftClientPatchedSrgJar, patchProvider.clientPatches); patchJars(minecraftServerSrgJar, minecraftServerPatchedSrgJar, patchProvider.serverPatches); - ThreadingUtils.run(() -> { - copyMissingClasses(minecraftClientSrgJar, minecraftClientPatchedSrgJar); - fixParameterAnnotation(minecraftClientPatchedSrgJar); - }, () -> { - copyMissingClasses(minecraftServerSrgJar, minecraftServerPatchedSrgJar); - fixParameterAnnotation(minecraftServerPatchedSrgJar); + ThreadingUtils.run(Arrays.asList(Environment.values()), environment -> { + copyMissingClasses(environment.srgJar.apply(this), environment.patchedSrgJar.apply(this)); + fixParameterAnnotation(environment.patchedSrgJar.apply(this)); }); } diff --git a/src/main/java/net/fabricmc/loom/task/CleanLoomBinaries.java b/src/main/java/net/fabricmc/loom/task/CleanLoomBinaries.java index 2b845afb..2981a6ec 100644 --- a/src/main/java/net/fabricmc/loom/task/CleanLoomBinaries.java +++ b/src/main/java/net/fabricmc/loom/task/CleanLoomBinaries.java @@ -45,7 +45,7 @@ public class CleanLoomBinaries extends AbstractLoomTask { try { MinecraftPatchedProvider provider = new MinecraftPatchedProvider(extension.getMappingsProvider(), getProject()); provider.initFiles(); - provider.cleanCache(); + provider.cleanAllCache(); } catch (IOException e) { e.printStackTrace(); } |