Commits

md_5 authored 5cc9c022a0b
SPIGOT-7152: Handle hand item changing during air interact event
No tags

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

Modified
605 605 + this.teleport(d0, d1, d2, f, f1, PlayerTeleportEvent.TeleportCause.UNKNOWN);
606 606 + }
607 607 +
608 608 + public void teleport(double d0, double d1, double d2, float f, float f1, PlayerTeleportEvent.TeleportCause cause) {
609 609 + this.teleport(d0, d1, d2, f, f1, Collections.emptySet(), false, cause);
610 610 }
611 611
612 612 public void teleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set) {
613 613 - this.teleport(d0, d1, d2, f, f1, set, false);
614 614 + this.teleport(d0, d1, d2, f, f1, set, PlayerTeleportEvent.TeleportCause.UNKNOWN);
615 -+ }
616 -+
615 + }
616 +
617 +- public void teleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, boolean flag) {
617 618 + public void teleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, PlayerTeleportEvent.TeleportCause cause) {
618 619 + this.teleport(d0, d1, d2, f, f1, set, false, cause);
619 620 + }
620 621 +
621 622 + public boolean teleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, boolean flag, PlayerTeleportEvent.TeleportCause cause) { // CraftBukkit - Return event status
622 623 + Player player = this.getCraftPlayer();
623 624 + Location from = player.getLocation();
624 625 +
625 626 + double x = d0;
626 627 + double y = d1;
643 644 + to = event.isCancelled() ? event.getFrom() : event.getTo();
644 645 + d0 = to.getX();
645 646 + d1 = to.getY();
646 647 + d2 = to.getZ();
647 648 + f = to.getYaw();
648 649 + f1 = to.getPitch();
649 650 + }
650 651 +
651 652 + this.internalTeleport(d0, d1, d2, f, f1, set, flag);
652 653 + return event.isCancelled(); // CraftBukkit - Return event status
653 - }
654 -
655 -- public void teleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, boolean flag) {
654 ++ }
655 ++
656 656 + public void teleport(Location dest) {
657 657 + internalTeleport(dest.getX(), dest.getY(), dest.getZ(), dest.getYaw(), dest.getPitch(), Collections.<PacketPlayOutPosition.EnumPlayerTeleportFlags>emptySet(), true);
658 658 + }
659 659 +
660 660 + private void internalTeleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, boolean flag) {
661 661 + // CraftBukkit start
662 662 + if (Float.isNaN(f)) {
663 663 + f = 0;
664 664 + }
665 665 + if (Float.isNaN(f1)) {
760 760
761 761 if (enumdirection == EnumDirection.UP && !enuminteractionresult.consumesAction() && blockposition.getY() >= i - 1 && wasBlockPlacementAttempt(this.player, itemstack)) {
762 762 @@ -1193,6 +1639,7 @@
763 763 @Override
764 764 public void handleUseItem(PacketPlayInBlockPlace packetplayinblockplace) {
765 765 PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinblockplace, this, this.player.getLevel());
766 766 + if (this.player.isImmobile()) return; // CraftBukkit
767 767 this.ackBlockChangesUpTo(packetplayinblockplace.getSequence());
768 768 WorldServer worldserver = this.player.getLevel();
769 769 EnumHand enumhand = packetplayinblockplace.getHand();
770 -@@ -1200,6 +1647,44 @@
770 +@@ -1200,6 +1647,49 @@
771 771
772 772 this.player.resetLastActionTime();
773 773 if (!itemstack.isEmpty()) {
774 774 + // CraftBukkit start
775 775 + // Raytrace to look for 'rogue armswings'
776 776 + float f1 = this.player.getXRot();
777 777 + float f2 = this.player.getYRot();
778 778 + double d0 = this.player.getX();
779 779 + double d1 = this.player.getY() + (double) this.player.getEyeHeight();
780 780 + double d2 = this.player.getZ();
802 802 + org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, movingobjectpositionblock.getBlockPos(), movingobjectpositionblock.getDirection(), itemstack, true, enumhand);
803 803 + cancelled = event.useItemInHand() == Event.Result.DENY;
804 804 + }
805 805 + player.gameMode.firedInteract = false;
806 806 + }
807 807 +
808 808 + if (cancelled) {
809 809 + this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524
810 810 + return;
811 811 + }
812 ++ itemstack = this.player.getItemInHand(enumhand); // Update in case it was changed in the event
813 ++ if (itemstack.isEmpty()) {
814 ++ return;
815 ++ }
816 ++ // CraftBukkit end
812 817 EnumInteractionResult enuminteractionresult = this.player.gameMode.useItem(this.player, worldserver, itemstack, enumhand);
813 818
814 819 if (enuminteractionresult.shouldSwing()) {
815 -@@ -1220,7 +1705,7 @@
820 +@@ -1220,7 +1710,7 @@
816 821 Entity entity = packetplayinspectate.getEntity(worldserver);
817 822
818 823 if (entity != null) {
819 824 - this.player.teleportTo(worldserver, entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot());
820 825 + this.player.teleportTo(worldserver, entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot(), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit
821 826 return;
822 827 }
823 828 }
824 -@@ -1235,6 +1720,7 @@
829 +@@ -1235,6 +1725,7 @@
825 830 PlayerConnection.LOGGER.info("Disconnecting {} due to resource pack rejection", this.player.getName());
826 831 this.disconnect(IChatBaseComponent.translatable("multiplayer.requiredTexturePrompt.disconnect"));
827 832 }
828 833 + this.cserver.getPluginManager().callEvent(new PlayerResourcePackStatusEvent(getCraftPlayer(), PlayerResourcePackStatusEvent.Status.values()[packetplayinresourcepackstatus.action.ordinal()])); // CraftBukkit
829 834
830 835 }
831 836
832 -@@ -1254,11 +1740,26 @@
837 +@@ -1254,11 +1745,26 @@
833 838
834 839 @Override
835 840 public void onDisconnect(IChatBaseComponent ichatbasecomponent) {
836 841 + // CraftBukkit start - Rarely it would send a disconnect line twice
837 842 + if (this.processedDisconnect) {
838 843 + return;
839 844 + } else {
840 845 + this.processedDisconnect = true;
841 846 + }
842 847 + // CraftBukkit end
850 855 this.player.disconnect();
851 856 - this.server.getPlayerList().remove(this.player);
852 857 + String quitMessage = this.server.getPlayerList().remove(this.player);
853 858 + if ((quitMessage != null) && (quitMessage.length() > 0)) {
854 859 + this.server.getPlayerList().broadcastMessage(CraftChatMessage.fromString(quitMessage));
855 860 + }
856 861 + // CraftBukkit end
857 862 this.player.getTextFilter().leave();
858 863 if (this.isSingleplayerOwner()) {
859 864 PlayerConnection.LOGGER.info("Stopping singleplayer server as player logged out");
860 -@@ -1281,6 +1782,15 @@
865 +@@ -1281,6 +1787,15 @@
861 866 }
862 867
863 868 public void send(Packet<?> packet, @Nullable PacketSendListener packetsendlistener) {
864 869 + // CraftBukkit start
865 870 + if (packet == null) {
866 871 + return;
867 872 + } else if (packet instanceof PacketPlayOutSpawnPosition) {
868 873 + PacketPlayOutSpawnPosition packet6 = (PacketPlayOutSpawnPosition) packet;
869 874 + this.player.compassTarget = new Location(this.getCraftPlayer().getWorld(), packet6.pos.getX(), packet6.pos.getY(), packet6.pos.getZ());
870 875 + }
871 876 + // CraftBukkit end
872 877 +
873 878 try {
874 879 this.connection.send(packet, packetsendlistener);
875 880 } catch (Throwable throwable) {
876 -@@ -1297,7 +1807,16 @@
881 +@@ -1297,7 +1812,16 @@
877 882 @Override
878 883 public void handleSetCarriedItem(PacketPlayInHeldItemSlot packetplayinhelditemslot) {
879 884 PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinhelditemslot, this, this.player.getLevel());
880 885 + if (this.player.isImmobile()) return; // CraftBukkit
881 886 if (packetplayinhelditemslot.getSlot() >= 0 && packetplayinhelditemslot.getSlot() < PlayerInventory.getSelectionSize()) {
882 887 + PlayerItemHeldEvent event = new PlayerItemHeldEvent(this.getCraftPlayer(), this.player.getInventory().selected, packetplayinhelditemslot.getSlot());
883 888 + this.cserver.getPluginManager().callEvent(event);
884 889 + if (event.isCancelled()) {
885 890 + this.send(new PacketPlayOutHeldItemSlot(this.player.getInventory().selected));
886 891 + this.player.resetLastActionTime();
887 892 + return;
888 893 + }
889 894 + // CraftBukkit end
890 895 if (this.player.getInventory().selected != packetplayinhelditemslot.getSlot() && this.player.getUsedItemHand() == EnumHand.MAIN_HAND) {
891 896 this.player.stopUsingItem();
892 897 }
893 -@@ -1306,16 +1825,23 @@
898 +@@ -1306,16 +1830,23 @@
894 899 this.player.resetLastActionTime();
895 900 } else {
896 901 PlayerConnection.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString());
897 902 + this.disconnect("Invalid hotbar selection (Hacking?)"); // CraftBukkit
898 903 }
899 904 }
900 905
901 906 @Override
902 907 public void handleChat(PacketPlayInChat packetplayinchat) {
903 908 + // CraftBukkit start - async chat
908 913 + // CraftBukkit end
909 914 if (isChatMessageIllegal(packetplayinchat.message())) {
910 915 this.disconnect(IChatBaseComponent.translatable("multiplayer.disconnect.illegal_characters"));
911 916 } else {
912 917 if (this.tryHandleChat(packetplayinchat.message(), packetplayinchat.timeStamp(), packetplayinchat.lastSeenMessages())) {
913 918 - this.server.submit(() -> {
914 919 + // this.server.submit(() -> { // CraftBukkit - async chat
915 920 PlayerChatMessage playerchatmessage = this.getSignedMessage(packetplayinchat);
916 921
917 922 if (this.verifyChatMessage(playerchatmessage)) {
918 -@@ -1328,10 +1854,10 @@
923 +@@ -1328,10 +1859,10 @@
919 924 PlayerChatMessage playerchatmessage1 = ((PlayerChatMessage) completablefuture1.join()).filter(filtermask);
920 925
921 926 this.broadcastChatMessage(playerchatmessage1);
922 927 - }, this.server);
923 928 + }, this.server.chatExecutor); // CraftBukkit - async chat
924 929 });
925 930 }
926 931 - });
927 932 + // }); // CraftBukkit - async chat
928 933 }
929 934
930 935 }
931 -@@ -1353,8 +1879,21 @@
936 +@@ -1353,8 +1884,21 @@
932 937 }
933 938
934 939 private void performChatCommand(ServerboundChatCommandPacket serverboundchatcommandpacket) {
935 940 - ParseResults<CommandListenerWrapper> parseresults = this.parseCommand(serverboundchatcommandpacket.command());
936 941 - Map<String, PlayerChatMessage> map = this.collectSignedArguments(serverboundchatcommandpacket, PreviewableCommand.of(parseresults));
937 942 + // CraftBukkit start
938 943 + String command = "/" + serverboundchatcommandpacket.command();
939 944 + PlayerConnection.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + command);
940 945 +
941 946 + PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(getCraftPlayer(), command, new LazyPlayerSet(server));
945 950 + return;
946 951 + }
947 952 + command = event.getMessage().substring(1);
948 953 +
949 954 + ParseResults<CommandListenerWrapper> parseresults = this.parseCommand(command);
950 955 + Map<String, PlayerChatMessage> map = (serverboundchatcommandpacket.command().equals(command)) ? this.collectSignedArguments(serverboundchatcommandpacket, PreviewableCommand.of(parseresults)) : Collections.emptyMap();
951 956 + // CraftBukkit end
952 957 Iterator iterator = map.values().iterator();
953 958
954 959 PlayerChatMessage playerchatmessage;
955 -@@ -1366,7 +1905,7 @@
960 +@@ -1366,7 +1910,7 @@
956 961 parseresults = CommandDispatcher.mapSource(parseresults, (commandlistenerwrapper) -> {
957 962 return commandlistenerwrapper.withSigningContext(commandsigningcontext_a);
958 963 });
959 964 - this.server.getCommands().performCommand(parseresults, serverboundchatcommandpacket.command());
960 965 + this.server.getCommands().performCommand(parseresults, command); // CraftBukkit
961 966 return;
962 967 }
963 968
964 -@@ -1415,7 +1954,7 @@
969 +@@ -1415,7 +1959,7 @@
965 970 PlayerConnection.LOGGER.warn("{} sent out-of-order chat: '{}'", this.player.getName().getString(), s);
966 971 this.disconnect(IChatBaseComponent.translatable("multiplayer.disconnect.out_of_order_chat"));
967 972 return false;
968 973 - } else if (this.player.getChatVisibility() == EnumChatVisibility.HIDDEN) {
969 974 + } else if (this.player.isRemoved() || this.player.getChatVisibility() == EnumChatVisibility.HIDDEN) { // CraftBukkit - dead men tell no tales
970 975 this.send(new ClientboundSystemChatPacket(IChatBaseComponent.translatable("chat.disabled.options").withStyle(EnumChatFormat.RED), false));
971 976 return false;
972 977 } else {
973 -@@ -1459,6 +1998,135 @@
978 +@@ -1459,6 +2003,135 @@
974 979 return false;
975 980 }
976 981
977 982 + // CraftBukkit start - add method
978 983 + public void chat(String s, PlayerChatMessage original, boolean async) {
979 984 + if (s.isEmpty() || this.player.getChatVisibility() == EnumChatVisibility.HIDDEN) {
980 985 + return;
981 986 + }
982 987 + OutgoingPlayerChatMessage outgoing = OutgoingPlayerChatMessage.create(original);
983 988 +
1099 1104 + player.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command");
1100 1105 + java.util.logging.Logger.getLogger(PlayerConnection.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
1101 1106 + return;
1102 1107 + }
1103 1108 + }
1104 1109 + // CraftBukkit end
1105 1110 +
1106 1111 private PlayerChatMessage getSignedMessage(PacketPlayInChat packetplayinchat) {
1107 1112 MessageSigner messagesigner = packetplayinchat.getSigner(this.player);
1108 1113 SignedMessageChain.c signedmessagechain_c = new SignedMessageChain.c(packetplayinchat.signature());
1109 -@@ -1475,7 +2143,28 @@
1114 +@@ -1475,7 +2148,28 @@
1110 1115 }
1111 1116
1112 1117 private void broadcastChatMessage(PlayerChatMessage playerchatmessage) {
1113 1118 - this.server.getPlayerList().broadcastChatMessage(playerchatmessage, this.player, ChatMessageType.bind(ChatMessageType.CHAT, (Entity) this.player));
1114 1119 + // CraftBukkit start
1115 1120 + String s = playerchatmessage.signedContent().plain();
1116 1121 + if (s.isEmpty()) {
1117 1122 + LOGGER.warn(this.player.getScoreboardName() + " tried to send an empty message");
1118 1123 + } else if (getCraftPlayer().isConversing()) {
1119 1124 + OutgoingPlayerChatMessage outgoing = OutgoingPlayerChatMessage.create(playerchatmessage);
1129 1134 + } else if (this.player.getChatVisibility() == EnumChatVisibility.SYSTEM) { // Re-add "Command Only" flag check
1130 1135 + this.send(new ClientboundSystemChatPacket(IChatBaseComponent.translatable("chat.cannotSend").withStyle(EnumChatFormat.RED), false));
1131 1136 + } else {
1132 1137 + this.chat(s, playerchatmessage, true);
1133 1138 + }
1134 1139 + // this.server.getPlayerList().broadcastChatMessage(playerchatmessage, this.player, ChatMessageType.bind(ChatMessageType.CHAT, (Entity) this.player));
1135 1140 + // CraftBukkit end
1136 1141 this.detectRateSpam();
1137 1142 }
1138 1143
1139 -@@ -1503,8 +2192,10 @@
1144 +@@ -1503,8 +2197,10 @@
1140 1145 }
1141 1146
1142 1147 private void detectRateSpam() {
1143 1148 - this.chatSpamTickCount += 20;
1144 1149 - if (this.chatSpamTickCount > 200 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) {
1145 1150 + // CraftBukkit start - replaced with thread safe throttle
1146 1151 + // this.chatSpamTickCount += 20;
1147 1152 + if (this.chatSpamTickCount.addAndGet(20) > 200 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) {
1148 1153 + // CraftBukkit end
1149 1154 this.disconnect(IChatBaseComponent.translatable("disconnect.spam"));
1150 1155 }
1151 1156
1152 -@@ -1568,7 +2259,7 @@
1157 +@@ -1568,7 +2264,7 @@
1153 1158 List<PreviewableCommand.a<CommandListenerWrapper>> list = previewablecommand.arguments();
1154 1159
1155 1160 if (list.isEmpty()) {
1156 1161 - return CompletableFuture.completedFuture((Object) null);
1157 1162 + return CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
1158 1163 } else {
1159 1164 for (int i = list.size() - 1; i >= 0; --i) {
1160 1165 PreviewableCommand.a previewablecommand_a = (PreviewableCommand.a) list.get(i);
1161 -@@ -1580,11 +2271,11 @@
1166 +@@ -1580,11 +2276,11 @@
1162 1167 return completablefuture;
1163 1168 }
1164 1169 } catch (CommandSyntaxException commandsyntaxexception) {
1165 1170 - return CompletableFuture.completedFuture((Object) null);
1166 1171 + return CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
1167 1172 }
1168 1173 }
1169 1174
1170 1175 - return CompletableFuture.completedFuture((Object) null);
1171 1176 + return CompletableFuture.completedFuture(null); // CraftBukkit - decompile error
1172 1177 }
1173 1178 }
1174 1179
1175 -@@ -1611,13 +2302,59 @@
1180 +@@ -1611,13 +2307,59 @@
1176 1181 @Override
1177 1182 public void handleAnimate(PacketPlayInArmAnimation packetplayinarmanimation) {
1178 1183 PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinarmanimation, this, this.player.getLevel());
1179 1184 + if (this.player.isImmobile()) return; // CraftBukkit
1180 1185 this.player.resetLastActionTime();
1181 1186 + // CraftBukkit start - Raytrace to look for 'rogue armswings'
1182 1187 + float f1 = this.player.getXRot();
1183 1188 + float f2 = this.player.getYRot();
1184 1189 + double d0 = this.player.getX();
1185 1190 + double d1 = this.player.getY() + (double) this.player.getEyeHeight();
1225 1230 +
1226 1231 + if (e2.isCancelled()) {
1227 1232 + return;
1228 1233 + }
1229 1234 + break;
1230 1235 + }
1231 1236 + // CraftBukkit end
1232 1237 this.player.resetLastActionTime();
1233 1238 IJumpable ijumpable;
1234 1239
1235 -@@ -1702,6 +2439,7 @@
1240 +@@ -1702,6 +2444,7 @@
1236 1241 @Override
1237 1242 public void handleInteract(PacketPlayInUseEntity packetplayinuseentity) {
1238 1243 PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinuseentity, this, this.player.getLevel());
1239 1244 + if (this.player.isImmobile()) return; // CraftBukkit
1240 1245 WorldServer worldserver = this.player.getLevel();
1241 1246 final Entity entity = packetplayinuseentity.getTarget(worldserver);
1242 1247
1243 -@@ -1714,10 +2452,49 @@
1248 +@@ -1714,10 +2457,49 @@
1244 1249
1245 1250 if (entity.distanceToSqr(this.player.getEyePosition()) < PlayerConnection.MAX_INTERACTION_DISTANCE) {
1246 1251 packetplayinuseentity.dispatch(new PacketPlayInUseEntity.c() {
1247 1252 - private void performInteraction(EnumHand enumhand, PlayerConnection.a playerconnection_a) {
1248 1253 + private void performInteraction(EnumHand enumhand, PlayerConnection.a playerconnection_a, PlayerInteractEntityEvent event) { // CraftBukkit
1249 1254 ItemStack itemstack = PlayerConnection.this.player.getItemInHand(enumhand).copy();
1250 1255 + // CraftBukkit start
1251 1256 + ItemStack itemInHand = PlayerConnection.this.player.getItemInHand(enumhand);
1252 1257 + boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.LEAD && entity instanceof EntityInsentient;
1253 1258 + Item origItem = player.getInventory().getSelected() == null ? null : player.getInventory().getSelected().getItem();
1284 1289
1285 1290 + // CraftBukkit start
1286 1291 + if (!itemInHand.isEmpty() && itemInHand.getCount() <= -1) {
1287 1292 + player.containerMenu.sendAllDataToRemote();
1288 1293 + }
1289 1294 + // CraftBukkit end
1290 1295 +
1291 1296 if (enuminteractionresult.consumesAction()) {
1292 1297 CriterionTriggers.PLAYER_INTERACTED_WITH_ENTITY.trigger(PlayerConnection.this.player, itemstack, entity);
1293 1298 if (enuminteractionresult.shouldSwing()) {
1294 -@@ -1729,20 +2506,27 @@
1299 +@@ -1729,20 +2511,27 @@
1295 1300
1296 1301 @Override
1297 1302 public void onInteraction(EnumHand enumhand) {
1298 1303 - this.performInteraction(enumhand, EntityHuman::interactOn);
1299 1304 + this.performInteraction(enumhand, EntityHuman::interactOn, new PlayerInteractEntityEvent(getCraftPlayer(), entity.getBukkitEntity(), (enumhand == EnumHand.OFF_HAND) ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND));
1300 1305 }
1301 1306
1302 1307 @Override
1303 1308 public void onInteraction(EnumHand enumhand, Vec3D vec3d) {
1304 1309 this.performInteraction(enumhand, (entityplayer, entity1, enumhand1) -> {
1315 1320 + ItemStack itemInHand = PlayerConnection.this.player.getMainHandItem();
1316 1321 PlayerConnection.this.player.attack(entity);
1317 1322 +
1318 1323 + if (!itemInHand.isEmpty() && itemInHand.getCount() <= -1) {
1319 1324 + player.containerMenu.sendAllDataToRemote();
1320 1325 + }
1321 1326 + // CraftBukkit end
1322 1327 } else {
1323 1328 PlayerConnection.this.disconnect(IChatBaseComponent.translatable("multiplayer.disconnect.invalid_entity_attacked"));
1324 1329 PlayerConnection.LOGGER.warn("Player {} tried to attack an invalid entity", PlayerConnection.this.player.getName().getString());
1325 -@@ -1787,15 +2571,21 @@
1330 +@@ -1787,15 +2576,21 @@
1326 1331 @Override
1327 1332 public void handleContainerClose(PacketPlayInCloseWindow packetplayinclosewindow) {
1328 1333 PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinclosewindow, this, this.player.getLevel());
1329 1334 +
1330 1335 + if (this.player.isImmobile()) return; // CraftBukkit
1331 1336 + CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit
1332 1337 +
1333 1338 this.player.doCloseContainer();
1334 1339 }
1335 1340
1339 1344 + if (this.player.isImmobile()) return; // CraftBukkit
1340 1345 this.player.resetLastActionTime();
1341 1346 - if (this.player.containerMenu.containerId == packetplayinwindowclick.getContainerId()) {
1342 1347 - if (this.player.isSpectator()) {
1343 1348 + if (this.player.containerMenu.containerId == packetplayinwindowclick.getContainerId() && this.player.containerMenu.stillValid(this.player)) { // CraftBukkit
1344 1349 + boolean cancelled = this.player.isSpectator(); // CraftBukkit - see below if
1345 1350 + if (false/*this.player.isSpectator()*/) { // CraftBukkit
1346 1351 this.player.containerMenu.sendAllDataToRemote();
1347 1352 } else if (!this.player.containerMenu.stillValid(this.player)) {
1348 1353 PlayerConnection.LOGGER.debug("Player {} interacted with invalid menu {}", this.player, this.player.containerMenu);
1349 -@@ -1808,7 +2598,284 @@
1354 +@@ -1808,7 +2603,284 @@
1350 1355 boolean flag = packetplayinwindowclick.getStateId() != this.player.containerMenu.getStateId();
1351 1356
1352 1357 this.player.containerMenu.suppressRemoteUpdates();
1353 1358 - this.player.containerMenu.clicked(i, packetplayinwindowclick.getButtonNum(), packetplayinwindowclick.getClickType(), this.player);
1354 1359 + // CraftBukkit start - Call InventoryClickEvent
1355 1360 + if (packetplayinwindowclick.getSlotNum() < -1 && packetplayinwindowclick.getSlotNum() != -999) {
1356 1361 + return;
1357 1362 + }
1358 1363 +
1359 1364 + InventoryView inventory = this.player.containerMenu.getBukkitView();
1625 1630 + if (event instanceof CraftItemEvent || event instanceof SmithItemEvent) {
1626 1631 + // Need to update the inventory on crafting to
1627 1632 + // correctly support custom recipes
1628 1633 + player.containerMenu.sendAllDataToRemote();
1629 1634 + }
1630 1635 + }
1631 1636 + // CraftBukkit end
1632 1637 ObjectIterator objectiterator = Int2ObjectMaps.fastIterable(packetplayinwindowclick.getChangedSlots()).iterator();
1633 1638
1634 1639 while (objectiterator.hasNext()) {
1635 -@@ -1848,6 +2915,7 @@
1640 +@@ -1848,6 +2920,7 @@
1636 1641 @Override
1637 1642 public void handleContainerButtonClick(PacketPlayInEnchantItem packetplayinenchantitem) {
1638 1643 PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinenchantitem, this, this.player.getLevel());
1639 1644 + if (this.player.isImmobile()) return; // CraftBukkit
1640 1645 this.player.resetLastActionTime();
1641 1646 if (this.player.containerMenu.containerId == packetplayinenchantitem.getContainerId() && !this.player.isSpectator()) {
1642 1647 if (!this.player.containerMenu.stillValid(this.player)) {
1643 -@@ -1885,6 +2953,43 @@
1648 +@@ -1885,6 +2958,43 @@
1644 1649
1645 1650 boolean flag1 = packetplayinsetcreativeslot.getSlotNum() >= 1 && packetplayinsetcreativeslot.getSlotNum() <= 45;
1646 1651 boolean flag2 = itemstack.isEmpty() || itemstack.getDamageValue() >= 0 && itemstack.getCount() <= 64 && !itemstack.isEmpty();
1647 1652 + if (flag || (flag1 && !ItemStack.matches(this.player.inventoryMenu.getSlot(packetplayinsetcreativeslot.getSlotNum()).getItem(), packetplayinsetcreativeslot.getItem()))) { // Insist on valid slot
1648 1653 + // CraftBukkit start - Call click event
1649 1654 + InventoryView inventory = this.player.inventoryMenu.getBukkitView();
1650 1655 + org.bukkit.inventory.ItemStack item = CraftItemStack.asBukkitCopy(packetplayinsetcreativeslot.getItem());
1651 1656 +
1652 1657 + SlotType type = SlotType.QUICKBAR;
1653 1658 + if (flag) {
1677 1682 + this.player.connection.send(new PacketPlayOutSetSlot(this.player.inventoryMenu.containerId, this.player.inventoryMenu.incrementStateId(), packetplayinsetcreativeslot.getSlotNum(), this.player.inventoryMenu.getSlot(packetplayinsetcreativeslot.getSlotNum()).getItem()));
1678 1683 + this.player.connection.send(new PacketPlayOutSetSlot(-1, this.player.inventoryMenu.incrementStateId(), -1, ItemStack.EMPTY));
1679 1684 + }
1680 1685 + return;
1681 1686 + }
1682 1687 + }
1683 1688 + // CraftBukkit end
1684 1689
1685 1690 if (flag1 && flag2) {
1686 1691 this.player.inventoryMenu.getSlot(packetplayinsetcreativeslot.getSlotNum()).set(itemstack);
1687 -@@ -1907,6 +3012,7 @@
1692 +@@ -1907,6 +3017,7 @@
1688 1693 }
1689 1694
1690 1695 private void updateSignText(PacketPlayInUpdateSign packetplayinupdatesign, List<FilteredText> list) {
1691 1696 + if (this.player.isImmobile()) return; // CraftBukkit
1692 1697 this.player.resetLastActionTime();
1693 1698 WorldServer worldserver = this.player.getLevel();
1694 1699 BlockPosition blockposition = packetplayinupdatesign.getPos();
1695 -@@ -1923,18 +3029,37 @@
1700 +@@ -1923,18 +3034,37 @@
1696 1701
1697 1702 if (!tileentitysign.isEditable() || !this.player.getUUID().equals(tileentitysign.getPlayerWhoMayEdit())) {
1698 1703 PlayerConnection.LOGGER.warn("Player {} just tried to change non-editable sign", this.player.getName().getString());
1699 1704 + this.send(tileentity.getUpdatePacket()); // CraftBukkit
1700 1705 return;
1701 1706 }
1702 1707
1703 1708 + // CraftBukkit start
1704 1709 + Player player = this.player.getBukkitEntity();
1705 1710 + int x = packetplayinupdatesign.getPos().getX();
1725 1730 + IChatBaseComponent[] components = org.bukkit.craftbukkit.block.CraftSign.sanitizeLines(event.getLines());
1726 1731 + for (int i = 0; i < components.length; i++) {
1727 1732 + tileentitysign.setMessage(i, components[i]);
1728 1733 }
1729 1734 + tileentitysign.isEditable = false;
1730 1735 }
1731 1736 + // CraftBukkit end
1732 1737
1733 1738 tileentitysign.setChanged();
1734 1739 worldserver.sendBlockUpdated(blockposition, iblockdata, iblockdata, 3);
1735 -@@ -1944,6 +3069,7 @@
1740 +@@ -1944,6 +3074,7 @@
1736 1741
1737 1742 @Override
1738 1743 public void handleKeepAlive(PacketPlayInKeepAlive packetplayinkeepalive) {
1739 1744 + PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinkeepalive, this, this.player.getLevel()); // CraftBukkit
1740 1745 if (this.keepAlivePending && packetplayinkeepalive.getId() == this.keepAliveChallenge) {
1741 1746 int i = (int) (SystemUtils.getMillis() - this.keepAliveTime);
1742 1747
1743 -@@ -1958,7 +3084,17 @@
1748 +@@ -1958,7 +3089,17 @@
1744 1749 @Override
1745 1750 public void handlePlayerAbilities(PacketPlayInAbilities packetplayinabilities) {
1746 1751 PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinabilities, this, this.player.getLevel());
1747 1752 - this.player.getAbilities().flying = packetplayinabilities.isFlying() && this.player.getAbilities().mayfly;
1748 1753 + // CraftBukkit start
1749 1754 + if (this.player.getAbilities().mayfly && this.player.getAbilities().flying != packetplayinabilities.isFlying()) {
1750 1755 + PlayerToggleFlightEvent event = new PlayerToggleFlightEvent(this.player.getBukkitEntity(), packetplayinabilities.isFlying());
1751 1756 + this.cserver.getPluginManager().callEvent(event);
1752 1757 + if (!event.isCancelled()) {
1753 1758 + this.player.getAbilities().flying = packetplayinabilities.isFlying(); // Actually set the player's flying status
1754 1759 + } else {
1755 1760 + this.player.onUpdateAbilities(); // Tell the player their ability was reverted
1756 1761 + }
1757 1762 + }
1758 1763 + // CraftBukkit end
1759 1764 }
1760 1765
1761 1766 @Override
1762 -@@ -1967,8 +3103,50 @@
1767 +@@ -1967,8 +3108,50 @@
1763 1768 this.player.updateOptions(packetplayinsettings);
1764 1769 }
1765 1770
1766 1771 - @Override
1767 1772 - public void handleCustomPayload(PacketPlayInCustomPayload packetplayincustompayload) {}
1768 1773 + // CraftBukkit start
1769 1774 + private static final MinecraftKey CUSTOM_REGISTER = new MinecraftKey("register");
1770 1775 + private static final MinecraftKey CUSTOM_UNREGISTER = new MinecraftKey("unregister");
1771 1776 +
1772 1777 + @Override

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

Add shortcut