make the chunk packet faster

This commit is contained in:
Alexander Medvedev 2025-03-17 22:46:48 +01:00
parent eaa2fe164c
commit d738b5879d
4 changed files with 40 additions and 33 deletions

View File

@ -53,7 +53,7 @@ futures = "0.3"
rayon = "1.10"
crossbeam = "0.8"
uuid = { version = "1.15", features = ["serde", "v3", "v4"] }
uuid = { version = "1.16", features = ["serde", "v3", "v4"] }
derive_more = { version = "2.0", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

View File

@ -3,6 +3,7 @@ use crate::{ClientPacket, VarInt, bytebuf::ByteBufMut, codec::bit_set::BitSet};
use bytes::{BufMut, BytesMut};
use pumpkin_data::packet::clientbound::PLAY_LEVEL_CHUNK_WITH_LIGHT;
use pumpkin_macros::packet;
use pumpkin_util::math::ceil_log2;
use pumpkin_world::{
DIRECT_PALETTE_BITS,
chunk::{ChunkData, SUBCHUNKS_COUNT},
@ -18,13 +19,24 @@ impl ClientPacket for CChunkData<'_> {
// Chunk Z
buf.put_i32(self.0.position.z);
let mut heightmap_nbt = Vec::new();
pumpkin_nbt::serializer::to_bytes_unnamed(&self.0.heightmap, &mut heightmap_nbt).unwrap();
// Heightmaps
buf.put_slice(&heightmap_nbt);
pumpkin_nbt::serializer::to_bytes_unnamed(&self.0.heightmap, &mut buf.writer()).unwrap();
let mut data_buf = BytesMut::new();
let mut light_buf = BytesMut::new();
self.0.blocks.array_iter_subchunks().for_each(|subchunk| {
let mut chunk_light = [0u8; 2048];
for i in 0..subchunk.len() {
// if !block .is_air() {
// continue;
// }
let index = i / 2;
let mask = if i % 2 == 1 { 0xF0 } else { 0x0F };
chunk_light[index] |= mask;
}
light_buf.put_var_int(&VarInt(chunk_light.len() as i32));
light_buf.put_slice(&chunk_light);
let block_count = subchunk.len() as i16;
// Block count
data_buf.put_i16(block_count);
@ -34,28 +46,37 @@ impl ClientPacket for CChunkData<'_> {
// TODO: make dynamic block_size work
// TODO: make direct block_size work
enum PaletteType {
Single,
Indirect(u32),
Direct,
}
let palette_type = {
let palette_bit_len = 64 - (palette.len() as i64 - 1).leading_zeros();
if palette_bit_len > 8 {
PaletteType::Direct
} else if palette_bit_len > 3 {
PaletteType::Indirect(palette_bit_len)
} else {
let palette_bit_len = ceil_log2(palette.len() as u32);
if palette_bit_len == 0 {
PaletteType::Single
} else if palette_bit_len <= 4 {
PaletteType::Indirect(4)
} else if palette_bit_len <= 8 {
PaletteType::Indirect(palette_bit_len as u32)
} else {
PaletteType::Direct
}
// TODO: fix indirect palette to work correctly
// PaletteType::Direct
};
match palette_type {
PaletteType::Single => {
data_buf.put_u8(0);
data_buf.put_var_int(&VarInt(*palette.first().unwrap() as i32));
data_buf.put_var_int(&VarInt(0));
}
PaletteType::Indirect(block_size) => {
// Bits per entry
data_buf.put_u8(block_size as u8);
// Palette length
data_buf.put_var_int(&VarInt(palette.len() as i32));
data_buf.put_var_int(&VarInt(palette.len() as i32 - 1));
palette.iter().for_each(|id| {
// Palette
@ -88,10 +109,8 @@ impl ClientPacket for CChunkData<'_> {
data_buf.reserve(data_array_len * 8);
for block_clump in subchunk.chunks(64 / DIRECT_PALETTE_BITS as usize) {
let mut out_long: i64 = 0;
let mut shift = 0;
for block in block_clump {
out_long |= (*block as i64) << shift;
shift += DIRECT_PALETTE_BITS;
for (i, &block) in block_clump.iter().enumerate() {
out_long |= (block as i64) << (i as u32 * DIRECT_PALETTE_BITS);
}
data_buf.put_i64(out_long);
}
@ -125,21 +144,9 @@ impl ClientPacket for CChunkData<'_> {
// Empty Block Light Mask
buf.put_bit_set(&BitSet(VarInt(1), vec![0]));
// Sky light
buf.put_var_int(&VarInt(SUBCHUNKS_COUNT as i32));
self.0.blocks.array_iter_subchunks().for_each(|chunk| {
let mut chunk_light = [0u8; 2048];
for (i, _) in chunk.iter().enumerate() {
// if !block .is_air() {
// continue;
// }
let index = i / 2;
let mask = if i % 2 == 1 { 0xF0 } else { 0x0F };
chunk_light[index] |= mask;
}
buf.put_var_int(&VarInt(chunk_light.len() as i32));
buf.put_slice(&chunk_light);
});
buf.put_slice(&light_buf);
// Block Lighting
buf.put_var_int(&VarInt(0));

View File

@ -9,7 +9,7 @@ pumpkin-protocol = { path = "../pumpkin-protocol" }
pumpkin-nbt = { path = "../pumpkin-nbt" }
pumpkin-util = { path = "../pumpkin-util" }
indexmap = { version = "2.7", features = ["serde"] }
indexmap = { version = "2.8", features = ["serde"] }
serde.workspace = true
serde_json.workspace = true

View File

@ -38,10 +38,10 @@ zstd = "0.13.3"
itertools = "0.14.0"
file-guard = "0.2"
indexmap = "2.7"
indexmap = "2.8"
enum_dispatch = "0.3"
noise = "0.9"
serde_json5 = "0.2.0"
serde_json5 = "0.2.1"
derive-getters = "0.5.0"
[dev-dependencies]