diff --git a/paper-server/patches/features/0003-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch b/paper-server/patches/features/0003-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch index a7533a2d46..77da1105f4 100644 --- a/paper-server/patches/features/0003-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch +++ b/paper-server/patches/features/0003-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch @@ -28,10 +28,10 @@ index 678b3027e8c53e6021ea49afa69cdbe5f60dcf25..cce78d73e8adafd66d0f3ffb3fabb5e6 } } diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index cfd30aa774d3bb3049ff9331a623624c6a13f774..940509d1f31aedf20b8f5b9192c34ad004875728 100644 +index 68e3282a0aa23bd41ab7c77be287d2b49461e33c..def43c515030412b147afd6049b100a3153733d2 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -2655,6 +2655,14 @@ public class ServerPlayer extends Player { +@@ -2607,6 +2607,14 @@ public class ServerPlayer extends Player { this.awardStat(Stats.DROP); } diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerEntity.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerEntity.java.patch index 5f30bfd43d..4413d91d0f 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerEntity.java.patch @@ -125,8 +125,8 @@ Set attributesToSync = ((LivingEntity)this.entity).getAttributes().getAttributesToSync(); if (!attributesToSync.isEmpty()) { + // CraftBukkit start - Send scaled max health -+ if (this.entity instanceof ServerPlayer) { -+ ((ServerPlayer) this.entity).getBukkitEntity().injectScaledMaxHealth(attributesToSync, false); ++ if (this.entity instanceof ServerPlayer serverPlayer) { ++ serverPlayer.getBukkitEntity().injectScaledMaxHealth(attributesToSync, false); + } + // CraftBukkit end this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), attributesToSync)); diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch index 0a308ad258..d506c224e1 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch @@ -24,14 +24,15 @@ @Override public void sendSlotChange(AbstractContainerMenu container, int slot, ItemStack itemStack) { ServerPlayer.this.connection.send(new ClientboundContainerSetSlotPacket(container.containerId, container.incrementStateId(), slot, itemStack)); -@@ -288,6 +_,31 @@ +@@ -288,6 +_,32 @@ } } + // Paper start - Add PlayerInventorySlotChangeEvent + @Override -+ public void slotChanged(AbstractContainerMenu handler, int slotId, ItemStack oldStack, ItemStack stack) { -+ Slot slot = handler.getSlot(slotId); ++ public void slotChanged(AbstractContainerMenu containerToSend, int dataSlotIndex, ItemStack oldStack, ItemStack stack) { ++ // See slotChanged above ++ Slot slot = containerToSend.getSlot(dataSlotIndex); + if (!(slot instanceof ResultSlot)) { + if (slot.container == ServerPlayer.this.getInventory()) { + if (io.papermc.paper.event.player.PlayerInventorySlotChangeEvent.getHandlerList().getRegisteredListeners().length == 0) { @@ -40,7 +41,7 @@ + } + io.papermc.paper.event.player.PlayerInventorySlotChangeEvent event = new io.papermc.paper.event.player.PlayerInventorySlotChangeEvent( + ServerPlayer.this.getBukkitEntity(), -+ slotId, ++ dataSlotIndex, + org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(oldStack), + org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(stack) + ); @@ -100,7 +101,7 @@ public ServerPlayer(MinecraftServer server, ServerLevel level, GameProfile gameProfile, ClientInformation clientInformation) { super(level, level.getSharedSpawnPos(), level.getSharedSpawnAngle(), gameProfile); -@@ -328,16 +_,71 @@ +@@ -328,16 +_,22 @@ this.server = server; this.stats = server.getPlayerList().getPlayerStats(this); this.advancements = server.getPlayerList().getPlayerAdvancements(this); @@ -115,55 +116,6 @@ + this.adventure$displayName = net.kyori.adventure.text.Component.text(this.getScoreboardName()); // Paper + this.bukkitPickUpLoot = true; + this.maxHealthCache = this.getMaxHealth(); -+ } -+ -+ // Use method to resend items in hands in case of client desync, because the item use got cancelled. -+ // For example, when cancelling the leash event -+ @Deprecated // Paper - this shouldn't be used, use the regular sendAllDataToRemote call to resync all -+ public void resendItemInHands() { -+ this.containerMenu.findSlot(this.getInventory(), this.getInventory().selected).ifPresent(s -> { -+ this.containerSynchronizer.sendSlotChange(this.containerMenu, s, this.getMainHandItem()); -+ }); -+ this.containerSynchronizer.sendSlotChange(this.inventoryMenu, net.minecraft.world.inventory.InventoryMenu.SHIELD_SLOT, this.getOffhandItem()); -+ } -+ -+ // Yes, this doesn't match Vanilla, but it's the best we can do for now. -+ // If this is an issue, PRs are welcome -+ public final BlockPos getSpawnPoint(ServerLevel worldserver) { -+ BlockPos blockposition = worldserver.getSharedSpawnPos(); -+ -+ if (worldserver.dimensionType().hasSkyLight() && worldserver.serverLevelData.getGameType() != GameType.ADVENTURE) { -+ int i = Math.max(0, this.server.getSpawnRadius(worldserver)); -+ int j = Mth.floor(worldserver.getWorldBorder().getDistanceToBorder((double) blockposition.getX(), (double) blockposition.getZ())); -+ -+ if (j < i) { -+ i = j; -+ } -+ -+ if (j <= 1) { -+ i = 1; -+ } -+ -+ long k = (long) (i * 2 + 1); -+ long l = k * k; -+ int i1 = l > 2147483647L ? Integer.MAX_VALUE : (int) l; -+ int j1 = this.getCoprime(i1); -+ int k1 = RandomSource.create().nextInt(i1); -+ -+ for (int l1 = 0; l1 < i1; ++l1) { -+ int i2 = (k1 + j1 * l1) % i1; -+ int j2 = i2 % (i * 2 + 1); -+ int k2 = i2 / (i * 2 + 1); -+ BlockPos blockposition1 = PlayerRespawnLogic.getOverworldRespawnPos(worldserver, blockposition.getX() + j2 - i, blockposition.getZ() + k2 - i); -+ -+ if (blockposition1 != null) { -+ return blockposition1; -+ } -+ } -+ } -+ -+ return blockposition; -+ // CraftBukkit end } @Override diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch index b77ca19e9f..da4d2fc24d 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -974,13 +974,12 @@ leashable.removeLeash(); } else { leashable.dropLeash(); -@@ -2043,6 +_,14 @@ +@@ -2043,6 +_,13 @@ ItemStack itemInHand = player.getItemInHand(hand); if (itemInHand.is(Items.LEAD) && leashable.canHaveALeashAttachedToIt()) { if (!this.level().isClientSide()) { + // CraftBukkit start - fire PlayerLeashEntityEvent + if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(this, player, player, hand).isCancelled()) { -+ // ((ServerPlayer) player).resendItemInHands(); // SPIGOT-7615: Resend to fix client desync with used item // Paper - Fix inventory desync + ((ServerPlayer) player).connection.send(new net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket(this, leashable.getLeashHolder())); + player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync + return InteractionResult.PASS;