MixinS22PacketMultiBlockChange
基本信息
| 属性 | 值 |
|---|---|
| Mixin 目标 | net.minecraft.network.play.server.S22PacketMultiBlockChange |
| Phase | EARLY |
| 角色 | 多方块变化包按方块 6 字节写入 + 客户端方块转换钩子 |
| 依赖 | ClientBlockTransformerRegistry、llamalad7 mixinextras @Local |
常量改写(@ModifyConstant)
@init(I[SLnet/minecraft/world/chunk/Chunk;)V(构造时):
| vanilla | NEID | 含义 |
|---|---|---|
4(每方块字节数) |
6 |
2 ID + 2 meta + 1 sky + 1 block |
NEID 每个方块占 6 字节(vanilla 是 4:1+1+1+1)。sky/block light 在 vanilla 中共享方块字节的高/低 4 位,NEID 改为各占独立字节。
写入重定向(@Redirect)
@init 内 DataOutputStream.writeShort(I)V ordinal = 1(vanilla 写 Metadata 为单字节):
private void neid$writeShortRedirectInConstructor(DataOutputStream dataOutputStream, int i,
@Local Chunk p_i45181_3_, @Local(ordinal = 3) int l, @Local(ordinal = 4) int i1,
@Local(ordinal = 5) int j1) throws IOException {
Block block = p_i45181_3_.getBlock(l, j1, i1); // 注意参数顺序:(x=l, y=j1, z=i1)
int meta = p_i45181_3_.getBlockMetadata(l, j1, i1);
pooled.setBlock(block);
pooled.setBlockMeta(meta);
boolean didSomething = ClientBlockTransformerRegistry.transformBlock(
p_i45181_3_.worldObj,
l + p_i45181_3_.xPosition * 16,
j1,
i1 + p_i45181_3_.zPosition * 16,
pooled);
if (didSomething) {
block = pooled.getBlock();
meta = pooled.getBlockMeta();
}
dataOutputStream.writeShort(Block.getIdFromBlock(block));
dataOutputStream.writeShort(meta);
}
调用顺序
- 调
Chunk.getBlock(x, y, z)拿服务端方块 - 调
ClientBlockTransformerRegistry.transformBlock让所有注册的 transformer 改写 - 如果
didSomething,用pooled中的新方块/Metadata writeShort写 16-bit ID + 16-bit Metadata
客户端反序列化
MixinNetHandlerPlayClient.handleMultiBlockChange(NetHandlerPlayClient mixin)配套:
- 用
readShort()读方块 ID(替换Block.getBlockById(int)调用) readShort() & METADATA_MASK读 Metadata(替换WorldClient.func_147492_c第 4 参数)
相关条目
- MixinNetHandlerPlayClient - 客户端解码方块
- ClientBlockTransformerRegistry - 转换入口
- Constants -
METADATA_MASK = 0xFFFF