SPIGOT-8042: BlockBreakEvent canceled - sign content not restored

This commit is contained in:
md_5 2025-04-18 11:58:43 +10:00
parent 3b4fd5b321
commit 6f3a375ee6
No known key found for this signature in database
GPG Key ID: E8E901AC7C617C11

View File

@ -1,11 +1,12 @@
--- a/net/minecraft/server/level/PlayerInteractManager.java --- a/net/minecraft/server/level/PlayerInteractManager.java
+++ b/net/minecraft/server/level/PlayerInteractManager.java +++ b/net/minecraft/server/level/PlayerInteractManager.java
@@ -26,6 +26,27 @@ @@ -26,6 +26,28 @@
import net.minecraft.world.phys.Vec3D; import net.minecraft.world.phys.Vec3D;
import org.slf4j.Logger; import org.slf4j.Logger;
+// CraftBukkit start +// CraftBukkit start
+import java.util.ArrayList; +import java.util.ArrayList;
+import net.minecraft.network.protocol.game.ClientboundBlockChangedAckPacket;
+import net.minecraft.network.protocol.game.PacketPlayOutBlockChange; +import net.minecraft.network.protocol.game.PacketPlayOutBlockChange;
+import net.minecraft.server.MinecraftServer; +import net.minecraft.server.MinecraftServer;
+import net.minecraft.world.entity.EnumItemSlot; +import net.minecraft.world.entity.EnumItemSlot;
@ -28,7 +29,7 @@
public class PlayerInteractManager { public class PlayerInteractManager {
private static final Logger LOGGER = LogUtils.getLogger(); private static final Logger LOGGER = LogUtils.getLogger();
@@ -56,9 +77,16 @@ @@ -56,9 +78,16 @@
if (enumgamemode == this.gameModeForPlayer) { if (enumgamemode == this.gameModeForPlayer) {
return false; return false;
} else { } else {
@ -46,7 +47,7 @@
this.level.updateSleepingPlayerList(); this.level.updateSleepingPlayerList();
if (enumgamemode == EnumGamemode.CREATIVE) { if (enumgamemode == EnumGamemode.CREATIVE) {
this.player.resetCurrentImpulseContext(); this.player.resetCurrentImpulseContext();
@@ -92,7 +120,7 @@ @@ -92,7 +121,7 @@
} }
public void tick() { public void tick() {
@ -55,7 +56,7 @@
if (this.hasDelayedDestroy) { if (this.hasDelayedDestroy) {
IBlockData iblockdata = this.level.getBlockState(this.delayedDestroyPos); IBlockData iblockdata = this.level.getBlockState(this.delayedDestroyPos);
@@ -144,11 +172,33 @@ @@ -144,10 +173,36 @@
} else { } else {
if (packetplayinblockdig_enumplayerdigtype == PacketPlayInBlockDig.EnumPlayerDigType.START_DESTROY_BLOCK) { if (packetplayinblockdig_enumplayerdigtype == PacketPlayInBlockDig.EnumPlayerDigType.START_DESTROY_BLOCK) {
if (!this.level.mayInteract(this.player, blockposition)) { if (!this.level.mayInteract(this.player, blockposition)) {
@ -63,33 +64,36 @@
+ CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockposition, enumdirection, this.player.getInventory().getSelectedItem(), EnumHand.MAIN_HAND); + CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockposition, enumdirection, this.player.getInventory().getSelectedItem(), EnumHand.MAIN_HAND);
this.player.connection.send(new PacketPlayOutBlockChange(blockposition, this.level.getBlockState(blockposition))); this.player.connection.send(new PacketPlayOutBlockChange(blockposition, this.level.getBlockState(blockposition)));
this.debugLogging(blockposition, false, j, "may not interact"); this.debugLogging(blockposition, false, j, "may not interact");
+ // SPIGOT-8042: Need to ACK above changes first
+ this.player.connection.send(new ClientboundBlockChangedAckPacket(j));
+ // Update any tile entity data for this block + // Update any tile entity data for this block
+ TileEntity tileentity = level.getBlockEntity(blockposition); + TileEntity tileentity = level.getBlockEntity(blockposition);
+ if (tileentity != null) { + if (tileentity != null) {
+ this.player.connection.send(tileentity.getUpdatePacket()); + this.player.connection.send(tileentity.getUpdatePacket());
+ } + }
+ // CraftBukkit end + // CraftBukkit end
return; + return;
} + }
+
+ // CraftBukkit start + // CraftBukkit start
+ PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockposition, enumdirection, this.player.getInventory().getSelectedItem(), EnumHand.MAIN_HAND); + PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockposition, enumdirection, this.player.getInventory().getSelectedItem(), EnumHand.MAIN_HAND);
+ if (event.isCancelled()) { + if (event.isCancelled()) {
+ // Let the client know the block still exists + // Let the client know the block still exists
+ this.player.connection.send(new PacketPlayOutBlockChange(this.level, blockposition)); + this.player.connection.send(new PacketPlayOutBlockChange(this.level, blockposition));
+ // SPIGOT-8042: Need to ACK above changes first
+ this.player.connection.send(new ClientboundBlockChangedAckPacket(j));
+ // Update any tile entity data for this block + // Update any tile entity data for this block
+ TileEntity tileentity = this.level.getBlockEntity(blockposition); + TileEntity tileentity = this.level.getBlockEntity(blockposition);
+ if (tileentity != null) { + if (tileentity != null) {
+ this.player.connection.send(tileentity.getUpdatePacket()); + this.player.connection.send(tileentity.getUpdatePacket());
+ } + }
+ return; return;
+ } }
+ // CraftBukkit end + // CraftBukkit end
+
if (this.player.getAbilities().instabuild) { if (this.player.getAbilities().instabuild) {
this.destroyAndAck(blockposition, j, "creative destroy"); this.destroyAndAck(blockposition, j, "creative destroy");
return; @@ -164,7 +219,19 @@
@@ -164,7 +214,19 @@
float f = 1.0F; float f = 1.0F;
IBlockData iblockdata = this.level.getBlockState(blockposition); IBlockData iblockdata = this.level.getBlockState(blockposition);
@ -110,7 +114,7 @@
EnchantmentManager.onHitBlock(this.level, this.player.getMainHandItem(), this.player, this.player, EnumItemSlot.MAINHAND, Vec3D.atCenterOf(blockposition), iblockdata, (item) -> { EnchantmentManager.onHitBlock(this.level, this.player.getMainHandItem(), this.player, this.player, EnumItemSlot.MAINHAND, Vec3D.atCenterOf(blockposition), iblockdata, (item) -> {
this.player.onEquippedItemBroken(item, EnumItemSlot.MAINHAND); this.player.onEquippedItemBroken(item, EnumItemSlot.MAINHAND);
}); });
@@ -172,6 +234,26 @@ @@ -172,6 +239,26 @@
f = iblockdata.getDestroyProgress(this.player, this.player.level(), blockposition); f = iblockdata.getDestroyProgress(this.player, this.player.level(), blockposition);
} }
@ -137,7 +141,7 @@
if (!iblockdata.isAir() && f >= 1.0F) { if (!iblockdata.isAir() && f >= 1.0F) {
this.destroyAndAck(blockposition, j, "insta mine"); this.destroyAndAck(blockposition, j, "insta mine");
} else { } else {
@@ -216,13 +298,15 @@ @@ -216,20 +303,22 @@
} else if (packetplayinblockdig_enumplayerdigtype == PacketPlayInBlockDig.EnumPlayerDigType.ABORT_DESTROY_BLOCK) { } else if (packetplayinblockdig_enumplayerdigtype == PacketPlayInBlockDig.EnumPlayerDigType.ABORT_DESTROY_BLOCK) {
this.isDestroyingBlock = false; this.isDestroyingBlock = false;
if (!Objects.equals(this.destroyPos, blockposition)) { if (!Objects.equals(this.destroyPos, blockposition)) {
@ -154,9 +158,24 @@
} }
} }
@@ -240,10 +324,65 @@ }
public void destroyAndAck(BlockPosition blockposition, int i, String s) {
- if (this.destroyBlock(blockposition)) {
+ if (this.destroyBlock(blockposition, i)) { // CraftBukkit - add ack
this.debugLogging(blockposition, true, i, s);
} else {
this.player.connection.send(new PacketPlayOutBlockChange(blockposition, this.level.getBlockState(blockposition)));
@@ -239,11 +328,74 @@
}
public boolean destroyBlock(BlockPosition blockposition) { public boolean destroyBlock(BlockPosition blockposition) {
+ // CraftBukkit start
+ return this.destroyBlock(blockposition, -1);
+ }
+
+ public boolean destroyBlock(BlockPosition blockposition, int ack) {
+ // CraftBukkit end
IBlockData iblockdata = this.level.getBlockState(blockposition); IBlockData iblockdata = this.level.getBlockState(blockposition);
+ // CraftBukkit start - fire BlockBreakEvent + // CraftBukkit start - fire BlockBreakEvent
+ org.bukkit.block.Block bblock = CraftBlock.at(level, blockposition); + org.bukkit.block.Block bblock = CraftBlock.at(level, blockposition);
@ -203,6 +222,8 @@
+ this.player.connection.send(new PacketPlayOutBlockChange(level, blockposition.relative(dir))); + this.player.connection.send(new PacketPlayOutBlockChange(level, blockposition.relative(dir)));
+ } + }
+ +
+ // SPIGOT-8042: Need to ACK above changes first
+ this.player.connection.send(new ClientboundBlockChangedAckPacket(ack));
+ // Update any tile entity data for this block + // Update any tile entity data for this block
+ TileEntity tileentity = this.level.getBlockEntity(blockposition); + TileEntity tileentity = this.level.getBlockEntity(blockposition);
+ if (tileentity != null) { + if (tileentity != null) {
@ -221,7 +242,7 @@
TileEntity tileentity = this.level.getBlockEntity(blockposition); TileEntity tileentity = this.level.getBlockEntity(blockposition);
Block block = iblockdata.getBlock(); Block block = iblockdata.getBlock();
@@ -253,6 +392,10 @@ @@ -253,6 +405,10 @@
} else if (this.player.blockActionRestricted(this.level, blockposition, this.gameModeForPlayer)) { } else if (this.player.blockActionRestricted(this.level, blockposition, this.gameModeForPlayer)) {
return false; return false;
} else { } else {
@ -232,7 +253,7 @@
IBlockData iblockdata1 = block.playerWillDestroy(this.level, blockposition, iblockdata, this.player); IBlockData iblockdata1 = block.playerWillDestroy(this.level, blockposition, iblockdata, this.player);
boolean flag = this.level.removeBlock(blockposition, false); boolean flag = this.level.removeBlock(blockposition, false);
@@ -261,19 +404,32 @@ @@ -261,19 +417,32 @@
} }
if (this.player.preventsBlockDrops()) { if (this.player.preventsBlockDrops()) {
@ -255,20 +276,20 @@
+ // CraftBukkit start + // CraftBukkit start
+ if (event.isDropItems()) { + if (event.isDropItems()) {
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, state, this.player, level.captureDrops); + org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, state, this.player, level.captureDrops);
+ } }
+ level.captureDrops = null; + level.captureDrops = null;
+ +
+ // Drop event experience + // Drop event experience
+ if (flag && event != null) { + if (flag && event != null) {
+ iblockdata.getBlock().popExperience(this.level, blockposition, event.getExpToDrop()); + iblockdata.getBlock().popExperience(this.level, blockposition, event.getExpToDrop());
} + }
+ +
+ return true; + return true;
+ // CraftBukkit end + // CraftBukkit end
} }
} }
} }
@@ -319,14 +475,53 @@ @@ -319,14 +488,53 @@
} }
} }
@ -322,7 +343,7 @@
if (itileinventory != null) { if (itileinventory != null) {
entityplayer.openMenu(itileinventory); entityplayer.openMenu(itileinventory);
@@ -357,7 +552,7 @@ @@ -357,7 +565,7 @@
} }
} }