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)]
#[packet(PLAY_SET_ENTITY_DATA)]
pub struct CSetEntityMetadata<T> {
pub struct CSetEntityMetadata {
entity_id: VarInt,
metadata: Metadata<T>,
end: u8,
metadata: Vec<u8>,
}
impl<T> CSetEntityMetadata<T> {
pub fn new(entity_id: VarInt, metadata: Metadata<T>) -> Self {
impl CSetEntityMetadata {
pub fn new(entity_id: VarInt, metadata: Vec<u8>) -> Self {
Self {
entity_id,
metadata,
end: 255,
}
}
}
#[derive(Serialize)]
#[derive(Serialize, Clone)]
pub struct Metadata<T> {
index: u8,
typ: VarInt,

View File

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

View File

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

View File

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

View File

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

View File

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