Move world into entity

Also fixes most of error when leaving while chunks are loading
This commit is contained in:
Snowiiii 2024-09-07 22:39:42 +02:00
parent 0d6f7b49ab
commit 39b4cb3ac9
7 changed files with 75 additions and 100 deletions

View File

@ -60,6 +60,7 @@ and customizable experience. It prioritizes performance and player enjoyment whi
- [x] Player Inventory - [x] Player Inventory
- [x] Player Combat - [x] Player Combat
- Server - Server
- [x] Plugins
- [ ] Query - [ ] Query
- [x] RCON - [x] RCON
- [x] Inventories - [x] Inventories

View File

@ -149,12 +149,13 @@ impl Level {
) { ) {
chunks.into_par_iter().for_each(|at| { chunks.into_par_iter().for_each(|at| {
if is_alive { if is_alive {
dbg!("a");
return; return;
} }
if let Ok(mut loaded_chunks) = self.loaded_chunks.lock() {
let channel = channel.clone(); let channel = channel.clone();
// Check if chunks is already loaded // Check if chunks is already loaded
let mut loaded_chunks = self.loaded_chunks.lock().unwrap();
if loaded_chunks.contains_key(at) { if loaded_chunks.contains_key(at) {
channel channel
.blocking_send(Ok(loaded_chunks.get(at).unwrap().clone())) .blocking_send(Ok(loaded_chunks.get(at).unwrap().clone()))
@ -184,6 +185,7 @@ impl Level {
.blocking_send(Ok(data.clone())) .blocking_send(Ok(data.clone()))
.expect("Failed sending ChunkData."); .expect("Failed sending ChunkData.");
loaded_chunks.insert(at, data); loaded_chunks.insert(at, data);
}
}) })
} }

View File

@ -127,6 +127,8 @@ impl Client {
/// Send a Clientbound Packet to the Client /// Send a Clientbound Packet to the Client
pub fn send_packet<P: ClientPacket>(&mut self, packet: &P) { pub fn send_packet<P: ClientPacket>(&mut self, packet: &P) {
// assert!(!self.closed);
self.enc self.enc
.append_packet(packet) .append_packet(packet)
.unwrap_or_else(|e| self.kick(&e.to_string())); .unwrap_or_else(|e| self.kick(&e.to_string()));
@ -137,6 +139,8 @@ impl Client {
} }
pub fn try_send_packet<P: ClientPacket>(&mut self, packet: &P) -> Result<(), PacketError> { pub fn try_send_packet<P: ClientPacket>(&mut self, packet: &P) -> Result<(), PacketError> {
// assert!(!self.closed);
self.enc.append_packet(packet)?; self.enc.append_packet(packet)?;
self.connection self.connection
.write_all(&self.enc.take()) .write_all(&self.enc.take())

View File

@ -87,7 +87,7 @@ impl Player {
let entity_id = entity.entity_id; let entity_id = entity.entity_id;
let (x, y, z) = entity.pos.into(); let (x, y, z) = entity.pos.into();
let (lastx, lasty, lastz) = self.last_position.into(); let (lastx, lasty, lastz) = self.last_position.into();
let world = self.world.clone(); let world = self.entity.world.clone();
let world = world.lock().await; let world = world.lock().await;
// let delta = Vector3::new(x - lastx, y - lasty, z - lastz); // let delta = Vector3::new(x - lastx, y - lasty, z - lastz);
@ -151,7 +151,7 @@ impl Player {
let yaw = modulus(entity.yaw * 256.0 / 360.0, 256.0); let yaw = modulus(entity.yaw * 256.0 / 360.0, 256.0);
let pitch = modulus(entity.pitch * 256.0 / 360.0, 256.0); let pitch = modulus(entity.pitch * 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 world = self.world.clone(); let world = self.entity.world.clone();
let world = world.lock().await; let world = world.lock().await;
// let delta = Vector3::new(x - lastx, y - lasty, z - lastz); // let delta = Vector3::new(x - lastx, y - lasty, z - lastz);
@ -204,7 +204,7 @@ impl Player {
let pitch = modulus(entity.pitch * 256.0 / 360.0, 256.0); let pitch = modulus(entity.pitch * 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 = self.world.lock().await; let world = self.entity.world.lock().await;
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, on_ground);
// self.client.send_packet(&packet); // self.client.send_packet(&packet);
world.broadcast_packet(&[self.client.token], &packet); world.broadcast_packet(&[self.client.token], &packet);
@ -231,31 +231,23 @@ impl Player {
match action { match action {
pumpkin_protocol::server::play::Action::StartSneaking => { pumpkin_protocol::server::play::Action::StartSneaking => {
if !self.entity.sneaking { if !self.entity.sneaking {
self.entity self.entity.set_sneaking(&mut self.client, true).await
.set_sneaking(&mut self.client, self.world.clone(), true)
.await
} }
} }
pumpkin_protocol::server::play::Action::StopSneaking => { pumpkin_protocol::server::play::Action::StopSneaking => {
if self.entity.sneaking { if self.entity.sneaking {
self.entity self.entity.set_sneaking(&mut self.client, false).await
.set_sneaking(&mut self.client, self.world.clone(), 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 !self.entity.sprinting { if !self.entity.sprinting {
self.entity self.entity.set_sprinting(&mut self.client, true).await
.set_sprinting(&mut self.client, self.world.clone(), true)
.await
} }
} }
pumpkin_protocol::server::play::Action::StopSprinting => { pumpkin_protocol::server::play::Action::StopSprinting => {
if self.entity.sprinting { if self.entity.sprinting {
self.entity self.entity.set_sprinting(&mut self.client, false).await
.set_sprinting(&mut self.client, self.world.clone(), false)
.await
} }
} }
pumpkin_protocol::server::play::Action::StartHorseJump => todo!(), pumpkin_protocol::server::play::Action::StartHorseJump => todo!(),
@ -265,7 +257,7 @@ impl Player {
let fall_flying = self.entity.check_fall_flying(); let fall_flying = self.entity.check_fall_flying();
if self.entity.fall_flying != fall_flying { if self.entity.fall_flying != fall_flying {
self.entity self.entity
.set_fall_flying(&mut self.client, self.world.clone(), fall_flying) .set_fall_flying(&mut self.client, fall_flying)
.await; .await;
} }
} // TODO } // TODO
@ -283,7 +275,7 @@ impl Player {
Hand::Off => Animation::SwingOffhand, Hand::Off => Animation::SwingOffhand,
}; };
let id = self.entity_id(); let id = self.entity_id();
let world = self.world.lock().await; let world = self.entity.world.lock().await;
world.broadcast_packet( world.broadcast_packet(
&[self.client.token], &[self.client.token],
&CEntityAnimation::new(id.into(), animation as u8), &CEntityAnimation::new(id.into(), animation as u8),
@ -307,7 +299,7 @@ impl Player {
// TODO: filter message & validation // TODO: filter message & validation
let gameprofile = &self.gameprofile; let gameprofile = &self.gameprofile;
let world = self.world.lock().await; let world = self.entity.world.lock().await;
world.broadcast_packet( world.broadcast_packet(
&[self.client.token], &[self.client.token],
&CPlayerChatMessage::new( &CPlayerChatMessage::new(
@ -364,9 +356,7 @@ impl Player {
pub async fn handle_interact(&mut self, _: &mut Server, interact: SInteract) { pub async fn handle_interact(&mut self, _: &mut Server, interact: SInteract) {
let sneaking = interact.sneaking; let sneaking = interact.sneaking;
if self.entity.sneaking != sneaking { if self.entity.sneaking != sneaking {
self.entity self.entity.set_sneaking(&mut self.client, sneaking).await;
.set_sneaking(&mut self.client, self.world.clone(), sneaking)
.await;
} }
match ActionType::from_i32(interact.typ.0) { match ActionType::from_i32(interact.typ.0) {
Some(action) => match action { Some(action) => match action {
@ -375,7 +365,7 @@ impl Player {
// TODO: do validation and stuff // TODO: do validation and stuff
let config = &ADVANCED_CONFIG.pvp; let config = &ADVANCED_CONFIG.pvp;
if config.enabled { if config.enabled {
let world = self.world.clone(); let world = self.entity.world.clone();
let world = world.lock().await; let world = world.lock().await;
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(mut player) = attacked_player { if let Some(mut player) = attacked_player {
@ -448,7 +438,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 world = self.world.lock().await; let world = self.entity.world.lock().await;
world.broadcast_packet( world.broadcast_packet(
&[self.client.token], &[self.client.token],
&CWorldEvent::new(2001, &location, 11, false), &CWorldEvent::new(2001, &location, 11, false),
@ -476,7 +466,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 world = self.world.lock().await; let world = self.entity.world.lock().await;
world.broadcast_packet( world.broadcast_packet(
&[self.client.token], &[self.client.token],
&CWorldEvent::new(2001, &location, 11, false), &CWorldEvent::new(2001, &location, 11, false),
@ -528,7 +518,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 world = self.world.lock().await; let world = self.entity.world.lock().await;
world.broadcast_packet( world.broadcast_packet(
&[self.client.token], &[self.client.token],
&CBlockUpdate::new(&location, block_state_id.get_id_mojang_repr().into()), &CBlockUpdate::new(&location, block_state_id.get_id_mojang_repr().into()),

View File

@ -16,6 +16,8 @@ pub mod player;
pub struct Entity { pub struct Entity {
pub entity_id: EntityId, pub entity_id: EntityId,
pub entity_type: EntityType, pub entity_type: EntityType,
pub world: Arc<tokio::sync::Mutex<World>>,
pub pos: Vector3<f64>, pub pos: Vector3<f64>,
pub block_pos: WorldPosition, pub block_pos: WorldPosition,
pub chunk_pos: Vector2<i32>, pub chunk_pos: Vector2<i32>,
@ -38,7 +40,12 @@ pub struct Entity {
// TODO: Remove client: &mut Client, world: Arc<tokio::sync::Mutex<World>> bs // TODO: Remove client: &mut Client, world: Arc<tokio::sync::Mutex<World>> bs
impl Entity { impl Entity {
pub fn new(entity_id: EntityId, entity_type: EntityType, standing_eye_height: f32) -> Self { pub fn new(
entity_id: EntityId,
world: Arc<tokio::sync::Mutex<World>>,
entity_type: EntityType,
standing_eye_height: f32,
) -> Self {
Self { Self {
entity_id, entity_id,
entity_type, entity_type,
@ -47,6 +54,7 @@ impl Entity {
block_pos: WorldPosition(Vector3::new(0, 0, 0)), block_pos: WorldPosition(Vector3::new(0, 0, 0)),
chunk_pos: Vector2::new(0, 0), chunk_pos: Vector2::new(0, 0),
sneaking: false, sneaking: false,
world,
sprinting: false, sprinting: false,
fall_flying: false, fall_flying: false,
yaw: 0.0, yaw: 0.0,
@ -101,15 +109,10 @@ impl Entity {
); );
} }
pub async fn set_sneaking( pub async fn set_sneaking(&mut self, client: &mut Client, sneaking: bool) {
&mut self,
client: &mut Client,
world: Arc<tokio::sync::Mutex<World>>,
sneaking: bool,
) {
assert!(self.sneaking != sneaking); assert!(self.sneaking != sneaking);
self.sneaking = sneaking; self.sneaking = sneaking;
self.set_flag(client, world, Self::SNEAKING_FLAG_INDEX, sneaking) self.set_flag(client, Self::SNEAKING_FLAG_INDEX, sneaking)
.await; .await;
// if sneaking { // if sneaking {
// self.set_pose(EntityPose::Crouching).await; // self.set_pose(EntityPose::Crouching).await;
@ -118,15 +121,10 @@ impl Entity {
// } // }
} }
pub async fn set_sprinting( pub async fn set_sprinting(&mut self, client: &mut Client, sprinting: bool) {
&mut self,
client: &mut Client,
world: Arc<tokio::sync::Mutex<World>>,
sprinting: bool,
) {
assert!(self.sprinting != sprinting); assert!(self.sprinting != sprinting);
self.sprinting = sprinting; self.sprinting = sprinting;
self.set_flag(client, world, Self::SPRINTING_FLAG_INDEX, sprinting) self.set_flag(client, Self::SPRINTING_FLAG_INDEX, sprinting)
.await; .await;
} }
@ -134,15 +132,10 @@ impl Entity {
!self.on_ground !self.on_ground
} }
pub async fn set_fall_flying( pub async fn set_fall_flying(&mut self, client: &mut Client, fall_flying: bool) {
&mut self,
client: &mut Client,
world: Arc<tokio::sync::Mutex<World>>,
fall_flying: bool,
) {
assert!(self.fall_flying != fall_flying); assert!(self.fall_flying != fall_flying);
self.fall_flying = fall_flying; self.fall_flying = fall_flying;
self.set_flag(client, world, Self::FALL_FLYING_FLAG_INDEX, fall_flying) self.set_flag(client, Self::FALL_FLYING_FLAG_INDEX, fall_flying)
.await; .await;
} }
@ -153,13 +146,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( async fn set_flag(&mut self, client: &mut Client, index: u32, value: bool) {
&mut self,
client: &mut Client,
world: Arc<tokio::sync::Mutex<World>>,
index: u32,
value: bool,
) {
let mut b = 0i8; let mut b = 0i8;
if value { if value {
b |= 1 << index; b |= 1 << index;
@ -168,18 +155,13 @@ impl Entity {
} }
let packet = CSetEntityMetadata::new(self.entity_id.into(), Metadata::new(0, 0.into(), b)); let packet = CSetEntityMetadata::new(self.entity_id.into(), Metadata::new(0, 0.into(), b));
client.send_packet(&packet); client.send_packet(&packet);
world self.world
.lock() .lock()
.await .await
.broadcast_packet(&[client.token], &packet); .broadcast_packet(&[client.token], &packet);
} }
pub async fn set_pose( pub async fn set_pose(&mut self, client: &mut Client, pose: EntityPose) {
&mut self,
client: &mut Client,
world: Arc<tokio::sync::Mutex<World>>,
pose: EntityPose,
) {
self.pose = pose; self.pose = pose;
let pose = self.pose as i32; let pose = self.pose as i32;
let packet = CSetEntityMetadata::<VarInt>::new( let packet = CSetEntityMetadata::<VarInt>::new(
@ -187,7 +169,7 @@ impl Entity {
Metadata::new(6, 20.into(), (pose).into()), Metadata::new(6, 20.into(), (pose).into()),
); );
client.send_packet(&packet); client.send_packet(&packet);
world self.world
.lock() .lock()
.await .await
.broadcast_packet(&[client.token], &packet) .broadcast_packet(&[client.token], &packet)

View File

@ -60,8 +60,6 @@ pub struct Player {
pub gameprofile: GameProfile, pub gameprofile: GameProfile,
pub client: Client, pub client: Client,
pub config: PlayerConfig, pub config: PlayerConfig,
// TODO: Put this into entity
pub world: Arc<tokio::sync::Mutex<World>>,
/// Current gamemode /// Current gamemode
pub gamemode: GameMode, pub gamemode: GameMode,
// TODO: prbly should put this into an Living Entitiy or something // TODO: prbly should put this into an Living Entitiy or something
@ -104,11 +102,10 @@ impl Player {
}; };
let config = client.config.clone().unwrap_or_default(); let config = client.config.clone().unwrap_or_default();
Self { Self {
entity: Entity::new(entity_id, EntityType::Player, 1.62), entity: Entity::new(entity_id, world, EntityType::Player, 1.62),
config, config,
gameprofile, gameprofile,
client, client,
world,
awaiting_teleport: None, awaiting_teleport: None,
// TODO: Load this from previous instance // TODO: Load this from previous instance
health: 20.0, health: 20.0,
@ -127,7 +124,7 @@ impl Player {
// TODO: Put this into entity // TODO: Put this into entity
/// Removes the Player out of the current World /// Removes the Player out of the current World
pub async fn remove(&mut self) { pub async fn remove(&mut self) {
self.world.lock().await.remove_player(self); self.entity.world.lock().await.remove_player(self);
} }
pub fn entity_id(&self) -> EntityId { pub fn entity_id(&self) -> EntityId {
@ -237,7 +234,7 @@ impl Player {
actions: vec![PlayerAction::UpdateGameMode((self.gamemode as i32).into())], actions: vec![PlayerAction::UpdateGameMode((self.gamemode as i32).into())],
}], }],
)); ));
self.world.lock().await.broadcast_packet( self.entity.world.lock().await.broadcast_packet(
&[self.client.token], &[self.client.token],
&CPlayerInfoUpdate::new( &CPlayerInfoUpdate::new(
0x04, 0x04,

View File

@ -237,9 +237,6 @@ impl World {
}); });
while let Some(chunk_data) = chunk_receiver.recv().await { while let Some(chunk_data) = chunk_receiver.recv().await {
if closed {
return;
}
// dbg!(chunk_pos); // dbg!(chunk_pos);
let chunk_data = match chunk_data { let chunk_data = match chunk_data {
Ok(d) => d, Ok(d) => d,
@ -258,8 +255,10 @@ impl World {
len / (1024 * 1024) len / (1024 * 1024)
); );
} }
if !client.closed {
client.send_packet(&CChunkData(&chunk_data)); client.send_packet(&CChunkData(&chunk_data));
} }
}
dbg!("DONE CHUNKS", inst.elapsed()); dbg!("DONE CHUNKS", inst.elapsed());
} }