Batch CSetEntityMetadata data

Allows us to send multiple meta in only one Packet
This commit is contained in:
Alexander Medvedev 2025-02-25 23:21:59 +01:00
parent 0f6c7aed73
commit b336a50955
6 changed files with 37 additions and 34 deletions

View File

@ -6,23 +6,21 @@ use crate::VarInt;
#[derive(Serialize)] #[derive(Serialize)]
#[packet(PLAY_SET_ENTITY_DATA)] #[packet(PLAY_SET_ENTITY_DATA)]
pub struct CSetEntityMetadata<T> { pub struct CSetEntityMetadata {
entity_id: VarInt, entity_id: VarInt,
metadata: Metadata<T>, metadata: Vec<u8>,
end: u8,
} }
impl<T> CSetEntityMetadata<T> { impl CSetEntityMetadata {
pub fn new(entity_id: VarInt, metadata: Metadata<T>) -> Self { pub fn new(entity_id: VarInt, metadata: Vec<u8>) -> Self {
Self { Self {
entity_id, entity_id,
metadata, metadata,
end: 255,
} }
} }
} }
#[derive(Serialize)] #[derive(Serialize, Clone)]
pub struct Metadata<T> { pub struct Metadata<T> {
index: u8, index: u8,
typ: VarInt, typ: VarInt,

View File

@ -33,7 +33,7 @@ impl ItemEntity {
pub async fn send_meta_packet(&self) { pub async fn send_meta_packet(&self) {
let slot = Slot::from(&self.item); let slot = Slot::from(&self.item);
self.entity self.entity
.send_meta_data(Metadata::new(8, MetaDataType::ItemStack, &slot)) .send_meta_data(&[Metadata::new(8, MetaDataType::ItemStack, &slot)])
.await; .await;
} }
} }

View File

@ -90,7 +90,7 @@ impl LivingEntity {
self.health.store(health); self.health.store(health);
// tell everyone entities health changed // tell everyone entities health changed
self.entity self.entity
.send_meta_data(Metadata::new(9, MetaDataType::Float, health)) .send_meta_data(&[Metadata::new(9, MetaDataType::Float, health)])
.await; .await;
} }

View File

@ -1,5 +1,6 @@
use crate::server::Server; use crate::server::Server;
use async_trait::async_trait; use async_trait::async_trait;
use bytes::{BufMut, BytesMut};
use core::f32; use core::f32;
use crossbeam::atomic::AtomicCell; use crossbeam::atomic::AtomicCell;
use living::LivingEntity; use living::LivingEntity;
@ -11,6 +12,7 @@ use pumpkin_data::{
}; };
use pumpkin_nbt::{compound::NbtCompound, tag::NbtTag}; use pumpkin_nbt::{compound::NbtCompound, tag::NbtTag};
use pumpkin_protocol::{ use pumpkin_protocol::{
bytebuf::serializer::Serializer,
client::play::{ client::play::{
CEntityVelocity, CHeadRot, CSetEntityMetadata, CSpawnEntity, CTeleportEntity, CEntityVelocity, CHeadRot, CSetEntityMetadata, CSpawnEntity, CTeleportEntity,
CUpdateEntityRot, MetaDataType, Metadata, CUpdateEntityRot, MetaDataType, Metadata,
@ -355,7 +357,7 @@ impl Entity {
} else { } else {
b &= !(1 << index); b &= !(1 << index);
} }
self.send_meta_data(Metadata::new(0, MetaDataType::Byte, b)) self.send_meta_data(&[Metadata::new(0, MetaDataType::Byte, b)])
.await; .await;
} }
@ -368,21 +370,29 @@ impl Entity {
.await; .await;
} }
pub async fn send_meta_data<T>(&self, meta: Metadata<T>) pub async fn send_meta_data<T>(&self, meta: &[Metadata<T>])
where where
T: Serialize, T: Serialize,
{ {
let mut buf = Vec::new();
for meta in meta {
let serializer_buf = BytesMut::new();
let mut serializer = Serializer::new(serializer_buf);
meta.serialize(&mut serializer).unwrap();
buf.put(serializer.output);
}
buf.put_u8(255);
self.world self.world
.read() .read()
.await .await
.broadcast_packet_all(&CSetEntityMetadata::new(self.entity_id.into(), meta)) .broadcast_packet_all(&CSetEntityMetadata::new(self.entity_id.into(), buf))
.await; .await;
} }
pub async fn set_pose(&self, pose: EntityPose) { pub async fn set_pose(&self, pose: EntityPose) {
self.pose.store(pose); self.pose.store(pose);
let pose = pose as i32; let pose = pose as i32;
self.send_meta_data(Metadata::new(6, MetaDataType::EntityPose, VarInt(pose))) self.send_meta_data(&[Metadata::new(6, MetaDataType::EntityPose, VarInt(pose))])
.await; .await;
} }

View File

@ -931,15 +931,10 @@ impl Player {
let config = self.config.lock().await; let config = self.config.lock().await;
self.living_entity self.living_entity
.entity .entity
.send_meta_data(Metadata::new(17, MetaDataType::Byte, config.skin_parts)) .send_meta_data(&[
.await; Metadata::new(17, MetaDataType::Byte, config.skin_parts),
self.living_entity Metadata::new(18, MetaDataType::Byte, config.main_hand as u8),
.entity ])
.send_meta_data(Metadata::new(
18,
MetaDataType::Byte,
config.main_hand as u8,
))
.await; .await;
} }

View File

@ -32,18 +32,18 @@ impl TNTEntity {
.await; .await;
// We can merge multiple data into one meta packet // We can merge multiple data into one meta packet
self.entity self.entity
.send_meta_data(Metadata::new( .send_meta_data(&[
Metadata::new(
8, 8,
MetaDataType::Integer, MetaDataType::Integer,
VarInt(self.fuse.load(std::sync::atomic::Ordering::Relaxed) as i32), VarInt(self.fuse.load(std::sync::atomic::Ordering::Relaxed) as i32),
)) ),
.await; Metadata::new(
self.entity
.send_meta_data(Metadata::new(
9, 9,
MetaDataType::BlockState, MetaDataType::BlockState,
VarInt(i32::from(block_state!("tnt").state_id)), VarInt(i32::from(block_state!("tnt").state_id)),
)) ),
])
.await; .await;
} }
} }