NOW IT FULLY WORKS
This commit is contained in:
parent
a991ce214b
commit
eaf806a928
@ -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 {
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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;
|
||||||
@ -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(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user