MixinS21PacketChunkData

基本信息

属性 值
Mixin 目标 net.minecraft.network.play.server.S21PacketChunkData
Phase EARLY
角色 服务端/客户端通用的区块数据包字节尺寸改写 + 数据拷贝重定向 + 客户端转换管线
配套 服务端专用变体 MixinS21PacketChunkDataThermosTainted 用于 Thermos(带 NibbleArray.copyToByteArray 路径)

常量改写(@ModifyConstant)

方法 常量(vanilla) 改写为(NEID) 说明
<clinit> 196864 327936 BYTES_PER_CHUNK
func_149275_c()I 196864 327936 同上
readPacketData 12288 20480 BYTES_PER_EBS

数据拷贝重定向(@Redirect / @WrapWithCondition)

func_149269_a(写客户端 chunk data packet 主循环):

注入点 改写逻辑
ExtendedBlockStorage.getBlockLSBArray() 不再读 byte[] LSB;改调 ebsMixin.getBlockData() 把 16-bit short 块直接 arraycopy 到目标缓冲;offset += BLOCKS_PER_EBS * 2
System.arraycopy ordinal = 0 返回 false 取消 vanilla LSB 拷贝
ExtendedBlockStorage.getMetadataArray() 同上但调 ebsMixin.getBlockMeta()
System.arraycopy ordinal = 1 返回 false 取消 vanilla metadata 拷贝
ExtendedBlockStorage.getBlockMSBArray() ordinal = 0 返回 null,跳过 MSB 循环

客户端转换管线(@Inject at TAIL)

@Inject(method = "func_149269_a", at = @At("TAIL"))
private static void neid$modifyChunkData(Chunk chunk, boolean firstSync, int flags,
        CallbackInfoReturnable<S21PacketChunkData.Extracted> cir, @Local S21PacketChunkData.Extracted data) {
    // 1. 把每个 EBS 的 blocks/metas 区段包装成 ShortBuffer
    // 2. 调用 ClientBlockTransformerRegistry.transformBulk(...) 让所有 ClientBlockTransformer 改写
    // 3. 改写直接在 ShortBuffer 上原地修改,绕开 NibbleArray 编码
}

涉及常量

private static final byte[] fakeByteArray = new byte[0];
private static final NibbleArray fakeNibbleArray = new NibbleArray(0, 0);
private final int ebsLength = Constants.BLOCKS_PER_EBS * 2;  // 8192 bytes per EBS

与 Thermos 变体对比

维度 本类(标准 vanilla 服务端) ThermosTainted
<clinit> / func_149275_c / readPacketData 同 同
getBlockLSBArray 重定向 同 同
LSB System.arraycopy 取消 ordinal = 0 ordinal = 0
metadata getMetadataArray 重定向 同 同
metadata System.arraycopy 取消 ordinal = 1 ——
metadata NibbleArray.copyToByteArray 取消 —— ordinal = 0,remap=false
MSB getBlockMSBArray 重定向 ordinal = 0 ordinal = 0
客户端 transformBulk 管线 ✅ ❌(Thermos 用 Bukkit 路径,client transform 走其他 mixin)

Mixins.java 里通过 addExcludedMod(TargetMods.THERMOS) / addRequiredMod(TargetMods.THERMOS) 二选一加载。

相关条目