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