mirror of
https://github.com/neoforged/NeoForge.git
synced 2025-12-10 00:22:25 -06:00
New Binpatching Tooling (#2809)
Co-authored-by: Marc Hermans <marc.hermans@ldtteam.com>
This commit is contained in:
parent
1a73d89162
commit
be1d9ebf61
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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");
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
@ -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,
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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.
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user