From 6a733d70c1dbca145b92025c5270d1b47d9ce2c6 Mon Sep 17 00:00:00 2001 From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Date: Sun, 18 Jun 2023 18:33:15 -0400 Subject: [PATCH] Properly Cancel Usable Items (#9225) This fixes the bug causing canceling PlayerInteractEvent to cause items to continue to be used despite being canceled on the server. For example, items being consumed but never finishing, shields being put up, etc. The underlying issue of this is that the client modifies their synced data values, and so we have to (forcibly) resend them in order for the client to reset their using item state. --- .../server/Properly-Cancel-Usable-Items.patch | 40 +++++++++++++++++++ patches/server/Properly-resend-entities.patch | 16 ++++++++ 2 files changed, 56 insertions(+) create mode 100644 patches/server/Properly-Cancel-Usable-Items.patch diff --git a/patches/server/Properly-Cancel-Usable-Items.patch b/patches/server/Properly-Cancel-Usable-Items.patch new file mode 100644 index 0000000000..9a8e5e1a8e --- /dev/null +++ b/patches/server/Properly-Cancel-Usable-Items.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> +Date: Tue, 23 May 2023 22:33:36 -0400 +Subject: [PATCH] Properly Cancel Usable Items + +This fixes the bug causing cancelling PlayerInteractEvent to cause items to continue to be used despite being cancelled on the server. + +For example, items being consumed but never finishing, shields being put up, etc. +The underlying issue of this is that the client modifies their synced data values, and so we have to (forcibly) resend +them in order for the client to reset their using item state. + +diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic + } + + if (cancelled) { ++ this.player.resyncUsingItem(this.player); // Paper - Resend player's using item status + this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524 + return; + } +diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java ++++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java +@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable { + return ((Byte) this.entityData.get(LivingEntity.DATA_LIVING_ENTITY_FLAGS) & 2) > 0 ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND; + } + ++ // Paper start ++ public void resyncUsingItem(ServerPlayer serverPlayer) { ++ this.getEntityData().resendPossiblyDesyncedDataValues(java.util.List.of(DATA_LIVING_ENTITY_FLAGS), serverPlayer); ++ } ++ // Paper end ++ + // Paper start - lag compensate eating + protected long eatStartTime; + protected int totalEatTimeTicks; diff --git a/patches/server/Properly-resend-entities.patch b/patches/server/Properly-resend-entities.patch index 93b57013ef..e9b4d92285 100644 --- a/patches/server/Properly-resend-entities.patch +++ b/patches/server/Properly-resend-entities.patch @@ -8,6 +8,8 @@ Entities that are interacted with need to be resent to the client, so we resend data to the player whilst making sure not to clear dirty entries from the tracker. This makes sure that values will be correctly updated to other players. +This also adds utilities to aid in further preventing entity desyncs. + See: https://github.com/PaperMC/Paper/pull/1896 == AT == @@ -61,6 +63,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + serverEntity.sendPairingData(player, player.connection::send); + } + } ++ ++ // This method allows you to specifically resend certain data accessor keys to the client ++ public void resendPossiblyDesyncedDataValues(List> keys, ServerPlayer to) { ++ if (!to.getBukkitEntity().canSee(this.entity.getBukkitEntity())) { ++ return; ++ } ++ List> values = new ArrayList<>(keys.size()); ++ for (EntityDataAccessor key : keys) { ++ SynchedEntityData.DataItem synchedValue = this.getItem(key); ++ values.add(synchedValue.value()); ++ } ++ ++ to.connection.send(new ClientboundSetEntityDataPacket(this.entity.getId(), values)); ++ } + // Paper end public static class DataItem {