diff --git a/src/main/java/dev/architectury/loom/neoforge/MojangMappingsMerger.java b/src/main/java/dev/architectury/loom/neoforge/MojangMappingsMerger.java new file mode 100644 index 00000000..e69eab08 --- /dev/null +++ b/src/main/java/dev/architectury/loom/neoforge/MojangMappingsMerger.java @@ -0,0 +1,66 @@ +package dev.architectury.loom.neoforge; + +import net.fabricmc.loom.api.mappings.layered.MappingContext; +import net.fabricmc.loom.api.mappings.layered.MappingLayer; +import net.fabricmc.loom.api.mappings.layered.MappingsNamespace; +import net.fabricmc.loom.configuration.providers.mappings.LayeredMappingsProcessor; +import net.fabricmc.loom.configuration.providers.mappings.mojmap.MojangMappingsSpec; +import net.fabricmc.loom.util.ExceptionUtil; +import net.fabricmc.mappingio.MappingReader; +import net.fabricmc.mappingio.MappingVisitor; +import net.fabricmc.mappingio.MappingWriter; +import net.fabricmc.mappingio.adapter.MappingNsRenamer; +import net.fabricmc.mappingio.format.MappingFormat; +import net.fabricmc.mappingio.tree.MemoryMappingTree; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.function.UnaryOperator; + +public final class MojangMappingsMerger { + public static void mergeMojangMappings(MappingContext context, Path raw, Path merged) { + try { + var processor = new LayeredMappingsProcessor(null); + var inputLayer = new FileLayer(raw, MappingsNamespace.NAMED); + var mojangLayer = new MojangMappingsSpec(true).createLayer(context); + var renamedMojangLayer = new WrappedLayer(mojangLayer, next -> { + Map renames = Map.of(MappingsNamespace.NAMED.toString(), MappingsNamespace.MOJANG.toString()); + return new MappingNsRenamer(next, renames); + }); + MemoryMappingTree mappingTree = processor.getMappings(List.of(inputLayer, renamedMojangLayer)); + + try (MappingWriter writer = MappingWriter.create(merged, MappingFormat.TINY_2)) { + mappingTree.accept(writer); + } + } catch (IOException e) { + throw ExceptionUtil.createDescriptiveWrapper(UncheckedIOException::new, "Could not merge Mojang mappings", e); + } + } + + private record FileLayer(Path input, MappingsNamespace mergeNamespace) implements MappingLayer { + @Override + public void visit(MappingVisitor mappingVisitor) throws IOException { + MappingReader.read(input, mappingVisitor); + } + + @Override + public MappingsNamespace getSourceNamespace() { + return mergeNamespace; + } + } + + private record WrappedLayer(MappingLayer layer, UnaryOperator visitorWrapper) implements MappingLayer { + @Override + public void visit(MappingVisitor mappingVisitor) throws IOException { + layer.visit(visitorWrapper.apply(mappingVisitor)); + } + + @Override + public MappingsNamespace getSourceNamespace() { + return layer.getSourceNamespace(); + } + } +} diff --git a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java index cd32359f..ad7e8d30 100644 --- a/src/main/java/net/fabricmc/loom/LoomGradleExtension.java +++ b/src/main/java/net/fabricmc/loom/LoomGradleExtension.java @@ -27,6 +27,8 @@ package net.fabricmc.loom; import java.nio.file.Path; import java.util.List; +import net.fabricmc.loom.configuration.providers.minecraft.mapped.MojangMappedMinecraftProvider; + import org.gradle.api.Project; import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.FileCollection; @@ -95,6 +97,10 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI { void setSrgMinecraftProvider(SrgMinecraftProvider srgMinecraftProvider); + MojangMappedMinecraftProvider getMojangMappedMinecraftProvider(); + + void setMojangMappedMinecraftProvider(MojangMappedMinecraftProvider srgMinecraftProvider); + default List getMinecraftJars(MappingsNamespace mappingsNamespace) { return switch (mappingsNamespace) { case NAMED -> getNamedMinecraftProvider().getMinecraftJarPaths(); @@ -104,6 +110,10 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI { ModPlatform.assertPlatform(this, ModPlatform.FORGE, () -> "SRG jars are only available on Forge."); yield getSrgMinecraftProvider().getMinecraftJarPaths(); } + case MOJANG -> { + ModPlatform.assertPlatform(this, ModPlatform.NEOFORGE, () -> "Mojang-mapped jars are only available on NeoForge."); + yield getMojangMappedMinecraftProvider().getMinecraftJarPaths(); + } }; } @@ -149,12 +159,13 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI { return isForge() && !getForge().getDataGenMods().isEmpty(); } - default boolean isForgeAndOfficial() { - return isForge() && getMcpConfigProvider().isOfficial(); + // TODO (Neo): Is the official key present in Neo's data? + default boolean isForgeLikeAndOfficial() { + return isForgeLike() && getMcpConfigProvider().isOfficial(); } - default boolean isForgeAndNotOfficial() { - return isForge() && !getMcpConfigProvider().isOfficial(); + default boolean isForgeLikeAndNotOfficial() { + return isForgeLike() && !getMcpConfigProvider().isOfficial(); } DependencyProviders getDependencyProviders(); @@ -179,4 +190,14 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI { ForgeRunsProvider getForgeRunsProvider(); void setForgeRunsProvider(ForgeRunsProvider forgeRunsProvider); + + /** + * The mapping file that is specific to the platform settings. + * It contains SRG (Forge/common) or Mojang mappings (NeoForge) as needed. + * + * @return the platform mapping file path + */ + default Path getPlatformMappingFile() { + return getMappingConfiguration().getPlatformMappingFile(this); + } } diff --git a/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java b/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java index 7c62569e..043b33de 100644 --- a/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java +++ b/src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java @@ -235,10 +235,18 @@ public interface LoomGradleExtensionAPI { Provider getPlatform(); + default boolean isForgeLike() { + return getPlatform().get().isForgeLike(); + } + default boolean isForge() { return getPlatform().get() == ModPlatform.FORGE; } + default boolean isNeoForge() { + return getPlatform().get() == ModPlatform.NEOFORGE; + } + default boolean isQuilt() { return getPlatform().get() == ModPlatform.QUILT; } @@ -260,7 +268,7 @@ public interface LoomGradleExtensionAPI { * * @return the Forge extension * @throws UnsupportedOperationException if running on another platform - * @see #isForge() + * @see #isForgeLike() */ ForgeExtensionAPI getForge(); diff --git a/src/main/java/net/fabricmc/loom/api/mappings/layered/MappingsNamespace.java b/src/main/java/net/fabricmc/loom/api/mappings/layered/MappingsNamespace.java index 67a35168..2d8316c7 100644 --- a/src/main/java/net/fabricmc/loom/api/mappings/layered/MappingsNamespace.java +++ b/src/main/java/net/fabricmc/loom/api/mappings/layered/MappingsNamespace.java @@ -54,6 +54,14 @@ public enum MappingsNamespace { */ SRG, + /** + * Mojang's official names from their deobfuscation maps. + * + *

They are used as the mapping set in a NeoForge production environment akin to Fabric's + * {@linkplain #INTERMEDIARY intermediary mappings}. + */ + MOJANG, + /** * Named mappings are the developer friendly names used to develop mods against. */ @@ -70,6 +78,7 @@ public enum MappingsNamespace { case "official" -> OFFICIAL; case "intermediary" -> INTERMEDIARY; case "srg" -> SRG; + case "mojang" -> MOJANG; case "named" -> NAMED; default -> null; }; diff --git a/src/main/java/net/fabricmc/loom/build/IntermediaryNamespaces.java b/src/main/java/net/fabricmc/loom/build/IntermediaryNamespaces.java index 36f5d958..bd2a92fa 100644 --- a/src/main/java/net/fabricmc/loom/build/IntermediaryNamespaces.java +++ b/src/main/java/net/fabricmc/loom/build/IntermediaryNamespaces.java @@ -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 @@ -35,7 +35,11 @@ public final class IntermediaryNamespaces { */ public static String intermediary(Project project) { LoomGradleExtension extension = LoomGradleExtension.get(project); - return extension.isForge() ? "srg" : "intermediary"; + return switch (extension.getPlatform().get()) { + case FABRIC, QUILT -> MappingsNamespace.INTERMEDIARY.toString(); + case FORGE -> MappingsNamespace.SRG.toString(); + case NEOFORGE -> MappingsNamespace.MOJANG.toString(); + }; } /** diff --git a/src/main/java/net/fabricmc/loom/build/nesting/JarNester.java b/src/main/java/net/fabricmc/loom/build/nesting/JarNester.java index a90d5de0..9bb9912d 100644 --- a/src/main/java/net/fabricmc/loom/build/nesting/JarNester.java +++ b/src/main/java/net/fabricmc/loom/build/nesting/JarNester.java @@ -64,7 +64,7 @@ public class JarNester { } }).collect(Collectors.toList())); - if (platform == ModPlatform.FORGE) { + if (platform.isForgeLike()) { handleForgeJarJar(forgeJars, modJar, logger); return; } diff --git a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java index eea545d4..2cc43631 100644 --- a/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/CompileConfiguration.java @@ -35,6 +35,8 @@ import java.util.function.Consumer; import javax.inject.Inject; +import net.fabricmc.loom.configuration.providers.minecraft.mapped.MojangMappedMinecraftProvider; + import org.gradle.api.Project; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginExtension; @@ -132,7 +134,7 @@ public abstract class CompileConfiguration implements Runnable { configureDecompileTasks(configContext); - if (extension.isForge()) { + if (extension.isForgeLike()) { if (extension.isDataGenEnabled()) { getProject().getExtensions().getByType(JavaPluginExtension.class).getSourceSets().getByName("main").resources(files -> { files.srcDir(getProject().file("src/generated/resources")); @@ -165,7 +167,7 @@ public abstract class CompileConfiguration implements Runnable { getTasks().withType(AbstractCopyTask.class).configureEach(abstractCopyTask -> abstractCopyTask.setFilteringCharset(StandardCharsets.UTF_8.name())); getTasks().withType(JavaCompile.class).configureEach(javaCompile -> javaCompile.getOptions().setEncoding(StandardCharsets.UTF_8.name())); - if (extension.isForge()) { + if (extension.isForgeLike()) { // Create default mod from main source set extension.mods(mods -> { final SourceSet main = getProject().getExtensions().getByType(JavaPluginExtension.class).getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME); @@ -188,7 +190,7 @@ public abstract class CompileConfiguration implements Runnable { // Provide the vanilla mc jars -- TODO share across getProject()s. final MinecraftProvider minecraftProvider = jarConfiguration.getMinecraftProviderFunction().apply(configContext); - if (extension.isForge() && !(minecraftProvider instanceof ForgeMinecraftProvider)) { + if (extension.isForgeLike() && !(minecraftProvider instanceof ForgeMinecraftProvider)) { throw new UnsupportedOperationException("Using Forge with split jars is not supported!"); } @@ -203,7 +205,7 @@ public abstract class CompileConfiguration implements Runnable { final MappingConfiguration mappingConfiguration = MappingConfiguration.create(getProject(), configContext.serviceManager(), mappingsDep, minecraftProvider); extension.setMappingConfiguration(mappingConfiguration); - if (extension.isForge()) { + if (extension.isForgeLike()) { ForgeLibrariesProvider.provide(mappingConfiguration, project); ((ForgeMinecraftProvider) minecraftProvider).getPatchedProvider().provide(); } @@ -211,7 +213,7 @@ public abstract class CompileConfiguration implements Runnable { mappingConfiguration.setupPost(project); mappingConfiguration.applyToProject(getProject(), mappingsDep); - if (extension.isForge()) { + if (extension.isForgeLike()) { extension.setForgeRunsProvider(ForgeRunsProvider.create(project)); } @@ -243,6 +245,10 @@ public abstract class CompileConfiguration implements Runnable { final SrgMinecraftProvider srgMinecraftProvider = jarConfiguration.getSrgMinecraftProviderBiFunction().apply(project, minecraftProvider); extension.setSrgMinecraftProvider(srgMinecraftProvider); srgMinecraftProvider.provide(provideContext); + } else if (extension.isNeoForge()) { + final MojangMappedMinecraftProvider mojangMappedMinecraftProvider = jarConfiguration.getMojangMappedMinecraftProviderBiFunction().apply(project, minecraftProvider); + extension.setMojangMappedMinecraftProvider(mojangMappedMinecraftProvider); + mojangMappedMinecraftProvider.provide(provideContext); } } @@ -262,7 +268,7 @@ public abstract class CompileConfiguration implements Runnable { extension.addMinecraftJarProcessor(InterfaceInjectionProcessor.class, "fabric-loom:interface-inject", interfaceInjection.getEnableDependencyInterfaceInjection().get()); } - if (extension.isForge()) { + if (extension.isForgeLike()) { extension.addMinecraftJarProcessor(AccessTransformerJarProcessor.class, "loom:access-transformer", configContext.project(), extension.getForge().getAccessTransformers()); } } @@ -356,7 +362,9 @@ public abstract class CompileConfiguration implements Runnable { DependencyProviders dependencyProviders = new DependencyProviders(); extension.setDependencyProviders(dependencyProviders); - if (extension.isForge()) { + // TODO (Neo): Adapt this stuff + + if (extension.isForgeLike()) { dependencyProviders.addProvider(new ForgeProvider(project)); dependencyProviders.addProvider(new ForgeUserdevProvider(project)); } @@ -365,7 +373,7 @@ public abstract class CompileConfiguration implements Runnable { dependencyProviders.addProvider(new SrgProvider(project)); } - if (extension.isForge()) { + if (extension.isForgeLike()) { dependencyProviders.addProvider(new McpConfigProvider(project)); dependencyProviders.addProvider(new PatchProvider(project)); dependencyProviders.addProvider(new ForgeUniversalProvider(project)); diff --git a/src/main/java/net/fabricmc/loom/configuration/LoomConfigurations.java b/src/main/java/net/fabricmc/loom/configuration/LoomConfigurations.java index 0aff9617..d5124ba7 100644 --- a/src/main/java/net/fabricmc/loom/configuration/LoomConfigurations.java +++ b/src/main/java/net/fabricmc/loom/configuration/LoomConfigurations.java @@ -118,7 +118,7 @@ public abstract class LoomConfigurations implements Runnable { } }); - if (extension.isForge()) { + if (extension.isForgeLike()) { // Set up Forge configurations registerNonTransitive(Constants.Configurations.FORGE, Role.RESOLVABLE); registerNonTransitive(Constants.Configurations.FORGE_USERDEV, Role.RESOLVABLE); diff --git a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java index 67afe66d..7372bb11 100644 --- a/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java +++ b/src/main/java/net/fabricmc/loom/configuration/LoomDependencyManager.java @@ -37,14 +37,14 @@ public class LoomDependencyManager { LoomGradleExtension extension = LoomGradleExtension.get(project); SourceRemapper sourceRemapper = new SourceRemapper(project, serviceManager, true); - String platformSuffix = extension.isForge() ? "_forge" : extension.isQuilt() ? "_arch_quilt" : ""; + String platformSuffix = extension.isForgeLike() ? "_forge" : extension.isQuilt() ? "_arch_quilt" : ""; String mappingsIdentifier = extension.getMappingConfiguration().mappingsIdentifier() + platformSuffix; ModConfigurationRemapper.supplyModConfigurations(project, serviceManager, mappingsIdentifier, extension, sourceRemapper); sourceRemapper.remapAll(); - if (extension.getInstallerData() == null && !extension.isForge()) { + if (extension.getInstallerData() == null && !extension.isForgeLike()) { if (extension.isQuilt()) { project.getLogger().warn("quilt_installer.json not found in dependencies!"); } else { diff --git a/src/main/java/net/fabricmc/loom/configuration/MavenPublication.java b/src/main/java/net/fabricmc/loom/configuration/MavenPublication.java index 7fbe9702..18991bba 100644 --- a/src/main/java/net/fabricmc/loom/configuration/MavenPublication.java +++ b/src/main/java/net/fabricmc/loom/configuration/MavenPublication.java @@ -100,7 +100,7 @@ public abstract class MavenPublication implements Runnable { if (hasSoftwareComponent(publication) || EXCLUDED_PUBLICATIONS.contains(publication)) { continue; - } else if (!reportedDeprecation.get() && !LoomGradleExtension.get(getProject()).isForge()) { + } else if (!reportedDeprecation.get() && !LoomGradleExtension.get(getProject()).isForgeLike()) { DeprecationHelper deprecationHelper = LoomGradleExtension.get(getProject()).getDeprecationHelper(); deprecationHelper.warn("Loom is applying dependency data manually to publications instead of using a software component (from(components[\"java\"])). This is deprecated."); reportedDeprecation.set(true); diff --git a/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java index 9576c3c6..68a7ac58 100644 --- a/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/decompile/SingleJarDecompileConfiguration.java @@ -75,7 +75,7 @@ public class SingleJarDecompileConfiguration extends DecompileConfiguration { task.setDescription("Decompile Minecraft using Forge's toolchain."); task.setGroup(Constants.TaskGroup.FABRIC); diff --git a/src/main/java/net/fabricmc/loom/configuration/ide/RunConfigSettings.java b/src/main/java/net/fabricmc/loom/configuration/ide/RunConfigSettings.java index 0e7f97a8..241cba67 100644 --- a/src/main/java/net/fabricmc/loom/configuration/ide/RunConfigSettings.java +++ b/src/main/java/net/fabricmc/loom/configuration/ide/RunConfigSettings.java @@ -345,7 +345,7 @@ public class RunConfigSettings implements Named { environment("client"); defaultMainClass(Constants.Knot.KNOT_CLIENT); - if (getExtension().isForge()) { + if (getExtension().isForgeLike()) { forgeTemplate("client"); } } @@ -358,7 +358,7 @@ public class RunConfigSettings implements Named { environment("server"); defaultMainClass(Constants.Knot.KNOT_SERVER); - if (getExtension().isForge()) { + if (getExtension().isForgeLike()) { forgeTemplate("server"); } } @@ -369,7 +369,7 @@ public class RunConfigSettings implements Named { *

This method can only be used on Forge. */ public void data() { - ModPlatform.assertPlatform(getExtension(), ModPlatform.FORGE, () -> "RunConfigSettings.data() is only usable on Forge."); + ModPlatform.assertForgeLike(getExtension(), () -> "RunConfigSettings.data() is only usable on Forge."); environment("data"); forgeTemplate("data"); } @@ -384,7 +384,7 @@ public class RunConfigSettings implements Named { * @since 1.0 */ public void forgeTemplate(String templateName) { - ModPlatform.assertPlatform(getExtension(), ModPlatform.FORGE); + ModPlatform.assertForgeLike(getExtension()); defaultMainClass(Constants.Forge.UNDETERMINED_MAIN_CLASS); // Evaluate later if Forge hasn't been resolved yet. evaluateNowOrLater(() -> { @@ -437,11 +437,11 @@ public class RunConfigSettings implements Named { * {@linkplain net.fabricmc.loom.api.LoomGradleExtensionAPI#getMods global container} * declared in the {@code loom} extension. * - *

This method is currently only available on Forge. + *

This method is currently only available on Forge and NeoForge. */ @ApiStatus.Experimental public NamedDomainObjectContainer getMods() { - ModPlatform.assertPlatform(project, ModPlatform.FORGE); + ModPlatform.assertForgeLike(extension); return mods; } diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/ArtifactMetadata.java b/src/main/java/net/fabricmc/loom/configuration/mods/ArtifactMetadata.java index 17bf8184..32a2d290 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/ArtifactMetadata.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/ArtifactMetadata.java @@ -60,8 +60,8 @@ public record ArtifactMetadata(boolean isFabricMod, RemapRequirements remapRequi RemapRequirements remapRequirements = RemapRequirements.DEFAULT; InstallerData installerData = null; - // Force-remap all mods on Forge. - if (platform == ModPlatform.FORGE) { + // Force-remap all mods on Forge and NeoForge. + if (platform.isForgeLike()) { remapRequirements = RemapRequirements.OPT_IN; } diff --git a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java index 3b72e016..90688938 100644 --- a/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java +++ b/src/main/java/net/fabricmc/loom/configuration/mods/ModProcessor.java @@ -166,7 +166,7 @@ public class ModProcessor { Stopwatch stopwatch = Stopwatch.createStarted(); - boolean srg = (fromM.equals("srg") || toM.equals("srg")) && extension.isForge(); + boolean srg = (fromM.equals("srg") || toM.equals("srg")) && extension.isForgeLike(); MemoryMappingTree mappings = mappingConfiguration.getMappingsService(serviceManager, srg).getMappingTree(); LoggerFilter.replaceSystemOut(); TinyRemapper.Builder builder = TinyRemapper.newRemapper() @@ -187,7 +187,7 @@ public class ModProcessor { final TinyRemapper remapper = builder.build(); - for (Path minecraftJar : extension.getMinecraftJars(extension.isForge() ? MappingsNamespace.SRG : MappingsNamespace.INTERMEDIARY)) { + for (Path minecraftJar : extension.getMinecraftJars(extension.isForgeLike() ? MappingsNamespace.SRG : MappingsNamespace.INTERMEDIARY)) { remapper.readClassPathAsync(minecraftJar); } @@ -264,7 +264,7 @@ public class ModProcessor { stripNestedJars(output); remapJarManifestEntries(output); - if (extension.isForge()) { + if (extension.isForgeLike()) { AtRemapper.remap(project.getLogger(), output, mappings); CoreModClassRemapper.remapJar(output, mappings, project.getLogger()); } diff --git a/src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java b/src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java index 2fa5cf22..e4a3b3ba 100644 --- a/src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java +++ b/src/main/java/net/fabricmc/loom/configuration/processors/ProcessorContextImpl.java @@ -64,6 +64,6 @@ public record ProcessorContextImpl(ConfigContext configContext, MinecraftJar min @Override public MemoryMappingTree getMappings() { LoomGradleExtension extension = LoomGradleExtension.get(configContext().project()); - return extension.getMappingConfiguration().getMappingsService(configContext().serviceManager(), extension.isForge()).getMappingTree(); + return extension.getMappingConfiguration().getMappingsService(configContext().serviceManager(), extension.isForgeLike()).getMappingTree(); } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingConfiguration.java index 72304ffb..7a96e6db 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/FieldMigratedMappingConfiguration.java @@ -35,6 +35,7 @@ import java.util.AbstractMap; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; @@ -68,8 +69,9 @@ import net.fabricmc.mappingio.tree.MemoryMappingTree; public final class FieldMigratedMappingConfiguration extends MappingConfiguration { private List> migratedFields = new ArrayList<>(); public Path migratedFieldsCache; - public Path rawTinyMappings; - public Path rawTinyMappingsWithSrg; + private Path rawTinyMappings; + private Path rawTinyMappingsWithSrg; + private Path rawTinyMappingsWithMojang; // TODO: Generate the migrated one public FieldMigratedMappingConfiguration(String mappingsIdentifier, Path mappingsWorkingDir) { super(mappingsIdentifier, mappingsWorkingDir); @@ -100,7 +102,10 @@ public final class FieldMigratedMappingConfiguration extends MappingConfiguratio } public static String createForgeMappingsIdentifier(LoomGradleExtension extension, String mappingsName, String version, String classifier, String minecraftVersion) { - return FieldMigratedMappingConfiguration.createMappingsIdentifier(mappingsName, version, classifier, minecraftVersion) + "-forge-" + extension.getForgeProvider().getVersion().getCombined(); + final String base = FieldMigratedMappingConfiguration.createMappingsIdentifier(mappingsName, version, classifier, minecraftVersion); + final String platform = extension.getPlatform().get().name().toLowerCase(Locale.ROOT); + final String forgeVersion = extension.getForgeProvider().getVersion().getCombined(); + return base + "-" + platform + "-" + forgeVersion; } @Override @@ -109,6 +114,7 @@ public final class FieldMigratedMappingConfiguration extends MappingConfiguratio LoomGradleExtension extension = LoomGradleExtension.get(project); this.rawTinyMappings = tinyMappings; this.rawTinyMappingsWithSrg = tinyMappingsWithSrg; + this.rawTinyMappingsWithMojang = tinyMappingsWithMojang; if (extension.shouldGenerateSrgTiny()) { if (Files.notExists(rawTinyMappingsWithSrg) || extension.refreshDeps()) { @@ -120,6 +126,7 @@ public final class FieldMigratedMappingConfiguration extends MappingConfiguratio tinyMappings = mappingsWorkingDir().resolve("mappings-field-migrated.tiny"); tinyMappingsWithSrg = mappingsWorkingDir().resolve("mappings-srg-field-migrated.tiny"); + tinyMappingsWithMojang = mappingsWorkingDir().resolve("mappings-mojang-field-migrated.tiny"); try { updateFieldMigration(project); 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 98d3fa65..92dd7829 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 @@ -436,7 +436,7 @@ public class MinecraftPatchedProvider { copyMissingClasses(minecraftSrgJar, minecraftPatchedSrgJar); deleteParameterNames(minecraftPatchedSrgJar); - if (getExtension().isForgeAndNotOfficial()) { + if (getExtension().isForgeLikeAndNotOfficial()) { fixParameterAnnotation(minecraftPatchedSrgJar); } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/forge/minecraft/ForgeMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/forge/minecraft/ForgeMinecraftProvider.java index f9d851b7..9ad86a57 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/forge/minecraft/ForgeMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/forge/minecraft/ForgeMinecraftProvider.java @@ -38,14 +38,14 @@ public interface ForgeMinecraftProvider { MinecraftPatchedProvider getPatchedProvider(); static MergedMinecraftProvider createMerged(ConfigContext context) { - return LoomGradleExtension.get(context.project()).isForge() ? new MergedForgeMinecraftProvider(context) : new MergedMinecraftProvider(context); + return LoomGradleExtension.get(context.project()).isForgeLike() ? new MergedForgeMinecraftProvider(context) : new MergedMinecraftProvider(context); } static SingleJarMinecraftProvider createServerOnly(ConfigContext context) { - return LoomGradleExtension.get(context.project()).isForge() ? SingleJarForgeMinecraftProvider.server(context) : SingleJarMinecraftProvider.server(context); + return LoomGradleExtension.get(context.project()).isForgeLike() ? SingleJarForgeMinecraftProvider.server(context) : SingleJarMinecraftProvider.server(context); } static SingleJarMinecraftProvider createClientOnly(ConfigContext context) { - return LoomGradleExtension.get(context.project()).isForge() ? SingleJarForgeMinecraftProvider.client(context) : SingleJarMinecraftProvider.client(context); + return LoomGradleExtension.get(context.project()).isForgeLike() ? SingleJarForgeMinecraftProvider.client(context) : SingleJarMinecraftProvider.client(context); } } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java index a2716566..9fa85eeb 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/mappings/MappingConfiguration.java @@ -44,6 +44,12 @@ import java.util.Objects; import com.google.common.base.Stopwatch; import com.google.gson.JsonObject; + +import dev.architectury.loom.neoforge.MojangMappingsMerger; + +import net.fabricmc.loom.api.mappings.layered.MappingContext; +import net.fabricmc.mappingio.adapter.MappingNsRenamer; + import org.apache.tools.ant.util.StringUtils; import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; @@ -87,6 +93,7 @@ public class MappingConfiguration { // The mappings we use in practice public Path tinyMappings; public final Path tinyMappingsJar; + public Path tinyMappingsWithMojang; public Path tinyMappingsWithSrg; public final Map mixinTinyMappings; // The mixin mappings have other names in intermediary. public final Path srgToNamedSrg; // FORGE: srg to named in srg file format @@ -105,6 +112,7 @@ public class MappingConfiguration { this.tinyMappingsJar = mappingsWorkingDir.resolve("mappings.jar"); this.unpickDefinitions = mappingsWorkingDir.resolve("mappings.unpick"); this.tinyMappingsWithSrg = mappingsWorkingDir.resolve("mappings-srg.tiny"); + this.tinyMappingsWithMojang = mappingsWorkingDir.resolve("mappings-mojang.tiny"); this.mixinTinyMappings = new HashMap<>(); this.srgToNamedSrg = mappingsWorkingDir.resolve("mappings-srg-named.srg"); } @@ -124,7 +132,7 @@ public class MappingConfiguration { final LoomGradleExtension extension = LoomGradleExtension.get(project); String mappingsIdentifier; - if (extension.isForge()) { + if (extension.isForgeLike()) { mappingsIdentifier = FieldMigratedMappingConfiguration.createForgeMappingsIdentifier(extension, mappingsName, version, getMappingsClassifier(dependency, jarInfo.v2()), minecraftProvider.minecraftVersion()); } else { mappingsIdentifier = createMappingsIdentifier(mappingsName, version, getMappingsClassifier(dependency, jarInfo.v2()), minecraftProvider.minecraftVersion()); @@ -138,7 +146,7 @@ public class MappingConfiguration { MappingConfiguration mappingConfiguration; - if (extension.isForge()) { + if (extension.isForgeLike()) { mappingConfiguration = new FieldMigratedMappingConfiguration(mappingsIdentifier, workingDir); } else { mappingConfiguration = new MappingConfiguration(mappingsIdentifier, workingDir); @@ -161,6 +169,7 @@ public class MappingConfiguration { public TinyMappingsService getMappingsService(SharedServiceManager serviceManager, boolean withSrg) { final Path tinyMappings; + // TODO (Neo): Needs a "with Mojang" option if (withSrg) { if (Files.notExists(this.tinyMappingsWithSrg)) { throw new UnsupportedOperationException("Cannot get mappings service with SRG mappings without SRG enabled!"); @@ -206,6 +215,15 @@ public class MappingConfiguration { project.getLogger().info(":merged srg mappings in " + stopwatch.stop()); } } + + if (extension.isNeoForge()) { + if (Files.notExists(tinyMappingsWithMojang) || extension.refreshDeps()) { + Stopwatch stopwatch = Stopwatch.createStarted(); + MappingContext context = new GradleMappingContext(project, "tmp-neoforge"); + MojangMappingsMerger.mergeMojangMappings(context, tinyMappings, tinyMappingsWithSrg); + project.getLogger().info(":merged mojang mappings in {}", stopwatch.stop()); + } + } } public void applyToProject(Project project, DependencyInfo dependency) throws IOException { @@ -222,7 +240,7 @@ public class MappingConfiguration { LoomGradleExtension extension = LoomGradleExtension.get(project); - if (extension.isForge()) { + if (extension.isForgeLike()) { if (!extension.shouldGenerateSrgTiny()) { throw new IllegalStateException("We have to generate srg tiny in a forge environment!"); } @@ -299,7 +317,7 @@ public class MappingConfiguration { MappingsMerger.mergeAndSaveMappings(baseTinyMappings, tinyMappings, intermediateMappingsService); } else { - if (LoomGradleExtension.get(project).isForge()) { + if (LoomGradleExtension.get(project).isForgeLike()) { // (2022-09-11) This is due to ordering issues. // To complete V1 mappings, we need the full MC jar. // On Forge, producing the full MC jar needs the list of all Forge dependencies @@ -506,14 +524,14 @@ public class MappingConfiguration { } public Path getReplacedTarget(LoomGradleExtension loom, String namespace) { - if (namespace.equals("intermediary")) return loom.shouldGenerateSrgTiny() ? tinyMappingsWithSrg : tinyMappings; + if (namespace.equals("intermediary")) return getPlatformMappingFile(loom); return mixinTinyMappings.computeIfAbsent(namespace, k -> { Path path = mappingsWorkingDir.resolve("mappings-mixin-" + namespace + ".tiny"); try { if (Files.notExists(path) || loom.refreshDeps()) { - List lines = new ArrayList<>(Files.readAllLines(loom.shouldGenerateSrgTiny() ? tinyMappingsWithSrg : tinyMappings)); + List lines = new ArrayList<>(Files.readAllLines(getPlatformMappingFile(loom))); lines.set(0, lines.get(0).replace("intermediary", "yraidemretni").replace(namespace, "intermediary")); Files.deleteIfExists(path); Files.write(path, lines); @@ -526,6 +544,22 @@ public class MappingConfiguration { }); } + /** + * The mapping file that is specific to the platform settings. + * It contains SRG (Forge/common) or Mojang mappings (NeoForge) as needed. + * + * @return the platform mapping file path + */ + public Path getPlatformMappingFile(LoomGradleExtension extension) { + if (extension.shouldGenerateSrgTiny()) { + return tinyMappingsWithSrg; + } else if (extension.isNeoForge()) { + return tinyMappingsWithMojang; + } else { + return tinyMappings; + } + } + public record UnpickMetadata(String unpickGroup, String unpickVersion) { } } 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 47370df7..a265889c 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 @@ -38,6 +38,7 @@ import net.fabricmc.loom.configuration.processors.MinecraftJarProcessorManager; import net.fabricmc.loom.configuration.providers.forge.minecraft.ForgeMinecraftProvider; 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.MojangMappedMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.NamedMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.ProcessedNamedMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.SrgMinecraftProvider; @@ -48,6 +49,7 @@ public enum MinecraftJarConfiguration { IntermediaryMinecraftProvider.MergedImpl::new, NamedMinecraftProvider.MergedImpl::new, SrgMinecraftProvider.MergedImpl::new, + MojangMappedMinecraftProvider.MergedImpl::new, ProcessedNamedMinecraftProvider.MergedImpl::new, SingleJarDecompileConfiguration::new, List.of("client", "server") @@ -57,6 +59,7 @@ public enum MinecraftJarConfiguration { IntermediaryMinecraftProvider.SingleJarImpl::server, NamedMinecraftProvider.SingleJarImpl::server, SrgMinecraftProvider.SingleJarImpl::server, + MojangMappedMinecraftProvider.SingleJarImpl::server, ProcessedNamedMinecraftProvider.SingleJarImpl::server, SingleJarDecompileConfiguration::new, List.of("server") @@ -66,6 +69,7 @@ public enum MinecraftJarConfiguration { IntermediaryMinecraftProvider.SingleJarImpl::client, NamedMinecraftProvider.SingleJarImpl::client, SrgMinecraftProvider.SingleJarImpl::client, + MojangMappedMinecraftProvider.SingleJarImpl::client, ProcessedNamedMinecraftProvider.SingleJarImpl::client, SingleJarDecompileConfiguration::new, List.of("client") @@ -75,6 +79,7 @@ public enum MinecraftJarConfiguration { IntermediaryMinecraftProvider.SplitImpl::new, NamedMinecraftProvider.SplitImpl::new, SrgMinecraftProvider.SplitImpl::new, + MojangMappedMinecraftProvider.SplitImpl::new, ProcessedNamedMinecraftProvider.SplitImpl::new, SplitDecompileConfiguration::new, List.of("client", "server") @@ -84,6 +89,7 @@ public enum MinecraftJarConfiguration { private final BiFunction> intermediaryMinecraftProviderBiFunction; private final BiFunction> namedMinecraftProviderBiFunction; private final BiFunction> srgMinecraftProviderBiFunction; + private final BiFunction> mojangMappedMinecraftProviderBiFunction; private final BiFunction, MinecraftJarProcessorManager, ProcessedNamedMinecraftProvider> processedNamedMinecraftProviderBiFunction; private final BiFunction> decompileConfigurationBiFunction; private final List supportedEnvironments; @@ -94,6 +100,7 @@ public enum MinecraftJarConfiguration { BiFunction> intermediaryMinecraftProviderBiFunction, BiFunction namedMinecraftProviderBiFunction, BiFunction> srgMinecraftProviderBiFunction, + BiFunction> mojangMappedMinecraftProviderBiFunction, BiFunction> processedNamedMinecraftProviderBiFunction, BiFunction> decompileConfigurationBiFunction, List supportedEnvironments @@ -102,6 +109,7 @@ public enum MinecraftJarConfiguration { this.intermediaryMinecraftProviderBiFunction = (BiFunction>) (Object) intermediaryMinecraftProviderBiFunction; this.namedMinecraftProviderBiFunction = (BiFunction>) namedMinecraftProviderBiFunction; this.srgMinecraftProviderBiFunction = (BiFunction>) (Object) srgMinecraftProviderBiFunction; + this.mojangMappedMinecraftProviderBiFunction = (BiFunction>) (Object) mojangMappedMinecraftProviderBiFunction; this.processedNamedMinecraftProviderBiFunction = (BiFunction, MinecraftJarProcessorManager, ProcessedNamedMinecraftProvider>) (Object) processedNamedMinecraftProviderBiFunction; this.decompileConfigurationBiFunction = (BiFunction>) decompileConfigurationBiFunction; this.supportedEnvironments = supportedEnvironments; @@ -131,6 +139,10 @@ public enum MinecraftJarConfiguration { return srgMinecraftProviderBiFunction; } + public BiFunction> getMojangMappedMinecraftProviderBiFunction() { + return mojangMappedMinecraftProviderBiFunction; + } + public List getSupportedEnvironments() { return supportedEnvironments; } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftProvider.java index 681d65d4..d7b53451 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftProvider.java @@ -76,7 +76,7 @@ public abstract class MinecraftProvider { final DependencyInfo dependency = DependencyInfo.create(getProject(), Constants.Configurations.MINECRAFT); minecraftVersion = dependency.getDependency().getVersion(); - if (getExtension().shouldGenerateSrgTiny() && !getExtension().isForge()) { + if (getExtension().shouldGenerateSrgTiny() && !getExtension().isForgeLike()) { getProject().getDependencies().add(Constants.Configurations.SRG, "de.oceanlabs.mcp:mcp_config:" + minecraftVersion); } diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftSourceSets.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftSourceSets.java index 9ed5a50d..a975f30e 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftSourceSets.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/MinecraftSourceSets.java @@ -70,7 +70,7 @@ public abstract sealed class MinecraftSourceSets permits MinecraftSourceSets.Sin configuration.extendsFrom(configurations.getByName(Constants.Configurations.LOADER_DEPENDENCIES)); configuration.extendsFrom(configurations.getByName(Constants.Configurations.LOOM_DEVELOPMENT_DEPENDENCIES)); - if (LoomGradleExtension.get(project).isForge()) { + if (LoomGradleExtension.get(project).isForgeLike()) { configurations.getByName(Constants.Configurations.FORGE_RUNTIME_LIBRARY).extendsFrom(configuration); } }); diff --git a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java index 239de6c7..4e870a2d 100644 --- a/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java +++ b/src/main/java/net/fabricmc/loom/configuration/providers/minecraft/mapped/AbstractMappedMinecraftProvider.java @@ -194,7 +194,7 @@ public abstract class AbstractMappedMinecraftProvider classNames = extension.isForge() ? InnerClassRemapper.readClassNames(remappedJars.inputJar()) : Set.of(); + final Set classNames = extension.isForgeLike() ? InnerClassRemapper.readClassNames(remappedJars.inputJar()) : Set.of(); final Map remappedSignatures = SignatureFixerApplyVisitor.getRemappedSignatures(getTargetNamespace() == MappingsNamespace.INTERMEDIARY, mappingConfiguration, getProject(), configContext.serviceManager(), toM); TinyRemapper remapper = TinyRemapperHelper.getTinyRemapper(getProject(), configContext.serviceManager(), fromM, toM, true, (builder) -> { builder.extraPostApplyVisitor(new SignatureFixerApplyVisitor(remappedSignatures)); @@ -219,7 +219,7 @@ public abstract class AbstractMappedMinecraftProvider extends AbstractMappedMinecraftProvider permits MojangMappedMinecraftProvider.MergedImpl, MojangMappedMinecraftProvider.SingleJarImpl, MojangMappedMinecraftProvider.SplitImpl { + public MojangMappedMinecraftProvider(Project project, M minecraftProvider) { + super(project, minecraftProvider); + } + + @Override + public MavenScope getMavenScope() { + return MavenScope.GLOBAL; + } + + @Override + public final MappingsNamespace getTargetNamespace() { + return MappingsNamespace.MOJANG; + } + + public static final class MergedImpl extends MojangMappedMinecraftProvider implements Merged { + public MergedImpl(Project project, MergedMinecraftProvider minecraftProvider) { + super(project, minecraftProvider); + } + + @Override + public List getRemappedJars() { + return List.of( + new RemappedJars(minecraftProvider.getMergedJar(), getMergedJar(), MappingsNamespace.OFFICIAL) + ); + } + } + + public static final class SplitImpl extends MojangMappedMinecraftProvider implements Split { + public SplitImpl(Project project, SplitMinecraftProvider minecraftProvider) { + super(project, minecraftProvider); + } + + @Override + public List getRemappedJars() { + return List.of( + new RemappedJars(minecraftProvider.getMinecraftCommonJar(), getCommonJar(), MappingsNamespace.OFFICIAL), + new RemappedJars(minecraftProvider.getMinecraftClientOnlyJar(), getClientOnlyJar(), MappingsNamespace.OFFICIAL, minecraftProvider.getMinecraftCommonJar()) + ); + } + + @Override + protected void configureRemapper(RemappedJars remappedJars, TinyRemapper.Builder tinyRemapperBuilder) { + if (remappedJars.outputJar().equals(getClientOnlyJar())) { + tinyRemapperBuilder.extraPostApplyVisitor(SidedClassVisitor.CLIENT); + } + } + } + + public static final class SingleJarImpl extends MojangMappedMinecraftProvider implements SingleJar { + private final SingleJarEnvType env; + + private SingleJarImpl(Project project, SingleJarMinecraftProvider minecraftProvider, SingleJarEnvType env) { + super(project, minecraftProvider); + this.env = env; + } + + public static SingleJarImpl server(Project project, SingleJarMinecraftProvider minecraftProvider) { + return new SingleJarImpl(project, minecraftProvider, SingleJarEnvType.SERVER); + } + + public static SingleJarImpl client(Project project, SingleJarMinecraftProvider minecraftProvider) { + return new SingleJarImpl(project, minecraftProvider, SingleJarEnvType.CLIENT); + } + + @Override + public List getRemappedJars() { + return List.of( + new RemappedJars(minecraftProvider.getMinecraftEnvOnlyJar(), getEnvOnlyJar(), MappingsNamespace.OFFICIAL) + ); + } + + @Override + public SingleJarEnvType env() { + return env; + } + } +} diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java index bd8ca862..1ac418f1 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionApiImpl.java @@ -134,7 +134,7 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA .convention(true); this.transitiveAccessWideners.finalizeValueOnRead(); this.modProvidedJavadoc = project.getObjects().property(Boolean.class) - .convention(project.provider(() -> !isForge())); + .convention(project.provider(() -> !isForgeLike())); this.modProvidedJavadoc.finalizeValueOnRead(); this.intermediary = project.getObjects().property(String.class) .convention("https://maven.fabricmc.net/net/fabricmc/intermediary/%1$s/intermediary-%1$s-v2.jar"); @@ -446,6 +446,14 @@ public abstract class LoomGradleExtensionApiImpl implements LoomGradleExtensionA @Override public void setGenerateSrgTiny(Boolean generateSrgTiny) { + if (isNeoForge()) { + // This is unsupported because supporting the full 2x2 combination of + // [no extra NS] [SRG] + // [mojang] [SRG+mojang] + // is a bit verbose to support. + throw new UnsupportedOperationException("SRG is not supported on NeoForge."); + } + this.generateSrgTiny = generateSrgTiny; } diff --git a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java index d135f4b6..e8b639a7 100644 --- a/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java +++ b/src/main/java/net/fabricmc/loom/extension/LoomGradleExtensionImpl.java @@ -52,6 +52,7 @@ import net.fabricmc.loom.configuration.providers.mappings.MappingConfiguration; import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.library.LibraryProcessorManager; import net.fabricmc.loom.configuration.providers.minecraft.mapped.IntermediaryMinecraftProvider; +import net.fabricmc.loom.configuration.providers.minecraft.mapped.MojangMappedMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.NamedMinecraftProvider; import net.fabricmc.loom.configuration.providers.minecraft.mapped.SrgMinecraftProvider; import net.fabricmc.loom.util.Constants; @@ -75,6 +76,7 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen private NamedMinecraftProvider namedMinecraftProvider; private IntermediaryMinecraftProvider intermediaryMinecraftProvider; private SrgMinecraftProvider srgMinecraftProvider; + private MojangMappedMinecraftProvider mojangMappedMinecraftProvider; private InstallerData installerData; private boolean refreshDeps; private Provider multiProjectOptimisation; @@ -93,7 +95,7 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen this.mixinApExtension = project.getObjects().newInstance(MixinExtensionImpl.class, project); this.loomFiles = files; this.unmappedMods = project.files(); - this.forgeExtension = Suppliers.memoize(() -> isForge() ? project.getObjects().newInstance(ForgeExtensionImpl.class, project, this) : null); + this.forgeExtension = Suppliers.memoize(() -> isForgeLike() ? project.getObjects().newInstance(ForgeExtensionImpl.class, project, this) : null); // Setup the default intermediate mappings provider. setIntermediateMappingsProvider(IntermediaryMappingsProvider.class, provider -> { @@ -185,6 +187,16 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen this.srgMinecraftProvider = srgMinecraftProvider; } + @Override + public MojangMappedMinecraftProvider getMojangMappedMinecraftProvider() { + return Objects.requireNonNull(mojangMappedMinecraftProvider, "Cannot get MojangMappedMinecraftProvider before it has been setup"); + } + + @Override + public void setMojangMappedMinecraftProvider(MojangMappedMinecraftProvider mojangMappedMinecraftProvider) { + this.mojangMappedMinecraftProvider = mojangMappedMinecraftProvider; + } + @Override public FileCollection getMinecraftJarsCollection(MappingsNamespace mappingsNamespace) { return getProject().files( @@ -289,7 +301,7 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen @Override public ForgeExtensionAPI getForge() { - ModPlatform.assertPlatform(this, ModPlatform.FORGE); + ModPlatform.assertForgeLike(this); return forgeExtension.get(); } @@ -305,13 +317,13 @@ public class LoomGradleExtensionImpl extends LoomGradleExtensionApiImpl implemen @Override public ForgeRunsProvider getForgeRunsProvider() { - ModPlatform.assertPlatform(this, ModPlatform.FORGE); + ModPlatform.assertForgeLike(this); return forgeRunsProvider; } @Override public void setForgeRunsProvider(ForgeRunsProvider forgeRunsProvider) { - ModPlatform.assertPlatform(this, ModPlatform.FORGE); + ModPlatform.assertForgeLike(this); this.forgeRunsProvider = forgeRunsProvider; } } diff --git a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java index b40fa6b8..3b9e20b3 100644 --- a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java +++ b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java @@ -192,7 +192,7 @@ public abstract class GenerateSourcesTask extends AbstractLoomTask { } // Inject Forge's own sources - if (getExtension().isForge()) { + if (getExtension().isForgeLike()) { try (var serviceManager = new ScopedSharedServiceManager()) { ForgeSourcesRemapper.addForgeSources(getProject(), serviceManager, getOutputJar().get().getAsFile().toPath()); } @@ -296,7 +296,7 @@ public abstract class GenerateSourcesTask extends AbstractLoomTask { params.getClassPath().setFrom(getProject().getConfigurations().getByName(Constants.Configurations.MINECRAFT_COMPILE_LIBRARIES)); // Architectury - params.getForge().set(getExtension().isForge()); + params.getForge().set(getExtension().isForgeLike()); }); try { @@ -470,7 +470,7 @@ public abstract class GenerateSourcesTask extends AbstractLoomTask { } private Path getMappings() { - Path inputMappings = getExtension().isForge() ? getExtension().getMappingConfiguration().tinyMappingsWithSrg : getExtension().getMappingConfiguration().tinyMappings; + Path inputMappings = getExtension().getPlatformMappingFile(); MemoryMappingTree mappingTree = new MemoryMappingTree(); diff --git a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java index 0ace2d06..a94b1a04 100644 --- a/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java +++ b/src/main/java/net/fabricmc/loom/task/MigrateMappingsTask.java @@ -192,7 +192,7 @@ public abstract class MigrateMappingsTask extends AbstractLoomTask { mercury.getClassPath().add(intermediaryJar); } - if (extension.isForge()) { + if (extension.isForgeLike()) { for (Path srgJar : extension.getMinecraftJars(MappingsNamespace.SRG)) { mercury.getClassPath().add(srgJar); } diff --git a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java index 44259867..ac928a85 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapJarTask.java +++ b/src/main/java/net/fabricmc/loom/task/RemapJarTask.java @@ -141,13 +141,13 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { getClasspath().from(getProject().getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME)); getAddNestedDependencies().convention(true).finalizeValueOnRead(); - getReadMixinConfigsFromManifest().convention(LoomGradleExtension.get(getProject()).isForge()).finalizeValueOnRead(); + getReadMixinConfigsFromManifest().convention(LoomGradleExtension.get(getProject()).isForgeLike()).finalizeValueOnRead(); getInjectAccessWidener().convention(false); Configuration includeConfiguration = getProject().getConfigurations().getByName(Constants.Configurations.INCLUDE); IncludedJarFactory factory = new IncludedJarFactory(getProject()); - if (!LoomGradleExtension.get(getProject()).isForge()) { + if (!LoomGradleExtension.get(getProject()).isForgeLike()) { getNestedJars().from(factory.getNestedJars(includeConfiguration)); } else { Provider, TaskDependency>> forgeNestedJars = factory.getForgeNestedJars(includeConfiguration); @@ -196,7 +196,7 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { if (getAddNestedDependencies().get()) { params.getNestedJars().from(getNestedJars()); - if (extension.isForge()) { + if (extension.isForgeLike()) { params.getForgeNestedJars().set(getForgeNestedJars()); } } @@ -210,7 +210,7 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { if (mixinAp) { setupLegacyMixinRefmapRemapping(params); - } else if (extension.isForge()) { + } else if (extension.isForgeLike()) { throw new RuntimeException("Forge must have useLegacyMixinAp enabled"); } @@ -326,7 +326,7 @@ public abstract class RemapJarTask extends AbstractRemapJarTask { addNestedJars(); ModBuildExtensions.convertAwToAt(getParameters().getAtAccessWideners(), outputFile, getParameters().getMappingBuildServiceUuid()); - if (getParameters().getPlatform().get() != ModPlatform.FORGE) { + if (!getParameters().getPlatform().get().isForgeLike()) { modifyJarManifest(); } diff --git a/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java b/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java index 66b86d96..e942876a 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java +++ b/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java @@ -104,7 +104,7 @@ public abstract class RemapTaskConfiguration implements Runnable { trySetupSourceRemapping(); getProject().afterEvaluate(p -> { - if (extension.isForge()) { + if (extension.isForgeLike()) { if (PropertyUtil.getAndFinalize(extension.getForge().getConvertAccessWideners())) { Aw2At.setup(getProject(), remapJarTask); } diff --git a/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java b/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java index 34184942..a561b991 100644 --- a/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java +++ b/src/main/java/net/fabricmc/loom/task/launch/GenerateDLIConfigTask.java @@ -75,7 +75,7 @@ public abstract class GenerateDLIConfigTask extends AbstractLoomTask { .property("client", "org.lwjgl.librarypath", nativesPath); } - if (!getExtension().isForge()) { + if (!getExtension().isForgeLike()) { launchConfig .argument("client", "--assetIndex") .argument("client", getExtension().getMinecraftProvider().getVersionInfo().assetIndex().fabricId(getExtension().getMinecraftProvider().minecraftVersion())) @@ -98,7 +98,7 @@ public abstract class GenerateDLIConfigTask extends AbstractLoomTask { .argument("client", "Architectury Loom"); } - if (getExtension().isForge()) { + if (getExtension().isForgeLike()) { // Find the mapping files for Unprotect to use for figuring out // which classes are from Minecraft. String unprotectMappings = getProject().getConfigurations() @@ -110,7 +110,8 @@ public abstract class GenerateDLIConfigTask extends AbstractLoomTask { launchConfig // Should match YarnNamingService.PATH_TO_MAPPINGS in forge-runtime - .property("fabric.yarnWithSrg.path", getExtension().getMappingConfiguration().tinyMappingsWithSrg.toAbsolutePath().toString()) + // TODO (Neo): Can we rename this property for Neo? It's not at all accurate. + .property("fabric.yarnWithSrg.path", getExtension().getPlatformMappingFile().toAbsolutePath().toString()) .property("unprotect.mappings", unprotectMappings) .property("mixin.env.remapRefMap", "true"); diff --git a/src/main/java/net/fabricmc/loom/task/launch/GenerateLog4jConfigTask.java b/src/main/java/net/fabricmc/loom/task/launch/GenerateLog4jConfigTask.java index 6163eade..127a6064 100644 --- a/src/main/java/net/fabricmc/loom/task/launch/GenerateLog4jConfigTask.java +++ b/src/main/java/net/fabricmc/loom/task/launch/GenerateLog4jConfigTask.java @@ -39,7 +39,7 @@ public abstract class GenerateLog4jConfigTask extends AbstractLoomTask { public void run() { Path outputFile = getExtension().getFiles().getDefaultLog4jConfigFile().toPath(); - if (getExtension().isForge() && getExtension().getForge().getUseForgeLoggerConfig().get()) { + if (getExtension().isForgeLike() && getExtension().getForge().getUseForgeLoggerConfig().get()) { ForgeLoggerConfig.copyToPath(getProject(), outputFile); return; } diff --git a/src/main/java/net/fabricmc/loom/task/service/JarManifestService.java b/src/main/java/net/fabricmc/loom/task/service/JarManifestService.java index ab6ad013..01eff08c 100644 --- a/src/main/java/net/fabricmc/loom/task/service/JarManifestService.java +++ b/src/main/java/net/fabricmc/loom/task/service/JarManifestService.java @@ -108,7 +108,7 @@ public abstract class JarManifestService implements BuildService getMixinVersion(Project project) { return project.getConfigurations().named(Constants.Configurations.LOADER_DEPENDENCIES).map(configuration -> { - if (LoomGradleExtension.get(project).isForge()) return new MixinVersion("unknown", "unknown"); + if (LoomGradleExtension.get(project).isForgeLike()) return new MixinVersion("unknown", "unknown"); // Not super ideal that this uses the mod compile classpath, should prob look into making this not a thing at somepoint Optional dependency = configuration diff --git a/src/main/java/net/fabricmc/loom/task/service/MappingsService.java b/src/main/java/net/fabricmc/loom/task/service/MappingsService.java index fccd798b..7f8e6123 100644 --- a/src/main/java/net/fabricmc/loom/task/service/MappingsService.java +++ b/src/main/java/net/fabricmc/loom/task/service/MappingsService.java @@ -52,7 +52,7 @@ public final class MappingsService implements SharedService { final MappingConfiguration mappingConfiguration = LoomGradleExtension.get(project).getMappingConfiguration(); final String name = mappingConfiguration.getBuildServiceName("mappingsProvider", from, to); - return MappingsService.create(serviceManager, name, (from.equals("srg") || to.equals("srg")) && LoomGradleExtension.get(project).shouldGenerateSrgTiny() ? mappingConfiguration.tinyMappingsWithSrg : mappingConfiguration.tinyMappings, from, to, false); + return MappingsService.create(serviceManager, name, LoomGradleExtension.get(project).getPlatformMappingFile(), from, to, false); } private final Options options; diff --git a/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java b/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java index a6a533d3..ee6f8602 100644 --- a/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java +++ b/src/main/java/net/fabricmc/loom/task/service/TinyRemapperService.java @@ -81,7 +81,7 @@ public class TinyRemapperService implements SharedService { extension.getKnownIndyBsms().get().stream().sorted().forEach(joiner::add); - if (extension.isForge()) { + if (extension.isForgeLike()) { joiner.add("forge"); } diff --git a/src/main/java/net/fabricmc/loom/util/ModPlatform.java b/src/main/java/net/fabricmc/loom/util/ModPlatform.java index 2b1a196a..c1e69ef8 100644 --- a/src/main/java/net/fabricmc/loom/util/ModPlatform.java +++ b/src/main/java/net/fabricmc/loom/util/ModPlatform.java @@ -1,7 +1,7 @@ /* * This file is part of fabric-loom, licensed under the MIT License (MIT). * - * Copyright (c) 2021-2022 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 @@ -36,7 +36,8 @@ import net.fabricmc.loom.api.LoomGradleExtensionAPI; public enum ModPlatform { FABRIC(false), FORGE(false), - QUILT(true); + QUILT(true), + NEOFORGE(true); boolean experimental; @@ -48,6 +49,10 @@ public enum ModPlatform { return experimental; } + public boolean isForgeLike() { + return this == FORGE || this == NEOFORGE; + } + public static void assertPlatform(Project project, ModPlatform platform) { assertPlatform(LoomGradleExtension.get(project), platform); } @@ -65,4 +70,14 @@ public enum ModPlatform { throw new GradleException(message.get()); } } + + public static void assertForgeLike(LoomGradleExtensionAPI extension) { + assertForgeLike(extension, () -> "Loom is not running on a Forge-like platform (Forge or NeoForge)."); + } + + public static void assertForgeLike(LoomGradleExtensionAPI extension, Supplier message) { + if (!extension.getPlatform().get().isForgeLike()) { + throw new GradleException(message.get()); + } + } } diff --git a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java index 39944c33..001516da 100644 --- a/src/main/java/net/fabricmc/loom/util/SourceRemapper.java +++ b/src/main/java/net/fabricmc/loom/util/SourceRemapper.java @@ -199,7 +199,7 @@ public class SourceRemapper { mercury.getClassPath().add(intermediaryJar); } - if (extension.isForge()) { + if (extension.isForgeLike()) { for (Path srgJar : extension.getMinecraftJars(MappingsNamespace.SRG)) { mercury.getClassPath().add(srgJar); } diff --git a/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java b/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java index cca3e8c0..986169fe 100644 --- a/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java +++ b/src/main/java/net/fabricmc/loom/util/TinyRemapperHelper.java @@ -70,7 +70,7 @@ public final class TinyRemapperHelper { public static TinyRemapper getTinyRemapper(Project project, SharedServiceManager serviceManager, String fromM, String toM, boolean fixRecords, Consumer builderConsumer, Set fromClassNames) throws IOException { LoomGradleExtension extension = LoomGradleExtension.get(project); - boolean srg = (fromM.equals(MappingsNamespace.SRG.toString()) || toM.equals(MappingsNamespace.SRG.toString())) && extension.isForge(); + boolean srg = (fromM.equals(MappingsNamespace.SRG.toString()) || toM.equals(MappingsNamespace.SRG.toString())) && extension.isForgeLike(); MemoryMappingTree mappingTree = extension.getMappingConfiguration().getMappingsService(serviceManager, srg).getMappingTree(); if (fixRecords && !mappingTree.getSrcNamespace().equals(fromM)) { @@ -81,7 +81,7 @@ public final class TinyRemapperHelper { TinyRemapper.Builder builder = TinyRemapper.newRemapper() .logUnknownInvokeDynamic(false) - .ignoreConflicts(extension.isForge()) + .ignoreConflicts(extension.isForgeLike()) .cacheMappings(true) .threads(Runtime.getRuntime().availableProcessors()) .logger(project.getLogger()::lifecycle) @@ -99,7 +99,7 @@ public final class TinyRemapperHelper { return next; }); - if (extension.isForge()) { + if (extension.isForgeLike()) { if (!fromClassNames.isEmpty()) { builder.withMappings(InnerClassRemapper.of(fromClassNames, mappingTree, fromM, toM)); } diff --git a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java index d5b806de..bf101370 100644 --- a/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java +++ b/src/main/java/net/fabricmc/loom/util/fmj/FabricModJsonFactory.java @@ -166,7 +166,7 @@ public final class FabricModJsonFactory { } public static boolean isModJar(Path input, ModPlatform platform) { - if (platform == ModPlatform.FORGE) { + if (platform.isForgeLike()) { return ZipUtils.contains(input, "META-INF/mods.toml"); } else if (platform == ModPlatform.QUILT) { return ZipUtils.contains(input, "quilt.mod.json") || isModJar(input, ModPlatform.FABRIC); @@ -180,8 +180,8 @@ public final class FabricModJsonFactory { } public static boolean isNestableModJar(Path input, ModPlatform platform) { - // Forge don't care if the main jar is mod jar. - if (platform == ModPlatform.FORGE) return true; + // Forge and NeoForge don't care if the main jar is mod jar. + if (platform.isForgeLike()) return true; return isModJar(input, platform); } @@ -190,7 +190,7 @@ public final class FabricModJsonFactory { return true; } - if (platform == ModPlatform.FORGE) { + if (platform.isForgeLike()) { return Files.exists(fs.getPath("META-INF/mods.toml")); } else if (platform == ModPlatform.QUILT) { return Files.exists(fs.getPath("quilt.mod.json")) || containsMod(fs, ModPlatform.FABRIC);