Commits

DerFrZocker authored and md_5 committed dd0a2183007
SPIGOT-5607: PlayerInteractEvent Left-Click Bug
No tags

nms-patches/net/minecraft/server/network/PlayerConnection.patch

Modified
1162 1162 - return CompletableFuture.completedFuture((Object) null);
1163 1163 + return CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
1164 1164 }
1165 1165 }
1166 1166
1167 1167 - return CompletableFuture.completedFuture((Object) null);
1168 1168 + return CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
1169 1169 }
1170 1170 }
1171 1171
1172 -@@ -1611,13 +2299,65 @@
1172 +@@ -1611,13 +2299,59 @@
1173 1173 @Override
1174 1174 public void handleAnimate(PacketPlayInArmAnimation packetplayinarmanimation) {
1175 1175 PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinarmanimation, this, this.player.getLevel());
1176 1176 + if (this.player.isImmobile()) return; // CraftBukkit
1177 1177 this.player.resetLastActionTime();
1178 1178 + // CraftBukkit start - Raytrace to look for 'rogue armswings'
1179 1179 + float f1 = this.player.getXRot();
1180 1180 + float f2 = this.player.getYRot();
1181 1181 + double d0 = this.player.getX();
1182 1182 + double d1 = this.player.getY() + (double) this.player.getEyeHeight();
1183 1183 + double d2 = this.player.getZ();
1184 -+ Vec3D vec3d = new Vec3D(d0, d1, d2);
1185 -+
1186 -+ float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F);
1187 -+ float f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F);
1188 -+ float f5 = -MathHelper.cos(-f1 * 0.017453292F);
1189 -+ float f6 = MathHelper.sin(-f1 * 0.017453292F);
1190 -+ float f7 = f4 * f5;
1191 -+ float f8 = f3 * f5;
1192 -+ double d3 = player.gameMode.getGameModeForPlayer()== EnumGamemode.CREATIVE ? 5.0D : 4.5D;
1193 -+ Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3);
1194 -+ MovingObjectPosition movingobjectposition = this.player.level.clip(new RayTrace(vec3d, vec3d1, RayTrace.BlockCollisionOption.OUTLINE, RayTrace.FluidCollisionOption.NONE, player));
1195 -+
1196 -+ if (movingobjectposition == null || movingobjectposition.getType() != MovingObjectPosition.EnumMovingObjectType.BLOCK) {
1184 ++ Location origin = new Location(this.player.level.getWorld(), d0, d1, d2, f2, f1);
1185 ++
1186 ++ double d3 = player.gameMode.getGameModeForPlayer() == EnumGamemode.CREATIVE ? 5.0D : 4.5D;
1187 ++ // SPIGOT-5607: Only call interact event if no block or entity is being clicked. Use bukkit ray trace method, because it handles blocks and entities at the same time
1188 ++ org.bukkit.util.RayTraceResult result = this.player.level.getWorld().rayTrace(origin, origin.getDirection(), d3, org.bukkit.FluidCollisionMode.NEVER, false, 0.1, entity -> entity != this.player.getBukkitEntity());
1189 ++
1190 ++ if (result == null) {
1197 1191 + CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_AIR, this.player.getInventory().getSelected(), EnumHand.MAIN_HAND);
1198 1192 + }
1199 1193 +
1200 1194 + // Arm swing animation
1201 1195 + PlayerAnimationEvent event = new PlayerAnimationEvent(this.getCraftPlayer(), (packetplayinarmanimation.getHand() == EnumHand.MAIN_HAND) ? PlayerAnimationType.ARM_SWING : PlayerAnimationType.OFF_ARM_SWING);
1202 1196 + this.cserver.getPluginManager().callEvent(event);
1203 1197 +
1204 1198 + if (event.isCancelled()) return;
1205 1199 + // CraftBukkit end
1206 1200 this.player.swing(packetplayinarmanimation.getHand());
1228 1222 +
1229 1223 + if (e2.isCancelled()) {
1230 1224 + return;
1231 1225 + }
1232 1226 + break;
1233 1227 + }
1234 1228 + // CraftBukkit end
1235 1229 this.player.resetLastActionTime();
1236 1230 IJumpable ijumpable;
1237 1231
1238 -@@ -1702,6 +2442,7 @@
1232 +@@ -1702,6 +2436,7 @@
1239 1233 @Override
1240 1234 public void handleInteract(PacketPlayInUseEntity packetplayinuseentity) {
1241 1235 PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinuseentity, this, this.player.getLevel());
1242 1236 + if (this.player.isImmobile()) return; // CraftBukkit
1243 1237 WorldServer worldserver = this.player.getLevel();
1244 1238 final Entity entity = packetplayinuseentity.getTarget(worldserver);
1245 1239
1246 -@@ -1714,10 +2455,49 @@
1240 +@@ -1714,10 +2449,49 @@
1247 1241
1248 1242 if (entity.distanceToSqr(this.player.getEyePosition()) < PlayerConnection.MAX_INTERACTION_DISTANCE) {
1249 1243 packetplayinuseentity.dispatch(new PacketPlayInUseEntity.c() {
1250 1244 - private void performInteraction(EnumHand enumhand, PlayerConnection.a playerconnection_a) {
1251 1245 + private void performInteraction(EnumHand enumhand, PlayerConnection.a playerconnection_a, PlayerInteractEntityEvent event) { // CraftBukkit
1252 1246 ItemStack itemstack = PlayerConnection.this.player.getItemInHand(enumhand).copy();
1253 1247 + // CraftBukkit start
1254 1248 + ItemStack itemInHand = PlayerConnection.this.player.getItemInHand(enumhand);
1255 1249 + boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.LEAD && entity instanceof EntityInsentient;
1256 1250 + Item origItem = player.getInventory().getSelected() == null ? null : player.getInventory().getSelected().getItem();
1287 1281
1288 1282 + // CraftBukkit start
1289 1283 + if (!itemInHand.isEmpty() && itemInHand.getCount() <= -1) {
1290 1284 + player.containerMenu.sendAllDataToRemote();
1291 1285 + }
1292 1286 + // CraftBukkit end
1293 1287 +
1294 1288 if (enuminteractionresult.consumesAction()) {
1295 1289 CriterionTriggers.PLAYER_INTERACTED_WITH_ENTITY.trigger(PlayerConnection.this.player, itemstack, entity);
1296 1290 if (enuminteractionresult.shouldSwing()) {
1297 -@@ -1729,20 +2509,27 @@
1291 +@@ -1729,20 +2503,27 @@
1298 1292
1299 1293 @Override
1300 1294 public void onInteraction(EnumHand enumhand) {
1301 1295 - this.performInteraction(enumhand, EntityHuman::interactOn);
1302 1296 + this.performInteraction(enumhand, EntityHuman::interactOn, new PlayerInteractEntityEvent(getCraftPlayer(), entity.getBukkitEntity(), (enumhand == EnumHand.OFF_HAND) ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND));
1303 1297 }
1304 1298
1305 1299 @Override
1306 1300 public void onInteraction(EnumHand enumhand, Vec3D vec3d) {
1307 1301 this.performInteraction(enumhand, (entityplayer, entity1, enumhand1) -> {
1318 1312 + ItemStack itemInHand = PlayerConnection.this.player.getMainHandItem();
1319 1313 PlayerConnection.this.player.attack(entity);
1320 1314 +
1321 1315 + if (!itemInHand.isEmpty() && itemInHand.getCount() <= -1) {
1322 1316 + player.containerMenu.sendAllDataToRemote();
1323 1317 + }
1324 1318 + // CraftBukkit end
1325 1319 } else {
1326 1320 PlayerConnection.this.disconnect(IChatBaseComponent.translatable("multiplayer.disconnect.invalid_entity_attacked"));
1327 1321 PlayerConnection.LOGGER.warn("Player {} tried to attack an invalid entity", PlayerConnection.this.player.getName().getString());
1328 -@@ -1787,15 +2574,21 @@
1322 +@@ -1787,15 +2568,21 @@
1329 1323 @Override
1330 1324 public void handleContainerClose(PacketPlayInCloseWindow packetplayinclosewindow) {
1331 1325 PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinclosewindow, this, this.player.getLevel());
1332 1326 +
1333 1327 + if (this.player.isImmobile()) return; // CraftBukkit
1334 1328 + CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit
1335 1329 +
1336 1330 this.player.doCloseContainer();
1337 1331 }
1338 1332
1342 1336 + if (this.player.isImmobile()) return; // CraftBukkit
1343 1337 this.player.resetLastActionTime();
1344 1338 - if (this.player.containerMenu.containerId == packetplayinwindowclick.getContainerId()) {
1345 1339 - if (this.player.isSpectator()) {
1346 1340 + if (this.player.containerMenu.containerId == packetplayinwindowclick.getContainerId() && this.player.containerMenu.stillValid(this.player)) { // CraftBukkit
1347 1341 + boolean cancelled = this.player.isSpectator(); // CraftBukkit - see below if
1348 1342 + if (false/*this.player.isSpectator()*/) { // CraftBukkit
1349 1343 this.player.containerMenu.sendAllDataToRemote();
1350 1344 } else if (!this.player.containerMenu.stillValid(this.player)) {
1351 1345 PlayerConnection.LOGGER.debug("Player {} interacted with invalid menu {}", this.player, this.player.containerMenu);
1352 -@@ -1808,7 +2601,284 @@
1346 +@@ -1808,7 +2595,284 @@
1353 1347 boolean flag = packetplayinwindowclick.getStateId() != this.player.containerMenu.getStateId();
1354 1348
1355 1349 this.player.containerMenu.suppressRemoteUpdates();
1356 1350 - this.player.containerMenu.clicked(i, packetplayinwindowclick.getButtonNum(), packetplayinwindowclick.getClickType(), this.player);
1357 1351 + // CraftBukkit start - Call InventoryClickEvent
1358 1352 + if (packetplayinwindowclick.getSlotNum() < -1 && packetplayinwindowclick.getSlotNum() != -999) {
1359 1353 + return;
1360 1354 + }
1361 1355 +
1362 1356 + InventoryView inventory = this.player.containerMenu.getBukkitView();
1628 1622 + if (event instanceof CraftItemEvent || event instanceof SmithItemEvent) {
1629 1623 + // Need to update the inventory on crafting to
1630 1624 + // correctly support custom recipes
1631 1625 + player.containerMenu.sendAllDataToRemote();
1632 1626 + }
1633 1627 + }
1634 1628 + // CraftBukkit end
1635 1629 ObjectIterator objectiterator = Int2ObjectMaps.fastIterable(packetplayinwindowclick.getChangedSlots()).iterator();
1636 1630
1637 1631 while (objectiterator.hasNext()) {
1638 -@@ -1848,6 +2918,7 @@
1632 +@@ -1848,6 +2912,7 @@
1639 1633 @Override
1640 1634 public void handleContainerButtonClick(PacketPlayInEnchantItem packetplayinenchantitem) {
1641 1635 PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinenchantitem, this, this.player.getLevel());
1642 1636 + if (this.player.isImmobile()) return; // CraftBukkit
1643 1637 this.player.resetLastActionTime();
1644 1638 if (this.player.containerMenu.containerId == packetplayinenchantitem.getContainerId() && !this.player.isSpectator()) {
1645 1639 if (!this.player.containerMenu.stillValid(this.player)) {
1646 -@@ -1885,6 +2956,43 @@
1640 +@@ -1885,6 +2950,43 @@
1647 1641
1648 1642 boolean flag1 = packetplayinsetcreativeslot.getSlotNum() >= 1 && packetplayinsetcreativeslot.getSlotNum() <= 45;
1649 1643 boolean flag2 = itemstack.isEmpty() || itemstack.getDamageValue() >= 0 && itemstack.getCount() <= 64 && !itemstack.isEmpty();
1650 1644 + if (flag || (flag1 && !ItemStack.matches(this.player.inventoryMenu.getSlot(packetplayinsetcreativeslot.getSlotNum()).getItem(), packetplayinsetcreativeslot.getItem()))) { // Insist on valid slot
1651 1645 + // CraftBukkit start - Call click event
1652 1646 + InventoryView inventory = this.player.inventoryMenu.getBukkitView();
1653 1647 + org.bukkit.inventory.ItemStack item = CraftItemStack.asBukkitCopy(packetplayinsetcreativeslot.getItem());
1654 1648 +
1655 1649 + SlotType type = SlotType.QUICKBAR;
1656 1650 + if (flag) {
1680 1674 + this.player.connection.send(new PacketPlayOutSetSlot(this.player.inventoryMenu.containerId, this.player.inventoryMenu.incrementStateId(), packetplayinsetcreativeslot.getSlotNum(), this.player.inventoryMenu.getSlot(packetplayinsetcreativeslot.getSlotNum()).getItem()));
1681 1675 + this.player.connection.send(new PacketPlayOutSetSlot(-1, this.player.inventoryMenu.incrementStateId(), -1, ItemStack.EMPTY));
1682 1676 + }
1683 1677 + return;
1684 1678 + }
1685 1679 + }
1686 1680 + // CraftBukkit end
1687 1681
1688 1682 if (flag1 && flag2) {
1689 1683 this.player.inventoryMenu.getSlot(packetplayinsetcreativeslot.getSlotNum()).set(itemstack);
1690 -@@ -1907,6 +3015,7 @@
1684 +@@ -1907,6 +3009,7 @@
1691 1685 }
1692 1686
1693 1687 private void updateSignText(PacketPlayInUpdateSign packetplayinupdatesign, List<FilteredText> list) {
1694 1688 + if (this.player.isImmobile()) return; // CraftBukkit
1695 1689 this.player.resetLastActionTime();
1696 1690 WorldServer worldserver = this.player.getLevel();
1697 1691 BlockPosition blockposition = packetplayinupdatesign.getPos();
1698 -@@ -1923,18 +3032,37 @@
1692 +@@ -1923,18 +3026,37 @@
1699 1693
1700 1694 if (!tileentitysign.isEditable() || !this.player.getUUID().equals(tileentitysign.getPlayerWhoMayEdit())) {
1701 1695 PlayerConnection.LOGGER.warn("Player {} just tried to change non-editable sign", this.player.getName().getString());
1702 1696 + this.send(tileentity.getUpdatePacket()); // CraftBukkit
1703 1697 return;
1704 1698 }
1705 1699
1706 1700 + // CraftBukkit start
1707 1701 + Player player = this.player.getBukkitEntity();
1708 1702 + int x = packetplayinupdatesign.getPos().getX();
1728 1722 + IChatBaseComponent[] components = org.bukkit.craftbukkit.block.CraftSign.sanitizeLines(event.getLines());
1729 1723 + for (int i = 0; i < components.length; i++) {
1730 1724 + tileentitysign.setMessage(i, components[i]);
1731 1725 }
1732 1726 + tileentitysign.isEditable = false;
1733 1727 }
1734 1728 + // CraftBukkit end
1735 1729
1736 1730 tileentitysign.setChanged();
1737 1731 worldserver.sendBlockUpdated(blockposition, iblockdata, iblockdata, 3);
1738 -@@ -1944,6 +3072,7 @@
1732 +@@ -1944,6 +3066,7 @@
1739 1733
1740 1734 @Override
1741 1735 public void handleKeepAlive(PacketPlayInKeepAlive packetplayinkeepalive) {
1742 1736 + PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinkeepalive, this, this.player.getLevel()); // CraftBukkit
1743 1737 if (this.keepAlivePending && packetplayinkeepalive.getId() == this.keepAliveChallenge) {
1744 1738 int i = (int) (SystemUtils.getMillis() - this.keepAliveTime);
1745 1739
1746 -@@ -1958,7 +3087,17 @@
1740 +@@ -1958,7 +3081,17 @@
1747 1741 @Override
1748 1742 public void handlePlayerAbilities(PacketPlayInAbilities packetplayinabilities) {
1749 1743 PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinabilities, this, this.player.getLevel());
1750 1744 - this.player.getAbilities().flying = packetplayinabilities.isFlying() && this.player.getAbilities().mayfly;
1751 1745 + // CraftBukkit start
1752 1746 + if (this.player.getAbilities().mayfly && this.player.getAbilities().flying != packetplayinabilities.isFlying()) {
1753 1747 + PlayerToggleFlightEvent event = new PlayerToggleFlightEvent(this.player.getBukkitEntity(), packetplayinabilities.isFlying());
1754 1748 + this.cserver.getPluginManager().callEvent(event);
1755 1749 + if (!event.isCancelled()) {
1756 1750 + this.player.getAbilities().flying = packetplayinabilities.isFlying(); // Actually set the player's flying status
1757 1751 + } else {
1758 1752 + this.player.onUpdateAbilities(); // Tell the player their ability was reverted
1759 1753 + }
1760 1754 + }
1761 1755 + // CraftBukkit end
1762 1756 }
1763 1757
1764 1758 @Override
1765 -@@ -1967,8 +3106,50 @@
1759 +@@ -1967,8 +3100,50 @@
1766 1760 this.player.updateOptions(packetplayinsettings);
1767 1761 }
1768 1762
1769 1763 - @Override
1770 1764 - public void handleCustomPayload(PacketPlayInCustomPayload packetplayincustompayload) {}
1771 1765 + // CraftBukkit start
1772 1766 + private static final MinecraftKey CUSTOM_REGISTER = new MinecraftKey("register");
1773 1767 + private static final MinecraftKey CUSTOM_UNREGISTER = new MinecraftKey("unregister");
1774 1768 +
1775 1769 + @Override

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut