feat: Add Storage overlay search

This commit is contained in:
Linnea Gräf
2024-11-18 20:53:20 +01:00
parent d37d13daca
commit 139fa705b3
9 changed files with 237 additions and 73 deletions

View File

@@ -32,12 +32,18 @@ public class HandledScreenRiser extends RiserUtils {
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, Type.CHAR_TYPE, Type.INT_TYPE);
String charTyped = remapper.mapMethodName("intermediary", Intermediary.<Element>className(),
Intermediary.methodName(Element::charTyped),
charTypedDesc.getDescriptor());
@Override
public void addTinkerers() {
ClassTinkerers.addTransformation(HandledScreen, this::addMouseScroll, true);
ClassTinkerers.addTransformation(HandledScreen, this::addKeyReleased, true);
ClassTinkerers.addTransformation(HandledScreen, this::addCharTyped, true);
}
/**
@@ -70,86 +76,77 @@ public class HandledScreenRiser extends RiserUtils {
}
void addKeyReleased(ClassNode classNode) {
var keyReleasedNode = findMethod(classNode, keyReleased, keyReleasedDesc);
addSuperInjector(
classNode, keyReleased, keyReleasedDesc, "keyReleased_firmament",
insns -> {
// ALOAD 0, load this
insns.add(new VarInsnNode(Opcodes.ALOAD, 0));
// ILOAD 1-3, load args
insns.add(new VarInsnNode(Opcodes.ILOAD, 1));
insns.add(new VarInsnNode(Opcodes.ILOAD, 2));
insns.add(new VarInsnNode(Opcodes.ILOAD, 3));
});
}
void addCharTyped(ClassNode classNode) {
addSuperInjector(
classNode, charTyped, charTypedDesc, "charTyped_firmament",
insns -> {
// ALOAD 0, load this
insns.add(new VarInsnNode(Opcodes.ALOAD, 0));
// ILOAD 1-2, load args. chars = ints
insns.add(new VarInsnNode(Opcodes.ILOAD, 1));
insns.add(new VarInsnNode(Opcodes.ILOAD, 2));
});
}
void addSuperInjector(
ClassNode classNode,
String name,
Type desc,
String firmamentName,
Consumer<InsnList> loadArgs
) {
var keyReleasedNode = findMethod(classNode, name, desc);
if (keyReleasedNode == null) {
keyReleasedNode = new MethodNode(
Modifier.PUBLIC,
keyReleased,
keyReleasedDesc.getDescriptor(),
name,
desc.getDescriptor(),
null,
new String[0]
);
var insns = keyReleasedNode.instructions;
// ALOAD 0, load this
insns.add(new VarInsnNode(Opcodes.ALOAD, 0));
// ILOAD 1-3, load args
insns.add(new VarInsnNode(Opcodes.ILOAD, 1));
insns.add(new VarInsnNode(Opcodes.ILOAD, 2));
insns.add(new VarInsnNode(Opcodes.ILOAD, 3));
loadArgs.accept(insns);
// INVOKESPECIAL call super method
insns.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, getTypeForClassName(Screen).getInternalName(),
keyReleased, keyReleasedDesc.getDescriptor()));
name, desc.getDescriptor()));
// IRETURN return int on stack (booleans are int at runtime)
insns.add(new InsnNode(Opcodes.IRETURN));
classNode.methods.add(keyReleasedNode);
}
insertTrueHandler(keyReleasedNode, insns -> {
// ALOAD 0, load this
insns.add(new VarInsnNode(Opcodes.ALOAD, 0));
// ILOAD 1-3, load args
insns.add(new VarInsnNode(Opcodes.ILOAD, 1));
insns.add(new VarInsnNode(Opcodes.ILOAD, 2));
insns.add(new VarInsnNode(Opcodes.ILOAD, 3));
}, insns -> {
insertTrueHandler(keyReleasedNode, loadArgs, insns -> {
// INVOKEVIRTUAL call custom handler
insns.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
getTypeForClassName(HandledScreen).getInternalName(),
"keyReleased_firmament",
keyReleasedDesc.getDescriptor()));
firmamentName,
desc.getDescriptor()));
});
}
void addMouseScroll(ClassNode classNode) {
MethodNode mouseScrolledNode = findMethod(classNode, mouseScrolled, mouseScrolledDesc);
if (mouseScrolledNode == null) {
mouseScrolledNode = new MethodNode(
Modifier.PUBLIC,
mouseScrolled,
mouseScrolledDesc.getDescriptor(),
null,
new String[0]
);
var insns = mouseScrolledNode.instructions;
// ALOAD 0, load this
insns.add(new VarInsnNode(Opcodes.ALOAD, 0));
// DLOAD 1-4, load the 4 argument doubles. Note that since doubles are two entries wide we skip 2 each time.
insns.add(new VarInsnNode(Opcodes.DLOAD, 1));
insns.add(new VarInsnNode(Opcodes.DLOAD, 3));
insns.add(new VarInsnNode(Opcodes.DLOAD, 5));
insns.add(new VarInsnNode(Opcodes.DLOAD, 7));
// INVOKESPECIAL call super method
insns.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, getTypeForClassName(Screen).getInternalName(), mouseScrolled, mouseScrolledDesc.getDescriptor()));
// IRETURN return int on stack (booleans are int at runtime)
insns.add(new InsnNode(Opcodes.IRETURN));
classNode.methods.add(mouseScrolledNode);
}
insertTrueHandler(mouseScrolledNode, insns -> {
// ALOAD 0, load this
insns.add(new VarInsnNode(Opcodes.ALOAD, 0));
// DLOAD 1-4, load the 4 argument doubles. Note that since doubles are two entries wide we skip 2 each time.
insns.add(new VarInsnNode(Opcodes.DLOAD, 1));
insns.add(new VarInsnNode(Opcodes.DLOAD, 3));
insns.add(new VarInsnNode(Opcodes.DLOAD, 5));
insns.add(new VarInsnNode(Opcodes.DLOAD, 7));
}, insns -> {
// INVOKEVIRTUAL call custom handler
insns.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
getTypeForClassName(HandledScreen).getInternalName(),
"mouseScrolled_firmament",
mouseScrolledDesc.getDescriptor()));
});
addSuperInjector(
classNode, mouseScrolled, mouseScrolledDesc, "mouseScrolled_firmament",
insns -> {
// ALOAD 0, load this
insns.add(new VarInsnNode(Opcodes.ALOAD, 0));
// DLOAD 1-4, load the 4 argument doubles. Note that since doubles are two entries wide we skip 2 each time.
insns.add(new VarInsnNode(Opcodes.DLOAD, 1));
insns.add(new VarInsnNode(Opcodes.DLOAD, 3));
insns.add(new VarInsnNode(Opcodes.DLOAD, 5));
insns.add(new VarInsnNode(Opcodes.DLOAD, 7));
});
}
}

View File

@@ -62,10 +62,6 @@ public abstract class MixinHandledScreen<T extends ScreenHandler> {
}
}
boolean keyReleased_firmament(int keyCode, int scanCode, int modifiers) {
return HandledScreenKeyReleasedEvent.Companion.publish(new HandledScreenKeyReleasedEvent((HandledScreen<?>) (Object) this, keyCode, scanCode, modifiers)).getCancelled();
}
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreen;drawForeground(Lnet/minecraft/client/gui/DrawContext;II)V", shift = At.Shift.AFTER))
public void onAfterRenderForeground(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
context.getMatrices().push();

View File

@@ -5,6 +5,7 @@ import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import moe.nea.firmament.events.HandledScreenKeyReleasedEvent;
import moe.nea.firmament.util.customgui.CoordRememberingSlot;
import moe.nea.firmament.util.customgui.CustomGui;
import moe.nea.firmament.util.customgui.HasCustomGui;
@@ -73,6 +74,16 @@ public class PatchHandledScreen<T extends ScreenHandler> extends Screen implemen
return override != null && override.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount);
}
public boolean keyReleased_firmament(int keyCode, int scanCode, int modifiers) {
if (HandledScreenKeyReleasedEvent.Companion.publish(new HandledScreenKeyReleasedEvent((HandledScreen<?>) (Object) this, keyCode, scanCode, modifiers)).getCancelled())
return true;
return override != null && override.keyReleased(keyCode, scanCode, modifiers);
}
public boolean charTyped_firmament(char chr, int modifiers) {
return override != null && override.charTyped(chr, modifiers);
}
@Inject(method = "init", at = @At("TAIL"))
private void onInit(CallbackInfo ci) {
if (override != null) {
@@ -179,6 +190,16 @@ public class PatchHandledScreen<T extends ScreenHandler> extends Screen implemen
}
}
@Inject(method = "keyPressed", at = @At("HEAD"), cancellable = true)
private void overrideKeyPressed(int keyCode, int scanCode, int modifiers, CallbackInfoReturnable<Boolean> cir) {
if (override != null) {
if (override.keyPressed(keyCode, scanCode, modifiers)) {
cir.setReturnValue(true);
}
}
}
@Inject(
method = "mouseReleased",
at = @At("HEAD"), cancellable = true)