From 4a7eadc976b93c9195626fca516383c4cdfcc46e Mon Sep 17 00:00:00 2001 From: Yannick Lamprecht Date: Wed, 14 Jun 2023 18:36:21 +1000 Subject: [PATCH] #1201: Add Player#sendBlockUpdate to send tile entity updates --- .../block/CraftBlockEntityState.java | 13 +++++++++++++ .../craftbukkit/block/data/CraftBlockData.java | 9 +++++++++ .../bukkit/craftbukkit/entity/CraftPlayer.java | 17 +++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java index adfb03968..9c767dc3f 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java @@ -1,10 +1,17 @@ package org.bukkit.craftbukkit.block; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.PacketListenerPlayOut; +import net.minecraft.network.protocol.game.PacketPlayOutTileEntityData; import net.minecraft.world.level.block.entity.TileEntity; +import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.TileState; +import org.bukkit.craftbukkit.util.CraftLocation; import org.bukkit.persistence.PersistentDataContainer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class CraftBlockEntityState extends CraftBlockState implements TileState { @@ -105,4 +112,10 @@ public class CraftBlockEntityState extends CraftBlockState public PersistentDataContainer getPersistentDataContainer() { return this.getSnapshot().persistentDataContainer; } + + @Nullable + public Packet getUpdatePacket(@NotNull Location location) { + T vanillaTileEntitiy = (T) TileEntity.loadStatic(CraftLocation.toBlockPosition(location), getHandle(), getSnapshotNBT()); + return PacketPlayOutTileEntityData.create(vanillaTileEntitiy); + } } diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java index d6d4c21d7..feb969295 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java +++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java @@ -29,6 +29,7 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.SoundGroup; import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; import org.bukkit.block.BlockSupport; import org.bukkit.block.PistonMoveReaction; import org.bukkit.block.data.BlockData; @@ -37,11 +38,13 @@ import org.bukkit.block.structure.StructureRotation; import org.bukkit.craftbukkit.CraftSoundGroup; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.block.CraftBlockStates; import org.bukkit.craftbukkit.block.CraftBlockSupport; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.util.CraftLocation; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; public class CraftBlockData implements BlockData { @@ -641,4 +644,10 @@ public class CraftBlockData implements BlockData { public void mirror(Mirror mirror) { this.state = state.mirror(EnumBlockMirror.valueOf(mirror.name())); } + + @NotNull + @Override + public BlockState createBlockState() { + return CraftBlockStates.getBlockState(this.state, null); + } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index ec5133ae8..058924b92 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -36,6 +36,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketDataSerializer; import net.minecraft.network.chat.IChatBaseComponent; import net.minecraft.network.chat.PlayerChatMessage; +import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientboundClearTitlesPacket; import net.minecraft.network.protocol.game.ClientboundCustomChatCompletionsPacket; import net.minecraft.network.protocol.game.ClientboundHurtAnimationPacket; @@ -62,6 +63,7 @@ import net.minecraft.network.protocol.game.PacketPlayOutNamedSoundEffect; import net.minecraft.network.protocol.game.PacketPlayOutPlayerListHeaderFooter; import net.minecraft.network.protocol.game.PacketPlayOutSpawnPosition; import net.minecraft.network.protocol.game.PacketPlayOutStopSound; +import net.minecraft.network.protocol.game.PacketPlayOutTileEntityData; import net.minecraft.network.protocol.game.PacketPlayOutUpdateAttributes; import net.minecraft.network.protocol.game.PacketPlayOutUpdateHealth; import net.minecraft.network.protocol.game.PacketPlayOutWorldEvent; @@ -86,6 +88,7 @@ import net.minecraft.world.item.EnumColor; import net.minecraft.world.level.EnumGamemode; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.SignText; +import net.minecraft.world.level.block.entity.TileEntity; import net.minecraft.world.level.block.entity.TileEntitySign; import net.minecraft.world.level.block.state.IBlockData; import net.minecraft.world.level.border.IWorldBorderListener; @@ -111,6 +114,7 @@ import org.bukkit.WorldBorder; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; +import org.bukkit.block.TileState; import org.bukkit.block.data.BlockData; import org.bukkit.block.sign.Side; import org.bukkit.configuration.serialization.DelegateDeserialization; @@ -128,7 +132,9 @@ import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.CraftWorldBorder; import org.bukkit.craftbukkit.advancement.CraftAdvancement; import org.bukkit.craftbukkit.advancement.CraftAdvancementProgress; +import org.bukkit.craftbukkit.block.CraftBlockEntityState; import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.craftbukkit.block.CraftBlockStates; import org.bukkit.craftbukkit.block.CraftSign; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.craftbukkit.conversations.ConversationTracker; @@ -705,6 +711,17 @@ public class CraftPlayer extends CraftHumanEntity implements Player { getHandle().connection.send(sign.getUpdatePacket()); } + @Override + public void sendBlockUpdate(@NotNull Location location, @NotNull TileState tileState) throws IllegalArgumentException { + Preconditions.checkArgument(location != null, "Location can not be null"); + Preconditions.checkArgument(tileState != null, "TileState can not be null"); + + if (getHandle().connection == null) return; + + CraftBlockEntityState craftState = ((CraftBlockEntityState) tileState); + getHandle().connection.send(craftState.getUpdatePacket(location)); + } + @Override public void sendEquipmentChange(LivingEntity entity, EquipmentSlot slot, ItemStack item) { this.sendEquipmentChange(entity, Map.of(slot, item));