Initial plumbing for NeoForge support

This commit is contained in:
Juuz
2023-10-30 22:31:12 +02:00
parent 31147018be
commit 8a1d09e69f
39 changed files with 405 additions and 82 deletions

View File

@@ -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<String, String> 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<MappingVisitor> visitorWrapper) implements MappingLayer {
@Override
public void visit(MappingVisitor mappingVisitor) throws IOException {
layer.visit(visitorWrapper.apply(mappingVisitor));
}
@Override
public MappingsNamespace getSourceNamespace() {
return layer.getSourceNamespace();
}
}
}

View File

@@ -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<Path> 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);
}
}

View File

@@ -235,10 +235,18 @@ public interface LoomGradleExtensionAPI {
Provider<ModPlatform> 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();

View File

@@ -54,6 +54,14 @@ public enum MappingsNamespace {
*/
SRG,
/**
* Mojang's official names from their deobfuscation maps.
*
* <p>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;
};

View File

@@ -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();
};
}
/**

View File

@@ -64,7 +64,7 @@ public class JarNester {
}
}).collect(Collectors.toList()));
if (platform == ModPlatform.FORGE) {
if (platform.isForgeLike()) {
handleForgeJarJar(forgeJars, modJar, logger);
return;
}

View File

@@ -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));

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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);

View File

@@ -75,7 +75,7 @@ public class SingleJarDecompileConfiguration extends DecompileConfiguration<Mapp
});
// TODO: Support for env-only jars?
if (extension.isForge() && extension.getMinecraftJarConfiguration().get() == MinecraftJarConfiguration.MERGED) {
if (extension.isForgeLike() && extension.getMinecraftJarConfiguration().get() == MinecraftJarConfiguration.MERGED) {
project.getTasks().register("genForgePatchedSources", GenerateForgePatchedSourcesTask.class, task -> {
task.setDescription("Decompile Minecraft using Forge's toolchain.");
task.setGroup(Constants.TaskGroup.FABRIC);

View File

@@ -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 {
* <p>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.
*
* <p>This method is currently only available on Forge.
* <p>This method is currently only available on Forge and NeoForge.
*/
@ApiStatus.Experimental
public NamedDomainObjectContainer<ModSettings> getMods() {
ModPlatform.assertPlatform(project, ModPlatform.FORGE);
ModPlatform.assertForgeLike(extension);
return mods;
}

View File

@@ -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;
}

View File

@@ -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());
}

View File

@@ -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();
}
}

View File

@@ -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<Map.Entry<FieldMember, String>> 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);

View File

@@ -436,7 +436,7 @@ public class MinecraftPatchedProvider {
copyMissingClasses(minecraftSrgJar, minecraftPatchedSrgJar);
deleteParameterNames(minecraftPatchedSrgJar);
if (getExtension().isForgeAndNotOfficial()) {
if (getExtension().isForgeLikeAndNotOfficial()) {
fixParameterAnnotation(minecraftPatchedSrgJar);
}

View File

@@ -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);
}
}

View File

@@ -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<String, Path> 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<String> lines = new ArrayList<>(Files.readAllLines(loom.shouldGenerateSrgTiny() ? tinyMappingsWithSrg : tinyMappings));
List<String> 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) {
}
}

View File

@@ -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<Project, MinecraftProvider, IntermediaryMinecraftProvider<?>> intermediaryMinecraftProviderBiFunction;
private final BiFunction<Project, MinecraftProvider, NamedMinecraftProvider<?>> namedMinecraftProviderBiFunction;
private final BiFunction<Project, MinecraftProvider, SrgMinecraftProvider<?>> srgMinecraftProviderBiFunction;
private final BiFunction<Project, MinecraftProvider, MojangMappedMinecraftProvider<?>> mojangMappedMinecraftProviderBiFunction;
private final BiFunction<NamedMinecraftProvider<?>, MinecraftJarProcessorManager, ProcessedNamedMinecraftProvider<?, ?>> processedNamedMinecraftProviderBiFunction;
private final BiFunction<ConfigContext, MappedMinecraftProvider, DecompileConfiguration<?>> decompileConfigurationBiFunction;
private final List<String> supportedEnvironments;
@@ -94,6 +100,7 @@ public enum MinecraftJarConfiguration {
BiFunction<Project, M, IntermediaryMinecraftProvider<M>> intermediaryMinecraftProviderBiFunction,
BiFunction<Project, M, P> namedMinecraftProviderBiFunction,
BiFunction<Project, M, SrgMinecraftProvider<M>> srgMinecraftProviderBiFunction,
BiFunction<Project, M, MojangMappedMinecraftProvider<M>> mojangMappedMinecraftProviderBiFunction,
BiFunction<P, MinecraftJarProcessorManager, ProcessedNamedMinecraftProvider<M, P>> processedNamedMinecraftProviderBiFunction,
BiFunction<ConfigContext, Q, DecompileConfiguration<?>> decompileConfigurationBiFunction,
List<String> supportedEnvironments
@@ -102,6 +109,7 @@ public enum MinecraftJarConfiguration {
this.intermediaryMinecraftProviderBiFunction = (BiFunction<Project, MinecraftProvider, IntermediaryMinecraftProvider<?>>) (Object) intermediaryMinecraftProviderBiFunction;
this.namedMinecraftProviderBiFunction = (BiFunction<Project, MinecraftProvider, NamedMinecraftProvider<?>>) namedMinecraftProviderBiFunction;
this.srgMinecraftProviderBiFunction = (BiFunction<Project, MinecraftProvider, SrgMinecraftProvider<?>>) (Object) srgMinecraftProviderBiFunction;
this.mojangMappedMinecraftProviderBiFunction = (BiFunction<Project, MinecraftProvider, MojangMappedMinecraftProvider<?>>) (Object) mojangMappedMinecraftProviderBiFunction;
this.processedNamedMinecraftProviderBiFunction = (BiFunction<NamedMinecraftProvider<?>, MinecraftJarProcessorManager, ProcessedNamedMinecraftProvider<?, ?>>) (Object) processedNamedMinecraftProviderBiFunction;
this.decompileConfigurationBiFunction = (BiFunction<ConfigContext, MappedMinecraftProvider, DecompileConfiguration<?>>) decompileConfigurationBiFunction;
this.supportedEnvironments = supportedEnvironments;
@@ -131,6 +139,10 @@ public enum MinecraftJarConfiguration {
return srgMinecraftProviderBiFunction;
}
public BiFunction<Project, MinecraftProvider, MojangMappedMinecraftProvider<?>> getMojangMappedMinecraftProviderBiFunction() {
return mojangMappedMinecraftProviderBiFunction;
}
public List<String> getSupportedEnvironments() {
return supportedEnvironments;
}

View File

@@ -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);
}

View File

@@ -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);
}
});

View File

@@ -194,7 +194,7 @@ public abstract class AbstractMappedMinecraftProvider<M extends MinecraftProvide
Files.deleteIfExists(remappedJars.outputJarPath());
final Set<String> classNames = extension.isForge() ? InnerClassRemapper.readClassNames(remappedJars.inputJar()) : Set.of();
final Set<String> classNames = extension.isForgeLike() ? InnerClassRemapper.readClassNames(remappedJars.inputJar()) : Set.of();
final Map<String, String> 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<M extends MinecraftProvide
getMavenHelper(remappedJars.name()).savePom();
if (extension.isForgeAndOfficial()) {
if (extension.isForgeLikeAndOfficial()) {
try (var serviceManager = new ScopedSharedServiceManager()) {
TinyMappingsService mappingsService = extension.getMappingConfiguration().getMappingsService(serviceManager, true);
MemoryMappingTree mappingsWithSrg = mappingsService.getMappingTree();

View File

@@ -0,0 +1,118 @@
/*
* This file is part of fabric-loom, licensed under the MIT License (MIT).
*
* Copyright (c) 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
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.fabricmc.loom.configuration.providers.minecraft.mapped;
import dev.architectury.tinyremapper.TinyRemapper;
import net.fabricmc.loom.api.mappings.layered.MappingsNamespace;
import net.fabricmc.loom.configuration.providers.minecraft.MergedMinecraftProvider;
import net.fabricmc.loom.configuration.providers.minecraft.MinecraftProvider;
import net.fabricmc.loom.configuration.providers.minecraft.SingleJarEnvType;
import net.fabricmc.loom.configuration.providers.minecraft.SingleJarMinecraftProvider;
import net.fabricmc.loom.configuration.providers.minecraft.SplitMinecraftProvider;
import net.fabricmc.loom.util.SidedClassVisitor;
import org.gradle.api.Project;
import java.util.List;
public abstract sealed class MojangMappedMinecraftProvider<M extends MinecraftProvider> extends AbstractMappedMinecraftProvider<M> 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<MergedMinecraftProvider> implements Merged {
public MergedImpl(Project project, MergedMinecraftProvider minecraftProvider) {
super(project, minecraftProvider);
}
@Override
public List<RemappedJars> getRemappedJars() {
return List.of(
new RemappedJars(minecraftProvider.getMergedJar(), getMergedJar(), MappingsNamespace.OFFICIAL)
);
}
}
public static final class SplitImpl extends MojangMappedMinecraftProvider<SplitMinecraftProvider> implements Split {
public SplitImpl(Project project, SplitMinecraftProvider minecraftProvider) {
super(project, minecraftProvider);
}
@Override
public List<RemappedJars> 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<SingleJarMinecraftProvider> 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<RemappedJars> getRemappedJars() {
return List.of(
new RemappedJars(minecraftProvider.getMinecraftEnvOnlyJar(), getEnvOnlyJar(), MappingsNamespace.OFFICIAL)
);
}
@Override
public SingleJarEnvType env() {
return env;
}
}
}

View File

@@ -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;
}

View File

@@ -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<Boolean> 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;
}
}

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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<Pair<List<LazyNestedFile>, 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();
}

View File

@@ -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);
}

View File

@@ -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");

View File

@@ -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;
}

View File

@@ -108,7 +108,7 @@ public abstract class JarManifestService implements BuildService<JarManifestServ
private static Provider<MixinVersion> 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> dependency = configuration

View File

@@ -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;

View File

@@ -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");
}

View File

@@ -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<String> message) {
if (!extension.getPlatform().get().isForgeLike()) {
throw new GradleException(message.get());
}
}
}

View File

@@ -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);
}

View File

@@ -70,7 +70,7 @@ public final class TinyRemapperHelper {
public static TinyRemapper getTinyRemapper(Project project, SharedServiceManager serviceManager, String fromM, String toM, boolean fixRecords, Consumer<TinyRemapper.Builder> builderConsumer, Set<String> 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));
}

View File

@@ -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);