mirror of
https://github.com/PaperMC/Paper.git
synced 2025-07-26 01:32:02 -07:00
Dont resend blocks on interactions
In general, the client now has an acknowledgment system which will prevent block changes made by the client to be reverted correctly. It should be noted that this system does not yet support block entities, so those still need to resynced when needed.
This commit is contained in:
@@ -135,20 +135,20 @@
|
||||
+ // Update any tile entity data for this block
|
||||
+ capturedBlockEntity = true; // Paper - Send block entities after destroy prediction
|
||||
+ // CraftBukkit end
|
||||
return;
|
||||
}
|
||||
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // CraftBukkit start
|
||||
+ PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, pos, direction, this.player.getInventory().getSelected(), InteractionHand.MAIN_HAND);
|
||||
+ if (event.isCancelled()) {
|
||||
+ // Let the client know the block still exists
|
||||
+ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); // Paper - Don't resync blocks
|
||||
+ // Update any tile entity data for this block
|
||||
+ capturedBlockEntity = true; // Paper - Send block entities after destroy prediction
|
||||
+ return;
|
||||
+ }
|
||||
return;
|
||||
}
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
|
||||
if (this.isCreative()) {
|
||||
this.destroyAndAck(pos, sequence, "creative destroy");
|
||||
return;
|
||||
@@ -157,7 +157,7 @@
|
||||
+ // Spigot start - handle debug stick left click for non-creative
|
||||
+ if (this.player.getMainHandItem().is(net.minecraft.world.item.Items.DEBUG_STICK)
|
||||
+ && ((net.minecraft.world.item.DebugStickItem) net.minecraft.world.item.Items.DEBUG_STICK).handleInteraction(this.player, this.level.getBlockState(pos), this.level, pos, false, this.player.getMainHandItem())) {
|
||||
+ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); // Paper - Don't resync block
|
||||
+ return;
|
||||
+ }
|
||||
+ // Spigot end
|
||||
@@ -165,7 +165,7 @@
|
||||
if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) {
|
||||
this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos)));
|
||||
this.debugLogging(pos, false, sequence, "block action restricted");
|
||||
@@ -166,7 +232,19 @@
|
||||
@@ -166,7 +232,21 @@
|
||||
float f = 1.0F;
|
||||
|
||||
iblockdata = this.level.getBlockState(pos);
|
||||
@@ -173,27 +173,29 @@
|
||||
+ // CraftBukkit start - Swings at air do *NOT* exist.
|
||||
+ if (event.useInteractedBlock() == Event.Result.DENY) {
|
||||
+ // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door.
|
||||
+ BlockState data = this.level.getBlockState(pos);
|
||||
+ if (data.getBlock() instanceof DoorBlock) {
|
||||
+ // For some reason *BOTH* the bottom/top part have to be marked updated.
|
||||
+ boolean bottom = data.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER;
|
||||
+ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, bottom ? pos.above() : pos.below()));
|
||||
+ } else if (data.getBlock() instanceof TrapDoorBlock) {
|
||||
+ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ }
|
||||
+ // Paper start - Don't resync blocks
|
||||
+ //BlockState data = this.level.getBlockState(pos);
|
||||
+ //if (data.getBlock() instanceof DoorBlock) {
|
||||
+ // // For some reason *BOTH* the bottom/top part have to be marked updated.
|
||||
+ // boolean bottom = data.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER;
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, bottom ? pos.above() : pos.below()));
|
||||
+ //} else if (data.getBlock() instanceof TrapDoorBlock) {
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ //}
|
||||
+ // Paper end - Don't resync blocks
|
||||
+ } else if (!iblockdata.isAir()) {
|
||||
EnchantmentHelper.onHitBlock(this.level, this.player.getMainHandItem(), this.player, this.player, EquipmentSlot.MAINHAND, Vec3.atCenterOf(pos), iblockdata, (item) -> {
|
||||
this.player.onEquippedItemBroken(item, EquipmentSlot.MAINHAND);
|
||||
});
|
||||
@@ -174,6 +252,26 @@
|
||||
@@ -174,6 +254,26 @@
|
||||
f = iblockdata.getDestroyProgress(this.player, this.player.level(), pos);
|
||||
}
|
||||
|
||||
+ if (event.useItemInHand() == Event.Result.DENY) {
|
||||
+ // If we 'insta destroyed' then the client needs to be informed.
|
||||
+ if (f > 1.0f) {
|
||||
+ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); // Paper - Don't resync blocks
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
@@ -201,7 +203,7 @@
|
||||
+
|
||||
+ if (blockEvent.isCancelled()) {
|
||||
+ // Let the client know the block still exists
|
||||
+ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); // Paper - Don't resync block
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
@@ -213,7 +215,7 @@
|
||||
if (!iblockdata.isAir() && f >= 1.0F) {
|
||||
this.destroyAndAck(pos, sequence, "insta mine");
|
||||
} else {
|
||||
@@ -217,14 +315,18 @@
|
||||
@@ -217,14 +317,18 @@
|
||||
this.debugLogging(pos, true, sequence, "stopped destroying");
|
||||
} else if (action == ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK) {
|
||||
this.isDestroyingBlock = false;
|
||||
@@ -236,7 +238,7 @@
|
||||
}
|
||||
|
||||
}
|
||||
@@ -242,19 +344,80 @@
|
||||
@@ -242,19 +346,82 @@
|
||||
|
||||
public boolean destroyBlock(BlockPos pos) {
|
||||
BlockState iblockdata = this.level.getBlockState(pos);
|
||||
@@ -251,7 +253,7 @@
|
||||
+
|
||||
+ // Tell client the block is gone immediately then process events
|
||||
+ // Don't tell the client if its a creative sword break because its not broken!
|
||||
+ if (this.level.getBlockEntity(pos) == null && !isSwordNoBreak) {
|
||||
+ if (false && this.level.getBlockEntity(pos) == null && !isSwordNoBreak) { // Paper - Don't resync block
|
||||
+ ClientboundBlockUpdatePacket packet = new ClientboundBlockUpdatePacket(pos, Blocks.AIR.defaultBlockState());
|
||||
+ this.player.connection.send(packet);
|
||||
+ }
|
||||
@@ -277,13 +279,15 @@
|
||||
+ if (isSwordNoBreak) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper start - Don't resync blocks
|
||||
+ // Let the client know the block still exists
|
||||
+ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+ //this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
|
||||
+
|
||||
+ // Brute force all possible updates
|
||||
+ for (Direction dir : Direction.values()) {
|
||||
+ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos.relative(dir)));
|
||||
+ }
|
||||
+ //for (Direction dir : Direction.values()) {
|
||||
+ // this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos.relative(dir)));
|
||||
+ //}
|
||||
+ // Paper end - Don't resync blocks
|
||||
+
|
||||
+ // Update any tile entity data for this block
|
||||
+ if (!captureSentBlockEntities) { // Paper - Send block entities after destroy prediction
|
||||
@@ -319,7 +323,7 @@
|
||||
BlockState iblockdata1 = block.playerWillDestroy(this.level, pos, iblockdata, this.player);
|
||||
boolean flag = this.level.removeBlock(pos, false);
|
||||
|
||||
@@ -262,20 +425,46 @@
|
||||
@@ -262,20 +429,46 @@
|
||||
block.destroy(this.level, pos, iblockdata1);
|
||||
}
|
||||
|
||||
@@ -370,7 +374,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -321,15 +510,59 @@
|
||||
@@ -321,15 +514,61 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,16 +411,18 @@
|
||||
+ if (event.useInteractedBlock() == Event.Result.DENY) {
|
||||
+ // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door.
|
||||
+ if (iblockdata.getBlock() instanceof DoorBlock) {
|
||||
+ boolean bottom = iblockdata.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER;
|
||||
+ player.connection.send(new ClientboundBlockUpdatePacket(world, bottom ? blockposition.above() : blockposition.below()));
|
||||
+ // Paper start - Don't resync blocks
|
||||
+ // boolean bottom = iblockdata.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER;
|
||||
+ // player.connection.send(new ClientboundBlockUpdatePacket(world, bottom ? blockposition.above() : blockposition.below()));
|
||||
+ // Paper end - Don't resync blocks
|
||||
+ } else if (iblockdata.getBlock() instanceof CakeBlock) {
|
||||
+ player.getBukkitEntity().sendHealthUpdate(); // SPIGOT-1341 - reset health for cake
|
||||
+ } else if (this.interactItemStack.getItem() instanceof DoubleHighBlockItem) {
|
||||
+ // send a correcting update to the client, as it already placed the upper half of the bisected item
|
||||
+ player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.relative(hitResult.getDirection()).above()));
|
||||
+ //player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.relative(hitResult.getDirection()).above())); // Paper - Don't resync blocks
|
||||
+
|
||||
+ // send a correcting update to the client for the block above as well, this because of replaceable blocks (such as grass, sea grass etc)
|
||||
+ player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.above()));
|
||||
+ //player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.above())); // Paper - Don't resync blocks
|
||||
+ // Paper start - extend Player Interact cancellation // TODO: consider merging this into the extracted method
|
||||
+ } else if (iblockdata.is(Blocks.JIGSAW) || iblockdata.is(Blocks.STRUCTURE_BLOCK) || iblockdata.getBlock() instanceof net.minecraft.world.level.block.CommandBlock) {
|
||||
+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundContainerClosePacket(this.player.containerMenu.containerId));
|
||||
@@ -430,7 +436,7 @@
|
||||
if (itileinventory != null) {
|
||||
player.openMenu(itileinventory);
|
||||
return InteractionResult.CONSUME;
|
||||
@@ -359,7 +592,7 @@
|
||||
@@ -359,7 +598,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user