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,
}
#[derive(Default)]
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 {
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 {

View File

@ -16,29 +16,27 @@ pub struct SLogin {
impl PacketRead for SLogin {
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
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 {

View File

@ -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<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
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(

View File

@ -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,