From 24ae9faa4f7a92237e692ec6775665ec14fe5900 Mon Sep 17 00:00:00 2001 From: Demetrius Kanios Date: Tue, 25 Aug 2026 09:06:23 -0700 Subject: [PATCH] chore(bedrock): Update most of the packets to mirror the official docs (#3044) * chore(bedrock): Update most of the packets to mirror the official docs more closely. * Fix typo * Fix CCreativeContent * Undo unrelated `registry.rs` change * Update WIT to merged PR --------- Signed-off-by: Demetrius Kanios --- crates/pumpkin-plugin-wit | 2 +- .../src/bedrock/client/add_actor.rs | 73 +-- .../src/bedrock/client/add_item_actor.rs | 14 +- .../src/bedrock/client/add_player.rs | 110 +---- .../src/bedrock/client/available_commands.rs | 99 ++--- .../src/bedrock/client/block_actor_data.rs | 22 +- .../src/bedrock/client/block_event.rs | 27 +- .../src/bedrock/client/change_dimension.rs | 16 +- ...dius_update.rs => chunk_radius_updated.rs} | 5 +- .../client/client_cache_miss_response.rs | 29 +- .../src/bedrock/client/common.rs | 96 +++- .../src/bedrock/client/container_open.rs | 3 +- ...e.rs => correct_player_move_prediction.rs} | 5 +- .../src/bedrock/client/creative_content.rs | 48 +- .../{disconnect_player.rs => disconnect.rs} | 9 +- .../src/bedrock/client/gamerules_changed.rs | 26 +- .../src/bedrock/client/inventory_content.rs | 3 +- .../src/bedrock/client/inventory_slot.rs | 10 +- .../src/bedrock/client/item_registry.rs | 12 +- .../src/bedrock/client/item_stack_response.rs | 45 +- .../src/bedrock/client/level_event.rs | 2 + .../src/bedrock/client/level_sound_event.rs | 22 +- .../src/bedrock/client/mob_effect.rs | 37 +- .../src/bedrock/client/mob_equipment.rs | 40 +- .../src/bedrock/client/mod.rs | 22 +- .../src/bedrock/client/modal_form_request.rs | 4 +- .../src/bedrock/client/move_actor_absolute.rs | 31 +- .../src/bedrock/client/network_settings.rs | 26 +- .../src/bedrock/client/play_status.rs | 3 + .../src/bedrock/client/player_hotbar.rs | 4 +- .../src/bedrock/client/remove_actor.rs | 8 +- .../src/bedrock/client/remove_objective.rs | 10 + .../src/bedrock/client/resource_pack_stack.rs | 31 +- .../src/bedrock/client/resource_packs_info.rs | 55 ++- .../src/bedrock/client/respawn.rs | 49 -- .../src/bedrock/client/set_actor_data.rs | 65 ++- .../src/bedrock/client/set_actor_link.rs | 10 +- .../src/bedrock/client/set_actor_motion.rs | 13 +- .../src/bedrock/client/set_difficulty.rs | 11 +- .../bedrock/client/set_display_objective.rs | 14 + .../src/bedrock/client/set_health.rs | 12 +- .../src/bedrock/client/set_player_gamemode.rs | 9 +- .../client/{scoreboard.rs => set_score.rs} | 24 - .../src/bedrock/client/set_spawn_position.rs | 36 +- .../src/bedrock/client/set_time.rs | 2 + .../src/bedrock/client/set_title.rs | 58 ++- .../src/bedrock/client/show_credits.rs | 14 +- .../src/bedrock/client/start_game.rs | 36 +- .../src/bedrock/client/take_item_actor.rs | 12 +- .../src/bedrock/client/transfer.rs | 14 +- .../src/bedrock/client/update_abilities.rs | 14 +- .../src/bedrock/client/update_attributes.rs | 27 +- .../src/bedrock/client/update_block.rs | 12 +- .../src/bedrock/client/update_trade.rs | 2 + .../src/bedrock/enum_as_str.rs | 44 ++ crates/pumpkin-protocol/src/bedrock/mod.rs | 2 +- .../pumpkin-protocol/src/bedrock/respawn.rs | 31 -- .../src/bedrock/server/actor_event.rs | 148 ++++--- .../src/bedrock/server/animate.rs | 56 ++- .../src/bedrock/server/block_pick_request.rs | 8 +- .../server/client_cache_blob_status.rs | 10 +- .../src/bedrock/server/client_cache_status.rs | 5 +- .../src/bedrock/server/command_request.rs | 19 +- .../src/bedrock/server/container_close.rs | 5 +- .../src/bedrock/server/emote.rs | 6 +- .../src/bedrock/server/emote_list.rs | 14 +- .../src/bedrock/server/interact.rs | 39 ++ .../src/bedrock/server/interaction.rs | 48 -- .../src/bedrock/server/loading_screen.rs | 34 +- .../src/bedrock/server/mob_equipment.rs | 35 +- .../src/bedrock/server/mod.rs | 10 +- .../src/bedrock/server/modal_form_response.rs | 8 +- .../server/packet_violation_warning.rs | 23 +- .../src/bedrock/server/player_action.rs | 128 +++--- .../src/bedrock/server/player_hotbar.rs | 7 +- .../bedrock/server/request_chunk_radius.rs | 5 +- .../server/request_network_settings.rs | 6 +- ...se.rs => resource_pack_client_response.rs} | 6 +- .../src/bedrock/server/respawn.rs | 61 ++- .../server/set_local_player_as_initialized.rs | 4 +- .../server/set_player_inventory_options.rs | 12 +- .../pumpkin-protocol/src/serial/serializer.rs | 18 +- .../pumpkin/src/command/client_suggestions.rs | 130 +++--- crates/pumpkin/src/entity/attributes.rs | 12 +- crates/pumpkin/src/entity/breath.rs | 2 +- crates/pumpkin/src/entity/item.rs | 8 +- crates/pumpkin/src/entity/living.rs | 68 ++- crates/pumpkin/src/entity/mob/mod.rs | 2 +- crates/pumpkin/src/entity/mod.rs | 91 ++-- crates/pumpkin/src/entity/passive/animal.rs | 4 +- crates/pumpkin/src/entity/passive/cat.rs | 6 +- crates/pumpkin/src/entity/passive/ocelot.rs | 6 +- .../src/entity/passive/villager/mod.rs | 18 +- crates/pumpkin/src/entity/player.rs | 138 +++--- crates/pumpkin/src/entity/projectile/egg.rs | 4 +- .../src/entity/projectile/ender_pearl.rs | 4 +- .../src/entity/projectile/firework_rocket.rs | 4 +- .../src/entity/projectile/lingering_potion.rs | 4 +- .../pumpkin/src/entity/projectile/snowball.rs | 4 +- .../src/entity/vehicle/minecart/tnt.rs | 4 +- crates/pumpkin/src/net/bedrock/login/login.rs | 24 +- crates/pumpkin/src/net/bedrock/login/mod.rs | 4 +- .../bedrock/login/request_network_settings.rs | 19 +- .../bedrock/login/resource_pack_response.rs | 30 +- crates/pumpkin/src/net/bedrock/mod.rs | 40 +- .../src/net/bedrock/play/actor_event.rs | 8 +- .../pumpkin/src/net/bedrock/play/animate.rs | 2 +- .../net/bedrock/play/block_pick_request.rs | 8 +- .../src/net/bedrock/play/container_close.rs | 2 +- crates/pumpkin/src/net/bedrock/play/emote.rs | 2 +- .../src/net/bedrock/play/interaction.rs | 55 +-- .../src/net/bedrock/play/inventory_action.rs | 18 +- .../net/bedrock/play/item_stack_request.rs | 26 +- .../src/net/bedrock/play/mob_equipment.rs | 4 +- crates/pumpkin/src/net/bedrock/play/mod.rs | 21 +- .../net/bedrock/play/modal_form_response.rs | 2 +- .../src/net/bedrock/play/player_action.rs | 18 +- .../net/bedrock/play/player_block_action.rs | 6 +- .../net/bedrock/play/request_chunk_radius.rs | 2 +- .../pumpkin/src/net/bedrock/play/respawn.rs | 12 +- .../play/set_local_player_as_initialized.rs | 2 +- .../wasm_host/wit/v0_1/generated_packets.rs | 291 ++++++------ .../loader/wasm/wasm_host/wit/v0_1/player.rs | 50 ++- crates/pumpkin/src/server/mod.rs | 8 +- crates/pumpkin/src/world/mod.rs | 418 +++++++++--------- crates/pumpkin/src/world/portal/mod.rs | 12 +- crates/pumpkin/src/world/scoreboard.rs | 47 +- 127 files changed, 1856 insertions(+), 1959 deletions(-) rename crates/pumpkin-protocol/src/bedrock/client/{chunk_radius_update.rs => chunk_radius_updated.rs} (56%) rename crates/pumpkin-protocol/src/bedrock/client/{correct_player_move.rs => correct_player_move_prediction.rs} (75%) rename crates/pumpkin-protocol/src/bedrock/client/{disconnect_player.rs => disconnect.rs} (81%) create mode 100644 crates/pumpkin-protocol/src/bedrock/client/remove_objective.rs delete mode 100644 crates/pumpkin-protocol/src/bedrock/client/respawn.rs create mode 100644 crates/pumpkin-protocol/src/bedrock/client/set_display_objective.rs rename crates/pumpkin-protocol/src/bedrock/client/{scoreboard.rs => set_score.rs} (83%) create mode 100644 crates/pumpkin-protocol/src/bedrock/enum_as_str.rs delete mode 100644 crates/pumpkin-protocol/src/bedrock/respawn.rs create mode 100644 crates/pumpkin-protocol/src/bedrock/server/interact.rs delete mode 100644 crates/pumpkin-protocol/src/bedrock/server/interaction.rs rename crates/pumpkin-protocol/src/bedrock/server/{resource_pack_response.rs => resource_pack_client_response.rs} (92%) diff --git a/crates/pumpkin-plugin-wit b/crates/pumpkin-plugin-wit index 060c913c3..10f15637d 160000 --- a/crates/pumpkin-plugin-wit +++ b/crates/pumpkin-plugin-wit @@ -1 +1 @@ -Subproject commit 060c913c3097ae730fb2c04b7835733dcc85a1a4 +Subproject commit 10f15637dcfd79371c3e40796f7e2575b26876cd diff --git a/crates/pumpkin-protocol/src/bedrock/client/add_actor.rs b/crates/pumpkin-protocol/src/bedrock/client/add_actor.rs index dffd74bca..16f30481e 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/add_actor.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/add_actor.rs @@ -1,73 +1,38 @@ +// Last verified for v2169 + use crate::{ codec::{var_long::VarLong, var_ulong::VarULong}, serial::PacketWrite, }; use pumpkin_macros::packet; -use pumpkin_util::math::vector3::Vector3; +use pumpkin_util::math::{vector2::Vector2, vector3::Vector3}; use super::{ - common::EntityLink, - set_actor_data::{EntityMetadata, PropertySyncData}, + common::ActorLink, + set_actor_data::{PropertySyncData, SyncedActorDataList}, }; #[derive(PacketWrite)] #[packet(13)] pub struct CAddActor { - pub entity_unique_id: VarLong, - pub entity_runtime_id: VarULong, - pub entity_type: String, + pub target_actor_id: VarLong, + pub target_runtime_id: VarULong, + pub actor_type: String, pub position: Vector3, pub velocity: Vector3, - pub pitch: f32, - pub yaw: f32, - pub head_yaw: f32, - pub body_yaw: f32, - pub attributes: Vec, - pub metadata: EntityMetadata, + pub rotation: Vector2, + pub y_head_rotation: f32, + pub y_body_rotation: f32, + pub attributes_list: Vec, + pub actor_data: SyncedActorDataList, pub synced_properties: PropertySyncData, - pub links: Vec, -} - -impl CAddActor { - #[allow(clippy::too_many_arguments)] - #[must_use] - pub const fn new( - entity_unique_id: VarLong, - entity_runtime_id: VarULong, - entity_type: String, - position: Vector3, - velocity: Vector3, - pitch: f32, - yaw: f32, - head_yaw: f32, - body_yaw: f32, - attributes: Vec, - metadata: EntityMetadata, - synced_properties: PropertySyncData, - links: Vec, - ) -> Self { - Self { - entity_unique_id, - entity_runtime_id, - entity_type, - position, - velocity, - pitch, - yaw, - head_yaw, - body_yaw, - attributes, - metadata, - synced_properties, - links, - } - } + pub actor_links: Vec, } #[derive(PacketWrite)] -pub struct AttributeValue { - pub name: String, - pub min: f32, - pub value: f32, - pub max: f32, +pub struct SyncedAttribute { + pub attribute_name: String, + pub min_value: f32, + pub current_value: f32, + pub max_value: f32, } diff --git a/crates/pumpkin-protocol/src/bedrock/client/add_item_actor.rs b/crates/pumpkin-protocol/src/bedrock/client/add_item_actor.rs index fd4f1a8b5..01d286b0c 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/add_item_actor.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/add_item_actor.rs @@ -1,21 +1,23 @@ +// TODO: update inventory + use crate::{ + bedrock::network_item::ItemStackWrapper, codec::{var_long::VarLong, var_ulong::VarULong}, serial::PacketWrite, }; use pumpkin_macros::packet; use pumpkin_util::math::vector3::Vector3; -use super::set_actor_data::EntityMetadata; -use crate::bedrock::network_item::ItemStackWrapper; +use super::set_actor_data::SyncedActorDataList; #[derive(PacketWrite)] #[packet(15)] pub struct CAddItemActor { - pub entity_unique_id: VarLong, - pub entity_runtime_id: VarULong, + pub target_actor_id: VarLong, + pub target_runtime_id: VarULong, pub item: ItemStackWrapper, pub position: Vector3, pub velocity: Vector3, - pub metadata: EntityMetadata, - pub from_fishing: bool, + pub entity_data: SyncedActorDataList, + pub is_from_fishing: bool, } diff --git a/crates/pumpkin-protocol/src/bedrock/client/add_player.rs b/crates/pumpkin-protocol/src/bedrock/client/add_player.rs index 825646674..267ef379c 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/add_player.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/add_player.rs @@ -1,110 +1,38 @@ use crate::{ - bedrock::network_item::NetworkItemDescriptor, - codec::{var_int::VarInt, var_uint::VarUInt, var_ulong::VarULong}, + bedrock::{client::GameType, network_item::NetworkItemStackDescriptor}, + codec::var_ulong::VarULong, serial::PacketWrite, }; use pumpkin_macros::packet; -use pumpkin_util::math::vector3::Vector3; -use std::io::{Error, Write}; +use pumpkin_util::math::{vector2::Vector2, vector3::Vector3}; use uuid::Uuid; use super::{ - common::{AbilityLayer, BuildPlatform, EntityLink}, - set_actor_data::EntityMetadata, + common::{ActorLink, BuildPlatform, SerializedAbilitiesData}, + set_actor_data::PropertySyncData, + set_actor_data::SyncedActorDataList, }; #[derive(PacketWrite)] #[packet(12)] pub struct CAddPlayer { pub uuid: Uuid, - pub username: String, - pub entity_runtime_id: VarULong, + pub player_name: String, + pub target_runtime_id: VarULong, pub platform_chat_id: String, pub position: Vector3, pub velocity: Vector3, - pub pitch: f32, - pub yaw: f32, - pub head_yaw: f32, - pub held_item: NetworkItemDescriptor, - pub game_mode: VarInt, - pub metadata: EntityMetadata, - pub properties: EntityProperties, - pub ability_data: AbilityData, - pub links: Vec, + pub rotation: Vector2, + pub y_head_rotation: f32, + + // TODO: update inventory + pub carried_item: NetworkItemStackDescriptor, + + pub player_game_type: GameType, + pub entity_data: SyncedActorDataList, + pub synced_properties: PropertySyncData, + pub abilities_data: SerializedAbilitiesData, + pub actor_links: Vec, pub device_id: String, pub build_platform: BuildPlatform, } - -impl CAddPlayer { - #[allow(clippy::too_many_arguments)] - #[must_use] - pub const fn new( - uuid: Uuid, - username: String, - entity_runtime_id: VarULong, - platform_chat_id: String, - position: Vector3, - velocity: Vector3, - pitch: f32, - yaw: f32, - head_yaw: f32, - held_item: NetworkItemDescriptor, - game_mode: VarInt, - metadata: EntityMetadata, - properties: EntityProperties, - ability_data: AbilityData, - links: Vec, - device_id: String, - build_platform: BuildPlatform, - ) -> Self { - Self { - uuid, - username, - entity_runtime_id, - platform_chat_id, - position, - velocity, - pitch, - yaw, - head_yaw, - held_item, - game_mode, - metadata, - properties, - ability_data, - links, - device_id, - build_platform, - } - } -} - -#[derive(Default, Clone)] -pub struct EntityProperties { - pub ints: Vec<(VarUInt, VarInt)>, - pub floats: Vec<(VarUInt, f32)>, -} - -impl PacketWrite for EntityProperties { - fn write(&self, writer: &mut W) -> Result<(), Error> { - VarUInt(self.ints.len() as u32).write(writer)?; - for (id, val) in &self.ints { - id.write(writer)?; - val.write(writer)?; - } - VarUInt(self.floats.len() as u32).write(writer)?; - for (id, val) in &self.floats { - id.write(writer)?; - val.write(writer)?; - } - Ok(()) - } -} - -#[derive(Default, Clone, PacketWrite)] -pub struct AbilityData { - pub entity_unique_id: i64, - pub player_permissions: u8, - pub command_permissions: u8, - pub layers: Vec, -} diff --git a/crates/pumpkin-protocol/src/bedrock/client/available_commands.rs b/crates/pumpkin-protocol/src/bedrock/client/available_commands.rs index 75b982462..0101579e0 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/available_commands.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/available_commands.rs @@ -1,4 +1,10 @@ -use crate::{codec::var_uint::VarUInt, serial::PacketWrite}; +// Last verified for v2169 + +use crate::{ + bedrock::{client::CommandPermissionLevel, enum_as_str::EnumAsStr}, + codec::var_uint::VarUInt, + serial::PacketWrite, +}; use pumpkin_macros::packet; #[derive(PacketWrite)] @@ -6,66 +12,60 @@ use pumpkin_macros::packet; pub struct CAvailableCommands { pub enum_values: Vec, pub chained_subcommand_values: Vec, - pub suffixes: Vec, - pub enums: Vec, - pub chained_subcommands: Vec, - pub commands: Vec, - pub soft_enums: Vec, - pub constraints: Vec, + pub post_fixes: Vec, + pub enum_data: Vec, + pub chained_subcommand_data: Vec, + pub commands: Vec, + pub soft_enums: Vec, + pub constraints: Vec, +} + +#[derive(PacketWrite)] +pub struct EnumData { + pub name: String, + pub values: Vec, } // Represents a subcommand that can chain commands, e.g. /execute. // Written as a flat list in section 3 of the packet; Commands reference // entries by index via ChainedSubcommandOffsets. #[derive(PacketWrite)] -pub struct ChainedSubcommand { +pub struct ChainedSubcommandData { pub name: String, - pub values: Vec, + pub subcommand_values: Vec, } #[derive(PacketWrite)] -pub struct ChainedSubcommandValue { - /// Index into the `ChainedSubcommandValues` flat list — `VarUInt` +pub struct ChainedSubcommandRelationship { + /// Index into the `ChainedSubcommandValues` flat list pub index: VarUInt, - /// Argument type flags (basic types only, no `ARG_FLAG`_* modifiers) — `VarUInt` + /// Argument type flags (basic types only, no `ARG_FLAG`_* modifiers) pub value: VarUInt, } - #[derive(PacketWrite)] -pub struct CommandEnum { - pub name: String, - pub value_indices: Vec, -} - -#[derive(PacketWrite)] -pub struct Command { +pub struct CommandData { pub name: String, pub description: String, - /// LE u16 — putLShort pub flags: u16, - /// Permission string (e.g. "any", "admin") - pub permission: String, - /// LE i32 — putLInt; -1 means no aliases - pub aliases_enum_index: i32, - /// LE u32 each — indices into the `chained_subcommands` flat list - pub chained_subcommand_offsets: Vec, - pub overloads: Vec, + pub permission_level: EnumAsStr, + /// -1 means no aliases + pub alias_enum: i32, + pub command_data_chained_subcommand_indexes: Vec, + pub overloads: Vec, } #[derive(PacketWrite)] -pub struct CommandOverload { - /// Written as a single byte before parameter count ← MISSING in original - /// true = this overload uses chained subcommands instead of regular params - pub chaining: bool, - pub parameters: Vec, +pub struct OverloadData { + pub is_chaining: bool, + pub parameter_data: Vec, } #[derive(Clone, PacketWrite)] -pub struct CommandParameter { +pub struct ParamData { pub name: String, - /// LE u32 — encodes type flags (`ARG_FLAG_VALID` | `ARG_FLAG_ENUM` | index, or raw type) - pub type_info: u32, - pub optional: bool, + /// encodes type flags (`ARG_FLAG_VALID` | `ARG_FLAG_ENUM` | index, or raw type) + pub parse_symbol: u32, + pub is_optional: bool, /// Options byte (`ARG_FLAG`_* options) — putByte pub options: u8, } @@ -99,24 +99,15 @@ pub mod arg_types { pub const ARG_TYPE_COMMAND: u32 = 0x46; } -pub mod command_permissions { - pub const ANY: &str = "any"; - pub const GAME_DIRECTORS: &str = "gamedirectors"; - pub const ADMIN: &str = "admin"; - pub const HOST: &str = "host"; - pub const OWNER: &str = "owner"; - pub const INTERNAL: &str = "internal"; +#[derive(Clone, PacketWrite)] +pub struct SoftEnumData { + pub enum_name: String, + pub enum_options: Vec, } #[derive(Clone, PacketWrite)] -pub struct SoftEnum { - pub name: String, - pub values: Vec, -} - -#[derive(Clone, PacketWrite)] -pub struct CommandEnumConstraint { - pub affected_value_index: i32, - pub enum_index: i32, - pub constraints: Vec, +pub struct ConstrainedValueData { + pub enum_value_symbol: u32, + pub enum_symbol: u32, + pub constraint_indices: Vec, } diff --git a/crates/pumpkin-protocol/src/bedrock/client/block_actor_data.rs b/crates/pumpkin-protocol/src/bedrock/client/block_actor_data.rs index 58b0eea5e..388014a2c 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/block_actor_data.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/block_actor_data.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use pumpkin_nbt::compound::NbtCompound; use pumpkin_util::math::position::BlockPos; @@ -8,14 +10,17 @@ use crate::serial::PacketWrite; #[derive(PacketWrite)] #[packet(56)] pub struct CBlockActorData { - pub position: BlockPos, - pub data: NbtCompound, + pub block_position: BlockPos, + pub actor_data_tags: NbtCompound, } impl CBlockActorData { #[must_use] - pub const fn new(position: BlockPos, data: NbtCompound) -> Self { - Self { position, data } + pub const fn new(block_position: BlockPos, actor_data_tags: NbtCompound) -> Self { + Self { + block_position, + actor_data_tags, + } } } @@ -37,9 +42,12 @@ mod tests { data.put_byte("color", 11); let mut encoded = Vec::new(); - CBlockActorData::new(BlockPos::new(1, 64, -2), data) - .write(&mut encoded) - .unwrap(); + CBlockActorData { + block_position: BlockPos::new(1, 64, -2), + actor_data_tags: data, + } + .write(&mut encoded) + .unwrap(); assert_eq!(&encoded[..4], &[2, 128, 1, 3]); let mut reader = NbtReadHelperBedrock::new(Cursor::new(&encoded[4..])); diff --git a/crates/pumpkin-protocol/src/bedrock/client/block_event.rs b/crates/pumpkin-protocol/src/bedrock/client/block_event.rs index e9be29743..42d80dbf8 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/block_event.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/block_event.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use pumpkin_util::math::position::BlockPos; @@ -7,20 +9,9 @@ use crate::{codec::var_int::VarInt, serial::PacketWrite}; #[derive(PacketWrite)] #[packet(26)] pub struct CBlockEvent { - pub position: BlockPos, + pub block_position: BlockPos, pub event_type: VarInt, - pub event_data: VarInt, -} - -impl CBlockEvent { - #[must_use] - pub const fn new(position: BlockPos, event_type: i32, event_data: i32) -> Self { - Self { - position, - event_type: VarInt(event_type), - event_data: VarInt(event_data), - } - } + pub event_value: VarInt, } #[cfg(test)] @@ -35,9 +26,13 @@ mod tests { assert_eq!(::PACKET_ID, 26); let mut encoded = Vec::new(); - CBlockEvent::new(BlockPos::new(1, 64, -2), 1, 3) - .write(&mut encoded) - .unwrap(); + CBlockEvent { + block_position: BlockPos::new(1, 64, -2), + event_type: 1.into(), + event_value: 3.into(), + } + .write(&mut encoded) + .unwrap(); assert_eq!(encoded, [2, 128, 1, 3, 2, 6]); } diff --git a/crates/pumpkin-protocol/src/bedrock/client/change_dimension.rs b/crates/pumpkin-protocol/src/bedrock/client/change_dimension.rs index bf3578c53..2e47ea845 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/change_dimension.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/change_dimension.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use pumpkin_util::math::vector3::Vector3; @@ -6,20 +8,8 @@ use crate::{codec::var_int::VarInt, serial::PacketWrite}; #[derive(PacketWrite)] #[packet(61)] pub struct CChangeDimension { - pub dimension: VarInt, + pub dimension_id: VarInt, pub position: Vector3, pub respawn: bool, pub loading_screen_id: Option, } - -impl CChangeDimension { - #[must_use] - pub const fn new(dimension: i32, position: Vector3, respawn: bool) -> Self { - Self { - dimension: VarInt(dimension), - position, - respawn, - loading_screen_id: None, - } - } -} diff --git a/crates/pumpkin-protocol/src/bedrock/client/chunk_radius_update.rs b/crates/pumpkin-protocol/src/bedrock/client/chunk_radius_updated.rs similarity index 56% rename from crates/pumpkin-protocol/src/bedrock/client/chunk_radius_update.rs rename to crates/pumpkin-protocol/src/bedrock/client/chunk_radius_updated.rs index 5c8e9ce26..ed326e3c0 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/chunk_radius_update.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/chunk_radius_updated.rs @@ -1,10 +1,11 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use crate::{codec::var_int::VarInt, serial::PacketWrite}; #[derive(PacketWrite)] #[packet(70)] -pub struct CChunkRadiusUpdate { - // https://mojang.github.io/bedrock-protocol-docs/html/ChunkRadiusUpdatedPacket.html +pub struct CChunkRadiusUpdated { pub chunk_radius: VarInt, } diff --git a/crates/pumpkin-protocol/src/bedrock/client/client_cache_miss_response.rs b/crates/pumpkin-protocol/src/bedrock/client/client_cache_miss_response.rs index c0a5aa7db..449549018 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/client_cache_miss_response.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/client_cache_miss_response.rs @@ -1,28 +1,17 @@ -use std::io::{Error, Write}; +// Last verified for v2169 use pumpkin_macros::packet; -use crate::{codec::var_uint::VarUInt, serial::PacketWrite}; +use crate::serial::PacketWrite; -#[derive(Clone, Debug)] -pub struct CacheBlob { - pub hash: u64, - pub payload: Vec, +#[derive(PacketWrite, Clone, Debug)] +pub struct MissingBlobData { + pub blob_id: u64, + pub blob_data: Vec, } +#[derive(PacketWrite)] #[packet(136)] -pub struct CClientCacheMissResponse<'a> { - pub blobs: &'a [CacheBlob], -} - -impl PacketWrite for CClientCacheMissResponse<'_> { - fn write(&self, writer: &mut W) -> Result<(), Error> { - VarUInt(self.blobs.len() as u32).write(writer)?; - for blob in self.blobs { - writer.write_all(&blob.hash.to_le_bytes())?; - VarUInt(blob.payload.len() as u32).write(writer)?; - writer.write_all(&blob.payload)?; - } - Ok(()) - } +pub struct CClientCacheMissResponse { + pub missing_blobs: Vec, } diff --git a/crates/pumpkin-protocol/src/bedrock/client/common.rs b/crates/pumpkin-protocol/src/bedrock/client/common.rs index 74f9f1b37..ab69906a1 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/common.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/common.rs @@ -1,6 +1,11 @@ use std::io::{Error, Write}; -use crate::{codec::var_long::VarLong, serial::PacketWrite}; +use pumpkin_util::GameMode; + +use crate::{ + codec::{var_int::VarInt, var_long::VarLong}, + serial::PacketWrite, +}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[repr(i32)] @@ -11,7 +16,6 @@ pub enum BuildPlatform { Osx = 3, Amazon = 4, GearVr = 5, - Hololens = 6, Uwp = 7, Win32 = 8, Dedicated = 9, @@ -29,8 +33,92 @@ impl PacketWrite for BuildPlatform { } } +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(i32)] +pub enum GameType { + Unknown = -1, + Survival = 0, + Creative = 1, + Adventure = 2, + Default = 5, + Spectator = 6, + //WorldDefault = 0, +} + +impl PacketWrite for GameType { + fn write(&self, writer: &mut W) -> Result<(), Error> { + VarInt(*self as i32).write(writer) + } +} + +impl From for GameType { + fn from(value: GameMode) -> Self { + match value { + GameMode::Survival => Self::Survival, + GameMode::Creative => Self::Creative, + GameMode::Adventure => Self::Adventure, + GameMode::Spectator => Self::Spectator, + } + } +} + +#[derive(Clone, PacketWrite)] +pub struct SerializedAbilitiesData { + pub target_player_raw_id: i64, + pub player_permissions: PlayerPermissionLevel, + pub command_permissions: CommandPermissionLevel, + pub layers: Vec, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(i8)] +pub enum PlayerPermissionLevel { + Visitor = 0, + Member = 1, + Operator = 2, + Custom = 3, +} + +impl PacketWrite for PlayerPermissionLevel { + fn write(&self, writer: &mut W) -> Result<(), Error> { + (*self as i8).write(writer) + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] +pub enum CommandPermissionLevel { + Any = 0, + GameDirectors = 1, + Admin = 2, + Host = 3, + Owner = 4, + Internal = 5, +} + +#[allow(clippy::to_string_trait_impl)] +impl ToString for CommandPermissionLevel { + fn to_string(&self) -> String { + match self { + Self::Any => "any", + Self::GameDirectors => "gamedirectors", + Self::Admin => "admin", + Self::Host => "host", + Self::Owner => "owner", + Self::Internal => "internal", + } + .into() + } +} + +impl PacketWrite for CommandPermissionLevel { + fn write(&self, writer: &mut W) -> Result<(), Error> { + (*self as u8).write(writer) + } +} + #[derive(Default, Clone, PacketWrite)] -pub struct AbilityLayer { +pub struct SerializedAbilitiesDataSerializedLayer { pub serialized_layer: u16, pub abilities_set: u32, pub ability_value: u32, @@ -40,7 +128,7 @@ pub struct AbilityLayer { } #[derive(Default, Clone, PacketWrite)] -pub struct EntityLink { +pub struct ActorLink { pub ridden_unique_id: VarLong, pub rider_unique_id: VarLong, pub link_type: u8, diff --git a/crates/pumpkin-protocol/src/bedrock/client/container_open.rs b/crates/pumpkin-protocol/src/bedrock/client/container_open.rs index 593025dda..8133363f5 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/container_open.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/container_open.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use pumpkin_util::math::position::BlockPos; @@ -6,7 +8,6 @@ use crate::{codec::var_long::VarLong, serial::PacketWrite}; #[derive(PacketWrite)] #[packet(46)] pub struct CContainerOpen { - // https://mojang.github.io/bedrock-protocol-docs/html/ContainerOpenPacket.html pub container_id: u8, pub container_type: u8, pub position: BlockPos, diff --git a/crates/pumpkin-protocol/src/bedrock/client/correct_player_move.rs b/crates/pumpkin-protocol/src/bedrock/client/correct_player_move_prediction.rs similarity index 75% rename from crates/pumpkin-protocol/src/bedrock/client/correct_player_move.rs rename to crates/pumpkin-protocol/src/bedrock/client/correct_player_move_prediction.rs index 0302964e0..4862fe619 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/correct_player_move.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/correct_player_move_prediction.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use pumpkin_util::math::{vector2::Vector2, vector3::Vector3}; @@ -5,8 +7,7 @@ use crate::{codec::var_ulong::VarULong, serial::PacketWrite}; #[derive(PacketWrite)] #[packet(161)] -pub struct CCorrectPlayerMove { - // https://mojang.github.io/bedrock-protocol-docs/html/CorrectPlayerMovePredictionPacket.html +pub struct CCorrectPlayerMovePrediction { pub prediction_type: u8, pub pos: Vector3, pub pos_delta: Vector3, diff --git a/crates/pumpkin-protocol/src/bedrock/client/creative_content.rs b/crates/pumpkin-protocol/src/bedrock/client/creative_content.rs index a60c76810..f55ad6908 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/creative_content.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/creative_content.rs @@ -8,9 +8,8 @@ use crate::{ #[packet(145)] pub struct CCreativeContent<'a> { - // https://mojang.github.io/bedrock-protocol-docs/html/CreativeContentPacket.html - pub groups: &'a [Group], - pub entries: &'a [Entry], + pub groups: &'a [CreativeGroupInfoPayload], + pub entries: &'a [CreativeItemEntryPayload], } impl PacketWrite for CCreativeContent<'_> { @@ -28,44 +27,57 @@ impl PacketWrite for CCreativeContent<'_> { } } -#[derive(Copy, Clone)] -#[repr(i32)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] pub enum CreativeCategory { - Construction = 1, - Nature = 2, - Equipment = 3, - Items = 4, - CommandOnly = 5, - Undefined = 6, + All, + Construction, + Nature, + Equipment, + Items, + ItemCommandOnly, + Undefined, } impl PacketWrite for CreativeCategory { fn write(&self, writer: &mut W) -> Result<(), Error> { - (*self as u8).write(writer) + match self { + Self::Construction + | Self::Nature + | Self::Equipment + | Self::Items + | Self::ItemCommandOnly => (*self as u8).write(writer), + _ => Err(Error::other("Invalid CreativeCategory to send")), + } } } -pub struct Group { +pub struct CreativeGroupInfoPayload { pub creative_category: CreativeCategory, pub name: String, - pub icon_item: NetworkItemDescriptor, + + // TODO: update inventory + pub group_icon_item: NetworkItemDescriptor, } -impl PacketWrite for Group { +impl PacketWrite for CreativeGroupInfoPayload { fn write(&self, writer: &mut W) -> Result<(), Error> { self.creative_category.write(writer)?; self.name.write(writer)?; - self.icon_item.write_item_instance(writer) + self.group_icon_item.write_item_instance(writer) } } -pub struct Entry { +pub struct CreativeItemEntryPayload { pub id: VarUInt, + + // TODO: update inventory pub item: NetworkItemDescriptor, + pub group_index: VarUInt, } -impl PacketWrite for Entry { +impl PacketWrite for CreativeItemEntryPayload { fn write(&self, writer: &mut W) -> Result<(), Error> { self.id.write(writer)?; self.item.write_item_instance(writer)?; diff --git a/crates/pumpkin-protocol/src/bedrock/client/disconnect_player.rs b/crates/pumpkin-protocol/src/bedrock/client/disconnect.rs similarity index 81% rename from crates/pumpkin-protocol/src/bedrock/client/disconnect_player.rs rename to crates/pumpkin-protocol/src/bedrock/client/disconnect.rs index bb26bd04e..b6b957afa 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/disconnect_player.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/disconnect.rs @@ -1,18 +1,19 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use std::io::{Error, Write}; use crate::{codec::var_int::VarInt, serial::PacketWrite}; #[packet(5)] -pub struct CDisconnectPlayer { - // https://mojang.github.io/bedrock-protocol-docs/html/DisconnectPacket.html +pub struct CDisconnect { pub reason: VarInt, pub skip_message: bool, pub message: String, pub filtered_message: String, } -impl CDisconnectPlayer { +impl CDisconnect { #[must_use] pub const fn new(reason: i32, message: String) -> Self { Self { @@ -24,7 +25,7 @@ impl CDisconnectPlayer { } } -impl PacketWrite for CDisconnectPlayer { +impl PacketWrite for CDisconnect { fn write(&self, writer: &mut W) -> Result<(), Error> { self.reason.write(writer)?; self.skip_message.write(writer)?; diff --git a/crates/pumpkin-protocol/src/bedrock/client/gamerules_changed.rs b/crates/pumpkin-protocol/src/bedrock/client/gamerules_changed.rs index b18eae350..a32423a8d 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/gamerules_changed.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/gamerules_changed.rs @@ -2,14 +2,26 @@ use pumpkin_macros::packet; use crate::{codec::var_uint::VarUInt, serial::PacketWrite}; -#[derive(PacketWrite, Default)] -#[packet(0x48)] +#[derive(PacketWrite)] +#[packet(72)] pub struct CGamerulesChanged { - pub rule_data: GameRules, + pub rule_data: Vec, } -#[derive(PacketWrite, Default)] -pub struct GameRules { - // TODO https://mojang.github.io/bedrock-protocol-docs/html/GameRulesChangedPacketData.html - pub list_size: VarUInt, +#[derive(PacketWrite)] +pub struct GameRule { + pub rule_name: String, + pub rule_can_be_modified: bool, + pub rule_value: RuleValue, +} + +// TODO: flesh out RuleValue +pub enum RuleValue { + Null, +} + +impl PacketWrite for RuleValue { + fn write(&self, writer: &mut W) -> Result<(), std::io::Error> { + VarUInt(0).write(writer) + } } diff --git a/crates/pumpkin-protocol/src/bedrock/client/inventory_content.rs b/crates/pumpkin-protocol/src/bedrock/client/inventory_content.rs index 2caf2a028..e38b40b8d 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/inventory_content.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/inventory_content.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use crate::{ @@ -9,7 +11,6 @@ use crate::{ #[derive(PacketWrite)] #[packet(49)] pub struct CInventoryContent { - // https://mojang.github.io/bedrock-protocol-docs/docs/InventoryContentPacket.html pub container_id: VarUInt, pub slots: Vec, pub full_container_name: FullContainerName, diff --git a/crates/pumpkin-protocol/src/bedrock/client/inventory_slot.rs b/crates/pumpkin-protocol/src/bedrock/client/inventory_slot.rs index 78ee9fd15..4cb9745b7 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/inventory_slot.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/inventory_slot.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use crate::{ bedrock::network_item::{FullContainerName, NetworkItemStackDescriptor}, codec::var_uint::VarUInt, @@ -8,9 +10,9 @@ use pumpkin_macros::packet; #[derive(PacketWrite)] #[packet(50)] pub struct CInventorySlot { - pub window_id: VarUInt, - pub inventory_slot: VarUInt, - pub container_name: Option, - pub storage: Option, + pub container_id: VarUInt, + pub slot: VarUInt, + pub full_container_name: Option, + pub storage_item: Option, pub item: NetworkItemStackDescriptor, } diff --git a/crates/pumpkin-protocol/src/bedrock/client/item_registry.rs b/crates/pumpkin-protocol/src/bedrock/client/item_registry.rs index f0c75ee1b..3d2a7957c 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/item_registry.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/item_registry.rs @@ -6,14 +6,16 @@ use crate::{codec::var_int::VarInt, serial::PacketWrite}; #[packet(162)] pub struct CItemRegistry { // https://mojang.github.io/bedrock-protocol-docs/docs/ItemRegistryPacket.html - pub items: Vec, + pub items: Vec, } #[derive(PacketWrite)] -pub struct ItemDefinition { - pub name: String, - pub id: i16, - pub component_based: bool, +pub struct ItemData { + pub item_name: String, + pub item_id: i16, + pub is_component_based: bool, + + // TODO: ItemVersion enum pub item_version: VarInt, // Normally would be `Nbt`, but for simplicity elsewhere, this is preserialized (via `Nbt::write_bedrock`) diff --git a/crates/pumpkin-protocol/src/bedrock/client/item_stack_response.rs b/crates/pumpkin-protocol/src/bedrock/client/item_stack_response.rs index a919fd84f..6f97d4048 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/item_stack_response.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/item_stack_response.rs @@ -9,10 +9,10 @@ use pumpkin_macros::packet; #[derive(Debug, Clone)] pub struct ItemStackResponseSlotInfo { + pub requested_slot: u8, pub slot: u8, - pub hotbar_slot: u8, - pub count: u8, - pub item_stack_id: VarInt, + pub amount: u8, + pub item_stack_net_id: VarInt, pub custom_name: String, pub filtered_custom_name: String, pub durability_correction: VarInt, @@ -26,13 +26,13 @@ impl PacketWrite for ItemStackResponseSlotInfo { "durability correction must fit in an i16", )); } + self.requested_slot.write(writer)?; self.slot.write(writer)?; - self.hotbar_slot.write(writer)?; - self.count.write(writer)?; + self.amount.write(writer)?; true.write(writer)?; - (self.item_stack_id.0 > 0).write(writer)?; - if self.item_stack_id.0 > 0 { - self.item_stack_id.write(writer)?; + (self.item_stack_net_id.0 > 0).write(writer)?; + if self.item_stack_net_id.0 > 0 { + self.item_stack_net_id.write(writer)?; } self.custom_name.write(writer)?; self.filtered_custom_name.write(writer)?; @@ -42,26 +42,27 @@ impl PacketWrite for ItemStackResponseSlotInfo { #[derive(PacketWrite, Debug, Clone)] pub struct ItemStackResponseContainerInfo { - pub container_name: FullContainerName, + pub full_container_name: FullContainerName, pub slots: Vec, } #[derive(Debug, Clone)] -pub struct ItemStackResponse { +pub struct ItemStackResponseInfo { + // TODO: proper enum pub result: u8, // 0 = SUCCESS, 1 = ERROR - pub request_id: VarInt, - pub container_infos: Vec, + pub client_request_id: VarInt, + pub containers: Vec, } -impl PacketWrite for ItemStackResponse { +impl PacketWrite for ItemStackResponseInfo { fn write(&self, writer: &mut W) -> Result<(), Error> { self.result.write(writer)?; - self.request_id.write(writer)?; + self.client_request_id.write(writer)?; true.write(writer)?; - (!self.container_infos.is_empty()).write(writer)?; - if !self.container_infos.is_empty() { - VarUInt(self.container_infos.len() as u32).write(writer)?; - for info in &self.container_infos { + (!self.containers.is_empty()).write(writer)?; + if !self.containers.is_empty() { + VarUInt(self.containers.len() as u32).write(writer)?; + for info in &self.containers { info.write(writer)?; } } @@ -72,7 +73,7 @@ impl PacketWrite for ItemStackResponse { #[derive(Debug, Clone)] #[packet(148)] pub struct CItemStackResponse { - pub responses: Vec, + pub responses: Vec, } impl PacketWrite for CItemStackResponse { @@ -98,10 +99,10 @@ mod tests { #[test] fn rejects_out_of_range_durability_correction() { let slot = ItemStackResponseSlotInfo { + requested_slot: 0, slot: 0, - hotbar_slot: 0, - count: 1, - item_stack_id: VarInt(1), + amount: 1, + item_stack_net_id: VarInt(1), custom_name: String::new(), filtered_custom_name: String::new(), durability_correction: VarInt(32768), diff --git a/crates/pumpkin-protocol/src/bedrock/client/level_event.rs b/crates/pumpkin-protocol/src/bedrock/client/level_event.rs index 8009925b8..cd293338b 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/level_event.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/level_event.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use pumpkin_util::math::vector3::Vector3; diff --git a/crates/pumpkin-protocol/src/bedrock/client/level_sound_event.rs b/crates/pumpkin-protocol/src/bedrock/client/level_sound_event.rs index 1bb7a08c3..be9165771 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/level_sound_event.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/level_sound_event.rs @@ -1,20 +1,18 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use pumpkin_util::math::vector3::Vector3; use crate::{codec::var_int::VarInt, serial::PacketWrite}; -/// Sent by the server to spawn a visual particle effect at a specific 3D location in the world. -/// -/// Packet ID: `123` -/// Ref: #[derive(PacketWrite)] #[packet(123)] pub struct CLevelSoundEvent { - pub sound_id: String, + pub sound_event: String, pub position: Vector3, - pub extra_data: VarInt, - pub entity_type: String, - pub is_baby_mob: bool, + pub data: VarInt, + pub actor_identifier: String, + pub is_baby: bool, pub is_global: bool, pub actor_unique_id: i64, pub fire_at_position: Option>, @@ -29,11 +27,11 @@ mod tests { assert_eq!(::PACKET_ID, 123); let packet = CLevelSoundEvent { - sound_id: "test".into(), + sound_event: "test".into(), position: Vector3::new(1.0, 2.0, 3.0), - extra_data: VarInt(-1), - entity_type: "actor".into(), - is_baby_mob: true, + data: VarInt(-1), + actor_identifier: "actor".into(), + is_baby: true, is_global: false, actor_unique_id: 42, fire_at_position: Some(Vector3::new(4.0, 5.0, 6.0)), diff --git a/crates/pumpkin-protocol/src/bedrock/client/mob_effect.rs b/crates/pumpkin-protocol/src/bedrock/client/mob_effect.rs index 97e664c65..34341c59f 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/mob_effect.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/mob_effect.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use crate::{ @@ -8,12 +10,15 @@ use crate::{ #[derive(PacketWrite)] #[packet(28)] pub struct CMobEffect { - pub runtime_entity_id: VarULong, + pub target_runtime_id: VarULong, + + // TODO: Event enum pub event_id: u8, + pub effect_id: VarInt, - pub amplifier: VarInt, - pub particles: bool, - pub duration: VarInt, + pub effect_amplifier: VarInt, + pub show_particles: bool, + pub effect_duration_ticks: VarInt, pub tick: VarULong, pub ambient: bool, } @@ -22,28 +27,4 @@ impl CMobEffect { pub const EVENT_ADD: u8 = 1; pub const EVENT_MODIFY: u8 = 2; pub const EVENT_REMOVE: u8 = 3; - - #[expect(clippy::too_many_arguments)] - #[must_use] - pub const fn new( - runtime_entity_id: VarULong, - event_id: u8, - effect_id: VarInt, - amplifier: VarInt, - particles: bool, - duration: VarInt, - tick: VarULong, - ambient: bool, - ) -> Self { - Self { - runtime_entity_id, - event_id, - effect_id, - amplifier, - particles, - duration, - tick, - ambient, - } - } } diff --git a/crates/pumpkin-protocol/src/bedrock/client/mob_equipment.rs b/crates/pumpkin-protocol/src/bedrock/client/mob_equipment.rs index 28a3d1649..70f523856 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/mob_equipment.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/mob_equipment.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use crate::{ bedrock::network_item::NetworkItemStackDescriptor, codec::var_ulong::VarULong, serial::PacketWrite, @@ -7,39 +9,9 @@ use pumpkin_macros::packet; #[derive(PacketWrite, Debug)] #[packet(31)] pub struct CMobEquipment { - pub entity_runtime_id: VarULong, + pub target_runtime_id: VarULong, pub item: NetworkItemStackDescriptor, - pub inventory_slot: u8, - pub hotbar_slot: u8, - pub window_id: u8, -} - -impl CMobEquipment { - #[must_use] - pub const fn new( - entity_runtime_id: u64, - item: NetworkItemStackDescriptor, - inventory_slot: u8, - hotbar_slot: u8, - window_id: u8, - ) -> Self { - Self { - entity_runtime_id: VarULong(entity_runtime_id), - item, - inventory_slot, - hotbar_slot, - window_id, - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::packet::Packet; - - #[test] - fn mob_equipment_packet_id() { - assert_eq!(CMobEquipment::PACKET_ID, 31); - } + pub slot: u8, + pub selected_slot: u8, + pub container_id: u8, } diff --git a/crates/pumpkin-protocol/src/bedrock/client/mod.rs b/crates/pumpkin-protocol/src/bedrock/client/mod.rs index ea41906d8..ffb273299 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/mod.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/mod.rs @@ -7,14 +7,14 @@ pub mod block_actor_data; pub mod block_event; pub mod boss_event; pub mod change_dimension; -pub mod chunk_radius_update; +pub mod chunk_radius_updated; pub mod client_cache_miss_response; pub mod common; pub mod container_open; -pub mod correct_player_move; +pub mod correct_player_move_prediction; pub mod crafting_data; pub mod creative_content; -pub mod disconnect_player; +pub mod disconnect; pub mod gamerules_changed; pub mod inventory_content; pub mod inventory_slot; @@ -35,16 +35,17 @@ pub mod play_status; pub mod player_hotbar; pub mod player_list; pub mod remove_actor; +pub mod remove_objective; pub mod resource_pack_stack; pub mod resource_packs_info; -pub mod respawn; -pub mod scoreboard; pub mod set_actor_data; pub mod set_actor_link; pub mod set_actor_motion; pub mod set_difficulty; +pub mod set_display_objective; pub mod set_health; pub mod set_player_gamemode; +pub mod set_score; pub mod set_spawn_position; pub mod set_time; pub mod set_title; @@ -66,14 +67,14 @@ pub use block_actor_data::*; pub use block_event::*; pub use boss_event::*; pub use change_dimension::*; -pub use chunk_radius_update::*; +pub use chunk_radius_updated::*; pub use client_cache_miss_response::*; pub use common::*; pub use container_open::*; -pub use correct_player_move::*; +pub use correct_player_move_prediction::*; pub use crafting_data::*; pub use creative_content::*; -pub use disconnect_player::*; +pub use disconnect::*; pub use gamerules_changed::*; pub use inventory_content::*; pub use inventory_slot::*; @@ -94,16 +95,17 @@ pub use play_status::*; pub use player_hotbar::*; pub use player_list::*; pub use remove_actor::*; +pub use remove_objective::*; pub use resource_pack_stack::*; pub use resource_packs_info::*; -pub use respawn::*; -pub use scoreboard::*; pub use set_actor_data::*; pub use set_actor_link::*; pub use set_actor_motion::*; pub use set_difficulty::*; +pub use set_display_objective::*; pub use set_health::*; pub use set_player_gamemode::*; +pub use set_score::*; pub use set_spawn_position::*; pub use set_time::*; pub use set_title::*; diff --git a/crates/pumpkin-protocol/src/bedrock/client/modal_form_request.rs b/crates/pumpkin-protocol/src/bedrock/client/modal_form_request.rs index b43bf6cbf..f105997ae 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/modal_form_request.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/modal_form_request.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use crate::{codec::var_uint::VarUInt, serial::PacketWrite}; use pumpkin_macros::packet; @@ -5,5 +7,5 @@ use pumpkin_macros::packet; #[derive(PacketWrite)] pub struct CModalFormRequest { pub form_id: VarUInt, - pub form_data: String, + pub form_ui_json: String, } diff --git a/crates/pumpkin-protocol/src/bedrock/client/move_actor_absolute.rs b/crates/pumpkin-protocol/src/bedrock/client/move_actor_absolute.rs index f8753faff..c342de1ce 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/move_actor_absolute.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/move_actor_absolute.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use crate::{codec::var_ulong::VarULong, serial::PacketWrite}; use pumpkin_macros::packet; use pumpkin_util::math::vector3::Vector3; @@ -5,35 +7,16 @@ use pumpkin_util::math::vector3::Vector3; #[derive(PacketWrite)] #[packet(18)] pub struct CMoveActorAbsolute { - pub entity_runtime_id: VarULong, - pub flags: u8, + pub actor_runtime_id: VarULong, + pub header: u8, pub position: Vector3, - pub pitch: u8, - pub yaw: u8, - pub head_yaw: u8, + pub rotation_x: u8, + pub rotation_y: u8, + pub rotation_y_head: u8, } impl CMoveActorAbsolute { pub const FLAG_ON_GROUND: u8 = 0x01; pub const FLAG_TELEPORT: u8 = 0x02; pub const FLAG_FORCE_MOVE: u8 = 0x04; - - #[must_use] - pub const fn new( - entity_runtime_id: VarULong, - flags: u8, - position: Vector3, - pitch: u8, - yaw: u8, - head_yaw: u8, - ) -> Self { - Self { - entity_runtime_id, - flags, - position, - pitch, - yaw, - head_yaw, - } - } } diff --git a/crates/pumpkin-protocol/src/bedrock/client/network_settings.rs b/crates/pumpkin-protocol/src/bedrock/client/network_settings.rs index cadb68447..d0c56dfac 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/network_settings.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/network_settings.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use crate::serial::PacketWrite; @@ -6,28 +8,12 @@ use crate::serial::PacketWrite; #[packet(143)] pub struct CNetworkSettings { pub compression_threshold: u16, + + // TODO: CompressionAlgorithm enum /// `ZLib` = 0, Snappy = 1, None = 255 - pub compression_method: u16, + pub compression_algorithm: u16, + pub client_throttle_enabled: bool, pub client_throttle_threshold: u8, pub client_throttle_scalar: f32, } - -impl CNetworkSettings { - #[must_use] - pub const fn new( - compression_threshold: u16, - compression_method: u16, - client_throttle_enabled: bool, - client_throttle_threshold: u8, - client_throttle_scalar: f32, - ) -> Self { - Self { - compression_threshold, - compression_method, - client_throttle_enabled, - client_throttle_threshold, - client_throttle_scalar, - } - } -} diff --git a/crates/pumpkin-protocol/src/bedrock/client/play_status.rs b/crates/pumpkin-protocol/src/bedrock/client/play_status.rs index 0efcba192..559e89662 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/play_status.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/play_status.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use std::io::{Error, Write}; use pumpkin_macros::packet; @@ -5,6 +7,7 @@ use pumpkin_macros::packet; use crate::serial::PacketWrite; #[derive(Clone, Copy)] +#[repr(i32)] #[packet(2)] pub enum CPlayStatus { LoginSuccess = 0, diff --git a/crates/pumpkin-protocol/src/bedrock/client/player_hotbar.rs b/crates/pumpkin-protocol/src/bedrock/client/player_hotbar.rs index 490d4d1ea..51ddb1369 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/player_hotbar.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/player_hotbar.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use crate::{codec::var_uint::VarUInt, serial::PacketWrite}; @@ -7,5 +9,5 @@ use crate::{codec::var_uint::VarUInt, serial::PacketWrite}; pub struct CPlayerHotbar { pub selected_slot: VarUInt, pub container_id: u8, - pub should_select_block: bool, + pub should_select_slot: bool, } diff --git a/crates/pumpkin-protocol/src/bedrock/client/remove_actor.rs b/crates/pumpkin-protocol/src/bedrock/client/remove_actor.rs index ab7c44abc..2b881d8f3 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/remove_actor.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/remove_actor.rs @@ -1,15 +1,17 @@ +// Last verified for v2169 + use crate::{codec::var_long::VarLong, serial::PacketWrite}; use pumpkin_macros::packet; #[derive(PacketWrite)] #[packet(14)] pub struct CRemoveActor { - pub entity_unique_id: VarLong, + pub target_actor_id: VarLong, } impl CRemoveActor { #[must_use] - pub const fn new(entity_unique_id: VarLong) -> Self { - Self { entity_unique_id } + pub const fn new(target_actor_id: VarLong) -> Self { + Self { target_actor_id } } } diff --git a/crates/pumpkin-protocol/src/bedrock/client/remove_objective.rs b/crates/pumpkin-protocol/src/bedrock/client/remove_objective.rs new file mode 100644 index 000000000..4e93d4b5a --- /dev/null +++ b/crates/pumpkin-protocol/src/bedrock/client/remove_objective.rs @@ -0,0 +1,10 @@ +// Last verified for v2169 + +use crate::serial::PacketWrite; +use pumpkin_macros::packet; + +#[derive(PacketWrite)] +#[packet(106)] +pub struct CRemoveObjective { + pub objective_name: String, +} diff --git a/crates/pumpkin-protocol/src/bedrock/client/resource_pack_stack.rs b/crates/pumpkin-protocol/src/bedrock/client/resource_pack_stack.rs index ef29ca5c9..1c65fbd0e 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/resource_pack_stack.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/resource_pack_stack.rs @@ -1,9 +1,11 @@ +// Last verified for v2169 + use crate::{bedrock::client::start_game::Experiments, serial::PacketWrite}; use pumpkin_macros::packet; #[derive(PacketWrite)] -pub struct ResourcePackStackEntry { - pub uuid: String, +pub struct PackInstanceId { + pub pack_id: String, pub version: String, pub sub_pack_name: String, } @@ -11,28 +13,9 @@ pub struct ResourcePackStackEntry { #[derive(PacketWrite)] #[packet(7)] pub struct CResourcePackStackPacket { - pub resource_pack_required: bool, - pub resource_packs: Vec, - pub game_version: String, + pub texture_pack_required: bool, + pub texture_pack_list: Vec, + pub base_game_version: String, pub experiments: Experiments, pub include_editor_packs: bool, } - -impl CResourcePackStackPacket { - #[must_use] - pub const fn new( - resource_pack_required: bool, - resource_packs: Vec, - game_version: String, - experiments: Experiments, - include_editor_packs: bool, - ) -> Self { - Self { - resource_pack_required, - resource_packs, - game_version, - experiments, - include_editor_packs, - } - } -} diff --git a/crates/pumpkin-protocol/src/bedrock/client/resource_packs_info.rs b/crates/pumpkin-protocol/src/bedrock/client/resource_packs_info.rs index 4db6a6523..2183e274d 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/resource_packs_info.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/resource_packs_info.rs @@ -1,49 +1,44 @@ +// Last verified for v2169 + use crate::serial::PacketWrite; use pumpkin_macros::packet; -use std::io::{Error, Write}; #[derive(PacketWrite)] -pub struct ResourcePackEntry { - pub uuid: uuid::Uuid, - pub version: String, - pub size: u64, +pub struct PackInfoData { + pub pack_id_version: PackIdVersion, + pub pack_size: u64, pub content_key: String, - pub sub_pack_name: String, - pub content_id: String, + pub subpack_name: String, + pub content_identity: String, pub has_scripts: bool, - pub addon_pack: bool, - pub rtx_enabled: bool, - pub download_url: String, + pub is_addon_pack: bool, + pub is_ray_tracing_capable: bool, + pub cdn_url: String, } +#[derive(PacketWrite)] #[packet(6)] pub struct CResourcePacksInfo { pub resource_pack_required: bool, pub has_addon_packs: bool, pub has_scripts: bool, - pub is_vibrant_visuals_force_disabled: bool, - pub world_template_id: uuid::Uuid, - pub world_template_version: String, - pub resource_packs: Vec, + pub force_disable_vibrant_visuals: bool, + pub world_template_id_and_version: PackIdVersion, + pub resource_packs: Vec, } -impl PacketWrite for CResourcePacksInfo { - fn write(&self, writer: &mut W) -> Result<(), Error> { - self.resource_pack_required.write(writer)?; - self.has_addon_packs.write(writer)?; - self.has_scripts.write(writer)?; - self.is_vibrant_visuals_force_disabled.write(writer)?; +#[derive(PacketWrite)] +pub struct PackIdVersion { + pub pack_uuid: uuid::Uuid, + pub pack_version: String, +} - self.world_template_id.write(writer)?; - - self.world_template_version.write(writer)?; - - crate::codec::var_uint::VarUInt(self.resource_packs.len() as u32).write(writer)?; - - for entry in &self.resource_packs { - entry.write(writer)?; +impl PackIdVersion { + #[must_use] + pub const fn new(pack_uuid: uuid::Uuid, pack_version: String) -> Self { + Self { + pack_uuid, + pack_version, } - - Ok(()) } } diff --git a/crates/pumpkin-protocol/src/bedrock/client/respawn.rs b/crates/pumpkin-protocol/src/bedrock/client/respawn.rs deleted file mode 100644 index dbe85c8cc..000000000 --- a/crates/pumpkin-protocol/src/bedrock/client/respawn.rs +++ /dev/null @@ -1,49 +0,0 @@ -use pumpkin_macros::packet; -use pumpkin_util::math::vector3::Vector3; - -use crate::{bedrock::respawn::RespawnState, codec::var_ulong::VarULong, serial::PacketWrite}; - -#[derive(PacketWrite)] -#[packet(45)] -pub struct CRespawn { - pub position: Vector3, - pub state: RespawnState, - pub player_runtime_id: VarULong, -} - -impl CRespawn { - #[must_use] - pub const fn new( - position: Vector3, - state: RespawnState, - player_runtime_id: VarULong, - ) -> Self { - Self { - position, - state, - player_runtime_id, - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{bedrock::server::respawn::SRespawn, serial::PacketRead}; - - #[test] - fn respawn_packet_roundtrip() { - let packet = CRespawn::new( - Vector3::new(1.5, 64.0, -2.25), - RespawnState::ReadyToSpawn, - VarULong(42), - ); - let mut encoded = Vec::new(); - packet.write(&mut encoded).unwrap(); - - let decoded = SRespawn::read(&mut encoded.as_slice()).unwrap(); - assert_eq!(decoded.position, packet.position); - assert_eq!(decoded.state, packet.state); - assert_eq!(decoded.player_runtime_id.0, packet.player_runtime_id.0); - } -} diff --git a/crates/pumpkin-protocol/src/bedrock/client/set_actor_data.rs b/crates/pumpkin-protocol/src/bedrock/client/set_actor_data.rs index 736d8ac9d..3741b42b5 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/set_actor_data.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/set_actor_data.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use std::{collections::HashMap, io::Write}; use crate::{ @@ -9,34 +11,34 @@ use pumpkin_util::math::{position::BlockPos, vector3::Vector3}; use std::io::Error; #[derive(PacketWrite)] -#[packet(39)] // ProtocolInfo::SET_ACTOR_DATA_PACKET is 39 +#[packet(39)] pub struct CSetActorData { /// The unique runtime ID of the entity being updated - pub actor_runtime_id: VarULong, + pub target_runtime_id: VarULong, /// A map of entity metadata properties (e.g., flags, name tags, scale) - pub metadata: EntityMetadata, + pub actor_data: SyncedActorDataList, /// Dynamic properties synced between client and server pub synced_properties: PropertySyncData, /// The server tick at which this update occurred pub tick: VarULong, } -pub struct EntityMetadata(pub HashMap); +pub struct SyncedActorDataList(pub HashMap); -impl Default for EntityMetadata { +impl Default for SyncedActorDataList { fn default() -> Self { Self::new() } } -impl EntityMetadata { +impl SyncedActorDataList { #[must_use] pub fn new() -> Self { Self(HashMap::new()) } } -impl EntityMetadata { +impl SyncedActorDataList { pub fn set(&mut self, key: u32, value: MetadataValue) { self.0.insert(key, value); } @@ -55,7 +57,7 @@ impl EntityMetadata { self.0.insert(key, MetadataValue::Byte(new_value)); } else { let current_value = match self.0.get(&key) { - Some(MetadataValue::Long(v)) => *v, + Some(MetadataValue::Int64(v)) => *v, _ => 0, }; let new_value = if value { @@ -63,12 +65,12 @@ impl EntityMetadata { } else { current_value & !(1i64 << index) }; - self.0.insert(key, MetadataValue::Long(new_value)); + self.0.insert(key, MetadataValue::Int64(new_value)); } } } -impl PacketWrite for EntityMetadata { +impl PacketWrite for SyncedActorDataList { fn write(&self, writer: &mut W) -> Result<(), Error> { VarUInt(self.0.len() as u32).write(writer)?; @@ -90,8 +92,8 @@ pub enum MetadataValue { Float(f32), String(String), CompoundTag, - BlockPos(BlockPos), - Long(i64), + ItemPos(BlockPos), + Int64(i64), Vec3(Vector3), } @@ -105,8 +107,8 @@ impl MetadataValue { Self::Float(_) => 3, Self::String(_) => 4, Self::CompoundTag => 5, - Self::BlockPos(_) => 6, - Self::Long(_) => 7, + Self::ItemPos(_) => 6, + Self::Int64(_) => 7, Self::Vec3(_) => 8, } } @@ -116,39 +118,34 @@ impl MetadataValue { Self::Byte(v) => v.write(writer), Self::Short(v) => v.write(writer), Self::Int(v) => VarInt(*v).write(writer), - Self::Float(v) => writer.write_all(&v.to_le_bytes()), + Self::Float(v) => v.write(writer), Self::String(v) => v.write(writer), Self::CompoundTag => Err(Error::other("CompoundTag not implemented")), - Self::BlockPos(v) => v.write(writer), - Self::Long(v) => VarLong(*v).write(writer), - Self::Vec3(v) => { - writer.write_all(&v.x.to_le_bytes())?; - writer.write_all(&v.y.to_le_bytes())?; - writer.write_all(&v.z.to_le_bytes()) - } + Self::ItemPos(v) => v.write(writer), + Self::Int64(v) => VarLong(*v).write(writer), + Self::Vec3(v) => v.write(writer), } } } +#[derive(Default)] pub struct PropertySyncData { - pub int_properties: std::collections::HashMap, - pub float_properties: std::collections::HashMap, + pub int_entries_list: std::collections::HashMap, + pub float_entries_list: std::collections::HashMap, } impl PacketWrite for PropertySyncData { fn write(&self, writer: &mut W) -> Result<(), Error> { - // Int Properties - VarUInt(self.int_properties.len() as u32).write(writer)?; - for (key, value) in &self.int_properties { + VarUInt(self.int_entries_list.len() as u32).write(writer)?; + for (key, value) in &self.int_entries_list { VarUInt(*key).write(writer)?; - VarInt(*value).write(writer)?; // Signed VarInt + VarInt(*value).write(writer)?; } - // Float Properties - VarUInt(self.float_properties.len() as u32).write(writer)?; - for (key, value) in &self.float_properties { + VarUInt(self.float_entries_list.len() as u32).write(writer)?; + for (key, value) in &self.float_entries_list { VarUInt(*key).write(writer)?; - writer.write_all(&value.to_le_bytes())?; // LE Float + value.write(writer)?; } Ok(()) } @@ -431,11 +428,11 @@ pub mod entity_data_flag { #[cfg(test)] mod tests { - use super::{EntityMetadata, entity_data_key}; + use super::{SyncedActorDataList, entity_data_key}; #[test] fn partial_metadata_does_not_reset_flags() { - let metadata = EntityMetadata::new(); + let metadata = SyncedActorDataList::new(); assert!(!metadata.0.contains_key(&entity_data_key::FLAGS)); assert!(!metadata.0.contains_key(&entity_data_key::FLAGS_TWO)); diff --git a/crates/pumpkin-protocol/src/bedrock/client/set_actor_link.rs b/crates/pumpkin-protocol/src/bedrock/client/set_actor_link.rs index 49a79da64..48ccb8065 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/set_actor_link.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/set_actor_link.rs @@ -1,13 +1,11 @@ +// Last verified for v2169 + use pumpkin_macros::packet; -use crate::{bedrock::client::common::EntityLink, serial::PacketWrite}; +use crate::{bedrock::client::common::ActorLink, serial::PacketWrite}; -/// Sent by the server to set the entity an actor is riding or to unmount an actor. -/// -/// Packet ID: `41` -/// Ref: #[derive(PacketWrite)] #[packet(41)] pub struct CSetActorLink { - pub link: EntityLink, + pub link: ActorLink, } diff --git a/crates/pumpkin-protocol/src/bedrock/client/set_actor_motion.rs b/crates/pumpkin-protocol/src/bedrock/client/set_actor_motion.rs index 50d585589..89319f3eb 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/set_actor_motion.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/set_actor_motion.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use pumpkin_util::math::vector3::Vector3; @@ -10,14 +12,3 @@ pub struct CSetActorMotion { pub motion: Vector3, pub tick: VarULong, } - -impl CSetActorMotion { - #[must_use] - pub const fn new(target_runtime_id: VarULong, motion: Vector3, tick: VarULong) -> Self { - Self { - target_runtime_id, - motion, - tick, - } - } -} diff --git a/crates/pumpkin-protocol/src/bedrock/client/set_difficulty.rs b/crates/pumpkin-protocol/src/bedrock/client/set_difficulty.rs index 708ec95c8..862ccc1e6 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/set_difficulty.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/set_difficulty.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use crate::{codec::var_uint::VarUInt, serial::PacketWrite}; @@ -7,12 +9,3 @@ use crate::{codec::var_uint::VarUInt, serial::PacketWrite}; pub struct CSetDifficulty { pub difficulty: VarUInt, } - -impl CSetDifficulty { - #[must_use] - pub const fn new(difficulty: u32) -> Self { - Self { - difficulty: VarUInt(difficulty), - } - } -} diff --git a/crates/pumpkin-protocol/src/bedrock/client/set_display_objective.rs b/crates/pumpkin-protocol/src/bedrock/client/set_display_objective.rs new file mode 100644 index 000000000..07e6432fe --- /dev/null +++ b/crates/pumpkin-protocol/src/bedrock/client/set_display_objective.rs @@ -0,0 +1,14 @@ +// Last verified for v2169 + +use crate::{codec::var_int::VarInt, serial::PacketWrite}; +use pumpkin_macros::packet; + +#[derive(PacketWrite)] +#[packet(107)] +pub struct CSetDisplayObjective { + pub display_slot_name: String, + pub objective_name: String, + pub objective_display_name: String, + pub criteria_name: String, + pub sort_order: VarInt, +} diff --git a/crates/pumpkin-protocol/src/bedrock/client/set_health.rs b/crates/pumpkin-protocol/src/bedrock/client/set_health.rs index 7d0d3021a..46e6d5f8f 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/set_health.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/set_health.rs @@ -1,18 +1,10 @@ +// Last verified for v2169 + use crate::{codec::var_int::VarInt, serial::PacketWrite}; use pumpkin_macros::packet; #[derive(PacketWrite)] #[packet(42)] pub struct CSetHealth { - // https://mojang.github.io/bedrock-protocol-docs/html/SetHealthPacket.html pub health: VarInt, } - -impl CSetHealth { - #[must_use] - pub const fn new(health: i32) -> Self { - Self { - health: VarInt(health), - } - } -} diff --git a/crates/pumpkin-protocol/src/bedrock/client/set_player_gamemode.rs b/crates/pumpkin-protocol/src/bedrock/client/set_player_gamemode.rs index cfcf3b584..0a69aa431 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/set_player_gamemode.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/set_player_gamemode.rs @@ -1,9 +1,10 @@ -use crate::serial::PacketWrite; +// Last verified for v2169 + +use crate::{bedrock::client::GameType, serial::PacketWrite}; use pumpkin_macros::packet; -use pumpkin_util::GameMode; #[derive(PacketWrite)] #[packet(62)] -pub struct CSetPlayerGamemode { - pub gamemode: GameMode, +pub struct CSetPlayerGameType { + pub player_game_type: GameType, } diff --git a/crates/pumpkin-protocol/src/bedrock/client/scoreboard.rs b/crates/pumpkin-protocol/src/bedrock/client/set_score.rs similarity index 83% rename from crates/pumpkin-protocol/src/bedrock/client/scoreboard.rs rename to crates/pumpkin-protocol/src/bedrock/client/set_score.rs index 24ec10639..520e54699 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/scoreboard.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/set_score.rs @@ -6,16 +6,6 @@ use crate::{ }; use pumpkin_macros::packet; -#[derive(PacketWrite)] -#[packet(107)] -pub struct CSetDisplayObjective { - pub display_slot: String, - pub objective_name: String, - pub display_name: String, - pub criteria_name: String, - pub sort_order: VarInt, -} - #[packet(108)] pub struct CSetScore { pub action: VarInt, // 0 = change, 1 = remove @@ -92,17 +82,3 @@ impl ScoreEntry { Ok(()) } } - -#[derive(PacketWrite)] -#[packet(106)] -pub struct CRemoveObjective { - pub objective_name: String, -} - -impl CRemoveObjective { - pub fn new(objective_name: impl Into) -> Self { - Self { - objective_name: objective_name.into(), - } - } -} diff --git a/crates/pumpkin-protocol/src/bedrock/client/set_spawn_position.rs b/crates/pumpkin-protocol/src/bedrock/client/set_spawn_position.rs index a2eb2d168..c0d843e12 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/set_spawn_position.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/set_spawn_position.rs @@ -1,3 +1,7 @@ +// Last verified for v2169 + +use std::io::{Error, Write}; + use pumpkin_macros::packet; use pumpkin_util::math::position::BlockPos; @@ -6,25 +10,21 @@ use crate::{codec::var_int::VarInt, serial::PacketWrite}; #[derive(Clone, Copy, PacketWrite)] #[packet(43)] pub struct CSetSpawnPosition { - pub spawn_type: VarInt, - pub position: BlockPos, - pub dimension: VarInt, - pub spawn_position: BlockPos, + pub spawn_position_type: SpawnPositionType, + pub block_position: BlockPos, + pub dimension_type: VarInt, + pub spawn_block_pos: BlockPos, } -impl CSetSpawnPosition { - #[must_use] - pub const fn new( - spawn_type: i32, - position: BlockPos, - dimension: i32, - spawn_position: BlockPos, - ) -> Self { - Self { - spawn_type: VarInt(spawn_type), - position, - dimension: VarInt(dimension), - spawn_position, - } +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(i32)] +pub enum SpawnPositionType { + PlayerRespawn, + WorldRespawn, +} + +impl PacketWrite for SpawnPositionType { + fn write(&self, writer: &mut W) -> Result<(), Error> { + VarInt(*self as i32).write(writer) } } diff --git a/crates/pumpkin-protocol/src/bedrock/client/set_time.rs b/crates/pumpkin-protocol/src/bedrock/client/set_time.rs index a618872ab..635613a63 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/set_time.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/set_time.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use crate::{codec::var_int::VarInt, serial::PacketWrite}; diff --git a/crates/pumpkin-protocol/src/bedrock/client/set_title.rs b/crates/pumpkin-protocol/src/bedrock/client/set_title.rs index c2979023f..8e9677582 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/set_title.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/set_title.rs @@ -1,37 +1,61 @@ +// Last verified for v2169 + +use std::io::{Error, Write}; + use crate::{codec::var_int::VarInt, serial::PacketWrite}; use pumpkin_macros::packet; #[derive(PacketWrite)] #[packet(88)] pub struct CSetTitle { - pub action_type: VarInt, - pub text: String, - pub fade_in_duration: VarInt, - pub remain_duration: VarInt, - pub fade_out_duration: VarInt, + pub title_type: TitleType, + pub title_text: String, + pub fade_in_time: VarInt, + pub stay_time: VarInt, + pub fade_out_time: VarInt, pub xuid: String, pub platform_online_id: String, - pub filtered_message: String, + pub filtered_title_message: String, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(i32)] +pub enum TitleType { + Clear, + Reset, + Title, + Subtitle, + Actionbar, + Times, + TitleTextObject, + SubtitleTextObject, + ActionbarTextObject, +} + +impl PacketWrite for TitleType { + fn write(&self, writer: &mut W) -> Result<(), Error> { + VarInt(*self as i32).write(writer) + } } impl CSetTitle { #[must_use] pub const fn new( - action_type: i32, - text: String, - fade_in_duration: i32, - remain_duration: i32, - fade_out_duration: i32, + title_type: TitleType, + title_text: String, + fade_in_time: i32, + stay_time: i32, + fade_out_time: i32, ) -> Self { Self { - action_type: VarInt(action_type), - text, - fade_in_duration: VarInt(fade_in_duration), - remain_duration: VarInt(remain_duration), - fade_out_duration: VarInt(fade_out_duration), + title_type, + title_text, + fade_in_time: VarInt(fade_in_time), + stay_time: VarInt(stay_time), + fade_out_time: VarInt(fade_out_time), xuid: String::new(), platform_online_id: String::new(), - filtered_message: String::new(), + filtered_title_message: String::new(), } } } diff --git a/crates/pumpkin-protocol/src/bedrock/client/show_credits.rs b/crates/pumpkin-protocol/src/bedrock/client/show_credits.rs index 2a9b54fb4..30c208770 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/show_credits.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/show_credits.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use crate::{ codec::{var_int::VarInt, var_ulong::VarULong}, serial::PacketWrite, @@ -8,15 +10,5 @@ use pumpkin_macros::packet; #[packet(75)] pub struct CShowCredits { pub player_runtime_id: VarULong, - pub status: VarInt, -} - -impl CShowCredits { - #[must_use] - pub const fn new(player_runtime_id: VarULong, status: VarInt) -> Self { - Self { - player_runtime_id, - status, - } - } + pub credits_state: VarInt, } diff --git a/crates/pumpkin-protocol/src/bedrock/client/start_game.rs b/crates/pumpkin-protocol/src/bedrock/client/start_game.rs index 631da5d96..842755554 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/start_game.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/start_game.rs @@ -1,15 +1,12 @@ use std::io::{Error, Write}; use crate::{ - bedrock::client::gamerules_changed::GameRules, + bedrock::client::{GameType, gamerules_changed::GameRule}, codec::{var_int::VarInt, var_long::VarLong, var_uint::VarUInt, var_ulong::VarULong}, serial::PacketWrite, }; use pumpkin_macros::packet; -use pumpkin_util::{ - GameMode, - math::{position::BlockPos, vector3::Vector3}, -}; +use pumpkin_util::math::{position::BlockPos, vector3::Vector3}; use uuid::Uuid; #[derive(PacketWrite)] @@ -22,7 +19,7 @@ pub struct CStartGame { // The runtime ID is unique for each world session, and // entities are generally identified in packets using this runtime ID. pub runtime_entity_id: VarULong, - pub player_gamemode: GameMode, + pub player_gamemode: GameType, pub position: Vector3, pub pitch: f32, pub yaw: f32, @@ -113,7 +110,7 @@ pub struct LevelSettings { // Level Settings pub generator_type: VarInt, - pub world_gamemode: GameMode, + pub world_gamemode: GameType, pub hardcore: bool, pub difficulty: VarInt, pub spawn_position: BlockPos, @@ -135,7 +132,7 @@ pub struct LevelSettings { pub commands_enabled: bool, pub is_texture_packs_required: bool, - pub rule_data: GameRules, + pub rule_data: Vec, pub experiments: Experiments, pub bonus_chest: bool, @@ -167,13 +164,30 @@ pub struct LevelSettings { pub allow_anonymous_block_drops_in_editor_worlds: bool, } -#[derive(Default, PacketWrite)] +#[derive(Default)] pub struct Experiments { - //TODO! https://mojang.github.io/bedrock-protocol-docs/html/Experiments.html - pub names_size: u32, + pub toggles: Vec, pub experiments_ever_toggled: bool, } +impl PacketWrite for Experiments { + fn write(&self, writer: &mut W) -> Result<(), Error> { + (self.toggles.len() as u32).write(writer)?; + for toggle in &self.toggles { + toggle.write(writer)?; + } + self.experiments_ever_toggled.write(writer)?; + + Ok(()) + } +} + +#[derive(PacketWrite)] +pub struct ExperimentToggle { + pub name: String, + pub enabled: bool, +} + #[derive(Clone, Copy)] pub enum GamePublishSetting { NoMultiPlay = 0, diff --git a/crates/pumpkin-protocol/src/bedrock/client/take_item_actor.rs b/crates/pumpkin-protocol/src/bedrock/client/take_item_actor.rs index 7c17422c2..085daca98 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/take_item_actor.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/take_item_actor.rs @@ -1,19 +1,11 @@ +// Last verified for v2169 + use crate::{codec::var_ulong::VarULong, serial::PacketWrite}; use pumpkin_macros::packet; #[derive(PacketWrite)] #[packet(17)] pub struct CTakeItemActor { - // https://github.com/Sandertv/gophertunnel/blob/master/minecraft/protocol/packet/take_item_actor.go pub item_runtime_id: VarULong, pub actor_runtime_id: VarULong, } -impl CTakeItemActor { - #[must_use] - pub const fn new(item_runtime_id: VarULong, actor_runtime_id: VarULong) -> Self { - Self { - item_runtime_id, - actor_runtime_id, - } - } -} diff --git a/crates/pumpkin-protocol/src/bedrock/client/transfer.rs b/crates/pumpkin-protocol/src/bedrock/client/transfer.rs index bb4c4d583..171c7d4e7 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/transfer.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/transfer.rs @@ -6,15 +6,15 @@ use crate::serial::PacketWrite; #[packet(85)] pub struct CTransfer { - pub address: String, - pub port: u16, + pub server_address: String, + pub server_port: u16, pub reload_world: bool, } impl PacketWrite for CTransfer { fn write(&self, writer: &mut W) -> Result<(), Error> { - self.address.write(writer)?; - self.port.write(writer)?; + self.server_address.write(writer)?; + self.server_port.write(writer)?; self.reload_world.write(writer)?; // Optional GatheringsConfigurationJoinInfo. false.write(writer) @@ -23,10 +23,10 @@ impl PacketWrite for CTransfer { impl CTransfer { #[must_use] - pub const fn new(address: String, port: u16, reload_world: bool) -> Self { + pub const fn new(server_address: String, server_port: u16, reload_world: bool) -> Self { Self { - address, - port, + server_address, + server_port, reload_world, } } diff --git a/crates/pumpkin-protocol/src/bedrock/client/update_abilities.rs b/crates/pumpkin-protocol/src/bedrock/client/update_abilities.rs index 67201b8ea..fdc2fdbd7 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/update_abilities.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/update_abilities.rs @@ -1,20 +1,16 @@ +// Last verified for v2169 + use pumpkin_macros::packet; -use crate::serial::PacketWrite; - -use super::common::AbilityLayer; +use crate::{bedrock::client::SerializedAbilitiesData, serial::PacketWrite}; #[packet(187)] #[derive(PacketWrite)] pub struct CUpdateAbilities { - // https://mojang.github.io/bedrock-protocol-docs/html/UpdateAbilitiesPacket.html - // https://mojang.github.io/bedrock-protocol-docs/html/SerializedAbilitiesData.html - pub target_player_raw_id: i64, - pub player_permission: u8, - pub command_permission: u8, - pub layers: Vec, + pub data: SerializedAbilitiesData, } +// TODO: confirm these #[repr(u32)] pub enum Ability { Build = 0, diff --git a/crates/pumpkin-protocol/src/bedrock/client/update_attributes.rs b/crates/pumpkin-protocol/src/bedrock/client/update_attributes.rs index 73e5c781d..02c74703b 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/update_attributes.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/update_attributes.rs @@ -1,20 +1,19 @@ +// Last verified for v2169 + use pumpkin_macros::packet; -use crate::{ - codec::{var_uint::VarUInt, var_ulong::VarULong}, - serial::PacketWrite, -}; +use crate::{codec::var_ulong::VarULong, serial::PacketWrite}; #[derive(PacketWrite)] #[packet(29)] pub struct CUpdateAttributes { - pub runtime_id: VarULong, - pub attributes: Vec, - pub player_tick: VarULong, + pub target_runtime_id: VarULong, + pub attribute_list: Vec, + pub tick: VarULong, } #[derive(PacketWrite)] -pub struct Attribute { +pub struct AttributeData { pub min_value: f32, pub max_value: f32, pub current_value: f32, @@ -22,5 +21,15 @@ pub struct Attribute { pub default_max_value: f32, pub default_value: f32, pub name: String, - pub modifiers_list_size: VarUInt, + pub modifiers: Vec, +} + +#[derive(PacketWrite)] +pub struct AttributeModifier { + pub id: String, + pub name: String, + pub amount: f32, + pub operation: i32, + pub operand: i32, + pub is_serializable: bool, } diff --git a/crates/pumpkin-protocol/src/bedrock/client/update_block.rs b/crates/pumpkin-protocol/src/bedrock/client/update_block.rs index bf78890c6..ff5938cef 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/update_block.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/update_block.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use pumpkin_util::math::position::BlockPos; @@ -6,7 +8,7 @@ use crate::{codec::var_uint::VarUInt, serial::PacketWrite}; #[derive(PacketWrite)] #[packet(21)] pub struct CUpdateBlock { - pub position: BlockPos, + pub block_position: BlockPos, pub block_runtime_id: VarUInt, pub flags: VarUInt, pub layer: VarUInt, @@ -14,14 +16,14 @@ pub struct CUpdateBlock { impl CUpdateBlock { #[must_use] - pub const fn new(position: BlockPos, block_runtime_id: u32) -> Self { - Self::with_layer(position, block_runtime_id, 0) + pub const fn new(block_position: BlockPos, block_runtime_id: u32) -> Self { + Self::with_layer(block_position, block_runtime_id, 0) } #[must_use] - pub const fn with_layer(position: BlockPos, block_runtime_id: u32, layer: u32) -> Self { + pub const fn with_layer(block_position: BlockPos, block_runtime_id: u32, layer: u32) -> Self { Self { - position, + block_position, block_runtime_id: VarUInt(block_runtime_id), flags: VarUInt(0x3), // neighbors | network layer: VarUInt(layer), diff --git a/crates/pumpkin-protocol/src/bedrock/client/update_trade.rs b/crates/pumpkin-protocol/src/bedrock/client/update_trade.rs index 365a55bed..4cb8850ee 100644 --- a/crates/pumpkin-protocol/src/bedrock/client/update_trade.rs +++ b/crates/pumpkin-protocol/src/bedrock/client/update_trade.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use pumpkin_nbt::compound::NbtCompound; diff --git a/crates/pumpkin-protocol/src/bedrock/enum_as_str.rs b/crates/pumpkin-protocol/src/bedrock/enum_as_str.rs new file mode 100644 index 000000000..47a030544 --- /dev/null +++ b/crates/pumpkin-protocol/src/bedrock/enum_as_str.rs @@ -0,0 +1,44 @@ +use crate::serial::{PacketRead, PacketWrite}; +use std::str::FromStr; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct EnumAsStr(T); + +impl FromStr for EnumAsStr +where + std::io::Error: From, +{ + type Err = std::io::Error; + + fn from_str(s: &str) -> Result { + Ok(Self(T::from_str(s)?)) + } +} + +#[allow(clippy::to_string_trait_impl)] +impl ToString for EnumAsStr { + fn to_string(&self) -> String { + self.0.to_string() + } +} + +impl PacketRead for EnumAsStr +where + std::io::Error: From, +{ + fn read(reader: &mut R) -> Result { + Self::from_str(&String::read(reader)?) + } +} + +impl PacketWrite for EnumAsStr { + fn write(&self, writer: &mut W) -> Result<(), std::io::Error> { + self.to_string().write(writer) + } +} + +impl From for EnumAsStr { + fn from(value: T) -> Self { + Self(value) + } +} diff --git a/crates/pumpkin-protocol/src/bedrock/mod.rs b/crates/pumpkin-protocol/src/bedrock/mod.rs index 61298dc9d..d56134c1f 100644 --- a/crates/pumpkin-protocol/src/bedrock/mod.rs +++ b/crates/pumpkin-protocol/src/bedrock/mod.rs @@ -1,8 +1,8 @@ pub mod client; +pub mod enum_as_str; pub mod network_item; pub mod packet_decoder; pub mod packet_encoder; -pub mod respawn; pub mod server; pub mod status; diff --git a/crates/pumpkin-protocol/src/bedrock/respawn.rs b/crates/pumpkin-protocol/src/bedrock/respawn.rs deleted file mode 100644 index edb58e5c2..000000000 --- a/crates/pumpkin-protocol/src/bedrock/respawn.rs +++ /dev/null @@ -1,31 +0,0 @@ -use std::io::{Error, ErrorKind, Read, Write}; - -use crate::serial::{PacketRead, PacketWrite}; - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[repr(u8)] -pub enum RespawnState { - SearchingForSpawn = 0, - ReadyToSpawn = 1, - ClientReadyToSpawn = 2, -} - -impl PacketRead for RespawnState { - fn read(reader: &mut R) -> Result { - match u8::read(reader)? { - 0 => Ok(Self::SearchingForSpawn), - 1 => Ok(Self::ReadyToSpawn), - 2 => Ok(Self::ClientReadyToSpawn), - state => Err(Error::new( - ErrorKind::InvalidData, - format!("invalid Bedrock respawn state {state}"), - )), - } - } -} - -impl PacketWrite for RespawnState { - fn write(&self, writer: &mut W) -> Result<(), Error> { - (*self as u8).write(writer) - } -} diff --git a/crates/pumpkin-protocol/src/bedrock/server/actor_event.rs b/crates/pumpkin-protocol/src/bedrock/server/actor_event.rs index db558d8c6..bbd4ee2b8 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/actor_event.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/actor_event.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use std::io::{Error, Read, Write}; use pumpkin_macros::packet; @@ -11,79 +13,79 @@ use crate::{ #[derive(Debug, PacketRead, PacketWrite)] #[packet(27)] pub struct SActorEvent { - pub entity_runtime_id: VarULong, - pub event_type: ActorEventType, - pub event_data: VarInt, + pub target_runtime_id: VarULong, + pub event_id: ActorEventID, + pub data: VarInt, pub fire_at_position: Option>, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(u8)] -pub enum ActorEventType { - None = 0, - Jump = 1, - Hurt = 2, - Death = 3, - StartAttacking = 4, - StopAttacking = 5, - TamingFailed = 6, - TamingSucceeded = 7, - ShakeWetness = 8, +pub enum ActorEventID { + None, + Jump, + Hurt, + Death, + StartAttacking, + StopAttacking, + TamingFailed, + TamingSucceeded, + ShakeWetness, EatGrass = 10, - FishhookBubble = 11, - FishhookFishPosition = 12, - FishhookHookTime = 13, - FishhookTease = 14, - SquidFleeing = 15, - ZombieConverting = 16, - PlayAmbient = 17, - SpawnAlive = 18, - StartOfferFlower = 19, - StopOfferFlower = 20, - LoveHearts = 21, - VillagerAngry = 22, - VillagerHappy = 23, - WitchHatMagic = 24, - FireworksExplode = 25, - InLoveHearts = 26, - SilverfishMergeAnimation = 27, - GuardianAttackSound = 28, - DrinkPotion = 29, - ThrowPotion = 30, - CartWithPrimeTNT = 31, - PrimeCreeper = 32, - AirSupply = 33, - AddPlayerLevels = 34, - GuardianMiningFatigue = 35, - AgentSwingArm = 36, - DragonStartDeathAnim = 37, - GroundDust = 38, - Shake = 39, + FishhookBubble, + FishhookFishPos, + FishhookHookTime, + FishhookTease, + SquidFleeing, + ZombieConverting, + PlayAmbient, + SpawnAlive, + StartOfferFlower, + StopOfferFlower, + LoveHearts, + VillagerAngry, + VillagerHappy, + WitchHatMagic, + FireworksExplode, + InLoveHearts, + SilverfishMergeAnimation, + GuardianAttackSound, + DrinkPotion, + ThrowPotion, + PrimeTNTCart, + PrimeCreeper, + AirSupply, + DeprecatedAddPlayerLevels, + GuardianMiningFatigue, + AgentSwingArm, + DragonStartDeathAnim, + GroundDust, + Shake, Feed = 57, BabyAge = 60, - InstantDeath = 61, - NotifyTrade = 62, - LeashDestroyed = 63, - CaravanUpdated = 64, - TalismanActivate = 65, - UpdateStructureFeature = 66, - PlayerSpawnedMob = 67, - Puke = 68, - UpdateStackSize = 69, - StartSwimming = 70, - BalloonPop = 71, - TreasureHunt = 72, - SummonAgent = 73, - FinishedChargingItem = 74, + InstantDeath, + NotifyTrade, + LeashDestroyed, + CaravanUpdated, + TalismanActivate, + DeprecatedUpdateStructureFeature, + PlayerSpawnedMob, + Puke, + UpdateStackSize, + StartSwimming, + BalloonPop, + TreasureHunt, + SummonAgent, + FinishedChargingItem, ActorGrowUp = 76, - VibrationDetected = 77, - DrinkMilk = 78, - ShakeWetnessStop = 79, - KineticDamageDealt = 80, - HurtWithoutReceivingDamage = 81, + VibrationDetected, + DrinkMilk, + ShakeWetnessStop, + KineticDamageDealt, + HurtWithoutReceivingDamage, } -impl PacketRead for ActorEventType { +impl PacketRead for ActorEventID { fn read(reader: &mut R) -> Result { Ok(match u8::read(reader)? { 0 => Self::None, @@ -97,7 +99,7 @@ impl PacketRead for ActorEventType { 8 => Self::ShakeWetness, 10 => Self::EatGrass, 11 => Self::FishhookBubble, - 12 => Self::FishhookFishPosition, + 12 => Self::FishhookFishPos, 13 => Self::FishhookHookTime, 14 => Self::FishhookTease, 15 => Self::SquidFleeing, @@ -116,10 +118,10 @@ impl PacketRead for ActorEventType { 28 => Self::GuardianAttackSound, 29 => Self::DrinkPotion, 30 => Self::ThrowPotion, - 31 => Self::CartWithPrimeTNT, + 31 => Self::PrimeTNTCart, 32 => Self::PrimeCreeper, 33 => Self::AirSupply, - 34 => Self::AddPlayerLevels, + 34 => Self::DeprecatedAddPlayerLevels, 35 => Self::GuardianMiningFatigue, 36 => Self::AgentSwingArm, 37 => Self::DragonStartDeathAnim, @@ -132,7 +134,7 @@ impl PacketRead for ActorEventType { 63 => Self::LeashDestroyed, 64 => Self::CaravanUpdated, 65 => Self::TalismanActivate, - 66 => Self::UpdateStructureFeature, + 66 => Self::DeprecatedUpdateStructureFeature, 67 => Self::PlayerSpawnedMob, 68 => Self::Puke, 69 => Self::UpdateStackSize, @@ -152,7 +154,7 @@ impl PacketRead for ActorEventType { } } -impl PacketWrite for ActorEventType { +impl PacketWrite for ActorEventID { fn write(&self, writer: &mut W) -> Result<(), Error> { (*self as u8).write(writer) } @@ -166,21 +168,21 @@ mod tests { fn reads_feed_event() { let packet = SActorEvent::read(&mut b"\x019\x80\x80\x90\x11\0".as_slice()).unwrap(); - assert_eq!(packet.entity_runtime_id, VarULong(1)); - assert_eq!(packet.event_type, ActorEventType::Feed); - assert_eq!(packet.event_data, VarInt(17_956_864)); + assert_eq!(packet.target_runtime_id, VarULong(1)); + assert_eq!(packet.event_id, ActorEventID::Feed); + assert_eq!(packet.data, VarInt(17_956_864)); assert_eq!(packet.fire_at_position, None); } #[test] fn feed_event_wire_value_is_bidirectional() { let mut encoded = Vec::new(); - ActorEventType::Feed.write(&mut encoded).unwrap(); + ActorEventID::Feed.write(&mut encoded).unwrap(); assert_eq!(encoded, [57]); assert_eq!( - ActorEventType::read(&mut encoded.as_slice()).unwrap(), - ActorEventType::Feed + ActorEventID::read(&mut encoded.as_slice()).unwrap(), + ActorEventID::Feed ); } } diff --git a/crates/pumpkin-protocol/src/bedrock/server/animate.rs b/crates/pumpkin-protocol/src/bedrock/server/animate.rs index a5c011dd5..647a946ff 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/animate.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/animate.rs @@ -1,8 +1,14 @@ -use std::io::{Error, Read, Write}; +// Last verified for v2169 + +use std::{ + io::{Error, Read, Write}, + str::FromStr, +}; use pumpkin_macros::packet; use crate::{ + bedrock::enum_as_str::EnumAsStr, codec::var_ulong::VarULong, serial::{PacketRead, PacketWrite}, }; @@ -39,21 +45,22 @@ impl PacketWrite for AnimateAction { #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(u8)] -pub enum AnimateSwingSource { - None = 1, - Build = 2, - Mine = 3, - Interact = 4, - Attack = 5, - UseItem = 6, - ThrowItem = 7, - DropItem = 8, - Event = 9, +pub enum ActorSwingSource { + None, + Build, + Mine, + Interact, + Attack, + UseItem, + ThrowItem, + DropItem, + Event, } -impl PacketRead for AnimateSwingSource { - fn read(reader: &mut R) -> Result { - match String::read(reader)?.as_str() { +impl FromStr for ActorSwingSource { + type Err = Error; + fn from_str(s: &str) -> Result { + match s { "none" => Ok(Self::None), "build" => Ok(Self::Build), "mine" => Ok(Self::Mine), @@ -68,8 +75,9 @@ impl PacketRead for AnimateSwingSource { } } -impl PacketWrite for AnimateSwingSource { - fn write(&self, writer: &mut W) -> Result<(), Error> { +#[allow(clippy::to_string_trait_impl)] +impl ToString for ActorSwingSource { + fn to_string(&self) -> String { match self { Self::None => "none", Self::Build => "build", @@ -81,7 +89,7 @@ impl PacketWrite for AnimateSwingSource { Self::DropItem => "dropitem", Self::Event => "event", } - .write(writer) + .into() } } @@ -89,9 +97,9 @@ impl PacketWrite for AnimateSwingSource { #[packet(44)] pub struct SAnimate { pub action: AnimateAction, - pub runtime_entity_id: VarULong, + pub target_actor_runtime_id: VarULong, pub data: f32, - pub swing_source: Option, + pub swing_source: Option>, } #[cfg(test)] @@ -102,9 +110,9 @@ mod tests { fn animate_uses_cereal_swing_source_encoding() { let packet = SAnimate { action: AnimateAction::SwingArm, - runtime_entity_id: VarULong(42), + target_actor_runtime_id: VarULong(42), data: 0.0, - swing_source: Some(AnimateSwingSource::Attack), + swing_source: Some(ActorSwingSource::Attack.into()), }; let mut encoded = Vec::new(); packet.write(&mut encoded).unwrap(); @@ -113,16 +121,16 @@ mod tests { let decoded = SAnimate::read(&mut encoded.as_slice()).unwrap(); assert_eq!(decoded.action, AnimateAction::SwingArm); - assert_eq!(decoded.runtime_entity_id, VarULong(42)); + assert_eq!(decoded.target_actor_runtime_id, VarULong(42)); assert_eq!(decoded.data, 0.0); - assert_eq!(decoded.swing_source, Some(AnimateSwingSource::Attack)); + assert_eq!(decoded.swing_source, Some(ActorSwingSource::Attack.into())); } #[test] fn animate_omits_absent_swing_source_value() { let packet = SAnimate { action: AnimateAction::NoAction, - runtime_entity_id: VarULong(1), + target_actor_runtime_id: VarULong(1), data: 0.0, swing_source: None, }; diff --git a/crates/pumpkin-protocol/src/bedrock/server/block_pick_request.rs b/crates/pumpkin-protocol/src/bedrock/server/block_pick_request.rs index 15fac6401..265f9d843 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/block_pick_request.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/block_pick_request.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use pumpkin_util::math::position::BlockPos; @@ -6,7 +8,7 @@ use crate::serial::PacketRead; #[derive(Debug, PacketRead)] #[packet(34)] pub struct SBlockPickRequest { - pub block_pos: BlockPos, - pub add_block_nbt: bool, - pub hotbar_slot: u8, + pub position: BlockPos, + pub with_data: bool, + pub max_slots: u8, } diff --git a/crates/pumpkin-protocol/src/bedrock/server/client_cache_blob_status.rs b/crates/pumpkin-protocol/src/bedrock/server/client_cache_blob_status.rs index 344807501..5cc00f1ab 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/client_cache_blob_status.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/client_cache_blob_status.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use std::io::{Error, Read}; use pumpkin_macros::packet; @@ -21,9 +23,7 @@ impl PacketRead for SClientCacheBlobStatus { } let mut miss_hashes = Vec::with_capacity(miss_count.min(256)); for _ in 0..miss_count { - let mut bytes = [0u8; 8]; - reader.read_exact(&mut bytes)?; - miss_hashes.push(u64::from_le_bytes(bytes)); + miss_hashes.push(u64::read(reader)?); } let hit_count = VarUInt::read(reader)?.0 as usize; @@ -35,9 +35,7 @@ impl PacketRead for SClientCacheBlobStatus { } let mut hit_hashes = Vec::with_capacity(hit_count.min(256)); for _ in 0..hit_count { - let mut bytes = [0u8; 8]; - reader.read_exact(&mut bytes)?; - hit_hashes.push(u64::from_le_bytes(bytes)); + hit_hashes.push(u64::read(reader)?); } Ok(Self { diff --git a/crates/pumpkin-protocol/src/bedrock/server/client_cache_status.rs b/crates/pumpkin-protocol/src/bedrock/server/client_cache_status.rs index 0a090c619..89e94c8ea 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/client_cache_status.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/client_cache_status.rs @@ -1,9 +1,10 @@ +// Last verified for v2169 + use crate::serial::PacketRead; use pumpkin_macros::packet; #[derive(PacketRead)] #[packet(129)] pub struct SClientCacheStatus { - // https://mojang.github.io/bedrock-protocol-docs/html/ClientCacheStatusPacket.html - pub cache_supported: bool, + pub is_cache_supported: bool, } diff --git a/crates/pumpkin-protocol/src/bedrock/server/command_request.rs b/crates/pumpkin-protocol/src/bedrock/server/command_request.rs index b685668f3..3c51c2329 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/command_request.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/command_request.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use std::borrow::Cow; use uuid::Uuid; @@ -8,10 +10,17 @@ use crate::serial::{PacketRead, PacketReadSlice}; #[packet(77)] pub struct SCommandRequest<'a> { pub command: Cow<'a, str>, - pub command_type: Cow<'a, str>, - pub command_uuid: Uuid, - pub request_id: Cow<'a, str>, - pub player_actor_unique_id: i64, - pub is_internal_source: bool, + pub origin: CommandOriginData<'a>, + pub is_internal: bool, + + // TODO: enum CurrentCmdVersion pub version: Cow<'a, str>, } + +#[derive(Debug, PacketRead, PacketReadSlice)] +pub struct CommandOriginData<'a> { + pub r#type: Cow<'a, str>, + pub uuid: Uuid, + pub request_id: Cow<'a, str>, + pub player_id: i64, +} diff --git a/crates/pumpkin-protocol/src/bedrock/server/container_close.rs b/crates/pumpkin-protocol/src/bedrock/server/container_close.rs index 646151fb3..19221e485 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/container_close.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/container_close.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use crate::serial::{PacketRead, PacketWrite}; @@ -5,8 +7,7 @@ use crate::serial::{PacketRead, PacketWrite}; #[derive(Debug, PacketWrite, PacketRead)] #[packet(47)] pub struct SContainerClose { - // https://mojang.github.io/bedrock-protocol-docs/html/ContainerClosePacket.html pub container_id: u8, pub container_type: u8, - pub server_initiated: bool, + pub server_initiated_close: bool, } diff --git a/crates/pumpkin-protocol/src/bedrock/server/emote.rs b/crates/pumpkin-protocol/src/bedrock/server/emote.rs index 93ea490fe..b6ec61b64 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/emote.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/emote.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use crate::codec::var_uint::VarUInt; use crate::codec::var_ulong::VarULong; use crate::serial::{PacketRead, PacketReadSlice, PacketWrite}; @@ -10,9 +12,9 @@ pub const EMOTE_FLAG_MUTE_CHAT: u8 = 1 << 1; #[derive(Debug, PacketRead, PacketReadSlice, PacketWrite)] #[packet(138)] pub struct SEmote<'a> { - pub runtime_entity_id: VarULong, - pub emote_length: VarUInt, + pub actor_runtime_id: VarULong, pub emote_id: Cow<'a, str>, + pub emote_length_ticks: VarUInt, pub xuid: Cow<'a, str>, pub platform_id: Cow<'a, str>, pub flags: u8, diff --git a/crates/pumpkin-protocol/src/bedrock/server/emote_list.rs b/crates/pumpkin-protocol/src/bedrock/server/emote_list.rs index 97ccb25b2..7cd098d22 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/emote_list.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/emote_list.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use uuid::Uuid; use crate::{ @@ -9,8 +11,8 @@ use pumpkin_macros::packet; #[derive(Debug, PacketRead, PacketWrite)] #[packet(152)] pub struct SEmoteList { - pub runtime_entity_id: VarULong, - pub emote_pieces: Vec, + pub runtime_id: VarULong, + pub emote_piece_ids: Vec, } #[cfg(test)] @@ -21,8 +23,8 @@ mod tests { #[test] fn emote_list_serialization() { let packet = SEmoteList { - runtime_entity_id: VarULong(123), - emote_pieces: vec![Uuid::new_v4(), Uuid::new_v4()], + runtime_id: VarULong(123), + emote_piece_ids: vec![Uuid::new_v4(), Uuid::new_v4()], }; let mut buf = Vec::new(); @@ -31,7 +33,7 @@ mod tests { let mut reader = Cursor::new(buf); let decoded = SEmoteList::read(&mut reader).unwrap(); - assert_eq!(packet.runtime_entity_id.0, decoded.runtime_entity_id.0); - assert_eq!(packet.emote_pieces, decoded.emote_pieces); + assert_eq!(packet.runtime_id.0, decoded.runtime_id.0); + assert_eq!(packet.emote_piece_ids, decoded.emote_piece_ids); } } diff --git a/crates/pumpkin-protocol/src/bedrock/server/interact.rs b/crates/pumpkin-protocol/src/bedrock/server/interact.rs new file mode 100644 index 000000000..68bc5e655 --- /dev/null +++ b/crates/pumpkin-protocol/src/bedrock/server/interact.rs @@ -0,0 +1,39 @@ +// Last verified for v2169 + +use std::io::{Error, Read}; + +use pumpkin_macros::packet; +use pumpkin_util::math::vector3::Vector3; + +use crate::{codec::var_ulong::VarULong, serial::PacketRead}; + +#[derive(Debug, PacketRead)] +#[packet(33)] +pub struct SInteract { + pub action: Action, + pub target_runtime_id: VarULong, + pub position: Option>, +} + +#[derive(Debug)] +#[repr(u8)] +pub enum Action { + Invalid = 0, + StopRiding = 3, + InteractUpdate = 4, + NpcOpen = 5, + OpenInventory = 6, +} + +impl PacketRead for Action { + fn read(reader: &mut R) -> Result { + match u8::read(reader)? { + 0 => Ok(Self::Invalid), + 3 => Ok(Self::StopRiding), + 4 => Ok(Self::InteractUpdate), + 5 => Ok(Self::NpcOpen), + 6 => Ok(Self::OpenInventory), + _ => Err(Error::other("")), + } + } +} diff --git a/crates/pumpkin-protocol/src/bedrock/server/interaction.rs b/crates/pumpkin-protocol/src/bedrock/server/interaction.rs deleted file mode 100644 index 4549a855e..000000000 --- a/crates/pumpkin-protocol/src/bedrock/server/interaction.rs +++ /dev/null @@ -1,48 +0,0 @@ -use std::io::{Error, Read}; - -use pumpkin_macros::packet; -use pumpkin_util::math::vector3::Vector3; - -use crate::{codec::var_ulong::VarULong, serial::PacketRead}; - -#[derive(Debug, PacketRead)] -#[packet(33)] -pub struct SInteraction { - // https://mojang.github.io/bedrock-protocol-docs/html/InteractPacket.html - pub action: Action, - pub target_runtime_id: VarULong, - pub position: Option>, -} - -#[derive(Debug)] -#[repr(i8)] -pub enum Action { - Invalid = 0, - Interact = 1, - // No longer used in newer versions - Attack = 2, - StopRiding = 3, - InteractUpdate = 4, - NpcOpen = 5, - OpenInventory = 6, -} - -impl PacketRead for Action { - fn read(reader: &mut R) -> Result { - let mut byte = [0]; - reader.read_exact(&mut byte)?; - - let this = match byte[0] { - 0 => Self::Invalid, - 1 => Self::Interact, - 2 => Self::Attack, - 3 => Self::StopRiding, - 4 => Self::InteractUpdate, - 5 => Self::NpcOpen, - 6 => Self::OpenInventory, - _ => return Err(Error::other("")), - }; - - Ok(this) - } -} diff --git a/crates/pumpkin-protocol/src/bedrock/server/loading_screen.rs b/crates/pumpkin-protocol/src/bedrock/server/loading_screen.rs index 05722db59..d7dd6e743 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/loading_screen.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/loading_screen.rs @@ -1,3 +1,7 @@ +// Last verified for v2169 + +use std::io::{Error, Read}; + use pumpkin_macros::packet; use crate::{codec::var_int::VarInt, serial::PacketRead}; @@ -5,16 +9,32 @@ use crate::{codec::var_int::VarInt, serial::PacketRead}; #[derive(PacketRead)] #[packet(312)] pub struct SLoadingScreen { - // https://mojang.github.io/bedrock-protocol-docs/html/ServerboundLoadingScreenPacket.html - // Loading Screen Packet Type - // 0: Inavil, 1: Start, 2: End - status: VarInt, - _id: Option, + loading_screen_packet_type: LoadingScreenPacketType, + _loading_screen_id: Option, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(i32)] +pub enum LoadingScreenPacketType { + StartLoadingScreen = 0, + EndLoadingScreen = 1, +} + +impl PacketRead for LoadingScreenPacketType { + fn read(reader: &mut R) -> Result { + match VarInt::read(reader)?.0 { + 0 => Ok(Self::StartLoadingScreen), + 1 => Ok(Self::EndLoadingScreen), + val => Err(Error::other(format!( + "Invalid LoadingScreenPacketType: {val}" + ))), + } + } } impl SLoadingScreen { #[must_use] - pub const fn is_loading_done(&self) -> bool { - self.status.0 == 2 + pub fn is_loading_done(&self) -> bool { + self.loading_screen_packet_type == LoadingScreenPacketType::EndLoadingScreen } } diff --git a/crates/pumpkin-protocol/src/bedrock/server/mob_equipment.rs b/crates/pumpkin-protocol/src/bedrock/server/mob_equipment.rs index b52ad8000..9ba82d3c4 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/mob_equipment.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/mob_equipment.rs @@ -1,36 +1,19 @@ +// Last verified for v2169 + use crate::{ bedrock::network_item::NetworkItemStackDescriptor, codec::var_ulong::VarULong, serial::PacketRead, }; use pumpkin_macros::packet; -use std::io::{Error, Read}; -#[derive(Debug)] +#[derive(Debug, PacketRead)] #[packet(31)] pub struct SMobEquipment { pub entity_runtime_id: VarULong, pub item: NetworkItemStackDescriptor, - pub inventory_slot: u8, - pub hotbar_slot: u8, - pub window_id: u8, -} - -impl PacketRead for SMobEquipment { - fn read(reader: &mut R) -> Result { - let entity_runtime_id = VarULong::read(reader)?; - let item = NetworkItemStackDescriptor::read(reader)?; - let inventory_slot = u8::read(reader)?; - let hotbar_slot = u8::read(reader)?; - let window_id = u8::read(reader)?; - - Ok(Self { - entity_runtime_id, - item, - inventory_slot, - hotbar_slot, - window_id, - }) - } + pub slot: u8, + pub selected_slot: u8, + pub container_id: u8, } #[cfg(test)] @@ -54,9 +37,9 @@ mod tests { assert_eq!(packet.entity_runtime_id.0, 42); assert_eq!(packet.item.id, 0); - assert_eq!(packet.inventory_slot, 3); - assert_eq!(packet.hotbar_slot, 4); - assert_eq!(packet.window_id, 5); + assert_eq!(packet.slot, 3); + assert_eq!(packet.selected_slot, 4); + assert_eq!(packet.container_id, 5); assert_eq!(reader.position(), reader.get_ref().len() as u64); } } diff --git a/crates/pumpkin-protocol/src/bedrock/server/mod.rs b/crates/pumpkin-protocol/src/bedrock/server/mod.rs index a6a0e095e..63c5fe0a0 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/mod.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/mod.rs @@ -7,7 +7,7 @@ pub mod command_request; pub mod container_close; pub mod emote; pub mod emote_list; -pub mod interaction; +pub mod interact; pub mod inventory_transaction; pub mod item_stack_request; pub mod loading_screen; @@ -21,7 +21,7 @@ pub mod player_hotbar; pub mod request_ability; pub mod request_chunk_radius; pub mod request_network_settings; -pub mod resource_pack_response; +pub mod resource_pack_client_response; pub mod respawn; pub mod set_local_player_as_initialized; pub mod set_player_inventory_options; @@ -36,7 +36,7 @@ pub use command_request::*; pub use container_close::*; pub use emote::*; pub use emote_list::*; -pub use interaction::{Action as InteractAction, SInteraction}; +pub use interact::{Action as InteractAction, SInteract}; pub use inventory_transaction::*; pub use item_stack_request::*; pub use loading_screen::*; @@ -44,13 +44,13 @@ pub use login::*; pub use mob_equipment::*; pub use modal_form_response::*; pub use packet_violation_warning::*; -pub use player_action::{Action as PlayerActionType, SPlayerAction}; +pub use player_action::{PlayerActionType, SPlayerAction}; pub use player_auth_input::*; pub use player_hotbar::*; pub use request_ability::*; pub use request_chunk_radius::*; pub use request_network_settings::*; -pub use resource_pack_response::*; +pub use resource_pack_client_response::*; pub use respawn::*; pub use set_local_player_as_initialized::*; pub use set_player_inventory_options::*; diff --git a/crates/pumpkin-protocol/src/bedrock/server/modal_form_response.rs b/crates/pumpkin-protocol/src/bedrock/server/modal_form_response.rs index 9f111925e..27e9166d8 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/modal_form_response.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/modal_form_response.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use crate::codec::var_uint::VarUInt; use crate::serial::{PacketRead, PacketReadSlice}; use pumpkin_macros::packet; @@ -7,6 +9,8 @@ use std::borrow::Cow; #[packet(101)] pub struct SModalFormResponse<'a> { pub form_id: VarUInt, - pub form_data: Option>, - pub cancel_reason: Option, + pub json_response: Option>, + + // TODO: enum ModalFormCancelReason + pub form_cancel_reason: Option, } diff --git a/crates/pumpkin-protocol/src/bedrock/server/packet_violation_warning.rs b/crates/pumpkin-protocol/src/bedrock/server/packet_violation_warning.rs index a9417e31c..5e92c36b0 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/packet_violation_warning.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/packet_violation_warning.rs @@ -1,25 +1,16 @@ -use std::io::{Error, Read}; +// Last verified for v2169 use pumpkin_macros::packet; use crate::{codec::var_int::VarInt, serial::PacketRead}; -#[derive(Debug)] +#[derive(Debug, PacketRead)] #[packet(156)] pub struct SPacketViolationWarning { + // TODO: enum PacketViolationType pub violation_type: VarInt, - pub severity: VarInt, - pub packet_id: VarInt, - pub context: String, -} - -impl PacketRead for SPacketViolationWarning { - fn read(reader: &mut R) -> Result { - Ok(Self { - violation_type: VarInt::read(reader)?, - severity: VarInt::read(reader)?, - packet_id: VarInt::read(reader)?, - context: String::read(reader)?, - }) - } + // TODO: enum PacketViolationSeverity + pub violation_severity: VarInt, + pub violation_packet_id: VarInt, + pub violation_context: String, } diff --git a/crates/pumpkin-protocol/src/bedrock/server/player_action.rs b/crates/pumpkin-protocol/src/bedrock/server/player_action.rs index b7efc8bcf..cec352d64 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/player_action.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/player_action.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use std::io::{Error, Read}; use pumpkin_macros::packet; @@ -11,92 +13,92 @@ use crate::{ #[derive(Debug, PacketRead)] #[packet(36)] pub struct SPlayerAction { - pub runtime_id: VarULong, - pub action: Action, - pub block_pos: BlockPos, + pub player_runtime_id: VarULong, + pub action: PlayerActionType, + pub block_position: BlockPos, pub result_pos: BlockPos, pub face: VarInt, } #[derive(Debug)] #[repr(i32)] -pub enum Action { +pub enum PlayerActionType { Unknown = -1, - StartBreak = 0, - AbortBreak = 1, - StopBreak = 2, - GetUpdatedBlock = 3, + StartDestroyBlock, + AbortDestroyBlock, + StopDestroyBlock, + GetUpdatedBlock, /// Seems to be not used, or atleast not send by client - DropItem = 4, - StartSleeping = 5, - StopSleeping = 6, - Respawn = 7, - Jump = 8, - StartSprint = 9, - StopSprint = 10, - StartSneak = 11, - StopSneak = 12, - CreativePlayerDestroyBlock = 13, - DimensionChangeAck = 14, - StartGlide = 15, - StopGlide = 16, - BuildDenied = 17, - CrackBreak = 18, - ChangeSkin = 19, - SetEnchantmentSeed = 20, - Swimming = 21, - StopSwimming = 22, - StartSpinAttack = 23, - StopSpinAttack = 24, - InteractBlock = 25, - PredictDestroyBlock = 26, - ContinueDestroyBlock = 27, - StartItemUseOn = 28, - StopItemUseOn = 29, - HandledTeleport = 30, - MissedSwing = 31, - StartCrawling = 32, - StopCrawling = 33, - StartFlying = 34, - StopFlying = 35, - ClientAckServerData = 36, - StartUsingItem = 37, - InternalUpdate = 38, - Count = 39, + DropItem, + StartSleeping, + StopSleeping, + Respawn, + StartJump, + StartSprinting, + StopSprinting, + StartSneaking, + StopSneaking, + CreativeDestroyBlock, + ChangeDimensionAck, + StartGliding, + StopGliding, + DenyDestroyBlock, + CrackBlock, + ChangeSkin, + UpdatedEnchantingSeed, + StartSwimming, + StopSwimming, + StartSpinAttack, + StopSpinAttack, + InteractWithBlock, + PredictDestroyBlock, + ContinueDestroyBlock, + StartItemUseOn, + StopItemUseOn, + HandledTeleport, + MissedSwing, + StartCrawling, + StopCrawling, + StartFlying, + StopFlying, + ClientAckServerData, + StartUsingItem, + InternalUpdate, + Count, } -impl TryFrom for Action { +impl TryFrom for PlayerActionType { type Error = String; fn try_from(value: i32) -> Result { match value { -1 => Ok(Self::Unknown), - 0 => Ok(Self::StartBreak), - 1 => Ok(Self::AbortBreak), - 2 => Ok(Self::StopBreak), + 0 => Ok(Self::StartDestroyBlock), + 1 => Ok(Self::AbortDestroyBlock), + 2 => Ok(Self::StopDestroyBlock), 3 => Ok(Self::GetUpdatedBlock), 4 => Ok(Self::DropItem), 5 => Ok(Self::StartSleeping), 6 => Ok(Self::StopSleeping), 7 => Ok(Self::Respawn), - 8 => Ok(Self::Jump), - 9 => Ok(Self::StartSprint), - 10 => Ok(Self::StopSprint), - 11 => Ok(Self::StartSneak), - 12 => Ok(Self::StopSneak), - 13 => Ok(Self::CreativePlayerDestroyBlock), - 14 => Ok(Self::DimensionChangeAck), - 15 => Ok(Self::StartGlide), - 16 => Ok(Self::StopGlide), - 17 => Ok(Self::BuildDenied), - 18 => Ok(Self::CrackBreak), + 8 => Ok(Self::StartJump), + 9 => Ok(Self::StartSprinting), + 10 => Ok(Self::StopSprinting), + 11 => Ok(Self::StartSneaking), + 12 => Ok(Self::StopSneaking), + 13 => Ok(Self::CreativeDestroyBlock), + 14 => Ok(Self::ChangeDimensionAck), + 15 => Ok(Self::StartGliding), + 16 => Ok(Self::StopGliding), + 17 => Ok(Self::DenyDestroyBlock), + 18 => Ok(Self::CrackBlock), 19 => Ok(Self::ChangeSkin), - 20 => Ok(Self::SetEnchantmentSeed), - 21 => Ok(Self::Swimming), + 20 => Ok(Self::UpdatedEnchantingSeed), + 21 => Ok(Self::StartSwimming), 22 => Ok(Self::StopSwimming), 23 => Ok(Self::StartSpinAttack), 24 => Ok(Self::StopSpinAttack), - 25 => Ok(Self::InteractBlock), + 25 => Ok(Self::InteractWithBlock), 26 => Ok(Self::PredictDestroyBlock), 27 => Ok(Self::ContinueDestroyBlock), 28 => Ok(Self::StartItemUseOn), @@ -116,7 +118,7 @@ impl TryFrom for Action { } } -impl PacketRead for Action { +impl PacketRead for PlayerActionType { fn read(reader: &mut R) -> Result { let action = VarInt::read(reader)?; diff --git a/crates/pumpkin-protocol/src/bedrock/server/player_hotbar.rs b/crates/pumpkin-protocol/src/bedrock/server/player_hotbar.rs index 186aca721..0f050bf8f 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/player_hotbar.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/player_hotbar.rs @@ -1,15 +1,14 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use crate::{codec::var_uint::VarUInt, serial::PacketRead}; /// Sent by the Bedrock client when the player changes their active hotbar slot. -/// -/// Packet ID: `48` -/// Ref: #[derive(PacketRead)] #[packet(48)] pub struct SPlayerHotbar { pub selected_slot: VarUInt, pub container_id: u8, - pub select_slot: bool, + pub should_select_slot: bool, } diff --git a/crates/pumpkin-protocol/src/bedrock/server/request_chunk_radius.rs b/crates/pumpkin-protocol/src/bedrock/server/request_chunk_radius.rs index d2c084c30..d8f6fd084 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/request_chunk_radius.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/request_chunk_radius.rs @@ -1,3 +1,5 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use crate::{codec::var_int::VarInt, serial::PacketRead}; @@ -5,7 +7,6 @@ use crate::{codec::var_int::VarInt, serial::PacketRead}; #[derive(PacketRead, Debug)] #[packet(69)] pub struct SRequestChunkRadius { - // https://mojang.github.io/bedrock-protocol-docs/html/RequestChunkRadiusPacket.html pub chunk_radius: VarInt, - pub max_radius: u8, + pub max_chunk_radius: u8, } diff --git a/crates/pumpkin-protocol/src/bedrock/server/request_network_settings.rs b/crates/pumpkin-protocol/src/bedrock/server/request_network_settings.rs index 0b0207821..bf9594462 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/request_network_settings.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/request_network_settings.rs @@ -1,10 +1,12 @@ +// Last verified for v2169 + use pumpkin_macros::packet; use crate::serial::PacketRead; #[derive(PacketRead)] -#[packet(0xC1)] +#[packet(193)] pub struct SRequestNetworkSettings { #[serial(big_endian)] - pub protocol_version: i32, + pub client_network_version: i32, } diff --git a/crates/pumpkin-protocol/src/bedrock/server/resource_pack_response.rs b/crates/pumpkin-protocol/src/bedrock/server/resource_pack_client_response.rs similarity index 92% rename from crates/pumpkin-protocol/src/bedrock/server/resource_pack_response.rs rename to crates/pumpkin-protocol/src/bedrock/server/resource_pack_client_response.rs index 6b009a4a2..d84ba9622 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/resource_pack_response.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/resource_pack_client_response.rs @@ -4,13 +4,13 @@ use crate::{codec::var_uint::VarUInt, serial::PacketRead}; use pumpkin_macros::packet; #[packet(8)] -pub struct SResourcePackResponse { +pub struct SResourcePackClientResponse { pub response: u8, pub download_size: u16, pub pack_ids: Vec, } -impl PacketRead for SResourcePackResponse { +impl PacketRead for SResourcePackClientResponse { fn read(reader: &mut R) -> Result { let encoded_status = VarUInt::read(reader)?.0; let response = encoded_status @@ -47,7 +47,7 @@ impl PacketRead for SResourcePackResponse { } } -impl SResourcePackResponse { +impl SResourcePackClientResponse { pub const STATUS_REFUSED: u8 = 1; pub const STATUS_SEND_PACKS: u8 = 2; pub const STATUS_HAVE_ALL_PACKS: u8 = 3; diff --git a/crates/pumpkin-protocol/src/bedrock/server/respawn.rs b/crates/pumpkin-protocol/src/bedrock/server/respawn.rs index 26dec803a..0c0adef7f 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/respawn.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/respawn.rs @@ -1,12 +1,69 @@ +// Last verified for v2169 + +use std::io::{Error, ErrorKind, Read, Write}; + use pumpkin_macros::packet; use pumpkin_util::math::vector3::Vector3; -use crate::{bedrock::respawn::RespawnState, codec::var_ulong::VarULong, serial::PacketRead}; +use crate::{ + codec::var_ulong::VarULong, + serial::{PacketRead, PacketWrite}, +}; -#[derive(PacketRead)] +#[derive(PacketRead, PacketWrite)] #[packet(45)] pub struct SRespawn { pub position: Vector3, pub state: RespawnState, pub player_runtime_id: VarULong, } + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] +pub enum RespawnState { + SearchingForSpawn, + ReadyToSpawn, + ClientReadyToSpawn, +} + +impl PacketRead for RespawnState { + fn read(reader: &mut R) -> Result { + match u8::read(reader)? { + 0 => Ok(Self::SearchingForSpawn), + 1 => Ok(Self::ReadyToSpawn), + 2 => Ok(Self::ClientReadyToSpawn), + state => Err(Error::new( + ErrorKind::InvalidData, + format!("invalid Bedrock respawn state {state}"), + )), + } + } +} + +impl PacketWrite for RespawnState { + fn write(&self, writer: &mut W) -> Result<(), Error> { + (*self as u8).write(writer) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::serial::PacketRead; + + #[test] + fn respawn_packet_roundtrip() { + let packet = SRespawn { + position: Vector3::new(1.5, 64.0, -2.25), + state: RespawnState::ReadyToSpawn, + player_runtime_id: VarULong(42), + }; + let mut encoded = Vec::new(); + packet.write(&mut encoded).unwrap(); + + let decoded = SRespawn::read(&mut encoded.as_slice()).unwrap(); + assert_eq!(decoded.position, packet.position); + assert_eq!(decoded.state, packet.state); + assert_eq!(decoded.player_runtime_id.0, packet.player_runtime_id.0); + } +} diff --git a/crates/pumpkin-protocol/src/bedrock/server/set_local_player_as_initialized.rs b/crates/pumpkin-protocol/src/bedrock/server/set_local_player_as_initialized.rs index 6db79e6c5..bc64ab080 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/set_local_player_as_initialized.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/set_local_player_as_initialized.rs @@ -1,8 +1,10 @@ +// Last verified for v2169 + use crate::{codec::var_ulong::VarULong, serial::PacketRead}; use pumpkin_macros::packet; #[derive(PacketRead)] #[packet(113)] pub struct SSetLocalPlayerAsInitialized { - pub runtime_entity_id: VarULong, + pub player_id: VarULong, } diff --git a/crates/pumpkin-protocol/src/bedrock/server/set_player_inventory_options.rs b/crates/pumpkin-protocol/src/bedrock/server/set_player_inventory_options.rs index 9a681e007..91408e2b3 100644 --- a/crates/pumpkin-protocol/src/bedrock/server/set_player_inventory_options.rs +++ b/crates/pumpkin-protocol/src/bedrock/server/set_player_inventory_options.rs @@ -1,12 +1,20 @@ +// Last verified for v2169 + use crate::{codec::var_int::VarInt, serial::PacketRead}; use pumpkin_macros::packet; #[derive(PacketRead)] #[packet(307)] pub struct SSetPlayerInventoryOptions { + // TODO: enum InventoryLeftTabIndex pub left_inventory_tab: VarInt, + // TODO: enum InventoryRightTabIndex pub right_inventory_tab: VarInt, + pub filtering: bool, - pub inventory_layout: VarInt, - pub crafting_layout: VarInt, + + // TODO: enum InventoryLayout + pub layout_inv: VarInt, + // TODO: enum InventoryLayout + pub layout_craft: VarInt, } diff --git a/crates/pumpkin-protocol/src/serial/serializer.rs b/crates/pumpkin-protocol/src/serial/serializer.rs index 8fe53d510..3f7164311 100644 --- a/crates/pumpkin-protocol/src/serial/serializer.rs +++ b/crates/pumpkin-protocol/src/serial/serializer.rs @@ -5,10 +5,7 @@ use std::{ }; use pumpkin_nbt::{Nbt, NbtCompound}; -use pumpkin_util::{ - GameMode, - math::{position::BlockPos, vector2::Vector2, vector3::Vector3}, -}; +use pumpkin_util::math::{position::BlockPos, vector2::Vector2, vector3::Vector3}; use crate::{ codec::{var_int::VarInt, var_uint::VarUInt}, @@ -190,19 +187,6 @@ impl PacketWrite for SocketAddr { } } -impl PacketWrite for GameMode { - fn write(&self, writer: &mut W) -> Result<(), Error> { - VarInt(match self { - Self::Survival => 0, - Self::Creative => 1, - Self::Adventure => 2, - // I have no idea why - Self::Spectator => 6, - }) - .write(writer) - } -} - impl PacketWrite for Cow<'_, str> { fn write(&self, writer: &mut W) -> Result<(), Error> { self.as_ref().write(writer) diff --git a/crates/pumpkin/src/command/client_suggestions.rs b/crates/pumpkin/src/command/client_suggestions.rs index 89c58b173..8575619b4 100644 --- a/crates/pumpkin/src/command/client_suggestions.rs +++ b/crates/pumpkin/src/command/client_suggestions.rs @@ -1,4 +1,5 @@ use pumpkin_protocol::{ + bedrock::client::CommandPermissionLevel, codec::var_int::VarInt, java::client::play::{ ArgumentType, CCommands, ProtoNode, ProtoNodeType, StringProtoArgBehavior, @@ -15,8 +16,7 @@ use crate::command::node::{ use crate::entity::player::Player; use crate::server::Server; use pumpkin_protocol::bedrock::client::available_commands::{ - CAvailableCommands, Command, CommandEnum, CommandOverload, CommandParameter, arg_flags, - arg_types, command_permissions, + CAvailableCommands, CommandData, EnumData, OverloadData, ParamData, arg_flags, arg_types, }; use pumpkin_protocol::java::client::play::SuggestionProviders; @@ -315,7 +315,7 @@ fn nodes_to_proto_node_builders<'a>( struct BuilderContext<'a> { enum_values: &'a mut Vec, - enums: &'a mut Vec, + enums: &'a mut Vec, } #[expect(clippy::too_many_lines)] @@ -327,8 +327,8 @@ pub async fn send_bedrock_commands_packet( let cmd_src = super::CommandSender::Player(player.clone()); let mut enum_values: Vec = Vec::new(); - let mut enums: Vec = Vec::new(); - let mut commands: Vec = Vec::new(); + let mut enums: Vec = Vec::new(); + let mut commands: Vec = Vec::new(); let fallback_dispatcher = &dispatcher.fallback_dispatcher; for key in fallback_dispatcher.commands.keys() { @@ -359,13 +359,13 @@ pub async fn send_bedrock_commands_packet( let overloads = build_overloads_from_nodes(&tree.nodes, &tree.children, &mut ctx); - commands.push(Command { + commands.push(CommandData { name: key.clone(), description: String::new(), flags: 0, - permission: command_permissions::ANY.to_string(), - aliases_enum_index: -1, - chained_subcommand_offsets: Vec::new(), + permission_level: CommandPermissionLevel::Any.into(), + alias_enum: -1, + command_data_chained_subcommand_indexes: Vec::new(), overloads, }); } @@ -419,13 +419,13 @@ pub async fn send_bedrock_commands_packet( let overloads = build_overloads_from_attached_nodes(&tree_nodes, &child_ids, is_executable, &mut ctx); - commands.push(Command { + commands.push(CommandData { name, description: String::new(), flags: 0, - permission: command_permissions::ANY.to_string(), - aliases_enum_index: -1, - chained_subcommand_offsets: Vec::new(), + permission_level: CommandPermissionLevel::Any.into(), + alias_enum: -1, + command_data_chained_subcommand_indexes: Vec::new(), overloads, }); } @@ -433,9 +433,9 @@ pub async fn send_bedrock_commands_packet( let packet = CAvailableCommands { enum_values, chained_subcommand_values: Vec::new(), - suffixes: Vec::new(), - chained_subcommands: Vec::new(), - enums, + post_fixes: Vec::new(), + chained_subcommand_data: Vec::new(), + enum_data: enums, commands, soft_enums: Vec::new(), constraints: Vec::new(), @@ -450,13 +450,13 @@ fn build_overloads_from_nodes( nodes: &[Node], children: &[usize], ctx: &mut BuilderContext, -) -> Vec { +) -> Vec { let mut overloads = Vec::new(); collect_overloads_from_nodes(nodes, children, &mut Vec::new(), &mut overloads, ctx); if overloads.is_empty() { - overloads.push(CommandOverload { - chaining: false, - parameters: Vec::new(), + overloads.push(OverloadData { + is_chaining: false, + parameter_data: Vec::new(), }); } overloads @@ -465,8 +465,8 @@ fn build_overloads_from_nodes( fn collect_overloads_from_nodes( nodes: &[Node], children: &[usize], - current_params: &mut Vec, - overloads: &mut Vec, + current_params: &mut Vec, + overloads: &mut Vec, ctx: &mut BuilderContext, ) { let mut has_executable = false; @@ -485,22 +485,22 @@ fn collect_overloads_from_nodes( std::slice::from_ref(string), ); let mut params = current_params.clone(); - params.push(CommandParameter { + params.push(ParamData { name: string.clone(), - type_info: arg_flags::ARG_FLAG_VALID + parse_symbol: arg_flags::ARG_FLAG_VALID | arg_flags::ARG_FLAG_ENUM | enum_idx as u32, - optional: false, + is_optional: false, options: 0, }); collect_overloads_from_nodes(nodes, &node.children, &mut params, overloads, ctx); } NodeType::Argument { name, consumer, .. } => { let mut params = current_params.clone(); - params.push(CommandParameter { + params.push(ParamData { name: name.clone(), - type_info: bedrock_param_type(&consumer.get_client_side_parser()), - optional: false, + parse_symbol: bedrock_param_type(&consumer.get_client_side_parser()), + is_optional: false, options: 0, }); collect_overloads_from_nodes(nodes, &node.children, &mut params, overloads, ctx); @@ -512,9 +512,9 @@ fn collect_overloads_from_nodes( } if has_executable { - overloads.push(CommandOverload { - chaining: false, - parameters: current_params.clone(), + overloads.push(OverloadData { + is_chaining: false, + parameter_data: current_params.clone(), }); } } @@ -524,19 +524,19 @@ fn build_overloads_from_attached_nodes( child_ids: &[NodeId], is_root_executable: bool, ctx: &mut BuilderContext, -) -> Vec { +) -> Vec { let mut overloads = Vec::new(); if is_root_executable { - overloads.push(CommandOverload { - chaining: false, - parameters: Vec::new(), + overloads.push(OverloadData { + is_chaining: false, + parameter_data: Vec::new(), }); } collect_overloads_from_attached(tree, child_ids, &Vec::new(), &mut overloads, ctx); if overloads.is_empty() { - overloads.push(CommandOverload { - chaining: false, - parameters: Vec::new(), + overloads.push(OverloadData { + is_chaining: false, + parameter_data: Vec::new(), }); } overloads @@ -545,8 +545,8 @@ fn build_overloads_from_attached_nodes( fn collect_overloads_from_attached( tree: &[&AttachedNode], child_ids: &[NodeId], - current_params: &[CommandParameter], - overloads: &mut Vec, + current_params: &[ParamData], + overloads: &mut Vec, ctx: &mut BuilderContext, ) { for &child_id in child_ids { @@ -563,19 +563,19 @@ fn collect_overloads_from_attached( &[name.to_string()], ); let mut params = current_params.to_vec(); - params.push(CommandParameter { + params.push(ParamData { name: name.to_string(), - type_info: arg_flags::ARG_FLAG_VALID + parse_symbol: arg_flags::ARG_FLAG_VALID | arg_flags::ARG_FLAG_ENUM | enum_idx as u32, - optional: false, + is_optional: false, options: 0, }); let grandchild_ids: Vec = node.children_ref().values().copied().collect(); if lit.owned.command.is_some() { - overloads.push(CommandOverload { - chaining: false, - parameters: params.clone(), + overloads.push(OverloadData { + is_chaining: false, + parameter_data: params.clone(), }); } collect_overloads_from_attached(tree, &grandchild_ids, ¶ms, overloads, ctx); @@ -589,19 +589,19 @@ fn collect_overloads_from_attached( &[name.to_string()], ); let mut params = current_params.to_vec(); - params.push(CommandParameter { + params.push(ParamData { name: name.to_string(), - type_info: arg_flags::ARG_FLAG_VALID + parse_symbol: arg_flags::ARG_FLAG_VALID | arg_flags::ARG_FLAG_ENUM | enum_idx as u32, - optional: false, + is_optional: false, options: 0, }); let grandchild_ids: Vec = node.children_ref().values().copied().collect(); if cmd.owned.command.is_some() { - overloads.push(CommandOverload { - chaining: false, - parameters: params.clone(), + overloads.push(OverloadData { + is_chaining: false, + parameter_data: params.clone(), }); } collect_overloads_from_attached(tree, &grandchild_ids, ¶ms, overloads, ctx); @@ -609,17 +609,17 @@ fn collect_overloads_from_attached( AttachedNode::Argument(arg) => { let parser = arg.meta.argument_type.client_side_parser(); let mut params = current_params.to_vec(); - params.push(CommandParameter { + params.push(ParamData { name: arg.meta.name.to_string(), - type_info: bedrock_param_type(&parser), - optional: false, + parse_symbol: bedrock_param_type(&parser), + is_optional: false, options: 0, }); let grandchild_ids: Vec = node.children_ref().values().copied().collect(); if arg.owned.command.is_some() { - overloads.push(CommandOverload { - chaining: false, - parameters: params.clone(), + overloads.push(OverloadData { + is_chaining: false, + parameter_data: params.clone(), }); } collect_overloads_from_attached(tree, &grandchild_ids, ¶ms, overloads, ctx); @@ -641,7 +641,7 @@ fn ensure_enum_value(enum_values: &mut Vec, value: &str) -> u32 { } fn ensure_command_enum( - enums: &mut Vec, + enums: &mut Vec, enum_values: &mut Vec, name: &str, values: &[String], @@ -650,14 +650,12 @@ fn ensure_command_enum( return pos; } - let value_indices: Vec = values - .iter() - .map(|val| ensure_enum_value(enum_values, val)) - .collect(); - - enums.push(CommandEnum { + enums.push(EnumData { name: name.to_string(), - value_indices, + values: values + .iter() + .map(|val| ensure_enum_value(enum_values, val)) + .collect(), }); enums.len() - 1 diff --git a/crates/pumpkin/src/entity/attributes.rs b/crates/pumpkin/src/entity/attributes.rs index f9c65798e..864969e34 100644 --- a/crates/pumpkin/src/entity/attributes.rs +++ b/crates/pumpkin/src/entity/attributes.rs @@ -94,10 +94,10 @@ pub async fn send_attribute_updates_for_living( attributes: Vec, ) { use pumpkin_protocol::bedrock::client::update_attributes::{ - Attribute as BeAttribute, CUpdateAttributes as BePacket, + AttributeData as BeAttribute, CUpdateAttributes as BePacket, }; use pumpkin_protocol::codec::var_int::VarInt; - use pumpkin_protocol::codec::{var_uint::VarUInt, var_ulong::VarULong}; + use pumpkin_protocol::codec::var_ulong::VarULong; use pumpkin_protocol::java::client::play::AttributeModifier as JeAttrMod; use pumpkin_protocol::java::client::play::CUpdateAttributes as JePacket; use pumpkin_protocol::java::client::play::Property as JeProperty; @@ -157,7 +157,7 @@ pub async fn send_attribute_updates_for_living( name, // Bedrock receives the already-computed effective value above. Do not advertise // modifier entries until their payload is encoded as well. - modifiers_list_size: VarUInt(0), + modifiers: Vec::new(), }; be_attributes.push(be_attribute); @@ -167,9 +167,9 @@ pub async fn send_attribute_updates_for_living( let runtime_id = living.entity.entity_id as u64; let be_packet = BePacket { - runtime_id: VarULong(runtime_id), - attributes: be_attributes, - player_tick: VarULong(0), + target_runtime_id: VarULong(runtime_id), + attribute_list: be_attributes, + tick: VarULong(0), }; living diff --git a/crates/pumpkin/src/entity/breath.rs b/crates/pumpkin/src/entity/breath.rs index ef3e8fe72..a35fb62ad 100644 --- a/crates/pumpkin/src/entity/breath.rs +++ b/crates/pumpkin/src/entity/breath.rs @@ -166,7 +166,7 @@ impl BreathManager { let air = self.air_supply.load(Ordering::Relaxed).clamp(0, MAX_AIR); let mut bedrock_meta = - pumpkin_protocol::bedrock::client::set_actor_data::EntityMetadata::new(); + pumpkin_protocol::bedrock::client::set_actor_data::SyncedActorDataList::new(); bedrock_meta.set( pumpkin_protocol::bedrock::client::set_actor_data::entity_data_key::AIR_SUPPLY, pumpkin_protocol::bedrock::client::set_actor_data::MetadataValue::Short(air as i16), diff --git a/crates/pumpkin/src/entity/item.rs b/crates/pumpkin/src/entity/item.rs index 430b4d1a8..e060b8f22 100644 --- a/crates/pumpkin/src/entity/item.rs +++ b/crates/pumpkin/src/entity/item.rs @@ -638,13 +638,13 @@ impl EntityBase for ItemEntity { let runtime_id = entity.entity_id as u64; let item_stack = self.item_stack.lock().await; let packet = CAddItemActor { - entity_unique_id: VarLong(runtime_id as i64), - entity_runtime_id: VarULong(runtime_id), + target_actor_id: VarLong(runtime_id as i64), + target_runtime_id: VarULong(runtime_id), item: ItemStackWrapper::from(&*item_stack), position: entity.pos.load().to_f32_lossy(), velocity: entity.velocity.load().to_f32_lossy(), - metadata: entity.bedrock_metadata(), - from_fishing: false, + entity_data: entity.bedrock_metadata(), + is_from_fishing: false, }; if let Ok(data) = client.serialize_packet(&packet) { client.send_game_packet(data).await; diff --git a/crates/pumpkin/src/entity/living.rs b/crates/pumpkin/src/entity/living.rs index 8abd42385..fd2bd62a0 100644 --- a/crates/pumpkin/src/entity/living.rs +++ b/crates/pumpkin/src/entity/living.rs @@ -7,7 +7,7 @@ use pumpkin_inventory::build_equipment_slots; use pumpkin_inventory::player::player_inventory::PlayerInventory; use pumpkin_inventory::screen_handler::InventoryPlayer; use pumpkin_protocol::bedrock::client::take_item_actor::CTakeItemActor; -use pumpkin_protocol::bedrock::server::actor_event::{ActorEventType, SActorEvent}; +use pumpkin_protocol::bedrock::server::actor_event::{ActorEventID, SActorEvent}; use pumpkin_protocol::codec::var_ulong::VarULong; use pumpkin_util::GameMode; use pumpkin_util::Hand; @@ -249,15 +249,16 @@ impl LivingEntity { } else { 0 }; - let be_packet = pumpkin_protocol::bedrock::client::CMobEquipment::new( - self.entity_id() as u64, - pumpkin_protocol::bedrock::network_item::NetworkItemStackDescriptor::from( + + let be_packet = pumpkin_protocol::bedrock::client::CMobEquipment { + target_runtime_id: (self.entity_id() as u64).into(), + item: pumpkin_protocol::bedrock::network_item::NetworkItemStackDescriptor::from( stack, ), - 0, - 0, - window_id, - ); + slot: 0, + selected_slot: 0, + container_id: window_id, + }; self.entity .world .load() @@ -305,10 +306,10 @@ impl LivingEntity { self.entity.entity_id.into(), VarInt(stack_amount as i32), ), - &CTakeItemActor::new( - VarULong(item.entity_id as u64), - VarULong(self.entity.entity_id as u64), - ), + &CTakeItemActor { + item_runtime_id: VarULong(item.entity_id as u64), + actor_runtime_id: VarULong(self.entity.entity_id as u64), + }, ); } @@ -343,10 +344,11 @@ impl LivingEntity { .fetch_and(!mask, Ordering::Relaxed); } - let mut meta = pumpkin_protocol::bedrock::client::set_actor_data::EntityMetadata::new(); + let mut meta = + pumpkin_protocol::bedrock::client::set_actor_data::SyncedActorDataList::new(); meta.set( pumpkin_protocol::bedrock::client::set_actor_data::entity_data_key::FLAGS, - pumpkin_protocol::bedrock::client::set_actor_data::MetadataValue::Long( + pumpkin_protocol::bedrock::client::set_actor_data::MetadataValue::Int64( self.entity.bedrock_flags.load(Ordering::Relaxed), ), ); @@ -712,16 +714,16 @@ impl LivingEntity { flag, ); - let be_packet = pumpkin_protocol::bedrock::client::CMobEffect::new( - VarULong(self.entity.entity_id as u64), - pumpkin_protocol::bedrock::client::CMobEffect::EVENT_ADD, - VarInt(effect.effect_type.to_bedrock_id()), - VarInt(i32::from(effect.amplifier)), - effect.show_particles, - VarInt(effect.duration), - VarULong(0), - effect.ambient, - ); + let be_packet = pumpkin_protocol::bedrock::client::CMobEffect { + target_runtime_id: VarULong(self.entity.entity_id as u64), + event_id: pumpkin_protocol::bedrock::client::CMobEffect::EVENT_ADD, + effect_id: VarInt(effect.effect_type.to_bedrock_id()), + effect_amplifier: VarInt(i32::from(effect.amplifier)), + show_particles: effect.show_particles, + effect_duration_ticks: VarInt(effect.duration), + tick: VarULong(0), + ambient: effect.ambient, + }; let chunk_pos = self.entity.chunk_pos.load(); self.entity @@ -964,7 +966,7 @@ impl LivingEntity { ); let be_packet = pumpkin_protocol::bedrock::server::animate::SAnimate { action: pumpkin_protocol::bedrock::server::animate::AnimateAction::SwingArm, - runtime_entity_id: pumpkin_protocol::codec::var_ulong::VarULong(entity_id as u64), + target_actor_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong(entity_id as u64), data: 0.0, swing_source: None, }; @@ -1542,11 +1544,7 @@ impl LivingEntity { self.update_death_stats(&*dyn_self, cause).await; // Plays the death sound - world.send_entity_status( - &self.entity, - EntityStatus::Death, - Some(ActorEventType::Death), - ); + world.send_entity_status(&self.entity, EntityStatus::Death, Some(ActorEventID::Death)); let looting_level; let tool = if let Some(cause_ent) = cause { if let Some(player) = cause_ent @@ -1873,7 +1871,7 @@ impl LivingEntity { self.entity.world.load().send_entity_status( &self.entity, EntityStatus::ProtectedFromDeath, - Some(ActorEventType::InstantDeath), + Some(ActorEventID::InstantDeath), ); // Set Absorption, Regeneration, and Fire Resistance effects @@ -2501,9 +2499,9 @@ impl EntityBase for LivingEntity { - self.entity.yaw.load() }); let hurt_event = SActorEvent { - entity_runtime_id: VarULong(entity_id as u64), - event_type: ActorEventType::Hurt, - event_data: VarInt(0), + target_runtime_id: VarULong(entity_id as u64), + event_id: ActorEventID::Hurt, + data: VarInt(0), fire_at_position: None, }; world @@ -2912,7 +2910,7 @@ impl EntityBase for LivingEntity { self.entity.world.load().send_entity_status( &self.entity, EntityStatus::Death, - Some(ActorEventType::Death), + Some(ActorEventID::Death), ); self.entity.remove().await; } diff --git a/crates/pumpkin/src/entity/mob/mod.rs b/crates/pumpkin/src/entity/mob/mod.rs index a449918bc..a960a1414 100644 --- a/crates/pumpkin/src/entity/mob/mod.rs +++ b/crates/pumpkin/src/entity/mob/mod.rs @@ -603,7 +603,7 @@ pub trait Mob: EntityBase + Send + Sync { &self, ) -> EntityBaseFuture< '_, - Option, + Option, > { Box::pin(async { None }) } diff --git a/crates/pumpkin/src/entity/mod.rs b/crates/pumpkin/src/entity/mod.rs index f8688bcfd..cdadcf5dd 100644 --- a/crates/pumpkin/src/entity/mod.rs +++ b/crates/pumpkin/src/entity/mod.rs @@ -46,7 +46,7 @@ use pumpkin_protocol::{ }, move_player::CMovePlayer, set_actor_data::{ - CSetActorData, EntityMetadata, MetadataValue, PropertySyncData, entity_data_flag, + CSetActorData, MetadataValue, PropertySyncData, SyncedActorDataList, entity_data_flag, entity_data_key, }, }, @@ -221,7 +221,7 @@ pub trait EntityBase: Send + Sync + std::any::Any { let is_baby = entity.age.load(Ordering::Relaxed) < 0; if is_baby { - let mut bedrock_meta = EntityMetadata::new(); + let mut bedrock_meta = SyncedActorDataList::new(); bedrock_meta.set_flag(entity_data_key::FLAGS, entity_data_flag::BABY as u8, true); entity.send_meta_data( &[Metadata::new(tracked_data::ageable_mob::DATA_BABY_ID, true)], @@ -344,24 +344,23 @@ pub trait EntityBase: Send + Sync + std::any::Any { { metadata.0.extend(mob_metadata.0); } - let packet = CAddActor::new( - VarLong(runtime_id as i64), - VarULong(runtime_id), - identifier.to_string(), - entity.pos.load().to_f32_lossy(), - entity.velocity.load().to_f32_lossy(), - entity.pitch.load(), - entity.yaw.load(), - entity.head_yaw.load(), - entity.body_yaw.load(), - Vec::new(), - metadata, - PropertySyncData { - int_properties: std::collections::HashMap::new(), - float_properties: std::collections::HashMap::new(), + let packet = CAddActor { + target_actor_id: VarLong(runtime_id as i64), + target_runtime_id: VarULong(runtime_id), + actor_type: identifier.to_string(), + position: entity.pos.load().to_f32_lossy(), + velocity: entity.velocity.load().to_f32_lossy(), + rotation: Vector2::new(entity.pitch.load(), entity.yaw.load()), + y_head_rotation: entity.head_yaw.load(), + y_body_rotation: entity.body_yaw.load(), + attributes_list: Vec::new(), + actor_data: metadata, + synced_properties: PropertySyncData { + int_entries_list: std::collections::HashMap::new(), + float_entries_list: std::collections::HashMap::new(), }, - Vec::new(), - ); + actor_links: Vec::new(), + }; if let Ok(data) = client.serialize_packet(&packet) { client.send_game_packet(data).await; } @@ -1101,7 +1100,7 @@ impl Entity { self.world.store(world); } - pub fn bedrock_metadata(&self) -> EntityMetadata { + pub fn bedrock_metadata(&self) -> SyncedActorDataList { if self.bedrock_flags.load(Ordering::Relaxed) == 0 { self.bedrock_flags.fetch_or( (1i64 << entity_data_flag::HAS_GRAVITY) @@ -1112,7 +1111,7 @@ impl Entity { ); } - let mut metadata = EntityMetadata::new(); + let mut metadata = SyncedActorDataList::new(); metadata.set( entity_data_key::WIDTH, MetadataValue::Float(self.entity_type.dimension[0]), @@ -1124,11 +1123,11 @@ impl Entity { metadata.set(entity_data_key::SCALE, MetadataValue::Float(1.0)); metadata.set( entity_data_key::FLAGS, - MetadataValue::Long(self.bedrock_flags.load(Ordering::Relaxed)), + MetadataValue::Int64(self.bedrock_flags.load(Ordering::Relaxed)), ); metadata.set( entity_data_key::FLAGS_TWO, - MetadataValue::Long(self.bedrock_flags_two.load(Ordering::Relaxed)), + MetadataValue::Int64(self.bedrock_flags_two.load(Ordering::Relaxed)), ); if let Some(name) = &**self.custom_name.load() { @@ -1178,7 +1177,7 @@ impl Entity { /// Sets a custom name for the entity, typically used with nametags pub fn set_custom_name(&self, name: TextComponent) { self.custom_name.store(Arc::new(Some(name.clone()))); - let mut bedrock_meta = EntityMetadata::new(); + let mut bedrock_meta = SyncedActorDataList::new(); bedrock_meta.set( entity_data_key::NAME, MetadataValue::String(name.clone().get_text()), @@ -1205,7 +1204,7 @@ impl Entity { pub fn set_custom_name_visible(&self, visible: bool) { self.custom_name_visible.store(visible, Ordering::Relaxed); - let mut bedrock_meta = EntityMetadata::new(); + let mut bedrock_meta = SyncedActorDataList::new(); if let Some(name) = &**self.custom_name.load() { bedrock_meta.set( entity_data_key::NAME, @@ -1264,11 +1263,11 @@ impl Entity { self.world.load().broadcast_to_chunk_editioned_sync( chunk_pos, &CEntityVelocity::new(self.entity_id.into(), velocity), - &CSetActorMotion::new( - VarULong(self.entity_id as u64), - Vector3::new(velocity.x as f32, velocity.y as f32, velocity.z as f32), - VarULong(0), - ), + &CSetActorMotion { + target_runtime_id: VarULong(self.entity_id as u64), + motion: Vector3::new(velocity.x as f32, velocity.y as f32, velocity.z as f32), + tick: VarULong(0), + }, ); } @@ -2639,7 +2638,7 @@ impl Entity { // Only update and send metadata if the value changed if new_frozen_ticks != old_frozen_ticks { self.frozen_ticks.store(new_frozen_ticks, Ordering::Relaxed); - let mut bedrock_meta = EntityMetadata::new(); + let mut bedrock_meta = SyncedActorDataList::new(); bedrock_meta.set( entity_data_key::FREEZING_EFFECT_STRENGTH, MetadataValue::Float(new_frozen_ticks as f32), @@ -2971,21 +2970,21 @@ impl Entity { let world = self.world.load(); let chunk_pos = self.chunk_pos.load(); - let mut metadata = EntityMetadata(std::collections::HashMap::new()); + let mut metadata = SyncedActorDataList(std::collections::HashMap::new()); metadata.set( entity_data_key::FLAGS, - MetadataValue::Long(self.bedrock_flags.load(Ordering::Relaxed)), + MetadataValue::Int64(self.bedrock_flags.load(Ordering::Relaxed)), ); metadata.set( entity_data_key::FLAGS_TWO, - MetadataValue::Long(self.bedrock_flags_two.load(Ordering::Relaxed)), + MetadataValue::Int64(self.bedrock_flags_two.load(Ordering::Relaxed)), ); let packet = CSetActorData { - actor_runtime_id: VarULong(self.entity_id as u64), - metadata, + target_runtime_id: VarULong(self.entity_id as u64), + actor_data: metadata, synced_properties: PropertySyncData { - int_properties: std::collections::HashMap::new(), - float_properties: std::collections::HashMap::new(), + int_entries_list: std::collections::HashMap::new(), + float_entries_list: std::collections::HashMap::new(), }, tick: VarULong(0), }; @@ -3003,7 +3002,7 @@ impl Entity { pub fn send_meta_data( &self, meta: &[Metadata], - bedrock_meta: Option<&EntityMetadata>, + bedrock_meta: Option<&SyncedActorDataList>, ) { let world = self.world.load(); let chunk_pos = self.chunk_pos.load(); @@ -3046,11 +3045,11 @@ impl Entity { if let Some(bedrock_meta) = bedrock_meta { let packet = CSetActorData { - actor_runtime_id: VarULong(self.entity_id as u64), - metadata: EntityMetadata(bedrock_meta.0.clone()), + target_runtime_id: VarULong(self.entity_id as u64), + actor_data: SyncedActorDataList(bedrock_meta.0.clone()), synced_properties: PropertySyncData { - int_properties: std::collections::HashMap::new(), - float_properties: std::collections::HashMap::new(), + int_entries_list: std::collections::HashMap::new(), + float_entries_list: std::collections::HashMap::new(), }, tick: VarULong(0), }; @@ -3088,7 +3087,7 @@ impl Entity { self.bounding_box.store(aabb); self.entity_dimension.store(dimension); let pose = pose as i32; - let mut bedrock_meta = EntityMetadata::new(); + let mut bedrock_meta = SyncedActorDataList::new(); bedrock_meta.set(entity_data_key::POSE_INDEX, MetadataValue::Int(pose)); bedrock_meta.set( entity_data_key::WIDTH, @@ -3270,7 +3269,7 @@ impl Entity { true, ); let be_packet = pumpkin_protocol::bedrock::client::CSetActorLink { - link: pumpkin_protocol::bedrock::client::common::EntityLink { + link: pumpkin_protocol::bedrock::client::common::ActorLink { ridden_unique_id: pumpkin_protocol::codec::var_long::VarLong(self.entity_id as i64), rider_unique_id: pumpkin_protocol::codec::var_long::VarLong( holder_entity.entity_id as i64, @@ -3298,7 +3297,7 @@ impl Entity { let je_packet = pumpkin_protocol::java::client::play::CSetEntityLink::new(self.entity_id, -1, true); let be_packet = pumpkin_protocol::bedrock::client::CSetActorLink { - link: pumpkin_protocol::bedrock::client::common::EntityLink { + link: pumpkin_protocol::bedrock::client::common::ActorLink { ridden_unique_id: pumpkin_protocol::codec::var_long::VarLong(self.entity_id as i64), rider_unique_id: pumpkin_protocol::codec::var_long::VarLong(-1), link_type: 0, // Unlink diff --git a/crates/pumpkin/src/entity/passive/animal.rs b/crates/pumpkin/src/entity/passive/animal.rs index 455595813..181d1dcd6 100644 --- a/crates/pumpkin/src/entity/passive/animal.rs +++ b/crates/pumpkin/src/entity/passive/animal.rs @@ -5,7 +5,7 @@ use pumpkin_data::particle::Particle; use pumpkin_data::sound::{Sound, SoundCategory}; use crate::entity::{EntityBaseFuture, mob::Mob, player::Player}; -use pumpkin_protocol::bedrock::server::actor_event::ActorEventType; +use pumpkin_protocol::bedrock::server::actor_event::ActorEventID; use pumpkin_util::math::vector3::Vector3; pub trait Animal: Mob { @@ -62,7 +62,7 @@ pub trait Animal: Mob { world.send_entity_status( entity, pumpkin_data::entity::EntityStatus::InLoveHearts, - Some(ActorEventType::InLoveHearts), + Some(ActorEventID::InLoveHearts), ); world.spawn_particle( diff --git a/crates/pumpkin/src/entity/passive/cat.rs b/crates/pumpkin/src/entity/passive/cat.rs index 9cbe33785..f5b1034cd 100644 --- a/crates/pumpkin/src/entity/passive/cat.rs +++ b/crates/pumpkin/src/entity/passive/cat.rs @@ -8,7 +8,7 @@ use pumpkin_data::item::Item; use pumpkin_data::item_stack::ItemStack; use pumpkin_data::tag::{self, Taggable}; use pumpkin_nbt::compound::NbtCompound; -use pumpkin_protocol::bedrock::server::actor_event::ActorEventType; +use pumpkin_protocol::bedrock::server::actor_event::ActorEventID; use pumpkin_protocol::codec::var_int::VarInt; use pumpkin_protocol::java::client::play::Metadata; use rand::RngExt; @@ -485,13 +485,13 @@ impl Mob for CatEntity { self.get_entity().world.load().send_entity_status( self.get_entity(), EntityStatus::TamingSucceeded, - Some(ActorEventType::TamingSucceeded), + Some(ActorEventID::TamingSucceeded), ); } else { self.get_entity().world.load().send_entity_status( self.get_entity(), EntityStatus::TamingFailed, - Some(ActorEventType::TamingFailed), + Some(ActorEventID::TamingFailed), ); } diff --git a/crates/pumpkin/src/entity/passive/ocelot.rs b/crates/pumpkin/src/entity/passive/ocelot.rs index 961f2570a..84122e55a 100644 --- a/crates/pumpkin/src/entity/passive/ocelot.rs +++ b/crates/pumpkin/src/entity/passive/ocelot.rs @@ -8,7 +8,7 @@ use pumpkin_data::item::Item; use pumpkin_data::item_stack::ItemStack; use pumpkin_data::tag::{self, Taggable}; use pumpkin_nbt::compound::NbtCompound; -use pumpkin_protocol::bedrock::server::actor_event::ActorEventType; +use pumpkin_protocol::bedrock::server::actor_event::ActorEventID; use pumpkin_protocol::java::client::play::Metadata; use rand::RngExt; @@ -196,13 +196,13 @@ impl Mob for OcelotEntity { self.get_entity().world.load().send_entity_status( self.get_entity(), EntityStatus::TrustingSucceeded, - Some(ActorEventType::TamingSucceeded), + Some(ActorEventID::TamingSucceeded), ); } else { self.get_entity().world.load().send_entity_status( self.get_entity(), EntityStatus::TrustingFailed, - Some(ActorEventType::TamingFailed), + Some(ActorEventID::TamingFailed), ); } diff --git a/crates/pumpkin/src/entity/passive/villager/mod.rs b/crates/pumpkin/src/entity/passive/villager/mod.rs index 6e9b0d7cd..ee0d6eb31 100644 --- a/crates/pumpkin/src/entity/passive/villager/mod.rs +++ b/crates/pumpkin/src/entity/passive/villager/mod.rs @@ -22,8 +22,8 @@ use pumpkin_inventory::screen_handler::{ }; use pumpkin_nbt::compound::NbtCompound; use pumpkin_protocol::bedrock::{ - client::set_actor_data::{EntityMetadata, MetadataValue, entity_data_key}, - server::actor_event::ActorEventType, + client::set_actor_data::{MetadataValue, SyncedActorDataList, entity_data_key}, + server::actor_event::ActorEventID, }; use pumpkin_protocol::codec::var_int::VarInt; use pumpkin_protocol::java::client::play::{CMerchantOffers, Metadata}; @@ -283,11 +283,11 @@ pub struct VillagerEntity { } impl VillagerEntity { - fn bedrock_metadata(data: VillagerData, xp: i32) -> EntityMetadata { + fn bedrock_metadata(data: VillagerData, xp: i32) -> SyncedActorDataList { const PROFESSIONS: [i32; 15] = [0, 8, 11, 6, 7, 1, 2, 4, 12, 5, 13, 14, 3, 10, 9]; const REGIONS: [i32; 7] = [1, 2, 0, 3, 4, 5, 6]; - let mut metadata = EntityMetadata::new(); + let mut metadata = SyncedActorDataList::new(); metadata.set( entity_data_key::VARIANT, MetadataValue::Int( @@ -1131,7 +1131,7 @@ impl VillagerEntity { world.send_entity_status( self.get_entity(), pumpkin_data::entity::EntityStatus::VillagerHappy, - Some(ActorEventType::VillagerHappy), + Some(ActorEventID::VillagerHappy), ); self.job_site_pending.store(false, Ordering::Relaxed); if profession == VillagerProfession::None { @@ -1156,7 +1156,7 @@ impl VillagerEntity { entity.world.load().send_entity_status( entity, pumpkin_data::entity::EntityStatus::VillagerAngry, - Some(ActorEventType::VillagerAngry), + Some(ActorEventID::VillagerAngry), ); entity.play_sound(pumpkin_data::sound::Sound::EntityVillagerNo); } @@ -1727,7 +1727,7 @@ impl Mob for VillagerEntity { fn mob_bedrock_spawn_metadata( &self, - ) -> crate::entity::EntityBaseFuture<'_, Option> { + ) -> crate::entity::EntityBaseFuture<'_, Option> { Box::pin(async move { Some(Self::bedrock_metadata( *self.villager_data.lock().await, @@ -1833,7 +1833,7 @@ impl Mob for VillagerEntity { self.get_entity().world.load().send_entity_status( self.get_entity(), pumpkin_data::entity::EntityStatus::VillagerAngry, - Some(ActorEventType::VillagerAngry), + Some(ActorEventID::VillagerAngry), ); }) } @@ -1878,7 +1878,7 @@ impl Mob for VillagerEntity { world.send_entity_status( self.get_entity(), pumpkin_data::entity::EntityStatus::VillagerHappy, - Some(ActorEventType::VillagerHappy), + Some(ActorEventID::VillagerHappy), ); } diff --git a/crates/pumpkin/src/entity/player.rs b/crates/pumpkin/src/entity/player.rs index ef3190186..b8f403d50 100644 --- a/crates/pumpkin/src/entity/player.rs +++ b/crates/pumpkin/src/entity/player.rs @@ -23,13 +23,19 @@ use pumpkin_protocol::bedrock::client::play_status::CPlayStatus; use pumpkin_protocol::bedrock::client::set_time::CSetTime; use pumpkin_protocol::bedrock::client::update_abilities::{Ability, CUpdateAbilities}; use pumpkin_protocol::bedrock::client::{ - AbilityLayer, + CommandPermissionLevel, PlayerPermissionLevel, SerializedAbilitiesData, +}; +use pumpkin_protocol::bedrock::client::{ + SerializedAbilitiesDataSerializedLayer, move_player::CMovePlayer as CBedrockMovePlayer, - respawn::CRespawn as CBedrockRespawn, - update_attributes::{Attribute as BedrockAttribute, CUpdateAttributes as CBedrockAttributes}, + update_attributes::{ + AttributeData as BedrockAttribute, CUpdateAttributes as CBedrockAttributes, + }, +}; +use pumpkin_protocol::bedrock::server::{ + respawn::{RespawnState, SRespawn as SBedrockRespawn}, + text::SText, }; -use pumpkin_protocol::bedrock::respawn::RespawnState; -use pumpkin_protocol::bedrock::server::text::SText; use pumpkin_protocol::codec::item_stack_seralizer::ItemStackSerializer; use pumpkin_util::translation::Locale; use pumpkin_util::version::JavaMinecraftVersion; @@ -229,7 +235,7 @@ use pumpkin_nbt::tag::NbtTag; use pumpkin_protocol::IdOr; use pumpkin_protocol::SoundEvent; use pumpkin_protocol::bedrock::client::container_open::CContainerOpen; -use pumpkin_protocol::bedrock::server::actor_event::{ActorEventType, SActorEvent}; +use pumpkin_protocol::bedrock::server::actor_event::{ActorEventID, SActorEvent}; use pumpkin_protocol::codec::var_int::VarInt; use pumpkin_protocol::codec::var_long::VarLong; use pumpkin_protocol::codec::var_ulong::VarULong; @@ -1745,12 +1751,13 @@ impl Player { pitch, dimension.minecraft_name.to_owned(), ), - &pumpkin_protocol::bedrock::client::CSetSpawnPosition::new( - 0, // Player spawn - block_pos, - bedrock_dimension, - block_pos, - ), + &pumpkin_protocol::bedrock::client::CSetSpawnPosition { + spawn_position_type: + pumpkin_protocol::bedrock::client::SpawnPositionType::PlayerRespawn, + block_position: block_pos, + dimension_type: bedrock_dimension.into(), + spawn_block_pos: block_pos, + }, ) .await; @@ -2223,7 +2230,7 @@ impl Player { .enqueue_packet_editioned( &CTitleText::new(text), &pumpkin_protocol::bedrock::client::set_title::CSetTitle::new( - 2, + pumpkin_protocol::bedrock::client::TitleType::Title, text.clone().get_text(), 0, 0, @@ -2237,7 +2244,7 @@ impl Player { .enqueue_packet_editioned( &CSubtitle::new(text), &pumpkin_protocol::bedrock::client::set_title::CSetTitle::new( - 3, + pumpkin_protocol::bedrock::client::TitleType::Subtitle, text.clone().get_text(), 0, 0, @@ -2251,7 +2258,7 @@ impl Player { .enqueue_packet_editioned( &CActionBar::new(text), &pumpkin_protocol::bedrock::client::set_title::CSetTitle::new( - 4, + pumpkin_protocol::bedrock::client::TitleType::Actionbar, text.clone().get_text(), 0, 0, @@ -2267,7 +2274,7 @@ impl Player { self.enqueue_packet_editioned( &CTitleAnimation::new(fade_in, stay, fade_out), &pumpkin_protocol::bedrock::client::set_title::CSetTitle::new( - 5, + pumpkin_protocol::bedrock::client::TitleType::Times, String::new(), fade_in, stay, @@ -2769,8 +2776,16 @@ impl Player { let is_spectator = self.gamemode.load() == GameMode::Spectator; // 1. Permission Mapping - let player_perm = if is_op { 2 } else { 1 }; // 1: Member, 2: Operator - let command_perm = u8::from(is_op); // 0: Normal, 1: Operator + let player_perm = if is_op { + PlayerPermissionLevel::Operator + } else { + PlayerPermissionLevel::Member + }; + let command_perm = if is_op { + CommandPermissionLevel::GameDirectors + } else { + CommandPermissionLevel::Any + }; // 2. Build the Ability Bitmask let mut ability_value: u32 = 0; @@ -2808,7 +2823,7 @@ impl Player { set_ability(Ability::NoClip, is_spectator); // 3. Construct the Layers - let mut layers = vec![AbilityLayer { + let mut layers = vec![SerializedAbilitiesDataSerializedLayer { serialized_layer: 0, // LAYER_BASE // 0x3FFFF defines the first 18 bits as "provided" by this packet abilities_set: (1 << Ability::AbilityCount as u32) - 1, @@ -2819,7 +2834,7 @@ impl Player { }]; if is_spectator { - layers.push(AbilityLayer { + layers.push(SerializedAbilitiesDataSerializedLayer { serialized_layer: 1, abilities_set: 1 << (Ability::Flying as u32), ability_value: 1 << (Ability::Flying as u32), @@ -2830,10 +2845,12 @@ impl Player { } let packet = CUpdateAbilities { - target_player_raw_id: self.entity_id().into(), - player_permission: player_perm, - command_permission: command_perm, - layers, + data: SerializedAbilitiesData { + target_player_raw_id: self.entity_id().into(), + player_permissions: player_perm, + command_permissions: command_perm, + layers, + }, }; if let Ok(data) = bedrock.serialize_packet(&packet) { @@ -3000,9 +3017,9 @@ impl Player { self.client .enqueue_packet_editioned( &CChangeDifficulty::new(level_info.difficulty as u8, level_info.difficulty_locked), - &pumpkin_protocol::bedrock::client::CSetDifficulty::new( - level_info.difficulty as u32, - ), + &pumpkin_protocol::bedrock::client::CSetDifficulty { + difficulty: (level_info.difficulty as u32).into(), + }, ) .await; } @@ -3461,11 +3478,12 @@ impl Player { 0 }; let pos_f32 = Vector3::new(position.x as f32, position.y as f32, position.z as f32); - let change_dim_packet = pumpkin_protocol::bedrock::client::CChangeDimension::new( - bedrock_dimension, - pos_f32, - false, - ); + let change_dim_packet = pumpkin_protocol::bedrock::client::CChangeDimension { + dimension_id: bedrock_dimension.into(), + position: pos_f32, + respawn: false, + loading_screen_id: None + }; if let Ok(data) = bedrock.serialize_packet(&change_dim_packet) { bedrock.enqueue_packet(data).await; } @@ -3719,7 +3737,7 @@ impl Player { default_max_value: max_value, default_value, name: name.to_string(), - modifiers_list_size: pumpkin_protocol::codec::var_uint::VarUInt(0), + modifiers: Vec::new(), }; self.enqueue_packet_editioned( @@ -3729,8 +3747,8 @@ impl Player { self.hunger_manager.saturation.load(), ), &CBedrockAttributes { - runtime_id: VarULong(self.entity_id() as u64), - attributes: vec![ + target_runtime_id: VarULong(self.entity_id() as u64), + attribute_list: vec![ attribute( "minecraft:health", self.living_entity.health.load(), @@ -3750,7 +3768,7 @@ impl Player { 5.0, ), ], - player_tick: VarULong(self.tick_counter.load(Ordering::Relaxed).max(0) as u64), + tick: VarULong(self.tick_counter.load(Ordering::Relaxed).max(0) as u64), }, ) .await; @@ -3761,15 +3779,15 @@ impl Player { let entity = self.get_entity(); let position = entity.pos.load(); client - .send_packet(&CBedrockRespawn::new( - Vector3::new( + .send_packet(&SBedrockRespawn { + position: Vector3::new( position.x as f32, position.y as f32 + entity.entity_type.eye_height, position.z as f32, ), state, - VarULong(self.entity_id() as u64), - )) + player_runtime_id: VarULong(self.entity_id() as u64), + }) .await; } } @@ -4093,9 +4111,9 @@ impl Player { .send_packet_now_editioned( &CCombatDeath::new(self.entity_id().into(), &death_msg), &SActorEvent { - entity_runtime_id: VarULong(self.entity_id() as u64), - event_type: ActorEventType::Death, - event_data: VarInt(0), + target_runtime_id: VarULong(self.entity_id() as u64), + event_id: ActorEventID::Death, + data: VarInt(0), fire_at_position: None, }, ) @@ -4184,8 +4202,8 @@ impl Player { self.client .enqueue_packet_editioned( &CGameEvent::new(GameEvent::ChangeGameMode, gamemode as i32 as f32), - &pumpkin_protocol::bedrock::client::set_player_gamemode::CSetPlayerGamemode { - gamemode, + &pumpkin_protocol::bedrock::client::set_player_gamemode::CSetPlayerGameType { + player_game_type: gamemode.into(), }, ) .await; @@ -4837,7 +4855,7 @@ impl Player { &pumpkin_protocol::bedrock::server::container_close::SContainerClose { container_id: sync_id, container_type: bedrock_window_type, - server_initiated: true, + server_initiated_close: true, }, ) .await; @@ -5462,7 +5480,7 @@ impl Player { let be_packet = pumpkin_protocol::bedrock::server::animate::SAnimate { action: pumpkin_protocol::bedrock::server::animate::AnimateAction::SwingArm, - runtime_entity_id: pumpkin_protocol::codec::var_ulong::VarULong(entity_id as u64), + target_actor_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong(entity_id as u64), data: 0.0, swing_source: None, }; @@ -6801,13 +6819,13 @@ impl InventoryPlayer for Player { if let Some(slot_idx) = bedrock_inventory_slot(packet.slot) { let item_desc = NetworkItemStackDescriptor::from(&*packet.slot_data.0); let bedrock_packet = CInventorySlot { - window_id: VarUInt(0), - inventory_slot: VarUInt(slot_idx), - container_name: Some(FullContainerName { + container_id: VarUInt(0), + slot: VarUInt(slot_idx), + full_container_name: Some(FullContainerName { container_name: ContainerName::Inventory, dynamic_id: None, }), - storage: None, + storage_item: None, item: item_desc, }; if let Ok(data) = bedrock.serialize_packet(&bedrock_packet) { @@ -6847,13 +6865,13 @@ impl InventoryPlayer for Player { if let Some((container_name, slot_id)) = bedrock_info { let bedrock_packet = CInventorySlot { - window_id: VarUInt(window_id as u32), - inventory_slot: VarUInt(slot_id as u32), - container_name: Some(FullContainerName { + container_id: VarUInt(window_id as u32), + slot: VarUInt(slot_id as u32), + full_container_name: Some(FullContainerName { container_name, dynamic_id: None, }), - storage: None, + storage_item: None, item: item_desc, }; if let Ok(data) = bedrock.serialize_packet(&bedrock_packet) { @@ -6938,13 +6956,13 @@ impl InventoryPlayer for Player { let item_stack = &*packet.item.0; let item_desc = NetworkItemStackDescriptor::from(item_stack); let bedrock_packet = CInventorySlot { - window_id: VarUInt(0), - inventory_slot: VarUInt(packet.slot.0 as u32), - container_name: Some(FullContainerName { + container_id: VarUInt(0), + slot: VarUInt(packet.slot.0 as u32), + full_container_name: Some(FullContainerName { container_name: ContainerName::Inventory, dynamic_id: None, }), - storage: None, + storage_item: None, item: item_desc, }; if let Ok(data) = bedrock.serialize_packet(&bedrock_packet) { @@ -6968,7 +6986,7 @@ impl InventoryPlayer for Player { packet.slot as u32, ), container_id: 0, - should_select_block: true, + should_select_slot: true, }, ) .await; diff --git a/crates/pumpkin/src/entity/projectile/egg.rs b/crates/pumpkin/src/entity/projectile/egg.rs index c6326d05c..2e3ed01f0 100644 --- a/crates/pumpkin/src/entity/projectile/egg.rs +++ b/crates/pumpkin/src/entity/projectile/egg.rs @@ -11,7 +11,7 @@ use crate::{ use pumpkin_data::entity::{EntityStatus, EntityType}; use pumpkin_data::item::Item; use pumpkin_data::item_stack::ItemStack; -use pumpkin_protocol::bedrock::server::actor_event::ActorEventType; +use pumpkin_protocol::bedrock::server::actor_event::ActorEventID; use pumpkin_protocol::codec::item_stack_seralizer::ItemStackSerializer; use pumpkin_protocol::java::client::play::Metadata; use pumpkin_util::math::vector3::Vector3; @@ -107,7 +107,7 @@ impl EntityBase for EggEntity { world.send_entity_status( self.get_entity(), EntityStatus::Death, - Some(ActorEventType::Death), + Some(ActorEventID::Death), ); // Decide spawn count per probabilities: diff --git a/crates/pumpkin/src/entity/projectile/ender_pearl.rs b/crates/pumpkin/src/entity/projectile/ender_pearl.rs index 041f783f8..3c87d9793 100644 --- a/crates/pumpkin/src/entity/projectile/ender_pearl.rs +++ b/crates/pumpkin/src/entity/projectile/ender_pearl.rs @@ -13,7 +13,7 @@ use pumpkin_data::damage::DamageType; use pumpkin_data::entity::{EntityPose, EntityStatus}; use pumpkin_data::particle::Particle; use pumpkin_data::sound::{Sound, SoundCategory}; -use pumpkin_protocol::bedrock::server::actor_event::ActorEventType; +use pumpkin_protocol::bedrock::server::actor_event::ActorEventID; use pumpkin_util::math::vector3::Vector3; const GRAVITY: f64 = 0.03; @@ -171,7 +171,7 @@ impl EntityBase for EnderPearlEntity { .await; } - world.send_entity_status(entity, EntityStatus::Death, Some(ActorEventType::Death)); + world.send_entity_status(entity, EntityStatus::Death, Some(ActorEventID::Death)); }) } } diff --git a/crates/pumpkin/src/entity/projectile/firework_rocket.rs b/crates/pumpkin/src/entity/projectile/firework_rocket.rs index 698bd7286..1ad6b4c00 100644 --- a/crates/pumpkin/src/entity/projectile/firework_rocket.rs +++ b/crates/pumpkin/src/entity/projectile/firework_rocket.rs @@ -4,7 +4,7 @@ use crate::{ world::World, }; use pumpkin_data::entity::EntityStatus; -use pumpkin_protocol::bedrock::server::actor_event::ActorEventType; +use pumpkin_protocol::bedrock::server::actor_event::ActorEventID; use pumpkin_protocol::{codec::optional_int::OptionalInt, java::client::play::Metadata}; use pumpkin_util::{ math::vector3::Vector3, @@ -85,7 +85,7 @@ impl FireworkRocketEntity { world.send_entity_status( entity, EntityStatus::FireworksExplode, - Some(ActorEventType::FireworksExplode), + Some(ActorEventID::FireworksExplode), ); // TODO: Explode/colors diff --git a/crates/pumpkin/src/entity/projectile/lingering_potion.rs b/crates/pumpkin/src/entity/projectile/lingering_potion.rs index b663d0c0d..5657c03b8 100644 --- a/crates/pumpkin/src/entity/projectile/lingering_potion.rs +++ b/crates/pumpkin/src/entity/projectile/lingering_potion.rs @@ -8,7 +8,7 @@ use crate::{ }; use pumpkin_data::entity::EntityStatus; use pumpkin_data::item_stack::ItemStack; -use pumpkin_protocol::bedrock::server::actor_event::ActorEventType; +use pumpkin_protocol::bedrock::server::actor_event::ActorEventID; use pumpkin_protocol::java::client::play::CWorldEvent; use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::vector2::{Vector2, to_chunk_pos}; @@ -112,7 +112,7 @@ impl EntityBase for LingeringPotionEntity { world.send_entity_status( self.get_entity(), EntityStatus::Death, - Some(ActorEventType::Death), + Some(ActorEventID::Death), ); // Read stored item stack and compute potion effects diff --git a/crates/pumpkin/src/entity/projectile/snowball.rs b/crates/pumpkin/src/entity/projectile/snowball.rs index 0a070d570..ecc3da48f 100644 --- a/crates/pumpkin/src/entity/projectile/snowball.rs +++ b/crates/pumpkin/src/entity/projectile/snowball.rs @@ -8,7 +8,7 @@ use crate::{ }; use pumpkin_data::damage::DamageType; use pumpkin_data::entity::{EntityStatus, EntityType}; -use pumpkin_protocol::bedrock::server::actor_event::ActorEventType; +use pumpkin_protocol::bedrock::server::actor_event::ActorEventID; use pumpkin_util::math::vector3::Vector3; const GRAVITY: f64 = 0.03; @@ -69,7 +69,7 @@ impl EntityBase for SnowballEntity { world.send_entity_status( self.get_entity(), EntityStatus::Death, - Some(ActorEventType::Death), + Some(ActorEventID::Death), ); // Handle entity-specific damage diff --git a/crates/pumpkin/src/entity/vehicle/minecart/tnt.rs b/crates/pumpkin/src/entity/vehicle/minecart/tnt.rs index d231c4111..c65c44476 100644 --- a/crates/pumpkin/src/entity/vehicle/minecart/tnt.rs +++ b/crates/pumpkin/src/entity/vehicle/minecart/tnt.rs @@ -5,7 +5,7 @@ use pumpkin_data::entity::EntityStatus; use pumpkin_data::particle::Particle; use pumpkin_data::sound::{Sound, SoundCategory}; use pumpkin_nbt::compound::NbtCompound; -use pumpkin_protocol::bedrock::server::actor_event::ActorEventType; +use pumpkin_protocol::bedrock::server::actor_event::ActorEventID; use pumpkin_util::math::vector3::Vector3; use rand::RngExt; @@ -44,7 +44,7 @@ impl TntMinecart { world.send_entity_status( entity, EntityStatus::TntPrime, - Some(ActorEventType::CartWithPrimeTNT), + Some(ActorEventID::PrimeTNTCart), ); world.play_sound( Sound::EntityTntPrimed, diff --git a/crates/pumpkin/src/net/bedrock/login/login.rs b/crates/pumpkin/src/net/bedrock/login/login.rs index f0dd32372..652224495 100644 --- a/crates/pumpkin/src/net/bedrock/login/login.rs +++ b/crates/pumpkin/src/net/bedrock/login/login.rs @@ -1,3 +1,5 @@ +use pumpkin_protocol::bedrock::client::PackIdVersion; + #[allow(clippy::wildcard_imports)] use super::*; @@ -86,17 +88,16 @@ impl BedrockClient { let mut entries = Vec::new(); if br_config.enabled { for pack in &br_config.packs { - entries.push(ResourcePackEntry { - uuid: pack.uuid, - version: pack.version.clone(), - size: pack.size, - download_url: pack.download_url.clone(), + entries.push(PackInfoData { + pack_id_version: PackIdVersion::new(pack.uuid, pack.version.clone()), + pack_size: pack.size, + cdn_url: pack.download_url.clone(), content_key: pack.content_key.clone(), - sub_pack_name: pack.sub_pack_name.clone(), - content_id: pack.content_id.clone(), + subpack_name: pack.sub_pack_name.clone(), + content_identity: pack.content_id.clone(), has_scripts: pack.has_scripts, - addon_pack: pack.addon_pack, - rtx_enabled: pack.rtx_enabled, + is_addon_pack: pack.addon_pack, + is_ray_tracing_capable: pack.rtx_enabled, }); } } @@ -105,9 +106,8 @@ impl BedrockClient { resource_pack_required: br_config.force, has_addon_packs: false, has_scripts: false, - is_vibrant_visuals_force_disabled: false, - world_template_id: uuid::Uuid::nil(), - world_template_version: String::new(), + force_disable_vibrant_visuals: false, + world_template_id_and_version: PackIdVersion::new(uuid::Uuid::nil(), String::new()), resource_packs: entries, }; self.enqueue_client_packet(&packs_info).await; diff --git a/crates/pumpkin/src/net/bedrock/login/mod.rs b/crates/pumpkin/src/net/bedrock/login/mod.rs index 3046fd282..1951158c1 100644 --- a/crates/pumpkin/src/net/bedrock/login/mod.rs +++ b/crates/pumpkin/src/net/bedrock/login/mod.rs @@ -14,8 +14,8 @@ use pumpkin_protocol::bedrock::{ server::{login::SLogin, request_network_settings::SRequestNetworkSettings}, }; use pumpkin_protocol::bedrock::{ - client::{resource_pack_stack::ResourcePackStackEntry, resource_packs_info::ResourcePackEntry}, - server::{login::ClientData, resource_pack_response::SResourcePackResponse}, + client::{resource_pack_stack::PackInstanceId, resource_packs_info::PackInfoData}, + server::{login::ClientData, resource_pack_client_response::SResourcePackClientResponse}, }; use pumpkin_util::jwt::AuthError; use pumpkin_util::version::BedrockMinecraftVersion; diff --git a/crates/pumpkin/src/net/bedrock/login/request_network_settings.rs b/crates/pumpkin/src/net/bedrock/login/request_network_settings.rs index 875d9a1ee..aa90cda90 100644 --- a/crates/pumpkin/src/net/bedrock/login/request_network_settings.rs +++ b/crates/pumpkin/src/net/bedrock/login/request_network_settings.rs @@ -8,7 +8,7 @@ impl BedrockClient { server: &Server, ) -> bool { let status = match packet - .protocol_version + .client_network_version .cmp(&(CURRENT_BEDROCK_MC_PROTOCOL as i32)) { std::cmp::Ordering::Less => Some(CPlayStatus::OutdatedClient), @@ -22,7 +22,7 @@ impl BedrockClient { } self.version.store(BedrockMinecraftVersion::from_protocol( - packet.protocol_version as u32, + packet.client_network_version as u32, )); let compression = server @@ -32,13 +32,14 @@ impl BedrockClient { .compression .info .clone(); - self.send_packet(&CNetworkSettings::new( - compression.threshold as u16, - 0, - false, - 0, - 0.0, - )) + + self.send_packet(&CNetworkSettings { + compression_threshold: compression.threshold as u16, + compression_algorithm: 0, + client_throttle_enabled: false, + client_throttle_threshold: 0, + client_throttle_scalar: 0.0, + }) .await; self.set_compression(compression).await; true diff --git a/crates/pumpkin/src/net/bedrock/login/resource_pack_response.rs b/crates/pumpkin/src/net/bedrock/login/resource_pack_response.rs index 81b37332c..1071e4acf 100644 --- a/crates/pumpkin/src/net/bedrock/login/resource_pack_response.rs +++ b/crates/pumpkin/src/net/bedrock/login/resource_pack_response.rs @@ -4,13 +4,13 @@ use super::*; impl BedrockClient { pub async fn handle_resource_pack_response( &self, - packet: SResourcePackResponse, + packet: SResourcePackClientResponse, server: &Arc, ) { // TODO: warn & ignore if the player is already spawned in match packet.response { - SResourcePackResponse::STATUS_REFUSED => { + SResourcePackClientResponse::STATUS_REFUSED => { debug!("Bedrock: SResourcePackResponse::STATUS_REFUSED"); self.kick( DisconnectReason::ResourcePackProblem, @@ -18,11 +18,11 @@ impl BedrockClient { ) .await; } - SResourcePackResponse::STATUS_SEND_PACKS => { + SResourcePackClientResponse::STATUS_SEND_PACKS => { debug!("Bedrock: SResourcePackResponse::STATUS_SEND_PACKS"); // TODO: send packs } - SResourcePackResponse::STATUS_HAVE_ALL_PACKS => { + SResourcePackClientResponse::STATUS_HAVE_ALL_PACKS => { debug!("Bedrock: SResourcePackResponse::STATUS_HAVE_ALL_PACKS"); let br_config = &server.advanced_config.resource_pack.bedrock; // Convert your config packs into protocol stack entries @@ -30,8 +30,8 @@ impl BedrockClient { br_config .packs .iter() - .map(|pack| ResourcePackStackEntry { - uuid: pack.uuid.to_string(), + .map(|pack| PackInstanceId { + pack_id: pack.uuid.to_string(), version: pack.version.clone(), sub_pack_name: String::new(), }) @@ -40,19 +40,19 @@ impl BedrockClient { Vec::new() }; - self.enqueue_client_packet(&CResourcePackStackPacket::new( - br_config.force, - resource_packs, - CURRENT_BEDROCK_MC_VERSION.to_string(), - Experiments { - names_size: 0, + self.enqueue_client_packet(&CResourcePackStackPacket { + texture_pack_required: br_config.force, + texture_pack_list: resource_packs, + base_game_version: CURRENT_BEDROCK_MC_VERSION.to_string(), + experiments: Experiments { + toggles: Vec::new(), experiments_ever_toggled: false, }, - false, - )) + include_editor_packs: false, + }) .await; } - SResourcePackResponse::STATUS_COMPLETED => { + SResourcePackClientResponse::STATUS_COMPLETED => { debug!("Bedrock: SResourcePackResponse::STATUS_COMPLETED"); let player = self.player.load_full(); if let Some(player) = player.as_ref() { diff --git a/crates/pumpkin/src/net/bedrock/mod.rs b/crates/pumpkin/src/net/bedrock/mod.rs index d39973b82..4ef104738 100644 --- a/crates/pumpkin/src/net/bedrock/mod.rs +++ b/crates/pumpkin/src/net/bedrock/mod.rs @@ -21,8 +21,8 @@ use pumpkin_protocol::{ bedrock::{ BEDROCK_GAME_PACKET, SubClient, client::{ - client_cache_miss_response::{CClientCacheMissResponse, CacheBlob}, - disconnect_player::CDisconnectPlayer, + client_cache_miss_response::{CClientCacheMissResponse, MissingBlobData}, + disconnect::CDisconnect, level_chunk::CLevelChunk, }, packet_decoder::BedrockBatchDecoder, @@ -32,13 +32,13 @@ use pumpkin_protocol::{ client_cache_blob_status::SClientCacheBlobStatus, client_cache_status::SClientCacheStatus, command_request::SCommandRequest, container_close::SContainerClose, emote::SEmote, emote_list::SEmoteList, - interaction::SInteraction, inventory_transaction::SInventoryTransaction, + interact::SInteract, inventory_transaction::SInventoryTransaction, loading_screen::SLoadingScreen, login::SLogin, mob_equipment::SMobEquipment, packet_violation_warning::SPacketViolationWarning, player_action::SPlayerAction, player_auth_input::SPlayerAuthInput, request_ability::SRequestAbility, request_chunk_radius::SRequestChunkRadius, request_network_settings::SRequestNetworkSettings, - resource_pack_response::SResourcePackResponse, respawn::SRespawn, + resource_pack_client_response::SResourcePackClientResponse, respawn::SRespawn, set_local_player_as_initialized::SSetLocalPlayerAsInitialized, set_player_inventory_options::SSetPlayerInventoryOptions, text::SText, }, @@ -270,7 +270,7 @@ impl BedrockClient { } pub async fn kick(&self, reason: DisconnectReason, message: String) { - self.send_packet(&CDisconnectPlayer::new(reason as i32, message)) + self.send_packet(&CDisconnect::new(reason as i32, message)) .await; self.close().await; } @@ -284,7 +284,7 @@ impl BedrockClient { send_packet: bool, ) { if send_packet { - self.send_packet(&CDisconnectPlayer { + self.send_packet(&CDisconnect { reason: pumpkin_protocol::codec::var_int::VarInt(reason as i32), skip_message, message, @@ -664,14 +664,14 @@ impl BedrockClient { SClientCacheStatus::PACKET_ID => { let packet = SClientCacheStatus::read(reader)?; self.client_cache_supported - .store(packet.cache_supported, Ordering::Relaxed); + .store(packet.is_cache_supported, Ordering::Relaxed); } SClientCacheBlobStatus::PACKET_ID => { self.handle_client_cache_blob_status(SClientCacheBlobStatus::read(reader)?) .await; } - SResourcePackResponse::PACKET_ID => { - self.handle_resource_pack_response(SResourcePackResponse::read(reader)?, server) + SResourcePackClientResponse::PACKET_ID => { + self.handle_resource_pack_response(SResourcePackClientResponse::read(reader)?, server) .await; } SPlayerAuthInput::PACKET_ID => { @@ -688,8 +688,8 @@ impl BedrockClient { pumpkin_protocol::bedrock::server::item_stack_request::SItemStackRequest::PACKET_ID => { self.handle_item_stack_request(player, pumpkin_protocol::bedrock::server::item_stack_request::SItemStackRequest::read(reader)?).await; } - SInteraction::PACKET_ID => { - self.handle_interaction(player, SInteraction::read(reader)?, server) + SInteract::PACKET_ID => { + self.handle_interaction(player, SInteract::read(reader)?, server) .await; } SContainerClose::PACKET_ID => { @@ -762,9 +762,9 @@ impl BedrockClient { let warning = SPacketViolationWarning::read(reader)?; warn!( violation_type = warning.violation_type.0, - severity = warning.severity.0, - packet_id = warning.packet_id.0, - context = %warning.context, + violation_severity = warning.violation_severity.0, + violation_packet_id = warning.violation_packet_id.0, + violation_context = %warning.violation_context, "Bedrock client rejected a server packet" ); } @@ -784,9 +784,9 @@ impl BedrockClient { let mut missing_blobs = Vec::with_capacity(packet.miss_hashes.len()); for hash in packet.miss_hashes { if let Some(payload) = cache.get(&hash) { - missing_blobs.push(CacheBlob { - hash, - payload: payload.clone(), + missing_blobs.push(MissingBlobData { + blob_id: hash, + blob_data: payload.clone(), }); } else { warn!("Client requested missing blob {hash:#x} not found in server cache"); @@ -795,10 +795,8 @@ impl BedrockClient { missing_blobs }; if !missing_blobs.is_empty() { - self.send_packet(&CClientCacheMissResponse { - blobs: &missing_blobs, - }) - .await; + self.send_packet(&CClientCacheMissResponse { missing_blobs }) + .await; } } diff --git a/crates/pumpkin/src/net/bedrock/play/actor_event.rs b/crates/pumpkin/src/net/bedrock/play/actor_event.rs index 90968d401..117e87f44 100644 --- a/crates/pumpkin/src/net/bedrock/play/actor_event.rs +++ b/crates/pumpkin/src/net/bedrock/play/actor_event.rs @@ -3,7 +3,7 @@ use super::*; impl BedrockClient { pub async fn handle_actor_event(&self, player: &Player, packet: SActorEvent) { - if packet.event_type != ActorEventType::Feed + if packet.event_id != ActorEventID::Feed || !player .living_entity .item_in_use @@ -20,9 +20,9 @@ impl BedrockClient { entity.world.load().broadcast_to_chunk_bedrock( entity.chunk_pos.load(), &SActorEvent { - entity_runtime_id: VarULong(entity.entity_id as u64), - event_type: ActorEventType::Feed, - event_data: packet.event_data, + target_runtime_id: VarULong(entity.entity_id as u64), + event_id: ActorEventID::Feed, + data: packet.data, fire_at_position: None, }, ); diff --git a/crates/pumpkin/src/net/bedrock/play/animate.rs b/crates/pumpkin/src/net/bedrock/play/animate.rs index 039e5c725..34b554697 100644 --- a/crates/pumpkin/src/net/bedrock/play/animate.rs +++ b/crates/pumpkin/src/net/bedrock/play/animate.rs @@ -22,7 +22,7 @@ impl BedrockClient { let je_packet = CEntityAnimation::new(VarInt(entity.entity_id), animation); let be_packet = SAnimate { action: packet.action, - runtime_entity_id: VarULong(entity.entity_id as u64), + target_actor_runtime_id: VarULong(entity.entity_id as u64), data: 0.0, swing_source: None, }; diff --git a/crates/pumpkin/src/net/bedrock/play/block_pick_request.rs b/crates/pumpkin/src/net/bedrock/play/block_pick_request.rs index df816a249..ba546188d 100644 --- a/crates/pumpkin/src/net/bedrock/play/block_pick_request.rs +++ b/crates/pumpkin/src/net/bedrock/play/block_pick_request.rs @@ -4,12 +4,12 @@ use super::*; impl BedrockClient { #[allow(clippy::too_many_lines)] pub async fn handle_block_pick_request(&self, player: &Arc, packet: SBlockPickRequest) { - if !player.can_interact_with_block_at(&packet.block_pos, 1.0) { + if !player.can_interact_with_block_at(&packet.position, 1.0) { return; } let world = player.world(); - let block = world.get_block(&packet.block_pos); + let block = world.get_block(&packet.position); if block.item_id == 0 { return; @@ -20,7 +20,7 @@ impl BedrockClient { }; let stack = ItemStack::new(1, item); - let target_hotbar_slot = packet.hotbar_slot as usize; + let target_hotbar_slot = packet.max_slots as usize; if target_hotbar_slot >= 9 { return; } @@ -71,7 +71,7 @@ impl BedrockClient { &CPlayerHotbar { selected_slot: VarUInt(player.inventory.get_selected_slot() as u32), container_id: 0, - should_select_block: true, + should_select_slot: true, }, ) .await; diff --git a/crates/pumpkin/src/net/bedrock/play/container_close.rs b/crates/pumpkin/src/net/bedrock/play/container_close.rs index 24c27b2c0..d23efcd4f 100644 --- a/crates/pumpkin/src/net/bedrock/play/container_close.rs +++ b/crates/pumpkin/src/net/bedrock/play/container_close.rs @@ -11,7 +11,7 @@ impl BedrockClient { self.enqueue_client_packet(&SContainerClose { container_id: packet.container_id, container_type: packet.container_type, - server_initiated: false, + server_initiated_close: false, }) .await; diff --git a/crates/pumpkin/src/net/bedrock/play/emote.rs b/crates/pumpkin/src/net/bedrock/play/emote.rs index 351e322cb..8256c6865 100644 --- a/crates/pumpkin/src/net/bedrock/play/emote.rs +++ b/crates/pumpkin/src/net/bedrock/play/emote.rs @@ -17,7 +17,7 @@ impl BedrockClient { let world = entity.world.load(); let mut broadcast_packet = packet; - broadcast_packet.runtime_entity_id = VarULong(entity.entity_id as u64); + broadcast_packet.actor_runtime_id = VarULong(entity.entity_id as u64); broadcast_packet.flags |= pumpkin_protocol::bedrock::server::emote::EMOTE_FLAG_SERVER_SIDE; world diff --git a/crates/pumpkin/src/net/bedrock/play/interaction.rs b/crates/pumpkin/src/net/bedrock/play/interaction.rs index c3f3b4a9c..746b8b9e1 100644 --- a/crates/pumpkin/src/net/bedrock/play/interaction.rs +++ b/crates/pumpkin/src/net/bedrock/play/interaction.rs @@ -4,49 +4,22 @@ use super::*; impl BedrockClient { pub async fn handle_interaction( &self, - player: &Arc, - packet: SInteraction, - server: &Arc, + _player: &Arc, + packet: SInteract, + _server: &Arc, ) { - match packet.action { - Action::Interact => { - player.update_last_action_time(); - let target_id = packet.target_runtime_id.0 as i32; - let Some(target) = player.world().get_entity_by_id(target_id) else { - return; - }; - - let mut stack = player.inventory().held_item().await; - if !target.interact(player, &mut stack).await { - server - .item_registry - .use_on_entity(&mut stack, player, target) - .await; - } - player.inventory().set_held_item(stack).await; + if matches!(packet.action, Action::OpenInventory) { + if self.inventory_opened.load(Ordering::Relaxed) { + return; } - Action::OpenInventory => { - if self.inventory_opened.load(Ordering::Relaxed) { - return; - } - self.inventory_opened.store(true, Ordering::Relaxed); - self.enqueue_client_packet(&CContainerOpen { - container_id: 0, - container_type: 0xff, - position: BlockPos::ZERO, - target_entity_id: VarLong(-1), - }) - .await; - } - // No longer used in newer versions - Action::Attack => { - let target_runtime_id = packet.target_runtime_id.0 as i32; - let world = player.world(); - if let Some(target) = world.get_entity_by_id(target_runtime_id) { - player.attack(target).await; - } - } - _ => {} + self.inventory_opened.store(true, Ordering::Relaxed); + self.enqueue_client_packet(&CContainerOpen { + container_id: 0, + container_type: 0xff, + position: BlockPos::ZERO, + target_entity_id: VarLong(-1), + }) + .await; } } } diff --git a/crates/pumpkin/src/net/bedrock/play/inventory_action.rs b/crates/pumpkin/src/net/bedrock/play/inventory_action.rs index f4f27fd00..7af675c28 100644 --- a/crates/pumpkin/src/net/bedrock/play/inventory_action.rs +++ b/crates/pumpkin/src/net/bedrock/play/inventory_action.rs @@ -410,7 +410,7 @@ impl BedrockClient { if packet.legacy_request_id.0 != 0 { use pumpkin_protocol::bedrock::client::item_stack_response::{ - CItemStackResponse, ItemStackResponse, ItemStackResponseContainerInfo, + CItemStackResponse, ItemStackResponseContainerInfo, ItemStackResponseInfo, ItemStackResponseSlotInfo, }; @@ -419,15 +419,15 @@ impl BedrockClient { for update in updates { let container_info = container_infos.iter_mut().find( |info: &&mut ItemStackResponseContainerInfo| { - info.container_name == update.container_name + info.full_container_name == update.container_name }, ); let slot_info = ItemStackResponseSlotInfo { + requested_slot: update.slot_id, slot: update.slot_id, - hotbar_slot: update.slot_id, - count: update.count, - item_stack_id: update.stack_id, + amount: update.count, + item_stack_net_id: update.stack_id, custom_name: String::new(), filtered_custom_name: String::new(), durability_correction: VarInt(0), @@ -437,7 +437,7 @@ impl BedrockClient { info.slots.push(slot_info); } else { container_infos.push(ItemStackResponseContainerInfo { - container_name: update.container_name.clone(), + full_container_name: update.container_name.clone(), slots: vec![slot_info], }); } @@ -445,10 +445,10 @@ impl BedrockClient { } self.enqueue_client_packet(&CItemStackResponse { - responses: vec![ItemStackResponse { + responses: vec![ItemStackResponseInfo { result, - request_id: packet.legacy_request_id, - container_infos, + client_request_id: packet.legacy_request_id, + containers: container_infos, }], }) .await; diff --git a/crates/pumpkin/src/net/bedrock/play/item_stack_request.rs b/crates/pumpkin/src/net/bedrock/play/item_stack_request.rs index cf80713e1..4f75754eb 100644 --- a/crates/pumpkin/src/net/bedrock/play/item_stack_request.rs +++ b/crates/pumpkin/src/net/bedrock/play/item_stack_request.rs @@ -9,7 +9,7 @@ impl BedrockClient { packet: pumpkin_protocol::bedrock::server::item_stack_request::SItemStackRequest, ) { use pumpkin_protocol::bedrock::client::item_stack_response::{ - CItemStackResponse, ItemStackResponse, ItemStackResponseContainerInfo, + CItemStackResponse, ItemStackResponseContainerInfo, ItemStackResponseInfo, ItemStackResponseSlotInfo, }; use pumpkin_protocol::bedrock::server::item_stack_request::ItemStackRequestAction; @@ -462,15 +462,15 @@ impl BedrockClient { for update in updates { let container_info = container_infos.iter_mut().find( |info: &&mut ItemStackResponseContainerInfo| { - info.container_name == update.container_name + info.full_container_name == update.container_name }, ); let slot_info = ItemStackResponseSlotInfo { + requested_slot: update.slot_id, slot: update.slot_id, - hotbar_slot: update.slot_id, - count: update.count, - item_stack_id: update.stack_id, + amount: update.count, + item_stack_net_id: update.stack_id, custom_name: String::new(), filtered_custom_name: String::new(), durability_correction: VarInt(0), @@ -480,17 +480,17 @@ impl BedrockClient { info.slots.push(slot_info); } else { container_infos.push(ItemStackResponseContainerInfo { - container_name: update.container_name, + full_container_name: update.container_name, slots: vec![slot_info], }); } } } - responses.push(ItemStackResponse { + responses.push(ItemStackResponseInfo { result, - request_id: request.request_id, - container_infos, + client_request_id: request.request_id, + containers: container_infos, }); } @@ -501,11 +501,11 @@ impl BedrockClient { let mut inventory_updated = false; for response in &responses { if response.result == 0 { - for info in &response.container_infos { - if info.container_name.container_name == ContainerName::Inventory - || info.container_name.container_name + for info in &response.containers { + if info.full_container_name.container_name == ContainerName::Inventory + || info.full_container_name.container_name == ContainerName::CombinedHotBarAndInventory - || info.container_name.container_name == ContainerName::HotBar + || info.full_container_name.container_name == ContainerName::HotBar { inventory_updated = true; } diff --git a/crates/pumpkin/src/net/bedrock/play/mob_equipment.rs b/crates/pumpkin/src/net/bedrock/play/mob_equipment.rs index 4f856f8be..2b8809c03 100644 --- a/crates/pumpkin/src/net/bedrock/play/mob_equipment.rs +++ b/crates/pumpkin/src/net/bedrock/play/mob_equipment.rs @@ -9,7 +9,7 @@ impl BedrockClient { packet: SMobEquipment, ) { player.update_last_action_time(); - let slot = packet.hotbar_slot; + let slot = packet.selected_slot; if slot >= 9 { return; } @@ -26,7 +26,7 @@ impl BedrockClient { self.enqueue_client_packet(&CPlayerHotbar { selected_slot: VarUInt(previous_slot as u32), container_id: 0, - should_select_block: true, + should_select_slot: true, }) .await; return; diff --git a/crates/pumpkin/src/net/bedrock/play/mod.rs b/crates/pumpkin/src/net/bedrock/play/mod.rs index 2a83bea3f..74209c222 100644 --- a/crates/pumpkin/src/net/bedrock/play/mod.rs +++ b/crates/pumpkin/src/net/bedrock/play/mod.rs @@ -14,31 +14,28 @@ use pumpkin_inventory::{ player::player_inventory::PlayerInventory, screen_handler::{InventoryPlayer, ScreenHandler}, }; -use pumpkin_protocol::bedrock::{ - client::{inventory_content::CInventoryContent, respawn::CRespawn}, - network_item::{ - ContainerName, FullContainerName, NetworkItemDescriptor, NetworkItemStackDescriptor, - }, - respawn::RespawnState, -}; use pumpkin_protocol::{ bedrock::{ client::{ - chunk_radius_update::CChunkRadiusUpdate, container_open::CContainerOpen, - player_hotbar::CPlayerHotbar, update_block::CUpdateBlock, + chunk_radius_updated::CChunkRadiusUpdated, container_open::CContainerOpen, + inventory_content::CInventoryContent, player_hotbar::CPlayerHotbar, + update_block::CUpdateBlock, + }, + network_item::{ + ContainerName, FullContainerName, NetworkItemDescriptor, NetworkItemStackDescriptor, }, server::{ - actor_event::{ActorEventType, SActorEvent}, + actor_event::{ActorEventID, SActorEvent}, animate::{AnimateAction, SAnimate}, block_pick_request::SBlockPickRequest, command_request::SCommandRequest, container_close::SContainerClose, emote::SEmote, emote_list::SEmoteList, - interaction::{Action, SInteraction}, + interact::{Action, SInteract}, inventory_transaction::{SInventoryTransaction, TransactionData}, mob_equipment::SMobEquipment, - player_action::{Action as PlayerAction, SPlayerAction}, + player_action::{PlayerActionType as PlayerAction, SPlayerAction}, player_auth_input::{InputData, SPlayerAuthInput}, request_chunk_radius::SRequestChunkRadius, respawn::SRespawn, diff --git a/crates/pumpkin/src/net/bedrock/play/modal_form_response.rs b/crates/pumpkin/src/net/bedrock/play/modal_form_response.rs index d1caf006d..3ac98f3d2 100644 --- a/crates/pumpkin/src/net/bedrock/play/modal_form_response.rs +++ b/crates/pumpkin/src/net/bedrock/play/modal_form_response.rs @@ -13,7 +13,7 @@ impl BedrockClient { player.clone(), packet.form_id.0, packet - .form_data + .json_response .filter(|data| data != "null") .map(std::borrow::Cow::into_owned), ); diff --git a/crates/pumpkin/src/net/bedrock/play/player_action.rs b/crates/pumpkin/src/net/bedrock/play/player_action.rs index 83af61e08..a6bc89097 100644 --- a/crates/pumpkin/src/net/bedrock/play/player_action.rs +++ b/crates/pumpkin/src/net/bedrock/play/player_action.rs @@ -20,10 +20,10 @@ impl BedrockClient { player.update_last_action_time(); match packet.action { - PlayerAction::StartBreak - | PlayerAction::CreativePlayerDestroyBlock + PlayerAction::StartDestroyBlock + | PlayerAction::CreativeDestroyBlock | PlayerAction::ContinueDestroyBlock => { - let location = packet.block_pos; + let location = packet.block_position; if !player.can_interact_with_block_at(&location, 1.0) { return; } @@ -123,8 +123,8 @@ impl BedrockClient { } } } - action @ (PlayerAction::PredictDestroyBlock | PlayerAction::StopBreak) => { - let location = packet.block_pos; + action @ (PlayerAction::PredictDestroyBlock | PlayerAction::StopDestroyBlock) => { + let location = packet.block_position; if !player.can_interact_with_block_at(&location, 1.0) { return; } @@ -169,7 +169,7 @@ impl BedrockClient { let runtime_id = pumpkin_data::BlockState::to_be_network_id(state.id); self.enqueue_client_packet(&CUpdateBlock::new(location, runtime_id as u32)) .await; - if matches!(action, PlayerAction::StopBreak) { + if matches!(action, PlayerAction::StopDestroyBlock) { player.stop_mining().await; } else { world @@ -186,15 +186,15 @@ impl BedrockClient { .await; } } - } else if matches!(action, PlayerAction::StopBreak) { + } else if matches!(action, PlayerAction::StopDestroyBlock) { player.stop_mining().await; } } - PlayerAction::CrackBreak => { + PlayerAction::CrackBlock => { // Don't do anything for this action. It is no longer used. Block // cracking is done fully server-side. } - PlayerAction::AbortBreak => { + PlayerAction::AbortDestroyBlock => { player.stop_mining().await; } PlayerAction::DropItem => { diff --git a/crates/pumpkin/src/net/bedrock/play/player_block_action.rs b/crates/pumpkin/src/net/bedrock/play/player_block_action.rs index a9cbcd5aa..328c78fd7 100644 --- a/crates/pumpkin/src/net/bedrock/play/player_block_action.rs +++ b/crates/pumpkin/src/net/bedrock/play/player_block_action.rs @@ -8,7 +8,7 @@ impl BedrockClient { server: &Server, packet: pumpkin_protocol::bedrock::server::player_auth_input::PlayerBlockAction, ) { - use pumpkin_protocol::bedrock::server::player_action::Action as PlayerAction; + use pumpkin_protocol::bedrock::server::player_action::PlayerActionType as PlayerAction; let Ok(action) = PlayerAction::try_from(packet.action.0) else { return; }; @@ -16,9 +16,9 @@ impl BedrockClient { player, server, SPlayerAction { - runtime_id: VarULong(0), // Unused + player_runtime_id: VarULong(0), // Unused action, - block_pos: packet.block_pos, + block_position: packet.block_pos, result_pos: BlockPos::ZERO, face: packet.face, }, diff --git a/crates/pumpkin/src/net/bedrock/play/request_chunk_radius.rs b/crates/pumpkin/src/net/bedrock/play/request_chunk_radius.rs index d9e063b28..476c37a9c 100644 --- a/crates/pumpkin/src/net/bedrock/play/request_chunk_radius.rs +++ b/crates/pumpkin/src/net/bedrock/play/request_chunk_radius.rs @@ -25,7 +25,7 @@ impl BedrockClient { NonZero::::from(server.advanced_config.networking.bedrock.view_distance).get(), ); - self.enqueue_client_packet(&CChunkRadiusUpdate { + self.enqueue_client_packet(&CChunkRadiusUpdated { chunk_radius: VarInt(view_distance), }) .await; diff --git a/crates/pumpkin/src/net/bedrock/play/respawn.rs b/crates/pumpkin/src/net/bedrock/play/respawn.rs index 7fb7baed4..6e65399f2 100644 --- a/crates/pumpkin/src/net/bedrock/play/respawn.rs +++ b/crates/pumpkin/src/net/bedrock/play/respawn.rs @@ -1,3 +1,5 @@ +use pumpkin_protocol::bedrock::server::RespawnState; + #[allow(clippy::wildcard_imports)] use super::*; @@ -12,15 +14,15 @@ impl BedrockClient { let entity = player.get_entity(); let position = entity.pos.load(); - self.enqueue_client_packet(&CRespawn::new( - pumpkin_util::math::vector3::Vector3::new( + self.enqueue_client_packet(&SRespawn { + position: pumpkin_util::math::vector3::Vector3::new( position.x as f32, position.y as f32 + entity.entity_type.eye_height, position.z as f32, ), - RespawnState::ReadyToSpawn, - VarULong(player.entity_id() as u64), - )) + state: RespawnState::ReadyToSpawn, + player_runtime_id: VarULong(player.entity_id() as u64), + }) .await; } } diff --git a/crates/pumpkin/src/net/bedrock/play/set_local_player_as_initialized.rs b/crates/pumpkin/src/net/bedrock/play/set_local_player_as_initialized.rs index 418668ae3..79b67efe6 100644 --- a/crates/pumpkin/src/net/bedrock/play/set_local_player_as_initialized.rs +++ b/crates/pumpkin/src/net/bedrock/play/set_local_player_as_initialized.rs @@ -9,7 +9,7 @@ impl BedrockClient { ) { debug!( "Player {} initialized (Runtime ID: {})", - player.gameprofile.name, packet.runtime_entity_id.0 + player.gameprofile.name, packet.player_id.0 ); // This is sent when the client has finished loading and rendering the world. player.set_client_loaded(true); diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/generated_packets.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/generated_packets.rs index 642ce2edd..3be5ae5ac 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/generated_packets.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/generated_packets.rs @@ -2719,20 +2719,39 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { match packet { BClientboundPacket::CBlockEvent(data) => { let p = pumpkin_protocol::bedrock::client::CBlockEvent { - position: pumpkin_util::math::position::BlockPos::new( - data.position.0, - data.position.1, - data.position.2, + block_position: pumpkin_util::math::position::BlockPos::new( + data.block_position.0, + data.block_position.1, + data.block_position.2, ), event_type: VarInt(data.event_type), - event_data: VarInt(data.event_data), + event_value: VarInt(data.event_value), }; let mut buf = Vec::new(); crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); Some(buf.into()) } - BClientboundPacket::CChunkRadiusUpdate(data) => { - let p = pumpkin_protocol::bedrock::client::CChunkRadiusUpdate { + BClientboundPacket::CBossEvent(data) => { + let p = pumpkin_protocol::bedrock::client::CBossEvent { + boss_entity_id: pumpkin_protocol::codec::var_long::VarLong( + data.boss_entity_id.try_into().unwrap(), + ), + player_entity_id: pumpkin_protocol::codec::var_long::VarLong( + data.player_entity_id.try_into().unwrap(), + ), + event_type: data.event_type.try_into().unwrap(), + title: data.title.clone(), + filtered_title: data.filtered_title.clone(), + health_percentage: data.health_percentage.try_into().unwrap(), + color: data.color.try_into().unwrap(), + overlay: data.overlay.try_into().unwrap(), + }; + let mut buf = Vec::new(); + crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); + Some(buf.into()) + } + BClientboundPacket::CChunkRadiusUpdated(data) => { + let p = pumpkin_protocol::bedrock::client::CChunkRadiusUpdated { chunk_radius: VarInt(data.chunk_radius), }; let mut buf = Vec::new(); @@ -2756,8 +2775,8 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); Some(buf.into()) } - BClientboundPacket::CDisconnectPlayer(data) => { - let p = pumpkin_protocol::bedrock::client::CDisconnectPlayer { + BClientboundPacket::CDisconnect(data) => { + let p = pumpkin_protocol::bedrock::client::CDisconnect { reason: VarInt(data.reason), skip_message: data.skip_message.try_into().unwrap(), message: data.message.clone(), @@ -2783,14 +2802,14 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { } BClientboundPacket::CMobEffect(data) => { let p = pumpkin_protocol::bedrock::client::CMobEffect { - runtime_entity_id: pumpkin_protocol::codec::var_ulong::VarULong( - data.runtime_entity_id.try_into().unwrap(), + target_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong( + data.target_runtime_id.try_into().unwrap(), ), event_id: data.event_id.try_into().unwrap(), effect_id: VarInt(data.effect_id), - amplifier: VarInt(data.amplifier), - particles: data.particles.try_into().unwrap(), - duration: VarInt(data.duration), + effect_amplifier: VarInt(data.effect_amplifier), + show_particles: data.show_particles.try_into().unwrap(), + effect_duration_ticks: VarInt(data.effect_duration_ticks), tick: pumpkin_protocol::codec::var_ulong::VarULong(data.tick.try_into().unwrap()), ambient: data.ambient.try_into().unwrap(), }; @@ -2803,7 +2822,7 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { form_id: pumpkin_protocol::codec::var_uint::VarUInt( data.form_id.try_into().unwrap(), ), - form_data: data.form_data.clone(), + form_ui_json: data.form_ui_json.clone(), }; let mut buf = Vec::new(); crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); @@ -2811,18 +2830,18 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { } BClientboundPacket::CMoveActorAbsolute(data) => { let p = pumpkin_protocol::bedrock::client::CMoveActorAbsolute { - entity_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong( - data.entity_runtime_id.try_into().unwrap(), + actor_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong( + data.actor_runtime_id.try_into().unwrap(), ), - flags: data.flags.try_into().unwrap(), + header: data.header.try_into().unwrap(), position: pumpkin_util::math::vector3::Vector3::new( data.position.0 as _, data.position.1 as _, data.position.2 as _, ), - pitch: data.pitch.try_into().unwrap(), - yaw: data.yaw.try_into().unwrap(), - head_yaw: data.head_yaw.try_into().unwrap(), + rotation_x: data.rotation_x.try_into().unwrap(), + rotation_y: data.rotation_y.try_into().unwrap(), + rotation_y_head: data.rotation_y_head.try_into().unwrap(), }; let mut buf = Vec::new(); crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); @@ -2874,7 +2893,7 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { BClientboundPacket::CNetworkSettings(data) => { let p = pumpkin_protocol::bedrock::client::CNetworkSettings { compression_threshold: data.compression_threshold.try_into().unwrap(), - compression_method: data.compression_method.try_into().unwrap(), + compression_algorithm: data.compression_algorithm.try_into().unwrap(), client_throttle_enabled: data.client_throttle_enabled.try_into().unwrap(), client_throttle_threshold: data.client_throttle_threshold.try_into().unwrap(), client_throttle_scalar: data.client_throttle_scalar.try_into().unwrap(), @@ -2906,7 +2925,7 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { data.selected_slot.try_into().unwrap(), ), container_id: data.container_id.try_into().unwrap(), - should_select_block: data.should_select_block.try_into().unwrap(), + should_select_slot: data.should_select_slot.try_into().unwrap(), }; let mut buf = Vec::new(); crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); @@ -2914,26 +2933,14 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { } BClientboundPacket::CRemoveActor(data) => { let p = pumpkin_protocol::bedrock::client::CRemoveActor { - entity_unique_id: pumpkin_protocol::codec::var_long::VarLong( - data.entity_unique_id.try_into().unwrap(), + target_actor_id: pumpkin_protocol::codec::var_long::VarLong( + data.target_actor_id.try_into().unwrap(), ), }; let mut buf = Vec::new(); crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); Some(buf.into()) } - BClientboundPacket::CSetDisplayObjective(data) => { - let p = pumpkin_protocol::bedrock::client::CSetDisplayObjective { - display_slot: data.display_slot.clone(), - objective_name: data.objective_name.clone(), - display_name: data.display_name.clone(), - criteria_name: data.criteria_name.clone(), - sort_order: VarInt(data.sort_order), - }; - let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); - Some(buf.into()) - } BClientboundPacket::CRemoveObjective(data) => { let p = pumpkin_protocol::bedrock::client::CRemoveObjective { objective_name: data.objective_name.clone(), @@ -2968,28 +2975,21 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); Some(buf.into()) } - BClientboundPacket::CSetHealth(data) => { - let p = pumpkin_protocol::bedrock::client::CSetHealth { - health: VarInt(data.health), + BClientboundPacket::CSetDisplayObjective(data) => { + let p = pumpkin_protocol::bedrock::client::CSetDisplayObjective { + display_slot_name: data.display_slot_name.clone(), + objective_name: data.objective_name.clone(), + objective_display_name: data.objective_display_name.clone(), + criteria_name: data.criteria_name.clone(), + sort_order: VarInt(data.sort_order), }; let mut buf = Vec::new(); crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); Some(buf.into()) } - BClientboundPacket::CSetSpawnPosition(data) => { - let p = pumpkin_protocol::bedrock::client::CSetSpawnPosition { - spawn_type: VarInt(data.spawn_type), - position: pumpkin_util::math::position::BlockPos::new( - data.position.0, - data.position.1, - data.position.2, - ), - dimension: VarInt(data.dimension), - spawn_position: pumpkin_util::math::position::BlockPos::new( - data.spawn_position.0, - data.spawn_position.1, - data.spawn_position.2, - ), + BClientboundPacket::CSetHealth(data) => { + let p = pumpkin_protocol::bedrock::client::CSetHealth { + health: VarInt(data.health), }; let mut buf = Vec::new(); crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); @@ -3003,27 +3003,12 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); Some(buf.into()) } - BClientboundPacket::CSetTitle(data) => { - let p = pumpkin_protocol::bedrock::client::CSetTitle { - action_type: VarInt(data.action_type), - text: data.text.clone(), - fade_in_duration: VarInt(data.fade_in_duration), - remain_duration: VarInt(data.remain_duration), - fade_out_duration: VarInt(data.fade_out_duration), - xuid: data.xuid.clone(), - platform_online_id: data.platform_online_id.clone(), - filtered_message: data.filtered_message.clone(), - }; - let mut buf = Vec::new(); - crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); - Some(buf.into()) - } BClientboundPacket::CShowCredits(data) => { let p = pumpkin_protocol::bedrock::client::CShowCredits { player_runtime_id: pumpkin_protocol::codec::var_ulong::VarULong( data.player_runtime_id.try_into().unwrap(), ), - status: VarInt(data.status), + credits_state: VarInt(data.credits_state), }; let mut buf = Vec::new(); crate::net::bedrock::BedrockClient::write_raw_packet(&p, &mut buf).unwrap(); @@ -3044,8 +3029,8 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { } BClientboundPacket::CTransfer(data) => { let p = pumpkin_protocol::bedrock::client::CTransfer { - address: data.address.clone(), - port: data.port.try_into().unwrap(), + server_address: data.server_address.clone(), + server_port: data.server_port.try_into().unwrap(), reload_world: data.reload_world.try_into().unwrap(), }; let mut buf = Vec::new(); @@ -3054,10 +3039,10 @@ pub fn serialize_bedrock_packet(packet: &BClientboundPacket) -> Option { } BClientboundPacket::CUpdateBlock(data) => { let p = pumpkin_protocol::bedrock::client::CUpdateBlock { - position: pumpkin_util::math::position::BlockPos::new( - data.position.0, - data.position.1, - data.position.2, + block_position: pumpkin_util::math::position::BlockPos::new( + data.block_position.0, + data.block_position.1, + data.block_position.2, ), block_runtime_id: pumpkin_protocol::codec::var_uint::VarUInt( data.block_runtime_id.try_into().unwrap(), @@ -3083,16 +3068,16 @@ pub fn deserialize_bedrock_serverbound_packet( use pumpkin_protocol::BServerPacket; let p = ::read(&mut Cursor::new(payload)).ok()?; Some(BServerboundPacket::SBlockPickRequest(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SBlockPickRequest { - block_pos: (p.block_pos.0.x, p.block_pos.0.y, p.block_pos.0.z), - add_block_nbt: p.add_block_nbt.try_into().unwrap(), - hotbar_slot: p.hotbar_slot.try_into().unwrap(), + position: (p.position.0.x, p.position.0.y, p.position.0.z), + with_data: p.with_data.try_into().unwrap(), + max_slots: p.max_slots.try_into().unwrap(), })) } id if id == ::PACKET_ID as i32 => { use pumpkin_protocol::BServerPacket; let p = ::read(&mut Cursor::new(payload)).ok()?; Some(BServerboundPacket::SClientCacheStatus(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SClientCacheStatus { - cache_supported: p.cache_supported.try_into().unwrap(), + is_cache_supported: p.is_cache_supported.try_into().unwrap(), })) } id if id == ::PACKET_ID as i32 => { @@ -3101,7 +3086,7 @@ pub fn deserialize_bedrock_serverbound_packet( Some(BServerboundPacket::SContainerClose(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SContainerClose { container_id: p.container_id.try_into().unwrap(), container_type: p.container_type.try_into().unwrap(), - server_initiated: p.server_initiated.try_into().unwrap(), + server_initiated_close: p.server_initiated_close.try_into().unwrap(), })) } id if id == ::PACKET_ID as i32 => { @@ -3109,9 +3094,9 @@ pub fn deserialize_bedrock_serverbound_packet( let p = ::read(&mut Cursor::new(payload)).ok()?; Some(BServerboundPacket::SPacketViolationWarning(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SPacketViolationWarning { violation_type: p.violation_type.0.try_into().unwrap(), - severity: p.severity.0.try_into().unwrap(), - packet_id: p.packet_id.0.try_into().unwrap(), - context: p.context.into(), + violation_severity: p.violation_severity.0.try_into().unwrap(), + violation_packet_id: p.violation_packet_id.0.try_into().unwrap(), + violation_context: p.violation_context.into(), })) } id if id == ::PACKET_ID as i32 => { @@ -3120,7 +3105,7 @@ pub fn deserialize_bedrock_serverbound_packet( Some(BServerboundPacket::SPlayerHotbar(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SPlayerHotbar { selected_slot: p.selected_slot.0.try_into().unwrap(), container_id: p.container_id.try_into().unwrap(), - select_slot: p.select_slot.try_into().unwrap(), + should_select_slot: p.should_select_slot.try_into().unwrap(), })) } id if id == ::PACKET_ID as i32 => { @@ -3128,21 +3113,21 @@ pub fn deserialize_bedrock_serverbound_packet( let p = ::read(&mut Cursor::new(payload)).ok()?; Some(BServerboundPacket::SRequestChunkRadius(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SRequestChunkRadius { chunk_radius: p.chunk_radius.0.try_into().unwrap(), - max_radius: p.max_radius.try_into().unwrap(), + max_chunk_radius: p.max_chunk_radius.try_into().unwrap(), })) } id if id == ::PACKET_ID as i32 => { use pumpkin_protocol::BServerPacket; let p = ::read(&mut Cursor::new(payload)).ok()?; Some(BServerboundPacket::SRequestNetworkSettings(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SRequestNetworkSettings { - protocol_version: p.protocol_version.try_into().unwrap(), + client_network_version: p.client_network_version.try_into().unwrap(), })) } id if id == ::PACKET_ID as i32 => { use pumpkin_protocol::BServerPacket; let p = ::read(&mut Cursor::new(payload)).ok()?; Some(BServerboundPacket::SSetLocalPlayerAsInitialized(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::SSetLocalPlayerAsInitialized { - runtime_entity_id: p.runtime_entity_id.0.try_into().unwrap(), + player_id: p.player_id.0.try_into().unwrap(), })) } id if id == ::PACKET_ID as i32 => { @@ -3152,8 +3137,8 @@ pub fn deserialize_bedrock_serverbound_packet( left_inventory_tab: p.left_inventory_tab.0.try_into().unwrap(), right_inventory_tab: p.right_inventory_tab.0.try_into().unwrap(), filtering: p.filtering.try_into().unwrap(), - inventory_layout: p.inventory_layout.0.try_into().unwrap(), - crafting_layout: p.crafting_layout.0.try_into().unwrap(), + layout_inv: p.layout_inv.0.try_into().unwrap(), + layout_craft: p.layout_craft.0.try_into().unwrap(), })) } _ => None, @@ -3167,16 +3152,31 @@ pub trait ToWitClientboundBedrock { impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CBlockEvent { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CBlockEvent(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CBlockEvent { - position: (self.position.0.x, self.position.0.y, self.position.0.z), + block_position: (self.block_position.0.x, self.block_position.0.y, self.block_position.0.z), event_type: self.event_type.0.try_into().unwrap(), - event_data: self.event_data.0.try_into().unwrap(), + event_value: self.event_value.0.try_into().unwrap(), }) } } -impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CChunkRadiusUpdate { +impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CBossEvent { fn to_wit(&self) -> BClientboundPacket { - BClientboundPacket::CChunkRadiusUpdate(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CChunkRadiusUpdate { + BClientboundPacket::CBossEvent(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CBossEvent { + boss_entity_id: self.boss_entity_id.0.try_into().unwrap(), + player_entity_id: self.player_entity_id.0.try_into().unwrap(), + event_type: self.event_type.try_into().unwrap(), + title: self.title.to_string(), + filtered_title: self.filtered_title.to_string(), + health_percentage: self.health_percentage.try_into().unwrap(), + color: self.color.try_into().unwrap(), + overlay: self.overlay.try_into().unwrap(), + }) + } +} + +impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CChunkRadiusUpdated { + fn to_wit(&self) -> BClientboundPacket { + BClientboundPacket::CChunkRadiusUpdated(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CChunkRadiusUpdated { chunk_radius: self.chunk_radius.0.try_into().unwrap(), }) } @@ -3193,9 +3193,9 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CContainerOp } } -impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CDisconnectPlayer { +impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CDisconnect { fn to_wit(&self) -> BClientboundPacket { - BClientboundPacket::CDisconnectPlayer(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CDisconnectPlayer { + BClientboundPacket::CDisconnect(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CDisconnect { reason: self.reason.0.try_into().unwrap(), skip_message: self.skip_message.try_into().unwrap(), message: self.message.to_string(), @@ -3217,12 +3217,12 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CLevelEvent impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CMobEffect { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CMobEffect(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CMobEffect { - runtime_entity_id: self.runtime_entity_id.0.try_into().unwrap(), + target_runtime_id: self.target_runtime_id.0.try_into().unwrap(), event_id: self.event_id.try_into().unwrap(), effect_id: self.effect_id.0.try_into().unwrap(), - amplifier: self.amplifier.0.try_into().unwrap(), - particles: self.particles.try_into().unwrap(), - duration: self.duration.0.try_into().unwrap(), + effect_amplifier: self.effect_amplifier.0.try_into().unwrap(), + show_particles: self.show_particles.try_into().unwrap(), + effect_duration_ticks: self.effect_duration_ticks.0.try_into().unwrap(), tick: self.tick.0.try_into().unwrap(), ambient: self.ambient.try_into().unwrap(), }) @@ -3233,7 +3233,7 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CModalFormRe fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CModalFormRequest(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CModalFormRequest { form_id: self.form_id.0.try_into().unwrap(), - form_data: self.form_data.to_string(), + form_ui_json: self.form_ui_json.to_string(), }) } } @@ -3241,12 +3241,12 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CModalFormRe impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CMoveActorAbsolute { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CMoveActorAbsolute(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CMoveActorAbsolute { - entity_runtime_id: self.entity_runtime_id.0.try_into().unwrap(), - flags: self.flags.try_into().unwrap(), + actor_runtime_id: self.actor_runtime_id.0.try_into().unwrap(), + header: self.header.try_into().unwrap(), position: (self.position.x as _, self.position.y as _, self.position.z as _), - pitch: self.pitch.try_into().unwrap(), - yaw: self.yaw.try_into().unwrap(), - head_yaw: self.head_yaw.try_into().unwrap(), + rotation_x: self.rotation_x.try_into().unwrap(), + rotation_y: self.rotation_y.try_into().unwrap(), + rotation_y_head: self.rotation_y_head.try_into().unwrap(), }) } } @@ -3288,7 +3288,7 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CNetworkSett fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CNetworkSettings(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CNetworkSettings { compression_threshold: self.compression_threshold.try_into().unwrap(), - compression_method: self.compression_method.try_into().unwrap(), + compression_algorithm: self.compression_algorithm.try_into().unwrap(), client_throttle_enabled: self.client_throttle_enabled.try_into().unwrap(), client_throttle_threshold: self.client_throttle_threshold.try_into().unwrap(), client_throttle_scalar: self.client_throttle_scalar.try_into().unwrap(), @@ -3318,7 +3318,7 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CPlayerHotba BClientboundPacket::CPlayerHotbar(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CPlayerHotbar { selected_slot: self.selected_slot.0.try_into().unwrap(), container_id: self.container_id.try_into().unwrap(), - should_select_block: self.should_select_block.try_into().unwrap(), + should_select_slot: self.should_select_slot.try_into().unwrap(), }) } } @@ -3326,19 +3326,7 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CPlayerHotba impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CRemoveActor { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CRemoveActor(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CRemoveActor { - entity_unique_id: self.entity_unique_id.0.try_into().unwrap(), - }) - } -} - -impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetDisplayObjective { - fn to_wit(&self) -> BClientboundPacket { - BClientboundPacket::CSetDisplayObjective(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetDisplayObjective { - display_slot: self.display_slot.to_string(), - objective_name: self.objective_name.to_string(), - display_name: self.display_name.to_string(), - criteria_name: self.criteria_name.to_string(), - sort_order: self.sort_order.0.try_into().unwrap(), + target_actor_id: self.target_actor_id.0.try_into().unwrap(), }) } } @@ -3369,21 +3357,22 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetDifficul } } -impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetHealth { +impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetDisplayObjective { fn to_wit(&self) -> BClientboundPacket { - BClientboundPacket::CSetHealth(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetHealth { - health: self.health.0.try_into().unwrap(), + BClientboundPacket::CSetDisplayObjective(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetDisplayObjective { + display_slot_name: self.display_slot_name.to_string(), + objective_name: self.objective_name.to_string(), + objective_display_name: self.objective_display_name.to_string(), + criteria_name: self.criteria_name.to_string(), + sort_order: self.sort_order.0.try_into().unwrap(), }) } } -impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetSpawnPosition { +impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetHealth { fn to_wit(&self) -> BClientboundPacket { - BClientboundPacket::CSetSpawnPosition(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetSpawnPosition { - spawn_type: self.spawn_type.0.try_into().unwrap(), - position: (self.position.0.x, self.position.0.y, self.position.0.z), - dimension: self.dimension.0.try_into().unwrap(), - spawn_position: (self.spawn_position.0.x, self.spawn_position.0.y, self.spawn_position.0.z), + BClientboundPacket::CSetHealth(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetHealth { + health: self.health.0.try_into().unwrap(), }) } } @@ -3396,26 +3385,11 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetTime { } } -impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CSetTitle { - fn to_wit(&self) -> BClientboundPacket { - BClientboundPacket::CSetTitle(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CSetTitle { - action_type: self.action_type.0.try_into().unwrap(), - text: self.text.to_string(), - fade_in_duration: self.fade_in_duration.0.try_into().unwrap(), - remain_duration: self.remain_duration.0.try_into().unwrap(), - fade_out_duration: self.fade_out_duration.0.try_into().unwrap(), - xuid: self.xuid.to_string(), - platform_online_id: self.platform_online_id.to_string(), - filtered_message: self.filtered_message.to_string(), - }) - } -} - impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CShowCredits { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CShowCredits(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CShowCredits { player_runtime_id: self.player_runtime_id.0.try_into().unwrap(), - status: self.status.0.try_into().unwrap(), + credits_state: self.credits_state.0.try_into().unwrap(), }) } } @@ -3432,8 +3406,8 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CTakeItemAct impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CTransfer { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CTransfer(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CTransfer { - address: self.address.to_string(), - port: self.port.try_into().unwrap(), + server_address: self.server_address.to_string(), + server_port: self.server_port.try_into().unwrap(), reload_world: self.reload_world.try_into().unwrap(), }) } @@ -3442,7 +3416,7 @@ impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CTransfer { impl ToWitClientboundBedrock for pumpkin_protocol::bedrock::client::CUpdateBlock { fn to_wit(&self) -> BClientboundPacket { BClientboundPacket::CUpdateBlock(crate::plugin::loader::wasm::wasm_host::wit::v0_1::pumpkin::plugin::bedrock_packets::CUpdateBlock { - position: (self.position.0.x, self.position.0.y, self.position.0.z), + block_position: (self.block_position.0.x, self.block_position.0.y, self.block_position.0.z), block_runtime_id: self.block_runtime_id.0.try_into().unwrap(), flags: self.flags.0.try_into().unwrap(), layer: self.layer.0.try_into().unwrap(), @@ -3455,13 +3429,16 @@ pub fn clientbound_bedrock_any_to_wit(any: &dyn Any) -> Option() { return Some(p.to_wit()); } - if let Some(p) = any.downcast_ref::() { + if let Some(p) = any.downcast_ref::() { + return Some(p.to_wit()); + } + if let Some(p) = any.downcast_ref::() { return Some(p.to_wit()); } if let Some(p) = any.downcast_ref::() { return Some(p.to_wit()); } - if let Some(p) = any.downcast_ref::() { + if let Some(p) = any.downcast_ref::() { return Some(p.to_wit()); } if let Some(p) = any.downcast_ref::() { @@ -3494,9 +3471,6 @@ pub fn clientbound_bedrock_any_to_wit(any: &dyn Any) -> Option() { return Some(p.to_wit()); } - if let Some(p) = any.downcast_ref::() { - return Some(p.to_wit()); - } if let Some(p) = any.downcast_ref::() { return Some(p.to_wit()); } @@ -3506,18 +3480,15 @@ pub fn clientbound_bedrock_any_to_wit(any: &dyn Any) -> Option() { return Some(p.to_wit()); } + if let Some(p) = any.downcast_ref::() { + return Some(p.to_wit()); + } if let Some(p) = any.downcast_ref::() { return Some(p.to_wit()); } - if let Some(p) = any.downcast_ref::() { - return Some(p.to_wit()); - } if let Some(p) = any.downcast_ref::() { return Some(p.to_wit()); } - if let Some(p) = any.downcast_ref::() { - return Some(p.to_wit()); - } if let Some(p) = any.downcast_ref::() { return Some(p.to_wit()); } diff --git a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/player.rs b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/player.rs index d3baba376..51e1f7eb6 100644 --- a/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/player.rs +++ b/crates/pumpkin/src/plugin/loader/wasm/wasm_host/wit/v0_1/player.rs @@ -1,3 +1,4 @@ +use pumpkin_protocol::bedrock::client::PackIdVersion; use std::sync::Arc; use std::sync::atomic::Ordering; use tokio::sync::Mutex; @@ -43,7 +44,7 @@ use pumpkin_util::translation::Locale; use std::str::FromStr; use pumpkin_protocol::bedrock::client::set_actor_data::{ - CSetActorData, EntityMetadata, MetadataValue, PropertySyncData, entity_data_key, + CSetActorData, MetadataValue, PropertySyncData, SyncedActorDataList, entity_data_key, }; use pumpkin_protocol::codec::var_ulong::VarULong; use pumpkin_util::version::{BedrockMinecraftVersion, JavaMinecraftVersion}; @@ -3473,10 +3474,10 @@ impl pumpkin::plugin::player::HostBedrockPlayer for PluginHostState { .store(flags, Ordering::Relaxed); } - let mut metadata = EntityMetadata(std::collections::HashMap::new()); + let mut metadata = SyncedActorDataList(std::collections::HashMap::new()); metadata.set( entity_data_key::FLAGS, - MetadataValue::Long( + MetadataValue::Int64( player .living_entity .entity @@ -3486,7 +3487,7 @@ impl pumpkin::plugin::player::HostBedrockPlayer for PluginHostState { ); metadata.set( entity_data_key::FLAGS_TWO, - MetadataValue::Long( + MetadataValue::Int64( player .living_entity .entity @@ -3496,11 +3497,11 @@ impl pumpkin::plugin::player::HostBedrockPlayer for PluginHostState { ); let packet = CSetActorData { - actor_runtime_id: VarULong(player.get_entity().entity_id as u64), - metadata, + target_runtime_id: VarULong(player.get_entity().entity_id as u64), + actor_data: metadata, synced_properties: PropertySyncData { - int_properties: std::collections::HashMap::new(), - float_properties: std::collections::HashMap::new(), + int_entries_list: std::collections::HashMap::new(), + float_entries_list: std::collections::HashMap::new(), }, tick: VarULong(0), }; @@ -3612,7 +3613,7 @@ impl pumpkin::plugin::player::HostBedrockPlayer for PluginHostState { client .send_packet(&CModalFormRequest { form_id: pumpkin_protocol::codec::var_uint::VarUInt(form_id), - form_data: form_json.to_string(), + form_ui_json: form_json.to_string(), }) .await; @@ -3671,20 +3672,19 @@ impl pumpkin::plugin::player::HostBedrockPlayer for PluginHostState { let entries = info .packs .into_iter() - .map(|p| { - pumpkin_protocol::bedrock::client::resource_packs_info::ResourcePackEntry { - uuid: Uuid::from_wit(&p.id), - version: p.version, - size: p.size, - download_url: p.download_url, + .map( + |p| pumpkin_protocol::bedrock::client::resource_packs_info::PackInfoData { + pack_id_version: PackIdVersion::new(Uuid::from_wit(&p.id), p.version), + pack_size: p.size, + cdn_url: p.download_url, content_key: p.content_key.unwrap_or_default(), - sub_pack_name: p.sub_pack_name.unwrap_or_default(), - content_id: p.content_id.unwrap_or_default(), + subpack_name: p.sub_pack_name.unwrap_or_default(), + content_identity: p.content_id.unwrap_or_default(), has_scripts: p.has_scripts, - addon_pack: p.addon_pack, - rtx_enabled: p.rtx_enabled, - } - }) + is_addon_pack: p.addon_pack, + is_ray_tracing_capable: p.rtx_enabled, + }, + ) .collect(); let world_template_id = info @@ -3696,9 +3696,11 @@ impl pumpkin::plugin::player::HostBedrockPlayer for PluginHostState { resource_pack_required: info.required, has_addon_packs: info.has_addon_packs, has_scripts: info.has_scripts, - is_vibrant_visuals_force_disabled: info.is_vibrant_visuals_force_disabled, - world_template_id, - world_template_version: info.world_template_version.unwrap_or_default(), + force_disable_vibrant_visuals: info.is_vibrant_visuals_force_disabled, + world_template_id_and_version: PackIdVersion::new( + world_template_id, + info.world_template_version.unwrap_or_default(), + ), resource_packs: entries, }; diff --git a/crates/pumpkin/src/server/mod.rs b/crates/pumpkin/src/server/mod.rs index 6752811fe..20cde6927 100644 --- a/crates/pumpkin/src/server/mod.rs +++ b/crates/pumpkin/src/server/mod.rs @@ -879,7 +879,9 @@ impl Server { world .broadcast_editioned( &CChangeDifficulty::new(difficulty as u8, locked), - &pumpkin_protocol::bedrock::client::CSetDifficulty::new(difficulty as u32), + &pumpkin_protocol::bedrock::client::CSetDifficulty { + difficulty: (difficulty as u32).into(), + }, ) .await; } @@ -897,7 +899,9 @@ impl Server { world .broadcast_editioned( &CChangeDifficulty::new(difficulty as u8, locked), - &pumpkin_protocol::bedrock::client::CSetDifficulty::new(difficulty as u32), + &pumpkin_protocol::bedrock::client::CSetDifficulty { + difficulty: (difficulty as u32).into(), + }, ) .await; } diff --git a/crates/pumpkin/src/world/mod.rs b/crates/pumpkin/src/world/mod.rs index 0dcf22219..d6f3fd948 100644 --- a/crates/pumpkin/src/world/mod.rs +++ b/crates/pumpkin/src/world/mod.rs @@ -3,11 +3,9 @@ use dashmap::DashMap; use pumpkin_data::attributes::Attributes; use pumpkin_data::chunk::Biome; use pumpkin_data::item::{BedrockItem, BedrockItemVersion}; -use pumpkin_protocol::bedrock::client::item_registry::{CItemRegistry, ItemDefinition}; +use pumpkin_protocol::bedrock::client::item_registry::{CItemRegistry, ItemData}; use pumpkin_protocol::bedrock::client::level_event::{CLevelEvent, LevelEvent}; -use pumpkin_protocol::bedrock::client::{ - CBiomeDefinitionList, EntityProperties, block_actor_data::CBlockActorData, -}; +use pumpkin_protocol::bedrock::client::{CBiomeDefinitionList, block_actor_data::CBlockActorData}; use pumpkin_protocol::bedrock::network_item::{NetworkItemDescriptor, NetworkItemStackDescriptor}; use pumpkin_protocol::codec::data_component::data_to_proto_sound; use pumpkin_world::generation::proto_chunk::GenerationCache; @@ -104,16 +102,18 @@ use pumpkin_protocol::{ add_player::CAddPlayer, block_event::CBlockEvent as CBedrockBlockEvent, common::BuildPlatform, - creative_content::{CCreativeContent, CreativeCategory, Entry, Group}, - gamerules_changed::GameRules, + creative_content::{ + CCreativeContent, CreativeCategory, CreativeGroupInfoPayload, + CreativeItemEntryPayload, + }, level_sound_event::CLevelSoundEvent, player_list::{CPlayerList, PlayerListEntry, Skin}, remove_actor::CRemoveActor, start_game::{Experiments, GamePublishSetting, LevelSettings}, - update_attributes::{Attribute, CUpdateAttributes}, + update_attributes::{AttributeData, CUpdateAttributes}, }, server::{ - actor_event::{ActorEventType, SActorEvent}, + actor_event::{ActorEventID, SActorEvent}, text::SText, }, }, @@ -133,7 +133,6 @@ use pumpkin_protocol::{ codec::item_stack_seralizer::ItemStackSerializer, java::client::play::{CBlockEvent, CRemoveMobEffect, CSetEquipment, CUpdateMobEffect}, }; -use pumpkin_util::GameMode; use pumpkin_util::resource_location::ResourceLocation; use pumpkin_util::text::{TextComponent, color::NamedColor}; use pumpkin_util::version::JavaMinecraftVersion; @@ -545,15 +544,15 @@ impl World { &self, entity: &Entity, java_status: EntityStatus, - bedrock_status: Option, + bedrock_status: Option, ) { let chunk_pos = entity.chunk_pos.load(); let je_packet = CEntityStatus::new(entity.entity_id, java_status as i8); if let Some(be_event) = bedrock_status { let be_packet = SActorEvent { - entity_runtime_id: VarULong(entity.entity_id as u64), - event_type: be_event, - event_data: VarInt(0), + target_runtime_id: VarULong(entity.entity_id as u64), + event_id: be_event, + data: VarInt(0), fire_at_position: None, }; self.broadcast_to_chunk_editioned_sync(chunk_pos, &je_packet, &be_packet); @@ -566,16 +565,17 @@ impl World { let chunk_pos = entity.chunk_pos.load(); let je_packet = CRemoveMobEffect::new(entity.entity_id.into(), VarInt(i32::from(effect_type.id))); - let be_packet = pumpkin_protocol::bedrock::client::CMobEffect::new( - VarULong(entity.entity_id as u64), - pumpkin_protocol::bedrock::client::CMobEffect::EVENT_REMOVE, - VarInt(effect_type.to_bedrock_id()), - VarInt(0), - false, - VarInt(0), - VarULong(0), - false, - ); + + let be_packet = pumpkin_protocol::bedrock::client::CMobEffect { + target_runtime_id: VarULong(entity.entity_id as u64), + event_id: pumpkin_protocol::bedrock::client::CMobEffect::EVENT_REMOVE, + effect_id: VarInt(effect_type.to_bedrock_id()), + effect_amplifier: VarInt(0), + show_particles: false, + effect_duration_ticks: VarInt(0), + tick: VarULong(0), + ambient: false, + }; self.broadcast_to_chunk_editioned_sync(chunk_pos, &je_packet, &be_packet); } @@ -599,16 +599,17 @@ impl World { VarInt(effect.duration), flags, ); - let be_packet = pumpkin_protocol::bedrock::client::CMobEffect::new( - VarULong(entity.entity_id as u64), - pumpkin_protocol::bedrock::client::CMobEffect::EVENT_ADD, - VarInt(effect.effect_type.to_bedrock_id()), - VarInt(i32::from(effect.amplifier)), - effect.show_particles, - VarInt(effect.duration), - VarULong(0), - effect.ambient, - ); + + let be_packet = pumpkin_protocol::bedrock::client::CMobEffect { + target_runtime_id: VarULong(entity.entity_id as u64), + event_id: pumpkin_protocol::bedrock::client::CMobEffect::EVENT_ADD, + effect_id: VarInt(effect.effect_type.to_bedrock_id()), + effect_amplifier: VarInt(i32::from(effect.amplifier)), + show_particles: effect.show_particles, + effect_duration_ticks: VarInt(effect.duration), + tick: VarULong(0), + ambient: effect.ambient, + }; self.broadcast_to_chunk_editioned_sync(chunk_pos, &je_packet, &be_packet); } @@ -674,7 +675,11 @@ impl World { event.data, VarInt(block.id.as_u16() as i32), ), - &CBedrockBlockEvent::new(event.pos, i32::from(event.r#type), i32::from(event.data)), + &CBedrockBlockEvent { + block_position: event.pos, + event_type: event.r#type.into(), + event_value: event.data.into(), + }, ); } } @@ -1099,11 +1104,11 @@ impl World { extra_data: i32, ) { let packet = CLevelSoundEvent { - sound_id: sound_id.to_string(), + sound_event: sound_id.to_string(), position: Vector3::new(position.x as f32, position.y as f32, position.z as f32), - extra_data: VarInt(extra_data), - entity_type: String::new(), - is_baby_mob: false, + data: VarInt(extra_data), + actor_identifier: String::new(), + is_baby: false, is_global: false, actor_unique_id: 0, fire_at_position: None, @@ -2282,8 +2287,10 @@ impl World { player: Arc, server: &Arc, ) { - static CREATIVE_CONTENT: std::sync::OnceLock<(Vec, Vec)> = - std::sync::OnceLock::new(); + static CREATIVE_CONTENT: std::sync::OnceLock<( + Vec, + Vec, + )> = std::sync::OnceLock::new(); static BEDROCK_CRAFTING_DATA: std::sync::OnceLock< Vec, @@ -2330,7 +2337,7 @@ impl World { custom_biome_name: String::new(), dimension: VarInt(0), generator_type: VarInt(1), - world_gamemode: server.defaultgamemode.lock().await.gamemode, + world_gamemode: server.defaultgamemode.lock().await.gamemode.into(), hardcore: base_config.hardcore, difficulty: VarInt(level_info.difficulty as i32), spawn_position: BlockPos::new( @@ -2355,11 +2362,9 @@ impl World { platform_broadcast_setting: GamePublishSetting::Public, commands_enabled: level_info.allow_commands, is_texture_packs_required: false, - rule_data: GameRules { - list_size: VarUInt(0), - }, + rule_data: Vec::new(), experiments: Experiments { - names_size: 0, + toggles: Vec::new(), experiments_ever_toggled: false, }, bonus_chest: false, @@ -2405,7 +2410,7 @@ impl World { let start_game = CStartGame { entity_id: VarLong(runtime_id as _), runtime_entity_id: VarULong(runtime_id), - player_gamemode: player.gamemode.load(), + player_gamemode: player.gamemode.load().into(), // Bedrock represents the local player at eye height; Pumpkin stores feet position. position: Vector3::new( position.x as f32, @@ -2455,10 +2460,10 @@ impl World { let item_registry = CItemRegistry { items: BedrockItem::ALL_BEDROCK_ITEMS .iter() - .map(|b| ItemDefinition { - name: b.registry_key.into(), - id: b.id, - component_based: b.component_based, + .map(|b| ItemData { + item_name: b.registry_key.into(), + item_id: b.id, + is_component_based: b.component_based, item_version: VarInt::from(match b.version { BedrockItemVersion::Legacy => 0, BedrockItemVersion::DataDriven => 1, @@ -2481,7 +2486,7 @@ impl World { 2 => CreativeCategory::Nature, 3 => CreativeCategory::Equipment, 4 => CreativeCategory::Items, - 5 => CreativeCategory::CommandOnly, + 5 => CreativeCategory::ItemCommandOnly, _ => CreativeCategory::Undefined, }; let icon_item = if g.icon_item_id != 0 { @@ -2499,10 +2504,10 @@ impl World { NetworkItemDescriptor::default() }; - Group { + CreativeGroupInfoPayload { creative_category, name: g.name.to_string(), - icon_item, + group_icon_item: icon_item, } }) .collect::>(); @@ -2510,7 +2515,7 @@ impl World { let entries = pumpkin_data::bedrock_creative::CREATIVE_ENTRIES .iter() .enumerate() - .map(|(i, e)| Entry { + .map(|(i, e)| CreativeItemEntryPayload { id: VarUInt((i + 1) as u32), item: NetworkItemDescriptor { id: VarInt::from(e.item_id), @@ -2726,11 +2731,11 @@ impl World { let metadata = entity.bedrock_metadata(); let actor_data = CSetActorData { - actor_runtime_id: VarULong(runtime_id), - metadata, + target_runtime_id: VarULong(runtime_id), + actor_data: metadata, synced_properties: PropertySyncData { - int_properties: HashMap::new(), - float_properties: HashMap::new(), + int_entries_list: HashMap::new(), + float_entries_list: HashMap::new(), }, tick: VarULong(0), }; @@ -2747,9 +2752,9 @@ impl World { client .enqueue_client_packet(&CUpdateAttributes { - runtime_id: VarULong(runtime_id), - attributes: vec![ - Attribute { + target_runtime_id: VarULong(runtime_id), + attribute_list: vec![ + AttributeData { min_value: 0.0, max_value: 3.402_823_5E38, current_value: 0.1, @@ -2757,9 +2762,9 @@ impl World { default_max_value: 3.402_823_5E38, default_value: 0.1, name: "minecraft:movement".to_string(), - modifiers_list_size: VarUInt(0), + modifiers: Vec::new(), }, - Attribute { + AttributeData { min_value: 0.0, max_value: 3.402_823_5E38, current_value: 0.02, @@ -2767,9 +2772,9 @@ impl World { default_max_value: 3.402_823_5E38, default_value: 0.02, name: "minecraft:underwater_movement".to_string(), - modifiers_list_size: VarUInt(0), + modifiers: Vec::new(), }, - Attribute { + AttributeData { min_value: 0.0, max_value: 1.0, current_value: 0.08, @@ -2777,9 +2782,9 @@ impl World { default_max_value: 1.0, default_value: 0.08, name: "minecraft:gravity".to_string(), - modifiers_list_size: VarUInt(0), + modifiers: Vec::new(), }, - Attribute { + AttributeData { min_value: 0.0, max_value: 400.0, current_value: 400.0, @@ -2787,9 +2792,9 @@ impl World { default_max_value: 400.0, default_value: 400.0, name: "minecraft:air".to_string(), - modifiers_list_size: VarUInt(0), + modifiers: Vec::new(), }, - Attribute { + AttributeData { min_value: 0.0, max_value: 20.0, current_value: player.living_entity.health.load(), @@ -2797,9 +2802,9 @@ impl World { default_max_value: 20.0, default_value: 20.0, name: "minecraft:health".to_string(), - modifiers_list_size: VarUInt(0), + modifiers: Vec::new(), }, - Attribute { + AttributeData { min_value: 0.0, max_value: 20.0, current_value: player.hunger_manager.level.load().into(), @@ -2807,10 +2812,10 @@ impl World { default_max_value: 20.0, default_value: 20.0, name: "minecraft:player.hunger".to_string(), - modifiers_list_size: VarUInt(0), + modifiers: Vec::new(), }, ], - player_tick: VarULong(0), + tick: VarULong(0), }) .await; @@ -2868,37 +2873,34 @@ impl World { let bedrock_add_player = CAddPlayer { uuid: gameprofile.id, - username: gameprofile.name.clone(), - entity_runtime_id: VarULong(runtime_id), + player_name: gameprofile.name.clone(), + target_runtime_id: VarULong(runtime_id), platform_chat_id: String::new(), position: Vector3::new(position.x as f32, position.y as f32, position.z as f32), velocity: Vector3::new(velocity.x as f32, velocity.y as f32, velocity.z as f32), - pitch, - yaw, - head_yaw: yaw, - held_item: NetworkItemDescriptor::default(), - game_mode: VarInt(match player.gamemode.load() { - GameMode::Survival => 0, - GameMode::Creative => 1, - GameMode::Adventure => 2, - GameMode::Spectator => 6, - }), - metadata: entity.bedrock_metadata(), - properties: EntityProperties::default(), - ability_data: pumpkin_protocol::bedrock::client::add_player::AbilityData { - entity_unique_id: runtime_id as i64, - player_permissions: 0, - command_permissions: 0, - layers: vec![pumpkin_protocol::bedrock::client::AbilityLayer { - serialized_layer: 0, - abilities_set: 0, - ability_value: 0, - fly_speed: 0.05, - vertical_fly_speed: 0.05, - walk_speed: 0.1, - }], + rotation: Vector2::new(pitch, yaw), + y_head_rotation: yaw, + carried_item: NetworkItemStackDescriptor::default(), + player_game_type: player.gamemode.load().into(), + entity_data: entity.bedrock_metadata(), + synced_properties: PropertySyncData::default(), + abilities_data: pumpkin_protocol::bedrock::client::SerializedAbilitiesData { + target_player_raw_id: runtime_id as i64, + player_permissions: + pumpkin_protocol::bedrock::client::PlayerPermissionLevel::Visitor, + command_permissions: pumpkin_protocol::bedrock::client::CommandPermissionLevel::Any, + layers: vec![ + pumpkin_protocol::bedrock::client::SerializedAbilitiesDataSerializedLayer { + serialized_layer: 0, + abilities_set: 0, + ability_value: 0, + fly_speed: 0.05, + vertical_fly_speed: 0.05, + walk_speed: 0.1, + }, + ], }, - links: Vec::new(), + actor_links: Vec::new(), device_id: String::new(), build_platform: BuildPlatform::Unknown, }; @@ -2964,37 +2966,35 @@ impl World { let ex_add_player = CAddPlayer { uuid: ex_profile.id, - username: ex_profile.name.clone(), - entity_runtime_id: VarULong(existing_player.entity_id() as u64), + player_name: ex_profile.name.clone(), + target_runtime_id: VarULong(existing_player.entity_id() as u64), platform_chat_id: String::new(), position: Vector3::new(ex_pos.x as f32, ex_pos.y as f32, ex_pos.z as f32), velocity: Vector3::new(ex_vel.x as f32, ex_vel.y as f32, ex_vel.z as f32), - pitch: ex_entity.pitch.load(), - yaw: ex_entity.yaw.load(), - head_yaw: ex_entity.head_yaw.load(), - held_item: NetworkItemDescriptor::default(), - game_mode: VarInt(match existing_player.gamemode.load() { - GameMode::Survival => 0, - GameMode::Creative => 1, - GameMode::Adventure => 2, - GameMode::Spectator => 6, - }), - metadata: ex_entity.bedrock_metadata(), - properties: EntityProperties::default(), - ability_data: pumpkin_protocol::bedrock::client::add_player::AbilityData { - entity_unique_id: existing_player.entity_id() as i64, - player_permissions: 0, - command_permissions: 0, - layers: vec![pumpkin_protocol::bedrock::client::AbilityLayer { - serialized_layer: 0, - abilities_set: 0, - ability_value: 0, - fly_speed: 0.05, - vertical_fly_speed: 0.05, - walk_speed: 0.1, - }], + rotation: Vector2::new(ex_entity.pitch.load(), ex_entity.yaw.load()), + y_head_rotation: ex_entity.head_yaw.load(), + carried_item: NetworkItemStackDescriptor::default(), + player_game_type: existing_player.gamemode.load().into(), + entity_data: ex_entity.bedrock_metadata(), + synced_properties: PropertySyncData::default(), + abilities_data: pumpkin_protocol::bedrock::client::SerializedAbilitiesData { + target_player_raw_id: existing_player.entity_id() as i64, + player_permissions: + pumpkin_protocol::bedrock::client::PlayerPermissionLevel::Visitor, + command_permissions: + pumpkin_protocol::bedrock::client::CommandPermissionLevel::Any, + layers: vec![ + pumpkin_protocol::bedrock::client::SerializedAbilitiesDataSerializedLayer { + serialized_layer: 0, + abilities_set: 0, + ability_value: 0, + fly_speed: 0.05, + vertical_fly_speed: 0.05, + walk_speed: 0.1, + }, + ], }, - links: Vec::new(), + actor_links: Vec::new(), device_id: String::new(), build_platform: BuildPlatform::Unknown, }; @@ -3003,13 +3003,13 @@ impl World { let ex_held_item = existing_player.inventory().held_item().await; - let ex_be_mob_equipment = pumpkin_protocol::bedrock::client::CMobEquipment::new( - existing_player.entity_id() as u64, - NetworkItemStackDescriptor::from(&ex_held_item), - 0, - 0, - 0, - ); + let ex_be_mob_equipment = pumpkin_protocol::bedrock::client::CMobEquipment { + target_runtime_id: (existing_player.entity_id() as u64).into(), + item: (&ex_held_item).into(), + slot: 0, + selected_slot: 0, + container_id: 0, + }; client.send_packet(&ex_be_mob_equipment).await; } @@ -3368,37 +3368,34 @@ impl World { let bedrock_add_player = CAddPlayer { uuid: gameprofile.id, - username: gameprofile.name.clone(), - entity_runtime_id: VarULong(entity_id as u64), + player_name: gameprofile.name.clone(), + target_runtime_id: VarULong(entity_id as u64), platform_chat_id: String::new(), position: Vector3::new(position.x as f32, position.y as f32, position.z as f32), velocity: Vector3::new(velocity.x as f32, velocity.y as f32, velocity.z as f32), - pitch, - yaw, - head_yaw: yaw, - held_item: NetworkItemDescriptor::default(), - game_mode: VarInt(match player.gamemode.load() { - GameMode::Survival => 0, - GameMode::Creative => 1, - GameMode::Adventure => 2, - GameMode::Spectator => 6, - }), - metadata: player.get_entity().bedrock_metadata(), - properties: EntityProperties::default(), - ability_data: pumpkin_protocol::bedrock::client::add_player::AbilityData { - entity_unique_id: entity_id as i64, - player_permissions: 0, - command_permissions: 0, - layers: vec![pumpkin_protocol::bedrock::client::AbilityLayer { - serialized_layer: 0, - abilities_set: 0, - ability_value: 0, - fly_speed: 0.05, - vertical_fly_speed: 0.05, - walk_speed: 0.1, - }], + rotation: Vector2::new(pitch, yaw), + y_head_rotation: yaw, + carried_item: NetworkItemStackDescriptor::default(), + player_game_type: player.gamemode.load().into(), + entity_data: player.get_entity().bedrock_metadata(), + synced_properties: PropertySyncData::default(), + abilities_data: pumpkin_protocol::bedrock::client::SerializedAbilitiesData { + target_player_raw_id: entity_id as i64, + player_permissions: + pumpkin_protocol::bedrock::client::PlayerPermissionLevel::Visitor, + command_permissions: pumpkin_protocol::bedrock::client::CommandPermissionLevel::Any, + layers: vec![ + pumpkin_protocol::bedrock::client::SerializedAbilitiesDataSerializedLayer { + serialized_layer: 0, + abilities_set: 0, + ability_value: 0, + fly_speed: 0.05, + vertical_fly_speed: 0.05, + walk_speed: 0.1, + }, + ], }, - links: Vec::new(), + actor_links: Vec::new(), device_id: String::new(), build_platform: BuildPlatform::Unknown, }; @@ -3430,11 +3427,11 @@ impl World { entity_id, skin_parts, &CSetActorData { - actor_runtime_id: VarULong(entity_id as u64), - metadata: player.get_entity().bedrock_metadata(), + target_runtime_id: VarULong(entity_id as u64), + actor_data: player.get_entity().bedrock_metadata(), synced_properties: PropertySyncData { - int_properties: HashMap::new(), - float_properties: HashMap::new(), + int_entries_list: HashMap::new(), + float_entries_list: HashMap::new(), }, tick: VarULong(0), }, @@ -3453,8 +3450,8 @@ impl World { let gameprofile = &existing_player.gameprofile; let bedrock_add_player = CAddPlayer { uuid: gameprofile.id, - username: gameprofile.name.clone(), - entity_runtime_id: VarULong(existing_player.entity_id() as u64), + player_name: gameprofile.name.clone(), + target_runtime_id: VarULong(existing_player.entity_id() as u64), platform_chat_id: String::new(), position: Vector3::new(pos.x as f32, pos.y as f32, pos.z as f32), velocity: Vector3::new( @@ -3462,32 +3459,30 @@ impl World { entity.velocity.load().y as f32, entity.velocity.load().z as f32, ), - pitch: entity.pitch.load(), - yaw: entity.yaw.load(), - head_yaw: entity.head_yaw.load(), - held_item: NetworkItemDescriptor::default(), - game_mode: VarInt(match existing_player.gamemode.load() { - GameMode::Survival => 0, - GameMode::Creative => 1, - GameMode::Adventure => 2, - GameMode::Spectator => 6, - }), - metadata: entity.bedrock_metadata(), - properties: EntityProperties::default(), - ability_data: pumpkin_protocol::bedrock::client::add_player::AbilityData { - entity_unique_id: existing_player.entity_id() as i64, - player_permissions: 0, - command_permissions: 0, - layers: vec![pumpkin_protocol::bedrock::client::AbilityLayer { - serialized_layer: 0, - abilities_set: 0, - ability_value: 0, - fly_speed: 0.05, - vertical_fly_speed: 0.05, - walk_speed: 0.1, - }], + rotation: Vector2::new(entity.pitch.load(), entity.yaw.load()), + y_head_rotation: entity.head_yaw.load(), + carried_item: NetworkItemStackDescriptor::default(), + player_game_type: existing_player.gamemode.load().into(), + entity_data: entity.bedrock_metadata(), + synced_properties: PropertySyncData::default(), + abilities_data: pumpkin_protocol::bedrock::client::SerializedAbilitiesData { + target_player_raw_id: existing_player.entity_id() as i64, + player_permissions: + pumpkin_protocol::bedrock::client::PlayerPermissionLevel::Visitor, + command_permissions: + pumpkin_protocol::bedrock::client::CommandPermissionLevel::Any, + layers: vec![ + pumpkin_protocol::bedrock::client::SerializedAbilitiesDataSerializedLayer { + serialized_layer: 0, + abilities_set: 0, + ability_value: 0, + fly_speed: 0.05, + vertical_fly_speed: 0.05, + walk_speed: 0.1, + }, + ], }, - links: Vec::new(), + actor_links: Vec::new(), device_id: String::new(), build_platform: BuildPlatform::Unknown, }; @@ -3608,13 +3603,13 @@ impl World { let je_packet = CSetEquipment::new(existing_player.entity_id().into(), equipment); - let be_mob_equipment = pumpkin_protocol::bedrock::client::CMobEquipment::new( - existing_player.entity_id() as u64, - NetworkItemStackDescriptor::from(&held_item), - 0, - 0, - 0, - ); + let be_mob_equipment = pumpkin_protocol::bedrock::client::CMobEquipment { + target_runtime_id: (existing_player.entity_id() as u64).into(), + item: (&held_item).into(), + slot: 0, + selected_slot: 0, + container_id: 0, + }; player .client @@ -3762,13 +3757,13 @@ impl World { .collect(); let je_packet = CSetEquipment::new(from.entity_id().into(), equipment); - let be_mob_equipment = pumpkin_protocol::bedrock::client::CMobEquipment::new( - from.entity_id() as u64, - NetworkItemStackDescriptor::from(&held_item), - 0, - 0, - 0, - ); + let be_mob_equipment = pumpkin_protocol::bedrock::client::CMobEquipment { + target_runtime_id: (from.entity_id() as u64).into(), + item: (&held_item).into(), + slot: 0, + selected_slot: 0, + container_id: 0, + }; let chunk_pos = from.get_entity().chunk_pos.load(); self.broadcast_to_chunk_except_editioned( @@ -4171,12 +4166,13 @@ impl World { pitch, target_world.dimension.minecraft_name.to_string(), ), - &pumpkin_protocol::bedrock::client::CSetSpawnPosition::new( - 1, // World spawn + &pumpkin_protocol::bedrock::client::CSetSpawnPosition { + spawn_position_type: + pumpkin_protocol::bedrock::client::SpawnPositionType::WorldRespawn, + block_position: spawn_block_pos, + dimension_type: bedrock_dimension.into(), spawn_block_pos, - bedrock_dimension, - spawn_block_pos, - ), + }, ) .await; diff --git a/crates/pumpkin/src/world/portal/mod.rs b/crates/pumpkin/src/world/portal/mod.rs index d314f63d7..0367abef2 100644 --- a/crates/pumpkin/src/world/portal/mod.rs +++ b/crates/pumpkin/src/world/portal/mod.rs @@ -146,12 +146,12 @@ impl PortalType { crate::net::ClientPlatform::Bedrock(client) => { client .send_packet( - &pumpkin_protocol::bedrock::client::CShowCredits::new( - pumpkin_protocol::codec::var_ulong::VarULong( - caller.get_entity().entity_id as u64, - ), - pumpkin_protocol::codec::var_int::VarInt(0), - ), + &pumpkin_protocol::bedrock::client::CShowCredits { + player_runtime_id: (caller.get_entity().entity_id + as u64) + .into(), + credits_state: 0.into(), + }, ) .await; } diff --git a/crates/pumpkin/src/world/scoreboard.rs b/crates/pumpkin/src/world/scoreboard.rs index 9b401d442..bbb002478 100644 --- a/crates/pumpkin/src/world/scoreboard.rs +++ b/crates/pumpkin/src/world/scoreboard.rs @@ -3,9 +3,10 @@ use std::collections::HashMap; use pumpkin_data::scoreboard::ScoreboardDisplaySlot; use pumpkin_protocol::{ BClientPacket, ClientPacket, NumberFormat, - bedrock::client::scoreboard::{ - CRemoveObjective as BRemoveObjective, CSetDisplayObjective as BSetDisplayObjective, - CSetScore as BSetScore, ScoreEntry as BScoreEntry, + bedrock::client::{ + remove_objective::CRemoveObjective as BRemoveObjective, + set_display_objective::CSetDisplayObjective as BSetDisplayObjective, + set_score::{CSetScore as BSetScore, ScoreEntry as BScoreEntry}, }, codec::var_int::VarInt, java::client::play::{ @@ -228,9 +229,9 @@ impl Scoreboard { ); let be_update = BSetDisplayObjective { - display_slot: "sidebar".to_string(), // Default to sidebar + display_slot_name: "sidebar".to_string(), // Default to sidebar objective_name: objective.name.clone(), - display_name: objective.display_name.clone().get_text(), + objective_display_name: objective.display_name.clone().get_text(), criteria_name: "dummy".to_string(), sort_order: VarInt(0), }; @@ -262,9 +263,9 @@ impl Scoreboard { ); let be_update = BSetDisplayObjective { - display_slot: "sidebar".to_string(), + display_slot_name: "sidebar".to_string(), objective_name: objective.name.clone(), - display_name: objective.display_name.clone().get_text(), + objective_display_name: objective.display_name.clone().get_text(), criteria_name: "dummy".to_string(), sort_order: VarInt(0), }; @@ -297,9 +298,9 @@ impl Scoreboard { let je_display = CDisplayObjective::new(slot, obj_name_str.to_string()); let be_display = BSetDisplayObjective { - display_slot: slot_str.to_string(), + display_slot_name: slot_str.to_string(), objective_name: obj_name_str.to_string(), - display_name, + objective_display_name: display_name, criteria_name: "dummy".to_string(), sort_order: VarInt(0), }; @@ -656,9 +657,9 @@ impl Scoreboard { objective.number_format.clone(), ); let be_update = BSetDisplayObjective { - display_slot: "sidebar".to_string(), + display_slot_name: "sidebar".to_string(), objective_name: objective.name.clone(), - display_name: objective.display_name.clone().get_text(), + objective_display_name: objective.display_name.clone().get_text(), criteria_name: "dummy".to_string(), sort_order: VarInt(0), }; @@ -677,9 +678,9 @@ impl Scoreboard { ); let je_display = CDisplayObjective::new(*slot, objective_name.clone()); let be_display = BSetDisplayObjective { - display_slot: slot_str.to_string(), + display_slot_name: slot_str.to_string(), objective_name: objective_name.clone(), - display_name, + objective_display_name: display_name, criteria_name: "dummy".to_string(), sort_order: VarInt(0), }; @@ -883,9 +884,9 @@ pub struct BedrockScoreboard { impl BedrockScoreboard { pub async fn add_objective(&mut self, player: &Player, objective: BedrockObjective) { let be_update = BSetDisplayObjective { - display_slot: "sidebar".to_string(), + display_slot_name: "sidebar".to_string(), objective_name: objective.name.clone(), - display_name: objective.display_name.clone(), + objective_display_name: objective.display_name.clone(), criteria_name: "dummy".to_string(), sort_order: VarInt(match objective.sort_order { BedrockSortOrder::Ascending => 0, @@ -910,9 +911,9 @@ impl BedrockScoreboard { pub async fn update_objective(&mut self, player: &Player, objective: BedrockObjective) { let be_update = BSetDisplayObjective { - display_slot: "sidebar".to_string(), + display_slot_name: "sidebar".to_string(), objective_name: objective.name.clone(), - display_name: objective.display_name.clone(), + objective_display_name: objective.display_name.clone(), criteria_name: "dummy".to_string(), sort_order: VarInt(match objective.sort_order { BedrockSortOrder::Ascending => 0, @@ -968,9 +969,9 @@ impl BedrockScoreboard { .map_or_else(|| obj_name_str.to_string(), |o| o.display_name.clone()); let be_display = BSetDisplayObjective { - display_slot: slot.to_str().to_string(), + display_slot_name: slot.to_str().to_string(), objective_name: obj_name_str.to_string(), - display_name, + objective_display_name: display_name, criteria_name: "dummy".to_string(), sort_order: VarInt(0), }; @@ -1091,9 +1092,9 @@ impl BedrockScoreboard { pub async fn send_to_player(&self, player: &Player) { for objective in self.objectives.values() { let be_update = BSetDisplayObjective { - display_slot: "sidebar".to_string(), + display_slot_name: "sidebar".to_string(), objective_name: objective.name.clone(), - display_name: objective.display_name.clone(), + objective_display_name: objective.display_name.clone(), criteria_name: "dummy".to_string(), sort_order: VarInt(match objective.sort_order { BedrockSortOrder::Ascending => 0, @@ -1120,9 +1121,9 @@ impl BedrockScoreboard { .get(objective_name) .map_or_else(|| objective_name.clone(), |o| o.display_name.clone()); let be_display = BSetDisplayObjective { - display_slot: slot.to_str().to_string(), + display_slot_name: slot.to_str().to_string(), objective_name: objective_name.clone(), - display_name, + objective_display_name: display_name, criteria_name: "dummy".to_string(), sort_order: VarInt(0), };