mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
chore(protocol): Clean up Bedrock by using more derive (#2808)
This commit is contained in:
@@ -509,8 +509,18 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
||||
.into();
|
||||
};
|
||||
|
||||
let type_generic = match input.generics.params.len() {
|
||||
0 => quote! {},
|
||||
1 => quote! { <'_> },
|
||||
_ => {
|
||||
return syn::Error::new(name.span(), "Only up to one lifetime parameter is supported.")
|
||||
.to_compile_error()
|
||||
.into();
|
||||
}
|
||||
};
|
||||
|
||||
let expanded = quote! {
|
||||
impl PacketWrite for #name {
|
||||
impl PacketWrite for #name #type_generic {
|
||||
fn write<W: std::io::Write>(&self, writer: &mut W) -> Result<(), std::io::Error> {
|
||||
#(#fields)*
|
||||
Ok(())
|
||||
@@ -537,26 +547,19 @@ pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
||||
let (is_big_endian, no_prefix) = check_serial_attributes(&f.attrs);
|
||||
let is_vec = is_vec(&f.ty);
|
||||
|
||||
if is_vec && !no_prefix {
|
||||
// Vec with prefix: read VarUInt length, then data
|
||||
if is_vec && no_prefix {
|
||||
return syn::Error::new(name.span(), "Cannot handle non-prefixed vecs")
|
||||
.to_compile_error();
|
||||
}
|
||||
|
||||
// Non-Vec or Vec without no_prefix: read directly
|
||||
if is_big_endian {
|
||||
quote! {
|
||||
#ident: {
|
||||
let len = crate::codec::var_uint::VarUInt::read(reader)?.0 as usize;
|
||||
let mut buf = vec![0u8; len];
|
||||
reader.read_exact(&mut buf)?;
|
||||
buf
|
||||
}
|
||||
#ident: PacketRead::read_be(reader)?
|
||||
}
|
||||
} else {
|
||||
// Non-Vec or Vec with no_prefix: read directly
|
||||
if is_big_endian {
|
||||
quote! {
|
||||
#ident: PacketRead::read_be(reader)?
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#ident: PacketRead::read(reader)?
|
||||
}
|
||||
quote! {
|
||||
#ident: PacketRead::read(reader)?
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -566,8 +569,19 @@ pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
||||
.into();
|
||||
};
|
||||
|
||||
|
||||
let type_generic = match input.generics.params.len() {
|
||||
0 => quote! {},
|
||||
1 => quote! { <'static> },
|
||||
_ => {
|
||||
return syn::Error::new(name.span(), "Only up to one lifetime parameter is supported.")
|
||||
.to_compile_error()
|
||||
.into();
|
||||
}
|
||||
};
|
||||
|
||||
let expanded = quote! {
|
||||
impl PacketRead for #name {
|
||||
impl PacketRead for #name #type_generic {
|
||||
fn read<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
|
||||
Ok(Self {
|
||||
#(#fields),*
|
||||
@@ -579,6 +593,56 @@ pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
||||
expanded.into()
|
||||
}
|
||||
|
||||
/// Derives the `PacketReadSlice` trait for a struct, enabling deserialization from a slice.
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `input` – The input `TokenStream` representing the struct to derive `PacketReadSlice` for.
|
||||
#[rustfmt::skip]
|
||||
#[proc_macro_derive(PacketReadSlice, attributes(serial))]
|
||||
pub fn derive_deserialize_from_slice(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
let name = &input.ident;
|
||||
|
||||
let fields = if let syn::Data::Struct(data) = &input.data {
|
||||
data.fields.iter().map(|f| {
|
||||
let ident = f.ident.as_ref().unwrap();
|
||||
let (is_big_endian, no_prefix) = check_serial_attributes(&f.attrs);
|
||||
let is_vec = is_vec(&f.ty);
|
||||
|
||||
if is_vec && no_prefix {
|
||||
return syn::Error::new(name.span(), "Cannot handle non-prefixed vecs.")
|
||||
.to_compile_error();
|
||||
}
|
||||
|
||||
// Non-Vec or Vec without no_prefix: read directly
|
||||
if is_big_endian {
|
||||
return syn::Error::new(name.span(), "Cannot handle big-endian encoded fields")
|
||||
.to_compile_error();
|
||||
}
|
||||
|
||||
quote! {
|
||||
#ident: PacketReadSlice::read_slice(buf)?
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return syn::Error::new(name.span(), "Only structs are supported")
|
||||
.to_compile_error()
|
||||
.into();
|
||||
};
|
||||
|
||||
let expanded = quote! {
|
||||
impl<'a> PacketReadSlice<'a> for #name<'a> {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> std::io::Result<Self> {
|
||||
Ok(Self {
|
||||
#(#fields),*
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expanded.into()
|
||||
}
|
||||
|
||||
/// Checks a field's `#[serial(...)]` attributes.
|
||||
///
|
||||
/// # Arguments
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::codec::var_int::VarInt;
|
||||
|
||||
#[derive(Debug, PacketWrite)]
|
||||
#[packet(27)]
|
||||
pub struct SActorEvent {
|
||||
pub struct CActorEvent {
|
||||
pub entity_runtime_id: VarULong,
|
||||
pub event_type: ActorEventType,
|
||||
pub event_data: VarInt,
|
||||
@@ -1,16 +1,16 @@
|
||||
use crate::{
|
||||
codec::{var_long::VarLong, var_uint::VarUInt, var_ulong::VarULong},
|
||||
codec::{var_long::VarLong, var_ulong::VarULong},
|
||||
serial::PacketWrite,
|
||||
};
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
use std::io::{Error, Write};
|
||||
|
||||
use super::{
|
||||
common::EntityLink,
|
||||
set_actor_data::{EntityMetadata, PropertySyncData},
|
||||
};
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
#[packet(13)]
|
||||
pub struct CAddActor {
|
||||
pub entity_unique_id: VarLong,
|
||||
@@ -28,31 +28,6 @@ pub struct CAddActor {
|
||||
pub links: Vec<EntityLink>,
|
||||
}
|
||||
|
||||
impl PacketWrite for CAddActor {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.entity_unique_id.write(writer)?;
|
||||
self.entity_runtime_id.write(writer)?;
|
||||
self.entity_type.write(writer)?;
|
||||
self.position.write(writer)?;
|
||||
self.velocity.write(writer)?;
|
||||
self.pitch.write(writer)?;
|
||||
self.yaw.write(writer)?;
|
||||
self.head_yaw.write(writer)?;
|
||||
self.body_yaw.write(writer)?;
|
||||
VarUInt(self.attributes.len() as u32).write(writer)?;
|
||||
for attr in &self.attributes {
|
||||
attr.write(writer)?;
|
||||
}
|
||||
self.metadata.write(writer)?;
|
||||
self.synced_properties.write(writer)?;
|
||||
VarUInt(self.links.len() as u32).write(writer)?;
|
||||
for link in &self.links {
|
||||
link.write(writer)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl CAddActor {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[must_use]
|
||||
|
||||
@@ -4,11 +4,11 @@ use crate::{
|
||||
};
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
use std::io::{Error, Write};
|
||||
|
||||
use super::set_actor_data::EntityMetadata;
|
||||
use crate::bedrock::network_item::ItemStackWrapper;
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
#[packet(15)]
|
||||
pub struct CAddItemActor {
|
||||
pub entity_unique_id: VarLong,
|
||||
@@ -19,16 +19,3 @@ pub struct CAddItemActor {
|
||||
pub metadata: EntityMetadata,
|
||||
pub from_fishing: bool,
|
||||
}
|
||||
|
||||
impl PacketWrite for CAddItemActor {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.entity_unique_id.write(writer)?;
|
||||
self.entity_runtime_id.write(writer)?;
|
||||
self.item.write(writer)?;
|
||||
self.position.write(writer)?;
|
||||
self.velocity.write(writer)?;
|
||||
self.metadata.write(writer)?;
|
||||
self.from_fishing.write(writer)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ use super::{
|
||||
set_actor_data::EntityMetadata,
|
||||
};
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
#[packet(12)]
|
||||
pub struct CAddPlayer {
|
||||
pub uuid: Uuid,
|
||||
@@ -34,31 +35,6 @@ pub struct CAddPlayer {
|
||||
pub build_platform: BuildPlatform,
|
||||
}
|
||||
|
||||
impl PacketWrite for CAddPlayer {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.uuid.write(writer)?;
|
||||
self.username.write(writer)?;
|
||||
self.entity_runtime_id.write(writer)?;
|
||||
self.platform_chat_id.write(writer)?;
|
||||
self.position.write(writer)?;
|
||||
self.velocity.write(writer)?;
|
||||
self.pitch.write(writer)?;
|
||||
self.yaw.write(writer)?;
|
||||
self.head_yaw.write(writer)?;
|
||||
self.held_item.write(writer)?;
|
||||
self.game_mode.write(writer)?;
|
||||
self.metadata.write(writer)?;
|
||||
self.properties.write(writer)?;
|
||||
self.ability_data.write(writer)?;
|
||||
VarUInt(self.links.len() as u32).write(writer)?;
|
||||
for link in &self.links {
|
||||
link.write(writer)?;
|
||||
}
|
||||
self.device_id.write(writer)?;
|
||||
self.build_platform.write(writer)
|
||||
}
|
||||
}
|
||||
|
||||
impl CAddPlayer {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[must_use]
|
||||
@@ -125,23 +101,10 @@ impl PacketWrite for EntityProperties {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
#[derive(Default, Clone, PacketWrite)]
|
||||
pub struct AbilityData {
|
||||
pub entity_unique_id: i64,
|
||||
pub player_permissions: u8,
|
||||
pub command_permissions: u8,
|
||||
pub layers: Vec<AbilityLayer>,
|
||||
}
|
||||
|
||||
impl PacketWrite for AbilityData {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.entity_unique_id.write(writer)?;
|
||||
self.player_permissions.write(writer)?;
|
||||
self.command_permissions.write(writer)?;
|
||||
(self.layers.len() as u8).write(writer)?;
|
||||
for layer in &self.layers {
|
||||
layer.write(writer)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{codec::var_uint::VarUInt, serial::PacketWrite};
|
||||
use pumpkin_macros::packet;
|
||||
use std::io::{Error, Write};
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
#[packet(76)]
|
||||
pub struct CAvailableCommands {
|
||||
pub enum_values: Vec<String>,
|
||||
@@ -14,102 +14,30 @@ pub struct CAvailableCommands {
|
||||
pub constraints: Vec<CommandEnumConstraint>,
|
||||
}
|
||||
|
||||
impl PacketWrite for CAvailableCommands {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
fn write_string_slice<W: Write>(writer: &mut W, slice: &[String]) -> Result<(), Error> {
|
||||
VarUInt(slice.len() as u32).write(writer)?;
|
||||
for s in slice {
|
||||
s.write(writer)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// 1. Enum values
|
||||
write_string_slice(writer, &self.enum_values)?;
|
||||
|
||||
// 2. Chained subcommand values (The flat string list)
|
||||
write_string_slice(writer, &self.chained_subcommand_values)?;
|
||||
|
||||
// 3. Suffixes
|
||||
write_string_slice(writer, &self.suffixes)?;
|
||||
|
||||
// 4. Enums
|
||||
VarUInt(self.enums.len() as u32).write(writer)?;
|
||||
for e in &self.enums {
|
||||
e.write(writer)?;
|
||||
}
|
||||
|
||||
// 5. Chained Subcommands
|
||||
VarUInt(self.chained_subcommands.len() as u32).write(writer)?;
|
||||
for cs in &self.chained_subcommands {
|
||||
cs.write(writer)?;
|
||||
}
|
||||
|
||||
// 6. Commands
|
||||
VarUInt(self.commands.len() as u32).write(writer)?;
|
||||
for cmd in &self.commands {
|
||||
cmd.write(writer)?;
|
||||
}
|
||||
|
||||
// 7. Dynamic (Soft) Enums
|
||||
VarUInt(self.soft_enums.len() as u32).write(writer)?;
|
||||
for se in &self.soft_enums {
|
||||
se.write(writer)?;
|
||||
}
|
||||
|
||||
// 8. Constraints
|
||||
VarUInt(self.constraints.len() as u32).write(writer)?;
|
||||
for c in &self.constraints {
|
||||
c.write(writer)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// 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 name: String,
|
||||
pub values: Vec<ChainedSubcommandValue>,
|
||||
}
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
pub struct ChainedSubcommandValue {
|
||||
/// Index into the `ChainedSubcommandValues` flat list — `VarUInt`
|
||||
pub index: u32,
|
||||
pub index: VarUInt,
|
||||
/// Argument type flags (basic types only, no `ARG_FLAG`_* modifiers) — `VarUInt`
|
||||
pub value: u32,
|
||||
}
|
||||
|
||||
impl PacketWrite for ChainedSubcommand {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.name.write(writer)?;
|
||||
VarUInt(self.values.len() as u32).write(writer)?;
|
||||
for v in &self.values {
|
||||
VarUInt(v.index).write(writer)?;
|
||||
VarUInt(v.value).write(writer)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub value: VarUInt,
|
||||
}
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
pub struct CommandEnum {
|
||||
pub name: String,
|
||||
pub value_indices: Vec<usize>,
|
||||
}
|
||||
|
||||
impl CommandEnum {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.name.write(writer)?;
|
||||
VarUInt(self.value_indices.len() as u32).write(writer)?;
|
||||
for &index in &self.value_indices {
|
||||
writer.write_all(&(index as u32).to_le_bytes())?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub value_indices: Vec<u32>,
|
||||
}
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
pub struct Command {
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
@@ -124,28 +52,7 @@ pub struct Command {
|
||||
pub overloads: Vec<CommandOverload>,
|
||||
}
|
||||
|
||||
impl PacketWrite for Command {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.name.write(writer)?;
|
||||
self.description.write(writer)?;
|
||||
writer.write_all(&self.flags.to_le_bytes())?;
|
||||
self.permission.write(writer)?;
|
||||
writer.write_all(&self.aliases_enum_index.to_le_bytes())?;
|
||||
|
||||
// Chained subcommand offsets
|
||||
VarUInt(self.chained_subcommand_offsets.len() as u32).write(writer)?;
|
||||
for &offset in &self.chained_subcommand_offsets {
|
||||
writer.write_all(&offset.to_le_bytes())?;
|
||||
}
|
||||
|
||||
VarUInt(self.overloads.len() as u32).write(writer)?;
|
||||
for overload in &self.overloads {
|
||||
overload.write(writer)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[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
|
||||
@@ -153,20 +60,7 @@ pub struct CommandOverload {
|
||||
pub parameters: Vec<CommandParameter>,
|
||||
}
|
||||
|
||||
impl PacketWrite for CommandOverload {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
// Chaining bool ← MISSING in original — client reads this byte first
|
||||
writer.write_all(&[u8::from(self.chaining)])?;
|
||||
|
||||
VarUInt(self.parameters.len() as u32).write(writer)?;
|
||||
for param in &self.parameters {
|
||||
param.write(writer)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, PacketWrite)]
|
||||
pub struct CommandParameter {
|
||||
pub name: String,
|
||||
/// LE u32 — encodes type flags (`ARG_FLAG_VALID` | `ARG_FLAG_ENUM` | index, or raw type)
|
||||
@@ -176,16 +70,6 @@ pub struct CommandParameter {
|
||||
pub options: u8,
|
||||
}
|
||||
|
||||
impl PacketWrite for CommandParameter {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.name.write(writer)?;
|
||||
writer.write_all(&self.type_info.to_le_bytes())?;
|
||||
writer.write_all(&[u8::from(self.optional)])?;
|
||||
writer.write_all(&[self.options])?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Constants matching PocketMine's ARG_FLAG_* and ARG_TYPE_* values
|
||||
pub mod arg_flags {
|
||||
pub const ARG_FLAG_VALID: u32 = 0x100000;
|
||||
@@ -224,34 +108,15 @@ pub mod command_permissions {
|
||||
pub const INTERNAL: &str = "internal";
|
||||
}
|
||||
|
||||
#[derive(Clone, PacketWrite)]
|
||||
pub struct SoftEnum {
|
||||
pub name: String,
|
||||
pub values: Vec<String>,
|
||||
}
|
||||
|
||||
impl PacketWrite for SoftEnum {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.name.write(writer)?;
|
||||
VarUInt(self.values.len() as u32).write(writer)?;
|
||||
for value in &self.values {
|
||||
value.write(writer)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PacketWrite)]
|
||||
pub struct CommandEnumConstraint {
|
||||
pub affected_value_index: i32,
|
||||
pub enum_index: i32,
|
||||
pub constraints: Vec<u8>,
|
||||
}
|
||||
|
||||
impl PacketWrite for CommandEnumConstraint {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
writer.write_all(&self.affected_value_index.to_le_bytes())?;
|
||||
writer.write_all(&self.enum_index.to_le_bytes())?;
|
||||
VarUInt(self.constraints.len() as u32).write(writer)?;
|
||||
writer.write_all(&self.constraints)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ use crate::{
|
||||
};
|
||||
use pumpkin_macros::packet;
|
||||
use std::io::{Error, Write};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ItemDescriptorCount {
|
||||
@@ -48,7 +49,7 @@ pub struct BedrockShapelessRecipe {
|
||||
pub recipe_id: String,
|
||||
pub input: Vec<ItemDescriptorCount>,
|
||||
pub output: Vec<NetworkItemDescriptor>,
|
||||
pub uuid: [u8; 16],
|
||||
pub uuid: Uuid,
|
||||
pub block: String,
|
||||
pub priority: VarInt,
|
||||
pub unlock_requirement: RecipeUnlockRequirement,
|
||||
@@ -72,7 +73,7 @@ impl PacketWrite for BedrockShapelessRecipe {
|
||||
}
|
||||
|
||||
// uuid
|
||||
writer.write_all(&self.uuid)?;
|
||||
self.uuid.write(writer)?;
|
||||
|
||||
// block
|
||||
self.block.write(writer)?;
|
||||
@@ -97,7 +98,7 @@ pub struct BedrockShapedRecipe {
|
||||
pub height: VarInt,
|
||||
pub input: Vec<ItemDescriptorCount>,
|
||||
pub output: Vec<NetworkItemDescriptor>,
|
||||
pub uuid: [u8; 16],
|
||||
pub uuid: Uuid,
|
||||
pub block: String,
|
||||
pub priority: VarInt,
|
||||
pub assume_symmetry: bool,
|
||||
@@ -123,7 +124,7 @@ impl PacketWrite for BedrockShapedRecipe {
|
||||
}
|
||||
|
||||
// uuid
|
||||
writer.write_all(&self.uuid)?;
|
||||
self.uuid.write(writer)?;
|
||||
|
||||
// block
|
||||
self.block.write(writer)?;
|
||||
|
||||
@@ -4,8 +4,8 @@ use crate::{
|
||||
serial::PacketWrite,
|
||||
};
|
||||
use pumpkin_macros::packet;
|
||||
use std::io::{Error, Write};
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
#[packet(50)]
|
||||
pub struct CInventorySlot {
|
||||
pub window_id: VarUInt,
|
||||
@@ -14,23 +14,3 @@ pub struct CInventorySlot {
|
||||
pub storage: Option<NetworkItemStackDescriptor>,
|
||||
pub item: NetworkItemStackDescriptor,
|
||||
}
|
||||
|
||||
impl PacketWrite for CInventorySlot {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.window_id.write(writer)?;
|
||||
self.inventory_slot.write(writer)?;
|
||||
|
||||
self.container_name.is_some().write(writer)?;
|
||||
if let Some(container_name) = &self.container_name {
|
||||
container_name.write(writer)?;
|
||||
}
|
||||
|
||||
self.storage.is_some().write(writer)?;
|
||||
if let Some(storage) = &self.storage {
|
||||
storage.write(writer)?;
|
||||
}
|
||||
|
||||
self.item.write(writer)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod actor_event;
|
||||
pub mod add_actor;
|
||||
pub mod add_item_actor;
|
||||
pub mod add_player;
|
||||
@@ -22,6 +23,7 @@ pub mod item_registry;
|
||||
pub mod item_stack_response;
|
||||
pub mod level_chunk;
|
||||
pub mod level_event;
|
||||
pub mod level_sound_event;
|
||||
pub mod mob_effect;
|
||||
pub mod mob_equipment;
|
||||
pub mod modal_form_request;
|
||||
@@ -39,6 +41,7 @@ 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_health;
|
||||
@@ -54,9 +57,6 @@ pub mod update_abilities;
|
||||
pub mod update_attributes;
|
||||
pub mod update_block;
|
||||
|
||||
pub mod level_sound_event;
|
||||
pub mod set_actor_link;
|
||||
|
||||
pub use add_actor::*;
|
||||
pub use add_item_actor::*;
|
||||
pub use add_player::*;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
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,
|
||||
@@ -14,23 +16,6 @@ pub struct ResourcePackEntry {
|
||||
pub download_url: String,
|
||||
}
|
||||
|
||||
impl PacketWrite for ResourcePackEntry {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.uuid.write(writer)?;
|
||||
self.version.write(writer)?;
|
||||
// Bedrock uses Little Endian u64 for size
|
||||
writer.write_all(&self.size.to_le_bytes())?;
|
||||
self.content_key.write(writer)?;
|
||||
self.sub_pack_name.write(writer)?;
|
||||
self.content_id.write(writer)?;
|
||||
self.has_scripts.write(writer)?;
|
||||
self.addon_pack.write(writer)?;
|
||||
self.rtx_enabled.write(writer)?;
|
||||
self.download_url.write(writer)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[packet(6)]
|
||||
pub struct CResourcePacksInfo {
|
||||
pub resource_pack_required: bool,
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
use std::io::{Error, Write};
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
|
||||
use crate::{codec::var_int::VarInt, serial::PacketWrite};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, PacketWrite)]
|
||||
#[packet(43)]
|
||||
pub struct CSetSpawnPosition {
|
||||
pub spawn_type: VarInt,
|
||||
@@ -30,13 +28,3 @@ impl CSetSpawnPosition {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketWrite for CSetSpawnPosition {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.spawn_type.write(writer)?;
|
||||
self.position.write(writer)?;
|
||||
self.dimension.write(writer)?;
|
||||
self.spawn_position.write(writer)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use std::io::{Error, Write};
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
|
||||
use crate::{codec::var_uint::VarUInt, serial::PacketWrite};
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
#[packet(21)]
|
||||
pub struct CUpdateBlock {
|
||||
pub position: BlockPos,
|
||||
@@ -24,13 +23,3 @@ impl CUpdateBlock {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketWrite for CUpdateBlock {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.position.write(writer)?;
|
||||
self.block_runtime_id.write(writer)?;
|
||||
self.flags.write(writer)?;
|
||||
self.layer.write(writer)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ impl PacketWrite for AnimateSwingSource {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PacketRead, PacketWrite)]
|
||||
#[packet(44)]
|
||||
pub struct SAnimate {
|
||||
pub action: AnimateAction,
|
||||
@@ -94,33 +94,6 @@ pub struct SAnimate {
|
||||
pub swing_source: Option<AnimateSwingSource>,
|
||||
}
|
||||
|
||||
impl PacketRead for SAnimate {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
let action = AnimateAction::read(reader)?;
|
||||
let runtime_entity_id = VarULong::read(reader)?;
|
||||
let data = f32::read(reader)?;
|
||||
|
||||
let swing_source = Option::<AnimateSwingSource>::read(reader)?;
|
||||
|
||||
Ok(Self {
|
||||
action,
|
||||
runtime_entity_id,
|
||||
data,
|
||||
swing_source,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketWrite for SAnimate {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.action.write(writer)?;
|
||||
self.runtime_entity_id.write(writer)?;
|
||||
self.data.write(writer)?;
|
||||
|
||||
self.swing_source.write(writer)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -2,9 +2,9 @@ use pumpkin_macros::packet;
|
||||
use std::borrow::Cow;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::serial::{PacketRead, PacketReadSlice, read_str_slice};
|
||||
use crate::serial::{PacketRead, PacketReadSlice};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PacketRead, PacketReadSlice)]
|
||||
#[packet(77)]
|
||||
pub struct SCommandRequest<'a> {
|
||||
pub command: Cow<'a, str>,
|
||||
@@ -15,46 +15,3 @@ pub struct SCommandRequest<'a> {
|
||||
pub is_internal_source: bool,
|
||||
pub version: Cow<'a, str>,
|
||||
}
|
||||
|
||||
impl<'a> PacketReadSlice<'a> for SCommandRequest<'a> {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, std::io::Error> {
|
||||
let command = Cow::Borrowed(read_str_slice(buf)?);
|
||||
let command_type = Cow::Borrowed(read_str_slice(buf)?);
|
||||
let command_uuid = Uuid::read_slice(buf)?;
|
||||
let request_id = Cow::Borrowed(read_str_slice(buf)?);
|
||||
let player_actor_unique_id = i64::read_slice(buf)?;
|
||||
let is_internal_source = bool::read_slice(buf)?;
|
||||
let version = Cow::Borrowed(read_str_slice(buf)?);
|
||||
Ok(Self {
|
||||
command,
|
||||
command_type,
|
||||
command_uuid,
|
||||
request_id,
|
||||
player_actor_unique_id,
|
||||
is_internal_source,
|
||||
version,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketRead for SCommandRequest<'static> {
|
||||
fn read<R: std::io::Read>(reader: &mut R) -> Result<Self, std::io::Error> {
|
||||
let command = Cow::Owned(String::read(reader)?);
|
||||
let command_type = Cow::Owned(String::read(reader)?);
|
||||
let command_uuid = Uuid::read(reader)?;
|
||||
let request_id = Cow::Owned(String::read(reader)?);
|
||||
let player_actor_unique_id = i64::read(reader)?;
|
||||
let is_internal_source = bool::read(reader)?;
|
||||
let version = Cow::Owned(String::read(reader)?);
|
||||
|
||||
Ok(Self {
|
||||
command,
|
||||
command_type,
|
||||
command_uuid,
|
||||
request_id,
|
||||
player_actor_unique_id,
|
||||
is_internal_source,
|
||||
version,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use crate::codec::{var_uint::VarUInt, var_ulong::VarULong};
|
||||
use crate::serial::{PacketRead, PacketReadSlice, PacketWrite, read_str_slice};
|
||||
use crate::codec::var_uint::VarUInt;
|
||||
use crate::codec::var_ulong::VarULong;
|
||||
use crate::serial::{PacketRead, PacketReadSlice, PacketWrite};
|
||||
use pumpkin_macros::packet;
|
||||
use std::borrow::Cow;
|
||||
use std::io::{Error, Write};
|
||||
|
||||
pub const EMOTE_FLAG_SERVER_SIDE: u8 = 1 << 0;
|
||||
pub const EMOTE_FLAG_MUTE_CHAT: u8 = 1 << 1;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PacketRead, PacketReadSlice, PacketWrite)]
|
||||
#[packet(138)]
|
||||
pub struct SEmote<'a> {
|
||||
pub runtime_entity_id: VarULong,
|
||||
@@ -17,46 +17,3 @@ pub struct SEmote<'a> {
|
||||
pub platform_id: Cow<'a, str>,
|
||||
pub flags: u8,
|
||||
}
|
||||
|
||||
impl<'a> PacketReadSlice<'a> for SEmote<'a> {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
let runtime_entity_id = VarULong::read_slice(buf)?;
|
||||
let emote_length = VarUInt::read_slice(buf)?;
|
||||
let emote_id = Cow::Borrowed(read_str_slice(buf)?);
|
||||
let xuid = Cow::Borrowed(read_str_slice(buf)?);
|
||||
let platform_id = Cow::Borrowed(read_str_slice(buf)?);
|
||||
let flags = u8::read_slice(buf)?;
|
||||
Ok(Self {
|
||||
runtime_entity_id,
|
||||
emote_length,
|
||||
emote_id,
|
||||
xuid,
|
||||
platform_id,
|
||||
flags,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketRead for SEmote<'static> {
|
||||
fn read<R: std::io::Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
runtime_entity_id: VarULong::read(reader)?,
|
||||
emote_length: VarUInt::read(reader)?,
|
||||
emote_id: Cow::Owned(String::read(reader)?),
|
||||
xuid: Cow::Owned(String::read(reader)?),
|
||||
platform_id: Cow::Owned(String::read(reader)?),
|
||||
flags: u8::read(reader)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketWrite for SEmote<'_> {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.runtime_entity_id.write(writer)?;
|
||||
self.emote_length.write(writer)?;
|
||||
self.emote_id.as_ref().write(writer)?;
|
||||
self.xuid.as_ref().write(writer)?;
|
||||
self.platform_id.as_ref().write(writer)?;
|
||||
self.flags.write(writer)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +1,18 @@
|
||||
use std::io::{Error, Read, Write};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
codec::{var_uint::VarUInt, var_ulong::VarULong},
|
||||
codec::var_ulong::VarULong,
|
||||
serial::{PacketRead, PacketWrite},
|
||||
};
|
||||
use pumpkin_macros::packet;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PacketRead, PacketWrite)]
|
||||
#[packet(152)]
|
||||
pub struct SEmoteList {
|
||||
pub runtime_entity_id: VarULong,
|
||||
pub emote_pieces: Vec<Uuid>,
|
||||
}
|
||||
|
||||
impl PacketRead for SEmoteList {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
let runtime_entity_id = VarULong::read(reader)?;
|
||||
let len = VarUInt::read(reader)?.0 as usize;
|
||||
let mut emote_pieces = Vec::with_capacity(len);
|
||||
for _ in 0..len {
|
||||
emote_pieces.push(Uuid::read(reader)?);
|
||||
}
|
||||
Ok(Self {
|
||||
runtime_entity_id,
|
||||
emote_pieces,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketWrite for SEmoteList {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.runtime_entity_id.write(writer)?;
|
||||
VarUInt(self.emote_pieces.len() as u32).write(writer)?;
|
||||
for piece in &self.emote_pieces {
|
||||
piece.write(writer)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -125,7 +125,7 @@ pub struct NormalTransactionData;
|
||||
#[derive(Debug, PacketRead)]
|
||||
pub struct MismatchTransactionData;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PacketRead)]
|
||||
pub struct UseItemTransactionData {
|
||||
pub action_type: VarInt,
|
||||
pub trigger_type: u8,
|
||||
@@ -140,25 +140,7 @@ pub struct UseItemTransactionData {
|
||||
pub client_cooldown_state: u8,
|
||||
}
|
||||
|
||||
impl PacketRead for UseItemTransactionData {
|
||||
fn read<R: Read>(buf: &mut R) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
action_type: VarInt::read(buf)?,
|
||||
trigger_type: u8::read(buf)?,
|
||||
block_position: BlockPos::read(buf)?,
|
||||
block_face: i32::from(u8::read(buf)?),
|
||||
hot_bar_slot: VarInt::read(buf)?,
|
||||
item_in_hand: NetworkItemDescriptor::read(buf)?,
|
||||
player_position: Vector3::read(buf)?,
|
||||
click_position: Vector3::read(buf)?,
|
||||
block_runtime_id: VarUInt::read(buf)?,
|
||||
client_prediction: u8::read(buf)?,
|
||||
client_cooldown_state: u8::read(buf)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PacketRead)]
|
||||
pub struct UseItemOnEntityTransactionData {
|
||||
pub target_entity_runtime_id: VarULong,
|
||||
pub action_type: VarInt,
|
||||
@@ -168,20 +150,7 @@ pub struct UseItemOnEntityTransactionData {
|
||||
pub click_position: Vector3<f32>,
|
||||
}
|
||||
|
||||
impl PacketRead for UseItemOnEntityTransactionData {
|
||||
fn read<R: Read>(buf: &mut R) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
target_entity_runtime_id: VarULong::read(buf)?,
|
||||
action_type: VarInt::read(buf)?,
|
||||
hot_bar_slot: VarInt::read(buf)?,
|
||||
item_in_hand: NetworkItemDescriptor::read(buf)?,
|
||||
player_position: Vector3::read(buf)?,
|
||||
click_position: Vector3::read(buf)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PacketRead)]
|
||||
pub struct ReleaseItemTransactionData {
|
||||
pub action_type: VarInt,
|
||||
pub hot_bar_slot: VarInt,
|
||||
@@ -189,17 +158,6 @@ pub struct ReleaseItemTransactionData {
|
||||
pub head_position: Vector3<f32>,
|
||||
}
|
||||
|
||||
impl PacketRead for ReleaseItemTransactionData {
|
||||
fn read<R: Read>(buf: &mut R) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
action_type: VarInt::read(buf)?,
|
||||
hot_bar_slot: VarInt::read(buf)?,
|
||||
item_in_hand: NetworkItemDescriptor::read(buf)?,
|
||||
head_position: Vector3::read(buf)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[packet(30)]
|
||||
pub struct SInventoryTransaction {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::io::{Error, ErrorKind, Read, Write};
|
||||
use std::io::{Error, ErrorKind, Read};
|
||||
|
||||
use crate::{
|
||||
bedrock::network_item::FullContainerName,
|
||||
@@ -20,11 +20,11 @@ fn collection_length<R: Read>(reader: &mut R, name: &str) -> Result<usize, Error
|
||||
Ok(len as usize)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PacketRead, PacketWrite)]
|
||||
pub struct ItemStackRequestSlotInfo {
|
||||
pub container_name: FullContainerName,
|
||||
pub slot_id: u8,
|
||||
pub stack_id: VarInt,
|
||||
pub stack_id: i32,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -65,28 +65,6 @@ impl PacketRead for StackRequestItem {
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketRead for ItemStackRequestSlotInfo {
|
||||
fn read<R: Read>(buf: &mut R) -> Result<Self, Error> {
|
||||
let container_name = FullContainerName::read(buf)?;
|
||||
let slot_id = u8::read(buf)?;
|
||||
let stack_id = VarInt(i32::read(buf)?);
|
||||
Ok(Self {
|
||||
container_name,
|
||||
slot_id,
|
||||
stack_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketWrite for ItemStackRequestSlotInfo {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.container_name.write(writer)?;
|
||||
self.slot_id.write(writer)?;
|
||||
self.stack_id.0.write(writer)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ItemStackRequestAction {
|
||||
Take {
|
||||
@@ -349,14 +327,14 @@ mod tests {
|
||||
dynamic_id: None,
|
||||
},
|
||||
slot_id: 4,
|
||||
stack_id: VarInt(-2),
|
||||
stack_id: -2,
|
||||
};
|
||||
let mut encoded = Vec::new();
|
||||
slot.write(&mut encoded).unwrap();
|
||||
|
||||
assert_eq!(&encoded[encoded.len() - 4..], &(-2i32).to_le_bytes());
|
||||
let decoded = ItemStackRequestSlotInfo::read(&mut encoded.as_slice()).unwrap();
|
||||
assert_eq!(decoded.stack_id, VarInt(-2));
|
||||
assert_eq!(decoded.stack_id, -2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::{MAX_PACKET_DATA_SIZE, codec::var_uint::VarUInt, serial::PacketRead};
|
||||
#[packet(1)]
|
||||
pub struct SLogin {
|
||||
// https://mojang.github.io/bedrock-protocol-docs/html/LoginPacket.html
|
||||
//#[serial(big_endian)]
|
||||
pub protocol_version: i32,
|
||||
|
||||
// https://mojang.github.io/bedrock-protocol-docs/html/connectionRequest.html
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
pub mod actor_event;
|
||||
pub mod animate;
|
||||
pub mod block_pick_request;
|
||||
pub mod client_cache_blob_status;
|
||||
@@ -27,7 +26,6 @@ pub mod set_local_player_as_initialized;
|
||||
pub mod set_player_inventory_options;
|
||||
pub mod text;
|
||||
|
||||
pub use actor_event::*;
|
||||
pub use animate::*;
|
||||
pub use block_pick_request::*;
|
||||
pub use client_cache_blob_status::*;
|
||||
|
||||
@@ -1,41 +1,12 @@
|
||||
use crate::codec::var_uint::VarUInt;
|
||||
use crate::serial::{PacketRead, PacketReadSlice, read_str_slice};
|
||||
use crate::serial::{PacketRead, PacketReadSlice};
|
||||
use pumpkin_macros::packet;
|
||||
use std::borrow::Cow;
|
||||
use std::io::{Error, Read};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PacketRead, PacketReadSlice)]
|
||||
#[packet(101)]
|
||||
pub struct SModalFormResponse<'a> {
|
||||
pub form_id: VarUInt,
|
||||
pub form_data: Option<Cow<'a, str>>,
|
||||
pub cancel_reason: Option<u8>,
|
||||
}
|
||||
|
||||
impl<'a> PacketReadSlice<'a> for SModalFormResponse<'a> {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
let form_id = VarUInt::read_slice(buf)?;
|
||||
let form_data = bool::read_slice(buf)?
|
||||
.then(|| read_str_slice(buf).map(Cow::Borrowed))
|
||||
.transpose()?;
|
||||
let cancel_reason = Option::<u8>::read_slice(buf)?;
|
||||
Ok(Self {
|
||||
form_id,
|
||||
form_data,
|
||||
cancel_reason,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketRead for SModalFormResponse<'static> {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
let form_id = VarUInt::read(reader)?;
|
||||
let form_data = Option::<String>::read(reader)?.map(Cow::Owned);
|
||||
let cancel_reason = Option::<u8>::read(reader)?;
|
||||
Ok(Self {
|
||||
form_id,
|
||||
form_data,
|
||||
cancel_reason,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,20 +24,13 @@ impl PacketRead for AbilityValue {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PacketRead)]
|
||||
#[packet(184)]
|
||||
pub struct SRequestAbility {
|
||||
pub ability: VarInt,
|
||||
pub value: AbilityValue,
|
||||
}
|
||||
|
||||
impl PacketRead for SRequestAbility {
|
||||
fn read<R: Read>(buf: &mut R) -> Result<Self, Error> {
|
||||
let ability = VarInt::read(buf)?;
|
||||
let value = AbilityValue::read(buf)?;
|
||||
Ok(Self { ability, value })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
use crate::{codec::var_ulong::VarULong, serial::PacketRead};
|
||||
use pumpkin_macros::packet;
|
||||
use std::io::{Error, Read};
|
||||
|
||||
#[derive(PacketRead)]
|
||||
#[packet(113)]
|
||||
pub struct SSetLocalPlayerAsInitialized {
|
||||
pub runtime_entity_id: VarULong,
|
||||
}
|
||||
|
||||
impl PacketRead for SSetLocalPlayerAsInitialized {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
runtime_entity_id: VarULong::read(reader)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{codec::var_int::VarInt, serial::PacketRead};
|
||||
use pumpkin_macros::packet;
|
||||
use std::io::{Error, Read};
|
||||
|
||||
#[derive(PacketRead)]
|
||||
#[packet(307)]
|
||||
pub struct SSetPlayerInventoryOptions {
|
||||
pub left_inventory_tab: VarInt,
|
||||
@@ -10,15 +10,3 @@ pub struct SSetPlayerInventoryOptions {
|
||||
pub inventory_layout: VarInt,
|
||||
pub crafting_layout: VarInt,
|
||||
}
|
||||
|
||||
impl PacketRead for SSetPlayerInventoryOptions {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
left_inventory_tab: VarInt::read(reader)?,
|
||||
right_inventory_tab: VarInt::read(reader)?,
|
||||
filtering: bool::read(reader)?,
|
||||
inventory_layout: VarInt::read(reader)?,
|
||||
crafting_layout: VarInt::read(reader)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
io::{Error, ErrorKind, Read},
|
||||
net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
|
||||
};
|
||||
@@ -8,7 +9,7 @@ use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
codec::{var_int::VarInt, var_uint::VarUInt},
|
||||
serial::PacketRead,
|
||||
serial::{PacketRead, PacketReadSlice, read_str_slice},
|
||||
};
|
||||
|
||||
impl PacketRead for bool {
|
||||
@@ -169,18 +170,13 @@ impl PacketRead for String {
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketRead for Vec<u8> {
|
||||
impl<T: PacketRead> PacketRead for Vec<T> {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
const MAX_VECTOR_BYTES: usize = 2 * 1024 * 1024; // 2 MB safety cap
|
||||
let len = VarUInt::read(reader)?.0 as usize;
|
||||
if len > MAX_VECTOR_BYTES {
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidData,
|
||||
format!("Byte vector length {len} exceeds maximum limit of {MAX_VECTOR_BYTES}"),
|
||||
));
|
||||
let len = VarUInt::read(reader)?.0 as _;
|
||||
let mut buf = Self::with_capacity(len);
|
||||
for _ in 0..len {
|
||||
buf.push(T::read(reader)?);
|
||||
}
|
||||
let mut buf = vec![0u8; len];
|
||||
reader.read_exact(&mut buf)?;
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
||||
@@ -255,7 +251,13 @@ impl<T: PacketRead> PacketRead for Option<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for bool {
|
||||
impl PacketRead for Cow<'_, str> {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
Ok(Self::Owned(String::read(reader)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PacketReadSlice<'a> for bool {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
if buf.is_empty() {
|
||||
return Err(Error::new(ErrorKind::UnexpectedEof, "expected bool byte"));
|
||||
@@ -266,7 +268,7 @@ impl<'a> crate::serial::PacketReadSlice<'a> for bool {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for u8 {
|
||||
impl<'a> PacketReadSlice<'a> for u8 {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
if buf.is_empty() {
|
||||
return Err(Error::new(ErrorKind::UnexpectedEof, "expected u8"));
|
||||
@@ -277,13 +279,13 @@ impl<'a> crate::serial::PacketReadSlice<'a> for u8 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for i8 {
|
||||
impl<'a> PacketReadSlice<'a> for i8 {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
u8::read_slice(buf).map(|b| b as Self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for i16 {
|
||||
impl<'a> PacketReadSlice<'a> for i16 {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
if buf.len() < 2 {
|
||||
return Err(Error::new(ErrorKind::UnexpectedEof, "expected i16"));
|
||||
@@ -297,7 +299,7 @@ impl<'a> crate::serial::PacketReadSlice<'a> for i16 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for i32 {
|
||||
impl<'a> PacketReadSlice<'a> for i32 {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
if buf.len() < 4 {
|
||||
return Err(Error::new(ErrorKind::UnexpectedEof, "expected i32"));
|
||||
@@ -311,7 +313,7 @@ impl<'a> crate::serial::PacketReadSlice<'a> for i32 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for i64 {
|
||||
impl<'a> PacketReadSlice<'a> for i64 {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
if buf.len() < 8 {
|
||||
return Err(Error::new(ErrorKind::UnexpectedEof, "expected i64"));
|
||||
@@ -325,7 +327,7 @@ impl<'a> crate::serial::PacketReadSlice<'a> for i64 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for u16 {
|
||||
impl<'a> PacketReadSlice<'a> for u16 {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
if buf.len() < 2 {
|
||||
return Err(Error::new(ErrorKind::UnexpectedEof, "expected u16"));
|
||||
@@ -339,7 +341,7 @@ impl<'a> crate::serial::PacketReadSlice<'a> for u16 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for u32 {
|
||||
impl<'a> PacketReadSlice<'a> for u32 {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
if buf.len() < 4 {
|
||||
return Err(Error::new(ErrorKind::UnexpectedEof, "expected u32"));
|
||||
@@ -353,7 +355,7 @@ impl<'a> crate::serial::PacketReadSlice<'a> for u32 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for u64 {
|
||||
impl<'a> PacketReadSlice<'a> for u64 {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
if buf.len() < 8 {
|
||||
return Err(Error::new(ErrorKind::UnexpectedEof, "expected u64"));
|
||||
@@ -367,7 +369,7 @@ impl<'a> crate::serial::PacketReadSlice<'a> for u64 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for f32 {
|
||||
impl<'a> PacketReadSlice<'a> for f32 {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
if buf.len() < 4 {
|
||||
return Err(Error::new(ErrorKind::UnexpectedEof, "expected f32"));
|
||||
@@ -381,7 +383,7 @@ impl<'a> crate::serial::PacketReadSlice<'a> for f32 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for f64 {
|
||||
impl<'a> PacketReadSlice<'a> for f64 {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
if buf.len() < 8 {
|
||||
return Err(Error::new(ErrorKind::UnexpectedEof, "expected f64"));
|
||||
@@ -395,13 +397,13 @@ impl<'a> crate::serial::PacketReadSlice<'a> for f64 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for &'a str {
|
||||
impl<'a> PacketReadSlice<'a> for &'a str {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
crate::serial::read_str_slice(buf)
|
||||
read_str_slice(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: crate::serial::PacketReadSlice<'a>> crate::serial::PacketReadSlice<'a> for Option<T> {
|
||||
impl<'a, T: PacketReadSlice<'a>> PacketReadSlice<'a> for Option<T> {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
bool::read_slice(buf)?
|
||||
.then(|| T::read_slice(buf))
|
||||
@@ -409,7 +411,7 @@ impl<'a, T: crate::serial::PacketReadSlice<'a>> crate::serial::PacketReadSlice<'
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for uuid::Uuid {
|
||||
impl<'a> PacketReadSlice<'a> for uuid::Uuid {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
if buf.len() < 16 {
|
||||
return Err(Error::new(ErrorKind::UnexpectedEof, "expected Uuid"));
|
||||
@@ -423,20 +425,26 @@ impl<'a> crate::serial::PacketReadSlice<'a> for uuid::Uuid {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for crate::codec::var_int::VarInt {
|
||||
impl<'a> PacketReadSlice<'a> for crate::codec::var_int::VarInt {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
Self::read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for crate::codec::var_uint::VarUInt {
|
||||
impl<'a> PacketReadSlice<'a> for crate::codec::var_uint::VarUInt {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
Self::read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> crate::serial::PacketReadSlice<'a> for crate::codec::var_ulong::VarULong {
|
||||
impl<'a> PacketReadSlice<'a> for crate::codec::var_ulong::VarULong {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
Self::read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PacketReadSlice<'a> for Cow<'a, str> {
|
||||
fn read_slice(buf: &mut &'a [u8]) -> Result<Self, Error> {
|
||||
Ok(Self::Borrowed(read_str_slice(buf)?))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pub mod deserializer;
|
||||
pub mod serializer;
|
||||
pub use pumpkin_macros::{PacketRead, PacketWrite};
|
||||
pub use pumpkin_macros::{PacketRead, PacketReadSlice, PacketWrite};
|
||||
use std::io::{Error, Read, Write};
|
||||
|
||||
pub trait PacketWrite {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
io::{Error, Write},
|
||||
net::SocketAddr,
|
||||
};
|
||||
@@ -200,3 +201,9 @@ impl PacketWrite for GameMode {
|
||||
.write(writer)
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketWrite for Cow<'_, str> {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.as_ref().write(writer)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,7 +588,7 @@ fn collect_overloads_from_attached(
|
||||
}
|
||||
}
|
||||
|
||||
fn ensure_enum_value(enum_values: &mut Vec<String>, value: &str) -> usize {
|
||||
fn ensure_enum_value(enum_values: &mut Vec<String>, value: &str) -> u32 {
|
||||
enum_values
|
||||
.iter()
|
||||
.position(|v| v == value)
|
||||
@@ -596,6 +596,8 @@ fn ensure_enum_value(enum_values: &mut Vec<String>, value: &str) -> usize {
|
||||
enum_values.push(value.to_string());
|
||||
enum_values.len() - 1
|
||||
})
|
||||
.try_into()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn ensure_command_enum(
|
||||
@@ -608,7 +610,7 @@ fn ensure_command_enum(
|
||||
return pos;
|
||||
}
|
||||
|
||||
let value_indices: Vec<usize> = values
|
||||
let value_indices: Vec<u32> = values
|
||||
.iter()
|
||||
.map(|val| ensure_enum_value(enum_values, val))
|
||||
.collect();
|
||||
|
||||
@@ -6,8 +6,8 @@ use pumpkin_data::tracked_data::{TrackedData, TrackedId};
|
||||
use pumpkin_inventory::build_equipment_slots;
|
||||
use pumpkin_inventory::player::player_inventory::PlayerInventory;
|
||||
use pumpkin_inventory::screen_handler::InventoryPlayer;
|
||||
use pumpkin_protocol::bedrock::client::actor_event::{ActorEventType, CActorEvent};
|
||||
use pumpkin_protocol::bedrock::client::take_item_actor::CTakeItemActor;
|
||||
use pumpkin_protocol::bedrock::server::actor_event::{ActorEventType, SActorEvent};
|
||||
use pumpkin_protocol::codec::var_ulong::VarULong;
|
||||
use pumpkin_util::GameMode;
|
||||
use pumpkin_util::Hand;
|
||||
@@ -2485,7 +2485,7 @@ impl EntityBase for LivingEntity {
|
||||
(src.z - tgt.z).atan2(src.x - tgt.x).to_degrees() as f32
|
||||
- self.entity.yaw.load()
|
||||
});
|
||||
let hurt_event = SActorEvent {
|
||||
let hurt_event = CActorEvent {
|
||||
entity_runtime_id: VarULong(entity_id as u64),
|
||||
event_type: ActorEventType::Hurt,
|
||||
event_data: VarInt(0),
|
||||
|
||||
@@ -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::client::actor_event::ActorEventType;
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
|
||||
pub trait Animal: Mob {
|
||||
|
||||
@@ -11,7 +11,7 @@ use pumpkin_data::meta_data_type::MetaDataType;
|
||||
use pumpkin_data::tag::{self, Taggable};
|
||||
use pumpkin_data::tracked_data::TrackedData;
|
||||
use pumpkin_nbt::compound::NbtCompound;
|
||||
use pumpkin_protocol::bedrock::server::actor_event::ActorEventType;
|
||||
use pumpkin_protocol::bedrock::client::actor_event::ActorEventType;
|
||||
use pumpkin_protocol::codec::var_int::VarInt;
|
||||
use pumpkin_protocol::java::client::play::Metadata;
|
||||
use rand::RngExt;
|
||||
|
||||
@@ -10,7 +10,7 @@ use pumpkin_data::meta_data_type::MetaDataType;
|
||||
use pumpkin_data::tag::{self, Taggable};
|
||||
use pumpkin_data::tracked_data::TrackedData;
|
||||
use pumpkin_nbt::compound::NbtCompound;
|
||||
use pumpkin_protocol::bedrock::server::actor_event::ActorEventType;
|
||||
use pumpkin_protocol::bedrock::client::actor_event::ActorEventType;
|
||||
use pumpkin_protocol::java::client::play::Metadata;
|
||||
use rand::RngExt;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ use pumpkin_inventory::screen_handler::{
|
||||
BoxFuture, InventoryPlayer, ScreenHandlerFactory, SharedScreenHandler,
|
||||
};
|
||||
use pumpkin_nbt::compound::NbtCompound;
|
||||
use pumpkin_protocol::bedrock::server::actor_event::ActorEventType;
|
||||
use pumpkin_protocol::bedrock::client::actor_event::ActorEventType;
|
||||
use pumpkin_protocol::codec::var_int::VarInt;
|
||||
use pumpkin_protocol::java::client::play::{CMerchantOffers, Metadata};
|
||||
use pumpkin_util::math::{boundingbox::BoundingBox, position::BlockPos, vector3::Vector3};
|
||||
|
||||
@@ -64,8 +64,8 @@ use pumpkin_nbt::compound::NbtCompound;
|
||||
use pumpkin_nbt::tag::NbtTag;
|
||||
use pumpkin_protocol::IdOr;
|
||||
use pumpkin_protocol::SoundEvent;
|
||||
use pumpkin_protocol::bedrock::client::actor_event::{ActorEventType, CActorEvent};
|
||||
use pumpkin_protocol::bedrock::client::container_open::CContainerOpen;
|
||||
use pumpkin_protocol::bedrock::server::actor_event::{ActorEventType, SActorEvent};
|
||||
use pumpkin_protocol::codec::var_int::VarInt;
|
||||
use pumpkin_protocol::codec::var_long::VarLong;
|
||||
use pumpkin_protocol::codec::var_ulong::VarULong;
|
||||
@@ -3440,7 +3440,7 @@ impl Player {
|
||||
self.client
|
||||
.send_packet_now_editioned(
|
||||
&CCombatDeath::new(self.entity_id().into(), &death_msg),
|
||||
&SActorEvent {
|
||||
&CActorEvent {
|
||||
entity_runtime_id: VarULong(self.entity_id() as u64),
|
||||
event_type: ActorEventType::Death,
|
||||
event_data: VarInt(0),
|
||||
|
||||
@@ -14,7 +14,7 @@ use pumpkin_data::item::Item;
|
||||
use pumpkin_data::item_stack::ItemStack;
|
||||
use pumpkin_data::meta_data_type::MetaDataType;
|
||||
use pumpkin_data::tracked_data::TrackedData;
|
||||
use pumpkin_protocol::bedrock::server::actor_event::ActorEventType;
|
||||
use pumpkin_protocol::bedrock::client::actor_event::ActorEventType;
|
||||
use pumpkin_protocol::codec::item_stack_seralizer::ItemStackSerializer;
|
||||
use pumpkin_protocol::java::client::play::Metadata;
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
|
||||
@@ -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::client::actor_event::ActorEventType;
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
|
||||
const GRAVITY: f64 = 0.03;
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::{
|
||||
world::World,
|
||||
};
|
||||
use pumpkin_data::{entity::EntityStatus, meta_data_type::MetaDataType, tracked_data::TrackedData};
|
||||
use pumpkin_protocol::bedrock::server::actor_event::ActorEventType;
|
||||
use pumpkin_protocol::bedrock::client::actor_event::ActorEventType;
|
||||
use pumpkin_protocol::{codec::optional_int::OptionalInt, java::client::play::Metadata};
|
||||
use pumpkin_util::{
|
||||
math::vector3::Vector3,
|
||||
|
||||
@@ -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::client::actor_event::ActorEventType;
|
||||
use pumpkin_protocol::java::client::play::CWorldEvent;
|
||||
use pumpkin_util::math::position::BlockPos;
|
||||
use pumpkin_util::math::vector2::{Vector2, to_chunk_pos};
|
||||
|
||||
@@ -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::client::actor_event::ActorEventType;
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
|
||||
const GRAVITY: f64 = 0.03;
|
||||
|
||||
@@ -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::client::actor_event::ActorEventType;
|
||||
use pumpkin_util::math::vector3::Vector3;
|
||||
use rand::RngExt;
|
||||
|
||||
|
||||
@@ -96,6 +96,7 @@ use pumpkin_protocol::{
|
||||
BClientPacket, ClientPacket, IdOr, SoundEvent,
|
||||
bedrock::{
|
||||
client::{
|
||||
actor_event::{ActorEventType, CActorEvent},
|
||||
add_player::CAddPlayer,
|
||||
block_event::CBlockEvent as CBedrockBlockEvent,
|
||||
common::BuildPlatform,
|
||||
@@ -107,10 +108,7 @@ use pumpkin_protocol::{
|
||||
start_game::{Experiments, GamePublishSetting, LevelSettings},
|
||||
update_attributes::{Attribute, CUpdateAttributes},
|
||||
},
|
||||
server::{
|
||||
actor_event::{ActorEventType, SActorEvent},
|
||||
text::SText,
|
||||
},
|
||||
server::text::SText,
|
||||
},
|
||||
codec::{var_int::VarInt, var_long::VarLong, var_uint::VarUInt, var_ulong::VarULong},
|
||||
java::{
|
||||
@@ -496,7 +494,7 @@ impl World {
|
||||
let chunk_pos = entity.chunk_pos.load();
|
||||
let je_packet = CEntityStatus::new(entity.entity_id, java_status as i8);
|
||||
if let Some(be_event) = bedrock_status {
|
||||
let be_packet = SActorEvent {
|
||||
let be_packet = CActorEvent {
|
||||
entity_runtime_id: VarULong(entity.entity_id as u64),
|
||||
event_type: be_event,
|
||||
event_data: VarInt(0),
|
||||
@@ -2421,7 +2419,7 @@ impl World {
|
||||
height: VarInt(height),
|
||||
input,
|
||||
output: vec![output_descriptor],
|
||||
uuid: [0; 16],
|
||||
uuid: Uuid::nil(),
|
||||
block: "crafting_table".to_string(),
|
||||
priority: VarInt(1),
|
||||
assume_symmetry: true,
|
||||
@@ -2459,7 +2457,7 @@ impl World {
|
||||
recipe_id: format!("pumpkin:recipe_{network_id_counter}"),
|
||||
input,
|
||||
output: vec![output_descriptor],
|
||||
uuid: [0; 16],
|
||||
uuid: Uuid::nil(),
|
||||
block: "crafting_table".to_string(),
|
||||
priority: VarInt(1),
|
||||
unlock_requirement: RecipeUnlockRequirement { context: 1 },
|
||||
|
||||
Reference in New Issue
Block a user