ClientboundLevelChunkPacketData.java
net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData
信息
- 全限定名:net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData
- 类型:public class
- 包:net.minecraft.network.protocol.game
- 源码路径:src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
- 起始行号:L27
- 职责:
TODO
字段/常量
-
HEIGHTMAPS_STREAM_CODEC- 类型:
StreamCodec<ByteBuf,Map<Heightmap.Types,long[]>> - 修饰符:
private static final - 源码定位:
L28 - 说明:
TODO
- 类型:
-
TWO_MEGABYTES- 类型:
int - 修饰符:
private static final - 源码定位:
L31 - 说明:
TODO
- 类型:
-
heightmaps- 类型:
Map<Heightmap.Types,long[]> - 修饰符:
private final - 源码定位:
L32 - 说明:
TODO
- 类型:
-
buffer- 类型:
byte[] - 修饰符:
private final - 源码定位:
L33 - 说明:
TODO
- 类型:
-
blockEntitiesData- 类型:
List<ClientboundLevelChunkPacketData.BlockEntityInfo> - 修饰符:
private final - 源码定位:
L34 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData.BlockEntityInfo- 类型:
class - 修饰符:
private static - 源码定位:
L120 - 说明:
TODO
- 类型:
-
net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData.BlockEntityTagOutput- 类型:
interface - 修饰符:
public - 源码定位:
L162 - 说明:
TODO
- 类型:
构造器
public ClientboundLevelChunkPacketData(LevelChunk levelChunk) @ L36
- 构造器名:ClientboundLevelChunkPacketData
- 源码定位:L36
- 修饰符:public
参数:
- levelChunk: LevelChunk
说明:
TODO
public ClientboundLevelChunkPacketData(RegistryFriendlyByteBuf input, int x, int z) @ L50
- 构造器名:ClientboundLevelChunkPacketData
- 源码定位:L50
- 修饰符:public
参数:
- input: RegistryFriendlyByteBuf
- x: int
- z: int
说明:
TODO
方法
下面的方法块按源码顺序生成。
public void write(RegistryFriendlyByteBuf output) @ L62
- 方法名:write
- 源码定位:L62
- 返回类型:void
- 修饰符:public
参数:
- output: RegistryFriendlyByteBuf
说明:
TODO
private static int calculateChunkSize(LevelChunk chunk) @ L69
- 方法名:calculateChunkSize
- 源码定位:L69
- 返回类型:int
- 修饰符:private static
参数:
- chunk: LevelChunk
说明:
TODO
private ByteBuf getWriteBuffer() @ L79
- 方法名:getWriteBuffer
- 源码定位:L79
- 返回类型:ByteBuf
- 修饰符:private
参数:
- 无
说明:
TODO
public static void extractChunkData(FriendlyByteBuf buffer, LevelChunk chunk) @ L85
- 方法名:extractChunkData
- 源码定位:L85
- 返回类型:void
- 修饰符:public static
参数:
- buffer: FriendlyByteBuf
- chunk: LevelChunk
说明:
TODO
public Consumer<ClientboundLevelChunkPacketData.BlockEntityTagOutput> getBlockEntitiesTagsConsumer(int x, int z) @ L95
- 方法名:getBlockEntitiesTagsConsumer
- 源码定位:L95
- 返回类型:Consumer<ClientboundLevelChunkPacketData.BlockEntityTagOutput>
- 修饰符:public
参数:
- x: int
- z: int
说明:
TODO
private void getBlockEntitiesTags(ClientboundLevelChunkPacketData.BlockEntityTagOutput output, int x, int z) @ L99
- 方法名:getBlockEntitiesTags
- 源码定位:L99
- 返回类型:void
- 修饰符:private
参数:
- output: ClientboundLevelChunkPacketData.BlockEntityTagOutput
- x: int
- z: int
说明:
TODO
public FriendlyByteBuf getReadBuffer() @ L112
- 方法名:getReadBuffer
- 源码定位:L112
- 返回类型:FriendlyByteBuf
- 修饰符:public
参数:
- 无
说明:
TODO
public Map<Heightmap.Types,long[]> getHeightmaps() @ L116
- 方法名:getHeightmaps
- 源码定位:L116
- 返回类型:Map<Heightmap.Types,long[]>
- 修饰符:public
参数:
- 无
说明:
TODO
代码
public class ClientboundLevelChunkPacketData {
private static final StreamCodec<ByteBuf, Map<Heightmap.Types, long[]>> HEIGHTMAPS_STREAM_CODEC = ByteBufCodecs.map(
size -> new EnumMap<>(Heightmap.Types.class), Heightmap.Types.STREAM_CODEC, ByteBufCodecs.LONG_ARRAY
);
private static final int TWO_MEGABYTES = 2097152;
private final Map<Heightmap.Types, long[]> heightmaps;
private final byte[] buffer;
private final List<ClientboundLevelChunkPacketData.BlockEntityInfo> blockEntitiesData;
public ClientboundLevelChunkPacketData(LevelChunk levelChunk) {
this.heightmaps = levelChunk.getHeightmaps()
.stream()
.filter(entryx -> ((Heightmap.Types)entryx.getKey()).sendToClient())
.collect(Collectors.toMap(Entry::getKey, entryx -> (long[])((Heightmap)entryx.getValue()).getRawData().clone()));
this.buffer = new byte[calculateChunkSize(levelChunk)];
extractChunkData(new FriendlyByteBuf(this.getWriteBuffer()), levelChunk);
this.blockEntitiesData = Lists.newArrayList();
for (Entry<BlockPos, BlockEntity> entry : levelChunk.getBlockEntities().entrySet()) {
this.blockEntitiesData.add(ClientboundLevelChunkPacketData.BlockEntityInfo.create(entry.getValue()));
}
}
public ClientboundLevelChunkPacketData(RegistryFriendlyByteBuf input, int x, int z) {
this.heightmaps = HEIGHTMAPS_STREAM_CODEC.decode(input);
int size = input.readVarInt();
if (size > 2097152) {
throw new RuntimeException("Chunk Packet trying to allocate too much memory on read.");
} else {
this.buffer = new byte[size];
input.readBytes(this.buffer);
this.blockEntitiesData = ClientboundLevelChunkPacketData.BlockEntityInfo.LIST_STREAM_CODEC.decode(input);
}
}
public void write(RegistryFriendlyByteBuf output) {
HEIGHTMAPS_STREAM_CODEC.encode(output, this.heightmaps);
output.writeVarInt(this.buffer.length);
output.writeBytes(this.buffer);
ClientboundLevelChunkPacketData.BlockEntityInfo.LIST_STREAM_CODEC.encode(output, this.blockEntitiesData);
}
private static int calculateChunkSize(LevelChunk chunk) {
int total = 0;
for (LevelChunkSection section : chunk.getSections()) {
total += section.getSerializedSize();
}
return total;
}
private ByteBuf getWriteBuffer() {
ByteBuf buffer = Unpooled.wrappedBuffer(this.buffer);
buffer.writerIndex(0);
return buffer;
}
public static void extractChunkData(FriendlyByteBuf buffer, LevelChunk chunk) {
for (LevelChunkSection section : chunk.getSections()) {
section.write(buffer);
}
if (buffer.writerIndex() != buffer.capacity()) {
throw new IllegalStateException("Didn't fill chunk buffer: expected " + buffer.capacity() + " bytes, got " + buffer.writerIndex());
}
}
public Consumer<ClientboundLevelChunkPacketData.BlockEntityTagOutput> getBlockEntitiesTagsConsumer(int x, int z) {
return output -> this.getBlockEntitiesTags(output, x, z);
}
private void getBlockEntitiesTags(ClientboundLevelChunkPacketData.BlockEntityTagOutput output, int x, int z) {
int baseX = 16 * x;
int baseZ = 16 * z;
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
for (ClientboundLevelChunkPacketData.BlockEntityInfo data : this.blockEntitiesData) {
int unpackedX = baseX + SectionPos.sectionRelative(data.packedXZ >> 4);
int unpackedZ = baseZ + SectionPos.sectionRelative(data.packedXZ);
pos.set(unpackedX, data.y, unpackedZ);
output.accept(pos, data.type, data.tag);
}
}
public FriendlyByteBuf getReadBuffer() {
return new FriendlyByteBuf(Unpooled.wrappedBuffer(this.buffer));
}
public Map<Heightmap.Types, long[]> getHeightmaps() {
return this.heightmaps;
}
private static class BlockEntityInfo {
public static final StreamCodec<RegistryFriendlyByteBuf, ClientboundLevelChunkPacketData.BlockEntityInfo> STREAM_CODEC = StreamCodec.ofMember(
ClientboundLevelChunkPacketData.BlockEntityInfo::write, ClientboundLevelChunkPacketData.BlockEntityInfo::new
);
public static final StreamCodec<RegistryFriendlyByteBuf, List<ClientboundLevelChunkPacketData.BlockEntityInfo>> LIST_STREAM_CODEC = STREAM_CODEC.apply(
ByteBufCodecs.list()
);
private final int packedXZ;
private final int y;
private final BlockEntityType<?> type;
private final @Nullable CompoundTag tag;
private BlockEntityInfo(int packedXZ, int y, BlockEntityType<?> type, @Nullable CompoundTag tag) {
this.packedXZ = packedXZ;
this.y = y;
this.type = type;
this.tag = tag;
}
private BlockEntityInfo(RegistryFriendlyByteBuf input) {
this.packedXZ = input.readByte();
this.y = input.readShort();
this.type = ByteBufCodecs.registry(Registries.BLOCK_ENTITY_TYPE).decode(input);
this.tag = input.readNbt();
}
private void write(RegistryFriendlyByteBuf output) {
output.writeByte(this.packedXZ);
output.writeShort(this.y);
ByteBufCodecs.registry(Registries.BLOCK_ENTITY_TYPE).encode(output, this.type);
output.writeNbt(this.tag);
}
private static ClientboundLevelChunkPacketData.BlockEntityInfo create(BlockEntity blockEntity) {
CompoundTag tag = blockEntity.getUpdateTag(blockEntity.getLevel().registryAccess());
BlockPos pos = blockEntity.getBlockPos();
int xz = SectionPos.sectionRelative(pos.getX()) << 4 | SectionPos.sectionRelative(pos.getZ());
return new ClientboundLevelChunkPacketData.BlockEntityInfo(xz, pos.getY(), blockEntity.getType(), tag.isEmpty() ? null : tag);
}
}
@FunctionalInterface
public interface BlockEntityTagOutput {
void accept(BlockPos pos, BlockEntityType<?> type, @Nullable CompoundTag tag);
}
}引用的其他类
-
- 引用位置:
方法调用/构造调用 - 关联成员:
BlockPos.MutableBlockPos(), MutableBlockPos()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
SectionPos.sectionRelative()
- 引用位置:
-
- 引用位置:
参数/构造调用/返回值 - 关联成员:
FriendlyByteBuf()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ByteBufCodecs.list(), ByteBufCodecs.map(), ByteBufCodecs.registry()
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
StreamCodec.ofMember()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置: