diff --git a/Cargo.toml b/Cargo.toml index 72de59782..375bcacd0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,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 valence_weather = { workspace = true, optional = true } [dev-dependencies] @@ -170,6 +171,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" @@ -181,6 +183,7 @@ 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_weather.path = "crates/valence_weather" valence.path = "." zip = "0.6.3" diff --git a/benches/many_players.rs b/benches/many_players.rs index 45c363953..44c93fe59 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_layer::chunk::UnloadedChunk; use valence_layer::LayerBundle; use valence_network::NetworkPlugin; +use valence_packet::packets::play::{FullC2s, HandSwingC2s}; pub fn many_players(c: &mut Criterion) { run_many_players(c, "many_players", 3000, 16, 16); diff --git a/benches/packet.rs b/benches/packet.rs index 5945c4492..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_entity::packet::EntitySpawnS2c; -use valence_layer::packet::ChunkDataS2c; -use valence_player_list::packet::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..8a4aa901c 100644 --- a/crates/valence_advancement/src/event.rs +++ b/crates/valence_advancement/src/event.rs @@ -1,8 +1,7 @@ use bevy_ecs::prelude::*; use valence_client::event_loop::PacketEvent; use valence_core::ident::Ident; - -use crate::packet::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_advancement/src/lib.rs b/crates/valence_advancement/src/lib.rs index 755b07487..dc2254d2e 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,16 +13,17 @@ 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 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::packets::play::{advancement_update_s2c as packet, SelectAdvancementTabS2c}; +use valence_packet::protocol::encode::WritePacket; +use valence_packet::protocol::{packet_id, Packet, PacketSide, PacketState}; pub struct AdvancementPlugin; @@ -54,8 +54,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), ), ); } 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/components.rs b/crates/valence_boss_bar/src/components.rs index 385b62925..e69de29bb 100644 --- a/crates/valence_boss_bar/src/components.rs +++ b/crates/valence_boss_bar/src/components.rs @@ -1,80 +0,0 @@ -use std::collections::BTreeSet; - -use bevy_ecs::prelude::{Bundle, Component, Entity}; -use bitfield_struct::bitfield; -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, Default)] -pub struct BossBarBundle { - pub id: UniqueId, - pub title: BossBarTitle, - pub health: BossBarHealth, - pub style: BossBarStyle, - pub flags: BossBarFlags, - pub viewers: BossBarViewers, -} - -/// The title of a boss bar. -#[derive(Component, Clone, Default)] -pub struct BossBarTitle(pub Text); - -/// The health of a boss bar. -#[derive(Component, Default)] -pub struct BossBarHealth(pub f32); - -/// The style of a boss bar. This includes the color and division of the boss -/// bar. -#[derive(Component, Default)] -pub struct BossBarStyle { - pub color: BossBarColor, - pub division: BossBarDivision, -} - -/// The color of a boss bar. -#[derive(Component, Copy, Clone, PartialEq, Eq, Default, Debug, Encode, Decode)] -pub enum BossBarColor { - #[default] - Pink, - Blue, - Red, - Green, - Yellow, - Purple, - White, -} - -/// The division of a boss bar. -#[derive(Component, Copy, Clone, PartialEq, Eq, Default, Debug, Encode, Decode)] -pub enum BossBarDivision { - #[default] - NoDivision, - SixNotches, - TenNotches, - TwelveNotches, - TwentyNotches, -} - -/// The flags of a boss bar (darken sky, dragon bar, create fog). -#[bitfield(u8)] -#[derive(Component, PartialEq, Eq, Default, Encode, Decode)] -pub struct BossBarFlags { - pub darken_sky: bool, - pub dragon_bar: bool, - pub create_fog: bool, - #[bits(5)] - _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 d1fd642f0..e93c02fe7 100644 --- a/crates/valence_boss_bar/src/lib.rs +++ b/crates/valence_boss_bar/src/lib.rs @@ -19,19 +19,75 @@ )] 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::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; -mod components; -pub use components::*; +/// The bundle of components that make up a boss bar. +#[derive(Bundle, Debug, Default)] +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(), + } + } +} -pub mod packet; +/// The title of a boss bar. +#[derive(Component, Clone, Debug, Default)] +pub struct BossBarTitle(pub Text); + +/// The health of a boss bar. +#[derive(Component, Debug, Default)] +pub struct BossBarHealth(pub f32); + +/// The style of a boss bar. This includes the color and division of the boss +/// bar. +#[derive(Component, Debug, Default)] +pub struct BossBarStyle { + pub color: BossBarColor, + pub division: BossBarDivision, +} + +/// The viewers of a boss bar. +#[derive(Component, Default, Debug)] +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, +} pub struct BossBarPlugin; 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_client/Cargo.toml b/crates/valence_client/Cargo.toml index bc0ec0d18..942d57ea8 100644 --- a/crates/valence_client/Cargo.toml +++ b/crates/valence_client/Cargo.toml @@ -19,6 +19,7 @@ valence_biome.workspace = true valence_core.workspace = true valence_dimension.workspace = true valence_entity.workspace = true +valence_packet.workspace = true valence_layer.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..05f36fe1d 100644 --- a/crates/valence_client/src/action.rs +++ b/crates/valence_client/src/action.rs @@ -1,11 +1,11 @@ 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::packets::play::player_action_c2s::PlayerAction; +use valence_packet::packets::play::{PlayerActionC2s, PlayerActionResponseS2c}; use super::*; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; -use crate::packet::{PlayerAction, PlayerActionC2s}; pub(super) fn build(app: &mut App) { app.add_event::() @@ -99,9 +99,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..8f67d905a 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}; +pub 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..5f35ad7d4 100644 --- a/crates/valence_client/src/custom_payload.rs +++ b/crates/valence_client/src/custom_payload.rs @@ -1,5 +1,4 @@ -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 +38,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..f9bf8fe5e 100644 --- a/crates/valence_client/src/interact_block.rs +++ b/crates/valence_client/src/interact_block.rs @@ -4,8 +4,7 @@ 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_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 +56,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..c6025843b 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; +pub 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 2eaf96d7f..284160bc0 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::{KeepAliveC2s, KeepAliveS2c}; 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 70762026f..b0b730acd 100644 --- a/crates/valence_client/src/lib.rs +++ b/crates/valence_client/src/lib.rs @@ -32,10 +32,6 @@ use bevy_ecs::system::Command; use byteorder::{NativeEndian, ReadBytesExt}; use bytes::{Bytes, BytesMut}; use glam::{DVec3, Vec3}; -use packet::{ - DeathMessageS2c, DisconnectS2c, GameEventKind, GameJoinS2c, GameStateChangeS2c, - PlayerRespawnS2c, PlayerSpawnPositionS2c, -}; use tracing::warn; use uuid::Uuid; use valence_biome::BiomeRegistry; @@ -44,18 +40,13 @@ 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::{PacketEncoder, WritePacket}; use valence_core::protocol::global_pos::GlobalPos; -use valence_core::protocol::packet::sound::{PlaySoundS2c, Sound, SoundCategory}; use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{Encode, Packet}; +use valence_core::protocol::Encode; +use valence_core::sound::{Sound, SoundCategory}; use valence_core::text::{IntoText, Text}; use valence_core::uuid::UniqueId; -use valence_entity::packet::{ - EntitiesDestroyS2c, EntityStatusS2c, EntityTrackerUpdateS2c, EntityVelocityUpdateS2c, -}; use valence_entity::player::PlayerEntityBundle; use valence_entity::query::EntityInitQuery; use valence_entity::tracked_data::TrackedData; @@ -63,11 +54,18 @@ use valence_entity::{ ClearEntityChangesSet, EntityId, EntityLayerId, EntityStatus, Look, OldPosition, Position, Velocity, }; -use valence_layer::packet::{ - ChunkBiome, ChunkBiomeDataS2c, ChunkLoadDistanceS2c, ChunkRenderDistanceCenterS2c, - UnloadChunkS2c, -}; use valence_layer::{ChunkLayer, EntityLayer, UpdateLayersPostClientSet, UpdateLayersPreClientSet}; +use valence_packet::packets::play::chunk_biome_data_s2c::ChunkBiome; +use valence_packet::packets::play::game_state_change_s2c::GameEventKind; +use valence_packet::packets::play::particle_s2c::Particle; +use valence_packet::packets::play::{ + ChunkBiomeDataS2c, ChunkLoadDistanceS2c, ChunkRenderDistanceCenterS2c, DeathMessageS2c, + DisconnectS2c, EntitiesDestroyS2c, EntityStatusS2c, EntityTrackerUpdateS2c, + EntityVelocityUpdateS2c, GameJoinS2c, GameStateChangeS2c, ParticleS2c, PlaySoundS2c, + PlayerRespawnS2c, PlayerSpawnPositionS2c, UnloadChunkS2c, +}; +use valence_packet::protocol::encode::{PacketEncoder, WritePacket}; +use valence_packet::protocol::Packet; use valence_registry::RegistrySet; pub mod action; @@ -82,7 +80,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 spawn; diff --git a/crates/valence_client/src/message.rs b/crates/valence_client/src/message.rs index c7b91ff69..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_core::protocol::encode::WritePacket; -use valence_core::protocol::packet::chat::{ChatMessageC2s, GameMessageS2c}; 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 76ddd2060..2cf34b73e 100644 --- a/crates/valence_client/src/movement.rs +++ b/crates/valence_client/src/movement.rs @@ -1,8 +1,10 @@ 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::{ + FullC2s, LookAndOnGroundC2s, OnGroundOnlyC2s, PositionAndOnGroundC2s, VehicleMoveC2s, +}; use super::teleport::TeleportState; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; @@ -201,41 +203,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 7cf0ed5b4..5426961f1 100644 --- a/crates/valence_client/src/op_level.rs +++ b/crates/valence_client/src/op_level.rs @@ -1,5 +1,3 @@ -use valence_entity::packet::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/packet.rs b/crates/valence_client/src/packet.rs deleted file mode 100644 index ee97e4b42..000000000 --- a/crates/valence_client/src/packet.rs +++ /dev/null @@ -1,457 +0,0 @@ -//! 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::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; - -#[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, -} - -#[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_client/src/resource_pack.rs b/crates/valence_client/src/resource_pack.rs index aeaee9bae..9d3edec94 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::{ResourcePackSendS2c, ResourcePackStatusC2s}; +use super::*; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; -use crate::Client; 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..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 bitfield_struct::bitfield; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; use valence_entity::player::{self, PlayerModelParts}; +use valence_packet::packets::play::client_settings_c2s::ChatMode; +use valence_packet::packets::play::ClientSettingsC2s; 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 81bf54cf6..dd8b6ae49 100644 --- a/crates/valence_client/src/teleport.rs +++ b/crates/valence_client/src/teleport.rs @@ -1,7 +1,6 @@ -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::player_position_look_s2c::PlayerPositionLookFlags; +use valence_packet::packets::play::{PlayerPositionLookS2c, TeleportConfirmC2s}; use super::*; use crate::event_loop::{EventLoopPreUpdate, PacketEvent}; @@ -129,31 +128,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..f6b1fe2c8 100644 --- a/crates/valence_client/src/title.rs +++ b/crates/valence_client/src/title.rs @@ -1,5 +1,7 @@ -use valence_core::protocol::{packet_id, Decode, Encode}; use valence_core::text::IntoText; +use valence_packet::packets::play::{ + ClearTitleS2c, OverlayMessageS2c, SubtitleS2c, TitleFadeS2c, TitleS2c, +}; use super::*; @@ -61,35 +63,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_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 1ba0106ac..aa1f59eea 100644 --- a/crates/valence_core/src/lib.rs +++ b/crates/valence_core/src/lib.rs @@ -28,11 +28,11 @@ 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; pub mod scratch; +pub mod sound; pub mod text; pub mod translation_key; pub mod uuid; @@ -52,7 +52,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/protocol.rs b/crates/valence_core/src/protocol.rs index a1e27f3f2..3b15c8e67 100644 --- a/crates/valence_core/src/protocol.rs +++ b/crates/valence_core/src/protocol.rs @@ -2,20 +2,15 @@ pub mod array; pub mod byte_angle; -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; 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; @@ -160,214 +155,3 @@ pub trait Decode<'a>: Sized { /// 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"); - } -} 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..91733d742 --- /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, +} diff --git a/crates/valence_core_macros/src/lib.rs b/crates/valence_core_macros/src/lib.rs index 1c7f59905..82de02d63 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()) { 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/build.rs b/crates/valence_entity/build.rs index 950d34840..4d018771d 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_entity/src/lib.rs b/crates/valence_entity/src/lib.rs index 475d7bd54..ad25c8a44 100644 --- a/crates/valence_entity/src/lib.rs +++ b/crates/valence_entity/src/lib.rs @@ -21,7 +21,6 @@ mod flags; pub mod hitbox; pub mod manager; -pub mod packet; pub mod query; pub mod tracked_data; diff --git a/crates/valence_entity/src/packet.rs b/crates/valence_entity/src/packet.rs deleted file mode 100644 index 71c59745b..000000000 --- a/crates/valence_entity/src/packet.rs +++ /dev/null @@ -1,300 +0,0 @@ -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; - -#[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, -} - -#[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(Copy, Clone, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_SPAWN_S2C)] -pub struct PlayerSpawnS2c { - 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::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], -} - -#[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, - 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_entity/src/query.rs b/crates/valence_entity/src/query.rs index f31c77016..dd3cd2262 100644 --- a/crates/valence_entity/src/query.rs +++ b/crates/valence_entity/src/query.rs @@ -5,15 +5,15 @@ use bevy_ecs::query::WorldQuery; use bevy_ecs::world::Ref; use glam::DVec3; use valence_core::protocol::byte_angle::ByteAngle; -use valence_core::protocol::encode::WritePacket; use valence_core::protocol::var_int::VarInt; use valence_core::uuid::UniqueId; - -use crate::packet::{ +use valence_packet::packets::play::{ EntityAnimationS2c, EntityPositionS2c, EntitySetHeadYawS2c, EntitySpawnS2c, EntityStatusS2c, EntityTrackerUpdateS2c, EntityVelocityUpdateS2c, ExperienceOrbSpawnS2c, MoveRelativeS2c, PlayerSpawnS2c, RotateAndMoveRelativeS2c, RotateS2c, }; +use valence_packet::protocol::encode::WritePacket; + use crate::tracked_data::TrackedData; use crate::{ EntityAnimations, EntityId, EntityKind, EntityLayerId, EntityStatuses, HeadYaw, Look, diff --git a/crates/valence_entity/src/tracked_data.rs b/crates/valence_entity/src/tracked_data.rs index a81a040c6..a8a38d5a2 100644 --- a/crates/valence_entity/src/tracked_data.rs +++ b/crates/valence_entity/src/tracked_data.rs @@ -5,7 +5,7 @@ use valence_core::protocol::Encode; /// Cache for all the tracked data of an entity. Used for the /// [`EntityTrackerUpdateS2c`][packet] packet. /// -/// [packet]: crate::packet::EntityTrackerUpdateS2c +/// [packet]: valence_packet::packets::play::EntityTrackerUpdateS2c #[derive(Component, Default, Debug)] pub struct TrackedData { init_data: Vec, @@ -20,7 +20,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::packets::play::EntityTrackerUpdateS2c pub fn init_data(&self) -> Option<&[u8]> { if self.init_data.len() > 1 { Some(&self.init_data) @@ -33,7 +33,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::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_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 37fbce870..ec969eec7 100644 --- a/crates/valence_inventory/src/lib.rs +++ b/crates/valence_inventory/src/lib.rs @@ -25,22 +25,22 @@ use std::ops::Range; use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use packet::{ - 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_client::{Client, FlushPacketsSet, SpawnClientsSet}; use valence_core::game_mode::GameMode; use valence_core::item::{ItemKind, ItemStack}; -use valence_core::protocol::encode::WritePacket; use valence_core::protocol::var_int::VarInt; use valence_core::text::{IntoText, Text}; +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; -pub mod packet; mod validate; pub struct InventoryPlugin; @@ -1222,7 +1222,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( @@ -1233,7 +1233,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/packet.rs b/crates/valence_inventory/src/packet.rs deleted file mode 100644 index 56f80b4b3..000000000 --- a/crates/valence_inventory/src/packet.rs +++ /dev/null @@ -1,786 +0,0 @@ -//! 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; - -#[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_inventory/src/validate.rs b/crates/valence_inventory/src/validate.rs index d07f17b26..ba1af7b4e 100644 --- a/crates/valence_inventory/src/validate.rs +++ b/crates/valence_inventory/src/validate.rs @@ -1,8 +1,9 @@ use anyhow::{bail, ensure}; use valence_core::item::ItemStack; +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}; -use crate::packet::{ClickMode, ClickSlotC2s}; /// Validates a click slot packet enforcing that all fields are valid. pub(super) fn validate_click_slot_packet( @@ -359,9 +360,9 @@ fn calculate_net_item_delta( mod tests { use valence_core::item::{ItemKind, ItemStack}; use valence_core::protocol::var_int::VarInt; + use valence_packet::packets::play::click_slot_c2s::SlotChange; use super::*; - use crate::packet::SlotChange; use crate::InventoryKind; #[test] diff --git a/crates/valence_layer/Cargo.toml b/crates/valence_layer/Cargo.toml index f7fae352a..14f134da9 100644 --- a/crates/valence_layer/Cargo.toml +++ b/crates/valence_layer/Cargo.toml @@ -20,4 +20,5 @@ valence_dimension.workspace = true valence_entity.workspace = true valence_nbt.workspace = true valence_registry.workspace = true +valence_packet.workspace = true tracing.workspace = true diff --git a/crates/valence_layer/src/chunk.rs b/crates/valence_layer/src/chunk.rs index f389c606f..ea7ad59bf 100644 --- a/crates/valence_layer/src/chunk.rs +++ b/crates/valence_layer/src/chunk.rs @@ -16,13 +16,15 @@ use valence_biome::{BiomeId, 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::encode::{PacketWriter, WritePacket}; -use valence_core::protocol::packet::sound::{PlaySoundS2c, Sound, SoundCategory}; -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::packets::play::particle_s2c::Particle; +use valence_packet::packets::play::{ParticleS2c, PlaySoundS2c}; +use valence_packet::protocol::encode::{PacketWriter, WritePacket}; +use valence_packet::protocol::Packet; pub use self::chunk::{MAX_HEIGHT, *}; pub use self::loaded::LoadedChunk; diff --git a/crates/valence_layer/src/chunk/loaded.rs b/crates/valence_layer/src/chunk/loaded.rs index 5e1720dba..68e0cad3f 100644 --- a/crates/valence_layer/src/chunk/loaded.rs +++ b/crates/valence_layer/src/chunk/loaded.rs @@ -8,11 +8,15 @@ use valence_biome::BiomeId; use valence_block::BlockState; use valence_core::block_pos::BlockPos; use valence_core::chunk_pos::ChunkPos; -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; use valence_nbt::{compound, Compound}; +use valence_packet::packets::play::chunk_data_s2c::ChunkDataBlockEntity; +use valence_packet::packets::play::{ + BlockEntityUpdateS2c, BlockUpdateS2c, ChunkDataS2c, ChunkDeltaUpdateS2c, +}; +use valence_packet::protocol::encode::{PacketWriter, WritePacket}; use valence_registry::RegistryIdx; use super::chunk::{ @@ -22,9 +26,6 @@ use super::chunk::{ use super::paletted_container::PalettedContainer; use super::unloaded::{self, UnloadedChunk}; use super::{ChunkLayerInfo, ChunkLayerMessages, LocalMsg}; -use crate::packet::{ - BlockEntityUpdateS2c, BlockUpdateS2c, ChunkDataBlockEntity, ChunkDataS2c, ChunkDeltaUpdateS2c, -}; #[derive(Debug)] pub struct LoadedChunk { diff --git a/crates/valence_layer/src/entity.rs b/crates/valence_layer/src/entity.rs index 56d926ab4..35b18f0be 100644 --- a/crates/valence_layer/src/entity.rs +++ b/crates/valence_layer/src/entity.rs @@ -8,11 +8,12 @@ use rustc_hash::FxHashMap; 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::{Encode, Packet}; +use valence_core::protocol::Encode; use valence_core::Server; use valence_entity::query::UpdateEntityQuery; use valence_entity::{EntityId, EntityLayerId, OldEntityLayerId, OldPosition, Position}; +use valence_packet::protocol::encode::{PacketWriter, WritePacket}; +use valence_packet::protocol::Packet; use crate::bvh::GetChunkPos; use crate::message::Messages; diff --git a/crates/valence_layer/src/lib.rs b/crates/valence_layer/src/lib.rs index 4f00aa9e5..52fba6ff6 100644 --- a/crates/valence_layer/src/lib.rs +++ b/crates/valence_layer/src/lib.rs @@ -22,7 +22,6 @@ pub mod bvh; pub mod chunk; pub mod entity; pub mod message; -pub mod packet; use std::marker::PhantomData; @@ -34,10 +33,10 @@ use valence_biome::BiomeRegistry; use valence_core::block_pos::BlockPos; use valence_core::chunk_pos::ChunkPos; use valence_core::ident::Ident; -use valence_core::protocol::encode::WritePacket; use valence_core::Server; use valence_dimension::DimensionTypeRegistry; use valence_entity::{InitEntitiesSet, UpdateTrackedDataSet}; +use valence_packet::protocol::encode::WritePacket; // Plugin is generic over the client type for hacky reasons. pub struct LayerPlugin(PhantomData); diff --git a/crates/valence_layer/src/packet.rs b/crates/valence_layer/src/packet.rs deleted file mode 100644 index 650b2e891..000000000 --- a/crates/valence_layer/src/packet.rs +++ /dev/null @@ -1,145 +0,0 @@ -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; - -#[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_network/Cargo.toml b/crates/valence_network/Cargo.toml index 7263c9927..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 @@ -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..ce1e68f38 100644 --- a/crates/valence_network/src/connect.rs +++ b/crates/valence_network/src/connect.rs @@ -19,20 +19,19 @@ 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::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::{ - HandshakeC2s, HandshakeNextState, LoginCompressionS2c, LoginDisconnectS2c, LoginHelloC2s, - LoginHelloS2c, LoginKeyC2s, LoginQueryRequestS2c, LoginQueryResponseC2s, LoginSuccessS2c, - QueryPingC2s, QueryPongS2c, QueryRequestC2s, QueryResponseS2c, -}; use crate::packet_io::PacketIo; use crate::{CleanupOnDrop, ConnectionMode, NewClientInfo, ServerListPing, SharedNetworkState}; 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_network/src/packet.rs b/crates/valence_network/src/packet.rs deleted file mode 100644 index bc43a2067..000000000 --- a/crates/valence_network/src/packet.rs +++ /dev/null @@ -1,105 +0,0 @@ -use std::borrow::Cow; - -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; - -#[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_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 new file mode 100644 index 000000000..f00dc53ac --- /dev/null +++ b/crates/valence_packet/Cargo.toml @@ -0,0 +1,38 @@ +[package] +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 +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"] } +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 + +[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_packet/README.md b/crates/valence_packet/README.md new file mode 100644 index 000000000..c4c1c616f --- /dev/null +++ b/crates/valence_packet/README.md @@ -0,0 +1,7 @@ +# 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_core/build/packet_id.rs b/crates/valence_packet/build.rs similarity index 68% rename from crates/valence_core/build/packet_id.rs rename to crates/valence_packet/build.rs index bcbd6f6b1..9edf33f51 100644 --- a/crates/valence_core/build/packet_id.rs +++ b/crates/valence_packet/build.rs @@ -2,7 +2,7 @@ use heck::ToShoutySnakeCase; use proc_macro2::TokenStream; use quote::quote; use serde::Deserialize; -use valence_build_utils::ident; +use valence_build_utils::{ident, rerun_if_changed, write_generated_file}; #[derive(Deserialize)] struct Packet { @@ -12,9 +12,16 @@ 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"))?; + 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 new file mode 100644 index 000000000..666794a87 --- /dev/null +++ b/crates/valence_packet/src/lib.rs @@ -0,0 +1,10 @@ +pub mod packets; +pub mod protocol; + +/// Used only by macros. Not public API. +#[doc(hidden)] +pub mod __private { + pub use crate::protocol::Packet; +} + +extern crate self as valence_packet; diff --git a/crates/valence_packet/src/packets.rs b/crates/valence_packet/src/packets.rs new file mode 100644 index 000000000..5f5befbd9 --- /dev/null +++ b/crates/valence_packet/src/packets.rs @@ -0,0 +1,18 @@ +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::{Decode, Encode}; +use valence_core::text::Text; + +use crate::protocol::{packet_id, Packet, PacketState}; + +pub mod handshaking; +pub mod login; +pub mod play; +pub mod status; diff --git a/crates/valence_packet/src/packets/handshaking.rs b/crates/valence_packet/src/packets/handshaking.rs new file mode 100644 index 000000000..b8508cf65 --- /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; 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/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 new file mode 100644 index 000000000..781a38026 --- /dev/null +++ b/crates/valence_packet/src/packets/login/login_compression_s2c.rs @@ -0,0 +1,7 @@ +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/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_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_advancement/src/packet.rs b/crates/valence_packet/src/packets/play/advancement_update_s2c.rs similarity index 81% rename from crates/valence_advancement/src/packet.rs rename to crates/valence_packet/src/packets/play/advancement_update_s2c.rs index e782e49a9..4010fa30d 100644 --- a/crates/valence_advancement/src/packet.rs +++ b/crates/valence_packet/src/packets/play/advancement_update_s2c.rs @@ -1,11 +1,4 @@ -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>)>; @@ -102,16 +95,3 @@ impl<'a, I: Decode<'a>> Decode<'a> for AdvancementDisplay<'a, I> { }) } } - -#[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/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..50012e1fe --- /dev/null +++ b/crates/valence_packet/src/packets/play/boss_bar_s2c.rs @@ -0,0 +1,61 @@ +use bevy_ecs::prelude::Component; + +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), +} + +/// The color of a boss bar. +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode, Component, Default)] +pub enum BossBarColor { + #[default] + Pink, + Blue, + Red, + Green, + Yellow, + Purple, + White, +} + +/// The division of a boss bar. +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode, Component, Default)] +pub enum BossBarDivision { + #[default] + NoDivision, + SixNotches, + TenNotches, + TwelveNotches, + TwentyNotches, +} + +/// The flags of a boss bar (darken sky, dragon bar, create fog). +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode, Component, Default)] +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_s2c.rs b/crates/valence_packet/src/packets/play/bundle_splitter_s2c.rs new file mode 100644 index 000000000..0d8f301ba --- /dev/null +++ b/crates/valence_packet/src/packets/play/bundle_splitter_s2c.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_c2s.rs b/crates/valence_packet/src/packets/play/full_c2s.rs new file mode 100644 index 000000000..561fc0f81 --- /dev/null +++ b/crates/valence_packet/src/packets/play/full_c2s.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_c2s.rs b/crates/valence_packet/src/packets/play/look_and_on_ground_c2s.rs new file mode 100644 index 000000000..6cf2fd28e --- /dev/null +++ b/crates/valence_packet/src/packets/play/look_and_on_ground_c2s.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/move_relative_s2c.rs b/crates/valence_packet/src/packets/play/move_relative_s2c.rs new file mode 100644 index 000000000..d69831461 --- /dev/null +++ b/crates/valence_packet/src/packets/play/move_relative_s2c.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_c2s.rs b/crates/valence_packet/src/packets/play/on_ground_only_c2s.rs new file mode 100644 index 000000000..d2b2cc184 --- /dev/null +++ b/crates/valence_packet/src/packets/play/on_ground_only_c2s.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_core/src/particle.rs b/crates/valence_packet/src/packets/play/particle_s2c.rs similarity index 98% rename from crates/valence_core/src/particle.rs rename to crates/valence_packet/src/packets/play/particle_s2c.rs index a07adde63..79db86674 100644 --- a/crates/valence_core/src/particle.rs +++ b/crates/valence_packet/src/packets/play/particle_s2c.rs @@ -1,13 +1,50 @@ -use std::borrow::Cow; -use std::io::Write; +use glam::Vec3; -use anyhow::bail; -use glam::{DVec3, Vec3}; +use super::*; -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, 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 { @@ -356,50 +393,6 @@ impl Particle { } } -#[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<()> { 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_player_list/src/packet.rs b/crates/valence_packet/src/packets/play/player_list_s2c.rs similarity index 83% rename from crates/valence_player_list/src/packet.rs rename to crates/valence_packet/src/packets/play/player_list_s2c.rs index b842b5cbe..c028c93bb 100644 --- a/crates/valence_player_list/src/packet.rs +++ b/crates/valence_packet/src/packets/play/player_list_s2c.rs @@ -1,20 +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; - -#[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>, -} +use super::*; #[derive(Clone, Debug, Packet)] #[packet(id = packet_id::PLAYER_LIST_S2C)] @@ -23,39 +7,6 @@ pub struct PlayerListS2c<'a> { pub entries: Cow<'a, [PlayerListEntry<'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 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], -} - impl<'a> Encode for PlayerListS2c<'a> { fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { self.actions.0.encode(&mut w)?; @@ -143,8 +94,35 @@ impl<'a> Decode<'a> for PlayerListS2c<'a> { } } -#[derive(Clone, PartialEq, Debug, Encode, Decode, Packet)] -#[packet(id = packet_id::PLAYER_REMOVE_S2C)] -pub struct PlayerRemoveS2c<'a> { - pub uuids: Cow<'a, [Uuid]>, +#[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_c2s.rs b/crates/valence_packet/src/packets/play/position_and_on_ground_c2s.rs new file mode 100644 index 000000000..50fb1b73e --- /dev/null +++ b/crates/valence_packet/src/packets/play/position_and_on_ground_c2s.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_and_move_relative_s2c.rs b/crates/valence_packet/src/packets/play/rotate_and_move_relative_s2c.rs new file mode 100644 index 000000000..83d064cfa --- /dev/null +++ b/crates/valence_packet/src/packets/play/rotate_and_move_relative_s2c.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/rotate_s2c.rs b/crates/valence_packet/src/packets/play/rotate_s2c.rs new file mode 100644 index 000000000..8e59af07b --- /dev/null +++ b/crates/valence_packet/src/packets/play/rotate_s2c.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/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..37c49426b --- /dev/null +++ b/crates/valence_packet/src/packets/play/synchronize_tags_s2c.rs @@ -0,0 +1,21 @@ +use serde::Deserialize; + +use super::*; + +#[derive(Clone, Debug, Encode, Decode, Packet)] +#[packet(id = packet_id::SYNCHRONIZE_TAGS_S2C)] +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_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..45cae93e3 --- /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 duration_millis: 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..53de86092 --- /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 duration_millis: 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.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/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, +} diff --git a/crates/valence_packet/src/protocol.rs b/crates/valence_packet/src/protocol.rs new file mode 100644 index 000000000..bee997831 --- /dev/null +++ b/crates/valence_packet/src/protocol.rs @@ -0,0 +1,220 @@ +pub mod decode; +pub mod encode; + +use std::io::Write; + +use anyhow::Context; +use valence_core::protocol::var_int::VarInt; +use valence_core::protocol::*; +pub use valence_packet_macros::Packet; + +/// 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..bbdcec8cb 100644 --- a/crates/valence_core/src/protocol/decode.rs +++ b/crates/valence_packet/src/protocol/decode.rs @@ -4,8 +4,8 @@ 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 super::Decode; use crate::protocol::var_int::{VarInt, VarIntDecodeError}; use crate::protocol::{Packet, MAX_PACKET_SIZE}; 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_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..d55edec1b --- /dev/null +++ b/crates/valence_packet_macros/src/lib.rs @@ -0,0 +1,40 @@ +#![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_player_list/Cargo.toml b/crates/valence_player_list/Cargo.toml index baf933fb1..d08cc184e 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_layer.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 f5eeb558b..445ef7c1a 100644 --- a/crates/valence_player_list/src/lib.rs +++ b/crates/valence_player_list/src/lib.rs @@ -18,29 +18,26 @@ )] #![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; 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_layer::UpdateLayersPreClientSet; - -use crate::packet::PlayerRemoveS2c; +use valence_packet::packets::play::{ + player_list_s2c as packet, PlayerListHeaderS2c, PlayerListS2c, PlayerRemoveS2c, +}; +use valence_packet::protocol::encode::{PacketWriter, WritePacket}; pub struct PlayerListPlugin; #[derive(SystemSet, Copy, Clone, PartialEq, Eq, Hash, Debug)] - struct PlayerListSet; impl Plugin for PlayerListPlugin { @@ -209,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) @@ -314,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. 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..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_core::protocol::encode::{PacketWriter, WritePacket}; -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; 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; @@ -17,30 +15,12 @@ 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, 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 { diff --git a/crates/valence_weather/Cargo.toml b/crates/valence_weather/Cargo.toml index 274b06cda..0022c6f42 100644 --- a/crates/valence_weather/Cargo.toml +++ b/crates/valence_weather/Cargo.toml @@ -10,5 +10,6 @@ license.workspace = true valence_client.workspace = true valence_layer.workspace = true valence_core.workspace = true +valence_packet.workspace = true bevy_ecs.workspace = true bevy_app.workspace = true \ No newline at end of file diff --git a/crates/valence_weather/src/lib.rs b/crates/valence_weather/src/lib.rs index 7c340706f..73e898fc4 100644 --- a/crates/valence_weather/src/lib.rs +++ b/crates/valence_weather/src/lib.rs @@ -20,10 +20,11 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use valence_client::packet::{GameEventKind, GameStateChangeS2c}; use valence_client::{Client, FlushPacketsSet, UpdateClientsSet, VisibleChunkLayer}; -use valence_core::protocol::encode::WritePacket; use valence_layer::ChunkLayer; +use valence_packet::packets::play::game_state_change_s2c::GameEventKind; +use valence_packet::packets::play::GameStateChangeS2c; +use valence_packet::protocol::encode::WritePacket; pub struct WeatherPlugin; diff --git a/crates/valence_world_border/Cargo.toml b/crates/valence_world_border/Cargo.toml index 6179212a9..8a3ce4782 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_layer.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 06bd914c8..37facf585 100644 --- a/crates/valence_world_border/src/lib.rs +++ b/crates/valence_world_border/src/lib.rs @@ -18,14 +18,16 @@ clippy::dbg_macro )] -pub mod packet; - use bevy_app::prelude::*; -use packet::*; use valence_client::{Client, UpdateClientsSet, VisibleChunkLayer}; -use valence_core::protocol::encode::WritePacket; use valence_core::CoreSettings; use valence_layer::ChunkLayer; +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/crates/valence_world_border/src/packet.rs b/crates/valence_world_border/src/packet.rs deleted file mode 100644 index ae0b4ab88..000000000 --- a/crates/valence_world_border/src/packet.rs +++ /dev/null @@ -1,49 +0,0 @@ -use valence_core::protocol::var_int::VarInt; -use valence_core::protocol::var_long::VarLong; -use valence_core::protocol::{packet_id, Decode, Encode, Packet}; - -#[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 duration_millis: 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 duration_millis: 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/examples/parkour.rs b/examples/parkour.rs index b3e8ebfca..2878620ba 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; use valence_client::spawn::IsFlat; diff --git a/examples/resource_pack.rs b/examples/resource_pack.rs index a85519633..aa841d845 100644 --- a/examples/resource_pack.rs +++ b/examples/resource_pack.rs @@ -3,7 +3,8 @@ 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; @@ -111,16 +112,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 0e575098c..8f3f52ca3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,7 +49,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_layer as layer, valence_nbt as nbt, valence_registry as registry, + valence_layer as layer, valence_nbt as nbt, valence_packet as packet, + valence_registry as registry, }; /// Contains the most frequently used items in Valence projects. @@ -100,7 +101,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}; @@ -124,6 +124,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 f61a53dc0..0beb401cb 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -9,16 +9,17 @@ 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_layer::{ChunkLayer, EntityLayer}; 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::DefaultPlugins; diff --git a/src/tests/boss_bar.rs b/src/tests/boss_bar.rs index 5539ed179..244ca6e2e 100644 --- a/src/tests/boss_bar.rs +++ b/src/tests/boss_bar.rs @@ -1,10 +1,10 @@ -use valence_boss_bar::packet::BossBarS2c; 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::packets::play::BossBarS2c; use crate::testing::ScenarioSingleClient; diff --git a/src/tests/client.rs b/src/tests/client.rs index 84d9cef1a..1690c7b5d 100644 --- a/src/tests/client.rs +++ b/src/tests/client.rs @@ -1,10 +1,10 @@ use glam::DVec3; -use valence_client::movement::FullC2s; -use valence_client::teleport::{PlayerPositionLookS2c, TeleportConfirmC2s}; use valence_core::chunk_pos::ChunkPos; -use valence_entity::packet::MoveRelativeS2c; use valence_layer::chunk::UnloadedChunk; use valence_layer::ChunkLayer; +use valence_packet::packets::play::{ + FullC2s, MoveRelativeS2c, PlayerPositionLookS2c, TeleportConfirmC2s, +}; use crate::testing::{create_mock_client, ScenarioSingleClient}; diff --git a/src/tests/example.rs b/src/tests/example.rs index 25405cea4..ac6b33c29 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::packet::{InventoryS2c, OpenScreenS2c}; use valence_inventory::{Inventory, InventoryKind, OpenInventory}; +use valence_packet::packets::play::{InventoryS2c, OpenScreenS2c, PositionAndOnGroundC2s}; use crate::testing::ScenarioSingleClient; use crate::DefaultPlugins; diff --git a/src/tests/inventory.rs b/src/tests/inventory.rs index 34d6b41a9..4b5d91021 100644 --- a/src/tests/inventory.rs +++ b/src/tests/inventory.rs @@ -3,13 +3,13 @@ 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::{ - ClickMode, ClickSlotC2s, CloseScreenS2c, CreativeInventoryActionC2s, InventoryS2c, - OpenScreenS2c, ScreenHandlerSlotUpdateS2c, SlotChange, UpdateSelectedSlotC2s, -}; 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::packets::play::{ + ClickSlotC2s, CloseScreenS2c, CreativeInventoryActionC2s, InventoryS2c, OpenScreenS2c, + ScreenHandlerSlotUpdateS2c, UpdateSelectedSlotC2s, }; use crate::testing::ScenarioSingleClient; @@ -581,10 +581,10 @@ fn should_not_increment_state_id_on_cursor_item_change() { } mod dropping_items { - use valence_client::packet::{PlayerAction, PlayerActionC2s}; use valence_core::block_pos::BlockPos; use valence_core::direction::Direction; - use valence_inventory::convert_to_player_slot_id; + use valence_inventory::{convert_to_player_slot_id, PlayerAction}; + use valence_packet::packets::play::PlayerActionC2s; use super::*; diff --git a/src/tests/layer.rs b/src/tests/layer.rs index 5a55882ce..11ac37dba 100644 --- a/src/tests/layer.rs +++ b/src/tests/layer.rs @@ -5,16 +5,16 @@ use valence_block::BlockState; use valence_client::{ViewDistance, VisibleEntityLayers}; use valence_core::chunk_pos::ChunkView; use valence_core::despawn::Despawned; -use valence_core::protocol::Packet; use valence_core::Server; use valence_entity::cow::CowEntityBundle; -use valence_entity::packet::{EntitiesDestroyS2c, EntitySpawnS2c, MoveRelativeS2c}; use valence_entity::{EntityLayerId, Position}; use valence_layer::chunk::UnloadedChunk; -use valence_layer::packet::{ - BlockEntityUpdateS2c, ChunkDataS2c, ChunkDeltaUpdateS2c, UnloadChunkS2c, -}; use valence_layer::{ChunkLayer, EntityLayer}; +use valence_packet::packets::play::{ + BlockEntityUpdateS2c, ChunkDataS2c, ChunkDeltaUpdateS2c, EntitiesDestroyS2c, EntitySpawnS2c, + MoveRelativeS2c, UnloadChunkS2c, +}; +use valence_packet::protocol::Packet; use crate::testing::ScenarioSingleClient; diff --git a/src/tests/player_list.rs b/src/tests/player_list.rs index 650c8aad8..b58e1dd11 100644 --- a/src/tests/player_list.rs +++ b/src/tests/player_list.rs @@ -1,7 +1,6 @@ -use valence_entity::packet::PlayerSpawnS2c; use valence_layer::chunk::UnloadedChunk; use valence_layer::ChunkLayer; -use valence_player_list::packet::PlayerListS2c; +use valence_packet::packets::play::{PlayerListS2c, PlayerSpawnS2c}; use crate::testing::{create_mock_client, ScenarioSingleClient}; diff --git a/tools/packet_inspector/src/app/text_viewer.rs b/tools/packet_inspector/src/app/text_viewer.rs index ec95b18ca..987c114bc 100644 --- a/tools/packet_inspector/src/app/text_viewer.rs +++ b/tools/packet_inspector/src/app/text_viewer.rs @@ -2,39 +2,12 @@ use super::{SharedState, Tab, View}; mod utils { use packet_inspector::{Packet as ProxyPacket, PacketSide, PacketState}; - use valence::advancement::packet::*; - use valence::boss_bar::packet::*; - 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::client::packet::structure_block::*; - use valence::client::packet::*; - 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::inventory::packet::synchronize_recipes::*; - use valence::inventory::packet::*; - use valence::layer::packet::*; - use valence::network::packet::*; - 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::protocol::{Decode, Packet}; - use valence::registry::tags::*; - use valence::world_border::packet::*; + 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 7aa931cff..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::network::packet::{ - 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/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..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_network::packet::{ - 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,