GetTileEntityNullGuardTransformer

基本信息

属性 值
类名 com.gtnewhorizons.angelicacompat.asm.transformers.generic.GetTileEntityNullGuardTransformer
实现接口 net.minecraft.launchwrapper.IClassTransformer
数据源 CompatRegistry.INSTANCE.getTileEntityNullGuardTransforms()
触发条件 AngelicaConfig.enableSodium == true 且 Side.CLIENT
注册枚举 AsmTransformers.GET_TILE_ENTITY_NULL_GUARD
启用版本 Minecraft 1.7.10(仅客户端)

功能

在 Angelica 的 Sodium 异步 ISBRH/ISBRT 路径下,world.getTileEntity(x, y, z) 可能异步返回 null(该位置尚未从主世界 tick 中读出),而许多原版 mod 在拿到结果后立即做强转:

MyTileEntity tile = (MyTileEntity) world.getTileEntity(x, y, z);
doSomethingWithTileEntity(tile); // 当 tile == null 时崩溃

GetTileEntityNullGuardTransformer 在 INVOKEINTERFACE net/minecraft/world/IBlockAccess.getTileEntity(III)Lnet/minecraft/tileentity/TileEntity; 紧接的 CHECKCAST 之后插入:

MyTileEntity tile = (MyTileEntity) world.getTileEntity(x, y, z);
if (tile != null) {
    doSomethingWithTileEntity(tile);
}

即仅当强转结果非 null 时才执行后续原始指令序列;返回 null 时把整段后续代码替换为 NOP 直至方法结束或下一个 INVOKEINTERFACE getTileEntity 调用边界。

注入算法(injectGetTileEntityNullGuard)

  1. 遍历方法所有 AbstractInsnNode,定位每个 MethodInsnNode:
    • Opcodes.INVOKEINTERFACE
    • owner = net/minecraft/world/IBlockAccess
    • name = "getTileEntity"(Obf 环境为 func_147438_o,由 AsmUtil.obf 决定)
    • desc = "(III)Lnet/minecraft/tileentity/TileEntity;"
  2. 在该指令后追加:
    • DUP
    • IFNULL skipLabel
    • 在原 CHECKCAST(紧跟其后的指令)之后插入 GOTO endLabel
    • 在 skipLabel 处插入 POP,然后直接 NOP 到方法末尾的原始逻辑(在 endLabel 之后是原代码继续)
  3. 配合 ClassWriter.COMPUTE_FRAMES 重算栈帧,使 null 路径与原路径在字节码层都合法。

补丁覆盖(默认)

ClassWriter 标志

COMPUTE_FRAMES:必需,保证新增 DUP/IFNULL/GOTO 后栈帧合法。

输出与调试

详见 AngelicaCompatCore — 当 AngelicaCompatCore.DUMP_CLASSES() 为 true 时写出改写前后字节码。

数值

数值 默认 含义
数据来源 CompatRegistry.getTileEntityNullGuardTransforms() 运行时由 CompatHandler 注册
默认目标方法数 1(Stacks on Stacks) RenderTilePile.renderWorldBlock
触发开关 AngelicaConfig.enableSodium 仅 Sodium 启用时装载

限制

  • 仅在 INVOKEINTERFACE getTileEntity 后紧跟强转时有效;若是先存到局部变量再判空再强转,无法自动注入。
  • Obf 环境使用 func_147438_o 识别,需要 SRG 映射表与运行环境一致。
  • 不会修改 World.getTileEntity 内部行为,仅补丁调用方——属于下游 mod 适配,不是修复底层。

第三方 mod 集成

通用 transformer,依赖 CompatRegistry 运行时填充。当前内置 Stacks on Stacks 一个兼容目标。

相关条目