New Binpatching Tooling (#2809)

Co-authored-by: Marc Hermans <marc.hermans@ldtteam.com>
This commit is contained in:
shartte 2025-11-26 23:03:42 +01:00 committed by GitHub
parent 1a73d89162
commit be1d9ebf61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 293 additions and 186 deletions

View File

@ -30,6 +30,9 @@ abstract class CreateCleanArtifacts extends CreateMinecraftArtifacts {
@OutputFile
abstract RegularFileProperty getMergedMappings();
@OutputFile
abstract RegularFileProperty getClientMappings();
@Inject
public CreateCleanArtifacts() {
getAdditionalResults().put("node.downloadClient.output.output", getRawClientJar().getAsFile());
@ -38,8 +41,6 @@ abstract class CreateCleanArtifacts extends CreateMinecraftArtifacts {
getAdditionalResults().put("node.stripServer.output.output", getCleanServerJar().getAsFile());
getAdditionalResults().put("node.rename.output.output", getCleanJoinedJar().getAsFile());
getAdditionalResults().put("node.mergeMappings.output.output", getMergedMappings().getAsFile());
// TODO: does anyone care about this? they should be contained in the client mappings
//"--write-result", "node.downloadServerMappings.output.output:" + getServerMappings().get().getAsFile().getAbsolutePath()
getAdditionalResults().put("node.downloadClientMappings.output.output", getClientMappings().getAsFile());
}
}

View File

@ -0,0 +1,58 @@
package net.neoforged.neodev;
import javax.inject.Inject;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.JavaExec;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.PathSensitive;
import org.gradle.api.tasks.PathSensitivity;
/**
* Create the base jar file that will be diffed against the modified jar to create binary patch files.
*/
abstract class GenerateBaseJar extends JavaExec {
@Inject
public GenerateBaseJar() {}
@InputFiles
@PathSensitive(PathSensitivity.NONE)
abstract ConfigurableFileCollection getMinecraft();
/**
* The official Mojang mappings file.
*/
@InputFile
@PathSensitive(PathSensitivity.NONE)
@Optional
abstract RegularFileProperty getMappings();
/**
* The NeoForm mappings (either LZMA or ZIP data file), this can be empty to not apply NeoForm mappings.
*/
@InputFiles
@PathSensitive(PathSensitivity.NONE)
abstract ConfigurableFileCollection getNeoFormMappings();
@OutputFile
abstract RegularFileProperty getOutput();
@Override
public void exec() {
args("--task", "PROCESS_MINECRAFT_JAR");
for (var file : getMinecraft().getFiles()) {
args("--input", file.getAbsolutePath());
}
if (getMappings().isPresent()) {
args("--input-mappings", getMappings().get().getAsFile().getAbsolutePath());
}
args("--output", getOutput().get().getAsFile().getAbsolutePath());
if (!getNeoFormMappings().isEmpty()) {
args("--neoform-data", getNeoFormMappings().getSingleFile().getAbsolutePath());
}
super.exec();
}
}

View File

@ -6,12 +6,11 @@ import java.io.FileOutputStream;
import java.io.IOException;
import javax.inject.Inject;
import org.gradle.api.GradleException;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.InputDirectory;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.JavaExec;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.OutputFile;
abstract class GenerateBinaryPatches extends JavaExec {
@ -19,61 +18,78 @@ abstract class GenerateBinaryPatches extends JavaExec {
public GenerateBinaryPatches() {}
/**
* The jar file containing classes in the base state.
* The base against which the patches should be created for the client distribution.
*/
@InputFile
abstract RegularFileProperty getCleanJar();
abstract RegularFileProperty getBaseClientJar();
/**
* The jar file containing classes in the desired target state.
* The target jar that will be diffed against {@link #getBaseClientJar()} to create the patches for the
* client distribution.
*/
@InputFile
abstract RegularFileProperty getPatchedJar();
@InputFile
abstract RegularFileProperty getMappings();
abstract RegularFileProperty getModifiedClientJar();
/**
* The files in this optional directory are used to filter which binary patches should be created.
* <p>A binary patch is only created for a file from {@link #getPatchedJar()}, if a source patch (A corresponding file
* with {@code .java.patch} extension) is present in this directory, or if a class with the same path is present in
* {@link #getIncludeClassesJar()} (if set).
* <p>For inner classes, only the outermost class is checked against the filters.
* <p>If neither this nor {@link #getIncludeClassesJar()} are set, no filtering is applied.
*/
@InputDirectory
@Optional
abstract DirectoryProperty getSourcePatchesFolder();
/**
* The list of files included in this optional Jar file is used to filter for which files binary patches should be created.
* <p>A binary patch is only created for a file from {@link #getPatchedJar()}, if a file with the same path is
* either present in this jar, or if a corresponding source patch is present in {@link #getSourcePatchesFolder()} (if set).
* <p>For inner classes, only the outermost class is checked against the filters.
* <p>If neither this nor {@link #getSourcePatchesFolder()} are set, no filtering is applied.
* The base against which the patches should be created for the server distribution.
*/
@InputFile
@Optional
abstract RegularFileProperty getIncludeClassesJar();
abstract RegularFileProperty getBaseServerJar();
/**
* The location where the LZMA compressed binary patches are written to.
* The target jar that will be diffed against {@link #getBaseServerJar()} to create the patches for the
* server distribution.
*/
@InputFile
abstract RegularFileProperty getModifiedServerJar();
/**
* The base against which the patches should be created for the combined client+server distribution.
*/
@InputFile
abstract RegularFileProperty getBaseJoinedJar();
/**
* The target jar that will be diffed against {@link #getBaseServerJar()} to create the patches for the
* combined client+server distribution.
*/
@InputFile
abstract RegularFileProperty getModifiedJoinedJar();
/**
* Ant-Style path patterns for paths to include in diffing.
*/
@Input
abstract ListProperty<String> getInclude();
/**
* Ant-Style path patterns for paths to exclude from diffing.
*/
@Input
abstract ListProperty<String> getExclude();
/**
* Where the created patch bundle should be written to.
*/
@OutputFile
abstract RegularFileProperty getOutputFile();
@Override
public void exec() {
args("--clean", getCleanJar().get().getAsFile().getAbsolutePath());
args("--dirty", getPatchedJar().get().getAsFile().getAbsolutePath());
args("--srg", getMappings().get().getAsFile().getAbsolutePath());
args("--minimize");
if (getSourcePatchesFolder().isPresent()) {
args("--patches", getSourcePatchesFolder().get().getAsFile().getAbsolutePath());
args("--diff");
args("--base-client", getBaseClientJar().get().getAsFile().getAbsolutePath());
args("--base-server", getBaseServerJar().get().getAsFile().getAbsolutePath());
args("--base-joined", getBaseJoinedJar().get().getAsFile().getAbsolutePath());
args("--modified-client", getModifiedClientJar().get().getAsFile().getAbsolutePath());
args("--modified-server", getModifiedServerJar().get().getAsFile().getAbsolutePath());
args("--modified-joined", getModifiedJoinedJar().get().getAsFile().getAbsolutePath());
for (String pattern : getInclude().get()) {
args("--include", pattern);
}
if (getIncludeClassesJar().isPresent()) {
args("--include-classes", getIncludeClassesJar().get().getAsFile().getAbsolutePath());
for (String pattern : getExclude().get()) {
args("--exclude", pattern);
}
args("--optimize-constantpool");
args("--output", getOutputFile().get().getAsFile().getAbsolutePath());
var logFile = new File(getTemporaryDir(), "console.log");

View File

@ -0,0 +1,47 @@
package net.neoforged.neodev;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.inject.Inject;
import org.gradle.api.GradleException;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.JavaExec;
import org.gradle.api.tasks.OutputFile;
/**
* A debugging task for helping with analyzing how the patches were de-duped, and what is being patched.
*/
abstract class ListBinaryPatches extends JavaExec {
@Inject
public ListBinaryPatches() {}
/**
* The patch bundle to report on.
*/
@InputFile
public abstract RegularFileProperty getPatchBundle();
/**
* Where the created patch bundle report should be written to.
*/
@OutputFile
abstract RegularFileProperty getOutputFile();
@Override
public void exec() {
args("--list", "--patches", getPatchBundle().get().getAsFile().getAbsolutePath());
File reportFile = getOutputFile().getAsFile().get();
try (var out = new BufferedOutputStream(new FileOutputStream(reportFile))) {
setStandardOutput(out);
super.exec();
} catch (IOException e) {
throw new GradleException("Failed to list binary patches.", e);
}
getLogger().lifecycle("Wrote contents of patch bundle to " + reportFile.getAbsolutePath());
}
}

View File

@ -5,6 +5,7 @@ import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.Consumer;
import net.neoforged.minecraftdependencies.MinecraftDependenciesPlugin;
@ -36,6 +37,7 @@ import org.gradle.api.plugins.BasePluginExtension;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginExtension;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.Sync;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.api.tasks.bundling.AbstractArchiveTask;
@ -62,6 +64,9 @@ public class NeoDevPlugin implements Plugin<Project> {
var extension = project.getExtensions().create(NeoDevExtension.NAME, NeoDevExtension.class);
var configurations = NeoDevConfigurations.createAndSetup(project);
// Pre-create the "client" source set
project.getExtensions().getByType(JavaPluginExtension.class).getSourceSets().create("client");
/*
* MINECRAFT SOURCES SETUP
*/
@ -70,7 +75,7 @@ public class NeoDevPlugin implements Plugin<Project> {
// Task must run on sync to have MC resources available for IDEA nondelegated builds.
NeoDevFacade.runTaskOnProjectSync(project, createSourceArtifacts);
// Obtain clean binary artifacts, needed to be able to generate ATs
// Obtain clean binary artifacts, needed to be able to generate ATs and binary patches
var createCleanArtifacts = tasks.register("createCleanArtifacts", CreateCleanArtifacts.class, task -> {
task.setGroup(INTERNAL_GROUP);
task.setDescription("This task retrieves various files for the Minecraft version without applying NeoForge patches to them");
@ -81,6 +86,7 @@ public class NeoDevPlugin implements Plugin<Project> {
task.getCleanServerJar().set(cleanArtifactsDir.map(dir -> dir.file("server.jar")));
task.getCleanJoinedJar().set(cleanArtifactsDir.map(dir -> dir.file("joined.jar")));
task.getMergedMappings().set(cleanArtifactsDir.map(dir -> dir.file("merged-mappings.txt")));
task.getClientMappings().set(cleanArtifactsDir.map(dir -> dir.file("client-mappings.txt")));
task.getNeoFormArtifact().set(mcAndNeoFormVersion.map(version -> "net.neoforged:neoform:" + version + "@zip"));
});
@ -246,13 +252,6 @@ public class NeoDevPlugin implements Plugin<Project> {
task.getPatchesFolder().set(neoDevBuildDir.map(dir -> dir.dir("production-source-patches")));
});
var genCommonProductionPatches = tasks.register("generateCommonProductionSourcePatches", GenerateSourcePatches.class, task -> {
task.setGroup(INTERNAL_GROUP);
task.getOriginalJar().set(splitUnpatchedSources.flatMap(SplitMergedSources::getCommonJar));
task.getModifiedSources().set(commonSources.flatMap(AbstractArchiveTask::getArchiveFile));
task.getPatchesFolder().set(neoDevBuildDir.map(dir -> dir.dir("production-source-patches-common")));
});
// Update the patch/ folder with the current patches.
tasks.register("genPatches", Sync.class, task -> {
task.setGroup(GROUP);
@ -310,10 +309,7 @@ public class NeoDevPlugin implements Plugin<Project> {
project,
configurations,
createCleanArtifacts,
joinedJar,
neoDevBuildDir,
genProductionPatches.flatMap(GenerateSourcePatches::getPatchesFolder),
genCommonProductionPatches.flatMap(GenerateSourcePatches::getPatchesFolder));
neoDevBuildDir);
var installerRepositoryUrls = getInstallerRepositoryUrls(project);
// Launcher profile = the version.json file used by the Minecraft launcher.
@ -412,13 +408,9 @@ public class NeoDevPlugin implements Plugin<Project> {
spec.into("data");
spec.rename(s -> "win_args.txt");
});
task.from(binaryPatchOutputs.binaryPatchesForClient(), spec -> {
task.from(binaryPatchOutputs, spec -> {
spec.into("data");
spec.rename(s -> "client.lzma");
});
task.from(binaryPatchOutputs.binaryPatchesForServer(), spec -> {
spec.into("data");
spec.rename(s -> "server.lzma");
spec.rename(s -> "patches.lzma");
});
var mavenPath = neoForgeVersion.map(v -> "net/neoforged/neoforge/" + v);
task.getInputs().property("mavenPath", mavenPath);
@ -450,8 +442,8 @@ public class NeoDevPlugin implements Plugin<Project> {
task.from(atFiles, spec -> {
spec.into("ats/");
});
task.from(binaryPatchOutputs.binaryPatchesForMerged(), spec -> {
spec.rename(s -> "joined.lzma");
task.from(binaryPatchOutputs, spec -> {
spec.rename(s -> "patches.lzma");
});
task.from(project.fileTree(genProductionPatches.flatMap(GenerateSourcePatches::getPatchesFolder)), spec -> {
spec.into("patches/");
@ -524,79 +516,50 @@ public class NeoDevPlugin implements Plugin<Project> {
});
}
private static BinaryPatchOutputs configureBinaryPatchCreation(Project project,
NeoDevConfigurations configurations,
private static Provider<RegularFile> configureBinaryPatchCreation(
Project project,
NeoDevConfigurations neoDevConfigurations,
TaskProvider<CreateCleanArtifacts> createCleanArtifacts,
TaskProvider<Jar> joinedJar,
Provider<Directory> neoDevBuildDir,
Provider<Directory> sourcesPatchesFolder,
Provider<Directory> sourcesServerPatchesFolder) {
Provider<Directory> neoDevBuildDir) {
var tasks = project.getTasks();
var artConfig = configurations.getExecutableTool(Tools.AUTO_RENAMING_TOOL);
var remapClientJar = tasks.register("remapClientJar", RemapJar.class, task -> {
task.setDescription("Creates a Minecraft client jar with the official mappings applied. Used as the base for generating binary patches for the client.");
task.getInputJar().set(createCleanArtifacts.flatMap(CreateCleanArtifacts::getCleanClientJar));
task.getOutputJar().set(neoDevBuildDir.map(dir -> dir.file("remapped-client.jar")));
});
var remapServerJar = tasks.register("remapServerJar", RemapJar.class, task -> {
task.setDescription("Creates a Minecraft dedicated server jar with the official mappings applied. Used as the base for generating binary patches for the client.");
task.getInputJar().set(createCleanArtifacts.flatMap(CreateCleanArtifacts::getCleanServerJar));
task.getOutputJar().set(neoDevBuildDir.map(dir -> dir.file("remapped-server.jar")));
});
for (var remapTask : List.of(remapClientJar, remapServerJar)) {
remapTask.configure(task -> {
task.setGroup(INTERNAL_GROUP);
task.classpath(artConfig);
task.getMappings().set(createCleanArtifacts.flatMap(CreateCleanArtifacts::getMergedMappings));
});
}
var clientBaseJar = setupBinaryPatchBaseJar(project, neoDevBuildDir, BinaryPatchBaseType.CLIENT, neoDevConfigurations, createCleanArtifacts);
var serverBaseJar = setupBinaryPatchBaseJar(project, neoDevBuildDir, BinaryPatchBaseType.SERVER, neoDevConfigurations, createCleanArtifacts);
var joinedBaseJar = setupBinaryPatchBaseJar(project, neoDevBuildDir, BinaryPatchBaseType.JOINED, neoDevConfigurations, createCleanArtifacts);
var clientModifiedJar = setupBinaryPatchModifiedJar(project, neoDevBuildDir, BinaryPatchBaseType.CLIENT);
var serverModifiedJar = setupBinaryPatchModifiedJar(project, neoDevBuildDir, BinaryPatchBaseType.SERVER);
var binpatcherConfig = configurations.getExecutableTool(Tools.BINPATCHER);
var generateMergedBinPatches = tasks.register("generateMergedBinPatches", GenerateBinaryPatches.class, task -> {
task.setDescription("Creates binary patch files by diffing a merged client/server jar-file and the compiled Minecraft classes in this project.");
task.getCleanJar().set(createCleanArtifacts.flatMap(CreateCleanArtifacts::getCleanJoinedJar));
// Included so that lambda names are correct in production
task.getIncludeClassesJar().set(createCleanArtifacts.flatMap(CreateCleanArtifacts::getCleanJoinedJar));
task.getSourcePatchesFolder().set(sourcesPatchesFolder);
task.getOutputFile().set(neoDevBuildDir.map(dir -> dir.file("merged-binpatches.lzma")));
});
var generateClientBinPatches = tasks.register("generateClientBinPatches", GenerateBinaryPatches.class, task -> {
task.setDescription("Creates binary patch files by diffing a merged client jar-file and the compiled Minecraft classes in this project.");
task.getCleanJar().set(remapClientJar.flatMap(RemapJar::getOutputJar));
// Included so that lambda names are correct in production
task.getIncludeClassesJar().set(remapClientJar.flatMap(RemapJar::getOutputJar));
task.getSourcePatchesFolder().set(sourcesPatchesFolder);
task.getOutputFile().set(neoDevBuildDir.map(dir -> dir.file("client-binpatches.lzma")));
});
var generateServerBinPatches = tasks.register("generateServerBinPatches", GenerateBinaryPatches.class, task -> {
task.setDescription("Creates binary patch files by diffing a merged server jar-file and the compiled Minecraft classes in this project.");
task.getCleanJar().set(remapServerJar.flatMap(RemapJar::getOutputJar));
// Included so that lambda names are correct in production
task.getIncludeClassesJar().set(remapServerJar.flatMap(RemapJar::getOutputJar));
task.getSourcePatchesFolder().set(sourcesServerPatchesFolder);
task.getOutputFile().set(neoDevBuildDir.map(dir -> dir.file("server-binpatches.lzma")));
});
for (var generateBinPatchesTask : List.of(generateMergedBinPatches, generateClientBinPatches, generateServerBinPatches)) {
generateBinPatchesTask.configure(task -> {
task.setGroup(INTERNAL_GROUP);
task.classpath(binpatcherConfig);
task.getPatchedJar().set(joinedJar.flatMap(Jar::getArchiveFile));
task.getMappings().set(createCleanArtifacts.flatMap(CreateCleanArtifacts::getMergedMappings));
});
}
var binpatcherConfig = neoDevConfigurations.getExecutableTool(Tools.BINPATCHER);
var generatePatchBundles = tasks.register("generatePatchBundle", GenerateBinaryPatches.class, task -> {
task.setDescription("Generates the binary patches.");
task.setGroup(INTERNAL_GROUP);
task.classpath(binpatcherConfig);
return new BinaryPatchOutputs(
generateMergedBinPatches.flatMap(GenerateBinaryPatches::getOutputFile),
generateClientBinPatches.flatMap(GenerateBinaryPatches::getOutputFile),
generateServerBinPatches.flatMap(GenerateBinaryPatches::getOutputFile));
task.getBaseClientJar().set(clientBaseJar);
task.getModifiedClientJar().set(clientModifiedJar);
task.getBaseServerJar().set(serverBaseJar);
task.getModifiedServerJar().set(serverModifiedJar);
task.getBaseJoinedJar().set(joinedBaseJar);
// Since we're filtering by *.class, the modified jar for client and joined is identical. They differ in manifest only.
task.getModifiedJoinedJar().set(clientModifiedJar);
task.getInclude().add("**/*.class");
task.getOutputFile().set(neoDevBuildDir.map(dir -> dir.file("patches.lzma")));
});
var patchBundle = generatePatchBundles.flatMap(GenerateBinaryPatches::getOutputFile);
tasks.register("listPatchBundleContent", ListBinaryPatches.class, task -> {
task.setDescription("Lists the content of the created binary patch bundle.");
task.setGroup(INTERNAL_GROUP);
task.classpath(binpatcherConfig);
task.getPatchBundle().set(patchBundle);
task.getOutputFile().set(neoDevBuildDir.map(dir -> dir.file("patches-content.txt")));
});
return patchBundle;
}
private record BinaryPatchOutputs(
Provider<RegularFile> binaryPatchesForMerged,
Provider<RegularFile> binaryPatchesForClient,
Provider<RegularFile> binaryPatchesForServer) {}
/**
* Sets up NFRT, and creates the sources and resources artifacts.
*/
@ -647,7 +610,85 @@ public class NeoDevPlugin implements Plugin<Project> {
});
}
private void setupProductionClientTest(Project project,
enum BinaryPatchBaseType {
CLIENT,
SERVER,
JOINED;
public String taskName(String prefix) {
return prefix + Character.toUpperCase(toString().charAt(0)) + toString().substring(1);
}
@Override
public String toString() {
return name().toLowerCase(Locale.ROOT);
}
}
private static Provider<RegularFile> setupBinaryPatchBaseJar(
Project project,
Provider<Directory> neoDevBuildDir,
BinaryPatchBaseType type,
NeoDevConfigurations neoDevConfigurations,
TaskProvider<CreateCleanArtifacts> createCleanArtifacts) {
var tasks = project.getTasks();
var binpatchesDir = neoDevBuildDir.map(dir -> dir.dir("artifacts/binpatches"));
var installerToolsConfig = neoDevConfigurations.getExecutableTool(Tools.INSTALLERTOOLS);
var baseJar = tasks.register(type.taskName("createBaseJar"), GenerateBaseJar.class, task -> {
task.setDescription("Generates the base jar for creating binary patches of the " + type + " distribution");
task.setGroup(INTERNAL_GROUP);
if (type == BinaryPatchBaseType.CLIENT || type == BinaryPatchBaseType.JOINED) {
task.getMinecraft().from(createCleanArtifacts.flatMap(CreateCleanArtifacts::getRawClientJar));
}
if (type == BinaryPatchBaseType.SERVER || type == BinaryPatchBaseType.JOINED) {
task.getMinecraft().from(createCleanArtifacts.flatMap(CreateCleanArtifacts::getRawServerJar));
}
// The client mappings are a superset of the server mappings and can be used to remap the server too.
task.getMappings().set(createCleanArtifacts.flatMap(CreateCleanArtifacts::getClientMappings));
task.getOutput().set(binpatchesDir.map(dir -> dir.file(type + "-base.jar")));
task.getNeoFormMappings().from(neoDevConfigurations.neoFormMappingsFiles);
task.classpath(installerToolsConfig);
});
return baseJar.flatMap(GenerateBaseJar::getOutput);
}
private static Provider<RegularFile> setupBinaryPatchModifiedJar(
Project project,
Provider<Directory> neoDevBuildDir,
BinaryPatchBaseType type) {
var tasks = project.getTasks();
var binpatchesDir = neoDevBuildDir.map(dir -> dir.dir("artifacts/binpatches"));
// Create the jar file in its target state. We will create binary patches to convert the base-jar to this jar.
var sourceSets = project.getExtensions().getByType(JavaPluginExtension.class).getSourceSets();
var modifiedJar = tasks.register(type.taskName("createModifiedJar"), Jar.class, task -> {
task.setDescription("Create the jar file for " + type + " in the state that we want to create binpatches from. This jar only contains classes since we don't modify original resources at the moment.");
task.setGroup(INTERNAL_GROUP);
task.getDestinationDirectory().set(binpatchesDir);
task.getArchiveFileName().set(type + "-modified-classes.jar");
// Copy only the unmodified+modified Minecraft classes, excluding NeoForges own classes
var mainSourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
task.from(mainSourceSet.getJava().getClassesDirectory(), spec -> {
spec.exclude("net/neoforged/**");
});
if (type == BinaryPatchBaseType.CLIENT || type == BinaryPatchBaseType.JOINED) {
var clientSourceSet = sourceSets.getByName("client");
task.from(clientSourceSet.getJava().getClassesDirectory(), spec -> {
spec.exclude("net/neoforged/**");
});
}
});
return modifiedJar.flatMap(AbstractArchiveTask::getArchiveFile);
}
private void setupProductionClientTest(
Project project,
NeoDevConfigurations configurations,
TaskProvider<? extends DownloadAssets> downloadAssets,
TaskProvider<? extends AbstractArchiveTask> installer,

View File

@ -1,52 +0,0 @@
package net.neoforged.neodev;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.inject.Inject;
import org.gradle.api.GradleException;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.JavaExec;
import org.gradle.api.tasks.OutputFile;
/**
* Produces a remapped jar-file that has almost no other changes applied with the intent of being
* the base against which we {@link GenerateBinaryPatches generate binary patches}.
* <p>
* The installer produces the same Jar file as this task does and then applies the patches against that.
* <p>
* Any changes to the options used here have to be reflected in the {@link net.neoforged.neodev.installer.CreateInstallerProfile installer profile}
* and vice versa, to ensure the patches are generated against the same binary files as they are applied to later.
*/
abstract class RemapJar extends JavaExec {
@Inject
public RemapJar() {}
@InputFile
abstract RegularFileProperty getInputJar();
@InputFile
abstract RegularFileProperty getMappings();
@OutputFile
abstract RegularFileProperty getOutputJar();
@Override
public void exec() {
args("--input", getInputJar().get().getAsFile().getAbsolutePath());
args("--output", getOutputJar().get().getAsFile().getAbsolutePath());
args("--names", getMappings().get().getAsFile().getAbsolutePath());
args("--ann-fix", "--ids-fix", "--src-fix", "--record-fix");
var logFile = new File(getTemporaryDir(), "console.log");
try (var out = new BufferedOutputStream(new FileOutputStream(logFile))) {
getLogger().info("Logging ART console output to {}", logFile.getAbsolutePath());
setStandardOutput(out);
super.exec();
} catch (IOException e) {
throw new GradleException("Failed to remap jar.", e);
}
}
}

View File

@ -8,8 +8,6 @@ public enum Tools {
JST("net.neoforged.jst:jst-cli-bundle:%s", "jst_version", "toolJstClasspath", true),
// Fatjar because the contents are copy/pasted into the installer jar which must be standalone.
LEGACYINSTALLER("net.neoforged:legacyinstaller:%s:shrunk", "legacyinstaller_version", "toolLegacyinstallerClasspath", true),
// Fatjar because the slim jar currently does not have the main class set in its manifest.
AUTO_RENAMING_TOOL("net.neoforged:AutoRenamingTool:%s:all", "art_version", "toolAutoRenamingToolClasspath", true),
INSTALLERTOOLS("net.neoforged.installertools:installertools:%s:fatjar", "installertools_version", "toolInstallertoolsClasspath", true),
// Fatjar because it was like that in the userdev json in the past.
// To reconsider, we need to get in touch with 3rd party plugin developers or wait for a BC window.

View File

@ -112,7 +112,7 @@ public abstract class CreateInstallerProfile extends DefaultTask {
var data = new LinkedHashMap<String, LauncherDataEntry>();
var neoFormVersion = getMcAndNeoFormVersion().get();
data.put("MOJMAPS", new LauncherDataEntry(clientMappingsCoordinate, serverMappingsCoordinate));
data.put("BINPATCH", new LauncherDataEntry("/data/client.lzma", "/data/server.lzma"));
data.put("BINPATCH", new LauncherDataEntry("/data/patches.lzma", "/data/patches.lzma"));
var patchedClientCoordinate = new MavenIdentifier("net.neoforged", "minecraft-client-patched", getNeoForgeVersion().get(), "", "jar");
var patchedServerCoordinate = new MavenIdentifier("net.neoforged", "minecraft-server-patched", getNeoForgeVersion().get(), "", "jar");

View File

@ -24,10 +24,8 @@ neoforge_snapshot_next_stable=21.11
# renovate: net.neoforged.jst:jst-cli-bundle
jst_version=1.0.67
legacyinstaller_version=3.0.+
# renovate: net.neoforged:AutoRenamingTool
art_version=2.0.11
# renovate: net.neoforged.installertools:installertools
installertools_version=3.0.14
installertools_version=4.0.6
# renovate: org.ow2.asm:asm
asm_version=9.8