Skip to content

Commit

Permalink
Merge branch '1.21.x' into PlayerSmithingEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
MeAlam1 authored Dec 8, 2024
2 parents 12da915 + 00f3f80 commit 73e72d3
Show file tree
Hide file tree
Showing 415 changed files with 6,663 additions and 5,020 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/check-local-changes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ jobs:
- name: Gen package infos
run: ./gradlew generatePackageInfos

- name: Gen patches
run: ./gradlew :neoforge:genPatches
- name: Gen patches and ATs
run: ./gradlew :neoforge:genPatches :neoforge:generateAccessTransformers

- name: Run datagen with Gradle
run: ./gradlew :neoforge:runData :tests:runData
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/test-prs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ jobs:
- name: Run JUnit tests with Gradle
run: ./gradlew :tests:runUnitTests

- name: Install software OpenGL rendering
run: sudo apt-get install xvfb libgl1-mesa-dri

- name: Run production client self-test
run: xvfb-run ./gradlew :neoforge:testProductionClient

- name: Run production server self-test
run: ./gradlew :neoforge:testProductionServer

- name: Store reports
if: failure()
uses: actions/upload-artifact@v4
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ build
**/eclipse/
**/runs/

**/out/
**/out/
2 changes: 2 additions & 0 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ dependencies {

implementation "com.google.code.gson:gson:${gradle.parent.ext.gson_version}"
implementation "io.codechicken:DiffPatch:${gradle.parent.ext.diffpatch_version}"

implementation "org.ow2.asm:asm:${gradle.parent.ext.asm_version}"
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.gradle.api.tasks.Classpath;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.JavaExec;
import org.gradle.api.tasks.OutputFile;
Expand All @@ -17,6 +18,8 @@
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;

/**
* Runs <a href="https://github.com/neoforged/JavaSourceTransformer">JavaSourceTransformer</a> to apply
Expand All @@ -28,8 +31,8 @@ abstract class ApplyAccessTransformer extends JavaExec {
@InputFile
public abstract RegularFileProperty getInputJar();

@InputFile
public abstract RegularFileProperty getAccessTransformer();
@InputFiles
public abstract ConfigurableFileCollection getAccessTransformers();

@Input
public abstract Property<Boolean> getValidate();
Expand Down Expand Up @@ -59,13 +62,23 @@ public void exec() {
throw new UncheckedIOException("Failed to write libraries for JST.", exception);
}

args(
var args = new ArrayList<>(Arrays.asList(
"--enable-accesstransformers",
"--access-transformer", getAccessTransformer().getAsFile().get().getAbsolutePath(),
"--access-transformer-validation", getValidate().get() ? "error" : "log",
"--libraries-list", getLibrariesFile().getAsFile().get().getAbsolutePath(),
"--libraries-list", getLibrariesFile().getAsFile().get().getAbsolutePath()
));

for (var file : getAccessTransformers().getFiles()) {
args.addAll(Arrays.asList(
"--access-transformer", file.getAbsolutePath()
));
}

args.addAll(Arrays.asList(
getInputJar().getAsFile().get().getAbsolutePath(),
getOutputJar().getAsFile().get().getAbsolutePath());
getOutputJar().getAsFile().get().getAbsolutePath()));

args(args);

super.exec();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,18 @@
import javax.inject.Inject;

abstract class CreateCleanArtifacts extends CreateMinecraftArtifacts {
/**
* The unmodified downloaded client jar.
*/
@OutputFile
abstract RegularFileProperty getRawClientJar();

@OutputFile
abstract RegularFileProperty getCleanClientJar();

/**
* The unmodified downloaded server jar.
*/
@OutputFile
abstract RegularFileProperty getRawServerJar();

Expand All @@ -24,6 +33,7 @@ abstract class CreateCleanArtifacts extends CreateMinecraftArtifacts {

@Inject
public CreateCleanArtifacts() {
getAdditionalResults().put("node.downloadClient.output.output", getRawClientJar().getAsFile());
getAdditionalResults().put("node.stripClient.output.output", getCleanClientJar().getAsFile());
getAdditionalResults().put("node.downloadServer.output.output", getRawServerJar().getAsFile());
getAdditionalResults().put("node.stripServer.output.output", getCleanServerJar().getAsFile());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,6 @@ abstract class CreateUserDevConfig extends DefaultTask {
@Inject
public CreateUserDevConfig() {}

/**
* Toggles the launch type written to the userdev configuration between *dev and *userdev.
*/
@Input
abstract Property<Boolean> getForNeoDev();

@Input
abstract Property<String> getFmlVersion();

Expand Down Expand Up @@ -85,11 +79,12 @@ public void writeUserDevConfig() throws IOException {

for (var runType : RunType.values()) {
var launchTarget = switch (runType) {
case CLIENT -> "forgeclient";
case DATA -> "forgedata";
case GAME_TEST_SERVER, SERVER -> "forgeserver";
case JUNIT -> "forgejunit";
} + (getForNeoDev().get() ? "dev" : "userdev");
case CLIENT -> "neoforgeclientdev";
case CLIENT_DATA -> "neoforgeclientdatadev";
case SERVER_DATA -> "neoforgeserverdatadev";
case GAME_TEST_SERVER, SERVER -> "neoforgeserverdev";
case JUNIT -> "neoforgejunitdev";
};

List<String> args = new ArrayList<>();
Collections.addAll(args,
Expand All @@ -101,7 +96,7 @@ public void writeUserDevConfig() throws IOException {
"--version", getNeoForgeVersion().get());
}

if (runType == RunType.CLIENT || runType == RunType.DATA || runType == RunType.JUNIT) {
if (runType == RunType.CLIENT || runType == RunType.CLIENT_DATA || runType == RunType.JUNIT) {
Collections.addAll(args,
"--assetIndex", "{asset_index}",
"--assetsDir", "{assets_root}");
Expand Down Expand Up @@ -138,9 +133,9 @@ public void writeUserDevConfig() throws IOException {
"--add-opens", "java.base/java.lang.invoke=cpw.mods.securejarhandler",
"--add-exports", "java.base/sun.security.util=cpw.mods.securejarhandler",
"--add-exports", "jdk.naming.dns/com.sun.jndi.dns=java.naming"),
runType == RunType.CLIENT || runType == RunType.JUNIT,
runType == RunType.GAME_TEST_SERVER || runType == RunType.SERVER,
runType == RunType.DATA,
runType == RunType.CLIENT || runType == RunType.JUNIT || runType == RunType.CLIENT_DATA,
runType == RunType.GAME_TEST_SERVER || runType == RunType.SERVER || runType == RunType.SERVER_DATA,
runType == RunType.CLIENT_DATA || runType == RunType.SERVER_DATA,
runType == RunType.CLIENT || runType == RunType.GAME_TEST_SERVER,
runType == RunType.JUNIT,
Map.of(
Expand All @@ -158,7 +153,8 @@ public void writeUserDevConfig() throws IOException {

private enum RunType {
CLIENT("client"),
DATA("data"),
CLIENT_DATA("clientData"),
SERVER_DATA("serverData"),
GAME_TEST_SERVER("gameTestServer"),
SERVER("server"),
JUNIT("junit");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package net.neoforged.neodev;

import net.neoforged.neodev.utils.FileUtils;
import net.neoforged.neodev.utils.SerializablePredicate;
import net.neoforged.neodev.utils.structure.ClassInfo;
import net.neoforged.neodev.utils.structure.ClassStructureVisitor;
import net.neoforged.neodev.utils.structure.FieldInfo;
import net.neoforged.neodev.utils.structure.MethodInfo;
import org.gradle.api.DefaultTask;
import org.gradle.api.Named;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import org.objectweb.asm.Opcodes;

import javax.annotation.Nullable;
import java.io.IOException;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
* This task is used to generate access transformers based on a set of rules defined in the buildscript.
*/
public abstract class GenerateAccessTransformers extends DefaultTask {
public static final Modifier PUBLIC = new Modifier("public", false, Opcodes.ACC_PUBLIC);
public static final Modifier PROTECTED = new Modifier("protected", false, Opcodes.ACC_PUBLIC, Opcodes.ACC_PROTECTED);

@InputFile
public abstract RegularFileProperty getInput();

@OutputFile
public abstract RegularFileProperty getAccessTransformer();

@Input
public abstract ListProperty<AtGroup> getGroups();

@TaskAction
public void exec() throws IOException {
// First we collect all classes
var targets = ClassStructureVisitor.readJar(getInput().getAsFile().get());

var groupList = getGroups().get();

List<String>[] groups = new List[groupList.size()];
for (int i = 0; i < groupList.size(); i++) {
groups[i] = new ArrayList<>();
}

// Now we check each class against each group and see if the group wants to handle it
for (ClassInfo value : targets.values()) {
for (int i = 0; i < groupList.size(); i++) {
var group = groupList.get(i);
if (group.classMatch.test(value)) {
var lastInner = value.name().lastIndexOf("$");
// Skip anonymous classes
if (lastInner >= 0 && Character.isDigit(value.name().charAt(lastInner + 1))) {
continue;
}

// fieldMatch is non-null only for field ATs
if (group.fieldMatch != null) {
for (var field : value.fields()) {
if (group.fieldMatch.test(field) && !group.modifier.test(field.access())) {
groups[i].add(group.modifier.name + " " + value.name().replace('/', '.') + " " + field.name());
}
}
}
// methodMatch is non-null only for group ATs
else if (group.methodMatch != null) {
for (var method : value.methods()) {
if (group.methodMatch.test(method) && !group.modifier.test(method.access())) {
groups[i].add(group.modifier.name + " " + value.name().replace('/', '.') + " " + method.name() + method.descriptor());
}
}
}
// If there's neither a field nor a method predicate, this is a class AT
else if (!group.modifier.test(value.access().intValue())) {
groups[i].add(group.modifier.name + " " + value.name().replace('/', '.'));

// If we AT a record we must ensure that its constructors have the same AT
if (value.hasSuperclass("java/lang/Record")) {
for (MethodInfo method : value.methods()) {
if (method.name().equals("<init>")) {
groups[i].add(group.modifier.name + " " + value.name().replace('/', '.') + " " + method.name() + method.descriptor());
}
}
}
}
}
}
}

// Dump the ATs
var text = new StringBuilder();

text.append("# This file is generated based on the rules defined in the buildscript. DO NOT modify it manually.\n# Add more rules in the buildscript and then run the generateAccessTransformers task to update this file.\n\n");

for (int i = 0; i < groups.length; i++) {
// Check if the group found no targets. If it didn't, there's probably an error in the test and it should be reported
if (groups[i].isEmpty()) {
throw new IllegalStateException("Generated AT group '" + groupList.get(i).name + "' found no entries!");
}
text.append("# ").append(groupList.get(i).name).append('\n');
text.append(groups[i].stream().sorted().collect(Collectors.joining("\n")));
text.append('\n');

if (i < groups.length - 1) text.append('\n');
}

var outFile = getAccessTransformer().getAsFile().get().toPath();
if (!Files.exists(outFile.getParent())) {
Files.createDirectories(outFile.getParent());
}

FileUtils.writeStringSafe(outFile, text.toString(), StandardCharsets.UTF_8);
}

public void classGroup(String name, Modifier modifier, SerializablePredicate<ClassInfo> match) {
getGroups().add(new AtGroup(name, modifier, match, null, null));
}

public void methodGroup(String name, Modifier modifier, SerializablePredicate<ClassInfo> targetTest, SerializablePredicate<MethodInfo> methodTest) {
getGroups().add(new AtGroup(name, modifier, targetTest, methodTest, null));
}

public void fieldGroup(String name, Modifier modifier, SerializablePredicate<ClassInfo> targetTest, SerializablePredicate<FieldInfo> fieldTest) {
getGroups().add(new AtGroup(name, modifier, targetTest, null, fieldTest));
}

public <T extends Named> SerializablePredicate<T> named(String name) {
return target -> target.getName().equals(name);
}

public SerializablePredicate<ClassInfo> classesWithSuperclass(String superClass) {
return target -> target.hasSuperclass(superClass);
}

public SerializablePredicate<ClassInfo> innerClassesOf(String parent) {
var parentFullName = parent + "$";
return target -> target.name().startsWith(parentFullName);
}

public SerializablePredicate<MethodInfo> methodsReturning(String type) {
var endMatch = ")L" + type + ";";
return methodInfo -> methodInfo.descriptor().endsWith(endMatch);
}

public SerializablePredicate<FieldInfo> fieldsOfType(SerializablePredicate<ClassInfo> type) {
return value -> type.test(value.type());
}

public <T> SerializablePredicate<T> matchAny() {
return value -> true;
}

public record AtGroup(String name, Modifier modifier, SerializablePredicate<ClassInfo> classMatch,
@Nullable SerializablePredicate<MethodInfo> methodMatch, @Nullable SerializablePredicate<FieldInfo> fieldMatch) implements Serializable {
}

public record Modifier(String name, boolean isFinal, int... validOpcodes) implements Serializable {
public boolean test(int value) {
if (isFinal && (value & Opcodes.ACC_FINAL) == 0) return false;

for (int validOpcode : validOpcodes) {
if ((value & validOpcode) != 0) {
return true;
}
}
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public void apply(Project project) {
var tasks = project.getTasks();
var neoDevBuildDir = project.getLayout().getBuildDirectory().dir("neodev");

var rawNeoFormVersion = project.getProviders().gradleProperty("neoform_version");
var minecraftVersion = project.getProviders().gradleProperty("minecraft_version");
var mcAndNeoFormVersion = minecraftVersion.zip(rawNeoFormVersion, (mc, nf) -> mc + "-" + nf);

var extension = project.getExtensions().create(NeoDevExtension.NAME, NeoDevExtension.class);

var createSources = NeoDevPlugin.configureMinecraftDecompilation(project);
Expand Down Expand Up @@ -54,7 +58,8 @@ public void apply(Project project) {
project.files(),
modulePath -> {},
legacyClasspath -> {},
downloadAssets.flatMap(DownloadAssets::getAssetPropertiesFile)
downloadAssets.flatMap(DownloadAssets::getAssetPropertiesFile),
mcAndNeoFormVersion
);
}
}
Loading

0 comments on commit 73e72d3

Please sign in to comment.