From e5bfbce2ce484e0914e7b072bf3d219d9fa3c252 Mon Sep 17 00:00:00 2001 From: Snowiiii Date: Mon, 9 Sep 2024 23:22:55 +0200 Subject: [PATCH] Fix dead locks --- pumpkin-protocol/src/lib.rs | 2 +- pumpkin/src/client/mod.rs | 5 +- pumpkin/src/client/player_packet.rs | 134 +++++++++++++++------------- pumpkin/src/entity/mod.rs | 128 ++++++++++++++------------ pumpkin/src/entity/player.rs | 24 +++-- pumpkin/src/main.rs | 4 + pumpkin/src/world/mod.rs | 17 ++-- pumpkin/src/world/player_chunker.rs | 17 ++-- 8 files changed, 181 insertions(+), 150 deletions(-) diff --git a/pumpkin-protocol/src/lib.rs b/pumpkin-protocol/src/lib.rs index 66caee7e9..dfabd2e99 100644 --- a/pumpkin-protocol/src/lib.rs +++ b/pumpkin-protocol/src/lib.rs @@ -151,7 +151,7 @@ pub enum PacketError { MalformedLength, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Clone)] pub enum ConnectionState { HandShake, Status, diff --git a/pumpkin/src/client/mod.rs b/pumpkin/src/client/mod.rs index 53ca10189..19a89fc1f 100644 --- a/pumpkin/src/client/mod.rs +++ b/pumpkin/src/client/mod.rs @@ -182,7 +182,10 @@ impl Client { ) -> Result<(), DeserializerError> { // TODO: handle each packet's Error instead of calling .unwrap() let bytebuf = &mut packet.bytebuf; - match *self.connection_state.lock().unwrap() { + let locked_state = self.connection_state.lock().unwrap(); + let state = locked_state.clone(); + drop(locked_state); + match state { pumpkin_protocol::ConnectionState::HandShake => match packet.id.0 { SHandShake::PACKET_ID => { self.handle_handshake(server, SHandShake::read(bytebuf)?); diff --git a/pumpkin/src/client/player_packet.rs b/pumpkin/src/client/player_packet.rs index 04c7788f6..d2c2a2716 100644 --- a/pumpkin/src/client/player_packet.rs +++ b/pumpkin/src/client/player_packet.rs @@ -50,10 +50,7 @@ impl Player { if let Some((id, position)) = awaiting_teleport.as_ref() { if id == &confirm_teleport.teleport_id { // we should set the pos now to that we requested in the teleport packet, Is may fixed issues when the client sended position packets while being teleported - self.entity - .lock() - .unwrap() - .set_pos(position.x, position.y, position.z); + self.entity.set_pos(position.x, position.y, position.z); *awaiting_teleport = None; } else { @@ -79,18 +76,20 @@ impl Player { self.kick(TextComponent::text("Invalid movement")); return; } - let mut entity = self.entity.lock().unwrap(); - let mut last_position = self.last_position.lock().unwrap(); - *last_position = entity.pos; + let entity = &self.entity; entity.set_pos( Self::clamp_horizontal(position.x), Self::clamp_vertical(position.feet_y), Self::clamp_horizontal(position.z), ); - entity.on_ground = position.ground; - let on_ground = entity.on_ground; + let mut last_position = self.last_position.lock().unwrap(); + let pos = entity.pos.lock().unwrap(); + *last_position = *pos; + entity + .on_ground + .store(position.ground, std::sync::atomic::Ordering::Relaxed); let entity_id = entity.entity_id; - let (x, y, z) = entity.pos.into(); + let (x, y, z) = (*pos).into(); let (lastx, lasty, lastz) = (last_position.x, last_position.y, last_position.z); let world = entity.world.clone(); @@ -114,10 +113,10 @@ impl Player { (x * 4096.0 - lastx * 4096.0) as i16, (y * 4096.0 - lasty * 4096.0) as i16, (z * 4096.0 - lastz * 4096.0) as i16, - on_ground, + position.ground, ), ); - player_chunker::update_position(&world, self).await; + player_chunker::update_position(entity, self).await; } pub async fn handle_position_rotation( @@ -136,27 +135,31 @@ impl Player { self.kick(TextComponent::text("Invalid rotation")); return; } - let mut entity = self.entity.lock().unwrap(); + let entity = &self.entity; - let mut last_position = self.last_position.lock().unwrap(); - *last_position = entity.pos; entity.set_pos( Self::clamp_horizontal(position_rotation.x), Self::clamp_vertical(position_rotation.feet_y), Self::clamp_horizontal(position_rotation.z), ); - entity.on_ground = position_rotation.ground; - entity.yaw = wrap_degrees(position_rotation.yaw) % 360.0; - entity.pitch = wrap_degrees(position_rotation.pitch).clamp(-90.0, 90.0) % 360.0; + let mut last_position = self.last_position.lock().unwrap(); + let pos = entity.pos.lock().unwrap(); + *last_position = *pos; + entity.on_ground.store( + position_rotation.ground, + std::sync::atomic::Ordering::Relaxed, + ); + entity.set_rotation( + wrap_degrees(position_rotation.yaw) % 360.0, + wrap_degrees(position_rotation.pitch).clamp(-90.0, 90.0) % 360.0, + ); - let on_ground = entity.on_ground; let entity_id = entity.entity_id; - let (x, y, z) = entity.pos.into(); + let (x, y, z) = (*pos).into(); let (lastx, lasty, lastz) = (last_position.x, last_position.y, last_position.z); - let yaw = modulus(entity.yaw * 256.0 / 360.0, 256.0); - let pitch = modulus(entity.pitch * 256.0 / 360.0, 256.0); + let yaw = modulus(*entity.yaw.lock().unwrap() * 256.0 / 360.0, 256.0); + let pitch = modulus(*entity.pitch.lock().unwrap() * 256.0 / 360.0, 256.0); // let head_yaw = (entity.head_yaw * 256.0 / 360.0).floor(); - let entity = self.entity.lock().unwrap(); let world = &entity.world; // let delta = Vector3::new(x - lastx, y - lasty, z - lastz); @@ -182,15 +185,14 @@ impl Player { (z * 4096.0 - lastz * 4096.0) as i16, yaw as u8, pitch as u8, - on_ground, + position_rotation.ground, ), ); world.broadcast_packet_expect( &[self.client.token], &CHeadRot::new(entity_id.into(), yaw as u8), ); - - player_chunker::update_position(world, self).await; + player_chunker::update_position(entity, self).await; } pub async fn handle_rotation(&self, _server: &Arc, rotation: SPlayerRotation) { @@ -198,19 +200,23 @@ impl Player { self.kick(TextComponent::text("Invalid rotation")); return; } - let mut entity = self.entity.lock().unwrap(); - entity.on_ground = rotation.ground; - entity.yaw = wrap_degrees(rotation.yaw) % 360.0; - entity.pitch = wrap_degrees(rotation.pitch).clamp(-90.0, 90.0) % 360.0; + let entity = &self.entity; + entity + .on_ground + .store(rotation.ground, std::sync::atomic::Ordering::Relaxed); + entity.set_rotation( + wrap_degrees(rotation.yaw) % 360.0, + wrap_degrees(rotation.pitch).clamp(-90.0, 90.0) % 360.0, + ); // send new position to all other players - let on_ground = entity.on_ground; let entity_id = entity.entity_id; - let yaw = modulus(entity.yaw * 256.0 / 360.0, 256.0); - let pitch = modulus(entity.pitch * 256.0 / 360.0, 256.0); + let yaw = modulus(*entity.yaw.lock().unwrap() * 256.0 / 360.0, 256.0); + let pitch = modulus(*entity.pitch.lock().unwrap() * 256.0 / 360.0, 256.0); // let head_yaw = modulus(entity.head_yaw * 256.0 / 360.0, 256.0); let world = &entity.world; - let packet = CUpdateEntityRot::new(entity_id.into(), yaw as u8, pitch as u8, on_ground); + let packet = + CUpdateEntityRot::new(entity_id.into(), yaw as u8, pitch as u8, rotation.ground); world.broadcast_packet_expect(&[self.client.token], &packet); let packet = CHeadRot::new(entity_id.into(), yaw as u8); world.broadcast_packet_expect(&[self.client.token], &packet); @@ -222,7 +228,9 @@ impl Player { } pub fn handle_player_ground(&self, _server: &Arc, ground: SSetPlayerGround) { - self.entity.lock().unwrap().on_ground = ground.on_ground; + self.entity + .on_ground + .store(ground.on_ground, std::sync::atomic::Ordering::Relaxed); } pub async fn handle_player_command(&self, _server: &Arc, command: SPlayerCommand) { @@ -231,26 +239,26 @@ impl Player { } if let Some(action) = Action::from_i32(command.action.0) { - let mut entity = self.entity.lock().unwrap(); + let entity = &self.entity; match action { pumpkin_protocol::server::play::Action::StartSneaking => { - if !entity.sneaking { + if !entity.sneaking.load(std::sync::atomic::Ordering::Relaxed) { entity.set_sneaking(true).await } } pumpkin_protocol::server::play::Action::StopSneaking => { - if entity.sneaking { + if entity.sneaking.load(std::sync::atomic::Ordering::Relaxed) { entity.set_sneaking(false).await } } pumpkin_protocol::server::play::Action::LeaveBed => todo!(), pumpkin_protocol::server::play::Action::StartSprinting => { - if !entity.sprinting { + if !entity.sprinting.load(std::sync::atomic::Ordering::Relaxed) { entity.set_sprinting(true).await } } pumpkin_protocol::server::play::Action::StopSprinting => { - if entity.sprinting { + if entity.sprinting.load(std::sync::atomic::Ordering::Relaxed) { entity.set_sprinting(false).await } } @@ -259,7 +267,11 @@ impl Player { pumpkin_protocol::server::play::Action::OpenVehicleInventory => todo!(), pumpkin_protocol::server::play::Action::StartFlyingElytra => { let fall_flying = entity.check_fall_flying(); - if entity.fall_flying != fall_flying { + if entity + .fall_flying + .load(std::sync::atomic::Ordering::Relaxed) + != fall_flying + { entity.set_fall_flying(fall_flying).await; } } // TODO @@ -277,8 +289,7 @@ impl Player { Hand::Off => Animation::SwingOffhand, }; let id = self.entity_id(); - let entity = self.entity.lock().unwrap(); - let world = &entity.world; + let world = &self.entity.world; world.broadcast_packet_expect( &[self.client.token], &CEntityAnimation::new(id.into(), animation as u8), @@ -302,7 +313,7 @@ impl Player { // TODO: filter message & validation let gameprofile = &self.gameprofile; - let entity = self.entity.lock().unwrap(); + let entity = &self.entity; let world = &entity.world; world.broadcast_packet_all(&CPlayerChatMessage::new( pumpkin_protocol::uuid::UUID(gameprofile.id), @@ -356,8 +367,8 @@ impl Player { pub async fn handle_interact(&self, _: &Arc, interact: SInteract) { let sneaking = interact.sneaking; - let mut entity = self.entity.lock().unwrap(); - if entity.sneaking != sneaking { + let entity = &self.entity; + if entity.sneaking.load(std::sync::atomic::Ordering::Relaxed) != sneaking { entity.set_sneaking(sneaking).await; } match ActionType::from_i32(interact.typ.0) { @@ -370,35 +381,38 @@ impl Player { let world = entity.world.clone(); let attacked_player = world.get_by_entityid(self, entity_id.0 as EntityId); if let Some(player) = attacked_player { - let mut victem_entity = player.entity.lock().unwrap(); - let velo = victem_entity.velocity; + let victem_entity = &player.entity; if config.protect_creative && *player.gamemode.lock().unwrap() == GameMode::Creative { return; } if config.knockback { - let yaw = entity.yaw; + let yaw = entity.yaw.lock().unwrap(); let strength = 1.0; + let mut victem_velocity = victem_entity.velocity.lock().unwrap(); + let saved_velo = *victem_velocity; victem_entity.knockback( strength * 0.5, - (yaw * (PI / 180.0)).sin() as f64, - -(yaw * (PI / 180.0)).cos() as f64, + (*yaw * (PI / 180.0)).sin() as f64, + -(*yaw * (PI / 180.0)).cos() as f64, ); let packet = &CEntityVelocity::new( &entity_id, - velo.x as f32, - velo.y as f32, - velo.z as f32, + victem_velocity.x as f32, + victem_velocity.y as f32, + victem_velocity.z as f32, ); - entity.velocity = entity.velocity.multiply(0.6, 1.0, 0.6); + let mut velocity = entity.velocity.lock().unwrap(); + *velocity = velocity.multiply(0.6, 1.0, 0.6); - victem_entity.velocity = velo; + *victem_velocity = saved_velo; player.client.send_packet(packet); } if config.hurt_animation { world.broadcast_packet_all(&CHurtAnimation::new( - &entity_id, entity.yaw, + &entity_id, + *entity.yaw.lock().unwrap(), )) } if config.swing {} @@ -431,7 +445,7 @@ impl Player { let location = player_action.location; // Block break & block break sound // TODO: currently this is always dirt replace it - let entity = self.entity.lock().unwrap(); + let entity = &self.entity; let world = &entity.world; world.broadcast_packet_all(&CWorldEvent::new(2001, &location, 11, false)); // AIR @@ -455,7 +469,7 @@ impl Player { } // Block break & block break sound // TODO: currently this is always dirt replace it - let entity = self.entity.lock().unwrap(); + let entity = &self.entity; let world = &entity.world; world.broadcast_packet_all(&CWorldEvent::new(2001, &location, 11, false)); // AIR @@ -502,7 +516,7 @@ impl Player { ) .expect("All item ids are in the global registry"); if let Ok(block_state_id) = BlockId::new(minecraft_id, None) { - let entity = self.entity.lock().unwrap(); + let entity = &self.entity; let world = &entity.world; world.broadcast_packet_all(&CBlockUpdate::new( &location, diff --git a/pumpkin/src/entity/mod.rs b/pumpkin/src/entity/mod.rs index a8f03821d..132dfedf0 100644 --- a/pumpkin/src/entity/mod.rs +++ b/pumpkin/src/entity/mod.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::sync::{atomic::AtomicBool, Arc, Mutex}; use pumpkin_core::math::{ get_section_cord, position::WorldPosition, vector2::Vector2, vector3::Vector3, @@ -18,24 +18,24 @@ pub struct Entity { pub entity_type: EntityType, pub world: Arc, - pub pos: Vector3, - pub block_pos: WorldPosition, - pub chunk_pos: Vector2, + pub pos: Mutex>, + pub block_pos: Mutex, + pub chunk_pos: Mutex>, - pub sneaking: bool, - pub sprinting: bool, - pub fall_flying: bool, - pub velocity: Vector3, + pub sneaking: AtomicBool, + pub sprinting: AtomicBool, + pub fall_flying: AtomicBool, + pub velocity: Mutex>, // Should be not trusted - pub on_ground: bool, + pub on_ground: AtomicBool, - pub yaw: f32, - pub head_yaw: f32, - pub pitch: f32, + pub yaw: Mutex, + pub head_yaw: Mutex, + pub pitch: Mutex, // TODO: Change this in diffrent poses pub standing_eye_height: f32, - pub pose: EntityPose, + pub pose: Mutex, } impl Entity { @@ -48,49 +48,58 @@ impl Entity { Self { entity_id, entity_type, - on_ground: false, - pos: Vector3::new(0.0, 0.0, 0.0), - block_pos: WorldPosition(Vector3::new(0, 0, 0)), - chunk_pos: Vector2::new(0, 0), - sneaking: false, + on_ground: AtomicBool::new(false), + pos: Mutex::new(Vector3::new(0.0, 0.0, 0.0)), + block_pos: Mutex::new(WorldPosition(Vector3::new(0, 0, 0))), + chunk_pos: Mutex::new(Vector2::new(0, 0)), + sneaking: AtomicBool::new(false), world, - sprinting: false, - fall_flying: false, - yaw: 0.0, - head_yaw: 0.0, - pitch: 0.0, - velocity: Vector3::new(0.0, 0.0, 0.0), + sprinting: AtomicBool::new(false), + fall_flying: AtomicBool::new(false), + yaw: Mutex::new(0.0), + head_yaw: Mutex::new(0.0), + pitch: Mutex::new(0.0), + velocity: Mutex::new(Vector3::new(0.0, 0.0, 0.0)), standing_eye_height, - pose: EntityPose::Standing, + pose: Mutex::new(EntityPose::Standing), } } - pub fn set_pos(&mut self, x: f64, y: f64, z: f64) { - if self.pos.x != x || self.pos.y != y || self.pos.z != z { - self.pos = Vector3::new(x, y, z); + pub fn set_pos(&self, x: f64, y: f64, z: f64) { + let mut pos = self.pos.lock().unwrap(); + if pos.x != x || pos.y != y || pos.z != z { + *pos = Vector3::new(x, y, z); let i = x.floor() as i32; let j = y.floor() as i32; let k = z.floor() as i32; - let block_pos = self.block_pos.0; - if i != block_pos.x || j != block_pos.y || k != block_pos.z { - self.block_pos = WorldPosition(Vector3::new(i, j, k)); + let mut block_pos = self.block_pos.lock().unwrap(); + let block_pos_vec = block_pos.0; + if i != block_pos_vec.x || j != block_pos_vec.y || k != block_pos_vec.z { + *block_pos = WorldPosition(Vector3::new(i, j, k)); - if get_section_cord(i) != self.chunk_pos.x - || get_section_cord(k) != self.chunk_pos.z - { - self.chunk_pos = - Vector2::new(get_section_cord(block_pos.x), get_section_cord(block_pos.z)); + let mut chunk_pos = self.chunk_pos.lock().unwrap(); + if get_section_cord(i) != chunk_pos.x || get_section_cord(k) != chunk_pos.z { + *chunk_pos = Vector2::new( + get_section_cord(block_pos_vec.x), + get_section_cord(block_pos_vec.z), + ); } } } } + pub fn set_rotation(&self, yaw: f32, pitch: f32) { + // TODO + *self.yaw.lock().unwrap() = yaw; + *self.pitch.lock().unwrap() = pitch + } + pub async fn remove(&mut self) { self.world.remove_entity(self); } - pub fn knockback(&mut self, strength: f64, x: f64, z: f64) { + pub fn knockback(&self, strength: f64, x: f64, z: f64) { // This has some vanilla magic let mut x = x; let mut z = z; @@ -100,21 +109,22 @@ impl Entity { } let var8 = Vector3::new(x, 0.0, z).normalize() * strength; - let var7 = self.velocity; - self.velocity = Vector3::new( - var7.x / 2.0 - var8.x, - if self.on_ground { - (var7.y / 2.0 + strength).min(0.4) + let mut velocity = self.velocity.lock().unwrap(); + *velocity = Vector3::new( + velocity.x / 2.0 - var8.x, + if self.on_ground.load(std::sync::atomic::Ordering::Relaxed) { + (velocity.y / 2.0 + strength).min(0.4) } else { - var7.y + velocity.y }, - var7.z / 2.0 - var8.z, + velocity.z / 2.0 - var8.z, ); } - pub async fn set_sneaking(&mut self, sneaking: bool) { - assert!(self.sneaking != sneaking); - self.sneaking = sneaking; + pub async fn set_sneaking(&self, sneaking: bool) { + assert!(self.sneaking.load(std::sync::atomic::Ordering::Relaxed) != sneaking); + self.sneaking + .store(sneaking, std::sync::atomic::Ordering::Relaxed); self.set_flag(Self::SNEAKING_FLAG_INDEX, sneaking).await; // if sneaking { // self.set_pose(EntityPose::Crouching).await; @@ -123,19 +133,21 @@ impl Entity { // } } - pub async fn set_sprinting(&mut self, sprinting: bool) { - assert!(self.sprinting != sprinting); - self.sprinting = sprinting; + pub async fn set_sprinting(&self, sprinting: bool) { + assert!(self.sprinting.load(std::sync::atomic::Ordering::Relaxed) != sprinting); + self.sprinting + .store(sprinting, std::sync::atomic::Ordering::Relaxed); self.set_flag(Self::SPRINTING_FLAG_INDEX, sprinting).await; } pub fn check_fall_flying(&self) -> bool { - !self.on_ground + !self.on_ground.load(std::sync::atomic::Ordering::Relaxed) } - pub async fn set_fall_flying(&mut self, fall_flying: bool) { - assert!(self.fall_flying != fall_flying); - self.fall_flying = fall_flying; + pub async fn set_fall_flying(&self, fall_flying: bool) { + assert!(self.fall_flying.load(std::sync::atomic::Ordering::Relaxed) != fall_flying); + self.fall_flying + .store(fall_flying, std::sync::atomic::Ordering::Relaxed); self.set_flag(Self::FALL_FLYING_FLAG_INDEX, fall_flying) .await; } @@ -147,7 +159,7 @@ impl Entity { pub const INVISIBLE_FLAG_INDEX: u32 = 5; pub const GLOWING_FLAG_INDEX: u32 = 6; pub const FALL_FLYING_FLAG_INDEX: u32 = 7; - async fn set_flag(&mut self, index: u32, value: bool) { + async fn set_flag(&self, index: u32, value: bool) { let mut b = 0i8; if value { b |= 1 << index; @@ -158,9 +170,9 @@ impl Entity { self.world.broadcast_packet_all(&packet); } - pub async fn set_pose(&mut self, pose: EntityPose) { - self.pose = pose; - let pose = self.pose as i32; + pub async fn set_pose(&self, pose: EntityPose) { + *self.pose.lock().unwrap() = pose; + let pose = pose as i32; let packet = CSetEntityMetadata::::new( self.entity_id.into(), Metadata::new(6, 20.into(), (pose).into()), diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index ed2e78b59..67ed05e8f 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -61,7 +61,7 @@ impl Default for PlayerAbilities { } pub struct Player { - pub entity: Mutex, + pub entity: Entity, pub gameprofile: GameProfile, pub client: Client, @@ -106,7 +106,7 @@ impl Player { }; let config = client.config.lock().unwrap().clone().unwrap_or_default(); Self { - entity: Mutex::new(Entity::new(entity_id, world, EntityType::Player, 1.62)), + entity: Entity::new(entity_id, world, EntityType::Player, 1.62), config: Mutex::new(config), gameprofile, client, @@ -129,11 +129,11 @@ impl Player { /// Removes the Player out of the current World pub async fn remove(&self) { - self.entity.lock().unwrap().world.remove_player(self); + self.entity.world.remove_player(self); } pub fn entity_id(&self) -> EntityId { - self.entity.lock().unwrap().entity_id + self.entity.entity_id } pub fn send_abilties_update(&mut self) { @@ -170,10 +170,9 @@ impl Player { .store(0, std::sync::atomic::Ordering::Relaxed); } let teleport_id = i + 1; - let mut entity = self.entity.lock().unwrap(); + let entity = &self.entity; entity.set_pos(x, y, z); - entity.yaw = yaw; - entity.pitch = pitch; + entity.set_rotation(yaw, pitch); *self.awaiting_teleport.lock().unwrap() = Some((teleport_id.into(), Vector3::new(x, y, z))); self.client.send_packet(&CSyncPlayerPosition::new( x, @@ -197,11 +196,12 @@ impl Player { pub fn can_interact_with_block_at(&self, pos: &WorldPosition, additional_range: f64) -> bool { let d = self.block_interaction_range() + additional_range; let box_pos = BoundingBox::from_block(pos); - let entity = self.entity.lock().unwrap(); + let entity_pos = self.entity.pos.lock().unwrap(); + let standing_eye_height = self.entity.standing_eye_height; box_pos.squared_magnitude(Vector3 { - x: entity.pos.x, - y: entity.pos.y + entity.standing_eye_height as f64, - z: entity.pos.z, + x: entity_pos.x, + y: entity_pos.y + standing_eye_height as f64, + z: entity_pos.z, }) < d * d } @@ -241,8 +241,6 @@ impl Player { // So a little story time. I actually made an abitlties_from_gamemode function. I looked at vanilla and they always send the abilties from the gamemode. But the funny thing actually is. That the client // does actually use the same method and set the abilties when receiving the CGameEvent gamemode packet. Just Mojang nonsense self.entity - .lock() - .unwrap() .world .broadcast_packet_all(&CPlayerInfoUpdate::new( 0x04, diff --git a/pumpkin/src/main.rs b/pumpkin/src/main.rs index f90f5b041..8a00ebbb4 100644 --- a/pumpkin/src/main.rs +++ b/pumpkin/src/main.rs @@ -169,8 +169,12 @@ fn main() -> io::Result<()> { } if closed { if let Some(player) = players.remove(&token) { + dbg!("a"); player.remove().await; + dbg!("b"); let connection = &mut player.client.connection.lock().unwrap(); + dbg!("c"); + poll.registry().deregister(connection.by_ref())?; } } diff --git a/pumpkin/src/world/mod.rs b/pumpkin/src/world/mod.rs index 672e37136..253fa27b4 100644 --- a/pumpkin/src/world/mod.rs +++ b/pumpkin/src/world/mod.rs @@ -177,18 +177,19 @@ impl World { .iter() .filter(|c| c.0 != &token) { - let entity = existing_player.entity.lock().unwrap(); + let entity = &existing_player.entity; + let pos = entity.pos.lock().unwrap(); let gameprofile = &existing_player.gameprofile; player.client.send_packet(&CSpawnEntity::new( existing_player.entity_id().into(), UUID(gameprofile.id), (EntityType::Player as i32).into(), - entity.pos.x, - entity.pos.y, - entity.pos.z, - entity.yaw, - entity.pitch, - entity.head_yaw, + pos.x, + pos.y, + pos.z, + *entity.yaw.lock().unwrap(), + *entity.pitch.lock().unwrap(), + *entity.head_yaw.lock().unwrap(), 0.into(), 0.0, 0.0, @@ -279,7 +280,7 @@ impl World { &[player.client.token], &CRemovePlayerInfo::new(1.into(), &[UUID(uuid)]), ); - self.remove_entity(&player.entity.lock().unwrap()); + self.remove_entity(&player.entity); } pub fn remove_entity(&self, entity: &Entity) { diff --git a/pumpkin/src/world/player_chunker.rs b/pumpkin/src/world/player_chunker.rs index 6c91e3508..0a8464883 100644 --- a/pumpkin/src/world/player_chunker.rs +++ b/pumpkin/src/world/player_chunker.rs @@ -7,7 +7,7 @@ use pumpkin_core::math::{ use pumpkin_protocol::client::play::{CCenterChunk, CUnloadChunk}; use pumpkin_world::cylindrical_chunk_iterator::Cylindrical; -use crate::entity::player::Player; +use crate::entity::{player::Player, Entity}; use super::World; @@ -21,11 +21,10 @@ fn get_view_distance(player: &Player) -> i8 { } pub async fn player_join(world: &World, player: Arc) { - let entity = player.entity.lock().unwrap(); - let new_watched = chunk_section_from_pos(&entity.block_pos); + let new_watched = chunk_section_from_pos(&player.entity.block_pos.lock().unwrap()); let mut watched_section = player.watched_section.lock().unwrap(); *watched_section = new_watched; - let chunk_pos = entity.chunk_pos; + let chunk_pos = player.entity.chunk_pos.lock().unwrap(); player.client.send_packet(&CCenterChunk { chunk_x: chunk_pos.x.into(), chunk_z: chunk_pos.z.into(), @@ -58,12 +57,11 @@ pub async fn player_join(world: &World, player: Arc) { } } -pub async fn update_position(world: &World, player: &Player) { +pub async fn update_position(entity: &Entity, player: &Player) { let mut current_watched = player.watched_section.lock().unwrap(); - let entity = player.entity.lock().unwrap(); - let new_watched = chunk_section_from_pos(&entity.block_pos); + let new_watched = chunk_section_from_pos(&entity.block_pos.lock().unwrap()); if *current_watched != new_watched { - let chunk_pos = entity.chunk_pos; + let chunk_pos = entity.chunk_pos.lock().unwrap(); player.client.send_packet(&CCenterChunk { chunk_x: chunk_pos.x.into(), chunk_z: chunk_pos.z.into(), @@ -92,7 +90,8 @@ pub async fn update_position(world: &World, player: &Player) { false, ); if !loading_chunks.is_empty() { - world + entity + .world .spawn_world_chunks(&player.client, loading_chunks, view_distance) .await; }