NOW IT FULLY WORKS

This commit is contained in:
lukas0008 2024-08-12 20:23:15 +02:00
parent a991ce214b
commit eaf806a928
4 changed files with 89 additions and 54 deletions

View File

@ -4,7 +4,7 @@ use crate::{bytebuf::ByteBuffer, BitSet, ClientPacket, VarInt};
use fastnbt::LongArray; use fastnbt::LongArray;
use itertools::Itertools; use itertools::Itertools;
use pumpkin_macros::packet; use pumpkin_macros::packet;
use pumpkin_world::chunk::ChunkData; use pumpkin_world::{chunk::ChunkData, DIRECT_PALETTE_BITS};
#[packet(0x27)] #[packet(0x27)]
pub struct CChunkData<'a>(pub &'a ChunkData); pub struct CChunkData<'a>(pub &'a ChunkData);
@ -37,45 +37,66 @@ impl<'a> ClientPacket for CChunkData<'a> {
// Block count // Block count
data_buf.put_i16(block_count); data_buf.put_i16(block_count);
//// Block states //// Block states
let palette = chunk.clone().into_iter().dedup().collect_vec(); let palette = chunk.clone().into_iter().dedup().collect_vec();
let mut palette_map = HashMap::new(); // TODO: make dynamic block_size work
let block_size = 8; // TODO: make direct block_size work
// let block_size = { enum PaletteType {
// let palette_bit_len = palette.len().leading_zeros(); Indirect(u32),
// if palette_bit_len > 3 { Direct,
// palette_bit_len }
// } else { let palette_type = {
// 4 let palette_bit_len = 64 - (palette.len() as i64 - 1).leading_zeros();
// } if palette_bit_len > 8 {
// }; PaletteType::Direct
// Bits per entry } else if palette_bit_len > 3 {
data_buf.put_u8(block_size as u8); PaletteType::Indirect(palette_bit_len)
// Palette length } else {
data_buf.put_var_int(&VarInt(palette.len() as i32)); PaletteType::Indirect(4)
palette.iter().enumerate().for_each(|(i, id)| { }
palette_map.insert(*id, i); // TODO: fix indirect palette to work correctly
// Palette // PaletteType::Direct
data_buf.put_var_int(&VarInt(**id as i32)); };
});
let mut block_data_array = Vec::new(); let mut block_data_array = Vec::new();
for block_clump in chunk.chunks(64 / block_size as usize) { match palette_type {
let mut out_long: i64 = 0; PaletteType::Indirect(block_size) => {
let mut first = true; // Bits per entry
for block in block_clump { data_buf.put_u8(block_size as u8);
if first { // Palette length
first = false; data_buf.put_var_int(&VarInt(palette.len() as i32));
} else { let mut palette_map = HashMap::new();
out_long = out_long << block_size; palette.iter().enumerate().for_each(|(i, id)| {
} palette_map.insert(**id, i);
let index = palette_map // Palette
.get(block) data_buf.put_var_int(&VarInt(**id as i32));
.expect("Its just got added, ofc it should be there"); });
out_long = out_long | *index as i64; for block_clump in chunk.chunks(64 / block_size as usize) {
let mut out_long: i64 = 0;
for block in block_clump.iter().rev() {
let index = palette_map
.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);
}
}
PaletteType::Direct => {
// Bits per entry
data_buf.put_u8(DIRECT_PALETTE_BITS as u8);
for block_clump in chunk.chunks(64 / DIRECT_PALETTE_BITS as usize) {
let mut out_long: i64 = 0;
for block in block_clump.iter().rev() {
out_long = out_long << DIRECT_PALETTE_BITS | (**block as i64);
}
block_data_array.push(out_long);
}
} }
block_data_array.push(out_long);
} }
// Data array length // Data array length
// 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
for data_int in block_data_array { for data_int in block_data_array {

View File

@ -105,7 +105,7 @@ impl ChunkData {
} }
.into_inner(); .into_inner();
let block_size = { let block_size = {
let size = 64 - (palette.len() - 1).leading_zeros(); let size = 64 - (palette.len() as i64 - 1).leading_zeros();
if size >= 4 { if size >= 4 {
size size
} else { } else {
@ -114,14 +114,17 @@ impl ChunkData {
}; };
let mask = (1 << block_size) - 1; let mask = (1 << block_size) - 1;
println!("{block_size} {:#08b}", mask); // println!("{block_size} {:#08b}", mask);
println!( // println!(
"{} {}", // "{} {}",
block_size, // block_size,
palette.iter().map(|v| v.to_string()).join(",") // palette.iter().map(|v| v.to_string()).join(",")
); // );
let mut blocks_left = 16 * 16 * 16; let mut blocks_left = 16 * 16 * 16;
'block_loop: for (j, block) in block_data.iter().enumerate() { 'block_loop: for (j, block) in block_data.iter().enumerate() {
// if at == (0,0) && block_size != 4 {
// println!("{} {:#066b}", 64 - (64 / block_size) * block_size, *block);
// }
for i in 0..64 / block_size { for i in 0..64 / block_size {
if blocks_left <= 0 { if blocks_left <= 0 {
break 'block_loop; break 'block_loop;
@ -146,12 +149,13 @@ impl ChunkData {
// .as_bytes(), // .as_bytes(),
// ); // );
if at == (0, 0) { // if at == (0, 0) {
println!( // println!(
"[{}]", // "[{}]",
&blocks[0..10000].iter().map(|v| v.to_string()).join(",") // &blocks[0..10000].iter().map(|v| v.to_string()).join(",")
); // );
} // }
// dbg!("{}", blocks.iter().filter(|v| **v == 2005).collect_vec().len());
Ok(ChunkData { Ok(ChunkData {
blocks: blocks, blocks: blocks,
position: at, position: at,

View File

@ -2,5 +2,6 @@ pub mod chunk;
pub mod dimension; pub mod dimension;
pub const WORLD_HEIGHT: usize = 384; pub const WORLD_HEIGHT: usize = 384;
pub const WORLD_Y_START_AT: i32 = -64; // TODO: make sure where it actually starts at (i think its at -64 but not sure) pub const WORLD_Y_START_AT: i32 = -64; // TODO: make sure where it actually starts at (i think its at -64 but not sure)
pub const DIRECT_PALETTE_BITS: u32 = 15;
mod world; mod world;
mod block_registry; mod block_registry;

View File

@ -12,14 +12,13 @@ use mio::{event::Event, Poll, Token};
use num_traits::ToPrimitive; use num_traits::ToPrimitive;
use pumpkin_entity::{entity_type::EntityType, EntityId}; use pumpkin_entity::{entity_type::EntityType, EntityId};
use pumpkin_protocol::{ use pumpkin_protocol::{
client::{ bytebuf::ByteBuffer, client::{
config::CPluginMessage, config::CPluginMessage,
play::{ play::{
CCenterChunk, CChunkData, CChunkDataUpdateLight, CGameEvent, CLogin, CPlayerAbilities, CCenterChunk, CChunkData, CChunkDataUpdateLight, CGameEvent, CLogin, CPlayerAbilities,
CPlayerInfoUpdate, CRemoveEntities, CSpawnEntity, PlayerAction, CPlayerInfoUpdate, CRemoveEntities, CSpawnEntity, PlayerAction,
}, },
}, }, BitSet, ClientPacket, Players, Sample, StatusResponse, VarInt, Version, CURRENT_MC_PROTOCOL
BitSet, ClientPacket, Players, Sample, StatusResponse, VarInt, Version, CURRENT_MC_PROTOCOL,
}; };
use pumpkin_world::dimension::Dimension; use pumpkin_world::dimension::Dimension;
use rsa::{traits::PublicKeyParts, RsaPrivateKey, RsaPublicKey}; use rsa::{traits::PublicKeyParts, RsaPrivateKey, RsaPublicKey};
@ -316,13 +315,23 @@ impl Server {
chunk_z: 0.into(), chunk_z: 0.into(),
}); });
chunks.iter().for_each(|chunk| match &chunk.1 { chunks.iter().for_each(|chunk| {
if chunk.0 == (0,0) {
let mut test = ByteBuffer::empty();
CChunkData(chunk.1.as_ref().unwrap()).write(&mut test);
let len = test.buf().len();
dbg!("Chunk packet size: {}B {}KB {}MB", len, len/1024, len/(1024*1024));
}
match &chunk.1 {
Err(err) => println!( Err(err) => println!(
"Chunk loading failed for chunk ({},{}): {}", "Chunk loading failed for chunk ({},{}): {}",
chunk.0 .0, chunk.0 .1, err chunk.0 .0, chunk.0 .1, err
), ),
Ok(data) => client.send_packet(CChunkData(data)), Ok(data) => client.send_packet(CChunkData(data)),
}); }});
// let test_chunk = TestChunk::new(); // let test_chunk = TestChunk::new();
// client.send_packet(CChunkDataUpdateLight::new( // client.send_packet(CChunkDataUpdateLight::new(