From 3825ee2b28e2e1168f206eb77639c4cf5b703ea5 Mon Sep 17 00:00:00 2001 From: Alexander Medvedev Date: Sun, 5 Apr 2026 11:10:22 +0200 Subject: [PATCH] fix: bedrock jwt error --- .../src/bedrock/client/set_actor_data.rs | 52 ++++++++++++++----- pumpkin-protocol/src/bedrock/server/login.rs | 14 +++-- pumpkin/src/net/bedrock/mod.rs | 12 +++-- pumpkin/src/world/mod.rs | 12 +++-- 4 files changed, 62 insertions(+), 28 deletions(-) diff --git a/pumpkin-protocol/src/bedrock/client/set_actor_data.rs b/pumpkin-protocol/src/bedrock/client/set_actor_data.rs index fd6c72901..b5db28a15 100644 --- a/pumpkin-protocol/src/bedrock/client/set_actor_data.rs +++ b/pumpkin-protocol/src/bedrock/client/set_actor_data.rs @@ -20,28 +20,46 @@ pub struct CSetActorData { pub tick: VarULong, } -#[derive(Default)] pub struct EntityMetadata(pub HashMap); +impl Default for EntityMetadata { + fn default() -> Self { + Self::new() + } +} + +impl EntityMetadata { + #[must_use] + pub fn new() -> Self { + let mut map = HashMap::new(); + map.insert(entity_data_key::FLAGS, MetadataValue::Long(0)); + map.insert(entity_data_key::FLAGS_TWO, MetadataValue::Long(0)); + map.insert(entity_data_key::PLAYER_FLAGS, MetadataValue::Byte(0)); + Self(map) + } +} + impl EntityMetadata { pub fn set(&mut self, key: u32, value: MetadataValue) { self.0.insert(key, value); } - pub fn set_flag(&mut self, flag_index: u32) { - let (key, index) = if flag_index < 64 { - (entity_data_key::FLAGS, flag_index) + pub fn set_flag(&mut self, key: u32, index: u8) { + if key == entity_data_key::PLAYER_FLAGS { + let current_value = match self.0.get(&key) { + Some(MetadataValue::Byte(v)) => *v, + _ => 0, + }; + self.0 + .insert(key, MetadataValue::Byte(current_value | (1i8 << index))); } else { - (entity_data_key::FLAGS_TWO, flag_index - 64) - }; - - let current_value = match self.0.get(&key) { - Some(MetadataValue::Long(v)) => *v, - _ => 0, - }; - - self.0 - .insert(key, MetadataValue::Long(current_value | (1 << index))); + let current_value = match self.0.get(&key) { + Some(MetadataValue::Long(v)) => *v, + _ => 0, + }; + self.0 + .insert(key, MetadataValue::Long(current_value | (1i64 << index))); + } } } @@ -264,6 +282,12 @@ pub mod entity_data_key { pub const ENTER_BED_POSITION: u32 = 133; pub const SEAT_THIRD_PERSON_CAMERA_RADIUS: u32 = 134; pub const SEAT_CAMERA_RELAX_DISTANCE_SMOOTHING: u32 = 135; + pub const AIM_ASSIST_PRIORITY_PRESET_ID: u32 = 136; + pub const AIM_ASSIST_PRIORITY_CATEGORY_ID: u32 = 137; + pub const AIM_ASSIST_PRIORITY_ACTOR_ID: u32 = 138; + pub const ARROW_SHOOTER_ID: u32 = 139; + pub const FIREWORK_DIRECTION: u32 = 140; + pub const FIREWORK_SHOOTER_ID: u32 = 141; } pub mod entity_data_flag { diff --git a/pumpkin-protocol/src/bedrock/server/login.rs b/pumpkin-protocol/src/bedrock/server/login.rs index 482e01a8b..cad8104bc 100644 --- a/pumpkin-protocol/src/bedrock/server/login.rs +++ b/pumpkin-protocol/src/bedrock/server/login.rs @@ -16,29 +16,27 @@ pub struct SLogin { impl PacketRead for SLogin { fn read(reader: &mut R) -> Result { const MAX_TOKEN_SIZE: usize = 2000 * 1024; // 2MB limit - let protocol_version = i32::read_be(reader)?; - let _len = VarUInt::read(reader)?; - let jwt_len = u32::read_be(reader)? as usize; - if jwt_len > MAX_TOKEN_SIZE { + let jwt_len = u32::read(reader)?; + if jwt_len as usize > MAX_TOKEN_SIZE { return Err(Error::new( ErrorKind::InvalidData, "JWT length exceeds limit", )); } - let mut jwt = vec![0u8; jwt_len]; + let mut jwt = vec![0; jwt_len as _]; reader.read_exact(&mut jwt)?; - let raw_token_len = u32::read_be(reader)? as usize; - if raw_token_len > MAX_TOKEN_SIZE { + let raw_token_len = u32::read(reader)?; + if raw_token_len as usize > MAX_TOKEN_SIZE { return Err(Error::new( ErrorKind::InvalidData, "Raw token length exceeds limit", )); } - let mut raw_token = vec![0u8; raw_token_len]; + let mut raw_token = vec![0; raw_token_len as _]; reader.read_exact(&mut raw_token)?; Ok(Self { diff --git a/pumpkin/src/net/bedrock/mod.rs b/pumpkin/src/net/bedrock/mod.rs index aa6da647a..a3cf483ff 100644 --- a/pumpkin/src/net/bedrock/mod.rs +++ b/pumpkin/src/net/bedrock/mod.rs @@ -407,7 +407,8 @@ impl BedrockClient { debug!("received nack, client is missing packets"); } 0x80..0x8d => { - self.handle_frame_set(server, FrameSet::read(reader)?).await; + self.handle_frame_set(server, FrameSet::read(reader)?) + .await?; } id => { warn!("Bedrock: Received unknown packet header {id}"); @@ -418,13 +419,18 @@ impl BedrockClient { const fn handle_ack(_ack: &Ack) {} - async fn handle_frame_set(self: &Arc, server: &Arc, frame_set: FrameSet) { + async fn handle_frame_set( + self: &Arc, + server: &Arc, + frame_set: FrameSet, + ) -> Result<(), Error> { // TODO: Send all ACKs in short intervals in batches self.send_ack(&Ack::new(vec![frame_set.sequence.0])).await; // TODO for frame in frame_set.frames { - self.handle_frame(server, frame).await.unwrap(); + self.handle_frame(server, frame).await?; } + Ok(()) } async fn handle_frame( diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index 1c28a871a..074dda68f 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -1615,16 +1615,22 @@ impl World { let mut abilities = player.abilities.lock().await; abilities.set_for_gamemode(player.gamemode.load()); }; - let mut metadata = EntityMetadata::default(); + let mut metadata = EntityMetadata::new(); metadata.set(entity_data_key::WIDTH, MetadataValue::Float(0.6)); metadata.set(entity_data_key::HEIGHT, MetadataValue::Float(1.8)); // This is super important, otherwise the client will float by default - metadata.set_flag(entity_data_flag::HAS_GRAVITY); + metadata.set_flag(entity_data_key::FLAGS, entity_data_flag::HAS_GRAVITY as u8); + metadata.set_flag(entity_data_key::FLAGS, entity_data_flag::CLIMB as u8); + // Player-specific: survival has collision + metadata.set_flag( + entity_data_key::FLAGS, + entity_data_flag::HAS_COLLISION as u8, + ); // Prevents the client from showing air buddles on hud even when not in water - metadata.set_flag(entity_data_flag::BREATHING); + metadata.set_flag(entity_data_key::FLAGS, entity_data_flag::BREATHING as u8); let actor_data = CSetActorData { actor_runtime_id: VarULong(runtime_id), metadata,