mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
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 <demetrius@kanios.net>
This commit is contained in:
Submodule crates/pumpkin-plugin-wit updated: 060c913c30...10f15637dc
@@ -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<f32>,
|
||||
pub velocity: Vector3<f32>,
|
||||
pub pitch: f32,
|
||||
pub yaw: f32,
|
||||
pub head_yaw: f32,
|
||||
pub body_yaw: f32,
|
||||
pub attributes: Vec<AttributeValue>,
|
||||
pub metadata: EntityMetadata,
|
||||
pub rotation: Vector2<f32>,
|
||||
pub y_head_rotation: f32,
|
||||
pub y_body_rotation: f32,
|
||||
pub attributes_list: Vec<SyncedAttribute>,
|
||||
pub actor_data: SyncedActorDataList,
|
||||
pub synced_properties: PropertySyncData,
|
||||
pub links: Vec<EntityLink>,
|
||||
}
|
||||
|
||||
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<f32>,
|
||||
velocity: Vector3<f32>,
|
||||
pitch: f32,
|
||||
yaw: f32,
|
||||
head_yaw: f32,
|
||||
body_yaw: f32,
|
||||
attributes: Vec<AttributeValue>,
|
||||
metadata: EntityMetadata,
|
||||
synced_properties: PropertySyncData,
|
||||
links: Vec<EntityLink>,
|
||||
) -> 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<ActorLink>,
|
||||
}
|
||||
|
||||
#[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,
|
||||
}
|
||||
|
||||
@@ -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<f32>,
|
||||
pub velocity: Vector3<f32>,
|
||||
pub metadata: EntityMetadata,
|
||||
pub from_fishing: bool,
|
||||
pub entity_data: SyncedActorDataList,
|
||||
pub is_from_fishing: bool,
|
||||
}
|
||||
|
||||
@@ -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<f32>,
|
||||
pub velocity: Vector3<f32>,
|
||||
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<EntityLink>,
|
||||
pub rotation: Vector2<f32>,
|
||||
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<ActorLink>,
|
||||
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<f32>,
|
||||
velocity: Vector3<f32>,
|
||||
pitch: f32,
|
||||
yaw: f32,
|
||||
head_yaw: f32,
|
||||
held_item: NetworkItemDescriptor,
|
||||
game_mode: VarInt,
|
||||
metadata: EntityMetadata,
|
||||
properties: EntityProperties,
|
||||
ability_data: AbilityData,
|
||||
links: Vec<EntityLink>,
|
||||
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<W: 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<AbilityLayer>,
|
||||
}
|
||||
|
||||
@@ -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<String>,
|
||||
pub chained_subcommand_values: Vec<String>,
|
||||
pub suffixes: Vec<String>,
|
||||
pub enums: Vec<CommandEnum>,
|
||||
pub chained_subcommands: Vec<ChainedSubcommand>,
|
||||
pub commands: Vec<Command>,
|
||||
pub soft_enums: Vec<SoftEnum>,
|
||||
pub constraints: Vec<CommandEnumConstraint>,
|
||||
pub post_fixes: Vec<String>,
|
||||
pub enum_data: Vec<EnumData>,
|
||||
pub chained_subcommand_data: Vec<ChainedSubcommandData>,
|
||||
pub commands: Vec<CommandData>,
|
||||
pub soft_enums: Vec<SoftEnumData>,
|
||||
pub constraints: Vec<ConstrainedValueData>,
|
||||
}
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
pub struct EnumData {
|
||||
pub name: String,
|
||||
pub values: Vec<u32>,
|
||||
}
|
||||
|
||||
// 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<ChainedSubcommandValue>,
|
||||
pub subcommand_values: Vec<ChainedSubcommandRelationship>,
|
||||
}
|
||||
|
||||
#[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<u32>,
|
||||
}
|
||||
|
||||
#[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<u32>,
|
||||
pub overloads: Vec<CommandOverload>,
|
||||
pub permission_level: EnumAsStr<CommandPermissionLevel>,
|
||||
/// -1 means no aliases
|
||||
pub alias_enum: i32,
|
||||
pub command_data_chained_subcommand_indexes: Vec<u32>,
|
||||
pub overloads: Vec<OverloadData>,
|
||||
}
|
||||
|
||||
#[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<CommandParameter>,
|
||||
pub struct OverloadData {
|
||||
pub is_chaining: bool,
|
||||
pub parameter_data: Vec<ParamData>,
|
||||
}
|
||||
|
||||
#[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<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PacketWrite)]
|
||||
pub struct SoftEnum {
|
||||
pub name: String,
|
||||
pub values: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PacketWrite)]
|
||||
pub struct CommandEnumConstraint {
|
||||
pub affected_value_index: i32,
|
||||
pub enum_index: i32,
|
||||
pub constraints: Vec<u8>,
|
||||
pub struct ConstrainedValueData {
|
||||
pub enum_value_symbol: u32,
|
||||
pub enum_symbol: u32,
|
||||
pub constraint_indices: Vec<u8>,
|
||||
}
|
||||
|
||||
@@ -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..]));
|
||||
|
||||
@@ -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!(<CBlockEvent as Packet>::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]);
|
||||
}
|
||||
|
||||
@@ -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<f32>,
|
||||
pub respawn: bool,
|
||||
pub loading_screen_id: Option<u32>,
|
||||
}
|
||||
|
||||
impl CChangeDimension {
|
||||
#[must_use]
|
||||
pub const fn new(dimension: i32, position: Vector3<f32>, respawn: bool) -> Self {
|
||||
Self {
|
||||
dimension: VarInt(dimension),
|
||||
position,
|
||||
respawn,
|
||||
loading_screen_id: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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<u8>,
|
||||
#[derive(PacketWrite, Clone, Debug)]
|
||||
pub struct MissingBlobData {
|
||||
pub blob_id: u64,
|
||||
pub blob_data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
#[packet(136)]
|
||||
pub struct CClientCacheMissResponse<'a> {
|
||||
pub blobs: &'a [CacheBlob],
|
||||
}
|
||||
|
||||
impl PacketWrite for CClientCacheMissResponse<'_> {
|
||||
fn write<W: 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<MissingBlobData>,
|
||||
}
|
||||
|
||||
@@ -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<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
VarInt(*self as i32).write(writer)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GameMode> 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<SerializedAbilitiesDataSerializedLayer>,
|
||||
}
|
||||
|
||||
#[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<W: 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<W: 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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<f32>,
|
||||
pub pos_delta: Vector3<f32>,
|
||||
@@ -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<W: 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<W: 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<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.id.write(writer)?;
|
||||
self.item.write_item_instance(writer)?;
|
||||
|
||||
@@ -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<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.reason.write(writer)?;
|
||||
self.skip_message.write(writer)?;
|
||||
@@ -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<GameRule>,
|
||||
}
|
||||
|
||||
#[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<W: std::io::prelude::Write>(&self, writer: &mut W) -> Result<(), std::io::Error> {
|
||||
VarUInt(0).write(writer)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<NetworkItemStackDescriptor>,
|
||||
pub full_container_name: FullContainerName,
|
||||
|
||||
@@ -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<FullContainerName>,
|
||||
pub storage: Option<NetworkItemStackDescriptor>,
|
||||
pub container_id: VarUInt,
|
||||
pub slot: VarUInt,
|
||||
pub full_container_name: Option<FullContainerName>,
|
||||
pub storage_item: Option<NetworkItemStackDescriptor>,
|
||||
pub item: NetworkItemStackDescriptor,
|
||||
}
|
||||
|
||||
@@ -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<ItemDefinition>,
|
||||
pub items: Vec<ItemData>,
|
||||
}
|
||||
|
||||
#[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`)
|
||||
|
||||
@@ -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<ItemStackResponseSlotInfo>,
|
||||
}
|
||||
|
||||
#[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<ItemStackResponseContainerInfo>,
|
||||
pub client_request_id: VarInt,
|
||||
pub containers: Vec<ItemStackResponseContainerInfo>,
|
||||
}
|
||||
|
||||
impl PacketWrite for ItemStackResponse {
|
||||
impl PacketWrite for ItemStackResponseInfo {
|
||||
fn write<W: 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<ItemStackResponse>,
|
||||
pub responses: Vec<ItemStackResponseInfo>,
|
||||
}
|
||||
|
||||
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),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Last verified for v2169
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
|
||||
|
||||
@@ -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: <https://mojang.github.io/bedrock-protocol-docs/html/LevelSoundEventPacket.html>
|
||||
#[derive(PacketWrite)]
|
||||
#[packet(123)]
|
||||
pub struct CLevelSoundEvent {
|
||||
pub sound_id: String,
|
||||
pub sound_event: String,
|
||||
pub position: Vector3<f32>,
|
||||
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<Vector3<f32>>,
|
||||
@@ -29,11 +27,11 @@ mod tests {
|
||||
assert_eq!(<CLevelSoundEvent as crate::Packet>::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)),
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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<f32>,
|
||||
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<f32>,
|
||||
pitch: u8,
|
||||
yaw: u8,
|
||||
head_yaw: u8,
|
||||
) -> Self {
|
||||
Self {
|
||||
entity_runtime_id,
|
||||
flags,
|
||||
position,
|
||||
pitch,
|
||||
yaw,
|
||||
head_yaw,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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<ResourcePackStackEntry>,
|
||||
pub game_version: String,
|
||||
pub texture_pack_required: bool,
|
||||
pub texture_pack_list: Vec<PackInstanceId>,
|
||||
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<ResourcePackStackEntry>,
|
||||
game_version: String,
|
||||
experiments: Experiments,
|
||||
include_editor_packs: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
resource_pack_required,
|
||||
resource_packs,
|
||||
game_version,
|
||||
experiments,
|
||||
include_editor_packs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ResourcePackEntry>,
|
||||
pub force_disable_vibrant_visuals: bool,
|
||||
pub world_template_id_and_version: PackIdVersion,
|
||||
pub resource_packs: Vec<PackInfoData>,
|
||||
}
|
||||
|
||||
impl PacketWrite for CResourcePacksInfo {
|
||||
fn write<W: 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(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<f32>,
|
||||
pub state: RespawnState,
|
||||
pub player_runtime_id: VarULong,
|
||||
}
|
||||
|
||||
impl CRespawn {
|
||||
#[must_use]
|
||||
pub const fn new(
|
||||
position: Vector3<f32>,
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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<u32, MetadataValue>);
|
||||
pub struct SyncedActorDataList(pub HashMap<u32, MetadataValue>);
|
||||
|
||||
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<W: 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<f32>),
|
||||
}
|
||||
|
||||
@@ -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<u32, i32>,
|
||||
pub float_properties: std::collections::HashMap<u32, f32>,
|
||||
pub int_entries_list: std::collections::HashMap<u32, i32>,
|
||||
pub float_entries_list: std::collections::HashMap<u32, f32>,
|
||||
}
|
||||
|
||||
impl PacketWrite for PropertySyncData {
|
||||
fn write<W: 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));
|
||||
|
||||
@@ -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: <https://mojang.github.io/bedrock-protocol-docs/html/SetActorLinkPacket.html>
|
||||
#[derive(PacketWrite)]
|
||||
#[packet(41)]
|
||||
pub struct CSetActorLink {
|
||||
pub link: EntityLink,
|
||||
pub link: ActorLink,
|
||||
}
|
||||
|
||||
@@ -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<f32>,
|
||||
pub tick: VarULong,
|
||||
}
|
||||
|
||||
impl CSetActorMotion {
|
||||
#[must_use]
|
||||
pub const fn new(target_runtime_id: VarULong, motion: Vector3<f32>, tick: VarULong) -> Self {
|
||||
Self {
|
||||
target_runtime_id,
|
||||
motion,
|
||||
tick,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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<String>) -> Self {
|
||||
Self {
|
||||
objective_name: objective_name.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
VarInt(*self as i32).write(writer)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Last verified for v2169
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
|
||||
use crate::{codec::var_int::VarInt, serial::PacketWrite};
|
||||
|
||||
@@ -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<W: 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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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<f32>,
|
||||
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<GameRule>,
|
||||
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<ExperimentToggle>,
|
||||
pub experiments_ever_toggled: bool,
|
||||
}
|
||||
|
||||
impl PacketWrite for Experiments {
|
||||
fn write<W: 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,
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<W: 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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<AbilityLayer>,
|
||||
pub data: SerializedAbilitiesData,
|
||||
}
|
||||
|
||||
// TODO: confirm these
|
||||
#[repr(u32)]
|
||||
pub enum Ability {
|
||||
Build = 0,
|
||||
|
||||
@@ -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<Attribute>,
|
||||
pub player_tick: VarULong,
|
||||
pub target_runtime_id: VarULong,
|
||||
pub attribute_list: Vec<AttributeData>,
|
||||
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<AttributeModifier>,
|
||||
}
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
pub struct AttributeModifier {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub amount: f32,
|
||||
pub operation: i32,
|
||||
pub operand: i32,
|
||||
pub is_serializable: bool,
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Last verified for v2169
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_nbt::compound::NbtCompound;
|
||||
|
||||
|
||||
44
crates/pumpkin-protocol/src/bedrock/enum_as_str.rs
Normal file
44
crates/pumpkin-protocol/src/bedrock/enum_as_str.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
use crate::serial::{PacketRead, PacketWrite};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct EnumAsStr<T>(T);
|
||||
|
||||
impl<T: FromStr> FromStr for EnumAsStr<T>
|
||||
where
|
||||
std::io::Error: From<T::Err>,
|
||||
{
|
||||
type Err = std::io::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(Self(T::from_str(s)?))
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::to_string_trait_impl)]
|
||||
impl<T: ToString> ToString for EnumAsStr<T> {
|
||||
fn to_string(&self) -> String {
|
||||
self.0.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: FromStr> PacketRead for EnumAsStr<T>
|
||||
where
|
||||
std::io::Error: From<T::Err>,
|
||||
{
|
||||
fn read<R: std::io::Read>(reader: &mut R) -> Result<Self, std::io::Error> {
|
||||
Self::from_str(&String::read(reader)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToString> PacketWrite for EnumAsStr<T> {
|
||||
fn write<W: std::io::Write>(&self, writer: &mut W) -> Result<(), std::io::Error> {
|
||||
self.to_string().write(writer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<T> for EnumAsStr<T> {
|
||||
fn from(value: T) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
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<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
(*self as u8).write(writer)
|
||||
}
|
||||
}
|
||||
@@ -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<Vector3<f32>>,
|
||||
}
|
||||
|
||||
#[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<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
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<W: 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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
match String::read(reader)?.as_str() {
|
||||
impl FromStr for ActorSwingSource {
|
||||
type Err = Error;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
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<W: 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<AnimateSwingSource>,
|
||||
pub swing_source: Option<EnumAsStr<ActorSwingSource>>,
|
||||
}
|
||||
|
||||
#[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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<Uuid>,
|
||||
pub runtime_id: VarULong,
|
||||
pub emote_piece_ids: Vec<Uuid>,
|
||||
}
|
||||
|
||||
#[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);
|
||||
}
|
||||
}
|
||||
|
||||
39
crates/pumpkin-protocol/src/bedrock/server/interact.rs
Normal file
39
crates/pumpkin-protocol/src/bedrock/server/interact.rs
Normal file
@@ -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<Vector3<f32>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(u8)]
|
||||
pub enum Action {
|
||||
Invalid = 0,
|
||||
StopRiding = 3,
|
||||
InteractUpdate = 4,
|
||||
NpcOpen = 5,
|
||||
OpenInventory = 6,
|
||||
}
|
||||
|
||||
impl PacketRead for Action {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
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("")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Vector3<f32>>,
|
||||
}
|
||||
|
||||
#[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<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -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<u32>,
|
||||
loading_screen_packet_type: LoadingScreenPacketType,
|
||||
_loading_screen_id: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(i32)]
|
||||
pub enum LoadingScreenPacketType {
|
||||
StartLoadingScreen = 0,
|
||||
EndLoadingScreen = 1,
|
||||
}
|
||||
|
||||
impl PacketRead for LoadingScreenPacketType {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
@@ -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<Cow<'a, str>>,
|
||||
pub cancel_reason: Option<u8>,
|
||||
pub json_response: Option<Cow<'a, str>>,
|
||||
|
||||
// TODO: enum ModalFormCancelReason
|
||||
pub form_cancel_reason: Option<u8>,
|
||||
}
|
||||
|
||||
@@ -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<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
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,
|
||||
}
|
||||
|
||||
@@ -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<i32> for Action {
|
||||
impl TryFrom<i32> for PlayerActionType {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(value: i32) -> Result<Self, Self::Error> {
|
||||
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<i32> for Action {
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketRead for Action {
|
||||
impl PacketRead for PlayerActionType {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
let action = VarInt::read(reader)?;
|
||||
|
||||
|
||||
@@ -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: <https://mojang.github.io/bedrock-protocol-docs/html/PlayerHotbarPacket.html>
|
||||
#[derive(PacketRead)]
|
||||
#[packet(48)]
|
||||
pub struct SPlayerHotbar {
|
||||
pub selected_slot: VarUInt,
|
||||
pub container_id: u8,
|
||||
pub select_slot: bool,
|
||||
pub should_select_slot: bool,
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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<String>,
|
||||
}
|
||||
|
||||
impl PacketRead for SResourcePackResponse {
|
||||
impl PacketRead for SResourcePackClientResponse {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
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;
|
||||
@@ -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<f32>,
|
||||
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<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
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<W: 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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<W: 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<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.as_ref().write(writer)
|
||||
|
||||
@@ -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<String>,
|
||||
enums: &'a mut Vec<CommandEnum>,
|
||||
enums: &'a mut Vec<EnumData>,
|
||||
}
|
||||
|
||||
#[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<String> = Vec::new();
|
||||
let mut enums: Vec<CommandEnum> = Vec::new();
|
||||
let mut commands: Vec<Command> = Vec::new();
|
||||
let mut enums: Vec<EnumData> = Vec::new();
|
||||
let mut commands: Vec<CommandData> = 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<CommandOverload> {
|
||||
) -> Vec<OverloadData> {
|
||||
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<CommandParameter>,
|
||||
overloads: &mut Vec<CommandOverload>,
|
||||
current_params: &mut Vec<ParamData>,
|
||||
overloads: &mut Vec<OverloadData>,
|
||||
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<CommandOverload> {
|
||||
) -> Vec<OverloadData> {
|
||||
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<CommandOverload>,
|
||||
current_params: &[ParamData],
|
||||
overloads: &mut Vec<OverloadData>,
|
||||
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<NodeId> = 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<NodeId> = 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<NodeId> = 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<String>, value: &str) -> u32 {
|
||||
}
|
||||
|
||||
fn ensure_command_enum(
|
||||
enums: &mut Vec<CommandEnum>,
|
||||
enums: &mut Vec<EnumData>,
|
||||
enum_values: &mut Vec<String>,
|
||||
name: &str,
|
||||
values: &[String],
|
||||
@@ -650,14 +650,12 @@ fn ensure_command_enum(
|
||||
return pos;
|
||||
}
|
||||
|
||||
let value_indices: Vec<u32> = 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
|
||||
|
||||
@@ -94,10 +94,10 @@ pub async fn send_attribute_updates_for_living(
|
||||
attributes: Vec<Attributes>,
|
||||
) {
|
||||
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
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -603,7 +603,7 @@ pub trait Mob: EntityBase + Send + Sync {
|
||||
&self,
|
||||
) -> EntityBaseFuture<
|
||||
'_,
|
||||
Option<pumpkin_protocol::bedrock::client::set_actor_data::EntityMetadata>,
|
||||
Option<pumpkin_protocol::bedrock::client::set_actor_data::SyncedActorDataList>,
|
||||
> {
|
||||
Box::pin(async { None })
|
||||
}
|
||||
|
||||
@@ -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<T: MetadataSerializer>(
|
||||
&self,
|
||||
meta: &[Metadata<T>],
|
||||
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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<EntityMetadata>> {
|
||||
) -> crate::entity::EntityBaseFuture<'_, Option<SyncedActorDataList>> {
|
||||
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),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user