Skip to content

Commit

Permalink
Merge branch '1.21.1' into elements_model_root_xform
Browse files Browse the repository at this point in the history
  • Loading branch information
XFactHD authored Oct 24, 2024
2 parents cce5c75 + 718fd71 commit 5749f6a
Show file tree
Hide file tree
Showing 181 changed files with 4,916 additions and 3,199 deletions.
14 changes: 6 additions & 8 deletions .github/workflows/build-prs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,13 @@ jobs:
run:
git switch -C pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.ref }}

- name: Validate wrapper
uses: gradle/actions/wrapper-validation@v3

- name: Setup JDK 21
uses: actions/setup-java@v2
uses: neoforged/actions/setup-java@main
with:
java-version: '21'
distribution: 'temurin'
java-version: 21

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
uses: gradle/actions/setup-gradle@v4
with:
cache-read-only: false

Expand All @@ -52,10 +48,12 @@ jobs:
run: ./gradlew assemble checkFormatting

- name: Run JCC
if: ${{ ! startsWith(github.event.pull_request.head.ref, 'refs/heads/port/') }}
run: ./gradlew checkJarCompatibility

- name: Upload JCC
if: ${{ ! startsWith(github.event.pull_request.head.ref, 'refs/heads/port/') }}
uses: neoforged/action-jar-compatibility/upload@v1

- name: Publish artifacts
uses: neoforged/action-pr-publishing/upload@v1
uses: neoforged/action-pr-publishing/upload@v1
7 changes: 3 additions & 4 deletions .github/workflows/check-local-changes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,12 @@ jobs:
git switch -C pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.ref }}

- name: Setup JDK 21
uses: actions/setup-java@v2
uses: neoforged/actions/setup-java@main
with:
java-version: '21'
distribution: 'temurin'
java-version: 21

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
uses: gradle/actions/setup-gradle@v4
with:
cache-read-only: false

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-jcc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:

jobs:
publish-jcc:
if: true
if: ${{ ! startsWith(github.event.workflow_run.head_branch, 'port/') }}
uses: neoforged/actions/.github/workflows/publish-jcc.yml@main
with:
beta_version_pattern: .*-beta.*
Expand Down
7 changes: 3 additions & 4 deletions .github/workflows/test-prs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,12 @@ jobs:
git switch -C pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.ref }}

- name: Setup JDK 21
uses: actions/setup-java@v2
uses: neoforged/actions/setup-java@main
with:
java-version: '21'
distribution: 'temurin'
java-version: 21

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
uses: gradle/actions/setup-gradle@v4
with:
cache-read-only: false

Expand Down
46 changes: 46 additions & 0 deletions coremods/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
plugins {
id 'java-library'
id 'com.diffplug.spotless'
id 'net.neoforged.licenser'
id 'neoforge.formatting-conventions'
}

repositories {
maven { url = 'https://maven.neoforged.net/releases' }
maven {
name 'Mojang'
url 'https://libraries.minecraft.net'
}
mavenCentral()
}

jar {
manifest {
attributes(
"Automatic-Module-Name": "neoforge.coremods",
FMLModType: "LIBRARY",
)
}
}

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(project.java_version))
}
}

dependencies {
compileOnly "org.jetbrains:annotations:${project.jetbrains_annotations_version}"
compileOnly "com.google.code.gson:gson:${gson_version}"
compileOnly "org.slf4j:slf4j-api:${slf4j_api_version}"
compileOnly "net.neoforged.fancymodloader:loader:${project.fancy_mod_loader_version}"
}

license {
header = rootProject.file('codeformat/HEADER.txt')
include '**/*.java'
}

tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.coremods;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import org.jetbrains.annotations.Nullable;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;

final class CoremodUtils {
private static final Gson GSON = new Gson();

CoremodUtils() {}

static <T> T loadResource(String filename, TypeToken<T> type) {
var stream = NeoForgeCoreMod.class.getResourceAsStream(filename);
if (stream == null) {
throw new IllegalStateException("Missing resource: " + filename);
}
try (var reader = new InputStreamReader(stream, StandardCharsets.UTF_8)) {
return GSON.fromJson(reader, type);
} catch (IOException e) {
throw new IllegalStateException("Failed to read JSON resource " + filename);
}
}

static <T> T loadResource(String filename, Class<T> type) {
return loadResource(filename, TypeToken.get(type));
}

static FieldNode getFieldByName(ClassNode classNode, String fieldName) {
FieldNode foundField = null;
for (var fieldNode : classNode.fields) {
if (Objects.equals(fieldNode.name, fieldName)) {
if (foundField == null) {
foundField = fieldNode;
} else {
throw new IllegalStateException("Found multiple fields with name " + fieldName + " in " + classNode.name);
}
}
}
if (foundField == null) {
throw new IllegalStateException("No field with name " + fieldName + " found in class " + classNode.name);
}
return foundField;
}

static MethodNode getMethodByDescriptor(ClassNode classNode, @Nullable String methodName, String methodSignature) {
MethodNode foundMethod = null;
for (var methodNode : classNode.methods) {
if (Objects.equals(methodNode.desc, methodSignature)
&& (methodName == null || Objects.equals(methodNode.name, methodName))) {
if (foundMethod == null) {
foundMethod = methodNode;
} else {
throw new IllegalStateException("Found duplicate method with signature " + methodSignature + " in " + classNode.name);
}
}
}

if (foundMethod == null) {
if (methodName != null) {
throw new IllegalStateException("Unable to find method " + methodSignature + " with name " + methodName + " in " + classNode.name);
} else {
throw new IllegalStateException("Unable to find method " + methodSignature + " in " + classNode.name);
}
}
return foundMethod;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.coremods;

import cpw.mods.modlauncher.api.ITransformer;
import cpw.mods.modlauncher.api.ITransformerVotingContext;
import cpw.mods.modlauncher.api.TargetType;
import cpw.mods.modlauncher.api.TransformerVoteResult;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodInsnNode;

/**
* Redirect calls to one method to another.
*/
public class MethodRedirector implements ITransformer<ClassNode> {
private final Map<String, List<MethodRedirection>> redirectionsByClass = new HashMap<>();
private final Set<Target<ClassNode>> targets = new HashSet<>();

private static final List<MethodRedirection> REDIRECTIONS = List.of(
new MethodRedirection(
Opcodes.INVOKEVIRTUAL,
"finalizeSpawn",
"(Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/world/DifficultyInstance;Lnet/minecraft/world/entity/MobSpawnType;Lnet/minecraft/world/entity/SpawnGroupData;)Lnet/minecraft/world/entity/SpawnGroupData;",
"finalize_spawn_targets.json",
methodInsnNode -> new MethodInsnNode(
Opcodes.INVOKESTATIC,
"net/neoforged/neoforge/event/EventHooks",
"finalizeMobSpawn",
"(Lnet/minecraft/world/entity/Mob;Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/world/DifficultyInstance;Lnet/minecraft/world/entity/MobSpawnType;Lnet/minecraft/world/entity/SpawnGroupData;)Lnet/minecraft/world/entity/SpawnGroupData;",
false)));

public MethodRedirector() {
for (var redirection : REDIRECTIONS) {
var targetClassNames = CoremodUtils.loadResource(redirection.targetClassListFile, String[].class);
for (var targetClassName : targetClassNames) {
targets.add(Target.targetClass(targetClassName));
var redirections = redirectionsByClass.computeIfAbsent(targetClassName, s -> new ArrayList<>());
redirections.add(redirection);
}
}
}

@Override
public TargetType<ClassNode> getTargetType() {
return TargetType.CLASS;
}

@Override
public Set<Target<ClassNode>> targets() {
return targets;
}

@Override
public ClassNode transform(ClassNode classNode, ITransformerVotingContext votingContext) {
var redirections = redirectionsByClass.getOrDefault(classNode.name, Collections.emptyList());

var methods = classNode.methods;
for (var method : methods) {
var instr = method.instructions;
for (var i = 0; i < instr.size(); i++) {
var node = instr.get(i);
if (node instanceof MethodInsnNode methodInsnNode) {
for (var redirection : redirections) {
if (redirection.invokeOpCode == methodInsnNode.getOpcode()
&& redirection.methodName.equals(methodInsnNode.name)
&& redirection.methodDescriptor.equals(methodInsnNode.desc)) {
// Found a match for the target method
instr.set(
methodInsnNode,
redirection.redirector.apply(methodInsnNode));
}
}
}
}
}
return classNode;
}

@Override
public TransformerVoteResult castVote(ITransformerVotingContext context) {
return TransformerVoteResult.YES;
}

private record MethodRedirection(
int invokeOpCode,
String methodName,
String methodDescriptor,
String targetClassListFile,
Function<MethodInsnNode, MethodInsnNode> redirector) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.coremods;

import cpw.mods.modlauncher.api.ITransformer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import net.neoforged.neoforgespi.coremod.ICoreMod;

public class NeoForgeCoreMod implements ICoreMod {
@Override
public Iterable<? extends ITransformer<?>> getTransformers() {
List<ITransformer<?>> transformers = new ArrayList<>();
transformers.add(new ReplaceFieldWithGetterAccess("net.minecraft.world.level.biome.Biome", Map.of(
"climateSettings", "getModifiedClimateSettings",
"specialEffects", "getModifiedSpecialEffects")));
transformers.add(new ReplaceFieldWithGetterAccess("net.minecraft.world.level.levelgen.structure.Structure", Map.of(
"settings", "getModifiedStructureSettings")));
transformers.add(new ReplaceFieldWithGetterAccess("net.minecraft.world.level.block.FlowerPotBlock", Map.of(
"potted", "getPotted")));

transformers.add(new MethodRedirector());

return transformers;
}
}
Loading

0 comments on commit 5749f6a

Please sign in to comment.