You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于Mixin注入时机:能否将RETURN注入点调整至return指令后执行?

Mixin注入时机:能否将RETURN注入点调整至return指令后执行?

嘿,我来帮你捋清楚这个Mixin注入时机的问题~

先直接给你核心结论:你没法把RETURN注入点“移到”return指令之后——因为@At("RETURN")本身就是设计在对应return指令执行完毕、方法即将退出的位置插入代码的。不过结合你的代码场景,我感觉你可能对注入点的使用场景有点误解,咱们拆解开说:

首先明确RETURN注入点的实际行为:

  • 当你写@At(value="RETURN", ordinal=0)时,Mixin会定位到方法里第一个出现的return指令,然后把你的注入代码插在这个return指令执行之后、方法从该分支退出前的位置。
  • 要是你想拿到这个return语句的返回值,只需要在注入方法的参数里加个@Return ItemInteractionResult result,就能直接获取到PASS_TO_DEFAULT_BLOCK_INTERACTION这个返回值。

不过看你代码里的注释,你真正想注入的位置是跳过那个if分支之后(就是//I want to inject some code here的地方,也就是当player.isShiftKeyDown() || !player.mayBuild()为false时,才会走到的代码段开头)。这种情况用RETURN注入点就不合适了,因为RETURN会在触发return的分支里执行,而你要的是“不触发这个return”时才运行注入代码。这时候你有两个更合适的选项:

选项1:基于后续方法调用的注入点

你的代码在if分支之后的第一行是boolean isWrench = AllItems.WRENCH.isIn(stack);,你可以针对这个isIn方法的调用做注入,精准定位到目标位置:

@Inject(
    method = "useItemOn",
    at = @At(
        value = "INVOKE",
        target = "L你的模组包路径/AllItems$WRENCH;isIn(Lnet/minecraft/world/item/ItemStack;)Z",
        shift = At.Shift.BEFORE
    )
)
private void injectAfterIfCheck(ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult, CallbackInfoReturnable<ItemInteractionResult> cir) {
    // 这里的代码会在不进入if分支时,在isIn方法调用前执行,完全对应你注释的位置
}

记得把target里的包路径换成你实际的AllItems.WRENCH的完整路径哦。

选项2:基于标签的注入点

如果AllItems.WRENCH.isIn()在方法里有多处调用,或者你不想依赖这个方法,也可以用标签注入点:

@Inject(
    method = "useItemOn",
    at = @At(value = "LABEL", ordinal = 0)
)

不过这个需要你先反编译原方法,找到if分支结束后对应的标签序号(ordinal从0开始数),优点是不依赖后续方法调用,但缺点是如果原方法编译后标签序号变化,注入就会失效,所以更推荐第一种选项。

最后补个小误区澄清

很多新手会误以为RETURN是在return指令之前插入代码,但实际上Mixin的RETURN注入点就是在return指令执行完成后(比如返回值已经准备好)、方法退出前插入的。如果你确实需要在某个特定return指令执行后触发逻辑,@At(value="RETURN", ordinal=N)就是正确的选择,N是该return语句在方法中的出现顺序序号。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 08:24:50