Revert "CChunkData optimizations (#193)"

This reverts commit a1b97730bd.

Due to Errors
```
thread 'tokio-runtime-worker' panicked at pumpkin-protocol/src/client/play/c_chunk_data.rs:84:25:
index out of bounds: the len is 4096 but the index is 25374
```
This commit is contained in:
Snowiiii 2024-10-27 12:29:53 +01:00
parent b17ade7b06
commit b23b7421cf
5 changed files with 40 additions and 56 deletions

View File

@ -20,10 +20,6 @@ edition = "2021"
lto = true lto = true
codegen-units = 1 codegen-units = 1
[profile.profiling]
inherits = "release"
debug = true
[workspace.dependencies] [workspace.dependencies]
log = "0.4" log = "0.4"
tokio = { version = "1.41", features = [ tokio = { version = "1.41", features = [

View File

@ -19,7 +19,6 @@ num-traits.workspace = true
num-derive.workspace = true num-derive.workspace = true
bytes = "1.8" bytes = "1.8"
arrayvec = "0.7.6"
flate2 = "1.0" flate2 = "1.0"

View File

@ -1,12 +1,10 @@
use std::collections::HashMap;
use crate::{bytebuf::ByteBuffer, BitSet, ClientPacket, VarInt}; use crate::{bytebuf::ByteBuffer, BitSet, ClientPacket, VarInt};
use arrayvec::ArrayVec;
use itertools::Itertools; use itertools::Itertools;
use pumpkin_macros::client_packet; use pumpkin_macros::client_packet;
use pumpkin_world::{ use pumpkin_world::{chunk::ChunkData, DIRECT_PALETTE_BITS};
chunk::{ChunkData, TOTAL_SUBCHUNK},
DIRECT_PALETTE_BITS,
};
use super::ClientboundPlayPackets; use super::ClientboundPlayPackets;
@ -27,23 +25,8 @@ impl<'a> ClientPacket for CChunkData<'a> {
buf.put_slice(&heightmap_nbt); buf.put_slice(&heightmap_nbt);
let mut data_buf = ByteBuffer::empty(); let mut data_buf = ByteBuffer::empty();
let mut palette_map = [0u16; 4096];
let mut lighting_subchunks = ArrayVec::<[u8; 2048], TOTAL_SUBCHUNK>::new();
self.0.blocks.iter_subchunks().for_each(|chunk| { self.0.blocks.iter_subchunks().for_each(|chunk| {
let mut block_count = 0; let block_count = chunk.iter().filter(|block| !block.is_air()).count() as i16;
let mut chunk_light = [0u8; 2048];
for (i, block) in chunk.iter().enumerate() {
if !block.is_air() {
block_count += 1;
continue;
}
let index = i / 2;
let mask = if i % 2 == 1 { 0xF0 } else { 0x0F };
chunk_light[index] |= mask;
}
lighting_subchunks.push(chunk_light);
// Block count // Block count
data_buf.put_i16(block_count); data_buf.put_i16(block_count);
//// Block states //// Block states
@ -68,28 +51,26 @@ impl<'a> ClientPacket for CChunkData<'a> {
// PaletteType::Direct // PaletteType::Direct
}; };
let chunk_size = match palette_type { let mut block_data_array = Vec::new();
PaletteType::Indirect(block_size) => 64 / block_size as usize,
PaletteType::Direct => 64 / DIRECT_PALETTE_BITS as usize,
};
let mut block_data_array = ArrayVec::<i64, 1024>::new();
match palette_type { match palette_type {
PaletteType::Indirect(block_size) => { PaletteType::Indirect(block_size) => {
// Bits per entry // Bits per entry
data_buf.put_u8(block_size as u8); data_buf.put_u8(block_size as u8);
// Palette length // Palette length
data_buf.put_var_int(&VarInt(palette.len() as i32)); data_buf.put_var_int(&VarInt(palette.len() as i32));
let mut palette_map = HashMap::new();
palette.iter().enumerate().for_each(|(i, id)| { palette.iter().enumerate().for_each(|(i, id)| {
palette_map[id.data as usize] = i as u16; palette_map.insert(*id, i);
// Palette // Palette
data_buf.put_var_int(&VarInt(id.get_id_mojang_repr())); data_buf.put_var_int(&VarInt(id.get_id_mojang_repr()));
}); });
for block_clump in chunk.chunks(chunk_size) { for block_clump in chunk.chunks(64 / block_size as usize) {
let mut out_long: i64 = 0; let mut out_long: i64 = 0;
for block in block_clump.iter().rev() { for block in block_clump.iter().rev() {
let index = palette_map[block.data as usize]; let index = palette_map
out_long = out_long << block_size | (index as i64); .get(block)
.expect("Its just got added, ofc it should be there");
out_long = out_long << block_size | (*index as i64);
} }
block_data_array.push(out_long); block_data_array.push(out_long);
} }
@ -97,7 +78,7 @@ impl<'a> ClientPacket for CChunkData<'a> {
PaletteType::Direct => { PaletteType::Direct => {
// Bits per entry // Bits per entry
data_buf.put_u8(DIRECT_PALETTE_BITS as u8); data_buf.put_u8(DIRECT_PALETTE_BITS as u8);
for block_clump in chunk.chunks(chunk_size) { for block_clump in chunk.chunks(64 / DIRECT_PALETTE_BITS as usize) {
let mut out_long: i64 = 0; let mut out_long: i64 = 0;
let mut shift = 0; let mut shift = 0;
for block in block_clump { for block in block_clump {
@ -113,9 +94,6 @@ impl<'a> ClientPacket for CChunkData<'a> {
// TODO: precompute this and omit making the `block_data_array` // TODO: precompute this and omit making the `block_data_array`
data_buf.put_var_int(&VarInt(block_data_array.len() as i32)); data_buf.put_var_int(&VarInt(block_data_array.len() as i32));
// Data array // Data array
let bytes = data_buf.buf();
bytes.reserve(block_data_array.len() * 8);
for data_int in block_data_array { for data_int in block_data_array {
data_buf.put_i64(data_int); data_buf.put_i64(data_int);
} }
@ -146,6 +124,22 @@ impl<'a> ClientPacket for CChunkData<'a> {
// Empty Block Light Mask // Empty Block Light Mask
buf.put_bit_set(&BitSet(VarInt(1), &[0])); buf.put_bit_set(&BitSet(VarInt(1), &[0]));
let mut lighting_subchunks = Vec::new();
self.0.blocks.iter_subchunks().for_each(|chunk| {
let mut chunk_light = [0u8; 2048];
for (i, block) 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;
}
lighting_subchunks.push(chunk_light);
});
buf.put_var_int(&lighting_subchunks.len().into()); buf.put_var_int(&lighting_subchunks.len().into());
for subchunk in lighting_subchunks { for subchunk in lighting_subchunks {
buf.put_var_int(&VarInt(subchunk.len() as i32)); buf.put_var_int(&VarInt(subchunk.len() as i32));

View File

@ -16,10 +16,9 @@ use crate::{
pub mod anvil; pub mod anvil;
pub const CHUNK_AREA: usize = 16 * 16; const CHUNK_AREA: usize = 16 * 16;
pub const SUBCHUNK_VOLUME: usize = CHUNK_AREA * 16; const SUBCHUNK_VOLUME: usize = CHUNK_AREA * 16;
pub const CHUNK_VOLUME: usize = CHUNK_AREA * WORLD_HEIGHT; const CHUNK_VOLUME: usize = CHUNK_AREA * WORLD_HEIGHT;
pub const TOTAL_SUBCHUNK: usize = CHUNK_VOLUME / SUBCHUNK_VOLUME;
pub trait ChunkReader: Sync + Send { pub trait ChunkReader: Sync + Send {
fn read_chunk( fn read_chunk(

View File

@ -87,19 +87,13 @@ const fn convert_logger_filter(level: pumpkin_config::logging::LevelFilter) -> L
} }
} }
fn main() { #[tokio::main]
// ensure rayon is built outside of tokio scope async fn main() -> io::Result<()> {
rayon::ThreadPoolBuilder::new().build_global().unwrap();
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap()
.block_on(async_main())
.unwrap();
}
async fn async_main() -> io::Result<()> {
init_logger(); init_logger();
// let rt = tokio::runtime::Builder::new_multi_thread()
// .enable_all()
// .build()
// .unwrap();
ctrlc::set_handler(|| { ctrlc::set_handler(|| {
log::warn!( log::warn!(
"{}", "{}",
@ -110,6 +104,8 @@ async fn async_main() -> io::Result<()> {
std::process::exit(0); std::process::exit(0);
}) })
.unwrap(); .unwrap();
// ensure rayon is built outside of tokio scope
rayon::ThreadPoolBuilder::new().build_global().unwrap();
let default_panic = std::panic::take_hook(); let default_panic = std::panic::take_hook();
std::panic::set_hook(Box::new(move |info| { std::panic::set_hook(Box::new(move |info| {
default_panic(info); default_panic(info);