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)
- 遍历方法所有
AbstractInsnNode,定位每个MethodInsnNode:Opcodes.INVOKEINTERFACEowner = net/minecraft/world/IBlockAccessname = "getTileEntity"(Obf 环境为func_147438_o,由AsmUtil.obf决定)desc = "(III)Lnet/minecraft/tileentity/TileEntity;"
- 在该指令后追加:
DUPIFNULL skipLabel- 在原
CHECKCAST(紧跟其后的指令)之后插入GOTO endLabel - 在
skipLabel处插入POP,然后直接NOP到方法末尾的原始逻辑(在endLabel之后是原代码继续)
- 配合
ClassWriter.COMPUTE_FRAMES重算栈帧,使null路径与原路径在字节码层都合法。
补丁覆盖(默认)
com.tierzero.stacksonstacks.client.render.RenderTilePile.renderWorldBlock(由 StacksOnStacksCompatHandler 注册)
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 一个兼容目标。
相关条目
- CompatRegistry - 中央注册表
- StacksOnStacksCompatHandler - 注册目标的 CompatHandler
- AsmTransformers - 装载控制
- AngelicaCompatCore - 类转储基础设施