Paper/patches/server/0160-API-to-get-a-BlockState-without-a-snapshot.patch
2024-10-27 18:39:30 +01:00

166 lines
7.6 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 6 Nov 2017 21:08:22 -0500
Subject: [PATCH] API to get a BlockState without a snapshot
This allows you to get a BlockState without creating a snapshot, operating
on the real tile entity.
This is useful for where performance is needed
also Avoid NPE during CraftBlockEntityState load if could not get TE
If Tile Entity was null, correct Sign to return empty lines instead of null
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
index 3d7c5db5514f9d4401da22d2df88c5614051e568..50413d317ce0282752c57535637f87d529f4c09f 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
@@ -54,6 +54,7 @@ public abstract class BlockEntity {
this.worldPosition = pos.immutable();
this.validateBlockState(state);
this.blockState = state;
+ this.persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY); // Paper - always init
}
private void validateBlockState(BlockState state) {
@@ -87,7 +88,7 @@ public abstract class BlockEntity {
// CraftBukkit start - read container
protected void loadAdditional(CompoundTag nbt, HolderLookup.Provider registries) {
- this.persistentDataContainer = new CraftPersistentDataContainer(BlockEntity.DATA_TYPE_REGISTRY);
+ this.persistentDataContainer.clear(); // Paper - clear instead of init
net.minecraft.nbt.Tag persistentDataTag = nbt.get("PublicBukkitValues");
if (persistentDataTag instanceof CompoundTag) {
@@ -375,8 +376,15 @@ public abstract class BlockEntity {
// CraftBukkit start - add method
public InventoryHolder getOwner() {
+ // Paper start
+ return getOwner(true);
+ }
+ public InventoryHolder getOwner(boolean useSnapshot) {
+ // Paper end
if (this.level == null) return null;
- org.bukkit.block.BlockState state = this.level.getWorld().getBlockAt(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ()).getState();
+ org.bukkit.block.Block block = this.level.getWorld().getBlockAt(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ());
+ if (block.getType() == org.bukkit.Material.AIR) return null;
+ org.bukkit.block.BlockState state = block.getState(useSnapshot); // Paper
if (state instanceof InventoryHolder) return (InventoryHolder) state;
return null;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index c9b1167b15990235e72d68ba6d1d2f0385eb5755..e163ff416f19766132d73fff2c8eb7f3f098f8c6 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -328,6 +328,13 @@ public class CraftBlock implements Block {
return CraftBlockStates.getBlockState(this);
}
+ // Paper start
+ @Override
+ public BlockState getState(boolean useSnapshot) {
+ return CraftBlockStates.getBlockState(this, useSnapshot);
+ }
+ // Paper end
+
@Override
public Biome getBiome() {
return this.getWorld().getBiome(this.getX(), this.getY(), this.getZ());
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
index 483a89ba477506ae108f680e586b37c142119696..80418a05d53516d2c539383aa9994099c634b905 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
@@ -24,15 +24,26 @@ public class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockStat
private final T tileEntity;
private final T snapshot;
+ public boolean snapshotDisabled; // Paper
+ public static boolean DISABLE_SNAPSHOT = false; // Paper
public CraftBlockEntityState(World world, T tileEntity) {
super(world, tileEntity.getBlockPos(), tileEntity.getBlockState());
this.tileEntity = tileEntity;
+ // Paper start
+ this.snapshotDisabled = DISABLE_SNAPSHOT;
+ if (DISABLE_SNAPSHOT) {
+ this.snapshot = this.tileEntity;
+ } else {
+ this.snapshot = this.createSnapshot(tileEntity);
+ }
// copy tile entity data:
- this.snapshot = this.createSnapshot(tileEntity);
- this.load(this.snapshot);
+ if (this.snapshot != null) {
+ this.load(this.snapshot);
+ }
+ // Paper end
}
protected CraftBlockEntityState(CraftBlockEntityState<T> state, Location location) {
@@ -184,4 +195,11 @@ public class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockStat
public CraftBlockEntityState<T> copy(Location location) {
return new CraftBlockEntityState<>(this, location);
}
+
+ // Paper start
+ @Override
+ public boolean isSnapshot() {
+ return !this.snapshotDisabled;
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
index b849ed6eefbc73a86d4dd823bbc5bbb2321c330f..1a8dcde39a252a45046866349b848d79e1b13260 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
@@ -393,15 +393,30 @@ public final class CraftBlockStates {
}
public static BlockState getBlockState(Block block) {
+ // Paper start
+ return CraftBlockStates.getBlockState(block, true);
+ }
+ public static BlockState getBlockState(Block block, boolean useSnapshot) {
+ // Paper end
Preconditions.checkNotNull(block, "block is null");
CraftBlock craftBlock = (CraftBlock) block;
CraftWorld world = (CraftWorld) block.getWorld();
BlockPos blockPosition = craftBlock.getPosition();
net.minecraft.world.level.block.state.BlockState blockData = craftBlock.getNMS();
BlockEntity tileEntity = craftBlock.getHandle().getBlockEntity(blockPosition);
+ // Paper start - block state snapshots
+ boolean prev = CraftBlockEntityState.DISABLE_SNAPSHOT;
+ CraftBlockEntityState.DISABLE_SNAPSHOT = !useSnapshot;
+ try {
+ // Paper end
CraftBlockState blockState = CraftBlockStates.getBlockState(world, blockPosition, blockData, tileEntity);
blockState.setWorldHandle(craftBlock.getHandle()); // Inject the block's generator access
return blockState;
+ // Paper start
+ } finally {
+ CraftBlockEntityState.DISABLE_SNAPSHOT = prev;
+ }
+ // Paper end
}
@Deprecated
diff --git a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
index dbb9a5b2f8d3bc0b13e0f56f6e8a0d9a7b761327..3001bb0e3d4af9b16645a0136093db594b89ab01 100644
--- a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
+++ b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
@@ -177,4 +177,10 @@ public class CraftPersistentDataContainer implements PersistentDataContainer {
public String serialize() {
return CraftNBTTagConfigSerializer.serialize(this.toTagCompound());
}
+
+ // Paper start
+ public void clear() {
+ this.customDataTags.clear();
+ }
+ // Paper end
}