diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/DependencyProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/DependencyProvider.java index 52eed4fc..28913658 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/DependencyProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/DependencyProvider.java @@ -25,7 +25,6 @@ package net.fabricmc.loom.configuration.providers.forge; import java.io.File; -import java.util.function.Consumer; import org.gradle.api.Project; import org.gradle.api.artifacts.Dependency; @@ -45,7 +44,7 @@ public abstract class DependencyProvider { this.extension = LoomGradleExtension.get(project); } - public abstract void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception; + public abstract void provide(DependencyInfo dependency) throws Exception; public abstract String getTargetConfig(); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/DependencyProviders.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/DependencyProviders.java index b32e53d5..d321f42c 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/DependencyProviders.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/DependencyProviders.java @@ -82,7 +82,7 @@ public class DependencyProviders { DependencyInfo info = DependencyInfo.create(project, dependency, configuration); try { - provider.provide(info, afterTasks::add); + provider.provide(info); } catch (Exception e) { throw new RuntimeException("Failed to provide " + dependency.getGroup() + ":" + dependency.getName() + ":" + dependency.getVersion() + " : " + e.toString(), e); } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingsProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingsProvider.java index b2ebfa71..d31a2906 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingsProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingsProvider.java @@ -39,7 +39,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; +import java.util.function.Supplier; import com.google.common.base.Stopwatch; import com.google.common.collect.HashBasedTable; @@ -56,7 +56,9 @@ import org.objectweb.asm.Opcodes; import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.LoomGradlePlugin; import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; +import net.fabricmc.loom.configuration.providers.mappings.IntermediaryService; import net.fabricmc.loom.configuration.providers.mappings.MappingsProviderImpl; +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.util.FileSystemUtil; import net.fabricmc.loom.util.ThreadingUtils; import net.fabricmc.loom.util.srg.SrgMerger; @@ -72,14 +74,14 @@ public class FieldMigratedMappingsProvider extends MappingsProviderImpl { public Path rawTinyMappings; public Path rawTinyMappingsWithSrg; - public FieldMigratedMappingsProvider(Project project) { - super(project); + public FieldMigratedMappingsProvider(String mappingsIdentifier, Path mappingsWorkingDir, Supplier intermediaryService) { + super(mappingsIdentifier, mappingsWorkingDir, intermediaryService); } @Override - public void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception { - LoomGradleExtension extension = getExtension(); - PatchProvider patchProvider = getExtension().getPatchProvider(); + protected void setup(Project project, MinecraftProvider minecraftProvider, Path inputJar) throws IOException { + LoomGradleExtension extension = LoomGradleExtension.get(project); + PatchProvider patchProvider = extension.getPatchProvider(); migratedFieldsCache = patchProvider.getProjectCacheFolder().resolve("migrated-fields.json"); migratedFields.clear(); @@ -97,26 +99,24 @@ public class FieldMigratedMappingsProvider extends MappingsProviderImpl { } } - super.provide(dependency, postPopulationScheduler); + super.setup(project, minecraftProvider, inputJar); + } + + public static String createForgeMappingsIdentifier(LoomGradleExtension extension, String mappingsName, String version, String classifier, String minecraftVersion) { + return FieldMigratedMappingsProvider.createMappingsIdentifier(mappingsName, version, classifier, minecraftVersion) + "-forge-" + extension.getForgeProvider().getVersion().getCombined(); } @Override - protected String createMappingsIdentifier(String mappingsName, String version, String classifier) { - return super.createMappingsIdentifier(mappingsName, version, classifier) + "-forge-" + getExtension().getForgeProvider().getVersion().getCombined(); - } - - @Override - public void manipulateMappings(Path mappingsJar) throws IOException { + public void manipulateMappings(Project project, Path mappingsJar) throws IOException { Stopwatch stopwatch = Stopwatch.createStarted(); - LoomGradleExtension extension = getExtension(); + LoomGradleExtension extension = LoomGradleExtension.get(project); this.rawTinyMappings = tinyMappings; this.rawTinyMappingsWithSrg = tinyMappingsWithSrg; - String mappingsJarName = mappingsJar.getFileName().toString(); - if (getExtension().shouldGenerateSrgTiny()) { + if (extension.shouldGenerateSrgTiny()) { if (Files.notExists(rawTinyMappingsWithSrg) || isRefreshDeps()) { // Merge tiny mappings with srg - SrgMerger.mergeSrg(getProject().getLogger(), getExtension().getMappingsProvider()::getMojmapSrgFileIfPossible, getRawSrgFile(), rawTinyMappings, rawTinyMappingsWithSrg, true); + SrgMerger.mergeSrg(project.getLogger(), () -> getMojmapSrgFileIfPossible(project), getRawSrgFile(project), rawTinyMappings, rawTinyMappingsWithSrg, true); } } @@ -124,17 +124,17 @@ public class FieldMigratedMappingsProvider extends MappingsProviderImpl { tinyMappingsWithSrg = mappingsWorkingDir().resolve("mappings-srg-updated.tiny"); try { - updateFieldMigration(); + updateFieldMigration(project); } catch (IOException e) { throw new UncheckedIOException(e); } - getProject().getLogger().info(":migrated srg fields in " + stopwatch.stop()); + project.getLogger().info(":migrated srg fields in " + stopwatch.stop()); } - public void updateFieldMigration() throws IOException { + public void updateFieldMigration(Project project) throws IOException { if (!Files.exists(migratedFieldsCache)) { - generateNewFieldMigration(); + generateNewFieldMigration(project); Map map = new HashMap<>(); migratedFields.forEach(entry -> { map.put(entry.getKey().owner + "#" + entry.getKey().field, entry.getValue()); @@ -177,9 +177,9 @@ public class FieldMigratedMappingsProvider extends MappingsProviderImpl { } } - private void generateNewFieldMigration() throws IOException { + private void generateNewFieldMigration(Project project) throws IOException { Map fieldDescriptorMap = new ConcurrentHashMap<>(); - LoomGradleExtension extension = getExtension(); + LoomGradleExtension extension = LoomGradleExtension.get(project); ThreadingUtils.TaskCompleter completer = ThreadingUtils.taskCompleter(); class Visitor extends ClassVisitor { @@ -204,7 +204,7 @@ public class FieldMigratedMappingsProvider extends MappingsProviderImpl { Visitor visitor = new Visitor(Opcodes.ASM9); for (MinecraftPatchedProvider.Environment environment : MinecraftPatchedProvider.Environment.values()) { - File patchedSrgJar = environment.patchedSrgJar.apply(extension.getMappingsProvider().patchedProvider); + File patchedSrgJar = environment.patchedSrgJar.apply(MinecraftPatchedProvider.get(project)); FileSystemUtil.Delegate system = FileSystemUtil.getJarFileSystem(patchedSrgJar, false); completer.onComplete(value -> system.close()); @@ -247,7 +247,7 @@ public class FieldMigratedMappingsProvider extends MappingsProviderImpl { String newDescriptorRemapped = DescriptorRemapper.remapDescriptor(newDescriptor, clazz -> srgToIntermediary.getOrDefault(clazz, clazz)); migratedFields.put(new FieldMember(ownerIntermediary, fieldIntermediary), newDescriptorRemapped); - getProject().getLogger().info(ownerIntermediary + "#" + fieldIntermediary + ": " + descriptorIntermediary + " -> " + newDescriptorRemapped); + project.getLogger().info(ownerIntermediary + "#" + fieldIntermediary + ": " + descriptorIntermediary + " -> " + newDescriptorRemapped); } } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeProvider.java index 31f97d46..78728f02 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeProvider.java @@ -25,7 +25,6 @@ package net.fabricmc.loom.configuration.providers.forge; import java.io.File; -import java.util.function.Consumer; import org.gradle.api.Project; @@ -42,7 +41,7 @@ public class ForgeProvider extends DependencyProvider { } @Override - public void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception { + public void provide(DependencyInfo dependency) throws Exception { version = new ForgeVersion(dependency.getResolvedVersion()); addDependency(dependency.getDepString() + ":userdev", Constants.Configurations.FORGE_USERDEV); addDependency(dependency.getDepString() + ":installer", Constants.Configurations.FORGE_INSTALLER); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeUniversalProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeUniversalProvider.java index 6abc7c8f..3cf742a3 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeUniversalProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeUniversalProvider.java @@ -25,7 +25,6 @@ package net.fabricmc.loom.configuration.providers.forge; import java.io.File; -import java.util.function.Consumer; import org.apache.commons.io.FileUtils; import org.gradle.api.Project; @@ -41,7 +40,7 @@ public class ForgeUniversalProvider extends DependencyProvider { } @Override - public void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception { + public void provide(DependencyInfo dependency) throws Exception { forge = new File(getExtension().getForgeProvider().getGlobalCache(), "forge-universal.jar"); if (!forge.exists() || isRefreshDeps()) { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeUserdevProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeUserdevProvider.java index 63063123..9da9d09b 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeUserdevProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/ForgeUserdevProvider.java @@ -78,7 +78,7 @@ public class ForgeUserdevProvider extends DependencyProvider { } @Override - public void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception { + public void provide(DependencyInfo dependency) throws Exception { this.postPopulationScheduler = postPopulationScheduler; Attribute transformed = Attribute.of("architectury-loom-forge-dependencies-transformed", Boolean.class); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/McpConfigProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/McpConfigProvider.java index 40d100b3..eb399914 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/McpConfigProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/McpConfigProvider.java @@ -33,7 +33,6 @@ import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.nio.file.StandardOpenOption; import java.util.List; -import java.util.function.Consumer; import java.util.jar.Attributes; import java.util.jar.Manifest; import java.util.stream.Collectors; @@ -63,7 +62,7 @@ public class McpConfigProvider extends DependencyProvider { } @Override - public void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception { + public void provide(DependencyInfo dependency) throws Exception { init(dependency.getDependency().getVersion()); Path mcpZip = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not resolve MCPConfig")).toPath(); 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 29af2c5e..a7cf7776 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 @@ -43,6 +43,9 @@ import de.oceanlabs.mcp.mcinjector.adaptors.ParameterAnnotationFixer; import dev.architectury.tinyremapper.InputTag; import dev.architectury.tinyremapper.OutputConsumerPath; import dev.architectury.tinyremapper.TinyRemapper; + +import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; + import net.minecraftforge.binarypatcher.ConsoleTool; import org.apache.commons.io.output.NullOutputStream; import org.gradle.api.Project; @@ -104,10 +107,20 @@ public class MinecraftPatchedProvider extends MergedMinecraftProvider { private boolean atDirty = false; private boolean filesDirty = false; - public static MergedMinecraftProvider getMergedMinecraftProvider(Project project) { + public static MergedMinecraftProvider createMergedMinecraftProvider(Project project) { return LoomGradleExtension.get(project).isForge() ? new MinecraftPatchedProvider(project) : new MergedMinecraftProvider(project); } + public static MinecraftPatchedProvider get(Project project) { + MinecraftProvider provider = LoomGradleExtension.get(project).getMinecraftProvider(); + + if (provider instanceof MinecraftPatchedProvider patched) { + return patched; + } else { + throw new UnsupportedOperationException("Project " + project.getPath() + " does not use MinecraftPatchedProvider!"); + } + } + public MinecraftPatchedProvider(Project project) { super(project); } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/PatchProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/PatchProvider.java index 52eda3bd..5a918d12 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/PatchProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/PatchProvider.java @@ -32,7 +32,6 @@ import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; -import java.util.function.Consumer; import com.google.common.collect.ImmutableMap; import org.gradle.api.Project; @@ -50,7 +49,7 @@ public class PatchProvider extends DependencyProvider { } @Override - public void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception { + public void provide(DependencyInfo dependency) throws Exception { init(dependency.getDependency().getVersion()); if (Files.notExists(clientPatches) || Files.notExists(serverPatches) || isRefreshDeps()) { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/SrgProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/SrgProvider.java index 2c048e93..f895caed 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/SrgProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/SrgProvider.java @@ -41,7 +41,6 @@ import java.nio.file.StandardCopyOption; import java.nio.file.StandardOpenOption; import java.util.HashMap; import java.util.Map; -import java.util.function.Consumer; import com.google.common.base.Stopwatch; import com.google.common.collect.ImmutableMap; @@ -80,7 +79,7 @@ public class SrgProvider extends DependencyProvider { } @Override - public void provide(DependencyInfo dependency, Consumer postPopulationScheduler) throws Exception { + public void provide(DependencyInfo dependency) throws Exception { init(dependency.getDependency().getVersion()); if (!Files.exists(srg) || isRefreshDeps()) { diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java index 9b2b78b6..f3e13573 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingsProviderImpl.java @@ -33,8 +33,12 @@ import java.nio.charset.StandardCharsets; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Supplier; @@ -43,13 +47,17 @@ import com.google.common.base.Suppliers; import com.google.gson.JsonObject; import org.apache.tools.ant.util.StringUtils; import org.gradle.api.Project; +import org.gradle.api.artifacts.Configuration; import org.jetbrains.annotations.Nullable; import org.objectweb.asm.Opcodes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.LoomGradlePlugin; import net.fabricmc.loom.configuration.DependencyInfo; +import net.fabricmc.loom.configuration.providers.forge.FieldMigratedMappingsProvider; +import net.fabricmc.loom.configuration.providers.forge.SrgProvider; import net.fabricmc.loom.configuration.providers.mappings.tiny.MappingsMerger; import net.fabricmc.loom.configuration.providers.mappings.tiny.TinyJarInfo; import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider; @@ -59,24 +67,33 @@ import net.fabricmc.loom.util.DeletingFileVisitor; import net.fabricmc.loom.util.ZipUtils; import net.fabricmc.loom.util.service.SharedService; import net.fabricmc.loom.util.service.SharedServiceManager; +import net.fabricmc.loom.util.srg.MCPReader; +import net.fabricmc.loom.util.srg.SrgMerger; +import net.fabricmc.loom.util.srg.SrgNamedWriter; import net.fabricmc.mappingio.MappingReader; import net.fabricmc.mappingio.format.MappingFormat; import net.fabricmc.mappingio.tree.MemoryMappingTree; import net.fabricmc.stitch.Command; import net.fabricmc.stitch.commands.CommandProposeFieldNames; +import net.fabricmc.stitch.commands.tinyv2.TinyFile; +import net.fabricmc.stitch.commands.tinyv2.TinyV2Writer; public class MappingsProviderImpl implements MappingsProvider, SharedService { private static final Logger LOGGER = LoggerFactory.getLogger(MappingsProviderImpl.class); private Supplier mappingTree; + private Supplier mappingTreeWithSrg; public final String mappingsIdentifier; private final Path mappingsWorkingDir; // The mappings that gradle gives us private final Path baseTinyMappings; // The mappings we use in practice - public final Path tinyMappings; + public Path tinyMappings; public final Path tinyMappingsJar; + public Path tinyMappingsWithSrg; + public final Path mixinTinyMappingsWithSrg; // FORGE: The mixin mappings have srg names in intermediary. + public final Path srgToNamedSrg; // FORGE: srg to named in srg file format private final Path unpickDefinitions; private boolean hasUnpickDefinitions; @@ -85,7 +102,7 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { private final Supplier intermediaryService; - private MappingsProviderImpl(String mappingsIdentifier, Path mappingsWorkingDir, Supplier intermediaryService) { + protected MappingsProviderImpl(String mappingsIdentifier, Path mappingsWorkingDir, Supplier intermediaryService) { this.mappingsIdentifier = mappingsIdentifier; this.mappingsWorkingDir = mappingsWorkingDir; @@ -93,6 +110,9 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { this.tinyMappings = mappingsWorkingDir.resolve("mappings.tiny"); this.tinyMappingsJar = mappingsWorkingDir.resolve("mappings.jar"); this.unpickDefinitions = mappingsWorkingDir.resolve("mappings.unpick"); + this.tinyMappingsWithSrg = mappingsWorkingDir.resolve("mappings-srg.tiny"); + this.mixinTinyMappingsWithSrg = mappingsWorkingDir.resolve("mappings-mixin-srg.tiny"); + this.srgToNamedSrg = mappingsWorkingDir.resolve("mappings-srg-named.srg"); this.intermediaryService = intermediaryService; } @@ -100,7 +120,7 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { public static synchronized MappingsProviderImpl getInstance(Project project, DependencyInfo dependency, MinecraftProvider minecraftProvider) { return SharedServiceManager.get(project).getOrCreateService("MappingsProvider:%s:%s".formatted(dependency.getDepString(), minecraftProvider.minecraftVersion()), () -> { Supplier intermediaryService = Suppliers.memoize(() -> IntermediaryService.getInstance(project, minecraftProvider)); - return create(dependency, minecraftProvider, intermediaryService); + return create(project, dependency, minecraftProvider, intermediaryService); }); } @@ -108,7 +128,11 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { return Objects.requireNonNull(mappingTree, "Cannot get mappings before they have been read").get(); } - private static MappingsProviderImpl create(DependencyInfo dependency, MinecraftProvider minecraftProvider, Supplier intermediaryService) { + public MemoryMappingTree getMappingsWithSrg() throws IOException { + return Objects.requireNonNull(mappingTreeWithSrg, "Cannot get mappings before they have been read").get(); + } + + private static MappingsProviderImpl create(Project project, DependencyInfo dependency, MinecraftProvider minecraftProvider, Supplier intermediaryService) { final String version = dependency.getResolvedVersion(); final Path inputJar = dependency.resolveFile().orElseThrow(() -> new RuntimeException("Could not resolve mappings: " + dependency)).toPath(); final String mappingsName = StringUtils.removeSuffix(dependency.getDependency().getGroup() + "." + dependency.getDependency().getName(), "-unmerged"); @@ -120,13 +144,27 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { } }); - final String mappingsIdentifier = createMappingsIdentifier(mappingsName, version, getMappingsClassifier(dependency, jarInfo.v2()), minecraftProvider.minecraftVersion()); + final LoomGradleExtension extension = LoomGradleExtension.get(project); + final String mappingsIdentifier; + + if (extension.isForge()) { + mappingsIdentifier = FieldMigratedMappingsProvider.createForgeMappingsIdentifier(extension, mappingsName, version, getMappingsClassifier(dependency, jarInfo.v2()), minecraftProvider.minecraftVersion()); + } else { + mappingsIdentifier = createMappingsIdentifier(mappingsName, version, getMappingsClassifier(dependency, jarInfo.v2()), minecraftProvider.minecraftVersion()); + } + final Path workingDir = minecraftProvider.dir(mappingsIdentifier).toPath(); - var mappingProvider = new MappingsProviderImpl(mappingsIdentifier, workingDir, intermediaryService); + MappingsProviderImpl mappingProvider; + + if (extension.isForge()) { + mappingProvider = new FieldMigratedMappingsProvider(mappingsIdentifier, workingDir, intermediaryService); + } else { + mappingProvider = new MappingsProviderImpl(mappingsIdentifier, workingDir, intermediaryService); + } try { - mappingProvider.setup(minecraftProvider, inputJar); + mappingProvider.setup(project, minecraftProvider, inputJar); } catch (IOException e) { cleanWorkingDirectory(workingDir); throw new UncheckedIOException("Failed to setup mappings: " + dependency.getDepString(), e); @@ -135,13 +173,13 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { return mappingProvider; } - private void setup(MinecraftProvider minecraftProvider, Path inputJar) throws IOException { + protected void setup(Project project, MinecraftProvider minecraftProvider, Path inputJar) throws IOException { if (isRefreshDeps()) { cleanWorkingDirectory(mappingsWorkingDir); } if (Files.notExists(tinyMappings) || isRefreshDeps()) { - storeMappings(minecraftProvider, inputJar); + storeMappings(project, minecraftProvider, inputJar); } else { try (FileSystem fileSystem = FileSystems.newFileSystem(inputJar, (ClassLoader) null)) { extractExtras(fileSystem); @@ -153,10 +191,21 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { ZipUtils.add(tinyMappingsJar, "mappings/mappings.tiny", Files.readAllBytes(tinyMappings)); } - mappingTree = Suppliers.memoize(this::readMappings); + mappingTree = Suppliers.memoize(() -> readMappings(tinyMappings)); + LoomGradleExtension extension = LoomGradleExtension.get(project); + manipulateMappings(project, tinyMappingsJar); + + if (extension.shouldGenerateSrgTiny()) { + if (Files.notExists(tinyMappingsWithSrg) || isRefreshDeps()) { + // Merge tiny mappings with srg + SrgMerger.mergeSrg(project.getLogger(), () -> getMojmapSrgFileIfPossible(project), getRawSrgFile(project), tinyMappings, tinyMappingsWithSrg, true); + } + + mappingTreeWithSrg = Suppliers.memoize(() -> readMappings(tinyMappingsWithSrg)); + } } - public void applyToProject(Project project, DependencyInfo dependency) { + public void applyToProject(Project project, DependencyInfo dependency) throws IOException { if (hasUnpickDefinitions()) { String notation = String.format("%s:%s:%s:constants", dependency.getDependency().getGroup(), @@ -168,7 +217,48 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { populateUnpickClasspath(project); } - project.getDependencies().add(Constants.Configurations.MAPPINGS_FINAL, project.files(tinyMappingsJar.toFile())); + LoomGradleExtension extension = LoomGradleExtension.get(project); + + if (extension.isForge()) { + if (!extension.shouldGenerateSrgTiny()) { + throw new IllegalStateException("We have to generate srg tiny in a forge environment!"); + } + + if (Files.notExists(mixinTinyMappingsWithSrg) || isRefreshDeps()) { + List lines = new ArrayList<>(Files.readAllLines(tinyMappingsWithSrg)); + lines.set(0, lines.get(0).replace("intermediary", "yraidemretni").replace("srg", "intermediary")); + Files.deleteIfExists(mixinTinyMappingsWithSrg); + Files.write(mixinTinyMappingsWithSrg, lines); + } + + if (Files.notExists(srgToNamedSrg) || isRefreshDeps()) { + SrgNamedWriter.writeTo(project.getLogger(), srgToNamedSrg, getMappingsWithSrg(), "srg", "named"); + } + } + + project.getDependencies().add(Constants.Configurations.MAPPINGS_FINAL, project.getDependencies().module("loom.resolved:mappings:" + extension.getMinecraftProvider().minecraftVersion() + "/" + mappingsIdentifier())); + } + + protected Path getRawSrgFile(Project project) throws IOException { + LoomGradleExtension extension = LoomGradleExtension.get(project); + + if (extension.getSrgProvider().isTsrgV2()) { + return extension.getSrgProvider().getMergedMojangTrimmed(); + } + + return extension.getSrgProvider().getSrg(); + } + + public Path getMojmapSrgFileIfPossible(Project project) { + try { + LoomGradleExtension extension = LoomGradleExtension.get(project); + return SrgProvider.getMojmapTsrg2(project, extension); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public void manipulateMappings(Project project, Path mappingsJar) throws IOException { } private static String getMappingsClassifier(DependencyInfo dependency, boolean isV2) { @@ -181,15 +271,30 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { return isV2 ? "-v2" : ""; } - private void storeMappings(MinecraftProvider minecraftProvider, Path inputJar) throws IOException { + private void storeMappings(Project project, MinecraftProvider minecraftProvider, Path inputJar) throws IOException { LOGGER.info(":extracting " + inputJar.getFileName()); + if (isMCP(inputJar)) { + try { + readAndMergeMCP(project, inputJar); + } catch (Exception e) { + throw new RuntimeException(e); + } + + return; + } + try (FileSystem fileSystem = FileSystems.newFileSystem(inputJar, (ClassLoader) null)) { extractMappings(fileSystem, baseTinyMappings); extractExtras(fileSystem); } - if (areMappingsV2(baseTinyMappings)) { + if (areMappingsMergedV2(baseTinyMappings)) { + // Architectury Loom Patch + // If a merged tiny v2 mappings file is provided + // Skip merging, should save a lot of time + Files.copy(baseTinyMappings, tinyMappings, StandardCopyOption.REPLACE_EXISTING); + } else if (areMappingsV2(baseTinyMappings)) { // These are unmerged v2 mappings MappingsMerger.mergeAndSaveMappings(baseTinyMappings, tinyMappings, intermediaryService.get()); } else { @@ -204,19 +309,58 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { } } - private MemoryMappingTree readMappings() { + private static MemoryMappingTree readMappings(Path file) { try { MemoryMappingTree mappingTree = new MemoryMappingTree(); - MappingReader.read(tinyMappings, mappingTree); + MappingReader.read(file, mappingTree); return mappingTree; } catch (IOException e) { throw new UncheckedIOException("Failed to read mappings", e); } } + private void readAndMergeMCP(Project project, Path mcpJar) throws Exception { + LoomGradleExtension extension = LoomGradleExtension.get(project); + Path intermediaryTinyPath = intermediaryTinyFile().toPath(); + SrgProvider provider = extension.getSrgProvider(); + + if (provider == null) { + if (!extension.shouldGenerateSrgTiny()) { + Configuration srg = project.getConfigurations().maybeCreate(Constants.Configurations.SRG); + srg.setTransitive(false); + } + + provider = new SrgProvider(project); + project.getDependencies().add(provider.getTargetConfig(), "de.oceanlabs.mcp:mcp_config:" + extension.getMinecraftProvider().minecraftVersion()); + Configuration configuration = project.getConfigurations().getByName(provider.getTargetConfig()); + provider.provide(DependencyInfo.create(project, configuration.getDependencies().iterator().next(), configuration)); + } + + Path srgPath = getRawSrgFile(project); + TinyFile file = new MCPReader(intermediaryTinyPath, srgPath).read(mcpJar); + TinyV2Writer.write(file, tinyMappings); + } + + private boolean isMCP(Path path) throws IOException { + try (FileSystem fs = FileSystems.newFileSystem(path, (ClassLoader) null)) { + return Files.exists(fs.getPath("fields.csv")) && Files.exists(fs.getPath("methods.csv")); + } + } + private static boolean areMappingsV2(Path path) throws IOException { try (BufferedReader reader = Files.newBufferedReader(path)) { return MappingReader.detectFormat(reader) == MappingFormat.TINY_2; + } catch (NoSuchFileException e) { + // TODO: just check the mappings version when Parser supports V1 in readMetadata() + return false; + } + } + + private static boolean areMappingsMergedV2(Path path) throws IOException { + try (BufferedReader reader = Files.newBufferedReader(path)) { + return MappingReader.detectFormat(reader) == MappingFormat.TINY_2 && MappingReader.getNamespaces(reader).containsAll(Arrays.asList("named", "intermediary", "official")); + } catch (NoSuchFileException e) { + return false; } } @@ -333,7 +477,7 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { return intermediaryService.get().getIntermediaryTiny().toFile(); } - private static String createMappingsIdentifier(String mappingsName, String version, String classifier, String minecraftVersion) { + protected static String createMappingsIdentifier(String mappingsName, String version, String classifier, String minecraftVersion) { // mappingsName . mcVersion . version classifier // Example: net.fabricmc.yarn . 1_16_5 . 1.16.5+build.5 -v2 return mappingsName + "." + minecraftVersion.replace(' ', '_').replace('.', '_').replace('-', '_') + "." + version + classifier; @@ -370,5 +514,6 @@ public class MappingsProviderImpl implements MappingsProvider, SharedService { @Override public void close() throws IOException { mappingTree = null; + mappingTreeWithSrg = null; } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/tiny/TinyJarInfo.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/tiny/TinyJarInfo.java index 1a6649a4..e6622165 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/tiny/TinyJarInfo.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/tiny/TinyJarInfo.java @@ -30,6 +30,7 @@ import java.io.UncheckedIOException; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.util.Optional; @@ -50,6 +51,8 @@ public record TinyJarInfo(boolean v2, Optional minecraftVersionId) { try (BufferedReader reader = Files.newBufferedReader(fs.getPath("mappings", "mappings.tiny"))) { return MappingReader.detectFormat(reader) == MappingFormat.TINY_2; } + } catch (NoSuchFileException e) { + return false; } } } 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 2e65eaa6..f1a1dcff 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 @@ -42,7 +42,7 @@ import net.fabricmc.loom.configuration.providers.minecraft.mapped.ProcessedNamed public enum MinecraftJarConfiguration { MERGED( - MinecraftPatchedProvider::getMergedMinecraftProvider, + MinecraftPatchedProvider::createMergedMinecraftProvider, IntermediaryMinecraftProvider.MergedImpl::new, NamedMinecraftProvider.MergedImpl::new, ProcessedNamedMinecraftProvider.MergedImpl::new,