-
-
Notifications
You must be signed in to change notification settings - Fork 179
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch '1.21.x' into PlayerSmithingEvent
- Loading branch information
Showing
50 changed files
with
3,046 additions
and
390 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# NeoForge Development Gradle Plugin | ||
|
||
## NeoForge Project Structure | ||
|
||
Before understanding the `buildSrc` plugin, one should understand the structure of the NeoForge Gradle project it is | ||
applied to. | ||
|
||
The project consists of a project tree with the following structure: | ||
|
||
| Folder Path | Gradle Project Path | Applied Plugins | Description | | ||
|------------------------------------------------------------------------|----------------------|:------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ||
| [`/build.gradle`](../build.gradle) | `:` | — | The root project. Since this project is reused for Kits, the root project name is based on the checkout folder, which actually can lead to issues if it is called `NeoForge`. | | ||
| [`/projects/neoforge/build.gradle`](../projects/neoforge/build.gradle) | `:neoforge` | [NeoDevPlugin](#neodevplugin) | The core NeoForge project, which produces the artifacts that will be published. | | ||
| [`/projects/base/build.gradle`](../projects/base/build.gradle) | `:base` | [NeoDevBasePlugin](#neodevbaseplugin) | A utility project that contains the Minecraft sources without any NeoForge additions. Can be used to quickly compare what NeoForge has changed. | | ||
| [`/tests/build.gradle`](../tests/build.gradle) | `:tests` | [NeoDevExtraPlugin](#neodevextraplugin) | Contains the game and unit tests for NeoForge. | | ||
| [`/testframework/build.gradle`](../testframework/build.gradle) | `:testframework` | [MinecraftDependenciesPlugin](#minecraftdependenciesplugin) | A library providing support classes around writing game tests. | | ||
| [`/coremods/build.gradle`](../coremods/build.gradle) | `:neoforge-coremods` | — | Java Bytecode transformers that are embedded into NeoForge as a nested Jar file. | | ||
| | ||
|
||
## Plugins | ||
|
||
### NeoDevBasePlugin | ||
|
||
Sources: [NeoDevBasePlugin.java](src/main/java/net/neoforged/neodev/NeoDevBasePlugin.java) | ||
|
||
Implicitly applies: [MinecraftDependenciesPlugin](#minecraftdependenciesplugin). | ||
|
||
Sets up a `setup` task that reuses code from [NeoDevPlugin](#neodevplugin) to decompile Minecraft and place the | ||
decompiled sources in `projects/base/src/main/java`. | ||
|
||
### NeoDevPlugin | ||
|
||
Sources: [NeoDevPlugin.java](src/main/java/net/neoforged/neodev/NeoDevPlugin.java) | ||
|
||
Implicitly applies: [MinecraftDependenciesPlugin](#minecraftdependenciesplugin). | ||
|
||
This is the primary of this repository and is used to configure the `neoforge` subproject. | ||
|
||
#### Setup | ||
|
||
It creates a `setup` task that performs the following actions via various subtasks: | ||
|
||
- Decompile Minecraft using the [NeoForm Runtime](https://github.com/neoforged/neoformruntime) and Minecraft version specific [NeoForm data](https://github.com/neoforged/NeoForm). | ||
- Applies [Access Transformers](../src/main/resources/META-INF/accesstransformer.cfg) to Minecraft sources. | ||
- Applies [NeoForge patches](../patches) to Minecraft sources. Any rejects are saved to the `/rejects` folder in the repository for manual inspection. During updates to new versions, the task can be run with `-Pupdating=true` to apply patches more leniently. | ||
- Unpacks the patched sources to `projects/neoforge/src/main/java`. | ||
|
||
#### Config Generation | ||
|
||
The plugin creates and configures the tasks to create various configuration files used downstream to develop | ||
mods with this version of NeoForge ([CreateUserDevConfig](src/main/java/net/neoforged/neodev/CreateUserDevConfig.java)), or install it ([CreateInstallerProfile](src/main/java/net/neoforged/neodev/installer/CreateInstallerProfile.java) and [CreateLauncherProfile](src/main/java/net/neoforged/neodev/installer/CreateLauncherProfile.java)). | ||
|
||
A separate userdev profile is created for use by other subprojects in this repository. | ||
The only difference is that it uses the FML launch types ending in `dev` rather than `userdev`. | ||
|
||
#### Patch Generation | ||
|
||
NeoForge injects its hooks into Minecraft by patching the decompiled source code. | ||
Changes are made locally to the decompiled and patched source. | ||
Since that source cannot be published, patches need to be generated before checking in. | ||
The plugin configures the necessary task to do this | ||
([GenerateSourcePatches](src/main/java/net/neoforged/neodev/GenerateSourcePatches.java)). | ||
|
||
The source patches are only used during development of NeoForge itself and development of mods that use Gradle plugins implementing the decompile/patch/recompile pipeline. | ||
For use by the installer intended for players as well as Gradle plugins wanting to replicate the production artifacts more closely, binary patches are generated using the ([GenerateBinaryPatches](src/main/java/net/neoforged/neodev/GenerateBinaryPatches.java)) task. | ||
|
||
### NeoDevExtraPlugin | ||
|
||
Sources: [NeoDevExtraPlugin.java](src/main/java/net/neoforged/neodev/NeoDevExtraPlugin.java) | ||
|
||
This plugin can be applied to obtain a dependency on the `neoforge` project to depend on NeoForge including Minecraft | ||
itself. Besides wiring up the dependency, it also creates run configurations based on the run-types defined in the | ||
`neoforge` project. | ||
|
||
### MinecraftDependenciesPlugin | ||
|
||
This plugin is reused from [ModDevGradle](https://github.com/neoforged/ModDevGradle/). | ||
|
||
It sets up repositories and attributes such that | ||
the [libraries that Minecraft itself depends upon](https://github.com/neoforged/GradleMinecraftDependencies) can be | ||
used. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,26 @@ | ||
plugins { | ||
id 'java-gradle-plugin' | ||
id 'groovy-gradle-plugin' | ||
} | ||
|
||
repositories { | ||
gradlePluginPortal() | ||
mavenCentral() | ||
maven { | ||
name = "NeoForged" | ||
url = "https://maven.neoforged.net/releases" | ||
content { | ||
includeGroup "codechicken" | ||
includeGroup "net.neoforged" | ||
} | ||
} | ||
} | ||
|
||
dependencies { | ||
// buildSrc is an includedbuild of the parent directory (gradle.parent) | ||
// ../settings.gradle sets these version properties accordingly | ||
implementation "net.neoforged:moddev-gradle:${gradle.parent.ext.moddevgradle_plugin_version}" | ||
|
||
implementation "com.google.code.gson:gson:${gradle.parent.ext.gson_version}" | ||
implementation "io.codechicken:DiffPatch:${gradle.parent.ext.diffpatch_version}" | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
72 changes: 72 additions & 0 deletions
72
buildSrc/src/main/java/net/neoforged/neodev/ApplyAccessTransformer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package net.neoforged.neodev; | ||
|
||
import net.neoforged.neodev.utils.FileUtils; | ||
import org.gradle.api.file.ConfigurableFileCollection; | ||
import org.gradle.api.file.RegularFileProperty; | ||
import org.gradle.api.provider.Property; | ||
import org.gradle.api.tasks.Classpath; | ||
import org.gradle.api.tasks.Input; | ||
import org.gradle.api.tasks.InputFile; | ||
import org.gradle.api.tasks.Internal; | ||
import org.gradle.api.tasks.JavaExec; | ||
import org.gradle.api.tasks.OutputFile; | ||
import org.gradle.api.tasks.TaskAction; | ||
|
||
import javax.inject.Inject; | ||
import java.io.File; | ||
import java.io.IOException; | ||
import java.io.UncheckedIOException; | ||
import java.nio.charset.StandardCharsets; | ||
|
||
/** | ||
* Runs <a href="https://github.com/neoforged/JavaSourceTransformer">JavaSourceTransformer</a> to apply | ||
* access transformers to the Minecraft source code for extending the access level of existing classes/methods/etc. | ||
* <p> | ||
* Note that at runtime, FML also applies access transformers. | ||
*/ | ||
abstract class ApplyAccessTransformer extends JavaExec { | ||
@InputFile | ||
public abstract RegularFileProperty getInputJar(); | ||
|
||
@InputFile | ||
public abstract RegularFileProperty getAccessTransformer(); | ||
|
||
@Input | ||
public abstract Property<Boolean> getValidate(); | ||
|
||
@OutputFile | ||
public abstract RegularFileProperty getOutputJar(); | ||
|
||
// Used to give JST more information about the classes. | ||
@Classpath | ||
public abstract ConfigurableFileCollection getLibraries(); | ||
|
||
@Internal | ||
public abstract RegularFileProperty getLibrariesFile(); | ||
|
||
@Inject | ||
public ApplyAccessTransformer() {} | ||
|
||
@Override | ||
@TaskAction | ||
public void exec() { | ||
try { | ||
FileUtils.writeLinesSafe( | ||
getLibrariesFile().getAsFile().get().toPath(), | ||
getLibraries().getFiles().stream().map(File::getAbsolutePath).toList(), | ||
StandardCharsets.UTF_8); | ||
} catch (IOException exception) { | ||
throw new UncheckedIOException("Failed to write libraries for JST.", exception); | ||
} | ||
|
||
args( | ||
"--enable-accesstransformers", | ||
"--access-transformer", getAccessTransformer().getAsFile().get().getAbsolutePath(), | ||
"--access-transformer-validation", getValidate().get() ? "error" : "log", | ||
"--libraries-list", getLibrariesFile().getAsFile().get().getAbsolutePath(), | ||
getInputJar().getAsFile().get().getAbsolutePath(), | ||
getOutputJar().getAsFile().get().getAbsolutePath()); | ||
|
||
super.exec(); | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
buildSrc/src/main/java/net/neoforged/neodev/ApplyPatches.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package net.neoforged.neodev; | ||
|
||
import io.codechicken.diffpatch.cli.PatchOperation; | ||
import io.codechicken.diffpatch.util.Input.MultiInput; | ||
import io.codechicken.diffpatch.util.Output.MultiOutput; | ||
import io.codechicken.diffpatch.util.PatchMode; | ||
import org.gradle.api.DefaultTask; | ||
import org.gradle.api.Project; | ||
import org.gradle.api.file.DirectoryProperty; | ||
import org.gradle.api.file.RegularFileProperty; | ||
import org.gradle.api.provider.Property; | ||
import org.gradle.api.tasks.Input; | ||
import org.gradle.api.tasks.InputDirectory; | ||
import org.gradle.api.tasks.InputFile; | ||
import org.gradle.api.tasks.OutputDirectory; | ||
import org.gradle.api.tasks.OutputFile; | ||
import org.gradle.api.tasks.PathSensitive; | ||
import org.gradle.api.tasks.PathSensitivity; | ||
import org.gradle.api.tasks.TaskAction; | ||
import org.gradle.work.DisableCachingByDefault; | ||
|
||
import javax.inject.Inject; | ||
import java.io.IOException; | ||
|
||
/** | ||
* Applies Java source patches to a source jar and produces a patched source jar as an output. | ||
* It can optionally store rejected hunks into a given folder, which is primarily used for updating | ||
* when the original sources changed and some hunks are expected to fail. | ||
*/ | ||
@DisableCachingByDefault(because = "Not worth caching") | ||
abstract class ApplyPatches extends DefaultTask { | ||
@InputFile | ||
public abstract RegularFileProperty getOriginalJar(); | ||
|
||
@InputDirectory | ||
@PathSensitive(PathSensitivity.NONE) | ||
public abstract DirectoryProperty getPatchesFolder(); | ||
|
||
@OutputFile | ||
public abstract RegularFileProperty getPatchedJar(); | ||
|
||
@OutputDirectory | ||
public abstract DirectoryProperty getRejectsFolder(); | ||
|
||
@Input | ||
protected abstract Property<Boolean> getIsUpdating(); | ||
|
||
@Inject | ||
public ApplyPatches(Project project) { | ||
getIsUpdating().set(project.getProviders().gradleProperty("updating").map(Boolean::parseBoolean).orElse(false)); | ||
} | ||
|
||
@TaskAction | ||
public void applyPatches() throws IOException { | ||
var isUpdating = getIsUpdating().get(); | ||
|
||
var builder = PatchOperation.builder() | ||
.logTo(getLogger()::lifecycle) | ||
.baseInput(MultiInput.detectedArchive(getOriginalJar().get().getAsFile().toPath())) | ||
.patchesInput(MultiInput.folder(getPatchesFolder().get().getAsFile().toPath())) | ||
.patchedOutput(MultiOutput.detectedArchive(getPatchedJar().get().getAsFile().toPath())) | ||
.rejectsOutput(MultiOutput.folder(getRejectsFolder().get().getAsFile().toPath())) | ||
.mode(isUpdating ? PatchMode.FUZZY : PatchMode.ACCESS) | ||
.aPrefix("a/") | ||
.bPrefix("b/") | ||
.level(isUpdating ? io.codechicken.diffpatch.util.LogLevel.ALL : io.codechicken.diffpatch.util.LogLevel.WARN) | ||
.minFuzz(0.9f); // The 0.5 default in DiffPatch is too low. | ||
|
||
var result = builder.build().operate(); | ||
|
||
int exit = result.exit; | ||
if (exit != 0 && exit != 1) { | ||
throw new RuntimeException("DiffPatch failed with exit code: " + exit); | ||
} | ||
if (exit != 0 && !isUpdating) { | ||
throw new RuntimeException("Patches failed to apply."); | ||
} | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
buildSrc/src/main/java/net/neoforged/neodev/CreateCleanArtifacts.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package net.neoforged.neodev; | ||
|
||
import net.neoforged.nfrtgradle.CreateMinecraftArtifacts; | ||
import org.gradle.api.file.RegularFileProperty; | ||
import org.gradle.api.tasks.OutputFile; | ||
|
||
import javax.inject.Inject; | ||
|
||
abstract class CreateCleanArtifacts extends CreateMinecraftArtifacts { | ||
@OutputFile | ||
abstract RegularFileProperty getCleanClientJar(); | ||
|
||
@OutputFile | ||
abstract RegularFileProperty getRawServerJar(); | ||
|
||
@OutputFile | ||
abstract RegularFileProperty getCleanServerJar(); | ||
|
||
@OutputFile | ||
abstract RegularFileProperty getCleanJoinedJar(); | ||
|
||
@OutputFile | ||
abstract RegularFileProperty getMergedMappings(); | ||
|
||
@Inject | ||
public CreateCleanArtifacts() { | ||
getAdditionalResults().put("node.stripClient.output.output", getCleanClientJar().getAsFile()); | ||
getAdditionalResults().put("node.downloadServer.output.output", getRawServerJar().getAsFile()); | ||
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() | ||
} | ||
} |
Oops, something went wrong.