mirror of
https://github.com/architectury/architectury-loom.git
synced 2026-03-28 04:07:01 -05:00
Implement non-deobf for NeoForge 26.1 (albeit ugly, will fix), add integration test for NF 26.1-snapshot-11
This commit is contained in:
@@ -23,7 +23,7 @@ access-transformers = "3.0.1"
|
||||
access-transformers-new = "8.0.5"
|
||||
access-transformers-neo = "10.0.2"
|
||||
unprotect = "2.0.2"
|
||||
asm = "9.7"
|
||||
asm = "9.9.1"
|
||||
access-transformers-log4j = "2.17.1"
|
||||
forge-installer-tools = "1.2.0"
|
||||
neoforge-installer-tools = "4.0.6"
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFiles;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
@@ -55,6 +56,7 @@ public final class ForgeSourcesService extends Service<ForgeSourcesService.Optio
|
||||
@InputFiles
|
||||
ConfigurableFileCollection getForgeSourceJars();
|
||||
|
||||
@Optional
|
||||
@Nested
|
||||
Property<SourceRemapperService.Options> getSourceRemapperService();
|
||||
|
||||
@@ -74,25 +76,27 @@ public final class ForgeSourcesService extends Service<ForgeSourcesService.Optio
|
||||
final String sourceDependency = extension.getForgeUserdevProvider().getConfig().sources();
|
||||
options.getForgeSourceJars().from(DependencyDownloader.download(project, sourceDependency));
|
||||
|
||||
options.getSourceRemapperService().set(SourceRemapperService.TYPE.create(project, sro -> {
|
||||
final MappingsNamespace sourceNamespace = IntermediaryNamespaces.intermediaryNamespace(project);
|
||||
final String targetNamespace = MappingsNamespace.NAMED.toString();
|
||||
if (!extension.isUnobfuscatedForge()) {
|
||||
options.getSourceRemapperService().set(SourceRemapperService.TYPE.create(project, sro -> {
|
||||
final MappingsNamespace sourceNamespace = IntermediaryNamespaces.intermediaryNamespace(project);
|
||||
final String targetNamespace = MappingsNamespace.NAMED.toString();
|
||||
|
||||
sro.getMappings().set(MappingsService.createOptionsWithProjectMappings(
|
||||
project,
|
||||
project.provider(sourceNamespace::toString),
|
||||
project.provider(() -> targetNamespace)
|
||||
));
|
||||
sro.getJavaCompileRelease().set(SourceRemapperService.getJavaCompileRelease(project));
|
||||
sro.getClasspath().from(DependencyDownloader.download(project, LoomVersions.JETBRAINS_ANNOTATIONS.mavenNotation()));
|
||||
sro.getClasspath().from(extension.getMinecraftJars(sourceNamespace));
|
||||
sro.getClasspath().from(project.getConfigurations().getByName(Constants.Configurations.MINECRAFT_COMPILE_LIBRARIES));
|
||||
sro.getMappings().set(MappingsService.createOptionsWithProjectMappings(
|
||||
project,
|
||||
project.provider(sourceNamespace::toString),
|
||||
project.provider(() -> targetNamespace)
|
||||
));
|
||||
sro.getJavaCompileRelease().set(SourceRemapperService.getJavaCompileRelease(project));
|
||||
sro.getClasspath().from(DependencyDownloader.download(project, LoomVersions.JETBRAINS_ANNOTATIONS.mavenNotation()));
|
||||
sro.getClasspath().from(extension.getMinecraftJars(sourceNamespace));
|
||||
sro.getClasspath().from(project.getConfigurations().getByName(Constants.Configurations.MINECRAFT_COMPILE_LIBRARIES));
|
||||
|
||||
TinyRemapperHelper.JSR_TO_JETBRAINS.forEach((from, to) -> {
|
||||
Pair<String, String> mapping = new Pair<>(from, to);
|
||||
sro.getAdditionalClassMappings().add(mapping);
|
||||
});
|
||||
}));
|
||||
TinyRemapperHelper.JSR_TO_JETBRAINS.forEach((from, to) -> {
|
||||
Pair<String, String> mapping = new Pair<>(from, to);
|
||||
sro.getAdditionalClassMappings().add(mapping);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
options.getShouldShowVerboseStderr().set(ForgeToolExecutor.shouldShowVerboseStderr(project));
|
||||
|
||||
@@ -174,8 +178,10 @@ public final class ForgeSourcesService extends Service<ForgeSourcesService.Optio
|
||||
forgeSources.keySet().removeIf(classFilter.negate());
|
||||
LOGGER.lifecycle(":extracted {} forge source classes", forgeSources.size());
|
||||
|
||||
try (var tempFiles = new TempFiles()) {
|
||||
remapSources(tempFiles, forgeSources);
|
||||
if (getOptions().getSourceRemapperService().isPresent()) {
|
||||
try (var tempFiles = new TempFiles()) {
|
||||
remapSources(tempFiles, forgeSources);
|
||||
}
|
||||
}
|
||||
|
||||
forgeSources.forEach(consumer);
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.gradle.api.artifacts.ModuleDependency;
|
||||
import org.gradle.api.artifacts.ModuleVersionIdentifier;
|
||||
import org.gradle.api.artifacts.ResolvedArtifact;
|
||||
import org.gradle.api.artifacts.ResolvedConfiguration;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.loom.LoomGradleExtension;
|
||||
import net.fabricmc.loom.api.mappings.layered.MappingContext;
|
||||
@@ -82,7 +83,7 @@ public class ForgeLibrariesProvider {
|
||||
private static final String NEOFORGE_GAME_LOCATOR_FILE = "net/neoforged/fml/loading/moddiscovery/locators/GameLocator.class";
|
||||
private static final String NEOFORGE_REQUIRED_SYSTEM_FILES_FILE = "net/neoforged/fml/loading/moddiscovery/locators/RequiredSystemFiles.class";
|
||||
|
||||
public static void provide(MappingConfiguration mappingConfiguration, Project project) throws Exception {
|
||||
public static void provide(@Nullable MappingConfiguration mappingConfiguration, Project project) throws Exception {
|
||||
LoomGradleExtension extension = LoomGradleExtension.get(project);
|
||||
final List<Dependency> dependencies = new ArrayList<>();
|
||||
|
||||
@@ -145,7 +146,7 @@ public class ForgeLibrariesProvider {
|
||||
isFancyModLoader10OrNewer = true;
|
||||
}
|
||||
|
||||
if (isFML || isFancyML) {
|
||||
if ((isFML || isFancyML) && mappingConfiguration != null) {
|
||||
// If FML, remap it.
|
||||
try (var serviceFactory = new ScopedServiceFactory()) {
|
||||
if (isFML) {
|
||||
|
||||
@@ -157,7 +157,9 @@ public class MinecraftPatchedProvider {
|
||||
|
||||
minecraftProvider.setJarPrefix(patchId);
|
||||
|
||||
final String intermediateId = getExtension().isNeoForge() ? "mojang" : "srg";
|
||||
final String intermediateId = getExtension().isNeoForge()
|
||||
? (getExtension().isUnobfuscatedForge() ? "official" : "mojang")
|
||||
: "srg";
|
||||
minecraftIntermediateJar = forgeWorkingDir.resolve("minecraft-" + type.id + "-" + intermediateId + ".jar");
|
||||
minecraftPatchedIntermediateJar = forgeWorkingDir.resolve("minecraft-" + type.id + "-" + intermediateId + "-patched.jar");
|
||||
minecraftPatchedIntermediateAtJar = forgeWorkingDir.resolve("minecraft-" + type.id + "-" + intermediateId + "-at-patched.jar");
|
||||
@@ -231,14 +233,40 @@ public class MinecraftPatchedProvider {
|
||||
|
||||
public void remapJar(ServiceFactory serviceFactory) throws Exception {
|
||||
if (dirty) {
|
||||
remapPatchedJar(serviceFactory);
|
||||
if (getExtension().isUnobfuscatedForge()) {
|
||||
mergeUnobfuscatedPatchedJar();
|
||||
} else {
|
||||
remapPatchedJar(serviceFactory);
|
||||
}
|
||||
|
||||
fillClientExtraJar(serviceFactory);
|
||||
}
|
||||
|
||||
if (getExtension().isUnobfuscatedForge()) {
|
||||
DependencyProvider.addDependency(project, getForgeJar(), Constants.Configurations.FORGE_EXTRA);
|
||||
}
|
||||
|
||||
DependencyProvider.addDependency(project, minecraftClientExtra, Constants.Configurations.FORGE_EXTRA);
|
||||
}
|
||||
|
||||
private void mergeUnobfuscatedPatchedJar() throws IOException {
|
||||
logger.lifecycle(":merging userdev into minecraft");
|
||||
Path mcOutput = minecraftPatchedJar;
|
||||
Path forgeUserdevJar = getForgeUserdevJar().toPath();
|
||||
|
||||
Files.deleteIfExists(mcOutput);
|
||||
Files.copy(minecraftPatchedIntermediateAtJar, mcOutput);
|
||||
|
||||
copyUserdevFiles(forgeUserdevJar, mcOutput);
|
||||
applyLoomPatchVersion(mcOutput);
|
||||
}
|
||||
|
||||
private void createPrePatchJar() throws IOException {
|
||||
if (getExtension().isUnobfuscatedForge()) {
|
||||
createUnobfuscatedPrePatchJar();
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldUseNeoForgeInstallerToolsToCreatePrePatchJar()) {
|
||||
createNeoForgeInstallerToolsPrePatchJar();
|
||||
return;
|
||||
@@ -253,6 +281,16 @@ public class MinecraftPatchedProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private void createUnobfuscatedPrePatchJar() throws IOException {
|
||||
try (var tempFiles = new TempFiles(); var serviceFactory = new ScopedServiceFactory()) {
|
||||
McpExecutorBuilder builder = createMcpExecutor(tempFiles.directory("loom-mcp"));
|
||||
builder.enqueue("preProcessJar");
|
||||
McpExecutor executor = serviceFactory.get(builder.build());
|
||||
Path output = executor.execute();
|
||||
Files.copy(output, minecraftIntermediateJar, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
}
|
||||
|
||||
private void createNeoForgeInstallerToolsPrePatchJar() throws IOException {
|
||||
try (var tempFiles = new TempFiles()) {
|
||||
final Path mappings = tempFiles.file("mappings", ".txt");
|
||||
@@ -300,7 +338,11 @@ public class MinecraftPatchedProvider {
|
||||
// The manifest includes a Minecraft-Dists attribute that specifies the dists in the current dev env,
|
||||
// as well as Minecraft-Dist attributes on every dist-only file.
|
||||
private void generateNeoForgeDistManifest(ServiceFactory serviceFactory, Path manifestPath) throws IOException {
|
||||
MemoryMappingTree mappings = getMappingTree(serviceFactory);
|
||||
// For unobfuscated NeoForge the classes are already in official namespace; an empty tree is safe
|
||||
// because SidedJarIndexGenerator falls back to the original name when no mapping is found.
|
||||
MemoryMappingTree mappings = getExtension().isUnobfuscatedForge()
|
||||
? new MemoryMappingTree()
|
||||
: getMappingTree(serviceFactory);
|
||||
|
||||
Manifest manifest = new Manifest();
|
||||
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
||||
@@ -527,7 +569,7 @@ public class MinecraftPatchedProvider {
|
||||
copyMissingClasses(minecraftIntermediateJar, minecraftPatchedIntermediateJar);
|
||||
deleteParameterNames(minecraftPatchedIntermediateJar);
|
||||
|
||||
if (getExtension().isForgeLikeAndNotOfficial()) {
|
||||
if (getExtension().isForgeLikeAndNotOfficial() && !getExtension().isUnobfuscatedForge()) {
|
||||
fixParameterAnnotation(minecraftPatchedIntermediateJar);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,13 +31,14 @@ import java.util.Map;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Data extracted from the MCPConfig JSON file.
|
||||
*
|
||||
* @param version the Minecraft version - the value of the {@code version} property
|
||||
* @param data the value of the {@code data} property
|
||||
* @param mappingsPath the path to srg mappings inside the MCP zip
|
||||
* @param mappingsPath the path to srg mappings inside the MCP zip, or {@code null} if absent (spec 6+)
|
||||
* @param official the value of the {@code official} property
|
||||
* @param steps the MCP step definitions by environment type
|
||||
* @param functions the MCP function definitions by name
|
||||
@@ -45,15 +46,19 @@ import com.google.gson.JsonObject;
|
||||
public record McpConfigData(
|
||||
String version,
|
||||
JsonObject data,
|
||||
String mappingsPath,
|
||||
@Nullable String mappingsPath,
|
||||
boolean official,
|
||||
Map<String, List<McpConfigStep>> steps,
|
||||
Map<String, McpConfigFunction> functions
|
||||
) {
|
||||
public boolean hasMappings() {
|
||||
return mappingsPath != null;
|
||||
}
|
||||
|
||||
public static McpConfigData fromJson(JsonObject json) {
|
||||
String version = json.get("version").getAsString();
|
||||
JsonObject data = json.getAsJsonObject("data");
|
||||
String mappingsPath = data.get("mappings").getAsString();
|
||||
@Nullable String mappingsPath = data.has("mappings") ? data.get("mappings").getAsString() : null;
|
||||
boolean official = json.has("official") && json.getAsJsonPrimitive("official").getAsBoolean();
|
||||
|
||||
JsonObject stepsJson = json.getAsJsonObject("steps");
|
||||
|
||||
@@ -47,6 +47,7 @@ import org.jspecify.annotations.Nullable;
|
||||
*/
|
||||
public record McpConfigFunction(String version, List<ConfigValue> args, List<ConfigValue> jvmArgs, @Nullable String repo) implements Serializable {
|
||||
private static final String VERSION_KEY = "version";
|
||||
private static final String CLASSPATH_KEY = "classpath";
|
||||
private static final String ARGS_KEY = "args";
|
||||
private static final String JVM_ARGS_KEY = "jvmargs";
|
||||
private static final String REPO_KEY = "repo";
|
||||
@@ -82,11 +83,21 @@ public record McpConfigFunction(String version, List<ConfigValue> args, List<Con
|
||||
}
|
||||
|
||||
public static McpConfigFunction fromJson(JsonObject json) {
|
||||
String version = json.get(VERSION_KEY).getAsString();
|
||||
String version;
|
||||
|
||||
if (json.has(VERSION_KEY)) {
|
||||
version = json.get(VERSION_KEY).getAsString();
|
||||
} else if (json.has(CLASSPATH_KEY)) {
|
||||
// Spec 6+: uses classpath array instead of version string
|
||||
version = json.getAsJsonArray(CLASSPATH_KEY).get(0).getAsString();
|
||||
} else {
|
||||
throw new IllegalArgumentException("MCP config function has neither 'version' nor 'classpath'");
|
||||
}
|
||||
|
||||
List<ConfigValue> args = json.has(ARGS_KEY) ? configValuesFromJson(json.getAsJsonArray(ARGS_KEY)) : List.of();
|
||||
List<ConfigValue> jvmArgs = json.has(JVM_ARGS_KEY) ? configValuesFromJson(json.getAsJsonArray(JVM_ARGS_KEY)) : List.of();
|
||||
JsonElement repoJson = json.get(REPO_KEY);
|
||||
@Nullable String repo = repoJson.isJsonPrimitive() ? repoJson.getAsString() : null;
|
||||
@Nullable JsonElement repoJson = json.get(REPO_KEY);
|
||||
@Nullable String repo = repoJson != null && repoJson.isJsonPrimitive() ? repoJson.getAsString() : null;
|
||||
return new McpConfigFunction(version, args, jvmArgs, repo);
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,15 @@ public class McpConfigProvider extends DependencyProvider {
|
||||
configJson = unpacked.resolve("config.json");
|
||||
}
|
||||
|
||||
public boolean hasMappings() {
|
||||
return data.hasMappings();
|
||||
}
|
||||
|
||||
public Path getMappings() {
|
||||
if (!hasMappings()) {
|
||||
throw new UnsupportedOperationException("MCP config has no mappings (spec 6+ unobfuscated)");
|
||||
}
|
||||
|
||||
return unpacked.resolve(getMappingsPath());
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFile;
|
||||
import org.gradle.api.tasks.Internal;
|
||||
import org.gradle.api.tasks.Nested;
|
||||
import org.gradle.api.tasks.Optional;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import net.fabricmc.loom.util.download.Download;
|
||||
@@ -90,7 +91,9 @@ public final class McpExecutor extends Service<McpExecutor.Options> {
|
||||
|
||||
/**
|
||||
* Mappings extracted from {@code data.mappings} in the MCPConfig JSON.
|
||||
* Optional for spec 6+ where mappings are absent.
|
||||
*/
|
||||
@Optional
|
||||
@InputFile
|
||||
RegularFileProperty getMappings();
|
||||
|
||||
@@ -217,6 +220,10 @@ public final class McpExecutor extends Service<McpExecutor.Options> {
|
||||
|
||||
@Override
|
||||
public Path mappings() {
|
||||
if (!getOptions().getMappings().isPresent()) {
|
||||
throw new UnsupportedOperationException("Mappings are not available (spec 6+ unobfuscated)");
|
||||
}
|
||||
|
||||
return getOptions().getMappings().get().getAsFile().toPath();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
@@ -194,7 +195,11 @@ public final class McpExecutorBuilder {
|
||||
}
|
||||
|
||||
options.getStepsToExecute().set(toExecute);
|
||||
options.getMappings().set(extension.getMcpConfigProvider().getMappings().toFile());
|
||||
|
||||
if (extension.getMcpConfigProvider().hasMappings()) {
|
||||
options.getMappings().set(extension.getMcpConfigProvider().getMappings().toFile());
|
||||
}
|
||||
|
||||
options.getInitialConfig().set(config);
|
||||
options.getOffline().set(project.getGradle().getStartParameter().isOffline());
|
||||
options.getManualRefreshDeps().set(extension.manualRefreshDeps());
|
||||
@@ -228,8 +233,12 @@ public final class McpExecutorBuilder {
|
||||
case "downloadServer" -> ConstantLogic.createOptions(setupContext, () -> minecraftProvider.getMinecraftServerJar().toPath());
|
||||
case "strip" -> StripLogic.createOptions(setupContext);
|
||||
case "listLibraries" -> ListLibrariesLogic.createOptions(setupContext);
|
||||
case "downloadClientMappings" -> DownloadManifestFileLogic.createOptions(setupContext, minecraftProvider.getVersionInfo().download("client_mappings"));
|
||||
case "downloadServerMappings" -> DownloadManifestFileLogic.createOptions(setupContext, minecraftProvider.getVersionInfo().download("server_mappings"));
|
||||
case "downloadClientMappings" -> DownloadManifestFileLogic.createOptions(setupContext,
|
||||
Objects.requireNonNull(minecraftProvider.getVersionInfo().download("client_mappings"),
|
||||
"client_mappings download is not available for this Minecraft version"));
|
||||
case "downloadServerMappings" -> DownloadManifestFileLogic.createOptions(setupContext,
|
||||
Objects.requireNonNull(minecraftProvider.getVersionInfo().download("server_mappings"),
|
||||
"server_mappings download is not available for this Minecraft version"));
|
||||
case "inject" -> InjectLogic.createOptions(setupContext);
|
||||
case "patch" -> PatchLogic.createOptions(setupContext);
|
||||
default -> {
|
||||
|
||||
@@ -188,6 +188,10 @@ public interface LoomGradleExtension extends LoomGradleExtensionAPI {
|
||||
return isForgeLike() && !getMcpConfigProvider().isOfficial();
|
||||
}
|
||||
|
||||
default boolean isUnobfuscatedForge() {
|
||||
return isForgeLike() && getProductionNamespace().get().equals(MappingsNamespace.OFFICIAL.toString());
|
||||
}
|
||||
|
||||
DependencyProviders getDependencyProviders();
|
||||
|
||||
void setDependencyProviders(DependencyProviders dependencyProviders);
|
||||
|
||||
@@ -242,9 +242,15 @@ public abstract class CompileConfiguration implements Runnable {
|
||||
throw new UnsupportedOperationException("Using %s with split jars is not supported!".formatted(extension.getPlatform().get().displayName()));
|
||||
}
|
||||
|
||||
if (extension.isForgeLike() && extension.disableObfuscation()) {
|
||||
// TODO: Allow setting up Forge and NeoForge without obfuscation
|
||||
throw new UnsupportedOperationException("Using %s without obfuscation is not supported!".formatted(extension.getPlatform().get().displayName()));
|
||||
// TODO: Re-evaluate if isUnobfuscatedForge() should even exist, or if the checks below should be removed
|
||||
if (extension.isForgeLike() && extension.disableObfuscation() && !extension.isUnobfuscatedForge()) {
|
||||
throw new UnsupportedOperationException(("Architectury Loom: The dev.architectury.loom-no-remap plugin was applied, but the Minecraft version '%s' is obfuscated. " +
|
||||
"Forge / NeoForge support for obfuscated Minecraft is through the regular dev.architectury.loom plugin instead.").formatted(metadataProvider.getMinecraftVersion()));
|
||||
}
|
||||
|
||||
if (extension.isForgeLike() && !extension.disableObfuscation() && extension.isUnobfuscatedForge()) {
|
||||
throw new UnsupportedOperationException(("Architectury Loom: The Minecraft version '%s' is unobfuscated (no mappings). " +
|
||||
"Forge / NeoForge support for unobfuscated Minecraft is through the dev.architectury.loom-no-remap plugin instead.").formatted(metadataProvider.getMinecraftVersion()));
|
||||
}
|
||||
|
||||
extension.setMinecraftProvider(minecraftProvider);
|
||||
@@ -273,9 +279,14 @@ public abstract class CompileConfiguration implements Runnable {
|
||||
|
||||
mappingConfiguration.setupPost(project);
|
||||
mappingConfiguration.applyToProject(getProject(), mappingsDep);
|
||||
} else if (extension.isUnobfuscatedForge()) {
|
||||
// Unobfuscated NeoForge: run the forge patch pipeline without requiring user-provided mappings.
|
||||
setupDependencyProviders(project, extension);
|
||||
ForgeLibrariesProvider.provide(null, project);
|
||||
((ForgeMinecraftProvider) minecraftProvider).getPatchedProvider().provide();
|
||||
}
|
||||
|
||||
if (extension.isForgeLike() && extension.getForgeProvider().usesMojangAtRuntime()) {
|
||||
if (extension.isForgeLike() && extension.getForgeProvider().usesMojangAtRuntime() && !extension.isUnobfuscatedForge()) {
|
||||
extension.getRuntimeIntermediaryNamespace().set(MappingsNamespace.MOJANG.toString());
|
||||
}
|
||||
|
||||
@@ -315,7 +326,7 @@ public abstract class CompileConfiguration implements Runnable {
|
||||
srgMinecraftProvider.provide(provideContext);
|
||||
}
|
||||
|
||||
if (extension.isForgeLike() && extension.getForgeProvider().usesMojangAtRuntime()) {
|
||||
if (extension.isForgeLike() && extension.getForgeProvider().usesMojangAtRuntime() && !extension.isUnobfuscatedForge()) {
|
||||
final MojangMappedMinecraftProvider<?> mojangMappedMinecraftProvider = jarConfiguration.createMojangMappedMinecraftProvider(project);
|
||||
extension.setMojangMappedMinecraftProvider(mojangMappedMinecraftProvider);
|
||||
mojangMappedMinecraftProvider.provide(provideContext);
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This file is part of fabric-loom, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2025 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.test.integration.neoforge
|
||||
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Unroll
|
||||
|
||||
import net.fabricmc.loom.test.util.GradleProjectTestTrait
|
||||
|
||||
import static net.fabricmc.loom.test.LoomTestConstants.DEFAULT_GRADLE
|
||||
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS
|
||||
|
||||
class NeoForge261Test extends Specification implements GradleProjectTestTrait {
|
||||
@Unroll
|
||||
def "build #mcVersion #neoforgeVersion"() {
|
||||
if (Integer.valueOf(System.getProperty("java.version").split("\\.")[0]) < 21) {
|
||||
println("This test requires Java 21. Currently you have Java ${System.getProperty("java.version")}.")
|
||||
return
|
||||
}
|
||||
|
||||
setup:
|
||||
def gradle = gradleProject(project: "neoforge/261", version: DEFAULT_GRADLE)
|
||||
gradle.buildGradle.text = gradle.buildGradle.text.replace('@MCVERSION@', mcVersion)
|
||||
.replace('@NEOFORGEVERSION@', neoforgeVersion)
|
||||
|
||||
when:
|
||||
def result = gradle.run(task: "build")
|
||||
|
||||
then:
|
||||
result.task(":build").outcome == SUCCESS
|
||||
|
||||
where:
|
||||
mcVersion | neoforgeVersion
|
||||
'26.1-snapshot-11' | '26.1.0.0-alpha.14+snapshot-11'
|
||||
}
|
||||
}
|
||||
50
src/test/resources/projects/neoforge/261/build.gradle
Normal file
50
src/test/resources/projects/neoforge/261/build.gradle
Normal file
@@ -0,0 +1,50 @@
|
||||
plugins {
|
||||
id 'dev.architectury.loom-no-remap'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
}
|
||||
|
||||
base {
|
||||
archivesName = project.archives_base_name
|
||||
}
|
||||
|
||||
version = project.mod_version
|
||||
group = project.maven_group
|
||||
|
||||
def mcVersion = "@MCVERSION@"
|
||||
def neoforgeVersion = "@NEOFORGEVERSION@"
|
||||
|
||||
repositories {
|
||||
maven { url = "https://maven.neoforged.net/releases/" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "com.mojang:minecraft:$mcVersion"
|
||||
neoForge "net.neoforged:neoforge:$neoforgeVersion"
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
it.options.release = 21
|
||||
}
|
||||
|
||||
java {
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
jar {
|
||||
from("LICENSE") {
|
||||
rename { "${it}_${project.archivesBaseName}"}
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
from components.java
|
||||
}
|
||||
}
|
||||
}
|
||||
10
src/test/resources/projects/neoforge/261/gradle.properties
Normal file
10
src/test/resources/projects/neoforge/261/gradle.properties
Normal file
@@ -0,0 +1,10 @@
|
||||
# Done to increase the memory available to gradle.
|
||||
org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.0.0
|
||||
maven_group = com.example
|
||||
archives_base_name = fabric-example-mod
|
||||
|
||||
# Dependencies
|
||||
loom.platform = neoforge
|
||||
1
src/test/resources/projects/neoforge/261/settings.gradle
Normal file
1
src/test/resources/projects/neoforge/261/settings.gradle
Normal file
@@ -0,0 +1 @@
|
||||
rootProject.name = "fabric-example-mod"
|
||||
Reference in New Issue
Block a user