SpongePowered / Mixin

Mixin is a trait/mixin and bytecode weaving framework for Java using ASM
MIT License
1.37k stars 185 forks source link

Multiversion Mixin Issues #665

Closed gXLg closed 2 months ago

gXLg commented 2 months ago

I am writing a fabric mod, which compiles on any version of Minecraft from 1.16.4 up to 1.20.4.

So far I had no issues regarding the code, but issues came as soon as I wanted to use Mixins.

The method ClientPlayerInteractionManager#interactBlock changed its' parameters during these versions and now I struggle to find a way to write an injection, which should work with both kinds of signature.

So far I tried

@SuppressWarnings({"MixinAnnotationTarget", "UnresolvedMixinReference"})
    @Inject(at = @At(value = "HEAD"), method = "interactBlock(Lnet/minecraft/client/network/ClientPlayerEntity;Lnet/minecraft/client/world/ClientWorld;Lnet/minecraft/util/Hand;Lnet/minecraft/util/hit/BlockHitResult;)Lnet/minecraft/util/ActionResult;", cancellable = true, require = 0)
    private void interactOld(CallbackInfoReturnable<ActionResult> info, @Local Hand hand) {
        if (client.player == null) {
            LibrGetter.MULTI.sendError(Worker.getSource(), "librgetter.internal", "player");
            return;
        }
        if (LibrGetter.config.manual && Worker.getState() == Worker.State.LOSE_SELECT_PLACE && ItemStack.areItemsEqual(client.player.getStackInHand(hand), Items.LECTERN.getDefaultStack())) {
            info.setReturnValue(ActionResult.FAIL);
        }
    }

Using require = 0 I was hoping to ignore the injection in case the method is not found. However the @Local annotation screws it all up, since it cannot find the correct argument and thus throws

[19:58:21] [Render thread/ERROR]:
 Unreported exception thrown!
java.lang.VerifyError: Bad local variable type
Exception Details:
  Location:
    net/minecraft/class_636.handler$bin000$librgetter$interactOld(Lorg/spongepowered/asm/mixin/injection/callback/CallbackInfoReturnable;)V @58: aload_2
  Reason:
    Type top (current frame, locals[2]) is not assignable to reference type
  Current Frame:
    bci: @58
    flags: { }
    locals: { 'net/minecraft/class_636', 'org/spongepowered/asm/mixin/injection/callback/CallbackInfoReturnable' }
    stack: { 'net/minecraft/class_746' }
  Bytecode:
    0000000: 2ab4 004e b400 69c7 001a b204 62b8 0465
    0000010: 1304 6704 bd00 0559 0313 0468 53b6 046e
    0000020: b1b2 0498 b404 9d99 002a b804 72b2 04a0
    0000030: a600 212a b400 4eb4 0069 2cb6 0218 b204
    0000040: a6b6 04a9 b804 ac99 000a 2bb2 01fa b603
    0000050: e9b1                                   
  Stackmap Table:
    same_frame(@33)
    same_frame(@81)

    at net.minecraft.class_634.method_11120(class_634.java:401) ~[client-intermediary.jar:?]
    at net.minecraft.class_2678.method_11567(class_2678.java:95) ~[client-intermediary.jar:?]
    at net.minecraft.class_2678.method_11054(class_2678.java:25) ~[client-intermediary.jar:?]
    at net.minecraft.class_2600.method_11072(class_2600.java:22) ~[client-intermediary.jar:?]
    at net.minecraft.class_1255.method_18859(class_1255.java:156) ~[client-intermediary.jar:?]
    at net.minecraft.class_4093.method_18859(class_4093.java:23) ~[client-intermediary.jar:?]
    at net.minecraft.class_1255.method_16075(class_1255.java:130) ~[client-intermediary.jar:?]
    at net.minecraft.class_1255.method_5383(class_1255.java:115) ~[client-intermediary.jar:?]
    at net.minecraft.class_310.method_1523(class_310.java:1175) ~[client-intermediary.jar:?]
    at net.minecraft.class_310.method_1514(class_310.java:802) ~[client-intermediary.jar:?]
    at net.minecraft.client.main.Main.main(Main.java:250) ~[1.20.1-0.15.9.jar:?]
    at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:470) ~[fabric-loader-0.15.9.jar:?]
    at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74) ~[fabric-loader-0.15.9.jar:?]
    at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23) ~[fabric-loader-0.15.9.jar:?]

Is there any way to completely ignore an injection, if the method was not found? Commenting out the annotated argument @Local Hand hand and the method body seems to produce no exceptions and run just fine.

I tried locals = Locals.CAPTURE_FAILEXCEPTION but this had no effect.

LlamaLad7 commented 2 months ago

This is an issue tracker, ask in the fabric discord's mixins channel. Also post a full log there.

gXLg commented 2 months ago

Thx, I will repost in discord. As for the full log, I have lots of other mods producing a ton of output and this Exception is the only one regarding my mod