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

View File

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

View File

@ -2,5 +2,6 @@ pub mod chunk;
pub mod dimension;
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 DIRECT_PALETTE_BITS: u32 = 15;
mod world;
mod block_registry;

View File

@ -12,14 +12,13 @@ use mio::{event::Event, Poll, Token};
use num_traits::ToPrimitive;
use pumpkin_entity::{entity_type::EntityType, EntityId};
use pumpkin_protocol::{
client::{
bytebuf::ByteBuffer, client::{
config::CPluginMessage,
play::{
CCenterChunk, CChunkData, CChunkDataUpdateLight, CGameEvent, CLogin, CPlayerAbilities,
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 rsa::{traits::PublicKeyParts, RsaPrivateKey, RsaPublicKey};
@ -316,13 +315,23 @@ impl Server {
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!(
"Chunk loading failed for chunk ({},{}): {}",
chunk.0 .0, chunk.0 .1, err
),
Ok(data) => client.send_packet(CChunkData(data)),
});
}});
// let test_chunk = TestChunk::new();
// client.send_packet(CChunkDataUpdateLight::new(