aboutsummaryrefslogtreecommitdiff
path: root/azalea-client/src
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2025-08-20 06:42:26 -1300
committermat <git@matdoes.dev>2025-08-20 22:42:40 +0300
commit63f15353e7c92c47b48df3aad7fa5c67012637c0 (patch)
tree0b7556cd3c80935fd8e323f0f11673857cb6ef46 /azalea-client/src
parenta89cae5703abe0e103a17e9c931fb6132c448172 (diff)
downloadazalea-drasl-63f15353e7c92c47b48df3aad7fa5c67012637c0.tar.xz
split client information handling out of BrandPlugin and some other cleanup
Diffstat (limited to 'azalea-client/src')
-rw-r--r--azalea-client/src/client.rs41
-rw-r--r--azalea-client/src/plugins/brand.rs47
-rw-r--r--azalea-client/src/plugins/chat/mod.rs4
-rw-r--r--azalea-client/src/plugins/client_information.rs79
-rw-r--r--azalea-client/src/plugins/mod.rs2
5 files changed, 95 insertions, 78 deletions
diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs
index be9c8e99..884d8c20 100644
--- a/azalea-client/src/client.rs
+++ b/azalea-client/src/client.rs
@@ -22,12 +22,8 @@ use azalea_entity::{
use azalea_physics::local_player::PhysicsState;
use azalea_protocol::{
ServerAddress,
- common::client_information::ClientInformation,
connect::Proxy,
- packets::{
- Packet,
- game::{self, ServerboundGamePacket},
- },
+ packets::{Packet, game::ServerboundGamePacket},
resolver,
};
use azalea_world::{Instance, InstanceContainer, InstanceName, MinecraftEntityId, PartialInstance};
@@ -43,7 +39,7 @@ use tokio::{
sync::mpsc::{self},
time,
};
-use tracing::{debug, error, info, warn};
+use tracing::{error, info, warn};
use uuid::Uuid;
use crate::{
@@ -378,39 +374,6 @@ impl Client {
self.query::<Option<&InstanceName>>(&mut self.ecs.lock())
.is_some()
}
-
- /// 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,
- });
- }
- }
}
impl Client {
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)