aboutsummaryrefslogtreecommitdiff
path: root/azalea-client/src
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2022-10-23 19:00:24 -0500
committerGitHub <noreply@github.com>2022-10-23 19:00:24 -0500
commit65da123631b0a2dc078786f60fa6b213e8b430ee (patch)
tree8854f29c4240d36bec1710ebc2293a488c495d3d /azalea-client/src
parent587001724acf8a7c6de30927da31c1f5fd7fdb09 (diff)
downloadazalea-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.rs4
-rw-r--r--azalea-client/src/client.rs51
-rwxr-xr-xazalea-client/src/lib.rs2
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;