diff --git a/crates/packet_inspector/src/main.rs b/crates/packet_inspector/src/main.rs index 4dbaa75..d13a221 100644 --- a/crates/packet_inspector/src/main.rs +++ b/crates/packet_inspector/src/main.rs @@ -15,15 +15,15 @@ use tokio::net::{TcpListener, TcpStream}; use tokio::sync::Semaphore; use tokio::task::JoinHandle; use tracing_subscriber::filter::LevelFilter; -use valence_protocol::packets::c2s::handshake::Handshake; -use valence_protocol::packets::c2s::login::{EncryptionResponse, LoginStart}; -use valence_protocol::packets::c2s::play::C2sPlayPacket; -use valence_protocol::packets::c2s::status::{PingRequest, StatusRequest}; -use valence_protocol::packets::s2c::login::{LoginSuccess, S2cLoginPacket}; -use valence_protocol::packets::s2c::play::S2cPlayPacket; -use valence_protocol::packets::s2c::status::{PingResponse, StatusResponse}; -use valence_protocol::types::HandshakeNextState; -use valence_protocol::{DecodePacket, EncodePacket, PacketDecoder, PacketEncoder}; +use valence_protocol::codec::{PacketDecoder, PacketEncoder}; +use valence_protocol::packet::c2s::handshake::handshake::NextState; +use valence_protocol::packet::c2s::handshake::HandshakeC2s; +use valence_protocol::packet::c2s::login::{LoginHelloC2s, LoginKeyC2s}; +use valence_protocol::packet::c2s::status::{QueryPingC2s, QueryRequestC2s}; +use valence_protocol::packet::s2c::login::LoginSuccessS2c; +use valence_protocol::packet::s2c::status::{QueryPongS2c, QueryResponseS2c}; +use valence_protocol::packet::{C2sPlayPacket, S2cLoginPacket, S2cPlayPacket}; +use valence_protocol::{DecodePacket, EncodePacket}; #[derive(Parser, Clone, Debug)] #[clap(author, version, about)] @@ -179,23 +179,23 @@ async fn handle_connection(client: TcpStream, cli: Arc) -> anyhow::Result<( style: owo_colors::Style::new().green(), }; - let handshake: Handshake = c2s.rw_packet().await?; + let handshake: HandshakeC2s = c2s.rw_packet().await?; match handshake.next_state { - HandshakeNextState::Status => { - c2s.rw_packet::().await?; - s2c.rw_packet::().await?; - c2s.rw_packet::().await?; - s2c.rw_packet::().await?; + NextState::Status => { + c2s.rw_packet::().await?; + s2c.rw_packet::().await?; + c2s.rw_packet::().await?; + s2c.rw_packet::().await?; Ok(()) } - HandshakeNextState::Login => { - c2s.rw_packet::().await?; + NextState::Login => { + c2s.rw_packet::().await?; match s2c.rw_packet::().await? { - S2cLoginPacket::EncryptionRequest(_) => { - c2s.rw_packet::().await?; + S2cLoginPacket::LoginHelloS2c(_) => { + c2s.rw_packet::().await?; eprintln!( "Encryption was enabled! Packet contents are inaccessible to the proxy. \ @@ -207,7 +207,7 @@ async fn handle_connection(client: TcpStream, cli: Arc) -> anyhow::Result<( s2c_res = passthrough(s2c.read, s2c.write) => s2c_res, }; } - S2cLoginPacket::SetCompression(pkt) => { + S2cLoginPacket::LoginCompressionS2c(pkt) => { let threshold = pkt.threshold.0 as u32; s2c.enc.set_compression(Some(threshold)); @@ -215,12 +215,12 @@ async fn handle_connection(client: TcpStream, cli: Arc) -> anyhow::Result<( c2s.enc.set_compression(Some(threshold)); c2s.dec.set_compression(true); - s2c.rw_packet::().await?; + s2c.rw_packet::().await?; } - S2cLoginPacket::LoginSuccess(_) => {} - S2cLoginPacket::DisconnectLogin(_) => return Ok(()), - S2cLoginPacket::LoginPluginRequest(_) => { - bail!("got login plugin request. Don't know how to proceed.") + S2cLoginPacket::LoginSuccessS2c(_) => {} + S2cLoginPacket::LoginDisconnectS2c(_) => return Ok(()), + S2cLoginPacket::LoginQueryRequestS2c(_) => { + bail!("got login query request. Don't know how to proceed.") } } diff --git a/crates/valence/examples/block_entities.rs b/crates/valence/examples/block_entities.rs index 1195169..3bbc6cf 100644 --- a/crates/valence/examples/block_entities.rs +++ b/crates/valence/examples/block_entities.rs @@ -1,5 +1,5 @@ use valence::client::despawn_disconnected_clients; -use valence::client::event::{default_event_handler, ChatMessage, UseItemOnBlock}; +use valence::client::event::{default_event_handler, ChatMessage, PlayerInteractBlock}; use valence::prelude::*; use valence_nbt::{compound, List}; use valence_protocol::types::Hand; @@ -75,7 +75,7 @@ fn init_clients( fn event_handler( clients: Query<&Client>, mut messages: EventReader, - mut block_interacts: EventReader, + mut block_interacts: EventReader, mut instances: Query<&mut Instance>, ) { let mut instance = instances.single_mut(); @@ -93,7 +93,7 @@ fn event_handler( nbt.insert("Text3", format!("~{}", client.username()).italic()); } - for UseItemOnBlock { + for PlayerInteractBlock { client, position, hand, diff --git a/crates/valence/examples/building.rs b/crates/valence/examples/building.rs index d62de19..e736574 100644 --- a/crates/valence/examples/building.rs +++ b/crates/valence/examples/building.rs @@ -1,6 +1,6 @@ use valence::client::despawn_disconnected_clients; use valence::client::event::{ - default_event_handler, FinishDigging, StartDigging, StartSneaking, UseItemOnBlock, + default_event_handler, PlayerInteractBlock, StartDigging, StartSneaking, StopDestroyBlock, }; use valence::prelude::*; use valence_protocol::types::Hand; @@ -93,7 +93,7 @@ fn digging_creative_mode( fn digging_survival_mode( clients: Query<&Client>, mut instances: Query<&mut Instance>, - mut events: EventReader, + mut events: EventReader, ) { let mut instance = instances.single_mut(); @@ -110,7 +110,7 @@ fn digging_survival_mode( fn place_blocks( mut clients: Query<(&Client, &mut Inventory)>, mut instances: Query<&mut Instance>, - mut events: EventReader, + mut events: EventReader, ) { let mut instance = instances.single_mut(); @@ -146,7 +146,7 @@ fn place_blocks( }; inventory.replace_slot(slot_id, slot); } - let real_pos = event.position.get_in_direction(event.face); + let real_pos = event.position.get_in_direction(event.direction); instance.set_block(real_pos, block_kind.to_state()); } } diff --git a/crates/valence/examples/chat.rs b/crates/valence/examples/chat.rs index ad01deb..45da195 100644 --- a/crates/valence/examples/chat.rs +++ b/crates/valence/examples/chat.rs @@ -1,7 +1,7 @@ use bevy_app::App; use tracing::warn; use valence::client::despawn_disconnected_clients; -use valence::client::event::{default_event_handler, ChatCommand, ChatMessage}; +use valence::client::event::{default_event_handler, ChatMessage, CommandExecution}; use valence::prelude::*; const SPAWN_Y: i32 = 64; @@ -73,7 +73,10 @@ fn handle_message_events(mut clients: Query<&mut Client>, mut messages: EventRea } } -fn handle_command_events(mut clients: Query<&mut Client>, mut commands: EventReader) { +fn handle_command_events( + mut clients: Query<&mut Client>, + mut commands: EventReader, +) { for command in commands.iter() { let Ok(mut client) = clients.get_component_mut::(command.client) else { warn!("Unable to find client for message: {:?}", command); diff --git a/crates/valence/examples/chest.rs b/crates/valence/examples/chest.rs index 2d9e79b..b194591 100644 --- a/crates/valence/examples/chest.rs +++ b/crates/valence/examples/chest.rs @@ -1,6 +1,6 @@ use tracing::warn; use valence::client::despawn_disconnected_clients; -use valence::client::event::{default_event_handler, StartSneaking, UseItemOnBlock}; +use valence::client::event::{default_event_handler, PlayerInteractBlock, StartSneaking}; use valence::prelude::*; const SPAWN_Y: i32 = 64; @@ -79,7 +79,7 @@ fn toggle_gamemode_on_sneak( fn open_chest( mut commands: Commands, inventories: Query, Without)>, - mut events: EventReader, + mut events: EventReader, ) { let Ok(inventory) = inventories.get_single() else { warn!("No inventories"); diff --git a/crates/valence/examples/combat.rs b/crates/valence/examples/combat.rs index 5af1305..ffc152e 100644 --- a/crates/valence/examples/combat.rs +++ b/crates/valence/examples/combat.rs @@ -1,7 +1,7 @@ use glam::Vec3Swizzles; use valence::client::despawn_disconnected_clients; use valence::client::event::{ - default_event_handler, InteractWithEntity, StartSprinting, StopSprinting, + default_event_handler, PlayerInteract, StartSprinting, StopSprinting, }; use valence::prelude::*; @@ -92,7 +92,7 @@ fn handle_combat_events( server: Res, mut start_sprinting: EventReader, mut stop_sprinting: EventReader, - mut interact_with_entity: EventReader, + mut interact_with_entity: EventReader, mut clients: Query<(&mut Client, &mut CombatState, &mut McEntity)>, ) { for &StartSprinting { client } in start_sprinting.iter() { @@ -107,7 +107,7 @@ fn handle_combat_events( } } - for &InteractWithEntity { + for &PlayerInteract { client: attacker_client, entity_id, .. diff --git a/crates/valence/examples/gamemode_switcher.rs b/crates/valence/examples/gamemode_switcher.rs index db3505b..8558535 100644 --- a/crates/valence/examples/gamemode_switcher.rs +++ b/crates/valence/examples/gamemode_switcher.rs @@ -1,5 +1,5 @@ use valence::client::despawn_disconnected_clients; -use valence::client::event::{default_event_handler, ChatCommand}; +use valence::client::event::{default_event_handler, CommandExecution}; use valence::prelude::*; const SPAWN_Y: i32 = 64; @@ -51,7 +51,7 @@ fn init_clients( } } -fn interpret_command(mut clients: Query<&mut Client>, mut events: EventReader) { +fn interpret_command(mut clients: Query<&mut Client>, mut events: EventReader) { for event in events.iter() { let Ok(mut client) = clients.get_component_mut::(event.client) else { continue; diff --git a/crates/valence/examples/parkour.rs b/crates/valence/examples/parkour.rs index 069c6a5..914ddf3 100644 --- a/crates/valence/examples/parkour.rs +++ b/crates/valence/examples/parkour.rs @@ -6,9 +6,9 @@ use rand::Rng; use valence::client::despawn_disconnected_clients; use valence::client::event::default_event_handler; use valence::prelude::*; -use valence_protocol::packets::s2c::play::SetTitleAnimationTimes; +use valence_protocol::packet::s2c::play::TitleFadeS2c; +use valence_protocol::sound::Sound; use valence_protocol::types::SoundCategory; -use valence_protocol::Sound; const START_POS: BlockPos = BlockPos::new(0, 100, 0); const VIEW_DIST: u8 = 10; @@ -149,7 +149,7 @@ fn manage_blocks(mut clients: Query<(&mut Client, &mut GameState, &mut Instance) client.set_title( "", state.score.to_string().color(Color::LIGHT_PURPLE).bold(), - SetTitleAnimationTimes { + TitleFadeS2c { fade_in: 0, stay: 7, fade_out: 4, diff --git a/crates/valence/examples/particles.rs b/crates/valence/examples/particles.rs index 6f9610c..2c3d7ca 100644 --- a/crates/valence/examples/particles.rs +++ b/crates/valence/examples/particles.rs @@ -1,7 +1,6 @@ use valence::client::despawn_disconnected_clients; use valence::client::event::default_event_handler; use valence::prelude::*; -use valence_protocol::packets::s2c::particle::Particle; const SPAWN_Y: i32 = 64; diff --git a/crates/valence/examples/resource_pack.rs b/crates/valence/examples/resource_pack.rs index 934c63c..94f20cb 100644 --- a/crates/valence/examples/resource_pack.rs +++ b/crates/valence/examples/resource_pack.rs @@ -1,9 +1,9 @@ use valence::client::despawn_disconnected_clients; use valence::client::event::{ - default_event_handler, InteractWithEntity, ResourcePackStatus, ResourcePackStatusChange, + default_event_handler, PlayerInteract, ResourcePackStatus, ResourcePackStatusChange, }; use valence::prelude::*; -use valence_protocol::types::EntityInteraction; +use valence_protocol::packet::c2s::play::player_interact::Interaction; const SPAWN_Y: i32 = 64; @@ -59,12 +59,12 @@ fn init_clients( } } -fn prompt_on_punch(mut clients: Query<&mut Client>, mut events: EventReader) { +fn prompt_on_punch(mut clients: Query<&mut Client>, mut events: EventReader) { for event in events.iter() { let Ok(mut client) = clients.get_mut(event.client) else { continue; }; - if event.interact == EntityInteraction::Attack { + if event.interact == Interaction::Attack { client.set_resource_pack( "https://github.com/valence-rs/valence/raw/main/assets/example_pack.zip", "d7c6108849fb190ec2a49f2d38b7f1f897d9ce9f", diff --git a/crates/valence/src/client.rs b/crates/valence/src/client.rs index 0081792..c20c5e1 100644 --- a/crates/valence/src/client.rs +++ b/crates/valence/src/client.rs @@ -9,21 +9,27 @@ use bytes::BytesMut; use glam::{DVec3, Vec3}; use tracing::warn; use uuid::Uuid; -use valence_protocol::packets::s2c::particle::Particle; -use valence_protocol::packets::s2c::play::{ - AcknowledgeBlockChange, CombatDeath, DisconnectPlay, EntityEvent, GameEvent, KeepAliveS2c, - LoginPlay, ParticleS2c, PluginMessageS2c, RemoveEntitiesEncode, ResourcePackS2c, Respawn, - SetActionBarText, SetCenterChunk, SetDefaultSpawnPosition, SetEntityMetadata, - SetEntityVelocity, SetRenderDistance, SetSubtitleText, SetTitleAnimationTimes, SetTitleText, - SoundEffect, SynchronizePlayerPosition, SystemChatMessage, UnloadChunk, -}; -use valence_protocol::types::{ - GameEventKind, GameMode, GlobalPos, Property, SoundCategory, SyncPlayerPosLookFlags, -}; -use valence_protocol::{ - BlockPos, EncodePacket, Ident, ItemStack, PacketDecoder, PacketEncoder, RawBytes, Sound, Text, - Username, VarInt, +use valence_protocol::block_pos::BlockPos; +use valence_protocol::codec::{PacketDecoder, PacketEncoder}; +use valence_protocol::ident::Ident; +use valence_protocol::item::ItemStack; +use valence_protocol::packet::s2c::play::game_state_change::GameEventKind; +use valence_protocol::packet::s2c::play::particle::Particle; +use valence_protocol::packet::s2c::play::player_position_look::Flags as PlayerPositionLookFlags; +use valence_protocol::packet::s2c::play::{ + ChunkLoadDistanceS2c, ChunkRenderDistanceCenterS2c, CustomPayloadS2c, DeathMessageS2c, + DisconnectS2c, EntitiesDestroyS2c, EntityStatusS2c, EntityTrackerUpdateS2c, + EntityVelocityUpdateS2c, GameJoinS2c, GameMessageS2c, GameStateChangeS2c, KeepAliveS2c, + OverlayMessageS2c, ParticleS2c, PlaySoundS2c, PlayerActionResponseS2c, PlayerPositionLookS2c, + PlayerRespawnS2c, PlayerSpawnPositionS2c, ResourcePackSendS2c, SubtitleS2c, TitleFadeS2c, + TitleS2c, UnloadChunkS2c, }; +use valence_protocol::sound::Sound; +use valence_protocol::text::Text; +use valence_protocol::types::{GameMode, GlobalPos, Property, SoundCategory}; +use valence_protocol::username::Username; +use valence_protocol::var_int::VarInt; +use valence_protocol::EncodePacket; use crate::dimension::DimensionId; use crate::entity::data::Player; @@ -261,7 +267,7 @@ impl Client { } pub fn set_velocity(&mut self, velocity: impl Into) { - self.enc.write_packet(&SetEntityVelocity { + self.enc.write_packet(&EntityVelocityUpdateS2c { entity_id: VarInt(0), velocity: velocity_to_packet_units(velocity.into()), }); @@ -297,7 +303,7 @@ impl Client { /// Kills the client and shows `message` on the death screen. If an entity /// killed the player, you should supply it as `killer`. pub fn kill(&mut self, killer: Option<&McEntity>, message: impl Into) { - self.write_packet(&CombatDeath { + self.write_packet(&DeathMessageS2c { player_id: VarInt(0), entity_id: killer.map_or(-1, |k| k.protocol_id()), message: message.into().into(), @@ -306,7 +312,7 @@ impl Client { /// Respawns client. Optionally can roll the credits before respawning. pub fn win_game(&mut self, show_credits: bool) { - self.write_packet(&GameEvent { + self.write_packet(&GameStateChangeS2c { kind: GameEventKind::WinGame, value: if show_credits { 1.0 } else { 0.0 }, }); @@ -322,7 +328,7 @@ impl Client { self.has_respawn_screen = enable; if !self.is_new { - self.write_packet(&GameEvent { + self.write_packet(&GameStateChangeS2c { kind: GameEventKind::EnableRespawnScreen, value: if enable { 0.0 } else { 1.0 }, }); @@ -381,7 +387,7 @@ impl Client { self.game_mode = game_mode; if !self.is_new { - self.write_packet(&GameEvent { + self.write_packet(&GameStateChangeS2c { kind: GameEventKind::ChangeGameMode, value: game_mode as i32 as f32, }); @@ -397,7 +403,7 @@ impl Client { return; } - self.write_packet(&EntityEvent { + self.write_packet(&EntityStatusS2c { entity_id: 0, entity_status: 24 + op_level, }); @@ -421,7 +427,7 @@ impl Client { } pub fn trigger_status(&mut self, status: EntityStatus) { - self.write_packet(&EntityEvent { + self.write_packet(&EntityStatusS2c { entity_id: 0, entity_status: status as u8, }); @@ -457,16 +463,16 @@ impl Client { /// Sends a system message to the player which is visible in the chat. The /// message is only visible to this client. pub fn send_message(&mut self, msg: impl Into) { - self.write_packet(&SystemChatMessage { + self.write_packet(&GameMessageS2c { chat: msg.into().into(), overlay: false, }); } pub fn send_plugin_message(&mut self, channel: Ident<&str>, data: &[u8]) { - self.write_packet(&PluginMessageS2c { + self.write_packet(&CustomPayloadS2c { channel, - data: RawBytes(data), + data: data.into(), }); } @@ -478,7 +484,7 @@ impl Client { /// Kick the client with the given reason. pub fn kick(&mut self, reason: impl Into) { - self.write_packet(&DisconnectPlay { + self.write_packet(&DisconnectS2c { reason: reason.into().into(), }); self.is_disconnected = true; @@ -501,7 +507,7 @@ impl Client { forced: bool, prompt_message: Option, ) { - self.write_packet(&ResourcePackS2c { + self.write_packet(&ResourcePackSendS2c { url, hash, forced, @@ -513,21 +519,21 @@ impl Client { /// /// A title is a large piece of text displayed in the center of the screen /// which may also include a subtitle underneath it. The title can be - /// configured to fade in and out using the [`SetTitleAnimationTimes`] + /// configured to fade in and out using the [`TitleFadeS2c`] /// struct. pub fn set_title( &mut self, title: impl Into, subtitle: impl Into, - animation: impl Into>, + animation: impl Into>, ) { let title = title.into().into(); let subtitle = subtitle.into(); - self.write_packet(&SetTitleText { title_text: title }); + self.write_packet(&TitleS2c { title_text: title }); if !subtitle.is_empty() { - self.write_packet(&SetSubtitleText { + self.write_packet(&SubtitleS2c { subtitle_text: subtitle.into(), }); } @@ -542,7 +548,7 @@ impl Client { /// The action bar is a small piece of text displayed at the bottom of the /// screen, above the hotbar. pub fn set_action_bar(&mut self, text: impl Into) { - self.write_packet(&SetActionBarText { + self.write_packet(&OverlayMessageS2c { action_bar_text: text.into().into(), }); } @@ -552,7 +558,7 @@ impl Client { /// If you want to show a particle effect to all players, use /// [`Instance::play_particle`] /// - /// [`Instance::play_particle`]: crate::instance::Instance::play_particle + /// [`Instance::play_particle`]: Instance::play_particle pub fn play_particle( &mut self, particle: &Particle, @@ -563,7 +569,7 @@ impl Client { count: i32, ) { self.write_packet(&ParticleS2c { - particle: particle.clone(), + particle: Cow::Borrowed(particle), long_distance, position: position.into().into(), offset: offset.into().into(), @@ -577,7 +583,7 @@ impl Client { /// If you want to play a sound effect to all players, use /// [`Instance::play_sound`] /// - /// [`Instance::play_sound`]: crate::instance::Instance::play_sound + /// [`Instance::play_sound`]: Instance::play_sound pub fn play_sound( &mut self, sound: Sound, @@ -588,7 +594,7 @@ impl Client { ) { let position = position.into(); - self.write_packet(&SoundEffect { + self.write_packet(&PlaySoundS2c { id: sound.to_id(), category, position: (position * 8.0).as_ivec3().into(), @@ -638,7 +644,7 @@ pub(crate) fn update_clients( &entities, &server, ) { - client.write_packet(&DisconnectPlay { + client.write_packet(&DisconnectS2c { reason: Text::from("").into(), }); client.is_disconnected = true; @@ -689,7 +695,7 @@ fn update_one_client( // The login packet is prepended so that it is sent before all the other // packets. Some packets don't work correctly when sent before the login packet, // which is why we're doing this. - client.enc.prepend_packet(&LoginPlay { + client.enc.prepend_packet(&GameJoinS2c { entity_id: 0, // ID 0 is reserved for clients. is_hardcore: client.is_hardcore, game_mode: client.game_mode, @@ -718,7 +724,7 @@ fn update_one_client( } else { if client.view_distance != client.old_view_distance { // Change the render distance fog. - client.enc.append_packet(&SetRenderDistance { + client.enc.append_packet(&ChunkLoadDistanceS2c { view_distance: VarInt(client.view_distance.into()), })?; } @@ -733,7 +739,7 @@ fn update_one_client( position: pos, }); - client.enc.append_packet(&Respawn { + client.enc.append_packet(&PlayerRespawnS2c { dimension_type_name: dimension_name, dimension_name, hashed_seed: 0, @@ -770,7 +776,7 @@ fn update_one_client( // Make sure the center chunk is set before loading chunks! if old_view.pos != view.pos { // TODO: does the client initialize the center chunk to (0, 0)? - client.enc.write_packet(&SetCenterChunk { + client.enc.write_packet(&ChunkRenderDistanceCenterS2c { chunk_x: VarInt(view.pos.x), chunk_z: VarInt(view.pos.z), }); @@ -782,7 +788,7 @@ fn update_one_client( if let Some(cell) = old_instance.partition.get(&pos) { if cell.chunk_removed && cell.chunk.is_none() { // Chunk was previously loaded and is now deleted. - client.enc.write_packet(&UnloadChunk { + client.enc.write_packet(&UnloadChunkS2c { chunk_x: pos.x, chunk_z: pos.z, }); @@ -841,7 +847,7 @@ fn update_one_client( if let Some(cell) = old_instance.partition.get(&pos) { // Unload the chunk at this cell if it was loaded. if cell.chunk.is_some() { - client.enc.write_packet(&UnloadChunk { + client.enc.write_packet(&UnloadChunkS2c { chunk_x: pos.x, chunk_z: pos.z, }); @@ -896,7 +902,7 @@ fn update_one_client( if let Some(cell) = instance.partition.get(&pos) { // Unload the chunk at this cell if it was loaded. if cell.chunk.is_some() { - client.enc.write_packet(&UnloadChunk { + client.enc.write_packet(&UnloadChunkS2c { chunk_x: pos.x, chunk_z: pos.z, }); @@ -943,8 +949,8 @@ fn update_one_client( // Despawn all the entities that are queued to be despawned. if !client.entities_to_despawn.is_empty() { - client.enc.append_packet(&RemoveEntitiesEncode { - entity_ids: &client.entities_to_despawn, + client.enc.append_packet(&EntitiesDestroyS2c { + entity_ids: Cow::Borrowed(&client.entities_to_despawn), })?; client.entities_to_despawn.clear(); @@ -953,14 +959,14 @@ fn update_one_client( // Teleport the client. Do this after chunk packets are sent so the client does // not accidentally pass through blocks. if client.position_modified || client.yaw_modified || client.pitch_modified { - let flags = SyncPlayerPosLookFlags::new() + let flags = PlayerPositionLookFlags::new() .with_x(!client.position_modified) .with_y(!client.position_modified) .with_z(!client.position_modified) .with_y_rot(!client.yaw_modified) .with_x_rot(!client.pitch_modified); - client.enc.write_packet(&SynchronizePlayerPosition { + client.enc.write_packet(&PlayerPositionLookS2c { position: if client.position_modified { client.position.to_array() } else { @@ -988,7 +994,7 @@ fn update_one_client( // This closes the "downloading terrain" screen. // Send this after the initial chunks are loaded. if client.is_new { - client.enc.write_packet(&SetDefaultSpawnPosition { + client.enc.write_packet(&PlayerSpawnPositionS2c { position: BlockPos::at(client.position), angle: client.yaw, }); @@ -1002,15 +1008,15 @@ fn update_one_client( client.scratch.push(0xff); - client.enc.write_packet(&SetEntityMetadata { + client.enc.write_packet(&EntityTrackerUpdateS2c { entity_id: VarInt(0), - metadata: RawBytes(&client.scratch), + metadata: client.scratch.as_slice().into(), }); } // Acknowledge broken/placed blocks. if client.block_change_sequence != 0 { - client.enc.write_packet(&AcknowledgeBlockChange { + client.enc.write_packet(&PlayerActionResponseS2c { sequence: VarInt(client.block_change_sequence), }); @@ -1034,8 +1040,8 @@ mod tests { use std::collections::BTreeSet; use bevy_app::App; - use valence_protocol::packets::s2c::play::ChunkDataAndUpdateLight; - use valence_protocol::packets::S2cPlayPacket; + use valence_protocol::packet::s2c::play::ChunkDataS2c; + use valence_protocol::packet::S2cPlayPacket; use super::*; use crate::instance::Chunk; @@ -1070,10 +1076,8 @@ mod tests { let mut loaded_chunks = BTreeSet::new(); for pkt in client_helper.collect_sent().unwrap() { - if let S2cPlayPacket::ChunkDataAndUpdateLight(ChunkDataAndUpdateLight { - chunk_x, - chunk_z, - .. + if let S2cPlayPacket::ChunkDataS2c(ChunkDataS2c { + chunk_x, chunk_z, .. }) = pkt { assert!( @@ -1098,17 +1102,15 @@ mod tests { for pkt in client_helper.collect_sent().unwrap() { match pkt { - S2cPlayPacket::ChunkDataAndUpdateLight(ChunkDataAndUpdateLight { - chunk_x, - chunk_z, - .. + S2cPlayPacket::ChunkDataS2c(ChunkDataS2c { + chunk_x, chunk_z, .. }) => { assert!( loaded_chunks.insert(ChunkPos::new(chunk_x, chunk_z)), "({chunk_x}, {chunk_z})" ); } - S2cPlayPacket::UnloadChunk(UnloadChunk { chunk_x, chunk_z }) => { + S2cPlayPacket::UnloadChunkS2c(UnloadChunkS2c { chunk_x, chunk_z }) => { assert!( loaded_chunks.remove(&ChunkPos::new(chunk_x, chunk_z)), "({chunk_x}, {chunk_z})" diff --git a/crates/valence/src/client/event.rs b/crates/valence/src/client/event.rs index 62d9adc..df9d9d1 100644 --- a/crates/valence/src/client/event.rs +++ b/crates/valence/src/client/event.rs @@ -8,31 +8,42 @@ use glam::{DVec3, Vec3}; use paste::paste; use tracing::warn; use uuid::Uuid; -use valence_protocol::entity_meta::Pose; -use valence_protocol::packets::c2s::play::{ - ClientCommand, PlayerAbilitiesC2s, ResourcePackC2s, SeenAdvancements, +use valence_protocol::block_pos::BlockPos; +use valence_protocol::ident::Ident; +use valence_protocol::item::ItemStack; +use valence_protocol::packet::c2s::play::click_slot::{ClickMode, Slot}; +use valence_protocol::packet::c2s::play::client_command::Action as ClientCommandAction; +use valence_protocol::packet::c2s::play::client_settings::{ + ChatMode, DisplayedSkinParts, MainHand, }; -use valence_protocol::packets::C2sPlayPacket; -use valence_protocol::types::{ - Action, ChatMode, ClickContainerMode, CommandBlockMode, Difficulty, DiggingStatus, - DisplayedSkinParts, EntityInteraction, Hand, MainHand, RecipeBookId, StructureBlockAction, - StructureBlockFlags, StructureBlockMirror, StructureBlockMode, StructureBlockRotation, +use valence_protocol::packet::c2s::play::player_action::Action as PlayerAction; +use valence_protocol::packet::c2s::play::player_interact::Interaction; +use valence_protocol::packet::c2s::play::recipe_category_options::RecipeBookId; +use valence_protocol::packet::c2s::play::update_command_block::Mode as CommandBlockMode; +use valence_protocol::packet::c2s::play::update_structure_block::{ + Action as StructureBlockAction, Flags as StructureBlockFlags, Mirror as StructureBlockMirror, + Mode as StructureBlockMode, Rotation as StructureBlockRotation, }; -use valence_protocol::{BlockFace, BlockPos, Ident, ItemStack}; +use valence_protocol::packet::c2s::play::{ + AdvancementTabC2s, ClientStatusC2s, ResourcePackStatusC2s, UpdatePlayerAbilitiesC2s, +}; +use valence_protocol::packet::C2sPlayPacket; +use valence_protocol::tracked_data::Pose; +use valence_protocol::types::{Difficulty, Direction, Hand}; use crate::client::Client; use crate::entity::{EntityAnimation, EntityKind, McEntity, TrackedData}; use crate::inventory::Inventory; #[derive(Clone, Debug)] -pub struct QueryBlockEntity { +pub struct QueryBlockNbt { pub client: Entity, pub position: BlockPos, pub transaction_id: i32, } #[derive(Clone, Debug)] -pub struct ChangeDifficulty { +pub struct UpdateDifficulty { pub client: Entity, pub difficulty: Difficulty, } @@ -44,7 +55,7 @@ pub struct MessageAcknowledgment { } #[derive(Clone, Debug)] -pub struct ChatCommand { +pub struct CommandExecution { pub client: Entity, pub command: Box, pub timestamp: u64, @@ -57,11 +68,6 @@ pub struct ChatMessage { pub timestamp: u64, } -#[derive(Clone, Debug)] -pub struct ChatPreview { - pub client: Entity, -} - #[derive(Clone, Debug)] pub struct PerformRespawn { pub client: Entity, @@ -73,7 +79,7 @@ pub struct RequestStats { } #[derive(Clone, Debug)] -pub struct UpdateSettings { +pub struct ClientSettings { pub client: Entity, /// e.g. en_US pub locale: Box, @@ -91,53 +97,53 @@ pub struct UpdateSettings { } #[derive(Clone, Debug)] -pub struct CommandSuggestionsRequest { +pub struct RequestCommandCompletions { pub client: Entity, pub transaction_id: i32, pub text: Box, } #[derive(Clone, Debug)] -pub struct ClickContainerButton { +pub struct ButtonClick { pub client: Entity, pub window_id: i8, pub button_id: i8, } #[derive(Clone, Debug)] -pub struct ClickContainer { +pub struct ClickSlot { pub client: Entity, pub window_id: u8, pub state_id: i32, pub slot_id: i16, pub button: i8, - pub mode: ClickContainerMode, - pub slot_changes: Vec<(i16, Option)>, + pub mode: ClickMode, + pub slot_changes: Vec, pub carried_item: Option, } #[derive(Clone, Debug)] -pub struct CloseContainer { +pub struct CloseHandledScreen { pub client: Entity, pub window_id: i8, } #[derive(Clone, Debug)] -pub struct PluginMessage { +pub struct CustomPayload { pub client: Entity, pub channel: Ident>, pub data: Box<[u8]>, } #[derive(Clone, Debug)] -pub struct EditBook { +pub struct BookUpdate { pub slot: i32, pub entries: Vec>, pub title: Option>, } #[derive(Clone, Debug)] -pub struct QueryEntityTag { +pub struct QueryEntityNbt { pub client: Entity, pub transaction_id: i32, pub entity_id: i32, @@ -145,18 +151,18 @@ pub struct QueryEntityTag { /// Left or right click interaction with an entity's hitbox. #[derive(Clone, Debug)] -pub struct InteractWithEntity { +pub struct PlayerInteract { pub client: Entity, /// The raw ID of the entity being interacted with. pub entity_id: i32, /// If the client was sneaking during the interaction. pub sneaking: bool, /// The kind of interaction that occurred. - pub interact: EntityInteraction, + pub interact: Interaction, } #[derive(Clone, Debug)] -pub struct JigsawGenerate { +pub struct JigsawGenerating { pub client: Entity, pub position: BlockPos, pub levels: i32, @@ -164,20 +170,13 @@ pub struct JigsawGenerate { } #[derive(Clone, Debug)] -pub struct LockDifficulty { +pub struct UpdateDifficultyLock { pub client: Entity, pub locked: bool, } #[derive(Clone, Debug)] -pub struct SetPlayerPosition { - pub client: Entity, - pub position: DVec3, - pub on_ground: bool, -} - -#[derive(Clone, Debug)] -pub struct SetPlayerPositionAndRotation { +pub struct PlayerMove { pub client: Entity, pub position: DVec3, pub yaw: f32, @@ -186,49 +185,13 @@ pub struct SetPlayerPositionAndRotation { } #[derive(Clone, Debug)] -pub struct SetPlayerRotation { - pub client: Entity, - pub yaw: f32, - pub pitch: f32, - pub on_ground: bool, -} - -#[derive(Clone, Debug)] -pub struct SetPlayerOnGround { - pub client: Entity, - pub on_ground: bool, -} - -#[derive(Clone, Debug)] -pub struct MoveVehicle { +pub struct VehicleMove { pub client: Entity, pub position: DVec3, pub yaw: f32, pub pitch: f32, } -/// Sent whenever one of the other movement events is sent. -#[derive(Clone, Debug)] -pub struct MovePlayer { - pub client: Entity, - /// The position of the client prior to the event. - pub old_position: DVec3, - /// The position of the client after the event. - pub position: DVec3, - /// The yaw of the client prior to the event. - pub old_yaw: f32, - /// The yaw of the client after the event. - pub yaw: f32, - /// The pitch of the client prior to the event. - pub old_pitch: f32, - /// The pitch of the client after the event. - pub pitch: f32, - /// If the client was on ground prior to the event. - pub old_on_ground: bool, - /// If the client is on ground after the event. - pub on_ground: bool, -} - #[derive(Clone, Debug)] pub struct StartSneaking { pub client: Entity, @@ -277,20 +240,20 @@ pub struct StartFlyingWithElytra { } #[derive(Clone, Debug)] -pub struct PaddleBoat { +pub struct BoatPaddleState { pub client: Entity, pub left_paddle_turning: bool, pub right_paddle_turning: bool, } #[derive(Clone, Debug)] -pub struct PickItem { +pub struct PickFromInventory { pub client: Entity, pub slot_to_use: i32, } #[derive(Clone, Debug)] -pub struct PlaceRecipe { +pub struct CraftRequest { pub client: Entity, pub window_id: i8, pub recipe: Ident>, @@ -311,23 +274,23 @@ pub struct StartFlying { pub struct StartDigging { pub client: Entity, pub position: BlockPos, - pub face: BlockFace, + pub direction: Direction, pub sequence: i32, } #[derive(Clone, Debug)] -pub struct CancelDigging { +pub struct AbortDestroyBlock { pub client: Entity, pub position: BlockPos, - pub face: BlockFace, + pub direction: Direction, pub sequence: i32, } #[derive(Clone, Debug)] -pub struct FinishDigging { +pub struct StopDestroyBlock { pub client: Entity, pub position: BlockPos, - pub face: BlockFace, + pub direction: Direction, pub sequence: i32, } @@ -340,12 +303,12 @@ pub struct DropItemStack { /// Eating food, pulling back bows, using buckets, etc. #[derive(Clone, Debug)] -pub struct UpdateHeldItemState { +pub struct ReleaseUseItem { pub client: Entity, } #[derive(Clone, Debug)] -pub struct SwapItemInHand { +pub struct SwapItemWithOffhand { pub client: Entity, } @@ -359,7 +322,7 @@ pub struct PlayerInput { } #[derive(Clone, Debug)] -pub struct Pong { +pub struct PlayPong { pub client: Entity, pub id: i32, } @@ -374,7 +337,7 @@ pub struct PlayerSession { } #[derive(Clone, Debug)] -pub struct ChangeRecipeBookSettings { +pub struct RecipeCategoryOptions { pub client: Entity, pub book_id: RecipeBookId, pub book_open: bool, @@ -382,7 +345,7 @@ pub struct ChangeRecipeBookSettings { } #[derive(Clone, Debug)] -pub struct SetSeenRecipe { +pub struct RecipeBookData { pub client: Entity, pub recipe_id: Ident>, } @@ -405,13 +368,13 @@ pub enum ResourcePackStatus { FailedDownload, } -impl From for ResourcePackStatus { - fn from(packet: ResourcePackC2s) -> Self { +impl From for ResourcePackStatus { + fn from(packet: ResourcePackStatusC2s) -> Self { match packet { - ResourcePackC2s::Accepted { .. } => Self::Accepted, - ResourcePackC2s::Declined { .. } => Self::Declined, - ResourcePackC2s::SuccessfullyLoaded { .. } => Self::Loaded, - ResourcePackC2s::FailedDownload { .. } => Self::FailedDownload, + ResourcePackStatusC2s::Accepted => Self::Accepted, + ResourcePackStatusC2s::Declined => Self::Declined, + ResourcePackStatusC2s::SuccessfullyLoaded => Self::Loaded, + ResourcePackStatusC2s::FailedDownload => Self::FailedDownload, } } } @@ -434,26 +397,26 @@ pub struct CloseAdvancementScreen { } #[derive(Clone, Debug)] -pub struct SelectTrade { +pub struct SelectMerchantTrade { pub client: Entity, pub slot: i32, } #[derive(Clone, Debug)] -pub struct SetBeaconEffect { +pub struct UpdateBeacon { pub client: Entity, pub primary_effect: Option, pub secondary_effect: Option, } #[derive(Clone, Debug)] -pub struct SetHeldItem { +pub struct UpdateSelectedSlot { pub client: Entity, pub slot: i16, } #[derive(Clone, Debug)] -pub struct ProgramCommandBlock { +pub struct UpdateCommandBlock { pub client: Entity, pub position: BlockPos, pub command: Box, @@ -464,7 +427,7 @@ pub struct ProgramCommandBlock { } #[derive(Clone, Debug)] -pub struct ProgramCommandBlockMinecart { +pub struct UpdateCommandBlockMinecart { pub client: Entity, pub entity_id: i32, pub command: Box, @@ -472,14 +435,14 @@ pub struct ProgramCommandBlockMinecart { } #[derive(Clone, Debug)] -pub struct SetCreativeModeSlot { +pub struct CreativeInventoryAction { pub client: Entity, pub slot: i16, pub clicked_item: Option, } #[derive(Clone, Debug)] -pub struct ProgramJigsawBlock { +pub struct UpdateJigsaw { pub client: Entity, pub position: BlockPos, pub name: Ident>, @@ -490,7 +453,7 @@ pub struct ProgramJigsawBlock { } #[derive(Clone, Debug)] -pub struct ProgramStructureBlock { +pub struct UpdateStructureBlock { pub client: Entity, pub position: BlockPos, pub action: StructureBlockAction, @@ -514,26 +477,26 @@ pub struct UpdateSign { } #[derive(Clone, Debug)] -pub struct SwingArm { +pub struct HandSwing { pub client: Entity, pub hand: Hand, } #[derive(Clone, Debug)] -pub struct TeleportToEntity { +pub struct SpectatorTeleport { pub client: Entity, pub target: Uuid, } #[derive(Clone, Debug)] -pub struct UseItemOnBlock { +pub struct PlayerInteractBlock { pub client: Entity, /// The hand that was used pub hand: Hand, /// The location of the block that was interacted with pub position: BlockPos, /// The face of the block that was clicked - pub face: BlockFace, + pub direction: Direction, /// The position inside of the block that was clicked on pub cursor_pos: Vec3, /// Whether or not the player's head is inside a block @@ -543,7 +506,7 @@ pub struct UseItemOnBlock { } #[derive(Clone, Debug)] -pub struct UseItem { +pub struct PlayerInteractItem { pub client: Entity, pub hand: Hand, pub sequence: i32, @@ -599,33 +562,28 @@ macro_rules! events { // Events are grouped to get around the 16 system parameter maximum. events! { 0 { - QueryBlockEntity - ChangeDifficulty + QueryBlockNbt + UpdateDifficulty MessageAcknowledgment - ChatCommand + CommandExecution ChatMessage - ChatPreview PerformRespawn RequestStats - UpdateSettings - CommandSuggestionsRequest - ClickContainerButton - ClickContainer - CloseContainer - PluginMessage - EditBook - QueryEntityTag + ClientSettings + RequestCommandCompletions + ButtonClick + ClickSlot + CloseHandledScreen + CustomPayload + BookUpdate + QueryEntityNbt } 1 { - InteractWithEntity - JigsawGenerate - LockDifficulty - SetPlayerPosition - SetPlayerPositionAndRotation - SetPlayerRotation - SetPlayerOnGround - MoveVehicle - MovePlayer + PlayerInteract + JigsawGenerating + UpdateDifficultyLock + PlayerMove + VehicleMove StartSneaking StopSneaking LeaveBed @@ -637,43 +595,43 @@ events! { 2 { OpenHorseInventory StartFlyingWithElytra - PaddleBoat - PickItem - PlaceRecipe + BoatPaddleState + PickFromInventory + CraftRequest StopFlying StartFlying StartDigging - CancelDigging - FinishDigging + AbortDestroyBlock + StopDestroyBlock DropItemStack - UpdateHeldItemState - SwapItemInHand + ReleaseUseItem + SwapItemWithOffhand PlayerInput - Pong + PlayPong } 3 { PlayerSession - ChangeRecipeBookSettings - SetSeenRecipe + RecipeCategoryOptions + RecipeBookData RenameItem ResourcePackStatusChange OpenAdvancementTab CloseAdvancementScreen - SelectTrade - SetBeaconEffect - SetHeldItem - ProgramCommandBlock - ProgramCommandBlockMinecart - SetCreativeModeSlot + SelectMerchantTrade + UpdateBeacon + UpdateSelectedSlot + UpdateCommandBlock + UpdateCommandBlockMinecart + CreativeInventoryAction } 4 { - ProgramJigsawBlock - ProgramStructureBlock + UpdateJigsaw + UpdateStructureBlock UpdateSign - SwingArm - TeleportToEntity - UseItemOnBlock - UseItem + HandSwing + SpectatorTeleport + PlayerInteractBlock + PlayerInteractItem } } @@ -712,7 +670,6 @@ pub(crate) fn event_loop_run_criteria( } } Err(e) => { - // TODO: validate packets in separate systems. warn!( username = %client.username, uuid = %client.uuid, @@ -735,7 +692,6 @@ pub(crate) fn event_loop_run_criteria( match handle_one_packet(&mut client, &mut inventory, entity, &mut events) { Ok(had_packet) => had_packet, Err(e) => { - // TODO: validate packets in separate systems. warn!( username = %client.username, uuid = %client.uuid, @@ -769,7 +725,7 @@ fn handle_one_packet( }; match pkt { - C2sPlayPacket::ConfirmTeleport(p) => { + C2sPlayPacket::TeleportConfirmC2s(p) => { if client.pending_teleports == 0 { bail!("unexpected teleport confirmation"); } @@ -785,17 +741,17 @@ fn handle_one_packet( bail!("unexpected teleport ID (expected {expected}, got {got}"); } } - C2sPlayPacket::QueryBlockEntityTag(p) => { - events.0.query_block_entity.send(QueryBlockEntity { + C2sPlayPacket::QueryBlockNbtC2s(p) => { + events.0.query_block_nbt.send(QueryBlockNbt { client: entity, position: p.position, transaction_id: p.transaction_id.0, }); } - C2sPlayPacket::ChangeDifficulty(p) => { - events.0.change_difficulty.send(ChangeDifficulty { + C2sPlayPacket::UpdateDifficultyC2s(p) => { + events.0.update_difficulty.send(UpdateDifficulty { client: entity, - difficulty: p.new_difficulty, + difficulty: p.difficulty, }); } C2sPlayPacket::MessageAcknowledgmentC2s(p) => { @@ -804,31 +760,31 @@ fn handle_one_packet( message_count: p.message_count.0, }); } - C2sPlayPacket::ChatCommand(p) => { - events.0.chat_command.send(ChatCommand { + C2sPlayPacket::CommandExecutionC2s(p) => { + events.0.command_execution.send(CommandExecution { client: entity, command: p.command.into(), timestamp: p.timestamp, }); } - C2sPlayPacket::ChatMessage(p) => { + C2sPlayPacket::ChatMessageC2s(p) => { events.0.chat_message.send(ChatMessage { client: entity, message: p.message.into(), timestamp: p.timestamp, }); } - C2sPlayPacket::ClientCommand(p) => match p { - ClientCommand::PerformRespawn => events + C2sPlayPacket::ClientStatusC2s(p) => match p { + ClientStatusC2s::PerformRespawn => events .0 .perform_respawn .send(PerformRespawn { client: entity }), - ClientCommand::RequestStats => { + ClientStatusC2s::RequestStats => { events.0.request_stats.send(RequestStats { client: entity }) } }, - C2sPlayPacket::ClientInformation(p) => { - events.0.update_settings.send(UpdateSettings { + C2sPlayPacket::ClientSettingsC2s(p) => { + events.0.client_settings.send(ClientSettings { client: entity, locale: p.locale.into(), view_distance: p.view_distance, @@ -840,24 +796,24 @@ fn handle_one_packet( allow_server_listings: p.allow_server_listings, }); } - C2sPlayPacket::CommandSuggestionsRequest(p) => { + C2sPlayPacket::RequestCommandCompletionsC2s(p) => { events .0 - .command_suggestions_request - .send(CommandSuggestionsRequest { + .request_command_completions + .send(RequestCommandCompletions { client: entity, transaction_id: p.transaction_id.0, text: p.text.into(), }); } - C2sPlayPacket::ClickContainerButton(p) => { - events.0.click_container_button.send(ClickContainerButton { + C2sPlayPacket::ButtonClickC2s(p) => { + events.0.button_click.send(ButtonClick { client: entity, window_id: p.window_id, button_id: p.button_id, }); } - C2sPlayPacket::ClickContainer(p) => { + C2sPlayPacket::ClickSlotC2s(p) => { if p.slot_idx < 0 { if let Some(stack) = client.cursor_item.take() { events.2.drop_item_stack.send(DropItemStack { @@ -866,7 +822,7 @@ fn handle_one_packet( stack, }); } - } else if p.mode == ClickContainerMode::DropKey { + } else if p.mode == ClickMode::DropKey { let entire_stack = p.button == 1; if let Some(stack) = inventory.slot(p.slot_idx as u16) { let dropped = if entire_stack || stack.count() == 1 { @@ -888,7 +844,7 @@ fn handle_one_packet( }); } } else { - events.0.click_container.send(ClickContainer { + events.0.click_slot.send(ClickSlot { client: entity, window_id: p.window_id, state_id: p.state_id.0, @@ -900,43 +856,43 @@ fn handle_one_packet( }); } } - C2sPlayPacket::CloseContainerC2s(p) => { - events.0.close_container.send(CloseContainer { + C2sPlayPacket::CloseHandledScreenC2s(p) => { + events.0.close_handled_screen.send(CloseHandledScreen { client: entity, window_id: p.window_id, }); } - C2sPlayPacket::PluginMessageC2s(p) => { - events.0.plugin_message.send(PluginMessage { + C2sPlayPacket::CustomPayloadC2s(p) => { + events.0.custom_payload.send(CustomPayload { client: entity, channel: p.channel.into(), data: p.data.0.into(), }); } - C2sPlayPacket::EditBook(p) => { - events.0.edit_book.send(EditBook { + C2sPlayPacket::BookUpdateC2s(p) => { + events.0.book_update.send(BookUpdate { slot: p.slot.0, entries: p.entries.into_iter().map(Into::into).collect(), title: p.title.map(Box::from), }); } - C2sPlayPacket::QueryEntityTag(p) => { - events.0.query_entity_tag.send(QueryEntityTag { + C2sPlayPacket::QueryEntityNbtC2s(p) => { + events.0.query_entity_nbt.send(QueryEntityNbt { client: entity, transaction_id: p.transaction_id.0, entity_id: p.entity_id.0, }); } - C2sPlayPacket::Interact(p) => { - events.1.interact_with_entity.send(InteractWithEntity { + C2sPlayPacket::PlayerInteractC2s(p) => { + events.1.player_interact.send(PlayerInteract { client: entity, entity_id: p.entity_id.0, sneaking: p.sneaking, interact: p.interact, }); } - C2sPlayPacket::JigsawGenerate(p) => { - events.1.jigsaw_generate.send(JigsawGenerate { + C2sPlayPacket::JigsawGeneratingC2s(p) => { + events.1.jigsaw_generating.send(JigsawGenerating { client: entity, position: p.position, levels: p.levels.0, @@ -957,63 +913,38 @@ fn handle_one_packet( client.ping = client.keepalive_sent_time.elapsed().as_millis() as i32; } } - C2sPlayPacket::LockDifficulty(p) => { - events.1.lock_difficulty.send(LockDifficulty { + C2sPlayPacket::UpdateDifficultyLockC2s(p) => { + events.1.update_difficulty_lock.send(UpdateDifficultyLock { client: entity, locked: p.locked, }); } - C2sPlayPacket::SetPlayerPosition(p) => { + C2sPlayPacket::PositionAndOnGroundC2s(p) => { if client.pending_teleports != 0 { return Ok(false); } - events.1.set_player_position.send(SetPlayerPosition { + events.1.player_move.send(PlayerMove { client: entity, position: p.position.into(), - on_ground: p.on_ground, - }); - - events.1.move_player.send(MovePlayer { - client: entity, - old_position: client.position, - position: p.position.into(), - old_yaw: client.yaw, yaw: client.yaw, - old_pitch: client.pitch, pitch: client.pitch, - old_on_ground: client.on_ground, on_ground: client.on_ground, }); client.position = p.position.into(); client.on_ground = p.on_ground; } - C2sPlayPacket::SetPlayerPositionAndRotation(p) => { + C2sPlayPacket::FullC2s(p) => { if client.pending_teleports != 0 { return Ok(false); } - events - .1 - .set_player_position_and_rotation - .send(SetPlayerPositionAndRotation { - client: entity, - position: p.position.into(), - yaw: p.yaw, - pitch: p.pitch, - on_ground: p.on_ground, - }); - - events.1.move_player.send(MovePlayer { + events.1.player_move.send(PlayerMove { client: entity, - old_position: client.position, position: p.position.into(), - old_yaw: client.yaw, yaw: p.yaw, - old_pitch: client.pitch, pitch: p.pitch, - old_on_ground: client.on_ground, on_ground: p.on_ground, }); @@ -1022,27 +953,16 @@ fn handle_one_packet( client.pitch = p.pitch; client.on_ground = p.on_ground; } - C2sPlayPacket::SetPlayerRotation(p) => { + C2sPlayPacket::LookAndOnGroundC2s(p) => { if client.pending_teleports != 0 { return Ok(false); } - events.1.set_player_rotation.send(SetPlayerRotation { + events.1.player_move.send(PlayerMove { client: entity, - yaw: p.yaw, - pitch: p.pitch, - on_ground: p.on_ground, - }); - - events.1.move_player.send(MovePlayer { - client: entity, - old_position: client.position, position: client.position, - old_yaw: client.yaw, yaw: p.yaw, - old_pitch: client.pitch, pitch: p.pitch, - old_on_ground: client.on_ground, on_ground: p.on_ground, }); @@ -1050,144 +970,95 @@ fn handle_one_packet( client.pitch = p.pitch; client.on_ground = p.on_ground; } - C2sPlayPacket::SetPlayerOnGround(p) => { + C2sPlayPacket::OnGroundOnlyC2s(p) => { if client.pending_teleports != 0 { return Ok(false); } - events.1.set_player_on_ground.send(SetPlayerOnGround { + events.1.player_move.send(PlayerMove { client: entity, - on_ground: p.on_ground, - }); - - events.1.move_player.send(MovePlayer { - client: entity, - old_position: client.position, position: client.position, - old_yaw: client.yaw, yaw: client.yaw, - old_pitch: client.pitch, pitch: client.pitch, - old_on_ground: client.on_ground, on_ground: p.on_ground, }); client.on_ground = p.on_ground; } - C2sPlayPacket::MoveVehicleC2s(p) => { + C2sPlayPacket::VehicleMoveC2s(p) => { if client.pending_teleports != 0 { return Ok(false); } - events.1.move_vehicle.send(MoveVehicle { + events.1.vehicle_move.send(VehicleMove { client: entity, position: p.position.into(), yaw: p.yaw, pitch: p.pitch, }); - events.1.move_player.send(MovePlayer { - client: entity, - old_position: client.position, - position: p.position.into(), - old_yaw: client.yaw, - yaw: p.yaw, - old_pitch: client.pitch, - pitch: p.pitch, - old_on_ground: client.on_ground, - on_ground: client.on_ground, - }); - client.position = p.position.into(); client.yaw = p.yaw; client.pitch = p.pitch; } - C2sPlayPacket::PlayerCommand(p) => match p.action_id { - Action::StartSneaking => events - .1 - .start_sneaking - .send(StartSneaking { client: entity }), - Action::StopSneaking => events.1.stop_sneaking.send(StopSneaking { client: entity }), - Action::LeaveBed => events.1.leave_bed.send(LeaveBed { client: entity }), - Action::StartSprinting => events - .1 - .start_sprinting - .send(StartSprinting { client: entity }), - Action::StopSprinting => events - .1 - .stop_sprinting - .send(StopSprinting { client: entity }), - Action::StartJumpWithHorse => events.1.start_jump_with_horse.send(StartJumpWithHorse { - client: entity, - jump_boost: p.jump_boost.0 as u8, - }), - Action::StopJumpWithHorse => events - .1 - .stop_jump_with_horse - .send(StopJumpWithHorse { client: entity }), - Action::OpenHorseInventory => events - .2 - .open_horse_inventory - .send(OpenHorseInventory { client: entity }), - Action::StartFlyingWithElytra => events - .2 - .start_flying_with_elytra - .send(StartFlyingWithElytra { client: entity }), - }, - C2sPlayPacket::PaddleBoat(p) => { - events.2.paddle_boat.send(PaddleBoat { + C2sPlayPacket::BoatPaddleStateC2s(p) => { + events.2.boat_paddle_state.send(BoatPaddleState { client: entity, left_paddle_turning: p.left_paddle_turning, right_paddle_turning: p.right_paddle_turning, }); } - C2sPlayPacket::PickItem(p) => { - events.2.pick_item.send(PickItem { + C2sPlayPacket::PickFromInventoryC2s(p) => { + events.2.pick_from_inventory.send(PickFromInventory { client: entity, slot_to_use: p.slot_to_use.0, }); } - C2sPlayPacket::PlaceRecipe(p) => { - events.2.place_recipe.send(PlaceRecipe { + C2sPlayPacket::CraftRequestC2s(p) => { + events.2.craft_request.send(CraftRequest { client: entity, window_id: p.window_id, recipe: p.recipe.into(), make_all: p.make_all, }); } - C2sPlayPacket::PlayerAbilitiesC2s(p) => match p { - PlayerAbilitiesC2s::StopFlying => { + C2sPlayPacket::UpdatePlayerAbilitiesC2s(p) => match p { + UpdatePlayerAbilitiesC2s::StopFlying => { events.2.stop_flying.send(StopFlying { client: entity }) } - PlayerAbilitiesC2s::StartFlying => { + UpdatePlayerAbilitiesC2s::StartFlying => { events.2.start_flying.send(StartFlying { client: entity }) } }, - C2sPlayPacket::PlayerAction(p) => { + C2sPlayPacket::PlayerActionC2s(p) => { if p.sequence.0 != 0 { client.block_change_sequence = cmp::max(p.sequence.0, client.block_change_sequence); } - match p.status { - DiggingStatus::StartedDigging => events.2.start_digging.send(StartDigging { + match p.action { + PlayerAction::StartDestroyBlock => events.2.start_digging.send(StartDigging { client: entity, position: p.position, - face: p.face, + direction: p.direction, sequence: p.sequence.0, }), - DiggingStatus::CancelledDigging => events.2.cancel_digging.send(CancelDigging { - client: entity, - position: p.position, - face: p.face, - sequence: p.sequence.0, - }), - DiggingStatus::FinishedDigging => events.2.finish_digging.send(FinishDigging { - client: entity, - position: p.position, - face: p.face, - sequence: p.sequence.0, - }), - DiggingStatus::DropItemStack => { + PlayerAction::AbortDestroyBlock => { + events.2.abort_destroy_block.send(AbortDestroyBlock { + client: entity, + position: p.position, + direction: p.direction, + sequence: p.sequence.0, + }) + } + PlayerAction::StopDestroyBlock => { + events.2.stop_destroy_block.send(StopDestroyBlock { + client: entity, + position: p.position, + direction: p.direction, + sequence: p.sequence.0, + }) + } + PlayerAction::DropAllItems => { if let Some(stack) = inventory.replace_slot(client.held_item_slot(), None) { client.inventory_slots_modified |= 1 << client.held_item_slot(); events.2.drop_item_stack.send(DropItemStack { @@ -1197,7 +1068,7 @@ fn handle_one_packet( }); } } - DiggingStatus::DropItem => { + PlayerAction::DropItem => { if let Some(stack) = inventory.slot(client.held_item_slot()) { let mut old_slot = if stack.count() == 1 { inventory.replace_slot(client.held_item_slot(), None) @@ -1217,17 +1088,53 @@ fn handle_one_packet( }); } } - DiggingStatus::UpdateHeldItemState => events + PlayerAction::ReleaseUseItem => events .2 - .update_held_item_state - .send(UpdateHeldItemState { client: entity }), - DiggingStatus::SwapItemInHand => events + .release_use_item + .send(ReleaseUseItem { client: entity }), + PlayerAction::SwapItemWithOffhand => events .2 - .swap_item_in_hand - .send(SwapItemInHand { client: entity }), + .swap_item_with_offhand + .send(SwapItemWithOffhand { client: entity }), } } - C2sPlayPacket::PlayerInput(p) => { + C2sPlayPacket::ClientCommandC2s(p) => match p.action { + ClientCommandAction::StartSneaking => events + .1 + .start_sneaking + .send(StartSneaking { client: entity }), + ClientCommandAction::StopSneaking => { + events.1.stop_sneaking.send(StopSneaking { client: entity }) + } + ClientCommandAction::LeaveBed => events.1.leave_bed.send(LeaveBed { client: entity }), + ClientCommandAction::StartSprinting => events + .1 + .start_sprinting + .send(StartSprinting { client: entity }), + ClientCommandAction::StopSprinting => events + .1 + .stop_sprinting + .send(StopSprinting { client: entity }), + ClientCommandAction::StartJumpWithHorse => { + events.1.start_jump_with_horse.send(StartJumpWithHorse { + client: entity, + jump_boost: p.jump_boost.0 as u8, + }) + } + ClientCommandAction::StopJumpWithHorse => events + .1 + .stop_jump_with_horse + .send(StopJumpWithHorse { client: entity }), + ClientCommandAction::OpenHorseInventory => events + .2 + .open_horse_inventory + .send(OpenHorseInventory { client: entity }), + ClientCommandAction::StartFlyingWithElytra => events + .2 + .start_flying_with_elytra + .send(StartFlyingWithElytra { client: entity }), + }, + C2sPlayPacket::PlayerInputC2s(p) => { events.2.player_input.send(PlayerInput { client: entity, sideways: p.sideways, @@ -1236,13 +1143,13 @@ fn handle_one_packet( unmount: p.flags.unmount(), }); } - C2sPlayPacket::PongPlay(p) => { - events.2.pong.send(Pong { + C2sPlayPacket::PlayPongC2s(p) => { + events.2.play_pong.send(PlayPong { client: entity, id: p.id, }); } - C2sPlayPacket::PlayerSession(p) => { + C2sPlayPacket::PlayerSessionC2s(p) => { events.3.player_session.send(PlayerSession { client: entity, session_id: p.session_id, @@ -1251,30 +1158,30 @@ fn handle_one_packet( key_signature: p.key_signature.into(), }); } - C2sPlayPacket::ChangeRecipeBookSettings(p) => { + C2sPlayPacket::RecipeCategoryOptionsC2s(p) => { events .3 - .change_recipe_book_settings - .send(ChangeRecipeBookSettings { + .recipe_category_options + .send(RecipeCategoryOptions { client: entity, book_id: p.book_id, book_open: p.book_open, filter_active: p.filter_active, }); } - C2sPlayPacket::SetSeenRecipe(p) => { - events.3.set_seen_recipe.send(SetSeenRecipe { + C2sPlayPacket::RecipeBookDataC2s(p) => { + events.3.recipe_book_data.send(RecipeBookData { client: entity, recipe_id: p.recipe_id.into(), }); } - C2sPlayPacket::RenameItem(p) => { + C2sPlayPacket::RenameItemC2s(p) => { events.3.rename_item.send(RenameItem { client: entity, name: p.item_name.into(), }); } - C2sPlayPacket::ResourcePackC2s(p) => { + C2sPlayPacket::ResourcePackStatusC2s(p) => { events .3 .resource_pack_status_change @@ -1283,37 +1190,39 @@ fn handle_one_packet( status: p.into(), }) } - C2sPlayPacket::SeenAdvancements(p) => match p { - SeenAdvancements::OpenedTab { tab_id } => { + C2sPlayPacket::AdvancementTabC2s(p) => match p { + AdvancementTabC2s::OpenedTab { tab_id } => { events.3.open_advancement_tab.send(OpenAdvancementTab { client: entity, tab_id: tab_id.into(), }) } - SeenAdvancements::ClosedScreen => events + AdvancementTabC2s::ClosedScreen => events .3 .close_advancement_screen .send(CloseAdvancementScreen { client: entity }), }, - C2sPlayPacket::SelectTrade(p) => { - events.3.select_trade.send(SelectTrade { + C2sPlayPacket::SelectMerchantTradeC2s(p) => { + events.3.select_merchant_trade.send(SelectMerchantTrade { client: entity, slot: p.selected_slot.0, }); } - C2sPlayPacket::SetBeaconEffect(p) => { - events.3.set_beacon_effect.send(SetBeaconEffect { + C2sPlayPacket::UpdateBeaconC2s(p) => { + events.3.update_beacon.send(UpdateBeacon { client: entity, primary_effect: p.primary_effect.map(|i| i.0), secondary_effect: p.secondary_effect.map(|i| i.0), }); } - C2sPlayPacket::SetHeldItemC2s(p) => events.3.set_held_item.send(SetHeldItem { - client: entity, - slot: p.slot, - }), - C2sPlayPacket::ProgramCommandBlock(p) => { - events.3.program_command_block.send(ProgramCommandBlock { + C2sPlayPacket::UpdateSelectedSlotC2s(p) => { + events.3.update_selected_slot.send(UpdateSelectedSlot { + client: entity, + slot: p.slot, + }) + } + C2sPlayPacket::UpdateCommandBlockC2s(p) => { + events.3.update_command_block.send(UpdateCommandBlock { client: entity, position: p.position, command: p.command.into(), @@ -1323,18 +1232,18 @@ fn handle_one_packet( automatic: p.flags.automatic(), }); } - C2sPlayPacket::ProgramCommandBlockMinecart(p) => { + C2sPlayPacket::UpdateCommandBlockMinecartC2s(p) => { events .3 - .program_command_block_minecart - .send(ProgramCommandBlockMinecart { + .update_command_block_minecart + .send(UpdateCommandBlockMinecart { client: entity, entity_id: p.entity_id.0, command: p.command.into(), track_output: p.track_output, }); } - C2sPlayPacket::SetCreativeModeSlot(p) => { + C2sPlayPacket::CreativeInventoryActionC2s(p) => { if p.slot == -1 { if let Some(stack) = p.clicked_item.as_ref() { events.2.drop_item_stack.send(DropItemStack { @@ -1344,14 +1253,17 @@ fn handle_one_packet( }); } } - events.3.set_creative_mode_slot.send(SetCreativeModeSlot { - client: entity, - slot: p.slot, - clicked_item: p.clicked_item, - }); + events + .3 + .creative_inventory_action + .send(CreativeInventoryAction { + client: entity, + slot: p.slot, + clicked_item: p.clicked_item, + }); } - C2sPlayPacket::ProgramJigsawBlock(p) => { - events.4.program_jigsaw_block.send(ProgramJigsawBlock { + C2sPlayPacket::UpdateJigsawC2s(p) => { + events.4.update_jigsaw.send(UpdateJigsaw { client: entity, position: p.position, name: p.name.into(), @@ -1361,66 +1273,63 @@ fn handle_one_packet( joint_type: p.joint_type.into(), }); } - C2sPlayPacket::ProgramStructureBlock(p) => { - events - .4 - .program_structure_block - .send(ProgramStructureBlock { - client: entity, - position: p.position, - action: p.action, - mode: p.mode, - name: p.name.into(), - offset_xyz: p.offset_xyz, - size_xyz: p.size_xyz, - mirror: p.mirror, - rotation: p.rotation, - metadata: p.metadata.into(), - integrity: p.integrity, - seed: p.seed.0, - flags: p.flags, - }) + C2sPlayPacket::UpdateStructureBlockC2s(p) => { + events.4.update_structure_block.send(UpdateStructureBlock { + client: entity, + position: p.position, + action: p.action, + mode: p.mode, + name: p.name.into(), + offset_xyz: p.offset_xyz, + size_xyz: p.size_xyz, + mirror: p.mirror, + rotation: p.rotation, + metadata: p.metadata.into(), + integrity: p.integrity, + seed: p.seed.0, + flags: p.flags, + }) } - C2sPlayPacket::UpdateSign(p) => { + C2sPlayPacket::UpdateSignC2s(p) => { events.4.update_sign.send(UpdateSign { client: entity, position: p.position, lines: p.lines.map(Into::into), }); } - C2sPlayPacket::SwingArm(p) => { - events.4.swing_arm.send(SwingArm { + C2sPlayPacket::HandSwingC2s(p) => { + events.4.hand_swing.send(HandSwing { client: entity, hand: p.hand, }); } - C2sPlayPacket::TeleportToEntity(p) => { - events.4.teleport_to_entity.send(TeleportToEntity { + C2sPlayPacket::SpectatorTeleportC2s(p) => { + events.4.spectator_teleport.send(SpectatorTeleport { client: entity, target: p.target, }); } - C2sPlayPacket::UseItemOn(p) => { + C2sPlayPacket::PlayerInteractBlockC2s(p) => { if p.sequence.0 != 0 { client.block_change_sequence = cmp::max(p.sequence.0, client.block_change_sequence); } - events.4.use_item_on_block.send(UseItemOnBlock { + events.4.player_interact_block.send(PlayerInteractBlock { client: entity, hand: p.hand, position: p.position, - face: p.face, + direction: p.face, cursor_pos: p.cursor_pos.into(), head_inside_block: false, sequence: 0, }) } - C2sPlayPacket::UseItem(p) => { + C2sPlayPacket::PlayerInteractItemC2s(p) => { if p.sequence.0 != 0 { client.block_change_sequence = cmp::max(p.sequence.0, client.block_change_sequence); } - events.4.use_item.send(UseItem { + events.4.player_interact_item.send(PlayerInteractItem { client: entity, hand: p.hand, sequence: p.sequence.0, @@ -1449,15 +1358,15 @@ fn handle_one_packet( #[allow(clippy::too_many_arguments)] pub fn default_event_handler( mut clients: Query<(&mut Client, Option<&mut McEntity>)>, - mut update_settings: EventReader, - mut move_player: EventReader, + mut update_settings: EventReader, + mut player_move: EventReader, mut start_sneaking: EventReader, mut stop_sneaking: EventReader, mut start_sprinting: EventReader, mut stop_sprinting: EventReader, - mut swing_arm: EventReader, + mut swing_arm: EventReader, ) { - for UpdateSettings { + for ClientSettings { client, view_distance, displayed_skin_parts, @@ -1496,14 +1405,14 @@ pub fn default_event_handler( } } - for MovePlayer { + for PlayerMove { client, position, yaw, pitch, on_ground, .. - } in move_player.iter() + } in player_move.iter() { let Ok((_, Some(mut entity))) = clients.get_mut(*client) else { continue @@ -1556,7 +1465,7 @@ pub fn default_event_handler( } } - for SwingArm { client, hand } in swing_arm.iter() { + for HandSwing { client, hand } in swing_arm.iter() { let Ok((_, Some(mut entity))) = clients.get_mut(*client) else { continue }; diff --git a/crates/valence/src/config.rs b/crates/valence/src/config.rs index 6a751c6..a19d977 100644 --- a/crates/valence/src/config.rs +++ b/crates/valence/src/config.rs @@ -7,7 +7,8 @@ use serde::Serialize; use tokio::runtime::Handle; use tracing::error; use uuid::Uuid; -use valence_protocol::{Text, Username}; +use valence_protocol::text::Text; +use valence_protocol::username::Username; use crate::biome::Biome; use crate::dimension::Dimension; diff --git a/crates/valence/src/entity.rs b/crates/valence/src/entity.rs index 4517e4d..e15697d 100644 --- a/crates/valence/src/entity.rs +++ b/crates/valence/src/entity.rs @@ -9,13 +9,14 @@ use glam::{DVec3, UVec3, Vec3}; use rustc_hash::FxHashMap; use tracing::warn; use uuid::Uuid; -use valence_protocol::entity_meta::{Facing, PaintingKind, Pose}; -use valence_protocol::packets::s2c::play::{ - EntityAnimationS2c, EntityEvent as EntityEventS2c, SetEntityMetadata, SetEntityVelocity, - SetHeadRotation, SpawnEntity, SpawnExperienceOrb, SpawnPlayer, TeleportEntity, - UpdateEntityPosition, UpdateEntityPositionAndRotation, UpdateEntityRotation, +use valence_protocol::byte_angle::ByteAngle; +use valence_protocol::packet::s2c::play::{ + EntityAnimationS2c, EntityPositionS2c, EntitySetHeadYawS2c, EntitySpawnS2c, + EntityStatusS2c as EntityEventS2c, EntityTrackerUpdateS2c, EntityVelocityUpdateS2c, + ExperienceOrbSpawnS2c, MoveRelativeS2c, PlayerSpawnS2c, RotateAndMoveRelativeS2c, RotateS2c, }; -use valence_protocol::{ByteAngle, RawBytes, VarInt}; +use valence_protocol::tracked_data::{Facing, PaintingKind, Pose}; +use valence_protocol::var_int::VarInt; use crate::config::DEFAULT_TPS; use crate::math::Aabb; @@ -321,7 +322,7 @@ impl McEntity { /// The hitbox of an entity is determined by its position, entity type, and /// other state specific to that type. /// - /// [interact event]: crate::client::event::InteractWithEntity + /// [interact event]: crate::client::event::PlayerInteract pub fn hitbox(&self) -> Aabb { fn baby(is_baby: bool, adult_hitbox: [f64; 3]) -> [f64; 3] { if is_baby { @@ -612,7 +613,7 @@ impl McEntity { position: DVec3, scratch: &mut Vec, ) { - let with_object_data = |data| SpawnEntity { + let with_object_data = |data| EntitySpawnS2c { entity_id: VarInt(self.protocol_id), object_uuid: self.uuid, kind: VarInt(self.kind() as i32), @@ -626,13 +627,13 @@ impl McEntity { match &self.data { TrackedData::Marker(_) => {} - TrackedData::ExperienceOrb(_) => writer.write_packet(&SpawnExperienceOrb { + TrackedData::ExperienceOrb(_) => writer.write_packet(&ExperienceOrbSpawnS2c { entity_id: VarInt(self.protocol_id), position: position.to_array(), count: 0, // TODO }), TrackedData::Player(_) => { - writer.write_packet(&SpawnPlayer { + writer.write_packet(&PlayerSpawnS2c { entity_id: VarInt(self.protocol_id), player_uuid: self.uuid, position: position.to_array(), @@ -641,7 +642,7 @@ impl McEntity { }); // Player spawn packet doesn't include head yaw for some reason. - writer.write_packet(&SetHeadRotation { + writer.write_packet(&EntitySetHeadYawS2c { entity_id: VarInt(self.protocol_id), head_yaw: ByteAngle::from_degrees(self.head_yaw), }); @@ -673,9 +674,9 @@ impl McEntity { scratch.clear(); self.data.write_initial_tracked_data(scratch); if !scratch.is_empty() { - writer.write_packet(&SetEntityMetadata { + writer.write_packet(&EntityTrackerUpdateS2c { entity_id: VarInt(self.protocol_id), - metadata: RawBytes(scratch), + metadata: scratch.as_slice().into(), }); } } @@ -690,7 +691,7 @@ impl McEntity { let changed_position = self.position != self.old_position; if changed_position && !needs_teleport && self.yaw_or_pitch_modified { - writer.write_packet(&UpdateEntityPositionAndRotation { + writer.write_packet(&RotateAndMoveRelativeS2c { entity_id, delta: (position_delta * 4096.0).to_array().map(|v| v as i16), yaw: ByteAngle::from_degrees(self.yaw), @@ -699,7 +700,7 @@ impl McEntity { }); } else { if changed_position && !needs_teleport { - writer.write_packet(&UpdateEntityPosition { + writer.write_packet(&MoveRelativeS2c { entity_id, delta: (position_delta * 4096.0).to_array().map(|v| v as i16), on_ground: self.on_ground, @@ -707,7 +708,7 @@ impl McEntity { } if self.yaw_or_pitch_modified { - writer.write_packet(&UpdateEntityRotation { + writer.write_packet(&RotateS2c { entity_id, yaw: ByteAngle::from_degrees(self.yaw), pitch: ByteAngle::from_degrees(self.pitch), @@ -717,7 +718,7 @@ impl McEntity { } if needs_teleport { - writer.write_packet(&TeleportEntity { + writer.write_packet(&EntityPositionS2c { entity_id, position: self.position.to_array(), yaw: ByteAngle::from_degrees(self.yaw), @@ -727,14 +728,14 @@ impl McEntity { } if self.velocity_modified { - writer.write_packet(&SetEntityVelocity { + writer.write_packet(&EntityVelocityUpdateS2c { entity_id, velocity: velocity_to_packet_units(self.velocity), }); } if self.head_yaw_modified { - writer.write_packet(&SetHeadRotation { + writer.write_packet(&EntitySetHeadYawS2c { entity_id, head_yaw: ByteAngle::from_degrees(self.head_yaw), }); @@ -743,9 +744,9 @@ impl McEntity { scratch.clear(); self.data.write_updated_tracked_data(scratch); if !scratch.is_empty() { - writer.write_packet(&SetEntityMetadata { + writer.write_packet(&EntityTrackerUpdateS2c { entity_id, - metadata: RawBytes(scratch), + metadata: scratch.as_slice().into(), }); } diff --git a/crates/valence/src/entity/data.rs b/crates/valence/src/entity/data.rs index 36272e4..dbe7a30 100644 --- a/crates/valence/src/entity/data.rs +++ b/crates/valence/src/entity/data.rs @@ -4,7 +4,11 @@ #![allow(clippy::all, missing_docs, trivial_numeric_casts, dead_code)] use uuid::Uuid; -use valence_protocol::entity_meta::*; -use valence_protocol::{BlockPos, BlockState, Encode, Text, VarInt}; +use valence_protocol::block::BlockState; +use valence_protocol::block_pos::BlockPos; +use valence_protocol::text::Text; +use valence_protocol::tracked_data::*; +use valence_protocol::var_int::VarInt; +use valence_protocol::Encode; include!(concat!(env!("OUT_DIR"), "/entity.rs")); diff --git a/crates/valence/src/instance.rs b/crates/valence/src/instance.rs index 761cb9a..504dba6 100644 --- a/crates/valence/src/instance.rs +++ b/crates/valence/src/instance.rs @@ -1,20 +1,25 @@ +use std::borrow::Cow; use std::collections::hash_map::Entry; use std::collections::BTreeSet; use std::iter::FusedIterator; use bevy_ecs::prelude::*; +pub use chunk::{Block, BlockEntity, BlockMut, BlockRef, Chunk}; pub use chunk_entry::*; use glam::{DVec3, Vec3}; use num::integer::div_ceil; use rustc_hash::FxHashMap; -use valence_protocol::packets::s2c::particle::{Particle, ParticleS2c}; -use valence_protocol::packets::s2c::play::{SetActionBarText, SoundEffect}; +use valence_protocol::array::LengthPrefixedArray; +use valence_protocol::block_pos::BlockPos; +use valence_protocol::packet::s2c::play::particle::Particle; +use valence_protocol::packet::s2c::play::{OverlayMessageS2c, ParticleS2c, PlaySoundS2c}; +use valence_protocol::sound::Sound; +use valence_protocol::text::Text; use valence_protocol::types::SoundCategory; -use valence_protocol::{BlockPos, EncodePacket, LengthPrefixedArray, Sound, Text}; +use valence_protocol::EncodePacket; use crate::dimension::DimensionId; use crate::entity::McEntity; -pub use crate::instance::chunk::{Block, BlockMut, BlockRef, Chunk}; use crate::packet::{PacketWriter, WritePacket}; use crate::server::{Server, SharedServer}; use crate::view::ChunkPos; @@ -383,7 +388,7 @@ impl Instance { self.write_packet_at( &ParticleS2c { - particle: particle.clone(), + particle: Cow::Borrowed(particle), long_distance, position: position.into(), offset: offset.into().into(), @@ -408,7 +413,7 @@ impl Instance { let position = position.into(); self.write_packet_at( - &SoundEffect { + &PlaySoundS2c { id: sound.to_id(), category, position: (position * 8.0).as_ivec3().into(), @@ -422,7 +427,7 @@ impl Instance { /// Sets the action bar text of all players in the instance. pub fn set_action_bar(&mut self, text: impl Into) { - self.write_packet(&SetActionBarText { + self.write_packet(&OverlayMessageS2c { action_bar_text: text.into().into(), }); } diff --git a/crates/valence/src/instance/chunk.rs b/crates/valence/src/instance/chunk.rs index 6a0f59d..37d04ec 100644 --- a/crates/valence/src/instance/chunk.rs +++ b/crates/valence/src/instance/chunk.rs @@ -6,12 +6,15 @@ use std::sync::atomic::{AtomicBool, Ordering}; // Using nonstandard mutex to avoid poisoning API. use parking_lot::Mutex; use valence_nbt::{compound, Compound}; -use valence_protocol::block::{BlockEntity, BlockState}; -use valence_protocol::packets::s2c::play::{ - BlockEntityData, BlockUpdate, ChunkDataAndUpdateLightEncode, UpdateSectionBlocksEncode, +use valence_protocol::block::{BlockEntityKind, BlockState}; +use valence_protocol::block_pos::BlockPos; +use valence_protocol::packet::s2c::play::chunk_data::ChunkDataBlockEntity; +use valence_protocol::packet::s2c::play::{ + BlockEntityUpdateS2c, BlockUpdateS2c, ChunkDataS2c, ChunkDeltaUpdateS2c, }; -use valence_protocol::types::ChunkDataBlockEntity; -use valence_protocol::{BlockPos, Encode, VarInt, VarLong}; +use valence_protocol::var_int::VarInt; +use valence_protocol::var_long::VarLong; +use valence_protocol::Encode; use crate::biome::BiomeId; use crate::instance::paletted_container::PalettedContainer; @@ -171,6 +174,18 @@ impl<'a> BlockMut<'a> { } } +#[derive(Debug, Clone, PartialEq)] +pub struct BlockEntity { + pub kind: BlockEntityKind, + pub nbt: Compound, +} + +impl BlockEntity { + pub fn new(kind: BlockEntityKind, nbt: Compound) -> Self { + Self { kind, nbt } + } +} + const SECTION_BLOCK_COUNT: usize = 16 * 16 * 16; const SECTION_BIOME_COUNT: usize = 4 * 4 * 4; @@ -329,7 +344,7 @@ impl Chunk { let global_y = info.min_y + sect_y as i32 * 16 + offset_y as i32; let global_z = pos.z * 16 + offset_z as i32; - writer.write_packet(&BlockUpdate { + writer.write_packet(&BlockUpdateS2c { position: BlockPos::new(global_x, global_y, global_z), block_id: VarInt(block as i32), }) @@ -338,10 +353,10 @@ impl Chunk { | (pos.z as i64 & 0x3fffff) << 20 | (sect_y as i64 + info.min_y.div_euclid(16) as i64) & 0xfffff; - writer.write_packet(&UpdateSectionBlocksEncode { + writer.write_packet(&ChunkDeltaUpdateS2c { chunk_section_position, invert_trust_edges: false, - blocks: §.section_updates, + blocks: Cow::Borrowed(§.section_updates), }); } } @@ -357,7 +372,7 @@ impl Chunk { let global_y = info.min_y + y as i32; let global_z = pos.z * 16 + z as i32; - writer.write_packet(&BlockEntityData { + writer.write_packet(&BlockEntityUpdateS2c { position: BlockPos::new(global_x, global_y, global_z), kind: block_entity.kind, data: Cow::Borrowed(&block_entity.nbt), @@ -429,21 +444,23 @@ impl Chunk { }) .collect(); - writer.write_packet(&ChunkDataAndUpdateLightEncode { + let heightmaps = compound! { + // TODO: MOTION_BLOCKING heightmap + }; + + writer.write_packet(&ChunkDataS2c { chunk_x: pos.x, chunk_z: pos.z, - heightmaps: &compound! { - // TODO: MOTION_BLOCKING heightmap - }, + heightmaps: Cow::Owned(heightmaps), blocks_and_biomes: scratch, - block_entities: &block_entities, + block_entities: Cow::Borrowed(&block_entities), trust_edges: true, - sky_light_mask: &info.filler_sky_light_mask, - block_light_mask: &[], - empty_sky_light_mask: &[], - empty_block_light_mask: &[], - sky_light_arrays: &info.filler_sky_light_arrays, - block_light_arrays: &[], + sky_light_mask: Cow::Borrowed(&info.filler_sky_light_mask), + block_light_mask: Cow::Borrowed(&[]), + empty_sky_light_mask: Cow::Borrowed(&[]), + empty_block_light_mask: Cow::Borrowed(&[]), + sky_light_arrays: Cow::Borrowed(&info.filler_sky_light_arrays), + block_light_arrays: Cow::Borrowed(&[]), }); } diff --git a/crates/valence/src/instance/paletted_container.rs b/crates/valence/src/instance/paletted_container.rs index 53357e1..accd51d 100644 --- a/crates/valence/src/instance/paletted_container.rs +++ b/crates/valence/src/instance/paletted_container.rs @@ -2,7 +2,8 @@ use std::array; use std::io::Write; use arrayvec::ArrayVec; -use valence_protocol::{Encode, VarInt}; +use valence_protocol::var_int::VarInt; +use valence_protocol::Encode; use crate::math::bit_width; diff --git a/crates/valence/src/inventory.rs b/crates/valence/src/inventory.rs index 43992ad..9eb1950 100644 --- a/crates/valence/src/inventory.rs +++ b/crates/valence/src/inventory.rs @@ -1,14 +1,19 @@ +use std::borrow::Cow; use std::iter::FusedIterator; use bevy_ecs::prelude::*; use tracing::{debug, warn}; -use valence_protocol::packets::s2c::play::{ - CloseContainerS2c, OpenScreen, SetContainerContentEncode, SetContainerSlotEncode, +use valence_protocol::item::ItemStack; +use valence_protocol::packet::s2c::play::{ + CloseScreenS2c, InventoryS2c, OpenScreenS2c, ScreenHandlerSlotUpdateS2c, }; +use valence_protocol::text::Text; use valence_protocol::types::{GameMode, WindowType}; -use valence_protocol::{ItemStack, Text, VarInt}; +use valence_protocol::var_int::VarInt; -use crate::client::event::{ClickContainer, CloseContainer, SetCreativeModeSlot, SetHeldItem}; +use crate::client::event::{ + ClickSlot, CloseHandledScreen, CreativeInventoryAction, UpdateSelectedSlot, +}; use crate::client::Client; #[derive(Debug, Clone, Component)] @@ -124,11 +129,11 @@ pub(crate) fn update_player_inventories( client.inventory_state_id += 1; let cursor_item = client.cursor_item.clone(); let state_id = client.inventory_state_id.0; - client.write_packet(&SetContainerContentEncode { + client.write_packet(&InventoryS2c { window_id: 0, state_id: VarInt(state_id), - slots: inventory.slot_slice(), - carried_item: &cursor_item, + slots: Cow::Borrowed(inventory.slot_slice()), + carried_item: Cow::Borrowed(&cursor_item), }); client.cursor_item_modified = false; @@ -142,11 +147,11 @@ pub(crate) fn update_player_inventories( let state_id = client.inventory_state_id.0; for (i, slot) in inventory.slots.iter().enumerate() { if ((modified_filtered >> i) & 1) == 1 { - client.write_packet(&SetContainerSlotEncode { + client.write_packet(&ScreenHandlerSlotUpdateS2c { window_id: 0, state_id: VarInt(state_id), slot_idx: i as i16, - slot_data: slot.as_ref(), + slot_data: Cow::Borrowed(slot), }); } } @@ -162,13 +167,14 @@ pub(crate) fn update_player_inventories( client.cursor_item_modified = false; + // TODO: eliminate clone? let cursor_item = client.cursor_item.clone(); let state_id = client.inventory_state_id.0; - client.write_packet(&SetContainerSlotEncode { + client.write_packet(&ScreenHandlerSlotUpdateS2c { window_id: -1, state_id: VarInt(state_id), slot_idx: -1, - slot_data: cursor_item.as_ref(), + slot_data: Cow::Borrowed(&cursor_item), }); } } @@ -342,7 +348,7 @@ pub(crate) fn update_open_inventories( // the inventory no longer exists, so close the inventory commands.entity(client_entity).remove::(); let window_id = client.window_id; - client.write_packet(&CloseContainerS2c { + client.write_packet(&CloseScreenS2c { window_id, }); continue; @@ -353,18 +359,19 @@ pub(crate) fn update_open_inventories( client.window_id = client.window_id % 100 + 1; open_inventory.client_modified = 0; - let packet = OpenScreen { + let packet = OpenScreenS2c { window_id: VarInt(client.window_id.into()), window_type: WindowType::from(inventory.kind), window_title: (&inventory.title).into(), }; client.write_packet(&packet); - let packet = SetContainerContentEncode { + let packet = InventoryS2c { window_id: client.window_id, state_id: VarInt(client.inventory_state_id.0), - slots: inventory.slot_slice(), - carried_item: &client.cursor_item.clone(), + slots: Cow::Borrowed(inventory.slot_slice()), + // TODO: eliminate clone? + carried_item: Cow::Owned(client.cursor_item.clone()), }; client.write_packet(&packet); } else { @@ -372,11 +379,12 @@ pub(crate) fn update_open_inventories( if inventory.modified == u64::MAX { // send the entire inventory client.inventory_state_id += 1; - let packet = SetContainerContentEncode { + let packet = InventoryS2c { window_id: client.window_id, state_id: VarInt(client.inventory_state_id.0), - slots: inventory.slot_slice(), - carried_item: &client.cursor_item.clone(), + slots: Cow::Borrowed(inventory.slot_slice()), + // TODO: eliminate clone? + carried_item: Cow::Owned(client.cursor_item.clone()), }; client.write_packet(&packet); } else { @@ -389,11 +397,11 @@ pub(crate) fn update_open_inventories( let state_id = client.inventory_state_id.0; for (i, slot) in inventory.slots.iter().enumerate() { if (modified_filtered >> i) & 1 == 1 { - client.write_packet(&SetContainerSlotEncode { + client.write_packet(&ScreenHandlerSlotUpdateS2c { window_id, state_id: VarInt(state_id), slot_idx: i as i16, - slot_data: slot.as_ref(), + slot_data: Cow::Borrowed(slot), }); } } @@ -418,7 +426,7 @@ pub(crate) fn update_open_inventories( /// Handles clients telling the server that they are closing an inventory. pub(crate) fn handle_close_container( mut commands: Commands, - mut events: EventReader, + mut events: EventReader, ) { for event in events.iter() { commands.entity(event.client).remove::(); @@ -434,7 +442,7 @@ pub(crate) fn update_client_on_close_inventory( for entity in removals.iter() { if let Ok(mut client) = clients.get_component_mut::(entity) { let window_id = client.window_id; - client.write_packet(&CloseContainerS2c { window_id }); + client.write_packet(&CloseScreenS2c { window_id }); } } } @@ -442,7 +450,7 @@ pub(crate) fn update_client_on_close_inventory( pub(crate) fn handle_click_container( mut clients: Query<(&mut Client, &mut Inventory, Option<&mut OpenInventory>)>, mut inventories: Query<&mut Inventory, Without>, - mut events: EventReader, + mut events: EventReader, ) { for event in events.iter() { let Ok((mut client, mut client_inventory, mut open_inventory)) = @@ -472,11 +480,12 @@ pub(crate) fn handle_click_container( // client is out of sync, resync, ignore click debug!("Client state id mismatch, resyncing"); client.inventory_state_id += 1; - let packet = SetContainerContentEncode { + let packet = InventoryS2c { window_id: client.window_id, state_id: VarInt(client.inventory_state_id.0), - slots: target_inventory.slot_slice(), - carried_item: &client.cursor_item.clone(), + slots: Cow::Borrowed(target_inventory.slot_slice()), + // TODO: eliminate clone? + carried_item: Cow::Owned(client.cursor_item.clone()), }; client.write_packet(&packet); continue; @@ -484,15 +493,15 @@ pub(crate) fn handle_click_container( client.cursor_item = event.carried_item.clone(); - for (slot_id, item) in event.slot_changes.clone() { - if (0i16..target_inventory.slot_count() as i16).contains(&slot_id) { + for slot in event.slot_changes.clone() { + if (0i16..target_inventory.slot_count() as i16).contains(&slot.idx) { // the client is interacting with a slot in the target inventory - target_inventory.replace_slot(slot_id as u16, item); - open_inventory.client_modified |= 1 << slot_id; + target_inventory.replace_slot(slot.idx as u16, slot.item); + open_inventory.client_modified |= 1 << slot.idx; } else { // the client is interacting with a slot in their own inventory - let slot_id = convert_to_player_slot_id(target_inventory.kind, slot_id as u16); - client_inventory.replace_slot(slot_id, item); + let slot_id = convert_to_player_slot_id(target_inventory.kind, slot.idx as u16); + client_inventory.replace_slot(slot_id, slot.item); client.inventory_slots_modified |= 1 << slot_id; } } @@ -503,11 +512,12 @@ pub(crate) fn handle_click_container( // client is out of sync, resync, and ignore the click debug!("Client state id mismatch, resyncing"); client.inventory_state_id += 1; - let packet = SetContainerContentEncode { + let packet = InventoryS2c { window_id: client.window_id, state_id: VarInt(client.inventory_state_id.0), - slots: client_inventory.slot_slice(), - carried_item: &client.cursor_item.clone(), + slots: Cow::Borrowed(client_inventory.slot_slice()), + // TODO: eliminate clone? + carried_item: Cow::Owned(client.cursor_item.clone()), }; client.write_packet(&packet); continue; @@ -515,16 +525,16 @@ pub(crate) fn handle_click_container( // TODO: do more validation on the click client.cursor_item = event.carried_item.clone(); - for (slot_id, item) in event.slot_changes.clone() { - if (0i16..client_inventory.slot_count() as i16).contains(&slot_id) { - client_inventory.replace_slot(slot_id as u16, item); - client.inventory_slots_modified |= 1 << slot_id; + for slot in event.slot_changes.clone() { + if (0i16..client_inventory.slot_count() as i16).contains(&slot.idx) { + client_inventory.replace_slot(slot.idx as u16, slot.item); + client.inventory_slots_modified |= 1 << slot.idx; } else { // the client is trying to interact with a slot that does not exist, // ignore warn!( "Client attempted to interact with slot {} which does not exist", - slot_id + slot.idx ); } } @@ -534,7 +544,7 @@ pub(crate) fn handle_click_container( pub(crate) fn handle_set_slot_creative( mut clients: Query<(&mut Client, &mut Inventory)>, - mut events: EventReader, + mut events: EventReader, ) { for event in events.iter() { if let Ok((mut client, mut inventory)) = clients.get_mut(event.client) { @@ -554,11 +564,11 @@ pub(crate) fn handle_set_slot_creative( // creative mode Simply marking the slot as modified is not enough. This was // discovered because shift-clicking the destroy item slot in creative mode does // not work without this hack. - client.write_packet(&SetContainerSlotEncode { + client.write_packet(&ScreenHandlerSlotUpdateS2c { window_id: 0, state_id: VarInt(state_id), slot_idx: event.slot, - slot_data: event.clicked_item.as_ref(), + slot_data: Cow::Borrowed(&event.clicked_item), }); } } @@ -566,7 +576,7 @@ pub(crate) fn handle_set_slot_creative( pub(crate) fn handle_set_held_item( mut clients: Query<&mut Client>, - mut events: EventReader, + mut events: EventReader, ) { for event in events.iter() { if let Ok(mut client) = clients.get_mut(event.client) { @@ -590,8 +600,8 @@ fn convert_hotbar_slot_id(slot_id: u16) -> u16 { #[cfg(test)] mod test { use bevy_app::App; - use valence_protocol::packets::S2cPlayPacket; - use valence_protocol::ItemKind; + use valence_protocol::item::ItemKind; + use valence_protocol::packet::S2cPlayPacket; use super::*; use crate::unit_test::util::scenario_single_client; @@ -636,12 +646,12 @@ mod test { // Make assertions let sent_packets = client_helper.collect_sent()?; - assert_packet_count!(sent_packets, 1, S2cPlayPacket::OpenScreen(_)); - assert_packet_count!(sent_packets, 1, S2cPlayPacket::SetContainerContent(_)); + assert_packet_count!(sent_packets, 1, S2cPlayPacket::OpenScreenS2c(_)); + assert_packet_count!(sent_packets, 1, S2cPlayPacket::InventoryS2c(_)); assert_packet_order!( sent_packets, - S2cPlayPacket::OpenScreen(_), - S2cPlayPacket::SetContainerContent(_) + S2cPlayPacket::OpenScreenS2c(_), + S2cPlayPacket::InventoryS2c(_) ); Ok(()) @@ -680,7 +690,7 @@ mod test { // Make assertions let sent_packets = client_helper.collect_sent()?; - assert_packet_count!(sent_packets, 1, S2cPlayPacket::CloseContainerS2c(_)); + assert_packet_count!(sent_packets, 1, S2cPlayPacket::CloseScreenS2c(_)); Ok(()) } @@ -715,13 +725,13 @@ mod test { // Make assertions assert!(app.world.get::(client_ent).is_none()); let sent_packets = client_helper.collect_sent()?; - assert_packet_count!(sent_packets, 1, S2cPlayPacket::CloseContainerS2c(_)); + assert_packet_count!(sent_packets, 1, S2cPlayPacket::CloseScreenS2c(_)); Ok(()) } #[test] - fn test_should_modify_player_inventory_click_container() -> anyhow::Result<()> { + fn test_should_modify_player_inventory_click_slot() -> anyhow::Result<()> { let mut app = App::new(); let (client_ent, mut client_helper) = scenario_single_client(&mut app); let mut inventory = app @@ -740,13 +750,16 @@ mod test { .get::(client_ent) .unwrap() .inventory_state_id; - client_helper.send(&valence_protocol::packets::c2s::play::ClickContainer { + client_helper.send(&valence_protocol::packet::c2s::play::ClickSlotC2s { window_id: 0, button: 0, - mode: valence_protocol::types::ClickContainerMode::Click, + mode: valence_protocol::packet::c2s::play::click_slot::ClickMode::Click, state_id: VarInt(state_id.0), slot_idx: 20, - slots: vec![(20, None)], + slots: vec![valence_protocol::packet::c2s::play::click_slot::Slot { + idx: 20, + item: None, + }], carried_item: Some(ItemStack::new(ItemKind::Diamond, 2, None)), }); @@ -761,7 +774,7 @@ mod test { assert_packet_count!( sent_packets, 0, - S2cPlayPacket::SetContainerContent(_) | S2cPlayPacket::SetContainerSlot(_) + S2cPlayPacket::InventoryS2c(_) | S2cPlayPacket::ScreenHandlerSlotUpdateS2c(_) ); let inventory = app .world @@ -807,7 +820,11 @@ mod test { let sent_packets = client_helper.collect_sent()?; // because the inventory was modified server side, the client needs to be // updated with the change. - assert_packet_count!(sent_packets, 1, S2cPlayPacket::SetContainerSlot(_)); + assert_packet_count!( + sent_packets, + 1, + S2cPlayPacket::ScreenHandlerSlotUpdateS2c(_) + ); Ok(()) } @@ -831,7 +848,7 @@ mod test { // Make assertions let sent_packets = client_helper.collect_sent()?; - assert_packet_count!(sent_packets, 1, S2cPlayPacket::SetContainerContent(_)); + assert_packet_count!(sent_packets, 1, S2cPlayPacket::InventoryS2c(_)); Ok(()) } @@ -851,7 +868,7 @@ mod test { } #[test] - fn test_should_modify_open_inventory_click_container() -> anyhow::Result<()> { + fn test_should_modify_open_inventory_click_slot() -> anyhow::Result<()> { let mut app = App::new(); let (client_ent, mut client_helper) = scenario_single_client(&mut app); let inventory_ent = set_up_open_inventory(&mut app, client_ent); @@ -867,13 +884,16 @@ mod test { .unwrap() .inventory_state_id; let window_id = app.world.get::(client_ent).unwrap().window_id; - client_helper.send(&valence_protocol::packets::c2s::play::ClickContainer { + client_helper.send(&valence_protocol::packet::c2s::play::ClickSlotC2s { window_id, button: 0, - mode: valence_protocol::types::ClickContainerMode::Click, + mode: valence_protocol::packet::c2s::play::click_slot::ClickMode::Click, state_id: VarInt(state_id.0), slot_idx: 20, - slots: vec![(20, None)], + slots: vec![valence_protocol::packet::c2s::play::click_slot::Slot { + idx: 20, + item: None, + }], carried_item: Some(ItemStack::new(ItemKind::Diamond, 2, None)), }); @@ -888,7 +908,7 @@ mod test { assert_packet_count!( sent_packets, 0, - S2cPlayPacket::SetContainerContent(_) | S2cPlayPacket::SetContainerSlot(_) + S2cPlayPacket::InventoryS2c(_) | S2cPlayPacket::ScreenHandlerSlotUpdateS2c(_) ); let inventory = app .world @@ -931,7 +951,11 @@ mod test { // because the inventory was modified server side, the client needs to be // updated with the change. - assert_packet_count!(sent_packets, 1, S2cPlayPacket::SetContainerSlot(_)); + assert_packet_count!( + sent_packets, + 1, + S2cPlayPacket::ScreenHandlerSlotUpdateS2c(_) + ); let inventory = app .world .get::(inventory_ent) @@ -964,7 +988,7 @@ mod test { // Make assertions let sent_packets = client_helper.collect_sent()?; - assert_packet_count!(sent_packets, 1, S2cPlayPacket::SetContainerContent(_)); + assert_packet_count!(sent_packets, 1, S2cPlayPacket::InventoryS2c(_)); Ok(()) } @@ -983,10 +1007,12 @@ mod test { app.update(); client_helper.clear_sent(); - client_helper.send(&valence_protocol::packets::c2s::play::SetCreativeModeSlot { - slot: 36, - clicked_item: Some(ItemStack::new(ItemKind::Diamond, 2, None)), - }); + client_helper.send( + &valence_protocol::packet::c2s::play::CreativeInventoryActionC2s { + slot: 36, + clicked_item: Some(ItemStack::new(ItemKind::Diamond, 2, None)), + }, + ); app.update(); @@ -1015,10 +1041,12 @@ mod test { app.update(); client_helper.clear_sent(); - client_helper.send(&valence_protocol::packets::c2s::play::SetCreativeModeSlot { - slot: 36, - clicked_item: Some(ItemStack::new(ItemKind::Diamond, 2, None)), - }); + client_helper.send( + &valence_protocol::packet::c2s::play::CreativeInventoryActionC2s { + slot: 36, + clicked_item: Some(ItemStack::new(ItemKind::Diamond, 2, None)), + }, + ); app.update(); @@ -1075,7 +1103,7 @@ mod test { app.update(); client_helper.clear_sent(); - client_helper.send(&valence_protocol::packets::c2s::play::SetHeldItemC2s { slot: 4 }); + client_helper.send(&valence_protocol::packet::c2s::play::UpdateSelectedSlotC2s { slot: 4 }); app.update(); @@ -1090,8 +1118,10 @@ mod test { } mod dropping_items { - use valence_protocol::types::{ClickContainerMode, DiggingStatus}; - use valence_protocol::{BlockFace, BlockPos}; + use valence_protocol::block_pos::BlockPos; + use valence_protocol::packet::c2s::play::click_slot::ClickMode; + use valence_protocol::packet::c2s::play::player_action::Action; + use valence_protocol::types::Direction; use super::*; use crate::client::event::DropItemStack; @@ -1110,10 +1140,10 @@ mod test { app.update(); client_helper.clear_sent(); - client_helper.send(&valence_protocol::packets::c2s::play::PlayerAction { - status: DiggingStatus::DropItem, + client_helper.send(&valence_protocol::packet::c2s::play::PlayerActionC2s { + action: Action::DropItem, position: BlockPos::new(0, 0, 0), - face: BlockFace::Bottom, + direction: Direction::Down, sequence: VarInt(0), }); @@ -1142,7 +1172,11 @@ mod test { ); let sent_packets = client_helper.collect_sent()?; - assert_packet_count!(sent_packets, 0, S2cPlayPacket::SetContainerSlot(_)); + assert_packet_count!( + sent_packets, + 0, + S2cPlayPacket::ScreenHandlerSlotUpdateS2c(_) + ); Ok(()) } @@ -1161,10 +1195,10 @@ mod test { app.update(); client_helper.clear_sent(); - client_helper.send(&valence_protocol::packets::c2s::play::PlayerAction { - status: DiggingStatus::DropItemStack, + client_helper.send(&valence_protocol::packet::c2s::play::PlayerActionC2s { + action: Action::DropAllItems, position: BlockPos::new(0, 0, 0), - face: BlockFace::Bottom, + direction: Direction::Down, sequence: VarInt(0), }); @@ -1206,10 +1240,12 @@ mod test { app.update(); client_helper.clear_sent(); - client_helper.send(&valence_protocol::packets::c2s::play::SetCreativeModeSlot { - slot: -1, - clicked_item: Some(ItemStack::new(ItemKind::IronIngot, 32, None)), - }); + client_helper.send( + &valence_protocol::packet::c2s::play::CreativeInventoryActionC2s { + slot: -1, + clicked_item: Some(ItemStack::new(ItemKind::IronIngot, 32, None)), + }, + ); app.update(); @@ -1245,11 +1281,11 @@ mod test { app.update(); client_helper.clear_sent(); - client_helper.send(&valence_protocol::packets::c2s::play::ClickContainer { + client_helper.send(&valence_protocol::packet::c2s::play::ClickSlotC2s { window_id: 0, slot_idx: -999, button: 0, - mode: ClickContainerMode::Click, + mode: ClickMode::Click, state_id: VarInt(state_id), slots: vec![], carried_item: None, @@ -1298,11 +1334,11 @@ mod test { app.update(); client_helper.clear_sent(); - client_helper.send(&valence_protocol::packets::c2s::play::ClickContainer { + client_helper.send(&valence_protocol::packet::c2s::play::ClickSlotC2s { window_id: 0, slot_idx: 40, button: 0, - mode: ClickContainerMode::DropKey, + mode: ClickMode::DropKey, state_id: VarInt(state_id), slots: vec![], carried_item: None, @@ -1346,11 +1382,11 @@ mod test { app.update(); client_helper.clear_sent(); - client_helper.send(&valence_protocol::packets::c2s::play::ClickContainer { + client_helper.send(&valence_protocol::packet::c2s::play::ClickSlotC2s { window_id: 0, slot_idx: 40, button: 1, // pressing control - mode: ClickContainerMode::DropKey, + mode: ClickMode::DropKey, state_id: VarInt(state_id), slots: vec![], carried_item: None, diff --git a/crates/valence/src/lib.rs b/crates/valence/src/lib.rs index f3a704c..218be40 100644 --- a/crates/valence/src/lib.rs +++ b/crates/valence/src/lib.rs @@ -66,14 +66,17 @@ pub mod prelude { pub use player_list::{PlayerList, PlayerListEntry}; pub use protocol::block::{BlockState, PropName, PropValue}; pub use protocol::ident::Ident; + pub use protocol::item::{ItemKind, ItemStack}; pub use protocol::text::{Color, Text, TextFormat}; pub use protocol::types::GameMode; pub use protocol::username::Username; - pub use protocol::{ident, ItemKind, ItemStack}; pub use server::{EventLoop, NewClientInfo, Server, SharedServer}; pub use uuid::Uuid; pub use valence_nbt::Compound; - pub use valence_protocol::{BlockKind, BlockPos}; + pub use valence_protocol::block::BlockKind; + pub use valence_protocol::block_pos::BlockPos; + pub use valence_protocol::ident; + pub use valence_protocol::packet::s2c::play::particle::Particle; pub use view::{ChunkPos, ChunkView}; use super::*; diff --git a/crates/valence/src/packet.rs b/crates/valence/src/packet.rs index 15aa450..744d518 100644 --- a/crates/valence/src/packet.rs +++ b/crates/valence/src/packet.rs @@ -1,7 +1,8 @@ use std::io::Write; use tracing::warn; -use valence_protocol::{encode_packet, encode_packet_compressed, EncodePacket, PacketEncoder}; +use valence_protocol::codec::{encode_packet, encode_packet_compressed, PacketEncoder}; +use valence_protocol::EncodePacket; pub(crate) trait WritePacket { fn write_packet

(&mut self, packet: &P) diff --git a/crates/valence/src/player_list.rs b/crates/valence/src/player_list.rs index 8942bb0..ed63873 100644 --- a/crates/valence/src/player_list.rs +++ b/crates/valence/src/player_list.rs @@ -7,12 +7,12 @@ use std::mem; use bevy_ecs::prelude::*; use tracing::warn; use uuid::Uuid; -use valence_protocol::packets::s2c::play::{PlayerInfoRemove, SetTabListHeaderAndFooter}; -use valence_protocol::packets::s2c::player_info_update::{ - Actions, Entry as PlayerInfoEntry, PlayerInfoUpdate, +use valence_protocol::packet::s2c::play::player_list::{ + Actions, Entry as PlayerInfoEntry, PlayerListS2c, }; +use valence_protocol::packet::s2c::play::{PlayerListHeaderS2c, PlayerRemoveS2c}; +use valence_protocol::text::Text; use valence_protocol::types::{GameMode, Property}; -use valence_protocol::Text; use crate::client::Client; use crate::packet::{PacketWriter, WritePacket}; @@ -242,14 +242,14 @@ impl PlayerList { .collect(); if !entries.is_empty() { - writer.write_packet(&PlayerInfoUpdate { + writer.write_packet(&PlayerListS2c { actions, entries: entries.into(), }); } if !self.header.is_empty() || !self.footer.is_empty() { - writer.write_packet(&SetTabListHeaderAndFooter { + writer.write_packet(&PlayerListHeaderS2c { header: (&self.header).into(), footer: (&self.footer).into(), }); @@ -610,7 +610,7 @@ pub(crate) fn update_player_list( display_name: entry.display_name.as_ref().map(|t| t.into()), }; - writer.write_packet(&PlayerInfoUpdate { + writer.write_packet(&PlayerListS2c { actions, entries: Cow::Borrowed(&[packet_entry]), }); @@ -638,7 +638,7 @@ pub(crate) fn update_player_list( } if u8::from(actions) != 0 { - writer.write_packet(&PlayerInfoUpdate { + writer.write_packet(&PlayerListS2c { actions, entries: Cow::Borrowed(&[PlayerInfoEntry { player_uuid: uuid, @@ -658,7 +658,7 @@ pub(crate) fn update_player_list( }); if !removed.is_empty() { - writer.write_packet(&PlayerInfoRemove { + writer.write_packet(&PlayerRemoveS2c { uuids: removed.into(), }); } @@ -666,7 +666,7 @@ pub(crate) fn update_player_list( if pl.modified_header_or_footer { pl.modified_header_or_footer = false; - writer.write_packet(&SetTabListHeaderAndFooter { + writer.write_packet(&PlayerListHeaderS2c { header: (&pl.header).into(), footer: (&pl.footer).into(), }); diff --git a/crates/valence/src/server.rs b/crates/valence/src/server.rs index 0d7e3a7..53cd552 100644 --- a/crates/valence/src/server.rs +++ b/crates/valence/src/server.rs @@ -17,8 +17,9 @@ use tokio::runtime::{Handle, Runtime}; use tokio::sync::Semaphore; use uuid::Uuid; use valence_nbt::{compound, Compound, List}; +use valence_protocol::ident; use valence_protocol::types::Property; -use valence_protocol::{ident, Username}; +use valence_protocol::username::Username; use crate::biome::{validate_biomes, Biome, BiomeId}; use crate::client::event::{event_loop_run_criteria, register_client_events}; diff --git a/crates/valence/src/server/connect.rs b/crates/valence/src/server/connect.rs index 251bbe4..049ba23 100644 --- a/crates/valence/src/server/connect.rs +++ b/crates/valence/src/server/connect.rs @@ -21,18 +21,22 @@ use tokio::net::{TcpListener, TcpStream}; use tokio::sync::OwnedSemaphorePermit; use tracing::{error, info, instrument, trace, warn}; use uuid::Uuid; -use valence_protocol::packets::c2s::handshake::HandshakeOwned; -use valence_protocol::packets::c2s::login::{EncryptionResponse, LoginPluginResponse, LoginStart}; -use valence_protocol::packets::c2s::status::{PingRequest, StatusRequest}; -use valence_protocol::packets::s2c::login::{ - DisconnectLogin, EncryptionRequest, LoginPluginRequest, LoginSuccess, SetCompression, -}; -use valence_protocol::packets::s2c::status::{PingResponse, StatusResponse}; -use valence_protocol::types::{HandshakeNextState, Property}; -use valence_protocol::{ - translation_key, Decode, Ident, PacketDecoder, PacketEncoder, RawBytes, Text, Username, VarInt, - MINECRAFT_VERSION, PROTOCOL_VERSION, +use valence_protocol::codec::{PacketDecoder, PacketEncoder}; +use valence_protocol::ident::Ident; +use valence_protocol::packet::c2s::handshake::handshake::NextState; +use valence_protocol::packet::c2s::handshake::HandshakeC2s; +use valence_protocol::packet::c2s::login::{LoginHelloC2s, LoginKeyC2s, LoginQueryResponseC2s}; +use valence_protocol::packet::c2s::status::{QueryPingC2s, QueryRequestC2s}; +use valence_protocol::packet::s2c::login::{ + LoginCompressionS2c, LoginDisconnectS2c, LoginHelloS2c, LoginQueryRequestS2c, LoginSuccessS2c, }; +use valence_protocol::packet::s2c::status::{QueryPongS2c, QueryResponseS2c}; +use valence_protocol::raw_bytes::RawBytes; +use valence_protocol::text::Text; +use valence_protocol::types::Property; +use valence_protocol::username::Username; +use valence_protocol::var_int::VarInt; +use valence_protocol::{translation_key, Decode, MINECRAFT_VERSION, PROTOCOL_VERSION}; use crate::config::{AsyncCallbacks, ConnectionMode, ServerListPing}; use crate::server::connection::InitialConnection; @@ -110,13 +114,25 @@ async fn handle_connection( } } +struct HandshakeData { + protocol_version: i32, + server_address: String, + next_state: NextState, +} + async fn handle_handshake( shared: SharedServer, callbacks: Arc, mut conn: InitialConnection, remote_addr: SocketAddr, ) -> anyhow::Result<()> { - let handshake = conn.recv_packet::().await?; + let handshake = conn.recv_packet::().await?; + + let handshake = HandshakeData { + protocol_version: handshake.protocol_version.0, + server_address: handshake.server_address.to_owned(), + next_state: handshake.next_state, + }; ensure!( matches!(shared.connection_mode(), ConnectionMode::BungeeCord) @@ -125,12 +141,10 @@ async fn handle_handshake( ); match handshake.next_state { - HandshakeNextState::Status => { - handle_status(shared, callbacks, conn, remote_addr, handshake) - .await - .context("error handling status") - } - HandshakeNextState::Login => { + NextState::Status => handle_status(shared, callbacks, conn, remote_addr, handshake) + .await + .context("error handling status"), + NextState::Login => { match handle_login(&shared, callbacks, &mut conn, remote_addr, handshake) .await .context("error handling login")? @@ -157,12 +171,12 @@ async fn handle_status( callbacks: Arc, mut conn: InitialConnection, remote_addr: SocketAddr, - handshake: HandshakeOwned, + handshake: HandshakeData, ) -> anyhow::Result<()> { - conn.recv_packet::().await?; + conn.recv_packet::().await?; match callbacks - .server_list_ping(&shared, remote_addr, handshake.protocol_version.0) + .server_list_ping(&shared, remote_addr, handshake.protocol_version) .await { ServerListPing::Respond { @@ -191,7 +205,7 @@ async fn handle_status( json["favicon"] = Value::String(buf); } - conn.send_packet(&StatusResponse { + conn.send_packet(&QueryResponseS2c { json: &json.to_string(), }) .await?; @@ -199,9 +213,9 @@ async fn handle_status( ServerListPing::Ignore => return Ok(()), } - let PingRequest { payload } = conn.recv_packet().await?; + let QueryPingC2s { payload } = conn.recv_packet().await?; - conn.send_packet(&PingResponse { payload }).await?; + conn.send_packet(&QueryPongS2c { payload }).await?; Ok(()) } @@ -212,14 +226,14 @@ async fn handle_login( callbacks: Arc, conn: &mut InitialConnection, remote_addr: SocketAddr, - handshake: HandshakeOwned, + handshake: HandshakeData, ) -> anyhow::Result> { - if handshake.protocol_version.0 != PROTOCOL_VERSION { + if handshake.protocol_version != PROTOCOL_VERSION { // TODO: send translated disconnect msg? return Ok(None); } - let LoginStart { + let LoginHelloC2s { username, profile_id: _, // TODO } = conn.recv_packet().await?; @@ -236,7 +250,7 @@ async fn handle_login( }; if let Some(threshold) = shared.0.compression_threshold { - conn.send_packet(&SetCompression { + conn.send_packet(&LoginCompressionS2c { threshold: VarInt(threshold as i32), }) .await?; @@ -246,14 +260,14 @@ async fn handle_login( if let Err(reason) = callbacks.login(shared, &info).await { info!("disconnect at login: \"{reason}\""); - conn.send_packet(&DisconnectLogin { + conn.send_packet(&LoginDisconnectS2c { reason: reason.into(), }) .await?; return Ok(None); } - conn.send_packet(&LoginSuccess { + conn.send_packet(&LoginSuccessS2c { uuid: info.uuid, username: info.username.as_str_username(), properties: Default::default(), @@ -273,14 +287,14 @@ pub(super) async fn login_online( ) -> anyhow::Result { let my_verify_token: [u8; 16] = rand::random(); - conn.send_packet(&EncryptionRequest { + conn.send_packet(&LoginHelloS2c { server_id: "", // Always empty public_key: &shared.0.public_key_der, verify_token: &my_verify_token, }) .await?; - let EncryptionResponse { + let LoginKeyC2s { shared_secret, verify_token: encrypted_verify_token, } = conn.recv_packet().await?; @@ -332,7 +346,7 @@ pub(super) async fn login_online( translation_key::MULTIPLAYER_DISCONNECT_UNVERIFIED_USERNAME, [], ); - conn.send_packet(&DisconnectLogin { + conn.send_packet(&LoginDisconnectS2c { reason: reason.into(), }) .await?; @@ -417,7 +431,7 @@ pub(super) async fn login_velocity( let message_id: i32 = 0; // TODO: make this random? // Send Player Info Request into the Plugin Channel - conn.send_packet(&LoginPluginRequest { + conn.send_packet(&LoginQueryRequestS2c { message_id: VarInt(message_id), channel: Ident::new("velocity:player_info").unwrap(), data: RawBytes(&[VELOCITY_MIN_SUPPORTED_VERSION]), @@ -425,7 +439,7 @@ pub(super) async fn login_velocity( .await?; // Get Response - let plugin_response: LoginPluginResponse = conn.recv_packet().await?; + let plugin_response: LoginQueryResponseC2s = conn.recv_packet().await?; ensure!( plugin_response.message_id.0 == message_id, diff --git a/crates/valence/src/server/connection.rs b/crates/valence/src/server/connection.rs index f0d610a..a77cf28 100644 --- a/crates/valence/src/server/connection.rs +++ b/crates/valence/src/server/connection.rs @@ -9,7 +9,8 @@ use tokio::sync::OwnedSemaphorePermit; use tokio::task::JoinHandle; use tokio::time::timeout; use tracing::debug; -use valence_protocol::{DecodePacket, EncodePacket, PacketDecoder, PacketEncoder}; +use valence_protocol::codec::{PacketDecoder, PacketEncoder}; +use valence_protocol::{DecodePacket, EncodePacket}; use crate::client::{Client, ClientConnection}; use crate::server::byte_channel::{ diff --git a/crates/valence/src/unit_test/example.rs b/crates/valence/src/unit_test/example.rs index fedd068..5fc0ae1 100644 --- a/crates/valence/src/unit_test/example.rs +++ b/crates/valence/src/unit_test/example.rs @@ -53,7 +53,7 @@ use crate::unit_test::util::scenario_single_client; /// Some of the tests in this file may be inferior duplicates of real tests. #[cfg(test)] mod tests { - use valence_protocol::packets::S2cPlayPacket; + use valence_protocol::packet::S2cPlayPacket; use super::*; use crate::client::Client; @@ -80,7 +80,7 @@ mod tests { let (client_ent, mut client_helper) = scenario_single_client(&mut app); // Send a packet as the client to the server. - let packet = valence_protocol::packets::c2s::play::SetPlayerPosition { + let packet = valence_protocol::packet::c2s::play::PositionAndOnGroundC2s { position: [12.0, 64.0, 0.0], on_ground: true, }; @@ -123,12 +123,12 @@ mod tests { .expect("client not found"); let sent_packets = client_helper.collect_sent()?; - assert_packet_count!(sent_packets, 1, S2cPlayPacket::OpenScreen(_)); - assert_packet_count!(sent_packets, 1, S2cPlayPacket::SetContainerContent(_)); + assert_packet_count!(sent_packets, 1, S2cPlayPacket::OpenScreenS2c(_)); + assert_packet_count!(sent_packets, 1, S2cPlayPacket::InventoryS2c(_)); assert_packet_order!( sent_packets, - S2cPlayPacket::OpenScreen(_), - S2cPlayPacket::SetContainerContent(_) + S2cPlayPacket::OpenScreenS2c(_), + S2cPlayPacket::InventoryS2c(_) ); Ok(()) diff --git a/crates/valence/src/unit_test/util.rs b/crates/valence/src/unit_test/util.rs index dadbd2a..dfea93f 100644 --- a/crates/valence/src/unit_test/util.rs +++ b/crates/valence/src/unit_test/util.rs @@ -3,8 +3,10 @@ use std::sync::{Arc, Mutex}; use bevy_app::App; use bevy_ecs::prelude::Entity; use bytes::BytesMut; -use valence_protocol::packets::S2cPlayPacket; -use valence_protocol::{EncodePacket, PacketDecoder, PacketEncoder, Username}; +use valence_protocol::codec::{PacketDecoder, PacketEncoder}; +use valence_protocol::packet::S2cPlayPacket; +use valence_protocol::username::Username; +use valence_protocol::EncodePacket; use crate::client::{Client, ClientConnection}; use crate::config::{ConnectionMode, ServerPlugin}; @@ -133,7 +135,7 @@ impl MockClientHelper { /// Inject a packet to be treated as a packet inbound to the server. Panics /// if the packet cannot be sent. - pub fn send(&mut self, packet: &impl EncodePacket) { + pub fn send(&mut self, packet: &(impl EncodePacket + ?Sized)) { self.enc .append_packet(packet) .expect("failed to encode packet"); @@ -179,7 +181,7 @@ pub fn scenario_single_client(app: &mut App) -> (Entity, MockClientHelper) { #[macro_export] macro_rules! assert_packet_order { ($sent_packets:ident, $($packets:pat),+) => {{ - let sent_packets: &Vec = &$sent_packets; + let sent_packets: &Vec = &$sent_packets; let positions = [ $((sent_packets.iter().position(|p| matches!(p, $packets))),)* ]; @@ -190,7 +192,7 @@ macro_rules! assert_packet_order { #[macro_export] macro_rules! assert_packet_count { ($sent_packets:ident, $count:tt, $packet:pat) => {{ - let sent_packets: &Vec = &$sent_packets; + let sent_packets: &Vec = &$sent_packets; let count = sent_packets.iter().filter(|p| matches!(p, $packet)).count(); assert_eq!( count, diff --git a/crates/valence/src/view.rs b/crates/valence/src/view.rs index 85b024f..9290a99 100644 --- a/crates/valence/src/view.rs +++ b/crates/valence/src/view.rs @@ -1,5 +1,5 @@ use glam::DVec3; -use valence_protocol::BlockPos; +use valence_protocol::block_pos::BlockPos; /// The X and Z position of a chunk in an /// [`Instance`](crate::instance::Instance). diff --git a/crates/valence_anvil/src/to_valence.rs b/crates/valence_anvil/src/to_valence.rs index a05f752..d11e09e 100644 --- a/crates/valence_anvil/src/to_valence.rs +++ b/crates/valence_anvil/src/to_valence.rs @@ -1,9 +1,9 @@ use num_integer::{div_ceil, Integer}; use thiserror::Error; use valence::biome::BiomeId; -use valence::instance::Chunk; -use valence::protocol::block::{BlockEntity, BlockEntityKind, BlockKind, PropName, PropValue}; -use valence::protocol::Ident; +use valence::instance::{BlockEntity, Chunk}; +use valence::protocol::block::{BlockEntityKind, BlockKind, PropName, PropValue}; +use valence::protocol::ident::Ident; use valence_nbt::{Compound, List, Value}; #[derive(Clone, Debug, Error)] diff --git a/crates/valence_nbt/src/snbt.rs b/crates/valence_nbt/src/snbt.rs index c75bca3..e664499 100644 --- a/crates/valence_nbt/src/snbt.rs +++ b/crates/valence_nbt/src/snbt.rs @@ -437,10 +437,13 @@ impl<'a> SnbtReader<'a> { /// Assert that the string has no trailing data. /// SNBT is quite similar to JSON, but with some differences. /// See [the wiki](https://minecraft.gamepedia.com/NBT_format#SNBT_format) for more information. +/// /// # Example +/// /// ``` -/// use valence_nbt::snbt::SnbtReader; +/// use valence_nbt::snbt::from_snbt_str; /// use valence_nbt::Value; +/// /// let value = from_snbt_str("1f").unwrap(); /// assert_eq!(value, Value::Float(1.0)); /// ``` diff --git a/crates/valence_protocol/benches/benches.rs b/crates/valence_protocol/benches/benches.rs index 8959f28..18634bf 100644 --- a/crates/valence_protocol/benches/benches.rs +++ b/crates/valence_protocol/benches/benches.rs @@ -1,17 +1,21 @@ +use std::borrow::Cow; use std::time::Duration; use criterion::{black_box, criterion_group, criterion_main, Criterion}; use rand::Rng; use valence_nbt::{compound, List}; +use valence_protocol::array::LengthPrefixedArray; use valence_protocol::block::{BlockKind, BlockState, PropName, PropValue}; -use valence_protocol::packets::s2c::play::{ - ChunkDataAndUpdateLight, ChunkDataAndUpdateLightEncode, SetTabListHeaderAndFooter, SpawnEntity, -}; -use valence_protocol::text::Color; -use valence_protocol::{ - encode_packet, encode_packet_compressed, ByteAngle, Decode, Encode, ItemKind, - LengthPrefixedArray, PacketDecoder, PacketEncoder, TextFormat, VarInt, VarLong, +use valence_protocol::byte_angle::ByteAngle; +use valence_protocol::codec::{ + encode_packet, encode_packet_compressed, PacketDecoder, PacketEncoder, }; +use valence_protocol::item::ItemKind; +use valence_protocol::packet::s2c::play::{ChunkDataS2c, EntitySpawnS2c, PlayerListHeaderS2c}; +use valence_protocol::text::{Color, TextFormat}; +use valence_protocol::var_int::VarInt; +use valence_protocol::var_long::VarLong; +use valence_protocol::{Decode, Encode}; criterion_group! { name = benches; @@ -112,24 +116,24 @@ fn packets(c: &mut Criterion) { const SKY_LIGHT_ARRAYS: [LengthPrefixedArray; 26] = [LengthPrefixedArray([0xff; 2048]); 26]; - let chunk_data_packet = ChunkDataAndUpdateLightEncode { + let chunk_data_packet = ChunkDataS2c { chunk_x: 123, chunk_z: 456, - heightmaps: &compound! { + heightmaps: Cow::Owned(compound! { "MOTION_BLOCKING" => List::Long(vec![123; 256]), - }, + }), blocks_and_biomes: BLOCKS_AND_BIOMES.as_slice(), - block_entities: &[], + block_entities: Cow::Borrowed(&[]), trust_edges: false, - sky_light_mask: &[], - block_light_mask: &[], - empty_sky_light_mask: &[], - empty_block_light_mask: &[], - sky_light_arrays: SKY_LIGHT_ARRAYS.as_slice(), - block_light_arrays: &[], + sky_light_mask: Cow::Borrowed(&[]), + block_light_mask: Cow::Borrowed(&[]), + empty_sky_light_mask: Cow::Borrowed(&[]), + empty_block_light_mask: Cow::Borrowed(&[]), + sky_light_arrays: Cow::Borrowed(SKY_LIGHT_ARRAYS.as_slice()), + block_light_arrays: Cow::Borrowed(&[]), }; - let tab_list_header_footer_packet = SetTabListHeaderAndFooter { + let player_list_header_packet = PlayerListHeaderS2c { header: ("this".italic() + " is the " + "header".bold().color(Color::RED)).into(), footer: ("this".italic() + " is the " @@ -139,7 +143,7 @@ fn packets(c: &mut Criterion) { .into(), }; - let spawn_entity_packet = SpawnEntity { + let spawn_entity_packet = EntitySpawnS2c { entity_id: VarInt(1234), object_uuid: Default::default(), kind: VarInt(5), @@ -162,14 +166,12 @@ fn packets(c: &mut Criterion) { }); }); - c.bench_function("encode_tab_list_header_footer", |b| { + c.bench_function("encode_player_list_header", |b| { b.iter(|| { let encoder = black_box(&mut encoder); encoder.clear(); - encoder - .append_packet(&tab_list_header_footer_packet) - .unwrap(); + encoder.append_packet(&player_list_header_packet).unwrap(); black_box(encoder); }); @@ -199,14 +201,12 @@ fn packets(c: &mut Criterion) { }); }); - c.bench_function("encode_tab_list_header_footer_compressed", |b| { + c.bench_function("encode_player_list_header_compressed", |b| { b.iter(|| { let encoder = black_box(&mut encoder); encoder.clear(); - encoder - .append_packet(&tab_list_header_footer_packet) - .unwrap(); + encoder.append_packet(&player_list_header_packet).unwrap(); black_box(encoder); }); @@ -233,25 +233,21 @@ fn packets(c: &mut Criterion) { let decoder = black_box(&mut decoder); decoder.queue_slice(&packet_buf); - decoder - .try_next_packet::() - .unwrap(); + decoder.try_next_packet::().unwrap(); black_box(decoder); }); }); packet_buf.clear(); - encode_packet(&mut packet_buf, &tab_list_header_footer_packet).unwrap(); + encode_packet(&mut packet_buf, &player_list_header_packet).unwrap(); - c.bench_function("decode_tab_list_header_footer", |b| { + c.bench_function("decode_player_list_header", |b| { b.iter(|| { let decoder = black_box(&mut decoder); decoder.queue_slice(&packet_buf); - decoder - .try_next_packet::() - .unwrap(); + decoder.try_next_packet::().unwrap(); black_box(decoder); }); @@ -260,12 +256,12 @@ fn packets(c: &mut Criterion) { packet_buf.clear(); encode_packet(&mut packet_buf, &spawn_entity_packet).unwrap(); - c.bench_function("decode_spawn_entity", |b| { + c.bench_function("decode_entity_spawn", |b| { b.iter(|| { let decoder = black_box(&mut decoder); decoder.queue_slice(&packet_buf); - decoder.try_next_packet::().unwrap(); + decoder.try_next_packet::().unwrap(); black_box(decoder); }); @@ -283,9 +279,7 @@ fn packets(c: &mut Criterion) { let decoder = black_box(&mut decoder); decoder.queue_slice(&packet_buf); - decoder - .try_next_packet::() - .unwrap(); + decoder.try_next_packet::().unwrap(); black_box(decoder); }); @@ -294,20 +288,18 @@ fn packets(c: &mut Criterion) { packet_buf.clear(); encode_packet_compressed( &mut packet_buf, - &tab_list_header_footer_packet, + &player_list_header_packet, 256, &mut scratch, ) .unwrap(); - c.bench_function("decode_tab_list_header_footer_compressed", |b| { + c.bench_function("decode_player_list_header_compressed", |b| { b.iter(|| { let decoder = black_box(&mut decoder); decoder.queue_slice(&packet_buf); - decoder - .try_next_packet::() - .unwrap(); + decoder.try_next_packet::().unwrap(); black_box(decoder); }); @@ -321,7 +313,7 @@ fn packets(c: &mut Criterion) { let decoder = black_box(&mut decoder); decoder.queue_slice(&packet_buf); - decoder.try_next_packet::().unwrap(); + decoder.try_next_packet::().unwrap(); black_box(decoder); }); diff --git a/crates/valence_protocol/src/array.rs b/crates/valence_protocol/src/array.rs index df4ccc1..c2253fd 100644 --- a/crates/valence_protocol/src/array.rs +++ b/crates/valence_protocol/src/array.rs @@ -2,7 +2,8 @@ use std::io::Write; use anyhow::ensure; -use crate::{Decode, Encode, VarInt}; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; /// A fixed-size array encoded and decoded with a [`VarInt`] length prefix. /// diff --git a/crates/valence_protocol/src/block.rs b/crates/valence_protocol/src/block.rs index 75f5da2..2c81aec 100644 --- a/crates/valence_protocol/src/block.rs +++ b/crates/valence_protocol/src/block.rs @@ -6,10 +6,12 @@ use std::io::Write; use std::iter::FusedIterator; use anyhow::Context; -use valence_nbt::Compound; use valence_protocol_macros::ident_str; -use crate::{Decode, Encode, Ident, ItemKind, Result, VarInt}; +use crate::ident::Ident; +use crate::item::ItemKind; +use crate::var_int::VarInt; +use crate::{Decode, Encode, Result}; include!(concat!(env!("OUT_DIR"), "/block.rs")); @@ -81,34 +83,6 @@ impl Decode<'_> for BlockKind { } } -#[derive(Debug, Clone, PartialEq)] -pub struct BlockEntity { - pub kind: BlockEntityKind, - pub nbt: Compound, -} - -impl BlockEntity { - pub const fn new(kind: BlockEntityKind, nbt: Compound) -> Self { - Self { kind, nbt } - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum BlockFace { - /// -Y - Bottom, - /// +Y - Top, - /// -Z - North, - /// +Z - South, - /// -X - West, - /// +X - East, -} - #[cfg(test)] mod tests { use super::*; diff --git a/crates/valence_protocol/src/block_pos.rs b/crates/valence_protocol/src/block_pos.rs index 1150191..1d28460 100644 --- a/crates/valence_protocol/src/block_pos.rs +++ b/crates/valence_protocol/src/block_pos.rs @@ -2,7 +2,8 @@ use std::io::Write; use anyhow::bail; -use crate::{BlockFace, Decode, Encode}; +use crate::types::Direction; +use crate::{Decode, Encode}; /// Represents an absolute block position in world space. #[derive(Clone, Copy, Default, PartialEq, Eq, Hash, Debug)] @@ -27,20 +28,21 @@ impl BlockPos { /// direction. /// /// ``` - /// use valence_protocol::{BlockFace, BlockPos}; + /// use valence_protocol::block_pos::BlockPos; + /// use valence_protocol::types::Direction; /// /// let pos = BlockPos::new(0, 0, 0); - /// let adj = pos.get_in_direction(BlockFace::South); + /// let adj = pos.get_in_direction(Direction::South); /// assert_eq!(adj, BlockPos::new(0, 0, 1)); /// ``` - pub fn get_in_direction(self, dir: BlockFace) -> BlockPos { + pub fn get_in_direction(self, dir: Direction) -> BlockPos { match dir { - BlockFace::Bottom => BlockPos::new(self.x, self.y - 1, self.z), - BlockFace::Top => BlockPos::new(self.x, self.y + 1, self.z), - BlockFace::North => BlockPos::new(self.x, self.y, self.z - 1), - BlockFace::South => BlockPos::new(self.x, self.y, self.z + 1), - BlockFace::West => BlockPos::new(self.x - 1, self.y, self.z), - BlockFace::East => BlockPos::new(self.x + 1, self.y, self.z), + Direction::Down => BlockPos::new(self.x, self.y - 1, self.z), + Direction::Up => BlockPos::new(self.x, self.y + 1, self.z), + Direction::North => BlockPos::new(self.x, self.y, self.z - 1), + Direction::South => BlockPos::new(self.x, self.y, self.z + 1), + Direction::West => BlockPos::new(self.x - 1, self.y, self.z), + Direction::East => BlockPos::new(self.x + 1, self.y, self.z), } } } diff --git a/crates/valence_protocol/src/bounded.rs b/crates/valence_protocol/src/bounded.rs deleted file mode 100644 index fb1e961..0000000 --- a/crates/valence_protocol/src/bounded.rs +++ /dev/null @@ -1,100 +0,0 @@ -/* -// TODO: implement BoundedFloat when floats are permitted in const generics. - -use std::io::Write; - -use anyhow::ensure; - -use crate::{Decode, Encode, Result}; - -/// An integer with a minimum and maximum value known at compile time. `T` is -/// the underlying integer type. -/// -/// If the value is not in bounds, an error is generated while -/// encoding or decoding. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug)] -pub struct BoundedInt(pub T); - -impl Encode for BoundedInt -where - T: Encode + Clone + Into, -{ - fn encode(&self, w: impl Write) -> Result<()> { - let n = self.0.clone().into(); - - ensure!( - (MIN..=MAX).contains(&n), - "integer is not in bounds while encoding (got {n}, expected {MIN}..={MAX})" - ); - - self.0.encode(w) - } -} - -impl<'a, T, const MIN: i128, const MAX: i128> Decode<'a> for BoundedInt -where - T: Decode<'a> + Clone + Into, -{ - fn decode(r: &mut &'a [u8]) -> Result { - let res = T::decode(r)?; - let n = res.clone().into(); - - ensure!( - (MIN..=MAX).contains(&n), - "integer is not in bounds while decoding (got {n}, expected {MIN}..={MAX})" - ); - - Ok(Self(res)) - } -} - -/// A string with a minimum and maximum character length known at compile time. -/// `S` is the underlying string type which is anything that implements -/// `AsRef`. -/// -/// If the string is not in bounds, an error is generated while -/// encoding or decoding. -/// -/// Note that the length is a count of the _characters_ in the string, not -/// bytes. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug)] -pub struct BoundedString(pub S); - -impl Encode for BoundedString -where - S: AsRef, -{ - fn encode(&self, w: impl Write) -> Result<()> { - let s = self.0.as_ref(); - let cnt = s.chars().count(); - - ensure!( - (MIN..=MAX).contains(&s.chars().count()), - "char count of string is out of bounds while encoding (got {cnt}, expected \ - {MIN}..={MAX})" - ); - - s.encode(w)?; - - Ok(()) - } -} - -impl<'a, S, const MIN: usize, const MAX: usize> Decode<'a> for BoundedString -where - S: Decode<'a> + AsRef, -{ - fn decode(r: &mut &'a [u8]) -> Result { - let s = S::decode(r)?; - let cnt = s.as_ref().chars().count(); - - ensure!( - (MIN..=MAX).contains(&cnt), - "char count of string is out of bounds while decoding (got {cnt}, expected \ - {MIN}..={MAX})" - ); - - Ok(Self(s)) - } -} -*/ diff --git a/crates/valence_protocol/src/codec.rs b/crates/valence_protocol/src/codec.rs index 0269af1..b154bda 100644 --- a/crates/valence_protocol/src/codec.rs +++ b/crates/valence_protocol/src/codec.rs @@ -501,10 +501,10 @@ impl PacketDecoder { mod tests { use super::*; use crate::block_pos::BlockPos; - use crate::entity_meta::PaintingKind; use crate::ident::Ident; use crate::item::{ItemKind, ItemStack}; use crate::text::{Text, TextFormat}; + use crate::tracked_data::PaintingKind; use crate::username::Username; use crate::var_long::VarLong; use crate::Decode; diff --git a/crates/valence_protocol/src/impls.rs b/crates/valence_protocol/src/impls.rs index cfd0d20..1c53559 100644 --- a/crates/valence_protocol/src/impls.rs +++ b/crates/valence_protocol/src/impls.rs @@ -12,7 +12,8 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use uuid::Uuid; use valence_nbt::Compound; -use crate::{Decode, Encode, Result, VarInt, MAX_PACKET_SIZE}; +use crate::var_int::VarInt; +use crate::{Decode, Encode, Result, MAX_PACKET_SIZE}; // ==== Primitive ==== // @@ -22,6 +23,7 @@ impl Encode for bool { } fn write_slice(slice: &[bool], mut w: impl Write) -> io::Result<()> { + // SAFETY: Bools have the same layout as u8. // Bools are guaranteed to have the correct bit pattern. let bytes: &[u8] = unsafe { mem::transmute(slice) }; w.write_all(bytes) diff --git a/crates/valence_protocol/src/item.rs b/crates/valence_protocol/src/item.rs index c2eff14..0b23de2 100644 --- a/crates/valence_protocol/src/item.rs +++ b/crates/valence_protocol/src/item.rs @@ -3,7 +3,9 @@ use std::io::Write; use anyhow::{ensure, Context}; use valence_nbt::Compound; -use crate::{BlockKind, Decode, Encode, Result, VarInt}; +use crate::block::BlockKind; +use crate::var_int::VarInt; +use crate::{Decode, Encode, Result}; include!(concat!(env!("OUT_DIR"), "/item.rs")); diff --git a/crates/valence_protocol/src/lib.rs b/crates/valence_protocol/src/lib.rs index 7bf3b7a..4b2b6f9 100644 --- a/crates/valence_protocol/src/lib.rs +++ b/crates/valence_protocol/src/lib.rs @@ -2,18 +2,21 @@ //! protocol. //! //! The API is centered around the [`Encode`] and [`Decode`] traits. Clientbound -//! and serverbound packets are defined in the [`packets`] module. Packets are +//! and serverbound packets are defined in the [`packet`] module. Packets are //! encoded and decoded using the [`PacketEncoder`] and [`PacketDecoder`] types. //! +//! [`PacketEncoder`]: codec::PacketEncoder +//! [`PacketDecoder`]: codec::PacketDecoder +//! //! # Examples //! //! ``` -//! use valence_protocol::packets::c2s::play::RenameItem; -//! use valence_protocol::{PacketDecoder, PacketEncoder}; +//! use valence_protocol::codec::{PacketDecoder, PacketEncoder}; +//! use valence_protocol::packet::c2s::play::RenameItemC2s; //! //! let mut enc = PacketEncoder::new(); //! -//! let outgoing = RenameItem { +//! let outgoing = RenameItemC2s { //! item_name: "Hello!", //! }; //! @@ -23,7 +26,7 @@ //! //! dec.queue_bytes(enc.take()); //! -//! let incoming = dec.try_next_packet::().unwrap().unwrap(); +//! let incoming = dec.try_next_packet::().unwrap().unwrap(); //! //! assert_eq!(outgoing.item_name, incoming.item_name); //! ``` @@ -72,21 +75,7 @@ use std::io::Write; use std::{fmt, io}; pub use anyhow::{Error, Result}; -pub use array::LengthPrefixedArray; -pub use block::{BlockFace, BlockKind, BlockState}; -pub use block_pos::BlockPos; -pub use byte_angle::ByteAngle; -pub use codec::*; -pub use ident::Ident; -pub use item::{ItemKind, ItemStack}; -pub use raw_bytes::RawBytes; -pub use sound::Sound; -pub use text::{Text, TextFormat}; -pub use username::Username; -pub use uuid::Uuid; -pub use valence_protocol_macros::{Decode, DecodePacket, Encode, EncodePacket}; -pub use var_int::VarInt; -pub use var_long::VarLong; +pub use valence_protocol_macros::{ident_str, Decode, DecodePacket, Encode, EncodePacket}; pub use {uuid, valence_nbt as nbt}; /// The Minecraft protocol version this library currently targets. @@ -96,33 +85,33 @@ pub const PROTOCOL_VERSION: i32 = 761; /// targets. pub const MINECRAFT_VERSION: &str = "1.19.3"; -mod array; +pub mod array; pub mod block; -mod block_pos; -mod bounded; -mod byte_angle; -mod codec; +pub mod block_pos; +pub mod byte_angle; +pub mod codec; pub mod enchant; -pub mod entity_meta; pub mod ident; mod impls; -mod item; -pub mod packets; -mod raw_bytes; +pub mod item; +pub mod packet; +pub mod raw_bytes; pub mod sound; pub mod text; +pub mod tracked_data; pub mod translation_key; pub mod types; pub mod username; pub mod var_int; -mod var_long; +pub mod var_long; /// Used only by proc macros. Not public API. #[doc(hidden)] pub mod __private { pub use anyhow::{anyhow, bail, ensure, Context, Result}; - pub use crate::{Decode, DecodePacket, Encode, EncodePacket, VarInt}; + pub use crate::var_int::VarInt; + pub use crate::{Decode, DecodePacket, Encode, EncodePacket}; } /// The maximum number of bytes in a single Minecraft packet. @@ -175,6 +164,7 @@ pub const MAX_PACKET_SIZE: i32 = 2097152; /// ``` /// /// [macro]: valence_protocol_macros::Encode +/// [`VarInt`]: var_int::VarInt pub trait Encode { /// Writes this object to the provided writer. /// @@ -250,6 +240,7 @@ pub trait Encode { /// ``` /// /// [macro]: valence_protocol_macros::Decode +/// [`VarInt`]: var_int::VarInt pub trait Decode<'a>: Sized { /// Reads this object from the provided byte slice. /// @@ -285,6 +276,7 @@ pub trait Decode<'a>: Sized { /// ``` /// /// [macro]: valence_protocol_macros::DecodePacket +/// [`VarInt`]: var_int::VarInt pub trait EncodePacket: fmt::Debug { /// The packet ID that is written when [`Self::encode_packet`] is called. A /// negative value indicates that the packet ID is not statically known. @@ -292,6 +284,8 @@ pub trait EncodePacket: fmt::Debug { /// Like [`Encode::encode`], but a leading [`VarInt`] packet ID must be /// written first. + /// + /// [`VarInt`]: var_int::VarInt fn encode_packet(&self, w: impl Write) -> Result<()>; } @@ -324,6 +318,7 @@ pub trait EncodePacket: fmt::Debug { /// ``` /// /// [macro]: valence_protocol::DecodePacket +/// [`VarInt`]: var_int::VarInt pub trait DecodePacket<'a>: Sized + fmt::Debug { /// The packet ID that is read when [`Self::decode_packet`] is called. A /// negative value indicates that the packet ID is not statically known. @@ -331,6 +326,8 @@ pub trait DecodePacket<'a>: Sized + fmt::Debug { /// Like [`Decode::decode`], but a leading [`VarInt`] packet ID must be read /// first. + /// + /// [`VarInt`]: var_int::VarInt fn decode_packet(r: &mut &'a [u8]) -> Result; } @@ -361,14 +358,14 @@ mod derive_tests { #[derive(Encode, EncodePacket, Decode, DecodePacket, Debug)] #[packet_id = 5] - struct StructWithGenerics<'z, T: std::fmt::Debug = ()> { + struct StructWithGenerics<'z, T: fmt::Debug = ()> { foo: &'z str, bar: T, } #[derive(Encode, EncodePacket, Decode, DecodePacket, Debug)] #[packet_id = 6] - struct TupleStructWithGenerics<'z, T: std::fmt::Debug = ()>(&'z str, i32, T); + struct TupleStructWithGenerics<'z, T: fmt::Debug = ()>(&'z str, i32, T); #[derive(Encode, EncodePacket, Decode, DecodePacket, Debug)] #[packet_id = 7] @@ -384,7 +381,7 @@ mod derive_tests { #[derive(Encode, EncodePacket, Decode, DecodePacket, Debug)] #[packet_id = 0xbeef] - enum EnumWithGenericsAndTags<'z, T: std::fmt::Debug = ()> { + enum EnumWithGenericsAndTags<'z, T: fmt::Debug = ()> { #[tag = 5] First { foo: &'z str, diff --git a/crates/valence_protocol/src/packets.rs b/crates/valence_protocol/src/packet.rs similarity index 56% rename from crates/valence_protocol/src/packets.rs rename to crates/valence_protocol/src/packet.rs index 48f48b0..45b3787 100644 --- a/crates/valence_protocol/src/packets.rs +++ b/crates/valence_protocol/src/packet.rs @@ -12,12 +12,13 @@ pub use s2c::login::S2cLoginPacket; pub use s2c::play::S2cPlayPacket; pub use s2c::status::S2cStatusPacket; -/// Defines an enum of packets. -macro_rules! packet_enum { +/// Defines an enum of packets and implements `EncodePacket` and `DecodePacket` +/// for each. +macro_rules! packet_group { ( $(#[$attrs:meta])* $enum_name:ident<$enum_life:lifetime> { - $($packet:ident $(<$life:lifetime>)?),* $(,)? + $($packet_id:literal = $packet:ident $(<$life:lifetime>)?),* $(,)? } ) => { $(#[$attrs])* @@ -33,11 +34,41 @@ macro_rules! packet_enum { Self::$packet(p) } } + + impl$(<$life>)? crate::EncodePacket for $packet$(<$life>)? { + const PACKET_ID: i32 = $packet_id; + + #[allow(unused_imports)] + fn encode_packet(&self, mut w: impl std::io::Write) -> crate::Result<()> { + use ::valence_protocol::__private::{Encode, Context, VarInt}; + + VarInt($packet_id) + .encode(&mut w) + .context("failed to encode packet ID")?; + + self.encode(w) + } + } + + impl<$enum_life> crate::DecodePacket<$enum_life> for $packet$(<$life>)? { + const PACKET_ID: i32 = $packet_id; + + #[allow(unused_imports)] + fn decode_packet(r: &mut &$enum_life [u8]) -> ::valence_protocol::__private::Result { + use ::valence_protocol::__private::{Decode, Context, VarInt, ensure}; + + let id = VarInt::decode(r).context("failed to decode packet ID")?.0; + ensure!(id == $packet_id, "unexpected packet ID {} (expected {})", id, $packet_id); + + Self::decode(r) + } + } )* impl<$enum_life> crate::EncodePacket for $enum_name<$enum_life> { fn encode_packet(&self, mut w: impl std::io::Write) -> crate::Result<()> { - use crate::{Encode, VarInt}; + use crate::Encode; + use crate::var_int::VarInt; match self { $( @@ -54,7 +85,8 @@ macro_rules! packet_enum { impl<$enum_life> crate::DecodePacket<$enum_life> for $enum_name<$enum_life> { fn decode_packet(r: &mut &$enum_life [u8]) -> crate::Result { - use crate::{Decode, VarInt}; + use crate::Decode; + use crate::var_int::VarInt; let id = VarInt::decode(r)?.0; Ok(match id { @@ -62,7 +94,7 @@ macro_rules! packet_enum { <$packet as crate::DecodePacket>::PACKET_ID => Self::$packet($packet::decode(r)?), )* - id => anyhow::bail!("unknown packet ID {:#02x} while decoding {}", id, stringify!($enum_name)), + id => anyhow::bail!("unknown packet ID {} while decoding {}", id, stringify!($enum_name)), }) } } @@ -81,7 +113,7 @@ macro_rules! packet_enum { ( $(#[$attrs:meta])* $enum_name:ident { - $($packet:ident),* $(,)? + $($packet_id:literal = $packet:ident),* $(,)? } ) => { $(#[$attrs])* @@ -97,11 +129,41 @@ macro_rules! packet_enum { Self::$packet(p) } } + + impl crate::EncodePacket for $packet { + const PACKET_ID: i32 = $packet_id; + + #[allow(unused_imports)] + fn encode_packet(&self, mut w: impl std::io::Write) -> crate::Result<()> { + use ::valence_protocol::__private::{Encode, Context, VarInt}; + + VarInt($packet_id) + .encode(&mut w) + .context("failed to encode packet ID")?; + + self.encode(w) + } + } + + impl crate::DecodePacket<'_> for $packet { + const PACKET_ID: i32 = $packet_id; + + #[allow(unused_imports)] + fn decode_packet(r: &mut &[u8]) -> ::valence_protocol::__private::Result { + use ::valence_protocol::__private::{Decode, Context, VarInt, ensure}; + + let id = VarInt::decode(r).context("failed to decode packet ID")?.0; + ensure!(id == $packet_id, "unexpected packet ID {} (expected {})", id, $packet_id); + + Self::decode(r) + } + } )* impl crate::EncodePacket for $enum_name { fn encode_packet(&self, mut w: impl std::io::Write) -> crate::Result<()> { - use crate::{Encode, VarInt}; + use crate::Encode; + use crate::var_int::VarInt; match self { $( @@ -118,7 +180,8 @@ macro_rules! packet_enum { impl crate::DecodePacket<'_> for $enum_name { fn decode_packet(r: &mut &[u8]) -> crate::Result { - use crate::{Decode, VarInt}; + use crate::Decode; + use crate::var_int::VarInt; let id = VarInt::decode(r)?.0; Ok(match id { @@ -126,7 +189,7 @@ macro_rules! packet_enum { <$packet as crate::DecodePacket>::PACKET_ID => Self::$packet($packet::decode(r)?), )* - id => anyhow::bail!("unknown packet ID {:#02x} while decoding {}", id, stringify!($enum_name)), + id => anyhow::bail!("unknown packet ID {} while decoding {}", id, stringify!($enum_name)), }) } } diff --git a/crates/valence_protocol/src/packet/c2s.rs b/crates/valence_protocol/src/packet/c2s.rs new file mode 100644 index 0000000..a0f3d0f --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s.rs @@ -0,0 +1,205 @@ +pub mod handshake { + pub use handshake::HandshakeC2s; + + #[allow(clippy::module_inception)] + pub mod handshake; + + packet_group! { + #[derive(Clone)] + C2sHandshakePacket<'a> { + 0 = HandshakeC2s<'a> + } + } +} + +pub mod status { + pub use query_ping::QueryPingC2s; + pub use query_request::QueryRequestC2s; + + pub mod query_ping; + pub mod query_request; + + packet_group! { + #[derive(Clone)] + C2sStatusPacket { + 0 = QueryRequestC2s, + 1 = QueryPingC2s, + } + } +} + +pub mod login { + pub use login_hello::LoginHelloC2s; + pub use login_key::LoginKeyC2s; + pub use login_query_response::LoginQueryResponseC2s; + + pub mod login_hello; + pub mod login_key; + pub mod login_query_response; + + packet_group! { + #[derive(Clone)] + C2sLoginPacket<'a> { + 0 = LoginHelloC2s<'a>, + 1 = LoginKeyC2s<'a>, + 2 = LoginQueryResponseC2s<'a>, + } + } +} + +pub mod play { + pub use advancement_tab::AdvancementTabC2s; + pub use boat_paddle::BoatPaddleStateC2s; + pub use book_update::BookUpdateC2s; + pub use button_click::ButtonClickC2s; + pub use chat_message::ChatMessageC2s; + pub use click_slot::ClickSlotC2s; + pub use client_command::ClientCommandC2s; + pub use client_settings::ClientSettingsC2s; + pub use client_status::ClientStatusC2s; + pub use close_handled_screen::CloseHandledScreenC2s; + pub use command_execution::CommandExecutionC2s; + pub use craft_request::CraftRequestC2s; + pub use creative_inventory_action::CreativeInventoryActionC2s; + pub use custom_payload::CustomPayloadC2s; + pub use hand_swing::HandSwingC2s; + pub use jigsaw_generating::JigsawGeneratingC2s; + pub use keep_alive::KeepAliveC2s; + pub use message_acknowledgment::MessageAcknowledgmentC2s; + pub use pick_from_inventory::PickFromInventoryC2s; + pub use play_pong::PlayPongC2s; + pub use player_action::PlayerActionC2s; + pub use player_input::PlayerInputC2s; + pub use player_interact::PlayerInteractC2s; + pub use player_interact_block::PlayerInteractBlockC2s; + pub use player_interact_item::PlayerInteractItemC2s; + pub use player_move::{FullC2s, LookAndOnGroundC2s, OnGroundOnlyC2s, PositionAndOnGroundC2s}; + pub use player_session::PlayerSessionC2s; + pub use query_block_nbt::QueryBlockNbtC2s; + pub use query_entity_nbt::QueryEntityNbtC2s; + pub use recipe_book_data::RecipeBookDataC2s; + pub use recipe_category_options::RecipeCategoryOptionsC2s; + pub use rename_item::RenameItemC2s; + pub use request_command_completions::RequestCommandCompletionsC2s; + pub use resource_pack_status::ResourcePackStatusC2s; + pub use select_merchant_trade::SelectMerchantTradeC2s; + pub use spectator_teleport::SpectatorTeleportC2s; + pub use teleport_confirm::TeleportConfirmC2s; + pub use update_beacon::UpdateBeaconC2s; + pub use update_command_block::UpdateCommandBlockC2s; + pub use update_command_block_minecart::UpdateCommandBlockMinecartC2s; + pub use update_difficulty::UpdateDifficultyC2s; + pub use update_difficulty_lock::UpdateDifficultyLockC2s; + pub use update_jigsaw::UpdateJigsawC2s; + pub use update_player_abilities::UpdatePlayerAbilitiesC2s; + pub use update_selected_slot::UpdateSelectedSlotC2s; + pub use update_sign::UpdateSignC2s; + pub use update_structure_block::UpdateStructureBlockC2s; + pub use vehicle_move::VehicleMoveC2s; + + pub mod advancement_tab; + pub mod boat_paddle; + pub mod book_update; + pub mod button_click; + pub mod chat_message; + pub mod click_slot; + pub mod client_command; + pub mod client_settings; + pub mod client_status; + pub mod close_handled_screen; + pub mod command_execution; + pub mod craft_request; + pub mod creative_inventory_action; + pub mod custom_payload; + pub mod hand_swing; + pub mod jigsaw_generating; + pub mod keep_alive; + pub mod message_acknowledgment; + pub mod pick_from_inventory; + pub mod play_pong; + pub mod player_action; + pub mod player_input; + pub mod player_interact; + pub mod player_interact_block; + pub mod player_interact_item; + pub mod player_move; + pub mod player_session; + pub mod query_block_nbt; + pub mod query_entity_nbt; + pub mod recipe_book_data; + pub mod recipe_category_options; + pub mod rename_item; + pub mod request_command_completions; + pub mod resource_pack_status; + pub mod select_merchant_trade; + pub mod spectator_teleport; + pub mod teleport_confirm; + pub mod update_beacon; + pub mod update_command_block; + pub mod update_command_block_minecart; + pub mod update_difficulty; + pub mod update_difficulty_lock; + pub mod update_jigsaw; + pub mod update_player_abilities; + pub mod update_selected_slot; + pub mod update_sign; + pub mod update_structure_block; + pub mod vehicle_move; + + packet_group! { + #[derive(Clone)] + C2sPlayPacket<'a> { + 0 = TeleportConfirmC2s, + 1 = QueryBlockNbtC2s, + 2 = UpdateDifficultyC2s, + 3 = MessageAcknowledgmentC2s, + 4 = CommandExecutionC2s<'a>, + 5 = ChatMessageC2s<'a>, + 6 = ClientStatusC2s, + 7 = ClientSettingsC2s<'a>, + 8 = RequestCommandCompletionsC2s<'a>, + 9 = ButtonClickC2s, + 10 = ClickSlotC2s, + 11 = CloseHandledScreenC2s, + 12 = CustomPayloadC2s<'a>, + 13 = BookUpdateC2s<'a>, + 14 = QueryEntityNbtC2s, + 15 = PlayerInteractC2s, + 16 = JigsawGeneratingC2s, + 17 = KeepAliveC2s, + 18 = UpdateDifficultyLockC2s, + 19 = PositionAndOnGroundC2s, + 20 = FullC2s, + 21 = LookAndOnGroundC2s, + 22 = OnGroundOnlyC2s, + 23 = VehicleMoveC2s, + 24 = BoatPaddleStateC2s, + 25 = PickFromInventoryC2s, + 26 = CraftRequestC2s<'a>, + 27 = UpdatePlayerAbilitiesC2s, + 28 = PlayerActionC2s, + 29 = ClientCommandC2s, + 30 = PlayerInputC2s, + 31 = PlayPongC2s, + 32 = PlayerSessionC2s<'a>, + 33 = RecipeCategoryOptionsC2s, + 34 = RecipeBookDataC2s<'a>, + 35 = RenameItemC2s<'a>, + 36 = ResourcePackStatusC2s, + 37 = AdvancementTabC2s<'a>, + 38 = SelectMerchantTradeC2s, + 39 = UpdateBeaconC2s, + 40 = UpdateSelectedSlotC2s, + 41 = UpdateCommandBlockC2s<'a>, + 42 = UpdateCommandBlockMinecartC2s<'a>, + 43 = CreativeInventoryActionC2s, + 44 = UpdateJigsawC2s<'a>, + 45 = UpdateStructureBlockC2s<'a>, + 46 = UpdateSignC2s<'a>, + 47 = HandSwingC2s, + 48 = SpectatorTeleportC2s, + 49 = PlayerInteractBlockC2s, + 50 = PlayerInteractItemC2s + } + } +} diff --git a/crates/valence_protocol/src/packet/c2s/handshake/handshake.rs b/crates/valence_protocol/src/packet/c2s/handshake/handshake.rs new file mode 100644 index 0000000..8158e24 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/handshake/handshake.rs @@ -0,0 +1,18 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct HandshakeC2s<'a> { + pub protocol_version: VarInt, + pub server_address: &'a str, + pub server_port: u16, + pub next_state: NextState, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Encode, Decode)] +pub enum NextState { + #[tag = 1] + Status, + #[tag = 2] + Login, +} diff --git a/crates/valence_protocol/src/packet/c2s/login/login_hello.rs b/crates/valence_protocol/src/packet/c2s/login/login_hello.rs new file mode 100644 index 0000000..368c4b2 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/login/login_hello.rs @@ -0,0 +1,10 @@ +use uuid::Uuid; + +use crate::username::Username; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct LoginHelloC2s<'a> { + pub username: Username<&'a str>, + pub profile_id: Option, +} diff --git a/crates/valence_protocol/src/packet/c2s/login/login_key.rs b/crates/valence_protocol/src/packet/c2s/login/login_key.rs new file mode 100644 index 0000000..f7f1eb2 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/login/login_key.rs @@ -0,0 +1,7 @@ +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct LoginKeyC2s<'a> { + pub shared_secret: &'a [u8], + pub verify_token: &'a [u8], +} diff --git a/crates/valence_protocol/src/packet/c2s/login/login_query_response.rs b/crates/valence_protocol/src/packet/c2s/login/login_query_response.rs new file mode 100644 index 0000000..06cfc4b --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/login/login_query_response.rs @@ -0,0 +1,9 @@ +use crate::raw_bytes::RawBytes; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct LoginQueryResponseC2s<'a> { + pub message_id: VarInt, + pub data: Option>, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/advancement_tab.rs b/crates/valence_protocol/src/packet/c2s/play/advancement_tab.rs new file mode 100644 index 0000000..7ee5201 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/advancement_tab.rs @@ -0,0 +1,8 @@ +use crate::ident::Ident; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub enum AdvancementTabC2s<'a> { + OpenedTab { tab_id: Ident<&'a str> }, + ClosedScreen, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/boat_paddle.rs b/crates/valence_protocol/src/packet/c2s/play/boat_paddle.rs new file mode 100644 index 0000000..b8f359d --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/boat_paddle.rs @@ -0,0 +1,7 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct BoatPaddleStateC2s { + pub left_paddle_turning: bool, + pub right_paddle_turning: bool, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/book_update.rs b/crates/valence_protocol/src/packet/c2s/play/book_update.rs new file mode 100644 index 0000000..9ecc5d9 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/book_update.rs @@ -0,0 +1,9 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct BookUpdateC2s<'a> { + pub slot: VarInt, + pub entries: Vec<&'a str>, + pub title: Option<&'a str>, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/button_click.rs b/crates/valence_protocol/src/packet/c2s/play/button_click.rs new file mode 100644 index 0000000..d218d5f --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/button_click.rs @@ -0,0 +1,7 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct ButtonClickC2s { + pub window_id: i8, + pub button_id: i8, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/chat_message.rs b/crates/valence_protocol/src/packet/c2s/play/chat_message.rs new file mode 100644 index 0000000..1e23ace --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/chat_message.rs @@ -0,0 +1,15 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +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_protocol/src/packet/c2s/play/click_slot.rs b/crates/valence_protocol/src/packet/c2s/play/click_slot.rs new file mode 100644 index 0000000..b69b091 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/click_slot.rs @@ -0,0 +1,31 @@ +use crate::item::ItemStack; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct ClickSlotC2s { + pub window_id: u8, + pub state_id: VarInt, + pub slot_idx: i16, + pub button: i8, + pub mode: ClickMode, + pub slots: 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 Slot { + pub idx: i16, + pub item: Option, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/client_command.rs b/crates/valence_protocol/src/packet/c2s/play/client_command.rs new file mode 100644 index 0000000..f8e400e --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/client_command.rs @@ -0,0 +1,22 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct ClientCommandC2s { + pub entity_id: VarInt, + pub action: Action, + pub jump_boost: VarInt, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum Action { + StartSneaking, + StopSneaking, + LeaveBed, + StartSprinting, + StopSprinting, + StartJumpWithHorse, + StopJumpWithHorse, + OpenHorseInventory, + StartFlyingWithElytra, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/client_settings.rs b/crates/valence_protocol/src/packet/c2s/play/client_settings.rs new file mode 100644 index 0000000..636c44a --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/client_settings.rs @@ -0,0 +1,42 @@ +use bitfield_struct::bitfield; + +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +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_hand: MainHand, + pub enable_text_filtering: bool, + pub allow_server_listings: bool, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum ChatMode { + Enabled, + CommandsOnly, + Hidden, +} + +#[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, Debug, Default, Encode, Decode)] +pub enum MainHand { + Left, + #[default] + Right, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/client_status.rs b/crates/valence_protocol/src/packet/c2s/play/client_status.rs new file mode 100644 index 0000000..d7184e9 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/client_status.rs @@ -0,0 +1,7 @@ +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub enum ClientStatusC2s { + PerformRespawn, + RequestStats, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/close_handled_screen.rs b/crates/valence_protocol/src/packet/c2s/play/close_handled_screen.rs new file mode 100644 index 0000000..75ab6ef --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/close_handled_screen.rs @@ -0,0 +1,6 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct CloseHandledScreenC2s { + pub window_id: i8, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/command_execution.rs b/crates/valence_protocol/src/packet/c2s/play/command_execution.rs new file mode 100644 index 0000000..69f5835 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/command_execution.rs @@ -0,0 +1,21 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +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_protocol/src/packet/c2s/play/craft_request.rs b/crates/valence_protocol/src/packet/c2s/play/craft_request.rs new file mode 100644 index 0000000..5d29d6e --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/craft_request.rs @@ -0,0 +1,9 @@ +use crate::ident::Ident; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct CraftRequestC2s<'a> { + pub window_id: i8, + pub recipe: Ident<&'a str>, + pub make_all: bool, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/creative_inventory_action.rs b/crates/valence_protocol/src/packet/c2s/play/creative_inventory_action.rs new file mode 100644 index 0000000..2e122d2 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/creative_inventory_action.rs @@ -0,0 +1,8 @@ +use crate::item::ItemStack; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct CreativeInventoryActionC2s { + pub slot: i16, + pub clicked_item: Option, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/custom_payload.rs b/crates/valence_protocol/src/packet/c2s/play/custom_payload.rs new file mode 100644 index 0000000..8ed3b93 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/custom_payload.rs @@ -0,0 +1,9 @@ +use crate::ident::Ident; +use crate::raw_bytes::RawBytes; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct CustomPayloadC2s<'a> { + pub channel: Ident<&'a str>, + pub data: RawBytes<'a>, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/hand_swing.rs b/crates/valence_protocol/src/packet/c2s/play/hand_swing.rs new file mode 100644 index 0000000..ca0a11d --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/hand_swing.rs @@ -0,0 +1,7 @@ +use crate::types::Hand; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct HandSwingC2s { + pub hand: Hand, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/jigsaw_generating.rs b/crates/valence_protocol/src/packet/c2s/play/jigsaw_generating.rs new file mode 100644 index 0000000..30ac538 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/jigsaw_generating.rs @@ -0,0 +1,10 @@ +use crate::block_pos::BlockPos; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct JigsawGeneratingC2s { + pub position: BlockPos, + pub levels: VarInt, + pub keep_jigsaws: bool, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/keep_alive.rs b/crates/valence_protocol/src/packet/c2s/play/keep_alive.rs new file mode 100644 index 0000000..2969701 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/keep_alive.rs @@ -0,0 +1,6 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct KeepAliveC2s { + pub id: u64, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/message_acknowledgment.rs b/crates/valence_protocol/src/packet/c2s/play/message_acknowledgment.rs new file mode 100644 index 0000000..dff0245 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/message_acknowledgment.rs @@ -0,0 +1,7 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct MessageAcknowledgmentC2s { + pub message_count: VarInt, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/pick_from_inventory.rs b/crates/valence_protocol/src/packet/c2s/play/pick_from_inventory.rs new file mode 100644 index 0000000..702333d --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/pick_from_inventory.rs @@ -0,0 +1,7 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct PickFromInventoryC2s { + pub slot_to_use: VarInt, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/play_pong.rs b/crates/valence_protocol/src/packet/c2s/play/play_pong.rs new file mode 100644 index 0000000..794dc62 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/play_pong.rs @@ -0,0 +1,6 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct PlayPongC2s { + pub id: i32, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/player_action.rs b/crates/valence_protocol/src/packet/c2s/play/player_action.rs new file mode 100644 index 0000000..0221252 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/player_action.rs @@ -0,0 +1,23 @@ +use crate::block_pos::BlockPos; +use crate::types::Direction; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct PlayerActionC2s { + pub action: Action, + pub position: BlockPos, + pub direction: Direction, + pub sequence: VarInt, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum Action { + StartDestroyBlock, + AbortDestroyBlock, + StopDestroyBlock, + DropAllItems, + DropItem, + ReleaseUseItem, + SwapItemWithOffhand, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/player_input.rs b/crates/valence_protocol/src/packet/c2s/play/player_input.rs new file mode 100644 index 0000000..9121851 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/player_input.rs @@ -0,0 +1,19 @@ +use bitfield_struct::bitfield; + +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct PlayerInputC2s { + pub sideways: f32, + pub forward: f32, + pub flags: Flags, +} + +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct Flags { + pub jump: bool, + pub unmount: bool, + #[bits(6)] + _pad: u8, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/player_interact.rs b/crates/valence_protocol/src/packet/c2s/play/player_interact.rs new file mode 100644 index 0000000..162caa8 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/player_interact.rs @@ -0,0 +1,17 @@ +use crate::types::Hand; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct PlayerInteractC2s { + pub entity_id: VarInt, + pub interact: Interaction, + pub sneaking: bool, +} + +#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode)] +pub enum Interaction { + Interact(Hand), + Attack, + InteractAt { target: [f32; 3], hand: Hand }, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/player_interact_block.rs b/crates/valence_protocol/src/packet/c2s/play/player_interact_block.rs new file mode 100644 index 0000000..78ad602 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/player_interact_block.rs @@ -0,0 +1,14 @@ +use crate::block_pos::BlockPos; +use crate::types::{Direction, Hand}; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct PlayerInteractBlockC2s { + pub hand: Hand, + pub position: BlockPos, + pub face: Direction, + pub cursor_pos: [f32; 3], + pub head_inside_block: bool, + pub sequence: VarInt, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/player_interact_item.rs b/crates/valence_protocol/src/packet/c2s/play/player_interact_item.rs new file mode 100644 index 0000000..19770bb --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/player_interact_item.rs @@ -0,0 +1,9 @@ +use crate::types::Hand; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct PlayerInteractItemC2s { + pub hand: Hand, + pub sequence: VarInt, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/player_move.rs b/crates/valence_protocol/src/packet/c2s/play/player_move.rs new file mode 100644 index 0000000..480cca4 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/player_move.rs @@ -0,0 +1,27 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct PositionAndOnGroundC2s { + pub position: [f64; 3], + pub on_ground: bool, +} + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct FullC2s { + pub position: [f64; 3], + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct LookAndOnGroundC2s { + pub yaw: f32, + pub pitch: f32, + pub on_ground: bool, +} + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct OnGroundOnlyC2s { + pub on_ground: bool, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/player_session.rs b/crates/valence_protocol/src/packet/c2s/play/player_session.rs new file mode 100644 index 0000000..e46e2fc --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/player_session.rs @@ -0,0 +1,12 @@ +use uuid::Uuid; + +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +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_protocol/src/packet/c2s/play/query_block_nbt.rs b/crates/valence_protocol/src/packet/c2s/play/query_block_nbt.rs new file mode 100644 index 0000000..91cb059 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/query_block_nbt.rs @@ -0,0 +1,9 @@ +use crate::block_pos::BlockPos; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct QueryBlockNbtC2s { + pub transaction_id: VarInt, + pub position: BlockPos, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/query_entity_nbt.rs b/crates/valence_protocol/src/packet/c2s/play/query_entity_nbt.rs new file mode 100644 index 0000000..e45f0fc --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/query_entity_nbt.rs @@ -0,0 +1,8 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct QueryEntityNbtC2s { + pub transaction_id: VarInt, + pub entity_id: VarInt, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/recipe_book_data.rs b/crates/valence_protocol/src/packet/c2s/play/recipe_book_data.rs new file mode 100644 index 0000000..b7f446f --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/recipe_book_data.rs @@ -0,0 +1,7 @@ +use crate::ident::Ident; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct RecipeBookDataC2s<'a> { + pub recipe_id: Ident<&'a str>, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/recipe_category_options.rs b/crates/valence_protocol/src/packet/c2s/play/recipe_category_options.rs new file mode 100644 index 0000000..351e96d --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/recipe_category_options.rs @@ -0,0 +1,16 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +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_protocol/src/packet/c2s/play/rename_item.rs b/crates/valence_protocol/src/packet/c2s/play/rename_item.rs new file mode 100644 index 0000000..996f078 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/rename_item.rs @@ -0,0 +1,6 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct RenameItemC2s<'a> { + pub item_name: &'a str, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/request_command_completions.rs b/crates/valence_protocol/src/packet/c2s/play/request_command_completions.rs new file mode 100644 index 0000000..c53356e --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/request_command_completions.rs @@ -0,0 +1,8 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct RequestCommandCompletionsC2s<'a> { + pub transaction_id: VarInt, + pub text: &'a str, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/resource_pack_status.rs b/crates/valence_protocol/src/packet/c2s/play/resource_pack_status.rs new file mode 100644 index 0000000..7860b08 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/resource_pack_status.rs @@ -0,0 +1,9 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub enum ResourcePackStatusC2s { + SuccessfullyLoaded, + Declined, + FailedDownload, + Accepted, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/select_merchant_trade.rs b/crates/valence_protocol/src/packet/c2s/play/select_merchant_trade.rs new file mode 100644 index 0000000..c87a089 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/select_merchant_trade.rs @@ -0,0 +1,7 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct SelectMerchantTradeC2s { + pub selected_slot: VarInt, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/spectator_teleport.rs b/crates/valence_protocol/src/packet/c2s/play/spectator_teleport.rs new file mode 100644 index 0000000..0eb65f4 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/spectator_teleport.rs @@ -0,0 +1,8 @@ +use uuid::Uuid; + +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct SpectatorTeleportC2s { + pub target: Uuid, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/teleport_confirm.rs b/crates/valence_protocol/src/packet/c2s/play/teleport_confirm.rs new file mode 100644 index 0000000..820d837 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/teleport_confirm.rs @@ -0,0 +1,7 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct TeleportConfirmC2s { + pub teleport_id: VarInt, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/update_beacon.rs b/crates/valence_protocol/src/packet/c2s/play/update_beacon.rs new file mode 100644 index 0000000..d1e4826 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/update_beacon.rs @@ -0,0 +1,9 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct UpdateBeaconC2s { + // TODO: extract effect IDs? + pub primary_effect: Option, + pub secondary_effect: Option, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/update_command_block.rs b/crates/valence_protocol/src/packet/c2s/play/update_command_block.rs new file mode 100644 index 0000000..e2dabe1 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/update_command_block.rs @@ -0,0 +1,29 @@ +use bitfield_struct::bitfield; + +use crate::block_pos::BlockPos; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct UpdateCommandBlockC2s<'a> { + pub position: BlockPos, + pub command: &'a str, + pub mode: Mode, + pub flags: Flags, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum Mode { + Sequence, + Auto, + Redstone, +} + +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct Flags { + pub track_output: bool, + pub conditional: bool, + pub automatic: bool, + #[bits(5)] + _pad: u8, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/update_command_block_minecart.rs b/crates/valence_protocol/src/packet/c2s/play/update_command_block_minecart.rs new file mode 100644 index 0000000..b234098 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/update_command_block_minecart.rs @@ -0,0 +1,9 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct UpdateCommandBlockMinecartC2s<'a> { + pub entity_id: VarInt, + pub command: &'a str, + pub track_output: bool, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/update_difficulty.rs b/crates/valence_protocol/src/packet/c2s/play/update_difficulty.rs new file mode 100644 index 0000000..78db016 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/update_difficulty.rs @@ -0,0 +1,7 @@ +use crate::types::Difficulty; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub struct UpdateDifficultyC2s { + pub difficulty: Difficulty, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/update_difficulty_lock.rs b/crates/valence_protocol/src/packet/c2s/play/update_difficulty_lock.rs new file mode 100644 index 0000000..979df8e --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/update_difficulty_lock.rs @@ -0,0 +1,6 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct UpdateDifficultyLockC2s { + pub locked: bool, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/update_jigsaw.rs b/crates/valence_protocol/src/packet/c2s/play/update_jigsaw.rs new file mode 100644 index 0000000..83321e9 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/update_jigsaw.rs @@ -0,0 +1,13 @@ +use crate::block_pos::BlockPos; +use crate::ident::Ident; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct UpdateJigsawC2s<'a> { + pub position: BlockPos, + pub name: Ident<&'a str>, + pub target: Ident<&'a str>, + pub pool: Ident<&'a str>, + pub final_state: &'a str, + pub joint_type: &'a str, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/update_player_abilities.rs b/crates/valence_protocol/src/packet/c2s/play/update_player_abilities.rs new file mode 100644 index 0000000..3b248ab --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/update_player_abilities.rs @@ -0,0 +1,9 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub enum UpdatePlayerAbilitiesC2s { + #[tag = 0b00] + StopFlying, + #[tag = 0b10] + StartFlying, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/update_selected_slot.rs b/crates/valence_protocol/src/packet/c2s/play/update_selected_slot.rs new file mode 100644 index 0000000..590da36 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/update_selected_slot.rs @@ -0,0 +1,6 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct UpdateSelectedSlotC2s { + pub slot: i16, +} diff --git a/crates/valence_protocol/src/packet/c2s/play/update_sign.rs b/crates/valence_protocol/src/packet/c2s/play/update_sign.rs new file mode 100644 index 0000000..2b129a0 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/update_sign.rs @@ -0,0 +1,8 @@ +use crate::block_pos::BlockPos; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct UpdateSignC2s<'a> { + pub position: BlockPos, + pub lines: [&'a str; 4], +} diff --git a/crates/valence_protocol/src/packet/c2s/play/update_structure_block.rs b/crates/valence_protocol/src/packet/c2s/play/update_structure_block.rs new file mode 100644 index 0000000..a523d29 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/update_structure_block.rs @@ -0,0 +1,62 @@ +use bitfield_struct::bitfield; + +use crate::block_pos::BlockPos; +use crate::var_long::VarLong; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +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_protocol/src/packet/c2s/play/vehicle_move.rs b/crates/valence_protocol/src/packet/c2s/play/vehicle_move.rs new file mode 100644 index 0000000..b7e05d0 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/play/vehicle_move.rs @@ -0,0 +1,8 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct VehicleMoveC2s { + pub position: [f64; 3], + pub yaw: f32, + pub pitch: f32, +} diff --git a/crates/valence_protocol/src/packet/c2s/status/query_ping.rs b/crates/valence_protocol/src/packet/c2s/status/query_ping.rs new file mode 100644 index 0000000..aef8910 --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/status/query_ping.rs @@ -0,0 +1,6 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct QueryPingC2s { + pub payload: u64, +} diff --git a/crates/valence_protocol/src/packet/c2s/status/query_request.rs b/crates/valence_protocol/src/packet/c2s/status/query_request.rs new file mode 100644 index 0000000..6daf3ea --- /dev/null +++ b/crates/valence_protocol/src/packet/c2s/status/query_request.rs @@ -0,0 +1,4 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct QueryRequestC2s; diff --git a/crates/valence_protocol/src/packet/s2c.rs b/crates/valence_protocol/src/packet/s2c.rs new file mode 100644 index 0000000..fc2987e --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c.rs @@ -0,0 +1,367 @@ +pub mod status { + pub use query_pong::QueryPongS2c; + pub use query_response::QueryResponseS2c; + + pub mod query_pong; + pub mod query_response; + + packet_group! { + #[derive(Clone)] + S2cStatusPacket<'a> { + 0 = QueryResponseS2c<'a>, + 1 = QueryPongS2c, + } + } +} + +pub mod login { + pub use login_compression::LoginCompressionS2c; + pub use login_disconnect::LoginDisconnectS2c; + pub use login_hello::LoginHelloS2c; + pub use login_query_request::LoginQueryRequestS2c; + pub use login_success::LoginSuccessS2c; + + pub mod login_compression; + pub mod login_disconnect; + pub mod login_hello; + pub mod login_query_request; + pub mod login_success; + + packet_group! { + #[derive(Clone)] + S2cLoginPacket<'a> { + 0 = LoginDisconnectS2c<'a>, + 1 = LoginHelloS2c<'a>, + 2 = LoginSuccessS2c<'a>, + 3 = LoginCompressionS2c, + 4 = LoginQueryRequestS2c<'a>, + } + } +} + +pub mod play { + pub use advancement_update::AdvancementUpdateS2c; + pub use block_breaking_progress::BlockBreakingProgressS2c; + pub use block_entity_update::BlockEntityUpdateS2c; + pub use block_event::BlockEventS2c; + pub use block_update::BlockUpdateS2c; + pub use boss_bar::BossBarS2c; + pub use chat_message::ChatMessageS2c; + pub use chat_suggestions::ChatSuggestionsS2c; + pub use chunk_data::ChunkDataS2c; + pub use chunk_delta_update::ChunkDeltaUpdateS2c; + pub use chunk_load_distance::ChunkLoadDistanceS2c; + pub use chunk_render_distance_center::ChunkRenderDistanceCenterS2c; + pub use clear_titles::ClearTitlesS2c; + pub use close_screen::CloseScreenS2c; + pub use command_suggestions::CommandSuggestionsS2c; + pub use command_tree::CommandTreeS2c; + pub use cooldown_update::CooldownUpdateS2c; + pub use craft_failed_response::CraftFailedResponseS2c; + pub use custom_payload::CustomPayloadS2c; + pub use death_message::DeathMessageS2c; + pub use difficulty::DifficultyS2c; + pub use disconnect::DisconnectS2c; + pub use end_combat::EndCombatS2c; + pub use enter_combat::EnterCombatS2c; + pub use entities_destroy::EntitiesDestroyS2c; + pub use entity::{MoveRelativeS2c, RotateAndMoveRelativeS2c, RotateS2c}; + pub use entity_animation::EntityAnimationS2c; + pub use entity_attach::EntityAttachS2c; + pub use entity_attributes::EntityAttributesS2c; + pub use entity_equipment_update::EntityEquipmentUpdateS2c; + pub use entity_passengers_set::EntityPassengersSetS2c; + pub use entity_position::EntityPositionS2c; + pub use entity_set_head_yaw::EntitySetHeadYawS2c; + pub use entity_spawn::EntitySpawnS2c; + pub use entity_status::EntityStatusS2c; + pub use entity_status_effect::EntityStatusEffectS2c; + pub use entity_tracker_update::EntityTrackerUpdateS2c; + pub use entity_velocity_update::EntityVelocityUpdateS2c; + pub use experience_bar_update::ExperienceBarUpdateS2c; + pub use experience_orb_spawn::ExperienceOrbSpawnS2c; + pub use explosion::ExplosionS2c; + pub use features::FeaturesS2c; + pub use game_join::GameJoinS2c; + pub use game_message::GameMessageS2c; + pub use game_state_change::GameStateChangeS2c; + pub use health_update::HealthUpdateS2c; + pub use inventory::InventoryS2c; + pub use item_pickup_animation::ItemPickupAnimationS2c; + pub use keep_alive::KeepAliveS2c; + pub use light_update::LightUpdateS2c; + pub use look_at::LookAtS2c; + pub use map_update::MapUpdateS2c; + pub use nbt_query_response::NbtQueryResponseS2c; + pub use open_horse_screen::OpenHorseScreenS2c; + pub use open_screen::OpenScreenS2c; + pub use open_written_book::OpenWrittenBookS2c; + pub use overlay_message::OverlayMessageS2c; + pub use particle::ParticleS2c; + pub use play_ping::PlayPingS2c; + pub use play_sound::PlaySoundS2c; + pub use play_sound_from_entity::PlaySoundFromEntityS2c; + pub use player_abilities::PlayerAbilitiesS2c; + pub use player_action_response::PlayerActionResponseS2c; + pub use player_list::PlayerListS2c; + pub use player_list_header::PlayerListHeaderS2c; + pub use player_position_look::PlayerPositionLookS2c; + pub use player_remove::PlayerRemoveS2c; + pub use player_respawn::PlayerRespawnS2c; + pub use player_spawn::PlayerSpawnS2c; + pub use player_spawn_position::PlayerSpawnPositionS2c; + pub use profileless_chat_message::ProfilelessChatMessageS2c; + pub use remove_entity_status_effect::RemoveEntityStatusEffectS2c; + pub use remove_message::RemoveMessageS2c; + pub use resource_pack_send::ResourcePackSendS2c; + pub use scoreboard_display::ScoreboardDisplayS2c; + pub use scoreboard_objective_update::ScoreboardObjectiveUpdateS2c; + pub use scoreboard_player_update::ScoreboardPlayerUpdateS2c; + pub use screen_handler_property_update::ScreenHandlerPropertyUpdateS2c; + pub use screen_handler_slot_update::ScreenHandlerSlotUpdateS2c; + pub use select_advancements_tab::SelectAdvancementsTabS2c; + pub use server_metadata::ServerMetadataS2c; + pub use set_camera_entity::SetCameraEntityS2c; + pub use set_trade_offers::SetTradeOffersS2c; + pub use sign_editor_open::SignEditorOpen; + pub use simulation_distance::SimulationDistanceS2c; + pub use statistics::StatisticsS2c; + pub use stop_sound::StopSoundS2c; + pub use subtitle::SubtitleS2c; + pub use synchronize_recipes::SynchronizeRecipesS2c; + pub use synchronize_tags::SynchronizeTagsS2c; + pub use team::TeamS2c; + pub use title::TitleS2c; + pub use title_fade::TitleFadeS2c; + pub use unload_chunk::UnloadChunkS2c; + pub use unlock_recipes::UnlockRecipesS2c; + pub use update_selected_slot::UpdateSelectedSlotS2c; + pub use vehicle_move::VehicleMoveS2c; + pub use world_border_center_changed::WorldBorderCenterChangedS2c; + pub use world_border_initialize::WorldBorderInitializeS2c; + pub use world_border_interpolate_size::WorldBorderInterpolateSizeS2c; + pub use world_border_size_changed::WorldBorderSizeChangedS2c; + pub use world_border_warning_blocks_changed::WorldBorderWarningBlocksChangedS2c; + pub use world_border_warning_time_changed::WorldBorderWarningTimeChangedS2c; + pub use world_event::WorldEventS2c; + pub use world_time_update::WorldTimeUpdateS2c; + + pub mod advancement_update; + pub mod block_breaking_progress; + pub mod block_entity_update; + pub mod block_event; + pub mod block_update; + pub mod boss_bar; + pub mod chat_message; + pub mod chat_suggestions; + pub mod chunk_data; + pub mod chunk_delta_update; + pub mod chunk_load_distance; + pub mod chunk_render_distance_center; + pub mod clear_titles; + pub mod close_screen; + pub mod command_suggestions; + pub mod command_tree; + pub mod cooldown_update; + pub mod craft_failed_response; + pub mod custom_payload; + pub mod death_message; + pub mod difficulty; + pub mod disconnect; + pub mod end_combat; + pub mod enter_combat; + pub mod entities_destroy; + pub mod entity; + pub mod entity_animation; + pub mod entity_attach; + pub mod entity_attributes; + pub mod entity_equipment_update; + pub mod entity_passengers_set; + pub mod entity_position; + pub mod entity_set_head_yaw; + pub mod entity_spawn; + pub mod entity_status; + pub mod entity_status_effect; + pub mod entity_tracker_update; + pub mod entity_velocity_update; + pub mod experience_bar_update; + pub mod experience_orb_spawn; + pub mod explosion; + pub mod features; + pub mod game_join; + pub mod game_message; + pub mod game_state_change; + pub mod health_update; + pub mod inventory; + pub mod item_pickup_animation; + pub mod keep_alive; + pub mod light_update; + pub mod look_at; + pub mod map_update; + pub mod nbt_query_response; + pub mod open_horse_screen; + pub mod open_screen; + pub mod open_written_book; + pub mod overlay_message; + pub mod particle; + pub mod play_ping; + pub mod play_sound; + pub mod play_sound_from_entity; + pub mod player_abilities; + pub mod player_action_response; + pub mod player_list; + pub mod player_list_header; + pub mod player_position_look; + pub mod player_remove; + pub mod player_respawn; + pub mod player_spawn; + pub mod player_spawn_position; + pub mod profileless_chat_message; + pub mod remove_entity_status_effect; + pub mod remove_message; + pub mod resource_pack_send; + pub mod scoreboard_display; + pub mod scoreboard_objective_update; + pub mod scoreboard_player_update; + pub mod screen_handler_property_update; + pub mod screen_handler_slot_update; + pub mod select_advancements_tab; + pub mod server_metadata; + pub mod set_camera_entity; + pub mod set_trade_offers; + pub mod sign_editor_open; + pub mod simulation_distance; + pub mod statistics; + pub mod stop_sound; + pub mod subtitle; + pub mod synchronize_recipes; + pub mod synchronize_tags; + pub mod team; + pub mod title; + pub mod title_fade; + pub mod unload_chunk; + pub mod unlock_recipes; + pub mod update_selected_slot; + pub mod vehicle_move; + pub mod world_border_center_changed; + pub mod world_border_initialize; + pub mod world_border_interpolate_size; + pub mod world_border_size_changed; + pub mod world_border_warning_blocks_changed; + pub mod world_border_warning_time_changed; + pub mod world_event; + pub mod world_time_update; + + packet_group! { + #[derive(Clone)] + S2cPlayPacket<'a> { + 0 = EntitySpawnS2c, + 1 = ExperienceOrbSpawnS2c, + 2 = PlayerSpawnS2c, + 3 = EntityAnimationS2c, + 4 = StatisticsS2c, + 5 = PlayerActionResponseS2c, + 6 = BlockBreakingProgressS2c, + 7 = BlockEntityUpdateS2c<'a>, + 8 = BlockEventS2c, + 9 = BlockUpdateS2c, + 10 = BossBarS2c, + 11 = DifficultyS2c, + 12 = ClearTitlesS2c, + 13 = CommandSuggestionsS2c<'a>, + 14 = CommandTreeS2c<'a>, + 15 = CloseScreenS2c, + 16 = InventoryS2c<'a>, + 17 = ScreenHandlerPropertyUpdateS2c, + 18 = ScreenHandlerSlotUpdateS2c<'a>, + 19 = CooldownUpdateS2c, + 20 = ChatSuggestionsS2c<'a>, + 21 = CustomPayloadS2c<'a>, + 22 = RemoveMessageS2c<'a>, + 23 = DisconnectS2c<'a>, + 24 = ProfilelessChatMessageS2c<'a>, + 25 = EntityStatusS2c, + 26 = ExplosionS2c<'a>, + 27 = UnloadChunkS2c, + 28 = GameStateChangeS2c, + 29 = OpenHorseScreenS2c, + 30 = WorldBorderInitializeS2c, + 31 = KeepAliveS2c, + 32 = ChunkDataS2c<'a>, + 33 = WorldEventS2c, + 34 = LightUpdateS2c, + 35 = ParticleS2c<'a>, + 36 = GameJoinS2c<'a>, + 37 = MapUpdateS2c<'a>, + 38 = SetTradeOffersS2c, + 39 = MoveRelativeS2c, + 40 = RotateAndMoveRelativeS2c, + 41 = RotateS2c, + 42 = VehicleMoveS2c, + 43 = OpenWrittenBookS2c, + 44 = OpenScreenS2c<'a>, + 45 = SignEditorOpen, + 46 = PlayPingS2c, + 47 = CraftFailedResponseS2c<'a>, + 48 = PlayerAbilitiesS2c, + 49 = ChatMessageS2c<'a>, + 50 = EndCombatS2c, + 51 = EnterCombatS2c, + 52 = DeathMessageS2c<'a>, + 53 = PlayerRemoveS2c<'a>, + 54 = PlayerListS2c<'a>, + 55 = LookAtS2c, + 56 = PlayerPositionLookS2c, + 57 = UnlockRecipesS2c<'a>, + 58 = EntitiesDestroyS2c<'a>, + 59 = RemoveEntityStatusEffectS2c, + 60 = ResourcePackSendS2c<'a>, + 61 = PlayerRespawnS2c<'a>, + 62 = EntitySetHeadYawS2c, + 63 = ChunkDeltaUpdateS2c<'a>, + 64 = SelectAdvancementsTabS2c<'a>, + 65 = ServerMetadataS2c<'a>, + 66 = OverlayMessageS2c<'a>, + 67 = WorldBorderCenterChangedS2c, + 68 = WorldBorderInterpolateSizeS2c, + 69 = WorldBorderSizeChangedS2c, + 70 = WorldBorderWarningTimeChangedS2c, + 71 = WorldBorderWarningBlocksChangedS2c, + 72 = SetCameraEntityS2c, + 73 = UpdateSelectedSlotS2c, + 74 = ChunkRenderDistanceCenterS2c, + 75 = ChunkLoadDistanceS2c, + 76 = PlayerSpawnPositionS2c, + 77 = ScoreboardDisplayS2c<'a>, + 78 = EntityTrackerUpdateS2c<'a>, + 79 = EntityAttachS2c, + 80 = EntityVelocityUpdateS2c, + 81 = EntityEquipmentUpdateS2c, + 82 = ExperienceBarUpdateS2c, + 83 = HealthUpdateS2c, + 84 = ScoreboardObjectiveUpdateS2c<'a>, + 85 = EntityPassengersSetS2c, + 86 = TeamS2c<'a>, + 87 = ScoreboardPlayerUpdateS2c<'a>, + 88 = SimulationDistanceS2c, + 89 = SubtitleS2c<'a>, + 90 = WorldTimeUpdateS2c, + 91 = TitleS2c<'a>, + 92 = TitleFadeS2c, + 93 = PlaySoundFromEntityS2c, + 94 = PlaySoundS2c<'a>, + 95 = StopSoundS2c<'a>, + 96 = GameMessageS2c<'a>, + 97 = PlayerListHeaderS2c<'a>, + 98 = NbtQueryResponseS2c, + 99 = ItemPickupAnimationS2c, + 100 = EntityPositionS2c, + 101 = AdvancementUpdateS2c<'a>, + 102 = EntityAttributesS2c<'a>, + 103 = FeaturesS2c<'a>, + 104 = EntityStatusEffectS2c, + 105 = SynchronizeRecipesS2c<'a>, + 106 = SynchronizeTagsS2c<'a>, + } + } +} diff --git a/crates/valence_protocol/src/packet/s2c/login/login_compression.rs b/crates/valence_protocol/src/packet/s2c/login/login_compression.rs new file mode 100644 index 0000000..28de385 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/login/login_compression.rs @@ -0,0 +1,7 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct LoginCompressionS2c { + pub threshold: VarInt, +} diff --git a/crates/valence_protocol/src/packet/s2c/login/login_disconnect.rs b/crates/valence_protocol/src/packet/s2c/login/login_disconnect.rs new file mode 100644 index 0000000..ec8392e --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/login/login_disconnect.rs @@ -0,0 +1,9 @@ +use std::borrow::Cow; + +use crate::text::Text; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct LoginDisconnectS2c<'a> { + pub reason: Cow<'a, Text>, +} diff --git a/crates/valence_protocol/src/packet/s2c/login/login_hello.rs b/crates/valence_protocol/src/packet/s2c/login/login_hello.rs new file mode 100644 index 0000000..89fa917 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/login/login_hello.rs @@ -0,0 +1,8 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct LoginHelloS2c<'a> { + pub server_id: &'a str, + pub public_key: &'a [u8], + pub verify_token: &'a [u8], +} diff --git a/crates/valence_protocol/src/packet/s2c/login/login_query_request.rs b/crates/valence_protocol/src/packet/s2c/login/login_query_request.rs new file mode 100644 index 0000000..7917c56 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/login/login_query_request.rs @@ -0,0 +1,11 @@ +use crate::ident::Ident; +use crate::raw_bytes::RawBytes; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct LoginQueryRequestS2c<'a> { + pub message_id: VarInt, + pub channel: Ident<&'a str>, + pub data: RawBytes<'a>, +} diff --git a/crates/valence_protocol/src/packet/s2c/login/login_success.rs b/crates/valence_protocol/src/packet/s2c/login/login_success.rs new file mode 100644 index 0000000..c7f0923 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/login/login_success.rs @@ -0,0 +1,14 @@ +use std::borrow::Cow; + +use uuid::Uuid; + +use crate::types::Property; +use crate::username::Username; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct LoginSuccessS2c<'a> { + pub uuid: Uuid, + pub username: Username<&'a str>, + pub properties: Cow<'a, [Property]>, +} diff --git a/crates/valence_protocol/src/packets/s2c/update_advancements.rs b/crates/valence_protocol/src/packet/s2c/play/advancement_update.rs similarity index 92% rename from crates/valence_protocol/src/packets/s2c/update_advancements.rs rename to crates/valence_protocol/src/packet/s2c/play/advancement_update.rs index bb9c0a0..d0be183 100644 --- a/crates/valence_protocol/src/packets/s2c/update_advancements.rs +++ b/crates/valence_protocol/src/packet/s2c/play/advancement_update.rs @@ -1,11 +1,14 @@ use std::borrow::Cow; use std::io::Write; -use crate::{Decode, DecodePacket, Encode, EncodePacket, Ident, ItemStack, Text, VarInt}; +use crate::ident::Ident; +use crate::item::ItemStack; +use crate::text::Text; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; -#[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] -#[packet_id = 0x65] -pub struct UpdateAdvancements<'a> { +#[derive(Clone, Debug, Encode, Decode)] +pub struct AdvancementUpdateS2c<'a> { pub reset: bool, pub advancement_mapping: Vec<(Ident<&'a str>, Advancement<'a>)>, pub identifiers: Vec>, diff --git a/crates/valence_protocol/src/packet/s2c/play/block_breaking_progress.rs b/crates/valence_protocol/src/packet/s2c/play/block_breaking_progress.rs new file mode 100644 index 0000000..0f7a79d --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/block_breaking_progress.rs @@ -0,0 +1,10 @@ +use crate::block_pos::BlockPos; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct BlockBreakingProgressS2c { + pub entity_id: VarInt, + pub position: BlockPos, + pub destroy_stage: u8, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/block_entity_update.rs b/crates/valence_protocol/src/packet/s2c/play/block_entity_update.rs new file mode 100644 index 0000000..e7b9712 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/block_entity_update.rs @@ -0,0 +1,14 @@ +use std::borrow::Cow; + +use valence_nbt::Compound; + +use crate::block::BlockEntityKind; +use crate::block_pos::BlockPos; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct BlockEntityUpdateS2c<'a> { + pub position: BlockPos, + pub kind: BlockEntityKind, + pub data: Cow<'a, Compound>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/block_event.rs b/crates/valence_protocol/src/packet/s2c/play/block_event.rs new file mode 100644 index 0000000..b15297c --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/block_event.rs @@ -0,0 +1,11 @@ +use crate::block_pos::BlockPos; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct BlockEventS2c { + pub position: BlockPos, + pub action_id: u8, + pub action_parameter: u8, + pub block_type: VarInt, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/block_update.rs b/crates/valence_protocol/src/packet/s2c/play/block_update.rs new file mode 100644 index 0000000..9d26486 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/block_update.rs @@ -0,0 +1,9 @@ +use crate::block_pos::BlockPos; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct BlockUpdateS2c { + pub position: BlockPos, + pub block_id: VarInt, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/boss_bar.rs b/crates/valence_protocol/src/packet/s2c/play/boss_bar.rs new file mode 100644 index 0000000..f6b4580 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/boss_bar.rs @@ -0,0 +1,57 @@ +use bitfield_struct::bitfield; +use uuid::Uuid; + +use crate::text::Text; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct BossBarS2c { + pub id: Uuid, + pub action: Action, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub enum Action { + Add { + title: Text, + health: f32, + color: Color, + division: Division, + flags: Flags, + }, + Remove, + UpdateHealth(f32), + UpdateTitle(Text), + UpdateStyle(Color, Division), + UpdateFlags(Flags), +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum Color { + Pink, + Blue, + Red, + Green, + Yellow, + Purple, + White, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum Division { + NoDivision, + SixNotches, + TenNotches, + TwelveNotches, + TwentyNotches, +} + +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct Flags { + pub darken_sky: bool, + pub dragon_bar: bool, + pub create_fog: bool, + #[bits(5)] + _pad: u8, +} diff --git a/crates/valence_protocol/src/packets/s2c/player_chat_message.rs b/crates/valence_protocol/src/packet/s2c/play/chat_message.rs similarity index 88% rename from crates/valence_protocol/src/packets/s2c/player_chat_message.rs rename to crates/valence_protocol/src/packet/s2c/play/chat_message.rs index ec04054..65f3f88 100644 --- a/crates/valence_protocol/src/packets/s2c/player_chat_message.rs +++ b/crates/valence_protocol/src/packet/s2c/play/chat_message.rs @@ -1,12 +1,15 @@ use std::borrow::Cow; use std::io::Write; -use crate::packets::s2c::message_signature::MessageSignature; -use crate::{Decode, DecodePacket, Encode, EncodePacket, Text, Uuid, VarInt}; +use uuid::Uuid; -#[derive(Clone, PartialEq, Debug, EncodePacket, DecodePacket)] -#[packet_id = 0x31] -pub struct PlayerChatMessage<'a> { +use crate::text::Text; +use crate::types::MessageSignature; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, PartialEq, Debug)] +pub struct ChatMessageS2c<'a> { pub sender: Uuid, pub index: VarInt, pub message_signature: Option<&'a [u8; 256]>, @@ -29,7 +32,7 @@ pub enum MessageFilterType { PartiallyFiltered, } -impl<'a> Encode for PlayerChatMessage<'a> { +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)?; @@ -57,7 +60,7 @@ impl<'a> Encode for PlayerChatMessage<'a> { } } -impl<'a> Decode<'a> for PlayerChatMessage<'a> { +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)?; diff --git a/crates/valence_protocol/src/packet/s2c/play/chat_suggestions.rs b/crates/valence_protocol/src/packet/s2c/play/chat_suggestions.rs new file mode 100644 index 0000000..995b66e --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/chat_suggestions.rs @@ -0,0 +1,16 @@ +use std::borrow::Cow; + +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct ChatSuggestionsS2c<'a> { + pub action: Action, + pub entries: Cow<'a, [&'a str]>, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum Action { + Add, + Remove, + Set, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/chunk_data.rs b/crates/valence_protocol/src/packet/s2c/play/chunk_data.rs new file mode 100644 index 0000000..19c225b --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/chunk_data.rs @@ -0,0 +1,31 @@ +use std::borrow::Cow; + +use valence_nbt::Compound; + +use crate::array::LengthPrefixedArray; +use crate::block::BlockEntityKind; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct ChunkDataS2c<'a> { + pub chunk_x: i32, + pub chunk_z: i32, + pub heightmaps: Cow<'a, Compound>, + pub blocks_and_biomes: &'a [u8], + pub block_entities: Cow<'a, [ChunkDataBlockEntity<'a>]>, + pub trust_edges: bool, + 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: BlockEntityKind, + pub data: Cow<'a, Compound>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/chunk_delta_update.rs b/crates/valence_protocol/src/packet/s2c/play/chunk_delta_update.rs new file mode 100644 index 0000000..71b9d49 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/chunk_delta_update.rs @@ -0,0 +1,11 @@ +use std::borrow::Cow; + +use crate::var_long::VarLong; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct ChunkDeltaUpdateS2c<'a> { + pub chunk_section_position: i64, + pub invert_trust_edges: bool, + pub blocks: Cow<'a, [VarLong]>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/chunk_load_distance.rs b/crates/valence_protocol/src/packet/s2c/play/chunk_load_distance.rs new file mode 100644 index 0000000..03fc76b --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/chunk_load_distance.rs @@ -0,0 +1,7 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct ChunkLoadDistanceS2c { + pub view_distance: VarInt, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/chunk_render_distance_center.rs b/crates/valence_protocol/src/packet/s2c/play/chunk_render_distance_center.rs new file mode 100644 index 0000000..fd56d48 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/chunk_render_distance_center.rs @@ -0,0 +1,8 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct ChunkRenderDistanceCenterS2c { + pub chunk_x: VarInt, + pub chunk_z: VarInt, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/clear_titles.rs b/crates/valence_protocol/src/packet/s2c/play/clear_titles.rs new file mode 100644 index 0000000..ddc53d2 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/clear_titles.rs @@ -0,0 +1,6 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct ClearTitlesS2c { + pub reset: bool, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/close_screen.rs b/crates/valence_protocol/src/packet/s2c/play/close_screen.rs new file mode 100644 index 0000000..0d96454 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/close_screen.rs @@ -0,0 +1,7 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct CloseScreenS2c { + /// Ignored by notchian clients. + pub window_id: u8, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/command_suggestions.rs b/crates/valence_protocol/src/packet/s2c/play/command_suggestions.rs new file mode 100644 index 0000000..e2b1257 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/command_suggestions.rs @@ -0,0 +1,19 @@ +use std::borrow::Cow; + +use crate::text::Text; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct CommandSuggestionsS2c<'a> { + pub id: VarInt, + pub start: VarInt, + pub length: VarInt, + pub matches: Vec>, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct Match<'a> { + pub suggested_match: &'a str, + pub tooltip: Option>, +} diff --git a/crates/valence_protocol/src/packets/s2c/commands.rs b/crates/valence_protocol/src/packet/s2c/play/command_tree.rs similarity index 98% rename from crates/valence_protocol/src/packets/s2c/commands.rs rename to crates/valence_protocol/src/packet/s2c/play/command_tree.rs index 45fd94a..396f196 100644 --- a/crates/valence_protocol/src/packets/s2c/commands.rs +++ b/crates/valence_protocol/src/packet/s2c/play/command_tree.rs @@ -3,7 +3,15 @@ use std::io::Write; use anyhow::bail; use byteorder::WriteBytesExt; -use crate::{Decode, Encode, Ident, VarInt}; +use crate::ident::Ident; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct CommandTreeS2c<'a> { + pub commands: Vec>, + pub root_index: VarInt, +} #[derive(Clone, Debug)] pub struct Node<'a> { diff --git a/crates/valence_protocol/src/packet/s2c/play/cooldown_update.rs b/crates/valence_protocol/src/packet/s2c/play/cooldown_update.rs new file mode 100644 index 0000000..92ddc6e --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/cooldown_update.rs @@ -0,0 +1,8 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct CooldownUpdateS2c { + pub item_id: VarInt, + pub cooldown_ticks: VarInt, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/craft_failed_response.rs b/crates/valence_protocol/src/packet/s2c/play/craft_failed_response.rs new file mode 100644 index 0000000..6c8af2d --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/craft_failed_response.rs @@ -0,0 +1,8 @@ +use crate::ident::Ident; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct CraftFailedResponseS2c<'a> { + pub window_id: u8, + pub recipe: Ident<&'a str>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/custom_payload.rs b/crates/valence_protocol/src/packet/s2c/play/custom_payload.rs new file mode 100644 index 0000000..fd85b3e --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/custom_payload.rs @@ -0,0 +1,9 @@ +use crate::ident::Ident; +use crate::raw_bytes::RawBytes; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct CustomPayloadS2c<'a> { + pub channel: Ident<&'a str>, + pub data: RawBytes<'a>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/death_message.rs b/crates/valence_protocol/src/packet/s2c/play/death_message.rs new file mode 100644 index 0000000..bf8f708 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/death_message.rs @@ -0,0 +1,13 @@ +use std::borrow::Cow; + +use crate::text::Text; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct DeathMessageS2c<'a> { + pub player_id: VarInt, + /// Killer's entity ID, -1 if no killer + pub entity_id: i32, + pub message: Cow<'a, Text>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/difficulty.rs b/crates/valence_protocol/src/packet/s2c/play/difficulty.rs new file mode 100644 index 0000000..997a479 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/difficulty.rs @@ -0,0 +1,8 @@ +use crate::types::Difficulty; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct DifficultyS2c { + pub difficulty: Difficulty, + pub locked: bool, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/disconnect.rs b/crates/valence_protocol/src/packet/s2c/play/disconnect.rs new file mode 100644 index 0000000..7b4852f --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/disconnect.rs @@ -0,0 +1,9 @@ +use std::borrow::Cow; + +use crate::text::Text; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct DisconnectS2c<'a> { + pub reason: Cow<'a, Text>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/end_combat.rs b/crates/valence_protocol/src/packet/s2c/play/end_combat.rs new file mode 100644 index 0000000..67aadbb --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/end_combat.rs @@ -0,0 +1,9 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +/// Unused by notchian clients. +#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode)] +pub struct EndCombatS2c { + pub duration: VarInt, + pub entity_id: i32, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/enter_combat.rs b/crates/valence_protocol/src/packet/s2c/play/enter_combat.rs new file mode 100644 index 0000000..db9fac2 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/enter_combat.rs @@ -0,0 +1,5 @@ +use crate::{Decode, Encode}; + +/// Unused by notchian clients. +#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode)] +pub struct EnterCombatS2c; diff --git a/crates/valence_protocol/src/packet/s2c/play/entities_destroy.rs b/crates/valence_protocol/src/packet/s2c/play/entities_destroy.rs new file mode 100644 index 0000000..c5d23e3 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/entities_destroy.rs @@ -0,0 +1,9 @@ +use std::borrow::Cow; + +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct EntitiesDestroyS2c<'a> { + pub entity_ids: Cow<'a, [VarInt]>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/entity.rs b/crates/valence_protocol/src/packet/s2c/play/entity.rs new file mode 100644 index 0000000..96816c6 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/entity.rs @@ -0,0 +1,27 @@ +use crate::byte_angle::ByteAngle; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct MoveRelativeS2c { + pub entity_id: VarInt, + pub delta: [i16; 3], + pub on_ground: bool, +} + +#[derive(Copy, Clone, Debug, Encode, Decode)] +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)] +pub struct RotateS2c { + pub entity_id: VarInt, + pub yaw: ByteAngle, + pub pitch: ByteAngle, + pub on_ground: bool, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/entity_animation.rs b/crates/valence_protocol/src/packet/s2c/play/entity_animation.rs new file mode 100644 index 0000000..ba30643 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/entity_animation.rs @@ -0,0 +1,8 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct EntityAnimationS2c { + pub entity_id: VarInt, + pub animation: u8, // TODO: use Animation enum. +} diff --git a/crates/valence_protocol/src/packet/s2c/play/entity_attach.rs b/crates/valence_protocol/src/packet/s2c/play/entity_attach.rs new file mode 100644 index 0000000..ba24d26 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/entity_attach.rs @@ -0,0 +1,7 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct EntityAttachS2c { + pub attached_entity_id: i32, + pub holding_entity_id: i32, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/entity_attributes.rs b/crates/valence_protocol/src/packet/s2c/play/entity_attributes.rs new file mode 100644 index 0000000..023ffc2 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/entity_attributes.rs @@ -0,0 +1,25 @@ +use uuid::Uuid; + +use crate::ident::Ident; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct EntityAttributesS2c<'a> { + pub entity_id: VarInt, + pub properties: Vec>, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct AttributeProperty<'a> { + pub key: Ident<&'a str>, + 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_protocol/src/packets/s2c/set_equipment.rs b/crates/valence_protocol/src/packet/s2c/play/entity_equipment_update.rs similarity index 82% rename from crates/valence_protocol/src/packets/s2c/set_equipment.rs rename to crates/valence_protocol/src/packet/s2c/play/entity_equipment_update.rs index 04e9ca5..0f0886a 100644 --- a/crates/valence_protocol/src/packets/s2c/set_equipment.rs +++ b/crates/valence_protocol/src/packet/s2c/play/entity_equipment_update.rs @@ -1,10 +1,11 @@ use std::io::Write; -use crate::{Decode, DecodePacket, Encode, EncodePacket, ItemStack, VarInt}; +use crate::item::ItemStack; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; -#[derive(Clone, PartialEq, Debug, EncodePacket, DecodePacket)] -#[packet_id = 0x51] -pub struct SetEquipment { +#[derive(Clone, PartialEq, Debug)] +pub struct EntityEquipmentUpdateS2c { pub entity_id: VarInt, pub equipment: Vec, } @@ -15,7 +16,7 @@ pub struct EquipmentEntry { pub item: Option, } -impl Encode for SetEquipment { +impl Encode for EntityEquipmentUpdateS2c { fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { self.entity_id.encode(&mut w)?; @@ -33,7 +34,7 @@ impl Encode for SetEquipment { } } -impl<'a> Decode<'a> for SetEquipment { +impl<'a> Decode<'a> for EntityEquipmentUpdateS2c { fn decode(r: &mut &'a [u8]) -> anyhow::Result { let entity_id = VarInt::decode(r)?; diff --git a/crates/valence_protocol/src/packet/s2c/play/entity_passengers_set.rs b/crates/valence_protocol/src/packet/s2c/play/entity_passengers_set.rs new file mode 100644 index 0000000..4b69cf3 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/entity_passengers_set.rs @@ -0,0 +1,9 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct EntityPassengersSetS2c { + /// Vehicle's entity id + pub entity_id: VarInt, + pub passengers: Vec, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/entity_position.rs b/crates/valence_protocol/src/packet/s2c/play/entity_position.rs new file mode 100644 index 0000000..e9af827 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/entity_position.rs @@ -0,0 +1,12 @@ +use crate::byte_angle::ByteAngle; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct EntityPositionS2c { + pub entity_id: VarInt, + pub position: [f64; 3], + pub yaw: ByteAngle, + pub pitch: ByteAngle, + pub on_ground: bool, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/entity_set_head_yaw.rs b/crates/valence_protocol/src/packet/s2c/play/entity_set_head_yaw.rs new file mode 100644 index 0000000..80df0de --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/entity_set_head_yaw.rs @@ -0,0 +1,9 @@ +use crate::byte_angle::ByteAngle; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct EntitySetHeadYawS2c { + pub entity_id: VarInt, + pub head_yaw: ByteAngle, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/entity_spawn.rs b/crates/valence_protocol/src/packet/s2c/play/entity_spawn.rs new file mode 100644 index 0000000..2381d92 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/entity_spawn.rs @@ -0,0 +1,19 @@ +use uuid::Uuid; + +use crate::byte_angle::ByteAngle; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct EntitySpawnS2c { + pub entity_id: VarInt, + pub object_uuid: Uuid, + // TODO: EntityKind type? + pub kind: VarInt, + pub position: [f64; 3], + pub pitch: ByteAngle, + pub yaw: ByteAngle, + pub head_yaw: ByteAngle, + pub data: VarInt, + pub velocity: [i16; 3], +} diff --git a/crates/valence_protocol/src/packet/s2c/play/entity_status.rs b/crates/valence_protocol/src/packet/s2c/play/entity_status.rs new file mode 100644 index 0000000..6998b71 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/entity_status.rs @@ -0,0 +1,7 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct EntityStatusS2c { + pub entity_id: i32, + pub entity_status: u8, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/entity_status_effect.rs b/crates/valence_protocol/src/packet/s2c/play/entity_status_effect.rs new file mode 100644 index 0000000..3ac9a5b --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/entity_status_effect.rs @@ -0,0 +1,25 @@ +use bitfield_struct::bitfield; +use valence_nbt::Compound; + +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +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_protocol/src/packet/s2c/play/entity_tracker_update.rs b/crates/valence_protocol/src/packet/s2c/play/entity_tracker_update.rs new file mode 100644 index 0000000..c151435 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/entity_tracker_update.rs @@ -0,0 +1,9 @@ +use crate::raw_bytes::RawBytes; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct EntityTrackerUpdateS2c<'a> { + pub entity_id: VarInt, + pub metadata: RawBytes<'a>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/entity_velocity_update.rs b/crates/valence_protocol/src/packet/s2c/play/entity_velocity_update.rs new file mode 100644 index 0000000..5dc1353 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/entity_velocity_update.rs @@ -0,0 +1,8 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct EntityVelocityUpdateS2c { + pub entity_id: VarInt, + pub velocity: [i16; 3], +} diff --git a/crates/valence_protocol/src/packet/s2c/play/experience_bar_update.rs b/crates/valence_protocol/src/packet/s2c/play/experience_bar_update.rs new file mode 100644 index 0000000..881d8e2 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/experience_bar_update.rs @@ -0,0 +1,9 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct ExperienceBarUpdateS2c { + pub bar: f32, + pub level: VarInt, + pub total_xp: VarInt, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/experience_orb_spawn.rs b/crates/valence_protocol/src/packet/s2c/play/experience_orb_spawn.rs new file mode 100644 index 0000000..5edb94e --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/experience_orb_spawn.rs @@ -0,0 +1,9 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct ExperienceOrbSpawnS2c { + pub entity_id: VarInt, + pub position: [f64; 3], + pub count: i16, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/explosion.rs b/crates/valence_protocol/src/packet/s2c/play/explosion.rs new file mode 100644 index 0000000..2e70dd7 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/explosion.rs @@ -0,0 +1,9 @@ +use crate::ident::Ident; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct ExplosionS2c<'a> { + pub window_id: u8, + pub recipe: Ident<&'a str>, + pub make_all: bool, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/features.rs b/crates/valence_protocol/src/packet/s2c/play/features.rs new file mode 100644 index 0000000..e7b34cf --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/features.rs @@ -0,0 +1,7 @@ +use crate::ident::Ident; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct FeaturesS2c<'a> { + pub features: Vec>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/game_join.rs b/crates/valence_protocol/src/packet/s2c/play/game_join.rs new file mode 100644 index 0000000..66bbeb3 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/game_join.rs @@ -0,0 +1,30 @@ +use std::borrow::Cow; + +use valence_nbt::Compound; + +use crate::ident::Ident; +use crate::types::{GameMode, GlobalPos}; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +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<&'a str>, + pub dimension_name: Ident<&'a str>, + 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>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/game_message.rs b/crates/valence_protocol/src/packet/s2c/play/game_message.rs new file mode 100644 index 0000000..94e30e8 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/game_message.rs @@ -0,0 +1,11 @@ +use std::borrow::Cow; + +use crate::text::Text; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +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_protocol/src/packet/s2c/play/game_state_change.rs b/crates/valence_protocol/src/packet/s2c/play/game_state_change.rs new file mode 100644 index 0000000..7cd0063 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/game_state_change.rs @@ -0,0 +1,23 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +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_protocol/src/packet/s2c/play/health_update.rs b/crates/valence_protocol/src/packet/s2c/play/health_update.rs new file mode 100644 index 0000000..f5f06bf --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/health_update.rs @@ -0,0 +1,9 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct HealthUpdateS2c { + pub health: f32, + pub food: VarInt, + pub food_saturation: f32, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/inventory.rs b/crates/valence_protocol/src/packet/s2c/play/inventory.rs new file mode 100644 index 0000000..0a16397 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/inventory.rs @@ -0,0 +1,13 @@ +use std::borrow::Cow; + +use crate::item::ItemStack; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +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_protocol/src/packet/s2c/play/item_pickup_animation.rs b/crates/valence_protocol/src/packet/s2c/play/item_pickup_animation.rs new file mode 100644 index 0000000..78f679a --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/item_pickup_animation.rs @@ -0,0 +1,9 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct ItemPickupAnimationS2c { + pub collected_entity_id: VarInt, + pub collector_entity_id: VarInt, + pub pickup_item_count: VarInt, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/keep_alive.rs b/crates/valence_protocol/src/packet/s2c/play/keep_alive.rs new file mode 100644 index 0000000..8373939 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/keep_alive.rs @@ -0,0 +1,6 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct KeepAliveS2c { + pub id: u64, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/light_update.rs b/crates/valence_protocol/src/packet/s2c/play/light_update.rs new file mode 100644 index 0000000..df299ea --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/light_update.rs @@ -0,0 +1,16 @@ +use crate::array::LengthPrefixedArray; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct LightUpdateS2c { + pub chunk_x: VarInt, + pub chunk_z: VarInt, + pub trust_edges: bool, + 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_protocol/src/packet/s2c/play/look_at.rs b/crates/valence_protocol/src/packet/s2c/play/look_at.rs new file mode 100644 index 0000000..e0fd234 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/look_at.rs @@ -0,0 +1,21 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode)] +pub struct LookAtS2c { + pub feet_or_eyes: FeetOrEyes, + pub target_position: [f64; 3], + 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_protocol/src/packets/s2c/map_data.rs b/crates/valence_protocol/src/packet/s2c/play/map_update.rs similarity index 90% rename from crates/valence_protocol/src/packets/s2c/map_data.rs rename to crates/valence_protocol/src/packet/s2c/play/map_update.rs index 9c7bca0..b09362c 100644 --- a/crates/valence_protocol/src/packets/s2c/map_data.rs +++ b/crates/valence_protocol/src/packet/s2c/play/map_update.rs @@ -1,11 +1,12 @@ use std::borrow::Cow; use std::io::Write; -use crate::{Decode, DecodePacket, Encode, EncodePacket, Text, VarInt}; +use crate::text::Text; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; -#[derive(Clone, PartialEq, Debug, EncodePacket, DecodePacket)] -#[packet_id = 0x25] -pub struct MapData<'a> { +#[derive(Clone, PartialEq, Debug)] +pub struct MapUpdateS2c<'a> { pub map_id: VarInt, pub scale: i8, pub locked: bool, @@ -62,7 +63,7 @@ pub struct Data<'a> { pub data: &'a [u8], } -impl Encode for MapData<'_> { +impl Encode for MapUpdateS2c<'_> { fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { self.map_id.encode(&mut w)?; self.scale.encode(&mut w)?; @@ -78,7 +79,7 @@ impl Encode for MapData<'_> { } } -impl<'a> Decode<'a> for MapData<'a> { +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)?; diff --git a/crates/valence_protocol/src/packet/s2c/play/nbt_query_response.rs b/crates/valence_protocol/src/packet/s2c/play/nbt_query_response.rs new file mode 100644 index 0000000..392cb32 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/nbt_query_response.rs @@ -0,0 +1,10 @@ +use valence_nbt::Compound; + +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct NbtQueryResponseS2c { + pub transaction_id: VarInt, + pub nbt: Compound, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/open_horse_screen.rs b/crates/valence_protocol/src/packet/s2c/play/open_horse_screen.rs new file mode 100644 index 0000000..bc1c8be --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/open_horse_screen.rs @@ -0,0 +1,9 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct OpenHorseScreenS2c { + pub window_id: u8, + pub slot_count: VarInt, + pub entity_id: i32, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/open_screen.rs b/crates/valence_protocol/src/packet/s2c/play/open_screen.rs new file mode 100644 index 0000000..e89ce9a --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/open_screen.rs @@ -0,0 +1,13 @@ +use std::borrow::Cow; + +use crate::text::Text; +use crate::types::WindowType; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct OpenScreenS2c<'a> { + pub window_id: VarInt, + pub window_type: WindowType, + pub window_title: Cow<'a, Text>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/open_written_book.rs b/crates/valence_protocol/src/packet/s2c/play/open_written_book.rs new file mode 100644 index 0000000..7cc88d1 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/open_written_book.rs @@ -0,0 +1,7 @@ +use crate::types::Hand; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct OpenWrittenBookS2c { + pub hand: Hand, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/overlay_message.rs b/crates/valence_protocol/src/packet/s2c/play/overlay_message.rs new file mode 100644 index 0000000..63dc23f --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/overlay_message.rs @@ -0,0 +1,9 @@ +use std::borrow::Cow; + +use crate::text::Text; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct OverlayMessageS2c<'a> { + pub action_bar_text: Cow<'a, Text>, +} diff --git a/crates/valence_protocol/src/packets/s2c/particle.rs b/crates/valence_protocol/src/packet/s2c/play/particle.rs similarity index 97% rename from crates/valence_protocol/src/packets/s2c/particle.rs rename to crates/valence_protocol/src/packet/s2c/play/particle.rs index 525bd7a..6f233c0 100644 --- a/crates/valence_protocol/src/packets/s2c/particle.rs +++ b/crates/valence_protocol/src/packet/s2c/play/particle.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::io::Write; use anyhow::bail; @@ -5,12 +6,12 @@ use anyhow::bail; use crate::block::BlockState; use crate::block_pos::BlockPos; use crate::item::ItemStack; -use crate::{Decode, DecodePacket, Encode, EncodePacket, VarInt}; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; -#[derive(Clone, Debug, EncodePacket, DecodePacket)] -#[packet_id = 0x22] -pub struct ParticleS2c { - pub particle: Particle, +#[derive(Clone, Debug)] +pub struct ParticleS2c<'a> { + pub particle: Cow<'a, Particle>, pub long_distance: bool, pub position: [f64; 3], pub offset: [f32; 3], @@ -233,7 +234,7 @@ impl Particle { } } -impl Encode for ParticleS2c { +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)?; @@ -242,7 +243,7 @@ impl Encode for ParticleS2c { self.max_speed.encode(&mut w)?; self.count.encode(&mut w)?; - match &self.particle { + match self.particle.as_ref() { Particle::Block(block_state) => block_state.encode(w), Particle::BlockMarker(block_state) => block_state.encode(w), Particle::Dust { rgb, scale } => { @@ -281,7 +282,7 @@ impl Encode for ParticleS2c { } } -impl<'a> Decode<'a> for ParticleS2c { +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)?; @@ -291,7 +292,7 @@ impl<'a> Decode<'a> for ParticleS2c { let particle_count = i32::decode(r)?; Ok(Self { - particle: match particle_id { + particle: Cow::Owned(match particle_id { 0 => Particle::AmbientEntityEffect, 1 => Particle::AngryVillager, 2 => Particle::Block(BlockState::decode(r)?), @@ -405,7 +406,7 @@ impl<'a> Decode<'a> for ParticleS2c { 90 => Particle::ElectricSpark, 91 => Particle::Scrape, id => bail!("invalid particle ID of {id}"), - }, + }), long_distance, position, offset, diff --git a/crates/valence_protocol/src/packet/s2c/play/play_ping.rs b/crates/valence_protocol/src/packet/s2c/play/play_ping.rs new file mode 100644 index 0000000..7cc34a1 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/play_ping.rs @@ -0,0 +1,6 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct PlayPingS2c { + pub id: i32, +} diff --git a/crates/valence_protocol/src/packets/s2c/sound_id.rs b/crates/valence_protocol/src/packet/s2c/play/play_sound.rs similarity index 74% rename from crates/valence_protocol/src/packets/s2c/sound_id.rs rename to crates/valence_protocol/src/packet/s2c/play/play_sound.rs index 66b267c..c006815 100644 --- a/crates/valence_protocol/src/packets/s2c/sound_id.rs +++ b/crates/valence_protocol/src/packet/s2c/play/play_sound.rs @@ -1,6 +1,19 @@ use std::io::Write; -use crate::{Decode, Encode, Ident, VarInt}; +use crate::ident::Ident; +use crate::types::SoundCategory; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct PlaySoundS2c<'a> { + pub id: SoundId<'a>, + pub category: SoundCategory, + pub position: [i32; 3], + pub volume: f32, + pub pitch: f32, + pub seed: i64, +} #[derive(Copy, Clone, PartialEq, Debug)] pub enum SoundId<'a> { diff --git a/crates/valence_protocol/src/packet/s2c/play/play_sound_from_entity.rs b/crates/valence_protocol/src/packet/s2c/play/play_sound_from_entity.rs new file mode 100644 index 0000000..76c9ec8 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/play_sound_from_entity.rs @@ -0,0 +1,13 @@ +use crate::types::SoundCategory; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +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_protocol/src/packet/s2c/play/player_abilities.rs b/crates/valence_protocol/src/packet/s2c/play/player_abilities.rs new file mode 100644 index 0000000..7f61966 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/player_abilities.rs @@ -0,0 +1,21 @@ +use bitfield_struct::bitfield; + +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +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_protocol/src/packet/s2c/play/player_action_response.rs b/crates/valence_protocol/src/packet/s2c/play/player_action_response.rs new file mode 100644 index 0000000..abce7db --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/player_action_response.rs @@ -0,0 +1,7 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct PlayerActionResponseS2c { + pub sequence: VarInt, +} diff --git a/crates/valence_protocol/src/packets/s2c/player_info_update.rs b/crates/valence_protocol/src/packet/s2c/play/player_list.rs similarity index 92% rename from crates/valence_protocol/src/packets/s2c/player_info_update.rs rename to crates/valence_protocol/src/packet/s2c/play/player_list.rs index 947e6b1..0af77b4 100644 --- a/crates/valence_protocol/src/packets/s2c/player_info_update.rs +++ b/crates/valence_protocol/src/packet/s2c/play/player_list.rs @@ -4,12 +4,13 @@ use std::io::Write; use bitfield_struct::bitfield; use uuid::Uuid; +use crate::text::Text; use crate::types::{GameMode, Property}; -use crate::{Decode, DecodePacket, Encode, EncodePacket, Text, VarInt}; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; -#[derive(Clone, Debug, EncodePacket, DecodePacket)] -#[packet_id = 0x36] -pub struct PlayerInfoUpdate<'a> { +#[derive(Clone, Debug)] +pub struct PlayerListS2c<'a> { pub actions: Actions, pub entries: Cow<'a, [Entry<'a>]>, } @@ -47,7 +48,7 @@ pub struct ChatData<'a> { pub public_key_signature: &'a [u8], } -impl<'a> Encode for PlayerInfoUpdate<'a> { +impl<'a> Encode for PlayerListS2c<'a> { fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { self.actions.0.encode(&mut w)?; @@ -87,7 +88,7 @@ impl<'a> Encode for PlayerInfoUpdate<'a> { } } -impl<'a> Decode<'a> for PlayerInfoUpdate<'a> { +impl<'a> Decode<'a> for PlayerListS2c<'a> { fn decode(r: &mut &'a [u8]) -> anyhow::Result { let actions = Actions(u8::decode(r)?); diff --git a/crates/valence_protocol/src/packet/s2c/play/player_list_header.rs b/crates/valence_protocol/src/packet/s2c/play/player_list_header.rs new file mode 100644 index 0000000..9220c7b --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/player_list_header.rs @@ -0,0 +1,10 @@ +use std::borrow::Cow; + +use crate::text::Text; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct PlayerListHeaderS2c<'a> { + pub header: Cow<'a, Text>, + pub footer: Cow<'a, Text>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/player_position_look.rs b/crates/valence_protocol/src/packet/s2c/play/player_position_look.rs new file mode 100644 index 0000000..fb0eede --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/player_position_look.rs @@ -0,0 +1,26 @@ +use bitfield_struct::bitfield; + +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode)] +pub struct PlayerPositionLookS2c { + pub position: [f64; 3], + pub yaw: f32, + pub pitch: f32, + pub flags: Flags, + pub teleport_id: VarInt, + pub dismount_vehicle: bool, +} + +#[bitfield(u8)] +#[derive(PartialEq, Eq, Encode, Decode)] +pub struct Flags { + 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_protocol/src/packet/s2c/play/player_remove.rs b/crates/valence_protocol/src/packet/s2c/play/player_remove.rs new file mode 100644 index 0000000..e28fcff --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/player_remove.rs @@ -0,0 +1,10 @@ +use std::borrow::Cow; + +use uuid::Uuid; + +use crate::{Decode, Encode}; + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct PlayerRemoveS2c<'a> { + pub uuids: Cow<'a, [Uuid]>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/player_respawn.rs b/crates/valence_protocol/src/packet/s2c/play/player_respawn.rs new file mode 100644 index 0000000..440acba --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/player_respawn.rs @@ -0,0 +1,16 @@ +use crate::ident::Ident; +use crate::types::{GameMode, GlobalPos}; +use crate::{Decode, Encode}; + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct PlayerRespawnS2c<'a> { + pub dimension_type_name: Ident<&'a str>, + pub dimension_name: Ident<&'a str>, + 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>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/player_spawn.rs b/crates/valence_protocol/src/packet/s2c/play/player_spawn.rs new file mode 100644 index 0000000..2fb249c --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/player_spawn.rs @@ -0,0 +1,14 @@ +use uuid::Uuid; + +use crate::byte_angle::ByteAngle; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct PlayerSpawnS2c { + pub entity_id: VarInt, + pub player_uuid: Uuid, + pub position: [f64; 3], + pub yaw: ByteAngle, + pub pitch: ByteAngle, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/player_spawn_position.rs b/crates/valence_protocol/src/packet/s2c/play/player_spawn_position.rs new file mode 100644 index 0000000..4a649a0 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/player_spawn_position.rs @@ -0,0 +1,8 @@ +use crate::block_pos::BlockPos; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct PlayerSpawnPositionS2c { + pub position: BlockPos, + pub angle: f32, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/profileless_chat_message.rs b/crates/valence_protocol/src/packet/s2c/play/profileless_chat_message.rs new file mode 100644 index 0000000..575763a --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/profileless_chat_message.rs @@ -0,0 +1,13 @@ +use std::borrow::Cow; + +use crate::text::Text; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +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_protocol/src/packet/s2c/play/remove_entity_status_effect.rs b/crates/valence_protocol/src/packet/s2c/play/remove_entity_status_effect.rs new file mode 100644 index 0000000..d6ea421 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/remove_entity_status_effect.rs @@ -0,0 +1,8 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct RemoveEntityStatusEffectS2c { + pub entity_id: VarInt, + pub effect_id: VarInt, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/remove_message.rs b/crates/valence_protocol/src/packet/s2c/play/remove_message.rs new file mode 100644 index 0000000..d80f921 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/remove_message.rs @@ -0,0 +1,7 @@ +use crate::types::MessageSignature; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct RemoveMessageS2c<'a> { + pub signature: MessageSignature<'a>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/resource_pack_send.rs b/crates/valence_protocol/src/packet/s2c/play/resource_pack_send.rs new file mode 100644 index 0000000..2980361 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/resource_pack_send.rs @@ -0,0 +1,12 @@ +use std::borrow::Cow; + +use crate::text::Text; +use crate::{Decode, Encode}; + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub struct ResourcePackSendS2c<'a> { + pub url: &'a str, + pub hash: &'a str, + pub forced: bool, + pub prompt_message: Option>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/scoreboard_display.rs b/crates/valence_protocol/src/packet/s2c/play/scoreboard_display.rs new file mode 100644 index 0000000..b683eee --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/scoreboard_display.rs @@ -0,0 +1,7 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct ScoreboardDisplayS2c<'a> { + pub position: u8, + pub score_name: &'a str, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/scoreboard_objective_update.rs b/crates/valence_protocol/src/packet/s2c/play/scoreboard_objective_update.rs new file mode 100644 index 0000000..1c5e752 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/scoreboard_objective_update.rs @@ -0,0 +1,27 @@ +use crate::text::Text; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct ScoreboardObjectiveUpdateS2c<'a> { + pub objective_name: &'a str, + pub mode: Mode, +} + +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub enum Mode { + Create { + objective_display_name: Text, + render_type: RenderType, + }, + Remove, + Update { + objective_display_name: Text, + render_type: RenderType, + }, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub enum RenderType { + Integer, + Hearts, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/scoreboard_player_update.rs b/crates/valence_protocol/src/packet/s2c/play/scoreboard_player_update.rs new file mode 100644 index 0000000..5cdb85c --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/scoreboard_player_update.rs @@ -0,0 +1,22 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct ScoreboardPlayerUpdateS2c<'a> { + pub entity_name: &'a str, + pub action: Action<'a>, +} + +// TODO: this looks wrong. +#[derive(Clone, PartialEq, Debug, Encode, Decode)] +pub enum Action<'a> { + Create { + objective_value: &'a str, + objective_type: VarInt, + }, + Remove, + Update { + objective_value: &'a str, + objective_type: VarInt, + }, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/screen_handler_property_update.rs b/crates/valence_protocol/src/packet/s2c/play/screen_handler_property_update.rs new file mode 100644 index 0000000..980d60d --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/screen_handler_property_update.rs @@ -0,0 +1,8 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct ScreenHandlerPropertyUpdateS2c { + pub window_id: u8, + pub property: i16, + pub value: i16, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/screen_handler_slot_update.rs b/crates/valence_protocol/src/packet/s2c/play/screen_handler_slot_update.rs new file mode 100644 index 0000000..3bae895 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/screen_handler_slot_update.rs @@ -0,0 +1,13 @@ +use std::borrow::Cow; + +use crate::item::ItemStack; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +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_protocol/src/packet/s2c/play/select_advancements_tab.rs b/crates/valence_protocol/src/packet/s2c/play/select_advancements_tab.rs new file mode 100644 index 0000000..1847046 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/select_advancements_tab.rs @@ -0,0 +1,7 @@ +use crate::ident::Ident; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct SelectAdvancementsTabS2c<'a> { + pub identifier: Option>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/server_metadata.rs b/crates/valence_protocol/src/packet/s2c/play/server_metadata.rs new file mode 100644 index 0000000..ae70919 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/server_metadata.rs @@ -0,0 +1,11 @@ +use std::borrow::Cow; + +use crate::text::Text; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct ServerMetadataS2c<'a> { + pub motd: Option>, + pub icon: Option<&'a str>, + pub enforce_secure_chat: bool, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/set_camera_entity.rs b/crates/valence_protocol/src/packet/s2c/play/set_camera_entity.rs new file mode 100644 index 0000000..370aab5 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/set_camera_entity.rs @@ -0,0 +1,7 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct SetCameraEntityS2c { + pub entity_id: VarInt, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/set_trade_offers.rs b/crates/valence_protocol/src/packet/s2c/play/set_trade_offers.rs new file mode 100644 index 0000000..7ed2b3a --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/set_trade_offers.rs @@ -0,0 +1,27 @@ +use crate::item::ItemStack; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +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_protocol/src/packet/s2c/play/sign_editor_open.rs b/crates/valence_protocol/src/packet/s2c/play/sign_editor_open.rs new file mode 100644 index 0000000..f5ab697 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/sign_editor_open.rs @@ -0,0 +1,7 @@ +use crate::block_pos::BlockPos; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct SignEditorOpen { + pub location: BlockPos, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/simulation_distance.rs b/crates/valence_protocol/src/packet/s2c/play/simulation_distance.rs new file mode 100644 index 0000000..b3d07da --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/simulation_distance.rs @@ -0,0 +1,7 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct SimulationDistanceS2c { + pub simulation_distance: VarInt, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/statistics.rs b/crates/valence_protocol/src/packet/s2c/play/statistics.rs new file mode 100644 index 0000000..d57bafe --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/statistics.rs @@ -0,0 +1,14 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +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_protocol/src/packets/s2c/stop_sound.rs b/crates/valence_protocol/src/packet/s2c/play/stop_sound.rs similarity index 82% rename from crates/valence_protocol/src/packets/s2c/stop_sound.rs rename to crates/valence_protocol/src/packet/s2c/play/stop_sound.rs index 22235d3..215db58 100644 --- a/crates/valence_protocol/src/packets/s2c/stop_sound.rs +++ b/crates/valence_protocol/src/packet/s2c/play/stop_sound.rs @@ -1,16 +1,16 @@ use std::io::Write; +use crate::ident::Ident; use crate::types::SoundCategory; -use crate::{Decode, DecodePacket, Encode, EncodePacket, Ident}; +use crate::{Decode, Encode}; -#[derive(Clone, PartialEq, Debug, EncodePacket, DecodePacket)] -#[packet_id = 0x5f] -pub struct StopSound<'a> { +#[derive(Clone, PartialEq, Debug)] +pub struct StopSoundS2c<'a> { pub source: Option, pub sound: Option>, } -impl Encode for StopSound<'_> { +impl Encode for StopSoundS2c<'_> { fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { match (self.source, self.sound) { (Some(source), Some(sound)) => { @@ -33,7 +33,7 @@ impl Encode for StopSound<'_> { } } -impl<'a> Decode<'a> for StopSound<'a> { +impl<'a> Decode<'a> for StopSoundS2c<'a> { fn decode(r: &mut &'a [u8]) -> anyhow::Result { let (source, sound) = match i8::decode(r)? { 3 => ( diff --git a/crates/valence_protocol/src/packet/s2c/play/subtitle.rs b/crates/valence_protocol/src/packet/s2c/play/subtitle.rs new file mode 100644 index 0000000..8316504 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/subtitle.rs @@ -0,0 +1,9 @@ +use std::borrow::Cow; + +use crate::text::Text; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct SubtitleS2c<'a> { + pub subtitle_text: Cow<'a, Text>, +} diff --git a/crates/valence_protocol/src/packets/s2c/declare_recipes.rs b/crates/valence_protocol/src/packet/s2c/play/synchronize_recipes.rs similarity index 95% rename from crates/valence_protocol/src/packets/s2c/declare_recipes.rs rename to crates/valence_protocol/src/packet/s2c/play/synchronize_recipes.rs index 383f824..ea758bf 100644 --- a/crates/valence_protocol/src/packets/s2c/declare_recipes.rs +++ b/crates/valence_protocol/src/packet/s2c/play/synchronize_recipes.rs @@ -2,10 +2,18 @@ use std::io::Write; use anyhow::{bail, ensure}; -use crate::{Decode, Encode, Ident, ItemStack, VarInt}; +use crate::ident::Ident; +use crate::item::ItemStack; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct SynchronizeRecipesS2c<'a> { + pub recipes: Vec>, +} #[derive(Clone, PartialEq, Debug)] -pub enum DeclaredRecipe<'a> { +pub enum Recipe<'a> { CraftingShapeless { recipe_id: Ident<&'a str>, group: &'a str, @@ -113,10 +121,10 @@ pub enum SmeltCategory { Misc, } -impl<'a> Encode for DeclaredRecipe<'a> { +impl<'a> Encode for Recipe<'a> { fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { match self { - DeclaredRecipe::CraftingShapeless { + Recipe::CraftingShapeless { recipe_id, group, category, @@ -130,7 +138,7 @@ impl<'a> Encode for DeclaredRecipe<'a> { ingredients.encode(&mut w)?; result.encode(w) } - DeclaredRecipe::CraftingShaped { + Recipe::CraftingShaped { recipe_id, width, height, @@ -157,7 +165,7 @@ impl<'a> Encode for DeclaredRecipe<'a> { result.encode(w) } - DeclaredRecipe::CraftingSpecial { + Recipe::CraftingSpecial { kind, recipe_id, category, @@ -184,7 +192,7 @@ impl<'a> Encode for DeclaredRecipe<'a> { recipe_id.encode(&mut w)?; category.encode(w) } - DeclaredRecipe::Smelting { + Recipe::Smelting { recipe_id, group, category, @@ -202,7 +210,7 @@ impl<'a> Encode for DeclaredRecipe<'a> { experience.encode(&mut w)?; cooking_time.encode(w) } - DeclaredRecipe::Blasting { + Recipe::Blasting { recipe_id, group, category, @@ -220,7 +228,7 @@ impl<'a> Encode for DeclaredRecipe<'a> { experience.encode(&mut w)?; cooking_time.encode(w) } - DeclaredRecipe::Smoking { + Recipe::Smoking { recipe_id, group, category, @@ -238,7 +246,7 @@ impl<'a> Encode for DeclaredRecipe<'a> { experience.encode(&mut w)?; cooking_time.encode(w) } - DeclaredRecipe::CampfireCooking { + Recipe::CampfireCooking { recipe_id, group, category, @@ -256,7 +264,7 @@ impl<'a> Encode for DeclaredRecipe<'a> { experience.encode(&mut w)?; cooking_time.encode(w) } - DeclaredRecipe::Stonecutting { + Recipe::Stonecutting { recipe_id, group, ingredient, @@ -268,7 +276,7 @@ impl<'a> Encode for DeclaredRecipe<'a> { ingredient.encode(&mut w)?; result.encode(w) } - DeclaredRecipe::Smithing { + Recipe::Smithing { recipe_id, base, addition, @@ -284,7 +292,7 @@ impl<'a> Encode for DeclaredRecipe<'a> { } } -impl<'a> Decode<'a> for DeclaredRecipe<'a> { +impl<'a> Decode<'a> for Recipe<'a> { fn decode(r: &mut &'a [u8]) -> anyhow::Result { Ok(match Ident::<&str>::decode(r)?.path() { "crafting_shapeless" => Self::CraftingShapeless { diff --git a/crates/valence_protocol/src/packet/s2c/play/synchronize_tags.rs b/crates/valence_protocol/src/packet/s2c/play/synchronize_tags.rs new file mode 100644 index 0000000..7ab0209 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/synchronize_tags.rs @@ -0,0 +1,20 @@ +use crate::ident::Ident; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct SynchronizeTagsS2c<'a> { + pub tags: Vec>, +} + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub struct TagGroup<'a> { + pub kind: Ident<&'a str>, + pub tags: Vec>, +} + +#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] +pub struct Tag<'a> { + pub name: Ident<&'a str>, + pub entries: Vec, +} diff --git a/crates/valence_protocol/src/packets/s2c/update_teams.rs b/crates/valence_protocol/src/packet/s2c/play/team.rs similarity index 93% rename from crates/valence_protocol/src/packets/s2c/update_teams.rs rename to crates/valence_protocol/src/packet/s2c/play/team.rs index 46848e6..fd3052f 100644 --- a/crates/valence_protocol/src/packets/s2c/update_teams.rs +++ b/crates/valence_protocol/src/packet/s2c/play/team.rs @@ -4,10 +4,17 @@ use std::io::Write; use anyhow::bail; use bitfield_struct::bitfield; -use crate::{Decode, Encode, Text}; +use crate::text::Text; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct TeamS2c<'a> { + pub team_name: &'a str, + pub mode: Mode<'a>, +} #[derive(Clone, PartialEq, Debug)] -pub enum UpdateTeamsMode<'a> { +pub enum Mode<'a> { CreateTeam { team_display_name: Cow<'a, Text>, friendly_flags: TeamFlags, @@ -87,10 +94,10 @@ pub enum TeamColor { Reset, } -impl Encode for UpdateTeamsMode<'_> { +impl Encode for Mode<'_> { fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { match self { - UpdateTeamsMode::CreateTeam { + Mode::CreateTeam { team_display_name, friendly_flags, name_tag_visibility, @@ -122,8 +129,8 @@ impl Encode for UpdateTeamsMode<'_> { team_suffix.encode(&mut w)?; entities.encode(&mut w)?; } - UpdateTeamsMode::RemoveTeam => 1i8.encode(&mut w)?, - UpdateTeamsMode::UpdateTeamInfo { + Mode::RemoveTeam => 1i8.encode(&mut w)?, + Mode::UpdateTeamInfo { team_display_name, friendly_flags, name_tag_visibility, @@ -153,11 +160,11 @@ impl Encode for UpdateTeamsMode<'_> { team_prefix.encode(&mut w)?; team_suffix.encode(&mut w)?; } - UpdateTeamsMode::AddEntities { entities } => { + Mode::AddEntities { entities } => { 3i8.encode(&mut w)?; entities.encode(&mut w)?; } - UpdateTeamsMode::RemoveEntities { entities } => { + Mode::RemoveEntities { entities } => { 4i8.encode(&mut w)?; entities.encode(&mut w)?; } @@ -166,7 +173,7 @@ impl Encode for UpdateTeamsMode<'_> { } } -impl<'a> Decode<'a> for UpdateTeamsMode<'a> { +impl<'a> Decode<'a> for Mode<'a> { fn decode(r: &mut &'a [u8]) -> anyhow::Result { Ok(match i8::decode(r)? { 0 => Self::CreateTeam { diff --git a/crates/valence_protocol/src/packet/s2c/play/title.rs b/crates/valence_protocol/src/packet/s2c/play/title.rs new file mode 100644 index 0000000..794f27e --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/title.rs @@ -0,0 +1,9 @@ +use std::borrow::Cow; + +use crate::text::Text; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct TitleS2c<'a> { + pub title_text: Cow<'a, Text>, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/title_fade.rs b/crates/valence_protocol/src/packet/s2c/play/title_fade.rs new file mode 100644 index 0000000..517d88c --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/title_fade.rs @@ -0,0 +1,11 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct TitleFadeS2c { + /// Ticks to spend fading in. + pub fade_in: i32, + /// Ticks to keep the title displayed. + pub stay: i32, + /// Ticks to spend fading out. + pub fade_out: i32, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/unload_chunk.rs b/crates/valence_protocol/src/packet/s2c/play/unload_chunk.rs new file mode 100644 index 0000000..06a4ece --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/unload_chunk.rs @@ -0,0 +1,7 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct UnloadChunkS2c { + pub chunk_x: i32, + pub chunk_z: i32, +} diff --git a/crates/valence_protocol/src/packets/s2c/update_recipe_book.rs b/crates/valence_protocol/src/packet/s2c/play/unlock_recipes.rs similarity index 91% rename from crates/valence_protocol/src/packets/s2c/update_recipe_book.rs rename to crates/valence_protocol/src/packet/s2c/play/unlock_recipes.rs index a7bcd61..406c89f 100644 --- a/crates/valence_protocol/src/packets/s2c/update_recipe_book.rs +++ b/crates/valence_protocol/src/packet/s2c/play/unlock_recipes.rs @@ -2,11 +2,12 @@ use std::io::Write; use anyhow::bail; -use crate::{Decode, DecodePacket, Encode, EncodePacket, Ident, VarInt}; +use crate::ident::Ident; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; -#[derive(Clone, PartialEq, Eq, Debug, EncodePacket, DecodePacket)] -#[packet_id = 0x39] -pub struct UpdateRecipeBook<'a> { +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct UnlockRecipesS2c<'a> { pub action: UpdateRecipeBookAction<'a>, pub crafting_recipe_book_open: bool, pub crafting_recipe_book_filter_active: bool, @@ -26,7 +27,7 @@ pub enum UpdateRecipeBookAction<'a> { Remove, } -impl Encode for UpdateRecipeBook<'_> { +impl Encode for UnlockRecipesS2c<'_> { fn encode(&self, mut w: impl Write) -> anyhow::Result<()> { VarInt(match &self.action { UpdateRecipeBookAction::Init { .. } => 0, @@ -53,7 +54,7 @@ impl Encode for UpdateRecipeBook<'_> { } } -impl<'a> Decode<'a> for UpdateRecipeBook<'a> { +impl<'a> Decode<'a> for UnlockRecipesS2c<'a> { fn decode(r: &mut &'a [u8]) -> anyhow::Result { let action_id = VarInt::decode(r)?.0; diff --git a/crates/valence_protocol/src/packet/s2c/play/update_selected_slot.rs b/crates/valence_protocol/src/packet/s2c/play/update_selected_slot.rs new file mode 100644 index 0000000..a721de0 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/update_selected_slot.rs @@ -0,0 +1,6 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct UpdateSelectedSlotS2c { + pub slot: u8, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/vehicle_move.rs b/crates/valence_protocol/src/packet/s2c/play/vehicle_move.rs new file mode 100644 index 0000000..fa65067 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/vehicle_move.rs @@ -0,0 +1,8 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct VehicleMoveS2c { + pub position: [f64; 3], + pub yaw: f32, + pub pitch: f32, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/world_border_center_changed.rs b/crates/valence_protocol/src/packet/s2c/play/world_border_center_changed.rs new file mode 100644 index 0000000..b8852c1 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/world_border_center_changed.rs @@ -0,0 +1,6 @@ +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct WorldBorderCenterChangedS2c { + pub xz_position: [f64; 2], +} diff --git a/crates/valence_protocol/src/packet/s2c/play/world_border_initialize.rs b/crates/valence_protocol/src/packet/s2c/play/world_border_initialize.rs new file mode 100644 index 0000000..06413a5 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/world_border_initialize.rs @@ -0,0 +1,15 @@ +use crate::var_int::VarInt; +use crate::var_long::VarLong; +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct WorldBorderInitializeS2c { + pub x: f64, + pub z: f64, + pub old_diameter: f64, + pub new_diameter: f64, + pub speed: VarLong, + pub portal_teleport_boundary: VarInt, + pub warning_blocks: VarInt, + pub warning_time: VarInt, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/world_border_interpolate_size.rs b/crates/valence_protocol/src/packet/s2c/play/world_border_interpolate_size.rs new file mode 100644 index 0000000..a4020b8 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/world_border_interpolate_size.rs @@ -0,0 +1,9 @@ +use crate::var_long::VarLong; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct WorldBorderInterpolateSizeS2c { + pub old_diameter: f64, + pub new_diameter: f64, + pub speed: VarLong, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/world_border_size_changed.rs b/crates/valence_protocol/src/packet/s2c/play/world_border_size_changed.rs new file mode 100644 index 0000000..bf3f626 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/world_border_size_changed.rs @@ -0,0 +1,6 @@ +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct WorldBorderSizeChangedS2c { + pub diameter: f64, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/world_border_warning_blocks_changed.rs b/crates/valence_protocol/src/packet/s2c/play/world_border_warning_blocks_changed.rs new file mode 100644 index 0000000..cbbe53b --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/world_border_warning_blocks_changed.rs @@ -0,0 +1,7 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct WorldBorderWarningBlocksChangedS2c { + pub warning_blocks: VarInt, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/world_border_warning_time_changed.rs b/crates/valence_protocol/src/packet/s2c/play/world_border_warning_time_changed.rs new file mode 100644 index 0000000..9d8a5d4 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/world_border_warning_time_changed.rs @@ -0,0 +1,7 @@ +use crate::var_int::VarInt; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct WorldBorderWarningTimeChangedS2c { + pub warning_time: VarInt, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/world_event.rs b/crates/valence_protocol/src/packet/s2c/play/world_event.rs new file mode 100644 index 0000000..2a1e087 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/world_event.rs @@ -0,0 +1,10 @@ +use crate::block_pos::BlockPos; +use crate::{Decode, Encode}; + +#[derive(Clone, Debug, Encode, Decode)] +pub struct WorldEventS2c { + pub event: i32, + pub location: BlockPos, + pub data: i32, + pub disable_relative_volume: bool, +} diff --git a/crates/valence_protocol/src/packet/s2c/play/world_time_update.rs b/crates/valence_protocol/src/packet/s2c/play/world_time_update.rs new file mode 100644 index 0000000..7b0bbcd --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/play/world_time_update.rs @@ -0,0 +1,11 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +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_protocol/src/packet/s2c/status/query_pong.rs b/crates/valence_protocol/src/packet/s2c/status/query_pong.rs new file mode 100644 index 0000000..1c0058b --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/status/query_pong.rs @@ -0,0 +1,6 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct QueryPongS2c { + pub payload: u64, +} diff --git a/crates/valence_protocol/src/packet/s2c/status/query_response.rs b/crates/valence_protocol/src/packet/s2c/status/query_response.rs new file mode 100644 index 0000000..b448409 --- /dev/null +++ b/crates/valence_protocol/src/packet/s2c/status/query_response.rs @@ -0,0 +1,6 @@ +use crate::{Decode, Encode}; + +#[derive(Copy, Clone, Debug, Encode, Decode)] +pub struct QueryResponseS2c<'a> { + pub json: &'a str, +} diff --git a/crates/valence_protocol/src/packets/c2s.rs b/crates/valence_protocol/src/packets/c2s.rs deleted file mode 100644 index 6ba19d5..0000000 --- a/crates/valence_protocol/src/packets/c2s.rs +++ /dev/null @@ -1,571 +0,0 @@ -use uuid::Uuid; - -use crate::block::BlockFace; -use crate::block_pos::BlockPos; -use crate::ident::Ident; -use crate::item::ItemStack; -use crate::raw_bytes::RawBytes; -use crate::types::{ - Action, ChatMode, ClickContainerMode, CommandArgumentSignature, CommandBlockFlags, - CommandBlockMode, Difficulty, DiggingStatus, DisplayedSkinParts, EntityInteraction, Hand, - HandshakeNextState, MainHand, PlayerInputFlags, RecipeBookId, StructureBlockAction, - StructureBlockFlags, StructureBlockMirror, StructureBlockMode, StructureBlockRotation, -}; -use crate::username::Username; -use crate::var_int::VarInt; -use crate::var_long::VarLong; -use crate::{Decode, DecodePacket, Encode, EncodePacket}; - -pub mod handshake { - use super::*; - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x00] - pub struct Handshake<'a> { - pub protocol_version: VarInt, - pub server_address: &'a str, - pub server_port: u16, - pub next_state: HandshakeNextState, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x00] - pub struct HandshakeOwned { - pub protocol_version: VarInt, - pub server_address: String, - pub server_port: u16, - pub next_state: HandshakeNextState, - } - - packet_enum! { - #[derive(Clone)] - C2sHandshakePacket<'a> { - Handshake<'a> - } - } -} - -pub mod status { - use super::*; - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x00] - pub struct StatusRequest; - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x01] - pub struct PingRequest { - pub payload: u64, - } - - packet_enum! { - #[derive(Clone)] - C2sStatusPacket { - StatusRequest, - PingRequest, - } - } -} - -pub mod login { - use super::*; - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x00] - pub struct LoginStart<'a> { - pub username: Username<&'a str>, - pub profile_id: Option, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x01] - pub struct EncryptionResponse<'a> { - pub shared_secret: &'a [u8], - pub verify_token: &'a [u8], - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x02] - pub struct LoginPluginResponse<'a> { - pub message_id: VarInt, - pub data: Option>, - } - - packet_enum! { - #[derive(Clone)] - C2sLoginPacket<'a> { - LoginStart<'a>, - EncryptionResponse<'a>, - LoginPluginResponse<'a>, - } - } -} - -pub mod play { - use super::*; - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x00] - pub struct ConfirmTeleport { - pub teleport_id: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x01] - pub struct QueryBlockEntityTag { - pub transaction_id: VarInt, - pub position: BlockPos, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x02] - pub struct ChangeDifficulty { - pub new_difficulty: Difficulty, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x03] - pub struct MessageAcknowledgmentC2s { - pub message_count: VarInt, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x04] - pub struct ChatCommand<'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: &'a [u8; 3], - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x05] - pub struct ChatMessage<'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: &'a [u8; 3], - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x06] - pub enum ClientCommand { - PerformRespawn, - RequestStats, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x07] - pub struct ClientInformation<'a> { - pub locale: &'a str, - pub view_distance: u8, - pub chat_mode: ChatMode, - pub chat_colors: bool, - pub displayed_skin_parts: DisplayedSkinParts, - pub main_hand: MainHand, - pub enable_text_filtering: bool, - pub allow_server_listings: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x08] - pub struct CommandSuggestionsRequest<'a> { - pub transaction_id: VarInt, - pub text: &'a str, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x09] - pub struct ClickContainerButton { - pub window_id: i8, - pub button_id: i8, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x0a] - pub struct ClickContainer { - pub window_id: u8, - pub state_id: VarInt, - pub slot_idx: i16, - pub button: i8, - pub mode: ClickContainerMode, - pub slots: Vec<(i16, Option)>, - pub carried_item: Option, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x0b] - pub struct CloseContainerC2s { - pub window_id: i8, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x0c] - pub struct PluginMessageC2s<'a> { - pub channel: Ident<&'a str>, - pub data: RawBytes<'a>, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x0d] - pub struct EditBook<'a> { - pub slot: VarInt, - pub entries: Vec<&'a str>, - pub title: Option<&'a str>, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x0e] - pub struct QueryEntityTag { - pub transaction_id: VarInt, - pub entity_id: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x0f] - pub struct Interact { - pub entity_id: VarInt, - pub interact: EntityInteraction, - pub sneaking: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x10] - pub struct JigsawGenerate { - pub position: BlockPos, - pub levels: VarInt, - pub keep_jigsaws: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x11] - pub struct KeepAliveC2s { - pub id: u64, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x12] - pub struct LockDifficulty { - pub locked: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x13] - pub struct SetPlayerPosition { - pub position: [f64; 3], - pub on_ground: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x14] - pub struct SetPlayerPositionAndRotation { - pub position: [f64; 3], - pub yaw: f32, - pub pitch: f32, - pub on_ground: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x15] - pub struct SetPlayerRotation { - pub yaw: f32, - pub pitch: f32, - pub on_ground: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x16] - pub struct SetPlayerOnGround { - pub on_ground: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x17] - pub struct MoveVehicleC2s { - pub position: [f64; 3], - pub yaw: f32, - pub pitch: f32, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x18] - pub struct PaddleBoat { - pub left_paddle_turning: bool, - pub right_paddle_turning: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x19] - pub struct PickItem { - pub slot_to_use: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x1a] - pub struct PlaceRecipe<'a> { - pub window_id: i8, - pub recipe: Ident<&'a str>, - pub make_all: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x1b] - pub enum PlayerAbilitiesC2s { - #[tag = 0b00] - StopFlying, - #[tag = 0b10] - StartFlying, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x1c] - pub struct PlayerAction { - pub status: DiggingStatus, - pub position: BlockPos, - pub face: BlockFace, - pub sequence: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x1d] - pub struct PlayerCommand { - pub entity_id: VarInt, - pub action_id: Action, - pub jump_boost: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x1e] - pub struct PlayerInput { - pub sideways: f32, - pub forward: f32, - pub flags: PlayerInputFlags, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x1f] - pub struct PongPlay { - pub id: i32, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x20] - pub struct PlayerSession<'a> { - pub session_id: Uuid, - // Public key - pub expires_at: i64, - pub public_key_data: &'a [u8], - pub key_signature: &'a [u8], - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x21] - pub struct ChangeRecipeBookSettings { - pub book_id: RecipeBookId, - pub book_open: bool, - pub filter_active: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x22] - pub struct SetSeenRecipe<'a> { - pub recipe_id: Ident<&'a str>, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x23] - pub struct RenameItem<'a> { - pub item_name: &'a str, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x24] - pub enum ResourcePackC2s { - SuccessfullyLoaded, - Declined, - FailedDownload, - Accepted, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x25] - pub enum SeenAdvancements<'a> { - OpenedTab { tab_id: Ident<&'a str> }, - ClosedScreen, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x26] - pub struct SelectTrade { - pub selected_slot: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x27] - pub struct SetBeaconEffect { - pub primary_effect: Option, - pub secondary_effect: Option, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x28] - pub struct SetHeldItemC2s { - pub slot: i16, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x29] - pub struct ProgramCommandBlock<'a> { - pub position: BlockPos, - pub command: &'a str, - pub mode: CommandBlockMode, - pub flags: CommandBlockFlags, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x2a] - pub struct ProgramCommandBlockMinecart<'a> { - pub entity_id: VarInt, - pub command: &'a str, - pub track_output: bool, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x2b] - pub struct SetCreativeModeSlot { - pub slot: i16, - pub clicked_item: Option, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x2c] - pub struct ProgramJigsawBlock<'a> { - pub position: BlockPos, - pub name: Ident<&'a str>, - pub target: Ident<&'a str>, - pub pool: Ident<&'a str>, - pub final_state: &'a str, - pub joint_type: &'a str, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x2d] - pub struct ProgramStructureBlock<'a> { - pub position: BlockPos, - pub action: StructureBlockAction, - pub mode: StructureBlockMode, - pub name: &'a str, - pub offset_xyz: [i8; 3], - pub size_xyz: [i8; 3], - pub mirror: StructureBlockMirror, - pub rotation: StructureBlockRotation, - pub metadata: &'a str, - pub integrity: f32, - pub seed: VarLong, - pub flags: StructureBlockFlags, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x2e] - pub struct UpdateSign<'a> { - pub position: BlockPos, - pub lines: [&'a str; 4], - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x2f] - pub struct SwingArm { - pub hand: Hand, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x30] - pub struct TeleportToEntity { - pub target: Uuid, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x31] - pub struct UseItemOn { - pub hand: Hand, - pub position: BlockPos, - pub face: BlockFace, - pub cursor_pos: [f32; 3], - pub head_inside_block: bool, - pub sequence: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x32] - pub struct UseItem { - pub hand: Hand, - pub sequence: VarInt, - } - - packet_enum! { - #[derive(Clone)] - C2sPlayPacket<'a> { - ConfirmTeleport, - QueryBlockEntityTag, - ChangeDifficulty, - MessageAcknowledgmentC2s, - ChatCommand<'a>, - ChatMessage<'a>, - ClientCommand, - ClientInformation<'a>, - CommandSuggestionsRequest<'a>, - ClickContainerButton, - ClickContainer, - CloseContainerC2s, - PluginMessageC2s<'a>, - EditBook<'a>, - QueryEntityTag, - Interact, - JigsawGenerate, - KeepAliveC2s, - LockDifficulty, - SetPlayerPosition, - SetPlayerPositionAndRotation, - SetPlayerRotation, - SetPlayerOnGround, - MoveVehicleC2s, - PaddleBoat, - PickItem, - PlaceRecipe<'a>, - PlayerAbilitiesC2s, - PlayerAction, - PlayerCommand, - PlayerInput, - PongPlay, - PlayerSession<'a>, - ChangeRecipeBookSettings, - SetSeenRecipe<'a>, - RenameItem<'a>, - ResourcePackC2s, - SeenAdvancements<'a>, - SelectTrade, - SetBeaconEffect, - SetHeldItemC2s, - ProgramCommandBlock<'a>, - ProgramCommandBlockMinecart<'a>, - SetCreativeModeSlot, - ProgramJigsawBlock<'a>, - ProgramStructureBlock<'a>, - UpdateSign<'a>, - SwingArm, - TeleportToEntity, - UseItemOn, - UseItem - } - } -} diff --git a/crates/valence_protocol/src/packets/s2c.rs b/crates/valence_protocol/src/packets/s2c.rs deleted file mode 100644 index 3d0d86e..0000000 --- a/crates/valence_protocol/src/packets/s2c.rs +++ /dev/null @@ -1,1086 +0,0 @@ -use std::borrow::Cow; - -use uuid::Uuid; -use valence_nbt::Compound; - -use crate::block::BlockEntityKind; -use crate::block_pos::BlockPos; -use crate::byte_angle::ByteAngle; -use crate::ident::Ident; -use crate::item::ItemStack; -use crate::raw_bytes::RawBytes; -use crate::text::Text; -use crate::types::{ - AttributeProperty, BossBarAction, ChatSuggestionAction, ChunkDataBlockEntity, - CommandSuggestionMatch, Difficulty, EntityEffectFlags, FeetOrEyes, GameEventKind, GameMode, - GlobalPos, Hand, LookAtEntity, MerchantTrade, PlayerAbilitiesFlags, Property, SoundCategory, - Statistic, SyncPlayerPosLookFlags, TagGroup, UpdateObjectiveMode, UpdateScoreAction, - WindowType, -}; -use crate::username::Username; -use crate::var_int::VarInt; -use crate::var_long::VarLong; -use crate::{Decode, DecodePacket, Encode, EncodePacket, LengthPrefixedArray}; - -pub mod commands; -pub mod declare_recipes; -pub mod map_data; -pub mod message_signature; -pub mod particle; -pub mod player_chat_message; -pub mod player_info_update; -pub mod set_equipment; -pub mod sound_id; -pub mod stop_sound; -pub mod update_advancements; -pub mod update_recipe_book; -pub mod update_teams; - -pub mod status { - use super::*; - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x00] - pub struct StatusResponse<'a> { - pub json: &'a str, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x01] - pub struct PingResponse { - pub payload: u64, - } - - packet_enum! { - #[derive(Clone)] - S2cStatusPacket<'a> { - StatusResponse<'a>, - PingResponse, - } - } -} - -pub mod login { - use super::*; - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x00] - pub struct DisconnectLogin<'a> { - pub reason: Cow<'a, Text>, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x01] - pub struct EncryptionRequest<'a> { - pub server_id: &'a str, - pub public_key: &'a [u8], - pub verify_token: &'a [u8], - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x02] - pub struct LoginSuccess<'a> { - pub uuid: Uuid, - pub username: Username<&'a str>, - pub properties: Cow<'a, [Property]>, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x03] - pub struct SetCompression { - pub threshold: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x04] - pub struct LoginPluginRequest<'a> { - pub message_id: VarInt, - pub channel: Ident<&'a str>, - pub data: RawBytes<'a>, - } - - packet_enum! { - #[derive(Clone)] - S2cLoginPacket<'a> { - DisconnectLogin<'a>, - EncryptionRequest<'a>, - LoginSuccess<'a>, - SetCompression, - LoginPluginRequest<'a>, - } - } -} - -pub mod play { - use commands::Node; - pub use map_data::MapData; - pub use message_signature::MessageSignature; - pub use particle::ParticleS2c; - pub use player_chat_message::PlayerChatMessage; - pub use player_info_update::PlayerInfoUpdate; - pub use set_equipment::SetEquipment; - pub use sound_id::SoundId; - pub use stop_sound::StopSound; - pub use update_advancements::UpdateAdvancements; - pub use update_recipe_book::UpdateRecipeBook; - - use super::*; - use crate::packets::s2c::declare_recipes::DeclaredRecipe; - use crate::packets::s2c::update_teams::UpdateTeamsMode; - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x00] - pub struct SpawnEntity { - pub entity_id: VarInt, - pub object_uuid: Uuid, - // TODO: EntityKind type? - pub kind: VarInt, - pub position: [f64; 3], - pub pitch: ByteAngle, - pub yaw: ByteAngle, - pub head_yaw: ByteAngle, - pub data: VarInt, - pub velocity: [i16; 3], - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x01] - pub struct SpawnExperienceOrb { - pub entity_id: VarInt, - pub position: [f64; 3], - pub count: i16, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x02] - pub struct SpawnPlayer { - pub entity_id: VarInt, - pub player_uuid: Uuid, - pub position: [f64; 3], - pub yaw: ByteAngle, - pub pitch: ByteAngle, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x03] - pub struct EntityAnimationS2c { - pub entity_id: VarInt, - pub animation: u8, // TODO: use Animation enum. - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x04] - pub struct AwardStatistics { - pub statistics: Vec, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x05] - pub struct AcknowledgeBlockChange { - pub sequence: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x06] - pub struct SetBlockDestroyStage { - pub entity_id: VarInt, - pub position: BlockPos, - pub destroy_stage: u8, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x07] - pub struct BlockEntityData<'a> { - pub position: BlockPos, - pub kind: BlockEntityKind, - pub data: Cow<'a, Compound>, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x08] - pub struct BlockAction { - pub position: BlockPos, - pub action_id: u8, - pub action_parameter: u8, - pub block_type: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x09] - pub struct BlockUpdate { - pub position: BlockPos, - pub block_id: VarInt, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x0a] - pub struct BossBar { - pub id: Uuid, - pub action: BossBarAction, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x0b] - pub struct SetDifficulty { - pub difficulty: Difficulty, - pub locked: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x0c] - pub struct ClearTitles { - pub reset: bool, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x0d] - pub struct CommandSuggestionResponse<'a> { - pub id: VarInt, - pub start: VarInt, - pub length: VarInt, - pub matches: Vec>, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x0e] - pub struct Commands<'a> { - pub commands: Vec>, - pub root_index: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x0f] - pub struct CloseContainerS2c { - /// Ignored by notchian clients. - pub window_id: u8, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x10] - pub struct SetContainerContent { - pub window_id: u8, - pub state_id: VarInt, - pub slots: Vec>, - pub carried_item: Option, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket)] - #[packet_id = 0x10] - pub struct SetContainerContentEncode<'a> { - pub window_id: u8, - pub state_id: VarInt, - pub slots: &'a [Option], - pub carried_item: &'a Option, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x11] - pub struct SetContainerProperty { - pub window_id: u8, - pub property: i16, - pub value: i16, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x12] - pub struct SetContainerSlot { - pub window_id: i8, - pub state_id: VarInt, - pub slot_idx: i16, - pub slot_data: Option, - } - - #[derive(Clone, Debug, Encode, EncodePacket)] - #[packet_id = 0x12] - pub struct SetContainerSlotEncode<'a> { - pub window_id: i8, - pub state_id: VarInt, - pub slot_idx: i16, - pub slot_data: Option<&'a ItemStack>, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x13] - pub struct SetCooldown { - pub item_id: VarInt, - pub cooldown_ticks: VarInt, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x14] - pub struct ChatSuggestions<'a> { - pub action: ChatSuggestionAction, - pub entries: Vec<&'a str>, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x15] - pub struct PluginMessageS2c<'a> { - pub channel: Ident<&'a str>, - pub data: RawBytes<'a>, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x16] - pub struct DeleteMessage<'a> { - pub signature: MessageSignature<'a>, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x17] - pub struct DisconnectPlay<'a> { - pub reason: Cow<'a, Text>, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x18] - pub struct DisguisedChatMessage<'a> { - pub message: Cow<'a, Text>, - pub chat_type: VarInt, - pub chat_type_name: Cow<'a, Text>, - pub target_name: Option>, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x19] - pub struct EntityEvent { - pub entity_id: i32, - pub entity_status: u8, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x1a] - pub struct PlaceRecipe<'a> { - pub window_id: u8, - pub recipe: Ident<&'a str>, - pub make_all: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x1b] - pub struct UnloadChunk { - pub chunk_x: i32, - pub chunk_z: i32, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x1c] - pub struct GameEvent { - pub kind: GameEventKind, - pub value: f32, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x1d] - pub struct OpenHorseScreen { - pub window_id: u8, - pub slot_count: VarInt, - pub entity_id: i32, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x1e] - pub struct WorldBorderInitialize { - pub x: f64, - pub z: f64, - pub old_diameter: f64, - pub new_diameter: f64, - pub speed: VarLong, - pub portal_teleport_boundary: VarInt, - pub warning_blocks: VarInt, - pub warning_time: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x1f] - pub struct KeepAliveS2c { - pub id: u64, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x20] - pub struct ChunkDataAndUpdateLight<'a> { - pub chunk_x: i32, - pub chunk_z: i32, - pub heightmaps: Compound, - pub blocks_and_biomes: &'a [u8], - pub block_entities: Vec>, - pub trust_edges: bool, - 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(Clone, Debug, Encode, EncodePacket)] - #[packet_id = 0x20] - pub struct ChunkDataAndUpdateLightEncode<'a> { - pub chunk_x: i32, - pub chunk_z: i32, - pub heightmaps: &'a Compound, - pub blocks_and_biomes: &'a [u8], - pub block_entities: &'a [ChunkDataBlockEntity<'a>], - pub trust_edges: bool, - pub sky_light_mask: &'a [u64], - pub block_light_mask: &'a [u64], - pub empty_sky_light_mask: &'a [u64], - pub empty_block_light_mask: &'a [u64], - pub sky_light_arrays: &'a [LengthPrefixedArray], - pub block_light_arrays: &'a [LengthPrefixedArray], - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x21] - pub struct WorldEvent { - pub event: i32, - pub location: BlockPos, - pub data: i32, - pub disable_relative_volume: bool, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x23] - pub struct UpdateLight { - pub chunk_x: VarInt, - pub chunk_z: VarInt, - pub trust_edges: bool, - 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(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x24] - pub struct LoginPlay<'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<&'a str>, - pub dimension_name: Ident<&'a str>, - 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>, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x26] - pub struct MerchantOffers { - pub window_id: VarInt, - pub trades: Vec, - pub villager_level: VarInt, - pub experience: VarInt, - pub is_regular_villager: bool, - pub can_restock: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x27] - pub struct UpdateEntityPosition { - pub entity_id: VarInt, - pub delta: [i16; 3], - pub on_ground: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x28] - pub struct UpdateEntityPositionAndRotation { - pub entity_id: VarInt, - pub delta: [i16; 3], - pub yaw: ByteAngle, - pub pitch: ByteAngle, - pub on_ground: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x29] - pub struct UpdateEntityRotation { - pub entity_id: VarInt, - pub yaw: ByteAngle, - pub pitch: ByteAngle, - pub on_ground: bool, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x2a] - pub struct MoveVehicle { - pub position: [f64; 3], - pub yaw: f32, - pub pitch: f32, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x2b] - pub struct OpenBook { - pub hand: Hand, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x2c] - pub struct OpenScreen<'a> { - pub window_id: VarInt, - pub window_type: WindowType, - pub window_title: Cow<'a, Text>, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x2d] - pub struct OpenSignEditor { - pub location: BlockPos, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x2e] - pub struct PingPlay { - pub id: i32, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x2f] - pub struct PlaceGhostRecipe<'a> { - pub window_id: u8, - pub recipe: Ident<&'a str>, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x30] - pub struct PlayerAbilitiesS2c { - pub flags: PlayerAbilitiesFlags, - pub flying_speed: f32, - pub fov_modifier: f32, - } - - /// Unused by notchian clients. - #[derive(Copy, Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x32] - pub struct EndCombat { - pub duration: VarInt, - pub entity_id: i32, - } - - /// Unused by notchian clients. - #[derive(Copy, Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x33] - pub struct EnterCombat {} - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x34] - pub struct CombatDeath<'a> { - pub player_id: VarInt, - /// Killer's entity ID, -1 if no killer - pub entity_id: i32, - pub message: Cow<'a, Text>, - } - - #[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x35] - pub struct PlayerInfoRemove<'a> { - pub uuids: Cow<'a, [Uuid]>, - } - - #[derive(Copy, Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x37] - pub struct LookAt { - pub feet_eyes: FeetOrEyes, - pub target_position: [f64; 3], - pub entity_to_face: Option, - } - - #[derive(Copy, Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x38] - pub struct SynchronizePlayerPosition { - pub position: [f64; 3], - pub yaw: f32, - pub pitch: f32, - pub flags: SyncPlayerPosLookFlags, - pub teleport_id: VarInt, - pub dismount_vehicle: bool, - } - - #[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x3a] - pub struct RemoveEntities { - pub entity_ids: Vec, - } - - #[derive(Copy, Clone, PartialEq, Debug, Encode, EncodePacket)] - #[packet_id = 0x3a] - pub struct RemoveEntitiesEncode<'a> { - pub entity_ids: &'a [VarInt], - } - - #[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x3b] - pub struct RemoveEntityEffect { - pub entity_id: VarInt, - pub effect_id: VarInt, - } - - #[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x3c] - pub struct ResourcePackS2c<'a> { - pub url: &'a str, - pub hash: &'a str, - pub forced: bool, - pub prompt_message: Option>, - } - - #[derive(Clone, PartialEq, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x3d] - pub struct Respawn<'a> { - pub dimension_type_name: Ident<&'a str>, - pub dimension_name: Ident<&'a str>, - 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>, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x3e] - pub struct SetHeadRotation { - pub entity_id: VarInt, - pub head_yaw: ByteAngle, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x3f] - pub struct UpdateSectionBlocks { - pub chunk_section_position: i64, - pub invert_trust_edges: bool, - pub blocks: Vec, - } - - #[derive(Clone, Debug, Encode, EncodePacket)] - #[packet_id = 0x3f] - pub struct UpdateSectionBlocksEncode<'a> { - pub chunk_section_position: i64, - pub invert_trust_edges: bool, - pub blocks: &'a [VarLong], - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x40] - pub struct SelectAdvancementsTab<'a> { - pub identifier: Option>, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x41] - pub struct ServerData<'a> { - pub motd: Option>, - pub icon: Option<&'a str>, - pub enforce_secure_chat: bool, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x42] - pub struct SetActionBarText<'a> { - pub action_bar_text: Cow<'a, Text>, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x43] - pub struct SetBorderCenter { - pub xz_position: [f64; 2], - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x44] - pub struct SetBorderLerpSize { - pub old_diameter: f64, - pub new_diameter: f64, - pub speed: VarLong, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x45] - pub struct SetBorderSize { - pub diameter: f64, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x46] - pub struct SetBorderWarningDelay { - pub warning_time: VarInt, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x47] - pub struct SetBorderWarningDistance { - pub warning_blocks: VarInt, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x48] - pub struct SetCamera { - pub entity_id: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x49] - pub struct SetHeldItemS2c { - pub slot: u8, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x4a] - pub struct SetCenterChunk { - pub chunk_x: VarInt, - pub chunk_z: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x4b] - pub struct SetRenderDistance { - pub view_distance: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x4c] - pub struct SetDefaultSpawnPosition { - pub position: BlockPos, - pub angle: f32, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x4d] - pub struct DisplayObjective<'a> { - pub position: u8, - pub score_name: &'a str, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x4e] - pub struct SetEntityMetadata<'a> { - pub entity_id: VarInt, - pub metadata: RawBytes<'a>, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x4f] - pub struct LinkEntities { - pub attached_entity_id: i32, - pub holding_entity_id: i32, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x50] - pub struct SetEntityVelocity { - pub entity_id: VarInt, - pub velocity: [i16; 3], - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x52] - pub struct SetExperience { - pub bar: f32, - pub level: VarInt, - pub total_xp: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x53] - pub struct SetHealth { - pub health: f32, - pub food: VarInt, - pub food_saturation: f32, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x54] - pub struct UpdateObjectives<'a> { - pub objective_name: &'a str, - pub mode: UpdateObjectiveMode, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x55] - pub struct SetPassengers { - /// Vehicle's entity id - pub entity_id: VarInt, - pub passengers: Vec, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x56] - pub struct UpdateTeams<'a> { - pub team_name: &'a str, - pub mode: UpdateTeamsMode<'a>, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x57] - pub struct UpdateScore<'a> { - pub entity_name: &'a str, - pub action: UpdateScoreAction<'a>, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x58] - pub struct SetSimulationDistance { - pub simulation_distance: VarInt, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x59] - pub struct SetSubtitleText<'a> { - pub subtitle_text: Cow<'a, Text>, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x5a] - pub struct UpdateTime { - /// 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, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x5b] - pub struct SetTitleText<'a> { - pub title_text: Cow<'a, Text>, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x5c] - pub struct SetTitleAnimationTimes { - /// Ticks to spend fading in. - pub fade_in: i32, - /// Ticks to keep the title displayed. - pub stay: i32, - /// Ticks to spend fading out. - pub fade_out: i32, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x5d] - pub struct EntitySoundEffect { - pub id: VarInt, - pub category: SoundCategory, - pub entity_id: VarInt, - pub volume: f32, - pub pitch: f32, - pub seed: i64, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x5e] - pub struct SoundEffect<'a> { - pub id: SoundId<'a>, - pub category: SoundCategory, - pub position: [i32; 3], - pub volume: f32, - pub pitch: f32, - pub seed: i64, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x60] - pub struct SystemChatMessage<'a> { - pub chat: Cow<'a, Text>, - /// Whether the message is in the actionbar or the chat. - pub overlay: bool, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x61] - pub struct SetTabListHeaderAndFooter<'a> { - pub header: Cow<'a, Text>, - pub footer: Cow<'a, Text>, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x62] - pub struct TagQueryResponse { - pub transaction_id: VarInt, - pub nbt: Compound, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x63] - pub struct PickupItem { - pub collected_entity_id: VarInt, - pub collector_entity_id: VarInt, - pub pickup_item_count: VarInt, - } - - #[derive(Copy, Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x64] - pub struct TeleportEntity { - pub entity_id: VarInt, - pub position: [f64; 3], - pub yaw: ByteAngle, - pub pitch: ByteAngle, - pub on_ground: bool, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x66] - pub struct UpdateAttributes<'a> { - pub entity_id: VarInt, - pub properties: Vec>, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x67] - pub struct FeatureFlags<'a> { - pub features: Vec>, - } - - #[derive(Clone, Debug, Encode, EncodePacket, Decode, DecodePacket)] - #[packet_id = 0x68] - pub struct EntityEffect { - pub entity_id: VarInt, - pub effect_id: VarInt, - pub amplifier: u8, - pub duration: VarInt, - pub flags: EntityEffectFlags, - pub factor_codec: Option, - } - - #[derive(Clone, Debug, Encode, Decode, EncodePacket, DecodePacket)] - #[packet_id = 0x69] - pub struct DeclareRecipes<'a> { - pub recipes: Vec>, - } - - #[derive(Clone, Debug, Encode, Decode, EncodePacket, DecodePacket)] - #[packet_id = 0x6a] - pub struct UpdateTags<'a> { - pub tags: Vec>, - } - - packet_enum! { - #[derive(Clone)] - S2cPlayPacket<'a> { - SpawnEntity, - SpawnExperienceOrb, - SpawnPlayer, - EntityAnimationS2c, - AwardStatistics, - AcknowledgeBlockChange, - SetBlockDestroyStage, - BlockEntityData<'a>, - BlockAction, - BlockUpdate, - BossBar, - SetDifficulty, - ClearTitles, - CommandSuggestionResponse<'a>, - Commands<'a>, - CloseContainerS2c, - SetContainerContent, - SetContainerProperty, - SetContainerSlot, - SetCooldown, - ChatSuggestions<'a>, - PluginMessageS2c<'a>, - DeleteMessage<'a>, - DisconnectPlay<'a>, - DisguisedChatMessage<'a>, - EntityEvent, - PlaceRecipe<'a>, - UnloadChunk, - GameEvent, - OpenHorseScreen, - WorldBorderInitialize, - KeepAliveS2c, - ChunkDataAndUpdateLight<'a>, - WorldEvent, - UpdateLight, - ParticleS2c, - LoginPlay<'a>, - MapData<'a>, - MerchantOffers, - UpdateEntityPosition, - UpdateEntityPositionAndRotation, - UpdateEntityRotation, - MoveVehicle, - OpenBook, - OpenScreen<'a>, - OpenSignEditor, - PingPlay, - PlaceGhostRecipe<'a>, - PlayerAbilitiesS2c, - PlayerChatMessage<'a>, - EndCombat, - EnterCombat, - CombatDeath<'a>, - PlayerInfoRemove<'a>, - PlayerInfoUpdate<'a>, - LookAt, - SynchronizePlayerPosition, - UpdateRecipeBook<'a>, - RemoveEntities, - RemoveEntityEffect, - ResourcePackS2c<'a>, - Respawn<'a>, - SetHeadRotation, - UpdateSectionBlocks, - SelectAdvancementsTab<'a>, - ServerData<'a>, - SetActionBarText<'a>, - SetBorderCenter, - SetBorderLerpSize, - SetBorderSize, - SetBorderWarningDelay, - SetBorderWarningDistance, - SetCamera, - SetHeldItemS2c, - SetCenterChunk, - SetRenderDistance, - SetDefaultSpawnPosition, - DisplayObjective<'a>, - SetEntityMetadata<'a>, - LinkEntities, - SetEntityVelocity, - SetEquipment, - SetExperience, - SetHealth, - UpdateObjectives<'a>, - SetPassengers, - UpdateTeams<'a>, - UpdateScore<'a>, - SetSimulationDistance, - SetSubtitleText<'a>, - UpdateTime, - SetTitleText<'a>, - SetTitleAnimationTimes, - EntitySoundEffect, - SoundEffect<'a>, - StopSound<'a>, - SystemChatMessage<'a>, - SetTabListHeaderAndFooter<'a>, - TagQueryResponse, - PickupItem, - TeleportEntity, - UpdateAdvancements<'a>, - UpdateAttributes<'a>, - FeatureFlags<'a>, - EntityEffect, - DeclareRecipes<'a>, - UpdateTags<'a>, - } - } -} diff --git a/crates/valence_protocol/src/packets/s2c/message_signature.rs b/crates/valence_protocol/src/packets/s2c/message_signature.rs deleted file mode 100644 index 3060433..0000000 --- a/crates/valence_protocol/src/packets/s2c/message_signature.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::io::Write; - -use crate::{Decode, Encode, VarInt}; - -#[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; - - let signature = if message_id == -1 { - Some(<&[u8; 256]>::decode(r)?) - } else { - None - }; - - Ok(Self { - message_id, - signature, - }) - } -} diff --git a/crates/valence_protocol/src/raw_bytes.rs b/crates/valence_protocol/src/raw_bytes.rs index 74428b0..c4f90c3 100644 --- a/crates/valence_protocol/src/raw_bytes.rs +++ b/crates/valence_protocol/src/raw_bytes.rs @@ -26,3 +26,15 @@ impl<'a> Decode<'a> for RawBytes<'a> { Ok(Self(slice)) } } + +impl<'a> From<&'a [u8]> for RawBytes<'a> { + fn from(value: &'a [u8]) -> Self { + Self(value) + } +} + +impl<'a> From> for &'a [u8] { + fn from(value: RawBytes<'a>) -> Self { + value.0 + } +} diff --git a/crates/valence_protocol/src/sound.rs b/crates/valence_protocol/src/sound.rs index 61b3beb..e8188c7 100644 --- a/crates/valence_protocol/src/sound.rs +++ b/crates/valence_protocol/src/sound.rs @@ -1,15 +1,12 @@ -// sound.rs exposes constant values provided by the build script. -// All sounds are located in `Sound`. You can use the -// associated const fn functions of `Sound` to access details about a sound. -include!(concat!(env!("OUT_DIR"), "/sound.rs")); +use crate::ident::Ident; +use crate::packet::s2c::play::play_sound::SoundId; -use crate::packets::s2c::play::SoundId; -use crate::Ident; +include!(concat!(env!("OUT_DIR"), "/sound.rs")); impl Sound { pub fn to_id(self) -> SoundId<'static> { SoundId::Direct { - id: Ident::new(self.to_str()).unwrap(), + id: Ident::new(self.to_str()).unwrap(), // TODO: use ident_str. range: None, } } diff --git a/crates/valence_protocol/src/text.rs b/crates/valence_protocol/src/text.rs index e26b322..13fa2f4 100644 --- a/crates/valence_protocol/src/text.rs +++ b/crates/valence_protocol/src/text.rs @@ -10,7 +10,8 @@ use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use uuid::Uuid; use valence_nbt::Value; -use crate::{Decode, Encode, Ident, Result}; +use crate::ident::Ident; +use crate::{Decode, Encode, Result}; /// Represents formatted text in Minecraft's JSON text format. /// diff --git a/crates/valence_protocol/src/entity_meta.rs b/crates/valence_protocol/src/tracked_data.rs similarity index 100% rename from crates/valence_protocol/src/entity_meta.rs rename to crates/valence_protocol/src/tracked_data.rs diff --git a/crates/valence_protocol/src/types.rs b/crates/valence_protocol/src/types.rs index e69f294..fbeca4e 100644 --- a/crates/valence_protocol/src/types.rs +++ b/crates/valence_protocol/src/types.rs @@ -1,22 +1,13 @@ //! Miscellaneous type definitions used in packets. -use std::borrow::Cow; +use std::io::Write; -use bitfield_struct::bitfield; use serde::{Deserialize, Serialize}; -use uuid::Uuid; -use valence_nbt::Compound; -use crate::block::BlockEntityKind; -use crate::{BlockPos, Decode, Encode, Ident, ItemStack, Text, VarInt}; - -#[derive(Copy, Clone, Debug, PartialEq, Eq, Encode, Decode)] -pub enum HandshakeNextState { - #[tag = 1] - Status, - #[tag = 2] - Login, -} +use crate::block_pos::BlockPos; +use crate::ident::Ident; +use crate::var_int::VarInt; +use crate::{Decode, Encode}; #[derive(Copy, Clone, Debug, PartialEq, Eq, Encode, Decode)] pub struct PublicKeyData<'a> { @@ -25,120 +16,12 @@ pub struct PublicKeyData<'a> { pub signature: &'a [u8], } -#[derive(Copy, Clone, Debug, Encode, Decode)] -pub struct CommandArgumentSignature<'a> { - pub argument_name: &'a str, - pub signature: &'a [u8; 256], -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum ChatMode { - Enabled, - CommandsOnly, - Hidden, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Default, Encode, Decode)] -pub enum MainHand { - Left, - #[default] - Right, -} - -#[derive(Copy, Clone, Debug, PartialEq, Eq, Encode, Decode)] -pub enum ClickContainerMode { - Click, - ShiftClick, - Hotbar, - CreativeMiddleClick, - DropKey, - Drag, - DoubleClick, -} - #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] pub enum Hand { Main, Off, } -#[derive(Copy, Clone, PartialEq, Debug, Encode, Decode)] -pub enum EntityInteraction { - Interact(Hand), - Attack, - InteractAt { target: [f32; 3], hand: Hand }, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum DiggingStatus { - StartedDigging, - CancelledDigging, - FinishedDigging, - DropItemStack, - DropItem, - UpdateHeldItemState, - SwapItemInHand, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum Action { - StartSneaking, - StopSneaking, - LeaveBed, - StartSprinting, - StopSprinting, - StartJumpWithHorse, - StopJumpWithHorse, - OpenHorseInventory, - StartFlyingWithElytra, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum RecipeBookId { - Crafting, - Furnace, - BlastFurnace, - Smoker, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum CommandBlockMode { - Sequence, - Auto, - Redstone, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum StructureBlockAction { - UpdateData, - SaveStructure, - LoadStructure, - DetectSize, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum StructureBlockMode { - Save, - Load, - Corner, - Data, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum StructureBlockMirror { - None, - LeftRight, - FrontBack, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum StructureBlockRotation { - None, - Clockwise90, - Clockwise180, - Counterclockwise90, -} - #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode, Serialize, Deserialize)] pub struct Property { pub name: S, @@ -146,62 +29,6 @@ pub struct Property { pub signature: Option, } -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum Animation { - SwingMainArm, - TakeDamage, - LeaveBed, - SwingOffhand, - CriticalEffect, - MagicCriticalEffect, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub enum BossBarAction { - Add { - title: Text, - health: f32, - color: BossBarColor, - division: BossBarDivision, - flags: BossBarFlags, - }, - Remove, - UpdateHealth(f32), - UpdateTitle(Text), - UpdateStyle(BossBarColor, BossBarDivision), - UpdateFlags(BossBarFlags), -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum BossBarColor { - Pink, - Blue, - Red, - Green, - Yellow, - Purple, - White, -} - -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum BossBarDivision { - NoDivision, - SixNotches, - TenNotches, - TwelveNotches, - TwentyNotches, -} - -#[bitfield(u8)] -#[derive(PartialEq, Eq, Encode, Decode)] -pub struct BossBarFlags { - pub darken_sky: bool, - pub dragon_bar: bool, - pub create_fog: bool, - #[bits(5)] - _pad: u8, -} - #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] pub enum Difficulty { Peaceful, @@ -224,30 +51,6 @@ pub enum SoundCategory { Voice, } -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum GameEventKind { - NoRespawnBlockAvailable, - EndRaining, - BeginRaining, - ChangeGameMode, - WinGame, - DemoEvent, - ArrowHitPlayer, - RainLevelChange, - ThunderLevelChange, - PlayPufferfishStingSound, - PlayElderGuardianMobAppearance, - EnableRespawnScreen, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct ChunkDataBlockEntity<'a> { - pub packed_xz: i8, - pub y: i16, - pub kind: BlockEntityKind, - pub data: Cow<'a, Compound>, -} - #[derive(Copy, Clone, PartialEq, Eq, Debug, Default, Encode, Decode)] pub enum GameMode { #[default] @@ -263,104 +66,6 @@ pub struct GlobalPos<'a> { pub position: BlockPos, } -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct AttributeProperty<'a> { - pub key: Ident<&'a str>, - pub value: f64, - pub modifiers: Vec, -} - -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct AttributeModifier { - pub uuid: Uuid, - pub amount: f64, - pub operation: u8, -} - -#[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, -} - -#[bitfield(u8)] -#[derive(PartialEq, Eq, Encode, Decode)] -pub struct PlayerInputFlags { - pub jump: bool, - pub unmount: bool, - #[bits(6)] - _pad: u8, -} - -#[bitfield(u8)] -#[derive(PartialEq, Eq, Encode, Decode)] -pub struct CommandBlockFlags { - pub track_output: bool, - pub conditional: bool, - pub automatic: bool, - #[bits(5)] - _pad: u8, -} - -#[bitfield(u8)] -#[derive(PartialEq, Eq, Encode, Decode)] -pub struct StructureBlockFlags { - pub ignore_entities: bool, - pub show_air: bool, - pub show_bounding_box: bool, - #[bits(5)] - _pad: u8, -} - -#[bitfield(u8)] -#[derive(PartialEq, Eq, Encode, Decode)] -pub struct SyncPlayerPosLookFlags { - pub x: bool, - pub y: bool, - pub z: bool, - pub y_rot: bool, - pub x_rot: bool, - #[bits(3)] - _pad: u8, -} - -#[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, Eq, Debug, Encode, Decode)] -pub struct TagGroup<'a> { - pub kind: Ident<&'a str>, - pub tags: Vec>, -} - -#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub struct Tag<'a> { - pub name: Ident<&'a str>, - pub entries: 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, PartialEq, Eq, Debug, Encode, Decode)] pub enum WindowType { Generic9x1, @@ -389,77 +94,54 @@ pub enum WindowType { Stonecutter, } -#[bitfield(u8)] -#[derive(PartialEq, Eq, Encode, Decode)] -pub struct EntityEffectFlags { - pub is_ambient: bool, - pub show_particles: bool, - pub show_icon: bool, - #[bits(5)] - _pad: u8, -} - #[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub enum FeetOrEyes { - Feet, - Eyes, +pub enum Direction { + /// -Y + Down, + /// +Y + Up, + /// -Z + North, + /// +Z + South, + /// -X + West, + /// +X + East, } -#[derive(Copy, Clone, PartialEq, Eq, Debug, Encode, Decode)] -pub struct LookAtEntity { - pub entity_id: VarInt, - pub entity_feet_eyes: FeetOrEyes, +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct MessageSignature<'a> { + pub message_id: i32, + pub signature: Option<&'a [u8; 256]>, } -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub enum UpdateObjectiveMode { - Create { - objective_value: Text, - objective_type: VarInt, - }, - Remove, - Update { - objective_value: Text, - objective_type: VarInt, - }, +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(()) + } } -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub enum UpdateScoreAction<'a> { - Create { - objective_value: &'a str, - objective_type: VarInt, - }, - Remove, - Update { - objective_value: &'a str, - objective_type: VarInt, - }, -} +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. -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct CommandSuggestionMatch<'a> { - pub suggested_match: &'a str, - pub tooltip: Option, -} + let signature = if message_id == -1 { + Some(<&[u8; 256]>::decode(r)?) + } else { + None + }; -#[derive(Clone, PartialEq, Debug, Encode, Decode)] -pub struct MerchantTrade { - 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, PartialEq, Eq, Debug, Encode, Decode)] -pub enum ChatSuggestionAction { - Add, - Remove, - Set, + Ok(Self { + message_id, + signature, + }) + } } diff --git a/crates/valence_protocol/src/username.rs b/crates/valence_protocol/src/username.rs index 4e1f4f9..ac99355 100644 --- a/crates/valence_protocol/src/username.rs +++ b/crates/valence_protocol/src/username.rs @@ -9,7 +9,8 @@ use anyhow::anyhow; use serde::de::Error as _; use serde::{Deserialize, Deserializer, Serialize}; -use crate::{Decode, Encode, Result, Text}; +use crate::text::Text; +use crate::{Decode, Encode, Result}; /// A newtype wrapper around a string type `S` which guarantees the wrapped /// string meets the criteria for a valid Minecraft username. diff --git a/crates/valence_stresser/src/stresser.rs b/crates/valence_stresser/src/stresser.rs index c7bae68..401004e 100644 --- a/crates/valence_stresser/src/stresser.rs +++ b/crates/valence_stresser/src/stresser.rs @@ -4,12 +4,18 @@ use std::net::SocketAddr; use anyhow::bail; use tokio::io::AsyncWriteExt; use tokio::net::TcpStream; -use valence_protocol::packets::c2s::handshake::Handshake; -use valence_protocol::packets::c2s::login::LoginStart; -use valence_protocol::packets::c2s::play::{ConfirmTeleport, KeepAliveC2s, SetPlayerPosition}; -use valence_protocol::packets::{C2sHandshakePacket, S2cLoginPacket, S2cPlayPacket}; -use valence_protocol::types::HandshakeNextState; -use valence_protocol::{PacketDecoder, PacketEncoder, Username, Uuid, VarInt, PROTOCOL_VERSION}; +use uuid::Uuid; +use valence_protocol::codec::{PacketDecoder, PacketEncoder}; +use valence_protocol::packet::c2s::handshake::handshake::NextState; +use valence_protocol::packet::c2s::handshake::HandshakeC2s; +use valence_protocol::packet::c2s::login::LoginHelloC2s; +use valence_protocol::packet::c2s::play::{ + KeepAliveC2s, PositionAndOnGroundC2s, TeleportConfirmC2s, +}; +use valence_protocol::packet::{C2sHandshakePacket, S2cLoginPacket, S2cPlayPacket}; +use valence_protocol::username::Username; +use valence_protocol::var_int::VarInt; +use valence_protocol::PROTOCOL_VERSION; pub struct SessionParams<'a> { pub socket_addr: SocketAddr, @@ -28,31 +34,31 @@ pub async fn make_session<'a>(params: &SessionParams<'a>) -> anyhow::Result<()> conn } Err(err) => { - println!("{sess_name} connection failed"); + eprintln!("{sess_name} connection failed"); return Err(err.into()); } }; - _ = conn.set_nodelay(true); + conn.set_nodelay(true)?; let mut dec = PacketDecoder::new(); let mut enc = PacketEncoder::new(); - let server_addr_str = sock_addr.ip().to_string().as_str().to_owned(); + let server_addr_str = sock_addr.ip().to_string(); - let handshake_pkt = C2sHandshakePacket::Handshake(Handshake { - protocol_version: VarInt::from(PROTOCOL_VERSION), + let handshake_pkt = C2sHandshakePacket::HandshakeC2s(HandshakeC2s { + protocol_version: VarInt(PROTOCOL_VERSION), server_address: &server_addr_str, server_port: sock_addr.port(), - next_state: HandshakeNextState::Login, + next_state: NextState::Login, }); - _ = enc.append_packet(&handshake_pkt); + enc.append_packet(&handshake_pkt)?; - _ = enc.append_packet(&LoginStart { + enc.append_packet(&LoginHelloC2s { username: Username::new(sess_name).unwrap(), profile_id: Some(Uuid::new_v4()), - }); + })?; let write_buf = enc.take(); conn.write_all(&write_buf).await?; @@ -75,18 +81,18 @@ pub async fn make_session<'a>(params: &SessionParams<'a>) -> anyhow::Result<()> if let Ok(Some(pkt)) = dec.try_next_packet::() { match pkt { - S2cLoginPacket::SetCompression(p) => { + S2cLoginPacket::LoginCompressionS2c(p) => { let threshold = p.threshold.0 as u32; dec.set_compression(true); enc.set_compression(Some(threshold)); } - S2cLoginPacket::LoginSuccess(_) => { + S2cLoginPacket::LoginSuccessS2c(_) => { break; } - S2cLoginPacket::EncryptionRequest(_) => { + S2cLoginPacket::LoginHelloS2c(_) => { bail!("encryption not implemented"); } @@ -121,23 +127,23 @@ pub async fn make_session<'a>(params: &SessionParams<'a>) -> anyhow::Result<()> S2cPlayPacket::KeepAliveS2c(p) => { enc.clear(); - _ = enc.append_packet(&KeepAliveC2s { id: p.id }); + enc.append_packet(&KeepAliveC2s { id: p.id })?; conn.write_all(&enc.take()).await?; println!("{sess_name} keep alive") } - S2cPlayPacket::SynchronizePlayerPosition(p) => { + S2cPlayPacket::PlayerPositionLookS2c(p) => { enc.clear(); - _ = enc.append_packet(&ConfirmTeleport { + enc.append_packet(&TeleportConfirmC2s { teleport_id: p.teleport_id, - }); + })?; - _ = enc.append_packet(&SetPlayerPosition { + enc.append_packet(&PositionAndOnGroundC2s { position: p.position, on_ground: true, - }); + })?; conn.write_all(&enc.take()).await?;