diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2022-10-23 19:00:24 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-23 19:00:24 -0500 |
| commit | 65da123631b0a2dc078786f60fa6b213e8b430ee (patch) | |
| tree | 8854f29c4240d36bec1710ebc2293a488c495d3d /azalea-client/src | |
| parent | 587001724acf8a7c6de30927da31c1f5fd7fdb09 (diff) | |
| download | azalea-drasl-65da123631b0a2dc078786f60fa6b213e8b430ee.tar.xz | |
Add Client::set_client_information (#33)
* start adding options
* add default options
* send options packet by default
* mention set_options in Client::join doc
* make TranslatableComponent::read return TextComponent
* change set_options to set_client_information
* clean up some code
* Add `Initialize` event
* fix some clippy warnings
* change `Client::options` to `client_information`
Diffstat (limited to 'azalea-client/src')
| -rw-r--r-- | azalea-client/src/chat.rs | 4 | ||||
| -rw-r--r-- | azalea-client/src/client.rs | 51 | ||||
| -rwxr-xr-x | azalea-client/src/lib.rs | 2 |
3 files changed, 53 insertions, 4 deletions
diff --git a/azalea-client/src/chat.rs b/azalea-client/src/chat.rs index 335261e6..18fa4549 100644 --- a/azalea-client/src/chat.rs +++ b/azalea-client/src/chat.rs @@ -84,8 +84,8 @@ impl Client { /// # } /// ``` pub async fn chat(&self, message: &str) -> Result<(), std::io::Error> { - if message.starts_with('/') { - self.send_command_packet(&message[1..]).await + if let Some(command) = message.strip_prefix('/') { + self.send_command_packet(command).await } else { self.send_chat_packet(message).await } diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs index af47b2cd..60f9c9fc 100644 --- a/azalea-client/src/client.rs +++ b/azalea-client/src/client.rs @@ -9,6 +9,7 @@ use azalea_protocol::{ clientbound_player_chat_packet::ClientboundPlayerChatPacket, clientbound_system_chat_packet::ClientboundSystemChatPacket, serverbound_accept_teleportation_packet::ServerboundAcceptTeleportationPacket, + serverbound_client_information_packet::ServerboundClientInformationPacket, serverbound_custom_payload_packet::ServerboundCustomPayloadPacket, serverbound_keep_alive_packet::ServerboundKeepAlivePacket, serverbound_move_player_pos_rot_packet::ServerboundMovePlayerPosRotPacket, @@ -30,7 +31,7 @@ use azalea_world::{ Dimension, }; use log::{debug, error, warn}; -use parking_lot::Mutex; +use parking_lot::{Mutex, RwLock}; use std::{ fmt::Debug, io::{self, Cursor}, @@ -43,10 +44,17 @@ use tokio::{ time::{self}, }; +pub type ClientInformation = ServerboundClientInformationPacket; + /// Events are sent before they're processed, so for example game ticks happen /// at the beginning of a tick before anything has happened. #[derive(Debug, Clone)] pub enum Event { + /// Happens right after the bot switches into the Game state, but before + /// it's actually spawned. This can be useful for setting the client + /// information with `Client::set_client_information`, so the packet + /// doesn't have to be sent twice. + Initialize, Login, Chat(ChatPacket), /// Happens 20 times per second, but only when the world is loaded. @@ -78,6 +86,7 @@ pub struct Client { pub player: Arc<Mutex<Player>>, pub dimension: Arc<Mutex<Dimension>>, pub physics_state: Arc<Mutex<PhysicsState>>, + pub client_information: Arc<RwLock<ClientInformation>>, tasks: Arc<Mutex<Vec<JoinHandle<()>>>>, } @@ -123,6 +132,8 @@ pub enum HandleError { impl Client { /// Connect to a Minecraft server. /// + /// To change the render distance and other settings, use [`Client::set_client_information`]. + /// /// # Examples /// /// ```rust,no_run @@ -240,8 +251,11 @@ impl Client { dimension: Arc::new(Mutex::new(Dimension::default())), physics_state: Arc::new(Mutex::new(PhysicsState::default())), tasks: Arc::new(Mutex::new(Vec::new())), + client_information: Arc::new(RwLock::new(ClientInformation::default())), }; + tx.send(Event::Initialize).unwrap(); + // just start up the game loop and we're ready! // if you get an error right here that means you're doing something with locks wrong @@ -389,6 +403,12 @@ impl Client { player_lock.set_entity_id(p.player_id); } + // send the client information that we have set + let client_information_packet: ClientInformation = + client.client_information.read().clone(); + client.write_packet(client_information_packet.get()).await?; + + // brand client .write_packet( ServerboundCustomPayloadPacket { @@ -806,6 +826,35 @@ impl Client { .entity(entity_id) .expect("Player entity should be in the given dimension") } + + /// Returns whether we have a received the login packet yet. + pub fn logged_in(&self) -> bool { + let dimension = self.dimension.lock(); + let player = self.player.lock(); + player.entity(&dimension).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. + pub async fn set_client_information( + &self, + client_information: ServerboundClientInformationPacket, + ) -> Result<(), std::io::Error> { + { + let mut client_information_lock = self.client_information.write(); + *client_information_lock = client_information; + } + + if self.logged_in() { + let client_information_packet = { + let client_information = self.client_information.read(); + client_information.clone().get() + }; + self.write_packet(client_information_packet).await?; + } + + Ok(()) + } } impl<T> From<std::sync::PoisonError<T>> for HandleError { diff --git a/azalea-client/src/lib.rs b/azalea-client/src/lib.rs index 61d2d9ee..84af0298 100755 --- a/azalea-client/src/lib.rs +++ b/azalea-client/src/lib.rs @@ -14,7 +14,7 @@ pub mod ping; mod player; pub use account::Account; -pub use client::{Client, Event}; +pub use client::{Client, ClientInformation, Event}; pub use movement::MoveDirection; pub use player::Player; |
