mirror of
https://github.com/italicsjenga/valence.git
synced 2025-01-11 07:11:30 +11:00
Add player metadata to client
This commit is contained in:
parent
806ffa4f42
commit
1aa4ca878e
102
build/entity.rs
102
build/entity.rs
|
@ -2105,6 +2105,34 @@ pub fn build() -> anyhow::Result<()> {
|
|||
})
|
||||
.collect::<TokenStream>();
|
||||
|
||||
let initial_metadata_fields = fields.iter().enumerate().map(|(idx, f)| {
|
||||
let name = ident(f.name.to_snake_case());
|
||||
let default = f.typ.default_expr();
|
||||
let index: u8 = idx.try_into().unwrap();
|
||||
let type_id = f.typ.type_id();
|
||||
quote! {
|
||||
if self.#name != #default {
|
||||
data.push(#index);
|
||||
VarInt(#type_id).encode(data).unwrap();
|
||||
self.#name.encode(data).unwrap();
|
||||
}
|
||||
}
|
||||
}).collect::<TokenStream>();
|
||||
|
||||
let updated_metadata_fields = fields.iter().enumerate().map(|(idx, f)| {
|
||||
let name = ident(f.name.to_snake_case());
|
||||
let u8_index: u8 = idx.try_into().unwrap();
|
||||
let u32_index = idx as u32;
|
||||
let type_id = f.typ.type_id();
|
||||
quote! {
|
||||
if (self.modified_flags >> #u32_index) & 1 == 1 {
|
||||
data.push(#u8_index);
|
||||
VarInt(#type_id).encode(data).unwrap();
|
||||
self.#name.encode(data).unwrap();
|
||||
}
|
||||
}
|
||||
}).collect::<TokenStream>();
|
||||
|
||||
quote! {
|
||||
pub struct #name {
|
||||
/// Contains a set bit for each modified field.
|
||||
|
@ -2113,7 +2141,7 @@ pub fn build() -> anyhow::Result<()> {
|
|||
}
|
||||
|
||||
impl #name {
|
||||
pub(super) fn new() -> Self {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self {
|
||||
modified_flags: 0,
|
||||
#(#constructor_fields)*
|
||||
|
@ -2121,62 +2149,22 @@ pub fn build() -> anyhow::Result<()> {
|
|||
}
|
||||
|
||||
#getter_setters
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let initial_metadata_arms = entities.iter().map(|&entity| {
|
||||
let name = ident(entity.name.to_pascal_case());
|
||||
let mut fields = Vec::new();
|
||||
collect_class_fields(entity, &mut fields);
|
||||
|
||||
let check_fields = fields.into_iter().enumerate().map(|(idx, f)| {
|
||||
let name = ident(f.name.to_snake_case());
|
||||
let default = f.typ.default_expr();
|
||||
let index: u8 = idx.try_into().unwrap();
|
||||
let type_id = f.typ.type_id();
|
||||
quote! {
|
||||
if m.#name != #default {
|
||||
data.push(#index);
|
||||
VarInt(#type_id).encode(&mut data).unwrap();
|
||||
m.#name.encode(&mut data).unwrap();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
Self::#name(m) => {
|
||||
#(#check_fields)*
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let updated_metadata_arms = entities.iter().map(|&entity| {
|
||||
let name = ident(entity.name.to_pascal_case());
|
||||
let mut fields = Vec::new();
|
||||
collect_class_fields(entity, &mut fields);
|
||||
|
||||
let update_fields = fields.into_iter().enumerate().map(|(idx, f)| {
|
||||
let name = ident(f.name.to_snake_case());
|
||||
let u8_index: u8 = idx.try_into().unwrap();
|
||||
let u32_index = idx as u32;
|
||||
let type_id = f.typ.type_id();
|
||||
quote! {
|
||||
if (m.modified_flags >> #u32_index) & 1 == 1 {
|
||||
data.push(#u8_index);
|
||||
VarInt(#type_id).encode(&mut data).unwrap();
|
||||
m.#name.encode(&mut data).unwrap();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
Self::#name(m) => {
|
||||
if m.modified_flags == 0 {
|
||||
return None;
|
||||
pub(crate) fn initial_metadata(&self, data: &mut Vec<u8>) {
|
||||
#initial_metadata_fields
|
||||
}
|
||||
|
||||
#(#update_fields)*
|
||||
pub(crate) fn updated_metadata(&self, data: &mut Vec<u8>) {
|
||||
if self.modified_flags == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
#updated_metadata_fields
|
||||
}
|
||||
|
||||
pub(crate) fn clear_modifications(&mut self) {
|
||||
self.modified_flags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -2221,7 +2209,7 @@ pub fn build() -> anyhow::Result<()> {
|
|||
let mut data = Vec::new();
|
||||
|
||||
match self {
|
||||
#(#initial_metadata_arms)*
|
||||
#(Self::#entity_type_variants(e) => e.initial_metadata(&mut data),)*
|
||||
}
|
||||
|
||||
if data.is_empty() {
|
||||
|
@ -2236,7 +2224,7 @@ pub fn build() -> anyhow::Result<()> {
|
|||
let mut data = Vec::new();
|
||||
|
||||
match self {
|
||||
#(#updated_metadata_arms)*
|
||||
#(Self::#entity_type_variants(e) => e.updated_metadata(&mut data),)*
|
||||
}
|
||||
|
||||
if data.is_empty() {
|
||||
|
@ -2249,7 +2237,7 @@ pub fn build() -> anyhow::Result<()> {
|
|||
|
||||
pub(super) fn clear_modifications(&mut self) {
|
||||
match self {
|
||||
#(Self::#entity_type_variants(m) => m.modified_flags = 0,)*
|
||||
#(Self::#entity_type_variants(e) => e.clear_modifications(),)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@ use valence::config::{Config, ServerListPing};
|
|||
use valence::text::Color;
|
||||
use valence::util::to_yaw_and_pitch;
|
||||
use valence::{
|
||||
async_trait, DimensionId, EntityId, EntityType, Server, ShutdownResult, Text,
|
||||
TextFormat, WorldId, Worlds, Client,
|
||||
async_trait, Client, DimensionId, EntityId, EntityType, Server, ShutdownResult, Text,
|
||||
TextFormat, WorldId, Worlds,
|
||||
};
|
||||
use vek::{Mat3, Vec3};
|
||||
|
||||
|
|
|
@ -13,19 +13,20 @@ use crate::biome::{Biome, BiomeGrassColorModifier, BiomePrecipitation};
|
|||
use crate::block_pos::BlockPos;
|
||||
use crate::byte_angle::ByteAngle;
|
||||
use crate::dimension::{Dimension, DimensionEffects};
|
||||
use crate::entity::types::Player;
|
||||
use crate::entity::{velocity_to_packet_units, EntityType};
|
||||
use crate::packets::play::c2s::{C2sPlayPacket, DiggingStatus};
|
||||
use crate::packets::play::s2c::{
|
||||
AcknowledgeBlockChanges, Biome as BiomeRegistryBiome, BiomeAdditionsSound, BiomeEffects,
|
||||
BiomeMoodSound, BiomeMusic, BiomeParticle, BiomeParticleOptions, BiomeProperty, BiomeRegistry,
|
||||
ChangeGameState, ChangeGameStateReason, ChatTypeRegistry, DestroyEntities, DimensionType,
|
||||
DimensionTypeRegistry, DimensionTypeRegistryEntry, Disconnect, EntityHeadLook, EntityPosition,
|
||||
EntityPositionAndRotation, EntityRotation, EntityTeleport, EntityVelocity, JoinGame, KeepAlive,
|
||||
PlayerPositionAndLook, PlayerPositionAndLookFlags, RegistryCodec, S2cPlayPacket, SpawnPosition,
|
||||
UnloadChunk, UpdateViewDistance, UpdateViewPosition,
|
||||
DimensionTypeRegistry, DimensionTypeRegistryEntry, Disconnect, EntityHeadLook, EntityMetadata,
|
||||
EntityPosition, EntityPositionAndRotation, EntityRotation, EntityTeleport, EntityVelocity,
|
||||
JoinGame, KeepAlive, PlayerPositionAndLook, PlayerPositionAndLookFlags, RegistryCodec,
|
||||
S2cPlayPacket, SpawnPosition, UnloadChunk, UpdateViewDistance, UpdateViewPosition,
|
||||
};
|
||||
use crate::player_textures::SignedPlayerTextures;
|
||||
use crate::protocol::{BoundedInt, Nbt};
|
||||
use crate::protocol::{BoundedInt, Nbt, RawBytes};
|
||||
use crate::server::C2sPacketChannels;
|
||||
use crate::slotmap::{Key, SlotMap};
|
||||
use crate::util::{chunks_in_view_distance, is_chunk_in_view_distance};
|
||||
|
@ -135,8 +136,8 @@ pub struct Client {
|
|||
old_game_mode: GameMode,
|
||||
settings: Option<Settings>,
|
||||
dug_blocks: Vec<i32>,
|
||||
// /// The metadata for the client's own player entity.
|
||||
// player_meta: Player,
|
||||
/// The metadata for the client's own player entity.
|
||||
player_meta: Player,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
|
@ -177,6 +178,7 @@ impl Client {
|
|||
old_game_mode: GameMode::Survival,
|
||||
settings: None,
|
||||
dug_blocks: Vec::new(),
|
||||
player_meta: Player::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,6 +330,14 @@ impl Client {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn meta(&self) -> &Player {
|
||||
&self.player_meta
|
||||
}
|
||||
|
||||
pub fn meta_mut(&mut self) -> &mut Player {
|
||||
&mut self.player_meta
|
||||
}
|
||||
|
||||
/// Attempts to enqueue a play packet to be sent to this client. The client
|
||||
/// is disconnected if the clientbound packet buffer is full.
|
||||
pub(crate) fn send_packet(&mut self, packet: impl Into<S2cPlayPacket>) {
|
||||
|
@ -813,6 +823,21 @@ impl Client {
|
|||
});
|
||||
}
|
||||
|
||||
// Update the client's own player metadata.
|
||||
{
|
||||
let mut data = Vec::new();
|
||||
self.player_meta.updated_metadata(&mut data);
|
||||
|
||||
if !data.is_empty() {
|
||||
data.push(0xff);
|
||||
|
||||
self.send_packet(EntityMetadata {
|
||||
entity_id: VarInt(0),
|
||||
metadata: RawBytes(data),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Spawn new entities within the view distance.
|
||||
let pos = self.position();
|
||||
spatial_index.query::<_, _, ()>(
|
||||
|
|
Loading…
Reference in a new issue