diff --git a/build.gradle b/build.gradle index 287b0ce3d..be71038b8 100644 --- a/build.gradle +++ b/build.gradle @@ -187,6 +187,7 @@ dependencies { implementation libs.opencsv implementation libs.forge.diffpatch implementation libs.datafixerupper + implementation libs.at // Forge mods.toml parsing implementation libs.night.config.toml diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 60e2cc6f0..139a2e261 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,6 +29,7 @@ opencsv = "5.4" forge-diffpatch = "2.0.7" night-config = "3.6.6" datafixerupper = "6.0.8" +at = "1.0.1" [libraries] # Loom compile libraries @@ -62,6 +63,7 @@ opencsv = { module = "com.opencsv:opencsv", version.ref = "opencsv" } forge-diffpatch = { module = "net.minecraftforge:DiffPatch", version.ref = "forge-diffpatch" } night-config-toml = { module = "com.electronwill.night-config:toml", version.ref = "night-config" } datafixerupper = { module = "com.mojang:datafixerupper", version.ref = "datafixerupper" } +at = { module = "dev.architectury:at", version.ref = "at" } [plugins] kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } diff --git a/src/main/java/dev/architectury/loom/extensions/ModBuildExtensions.java b/src/main/java/dev/architectury/loom/extensions/ModBuildExtensions.java index 39f61a1fe..d67755c44 100644 --- a/src/main/java/dev/architectury/loom/extensions/ModBuildExtensions.java +++ b/src/main/java/dev/architectury/loom/extensions/ModBuildExtensions.java @@ -16,9 +16,8 @@ import java.util.jar.JarFile; import java.util.jar.Manifest; -import org.cadixdev.at.AccessTransformSet; -import org.cadixdev.at.io.AccessTransformFormats; -import org.cadixdev.lorenz.MappingSet; +import dev.architectury.at.AccessTransformSet; +import dev.architectury.at.io.AccessTransformFormats; import org.gradle.api.provider.Property; import org.gradle.api.provider.SetProperty; import org.jetbrains.annotations.Nullable; @@ -29,7 +28,6 @@ import net.fabricmc.loom.util.LfWriter; import net.fabricmc.loom.util.aw2at.Aw2At; import net.fabricmc.loom.util.service.UnsafeWorkQueueHelper; -import net.fabricmc.lorenztiny.TinyMappingsReader; public final class ModBuildExtensions { public static Set readMixinConfigsFromManifest(File jarFile) { @@ -87,11 +85,7 @@ public static void convertAwToAt(SetProperty atAccessWidenersProperty, P } MappingsService service = UnsafeWorkQueueHelper.get(mappingBuildServiceUuid, MappingsService.class); - - try (TinyMappingsReader reader = new TinyMappingsReader(service.getMemoryMappingTree(), service.getFromNamespace(), service.getToNamespace())) { - MappingSet mappingSet = reader.read(); - at = at.remap(mappingSet); - } + at = at.remap(service.getMemoryMappingTree(), service.getFromNamespace(), service.getToNamespace()); try (Writer writer = new LfWriter(Files.newBufferedWriter(atPath))) { AccessTransformFormats.FML.write(writer, at); diff --git a/src/main/java/dev/architectury/loom/metadata/ArchitecturyCommonJson.java b/src/main/java/dev/architectury/loom/metadata/ArchitecturyCommonJson.java index c0e448980..238af4a40 100644 --- a/src/main/java/dev/architectury/loom/metadata/ArchitecturyCommonJson.java +++ b/src/main/java/dev/architectury/loom/metadata/ArchitecturyCommonJson.java @@ -18,6 +18,7 @@ import net.fabricmc.loom.LoomGradlePlugin; import net.fabricmc.loom.configuration.ifaceinject.InterfaceInjectionProcessor; +import net.fabricmc.loom.util.ModPlatform; public final class ArchitecturyCommonJson implements JsonBackedModMetadataFile, SingleIdModMetadataFile { public static final String FILE_NAME = "architectury.common.json"; @@ -68,6 +69,11 @@ public Set getAccessWideners() { } } + @Override + public Set getAccessTransformers(ModPlatform platform) { + return Set.of(); + } + @Override public List getInjectedInterfaces(@Nullable String modId) { if (modId == null) { diff --git a/src/main/java/dev/architectury/loom/metadata/ErroringModMetadataFile.java b/src/main/java/dev/architectury/loom/metadata/ErroringModMetadataFile.java index 38d0b3688..7e750934d 100644 --- a/src/main/java/dev/architectury/loom/metadata/ErroringModMetadataFile.java +++ b/src/main/java/dev/architectury/loom/metadata/ErroringModMetadataFile.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.VisibleForTesting; import net.fabricmc.loom.configuration.ifaceinject.InterfaceInjectionProcessor; +import net.fabricmc.loom.util.ModPlatform; /** * A fallback mod metadata file that represents a non-fatal format error @@ -31,6 +32,11 @@ public Set getAccessWideners() { return Set.of(); } + @Override + public Set getAccessTransformers(ModPlatform platform) { + return Set.of(); + } + @Override public List getInjectedInterfaces(@Nullable String modId) { return List.of(); diff --git a/src/main/java/dev/architectury/loom/metadata/ModMetadataFile.java b/src/main/java/dev/architectury/loom/metadata/ModMetadataFile.java index ded523d40..ee5444ce7 100644 --- a/src/main/java/dev/architectury/loom/metadata/ModMetadataFile.java +++ b/src/main/java/dev/architectury/loom/metadata/ModMetadataFile.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable; import net.fabricmc.loom.configuration.ifaceinject.InterfaceInjectionProcessor; +import net.fabricmc.loom.util.ModPlatform; import net.fabricmc.loom.util.function.CollectionUtil; /** @@ -32,6 +33,13 @@ public interface ModMetadataFile { */ Set getAccessWideners(); + /** + * {@return the paths to the access transformer files of this mod, or an empty set if absent}. + * + * @param platform the platform to run the query on + */ + Set getAccessTransformers(ModPlatform platform); + /** * {@return the injected interface data in this mod metadata file}. * diff --git a/src/main/java/dev/architectury/loom/metadata/ModsToml.java b/src/main/java/dev/architectury/loom/metadata/ModsToml.java index 5546a8536..cd698a74f 100644 --- a/src/main/java/dev/architectury/loom/metadata/ModsToml.java +++ b/src/main/java/dev/architectury/loom/metadata/ModsToml.java @@ -6,6 +6,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -19,6 +20,7 @@ import net.fabricmc.loom.configuration.ifaceinject.InterfaceInjectionProcessor; import net.fabricmc.loom.util.ExceptionUtil; +import net.fabricmc.loom.util.ModPlatform; public final class ModsToml implements ModMetadataFile { public static final String FILE_PATH = "META-INF/mods.toml"; @@ -72,6 +74,26 @@ public Set getAccessWideners() { return Set.of(); } + @Override + public Set getAccessTransformers(ModPlatform platform) { + if (platform == ModPlatform.NEOFORGE) { + final List ats = config.get("accessTransformers"); + + if (ats != null) { + final Set result = new HashSet<>(); + + for (Config atEntry : ats) { + final String file = atEntry.get("file"); + if (file != null) result.add(file); + } + + return result; + } + } + + return Set.of(); + } + @Override public List getInjectedInterfaces(@Nullable String modId) { return List.of(); diff --git a/src/main/java/dev/architectury/loom/metadata/QuiltModJson.java b/src/main/java/dev/architectury/loom/metadata/QuiltModJson.java index 05044f993..311831b4f 100644 --- a/src/main/java/dev/architectury/loom/metadata/QuiltModJson.java +++ b/src/main/java/dev/architectury/loom/metadata/QuiltModJson.java @@ -20,6 +20,7 @@ import net.fabricmc.loom.LoomGradlePlugin; import net.fabricmc.loom.configuration.ifaceinject.InterfaceInjectionProcessor; +import net.fabricmc.loom.util.ModPlatform; import net.fabricmc.loom.util.function.CollectionUtil; public final class QuiltModJson implements JsonBackedModMetadataFile, SingleIdModMetadataFile { @@ -84,6 +85,11 @@ public Set getAccessWideners() { } } + @Override + public Set getAccessTransformers(ModPlatform platform) { + return Set.of(); + } + @Override public List getInjectedInterfaces(@Nullable String modId) { try { diff --git a/src/main/java/dev/architectury/loom/neoforge/NeoForgeModDependencies.java b/src/main/java/dev/architectury/loom/neoforge/NeoForgeModDependencies.java new file mode 100644 index 000000000..dda85162b --- /dev/null +++ b/src/main/java/dev/architectury/loom/neoforge/NeoForgeModDependencies.java @@ -0,0 +1,43 @@ +package dev.architectury.loom.neoforge; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Set; + +import dev.architectury.at.AccessTransformSet; +import dev.architectury.at.io.AccessTransformFormats; +import dev.architectury.loom.metadata.ModMetadataFile; +import dev.architectury.loom.metadata.ModMetadataFiles; + +import net.fabricmc.loom.util.Constants; +import net.fabricmc.loom.util.FileSystemUtil; +import net.fabricmc.loom.util.ModPlatform; +import net.fabricmc.mappingio.tree.MappingTreeView; + +public final class NeoForgeModDependencies { + public static void remapAts(Path jar, MappingTreeView mappings, String from, String to) throws IOException { + final ModMetadataFile modMetadata = ModMetadataFiles.fromJar(jar); + Set atPaths = Set.of(Constants.Forge.ACCESS_TRANSFORMER_PATH); + + if (modMetadata != null) { + final Set modsTomlAts = modMetadata.getAccessTransformers(ModPlatform.NEOFORGE); + + if (!modsTomlAts.isEmpty()) { + atPaths = modsTomlAts; + } + } + + try (FileSystemUtil.Delegate fs = FileSystemUtil.getJarFileSystem(jar)) { + for (String atPathStr : atPaths) { + final Path atPath = fs.getPath(atPathStr); + + if (Files.exists(atPath)) { + AccessTransformSet ats = AccessTransformFormats.FML.read(atPath); + ats = ats.remap(mappings, from, to); + AccessTransformFormats.FML.write(atPath, ats); + } + } + } + } +} diff --git a/src/main/java/net/fabricmc/loom/configuration/accesstransformer/AccessTransformerJarProcessor.java b/src/main/java/net/fabricmc/loom/configuration/accesstransformer/AccessTransformerJarProcessor.java index 39c0b86f7..52528301f 100644 --- a/src/main/java/net/fabricmc/loom/configuration/accesstransformer/AccessTransformerJarProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/accesstransformer/AccessTransformerJarProcessor.java @@ -40,9 +40,9 @@ import com.google.common.hash.Hashing; import com.google.common.io.MoreFiles; +import dev.architectury.at.AccessTransformSet; +import dev.architectury.at.io.AccessTransformFormats; import dev.architectury.loom.util.TempFiles; -import org.cadixdev.at.AccessTransformSet; -import org.cadixdev.at.io.AccessTransformFormats; import org.gradle.api.Project; import org.gradle.api.file.FileCollection; import org.gradle.api.logging.Logger; @@ -61,7 +61,6 @@ import net.fabricmc.loom.util.ForgeToolExecutor; import net.fabricmc.loom.util.LoomVersions; import net.fabricmc.loom.util.fmj.FabricModJson; -import net.fabricmc.lorenztiny.TinyMappingsReader; public class AccessTransformerJarProcessor implements MinecraftJarProcessor { private static final Logger LOGGER = Logging.getLogger(AccessTransformerJarProcessor.class); @@ -139,7 +138,7 @@ private Path mergeAndRemapAccessTransformers(ProcessorContext context, List remapList) throws IOException { remapJarManifestEntries(output); if (extension.isForgeLike()) { - AtRemapper.remap(project, output, mappings); + if (extension.isNeoForge()) { + // NeoForge: Fully map ATs + NeoForgeModDependencies.remapAts(output, mappings, fromM, toM); + } else { + // Forge: only map class names, the rest are mapped srg -> named at runtime + AtClassRemapper.remap(project, output, mappings); + } + CoreModClassRemapper.remapJar(project, extension.getPlatform().get(), output, mappings); } diff --git a/src/main/java/net/fabricmc/loom/util/aw2at/Aw2At.java b/src/main/java/net/fabricmc/loom/util/aw2at/Aw2At.java index e18f5efdc..72662d515 100644 --- a/src/main/java/net/fabricmc/loom/util/aw2at/Aw2At.java +++ b/src/main/java/net/fabricmc/loom/util/aw2at/Aw2At.java @@ -1,7 +1,7 @@ /* * This file is part of fabric-loom, licensed under the MIT License (MIT). * - * Copyright (c) 2021 FabricMC + * Copyright (c) 2021-2023 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 @@ -29,10 +29,10 @@ import java.io.IOException; import java.nio.file.Path; -import org.cadixdev.at.AccessChange; -import org.cadixdev.at.AccessTransform; -import org.cadixdev.at.AccessTransformSet; -import org.cadixdev.at.ModifierChange; +import dev.architectury.at.AccessChange; +import dev.architectury.at.AccessTransform; +import dev.architectury.at.AccessTransformSet; +import dev.architectury.at.ModifierChange; import org.cadixdev.bombe.type.signature.MethodSignature; import org.gradle.api.Project; import org.gradle.api.tasks.SourceSet; diff --git a/src/main/java/net/fabricmc/loom/util/srg/AtRemapper.java b/src/main/java/net/fabricmc/loom/util/srg/AtClassRemapper.java similarity index 99% rename from src/main/java/net/fabricmc/loom/util/srg/AtRemapper.java rename to src/main/java/net/fabricmc/loom/util/srg/AtClassRemapper.java index cd3f56f07..f87c2371c 100644 --- a/src/main/java/net/fabricmc/loom/util/srg/AtRemapper.java +++ b/src/main/java/net/fabricmc/loom/util/srg/AtClassRemapper.java @@ -48,7 +48,7 @@ * * @author Juuz */ -public final class AtRemapper { +public final class AtClassRemapper { public static void remap(Project project, Path jar, MappingTree mappings) throws IOException { final Logger logger = project.getLogger(); final String sourceNamespace = IntermediaryNamespaces.intermediary(project); diff --git a/src/test/groovy/net/fabricmc/loom/test/unit/forge/Aw2AtTest.groovy b/src/test/groovy/net/fabricmc/loom/test/unit/forge/Aw2AtTest.groovy index 3fc25d46f..62827ef58 100644 --- a/src/test/groovy/net/fabricmc/loom/test/unit/forge/Aw2AtTest.groovy +++ b/src/test/groovy/net/fabricmc/loom/test/unit/forge/Aw2AtTest.groovy @@ -1,7 +1,7 @@ /* * This file is part of fabric-loom, licensed under the MIT License (MIT). * - * Copyright (c) 2022 FabricMC + * Copyright (c) 2022-2023 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 @@ -24,8 +24,8 @@ package net.fabricmc.loom.test.unit.forge -import org.cadixdev.at.AccessChange -import org.cadixdev.at.ModifierChange +import dev.architectury.at.AccessChange +import dev.architectury.at.ModifierChange import spock.lang.Specification import net.fabricmc.accesswidener.AccessWidenerReader