aboutsummaryrefslogtreecommitdiff
path: root/azalea-client
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2023-02-05 14:31:52 -0600
committermat <github@matdoes.dev>2023-02-05 14:31:52 -0600
commit0d3a091c232d409939db82dfb30f700e57583c85 (patch)
tree592c3734d824fb2a5cc25d07a997c98239b7d99c /azalea-client
parenta72b76839782b26e49598313bb04c5d322a34788 (diff)
downloadazalea-drasl-0d3a091c232d409939db82dfb30f700e57583c85.tar.xz
improve docs
Diffstat (limited to 'azalea-client')
-rwxr-xr-xazalea-client/src/account.rs6
-rw-r--r--azalea-client/src/client.rs36
-rw-r--r--azalea-client/src/entity_query.rs9
-rw-r--r--azalea-client/src/local_player.rs24
-rw-r--r--azalea-client/src/movement.rs4
-rw-r--r--azalea-client/src/packet_handling.rs42
-rw-r--r--azalea-client/src/task_pool.rs2
7 files changed, 84 insertions, 39 deletions
diff --git a/azalea-client/src/account.rs b/azalea-client/src/account.rs
index 3c2c7d1b..b6073209 100755
--- a/azalea-client/src/account.rs
+++ b/azalea-client/src/account.rs
@@ -8,7 +8,8 @@ use uuid::Uuid;
/// Something that can join Minecraft servers.
///
-/// To join a server using this account, use [`crate::Client::join`].
+/// To join a server using this account, use [`Client::join`] or
+/// [`azalea::ClientBuilder`].
///
/// # Examples
///
@@ -21,6 +22,9 @@ use uuid::Uuid;
/// // or Account::offline("example");
/// # }
/// ```
+///
+/// [`Client::join`]: crate::Client::join
+/// [`azalea::ClientBuilder`]: https://docs.rs/azalea/latest/azalea/struct.ClientBuilder.html
#[derive(Clone, Debug)]
pub struct Account {
/// The Minecraft username of the account.
diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs
index bc1d8d62..ddeeeef3 100644
--- a/azalea-client/src/client.rs
+++ b/azalea-client/src/client.rs
@@ -42,7 +42,7 @@ use azalea_protocol::{
},
resolver, ServerAddress,
};
-use azalea_world::{EntityPlugin, Local, PartialWorld, World, WorldContainer};
+use azalea_world::{entity::WorldName, EntityPlugin, Local, PartialWorld, World, WorldContainer};
use log::{debug, error};
use parking_lot::{Mutex, RwLock};
use std::{collections::HashMap, fmt::Debug, io, net::SocketAddr, sync::Arc};
@@ -52,8 +52,13 @@ use uuid::Uuid;
pub type ClientInformation = ServerboundClientInformationPacket;
-/// Client has the things that a user interacting with the library will want.
+/// `Client` has the things that a user interacting with the library will want.
/// Things that a player in the world will want to know are in [`LocalPlayer`].
+///
+/// To make a new client, use either [`azalea::ClientBuilder`] or
+/// [`Client::join`].
+///
+/// [`azalea::ClientBuilder`]: https://docs.rs/azalea/latest/azalea/struct.ClientBuilder.html
#[derive(Clone)]
pub struct Client {
/// The [`GameProfile`] for our client. This contains your username, UUID,
@@ -362,6 +367,17 @@ impl Client {
/// 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
+ ///
+ /// ```
+ /// # fn example(client: &azalea::Client) {
+ /// let world_name = client.component::<WorldName>();
+ /// # }
pub fn component<T: Component + Clone>(&self) -> T {
self.query::<&T>(&mut self.ecs.lock()).clone()
}
@@ -373,17 +389,8 @@ impl Client {
/// If the client using a shared world, then the shared world will be a
/// superset of the client's world.
pub fn world(&self) -> Arc<RwLock<World>> {
- let mut ecs = self.ecs.lock();
-
- let world_name = {
- let local_player = self.local_player(&mut ecs);
- local_player
- .world_name
- .as_ref()
- .expect("World name must be known if we're doing Client::world")
- .clone()
- };
-
+ let world_name = self.component::<WorldName>();
+ let ecs = self.ecs.lock();
let world_container = ecs.resource::<WorldContainer>();
world_container.get(&world_name).unwrap()
}
@@ -391,7 +398,8 @@ impl Client {
/// Returns whether we have a received the login packet yet.
pub fn logged_in(&self) -> bool {
// the login packet tells us the world name
- self.local_player(&mut self.ecs.lock()).world_name.is_some()
+ self.query::<Option<&WorldName>>(&mut self.ecs.lock())
+ .is_some()
}
/// Tell the server we changed our game options (i.e. render distance, main
diff --git a/azalea-client/src/entity_query.rs b/azalea-client/src/entity_query.rs
index 0e486741..7ac0e325 100644
--- a/azalea-client/src/entity_query.rs
+++ b/azalea-client/src/entity_query.rs
@@ -12,6 +12,15 @@ use crate::Client;
impl Client {
/// A convenience function for getting components of our player's entity.
+ ///
+ /// # Examples
+ /// ```
+ /// # fn example(mut client: azalea_client::Client) {
+ /// let is_logged_in = client
+ /// .query::<Option<&WorldName>>(&mut client.ecs.lock())
+ /// .is_some();
+ /// # }
+ /// ```
pub fn query<'w, Q: WorldQuery>(&self, ecs: &'w mut Ecs) -> <Q as WorldQuery>::Item<'w> {
ecs.query::<Q>()
.get_mut(ecs, self.entity)
diff --git a/azalea-client/src/local_player.rs b/azalea-client/src/local_player.rs
index 0165a5f5..a6921d76 100644
--- a/azalea-client/src/local_player.rs
+++ b/azalea-client/src/local_player.rs
@@ -1,7 +1,7 @@
use std::{collections::HashMap, io, sync::Arc};
use azalea_auth::game_profile::GameProfile;
-use azalea_core::{ChunkPos, ResourceLocation};
+use azalea_core::ChunkPos;
use azalea_ecs::component::Component;
use azalea_ecs::entity::Entity;
use azalea_ecs::{query::Added, system::Query};
@@ -21,22 +21,29 @@ use crate::{
ClientInformation, PlayerInfo, WalkDirection,
};
-/// A player that you control that is currently in a Minecraft server.
+/// This is a component for our local player entities that are probably in a
+/// world. If you have access to a [`Client`], you probably don't need to care
+/// about this since `Client` gives you access to everything here.
+///
+/// You can also use the [`Local`] marker component for queries if you're only
+/// checking for a local player and don't need the contents of this component.
+///
+/// [`Local`]: azalea_world::Local
+/// [`Client`]: crate::Client
#[derive(Component)]
pub struct LocalPlayer {
- pub packet_writer: mpsc::UnboundedSender<ServerboundGamePacket>,
-
+ packet_writer: mpsc::UnboundedSender<ServerboundGamePacket>,
+ /// Some of the "settings" for this client that are sent to the server, such
+ /// as render distance.
pub client_information: ClientInformation,
- /// A map of player uuids to their information in the tab list
+ /// A map of player UUIDs to their information in the tab list
pub players: HashMap<Uuid, PlayerInfo>,
-
/// The partial world is the world this client currently has loaded. It has
/// a limited render distance.
pub partial_world: Arc<RwLock<PartialWorld>>,
/// The world is the combined [`PartialWorld`]s of all clients in the same
/// world. (Only relevant if you're using a shared world, i.e. a swarm)
pub world: Arc<RwLock<World>>,
- pub world_name: Option<ResourceLocation>,
/// A list of async tasks that are running and will stop running when this
/// LocalPlayer is dropped or disconnected with [`Self::disconnect`]
@@ -93,13 +100,12 @@ impl LocalPlayer {
client_information.view_distance.into(),
Some(entity),
))),
- world_name: None,
tasks: Vec::new(),
}
}
- /// Spawn a task to write a packet directly to the server.
+ /// Write a packet directly to the server.
pub fn write_packet(&mut self, packet: ServerboundGamePacket) {
self.packet_writer
.send(packet)
diff --git a/azalea-client/src/movement.rs b/azalea-client/src/movement.rs
index 8d6faabe..f379501c 100644
--- a/azalea-client/src/movement.rs
+++ b/azalea-client/src/movement.rs
@@ -333,6 +333,8 @@ impl Client {
}
}
+/// An event sent when the client starts walking. This does not get sent for
+/// non-local entities.
pub struct StartWalkEvent {
pub entity: Entity,
pub direction: WalkDirection,
@@ -354,6 +356,8 @@ pub fn walk_listener(
}
}
+/// An event sent when the client starts sprinting. This does not get sent for
+/// non-local entities.
pub struct StartSprintEvent {
pub entity: Entity,
pub direction: SprintDirection,
diff --git a/azalea-client/src/packet_handling.rs b/azalea-client/src/packet_handling.rs
index db2c3c45..2d591531 100644
--- a/azalea-client/src/packet_handling.rs
+++ b/azalea-client/src/packet_handling.rs
@@ -26,7 +26,7 @@ use azalea_world::{
entity::{
metadata::{apply_metadata, Health, PlayerMetadataBundle},
set_rotation, Dead, EntityBundle, EntityKind, LastSentPosition, MinecraftEntityId, Physics,
- PlayerBundle, Position,
+ PlayerBundle, Position, WorldName,
},
LoadedBy, PartialWorld, RelativeEntityUpdate, WorldContainer,
};
@@ -128,11 +128,16 @@ fn handle_packets(ecs: &mut Ecs) {
#[allow(clippy::type_complexity)]
let mut system_state: SystemState<(
Commands,
- Query<(&mut LocalPlayer, &GameProfileComponent)>,
+ Query<(
+ &mut LocalPlayer,
+ Option<&mut WorldName>,
+ &GameProfileComponent,
+ )>,
ResMut<WorldContainer>,
)> = SystemState::new(ecs);
let (mut commands, mut query, mut world_container) = system_state.get_mut(ecs);
- let (mut local_player, game_profile) = query.get_mut(player_entity).unwrap();
+ let (mut local_player, world_name, game_profile) =
+ query.get_mut(player_entity).unwrap();
{
// TODO: have registry_holder be a struct because this sucks rn
@@ -188,12 +193,19 @@ fn handle_packets(ecs: &mut Ecs) {
.as_int()
.expect("min_y tag is not an int");
- let world_name = p.dimension.clone();
+ let new_world_name = p.dimension.clone();
- local_player.world_name = Some(world_name.clone());
+ if let Some(mut world_name) = world_name {
+ *world_name = world_name.clone();
+ } else {
+ commands
+ .entity(player_entity)
+ .insert(WorldName(new_world_name.clone()));
+ }
// add this world to the world_container (or don't if it's already
// there)
- let weak_world = world_container.insert(world_name.clone(), height, min_y);
+ let weak_world =
+ world_container.insert(new_world_name.clone(), height, min_y);
// set the partial_world to an empty world
// (when we add chunks or entities those will be in the
// world_container)
@@ -212,7 +224,7 @@ fn handle_packets(ecs: &mut Ecs) {
game_profile.uuid,
Vec3::default(),
azalea_registry::EntityKind::Player,
- world_name,
+ new_world_name,
),
metadata: PlayerMetadataBundle::default(),
};
@@ -506,12 +518,12 @@ fn handle_packets(ecs: &mut Ecs) {
ClientboundGamePacket::AddEntity(p) => {
debug!("Got add entity packet {:?}", p);
- let mut system_state: SystemState<(Commands, Query<&mut LocalPlayer>)> =
+ let mut system_state: SystemState<(Commands, Query<Option<&WorldName>>)> =
SystemState::new(ecs);
let (mut commands, mut query) = system_state.get_mut(ecs);
- let local_player = query.get_mut(player_entity).unwrap();
+ let world_name = query.get_mut(player_entity).unwrap();
- if let Some(world_name) = &local_player.world_name {
+ if let Some(WorldName(world_name)) = world_name {
let bundle = p.as_entity_bundle(world_name.clone());
let mut entity_commands = commands.spawn((
MinecraftEntityId(p.id),
@@ -570,12 +582,14 @@ fn handle_packets(ecs: &mut Ecs) {
ClientboundGamePacket::AddPlayer(p) => {
debug!("Got add player packet {:?}", p);
- let mut system_state: SystemState<(Commands, Query<&mut LocalPlayer>)> =
- SystemState::new(ecs);
+ let mut system_state: SystemState<(
+ Commands,
+ Query<(&mut LocalPlayer, Option<&WorldName>)>,
+ )> = SystemState::new(ecs);
let (mut commands, mut query) = system_state.get_mut(ecs);
- let local_player = query.get_mut(player_entity).unwrap();
+ let (local_player, world_name) = query.get_mut(player_entity).unwrap();
- if let Some(world_name) = &local_player.world_name {
+ if let Some(WorldName(world_name)) = world_name {
let bundle = p.as_player_bundle(world_name.clone());
let mut spawned = commands.spawn((
MinecraftEntityId(p.id),
diff --git a/azalea-client/src/task_pool.rs b/azalea-client/src/task_pool.rs
index 2a3afbbc..59f70487 100644
--- a/azalea-client/src/task_pool.rs
+++ b/azalea-client/src/task_pool.rs
@@ -30,7 +30,7 @@ impl Plugin for TaskPoolPlugin {
}
/// Helper for configuring and creating the default task pools. For end-users
-/// who want full control, set up [`TaskPoolPlugin`](super::TaskPoolPlugin)
+/// who want full control, set up [`TaskPoolPlugin`](TaskPoolPlugin)
#[derive(Clone, Resource)]
pub struct TaskPoolOptions {
/// If the number of physical cores is less than min_total_threads, force