From b4772158bcf5c2df761111646220632b84ab8702 Mon Sep 17 00:00:00 2001 From: ImTheLion <85840208+ImTheLion@users.noreply.github.com> Date: Sun, 13 Apr 2025 14:27:19 +0200 Subject: [PATCH] add BlockType/ItemType getters and setters --- .../src/main/java/org/bukkit/block/Block.java | 36 +++++++++++++++++++ .../java/org/bukkit/block/BlockState.java | 15 ++++++++ .../java/org/bukkit/block/data/BlockData.java | 9 +++++ .../java/org/bukkit/inventory/ItemStack.java | 22 ++++++++++++ .../level/block/state/BlockState.java.patch | 13 ++++++- .../bukkit/craftbukkit/block/CraftBlock.java | 17 +++++++++ .../craftbukkit/block/CraftBlockState.java | 15 ++++++++ .../block/data/CraftBlockData.java | 5 +++ .../craftbukkit/inventory/CraftItemStack.java | 25 +++++++++++++ 9 files changed, 156 insertions(+), 1 deletion(-) diff --git a/paper-api/src/main/java/org/bukkit/block/Block.java b/paper-api/src/main/java/org/bukkit/block/Block.java index d309e28d7e67..2ba8d00a3dd7 100644 --- a/paper-api/src/main/java/org/bukkit/block/Block.java +++ b/paper-api/src/main/java/org/bukkit/block/Block.java @@ -101,6 +101,14 @@ public interface Block extends Metadatable, Translatable, net.kyori.adventure.tr @NotNull Material getType(); + /** + * Gets the type of this block + * + * @return block type + */ + @NotNull + BlockType getBlockType(); + /** * Gets the light level between 0-15 * @@ -330,6 +338,34 @@ public static int getBlockKeyZ(long packed) { */ void setType(@NotNull Material type, boolean applyPhysics); + /** + * Sets the type of this block + * + * @param type BlockType to change this block to + */ + void setType(BlockType type); + + /** + * Sets the type of this block + * + *
+ * Note that applyPhysics = false is not in general safe. It should only be + * used when you need to avoid triggering a physics update of neighboring + * blocks, for example when creating a {@link Bisected} block. If you are + * using a custom populator, then this parameter may also be required to + * prevent triggering infinite chunk loads on border blocks. This method + * should NOT be used to "hack" physics by placing blocks in impossible + * locations. Such blocks are liable to be removed on various events such as + * world upgrades. Furthermore setting large amounts of such blocks in close + * proximity may overload the server physics engine if an update is + * triggered at a later point. If this occurs, the resulting behavior is + * undefined. + * + * @param type BlockType to change this block to + * @param applyPhysics False to cancel physics on the changed block. + */ + void setType(BlockType type, boolean applyPhysics); + /** * Gets the face relation of this block compared to the given block. *

diff --git a/paper-api/src/main/java/org/bukkit/block/BlockState.java b/paper-api/src/main/java/org/bukkit/block/BlockState.java index 2c430a7fb923..1e29ac01b23d 100644 --- a/paper-api/src/main/java/org/bukkit/block/BlockState.java +++ b/paper-api/src/main/java/org/bukkit/block/BlockState.java @@ -77,6 +77,14 @@ public interface BlockState extends Metadatable { @NotNull Material getType(); + /** + * Gets the type of this block state. + * + * @return block type + */ + @NotNull + BlockType getBlockType(); + /** * Gets the current light level of the block represented by this block state. * @@ -172,6 +180,13 @@ public interface BlockState extends Metadatable { */ void setType(@NotNull Material type); + /** + * Sets the type of this block state. + * + * @param type BlockType to change this block state to + */ + void setType(@NotNull BlockType type); + /** * Attempts to update the block represented by this state, setting it to * the new values as defined by this state. diff --git a/paper-api/src/main/java/org/bukkit/block/data/BlockData.java b/paper-api/src/main/java/org/bukkit/block/data/BlockData.java index 0ecc54bd810a..4f06794f7a96 100644 --- a/paper-api/src/main/java/org/bukkit/block/data/BlockData.java +++ b/paper-api/src/main/java/org/bukkit/block/data/BlockData.java @@ -9,6 +9,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.block.BlockSupport; +import org.bukkit.block.BlockType; import org.bukkit.block.PistonMoveReaction; import org.bukkit.block.structure.Mirror; import org.bukkit.block.structure.StructureRotation; @@ -27,6 +28,14 @@ public interface BlockData extends Cloneable { @NotNull Material getMaterial(); + /** + * Get the BlockType represented by this block data. + * + * @return the block type + */ + @NotNull + BlockType getBlockType(); + /** * Gets a string, which when passed into a method such as * {@link Server#createBlockData(java.lang.String)} will unambiguously diff --git a/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java b/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java index 3179607e892b..a0c13f59c9fd 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java @@ -193,6 +193,16 @@ public Material getType() { return this.craftDelegate.getType(); // Paper - delegate } + /** + * Gets the type of this item + * + * @return Type of the items in this stack + */ + @NotNull + public ItemType getItemType() { + return this.craftDelegate.getItemType(); + } + /** * Sets the type of this item *

@@ -230,6 +240,18 @@ public void setType(@NotNull Material type) { public ItemStack withType(@NotNull Material type) { return this.craftDelegate.withType(type); // Paper - delegate } + + /** + * Creates a new ItemStack with the specified ItemType, where the item count and item meta is preserved. + * + * @param type The ItemType of the new ItemStack. + * @return A new ItemStack instance with the specified ItemType. + */ + @NotNull + @org.jetbrains.annotations.Contract(value = "_ -> new", pure = true) + public ItemStack withType(@NotNull ItemType type) { + return this.craftDelegate.withType(type); + } // Paper end /** diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockState.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockState.java.patch index 01e51688b1ad..8edbbeaa877e 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockState.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/state/BlockState.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/state/BlockState.java +++ b/net/minecraft/world/level/block/state/BlockState.java -@@ -10,6 +_,17 @@ +@@ -10,6 +_,28 @@ public class BlockState extends BlockBehaviour.BlockStateBase { public static final Codec CODEC = codec(BuiltInRegistries.BLOCK.byNameCodec(), Block::defaultBlockState).stable(); @@ -14,6 +14,17 @@ + return this.cachedMaterial; + } + // Paper end - optimise getType calls ++ ++ // Paper start - add BlockType getter ++ org.bukkit.block.@org.jspecify.annotations.Nullable BlockType cachedBlockType; ++ ++ public final org.bukkit.block.BlockType getBukkitBlockType() { ++ if (this.cachedBlockType == null) { ++ this.cachedBlockType = org.bukkit.craftbukkit.block.CraftBlockType.minecraftToBukkitNew(this.getBlock()); ++ } ++ return this.cachedBlockType; ++ } ++ // Paper end - add BlockType getter + public BlockState(Block owner, Reference2ObjectArrayMap, Comparable> values, MapCodec propertiesCodec) { super(owner, values, propertiesCodec); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java index e9ca19c8668d..922224a6515d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -37,6 +37,7 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; +import org.bukkit.block.BlockType; import org.bukkit.block.PistonMoveReaction; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.CraftFluidCollisionMode; @@ -180,6 +181,17 @@ public void setType(Material type, boolean applyPhysics) { this.setBlockData(type.createBlockData(), applyPhysics); } + @Override + public void setType(final BlockType type) { + this.setType(type, true); + } + + @Override + public void setType(BlockType type, boolean applyPhysics) { + Preconditions.checkArgument(type != null, "BlockType cannot be null"); + this.setBlockData(type.createBlockData(), applyPhysics); + } + @Override public void setBlockData(BlockData data) { this.setBlockData(data, true); @@ -230,6 +242,11 @@ public Material getType() { return this.world.getBlockState(this.position).getBukkitMaterial(); // Paper - optimise getType calls } + @Override + public BlockType getBlockType() { + return this.world.getBlockState(this.position).getBukkitBlockType(); + } + @Override public byte getLightLevel() { return (byte) this.world.getMinecraftWorld().getMaxLocalRawBrightness(this.position); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java index c0a7659776a9..bf4ddfb1cbbe 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java @@ -13,6 +13,7 @@ import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockState; +import org.bukkit.block.BlockType; import org.bukkit.block.data.BlockData; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.block.data.CraftBlockData; @@ -175,11 +176,25 @@ public void setType(final Material type) { } } + @Override + public void setType(final BlockType type) { + Preconditions.checkArgument(type != null, "BlockType cannot be null"); + + if (this.getBlockType().equals(type)) { + this.data = CraftBlockType.bukkitToMinecraftNew(type).defaultBlockState(); + } + } + @Override public Material getType() { return this.data.getBukkitMaterial(); // Paper - optimise getType calls } + @Override + public BlockType getBlockType() { + return this.data.getBukkitBlockType(); + } + public void setFlags(int flags) { this.capturedFlags = flags; } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java index 328773b37c5c..6e19aea232c9 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java @@ -66,6 +66,11 @@ public Material getMaterial() { return this.state.getBukkitMaterial(); // Paper - optimise getType calls } + @Override + public BlockType getBlockType() { + return this.state.getBukkitBlockType(); + } + public net.minecraft.world.level.block.state.BlockState getState() { return this.state; } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java index 1aa17423f4ec..8824d423e61e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -32,6 +32,7 @@ import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.ItemType; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.material.MaterialData; import org.bukkit.persistence.PersistentDataContainer; @@ -194,6 +195,11 @@ public Material getType() { return this.handle != null ? CraftItemType.minecraftToBukkit(this.handle.getItem()) : Material.AIR; } + @Override + public ItemType getItemType() { + return this.handle != null ? CraftItemType.minecraftToBukkitNew(this.handle.getItem()) : ItemType.AIR; + } + @Override public void setType(Material type) { if (this.getType() == type) { @@ -484,6 +490,25 @@ public ItemStack withType(final Material type) { } // Paper end + @Override + public ItemStack withType(final ItemType type) { + if (type == ItemType.AIR) { + return CraftItemStack.asCraftMirror(null); + } + + final net.minecraft.world.item.ItemStack copy = new net.minecraft.world.item.ItemStack( + CraftItemType.bukkitToMinecraftNew(type), this.getAmount() + ); + + if (this.handle != null) { + copy.applyComponents(this.handle.getComponentsPatch()); + } + + final CraftItemStack mirrored = CraftItemStack.asCraftMirror(copy); + mirrored.setItemMeta(mirrored.getItemMeta()); + return mirrored; + } + public static final String PDC_CUSTOM_DATA_KEY = "PublicBukkitValues"; private net.minecraft.nbt.CompoundTag getPdcTag() { if (this.handle == null) {