package dev.modzuozhi.mixin; import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import org.spongepowered.asm.mixin.Mixin; /** * 防御:{@code Entity.getInBlockState()} 空值兜底。 *
* 罕见 NPE 根因:并行子任务线程上,{@code getInBlockState()} 读取实体所在位置方块状态时 * 偶发返回 {@code null}(区块读路径的边缘竞态),随后该值被传给 * {@code CommonHooks.isLivingOnLadder(state, ...)} 并直接 {@code state.isLadder(...)} → NPE * (日志:[FineGrain] 子任务异常 ... because "state" is null,50 分钟约 1 次,被屏障捕获不降级)。 *
* 注意:{@code getInBlockState()} 定义在 {@link Entity}(父类)而非 {@code LivingEntity},
* 因此 {@code @WrapMethod} 必须目标 {@code Entity.class}(mixin 只包装目标类声明的方法)。
* 这里对返回值做空值兜底(null → 空气方块),从根源上杜绝该路径的 NPE;正常情况零改动。
*/
@Mixin(Entity.class)
public abstract class LivingEntityGetInBlockStateMixin {
@WrapMethod(method = "getInBlockState")
private BlockState modzuozhi_nullSafeInBlockState(Operation