fix: bedrock jwt error

This commit is contained in:
Alexander Medvedev 2026-04-05 11:10:22 +02:00
parent 5edd0e93df
commit 3825ee2b28
4 changed files with 62 additions and 28 deletions

View File

@ -20,28 +20,46 @@ pub struct CSetActorData {
pub tick: VarULong, pub tick: VarULong,
} }
#[derive(Default)]
pub struct EntityMetadata(pub HashMap<u32, MetadataValue>); pub struct EntityMetadata(pub HashMap<u32, MetadataValue>);
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 { impl EntityMetadata {
pub fn set(&mut self, key: u32, value: MetadataValue) { pub fn set(&mut self, key: u32, value: MetadataValue) {
self.0.insert(key, value); self.0.insert(key, value);
} }
pub fn set_flag(&mut self, flag_index: u32) { pub fn set_flag(&mut self, key: u32, index: u8) {
let (key, index) = if flag_index < 64 { if key == entity_data_key::PLAYER_FLAGS {
(entity_data_key::FLAGS, flag_index) let current_value = match self.0.get(&key) {
} else { Some(MetadataValue::Byte(v)) => *v,
(entity_data_key::FLAGS_TWO, flag_index - 64) _ => 0,
}; };
self.0
.insert(key, MetadataValue::Byte(current_value | (1i8 << index)));
} else {
let current_value = match self.0.get(&key) { let current_value = match self.0.get(&key) {
Some(MetadataValue::Long(v)) => *v, Some(MetadataValue::Long(v)) => *v,
_ => 0, _ => 0,
}; };
self.0 self.0
.insert(key, MetadataValue::Long(current_value | (1 << index))); .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 ENTER_BED_POSITION: u32 = 133;
pub const SEAT_THIRD_PERSON_CAMERA_RADIUS: u32 = 134; pub const SEAT_THIRD_PERSON_CAMERA_RADIUS: u32 = 134;
pub const SEAT_CAMERA_RELAX_DISTANCE_SMOOTHING: u32 = 135; 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 { pub mod entity_data_flag {

View File

@ -16,29 +16,27 @@ pub struct SLogin {
impl PacketRead for SLogin { impl PacketRead for SLogin {
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> { fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
const MAX_TOKEN_SIZE: usize = 2000 * 1024; // 2MB limit const MAX_TOKEN_SIZE: usize = 2000 * 1024; // 2MB limit
let protocol_version = i32::read_be(reader)?; let protocol_version = i32::read_be(reader)?;
let _len = VarUInt::read(reader)?; let _len = VarUInt::read(reader)?;
let jwt_len = u32::read_be(reader)? as usize; let jwt_len = u32::read(reader)?;
if jwt_len > MAX_TOKEN_SIZE { if jwt_len as usize > MAX_TOKEN_SIZE {
return Err(Error::new( return Err(Error::new(
ErrorKind::InvalidData, ErrorKind::InvalidData,
"JWT length exceeds limit", "JWT length exceeds limit",
)); ));
} }
let mut jwt = vec![0u8; jwt_len]; let mut jwt = vec![0; jwt_len as _];
reader.read_exact(&mut jwt)?; reader.read_exact(&mut jwt)?;
let raw_token_len = u32::read_be(reader)? as usize; let raw_token_len = u32::read(reader)?;
if raw_token_len > MAX_TOKEN_SIZE { if raw_token_len as usize > MAX_TOKEN_SIZE {
return Err(Error::new( return Err(Error::new(
ErrorKind::InvalidData, ErrorKind::InvalidData,
"Raw token length exceeds limit", "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)?; reader.read_exact(&mut raw_token)?;
Ok(Self { Ok(Self {

View File

@ -407,7 +407,8 @@ impl BedrockClient {
debug!("received nack, client is missing packets"); debug!("received nack, client is missing packets");
} }
0x80..0x8d => { 0x80..0x8d => {
self.handle_frame_set(server, FrameSet::read(reader)?).await; self.handle_frame_set(server, FrameSet::read(reader)?)
.await?;
} }
id => { id => {
warn!("Bedrock: Received unknown packet header {id}"); warn!("Bedrock: Received unknown packet header {id}");
@ -418,13 +419,18 @@ impl BedrockClient {
const fn handle_ack(_ack: &Ack) {} const fn handle_ack(_ack: &Ack) {}
async fn handle_frame_set(self: &Arc<Self>, server: &Arc<Server>, frame_set: FrameSet) { async fn handle_frame_set(
self: &Arc<Self>,
server: &Arc<Server>,
frame_set: FrameSet,
) -> Result<(), Error> {
// TODO: Send all ACKs in short intervals in batches // TODO: Send all ACKs in short intervals in batches
self.send_ack(&Ack::new(vec![frame_set.sequence.0])).await; self.send_ack(&Ack::new(vec![frame_set.sequence.0])).await;
// TODO // TODO
for frame in frame_set.frames { for frame in frame_set.frames {
self.handle_frame(server, frame).await.unwrap(); self.handle_frame(server, frame).await?;
} }
Ok(())
} }
async fn handle_frame( async fn handle_frame(

View File

@ -1615,16 +1615,22 @@ impl World {
let mut abilities = player.abilities.lock().await; let mut abilities = player.abilities.lock().await;
abilities.set_for_gamemode(player.gamemode.load()); 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::WIDTH, MetadataValue::Float(0.6));
metadata.set(entity_data_key::HEIGHT, MetadataValue::Float(1.8)); metadata.set(entity_data_key::HEIGHT, MetadataValue::Float(1.8));
// This is super important, otherwise the client will float by default // 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 // 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 { let actor_data = CSetActorData {
actor_runtime_id: VarULong(runtime_id), actor_runtime_id: VarULong(runtime_id),
metadata, metadata,