PaperMC/patches/server/0944-Fix-block-place-logic.patch
Owen 9271ee7643
Dont resend blocks on interactions (#9413)
In general, the client now has an acknowledgment system that will cause block changes made by the client to be reverted correctly.

Essentially:

The client enters a "prediction" stage, where any block changes made will have its old blockstate captured (this is referred to as "server state").
If you update blocks during this stage, the client will update this captured server state as long as they're still currently predicting.
After prediction is done (via an ack packet) all captured blockstates are reverted to their captured server state.
This means that if the server actually updated a block and send a block update packet, it's correctly set, while if a block wasn't updated on the server but WAS updated on the client (server state wasn't updated), that change will be reverted.

It should be noted that this system does not yet support block entities, so those still need to be resynced when needed.

I discovered this when noticing that blocks broken outside of the player's valid interaction distance are still properly reverted, even though the server doesn't send any block updates, only an ack packet.
2023-12-02 22:41:35 -05:00

68 lines
4.5 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
Date: Mon, 3 Apr 2023 18:46:49 +0200
Subject: [PATCH] Fix block place logic
Fix several issues when a player interact with a block:
* the place sound isn't played for the dispensed shulker block
* desync of the jukebox blocks between bukkit handler and the vanilla interaction
* poi can desync when the BlockPhysicsEvent is cancelled
diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java
index e581dc10f3c805f7f8b6e4c842092609e7e1a0f8..6819cea2858f0035a4fbf3671612d43fead883b6 100644
--- a/src/main/java/net/minecraft/world/item/BlockItem.java
+++ b/src/main/java/net/minecraft/world/item/BlockItem.java
@@ -130,7 +130,7 @@ public class BlockItem extends Item {
SoundType soundeffecttype = iblockdata1.getSoundType();
- // world.playSound(entityhuman, blockposition, this.getPlaceSound(iblockdata1), SoundCategory.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F);
+ if (entityhuman == null) world.playSound(entityhuman, blockposition, this.getPlaceSound(iblockdata1), net.minecraft.sounds.SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F); // Paper - reintroduce this for the dispenser (i.e the shulker)
world.gameEvent(GameEvent.BLOCK_PLACE, blockposition, GameEvent.Context.of(entityhuman, iblockdata1));
if ((entityhuman == null || !entityhuman.getAbilities().instabuild) && itemstack != ItemStack.EMPTY) { // CraftBukkit
itemstack.shrink(1);
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index c73b57ffd622ccc2e6c570cf874ed118108b899b..efa73faab21c301a99cfe58c3d822d961ea4d2a5 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -472,13 +472,7 @@ public final class ItemStack {
if (tileentity instanceof JukeboxBlockEntity) {
JukeboxBlockEntity tileentityjukebox = (JukeboxBlockEntity) tileentity;
- // There can only be one
- ItemStack record = this.copy();
- if (!record.isEmpty()) {
- record.setCount(1);
- }
-
- tileentityjukebox.setFirstItem(record);
+ tileentityjukebox.setFirstItem(this.copy()); // Paper - sync this with record item, jukebox has now an inventory
world.gameEvent(GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entityhuman, world.getBlockState(blockposition)));
}
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 6942c0e42814b995971bbe9bd3bd396e121989dd..169fc7b1aaf2cefec3ddab53fcec912e0ec0117a 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -1035,17 +1035,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
// CraftBukkit start
iblockdata1.updateIndirectNeighbourShapes(this, blockposition, k, j - 1); // Don't call an event for the old block to limit event spam
CraftWorld world = ((ServerLevel) this).getWorld();
+ boolean cancelledUpdates = false; // Paper
if (world != null && ((ServerLevel)this).hasPhysicsEvent) { // Paper
BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftBlockData.fromData(iblockdata));
this.getCraftServer().getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- return;
- }
+ cancelledUpdates = event.isCancelled(); // Paper
}
// CraftBukkit end
+ if (!cancelledUpdates) { // Paper
iblockdata.updateNeighbourShapes(this, blockposition, k, j - 1);
iblockdata.updateIndirectNeighbourShapes(this, blockposition, k, j - 1);
+ } // Paper
}
// CraftBukkit start - SPIGOT-5710