From d66d63cc4b4d703a14ed8c9510fbb8f6717b47ab Mon Sep 17 00:00:00 2001 From: David Alasow Date: Mon, 27 Sep 2021 13:34:23 +0200 Subject: [PATCH 1/4] Add Pose Enum and change Const name for it. --- feather/base/src/metadata.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/feather/base/src/metadata.rs b/feather/base/src/metadata.rs index bf5d513a5..46178ebde 100644 --- a/feather/base/src/metadata.rs +++ b/feather/base/src/metadata.rs @@ -20,7 +20,7 @@ pub const META_INDEX_IS_CUSTOM_NAME_VISIBLE: u8 = 3; pub const META_INDEX_IS_SILENT: u8 = 4; pub const META_INDEX_NO_GRAVITY: u8 = 5; -pub const META_INDEX_ITEM_SLOT: u8 = 6; +pub const META_INDEX_POSE: u8 = 6; pub const META_INDEX_FALLING_BLOCK_SPAWN_POSITION: u8 = 7; @@ -85,6 +85,30 @@ impl MetaEntry { } } +pub enum Pose { + Standing, + FallFlying, + Sleeping, + Swimming, + SpinAttack, + Sneaking, + Dying, +} + +impl ToMetaEntry for Pose { + fn to_meta_entry(&self) -> MetaEntry { + MetaEntry::Pose(match self { + Self::Standing => 0, + Self::FallFlying => 1, + Self::Sleeping => 2, + Self::Swimming => 3, + Self::SpinAttack => 4, + Self::Sneaking => 5, + Self::Dying => 6, + }) + } +} + pub trait ToMetaEntry { fn to_meta_entry(&self) -> MetaEntry; } From e578c48318402de5522a12c05810ba6a58e5f13b Mon Sep 17 00:00:00 2001 From: David Alasow Date: Mon, 27 Sep 2021 13:34:59 +0200 Subject: [PATCH 2/4] Add client function to send `SendEntityMetadata` packet. --- feather/server/src/client.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/feather/server/src/client.rs b/feather/server/src/client.rs index ca5f07533..bf25d17fb 100644 --- a/feather/server/src/client.rs +++ b/feather/server/src/client.rs @@ -547,6 +547,16 @@ impl Client { }); } + pub fn send_entity_metadata(&self, network_id: NetworkId, metadata: EntityMetadata) { + if self.network_id().unwrap() == network_id { + return; + } + self.send_packet(SendEntityMetadata { + entity_id: network_id.0, + entries: metadata, + }); + } + pub fn send_abilities(&self, abilities: &base::anvil::player::PlayerAbilities) { let mut bitfield = 0; if *abilities.invulnerable { From ad0c8d49192591ceeab3fcdb49cb9928a1881a91 Mon Sep 17 00:00:00 2001 From: David Alasow Date: Mon, 27 Sep 2021 13:35:38 +0200 Subject: [PATCH 3/4] Add entity_sneak and entity_sprint systems for metadata. --- feather/server/src/systems/entity.rs | 64 ++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/feather/server/src/systems/entity.rs b/feather/server/src/systems/entity.rs index fd02c9575..37e77cef5 100644 --- a/feather/server/src/systems/entity.rs +++ b/feather/server/src/systems/entity.rs @@ -1,10 +1,16 @@ //! Sends entity-related packets to clients. //! Spawn packets, position updates, equipment, animations, etc. -use base::Position; +use base::{ + metadata::{EntityBitMask, Pose, META_INDEX_ENTITY_BITMASK, META_INDEX_POSE}, + EntityMetadata, Position, +}; use common::Game; use ecs::{SysResult, SystemExecutor}; -use quill_common::components::OnGround; +use quill_common::{ + components::{OnGround, Sprinting}, + events::{SneakEvent, SprintEvent}, +}; use crate::{entities::PreviousPosition, NetworkId, Server}; @@ -12,7 +18,11 @@ mod spawn_packet; pub fn register(game: &mut Game, systems: &mut SystemExecutor) { spawn_packet::register(game, systems); - systems.group::().add_system(send_entity_movement); + systems + .group::() + .add_system(send_entity_movement) + .add_system(send_entity_sneak_metadata) + .add_system(send_entity_sprint_metadata); } /// Sends entity movement packets. @@ -31,3 +41,51 @@ fn send_entity_movement(game: &mut Game, server: &mut Server) -> SysResult { } Ok(()) } + +/// Sends [SendEntityMetadata](protocol::packets::server::play::SendEntityMetadata) packet for when an entity is sneaking. +fn send_entity_sneak_metadata(game: &mut Game, server: &mut Server) -> SysResult { + for (_, (&position, &SneakEvent { is_sneaking }, is_sprinting, &network_id)) in game + .ecs + .query::<(&Position, &SneakEvent, &Sprinting, &NetworkId)>() + .iter() + { + let mut metadata = EntityMetadata::entity_base(); + let mut bit_mask = EntityBitMask::empty(); + + // The Entity can sneak and sprint at the same time, what happens is that when it stops sneaking you immediately start running again. + bit_mask.set(EntityBitMask::CROUCHED, is_sneaking); + bit_mask.set(EntityBitMask::SPRINTING, is_sprinting.0); + metadata.set(META_INDEX_ENTITY_BITMASK, bit_mask.bits()); + + if is_sneaking { + metadata.set(META_INDEX_POSE, Pose::Sneaking); + } else { + metadata.set(META_INDEX_POSE, Pose::Standing); + } + + server.broadcast_nearby_with(position, |client| { + client.send_entity_metadata(network_id, metadata.clone()); + }); + } + Ok(()) +} + +/// Sends [SendEntityMetadata](protocol::packets::server::play::SendEntityMetadata) packet for when an entity is sprinting. +fn send_entity_sprint_metadata(game: &mut Game, server: &mut Server) -> SysResult { + for (_, (&position, &SprintEvent { is_sprinting }, &network_id)) in game + .ecs + .query::<(&Position, &SprintEvent, &NetworkId)>() + .iter() + { + let mut metadata = EntityMetadata::entity_base(); + let mut bit_mask = EntityBitMask::empty(); + + bit_mask.set(EntityBitMask::SPRINTING, is_sprinting); + metadata.set(META_INDEX_ENTITY_BITMASK, bit_mask.bits()); + + server.broadcast_nearby_with(position, |client| { + client.send_entity_metadata(network_id, metadata.clone()); + }); + } + Ok(()) +} From 89ec641616b150fd86e5adc1d9a6b939b50bdace Mon Sep 17 00:00:00 2001 From: David Alasow Date: Mon, 27 Sep 2021 17:38:25 +0200 Subject: [PATCH 4/4] don't call the function. --- feather/server/src/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feather/server/src/client.rs b/feather/server/src/client.rs index bf25d17fb..8fed3d128 100644 --- a/feather/server/src/client.rs +++ b/feather/server/src/client.rs @@ -548,7 +548,7 @@ impl Client { } pub fn send_entity_metadata(&self, network_id: NetworkId, metadata: EntityMetadata) { - if self.network_id().unwrap() == network_id { + if self.network_id == Some(network_id) { return; } self.send_packet(SendEntityMetadata {