diff --git a/README.md b/README.md index 817d42850..98b5e06aa 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ and customizable experience. It prioritizes performance and player enjoyment whi - [ ] Query - [x] RCON - [x] Inventories + - [x] Particles - [x] Chat - [x] Commands - Proxy diff --git a/pumpkin-protocol/src/client/play/c_particle.rs b/pumpkin-protocol/src/client/play/c_particle.rs new file mode 100644 index 000000000..5ef4f1b91 --- /dev/null +++ b/pumpkin-protocol/src/client/play/c_particle.rs @@ -0,0 +1,51 @@ +use pumpkin_macros::packet; +use serde::Serialize; + +use crate::VarInt; + +#[derive(Serialize)] +#[packet(0x29)] +pub struct CParticle<'a> { + /// If true, particle distance increases from 256 to 65536. + long_distance: bool, + x: f64, + y: f64, + z: f64, + offset_x: f32, + offset_y: f32, + offset_z: f32, + max_speed: f32, + particle_count: i32, + pariticle_id: VarInt, + data: &'a [u8], +} + +impl<'a> CParticle<'a> { + pub fn new( + long_distance: bool, + x: f64, + y: f64, + z: f64, + offset_x: f32, + offset_y: f32, + offset_z: f32, + max_speed: f32, + particle_count: i32, + pariticle_id: VarInt, + data: &'a [u8], + ) -> Self { + Self { + long_distance, + x, + y, + z, + offset_x, + offset_y, + offset_z, + max_speed, + particle_count, + pariticle_id, + data, + } + } +} diff --git a/pumpkin-protocol/src/client/play/mod.rs b/pumpkin-protocol/src/client/play/mod.rs index 122756990..1b352d21f 100644 --- a/pumpkin-protocol/src/client/play/mod.rs +++ b/pumpkin-protocol/src/client/play/mod.rs @@ -11,6 +11,7 @@ mod c_head_rot; mod c_hurt_animation; mod c_login; mod c_open_screen; +mod c_particle; mod c_play_disconnect; mod c_player_abilities; mod c_player_chat_message; @@ -41,6 +42,7 @@ pub use c_head_rot::*; pub use c_hurt_animation::*; pub use c_login::*; pub use c_open_screen::*; +pub use c_particle::*; pub use c_play_disconnect::*; pub use c_player_abilities::*; pub use c_player_chat_message::*; diff --git a/pumpkin-world/src/chunk.rs b/pumpkin-world/src/chunk.rs index f41034d58..459571bf5 100644 --- a/pumpkin-world/src/chunk.rs +++ b/pumpkin-world/src/chunk.rs @@ -114,17 +114,8 @@ impl ChunkData { }; let mask = (1 << block_size) - 1; - // 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; @@ -138,24 +129,6 @@ impl ChunkData { } } - // std::fs::File::create_new("../mafaile.txt") - // .unwrap() - // .write_all( - // blocks - // .iter() - // .map(|v| v.to_string()) - // .collect::>() - // .join(",") - // .as_bytes(), - // ); - - // 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, position: at, diff --git a/pumpkin-world/src/world.rs b/pumpkin-world/src/world.rs index 274ef7857..464ae3668 100644 --- a/pumpkin-world/src/world.rs +++ b/pumpkin-world/src/world.rs @@ -57,6 +57,18 @@ pub enum Compression { LZ4, } +impl Compression { + pub fn from_byte(byte: u8) -> Option { + match byte { + 1 => Some(Self::Gzip), + 2 => Some(Self::Zlib), + 3 => Some(Self::None), + 4 => Some(Self::LZ4), + _ => None, + } + } +} + impl Level { pub fn from_root_folder(root_folder: PathBuf) -> Self { // TODO: Check if exists @@ -177,13 +189,10 @@ impl Level { // TODO: check checksum to make sure chunk is not corrupted let header = file_buf.drain(0..5).collect_vec(); - let compression = match header[4] { - 1 => Compression::Gzip, - 2 => Compression::Zlib, - 3 => Compression::None, - 4 => Compression::LZ4, - _ => { - let _ = channel.send(( + let compression = match Compression::from_byte(header[4]) { + Some(c) => c, + None => { + let _ = channel.blocking_send(( (chunk.0, chunk.1), Err(WorldError::Compression( CompressionError::UnknownCompression, @@ -193,20 +202,23 @@ impl Level { } }; - let size = u32::from_be_bytes(header[0..4].try_into().unwrap()); + let size = u32::from_be_bytes(header[..4].try_into().unwrap()); // size includes the compression scheme byte, so we need to subtract 1 let chunk_data = file_buf.drain(0..size as usize - 1).collect_vec(); let decompressed_chunk = match Self::decompress_data(compression, chunk_data) { Ok(data) => data, Err(e) => { - let _ = channel.send(((chunk.0, chunk.1), Err(WorldError::Compression(e)))); + channel + .blocking_send(((chunk.0, chunk.1), Err(WorldError::Compression(e)))) + .expect("Failed to send Compression error"); return; } }; - let _ = channel - .blocking_send((chunk, ChunkData::from_bytes(decompressed_chunk, chunk))); + channel + .blocking_send((chunk, ChunkData::from_bytes(decompressed_chunk, chunk))) + .expect("Error sending decompressed chunk"); }) .collect::>(); } diff --git a/pumpkin/src/client/player_packet.rs b/pumpkin/src/client/player_packet.rs index 47fa3e44f..953f97058 100644 --- a/pumpkin/src/client/player_packet.rs +++ b/pumpkin/src/client/player_packet.rs @@ -2,8 +2,8 @@ use num_traits::FromPrimitive; use pumpkin_entity::EntityId; use pumpkin_protocol::{ client::play::{ - Animation, CEntityAnimation, CEntityVelocity, CHeadRot, CHurtAnimation, CSystemChatMessge, - CUpdateEntityPos, CUpdateEntityPosRot, CUpdateEntityRot, + Animation, CEntityAnimation, CEntityVelocity, CHeadRot, CHurtAnimation, + CSystemChatMessge, CUpdateEntityPos, CUpdateEntityPosRot, CUpdateEntityRot, }, server::play::{ Action, SChatCommand, SChatMessage, SClientInformationPlay, SConfirmTeleport, SInteract, @@ -217,6 +217,7 @@ impl Client { false, ), ); + /* server.broadcast_packet( self, CPlayerChatMessage::new(