Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ public abstract class PlayerPickItemEvent extends PlayerEvent implements Cancell

private static final HandlerList HANDLER_LIST = new HandlerList();

private final boolean includeData;

private boolean includeData;
private int targetSlot;
private int sourceSlot;

Expand All @@ -48,6 +47,17 @@ public boolean isIncludeData() {
return includeData;
}

/**
* Sets whether block/entity data should be included.<br>
*
* This does not bypass gamemode and permission checks.
*
* @param includeData whether to include blopck/entity data
*/
public void setIncludeData(final boolean includeData) {
this.includeData = includeData;
}

/**
* Returns the slot the item that is being picked goes into.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Subject: [PATCH] Optimise collision checking in player move packet handling
Move collision logic to just the hasNewCollision call instead of getCubes + hasNewCollision

diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 92ce1962e9df66dbda6a3c0e25f6accdafbc4dc7..c6e5e45b1e97bbbfdae6804c313d499aaf3e6e50 100644
index 5dfd13beabb7ece9043c8f90a9e61e6389c3460b..d0446e202dcc7a8b1223822199840644763319b7 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -636,6 +636,7 @@ public class ServerGamePacketListenerImpl
Expand Down Expand Up @@ -72,7 +72,7 @@ index 92ce1962e9df66dbda6a3c0e25f6accdafbc4dc7..c6e5e45b1e97bbbfdae6804c313d499a
}

@Override
@@ -1544,7 +1578,7 @@ public class ServerGamePacketListenerImpl
@@ -1586,7 +1620,7 @@ public class ServerGamePacketListenerImpl
}
}

Expand All @@ -81,15 +81,15 @@ index 92ce1962e9df66dbda6a3c0e25f6accdafbc4dc7..c6e5e45b1e97bbbfdae6804c313d499a
xDist = targetX - this.lastGoodX; // Paper - diff on change, used for checking large move vectors above
yDist = targetY - this.lastGoodY; // Paper - diff on change, used for checking large move vectors above
zDist = targetZ - this.lastGoodZ; // Paper - diff on change, used for checking large move vectors above
@@ -1570,6 +1604,7 @@ public class ServerGamePacketListenerImpl
@@ -1612,6 +1646,7 @@ public class ServerGamePacketListenerImpl
boolean playerStandsOnSomething = this.player.verticalCollisionBelow;
this.player.move(MoverType.PLAYER, new Vec3(xDist, yDist, zDist));
this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move
+ final boolean didCollide = targetX != this.player.getX() || targetY != this.player.getY() || targetZ != this.player.getZ(); // Paper - needed here as the difference in Y can be reset - also note: this is only a guess at whether collisions took place, floating point errors can make this true when it shouldn't be...
// Paper start - prevent position desync
if (this.awaitingPositionFromClient != null) {
return; // ... thanks Mojang for letting move calls teleport across dimensions.
@@ -1603,7 +1638,17 @@ public class ServerGamePacketListenerImpl
@@ -1645,7 +1680,17 @@ public class ServerGamePacketListenerImpl
}

// Paper start - Add fail move event
Expand All @@ -108,7 +108,7 @@ index 92ce1962e9df66dbda6a3c0e25f6accdafbc4dc7..c6e5e45b1e97bbbfdae6804c313d499a
if (!allowMovement) {
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK,
targetX, targetY, targetZ, targetYRot, targetXRot, false);
@@ -1730,7 +1775,7 @@ public class ServerGamePacketListenerImpl
@@ -1772,7 +1817,7 @@ public class ServerGamePacketListenerImpl

private boolean updateAwaitingTeleport() {
if (this.awaitingPositionFromClient != null) {
Expand All @@ -117,7 +117,7 @@ index 92ce1962e9df66dbda6a3c0e25f6accdafbc4dc7..c6e5e45b1e97bbbfdae6804c313d499a
this.awaitingTeleportTime = this.tickCount;
this.teleport(
this.awaitingPositionFromClient.x,
@@ -1749,6 +1794,34 @@ public class ServerGamePacketListenerImpl
@@ -1791,6 +1836,34 @@ public class ServerGamePacketListenerImpl
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ index 3b28b39ebf252d8de46f7d0ce27037cdb041f1b5..0b6d7f99edde802cb464baa5a4b2b4a4
return savedChunks;
}
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index a61fb7d1c65b8b940d66f02e64c131b20a3ee610..b4434d534677403c68f1ff657c42736333e2e15e 100644
index d0446e202dcc7a8b1223822199840644763319b7..cc7d66f9d7d9f206417dc080dda2a89e5c81dbe3 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1798,9 +1798,14 @@ public class ServerGamePacketListenerImpl
@@ -1840,9 +1840,14 @@ public class ServerGamePacketListenerImpl
private boolean hasNewCollision(final ServerLevel level, final Entity entity, final AABB oldBox, final AABB newBox) {
final List<AABB> collisionsBB = new java.util.ArrayList<>();
final List<VoxelShape> collisionsVoxel = new java.util.ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -514,67 +514,120 @@
this.player.sendSystemMessage(Component.translatable("advMode.notAllowed"));
} else {
BaseCommandBlock commandBlock = packet.getCommandBlock(this.player.level());
@@ -706,11 +_,11 @@
@@ -704,14 +_,7 @@
if (level.isLoaded(pos)) {
BlockState blockState = level.getBlockState(pos);
boolean includeData = this.player.hasInfiniteMaterials() && packet.includeData();
ItemStack itemStack = blockState.getCloneItemStack(level, pos, includeData);
if (!itemStack.isEmpty()) {
- ItemStack itemStack = blockState.getCloneItemStack(level, pos, includeData);
- if (!itemStack.isEmpty()) {
- if (includeData) {
+ if (includeData && this.player.getBukkitEntity().hasPermission("minecraft.nbt.copy")) { // Spigot
addBlockDataToItem(blockState, level, pos, itemStack);
}

- addBlockDataToItem(blockState, level, pos, itemStack);
- }
-
- this.tryPickItem(itemStack);
+ this.tryPickItem(itemStack, pos, null, packet.includeData()); // Paper - Extend PlayerPickItemEvent API
}
- }
+ tryPickItemFromBlock(level, pos, blockState, includeData); // Paper - Make includeData mutable for PlayerPickItemEvent
}
}
}
@@ -737,7 +_,7 @@
if (entity != null && this.player.isWithinEntityInteractionRange(entity, 3.0)) {
ItemStack itemStack = entity.getPickResult();
if (itemStack != null && !itemStack.isEmpty()) {
- this.tryPickItem(itemStack);
+ this.tryPickItem(itemStack, null, entity, packet.includeData()); // Paper - Extend PlayerPickItemEvent API
+ this.tryPickItemFromEntity(entity, packet.includeData(), itemStack); // Paper - Make includeData mutable for PlayerPickItemEvent
}

if (packet.includeData() && this.player.canUseGameMasterBlocks() && entity instanceof Avatar avatar) {
@@ -746,22 +_,35 @@
@@ -746,22 +_,84 @@
}
}

- private void tryPickItem(final ItemStack itemStack) {
+ private void tryPickItem(ItemStack itemStack, @Nullable BlockPos blockPos, @Nullable Entity entity, boolean includeData) { // Paper - Extend PlayerPickItemEvent API
if (itemStack.isItemEnabled(this.player.level().enabledFeatures())) {
Inventory inventory = this.player.getInventory();
int slotWithExistingItem = inventory.findSlotMatchingItem(itemStack);
+ // Paper start - Add PlayerPickItemEvent
+ final int sourceSlot = slotWithExistingItem;
+ // Paper start - Make includeData mutable for PlayerPickItemEvent
+ private void tryPickItemFromBlock(
+ ServerLevel level, BlockPos pos, BlockState blockState, boolean initialIncludeData
+ ) {
+ ItemStack previewStack = blockState.getCloneItemStack(level, pos, initialIncludeData);
+ if (!previewStack.isEmpty()) {
+ if (initialIncludeData && this.player.getBukkitEntity().hasPermission("minecraft.nbt.copy")) {
+ addBlockDataToItem(blockState, level, pos, previewStack);
+ }
+
+ Inventory inventory = this.player.getInventory();
+ final int sourceSlot = inventory.findSlotMatchingItem(previewStack);
+ final int targetSlot = Inventory.isHotbarSlot(sourceSlot) ? sourceSlot : inventory.getSuitableHotbarSlot();
+ final org.bukkit.entity.Player bukkitPlayer = this.player.getBukkitEntity();
+ final io.papermc.paper.event.player.PlayerPickItemEvent event = entity != null
+ ? new io.papermc.paper.event.player.PlayerPickEntityEvent(bukkitPlayer, entity.getBukkitEntity(), includeData, targetSlot, sourceSlot)
+ : new io.papermc.paper.event.player.PlayerPickBlockEvent(bukkitPlayer, org.bukkit.craftbukkit.block.CraftBlock.at(this.player.level(), blockPos), includeData, targetSlot, sourceSlot);
+
+ io.papermc.paper.event.player.PlayerPickBlockEvent event = new io.papermc.paper.event.player.PlayerPickBlockEvent(
+ this.player.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), initialIncludeData, targetSlot, sourceSlot
+ );
+
+ if (!event.callEvent()) {
+ return;
+ }
+ slotWithExistingItem = event.getSourceSlot();
+ // Paper end - Add PlayerPickItemEvent
if (slotWithExistingItem != Inventory.NOT_FOUND_INDEX) {
+
+ ItemStack stack;
+ if (initialIncludeData != event.isIncludeData()) {
+ stack = blockState.getCloneItemStack(level, pos, initialIncludeData);
+ if (event.isIncludeData() && this.player.getBukkitEntity().hasPermission("minecraft.nbt.copy")) {
+ addBlockDataToItem(blockState, level, pos, previewStack);
+ }
+ } else {
+ stack = previewStack;
+ }
+
+ this.tryPickItem(stack, event.getSourceSlot(), event.getTargetSlot());
+ }
+ }
+
+ private void tryPickItemFromEntity(
+ Entity entity, boolean initialIncludeData, ItemStack itemStack
+ ) {
+ Inventory inventory = this.player.getInventory();
+ final int sourceSlot = inventory.findSlotMatchingItem(itemStack);
+ final int targetSlot = Inventory.isHotbarSlot(sourceSlot) ? sourceSlot : inventory.getSuitableHotbarSlot();
+
+ io.papermc.paper.event.player.PlayerPickEntityEvent event = new io.papermc.paper.event.player.PlayerPickEntityEvent(
+ this.player.getBukkitEntity(), entity.getBukkitEntity(), initialIncludeData, targetSlot, sourceSlot
+ );
+
+ if (!event.callEvent()) {
+ return;
+ }
+
+ if (initialIncludeData != event.isIncludeData()) {
+ // This currently has no effect
+ }
+
+ this.tryPickItem(itemStack, event.getSourceSlot(), event.getTargetSlot());
+ }
+ // Paper end - Make includeData mutable for PlayerPickItemEvent
+
+ private void tryPickItem(ItemStack itemStack, int sourceSlot, int targetSlot) { // Paper - Make includeData mutable for PlayerPickItemEvent
if (itemStack.isItemEnabled(this.player.level().enabledFeatures())) {
Inventory inventory = this.player.getInventory();
- int slotWithExistingItem = inventory.findSlotMatchingItem(itemStack);
- if (slotWithExistingItem != Inventory.NOT_FOUND_INDEX) {
- if (Inventory.isHotbarSlot(slotWithExistingItem)) {
- inventory.setSelectedSlot(slotWithExistingItem);
+ if (Inventory.isHotbarSlot(slotWithExistingItem) && Inventory.isHotbarSlot(event.getTargetSlot())) { // Paper - Add PlayerPickItemEvent
+ inventory.setSelectedSlot(event.getTargetSlot()); // Paper - Add PlayerPickItemEvent
+
+ if (sourceSlot != Inventory.NOT_FOUND_INDEX) { // Paper - Make includeData mutable for PlayerPickItemEvent
+ if (Inventory.isHotbarSlot(sourceSlot) && Inventory.isHotbarSlot(targetSlot)) { // Paper - Make includeData mutable for PlayerPickItemEvent
+ inventory.setSelectedSlot(targetSlot); // Paper - Make includeData mutable for PlayerPickItemEvent
} else {
- inventory.pickSlot(slotWithExistingItem);
+ inventory.pickSlot(slotWithExistingItem, event.getTargetSlot()); // Paper - Add PlayerPickItemEvent
+ inventory.pickSlot(sourceSlot, targetSlot); // Paper - Make includeData mutable for PlayerPickItemEvent
}
} else if (this.player.hasInfiniteMaterials()) {
- inventory.addAndPickItem(itemStack);
+ inventory.addAndPickItem(itemStack, event.getTargetSlot()); // Paper - Add PlayerPickItemEvent
+ inventory.addAndPickItem(itemStack, targetSlot); // Paper - Make includeData mutable for PlayerPickItemEvent
}

this.send(new ClientboundSetHeldSlotPacket(inventory.getSelectedSlot()));
this.player.inventoryMenu.broadcastChanges();
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes.
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions)
+ this.player.detectEquipmentUpdates(); // Paper - Force update attributes.
}
}

Expand Down
Loading