Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ index aa4e5a8977fd437780675b173397988e37303f46..118af4e35eec652e7eb8a484a44652cf
protected void onOpen(final Level level, final BlockPos pos, final BlockState state) {
BarrelBlockEntity.this.playSound(state, SoundEvents.BARREL_OPEN);
diff --git a/net/minecraft/world/level/block/entity/ChestBlockEntity.java b/net/minecraft/world/level/block/entity/ChestBlockEntity.java
index 06878204e0df42fc35cfa380413986a045ee229d..a9273aebb5c8efe78e88158f11e1ee2af0dff3f1 100644
index 58e532e913f360280f5bee461d1e86a63f4f76ed..13ba29eaaea8bdc8d8dff14a9504b7918006d9fc 100644
--- a/net/minecraft/world/level/block/entity/ChestBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/ChestBlockEntity.java
@@ -30,6 +30,13 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
Expand Down
6 changes: 3 additions & 3 deletions paper-server/patches/features/0031-Optimize-Hoppers.patch
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ index a8da0c5b2f9b75216d6b93addabff744c6b10431..44a7590558fa73fb570f76ba7a4e7db1
return copy;
}
diff --git a/net/minecraft/world/level/block/entity/BlockEntity.java b/net/minecraft/world/level/block/entity/BlockEntity.java
index bb61b97a9619e76344bae5458bbdf2bc96e5494c..ae0df53c3be7ebcf48886adbedfaa2c071a94023 100644
index 378d72b7f0e02ea19e5e96f7fe1359e0cb6310bb..cc5c7cc3c0c5c28ebc36bf532e61759efbc4544a 100644
--- a/net/minecraft/world/level/block/entity/BlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BlockEntity.java
@@ -39,6 +39,7 @@ import org.jspecify.annotations.Nullable;
Expand All @@ -95,10 +95,10 @@ index bb61b97a9619e76344bae5458bbdf2bc96e5494c..ae0df53c3be7ebcf48886adbedfaa2c0
// CraftBukkit start - data containers
private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
public final org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer persistentDataContainer;
@@ -209,6 +210,7 @@ public abstract class BlockEntity implements DebugValueSource, TypedInstance<Blo
@@ -210,6 +211,7 @@ public abstract class BlockEntity implements DebugValueSource, TypedInstance<Blo

public void setChanged() {
if (this.level != null) {
if (this.level != null && this.real) { // Paper - don't broadcast for fake block entities
+ if (ignoreBlockEntityUpdates) return; // Paper - Perf: Optimize Hoppers
setChanged(this.level, this.worldPosition, this.blockState);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@
private static final Codec<BlockEntityType<?>> TYPE_CODEC = BuiltInRegistries.BLOCK_ENTITY_TYPE.byNameCodec();
private static final Logger LOGGER = LogUtils.getLogger();
private final BlockEntityType<?> type;
@@ -53,6 +_,7 @@
@@ -47,12 +_,14 @@
protected boolean remove;
private BlockState blockState;
private DataComponentMap components = DataComponentMap.EMPTY;
+ public boolean real = true; // Paper - mark block entities that aren't actually in the level

public BlockEntity(final BlockEntityType<?> type, final BlockPos worldPosition, final BlockState blockState) {
this.type = type;
this.worldPosition = worldPosition.immutable();
this.validateBlockState(blockState);
this.blockState = blockState;
Expand Down Expand Up @@ -65,6 +72,15 @@
}

public final CompoundTag saveWithFullMetadata(final HolderLookup.Provider registries) {
@@ -190,7 +_,7 @@
}

public void setChanged() {
- if (this.level != null) {
+ if (this.level != null && this.real) { // Paper - don't broadcast for fake block entities
setChanged(this.level, this.worldPosition, this.blockState);
}
}
@@ -278,6 +_,12 @@
}

Expand Down Expand Up @@ -100,7 +116,7 @@
+ }
+
+ public org.bukkit.inventory.@Nullable InventoryHolder getOwner(boolean useSnapshot) {
+ if (this.level == null) return null;
+ if (this.level == null || !this.real) return null; // Paper - fake block entities have no owner
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(this.level, this.worldPosition);
+ org.bukkit.block.BlockState state = block.getState(useSnapshot); // Paper
+ return state instanceof final org.bukkit.inventory.InventoryHolder inventoryHolder ? inventoryHolder : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,19 @@
protected ChestBlockEntity(final BlockEntityType<?> type, final BlockPos worldPosition, final BlockState blockState) {
super(type, worldPosition, blockState);
}
@@ -129,6 +_,7 @@

@Override
public void startOpen(final ContainerUser containerUser) {
+ if (!this.real) return; // Paper - don't broadcast for fake block entities
if (!this.remove && !containerUser.getLivingEntity().isSpectator()) {
this.openersCounter
Comment thread
Y2Kwastaken marked this conversation as resolved.
.incrementOpeners(
@@ -139,6 +_,7 @@

@Override
public void stopOpen(final ContainerUser containerUser) {
+ if (!this.real) return; // Paper - don't broadcast for fake block entities
if (!this.remove && !containerUser.getLivingEntity().isSpectator()) {
this.openersCounter.decrementOpeners(containerUser.getLivingEntity(), this.getLevel(), this.getBlockPos(), this.getBlockState());
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
+ // CraftBukkit start
+ if (slot == 0) {
+ LecternBlockEntity.this.setBook(itemStack);
+ if (LecternBlockEntity.this.getLevel() != null) {
+ if (LecternBlockEntity.this.getLevel() != null && LecternBlockEntity.this.real) { // Paper - don't update the block for fake block entities
+ LecternBlock.resetBookState(null, LecternBlockEntity.this.getLevel(), LecternBlockEntity.this.getBlockPos(), LecternBlockEntity.this.getBlockState(), LecternBlockEntity.this.hasBook());
+ }
+ }
Expand All @@ -75,12 +75,21 @@
}

@Override
@@ -146,7 +_,7 @@
private void onBookItemRemove() {
this.page = 0;
this.pageCount = 0;
- LecternBlock.resetBookState(null, this.getLevel(), this.getBlockPos(), this.getBlockState(), false);
+ if (this.level != null && this.real) LecternBlock.resetBookState(null, this.getLevel(), this.getBlockPos(), this.getBlockState(), false); // Paper - don't update the block for fake block entities
}

public void setBook(final ItemStack book, final @Nullable Player resolutionContext) {
@@ -161,7 +_,7 @@
if (newPage != this.page) {
this.page = newPage;
this.setChanged();
- LecternBlock.signalPageChange(this.getLevel(), this.getBlockPos(), this.getBlockState());
+ if (this.level != null) LecternBlock.signalPageChange(this.getLevel(), this.getBlockPos(), this.getBlockState()); // CraftBukkit
+ if (this.level != null && this.real) LecternBlock.signalPageChange(this.getLevel(), this.getBlockPos(), this.getBlockState()); // CraftBukkit // Paper - don't update the block for fake block entities
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@
}

this.openCount++;
+ if (this.opened) return; // CraftBukkit - only animate if the ShulkerBox hasn't been forced open already by an API call
+ if (this.opened || !this.real) return; // CraftBukkit - only animate if the ShulkerBox hasn't been forced open already by an API call // Paper - don't animate fake block entities
this.level.blockEvent(this.worldPosition, this.getBlockState().getBlock(), EVENT_SET_OPEN_COUNT, this.openCount);
if (this.openCount == 1) {
this.level.gameEvent(containerUser.getLivingEntity(), GameEvent.CONTAINER_OPEN, this.worldPosition);
@@ -186,6 +_,7 @@
public void stopOpen(final ContainerUser containerUser) {
if (!this.remove && !containerUser.getLivingEntity().isSpectator()) {
this.openCount--;
+ if (this.opened) return; // CraftBukkit - only animate if the ShulkerBox hasn't been forced open already by an API call.
+ if (this.opened || !this.real) return; // CraftBukkit - only animate if the ShulkerBox hasn't been forced open already by an API call. // Paper - don't animate fake block entities
this.level.blockEvent(this.worldPosition, this.getBlockState().getBlock(), EVENT_SET_OPEN_COUNT, this.openCount);
if (this.openCount <= 0) {
this.level.gameEvent(containerUser.getLivingEntity(), GameEvent.CONTAINER_CLOSE, this.worldPosition);
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public static <V extends InventoryView, B extends InventoryViewBuilder<V>> MenuT
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftDoubleChestInventoryViewBuilder<>(handle)));
}
if (menuType == MenuType.GENERIC_9X3) {
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.CHEST, ChestBlockEntity::new, false)));
return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.CHEST, ChestBlockEntity::new)));
}
// this isn't ideal as both dispenser and dropper are 3x3, InventoryType can't currently handle generic 3x3s with size 9
// this needs to be removed when inventory creation is overhauled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,14 @@
public class CraftBlockEntityInventoryViewBuilder<V extends InventoryView> extends CraftAbstractLocationInventoryViewBuilder<V> {

private final Block block;
private final boolean useFakeBlockEntity;
private final @Nullable CraftBlockInventoryBuilder builder;

public CraftBlockEntityInventoryViewBuilder(
final MenuType<?> handle,
final Block block,
final @Nullable CraftBlockInventoryBuilder builder
) {
this(handle, block, builder, true);
}

public CraftBlockEntityInventoryViewBuilder(
final MenuType<?> handle,
final Block block,
final @Nullable CraftBlockInventoryBuilder builder,
final boolean useFakeBlockEntity
) {
super(handle);
this.useFakeBlockEntity = useFakeBlockEntity;
this.block = block;
this.builder = builder;
}
Expand Down Expand Up @@ -72,19 +61,17 @@ private AbstractContainerMenu buildFakeBlockEntity(final ServerPlayer player) {
final MenuProvider inventory = this.builder.build(this.position, this.block.defaultBlockState());
if (inventory instanceof final BlockEntity blockEntity) {
blockEntity.setLevel(this.world);
// marks this as "not in world" for gating general level broadcasts
blockEntity.real = false;
super.defaultTitle = inventory.getDisplayName();
}

if (!this.useFakeBlockEntity) { // gets around open noise for chest
return handle.create(player.nextContainerCounter(), player.getInventory());
}

return inventory.createMenu(player.nextContainerCounter(), player.getInventory(), player);
}

@Override
public LocationInventoryViewBuilder<V> copy() {
final CraftBlockEntityInventoryViewBuilder<V> copy = new CraftBlockEntityInventoryViewBuilder<>(super.handle, this.block, this.builder, this.useFakeBlockEntity);
final CraftBlockEntityInventoryViewBuilder<V> copy = new CraftBlockEntityInventoryViewBuilder<>(super.handle, this.block, this.builder);
copy.world = this.world;
copy.position = this.position;
copy.checkReachable = super.checkReachable;
Expand Down
Loading