diff options
Diffstat (limited to 'azalea-client/src/plugins')
| -rw-r--r-- | azalea-client/src/plugins/brand.rs | 47 | ||||
| -rw-r--r-- | azalea-client/src/plugins/chat/mod.rs | 4 | ||||
| -rw-r--r-- | azalea-client/src/plugins/client_information.rs | 79 | ||||
| -rw-r--r-- | azalea-client/src/plugins/mod.rs | 2 |
4 files changed, 93 insertions, 39 deletions
diff --git a/azalea-client/src/plugins/brand.rs b/azalea-client/src/plugins/brand.rs index cf179e71..3b118efd 100644 --- a/azalea-client/src/plugins/brand.rs +++ b/azalea-client/src/plugins/brand.rs @@ -1,60 +1,33 @@ use azalea_buf::AzaleaWrite; -use azalea_core::resource_location::ResourceLocation; -use azalea_protocol::{ - common::client_information::ClientInformation, - packets::config::{ - s_client_information::ServerboundClientInformation, - s_custom_payload::ServerboundCustomPayload, - }, -}; +use azalea_protocol::packets::config::s_custom_payload::ServerboundCustomPayload; use bevy_app::prelude::*; use bevy_ecs::prelude::*; -use tracing::{debug, warn}; use super::packet::config::SendConfigPacketEvent; -use crate::packet::login::InLoginState; +use crate::{client_information::send_client_information, packet::login::InLoginState}; +/// Send a [`ServerboundCustomPayload`] with "vanilla" as the brand on join. +/// +/// You can [disable this plugin](https://azalea.matdoes.dev/azalea/struct.ClientBuilder.html#method.new_without_plugins) +/// and register your own system if you'd like to send a different brand. pub struct BrandPlugin; impl Plugin for BrandPlugin { fn build(&self, app: &mut App) { - app.add_systems(Update, handle_end_login_state); + app.add_systems(Update, send_brand.before(send_client_information)); } } -pub fn handle_end_login_state( - mut commands: Commands, - mut removed: RemovedComponents<InLoginState>, - query: Query<&ClientInformation>, -) { +pub fn send_brand(mut commands: Commands, mut removed: RemovedComponents<InLoginState>) { for entity in removed.read() { let mut brand_data = Vec::new(); - // azalea pretends to be vanilla everywhere else so it makes sense to lie here - // too + // pretend to be vanilla "vanilla".azalea_write(&mut brand_data).unwrap(); commands.trigger(SendConfigPacketEvent::new( entity, ServerboundCustomPayload { - identifier: ResourceLocation::new("brand"), + identifier: "brand".into(), data: brand_data.into(), }, )); - - let client_information = match query.get(entity).ok() { - Some(i) => i, - None => { - warn!( - "ClientInformation component was not set before leaving login state, using a default" - ); - &ClientInformation::default() - } - }; - - debug!("Writing ClientInformation while in config state: {client_information:?}"); - commands.trigger(SendConfigPacketEvent::new( - entity, - ServerboundClientInformation { - information: client_information.clone(), - }, - )); } } diff --git a/azalea-client/src/plugins/chat/mod.rs b/azalea-client/src/plugins/chat/mod.rs index f70d0eb6..f8ef3251 100644 --- a/azalea-client/src/plugins/chat/mod.rs +++ b/azalea-client/src/plugins/chat/mod.rs @@ -188,7 +188,7 @@ impl Client { /// send chat messages that start with a `/`. The [`Client::chat`] function /// handles checking whether the message is a command and using the /// proper packet for you, so you should use that instead. - pub fn send_chat_packet(&self, message: &str) { + pub fn write_chat_packet(&self, message: &str) { self.ecs.lock().send_event(SendChatKindEvent { entity: self.entity, content: message.to_string(), @@ -201,7 +201,7 @@ impl Client { /// /// You can also just use [`Client::chat`] and start your message with a `/` /// to send a command. - pub fn send_command_packet(&self, command: &str) { + pub fn write_command_packet(&self, command: &str) { self.ecs.lock().send_event(SendChatKindEvent { entity: self.entity, content: command.to_string(), diff --git a/azalea-client/src/plugins/client_information.rs b/azalea-client/src/plugins/client_information.rs new file mode 100644 index 00000000..d30b5329 --- /dev/null +++ b/azalea-client/src/plugins/client_information.rs @@ -0,0 +1,79 @@ +use azalea_protocol::{ + common::client_information::ClientInformation, + packets::{config::s_client_information::ServerboundClientInformation, game}, +}; +use bevy_app::prelude::*; +use bevy_ecs::prelude::*; +use tracing::{debug, warn}; + +use super::packet::config::SendConfigPacketEvent; +use crate::{Client, brand::send_brand, packet::login::InLoginState}; + +/// Send [`ServerboundClientInformation`] on join. +pub struct ClientInformationPlugin; +impl Plugin for ClientInformationPlugin { + fn build(&self, app: &mut App) { + app.add_systems(Update, send_client_information.after(send_brand)); + } +} + +pub fn send_client_information( + mut commands: Commands, + mut removed: RemovedComponents<InLoginState>, + query: Query<&ClientInformation>, +) { + for entity in removed.read() { + let client_information = match query.get(entity).ok() { + Some(i) => i, + None => { + warn!( + "ClientInformation component was not set before leaving login state, using a default" + ); + &ClientInformation::default() + } + }; + + debug!("Writing ClientInformation while in config state: {client_information:?}"); + commands.trigger(SendConfigPacketEvent::new( + entity, + ServerboundClientInformation { + information: client_information.clone(), + }, + )); + } +} + +impl Client { + /// Tell the server we changed our game options (i.e. render distance, main + /// hand). If this is not set before the login packet, the default will + /// be sent. + /// + /// ```rust,no_run + /// # use azalea_client::{Client, ClientInformation}; + /// # async fn example(bot: Client) -> Result<(), Box<dyn std::error::Error>> { + /// bot.set_client_information(ClientInformation { + /// view_distance: 2, + /// ..Default::default() + /// }) + /// .await; + /// # Ok(()) + /// # } + /// ``` + pub async fn set_client_information(&self, client_information: ClientInformation) { + { + let mut ecs = self.ecs.lock(); + let mut client_information_mut = self.query::<&mut ClientInformation>(&mut ecs); + *client_information_mut = client_information.clone(); + } + + if self.logged_in() { + debug!( + "Sending client information (already logged in): {:?}", + client_information + ); + self.write_packet(game::s_client_information::ServerboundClientInformation { + client_information, + }); + } + } +} diff --git a/azalea-client/src/plugins/mod.rs b/azalea-client/src/plugins/mod.rs index 2319f6fc..a12d69cb 100644 --- a/azalea-client/src/plugins/mod.rs +++ b/azalea-client/src/plugins/mod.rs @@ -7,6 +7,7 @@ pub mod brand; pub mod chat; pub mod chat_signing; pub mod chunks; +pub mod client_information; pub mod connection; pub mod disconnect; pub mod events; @@ -54,6 +55,7 @@ impl PluginGroup for DefaultPlugins { .add(tick_end::TickEndPlugin) .add(loading::PlayerLoadedPlugin) .add(brand::BrandPlugin) + .add(client_information::ClientInformationPlugin) .add(tick_broadcast::TickBroadcastPlugin) .add(tick_counter::TickCounterPlugin) .add(pong::PongPlugin) |
