aboutsummaryrefslogtreecommitdiff
path: root/azalea-client/src
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-12-11 00:15:37 -0600
committermat <github@matdoes.dev>2022-12-11 00:15:37 -0600
commit37b9f10b3bcc74b48df2c6843a5286a7d41e2414 (patch)
tree6a995f7ad3f3309e57c276e10dc7e655dae9c5bb /azalea-client/src
parent2d6737b247b74e964fd734d5ab4828a3193c296f (diff)
downloadazalea-drasl-37b9f10b3bcc74b48df2c6843a5286a7d41e2414.tar.xz
make entities have a reference to WeakWorlds instead
... and other exciting bug fixes
Diffstat (limited to 'azalea-client/src')
-rwxr-xr-xazalea-client/src/chat.rs9
-rw-r--r--azalea-client/src/client.rs64
-rw-r--r--azalea-client/src/movement.rs13
-rwxr-xr-xazalea-client/src/player.rs4
4 files changed, 39 insertions, 51 deletions
diff --git a/azalea-client/src/chat.rs b/azalea-client/src/chat.rs
index 510bf043..fa88daf7 100755
--- a/azalea-client/src/chat.rs
+++ b/azalea-client/src/chat.rs
@@ -78,6 +78,15 @@ impl ChatPacket {
pub fn content(&self) -> String {
self.split_sender_and_content().1
}
+
+ /// Create a new ChatPacket from a string. This is meant to be used as a
+ /// convenience function for testing.
+ pub fn new(message: &str) -> Self {
+ ChatPacket::System(Arc::new(ClientboundSystemChatPacket {
+ content: Component::from(message),
+ overlay: false,
+ }))
+ }
}
impl Client {
diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs
index 3aad96c4..44c0f8cc 100644
--- a/azalea-client/src/client.rs
+++ b/azalea-client/src/client.rs
@@ -30,10 +30,10 @@ use azalea_protocol::{
};
use azalea_world::{
entity::{metadata, Entity, EntityData, EntityMetadata},
- WeakWorld, WeakWorldContainer, World,
+ PartialWorld, WeakWorld, WeakWorldContainer,
};
use log::{debug, error, info, trace, warn};
-use parking_lot::{Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard};
+use parking_lot::{Mutex, RwLock};
use std::{
any,
backtrace::Backtrace,
@@ -92,7 +92,7 @@ pub struct Client {
pub write_conn: Arc<tokio::sync::Mutex<WriteConnection<ServerboundGamePacket>>>,
pub entity_id: Arc<RwLock<u32>>,
/// The world that this client has access to. This supports shared worlds.
- pub world: Arc<RwLock<World>>,
+ pub world: Arc<RwLock<PartialWorld>>,
/// A container of world names to worlds. If we're not using a shared world
/// (i.e. not a swarm), then this will only contain data about the world
/// we're currently in.
@@ -180,7 +180,7 @@ impl Client {
write_conn,
// default our id to 0, it'll be set later
entity_id: Arc::new(RwLock::new(0)),
- world: Arc::new(RwLock::new(World::default())),
+ world: Arc::new(RwLock::new(PartialWorld::default())),
world_container: world_container
.unwrap_or_else(|| Arc::new(RwLock::new(WeakWorldContainer::new()))),
world_name: Arc::new(RwLock::new(None)),
@@ -509,16 +509,18 @@ impl Client {
.as_int()
.expect("min_y tag is not an int");
+ let world_name = p.dimension.clone();
+
+ *client.world_name.write() = Some(world_name.clone());
// add this world to the world_container (or don't if it's already there)
- let weak_world =
- client
- .world_container
- .write()
- .insert(p.dimension.clone(), height, min_y);
+ let weak_world = client
+ .world_container
+ .write()
+ .insert(world_name, height, min_y);
// set the loaded_world to an empty world
// (when we add chunks or entities those will be in the world_container)
let mut world_lock = client.world.write();
- *world_lock = World::new(
+ *world_lock = PartialWorld::new(
client.client_information.read().view_distance.into(),
weak_world,
p.player_id,
@@ -1011,7 +1013,7 @@ impl Client {
// return if there's no chunk at the player's position
{
- let world_lock = client.world.read();
+ let world_lock = client.world();
let player_entity_id = *client.entity_id.read();
let player_entity = world_lock.entity(player_entity_id);
let Some(player_entity) = player_entity else {
@@ -1037,46 +1039,24 @@ impl Client {
// TODO: minecraft does ambient sounds here
}
- /// Get a [`WeakWorld`] from our world container. If it's a normal client,
- /// then it'll be the same as the world the client has loaded. If the
- /// client using a shared world, then the shared world will be a superset
- /// of the client's world.
+ /// Get a reference to our (potentially shared) world.
///
- /// # Panics
- /// Panics if the client has not received the login packet yet. You can
- /// check this with [`Client::logged_in`].
+ /// This gets the [`WeakWorld`] from our world container. If it's a normal
+ /// client, then it'll be the same as the world the client has loaded.
+ /// 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<WeakWorld> {
- let world_name = self.world_name.read();
- let world_name = world_name
- .as_ref()
- .expect("Client has not received login packet yet");
- if let Some(world) = self.world_container.read().get(world_name) {
- world
- } else {
- unreachable!("The world name must be in the world container");
- }
+ self.world.read().shared.clone()
}
/// Returns the entity associated to the player.
- pub fn entity_mut(&self) -> Entity<RwLockWriteGuard<World>> {
- let entity_id = *self.entity_id.read();
-
- let world = self.world.write();
-
- let entity_data = world
- .entity_storage
- .get_by_id(entity_id)
- .expect("Player entity should exist");
- let entity_ptr = unsafe { entity_data.as_ptr() };
- Entity::new(world, entity_id, entity_ptr)
- }
- /// Returns the entity associated to the player.
- pub fn entity(&self) -> Entity<RwLockReadGuard<World>> {
+ pub fn entity(&self) -> Entity<Arc<WeakWorld>> {
let entity_id = *self.entity_id.read();
- let world = self.world.read();
+ let world = self.world();
let entity_data = world
.entity_storage
+ .read()
.get_by_id(entity_id)
.expect("Player entity should be in the given world");
let entity_ptr = unsafe { entity_data.as_ptr() };
diff --git a/azalea-client/src/movement.rs b/azalea-client/src/movement.rs
index 5a638883..d9cab1d4 100644
--- a/azalea-client/src/movement.rs
+++ b/azalea-client/src/movement.rs
@@ -107,7 +107,7 @@ impl Client {
};
drop(player_entity);
- let mut player_entity = self.entity_mut();
+ let mut player_entity = self.entity();
if sending_position {
player_entity.last_pos = *player_entity.pos();
@@ -192,7 +192,7 @@ impl Client {
// server ai step
{
- let mut player_entity = self.entity_mut();
+ let mut player_entity = self.entity();
let physics_state = self.physics_state.lock();
player_entity.xxa = physics_state.left_impulse;
@@ -222,7 +222,7 @@ impl Client {
self.set_sprinting(true);
}
- let mut player_entity = self.entity_mut();
+ let mut player_entity = self.entity();
player_entity.ai_step();
}
@@ -318,7 +318,7 @@ impl Client {
/// player. You should use the [`walk`] and [`sprint`] methods instead.
/// Returns if the operation was successful.
fn set_sprinting(&mut self, sprinting: bool) -> bool {
- let mut player_entity = self.entity_mut();
+ let mut player_entity = self.entity();
player_entity.metadata.sprinting = sprinting;
if sprinting {
player_entity
@@ -341,14 +341,13 @@ impl Client {
/// If you're making a realistic client, calling this function every tick is
/// recommended.
pub fn set_jumping(&mut self, jumping: bool) {
- let mut player_entity = self.entity_mut();
+ let mut player_entity = self.entity();
player_entity.jumping = jumping;
}
/// Returns whether the player will try to jump next tick.
pub fn jumping(&self) -> bool {
let player_entity = self.entity();
-
player_entity.jumping
}
@@ -357,7 +356,7 @@ impl Client {
/// f3 screen.
/// `y_rot` goes from -180 to 180, and `x_rot` goes from -90 to 90.
pub fn set_rotation(&mut self, y_rot: f32, x_rot: f32) {
- let mut player_entity = self.entity_mut();
+ let mut player_entity = self.entity();
player_entity.set_rotation(y_rot, x_rot);
}
diff --git a/azalea-client/src/player.rs b/azalea-client/src/player.rs
index 1b4f052b..650fb58c 100755
--- a/azalea-client/src/player.rs
+++ b/azalea-client/src/player.rs
@@ -1,12 +1,12 @@
use azalea_auth::game_profile::GameProfile;
use azalea_chat::Component;
use azalea_core::GameType;
-use azalea_world::World;
+use azalea_world::PartialWorld;
use uuid::Uuid;
/// Something that has a world associated to it. this is usually a `Client`.
pub trait WorldHaver {
- fn world(&self) -> &World;
+ fn world(&self) -> &PartialWorld;
}
/// A player in the tab list.