refactor things out into functions

This commit is contained in:
Edvin Bryntesson 2024-10-21 15:10:09 +02:00
parent d7b162e68e
commit 4338bcff16
No known key found for this signature in database
4 changed files with 63 additions and 40 deletions

View File

@ -1,13 +1,33 @@
use super::vector3::Vector3;
use std::fmt; use std::fmt;
use crate::math::vector2::Vector2;
use num_traits::Euclid;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use super::vector3::Vector3;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
/// Aka Block Position /// Aka Block Position
pub struct WorldPosition(pub Vector3<i32>); pub struct WorldPosition(pub Vector3<i32>);
impl WorldPosition {
pub fn chunk_and_chunk_relative_position(&self) -> (Vector2<i32>, Vector3<i32>) {
let (z_chunk, z_rem) = self.0.z.div_rem_euclid(&16);
let (x_chunk, x_rem) = self.0.x.div_rem_euclid(&16);
let chunk_coordinate = Vector2 {
x: x_chunk,
z: z_chunk,
};
// Since we divide by 16 remnant can never exceed u8
let relative = Vector3 {
x: x_rem,
z: z_rem,
y: self.0.y,
};
(chunk_coordinate, relative)
}
}
impl Serialize for WorldPosition { impl Serialize for WorldPosition {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where

View File

@ -1,12 +1,12 @@
use std::ops::Deref; use std::ops::Deref;
use crate::{WORLD_LOWEST_Y, WORLD_MAX_Y};
use derive_more::derive::{AsMut, AsRef, Display, Into}; use derive_more::derive::{AsMut, AsRef, Display, Into};
use num_traits::{PrimInt, Signed, Unsigned}; use num_traits::{PrimInt, Signed, Unsigned};
use pumpkin_core::math::vector2::Vector2; use pumpkin_core::math::vector2::Vector2;
use pumpkin_core::math::vector3::Vector3;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{WORLD_LOWEST_Y, WORLD_MAX_Y};
#[derive( #[derive(
Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, AsRef, AsMut, Into, Display, Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, AsRef, AsMut, Into, Display,
)] )]
@ -130,3 +130,13 @@ impl ChunkRelativeXZBlockCoordinates {
} }
} }
} }
impl From<Vector3<i32>> for ChunkRelativeBlockCoordinates {
fn from(value: Vector3<i32>) -> Self {
Self {
x: (value.x as u8).into(),
z: (value.z as u8).into(),
y: value.y.into(),
}
}
}

View File

@ -6,7 +6,7 @@ use crate::{
client::Client, client::Client,
entity::{player::Player, Entity}, entity::{player::Player, Entity},
}; };
use num_traits::{Euclid, ToPrimitive}; use num_traits::ToPrimitive;
use pumpkin_config::BasicConfiguration; use pumpkin_config::BasicConfiguration;
use pumpkin_core::math::position::WorldPosition; use pumpkin_core::math::position::WorldPosition;
use pumpkin_core::math::vector2::Vector2; use pumpkin_core::math::vector2::Vector2;
@ -20,11 +20,12 @@ use pumpkin_protocol::{
ClientPacket, VarInt, ClientPacket, VarInt,
}; };
use pumpkin_world::block::BlockId; use pumpkin_world::block::BlockId;
use pumpkin_world::chunk::ChunkData;
use pumpkin_world::coordinates::ChunkRelativeBlockCoordinates; use pumpkin_world::coordinates::ChunkRelativeBlockCoordinates;
use pumpkin_world::level::Level; use pumpkin_world::level::Level;
use scoreboard::Scoreboard; use scoreboard::Scoreboard;
use tokio::sync::mpsc;
use tokio::sync::Mutex; use tokio::sync::Mutex;
use tokio::sync::{mpsc, RwLock};
pub mod scoreboard; pub mod scoreboard;
@ -285,7 +286,7 @@ impl World {
level.mark_chunk_as_newly_watched(chunks).await; level.mark_chunk_as_newly_watched(chunks).await;
} }
fn spawn_world_chunks(&self, client: Arc<Client>, chunks: Vec<Vector2<i32>>, distance: i32) { async fn spawn_world_chunks(&self, client: Arc<Client>, chunks: Vec<Vector2<i32>>) {
if client.closed.load(std::sync::atomic::Ordering::Relaxed) { if client.closed.load(std::sync::atomic::Ordering::Relaxed) {
log::info!( log::info!(
"The connection with {} has closed before world chunks were spawned", "The connection with {} has closed before world chunks were spawned",
@ -294,21 +295,10 @@ impl World {
return; return;
} }
let inst = std::time::Instant::now(); let inst = std::time::Instant::now();
let (sender, mut chunk_receiver) = mpsc::channel(distance as usize); let chunks = self.get_chunks(chunks).await;
let client_id = client.id;
{
let level = self.level.clone();
tokio::spawn(async move {
log::debug!("Spawned chunk fetcher for {}", client_id);
let level = level.lock().await;
level.fetch_chunks(&chunks, sender);
});
}
tokio::spawn(async move { tokio::spawn(async move {
log::debug!("Spawned chunk sender for {}", client_id); for chunk_data in chunks {
while let Some(chunk_data) = chunk_receiver.recv().await {
let chunk_data = chunk_data.read().await; let chunk_data = chunk_data.read().await;
let packet = CChunkData(&chunk_data); let packet = CChunkData(&chunk_data);
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
@ -381,32 +371,32 @@ impl World {
.await; .await;
} }
pub async fn set_block(&self, position: WorldPosition, block_id: BlockId) { pub async fn set_block(&self, position: WorldPosition, block_id: BlockId) {
let (z_chunk, z_rem) = position.0.z.div_rem_euclid(&16); let (chunk_coordinate, relative_coordinates) = position.chunk_and_chunk_relative_position();
let (x_chunk, x_rem) = position.0.x.div_rem_euclid(&16);
let chunk_coordinate = Vector2 {
x: x_chunk,
z: z_chunk,
};
// Since we divide by 16 remnant can never exceed u8 // Since we divide by 16 remnant can never exceed u8
let relative = ChunkRelativeBlockCoordinates { let relative = ChunkRelativeBlockCoordinates::from(relative_coordinates);
x: (x_rem as u8).into(),
z: (z_rem as u8).into(),
y: position.0.y.into(),
};
let chunk = self.get_chunks(vec![chunk_coordinate]).await[0].clone();
chunk.write().await.blocks.set_block(relative, block_id);
self.broadcast_packet_all(&CBlockUpdate::new(
&position,
i32::from(block_id.data).into(),
))
.await;
}
pub async fn get_chunks(&self, chunks: Vec<Vector2<i32>>) -> Vec<Arc<RwLock<ChunkData>>> {
let (sender, mut receive) = mpsc::channel(1024); let (sender, mut receive) = mpsc::channel(1024);
{ {
let level = self.level.clone(); let level = self.level.clone();
tokio::spawn( tokio::spawn(async move { level.lock().await.fetch_chunks(&chunks, sender) });
async move { level.lock().await.fetch_chunks(&[chunk_coordinate], sender) },
);
} }
if let Some(data) = receive.recv().await { let mut received = vec![];
data.write().await.blocks.set_block(relative, block_id); while let Some(chunk) = receive.recv().await {
self.broadcast_packet_all(&CBlockUpdate::new(&position, (block_id.data as i32).into())) received.push(chunk);
.await;
} }
received
} }
pub async fn break_block(&self, position: WorldPosition) { pub async fn break_block(&self, position: WorldPosition) {

View File

@ -74,7 +74,9 @@ pub async fn player_join(world: &World, player: Arc<Player>) {
if !loading_chunks.is_empty() { if !loading_chunks.is_empty() {
world.mark_chunks_as_watched(&loading_chunks).await; world.mark_chunks_as_watched(&loading_chunks).await;
world.spawn_world_chunks(player.client.clone(), loading_chunks, view_distance); world
.spawn_world_chunks(player.client.clone(), loading_chunks)
.await;
} }
if !unloading_chunks.is_empty() { if !unloading_chunks.is_empty() {
@ -134,7 +136,8 @@ pub async fn update_position(player: &Player) {
entity.world.mark_chunks_as_watched(&loading_chunks).await; entity.world.mark_chunks_as_watched(&loading_chunks).await;
entity entity
.world .world
.spawn_world_chunks(player.client.clone(), loading_chunks, view_distance); .spawn_world_chunks(player.client.clone(), loading_chunks)
.await;
} }
if !unloading_chunks.is_empty() { if !unloading_chunks.is_empty() {