From 08958c2278b15ebeac8a964f392ebb792e479b61 Mon Sep 17 00:00:00 2001 From: mat <27899617+mat-1@users.noreply.github.com> Date: Wed, 27 Nov 2024 19:31:40 -0600 Subject: Refactor azalea-protocol (#190) * start updating to 1.21.4 * fix block codegen and stop using block data from burger * rename packet related modules and structs to be simpler * ItemSlot -> ItemStack for more consistency with mojmap * .get() -> .into_packet() * simplify declare_state_packets by removing packet ids * rename read_from and write_into to azalea_read and azalea_write * rename McBufReadable and McBufWritable to AzaleaRead and AzaleaWrite * McBuf -> AzBuf * remove most uses of into_variant * update codegen and use resourcelocation names for packets * implement #[limit(i)] attribute for AzBuf derive macro * fixes for 1.21.4 * fix examples * update some physics code and fix ChatType * remove unused imports in codegen * re-add some things to migrate.py and update +mc version numbers automatically * downgrade to 1.21.3 lol --- azalea-client/src/attack.rs | 17 +-- azalea-client/src/chat.rs | 50 +++---- azalea-client/src/chunks.rs | 17 ++- azalea-client/src/client.rs | 77 +++++------ azalea-client/src/configuration.rs | 37 +++--- azalea-client/src/events.rs | 4 +- azalea-client/src/interact.rs | 32 +++-- azalea-client/src/inventory.rs | 92 +++++++------ azalea-client/src/lib.rs | 2 +- azalea-client/src/local_player.rs | 6 +- azalea-client/src/mining.rs | 71 +++++----- azalea-client/src/movement.rs | 49 +++---- azalea-client/src/packet_handling/configuration.rs | 145 ++++++++++++--------- azalea-client/src/packet_handling/game.rs | 87 +++++++------ azalea-client/src/packet_handling/login.rs | 26 ++-- azalea-client/src/packet_handling/mod.rs | 4 +- azalea-client/src/ping.rs | 32 ++--- azalea-client/src/raw_connection.rs | 5 +- azalea-client/src/respawn.rs | 17 +-- 19 files changed, 386 insertions(+), 384 deletions(-) (limited to 'azalea-client/src') diff --git a/azalea-client/src/attack.rs b/azalea-client/src/attack.rs index a28f800d..b1b36b69 100644 --- a/azalea-client/src/attack.rs +++ b/azalea-client/src/attack.rs @@ -4,9 +4,7 @@ use azalea_entity::{ update_bounding_box, Attributes, Physics, }; use azalea_physics::PhysicsSet; -use azalea_protocol::packets::game::serverbound_interact_packet::{ - self, ServerboundInteractPacket, -}; +use azalea_protocol::packets::game::s_interact::{self, ServerboundInteract}; use azalea_world::MinecraftEntityId; use bevy_app::{App, Plugin, Update}; use bevy_ecs::prelude::*; @@ -85,15 +83,14 @@ pub fn handle_attack_event( swing_arm_event.send(SwingArmEvent { entity: event.entity, }); - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundInteractPacket { + send_packet_events.send(SendPacketEvent::new( + event.entity, + ServerboundInteract { entity_id: *event.target, - action: serverbound_interact_packet::ActionType::Attack, + action: s_interact::ActionType::Attack, using_secondary_action: **sneaking, - } - .get(), - }); + }, + )); // we can't attack if we're in spectator mode but it still sends the attack // packet diff --git a/azalea-client/src/chat.rs b/azalea-client/src/chat.rs index 80c52baf..de0b8a7d 100755 --- a/azalea-client/src/chat.rs +++ b/azalea-client/src/chat.rs @@ -6,12 +6,15 @@ use std::{ }; use azalea_chat::FormattedText; -use azalea_protocol::packets::game::{ - clientbound_disguised_chat_packet::ClientboundDisguisedChatPacket, - clientbound_player_chat_packet::ClientboundPlayerChatPacket, - clientbound_system_chat_packet::ClientboundSystemChatPacket, - serverbound_chat_command_packet::ServerboundChatCommandPacket, - serverbound_chat_packet::{LastSeenMessagesUpdate, ServerboundChatPacket}, +use azalea_protocol::packets::{ + game::{ + c_disguised_chat::ClientboundDisguisedChat, + c_player_chat::ClientboundPlayerChat, + c_system_chat::ClientboundSystemChat, + s_chat::{LastSeenMessagesUpdate, ServerboundChat}, + s_chat_command::ServerboundChatCommand, + }, + Packet, }; use bevy_app::{App, Plugin, Update}; use bevy_ecs::{ @@ -30,9 +33,9 @@ use crate::{ /// A chat packet, either a system message or a chat message. #[derive(Debug, Clone, PartialEq)] pub enum ChatPacket { - System(Arc), - Player(Arc), - Disguised(Arc), + System(Arc), + Player(Arc), + Disguised(Arc), } macro_rules! regex { @@ -111,10 +114,10 @@ impl ChatPacket { self.split_sender_and_content().1 } - /// Create a new ChatPacket from a string. This is meant to be used as a + /// Create a new Chat from a string. This is meant to be used as a /// convenience function for testing. pub fn new(message: &str) -> Self { - ChatPacket::System(Arc::new(ClientboundSystemChatPacket { + ChatPacket::System(Arc::new(ClientboundSystemChat { content: FormattedText::from(message), overlay: false, })) @@ -141,7 +144,7 @@ impl Client { self.ecs.lock().send_event(SendChatKindEvent { entity: self.entity, content: message.to_string(), - kind: ChatPacketKind::Message, + kind: ChatKind::Message, }); self.run_schedule_sender.send(()).unwrap(); } @@ -152,7 +155,7 @@ impl Client { self.ecs.lock().send_event(SendChatKindEvent { entity: self.entity, content: command.to_string(), - kind: ChatPacketKind::Command, + kind: ChatKind::Command, }); self.run_schedule_sender.send(()).unwrap(); } @@ -215,13 +218,13 @@ pub fn handle_send_chat_event( send_chat_kind_events.send(SendChatKindEvent { entity: event.entity, content: event.content[1..].to_string(), - kind: ChatPacketKind::Command, + kind: ChatKind::Command, }); } else { send_chat_kind_events.send(SendChatKindEvent { entity: event.entity, content: event.content.clone(), - kind: ChatPacketKind::Message, + kind: ChatKind::Message, }); } } @@ -240,11 +243,11 @@ pub fn handle_send_chat_event( pub struct SendChatKindEvent { pub entity: Entity, pub content: String, - pub kind: ChatPacketKind, + pub kind: ChatKind, } /// A kind of chat packet, either a chat message or a command. -pub enum ChatPacketKind { +pub enum ChatKind { Message, Command, } @@ -261,7 +264,7 @@ pub fn handle_send_chat_kind_event( .take(256) .collect::(); let packet = match event.kind { - ChatPacketKind::Message => ServerboundChatPacket { + ChatKind::Message => ServerboundChat { message: content, timestamp: SystemTime::now() .duration_since(UNIX_EPOCH) @@ -273,17 +276,14 @@ pub fn handle_send_chat_kind_event( signature: None, last_seen_messages: LastSeenMessagesUpdate::default(), } - .get(), - ChatPacketKind::Command => { + .into_variant(), + ChatKind::Command => { // TODO: chat signing - ServerboundChatCommandPacket { command: content }.get() + ServerboundChatCommand { command: content }.into_variant() } }; - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet, - }); + send_packet_events.send(SendPacketEvent::new(event.entity, packet)); } } diff --git a/azalea-client/src/chunks.rs b/azalea-client/src/chunks.rs index 40e295aa..7056efa4 100644 --- a/azalea-client/src/chunks.rs +++ b/azalea-client/src/chunks.rs @@ -10,8 +10,8 @@ use std::{ use azalea_core::position::ChunkPos; use azalea_protocol::packets::game::{ - clientbound_level_chunk_with_light_packet::ClientboundLevelChunkWithLightPacket, - serverbound_chunk_batch_received_packet::ServerboundChunkBatchReceivedPacket, + c_level_chunk_with_light::ClientboundLevelChunkWithLight, + s_chunk_batch_received::ServerboundChunkBatchReceived, }; use bevy_app::{App, Plugin, Update}; use bevy_ecs::prelude::*; @@ -51,7 +51,7 @@ impl Plugin for ChunkPlugin { #[derive(Event)] pub struct ReceiveChunkEvent { pub entity: Entity, - pub packet: ClientboundLevelChunkWithLightPacket, + pub packet: ClientboundLevelChunkWithLight, } #[derive(Component, Clone, Debug)] @@ -159,13 +159,12 @@ pub fn handle_chunk_batch_finished_event( if let Ok(mut chunk_batch_info) = query.get_mut(event.entity) { chunk_batch_info.batch_finished(event.batch_size); let desired_chunks_per_tick = chunk_batch_info.desired_chunks_per_tick(); - send_packets.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundChunkBatchReceivedPacket { + send_packets.send(SendPacketEvent::new( + event.entity, + ServerboundChunkBatchReceived { desired_chunks_per_tick, - } - .get(), - }); + }, + )); } } } diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index 9083a80b..5158eedf 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -17,24 +17,21 @@ use azalea_entity::{ }; use azalea_physics::PhysicsPlugin; use azalea_protocol::{ + common::client_information::ClientInformation, connect::{Connection, ConnectionError, Proxy}, packets::{ - configuration::{ - serverbound_client_information_packet::ClientInformation, - ClientboundConfigurationPacket, ServerboundConfigurationPacket, - }, + self, + config::{ClientboundConfigPacket, ServerboundConfigPacket}, game::ServerboundGamePacket, - handshaking::{ - client_intention_packet::ClientIntentionPacket, ClientboundHandshakePacket, + handshake::{ + s_intention::ServerboundIntention, ClientboundHandshakePacket, ServerboundHandshakePacket, }, login::{ - serverbound_hello_packet::ServerboundHelloPacket, - serverbound_key_packet::ServerboundKeyPacket, - serverbound_login_acknowledged_packet::ServerboundLoginAcknowledgedPacket, - ClientboundLoginPacket, + s_hello::ServerboundHello, s_key::ServerboundKey, + s_login_acknowledged::ServerboundLoginAcknowledged, ClientboundLoginPacket, }, - ClientIntention, ConnectionProtocol, PROTOCOL_VERSION, + ClientIntention, ConnectionProtocol, Packet, PROTOCOL_VERSION, }, resolver, ServerAddress, }; @@ -347,21 +344,18 @@ impl Client { address: &ServerAddress, ) -> Result< ( - Connection, + Connection, GameProfile, ), JoinError, > { // handshake - conn.write( - ClientIntentionPacket { - protocol_version: PROTOCOL_VERSION, - hostname: address.host.clone(), - port: address.port, - intention: ClientIntention::Login, - } - .get(), - ) + conn.write(ServerboundIntention { + protocol_version: PROTOCOL_VERSION, + hostname: address.host.clone(), + port: address.port, + intention: ClientIntention::Login, + }) .await?; let mut conn = conn.login(); @@ -374,15 +368,12 @@ impl Client { )); // login - conn.write( - ServerboundHelloPacket { - name: account.username.clone(), - // TODO: pretty sure this should generate an offline-mode uuid instead of just - // Uuid::default() - profile_id: account.uuid.unwrap_or_default(), - } - .get(), - ) + conn.write(ServerboundHello { + name: account.username.clone(), + // TODO: pretty sure this should generate an offline-mode uuid instead of just + // Uuid::default() + profile_id: account.uuid.unwrap_or_default(), + }) .await?; let (conn, profile) = loop { @@ -442,13 +433,10 @@ impl Client { } } - conn.write( - ServerboundKeyPacket { - key_bytes: e.encrypted_public_key, - encrypted_challenge: e.encrypted_challenge, - } - .get(), - ) + conn.write(ServerboundKey { + key_bytes: e.encrypted_public_key, + encrypted_challenge: e.encrypted_challenge, + }) .await?; conn.set_encryption_key(e.secret_key); @@ -462,8 +450,7 @@ impl Client { "Got profile {:?}. handshake is finished and we're now switching to the configuration state", p.game_profile ); - conn.write(ServerboundLoginAcknowledgedPacket {}.get()) - .await?; + conn.write(ServerboundLoginAcknowledged {}).await?; break (conn.configuration(), p.game_profile); } ClientboundLoginPacket::LoginDisconnect(p) => { @@ -477,6 +464,13 @@ impl Client { } ClientboundLoginPacket::CookieRequest(p) => { debug!("Got cookie request {:?}", p); + + conn.write(packets::login::ServerboundCookieResponse { + key: p.key, + // cookies aren't implemented + payload: None, + }) + .await?; } } }; @@ -493,8 +487,9 @@ impl Client { /// Write a packet directly to the server. pub fn write_packet( &self, - packet: ServerboundGamePacket, + packet: impl Packet, ) -> Result<(), crate::raw_connection::WritePacketError> { + let packet = packet.into_variant(); self.raw_connection_mut(&mut self.ecs.lock()) .write_packet(packet) } @@ -605,7 +600,7 @@ impl Client { "Sending client information (already logged in): {:?}", client_information ); - self.write_packet(azalea_protocol::packets::game::serverbound_client_information_packet::ServerboundClientInformationPacket { information: client_information.clone() }.get())?; + self.write_packet(azalea_protocol::packets::game::s_client_information::ServerboundClientInformation { information: client_information.clone() })?; } Ok(()) diff --git a/azalea-client/src/configuration.rs b/azalea-client/src/configuration.rs index 99b97f60..bfaa36f0 100644 --- a/azalea-client/src/configuration.rs +++ b/azalea-client/src/configuration.rs @@ -1,17 +1,16 @@ -use azalea_buf::McBufWritable; +use azalea_buf::AzaleaWrite; use azalea_core::resource_location::ResourceLocation; -use azalea_protocol::packets::configuration::{ - serverbound_client_information_packet::{ - ClientInformation, ServerboundClientInformationPacket, +use azalea_protocol::{ + common::client_information::ClientInformation, + packets::config::{ + s_client_information::ServerboundClientInformation, + s_custom_payload::ServerboundCustomPayload, }, - serverbound_custom_payload_packet::ServerboundCustomPayloadPacket, }; use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use crate::{ - client::InConfigurationState, packet_handling::configuration::SendConfigurationPacketEvent, -}; +use crate::{client::InConfigurationState, packet_handling::configuration::SendConfigurationEvent}; pub struct ConfigurationPlugin; impl Plugin for ConfigurationPlugin { @@ -26,27 +25,25 @@ impl Plugin for ConfigurationPlugin { fn handle_in_configuration_state( query: Query<(Entity, &ClientInformation), Added>, - mut send_packet_events: EventWriter, + mut send_packet_events: EventWriter, ) { for (entity, client_information) in query.iter() { let mut brand_data = Vec::new(); // they don't have to know :) - "vanilla".write_into(&mut brand_data).unwrap(); - send_packet_events.send(SendConfigurationPacketEvent { + "vanilla".azalea_write(&mut brand_data).unwrap(); + send_packet_events.send(SendConfigurationEvent::new( entity, - packet: ServerboundCustomPayloadPacket { + ServerboundCustomPayload { identifier: ResourceLocation::new("brand"), data: brand_data.into(), - } - .get(), - }); + }, + )); - send_packet_events.send(SendConfigurationPacketEvent { + send_packet_events.send(SendConfigurationEvent::new( entity, - packet: ServerboundClientInformationPacket { + ServerboundClientInformation { information: client_information.clone(), - } - .get(), - }); + }, + )); } } diff --git a/azalea-client/src/events.rs b/azalea-client/src/events.rs index 61104a4b..fb8afa75 100644 --- a/azalea-client/src/events.rs +++ b/azalea-client/src/events.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use azalea_chat::FormattedText; use azalea_core::tick::GameTick; use azalea_protocol::packets::game::{ - clientbound_player_combat_kill_packet::ClientboundPlayerCombatKillPacket, ClientboundGamePacket, + c_player_combat_kill::ClientboundPlayerCombatKill, ClientboundGamePacket, }; use azalea_world::{InstanceName, MinecraftEntityId}; use bevy_app::{App, Plugin, PreUpdate, Update}; @@ -93,7 +93,7 @@ pub enum Event { /// name, or latency changed). UpdatePlayer(PlayerInfo), /// The client player died in-game. - Death(Option>), + Death(Option>), /// A `KeepAlive` packet was sent by the server. KeepAlive(u64), /// The client disconnected from the server. diff --git a/azalea-client/src/interact.rs b/azalea-client/src/interact.rs index 94b60ddc..d2dfd93a 100644 --- a/azalea-client/src/interact.rs +++ b/azalea-client/src/interact.rs @@ -10,12 +10,12 @@ use azalea_core::{ use azalea_entity::{ clamp_look_direction, view_vector, Attributes, EyeHeight, LocalEntity, LookDirection, Position, }; -use azalea_inventory::{ItemSlot, ItemSlotData}; +use azalea_inventory::{ItemStack, ItemStackData}; use azalea_physics::clip::{BlockShapeType, ClipContext, FluidPickType}; use azalea_protocol::packets::game::{ - serverbound_interact_packet::InteractionHand, - serverbound_swing_packet::ServerboundSwingPacket, - serverbound_use_item_on_packet::{BlockHit, ServerboundUseItemOnPacket}, + s_interact::InteractionHand, + s_swing::ServerboundSwing, + s_use_item_on::{BlockHit, ServerboundUseItemOn}, }; use azalea_registry::DataComponentKind; use azalea_world::{Instance, InstanceContainer, InstanceName}; @@ -148,15 +148,14 @@ pub fn handle_block_interact_event( } }; - send_packet_events.send(SendPacketEvent { + send_packet_events.send(SendPacketEvent::new( entity, - packet: ServerboundUseItemOnPacket { + ServerboundUseItemOn { hand: InteractionHand::MainHand, block_hit, sequence: sequence_number.0, - } - .get(), - }); + }, + )); } } @@ -245,7 +244,7 @@ pub fn check_is_interaction_restricted( // way of modifying that let held_item = inventory.held_item(); - if let ItemSlot::Present(item) = &held_item { + if let ItemStack::Present(item) = &held_item { let block = instance.chunks.get_block_state(block_pos); let Some(block) = block else { // block isn't loaded so just say that it is restricted @@ -263,7 +262,7 @@ pub fn check_is_interaction_restricted( /// Check if the item has the `CanDestroy` tag for the block. pub fn check_block_can_be_broken_by_item_in_adventure_mode( - item: &ItemSlotData, + item: &ItemStackData, _block: &BlockState, ) -> bool { // minecraft caches the last checked block but that's kind of an unnecessary @@ -302,13 +301,12 @@ pub fn handle_swing_arm_event( mut send_packet_events: EventWriter, ) { for event in events.read() { - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundSwingPacket { + send_packet_events.send(SendPacketEvent::new( + event.entity, + ServerboundSwing { hand: InteractionHand::MainHand, - } - .get(), - }); + }, + )); } } diff --git a/azalea-client/src/inventory.rs b/azalea-client/src/inventory.rs index d4ccab14..eb0b0675 100644 --- a/azalea-client/src/inventory.rs +++ b/azalea-client/src/inventory.rs @@ -10,9 +10,8 @@ use azalea_inventory::{ }, }; use azalea_protocol::packets::game::{ - serverbound_container_click_packet::ServerboundContainerClickPacket, - serverbound_container_close_packet::ServerboundContainerClosePacket, - serverbound_set_carried_item_packet::ServerboundSetCarriedItemPacket, + s_container_click::ServerboundContainerClick, s_container_close::ServerboundContainerClose, + s_set_carried_item::ServerboundSetCarriedItem, }; use azalea_registry::MenuKind; use bevy_app::{App, Plugin, Update}; @@ -98,7 +97,7 @@ pub struct Inventory { /// /// This is different from [`Self::selected_hotbar_slot`], which is the /// item that's selected in the hotbar. - pub carried: ItemSlot, + pub carried: ItemStack, /// An identifier used by the server to track client inventory desyncs. This /// is sent on every container click, and it's only ever updated when the /// server sends a new container update. @@ -183,7 +182,7 @@ impl Inventory { if let QuickCraftStatus::Add { slot } = quick_craft.status { let slot_item = self.menu().slot(slot as usize); if let Some(slot_item) = slot_item { - if let ItemSlot::Present(carried) = &self.carried { + if let ItemStack::Present(carried) = &self.carried { // minecraft also checks slot.may_place(carried) and // menu.can_drag_to(slot) // but they always return true so they're not relevant for us @@ -222,7 +221,7 @@ impl Inventory { return; } - let ItemSlot::Present(mut carried) = self.carried.clone() else { + let ItemStack::Present(mut carried) = self.carried.clone() else { // this should never happen return self.reset_quick_craft(); }; @@ -231,14 +230,14 @@ impl Inventory { let mut quick_craft_slots_iter = self.quick_craft_slots.iter(); loop { - let mut slot: &ItemSlot; + let mut slot: &ItemStack; let mut slot_index: u16; - let mut item_stack: &ItemSlot; + let mut item_stack: &ItemStack; loop { let Some(&next_slot) = quick_craft_slots_iter.next() else { carried.count = carried_count; - self.carried = ItemSlot::Present(carried); + self.carried = ItemStack::Present(carried); return self.reset_quick_craft(); }; @@ -259,8 +258,8 @@ impl Inventory { } } - // get the ItemSlotData for the slot - let ItemSlot::Present(slot) = slot else { + // get the ItemStackData for the slot + let ItemStack::Present(slot) = slot else { unreachable!("the loop above requires the slot to be present to break") }; @@ -293,7 +292,7 @@ impl Inventory { &mut self.inventory_menu }; *menu.slot_mut(slot_index as usize).unwrap() = - ItemSlot::Present(new_carried); + ItemStack::Present(new_carried); } } } else { @@ -316,7 +315,7 @@ impl Inventory { // implementation // player.drop(self.carried, true); - self.carried = ItemSlot::Empty; + self.carried = ItemStack::Empty; } } ClickOperation::Pickup(PickupClick::Right { slot: None }) => { @@ -336,8 +335,8 @@ impl Inventory { // here // i don't understand it so i didn't implement it match slot_item { - ItemSlot::Empty => if carried.is_present() {}, - ItemSlot::Present(_) => todo!(), + ItemStack::Empty => if carried.is_present() {}, + ItemStack::Present(_) => todo!(), } } ClickOperation::QuickMove( @@ -374,7 +373,7 @@ impl Inventory { *target_slot = source_slot; } } else if source_slot.is_empty() { - let ItemSlot::Present(target_item) = target_slot else { + let ItemStack::Present(target_item) = target_slot else { unreachable!("target slot is not empty but is not present"); }; if self.menu().may_place(source_slot_index, target_item) { @@ -386,7 +385,7 @@ impl Inventory { *self.menu_mut().slot_mut(source_slot_index).unwrap() = new_source_slot; } } else if self.menu().may_pickup(source_slot_index) { - let ItemSlot::Present(target_item) = target_slot else { + let ItemStack::Present(target_item) = target_slot else { unreachable!("target slot is not empty but is not present"); }; if self.menu().may_place(source_slot_index, target_item) { @@ -421,12 +420,12 @@ impl Inventory { let Some(source_slot) = self.menu().slot(*slot as usize) else { return; }; - let ItemSlot::Present(source_item) = source_slot else { + let ItemStack::Present(source_item) = source_slot else { return; }; let mut new_carried = source_item.clone(); new_carried.count = new_carried.kind.max_stack_size(); - self.carried = ItemSlot::Present(new_carried); + self.carried = ItemStack::Present(new_carried); } ClickOperation::Throw(c) => { if self.carried.is_present() { @@ -440,7 +439,7 @@ impl Inventory { let Some(slot) = self.menu_mut().slot_mut(slot_index) else { return; }; - let ItemSlot::Present(slot_item) = slot else { + let ItemStack::Present(slot_item) = slot else { return; }; @@ -467,7 +466,7 @@ impl Inventory { return; } - let ItemSlot::Present(target_slot_item) = &target_slot else { + let ItemStack::Present(target_slot_item) = &target_slot else { unreachable!("target slot is not empty but is not present"); }; @@ -481,7 +480,7 @@ impl Inventory { for i in iterator { if target_slot_item.count < target_slot_item.kind.max_stack_size() { let checking_slot = self.menu().slot(i).unwrap(); - if let ItemSlot::Present(checking_item) = checking_slot { + if let ItemStack::Present(checking_item) = checking_slot { if can_item_quick_replace(checking_slot, &target_slot, true) && self.menu().may_pickup(i) && (round != 0 @@ -496,7 +495,7 @@ impl Inventory { // now extend the carried item let target_slot = &mut self.carried; - let ItemSlot::Present(target_slot_item) = target_slot else { + let ItemStack::Present(target_slot_item) = target_slot else { unreachable!("target slot is not empty but is not present"); }; target_slot_item.count += taken_item.count(); @@ -516,7 +515,7 @@ impl Inventory { } /// Get the item in the player's hotbar that is currently being held. - pub fn held_item(&self) -> ItemSlot { + pub fn held_item(&self) -> ItemStack { let inventory = &self.inventory_menu; let hotbar_items = &inventory.slots()[inventory.hotbar_slots_range()]; hotbar_items[self.selected_hotbar_slot as usize].clone() @@ -524,14 +523,14 @@ impl Inventory { } fn can_item_quick_replace( - target_slot: &ItemSlot, - item: &ItemSlot, + target_slot: &ItemStack, + item: &ItemStack, ignore_item_count: bool, ) -> bool { - let ItemSlot::Present(target_slot) = target_slot else { + let ItemStack::Present(target_slot) = target_slot else { return false; }; - let ItemSlot::Present(item) = item else { + let ItemStack::Present(item) = item else { // i *think* this is what vanilla does // not 100% sure lol probably doesn't matter though return false; @@ -552,7 +551,7 @@ fn can_item_quick_replace( fn get_quick_craft_slot_count( quick_craft_slots: &HashSet, quick_craft_kind: &QuickCraftKind, - item: &mut ItemSlotData, + item: &mut ItemStackData, slot_item_count: i32, ) { item.count = match quick_craft_kind { @@ -570,7 +569,7 @@ impl Default for Inventory { id: 0, container_menu: None, container_menu_title: None, - carried: ItemSlot::Empty, + carried: ItemStack::Empty, state_id: 0, quick_craft_status: QuickCraftStatusKind::Start, quick_craft_kind: QuickCraftKind::Middle, @@ -628,13 +627,12 @@ fn handle_container_close_event( continue; } - send_packet_events.send(SendPacketEvent { + send_packet_events.send(SendPacketEvent::new( entity, - packet: ServerboundContainerClosePacket { + ServerboundContainerClose { container_id: inventory.id, - } - .get(), - }); + }, + )); client_side_events.send(ClientSideCloseContainerEvent { entity: event.entity, }); @@ -688,7 +686,7 @@ pub fn handle_container_click_event( // see which slots changed after clicking and put them in the hashmap // the server uses this to check if we desynced - let mut changed_slots: HashMap = HashMap::new(); + let mut changed_slots: HashMap = HashMap::new(); for (slot_index, old_slot) in old_slots.iter().enumerate() { let new_slot = &menu.slots()[slot_index]; if old_slot != new_slot { @@ -696,9 +694,9 @@ pub fn handle_container_click_event( } } - send_packet_events.send(SendPacketEvent { + send_packet_events.send(SendPacketEvent::new( entity, - packet: ServerboundContainerClickPacket { + ServerboundContainerClick { container_id: event.window_id, state_id: inventory.state_id, slot_num: event.operation.slot_num().map(|n| n as i16).unwrap_or(-999), @@ -706,9 +704,8 @@ pub fn handle_container_click_event( click_type: event.operation.click_type(), changed_slots, carried_item: inventory.carried.clone(), - } - .get(), - }); + }, + )); } } @@ -717,7 +714,7 @@ pub fn handle_container_click_event( #[derive(Event)] pub struct SetContainerContentEvent { pub entity: Entity, - pub slots: Vec, + pub slots: Vec, pub container_id: u8, } fn handle_set_container_content_event( @@ -764,12 +761,11 @@ fn handle_set_selected_hotbar_slot_event( } inventory.selected_hotbar_slot = event.slot; - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundSetCarriedItemPacket { + send_packet_events.send(SendPacketEvent::new( + event.entity, + ServerboundSetCarriedItem { slot: event.slot as u16, - } - .get(), - }); + }, + )); } } diff --git a/azalea-client/src/lib.rs b/azalea-client/src/lib.rs index 82d4f561..3e4a48aa 100644 --- a/azalea-client/src/lib.rs +++ b/azalea-client/src/lib.rs @@ -30,7 +30,7 @@ pub mod respawn; pub mod task_pool; pub use account::{Account, AccountOpts}; -pub use azalea_protocol::packets::configuration::serverbound_client_information_packet::ClientInformation; +pub use azalea_protocol::common::client_information::ClientInformation; pub use client::{ start_ecs_runner, Client, DefaultPlugins, JoinError, JoinedClientBundle, StartClientOpts, TickBroadcast, diff --git a/azalea-client/src/local_player.rs b/azalea-client/src/local_player.rs index 3cc77f9d..d2fce3f1 100644 --- a/azalea-client/src/local_player.rs +++ b/azalea-client/src/local_player.rs @@ -3,7 +3,7 @@ use std::{collections::HashMap, io, sync::Arc}; use azalea_auth::game_profile::GameProfile; use azalea_core::game_type::GameMode; use azalea_entity::Dead; -use azalea_protocol::packets::game::clientbound_player_abilities_packet::ClientboundPlayerAbilitiesPacket; +use azalea_protocol::packets::game::c_player_abilities::ClientboundPlayerAbilities; use azalea_world::{Instance, PartialInstance}; use bevy_ecs::{component::Component, prelude::*}; use derive_more::{Deref, DerefMut}; @@ -62,8 +62,8 @@ pub struct PlayerAbilities { /// Used for the fov pub walking_speed: f32, } -impl From<&ClientboundPlayerAbilitiesPacket> for PlayerAbilities { - fn from(packet: &ClientboundPlayerAbilitiesPacket) -> Self { +impl From<&ClientboundPlayerAbilities> for PlayerAbilities { + fn from(packet: &ClientboundPlayerAbilities) -> Self { Self { invulnerable: packet.flags.invulnerable, flying: packet.flags.flying, diff --git a/azalea-client/src/mining.rs b/azalea-client/src/mining.rs index 1c8461c5..bf5a48ca 100644 --- a/azalea-client/src/mining.rs +++ b/azalea-client/src/mining.rs @@ -1,11 +1,9 @@ use azalea_block::{Block, BlockState, FluidState}; use azalea_core::{direction::Direction, game_type::GameMode, position::BlockPos, tick::GameTick}; use azalea_entity::{mining::get_mine_progress, FluidOnEyes, Physics}; -use azalea_inventory::ItemSlot; +use azalea_inventory::ItemStack; use azalea_physics::PhysicsSet; -use azalea_protocol::packets::game::serverbound_player_action_packet::{ - self, ServerboundPlayerActionPacket, -}; +use azalea_protocol::packets::game::s_player_action::{self, ServerboundPlayerAction}; use azalea_world::{InstanceContainer, InstanceName}; use bevy_app::{App, Plugin, Update}; use bevy_ecs::prelude::*; @@ -253,17 +251,16 @@ fn handle_start_mining_block_with_direction_event( { if mining.is_some() { // send a packet to stop mining since we just changed target - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundPlayerActionPacket { - action: serverbound_player_action_packet::Action::AbortDestroyBlock, + send_packet_events.send(SendPacketEvent::new( + event.entity, + ServerboundPlayerAction { + action: s_player_action::Action::AbortDestroyBlock, pos: current_mining_pos .expect("IsMining is true so MineBlockPos must be present"), direction: event.direction, sequence: 0, - } - .get(), - }); + }, + )); } let target_block_state = instance @@ -326,16 +323,15 @@ fn handle_start_mining_block_with_direction_event( }); } - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundPlayerActionPacket { - action: serverbound_player_action_packet::Action::StartDestroyBlock, + send_packet_events.send(SendPacketEvent::new( + event.entity, + ServerboundPlayerAction { + action: s_player_action::Action::StartDestroyBlock, pos: event.position, direction: event.direction, sequence: **sequence_number, - } - .get(), - }); + }, + )); } } } @@ -407,9 +403,9 @@ pub struct MineTicks(pub f32); pub struct MineBlockPos(pub Option); /// A component that contains the item we're currently using to mine. If we're -/// not mining anything, it'll be [`ItemSlot::Empty`]. +/// not mining anything, it'll be [`ItemStack::Empty`]. #[derive(Component, Clone, Debug, Default, Deref, DerefMut)] -pub struct MineItem(pub ItemSlot); +pub struct MineItem(pub ItemStack); /// Sent when we completed mining a block. #[derive(Event)] @@ -496,16 +492,15 @@ pub fn handle_stop_mining_block_event( let mine_block_pos = mine_block_pos.expect("IsMining is true so MineBlockPos must be present"); - send_packet_events.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundPlayerActionPacket { - action: serverbound_player_action_packet::Action::AbortDestroyBlock, + send_packet_events.send(SendPacketEvent::new( + event.entity, + ServerboundPlayerAction { + action: s_player_action::Action::AbortDestroyBlock, pos: mine_block_pos, direction: Direction::Down, sequence: 0, - } - .get(), - }); + }, + )); commands.entity(event.entity).remove::(); **mine_progress = 0.; mine_block_progress_events.send(MineBlockProgressEvent { @@ -570,16 +565,15 @@ pub fn continue_mining_block( position: mining.pos, }); *sequence_number += 1; - send_packet_events.send(SendPacketEvent { + send_packet_events.send(SendPacketEvent::new( entity, - packet: ServerboundPlayerActionPacket { - action: serverbound_player_action_packet::Action::StartDestroyBlock, + ServerboundPlayerAction { + action: s_player_action::Action::StartDestroyBlock, pos: mining.pos, direction: mining.dir, sequence: **sequence_number, - } - .get(), - }); + }, + )); swing_arm_events.send(SwingArmEvent { entity }); } else if is_same_mining_target( mining.pos, @@ -616,16 +610,15 @@ pub fn continue_mining_block( entity, position: mining.pos, }); - send_packet_events.send(SendPacketEvent { + send_packet_events.send(SendPacketEvent::new( entity, - packet: ServerboundPlayerActionPacket { - action: serverbound_player_action_packet::Action::StopDestroyBlock, + ServerboundPlayerAction { + action: s_player_action::Action::StopDestroyBlock, pos: mining.pos, direction: mining.dir, sequence: **sequence_number, - } - .get(), - }); + }, + )); **mine_progress = 0.; **mine_ticks = 0.; **mine_delay = 0; diff --git a/azalea-client/src/movement.rs b/azalea-client/src/movement.rs index 806f8734..3304e27d 100644 --- a/azalea-client/src/movement.rs +++ b/azalea-client/src/movement.rs @@ -5,12 +5,15 @@ use azalea_core::tick::GameTick; use azalea_entity::{metadata::Sprinting, Attributes, Jumping}; use azalea_entity::{InLoadedChunk, LastSentPosition, LookDirection, Physics, Position}; use azalea_physics::{ai_step, PhysicsSet}; -use azalea_protocol::packets::game::serverbound_player_command_packet::ServerboundPlayerCommandPacket; -use azalea_protocol::packets::game::{ - serverbound_move_player_pos_packet::ServerboundMovePlayerPosPacket, - serverbound_move_player_pos_rot_packet::ServerboundMovePlayerPosRotPacket, - serverbound_move_player_rot_packet::ServerboundMovePlayerRotPacket, - serverbound_move_player_status_only_packet::ServerboundMovePlayerStatusOnlyPacket, +use azalea_protocol::packets::game::ServerboundPlayerCommand; +use azalea_protocol::packets::{ + game::{ + s_move_player_pos::ServerboundMovePlayerPos, + s_move_player_pos_rot::ServerboundMovePlayerPosRot, + s_move_player_rot::ServerboundMovePlayerRot, + s_move_player_status_only::ServerboundMovePlayerStatusOnly, + }, + Packet, }; use azalea_world::{MinecraftEntityId, MoveEntityError}; use bevy_app::{App, Plugin, Update}; @@ -188,7 +191,7 @@ pub fn send_position( // } let packet = if sending_position && sending_direction { Some( - ServerboundMovePlayerPosRotPacket { + ServerboundMovePlayerPosRot { x: position.x, y: position.y, z: position.z, @@ -196,33 +199,33 @@ pub fn send_position( y_rot: direction.y_rot, on_ground: physics.on_ground, } - .get(), + .into_variant(), ) } else if sending_position { Some( - ServerboundMovePlayerPosPacket { + ServerboundMovePlayerPos { x: position.x, y: position.y, z: position.z, on_ground: physics.on_ground, } - .get(), + .into_variant(), ) } else if sending_direction { Some( - ServerboundMovePlayerRotPacket { + ServerboundMovePlayerRot { x_rot: direction.x_rot, y_rot: direction.y_rot, on_ground: physics.on_ground, } - .get(), + .into_variant(), ) } else if physics.last_on_ground != physics.on_ground { Some( - ServerboundMovePlayerStatusOnlyPacket { + ServerboundMovePlayerStatusOnly { on_ground: physics.on_ground, } - .get(), + .into_variant(), ) } else { None @@ -244,7 +247,10 @@ pub fn send_position( }; if let Some(packet) = packet { - send_packet_events.send(SendPacketEvent { entity, packet }); + send_packet_events.send(SendPacketEvent { + sent_by: entity, + packet, + }); } } } @@ -257,19 +263,18 @@ fn send_sprinting_if_needed( let was_sprinting = physics_state.was_sprinting; if **sprinting != was_sprinting { let sprinting_action = if **sprinting { - azalea_protocol::packets::game::serverbound_player_command_packet::Action::StartSprinting + azalea_protocol::packets::game::s_player_command::Action::StartSprinting } else { - azalea_protocol::packets::game::serverbound_player_command_packet::Action::StopSprinting + azalea_protocol::packets::game::s_player_command::Action::StopSprinting }; - send_packet_events.send(SendPacketEvent { + send_packet_events.send(SendPacketEvent::new( entity, - packet: ServerboundPlayerCommandPacket { + ServerboundPlayerCommand { id: **minecraft_entity_id, action: sprinting_action, data: 0, - } - .get(), - }); + }, + )); physics_state.was_sprinting = **sprinting; } } diff --git a/azalea-client/src/packet_handling/configuration.rs b/azalea-client/src/packet_handling/configuration.rs index de365394..e427e36e 100644 --- a/azalea-client/src/packet_handling/configuration.rs +++ b/azalea-client/src/packet_handling/configuration.rs @@ -1,15 +1,14 @@ use std::io::Cursor; use azalea_entity::indexing::EntityIdIndex; -use azalea_protocol::packets::configuration::serverbound_finish_configuration_packet::ServerboundFinishConfigurationPacket; -use azalea_protocol::packets::configuration::serverbound_keep_alive_packet::ServerboundKeepAlivePacket; -use azalea_protocol::packets::configuration::serverbound_pong_packet::ServerboundPongPacket; -use azalea_protocol::packets::configuration::serverbound_resource_pack_packet::ServerboundResourcePackPacket; -use azalea_protocol::packets::configuration::serverbound_select_known_packs_packet::ServerboundSelectKnownPacksPacket; -use azalea_protocol::packets::configuration::{ - ClientboundConfigurationPacket, ServerboundConfigurationPacket, +use azalea_protocol::packets::config::s_finish_configuration::ServerboundFinishConfiguration; +use azalea_protocol::packets::config::s_keep_alive::ServerboundKeepAlive; +use azalea_protocol::packets::config::s_select_known_packs::ServerboundSelectKnownPacks; +use azalea_protocol::packets::config::{ + self, ClientboundConfigPacket, ServerboundConfigPacket, ServerboundCookieResponse, + ServerboundResourcePack, }; -use azalea_protocol::packets::ConnectionProtocol; +use azalea_protocol::packets::{ConnectionProtocol, Packet}; use azalea_protocol::read::deserialize_packet; use bevy_ecs::prelude::*; use bevy_ecs::system::SystemState; @@ -23,29 +22,29 @@ use crate::raw_connection::RawConnection; use crate::InstanceHolder; #[derive(Event, Debug, Clone)] -pub struct ConfigurationPacketEvent { +pub struct ConfigurationEvent { /// The client entity that received the packet. pub entity: Entity, /// The packet that was actually received. - pub packet: ClientboundConfigurationPacket, + pub packet: ClientboundConfigPacket, } pub fn send_packet_events( query: Query<(Entity, &RawConnection), With>, - mut packet_events: ResMut>, + mut packet_events: ResMut>, ) { // we manually clear and send the events at the beginning of each update // since otherwise it'd cause issues with events in process_packet_events // running twice packet_events.clear(); - for (player_entity, raw_connection) in &query { - let packets_lock = raw_connection.incoming_packet_queue(); + for (player_entity, raw_conn) in &query { + let packets_lock = raw_conn.incoming_packet_queue(); let mut packets = packets_lock.lock(); if !packets.is_empty() { for raw_packet in packets.iter() { - let packet = match deserialize_packet::( - &mut Cursor::new(raw_packet), - ) { + let packet = match deserialize_packet::(&mut Cursor::new( + raw_packet, + )) { Ok(packet) => packet, Err(err) => { error!("failed to read packet: {:?}", err); @@ -53,7 +52,7 @@ pub fn send_packet_events( continue; } }; - packet_events.send(ConfigurationPacketEvent { + packet_events.send(ConfigurationEvent { entity: player_entity, packet, }); @@ -66,10 +65,9 @@ pub fn send_packet_events( pub fn process_packet_events(ecs: &mut World) { let mut events_owned = Vec::new(); - let mut system_state: SystemState> = - SystemState::new(ecs); + let mut system_state: SystemState> = SystemState::new(ecs); let mut events = system_state.get_mut(ecs); - for ConfigurationPacketEvent { + for ConfigurationEvent { entity: player_entity, packet, } in events.read() @@ -79,7 +77,7 @@ pub fn process_packet_events(ecs: &mut World) { } for (player_entity, packet) in events_owned { match packet { - ClientboundConfigurationPacket::RegistryData(p) => { + ClientboundConfigPacket::RegistryData(p) => { let mut system_state: SystemState> = SystemState::new(ecs); let mut query = system_state.get_mut(ecs); @@ -90,10 +88,10 @@ pub fn process_packet_events(ecs: &mut World) { instance.registries.append(p.registry_id, p.entries); } - ClientboundConfigurationPacket::CustomPayload(p) => { + ClientboundConfigPacket::CustomPayload(p) => { debug!("Got custom payload packet {p:?}"); } - ClientboundConfigurationPacket::Disconnect(p) => { + ClientboundConfigPacket::Disconnect(p) => { warn!("Got disconnect packet {p:?}"); let mut system_state: SystemState> = SystemState::new(ecs); @@ -103,20 +101,20 @@ pub fn process_packet_events(ecs: &mut World) { reason: Some(p.reason.clone()), }); } - ClientboundConfigurationPacket::FinishConfiguration(p) => { + ClientboundConfigPacket::FinishConfiguration(p) => { debug!("got FinishConfiguration packet: {p:?}"); let mut system_state: SystemState> = SystemState::new(ecs); let mut query = system_state.get_mut(ecs); - let mut raw_connection = query.get_mut(player_entity).unwrap(); + let mut raw_conn = query.get_mut(player_entity).unwrap(); - raw_connection - .write_packet(ServerboundFinishConfigurationPacket {}.get()) + raw_conn + .write_packet(ServerboundFinishConfiguration {}) .expect( "we should be in the right state and encoding this packet shouldn't fail", ); - raw_connection.set_state(ConnectionProtocol::Game); + raw_conn.set_state(ConnectionProtocol::Game); // these components are added now that we're going to be in the Game state ecs.entity_mut(player_entity) @@ -140,7 +138,7 @@ pub fn process_packet_events(ecs: &mut World) { _local_entity: azalea_entity::LocalEntity, }); } - ClientboundConfigurationPacket::KeepAlive(p) => { + ClientboundConfigPacket::KeepAlive(p) => { debug!("Got keep alive packet (in configuration) {p:?} for {player_entity:?}"); let mut system_state: SystemState<( @@ -148,80 +146,91 @@ pub fn process_packet_events(ecs: &mut World) { EventWriter, )> = SystemState::new(ecs); let (query, mut keepalive_events) = system_state.get_mut(ecs); - let raw_connection = query.get(player_entity).unwrap(); + let raw_conn = query.get(player_entity).unwrap(); keepalive_events.send(KeepAliveEvent { entity: player_entity, id: p.id, }); - raw_connection - .write_packet(ServerboundKeepAlivePacket { id: p.id }.get()) + raw_conn + .write_packet(ServerboundKeepAlive { id: p.id }) .unwrap(); } - ClientboundConfigurationPacket::Ping(p) => { + ClientboundConfigPacket::Ping(p) => { debug!("Got ping packet {p:?}"); let mut system_state: SystemState> = SystemState::new(ecs); let mut query = system_state.get_mut(ecs); - let raw_connection = query.get_mut(player_entity).unwrap(); + let raw_conn = query.get_mut(player_entity).unwrap(); - raw_connection - .write_packet(ServerboundPongPacket { id: p.id }.get()) + raw_conn + .write_packet(config::s_pong::ServerboundPong { id: p.id }) .unwrap(); } - ClientboundConfigurationPacket::ResourcePackPush(p) => { + ClientboundConfigPacket::ResourcePackPush(p) => { debug!("Got resource pack packet {p:?}"); let mut system_state: SystemState> = SystemState::new(ecs); let mut query = system_state.get_mut(ecs); - let raw_connection = query.get_mut(player_entity).unwrap(); + let raw_conn = query.get_mut(player_entity).unwrap(); // always accept resource pack - raw_connection.write_packet( - ServerboundResourcePackPacket { + raw_conn + .write_packet(ServerboundResourcePack { id: p.id, - action: azalea_protocol::packets::configuration::serverbound_resource_pack_packet::Action::Accepted - }.get() - ).unwrap(); + action: config::s_resource_pack::Action::Accepted, + }) + .unwrap(); } - ClientboundConfigurationPacket::ResourcePackPop(_) => { + ClientboundConfigPacket::ResourcePackPop(_) => { // we can ignore this } - ClientboundConfigurationPacket::UpdateEnabledFeatures(p) => { + ClientboundConfigPacket::UpdateEnabledFeatures(p) => { debug!("Got update enabled features packet {p:?}"); } - ClientboundConfigurationPacket::UpdateTags(_p) => { + ClientboundConfigPacket::UpdateTags(_p) => { debug!("Got update tags packet"); } - ClientboundConfigurationPacket::CookieRequest(p) => { + ClientboundConfigPacket::CookieRequest(p) => { debug!("Got cookie request packet {p:?}"); + + let mut system_state: SystemState> = SystemState::new(ecs); + let mut query = system_state.get_mut(ecs); + let raw_conn = query.get_mut(player_entity).unwrap(); + + raw_conn + .write_packet(ServerboundCookieResponse { + key: p.key, + // cookies aren't implemented + payload: None, + }) + .unwrap(); } - ClientboundConfigurationPacket::ResetChat(p) => { + ClientboundConfigPacket::ResetChat(p) => { debug!("Got reset chat packet {p:?}"); } - ClientboundConfigurationPacket::StoreCookie(p) => { + ClientboundConfigPacket::StoreCookie(p) => { debug!("Got store cookie packet {p:?}"); } - ClientboundConfigurationPacket::Transfer(p) => { + ClientboundConfigPacket::Transfer(p) => { debug!("Got transfer packet {p:?}"); } - ClientboundConfigurationPacket::SelectKnownPacks(p) => { + ClientboundConfigPacket::SelectKnownPacks(p) => { debug!("Got select known packs packet {p:?}"); let mut system_state: SystemState> = SystemState::new(ecs); let mut query = system_state.get_mut(ecs); - let raw_connection = query.get_mut(player_entity).unwrap(); + let raw_conn = query.get_mut(player_entity).unwrap(); // resource pack management isn't implemented - raw_connection - .write_packet( - ServerboundSelectKnownPacksPacket { - known_packs: vec![], - } - .get(), - ) + raw_conn + .write_packet(ServerboundSelectKnownPacks { + known_packs: vec![], + }) .unwrap(); } + ClientboundConfigPacket::ServerLinks(_) => {} + ClientboundConfigPacket::CustomReportDetails(_) => {} } } } @@ -229,19 +238,25 @@ pub fn process_packet_events(ecs: &mut World) { /// An event for sending a packet to the server while we're in the /// `configuration` state. #[derive(Event)] -pub struct SendConfigurationPacketEvent { - pub entity: Entity, - pub packet: ServerboundConfigurationPacket, +pub struct SendConfigurationEvent { + pub sent_by: Entity, + pub packet: ServerboundConfigPacket, +} +impl SendConfigurationEvent { + pub fn new(sent_by: Entity, packet: impl Packet) -> Self { + let packet = packet.into_variant(); + Self { sent_by, packet } + } } pub fn handle_send_packet_event( - mut send_packet_events: EventReader, + mut send_packet_events: EventReader, mut query: Query<&mut RawConnection>, ) { for event in send_packet_events.read() { - if let Ok(raw_connection) = query.get_mut(event.entity) { + if let Ok(raw_conn) = query.get_mut(event.sent_by) { // debug!("Sending packet: {:?}", event.packet); - if let Err(e) = raw_connection.write_packet(event.packet.clone()) { + if let Err(e) = raw_conn.write_packet(event.packet.clone()) { error!("Failed to send packet: {e}"); } } diff --git a/azalea-client/src/packet_handling/game.rs b/azalea-client/src/packet_handling/game.rs index 3c6ad6b5..38178a63 100644 --- a/azalea-client/src/packet_handling/game.rs +++ b/azalea-client/src/packet_handling/game.rs @@ -17,14 +17,15 @@ use azalea_entity::{ Physics, PlayerBundle, Position, RelativeEntityUpdate, }; use azalea_protocol::{ - packets::game::{ - clientbound_player_combat_kill_packet::ClientboundPlayerCombatKillPacket, - serverbound_accept_teleportation_packet::ServerboundAcceptTeleportationPacket, - serverbound_configuration_acknowledged_packet::ServerboundConfigurationAcknowledgedPacket, - serverbound_keep_alive_packet::ServerboundKeepAlivePacket, - serverbound_move_player_pos_rot_packet::ServerboundMovePlayerPosRotPacket, - serverbound_pong_packet::ServerboundPongPacket, ClientboundGamePacket, - ServerboundGamePacket, + packets::{ + game::{ + c_player_combat_kill::ClientboundPlayerCombatKill, + s_accept_teleportation::ServerboundAcceptTeleportation, + s_configuration_acknowledged::ServerboundConfigurationAcknowledged, + s_keep_alive::ServerboundKeepAlive, s_move_player_pos_rot::ServerboundMovePlayerPosRot, + s_pong::ServerboundPong, ClientboundGamePacket, ServerboundGamePacket, + }, + Packet, }, read::deserialize_packet, }; @@ -103,12 +104,12 @@ pub struct UpdatePlayerEvent { } /// Event for when an entity dies. dies. If it's a local player and there's a -/// reason in the death screen, the [`ClientboundPlayerCombatKillPacket`] will +/// reason in the death screen, the [`ClientboundPlayerCombatKill`] will /// be included. #[derive(Event, Debug, Clone)] pub struct DeathEvent { pub entity: Entity, - pub packet: Option, + pub packet: Option, } /// A KeepAlive packet is sent from the server to verify that the client is @@ -340,10 +341,9 @@ pub fn process_packet_events(ecs: &mut World) { "Sending client information because login: {:?}", client_information ); - send_packet_events.send(SendPacketEvent { - entity: player_entity, - packet: azalea_protocol::packets::game::serverbound_client_information_packet::ServerboundClientInformationPacket { information: client_information.clone() }.get(), - }); + send_packet_events.send(SendPacketEvent::new(player_entity, + azalea_protocol::packets::game::s_client_information::ServerboundClientInformation { information: client_information.clone() }, + )); system_state.apply(ecs); } @@ -493,13 +493,13 @@ pub fn process_packet_events(ecs: &mut World) { **position = new_pos; } - send_packet_events.send(SendPacketEvent { - entity: player_entity, - packet: ServerboundAcceptTeleportationPacket { id: p.id }.get(), - }); - send_packet_events.send(SendPacketEvent { - entity: player_entity, - packet: ServerboundMovePlayerPosRotPacket { + send_packet_events.send(SendPacketEvent::new( + player_entity, + ServerboundAcceptTeleportation { id: p.id }, + )); + send_packet_events.send(SendPacketEvent::new( + player_entity, + ServerboundMovePlayerPosRot { x: new_pos.x, y: new_pos.y, z: new_pos.z, @@ -507,9 +507,8 @@ pub fn process_packet_events(ecs: &mut World) { x_rot, // this is always false on_ground: false, - } - .get(), - }); + }, + )); } ClientboundGamePacket::PlayerInfoUpdate(p) => { debug!("Got player info packet {p:?}"); @@ -983,10 +982,10 @@ pub fn process_packet_events(ecs: &mut World) { entity: player_entity, id: p.id, }); - send_packet_events.send(SendPacketEvent { - entity: player_entity, - packet: ServerboundKeepAlivePacket { id: p.id }.get(), - }); + send_packet_events.send(SendPacketEvent::new( + player_entity, + ServerboundKeepAlive { id: p.id }, + )); } ClientboundGamePacket::RemoveEntities(p) => { debug!("Got remove entities packet {:?}", p); @@ -1096,7 +1095,7 @@ pub fn process_packet_events(ecs: &mut World) { } } ClientboundGamePacket::GameEvent(p) => { - use azalea_protocol::packets::game::clientbound_game_event_packet::EventType; + use azalea_protocol::packets::game::c_game_event::EventType; debug!("Got game event packet {p:?}"); @@ -1279,10 +1278,10 @@ pub fn process_packet_events(ecs: &mut World) { SystemState::new(ecs); let mut send_packet_events = system_state.get_mut(ecs); - send_packet_events.send(SendPacketEvent { - entity: player_entity, - packet: ServerboundPongPacket { id: p.id }.get(), - }); + send_packet_events.send(SendPacketEvent::new( + player_entity, + ServerboundPong { id: p.id }, + )); } ClientboundGamePacket::PlaceGhostRecipe(_) => {} ClientboundGamePacket::PlayerCombatEnd(_) => {} @@ -1423,10 +1422,10 @@ pub fn process_packet_events(ecs: &mut World) { SystemState::new(ecs); let (mut commands, mut packet_events) = system_state.get_mut(ecs); - packet_events.send(SendPacketEvent { - entity: player_entity, - packet: ServerboundConfigurationAcknowledgedPacket {}.get(), - }); + packet_events.send(SendPacketEvent::new( + player_entity, + ServerboundConfigurationAcknowledged {}, + )); commands .entity(player_entity) @@ -1459,7 +1458,7 @@ pub fn process_packet_events(ecs: &mut World) { ClientboundGamePacket::TabList(_) => {} ClientboundGamePacket::TagQuery(_) => {} ClientboundGamePacket::TakeItemEntity(_) => {} - ClientboundGamePacket::Bundle(_) => {} + ClientboundGamePacket::BundleDelimiter(_) => {} ClientboundGamePacket::DamageEvent(_) => {} ClientboundGamePacket::HurtAnimation(_) => {} @@ -1472,7 +1471,7 @@ pub fn process_packet_events(ecs: &mut World) { ClientboundGamePacket::PongResponse(_) => {} ClientboundGamePacket::StoreCookie(_) => {} ClientboundGamePacket::Transfer(_) => {} - ClientboundGamePacket::MoveMinecart(_) => {} + ClientboundGamePacket::MoveMinecartAlongTrack(_) => {} ClientboundGamePacket::SetHeldSlot(_) => {} ClientboundGamePacket::SetPlayerInventory(_) => {} ClientboundGamePacket::ProjectilePower(_) => {} @@ -1490,16 +1489,22 @@ pub fn process_packet_events(ecs: &mut World) { /// An event for sending a packet to the server while we're in the `game` state. #[derive(Event)] pub struct SendPacketEvent { - pub entity: Entity, + pub sent_by: Entity, pub packet: ServerboundGamePacket, } +impl SendPacketEvent { + pub fn new(sent_by: Entity, packet: impl Packet) -> Self { + let packet = packet.into_variant(); + Self { sent_by, packet } + } +} pub fn handle_send_packet_event( mut send_packet_events: EventReader, mut query: Query<&mut RawConnection>, ) { for event in send_packet_events.read() { - if let Ok(raw_connection) = query.get_mut(event.entity) { + if let Ok(raw_connection) = query.get_mut(event.sent_by) { // debug!("Sending packet: {:?}", event.packet); if let Err(e) = raw_connection.write_packet(event.packet.clone()) { error!("Failed to send packet: {e}"); diff --git a/azalea-client/src/packet_handling/login.rs b/azalea-client/src/packet_handling/login.rs index 7d71b440..11c0b8e9 100644 --- a/azalea-client/src/packet_handling/login.rs +++ b/azalea-client/src/packet_handling/login.rs @@ -3,9 +3,12 @@ use std::{collections::HashSet, sync::Arc}; -use azalea_protocol::packets::login::{ - serverbound_custom_query_answer_packet::ServerboundCustomQueryAnswerPacket, - ClientboundLoginPacket, ServerboundLoginPacket, +use azalea_protocol::packets::{ + login::{ + s_custom_query_answer::ServerboundCustomQueryAnswer, ClientboundLoginPacket, + ServerboundLoginPacket, + }, + Packet, }; use bevy_ecs::{prelude::*, system::SystemState}; use derive_more::{Deref, DerefMut}; @@ -33,6 +36,12 @@ pub struct SendLoginPacketEvent { pub entity: Entity, pub packet: ServerboundLoginPacket, } +impl SendLoginPacketEvent { + pub fn new(entity: Entity, packet: impl Packet) -> Self { + let packet = packet.into_variant(); + Self { entity, packet } + } +} #[derive(Component)] pub struct LoginSendPacketQueue { @@ -86,14 +95,13 @@ pub fn process_packet_events(ecs: &mut World) { } } - send_packet_events.send(SendLoginPacketEvent { - entity: player_entity, - packet: ServerboundCustomQueryAnswerPacket { + send_packet_events.send(SendLoginPacketEvent::new( + player_entity, + ServerboundCustomQueryAnswer { transaction_id: p.transaction_id, data: None, - } - .get(), - }); + }, + )); } _ => {} } diff --git a/azalea-client/src/packet_handling/mod.rs b/azalea-client/src/packet_handling/mod.rs index eb8f1d47..6bb9c319 100644 --- a/azalea-client/src/packet_handling/mod.rs +++ b/azalea-client/src/packet_handling/mod.rs @@ -61,9 +61,9 @@ impl Plugin for PacketHandlerPlugin { ) // we do this instead of add_event so we can handle the events ourselves .init_resource::>() - .init_resource::>() + .init_resource::>() .add_event::() - .add_event::() + .add_event::() .add_event::() .add_event::() .add_event::() diff --git a/azalea-client/src/ping.rs b/azalea-client/src/ping.rs index ded1b521..f5d714cd 100755 --- a/azalea-client/src/ping.rs +++ b/azalea-client/src/ping.rs @@ -5,14 +5,13 @@ use std::io; use azalea_protocol::{ connect::{Connection, ConnectionError, Proxy}, packets::{ - handshaking::{ - client_intention_packet::ClientIntentionPacket, ClientboundHandshakePacket, + handshake::{ + s_intention::ServerboundIntention, ClientboundHandshakePacket, ServerboundHandshakePacket, }, status::{ - clientbound_status_response_packet::ClientboundStatusResponsePacket, - serverbound_status_request_packet::ServerboundStatusRequestPacket, - ClientboundStatusPacket, + c_status_response::ClientboundStatusResponse, + s_status_request::ServerboundStatusRequest, ClientboundStatusPacket, }, ClientIntention, PROTOCOL_VERSION, }, @@ -49,7 +48,7 @@ pub enum PingError { /// ``` pub async fn ping_server( address: impl TryInto, -) -> Result { +) -> Result { let address: ServerAddress = address.try_into().map_err(|_| PingError::InvalidAddress)?; let resolved_address = resolver::resolve_address(&address).await?; let conn = Connection::new(&resolved_address).await?; @@ -60,7 +59,7 @@ pub async fn ping_server( pub async fn ping_server_with_proxy( address: impl TryInto, proxy: Proxy, -) -> Result { +) -> Result { let address: ServerAddress = address.try_into().map_err(|_| PingError::InvalidAddress)?; let resolved_address = resolver::resolve_address(&address).await?; let conn = Connection::new_with_proxy(&resolved_address, proxy).await?; @@ -73,22 +72,19 @@ pub async fn ping_server_with_proxy( pub async fn ping_server_with_connection( address: ServerAddress, mut conn: Connection, -) -> Result { +) -> Result { // send the client intention packet and switch to the status state - conn.write( - ClientIntentionPacket { - protocol_version: PROTOCOL_VERSION, - hostname: address.host.clone(), - port: address.port, - intention: ClientIntention::Status, - } - .get(), - ) + conn.write(ServerboundIntention { + protocol_version: PROTOCOL_VERSION, + hostname: address.host.clone(), + port: address.port, + intention: ClientIntention::Status, + }) .await?; let mut conn = conn.status(); // send the empty status request packet - conn.write(ServerboundStatusRequestPacket {}.get()).await?; + conn.write(ServerboundStatusRequest {}).await?; let packet = conn.read().await?; diff --git a/azalea-client/src/raw_connection.rs b/azalea-client/src/raw_connection.rs index 8cbb15a4..3eacf528 100644 --- a/azalea-client/src/raw_connection.rs +++ b/azalea-client/src/raw_connection.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use azalea_protocol::{ connect::{RawReadConnection, RawWriteConnection}, - packets::{ConnectionProtocol, ProtocolPacket}, + packets::{ConnectionProtocol, Packet, ProtocolPacket}, read::ReadPacketError, write::serialize_packet, }; @@ -106,8 +106,9 @@ impl RawConnection { /// encoding it failed somehow (like it's too big or something). pub fn write_packet( &self, - packet: P, + packet: impl Packet

, ) -> Result<(), WritePacketError> { + let packet = packet.into_variant(); let raw_packet = serialize_packet(&packet)?; self.write_raw_packet(raw_packet)?; diff --git a/azalea-client/src/respawn.rs b/azalea-client/src/respawn.rs index 150b3591..edd2a43a 100644 --- a/azalea-client/src/respawn.rs +++ b/azalea-client/src/respawn.rs @@ -1,6 +1,4 @@ -use azalea_protocol::packets::game::serverbound_client_command_packet::{ - self, ServerboundClientCommandPacket, -}; +use azalea_protocol::packets::game::s_client_command::{self, ServerboundClientCommand}; use bevy_app::{App, Plugin, Update}; use bevy_ecs::prelude::*; @@ -26,12 +24,11 @@ pub fn perform_respawn( mut send_packets: EventWriter, ) { for event in events.read() { - send_packets.send(SendPacketEvent { - entity: event.entity, - packet: ServerboundClientCommandPacket { - action: serverbound_client_command_packet::Action::PerformRespawn, - } - .get(), - }); + send_packets.send(SendPacketEvent::new( + event.entity, + ServerboundClientCommand { + action: s_client_command::Action::PerformRespawn, + }, + )); } } -- cgit v1.2.3