diff --git a/.gitignore b/.gitignore index 8adfdd765..874a1cc2f 100644 --- a/.gitignore +++ b/.gitignore @@ -77,9 +77,7 @@ Cargo.lock # === PROJECT SPECIFIC === # mc decompiled source -mc-source-code/DecompilerMC/ -mc-source-code/src/ -mc-source-code/target/ +mc-source-code/ plugins/* world/* diff --git a/pumpkin-protocol/src/server/play/mod.rs b/pumpkin-protocol/src/server/play/mod.rs index 4723a6b57..6d97dd3d6 100644 --- a/pumpkin-protocol/src/server/play/mod.rs +++ b/pumpkin-protocol/src/server/play/mod.rs @@ -7,6 +7,7 @@ mod s_confirm_teleport; mod s_interact; mod s_keep_alive; mod s_ping_request; +mod s_player_abilities; mod s_player_action; mod s_player_command; mod s_player_ground; @@ -28,6 +29,7 @@ pub use s_confirm_teleport::*; pub use s_interact::*; pub use s_keep_alive::*; pub use s_ping_request::*; +pub use s_player_abilities::*; pub use s_player_action::*; pub use s_player_command::*; pub use s_player_ground::*; diff --git a/pumpkin-protocol/src/server/play/s_player_abilities.rs b/pumpkin-protocol/src/server/play/s_player_abilities.rs new file mode 100644 index 000000000..9d8631e8f --- /dev/null +++ b/pumpkin-protocol/src/server/play/s_player_abilities.rs @@ -0,0 +1,10 @@ +use pumpkin_macros::packet; +use serde::Deserialize; + +//The vanilla client sends this packet when the player starts/stops flying. Bitmask 0x02 is set when the player is flying. + +#[derive(Deserialize)] +#[packet(0x23)] +pub struct SPlayerAbilities { + pub flags: i8, +} diff --git a/pumpkin/src/client/player_packet.rs b/pumpkin/src/client/player_packet.rs index 6230eff12..a1a88bd61 100644 --- a/pumpkin/src/client/player_packet.rs +++ b/pumpkin/src/client/player_packet.rs @@ -15,7 +15,6 @@ use pumpkin_core::{ }; use pumpkin_entity::EntityId; use pumpkin_inventory::{InventoryError, WindowType}; -use pumpkin_protocol::server::play::{SCloseContainer, SSetPlayerGround, SUseItem}; use pumpkin_protocol::{ client::play::{ Animation, CAcknowledgeBlockChange, CBlockUpdate, CEntityAnimation, CEntityVelocity, @@ -23,10 +22,10 @@ use pumpkin_protocol::{ CUpdateEntityPosRot, CUpdateEntityRot, CWorldEvent, FilterType, }, server::play::{ - Action, ActionType, SChatCommand, SChatMessage, SClientInformationPlay, SConfirmTeleport, - SInteract, SPlayPingRequest, SPlayerAction, SPlayerCommand, SPlayerPosition, - SPlayerPositionRotation, SPlayerRotation, SSetCreativeSlot, SSetHeldItem, SSwingArm, - SUseItemOn, Status, + Action, ActionType, SChatCommand, SChatMessage, SClientInformationPlay, SCloseContainer, + SConfirmTeleport, SInteract, SPlayPingRequest, SPlayerAbilities, SPlayerAction, + SPlayerCommand, SPlayerPosition, SPlayerPositionRotation, SPlayerRotation, + SSetCreativeSlot, SSetHeldItem, SSetPlayerGround, SSwingArm, SUseItem, SUseItemOn, Status, }, }; use pumpkin_world::block::{BlockFace, BlockState}; @@ -466,6 +465,7 @@ impl Player { None => self.kick(TextComponent::text("Invalid action type")).await, } } + pub async fn handle_player_action(&self, player_action: SPlayerAction) { match Status::from_i32(player_action.status.0) { Some(status) => match status { @@ -539,6 +539,13 @@ impl Player { } } + pub async fn handle_player_abilities(&self, player_abilities: SPlayerAbilities) { + let mut abilities = self.abilities.lock().await; + + // Set the flying ability + abilities.flying = player_abilities.flags & 0x02 != 0 && abilities.allow_flying; + } + pub async fn handle_play_ping_request(&self, request: SPlayPingRequest) { self.client .send_packet(&CPingResponse::new(request.payload)) diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index cdf01ab2f..7ac249388 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -21,9 +21,9 @@ use pumpkin_protocol::{ }, server::play::{ SChatCommand, SChatMessage, SClickContainer, SClientInformationPlay, SConfirmTeleport, - SInteract, SPlayPingRequest, SPlayerAction, SPlayerCommand, SPlayerPosition, - SPlayerPositionRotation, SPlayerRotation, SSetCreativeSlot, SSetHeldItem, SSetPlayerGround, - SSwingArm, SUseItem, SUseItemOn, + SInteract, SPlayPingRequest, SPlayerAbilities, SPlayerAction, SPlayerCommand, + SPlayerPosition, SPlayerPositionRotation, SPlayerRotation, SSetCreativeSlot, SSetHeldItem, + SSetPlayerGround, SSwingArm, SUseItem, SUseItemOn, }, RawPacket, ServerPacket, VarInt, }; @@ -73,7 +73,7 @@ pub struct Player { /// This field represents the various abilities that the player possesses, such as flight, invulnerability, and other special effects. /// /// **Note:** When the `abilities` field is updated, the server should send a `send_abilities_update` packet to the client to notify them of the changes. - pub abilities: PlayerAbilities, + pub abilities: Mutex, /// The player's last known position. /// /// This field is used to calculate the player's movement delta for network synchronization and other purposes. @@ -129,7 +129,7 @@ impl Player { open_container: AtomicCell::new(None), carried_item: AtomicCell::new(None), teleport_id_count: AtomicI32::new(0), - abilities: PlayerAbilities::default(), + abilities: Mutex::new(PlayerAbilities::default()), gamemode: AtomicCell::new(gamemode), watched_section: AtomicCell::new(Vector3::new(0, 0, 0)), last_position: AtomicCell::new(Vector3::new(0.0, 0.0, 0.0)), @@ -157,7 +157,7 @@ impl Player { /// Updates the current abilities the Player has pub async fn send_abilties_update(&mut self) { let mut b = 0i8; - let abilities = &self.abilities; + let abilities = &self.abilities.lock().await; if abilities.invulnerable { b |= 1; @@ -379,6 +379,11 @@ impl Player { .await; Ok(()) } + SPlayerAbilities::PACKET_ID => { + self.handle_player_abilities(SPlayerAbilities::read(bytebuf)?) + .await; + Ok(()) + } SUseItemOn::PACKET_ID => { self.handle_use_item_on(SUseItemOn::read(bytebuf)?).await; Ok(())