diff --git a/crates/valence/src/client.rs b/crates/valence/src/client.rs index 796d017..79bba1a 100644 --- a/crates/valence/src/client.rs +++ b/crates/valence/src/client.rs @@ -39,7 +39,7 @@ use crate::component::{ Properties, UniqueId, Username, }; use crate::entity::{ - EntityId, EntityKind, EntityStatus, HeadYaw, ObjectData, TrackedData, Velocity, + EntityId, EntityKind, EntityStatus, HeadYaw, ObjectData, PacketByteRange, TrackedData, Velocity, }; use crate::instance::{Instance, WriteUpdatePacketsToInstancesSet}; use crate::inventory::{Inventory, InventoryKind}; @@ -859,16 +859,19 @@ fn read_data_in_old_view( mut clients: Query<( &mut Client, &mut EntityRemoveBuf, + &Location, &OldLocation, + &Position, &OldPosition, &OldViewDistance, + Option<&PacketByteRange>, )>, instances: Query<&Instance>, entities: Query<(EntityInitQuery, &OldPosition)>, entity_ids: Query<&EntityId>, ) { clients.par_iter_mut().for_each_mut( - |(mut client, mut remove_buf, old_loc, old_pos, old_view_dist)| { + |(mut client, mut remove_buf, loc, old_loc, pos, old_pos, old_view_dist, byte_range)| { let Ok(instance) = instances.get(old_loc.get()) else { return; }; @@ -877,9 +880,10 @@ fn read_data_in_old_view( client.write_packet_bytes(&instance.packet_buf); // TODO: cache the chunk position? - let chunk_pos = old_pos.chunk_pos(); + let old_chunk_pos = old_pos.chunk_pos(); + let new_chunk_pos = pos.chunk_pos(); - let view = ChunkView::new(chunk_pos, old_view_dist.0); + let view = ChunkView::new(old_chunk_pos, old_view_dist.0); // Iterate over all visible chunks from the previous tick. view.for_each(|pos| { @@ -925,7 +929,16 @@ fn read_data_in_old_view( // Send all data in the chunk's packet buffer to this client. This will update // entities in the cell, spawn or update the chunk in the cell, or send any // other packet data that was added here by users. - client.write_packet_bytes(&cell.packet_buf); + match byte_range { + Some(byte_range) if pos == new_chunk_pos && loc == old_loc => { + // Skip range of bytes for the client's own entity. + client.write_packet_bytes(&cell.packet_buf[..byte_range.0.start]); + client.write_packet_bytes(&cell.packet_buf[byte_range.0.end..]); + } + _ => { + client.write_packet_bytes(&cell.packet_buf); + } + } } }); }, @@ -940,6 +953,7 @@ fn read_data_in_old_view( fn update_view( mut clients: Query< ( + Entity, &mut Client, &mut ScratchBuf, &mut EntityRemoveBuf, @@ -958,6 +972,7 @@ fn update_view( ) { clients.par_iter_mut().for_each_mut( |( + entity, mut client, mut scratch, mut remove_buf, @@ -1000,8 +1015,11 @@ fn update_view( // Unload all the entities in the cell. for &id in &cell.entities { - if let Ok(entity_id) = entity_ids.get(id) { - remove_buf.push(entity_id.get()); + // Skip client's own entity. + if id != entity { + if let Ok(entity_id) = entity_ids.get(id) { + remove_buf.push(entity_id.get()); + } } } } @@ -1026,8 +1044,11 @@ fn update_view( // Load all the entities in this cell. for &id in &cell.entities { - if let Ok((entity, pos)) = entities.get(id) { - entity.write_init_packets(pos.get(), &mut client.enc); + // Skip client's own entity. + if id != entity { + if let Ok((entity, pos)) = entities.get(id) { + entity.write_init_packets(pos.get(), &mut client.enc); + } } } } diff --git a/crates/valence/src/component.rs b/crates/valence/src/component.rs index 3c0aa01..2d0bb1b 100644 --- a/crates/valence/src/component.rs +++ b/crates/valence/src/component.rs @@ -120,6 +120,12 @@ impl Default for Location { } } +impl PartialEq for Location { + fn eq(&self, other: &OldLocation) -> bool { + self.0 == other.0 + } +} + /// The value of [`Location`] from the end of the previous tick. /// /// **NOTE**: You should not modify this component after the entity is spawned. @@ -142,6 +148,12 @@ impl Default for OldLocation { } } +impl PartialEq for OldLocation { + fn eq(&self, other: &Location) -> bool { + self.0 == other.0 + } +} + #[derive(Component, Copy, Clone, PartialEq, Default, Debug)] pub struct Position(pub DVec3); @@ -163,6 +175,12 @@ impl Position { } } +impl PartialEq for Position { + fn eq(&self, other: &OldPosition) -> bool { + self.0 == other.0 + } +} + /// The value of [`Location`] from the end of the previous tick. /// /// **NOTE**: You should not modify this component after the entity is spawned. @@ -183,6 +201,12 @@ impl OldPosition { } } +impl PartialEq for OldPosition { + fn eq(&self, other: &Position) -> bool { + self.0 == other.0 + } +} + /// Describes the direction an entity is looking using pitch and yaw angles. #[derive(Component, Copy, Clone, PartialEq, Default, Debug)] pub struct Look {