aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--javaplugin/src/main/java/moe/nea/firmament/javaplugin/IntermediaryMethodReplacer.java13
-rw-r--r--javaplugin/src/main/java/moe/nea/firmament/javaplugin/MappingTree.java22
-rw-r--r--src/main/java/moe/nea/firmament/init/HandledScreenRiser.java61
-rw-r--r--src/main/java/moe/nea/firmament/init/Intermediary.java115
-rw-r--r--src/main/java/moe/nea/firmament/init/RiserUtils.java7
-rw-r--r--src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java52
6 files changed, 144 insertions, 126 deletions
diff --git a/javaplugin/src/main/java/moe/nea/firmament/javaplugin/IntermediaryMethodReplacer.java b/javaplugin/src/main/java/moe/nea/firmament/javaplugin/IntermediaryMethodReplacer.java
index cb87b20..d45563b 100644
--- a/javaplugin/src/main/java/moe/nea/firmament/javaplugin/IntermediaryMethodReplacer.java
+++ b/javaplugin/src/main/java/moe/nea/firmament/javaplugin/IntermediaryMethodReplacer.java
@@ -31,7 +31,7 @@ public class IntermediaryMethodReplacer extends TreeScanner<Void, Void> {
public void replaceMethodName(JCTree.JCMethodInvocation node) {
var select = node.getMethodSelect();
if (!(select instanceof JCTree.JCFieldAccess fieldAccess)) return;
- if (!fieldAccess.name.contentEquals("methodName")) return;
+ if (!fieldAccess.name.contentEquals("intermediaryMethod")) return;
if (!(node.args.head instanceof JCTree.JCMemberReference methodReference)) {
plugin.utils.reportError(sourceFile, node, "Please provide a Class::method reference directly (and nothing else)");
return;
@@ -43,14 +43,17 @@ public class IntermediaryMethodReplacer extends TreeScanner<Void, Void> {
type.tsym.flatName().toString(),
clearName
);
- fieldAccess.name = plugin.names.fromString("id");
- node.args = List.of(plugin.treeMaker.Literal(intermediaryName));
+ fieldAccess.name = plugin.names.fromString("ofMethod");
+ var args = List.<JCTree.JCExpression>of(plugin.treeMaker.Literal(intermediaryName.interMethodName()));
+ args.tail = List.of(plugin.treeMaker.Literal(intermediaryName.interClassName()));
+ args.tail.tail = node.args.tail;
+ node.args = args;
}
public void replaceClassName(JCTree.JCMethodInvocation node) {
var select = node.getMethodSelect();
if (!(select instanceof JCTree.JCFieldAccess fieldAccess)) return;
- if (!fieldAccess.name.contentEquals("className")) return;
+ if (!fieldAccess.name.contentEquals("intermediaryClass")) return;
if (node.getTypeArguments().size() != 1) {
plugin.utils.reportError(sourceFile, node, "You need to explicitly provide the class you want the intermediary name for");
return;
@@ -63,7 +66,7 @@ public class IntermediaryMethodReplacer extends TreeScanner<Void, Void> {
plugin.utils.reportError(sourceFile, node, "Unknown class name " + sourceName);
return;
}
- fieldAccess.name = plugin.names.fromString("id");
+ fieldAccess.name = plugin.names.fromString("ofIntermediaryClass");
node.typeargs = List.nil();
node.args = List.of(plugin.treeMaker.Literal(mappedName));
}
diff --git a/javaplugin/src/main/java/moe/nea/firmament/javaplugin/MappingTree.java b/javaplugin/src/main/java/moe/nea/firmament/javaplugin/MappingTree.java
index eef5f9a..36713b6 100644
--- a/javaplugin/src/main/java/moe/nea/firmament/javaplugin/MappingTree.java
+++ b/javaplugin/src/main/java/moe/nea/firmament/javaplugin/MappingTree.java
@@ -18,15 +18,21 @@ public class MappingTree {
if (sourceIndex < 0)
throw new RuntimeException("Could not find source namespace " + sourceNamespace + " in mappings file.");
this.classLookup = tinyV2File
- .getClassEntries()
- .stream()
- .collect(Collectors.toMap(it -> it.getClassNames().get(sourceIndex), it -> it));
+ .getClassEntries()
+ .stream()
+ .collect(Collectors.toMap(it -> it.getClassNames().get(sourceIndex), it -> it));
targetIndex = tinyV2File.getHeader().getNamespaces().indexOf(targetNamespace);
if (targetIndex < 0)
throw new RuntimeException("Could not find target namespace " + targetNamespace + " in mappings file.");
}
- public String resolveMethodToIntermediary(String className, String methodName) {
+ public record MethodCoordinate(
+ String interClassName,
+ String interMethodName
+ ) {
+ }
+
+ public MethodCoordinate resolveMethodToIntermediary(String className, String methodName) {
var classData = classLookup.get(className.replace(".", "/"));
TinyMethod candidate = null;
for (TinyMethod method : classData.getMethods()) {
@@ -37,7 +43,11 @@ public class MappingTree {
candidate = method;
}
}
- return candidate.getMethodNames().get(targetIndex);
+ if (candidate == null)
+ throw new RuntimeException("Couldd not find candidate for method " + className + "." + methodName);
+ return new MethodCoordinate(
+ classData.getClassNames().get(targetIndex),
+ candidate.getMethodNames().get(targetIndex));
}
public String resolveClassToIntermediary(String className) {
@@ -46,6 +56,6 @@ public class MappingTree {
return null;
}
return cls.getClassNames().get(targetIndex)
- .replace("/", ".");
+ .replace("/", ".");
}
}
diff --git a/src/main/java/moe/nea/firmament/init/HandledScreenRiser.java b/src/main/java/moe/nea/firmament/init/HandledScreenRiser.java
index cb0058d..605e7ac 100644
--- a/src/main/java/moe/nea/firmament/init/HandledScreenRiser.java
+++ b/src/main/java/moe/nea/firmament/init/HandledScreenRiser.java
@@ -23,35 +23,36 @@ import java.lang.reflect.Modifier;
import java.util.function.Consumer;
public class HandledScreenRiser extends RiserUtils {
- @IntermediaryName(Screen.class)
- String Screen;
- @IntermediaryName(KeyInput.class)
- String KeyInput;
- @IntermediaryName(CharInput.class)
- String CharInput;
- @IntermediaryName(HandledScreen.class)
- String HandledScreen;
- Type mouseScrolledDesc = Type.getMethodType(Type.BOOLEAN_TYPE, Type.DOUBLE_TYPE, Type.DOUBLE_TYPE, Type.DOUBLE_TYPE, Type.DOUBLE_TYPE);
- String mouseScrolled = remapper.mapMethodName("intermediary", Intermediary.<Element>className(),
- Intermediary.methodName(Element::mouseScrolled),
- mouseScrolledDesc.getDescriptor());
- // boolean keyReleased(int keyCode, int scanCode, int modifiers)
- Type keyReleasedDesc = Type.getMethodType(Type.BOOLEAN_TYPE, getTypeForClassName(KeyInput));
- String keyReleased = remapper.mapMethodName("intermediary", Intermediary.<Element>className(),
- Intermediary.methodName(Element::keyReleased),
- keyReleasedDesc.getDescriptor());
- // public boolean charTyped(char chr, int modifiers)
- Type charTypedDesc = Type.getMethodType(Type.BOOLEAN_TYPE, getTypeForClassName(CharInput));
- String charTyped = remapper.mapMethodName("intermediary", Intermediary.<Element>className(),
- Intermediary.methodName(Element::charTyped),
- charTypedDesc.getDescriptor());
+ Intermediary.InterClass Screen = Intermediary.<Screen>intermediaryClass();
+ Intermediary.InterClass KeyInput = Intermediary.<KeyInput>intermediaryClass();
+ Intermediary.InterClass CharInput = Intermediary.<CharInput>intermediaryClass();
+ Intermediary.InterClass HandledScreen = Intermediary.<HandledScreen>intermediaryClass();
+ Intermediary.InterMethod mouseScrolled = Intermediary.intermediaryMethod(
+ Element::mouseScrolled,
+ Intermediary.ofClass(boolean.class),
+ Intermediary.ofClass(double.class),
+ Intermediary.ofClass(double.class),
+ Intermediary.ofClass(double.class),
+ Intermediary.ofClass(double.class)
+ );
+ Intermediary.InterMethod keyReleased = Intermediary.intermediaryMethod(
+ Element::keyReleased,
+ Intermediary.ofClass(boolean.class),
+ KeyInput
+ );
+ Intermediary.InterMethod charTyped = Intermediary.intermediaryMethod(
+ Element::charTyped,
+ Intermediary.ofClass(boolean.class),
+ CharInput
+ );
+
@Override
public void addTinkerers() {
- ClassTinkerers.addTransformation(HandledScreen, this::addMouseScroll, true);
- ClassTinkerers.addTransformation(HandledScreen, this::addKeyReleased, true);
- ClassTinkerers.addTransformation(HandledScreen, this::addCharTyped, true);
+ addTransformation(HandledScreen, this::addMouseScroll, true);
+ addTransformation(HandledScreen, this::addKeyReleased, true);
+ addTransformation(HandledScreen, this::addCharTyped, true);
}
/**
@@ -85,7 +86,7 @@ public class HandledScreenRiser extends RiserUtils {
void addKeyReleased(ClassNode classNode) {
addSuperInjector(
- classNode, keyReleased, keyReleasedDesc, "keyReleased_firmament",
+ classNode, keyReleased.mapped(), keyReleased.mappedDesc(), "keyReleased_firmament",
insns -> {
// ALOAD 0, load this
insns.add(new VarInsnNode(Opcodes.ALOAD, 0));
@@ -96,7 +97,7 @@ public class HandledScreenRiser extends RiserUtils {
void addCharTyped(ClassNode classNode) {
addSuperInjector(
- classNode, charTyped, charTypedDesc, "charTyped_firmament",
+ classNode, charTyped.mapped(), charTyped.mappedDesc(), "charTyped_firmament",
insns -> {
// ALOAD 0, load this
insns.add(new VarInsnNode(Opcodes.ALOAD, 0));
@@ -124,7 +125,7 @@ public class HandledScreenRiser extends RiserUtils {
var insns = keyReleasedNode.instructions;
loadArgs.accept(insns);
// INVOKESPECIAL call super method
- insns.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, getTypeForClassName(Screen).getInternalName(),
+ insns.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, Screen.mapped().getInternalName(),
name, desc.getDescriptor()));
// IRETURN return int on stack (booleans are int at runtime)
insns.add(new InsnNode(Opcodes.IRETURN));
@@ -133,7 +134,7 @@ public class HandledScreenRiser extends RiserUtils {
insertTrueHandler(keyReleasedNode, loadArgs, insns -> {
// INVOKEVIRTUAL call custom handler
insns.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
- getTypeForClassName(HandledScreen).getInternalName(),
+ HandledScreen.mapped().getInternalName(),
firmamentName,
desc.getDescriptor()));
});
@@ -142,7 +143,7 @@ public class HandledScreenRiser extends RiserUtils {
void addMouseScroll(ClassNode classNode) {
addSuperInjector(
- classNode, mouseScrolled, mouseScrolledDesc, "mouseScrolled_firmament",
+ classNode, mouseScrolled.mapped(), mouseScrolled.mappedDesc(), "mouseScrolled_firmament",
insns -> {
// ALOAD 0, load this
insns.add(new VarInsnNode(Opcodes.ALOAD, 0));
diff --git a/src/main/java/moe/nea/firmament/init/Intermediary.java b/src/main/java/moe/nea/firmament/init/Intermediary.java
index 61494d7..3513a6b 100644
--- a/src/main/java/moe/nea/firmament/init/Intermediary.java
+++ b/src/main/java/moe/nea/firmament/init/Intermediary.java
@@ -7,57 +7,66 @@ import org.objectweb.asm.Type;
import java.util.List;
public class Intermediary {
- private static final MappingResolver RESOLVER = FabricLoader.getInstance().getMappingResolver();
-
- static String methodName(Object object) {
- throw new AssertionError("Cannot be called at runtime");
- }
-
- static <T> String className() {
- throw new AssertionError("Cannot be called at runtime");
- }
-
- static String id(String source) {
- return source;
- }
-
-// public record Class(
-// Type intermediaryClass
-// ) {
-// public Class(String intermediaryClass) {
-// this(Type.getObjectType(intermediaryClass.replace('.', '/')));
-// }
-//
-// public String getMappedName() {
-// return RESOLVER.mapClassName("intermediary", intermediaryClass.getInternalName()
-// .replace('/', '.'));
-// }
-// }
-//
-// public record Method(
-// Type intermediaryClassName,
-// String intermediaryMethodName,
-// Type intermediaryReturnType,
-// List<Type> intermediaryArgumentTypes
-// ) {
-// public Method(
-// String intermediaryClassName,
-// String intermediaryMethodName,
-// String intermediaryReturnType,
-// String... intermediaryArgumentTypes
-// ) {
-// this(intermediaryClassName, intermediaryMethodName, intermediaryReturnType, List.of(intermediaryArgumentTypes));
-// }
-//
-// public String getMappedMethodName() {
-// return RESOLVER.mapMethodName("intermediary",
-// intermediaryClassName.getInternalName().replace('/', '.'));
-// }
-//
-// public Type getIntermediaryDescriptor() {
-// return Type.getMethodType(intermediaryReturnType, intermediaryArgumentTypes.toArray(Type[]::new));
-// }
-//
-//
-// }
+ private static final MappingResolver RESOLVER = FabricLoader.getInstance().getMappingResolver();
+
+ static InterMethod intermediaryMethod(Object object, InterClass returnType, InterClass... args) {
+ throw new AssertionError("Cannot be called at runtime");
+ }
+
+ static <T> InterClass intermediaryClass() {
+ throw new AssertionError("Cannot be called at runtime");
+ }
+
+ public static InterClass ofIntermediaryClass(String interClass) {
+ return new InterClass(Type.getObjectType(interClass.replace('.', '/')));
+ }
+
+ public static InterClass ofClass(Class<?> unmappedClass) {
+ return new InterClass(Type.getType(unmappedClass));
+ }
+
+ public static InterMethod ofMethod(String intermediary, String ownerType, InterClass returnType, InterClass... argTypes) {
+ return new InterMethod(intermediary, ofIntermediaryClass(ownerType), returnType, List.of(argTypes));
+ }
+
+ public record InterClass(
+ Type intermediary
+ ) {
+ public Type mapped() {
+ if (intermediary().getSort() != Type.OBJECT)
+ return intermediary();
+ return Type.getObjectType(RESOLVER.mapClassName("intermediary", intermediary().getClassName())
+ .replace('.', '/'));
+ }
+ }
+
+ public record InterMethod(
+ String intermediary,
+ InterClass ownerType,
+ InterClass returnType,
+ List<InterClass> argumentTypes
+ ) {
+ public Type intermediaryDesc() {
+ return Type.getMethodType(
+ returnType.intermediary(),
+ argumentTypes().stream().map(InterClass::intermediary).toArray(Type[]::new)
+ );
+ }
+
+ public Type mappedDesc() {
+ return Type.getMethodType(
+ returnType.mapped(),
+ argumentTypes().stream().map(InterClass::mapped).toArray(Type[]::new)
+ );
+ }
+
+ public String mapped() {
+ return RESOLVER.mapMethodName(
+ "intermediary",
+ ownerType.intermediary().getClassName(),
+ intermediary(),
+ intermediaryDesc().getDescriptor()
+ );
+ }
+ }
}
diff --git a/src/main/java/moe/nea/firmament/init/RiserUtils.java b/src/main/java/moe/nea/firmament/init/RiserUtils.java
index c1c8fd1..ad4ac8f 100644
--- a/src/main/java/moe/nea/firmament/init/RiserUtils.java
+++ b/src/main/java/moe/nea/firmament/init/RiserUtils.java
@@ -1,12 +1,15 @@
package moe.nea.firmament.init;
+import me.shedaniel.mm.api.ClassTinkerers;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.MappingResolver;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
+import java.util.function.Consumer;
+
public abstract class RiserUtils {
protected Type getTypeForClassName(String className) {
return Type.getObjectType(className.replace('.', '/'));
@@ -24,4 +27,8 @@ public abstract class RiserUtils {
return null;
}
+ public void addTransformation(Intermediary.InterClass interClass, Consumer<ClassNode> transformer, boolean post) {
+ ClassTinkerers.addTransformation(interClass.mapped().getClassName(), transformer, post);
+ }
+
}
diff --git a/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java b/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java
index 8b65946..03c63b3 100644
--- a/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java
+++ b/src/main/java/moe/nea/firmament/init/SectionBuilderRiser.java
@@ -1,6 +1,5 @@
package moe.nea.firmament.init;
-import me.shedaniel.mm.api.ClassTinkerers;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.block.BlockRenderManager;
@@ -19,36 +18,24 @@ import org.objectweb.asm.tree.VarInsnNode;
public class SectionBuilderRiser extends RiserUtils {
- @IntermediaryName(SectionBuilder.class)
- String SectionBuilder;
- @IntermediaryName(BlockPos.class)
- String BlockPos;
- @IntermediaryName(BlockRenderManager.class)
- String BlockRenderManager;
- @IntermediaryName(BlockState.class)
- String BlockState;
- @IntermediaryName(BlockStateModel.class)
- String BlockStateModel;
+ Intermediary.InterClass SectionBuilder = Intermediary.<SectionBuilder>intermediaryClass();
+ Intermediary.InterClass BlockPos = Intermediary.<BlockPos>intermediaryClass();
+ Intermediary.InterClass BlockRenderManager = Intermediary.<BlockRenderManager>intermediaryClass();
+ Intermediary.InterClass BlockState = Intermediary.<BlockState>intermediaryClass();
+ Intermediary.InterClass BlockStateModel = Intermediary.<BlockStateModel>intermediaryClass();
String CustomBlockTextures = "moe.nea.firmament.features.texturepack.CustomBlockTextures";
- Type getModelDesc = Type.getMethodType(
- getTypeForClassName(BlockRenderManager),
- getTypeForClassName(BlockState)
- );
- String getModel = remapper.mapMethodName(
- "intermediary",
- Intermediary.<BlockRenderManager>className(),
- Intermediary.methodName(net.minecraft.client.render.block.BlockRenderManager::getModel),
- Type.getMethodDescriptor(
- getTypeForClassName(Intermediary.<BlockStateModel>className()),
- getTypeForClassName(Intermediary.<BlockState>className())
- )
- );
+ Intermediary.InterMethod getModel =
+ Intermediary.intermediaryMethod(
+ net.minecraft.client.render.block.BlockRenderManager::getModel,
+ BlockStateModel,
+ BlockState
+ );
@Override
public void addTinkerers() {
if (FabricLoader.getInstance().isModLoaded("fabric-renderer-indigo"))
- ClassTinkerers.addTransformation(SectionBuilder, this::handle, true);
+ addTransformation(SectionBuilder, this::handle, true);
}
private void handle(ClassNode classNode) {
@@ -67,10 +54,10 @@ public class SectionBuilderRiser extends RiserUtils {
private void handleIndigo(MethodNode method) {
LocalVariableNode blockPosVar = null, blockStateVar = null;
for (LocalVariableNode localVariable : method.localVariables) {
- if (Type.getType(localVariable.desc).equals(getTypeForClassName(BlockPos))) {
+ if (Type.getType(localVariable.desc).equals(BlockPos.mapped())) {
blockPosVar = localVariable;
}
- if (Type.getType(localVariable.desc).equals(getTypeForClassName(BlockState))) {
+ if (Type.getType(localVariable.desc).equals(BlockState.mapped())) {
blockStateVar = localVariable;
}
}
@@ -81,7 +68,8 @@ public class SectionBuilderRiser extends RiserUtils {
for (AbstractInsnNode instruction : method.instructions) {
if (instruction.getOpcode() != Opcodes.INVOKEVIRTUAL) continue;
var methodInsn = (MethodInsnNode) instruction;
- if (!(methodInsn.name.equals(getModel) && Type.getObjectType(methodInsn.owner).equals(getTypeForClassName(BlockRenderManager))))
+ if (!(methodInsn.name.equals(getModel.mapped()) &&
+ Type.getObjectType(methodInsn.owner).equals(BlockRenderManager.mapped())))
continue;
method.instructions.insertBefore(
methodInsn,
@@ -106,10 +94,10 @@ public class SectionBuilderRiser extends RiserUtils {
getTypeForClassName(CustomBlockTextures).getInternalName(),
"patchIndigo",
Type.getMethodDescriptor(
- getTypeForClassName(BlockStateModel),
- getTypeForClassName(BlockStateModel),
- getTypeForClassName(BlockPos),
- getTypeForClassName(BlockState)),
+ (BlockStateModel).mapped(),
+ (BlockStateModel).mapped(),
+ (BlockPos).mapped(),
+ (BlockState).mapped()),
false
));
method.instructions.insert(methodInsn, insnList);