azalea

Struct Client

Source
pub struct Client {
    pub profile: GameProfile,
    pub entity: Entity,
    pub ecs: Arc<Mutex<RawMutex, World>>,
    pub run_schedule_sender: UnboundedSender<()>,
}
Expand description

Client has the things that a user interacting with the library will want.

To make a new client, use either azalea::ClientBuilder or Client::join.

Note that Client is inaccessible from systems (i.e. plugins), but you can achieve everything that client can do with events.

Fields§

§profile: GameProfile

The GameProfile for our client. This contains your username, UUID, and skin data.

This is immutable; the server cannot change it. To get the username and skin the server chose for you, get your player from the TabList component.

This as also available from the ECS as GameProfileComponent.

§entity: Entity

The entity for this client in the ECS.

§ecs: Arc<Mutex<RawMutex, World>>

The entity component system. You probably don’t need to access this directly. Note that if you’re using a shared world (i.e. a swarm), this will contain all entities in all worlds.

§run_schedule_sender: UnboundedSender<()>

Use this to force the client to run the schedule outside of a tick.

Implementations§

Source§

impl Client

Source

pub fn attack(&mut self, entity_id: MinecraftEntityId)

Attack the entity with the given id.

Source

pub fn has_attack_cooldown(&self) -> bool

Whether the player has an attack cooldown.

Source§

impl Client

Source

pub fn send_chat_packet(&self, message: &str)

Send a chat message to the server. This only sends the chat packet and not the command packet, which means on some servers you can use this to 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.

Source

pub fn send_command_packet(&self, command: &str)

Send a command packet to the server. The command argument should not include the slash at the front.

Source

pub fn chat(&self, content: &str)

Send a message in chat.

bot.chat("Hello, world!");
Source§

impl Client

Source

pub fn new( profile: GameProfile, entity: Entity, ecs: Arc<Mutex<RawMutex, World>>, run_schedule_sender: UnboundedSender<()>, ) -> Client

Create a new client from the given GameProfile, ECS Entity, ECS World, and schedule runner function. You should only use this if you want to change these fields from the defaults, otherwise use Client::join.

Source

pub async fn join( account: &Account, address: impl TryInto<ServerAddress>, ) -> Result<(Client, UnboundedReceiver<Event>), JoinError>

Connect to a Minecraft server.

To change the render distance and other settings, use Client::set_client_information. To watch for events like packets sent by the server, use the rx variable this function returns.

§Examples
use azalea_client::{Client, Account};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let account = Account::offline("bot");
    let (client, rx) = Client::join(&account, "localhost").await?;
    client.chat("Hello, world!");
    client.disconnect();
    Ok(())
}
Source

pub async fn join_with_proxy( account: &Account, address: impl TryInto<ServerAddress>, proxy: Proxy, ) -> Result<(Client, UnboundedReceiver<Event>), JoinError>

Source

pub async fn start_client( __arg0: StartClientOpts<'_>, ) -> Result<(Client, UnboundedReceiver<Event>), JoinError>

Create a Client when you already have the ECS made with [start_ecs_runner]. You’d usually want to use Self::join instead.

Source

pub async fn handshake( ecs_lock: Arc<Mutex<RawMutex, World>>, entity: Entity, conn: Connection<ClientboundHandshakePacket, ServerboundHandshakePacket>, account: &Account, address: &ServerAddress, ) -> Result<(Connection<ClientboundConfigurationPacket, ServerboundConfigurationPacket>, GameProfile), JoinError>

Do a handshake with the server and get to the game state from the initial handshake state.

This will also automatically refresh the account’s access token if it’s expired.

Source

pub fn write_packet( &self, packet: ServerboundGamePacket, ) -> Result<(), WritePacketError>

Write a packet directly to the server.

Source

pub fn disconnect(&self)

Disconnect this client from the server by ending all tasks.

The OwnedReadHalf for the TCP connection is in one of the tasks, so it automatically closes the connection when that’s dropped.

Source

pub fn raw_connection<'a>(&'a self, ecs: &'a mut World) -> &'a RawConnection

Source

pub fn raw_connection_mut<'a>( &'a self, ecs: &'a mut World, ) -> Mut<'a, RawConnection>

Source

pub fn component<T>(&self) -> T
where T: Component + Clone,

Get a component from this client. This will clone the component and return it.

§Panics

This will panic if the component doesn’t exist on the client.

§Examples
let world_name = client.component::<InstanceName>();
Source

pub fn get_component<T>(&self) -> Option<T>
where T: Component + Clone,

Get a component from this client, or None if it doesn’t exist.

Source

pub fn world(&self) -> Arc<RwLock<RawRwLock, Instance>>

Get an RwLock with a reference to our (potentially shared) world.

This gets the Instance from the client’s InstanceHolder component. If it’s a normal client, then it’ll be the same as the world the client has loaded. If the client is using a shared world, then the shared world will be a superset of the client’s world.

Source

pub fn partial_world(&self) -> Arc<RwLock<RawRwLock, PartialInstance>>

Get an RwLock with a reference to the world that this client has loaded.

let world = client.partial_world();
let is_0_0_loaded = world.read().chunks.limited_get(&ChunkPos::new(0, 0)).is_some();
Source

pub fn logged_in(&self) -> bool

Returns whether we have a received the login packet yet.

Source

pub async fn set_client_information( &self, client_information: ClientInformation, ) -> Result<(), WritePacketError>

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.

bot.set_client_information(ClientInformation {
    view_distance: 2,
    ..Default::default()
})
.await?;
Source§

impl Client

Source

pub fn position(&self) -> Vec3

Get the position of this client.

This is a shortcut for Vec3::from(&bot.component::<Position>()).

Source

pub fn eye_position(&self) -> Vec3

Get the position of this client’s eyes.

This is a shortcut for bot.position().up(bot.component::<EyeHeight>()).

Source

pub fn health(&self) -> f32

Get the health of this client.

This is a shortcut for *bot.component::<Health>().

Source

pub fn hunger(&self) -> Hunger

Get the hunger level of this client, which includes both food and saturation.

This is a shortcut for self.component::<Hunger>().to_owned().

Source

pub fn username(&self) -> String

Get the username of this client.

This is a shortcut for bot.component::<GameProfileComponent>().name.to_owned().

Source

pub fn uuid(&self) -> Uuid

Get the Minecraft UUID of this client.

This is a shortcut for bot.component::<GameProfileComponent>().uuid.

Source

pub fn tab_list(&self) -> HashMap<Uuid, PlayerInfo>

Get a map of player UUIDs to their information in the tab list.

This is a shortcut for *bot.component::<TabList>().

Source§

impl Client

Source

pub fn query<'w, D>(&self, ecs: &'w mut World) -> <D as WorldQuery>::Item<'w>
where D: QueryData,

A convenience function for getting components of our player’s entity.

§Examples
let is_logged_in = client
    .query::<Option<&InstanceName>>(&mut client.ecs.lock())
    .is_some();
Source

pub fn entity_by<F, Q>( &mut self, predicate: impl EntityPredicate<Q, F>, ) -> Option<Entity>
where F: QueryFilter, Q: QueryData,

Return a lightweight Entity for the entity that matches the given predicate function.

You can then use Self::entity_component to get components from this entity.

§Example

Note that this will very likely change in the future.

use azalea_client::{Client, GameProfileComponent};
use bevy_ecs::query::With;
use azalea_entity::{Position, metadata::Player};

let entity = bot.entity_by::<With<Player>, (&GameProfileComponent,)>(
    |(profile,): &(&GameProfileComponent,)| profile.name == sender_name,
);
if let Some(entity) = entity {
    let position = bot.entity_component::<Position>(entity);
    // ...
}
Source

pub fn entity_component<Q>(&mut self, entity: Entity) -> Q
where Q: Component + Clone,

Get a component from an entity. Note that this will return an owned type (i.e. not a reference) so it may be expensive for larger types.

If you’re trying to get a component for this client, use Self::component.

Source

pub fn get_entity_component<Q>(&mut self, entity: Entity) -> Option<Q>
where Q: Component + Clone,

Get a component from an entity, if it exists. This is similar to Self::entity_component but returns an Option instead of panicking if the component isn’t present.

Source§

impl Client

Source

pub fn block_interact(&mut self, position: BlockPos)

Right click a block. The behavior of this depends on the target block, and it’ll either place the block you’re holding in your hand or use the block you clicked (like toggling a lever).

Note that this may trigger anticheats as it doesn’t take into account whether you’re actually looking at the block.

Source§

impl Client

Source

pub fn menu(&self) -> Menu

Return the menu that is currently open. If no menu is open, this will have the player’s inventory.

Source§

impl Client

Source

pub fn start_mining(&mut self, position: BlockPos)

Source

pub fn left_click_mine(&self, enabled: bool)

When enabled, the bot will mine any block that it is looking at if it is reachable.

Source§

impl Client

Source

pub fn set_jumping(&mut self, jumping: bool)

Set whether we’re jumping. This acts as if you held space in vanilla. If you want to jump once, use the jump function.

If you’re making a realistic client, calling this function every tick is recommended.

Source

pub fn jumping(&self) -> bool

Returns whether the player will try to jump next tick.

Source

pub fn set_direction(&mut self, y_rot: f32, x_rot: f32)

Sets the direction the client is looking. y_rot is yaw (looking to the side), x_rot is pitch (looking up and down). You can get these numbers from the vanilla f3 screen. y_rot goes from -180 to 180, and x_rot goes from -90 to 90.

Source

pub fn direction(&self) -> (f32, f32)

Returns the direction the client is looking. The first value is the y rotation (ie. yaw, looking to the side) and the second value is the x rotation (ie. pitch, looking up and down).

Source§

impl Client

Source

pub fn walk(&mut self, direction: WalkDirection)

Start walking in the given direction. To sprint, use Client::sprint. To stop walking, call walk with WalkDirection::None.

§Examples

Walk for 1 second

bot.walk(WalkDirection::Forward);
tokio::time::sleep(Duration::from_secs(1)).await;
bot.walk(WalkDirection::None);
Source

pub fn sprint(&mut self, direction: SprintDirection)

Start sprinting in the given direction. To stop moving, call [Client::walk(WalkDirection::None)]

§Examples

Sprint for 1 second

bot.sprint(SprintDirection::Forward);
tokio::time::sleep(Duration::from_secs(1)).await;
bot.walk(WalkDirection::None);

Trait Implementations§

Source§

impl AutoToolClientExt for Client

Source§

impl BotClientExt for Client

Source§

fn get_tick_broadcaster(&self) -> Receiver<()>

let mut ticks = bot.get_tick_broadcaster();
while ticks.recv().await.is_ok() {
    let ecs = bot.ecs.lock();
    if ecs.get::<WaitingForInventoryOpen>(bot.entity).is_none() {
        break;
    }
}
Source§

fn jump(&mut self)

Queue a jump for the next tick.
Source§

fn look_at(&mut self, position: Vec3)

Turn the bot’s head to look at the coordinate in the world.
Source§

async fn mine(&mut self, position: BlockPos)

Mine a block. This won’t turn the bot’s head towards the block, so if that’s necessary you’ll have to do that yourself with look_at.
Source§

impl Clone for Client

Source§

fn clone(&self) -> Client

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl ContainerClientExt for Client

Source§

async fn open_container_at(&mut self, pos: BlockPos) -> Option<ContainerHandle>

Open a container in the world, like a chest. Use Client::open_inventory to open your own inventory.

let target_pos = bot
    .world()
    .read()
    .find_block(bot.position(), &azalea::registry::Block::Chest.into());
let Some(target_pos) = target_pos else {
    bot.chat("no chest found");
    return;
};
let container = bot.open_container_at(target_pos).await;
Source§

fn open_inventory(&mut self) -> Option<ContainerHandle>

Open the player’s inventory. This will return None if another container is open.

Note that this will send a packet to the server once it’s dropped. Also, due to how it’s implemented, you could call this function multiple times while another inventory handle already exists (but you shouldn’t).

If you just want to get the items in the player’s inventory without sending any packets, use Client::menu, Menu::player_slots_range, and Menu::slots.

Source§

fn get_open_container(&self) -> Option<ContainerHandleRef>

Get a handle to the open container. This will return None if no container is open. This will not close the container when it’s dropped.

See Client::open_inventory or Client::menu if you want to open your own inventory.

Source§

impl PathfinderClientExt for Client

Source§

fn goto(&self, goal: impl Goal + Send + Sync + 'static)

bot.goto(BlockPosGoal(BlockPos::new(0, 70, 0)));
Source§

fn goto_without_mining(&self, goal: impl Goal + Send + Sync + 'static)

Same as goto. but the bot won’t break any blocks while executing the path.

Source§

fn stop_pathfinding(&self)

Auto Trait Implementations§

§

impl Freeze for Client

§

impl !RefUnwindSafe for Client

§

impl Send for Client

§

impl Sync for Client

§

impl Unpin for Client

§

impl !UnwindSafe for Client

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> AsAny for T
where T: Any,

§

fn as_any(&self) -> &(dyn Any + 'static)

§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

§

fn type_name(&self) -> &'static str

Gets the type name of self
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> Downcast for T
where T: AsAny + ?Sized,

§

fn is<T>(&self) -> bool
where T: AsAny,

Returns true if the boxed type is the same as T. Read more
§

fn downcast_ref<T>(&self) -> Option<&T>
where T: AsAny,

Forward to the method defined on the type Any.
§

fn downcast_mut<T>(&mut self) -> Option<&mut T>
where T: AsAny,

Forward to the method defined on the type Any.
§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> TypeData for T
where T: 'static + Send + Sync + Clone,

§

fn clone_type_data(&self) -> Box<dyn TypeData>

§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more