From 0a76db406574da85a28802c5945c09d18c86b8ea Mon Sep 17 00:00:00 2001 From: Bafbi Date: Sun, 30 Jul 2023 19:13:10 +0200 Subject: [PATCH 1/9] put all packets into tha valence_packet crate --- Cargo.toml | 2 + benches/packet.rs | 6 +- crates/valence_advancement/Cargo.toml | 1 + crates/valence_advancement/src/event.rs | 2 +- crates/valence_advancement/src/lib.rs | 31 +- crates/valence_client/Cargo.toml | 1 + crates/valence_client/src/action.rs | 2 +- crates/valence_client/src/lib.rs | 10 +- crates/valence_client/src/message.rs | 2 +- crates/valence_client/src/op_level.rs | 2 +- crates/valence_client/src/weather.rs | 2 +- crates/valence_core/src/lib.rs | 1 + crates/valence_core/src/protocol.rs | 1 - .../src/protocol/{packet.rs => packet.old.rs} | 0 crates/valence_core/src/sound.rs | 73 +++ crates/valence_entity/Cargo.toml | 1 + crates/valence_entity/src/lib.rs | 1 - crates/valence_instance/Cargo.toml | 1 + crates/valence_instance/src/chunk/loaded.rs | 2 +- crates/valence_instance/src/instance.rs | 3 +- crates/valence_instance/src/lib.rs | 3 +- crates/valence_inventory/Cargo.toml | 1 + crates/valence_inventory/src/lib.rs | 5 +- crates/valence_inventory/src/validate.rs | 4 +- crates/valence_network/Cargo.toml | 1 + crates/valence_network/src/connect.rs | 2 +- crates/valence_network/src/lib.rs | 1 - crates/valence_packet/Cargo.toml | 13 + crates/valence_packet/README.md | 1 + .../src/advancement.rs} | 29 +- crates/valence_packet/src/boss_bar.rs | 24 + crates/valence_packet/src/chat.rs | 239 ++++++++++ .../src/client.rs} | 21 +- crates/valence_packet/src/command.rs | 434 ++++++++++++++++++ .../src/entity.rs} | 14 +- .../src/instance.rs} | 13 +- .../src/inventory.rs} | 12 +- crates/valence_packet/src/lib.rs | 39 ++ crates/valence_packet/src/map.rs | 109 +++++ .../src/network.rs} | 10 +- .../src/player_list.rs} | 17 +- crates/valence_packet/src/scoreboard.rs | 342 ++++++++++++++ crates/valence_packet/src/sound.rs | 90 ++++ .../src/world_border.rs} | 4 +- crates/valence_player_list/Cargo.toml | 1 + crates/valence_player_list/src/lib.rs | 13 +- crates/valence_world_border/Cargo.toml | 1 + crates/valence_world_border/src/lib.rs | 4 +- examples/parkour.rs | 2 +- src/lib.rs | 1 + src/tests/client.rs | 4 +- src/tests/example.rs | 2 +- src/tests/instance.rs | 2 +- src/tests/inventory.rs | 4 +- src/tests/player_list.rs | 4 +- src/tests/weather.rs | 2 +- src/tests/world_border.rs | 2 +- tools/packet_inspector/src/lib.rs | 2 +- tools/stresser/Cargo.toml | 1 + tools/stresser/src/stresser.rs | 2 +- 60 files changed, 1462 insertions(+), 157 deletions(-) rename crates/valence_core/src/protocol/{packet.rs => packet.old.rs} (100%) create mode 100644 crates/valence_core/src/sound.rs create mode 100644 crates/valence_packet/Cargo.toml create mode 100644 crates/valence_packet/README.md rename crates/{valence_advancement/src/packet.rs => valence_packet/src/advancement.rs} (80%) create mode 100644 crates/valence_packet/src/boss_bar.rs create mode 100644 crates/valence_packet/src/chat.rs rename crates/{valence_client/src/packet.rs => valence_packet/src/client.rs} (94%) create mode 100644 crates/valence_packet/src/command.rs rename crates/{valence_entity/src/packet.rs => valence_packet/src/entity.rs} (95%) rename crates/{valence_instance/src/packet.rs => valence_packet/src/instance.rs} (91%) rename crates/{valence_inventory/src/packet.rs => valence_packet/src/inventory.rs} (99%) create mode 100644 crates/valence_packet/src/lib.rs create mode 100644 crates/valence_packet/src/map.rs rename crates/{valence_network/src/packet.rs => valence_packet/src/network.rs} (90%) rename crates/{valence_player_list/src/packet.rs => valence_packet/src/player_list.rs} (89%) create mode 100644 crates/valence_packet/src/scoreboard.rs create mode 100644 crates/valence_packet/src/sound.rs rename crates/{valence_world_border/src/packet.rs => valence_packet/src/world_border.rs} (89%) diff --git a/Cargo.toml b/Cargo.toml index 3fd30423c..84bf5ce5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,6 +55,7 @@ valence_network = { workspace = true, optional = true } valence_player_list = { workspace = true, optional = true } valence_registry.workspace = true valence_world_border = { workspace = true, optional = true } +valence_packet.workspace = true [dev-dependencies] anyhow.workspace = true @@ -178,5 +179,6 @@ valence_player_list.path = "crates/valence_player_list" valence_registry.path = "crates/valence_registry" valence_world_border.path = "crates/valence_world_border" valence_boss_bar.path = "crates/valence_boss_bar" +valence_packet.path = "crates/valence_packet" valence.path = "." zip = "0.6.3" diff --git a/benches/packet.rs b/benches/packet.rs index 8de29f113..9ad3fb945 100644 --- a/benches/packet.rs +++ b/benches/packet.rs @@ -11,9 +11,9 @@ use valence::protocol::encode::PacketEncoder; use valence::protocol::var_int::VarInt; use valence::text::IntoText; use valence_core::protocol::encode::{PacketWriter, WritePacket}; -use valence_entity::packet::EntitySpawnS2c; -use valence_instance::packet::ChunkDataS2c; -use valence_player_list::packet::PlayerListHeaderS2c; +use valence_packet::entity::EntitySpawnS2c; +use valence_packet::instance::ChunkDataS2c; +use valence_packet::player_list::PlayerListHeaderS2c; pub fn packet(c: &mut Criterion) { let mut group = c.benchmark_group("packet"); diff --git a/crates/valence_advancement/Cargo.toml b/crates/valence_advancement/Cargo.toml index 76d0aebd0..5a8514e8c 100644 --- a/crates/valence_advancement/Cargo.toml +++ b/crates/valence_advancement/Cargo.toml @@ -6,6 +6,7 @@ edition.workspace = true [dependencies] valence_core.workspace = true valence_client.workspace = true +valence_packet.workspace = true bevy_app.workspace = true bevy_ecs.workspace = true bevy_hierarchy.workspace = true diff --git a/crates/valence_advancement/src/event.rs b/crates/valence_advancement/src/event.rs index 2d05aa068..a2e42ccde 100644 --- a/crates/valence_advancement/src/event.rs +++ b/crates/valence_advancement/src/event.rs @@ -2,7 +2,7 @@ use bevy_ecs::prelude::*; use valence_client::event_loop::PacketEvent; use valence_core::ident::Ident; -use crate::packet::AdvancementTabC2s; +use valence_packet::advancement::AdvancementTabC2s; /// This event sends when the client changes or closes advancement's tab. #[derive(Event, Clone, PartialEq, Eq, Debug)] diff --git a/crates/valence_advancement/src/lib.rs b/crates/valence_advancement/src/lib.rs index 755b07487..161ae794f 100644 --- a/crates/valence_advancement/src/lib.rs +++ b/crates/valence_advancement/src/lib.rs @@ -2,7 +2,6 @@ #![allow(clippy::type_complexity)] pub mod event; -pub mod packet; use std::borrow::Cow; use std::io::Write; @@ -14,7 +13,9 @@ use bevy_ecs::system::SystemParam; pub use bevy_hierarchy; use bevy_hierarchy::{Children, HierarchyPlugin, Parent}; use event::{handle_advancement_tab_change, AdvancementTabChangeEvent}; -use packet::SelectAdvancementTabS2c; +use valence_packet::advancement::{SelectAdvancementTabS2c, AdvancementRequirementsPkt, GenericAdvancementUpdateS2c, AdvancementCriteriaPkt}; +use valence_packet::advancement::AdvancementPkt; +use valence_packet::advancement::AdvancementDisplayPkt; use rustc_hash::FxHashMap; use valence_client::{Client, FlushPacketsSet, SpawnClientsSet}; use valence_core::ident::Ident; @@ -92,7 +93,8 @@ struct UpdateAdvancementCachedBytesQuery<'w, 's> { impl<'w, 's> UpdateAdvancementCachedBytesQuery<'w, 's> { fn write( &self, - a_identifier: &Advancement, + a_identifier: &Advancement +, a_requirements: &AdvancementRequirements, a_display: Option<&AdvancementDisplay>, a_children: Option<&Children>, @@ -104,7 +106,8 @@ impl<'w, 's> UpdateAdvancementCachedBytesQuery<'w, 's> { criteria_query, } = self; - let mut pkt = packet::Advancement { + let mut pkt = AdvancementPkt + { parent_id: None, display_data: None, criteria: vec![], @@ -118,7 +121,7 @@ impl<'w, 's> UpdateAdvancementCachedBytesQuery<'w, 's> { } if let Some(a_display) = a_display { - pkt.display_data = Some(packet::AdvancementDisplay { + pkt.display_data = Some(AdvancementDisplayPkt { title: Cow::Borrowed(&a_display.title), description: Cow::Borrowed(&a_display.description), icon: &a_display.icon, @@ -145,7 +148,7 @@ impl<'w, 's> UpdateAdvancementCachedBytesQuery<'w, 's> { let c_identifier = criteria_query.get(*requirement)?; requirements_p.push(c_identifier.0.as_str()); } - pkt.requirements.push(packet::AdvancementRequirements { + pkt.requirements.push(AdvancementRequirementsPkt { requirement: requirements_p, }); } @@ -157,7 +160,8 @@ impl<'w, 's> UpdateAdvancementCachedBytesQuery<'w, 's> { fn update_advancement_cached_bytes( mut query: Query< ( - &Advancement, + &Advancement + , &AdvancementRequirements, &mut AdvancementCachedBytes, Option<&AdvancementDisplay>, @@ -222,7 +226,7 @@ impl<'w, 's, 'a> Encode for AdvancementUpdateEncodeS2c<'w, 's, 'a> { reset, } = &self.client_update; - let mut pkt = packet::GenericAdvancementUpdateS2c { + let mut pkt = GenericAdvancementUpdateS2c { reset: *reset, advancement_mapping: vec![], identifiers: vec![], @@ -255,7 +259,7 @@ impl<'w, 's, 'a> Encode for AdvancementUpdateEncodeS2c<'w, 's, 'a> { let mut c_progresses_p = vec![]; for (c, c_progress) in c_progresses { let c_identifier = criteria_query.get(c)?; - c_progresses_p.push(packet::AdvancementCriteria { + c_progresses_p.push(AdvancementCriteriaPkt { criterion_identifier: c_identifier.0.borrowed(), criterion_progress: c_progress, }); @@ -432,7 +436,8 @@ impl AdvancementClientUpdate { pub(crate) fn walk_advancements( root: Entity, children_query: &Query<&Children>, - advancement_check_query: &Query<(), With>, + advancement_check_query: &Query<(), With>, func: &mut impl FnMut(Entity), ) { func(root); @@ -451,7 +456,8 @@ impl AdvancementClientUpdate { &mut self, root: Entity, children_query: &Query<&Children>, - advancement_check_query: &Query<(), With>, + advancement_check_query: &Query<(), With>, ) { Self::walk_advancements(root, children_query, advancement_check_query, &mut |e| { self.new_advancements.push(e) @@ -463,7 +469,8 @@ impl AdvancementClientUpdate { &mut self, root: Entity, children_query: &Query<&Children>, - advancement_check_query: &Query<(), With>, + advancement_check_query: &Query<(), With>, ) { Self::walk_advancements(root, children_query, advancement_check_query, &mut |e| { self.remove_advancements.push(e) diff --git a/crates/valence_client/Cargo.toml b/crates/valence_client/Cargo.toml index b7df47732..85dc97447 100644 --- a/crates/valence_client/Cargo.toml +++ b/crates/valence_client/Cargo.toml @@ -19,5 +19,6 @@ valence_core.workspace = true valence_dimension.workspace = true valence_entity.workspace = true valence_instance.workspace = true +valence_packet.workspace = true valence_nbt.workspace = true valence_registry.workspace = true diff --git a/crates/valence_client/src/action.rs b/crates/valence_client/src/action.rs index c23e1e8e8..2589d7ad2 100644 --- a/crates/valence_client/src/action.rs +++ b/crates/valence_client/src/action.rs @@ -5,7 +5,7 @@ use valence_core::protocol::{packet_id, Decode, Encode, Packet}; use super::*; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; -use crate::packet::{PlayerAction, PlayerActionC2s}; +use valence_packet::client::{PlayerAction, PlayerActionC2s}; pub(super) fn build(app: &mut App) { app.add_event::() diff --git a/crates/valence_client/src/lib.rs b/crates/valence_client/src/lib.rs index 9dd7aff18..5f7fc1ee5 100644 --- a/crates/valence_client/src/lib.rs +++ b/crates/valence_client/src/lib.rs @@ -30,7 +30,7 @@ use bevy_ecs::query::WorldQuery; use bevy_ecs::system::Command; use bytes::{Bytes, BytesMut}; use glam::{DVec3, Vec3}; -use packet::{ +use valence_packet::client::{ DeathMessageS2c, DisconnectS2c, GameEventKind, GameJoinS2c, GameStateChangeS2c, PlayerRespawnS2c, PlayerSpawnPositionS2c, PlayerSpawnS2c, }; @@ -47,12 +47,13 @@ use valence_core::property::Property; use valence_core::protocol::byte_angle::ByteAngle; use valence_core::protocol::encode::{PacketEncoder, WritePacket}; use valence_core::protocol::global_pos::GlobalPos; -use valence_core::protocol::packet::sound::{PlaySoundS2c, Sound, SoundCategory}; +use valence_packet::sound::PlaySoundS2c; +use valence_core::sound::{Sound, SoundCategory}; use valence_core::protocol::var_int::VarInt; use valence_core::protocol::{Encode, Packet}; use valence_core::text::{IntoText, Text}; use valence_core::uuid::UniqueId; -use valence_entity::packet::{ +use valence_packet::entity::{ EntitiesDestroyS2c, EntitySetHeadYawS2c, EntitySpawnS2c, EntityStatusS2c, EntityTrackerUpdateS2c, EntityVelocityUpdateS2c, ExperienceOrbSpawnS2c, }; @@ -62,7 +63,7 @@ use valence_entity::{ OldLocation, OldPosition, OnGround, PacketByteRange, Position, TrackedData, Velocity, }; use valence_instance::chunk::loaded::ChunkState; -use valence_instance::packet::{ +use valence_packet::instance::{ ChunkLoadDistanceS2c, ChunkRenderDistanceCenterS2c, UnloadChunkS2c, }; use valence_instance::{ClearInstanceChangesSet, Instance, WriteUpdatePacketsToInstancesSet}; @@ -82,7 +83,6 @@ pub mod keepalive; pub mod message; pub mod movement; pub mod op_level; -pub mod packet; pub mod resource_pack; pub mod settings; pub mod status; diff --git a/crates/valence_client/src/message.rs b/crates/valence_client/src/message.rs index c7b91ff69..8a5483490 100644 --- a/crates/valence_client/src/message.rs +++ b/crates/valence_client/src/message.rs @@ -3,7 +3,7 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use valence_core::protocol::encode::WritePacket; -use valence_core::protocol::packet::chat::{ChatMessageC2s, GameMessageS2c}; +use valence_packet::chat::{ChatMessageC2s, GameMessageS2c}; use valence_core::text::IntoText; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; diff --git a/crates/valence_client/src/op_level.rs b/crates/valence_client/src/op_level.rs index 7cf0ed5b4..955d59b63 100644 --- a/crates/valence_client/src/op_level.rs +++ b/crates/valence_client/src/op_level.rs @@ -1,4 +1,4 @@ -use valence_entity::packet::EntityStatusS2c; +use valence_packet::entity::EntityStatusS2c; use super::*; diff --git a/crates/valence_client/src/weather.rs b/crates/valence_client/src/weather.rs index 2f0ce9788..07480c469 100644 --- a/crates/valence_client/src/weather.rs +++ b/crates/valence_client/src/weather.rs @@ -16,7 +16,7 @@ //! the instance. use super::*; -use crate::packet::{GameEventKind, GameStateChangeS2c}; +use valence_packet::client::{GameEventKind, GameStateChangeS2c}; #[derive(SystemSet, Copy, Clone, PartialEq, Eq, Hash, Debug)] struct UpdateWeatherPerInstanceSet; diff --git a/crates/valence_core/src/lib.rs b/crates/valence_core/src/lib.rs index 1ba0106ac..2873b986a 100644 --- a/crates/valence_core/src/lib.rs +++ b/crates/valence_core/src/lib.rs @@ -36,6 +36,7 @@ pub mod scratch; pub mod text; pub mod translation_key; pub mod uuid; +pub mod sound; use std::num::NonZeroU32; use std::time::Duration; diff --git a/crates/valence_core/src/protocol.rs b/crates/valence_core/src/protocol.rs index a1e27f3f2..6998c2c43 100644 --- a/crates/valence_core/src/protocol.rs +++ b/crates/valence_core/src/protocol.rs @@ -6,7 +6,6 @@ pub mod decode; pub mod encode; pub mod global_pos; pub mod impls; -pub mod packet; pub mod raw; pub mod var_int; pub mod var_long; diff --git a/crates/valence_core/src/protocol/packet.rs b/crates/valence_core/src/protocol/packet.old.rs similarity index 100% rename from crates/valence_core/src/protocol/packet.rs rename to crates/valence_core/src/protocol/packet.old.rs diff --git a/crates/valence_core/src/sound.rs b/crates/valence_core/src/sound.rs new file mode 100644 index 000000000..27177f307 --- /dev/null +++ b/crates/valence_core/src/sound.rs @@ -0,0 +1,73 @@ +use std::borrow::Cow; +use std::io::Write; + +use crate::ident; +use crate::ident::Ident; +use crate::protocol::var_int::VarInt; +use crate::protocol::{Decode, Encode}; + +include!(concat!(env!("OUT_DIR"), "/sound.rs")); + +impl Sound { + pub fn to_id(self) -> SoundId<'static> { + SoundId::Direct { + id: self.to_ident().into(), + range: None, + } + } +} + +#[derive(Clone, PartialEq, Debug)] +pub enum SoundId<'a> { + Direct { + id: Ident>, + range: Option, + }, + Reference { + id: VarInt, + }, +} + +impl Encode for SoundId<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + match self { + SoundId::Direct { id, range } => { + VarInt(0).encode(&mut w)?; + id.encode(&mut w)?; + range.encode(&mut w)?; + } + SoundId::Reference { id } => VarInt(id.0 + 1).encode(&mut w)?, + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for SoundId<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let i = VarInt::decode(r)?.0; + + if i == 0 { + Ok(SoundId::Direct { + id: Ident::decode(r)?, + range: >::decode(r)?, + }) + } else { + Ok(SoundId::Reference { id: VarInt(i - 1) }) + } + } +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum SoundCategory { + Master, + Music, + Record, + Weather, + Block, + Hostile, + Neutral, + Player, + Ambient, + Voice, +} \ No newline at end of file diff --git a/crates/valence_entity/Cargo.toml b/crates/valence_entity/Cargo.toml index 1e6d564b9..c6383b515 100644 --- a/crates/valence_entity/Cargo.toml +++ b/crates/valence_entity/Cargo.toml @@ -16,6 +16,7 @@ uuid.workspace = true valence_block.workspace = true valence_core.workspace = true valence_nbt.workspace = true +valence_packet.workspace = true [build-dependencies] anyhow.workspace = true diff --git a/crates/valence_entity/src/lib.rs b/crates/valence_entity/src/lib.rs index 3d9ef9f16..9d2aed9f0 100644 --- a/crates/valence_entity/src/lib.rs +++ b/crates/valence_entity/src/lib.rs @@ -18,7 +18,6 @@ )] pub mod hitbox; -pub mod packet; use std::num::Wrapping; use std::ops::Range; diff --git a/crates/valence_instance/Cargo.toml b/crates/valence_instance/Cargo.toml index 6f9266bb3..aed86209b 100644 --- a/crates/valence_instance/Cargo.toml +++ b/crates/valence_instance/Cargo.toml @@ -20,3 +20,4 @@ valence_dimension.workspace = true valence_entity.workspace = true valence_nbt.workspace = true valence_registry.workspace = true +valence_packet.workspace = true diff --git a/crates/valence_instance/src/chunk/loaded.rs b/crates/valence_instance/src/chunk/loaded.rs index 7ced7e1aa..963fc71db 100644 --- a/crates/valence_instance/src/chunk/loaded.rs +++ b/crates/valence_instance/src/chunk/loaded.rs @@ -24,7 +24,7 @@ use super::{ bit_width, check_biome_oob, check_block_oob, check_section_oob, unloaded, BiomeContainer, BlockStateContainer, Chunk, UnloadedChunk, SECTION_BLOCK_COUNT, }; -use crate::packet::{ +use valence_packet::instance::{ BlockEntityUpdateS2c, BlockUpdateS2c, ChunkBiome, ChunkBiomeDataS2c, ChunkDataBlockEntity, ChunkDataS2c, ChunkDeltaUpdateS2c, }; diff --git a/crates/valence_instance/src/instance.rs b/crates/valence_instance/src/instance.rs index 174849f92..9334942b5 100644 --- a/crates/valence_instance/src/instance.rs +++ b/crates/valence_instance/src/instance.rs @@ -14,7 +14,8 @@ use valence_core::ident::Ident; use valence_core::particle::{Particle, ParticleS2c}; use valence_core::protocol::array::LengthPrefixedArray; use valence_core::protocol::encode::{PacketWriter, WritePacket}; -use valence_core::protocol::packet::sound::{PlaySoundS2c, Sound, SoundCategory}; +use valence_packet::sound::PlaySoundS2c; +use valence_core::sound::{Sound, SoundCategory}; use valence_core::protocol::{Encode, Packet}; use valence_core::Server; use valence_dimension::DimensionTypeRegistry; diff --git a/crates/valence_instance/src/lib.rs b/crates/valence_instance/src/lib.rs index d9f9fb34e..9a2145a44 100644 --- a/crates/valence_instance/src/lib.rs +++ b/crates/valence_instance/src/lib.rs @@ -29,7 +29,7 @@ use valence_core::despawn::Despawned; use valence_core::protocol::byte_angle::ByteAngle; use valence_core::protocol::encode::WritePacket; use valence_core::protocol::var_int::VarInt; -use valence_entity::packet::{ +use valence_packet::entity::{ EntityAnimationS2c, EntityPositionS2c, EntitySetHeadYawS2c, EntityStatusS2c, EntityTrackerUpdateS2c, EntityVelocityUpdateS2c, MoveRelativeS2c, RotateAndMoveRelativeS2c, RotateS2c, @@ -42,7 +42,6 @@ use valence_entity::{ pub mod chunk; mod instance; -pub mod packet; pub use chunk::{Block, BlockRef}; pub use instance::*; diff --git a/crates/valence_inventory/Cargo.toml b/crates/valence_inventory/Cargo.toml index 4e0a8d70a..2128f02ab 100644 --- a/crates/valence_inventory/Cargo.toml +++ b/crates/valence_inventory/Cargo.toml @@ -10,3 +10,4 @@ bevy_ecs.workspace = true tracing.workspace = true valence_client.workspace = true valence_core.workspace = true +valence_packet.workspace = true diff --git a/crates/valence_inventory/src/lib.rs b/crates/valence_inventory/src/lib.rs index cf7f58247..cf82a974e 100644 --- a/crates/valence_inventory/src/lib.rs +++ b/crates/valence_inventory/src/lib.rs @@ -25,14 +25,14 @@ use std::ops::Range; use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use packet::{ +use valence_packet::inventory::{ ClickMode, ClickSlotC2s, CloseHandledScreenC2s, CloseScreenS2c, CreativeInventoryActionC2s, InventoryS2c, OpenScreenS2c, ScreenHandlerSlotUpdateS2c, SlotChange, UpdateSelectedSlotC2s, WindowType, }; use tracing::{debug, warn}; use valence_client::event_loop::{EventLoopPreUpdate, PacketEvent}; -use valence_client::packet::{PlayerAction, PlayerActionC2s}; +use valence_packet::client::{PlayerAction, PlayerActionC2s}; use valence_client::{Client, FlushPacketsSet, SpawnClientsSet}; use valence_core::game_mode::GameMode; use valence_core::item::ItemStack; @@ -40,7 +40,6 @@ use valence_core::protocol::encode::WritePacket; use valence_core::protocol::var_int::VarInt; use valence_core::text::{IntoText, Text}; -pub mod packet; mod validate; pub struct InventoryPlugin; diff --git a/crates/valence_inventory/src/validate.rs b/crates/valence_inventory/src/validate.rs index d07f17b26..614b7882b 100644 --- a/crates/valence_inventory/src/validate.rs +++ b/crates/valence_inventory/src/validate.rs @@ -2,7 +2,7 @@ use anyhow::{bail, ensure}; use valence_core::item::ItemStack; use super::{CursorItem, Inventory, InventoryWindow, PLAYER_INVENTORY_MAIN_SLOTS_COUNT}; -use crate::packet::{ClickMode, ClickSlotC2s}; +use valence_packet::inventory::{ClickMode, ClickSlotC2s}; /// Validates a click slot packet enforcing that all fields are valid. pub(super) fn validate_click_slot_packet( @@ -361,7 +361,7 @@ mod tests { use valence_core::protocol::var_int::VarInt; use super::*; - use crate::packet::SlotChange; + use valence_packet::inventory::SlotChange; use crate::InventoryKind; #[test] diff --git a/crates/valence_network/Cargo.toml b/crates/valence_network/Cargo.toml index 7263c9927..870bc0c8d 100644 --- a/crates/valence_network/Cargo.toml +++ b/crates/valence_network/Cargo.toml @@ -32,6 +32,7 @@ uuid.workspace = true valence_client.workspace = true valence_core.workspace = true valence_entity.workspace = true +valence_packet.workspace = true [dependencies.reqwest] workspace = true diff --git a/crates/valence_network/src/connect.rs b/crates/valence_network/src/connect.rs index cda4940a0..feb36c9e9 100644 --- a/crates/valence_network/src/connect.rs +++ b/crates/valence_network/src/connect.rs @@ -28,7 +28,7 @@ use valence_core::text::{Color, IntoText, Text}; use valence_core::{ident, translation_key, MINECRAFT_VERSION, PROTOCOL_VERSION}; use crate::legacy_ping::try_handle_legacy_ping; -use crate::packet::{ +use valence_packet::network::{ HandshakeC2s, HandshakeNextState, LoginCompressionS2c, LoginDisconnectS2c, LoginHelloC2s, LoginHelloS2c, LoginKeyC2s, LoginQueryRequestS2c, LoginQueryResponseC2s, LoginSuccessS2c, QueryPingC2s, QueryPongS2c, QueryRequestC2s, QueryResponseS2c, diff --git a/crates/valence_network/src/lib.rs b/crates/valence_network/src/lib.rs index 20c971388..431c84bf6 100644 --- a/crates/valence_network/src/lib.rs +++ b/crates/valence_network/src/lib.rs @@ -20,7 +20,6 @@ mod byte_channel; mod connect; mod legacy_ping; -pub mod packet; mod packet_io; use std::borrow::Cow; diff --git a/crates/valence_packet/Cargo.toml b/crates/valence_packet/Cargo.toml new file mode 100644 index 000000000..fa6a5c708 --- /dev/null +++ b/crates/valence_packet/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "valence_packet" +version.workspace = true +edition.workspace = true + +[dependencies] +valence_core.workspace = true +valence_nbt.workspace = true +anyhow.workspace = true +bitfield-struct.workspace = true +byteorder.workspace = true +glam.workspace = true +uuid = { workspace = true, features = ["serde"] } \ No newline at end of file diff --git a/crates/valence_packet/README.md b/crates/valence_packet/README.md new file mode 100644 index 000000000..f87f5c14c --- /dev/null +++ b/crates/valence_packet/README.md @@ -0,0 +1 @@ +# TODO \ No newline at end of file diff --git a/crates/valence_advancement/src/packet.rs b/crates/valence_packet/src/advancement.rs similarity index 80% rename from crates/valence_advancement/src/packet.rs rename to crates/valence_packet/src/advancement.rs index e782e49a9..292241a71 100644 --- a/crates/valence_advancement/src/packet.rs +++ b/crates/valence_packet/src/advancement.rs @@ -1,14 +1,7 @@ -use std::borrow::Cow; -use std::io::Write; - -use valence_core::ident::Ident; -use valence_core::item::ItemStack; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; -use valence_core::text::Text; +use super::*; pub type AdvancementUpdateS2c<'a> = - GenericAdvancementUpdateS2c<'a, (Ident>, Advancement<'a, Option>)>; + GenericAdvancementUpdateS2c<'a, (Ident>, AdvancementPkt<'a, Option>)>; #[derive(Clone, Debug, Encode, Decode, Packet)] #[packet(id = packet_id::ADVANCEMENT_UPDATE_S2C)] @@ -16,25 +9,25 @@ pub struct GenericAdvancementUpdateS2c<'a, AM: 'a> { pub reset: bool, pub advancement_mapping: Vec, pub identifiers: Vec>>, - pub progress_mapping: Vec<(Ident>, Vec>)>, + pub progress_mapping: Vec<(Ident>, Vec>)>, } #[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct Advancement<'a, I> { +pub struct AdvancementPkt<'a, I> { pub parent_id: Option>>, - pub display_data: Option>, + pub display_data: Option>, pub criteria: Vec<(Ident>, ())>, - pub requirements: Vec>, + pub requirements: Vec>, pub sends_telemetry_data: bool, } #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub struct AdvancementRequirements<'a> { +pub struct AdvancementRequirementsPkt<'a> { pub requirement: Vec<&'a str>, } #[derive(Clone, PartialEq, Debug)] -pub struct AdvancementDisplay<'a, I> { +pub struct AdvancementDisplayPkt<'a, I> { pub title: Cow<'a, Text>, pub description: Cow<'a, Text>, pub icon: I, @@ -46,14 +39,14 @@ pub struct AdvancementDisplay<'a, I> { } #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub struct AdvancementCriteria<'a> { +pub struct AdvancementCriteriaPkt<'a> { pub criterion_identifier: Ident>, /// If present, the criteria has been achieved at the /// time wrapped; time represented as millis since epoch pub criterion_progress: Option, } -impl Encode for AdvancementDisplay<'_, I> { +impl Encode for AdvancementDisplayPkt<'_, I> { fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { self.title.encode(&mut w)?; self.description.encode(&mut w)?; @@ -73,7 +66,7 @@ impl Encode for AdvancementDisplay<'_, I> { } } -impl<'a, I: Decode<'a>> Decode<'a> for AdvancementDisplay<'a, I> { +impl<'a, I: Decode<'a>> Decode<'a> for AdvancementDisplayPkt<'a, I> { fn decode(r: &mut &'a [u8]) -> anyhow::Result { let title = >::decode(r)?; let description = >::decode(r)?; diff --git a/crates/valence_packet/src/boss_bar.rs b/crates/valence_packet/src/boss_bar.rs new file mode 100644 index 000000000..feff21558 --- /dev/null +++ b/crates/valence_packet/src/boss_bar.rs @@ -0,0 +1,24 @@ +use super::*; + +// #[derive(Clone, Debug, Encode, Decode, Packet)] +// #[packet(id = packet_id::BOSS_BAR_S2C)] +// pub struct BossBarS2c<'a> { +// pub id: Uuid, +// pub action: BossBarAction<'a>, +// } + +// #[derive(Clone, PartialEq, Debug, Encode, Decode)] +// pub enum BossBarAction<'a> { +// Add { +// title: Cow<'a, Text>, +// health: f32, +// color: BossBarColor, +// division: BossBarDivision, +// flags: BossBarFlags, +// }, +// Remove, +// UpdateHealth(f32), +// UpdateTitle(Cow<'a, Text>), +// UpdateStyle(BossBarColor, BossBarDivision), +// UpdateFlags(BossBarFlags), +// } diff --git a/crates/valence_packet/src/chat.rs b/crates/valence_packet/src/chat.rs new file mode 100644 index 000000000..13e18d4bb --- /dev/null +++ b/crates/valence_packet/src/chat.rs @@ -0,0 +1,239 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::GAME_MESSAGE_S2C)] +pub struct GameMessageS2c<'a> { + pub chat: Cow<'a, Text>, + /// Whether the message is in the actionbar or the chat. + pub overlay: bool, +} + +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct MessageSignature<'a> { + pub message_id: i32, + pub signature: Option<&'a [u8; 256]>, +} + +impl<'a> Encode for MessageSignature<'a> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + VarInt(self.message_id + 1).encode(&mut w)?; + + match self.signature { + None => {} + Some(signature) => signature.encode(&mut w)?, + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for MessageSignature<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let message_id = VarInt::decode(r)?.0 - 1; // TODO: this can underflow. + + let signature = if message_id == -1 { + Some(<&[u8; 256]>::decode(r)?) + } else { + None + }; + + Ok(Self { + message_id, + signature, + }) + } +} + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CHAT_MESSAGE_C2S)] +pub struct ChatMessageC2s<'a> { + pub message: &'a str, + pub timestamp: u64, + pub salt: u64, + pub signature: Option<&'a [u8; 256]>, + pub message_count: VarInt, + // This is a bitset of 20; each bit represents one + // of the last 20 messages received and whether or not + // the message was acknowledged by the client + pub acknowledgement: [u8; 3], +} + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::COMMAND_EXECUTION_C2S)] +pub struct CommandExecutionC2s<'a> { + pub command: &'a str, + pub timestamp: u64, + pub salt: u64, + pub argument_signatures: Vec>, + pub message_count: VarInt, + //// This is a bitset of 20; each bit represents one + //// of the last 20 messages received and whether or not + //// the message was acknowledged by the client + pub acknowledgement: [u8; 3], +} + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct CommandArgumentSignature<'a> { + pub argument_name: &'a str, + pub signature: &'a [u8; 256], +} + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::MESSAGE_ACKNOWLEDGMENT_C2S)] + +pub struct MessageAcknowledgmentC2s { + pub message_count: VarInt, +} + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAYER_SESSION_C2S)] +pub struct PlayerSessionC2s<'a> { + pub session_id: Uuid, + // Public key + pub expires_at: i64, + pub public_key_data: &'a [u8], + pub key_signature: &'a [u8], +} + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::REQUEST_COMMAND_COMPLETIONS_C2S)] +pub struct RequestCommandCompletionsC2s<'a> { + pub transaction_id: VarInt, + pub text: &'a str, +} + +#[derive(Clone, PartialEq, Debug, Packet)] +#[packet(id = packet_id::CHAT_MESSAGE_S2C)] +pub struct ChatMessageS2c<'a> { + pub sender: Uuid, + pub index: VarInt, + pub message_signature: Option<&'a [u8; 256]>, + pub message: &'a str, + pub time_stamp: u64, + pub salt: u64, + pub previous_messages: Vec>, + pub unsigned_content: Option>, + pub filter_type: MessageFilterType, + pub filter_type_bits: Option, + pub chat_type: VarInt, + pub network_name: Cow<'a, Text>, + pub network_target_name: Option>, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum MessageFilterType { + PassThrough, + FullyFiltered, + PartiallyFiltered, +} + +impl<'a> Encode for ChatMessageS2c<'a> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + self.sender.encode(&mut w)?; + self.index.encode(&mut w)?; + self.message_signature.encode(&mut w)?; + self.message.encode(&mut w)?; + self.time_stamp.encode(&mut w)?; + self.salt.encode(&mut w)?; + self.previous_messages.encode(&mut w)?; + self.unsigned_content.encode(&mut w)?; + self.filter_type.encode(&mut w)?; + + if self.filter_type == MessageFilterType::PartiallyFiltered { + match self.filter_type_bits { + // Filler data + None => 0u8.encode(&mut w)?, + Some(bits) => bits.encode(&mut w)?, + } + } + + self.chat_type.encode(&mut w)?; + self.network_name.encode(&mut w)?; + self.network_target_name.encode(&mut w)?; + + Ok(()) + } +} + +impl<'a> Decode<'a> for ChatMessageS2c<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let sender = Uuid::decode(r)?; + let index = VarInt::decode(r)?; + let message_signature = Option::<&'a [u8; 256]>::decode(r)?; + let message = <&str>::decode(r)?; + let time_stamp = u64::decode(r)?; + let salt = u64::decode(r)?; + let previous_messages = Vec::::decode(r)?; + let unsigned_content = Option::>::decode(r)?; + let filter_type = MessageFilterType::decode(r)?; + + let filter_type_bits = match filter_type { + MessageFilterType::PartiallyFiltered => Some(u8::decode(r)?), + _ => None, + }; + + let chat_type = VarInt::decode(r)?; + let network_name = >::decode(r)?; + let network_target_name = Option::>::decode(r)?; + + Ok(Self { + sender, + index, + message_signature, + message, + time_stamp, + salt, + previous_messages, + unsigned_content, + filter_type, + filter_type_bits, + chat_type, + network_name, + network_target_name, + }) + } +} + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CHAT_SUGGESTIONS_S2C)] +pub struct ChatSuggestionsS2c<'a> { + pub action: ChatSuggestionsAction, + pub entries: Cow<'a, [&'a str]>, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum ChatSuggestionsAction { + Add, + Remove, + Set, +} + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::REMOVE_MESSAGE_S2C)] +pub struct RemoveMessageS2c<'a> { + pub signature: MessageSignature<'a>, +} + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::COMMAND_SUGGESTIONS_S2C)] +pub struct CommandSuggestionsS2c<'a> { + pub id: VarInt, + pub start: VarInt, + pub length: VarInt, + pub matches: Vec>, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct CommandSuggestionsMatch<'a> { + pub suggested_match: &'a str, + pub tooltip: Option>, +} + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PROFILELESS_CHAT_MESSAGE_S2C)] +pub struct ProfilelessChatMessageS2c<'a> { + pub message: Cow<'a, Text>, + pub chat_type: VarInt, + pub chat_type_name: Cow<'a, Text>, + pub target_name: Option>, +} diff --git a/crates/valence_client/src/packet.rs b/crates/valence_packet/src/client.rs similarity index 94% rename from crates/valence_client/src/packet.rs rename to crates/valence_packet/src/client.rs index 989826f1a..7a96e69ab 100644 --- a/crates/valence_client/src/packet.rs +++ b/crates/valence_packet/src/client.rs @@ -1,23 +1,4 @@ -//! Common packets for this crate. - -use std::borrow::Cow; - -use bitfield_struct::bitfield; -use glam::DVec3; -use uuid::Uuid; -use valence_core::block_pos::BlockPos; -use valence_core::difficulty::Difficulty; -use valence_core::direction::Direction; -use valence_core::game_mode::GameMode; -use valence_core::hand::Hand; -use valence_core::ident::Ident; -use valence_core::protocol::byte_angle::ByteAngle; -use valence_core::protocol::global_pos::GlobalPos; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::var_long::VarLong; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; -use valence_core::text::Text; -use valence_nbt::Compound; +use super::*; #[derive(Copy, Clone, Debug, Encode, Decode, Packet)] #[packet(id = packet_id::BUNDLE_SPLITTER)] diff --git a/crates/valence_packet/src/command.rs b/crates/valence_packet/src/command.rs new file mode 100644 index 000000000..310637aad --- /dev/null +++ b/crates/valence_packet/src/command.rs @@ -0,0 +1,434 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::COMMAND_TREE_S2C)] +pub struct CommandTreeS2c<'a> { + pub commands: Vec>, + pub root_index: VarInt, +} + +#[derive(Clone, Debug)] +pub struct Node<'a> { + pub children: Vec, + pub data: NodeData<'a>, + pub executable: bool, + pub redirect_node: Option, +} + +#[derive(Clone, Debug)] +pub enum NodeData<'a> { + Root, + Literal { + name: &'a str, + }, + Argument { + name: &'a str, + parser: Parser<'a>, + suggestion: Option, + }, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum Suggestion { + AskServer, + AllRecipes, + AvailableSounds, + AvailableBiomes, + SummonableEntities, +} + +#[derive(Clone, Debug)] +pub enum Parser<'a> { + Bool, + Float { min: Option, max: Option }, + Double { min: Option, max: Option }, + Integer { min: Option, max: Option }, + Long { min: Option, max: Option }, + String(StringArg), + Entity { single: bool, only_players: bool }, + GameProfile, + BlockPos, + ColumnPos, + Vec3, + Vec2, + BlockState, + BlockPredicate, + ItemStack, + ItemPredicate, + Color, + Component, + Message, + NbtCompoundTag, + NbtTag, + NbtPath, + Objective, + ObjectiveCriteria, + Operation, + Particle, + Angle, + Rotation, + ScoreboardSlot, + ScoreHolder { allow_multiple: bool }, + Swizzle, + Team, + ItemSlot, + ResourceLocation, + Function, + EntityAnchor, + IntRange, + FloatRange, + Dimension, + GameMode, + Time, + ResourceOrTag { registry: Ident> }, + ResourceOrTagKey { registry: Ident> }, + Resource { registry: Ident> }, + ResourceKey { registry: Ident> }, + TemplateMirror, + TemplateRotation, + Uuid, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum StringArg { + SingleWord, + QuotablePhrase, + GreedyPhrase, +} + +impl Encode for Node<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + let node_type = match &self.data { + NodeData::Root => 0, + NodeData::Literal { .. } => 1, + NodeData::Argument { .. } => 2, + }; + + let has_suggestion = matches!( + &self.data, + NodeData::Argument { + suggestion: Some(_), + .. + } + ); + + let flags: u8 = node_type + | (self.executable as u8 * 0x04) + | (self.redirect_node.is_some() as u8 * 0x08) + | (has_suggestion as u8 * 0x10); + + w.write_u8(flags)?; + + self.children.encode(&mut w)?; + + if let Some(redirect_node) = self.redirect_node { + redirect_node.encode(&mut w)?; + } + + match &self.data { + NodeData::Root => {} + NodeData::Literal { name } => { + name.encode(&mut w)?; + } + NodeData::Argument { + name, + parser, + suggestion, + } => { + name.encode(&mut w)?; + parser.encode(&mut w)?; + + if let Some(suggestion) = suggestion { + match suggestion { + Suggestion::AskServer => "ask_server", + Suggestion::AllRecipes => "all_recipes", + Suggestion::AvailableSounds => "available_sounds", + Suggestion::AvailableBiomes => "available_biomes", + Suggestion::SummonableEntities => "summonable_entities", + } + .encode(&mut w)?; + } + } + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for Node<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let flags = u8::decode(r)?; + + let children = Vec::decode(r)?; + + let redirect_node = if flags & 0x08 != 0 { + Some(VarInt::decode(r)?) + } else { + None + }; + + let node_data = match flags & 0x3 { + 0 => NodeData::Root, + 1 => NodeData::Literal { + name: <&str>::decode(r)?, + }, + 2 => NodeData::Argument { + name: <&str>::decode(r)?, + parser: Parser::decode(r)?, + suggestion: if flags & 0x10 != 0 { + Some(match Ident::>::decode(r)?.as_str() { + "minecraft:ask_server" => Suggestion::AskServer, + "minecraft:all_recipes" => Suggestion::AllRecipes, + "minecraft:available_sounds" => Suggestion::AvailableSounds, + "minecraft:available_biomes" => Suggestion::AvailableBiomes, + "minecraft:summonable_entities" => Suggestion::SummonableEntities, + other => bail!("unknown command suggestion type of \"{other}\""), + }) + } else { + None + }, + }, + n => bail!("invalid node type of {n}"), + }; + + Ok(Self { + children, + data: node_data, + executable: flags & 0x04 != 0, + redirect_node, + }) + } +} + +impl Encode for Parser<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + match self { + Parser::Bool => 0u8.encode(&mut w)?, + Parser::Float { min, max } => { + 1u8.encode(&mut w)?; + + (min.is_some() as u8 | (max.is_some() as u8 * 0x2)).encode(&mut w)?; + + if let Some(min) = min { + min.encode(&mut w)?; + } + + if let Some(max) = max { + max.encode(&mut w)?; + } + } + Parser::Double { min, max } => { + 2u8.encode(&mut w)?; + + (min.is_some() as u8 | (max.is_some() as u8 * 0x2)).encode(&mut w)?; + + if let Some(min) = min { + min.encode(&mut w)?; + } + + if let Some(max) = max { + max.encode(&mut w)?; + } + } + Parser::Integer { min, max } => { + 3u8.encode(&mut w)?; + + (min.is_some() as u8 | (max.is_some() as u8 * 0x2)).encode(&mut w)?; + + if let Some(min) = min { + min.encode(&mut w)?; + } + + if let Some(max) = max { + max.encode(&mut w)?; + } + } + Parser::Long { min, max } => { + 4u8.encode(&mut w)?; + + (min.is_some() as u8 | (max.is_some() as u8 * 0x2)).encode(&mut w)?; + + if let Some(min) = min { + min.encode(&mut w)?; + } + + if let Some(max) = max { + max.encode(&mut w)?; + } + } + Parser::String(arg) => { + 5u8.encode(&mut w)?; + arg.encode(&mut w)?; + } + Parser::Entity { + single, + only_players, + } => { + 6u8.encode(&mut w)?; + (*single as u8 | (*only_players as u8 * 0x2)).encode(&mut w)?; + } + Parser::GameProfile => 7u8.encode(&mut w)?, + Parser::BlockPos => 8u8.encode(&mut w)?, + Parser::ColumnPos => 9u8.encode(&mut w)?, + Parser::Vec3 => 10u8.encode(&mut w)?, + Parser::Vec2 => 11u8.encode(&mut w)?, + Parser::BlockState => 12u8.encode(&mut w)?, + Parser::BlockPredicate => 13u8.encode(&mut w)?, + Parser::ItemStack => 14u8.encode(&mut w)?, + Parser::ItemPredicate => 15u8.encode(&mut w)?, + Parser::Color => 16u8.encode(&mut w)?, + Parser::Component => 17u8.encode(&mut w)?, + Parser::Message => 18u8.encode(&mut w)?, + Parser::NbtCompoundTag => 19u8.encode(&mut w)?, + Parser::NbtTag => 20u8.encode(&mut w)?, + Parser::NbtPath => 21u8.encode(&mut w)?, + Parser::Objective => 22u8.encode(&mut w)?, + Parser::ObjectiveCriteria => 23u8.encode(&mut w)?, + Parser::Operation => 24u8.encode(&mut w)?, + Parser::Particle => 25u8.encode(&mut w)?, + Parser::Angle => 26u8.encode(&mut w)?, + Parser::Rotation => 27u8.encode(&mut w)?, + Parser::ScoreboardSlot => 28u8.encode(&mut w)?, + Parser::ScoreHolder { allow_multiple } => { + 29u8.encode(&mut w)?; + allow_multiple.encode(&mut w)?; + } + Parser::Swizzle => 30u8.encode(&mut w)?, + Parser::Team => 31u8.encode(&mut w)?, + Parser::ItemSlot => 32u8.encode(&mut w)?, + Parser::ResourceLocation => 33u8.encode(&mut w)?, + Parser::Function => 34u8.encode(&mut w)?, + Parser::EntityAnchor => 35u8.encode(&mut w)?, + Parser::IntRange => 36u8.encode(&mut w)?, + Parser::FloatRange => 37u8.encode(&mut w)?, + Parser::Dimension => 38u8.encode(&mut w)?, + Parser::GameMode => 39u8.encode(&mut w)?, + Parser::Time => 40u8.encode(&mut w)?, + Parser::ResourceOrTag { registry } => { + 41u8.encode(&mut w)?; + registry.encode(&mut w)?; + } + Parser::ResourceOrTagKey { registry } => { + 42u8.encode(&mut w)?; + registry.encode(&mut w)?; + } + Parser::Resource { registry } => { + 43u8.encode(&mut w)?; + registry.encode(&mut w)?; + } + Parser::ResourceKey { registry } => { + 44u8.encode(&mut w)?; + registry.encode(&mut w)?; + } + Parser::TemplateMirror => 45u8.encode(&mut w)?, + Parser::TemplateRotation => 46u8.encode(&mut w)?, + Parser::Uuid => 47u8.encode(&mut w)?, + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for Parser<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + fn decode_min_max<'a, T: Decode<'a>>( + r: &mut &'a [u8], + ) -> anyhow::Result<(Option, Option)> { + let flags = u8::decode(r)?; + + let min = if flags & 0x1 != 0 { + Some(T::decode(r)?) + } else { + None + }; + + let max = if flags & 0x2 != 0 { + Some(T::decode(r)?) + } else { + None + }; + + Ok((min, max)) + } + + Ok(match u8::decode(r)? { + 0 => Self::Bool, + 1 => { + let (min, max) = decode_min_max(r)?; + Self::Float { min, max } + } + 2 => { + let (min, max) = decode_min_max(r)?; + Self::Double { min, max } + } + 3 => { + let (min, max) = decode_min_max(r)?; + Self::Integer { min, max } + } + 4 => { + let (min, max) = decode_min_max(r)?; + Self::Long { min, max } + } + 5 => Self::String(StringArg::decode(r)?), + 6 => { + let flags = u8::decode(r)?; + Self::Entity { + single: flags & 0x1 != 0, + only_players: flags & 0x2 != 0, + } + } + 7 => Self::GameProfile, + 8 => Self::BlockPos, + 9 => Self::ColumnPos, + 10 => Self::Vec3, + 11 => Self::Vec2, + 12 => Self::BlockState, + 13 => Self::BlockPredicate, + 14 => Self::ItemStack, + 15 => Self::ItemPredicate, + 16 => Self::Color, + 17 => Self::Component, + 18 => Self::Message, + 19 => Self::NbtCompoundTag, + 20 => Self::NbtTag, + 21 => Self::NbtPath, + 22 => Self::Objective, + 23 => Self::ObjectiveCriteria, + 24 => Self::Operation, + 25 => Self::Particle, + 26 => Self::Angle, + 27 => Self::Rotation, + 28 => Self::ScoreboardSlot, + 29 => Self::ScoreHolder { + allow_multiple: bool::decode(r)?, + }, + 30 => Self::Swizzle, + 31 => Self::Team, + 32 => Self::ItemSlot, + 33 => Self::ResourceLocation, + 34 => Self::Function, + 35 => Self::EntityAnchor, + 36 => Self::IntRange, + 37 => Self::FloatRange, + 38 => Self::Dimension, + 39 => Self::GameMode, + 40 => Self::Time, + 41 => Self::ResourceOrTag { + registry: Ident::decode(r)?, + }, + 42 => Self::ResourceOrTagKey { + registry: Ident::decode(r)?, + }, + 43 => Self::Resource { + registry: Ident::decode(r)?, + }, + 44 => Self::ResourceKey { + registry: Ident::decode(r)?, + }, + 45 => Self::TemplateMirror, + 46 => Self::TemplateRotation, + 47 => Self::Uuid, + n => bail!("unknown command parser ID of {n}"), + }) + } +} diff --git a/crates/valence_entity/src/packet.rs b/crates/valence_packet/src/entity.rs similarity index 95% rename from crates/valence_entity/src/packet.rs rename to crates/valence_packet/src/entity.rs index ab6a3d4be..cf3d48163 100644 --- a/crates/valence_entity/src/packet.rs +++ b/crates/valence_packet/src/entity.rs @@ -1,16 +1,4 @@ -use std::borrow::Cow; -use std::io::Write; - -use bitfield_struct::bitfield; -use glam::DVec3; -use uuid::Uuid; -use valence_core::ident::Ident; -use valence_core::item::ItemStack; -use valence_core::protocol::byte_angle::ByteAngle; -use valence_core::protocol::raw::RawBytes; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; -use valence_nbt::Compound; +use super::*; #[derive(Clone, PartialEq, Debug, Encode, Decode, Packet)] #[packet(id = packet_id::ENTITIES_DESTROY_S2C)] diff --git a/crates/valence_instance/src/packet.rs b/crates/valence_packet/src/instance.rs similarity index 91% rename from crates/valence_instance/src/packet.rs rename to crates/valence_packet/src/instance.rs index 650b2e891..5a8c4b149 100644 --- a/crates/valence_instance/src/packet.rs +++ b/crates/valence_packet/src/instance.rs @@ -1,13 +1,6 @@ -use std::borrow::Cow; - -use valence_core::block_pos::BlockPos; -use valence_core::chunk_pos::ChunkPos; -use valence_core::ident::Ident; -use valence_core::protocol::array::LengthPrefixedArray; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::var_long::VarLong; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; -use valence_nbt::Compound; +use valence_core::{chunk_pos::ChunkPos, protocol::array::LengthPrefixedArray}; + +use super::*; #[derive(Clone, Debug, Encode, Decode, Packet)] #[packet(id = packet_id::WORLD_EVENT_S2C)] diff --git a/crates/valence_inventory/src/packet.rs b/crates/valence_packet/src/inventory.rs similarity index 99% rename from crates/valence_inventory/src/packet.rs rename to crates/valence_packet/src/inventory.rs index 56f80b4b3..ee3ed2cb0 100644 --- a/crates/valence_inventory/src/packet.rs +++ b/crates/valence_packet/src/inventory.rs @@ -1,14 +1,6 @@ -//! Inventory packets - -use std::borrow::Cow; -use std::io::Write; - -use anyhow::bail; -use valence_core::ident::Ident; use valence_core::item::ItemStack; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; -use valence_core::text::Text; + +use super::*; #[derive(Clone, Debug, Encode, Decode, Packet)] #[packet(id = packet_id::CLICK_SLOT_C2S)] diff --git a/crates/valence_packet/src/lib.rs b/crates/valence_packet/src/lib.rs new file mode 100644 index 000000000..2e2e1d554 --- /dev/null +++ b/crates/valence_packet/src/lib.rs @@ -0,0 +1,39 @@ +use std::borrow::Cow; +use std::io::Write; + +use anyhow::bail; +use bitfield_struct::bitfield; +use byteorder::WriteBytesExt; +use glam::{DVec3, IVec3}; +use uuid::Uuid; +use valence_core::block_pos::BlockPos; +use valence_core::difficulty::Difficulty; +use valence_core::direction::Direction; +use valence_core::game_mode::GameMode; +use valence_core::hand::Hand; +use valence_core::ident::Ident; +use valence_core::item::ItemStack; +use valence_core::property::Property; +use valence_core::protocol::byte_angle::ByteAngle; +use valence_core::protocol::global_pos::GlobalPos; +use valence_core::protocol::raw::RawBytes; +use valence_core::protocol::var_int::VarInt; +use valence_core::protocol::var_long::VarLong; +use valence_core::protocol::{packet_id, Decode, Encode, Packet}; +use valence_core::text::Text; +use valence_nbt::Compound; + +pub mod advancement; +pub mod boss_bar; +pub mod chat; +pub mod client; +pub mod command; +pub mod entity; +pub mod instance; +pub mod inventory; +pub mod map; +pub mod network; +pub mod player_list; +pub mod scoreboard; +pub mod sound; +pub mod world_border; diff --git a/crates/valence_packet/src/map.rs b/crates/valence_packet/src/map.rs new file mode 100644 index 000000000..1e809d864 --- /dev/null +++ b/crates/valence_packet/src/map.rs @@ -0,0 +1,109 @@ +use super::*; + +#[derive(Clone, PartialEq, Debug, Packet)] +#[packet(id = packet_id::MAP_UPDATE_S2C)] +pub struct MapUpdateS2c<'a> { + pub map_id: VarInt, + pub scale: i8, + pub locked: bool, + pub icons: Option>>, + pub data: Option>, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct Icon<'a> { + pub icon_type: IconType, + /// In map coordinates; -128 for furthest left, +127 for furthest right + pub position: [i8; 2], + /// 0 is a vertical icon and increments by 22.5° + pub direction: i8, + pub display_name: Option>, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum IconType { + WhiteArrow, + GreenArrow, + RedArrow, + BlueArrow, + WhiteCross, + RedPointer, + WhiteCircle, + SmallWhiteCircle, + Mansion, + Temple, + WhiteBanner, + OrangeBanner, + MagentaBanner, + LightBlueBanner, + YellowBanner, + LimeBanner, + PinkBanner, + GrayBanner, + LightGrayBanner, + CyanBanner, + PurpleBanner, + BlueBanner, + BrownBanner, + GreenBanner, + RedBanner, + BlackBanner, + TreasureMarker, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode)] +pub struct Data<'a> { + pub columns: u8, + pub rows: u8, + pub position: [i8; 2], + pub data: &'a [u8], +} + +impl Encode for MapUpdateS2c<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + self.map_id.encode(&mut w)?; + self.scale.encode(&mut w)?; + self.locked.encode(&mut w)?; + self.icons.encode(&mut w)?; + + match self.data { + None => 0u8.encode(&mut w)?, + Some(data) => data.encode(&mut w)?, + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for MapUpdateS2c<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let map_id = VarInt::decode(r)?; + let scale = i8::decode(r)?; + let locked = bool::decode(r)?; + let icons = >>>::decode(r)?; + let columns = u8::decode(r)?; + + let data = if columns > 0 { + let rows = u8::decode(r)?; + let position = <[i8; 2]>::decode(r)?; + let data = <&'a [u8]>::decode(r)?; + + Some(Data { + columns, + rows, + position, + data, + }) + } else { + None + }; + + Ok(Self { + map_id, + scale, + locked, + icons, + data, + }) + } +} diff --git a/crates/valence_network/src/packet.rs b/crates/valence_packet/src/network.rs similarity index 90% rename from crates/valence_network/src/packet.rs rename to crates/valence_packet/src/network.rs index bc43a2067..ed6dc402b 100644 --- a/crates/valence_network/src/packet.rs +++ b/crates/valence_packet/src/network.rs @@ -1,12 +1,6 @@ -use std::borrow::Cow; +use valence_core::protocol::PacketState; -use uuid::Uuid; -use valence_core::ident::Ident; -use valence_core::property::Property; -use valence_core::protocol::raw::RawBytes; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{packet_id, Decode, Encode, Packet, PacketState}; -use valence_core::text::Text; +use super::*; #[derive(Clone, Debug, Encode, Decode, Packet)] #[packet(id = packet_id::HANDSHAKE_C2S, state = PacketState::Handshaking)] diff --git a/crates/valence_player_list/src/packet.rs b/crates/valence_packet/src/player_list.rs similarity index 89% rename from crates/valence_player_list/src/packet.rs rename to crates/valence_packet/src/player_list.rs index b842b5cbe..29a8833cb 100644 --- a/crates/valence_player_list/src/packet.rs +++ b/crates/valence_packet/src/player_list.rs @@ -1,13 +1,4 @@ -use std::borrow::Cow; -use std::io::Write; - -use bitfield_struct::bitfield; -use uuid::Uuid; -use valence_core::game_mode::GameMode; -use valence_core::property::Property; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; -use valence_core::text::Text; +use super::*; #[derive(Clone, Debug, Encode, Decode, Packet)] #[packet(id = packet_id::PLAYER_LIST_HEADER_S2C)] @@ -20,7 +11,7 @@ pub struct PlayerListHeaderS2c<'a> { #[packet(id = packet_id::PLAYER_LIST_S2C)] pub struct PlayerListS2c<'a> { pub actions: PlayerListActions, - pub entries: Cow<'a, [PlayerListEntry<'a>]>, + pub entries: Cow<'a, [PlayerListEntryPkt<'a>]>, } #[bitfield(u8)] @@ -36,7 +27,7 @@ pub struct PlayerListActions { } #[derive(Clone, Default, Debug)] -pub struct PlayerListEntry<'a> { +pub struct PlayerListEntryPkt<'a> { pub player_uuid: Uuid, pub username: &'a str, pub properties: Cow<'a, [Property]>, @@ -103,7 +94,7 @@ impl<'a> Decode<'a> for PlayerListS2c<'a> { let mut entries = vec![]; for _ in 0..VarInt::decode(r)?.0 { - let mut entry = PlayerListEntry { + let mut entry = PlayerListEntryPkt { player_uuid: Uuid::decode(r)?, ..Default::default() }; diff --git a/crates/valence_packet/src/scoreboard.rs b/crates/valence_packet/src/scoreboard.rs new file mode 100644 index 000000000..94d69d0f6 --- /dev/null +++ b/crates/valence_packet/src/scoreboard.rs @@ -0,0 +1,342 @@ +use super::*; + + #[derive(Clone, Debug, Encode, Decode, Packet)] + #[packet(id = packet_id::TEAM_S2C)] + pub struct TeamS2c<'a> { + pub team_name: &'a str, + pub mode: Mode<'a>, + } + + #[derive(Clone, PartialEq, Debug)] + pub enum Mode<'a> { + CreateTeam { + team_display_name: Cow<'a, Text>, + friendly_flags: TeamFlags, + name_tag_visibility: NameTagVisibility, + collision_rule: CollisionRule, + team_color: TeamColor, + team_prefix: Cow<'a, Text>, + team_suffix: Cow<'a, Text>, + entities: Vec<&'a str>, + }, + RemoveTeam, + UpdateTeamInfo { + team_display_name: Cow<'a, Text>, + friendly_flags: TeamFlags, + name_tag_visibility: NameTagVisibility, + collision_rule: CollisionRule, + team_color: TeamColor, + team_prefix: Cow<'a, Text>, + team_suffix: Cow<'a, Text>, + }, + AddEntities { + entities: Vec<&'a str>, + }, + RemoveEntities { + entities: Vec<&'a str>, + }, + } + + #[bitfield(u8)] + #[derive(PartialEq, Eq, Encode, Decode)] + pub struct TeamFlags { + pub friendly_fire: bool, + pub see_invisible_teammates: bool, + #[bits(6)] + _pad: u8, + } + + #[derive(Copy, Clone, PartialEq, Eq, Debug)] + pub enum NameTagVisibility { + Always, + Never, + HideForOtherTeams, + HideForOwnTeam, + } + + #[derive(Copy, Clone, PartialEq, Eq, Debug)] + pub enum CollisionRule { + Always, + Never, + PushOtherTeams, + PushOwnTeam, + } + + #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] + pub enum TeamColor { + Black, + DarkBlue, + DarkGreen, + DarkCyan, + DarkRed, + Purple, + Gold, + Gray, + DarkGray, + Blue, + BrightGreen, + Cyan, + Red, + Pink, + Yellow, + White, + Obfuscated, + Bold, + Strikethrough, + Underlined, + Italic, + Reset, + } + + impl Encode for Mode<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + match self { + Mode::CreateTeam { + team_display_name, + friendly_flags, + name_tag_visibility, + collision_rule, + team_color, + team_prefix, + team_suffix, + entities, + } => { + 0i8.encode(&mut w)?; + team_display_name.encode(&mut w)?; + friendly_flags.encode(&mut w)?; + match name_tag_visibility { + NameTagVisibility::Always => "always", + NameTagVisibility::Never => "never", + NameTagVisibility::HideForOtherTeams => "hideForOtherTeams", + NameTagVisibility::HideForOwnTeam => "hideForOwnTeam", + } + .encode(&mut w)?; + match collision_rule { + CollisionRule::Always => "always", + CollisionRule::Never => "never", + CollisionRule::PushOtherTeams => "pushOtherTeams", + CollisionRule::PushOwnTeam => "pushOwnTeam", + } + .encode(&mut w)?; + team_color.encode(&mut w)?; + team_prefix.encode(&mut w)?; + team_suffix.encode(&mut w)?; + entities.encode(&mut w)?; + } + Mode::RemoveTeam => 1i8.encode(&mut w)?, + Mode::UpdateTeamInfo { + team_display_name, + friendly_flags, + name_tag_visibility, + collision_rule, + team_color, + team_prefix, + team_suffix, + } => { + 2i8.encode(&mut w)?; + team_display_name.encode(&mut w)?; + friendly_flags.encode(&mut w)?; + match name_tag_visibility { + NameTagVisibility::Always => "always", + NameTagVisibility::Never => "never", + NameTagVisibility::HideForOtherTeams => "hideForOtherTeams", + NameTagVisibility::HideForOwnTeam => "hideForOwnTeam", + } + .encode(&mut w)?; + match collision_rule { + CollisionRule::Always => "always", + CollisionRule::Never => "never", + CollisionRule::PushOtherTeams => "pushOtherTeams", + CollisionRule::PushOwnTeam => "pushOwnTeam", + } + .encode(&mut w)?; + team_color.encode(&mut w)?; + team_prefix.encode(&mut w)?; + team_suffix.encode(&mut w)?; + } + Mode::AddEntities { entities } => { + 3i8.encode(&mut w)?; + entities.encode(&mut w)?; + } + Mode::RemoveEntities { entities } => { + 4i8.encode(&mut w)?; + entities.encode(&mut w)?; + } + } + Ok(()) + } + } + + impl<'a> Decode<'a> for Mode<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + Ok(match i8::decode(r)? { + 0 => Self::CreateTeam { + team_display_name: Decode::decode(r)?, + friendly_flags: Decode::decode(r)?, + name_tag_visibility: match <&str>::decode(r)? { + "always" => NameTagVisibility::Always, + "never" => NameTagVisibility::Never, + "hideForOtherTeams" => NameTagVisibility::HideForOtherTeams, + "hideForOwnTeam" => NameTagVisibility::HideForOwnTeam, + other => bail!("unknown name tag visibility type \"{other}\""), + }, + collision_rule: match <&str>::decode(r)? { + "always" => CollisionRule::Always, + "never" => CollisionRule::Never, + "pushOtherTeams" => CollisionRule::PushOtherTeams, + "pushOwnTeam" => CollisionRule::PushOwnTeam, + other => bail!("unknown collision rule type \"{other}\""), + }, + team_color: Decode::decode(r)?, + team_prefix: Decode::decode(r)?, + team_suffix: Decode::decode(r)?, + entities: Decode::decode(r)?, + }, + 1 => Self::RemoveTeam, + 2 => Self::UpdateTeamInfo { + team_display_name: Decode::decode(r)?, + friendly_flags: Decode::decode(r)?, + name_tag_visibility: match <&str>::decode(r)? { + "always" => NameTagVisibility::Always, + "never" => NameTagVisibility::Never, + "hideForOtherTeams" => NameTagVisibility::HideForOtherTeams, + "hideForOwnTeam" => NameTagVisibility::HideForOwnTeam, + other => bail!("unknown name tag visibility type \"{other}\""), + }, + collision_rule: match <&str>::decode(r)? { + "always" => CollisionRule::Always, + "never" => CollisionRule::Never, + "pushOtherTeams" => CollisionRule::PushOtherTeams, + "pushOwnTeam" => CollisionRule::PushOwnTeam, + other => bail!("unknown collision rule type \"{other}\""), + }, + team_color: Decode::decode(r)?, + team_prefix: Decode::decode(r)?, + team_suffix: Decode::decode(r)?, + }, + 3 => Self::AddEntities { + entities: Decode::decode(r)?, + }, + 4 => Self::RemoveEntities { + entities: Decode::decode(r)?, + }, + n => bail!("unknown update teams action of {n}"), + }) + } + } + + #[derive(Copy, Clone, Debug, Encode, Decode, Packet)] + #[packet(id = packet_id::SCOREBOARD_DISPLAY_S2C)] + pub struct ScoreboardDisplayS2c<'a> { + pub position: ScoreboardPosition, + pub score_name: &'a str, + } + + #[derive(Copy, Clone, PartialEq, Debug)] + pub enum ScoreboardPosition { + List, + Sidebar, + BelowName, + SidebarTeam(TeamColor), + } + + impl Encode for ScoreboardPosition { + fn encode(&self, w: impl std::io::Write) -> anyhow::Result<()> { + match self { + ScoreboardPosition::List => 0u8.encode(w), + ScoreboardPosition::Sidebar => 1u8.encode(w), + ScoreboardPosition::BelowName => 2u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Black) => 3u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::DarkBlue) => 4u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::DarkGreen) => 5u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::DarkCyan) => 6u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::DarkRed) => 7u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Purple) => 8u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Gold) => 9u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Gray) => 10u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::DarkGray) => 11u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Blue) => 12u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::BrightGreen) => 13u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Cyan) => 14u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Red) => 15u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Pink) => 16u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Yellow) => 17u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::White) => 18u8.encode(w), + ScoreboardPosition::SidebarTeam(_) => { + Err(anyhow::anyhow!("Invalid scoreboard display position")) + } + } + } + } + + impl<'a> Decode<'a> for ScoreboardPosition { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let value = u8::decode(r)?; + match value { + 0 => Ok(ScoreboardPosition::List), + 1 => Ok(ScoreboardPosition::Sidebar), + 2 => Ok(ScoreboardPosition::BelowName), + 3 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Black)), + 4 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkBlue)), + 5 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkGreen)), + 6 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkCyan)), + 7 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkRed)), + 8 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Purple)), + 9 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Gold)), + 10 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Gray)), + 11 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkGray)), + 12 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Blue)), + 13 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::BrightGreen)), + 14 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Cyan)), + 15 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Red)), + 16 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Pink)), + 17 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Yellow)), + 18 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::White)), + _ => Err(anyhow::anyhow!("Invalid scoreboard display position")), + } + } + } + + #[derive(Clone, Debug, Encode, Decode, Packet)] + #[packet(id = packet_id::SCOREBOARD_OBJECTIVE_UPDATE_S2C)] + pub struct ScoreboardObjectiveUpdateS2c<'a> { + pub objective_name: &'a str, + pub mode: ObjectiveMode, + } + + #[derive(Clone, PartialEq, Debug, Encode, Decode)] + pub enum ObjectiveMode { + Create { + objective_display_name: Text, + render_type: ObjectiveRenderType, + }, + Remove, + Update { + objective_display_name: Text, + render_type: ObjectiveRenderType, + }, + } + + #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] + pub enum ObjectiveRenderType { + Integer, + Hearts, + } + + #[derive(Clone, Debug, Encode, Decode, Packet)] + #[packet(id = packet_id::SCOREBOARD_PLAYER_UPDATE_S2C)] + pub struct ScoreboardPlayerUpdateS2c<'a> { + pub entity_name: &'a str, + pub action: ScoreboardPlayerUpdateAction<'a>, + } + + #[derive(Clone, PartialEq, Debug, Encode, Decode)] + pub enum ScoreboardPlayerUpdateAction<'a> { + Update { + objective_name: &'a str, + objective_score: VarInt, + }, + Remove { + objective_name: &'a str, + }, + } \ No newline at end of file diff --git a/crates/valence_packet/src/sound.rs b/crates/valence_packet/src/sound.rs new file mode 100644 index 000000000..c5ea76147 --- /dev/null +++ b/crates/valence_packet/src/sound.rs @@ -0,0 +1,90 @@ +use valence_core::sound::{SoundCategory, SoundId}; + +use super::*; + +#[cfg(test)] +mod tests { + use valence_core::ident; + use valence_core::sound::Sound; + + use super::*; + + #[test] + fn sound_to_soundid() { + assert_eq!( + Sound::BlockBellUse.to_id(), + SoundId::Direct { + id: ident!("block.bell.use").into(), + range: None + }, + ); + } +} + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAY_SOUND_FROM_ENTITY_S2C)] +pub struct PlaySoundFromEntityS2c { + pub id: VarInt, + pub category: SoundCategory, + pub entity_id: VarInt, + pub volume: f32, + pub pitch: f32, + pub seed: i64, +} + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAY_SOUND_S2C)] +pub struct PlaySoundS2c<'a> { + pub id: SoundId<'a>, + pub category: SoundCategory, + pub position: IVec3, + pub volume: f32, + pub pitch: f32, + pub seed: i64, +} + +#[derive(Clone, PartialEq, Debug, Packet)] +#[packet(id = packet_id::STOP_SOUND_S2C)] +pub struct StopSoundS2c<'a> { + pub source: Option, + pub sound: Option>>, +} + +impl Encode for StopSoundS2c<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + match (self.source, self.sound.as_ref()) { + (Some(source), Some(sound)) => { + 3i8.encode(&mut w)?; + source.encode(&mut w)?; + sound.encode(&mut w)?; + } + (None, Some(sound)) => { + 2i8.encode(&mut w)?; + sound.encode(&mut w)?; + } + (Some(source), None) => { + 1i8.encode(&mut w)?; + source.encode(&mut w)?; + } + _ => 0i8.encode(&mut w)?, + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for StopSoundS2c<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let (source, sound) = match i8::decode(r)? { + 3 => ( + Some(SoundCategory::decode(r)?), + Some(>>::decode(r)?), + ), + 2 => (None, Some(>>::decode(r)?)), + 1 => (Some(SoundCategory::decode(r)?), None), + _ => (None, None), + }; + + Ok(Self { source, sound }) + } +} diff --git a/crates/valence_world_border/src/packet.rs b/crates/valence_packet/src/world_border.rs similarity index 89% rename from crates/valence_world_border/src/packet.rs rename to crates/valence_packet/src/world_border.rs index 30465ab54..e3974682d 100644 --- a/crates/valence_world_border/src/packet.rs +++ b/crates/valence_packet/src/world_border.rs @@ -1,6 +1,4 @@ -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::var_long::VarLong; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; +use super::*; #[derive(Clone, Debug, Encode, Decode, Packet)] #[packet(id = packet_id::WORLD_BORDER_CENTER_CHANGED_S2C)] diff --git a/crates/valence_player_list/Cargo.toml b/crates/valence_player_list/Cargo.toml index 21aef41c6..a87ba8324 100644 --- a/crates/valence_player_list/Cargo.toml +++ b/crates/valence_player_list/Cargo.toml @@ -12,3 +12,4 @@ valence_core.workspace = true valence_client.workspace = true valence_instance.workspace = true uuid.workspace = true +valence_packet.workspace = true diff --git a/crates/valence_player_list/src/lib.rs b/crates/valence_player_list/src/lib.rs index 0d4f1aa73..cef147b65 100644 --- a/crates/valence_player_list/src/lib.rs +++ b/crates/valence_player_list/src/lib.rs @@ -18,13 +18,10 @@ )] #![allow(clippy::type_complexity)] -pub mod packet; - use std::borrow::Cow; use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use packet::{PlayerListActions, PlayerListHeaderS2c, PlayerListS2c}; use uuid::Uuid; use valence_client::{Client, Ping, Properties, Username}; use valence_core::despawn::Despawned; @@ -34,13 +31,13 @@ use valence_core::text::{IntoText, Text}; use valence_core::uuid::UniqueId; use valence_core::Server; use valence_instance::WriteUpdatePacketsToInstancesSet; - -use crate::packet::PlayerRemoveS2c; +use valence_packet::player_list::{ + PlayerListActions, PlayerListHeaderS2c, PlayerListS2c, PlayerRemoveS2c, PlayerListEntryPkt, +}; pub struct PlayerListPlugin; #[derive(SystemSet, Copy, Clone, PartialEq, Eq, Hash, Debug)] - struct PlayerListSet; impl Plugin for PlayerListPlugin { @@ -220,7 +217,7 @@ fn init_player_list_for_clients( .iter() .map( |(uuid, username, props, game_mode, ping, display_name, listed)| { - packet::PlayerListEntry { + PlayerListEntryPkt { player_uuid: uuid.0, username: &username.0, properties: Cow::Borrowed(&props.0), @@ -356,7 +353,7 @@ fn update_entries( debug_assert_ne!(u8::from(actions), 0); } - let entry = packet::PlayerListEntry { + let entry = PlayerListEntryPkt { player_uuid: uuid.0, username: &username.0, properties: (&props.0).into(), diff --git a/crates/valence_world_border/Cargo.toml b/crates/valence_world_border/Cargo.toml index c2e5e2736..95f55f47d 100644 --- a/crates/valence_world_border/Cargo.toml +++ b/crates/valence_world_border/Cargo.toml @@ -12,3 +12,4 @@ valence_core.workspace = true valence_entity.workspace = true valence_instance.workspace = true valence_registry.workspace = true +valence_packet.workspace = true diff --git a/crates/valence_world_border/src/lib.rs b/crates/valence_world_border/src/lib.rs index 059c1f82b..66afdb057 100644 --- a/crates/valence_world_border/src/lib.rs +++ b/crates/valence_world_border/src/lib.rs @@ -73,13 +73,11 @@ clippy::dbg_macro )] -pub mod packet; - use std::time::{Duration, Instant}; use bevy_app::prelude::*; use glam::DVec2; -use packet::*; +use valence_packet::world_border::*; use valence_client::{Client, FlushPacketsSet}; use valence_core::protocol::encode::WritePacket; use valence_core::protocol::var_int::VarInt; diff --git a/examples/parkour.rs b/examples/parkour.rs index aa079f798..de30e7118 100644 --- a/examples/parkour.rs +++ b/examples/parkour.rs @@ -6,7 +6,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; use rand::seq::SliceRandom; use rand::Rng; use valence::prelude::*; -use valence::protocol::packet::sound::{Sound, SoundCategory}; +use valence::sound::{Sound, SoundCategory}; use valence_client::message::SendMessage; const START_POS: BlockPos = BlockPos::new(0, 100, 0); diff --git a/src/lib.rs b/src/lib.rs index 87f810878..a69861c8b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,6 +36,7 @@ pub use valence_anvil as anvil; #[cfg(feature = "boss_bar")] pub use valence_boss_bar as boss_bar; pub use valence_core::*; +pub use valence_packet as packet; #[cfg(feature = "inventory")] pub use valence_inventory as inventory; #[cfg(feature = "network")] diff --git a/src/tests/client.rs b/src/tests/client.rs index df14b65c9..0a7d5bd71 100644 --- a/src/tests/client.rs +++ b/src/tests/client.rs @@ -10,10 +10,10 @@ use valence_client::ViewDistance; use valence_core::chunk_pos::{ChunkPos, ChunkView}; use valence_core::protocol::Packet; use valence_entity::cow::CowEntityBundle; -use valence_entity::packet::{EntitiesDestroyS2c, EntitySpawnS2c, MoveRelativeS2c}; +use valence_packet::entity::{EntitiesDestroyS2c, EntitySpawnS2c, MoveRelativeS2c}; use valence_entity::{Location, Position}; use valence_instance::chunk::UnloadedChunk; -use valence_instance::packet::{ChunkDataS2c, UnloadChunkS2c}; +use valence_packet::instance::{ChunkDataS2c, UnloadChunkS2c}; use valence_instance::Instance; use crate::testing::{create_mock_client, scenario_single_client}; diff --git a/src/tests/example.rs b/src/tests/example.rs index 413d8a087..7bca4085c 100644 --- a/src/tests/example.rs +++ b/src/tests/example.rs @@ -11,7 +11,7 @@ use valence_client::movement::PositionAndOnGroundC2s; use valence_client::Client; use valence_core::Server; use valence_entity::Position; -use valence_inventory::packet::{InventoryS2c, OpenScreenS2c}; +use valence_packet::inventory::{InventoryS2c, OpenScreenS2c}; use valence_inventory::{Inventory, InventoryKind, OpenInventory}; use crate::testing::scenario_single_client; diff --git a/src/tests/instance.rs b/src/tests/instance.rs index e13d7abdb..a2a86e23f 100644 --- a/src/tests/instance.rs +++ b/src/tests/instance.rs @@ -2,7 +2,7 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use valence_block::BlockState; use valence_instance::chunk::UnloadedChunk; -use valence_instance::packet::{BlockEntityUpdateS2c, ChunkDeltaUpdateS2c}; +use valence_packet::instance::{BlockEntityUpdateS2c, ChunkDeltaUpdateS2c}; use valence_instance::Instance; use crate::testing::scenario_single_client; diff --git a/src/tests/inventory.rs b/src/tests/inventory.rs index ab6fd042e..43c754ceb 100644 --- a/src/tests/inventory.rs +++ b/src/tests/inventory.rs @@ -3,7 +3,7 @@ use bevy_ecs::prelude::*; use valence_core::game_mode::GameMode; use valence_core::item::{ItemKind, ItemStack}; use valence_core::protocol::var_int::VarInt; -use valence_inventory::packet::{ +use valence_packet::inventory::{ ClickMode, ClickSlotC2s, CloseScreenS2c, CreativeInventoryActionC2s, InventoryS2c, OpenScreenS2c, ScreenHandlerSlotUpdateS2c, SlotChange, UpdateSelectedSlotC2s, }; @@ -517,7 +517,7 @@ fn should_not_increment_state_id_on_cursor_item_change() { } mod dropping_items { - use valence_client::packet::{PlayerAction, PlayerActionC2s}; + use valence_packet::client::{PlayerAction, PlayerActionC2s}; use valence_core::block_pos::BlockPos; use valence_core::direction::Direction; use valence_inventory::convert_to_player_slot_id; diff --git a/src/tests/player_list.rs b/src/tests/player_list.rs index d5b1936f3..67ae34e9e 100644 --- a/src/tests/player_list.rs +++ b/src/tests/player_list.rs @@ -1,9 +1,9 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use valence_client::packet::PlayerSpawnS2c; +use valence_packet::client::PlayerSpawnS2c; use valence_instance::chunk::UnloadedChunk; use valence_instance::Instance; -use valence_player_list::packet::PlayerListS2c; +use valence_packet::player_list::PlayerListS2c; use crate::testing::{create_mock_client, scenario_single_client}; diff --git a/src/tests/weather.rs b/src/tests/weather.rs index ada7fdce6..1f4fb712a 100644 --- a/src/tests/weather.rs +++ b/src/tests/weather.rs @@ -1,5 +1,5 @@ use bevy_app::App; -use valence_client::packet::GameStateChangeS2c; +use valence_packet::client::GameStateChangeS2c; use valence_client::weather::{Rain, Thunder}; use valence_client::Client; use valence_instance::Instance; diff --git a/src/tests/world_border.rs b/src/tests/world_border.rs index cedf9fc28..a2840faec 100644 --- a/src/tests/world_border.rs +++ b/src/tests/world_border.rs @@ -4,7 +4,7 @@ use bevy_app::App; use valence_entity::Location; use valence_instance::Instance; use valence_registry::{Entity, Mut}; -use valence_world_border::packet::*; +use valence_packet::world_border::*; use valence_world_border::*; use crate::testing::{create_mock_client, scenario_single_client, MockClientHelper}; diff --git a/tools/packet_inspector/src/lib.rs b/tools/packet_inspector/src/lib.rs index 7aa931cff..d1b74fb92 100644 --- a/tools/packet_inspector/src/lib.rs +++ b/tools/packet_inspector/src/lib.rs @@ -7,7 +7,7 @@ use std::sync::{Arc, OnceLock}; pub use packet_registry::Packet; use tokio::net::TcpStream; use tokio::sync::RwLock; -use valence::network::packet::{ +use valence::packet::network::{ HandshakeC2s, HandshakeNextState, LoginCompressionS2c, LoginSuccessS2c, }; use valence::protocol::decode::PacketFrame; diff --git a/tools/stresser/Cargo.toml b/tools/stresser/Cargo.toml index df951e0fb..c403774e3 100644 --- a/tools/stresser/Cargo.toml +++ b/tools/stresser/Cargo.toml @@ -13,3 +13,4 @@ uuid = { workspace = true, features = ["v4"] } valence_network = { workspace = true, features = ["compression"] } valence_core = { workspace = true } valence_client = { workspace = true } +valence_packet.workspace = true diff --git a/tools/stresser/src/stresser.rs b/tools/stresser/src/stresser.rs index c9512d41a..f414f347c 100644 --- a/tools/stresser/src/stresser.rs +++ b/tools/stresser/src/stresser.rs @@ -13,7 +13,7 @@ use valence_core::protocol::encode::PacketEncoder; use valence_core::protocol::var_int::VarInt; use valence_core::protocol::Packet; use valence_core::PROTOCOL_VERSION; -use valence_network::packet::{ +use valence_packet::network::{ HandshakeC2s, HandshakeNextState, LoginCompressionS2c, LoginHelloC2s, LoginHelloS2c, LoginSuccessS2c, }; From cf58e3a42003385079ba0b7c0fe52fe31ef112f9 Mon Sep 17 00:00:00 2001 From: Bafbi Date: Sun, 30 Jul 2023 21:37:43 +0200 Subject: [PATCH 2/9] rework valence_boss_bar + moved his packets --- crates/valence_boss_bar/Cargo.toml | 1 + crates/valence_boss_bar/src/lib.rs | 251 +++++++++++++++++--------- crates/valence_core/src/boss_bar.rs | 35 ++++ crates/valence_core/src/lib.rs | 3 +- crates/valence_packet/src/boss_bar.rs | 44 ++--- examples/boss_bar.rs | 92 +++++++--- src/tests/boss_bar.rs | 51 +++--- 7 files changed, 314 insertions(+), 163 deletions(-) create mode 100644 crates/valence_core/src/boss_bar.rs diff --git a/crates/valence_boss_bar/Cargo.toml b/crates/valence_boss_bar/Cargo.toml index efe5fdfee..a2d669157 100644 --- a/crates/valence_boss_bar/Cargo.toml +++ b/crates/valence_boss_bar/Cargo.toml @@ -12,6 +12,7 @@ valence_core.workspace = true valence_network.workspace = true valence_entity.workspace = true valence_client.workspace = true +valence_packet.workspace = true uuid.workspace = true bitfield-struct.workspace = true bevy_app.workspace = true diff --git a/crates/valence_boss_bar/src/lib.rs b/crates/valence_boss_bar/src/lib.rs index d1fd642f0..e1f2e6986 100644 --- a/crates/valence_boss_bar/src/lib.rs +++ b/crates/valence_boss_bar/src/lib.rs @@ -19,19 +19,138 @@ )] use std::borrow::Cow; +use std::collections::BTreeSet; use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use packet::{BossBarAction, BossBarS2c}; use valence_client::{Client, FlushPacketsSet}; +use valence_core::boss_bar::{BossBarColor, BossBarDivision, BossBarFlags}; use valence_core::despawn::Despawned; use valence_core::protocol::encode::WritePacket; +use valence_core::text::Text; use valence_core::uuid::UniqueId; +use valence_packet::boss_bar::{BossBarAction, BossBarS2c}; -mod components; -pub use components::*; +#[derive(Clone, Debug)] +enum BossBarUpdate { + UpdateHealth(f32), + UpdateTitle(Text), + UpdateStyle(BossBarColor, BossBarDivision), + UpdateFlags(BossBarFlags), +} + +#[derive(Clone, Debug, Component)] +pub struct BossBar { + pub title: Text, + /// From 0 to 1. Values greater than 1 do not crash a Notchian client, and + /// start rendering part of a second health bar at around 1.5 + pub health: f32, + pub color: BossBarColor, + pub division: BossBarDivision, + pub flags: BossBarFlags, + update: Vec, +} + +impl BossBar { + fn new( + title: Text, + health: f32, + color: BossBarColor, + division: BossBarDivision, + flags: BossBarFlags, + ) -> Self { + Self { + title, + health, + color, + division, + flags, + update: Vec::new(), + } + } + + pub fn update_health(&mut self, health: f32) { + self.health = health; + self.update.push(BossBarUpdate::UpdateHealth(health)); + } + + pub fn update_title(&mut self, title: Text) { + let cloned_title = title.clone(); + self.title = title; + self.update.push(BossBarUpdate::UpdateTitle(cloned_title)); + } + + pub fn update_style(&mut self, color: Option, division: Option) { + if let Some(color) = color { + self.color = color; + } + if let Some(division) = division { + self.division = division; + } + self.update + .push(BossBarUpdate::UpdateStyle(self.color, self.division)); + } + + pub fn update_flags(&mut self, flags: BossBarFlags) { + self.flags = flags; + self.update.push(BossBarUpdate::UpdateFlags(flags)); + } +} -pub mod packet; +/// The viewers of a boss bar. +#[derive(Component, Default, Debug, Clone)] +pub struct BossBarViewers { + /// The current viewers of the boss bar. It is the list that should be + /// updated. + pub viewers: BTreeSet, + /// The viewers of the last tick in order to determine which viewers have + /// been added and removed. + pub(crate) old_viewers: BTreeSet, +} + +#[derive(Bundle, Debug)] +pub struct BossBarBundle { + boss_bar: BossBar, + unique_id: UniqueId, + viewers: BossBarViewers, +} + +impl BossBarBundle { + pub fn new( + title: Text, + health: f32, + color: BossBarColor, + division: BossBarDivision, + flags: BossBarFlags, + ) -> Self { + Self { + boss_bar: BossBar::new(title, health, color, division, flags), + unique_id: UniqueId::default(), + viewers: BossBarViewers::default(), + } + } +} + +// #[derive(Debug, Component, Default)] +// struct VisibleBossBar(pub BTreeSet); + +// #[derive(Debug, Component, Default)] +// struct OldVisibleBossBar(BTreeSet); + +// #[derive(Debug, Bundle, Default)] +// pub struct VisibleBossBarBundle { +// visible_boss_bar: VisibleBossBar, +// old_visible_boss_bar: OldVisibleBossBar, +// } + +// impl VisibleBossBarBundle { +// pub fn new(boss_bar_ids: Vec) -> Self { +// Self { +// visible_boss_bar: +// VisibleBossBar(boss_bar_ids.into_iter().collect()), +// ..Default::default() } +// } +// } pub struct BossBarPlugin; @@ -40,10 +159,7 @@ impl Plugin for BossBarPlugin { app.add_systems( PostUpdate, ( - boss_bar_title_update, - boss_bar_health_update, - boss_bar_style_update, - boss_bar_flags_update, + update_boss_bar, boss_bar_viewers_update, boss_bar_despawn, client_disconnection.before(boss_bar_viewers_update), @@ -53,95 +169,54 @@ impl Plugin for BossBarPlugin { } } -/// System that sends a bossbar update title packet to all viewers of a boss bar -/// that has had its title updated. -fn boss_bar_title_update( - boss_bars: Query<(&UniqueId, &BossBarTitle, &BossBarViewers), Changed>, +fn update_boss_bar( + mut boss_bars: Query<(&UniqueId, &mut BossBar, &BossBarViewers), Changed>, mut clients: Query<&mut Client>, ) { - for (id, title, boss_bar_viewers) in boss_bars.iter() { + for (id, mut boss_bar, boss_bar_viewers) in boss_bars.iter_mut() { for viewer in boss_bar_viewers.viewers.iter() { if let Ok(mut client) = clients.get_mut(*viewer) { - client.write_packet(&BossBarS2c { - id: id.0, - action: BossBarAction::UpdateTitle(Cow::Borrowed(&title.0)), - }); - } - } - } -} - -/// System that sends a bossbar update health packet to all viewers of a boss -/// bar that has had its health updated. -fn boss_bar_health_update( - boss_bars: Query<(&UniqueId, &BossBarHealth, &BossBarViewers), Changed>, - mut clients: Query<&mut Client>, -) { - for (id, health, boss_bar_viewers) in boss_bars.iter() { - for viewer in boss_bar_viewers.viewers.iter() { - if let Ok(mut client) = clients.get_mut(*viewer) { - client.write_packet(&BossBarS2c { - id: id.0, - action: BossBarAction::UpdateHealth(health.0), - }); - } - } - } -} - -/// System that sends a bossbar update style packet to all viewers of a boss bar -/// that has had its style updated. -fn boss_bar_style_update( - boss_bars: Query<(&UniqueId, &BossBarStyle, &BossBarViewers), Changed>, - mut clients: Query<&mut Client>, -) { - for (id, style, boss_bar_viewers) in boss_bars.iter() { - for viewer in boss_bar_viewers.viewers.iter() { - if let Ok(mut client) = clients.get_mut(*viewer) { - client.write_packet(&BossBarS2c { - id: id.0, - action: BossBarAction::UpdateStyle(style.color, style.division), - }); - } - } - } -} - -/// System that sends a bossbar update flags packet to all viewers of a boss bar -/// that has had its flags updated. -fn boss_bar_flags_update( - boss_bars: Query<(&UniqueId, &BossBarFlags, &BossBarViewers), Changed>, - mut clients: Query<&mut Client>, -) { - for (id, flags, boss_bar_viewers) in boss_bars.iter() { - for viewer in boss_bar_viewers.viewers.iter() { - if let Ok(mut client) = clients.get_mut(*viewer) { - client.write_packet(&BossBarS2c { - id: id.0, - action: BossBarAction::UpdateFlags(*flags), - }); + for update in boss_bar.update.clone().into_iter() { + match update { + BossBarUpdate::UpdateHealth(health) => { + client.write_packet(&BossBarS2c { + id: id.0, + action: BossBarAction::UpdateHealth(health), + }); + } + BossBarUpdate::UpdateTitle(title) => { + client.write_packet(&BossBarS2c { + id: id.0, + action: BossBarAction::UpdateTitle(Cow::Borrowed(&title)), + }); + } + BossBarUpdate::UpdateStyle(color, division) => { + client.write_packet(&BossBarS2c { + id: id.0, + action: BossBarAction::UpdateStyle(color, division), + }); + } + BossBarUpdate::UpdateFlags(flags) => { + client.write_packet(&BossBarS2c { + id: id.0, + action: BossBarAction::UpdateFlags(flags), + }); + } + } + } } } + boss_bar.update.clear(); } } /// System that sends a bossbar add/remove packet to all viewers of a boss bar /// that just have been added/removed. fn boss_bar_viewers_update( - mut boss_bars: Query< - ( - &UniqueId, - &BossBarTitle, - &BossBarHealth, - &BossBarStyle, - &BossBarFlags, - &mut BossBarViewers, - ), - Changed, - >, + mut boss_bars: Query<(&UniqueId, &BossBar, &mut BossBarViewers), Changed>, mut clients: Query<&mut Client>, ) { - for (id, title, health, style, flags, mut boss_bar_viewers) in boss_bars.iter_mut() { + for (id, boss_bar, mut boss_bar_viewers) in boss_bars.iter_mut() { let old_viewers = &boss_bar_viewers.old_viewers; let current_viewers = &boss_bar_viewers.viewers; @@ -150,11 +225,11 @@ fn boss_bar_viewers_update( client.write_packet(&BossBarS2c { id: id.0, action: BossBarAction::Add { - title: Cow::Borrowed(&title.0), - health: health.0, - color: style.color, - division: style.division, - flags: *flags, + title: Cow::Borrowed(&boss_bar.title), + health: boss_bar.health, + color: boss_bar.color, + division: boss_bar.division, + flags: boss_bar.flags, }, }); } diff --git a/crates/valence_core/src/boss_bar.rs b/crates/valence_core/src/boss_bar.rs new file mode 100644 index 000000000..8c2f8c587 --- /dev/null +++ b/crates/valence_core/src/boss_bar.rs @@ -0,0 +1,35 @@ +use bitfield_struct::bitfield; +use valence_core_macros::{Decode, Encode}; + +/// The color of a boss bar. +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum BossBarColor { + Pink, + Blue, + Red, + Green, + Yellow, + Purple, + White, +} + +/// The division of a boss bar. +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum BossBarDivision { + NoDivision, + SixNotches, + TenNotches, + TwelveNotches, + TwentyNotches, +} + +/// The flags of a boss bar (darken sky, dragon bar, create fog). +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct BossBarFlags { + pub darken_sky: bool, + pub dragon_bar: bool, + pub create_fog: bool, + #[bits(5)] + _pad: u8, +} diff --git a/crates/valence_core/src/lib.rs b/crates/valence_core/src/lib.rs index 2873b986a..e6e4fc9b5 100644 --- a/crates/valence_core/src/lib.rs +++ b/crates/valence_core/src/lib.rs @@ -20,6 +20,7 @@ pub mod aabb; pub mod block_pos; +pub mod boss_bar; pub mod chunk_pos; pub mod despawn; pub mod difficulty; @@ -33,10 +34,10 @@ pub mod player_textures; pub mod property; pub mod protocol; pub mod scratch; +pub mod sound; pub mod text; pub mod translation_key; pub mod uuid; -pub mod sound; use std::num::NonZeroU32; use std::time::Duration; diff --git a/crates/valence_packet/src/boss_bar.rs b/crates/valence_packet/src/boss_bar.rs index feff21558..e427eb46d 100644 --- a/crates/valence_packet/src/boss_bar.rs +++ b/crates/valence_packet/src/boss_bar.rs @@ -1,24 +1,26 @@ +use valence_core::boss_bar::{BossBarColor, BossBarDivision, BossBarFlags}; + use super::*; -// #[derive(Clone, Debug, Encode, Decode, Packet)] -// #[packet(id = packet_id::BOSS_BAR_S2C)] -// pub struct BossBarS2c<'a> { -// pub id: Uuid, -// pub action: BossBarAction<'a>, -// } +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::BOSS_BAR_S2C)] +pub struct BossBarS2c<'a> { + pub id: Uuid, + pub action: BossBarAction<'a>, +} -// #[derive(Clone, PartialEq, Debug, Encode, Decode)] -// pub enum BossBarAction<'a> { -// Add { -// title: Cow<'a, Text>, -// health: f32, -// color: BossBarColor, -// division: BossBarDivision, -// flags: BossBarFlags, -// }, -// Remove, -// UpdateHealth(f32), -// UpdateTitle(Cow<'a, Text>), -// UpdateStyle(BossBarColor, BossBarDivision), -// UpdateFlags(BossBarFlags), -// } +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub enum BossBarAction<'a> { + Add { + title: Cow<'a, Text>, + health: f32, + color: BossBarColor, + division: BossBarDivision, + flags: BossBarFlags, + }, + Remove, + UpdateHealth(f32), + UpdateTitle(Cow<'a, Text>), + UpdateStyle(BossBarColor, BossBarDivision), + UpdateFlags(BossBarFlags), +} diff --git a/examples/boss_bar.rs b/examples/boss_bar.rs index ac73c457a..9b26eb3f1 100644 --- a/examples/boss_bar.rs +++ b/examples/boss_bar.rs @@ -1,10 +1,8 @@ use rand::seq::SliceRandom; use valence::prelude::*; -use valence_boss_bar::{ - BossBarBundle, BossBarColor, BossBarDivision, BossBarFlags, BossBarHealth, BossBarStyle, - BossBarTitle, BossBarViewers, -}; +use valence_boss_bar::{BossBar, BossBarBundle, BossBarViewers}; use valence_client::message::{ChatMessageEvent, SendMessage}; +use valence_core::boss_bar::{BossBarColor, BossBarDivision, BossBarFlags}; const SPAWN_Y: i32 = 64; @@ -41,6 +39,7 @@ fn setup( commands.spawn(BossBarBundle::new( Text::text("Boss bar"), + 1.0, BossBarColor::Blue, BossBarDivision::TenNotches, BossBarFlags::new(), @@ -95,6 +94,9 @@ fn init_clients( client.send_chat_message( "Type any number between 0 and 1 to set the health".on_click_suggest_command("health"), ); + client.send_chat_message( + "Type 'random' to set random values".on_click_suggest_command("random"), + ); boss_bar_viewers.viewers.insert(entity); } @@ -102,21 +104,9 @@ fn init_clients( fn listen_messages( mut message_events: EventReader, - mut boss_bar: Query<( - &mut BossBarViewers, - &mut BossBarStyle, - &mut BossBarFlags, - &mut BossBarHealth, - &mut BossBarTitle, - )>, + mut boss_bar: Query<(&mut BossBarViewers, &mut BossBar)>, ) { - let ( - mut boss_bar_viewers, - mut boss_bar_style, - mut boss_bar_flags, - mut boss_bar_health, - mut boss_bar_title, - ) = boss_bar.single_mut(); + let (mut boss_bar_viewers, mut boss_bar) = boss_bar.single_mut(); let events: Vec = message_events.iter().cloned().collect(); for ChatMessageEvent { @@ -139,11 +129,11 @@ fn listen_messages( BossBarColor::Green, BossBarColor::Yellow, ]; - colors.retain(|c| *c != boss_bar_style.color); + colors.retain(|c| *c != boss_bar.color); let random_color = colors.choose(&mut rand::thread_rng()).unwrap(); - boss_bar_style.color = *random_color; + boss_bar.update_style(Some(*random_color), None); } "division" => { let mut divisions = vec![ @@ -153,30 +143,78 @@ fn listen_messages( BossBarDivision::TwelveNotches, BossBarDivision::TwentyNotches, ]; - divisions.retain(|d| *d != boss_bar_style.division); + divisions.retain(|d| *d != boss_bar.division); let random_division = divisions.choose(&mut rand::thread_rng()).unwrap(); - boss_bar_style.division = *random_division; + boss_bar.update_style(None, Some(*random_division)); } "flags" => { let darken_sky: bool = rand::random(); let dragon_bar: bool = rand::random(); let create_fog: bool = rand::random(); - boss_bar_flags.set_darken_sky(darken_sky); - boss_bar_flags.set_dragon_bar(dragon_bar); - boss_bar_flags.set_create_fog(create_fog); + boss_bar.update_flags( + BossBarFlags::new() + .with_create_fog(create_fog) + .with_darken_sky(darken_sky) + .with_dragon_bar(dragon_bar), + ); + } + "random" => { + let mut colors = vec![ + BossBarColor::Pink, + BossBarColor::Blue, + BossBarColor::Red, + BossBarColor::Green, + BossBarColor::Yellow, + ]; + colors.retain(|c| *c != boss_bar.color); + + let random_color = colors.choose(&mut rand::thread_rng()).unwrap(); + + let mut divisions = vec![ + BossBarDivision::NoDivision, + BossBarDivision::SixNotches, + BossBarDivision::TenNotches, + BossBarDivision::TwelveNotches, + BossBarDivision::TwentyNotches, + ]; + divisions.retain(|d| *d != boss_bar.division); + + let random_division = divisions.choose(&mut rand::thread_rng()).unwrap(); + + let darken_sky: bool = rand::random(); + let dragon_bar: bool = rand::random(); + let create_fog: bool = rand::random(); + + boss_bar.update_style(Some(*random_color), Some(*random_division)); + boss_bar.update_flags( + BossBarFlags::new() + .with_create_fog(create_fog) + .with_darken_sky(darken_sky) + .with_dragon_bar(dragon_bar), + ); + boss_bar.update_title(randomize_string("Random boss bar").into()); + + let random_health = rand::random::(); + boss_bar.update_health(random_health); } _ => { if let Ok(health) = message.parse::() { if (0.0..=1.0).contains(&health) { - boss_bar_health.0 = health; + boss_bar.update_health(health); } } else { - boss_bar_title.0 = message.to_string().into(); + boss_bar.update_title(message.to_string().into()); } } }; } } + +fn randomize_string(s: &str) -> String { + let mut chars: Vec = s.chars().collect(); + chars.shuffle(&mut rand::thread_rng()); + chars.into_iter().collect() +} diff --git a/src/tests/boss_bar.rs b/src/tests/boss_bar.rs index 317f10730..2023fa9d7 100644 --- a/src/tests/boss_bar.rs +++ b/src/tests/boss_bar.rs @@ -1,12 +1,10 @@ use bevy_app::App; use bevy_ecs::entity::Entity; -use valence_boss_bar::packet::BossBarS2c; -use valence_boss_bar::{ - BossBarBundle, BossBarColor, BossBarDivision, BossBarFlags, BossBarHealth, BossBarStyle, - BossBarTitle, BossBarViewers, -}; +use valence_boss_bar::{BossBar, BossBarBundle, BossBarViewers}; +use valence_core::boss_bar::{BossBarColor, BossBarDivision, BossBarFlags}; use valence_core::despawn::Despawned; use valence_core::text::Text; +use valence_packet::boss_bar::BossBarS2c; use crate::testing::{scenario_single_client, MockClientHelper}; @@ -55,17 +53,17 @@ fn test_title_update() { let mut app = App::new(); let (client_ent, mut client_helper, instance_ent) = prepare(&mut app); - // Fetch the boss bar component - let mut boss_bar = app.world.get_mut::(instance_ent).unwrap(); + // Fetch the boss bar viewers component + let mut boss_bar_viewers = app.world.get_mut::(instance_ent).unwrap(); // Add our mock client to the viewers list - assert!(boss_bar.viewers.insert(client_ent)); + assert!(boss_bar_viewers.viewers.insert(client_ent)); app.update(); - // Update the title - app.world - .entity_mut(instance_ent) - .insert(BossBarTitle(Text::text("Test 2"))); + // Update the bossbar component + let mut boss_bar = app.world.get_mut::(instance_ent).unwrap(); + + boss_bar.update_title(Text::text("New title")); app.update(); @@ -87,10 +85,10 @@ fn test_health_update() { app.update(); - // Update the health - app.world - .entity_mut(instance_ent) - .insert(BossBarHealth(0.5)); + // Update the bossbar component + let mut boss_bar = app.world.get_mut::(instance_ent).unwrap(); + + boss_bar.update_health(0.5); app.update(); @@ -107,16 +105,16 @@ fn test_style_update() { // Fetch the boss bar component let mut boss_bar = app.world.get_mut::(instance_ent).unwrap(); + // Add our mock client to the viewers list assert!(boss_bar.viewers.insert(client_ent)); app.update(); - // Update the style - app.world.entity_mut(instance_ent).insert(BossBarStyle { - color: BossBarColor::Red, - division: BossBarDivision::TenNotches, - }); + // Update the bossbar component + let mut boss_bar = app.world.get_mut::(instance_ent).unwrap(); + + boss_bar.update_style(Some(BossBarColor::Red), Some(BossBarDivision::TenNotches)); app.update(); @@ -138,10 +136,10 @@ fn test_flags_update() { app.update(); - // Update the flags - let mut new_flags = BossBarFlags::new(); - new_flags.set_create_fog(true); - app.world.entity_mut(instance_ent).insert(new_flags); + // Update the bossbar component + let mut boss_bar = app.world.get_mut::(instance_ent).unwrap(); + + boss_bar.update_flags(BossBarFlags::new().with_create_fog(true)); app.update(); @@ -192,7 +190,8 @@ fn prepare(app: &mut App) -> (Entity, MockClientHelper, Entity) { let boss_bar = app .world .spawn(BossBarBundle::new( - Text::text("Test"), + Text::text("Test boss bar"), + 1.0, BossBarColor::Blue, BossBarDivision::SixNotches, BossBarFlags::new(), From 97854c1433c43da113db23a3b2f28a8da1f93a41 Mon Sep 17 00:00:00 2001 From: Bafbi Date: Sun, 30 Jul 2023 21:42:13 +0200 Subject: [PATCH 3/9] fmt + clippy --- crates/valence_advancement/src/event.rs | 1 - crates/valence_advancement/src/lib.rs | 25 +- crates/valence_boss_bar/src/lib.rs | 24 +- crates/valence_client/src/action.rs | 2 +- crates/valence_client/src/lib.rs | 22 +- crates/valence_client/src/message.rs | 2 +- crates/valence_client/src/weather.rs | 3 +- crates/valence_core/src/sound.rs | 2 +- crates/valence_instance/src/chunk/loaded.rs | 8 +- crates/valence_instance/src/instance.rs | 4 +- crates/valence_instance/src/lib.rs | 10 +- crates/valence_inventory/src/lib.rs | 12 +- crates/valence_inventory/src/validate.rs | 4 +- crates/valence_network/src/connect.rs | 4 +- crates/valence_packet/src/instance.rs | 3 +- crates/valence_packet/src/scoreboard.rs | 614 ++++++++++---------- crates/valence_player_list/src/lib.rs | 2 +- crates/valence_world_border/src/lib.rs | 2 +- src/lib.rs | 4 +- src/tests/client.rs | 4 +- src/tests/example.rs | 2 +- src/tests/instance.rs | 2 +- src/tests/inventory.rs | 10 +- src/tests/player_list.rs | 2 +- src/tests/weather.rs | 2 +- src/tests/world_border.rs | 2 +- 26 files changed, 384 insertions(+), 388 deletions(-) diff --git a/crates/valence_advancement/src/event.rs b/crates/valence_advancement/src/event.rs index a2e42ccde..bb2a46dcb 100644 --- a/crates/valence_advancement/src/event.rs +++ b/crates/valence_advancement/src/event.rs @@ -1,7 +1,6 @@ use bevy_ecs::prelude::*; use valence_client::event_loop::PacketEvent; use valence_core::ident::Ident; - use valence_packet::advancement::AdvancementTabC2s; /// This event sends when the client changes or closes advancement's tab. diff --git a/crates/valence_advancement/src/lib.rs b/crates/valence_advancement/src/lib.rs index 161ae794f..93478164e 100644 --- a/crates/valence_advancement/src/lib.rs +++ b/crates/valence_advancement/src/lib.rs @@ -13,9 +13,6 @@ use bevy_ecs::system::SystemParam; pub use bevy_hierarchy; use bevy_hierarchy::{Children, HierarchyPlugin, Parent}; use event::{handle_advancement_tab_change, AdvancementTabChangeEvent}; -use valence_packet::advancement::{SelectAdvancementTabS2c, AdvancementRequirementsPkt, GenericAdvancementUpdateS2c, AdvancementCriteriaPkt}; -use valence_packet::advancement::AdvancementPkt; -use valence_packet::advancement::AdvancementDisplayPkt; use rustc_hash::FxHashMap; use valence_client::{Client, FlushPacketsSet, SpawnClientsSet}; use valence_core::ident::Ident; @@ -25,6 +22,10 @@ use valence_core::protocol::raw::RawBytes; use valence_core::protocol::var_int::VarInt; use valence_core::protocol::{packet_id, Encode, Packet, PacketSide, PacketState}; use valence_core::text::Text; +use valence_packet::advancement::{ + AdvancementCriteriaPkt, AdvancementDisplayPkt, AdvancementPkt, AdvancementRequirementsPkt, + GenericAdvancementUpdateS2c, SelectAdvancementTabS2c, +}; pub struct AdvancementPlugin; @@ -93,8 +94,7 @@ struct UpdateAdvancementCachedBytesQuery<'w, 's> { impl<'w, 's> UpdateAdvancementCachedBytesQuery<'w, 's> { fn write( &self, - a_identifier: &Advancement -, + a_identifier: &Advancement, a_requirements: &AdvancementRequirements, a_display: Option<&AdvancementDisplay>, a_children: Option<&Children>, @@ -106,8 +106,7 @@ impl<'w, 's> UpdateAdvancementCachedBytesQuery<'w, 's> { criteria_query, } = self; - let mut pkt = AdvancementPkt - { + let mut pkt = AdvancementPkt { parent_id: None, display_data: None, criteria: vec![], @@ -160,8 +159,7 @@ impl<'w, 's> UpdateAdvancementCachedBytesQuery<'w, 's> { fn update_advancement_cached_bytes( mut query: Query< ( - &Advancement - , + &Advancement, &AdvancementRequirements, &mut AdvancementCachedBytes, Option<&AdvancementDisplay>, @@ -436,8 +434,7 @@ impl AdvancementClientUpdate { pub(crate) fn walk_advancements( root: Entity, children_query: &Query<&Children>, - advancement_check_query: &Query<(), With>, + advancement_check_query: &Query<(), With>, func: &mut impl FnMut(Entity), ) { func(root); @@ -456,8 +453,7 @@ impl AdvancementClientUpdate { &mut self, root: Entity, children_query: &Query<&Children>, - advancement_check_query: &Query<(), With>, + advancement_check_query: &Query<(), With>, ) { Self::walk_advancements(root, children_query, advancement_check_query, &mut |e| { self.new_advancements.push(e) @@ -469,8 +465,7 @@ impl AdvancementClientUpdate { &mut self, root: Entity, children_query: &Query<&Children>, - advancement_check_query: &Query<(), With>, + advancement_check_query: &Query<(), With>, ) { Self::walk_advancements(root, children_query, advancement_check_query, &mut |e| { self.remove_advancements.push(e) diff --git a/crates/valence_boss_bar/src/lib.rs b/crates/valence_boss_bar/src/lib.rs index e1f2e6986..a815d0205 100644 --- a/crates/valence_boss_bar/src/lib.rs +++ b/crates/valence_boss_bar/src/lib.rs @@ -33,10 +33,10 @@ use valence_packet::boss_bar::{BossBarAction, BossBarS2c}; #[derive(Clone, Debug)] enum BossBarUpdate { - UpdateHealth(f32), - UpdateTitle(Text), - UpdateStyle(BossBarColor, BossBarDivision), - UpdateFlags(BossBarFlags), + Health(f32), + Title(Text), + Style(BossBarColor, BossBarDivision), + Flags(BossBarFlags), } #[derive(Clone, Debug, Component)] @@ -71,13 +71,13 @@ impl BossBar { pub fn update_health(&mut self, health: f32) { self.health = health; - self.update.push(BossBarUpdate::UpdateHealth(health)); + self.update.push(BossBarUpdate::Health(health)); } pub fn update_title(&mut self, title: Text) { let cloned_title = title.clone(); self.title = title; - self.update.push(BossBarUpdate::UpdateTitle(cloned_title)); + self.update.push(BossBarUpdate::Title(cloned_title)); } pub fn update_style(&mut self, color: Option, division: Option) { @@ -88,12 +88,12 @@ impl BossBar { self.division = division; } self.update - .push(BossBarUpdate::UpdateStyle(self.color, self.division)); + .push(BossBarUpdate::Style(self.color, self.division)); } pub fn update_flags(&mut self, flags: BossBarFlags) { self.flags = flags; - self.update.push(BossBarUpdate::UpdateFlags(flags)); + self.update.push(BossBarUpdate::Flags(flags)); } } @@ -178,25 +178,25 @@ fn update_boss_bar( if let Ok(mut client) = clients.get_mut(*viewer) { for update in boss_bar.update.clone().into_iter() { match update { - BossBarUpdate::UpdateHealth(health) => { + BossBarUpdate::Health(health) => { client.write_packet(&BossBarS2c { id: id.0, action: BossBarAction::UpdateHealth(health), }); } - BossBarUpdate::UpdateTitle(title) => { + BossBarUpdate::Title(title) => { client.write_packet(&BossBarS2c { id: id.0, action: BossBarAction::UpdateTitle(Cow::Borrowed(&title)), }); } - BossBarUpdate::UpdateStyle(color, division) => { + BossBarUpdate::Style(color, division) => { client.write_packet(&BossBarS2c { id: id.0, action: BossBarAction::UpdateStyle(color, division), }); } - BossBarUpdate::UpdateFlags(flags) => { + BossBarUpdate::Flags(flags) => { client.write_packet(&BossBarS2c { id: id.0, action: BossBarAction::UpdateFlags(flags), diff --git a/crates/valence_client/src/action.rs b/crates/valence_client/src/action.rs index 2589d7ad2..c8bea94db 100644 --- a/crates/valence_client/src/action.rs +++ b/crates/valence_client/src/action.rs @@ -2,10 +2,10 @@ use valence_core::block_pos::BlockPos; use valence_core::direction::Direction; use valence_core::protocol::var_int::VarInt; use valence_core::protocol::{packet_id, Decode, Encode, Packet}; +use valence_packet::client::{PlayerAction, PlayerActionC2s}; use super::*; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; -use valence_packet::client::{PlayerAction, PlayerActionC2s}; pub(super) fn build(app: &mut App) { app.add_event::() diff --git a/crates/valence_client/src/lib.rs b/crates/valence_client/src/lib.rs index 5f7fc1ee5..aa0296b3f 100644 --- a/crates/valence_client/src/lib.rs +++ b/crates/valence_client/src/lib.rs @@ -30,10 +30,6 @@ use bevy_ecs::query::WorldQuery; use bevy_ecs::system::Command; use bytes::{Bytes, BytesMut}; use glam::{DVec3, Vec3}; -use valence_packet::client::{ - DeathMessageS2c, DisconnectS2c, GameEventKind, GameJoinS2c, GameStateChangeS2c, - PlayerRespawnS2c, PlayerSpawnPositionS2c, PlayerSpawnS2c, -}; use tracing::{debug, warn}; use uuid::Uuid; use valence_biome::BiomeRegistry; @@ -47,26 +43,30 @@ use valence_core::property::Property; use valence_core::protocol::byte_angle::ByteAngle; use valence_core::protocol::encode::{PacketEncoder, WritePacket}; use valence_core::protocol::global_pos::GlobalPos; -use valence_packet::sound::PlaySoundS2c; -use valence_core::sound::{Sound, SoundCategory}; use valence_core::protocol::var_int::VarInt; use valence_core::protocol::{Encode, Packet}; +use valence_core::sound::{Sound, SoundCategory}; use valence_core::text::{IntoText, Text}; use valence_core::uuid::UniqueId; -use valence_packet::entity::{ - EntitiesDestroyS2c, EntitySetHeadYawS2c, EntitySpawnS2c, EntityStatusS2c, - EntityTrackerUpdateS2c, EntityVelocityUpdateS2c, ExperienceOrbSpawnS2c, -}; use valence_entity::player::PlayerEntityBundle; use valence_entity::{ ClearEntityChangesSet, EntityId, EntityKind, EntityStatus, HeadYaw, Location, Look, ObjectData, OldLocation, OldPosition, OnGround, PacketByteRange, Position, TrackedData, Velocity, }; use valence_instance::chunk::loaded::ChunkState; +use valence_instance::{ClearInstanceChangesSet, Instance, WriteUpdatePacketsToInstancesSet}; +use valence_packet::client::{ + DeathMessageS2c, DisconnectS2c, GameEventKind, GameJoinS2c, GameStateChangeS2c, + PlayerRespawnS2c, PlayerSpawnPositionS2c, PlayerSpawnS2c, +}; +use valence_packet::entity::{ + EntitiesDestroyS2c, EntitySetHeadYawS2c, EntitySpawnS2c, EntityStatusS2c, + EntityTrackerUpdateS2c, EntityVelocityUpdateS2c, ExperienceOrbSpawnS2c, +}; use valence_packet::instance::{ ChunkLoadDistanceS2c, ChunkRenderDistanceCenterS2c, UnloadChunkS2c, }; -use valence_instance::{ClearInstanceChangesSet, Instance, WriteUpdatePacketsToInstancesSet}; +use valence_packet::sound::PlaySoundS2c; use valence_registry::codec::RegistryCodec; use valence_registry::tags::TagsRegistry; use valence_registry::RegistrySet; diff --git a/crates/valence_client/src/message.rs b/crates/valence_client/src/message.rs index 8a5483490..8bc5c0996 100644 --- a/crates/valence_client/src/message.rs +++ b/crates/valence_client/src/message.rs @@ -3,8 +3,8 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use valence_core::protocol::encode::WritePacket; -use valence_packet::chat::{ChatMessageC2s, GameMessageS2c}; use valence_core::text::IntoText; +use valence_packet::chat::{ChatMessageC2s, GameMessageS2c}; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; diff --git a/crates/valence_client/src/weather.rs b/crates/valence_client/src/weather.rs index 07480c469..4694a9841 100644 --- a/crates/valence_client/src/weather.rs +++ b/crates/valence_client/src/weather.rs @@ -15,9 +15,10 @@ //! New joined players are handled, so that they are get weather events from //! the instance. -use super::*; use valence_packet::client::{GameEventKind, GameStateChangeS2c}; +use super::*; + #[derive(SystemSet, Copy, Clone, PartialEq, Eq, Hash, Debug)] struct UpdateWeatherPerInstanceSet; diff --git a/crates/valence_core/src/sound.rs b/crates/valence_core/src/sound.rs index 27177f307..91733d742 100644 --- a/crates/valence_core/src/sound.rs +++ b/crates/valence_core/src/sound.rs @@ -70,4 +70,4 @@ pub enum SoundCategory { Player, Ambient, Voice, -} \ No newline at end of file +} diff --git a/crates/valence_instance/src/chunk/loaded.rs b/crates/valence_instance/src/chunk/loaded.rs index 963fc71db..c6bffddfd 100644 --- a/crates/valence_instance/src/chunk/loaded.rs +++ b/crates/valence_instance/src/chunk/loaded.rs @@ -17,6 +17,10 @@ use valence_core::protocol::var_long::VarLong; use valence_core::protocol::{Encode, Packet}; use valence_entity::EntityKind; use valence_nbt::{compound, Compound}; +use valence_packet::instance::{ + BlockEntityUpdateS2c, BlockUpdateS2c, ChunkBiome, ChunkBiomeDataS2c, ChunkDataBlockEntity, + ChunkDataS2c, ChunkDeltaUpdateS2c, +}; use valence_registry::RegistryIdx; use super::paletted_container::PalettedContainer; @@ -24,10 +28,6 @@ use super::{ bit_width, check_biome_oob, check_block_oob, check_section_oob, unloaded, BiomeContainer, BlockStateContainer, Chunk, UnloadedChunk, SECTION_BLOCK_COUNT, }; -use valence_packet::instance::{ - BlockEntityUpdateS2c, BlockUpdateS2c, ChunkBiome, ChunkBiomeDataS2c, ChunkDataBlockEntity, - ChunkDataS2c, ChunkDeltaUpdateS2c, -}; use crate::{InstanceInfo, UpdateEntityQuery}; #[derive(Debug)] diff --git a/crates/valence_instance/src/instance.rs b/crates/valence_instance/src/instance.rs index 9334942b5..e291b0609 100644 --- a/crates/valence_instance/src/instance.rs +++ b/crates/valence_instance/src/instance.rs @@ -14,12 +14,12 @@ use valence_core::ident::Ident; use valence_core::particle::{Particle, ParticleS2c}; use valence_core::protocol::array::LengthPrefixedArray; use valence_core::protocol::encode::{PacketWriter, WritePacket}; -use valence_packet::sound::PlaySoundS2c; -use valence_core::sound::{Sound, SoundCategory}; use valence_core::protocol::{Encode, Packet}; +use valence_core::sound::{Sound, SoundCategory}; use valence_core::Server; use valence_dimension::DimensionTypeRegistry; use valence_nbt::Compound; +use valence_packet::sound::PlaySoundS2c; use crate::chunk::{Block, BlockRef, Chunk, IntoBlock, LoadedChunk, UnloadedChunk, MAX_HEIGHT}; diff --git a/crates/valence_instance/src/lib.rs b/crates/valence_instance/src/lib.rs index 9a2145a44..8f2c582e3 100644 --- a/crates/valence_instance/src/lib.rs +++ b/crates/valence_instance/src/lib.rs @@ -29,16 +29,16 @@ use valence_core::despawn::Despawned; use valence_core::protocol::byte_angle::ByteAngle; use valence_core::protocol::encode::WritePacket; use valence_core::protocol::var_int::VarInt; -use valence_packet::entity::{ - EntityAnimationS2c, EntityPositionS2c, EntitySetHeadYawS2c, EntityStatusS2c, - EntityTrackerUpdateS2c, EntityVelocityUpdateS2c, MoveRelativeS2c, RotateAndMoveRelativeS2c, - RotateS2c, -}; use valence_entity::{ EntityAnimations, EntityId, EntityKind, EntityStatuses, HeadYaw, InitEntitiesSet, Location, Look, OldLocation, OldPosition, OnGround, PacketByteRange, Position, TrackedData, UpdateTrackedDataSet, Velocity, }; +use valence_packet::entity::{ + EntityAnimationS2c, EntityPositionS2c, EntitySetHeadYawS2c, EntityStatusS2c, + EntityTrackerUpdateS2c, EntityVelocityUpdateS2c, MoveRelativeS2c, RotateAndMoveRelativeS2c, + RotateS2c, +}; pub mod chunk; mod instance; diff --git a/crates/valence_inventory/src/lib.rs b/crates/valence_inventory/src/lib.rs index cf82a974e..624d4b688 100644 --- a/crates/valence_inventory/src/lib.rs +++ b/crates/valence_inventory/src/lib.rs @@ -25,20 +25,20 @@ use std::ops::Range; use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use valence_packet::inventory::{ - ClickMode, ClickSlotC2s, CloseHandledScreenC2s, CloseScreenS2c, CreativeInventoryActionC2s, - InventoryS2c, OpenScreenS2c, ScreenHandlerSlotUpdateS2c, SlotChange, UpdateSelectedSlotC2s, - WindowType, -}; use tracing::{debug, warn}; use valence_client::event_loop::{EventLoopPreUpdate, PacketEvent}; -use valence_packet::client::{PlayerAction, PlayerActionC2s}; use valence_client::{Client, FlushPacketsSet, SpawnClientsSet}; use valence_core::game_mode::GameMode; use valence_core::item::ItemStack; use valence_core::protocol::encode::WritePacket; use valence_core::protocol::var_int::VarInt; use valence_core::text::{IntoText, Text}; +use valence_packet::client::{PlayerAction, PlayerActionC2s}; +use valence_packet::inventory::{ + ClickMode, ClickSlotC2s, CloseHandledScreenC2s, CloseScreenS2c, CreativeInventoryActionC2s, + InventoryS2c, OpenScreenS2c, ScreenHandlerSlotUpdateS2c, SlotChange, UpdateSelectedSlotC2s, + WindowType, +}; mod validate; diff --git a/crates/valence_inventory/src/validate.rs b/crates/valence_inventory/src/validate.rs index 614b7882b..883d4178b 100644 --- a/crates/valence_inventory/src/validate.rs +++ b/crates/valence_inventory/src/validate.rs @@ -1,8 +1,8 @@ use anyhow::{bail, ensure}; use valence_core::item::ItemStack; +use valence_packet::inventory::{ClickMode, ClickSlotC2s}; use super::{CursorItem, Inventory, InventoryWindow, PLAYER_INVENTORY_MAIN_SLOTS_COUNT}; -use valence_packet::inventory::{ClickMode, ClickSlotC2s}; /// Validates a click slot packet enforcing that all fields are valid. pub(super) fn validate_click_slot_packet( @@ -359,9 +359,9 @@ fn calculate_net_item_delta( mod tests { use valence_core::item::{ItemKind, ItemStack}; use valence_core::protocol::var_int::VarInt; + use valence_packet::inventory::SlotChange; use super::*; - use valence_packet::inventory::SlotChange; use crate::InventoryKind; #[test] diff --git a/crates/valence_network/src/connect.rs b/crates/valence_network/src/connect.rs index feb36c9e9..4da9fa5fb 100644 --- a/crates/valence_network/src/connect.rs +++ b/crates/valence_network/src/connect.rs @@ -26,13 +26,13 @@ use valence_core::protocol::var_int::VarInt; use valence_core::protocol::Decode; use valence_core::text::{Color, IntoText, Text}; use valence_core::{ident, translation_key, MINECRAFT_VERSION, PROTOCOL_VERSION}; - -use crate::legacy_ping::try_handle_legacy_ping; use valence_packet::network::{ HandshakeC2s, HandshakeNextState, LoginCompressionS2c, LoginDisconnectS2c, LoginHelloC2s, LoginHelloS2c, LoginKeyC2s, LoginQueryRequestS2c, LoginQueryResponseC2s, LoginSuccessS2c, QueryPingC2s, QueryPongS2c, QueryRequestC2s, QueryResponseS2c, }; + +use crate::legacy_ping::try_handle_legacy_ping; use crate::packet_io::PacketIo; use crate::{CleanupOnDrop, ConnectionMode, NewClientInfo, ServerListPing, SharedNetworkState}; diff --git a/crates/valence_packet/src/instance.rs b/crates/valence_packet/src/instance.rs index 5a8c4b149..d7d727863 100644 --- a/crates/valence_packet/src/instance.rs +++ b/crates/valence_packet/src/instance.rs @@ -1,4 +1,5 @@ -use valence_core::{chunk_pos::ChunkPos, protocol::array::LengthPrefixedArray}; +use valence_core::chunk_pos::ChunkPos; +use valence_core::protocol::array::LengthPrefixedArray; use super::*; diff --git a/crates/valence_packet/src/scoreboard.rs b/crates/valence_packet/src/scoreboard.rs index 94d69d0f6..4cfcf334b 100644 --- a/crates/valence_packet/src/scoreboard.rs +++ b/crates/valence_packet/src/scoreboard.rs @@ -1,342 +1,342 @@ use super::*; - #[derive(Clone, Debug, Encode, Decode, Packet)] - #[packet(id = packet_id::TEAM_S2C)] - pub struct TeamS2c<'a> { - pub team_name: &'a str, - pub mode: Mode<'a>, - } +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::TEAM_S2C)] +pub struct TeamS2c<'a> { + pub team_name: &'a str, + pub mode: Mode<'a>, +} - #[derive(Clone, PartialEq, Debug)] - pub enum Mode<'a> { - CreateTeam { - team_display_name: Cow<'a, Text>, - friendly_flags: TeamFlags, - name_tag_visibility: NameTagVisibility, - collision_rule: CollisionRule, - team_color: TeamColor, - team_prefix: Cow<'a, Text>, - team_suffix: Cow<'a, Text>, - entities: Vec<&'a str>, - }, - RemoveTeam, - UpdateTeamInfo { - team_display_name: Cow<'a, Text>, - friendly_flags: TeamFlags, - name_tag_visibility: NameTagVisibility, - collision_rule: CollisionRule, - team_color: TeamColor, - team_prefix: Cow<'a, Text>, - team_suffix: Cow<'a, Text>, - }, - AddEntities { - entities: Vec<&'a str>, - }, - RemoveEntities { - entities: Vec<&'a str>, - }, - } +#[derive(Clone, PartialEq, Debug)] +pub enum Mode<'a> { + CreateTeam { + team_display_name: Cow<'a, Text>, + friendly_flags: TeamFlags, + name_tag_visibility: NameTagVisibility, + collision_rule: CollisionRule, + team_color: TeamColor, + team_prefix: Cow<'a, Text>, + team_suffix: Cow<'a, Text>, + entities: Vec<&'a str>, + }, + RemoveTeam, + UpdateTeamInfo { + team_display_name: Cow<'a, Text>, + friendly_flags: TeamFlags, + name_tag_visibility: NameTagVisibility, + collision_rule: CollisionRule, + team_color: TeamColor, + team_prefix: Cow<'a, Text>, + team_suffix: Cow<'a, Text>, + }, + AddEntities { + entities: Vec<&'a str>, + }, + RemoveEntities { + entities: Vec<&'a str>, + }, +} - #[bitfield(u8)] - #[derive(PartialEq, Eq, Encode, Decode)] - pub struct TeamFlags { - pub friendly_fire: bool, - pub see_invisible_teammates: bool, - #[bits(6)] - _pad: u8, - } +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct TeamFlags { + pub friendly_fire: bool, + pub see_invisible_teammates: bool, + #[bits(6)] + _pad: u8, +} - #[derive(Copy, Clone, PartialEq, Eq, Debug)] - pub enum NameTagVisibility { - Always, - Never, - HideForOtherTeams, - HideForOwnTeam, - } +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum NameTagVisibility { + Always, + Never, + HideForOtherTeams, + HideForOwnTeam, +} - #[derive(Copy, Clone, PartialEq, Eq, Debug)] - pub enum CollisionRule { - Always, - Never, - PushOtherTeams, - PushOwnTeam, - } +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum CollisionRule { + Always, + Never, + PushOtherTeams, + PushOwnTeam, +} - #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] - pub enum TeamColor { - Black, - DarkBlue, - DarkGreen, - DarkCyan, - DarkRed, - Purple, - Gold, - Gray, - DarkGray, - Blue, - BrightGreen, - Cyan, - Red, - Pink, - Yellow, - White, - Obfuscated, - Bold, - Strikethrough, - Underlined, - Italic, - Reset, - } +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum TeamColor { + Black, + DarkBlue, + DarkGreen, + DarkCyan, + DarkRed, + Purple, + Gold, + Gray, + DarkGray, + Blue, + BrightGreen, + Cyan, + Red, + Pink, + Yellow, + White, + Obfuscated, + Bold, + Strikethrough, + Underlined, + Italic, + Reset, +} - impl Encode for Mode<'_> { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - match self { - Mode::CreateTeam { - team_display_name, - friendly_flags, - name_tag_visibility, - collision_rule, - team_color, - team_prefix, - team_suffix, - entities, - } => { - 0i8.encode(&mut w)?; - team_display_name.encode(&mut w)?; - friendly_flags.encode(&mut w)?; - match name_tag_visibility { - NameTagVisibility::Always => "always", - NameTagVisibility::Never => "never", - NameTagVisibility::HideForOtherTeams => "hideForOtherTeams", - NameTagVisibility::HideForOwnTeam => "hideForOwnTeam", - } - .encode(&mut w)?; - match collision_rule { - CollisionRule::Always => "always", - CollisionRule::Never => "never", - CollisionRule::PushOtherTeams => "pushOtherTeams", - CollisionRule::PushOwnTeam => "pushOwnTeam", - } - .encode(&mut w)?; - team_color.encode(&mut w)?; - team_prefix.encode(&mut w)?; - team_suffix.encode(&mut w)?; - entities.encode(&mut w)?; +impl Encode for Mode<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + match self { + Mode::CreateTeam { + team_display_name, + friendly_flags, + name_tag_visibility, + collision_rule, + team_color, + team_prefix, + team_suffix, + entities, + } => { + 0i8.encode(&mut w)?; + team_display_name.encode(&mut w)?; + friendly_flags.encode(&mut w)?; + match name_tag_visibility { + NameTagVisibility::Always => "always", + NameTagVisibility::Never => "never", + NameTagVisibility::HideForOtherTeams => "hideForOtherTeams", + NameTagVisibility::HideForOwnTeam => "hideForOwnTeam", } - Mode::RemoveTeam => 1i8.encode(&mut w)?, - Mode::UpdateTeamInfo { - team_display_name, - friendly_flags, - name_tag_visibility, - collision_rule, - team_color, - team_prefix, - team_suffix, - } => { - 2i8.encode(&mut w)?; - team_display_name.encode(&mut w)?; - friendly_flags.encode(&mut w)?; - match name_tag_visibility { - NameTagVisibility::Always => "always", - NameTagVisibility::Never => "never", - NameTagVisibility::HideForOtherTeams => "hideForOtherTeams", - NameTagVisibility::HideForOwnTeam => "hideForOwnTeam", - } - .encode(&mut w)?; - match collision_rule { - CollisionRule::Always => "always", - CollisionRule::Never => "never", - CollisionRule::PushOtherTeams => "pushOtherTeams", - CollisionRule::PushOwnTeam => "pushOwnTeam", - } - .encode(&mut w)?; - team_color.encode(&mut w)?; - team_prefix.encode(&mut w)?; - team_suffix.encode(&mut w)?; + .encode(&mut w)?; + match collision_rule { + CollisionRule::Always => "always", + CollisionRule::Never => "never", + CollisionRule::PushOtherTeams => "pushOtherTeams", + CollisionRule::PushOwnTeam => "pushOwnTeam", } - Mode::AddEntities { entities } => { - 3i8.encode(&mut w)?; - entities.encode(&mut w)?; + .encode(&mut w)?; + team_color.encode(&mut w)?; + team_prefix.encode(&mut w)?; + team_suffix.encode(&mut w)?; + entities.encode(&mut w)?; + } + Mode::RemoveTeam => 1i8.encode(&mut w)?, + Mode::UpdateTeamInfo { + team_display_name, + friendly_flags, + name_tag_visibility, + collision_rule, + team_color, + team_prefix, + team_suffix, + } => { + 2i8.encode(&mut w)?; + team_display_name.encode(&mut w)?; + friendly_flags.encode(&mut w)?; + match name_tag_visibility { + NameTagVisibility::Always => "always", + NameTagVisibility::Never => "never", + NameTagVisibility::HideForOtherTeams => "hideForOtherTeams", + NameTagVisibility::HideForOwnTeam => "hideForOwnTeam", } - Mode::RemoveEntities { entities } => { - 4i8.encode(&mut w)?; - entities.encode(&mut w)?; + .encode(&mut w)?; + match collision_rule { + CollisionRule::Always => "always", + CollisionRule::Never => "never", + CollisionRule::PushOtherTeams => "pushOtherTeams", + CollisionRule::PushOwnTeam => "pushOwnTeam", } + .encode(&mut w)?; + team_color.encode(&mut w)?; + team_prefix.encode(&mut w)?; + team_suffix.encode(&mut w)?; + } + Mode::AddEntities { entities } => { + 3i8.encode(&mut w)?; + entities.encode(&mut w)?; + } + Mode::RemoveEntities { entities } => { + 4i8.encode(&mut w)?; + entities.encode(&mut w)?; } - Ok(()) } + Ok(()) } +} - impl<'a> Decode<'a> for Mode<'a> { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - Ok(match i8::decode(r)? { - 0 => Self::CreateTeam { - team_display_name: Decode::decode(r)?, - friendly_flags: Decode::decode(r)?, - name_tag_visibility: match <&str>::decode(r)? { - "always" => NameTagVisibility::Always, - "never" => NameTagVisibility::Never, - "hideForOtherTeams" => NameTagVisibility::HideForOtherTeams, - "hideForOwnTeam" => NameTagVisibility::HideForOwnTeam, - other => bail!("unknown name tag visibility type \"{other}\""), - }, - collision_rule: match <&str>::decode(r)? { - "always" => CollisionRule::Always, - "never" => CollisionRule::Never, - "pushOtherTeams" => CollisionRule::PushOtherTeams, - "pushOwnTeam" => CollisionRule::PushOwnTeam, - other => bail!("unknown collision rule type \"{other}\""), - }, - team_color: Decode::decode(r)?, - team_prefix: Decode::decode(r)?, - team_suffix: Decode::decode(r)?, - entities: Decode::decode(r)?, +impl<'a> Decode<'a> for Mode<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + Ok(match i8::decode(r)? { + 0 => Self::CreateTeam { + team_display_name: Decode::decode(r)?, + friendly_flags: Decode::decode(r)?, + name_tag_visibility: match <&str>::decode(r)? { + "always" => NameTagVisibility::Always, + "never" => NameTagVisibility::Never, + "hideForOtherTeams" => NameTagVisibility::HideForOtherTeams, + "hideForOwnTeam" => NameTagVisibility::HideForOwnTeam, + other => bail!("unknown name tag visibility type \"{other}\""), }, - 1 => Self::RemoveTeam, - 2 => Self::UpdateTeamInfo { - team_display_name: Decode::decode(r)?, - friendly_flags: Decode::decode(r)?, - name_tag_visibility: match <&str>::decode(r)? { - "always" => NameTagVisibility::Always, - "never" => NameTagVisibility::Never, - "hideForOtherTeams" => NameTagVisibility::HideForOtherTeams, - "hideForOwnTeam" => NameTagVisibility::HideForOwnTeam, - other => bail!("unknown name tag visibility type \"{other}\""), - }, - collision_rule: match <&str>::decode(r)? { - "always" => CollisionRule::Always, - "never" => CollisionRule::Never, - "pushOtherTeams" => CollisionRule::PushOtherTeams, - "pushOwnTeam" => CollisionRule::PushOwnTeam, - other => bail!("unknown collision rule type \"{other}\""), - }, - team_color: Decode::decode(r)?, - team_prefix: Decode::decode(r)?, - team_suffix: Decode::decode(r)?, + collision_rule: match <&str>::decode(r)? { + "always" => CollisionRule::Always, + "never" => CollisionRule::Never, + "pushOtherTeams" => CollisionRule::PushOtherTeams, + "pushOwnTeam" => CollisionRule::PushOwnTeam, + other => bail!("unknown collision rule type \"{other}\""), }, - 3 => Self::AddEntities { - entities: Decode::decode(r)?, + team_color: Decode::decode(r)?, + team_prefix: Decode::decode(r)?, + team_suffix: Decode::decode(r)?, + entities: Decode::decode(r)?, + }, + 1 => Self::RemoveTeam, + 2 => Self::UpdateTeamInfo { + team_display_name: Decode::decode(r)?, + friendly_flags: Decode::decode(r)?, + name_tag_visibility: match <&str>::decode(r)? { + "always" => NameTagVisibility::Always, + "never" => NameTagVisibility::Never, + "hideForOtherTeams" => NameTagVisibility::HideForOtherTeams, + "hideForOwnTeam" => NameTagVisibility::HideForOwnTeam, + other => bail!("unknown name tag visibility type \"{other}\""), }, - 4 => Self::RemoveEntities { - entities: Decode::decode(r)?, + collision_rule: match <&str>::decode(r)? { + "always" => CollisionRule::Always, + "never" => CollisionRule::Never, + "pushOtherTeams" => CollisionRule::PushOtherTeams, + "pushOwnTeam" => CollisionRule::PushOwnTeam, + other => bail!("unknown collision rule type \"{other}\""), }, - n => bail!("unknown update teams action of {n}"), - }) - } + team_color: Decode::decode(r)?, + team_prefix: Decode::decode(r)?, + team_suffix: Decode::decode(r)?, + }, + 3 => Self::AddEntities { + entities: Decode::decode(r)?, + }, + 4 => Self::RemoveEntities { + entities: Decode::decode(r)?, + }, + n => bail!("unknown update teams action of {n}"), + }) } +} - #[derive(Copy, Clone, Debug, Encode, Decode, Packet)] - #[packet(id = packet_id::SCOREBOARD_DISPLAY_S2C)] - pub struct ScoreboardDisplayS2c<'a> { - pub position: ScoreboardPosition, - pub score_name: &'a str, - } +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SCOREBOARD_DISPLAY_S2C)] +pub struct ScoreboardDisplayS2c<'a> { + pub position: ScoreboardPosition, + pub score_name: &'a str, +} - #[derive(Copy, Clone, PartialEq, Debug)] - pub enum ScoreboardPosition { - List, - Sidebar, - BelowName, - SidebarTeam(TeamColor), - } +#[derive(Copy, Clone, PartialEq, Debug)] +pub enum ScoreboardPosition { + List, + Sidebar, + BelowName, + SidebarTeam(TeamColor), +} - impl Encode for ScoreboardPosition { - fn encode(&self, w: impl std::io::Write) -> anyhow::Result<()> { - match self { - ScoreboardPosition::List => 0u8.encode(w), - ScoreboardPosition::Sidebar => 1u8.encode(w), - ScoreboardPosition::BelowName => 2u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Black) => 3u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::DarkBlue) => 4u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::DarkGreen) => 5u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::DarkCyan) => 6u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::DarkRed) => 7u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Purple) => 8u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Gold) => 9u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Gray) => 10u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::DarkGray) => 11u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Blue) => 12u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::BrightGreen) => 13u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Cyan) => 14u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Red) => 15u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Pink) => 16u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Yellow) => 17u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::White) => 18u8.encode(w), - ScoreboardPosition::SidebarTeam(_) => { - Err(anyhow::anyhow!("Invalid scoreboard display position")) - } +impl Encode for ScoreboardPosition { + fn encode(&self, w: impl std::io::Write) -> anyhow::Result<()> { + match self { + ScoreboardPosition::List => 0u8.encode(w), + ScoreboardPosition::Sidebar => 1u8.encode(w), + ScoreboardPosition::BelowName => 2u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Black) => 3u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::DarkBlue) => 4u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::DarkGreen) => 5u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::DarkCyan) => 6u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::DarkRed) => 7u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Purple) => 8u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Gold) => 9u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Gray) => 10u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::DarkGray) => 11u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Blue) => 12u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::BrightGreen) => 13u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Cyan) => 14u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Red) => 15u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Pink) => 16u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Yellow) => 17u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::White) => 18u8.encode(w), + ScoreboardPosition::SidebarTeam(_) => { + Err(anyhow::anyhow!("Invalid scoreboard display position")) } } } +} - impl<'a> Decode<'a> for ScoreboardPosition { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - let value = u8::decode(r)?; - match value { - 0 => Ok(ScoreboardPosition::List), - 1 => Ok(ScoreboardPosition::Sidebar), - 2 => Ok(ScoreboardPosition::BelowName), - 3 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Black)), - 4 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkBlue)), - 5 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkGreen)), - 6 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkCyan)), - 7 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkRed)), - 8 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Purple)), - 9 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Gold)), - 10 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Gray)), - 11 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkGray)), - 12 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Blue)), - 13 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::BrightGreen)), - 14 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Cyan)), - 15 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Red)), - 16 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Pink)), - 17 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Yellow)), - 18 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::White)), - _ => Err(anyhow::anyhow!("Invalid scoreboard display position")), - } +impl<'a> Decode<'a> for ScoreboardPosition { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let value = u8::decode(r)?; + match value { + 0 => Ok(ScoreboardPosition::List), + 1 => Ok(ScoreboardPosition::Sidebar), + 2 => Ok(ScoreboardPosition::BelowName), + 3 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Black)), + 4 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkBlue)), + 5 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkGreen)), + 6 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkCyan)), + 7 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkRed)), + 8 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Purple)), + 9 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Gold)), + 10 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Gray)), + 11 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkGray)), + 12 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Blue)), + 13 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::BrightGreen)), + 14 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Cyan)), + 15 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Red)), + 16 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Pink)), + 17 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Yellow)), + 18 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::White)), + _ => Err(anyhow::anyhow!("Invalid scoreboard display position")), } } +} - #[derive(Clone, Debug, Encode, Decode, Packet)] - #[packet(id = packet_id::SCOREBOARD_OBJECTIVE_UPDATE_S2C)] - pub struct ScoreboardObjectiveUpdateS2c<'a> { - pub objective_name: &'a str, - pub mode: ObjectiveMode, - } +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SCOREBOARD_OBJECTIVE_UPDATE_S2C)] +pub struct ScoreboardObjectiveUpdateS2c<'a> { + pub objective_name: &'a str, + pub mode: ObjectiveMode, +} - #[derive(Clone, PartialEq, Debug, Encode, Decode)] - pub enum ObjectiveMode { - Create { - objective_display_name: Text, - render_type: ObjectiveRenderType, - }, - Remove, - Update { - objective_display_name: Text, - render_type: ObjectiveRenderType, - }, - } +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub enum ObjectiveMode { + Create { + objective_display_name: Text, + render_type: ObjectiveRenderType, + }, + Remove, + Update { + objective_display_name: Text, + render_type: ObjectiveRenderType, + }, +} - #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] - pub enum ObjectiveRenderType { - Integer, - Hearts, - } +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum ObjectiveRenderType { + Integer, + Hearts, +} - #[derive(Clone, Debug, Encode, Decode, Packet)] - #[packet(id = packet_id::SCOREBOARD_PLAYER_UPDATE_S2C)] - pub struct ScoreboardPlayerUpdateS2c<'a> { - pub entity_name: &'a str, - pub action: ScoreboardPlayerUpdateAction<'a>, - } +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SCOREBOARD_PLAYER_UPDATE_S2C)] +pub struct ScoreboardPlayerUpdateS2c<'a> { + pub entity_name: &'a str, + pub action: ScoreboardPlayerUpdateAction<'a>, +} - #[derive(Clone, PartialEq, Debug, Encode, Decode)] - pub enum ScoreboardPlayerUpdateAction<'a> { - Update { - objective_name: &'a str, - objective_score: VarInt, - }, - Remove { - objective_name: &'a str, - }, - } \ No newline at end of file +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub enum ScoreboardPlayerUpdateAction<'a> { + Update { + objective_name: &'a str, + objective_score: VarInt, + }, + Remove { + objective_name: &'a str, + }, +} diff --git a/crates/valence_player_list/src/lib.rs b/crates/valence_player_list/src/lib.rs index cef147b65..74df598fc 100644 --- a/crates/valence_player_list/src/lib.rs +++ b/crates/valence_player_list/src/lib.rs @@ -32,7 +32,7 @@ use valence_core::uuid::UniqueId; use valence_core::Server; use valence_instance::WriteUpdatePacketsToInstancesSet; use valence_packet::player_list::{ - PlayerListActions, PlayerListHeaderS2c, PlayerListS2c, PlayerRemoveS2c, PlayerListEntryPkt, + PlayerListActions, PlayerListEntryPkt, PlayerListHeaderS2c, PlayerListS2c, PlayerRemoveS2c, }; pub struct PlayerListPlugin; diff --git a/crates/valence_world_border/src/lib.rs b/crates/valence_world_border/src/lib.rs index 66afdb057..c5258e364 100644 --- a/crates/valence_world_border/src/lib.rs +++ b/crates/valence_world_border/src/lib.rs @@ -77,13 +77,13 @@ use std::time::{Duration, Instant}; use bevy_app::prelude::*; use glam::DVec2; -use valence_packet::world_border::*; use valence_client::{Client, FlushPacketsSet}; use valence_core::protocol::encode::WritePacket; use valence_core::protocol::var_int::VarInt; use valence_core::protocol::var_long::VarLong; use valence_entity::Location; use valence_instance::{Instance, WriteUpdatePacketsToInstancesSet}; +use valence_packet::world_border::*; use valence_registry::*; // https://minecraft.fandom.com/wiki/World_border diff --git a/src/lib.rs b/src/lib.rs index a69861c8b..f0a297bf0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,7 +36,6 @@ pub use valence_anvil as anvil; #[cfg(feature = "boss_bar")] pub use valence_boss_bar as boss_bar; pub use valence_core::*; -pub use valence_packet as packet; #[cfg(feature = "inventory")] pub use valence_inventory as inventory; #[cfg(feature = "network")] @@ -48,7 +47,8 @@ pub use valence_world_border as world_border; pub use { bevy_app as app, bevy_ecs as ecs, glam, valence_biome as biome, valence_block as block, valence_client as client, valence_dimension as dimension, valence_entity as entity, - valence_instance as instance, valence_nbt as nbt, valence_registry as registry, + valence_instance as instance, valence_nbt as nbt, valence_packet as packet, + valence_registry as registry, }; /// Contains the most frequently used items in Valence projects. diff --git a/src/tests/client.rs b/src/tests/client.rs index 0a7d5bd71..57a5a52bb 100644 --- a/src/tests/client.rs +++ b/src/tests/client.rs @@ -10,11 +10,11 @@ use valence_client::ViewDistance; use valence_core::chunk_pos::{ChunkPos, ChunkView}; use valence_core::protocol::Packet; use valence_entity::cow::CowEntityBundle; -use valence_packet::entity::{EntitiesDestroyS2c, EntitySpawnS2c, MoveRelativeS2c}; use valence_entity::{Location, Position}; use valence_instance::chunk::UnloadedChunk; -use valence_packet::instance::{ChunkDataS2c, UnloadChunkS2c}; use valence_instance::Instance; +use valence_packet::entity::{EntitiesDestroyS2c, EntitySpawnS2c, MoveRelativeS2c}; +use valence_packet::instance::{ChunkDataS2c, UnloadChunkS2c}; use crate::testing::{create_mock_client, scenario_single_client}; diff --git a/src/tests/example.rs b/src/tests/example.rs index 7bca4085c..d4f603258 100644 --- a/src/tests/example.rs +++ b/src/tests/example.rs @@ -11,8 +11,8 @@ use valence_client::movement::PositionAndOnGroundC2s; use valence_client::Client; use valence_core::Server; use valence_entity::Position; -use valence_packet::inventory::{InventoryS2c, OpenScreenS2c}; use valence_inventory::{Inventory, InventoryKind, OpenInventory}; +use valence_packet::inventory::{InventoryS2c, OpenScreenS2c}; use crate::testing::scenario_single_client; use crate::DefaultPlugins; diff --git a/src/tests/instance.rs b/src/tests/instance.rs index a2a86e23f..87fe4cb33 100644 --- a/src/tests/instance.rs +++ b/src/tests/instance.rs @@ -2,8 +2,8 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use valence_block::BlockState; use valence_instance::chunk::UnloadedChunk; -use valence_packet::instance::{BlockEntityUpdateS2c, ChunkDeltaUpdateS2c}; use valence_instance::Instance; +use valence_packet::instance::{BlockEntityUpdateS2c, ChunkDeltaUpdateS2c}; use crate::testing::scenario_single_client; diff --git a/src/tests/inventory.rs b/src/tests/inventory.rs index 43c754ceb..97f5b0853 100644 --- a/src/tests/inventory.rs +++ b/src/tests/inventory.rs @@ -3,14 +3,14 @@ use bevy_ecs::prelude::*; use valence_core::game_mode::GameMode; use valence_core::item::{ItemKind, ItemStack}; use valence_core::protocol::var_int::VarInt; -use valence_packet::inventory::{ - ClickMode, ClickSlotC2s, CloseScreenS2c, CreativeInventoryActionC2s, InventoryS2c, - OpenScreenS2c, ScreenHandlerSlotUpdateS2c, SlotChange, UpdateSelectedSlotC2s, -}; use valence_inventory::{ convert_to_player_slot_id, ClientInventoryState, CursorItem, DropItemStackEvent, HeldItem, Inventory, InventoryKind, OpenInventory, }; +use valence_packet::inventory::{ + ClickMode, ClickSlotC2s, CloseScreenS2c, CreativeInventoryActionC2s, InventoryS2c, + OpenScreenS2c, ScreenHandlerSlotUpdateS2c, SlotChange, UpdateSelectedSlotC2s, +}; use crate::testing::scenario_single_client; @@ -517,10 +517,10 @@ fn should_not_increment_state_id_on_cursor_item_change() { } mod dropping_items { - use valence_packet::client::{PlayerAction, PlayerActionC2s}; use valence_core::block_pos::BlockPos; use valence_core::direction::Direction; use valence_inventory::convert_to_player_slot_id; + use valence_packet::client::{PlayerAction, PlayerActionC2s}; use super::*; diff --git a/src/tests/player_list.rs b/src/tests/player_list.rs index 67ae34e9e..6b1fb7862 100644 --- a/src/tests/player_list.rs +++ b/src/tests/player_list.rs @@ -1,8 +1,8 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use valence_packet::client::PlayerSpawnS2c; use valence_instance::chunk::UnloadedChunk; use valence_instance::Instance; +use valence_packet::client::PlayerSpawnS2c; use valence_packet::player_list::PlayerListS2c; use crate::testing::{create_mock_client, scenario_single_client}; diff --git a/src/tests/weather.rs b/src/tests/weather.rs index 1f4fb712a..67dc149da 100644 --- a/src/tests/weather.rs +++ b/src/tests/weather.rs @@ -1,8 +1,8 @@ use bevy_app::App; -use valence_packet::client::GameStateChangeS2c; use valence_client::weather::{Rain, Thunder}; use valence_client::Client; use valence_instance::Instance; +use valence_packet::client::GameStateChangeS2c; use crate::testing::{scenario_single_client, PacketFrames}; diff --git a/src/tests/world_border.rs b/src/tests/world_border.rs index a2840faec..9df1a5e86 100644 --- a/src/tests/world_border.rs +++ b/src/tests/world_border.rs @@ -3,8 +3,8 @@ use std::time::Duration; use bevy_app::App; use valence_entity::Location; use valence_instance::Instance; -use valence_registry::{Entity, Mut}; use valence_packet::world_border::*; +use valence_registry::{Entity, Mut}; use valence_world_border::*; use crate::testing::{create_mock_client, scenario_single_client, MockClientHelper}; From 7f370b845afea6bc4e8929970196bca120c74ca2 Mon Sep 17 00:00:00 2001 From: Bafbi Date: Mon, 31 Jul 2023 13:25:56 +0200 Subject: [PATCH 4/9] update packet_inspector import + doc --- crates/valence_entity/src/lib.rs | 6 ++-- tools/packet_inspector/src/app/text_viewer.rs | 32 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/crates/valence_entity/src/lib.rs b/crates/valence_entity/src/lib.rs index 9d2aed9f0..243d16bb1 100644 --- a/crates/valence_entity/src/lib.rs +++ b/crates/valence_entity/src/lib.rs @@ -413,7 +413,7 @@ pub struct PacketByteRange(pub Range); /// Cache for all the tracked data of an entity. Used for the /// [`EntityTrackerUpdateS2c`][packet] packet. /// -/// [packet]: crate::packet::EntityTrackerUpdateS2c +/// [packet]: valence_packet::entity::EntityTrackerUpdateS2c #[derive(Component, Default, Debug)] pub struct TrackedData { init_data: Vec, @@ -428,7 +428,7 @@ impl TrackedData { /// [`EntityTrackerUpdateS2c`][packet] packet. This is used when the entity /// enters the view of a client. /// - /// [packet]: crate::packet::EntityTrackerUpdateS2c + /// [packet]: valence_packet::entity::EntityTrackerUpdateS2c pub fn init_data(&self) -> Option<&[u8]> { if self.init_data.len() > 1 { Some(&self.init_data) @@ -441,7 +441,7 @@ impl TrackedData { /// [`EntityTrackerUpdateS2c`][packet] packet. This is used when tracked /// data is changed and the client is already in view of the entity. /// - /// [packet]: crate::packet::EntityTrackerUpdateS2c + /// [packet]: valence_packet::entity::EntityTrackerUpdateS2c pub fn update_data(&self) -> Option<&[u8]> { if self.update_data.len() > 1 { Some(&self.update_data) diff --git a/tools/packet_inspector/src/app/text_viewer.rs b/tools/packet_inspector/src/app/text_viewer.rs index 6da07d594..9a4f275aa 100644 --- a/tools/packet_inspector/src/app/text_viewer.rs +++ b/tools/packet_inspector/src/app/text_viewer.rs @@ -5,8 +5,8 @@ mod utils { use packet_inspector::{PacketSide, PacketState}; use valence::protocol::{Decode, Packet}; - use valence::advancement::packet::*; - use valence::boss_bar::packet::*; + use valence::packet::advancement::*; + use valence::packet::boss_bar::*; use valence::client::action::*; use valence::client::command::*; use valence::client::custom_payload::*; @@ -16,27 +16,27 @@ mod utils { use valence::client::interact_item::*; use valence::client::keepalive::*; use valence::client::movement::*; - use valence::client::packet::structure_block::*; - use valence::client::packet::*; + use valence::packet::client::structure_block::*; + use valence::packet::client::*; use valence::client::resource_pack::*; use valence::client::settings::*; use valence::client::status::*; use valence::client::teleport::*; use valence::client::title::*; - use valence::entity::packet::*; - use valence::instance::packet::*; - use valence::inventory::packet::synchronize_recipes::*; - use valence::inventory::packet::*; - use valence::network::packet::*; + use valence::packet::entity::*; + use valence::packet::instance::*; + use valence::packet::inventory::synchronize_recipes::*; + use valence::packet::inventory::*; + use valence::packet::network::*; use valence::particle::*; - use valence::player_list::packet::*; - use valence::protocol::packet::chat::*; - use valence::protocol::packet::command::*; - use valence::protocol::packet::map::*; - use valence::protocol::packet::scoreboard::*; - use valence::protocol::packet::sound::*; + use valence::packet::player_list::*; + use valence::packet::chat::*; + use valence::packet::command::*; + use valence::packet::map::*; + use valence::packet::scoreboard::*; + use valence::packet::sound::*; use valence::registry::tags::*; - use valence::world_border::packet::*; + use valence::packet::world_border::*; include!(concat!(env!("OUT_DIR"), "/packet_to_string.rs")); } From e37dcba12b3dced96c607df3cbb21a22f1768e3c Mon Sep 17 00:00:00 2001 From: Bafbi Date: Tue, 1 Aug 2023 14:36:16 +0200 Subject: [PATCH 5/9] reorganise all packets --- crates/valence_packet/Cargo.toml | 1 + crates/valence_packet/README.md | 8 +- crates/valence_packet/src/client.rs | 15 + crates/valence_packet/src/entity.rs | 9 + crates/valence_packet/src/lib.rs | 1 + crates/valence_packet/src/packets.rs | 16 + .../src/packets/handshaking/handshake_c2s.rs | 18 + .../src/packets/handshaking/mod.rs | 5 + .../packets/login/login_compression_s2c.rs | 9 + .../src/packets/login/login_disconnect_s2c.rs | 7 + .../src/packets/login/login_hello_c2s.rs | 8 + .../src/packets/login/login_hello_s2c.rs | 9 + .../src/packets/login/login_key_c2s.rs | 8 + .../packets/login/login_query_request_s2c.rs | 9 + .../packets/login/login_query_response_c2s.rs | 8 + .../src/packets/login/login_success_s2c.rs | 9 + .../valence_packet/src/packets/login/mod.rs | 12 + .../src/packets/play/advancement_tab_c2s.rs | 8 + .../packets/play/advancement_update_s2c.rs | 80 ++++ .../play/block_breaking_progress_s2c.rs | 9 + .../packets/play/block_entity_update_s2c.rs | 9 + .../src/packets/play/block_event_s2c.rs | 10 + .../src/packets/play/block_update_s2c.rs | 8 + .../src/packets/play/boat_paddle_state_c2s.rs | 8 + .../src/packets/play/book_update_c2s.rs | 9 + .../src/packets/play/boss_bar_s2c.rs | 26 ++ .../src/packets/play/bundle_splitter.rs | 5 + .../src/packets/play/button_click_c2s.rs | 8 + .../src/packets/play/chat_message_c2s.rs | 15 + .../src/packets/play/chat_message_s2c.rs | 129 ++++++ .../src/packets/play/chat_suggestions_s2c.rs | 15 + .../src/packets/play/chunk_biome_data_s2c.rs | 14 + .../src/packets/play/chunk_data_s2c.rs | 26 ++ .../packets/play/chunk_delta_update_s2c.rs | 8 + .../packets/play/chunk_load_distance_s2c.rs | 7 + .../play/chunk_render_distance_center_s2c.rs | 8 + .../src/packets/play/clear_title_s2c.rs | 7 + .../src/packets/play/click_slot_c2s.rs | 32 ++ .../src/packets/play/client_command_c2s.rs | 22 + .../src/packets/play/client_settings_c2s.rs | 42 ++ .../src/packets/play/client_status_c2s.rs | 8 + .../packets/play/close_handled_screen_c2s.rs | 7 + .../src/packets/play/close_screen_s2c.rs | 8 + .../src/packets/play/command_execution_c2s.rs | 21 + .../packets/play/command_suggestions_s2c.rs | 16 + .../src/packets/play/command_tree_s2c.rs | 434 +++++++++++++++++ .../src/packets/play/cooldown_update_s2c.rs | 8 + .../packets/play/craft_failed_response_s2c.rs | 8 + .../src/packets/play/craft_request_c2s.rs | 9 + .../play/creative_inventory_action_c2s.rs | 8 + .../src/packets/play/custom_payload_c2s.rs | 8 + .../src/packets/play/custom_payload_s2c.rs | 8 + .../src/packets/play/damage_tilt_s2c.rs | 10 + .../src/packets/play/death_message_s2c.rs | 8 + .../src/packets/play/difficulty_s2c.rs | 8 + .../src/packets/play/disconnect_s2c.rs | 7 + .../src/packets/play/end_combat_s2c.rs | 8 + .../src/packets/play/enter_combat_s2c.rs | 6 + .../src/packets/play/entities_destroy_s2c.rs | 7 + .../src/packets/play/entity_animation_s2c.rs | 8 + .../src/packets/play/entity_attach_s2c.rs | 8 + .../src/packets/play/entity_attributes_s2c.rs | 22 + .../src/packets/play/entity_damage_s2c.rs | 23 + .../play/entity_equipment_update_s2c.rs | 57 +++ .../packets/play/entity_passengers_set_s2c.rs | 9 + .../src/packets/play/entity_position_s2c.rs | 11 + .../packets/play/entity_set_head_yaw_s2c.rs | 8 + .../src/packets/play/entity_spawn_s2c.rs | 18 + .../packets/play/entity_status_effect_s2c.rs | 22 + .../src/packets/play/entity_status_s2c.rs | 8 + .../packets/play/entity_tracker_update_s2c.rs | 8 + .../play/entity_velocity_update_s2c.rs | 8 + .../packets/play/experience_bar_update_s2c.rs | 9 + .../packets/play/experience_orb_spawn_s2c.rs | 13 + .../src/packets/play/explosion_s2c.rs | 9 + .../src/packets/play/features_s2c.rs | 7 + .../valence_packet/src/packets/play/full.rs | 10 + .../src/packets/play/game_join_s2c.rs | 25 + .../src/packets/play/game_message_s2c.rs | 9 + .../src/packets/play/game_state_change_s2c.rs | 24 + .../src/packets/play/hand_swing_c2s.rs | 7 + .../src/packets/play/health_update_s2c.rs | 9 + .../src/packets/play/inventory_s2c.rs | 10 + .../packets/play/item_pickup_animation_s2c.rs | 9 + .../src/packets/play/jigsaw_generating_c2s.rs | 9 + .../src/packets/play/keep_alive_c2s.rs | 7 + .../src/packets/play/keep_alive_s2c.rs | 7 + .../src/packets/play/light_update_s2c.rs | 16 + .../src/packets/play/look_and_on_ground.rs | 9 + .../src/packets/play/look_at_s2c.rs | 22 + .../src/packets/play/map_update_s2c.rs | 109 +++++ .../play/message_acknowledgment_c2s.rs | 8 + crates/valence_packet/src/packets/play/mod.rs | 179 +++++++ .../src/packets/play/move_relative.rs | 9 + .../packets/play/nbt_query_response_s2c.rs | 8 + .../src/packets/play/on_ground_only.rs | 7 + .../src/packets/play/open_horse_screen_s2c.rs | 9 + .../src/packets/play/open_screen_s2c.rs | 37 ++ .../src/packets/play/open_written_book_s2c.rs | 7 + .../src/packets/play/overlay_message_s2c.rs | 7 + .../src/packets/play/particle_s2c.rs | 437 ++++++++++++++++++ .../packets/play/pick_from_inventory_c2s.rs | 7 + .../src/packets/play/play_ping_s2c.rs | 7 + .../src/packets/play/play_pong_c2s.rs | 7 + .../play/play_sound_from_entity_s2c.rs | 14 + .../src/packets/play/play_sound_s2c.rs | 14 + .../src/packets/play/player_abilities_s2c.rs | 20 + .../src/packets/play/player_action_c2s.rs | 21 + .../play/player_action_response_s2c.rs | 7 + .../src/packets/play/player_input_c2s.rs | 18 + .../packets/play/player_interact_block_c2s.rs | 12 + .../play/player_interact_entity_c2s.rs | 16 + .../packets/play/player_interact_item_c2s.rs | 8 + .../packets/play/player_list_header_s2c.rs | 8 + .../src/packets/play/player_list_s2c.rs | 128 +++++ .../packets/play/player_position_look_s2c.rs | 23 + .../src/packets/play/player_remove_s2c.rs | 7 + .../src/packets/play/player_respawn_s2c.rs | 16 + .../src/packets/play/player_session_c2s.rs | 11 + .../packets/play/player_spawn_position_s2c.rs | 8 + .../src/packets/play/player_spawn_s2c.rs | 25 + .../packets/play/position_and_on_ground.rs | 8 + .../play/profileless_chat_message_s2c.rs | 10 + .../src/packets/play/query_block_nbt_c2s.rs | 8 + .../src/packets/play/query_entity_nbt_c2s.rs | 8 + .../src/packets/play/recipe_book_data_c2s.rs | 7 + .../play/recipe_category_options_c2s.rs | 17 + .../play/remove_entity_status_effect_s2c.rs | 8 + .../src/packets/play/remove_message_s2c.rs | 8 + .../src/packets/play/rename_item_c2s.rs | 7 + .../play/request_command_completions_c2s.rs | 8 + .../packets/play/resource_pack_send_s2c.rs | 10 + .../packets/play/resource_pack_status_c2s.rs | 14 + .../valence_packet/src/packets/play/rotate.rs | 10 + .../packets/play/rotate_and_move_relative.rs | 11 + .../packets/play/scoreboard_display_s2c.rs | 74 +++ .../play/scoreboard_objective_update_s2c.rs | 27 ++ .../play/scoreboard_player_update_s2c.rs | 19 + .../screen_handler_property_update_s2c.rs | 9 + .../play/screen_handler_slot_update_s2c.rs | 10 + .../play/select_advancement_tab_s2c.rs | 7 + .../packets/play/select_merchant_trade_c2s.rs | 7 + .../src/packets/play/server_metadata_s2c.rs | 9 + .../src/packets/play/set_camera_entity_s2c.rs | 7 + .../src/packets/play/set_trade_offers_s2c.rs | 26 ++ .../src/packets/play/sign_editor_open_s2c.rs | 7 + .../packets/play/simulation_distance_s2c.rs | 7 + .../packets/play/spectator_teleport_c2s.rs | 7 + .../src/packets/play/statistics_s2c.rs | 14 + .../src/packets/play/stop_sound_s2c.rs | 49 ++ .../src/packets/play/subtitle_s2c.rs | 7 + .../packets/play/synchronize_recipes_s2c.rs | 8 + .../src/packets/play/synchronize_tags_s2c.rs | 9 + .../src/packets/play/team_s2c.rs | 226 +++++++++ .../src/packets/play/teleport_confirm_c2s.rs | 7 + .../src/packets/play/title_fade_s2c.rs | 9 + .../src/packets/play/title_s2c.rs | 7 + .../src/packets/play/unload_chunk_s2c.rs | 7 + .../src/packets/play/unlock_recipes_s2c.rs | 61 +++ .../src/packets/play/update_beacon_c2s.rs | 8 + .../packets/play/update_command_block_c2s.rs | 27 ++ .../play/update_command_block_minecart_c2s.rs | 9 + .../src/packets/play/update_difficulty_c2s.rs | 7 + .../play/update_difficulty_lock_c2s.rs | 7 + .../src/packets/play/update_jigsaw_c2s.rs | 12 + .../play/update_player_abilities_c2s.rs | 10 + .../packets/play/update_selected_slot_c2s.rs | 7 + .../packets/play/update_selected_slot_s2c.rs | 7 + .../src/packets/play/update_sign_c2s.rs | 9 + .../play/update_structure_block_c2s.rs | 59 +++ .../src/packets/play/vehicle_move_c2s.rs | 9 + .../src/packets/play/vehicle_move_s2c.rs | 9 + .../play/world_border_center_changed_s2c.rs | 8 + .../play/world_border_initialize_s2c.rs | 14 + .../play/world_border_interpolate_size_s2c.rs | 9 + .../play/world_border_size_changed_s2c.rs | 7 + ...world_border_warning_blocks_changed_s2c.rs | 7 + .../world_border_warning_time_changed_s2c.rs | 7 + .../src/packets/play/world_event_s2c.rs | 10 + .../src/packets/play/world_time_update_s2c.rs | 12 + .../valence_packet/src/packets/status/mod.rs | 8 + .../src/packets/status/query_ping_c2s.rs | 7 + .../src/packets/status/query_pong_s2c.rs | 7 + .../src/packets/status/query_request_c2s.rs | 5 + .../src/packets/status/query_response_s2c.rs | 7 + 185 files changed, 3910 insertions(+), 1 deletion(-) create mode 100644 crates/valence_packet/src/packets.rs create mode 100644 crates/valence_packet/src/packets/handshaking/handshake_c2s.rs create mode 100644 crates/valence_packet/src/packets/handshaking/mod.rs create mode 100644 crates/valence_packet/src/packets/login/login_compression_s2c.rs create mode 100644 crates/valence_packet/src/packets/login/login_disconnect_s2c.rs create mode 100644 crates/valence_packet/src/packets/login/login_hello_c2s.rs create mode 100644 crates/valence_packet/src/packets/login/login_hello_s2c.rs create mode 100644 crates/valence_packet/src/packets/login/login_key_c2s.rs create mode 100644 crates/valence_packet/src/packets/login/login_query_request_s2c.rs create mode 100644 crates/valence_packet/src/packets/login/login_query_response_c2s.rs create mode 100644 crates/valence_packet/src/packets/login/login_success_s2c.rs create mode 100644 crates/valence_packet/src/packets/login/mod.rs create mode 100644 crates/valence_packet/src/packets/play/advancement_tab_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/advancement_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/block_breaking_progress_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/block_entity_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/block_event_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/block_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/boat_paddle_state_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/book_update_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/boss_bar_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/bundle_splitter.rs create mode 100644 crates/valence_packet/src/packets/play/button_click_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/chat_message_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/chat_message_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/chat_suggestions_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/chunk_biome_data_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/chunk_data_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/chunk_delta_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/chunk_load_distance_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/chunk_render_distance_center_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/clear_title_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/click_slot_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/client_command_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/client_settings_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/client_status_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/close_handled_screen_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/close_screen_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/command_execution_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/command_suggestions_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/command_tree_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/cooldown_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/craft_failed_response_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/craft_request_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/creative_inventory_action_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/custom_payload_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/custom_payload_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/damage_tilt_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/death_message_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/difficulty_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/disconnect_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/end_combat_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/enter_combat_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/entities_destroy_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/entity_animation_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/entity_attach_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/entity_attributes_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/entity_damage_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/entity_equipment_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/entity_passengers_set_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/entity_position_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/entity_set_head_yaw_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/entity_spawn_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/entity_status_effect_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/entity_status_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/entity_tracker_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/entity_velocity_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/experience_bar_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/experience_orb_spawn_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/explosion_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/features_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/full.rs create mode 100644 crates/valence_packet/src/packets/play/game_join_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/game_message_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/game_state_change_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/hand_swing_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/health_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/inventory_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/item_pickup_animation_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/jigsaw_generating_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/keep_alive_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/keep_alive_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/light_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/look_and_on_ground.rs create mode 100644 crates/valence_packet/src/packets/play/look_at_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/map_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/message_acknowledgment_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/mod.rs create mode 100644 crates/valence_packet/src/packets/play/move_relative.rs create mode 100644 crates/valence_packet/src/packets/play/nbt_query_response_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/on_ground_only.rs create mode 100644 crates/valence_packet/src/packets/play/open_horse_screen_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/open_screen_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/open_written_book_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/overlay_message_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/particle_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/pick_from_inventory_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/play_ping_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/play_pong_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/play_sound_from_entity_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/play_sound_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/player_abilities_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/player_action_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/player_action_response_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/player_input_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/player_interact_block_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/player_interact_entity_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/player_interact_item_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/player_list_header_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/player_list_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/player_position_look_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/player_remove_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/player_respawn_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/player_session_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/player_spawn_position_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/player_spawn_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/position_and_on_ground.rs create mode 100644 crates/valence_packet/src/packets/play/profileless_chat_message_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/query_block_nbt_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/query_entity_nbt_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/recipe_book_data_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/recipe_category_options_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/remove_entity_status_effect_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/remove_message_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/rename_item_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/request_command_completions_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/resource_pack_send_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/resource_pack_status_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/rotate.rs create mode 100644 crates/valence_packet/src/packets/play/rotate_and_move_relative.rs create mode 100644 crates/valence_packet/src/packets/play/scoreboard_display_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/scoreboard_objective_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/scoreboard_player_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/screen_handler_property_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/screen_handler_slot_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/select_advancement_tab_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/select_merchant_trade_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/server_metadata_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/set_camera_entity_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/set_trade_offers_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/sign_editor_open_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/simulation_distance_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/spectator_teleport_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/statistics_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/stop_sound_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/subtitle_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/synchronize_recipes_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/synchronize_tags_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/team_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/teleport_confirm_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/title_fade_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/title_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/unload_chunk_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/unlock_recipes_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/update_beacon_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/update_command_block_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/update_command_block_minecart_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/update_difficulty_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/update_difficulty_lock_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/update_jigsaw_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/update_player_abilities_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/update_selected_slot_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/update_selected_slot_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/update_sign_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/update_structure_block_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/vehicle_move_c2s.rs create mode 100644 crates/valence_packet/src/packets/play/vehicle_move_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/world_border_center_changed_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/world_border_initialize_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/world_border_interpolate_size_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/world_border_size_changed_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/world_border_warning_blocks_changed_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/world_border_warning_time_changed_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/world_event_s2c.rs create mode 100644 crates/valence_packet/src/packets/play/world_time_update_s2c.rs create mode 100644 crates/valence_packet/src/packets/status/mod.rs create mode 100644 crates/valence_packet/src/packets/status/query_ping_c2s.rs create mode 100644 crates/valence_packet/src/packets/status/query_pong_s2c.rs create mode 100644 crates/valence_packet/src/packets/status/query_request_c2s.rs create mode 100644 crates/valence_packet/src/packets/status/query_response_s2c.rs diff --git a/crates/valence_packet/Cargo.toml b/crates/valence_packet/Cargo.toml index fa6a5c708..04fd5e0cf 100644 --- a/crates/valence_packet/Cargo.toml +++ b/crates/valence_packet/Cargo.toml @@ -6,6 +6,7 @@ edition.workspace = true [dependencies] valence_core.workspace = true valence_nbt.workspace = true +valence_registry.workspace = true anyhow.workspace = true bitfield-struct.workspace = true byteorder.workspace = true diff --git a/crates/valence_packet/README.md b/crates/valence_packet/README.md index f87f5c14c..c4c1c616f 100644 --- a/crates/valence_packet/README.md +++ b/crates/valence_packet/README.md @@ -1 +1,7 @@ -# TODO \ No newline at end of file +# valence_packet + +This contain all (some) the packets structures of the minecraft protocol #763. + +## Naming + +Tha naming of the struct are based on the yarn mapping name and the packet side, for that reason it can be a bit different from the [wiki.vg](https://wiki.vg) name. diff --git a/crates/valence_packet/src/client.rs b/crates/valence_packet/src/client.rs index 7a96e69ab..fa3241b6a 100644 --- a/crates/valence_packet/src/client.rs +++ b/crates/valence_packet/src/client.rs @@ -378,9 +378,24 @@ pub struct PlayerSpawnPositionS2c { pub angle: f32, } +// https://wiki.vg/Protocol#Spawn_Player +/// This packet is sent by the server when a player comes into visible range, +/// not when a player joins. +/// +/// This packet must be sent after the Player Info Update packet that adds the +/// player data for the client to use when spawning a player. If the Player Info +/// for the player spawned by this packet is not present when this packet +/// arrives, Notchian clients will not spawn the player entity. The Player Info +/// packet includes skin/cape data. +/// +/// Servers can, however, safely spawn player entities for players not in +/// visible range. The client appears to handle it correctly. +/// +/// wiki : [Spawn Player](https://wiki.vg/Protocol#Spawn_Player) #[derive(Copy, Clone, Debug, Encode, Decode, Packet)] #[packet(id = packet_id::PLAYER_SPAWN_S2C)] pub struct PlayerSpawnS2c { + /// A unique integer ID mostly used in the protocol to identify the player. pub entity_id: VarInt, pub player_uuid: Uuid, pub position: DVec3, diff --git a/crates/valence_packet/src/entity.rs b/crates/valence_packet/src/entity.rs index cf3d48163..b6e9d4668 100644 --- a/crates/valence_packet/src/entity.rs +++ b/crates/valence_packet/src/entity.rs @@ -171,6 +171,10 @@ pub struct EntitySetHeadYawS2c { pub head_yaw: ByteAngle, } +// https://wiki.vg/Protocol#Spawn_Experience_Orb +/// Sent by the server when a vehicle or other non-living entity is created. +/// +/// wiki : [Spawn Entity](https://wiki.vg/Protocol#Spawn_Experience_Orb) #[derive(Copy, Clone, Debug, Encode, Decode, Packet)] #[packet(id = packet_id::ENTITY_SPAWN_S2C)] pub struct EntitySpawnS2c { @@ -227,11 +231,16 @@ pub struct EntityVelocityUpdateS2c { pub velocity: [i16; 3], } +// https://wiki.vg/Protocol#Spawn_Experience_Orb +/// Spawns one or more experience orbs. +/// +/// wiki : [Spawn Experience Orb](https://wiki.vg/Protocol#Spawn_Experience_Orb) #[derive(Copy, Clone, Debug, Encode, Decode, Packet)] #[packet(id = packet_id::EXPERIENCE_ORB_SPAWN_S2C)] pub struct ExperienceOrbSpawnS2c { pub entity_id: VarInt, pub position: DVec3, + /// The amount of experience this orb will reward once collected. pub count: i16, } diff --git a/crates/valence_packet/src/lib.rs b/crates/valence_packet/src/lib.rs index 2e2e1d554..bf18758a4 100644 --- a/crates/valence_packet/src/lib.rs +++ b/crates/valence_packet/src/lib.rs @@ -33,6 +33,7 @@ pub mod instance; pub mod inventory; pub mod map; pub mod network; +pub mod packets; pub mod player_list; pub mod scoreboard; pub mod sound; diff --git a/crates/valence_packet/src/packets.rs b/crates/valence_packet/src/packets.rs new file mode 100644 index 000000000..32c627120 --- /dev/null +++ b/crates/valence_packet/src/packets.rs @@ -0,0 +1,16 @@ +use std::borrow::Cow; +use std::io::Write; + +use anyhow::bail; +use uuid::Uuid; +use valence_core::ident::Ident; +use valence_core::property::Property; +use valence_core::protocol::raw::RawBytes; +use valence_core::protocol::var_int::VarInt; +use valence_core::protocol::{packet_id, Decode, Encode, Packet}; +use valence_core::text::Text; + +pub mod handshaking; +pub mod login; +pub mod play; +pub mod status; diff --git a/crates/valence_packet/src/packets/handshaking/handshake_c2s.rs b/crates/valence_packet/src/packets/handshaking/handshake_c2s.rs new file mode 100644 index 000000000..ac8a65633 --- /dev/null +++ b/crates/valence_packet/src/packets/handshaking/handshake_c2s.rs @@ -0,0 +1,18 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::HANDSHAKE_C2S, state = PacketState::Handshaking)] +pub struct HandshakeC2s<'a> { + pub protocol_version: VarInt, + pub server_address: &'a str, + pub server_port: u16, + pub next_state: HandshakeNextState, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Encode, Decode)] +pub enum HandshakeNextState { + #[packet(tag = 1)] + Status, + #[packet(tag = 2)] + Login, +} diff --git a/crates/valence_packet/src/packets/handshaking/mod.rs b/crates/valence_packet/src/packets/handshaking/mod.rs new file mode 100644 index 000000000..75f7a049d --- /dev/null +++ b/crates/valence_packet/src/packets/handshaking/mod.rs @@ -0,0 +1,5 @@ +use valence_core::protocol::PacketState; + +use super::*; + +pub mod handshake_c2s; diff --git a/crates/valence_packet/src/packets/login/login_compression_s2c.rs b/crates/valence_packet/src/packets/login/login_compression_s2c.rs new file mode 100644 index 000000000..bfee7a4e6 --- /dev/null +++ b/crates/valence_packet/src/packets/login/login_compression_s2c.rs @@ -0,0 +1,9 @@ +use valence_core::protocol::PacketState; + +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::LOGIN_COMPRESSION_S2C, state = PacketState::Login)] +pub struct LoginCompressionS2c { + pub threshold: VarInt, +} diff --git a/crates/valence_packet/src/packets/login/login_disconnect_s2c.rs b/crates/valence_packet/src/packets/login/login_disconnect_s2c.rs new file mode 100644 index 000000000..13fcaf10f --- /dev/null +++ b/crates/valence_packet/src/packets/login/login_disconnect_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::LOGIN_DISCONNECT_S2C, state = PacketState::Login)] +pub struct LoginDisconnectS2c<'a> { + pub reason: Cow<'a, Text>, +} diff --git a/crates/valence_packet/src/packets/login/login_hello_c2s.rs b/crates/valence_packet/src/packets/login/login_hello_c2s.rs new file mode 100644 index 000000000..5b9500dbe --- /dev/null +++ b/crates/valence_packet/src/packets/login/login_hello_c2s.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::LOGIN_HELLO_C2S, state = PacketState::Login)] +pub struct LoginHelloC2s<'a> { + pub username: &'a str, // TODO: bound this + pub profile_id: Option, +} diff --git a/crates/valence_packet/src/packets/login/login_hello_s2c.rs b/crates/valence_packet/src/packets/login/login_hello_s2c.rs new file mode 100644 index 000000000..9df1d2bd7 --- /dev/null +++ b/crates/valence_packet/src/packets/login/login_hello_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::LOGIN_HELLO_S2C, state = PacketState::Login)] +pub struct LoginHelloS2c<'a> { + pub server_id: &'a str, + pub public_key: &'a [u8], + pub verify_token: &'a [u8], +} diff --git a/crates/valence_packet/src/packets/login/login_key_c2s.rs b/crates/valence_packet/src/packets/login/login_key_c2s.rs new file mode 100644 index 000000000..3e179cae6 --- /dev/null +++ b/crates/valence_packet/src/packets/login/login_key_c2s.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::LOGIN_KEY_C2S, state = PacketState::Login)] +pub struct LoginKeyC2s<'a> { + pub shared_secret: &'a [u8], + pub verify_token: &'a [u8], +} diff --git a/crates/valence_packet/src/packets/login/login_query_request_s2c.rs b/crates/valence_packet/src/packets/login/login_query_request_s2c.rs new file mode 100644 index 000000000..4cfcb4293 --- /dev/null +++ b/crates/valence_packet/src/packets/login/login_query_request_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::LOGIN_QUERY_REQUEST_S2C, state = PacketState::Login)] +pub struct LoginQueryRequestS2c<'a> { + pub message_id: VarInt, + pub channel: Ident>, + pub data: RawBytes<'a>, +} diff --git a/crates/valence_packet/src/packets/login/login_query_response_c2s.rs b/crates/valence_packet/src/packets/login/login_query_response_c2s.rs new file mode 100644 index 000000000..0e2423880 --- /dev/null +++ b/crates/valence_packet/src/packets/login/login_query_response_c2s.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::LOGIN_QUERY_RESPONSE_C2S, state = PacketState::Login)] +pub struct LoginQueryResponseC2s<'a> { + pub message_id: VarInt, + pub data: Option>, +} diff --git a/crates/valence_packet/src/packets/login/login_success_s2c.rs b/crates/valence_packet/src/packets/login/login_success_s2c.rs new file mode 100644 index 000000000..6eb6dfd6c --- /dev/null +++ b/crates/valence_packet/src/packets/login/login_success_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::LOGIN_SUCCESS_S2C, state = PacketState::Login)] +pub struct LoginSuccessS2c<'a> { + pub uuid: Uuid, + pub username: &'a str, // TODO: bound this. + pub properties: Cow<'a, [Property]>, +} diff --git a/crates/valence_packet/src/packets/login/mod.rs b/crates/valence_packet/src/packets/login/mod.rs new file mode 100644 index 000000000..02147b9d5 --- /dev/null +++ b/crates/valence_packet/src/packets/login/mod.rs @@ -0,0 +1,12 @@ +use valence_core::protocol::PacketState; + +use super::*; + +pub mod login_compression_s2c; +pub mod login_disconnect_s2c; +pub mod login_hello_c2s; +pub mod login_hello_s2c; +pub mod login_key_c2s; +pub mod login_query_request_s2c; +pub mod login_query_response_c2s; +pub mod login_success_s2c; diff --git a/crates/valence_packet/src/packets/play/advancement_tab_c2s.rs b/crates/valence_packet/src/packets/play/advancement_tab_c2s.rs new file mode 100644 index 000000000..fd085032d --- /dev/null +++ b/crates/valence_packet/src/packets/play/advancement_tab_c2s.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ADVANCEMENT_TAB_C2S)] +pub enum AdvancementTabC2s<'a> { + OpenedTab { tab_id: Ident> }, + ClosedScreen, +} diff --git a/crates/valence_packet/src/packets/play/advancement_update_s2c.rs b/crates/valence_packet/src/packets/play/advancement_update_s2c.rs new file mode 100644 index 000000000..24a7ca7fd --- /dev/null +++ b/crates/valence_packet/src/packets/play/advancement_update_s2c.rs @@ -0,0 +1,80 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ADVANCEMENT_UPDATE_S2C)] +pub struct GenericAdvancementUpdateS2c<'a, AM: 'a> { + pub reset: bool, + pub advancement_mapping: Vec, + pub identifiers: Vec>>, + pub progress_mapping: Vec<(Ident>, Vec>)>, +} + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub struct AdvancementCriteria<'a> { + pub criterion_identifier: Ident>, + /// If present, the criteria has been achieved at the + /// time wrapped; time represented as millis since epoch + pub criterion_progress: Option, +} + +#[derive(Clone, PartialEq, Debug)] +pub struct AdvancementDisplay<'a, I> { + pub title: Cow<'a, Text>, + pub description: Cow<'a, Text>, + pub icon: I, + pub frame_type: VarInt, + pub flags: i32, + pub background_texture: Option>>, + pub x_coord: f32, + pub y_coord: f32, +} + +impl Encode for AdvancementDisplay<'_, I> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + self.title.encode(&mut w)?; + self.description.encode(&mut w)?; + self.icon.encode(&mut w)?; + self.frame_type.encode(&mut w)?; + self.flags.encode(&mut w)?; + + match self.background_texture.as_ref() { + None => {} + Some(texture) => texture.encode(&mut w)?, + } + + self.x_coord.encode(&mut w)?; + self.y_coord.encode(&mut w)?; + + Ok(()) + } +} + +impl<'a, I: Decode<'a>> Decode<'a> for AdvancementDisplay<'a, I> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let title = >::decode(r)?; + let description = >::decode(r)?; + let icon = I::decode(r)?; + let frame_type = VarInt::decode(r)?; + let flags = i32::decode(r)?; + + let background_texture = if flags & 1 == 1 { + Some(Ident::decode(r)?) + } else { + None + }; + + let x_coord = f32::decode(r)?; + let y_coord = f32::decode(r)?; + + Ok(Self { + title, + description, + icon, + frame_type, + flags, + background_texture, + x_coord, + y_coord, + }) + } +} diff --git a/crates/valence_packet/src/packets/play/block_breaking_progress_s2c.rs b/crates/valence_packet/src/packets/play/block_breaking_progress_s2c.rs new file mode 100644 index 000000000..7f4974e4b --- /dev/null +++ b/crates/valence_packet/src/packets/play/block_breaking_progress_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::BLOCK_BREAKING_PROGRESS_S2C)] +pub struct BlockBreakingProgressS2c { + pub entity_id: VarInt, + pub position: BlockPos, + pub destroy_stage: u8, +} diff --git a/crates/valence_packet/src/packets/play/block_entity_update_s2c.rs b/crates/valence_packet/src/packets/play/block_entity_update_s2c.rs new file mode 100644 index 000000000..c2383f7d8 --- /dev/null +++ b/crates/valence_packet/src/packets/play/block_entity_update_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::BLOCK_ENTITY_UPDATE_S2C)] +pub struct BlockEntityUpdateS2c<'a> { + pub position: BlockPos, + pub kind: VarInt, + pub data: Cow<'a, Compound>, +} diff --git a/crates/valence_packet/src/packets/play/block_event_s2c.rs b/crates/valence_packet/src/packets/play/block_event_s2c.rs new file mode 100644 index 000000000..ae00e77b2 --- /dev/null +++ b/crates/valence_packet/src/packets/play/block_event_s2c.rs @@ -0,0 +1,10 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::BLOCK_EVENT_S2C)] +pub struct BlockEventS2c { + pub position: BlockPos, + pub action_id: u8, + pub action_parameter: u8, + pub block_type: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/block_update_s2c.rs b/crates/valence_packet/src/packets/play/block_update_s2c.rs new file mode 100644 index 000000000..cc244a0a2 --- /dev/null +++ b/crates/valence_packet/src/packets/play/block_update_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::BLOCK_UPDATE_S2C)] +pub struct BlockUpdateS2c { + pub position: BlockPos, + pub block_id: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/boat_paddle_state_c2s.rs b/crates/valence_packet/src/packets/play/boat_paddle_state_c2s.rs new file mode 100644 index 000000000..4135d5784 --- /dev/null +++ b/crates/valence_packet/src/packets/play/boat_paddle_state_c2s.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::BOAT_PADDLE_STATE_C2S)] +pub struct BoatPaddleStateC2s { + pub left_paddle_turning: bool, + pub right_paddle_turning: bool, +} diff --git a/crates/valence_packet/src/packets/play/book_update_c2s.rs b/crates/valence_packet/src/packets/play/book_update_c2s.rs new file mode 100644 index 000000000..538012e85 --- /dev/null +++ b/crates/valence_packet/src/packets/play/book_update_c2s.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::BOOK_UPDATE_C2S)] +pub struct BookUpdateC2s<'a> { + pub slot: VarInt, + pub entries: Vec<&'a str>, + pub title: Option<&'a str>, +} diff --git a/crates/valence_packet/src/packets/play/boss_bar_s2c.rs b/crates/valence_packet/src/packets/play/boss_bar_s2c.rs new file mode 100644 index 000000000..e427eb46d --- /dev/null +++ b/crates/valence_packet/src/packets/play/boss_bar_s2c.rs @@ -0,0 +1,26 @@ +use valence_core::boss_bar::{BossBarColor, BossBarDivision, BossBarFlags}; + +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::BOSS_BAR_S2C)] +pub struct BossBarS2c<'a> { + pub id: Uuid, + pub action: BossBarAction<'a>, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub enum BossBarAction<'a> { + Add { + title: Cow<'a, Text>, + health: f32, + color: BossBarColor, + division: BossBarDivision, + flags: BossBarFlags, + }, + Remove, + UpdateHealth(f32), + UpdateTitle(Cow<'a, Text>), + UpdateStyle(BossBarColor, BossBarDivision), + UpdateFlags(BossBarFlags), +} diff --git a/crates/valence_packet/src/packets/play/bundle_splitter.rs b/crates/valence_packet/src/packets/play/bundle_splitter.rs new file mode 100644 index 000000000..0d8f301ba --- /dev/null +++ b/crates/valence_packet/src/packets/play/bundle_splitter.rs @@ -0,0 +1,5 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::BUNDLE_SPLITTER)] +pub struct BundleSplitterS2c; diff --git a/crates/valence_packet/src/packets/play/button_click_c2s.rs b/crates/valence_packet/src/packets/play/button_click_c2s.rs new file mode 100644 index 000000000..1ed0984a5 --- /dev/null +++ b/crates/valence_packet/src/packets/play/button_click_c2s.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::BUTTON_CLICK_C2S)] +pub struct ButtonClickC2s { + pub window_id: i8, + pub button_id: i8, +} diff --git a/crates/valence_packet/src/packets/play/chat_message_c2s.rs b/crates/valence_packet/src/packets/play/chat_message_c2s.rs new file mode 100644 index 000000000..422374811 --- /dev/null +++ b/crates/valence_packet/src/packets/play/chat_message_c2s.rs @@ -0,0 +1,15 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CHAT_MESSAGE_C2S)] +pub struct ChatMessageC2s<'a> { + pub message: &'a str, + pub timestamp: u64, + pub salt: u64, + pub signature: Option<&'a [u8; 256]>, + pub message_count: VarInt, + // This is a bitset of 20; each bit represents one + // of the last 20 messages received and whether or not + // the message was acknowledged by the client + pub acknowledgement: [u8; 3], +} diff --git a/crates/valence_packet/src/packets/play/chat_message_s2c.rs b/crates/valence_packet/src/packets/play/chat_message_s2c.rs new file mode 100644 index 000000000..14c36b7b3 --- /dev/null +++ b/crates/valence_packet/src/packets/play/chat_message_s2c.rs @@ -0,0 +1,129 @@ +use super::*; + +#[derive(Clone, PartialEq, Debug, Packet)] +#[packet(id = packet_id::CHAT_MESSAGE_S2C)] +pub struct ChatMessageS2c<'a> { + pub sender: Uuid, + pub index: VarInt, + pub message_signature: Option<&'a [u8; 256]>, + pub message: &'a str, + pub time_stamp: u64, + pub salt: u64, + pub previous_messages: Vec>, + pub unsigned_content: Option>, + pub filter_type: MessageFilterType, + pub filter_type_bits: Option, + pub chat_type: VarInt, + pub network_name: Cow<'a, Text>, + pub network_target_name: Option>, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum MessageFilterType { + PassThrough, + FullyFiltered, + PartiallyFiltered, +} + +impl<'a> Encode for ChatMessageS2c<'a> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + self.sender.encode(&mut w)?; + self.index.encode(&mut w)?; + self.message_signature.encode(&mut w)?; + self.message.encode(&mut w)?; + self.time_stamp.encode(&mut w)?; + self.salt.encode(&mut w)?; + self.previous_messages.encode(&mut w)?; + self.unsigned_content.encode(&mut w)?; + self.filter_type.encode(&mut w)?; + + if self.filter_type == MessageFilterType::PartiallyFiltered { + match self.filter_type_bits { + // Filler data + None => 0u8.encode(&mut w)?, + Some(bits) => bits.encode(&mut w)?, + } + } + + self.chat_type.encode(&mut w)?; + self.network_name.encode(&mut w)?; + self.network_target_name.encode(&mut w)?; + + Ok(()) + } +} + +impl<'a> Decode<'a> for ChatMessageS2c<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let sender = Uuid::decode(r)?; + let index = VarInt::decode(r)?; + let message_signature = Option::<&'a [u8; 256]>::decode(r)?; + let message = <&str>::decode(r)?; + let time_stamp = u64::decode(r)?; + let salt = u64::decode(r)?; + let previous_messages = Vec::::decode(r)?; + let unsigned_content = Option::>::decode(r)?; + let filter_type = MessageFilterType::decode(r)?; + + let filter_type_bits = match filter_type { + MessageFilterType::PartiallyFiltered => Some(u8::decode(r)?), + _ => None, + }; + + let chat_type = VarInt::decode(r)?; + let network_name = >::decode(r)?; + let network_target_name = Option::>::decode(r)?; + + Ok(Self { + sender, + index, + message_signature, + message, + time_stamp, + salt, + previous_messages, + unsigned_content, + filter_type, + filter_type_bits, + chat_type, + network_name, + network_target_name, + }) + } +} + +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct MessageSignature<'a> { + pub message_id: i32, + pub signature: Option<&'a [u8; 256]>, +} + +impl<'a> Encode for MessageSignature<'a> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + VarInt(self.message_id + 1).encode(&mut w)?; + + match self.signature { + None => {} + Some(signature) => signature.encode(&mut w)?, + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for MessageSignature<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let message_id = VarInt::decode(r)?.0 - 1; // TODO: this can underflow. + + let signature = if message_id == -1 { + Some(<&[u8; 256]>::decode(r)?) + } else { + None + }; + + Ok(Self { + message_id, + signature, + }) + } +} diff --git a/crates/valence_packet/src/packets/play/chat_suggestions_s2c.rs b/crates/valence_packet/src/packets/play/chat_suggestions_s2c.rs new file mode 100644 index 000000000..1911d264f --- /dev/null +++ b/crates/valence_packet/src/packets/play/chat_suggestions_s2c.rs @@ -0,0 +1,15 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CHAT_SUGGESTIONS_S2C)] +pub struct ChatSuggestionsS2c<'a> { + pub action: ChatSuggestionsAction, + pub entries: Cow<'a, [&'a str]>, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum ChatSuggestionsAction { + Add, + Remove, + Set, +} diff --git a/crates/valence_packet/src/packets/play/chunk_biome_data_s2c.rs b/crates/valence_packet/src/packets/play/chunk_biome_data_s2c.rs new file mode 100644 index 000000000..8fa646b55 --- /dev/null +++ b/crates/valence_packet/src/packets/play/chunk_biome_data_s2c.rs @@ -0,0 +1,14 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CHUNK_BIOME_DATA_S2C)] +pub struct ChunkBiomeDataS2c<'a> { + pub chunks: Cow<'a, [ChunkBiome<'a>]>, +} + +#[derive(Clone, Debug, Encode, Decode)] +pub struct ChunkBiome<'a> { + pub pos: ChunkPos, + /// Chunk data structure, with sections containing only the `Biomes` field. + pub data: &'a [u8], +} diff --git a/crates/valence_packet/src/packets/play/chunk_data_s2c.rs b/crates/valence_packet/src/packets/play/chunk_data_s2c.rs new file mode 100644 index 000000000..6d7226fc2 --- /dev/null +++ b/crates/valence_packet/src/packets/play/chunk_data_s2c.rs @@ -0,0 +1,26 @@ +use valence_core::protocol::array::LengthPrefixedArray; + +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CHUNK_DATA_S2C)] +pub struct ChunkDataS2c<'a> { + pub pos: ChunkPos, + pub heightmaps: Cow<'a, Compound>, + pub blocks_and_biomes: &'a [u8], + pub block_entities: Cow<'a, [ChunkDataBlockEntity<'a>]>, + pub sky_light_mask: Cow<'a, [u64]>, + pub block_light_mask: Cow<'a, [u64]>, + pub empty_sky_light_mask: Cow<'a, [u64]>, + pub empty_block_light_mask: Cow<'a, [u64]>, + pub sky_light_arrays: Cow<'a, [LengthPrefixedArray]>, + pub block_light_arrays: Cow<'a, [LengthPrefixedArray]>, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct ChunkDataBlockEntity<'a> { + pub packed_xz: i8, + pub y: i16, + pub kind: VarInt, + pub data: Cow<'a, Compound>, +} diff --git a/crates/valence_packet/src/packets/play/chunk_delta_update_s2c.rs b/crates/valence_packet/src/packets/play/chunk_delta_update_s2c.rs new file mode 100644 index 000000000..458ea8c4d --- /dev/null +++ b/crates/valence_packet/src/packets/play/chunk_delta_update_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CHUNK_DELTA_UPDATE_S2C)] +pub struct ChunkDeltaUpdateS2c<'a> { + pub chunk_section_position: i64, + pub blocks: Cow<'a, [VarLong]>, +} diff --git a/crates/valence_packet/src/packets/play/chunk_load_distance_s2c.rs b/crates/valence_packet/src/packets/play/chunk_load_distance_s2c.rs new file mode 100644 index 000000000..c3f774656 --- /dev/null +++ b/crates/valence_packet/src/packets/play/chunk_load_distance_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CHUNK_LOAD_DISTANCE_S2C)] +pub struct ChunkLoadDistanceS2c { + pub view_distance: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/chunk_render_distance_center_s2c.rs b/crates/valence_packet/src/packets/play/chunk_render_distance_center_s2c.rs new file mode 100644 index 000000000..53cbd7684 --- /dev/null +++ b/crates/valence_packet/src/packets/play/chunk_render_distance_center_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CHUNK_RENDER_DISTANCE_CENTER_S2C)] +pub struct ChunkRenderDistanceCenterS2c { + pub chunk_x: VarInt, + pub chunk_z: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/clear_title_s2c.rs b/crates/valence_packet/src/packets/play/clear_title_s2c.rs new file mode 100644 index 000000000..85ea2fa7b --- /dev/null +++ b/crates/valence_packet/src/packets/play/clear_title_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CLEAR_TITLE_S2C)] +pub struct ClearTitleS2c { + pub reset: bool, +} diff --git a/crates/valence_packet/src/packets/play/click_slot_c2s.rs b/crates/valence_packet/src/packets/play/click_slot_c2s.rs new file mode 100644 index 000000000..29a07fc18 --- /dev/null +++ b/crates/valence_packet/src/packets/play/click_slot_c2s.rs @@ -0,0 +1,32 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CLICK_SLOT_C2S)] +pub struct ClickSlotC2s { + pub window_id: u8, + pub state_id: VarInt, + pub slot_idx: i16, + /// The button used to click the slot. An enum can't easily be used for this + /// because the meaning of this value depends on the mode. + pub button: i8, + pub mode: ClickMode, + pub slot_changes: Vec, + pub carried_item: Option, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Encode, Decode)] +pub enum ClickMode { + Click, + ShiftClick, + Hotbar, + CreativeMiddleClick, + DropKey, + Drag, + DoubleClick, +} + +#[derive(Clone, Debug, Encode, Decode)] +pub struct SlotChange { + pub idx: i16, + pub item: Option, +} diff --git a/crates/valence_packet/src/packets/play/client_command_c2s.rs b/crates/valence_packet/src/packets/play/client_command_c2s.rs new file mode 100644 index 000000000..4e4933835 --- /dev/null +++ b/crates/valence_packet/src/packets/play/client_command_c2s.rs @@ -0,0 +1,22 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CLIENT_COMMAND_C2S)] +pub struct ClientCommandC2s { + pub entity_id: VarInt, + pub action: ClientCommand, + pub jump_boost: VarInt, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum ClientCommand { + StartSneaking, + StopSneaking, + LeaveBed, + StartSprinting, + StopSprinting, + StartJumpWithHorse, + StopJumpWithHorse, + OpenHorseInventory, + StartFlyingWithElytra, +} diff --git a/crates/valence_packet/src/packets/play/client_settings_c2s.rs b/crates/valence_packet/src/packets/play/client_settings_c2s.rs new file mode 100644 index 000000000..e807c9752 --- /dev/null +++ b/crates/valence_packet/src/packets/play/client_settings_c2s.rs @@ -0,0 +1,42 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CLIENT_SETTINGS_C2S)] +pub struct ClientSettingsC2s<'a> { + pub locale: &'a str, + pub view_distance: u8, + pub chat_mode: ChatMode, + pub chat_colors: bool, + pub displayed_skin_parts: DisplayedSkinParts, + pub main_arm: MainArm, + pub enable_text_filtering: bool, + pub allow_server_listings: bool, +} + +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct DisplayedSkinParts { + pub cape: bool, + pub jacket: bool, + pub left_sleeve: bool, + pub right_sleeve: bool, + pub left_pants_leg: bool, + pub right_pants_leg: bool, + pub hat: bool, + _pad: bool, +} + +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug, Encode, Decode)] +pub enum ChatMode { + Enabled, + CommandsOnly, + #[default] + Hidden, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Default, Encode, Decode)] +pub enum MainArm { + Left, + #[default] + Right, +} diff --git a/crates/valence_packet/src/packets/play/client_status_c2s.rs b/crates/valence_packet/src/packets/play/client_status_c2s.rs new file mode 100644 index 000000000..64fae6d3b --- /dev/null +++ b/crates/valence_packet/src/packets/play/client_status_c2s.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CLIENT_STATUS_C2S)] +pub enum ClientStatusC2s { + PerformRespawn, + RequestStats, +} diff --git a/crates/valence_packet/src/packets/play/close_handled_screen_c2s.rs b/crates/valence_packet/src/packets/play/close_handled_screen_c2s.rs new file mode 100644 index 000000000..551ab979c --- /dev/null +++ b/crates/valence_packet/src/packets/play/close_handled_screen_c2s.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CLOSE_HANDLED_SCREEN_C2S)] +pub struct CloseHandledScreenC2s { + pub window_id: i8, +} diff --git a/crates/valence_packet/src/packets/play/close_screen_s2c.rs b/crates/valence_packet/src/packets/play/close_screen_s2c.rs new file mode 100644 index 000000000..36bb804b2 --- /dev/null +++ b/crates/valence_packet/src/packets/play/close_screen_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CLOSE_SCREEN_S2C)] +pub struct CloseScreenS2c { + /// Ignored by notchian clients. + pub window_id: u8, +} diff --git a/crates/valence_packet/src/packets/play/command_execution_c2s.rs b/crates/valence_packet/src/packets/play/command_execution_c2s.rs new file mode 100644 index 000000000..64975379c --- /dev/null +++ b/crates/valence_packet/src/packets/play/command_execution_c2s.rs @@ -0,0 +1,21 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::COMMAND_EXECUTION_C2S)] +pub struct CommandExecutionC2s<'a> { + pub command: &'a str, + pub timestamp: u64, + pub salt: u64, + pub argument_signatures: Vec>, + pub message_count: VarInt, + //// This is a bitset of 20; each bit represents one + //// of the last 20 messages received and whether or not + //// the message was acknowledged by the client + pub acknowledgement: [u8; 3], +} + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct CommandArgumentSignature<'a> { + pub argument_name: &'a str, + pub signature: &'a [u8; 256], +} diff --git a/crates/valence_packet/src/packets/play/command_suggestions_s2c.rs b/crates/valence_packet/src/packets/play/command_suggestions_s2c.rs new file mode 100644 index 000000000..dd3f19be9 --- /dev/null +++ b/crates/valence_packet/src/packets/play/command_suggestions_s2c.rs @@ -0,0 +1,16 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::COMMAND_SUGGESTIONS_S2C)] +pub struct CommandSuggestionsS2c<'a> { + pub id: VarInt, + pub start: VarInt, + pub length: VarInt, + pub matches: Vec>, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct CommandSuggestionsMatch<'a> { + pub suggested_match: &'a str, + pub tooltip: Option>, +} diff --git a/crates/valence_packet/src/packets/play/command_tree_s2c.rs b/crates/valence_packet/src/packets/play/command_tree_s2c.rs new file mode 100644 index 000000000..310637aad --- /dev/null +++ b/crates/valence_packet/src/packets/play/command_tree_s2c.rs @@ -0,0 +1,434 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::COMMAND_TREE_S2C)] +pub struct CommandTreeS2c<'a> { + pub commands: Vec>, + pub root_index: VarInt, +} + +#[derive(Clone, Debug)] +pub struct Node<'a> { + pub children: Vec, + pub data: NodeData<'a>, + pub executable: bool, + pub redirect_node: Option, +} + +#[derive(Clone, Debug)] +pub enum NodeData<'a> { + Root, + Literal { + name: &'a str, + }, + Argument { + name: &'a str, + parser: Parser<'a>, + suggestion: Option, + }, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum Suggestion { + AskServer, + AllRecipes, + AvailableSounds, + AvailableBiomes, + SummonableEntities, +} + +#[derive(Clone, Debug)] +pub enum Parser<'a> { + Bool, + Float { min: Option, max: Option }, + Double { min: Option, max: Option }, + Integer { min: Option, max: Option }, + Long { min: Option, max: Option }, + String(StringArg), + Entity { single: bool, only_players: bool }, + GameProfile, + BlockPos, + ColumnPos, + Vec3, + Vec2, + BlockState, + BlockPredicate, + ItemStack, + ItemPredicate, + Color, + Component, + Message, + NbtCompoundTag, + NbtTag, + NbtPath, + Objective, + ObjectiveCriteria, + Operation, + Particle, + Angle, + Rotation, + ScoreboardSlot, + ScoreHolder { allow_multiple: bool }, + Swizzle, + Team, + ItemSlot, + ResourceLocation, + Function, + EntityAnchor, + IntRange, + FloatRange, + Dimension, + GameMode, + Time, + ResourceOrTag { registry: Ident> }, + ResourceOrTagKey { registry: Ident> }, + Resource { registry: Ident> }, + ResourceKey { registry: Ident> }, + TemplateMirror, + TemplateRotation, + Uuid, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum StringArg { + SingleWord, + QuotablePhrase, + GreedyPhrase, +} + +impl Encode for Node<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + let node_type = match &self.data { + NodeData::Root => 0, + NodeData::Literal { .. } => 1, + NodeData::Argument { .. } => 2, + }; + + let has_suggestion = matches!( + &self.data, + NodeData::Argument { + suggestion: Some(_), + .. + } + ); + + let flags: u8 = node_type + | (self.executable as u8 * 0x04) + | (self.redirect_node.is_some() as u8 * 0x08) + | (has_suggestion as u8 * 0x10); + + w.write_u8(flags)?; + + self.children.encode(&mut w)?; + + if let Some(redirect_node) = self.redirect_node { + redirect_node.encode(&mut w)?; + } + + match &self.data { + NodeData::Root => {} + NodeData::Literal { name } => { + name.encode(&mut w)?; + } + NodeData::Argument { + name, + parser, + suggestion, + } => { + name.encode(&mut w)?; + parser.encode(&mut w)?; + + if let Some(suggestion) = suggestion { + match suggestion { + Suggestion::AskServer => "ask_server", + Suggestion::AllRecipes => "all_recipes", + Suggestion::AvailableSounds => "available_sounds", + Suggestion::AvailableBiomes => "available_biomes", + Suggestion::SummonableEntities => "summonable_entities", + } + .encode(&mut w)?; + } + } + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for Node<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let flags = u8::decode(r)?; + + let children = Vec::decode(r)?; + + let redirect_node = if flags & 0x08 != 0 { + Some(VarInt::decode(r)?) + } else { + None + }; + + let node_data = match flags & 0x3 { + 0 => NodeData::Root, + 1 => NodeData::Literal { + name: <&str>::decode(r)?, + }, + 2 => NodeData::Argument { + name: <&str>::decode(r)?, + parser: Parser::decode(r)?, + suggestion: if flags & 0x10 != 0 { + Some(match Ident::>::decode(r)?.as_str() { + "minecraft:ask_server" => Suggestion::AskServer, + "minecraft:all_recipes" => Suggestion::AllRecipes, + "minecraft:available_sounds" => Suggestion::AvailableSounds, + "minecraft:available_biomes" => Suggestion::AvailableBiomes, + "minecraft:summonable_entities" => Suggestion::SummonableEntities, + other => bail!("unknown command suggestion type of \"{other}\""), + }) + } else { + None + }, + }, + n => bail!("invalid node type of {n}"), + }; + + Ok(Self { + children, + data: node_data, + executable: flags & 0x04 != 0, + redirect_node, + }) + } +} + +impl Encode for Parser<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + match self { + Parser::Bool => 0u8.encode(&mut w)?, + Parser::Float { min, max } => { + 1u8.encode(&mut w)?; + + (min.is_some() as u8 | (max.is_some() as u8 * 0x2)).encode(&mut w)?; + + if let Some(min) = min { + min.encode(&mut w)?; + } + + if let Some(max) = max { + max.encode(&mut w)?; + } + } + Parser::Double { min, max } => { + 2u8.encode(&mut w)?; + + (min.is_some() as u8 | (max.is_some() as u8 * 0x2)).encode(&mut w)?; + + if let Some(min) = min { + min.encode(&mut w)?; + } + + if let Some(max) = max { + max.encode(&mut w)?; + } + } + Parser::Integer { min, max } => { + 3u8.encode(&mut w)?; + + (min.is_some() as u8 | (max.is_some() as u8 * 0x2)).encode(&mut w)?; + + if let Some(min) = min { + min.encode(&mut w)?; + } + + if let Some(max) = max { + max.encode(&mut w)?; + } + } + Parser::Long { min, max } => { + 4u8.encode(&mut w)?; + + (min.is_some() as u8 | (max.is_some() as u8 * 0x2)).encode(&mut w)?; + + if let Some(min) = min { + min.encode(&mut w)?; + } + + if let Some(max) = max { + max.encode(&mut w)?; + } + } + Parser::String(arg) => { + 5u8.encode(&mut w)?; + arg.encode(&mut w)?; + } + Parser::Entity { + single, + only_players, + } => { + 6u8.encode(&mut w)?; + (*single as u8 | (*only_players as u8 * 0x2)).encode(&mut w)?; + } + Parser::GameProfile => 7u8.encode(&mut w)?, + Parser::BlockPos => 8u8.encode(&mut w)?, + Parser::ColumnPos => 9u8.encode(&mut w)?, + Parser::Vec3 => 10u8.encode(&mut w)?, + Parser::Vec2 => 11u8.encode(&mut w)?, + Parser::BlockState => 12u8.encode(&mut w)?, + Parser::BlockPredicate => 13u8.encode(&mut w)?, + Parser::ItemStack => 14u8.encode(&mut w)?, + Parser::ItemPredicate => 15u8.encode(&mut w)?, + Parser::Color => 16u8.encode(&mut w)?, + Parser::Component => 17u8.encode(&mut w)?, + Parser::Message => 18u8.encode(&mut w)?, + Parser::NbtCompoundTag => 19u8.encode(&mut w)?, + Parser::NbtTag => 20u8.encode(&mut w)?, + Parser::NbtPath => 21u8.encode(&mut w)?, + Parser::Objective => 22u8.encode(&mut w)?, + Parser::ObjectiveCriteria => 23u8.encode(&mut w)?, + Parser::Operation => 24u8.encode(&mut w)?, + Parser::Particle => 25u8.encode(&mut w)?, + Parser::Angle => 26u8.encode(&mut w)?, + Parser::Rotation => 27u8.encode(&mut w)?, + Parser::ScoreboardSlot => 28u8.encode(&mut w)?, + Parser::ScoreHolder { allow_multiple } => { + 29u8.encode(&mut w)?; + allow_multiple.encode(&mut w)?; + } + Parser::Swizzle => 30u8.encode(&mut w)?, + Parser::Team => 31u8.encode(&mut w)?, + Parser::ItemSlot => 32u8.encode(&mut w)?, + Parser::ResourceLocation => 33u8.encode(&mut w)?, + Parser::Function => 34u8.encode(&mut w)?, + Parser::EntityAnchor => 35u8.encode(&mut w)?, + Parser::IntRange => 36u8.encode(&mut w)?, + Parser::FloatRange => 37u8.encode(&mut w)?, + Parser::Dimension => 38u8.encode(&mut w)?, + Parser::GameMode => 39u8.encode(&mut w)?, + Parser::Time => 40u8.encode(&mut w)?, + Parser::ResourceOrTag { registry } => { + 41u8.encode(&mut w)?; + registry.encode(&mut w)?; + } + Parser::ResourceOrTagKey { registry } => { + 42u8.encode(&mut w)?; + registry.encode(&mut w)?; + } + Parser::Resource { registry } => { + 43u8.encode(&mut w)?; + registry.encode(&mut w)?; + } + Parser::ResourceKey { registry } => { + 44u8.encode(&mut w)?; + registry.encode(&mut w)?; + } + Parser::TemplateMirror => 45u8.encode(&mut w)?, + Parser::TemplateRotation => 46u8.encode(&mut w)?, + Parser::Uuid => 47u8.encode(&mut w)?, + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for Parser<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + fn decode_min_max<'a, T: Decode<'a>>( + r: &mut &'a [u8], + ) -> anyhow::Result<(Option, Option)> { + let flags = u8::decode(r)?; + + let min = if flags & 0x1 != 0 { + Some(T::decode(r)?) + } else { + None + }; + + let max = if flags & 0x2 != 0 { + Some(T::decode(r)?) + } else { + None + }; + + Ok((min, max)) + } + + Ok(match u8::decode(r)? { + 0 => Self::Bool, + 1 => { + let (min, max) = decode_min_max(r)?; + Self::Float { min, max } + } + 2 => { + let (min, max) = decode_min_max(r)?; + Self::Double { min, max } + } + 3 => { + let (min, max) = decode_min_max(r)?; + Self::Integer { min, max } + } + 4 => { + let (min, max) = decode_min_max(r)?; + Self::Long { min, max } + } + 5 => Self::String(StringArg::decode(r)?), + 6 => { + let flags = u8::decode(r)?; + Self::Entity { + single: flags & 0x1 != 0, + only_players: flags & 0x2 != 0, + } + } + 7 => Self::GameProfile, + 8 => Self::BlockPos, + 9 => Self::ColumnPos, + 10 => Self::Vec3, + 11 => Self::Vec2, + 12 => Self::BlockState, + 13 => Self::BlockPredicate, + 14 => Self::ItemStack, + 15 => Self::ItemPredicate, + 16 => Self::Color, + 17 => Self::Component, + 18 => Self::Message, + 19 => Self::NbtCompoundTag, + 20 => Self::NbtTag, + 21 => Self::NbtPath, + 22 => Self::Objective, + 23 => Self::ObjectiveCriteria, + 24 => Self::Operation, + 25 => Self::Particle, + 26 => Self::Angle, + 27 => Self::Rotation, + 28 => Self::ScoreboardSlot, + 29 => Self::ScoreHolder { + allow_multiple: bool::decode(r)?, + }, + 30 => Self::Swizzle, + 31 => Self::Team, + 32 => Self::ItemSlot, + 33 => Self::ResourceLocation, + 34 => Self::Function, + 35 => Self::EntityAnchor, + 36 => Self::IntRange, + 37 => Self::FloatRange, + 38 => Self::Dimension, + 39 => Self::GameMode, + 40 => Self::Time, + 41 => Self::ResourceOrTag { + registry: Ident::decode(r)?, + }, + 42 => Self::ResourceOrTagKey { + registry: Ident::decode(r)?, + }, + 43 => Self::Resource { + registry: Ident::decode(r)?, + }, + 44 => Self::ResourceKey { + registry: Ident::decode(r)?, + }, + 45 => Self::TemplateMirror, + 46 => Self::TemplateRotation, + 47 => Self::Uuid, + n => bail!("unknown command parser ID of {n}"), + }) + } +} diff --git a/crates/valence_packet/src/packets/play/cooldown_update_s2c.rs b/crates/valence_packet/src/packets/play/cooldown_update_s2c.rs new file mode 100644 index 000000000..3b306368a --- /dev/null +++ b/crates/valence_packet/src/packets/play/cooldown_update_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::COOLDOWN_UPDATE_S2C)] +pub struct CooldownUpdateS2c { + pub item_id: VarInt, + pub cooldown_ticks: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/craft_failed_response_s2c.rs b/crates/valence_packet/src/packets/play/craft_failed_response_s2c.rs new file mode 100644 index 000000000..e2a71ffb6 --- /dev/null +++ b/crates/valence_packet/src/packets/play/craft_failed_response_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CRAFT_FAILED_RESPONSE_S2C)] +pub struct CraftFailedResponseS2c<'a> { + pub window_id: u8, + pub recipe: Ident>, +} diff --git a/crates/valence_packet/src/packets/play/craft_request_c2s.rs b/crates/valence_packet/src/packets/play/craft_request_c2s.rs new file mode 100644 index 000000000..521f71bbc --- /dev/null +++ b/crates/valence_packet/src/packets/play/craft_request_c2s.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CRAFT_REQUEST_C2S)] +pub struct CraftRequestC2s<'a> { + pub window_id: i8, + pub recipe: Ident>, + pub make_all: bool, +} diff --git a/crates/valence_packet/src/packets/play/creative_inventory_action_c2s.rs b/crates/valence_packet/src/packets/play/creative_inventory_action_c2s.rs new file mode 100644 index 000000000..f5f16d1d7 --- /dev/null +++ b/crates/valence_packet/src/packets/play/creative_inventory_action_c2s.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CREATIVE_INVENTORY_ACTION_C2S)] +pub struct CreativeInventoryActionC2s { + pub slot: i16, + pub clicked_item: Option, +} diff --git a/crates/valence_packet/src/packets/play/custom_payload_c2s.rs b/crates/valence_packet/src/packets/play/custom_payload_c2s.rs new file mode 100644 index 000000000..7ef357cf1 --- /dev/null +++ b/crates/valence_packet/src/packets/play/custom_payload_c2s.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CUSTOM_PAYLOAD_C2S)] +pub struct CustomPayloadC2s<'a> { + pub channel: Ident>, + pub data: RawBytes<'a>, +} diff --git a/crates/valence_packet/src/packets/play/custom_payload_s2c.rs b/crates/valence_packet/src/packets/play/custom_payload_s2c.rs new file mode 100644 index 000000000..28b96d559 --- /dev/null +++ b/crates/valence_packet/src/packets/play/custom_payload_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::CUSTOM_PAYLOAD_S2C)] +pub struct CustomPayloadS2c<'a> { + pub channel: Ident>, + pub data: RawBytes<'a>, +} diff --git a/crates/valence_packet/src/packets/play/damage_tilt_s2c.rs b/crates/valence_packet/src/packets/play/damage_tilt_s2c.rs new file mode 100644 index 000000000..57ed718cb --- /dev/null +++ b/crates/valence_packet/src/packets/play/damage_tilt_s2c.rs @@ -0,0 +1,10 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::DAMAGE_TILT_S2C)] +pub struct DamageTiltS2c { + /// The ID of the entity taking damage. + pub entity_id: VarInt, + /// The direction the damage is coming from in relation to the entity. + pub yaw: f32, +} diff --git a/crates/valence_packet/src/packets/play/death_message_s2c.rs b/crates/valence_packet/src/packets/play/death_message_s2c.rs new file mode 100644 index 000000000..8f86ff489 --- /dev/null +++ b/crates/valence_packet/src/packets/play/death_message_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::DEATH_MESSAGE_S2C)] +pub struct DeathMessageS2c<'a> { + pub player_id: VarInt, + pub message: Cow<'a, Text>, +} diff --git a/crates/valence_packet/src/packets/play/difficulty_s2c.rs b/crates/valence_packet/src/packets/play/difficulty_s2c.rs new file mode 100644 index 000000000..b3d298587 --- /dev/null +++ b/crates/valence_packet/src/packets/play/difficulty_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::DIFFICULTY_S2C)] +pub struct DifficultyS2c { + pub difficulty: Difficulty, + pub locked: bool, +} diff --git a/crates/valence_packet/src/packets/play/disconnect_s2c.rs b/crates/valence_packet/src/packets/play/disconnect_s2c.rs new file mode 100644 index 000000000..83e8b9de8 --- /dev/null +++ b/crates/valence_packet/src/packets/play/disconnect_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::DISCONNECT_S2C)] +pub struct DisconnectS2c<'a> { + pub reason: Cow<'a, Text>, +} diff --git a/crates/valence_packet/src/packets/play/end_combat_s2c.rs b/crates/valence_packet/src/packets/play/end_combat_s2c.rs new file mode 100644 index 000000000..c44d1ea6c --- /dev/null +++ b/crates/valence_packet/src/packets/play/end_combat_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +/// Unused by notchian clients. +#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::END_COMBAT_S2C)] +pub struct EndCombatS2c { + pub duration: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/enter_combat_s2c.rs b/crates/valence_packet/src/packets/play/enter_combat_s2c.rs new file mode 100644 index 000000000..24a2dbcb5 --- /dev/null +++ b/crates/valence_packet/src/packets/play/enter_combat_s2c.rs @@ -0,0 +1,6 @@ +use super::*; + +/// Unused by notchian clients. +#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ENTER_COMBAT_S2C)] +pub struct EnterCombatS2c; diff --git a/crates/valence_packet/src/packets/play/entities_destroy_s2c.rs b/crates/valence_packet/src/packets/play/entities_destroy_s2c.rs new file mode 100644 index 000000000..a9433e761 --- /dev/null +++ b/crates/valence_packet/src/packets/play/entities_destroy_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, PartialEq, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ENTITIES_DESTROY_S2C)] +pub struct EntitiesDestroyS2c<'a> { + pub entity_ids: Cow<'a, [VarInt]>, +} diff --git a/crates/valence_packet/src/packets/play/entity_animation_s2c.rs b/crates/valence_packet/src/packets/play/entity_animation_s2c.rs new file mode 100644 index 000000000..be03d4397 --- /dev/null +++ b/crates/valence_packet/src/packets/play/entity_animation_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ENTITY_ANIMATION_S2C)] +pub struct EntityAnimationS2c { + pub entity_id: VarInt, + pub animation: u8, +} diff --git a/crates/valence_packet/src/packets/play/entity_attach_s2c.rs b/crates/valence_packet/src/packets/play/entity_attach_s2c.rs new file mode 100644 index 000000000..79eedb982 --- /dev/null +++ b/crates/valence_packet/src/packets/play/entity_attach_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ENTITY_ATTACH_S2C)] +pub struct EntityAttachS2c { + pub attached_entity_id: i32, + pub holding_entity_id: i32, +} diff --git a/crates/valence_packet/src/packets/play/entity_attributes_s2c.rs b/crates/valence_packet/src/packets/play/entity_attributes_s2c.rs new file mode 100644 index 000000000..fd84e53c0 --- /dev/null +++ b/crates/valence_packet/src/packets/play/entity_attributes_s2c.rs @@ -0,0 +1,22 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ENTITY_ATTRIBUTES_S2C)] +pub struct EntityAttributesS2c<'a> { + pub entity_id: VarInt, + pub properties: Vec>, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct AttributeProperty<'a> { + pub key: Ident>, + pub value: f64, + pub modifiers: Vec, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct AttributeModifier { + pub uuid: Uuid, + pub amount: f64, + pub operation: u8, +} diff --git a/crates/valence_packet/src/packets/play/entity_damage_s2c.rs b/crates/valence_packet/src/packets/play/entity_damage_s2c.rs new file mode 100644 index 000000000..15eacf920 --- /dev/null +++ b/crates/valence_packet/src/packets/play/entity_damage_s2c.rs @@ -0,0 +1,23 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ENTITY_DAMAGE_S2C)] +pub struct EntityDamageS2c { + /// The ID of the entity taking damage + pub entity_id: VarInt, + /// The ID of the type of damage taken + pub source_type_id: VarInt, + /// The ID + 1 of the entity responsible for the damage, if present. If not + /// present, the value is 0 + pub source_cause_id: VarInt, + /// The ID + 1 of the entity that directly dealt the damage, if present. If + /// not present, the value is 0. If this field is present: + /// * and damage was dealt indirectly, such as by the use of a projectile, + /// this field will contain the ID of such projectile; + /// * and damage was dealt dirctly, such as by manually attacking, this + /// field will contain the same value as Source Cause ID. + pub source_direct_id: VarInt, + /// The Notchian server sends the Source Position when the damage was dealt + /// by the /damage command and a position was specified + pub source_pos: Option, +} diff --git a/crates/valence_packet/src/packets/play/entity_equipment_update_s2c.rs b/crates/valence_packet/src/packets/play/entity_equipment_update_s2c.rs new file mode 100644 index 000000000..c43e5809c --- /dev/null +++ b/crates/valence_packet/src/packets/play/entity_equipment_update_s2c.rs @@ -0,0 +1,57 @@ +use super::*; + +#[derive(Clone, PartialEq, Debug, Packet)] +#[packet(id = packet_id::ENTITY_EQUIPMENT_UPDATE_S2C)] +pub struct EntityEquipmentUpdateS2c { + pub entity_id: VarInt, + pub equipment: Vec, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct EquipmentEntry { + pub slot: i8, + pub item: Option, +} + +impl Encode for EntityEquipmentUpdateS2c { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + self.entity_id.encode(&mut w)?; + + for i in 0..self.equipment.len() { + let slot = self.equipment[i].slot; + if i != self.equipment.len() - 1 { + (slot | -128).encode(&mut w)?; + } else { + slot.encode(&mut w)?; + } + self.equipment[i].item.encode(&mut w)?; + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for EntityEquipmentUpdateS2c { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let entity_id = VarInt::decode(r)?; + + let mut equipment = vec![]; + + loop { + let slot = i8::decode(r)?; + let item = Option::::decode(r)?; + equipment.push(EquipmentEntry { + slot: slot & 127, + item, + }); + if slot & -128 == 0 { + break; + } + } + + Ok(Self { + entity_id, + equipment, + }) + } +} diff --git a/crates/valence_packet/src/packets/play/entity_passengers_set_s2c.rs b/crates/valence_packet/src/packets/play/entity_passengers_set_s2c.rs new file mode 100644 index 000000000..e5909d5dd --- /dev/null +++ b/crates/valence_packet/src/packets/play/entity_passengers_set_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ENTITY_PASSENGERS_SET_S2C)] +pub struct EntityPassengersSetS2c { + /// Vehicle's entity id + pub entity_id: VarInt, + pub passengers: Vec, +} diff --git a/crates/valence_packet/src/packets/play/entity_position_s2c.rs b/crates/valence_packet/src/packets/play/entity_position_s2c.rs new file mode 100644 index 000000000..a1c1bbdd2 --- /dev/null +++ b/crates/valence_packet/src/packets/play/entity_position_s2c.rs @@ -0,0 +1,11 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ENTITY_POSITION_S2C)] +pub struct EntityPositionS2c { + pub entity_id: VarInt, + pub position: DVec3, + pub yaw: ByteAngle, + pub pitch: ByteAngle, + pub on_ground: bool, +} diff --git a/crates/valence_packet/src/packets/play/entity_set_head_yaw_s2c.rs b/crates/valence_packet/src/packets/play/entity_set_head_yaw_s2c.rs new file mode 100644 index 000000000..dfe9da650 --- /dev/null +++ b/crates/valence_packet/src/packets/play/entity_set_head_yaw_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ENTITY_SET_HEAD_YAW_S2C)] +pub struct EntitySetHeadYawS2c { + pub entity_id: VarInt, + pub head_yaw: ByteAngle, +} diff --git a/crates/valence_packet/src/packets/play/entity_spawn_s2c.rs b/crates/valence_packet/src/packets/play/entity_spawn_s2c.rs new file mode 100644 index 000000000..dd95209d8 --- /dev/null +++ b/crates/valence_packet/src/packets/play/entity_spawn_s2c.rs @@ -0,0 +1,18 @@ +use super::*; + +/// Sent by the server when a vehicle or other non-living entity is created. +/// +/// wiki : [Spawn Entity](https://wiki.vg/Protocol#Spawn_Experience_Orb) +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ENTITY_SPAWN_S2C)] +pub struct EntitySpawnS2c { + pub entity_id: VarInt, + pub object_uuid: Uuid, + pub kind: VarInt, + pub position: DVec3, + pub pitch: ByteAngle, + pub yaw: ByteAngle, + pub head_yaw: ByteAngle, + pub data: VarInt, + pub velocity: [i16; 3], +} diff --git a/crates/valence_packet/src/packets/play/entity_status_effect_s2c.rs b/crates/valence_packet/src/packets/play/entity_status_effect_s2c.rs new file mode 100644 index 000000000..513b40dfa --- /dev/null +++ b/crates/valence_packet/src/packets/play/entity_status_effect_s2c.rs @@ -0,0 +1,22 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ENTITY_STATUS_EFFECT_S2C)] +pub struct EntityStatusEffectS2c { + pub entity_id: VarInt, + pub effect_id: VarInt, + pub amplifier: u8, + pub duration: VarInt, + pub flags: Flags, + pub factor_codec: Option, +} + +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct Flags { + pub is_ambient: bool, + pub show_particles: bool, + pub show_icon: bool, + #[bits(5)] + _pad: u8, +} diff --git a/crates/valence_packet/src/packets/play/entity_status_s2c.rs b/crates/valence_packet/src/packets/play/entity_status_s2c.rs new file mode 100644 index 000000000..8273184ab --- /dev/null +++ b/crates/valence_packet/src/packets/play/entity_status_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ENTITY_STATUS_S2C)] +pub struct EntityStatusS2c { + pub entity_id: i32, + pub entity_status: u8, +} diff --git a/crates/valence_packet/src/packets/play/entity_tracker_update_s2c.rs b/crates/valence_packet/src/packets/play/entity_tracker_update_s2c.rs new file mode 100644 index 000000000..aca3a3261 --- /dev/null +++ b/crates/valence_packet/src/packets/play/entity_tracker_update_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ENTITY_TRACKER_UPDATE_S2C)] +pub struct EntityTrackerUpdateS2c<'a> { + pub entity_id: VarInt, + pub metadata: RawBytes<'a>, +} diff --git a/crates/valence_packet/src/packets/play/entity_velocity_update_s2c.rs b/crates/valence_packet/src/packets/play/entity_velocity_update_s2c.rs new file mode 100644 index 000000000..f8ec36bb7 --- /dev/null +++ b/crates/valence_packet/src/packets/play/entity_velocity_update_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ENTITY_VELOCITY_UPDATE_S2C)] +pub struct EntityVelocityUpdateS2c { + pub entity_id: VarInt, + pub velocity: [i16; 3], +} diff --git a/crates/valence_packet/src/packets/play/experience_bar_update_s2c.rs b/crates/valence_packet/src/packets/play/experience_bar_update_s2c.rs new file mode 100644 index 000000000..bb5c9153f --- /dev/null +++ b/crates/valence_packet/src/packets/play/experience_bar_update_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::EXPERIENCE_BAR_UPDATE_S2C)] +pub struct ExperienceBarUpdateS2c { + pub bar: f32, + pub level: VarInt, + pub total_xp: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/experience_orb_spawn_s2c.rs b/crates/valence_packet/src/packets/play/experience_orb_spawn_s2c.rs new file mode 100644 index 000000000..a14045423 --- /dev/null +++ b/crates/valence_packet/src/packets/play/experience_orb_spawn_s2c.rs @@ -0,0 +1,13 @@ +use super::*; + +/// Spawns one or more experience orbs. +/// +/// wiki : [Spawn Experience Orb](https://wiki.vg/Protocol#Spawn_Experience_Orb) +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::EXPERIENCE_ORB_SPAWN_S2C)] +pub struct ExperienceOrbSpawnS2c { + pub entity_id: VarInt, + pub position: DVec3, + /// The amount of experience this orb will reward once collected. + pub count: i16, +} diff --git a/crates/valence_packet/src/packets/play/explosion_s2c.rs b/crates/valence_packet/src/packets/play/explosion_s2c.rs new file mode 100644 index 000000000..fd8e66155 --- /dev/null +++ b/crates/valence_packet/src/packets/play/explosion_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::EXPLOSION_S2C)] +pub struct ExplosionS2c<'a> { + pub window_id: u8, + pub recipe: Ident>, + pub make_all: bool, +} diff --git a/crates/valence_packet/src/packets/play/features_s2c.rs b/crates/valence_packet/src/packets/play/features_s2c.rs new file mode 100644 index 000000000..f2e84f1ad --- /dev/null +++ b/crates/valence_packet/src/packets/play/features_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::FEATURES_S2C)] +pub struct FeaturesS2c<'a> { + pub features: Vec>>, +} diff --git a/crates/valence_packet/src/packets/play/full.rs b/crates/valence_packet/src/packets/play/full.rs new file mode 100644 index 000000000..561fc0f81 --- /dev/null +++ b/crates/valence_packet/src/packets/play/full.rs @@ -0,0 +1,10 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::FULL)] +pub struct FullC2s { + pub position: DVec3, + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} diff --git a/crates/valence_packet/src/packets/play/game_join_s2c.rs b/crates/valence_packet/src/packets/play/game_join_s2c.rs new file mode 100644 index 000000000..5799969c9 --- /dev/null +++ b/crates/valence_packet/src/packets/play/game_join_s2c.rs @@ -0,0 +1,25 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::GAME_JOIN_S2C)] +pub struct GameJoinS2c<'a> { + pub entity_id: i32, + pub is_hardcore: bool, + pub game_mode: GameMode, + /// Same values as `game_mode` but with -1 to indicate no previous. + pub previous_game_mode: i8, + pub dimension_names: Vec>>, + pub registry_codec: Cow<'a, Compound>, + pub dimension_type_name: Ident>, + pub dimension_name: Ident>, + pub hashed_seed: i64, + pub max_players: VarInt, + pub view_distance: VarInt, + pub simulation_distance: VarInt, + pub reduced_debug_info: bool, + pub enable_respawn_screen: bool, + pub is_debug: bool, + pub is_flat: bool, + pub last_death_location: Option>, + pub portal_cooldown: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/game_message_s2c.rs b/crates/valence_packet/src/packets/play/game_message_s2c.rs new file mode 100644 index 000000000..2bb98ead4 --- /dev/null +++ b/crates/valence_packet/src/packets/play/game_message_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::GAME_MESSAGE_S2C)] +pub struct GameMessageS2c<'a> { + pub chat: Cow<'a, Text>, + /// Whether the message is in the actionbar or the chat. + pub overlay: bool, +} diff --git a/crates/valence_packet/src/packets/play/game_state_change_s2c.rs b/crates/valence_packet/src/packets/play/game_state_change_s2c.rs new file mode 100644 index 000000000..4277d89ea --- /dev/null +++ b/crates/valence_packet/src/packets/play/game_state_change_s2c.rs @@ -0,0 +1,24 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::GAME_STATE_CHANGE_S2C)] +pub struct GameStateChangeS2c { + pub kind: GameEventKind, + pub value: f32, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum GameEventKind { + NoRespawnBlockAvailable, + EndRaining, + BeginRaining, + ChangeGameMode, + WinGame, + DemoEvent, + ArrowHitPlayer, + RainLevelChange, + ThunderLevelChange, + PlayPufferfishStingSound, + PlayElderGuardianMobAppearance, + EnableRespawnScreen, +} diff --git a/crates/valence_packet/src/packets/play/hand_swing_c2s.rs b/crates/valence_packet/src/packets/play/hand_swing_c2s.rs new file mode 100644 index 000000000..82db13850 --- /dev/null +++ b/crates/valence_packet/src/packets/play/hand_swing_c2s.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::HAND_SWING_C2S)] +pub struct HandSwingC2s { + pub hand: Hand, +} diff --git a/crates/valence_packet/src/packets/play/health_update_s2c.rs b/crates/valence_packet/src/packets/play/health_update_s2c.rs new file mode 100644 index 000000000..71821fe83 --- /dev/null +++ b/crates/valence_packet/src/packets/play/health_update_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::HEALTH_UPDATE_S2C)] +pub struct HealthUpdateS2c { + pub health: f32, + pub food: VarInt, + pub food_saturation: f32, +} diff --git a/crates/valence_packet/src/packets/play/inventory_s2c.rs b/crates/valence_packet/src/packets/play/inventory_s2c.rs new file mode 100644 index 000000000..fd537b37c --- /dev/null +++ b/crates/valence_packet/src/packets/play/inventory_s2c.rs @@ -0,0 +1,10 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::INVENTORY_S2C)] +pub struct InventoryS2c<'a> { + pub window_id: u8, + pub state_id: VarInt, + pub slots: Cow<'a, [Option]>, + pub carried_item: Cow<'a, Option>, +} diff --git a/crates/valence_packet/src/packets/play/item_pickup_animation_s2c.rs b/crates/valence_packet/src/packets/play/item_pickup_animation_s2c.rs new file mode 100644 index 000000000..7539d5dd8 --- /dev/null +++ b/crates/valence_packet/src/packets/play/item_pickup_animation_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ITEM_PICKUP_ANIMATION_S2C)] +pub struct ItemPickupAnimationS2c { + pub collected_entity_id: VarInt, + pub collector_entity_id: VarInt, + pub pickup_item_count: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/jigsaw_generating_c2s.rs b/crates/valence_packet/src/packets/play/jigsaw_generating_c2s.rs new file mode 100644 index 000000000..7ee8ef620 --- /dev/null +++ b/crates/valence_packet/src/packets/play/jigsaw_generating_c2s.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::JIGSAW_GENERATING_C2S)] +pub struct JigsawGeneratingC2s { + pub position: BlockPos, + pub levels: VarInt, + pub keep_jigsaws: bool, +} diff --git a/crates/valence_packet/src/packets/play/keep_alive_c2s.rs b/crates/valence_packet/src/packets/play/keep_alive_c2s.rs new file mode 100644 index 000000000..6f80c2669 --- /dev/null +++ b/crates/valence_packet/src/packets/play/keep_alive_c2s.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::KEEP_ALIVE_C2S)] +pub struct KeepAliveC2s { + pub id: u64, +} diff --git a/crates/valence_packet/src/packets/play/keep_alive_s2c.rs b/crates/valence_packet/src/packets/play/keep_alive_s2c.rs new file mode 100644 index 000000000..52a28cb2e --- /dev/null +++ b/crates/valence_packet/src/packets/play/keep_alive_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::KEEP_ALIVE_S2C)] +pub struct KeepAliveS2c { + pub id: u64, +} diff --git a/crates/valence_packet/src/packets/play/light_update_s2c.rs b/crates/valence_packet/src/packets/play/light_update_s2c.rs new file mode 100644 index 000000000..b265f76f1 --- /dev/null +++ b/crates/valence_packet/src/packets/play/light_update_s2c.rs @@ -0,0 +1,16 @@ +use valence_core::protocol::array::LengthPrefixedArray; + +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::LIGHT_UPDATE_S2C)] +pub struct LightUpdateS2c { + pub chunk_x: VarInt, + pub chunk_z: VarInt, + pub sky_light_mask: Vec, + pub block_light_mask: Vec, + pub empty_sky_light_mask: Vec, + pub empty_block_light_mask: Vec, + pub sky_light_arrays: Vec>, + pub block_light_arrays: Vec>, +} diff --git a/crates/valence_packet/src/packets/play/look_and_on_ground.rs b/crates/valence_packet/src/packets/play/look_and_on_ground.rs new file mode 100644 index 000000000..6cf2fd28e --- /dev/null +++ b/crates/valence_packet/src/packets/play/look_and_on_ground.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::LOOK_AND_ON_GROUND)] +pub struct LookAndOnGroundC2s { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} diff --git a/crates/valence_packet/src/packets/play/look_at_s2c.rs b/crates/valence_packet/src/packets/play/look_at_s2c.rs new file mode 100644 index 000000000..968feb85f --- /dev/null +++ b/crates/valence_packet/src/packets/play/look_at_s2c.rs @@ -0,0 +1,22 @@ +use super::*; + +/// Instructs a client to face an entity. +#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::LOOK_AT_S2C)] +pub struct LookAtS2c { + pub feet_or_eyes: FeetOrEyes, + pub target_position: DVec3, + pub entity_to_face: Option, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum FeetOrEyes { + Feet, + Eyes, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub struct LookAtEntity { + pub entity_id: VarInt, + pub feet_or_eyes: FeetOrEyes, +} diff --git a/crates/valence_packet/src/packets/play/map_update_s2c.rs b/crates/valence_packet/src/packets/play/map_update_s2c.rs new file mode 100644 index 000000000..1e809d864 --- /dev/null +++ b/crates/valence_packet/src/packets/play/map_update_s2c.rs @@ -0,0 +1,109 @@ +use super::*; + +#[derive(Clone, PartialEq, Debug, Packet)] +#[packet(id = packet_id::MAP_UPDATE_S2C)] +pub struct MapUpdateS2c<'a> { + pub map_id: VarInt, + pub scale: i8, + pub locked: bool, + pub icons: Option>>, + pub data: Option>, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct Icon<'a> { + pub icon_type: IconType, + /// In map coordinates; -128 for furthest left, +127 for furthest right + pub position: [i8; 2], + /// 0 is a vertical icon and increments by 22.5° + pub direction: i8, + pub display_name: Option>, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum IconType { + WhiteArrow, + GreenArrow, + RedArrow, + BlueArrow, + WhiteCross, + RedPointer, + WhiteCircle, + SmallWhiteCircle, + Mansion, + Temple, + WhiteBanner, + OrangeBanner, + MagentaBanner, + LightBlueBanner, + YellowBanner, + LimeBanner, + PinkBanner, + GrayBanner, + LightGrayBanner, + CyanBanner, + PurpleBanner, + BlueBanner, + BrownBanner, + GreenBanner, + RedBanner, + BlackBanner, + TreasureMarker, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode)] +pub struct Data<'a> { + pub columns: u8, + pub rows: u8, + pub position: [i8; 2], + pub data: &'a [u8], +} + +impl Encode for MapUpdateS2c<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + self.map_id.encode(&mut w)?; + self.scale.encode(&mut w)?; + self.locked.encode(&mut w)?; + self.icons.encode(&mut w)?; + + match self.data { + None => 0u8.encode(&mut w)?, + Some(data) => data.encode(&mut w)?, + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for MapUpdateS2c<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let map_id = VarInt::decode(r)?; + let scale = i8::decode(r)?; + let locked = bool::decode(r)?; + let icons = >>>::decode(r)?; + let columns = u8::decode(r)?; + + let data = if columns > 0 { + let rows = u8::decode(r)?; + let position = <[i8; 2]>::decode(r)?; + let data = <&'a [u8]>::decode(r)?; + + Some(Data { + columns, + rows, + position, + data, + }) + } else { + None + }; + + Ok(Self { + map_id, + scale, + locked, + icons, + data, + }) + } +} diff --git a/crates/valence_packet/src/packets/play/message_acknowledgment_c2s.rs b/crates/valence_packet/src/packets/play/message_acknowledgment_c2s.rs new file mode 100644 index 000000000..57eeb1130 --- /dev/null +++ b/crates/valence_packet/src/packets/play/message_acknowledgment_c2s.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::MESSAGE_ACKNOWLEDGMENT_C2S)] + +pub struct MessageAcknowledgmentC2s { + pub message_count: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/mod.rs b/crates/valence_packet/src/packets/play/mod.rs new file mode 100644 index 000000000..b48e488f9 --- /dev/null +++ b/crates/valence_packet/src/packets/play/mod.rs @@ -0,0 +1,179 @@ +use bitfield_struct::bitfield; +use byteorder::WriteBytesExt; +use glam::{DVec3, IVec3, Vec3}; +use valence_core::block_pos::BlockPos; +use valence_core::chunk_pos::ChunkPos; +use valence_core::difficulty::Difficulty; +use valence_core::direction::Direction; +use valence_core::game_mode::GameMode; +use valence_core::hand::Hand; +use valence_core::item::ItemStack; +use valence_core::protocol::byte_angle::ByteAngle; +use valence_core::protocol::global_pos::GlobalPos; +use valence_core::protocol::var_long::VarLong; +use valence_nbt::Compound; + +use super::*; + +pub mod advancement_tab_c2s; +pub mod advancement_update_s2c; +pub mod block_breaking_progress_s2c; +pub mod block_entity_update_s2c; +pub mod block_event_s2c; +pub mod block_update_s2c; +pub mod boat_paddle_state_c2s; +pub mod book_update_c2s; +pub mod boss_bar_s2c; +pub mod bundle_splitter; +pub mod button_click_c2s; +pub mod chat_message_c2s; +pub mod chat_message_s2c; +pub mod chat_suggestions_s2c; +pub mod chunk_biome_data_s2c; +pub mod chunk_data_s2c; +pub mod chunk_delta_update_s2c; +pub mod chunk_load_distance_s2c; +pub mod chunk_render_distance_center_s2c; +pub mod clear_title_s2c; +pub mod click_slot_c2s; +pub mod client_command_c2s; +pub mod client_settings_c2s; +pub mod client_status_c2s; +pub mod close_handled_screen_c2s; +pub mod close_screen_s2c; +pub mod command_execution_c2s; +pub mod command_suggestions_s2c; +pub mod command_tree_s2c; +pub mod cooldown_update_s2c; +pub mod craft_failed_response_s2c; +pub mod craft_request_c2s; +pub mod creative_inventory_action_c2s; +pub mod custom_payload_c2s; +pub mod custom_payload_s2c; +pub mod damage_tilt_s2c; +pub mod death_message_s2c; +pub mod difficulty_s2c; +pub mod disconnect_s2c; +pub mod end_combat_s2c; +pub mod enter_combat_s2c; +pub mod entities_destroy_s2c; +pub mod entity_animation_s2c; +pub mod entity_attach_s2c; +pub mod entity_attributes_s2c; +pub mod entity_damage_s2c; +pub mod entity_equipment_update_s2c; +pub mod entity_passengers_set_s2c; +pub mod entity_position_s2c; +pub mod entity_set_head_yaw_s2c; +pub mod entity_spawn_s2c; +pub mod entity_status_effect_s2c; +pub mod entity_status_s2c; +pub mod entity_tracker_update_s2c; +pub mod entity_velocity_update_s2c; +pub mod experience_bar_update_s2c; +pub mod experience_orb_spawn_s2c; +pub mod explosion_s2c; +pub mod features_s2c; +pub mod full; +pub mod game_join_s2c; +pub mod game_message_s2c; +pub mod game_state_change_s2c; +pub mod hand_swing_c2s; +pub mod health_update_s2c; +pub mod inventory_s2c; +pub mod item_pickup_animation_s2c; +pub mod jigsaw_generating_c2s; +pub mod keep_alive_c2s; +pub mod keep_alive_s2c; +pub mod light_update_s2c; +pub mod look_and_on_ground; +pub mod look_at_s2c; +pub mod map_update_s2c; +pub mod message_acknowledgment_c2s; +pub mod move_relative; +pub mod nbt_query_response_s2c; +pub mod on_ground_only; +pub mod open_horse_screen_s2c; +pub mod open_screen_s2c; +pub mod open_written_book_s2c; +pub mod overlay_message_s2c; +pub mod particle_s2c; +pub mod pick_from_inventory_c2s; +pub mod play_ping_s2c; +pub mod play_pong_c2s; +pub mod play_sound_from_entity_s2c; +pub mod play_sound_s2c; +pub mod player_abilities_s2c; +pub mod player_action_c2s; +pub mod player_action_response_s2c; +pub mod player_input_c2s; +pub mod player_interact_block_c2s; +pub mod player_interact_entity_c2s; +pub mod player_interact_item_c2s; +pub mod player_list_header_s2c; +pub mod player_list_s2c; +pub mod player_position_look_s2c; +pub mod player_remove_s2c; +pub mod player_respawn_s2c; +pub mod player_session_c2s; +pub mod player_spawn_position_s2c; +pub mod player_spawn_s2c; +pub mod position_and_on_ground; +pub mod profileless_chat_message_s2c; +pub mod query_block_nbt_c2s; +pub mod query_entity_nbt_c2s; +pub mod recipe_book_data_c2s; +pub mod recipe_category_options_c2s; +pub mod remove_entity_status_effect_s2c; +pub mod remove_message_s2c; +pub mod rename_item_c2s; +pub mod request_command_completions_c2s; +pub mod resource_pack_send_s2c; +pub mod resource_pack_status_c2s; +pub mod rotate; +pub mod rotate_and_move_relative; +pub mod scoreboard_display_s2c; +pub mod scoreboard_objective_update_s2c; +pub mod scoreboard_player_update_s2c; +pub mod screen_handler_property_update_s2c; +pub mod screen_handler_slot_update_s2c; +pub mod select_advancement_tab_s2c; +pub mod select_merchant_trade_c2s; +pub mod server_metadata_s2c; +pub mod set_camera_entity_s2c; +pub mod set_trade_offers_s2c; +pub mod sign_editor_open_s2c; +pub mod simulation_distance_s2c; +pub mod spectator_teleport_c2s; +pub mod statistics_s2c; +pub mod stop_sound_s2c; +pub mod subtitle_s2c; +pub mod synchronize_recipes_s2c; +pub mod synchronize_tags_s2c; +pub mod team_s2c; +pub mod teleport_confirm_c2s; +pub mod title_fade_s2c; +pub mod title_s2c; +pub mod unload_chunk_s2c; +pub mod unlock_recipes_s2c; +pub mod update_beacon_c2s; +pub mod update_command_block_c2s; +pub mod update_command_block_minecart_c2s; +pub mod update_difficulty_c2s; +pub mod update_difficulty_lock_c2s; +pub mod update_jigsaw_c2s; +pub mod update_player_abilities_c2s; +pub mod update_selected_slot_c2s; +pub mod update_selected_slot_s2c; +pub mod update_sign_c2s; +pub mod update_structure_block_c2s; +pub mod vehicle_move_c2s; +pub mod vehicle_move_s2c; +pub mod world_border_center_changed_s2c; +pub mod world_border_initialize_s2c; +pub mod world_border_interpolate_size_s2c; +pub mod world_border_size_changed_s2c; +pub mod world_border_warning_blocks_changed_s2c; +pub mod world_border_warning_time_changed_s2c; +pub mod world_event_s2c; +pub mod world_time_update_s2c; diff --git a/crates/valence_packet/src/packets/play/move_relative.rs b/crates/valence_packet/src/packets/play/move_relative.rs new file mode 100644 index 000000000..d69831461 --- /dev/null +++ b/crates/valence_packet/src/packets/play/move_relative.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::MOVE_RELATIVE)] +pub struct MoveRelativeS2c { + pub entity_id: VarInt, + pub delta: [i16; 3], + pub on_ground: bool, +} diff --git a/crates/valence_packet/src/packets/play/nbt_query_response_s2c.rs b/crates/valence_packet/src/packets/play/nbt_query_response_s2c.rs new file mode 100644 index 000000000..8c510237b --- /dev/null +++ b/crates/valence_packet/src/packets/play/nbt_query_response_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::NBT_QUERY_RESPONSE_S2C)] +pub struct NbtQueryResponseS2c { + pub transaction_id: VarInt, + pub nbt: Compound, +} diff --git a/crates/valence_packet/src/packets/play/on_ground_only.rs b/crates/valence_packet/src/packets/play/on_ground_only.rs new file mode 100644 index 000000000..d2b2cc184 --- /dev/null +++ b/crates/valence_packet/src/packets/play/on_ground_only.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ON_GROUND_ONLY)] +pub struct OnGroundOnlyC2s { + pub on_ground: bool, +} diff --git a/crates/valence_packet/src/packets/play/open_horse_screen_s2c.rs b/crates/valence_packet/src/packets/play/open_horse_screen_s2c.rs new file mode 100644 index 000000000..3ef6b5930 --- /dev/null +++ b/crates/valence_packet/src/packets/play/open_horse_screen_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::OPEN_HORSE_SCREEN_S2C)] +pub struct OpenHorseScreenS2c { + pub window_id: u8, + pub slot_count: VarInt, + pub entity_id: i32, +} diff --git a/crates/valence_packet/src/packets/play/open_screen_s2c.rs b/crates/valence_packet/src/packets/play/open_screen_s2c.rs new file mode 100644 index 000000000..eaba283b3 --- /dev/null +++ b/crates/valence_packet/src/packets/play/open_screen_s2c.rs @@ -0,0 +1,37 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::OPEN_SCREEN_S2C)] +pub struct OpenScreenS2c<'a> { + pub window_id: VarInt, + pub window_type: WindowType, + pub window_title: Cow<'a, Text>, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum WindowType { + Generic9x1, + Generic9x2, + Generic9x3, + Generic9x4, + Generic9x5, + Generic9x6, + Generic3x3, + Anvil, + Beacon, + BlastFurnace, + BrewingStand, + Crafting, + Enchantment, + Furnace, + Grindstone, + Hopper, + Lectern, + Loom, + Merchant, + ShulkerBox, + Smithing, + Smoker, + Cartography, + Stonecutter, +} diff --git a/crates/valence_packet/src/packets/play/open_written_book_s2c.rs b/crates/valence_packet/src/packets/play/open_written_book_s2c.rs new file mode 100644 index 000000000..91da3094e --- /dev/null +++ b/crates/valence_packet/src/packets/play/open_written_book_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::OPEN_WRITTEN_BOOK_S2C)] +pub struct OpenWrittenBookS2c { + pub hand: Hand, +} diff --git a/crates/valence_packet/src/packets/play/overlay_message_s2c.rs b/crates/valence_packet/src/packets/play/overlay_message_s2c.rs new file mode 100644 index 000000000..79178dd68 --- /dev/null +++ b/crates/valence_packet/src/packets/play/overlay_message_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::OVERLAY_MESSAGE_S2C)] +pub struct OverlayMessageS2c<'a> { + pub action_bar_text: Cow<'a, Text>, +} diff --git a/crates/valence_packet/src/packets/play/particle_s2c.rs b/crates/valence_packet/src/packets/play/particle_s2c.rs new file mode 100644 index 000000000..79db86674 --- /dev/null +++ b/crates/valence_packet/src/packets/play/particle_s2c.rs @@ -0,0 +1,437 @@ +use glam::Vec3; + +use super::*; + +#[derive(Clone, Debug, Packet)] +#[packet(id = packet_id::PARTICLE_S2C)] +pub struct ParticleS2c<'a> { + pub particle: Cow<'a, Particle>, + pub long_distance: bool, + pub position: DVec3, + pub offset: Vec3, + pub max_speed: f32, + pub count: i32, +} + +impl Encode for ParticleS2c<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + VarInt(self.particle.id()).encode(&mut w)?; + self.long_distance.encode(&mut w)?; + self.position.encode(&mut w)?; + self.offset.encode(&mut w)?; + self.max_speed.encode(&mut w)?; + self.count.encode(&mut w)?; + + self.particle.as_ref().encode(w) + } +} + +impl<'a> Decode<'a> for ParticleS2c<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let particle_id = VarInt::decode(r)?.0; + let long_distance = bool::decode(r)?; + let position = Decode::decode(r)?; + let offset = Decode::decode(r)?; + let max_speed = f32::decode(r)?; + let particle_count = i32::decode(r)?; + + Ok(Self { + particle: Cow::Owned(Particle::decode_with_id(particle_id, r)?), + long_distance, + position, + offset, + max_speed, + count: particle_count, + }) + } +} + +#[derive(Clone, PartialEq, Debug)] +pub enum Particle { + AmbientEntityEffect, + AngryVillager, + Block(i32), // TODO: use BlockState type. + BlockMarker(i32), // TODO: use BlockState type. + Bubble, + Cloud, + Crit, + DamageIndicator, + DragonBreath, + DrippingLava, + FallingLava, + LandingLava, + DrippingWater, + FallingWater, + Dust { + rgb: Vec3, + scale: f32, + }, + DustColorTransition { + from_rgb: Vec3, + scale: f32, + to_rgb: Vec3, + }, + Effect, + ElderGuardian, + EnchantedHit, + Enchant, + EndRod, + EntityEffect, + ExplosionEmitter, + Explosion, + SonicBoom, + FallingDust(i32), // TODO: use BlockState type. + Firework, + Fishing, + Flame, + CherryLeaves, + SculkSoul, + SculkCharge { + roll: f32, + }, + SculkChargePop, + SoulFireFlame, + Soul, + Flash, + HappyVillager, + Composter, + Heart, + InstantEffect, + Item(Option), + /// The 'Block' variant of the 'Vibration' particle + VibrationBlock { + block_pos: BlockPos, + ticks: i32, + }, + /// The 'Entity' variant of the 'Vibration' particle + VibrationEntity { + entity_id: i32, + entity_eye_height: f32, + ticks: i32, + }, + ItemSlime, + ItemSnowball, + LargeSmoke, + Lava, + Mycelium, + Note, + Poof, + Portal, + Rain, + Smoke, + Sneeze, + Spit, + SquidInk, + SweepAttack, + TotemOfUndying, + Underwater, + Splash, + Witch, + BubblePop, + CurrentDown, + BubbleColumnUp, + Nautilus, + Dolphin, + CampfireCosySmoke, + CampfireSignalSmoke, + DrippingHoney, + FallingHoney, + LandingHoney, + FallingNectar, + FallingSporeBlossom, + Ash, + CrimsonSpore, + WarpedSpore, + SporeBlossomAir, + DrippingObsidianTear, + FallingObsidianTear, + LandingObsidianTear, + ReversePortal, + WhiteAsh, + SmallFlame, + Snowflake, + DrippingDripstoneLava, + FallingDripstoneLava, + DrippingDripstoneWater, + FallingDripstoneWater, + GlowSquidInk, + Glow, + WaxOn, + WaxOff, + ElectricSpark, + Scrape, + Shriek { + delay: i32, + }, + EggCrack, +} + +impl Particle { + pub const fn id(&self) -> i32 { + match self { + Particle::AmbientEntityEffect => 0, + Particle::AngryVillager => 1, + Particle::Block(_) => 2, + Particle::BlockMarker(_) => 3, + Particle::Bubble => 4, + Particle::Cloud => 5, + Particle::Crit => 6, + Particle::DamageIndicator => 7, + Particle::DragonBreath => 8, + Particle::DrippingLava => 9, + Particle::FallingLava => 10, + Particle::LandingLava => 11, + Particle::DrippingWater => 12, + Particle::FallingWater => 13, + Particle::Dust { .. } => 14, + Particle::DustColorTransition { .. } => 15, + Particle::Effect => 16, + Particle::ElderGuardian => 17, + Particle::EnchantedHit => 18, + Particle::Enchant => 19, + Particle::EndRod => 20, + Particle::EntityEffect => 21, + Particle::ExplosionEmitter => 22, + Particle::Explosion => 23, + Particle::SonicBoom => 24, + Particle::FallingDust(_) => 25, + Particle::Firework => 26, + Particle::Fishing => 27, + Particle::Flame => 28, + Particle::CherryLeaves => 29, + Particle::SculkSoul => 30, + Particle::SculkCharge { .. } => 31, + Particle::SculkChargePop => 32, + Particle::SoulFireFlame => 33, + Particle::Soul => 34, + Particle::Flash => 35, + Particle::HappyVillager => 36, + Particle::Composter => 37, + Particle::Heart => 38, + Particle::InstantEffect => 39, + Particle::Item { .. } => 40, + Particle::VibrationBlock { .. } => 41, + Particle::VibrationEntity { .. } => 41, + Particle::ItemSlime => 42, + Particle::ItemSnowball => 43, + Particle::LargeSmoke => 44, + Particle::Lava => 45, + Particle::Mycelium => 46, + Particle::Note => 47, + Particle::Poof => 48, + Particle::Portal => 49, + Particle::Rain => 50, + Particle::Smoke => 51, + Particle::Sneeze => 52, + Particle::Spit => 53, + Particle::SquidInk => 54, + Particle::SweepAttack => 55, + Particle::TotemOfUndying => 56, + Particle::Underwater => 57, + Particle::Splash => 58, + Particle::Witch => 59, + Particle::BubblePop => 60, + Particle::CurrentDown => 61, + Particle::BubbleColumnUp => 62, + Particle::Nautilus => 63, + Particle::Dolphin => 64, + Particle::CampfireCosySmoke => 65, + Particle::CampfireSignalSmoke => 66, + Particle::DrippingHoney => 67, + Particle::FallingHoney => 68, + Particle::LandingHoney => 69, + Particle::FallingNectar => 70, + Particle::FallingSporeBlossom => 71, + Particle::Ash => 72, + Particle::CrimsonSpore => 73, + Particle::WarpedSpore => 74, + Particle::SporeBlossomAir => 75, + Particle::DrippingObsidianTear => 76, + Particle::FallingObsidianTear => 77, + Particle::LandingObsidianTear => 78, + Particle::ReversePortal => 79, + Particle::WhiteAsh => 80, + Particle::SmallFlame => 81, + Particle::Snowflake => 82, + Particle::DrippingDripstoneLava => 83, + Particle::FallingDripstoneLava => 84, + Particle::DrippingDripstoneWater => 85, + Particle::FallingDripstoneWater => 86, + Particle::GlowSquidInk => 87, + Particle::Glow => 88, + Particle::WaxOn => 89, + Particle::WaxOff => 80, + Particle::ElectricSpark => 91, + Particle::Scrape => 92, + Particle::Shriek { .. } => 93, + Particle::EggCrack => 94, + } + } + + /// Decodes the particle assuming the given particle ID. + pub fn decode_with_id(particle_id: i32, r: &mut &[u8]) -> anyhow::Result { + Ok(match particle_id { + 0 => Particle::AmbientEntityEffect, + 1 => Particle::AngryVillager, + 2 => Particle::Block(VarInt::decode(r)?.0), + 3 => Particle::BlockMarker(VarInt::decode(r)?.0), + 4 => Particle::Bubble, + 5 => Particle::Cloud, + 6 => Particle::Crit, + 7 => Particle::DamageIndicator, + 8 => Particle::DragonBreath, + 9 => Particle::DrippingLava, + 10 => Particle::FallingLava, + 11 => Particle::LandingLava, + 12 => Particle::DrippingWater, + 13 => Particle::FallingWater, + 14 => Particle::Dust { + rgb: Decode::decode(r)?, + scale: Decode::decode(r)?, + }, + 15 => Particle::DustColorTransition { + from_rgb: Decode::decode(r)?, + scale: Decode::decode(r)?, + to_rgb: Decode::decode(r)?, + }, + 16 => Particle::Effect, + 17 => Particle::ElderGuardian, + 18 => Particle::EnchantedHit, + 19 => Particle::Enchant, + 20 => Particle::EndRod, + 21 => Particle::EntityEffect, + 22 => Particle::ExplosionEmitter, + 23 => Particle::Explosion, + 24 => Particle::SonicBoom, + 25 => Particle::FallingDust(VarInt::decode(r)?.0), + 26 => Particle::Firework, + 27 => Particle::Fishing, + 28 => Particle::Flame, + 29 => Particle::CherryLeaves, + 30 => Particle::SculkSoul, + 31 => Particle::SculkCharge { + roll: f32::decode(r)?, + }, + 32 => Particle::SculkChargePop, + 33 => Particle::SoulFireFlame, + 34 => Particle::Soul, + 35 => Particle::Flash, + 36 => Particle::HappyVillager, + 37 => Particle::Composter, + 38 => Particle::Heart, + 39 => Particle::InstantEffect, + 40 => Particle::Item(Decode::decode(r)?), + 41 => match <&str>::decode(r)? { + "block" => Particle::VibrationBlock { + block_pos: BlockPos::decode(r)?, + ticks: VarInt::decode(r)?.0, + }, + "entity" => Particle::VibrationEntity { + entity_id: VarInt::decode(r)?.0, + entity_eye_height: f32::decode(r)?, + ticks: VarInt::decode(r)?.0, + }, + invalid => bail!("invalid vibration position source of \"{invalid}\""), + }, + 42 => Particle::ItemSlime, + 43 => Particle::ItemSnowball, + 44 => Particle::LargeSmoke, + 45 => Particle::Lava, + 46 => Particle::Mycelium, + 47 => Particle::Note, + 48 => Particle::Poof, + 49 => Particle::Portal, + 50 => Particle::Rain, + 51 => Particle::Smoke, + 52 => Particle::Sneeze, + 53 => Particle::Spit, + 54 => Particle::SquidInk, + 55 => Particle::SweepAttack, + 56 => Particle::TotemOfUndying, + 57 => Particle::Underwater, + 58 => Particle::Splash, + 59 => Particle::Witch, + 60 => Particle::BubblePop, + 61 => Particle::CurrentDown, + 62 => Particle::BubbleColumnUp, + 63 => Particle::Nautilus, + 64 => Particle::Dolphin, + 65 => Particle::CampfireCosySmoke, + 66 => Particle::CampfireSignalSmoke, + 67 => Particle::DrippingHoney, + 68 => Particle::FallingHoney, + 69 => Particle::LandingHoney, + 70 => Particle::FallingNectar, + 71 => Particle::FallingSporeBlossom, + 72 => Particle::Ash, + 73 => Particle::CrimsonSpore, + 74 => Particle::WarpedSpore, + 75 => Particle::SporeBlossomAir, + 76 => Particle::DrippingObsidianTear, + 77 => Particle::FallingObsidianTear, + 78 => Particle::LandingObsidianTear, + 79 => Particle::ReversePortal, + 80 => Particle::WhiteAsh, + 81 => Particle::SmallFlame, + 82 => Particle::Snowflake, + 83 => Particle::DrippingDripstoneLava, + 84 => Particle::FallingDripstoneLava, + 85 => Particle::DrippingDripstoneWater, + 86 => Particle::FallingDripstoneWater, + 87 => Particle::GlowSquidInk, + 88 => Particle::Glow, + 89 => Particle::WaxOn, + 90 => Particle::WaxOff, + 91 => Particle::ElectricSpark, + 92 => Particle::Scrape, + 93 => Particle::Shriek { + delay: VarInt::decode(r)?.0, + }, + 94 => Particle::EggCrack, + id => bail!("invalid particle ID of {id}"), + }) + } +} + +/// Encodes the particle without an ID. +impl Encode for Particle { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + match self { + Particle::Block(block_state) => VarInt(*block_state).encode(w), + Particle::BlockMarker(block_state) => VarInt(*block_state).encode(w), + Particle::Dust { rgb, scale } => { + rgb.encode(&mut w)?; + scale.encode(w) + } + Particle::DustColorTransition { + from_rgb, + scale, + to_rgb, + } => { + from_rgb.encode(&mut w)?; + scale.encode(&mut w)?; + to_rgb.encode(w) + } + Particle::FallingDust(block_state) => VarInt(*block_state).encode(w), + Particle::SculkCharge { roll } => roll.encode(w), + Particle::Item(stack) => stack.encode(w), + Particle::VibrationBlock { block_pos, ticks } => { + "block".encode(&mut w)?; + block_pos.encode(&mut w)?; + VarInt(*ticks).encode(w) + } + Particle::VibrationEntity { + entity_id, + entity_eye_height, + ticks, + } => { + "entity".encode(&mut w)?; + VarInt(*entity_id).encode(&mut w)?; + entity_eye_height.encode(&mut w)?; + VarInt(*ticks).encode(w) + } + Particle::Shriek { delay } => VarInt(*delay).encode(w), + _ => Ok(()), + } + } +} diff --git a/crates/valence_packet/src/packets/play/pick_from_inventory_c2s.rs b/crates/valence_packet/src/packets/play/pick_from_inventory_c2s.rs new file mode 100644 index 000000000..4c7123a49 --- /dev/null +++ b/crates/valence_packet/src/packets/play/pick_from_inventory_c2s.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PICK_FROM_INVENTORY_C2S)] +pub struct PickFromInventoryC2s { + pub slot_to_use: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/play_ping_s2c.rs b/crates/valence_packet/src/packets/play/play_ping_s2c.rs new file mode 100644 index 000000000..7c1aa43e0 --- /dev/null +++ b/crates/valence_packet/src/packets/play/play_ping_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAY_PING_S2C)] +pub struct PlayPingS2c { + pub id: i32, +} diff --git a/crates/valence_packet/src/packets/play/play_pong_c2s.rs b/crates/valence_packet/src/packets/play/play_pong_c2s.rs new file mode 100644 index 000000000..1dbdec132 --- /dev/null +++ b/crates/valence_packet/src/packets/play/play_pong_c2s.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAY_PONG_C2S)] +pub struct PlayPongC2s { + pub id: i32, +} diff --git a/crates/valence_packet/src/packets/play/play_sound_from_entity_s2c.rs b/crates/valence_packet/src/packets/play/play_sound_from_entity_s2c.rs new file mode 100644 index 000000000..ea36d1987 --- /dev/null +++ b/crates/valence_packet/src/packets/play/play_sound_from_entity_s2c.rs @@ -0,0 +1,14 @@ +use valence_core::sound::SoundCategory; + +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAY_SOUND_FROM_ENTITY_S2C)] +pub struct PlaySoundFromEntityS2c { + pub id: VarInt, + pub category: SoundCategory, + pub entity_id: VarInt, + pub volume: f32, + pub pitch: f32, + pub seed: i64, +} diff --git a/crates/valence_packet/src/packets/play/play_sound_s2c.rs b/crates/valence_packet/src/packets/play/play_sound_s2c.rs new file mode 100644 index 000000000..2651c29a9 --- /dev/null +++ b/crates/valence_packet/src/packets/play/play_sound_s2c.rs @@ -0,0 +1,14 @@ +use valence_core::sound::{SoundCategory, SoundId}; + +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAY_SOUND_S2C)] +pub struct PlaySoundS2c<'a> { + pub id: SoundId<'a>, + pub category: SoundCategory, + pub position: IVec3, + pub volume: f32, + pub pitch: f32, + pub seed: i64, +} diff --git a/crates/valence_packet/src/packets/play/player_abilities_s2c.rs b/crates/valence_packet/src/packets/play/player_abilities_s2c.rs new file mode 100644 index 000000000..bc8621f94 --- /dev/null +++ b/crates/valence_packet/src/packets/play/player_abilities_s2c.rs @@ -0,0 +1,20 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAYER_ABILITIES_S2C)] +pub struct PlayerAbilitiesS2c { + pub flags: PlayerAbilitiesFlags, + pub flying_speed: f32, + pub fov_modifier: f32, +} + +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct PlayerAbilitiesFlags { + pub invulnerable: bool, + pub flying: bool, + pub allow_flying: bool, + pub instant_break: bool, + #[bits(4)] + _pad: u8, +} diff --git a/crates/valence_packet/src/packets/play/player_action_c2s.rs b/crates/valence_packet/src/packets/play/player_action_c2s.rs new file mode 100644 index 000000000..836832747 --- /dev/null +++ b/crates/valence_packet/src/packets/play/player_action_c2s.rs @@ -0,0 +1,21 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAYER_ACTION_C2S)] +pub struct PlayerActionC2s { + pub action: PlayerAction, + pub position: BlockPos, + pub direction: Direction, + pub sequence: VarInt, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum PlayerAction { + StartDestroyBlock, + AbortDestroyBlock, + StopDestroyBlock, + DropAllItems, + DropItem, + ReleaseUseItem, + SwapItemWithOffhand, +} diff --git a/crates/valence_packet/src/packets/play/player_action_response_s2c.rs b/crates/valence_packet/src/packets/play/player_action_response_s2c.rs new file mode 100644 index 000000000..f358e5aae --- /dev/null +++ b/crates/valence_packet/src/packets/play/player_action_response_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAYER_ACTION_RESPONSE_S2C)] +pub struct PlayerActionResponseS2c { + pub sequence: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/player_input_c2s.rs b/crates/valence_packet/src/packets/play/player_input_c2s.rs new file mode 100644 index 000000000..a83ad6b3e --- /dev/null +++ b/crates/valence_packet/src/packets/play/player_input_c2s.rs @@ -0,0 +1,18 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAYER_INPUT_C2S)] +pub struct PlayerInputC2s { + pub sideways: f32, + pub forward: f32, + pub flags: PlayerInputFlags, +} + +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct PlayerInputFlags { + pub jump: bool, + pub unmount: bool, + #[bits(6)] + _pad: u8, +} diff --git a/crates/valence_packet/src/packets/play/player_interact_block_c2s.rs b/crates/valence_packet/src/packets/play/player_interact_block_c2s.rs new file mode 100644 index 000000000..4b2b6817d --- /dev/null +++ b/crates/valence_packet/src/packets/play/player_interact_block_c2s.rs @@ -0,0 +1,12 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAYER_INTERACT_BLOCK_C2S)] +pub struct PlayerInteractBlockC2s { + pub hand: Hand, + pub position: BlockPos, + pub face: Direction, + pub cursor_pos: Vec3, + pub head_inside_block: bool, + pub sequence: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/player_interact_entity_c2s.rs b/crates/valence_packet/src/packets/play/player_interact_entity_c2s.rs new file mode 100644 index 000000000..e157ae8d1 --- /dev/null +++ b/crates/valence_packet/src/packets/play/player_interact_entity_c2s.rs @@ -0,0 +1,16 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAYER_INTERACT_ENTITY_C2S)] +pub struct PlayerInteractEntityC2s { + pub entity_id: VarInt, + pub interact: EntityInteraction, + pub sneaking: bool, +} + +#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode)] +pub enum EntityInteraction { + Interact(Hand), + Attack, + InteractAt { target: Vec3, hand: Hand }, +} diff --git a/crates/valence_packet/src/packets/play/player_interact_item_c2s.rs b/crates/valence_packet/src/packets/play/player_interact_item_c2s.rs new file mode 100644 index 000000000..7806f61a5 --- /dev/null +++ b/crates/valence_packet/src/packets/play/player_interact_item_c2s.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAYER_INTERACT_ITEM_C2S)] +pub struct PlayerInteractItemC2s { + pub hand: Hand, + pub sequence: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/player_list_header_s2c.rs b/crates/valence_packet/src/packets/play/player_list_header_s2c.rs new file mode 100644 index 000000000..73e7d299b --- /dev/null +++ b/crates/valence_packet/src/packets/play/player_list_header_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAYER_LIST_HEADER_S2C)] +pub struct PlayerListHeaderS2c<'a> { + pub header: Cow<'a, Text>, + pub footer: Cow<'a, Text>, +} diff --git a/crates/valence_packet/src/packets/play/player_list_s2c.rs b/crates/valence_packet/src/packets/play/player_list_s2c.rs new file mode 100644 index 000000000..c028c93bb --- /dev/null +++ b/crates/valence_packet/src/packets/play/player_list_s2c.rs @@ -0,0 +1,128 @@ +use super::*; + +#[derive(Clone, Debug, Packet)] +#[packet(id = packet_id::PLAYER_LIST_S2C)] +pub struct PlayerListS2c<'a> { + pub actions: PlayerListActions, + pub entries: Cow<'a, [PlayerListEntry<'a>]>, +} + +impl<'a> Encode for PlayerListS2c<'a> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + self.actions.0.encode(&mut w)?; + + // Write number of entries. + VarInt(self.entries.len() as i32).encode(&mut w)?; + + for entry in self.entries.as_ref() { + entry.player_uuid.encode(&mut w)?; + + if self.actions.add_player() { + entry.username.encode(&mut w)?; + entry.properties.encode(&mut w)?; + } + + if self.actions.initialize_chat() { + entry.chat_data.encode(&mut w)?; + } + + if self.actions.update_game_mode() { + entry.game_mode.encode(&mut w)?; + } + + if self.actions.update_listed() { + entry.listed.encode(&mut w)?; + } + + if self.actions.update_latency() { + VarInt(entry.ping).encode(&mut w)?; + } + + if self.actions.update_display_name() { + entry.display_name.encode(&mut w)?; + } + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for PlayerListS2c<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let actions = PlayerListActions(u8::decode(r)?); + + let mut entries = vec![]; + + for _ in 0..VarInt::decode(r)?.0 { + let mut entry = PlayerListEntry { + player_uuid: Uuid::decode(r)?, + ..Default::default() + }; + + if actions.add_player() { + entry.username = Decode::decode(r)?; + entry.properties = Decode::decode(r)?; + } + + if actions.initialize_chat() { + entry.chat_data = Decode::decode(r)?; + } + + if actions.update_game_mode() { + entry.game_mode = Decode::decode(r)?; + } + + if actions.update_listed() { + entry.listed = Decode::decode(r)?; + } + + if actions.update_latency() { + entry.ping = VarInt::decode(r)?.0; + } + + if actions.update_display_name() { + entry.display_name = Decode::decode(r)?; + } + + entries.push(entry); + } + + Ok(Self { + actions, + entries: entries.into(), + }) + } +} + +#[bitfield(u8)] +pub struct PlayerListActions { + pub add_player: bool, + pub initialize_chat: bool, + pub update_game_mode: bool, + pub update_listed: bool, + pub update_latency: bool, + pub update_display_name: bool, + #[bits(2)] + _pad: u8, +} + +#[derive(Clone, Default, Debug)] +pub struct PlayerListEntry<'a> { + pub player_uuid: Uuid, + pub username: &'a str, + pub properties: Cow<'a, [Property]>, + pub chat_data: Option>, + pub listed: bool, + pub ping: i32, + pub game_mode: GameMode, + pub display_name: Option>, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct ChatData<'a> { + pub session_id: Uuid, + /// Unix timestamp in milliseconds. + pub key_expiry_time: i64, + pub public_key: &'a [u8], + pub public_key_signature: &'a [u8], +} diff --git a/crates/valence_packet/src/packets/play/player_position_look_s2c.rs b/crates/valence_packet/src/packets/play/player_position_look_s2c.rs new file mode 100644 index 000000000..d1c57a662 --- /dev/null +++ b/crates/valence_packet/src/packets/play/player_position_look_s2c.rs @@ -0,0 +1,23 @@ +use super::*; + +#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAYER_POSITION_LOOK_S2C)] +pub struct PlayerPositionLookS2c { + pub position: DVec3, + pub yaw: f32, + pub pitch: f32, + pub flags: PlayerPositionLookFlags, + pub teleport_id: VarInt, +} + +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct PlayerPositionLookFlags { + pub x: bool, + pub y: bool, + pub z: bool, + pub y_rot: bool, + pub x_rot: bool, + #[bits(3)] + _pad: u8, +} diff --git a/crates/valence_packet/src/packets/play/player_remove_s2c.rs b/crates/valence_packet/src/packets/play/player_remove_s2c.rs new file mode 100644 index 000000000..00cb7ff81 --- /dev/null +++ b/crates/valence_packet/src/packets/play/player_remove_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, PartialEq, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAYER_REMOVE_S2C)] +pub struct PlayerRemoveS2c<'a> { + pub uuids: Cow<'a, [Uuid]>, +} diff --git a/crates/valence_packet/src/packets/play/player_respawn_s2c.rs b/crates/valence_packet/src/packets/play/player_respawn_s2c.rs new file mode 100644 index 000000000..b1b9dbd9e --- /dev/null +++ b/crates/valence_packet/src/packets/play/player_respawn_s2c.rs @@ -0,0 +1,16 @@ +use super::*; + +#[derive(Clone, PartialEq, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAYER_RESPAWN_S2C)] +pub struct PlayerRespawnS2c<'a> { + pub dimension_type_name: Ident>, + pub dimension_name: Ident>, + pub hashed_seed: u64, + pub game_mode: GameMode, + pub previous_game_mode: i8, + pub is_debug: bool, + pub is_flat: bool, + pub copy_metadata: bool, + pub last_death_location: Option>, + pub portal_cooldown: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/player_session_c2s.rs b/crates/valence_packet/src/packets/play/player_session_c2s.rs new file mode 100644 index 000000000..fc298b7d4 --- /dev/null +++ b/crates/valence_packet/src/packets/play/player_session_c2s.rs @@ -0,0 +1,11 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAYER_SESSION_C2S)] +pub struct PlayerSessionC2s<'a> { + pub session_id: Uuid, + // Public key + pub expires_at: i64, + pub public_key_data: &'a [u8], + pub key_signature: &'a [u8], +} diff --git a/crates/valence_packet/src/packets/play/player_spawn_position_s2c.rs b/crates/valence_packet/src/packets/play/player_spawn_position_s2c.rs new file mode 100644 index 000000000..f056e6744 --- /dev/null +++ b/crates/valence_packet/src/packets/play/player_spawn_position_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAYER_SPAWN_POSITION_S2C)] +pub struct PlayerSpawnPositionS2c { + pub position: BlockPos, + pub angle: f32, +} diff --git a/crates/valence_packet/src/packets/play/player_spawn_s2c.rs b/crates/valence_packet/src/packets/play/player_spawn_s2c.rs new file mode 100644 index 000000000..6da85cbbb --- /dev/null +++ b/crates/valence_packet/src/packets/play/player_spawn_s2c.rs @@ -0,0 +1,25 @@ +use super::*; + +/// This packet is sent by the server when a player comes into visible range, +/// not when a player joins. +/// +/// This packet must be sent after the Player Info Update packet that adds the +/// player data for the client to use when spawning a player. If the Player Info +/// for the player spawned by this packet is not present when this packet +/// arrives, Notchian clients will not spawn the player entity. The Player Info +/// packet includes skin/cape data. +/// +/// Servers can, however, safely spawn player entities for players not in +/// visible range. The client appears to handle it correctly. +/// +/// wiki : [Spawn Player](https://wiki.vg/Protocol#Spawn_Player) +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PLAYER_SPAWN_S2C)] +pub struct PlayerSpawnS2c { + /// A unique integer ID mostly used in the protocol to identify the player. + pub entity_id: VarInt, + pub player_uuid: Uuid, + pub position: DVec3, + pub yaw: ByteAngle, + pub pitch: ByteAngle, +} diff --git a/crates/valence_packet/src/packets/play/position_and_on_ground.rs b/crates/valence_packet/src/packets/play/position_and_on_ground.rs new file mode 100644 index 000000000..50fb1b73e --- /dev/null +++ b/crates/valence_packet/src/packets/play/position_and_on_ground.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::POSITION_AND_ON_GROUND)] +pub struct PositionAndOnGroundC2s { + pub position: DVec3, + pub on_ground: bool, +} diff --git a/crates/valence_packet/src/packets/play/profileless_chat_message_s2c.rs b/crates/valence_packet/src/packets/play/profileless_chat_message_s2c.rs new file mode 100644 index 000000000..97b2dcd14 --- /dev/null +++ b/crates/valence_packet/src/packets/play/profileless_chat_message_s2c.rs @@ -0,0 +1,10 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::PROFILELESS_CHAT_MESSAGE_S2C)] +pub struct ProfilelessChatMessageS2c<'a> { + pub message: Cow<'a, Text>, + pub chat_type: VarInt, + pub chat_type_name: Cow<'a, Text>, + pub target_name: Option>, +} diff --git a/crates/valence_packet/src/packets/play/query_block_nbt_c2s.rs b/crates/valence_packet/src/packets/play/query_block_nbt_c2s.rs new file mode 100644 index 000000000..704834799 --- /dev/null +++ b/crates/valence_packet/src/packets/play/query_block_nbt_c2s.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::QUERY_BLOCK_NBT_C2S)] +pub struct QueryBlockNbtC2s { + pub transaction_id: VarInt, + pub position: BlockPos, +} diff --git a/crates/valence_packet/src/packets/play/query_entity_nbt_c2s.rs b/crates/valence_packet/src/packets/play/query_entity_nbt_c2s.rs new file mode 100644 index 000000000..717f39b45 --- /dev/null +++ b/crates/valence_packet/src/packets/play/query_entity_nbt_c2s.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::QUERY_ENTITY_NBT_C2S)] +pub struct QueryEntityNbtC2s { + pub transaction_id: VarInt, + pub entity_id: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/recipe_book_data_c2s.rs b/crates/valence_packet/src/packets/play/recipe_book_data_c2s.rs new file mode 100644 index 000000000..3f1fc9051 --- /dev/null +++ b/crates/valence_packet/src/packets/play/recipe_book_data_c2s.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::RECIPE_BOOK_DATA_C2S)] +pub struct RecipeBookDataC2s<'a> { + pub recipe_id: Ident>, +} diff --git a/crates/valence_packet/src/packets/play/recipe_category_options_c2s.rs b/crates/valence_packet/src/packets/play/recipe_category_options_c2s.rs new file mode 100644 index 000000000..1116ff8a5 --- /dev/null +++ b/crates/valence_packet/src/packets/play/recipe_category_options_c2s.rs @@ -0,0 +1,17 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::RECIPE_CATEGORY_OPTIONS_C2S)] +pub struct RecipeCategoryOptionsC2s { + pub book_id: RecipeBookId, + pub book_open: bool, + pub filter_active: bool, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum RecipeBookId { + Crafting, + Furnace, + BlastFurnace, + Smoker, +} diff --git a/crates/valence_packet/src/packets/play/remove_entity_status_effect_s2c.rs b/crates/valence_packet/src/packets/play/remove_entity_status_effect_s2c.rs new file mode 100644 index 000000000..867a963e3 --- /dev/null +++ b/crates/valence_packet/src/packets/play/remove_entity_status_effect_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, PartialEq, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::REMOVE_ENTITY_STATUS_EFFECT_S2C)] +pub struct RemoveEntityStatusEffectS2c { + pub entity_id: VarInt, + pub effect_id: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/remove_message_s2c.rs b/crates/valence_packet/src/packets/play/remove_message_s2c.rs new file mode 100644 index 000000000..8cc214af6 --- /dev/null +++ b/crates/valence_packet/src/packets/play/remove_message_s2c.rs @@ -0,0 +1,8 @@ +use super::chat_message_s2c::MessageSignature; +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::REMOVE_MESSAGE_S2C)] +pub struct RemoveMessageS2c<'a> { + pub signature: MessageSignature<'a>, +} diff --git a/crates/valence_packet/src/packets/play/rename_item_c2s.rs b/crates/valence_packet/src/packets/play/rename_item_c2s.rs new file mode 100644 index 000000000..dc178c2db --- /dev/null +++ b/crates/valence_packet/src/packets/play/rename_item_c2s.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::RENAME_ITEM_C2S)] +pub struct RenameItemC2s<'a> { + pub item_name: &'a str, +} diff --git a/crates/valence_packet/src/packets/play/request_command_completions_c2s.rs b/crates/valence_packet/src/packets/play/request_command_completions_c2s.rs new file mode 100644 index 000000000..257731885 --- /dev/null +++ b/crates/valence_packet/src/packets/play/request_command_completions_c2s.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::REQUEST_COMMAND_COMPLETIONS_C2S)] +pub struct RequestCommandCompletionsC2s<'a> { + pub transaction_id: VarInt, + pub text: &'a str, +} diff --git a/crates/valence_packet/src/packets/play/resource_pack_send_s2c.rs b/crates/valence_packet/src/packets/play/resource_pack_send_s2c.rs new file mode 100644 index 000000000..68e381d40 --- /dev/null +++ b/crates/valence_packet/src/packets/play/resource_pack_send_s2c.rs @@ -0,0 +1,10 @@ +use super::*; + +#[derive(Clone, PartialEq, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::RESOURCE_PACK_SEND_S2C)] +pub struct ResourcePackSendS2c<'a> { + pub url: &'a str, + pub hash: &'a str, + pub forced: bool, + pub prompt_message: Option>, +} diff --git a/crates/valence_packet/src/packets/play/resource_pack_status_c2s.rs b/crates/valence_packet/src/packets/play/resource_pack_status_c2s.rs new file mode 100644 index 000000000..10cce2ffd --- /dev/null +++ b/crates/valence_packet/src/packets/play/resource_pack_status_c2s.rs @@ -0,0 +1,14 @@ +use super::*; + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::RESOURCE_PACK_STATUS_C2S)] +pub enum ResourcePackStatusC2s { + /// The client has successfully loaded the server's resource pack. + SuccessfullyLoaded, + /// The client has declined the server's resource pack. + Declined, + /// The client has failed to download the server's resource pack. + FailedDownload, + /// The client has accepted the server's resource pack. + Accepted, +} diff --git a/crates/valence_packet/src/packets/play/rotate.rs b/crates/valence_packet/src/packets/play/rotate.rs new file mode 100644 index 000000000..8e59af07b --- /dev/null +++ b/crates/valence_packet/src/packets/play/rotate.rs @@ -0,0 +1,10 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ROTATE)] +pub struct RotateS2c { + pub entity_id: VarInt, + pub yaw: ByteAngle, + pub pitch: ByteAngle, + pub on_ground: bool, +} diff --git a/crates/valence_packet/src/packets/play/rotate_and_move_relative.rs b/crates/valence_packet/src/packets/play/rotate_and_move_relative.rs new file mode 100644 index 000000000..83d064cfa --- /dev/null +++ b/crates/valence_packet/src/packets/play/rotate_and_move_relative.rs @@ -0,0 +1,11 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::ROTATE_AND_MOVE_RELATIVE)] +pub struct RotateAndMoveRelativeS2c { + pub entity_id: VarInt, + pub delta: [i16; 3], + pub yaw: ByteAngle, + pub pitch: ByteAngle, + pub on_ground: bool, +} diff --git a/crates/valence_packet/src/packets/play/scoreboard_display_s2c.rs b/crates/valence_packet/src/packets/play/scoreboard_display_s2c.rs new file mode 100644 index 000000000..a74411cf9 --- /dev/null +++ b/crates/valence_packet/src/packets/play/scoreboard_display_s2c.rs @@ -0,0 +1,74 @@ +use super::team_s2c::TeamColor; +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SCOREBOARD_DISPLAY_S2C)] +pub struct ScoreboardDisplayS2c<'a> { + pub position: ScoreboardPosition, + pub score_name: &'a str, +} + +#[derive(Copy, Clone, PartialEq, Debug)] +pub enum ScoreboardPosition { + List, + Sidebar, + BelowName, + SidebarTeam(TeamColor), +} + +impl Encode for ScoreboardPosition { + fn encode(&self, w: impl std::io::Write) -> anyhow::Result<()> { + match self { + ScoreboardPosition::List => 0u8.encode(w), + ScoreboardPosition::Sidebar => 1u8.encode(w), + ScoreboardPosition::BelowName => 2u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Black) => 3u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::DarkBlue) => 4u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::DarkGreen) => 5u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::DarkCyan) => 6u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::DarkRed) => 7u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Purple) => 8u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Gold) => 9u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Gray) => 10u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::DarkGray) => 11u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Blue) => 12u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::BrightGreen) => 13u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Cyan) => 14u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Red) => 15u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Pink) => 16u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::Yellow) => 17u8.encode(w), + ScoreboardPosition::SidebarTeam(TeamColor::White) => 18u8.encode(w), + ScoreboardPosition::SidebarTeam(_) => { + Err(anyhow::anyhow!("Invalid scoreboard display position")) + } + } + } +} + +impl<'a> Decode<'a> for ScoreboardPosition { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let value = u8::decode(r)?; + match value { + 0 => Ok(ScoreboardPosition::List), + 1 => Ok(ScoreboardPosition::Sidebar), + 2 => Ok(ScoreboardPosition::BelowName), + 3 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Black)), + 4 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkBlue)), + 5 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkGreen)), + 6 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkCyan)), + 7 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkRed)), + 8 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Purple)), + 9 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Gold)), + 10 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Gray)), + 11 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkGray)), + 12 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Blue)), + 13 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::BrightGreen)), + 14 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Cyan)), + 15 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Red)), + 16 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Pink)), + 17 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Yellow)), + 18 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::White)), + _ => Err(anyhow::anyhow!("Invalid scoreboard display position")), + } + } +} diff --git a/crates/valence_packet/src/packets/play/scoreboard_objective_update_s2c.rs b/crates/valence_packet/src/packets/play/scoreboard_objective_update_s2c.rs new file mode 100644 index 000000000..a7e9c59fa --- /dev/null +++ b/crates/valence_packet/src/packets/play/scoreboard_objective_update_s2c.rs @@ -0,0 +1,27 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SCOREBOARD_OBJECTIVE_UPDATE_S2C)] +pub struct ScoreboardObjectiveUpdateS2c<'a> { + pub objective_name: &'a str, + pub mode: ObjectiveMode, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub enum ObjectiveMode { + Create { + objective_display_name: Text, + render_type: ObjectiveRenderType, + }, + Remove, + Update { + objective_display_name: Text, + render_type: ObjectiveRenderType, + }, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum ObjectiveRenderType { + Integer, + Hearts, +} diff --git a/crates/valence_packet/src/packets/play/scoreboard_player_update_s2c.rs b/crates/valence_packet/src/packets/play/scoreboard_player_update_s2c.rs new file mode 100644 index 000000000..c211d40a2 --- /dev/null +++ b/crates/valence_packet/src/packets/play/scoreboard_player_update_s2c.rs @@ -0,0 +1,19 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SCOREBOARD_PLAYER_UPDATE_S2C)] +pub struct ScoreboardPlayerUpdateS2c<'a> { + pub entity_name: &'a str, + pub action: ScoreboardPlayerUpdateAction<'a>, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub enum ScoreboardPlayerUpdateAction<'a> { + Update { + objective_name: &'a str, + objective_score: VarInt, + }, + Remove { + objective_name: &'a str, + }, +} diff --git a/crates/valence_packet/src/packets/play/screen_handler_property_update_s2c.rs b/crates/valence_packet/src/packets/play/screen_handler_property_update_s2c.rs new file mode 100644 index 000000000..b2f9f732f --- /dev/null +++ b/crates/valence_packet/src/packets/play/screen_handler_property_update_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SCREEN_HANDLER_PROPERTY_UPDATE_S2C)] +pub struct ScreenHandlerPropertyUpdateS2c { + pub window_id: u8, + pub property: i16, + pub value: i16, +} diff --git a/crates/valence_packet/src/packets/play/screen_handler_slot_update_s2c.rs b/crates/valence_packet/src/packets/play/screen_handler_slot_update_s2c.rs new file mode 100644 index 000000000..0e0858925 --- /dev/null +++ b/crates/valence_packet/src/packets/play/screen_handler_slot_update_s2c.rs @@ -0,0 +1,10 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SCREEN_HANDLER_SLOT_UPDATE_S2C)] +pub struct ScreenHandlerSlotUpdateS2c<'a> { + pub window_id: i8, + pub state_id: VarInt, + pub slot_idx: i16, + pub slot_data: Cow<'a, Option>, +} diff --git a/crates/valence_packet/src/packets/play/select_advancement_tab_s2c.rs b/crates/valence_packet/src/packets/play/select_advancement_tab_s2c.rs new file mode 100644 index 000000000..27ba0e128 --- /dev/null +++ b/crates/valence_packet/src/packets/play/select_advancement_tab_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SELECT_ADVANCEMENT_TAB_S2C)] +pub struct SelectAdvancementTabS2c<'a> { + pub identifier: Option>>, +} diff --git a/crates/valence_packet/src/packets/play/select_merchant_trade_c2s.rs b/crates/valence_packet/src/packets/play/select_merchant_trade_c2s.rs new file mode 100644 index 000000000..ee236634e --- /dev/null +++ b/crates/valence_packet/src/packets/play/select_merchant_trade_c2s.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SELECT_MERCHANT_TRADE_C2S)] +pub struct SelectMerchantTradeC2s { + pub selected_slot: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/server_metadata_s2c.rs b/crates/valence_packet/src/packets/play/server_metadata_s2c.rs new file mode 100644 index 000000000..08eb0b940 --- /dev/null +++ b/crates/valence_packet/src/packets/play/server_metadata_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SERVER_METADATA_S2C)] +pub struct ServerMetadataS2c<'a> { + pub motd: Cow<'a, Text>, + pub icon: Option<&'a [u8]>, + pub enforce_secure_chat: bool, +} diff --git a/crates/valence_packet/src/packets/play/set_camera_entity_s2c.rs b/crates/valence_packet/src/packets/play/set_camera_entity_s2c.rs new file mode 100644 index 000000000..e2eb2634c --- /dev/null +++ b/crates/valence_packet/src/packets/play/set_camera_entity_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SET_CAMERA_ENTITY_S2C)] +pub struct SetCameraEntityS2c { + pub entity_id: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/set_trade_offers_s2c.rs b/crates/valence_packet/src/packets/play/set_trade_offers_s2c.rs new file mode 100644 index 000000000..f5e7f3f6d --- /dev/null +++ b/crates/valence_packet/src/packets/play/set_trade_offers_s2c.rs @@ -0,0 +1,26 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SET_TRADE_OFFERS_S2C)] +pub struct SetTradeOffersS2c { + pub window_id: VarInt, + pub trades: Vec, + pub villager_level: VarInt, + pub experience: VarInt, + pub is_regular_villager: bool, + pub can_restock: bool, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct TradeOffer { + pub input_one: Option, + pub output_item: Option, + pub input_two: Option, + pub trade_disabled: bool, + pub number_of_trade_uses: i32, + pub max_trade_uses: i32, + pub xp: i32, + pub special_price: i32, + pub price_multiplier: f32, + pub demand: i32, +} diff --git a/crates/valence_packet/src/packets/play/sign_editor_open_s2c.rs b/crates/valence_packet/src/packets/play/sign_editor_open_s2c.rs new file mode 100644 index 000000000..d509c2ee6 --- /dev/null +++ b/crates/valence_packet/src/packets/play/sign_editor_open_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SIGN_EDITOR_OPEN_S2C)] +pub struct SignEditorOpenS2c { + pub location: BlockPos, +} diff --git a/crates/valence_packet/src/packets/play/simulation_distance_s2c.rs b/crates/valence_packet/src/packets/play/simulation_distance_s2c.rs new file mode 100644 index 000000000..d32efb96d --- /dev/null +++ b/crates/valence_packet/src/packets/play/simulation_distance_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SIMULATION_DISTANCE_S2C)] +pub struct SimulationDistanceS2c { + pub simulation_distance: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/spectator_teleport_c2s.rs b/crates/valence_packet/src/packets/play/spectator_teleport_c2s.rs new file mode 100644 index 000000000..8593b5448 --- /dev/null +++ b/crates/valence_packet/src/packets/play/spectator_teleport_c2s.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SPECTATOR_TELEPORT_C2S)] +pub struct SpectatorTeleportC2s { + pub target: Uuid, +} diff --git a/crates/valence_packet/src/packets/play/statistics_s2c.rs b/crates/valence_packet/src/packets/play/statistics_s2c.rs new file mode 100644 index 000000000..958c7b3ed --- /dev/null +++ b/crates/valence_packet/src/packets/play/statistics_s2c.rs @@ -0,0 +1,14 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::STATISTICS_S2C)] +pub struct StatisticsS2c { + pub statistics: Vec, +} + +#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode)] +pub struct Statistic { + pub category_id: VarInt, + pub statistic_id: VarInt, + pub value: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/stop_sound_s2c.rs b/crates/valence_packet/src/packets/play/stop_sound_s2c.rs new file mode 100644 index 000000000..85ed75ca3 --- /dev/null +++ b/crates/valence_packet/src/packets/play/stop_sound_s2c.rs @@ -0,0 +1,49 @@ +use valence_core::sound::SoundCategory; + +use super::*; + +#[derive(Clone, PartialEq, Debug, Packet)] +#[packet(id = packet_id::STOP_SOUND_S2C)] +pub struct StopSoundS2c<'a> { + pub source: Option, + pub sound: Option>>, +} + +impl Encode for StopSoundS2c<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + match (self.source, self.sound.as_ref()) { + (Some(source), Some(sound)) => { + 3i8.encode(&mut w)?; + source.encode(&mut w)?; + sound.encode(&mut w)?; + } + (None, Some(sound)) => { + 2i8.encode(&mut w)?; + sound.encode(&mut w)?; + } + (Some(source), None) => { + 1i8.encode(&mut w)?; + source.encode(&mut w)?; + } + _ => 0i8.encode(&mut w)?, + } + + Ok(()) + } +} + +impl<'a> Decode<'a> for StopSoundS2c<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let (source, sound) = match i8::decode(r)? { + 3 => ( + Some(SoundCategory::decode(r)?), + Some(>>::decode(r)?), + ), + 2 => (None, Some(>>::decode(r)?)), + 1 => (Some(SoundCategory::decode(r)?), None), + _ => (None, None), + }; + + Ok(Self { source, sound }) + } +} diff --git a/crates/valence_packet/src/packets/play/subtitle_s2c.rs b/crates/valence_packet/src/packets/play/subtitle_s2c.rs new file mode 100644 index 000000000..260240994 --- /dev/null +++ b/crates/valence_packet/src/packets/play/subtitle_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SUBTITLE_S2C)] +pub struct SubtitleS2c<'a> { + pub subtitle_text: Cow<'a, Text>, +} diff --git a/crates/valence_packet/src/packets/play/synchronize_recipes_s2c.rs b/crates/valence_packet/src/packets/play/synchronize_recipes_s2c.rs new file mode 100644 index 000000000..ac50eda20 --- /dev/null +++ b/crates/valence_packet/src/packets/play/synchronize_recipes_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SYNCHRONIZE_RECIPES_S2C)] +pub struct SynchronizeRecipesS2c<'a> { + // TODO: this should be a Vec> + pub recipes: RawBytes<'a>, +} diff --git a/crates/valence_packet/src/packets/play/synchronize_tags_s2c.rs b/crates/valence_packet/src/packets/play/synchronize_tags_s2c.rs new file mode 100644 index 000000000..68ca74cd1 --- /dev/null +++ b/crates/valence_packet/src/packets/play/synchronize_tags_s2c.rs @@ -0,0 +1,9 @@ +use valence_registry::tags::Registry; + +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SYNCHRONIZE_TAGS_S2C)] +pub struct SynchronizeTagsS2c<'a> { + pub registries: Cow<'a, [Registry]>, +} diff --git a/crates/valence_packet/src/packets/play/team_s2c.rs b/crates/valence_packet/src/packets/play/team_s2c.rs new file mode 100644 index 000000000..1cc9615b6 --- /dev/null +++ b/crates/valence_packet/src/packets/play/team_s2c.rs @@ -0,0 +1,226 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::TEAM_S2C)] +pub struct TeamS2c<'a> { + pub team_name: &'a str, + pub mode: Mode<'a>, +} + +#[derive(Clone, PartialEq, Debug)] +pub enum Mode<'a> { + CreateTeam { + team_display_name: Cow<'a, Text>, + friendly_flags: TeamFlags, + name_tag_visibility: NameTagVisibility, + collision_rule: CollisionRule, + team_color: TeamColor, + team_prefix: Cow<'a, Text>, + team_suffix: Cow<'a, Text>, + entities: Vec<&'a str>, + }, + RemoveTeam, + UpdateTeamInfo { + team_display_name: Cow<'a, Text>, + friendly_flags: TeamFlags, + name_tag_visibility: NameTagVisibility, + collision_rule: CollisionRule, + team_color: TeamColor, + team_prefix: Cow<'a, Text>, + team_suffix: Cow<'a, Text>, + }, + AddEntities { + entities: Vec<&'a str>, + }, + RemoveEntities { + entities: Vec<&'a str>, + }, +} + +impl Encode for Mode<'_> { + fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { + match self { + Mode::CreateTeam { + team_display_name, + friendly_flags, + name_tag_visibility, + collision_rule, + team_color, + team_prefix, + team_suffix, + entities, + } => { + 0i8.encode(&mut w)?; + team_display_name.encode(&mut w)?; + friendly_flags.encode(&mut w)?; + match name_tag_visibility { + NameTagVisibility::Always => "always", + NameTagVisibility::Never => "never", + NameTagVisibility::HideForOtherTeams => "hideForOtherTeams", + NameTagVisibility::HideForOwnTeam => "hideForOwnTeam", + } + .encode(&mut w)?; + match collision_rule { + CollisionRule::Always => "always", + CollisionRule::Never => "never", + CollisionRule::PushOtherTeams => "pushOtherTeams", + CollisionRule::PushOwnTeam => "pushOwnTeam", + } + .encode(&mut w)?; + team_color.encode(&mut w)?; + team_prefix.encode(&mut w)?; + team_suffix.encode(&mut w)?; + entities.encode(&mut w)?; + } + Mode::RemoveTeam => 1i8.encode(&mut w)?, + Mode::UpdateTeamInfo { + team_display_name, + friendly_flags, + name_tag_visibility, + collision_rule, + team_color, + team_prefix, + team_suffix, + } => { + 2i8.encode(&mut w)?; + team_display_name.encode(&mut w)?; + friendly_flags.encode(&mut w)?; + match name_tag_visibility { + NameTagVisibility::Always => "always", + NameTagVisibility::Never => "never", + NameTagVisibility::HideForOtherTeams => "hideForOtherTeams", + NameTagVisibility::HideForOwnTeam => "hideForOwnTeam", + } + .encode(&mut w)?; + match collision_rule { + CollisionRule::Always => "always", + CollisionRule::Never => "never", + CollisionRule::PushOtherTeams => "pushOtherTeams", + CollisionRule::PushOwnTeam => "pushOwnTeam", + } + .encode(&mut w)?; + team_color.encode(&mut w)?; + team_prefix.encode(&mut w)?; + team_suffix.encode(&mut w)?; + } + Mode::AddEntities { entities } => { + 3i8.encode(&mut w)?; + entities.encode(&mut w)?; + } + Mode::RemoveEntities { entities } => { + 4i8.encode(&mut w)?; + entities.encode(&mut w)?; + } + } + Ok(()) + } +} + +impl<'a> Decode<'a> for Mode<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + Ok(match i8::decode(r)? { + 0 => Self::CreateTeam { + team_display_name: Decode::decode(r)?, + friendly_flags: Decode::decode(r)?, + name_tag_visibility: match <&str>::decode(r)? { + "always" => NameTagVisibility::Always, + "never" => NameTagVisibility::Never, + "hideForOtherTeams" => NameTagVisibility::HideForOtherTeams, + "hideForOwnTeam" => NameTagVisibility::HideForOwnTeam, + other => bail!("unknown name tag visibility type \"{other}\""), + }, + collision_rule: match <&str>::decode(r)? { + "always" => CollisionRule::Always, + "never" => CollisionRule::Never, + "pushOtherTeams" => CollisionRule::PushOtherTeams, + "pushOwnTeam" => CollisionRule::PushOwnTeam, + other => bail!("unknown collision rule type \"{other}\""), + }, + team_color: Decode::decode(r)?, + team_prefix: Decode::decode(r)?, + team_suffix: Decode::decode(r)?, + entities: Decode::decode(r)?, + }, + 1 => Self::RemoveTeam, + 2 => Self::UpdateTeamInfo { + team_display_name: Decode::decode(r)?, + friendly_flags: Decode::decode(r)?, + name_tag_visibility: match <&str>::decode(r)? { + "always" => NameTagVisibility::Always, + "never" => NameTagVisibility::Never, + "hideForOtherTeams" => NameTagVisibility::HideForOtherTeams, + "hideForOwnTeam" => NameTagVisibility::HideForOwnTeam, + other => bail!("unknown name tag visibility type \"{other}\""), + }, + collision_rule: match <&str>::decode(r)? { + "always" => CollisionRule::Always, + "never" => CollisionRule::Never, + "pushOtherTeams" => CollisionRule::PushOtherTeams, + "pushOwnTeam" => CollisionRule::PushOwnTeam, + other => bail!("unknown collision rule type \"{other}\""), + }, + team_color: Decode::decode(r)?, + team_prefix: Decode::decode(r)?, + team_suffix: Decode::decode(r)?, + }, + 3 => Self::AddEntities { + entities: Decode::decode(r)?, + }, + 4 => Self::RemoveEntities { + entities: Decode::decode(r)?, + }, + n => bail!("unknown update teams action of {n}"), + }) + } +} + +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct TeamFlags { + pub friendly_fire: bool, + pub see_invisible_teammates: bool, + #[bits(6)] + _pad: u8, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum NameTagVisibility { + Always, + Never, + HideForOtherTeams, + HideForOwnTeam, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum CollisionRule { + Always, + Never, + PushOtherTeams, + PushOwnTeam, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum TeamColor { + Black, + DarkBlue, + DarkGreen, + DarkCyan, + DarkRed, + Purple, + Gold, + Gray, + DarkGray, + Blue, + BrightGreen, + Cyan, + Red, + Pink, + Yellow, + White, + Obfuscated, + Bold, + Strikethrough, + Underlined, + Italic, + Reset, +} diff --git a/crates/valence_packet/src/packets/play/teleport_confirm_c2s.rs b/crates/valence_packet/src/packets/play/teleport_confirm_c2s.rs new file mode 100644 index 000000000..f0fa997f1 --- /dev/null +++ b/crates/valence_packet/src/packets/play/teleport_confirm_c2s.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::TELEPORT_CONFIRM_C2S)] +pub struct TeleportConfirmC2s { + pub teleport_id: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/title_fade_s2c.rs b/crates/valence_packet/src/packets/play/title_fade_s2c.rs new file mode 100644 index 000000000..49e9763c1 --- /dev/null +++ b/crates/valence_packet/src/packets/play/title_fade_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::TITLE_FADE_S2C)] +pub struct TitleFadeS2c { + pub fade_in: i32, + pub stay: i32, + pub fade_out: i32, +} diff --git a/crates/valence_packet/src/packets/play/title_s2c.rs b/crates/valence_packet/src/packets/play/title_s2c.rs new file mode 100644 index 000000000..d121aae80 --- /dev/null +++ b/crates/valence_packet/src/packets/play/title_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::TITLE_S2C)] +pub struct TitleS2c<'a> { + pub title_text: Cow<'a, Text>, +} diff --git a/crates/valence_packet/src/packets/play/unload_chunk_s2c.rs b/crates/valence_packet/src/packets/play/unload_chunk_s2c.rs new file mode 100644 index 000000000..4292e6f9b --- /dev/null +++ b/crates/valence_packet/src/packets/play/unload_chunk_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::UNLOAD_CHUNK_S2C)] +pub struct UnloadChunkS2c { + pub pos: ChunkPos, +} diff --git a/crates/valence_packet/src/packets/play/unlock_recipes_s2c.rs b/crates/valence_packet/src/packets/play/unlock_recipes_s2c.rs new file mode 100644 index 000000000..40a4220b1 --- /dev/null +++ b/crates/valence_packet/src/packets/play/unlock_recipes_s2c.rs @@ -0,0 +1,61 @@ +use super::*; + +#[derive(Clone, PartialEq, Eq, Debug, Packet)] +#[packet(id = packet_id::UNLOCK_RECIPES_S2C)] +pub struct UnlockRecipesS2c<'a> { + pub action: UpdateRecipeBookAction<'a>, + pub crafting_recipe_book_open: bool, + pub crafting_recipe_book_filter_active: bool, + pub smelting_recipe_book_open: bool, + pub smelting_recipe_book_filter_active: bool, + pub blast_furnace_recipe_book_open: bool, + pub blast_furnace_recipe_book_filter_active: bool, + pub smoker_recipe_book_open: bool, + pub smoker_recipe_book_filter_active: bool, + pub recipe_ids: Vec>>, +} + +impl<'a> Decode<'a> for UnlockRecipesS2c<'a> { + fn decode(r: &mut &'a [u8]) -> anyhow::Result { + let action_id = VarInt::decode(r)?.0; + + let crafting_recipe_book_open = bool::decode(r)?; + let crafting_recipe_book_filter_active = bool::decode(r)?; + let smelting_recipe_book_open = bool::decode(r)?; + let smelting_recipe_book_filter_active = bool::decode(r)?; + let blast_furnace_recipe_book_open = bool::decode(r)?; + let blast_furnace_recipe_book_filter_active = bool::decode(r)?; + let smoker_recipe_book_open = bool::decode(r)?; + let smoker_recipe_book_filter_active = bool::decode(r)?; + let recipe_ids = Vec::decode(r)?; + + Ok(Self { + action: match action_id { + 0 => UpdateRecipeBookAction::Init { + recipe_ids: Vec::decode(r)?, + }, + 1 => UpdateRecipeBookAction::Add, + 2 => UpdateRecipeBookAction::Remove, + n => bail!("unknown recipe book action of {n}"), + }, + crafting_recipe_book_open, + crafting_recipe_book_filter_active, + smelting_recipe_book_open, + smelting_recipe_book_filter_active, + blast_furnace_recipe_book_open, + blast_furnace_recipe_book_filter_active, + smoker_recipe_book_open, + smoker_recipe_book_filter_active, + recipe_ids, + }) + } +} + +#[derive(Clone, PartialEq, Eq, Debug)] +pub enum UpdateRecipeBookAction<'a> { + Init { + recipe_ids: Vec>>, + }, + Add, + Remove, +} diff --git a/crates/valence_packet/src/packets/play/update_beacon_c2s.rs b/crates/valence_packet/src/packets/play/update_beacon_c2s.rs new file mode 100644 index 000000000..cb2806fb9 --- /dev/null +++ b/crates/valence_packet/src/packets/play/update_beacon_c2s.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::UPDATE_BEACON_C2S)] +pub struct UpdateBeaconC2s { + pub primary_effect: Option, + pub secondary_effect: Option, +} diff --git a/crates/valence_packet/src/packets/play/update_command_block_c2s.rs b/crates/valence_packet/src/packets/play/update_command_block_c2s.rs new file mode 100644 index 000000000..f60b8eaee --- /dev/null +++ b/crates/valence_packet/src/packets/play/update_command_block_c2s.rs @@ -0,0 +1,27 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::UPDATE_COMMAND_BLOCK_C2S)] +pub struct UpdateCommandBlockC2s<'a> { + pub position: BlockPos, + pub command: &'a str, + pub mode: UpdateCommandBlockMode, + pub flags: UpdateCommandBlockFlags, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum UpdateCommandBlockMode { + Sequence, + Auto, + Redstone, +} + +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct UpdateCommandBlockFlags { + pub track_output: bool, + pub conditional: bool, + pub automatic: bool, + #[bits(5)] + _pad: u8, +} diff --git a/crates/valence_packet/src/packets/play/update_command_block_minecart_c2s.rs b/crates/valence_packet/src/packets/play/update_command_block_minecart_c2s.rs new file mode 100644 index 000000000..8b3e1e418 --- /dev/null +++ b/crates/valence_packet/src/packets/play/update_command_block_minecart_c2s.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::UPDATE_COMMAND_BLOCK_MINECART_C2S)] +pub struct UpdateCommandBlockMinecartC2s<'a> { + pub entity_id: VarInt, + pub command: &'a str, + pub track_output: bool, +} diff --git a/crates/valence_packet/src/packets/play/update_difficulty_c2s.rs b/crates/valence_packet/src/packets/play/update_difficulty_c2s.rs new file mode 100644 index 000000000..7e70004ad --- /dev/null +++ b/crates/valence_packet/src/packets/play/update_difficulty_c2s.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::UPDATE_DIFFICULTY_C2S)] +pub struct UpdateDifficultyC2s { + pub difficulty: Difficulty, +} diff --git a/crates/valence_packet/src/packets/play/update_difficulty_lock_c2s.rs b/crates/valence_packet/src/packets/play/update_difficulty_lock_c2s.rs new file mode 100644 index 000000000..477a023ee --- /dev/null +++ b/crates/valence_packet/src/packets/play/update_difficulty_lock_c2s.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::UPDATE_DIFFICULTY_LOCK_C2S)] +pub struct UpdateDifficultyLockC2s { + pub locked: bool, +} diff --git a/crates/valence_packet/src/packets/play/update_jigsaw_c2s.rs b/crates/valence_packet/src/packets/play/update_jigsaw_c2s.rs new file mode 100644 index 000000000..144469948 --- /dev/null +++ b/crates/valence_packet/src/packets/play/update_jigsaw_c2s.rs @@ -0,0 +1,12 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::UPDATE_JIGSAW_C2S)] +pub struct UpdateJigsawC2s<'a> { + pub position: BlockPos, + pub name: Ident>, + pub target: Ident>, + pub pool: Ident>, + pub final_state: &'a str, + pub joint_type: &'a str, +} diff --git a/crates/valence_packet/src/packets/play/update_player_abilities_c2s.rs b/crates/valence_packet/src/packets/play/update_player_abilities_c2s.rs new file mode 100644 index 000000000..979e14280 --- /dev/null +++ b/crates/valence_packet/src/packets/play/update_player_abilities_c2s.rs @@ -0,0 +1,10 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::UPDATE_PLAYER_ABILITIES_C2S)] +pub enum UpdatePlayerAbilitiesC2s { + #[packet(tag = 0b00)] + StopFlying, + #[packet(tag = 0b10)] + StartFlying, +} diff --git a/crates/valence_packet/src/packets/play/update_selected_slot_c2s.rs b/crates/valence_packet/src/packets/play/update_selected_slot_c2s.rs new file mode 100644 index 000000000..445238593 --- /dev/null +++ b/crates/valence_packet/src/packets/play/update_selected_slot_c2s.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::UPDATE_SELECTED_SLOT_C2S)] +pub struct UpdateSelectedSlotC2s { + pub slot: u8, +} diff --git a/crates/valence_packet/src/packets/play/update_selected_slot_s2c.rs b/crates/valence_packet/src/packets/play/update_selected_slot_s2c.rs new file mode 100644 index 000000000..478c5015e --- /dev/null +++ b/crates/valence_packet/src/packets/play/update_selected_slot_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::UPDATE_SELECTED_SLOT_S2C)] +pub struct UpdateSelectedSlotS2c { + pub slot: u8, +} diff --git a/crates/valence_packet/src/packets/play/update_sign_c2s.rs b/crates/valence_packet/src/packets/play/update_sign_c2s.rs new file mode 100644 index 000000000..65455594c --- /dev/null +++ b/crates/valence_packet/src/packets/play/update_sign_c2s.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::UPDATE_SIGN_C2S)] +pub struct UpdateSignC2s<'a> { + pub position: BlockPos, + pub is_front_text: bool, + pub lines: [&'a str; 4], +} diff --git a/crates/valence_packet/src/packets/play/update_structure_block_c2s.rs b/crates/valence_packet/src/packets/play/update_structure_block_c2s.rs new file mode 100644 index 000000000..18d4b8679 --- /dev/null +++ b/crates/valence_packet/src/packets/play/update_structure_block_c2s.rs @@ -0,0 +1,59 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::UPDATE_STRUCTURE_BLOCK_C2S)] +pub struct UpdateStructureBlockC2s<'a> { + pub position: BlockPos, + pub action: Action, + pub mode: Mode, + pub name: &'a str, + pub offset_xyz: [i8; 3], + pub size_xyz: [i8; 3], + pub mirror: Mirror, + pub rotation: Rotation, + pub metadata: &'a str, + pub integrity: f32, + pub seed: VarLong, + pub flags: Flags, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum Action { + UpdateData, + SaveStructure, + LoadStructure, + DetectSize, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum Mode { + Save, + Load, + Corner, + Data, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum Mirror { + None, + LeftRight, + FrontBack, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum Rotation { + None, + Clockwise90, + Clockwise180, + Counterclockwise90, +} + +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct Flags { + pub ignore_entities: bool, + pub show_air: bool, + pub show_bounding_box: bool, + #[bits(5)] + _pad: u8, +} diff --git a/crates/valence_packet/src/packets/play/vehicle_move_c2s.rs b/crates/valence_packet/src/packets/play/vehicle_move_c2s.rs new file mode 100644 index 000000000..72b703a33 --- /dev/null +++ b/crates/valence_packet/src/packets/play/vehicle_move_c2s.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::VEHICLE_MOVE_C2S)] +pub struct VehicleMoveC2s { + pub position: DVec3, + pub yaw: f32, + pub pitch: f32, +} diff --git a/crates/valence_packet/src/packets/play/vehicle_move_s2c.rs b/crates/valence_packet/src/packets/play/vehicle_move_s2c.rs new file mode 100644 index 000000000..d88bca612 --- /dev/null +++ b/crates/valence_packet/src/packets/play/vehicle_move_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::VEHICLE_MOVE_S2C)] +pub struct VehicleMoveS2c { + pub position: DVec3, + pub yaw: f32, + pub pitch: f32, +} diff --git a/crates/valence_packet/src/packets/play/world_border_center_changed_s2c.rs b/crates/valence_packet/src/packets/play/world_border_center_changed_s2c.rs new file mode 100644 index 000000000..59ef07814 --- /dev/null +++ b/crates/valence_packet/src/packets/play/world_border_center_changed_s2c.rs @@ -0,0 +1,8 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::WORLD_BORDER_CENTER_CHANGED_S2C)] +pub struct WorldBorderCenterChangedS2c { + pub x_pos: f64, + pub z_pos: f64, +} diff --git a/crates/valence_packet/src/packets/play/world_border_initialize_s2c.rs b/crates/valence_packet/src/packets/play/world_border_initialize_s2c.rs new file mode 100644 index 000000000..acf3879a5 --- /dev/null +++ b/crates/valence_packet/src/packets/play/world_border_initialize_s2c.rs @@ -0,0 +1,14 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::WORLD_BORDER_INITIALIZE_S2C)] +pub struct WorldBorderInitializeS2c { + pub x: f64, + pub z: f64, + pub old_diameter: f64, + pub new_diameter: f64, + pub speed: VarLong, + pub portal_teleport_boundary: VarInt, + pub warning_blocks: VarInt, + pub warning_time: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/world_border_interpolate_size_s2c.rs b/crates/valence_packet/src/packets/play/world_border_interpolate_size_s2c.rs new file mode 100644 index 000000000..e2c593be2 --- /dev/null +++ b/crates/valence_packet/src/packets/play/world_border_interpolate_size_s2c.rs @@ -0,0 +1,9 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::WORLD_BORDER_INTERPOLATE_SIZE_S2C)] +pub struct WorldBorderInterpolateSizeS2c { + pub old_diameter: f64, + pub new_diameter: f64, + pub speed: VarLong, +} diff --git a/crates/valence_packet/src/packets/play/world_border_size_changed_s2c.rs b/crates/valence_packet/src/packets/play/world_border_size_changed_s2c.rs new file mode 100644 index 000000000..f315d96e9 --- /dev/null +++ b/crates/valence_packet/src/packets/play/world_border_size_changed_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::WORLD_BORDER_SIZE_CHANGED_S2C)] +pub struct WorldBorderSizeChangedS2c { + pub diameter: f64, +} diff --git a/crates/valence_packet/src/packets/play/world_border_warning_blocks_changed_s2c.rs b/crates/valence_packet/src/packets/play/world_border_warning_blocks_changed_s2c.rs new file mode 100644 index 000000000..b5e4aca80 --- /dev/null +++ b/crates/valence_packet/src/packets/play/world_border_warning_blocks_changed_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::WORLD_BORDER_WARNING_BLOCKS_CHANGED_S2C)] +pub struct WorldBorderWarningBlocksChangedS2c { + pub warning_blocks: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/world_border_warning_time_changed_s2c.rs b/crates/valence_packet/src/packets/play/world_border_warning_time_changed_s2c.rs new file mode 100644 index 000000000..561053f8b --- /dev/null +++ b/crates/valence_packet/src/packets/play/world_border_warning_time_changed_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::WORLD_BORDER_WARNING_TIME_CHANGED_S2C)] +pub struct WorldBorderWarningTimeChangedS2c { + pub warning_time: VarInt, +} diff --git a/crates/valence_packet/src/packets/play/world_event_s2c.rs b/crates/valence_packet/src/packets/play/world_event_s2c.rs new file mode 100644 index 000000000..d5573f1fe --- /dev/null +++ b/crates/valence_packet/src/packets/play/world_event_s2c.rs @@ -0,0 +1,10 @@ +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::WORLD_EVENT_S2C)] +pub struct WorldEventS2c { + pub event: i32, + pub location: BlockPos, + pub data: i32, + pub disable_relative_volume: bool, +} diff --git a/crates/valence_packet/src/packets/play/world_time_update_s2c.rs b/crates/valence_packet/src/packets/play/world_time_update_s2c.rs new file mode 100644 index 000000000..ae0693c7a --- /dev/null +++ b/crates/valence_packet/src/packets/play/world_time_update_s2c.rs @@ -0,0 +1,12 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::WORLD_TIME_UPDATE_S2C)] +pub struct WorldTimeUpdateS2c { + /// The age of the world in 1/20ths of a second. + pub world_age: i64, + /// The current time of day in 1/20ths of a second. + /// The value should be in the range \[0, 24000]. + /// 6000 is noon, 12000 is sunset, and 18000 is midnight. + pub time_of_day: i64, +} diff --git a/crates/valence_packet/src/packets/status/mod.rs b/crates/valence_packet/src/packets/status/mod.rs new file mode 100644 index 000000000..faffd1d23 --- /dev/null +++ b/crates/valence_packet/src/packets/status/mod.rs @@ -0,0 +1,8 @@ +use valence_core::protocol::PacketState; + +use super::*; + +pub mod query_ping_c2s; +pub mod query_pong_s2c; +pub mod query_request_c2s; +pub mod query_response_s2c; diff --git a/crates/valence_packet/src/packets/status/query_ping_c2s.rs b/crates/valence_packet/src/packets/status/query_ping_c2s.rs new file mode 100644 index 000000000..f8c8bbe33 --- /dev/null +++ b/crates/valence_packet/src/packets/status/query_ping_c2s.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::QUERY_PING_C2S, state = PacketState::Status)] +pub struct QueryPingC2s { + pub payload: u64, +} diff --git a/crates/valence_packet/src/packets/status/query_pong_s2c.rs b/crates/valence_packet/src/packets/status/query_pong_s2c.rs new file mode 100644 index 000000000..af796a074 --- /dev/null +++ b/crates/valence_packet/src/packets/status/query_pong_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::QUERY_PONG_S2C, state = PacketState::Status)] +pub struct QueryPongS2c { + pub payload: u64, +} diff --git a/crates/valence_packet/src/packets/status/query_request_c2s.rs b/crates/valence_packet/src/packets/status/query_request_c2s.rs new file mode 100644 index 000000000..ea448a7e1 --- /dev/null +++ b/crates/valence_packet/src/packets/status/query_request_c2s.rs @@ -0,0 +1,5 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::QUERY_REQUEST_C2S, state = PacketState::Status)] +pub struct QueryRequestC2s; diff --git a/crates/valence_packet/src/packets/status/query_response_s2c.rs b/crates/valence_packet/src/packets/status/query_response_s2c.rs new file mode 100644 index 000000000..c23e95e94 --- /dev/null +++ b/crates/valence_packet/src/packets/status/query_response_s2c.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::QUERY_RESPONSE_S2C, state = PacketState::Status)] +pub struct QueryResponseS2c<'a> { + pub json: &'a str, +} From aaff078d0b77fe174885a8f74e95beaeb4e659e1 Mon Sep 17 00:00:00 2001 From: Bafbi Date: Tue, 1 Aug 2023 21:35:41 +0200 Subject: [PATCH 6/9] cleaning + move `Packet` trait / macro --- Cargo.toml | 1 + crates/valence_boss_bar/src/components.rs | 53 -- crates/valence_boss_bar/src/lib.rs | 256 +++--- crates/valence_boss_bar/src/packet.rs | 30 - crates/valence_core/Cargo.toml | 2 +- crates/valence_core/build/main.rs | 3 - crates/valence_core/src/lib.rs | 3 +- crates/valence_core/src/particle.rs | 444 ---------- crates/valence_core/src/protocol.rs | 219 +---- crates/valence_core_macros/src/lib.rs | 11 +- crates/valence_packet/Cargo.toml | 20 +- .../packet_id.rs => valence_packet/build.rs} | 14 +- crates/valence_packet/src/advancement.rs | 110 --- crates/valence_packet/src/boss_bar.rs | 26 - crates/valence_packet/src/chat.rs | 239 ------ crates/valence_packet/src/client.rs | 464 ----------- crates/valence_packet/src/command.rs | 434 ---------- crates/valence_packet/src/entity.rs | 287 ------- crates/valence_packet/src/instance.rs | 139 ---- crates/valence_packet/src/inventory.rs | 778 ------------------ crates/valence_packet/src/lib.rs | 46 +- crates/valence_packet/src/map.rs | 109 --- crates/valence_packet/src/network.rs | 99 --- crates/valence_packet/src/packets.rs | 7 +- .../valence_packet/src/packets/handshaking.rs | 4 + .../src/packets/handshaking/mod.rs | 5 - crates/valence_packet/src/packets/login.rs | 18 + .../packets/login/login_compression_s2c.rs | 2 - .../valence_packet/src/packets/login/mod.rs | 12 - crates/valence_packet/src/packets/play.rs | 341 ++++++++ .../packets/play/advancement_update_s2c.rs | 2 +- .../src/packets/play/boss_bar_s2c.rs | 35 +- ...dle_splitter.rs => bundle_splitter_s2c.rs} | 0 .../src/packets/play/{full.rs => full_c2s.rs} | 0 ...on_ground.rs => look_and_on_ground_c2s.rs} | 0 crates/valence_packet/src/packets/play/mod.rs | 179 ---- ...{move_relative.rs => move_relative_s2c.rs} | 0 ...n_ground_only.rs => on_ground_only_c2s.rs} | 0 ...round.rs => position_and_on_ground_c2s.rs} | 0 ...ive.rs => rotate_and_move_relative_s2c.rs} | 0 .../packets/play/{rotate.rs => rotate_s2c.rs} | 0 crates/valence_packet/src/packets/status.rs | 10 + .../valence_packet/src/packets/status/mod.rs | 8 - crates/valence_packet/src/player_list.rs | 141 ---- crates/valence_packet/src/protocol.rs | 221 +++++ .../src/protocol/decode.rs | 3 +- .../src/protocol/encode.rs | 0 crates/valence_packet/src/scoreboard.rs | 342 -------- crates/valence_packet/src/sound.rs | 90 -- crates/valence_packet/src/world_border.rs | 47 -- crates/valence_packet_macros/Cargo.toml | 12 + crates/valence_packet_macros/README.md | 3 + crates/valence_packet_macros/src/lib.rs | 42 + .../src/packet.rs | 12 +- crates/valence_registry/Cargo.toml | 1 + crates/valence_registry/src/tags.rs | 10 +- 56 files changed, 861 insertions(+), 4473 deletions(-) delete mode 100644 crates/valence_boss_bar/src/packet.rs delete mode 100644 crates/valence_core/src/particle.rs rename crates/{valence_core/build/packet_id.rs => valence_packet/build.rs} (71%) delete mode 100644 crates/valence_packet/src/advancement.rs delete mode 100644 crates/valence_packet/src/boss_bar.rs delete mode 100644 crates/valence_packet/src/chat.rs delete mode 100644 crates/valence_packet/src/client.rs delete mode 100644 crates/valence_packet/src/command.rs delete mode 100644 crates/valence_packet/src/entity.rs delete mode 100644 crates/valence_packet/src/instance.rs delete mode 100644 crates/valence_packet/src/inventory.rs delete mode 100644 crates/valence_packet/src/map.rs delete mode 100644 crates/valence_packet/src/network.rs create mode 100644 crates/valence_packet/src/packets/handshaking.rs delete mode 100644 crates/valence_packet/src/packets/handshaking/mod.rs create mode 100644 crates/valence_packet/src/packets/login.rs delete mode 100644 crates/valence_packet/src/packets/login/mod.rs create mode 100644 crates/valence_packet/src/packets/play.rs rename crates/valence_packet/src/packets/play/{bundle_splitter.rs => bundle_splitter_s2c.rs} (100%) rename crates/valence_packet/src/packets/play/{full.rs => full_c2s.rs} (100%) rename crates/valence_packet/src/packets/play/{look_and_on_ground.rs => look_and_on_ground_c2s.rs} (100%) delete mode 100644 crates/valence_packet/src/packets/play/mod.rs rename crates/valence_packet/src/packets/play/{move_relative.rs => move_relative_s2c.rs} (100%) rename crates/valence_packet/src/packets/play/{on_ground_only.rs => on_ground_only_c2s.rs} (100%) rename crates/valence_packet/src/packets/play/{position_and_on_ground.rs => position_and_on_ground_c2s.rs} (100%) rename crates/valence_packet/src/packets/play/{rotate_and_move_relative.rs => rotate_and_move_relative_s2c.rs} (100%) rename crates/valence_packet/src/packets/play/{rotate.rs => rotate_s2c.rs} (100%) create mode 100644 crates/valence_packet/src/packets/status.rs delete mode 100644 crates/valence_packet/src/packets/status/mod.rs delete mode 100644 crates/valence_packet/src/player_list.rs create mode 100644 crates/valence_packet/src/protocol.rs rename crates/{valence_core => valence_packet}/src/protocol/decode.rs (99%) rename crates/{valence_core => valence_packet}/src/protocol/encode.rs (100%) delete mode 100644 crates/valence_packet/src/scoreboard.rs delete mode 100644 crates/valence_packet/src/sound.rs delete mode 100644 crates/valence_packet/src/world_border.rs create mode 100644 crates/valence_packet_macros/Cargo.toml create mode 100644 crates/valence_packet_macros/README.md create mode 100644 crates/valence_packet_macros/src/lib.rs rename crates/{valence_core_macros => valence_packet_macros}/src/packet.rs (86%) diff --git a/Cargo.toml b/Cargo.toml index 84bf5ce5a..500c5aaf0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -168,6 +168,7 @@ valence_block.path = "crates/valence_block" valence_build_utils.path = "crates/valence_build_utils" valence_client.path = "crates/valence_client" valence_core_macros.path = "crates/valence_core_macros" +valence_packet_macros.path = "crates/valence_packet_macros" valence_core.path = "crates/valence_core" valence_dimension.path = "crates/valence_dimension" valence_entity.path = "crates/valence_entity" diff --git a/crates/valence_boss_bar/src/components.rs b/crates/valence_boss_bar/src/components.rs index 86f422e45..3657f6b98 100644 --- a/crates/valence_boss_bar/src/components.rs +++ b/crates/valence_boss_bar/src/components.rs @@ -6,50 +6,7 @@ use valence_core::protocol::{Decode, Encode}; use valence_core::text::Text; use valence_core::uuid::UniqueId; -/// The bundle of components that make up a boss bar. -#[derive(Bundle)] -pub struct BossBarBundle { - pub id: UniqueId, - pub title: BossBarTitle, - pub health: BossBarHealth, - pub style: BossBarStyle, - pub flags: BossBarFlags, - pub viewers: BossBarViewers, -} - -impl BossBarBundle { - pub fn new( - title: Text, - color: BossBarColor, - division: BossBarDivision, - flags: BossBarFlags, - ) -> BossBarBundle { - BossBarBundle { - id: UniqueId::default(), - title: BossBarTitle(title), - health: BossBarHealth(1.0), - style: BossBarStyle { color, division }, - flags, - viewers: BossBarViewers::default(), - } - } -} - -/// The title of a boss bar. -#[derive(Component, Clone)] -pub struct BossBarTitle(pub Text); -/// The health of a boss bar. -#[derive(Component)] -pub struct BossBarHealth(pub f32); - -/// The style of a boss bar. This includes the color and division of the boss -/// bar. -#[derive(Component)] -pub struct BossBarStyle { - pub color: BossBarColor, - pub division: BossBarDivision, -} /// The color of a boss bar. #[derive(Component, Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] @@ -84,13 +41,3 @@ pub struct BossBarFlags { _pad: u8, } -/// The viewers of a boss bar. -#[derive(Component, Default)] -pub struct BossBarViewers { - /// The current viewers of the boss bar. It is the list that should be - /// updated. - pub viewers: BTreeSet, - /// The viewers of the last tick in order to determine which viewers have - /// been added and removed. - pub(crate) old_viewers: BTreeSet, -} diff --git a/crates/valence_boss_bar/src/lib.rs b/crates/valence_boss_bar/src/lib.rs index a815d0205..b2e199d1c 100644 --- a/crates/valence_boss_bar/src/lib.rs +++ b/crates/valence_boss_bar/src/lib.rs @@ -19,86 +19,61 @@ )] use std::borrow::Cow; -use std::collections::BTreeSet; use bevy_app::prelude::*; use bevy_ecs::prelude::*; use valence_client::{Client, FlushPacketsSet}; -use valence_core::boss_bar::{BossBarColor, BossBarDivision, BossBarFlags}; use valence_core::despawn::Despawned; use valence_core::protocol::encode::WritePacket; -use valence_core::text::Text; use valence_core::uuid::UniqueId; -use valence_packet::boss_bar::{BossBarAction, BossBarS2c}; -#[derive(Clone, Debug)] -enum BossBarUpdate { - Health(f32), - Title(Text), - Style(BossBarColor, BossBarDivision), - Flags(BossBarFlags), -} - -#[derive(Clone, Debug, Component)] -pub struct BossBar { - pub title: Text, - /// From 0 to 1. Values greater than 1 do not crash a Notchian client, and - /// start rendering part of a second health bar at around 1.5 - pub health: f32, - pub color: BossBarColor, - pub division: BossBarDivision, +/// The bundle of components that make up a boss bar. +#[derive(Bundle)] +pub struct BossBarBundle { + pub id: UniqueId, + pub title: BossBarTitle, + pub health: BossBarHealth, + pub style: BossBarStyle, pub flags: BossBarFlags, - update: Vec, + pub viewers: BossBarViewers, } -impl BossBar { - fn new( +impl BossBarBundle { + pub fn new( title: Text, - health: f32, color: BossBarColor, division: BossBarDivision, flags: BossBarFlags, - ) -> Self { - Self { - title, - health, - color, - division, + ) -> BossBarBundle { + BossBarBundle { + id: UniqueId::default(), + title: BossBarTitle(title), + health: BossBarHealth(1.0), + style: BossBarStyle { color, division }, flags, - update: Vec::new(), + viewers: BossBarViewers::default(), } } +} - pub fn update_health(&mut self, health: f32) { - self.health = health; - self.update.push(BossBarUpdate::Health(health)); - } - - pub fn update_title(&mut self, title: Text) { - let cloned_title = title.clone(); - self.title = title; - self.update.push(BossBarUpdate::Title(cloned_title)); - } +/// The title of a boss bar. +#[derive(Component, Clone)] +pub struct BossBarTitle(pub Text); - pub fn update_style(&mut self, color: Option, division: Option) { - if let Some(color) = color { - self.color = color; - } - if let Some(division) = division { - self.division = division; - } - self.update - .push(BossBarUpdate::Style(self.color, self.division)); - } +/// The health of a boss bar. +#[derive(Component)] +pub struct BossBarHealth(pub f32); - pub fn update_flags(&mut self, flags: BossBarFlags) { - self.flags = flags; - self.update.push(BossBarUpdate::Flags(flags)); - } +/// The style of a boss bar. This includes the color and division of the boss +/// bar. +#[derive(Component)] +pub struct BossBarStyle { + pub color: BossBarColor, + pub division: BossBarDivision, } /// The viewers of a boss bar. -#[derive(Component, Default, Debug, Clone)] +#[derive(Component, Default)] pub struct BossBarViewers { /// The current viewers of the boss bar. It is the list that should be /// updated. @@ -108,49 +83,6 @@ pub struct BossBarViewers { pub(crate) old_viewers: BTreeSet, } -#[derive(Bundle, Debug)] -pub struct BossBarBundle { - boss_bar: BossBar, - unique_id: UniqueId, - viewers: BossBarViewers, -} - -impl BossBarBundle { - pub fn new( - title: Text, - health: f32, - color: BossBarColor, - division: BossBarDivision, - flags: BossBarFlags, - ) -> Self { - Self { - boss_bar: BossBar::new(title, health, color, division, flags), - unique_id: UniqueId::default(), - viewers: BossBarViewers::default(), - } - } -} - -// #[derive(Debug, Component, Default)] -// struct VisibleBossBar(pub BTreeSet); - -// #[derive(Debug, Component, Default)] -// struct OldVisibleBossBar(BTreeSet); - -// #[derive(Debug, Bundle, Default)] -// pub struct VisibleBossBarBundle { -// visible_boss_bar: VisibleBossBar, -// old_visible_boss_bar: OldVisibleBossBar, -// } - -// impl VisibleBossBarBundle { -// pub fn new(boss_bar_ids: Vec) -> Self { -// Self { -// visible_boss_bar: -// VisibleBossBar(boss_bar_ids.into_iter().collect()), -// ..Default::default() } -// } -// } pub struct BossBarPlugin; @@ -159,7 +91,10 @@ impl Plugin for BossBarPlugin { app.add_systems( PostUpdate, ( - update_boss_bar, + boss_bar_title_update, + boss_bar_health_update, + boss_bar_style_update, + boss_bar_flags_update, boss_bar_viewers_update, boss_bar_despawn, client_disconnection.before(boss_bar_viewers_update), @@ -169,54 +104,95 @@ impl Plugin for BossBarPlugin { } } -fn update_boss_bar( - mut boss_bars: Query<(&UniqueId, &mut BossBar, &BossBarViewers), Changed>, +/// System that sends a bossbar update title packet to all viewers of a boss bar +/// that has had its title updated. +fn boss_bar_title_update( + boss_bars: Query<(&UniqueId, &BossBarTitle, &BossBarViewers), Changed>, mut clients: Query<&mut Client>, ) { - for (id, mut boss_bar, boss_bar_viewers) in boss_bars.iter_mut() { + for (id, title, boss_bar_viewers) in boss_bars.iter() { for viewer in boss_bar_viewers.viewers.iter() { if let Ok(mut client) = clients.get_mut(*viewer) { - for update in boss_bar.update.clone().into_iter() { - match update { - BossBarUpdate::Health(health) => { - client.write_packet(&BossBarS2c { - id: id.0, - action: BossBarAction::UpdateHealth(health), - }); - } - BossBarUpdate::Title(title) => { - client.write_packet(&BossBarS2c { - id: id.0, - action: BossBarAction::UpdateTitle(Cow::Borrowed(&title)), - }); - } - BossBarUpdate::Style(color, division) => { - client.write_packet(&BossBarS2c { - id: id.0, - action: BossBarAction::UpdateStyle(color, division), - }); - } - BossBarUpdate::Flags(flags) => { - client.write_packet(&BossBarS2c { - id: id.0, - action: BossBarAction::UpdateFlags(flags), - }); - } - } - } + client.write_packet(&BossBarS2c { + id: id.0, + action: BossBarAction::UpdateTitle(Cow::Borrowed(&title.0)), + }); + } + } + } +} + +/// System that sends a bossbar update health packet to all viewers of a boss +/// bar that has had its health updated. +fn boss_bar_health_update( + boss_bars: Query<(&UniqueId, &BossBarHealth, &BossBarViewers), Changed>, + mut clients: Query<&mut Client>, +) { + for (id, health, boss_bar_viewers) in boss_bars.iter() { + for viewer in boss_bar_viewers.viewers.iter() { + if let Ok(mut client) = clients.get_mut(*viewer) { + client.write_packet(&BossBarS2c { + id: id.0, + action: BossBarAction::UpdateHealth(health.0), + }); + } + } + } +} + +/// System that sends a bossbar update style packet to all viewers of a boss bar +/// that has had its style updated. +fn boss_bar_style_update( + boss_bars: Query<(&UniqueId, &BossBarStyle, &BossBarViewers), Changed>, + mut clients: Query<&mut Client>, +) { + for (id, style, boss_bar_viewers) in boss_bars.iter() { + for viewer in boss_bar_viewers.viewers.iter() { + if let Ok(mut client) = clients.get_mut(*viewer) { + client.write_packet(&BossBarS2c { + id: id.0, + action: BossBarAction::UpdateStyle(style.color, style.division), + }); + } + } + } +} + +/// System that sends a bossbar update flags packet to all viewers of a boss bar +/// that has had its flags updated. +fn boss_bar_flags_update( + boss_bars: Query<(&UniqueId, &BossBarFlags, &BossBarViewers), Changed>, + mut clients: Query<&mut Client>, +) { + for (id, flags, boss_bar_viewers) in boss_bars.iter() { + for viewer in boss_bar_viewers.viewers.iter() { + if let Ok(mut client) = clients.get_mut(*viewer) { + client.write_packet(&BossBarS2c { + id: id.0, + action: BossBarAction::UpdateFlags(*flags), + }); } } - boss_bar.update.clear(); } } /// System that sends a bossbar add/remove packet to all viewers of a boss bar /// that just have been added/removed. fn boss_bar_viewers_update( - mut boss_bars: Query<(&UniqueId, &BossBar, &mut BossBarViewers), Changed>, + mut boss_bars: Query< + ( + &UniqueId, + &BossBarTitle, + &BossBarHealth, + &BossBarStyle, + &BossBarFlags, + &mut BossBarViewers, + ), + Changed, + >, mut clients: Query<&mut Client>, ) { - for (id, boss_bar, mut boss_bar_viewers) in boss_bars.iter_mut() { + for (id, title, health, style, flags, mut boss_bar_viewers) in boss_bars.iter_mut() { let old_viewers = &boss_bar_viewers.old_viewers; let current_viewers = &boss_bar_viewers.viewers; @@ -225,11 +201,11 @@ fn boss_bar_viewers_update( client.write_packet(&BossBarS2c { id: id.0, action: BossBarAction::Add { - title: Cow::Borrowed(&boss_bar.title), - health: boss_bar.health, - color: boss_bar.color, - division: boss_bar.division, - flags: boss_bar.flags, + title: Cow::Borrowed(&title.0), + health: health.0, + color: style.color, + division: style.division, + flags: *flags, }, }); } @@ -277,4 +253,4 @@ fn client_disconnection( boss_bar_viewers.viewers.remove(&entity); } } -} +} \ No newline at end of file diff --git a/crates/valence_boss_bar/src/packet.rs b/crates/valence_boss_bar/src/packet.rs deleted file mode 100644 index ef87b82ef..000000000 --- a/crates/valence_boss_bar/src/packet.rs +++ /dev/null @@ -1,30 +0,0 @@ -use std::borrow::Cow; - -use uuid::Uuid; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; -use valence_core::text::Text; - -use crate::components::{BossBarColor, BossBarDivision, BossBarFlags}; - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::BOSS_BAR_S2C)] -pub struct BossBarS2c<'a> { - pub id: Uuid, - pub action: BossBarAction<'a>, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub enum BossBarAction<'a> { - Add { - title: Cow<'a, Text>, - health: f32, - color: BossBarColor, - division: BossBarDivision, - flags: BossBarFlags, - }, - Remove, - UpdateHealth(f32), - UpdateTitle(Cow<'a, Text>), - UpdateStyle(BossBarColor, BossBarDivision), - UpdateFlags(BossBarFlags), -} diff --git a/crates/valence_core/Cargo.toml b/crates/valence_core/Cargo.toml index 4430321a6..7c3f94964 100644 --- a/crates/valence_core/Cargo.toml +++ b/crates/valence_core/Cargo.toml @@ -32,7 +32,7 @@ rand.workspace = true [dev-dependencies] rand.workspace = true -valence_core = { workspace = true, features = ["compression"] } +# valence_core = { workspace = true, features = ["compression"] } [build-dependencies] anyhow.workspace = true diff --git a/crates/valence_core/build/main.rs b/crates/valence_core/build/main.rs index fc1c1f81f..f77de4bb3 100644 --- a/crates/valence_core/build/main.rs +++ b/crates/valence_core/build/main.rs @@ -2,14 +2,12 @@ use valence_build_utils::{rerun_if_changed, write_generated_file}; mod chunk_pos; mod item; -mod packet_id; mod sound; mod translation_key; pub fn main() -> anyhow::Result<()> { rerun_if_changed([ "../../extracted/items.json", - "../../extracted/packets.json", "../../extracted/sounds.json", "../../extracted/translation_keys.json", ]); @@ -17,7 +15,6 @@ pub fn main() -> anyhow::Result<()> { write_generated_file(item::build()?, "item.rs")?; write_generated_file(sound::build()?, "sound.rs")?; write_generated_file(translation_key::build()?, "translation_key.rs")?; - write_generated_file(packet_id::build()?, "packet_id.rs")?; write_generated_file(chunk_pos::build(), "chunk_pos.rs")?; Ok(()) diff --git a/crates/valence_core/src/lib.rs b/crates/valence_core/src/lib.rs index e6e4fc9b5..f32ae8791 100644 --- a/crates/valence_core/src/lib.rs +++ b/crates/valence_core/src/lib.rs @@ -29,7 +29,6 @@ pub mod game_mode; pub mod hand; pub mod ident; pub mod item; -pub mod particle; pub mod player_textures; pub mod property; pub mod protocol; @@ -54,7 +53,7 @@ pub mod __private { pub use anyhow::{anyhow, bail, ensure, Context, Result}; pub use crate::protocol::var_int::VarInt; - pub use crate::protocol::{Decode, Encode, Packet}; + pub use crate::protocol::{Decode, Encode}; } // Needed to make proc macros work. diff --git a/crates/valence_core/src/particle.rs b/crates/valence_core/src/particle.rs deleted file mode 100644 index a07adde63..000000000 --- a/crates/valence_core/src/particle.rs +++ /dev/null @@ -1,444 +0,0 @@ -use std::borrow::Cow; -use std::io::Write; - -use anyhow::bail; -use glam::{DVec3, Vec3}; - -use crate::block_pos::BlockPos; -use crate::item::ItemStack; -use crate::protocol::var_int::VarInt; -use crate::protocol::{packet_id, Decode, Encode, Packet}; - -#[derive(Clone, PartialEq, Debug)] -pub enum Particle { - AmbientEntityEffect, - AngryVillager, - Block(i32), // TODO: use BlockState type. - BlockMarker(i32), // TODO: use BlockState type. - Bubble, - Cloud, - Crit, - DamageIndicator, - DragonBreath, - DrippingLava, - FallingLava, - LandingLava, - DrippingWater, - FallingWater, - Dust { - rgb: Vec3, - scale: f32, - }, - DustColorTransition { - from_rgb: Vec3, - scale: f32, - to_rgb: Vec3, - }, - Effect, - ElderGuardian, - EnchantedHit, - Enchant, - EndRod, - EntityEffect, - ExplosionEmitter, - Explosion, - SonicBoom, - FallingDust(i32), // TODO: use BlockState type. - Firework, - Fishing, - Flame, - CherryLeaves, - SculkSoul, - SculkCharge { - roll: f32, - }, - SculkChargePop, - SoulFireFlame, - Soul, - Flash, - HappyVillager, - Composter, - Heart, - InstantEffect, - Item(Option), - /// The 'Block' variant of the 'Vibration' particle - VibrationBlock { - block_pos: BlockPos, - ticks: i32, - }, - /// The 'Entity' variant of the 'Vibration' particle - VibrationEntity { - entity_id: i32, - entity_eye_height: f32, - ticks: i32, - }, - ItemSlime, - ItemSnowball, - LargeSmoke, - Lava, - Mycelium, - Note, - Poof, - Portal, - Rain, - Smoke, - Sneeze, - Spit, - SquidInk, - SweepAttack, - TotemOfUndying, - Underwater, - Splash, - Witch, - BubblePop, - CurrentDown, - BubbleColumnUp, - Nautilus, - Dolphin, - CampfireCosySmoke, - CampfireSignalSmoke, - DrippingHoney, - FallingHoney, - LandingHoney, - FallingNectar, - FallingSporeBlossom, - Ash, - CrimsonSpore, - WarpedSpore, - SporeBlossomAir, - DrippingObsidianTear, - FallingObsidianTear, - LandingObsidianTear, - ReversePortal, - WhiteAsh, - SmallFlame, - Snowflake, - DrippingDripstoneLava, - FallingDripstoneLava, - DrippingDripstoneWater, - FallingDripstoneWater, - GlowSquidInk, - Glow, - WaxOn, - WaxOff, - ElectricSpark, - Scrape, - Shriek { - delay: i32, - }, - EggCrack, -} - -impl Particle { - pub const fn id(&self) -> i32 { - match self { - Particle::AmbientEntityEffect => 0, - Particle::AngryVillager => 1, - Particle::Block(_) => 2, - Particle::BlockMarker(_) => 3, - Particle::Bubble => 4, - Particle::Cloud => 5, - Particle::Crit => 6, - Particle::DamageIndicator => 7, - Particle::DragonBreath => 8, - Particle::DrippingLava => 9, - Particle::FallingLava => 10, - Particle::LandingLava => 11, - Particle::DrippingWater => 12, - Particle::FallingWater => 13, - Particle::Dust { .. } => 14, - Particle::DustColorTransition { .. } => 15, - Particle::Effect => 16, - Particle::ElderGuardian => 17, - Particle::EnchantedHit => 18, - Particle::Enchant => 19, - Particle::EndRod => 20, - Particle::EntityEffect => 21, - Particle::ExplosionEmitter => 22, - Particle::Explosion => 23, - Particle::SonicBoom => 24, - Particle::FallingDust(_) => 25, - Particle::Firework => 26, - Particle::Fishing => 27, - Particle::Flame => 28, - Particle::CherryLeaves => 29, - Particle::SculkSoul => 30, - Particle::SculkCharge { .. } => 31, - Particle::SculkChargePop => 32, - Particle::SoulFireFlame => 33, - Particle::Soul => 34, - Particle::Flash => 35, - Particle::HappyVillager => 36, - Particle::Composter => 37, - Particle::Heart => 38, - Particle::InstantEffect => 39, - Particle::Item { .. } => 40, - Particle::VibrationBlock { .. } => 41, - Particle::VibrationEntity { .. } => 41, - Particle::ItemSlime => 42, - Particle::ItemSnowball => 43, - Particle::LargeSmoke => 44, - Particle::Lava => 45, - Particle::Mycelium => 46, - Particle::Note => 47, - Particle::Poof => 48, - Particle::Portal => 49, - Particle::Rain => 50, - Particle::Smoke => 51, - Particle::Sneeze => 52, - Particle::Spit => 53, - Particle::SquidInk => 54, - Particle::SweepAttack => 55, - Particle::TotemOfUndying => 56, - Particle::Underwater => 57, - Particle::Splash => 58, - Particle::Witch => 59, - Particle::BubblePop => 60, - Particle::CurrentDown => 61, - Particle::BubbleColumnUp => 62, - Particle::Nautilus => 63, - Particle::Dolphin => 64, - Particle::CampfireCosySmoke => 65, - Particle::CampfireSignalSmoke => 66, - Particle::DrippingHoney => 67, - Particle::FallingHoney => 68, - Particle::LandingHoney => 69, - Particle::FallingNectar => 70, - Particle::FallingSporeBlossom => 71, - Particle::Ash => 72, - Particle::CrimsonSpore => 73, - Particle::WarpedSpore => 74, - Particle::SporeBlossomAir => 75, - Particle::DrippingObsidianTear => 76, - Particle::FallingObsidianTear => 77, - Particle::LandingObsidianTear => 78, - Particle::ReversePortal => 79, - Particle::WhiteAsh => 80, - Particle::SmallFlame => 81, - Particle::Snowflake => 82, - Particle::DrippingDripstoneLava => 83, - Particle::FallingDripstoneLava => 84, - Particle::DrippingDripstoneWater => 85, - Particle::FallingDripstoneWater => 86, - Particle::GlowSquidInk => 87, - Particle::Glow => 88, - Particle::WaxOn => 89, - Particle::WaxOff => 80, - Particle::ElectricSpark => 91, - Particle::Scrape => 92, - Particle::Shriek { .. } => 93, - Particle::EggCrack => 94, - } - } - - /// Decodes the particle assuming the given particle ID. - pub fn decode_with_id(particle_id: i32, r: &mut &[u8]) -> anyhow::Result { - Ok(match particle_id { - 0 => Particle::AmbientEntityEffect, - 1 => Particle::AngryVillager, - 2 => Particle::Block(VarInt::decode(r)?.0), - 3 => Particle::BlockMarker(VarInt::decode(r)?.0), - 4 => Particle::Bubble, - 5 => Particle::Cloud, - 6 => Particle::Crit, - 7 => Particle::DamageIndicator, - 8 => Particle::DragonBreath, - 9 => Particle::DrippingLava, - 10 => Particle::FallingLava, - 11 => Particle::LandingLava, - 12 => Particle::DrippingWater, - 13 => Particle::FallingWater, - 14 => Particle::Dust { - rgb: Decode::decode(r)?, - scale: Decode::decode(r)?, - }, - 15 => Particle::DustColorTransition { - from_rgb: Decode::decode(r)?, - scale: Decode::decode(r)?, - to_rgb: Decode::decode(r)?, - }, - 16 => Particle::Effect, - 17 => Particle::ElderGuardian, - 18 => Particle::EnchantedHit, - 19 => Particle::Enchant, - 20 => Particle::EndRod, - 21 => Particle::EntityEffect, - 22 => Particle::ExplosionEmitter, - 23 => Particle::Explosion, - 24 => Particle::SonicBoom, - 25 => Particle::FallingDust(VarInt::decode(r)?.0), - 26 => Particle::Firework, - 27 => Particle::Fishing, - 28 => Particle::Flame, - 29 => Particle::CherryLeaves, - 30 => Particle::SculkSoul, - 31 => Particle::SculkCharge { - roll: f32::decode(r)?, - }, - 32 => Particle::SculkChargePop, - 33 => Particle::SoulFireFlame, - 34 => Particle::Soul, - 35 => Particle::Flash, - 36 => Particle::HappyVillager, - 37 => Particle::Composter, - 38 => Particle::Heart, - 39 => Particle::InstantEffect, - 40 => Particle::Item(Decode::decode(r)?), - 41 => match <&str>::decode(r)? { - "block" => Particle::VibrationBlock { - block_pos: BlockPos::decode(r)?, - ticks: VarInt::decode(r)?.0, - }, - "entity" => Particle::VibrationEntity { - entity_id: VarInt::decode(r)?.0, - entity_eye_height: f32::decode(r)?, - ticks: VarInt::decode(r)?.0, - }, - invalid => bail!("invalid vibration position source of \"{invalid}\""), - }, - 42 => Particle::ItemSlime, - 43 => Particle::ItemSnowball, - 44 => Particle::LargeSmoke, - 45 => Particle::Lava, - 46 => Particle::Mycelium, - 47 => Particle::Note, - 48 => Particle::Poof, - 49 => Particle::Portal, - 50 => Particle::Rain, - 51 => Particle::Smoke, - 52 => Particle::Sneeze, - 53 => Particle::Spit, - 54 => Particle::SquidInk, - 55 => Particle::SweepAttack, - 56 => Particle::TotemOfUndying, - 57 => Particle::Underwater, - 58 => Particle::Splash, - 59 => Particle::Witch, - 60 => Particle::BubblePop, - 61 => Particle::CurrentDown, - 62 => Particle::BubbleColumnUp, - 63 => Particle::Nautilus, - 64 => Particle::Dolphin, - 65 => Particle::CampfireCosySmoke, - 66 => Particle::CampfireSignalSmoke, - 67 => Particle::DrippingHoney, - 68 => Particle::FallingHoney, - 69 => Particle::LandingHoney, - 70 => Particle::FallingNectar, - 71 => Particle::FallingSporeBlossom, - 72 => Particle::Ash, - 73 => Particle::CrimsonSpore, - 74 => Particle::WarpedSpore, - 75 => Particle::SporeBlossomAir, - 76 => Particle::DrippingObsidianTear, - 77 => Particle::FallingObsidianTear, - 78 => Particle::LandingObsidianTear, - 79 => Particle::ReversePortal, - 80 => Particle::WhiteAsh, - 81 => Particle::SmallFlame, - 82 => Particle::Snowflake, - 83 => Particle::DrippingDripstoneLava, - 84 => Particle::FallingDripstoneLava, - 85 => Particle::DrippingDripstoneWater, - 86 => Particle::FallingDripstoneWater, - 87 => Particle::GlowSquidInk, - 88 => Particle::Glow, - 89 => Particle::WaxOn, - 90 => Particle::WaxOff, - 91 => Particle::ElectricSpark, - 92 => Particle::Scrape, - 93 => Particle::Shriek { - delay: VarInt::decode(r)?.0, - }, - 94 => Particle::EggCrack, - id => bail!("invalid particle ID of {id}"), - }) - } -} - -#[derive(Clone, Debug, Packet)] -#[packet(id = packet_id::PARTICLE_S2C)] -pub struct ParticleS2c<'a> { - pub particle: Cow<'a, Particle>, - pub long_distance: bool, - pub position: DVec3, - pub offset: Vec3, - pub max_speed: f32, - pub count: i32, -} - -impl Encode for ParticleS2c<'_> { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - VarInt(self.particle.id()).encode(&mut w)?; - self.long_distance.encode(&mut w)?; - self.position.encode(&mut w)?; - self.offset.encode(&mut w)?; - self.max_speed.encode(&mut w)?; - self.count.encode(&mut w)?; - - self.particle.as_ref().encode(w) - } -} - -impl<'a> Decode<'a> for ParticleS2c<'a> { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - let particle_id = VarInt::decode(r)?.0; - let long_distance = bool::decode(r)?; - let position = Decode::decode(r)?; - let offset = Decode::decode(r)?; - let max_speed = f32::decode(r)?; - let particle_count = i32::decode(r)?; - - Ok(Self { - particle: Cow::Owned(Particle::decode_with_id(particle_id, r)?), - long_distance, - position, - offset, - max_speed, - count: particle_count, - }) - } -} - -/// Encodes the particle without an ID. -impl Encode for Particle { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - match self { - Particle::Block(block_state) => VarInt(*block_state).encode(w), - Particle::BlockMarker(block_state) => VarInt(*block_state).encode(w), - Particle::Dust { rgb, scale } => { - rgb.encode(&mut w)?; - scale.encode(w) - } - Particle::DustColorTransition { - from_rgb, - scale, - to_rgb, - } => { - from_rgb.encode(&mut w)?; - scale.encode(&mut w)?; - to_rgb.encode(w) - } - Particle::FallingDust(block_state) => VarInt(*block_state).encode(w), - Particle::SculkCharge { roll } => roll.encode(w), - Particle::Item(stack) => stack.encode(w), - Particle::VibrationBlock { block_pos, ticks } => { - "block".encode(&mut w)?; - block_pos.encode(&mut w)?; - VarInt(*ticks).encode(w) - } - Particle::VibrationEntity { - entity_id, - entity_eye_height, - ticks, - } => { - "entity".encode(&mut w)?; - VarInt(*entity_id).encode(&mut w)?; - entity_eye_height.encode(&mut w)?; - VarInt(*ticks).encode(w) - } - Particle::Shriek { delay } => VarInt(*delay).encode(w), - _ => Ok(()), - } - } -} diff --git a/crates/valence_core/src/protocol.rs b/crates/valence_core/src/protocol.rs index 6998c2c43..fc0c5935b 100644 --- a/crates/valence_core/src/protocol.rs +++ b/crates/valence_core/src/protocol.rs @@ -2,8 +2,6 @@ pub mod array; pub mod byte_angle; -pub mod decode; -pub mod encode; pub mod global_pos; pub mod impls; pub mod raw; @@ -12,9 +10,7 @@ pub mod var_long; use std::io::Write; -use anyhow::Context; -pub use valence_core_macros::{Decode, Encode, Packet}; -use var_int::VarInt; +pub use valence_core_macros::{Decode, Encode}; /// The maximum number of bytes in a single Minecraft packet. pub const MAX_PACKET_SIZE: i32 = 2097152; @@ -158,215 +154,4 @@ pub trait Decode<'a>: Sized { /// Implementations of `Decode` are expected to shrink the slice from the /// front as bytes are read. fn decode(r: &mut &'a [u8]) -> anyhow::Result; -} - -/// Types considered to be Minecraft packets. -/// -/// In serialized form, a packet begins with a [`VarInt`] packet ID followed by -/// the body of the packet. If present, the implementations of [`Encode`] and -/// [`Decode`] on `Self` are expected to only encode/decode the _body_ of this -/// packet without the leading ID. -pub trait Packet: std::fmt::Debug { - /// The leading VarInt ID of this packet. - const ID: i32; - /// The name of this packet for debugging purposes. - const NAME: &'static str; - /// The side this packet is intended for - const SIDE: PacketSide; - /// The state which this packet is used - const STATE: PacketState; - - /// Encodes this packet's VarInt ID first, followed by the packet's body. - fn encode_with_id(&self, mut w: impl Write) -> anyhow::Result<()> - where - Self: Encode, - { - VarInt(Self::ID) - .encode(&mut w) - .context("failed to encode packet ID")?; - self.encode(w) - } -} - -/// The side a packet is intended for -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum PacketSide { - /// Server -> Client - Clientbound, - /// Client -> Server - Serverbound, -} - -/// The state which a packet is used -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum PacketState { - Handshaking, - Status, - Login, - Play, -} - -/// Contains constants for every vanilla packet ID. -pub mod packet_id { - include!(concat!(env!("OUT_DIR"), "/packet_id.rs")); -} - -#[allow(dead_code)] -#[cfg(test)] -mod tests { - use std::borrow::Cow; - - use bytes::BytesMut; - - use super::*; - use crate::protocol::decode::PacketDecoder; - use crate::protocol::encode::PacketEncoder; - - #[derive(Encode, Decode, Packet, Debug)] - #[packet(id = 1, side = PacketSide::Clientbound)] - struct RegularStruct { - foo: i32, - bar: bool, - baz: f64, - } - - #[derive(Encode, Decode, Packet, Debug)] - #[packet(id = 2, side = PacketSide::Clientbound)] - struct UnitStruct; - - #[derive(Encode, Decode, Packet, Debug)] - #[packet(id = 3, side = PacketSide::Clientbound)] - struct EmptyStruct {} - - #[derive(Encode, Decode, Packet, Debug)] - #[packet(id = 4, side = PacketSide::Clientbound)] - struct TupleStruct(i32, bool, f64); - - #[derive(Encode, Decode, Packet, Debug)] - #[packet(id = 5, side = PacketSide::Clientbound)] - struct StructWithGenerics<'z, T = ()> { - foo: &'z str, - bar: T, - } - - #[derive(Encode, Decode, Packet, Debug)] - #[packet(id = 6, side = PacketSide::Clientbound)] - struct TupleStructWithGenerics<'z, T = ()>(&'z str, i32, T); - - #[allow(unconditional_recursion, clippy::extra_unused_type_parameters)] - fn assert_has_impls<'a, T>() - where - T: Encode + Decode<'a> + Packet, - { - assert_has_impls::(); - assert_has_impls::(); - assert_has_impls::(); - assert_has_impls::(); - assert_has_impls::(); - assert_has_impls::(); - } - - #[test] - fn packet_name() { - assert_eq!(RegularStruct::NAME, "RegularStruct"); - assert_eq!(UnitStruct::NAME, "UnitStruct"); - assert_eq!(StructWithGenerics::<()>::NAME, "StructWithGenerics"); - } - - use crate::block_pos::BlockPos; - use crate::hand::Hand; - use crate::ident::Ident; - use crate::item::{ItemKind, ItemStack}; - use crate::protocol::var_int::VarInt; - use crate::protocol::var_long::VarLong; - use crate::text::{IntoText, Text}; - - #[cfg(feature = "encryption")] - const CRYPT_KEY: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; - - #[derive(PartialEq, Debug, Encode, Decode, Packet)] - #[packet(id = 42, side = PacketSide::Clientbound)] - struct TestPacket<'a> { - a: bool, - b: u8, - c: i32, - d: f32, - e: f64, - f: BlockPos, - g: Hand, - h: Ident>, - i: Option, - j: Text, - k: VarInt, - l: VarLong, - m: &'a str, - n: &'a [u8; 10], - o: [u128; 3], - } - - impl<'a> TestPacket<'a> { - fn new(string: &'a str) -> Self { - Self { - a: true, - b: 12, - c: -999, - d: 5.001, - e: 1e10, - f: BlockPos::new(1, 2, 3), - g: Hand::Off, - h: Ident::new("minecraft:whatever").unwrap(), - i: Some(ItemStack::new(ItemKind::WoodenSword, 12, None)), - j: "my ".into_text() + "fancy".italic() + " text", - k: VarInt(123), - l: VarLong(456), - m: string, - n: &[7; 10], - o: [123456789; 3], - } - } - } - - fn check_test_packet(dec: &mut PacketDecoder, string: &str) { - let frame = dec.try_next_packet().unwrap().unwrap(); - - let pkt = frame.decode::().unwrap(); - - assert_eq!(&pkt, &TestPacket::new(string)); - } - - #[test] - fn packets_round_trip() { - let mut buf = BytesMut::new(); - - let mut enc = PacketEncoder::new(); - - enc.append_packet(&TestPacket::new("first")).unwrap(); - #[cfg(feature = "compression")] - enc.set_compression(Some(0)); - enc.append_packet(&TestPacket::new("second")).unwrap(); - buf.unsplit(enc.take()); - #[cfg(feature = "encryption")] - enc.enable_encryption(&CRYPT_KEY); - enc.append_packet(&TestPacket::new("third")).unwrap(); - enc.prepend_packet(&TestPacket::new("fourth")).unwrap(); - - buf.unsplit(enc.take()); - - let mut dec = PacketDecoder::new(); - - dec.queue_bytes(buf); - - check_test_packet(&mut dec, "first"); - - #[cfg(feature = "compression")] - dec.set_compression(Some(0)); - - check_test_packet(&mut dec, "second"); - - #[cfg(feature = "encryption")] - dec.enable_encryption(&CRYPT_KEY); - - check_test_packet(&mut dec, "fourth"); - check_test_packet(&mut dec, "third"); - } -} +} \ No newline at end of file diff --git a/crates/valence_core_macros/src/lib.rs b/crates/valence_core_macros/src/lib.rs index 1c7f59905..32f68c1c6 100644 --- a/crates/valence_core_macros/src/lib.rs +++ b/crates/valence_core_macros/src/lib.rs @@ -28,7 +28,6 @@ use syn::{ mod decode; mod encode; mod ident; -mod packet; #[proc_macro_derive(Encode, attributes(packet))] pub fn derive_encode(item: StdTokenStream) -> StdTokenStream { @@ -46,14 +45,6 @@ pub fn derive_decode(item: StdTokenStream) -> StdTokenStream { } } -#[proc_macro_derive(Packet, attributes(packet))] -pub fn derive_packet(item: StdTokenStream) -> StdTokenStream { - match packet::derive_packet(item.into()) { - Ok(tokens) => tokens.into(), - Err(e) => e.into_compile_error().into(), - } -} - #[proc_macro] pub fn parse_ident_str(item: StdTokenStream) -> StdTokenStream { match ident::parse_ident_str(item.into()) { @@ -131,4 +122,4 @@ fn add_trait_bounds(generics: &mut Generics, trait_: TokenStream) { type_param.bounds.push(parse_quote!(#trait_)) } } -} +} \ No newline at end of file diff --git a/crates/valence_packet/Cargo.toml b/crates/valence_packet/Cargo.toml index 04fd5e0cf..bcef7737b 100644 --- a/crates/valence_packet/Cargo.toml +++ b/crates/valence_packet/Cargo.toml @@ -6,9 +6,25 @@ edition.workspace = true [dependencies] valence_core.workspace = true valence_nbt.workspace = true -valence_registry.workspace = true +valence_build_utils.workspace = true +valence_packet_macros.workspace = true anyhow.workspace = true bitfield-struct.workspace = true byteorder.workspace = true glam.workspace = true -uuid = { workspace = true, features = ["serde"] } \ No newline at end of file +uuid = { workspace = true, features = ["serde"] } +bytes.workspace = true +tracing.workspace = true +bevy_ecs.workspace = true + +[dev-dependencies] +rand.workspace = true + +[build-dependencies] +anyhow.workspace = true +heck.workspace = true +proc-macro2.workspace = true +quote.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +valence_build_utils.workspace = true diff --git a/crates/valence_core/build/packet_id.rs b/crates/valence_packet/build.rs similarity index 71% rename from crates/valence_core/build/packet_id.rs rename to crates/valence_packet/build.rs index bcbd6f6b1..fe3c4fb31 100644 --- a/crates/valence_core/build/packet_id.rs +++ b/crates/valence_packet/build.rs @@ -3,6 +3,7 @@ use proc_macro2::TokenStream; use quote::quote; use serde::Deserialize; use valence_build_utils::ident; +use valence_build_utils::{rerun_if_changed, write_generated_file}; #[derive(Deserialize)] struct Packet { @@ -12,9 +13,20 @@ struct Packet { id: i32, } +pub fn main() -> anyhow::Result<()> { + rerun_if_changed([ + "../../extracted/packets.json", + ]); + + write_generated_file(build()?, "packet_id.rs")?; + + Ok(()) +} + + pub fn build() -> anyhow::Result { let packets: Vec = - serde_json::from_str(include_str!("../../../extracted/packets.json"))?; + serde_json::from_str(include_str!("../../extracted/packets.json"))?; let mut consts = TokenStream::new(); diff --git a/crates/valence_packet/src/advancement.rs b/crates/valence_packet/src/advancement.rs deleted file mode 100644 index 292241a71..000000000 --- a/crates/valence_packet/src/advancement.rs +++ /dev/null @@ -1,110 +0,0 @@ -use super::*; - -pub type AdvancementUpdateS2c<'a> = - GenericAdvancementUpdateS2c<'a, (Ident>, AdvancementPkt<'a, Option>)>; - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ADVANCEMENT_UPDATE_S2C)] -pub struct GenericAdvancementUpdateS2c<'a, AM: 'a> { - pub reset: bool, - pub advancement_mapping: Vec, - pub identifiers: Vec>>, - pub progress_mapping: Vec<(Ident>, Vec>)>, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct AdvancementPkt<'a, I> { - pub parent_id: Option>>, - pub display_data: Option>, - pub criteria: Vec<(Ident>, ())>, - pub requirements: Vec>, - pub sends_telemetry_data: bool, -} - -#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub struct AdvancementRequirementsPkt<'a> { - pub requirement: Vec<&'a str>, -} - -#[derive(Clone, PartialEq, Debug)] -pub struct AdvancementDisplayPkt<'a, I> { - pub title: Cow<'a, Text>, - pub description: Cow<'a, Text>, - pub icon: I, - pub frame_type: VarInt, - pub flags: i32, - pub background_texture: Option>>, - pub x_coord: f32, - pub y_coord: f32, -} - -#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub struct AdvancementCriteriaPkt<'a> { - pub criterion_identifier: Ident>, - /// If present, the criteria has been achieved at the - /// time wrapped; time represented as millis since epoch - pub criterion_progress: Option, -} - -impl Encode for AdvancementDisplayPkt<'_, I> { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - self.title.encode(&mut w)?; - self.description.encode(&mut w)?; - self.icon.encode(&mut w)?; - self.frame_type.encode(&mut w)?; - self.flags.encode(&mut w)?; - - match self.background_texture.as_ref() { - None => {} - Some(texture) => texture.encode(&mut w)?, - } - - self.x_coord.encode(&mut w)?; - self.y_coord.encode(&mut w)?; - - Ok(()) - } -} - -impl<'a, I: Decode<'a>> Decode<'a> for AdvancementDisplayPkt<'a, I> { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - let title = >::decode(r)?; - let description = >::decode(r)?; - let icon = I::decode(r)?; - let frame_type = VarInt::decode(r)?; - let flags = i32::decode(r)?; - - let background_texture = if flags & 1 == 1 { - Some(Ident::decode(r)?) - } else { - None - }; - - let x_coord = f32::decode(r)?; - let y_coord = f32::decode(r)?; - - Ok(Self { - title, - description, - icon, - frame_type, - flags, - background_texture, - x_coord, - y_coord, - }) - } -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ADVANCEMENT_TAB_C2S)] -pub enum AdvancementTabC2s<'a> { - OpenedTab { tab_id: Ident> }, - ClosedScreen, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::SELECT_ADVANCEMENT_TAB_S2C)] -pub struct SelectAdvancementTabS2c<'a> { - pub identifier: Option>>, -} diff --git a/crates/valence_packet/src/boss_bar.rs b/crates/valence_packet/src/boss_bar.rs deleted file mode 100644 index e427eb46d..000000000 --- a/crates/valence_packet/src/boss_bar.rs +++ /dev/null @@ -1,26 +0,0 @@ -use valence_core::boss_bar::{BossBarColor, BossBarDivision, BossBarFlags}; - -use super::*; - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::BOSS_BAR_S2C)] -pub struct BossBarS2c<'a> { - pub id: Uuid, - pub action: BossBarAction<'a>, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub enum BossBarAction<'a> { - Add { - title: Cow<'a, Text>, - health: f32, - color: BossBarColor, - division: BossBarDivision, - flags: BossBarFlags, - }, - Remove, - UpdateHealth(f32), - UpdateTitle(Cow<'a, Text>), - UpdateStyle(BossBarColor, BossBarDivision), - UpdateFlags(BossBarFlags), -} diff --git a/crates/valence_packet/src/chat.rs b/crates/valence_packet/src/chat.rs deleted file mode 100644 index 13e18d4bb..000000000 --- a/crates/valence_packet/src/chat.rs +++ /dev/null @@ -1,239 +0,0 @@ -use super::*; - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::GAME_MESSAGE_S2C)] -pub struct GameMessageS2c<'a> { - pub chat: Cow<'a, Text>, - /// Whether the message is in the actionbar or the chat. - pub overlay: bool, -} - -#[derive(Copy, Clone, PartialEq, Debug)] -pub struct MessageSignature<'a> { - pub message_id: i32, - pub signature: Option<&'a [u8; 256]>, -} - -impl<'a> Encode for MessageSignature<'a> { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - VarInt(self.message_id + 1).encode(&mut w)?; - - match self.signature { - None => {} - Some(signature) => signature.encode(&mut w)?, - } - - Ok(()) - } -} - -impl<'a> Decode<'a> for MessageSignature<'a> { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - let message_id = VarInt::decode(r)?.0 - 1; // TODO: this can underflow. - - let signature = if message_id == -1 { - Some(<&[u8; 256]>::decode(r)?) - } else { - None - }; - - Ok(Self { - message_id, - signature, - }) - } -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CHAT_MESSAGE_C2S)] -pub struct ChatMessageC2s<'a> { - pub message: &'a str, - pub timestamp: u64, - pub salt: u64, - pub signature: Option<&'a [u8; 256]>, - pub message_count: VarInt, - // This is a bitset of 20; each bit represents one - // of the last 20 messages received and whether or not - // the message was acknowledged by the client - pub acknowledgement: [u8; 3], -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::COMMAND_EXECUTION_C2S)] -pub struct CommandExecutionC2s<'a> { - pub command: &'a str, - pub timestamp: u64, - pub salt: u64, - pub argument_signatures: Vec>, - pub message_count: VarInt, - //// This is a bitset of 20; each bit represents one - //// of the last 20 messages received and whether or not - //// the message was acknowledged by the client - pub acknowledgement: [u8; 3], -} - -#[derive(Copy, Clone, Debug, Encode, Decode)] -pub struct CommandArgumentSignature<'a> { - pub argument_name: &'a str, - pub signature: &'a [u8; 256], -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::MESSAGE_ACKNOWLEDGMENT_C2S)] - -pub struct MessageAcknowledgmentC2s { - pub message_count: VarInt, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_SESSION_C2S)] -pub struct PlayerSessionC2s<'a> { - pub session_id: Uuid, - // Public key - pub expires_at: i64, - pub public_key_data: &'a [u8], - pub key_signature: &'a [u8], -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::REQUEST_COMMAND_COMPLETIONS_C2S)] -pub struct RequestCommandCompletionsC2s<'a> { - pub transaction_id: VarInt, - pub text: &'a str, -} - -#[derive(Clone, PartialEq, Debug, Packet)] -#[packet(id = packet_id::CHAT_MESSAGE_S2C)] -pub struct ChatMessageS2c<'a> { - pub sender: Uuid, - pub index: VarInt, - pub message_signature: Option<&'a [u8; 256]>, - pub message: &'a str, - pub time_stamp: u64, - pub salt: u64, - pub previous_messages: Vec>, - pub unsigned_content: Option>, - pub filter_type: MessageFilterType, - pub filter_type_bits: Option, - pub chat_type: VarInt, - pub network_name: Cow<'a, Text>, - pub network_target_name: Option>, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum MessageFilterType { - PassThrough, - FullyFiltered, - PartiallyFiltered, -} - -impl<'a> Encode for ChatMessageS2c<'a> { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - self.sender.encode(&mut w)?; - self.index.encode(&mut w)?; - self.message_signature.encode(&mut w)?; - self.message.encode(&mut w)?; - self.time_stamp.encode(&mut w)?; - self.salt.encode(&mut w)?; - self.previous_messages.encode(&mut w)?; - self.unsigned_content.encode(&mut w)?; - self.filter_type.encode(&mut w)?; - - if self.filter_type == MessageFilterType::PartiallyFiltered { - match self.filter_type_bits { - // Filler data - None => 0u8.encode(&mut w)?, - Some(bits) => bits.encode(&mut w)?, - } - } - - self.chat_type.encode(&mut w)?; - self.network_name.encode(&mut w)?; - self.network_target_name.encode(&mut w)?; - - Ok(()) - } -} - -impl<'a> Decode<'a> for ChatMessageS2c<'a> { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - let sender = Uuid::decode(r)?; - let index = VarInt::decode(r)?; - let message_signature = Option::<&'a [u8; 256]>::decode(r)?; - let message = <&str>::decode(r)?; - let time_stamp = u64::decode(r)?; - let salt = u64::decode(r)?; - let previous_messages = Vec::::decode(r)?; - let unsigned_content = Option::>::decode(r)?; - let filter_type = MessageFilterType::decode(r)?; - - let filter_type_bits = match filter_type { - MessageFilterType::PartiallyFiltered => Some(u8::decode(r)?), - _ => None, - }; - - let chat_type = VarInt::decode(r)?; - let network_name = >::decode(r)?; - let network_target_name = Option::>::decode(r)?; - - Ok(Self { - sender, - index, - message_signature, - message, - time_stamp, - salt, - previous_messages, - unsigned_content, - filter_type, - filter_type_bits, - chat_type, - network_name, - network_target_name, - }) - } -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CHAT_SUGGESTIONS_S2C)] -pub struct ChatSuggestionsS2c<'a> { - pub action: ChatSuggestionsAction, - pub entries: Cow<'a, [&'a str]>, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum ChatSuggestionsAction { - Add, - Remove, - Set, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::REMOVE_MESSAGE_S2C)] -pub struct RemoveMessageS2c<'a> { - pub signature: MessageSignature<'a>, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::COMMAND_SUGGESTIONS_S2C)] -pub struct CommandSuggestionsS2c<'a> { - pub id: VarInt, - pub start: VarInt, - pub length: VarInt, - pub matches: Vec>, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct CommandSuggestionsMatch<'a> { - pub suggested_match: &'a str, - pub tooltip: Option>, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PROFILELESS_CHAT_MESSAGE_S2C)] -pub struct ProfilelessChatMessageS2c<'a> { - pub message: Cow<'a, Text>, - pub chat_type: VarInt, - pub chat_type_name: Cow<'a, Text>, - pub target_name: Option>, -} diff --git a/crates/valence_packet/src/client.rs b/crates/valence_packet/src/client.rs deleted file mode 100644 index fa3241b6a..000000000 --- a/crates/valence_packet/src/client.rs +++ /dev/null @@ -1,464 +0,0 @@ -use super::*; - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::BUNDLE_SPLITTER)] -pub struct BundleSplitterS2c; - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::BOAT_PADDLE_STATE_C2S)] -pub struct BoatPaddleStateC2s { - pub left_paddle_turning: bool, - pub right_paddle_turning: bool, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::BOOK_UPDATE_C2S)] -pub struct BookUpdateC2s<'a> { - pub slot: VarInt, - pub entries: Vec<&'a str>, - pub title: Option<&'a str>, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::JIGSAW_GENERATING_C2S)] -pub struct JigsawGeneratingC2s { - pub position: BlockPos, - pub levels: VarInt, - pub keep_jigsaws: bool, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAY_PONG_C2S)] -pub struct PlayPongC2s { - pub id: i32, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_ACTION_C2S)] -pub struct PlayerActionC2s { - pub action: PlayerAction, - pub position: BlockPos, - pub direction: Direction, - pub sequence: VarInt, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum PlayerAction { - StartDestroyBlock, - AbortDestroyBlock, - StopDestroyBlock, - DropAllItems, - DropItem, - ReleaseUseItem, - SwapItemWithOffhand, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_INPUT_C2S)] -pub struct PlayerInputC2s { - pub sideways: f32, - pub forward: f32, - pub flags: PlayerInputFlags, -} - -#[bitfield(u8)] -#[derive(PartialEq, Eq, Encode, Decode)] -pub struct PlayerInputFlags { - pub jump: bool, - pub unmount: bool, - #[bits(6)] - _pad: u8, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::QUERY_BLOCK_NBT_C2S)] -pub struct QueryBlockNbtC2s { - pub transaction_id: VarInt, - pub position: BlockPos, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::QUERY_ENTITY_NBT_C2S)] -pub struct QueryEntityNbtC2s { - pub transaction_id: VarInt, - pub entity_id: VarInt, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::SPECTATOR_TELEPORT_C2S)] -pub struct SpectatorTeleportC2s { - pub target: Uuid, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::UPDATE_COMMAND_BLOCK_MINECART_C2S)] -pub struct UpdateCommandBlockMinecartC2s<'a> { - pub entity_id: VarInt, - pub command: &'a str, - pub track_output: bool, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::UPDATE_COMMAND_BLOCK_C2S)] -pub struct UpdateCommandBlockC2s<'a> { - pub position: BlockPos, - pub command: &'a str, - pub mode: UpdateCommandBlockMode, - pub flags: UpdateCommandBlockFlags, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum UpdateCommandBlockMode { - Sequence, - Auto, - Redstone, -} - -#[bitfield(u8)] -#[derive(PartialEq, Eq, Encode, Decode)] -pub struct UpdateCommandBlockFlags { - pub track_output: bool, - pub conditional: bool, - pub automatic: bool, - #[bits(5)] - _pad: u8, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::UPDATE_DIFFICULTY_LOCK_C2S)] -pub struct UpdateDifficultyLockC2s { - pub locked: bool, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::UPDATE_DIFFICULTY_C2S)] -pub struct UpdateDifficultyC2s { - pub difficulty: Difficulty, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::UPDATE_JIGSAW_C2S)] -pub struct UpdateJigsawC2s<'a> { - pub position: BlockPos, - pub name: Ident>, - pub target: Ident>, - pub pool: Ident>, - pub final_state: &'a str, - pub joint_type: &'a str, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::UPDATE_PLAYER_ABILITIES_C2S)] -pub enum UpdatePlayerAbilitiesC2s { - #[packet(tag = 0b00)] - StopFlying, - #[packet(tag = 0b10)] - StartFlying, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::UPDATE_SIGN_C2S)] -pub struct UpdateSignC2s<'a> { - pub position: BlockPos, - pub is_front_text: bool, - pub lines: [&'a str; 4], -} - -pub mod structure_block { - - use super::*; - - #[derive(Copy, Clone, Debug, Encode, Decode, Packet)] - #[packet(id = packet_id::UPDATE_STRUCTURE_BLOCK_C2S)] - pub struct UpdateStructureBlockC2s<'a> { - pub position: BlockPos, - pub action: Action, - pub mode: Mode, - pub name: &'a str, - pub offset_xyz: [i8; 3], - pub size_xyz: [i8; 3], - pub mirror: Mirror, - pub rotation: Rotation, - pub metadata: &'a str, - pub integrity: f32, - pub seed: VarLong, - pub flags: Flags, - } - - #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] - pub enum Action { - UpdateData, - SaveStructure, - LoadStructure, - DetectSize, - } - - #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] - pub enum Mode { - Save, - Load, - Corner, - Data, - } - - #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] - pub enum Mirror { - None, - LeftRight, - FrontBack, - } - - #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] - pub enum Rotation { - None, - Clockwise90, - Clockwise180, - Counterclockwise90, - } - - #[bitfield(u8)] - #[derive(PartialEq, Eq, Encode, Decode)] - pub struct Flags { - pub ignore_entities: bool, - pub show_air: bool, - pub show_bounding_box: bool, - #[bits(5)] - _pad: u8, - } -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::DEATH_MESSAGE_S2C)] -pub struct DeathMessageS2c<'a> { - pub player_id: VarInt, - pub message: Cow<'a, Text>, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::DAMAGE_TILT_S2C)] -pub struct DamageTiltS2c { - /// The ID of the entity taking damage. - pub entity_id: VarInt, - /// The direction the damage is coming from in relation to the entity. - pub yaw: f32, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::DIFFICULTY_S2C)] -pub struct DifficultyS2c { - pub difficulty: Difficulty, - pub locked: bool, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::DISCONNECT_S2C)] -pub struct DisconnectS2c<'a> { - pub reason: Cow<'a, Text>, -} - -/// Unused by notchian clients. -#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ENTER_COMBAT_S2C)] -pub struct EnterCombatS2c; - -/// Unused by notchian clients. -#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::END_COMBAT_S2C)] -pub struct EndCombatS2c { - pub duration: VarInt, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::EXPERIENCE_BAR_UPDATE_S2C)] -pub struct ExperienceBarUpdateS2c { - pub bar: f32, - pub level: VarInt, - pub total_xp: VarInt, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::FEATURES_S2C)] -pub struct FeaturesS2c<'a> { - pub features: Vec>>, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::GAME_JOIN_S2C)] -pub struct GameJoinS2c<'a> { - pub entity_id: i32, - pub is_hardcore: bool, - pub game_mode: GameMode, - /// Same values as `game_mode` but with -1 to indicate no previous. - pub previous_game_mode: i8, - pub dimension_names: Vec>>, - pub registry_codec: Cow<'a, Compound>, - pub dimension_type_name: Ident>, - pub dimension_name: Ident>, - pub hashed_seed: i64, - pub max_players: VarInt, - pub view_distance: VarInt, - pub simulation_distance: VarInt, - pub reduced_debug_info: bool, - pub enable_respawn_screen: bool, - pub is_debug: bool, - pub is_flat: bool, - pub last_death_location: Option>, - pub portal_cooldown: VarInt, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::GAME_STATE_CHANGE_S2C)] -pub struct GameStateChangeS2c { - pub kind: GameEventKind, - pub value: f32, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum GameEventKind { - NoRespawnBlockAvailable, - EndRaining, - BeginRaining, - ChangeGameMode, - WinGame, - DemoEvent, - ArrowHitPlayer, - RainLevelChange, - ThunderLevelChange, - PlayPufferfishStingSound, - PlayElderGuardianMobAppearance, - EnableRespawnScreen, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::HEALTH_UPDATE_S2C)] -pub struct HealthUpdateS2c { - pub health: f32, - pub food: VarInt, - pub food_saturation: f32, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_ABILITIES_S2C)] -pub struct PlayerAbilitiesS2c { - pub flags: PlayerAbilitiesFlags, - pub flying_speed: f32, - pub fov_modifier: f32, -} - -#[bitfield(u8)] -#[derive(PartialEq, Eq, Encode, Decode)] -pub struct PlayerAbilitiesFlags { - pub invulnerable: bool, - pub flying: bool, - pub allow_flying: bool, - pub instant_break: bool, - #[bits(4)] - _pad: u8, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_RESPAWN_S2C)] -pub struct PlayerRespawnS2c<'a> { - pub dimension_type_name: Ident>, - pub dimension_name: Ident>, - pub hashed_seed: u64, - pub game_mode: GameMode, - pub previous_game_mode: i8, - pub is_debug: bool, - pub is_flat: bool, - pub copy_metadata: bool, - pub last_death_location: Option>, - pub portal_cooldown: VarInt, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_SPAWN_POSITION_S2C)] -pub struct PlayerSpawnPositionS2c { - pub position: BlockPos, - pub angle: f32, -} - -// https://wiki.vg/Protocol#Spawn_Player -/// This packet is sent by the server when a player comes into visible range, -/// not when a player joins. -/// -/// This packet must be sent after the Player Info Update packet that adds the -/// player data for the client to use when spawning a player. If the Player Info -/// for the player spawned by this packet is not present when this packet -/// arrives, Notchian clients will not spawn the player entity. The Player Info -/// packet includes skin/cape data. -/// -/// Servers can, however, safely spawn player entities for players not in -/// visible range. The client appears to handle it correctly. -/// -/// wiki : [Spawn Player](https://wiki.vg/Protocol#Spawn_Player) -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_SPAWN_S2C)] -pub struct PlayerSpawnS2c { - /// A unique integer ID mostly used in the protocol to identify the player. - pub entity_id: VarInt, - pub player_uuid: Uuid, - pub position: DVec3, - pub yaw: ByteAngle, - pub pitch: ByteAngle, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::SERVER_METADATA_S2C)] -pub struct ServerMetadataS2c<'a> { - pub motd: Cow<'a, Text>, - pub icon: Option<&'a [u8]>, - pub enforce_secure_chat: bool, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::SIGN_EDITOR_OPEN_S2C)] -pub struct SignEditorOpenS2c { - pub location: BlockPos, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::SIMULATION_DISTANCE_S2C)] -pub struct SimulationDistanceS2c { - pub simulation_distance: VarInt, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::STATISTICS_S2C)] -pub struct StatisticsS2c { - pub statistics: Vec, -} - -#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode)] -pub struct Statistic { - pub category_id: VarInt, - pub statistic_id: VarInt, - pub value: VarInt, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::VEHICLE_MOVE_S2C)] -pub struct VehicleMoveS2c { - pub position: DVec3, - pub yaw: f32, - pub pitch: f32, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::OPEN_WRITTEN_BOOK_S2C)] -pub struct OpenWrittenBookS2c { - pub hand: Hand, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAY_PING_S2C)] -pub struct PlayPingS2c { - pub id: i32, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::NBT_QUERY_RESPONSE_S2C)] -pub struct NbtQueryResponseS2c { - pub transaction_id: VarInt, - pub nbt: Compound, -} diff --git a/crates/valence_packet/src/command.rs b/crates/valence_packet/src/command.rs deleted file mode 100644 index 310637aad..000000000 --- a/crates/valence_packet/src/command.rs +++ /dev/null @@ -1,434 +0,0 @@ -use super::*; - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::COMMAND_TREE_S2C)] -pub struct CommandTreeS2c<'a> { - pub commands: Vec>, - pub root_index: VarInt, -} - -#[derive(Clone, Debug)] -pub struct Node<'a> { - pub children: Vec, - pub data: NodeData<'a>, - pub executable: bool, - pub redirect_node: Option, -} - -#[derive(Clone, Debug)] -pub enum NodeData<'a> { - Root, - Literal { - name: &'a str, - }, - Argument { - name: &'a str, - parser: Parser<'a>, - suggestion: Option, - }, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub enum Suggestion { - AskServer, - AllRecipes, - AvailableSounds, - AvailableBiomes, - SummonableEntities, -} - -#[derive(Clone, Debug)] -pub enum Parser<'a> { - Bool, - Float { min: Option, max: Option }, - Double { min: Option, max: Option }, - Integer { min: Option, max: Option }, - Long { min: Option, max: Option }, - String(StringArg), - Entity { single: bool, only_players: bool }, - GameProfile, - BlockPos, - ColumnPos, - Vec3, - Vec2, - BlockState, - BlockPredicate, - ItemStack, - ItemPredicate, - Color, - Component, - Message, - NbtCompoundTag, - NbtTag, - NbtPath, - Objective, - ObjectiveCriteria, - Operation, - Particle, - Angle, - Rotation, - ScoreboardSlot, - ScoreHolder { allow_multiple: bool }, - Swizzle, - Team, - ItemSlot, - ResourceLocation, - Function, - EntityAnchor, - IntRange, - FloatRange, - Dimension, - GameMode, - Time, - ResourceOrTag { registry: Ident> }, - ResourceOrTagKey { registry: Ident> }, - Resource { registry: Ident> }, - ResourceKey { registry: Ident> }, - TemplateMirror, - TemplateRotation, - Uuid, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum StringArg { - SingleWord, - QuotablePhrase, - GreedyPhrase, -} - -impl Encode for Node<'_> { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - let node_type = match &self.data { - NodeData::Root => 0, - NodeData::Literal { .. } => 1, - NodeData::Argument { .. } => 2, - }; - - let has_suggestion = matches!( - &self.data, - NodeData::Argument { - suggestion: Some(_), - .. - } - ); - - let flags: u8 = node_type - | (self.executable as u8 * 0x04) - | (self.redirect_node.is_some() as u8 * 0x08) - | (has_suggestion as u8 * 0x10); - - w.write_u8(flags)?; - - self.children.encode(&mut w)?; - - if let Some(redirect_node) = self.redirect_node { - redirect_node.encode(&mut w)?; - } - - match &self.data { - NodeData::Root => {} - NodeData::Literal { name } => { - name.encode(&mut w)?; - } - NodeData::Argument { - name, - parser, - suggestion, - } => { - name.encode(&mut w)?; - parser.encode(&mut w)?; - - if let Some(suggestion) = suggestion { - match suggestion { - Suggestion::AskServer => "ask_server", - Suggestion::AllRecipes => "all_recipes", - Suggestion::AvailableSounds => "available_sounds", - Suggestion::AvailableBiomes => "available_biomes", - Suggestion::SummonableEntities => "summonable_entities", - } - .encode(&mut w)?; - } - } - } - - Ok(()) - } -} - -impl<'a> Decode<'a> for Node<'a> { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - let flags = u8::decode(r)?; - - let children = Vec::decode(r)?; - - let redirect_node = if flags & 0x08 != 0 { - Some(VarInt::decode(r)?) - } else { - None - }; - - let node_data = match flags & 0x3 { - 0 => NodeData::Root, - 1 => NodeData::Literal { - name: <&str>::decode(r)?, - }, - 2 => NodeData::Argument { - name: <&str>::decode(r)?, - parser: Parser::decode(r)?, - suggestion: if flags & 0x10 != 0 { - Some(match Ident::>::decode(r)?.as_str() { - "minecraft:ask_server" => Suggestion::AskServer, - "minecraft:all_recipes" => Suggestion::AllRecipes, - "minecraft:available_sounds" => Suggestion::AvailableSounds, - "minecraft:available_biomes" => Suggestion::AvailableBiomes, - "minecraft:summonable_entities" => Suggestion::SummonableEntities, - other => bail!("unknown command suggestion type of \"{other}\""), - }) - } else { - None - }, - }, - n => bail!("invalid node type of {n}"), - }; - - Ok(Self { - children, - data: node_data, - executable: flags & 0x04 != 0, - redirect_node, - }) - } -} - -impl Encode for Parser<'_> { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - match self { - Parser::Bool => 0u8.encode(&mut w)?, - Parser::Float { min, max } => { - 1u8.encode(&mut w)?; - - (min.is_some() as u8 | (max.is_some() as u8 * 0x2)).encode(&mut w)?; - - if let Some(min) = min { - min.encode(&mut w)?; - } - - if let Some(max) = max { - max.encode(&mut w)?; - } - } - Parser::Double { min, max } => { - 2u8.encode(&mut w)?; - - (min.is_some() as u8 | (max.is_some() as u8 * 0x2)).encode(&mut w)?; - - if let Some(min) = min { - min.encode(&mut w)?; - } - - if let Some(max) = max { - max.encode(&mut w)?; - } - } - Parser::Integer { min, max } => { - 3u8.encode(&mut w)?; - - (min.is_some() as u8 | (max.is_some() as u8 * 0x2)).encode(&mut w)?; - - if let Some(min) = min { - min.encode(&mut w)?; - } - - if let Some(max) = max { - max.encode(&mut w)?; - } - } - Parser::Long { min, max } => { - 4u8.encode(&mut w)?; - - (min.is_some() as u8 | (max.is_some() as u8 * 0x2)).encode(&mut w)?; - - if let Some(min) = min { - min.encode(&mut w)?; - } - - if let Some(max) = max { - max.encode(&mut w)?; - } - } - Parser::String(arg) => { - 5u8.encode(&mut w)?; - arg.encode(&mut w)?; - } - Parser::Entity { - single, - only_players, - } => { - 6u8.encode(&mut w)?; - (*single as u8 | (*only_players as u8 * 0x2)).encode(&mut w)?; - } - Parser::GameProfile => 7u8.encode(&mut w)?, - Parser::BlockPos => 8u8.encode(&mut w)?, - Parser::ColumnPos => 9u8.encode(&mut w)?, - Parser::Vec3 => 10u8.encode(&mut w)?, - Parser::Vec2 => 11u8.encode(&mut w)?, - Parser::BlockState => 12u8.encode(&mut w)?, - Parser::BlockPredicate => 13u8.encode(&mut w)?, - Parser::ItemStack => 14u8.encode(&mut w)?, - Parser::ItemPredicate => 15u8.encode(&mut w)?, - Parser::Color => 16u8.encode(&mut w)?, - Parser::Component => 17u8.encode(&mut w)?, - Parser::Message => 18u8.encode(&mut w)?, - Parser::NbtCompoundTag => 19u8.encode(&mut w)?, - Parser::NbtTag => 20u8.encode(&mut w)?, - Parser::NbtPath => 21u8.encode(&mut w)?, - Parser::Objective => 22u8.encode(&mut w)?, - Parser::ObjectiveCriteria => 23u8.encode(&mut w)?, - Parser::Operation => 24u8.encode(&mut w)?, - Parser::Particle => 25u8.encode(&mut w)?, - Parser::Angle => 26u8.encode(&mut w)?, - Parser::Rotation => 27u8.encode(&mut w)?, - Parser::ScoreboardSlot => 28u8.encode(&mut w)?, - Parser::ScoreHolder { allow_multiple } => { - 29u8.encode(&mut w)?; - allow_multiple.encode(&mut w)?; - } - Parser::Swizzle => 30u8.encode(&mut w)?, - Parser::Team => 31u8.encode(&mut w)?, - Parser::ItemSlot => 32u8.encode(&mut w)?, - Parser::ResourceLocation => 33u8.encode(&mut w)?, - Parser::Function => 34u8.encode(&mut w)?, - Parser::EntityAnchor => 35u8.encode(&mut w)?, - Parser::IntRange => 36u8.encode(&mut w)?, - Parser::FloatRange => 37u8.encode(&mut w)?, - Parser::Dimension => 38u8.encode(&mut w)?, - Parser::GameMode => 39u8.encode(&mut w)?, - Parser::Time => 40u8.encode(&mut w)?, - Parser::ResourceOrTag { registry } => { - 41u8.encode(&mut w)?; - registry.encode(&mut w)?; - } - Parser::ResourceOrTagKey { registry } => { - 42u8.encode(&mut w)?; - registry.encode(&mut w)?; - } - Parser::Resource { registry } => { - 43u8.encode(&mut w)?; - registry.encode(&mut w)?; - } - Parser::ResourceKey { registry } => { - 44u8.encode(&mut w)?; - registry.encode(&mut w)?; - } - Parser::TemplateMirror => 45u8.encode(&mut w)?, - Parser::TemplateRotation => 46u8.encode(&mut w)?, - Parser::Uuid => 47u8.encode(&mut w)?, - } - - Ok(()) - } -} - -impl<'a> Decode<'a> for Parser<'a> { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - fn decode_min_max<'a, T: Decode<'a>>( - r: &mut &'a [u8], - ) -> anyhow::Result<(Option, Option)> { - let flags = u8::decode(r)?; - - let min = if flags & 0x1 != 0 { - Some(T::decode(r)?) - } else { - None - }; - - let max = if flags & 0x2 != 0 { - Some(T::decode(r)?) - } else { - None - }; - - Ok((min, max)) - } - - Ok(match u8::decode(r)? { - 0 => Self::Bool, - 1 => { - let (min, max) = decode_min_max(r)?; - Self::Float { min, max } - } - 2 => { - let (min, max) = decode_min_max(r)?; - Self::Double { min, max } - } - 3 => { - let (min, max) = decode_min_max(r)?; - Self::Integer { min, max } - } - 4 => { - let (min, max) = decode_min_max(r)?; - Self::Long { min, max } - } - 5 => Self::String(StringArg::decode(r)?), - 6 => { - let flags = u8::decode(r)?; - Self::Entity { - single: flags & 0x1 != 0, - only_players: flags & 0x2 != 0, - } - } - 7 => Self::GameProfile, - 8 => Self::BlockPos, - 9 => Self::ColumnPos, - 10 => Self::Vec3, - 11 => Self::Vec2, - 12 => Self::BlockState, - 13 => Self::BlockPredicate, - 14 => Self::ItemStack, - 15 => Self::ItemPredicate, - 16 => Self::Color, - 17 => Self::Component, - 18 => Self::Message, - 19 => Self::NbtCompoundTag, - 20 => Self::NbtTag, - 21 => Self::NbtPath, - 22 => Self::Objective, - 23 => Self::ObjectiveCriteria, - 24 => Self::Operation, - 25 => Self::Particle, - 26 => Self::Angle, - 27 => Self::Rotation, - 28 => Self::ScoreboardSlot, - 29 => Self::ScoreHolder { - allow_multiple: bool::decode(r)?, - }, - 30 => Self::Swizzle, - 31 => Self::Team, - 32 => Self::ItemSlot, - 33 => Self::ResourceLocation, - 34 => Self::Function, - 35 => Self::EntityAnchor, - 36 => Self::IntRange, - 37 => Self::FloatRange, - 38 => Self::Dimension, - 39 => Self::GameMode, - 40 => Self::Time, - 41 => Self::ResourceOrTag { - registry: Ident::decode(r)?, - }, - 42 => Self::ResourceOrTagKey { - registry: Ident::decode(r)?, - }, - 43 => Self::Resource { - registry: Ident::decode(r)?, - }, - 44 => Self::ResourceKey { - registry: Ident::decode(r)?, - }, - 45 => Self::TemplateMirror, - 46 => Self::TemplateRotation, - 47 => Self::Uuid, - n => bail!("unknown command parser ID of {n}"), - }) - } -} diff --git a/crates/valence_packet/src/entity.rs b/crates/valence_packet/src/entity.rs deleted file mode 100644 index b6e9d4668..000000000 --- a/crates/valence_packet/src/entity.rs +++ /dev/null @@ -1,287 +0,0 @@ -use super::*; - -#[derive(Clone, PartialEq, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ENTITIES_DESTROY_S2C)] -pub struct EntitiesDestroyS2c<'a> { - pub entity_ids: Cow<'a, [VarInt]>, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ENTITY_ANIMATION_S2C)] -pub struct EntityAnimationS2c { - pub entity_id: VarInt, - pub animation: u8, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ENTITY_ATTACH_S2C)] -pub struct EntityAttachS2c { - pub attached_entity_id: i32, - pub holding_entity_id: i32, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ENTITY_ATTRIBUTES_S2C)] -pub struct EntityAttributesS2c<'a> { - pub entity_id: VarInt, - pub properties: Vec>, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct AttributeProperty<'a> { - pub key: Ident>, - pub value: f64, - pub modifiers: Vec, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct AttributeModifier { - pub uuid: Uuid, - pub amount: f64, - pub operation: u8, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ENTITY_DAMAGE_S2C)] -pub struct EntityDamageS2c { - /// The ID of the entity taking damage - pub entity_id: VarInt, - /// The ID of the type of damage taken - pub source_type_id: VarInt, - /// The ID + 1 of the entity responsible for the damage, if present. If not - /// present, the value is 0 - pub source_cause_id: VarInt, - /// The ID + 1 of the entity that directly dealt the damage, if present. If - /// not present, the value is 0. If this field is present: - /// * and damage was dealt indirectly, such as by the use of a projectile, - /// this field will contain the ID of such projectile; - /// * and damage was dealt dirctly, such as by manually attacking, this - /// field will contain the same value as Source Cause ID. - pub source_direct_id: VarInt, - /// The Notchian server sends the Source Position when the damage was dealt - /// by the /damage command and a position was specified - pub source_pos: Option, -} - -#[derive(Clone, PartialEq, Debug, Packet)] -#[packet(id = packet_id::ENTITY_EQUIPMENT_UPDATE_S2C)] -pub struct EntityEquipmentUpdateS2c { - pub entity_id: VarInt, - pub equipment: Vec, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct EquipmentEntry { - pub slot: i8, - pub item: Option, -} - -impl Encode for EntityEquipmentUpdateS2c { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - self.entity_id.encode(&mut w)?; - - for i in 0..self.equipment.len() { - let slot = self.equipment[i].slot; - if i != self.equipment.len() - 1 { - (slot | -128).encode(&mut w)?; - } else { - slot.encode(&mut w)?; - } - self.equipment[i].item.encode(&mut w)?; - } - - Ok(()) - } -} - -impl<'a> Decode<'a> for EntityEquipmentUpdateS2c { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - let entity_id = VarInt::decode(r)?; - - let mut equipment = vec![]; - - loop { - let slot = i8::decode(r)?; - let item = Option::::decode(r)?; - equipment.push(EquipmentEntry { - slot: slot & 127, - item, - }); - if slot & -128 == 0 { - break; - } - } - - Ok(Self { - entity_id, - equipment, - }) - } -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::MOVE_RELATIVE)] -pub struct MoveRelativeS2c { - pub entity_id: VarInt, - pub delta: [i16; 3], - pub on_ground: bool, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ROTATE_AND_MOVE_RELATIVE)] -pub struct RotateAndMoveRelativeS2c { - pub entity_id: VarInt, - pub delta: [i16; 3], - pub yaw: ByteAngle, - pub pitch: ByteAngle, - pub on_ground: bool, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ROTATE)] -pub struct RotateS2c { - pub entity_id: VarInt, - pub yaw: ByteAngle, - pub pitch: ByteAngle, - pub on_ground: bool, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ENTITY_PASSENGERS_SET_S2C)] -pub struct EntityPassengersSetS2c { - /// Vehicle's entity id - pub entity_id: VarInt, - pub passengers: Vec, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ENTITY_POSITION_S2C)] -pub struct EntityPositionS2c { - pub entity_id: VarInt, - pub position: DVec3, - pub yaw: ByteAngle, - pub pitch: ByteAngle, - pub on_ground: bool, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ENTITY_SET_HEAD_YAW_S2C)] -pub struct EntitySetHeadYawS2c { - pub entity_id: VarInt, - pub head_yaw: ByteAngle, -} - -// https://wiki.vg/Protocol#Spawn_Experience_Orb -/// Sent by the server when a vehicle or other non-living entity is created. -/// -/// wiki : [Spawn Entity](https://wiki.vg/Protocol#Spawn_Experience_Orb) -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ENTITY_SPAWN_S2C)] -pub struct EntitySpawnS2c { - pub entity_id: VarInt, - pub object_uuid: Uuid, - pub kind: VarInt, - pub position: DVec3, - pub pitch: ByteAngle, - pub yaw: ByteAngle, - pub head_yaw: ByteAngle, - pub data: VarInt, - pub velocity: [i16; 3], -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ENTITY_STATUS_EFFECT_S2C)] -pub struct EntityStatusEffectS2c { - pub entity_id: VarInt, - pub effect_id: VarInt, - pub amplifier: u8, - pub duration: VarInt, - pub flags: Flags, - pub factor_codec: Option, -} - -#[bitfield(u8)] -#[derive(PartialEq, Eq, Encode, Decode)] -pub struct Flags { - pub is_ambient: bool, - pub show_particles: bool, - pub show_icon: bool, - #[bits(5)] - _pad: u8, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ENTITY_STATUS_S2C)] -pub struct EntityStatusS2c { - pub entity_id: i32, - pub entity_status: u8, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ENTITY_TRACKER_UPDATE_S2C)] -pub struct EntityTrackerUpdateS2c<'a> { - pub entity_id: VarInt, - pub metadata: RawBytes<'a>, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ENTITY_VELOCITY_UPDATE_S2C)] -pub struct EntityVelocityUpdateS2c { - pub entity_id: VarInt, - pub velocity: [i16; 3], -} - -// https://wiki.vg/Protocol#Spawn_Experience_Orb -/// Spawns one or more experience orbs. -/// -/// wiki : [Spawn Experience Orb](https://wiki.vg/Protocol#Spawn_Experience_Orb) -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::EXPERIENCE_ORB_SPAWN_S2C)] -pub struct ExperienceOrbSpawnS2c { - pub entity_id: VarInt, - pub position: DVec3, - /// The amount of experience this orb will reward once collected. - pub count: i16, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::REMOVE_ENTITY_STATUS_EFFECT_S2C)] -pub struct RemoveEntityStatusEffectS2c { - pub entity_id: VarInt, - pub effect_id: VarInt, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ITEM_PICKUP_ANIMATION_S2C)] -pub struct ItemPickupAnimationS2c { - pub collected_entity_id: VarInt, - pub collector_entity_id: VarInt, - pub pickup_item_count: VarInt, -} - -/// Instructs a client to face an entity. -#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::LOOK_AT_S2C)] -pub struct LookAtS2c { - pub feet_or_eyes: FeetOrEyes, - pub target_position: DVec3, - pub entity_to_face: Option, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum FeetOrEyes { - Feet, - Eyes, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub struct LookAtEntity { - pub entity_id: VarInt, - pub feet_or_eyes: FeetOrEyes, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::SET_CAMERA_ENTITY_S2C)] -pub struct SetCameraEntityS2c { - pub entity_id: VarInt, -} diff --git a/crates/valence_packet/src/instance.rs b/crates/valence_packet/src/instance.rs deleted file mode 100644 index d7d727863..000000000 --- a/crates/valence_packet/src/instance.rs +++ /dev/null @@ -1,139 +0,0 @@ -use valence_core::chunk_pos::ChunkPos; -use valence_core::protocol::array::LengthPrefixedArray; - -use super::*; - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::WORLD_EVENT_S2C)] -pub struct WorldEventS2c { - pub event: i32, - pub location: BlockPos, - pub data: i32, - pub disable_relative_volume: bool, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::WORLD_TIME_UPDATE_S2C)] -pub struct WorldTimeUpdateS2c { - /// The age of the world in 1/20ths of a second. - pub world_age: i64, - /// The current time of day in 1/20ths of a second. - /// The value should be in the range \[0, 24000]. - /// 6000 is noon, 12000 is sunset, and 18000 is midnight. - pub time_of_day: i64, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CHUNK_BIOME_DATA_S2C)] -pub struct ChunkBiomeDataS2c<'a> { - pub chunks: Cow<'a, [ChunkBiome<'a>]>, -} - -#[derive(Clone, Debug, Encode, Decode)] -pub struct ChunkBiome<'a> { - pub pos: ChunkPos, - /// Chunk data structure, with sections containing only the `Biomes` field. - pub data: &'a [u8], -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CHUNK_DATA_S2C)] -pub struct ChunkDataS2c<'a> { - pub pos: ChunkPos, - pub heightmaps: Cow<'a, Compound>, - pub blocks_and_biomes: &'a [u8], - pub block_entities: Cow<'a, [ChunkDataBlockEntity<'a>]>, - pub sky_light_mask: Cow<'a, [u64]>, - pub block_light_mask: Cow<'a, [u64]>, - pub empty_sky_light_mask: Cow<'a, [u64]>, - pub empty_block_light_mask: Cow<'a, [u64]>, - pub sky_light_arrays: Cow<'a, [LengthPrefixedArray]>, - pub block_light_arrays: Cow<'a, [LengthPrefixedArray]>, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct ChunkDataBlockEntity<'a> { - pub packed_xz: i8, - pub y: i16, - pub kind: VarInt, - pub data: Cow<'a, Compound>, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CHUNK_DELTA_UPDATE_S2C)] -pub struct ChunkDeltaUpdateS2c<'a> { - pub chunk_section_position: i64, - pub blocks: Cow<'a, [VarLong]>, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CHUNK_LOAD_DISTANCE_S2C)] -pub struct ChunkLoadDistanceS2c { - pub view_distance: VarInt, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::UNLOAD_CHUNK_S2C)] -pub struct UnloadChunkS2c { - pub pos: ChunkPos, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CHUNK_RENDER_DISTANCE_CENTER_S2C)] -pub struct ChunkRenderDistanceCenterS2c { - pub chunk_x: VarInt, - pub chunk_z: VarInt, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::LIGHT_UPDATE_S2C)] -pub struct LightUpdateS2c { - pub chunk_x: VarInt, - pub chunk_z: VarInt, - pub sky_light_mask: Vec, - pub block_light_mask: Vec, - pub empty_sky_light_mask: Vec, - pub empty_block_light_mask: Vec, - pub sky_light_arrays: Vec>, - pub block_light_arrays: Vec>, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::BLOCK_BREAKING_PROGRESS_S2C)] -pub struct BlockBreakingProgressS2c { - pub entity_id: VarInt, - pub position: BlockPos, - pub destroy_stage: u8, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::BLOCK_ENTITY_UPDATE_S2C)] -pub struct BlockEntityUpdateS2c<'a> { - pub position: BlockPos, - pub kind: VarInt, - pub data: Cow<'a, Compound>, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::BLOCK_EVENT_S2C)] -pub struct BlockEventS2c { - pub position: BlockPos, - pub action_id: u8, - pub action_parameter: u8, - pub block_type: VarInt, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::BLOCK_UPDATE_S2C)] -pub struct BlockUpdateS2c { - pub position: BlockPos, - pub block_id: VarInt, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::EXPLOSION_S2C)] -pub struct ExplosionS2c<'a> { - pub window_id: u8, - pub recipe: Ident>, - pub make_all: bool, -} diff --git a/crates/valence_packet/src/inventory.rs b/crates/valence_packet/src/inventory.rs deleted file mode 100644 index ee3ed2cb0..000000000 --- a/crates/valence_packet/src/inventory.rs +++ /dev/null @@ -1,778 +0,0 @@ -use valence_core::item::ItemStack; - -use super::*; - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CLICK_SLOT_C2S)] -pub struct ClickSlotC2s { - pub window_id: u8, - pub state_id: VarInt, - pub slot_idx: i16, - /// The button used to click the slot. An enum can't easily be used for this - /// because the meaning of this value depends on the mode. - pub button: i8, - pub mode: ClickMode, - pub slot_changes: Vec, - pub carried_item: Option, -} - -#[derive(Copy, Clone, Debug, PartialEq, Eq, Encode, Decode)] -pub enum ClickMode { - Click, - ShiftClick, - Hotbar, - CreativeMiddleClick, - DropKey, - Drag, - DoubleClick, -} - -#[derive(Clone, Debug, Encode, Decode)] -pub struct SlotChange { - pub idx: i16, - pub item: Option, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CLOSE_HANDLED_SCREEN_C2S)] -pub struct CloseHandledScreenC2s { - pub window_id: i8, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CREATIVE_INVENTORY_ACTION_C2S)] -pub struct CreativeInventoryActionC2s { - pub slot: i16, - pub clicked_item: Option, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::UPDATE_SELECTED_SLOT_C2S)] -pub struct UpdateSelectedSlotC2s { - pub slot: i16, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CLOSE_SCREEN_S2C)] -pub struct CloseScreenS2c { - /// Ignored by notchian clients. - pub window_id: u8, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::INVENTORY_S2C)] -pub struct InventoryS2c<'a> { - pub window_id: u8, - pub state_id: VarInt, - pub slots: Cow<'a, [Option]>, - pub carried_item: Cow<'a, Option>, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum WindowType { - Generic9x1, - Generic9x2, - Generic9x3, - Generic9x4, - Generic9x5, - Generic9x6, - Generic3x3, - Anvil, - Beacon, - BlastFurnace, - BrewingStand, - Crafting, - Enchantment, - Furnace, - Grindstone, - Hopper, - Lectern, - Loom, - Merchant, - ShulkerBox, - Smithing, - Smoker, - Cartography, - Stonecutter, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::OPEN_SCREEN_S2C)] -pub struct OpenScreenS2c<'a> { - pub window_id: VarInt, - pub window_type: WindowType, - pub window_title: Cow<'a, Text>, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::OPEN_HORSE_SCREEN_S2C)] -pub struct OpenHorseScreenS2c { - pub window_id: u8, - pub slot_count: VarInt, - pub entity_id: i32, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::SCREEN_HANDLER_SLOT_UPDATE_S2C)] -pub struct ScreenHandlerSlotUpdateS2c<'a> { - pub window_id: i8, - pub state_id: VarInt, - pub slot_idx: i16, - pub slot_data: Cow<'a, Option>, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::SCREEN_HANDLER_PROPERTY_UPDATE_S2C)] -pub struct ScreenHandlerPropertyUpdateS2c { - pub window_id: u8, - pub property: i16, - pub value: i16, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CRAFT_REQUEST_C2S)] -pub struct CraftRequestC2s<'a> { - pub window_id: i8, - pub recipe: Ident>, - pub make_all: bool, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CRAFT_FAILED_RESPONSE_S2C)] -pub struct CraftFailedResponseS2c<'a> { - pub window_id: u8, - pub recipe: Ident>, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PICK_FROM_INVENTORY_C2S)] -pub struct PickFromInventoryC2s { - pub slot_to_use: VarInt, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::SET_TRADE_OFFERS_S2C)] -pub struct SetTradeOffersS2c { - pub window_id: VarInt, - pub trades: Vec, - pub villager_level: VarInt, - pub experience: VarInt, - pub is_regular_villager: bool, - pub can_restock: bool, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct TradeOffer { - pub input_one: Option, - pub output_item: Option, - pub input_two: Option, - pub trade_disabled: bool, - pub number_of_trade_uses: i32, - pub max_trade_uses: i32, - pub xp: i32, - pub special_price: i32, - pub price_multiplier: f32, - pub demand: i32, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::BUTTON_CLICK_C2S)] -pub struct ButtonClickC2s { - pub window_id: i8, - pub button_id: i8, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::RECIPE_BOOK_DATA_C2S)] -pub struct RecipeBookDataC2s<'a> { - pub recipe_id: Ident>, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::RENAME_ITEM_C2S)] -pub struct RenameItemC2s<'a> { - pub item_name: &'a str, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::RECIPE_CATEGORY_OPTIONS_C2S)] -pub struct RecipeCategoryOptionsC2s { - pub book_id: RecipeBookId, - pub book_open: bool, - pub filter_active: bool, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum RecipeBookId { - Crafting, - Furnace, - BlastFurnace, - Smoker, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::SELECT_MERCHANT_TRADE_C2S)] -pub struct SelectMerchantTradeC2s { - pub selected_slot: VarInt, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::UPDATE_BEACON_C2S)] -pub struct UpdateBeaconC2s { - pub primary_effect: Option, - pub secondary_effect: Option, -} - -#[derive(Clone, PartialEq, Eq, Debug, Packet)] -#[packet(id = packet_id::UNLOCK_RECIPES_S2C)] -pub struct UnlockRecipesS2c<'a> { - pub action: UpdateRecipeBookAction<'a>, - pub crafting_recipe_book_open: bool, - pub crafting_recipe_book_filter_active: bool, - pub smelting_recipe_book_open: bool, - pub smelting_recipe_book_filter_active: bool, - pub blast_furnace_recipe_book_open: bool, - pub blast_furnace_recipe_book_filter_active: bool, - pub smoker_recipe_book_open: bool, - pub smoker_recipe_book_filter_active: bool, - pub recipe_ids: Vec>>, -} - -#[derive(Clone, PartialEq, Eq, Debug)] -pub enum UpdateRecipeBookAction<'a> { - Init { - recipe_ids: Vec>>, - }, - Add, - Remove, -} - -impl Encode for UnlockRecipesS2c<'_> { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - VarInt(match &self.action { - UpdateRecipeBookAction::Init { .. } => 0, - UpdateRecipeBookAction::Add => 1, - UpdateRecipeBookAction::Remove => 2, - }) - .encode(&mut w)?; - - self.crafting_recipe_book_open.encode(&mut w)?; - self.crafting_recipe_book_filter_active.encode(&mut w)?; - self.smelting_recipe_book_open.encode(&mut w)?; - self.smelting_recipe_book_filter_active.encode(&mut w)?; - self.blast_furnace_recipe_book_open.encode(&mut w)?; - self.blast_furnace_recipe_book_filter_active - .encode(&mut w)?; - self.smoker_recipe_book_open.encode(&mut w)?; - self.smoker_recipe_book_filter_active.encode(&mut w)?; - self.recipe_ids.encode(&mut w)?; - if let UpdateRecipeBookAction::Init { recipe_ids } = &self.action { - recipe_ids.encode(&mut w)?; - } - - Ok(()) - } -} - -impl<'a> Decode<'a> for UnlockRecipesS2c<'a> { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - let action_id = VarInt::decode(r)?.0; - - let crafting_recipe_book_open = bool::decode(r)?; - let crafting_recipe_book_filter_active = bool::decode(r)?; - let smelting_recipe_book_open = bool::decode(r)?; - let smelting_recipe_book_filter_active = bool::decode(r)?; - let blast_furnace_recipe_book_open = bool::decode(r)?; - let blast_furnace_recipe_book_filter_active = bool::decode(r)?; - let smoker_recipe_book_open = bool::decode(r)?; - let smoker_recipe_book_filter_active = bool::decode(r)?; - let recipe_ids = Vec::decode(r)?; - - Ok(Self { - action: match action_id { - 0 => UpdateRecipeBookAction::Init { - recipe_ids: Vec::decode(r)?, - }, - 1 => UpdateRecipeBookAction::Add, - 2 => UpdateRecipeBookAction::Remove, - n => bail!("unknown recipe book action of {n}"), - }, - crafting_recipe_book_open, - crafting_recipe_book_filter_active, - smelting_recipe_book_open, - smelting_recipe_book_filter_active, - blast_furnace_recipe_book_open, - blast_furnace_recipe_book_filter_active, - smoker_recipe_book_open, - smoker_recipe_book_filter_active, - recipe_ids, - }) - } -} - -pub mod synchronize_recipes { - use anyhow::ensure; - - use super::*; - - #[derive(Clone, Debug, Encode, Decode, Packet)] - #[packet(id = packet_id::SYNCHRONIZE_RECIPES_S2C)] - pub struct SynchronizeRecipesS2c<'a> { - // TODO: this should be a Vec> - pub recipes: valence_core::protocol::raw::RawBytes<'a>, - } - - #[derive(Clone, PartialEq, Debug)] - pub enum Recipe<'a> { - CraftingShapeless { - recipe_id: Ident>, - group: &'a str, - category: CraftingCategory, - ingredients: Vec, - result: Option, - }, - CraftingShaped { - recipe_id: Ident>, - width: VarInt, - height: VarInt, - group: &'a str, - category: CraftingCategory, - ingredients: Vec, - result: Option, - }, - CraftingSpecial { - kind: SpecialCraftingKind, - recipe_id: Ident>, - category: CraftingCategory, - }, - Smelting { - recipe_id: Ident>, - group: &'a str, - category: SmeltCategory, - ingredient: Ingredient, - result: Option, - experience: f32, - cooking_time: VarInt, - }, - Blasting { - recipe_id: Ident>, - group: &'a str, - category: SmeltCategory, - ingredient: Ingredient, - result: Option, - experience: f32, - cooking_time: VarInt, - }, - Smoking { - recipe_id: Ident>, - group: &'a str, - category: SmeltCategory, - ingredient: Ingredient, - result: Option, - experience: f32, - cooking_time: VarInt, - }, - CampfireCooking { - recipe_id: Ident>, - group: &'a str, - category: SmeltCategory, - ingredient: Ingredient, - result: Option, - experience: f32, - cooking_time: VarInt, - }, - Stonecutting { - recipe_id: Ident>, - group: &'a str, - ingredient: Ingredient, - result: Option, - }, - SmithingTransform { - recipe_id: Ident>, - template: Ingredient, - base: Ingredient, - addition: Ingredient, - result: Option, - }, - SmithingTrim { - recipe_id: Ident>, - template: Ingredient, - base: Ingredient, - addition: Ingredient, - }, - } - - #[derive(Copy, Clone, PartialEq, Eq, Debug)] - pub enum SpecialCraftingKind { - ArmorDye, - BookCloning, - MapCloning, - MapExtending, - FireworkRocket, - FireworkStar, - FireworkStarFade, - RepairItem, - TippedArrow, - BannerDuplicate, - BannerAddPattern, - ShieldDecoration, - ShulkerBoxColoring, - SuspiciousStew, - } - - /// Any item in the Vec may be used for the recipe. - pub type Ingredient = Vec>; - - #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] - pub enum CraftingCategory { - Building, - Redstone, - Equipment, - Misc, - } - - #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] - pub enum SmeltCategory { - Food, - Blocks, - Misc, - } - - impl<'a> Encode for Recipe<'a> { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - match self { - Recipe::CraftingShapeless { - recipe_id, - group, - category, - ingredients, - result, - } => { - "crafting_shapeless".encode(&mut w)?; - recipe_id.encode(&mut w)?; - group.encode(&mut w)?; - category.encode(&mut w)?; - ingredients.encode(&mut w)?; - result.encode(w) - } - Recipe::CraftingShaped { - recipe_id, - width, - height, - group, - category, - ingredients, - result, - } => { - "crafting_shaped".encode(&mut w)?; - recipe_id.encode(&mut w)?; - width.encode(&mut w)?; - height.encode(&mut w)?; - group.encode(&mut w)?; - category.encode(&mut w)?; - - ensure!( - (width.0 as usize).saturating_mul(height.0 as usize) == ingredients.len(), - "width * height must be equal to the number of ingredients" - ); - - for ing in ingredients { - ing.encode(&mut w)?; - } - - result.encode(w) - } - Recipe::CraftingSpecial { - kind, - recipe_id, - category, - } => { - match kind { - SpecialCraftingKind::ArmorDye => "crafting_special_armordye", - SpecialCraftingKind::BookCloning => "crafting_special_bookcloning", - SpecialCraftingKind::MapCloning => "crafting_special_mapcloning", - SpecialCraftingKind::MapExtending => "crafting_special_mapextending", - SpecialCraftingKind::FireworkRocket => "crafting_special_firework_rocket", - SpecialCraftingKind::FireworkStar => "crafting_special_firework_star", - SpecialCraftingKind::FireworkStarFade => { - "crafting_special_firework_star_fade" - } - SpecialCraftingKind::RepairItem => "crafting_special_repairitem", - SpecialCraftingKind::TippedArrow => "crafting_special_tippedarrow", - SpecialCraftingKind::BannerDuplicate => "crafting_special_bannerduplicate", - SpecialCraftingKind::BannerAddPattern => { - "crafting_special_banneraddpattern" - } - SpecialCraftingKind::ShieldDecoration => { - "crafting_special_shielddecoration" - } - SpecialCraftingKind::ShulkerBoxColoring => { - "crafting_special_shulkerboxcoloring" - } - SpecialCraftingKind::SuspiciousStew => "crafting_special_suspiciousstew", - } - .encode(&mut w)?; - recipe_id.encode(&mut w)?; - category.encode(w) - } - Recipe::Smelting { - recipe_id, - group, - category, - ingredient, - result, - experience, - cooking_time, - } => { - "smelting".encode(&mut w)?; - recipe_id.encode(&mut w)?; - group.encode(&mut w)?; - category.encode(&mut w)?; - ingredient.encode(&mut w)?; - result.encode(&mut w)?; - experience.encode(&mut w)?; - cooking_time.encode(w) - } - Recipe::Blasting { - recipe_id, - group, - category, - ingredient, - result, - experience, - cooking_time, - } => { - "blasting".encode(&mut w)?; - recipe_id.encode(&mut w)?; - group.encode(&mut w)?; - category.encode(&mut w)?; - ingredient.encode(&mut w)?; - result.encode(&mut w)?; - experience.encode(&mut w)?; - cooking_time.encode(w) - } - Recipe::Smoking { - recipe_id, - group, - category, - ingredient, - result, - experience, - cooking_time, - } => { - "smoking".encode(&mut w)?; - recipe_id.encode(&mut w)?; - group.encode(&mut w)?; - category.encode(&mut w)?; - ingredient.encode(&mut w)?; - result.encode(&mut w)?; - experience.encode(&mut w)?; - cooking_time.encode(w) - } - Recipe::CampfireCooking { - recipe_id, - group, - category, - ingredient, - result, - experience, - cooking_time, - } => { - "campfire_cooking".encode(&mut w)?; - recipe_id.encode(&mut w)?; - group.encode(&mut w)?; - category.encode(&mut w)?; - ingredient.encode(&mut w)?; - result.encode(&mut w)?; - experience.encode(&mut w)?; - cooking_time.encode(w) - } - Recipe::Stonecutting { - recipe_id, - group, - ingredient, - result, - } => { - "stonecutting".encode(&mut w)?; - recipe_id.encode(&mut w)?; - group.encode(&mut w)?; - ingredient.encode(&mut w)?; - result.encode(w) - } - Recipe::SmithingTransform { - recipe_id, - template, - base, - addition, - result, - } => { - "smithing_transform".encode(&mut w)?; - recipe_id.encode(&mut w)?; - template.encode(&mut w)?; - base.encode(&mut w)?; - addition.encode(&mut w)?; - result.encode(&mut w) - } - Recipe::SmithingTrim { - recipe_id, - template, - base, - addition, - } => { - "smithing_trim".encode(&mut w)?; - recipe_id.encode(&mut w)?; - template.encode(&mut w)?; - base.encode(&mut w)?; - addition.encode(&mut w) - } - } - } - } - - impl<'a> Decode<'a> for Recipe<'a> { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - Ok(match Ident::>::decode(r)?.as_str() { - "minecraft:crafting_shapeless" => Self::CraftingShapeless { - recipe_id: Decode::decode(r)?, - group: Decode::decode(r)?, - category: Decode::decode(r)?, - ingredients: Decode::decode(r)?, - result: Decode::decode(r)?, - }, - "minecraft:crafting_shaped" => { - let recipe_id = Ident::decode(r)?; - let width = VarInt::decode(r)?.0; - let height = VarInt::decode(r)?.0; - let group = <&str>::decode(r)?; - let category = CraftingCategory::decode(r)?; - - let mut ingredients = Vec::new(); - for _ in 0..width.saturating_mul(height) { - ingredients.push(Ingredient::decode(r)?); - } - - Self::CraftingShaped { - recipe_id, - width: VarInt(width), - height: VarInt(height), - group, - category, - ingredients, - result: Decode::decode(r)?, - } - } - "minecraft:smelting" => Self::Smelting { - recipe_id: Decode::decode(r)?, - group: Decode::decode(r)?, - category: Decode::decode(r)?, - ingredient: Decode::decode(r)?, - result: Decode::decode(r)?, - experience: Decode::decode(r)?, - cooking_time: Decode::decode(r)?, - }, - "minecraft:blasting" => Self::Blasting { - recipe_id: Decode::decode(r)?, - group: Decode::decode(r)?, - category: Decode::decode(r)?, - ingredient: Decode::decode(r)?, - result: Decode::decode(r)?, - experience: Decode::decode(r)?, - cooking_time: Decode::decode(r)?, - }, - "minecraft:smoking" => Self::Smoking { - recipe_id: Decode::decode(r)?, - group: Decode::decode(r)?, - category: Decode::decode(r)?, - ingredient: Decode::decode(r)?, - result: Decode::decode(r)?, - experience: Decode::decode(r)?, - cooking_time: Decode::decode(r)?, - }, - "minecraft:campfire_cooking" => Self::CampfireCooking { - recipe_id: Decode::decode(r)?, - group: Decode::decode(r)?, - category: Decode::decode(r)?, - ingredient: Decode::decode(r)?, - result: Decode::decode(r)?, - experience: Decode::decode(r)?, - cooking_time: Decode::decode(r)?, - }, - "minecraft:stonecutting" => Self::Stonecutting { - recipe_id: Decode::decode(r)?, - group: Decode::decode(r)?, - ingredient: Decode::decode(r)?, - result: Decode::decode(r)?, - }, - "minecraft:smithing_transform" => Self::SmithingTransform { - recipe_id: Decode::decode(r)?, - template: Decode::decode(r)?, - base: Decode::decode(r)?, - addition: Decode::decode(r)?, - result: Decode::decode(r)?, - }, - "minecraft:smithing_trim" => Self::SmithingTrim { - recipe_id: Decode::decode(r)?, - template: Decode::decode(r)?, - base: Decode::decode(r)?, - addition: Decode::decode(r)?, - }, - other => Self::CraftingSpecial { - kind: match other { - "minecraft:crafting_special_armordye" => SpecialCraftingKind::ArmorDye, - "minecraft:crafting_special_bookcloning" => { - SpecialCraftingKind::BookCloning - } - "minecraft:crafting_special_mapcloning" => SpecialCraftingKind::MapCloning, - "minecraft:crafting_special_mapextending" => { - SpecialCraftingKind::MapExtending - } - "minecraft:crafting_special_firework_rocket" => { - SpecialCraftingKind::FireworkRocket - } - "minecraft:crafting_special_firework_star" => { - SpecialCraftingKind::FireworkStar - } - "minecraft:crafting_special_firework_star_fade" => { - SpecialCraftingKind::FireworkStarFade - } - "minecraft:crafting_special_repairitem" => SpecialCraftingKind::RepairItem, - "minecraft:crafting_special_tippedarrow" => { - SpecialCraftingKind::TippedArrow - } - "minecraft:crafting_special_bannerduplicate" => { - SpecialCraftingKind::BannerDuplicate - } - "minecraft:crafting_special_banneraddpattern" => { - SpecialCraftingKind::BannerAddPattern - } - "minecraft:crafting_special_shielddecoration" => { - SpecialCraftingKind::ShieldDecoration - } - "minecraft:crafting_special_shulkerboxcoloring" => { - SpecialCraftingKind::ShulkerBoxColoring - } - "minecraft:crafting_special_suspiciousstew" => { - SpecialCraftingKind::SuspiciousStew - } - _ => bail!("unknown recipe type \"{other}\""), - }, - recipe_id: Decode::decode(r)?, - category: CraftingCategory::decode(r)?, - }, - }) - } - } -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::COOLDOWN_UPDATE_S2C)] -pub struct CooldownUpdateS2c { - pub item_id: VarInt, - pub cooldown_ticks: VarInt, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::UPDATE_SELECTED_SLOT_S2C)] -pub struct UpdateSelectedSlotS2c { - pub slot: u8, -} diff --git a/crates/valence_packet/src/lib.rs b/crates/valence_packet/src/lib.rs index bf18758a4..112a343ef 100644 --- a/crates/valence_packet/src/lib.rs +++ b/crates/valence_packet/src/lib.rs @@ -1,40 +1,10 @@ -use std::borrow::Cow; -use std::io::Write; +pub mod packets; +pub mod protocol; -use anyhow::bail; -use bitfield_struct::bitfield; -use byteorder::WriteBytesExt; -use glam::{DVec3, IVec3}; -use uuid::Uuid; -use valence_core::block_pos::BlockPos; -use valence_core::difficulty::Difficulty; -use valence_core::direction::Direction; -use valence_core::game_mode::GameMode; -use valence_core::hand::Hand; -use valence_core::ident::Ident; -use valence_core::item::ItemStack; -use valence_core::property::Property; -use valence_core::protocol::byte_angle::ByteAngle; -use valence_core::protocol::global_pos::GlobalPos; -use valence_core::protocol::raw::RawBytes; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::var_long::VarLong; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; -use valence_core::text::Text; -use valence_nbt::Compound; +/// Used only by macros. Not public API. +#[doc(hidden)] +pub mod __private { + pub use crate::protocol::Packet; +} -pub mod advancement; -pub mod boss_bar; -pub mod chat; -pub mod client; -pub mod command; -pub mod entity; -pub mod instance; -pub mod inventory; -pub mod map; -pub mod network; -pub mod packets; -pub mod player_list; -pub mod scoreboard; -pub mod sound; -pub mod world_border; +extern crate self as valence_packet; \ No newline at end of file diff --git a/crates/valence_packet/src/map.rs b/crates/valence_packet/src/map.rs deleted file mode 100644 index 1e809d864..000000000 --- a/crates/valence_packet/src/map.rs +++ /dev/null @@ -1,109 +0,0 @@ -use super::*; - -#[derive(Clone, PartialEq, Debug, Packet)] -#[packet(id = packet_id::MAP_UPDATE_S2C)] -pub struct MapUpdateS2c<'a> { - pub map_id: VarInt, - pub scale: i8, - pub locked: bool, - pub icons: Option>>, - pub data: Option>, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct Icon<'a> { - pub icon_type: IconType, - /// In map coordinates; -128 for furthest left, +127 for furthest right - pub position: [i8; 2], - /// 0 is a vertical icon and increments by 22.5° - pub direction: i8, - pub display_name: Option>, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum IconType { - WhiteArrow, - GreenArrow, - RedArrow, - BlueArrow, - WhiteCross, - RedPointer, - WhiteCircle, - SmallWhiteCircle, - Mansion, - Temple, - WhiteBanner, - OrangeBanner, - MagentaBanner, - LightBlueBanner, - YellowBanner, - LimeBanner, - PinkBanner, - GrayBanner, - LightGrayBanner, - CyanBanner, - PurpleBanner, - BlueBanner, - BrownBanner, - GreenBanner, - RedBanner, - BlackBanner, - TreasureMarker, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode)] -pub struct Data<'a> { - pub columns: u8, - pub rows: u8, - pub position: [i8; 2], - pub data: &'a [u8], -} - -impl Encode for MapUpdateS2c<'_> { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - self.map_id.encode(&mut w)?; - self.scale.encode(&mut w)?; - self.locked.encode(&mut w)?; - self.icons.encode(&mut w)?; - - match self.data { - None => 0u8.encode(&mut w)?, - Some(data) => data.encode(&mut w)?, - } - - Ok(()) - } -} - -impl<'a> Decode<'a> for MapUpdateS2c<'a> { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - let map_id = VarInt::decode(r)?; - let scale = i8::decode(r)?; - let locked = bool::decode(r)?; - let icons = >>>::decode(r)?; - let columns = u8::decode(r)?; - - let data = if columns > 0 { - let rows = u8::decode(r)?; - let position = <[i8; 2]>::decode(r)?; - let data = <&'a [u8]>::decode(r)?; - - Some(Data { - columns, - rows, - position, - data, - }) - } else { - None - }; - - Ok(Self { - map_id, - scale, - locked, - icons, - data, - }) - } -} diff --git a/crates/valence_packet/src/network.rs b/crates/valence_packet/src/network.rs deleted file mode 100644 index ed6dc402b..000000000 --- a/crates/valence_packet/src/network.rs +++ /dev/null @@ -1,99 +0,0 @@ -use valence_core::protocol::PacketState; - -use super::*; - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::HANDSHAKE_C2S, state = PacketState::Handshaking)] -pub struct HandshakeC2s<'a> { - pub protocol_version: VarInt, - pub server_address: &'a str, - pub server_port: u16, - pub next_state: HandshakeNextState, -} - -#[derive(Copy, Clone, Debug, PartialEq, Eq, Encode, Decode)] -pub enum HandshakeNextState { - #[packet(tag = 1)] - Status, - #[packet(tag = 2)] - Login, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::QUERY_PING_C2S, state = PacketState::Status)] -pub struct QueryPingC2s { - pub payload: u64, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::QUERY_REQUEST_C2S, state = PacketState::Status)] -pub struct QueryRequestC2s; - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::QUERY_PONG_S2C, state = PacketState::Status)] -pub struct QueryPongS2c { - pub payload: u64, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::QUERY_RESPONSE_S2C, state = PacketState::Status)] -pub struct QueryResponseS2c<'a> { - pub json: &'a str, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::LOGIN_HELLO_C2S, state = PacketState::Login)] -pub struct LoginHelloC2s<'a> { - pub username: &'a str, // TODO: bound this - pub profile_id: Option, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::LOGIN_KEY_C2S, state = PacketState::Login)] -pub struct LoginKeyC2s<'a> { - pub shared_secret: &'a [u8], - pub verify_token: &'a [u8], -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::LOGIN_QUERY_RESPONSE_C2S, state = PacketState::Login)] -pub struct LoginQueryResponseC2s<'a> { - pub message_id: VarInt, - pub data: Option>, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::LOGIN_COMPRESSION_S2C, state = PacketState::Login)] -pub struct LoginCompressionS2c { - pub threshold: VarInt, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::LOGIN_DISCONNECT_S2C, state = PacketState::Login)] -pub struct LoginDisconnectS2c<'a> { - pub reason: Cow<'a, Text>, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::LOGIN_HELLO_S2C, state = PacketState::Login)] -pub struct LoginHelloS2c<'a> { - pub server_id: &'a str, - pub public_key: &'a [u8], - pub verify_token: &'a [u8], -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::LOGIN_QUERY_REQUEST_S2C, state = PacketState::Login)] -pub struct LoginQueryRequestS2c<'a> { - pub message_id: VarInt, - pub channel: Ident>, - pub data: RawBytes<'a>, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::LOGIN_SUCCESS_S2C, state = PacketState::Login)] -pub struct LoginSuccessS2c<'a> { - pub uuid: Uuid, - pub username: &'a str, // TODO: bound this. - pub properties: Cow<'a, [Property]>, -} diff --git a/crates/valence_packet/src/packets.rs b/crates/valence_packet/src/packets.rs index 32c627120..95a3a203d 100644 --- a/crates/valence_packet/src/packets.rs +++ b/crates/valence_packet/src/packets.rs @@ -5,10 +5,11 @@ use anyhow::bail; use uuid::Uuid; use valence_core::ident::Ident; use valence_core::property::Property; -use valence_core::protocol::raw::RawBytes; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; use valence_core::text::Text; +use valence_core::protocol::var_int::VarInt; +use valence_core::protocol::{Encode, Decode}; +use valence_core::protocol::raw::RawBytes; +use crate::protocol::{Packet, packet_id, PacketState}; pub mod handshaking; pub mod login; diff --git a/crates/valence_packet/src/packets/handshaking.rs b/crates/valence_packet/src/packets/handshaking.rs new file mode 100644 index 000000000..1aa5cbef3 --- /dev/null +++ b/crates/valence_packet/src/packets/handshaking.rs @@ -0,0 +1,4 @@ +use super::*; + +pub mod handshake_c2s; +pub use handshake_c2s::HandshakeC2s; \ No newline at end of file diff --git a/crates/valence_packet/src/packets/handshaking/mod.rs b/crates/valence_packet/src/packets/handshaking/mod.rs deleted file mode 100644 index 75f7a049d..000000000 --- a/crates/valence_packet/src/packets/handshaking/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -use valence_core::protocol::PacketState; - -use super::*; - -pub mod handshake_c2s; diff --git a/crates/valence_packet/src/packets/login.rs b/crates/valence_packet/src/packets/login.rs new file mode 100644 index 000000000..6c337f9a7 --- /dev/null +++ b/crates/valence_packet/src/packets/login.rs @@ -0,0 +1,18 @@ +use super::*; + +pub mod login_compression_s2c; +pub use login_compression_s2c::LoginCompressionS2c; +pub mod login_disconnect_s2c; +pub use login_disconnect_s2c::LoginDisconnectS2c; +pub mod login_hello_c2s; +pub use login_hello_c2s::LoginHelloC2s; +pub mod login_hello_s2c; +pub use login_hello_s2c::LoginHelloS2c; +pub mod login_key_c2s; +pub use login_key_c2s::LoginKeyC2s; +pub mod login_query_request_s2c; +pub use login_query_request_s2c::LoginQueryRequestS2c; +pub mod login_query_response_c2s; +pub use login_query_response_c2s::LoginQueryResponseC2s; +pub mod login_success_s2c; +pub use login_success_s2c::LoginSuccessS2c; diff --git a/crates/valence_packet/src/packets/login/login_compression_s2c.rs b/crates/valence_packet/src/packets/login/login_compression_s2c.rs index bfee7a4e6..781a38026 100644 --- a/crates/valence_packet/src/packets/login/login_compression_s2c.rs +++ b/crates/valence_packet/src/packets/login/login_compression_s2c.rs @@ -1,5 +1,3 @@ -use valence_core::protocol::PacketState; - use super::*; #[derive(Copy, Clone, Debug, Encode, Decode, Packet)] diff --git a/crates/valence_packet/src/packets/login/mod.rs b/crates/valence_packet/src/packets/login/mod.rs deleted file mode 100644 index 02147b9d5..000000000 --- a/crates/valence_packet/src/packets/login/mod.rs +++ /dev/null @@ -1,12 +0,0 @@ -use valence_core::protocol::PacketState; - -use super::*; - -pub mod login_compression_s2c; -pub mod login_disconnect_s2c; -pub mod login_hello_c2s; -pub mod login_hello_s2c; -pub mod login_key_c2s; -pub mod login_query_request_s2c; -pub mod login_query_response_c2s; -pub mod login_success_s2c; diff --git a/crates/valence_packet/src/packets/play.rs b/crates/valence_packet/src/packets/play.rs new file mode 100644 index 000000000..50bd28844 --- /dev/null +++ b/crates/valence_packet/src/packets/play.rs @@ -0,0 +1,341 @@ +use bitfield_struct::bitfield; +use byteorder::WriteBytesExt; +use glam::{DVec3, IVec3, Vec3}; +use valence_core::block_pos::BlockPos; +use valence_core::chunk_pos::ChunkPos; +use valence_core::difficulty::Difficulty; +use valence_core::direction::Direction; +use valence_core::game_mode::GameMode; +use valence_core::hand::Hand; +use valence_core::item::ItemStack; +use valence_core::protocol::byte_angle::ByteAngle; +use valence_core::protocol::global_pos::GlobalPos; +use valence_core::protocol::var_long::VarLong; +use valence_nbt::Compound; + +use super::*; + +pub mod advancement_tab_c2s; +pub use advancement_tab_c2s::AdvancementTabC2s; +pub mod advancement_update_s2c; +pub use advancement_update_s2c::AdvancementUpdateS2c; +pub mod block_breaking_progress_s2c; +pub use block_breaking_progress_s2c::BlockBreakingProgressS2c; +pub mod block_entity_update_s2c; +pub use block_entity_update_s2c::BlockEntityUpdateS2c; +pub mod block_event_s2c; +pub use block_event_s2c::BlockEventS2c; +pub mod block_update_s2c; +pub use block_update_s2c::BlockUpdateS2c; +pub mod boat_paddle_state_c2s; +pub use boat_paddle_state_c2s::BoatPaddleStateC2s; +pub mod book_update_c2s; +pub use book_update_c2s::BookUpdateC2s; +pub mod boss_bar_s2c; +pub use boss_bar_s2c::BossBarS2c; +pub mod bundle_splitter_s2c; +pub use bundle_splitter_s2c::BundleSplitterS2c; +pub mod button_click_c2s; +pub use button_click_c2s::ButtonClickC2s; +pub mod chat_message_c2s; +pub use chat_message_c2s::ChatMessageC2s; +pub mod chat_message_s2c; +pub use chat_message_s2c::ChatMessageS2c; +pub mod chat_suggestions_s2c; +pub use chat_suggestions_s2c::ChatSuggestionsS2c; +pub mod chunk_biome_data_s2c; +pub use chunk_biome_data_s2c::ChunkBiomeDataS2c; +pub mod chunk_data_s2c; +pub use chunk_data_s2c::ChunkDataS2c; +pub mod chunk_delta_update_s2c; +pub use chunk_delta_update_s2c::ChunkDeltaUpdateS2c; +pub mod chunk_load_distance_s2c; +pub use chunk_load_distance_s2c::ChunkLoadDistanceS2c; +pub mod chunk_render_distance_center_s2c; +pub use chunk_render_distance_center_s2c::ChunkRenderDistanceCenterS2c; +pub mod clear_title_s2c; +pub use clear_title_s2c::ClearTitleS2c; +pub mod click_slot_c2s; +pub use click_slot_c2s::ClickSlotC2s; +pub mod client_command_c2s; +pub use client_command_c2s::ClientCommandC2s; +pub mod client_settings_c2s; +pub use client_settings_c2s::ClientSettingsC2s; +pub mod client_status_c2s; +pub use client_status_c2s::ClientStatusC2s; +pub mod close_handled_screen_c2s; +pub use close_handled_screen_c2s::CloseHandledScreenC2s; +pub mod close_screen_s2c; +pub use close_screen_s2c::CloseScreenS2c; +pub mod command_execution_c2s; +pub use command_execution_c2s::CommandExecutionC2s; +pub mod command_suggestions_s2c; +pub use command_suggestions_s2c::CommandSuggestionsS2c; +pub mod command_tree_s2c; +pub use command_tree_s2c::CommandTreeS2c; +pub mod cooldown_update_s2c; +pub use cooldown_update_s2c::CooldownUpdateS2c; +pub mod craft_failed_response_s2c; +pub use craft_failed_response_s2c::CraftFailedResponseS2c; +pub mod craft_request_c2s; +pub use craft_request_c2s::CraftRequestC2s; +pub mod creative_inventory_action_c2s; +pub use creative_inventory_action_c2s::CreativeInventoryActionC2s; +pub mod custom_payload_c2s; +pub use custom_payload_c2s::CustomPayloadC2s; +pub mod custom_payload_s2c; +pub use custom_payload_s2c::CustomPayloadS2c; +pub mod damage_tilt_s2c; +pub use damage_tilt_s2c::DamageTiltS2c; +pub mod death_message_s2c; +pub use death_message_s2c::DeathMessageS2c; +pub mod difficulty_s2c; +pub use difficulty_s2c::DifficultyS2c; +pub mod disconnect_s2c; +pub use disconnect_s2c::DisconnectS2c; +pub mod end_combat_s2c; +pub use end_combat_s2c::EndCombatS2c; +pub mod enter_combat_s2c; +pub use enter_combat_s2c::EnterCombatS2c; +pub mod entities_destroy_s2c; +pub use entities_destroy_s2c::EntitiesDestroyS2c; +pub mod entity_animation_s2c; +pub use entity_animation_s2c::EntityAnimationS2c; +pub mod entity_attach_s2c; +pub use entity_attach_s2c::EntityAttachS2c; +pub mod entity_attributes_s2c; +pub use entity_attributes_s2c::EntityAttributesS2c; +pub mod entity_damage_s2c; +pub use entity_damage_s2c::EntityDamageS2c; +pub mod entity_equipment_update_s2c; +pub use entity_equipment_update_s2c::EntityEquipmentUpdateS2c; +pub mod entity_passengers_set_s2c; +pub use entity_passengers_set_s2c::EntityPassengersSetS2c; +pub mod entity_position_s2c; +pub use entity_position_s2c::EntityPositionS2c; +pub mod entity_set_head_yaw_s2c; +pub use entity_set_head_yaw_s2c::EntitySetHeadYawS2c; +pub mod entity_spawn_s2c; +pub use entity_spawn_s2c::EntitySpawnS2c; +pub mod entity_status_effect_s2c; +pub use entity_status_effect_s2c::EntityStatusEffectS2c; +pub mod entity_status_s2c; +pub use entity_status_s2c::EntityStatusS2c; +pub mod entity_tracker_update_s2c; +pub use entity_tracker_update_s2c::EntityTrackerUpdateS2c; +pub mod entity_velocity_update_s2c; +pub use entity_velocity_update_s2c::EntityVelocityUpdateS2c; +pub mod experience_bar_update_s2c; +pub use experience_bar_update_s2c::ExperienceBarUpdateS2c; +pub mod experience_orb_spawn_s2c; +pub use experience_orb_spawn_s2c::ExperienceOrbSpawnS2c; +pub mod explosion_s2c; +pub use explosion_s2c::ExplosionS2c; +pub mod features_s2c; +pub use features_s2c::FeaturesS2c; +pub mod full_c2s; +pub use full_c2s::FullC2s; +pub mod game_join_s2c; +pub use game_join_s2c::GameJoinS2c; +pub mod game_message_s2c; +pub use game_message_s2c::GameMessageS2c; +pub mod game_state_change_s2c; +pub use game_state_change_s2c::GameStateChangeS2c; +pub mod hand_swing_c2s; +pub use hand_swing_c2s::HandSwingC2s; +pub mod health_update_s2c; +pub use health_update_s2c::HealthUpdateS2c; +pub mod inventory_s2c; +pub use inventory_s2c::InventoryS2c; +pub mod item_pickup_animation_s2c; +pub use item_pickup_animation_s2c::ItemPickupAnimationS2c; +pub mod jigsaw_generating_c2s; +pub use jigsaw_generating_c2s::JigsawGeneratingC2s; +pub mod keep_alive_c2s; +pub use keep_alive_c2s::KeepAliveC2s; +pub mod keep_alive_s2c; +pub use keep_alive_s2c::KeepAliveS2c; +pub mod light_update_s2c; +pub use light_update_s2c::LightUpdateS2c; +pub mod look_and_on_ground_c2s; +pub use look_and_on_ground_c2s::LookAndOnGroundC2s; +pub mod look_at_s2c; +pub use look_at_s2c::LookAtS2c; +pub mod map_update_s2c; +pub use map_update_s2c::MapUpdateS2c; +pub mod message_acknowledgment_c2s; +pub use message_acknowledgment_c2s::MessageAcknowledgmentC2s; +pub mod move_relative_s2c; +pub use move_relative_s2c::MoveRelativeS2c; +pub mod nbt_query_response_s2c; +pub use nbt_query_response_s2c::NbtQueryResponseS2c; +pub mod on_ground_only_c2s; +pub use on_ground_only_c2s::OnGroundOnlyC2s; +pub mod open_horse_screen_s2c; +pub use open_horse_screen_s2c::OpenHorseScreenS2c; +pub mod open_screen_s2c; +pub use open_screen_s2c::OpenScreenS2c; +pub mod open_written_book_s2c; +pub use open_written_book_s2c::OpenWrittenBookS2c; +pub mod overlay_message_s2c; +pub use overlay_message_s2c::OverlayMessageS2c; +pub mod particle_s2c; +pub use particle_s2c::ParticleS2c; +pub mod pick_from_inventory_c2s; +pub use pick_from_inventory_c2s::PickFromInventoryC2s; +pub mod play_ping_s2c; +pub use play_ping_s2c::PlayPingS2c; +pub mod play_pong_c2s; +pub use play_pong_c2s::PlayPongC2s; +pub mod play_sound_from_entity_s2c; +pub use play_sound_from_entity_s2c::PlaySoundFromEntityS2c; +pub mod play_sound_s2c; +pub use play_sound_s2c::PlaySoundS2c; +pub mod player_abilities_s2c; +pub use player_abilities_s2c::PlayerAbilitiesS2c; +pub mod player_action_c2s; +pub use player_action_c2s::PlayerActionC2s; +pub mod player_action_response_s2c; +pub use player_action_response_s2c::PlayerActionResponseS2c; +pub mod player_input_c2s; +pub use player_input_c2s::PlayerInputC2s; +pub mod player_interact_block_c2s; +pub use player_interact_block_c2s::PlayerInteractBlockC2s; +pub mod player_interact_entity_c2s; +pub use player_interact_entity_c2s::PlayerInteractEntityC2s; +pub mod player_interact_item_c2s; +pub use player_interact_item_c2s::PlayerInteractItemC2s; +pub mod player_list_header_s2c; +pub use player_list_header_s2c::PlayerListHeaderS2c; +pub mod player_list_s2c; +pub use player_list_s2c::PlayerListS2c; +pub mod player_position_look_s2c; +pub use player_position_look_s2c::PlayerPositionLookS2c; +pub mod player_remove_s2c; +pub use player_remove_s2c::PlayerRemoveS2c; +pub mod player_respawn_s2c; +pub use player_respawn_s2c::PlayerRespawnS2c; +pub mod player_session_c2s; +pub use player_session_c2s::PlayerSessionC2s; +pub mod player_spawn_position_s2c; +pub use player_spawn_position_s2c::PlayerSpawnPositionS2c; +pub mod player_spawn_s2c; +pub use player_spawn_s2c::PlayerSpawnS2c; +pub mod position_and_on_ground_c2s; +pub use position_and_on_ground_c2s::PositionAndOnGroundC2s; +pub mod profileless_chat_message_s2c; +pub use profileless_chat_message_s2c::ProfilelessChatMessageS2c; +pub mod query_block_nbt_c2s; +pub use query_block_nbt_c2s::QueryBlockNbtC2s; +pub mod query_entity_nbt_c2s; +pub use query_entity_nbt_c2s::QueryEntityNbtC2s; +pub mod recipe_book_data_c2s; +pub use recipe_book_data_c2s::RecipeBookDataC2s; +pub mod recipe_category_options_c2s; +pub use recipe_category_options_c2s::RecipeCategoryOptionsC2s; +pub mod remove_entity_status_effect_s2c; +pub use remove_entity_status_effect_s2c::RemoveEntityStatusEffectS2c; +pub mod remove_message_s2c; +pub use remove_message_s2c::RemoveMessageS2c; +pub mod rename_item_c2s; +pub use rename_item_c2s::RenameItemC2s; +pub mod request_command_completions_c2s; +pub use request_command_completions_c2s::RequestCommandCompletionsC2s; +pub mod resource_pack_send_s2c; +pub use resource_pack_send_s2c::ResourcePackSendS2c; +pub mod resource_pack_status_c2s; +pub use resource_pack_status_c2s::ResourcePackStatusC2s; +pub mod rotate_s2c; +pub use rotate_s2c::RotateS2c; +pub mod rotate_and_move_relative_s2c; +pub use rotate_and_move_relative_s2c::RotateAndMoveRelativeS2c; +pub mod scoreboard_display_s2c; +pub use scoreboard_display_s2c::ScoreboardDisplayS2c; +pub mod scoreboard_objective_update_s2c; +pub use scoreboard_objective_update_s2c::ScoreboardObjectiveUpdateS2c; +pub mod scoreboard_player_update_s2c; +pub use scoreboard_player_update_s2c::ScoreboardPlayerUpdateS2c; +pub mod screen_handler_property_update_s2c; +pub use screen_handler_property_update_s2c::ScreenHandlerPropertyUpdateS2c; +pub mod screen_handler_slot_update_s2c; +pub use screen_handler_slot_update_s2c::ScreenHandlerSlotUpdateS2c; +pub mod select_advancement_tab_s2c; +pub use select_advancement_tab_s2c::SelectAdvancementTabS2c; +pub mod select_merchant_trade_c2s; +pub use select_merchant_trade_c2s::SelectMerchantTradeC2s; +pub mod server_metadata_s2c; +pub use server_metadata_s2c::ServerMetadataS2c; +pub mod set_camera_entity_s2c; +pub use set_camera_entity_s2c::SetCameraEntityS2c; +pub mod set_trade_offers_s2c; +pub use set_trade_offers_s2c::SetTradeOffersS2c; +pub mod sign_editor_open_s2c; +pub use sign_editor_open_s2c::SignEditorOpenS2c; +pub mod simulation_distance_s2c; +pub use simulation_distance_s2c::SimulationDistanceS2c; +pub mod spectator_teleport_c2s; +pub use spectator_teleport_c2s::SpectatorTeleportC2s; +pub mod statistics_s2c; +pub use statistics_s2c::StatisticsS2c; +pub mod stop_sound_s2c; +pub use stop_sound_s2c::StopSoundS2c; +pub mod subtitle_s2c; +pub use subtitle_s2c::SubtitleS2c; +pub mod synchronize_recipes_s2c; +pub use synchronize_recipes_s2c::SynchronizeRecipesS2c; +pub mod synchronize_tags_s2c; +pub use synchronize_tags_s2c::SynchronizeTagsS2c; +pub mod team_s2c; +pub use team_s2c::TeamS2c; +pub mod teleport_confirm_c2s; +pub use teleport_confirm_c2s::TeleportConfirmC2s; +pub mod title_fade_s2c; +pub use title_fade_s2c::TitleFadeS2c; +pub mod title_s2c; +pub use title_s2c::TitleS2c; +pub mod unload_chunk_s2c; +pub use unload_chunk_s2c::UnloadChunkS2c; +pub mod unlock_recipes_s2c; +pub use unlock_recipes_s2c::UnlockRecipesS2c; +pub mod update_beacon_c2s; +pub use update_beacon_c2s::UpdateBeaconC2s; +pub mod update_command_block_c2s; +pub use update_command_block_c2s::UpdateCommandBlockC2s; +pub mod update_command_block_minecart_c2s; +pub use update_command_block_minecart_c2s::UpdateCommandBlockMinecartC2s; +pub mod update_difficulty_c2s; +pub use update_difficulty_c2s::UpdateDifficultyC2s; +pub mod update_difficulty_lock_c2s; +pub use update_difficulty_lock_c2s::UpdateDifficultyLockC2s; +pub mod update_jigsaw_c2s; +pub use update_jigsaw_c2s::UpdateJigsawC2s; +pub mod update_player_abilities_c2s; +pub use update_player_abilities_c2s::UpdatePlayerAbilitiesC2s; +pub mod update_selected_slot_c2s; +pub use update_selected_slot_c2s::UpdateSelectedSlotC2s; +pub mod update_selected_slot_s2c; +pub use update_selected_slot_s2c::UpdateSelectedSlotS2c; +pub mod update_sign_c2s; +pub use update_sign_c2s::UpdateSignC2s; +pub mod update_structure_block_c2s; +pub use update_structure_block_c2s::UpdateStructureBlockC2s; +pub mod vehicle_move_c2s; +pub use vehicle_move_c2s::VehicleMoveC2s; +pub mod vehicle_move_s2c; +pub use vehicle_move_s2c::VehicleMoveS2c; +pub mod world_border_center_changed_s2c; +pub use world_border_center_changed_s2c::WorldBorderCenterChangedS2c; +pub mod world_border_initialize_s2c; +pub use world_border_initialize_s2c::WorldBorderInitializeS2c; +pub mod world_border_interpolate_size_s2c; +pub use world_border_interpolate_size_s2c::WorldBorderInterpolateSizeS2c; +pub mod world_border_size_changed_s2c; +pub use world_border_size_changed_s2c::WorldBorderSizeChangedS2c; +pub mod world_border_warning_blocks_changed_s2c; +pub use world_border_warning_blocks_changed_s2c::WorldBorderWarningBlocksChangedS2c; +pub mod world_border_warning_time_changed_s2c; +pub use world_border_warning_time_changed_s2c::WorldBorderWarningTimeChangedS2c; +pub mod world_event_s2c; +pub use world_event_s2c::WorldEventS2c; +pub mod world_time_update_s2c; +pub use world_time_update_s2c::WorldTimeUpdateS2c; diff --git a/crates/valence_packet/src/packets/play/advancement_update_s2c.rs b/crates/valence_packet/src/packets/play/advancement_update_s2c.rs index 24a7ca7fd..e280dac56 100644 --- a/crates/valence_packet/src/packets/play/advancement_update_s2c.rs +++ b/crates/valence_packet/src/packets/play/advancement_update_s2c.rs @@ -2,7 +2,7 @@ use super::*; #[derive(Clone, Debug, Encode, Decode, Packet)] #[packet(id = packet_id::ADVANCEMENT_UPDATE_S2C)] -pub struct GenericAdvancementUpdateS2c<'a, AM: 'a> { +pub struct AdvancementUpdateS2c<'a, AM: 'a> { pub reset: bool, pub advancement_mapping: Vec, pub identifiers: Vec>>, diff --git a/crates/valence_packet/src/packets/play/boss_bar_s2c.rs b/crates/valence_packet/src/packets/play/boss_bar_s2c.rs index e427eb46d..ab50553b5 100644 --- a/crates/valence_packet/src/packets/play/boss_bar_s2c.rs +++ b/crates/valence_packet/src/packets/play/boss_bar_s2c.rs @@ -1,5 +1,3 @@ -use valence_core::boss_bar::{BossBarColor, BossBarDivision, BossBarFlags}; - use super::*; #[derive(Clone, Debug, Encode, Decode, Packet)] @@ -24,3 +22,36 @@ pub enum BossBarAction<'a> { UpdateStyle(BossBarColor, BossBarDivision), UpdateFlags(BossBarFlags), } + +/// The color of a boss bar. +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum BossBarColor { + Pink, + Blue, + Red, + Green, + Yellow, + Purple, + White, +} + +/// The division of a boss bar. +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum BossBarDivision { + NoDivision, + SixNotches, + TenNotches, + TwelveNotches, + TwentyNotches, +} + +/// The flags of a boss bar (darken sky, dragon bar, create fog). +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct BossBarFlags { + pub darken_sky: bool, + pub dragon_bar: bool, + pub create_fog: bool, + #[bits(5)] + _pad: u8, +} diff --git a/crates/valence_packet/src/packets/play/bundle_splitter.rs b/crates/valence_packet/src/packets/play/bundle_splitter_s2c.rs similarity index 100% rename from crates/valence_packet/src/packets/play/bundle_splitter.rs rename to crates/valence_packet/src/packets/play/bundle_splitter_s2c.rs diff --git a/crates/valence_packet/src/packets/play/full.rs b/crates/valence_packet/src/packets/play/full_c2s.rs similarity index 100% rename from crates/valence_packet/src/packets/play/full.rs rename to crates/valence_packet/src/packets/play/full_c2s.rs diff --git a/crates/valence_packet/src/packets/play/look_and_on_ground.rs b/crates/valence_packet/src/packets/play/look_and_on_ground_c2s.rs similarity index 100% rename from crates/valence_packet/src/packets/play/look_and_on_ground.rs rename to crates/valence_packet/src/packets/play/look_and_on_ground_c2s.rs diff --git a/crates/valence_packet/src/packets/play/mod.rs b/crates/valence_packet/src/packets/play/mod.rs deleted file mode 100644 index b48e488f9..000000000 --- a/crates/valence_packet/src/packets/play/mod.rs +++ /dev/null @@ -1,179 +0,0 @@ -use bitfield_struct::bitfield; -use byteorder::WriteBytesExt; -use glam::{DVec3, IVec3, Vec3}; -use valence_core::block_pos::BlockPos; -use valence_core::chunk_pos::ChunkPos; -use valence_core::difficulty::Difficulty; -use valence_core::direction::Direction; -use valence_core::game_mode::GameMode; -use valence_core::hand::Hand; -use valence_core::item::ItemStack; -use valence_core::protocol::byte_angle::ByteAngle; -use valence_core::protocol::global_pos::GlobalPos; -use valence_core::protocol::var_long::VarLong; -use valence_nbt::Compound; - -use super::*; - -pub mod advancement_tab_c2s; -pub mod advancement_update_s2c; -pub mod block_breaking_progress_s2c; -pub mod block_entity_update_s2c; -pub mod block_event_s2c; -pub mod block_update_s2c; -pub mod boat_paddle_state_c2s; -pub mod book_update_c2s; -pub mod boss_bar_s2c; -pub mod bundle_splitter; -pub mod button_click_c2s; -pub mod chat_message_c2s; -pub mod chat_message_s2c; -pub mod chat_suggestions_s2c; -pub mod chunk_biome_data_s2c; -pub mod chunk_data_s2c; -pub mod chunk_delta_update_s2c; -pub mod chunk_load_distance_s2c; -pub mod chunk_render_distance_center_s2c; -pub mod clear_title_s2c; -pub mod click_slot_c2s; -pub mod client_command_c2s; -pub mod client_settings_c2s; -pub mod client_status_c2s; -pub mod close_handled_screen_c2s; -pub mod close_screen_s2c; -pub mod command_execution_c2s; -pub mod command_suggestions_s2c; -pub mod command_tree_s2c; -pub mod cooldown_update_s2c; -pub mod craft_failed_response_s2c; -pub mod craft_request_c2s; -pub mod creative_inventory_action_c2s; -pub mod custom_payload_c2s; -pub mod custom_payload_s2c; -pub mod damage_tilt_s2c; -pub mod death_message_s2c; -pub mod difficulty_s2c; -pub mod disconnect_s2c; -pub mod end_combat_s2c; -pub mod enter_combat_s2c; -pub mod entities_destroy_s2c; -pub mod entity_animation_s2c; -pub mod entity_attach_s2c; -pub mod entity_attributes_s2c; -pub mod entity_damage_s2c; -pub mod entity_equipment_update_s2c; -pub mod entity_passengers_set_s2c; -pub mod entity_position_s2c; -pub mod entity_set_head_yaw_s2c; -pub mod entity_spawn_s2c; -pub mod entity_status_effect_s2c; -pub mod entity_status_s2c; -pub mod entity_tracker_update_s2c; -pub mod entity_velocity_update_s2c; -pub mod experience_bar_update_s2c; -pub mod experience_orb_spawn_s2c; -pub mod explosion_s2c; -pub mod features_s2c; -pub mod full; -pub mod game_join_s2c; -pub mod game_message_s2c; -pub mod game_state_change_s2c; -pub mod hand_swing_c2s; -pub mod health_update_s2c; -pub mod inventory_s2c; -pub mod item_pickup_animation_s2c; -pub mod jigsaw_generating_c2s; -pub mod keep_alive_c2s; -pub mod keep_alive_s2c; -pub mod light_update_s2c; -pub mod look_and_on_ground; -pub mod look_at_s2c; -pub mod map_update_s2c; -pub mod message_acknowledgment_c2s; -pub mod move_relative; -pub mod nbt_query_response_s2c; -pub mod on_ground_only; -pub mod open_horse_screen_s2c; -pub mod open_screen_s2c; -pub mod open_written_book_s2c; -pub mod overlay_message_s2c; -pub mod particle_s2c; -pub mod pick_from_inventory_c2s; -pub mod play_ping_s2c; -pub mod play_pong_c2s; -pub mod play_sound_from_entity_s2c; -pub mod play_sound_s2c; -pub mod player_abilities_s2c; -pub mod player_action_c2s; -pub mod player_action_response_s2c; -pub mod player_input_c2s; -pub mod player_interact_block_c2s; -pub mod player_interact_entity_c2s; -pub mod player_interact_item_c2s; -pub mod player_list_header_s2c; -pub mod player_list_s2c; -pub mod player_position_look_s2c; -pub mod player_remove_s2c; -pub mod player_respawn_s2c; -pub mod player_session_c2s; -pub mod player_spawn_position_s2c; -pub mod player_spawn_s2c; -pub mod position_and_on_ground; -pub mod profileless_chat_message_s2c; -pub mod query_block_nbt_c2s; -pub mod query_entity_nbt_c2s; -pub mod recipe_book_data_c2s; -pub mod recipe_category_options_c2s; -pub mod remove_entity_status_effect_s2c; -pub mod remove_message_s2c; -pub mod rename_item_c2s; -pub mod request_command_completions_c2s; -pub mod resource_pack_send_s2c; -pub mod resource_pack_status_c2s; -pub mod rotate; -pub mod rotate_and_move_relative; -pub mod scoreboard_display_s2c; -pub mod scoreboard_objective_update_s2c; -pub mod scoreboard_player_update_s2c; -pub mod screen_handler_property_update_s2c; -pub mod screen_handler_slot_update_s2c; -pub mod select_advancement_tab_s2c; -pub mod select_merchant_trade_c2s; -pub mod server_metadata_s2c; -pub mod set_camera_entity_s2c; -pub mod set_trade_offers_s2c; -pub mod sign_editor_open_s2c; -pub mod simulation_distance_s2c; -pub mod spectator_teleport_c2s; -pub mod statistics_s2c; -pub mod stop_sound_s2c; -pub mod subtitle_s2c; -pub mod synchronize_recipes_s2c; -pub mod synchronize_tags_s2c; -pub mod team_s2c; -pub mod teleport_confirm_c2s; -pub mod title_fade_s2c; -pub mod title_s2c; -pub mod unload_chunk_s2c; -pub mod unlock_recipes_s2c; -pub mod update_beacon_c2s; -pub mod update_command_block_c2s; -pub mod update_command_block_minecart_c2s; -pub mod update_difficulty_c2s; -pub mod update_difficulty_lock_c2s; -pub mod update_jigsaw_c2s; -pub mod update_player_abilities_c2s; -pub mod update_selected_slot_c2s; -pub mod update_selected_slot_s2c; -pub mod update_sign_c2s; -pub mod update_structure_block_c2s; -pub mod vehicle_move_c2s; -pub mod vehicle_move_s2c; -pub mod world_border_center_changed_s2c; -pub mod world_border_initialize_s2c; -pub mod world_border_interpolate_size_s2c; -pub mod world_border_size_changed_s2c; -pub mod world_border_warning_blocks_changed_s2c; -pub mod world_border_warning_time_changed_s2c; -pub mod world_event_s2c; -pub mod world_time_update_s2c; diff --git a/crates/valence_packet/src/packets/play/move_relative.rs b/crates/valence_packet/src/packets/play/move_relative_s2c.rs similarity index 100% rename from crates/valence_packet/src/packets/play/move_relative.rs rename to crates/valence_packet/src/packets/play/move_relative_s2c.rs diff --git a/crates/valence_packet/src/packets/play/on_ground_only.rs b/crates/valence_packet/src/packets/play/on_ground_only_c2s.rs similarity index 100% rename from crates/valence_packet/src/packets/play/on_ground_only.rs rename to crates/valence_packet/src/packets/play/on_ground_only_c2s.rs diff --git a/crates/valence_packet/src/packets/play/position_and_on_ground.rs b/crates/valence_packet/src/packets/play/position_and_on_ground_c2s.rs similarity index 100% rename from crates/valence_packet/src/packets/play/position_and_on_ground.rs rename to crates/valence_packet/src/packets/play/position_and_on_ground_c2s.rs diff --git a/crates/valence_packet/src/packets/play/rotate_and_move_relative.rs b/crates/valence_packet/src/packets/play/rotate_and_move_relative_s2c.rs similarity index 100% rename from crates/valence_packet/src/packets/play/rotate_and_move_relative.rs rename to crates/valence_packet/src/packets/play/rotate_and_move_relative_s2c.rs diff --git a/crates/valence_packet/src/packets/play/rotate.rs b/crates/valence_packet/src/packets/play/rotate_s2c.rs similarity index 100% rename from crates/valence_packet/src/packets/play/rotate.rs rename to crates/valence_packet/src/packets/play/rotate_s2c.rs diff --git a/crates/valence_packet/src/packets/status.rs b/crates/valence_packet/src/packets/status.rs new file mode 100644 index 000000000..a6473cb8b --- /dev/null +++ b/crates/valence_packet/src/packets/status.rs @@ -0,0 +1,10 @@ +use super::*; + +pub mod query_ping_c2s; +pub use query_ping_c2s::QueryPingC2s; +pub mod query_pong_s2c; +pub use query_pong_s2c::QueryPongS2c; +pub mod query_request_c2s; +pub use query_request_c2s::QueryRequestC2s; +pub mod query_response_s2c; +pub use query_response_s2c::QueryResponseS2c; diff --git a/crates/valence_packet/src/packets/status/mod.rs b/crates/valence_packet/src/packets/status/mod.rs deleted file mode 100644 index faffd1d23..000000000 --- a/crates/valence_packet/src/packets/status/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -use valence_core::protocol::PacketState; - -use super::*; - -pub mod query_ping_c2s; -pub mod query_pong_s2c; -pub mod query_request_c2s; -pub mod query_response_s2c; diff --git a/crates/valence_packet/src/player_list.rs b/crates/valence_packet/src/player_list.rs deleted file mode 100644 index 29a8833cb..000000000 --- a/crates/valence_packet/src/player_list.rs +++ /dev/null @@ -1,141 +0,0 @@ -use super::*; - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_LIST_HEADER_S2C)] -pub struct PlayerListHeaderS2c<'a> { - pub header: Cow<'a, Text>, - pub footer: Cow<'a, Text>, -} - -#[derive(Clone, Debug, Packet)] -#[packet(id = packet_id::PLAYER_LIST_S2C)] -pub struct PlayerListS2c<'a> { - pub actions: PlayerListActions, - pub entries: Cow<'a, [PlayerListEntryPkt<'a>]>, -} - -#[bitfield(u8)] -pub struct PlayerListActions { - pub add_player: bool, - pub initialize_chat: bool, - pub update_game_mode: bool, - pub update_listed: bool, - pub update_latency: bool, - pub update_display_name: bool, - #[bits(2)] - _pad: u8, -} - -#[derive(Clone, Default, Debug)] -pub struct PlayerListEntryPkt<'a> { - pub player_uuid: Uuid, - pub username: &'a str, - pub properties: Cow<'a, [Property]>, - pub chat_data: Option>, - pub listed: bool, - pub ping: i32, - pub game_mode: GameMode, - pub display_name: Option>, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct ChatData<'a> { - pub session_id: Uuid, - /// Unix timestamp in milliseconds. - pub key_expiry_time: i64, - pub public_key: &'a [u8], - pub public_key_signature: &'a [u8], -} - -impl<'a> Encode for PlayerListS2c<'a> { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - self.actions.0.encode(&mut w)?; - - // Write number of entries. - VarInt(self.entries.len() as i32).encode(&mut w)?; - - for entry in self.entries.as_ref() { - entry.player_uuid.encode(&mut w)?; - - if self.actions.add_player() { - entry.username.encode(&mut w)?; - entry.properties.encode(&mut w)?; - } - - if self.actions.initialize_chat() { - entry.chat_data.encode(&mut w)?; - } - - if self.actions.update_game_mode() { - entry.game_mode.encode(&mut w)?; - } - - if self.actions.update_listed() { - entry.listed.encode(&mut w)?; - } - - if self.actions.update_latency() { - VarInt(entry.ping).encode(&mut w)?; - } - - if self.actions.update_display_name() { - entry.display_name.encode(&mut w)?; - } - } - - Ok(()) - } -} - -impl<'a> Decode<'a> for PlayerListS2c<'a> { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - let actions = PlayerListActions(u8::decode(r)?); - - let mut entries = vec![]; - - for _ in 0..VarInt::decode(r)?.0 { - let mut entry = PlayerListEntryPkt { - player_uuid: Uuid::decode(r)?, - ..Default::default() - }; - - if actions.add_player() { - entry.username = Decode::decode(r)?; - entry.properties = Decode::decode(r)?; - } - - if actions.initialize_chat() { - entry.chat_data = Decode::decode(r)?; - } - - if actions.update_game_mode() { - entry.game_mode = Decode::decode(r)?; - } - - if actions.update_listed() { - entry.listed = Decode::decode(r)?; - } - - if actions.update_latency() { - entry.ping = VarInt::decode(r)?.0; - } - - if actions.update_display_name() { - entry.display_name = Decode::decode(r)?; - } - - entries.push(entry); - } - - Ok(Self { - actions, - entries: entries.into(), - }) - } -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_REMOVE_S2C)] -pub struct PlayerRemoveS2c<'a> { - pub uuids: Cow<'a, [Uuid]>, -} diff --git a/crates/valence_packet/src/protocol.rs b/crates/valence_packet/src/protocol.rs new file mode 100644 index 000000000..93111edc3 --- /dev/null +++ b/crates/valence_packet/src/protocol.rs @@ -0,0 +1,221 @@ +pub mod decode; +pub mod encode; + +use std::io::Write; + +use anyhow::Context; +pub use valence_packet_macros::Packet; + +use valence_core::protocol::*; +use valence_core::protocol::var_int::VarInt; + +/// Types considered to be Minecraft packets. +/// +/// In serialized form, a packet begins with a [`VarInt`] packet ID followed by +/// the body of the packet. If present, the implementations of [`Encode`] and +/// [`Decode`] on `Self` are expected to only encode/decode the _body_ of this +/// packet without the leading ID. +pub trait Packet: std::fmt::Debug { + /// The leading VarInt ID of this packet. + const ID: i32; + /// The name of this packet for debugging purposes. + const NAME: &'static str; + /// The side this packet is intended for + const SIDE: PacketSide; + /// The state which this packet is used + const STATE: PacketState; + + /// Encodes this packet's VarInt ID first, followed by the packet's body. + fn encode_with_id(&self, mut w: impl Write) -> anyhow::Result<()> + where + Self: Encode, + { + VarInt(Self::ID) + .encode(&mut w) + .context("failed to encode packet ID")?; + self.encode(w) + } +} + +/// The side a packet is intended for +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum PacketSide { + /// Server -> Client + Clientbound, + /// Client -> Server + Serverbound, +} + +/// The state which a packet is used +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum PacketState { + Handshaking, + Status, + Login, + Play, +} + +/// Contains constants for every vanilla packet ID. +pub mod packet_id { + include!(concat!(env!("OUT_DIR"), "/packet_id.rs")); +} + +#[allow(dead_code)] +#[cfg(test)] +mod tests { + use std::borrow::Cow; + + use bytes::BytesMut; + + use super::*; + use crate::protocol::decode::PacketDecoder; + use crate::protocol::encode::PacketEncoder; + + #[derive(Encode, Decode, Packet, Debug)] + #[packet(id = 1, side = PacketSide::Clientbound)] + struct RegularStruct { + foo: i32, + bar: bool, + baz: f64, + } + + #[derive(Encode, Decode, Packet, Debug)] + #[packet(id = 2, side = PacketSide::Clientbound)] + struct UnitStruct; + + #[derive(Encode, Decode, Packet, Debug)] + #[packet(id = 3, side = PacketSide::Clientbound)] + struct EmptyStruct {} + + #[derive(Encode, Decode, Packet, Debug)] + #[packet(id = 4, side = PacketSide::Clientbound)] + struct TupleStruct(i32, bool, f64); + + #[derive(Encode, Decode, Packet, Debug)] + #[packet(id = 5, side = PacketSide::Clientbound)] + struct StructWithGenerics<'z, T = ()> { + foo: &'z str, + bar: T, + } + + #[derive(Encode, Decode, Packet, Debug)] + #[packet(id = 6, side = PacketSide::Clientbound)] + struct TupleStructWithGenerics<'z, T = ()>(&'z str, i32, T); + + #[allow(unconditional_recursion, clippy::extra_unused_type_parameters)] + fn assert_has_impls<'a, T>() + where + T: Encode + Decode<'a> + Packet, + { + assert_has_impls::(); + assert_has_impls::(); + assert_has_impls::(); + assert_has_impls::(); + assert_has_impls::(); + assert_has_impls::(); + } + + #[test] + fn packet_name() { + assert_eq!(RegularStruct::NAME, "RegularStruct"); + assert_eq!(UnitStruct::NAME, "UnitStruct"); + assert_eq!(StructWithGenerics::<()>::NAME, "StructWithGenerics"); + } + + use valence_core::block_pos::BlockPos; + use valence_core::hand::Hand; + use valence_core::ident::Ident; + use valence_core::item::{ItemKind, ItemStack}; + use valence_core::protocol::var_int::VarInt; + use valence_core::protocol::var_long::VarLong; + use valence_core::text::{IntoText, Text}; + + #[cfg(feature = "encryption")] + const CRYPT_KEY: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; + + #[derive(PartialEq, Debug, Encode, Decode, Packet)] + #[packet(id = 42, side = PacketSide::Clientbound)] + struct TestPacket<'a> { + a: bool, + b: u8, + c: i32, + d: f32, + e: f64, + f: BlockPos, + g: Hand, + h: Ident>, + i: Option, + j: Text, + k: VarInt, + l: VarLong, + m: &'a str, + n: &'a [u8; 10], + o: [u128; 3], + } + + impl<'a> TestPacket<'a> { + fn new(string: &'a str) -> Self { + Self { + a: true, + b: 12, + c: -999, + d: 5.001, + e: 1e10, + f: BlockPos::new(1, 2, 3), + g: Hand::Off, + h: Ident::new("minecraft:whatever").unwrap(), + i: Some(ItemStack::new(ItemKind::WoodenSword, 12, None)), + j: "my ".into_text() + "fancy".italic() + " text", + k: VarInt(123), + l: VarLong(456), + m: string, + n: &[7; 10], + o: [123456789; 3], + } + } + } + + fn check_test_packet(dec: &mut PacketDecoder, string: &str) { + let frame = dec.try_next_packet().unwrap().unwrap(); + + let pkt = frame.decode::().unwrap(); + + assert_eq!(&pkt, &TestPacket::new(string)); + } + + #[test] + fn packets_round_trip() { + let mut buf = BytesMut::new(); + + let mut enc = PacketEncoder::new(); + + enc.append_packet(&TestPacket::new("first")).unwrap(); + #[cfg(feature = "compression")] + enc.set_compression(Some(0)); + enc.append_packet(&TestPacket::new("second")).unwrap(); + buf.unsplit(enc.take()); + #[cfg(feature = "encryption")] + enc.enable_encryption(&CRYPT_KEY); + enc.append_packet(&TestPacket::new("third")).unwrap(); + enc.prepend_packet(&TestPacket::new("fourth")).unwrap(); + + buf.unsplit(enc.take()); + + let mut dec = PacketDecoder::new(); + + dec.queue_bytes(buf); + + check_test_packet(&mut dec, "first"); + + #[cfg(feature = "compression")] + dec.set_compression(Some(0)); + + check_test_packet(&mut dec, "second"); + + #[cfg(feature = "encryption")] + dec.enable_encryption(&CRYPT_KEY); + + check_test_packet(&mut dec, "fourth"); + check_test_packet(&mut dec, "third"); + } +} diff --git a/crates/valence_core/src/protocol/decode.rs b/crates/valence_packet/src/protocol/decode.rs similarity index 99% rename from crates/valence_core/src/protocol/decode.rs rename to crates/valence_packet/src/protocol/decode.rs index 6a383d265..2418bf078 100644 --- a/crates/valence_core/src/protocol/decode.rs +++ b/crates/valence_packet/src/protocol/decode.rs @@ -5,10 +5,11 @@ use aes::cipher::{BlockDecryptMut, BlockSizeUser, KeyIvInit}; use anyhow::{bail, ensure, Context}; use bytes::{Buf, BytesMut}; -use super::Decode; use crate::protocol::var_int::{VarInt, VarIntDecodeError}; use crate::protocol::{Packet, MAX_PACKET_SIZE}; +use valence_core::protocol::Decode; + /// The AES block cipher with a 128 bit key, using the CFB-8 mode of /// operation. #[cfg(feature = "encryption")] diff --git a/crates/valence_core/src/protocol/encode.rs b/crates/valence_packet/src/protocol/encode.rs similarity index 100% rename from crates/valence_core/src/protocol/encode.rs rename to crates/valence_packet/src/protocol/encode.rs diff --git a/crates/valence_packet/src/scoreboard.rs b/crates/valence_packet/src/scoreboard.rs deleted file mode 100644 index 4cfcf334b..000000000 --- a/crates/valence_packet/src/scoreboard.rs +++ /dev/null @@ -1,342 +0,0 @@ -use super::*; - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::TEAM_S2C)] -pub struct TeamS2c<'a> { - pub team_name: &'a str, - pub mode: Mode<'a>, -} - -#[derive(Clone, PartialEq, Debug)] -pub enum Mode<'a> { - CreateTeam { - team_display_name: Cow<'a, Text>, - friendly_flags: TeamFlags, - name_tag_visibility: NameTagVisibility, - collision_rule: CollisionRule, - team_color: TeamColor, - team_prefix: Cow<'a, Text>, - team_suffix: Cow<'a, Text>, - entities: Vec<&'a str>, - }, - RemoveTeam, - UpdateTeamInfo { - team_display_name: Cow<'a, Text>, - friendly_flags: TeamFlags, - name_tag_visibility: NameTagVisibility, - collision_rule: CollisionRule, - team_color: TeamColor, - team_prefix: Cow<'a, Text>, - team_suffix: Cow<'a, Text>, - }, - AddEntities { - entities: Vec<&'a str>, - }, - RemoveEntities { - entities: Vec<&'a str>, - }, -} - -#[bitfield(u8)] -#[derive(PartialEq, Eq, Encode, Decode)] -pub struct TeamFlags { - pub friendly_fire: bool, - pub see_invisible_teammates: bool, - #[bits(6)] - _pad: u8, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub enum NameTagVisibility { - Always, - Never, - HideForOtherTeams, - HideForOwnTeam, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub enum CollisionRule { - Always, - Never, - PushOtherTeams, - PushOwnTeam, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum TeamColor { - Black, - DarkBlue, - DarkGreen, - DarkCyan, - DarkRed, - Purple, - Gold, - Gray, - DarkGray, - Blue, - BrightGreen, - Cyan, - Red, - Pink, - Yellow, - White, - Obfuscated, - Bold, - Strikethrough, - Underlined, - Italic, - Reset, -} - -impl Encode for Mode<'_> { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - match self { - Mode::CreateTeam { - team_display_name, - friendly_flags, - name_tag_visibility, - collision_rule, - team_color, - team_prefix, - team_suffix, - entities, - } => { - 0i8.encode(&mut w)?; - team_display_name.encode(&mut w)?; - friendly_flags.encode(&mut w)?; - match name_tag_visibility { - NameTagVisibility::Always => "always", - NameTagVisibility::Never => "never", - NameTagVisibility::HideForOtherTeams => "hideForOtherTeams", - NameTagVisibility::HideForOwnTeam => "hideForOwnTeam", - } - .encode(&mut w)?; - match collision_rule { - CollisionRule::Always => "always", - CollisionRule::Never => "never", - CollisionRule::PushOtherTeams => "pushOtherTeams", - CollisionRule::PushOwnTeam => "pushOwnTeam", - } - .encode(&mut w)?; - team_color.encode(&mut w)?; - team_prefix.encode(&mut w)?; - team_suffix.encode(&mut w)?; - entities.encode(&mut w)?; - } - Mode::RemoveTeam => 1i8.encode(&mut w)?, - Mode::UpdateTeamInfo { - team_display_name, - friendly_flags, - name_tag_visibility, - collision_rule, - team_color, - team_prefix, - team_suffix, - } => { - 2i8.encode(&mut w)?; - team_display_name.encode(&mut w)?; - friendly_flags.encode(&mut w)?; - match name_tag_visibility { - NameTagVisibility::Always => "always", - NameTagVisibility::Never => "never", - NameTagVisibility::HideForOtherTeams => "hideForOtherTeams", - NameTagVisibility::HideForOwnTeam => "hideForOwnTeam", - } - .encode(&mut w)?; - match collision_rule { - CollisionRule::Always => "always", - CollisionRule::Never => "never", - CollisionRule::PushOtherTeams => "pushOtherTeams", - CollisionRule::PushOwnTeam => "pushOwnTeam", - } - .encode(&mut w)?; - team_color.encode(&mut w)?; - team_prefix.encode(&mut w)?; - team_suffix.encode(&mut w)?; - } - Mode::AddEntities { entities } => { - 3i8.encode(&mut w)?; - entities.encode(&mut w)?; - } - Mode::RemoveEntities { entities } => { - 4i8.encode(&mut w)?; - entities.encode(&mut w)?; - } - } - Ok(()) - } -} - -impl<'a> Decode<'a> for Mode<'a> { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - Ok(match i8::decode(r)? { - 0 => Self::CreateTeam { - team_display_name: Decode::decode(r)?, - friendly_flags: Decode::decode(r)?, - name_tag_visibility: match <&str>::decode(r)? { - "always" => NameTagVisibility::Always, - "never" => NameTagVisibility::Never, - "hideForOtherTeams" => NameTagVisibility::HideForOtherTeams, - "hideForOwnTeam" => NameTagVisibility::HideForOwnTeam, - other => bail!("unknown name tag visibility type \"{other}\""), - }, - collision_rule: match <&str>::decode(r)? { - "always" => CollisionRule::Always, - "never" => CollisionRule::Never, - "pushOtherTeams" => CollisionRule::PushOtherTeams, - "pushOwnTeam" => CollisionRule::PushOwnTeam, - other => bail!("unknown collision rule type \"{other}\""), - }, - team_color: Decode::decode(r)?, - team_prefix: Decode::decode(r)?, - team_suffix: Decode::decode(r)?, - entities: Decode::decode(r)?, - }, - 1 => Self::RemoveTeam, - 2 => Self::UpdateTeamInfo { - team_display_name: Decode::decode(r)?, - friendly_flags: Decode::decode(r)?, - name_tag_visibility: match <&str>::decode(r)? { - "always" => NameTagVisibility::Always, - "never" => NameTagVisibility::Never, - "hideForOtherTeams" => NameTagVisibility::HideForOtherTeams, - "hideForOwnTeam" => NameTagVisibility::HideForOwnTeam, - other => bail!("unknown name tag visibility type \"{other}\""), - }, - collision_rule: match <&str>::decode(r)? { - "always" => CollisionRule::Always, - "never" => CollisionRule::Never, - "pushOtherTeams" => CollisionRule::PushOtherTeams, - "pushOwnTeam" => CollisionRule::PushOwnTeam, - other => bail!("unknown collision rule type \"{other}\""), - }, - team_color: Decode::decode(r)?, - team_prefix: Decode::decode(r)?, - team_suffix: Decode::decode(r)?, - }, - 3 => Self::AddEntities { - entities: Decode::decode(r)?, - }, - 4 => Self::RemoveEntities { - entities: Decode::decode(r)?, - }, - n => bail!("unknown update teams action of {n}"), - }) - } -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::SCOREBOARD_DISPLAY_S2C)] -pub struct ScoreboardDisplayS2c<'a> { - pub position: ScoreboardPosition, - pub score_name: &'a str, -} - -#[derive(Copy, Clone, PartialEq, Debug)] -pub enum ScoreboardPosition { - List, - Sidebar, - BelowName, - SidebarTeam(TeamColor), -} - -impl Encode for ScoreboardPosition { - fn encode(&self, w: impl std::io::Write) -> anyhow::Result<()> { - match self { - ScoreboardPosition::List => 0u8.encode(w), - ScoreboardPosition::Sidebar => 1u8.encode(w), - ScoreboardPosition::BelowName => 2u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Black) => 3u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::DarkBlue) => 4u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::DarkGreen) => 5u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::DarkCyan) => 6u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::DarkRed) => 7u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Purple) => 8u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Gold) => 9u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Gray) => 10u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::DarkGray) => 11u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Blue) => 12u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::BrightGreen) => 13u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Cyan) => 14u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Red) => 15u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Pink) => 16u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::Yellow) => 17u8.encode(w), - ScoreboardPosition::SidebarTeam(TeamColor::White) => 18u8.encode(w), - ScoreboardPosition::SidebarTeam(_) => { - Err(anyhow::anyhow!("Invalid scoreboard display position")) - } - } - } -} - -impl<'a> Decode<'a> for ScoreboardPosition { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - let value = u8::decode(r)?; - match value { - 0 => Ok(ScoreboardPosition::List), - 1 => Ok(ScoreboardPosition::Sidebar), - 2 => Ok(ScoreboardPosition::BelowName), - 3 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Black)), - 4 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkBlue)), - 5 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkGreen)), - 6 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkCyan)), - 7 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkRed)), - 8 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Purple)), - 9 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Gold)), - 10 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Gray)), - 11 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::DarkGray)), - 12 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Blue)), - 13 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::BrightGreen)), - 14 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Cyan)), - 15 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Red)), - 16 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Pink)), - 17 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::Yellow)), - 18 => Ok(ScoreboardPosition::SidebarTeam(TeamColor::White)), - _ => Err(anyhow::anyhow!("Invalid scoreboard display position")), - } - } -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::SCOREBOARD_OBJECTIVE_UPDATE_S2C)] -pub struct ScoreboardObjectiveUpdateS2c<'a> { - pub objective_name: &'a str, - pub mode: ObjectiveMode, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub enum ObjectiveMode { - Create { - objective_display_name: Text, - render_type: ObjectiveRenderType, - }, - Remove, - Update { - objective_display_name: Text, - render_type: ObjectiveRenderType, - }, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum ObjectiveRenderType { - Integer, - Hearts, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::SCOREBOARD_PLAYER_UPDATE_S2C)] -pub struct ScoreboardPlayerUpdateS2c<'a> { - pub entity_name: &'a str, - pub action: ScoreboardPlayerUpdateAction<'a>, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub enum ScoreboardPlayerUpdateAction<'a> { - Update { - objective_name: &'a str, - objective_score: VarInt, - }, - Remove { - objective_name: &'a str, - }, -} diff --git a/crates/valence_packet/src/sound.rs b/crates/valence_packet/src/sound.rs deleted file mode 100644 index c5ea76147..000000000 --- a/crates/valence_packet/src/sound.rs +++ /dev/null @@ -1,90 +0,0 @@ -use valence_core::sound::{SoundCategory, SoundId}; - -use super::*; - -#[cfg(test)] -mod tests { - use valence_core::ident; - use valence_core::sound::Sound; - - use super::*; - - #[test] - fn sound_to_soundid() { - assert_eq!( - Sound::BlockBellUse.to_id(), - SoundId::Direct { - id: ident!("block.bell.use").into(), - range: None - }, - ); - } -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAY_SOUND_FROM_ENTITY_S2C)] -pub struct PlaySoundFromEntityS2c { - pub id: VarInt, - pub category: SoundCategory, - pub entity_id: VarInt, - pub volume: f32, - pub pitch: f32, - pub seed: i64, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAY_SOUND_S2C)] -pub struct PlaySoundS2c<'a> { - pub id: SoundId<'a>, - pub category: SoundCategory, - pub position: IVec3, - pub volume: f32, - pub pitch: f32, - pub seed: i64, -} - -#[derive(Clone, PartialEq, Debug, Packet)] -#[packet(id = packet_id::STOP_SOUND_S2C)] -pub struct StopSoundS2c<'a> { - pub source: Option, - pub sound: Option>>, -} - -impl Encode for StopSoundS2c<'_> { - fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { - match (self.source, self.sound.as_ref()) { - (Some(source), Some(sound)) => { - 3i8.encode(&mut w)?; - source.encode(&mut w)?; - sound.encode(&mut w)?; - } - (None, Some(sound)) => { - 2i8.encode(&mut w)?; - sound.encode(&mut w)?; - } - (Some(source), None) => { - 1i8.encode(&mut w)?; - source.encode(&mut w)?; - } - _ => 0i8.encode(&mut w)?, - } - - Ok(()) - } -} - -impl<'a> Decode<'a> for StopSoundS2c<'a> { - fn decode(r: &mut &'a [u8]) -> anyhow::Result { - let (source, sound) = match i8::decode(r)? { - 3 => ( - Some(SoundCategory::decode(r)?), - Some(>>::decode(r)?), - ), - 2 => (None, Some(>>::decode(r)?)), - 1 => (Some(SoundCategory::decode(r)?), None), - _ => (None, None), - }; - - Ok(Self { source, sound }) - } -} diff --git a/crates/valence_packet/src/world_border.rs b/crates/valence_packet/src/world_border.rs deleted file mode 100644 index e3974682d..000000000 --- a/crates/valence_packet/src/world_border.rs +++ /dev/null @@ -1,47 +0,0 @@ -use super::*; - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::WORLD_BORDER_CENTER_CHANGED_S2C)] -pub struct WorldBorderCenterChangedS2c { - pub x_pos: f64, - pub z_pos: f64, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::WORLD_BORDER_INITIALIZE_S2C)] -pub struct WorldBorderInitializeS2c { - pub x: f64, - pub z: f64, - pub old_diameter: f64, - pub new_diameter: f64, - pub speed: VarLong, - pub portal_teleport_boundary: VarInt, - pub warning_blocks: VarInt, - pub warning_time: VarInt, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::WORLD_BORDER_INTERPOLATE_SIZE_S2C)] -pub struct WorldBorderInterpolateSizeS2c { - pub old_diameter: f64, - pub new_diameter: f64, - pub speed: VarLong, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::WORLD_BORDER_SIZE_CHANGED_S2C)] -pub struct WorldBorderSizeChangedS2c { - pub diameter: f64, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::WORLD_BORDER_WARNING_BLOCKS_CHANGED_S2C)] -pub struct WorldBorderWarningBlocksChangedS2c { - pub warning_blocks: VarInt, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::WORLD_BORDER_WARNING_TIME_CHANGED_S2C)] -pub struct WorldBorderWarningTimeChangedS2c { - pub warning_time: VarInt, -} diff --git a/crates/valence_packet_macros/Cargo.toml b/crates/valence_packet_macros/Cargo.toml new file mode 100644 index 000000000..51394e258 --- /dev/null +++ b/crates/valence_packet_macros/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "valence_packet_macros" +version.workspace = true +edition.workspace = true + +[lib] +proc-macro = true + +[dependencies] +proc-macro2.workspace = true +quote.workspace = true +syn = { workspace = true, features = ["full"] } diff --git a/crates/valence_packet_macros/README.md b/crates/valence_packet_macros/README.md new file mode 100644 index 000000000..5c1cd2b74 --- /dev/null +++ b/crates/valence_packet_macros/README.md @@ -0,0 +1,3 @@ +# valence_packet_macros + +Procedural macros for `valence_packet` diff --git a/crates/valence_packet_macros/src/lib.rs b/crates/valence_packet_macros/src/lib.rs new file mode 100644 index 000000000..efdeadc6f --- /dev/null +++ b/crates/valence_packet_macros/src/lib.rs @@ -0,0 +1,42 @@ +#![doc = include_str!("../README.md")] +#![deny( + rustdoc::broken_intra_doc_links, + rustdoc::private_intra_doc_links, + rustdoc::missing_crate_level_docs, + rustdoc::invalid_codeblock_attributes, + rustdoc::invalid_rust_codeblocks, + rustdoc::bare_urls, + rustdoc::invalid_html_tags +)] +#![warn( + trivial_casts, + trivial_numeric_casts, + unused_lifetimes, + unused_import_braces, + unreachable_pub, + clippy::dbg_macro +)] + +use proc_macro::TokenStream as StdTokenStream; +use proc_macro2::TokenStream; +use syn::{ + parse_quote, GenericParam, Generics, +}; + +mod packet; + +#[proc_macro_derive(Packet, attributes(packet))] +pub fn derive_packet(item: StdTokenStream) -> StdTokenStream { + match packet::derive_packet(item.into()) { + Ok(tokens) => tokens.into(), + Err(e) => e.into_compile_error().into(), + } +} + +fn add_trait_bounds(generics: &mut Generics, trait_: TokenStream) { + for param in &mut generics.params { + if let GenericParam::Type(type_param) = param { + type_param.bounds.push(parse_quote!(#trait_)) + } + } +} diff --git a/crates/valence_core_macros/src/packet.rs b/crates/valence_packet_macros/src/packet.rs similarity index 86% rename from crates/valence_core_macros/src/packet.rs rename to crates/valence_packet_macros/src/packet.rs index f1eda6a18..cb97c77ba 100644 --- a/crates/valence_core_macros/src/packet.rs +++ b/crates/valence_packet_macros/src/packet.rs @@ -34,9 +34,9 @@ pub(super) fn derive_packet(item: TokenStream) -> Result { let side = if let Some(side_attr) = packet_attr.side { side_attr } else if name_str.to_lowercase().contains("s2c") { - parse_quote!(::valence_core::protocol::PacketSide::Clientbound) + parse_quote!(::valence_packet::protocol::PacketSide::Clientbound) } else if name_str.to_lowercase().contains("c2s") { - parse_quote!(::valence_core::protocol::PacketSide::Serverbound) + parse_quote!(::valence_packet::protocol::PacketSide::Serverbound) } else { return Err(Error::new( input.span(), @@ -46,16 +46,16 @@ pub(super) fn derive_packet(item: TokenStream) -> Result { let state = packet_attr .state - .unwrap_or_else(|| parse_quote!(::valence_core::protocol::PacketState::Play)); + .unwrap_or_else(|| parse_quote!(::valence_packet::protocol::PacketState::Play)); Ok(quote! { - impl #impl_generics ::valence_core::__private::Packet for #name #ty_generics + impl #impl_generics ::valence_packet::__private::Packet for #name #ty_generics #where_clause { const ID: i32 = #packet_id; const NAME: &'static str = #name_str; - const SIDE: ::valence_core::protocol::PacketSide = #side; - const STATE: ::valence_core::protocol::PacketState = #state; + const SIDE: ::valence_packet::protocol::PacketSide = #side; + const STATE: ::valence_packet::protocol::PacketState = #state; } }) } diff --git a/crates/valence_registry/Cargo.toml b/crates/valence_registry/Cargo.toml index 2dba59736..0de4f26c8 100644 --- a/crates/valence_registry/Cargo.toml +++ b/crates/valence_registry/Cargo.toml @@ -11,4 +11,5 @@ serde_json.workspace = true serde.workspace = true tracing.workspace = true valence_core.workspace = true +valence_packet.workspace = true valence_nbt.workspace = true \ No newline at end of file diff --git a/crates/valence_registry/src/tags.rs b/crates/valence_registry/src/tags.rs index d9f8b0d7b..57d307ea5 100644 --- a/crates/valence_registry/src/tags.rs +++ b/crates/valence_registry/src/tags.rs @@ -4,9 +4,9 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use serde::Deserialize; use valence_core::ident::Ident; -use valence_core::protocol::encode::{PacketWriter, WritePacket}; +use valence_packet::protocol::encode::{PacketWriter, WritePacket}; use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; +use valence_core::protocol::{Decode, Encode}; use valence_core::Server; use crate::RegistrySet; @@ -17,12 +17,6 @@ pub(super) fn build(app: &mut App) { .add_systems(PostUpdate, cache_tags_packet.in_set(RegistrySet)); } -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::SYNCHRONIZE_TAGS_S2C)] -pub struct SynchronizeTagsS2c<'a> { - pub registries: Cow<'a, [Registry]>, -} - #[derive(Debug, Resource, Default)] pub struct TagsRegistry { pub registries: Vec, From 2821fdefad01fe96ebbd9fb951dbaec59417df42 Mon Sep 17 00:00:00 2001 From: Bafbi Date: Wed, 2 Aug 2023 01:14:58 +0200 Subject: [PATCH 7/9] remove some alone packet def + repair some import --- crates/valence_advancement/src/event.rs | 2 +- crates/valence_client/src/action.rs | 12 ++--- crates/valence_client/src/command.rs | 25 +-------- crates/valence_client/src/custom_payload.rs | 16 +----- crates/valence_client/src/event_loop.rs | 3 +- crates/valence_client/src/hand_swing.rs | 8 +-- crates/valence_client/src/interact_block.rs | 13 +---- crates/valence_client/src/interact_entity.rs | 21 +------- crates/valence_client/src/interact_item.rs | 10 +--- crates/valence_client/src/keepalive.rs | 14 +---- crates/valence_client/src/lib.rs | 22 ++++---- crates/valence_client/src/message.rs | 4 +- crates/valence_client/src/movement.rs | 40 +-------------- crates/valence_client/src/op_level.rs | 4 +- crates/valence_client/src/resource_pack.rs | 33 ++---------- crates/valence_client/src/settings.rs | 51 +------------------ crates/valence_client/src/status.rs | 9 +--- crates/valence_client/src/teleport.rs | 32 +----------- crates/valence_client/src/title.rs | 34 +------------ crates/valence_client/src/weather.rs | 2 - crates/valence_entity/build.rs | 4 +- crates/valence_instance/src/chunk/loaded.rs | 12 +++-- crates/valence_instance/src/instance.rs | 9 ++-- crates/valence_instance/src/lib.rs | 4 +- crates/valence_packet/Cargo.toml | 1 + .../src/packets/play/synchronize_tags_s2c.rs | 14 ++++- crates/valence_registry/src/tags.rs | 20 ++------ 27 files changed, 70 insertions(+), 349 deletions(-) diff --git a/crates/valence_advancement/src/event.rs b/crates/valence_advancement/src/event.rs index bb2a46dcb..8a4aa901c 100644 --- a/crates/valence_advancement/src/event.rs +++ b/crates/valence_advancement/src/event.rs @@ -1,7 +1,7 @@ use bevy_ecs::prelude::*; use valence_client::event_loop::PacketEvent; use valence_core::ident::Ident; -use valence_packet::advancement::AdvancementTabC2s; +use valence_packet::packets::play::AdvancementTabC2s; /// This event sends when the client changes or closes advancement's tab. #[derive(Event, Clone, PartialEq, Eq, Debug)] diff --git a/crates/valence_client/src/action.rs b/crates/valence_client/src/action.rs index c8bea94db..3c26ba6b5 100644 --- a/crates/valence_client/src/action.rs +++ b/crates/valence_client/src/action.rs @@ -1,8 +1,10 @@ use valence_core::block_pos::BlockPos; use valence_core::direction::Direction; use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; -use valence_packet::client::{PlayerAction, PlayerActionC2s}; +use valence_core::protocol::{Decode, Encode}; +use valence_packet::packets::play::player_action_c2s::PlayerAction; +use valence_packet::packets::play::{PlayerActionC2s, PlayerActionResponseS2c}; +use valence_packet::protocol::Packet; use super::*; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; @@ -99,9 +101,3 @@ fn acknowledge_player_actions( } } } - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_ACTION_RESPONSE_S2C)] -pub struct PlayerActionResponseS2c { - pub sequence: VarInt, -} diff --git a/crates/valence_client/src/command.rs b/crates/valence_client/src/command.rs index 756e13f83..78b7c2d11 100644 --- a/crates/valence_client/src/command.rs +++ b/crates/valence_client/src/command.rs @@ -1,9 +1,9 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; use valence_entity::entity::Flags; use valence_entity::{entity, Pose}; +use valence_packet::packets::play::client_command_c2s::ClientCommand; +use valence_packet::packets::play::ClientCommandC2s; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; @@ -141,24 +141,3 @@ fn handle_client_command( } } } - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CLIENT_COMMAND_C2S)] -pub struct ClientCommandC2s { - pub entity_id: VarInt, - pub action: ClientCommand, - pub jump_boost: VarInt, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum ClientCommand { - StartSneaking, - StopSneaking, - LeaveBed, - StartSprinting, - StopSprinting, - StartJumpWithHorse, - StopJumpWithHorse, - OpenHorseInventory, - StartFlyingWithElytra, -} diff --git a/crates/valence_client/src/custom_payload.rs b/crates/valence_client/src/custom_payload.rs index 15f52f561..8baa67730 100644 --- a/crates/valence_client/src/custom_payload.rs +++ b/crates/valence_client/src/custom_payload.rs @@ -1,5 +1,5 @@ use valence_core::protocol::raw::RawBytes; -use valence_core::protocol::{packet_id, Decode, Encode}; +use valence_packet::packets::play::{CustomPayloadC2s, CustomPayloadS2c}; use super::*; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; @@ -39,17 +39,3 @@ fn handle_custom_payload( } } } - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CUSTOM_PAYLOAD_C2S)] -pub struct CustomPayloadC2s<'a> { - pub channel: Ident>, - pub data: RawBytes<'a>, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CUSTOM_PAYLOAD_S2C)] -pub struct CustomPayloadS2c<'a> { - pub channel: Ident>, - pub data: RawBytes<'a>, -} diff --git a/crates/valence_client/src/event_loop.rs b/crates/valence_client/src/event_loop.rs index d245031e8..b2be540ee 100644 --- a/crates/valence_client/src/event_loop.rs +++ b/crates/valence_client/src/event_loop.rs @@ -7,7 +7,8 @@ use bevy_ecs::schedule::ScheduleLabel; use bevy_ecs::system::SystemState; use bytes::Bytes; use tracing::{debug, warn}; -use valence_core::protocol::{Decode, Packet}; +use valence_core::protocol::Decode; +use valence_packet::protocol::Packet; use crate::Client; diff --git a/crates/valence_client/src/hand_swing.rs b/crates/valence_client/src/hand_swing.rs index 8c6ef45ba..ebf70bef4 100644 --- a/crates/valence_client/src/hand_swing.rs +++ b/crates/valence_client/src/hand_swing.rs @@ -1,8 +1,8 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use valence_core::hand::Hand; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; use valence_entity::{EntityAnimation, EntityAnimations}; +use valence_packet::packets::play::HandSwingC2s; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; @@ -38,9 +38,3 @@ fn handle_hand_swing( } } } - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::HAND_SWING_C2S)] -pub struct HandSwingC2s { - pub hand: Hand, -} diff --git a/crates/valence_client/src/interact_block.rs b/crates/valence_client/src/interact_block.rs index c2c9c36ed..322ff4b16 100644 --- a/crates/valence_client/src/interact_block.rs +++ b/crates/valence_client/src/interact_block.rs @@ -5,7 +5,7 @@ use valence_core::block_pos::BlockPos; use valence_core::direction::Direction; use valence_core::hand::Hand; use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; +use valence_packet::packets::play::PlayerInteractBlockC2s; use crate::action::ActionSequence; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; @@ -57,14 +57,3 @@ fn handle_interact_block( } } } - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_INTERACT_BLOCK_C2S)] -pub struct PlayerInteractBlockC2s { - pub hand: Hand, - pub position: BlockPos, - pub face: Direction, - pub cursor_pos: Vec3, - pub head_inside_block: bool, - pub sequence: VarInt, -} diff --git a/crates/valence_client/src/interact_entity.rs b/crates/valence_client/src/interact_entity.rs index 0c62b2ddf..80dae15ff 100644 --- a/crates/valence_client/src/interact_entity.rs +++ b/crates/valence_client/src/interact_entity.rs @@ -1,10 +1,8 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use glam::Vec3; -use valence_core::hand::Hand; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; use valence_entity::EntityManager; +use valence_packet::packets::play::player_interact_entity_c2s::EntityInteraction; +use valence_packet::packets::play::PlayerInteractEntityC2s; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; @@ -24,13 +22,6 @@ pub struct InteractEntityEvent { pub interact: EntityInteraction, } -#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode)] -pub enum EntityInteraction { - Interact(Hand), - Attack, - InteractAt { target: Vec3, hand: Hand }, -} - fn handle_interact_entity( mut packets: EventReader, entities: Res, @@ -53,11 +44,3 @@ fn handle_interact_entity( } } } - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_INTERACT_ENTITY_C2S)] -pub struct PlayerInteractEntityC2s { - pub entity_id: VarInt, - pub interact: EntityInteraction, - pub sneaking: bool, -} diff --git a/crates/valence_client/src/interact_item.rs b/crates/valence_client/src/interact_item.rs index f265e7d9f..09f61080c 100644 --- a/crates/valence_client/src/interact_item.rs +++ b/crates/valence_client/src/interact_item.rs @@ -1,8 +1,7 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use valence_core::hand::Hand; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; +use valence_packet::packets::play::PlayerInteractItemC2s; use crate::action::ActionSequence; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; @@ -38,10 +37,3 @@ fn handle_player_interact_item( } } } - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_INTERACT_ITEM_C2S)] -pub struct PlayerInteractItemC2s { - pub hand: Hand, - pub sequence: VarInt, -} diff --git a/crates/valence_client/src/keepalive.rs b/crates/valence_client/src/keepalive.rs index bc8b5eaad..6654d5d79 100644 --- a/crates/valence_client/src/keepalive.rs +++ b/crates/valence_client/src/keepalive.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; +use valence_packet::packets::play::{KeepAliveS2c, KeepAliveC2s}; use super::*; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; @@ -97,15 +97,3 @@ fn handle_keepalive_response( } } } - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::KEEP_ALIVE_C2S)] -pub struct KeepAliveC2s { - pub id: u64, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::KEEP_ALIVE_S2C)] -pub struct KeepAliveS2c { - pub id: u64, -} diff --git a/crates/valence_client/src/lib.rs b/crates/valence_client/src/lib.rs index aa0296b3f..1627f97c6 100644 --- a/crates/valence_client/src/lib.rs +++ b/crates/valence_client/src/lib.rs @@ -38,13 +38,11 @@ use valence_core::chunk_pos::{ChunkPos, ChunkView}; use valence_core::despawn::Despawned; use valence_core::game_mode::GameMode; use valence_core::ident::Ident; -use valence_core::particle::{Particle, ParticleS2c}; use valence_core::property::Property; +use valence_core::protocol::Encode; use valence_core::protocol::byte_angle::ByteAngle; -use valence_core::protocol::encode::{PacketEncoder, WritePacket}; use valence_core::protocol::global_pos::GlobalPos; use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{Encode, Packet}; use valence_core::sound::{Sound, SoundCategory}; use valence_core::text::{IntoText, Text}; use valence_core::uuid::UniqueId; @@ -55,18 +53,16 @@ use valence_entity::{ }; use valence_instance::chunk::loaded::ChunkState; use valence_instance::{ClearInstanceChangesSet, Instance, WriteUpdatePacketsToInstancesSet}; -use valence_packet::client::{ - DeathMessageS2c, DisconnectS2c, GameEventKind, GameJoinS2c, GameStateChangeS2c, - PlayerRespawnS2c, PlayerSpawnPositionS2c, PlayerSpawnS2c, -}; -use valence_packet::entity::{ +use valence_packet::packets::play::game_state_change_s2c::GameEventKind; +use valence_packet::packets::play::particle_s2c::Particle; +use valence_packet::packets::play::{ + ChunkLoadDistanceS2c, ChunkRenderDistanceCenterS2c, DeathMessageS2c, DisconnectS2c, EntitiesDestroyS2c, EntitySetHeadYawS2c, EntitySpawnS2c, EntityStatusS2c, - EntityTrackerUpdateS2c, EntityVelocityUpdateS2c, ExperienceOrbSpawnS2c, -}; -use valence_packet::instance::{ - ChunkLoadDistanceS2c, ChunkRenderDistanceCenterS2c, UnloadChunkS2c, + EntityTrackerUpdateS2c, EntityVelocityUpdateS2c, ExperienceOrbSpawnS2c, GameJoinS2c, + GameStateChangeS2c, PlayerRespawnS2c, PlayerSpawnPositionS2c, PlayerSpawnS2c, UnloadChunkS2c, ParticleS2c, PlaySoundS2c, }; -use valence_packet::sound::PlaySoundS2c; +use valence_packet::protocol::Packet; +use valence_packet::protocol::encode::{PacketEncoder, WritePacket}; use valence_registry::codec::RegistryCodec; use valence_registry::tags::TagsRegistry; use valence_registry::RegistrySet; diff --git a/crates/valence_client/src/message.rs b/crates/valence_client/src/message.rs index 8bc5c0996..dc2b7e24f 100644 --- a/crates/valence_client/src/message.rs +++ b/crates/valence_client/src/message.rs @@ -2,9 +2,9 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use valence_core::protocol::encode::WritePacket; +use valence_packet::protocol::encode::WritePacket; use valence_core::text::IntoText; -use valence_packet::chat::{ChatMessageC2s, GameMessageS2c}; +use valence_packet::packets::play::{ChatMessageC2s, GameMessageS2c}; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; diff --git a/crates/valence_client/src/movement.rs b/crates/valence_client/src/movement.rs index 76ddd2060..4f9b23a8b 100644 --- a/crates/valence_client/src/movement.rs +++ b/crates/valence_client/src/movement.rs @@ -1,8 +1,8 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use glam::DVec3; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; use valence_entity::{HeadYaw, Look, OnGround, Position}; +use valence_packet::packets::play::{VehicleMoveC2s, OnGroundOnlyC2s, LookAndOnGroundC2s, FullC2s, PositionAndOnGroundC2s}; use super::teleport::TeleportState; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; @@ -201,41 +201,3 @@ fn handle( movement_events.send(mov); } - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::POSITION_AND_ON_GROUND)] -pub struct PositionAndOnGroundC2s { - pub position: DVec3, - pub on_ground: bool, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::FULL)] -pub struct FullC2s { - pub position: DVec3, - pub yaw: f32, - pub pitch: f32, - pub on_ground: bool, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::LOOK_AND_ON_GROUND)] -pub struct LookAndOnGroundC2s { - pub yaw: f32, - pub pitch: f32, - pub on_ground: bool, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::ON_GROUND_ONLY)] -pub struct OnGroundOnlyC2s { - pub on_ground: bool, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::VEHICLE_MOVE_C2S)] -pub struct VehicleMoveC2s { - pub position: DVec3, - pub yaw: f32, - pub pitch: f32, -} diff --git a/crates/valence_client/src/op_level.rs b/crates/valence_client/src/op_level.rs index 955d59b63..5426961f1 100644 --- a/crates/valence_client/src/op_level.rs +++ b/crates/valence_client/src/op_level.rs @@ -1,5 +1,3 @@ -use valence_packet::entity::EntityStatusS2c; - use super::*; pub(super) fn build(app: &mut App) { @@ -21,7 +19,7 @@ impl OpLevel { } fn update_op_level(mut clients: Query<(&mut Client, &OpLevel), Changed>) { - for (mut client, lvl) in &mut clients { + for (mut client, lvl) in &mut clients.iter_mut() { client.write_packet(&EntityStatusS2c { entity_id: 0, entity_status: 24 + lvl.0, diff --git a/crates/valence_client/src/resource_pack.rs b/crates/valence_client/src/resource_pack.rs index aeaee9bae..0c25c11a3 100644 --- a/crates/valence_client/src/resource_pack.rs +++ b/crates/valence_client/src/resource_pack.rs @@ -1,13 +1,10 @@ -use std::borrow::Cow; - use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use valence_core::protocol::encode::WritePacket; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; use valence_core::text::Text; +use valence_packet::packets::play::{ResourcePackStatusC2s, ResourcePackSendS2c}; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; -use crate::Client; +use super::*; pub(super) fn build(app: &mut App) { app.add_event::() @@ -17,11 +14,9 @@ pub(super) fn build(app: &mut App) { #[derive(Event, Copy, Clone, PartialEq, Eq, Debug)] pub struct ResourcePackStatusEvent { pub client: Entity, - pub status: ResourcePackStatus, + pub status: ResourcePackStatusC2s, } -pub use ResourcePackStatusC2s as ResourcePackStatus; - impl Client { /// Requests that the client download and enable a resource pack. /// @@ -62,25 +57,3 @@ fn handle_resource_pack_status( } } } - -#[derive(Clone, PartialEq, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::RESOURCE_PACK_SEND_S2C)] -pub struct ResourcePackSendS2c<'a> { - pub url: &'a str, - pub hash: &'a str, - pub forced: bool, - pub prompt_message: Option>, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::RESOURCE_PACK_STATUS_C2S)] -pub enum ResourcePackStatusC2s { - /// The client has successfully loaded the server's resource pack. - SuccessfullyLoaded, - /// The client has declined the server's resource pack. - Declined, - /// The client has failed to download the server's resource pack. - FailedDownload, - /// The client has accepted the server's resource pack. - Accepted, -} diff --git a/crates/valence_client/src/settings.rs b/crates/valence_client/src/settings.rs index 369dbccf8..2f56acd91 100644 --- a/crates/valence_client/src/settings.rs +++ b/crates/valence_client/src/settings.rs @@ -1,8 +1,8 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use bitfield_struct::bitfield; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; use valence_entity::player::{self, PlayerModelParts}; +use valence_packet::packets::play::ClientSettingsC2s; +use valence_packet::packets::play::client_settings_c2s::ChatMode; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; use crate::ViewDistance; @@ -49,50 +49,3 @@ fn handle_client_settings( } } } - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CLIENT_SETTINGS_C2S)] -pub struct ClientSettingsC2s<'a> { - pub locale: &'a str, - pub view_distance: u8, - pub chat_mode: ChatMode, - pub chat_colors: bool, - pub displayed_skin_parts: DisplayedSkinParts, - pub main_arm: MainArm, - pub enable_text_filtering: bool, - pub allow_server_listings: bool, -} - -#[bitfield(u8)] -#[derive(PartialEq, Eq, Encode, Decode)] -pub struct DisplayedSkinParts { - pub cape: bool, - pub jacket: bool, - pub left_sleeve: bool, - pub right_sleeve: bool, - pub left_pants_leg: bool, - pub right_pants_leg: bool, - pub hat: bool, - _pad: bool, -} - -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug, Encode, Decode)] -pub enum ChatMode { - Enabled, - CommandsOnly, - #[default] - Hidden, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Default, Encode, Decode)] -pub enum MainArm { - Left, - #[default] - Right, -} - -impl From for player::MainArm { - fn from(value: MainArm) -> Self { - Self(value as i8) - } -} diff --git a/crates/valence_client/src/status.rs b/crates/valence_client/src/status.rs index ec68232a6..74bf9218f 100644 --- a/crates/valence_client/src/status.rs +++ b/crates/valence_client/src/status.rs @@ -1,6 +1,6 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; +use valence_packet::packets::play::ClientStatusC2s; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; @@ -38,10 +38,3 @@ fn handle_status( } } } - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CLIENT_STATUS_C2S)] -pub enum ClientStatusC2s { - PerformRespawn, - RequestStats, -} diff --git a/crates/valence_client/src/teleport.rs b/crates/valence_client/src/teleport.rs index 1c18848b2..a03470116 100644 --- a/crates/valence_client/src/teleport.rs +++ b/crates/valence_client/src/teleport.rs @@ -1,7 +1,5 @@ -use bitfield_struct::bitfield; use glam::DVec3; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; +use valence_packet::packets::play::{TeleportConfirmC2s, PlayerPositionLookS2c, player_position_look_s2c::PlayerPositionLookFlags}; use super::*; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; @@ -128,31 +126,3 @@ fn handle_teleport_confirmations( } } } - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::TELEPORT_CONFIRM_C2S)] -pub struct TeleportConfirmC2s { - pub teleport_id: VarInt, -} - -#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_POSITION_LOOK_S2C)] -pub struct PlayerPositionLookS2c { - pub position: DVec3, - pub yaw: f32, - pub pitch: f32, - pub flags: PlayerPositionLookFlags, - pub teleport_id: VarInt, -} - -#[bitfield(u8)] -#[derive(PartialEq, Eq, Encode, Decode)] -pub struct PlayerPositionLookFlags { - pub x: bool, - pub y: bool, - pub z: bool, - pub y_rot: bool, - pub x_rot: bool, - #[bits(3)] - _pad: u8, -} diff --git a/crates/valence_client/src/title.rs b/crates/valence_client/src/title.rs index c1767dbe9..20282a5b3 100644 --- a/crates/valence_client/src/title.rs +++ b/crates/valence_client/src/title.rs @@ -1,5 +1,5 @@ -use valence_core::protocol::{packet_id, Decode, Encode}; use valence_core::text::IntoText; +use valence_packet::packets::play::{TitleS2c, SubtitleS2c, OverlayMessageS2c, TitleFadeS2c, ClearTitleS2c}; use super::*; @@ -61,35 +61,3 @@ impl SetTitle for T { self.write_packet(&ClearTitleS2c { reset: true }); } } - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::TITLE_S2C)] -pub struct TitleS2c<'a> { - pub title_text: Cow<'a, Text>, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::SUBTITLE_S2C)] -pub struct SubtitleS2c<'a> { - pub subtitle_text: Cow<'a, Text>, -} - -#[derive(Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::OVERLAY_MESSAGE_S2C)] -pub struct OverlayMessageS2c<'a> { - pub action_bar_text: Cow<'a, Text>, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::TITLE_FADE_S2C)] -pub struct TitleFadeS2c { - pub fade_in: i32, - pub stay: i32, - pub fade_out: i32, -} - -#[derive(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::CLEAR_TITLE_S2C)] -pub struct ClearTitleS2c { - pub reset: bool, -} diff --git a/crates/valence_client/src/weather.rs b/crates/valence_client/src/weather.rs index 4694a9841..44dd5befd 100644 --- a/crates/valence_client/src/weather.rs +++ b/crates/valence_client/src/weather.rs @@ -15,8 +15,6 @@ //! New joined players are handled, so that they are get weather events from //! the instance. -use valence_packet::client::{GameEventKind, GameStateChangeS2c}; - use super::*; #[derive(SystemSet, Copy, Clone, PartialEq, Eq, Hash, Debug)] diff --git a/crates/valence_entity/build.rs b/crates/valence_entity/build.rs index 20bbd2ea0..4685b9ef2 100644 --- a/crates/valence_entity/build.rs +++ b/crates/valence_entity/build.rs @@ -140,7 +140,7 @@ impl Value { Value::BlockState(_) => quote!(valence_block::BlockState), Value::OptionalBlockState(_) => quote!(valence_block::BlockState), Value::NbtCompound(_) => quote!(valence_nbt::Compound), - Value::Particle(_) => quote!(valence_core::particle::Particle), + Value::Particle(_) => quote!(valence_packet::packets::play::particle_s2c::Particle), Value::VillagerData { .. } => quote!(crate::VillagerData), Value::OptionalInt(_) => quote!(Option), Value::EntityPose(_) => quote!(crate::Pose), @@ -209,7 +209,7 @@ impl Value { } Value::Particle(p) => { let variant = ident(p.replace('.', "_").to_pascal_case()); - quote!(valence_core::particle::Particle::#variant) + quote!(valence_packet::packets::play::particle_s2c::Particle::#variant) } Value::VillagerData { typ, diff --git a/crates/valence_instance/src/chunk/loaded.rs b/crates/valence_instance/src/chunk/loaded.rs index c6bffddfd..21af9a7c6 100644 --- a/crates/valence_instance/src/chunk/loaded.rs +++ b/crates/valence_instance/src/chunk/loaded.rs @@ -11,16 +11,18 @@ use valence_block::BlockState; use valence_core::block_pos::BlockPos; use valence_core::chunk_pos::ChunkPos; use valence_core::despawn::Despawned; -use valence_core::protocol::encode::{PacketWriter, WritePacket}; use valence_core::protocol::var_int::VarInt; use valence_core::protocol::var_long::VarLong; -use valence_core::protocol::{Encode, Packet}; +use valence_core::protocol::Encode; use valence_entity::EntityKind; use valence_nbt::{compound, Compound}; -use valence_packet::instance::{ - BlockEntityUpdateS2c, BlockUpdateS2c, ChunkBiome, ChunkBiomeDataS2c, ChunkDataBlockEntity, - ChunkDataS2c, ChunkDeltaUpdateS2c, +use valence_packet::packets::play::chunk_biome_data_s2c::ChunkBiome; +use valence_packet::packets::play::chunk_data_s2c::ChunkDataBlockEntity; +use valence_packet::packets::play::{ + BlockEntityUpdateS2c, BlockUpdateS2c, ChunkBiomeDataS2c, ChunkDataS2c, ChunkDeltaUpdateS2c, }; +use valence_packet::protocol::encode::{PacketWriter, WritePacket}; +use valence_packet::protocol::Packet; use valence_registry::RegistryIdx; use super::paletted_container::PalettedContainer; diff --git a/crates/valence_instance/src/instance.rs b/crates/valence_instance/src/instance.rs index e291b0609..1646c1f44 100644 --- a/crates/valence_instance/src/instance.rs +++ b/crates/valence_instance/src/instance.rs @@ -11,15 +11,16 @@ use valence_biome::BiomeRegistry; use valence_core::block_pos::BlockPos; use valence_core::chunk_pos::ChunkPos; use valence_core::ident::Ident; -use valence_core::particle::{Particle, ParticleS2c}; use valence_core::protocol::array::LengthPrefixedArray; -use valence_core::protocol::encode::{PacketWriter, WritePacket}; -use valence_core::protocol::{Encode, Packet}; +use valence_core::protocol::Encode; use valence_core::sound::{Sound, SoundCategory}; use valence_core::Server; use valence_dimension::DimensionTypeRegistry; use valence_nbt::Compound; -use valence_packet::sound::PlaySoundS2c; +use valence_packet::packets::play::particle_s2c::Particle; +use valence_packet::packets::play::{ParticleS2c, PlaySoundS2c}; +use valence_packet::protocol::encode::{PacketWriter, WritePacket}; +use valence_packet::protocol::Packet; use crate::chunk::{Block, BlockRef, Chunk, IntoBlock, LoadedChunk, UnloadedChunk, MAX_HEIGHT}; diff --git a/crates/valence_instance/src/lib.rs b/crates/valence_instance/src/lib.rs index 8f2c582e3..7139808ac 100644 --- a/crates/valence_instance/src/lib.rs +++ b/crates/valence_instance/src/lib.rs @@ -27,14 +27,13 @@ use chunk::loaded::ChunkState; use valence_core::chunk_pos::ChunkPos; use valence_core::despawn::Despawned; use valence_core::protocol::byte_angle::ByteAngle; -use valence_core::protocol::encode::WritePacket; use valence_core::protocol::var_int::VarInt; use valence_entity::{ EntityAnimations, EntityId, EntityKind, EntityStatuses, HeadYaw, InitEntitiesSet, Location, Look, OldLocation, OldPosition, OnGround, PacketByteRange, Position, TrackedData, UpdateTrackedDataSet, Velocity, }; -use valence_packet::entity::{ +use valence_packet::packets::play::{ EntityAnimationS2c, EntityPositionS2c, EntitySetHeadYawS2c, EntityStatusS2c, EntityTrackerUpdateS2c, EntityVelocityUpdateS2c, MoveRelativeS2c, RotateAndMoveRelativeS2c, RotateS2c, @@ -45,6 +44,7 @@ mod instance; pub use chunk::{Block, BlockRef}; pub use instance::*; +use valence_packet::protocol::encode::WritePacket; pub struct InstancePlugin; diff --git a/crates/valence_packet/Cargo.toml b/crates/valence_packet/Cargo.toml index bcef7737b..682b20d57 100644 --- a/crates/valence_packet/Cargo.toml +++ b/crates/valence_packet/Cargo.toml @@ -16,6 +16,7 @@ uuid = { workspace = true, features = ["serde"] } bytes.workspace = true tracing.workspace = true bevy_ecs.workspace = true +serde = { workspace = true, features = ["derive"] } [dev-dependencies] rand.workspace = true diff --git a/crates/valence_packet/src/packets/play/synchronize_tags_s2c.rs b/crates/valence_packet/src/packets/play/synchronize_tags_s2c.rs index 68ca74cd1..37c49426b 100644 --- a/crates/valence_packet/src/packets/play/synchronize_tags_s2c.rs +++ b/crates/valence_packet/src/packets/play/synchronize_tags_s2c.rs @@ -1,4 +1,4 @@ -use valence_registry::tags::Registry; +use serde::Deserialize; use super::*; @@ -7,3 +7,15 @@ use super::*; pub struct SynchronizeTagsS2c<'a> { pub registries: Cow<'a, [Registry]>, } + +#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Encode, Decode)] +pub struct Registry { + pub registry: Ident, + pub tags: Vec, +} + +#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Encode, Decode)] +pub struct TagEntry { + pub name: Ident, + pub entries: Vec, +} diff --git a/crates/valence_registry/src/tags.rs b/crates/valence_registry/src/tags.rs index 57d307ea5..5e9ae25eb 100644 --- a/crates/valence_registry/src/tags.rs +++ b/crates/valence_registry/src/tags.rs @@ -2,12 +2,10 @@ use std::borrow::Cow; use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use serde::Deserialize; -use valence_core::ident::Ident; -use valence_packet::protocol::encode::{PacketWriter, WritePacket}; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{Decode, Encode}; use valence_core::Server; +pub use valence_packet::packets::play::synchronize_tags_s2c::Registry; +use valence_packet::packets::play::SynchronizeTagsS2c; +use valence_packet::protocol::encode::{PacketWriter, WritePacket}; use crate::RegistrySet; @@ -23,18 +21,6 @@ pub struct TagsRegistry { cached_packet: Vec, } -#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Encode, Decode)] -pub struct Registry { - pub registry: Ident, - pub tags: Vec, -} - -#[derive(Debug, Deserialize, Clone, PartialEq, Eq, Encode, Decode)] -pub struct TagEntry { - pub name: Ident, - pub entries: Vec, -} - impl TagsRegistry { fn build_synchronize_tags(&self) -> SynchronizeTagsS2c { SynchronizeTagsS2c { From 3a3ca8cb09747b26110e83be8b376758a97d2d06 Mon Sep 17 00:00:00 2001 From: Bafbi Date: Wed, 2 Aug 2023 15:11:12 +0200 Subject: [PATCH 8/9] update all import --- benches/many_players.rs | 3 +- benches/packet.rs | 9 +- crates/valence_advancement/src/lib.rs | 24 ++--- crates/valence_boss_bar/src/lib.rs | 11 ++- crates/valence_client/src/action.rs | 2 - crates/valence_client/src/command.rs | 2 +- crates/valence_client/src/custom_payload.rs | 1 - crates/valence_client/src/interact_block.rs | 1 - crates/valence_client/src/interact_entity.rs | 2 +- crates/valence_client/src/keepalive.rs | 2 +- crates/valence_client/src/lib.rs | 7 +- crates/valence_client/src/message.rs | 2 +- crates/valence_client/src/movement.rs | 4 +- crates/valence_client/src/resource_pack.rs | 4 +- crates/valence_client/src/settings.rs | 2 +- crates/valence_client/src/teleport.rs | 3 +- crates/valence_client/src/title.rs | 4 +- crates/valence_core/src/boss_bar.rs | 35 ------- crates/valence_core/src/lib.rs | 1 - crates/valence_core/src/protocol.rs | 2 +- crates/valence_core_macros/src/lib.rs | 2 +- crates/valence_inventory/src/lib.rs | 17 ++-- crates/valence_inventory/src/validate.rs | 5 +- crates/valence_network/Cargo.toml | 4 +- crates/valence_network/src/connect.rs | 13 ++- crates/valence_network/src/packet_io.rs | 7 +- crates/valence_packet/Cargo.toml | 7 ++ crates/valence_packet/build.rs | 15 +-- crates/valence_packet/src/lib.rs | 2 +- crates/valence_packet/src/packets.rs | 9 +- .../valence_packet/src/packets/handshaking.rs | 2 +- .../packets/play/advancement_update_s2c.rs | 18 +++- .../src/packets/play/boss_bar_s2c.rs | 8 +- crates/valence_packet/src/protocol.rs | 5 +- crates/valence_packet/src/protocol/decode.rs | 3 +- crates/valence_packet_macros/src/lib.rs | 4 +- crates/valence_player_list/src/lib.rs | 14 +-- crates/valence_world_border/src/lib.rs | 8 +- examples/boss_bar.rs | 92 ++++++------------- examples/resource_pack.rs | 11 ++- src/lib.rs | 2 +- src/testing.rs | 9 +- src/tests/boss_bar.rs | 51 +++++----- src/tests/client.rs | 10 +- src/tests/example.rs | 3 +- src/tests/instance.rs | 2 +- src/tests/inventory.rs | 14 +-- src/tests/player_list.rs | 3 +- src/tests/weather.rs | 2 +- src/tests/world_border.rs | 5 +- tools/packet_inspector/src/app/text_viewer.rs | 43 ++------- tools/packet_inspector/src/lib.rs | 11 ++- tools/packet_inspector/src/packet_io.rs | 4 +- tools/packet_inspector/src/packet_registry.rs | 2 +- tools/stresser/src/stresser.rs | 19 ++-- 55 files changed, 237 insertions(+), 310 deletions(-) delete mode 100644 crates/valence_core/src/boss_bar.rs diff --git a/benches/many_players.rs b/benches/many_players.rs index f31c5b67e..7cc14e875 100644 --- a/benches/many_players.rs +++ b/benches/many_players.rs @@ -7,9 +7,7 @@ use rand::Rng; use valence::testing::create_mock_client; use valence::DefaultPlugins; use valence_biome::BiomeRegistry; -use valence_client::hand_swing::HandSwingC2s; use valence_client::keepalive::KeepaliveSettings; -use valence_client::movement::FullC2s; use valence_core::chunk_pos::ChunkPos; use valence_core::{ident, CoreSettings, Server}; use valence_dimension::DimensionTypeRegistry; @@ -17,6 +15,7 @@ use valence_entity::Position; use valence_instance::chunk::UnloadedChunk; use valence_instance::Instance; use valence_network::NetworkPlugin; +use valence_packet::packets::play::{FullC2s, HandSwingC2s}; const CLIENT_COUNT: usize = 3000; const VIEW_DIST: u8 = 20; diff --git a/benches/packet.rs b/benches/packet.rs index 9ad3fb945..1e0525bdb 100644 --- a/benches/packet.rs +++ b/benches/packet.rs @@ -3,17 +3,14 @@ use std::hint::black_box; use criterion::Criterion; use valence::nbt::{compound, List}; +use valence::packet::packets::play::{ChunkDataS2c, EntitySpawnS2c, PlayerListHeaderS2c}; +use valence::packet::protocol::decode::PacketDecoder; +use valence::packet::protocol::encode::{PacketEncoder, PacketWriter, WritePacket}; use valence::prelude::*; use valence::protocol::array::LengthPrefixedArray; use valence::protocol::byte_angle::ByteAngle; -use valence::protocol::decode::PacketDecoder; -use valence::protocol::encode::PacketEncoder; use valence::protocol::var_int::VarInt; use valence::text::IntoText; -use valence_core::protocol::encode::{PacketWriter, WritePacket}; -use valence_packet::entity::EntitySpawnS2c; -use valence_packet::instance::ChunkDataS2c; -use valence_packet::player_list::PlayerListHeaderS2c; pub fn packet(c: &mut Criterion) { let mut group = c.benchmark_group("packet"); diff --git a/crates/valence_advancement/src/lib.rs b/crates/valence_advancement/src/lib.rs index 93478164e..cc30f53c0 100644 --- a/crates/valence_advancement/src/lib.rs +++ b/crates/valence_advancement/src/lib.rs @@ -17,15 +17,15 @@ use rustc_hash::FxHashMap; use valence_client::{Client, FlushPacketsSet, SpawnClientsSet}; use valence_core::ident::Ident; use valence_core::item::ItemStack; -use valence_core::protocol::encode::WritePacket; use valence_core::protocol::raw::RawBytes; use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{packet_id, Encode, Packet, PacketSide, PacketState}; +use valence_core::protocol::Encode; use valence_core::text::Text; -use valence_packet::advancement::{ - AdvancementCriteriaPkt, AdvancementDisplayPkt, AdvancementPkt, AdvancementRequirementsPkt, - GenericAdvancementUpdateS2c, SelectAdvancementTabS2c, +use valence_packet::packets::play::{ + advancement_update_s2c as packet, AdvancementUpdateS2c, SelectAdvancementTabS2c, }; +use valence_packet::protocol::encode::WritePacket; +use valence_packet::protocol::{packet_id, Packet, PacketSide, PacketState}; pub struct AdvancementPlugin; @@ -56,8 +56,8 @@ impl Plugin for AdvancementPlugin { .add_systems( PostUpdate, ( - update_advancement_cached_bytes, - send_advancement_update_packet, + update_advancement_cached_bytes.in_set(WriteAdvancementToCacheSet), + send_advancement_update_packet.in_set(WriteAdvancementPacketToClientsSet), ), ); } @@ -106,7 +106,7 @@ impl<'w, 's> UpdateAdvancementCachedBytesQuery<'w, 's> { criteria_query, } = self; - let mut pkt = AdvancementPkt { + let mut pkt = packet::Advancement { parent_id: None, display_data: None, criteria: vec![], @@ -120,7 +120,7 @@ impl<'w, 's> UpdateAdvancementCachedBytesQuery<'w, 's> { } if let Some(a_display) = a_display { - pkt.display_data = Some(AdvancementDisplayPkt { + pkt.display_data = Some(packet::AdvancementDisplay { title: Cow::Borrowed(&a_display.title), description: Cow::Borrowed(&a_display.description), icon: &a_display.icon, @@ -147,7 +147,7 @@ impl<'w, 's> UpdateAdvancementCachedBytesQuery<'w, 's> { let c_identifier = criteria_query.get(*requirement)?; requirements_p.push(c_identifier.0.as_str()); } - pkt.requirements.push(AdvancementRequirementsPkt { + pkt.requirements.push(packet::AdvancementRequirements { requirement: requirements_p, }); } @@ -224,7 +224,7 @@ impl<'w, 's, 'a> Encode for AdvancementUpdateEncodeS2c<'w, 's, 'a> { reset, } = &self.client_update; - let mut pkt = GenericAdvancementUpdateS2c { + let mut pkt = AdvancementUpdateS2c { reset: *reset, advancement_mapping: vec![], identifiers: vec![], @@ -257,7 +257,7 @@ impl<'w, 's, 'a> Encode for AdvancementUpdateEncodeS2c<'w, 's, 'a> { let mut c_progresses_p = vec![]; for (c, c_progress) in c_progresses { let c_identifier = criteria_query.get(c)?; - c_progresses_p.push(AdvancementCriteriaPkt { + c_progresses_p.push(packet::AdvancementCriteria { criterion_identifier: c_identifier.0.borrowed(), criterion_progress: c_progress, }); diff --git a/crates/valence_boss_bar/src/lib.rs b/crates/valence_boss_bar/src/lib.rs index b2e199d1c..d756fad29 100644 --- a/crates/valence_boss_bar/src/lib.rs +++ b/crates/valence_boss_bar/src/lib.rs @@ -19,13 +19,19 @@ )] use std::borrow::Cow; +use std::collections::BTreeSet; use bevy_app::prelude::*; use bevy_ecs::prelude::*; use valence_client::{Client, FlushPacketsSet}; use valence_core::despawn::Despawned; -use valence_core::protocol::encode::WritePacket; +use valence_core::text::Text; use valence_core::uuid::UniqueId; +pub use valence_packet::packets::play::boss_bar_s2c::{ + BossBarAction, BossBarColor, BossBarDivision, BossBarFlags, +}; +use valence_packet::packets::play::BossBarS2c; +use valence_packet::protocol::encode::WritePacket; /// The bundle of components that make up a boss bar. #[derive(Bundle)] @@ -83,7 +89,6 @@ pub struct BossBarViewers { pub(crate) old_viewers: BTreeSet, } - pub struct BossBarPlugin; impl Plugin for BossBarPlugin { @@ -253,4 +258,4 @@ fn client_disconnection( boss_bar_viewers.viewers.remove(&entity); } } -} \ No newline at end of file +} diff --git a/crates/valence_client/src/action.rs b/crates/valence_client/src/action.rs index 3c26ba6b5..05f36fe1d 100644 --- a/crates/valence_client/src/action.rs +++ b/crates/valence_client/src/action.rs @@ -1,10 +1,8 @@ use valence_core::block_pos::BlockPos; use valence_core::direction::Direction; use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{Decode, Encode}; use valence_packet::packets::play::player_action_c2s::PlayerAction; use valence_packet::packets::play::{PlayerActionC2s, PlayerActionResponseS2c}; -use valence_packet::protocol::Packet; use super::*; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; diff --git a/crates/valence_client/src/command.rs b/crates/valence_client/src/command.rs index 78b7c2d11..8f67d905a 100644 --- a/crates/valence_client/src/command.rs +++ b/crates/valence_client/src/command.rs @@ -2,7 +2,7 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use valence_entity::entity::Flags; use valence_entity::{entity, Pose}; -use valence_packet::packets::play::client_command_c2s::ClientCommand; +pub use valence_packet::packets::play::client_command_c2s::ClientCommand; use valence_packet::packets::play::ClientCommandC2s; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; diff --git a/crates/valence_client/src/custom_payload.rs b/crates/valence_client/src/custom_payload.rs index 8baa67730..5f35ad7d4 100644 --- a/crates/valence_client/src/custom_payload.rs +++ b/crates/valence_client/src/custom_payload.rs @@ -1,4 +1,3 @@ -use valence_core::protocol::raw::RawBytes; use valence_packet::packets::play::{CustomPayloadC2s, CustomPayloadS2c}; use super::*; diff --git a/crates/valence_client/src/interact_block.rs b/crates/valence_client/src/interact_block.rs index 322ff4b16..f9bf8fe5e 100644 --- a/crates/valence_client/src/interact_block.rs +++ b/crates/valence_client/src/interact_block.rs @@ -4,7 +4,6 @@ use glam::Vec3; use valence_core::block_pos::BlockPos; use valence_core::direction::Direction; use valence_core::hand::Hand; -use valence_core::protocol::var_int::VarInt; use valence_packet::packets::play::PlayerInteractBlockC2s; use crate::action::ActionSequence; diff --git a/crates/valence_client/src/interact_entity.rs b/crates/valence_client/src/interact_entity.rs index 80dae15ff..c6025843b 100644 --- a/crates/valence_client/src/interact_entity.rs +++ b/crates/valence_client/src/interact_entity.rs @@ -1,7 +1,7 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use valence_entity::EntityManager; -use valence_packet::packets::play::player_interact_entity_c2s::EntityInteraction; +pub use valence_packet::packets::play::player_interact_entity_c2s::EntityInteraction; use valence_packet::packets::play::PlayerInteractEntityC2s; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; diff --git a/crates/valence_client/src/keepalive.rs b/crates/valence_client/src/keepalive.rs index 6654d5d79..aa24a9a5f 100644 --- a/crates/valence_client/src/keepalive.rs +++ b/crates/valence_client/src/keepalive.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use valence_packet::packets::play::{KeepAliveS2c, KeepAliveC2s}; +use valence_packet::packets::play::{KeepAliveC2s, KeepAliveS2c}; use super::*; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; diff --git a/crates/valence_client/src/lib.rs b/crates/valence_client/src/lib.rs index 1627f97c6..155639a50 100644 --- a/crates/valence_client/src/lib.rs +++ b/crates/valence_client/src/lib.rs @@ -39,10 +39,10 @@ use valence_core::despawn::Despawned; use valence_core::game_mode::GameMode; use valence_core::ident::Ident; use valence_core::property::Property; -use valence_core::protocol::Encode; use valence_core::protocol::byte_angle::ByteAngle; use valence_core::protocol::global_pos::GlobalPos; use valence_core::protocol::var_int::VarInt; +use valence_core::protocol::Encode; use valence_core::sound::{Sound, SoundCategory}; use valence_core::text::{IntoText, Text}; use valence_core::uuid::UniqueId; @@ -59,10 +59,11 @@ use valence_packet::packets::play::{ ChunkLoadDistanceS2c, ChunkRenderDistanceCenterS2c, DeathMessageS2c, DisconnectS2c, EntitiesDestroyS2c, EntitySetHeadYawS2c, EntitySpawnS2c, EntityStatusS2c, EntityTrackerUpdateS2c, EntityVelocityUpdateS2c, ExperienceOrbSpawnS2c, GameJoinS2c, - GameStateChangeS2c, PlayerRespawnS2c, PlayerSpawnPositionS2c, PlayerSpawnS2c, UnloadChunkS2c, ParticleS2c, PlaySoundS2c, + GameStateChangeS2c, ParticleS2c, PlaySoundS2c, PlayerRespawnS2c, PlayerSpawnPositionS2c, + PlayerSpawnS2c, UnloadChunkS2c, }; -use valence_packet::protocol::Packet; use valence_packet::protocol::encode::{PacketEncoder, WritePacket}; +use valence_packet::protocol::Packet; use valence_registry::codec::RegistryCodec; use valence_registry::tags::TagsRegistry; use valence_registry::RegistrySet; diff --git a/crates/valence_client/src/message.rs b/crates/valence_client/src/message.rs index dc2b7e24f..c0f6941ad 100644 --- a/crates/valence_client/src/message.rs +++ b/crates/valence_client/src/message.rs @@ -2,9 +2,9 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use valence_packet::protocol::encode::WritePacket; use valence_core::text::IntoText; use valence_packet::packets::play::{ChatMessageC2s, GameMessageS2c}; +use valence_packet::protocol::encode::WritePacket; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; diff --git a/crates/valence_client/src/movement.rs b/crates/valence_client/src/movement.rs index 4f9b23a8b..2cf34b73e 100644 --- a/crates/valence_client/src/movement.rs +++ b/crates/valence_client/src/movement.rs @@ -2,7 +2,9 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use glam::DVec3; use valence_entity::{HeadYaw, Look, OnGround, Position}; -use valence_packet::packets::play::{VehicleMoveC2s, OnGroundOnlyC2s, LookAndOnGroundC2s, FullC2s, PositionAndOnGroundC2s}; +use valence_packet::packets::play::{ + FullC2s, LookAndOnGroundC2s, OnGroundOnlyC2s, PositionAndOnGroundC2s, VehicleMoveC2s, +}; use super::teleport::TeleportState; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; diff --git a/crates/valence_client/src/resource_pack.rs b/crates/valence_client/src/resource_pack.rs index 0c25c11a3..9d3edec94 100644 --- a/crates/valence_client/src/resource_pack.rs +++ b/crates/valence_client/src/resource_pack.rs @@ -1,10 +1,10 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use valence_core::text::Text; -use valence_packet::packets::play::{ResourcePackStatusC2s, ResourcePackSendS2c}; +use valence_packet::packets::play::{ResourcePackSendS2c, ResourcePackStatusC2s}; -use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; use super::*; +use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; pub(super) fn build(app: &mut App) { app.add_event::() diff --git a/crates/valence_client/src/settings.rs b/crates/valence_client/src/settings.rs index 2f56acd91..2c99d32ab 100644 --- a/crates/valence_client/src/settings.rs +++ b/crates/valence_client/src/settings.rs @@ -1,8 +1,8 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use valence_entity::player::{self, PlayerModelParts}; -use valence_packet::packets::play::ClientSettingsC2s; use valence_packet::packets::play::client_settings_c2s::ChatMode; +use valence_packet::packets::play::ClientSettingsC2s; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; use crate::ViewDistance; diff --git a/crates/valence_client/src/teleport.rs b/crates/valence_client/src/teleport.rs index a03470116..93ac21dc4 100644 --- a/crates/valence_client/src/teleport.rs +++ b/crates/valence_client/src/teleport.rs @@ -1,5 +1,6 @@ use glam::DVec3; -use valence_packet::packets::play::{TeleportConfirmC2s, PlayerPositionLookS2c, player_position_look_s2c::PlayerPositionLookFlags}; +use valence_packet::packets::play::player_position_look_s2c::PlayerPositionLookFlags; +use valence_packet::packets::play::{PlayerPositionLookS2c, TeleportConfirmC2s}; use super::*; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; diff --git a/crates/valence_client/src/title.rs b/crates/valence_client/src/title.rs index 20282a5b3..f6b1fe2c8 100644 --- a/crates/valence_client/src/title.rs +++ b/crates/valence_client/src/title.rs @@ -1,5 +1,7 @@ use valence_core::text::IntoText; -use valence_packet::packets::play::{TitleS2c, SubtitleS2c, OverlayMessageS2c, TitleFadeS2c, ClearTitleS2c}; +use valence_packet::packets::play::{ + ClearTitleS2c, OverlayMessageS2c, SubtitleS2c, TitleFadeS2c, TitleS2c, +}; use super::*; diff --git a/crates/valence_core/src/boss_bar.rs b/crates/valence_core/src/boss_bar.rs deleted file mode 100644 index 8c2f8c587..000000000 --- a/crates/valence_core/src/boss_bar.rs +++ /dev/null @@ -1,35 +0,0 @@ -use bitfield_struct::bitfield; -use valence_core_macros::{Decode, Encode}; - -/// The color of a boss bar. -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum BossBarColor { - Pink, - Blue, - Red, - Green, - Yellow, - Purple, - White, -} - -/// The division of a boss bar. -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum BossBarDivision { - NoDivision, - SixNotches, - TenNotches, - TwelveNotches, - TwentyNotches, -} - -/// The flags of a boss bar (darken sky, dragon bar, create fog). -#[bitfield(u8)] -#[derive(PartialEq, Eq, Encode, Decode)] -pub struct BossBarFlags { - pub darken_sky: bool, - pub dragon_bar: bool, - pub create_fog: bool, - #[bits(5)] - _pad: u8, -} diff --git a/crates/valence_core/src/lib.rs b/crates/valence_core/src/lib.rs index f32ae8791..aa1f59eea 100644 --- a/crates/valence_core/src/lib.rs +++ b/crates/valence_core/src/lib.rs @@ -20,7 +20,6 @@ pub mod aabb; pub mod block_pos; -pub mod boss_bar; pub mod chunk_pos; pub mod despawn; pub mod difficulty; diff --git a/crates/valence_core/src/protocol.rs b/crates/valence_core/src/protocol.rs index fc0c5935b..3b15c8e67 100644 --- a/crates/valence_core/src/protocol.rs +++ b/crates/valence_core/src/protocol.rs @@ -154,4 +154,4 @@ pub trait Decode<'a>: Sized { /// Implementations of `Decode` are expected to shrink the slice from the /// front as bytes are read. fn decode(r: &mut &'a [u8]) -> anyhow::Result; -} \ No newline at end of file +} diff --git a/crates/valence_core_macros/src/lib.rs b/crates/valence_core_macros/src/lib.rs index 32f68c1c6..82de02d63 100644 --- a/crates/valence_core_macros/src/lib.rs +++ b/crates/valence_core_macros/src/lib.rs @@ -122,4 +122,4 @@ fn add_trait_bounds(generics: &mut Generics, trait_: TokenStream) { type_param.bounds.push(parse_quote!(#trait_)) } } -} \ No newline at end of file +} diff --git a/crates/valence_inventory/src/lib.rs b/crates/valence_inventory/src/lib.rs index 624d4b688..f55a5d7eb 100644 --- a/crates/valence_inventory/src/lib.rs +++ b/crates/valence_inventory/src/lib.rs @@ -30,15 +30,16 @@ use valence_client::event_loop::{EventLoopPreUpdate, PacketEvent}; use valence_client::{Client, FlushPacketsSet, SpawnClientsSet}; use valence_core::game_mode::GameMode; use valence_core::item::ItemStack; -use valence_core::protocol::encode::WritePacket; use valence_core::protocol::var_int::VarInt; use valence_core::text::{IntoText, Text}; -use valence_packet::client::{PlayerAction, PlayerActionC2s}; -use valence_packet::inventory::{ - ClickMode, ClickSlotC2s, CloseHandledScreenC2s, CloseScreenS2c, CreativeInventoryActionC2s, - InventoryS2c, OpenScreenS2c, ScreenHandlerSlotUpdateS2c, SlotChange, UpdateSelectedSlotC2s, - WindowType, +pub use valence_packet::packets::play::click_slot_c2s::{ClickMode, SlotChange}; +pub use valence_packet::packets::play::open_screen_s2c::WindowType; +pub use valence_packet::packets::play::player_action_c2s::PlayerAction; +use valence_packet::packets::play::{ + ClickSlotC2s, CloseHandledScreenC2s, CloseScreenS2c, CreativeInventoryActionC2s, InventoryS2c, + OpenScreenS2c, PlayerActionC2s, ScreenHandlerSlotUpdateS2c, UpdateSelectedSlotC2s, }; +use valence_packet::protocol::encode::WritePacket; mod validate; @@ -1167,7 +1168,7 @@ fn handle_creative_inventory_action( #[derive(Event, Clone, Debug)] pub struct UpdateSelectedSlotEvent { pub client: Entity, - pub slot: i16, + pub slot: u8, } fn handle_update_selected_slot( @@ -1178,7 +1179,7 @@ fn handle_update_selected_slot( for packet in packets.iter() { if let Some(pkt) = packet.decode::() { if let Ok(mut held) = clients.get_mut(packet.client) { - if pkt.slot < 0 || pkt.slot > 8 { + if pkt.slot > 8 { // The client is trying to interact with a slot that does not exist, ignore. continue; } diff --git a/crates/valence_inventory/src/validate.rs b/crates/valence_inventory/src/validate.rs index 883d4178b..ba1af7b4e 100644 --- a/crates/valence_inventory/src/validate.rs +++ b/crates/valence_inventory/src/validate.rs @@ -1,6 +1,7 @@ use anyhow::{bail, ensure}; use valence_core::item::ItemStack; -use valence_packet::inventory::{ClickMode, ClickSlotC2s}; +use valence_packet::packets::play::click_slot_c2s::ClickMode; +use valence_packet::packets::play::ClickSlotC2s; use super::{CursorItem, Inventory, InventoryWindow, PLAYER_INVENTORY_MAIN_SLOTS_COUNT}; @@ -359,7 +360,7 @@ fn calculate_net_item_delta( mod tests { use valence_core::item::{ItemKind, ItemStack}; use valence_core::protocol::var_int::VarInt; - use valence_packet::inventory::SlotChange; + use valence_packet::packets::play::click_slot_c2s::SlotChange; use super::*; use crate::InventoryKind; diff --git a/crates/valence_network/Cargo.toml b/crates/valence_network/Cargo.toml index 870bc0c8d..68be203f7 100644 --- a/crates/valence_network/Cargo.toml +++ b/crates/valence_network/Cargo.toml @@ -5,8 +5,8 @@ edition.workspace = true [features] default = ["encryption", "compression"] # TODO: remove this. -encryption = ["valence_core/encryption"] -compression = ["valence_core/compression"] +encryption = ["valence_packet/encryption"] +compression = ["valence_packet/compression"] [dependencies] anyhow.workspace = true diff --git a/crates/valence_network/src/connect.rs b/crates/valence_network/src/connect.rs index 4da9fa5fb..ce1e68f38 100644 --- a/crates/valence_network/src/connect.rs +++ b/crates/valence_network/src/connect.rs @@ -19,18 +19,17 @@ use tokio::net::{TcpListener, TcpStream}; use tracing::{error, info, trace, warn}; use uuid::Uuid; use valence_core::property::Property; -use valence_core::protocol::decode::PacketDecoder; -use valence_core::protocol::encode::PacketEncoder; use valence_core::protocol::raw::RawBytes; use valence_core::protocol::var_int::VarInt; use valence_core::protocol::Decode; use valence_core::text::{Color, IntoText, Text}; use valence_core::{ident, translation_key, MINECRAFT_VERSION, PROTOCOL_VERSION}; -use valence_packet::network::{ - HandshakeC2s, HandshakeNextState, LoginCompressionS2c, LoginDisconnectS2c, LoginHelloC2s, - LoginHelloS2c, LoginKeyC2s, LoginQueryRequestS2c, LoginQueryResponseC2s, LoginSuccessS2c, - QueryPingC2s, QueryPongS2c, QueryRequestC2s, QueryResponseS2c, -}; +use valence_packet::packets::handshaking::handshake_c2s::HandshakeNextState; +use valence_packet::packets::handshaking::*; +use valence_packet::packets::login::*; +use valence_packet::packets::status::*; +use valence_packet::protocol::decode::PacketDecoder; +use valence_packet::protocol::encode::PacketEncoder; use crate::legacy_ping::try_handle_legacy_ping; use crate::packet_io::PacketIo; diff --git a/crates/valence_network/src/packet_io.rs b/crates/valence_network/src/packet_io.rs index d7e176723..c7a584f75 100644 --- a/crates/valence_network/src/packet_io.rs +++ b/crates/valence_network/src/packet_io.rs @@ -11,9 +11,10 @@ use tokio::sync::Semaphore; use tokio::task::JoinHandle; use tracing::{debug, warn}; use valence_client::{ClientBundleArgs, ClientConnection, ReceivedPacket}; -use valence_core::protocol::decode::{PacketDecoder, PacketFrame}; -use valence_core::protocol::encode::PacketEncoder; -use valence_core::protocol::{Decode, Encode, Packet}; +use valence_core::protocol::{Decode, Encode}; +use valence_packet::protocol::decode::{PacketDecoder, PacketFrame}; +use valence_packet::protocol::encode::PacketEncoder; +use valence_packet::protocol::Packet; use crate::byte_channel::{byte_channel, ByteSender, TrySendError}; use crate::{CleanupOnDrop, NewClientInfo}; diff --git a/crates/valence_packet/Cargo.toml b/crates/valence_packet/Cargo.toml index 682b20d57..f00dc53ac 100644 --- a/crates/valence_packet/Cargo.toml +++ b/crates/valence_packet/Cargo.toml @@ -3,6 +3,10 @@ name = "valence_packet" version.workspace = true edition.workspace = true +[features] +encryption = ["dep:aes", "dep:cfb8"] +compression = ["dep:flate2"] + [dependencies] valence_core.workspace = true valence_nbt.workspace = true @@ -17,6 +21,9 @@ bytes.workspace = true tracing.workspace = true bevy_ecs.workspace = true serde = { workspace = true, features = ["derive"] } +cfb8 = { workspace = true, optional = true } +flate2 = { workspace = true, optional = true } +aes = { workspace = true, optional = true } [dev-dependencies] rand.workspace = true diff --git a/crates/valence_packet/build.rs b/crates/valence_packet/build.rs index fe3c4fb31..9edf33f51 100644 --- a/crates/valence_packet/build.rs +++ b/crates/valence_packet/build.rs @@ -2,8 +2,7 @@ use heck::ToShoutySnakeCase; use proc_macro2::TokenStream; use quote::quote; use serde::Deserialize; -use valence_build_utils::ident; -use valence_build_utils::{rerun_if_changed, write_generated_file}; +use valence_build_utils::{ident, rerun_if_changed, write_generated_file}; #[derive(Deserialize)] struct Packet { @@ -14,19 +13,15 @@ struct Packet { } pub fn main() -> anyhow::Result<()> { - rerun_if_changed([ - "../../extracted/packets.json", - ]); + rerun_if_changed(["../../extracted/packets.json"]); - write_generated_file(build()?, "packet_id.rs")?; + write_generated_file(build()?, "packet_id.rs")?; - Ok(()) + Ok(()) } - pub fn build() -> anyhow::Result { - let packets: Vec = - serde_json::from_str(include_str!("../../extracted/packets.json"))?; + let packets: Vec = serde_json::from_str(include_str!("../../extracted/packets.json"))?; let mut consts = TokenStream::new(); diff --git a/crates/valence_packet/src/lib.rs b/crates/valence_packet/src/lib.rs index 112a343ef..666794a87 100644 --- a/crates/valence_packet/src/lib.rs +++ b/crates/valence_packet/src/lib.rs @@ -7,4 +7,4 @@ pub mod __private { pub use crate::protocol::Packet; } -extern crate self as valence_packet; \ No newline at end of file +extern crate self as valence_packet; diff --git a/crates/valence_packet/src/packets.rs b/crates/valence_packet/src/packets.rs index 95a3a203d..5f5befbd9 100644 --- a/crates/valence_packet/src/packets.rs +++ b/crates/valence_packet/src/packets.rs @@ -5,11 +5,12 @@ use anyhow::bail; use uuid::Uuid; use valence_core::ident::Ident; use valence_core::property::Property; -use valence_core::text::Text; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{Encode, Decode}; use valence_core::protocol::raw::RawBytes; -use crate::protocol::{Packet, packet_id, PacketState}; +use valence_core::protocol::var_int::VarInt; +use valence_core::protocol::{Decode, Encode}; +use valence_core::text::Text; + +use crate::protocol::{packet_id, Packet, PacketState}; pub mod handshaking; pub mod login; diff --git a/crates/valence_packet/src/packets/handshaking.rs b/crates/valence_packet/src/packets/handshaking.rs index 1aa5cbef3..b8508cf65 100644 --- a/crates/valence_packet/src/packets/handshaking.rs +++ b/crates/valence_packet/src/packets/handshaking.rs @@ -1,4 +1,4 @@ use super::*; pub mod handshake_c2s; -pub use handshake_c2s::HandshakeC2s; \ No newline at end of file +pub use handshake_c2s::HandshakeC2s; diff --git a/crates/valence_packet/src/packets/play/advancement_update_s2c.rs b/crates/valence_packet/src/packets/play/advancement_update_s2c.rs index e280dac56..35bad7098 100644 --- a/crates/valence_packet/src/packets/play/advancement_update_s2c.rs +++ b/crates/valence_packet/src/packets/play/advancement_update_s2c.rs @@ -2,9 +2,9 @@ use super::*; #[derive(Clone, Debug, Encode, Decode, Packet)] #[packet(id = packet_id::ADVANCEMENT_UPDATE_S2C)] -pub struct AdvancementUpdateS2c<'a, AM: 'a> { +pub struct AdvancementUpdateS2c<'a> { pub reset: bool, - pub advancement_mapping: Vec, + pub advancement_mapping: Vec<(Ident>, Advancement<'a, Option>)>, pub identifiers: Vec>>, pub progress_mapping: Vec<(Ident>, Vec>)>, } @@ -78,3 +78,17 @@ impl<'a, I: Decode<'a>> Decode<'a> for AdvancementDisplay<'a, I> { }) } } + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct Advancement<'a, I> { + pub parent_id: Option>>, + pub display_data: Option>, + pub criteria: Vec<(Ident>, ())>, + pub requirements: Vec>, + pub sends_telemetry_data: bool, +} + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub struct AdvancementRequirements<'a> { + pub requirement: Vec<&'a str>, +} diff --git a/crates/valence_packet/src/packets/play/boss_bar_s2c.rs b/crates/valence_packet/src/packets/play/boss_bar_s2c.rs index ab50553b5..3445789f9 100644 --- a/crates/valence_packet/src/packets/play/boss_bar_s2c.rs +++ b/crates/valence_packet/src/packets/play/boss_bar_s2c.rs @@ -1,3 +1,5 @@ +use bevy_ecs::prelude::Component; + use super::*; #[derive(Clone, Debug, Encode, Decode, Packet)] @@ -24,7 +26,7 @@ pub enum BossBarAction<'a> { } /// The color of a boss bar. -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode, Component)] pub enum BossBarColor { Pink, Blue, @@ -36,7 +38,7 @@ pub enum BossBarColor { } /// The division of a boss bar. -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode, Component)] pub enum BossBarDivision { NoDivision, SixNotches, @@ -47,7 +49,7 @@ pub enum BossBarDivision { /// The flags of a boss bar (darken sky, dragon bar, create fog). #[bitfield(u8)] -#[derive(PartialEq, Eq, Encode, Decode)] +#[derive(PartialEq, Eq, Encode, Decode, Component)] pub struct BossBarFlags { pub darken_sky: bool, pub dragon_bar: bool, diff --git a/crates/valence_packet/src/protocol.rs b/crates/valence_packet/src/protocol.rs index 93111edc3..bee997831 100644 --- a/crates/valence_packet/src/protocol.rs +++ b/crates/valence_packet/src/protocol.rs @@ -4,10 +4,9 @@ pub mod encode; use std::io::Write; use anyhow::Context; -pub use valence_packet_macros::Packet; - -use valence_core::protocol::*; use valence_core::protocol::var_int::VarInt; +use valence_core::protocol::*; +pub use valence_packet_macros::Packet; /// Types considered to be Minecraft packets. /// diff --git a/crates/valence_packet/src/protocol/decode.rs b/crates/valence_packet/src/protocol/decode.rs index 2418bf078..bbdcec8cb 100644 --- a/crates/valence_packet/src/protocol/decode.rs +++ b/crates/valence_packet/src/protocol/decode.rs @@ -4,12 +4,11 @@ use aes::cipher::generic_array::GenericArray; use aes::cipher::{BlockDecryptMut, BlockSizeUser, KeyIvInit}; use anyhow::{bail, ensure, Context}; use bytes::{Buf, BytesMut}; +use valence_core::protocol::Decode; use crate::protocol::var_int::{VarInt, VarIntDecodeError}; use crate::protocol::{Packet, MAX_PACKET_SIZE}; -use valence_core::protocol::Decode; - /// The AES block cipher with a 128 bit key, using the CFB-8 mode of /// operation. #[cfg(feature = "encryption")] diff --git a/crates/valence_packet_macros/src/lib.rs b/crates/valence_packet_macros/src/lib.rs index efdeadc6f..d55edec1b 100644 --- a/crates/valence_packet_macros/src/lib.rs +++ b/crates/valence_packet_macros/src/lib.rs @@ -19,9 +19,7 @@ use proc_macro::TokenStream as StdTokenStream; use proc_macro2::TokenStream; -use syn::{ - parse_quote, GenericParam, Generics, -}; +use syn::{parse_quote, GenericParam, Generics}; mod packet; diff --git a/crates/valence_player_list/src/lib.rs b/crates/valence_player_list/src/lib.rs index 74df598fc..3203d5ea8 100644 --- a/crates/valence_player_list/src/lib.rs +++ b/crates/valence_player_list/src/lib.rs @@ -26,14 +26,14 @@ use uuid::Uuid; use valence_client::{Client, Ping, Properties, Username}; use valence_core::despawn::Despawned; use valence_core::game_mode::GameMode; -use valence_core::protocol::encode::{PacketWriter, WritePacket}; use valence_core::text::{IntoText, Text}; use valence_core::uuid::UniqueId; use valence_core::Server; use valence_instance::WriteUpdatePacketsToInstancesSet; -use valence_packet::player_list::{ - PlayerListActions, PlayerListEntryPkt, PlayerListHeaderS2c, PlayerListS2c, PlayerRemoveS2c, +use valence_packet::packets::play::{ + player_list_s2c as packet, PlayerListHeaderS2c, PlayerListS2c, PlayerRemoveS2c, }; +use valence_packet::protocol::encode::{PacketWriter, WritePacket}; pub struct PlayerListPlugin; @@ -206,7 +206,7 @@ fn init_player_list_for_clients( ) { if player_list.manage_clients { for mut client in &mut clients { - let actions = PlayerListActions::new() + let actions = packet::PlayerListActions::new() .with_add_player(true) .with_update_game_mode(true) .with_update_listed(true) @@ -217,7 +217,7 @@ fn init_player_list_for_clients( .iter() .map( |(uuid, username, props, game_mode, ping, display_name, listed)| { - PlayerListEntryPkt { + packet::PlayerListEntry { player_uuid: uuid.0, username: &username.0, properties: Cow::Borrowed(&props.0), @@ -311,7 +311,7 @@ fn update_entries( ); for (uuid, username, props, game_mode, ping, display_name, listed) in &entries { - let mut actions = PlayerListActions::new(); + let mut actions = packet::PlayerListActions::new(); // Did a change occur that would force us to overwrite the entry? This also adds // new entries. @@ -353,7 +353,7 @@ fn update_entries( debug_assert_ne!(u8::from(actions), 0); } - let entry = PlayerListEntryPkt { + let entry = packet::PlayerListEntry { player_uuid: uuid.0, username: &username.0, properties: (&props.0).into(), diff --git a/crates/valence_world_border/src/lib.rs b/crates/valence_world_border/src/lib.rs index c5258e364..f3e0bfdf7 100644 --- a/crates/valence_world_border/src/lib.rs +++ b/crates/valence_world_border/src/lib.rs @@ -78,12 +78,16 @@ use std::time::{Duration, Instant}; use bevy_app::prelude::*; use glam::DVec2; use valence_client::{Client, FlushPacketsSet}; -use valence_core::protocol::encode::WritePacket; use valence_core::protocol::var_int::VarInt; use valence_core::protocol::var_long::VarLong; use valence_entity::Location; use valence_instance::{Instance, WriteUpdatePacketsToInstancesSet}; -use valence_packet::world_border::*; +use valence_packet::packets::play::{ + WorldBorderCenterChangedS2c, WorldBorderInitializeS2c, WorldBorderInterpolateSizeS2c, + WorldBorderSizeChangedS2c, WorldBorderWarningBlocksChangedS2c, + WorldBorderWarningTimeChangedS2c, +}; +use valence_packet::protocol::encode::WritePacket; use valence_registry::*; // https://minecraft.fandom.com/wiki/World_border diff --git a/examples/boss_bar.rs b/examples/boss_bar.rs index 9b26eb3f1..ac73c457a 100644 --- a/examples/boss_bar.rs +++ b/examples/boss_bar.rs @@ -1,8 +1,10 @@ use rand::seq::SliceRandom; use valence::prelude::*; -use valence_boss_bar::{BossBar, BossBarBundle, BossBarViewers}; +use valence_boss_bar::{ + BossBarBundle, BossBarColor, BossBarDivision, BossBarFlags, BossBarHealth, BossBarStyle, + BossBarTitle, BossBarViewers, +}; use valence_client::message::{ChatMessageEvent, SendMessage}; -use valence_core::boss_bar::{BossBarColor, BossBarDivision, BossBarFlags}; const SPAWN_Y: i32 = 64; @@ -39,7 +41,6 @@ fn setup( commands.spawn(BossBarBundle::new( Text::text("Boss bar"), - 1.0, BossBarColor::Blue, BossBarDivision::TenNotches, BossBarFlags::new(), @@ -94,9 +95,6 @@ fn init_clients( client.send_chat_message( "Type any number between 0 and 1 to set the health".on_click_suggest_command("health"), ); - client.send_chat_message( - "Type 'random' to set random values".on_click_suggest_command("random"), - ); boss_bar_viewers.viewers.insert(entity); } @@ -104,9 +102,21 @@ fn init_clients( fn listen_messages( mut message_events: EventReader, - mut boss_bar: Query<(&mut BossBarViewers, &mut BossBar)>, + mut boss_bar: Query<( + &mut BossBarViewers, + &mut BossBarStyle, + &mut BossBarFlags, + &mut BossBarHealth, + &mut BossBarTitle, + )>, ) { - let (mut boss_bar_viewers, mut boss_bar) = boss_bar.single_mut(); + let ( + mut boss_bar_viewers, + mut boss_bar_style, + mut boss_bar_flags, + mut boss_bar_health, + mut boss_bar_title, + ) = boss_bar.single_mut(); let events: Vec = message_events.iter().cloned().collect(); for ChatMessageEvent { @@ -129,11 +139,11 @@ fn listen_messages( BossBarColor::Green, BossBarColor::Yellow, ]; - colors.retain(|c| *c != boss_bar.color); + colors.retain(|c| *c != boss_bar_style.color); let random_color = colors.choose(&mut rand::thread_rng()).unwrap(); - boss_bar.update_style(Some(*random_color), None); + boss_bar_style.color = *random_color; } "division" => { let mut divisions = vec![ @@ -143,78 +153,30 @@ fn listen_messages( BossBarDivision::TwelveNotches, BossBarDivision::TwentyNotches, ]; - divisions.retain(|d| *d != boss_bar.division); + divisions.retain(|d| *d != boss_bar_style.division); let random_division = divisions.choose(&mut rand::thread_rng()).unwrap(); - boss_bar.update_style(None, Some(*random_division)); + boss_bar_style.division = *random_division; } "flags" => { let darken_sky: bool = rand::random(); let dragon_bar: bool = rand::random(); let create_fog: bool = rand::random(); - boss_bar.update_flags( - BossBarFlags::new() - .with_create_fog(create_fog) - .with_darken_sky(darken_sky) - .with_dragon_bar(dragon_bar), - ); - } - "random" => { - let mut colors = vec![ - BossBarColor::Pink, - BossBarColor::Blue, - BossBarColor::Red, - BossBarColor::Green, - BossBarColor::Yellow, - ]; - colors.retain(|c| *c != boss_bar.color); - - let random_color = colors.choose(&mut rand::thread_rng()).unwrap(); - - let mut divisions = vec![ - BossBarDivision::NoDivision, - BossBarDivision::SixNotches, - BossBarDivision::TenNotches, - BossBarDivision::TwelveNotches, - BossBarDivision::TwentyNotches, - ]; - divisions.retain(|d| *d != boss_bar.division); - - let random_division = divisions.choose(&mut rand::thread_rng()).unwrap(); - - let darken_sky: bool = rand::random(); - let dragon_bar: bool = rand::random(); - let create_fog: bool = rand::random(); - - boss_bar.update_style(Some(*random_color), Some(*random_division)); - boss_bar.update_flags( - BossBarFlags::new() - .with_create_fog(create_fog) - .with_darken_sky(darken_sky) - .with_dragon_bar(dragon_bar), - ); - boss_bar.update_title(randomize_string("Random boss bar").into()); - - let random_health = rand::random::(); - boss_bar.update_health(random_health); + boss_bar_flags.set_darken_sky(darken_sky); + boss_bar_flags.set_dragon_bar(dragon_bar); + boss_bar_flags.set_create_fog(create_fog); } _ => { if let Ok(health) = message.parse::() { if (0.0..=1.0).contains(&health) { - boss_bar.update_health(health); + boss_bar_health.0 = health; } } else { - boss_bar.update_title(message.to_string().into()); + boss_bar_title.0 = message.to_string().into(); } } }; } } - -fn randomize_string(s: &str) -> String { - let mut chars: Vec = s.chars().collect(); - chars.shuffle(&mut rand::thread_rng()); - chars.into_iter().collect() -} diff --git a/examples/resource_pack.rs b/examples/resource_pack.rs index 8d3512d53..b4614460b 100644 --- a/examples/resource_pack.rs +++ b/examples/resource_pack.rs @@ -4,7 +4,8 @@ use valence::entity::player::PlayerEntityBundle; use valence::entity::sheep::SheepEntityBundle; use valence::prelude::*; use valence_client::message::SendMessage; -use valence_client::resource_pack::{ResourcePackStatus, ResourcePackStatusEvent}; +use valence_client::resource_pack::ResourcePackStatusEvent; +use valence_packet::packets::play::ResourcePackStatusC2s; const SPAWN_Y: i32 = 64; @@ -96,16 +97,16 @@ fn on_resource_pack_status( for event in events.iter() { if let Ok(mut client) = clients.get_mut(event.client) { match event.status { - ResourcePackStatus::Accepted => { + ResourcePackStatusC2s::Accepted => { client.send_chat_message("Resource pack accepted.".color(Color::GREEN)); } - ResourcePackStatus::Declined => { + ResourcePackStatusC2s::Declined => { client.send_chat_message("Resource pack declined.".color(Color::RED)); } - ResourcePackStatus::FailedDownload => { + ResourcePackStatusC2s::FailedDownload => { client.send_chat_message("Resource pack failed to download.".color(Color::RED)); } - ResourcePackStatus::SuccessfullyLoaded => { + ResourcePackStatusC2s::SuccessfullyLoaded => { client.send_chat_message( "Resource pack successfully downloaded.".color(Color::BLUE), ); diff --git a/src/lib.rs b/src/lib.rs index f0a297bf0..6e92f2824 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -99,7 +99,6 @@ pub mod prelude { pub use valence_core::hand::Hand; pub use valence_core::ident; // Export the `ident!` macro. pub use valence_core::item::{ItemKind, ItemStack}; - pub use valence_core::particle::Particle; pub use valence_core::text::{Color, IntoText, Text}; pub use valence_core::uuid::UniqueId; pub use valence_core::{translation_key, CoreSettings, Server}; @@ -121,6 +120,7 @@ pub mod prelude { ConnectionMode, ErasedNetworkCallbacks, NetworkCallbacks, NetworkSettings, NewClientInfo, SharedNetworkState, }; + pub use valence_packet::packets::play::particle_s2c::Particle; #[cfg(feature = "player_list")] pub use valence_player_list::{PlayerList, PlayerListEntry}; diff --git a/src/testing.rs b/src/testing.rs index fe8507f34..93b2c8ea9 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -9,15 +9,16 @@ use bytes::{Buf, BufMut, BytesMut}; use uuid::Uuid; use valence_biome::BiomeRegistry; use valence_client::keepalive::KeepaliveSettings; -use valence_client::teleport::{PlayerPositionLookS2c, TeleportConfirmC2s}; use valence_client::ClientBundleArgs; -use valence_core::protocol::decode::{PacketDecoder, PacketFrame}; -use valence_core::protocol::encode::PacketEncoder; use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{Decode, Encode, Packet}; +use valence_core::protocol::{Decode, Encode}; use valence_core::{ident, CoreSettings, Server}; use valence_dimension::DimensionTypeRegistry; use valence_network::NetworkPlugin; +use valence_packet::packets::play::{PlayerPositionLookS2c, TeleportConfirmC2s}; +use valence_packet::protocol::decode::{PacketDecoder, PacketFrame}; +use valence_packet::protocol::encode::PacketEncoder; +use valence_packet::protocol::Packet; use crate::client::{ClientBundle, ClientConnection, ReceivedPacket}; use crate::instance::Instance; diff --git a/src/tests/boss_bar.rs b/src/tests/boss_bar.rs index 2023fa9d7..a09a32460 100644 --- a/src/tests/boss_bar.rs +++ b/src/tests/boss_bar.rs @@ -1,10 +1,12 @@ use bevy_app::App; use bevy_ecs::entity::Entity; -use valence_boss_bar::{BossBar, BossBarBundle, BossBarViewers}; -use valence_core::boss_bar::{BossBarColor, BossBarDivision, BossBarFlags}; +use valence_boss_bar::{ + BossBarBundle, BossBarColor, BossBarDivision, BossBarFlags, BossBarHealth, BossBarStyle, + BossBarTitle, BossBarViewers, +}; use valence_core::despawn::Despawned; use valence_core::text::Text; -use valence_packet::boss_bar::BossBarS2c; +use valence_packet::packets::play::BossBarS2c; use crate::testing::{scenario_single_client, MockClientHelper}; @@ -53,17 +55,17 @@ fn test_title_update() { let mut app = App::new(); let (client_ent, mut client_helper, instance_ent) = prepare(&mut app); - // Fetch the boss bar viewers component - let mut boss_bar_viewers = app.world.get_mut::(instance_ent).unwrap(); + // Fetch the boss bar component + let mut boss_bar = app.world.get_mut::(instance_ent).unwrap(); // Add our mock client to the viewers list - assert!(boss_bar_viewers.viewers.insert(client_ent)); + assert!(boss_bar.viewers.insert(client_ent)); app.update(); - // Update the bossbar component - let mut boss_bar = app.world.get_mut::(instance_ent).unwrap(); - - boss_bar.update_title(Text::text("New title")); + // Update the title + app.world + .entity_mut(instance_ent) + .insert(BossBarTitle(Text::text("Test 2"))); app.update(); @@ -85,10 +87,10 @@ fn test_health_update() { app.update(); - // Update the bossbar component - let mut boss_bar = app.world.get_mut::(instance_ent).unwrap(); - - boss_bar.update_health(0.5); + // Update the health + app.world + .entity_mut(instance_ent) + .insert(BossBarHealth(0.5)); app.update(); @@ -105,16 +107,16 @@ fn test_style_update() { // Fetch the boss bar component let mut boss_bar = app.world.get_mut::(instance_ent).unwrap(); - // Add our mock client to the viewers list assert!(boss_bar.viewers.insert(client_ent)); app.update(); - // Update the bossbar component - let mut boss_bar = app.world.get_mut::(instance_ent).unwrap(); - - boss_bar.update_style(Some(BossBarColor::Red), Some(BossBarDivision::TenNotches)); + // Update the style + app.world.entity_mut(instance_ent).insert(BossBarStyle { + color: BossBarColor::Red, + division: BossBarDivision::TenNotches, + }); app.update(); @@ -136,10 +138,10 @@ fn test_flags_update() { app.update(); - // Update the bossbar component - let mut boss_bar = app.world.get_mut::(instance_ent).unwrap(); - - boss_bar.update_flags(BossBarFlags::new().with_create_fog(true)); + // Update the flags + let mut new_flags = BossBarFlags::new(); + new_flags.set_create_fog(true); + app.world.entity_mut(instance_ent).insert(new_flags); app.update(); @@ -190,8 +192,7 @@ fn prepare(app: &mut App) -> (Entity, MockClientHelper, Entity) { let boss_bar = app .world .spawn(BossBarBundle::new( - Text::text("Test boss bar"), - 1.0, + Text::text("Test"), BossBarColor::Blue, BossBarDivision::SixNotches, BossBarFlags::new(), diff --git a/src/tests/client.rs b/src/tests/client.rs index 57a5a52bb..d3b55b351 100644 --- a/src/tests/client.rs +++ b/src/tests/client.rs @@ -4,17 +4,17 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use bevy_ecs::world::EntityMut; use glam::DVec3; -use valence_client::movement::FullC2s; -use valence_client::teleport::{PlayerPositionLookS2c, TeleportConfirmC2s}; use valence_client::ViewDistance; use valence_core::chunk_pos::{ChunkPos, ChunkView}; -use valence_core::protocol::Packet; use valence_entity::cow::CowEntityBundle; use valence_entity::{Location, Position}; use valence_instance::chunk::UnloadedChunk; use valence_instance::Instance; -use valence_packet::entity::{EntitiesDestroyS2c, EntitySpawnS2c, MoveRelativeS2c}; -use valence_packet::instance::{ChunkDataS2c, UnloadChunkS2c}; +use valence_packet::packets::play::{ + ChunkDataS2c, EntitiesDestroyS2c, EntitySpawnS2c, FullC2s, MoveRelativeS2c, + PlayerPositionLookS2c, TeleportConfirmC2s, UnloadChunkS2c, +}; +use valence_packet::protocol::Packet; use crate::testing::{create_mock_client, scenario_single_client}; diff --git a/src/tests/example.rs b/src/tests/example.rs index d4f603258..3def3b723 100644 --- a/src/tests/example.rs +++ b/src/tests/example.rs @@ -7,12 +7,11 @@ use bevy_app::App; use glam::DVec3; -use valence_client::movement::PositionAndOnGroundC2s; use valence_client::Client; use valence_core::Server; use valence_entity::Position; use valence_inventory::{Inventory, InventoryKind, OpenInventory}; -use valence_packet::inventory::{InventoryS2c, OpenScreenS2c}; +use valence_packet::packets::play::{InventoryS2c, OpenScreenS2c, PositionAndOnGroundC2s}; use crate::testing::scenario_single_client; use crate::DefaultPlugins; diff --git a/src/tests/instance.rs b/src/tests/instance.rs index 87fe4cb33..832792c2a 100644 --- a/src/tests/instance.rs +++ b/src/tests/instance.rs @@ -3,7 +3,7 @@ use bevy_ecs::prelude::*; use valence_block::BlockState; use valence_instance::chunk::UnloadedChunk; use valence_instance::Instance; -use valence_packet::instance::{BlockEntityUpdateS2c, ChunkDeltaUpdateS2c}; +use valence_packet::packets::play::{BlockEntityUpdateS2c, ChunkDeltaUpdateS2c}; use crate::testing::scenario_single_client; diff --git a/src/tests/inventory.rs b/src/tests/inventory.rs index 97f5b0853..66dba834b 100644 --- a/src/tests/inventory.rs +++ b/src/tests/inventory.rs @@ -4,12 +4,12 @@ use valence_core::game_mode::GameMode; use valence_core::item::{ItemKind, ItemStack}; use valence_core::protocol::var_int::VarInt; use valence_inventory::{ - convert_to_player_slot_id, ClientInventoryState, CursorItem, DropItemStackEvent, HeldItem, - Inventory, InventoryKind, OpenInventory, + convert_to_player_slot_id, ClickMode, ClientInventoryState, CursorItem, DropItemStackEvent, + HeldItem, Inventory, InventoryKind, OpenInventory, SlotChange, }; -use valence_packet::inventory::{ - ClickMode, ClickSlotC2s, CloseScreenS2c, CreativeInventoryActionC2s, InventoryS2c, - OpenScreenS2c, ScreenHandlerSlotUpdateS2c, SlotChange, UpdateSelectedSlotC2s, +use valence_packet::packets::play::{ + ClickSlotC2s, CloseScreenS2c, CreativeInventoryActionC2s, InventoryS2c, OpenScreenS2c, + ScreenHandlerSlotUpdateS2c, UpdateSelectedSlotC2s, }; use crate::testing::scenario_single_client; @@ -519,8 +519,8 @@ fn should_not_increment_state_id_on_cursor_item_change() { mod dropping_items { use valence_core::block_pos::BlockPos; use valence_core::direction::Direction; - use valence_inventory::convert_to_player_slot_id; - use valence_packet::client::{PlayerAction, PlayerActionC2s}; + use valence_inventory::{convert_to_player_slot_id, PlayerAction}; + use valence_packet::packets::play::PlayerActionC2s; use super::*; diff --git a/src/tests/player_list.rs b/src/tests/player_list.rs index 6b1fb7862..de5067fe0 100644 --- a/src/tests/player_list.rs +++ b/src/tests/player_list.rs @@ -2,8 +2,7 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use valence_instance::chunk::UnloadedChunk; use valence_instance::Instance; -use valence_packet::client::PlayerSpawnS2c; -use valence_packet::player_list::PlayerListS2c; +use valence_packet::packets::play::{PlayerListS2c, PlayerSpawnS2c}; use crate::testing::{create_mock_client, scenario_single_client}; diff --git a/src/tests/weather.rs b/src/tests/weather.rs index 67dc149da..9ff8c952d 100644 --- a/src/tests/weather.rs +++ b/src/tests/weather.rs @@ -2,7 +2,7 @@ use bevy_app::App; use valence_client::weather::{Rain, Thunder}; use valence_client::Client; use valence_instance::Instance; -use valence_packet::client::GameStateChangeS2c; +use valence_packet::packets::play::GameStateChangeS2c; use crate::testing::{scenario_single_client, PacketFrames}; diff --git a/src/tests/world_border.rs b/src/tests/world_border.rs index 9df1a5e86..11ce0d545 100644 --- a/src/tests/world_border.rs +++ b/src/tests/world_border.rs @@ -3,7 +3,10 @@ use std::time::Duration; use bevy_app::App; use valence_entity::Location; use valence_instance::Instance; -use valence_packet::world_border::*; +use valence_packet::packets::play::{ + WorldBorderCenterChangedS2c, WorldBorderInitializeS2c, WorldBorderSizeChangedS2c, + WorldBorderWarningBlocksChangedS2c, WorldBorderWarningTimeChangedS2c, +}; use valence_registry::{Entity, Mut}; use valence_world_border::*; diff --git a/tools/packet_inspector/src/app/text_viewer.rs b/tools/packet_inspector/src/app/text_viewer.rs index 9a4f275aa..987c114bc 100644 --- a/tools/packet_inspector/src/app/text_viewer.rs +++ b/tools/packet_inspector/src/app/text_viewer.rs @@ -1,42 +1,13 @@ use super::{SharedState, Tab, View}; mod utils { - use packet_inspector::Packet as ProxyPacket; - use packet_inspector::{PacketSide, PacketState}; - use valence::protocol::{Decode, Packet}; - - use valence::packet::advancement::*; - use valence::packet::boss_bar::*; - use valence::client::action::*; - use valence::client::command::*; - use valence::client::custom_payload::*; - use valence::client::hand_swing::*; - use valence::client::interact_block::*; - use valence::client::interact_entity::*; - use valence::client::interact_item::*; - use valence::client::keepalive::*; - use valence::client::movement::*; - use valence::packet::client::structure_block::*; - use valence::packet::client::*; - use valence::client::resource_pack::*; - use valence::client::settings::*; - use valence::client::status::*; - use valence::client::teleport::*; - use valence::client::title::*; - use valence::packet::entity::*; - use valence::packet::instance::*; - use valence::packet::inventory::synchronize_recipes::*; - use valence::packet::inventory::*; - use valence::packet::network::*; - use valence::particle::*; - use valence::packet::player_list::*; - use valence::packet::chat::*; - use valence::packet::command::*; - use valence::packet::map::*; - use valence::packet::scoreboard::*; - use valence::packet::sound::*; - use valence::registry::tags::*; - use valence::packet::world_border::*; + use packet_inspector::{Packet as ProxyPacket, PacketSide, PacketState}; + use valence::packet::packets::play::*; + use valence::packet::packets::status::*; + use valence::packet::packets::login::*; + use valence::packet::packets::handshaking::*; + use valence::packet::protocol::Packet; + use valence::protocol::Decode; include!(concat!(env!("OUT_DIR"), "/packet_to_string.rs")); } diff --git a/tools/packet_inspector/src/lib.rs b/tools/packet_inspector/src/lib.rs index d1b74fb92..697f12cec 100644 --- a/tools/packet_inspector/src/lib.rs +++ b/tools/packet_inspector/src/lib.rs @@ -7,11 +7,12 @@ use std::sync::{Arc, OnceLock}; pub use packet_registry::Packet; use tokio::net::TcpStream; use tokio::sync::RwLock; -use valence::packet::network::{ - HandshakeC2s, HandshakeNextState, LoginCompressionS2c, LoginSuccessS2c, -}; -use valence::protocol::decode::PacketFrame; -use valence::protocol::{Decode, Packet as ValencePacket}; +use valence::packet::packets::handshaking::handshake_c2s::HandshakeNextState; +use valence::packet::packets::handshaking::HandshakeC2s; +use valence::packet::packets::login::{LoginCompressionS2c, LoginSuccessS2c}; +use valence::packet::protocol::decode::PacketFrame; +use valence::packet::protocol::Packet as ValencePacket; +use valence::protocol::Decode; use crate::packet_io::PacketIo; use crate::packet_registry::PacketRegistry; diff --git a/tools/packet_inspector/src/packet_io.rs b/tools/packet_inspector/src/packet_io.rs index 61923ebe2..c1a847f35 100644 --- a/tools/packet_inspector/src/packet_io.rs +++ b/tools/packet_inspector/src/packet_io.rs @@ -6,8 +6,8 @@ use bytes::{BufMut, BytesMut}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::TcpStream; use valence::__private::VarInt; -use valence::protocol::decode::{PacketDecoder, PacketFrame}; -use valence::protocol::encode::PacketEncoder; +use valence::packet::protocol::decode::{PacketDecoder, PacketFrame}; +use valence::packet::protocol::encode::PacketEncoder; use valence::protocol::{Encode, MAX_PACKET_SIZE}; pub(crate) struct PacketIoReader { diff --git a/tools/packet_inspector/src/packet_registry.rs b/tools/packet_inspector/src/packet_registry.rs index bcf33ac51..4e8d7f18e 100644 --- a/tools/packet_inspector/src/packet_registry.rs +++ b/tools/packet_inspector/src/packet_registry.rs @@ -3,7 +3,7 @@ use std::sync::RwLock; use bytes::Bytes; use time::OffsetDateTime; -use valence::protocol::decode::PacketFrame; +use valence::packet::protocol::decode::PacketFrame; pub struct PacketRegistry { packets: RwLock>, diff --git a/tools/stresser/src/stresser.rs b/tools/stresser/src/stresser.rs index f414f347c..06b672dff 100644 --- a/tools/stresser/src/stresser.rs +++ b/tools/stresser/src/stresser.rs @@ -5,18 +5,19 @@ use anyhow::bail; use tokio::io::AsyncWriteExt; use tokio::net::TcpStream; use uuid::Uuid; -use valence_client::keepalive::{KeepAliveC2s, KeepAliveS2c}; -use valence_client::movement::PositionAndOnGroundC2s; -use valence_client::teleport::{PlayerPositionLookS2c, TeleportConfirmC2s}; -use valence_core::protocol::decode::PacketDecoder; -use valence_core::protocol::encode::PacketEncoder; use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::Packet; use valence_core::PROTOCOL_VERSION; -use valence_packet::network::{ - HandshakeC2s, HandshakeNextState, LoginCompressionS2c, LoginHelloC2s, LoginHelloS2c, - LoginSuccessS2c, +use valence_packet::packets::handshaking::handshake_c2s::HandshakeNextState; +use valence_packet::packets::handshaking::HandshakeC2s; +use valence_packet::packets::login::{ + LoginCompressionS2c, LoginHelloC2s, LoginHelloS2c, LoginSuccessS2c, }; +use valence_packet::packets::play::{ + KeepAliveC2s, KeepAliveS2c, PlayerPositionLookS2c, PositionAndOnGroundC2s, TeleportConfirmC2s, +}; +use valence_packet::protocol::decode::PacketDecoder; +use valence_packet::protocol::encode::PacketEncoder; +use valence_packet::protocol::Packet; pub struct SessionParams<'a> { pub socket_addr: SocketAddr, From c5ca16bb8fb4e0af7b9994104c9b0ffd985fc961 Mon Sep 17 00:00:00 2001 From: Bafbi Date: Wed, 2 Aug 2023 15:37:51 +0200 Subject: [PATCH 9/9] repare `valence_advancement` + check pass --- crates/valence_advancement/src/lib.rs | 6 +-- crates/valence_entity/src/lib.rs | 6 +-- .../packets/play/advancement_update_s2c.rs | 45 ++++++++++--------- 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/crates/valence_advancement/src/lib.rs b/crates/valence_advancement/src/lib.rs index cc30f53c0..dc2254d2e 100644 --- a/crates/valence_advancement/src/lib.rs +++ b/crates/valence_advancement/src/lib.rs @@ -21,9 +21,7 @@ use valence_core::protocol::raw::RawBytes; use valence_core::protocol::var_int::VarInt; use valence_core::protocol::Encode; use valence_core::text::Text; -use valence_packet::packets::play::{ - advancement_update_s2c as packet, AdvancementUpdateS2c, SelectAdvancementTabS2c, -}; +use valence_packet::packets::play::{advancement_update_s2c as packet, SelectAdvancementTabS2c}; use valence_packet::protocol::encode::WritePacket; use valence_packet::protocol::{packet_id, Packet, PacketSide, PacketState}; @@ -224,7 +222,7 @@ impl<'w, 's, 'a> Encode for AdvancementUpdateEncodeS2c<'w, 's, 'a> { reset, } = &self.client_update; - let mut pkt = AdvancementUpdateS2c { + let mut pkt = packet::GenericAdvancementUpdateS2c { reset: *reset, advancement_mapping: vec![], identifiers: vec![], diff --git a/crates/valence_entity/src/lib.rs b/crates/valence_entity/src/lib.rs index 243d16bb1..9549f19fc 100644 --- a/crates/valence_entity/src/lib.rs +++ b/crates/valence_entity/src/lib.rs @@ -413,7 +413,7 @@ pub struct PacketByteRange(pub Range); /// Cache for all the tracked data of an entity. Used for the /// [`EntityTrackerUpdateS2c`][packet] packet. /// -/// [packet]: valence_packet::entity::EntityTrackerUpdateS2c +/// [packet]: valence_packet::packets::play::EntityTrackerUpdateS2c #[derive(Component, Default, Debug)] pub struct TrackedData { init_data: Vec, @@ -428,7 +428,7 @@ impl TrackedData { /// [`EntityTrackerUpdateS2c`][packet] packet. This is used when the entity /// enters the view of a client. /// - /// [packet]: valence_packet::entity::EntityTrackerUpdateS2c + /// [packet]: valence_packet::packets::play::EntityTrackerUpdateS2c pub fn init_data(&self) -> Option<&[u8]> { if self.init_data.len() > 1 { Some(&self.init_data) @@ -441,7 +441,7 @@ impl TrackedData { /// [`EntityTrackerUpdateS2c`][packet] packet. This is used when tracked /// data is changed and the client is already in view of the entity. /// - /// [packet]: valence_packet::entity::EntityTrackerUpdateS2c + /// [packet]: valence_packet::packets::play::EntityTrackerUpdateS2c pub fn update_data(&self) -> Option<&[u8]> { if self.update_data.len() > 1 { Some(&self.update_data) diff --git a/crates/valence_packet/src/packets/play/advancement_update_s2c.rs b/crates/valence_packet/src/packets/play/advancement_update_s2c.rs index 35bad7098..4010fa30d 100644 --- a/crates/valence_packet/src/packets/play/advancement_update_s2c.rs +++ b/crates/valence_packet/src/packets/play/advancement_update_s2c.rs @@ -1,20 +1,29 @@ use super::*; +pub type AdvancementUpdateS2c<'a> = + GenericAdvancementUpdateS2c<'a, (Ident>, Advancement<'a, Option>)>; + #[derive(Clone, Debug, Encode, Decode, Packet)] #[packet(id = packet_id::ADVANCEMENT_UPDATE_S2C)] -pub struct AdvancementUpdateS2c<'a> { +pub struct GenericAdvancementUpdateS2c<'a, AM: 'a> { pub reset: bool, - pub advancement_mapping: Vec<(Ident>, Advancement<'a, Option>)>, + pub advancement_mapping: Vec, pub identifiers: Vec>>, pub progress_mapping: Vec<(Ident>, Vec>)>, } +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct Advancement<'a, I> { + pub parent_id: Option>>, + pub display_data: Option>, + pub criteria: Vec<(Ident>, ())>, + pub requirements: Vec>, + pub sends_telemetry_data: bool, +} + #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub struct AdvancementCriteria<'a> { - pub criterion_identifier: Ident>, - /// If present, the criteria has been achieved at the - /// time wrapped; time represented as millis since epoch - pub criterion_progress: Option, +pub struct AdvancementRequirements<'a> { + pub requirement: Vec<&'a str>, } #[derive(Clone, PartialEq, Debug)] @@ -29,6 +38,14 @@ pub struct AdvancementDisplay<'a, I> { pub y_coord: f32, } +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub struct AdvancementCriteria<'a> { + pub criterion_identifier: Ident>, + /// If present, the criteria has been achieved at the + /// time wrapped; time represented as millis since epoch + pub criterion_progress: Option, +} + impl Encode for AdvancementDisplay<'_, I> { fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { self.title.encode(&mut w)?; @@ -78,17 +95,3 @@ impl<'a, I: Decode<'a>> Decode<'a> for AdvancementDisplay<'a, I> { }) } } - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct Advancement<'a, I> { - pub parent_id: Option>>, - pub display_data: Option>, - pub criteria: Vec<(Ident>, ())>, - pub requirements: Vec>, - pub sends_telemetry_data: bool, -} - -#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub struct AdvancementRequirements<'a> { - pub requirement: Vec<&'a str>, -}