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 {
let player = Arc::clone(args.player);
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
Self::use_bed(args.world, args.player, args.block, args.position)
}
}
impl BedBlock {
#[expect(clippy::too_many_lines)]
async fn use_bed(
fn use_bed(
world: &Arc<World>,
player: &Arc<Player>,
block: &Block,
@ -341,7 +333,7 @@ impl BedBlock {
player.clone(),
bed_head_pos,
);
server.plugin_manager.fire(&server, &mut event).await;
server.plugin_manager.fire_blocking(&server, &mut event);
if event.cancelled {
return BlockActionResult::SuccessServer;
}

View File

@ -30,11 +30,18 @@ impl BrushableBlock {
if let Some(be) = world.get_block_entity(pos)
&& 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;
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 {
world.drop_stack(pos, item_stack);
}
@ -84,7 +91,11 @@ impl BlockBehaviour for BrushableBlock {
fn broken(&self, args: BrokenArgs<'_>) {
if let Some(be) = args.world.get_block_entity(args.position)
&& 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);
}

View File

@ -174,11 +174,8 @@ impl BlockBehaviour for DispenserBlock {
}
fn on_scheduled_tick(&self, args: OnScheduledTickArgs<'_>) {
let world = args.world.clone();
let position = *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 (block, state) = args.world.get_block_and_state(args.position);
if let Some(block_entity) = args.world.get_block_entity(args.position) {
let Some(dispenser) = block_entity.as_any().downcast_ref::<DispenserBlockEntity>()
else {
return;
@ -187,17 +184,17 @@ impl BlockBehaviour for DispenserBlock {
if let Some((slot_index, mut item)) = dispenser.get_random_slot() {
let props = DispenserLikeProperties::from_state_id(state.id, block);
let ctx = DispenseContext {
world: &world,
position: &position,
world: args.world,
position: args.position,
facing: props.facing,
};
Self::dispense(&ctx, dispenser, &mut item).await;
Self::dispense(&ctx, dispenser, &mut item);
dispenser.set_stack(slot_index, item);
} 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> {
@ -225,17 +222,13 @@ impl DispenserBlock {
const FIREWORK_PROJECTILE_POWER: f64 = 0.5;
const FIREWORK_PROJECTILE_UNCERTAINTY: f64 = 1.0;
async fn dispense(
ctx: &DispenseContext<'_>,
dispenser: &DispenserBlockEntity,
item: &mut ItemStack,
) {
fn dispense(ctx: &DispenseContext<'_>, dispenser: &DispenserBlockEntity, item: &mut ItemStack) {
let mut event = crate::plugin::api::events::block::block_dispense::BlockDispenseEvent::new(
*ctx.position,
item.item.registry_key.to_string(),
);
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 {
ctx.world

View File

@ -135,22 +135,20 @@ impl BlockBehaviour for DropperBlock {
}
fn on_scheduled_tick(&self, args: OnScheduledTickArgs<'_>) {
let world = args.world.clone();
let position = *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(dropper) = block_entity.as_any().downcast_ref::<DropperBlockEntity>()
else {
let (block, state) = args.world.get_block_and_state(args.position);
if let Some(block_entity) = args.world.get_block_entity(args.position) {
let Some(dropper) = block_entity.as_any().downcast_ref::<DropperBlockEntity>() else {
return;
};
if let Some((slot_index, mut item)) = dropper.get_random_slot() {
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 backup = item.clone();
@ -169,14 +167,14 @@ impl BlockBehaviour for DropperBlock {
let drop_item = item.split(1);
dropper.set_stack(slot_index, item);
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 {
Facing::Up | Facing::Down => 0.125,
_ => 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 velocity = Vector3::new(
@ -188,20 +186,21 @@ impl BlockBehaviour for DropperBlock {
let item_entity = Arc::new(ItemEntity::new_with_velocity(
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,
position,
*args.position,
to_data3d(props.facing),
);
} 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> {

View File

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

View File

@ -42,7 +42,10 @@ impl SculkSensorBlock {
if let Some(be) = world.get_block_entity(pos)
&& 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;
@ -73,7 +76,10 @@ impl SculkSensorBlock {
.as_any()
.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;
@ -136,13 +142,23 @@ impl BlockBehaviour for SculkSensorBlock {
fn get_comparator_output(&self, args: GetComparatorOutputArgs<'_>) -> Option<u8> {
let be = args.world.get_block_entity(args.position)?;
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
.as_any()
.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
}

View File

@ -68,7 +68,10 @@ impl SculkShriekerBlock {
if let Some(entity) = world.get_block_entity(pos)
&& 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);
if props.can_summon && *level >= 4 {
// TODO: spawn Warden near pos

View File

@ -2,8 +2,7 @@ use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound;
use pumpkin_nbt::tag::NbtTag;
use pumpkin_util::math::position::BlockPos;
use std::pin::Pin;
use tokio::sync::Mutex;
use std::sync::Mutex;
pub struct BannerBlockEntity {
pub position: BlockPos,
@ -33,18 +32,17 @@ impl BlockEntity for BannerBlockEntity {
}
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
if let Some(name) = self.custom_name.lock().await.as_ref() {
fn write_nbt(&self, nbt: &mut NbtCompound) {
if let Ok(name) = self.custom_name.lock()
&& let Some(name) = name.as_ref()
{
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());
}
})
}
fn chunk_data_nbt(&self) -> Option<NbtCompound> {
@ -73,8 +71,8 @@ impl BannerBlockEntity {
pub const fn new(position: BlockPos) -> Self {
Self {
position,
custom_name: Mutex::const_new(None),
patterns: Mutex::const_new(None),
custom_name: Mutex::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::{RandomImpl, get_seed};
use std::any::Any;
use std::pin::Pin;
use std::sync::RwLock;
use std::{
array::from_fn,
@ -63,13 +62,8 @@ impl BlockEntity for BarrelBlockEntity {
barrel
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
fn write_nbt(&self, nbt: &mut NbtCompound) {
self.write_inventory_nbt(nbt, true);
})
}
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::tag::Taggable;
use std::any::Any;
use std::pin::Pin;
use std::sync::atomic::{AtomicBool, AtomicI32, Ordering};
use std::sync::{Arc, Mutex};
@ -262,11 +260,7 @@ impl BlockEntity for BeaconBlockEntity {
}
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
fn write_nbt(&self, nbt: &mut NbtCompound) {
nbt.put_int(
"primary_effect",
self.primary_effect.load(Ordering::Relaxed),
@ -291,7 +285,6 @@ impl BlockEntity for BeaconBlockEntity {
{
nbt.put_string("Lock", lock.clone());
}
})
}
fn tick(&self, world: &Arc<World>) {

View File

@ -1,5 +1,3 @@
use std::pin::Pin;
use pumpkin_data::{
BlockState, BlockStateId,
item::JavaToBedrockItemMapping,
@ -30,12 +28,7 @@ impl BlockEntity for BedBlockEntity {
Self { position }
}
fn write_nbt<'a>(
&'a self,
_nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async {})
}
fn write_nbt(&self, _nbt: &mut NbtCompound) {}
fn bedrock_block_actor_data(&self, state_id: BlockStateId) -> Option<NbtCompound> {
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::tag::NbtTag;
use pumpkin_util::math::position::BlockPos;
use std::pin::Pin;
use tokio::sync::Mutex;
use std::sync::Mutex;
pub struct BeehiveBlockEntity {
pub position: BlockPos,
@ -39,22 +38,21 @@ impl BlockEntity for BeehiveBlockEntity {
}
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
if let Some(b) = self.bees.lock().await.as_ref() {
fn write_nbt(&self, nbt: &mut NbtCompound) {
if let Ok(b) = self.bees.lock()
&& let Some(b) = b.as_ref()
{
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();
fp_nbt.put_int("X", fp.0.x);
fp_nbt.put_int("Y", fp.0.y);
fp_nbt.put_int("Z", fp.0.z);
nbt.put_compound("FlowerPos", fp_nbt);
}
})
}
fn chunk_data_nbt(&self) -> Option<NbtCompound> {
@ -87,8 +85,8 @@ impl BeehiveBlockEntity {
pub const fn new(position: BlockPos) -> Self {
Self {
position,
bees: Mutex::const_new(None),
flower_pos: Mutex::const_new(None),
bees: Mutex::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_util::math::position::BlockPos;
use std::any::Any;
use std::pin::Pin;
use std::sync::Arc;
pub struct BellBlockEntity {
@ -47,12 +46,7 @@ impl BellBlockEntity {
}
impl BlockEntity for BellBlockEntity {
fn write_nbt<'a>(
&'a self,
_nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {})
}
fn write_nbt(&self, _nbt: &mut NbtCompound) {}
fn from_nbt(_nbt: &NbtCompound, position: BlockPos) -> Self
where

View File

@ -1,6 +1,4 @@
use std::any::Any;
use std::future::Future;
use std::pin::Pin;
use std::sync::{
Arc, Mutex as StdMutex, RwLock,
atomic::AtomicI32,
@ -401,18 +399,13 @@ impl crate::block::entities::BlockEntity for BrewingStandBlockEntity {
entity
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
fn write_nbt(&self, nbt: &mut NbtCompound) {
// Persist brew state
nbt.put_int("BrewTime", self.brew_time.load(Ordering::Relaxed));
nbt.put_int("Fuel", self.fuel.load(Ordering::Relaxed));
// Save inventory contents to NBT
self.write_inventory_nbt(nbt, true);
})
}
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_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos;
use std::pin::Pin;
use tokio::sync::Mutex;
use std::sync::Mutex;
pub struct BrushableBlockBlockEntity {
pub position: BlockPos,
@ -38,19 +37,20 @@ impl BlockEntity for BrushableBlockBlockEntity {
}
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
if let Some(it) = self.item.lock().await.as_ref() {
fn write_nbt(&self, nbt: &mut NbtCompound) {
if let Ok(item) = self.item.lock()
&& let Some(it) = item.as_ref()
{
let mut it_nbt = NbtCompound::new();
it.write_item_stack(&mut it_nbt);
nbt.put_compound("item", it_nbt);
}
nbt.put_int("hits", *self.hits.lock().await);
nbt.put_byte("direction", *self.direction.lock().await as i8);
})
if let Ok(hits) = self.hits.lock() {
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> {
@ -78,9 +78,9 @@ impl BrushableBlockBlockEntity {
pub const fn new(position: BlockPos) -> Self {
Self {
position,
item: Mutex::const_new(None),
hits: Mutex::const_new(0),
direction: Mutex::const_new(0),
item: Mutex::new(None),
hits: Mutex::new(0),
direction: Mutex::new(0),
}
}
}

View File

@ -1,8 +1,7 @@
use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos;
use std::pin::Pin;
use tokio::sync::Mutex;
use std::sync::Mutex;
pub struct CalibratedSculkSensorBlockEntity {
pub position: BlockPos,
@ -29,16 +28,10 @@ impl BlockEntity for CalibratedSculkSensorBlockEntity {
}
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
nbt.put_int(
"last_vibration_frequency",
*self.last_vibration_frequency.lock().await,
);
})
fn write_nbt(&self, nbt: &mut NbtCompound) {
if let Ok(freq) = self.last_vibration_frequency.lock() {
nbt.put_int("last_vibration_frequency", *freq);
}
}
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::tag::NbtTag;
use pumpkin_util::math::position::BlockPos;
use std::pin::Pin;
use std::sync::Arc;
use tokio::sync::Mutex;
use std::sync::{Arc, Mutex};
pub struct CampfireBlockEntity {
pub position: BlockPos,
pub items: [Arc<Mutex<ItemStack>>; 4],
pub cooking_times: [tokio::sync::Mutex<i32>; 4],
pub cooking_total_times: [tokio::sync::Mutex<i32>; 4],
pub cooking_times: [Mutex<i32>; 4],
pub cooking_total_times: [Mutex<i32>; 4],
}
impl BlockEntity for CampfireBlockEntity {
@ -61,15 +59,12 @@ impl BlockEntity for CampfireBlockEntity {
}
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
fn write_nbt(&self, nbt: &mut NbtCompound) {
let mut list = Vec::new();
for (i, item_mutex) in self.items.iter().enumerate() {
let stack = item_mutex.lock().await;
if !stack.is_empty() {
if let Ok(stack) = item_mutex.lock()
&& !stack.is_empty()
{
let mut item_nbt = NbtCompound::new();
item_nbt.put_byte("Slot", i as i8);
stack.write_item_stack(&mut item_nbt);
@ -80,16 +75,19 @@ impl BlockEntity for CampfireBlockEntity {
let mut times = Vec::new();
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));
let mut total_times = Vec::new();
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));
})
}
fn as_any(&self) -> &dyn std::any::Any {

View File

@ -52,14 +52,9 @@ macro_rules! impl_block_entity_for_chest {
chest
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut pumpkin_nbt::compound::NbtCompound,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = ()> + Send + 'a>> {
fn write_nbt(&self, nbt: &mut pumpkin_nbt::compound::NbtCompound) {
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 guard = self
.loot_table
@ -78,7 +73,6 @@ macro_rules! impl_block_entity_for_chest {
// Loot has already been generated, so persist the actual items.
self.write_inventory_nbt(nbt, true);
}
})
}
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_util::math::position::BlockPos;
use std::any::Any;
use std::future::Future;
use std::pin::Pin;
use std::sync::RwLock;
use std::{
array::from_fn,
@ -66,11 +64,7 @@ impl BlockEntity for ChiseledBookshelfBlockEntity {
bookshelf
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
fn write_nbt(&self, nbt: &mut NbtCompound) {
let items = self
.items
.read()
@ -80,7 +74,6 @@ impl BlockEntity for ChiseledBookshelfBlockEntity {
LAST_INTERACTED_SLOT,
i32::from(self.last_interacted_slot.load(Ordering::Relaxed)),
);
})
}
fn get_inventory(self: Arc<Self>) -> Option<Arc<dyn Inventory>> {

View File

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

View File

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

View File

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

View File

@ -1,5 +1,3 @@
use std::pin::Pin;
use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos;
@ -25,12 +23,7 @@ impl BlockEntity for CopperGolemStatueBlockEntity {
Self { position }
}
fn write_nbt<'a>(
&'a self,
_nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async {})
}
fn write_nbt(&self, _nbt: &mut NbtCompound) {}
fn as_any(&self) -> &dyn std::any::Any {
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 std::any::Any;
use std::array::from_fn;
use std::pin::Pin;
use std::sync::Arc;
use std::sync::RwLock;
use std::sync::atomic::{AtomicBool, AtomicI32, Ordering};
@ -19,11 +18,7 @@ pub struct CrafterBlockEntity {
}
impl BlockEntity for CrafterBlockEntity {
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
fn write_nbt(&self, nbt: &mut NbtCompound) {
let items = self
.items
.read()
@ -34,7 +29,6 @@ impl BlockEntity for CrafterBlockEntity {
self.crafting_ticks_remaining.load(Ordering::Relaxed),
);
nbt.put_bool("triggered", self.triggered.load(Ordering::Relaxed));
})
}
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 crossbeam::atomic::AtomicCell;
@ -38,15 +37,10 @@ impl BlockEntity for CreakingHeartBlockEntity {
}
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
fn write_nbt(&self, nbt: &mut NbtCompound) {
if let Some(uuid) = self.creaking_uuid.load() {
nbt.put_string("creaking_uuid", uuid.to_string());
}
})
}
fn as_any(&self) -> &dyn std::any::Any {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -552,11 +552,7 @@ macro_rules! impl_block_entity_for_cooking {
furnace
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut pumpkin_nbt::compound::NbtCompound,
) -> std::pin::Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
fn write_nbt(&self, nbt: &mut pumpkin_nbt::compound::NbtCompound) {
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("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);
})
}
fn get_inventory(

View File

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

View File

@ -1,13 +1,9 @@
use rand::Rng;
use std::{
pin::Pin,
sync::{
Arc,
use std::sync::{
Arc, Mutex,
atomic::{AtomicBool, AtomicI32, Ordering},
},
};
use futures::Future;
use pumpkin_data::block_properties::{BlockProperties, JigsawLikeProperties, Orientation};
use pumpkin_nbt::compound::NbtCompound;
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::world::World;
@ -81,8 +75,16 @@ impl JigsawBlockEntity {
}
pub async fn generate(&self, world: &Arc<World>, levels: i32, keep_jigsaws: bool) {
let pool = self.pool.lock().await.clone();
let target = self.target.lock().await.clone();
let pool = self
.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 props =
@ -206,17 +208,22 @@ impl BlockEntity for JigsawBlockEntity {
}
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
nbt.put_string(Self::NAME, self.name.lock().await.clone());
nbt.put_string(Self::TARGET, self.target.lock().await.clone());
nbt.put_string(Self::POOL, self.pool.lock().await.clone());
nbt.put_string(Self::FINAL_STATE, self.final_state.lock().await.clone());
let joint = *self.joint.lock().await;
fn write_nbt(&self, nbt: &mut NbtCompound) {
if let Ok(name) = self.name.lock() {
nbt.put_string(Self::NAME, name.clone());
}
if let Ok(target) = self.target.lock() {
nbt.put_string(Self::TARGET, target.clone());
}
if let Ok(pool) = self.pool.lock() {
nbt.put_string(Self::POOL, pool.clone());
}
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_int(
Self::PLACEMENT_PRIORITY,
self.placement_priority.load(Ordering::SeqCst),
@ -225,7 +232,6 @@ impl BlockEntity for JigsawBlockEntity {
Self::SELECTION_PRIORITY,
self.selection_priority.load(Ordering::SeqCst),
);
})
}
fn chunk_data_nbt(&self) -> Option<NbtCompound> {

View File

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

View File

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

View File

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

View File

@ -1,9 +1,6 @@
use std::{
pin::Pin,
sync::{
use std::sync::{
Arc,
atomic::{AtomicI32, Ordering},
},
};
use crossbeam::atomic::AtomicCell;
@ -54,13 +51,7 @@ impl MobSpawnerBlockEntity {
}
}
pub fn write_nbt<'a>(&'a self, nbt: &'a 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);
pub fn write_spawner_nbt(&self, nbt: &mut NbtCompound) {
nbt.put_short("Delay", self.delay.load(Ordering::Relaxed) as i16);
nbt.put_short("MinSpawnDelay", self.min_delay as i16);
nbt.put_short("MaxSpawnDelay", self.max_delay as i16);
@ -264,13 +255,8 @@ impl BlockEntity for MobSpawnerBlockEntity {
}
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
self.write_nbt(nbt);
})
fn write_nbt(&self, nbt: &mut NbtCompound) {
self.write_spawner_nbt(nbt);
}
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
pub trait BlockEntity: Any + Send + Sync {
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>>;
fn write_nbt(&self, nbt: &mut NbtCompound);
fn from_nbt(nbt: &NbtCompound, position: BlockPos) -> Self
where
Self: Sized;
@ -95,18 +92,13 @@ pub trait BlockEntity: Any + Send + Sync {
false
}
fn write_internal<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
fn write_internal(&self, nbt: &mut NbtCompound) {
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);
self.write_nbt(nbt).await;
})
self.write_nbt(nbt);
}
fn get_id(&self) -> u32 {
let name = self
@ -462,7 +454,7 @@ mod test {
furnace.set_stack(0, ItemStack::new(5, &Item::DIAMOND));
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);
assert!(

View File

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

View File

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

View File

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

View File

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

View File

@ -1,8 +1,7 @@
use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos;
use std::pin::Pin;
use tokio::sync::Mutex;
use std::sync::Mutex;
pub struct SculkShriekerBlockEntity {
pub position: BlockPos,
@ -29,13 +28,10 @@ impl BlockEntity for SculkShriekerBlockEntity {
}
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
nbt.put_int("warning_level", *self.warning_level.lock().await);
})
fn write_nbt(&self, nbt: &mut NbtCompound) {
if let Ok(warning_level) = self.warning_level.lock() {
nbt.put_int("warning_level", *warning_level);
}
}
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 std::any::Any;
use std::array::from_fn;
use std::pin::Pin;
use std::sync::Arc;
use std::sync::RwLock;
use std::sync::atomic::{AtomicBool, Ordering};
@ -17,13 +16,8 @@ pub struct ShelfBlockEntity {
}
impl BlockEntity for ShelfBlockEntity {
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
fn write_nbt(&self, nbt: &mut NbtCompound) {
self.write_inventory_nbt(nbt, true);
})
}
fn from_nbt(nbt: &pumpkin_nbt::compound::NbtCompound, position: BlockPos) -> Self

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,8 +2,7 @@ use super::BlockEntity;
use pumpkin_nbt::compound::NbtCompound;
use pumpkin_util::math::position::BlockPos;
use std::collections::HashSet;
use std::pin::Pin;
use tokio::sync::Mutex;
use std::sync::Mutex;
use uuid::Uuid;
pub struct VaultBlockEntity {
@ -34,18 +33,17 @@ impl BlockEntity for VaultBlockEntity {
}
}
fn write_nbt<'a>(
&'a self,
nbt: &'a mut NbtCompound,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'a>> {
Box::pin(async move {
if let Some(cfg) = self.config.lock().await.as_ref() {
fn write_nbt(&self, nbt: &mut NbtCompound) {
if let Ok(cfg) = self.config.lock()
&& let Some(cfg) = cfg.as_ref()
{
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());
}
})
}
fn chunk_data_nbt(&self) -> Option<NbtCompound> {
@ -82,10 +80,16 @@ impl VaultBlockEntity {
}
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) {
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 {
let block_entity_nbt = world.get_block_entity(&src_pos).map(|be| {
let mut nbt = NbtCompound::new();
if let Ok(handle) = tokio::runtime::Handle::try_current() {
tokio::task::block_in_place(|| {
handle.block_on(be.write_internal(&mut nbt));
});
}
be.write_internal(&mut nbt);
nbt
});

View File

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

View File

@ -426,18 +426,14 @@ impl PlayerAdvancement {
result = true;
self.progress_changed.insert(advancement);
if !was_done && progress.is_done() {
let player_c = player.clone();
let adv_id = advancement.id.to_string();
tokio::spawn(async move {
if let Some(server) = player_c.world().server.upgrade() {
if let Some(server) = player.world().server.upgrade() {
let mut event =
crate::plugin::api::events::player::player_advancement_done::PlayerAdvancementDoneEvent::new(
player_c,
adv_id,
player.clone(),
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);
if let Some(display) = advancement.display
&& display.announce_to_chat
@ -448,7 +444,6 @@ impl PlayerAdvancement {
.game_rules
.show_advancement_messages
{
tokio::spawn(async move {
let player_name = player.get_display_name();
let je_component = TextComponent::translate(
display.frame_type.get_translation(),
@ -465,7 +460,6 @@ impl PlayerAdvancement {
);
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 entity_type: &'static EntityType = entity.entity_type;
let owner_id = self.owner_id;
let target_clone = target.clone();
let world_clone = world.clone();
let pierce = self.pierce_level.load(Ordering::Relaxed);
tokio::spawn(async move {
let damage_succeeded = target_clone.damage_with_context(
&*target_clone,
let damage_succeeded = target.damage_with_context(
target.as_ref(),
damage as f32,
DamageType::ARROW,
Some(hit_pos),
@ -533,14 +529,14 @@ impl EntityBase for ArrowEntity {
None,
);
if let Some(living) = target_clone.get_living_entity() {
if let Some(living) = target.get_living_entity() {
if punch > 0
&& 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(
owner_entity.get_entity(),
target_clone.as_ref(),
target.as_ref(),
f64::from(punch) * 0.6,
);
}
@ -554,7 +550,7 @@ impl EntityBase for ArrowEntity {
1.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) {
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);
crate::item::potion::PotionContents::apply_effects_to(
living,
crate::item::potion::PotionContents::read_potion_effects(
&item_stack,
),
crate::item::potion::PotionContents::read_potion_effects(&item_stack),
scale,
crate::item::potion::PotionApplicationSource::Arrow,
);
@ -575,7 +569,6 @@ impl EntityBase for ArrowEntity {
}
}
}
});
// Check pierce level
if pierce == 0 {

View File

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

View File

@ -42,18 +42,15 @@ impl HopperMinecart {
let world = entity.world.load();
let pos = entity.pos.load();
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 world_clone = world.clone();
tokio::spawn(async move {
if let Some(block_entity) = world_clone.get_block_entity(&source_pos)
if let Some(block_entity) = world.get_block_entity(&source_pos)
&& let Some(source) = block_entity.get_inventory()
{
for slot in 0..source.size() {
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;
}
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 + 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;
}
Self::pick_up_item_internal(&world_clone, &inventory, &cart_box);
});
Self::pick_up_item_internal(&world, inventory, &cart_box);
}
fn pick_up_item_internal(

View File

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

View File

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

View File

@ -18,7 +18,7 @@ impl JavaClient {
let mut compound = NbtCompound::new();
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();

View File

@ -1225,7 +1225,7 @@ impl pumpkin::plugin::world::HostWorld for PluginHostState {
};
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();
Ok(Some(bytes.to_vec()))

View File

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

View File

@ -481,7 +481,7 @@ impl World {
.map(|chunk_block_entities| *chunk_block_entities.key())
.collect();
for chunk_pos in chunks {
self.save_block_entities(&chunk_pos).await;
self.save_block_entities(&chunk_pos);
}
// 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
/// entity up - so this has to run before the chunk is dropped, or everything
/// 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
.block_entities
.get(chunk_pos)
@ -531,7 +531,7 @@ impl World {
for block_entity in block_entities {
let mut nbt = NbtCompound::new();
block_entity.write_internal(&mut nbt).await;
block_entity.write_internal(&mut nbt);
if let Some(custom_data) = self
.custom_block_entity_data
.get(&block_entity.get_position())
@ -1238,7 +1238,9 @@ impl World {
);
let t_players = std::time::Instant::now();
let player_handle = handle.clone();
players.par_iter().for_each(|player| {
let _guard = player_handle.enter();
player.tick(server);
});
let player_elapsed = t_players.elapsed();
@ -1664,7 +1666,7 @@ impl World {
// 3. Parallel Random Ticks via Rayon
let world = self.clone();
let random_handle = handle;
let random_handle = handle.clone();
tick_data
.random_ticks
.par_chunks(BATCH_SIZE)
@ -1737,7 +1739,9 @@ impl World {
spawning_chunks.shuffle(&mut rng());
let world = self.clone();
let spawn_handle = handle.clone();
spawning_chunks.par_chunks(8).for_each(|batch| {
let _guard = spawn_handle.enter();
let world = world.clone();
let s_list = spawn_list.clone();
let s_state = spawn_state.clone();
@ -4930,7 +4934,7 @@ impl World {
}
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);
}
}
@ -6423,7 +6427,7 @@ impl World {
.map(|chunk_block_entities| *chunk_block_entities.key())
.collect();
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() {