Skip to content

Commit

Permalink
Initial plumbing for NeoForge support
Browse files Browse the repository at this point in the history
  • Loading branch information
Juuxel committed Oct 30, 2023
1 parent 3114701 commit 8a1d09e
Show file tree
Hide file tree
Showing 39 changed files with 405 additions and 82 deletions.
Original file line number Diff line number Diff line change
@@ -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();
}
}
}
29 changes: 25 additions & 4 deletions src/main/java/net/fabricmc/loom/LoomGradleExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
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;
Expand Down Expand Up @@ -95,6 +97,10 @@ static LoomGradleExtension get(Project project) {

void setSrgMinecraftProvider(SrgMinecraftProvider<?> srgMinecraftProvider);

MojangMappedMinecraftProvider<?> getMojangMappedMinecraftProvider();

void setMojangMappedMinecraftProvider(MojangMappedMinecraftProvider<?> srgMinecraftProvider);

default List<Path> getMinecraftJars(MappingsNamespace mappingsNamespace) {
return switch (mappingsNamespace) {
case NAMED -> getNamedMinecraftProvider().getMinecraftJarPaths();
Expand All @@ -104,6 +110,10 @@ default List<Path> getMinecraftJars(MappingsNamespace mappingsNamespace) {
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();
}
};
}

Expand Down Expand Up @@ -149,12 +159,13 @@ default boolean isDataGenEnabled() {
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();
Expand All @@ -179,4 +190,14 @@ default ForgeProvider getForgeProvider() {

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);
}
}
10 changes: 9 additions & 1 deletion src/main/java/net/fabricmc/loom/api/LoomGradleExtensionAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,18 @@ default void splitMinecraftJar() {

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;
}
Expand All @@ -260,7 +268,7 @@ default void addTaskBeforeRun(String task) {
*
* @return the Forge extension
* @throws UnsupportedOperationException if running on another platform
* @see #isForge()
* @see #isForgeLike()
*/
ForgeExtensionAPI getForge();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -70,6 +78,7 @@ public enum MappingsNamespace {
case "official" -> OFFICIAL;
case "intermediary" -> INTERMEDIARY;
case "srg" -> SRG;
case "mojang" -> MOJANG;
case "named" -> NAMED;
default -> null;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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();
};
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public static void nestJars(Collection<File> jars, List<NestedFile> forgeJars, F
}
}).collect(Collectors.toList()));

if (platform == ModPlatform.FORGE) {
if (platform.isForgeLike()) {
handleForgeJarJar(forgeJars, modJar, logger);
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@

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;
Expand Down Expand Up @@ -132,7 +134,7 @@ public void run() {

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"));
Expand Down Expand Up @@ -165,7 +167,7 @@ public void run() {
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);
Expand All @@ -188,7 +190,7 @@ private synchronized void setupMinecraft(ConfigContext configContext) throws Exc
// 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!");
}

Expand All @@ -203,15 +205,15 @@ private synchronized void setupMinecraft(ConfigContext configContext) throws Exc
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();
}

mappingConfiguration.setupPost(project);
mappingConfiguration.applyToProject(getProject(), mappingsDep);

if (extension.isForge()) {
if (extension.isForgeLike()) {
extension.setForgeRunsProvider(ForgeRunsProvider.create(project));
}

Expand Down Expand Up @@ -243,6 +245,10 @@ private synchronized void setupMinecraft(ConfigContext configContext) throws Exc
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);
}
}

Expand All @@ -262,7 +268,7 @@ private void registerGameProcessors(ConfigContext configContext) {
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());
}
}
Expand Down Expand Up @@ -356,7 +362,9 @@ public static void setupDependencyProviders(Project project, LoomGradleExtension
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));
}
Expand All @@ -365,7 +373,7 @@ public static void setupDependencyProviders(Project project, LoomGradleExtension
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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public void run() {
}
});

if (extension.isForge()) {
if (extension.isForgeLike()) {
// Set up Forge configurations
registerNonTransitive(Constants.Configurations.FORGE, Role.RESOLVABLE);
registerNonTransitive(Constants.Configurations.FORGE_USERDEV, Role.RESOLVABLE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ public void handleDependencies(Project project, SharedServiceManager serviceMana
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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ private void processEntry(String scope, Configuration config, PublishingExtensio

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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public final void afterEvaluation() {
});

// 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);
Expand Down
Loading

0 comments on commit 8a1d09e

Please sign in to comment.