MixinAnvilChunkLoader

基本信息

属性 值
Mixin 目标 net.minecraft.world.chunk.storage.AnvilChunkLoader
Phase EARLY
角色 区块 NBT 序列化 Blocks16/Data16 与原版 Blocks/Add/Data 双向兼容
依赖 IExtendedBlockStorageMixin、llamalad7 mixinextras(@Local、@WrapOperation)

写入路径(writeChunkToNBT)

1. Blocks16 / 兼容 Blocks + Add

@Redirect 第一个 NBTTagCompound.setByteArray(ordinal = 0):

private void neid$overrideWriteLSBArray(NBTTagCompound nbt, String s, byte[] oldbrokenbytes,
        @Local(ordinal = 0) ExtendedBlockStorage ebs) {
    IExtendedBlockStorageMixin ebsMixin = (IExtendedBlockStorageMixin) ebs;
    nbt.setByteArray("Blocks16", ebsMixin.getBlockData());   // 16-bit 主存储
    if (NEIDConfig.PostNeidWorldsSupport) {
        // 同时写出 vanilla 12-bit 兼容字段
        // 遍历 block16BArray:id <= 255 直接写 LSB
        // 256 <= id <= 4095 时 LSB + MSB(两块共享一个字节)
        // 4096 < id 不写(卸载 NEID 后会消失)
    }
}

注意:若 PostNeidWorldsSupport = false,卸载 NEID 后该区块直接丢失所有 id > 4095 的方块(变成空地或边界)。

2. Data16 / 兼容 Data

@Redirect 第二个 setByteArray(ordinal = 2):

private void neid$overrideWriteMetadataArray(...) {
    nbt.setByteArray("Data16", ebsMixin.getBlockMeta());
    if (NEIDConfig.PostNeidWorldsSupport) {
        // 遍历 block16BMetaArray,每 2 个 meta 合成 1 字节(高 4 位 + 低 4 位)
        // meta < 0 或 meta > 15 时强行设 0(即原版 4-bit metadata 范围)
    }
}

NEID 16-bit metadata 范围 0–65535,超出 0–15 的部分在 vanilla Data 字段里被钳为 0。

读取路径(readChunkFromNBT)

@Redirect 序号 目标 行为
1 ExtendedBlockStorage.setBlockLSBArray 优先读 Blocks16(无符号);否则读 Blocks + Add 合并成 16-bit 写入 block16BArray
2 NBTTagCompound.hasKey("Add", 99) ordinal = 0 永远返回 false,跳过 MSB 读取
3 NBTTagCompound.getByteArray ordinal = 2 返回 fakeByteArray(空 byte[]),让 vanilla metadata 数组创建被短路
4 new NibbleArray(bytes, length) ordinal = 1(WrapOperation) 返回 fakeNibbleArray(长度 0)
5 ExtendedBlockStorage.setBlockMetadataArray(NibbleArray) 优先读 Data16;否则读 Data(每字节拆成 2 个 meta 写入 block16BMetaArray)

静态常量

private static byte[] fakeByteArray = new byte[0];
private static NibbleArray fakeNibbleArray = new NibbleArray(0, 0);

用作"占位返回值",让 vanilla 的 metadata 数组创建/NBT 读取被静默跳过,避免把 Data16 误写到 vanilla setBlockMetadataArray。

行为开关

配置 触发位置 行为
PostNeidWorldsSupport 两次 writeChunkToNBT @Redirect 决定是否额外写 vanilla 字段(卸载 NEID 后可读)

注意事项

  • assert false 出现在两处(既无 Blocks16 也无 Blocks 的 NBT):正常情况不会出现。
  • Data16 vs Data 命名:NEID 用大写 16 表示 16-bit 字段,跟原版 Blocks/Data 区分。
  • 行为对称性:写入兼容字段时仅保留 id <= 4095 的方块;NEID 卸载后超出部分丢失——这是设计妥协,不是 bug。

相关条目