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):正常情况不会出现。Data16vsData命名:NEID 用大写 16 表示 16-bit 字段,跟原版Blocks/Data区分。- 行为对称性:写入兼容字段时仅保留
id <= 4095的方块;NEID 卸载后超出部分丢失——这是设计妥协,不是 bug。
相关条目
- MixinExtendedBlockStorage - 短数组存储
- NEIDConfig -
PostNeidWorldsSupport开关 - IExtendedBlockStorageMixin - 短数组访问接口