refactor(block-entities): from async to sync Part 4

This commit is contained in:
Alexander Medvedev 2026-08-26 21:13:42 +02:00
parent 52038e3356
commit e2a138cfa6
68 changed files with 830 additions and 1018 deletions

View File

@ -196,21 +196,13 @@ impl BlockBehaviour for BedBlock {
} }
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult { fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {
let player = Arc::clone(args.player); Self::use_bed(args.world, args.player, args.block, args.position)
let world = Arc::clone(args.world);
let block_id = args.block.id;
let position = *args.position;
tokio::spawn(async move {
let block = Block::from_id(block_id);
Self::use_bed(&world, &player, block, &position).await;
});
BlockActionResult::SuccessServer
} }
} }
impl BedBlock { impl BedBlock {
#[expect(clippy::too_many_lines)] #[expect(clippy::too_many_lines)]
async fn use_bed( fn use_bed(
world: &Arc<World>, world: &Arc<World>,
player: &Arc<Player>, player: &Arc<Player>,
block: &Block, block: &Block,
@ -341,7 +333,7 @@ impl BedBlock {
player.clone(), player.clone(),
bed_head_pos, bed_head_pos,
); );
server.plugin_manager.fire(&server, &mut event).await; server.plugin_manager.fire_blocking(&server, &mut event);
if event.cancelled { if event.cancelled {
return BlockActionResult::SuccessServer; return BlockActionResult::SuccessServer;
} }

View File

@ -30,11 +30,18 @@ impl BrushableBlock {
if let Some(be) = world.get_block_entity(pos) if let Some(be) = world.get_block_entity(pos)
&& let Some(brush_be) = be.as_any().downcast_ref::<BrushableBlockBlockEntity>() && let Some(brush_be) = be.as_any().downcast_ref::<BrushableBlockBlockEntity>()
{ {
let mut hits = brush_be.hits.lock().await; let mut hits = brush_be
.hits
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
*hits += 1; *hits += 1;
if *hits >= 4 { if *hits >= 4 {
let item = brush_be.item.lock().await.take(); let item = brush_be
.item
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.take();
if let Some(item_stack) = item { if let Some(item_stack) = item {
world.drop_stack(pos, item_stack); world.drop_stack(pos, item_stack);
} }
@ -84,7 +91,11 @@ impl BlockBehaviour for BrushableBlock {
fn broken(&self, args: BrokenArgs<'_>) { fn broken(&self, args: BrokenArgs<'_>) {
if let Some(be) = args.world.get_block_entity(args.position) if let Some(be) = args.world.get_block_entity(args.position)
&& let Some(brush_be) = be.as_any().downcast_ref::<BrushableBlockBlockEntity>() && let Some(brush_be) = be.as_any().downcast_ref::<BrushableBlockBlockEntity>()
&& let Some(contained) = brush_be.item.blocking_lock().take() && let Some(contained) = brush_be
.item
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.take()
{ {
args.world.drop_stack(args.position, contained); args.world.drop_stack(args.position, contained);
} }

View File

@ -174,11 +174,8 @@ impl BlockBehaviour for DispenserBlock {
} }
fn on_scheduled_tick(&self, args: OnScheduledTickArgs<'_>) { fn on_scheduled_tick(&self, args: OnScheduledTickArgs<'_>) {
let world = args.world.clone(); let (block, state) = args.world.get_block_and_state(args.position);
let position = *args.position; if let Some(block_entity) = args.world.get_block_entity(args.position) {
tokio::spawn(async move {
let (block, state) = world.get_block_and_state(&position);
if let Some(block_entity) = world.get_block_entity(&position) {
let Some(dispenser) = block_entity.as_any().downcast_ref::<DispenserBlockEntity>() let Some(dispenser) = block_entity.as_any().downcast_ref::<DispenserBlockEntity>()
else { else {
return; return;
@ -187,17 +184,17 @@ impl BlockBehaviour for DispenserBlock {
if let Some((slot_index, mut item)) = dispenser.get_random_slot() { if let Some((slot_index, mut item)) = dispenser.get_random_slot() {
let props = DispenserLikeProperties::from_state_id(state.id, block); let props = DispenserLikeProperties::from_state_id(state.id, block);
let ctx = DispenseContext { let ctx = DispenseContext {
world: &world, world: args.world,
position: &position, position: args.position,
facing: props.facing, facing: props.facing,
}; };
Self::dispense(&ctx, dispenser, &mut item).await; Self::dispense(&ctx, dispenser, &mut item);
dispenser.set_stack(slot_index, item); dispenser.set_stack(slot_index, item);
} else { } else {
world.sync_world_event(WorldEvent::SoundDispenserFail, position, 0); args.world
.sync_world_event(WorldEvent::SoundDispenserFail, *args.position, 0);
} }
} }
});
} }
fn get_comparator_output(&self, args: GetComparatorOutputArgs<'_>) -> Option<u8> { fn get_comparator_output(&self, args: GetComparatorOutputArgs<'_>) -> Option<u8> {
@ -225,17 +222,13 @@ impl DispenserBlock {
const FIREWORK_PROJECTILE_POWER: f64 = 0.5; const FIREWORK_PROJECTILE_POWER: f64 = 0.5;
const FIREWORK_PROJECTILE_UNCERTAINTY: f64 = 1.0; const FIREWORK_PROJECTILE_UNCERTAINTY: f64 = 1.0;
async fn dispense( fn dispense(ctx: &DispenseContext<'_>, dispenser: &DispenserBlockEntity, item: &mut ItemStack) {
ctx: &DispenseContext<'_>,
dispenser: &DispenserBlockEntity,
item: &mut ItemStack,
) {
let mut event = crate::plugin::api::events::block::block_dispense::BlockDispenseEvent::new( let mut event = crate::plugin::api::events::block::block_dispense::BlockDispenseEvent::new(
*ctx.position, *ctx.position,
item.item.registry_key.to_string(), item.item.registry_key.to_string(),
); );
if let Some(server) = ctx.world.server.upgrade() { if let Some(server) = ctx.world.server.upgrade() {
server.plugin_manager.fire(&server, &mut event).await; server.plugin_manager.fire_blocking(&server, &mut event);
} }
if event.cancelled { if event.cancelled {
ctx.world ctx.world

View File

@ -135,22 +135,20 @@ impl BlockBehaviour for DropperBlock {
} }
fn on_scheduled_tick(&self, args: OnScheduledTickArgs<'_>) { fn on_scheduled_tick(&self, args: OnScheduledTickArgs<'_>) {
let world = args.world.clone(); let (block, state) = args.world.get_block_and_state(args.position);
let position = *args.position; if let Some(block_entity) = args.world.get_block_entity(args.position) {
tokio::spawn(async move { let Some(dropper) = block_entity.as_any().downcast_ref::<DropperBlockEntity>() else {
let (block, state) = world.get_block_and_state(&position);
if let Some(block_entity) = world.get_block_entity(&position) {
let Some(dropper) = block_entity.as_any().downcast_ref::<DropperBlockEntity>()
else {
return; return;
}; };
if let Some((slot_index, mut item)) = dropper.get_random_slot() { if let Some((slot_index, mut item)) = dropper.get_random_slot() {
let props = DispenserLikeProperties::from_state_id(state.id, block); let props = DispenserLikeProperties::from_state_id(state.id, block);
let target_pos = position.offset(props.facing.to_block_direction().to_offset()); let target_pos = args
.position
.offset(props.facing.to_block_direction().to_offset());
if let Some(entity) = world.get_block_entity(&target_pos) if let Some(entity) = args.world.get_block_entity(&target_pos)
&& let Some(container) = entity.get_inventory() && let Some(container) = entity.get_inventory()
{ {
let backup = item.clone(); let backup = item.clone();
@ -169,14 +167,14 @@ impl BlockBehaviour for DropperBlock {
let drop_item = item.split(1); let drop_item = item.split(1);
dropper.set_stack(slot_index, item); dropper.set_stack(slot_index, item);
let facing = to_normal(props.facing); let facing = to_normal(props.facing);
let mut pos = position.to_centered_f64().add(&(facing * 0.7)); let mut pos = args.position.to_centered_f64().add(&(facing * 0.7));
pos.y -= match props.facing { pos.y -= match props.facing {
Facing::Up | Facing::Down => 0.125, Facing::Up | Facing::Down => 0.125,
_ => 0.15625, _ => 0.15625,
}; };
let entity = Entity::new(world.clone(), pos, &EntityType::ITEM); let entity = Entity::new(args.world.clone(), pos, &EntityType::ITEM);
let rd = rng().random::<f64>().mul_add(0.1, 0.2); let rd = rng().random::<f64>().mul_add(0.1, 0.2);
let velocity = Vector3::new( let velocity = Vector3::new(
@ -188,20 +186,21 @@ impl BlockBehaviour for DropperBlock {
let item_entity = Arc::new(ItemEntity::new_with_velocity( let item_entity = Arc::new(ItemEntity::new_with_velocity(
entity, drop_item, velocity, 40, entity, drop_item, velocity, 40,
)); ));
world.spawn_entity(item_entity); args.world.spawn_entity(item_entity);
world.sync_world_event(WorldEvent::SoundDispenserDispense, position, 0); args.world
.sync_world_event(WorldEvent::SoundDispenserDispense, *args.position, 0);
world.sync_world_event( args.world.sync_world_event(
WorldEvent::ParticlesShootSmoke, WorldEvent::ParticlesShootSmoke,
position, *args.position,
to_data3d(props.facing), to_data3d(props.facing),
); );
} else { } else {
world.sync_world_event(WorldEvent::SoundDispenserDispense, position, 0); args.world
.sync_world_event(WorldEvent::SoundDispenserDispense, *args.position, 0);
} }
} }
});
} }
fn get_comparator_output(&self, args: GetComparatorOutputArgs<'_>) -> Option<u8> { fn get_comparator_output(&self, args: GetComparatorOutputArgs<'_>) -> Option<u8> {

View File

@ -41,37 +41,42 @@ impl BlockBehaviour for RepeaterBlock {
} }
fn on_scheduled_tick(&self, args: OnScheduledTickArgs<'_>) { fn on_scheduled_tick(&self, args: OnScheduledTickArgs<'_>) {
let world = args.world.clone(); let (block, state) = args.world.get_block_and_state(args.position);
let pos = *args.position; if self.is_locked(args.world, *args.position, state.id, block) {
tokio::spawn(async move {
let (block, state) = world.get_block_and_state(&pos);
if Self.is_locked(&world, pos, state.id, block) {
return; return;
} }
let mut props = RepeaterProperties::from_state_id(state.id, block); let mut props = RepeaterProperties::from_state_id(state.id, block);
let now_powered = props.powered; let now_powered = props.powered;
let should_be_powered = Self.has_power(&world, pos, state, block); let should_be_powered = self.has_power(args.world, *args.position, state, block);
if now_powered && !should_be_powered { if now_powered && !should_be_powered {
props.powered = false; props.powered = false;
world.set_block_state(&pos, props.to_state_id(block), BlockFlags::NOTIFY_LISTENERS); args.world.set_block_state(
args.position,
props.to_state_id(block),
BlockFlags::NOTIFY_LISTENERS,
);
RedstoneGateBlock::update_target( RedstoneGateBlock::update_target(
&Self, self,
&world, args.world,
pos, *args.position,
props.to_state_id(block), props.to_state_id(block),
block, block,
); );
} else if !now_powered { } else if !now_powered {
props.powered = true; props.powered = true;
world.set_block_state(&pos, props.to_state_id(block), BlockFlags::NOTIFY_LISTENERS); args.world.set_block_state(
args.position,
props.to_state_id(block),
BlockFlags::NOTIFY_LISTENERS,
);
if !should_be_powered { if !should_be_powered {
world.schedule_block_tick( args.world.schedule_block_tick(
block, block,
pos, *args.position,
RedstoneGateBlock::get_update_delay_internal( RedstoneGateBlock::get_update_delay_internal(
&Self, self,
props.to_state_id(block), props.to_state_id(block),
block, block,
), ),
@ -79,14 +84,13 @@ impl BlockBehaviour for RepeaterBlock {
); );
} }
RedstoneGateBlock::update_target( RedstoneGateBlock::update_target(
&Self, self,
&world, args.world,
pos, *args.position,
props.to_state_id(block), props.to_state_id(block),
block, block,
); );
} }
});
} }
fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult { fn normal_use(&self, args: NormalUseArgs<'_>) -> BlockActionResult {

View File

@ -42,7 +42,10 @@ impl SculkSensorBlock {
if let Some(be) = world.get_block_entity(pos) if let Some(be) = world.get_block_entity(pos)
&& let Some(sensor_be) = be.as_any().downcast_ref::<SculkSensorBlockEntity>() && let Some(sensor_be) = be.as_any().downcast_ref::<SculkSensorBlockEntity>()
{ {
*sensor_be.last_vibration_frequency.blocking_lock() = power as i32; *sensor_be
.last_vibration_frequency
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner) = power as i32;
} }
props.sculk_sensor_phase = SculkSensorPhase::Active; props.sculk_sensor_phase = SculkSensorPhase::Active;
@ -73,7 +76,10 @@ impl SculkSensorBlock {
.as_any() .as_any()
.downcast_ref::<CalibratedSculkSensorBlockEntity>() .downcast_ref::<CalibratedSculkSensorBlockEntity>()
{ {
*cal_be.last_vibration_frequency.blocking_lock() = power as i32; *cal_be
.last_vibration_frequency
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner) = power as i32;
} }
props.sculk_sensor_phase = SculkSensorPhase::Active; props.sculk_sensor_phase = SculkSensorPhase::Active;
@ -136,13 +142,23 @@ impl BlockBehaviour for SculkSensorBlock {
fn get_comparator_output(&self, args: GetComparatorOutputArgs<'_>) -> Option<u8> { fn get_comparator_output(&self, args: GetComparatorOutputArgs<'_>) -> Option<u8> {
let be = args.world.get_block_entity(args.position)?; let be = args.world.get_block_entity(args.position)?;
if let Some(sensor_be) = be.as_any().downcast_ref::<SculkSensorBlockEntity>() { if let Some(sensor_be) = be.as_any().downcast_ref::<SculkSensorBlockEntity>() {
return Some(*sensor_be.last_vibration_frequency.blocking_lock() as u8); return Some(
*sensor_be
.last_vibration_frequency
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner) as u8,
);
} }
if let Some(cal_be) = be if let Some(cal_be) = be
.as_any() .as_any()
.downcast_ref::<CalibratedSculkSensorBlockEntity>() .downcast_ref::<CalibratedSculkSensorBlockEntity>()
{ {
return Some(*cal_be.last_vibration_frequency.blocking_lock() as u8); return Some(
*cal_be
.last_vibration_frequency
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner) as u8,
);
} }
None None
} }

View File

@ -68,7 +68,10 @@ impl SculkShriekerBlock {
if let Some(entity) = world.get_block_entity(pos) if let Some(entity) = world.get_block_entity(pos)
&& let Some(shrieker) = entity.as_any().downcast_ref::<SculkShriekerBlockEntity>() && let Some(shrieker) = entity.as_any().downcast_ref::<SculkShriekerBlockEntity>()
{ {
let mut level = shrieker.warning_level.lock().await; let mut level = shrieker
.warning_level
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
*level = (*level + 1).min(4); *level = (*level + 1).min(4);
if props.can_summon && *level >= 4 { if props.can_summon && *level >= 4 {
// TODO: spawn Warden near pos // TODO: spawn Warden near pos

View File

@ -2,8 +2,7 @@ use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_nbt::tag::NbtTag; use pumpkin_nbt::tag::NbtTag;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::pin::Pin; use std::sync::Mutex;
use tokio::sync::Mutex;
pub struct BannerBlockEntity { pub struct BannerBlockEntity {
pub position: BlockPos, pub position: BlockPos,
@ -33,18 +32,17 @@ impl BlockEntity for BannerBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(name) = self.custom_name.lock()
nbt: &'a mut NbtCompound, && let Some(name) = name.as_ref()
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { {
Box::pin(async move {
if let Some(name) = self.custom_name.lock().await.as_ref() {
nbt.put_string("CustomName", name.clone()); nbt.put_string("CustomName", name.clone());
} }
if let Some(pats) = self.patterns.lock().await.as_ref() { if let Ok(pats) = self.patterns.lock()
&& let Some(pats) = pats.as_ref()
{
nbt.put_list("patterns", pats.clone()); nbt.put_list("patterns", pats.clone());
} }
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {
@ -73,8 +71,8 @@ impl BannerBlockEntity {
pub const fn new(position: BlockPos) -> Self { pub const fn new(position: BlockPos) -> Self {
Self { Self {
position, position,
custom_name: Mutex::const_new(None), custom_name: Mutex::new(None),
patterns: Mutex::const_new(None), patterns: Mutex::new(None),
} }
} }
} }

View File

@ -7,7 +7,6 @@ use pumpkin_util::math::vector3::Vector3;
use pumpkin_util::random::xoroshiro128::Xoroshiro; use pumpkin_util::random::xoroshiro128::Xoroshiro;
use pumpkin_util::random::{RandomImpl, get_seed}; use pumpkin_util::random::{RandomImpl, get_seed};
use std::any::Any; use std::any::Any;
use std::pin::Pin;
use std::sync::RwLock; use std::sync::RwLock;
use std::{ use std::{
array::from_fn, array::from_fn,
@ -63,13 +62,8 @@ impl BlockEntity for BarrelBlockEntity {
barrel barrel
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
self.write_inventory_nbt(nbt, true); self.write_inventory_nbt(nbt, true);
})
} }
fn tick(&self, world: &Arc<World>) { fn tick(&self, world: &Arc<World>) {

View File

@ -1,8 +1,6 @@
use futures::Future;
use pumpkin_data::data_component_impl::IDSetContent; use pumpkin_data::data_component_impl::IDSetContent;
use pumpkin_data::tag::Taggable; use pumpkin_data::tag::Taggable;
use std::any::Any; use std::any::Any;
use std::pin::Pin;
use std::sync::atomic::{AtomicBool, AtomicI32, Ordering}; use std::sync::atomic::{AtomicBool, AtomicI32, Ordering};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@ -262,11 +260,7 @@ impl BlockEntity for BeaconBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
nbt.put_int( nbt.put_int(
"primary_effect", "primary_effect",
self.primary_effect.load(Ordering::Relaxed), self.primary_effect.load(Ordering::Relaxed),
@ -291,7 +285,6 @@ impl BlockEntity for BeaconBlockEntity {
{ {
nbt.put_string("Lock", lock.clone()); nbt.put_string("Lock", lock.clone());
} }
})
} }
fn tick(&self, world: &Arc<World>) { fn tick(&self, world: &Arc<World>) {

View File

@ -1,5 +1,3 @@
use std::pin::Pin;
use pumpkin_data::{ use pumpkin_data::{
BlockState, BlockStateId, BlockState, BlockStateId,
item::JavaToBedrockItemMapping, item::JavaToBedrockItemMapping,
@ -30,12 +28,7 @@ impl BlockEntity for BedBlockEntity {
Self { position } Self { position }
} }
fn write_nbt<'a>( fn write_nbt(&self, _nbt: &mut NbtCompound) {}
&'a self,
_nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async {})
}
fn bedrock_block_actor_data(&self, state_id: BlockStateId) -> Option<NbtCompound> { fn bedrock_block_actor_data(&self, state_id: BlockStateId) -> Option<NbtCompound> {
let (block, _) = BlockState::from_id_with_block(state_id); let (block, _) = BlockState::from_id_with_block(state_id);

View File

@ -2,8 +2,7 @@ use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_nbt::tag::NbtTag; use pumpkin_nbt::tag::NbtTag;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::pin::Pin; use std::sync::Mutex;
use tokio::sync::Mutex;
pub struct BeehiveBlockEntity { pub struct BeehiveBlockEntity {
pub position: BlockPos, pub position: BlockPos,
@ -39,22 +38,21 @@ impl BlockEntity for BeehiveBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(b) = self.bees.lock()
nbt: &'a mut NbtCompound, && let Some(b) = b.as_ref()
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { {
Box::pin(async move {
if let Some(b) = self.bees.lock().await.as_ref() {
nbt.put_list("Bees", b.clone()); nbt.put_list("Bees", b.clone());
} }
if let Some(fp) = self.flower_pos.lock().await.as_ref() { if let Ok(fp) = self.flower_pos.lock()
&& let Some(fp) = fp.as_ref()
{
let mut fp_nbt = NbtCompound::new(); let mut fp_nbt = NbtCompound::new();
fp_nbt.put_int("X", fp.0.x); fp_nbt.put_int("X", fp.0.x);
fp_nbt.put_int("Y", fp.0.y); fp_nbt.put_int("Y", fp.0.y);
fp_nbt.put_int("Z", fp.0.z); fp_nbt.put_int("Z", fp.0.z);
nbt.put_compound("FlowerPos", fp_nbt); nbt.put_compound("FlowerPos", fp_nbt);
} }
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {
@ -87,8 +85,8 @@ impl BeehiveBlockEntity {
pub const fn new(position: BlockPos) -> Self { pub const fn new(position: BlockPos) -> Self {
Self { Self {
position, position,
bees: Mutex::const_new(None), bees: Mutex::new(None),
flower_pos: Mutex::const_new(None), flower_pos: Mutex::new(None),
} }
} }
} }

View File

@ -6,7 +6,6 @@ use pumpkin_data::sound::{Sound, SoundCategory};
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::any::Any; use std::any::Any;
use std::pin::Pin;
use std::sync::Arc; use std::sync::Arc;
pub struct BellBlockEntity { pub struct BellBlockEntity {
@ -47,12 +46,7 @@ impl BellBlockEntity {
} }
impl BlockEntity for BellBlockEntity { impl BlockEntity for BellBlockEntity {
fn write_nbt<'a>( fn write_nbt(&self, _nbt: &mut NbtCompound) {}
&'a self,
_nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {})
}
fn from_nbt(_nbt: &NbtCompound, position: BlockPos) -> Self fn from_nbt(_nbt: &NbtCompound, position: BlockPos) -> Self
where where

View File

@ -1,6 +1,4 @@
use std::any::Any; use std::any::Any;
use std::future::Future;
use std::pin::Pin;
use std::sync::{ use std::sync::{
Arc, Mutex as StdMutex, RwLock, Arc, Mutex as StdMutex, RwLock,
atomic::AtomicI32, atomic::AtomicI32,
@ -401,18 +399,13 @@ impl crate::block::entities::BlockEntity for BrewingStandBlockEntity {
entity entity
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
// Persist brew state // Persist brew state
nbt.put_int("BrewTime", self.brew_time.load(Ordering::Relaxed)); nbt.put_int("BrewTime", self.brew_time.load(Ordering::Relaxed));
nbt.put_int("Fuel", self.fuel.load(Ordering::Relaxed)); nbt.put_int("Fuel", self.fuel.load(Ordering::Relaxed));
// Save inventory contents to NBT // Save inventory contents to NBT
self.write_inventory_nbt(nbt, true); self.write_inventory_nbt(nbt, true);
})
} }
fn get_inventory(self: Arc<Self>) -> Option<Arc<dyn Inventory>> { fn get_inventory(self: Arc<Self>) -> Option<Arc<dyn Inventory>> {

View File

@ -2,8 +2,7 @@ use super::BlockEntity;
use pumpkin_data::item_stack::ItemStack; use pumpkin_data::item_stack::ItemStack;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::pin::Pin; use std::sync::Mutex;
use tokio::sync::Mutex;
pub struct BrushableBlockBlockEntity { pub struct BrushableBlockBlockEntity {
pub position: BlockPos, pub position: BlockPos,
@ -38,19 +37,20 @@ impl BlockEntity for BrushableBlockBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(item) = self.item.lock()
nbt: &'a mut NbtCompound, && let Some(it) = item.as_ref()
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { {
Box::pin(async move {
if let Some(it) = self.item.lock().await.as_ref() {
let mut it_nbt = NbtCompound::new(); let mut it_nbt = NbtCompound::new();
it.write_item_stack(&mut it_nbt); it.write_item_stack(&mut it_nbt);
nbt.put_compound("item", it_nbt); nbt.put_compound("item", it_nbt);
} }
nbt.put_int("hits", *self.hits.lock().await); if let Ok(hits) = self.hits.lock() {
nbt.put_byte("direction", *self.direction.lock().await as i8); nbt.put_int("hits", *hits);
}) }
if let Ok(direction) = self.direction.lock() {
nbt.put_byte("direction", *direction as i8);
}
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {
@ -78,9 +78,9 @@ impl BrushableBlockBlockEntity {
pub const fn new(position: BlockPos) -> Self { pub const fn new(position: BlockPos) -> Self {
Self { Self {
position, position,
item: Mutex::const_new(None), item: Mutex::new(None),
hits: Mutex::const_new(0), hits: Mutex::new(0),
direction: Mutex::const_new(0), direction: Mutex::new(0),
} }
} }
} }

View File

@ -1,8 +1,7 @@
use super::BlockEntity; use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::pin::Pin; use std::sync::Mutex;
use tokio::sync::Mutex;
pub struct CalibratedSculkSensorBlockEntity { pub struct CalibratedSculkSensorBlockEntity {
pub position: BlockPos, pub position: BlockPos,
@ -29,16 +28,10 @@ impl BlockEntity for CalibratedSculkSensorBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(freq) = self.last_vibration_frequency.lock() {
nbt: &'a mut NbtCompound, nbt.put_int("last_vibration_frequency", *freq);
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { }
Box::pin(async move {
nbt.put_int(
"last_vibration_frequency",
*self.last_vibration_frequency.lock().await,
);
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {

View File

@ -3,15 +3,13 @@ use pumpkin_data::item_stack::ItemStack;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_nbt::tag::NbtTag; use pumpkin_nbt::tag::NbtTag;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::pin::Pin; use std::sync::{Arc, Mutex};
use std::sync::Arc;
use tokio::sync::Mutex;
pub struct CampfireBlockEntity { pub struct CampfireBlockEntity {
pub position: BlockPos, pub position: BlockPos,
pub items: [Arc<Mutex<ItemStack>>; 4], pub items: [Arc<Mutex<ItemStack>>; 4],
pub cooking_times: [tokio::sync::Mutex<i32>; 4], pub cooking_times: [Mutex<i32>; 4],
pub cooking_total_times: [tokio::sync::Mutex<i32>; 4], pub cooking_total_times: [Mutex<i32>; 4],
} }
impl BlockEntity for CampfireBlockEntity { impl BlockEntity for CampfireBlockEntity {
@ -61,15 +59,12 @@ impl BlockEntity for CampfireBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
let mut list = Vec::new(); let mut list = Vec::new();
for (i, item_mutex) in self.items.iter().enumerate() { for (i, item_mutex) in self.items.iter().enumerate() {
let stack = item_mutex.lock().await; if let Ok(stack) = item_mutex.lock()
if !stack.is_empty() { && !stack.is_empty()
{
let mut item_nbt = NbtCompound::new(); let mut item_nbt = NbtCompound::new();
item_nbt.put_byte("Slot", i as i8); item_nbt.put_byte("Slot", i as i8);
stack.write_item_stack(&mut item_nbt); stack.write_item_stack(&mut item_nbt);
@ -80,16 +75,19 @@ impl BlockEntity for CampfireBlockEntity {
let mut times = Vec::new(); let mut times = Vec::new();
for m in &self.cooking_times { for m in &self.cooking_times {
times.push(*m.lock().await); if let Ok(t) = m.lock() {
times.push(*t);
}
} }
nbt.put("CookingTimes", NbtTag::IntArray(times)); nbt.put("CookingTimes", NbtTag::IntArray(times));
let mut total_times = Vec::new(); let mut total_times = Vec::new();
for m in &self.cooking_total_times { for m in &self.cooking_total_times {
total_times.push(*m.lock().await); if let Ok(t) = m.lock() {
total_times.push(*t);
}
} }
nbt.put("CookingTotalTimes", NbtTag::IntArray(total_times)); nbt.put("CookingTotalTimes", NbtTag::IntArray(total_times));
})
} }
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {

View File

@ -52,14 +52,9 @@ macro_rules! impl_block_entity_for_chest {
chest chest
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut pumpkin_nbt::compound::NbtCompound) {
&'a self,
nbt: &'a mut pumpkin_nbt::compound::NbtCompound,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = ()> + Send + 'a>> {
use pumpkin_world::inventory::Inventory; use pumpkin_world::inventory::Inventory;
Box::pin(async move {
// Clone the loot table key without holding the lock across an await.
let loot_table_key = { let loot_table_key = {
let guard = self let guard = self
.loot_table .loot_table
@ -78,7 +73,6 @@ macro_rules! impl_block_entity_for_chest {
// Loot has already been generated, so persist the actual items. // Loot has already been generated, so persist the actual items.
self.write_inventory_nbt(nbt, true); self.write_inventory_nbt(nbt, true);
} }
})
} }
fn tick(&self, world: &Arc<$crate::world::World>) { fn tick(&self, world: &Arc<$crate::world::World>) {

View File

@ -4,8 +4,6 @@ use pumpkin_data::item_stack::ItemStack;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::any::Any; use std::any::Any;
use std::future::Future;
use std::pin::Pin;
use std::sync::RwLock; use std::sync::RwLock;
use std::{ use std::{
array::from_fn, array::from_fn,
@ -66,11 +64,7 @@ impl BlockEntity for ChiseledBookshelfBlockEntity {
bookshelf bookshelf
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
let items = self let items = self
.items .items
.read() .read()
@ -80,7 +74,6 @@ impl BlockEntity for ChiseledBookshelfBlockEntity {
LAST_INTERACTED_SLOT, LAST_INTERACTED_SLOT,
i32::from(self.last_interacted_slot.load(Ordering::Relaxed)), i32::from(self.last_interacted_slot.load(Ordering::Relaxed)),
); );
})
} }
fn get_inventory(self: Arc<Self>) -> Option<Arc<dyn Inventory>> { fn get_inventory(self: Arc<Self>) -> Option<Arc<dyn Inventory>> {

View File

@ -1,9 +1,6 @@
use std::{ use std::sync::{
pin::Pin,
sync::{
Mutex as StdMutex, Mutex as StdMutex,
atomic::{AtomicBool, AtomicU32, Ordering}, atomic::{AtomicBool, AtomicU32, Ordering},
},
}; };
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
@ -102,13 +99,8 @@ impl BlockEntity for CommandBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn std::future::Future<Output = ()> + Send + 'a>> {
Box::pin(async {
self.write_sync_nbt(nbt); self.write_sync_nbt(nbt);
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {

View File

@ -1,7 +1,4 @@
use std::{ use std::sync::atomic::{AtomicU8, Ordering};
pin::Pin,
sync::atomic::{AtomicU8, Ordering},
};
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
@ -46,16 +43,11 @@ impl BlockEntity for ComparatorBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
nbt.put_int( nbt.put_int(
OUTPUT_SIGNAL, OUTPUT_SIGNAL,
self.output_signal.load(Ordering::Relaxed) as i32, self.output_signal.load(Ordering::Relaxed) as i32,
); );
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {

View File

@ -2,8 +2,7 @@ use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_nbt::tag::NbtTag; use pumpkin_nbt::tag::NbtTag;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::pin::Pin; use std::sync::Mutex;
use tokio::sync::Mutex;
pub struct ConduitBlockEntity { pub struct ConduitBlockEntity {
pub position: BlockPos, pub position: BlockPos,
@ -33,16 +32,15 @@ impl BlockEntity for ConduitBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(active) = self.active.lock() {
nbt: &'a mut NbtCompound, nbt.put_bool("Active", *active);
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { }
Box::pin(async move { if let Ok(target) = self.target.lock()
nbt.put_bool("Active", *self.active.lock().await); && let Some(tgt) = target.as_ref()
if let Some(tgt) = self.target.lock().await.as_ref() { {
nbt.put("Target", tgt.clone()); nbt.put("Target", tgt.clone());
} }
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {

View File

@ -1,5 +1,3 @@
use std::pin::Pin;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
@ -25,12 +23,7 @@ impl BlockEntity for CopperGolemStatueBlockEntity {
Self { position } Self { position }
} }
fn write_nbt<'a>( fn write_nbt(&self, _nbt: &mut NbtCompound) {}
&'a self,
_nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async {})
}
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self

View File

@ -5,7 +5,6 @@ use pumpkin_util::math::position::BlockPos;
use pumpkin_world::inventory::{Clearable, Inventory, sync_write_items_to_nbt}; use pumpkin_world::inventory::{Clearable, Inventory, sync_write_items_to_nbt};
use std::any::Any; use std::any::Any;
use std::array::from_fn; use std::array::from_fn;
use std::pin::Pin;
use std::sync::Arc; use std::sync::Arc;
use std::sync::RwLock; use std::sync::RwLock;
use std::sync::atomic::{AtomicBool, AtomicI32, Ordering}; use std::sync::atomic::{AtomicBool, AtomicI32, Ordering};
@ -19,11 +18,7 @@ pub struct CrafterBlockEntity {
} }
impl BlockEntity for CrafterBlockEntity { impl BlockEntity for CrafterBlockEntity {
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
let items = self let items = self
.items .items
.read() .read()
@ -34,7 +29,6 @@ impl BlockEntity for CrafterBlockEntity {
self.crafting_ticks_remaining.load(Ordering::Relaxed), self.crafting_ticks_remaining.load(Ordering::Relaxed),
); );
nbt.put_bool("triggered", self.triggered.load(Ordering::Relaxed)); nbt.put_bool("triggered", self.triggered.load(Ordering::Relaxed));
})
} }
fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self

View File

@ -1,4 +1,3 @@
use std::pin::Pin;
use std::sync::Arc; use std::sync::Arc;
use crossbeam::atomic::AtomicCell; use crossbeam::atomic::AtomicCell;
@ -38,15 +37,10 @@ impl BlockEntity for CreakingHeartBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
if let Some(uuid) = self.creaking_uuid.load() { if let Some(uuid) = self.creaking_uuid.load() {
nbt.put_string("creaking_uuid", uuid.to_string()); nbt.put_string("creaking_uuid", uuid.to_string());
} }
})
} }
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {

View File

@ -1,4 +1,3 @@
use std::pin::Pin;
use std::sync::Arc; use std::sync::Arc;
use pumpkin_data::block_properties::BlockProperties; use pumpkin_data::block_properties::BlockProperties;
@ -31,12 +30,7 @@ impl BlockEntity for DaylightDetectorBlockEntity {
Self { position } Self { position }
} }
fn write_nbt<'a>( fn write_nbt(&self, _nbt: &mut NbtCompound) {}
&'a self,
_nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async {})
}
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self

View File

@ -3,8 +3,7 @@ use pumpkin_data::item_stack::ItemStack;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_nbt::tag::NbtTag; use pumpkin_nbt::tag::NbtTag;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::pin::Pin; use std::sync::Mutex;
use tokio::sync::Mutex;
pub struct DecoratedPotBlockEntity { pub struct DecoratedPotBlockEntity {
pub position: BlockPos, pub position: BlockPos,
@ -36,20 +35,19 @@ impl BlockEntity for DecoratedPotBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(sherds) = self.sherds.lock()
nbt: &'a mut NbtCompound, && let Some(sh) = sherds.as_ref()
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { {
Box::pin(async move {
if let Some(sh) = self.sherds.lock().await.as_ref() {
nbt.put_list("sherds", sh.clone()); nbt.put_list("sherds", sh.clone());
} }
if let Some(it) = self.item.lock().await.as_ref() { if let Ok(item) = self.item.lock()
&& let Some(it) = item.as_ref()
{
let mut it_nbt = NbtCompound::new(); let mut it_nbt = NbtCompound::new();
it.write_item_stack(&mut it_nbt); it.write_item_stack(&mut it_nbt);
nbt.put_compound("item", it_nbt); nbt.put_compound("item", it_nbt);
} }
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {
@ -81,21 +79,30 @@ impl DecoratedPotBlockEntity {
pub const fn new(position: BlockPos) -> Self { pub const fn new(position: BlockPos) -> Self {
Self { Self {
position, position,
sherds: Mutex::const_new(None), sherds: Mutex::new(None),
item: Mutex::const_new(None), item: Mutex::new(None),
} }
} }
pub fn get_item(&self) -> Option<ItemStack> { pub fn get_item(&self) -> Option<ItemStack> {
self.item.blocking_lock().clone() self.item
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.clone()
} }
pub fn take_item(&self) -> Option<ItemStack> { pub fn take_item(&self) -> Option<ItemStack> {
self.item.blocking_lock().take() self.item
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.take()
} }
pub fn try_insert_item(&self, stack: &mut ItemStack, count: u8) -> bool { pub fn try_insert_item(&self, stack: &mut ItemStack, count: u8) -> bool {
let mut item_guard = self.item.blocking_lock(); let mut item_guard = self
.item
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
if let Some(existing) = item_guard.as_mut() { if let Some(existing) = item_guard.as_mut() {
if existing.item.id == stack.item.id { if existing.item.id == stack.item.id {
let add = count.min(64 - existing.item_count); let add = count.min(64 - existing.item_count);
@ -117,7 +124,11 @@ impl DecoratedPotBlockEntity {
} }
pub fn get_comparator_output(&self) -> u8 { pub fn get_comparator_output(&self) -> u8 {
self.item.blocking_lock().as_ref().map_or(0, |item| { self.item
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.as_ref()
.map_or(0, |item| {
if item.item_count == 0 { if item.item_count == 0 {
0 0
} else { } else {

View File

@ -6,7 +6,6 @@ use pumpkin_world::inventory::{Clearable, Inventory, sync_write_items_to_nbt};
use rand::{RngExt, rng}; use rand::{RngExt, rng};
use std::any::Any; use std::any::Any;
use std::array::from_fn; use std::array::from_fn;
use std::pin::Pin;
use std::sync::Arc; use std::sync::Arc;
use std::sync::RwLock; use std::sync::RwLock;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
@ -18,13 +17,8 @@ pub struct DispenserBlockEntity {
} }
impl BlockEntity for DispenserBlockEntity { impl BlockEntity for DispenserBlockEntity {
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
self.write_inventory_nbt(nbt, true); self.write_inventory_nbt(nbt, true);
})
} }
fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self

View File

@ -6,7 +6,6 @@ use pumpkin_world::inventory::{Clearable, Inventory, sync_write_items_to_nbt};
use rand::{RngExt, rng}; use rand::{RngExt, rng};
use std::any::Any; use std::any::Any;
use std::array::from_fn; use std::array::from_fn;
use std::pin::Pin;
use std::sync::Arc; use std::sync::Arc;
use std::sync::RwLock; use std::sync::RwLock;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
@ -18,13 +17,8 @@ pub struct DropperBlockEntity {
} }
impl BlockEntity for DropperBlockEntity { impl BlockEntity for DropperBlockEntity {
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
self.write_inventory_nbt(nbt, true); self.write_inventory_nbt(nbt, true);
})
} }
fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self

View File

@ -1,8 +1,7 @@
use super::BlockEntity; use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::pin::Pin; use std::sync::Mutex;
use tokio::sync::Mutex;
pub struct EnchantingTableBlockEntity { pub struct EnchantingTableBlockEntity {
pub position: BlockPos, pub position: BlockPos,
@ -29,15 +28,12 @@ impl BlockEntity for EnchantingTableBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(name) = self.custom_name.lock()
nbt: &'a mut NbtCompound, && let Some(name) = name.as_ref()
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { {
Box::pin(async move {
if let Some(name) = self.custom_name.lock().await.as_ref() {
nbt.put_string("CustomName", name.clone()); nbt.put_string("CustomName", name.clone());
} }
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {
@ -61,7 +57,7 @@ impl EnchantingTableBlockEntity {
pub const fn new(position: BlockPos) -> Self { pub const fn new(position: BlockPos) -> Self {
Self { Self {
position, position,
custom_name: Mutex::const_new(None), custom_name: Mutex::new(None),
} }
} }
} }

View File

@ -1,8 +1,7 @@
use super::BlockEntity; use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::pin::Pin; use std::sync::Mutex;
use tokio::sync::Mutex;
pub struct EndGatewayBlockEntity { pub struct EndGatewayBlockEntity {
pub position: BlockPos, pub position: BlockPos,
@ -41,21 +40,22 @@ impl BlockEntity for EndGatewayBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(age) = self.age.lock() {
nbt: &'a mut NbtCompound, nbt.put_long("Age", *age);
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { }
Box::pin(async move { if let Ok(exact_teleport) = self.exact_teleport.lock() {
nbt.put_long("Age", *self.age.lock().await); nbt.put_bool("ExactTeleport", *exact_teleport);
nbt.put_bool("ExactTeleport", *self.exact_teleport.lock().await); }
if let Some(exit) = self.exit_portal.lock().await.as_ref() { if let Ok(exit_portal) = self.exit_portal.lock()
&& let Some(exit) = exit_portal.as_ref()
{
let mut exit_nbt = NbtCompound::new(); let mut exit_nbt = NbtCompound::new();
exit_nbt.put_int("X", exit.0.x); exit_nbt.put_int("X", exit.0.x);
exit_nbt.put_int("Y", exit.0.y); exit_nbt.put_int("Y", exit.0.y);
exit_nbt.put_int("Z", exit.0.z); exit_nbt.put_int("Z", exit.0.z);
nbt.put_compound("ExitPortal", exit_nbt); nbt.put_compound("ExitPortal", exit_nbt);
} }
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {

View File

@ -1,5 +1,3 @@
use std::pin::Pin;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
@ -43,12 +41,7 @@ impl BlockEntity for EndPortalBlockEntity {
Self { position } Self { position }
} }
fn write_nbt<'a>( fn write_nbt(&self, _nbt: &mut NbtCompound) {}
&'a self,
_nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async {})
}
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self

View File

@ -4,7 +4,6 @@ use pumpkin_util::math::position::BlockPos;
use pumpkin_util::random::xoroshiro128::Xoroshiro; use pumpkin_util::random::xoroshiro128::Xoroshiro;
use pumpkin_util::random::{RandomImpl, get_seed}; use pumpkin_util::random::{RandomImpl, get_seed};
use std::any::Any; use std::any::Any;
use std::pin::Pin;
use std::sync::Arc; use std::sync::Arc;
use crate::block::viewer::{ViewerCountListener, ViewerCountTracker, ViewerCountTrackerExt}; use crate::block::viewer::{ViewerCountListener, ViewerCountTracker, ViewerCountTrackerExt};
@ -38,12 +37,7 @@ impl BlockEntity for EnderChestBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, _nbt: &mut NbtCompound) {}
&'a self,
_nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async {})
}
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {
Some(NbtCompound::new()) Some(NbtCompound::new())

View File

@ -552,11 +552,7 @@ macro_rules! impl_block_entity_for_cooking {
furnace furnace
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut pumpkin_nbt::compound::NbtCompound) {
&'a self,
nbt: &'a mut pumpkin_nbt::compound::NbtCompound,
) -> std::pin::Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
nbt.put_short("cooking_total_time", self.get_cooking_total_time() as i16); nbt.put_short("cooking_total_time", self.get_cooking_total_time() as i16);
nbt.put_short("cooking_time_spent", self.get_cooking_time_spent() as i16); nbt.put_short("cooking_time_spent", self.get_cooking_time_spent() as i16);
nbt.put_short("lit_total_time", self.get_lit_total_time() as i16); nbt.put_short("lit_total_time", self.get_lit_total_time() as i16);
@ -584,7 +580,6 @@ macro_rules! impl_block_entity_for_cooking {
} }
self.write_inventory_nbt(nbt, true); self.write_inventory_nbt(nbt, true);
})
} }
fn get_inventory( fn get_inventory(

View File

@ -1,9 +1,6 @@
use std::{ use std::sync::{
pin::Pin,
sync::{
Arc, Arc,
atomic::{AtomicBool, Ordering}, atomic::{AtomicBool, Ordering},
},
}; };
use super::BlockEntity; use super::BlockEntity;
@ -53,15 +50,10 @@ impl BlockEntity for HangingSignBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
nbt.put("front_text", self.front_text.clone()); nbt.put("front_text", self.front_text.clone());
nbt.put("back_text", self.back_text.clone()); nbt.put("back_text", self.back_text.clone());
nbt.put_bool("is_waxed", self.is_waxed.load(Ordering::Relaxed)); nbt.put_bool("is_waxed", self.is_waxed.load(Ordering::Relaxed));
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {

View File

@ -13,7 +13,6 @@ use pumpkin_util::math::vector3::Vector3;
use pumpkin_world::inventory::{Clearable, Inventory, sync_write_items_to_nbt}; use pumpkin_world::inventory::{Clearable, Inventory, sync_write_items_to_nbt};
use std::any::Any; use std::any::Any;
use std::array::from_fn; use std::array::from_fn;
use std::pin::Pin;
use std::sync::Arc; use std::sync::Arc;
use std::sync::RwLock; use std::sync::RwLock;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
@ -41,17 +40,12 @@ pub fn to_offset(facing: &FacingHopper) -> Vector3<i32> {
} }
impl BlockEntity for HopperBlockEntity { impl BlockEntity for HopperBlockEntity {
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
nbt.put( nbt.put(
"TransferCooldown", "TransferCooldown",
NbtTag::Int(self.cooldown_time.load(Ordering::Relaxed)), NbtTag::Int(self.cooldown_time.load(Ordering::Relaxed)),
); );
self.write_inventory_nbt(nbt, true); self.write_inventory_nbt(nbt, true);
})
} }
fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self
@ -89,13 +83,9 @@ impl BlockEntity for HopperBlockEntity {
); );
if state.enabled if state.enabled
&& let Some(entity) = world.get_block_entity(&self.position) && let Some(entity) = world.get_block_entity(&self.position)
&& let Some(hopper) = entity.as_any().downcast_ref::<Self>()
{ {
let world = world.clone(); hopper.try_move_items(state, world);
tokio::spawn(async move {
if let Some(hopper) = entity.as_any().downcast_ref::<Self>() {
hopper.try_move_items(&state, &world).await;
}
});
} }
} }
} }
@ -157,15 +147,15 @@ impl HopperBlockEntity {
ticked_game_time: AtomicI64::new(0), ticked_game_time: AtomicI64::new(0),
} }
} }
async fn try_move_items(&self, state: &HopperLikeProperties, world: &Arc<World>) { fn try_move_items(&self, state: HopperLikeProperties, world: &Arc<World>) {
if self.cooldown_time.load(Ordering::Relaxed) <= 0 && state.enabled { if self.cooldown_time.load(Ordering::Relaxed) <= 0 && state.enabled {
let mut success = if self.is_empty() { let mut success = if self.is_empty() {
false false
} else { } else {
self.eject_items(world).await self.eject_items(world)
}; };
if !self.inventory_full() { if !self.inventory_full() {
success |= self.suck_in_items(world).await; success |= self.suck_in_items(world);
} }
if success { if success {
self.cooldown_time.store(8, Ordering::Relaxed); self.cooldown_time.store(8, Ordering::Relaxed);
@ -187,7 +177,7 @@ impl HopperBlockEntity {
true true
} }
async fn suck_in_items(&self, world: &Arc<World>) -> bool { fn suck_in_items(&self, world: &Arc<World>) -> bool {
// TODO getEntityContainer // TODO getEntityContainer
let pos_up = &self.position.up(); let pos_up = &self.position.up();
let mut search_event = crate::plugin::api::events::inventory::hopper_inventory_search::HopperInventorySearchEvent::new( let mut search_event = crate::plugin::api::events::inventory::hopper_inventory_search::HopperInventorySearchEvent::new(
@ -195,7 +185,9 @@ impl HopperBlockEntity {
*pos_up, *pos_up,
); );
if let Some(server) = world.server.upgrade() { if let Some(server) = world.server.upgrade() {
server.plugin_manager.fire(&server, &mut search_event).await; server
.plugin_manager
.fire_blocking(&server, &mut search_event);
} }
if search_event.cancelled { if search_event.cancelled {
return false; return false;
@ -256,7 +248,9 @@ impl HopperBlockEntity {
registry_key, registry_key,
); );
if let Some(server) = world.server.upgrade() { if let Some(server) = world.server.upgrade() {
server.plugin_manager.fire(&server, &mut pickup_event).await; server
.plugin_manager
.fire_blocking(&server, &mut pickup_event);
} }
if pickup_event.cancelled { if pickup_event.cancelled {
continue; continue;
@ -292,7 +286,7 @@ impl HopperBlockEntity {
false false
} }
async fn eject_items(&self, world: &Arc<World>) -> bool { fn eject_items(&self, world: &Arc<World>) -> bool {
// TODO getEntityContainer // TODO getEntityContainer
if let Some(entity) = world.get_block_entity(&self.position.offset(to_offset(&self.facing))) if let Some(entity) = world.get_block_entity(&self.position.offset(to_offset(&self.facing)))
@ -325,7 +319,9 @@ impl HopperBlockEntity {
1, 1,
); );
if let Some(server) = world.server.upgrade() { if let Some(server) = world.server.upgrade() {
server.plugin_manager.fire(&server, &mut move_event).await; server
.plugin_manager
.fire_blocking(&server, &mut move_event);
} }
if move_event.cancelled { if move_event.cancelled {
continue; continue;

View File

@ -1,13 +1,9 @@
use rand::Rng; use rand::Rng;
use std::{ use std::sync::{
pin::Pin, Arc, Mutex,
sync::{
Arc,
atomic::{AtomicBool, AtomicI32, Ordering}, atomic::{AtomicBool, AtomicI32, Ordering},
},
}; };
use futures::Future;
use pumpkin_data::block_properties::{BlockProperties, JigsawLikeProperties, Orientation}; use pumpkin_data::block_properties::{BlockProperties, JigsawLikeProperties, Orientation};
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::{ use pumpkin_util::{
@ -22,8 +18,6 @@ use pumpkin_world::generation::structure::structures::{
}, },
}; };
use tokio::sync::Mutex;
use crate::block::blocks::jigsaw::JigsawBlock; use crate::block::blocks::jigsaw::JigsawBlock;
use crate::world::World; use crate::world::World;
@ -81,8 +75,16 @@ impl JigsawBlockEntity {
} }
pub async fn generate(&self, world: &Arc<World>, levels: i32, keep_jigsaws: bool) { pub async fn generate(&self, world: &Arc<World>, levels: i32, keep_jigsaws: bool) {
let pool = self.pool.lock().await.clone(); let pool = self
let target = self.target.lock().await.clone(); .pool
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.clone();
let target = self
.target
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.clone();
let block_state = world.get_block_state(&self.position); let block_state = world.get_block_state(&self.position);
let props = let props =
@ -206,17 +208,22 @@ impl BlockEntity for JigsawBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(name) = self.name.lock() {
nbt: &'a mut NbtCompound, nbt.put_string(Self::NAME, name.clone());
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { }
Box::pin(async move { if let Ok(target) = self.target.lock() {
nbt.put_string(Self::NAME, self.name.lock().await.clone()); nbt.put_string(Self::TARGET, target.clone());
nbt.put_string(Self::TARGET, self.target.lock().await.clone()); }
nbt.put_string(Self::POOL, self.pool.lock().await.clone()); if let Ok(pool) = self.pool.lock() {
nbt.put_string(Self::FINAL_STATE, self.final_state.lock().await.clone()); nbt.put_string(Self::POOL, pool.clone());
let joint = *self.joint.lock().await; }
if let Ok(final_state) = self.final_state.lock() {
nbt.put_string(Self::FINAL_STATE, final_state.clone());
}
if let Ok(joint) = self.joint.lock() {
nbt.put_string(Self::JOINT, joint.as_str().to_string()); nbt.put_string(Self::JOINT, joint.as_str().to_string());
}
nbt.put_int( nbt.put_int(
Self::PLACEMENT_PRIORITY, Self::PLACEMENT_PRIORITY,
self.placement_priority.load(Ordering::SeqCst), self.placement_priority.load(Ordering::SeqCst),
@ -225,7 +232,6 @@ impl BlockEntity for JigsawBlockEntity {
Self::SELECTION_PRIORITY, Self::SELECTION_PRIORITY,
self.selection_priority.load(Ordering::SeqCst), self.selection_priority.load(Ordering::SeqCst),
); );
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {

View File

@ -1,6 +1,4 @@
use std::any::Any; use std::any::Any;
use std::future::Future;
use std::pin::Pin;
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@ -58,11 +56,7 @@ impl BlockEntity for JukeboxBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
let record = self let record = self
.record_stack .record_stack
.lock() .lock()
@ -77,7 +71,6 @@ impl BlockEntity for JukeboxBlockEntity {
if ticks > 0 { if ticks > 0 {
nbt.put_long(TICKS_SINCE_SONG_STARTED_NBT_KEY, ticks as i64); nbt.put_long(TICKS_SINCE_SONG_STARTED_NBT_KEY, ticks as i64);
} }
})
} }
fn tick(&self, _world: &Arc<World>) { fn tick(&self, _world: &Arc<World>) {

View File

@ -5,8 +5,6 @@ use pumpkin_nbt::tag::NbtTag;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::{ use std::{
any::Any, any::Any,
future::Future,
pin::Pin,
sync::{ sync::{
Arc, Mutex, Arc, Mutex,
atomic::{AtomicBool, AtomicUsize, Ordering}, atomic::{AtomicBool, AtomicUsize, Ordering},
@ -56,11 +54,7 @@ impl BlockEntity for LecternBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
let book = self let book = self
.book .book
.lock() .lock()
@ -71,7 +65,6 @@ impl BlockEntity for LecternBlockEntity {
nbt.put_compound("Book", book_nbt); nbt.put_compound("Book", book_nbt);
} }
nbt.put_int("Page", self.page.load(Ordering::Relaxed) as i32); nbt.put_int("Page", self.page.load(Ordering::Relaxed) as i32);
})
} }
fn get_inventory(self: Arc<Self>) -> Option<Arc<dyn Inventory>> { fn get_inventory(self: Arc<Self>) -> Option<Arc<dyn Inventory>> {

View File

@ -1,6 +1,4 @@
use std::any::Any; use std::any::Any;
use std::future::Future;
use std::pin::Pin;
use std::sync::Mutex; use std::sync::Mutex;
use std::sync::atomic::{AtomicBool, AtomicI32, Ordering}; use std::sync::atomic::{AtomicBool, AtomicI32, Ordering};
@ -162,11 +160,7 @@ impl BlockEntity for MapBlockEntity {
entity entity
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
nbt.put_int("MapId", self.get_map_id()); nbt.put_int("MapId", self.get_map_id());
let colors = self let colors = self
.colors .colors
@ -174,7 +168,6 @@ impl BlockEntity for MapBlockEntity {
.unwrap_or_else(std::sync::PoisonError::into_inner); .unwrap_or_else(std::sync::PoisonError::into_inner);
let colors_i8: Vec<i8> = colors.iter().map(|&b| b as i8).collect(); let colors_i8: Vec<i8> = colors.iter().map(|&b| b as i8).collect();
nbt.put("Colors", NbtTag::ByteArray(colors_i8.into_boxed_slice())); nbt.put("Colors", NbtTag::ByteArray(colors_i8.into_boxed_slice()));
})
} }
fn is_dirty(&self) -> bool { fn is_dirty(&self) -> bool {

View File

@ -1,9 +1,6 @@
use std::{ use std::sync::{
pin::Pin,
sync::{
Arc, Arc,
atomic::{AtomicI32, Ordering}, atomic::{AtomicI32, Ordering},
},
}; };
use crossbeam::atomic::AtomicCell; use crossbeam::atomic::AtomicCell;
@ -54,13 +51,7 @@ impl MobSpawnerBlockEntity {
} }
} }
pub fn write_nbt<'a>(&'a self, nbt: &'a mut NbtCompound) { pub fn write_spawner_nbt(&self, nbt: &mut NbtCompound) {
// TODO: this is ugly af
nbt.put_string("id", self.resource_location().to_string());
let position = self.get_position();
nbt.put_int("x", position.0.x);
nbt.put_int("y", position.0.y);
nbt.put_int("z", position.0.z);
nbt.put_short("Delay", self.delay.load(Ordering::Relaxed) as i16); nbt.put_short("Delay", self.delay.load(Ordering::Relaxed) as i16);
nbt.put_short("MinSpawnDelay", self.min_delay as i16); nbt.put_short("MinSpawnDelay", self.min_delay as i16);
nbt.put_short("MaxSpawnDelay", self.max_delay as i16); nbt.put_short("MaxSpawnDelay", self.max_delay as i16);
@ -264,13 +255,8 @@ impl BlockEntity for MobSpawnerBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, self.write_spawner_nbt(nbt);
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
self.write_nbt(nbt);
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {

View File

@ -69,10 +69,7 @@ pub use pumpkin_world::block::entities::PropertyDelegate;
//TODO: We need a mark_dirty for chests //TODO: We need a mark_dirty for chests
pub trait BlockEntity: Any + Send + Sync { pub trait BlockEntity: Any + Send + Sync {
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound);
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>>;
fn from_nbt(nbt: &NbtCompound, position: BlockPos) -> Self fn from_nbt(nbt: &NbtCompound, position: BlockPos) -> Self
where where
Self: Sized; Self: Sized;
@ -95,18 +92,13 @@ pub trait BlockEntity: Any + Send + Sync {
false false
} }
fn write_internal<'a>( fn write_internal(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
nbt.put_string("id", self.resource_location().to_string()); nbt.put_string("id", self.resource_location().to_string());
let position = self.get_position(); let position = self.get_position();
nbt.put_int("x", position.0.x); nbt.put_int("x", position.0.x);
nbt.put_int("y", position.0.y); nbt.put_int("y", position.0.y);
nbt.put_int("z", position.0.z); nbt.put_int("z", position.0.z);
self.write_nbt(nbt).await; self.write_nbt(nbt);
})
} }
fn get_id(&self) -> u32 { fn get_id(&self) -> u32 {
let name = self let name = self
@ -462,7 +454,7 @@ mod test {
furnace.set_stack(0, ItemStack::new(5, &Item::DIAMOND)); furnace.set_stack(0, ItemStack::new(5, &Item::DIAMOND));
let mut nbt = NbtCompound::new(); let mut nbt = NbtCompound::new();
furnace.write_internal(&mut nbt).await; furnace.write_internal(&mut nbt);
let inventory = block_entity_from_nbt(&nbt).and_then(BlockEntity::get_inventory); let inventory = block_entity_from_nbt(&nbt).and_then(BlockEntity::get_inventory);
assert!( assert!(

View File

@ -1,5 +1,5 @@
use std::sync::Arc;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use std::{pin::Pin, sync::Arc};
use crossbeam::atomic::AtomicCell; use crossbeam::atomic::AtomicCell;
use pumpkin_data::{Block, BlockDirection, BlockState}; use pumpkin_data::{Block, BlockDirection, BlockState};
@ -274,17 +274,12 @@ impl BlockEntity for PistonBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
// TODO: pushed_block_state // TODO: pushed_block_state
nbt.put_byte(FACING, self.facing.to_index() as i8); nbt.put_byte(FACING, self.facing.to_index() as i8);
nbt.put_float(LAST_PROGRESS, self.last_progress.load()); nbt.put_float(LAST_PROGRESS, self.last_progress.load());
nbt.put_bool(EXTENDING, self.extending); nbt.put_bool(EXTENDING, self.extending);
nbt.put_bool(SOURCE, self.source); nbt.put_bool(SOURCE, self.source);
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {

View File

@ -1,5 +1,3 @@
use std::pin::Pin;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
@ -25,12 +23,7 @@ impl BlockEntity for PotentSulfurBlockEntity {
Self { position } Self { position }
} }
fn write_nbt<'a>( fn write_nbt(&self, _nbt: &mut NbtCompound) {}
&'a self,
_nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async {})
}
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self

View File

@ -1,8 +1,7 @@
use super::BlockEntity; use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::pin::Pin; use std::sync::Mutex;
use tokio::sync::Mutex;
pub struct SculkCatalystBlockEntity { pub struct SculkCatalystBlockEntity {
pub position: BlockPos, pub position: BlockPos,
@ -29,13 +28,10 @@ impl BlockEntity for SculkCatalystBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(decay_delay) = self.decay_delay.lock() {
nbt: &'a mut NbtCompound, nbt.put_int("decay_delay", *decay_delay);
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { }
Box::pin(async move {
nbt.put_int("decay_delay", *self.decay_delay.lock().await);
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {

View File

@ -1,8 +1,7 @@
use super::BlockEntity; use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::pin::Pin; use std::sync::Mutex;
use tokio::sync::Mutex;
pub struct SculkSensorBlockEntity { pub struct SculkSensorBlockEntity {
pub position: BlockPos, pub position: BlockPos,
@ -29,16 +28,10 @@ impl BlockEntity for SculkSensorBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(last_vibration_frequency) = self.last_vibration_frequency.lock() {
nbt: &'a mut NbtCompound, nbt.put_int("last_vibration_frequency", *last_vibration_frequency);
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { }
Box::pin(async move {
nbt.put_int(
"last_vibration_frequency",
*self.last_vibration_frequency.lock().await,
);
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {

View File

@ -1,8 +1,7 @@
use super::BlockEntity; use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::pin::Pin; use std::sync::Mutex;
use tokio::sync::Mutex;
pub struct SculkShriekerBlockEntity { pub struct SculkShriekerBlockEntity {
pub position: BlockPos, pub position: BlockPos,
@ -29,13 +28,10 @@ impl BlockEntity for SculkShriekerBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(warning_level) = self.warning_level.lock() {
nbt: &'a mut NbtCompound, nbt.put_int("warning_level", *warning_level);
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { }
Box::pin(async move {
nbt.put_int("warning_level", *self.warning_level.lock().await);
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {

View File

@ -5,7 +5,6 @@ use pumpkin_util::math::position::BlockPos;
use pumpkin_world::inventory::{Clearable, Inventory, sync_write_items_to_nbt}; use pumpkin_world::inventory::{Clearable, Inventory, sync_write_items_to_nbt};
use std::any::Any; use std::any::Any;
use std::array::from_fn; use std::array::from_fn;
use std::pin::Pin;
use std::sync::Arc; use std::sync::Arc;
use std::sync::RwLock; use std::sync::RwLock;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
@ -17,13 +16,8 @@ pub struct ShelfBlockEntity {
} }
impl BlockEntity for ShelfBlockEntity { impl BlockEntity for ShelfBlockEntity {
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
self.write_inventory_nbt(nbt, true); self.write_inventory_nbt(nbt, true);
})
} }
fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self

View File

@ -54,13 +54,8 @@ impl BlockEntity for ShulkerBoxBlockEntity {
shulker_box shulker_box
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
self.write_inventory_nbt(nbt, true); self.write_inventory_nbt(nbt, true);
})
} }
fn tick(&self, world: &Arc<World>) { fn tick(&self, world: &Arc<World>) {

View File

@ -1,9 +1,6 @@
use std::{ use std::sync::{
pin::Pin,
sync::{
Arc, Arc,
atomic::{AtomicBool, AtomicI8, Ordering}, atomic::{AtomicBool, AtomicI8, Ordering},
},
}; };
use super::BlockEntity; use super::BlockEntity;
@ -155,15 +152,10 @@ impl BlockEntity for SignBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
nbt.put("front_text", self.front_text.clone()); nbt.put("front_text", self.front_text.clone());
nbt.put("back_text", self.back_text.clone()); nbt.put("back_text", self.back_text.clone());
nbt.put_bool("is_waxed", self.is_waxed.load(Ordering::Relaxed)); nbt.put_bool("is_waxed", self.is_waxed.load(Ordering::Relaxed));
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {

View File

@ -1,8 +1,7 @@
use super::BlockEntity; use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::pin::Pin; use std::sync::Mutex;
use tokio::sync::Mutex;
pub struct SkullBlockEntity { pub struct SkullBlockEntity {
pub position: BlockPos, pub position: BlockPos,
@ -32,18 +31,17 @@ impl BlockEntity for SkullBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(sound) = self.note_block_sound.lock()
nbt: &'a mut NbtCompound, && let Some(sound) = sound.as_ref()
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { {
Box::pin(async move {
if let Some(sound) = self.note_block_sound.lock().await.as_ref() {
nbt.put_string("note_block_sound", sound.clone()); nbt.put_string("note_block_sound", sound.clone());
} }
if let Some(prof) = self.profile.lock().await.as_ref() { if let Ok(prof) = self.profile.lock()
&& let Some(prof) = prof.as_ref()
{
nbt.put_compound("profile", prof.clone()); nbt.put_compound("profile", prof.clone());
} }
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {
@ -72,8 +70,8 @@ impl SkullBlockEntity {
pub const fn new(position: BlockPos) -> Self { pub const fn new(position: BlockPos) -> Self {
Self { Self {
position, position,
note_block_sound: Mutex::const_new(None), note_block_sound: Mutex::new(None),
profile: Mutex::const_new(None), profile: Mutex::new(None),
} }
} }
} }

View File

@ -1,8 +1,7 @@
use super::BlockEntity; use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::pin::Pin; use std::sync::Mutex;
use tokio::sync::Mutex;
pub struct StructureBlockBlockEntity { pub struct StructureBlockBlockEntity {
pub position: BlockPos, pub position: BlockPos,
@ -60,29 +59,58 @@ impl BlockEntity for StructureBlockBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(name) = self.name.lock() {
nbt: &'a mut NbtCompound, nbt.put_string("name", name.clone());
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { }
Box::pin(async move { if let Ok(author) = self.author.lock() {
nbt.put_string("name", self.name.lock().await.clone()); nbt.put_string("author", author.clone());
nbt.put_string("author", self.author.lock().await.clone()); }
nbt.put_string("metadata", self.metadata.lock().await.clone()); if let Ok(metadata) = self.metadata.lock() {
nbt.put_int("posX", *self.pos_x.lock().await); nbt.put_string("metadata", metadata.clone());
nbt.put_int("posY", *self.pos_y.lock().await); }
nbt.put_int("posZ", *self.pos_z.lock().await); if let Ok(pos_x) = self.pos_x.lock() {
nbt.put_int("sizeX", *self.size_x.lock().await); nbt.put_int("posX", *pos_x);
nbt.put_int("sizeY", *self.size_y.lock().await); }
nbt.put_int("sizeZ", *self.size_z.lock().await); if let Ok(pos_y) = self.pos_y.lock() {
nbt.put_string("rotation", self.rotation.lock().await.clone()); nbt.put_int("posY", *pos_y);
nbt.put_string("mirror", self.mirror.lock().await.clone()); }
nbt.put_string("mode", self.mode.lock().await.clone()); if let Ok(pos_z) = self.pos_z.lock() {
nbt.put_bool("ignoreEntities", *self.ignore_entities.lock().await); nbt.put_int("posZ", *pos_z);
nbt.put_bool("showAir", *self.show_air.lock().await); }
nbt.put_bool("showBoundingBox", *self.show_bounding_box.lock().await); if let Ok(size_x) = self.size_x.lock() {
nbt.put_float("integrity", *self.integrity.lock().await); nbt.put_int("sizeX", *size_x);
nbt.put_long("seed", *self.seed.lock().await); }
}) if let Ok(size_y) = self.size_y.lock() {
nbt.put_int("sizeY", *size_y);
}
if let Ok(size_z) = self.size_z.lock() {
nbt.put_int("sizeZ", *size_z);
}
if let Ok(rotation) = self.rotation.lock() {
nbt.put_string("rotation", rotation.clone());
}
if let Ok(mirror) = self.mirror.lock() {
nbt.put_string("mirror", mirror.clone());
}
if let Ok(mode) = self.mode.lock() {
nbt.put_string("mode", mode.clone());
}
if let Ok(ignore_entities) = self.ignore_entities.lock() {
nbt.put_bool("ignoreEntities", *ignore_entities);
}
if let Ok(show_air) = self.show_air.lock() {
nbt.put_bool("showAir", *show_air);
}
if let Ok(show_bounding_box) = self.show_bounding_box.lock() {
nbt.put_bool("showBoundingBox", *show_bounding_box);
}
if let Ok(integrity) = self.integrity.lock() {
nbt.put_float("integrity", *integrity);
}
if let Ok(seed) = self.seed.lock() {
nbt.put_long("seed", *seed);
}
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {

View File

@ -1,5 +1,3 @@
use std::pin::Pin;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
@ -25,12 +23,7 @@ impl BlockEntity for TestBlockBlockEntity {
Self { position } Self { position }
} }
fn write_nbt<'a>( fn write_nbt(&self, _nbt: &mut NbtCompound) {}
&'a self,
_nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async {})
}
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self

View File

@ -1,5 +1,3 @@
use std::pin::Pin;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
@ -25,12 +23,7 @@ impl BlockEntity for TestInstanceBlockBlockEntity {
Self { position } Self { position }
} }
fn write_nbt<'a>( fn write_nbt(&self, _nbt: &mut NbtCompound) {}
&'a self,
_nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async {})
}
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
self self

View File

@ -1,8 +1,7 @@
use super::BlockEntity; use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::pin::Pin; use std::sync::Mutex;
use tokio::sync::Mutex;
pub struct TrialSpawnerBlockEntity { pub struct TrialSpawnerBlockEntity {
pub position: BlockPos, pub position: BlockPos,
@ -32,21 +31,22 @@ impl BlockEntity for TrialSpawnerBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(cfg) = self.normal_config.lock()
nbt: &'a mut NbtCompound, && let Some(cfg) = cfg.as_ref()
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { {
Box::pin(async move {
if let Some(cfg) = self.normal_config.lock().await.as_ref() {
nbt.put_compound("normal_config", cfg.clone()); nbt.put_compound("normal_config", cfg.clone());
} }
if let Some(cfg) = self.ominous_config.lock().await.as_ref() { if let Ok(cfg) = self.ominous_config.lock()
&& let Some(cfg) = cfg.as_ref()
{
nbt.put_compound("ominous_config", cfg.clone()); nbt.put_compound("ominous_config", cfg.clone());
} }
if let Some(data) = self.spawner_data.lock().await.as_ref() { if let Ok(data) = self.spawner_data.lock()
&& let Some(data) = data.as_ref()
{
nbt.put_compound("spawner_data", data.clone()); nbt.put_compound("spawner_data", data.clone());
} }
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {
@ -77,12 +77,12 @@ impl BlockEntity for TrialSpawnerBlockEntity {
impl TrialSpawnerBlockEntity { impl TrialSpawnerBlockEntity {
pub const ID: &'static str = "minecraft:trial_spawner"; pub const ID: &'static str = "minecraft:trial_spawner";
#[must_use] #[must_use]
pub const fn new(position: BlockPos) -> Self { pub fn new(position: BlockPos) -> Self {
Self { Self {
position, position,
normal_config: Mutex::const_new(None), normal_config: Mutex::new(None),
ominous_config: Mutex::const_new(None), ominous_config: Mutex::new(None),
spawner_data: Mutex::const_new(None), spawner_data: Mutex::new(None),
} }
} }
} }

View File

@ -2,8 +2,7 @@ use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound; use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos; use pumpkin_util::math::position::BlockPos;
use std::collections::HashSet; use std::collections::HashSet;
use std::pin::Pin; use std::sync::Mutex;
use tokio::sync::Mutex;
use uuid::Uuid; use uuid::Uuid;
pub struct VaultBlockEntity { pub struct VaultBlockEntity {
@ -34,18 +33,17 @@ impl BlockEntity for VaultBlockEntity {
} }
} }
fn write_nbt<'a>( fn write_nbt(&self, nbt: &mut NbtCompound) {
&'a self, if let Ok(cfg) = self.config.lock()
nbt: &'a mut NbtCompound, && let Some(cfg) = cfg.as_ref()
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> { {
Box::pin(async move {
if let Some(cfg) = self.config.lock().await.as_ref() {
nbt.put_compound("config", cfg.clone()); nbt.put_compound("config", cfg.clone());
} }
if let Some(data) = self.server_data.lock().await.as_ref() { if let Ok(data) = self.server_data.lock()
&& let Some(data) = data.as_ref()
{
nbt.put_compound("server_data", data.clone()); nbt.put_compound("server_data", data.clone());
} }
})
} }
fn chunk_data_nbt(&self) -> Option<NbtCompound> { fn chunk_data_nbt(&self) -> Option<NbtCompound> {
@ -82,10 +80,16 @@ impl VaultBlockEntity {
} }
pub fn has_rewarded(&self, player_id: &Uuid) -> bool { pub fn has_rewarded(&self, player_id: &Uuid) -> bool {
self.rewarded_players.blocking_lock().contains(player_id) self.rewarded_players
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.contains(player_id)
} }
pub fn mark_rewarded(&self, player_id: Uuid) { pub fn mark_rewarded(&self, player_id: Uuid) {
self.rewarded_players.blocking_lock().insert(player_id); self.rewarded_players
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.insert(player_id);
} }
} }

View File

@ -180,11 +180,7 @@ impl CommandExecutor for CloneExecutor {
if should_clone { if should_clone {
let block_entity_nbt = world.get_block_entity(&src_pos).map(|be| { let block_entity_nbt = world.get_block_entity(&src_pos).map(|be| {
let mut nbt = NbtCompound::new(); let mut nbt = NbtCompound::new();
if let Ok(handle) = tokio::runtime::Handle::try_current() { be.write_internal(&mut nbt);
tokio::task::block_in_place(|| {
handle.block_on(be.write_internal(&mut nbt));
});
}
nbt nbt
}); });

View File

@ -2441,7 +2441,7 @@ impl Player {
if player_pos != target_pos { if player_pos != target_pos {
self.living_entity.entity.set_pos(target_pos); self.living_entity.entity.set_pos(target_pos);
if let Some(p) = self.world().get_player_by_uuid(self.gameprofile.id) { if let Some(p) = self.world().get_player_by_uuid(self.gameprofile.id) {
tokio::spawn(async move { server.runtime.spawn(async move {
crate::world::chunker::update_position(&p).await; crate::world::chunker::update_position(&p).await;
}); });
} }
@ -2515,7 +2515,7 @@ impl Player {
&& !chunk_of_chunks.is_empty() && !chunk_of_chunks.is_empty()
{ {
let client = self.client.clone(); let client = self.client.clone();
tokio::spawn(async move { server.runtime.spawn(async move {
client.send_chunks(&chunk_of_chunks).await; client.send_chunks(&chunk_of_chunks).await;
}); });
if let ClientPlatform::Bedrock(bedrock_client) = self.client.as_ref() if let ClientPlatform::Bedrock(bedrock_client) = self.client.as_ref()
@ -2550,7 +2550,7 @@ impl Player {
{ {
let world_clone = p.world(); let world_clone = p.world();
let server_clone = world_clone.server.upgrade(); let server_clone = world_clone.server.upgrade();
tokio::spawn(async move { server.runtime.spawn(async move {
let pos = *p.mining_pos.lock().await; let pos = *p.mining_pos.lock().await;
let world = p.world(); let world = p.world();
let state = world.get_block_state(&pos); let state = world.get_block_state(&pos);

View File

@ -426,18 +426,14 @@ impl PlayerAdvancement {
result = true; result = true;
self.progress_changed.insert(advancement); self.progress_changed.insert(advancement);
if !was_done && progress.is_done() { if !was_done && progress.is_done() {
let player_c = player.clone(); if let Some(server) = player.world().server.upgrade() {
let adv_id = advancement.id.to_string();
tokio::spawn(async move {
if let Some(server) = player_c.world().server.upgrade() {
let mut event = let mut event =
crate::plugin::api::events::player::player_advancement_done::PlayerAdvancementDoneEvent::new( crate::plugin::api::events::player::player_advancement_done::PlayerAdvancementDoneEvent::new(
player_c, player.clone(),
adv_id, advancement.id.to_string(),
); );
server.plugin_manager.fire(&server, &mut event).await; server.plugin_manager.fire_blocking(&server, &mut event);
} }
});
Self::grant_reward(&player, advancement.reward); Self::grant_reward(&player, advancement.reward);
if let Some(display) = advancement.display if let Some(display) = advancement.display
&& display.announce_to_chat && display.announce_to_chat
@ -448,7 +444,6 @@ impl PlayerAdvancement {
.game_rules .game_rules
.show_advancement_messages .show_advancement_messages
{ {
tokio::spawn(async move {
let player_name = player.get_display_name(); let player_name = player.get_display_name();
let je_component = TextComponent::translate( let je_component = TextComponent::translate(
display.frame_type.get_translation(), display.frame_type.get_translation(),
@ -465,7 +460,6 @@ impl PlayerAdvancement {
); );
player.world().broadcast_editioned(&je_packet, &be_packet); player.world().broadcast_editioned(&je_packet, &be_packet);
});
} }
} }
} }

View File

@ -519,13 +519,9 @@ impl EntityBase for ArrowEntity {
let is_spectral = entity.entity_type.id == EntityType::SPECTRAL_ARROW.id; let is_spectral = entity.entity_type.id == EntityType::SPECTRAL_ARROW.id;
let entity_type: &'static EntityType = entity.entity_type; let entity_type: &'static EntityType = entity.entity_type;
let owner_id = self.owner_id; let owner_id = self.owner_id;
let target_clone = target.clone();
let world_clone = world.clone();
let pierce = self.pierce_level.load(Ordering::Relaxed); let pierce = self.pierce_level.load(Ordering::Relaxed);
let damage_succeeded = target.damage_with_context(
tokio::spawn(async move { target.as_ref(),
let damage_succeeded = target_clone.damage_with_context(
&*target_clone,
damage as f32, damage as f32,
DamageType::ARROW, DamageType::ARROW,
Some(hit_pos), Some(hit_pos),
@ -533,14 +529,14 @@ impl EntityBase for ArrowEntity {
None, None,
); );
if let Some(living) = target_clone.get_living_entity() { if let Some(living) = target.get_living_entity() {
if punch > 0 if punch > 0
&& let Some(owner_id) = owner_id && let Some(owner_id) = owner_id
&& let Some(owner_entity) = world_clone.get_entity_by_id(owner_id) && let Some(owner_entity) = world.get_entity_by_id(owner_id)
{ {
crate::entity::combat::handle_knockback( crate::entity::combat::handle_knockback(
owner_entity.get_entity(), owner_entity.get_entity(),
target_clone.as_ref(), target.as_ref(),
f64::from(punch) * 0.6, f64::from(punch) * 0.6,
); );
} }
@ -554,7 +550,7 @@ impl EntityBase for ArrowEntity {
1.0, 1.0,
0.0, 0.0,
); );
world_clone.broadcast_packet_all(&sound_packet); world.broadcast_packet_all(&sound_packet);
if Self::should_apply_post_hurt_effects(damage_succeeded) { if Self::should_apply_post_hurt_effects(damage_succeeded) {
let item_stack = ItemStack::new(1, Self::default_item(entity_type)); let item_stack = ItemStack::new(1, Self::default_item(entity_type));
@ -563,9 +559,7 @@ impl EntityBase for ArrowEntity {
.map_or(1.0, |component| component.scale); .map_or(1.0, |component| component.scale);
crate::item::potion::PotionContents::apply_effects_to( crate::item::potion::PotionContents::apply_effects_to(
living, living,
crate::item::potion::PotionContents::read_potion_effects( crate::item::potion::PotionContents::read_potion_effects(&item_stack),
&item_stack,
),
scale, scale,
crate::item::potion::PotionApplicationSource::Arrow, crate::item::potion::PotionApplicationSource::Arrow,
); );
@ -575,7 +569,6 @@ impl EntityBase for ArrowEntity {
} }
} }
} }
});
// Check pierce level // Check pierce level
if pierce == 0 { if pierce == 0 {

View File

@ -730,13 +730,9 @@ impl EntityBase for MinecartEntity {
if let Some(container) = self.container() if let Some(container) = self.container()
&& container.claim_drops() && container.claim_drops()
{ {
let container_clone = container.clone(); container.unpack_loot();
let world_clone = self.vehicle.entity.world.load_full(); let inventory: Arc<dyn Inventory> = container.clone();
container_clone.unpack_loot(); world.scatter_inventory(&position, &inventory);
tokio::spawn(async move {
let inventory: Arc<dyn Inventory> = container_clone;
world_clone.scatter_inventory(&position, &inventory);
});
} }
if let Some(item) = self.drop_item() { if let Some(item) = self.drop_item() {
world.drop_stack(&position, ItemStack::new(1, item)); world.drop_stack(&position, ItemStack::new(1, item));

View File

@ -42,18 +42,15 @@ impl HopperMinecart {
let world = entity.world.load(); let world = entity.world.load();
let pos = entity.pos.load(); let pos = entity.pos.load();
let source_pos = BlockPos::floored(pos.x, pos.y + 1.5, pos.z); let source_pos = BlockPos::floored(pos.x, pos.y + 1.5, pos.z);
let inventory = self.inventory.clone(); let inventory = &self.inventory;
let cart_box = entity.bounding_box.load().expand(0.25, 0.0, 0.25); let cart_box = entity.bounding_box.load().expand(0.25, 0.0, 0.25);
let world_clone = world.clone();
tokio::spawn(async move { if let Some(block_entity) = world.get_block_entity(&source_pos)
if let Some(block_entity) = world_clone.get_block_entity(&source_pos)
&& let Some(source) = block_entity.get_inventory() && let Some(source) = block_entity.get_inventory()
{ {
for slot in 0..source.size() { for slot in 0..source.size() {
let stack = source.get_stack(slot); let stack = source.get_stack(slot);
if stack.is_empty() || !source.can_transfer_to(inventory.as_ref(), slot, &stack) if stack.is_empty() || !source.can_transfer_to(inventory.as_ref(), slot, &stack) {
{
continue; continue;
} }
let backup = stack.clone(); let backup = stack.clone();
@ -70,11 +67,10 @@ impl HopperMinecart {
Vector3::new(pos.x - 0.5, pos.y + 0.6875, pos.z - 0.5), Vector3::new(pos.x - 0.5, pos.y + 0.6875, pos.z - 0.5),
Vector3::new(pos.x + 0.5, pos.y + 2.0, pos.z + 0.5), Vector3::new(pos.x + 0.5, pos.y + 2.0, pos.z + 0.5),
); );
if Self::pick_up_item_internal(&world_clone, &inventory, &suction_box) { if Self::pick_up_item_internal(&world, inventory, &suction_box) {
return; return;
} }
Self::pick_up_item_internal(&world_clone, &inventory, &cart_box); Self::pick_up_item_internal(&world, inventory, &cart_box);
});
} }
fn pick_up_item_internal( fn pick_up_item_internal(

View File

@ -42,9 +42,9 @@ impl VehicleEntity {
self.entity.entity_id, self.entity.entity_id,
); );
if let Some(server) = self.entity.world.load().server.upgrade() { if let Some(server) = self.entity.world.load().server.upgrade() {
tokio::spawn(async move { server
server.plugin_manager.fire(&server, &mut update_event).await; .plugin_manager
}); .fire_blocking(&server, &mut update_event);
} }
} }

View File

@ -22,11 +22,28 @@ impl JavaClient {
return; return;
}; };
*jigsaw_block.name.lock().await = jigsaw.name.to_string(); *jigsaw_block
*jigsaw_block.target.lock().await = jigsaw.target.to_string(); .name
*jigsaw_block.pool.lock().await = jigsaw.pool.to_string(); .lock()
*jigsaw_block.final_state.lock().await = jigsaw.final_state.to_string(); .unwrap_or_else(std::sync::PoisonError::into_inner) = jigsaw.name.to_string();
*jigsaw_block.joint.lock().await = JigsawJointType::from_str(jigsaw.joint); *jigsaw_block
.target
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner) = jigsaw.target.to_string();
*jigsaw_block
.pool
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner) = jigsaw.pool.to_string();
*jigsaw_block
.final_state
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner) =
jigsaw.final_state.to_string();
*jigsaw_block
.joint
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner) =
JigsawJointType::from_str(jigsaw.joint);
jigsaw_block jigsaw_block
.selection_priority .selection_priority
.store(jigsaw.selection_priority.0, Ordering::SeqCst); .store(jigsaw.selection_priority.0, Ordering::SeqCst);

View File

@ -18,7 +18,7 @@ impl JavaClient {
let mut compound = NbtCompound::new(); let mut compound = NbtCompound::new();
if let Some(block_entity) = player.world().get_block_entity(&packet.location) { if let Some(block_entity) = player.world().get_block_entity(&packet.location) {
block_entity.write_nbt(&mut compound).await; block_entity.write_nbt(&mut compound);
} }
let nbt_bytes = Nbt::new(String::new(), compound).write_unnamed(); let nbt_bytes = Nbt::new(String::new(), compound).write_unnamed();

View File

@ -1225,7 +1225,7 @@ impl pumpkin::plugin::world::HostWorld for PluginHostState {
}; };
let mut nbt = pumpkin_nbt::NbtCompound::new(); let mut nbt = pumpkin_nbt::NbtCompound::new();
entity.write_internal(&mut nbt).await; entity.write_internal(&mut nbt);
let bytes = pumpkin_nbt::Nbt::from(nbt).write_unnamed(); let bytes = pumpkin_nbt::Nbt::from(nbt).write_unnamed();
Ok(Some(bytes.to_vec())) Ok(Some(bytes.to_vec()))

View File

@ -1083,7 +1083,9 @@ impl Server {
all_players.extend(players.iter().cloned()); all_players.extend(players.iter().cloned());
} }
let handle = self.runtime.clone();
all_players.par_iter().for_each(|player| { all_players.par_iter().for_each(|player| {
let _guard = handle.enter();
player.tick(self); player.tick(self);
}); });
} }

View File

@ -481,7 +481,7 @@ impl World {
.map(|chunk_block_entities| *chunk_block_entities.key()) .map(|chunk_block_entities| *chunk_block_entities.key())
.collect(); .collect();
for chunk_pos in chunks { for chunk_pos in chunks {
self.save_block_entities(&chunk_pos).await; self.save_block_entities(&chunk_pos);
} }
// Save portal POI to disk // Save portal POI to disk
@ -520,7 +520,7 @@ impl World {
/// `get_block_entity` takes the saved NBT out of the chunk when it wakes an /// `get_block_entity` takes the saved NBT out of the chunk when it wakes an
/// entity up - so this has to run before the chunk is dropped, or everything /// entity up - so this has to run before the chunk is dropped, or everything
/// the entity did since it was loaded is lost. /// the entity did since it was loaded is lost.
async fn save_block_entities(&self, chunk_pos: &Vector2<i32>) { fn save_block_entities(&self, chunk_pos: &Vector2<i32>) {
let Some(block_entities) = self let Some(block_entities) = self
.block_entities .block_entities
.get(chunk_pos) .get(chunk_pos)
@ -531,7 +531,7 @@ impl World {
for block_entity in block_entities { for block_entity in block_entities {
let mut nbt = NbtCompound::new(); let mut nbt = NbtCompound::new();
block_entity.write_internal(&mut nbt).await; block_entity.write_internal(&mut nbt);
if let Some(custom_data) = self if let Some(custom_data) = self
.custom_block_entity_data .custom_block_entity_data
.get(&block_entity.get_position()) .get(&block_entity.get_position())
@ -1238,7 +1238,9 @@ impl World {
); );
let t_players = std::time::Instant::now(); let t_players = std::time::Instant::now();
let player_handle = handle.clone();
players.par_iter().for_each(|player| { players.par_iter().for_each(|player| {
let _guard = player_handle.enter();
player.tick(server); player.tick(server);
}); });
let player_elapsed = t_players.elapsed(); let player_elapsed = t_players.elapsed();
@ -1664,7 +1666,7 @@ impl World {
// 3. Parallel Random Ticks via Rayon // 3. Parallel Random Ticks via Rayon
let world = self.clone(); let world = self.clone();
let random_handle = handle; let random_handle = handle.clone();
tick_data tick_data
.random_ticks .random_ticks
.par_chunks(BATCH_SIZE) .par_chunks(BATCH_SIZE)
@ -1737,7 +1739,9 @@ impl World {
spawning_chunks.shuffle(&mut rng()); spawning_chunks.shuffle(&mut rng());
let world = self.clone(); let world = self.clone();
let spawn_handle = handle.clone();
spawning_chunks.par_chunks(8).for_each(|batch| { spawning_chunks.par_chunks(8).for_each(|batch| {
let _guard = spawn_handle.enter();
let world = world.clone(); let world = world.clone();
let s_list = spawn_list.clone(); let s_list = spawn_list.clone();
let s_state = spawn_state.clone(); let s_state = spawn_state.clone();
@ -4930,7 +4934,7 @@ impl World {
} }
for chunk_pos in &chunks_set { for chunk_pos in &chunks_set {
self.save_block_entities(chunk_pos).await; self.save_block_entities(chunk_pos);
self.block_entities.remove(chunk_pos); self.block_entities.remove(chunk_pos);
} }
} }
@ -6423,7 +6427,7 @@ impl World {
.map(|chunk_block_entities| *chunk_block_entities.key()) .map(|chunk_block_entities| *chunk_block_entities.key())
.collect(); .collect();
for chunk_pos in chunks { for chunk_pos in chunks {
self.save_block_entities(&chunk_pos).await; self.save_block_entities(&chunk_pos);
} }
if let Ok(mut portal_poi) = self.portal_poi.try_lock() { if let Ok(mut portal_poi) = self.portal_poi.try_lock() {