Chunks: remove some clone's

This commit is contained in:
Snowiiii 2024-08-13 10:53:24 +02:00
parent 9fc86e260b
commit 651089033d
8 changed files with 91 additions and 112 deletions

View File

@ -150,7 +150,7 @@ impl ByteBuffer {
pub fn put_bit_set(&mut self, set: &BitSet) { pub fn put_bit_set(&mut self, set: &BitSet) {
self.put_var_int(&set.0); self.put_var_int(&set.0);
for b in &set.1 { for b in set.1 {
self.put_i64(*b); self.put_i64(*b);
} }
} }

View File

@ -7,13 +7,13 @@ use crate::{BitSet, ClientPacket, ServerPacket, VarInt, VarIntType};
use super::{deserializer, serializer, ByteBuffer, DeserializerError}; use super::{deserializer, serializer, ByteBuffer, DeserializerError};
impl Serialize for BitSet { impl Serialize for BitSet<'static> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
S: Serializer, S: Serializer,
{ {
// TODO: make this right // TODO: make this right
(self.0.clone(), self.1.clone()).serialize(serializer) (&self.0, self.1).serialize(serializer)
} }
} }

View File

@ -22,92 +22,89 @@ 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();
self.0 self.0.blocks.chunks(16 * 16 * 16).for_each(|chunk| {
.blocks let block_count = chunk
.iter() .iter()
.chunks(16 * 16 * 16) .dedup()
.into_iter() .filter(|block| **block != 0 && **block != 12959 && **block != 12958)
.for_each(|chunk| { .count() as i16;
let chunk = chunk.collect_vec(); // Block count
let block_count = chunk data_buf.put_i16(block_count);
.iter() //// Block states
.filter(|block| ***block != 0 && ***block != 12959 && ***block != 12958)
.count() as i16;
// Block count
data_buf.put_i16(block_count);
//// Block states
let palette = chunk.clone().into_iter().dedup().collect_vec(); let palette = chunk.into_iter().dedup().collect_vec();
// TODO: make dynamic block_size work // TODO: make dynamic block_size work
// TODO: make direct block_size work // TODO: make direct block_size work
enum PaletteType { enum PaletteType {
Indirect(u32), Indirect(u32),
Direct, 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)
} }
let palette_type = { // TODO: fix indirect palette to work correctly
let palette_bit_len = 64 - (palette.len() as i64 - 1).leading_zeros(); // PaletteType::Direct
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(); let mut block_data_array = Vec::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(); let mut palette_map = HashMap::new();
palette.iter().enumerate().for_each(|(i, id)| { palette.iter().enumerate().for_each(|(i, id)| {
palette_map.insert(**id, i); palette_map.insert(*id, i);
// Palette // Palette
data_buf.put_var_int(&VarInt(**id as i32)); data_buf.put_var_int(&VarInt(**id as i32));
}); });
for block_clump in chunk.chunks(64 / block_size as usize) { 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 let index = palette_map
.get(*block) .get(block)
.expect("Its just got added, ofc it should be there"); .expect("Its just got added, ofc it should be there");
out_long = out_long << block_size | (*index as i64); out_long = out_long << block_size | (*index as i64);
}
block_data_array.push(out_long);
} }
block_data_array.push(out_long);
} }
PaletteType::Direct => { }
// Bits per entry PaletteType::Direct => {
data_buf.put_u8(DIRECT_PALETTE_BITS as u8); // Bits per entry
for block_clump in chunk.chunks(64 / DIRECT_PALETTE_BITS as usize) { data_buf.put_u8(DIRECT_PALETTE_BITS as u8);
let mut out_long: i64 = 0; for block_clump in chunk.chunks(64 / DIRECT_PALETTE_BITS as usize) {
for block in block_clump.iter().rev() { let mut out_long: i64 = 0;
out_long = out_long << DIRECT_PALETTE_BITS | (**block as i64); let mut shift = 0;
} for block in block_clump {
block_data_array.push(out_long); out_long |= (*block as i64) << shift;
shift += DIRECT_PALETTE_BITS;
} }
block_data_array.push(out_long);
} }
} }
}
// Data array length // Data array length
// 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
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);
} }
//// Biomes //// Biomes
// TODO: make biomes work // TODO: make biomes work
data_buf.put_u8(0); data_buf.put_u8(0);
data_buf.put_var_int(&VarInt(0)); data_buf.put_var_int(&VarInt(0));
data_buf.put_var_int(&VarInt(0)); data_buf.put_var_int(&VarInt(0));
}); });
// Size // Size
buf.put_var_int(&VarInt(data_buf.buf().len() as i32)); buf.put_var_int(&VarInt(data_buf.buf().len() as i32));
@ -118,10 +115,10 @@ impl<'a> ClientPacket for CChunkData<'a> {
buf.put_var_int(&VarInt(0)); buf.put_var_int(&VarInt(0));
// TODO // TODO
buf.put_bit_set(&BitSet(VarInt(1), vec![0])); buf.put_bit_set(&BitSet(VarInt(1), &[0]));
buf.put_bit_set(&BitSet(VarInt(1), vec![0])); buf.put_bit_set(&BitSet(VarInt(1), &[0]));
buf.put_bit_set(&BitSet(VarInt(1), vec![0])); buf.put_bit_set(&BitSet(VarInt(1), &[0]));
buf.put_bit_set(&BitSet(VarInt(1), vec![0])); buf.put_bit_set(&BitSet(VarInt(1), &[0]));
// buf.put_bit_set(&BitSet(VarInt(0), vec![])); // buf.put_bit_set(&BitSet(VarInt(0), vec![]));
// buf.put_bit_set(&BitSet(VarInt(0), vec![])); // buf.put_bit_set(&BitSet(VarInt(0), vec![]));
// buf.put_bit_set(&BitSet(VarInt(0), vec![])); // buf.put_bit_set(&BitSet(VarInt(0), vec![]));

View File

@ -4,7 +4,6 @@ use crate::{bytebuf::ByteBuffer, ClientPacket, Property};
use super::PlayerAction; use super::PlayerAction;
#[derive(Clone)]
#[packet(0x3E)] #[packet(0x3E)]
pub struct CPlayerInfoUpdate<'a> { pub struct CPlayerInfoUpdate<'a> {
pub actions: i8, pub actions: i8,

View File

@ -22,7 +22,7 @@ pub type Identifier = String;
pub type VarIntType = i32; pub type VarIntType = i32;
pub type VarLongType = i64; pub type VarLongType = i64;
pub struct BitSet(pub VarInt, pub Vec<i64>); pub struct BitSet<'a>(pub VarInt, pub &'a [i64]);
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct VarInt(pub VarIntType); pub struct VarInt(pub VarIntType);

View File

@ -271,7 +271,7 @@ impl Client {
} }
drop(client); drop(client);
if config.hurt_animation { if config.hurt_animation {
// todo // TODO
server.broadcast_packet(self, &CHurtAnimation::new(interact.entity_id, 10.0)) server.broadcast_packet(self, &CHurtAnimation::new(interact.entity_id, 10.0))
} }
} }

View File

@ -15,6 +15,6 @@ impl<'a> Command<'a> for PumpkinCommand {
fn on_execute(sender: &mut super::CommandSender<'a>, _command: String) { fn on_execute(sender: &mut super::CommandSender<'a>, _command: String) {
let version = env!("CARGO_PKG_VERSION"); let version = env!("CARGO_PKG_VERSION");
let description = env!("CARGO_PKG_DESCRIPTION"); let description = env!("CARGO_PKG_DESCRIPTION");
sender.send_message(TextComponent::from(format!("Pumpkin {version}, {description} (Minecraft {CURRENT_MC_VERSION}, Protocol {CURRENT_MC_PROTOCOL})")).color_named(NamedColor::Green).bold()) sender.send_message(TextComponent::from(format!("Pumpkin {version}, {description} (Minecraft {CURRENT_MC_VERSION}, Protocol {CURRENT_MC_PROTOCOL})")).color_named(NamedColor::Green))
} }
} }

View File

@ -127,17 +127,14 @@ impl Server {
pub fn remove_client(&mut self, token: &Token) { pub fn remove_client(&mut self, token: &Token) {
let client = self.current_clients.remove(token).unwrap(); let client = self.current_clients.remove(token).unwrap();
let mut client = client.borrow_mut(); let client = client.borrow();
// despawn the player // despawn the player
// todo: put this into the entitiy struct // todo: put this into the entitiy struct
if client.is_player() { if client.is_player() {
let id = client.player.as_ref().unwrap().entity_id(); let id = client.player.as_ref().unwrap().entity_id();
let uuid = client.gameprofile.as_ref().unwrap().id; let uuid = client.gameprofile.as_ref().unwrap().id;
self.broadcast_packet_expect( self.broadcast_packet_expect(&client, &CRemovePlayerInfo::new(1.into(), &[UUID(uuid)]));
&mut client, self.broadcast_packet_expect(&client, &CRemoveEntities::new(&[id.into()]))
&CRemovePlayerInfo::new(1.into(), &[UUID(uuid)]),
);
self.broadcast_packet_expect(&mut client, &CRemoveEntities::new(&[id.into()]))
} }
} }
@ -313,7 +310,6 @@ impl Server {
// Check if client is a player // Check if client is a player
let mut client = client.borrow_mut(); let mut client = client.borrow_mut();
if client.is_player() { if client.is_player() {
// we need to clone, Because we send a new packet to every client
client.send_packet(packet); client.send_packet(packet);
} }
} }
@ -327,7 +323,6 @@ impl Server {
// Check if client is a player // Check if client is a player
let mut client = client.borrow_mut(); let mut client = client.borrow_mut();
if client.is_player() { if client.is_player() {
// we need to clone, Because we send a new packet to every client
client.send_packet(packet); client.send_packet(packet);
} }
} }
@ -360,7 +355,7 @@ impl Server {
let mut test = ByteBuffer::empty(); let mut test = ByteBuffer::empty();
CChunkData(chunk.1.as_ref().unwrap()).write(&mut test); CChunkData(chunk.1.as_ref().unwrap()).write(&mut test);
let len = test.buf().len(); let len = test.buf().len();
dbg!( log::debug!(
"Chunk packet size: {}B {}KB {}MB", "Chunk packet size: {}B {}KB {}MB",
len, len,
len / 1024, len / 1024,
@ -368,27 +363,15 @@ impl Server {
); );
} }
match &chunk.1 { match &chunk.1 {
Err(err) => println!( Err(err) => log::warn!(
"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();
// client.send_packet(CChunkDataUpdateLight::new(
// 10,
// 10,
// test_chunk.heightmap,
// Vec::new(),
// Vec::new(),
// BitSet(0.into(), Vec::new()),
// BitSet(0.into(), Vec::new()),
// BitSet(0.into(), Vec::new()),
// Vec::new(),
// Vec::new(),
// ));
} }
// move to world // move to world