MixinRedNetCableRenderer

基本信息

属性 值
类名 com.gtnewhorizons.angelicacompat.mixins.late.client.minefactoryreloaded.MixinRedNetCableRenderer
目标类 powercrystals.minefactoryreloaded.render.block.RedNetCableRenderer
父类继承 net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer
Mixin 阶段 LATE
Mixin 启用条件 PatchesConfig.patchMFR == true
Mixin 注入方法 renderWorldBlock (@Inject)
注入位置 FIELD powercrystals/minefactoryreloaded/setup/MFRConfig.TESRCables:Z 之后
局部捕获 LocalCapture.CAPTURE_FAILHARD,捕获 TileEntityRedNetCable _cable
启用版本 Minecraft 1.7.10(仅客户端)

功能

MineFactory Reloaded 的 RedNetCableRenderer.renderWorldBlock 是 ISBRT(renderTileEntityAt-like)路径下被并发调用的渲染器。原版实现从 world.getTileEntity(x, y, z) 取到 TileEntityRedNetCable 后,直接做强转并访问字段:

TileEntityRedNetCable cable = (TileEntityRedNetCable) world.getTileEntity(x, y, z);
cable.someField; // 当 getTileEntity 返回 null 时崩溃

在 Angelica 的 Sodium 异步 ISBRT 路径下,getTileEntity 异步返回可能为 null,原版会立即抛 NPE。

本 Mixin 在 MFRConfig.TESRCables 字段读取后插入 null 守卫:

@Inject(
    method = "renderWorldBlock",
    at = @At(value = "FIELD", target = "Lpowercrystals/minefactoryreloaded/setup/MFRConfig;TESRCables*:Z"),
    locals = LocalCapture.CAPTURE_FAILHARD,
    cancellable = true,
    remap = false)
public void angelica$checkNullBeforeAccess(IBlockAccess world, int x, int y, int z, Block block, int modelId,
    RenderBlocks renderer, CallbackInfoReturnable<Boolean> cir, TileEntityRedNetCable _cable) {
    if (_cable == null) {
        cir.setReturnValue(false);
    }
}
  • 通过 LocalCapture.CAPTURE_FAILHARD 把 MFR 原版强转后赋值的 TileEntityRedNetCable cable 局部变量捕获到本 Mixin 的 _cable 参数;
  • 若 _cable == null,cir.setReturnValue(false) 让原方法立即返回 false(“本方块未渲染”),不进入后续 NPE 路径;
  • 若非 null,则继续原方法逻辑。

MFRConfig.TESRCables 字段读取点选取作为注入锚点是为了保证已被原方法强转过 getTileEntity,避免在更早的位置插入造成死代码。

第三方 mod 集成

依赖 包 是否必需
powercrystals.minefactoryreloaded.render.block.RedNetCableRenderer MFR 是
powercrystals.minefactoryreloaded.tile.rednet.TileEntityRedNetCable MFR 是(被 LocalCapture 捕获)

相关条目