diff options
| author | mat <github@matdoes.dev> | 2022-12-11 00:15:37 -0600 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2022-12-11 00:15:37 -0600 |
| commit | 37b9f10b3bcc74b48df2c6843a5286a7d41e2414 (patch) | |
| tree | 6a995f7ad3f3309e57c276e10dc7e655dae9c5bb /azalea-client/src | |
| parent | 2d6737b247b74e964fd734d5ab4828a3193c296f (diff) | |
| download | azalea-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-x | azalea-client/src/chat.rs | 9 | ||||
| -rw-r--r-- | azalea-client/src/client.rs | 64 | ||||
| -rw-r--r-- | azalea-client/src/movement.rs | 13 | ||||
| -rwxr-xr-x | azalea-client/src/player.rs | 4 |
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. |
