From c335a555fb8cf6efda5b99d89bda26393199fa92 Mon Sep 17 00:00:00 2001 From: Jishuna Date: Wed, 2 Aug 2023 07:46:19 +1000 Subject: [PATCH] #1212: Add PlayerRecipeBookClickEvent --- .../server/network/PlayerConnection.patch | 140 ++++++++++-------- .../craftbukkit/event/CraftEventFactory.java | 8 + 2 files changed, 89 insertions(+), 59 deletions(-) diff --git a/nms-patches/net/minecraft/server/network/PlayerConnection.patch b/nms-patches/net/minecraft/server/network/PlayerConnection.patch index 898e89423..09fc2656a 100644 --- a/nms-patches/net/minecraft/server/network/PlayerConnection.patch +++ b/nms-patches/net/minecraft/server/network/PlayerConnection.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/network/PlayerConnection.java +++ b/net/minecraft/server/network/PlayerConnection.java -@@ -185,6 +185,70 @@ +@@ -185,6 +185,71 @@ import net.minecraft.world.phys.shapes.VoxelShapes; import org.slf4j.Logger; @@ -32,6 +32,7 @@ +import org.bukkit.craftbukkit.util.CraftChatMessage; +import org.bukkit.craftbukkit.util.CraftLocation; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; ++import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.craftbukkit.util.LazyPlayerSet; +import org.bukkit.craftbukkit.util.Waitable; +import org.bukkit.entity.Player; @@ -71,7 +72,7 @@ public class PlayerConnection implements ServerPlayerConnection, TickablePacketListener, PacketListenerPlayIn { static final Logger LOGGER = LogUtils.getLogger(); -@@ -201,7 +265,9 @@ +@@ -201,7 +266,9 @@ private long keepAliveTime; private boolean keepAlivePending; private long keepAliveChallenge; @@ -82,7 +83,7 @@ private int dropSpamTickCount; private double firstGoodX; private double firstGoodY; -@@ -247,8 +313,31 @@ +@@ -247,8 +314,31 @@ this.keepAliveTime = SystemUtils.getMillis(); entityplayer.getTextFilter().join(); this.signedMessageDecoder = minecraftserver.enforceSecureProfile() ? SignedMessageChain.b.REJECT_ALL : SignedMessageChain.b.unsigned(entityplayer.getUUID()); @@ -115,7 +116,7 @@ @Override public void tick() { -@@ -303,7 +392,7 @@ +@@ -303,7 +393,7 @@ this.server.getProfiler().push("keepAlive"); long i = SystemUtils.getMillis(); @@ -124,7 +125,7 @@ if (this.keepAlivePending) { this.disconnect(IChatBaseComponent.translatable("disconnect.timeout")); } else { -@@ -315,15 +404,21 @@ +@@ -315,15 +405,21 @@ } this.server.getProfiler().pop(); @@ -146,7 +147,7 @@ this.disconnect(IChatBaseComponent.translatable("multiplayer.disconnect.idling")); } -@@ -347,16 +442,67 @@ +@@ -347,16 +443,67 @@ return this.server.isSingleplayerOwner(this.player.getGameProfile()); } @@ -215,7 +216,7 @@ } private CompletableFuture filterTextPacket(T t0, BiFunction> bifunction) { -@@ -420,7 +566,34 @@ +@@ -420,7 +567,34 @@ double d9 = entity.getDeltaMovement().lengthSqr(); double d10 = d6 * d6 + d7 * d7 + d8 * d8; @@ -251,7 +252,7 @@ PlayerConnection.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", new Object[]{entity.getName().getString(), this.player.getName().getString(), d6, d7, d8}); this.connection.send(new PacketPlayOutVehicleMove(entity)); return; -@@ -460,14 +633,72 @@ +@@ -460,14 +634,72 @@ } entity.absMoveTo(d3, d4, d5, f, f1); @@ -324,7 +325,7 @@ this.player.serverLevel().getChunkSource().move(this.player); this.player.checkMovementStatistics(this.player.getX() - d0, this.player.getY() - d1, this.player.getZ() - d2); this.clientVehicleIsFloating = d11 >= -0.03125D && !flag1 && !this.server.isFlightAllowed() && !entity.isNoGravity() && this.noBlocksAround(entity); -@@ -501,6 +732,7 @@ +@@ -501,6 +733,7 @@ } this.awaitingPositionFromClient = null; @@ -332,7 +333,7 @@ } } -@@ -508,7 +740,7 @@ +@@ -508,7 +741,7 @@ @Override public void handleRecipeBookSeenRecipePacket(PacketPlayInRecipeDisplayed packetplayinrecipedisplayed) { PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinrecipedisplayed, this, this.player.serverLevel()); @@ -341,7 +342,7 @@ RecipeBookServer recipebookserver = this.player.getRecipeBook(); Objects.requireNonNull(recipebookserver); -@@ -538,6 +770,12 @@ +@@ -538,6 +771,12 @@ @Override public void handleCustomCommandSuggestions(PacketPlayInTabComplete packetplayintabcomplete) { PlayerConnectionUtils.ensureRunningOnSameThread(packetplayintabcomplete, this, this.player.serverLevel()); @@ -354,7 +355,7 @@ StringReader stringreader = new StringReader(packetplayintabcomplete.getCommand()); if (stringreader.canRead() && stringreader.peek() == '/') { -@@ -547,6 +785,7 @@ +@@ -547,6 +786,7 @@ ParseResults parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack()); this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { @@ -362,7 +363,7 @@ this.connection.send(new PacketPlayOutTabComplete(packetplayintabcomplete.getId(), suggestions)); }); } -@@ -792,6 +1031,13 @@ +@@ -792,6 +1032,13 @@ if (container instanceof ContainerMerchant) { ContainerMerchant containermerchant = (ContainerMerchant) container; @@ -376,7 +377,7 @@ if (!containermerchant.stillValid(this.player)) { PlayerConnection.LOGGER.debug("Player {} interacted with invalid menu {}", this.player, containermerchant); -@@ -806,6 +1052,13 @@ +@@ -806,6 +1053,13 @@ @Override public void handleEditBook(PacketPlayInBEdit packetplayinbedit) { @@ -390,7 +391,7 @@ int i = packetplayinbedit.getSlot(); if (PlayerInventory.isHotbarSlot(i) || i == 40) { -@@ -814,7 +1067,7 @@ +@@ -814,7 +1068,7 @@ Objects.requireNonNull(list); optional.ifPresent(list::add); @@ -399,7 +400,7 @@ Objects.requireNonNull(list); stream.forEach(list::add); -@@ -832,7 +1085,7 @@ +@@ -832,7 +1086,7 @@ ItemStack itemstack = this.player.getInventory().getItem(i); if (itemstack.is(Items.WRITABLE_BOOK)) { @@ -408,7 +409,7 @@ } } -@@ -857,16 +1110,16 @@ +@@ -857,16 +1111,16 @@ this.updateBookPages(list, (s) -> { return IChatBaseComponent.ChatSerializer.toJson(IChatBaseComponent.literal(s)); @@ -429,7 +430,7 @@ return NBTTagString.valueOf((String) unaryoperator.apply(filteredtext.filteredOrEmpty())); }); -@@ -892,6 +1145,7 @@ +@@ -892,6 +1146,7 @@ } itemstack.addTagElement("pages", nbttaglist); @@ -437,7 +438,7 @@ } @Override -@@ -928,7 +1182,7 @@ +@@ -928,7 +1183,7 @@ } else { WorldServer worldserver = this.player.serverLevel(); @@ -446,7 +447,7 @@ if (this.tickCount == 0) { this.resetPosition(); } -@@ -938,7 +1192,7 @@ +@@ -938,7 +1193,7 @@ this.awaitingTeleportTime = this.tickCount; this.teleport(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot()); } @@ -455,7 +456,7 @@ } else { this.awaitingTeleportTime = this.tickCount; double d0 = clampHorizontal(packetplayinflying.getX(this.player.getX())); -@@ -950,7 +1204,15 @@ +@@ -950,7 +1205,15 @@ if (this.player.isPassenger()) { this.player.absMoveTo(this.player.getX(), this.player.getY(), this.player.getZ(), f, f1); this.player.serverLevel().getChunkSource().move(this.player); @@ -471,7 +472,7 @@ double d3 = this.player.getX(); double d4 = this.player.getY(); double d5 = this.player.getZ(); -@@ -969,15 +1231,33 @@ +@@ -969,15 +1232,33 @@ ++this.receivedMovePacketCount; int i = this.receivedMovePacketCount - this.knownMovePacketCount; @@ -507,7 +508,7 @@ PlayerConnection.LOGGER.warn("{} moved too quickly! {},{},{}", new Object[]{this.player.getName().getString(), d6, d7, d8}); this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot()); return; -@@ -998,6 +1278,7 @@ +@@ -998,6 +1279,7 @@ boolean flag1 = this.player.verticalCollisionBelow; this.player.move(EnumMoveType.PLAYER, new Vec3D(d6, d7, d8)); @@ -515,7 +516,7 @@ double d11 = d7; d6 = d0 - this.player.getX(); -@@ -1016,9 +1297,70 @@ +@@ -1016,9 +1298,70 @@ } if (!this.player.noPhysics && !this.player.isSleeping() && (flag2 && worldserver.noCollision(this.player, axisalignedbb) || this.isPlayerCollidingWithAnythingNew(worldserver, axisalignedbb, d0, d1, d2))) { @@ -587,7 +588,7 @@ this.player.absMoveTo(d0, d1, d2, f, f1); this.clientIsFloating = d11 >= -0.03125D && !flag1 && this.player.gameMode.getGameModeForPlayer() != EnumGamemode.SPECTATOR && !this.server.isFlightAllowed() && !this.player.getAbilities().mayfly && !this.player.hasEffect(MobEffects.LEVITATION) && !this.player.isFallFlying() && !this.player.isAutoSpinAttack() && this.noBlocksAround(this.player); this.player.serverLevel().getChunkSource().move(this.player); -@@ -1059,11 +1401,68 @@ +@@ -1059,11 +1402,68 @@ return true; } @@ -657,7 +658,7 @@ double d3 = set.contains(RelativeMovement.X) ? this.player.getX() : 0.0D; double d4 = set.contains(RelativeMovement.Y) ? this.player.getY() : 0.0D; double d5 = set.contains(RelativeMovement.Z) ? this.player.getZ() : 0.0D; -@@ -1075,6 +1474,14 @@ +@@ -1075,6 +1475,14 @@ this.awaitingTeleport = 0; } @@ -672,7 +673,7 @@ this.awaitingTeleportTime = this.tickCount; this.player.absMoveTo(d0, d1, d2, f, f1); this.player.connection.send(new PacketPlayOutPosition(d0 - d3, d1 - d4, d2 - d5, f - f2, f1 - f3, set, this.awaitingTeleport)); -@@ -1083,6 +1490,7 @@ +@@ -1083,6 +1491,7 @@ @Override public void handlePlayerAction(PacketPlayInBlockDig packetplayinblockdig) { PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinblockdig, this, this.player.serverLevel()); @@ -680,7 +681,7 @@ BlockPosition blockposition = packetplayinblockdig.getPos(); this.player.resetLastActionTime(); -@@ -1093,14 +1501,46 @@ +@@ -1093,14 +1502,46 @@ if (!this.player.isSpectator()) { ItemStack itemstack = this.player.getItemInHand(EnumHand.OFF_HAND); @@ -729,7 +730,7 @@ this.player.drop(false); } -@@ -1138,6 +1578,7 @@ +@@ -1138,6 +1579,7 @@ @Override public void handleUseItemOn(PacketPlayInUseItem packetplayinuseitem) { PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinuseitem, this, this.player.serverLevel()); @@ -737,7 +738,7 @@ this.player.connection.ackBlockChangesUpTo(packetplayinuseitem.getSequence()); WorldServer worldserver = this.player.serverLevel(); EnumHand enumhand = packetplayinuseitem.getHand(); -@@ -1161,6 +1602,7 @@ +@@ -1161,6 +1603,7 @@ if (blockposition.getY() < i) { if (this.awaitingPositionFromClient == null && this.player.distanceToSqr((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) < 64.0D && worldserver.mayInteract(this.player, blockposition)) { @@ -745,7 +746,7 @@ EnumInteractionResult enuminteractionresult = this.player.gameMode.useItemOn(this.player, worldserver, itemstack, enumhand, movingobjectpositionblock); if (enumdirection == EnumDirection.UP && !enuminteractionresult.consumesAction() && blockposition.getY() >= i - 1 && wasBlockPlacementAttempt(this.player, itemstack)) { -@@ -1189,6 +1631,7 @@ +@@ -1189,6 +1632,7 @@ @Override public void handleUseItem(PacketPlayInBlockPlace packetplayinblockplace) { PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinblockplace, this, this.player.serverLevel()); @@ -753,7 +754,7 @@ this.ackBlockChangesUpTo(packetplayinblockplace.getSequence()); WorldServer worldserver = this.player.serverLevel(); EnumHand enumhand = packetplayinblockplace.getHand(); -@@ -1196,6 +1639,49 @@ +@@ -1196,6 +1640,49 @@ this.player.resetLastActionTime(); if (!itemstack.isEmpty() && itemstack.isItemEnabled(worldserver.enabledFeatures())) { @@ -803,7 +804,7 @@ EnumInteractionResult enuminteractionresult = this.player.gameMode.useItem(this.player, worldserver, itemstack, enumhand); if (enuminteractionresult.shouldSwing()) { -@@ -1216,7 +1702,7 @@ +@@ -1216,7 +1703,7 @@ Entity entity = packetplayinspectate.getEntity(worldserver); if (entity != null) { @@ -812,7 +813,7 @@ return; } } -@@ -1231,6 +1717,7 @@ +@@ -1231,6 +1718,7 @@ PlayerConnection.LOGGER.info("Disconnecting {} due to resource pack rejection", this.player.getName()); this.disconnect(IChatBaseComponent.translatable("multiplayer.requiredTexturePrompt.disconnect")); } @@ -820,7 +821,7 @@ } -@@ -1252,12 +1739,27 @@ +@@ -1252,12 +1740,27 @@ @Override public void onDisconnect(IChatBaseComponent ichatbasecomponent) { @@ -849,7 +850,7 @@ this.player.getTextFilter().leave(); if (this.isSingleplayerOwner()) { PlayerConnection.LOGGER.info("Stopping singleplayer server as player logged out"); -@@ -1280,6 +1782,15 @@ +@@ -1280,6 +1783,15 @@ } public void send(Packet packet, @Nullable PacketSendListener packetsendlistener) { @@ -865,7 +866,7 @@ try { this.connection.send(packet, packetsendlistener); } catch (Throwable throwable) { -@@ -1296,7 +1807,16 @@ +@@ -1296,7 +1808,16 @@ @Override public void handleSetCarriedItem(PacketPlayInHeldItemSlot packetplayinhelditemslot) { PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinhelditemslot, this, this.player.serverLevel()); @@ -882,7 +883,7 @@ if (this.player.getInventory().selected != packetplayinhelditemslot.getSlot() && this.player.getUsedItemHand() == EnumHand.MAIN_HAND) { this.player.stopUsingItem(); } -@@ -1305,18 +1825,25 @@ +@@ -1305,18 +1826,25 @@ this.player.resetLastActionTime(); } else { PlayerConnection.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString()); @@ -909,7 +910,7 @@ PlayerChatMessage playerchatmessage; try { -@@ -1334,9 +1861,9 @@ +@@ -1334,9 +1862,9 @@ PlayerChatMessage playerchatmessage1 = playerchatmessage.withUnsignedContent((IChatBaseComponent) completablefuture1.join()).filter(((FilteredText) completablefuture.join()).mask()); this.broadcastChatMessage(playerchatmessage1); @@ -921,7 +922,7 @@ } } -@@ -1351,6 +1878,12 @@ +@@ -1351,6 +1879,12 @@ if (optional.isPresent()) { this.server.submit(() -> { @@ -934,7 +935,7 @@ this.performChatCommand(serverboundchatcommandpacket, (LastSeenMessages) optional.get()); this.detectRateSpam(); }); -@@ -1360,12 +1893,25 @@ +@@ -1360,12 +1894,25 @@ } private void performChatCommand(ServerboundChatCommandPacket serverboundchatcommandpacket, LastSeenMessages lastseenmessages) { @@ -962,7 +963,7 @@ } catch (SignedMessageChain.a signedmessagechain_a) { this.handleMessageDecodeFailure(signedmessagechain_a); return; -@@ -1373,10 +1919,10 @@ +@@ -1373,10 +1920,10 @@ CommandSigningContext.a commandsigningcontext_a = new CommandSigningContext.a(map); @@ -975,7 +976,7 @@ } private void handleMessageDecodeFailure(SignedMessageChain.a signedmessagechain_a) { -@@ -1417,7 +1963,7 @@ +@@ -1417,7 +1964,7 @@ } else { Optional optional = this.unpackAndApplyLastSeen(lastseenmessages_b); @@ -984,7 +985,7 @@ this.send(new ClientboundSystemChatPacket(IChatBaseComponent.translatable("chat.disabled.options").withStyle(EnumChatFormat.RED), false)); return Optional.empty(); } else { -@@ -1465,6 +2011,116 @@ +@@ -1465,6 +2012,116 @@ return false; } @@ -1101,7 +1102,7 @@ private PlayerChatMessage getSignedMessage(PacketPlayInChat packetplayinchat, LastSeenMessages lastseenmessages) throws SignedMessageChain.a { SignedMessageBody signedmessagebody = new SignedMessageBody(packetplayinchat.message(), packetplayinchat.timeStamp(), packetplayinchat.salt(), lastseenmessages); -@@ -1472,13 +2128,33 @@ +@@ -1472,13 +2129,33 @@ } private void broadcastChatMessage(PlayerChatMessage playerchatmessage) { @@ -1138,7 +1139,7 @@ this.disconnect(IChatBaseComponent.translatable("disconnect.spam")); } -@@ -1500,13 +2176,62 @@ +@@ -1500,13 +2177,62 @@ @Override public void handleAnimate(PacketPlayInArmAnimation packetplayinarmanimation) { PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinarmanimation, this, this.player.serverLevel()); @@ -1201,7 +1202,7 @@ this.player.resetLastActionTime(); Entity entity; IJumpable ijumpable; -@@ -1588,6 +2313,12 @@ +@@ -1588,6 +2314,12 @@ } public void sendPlayerChatMessage(PlayerChatMessage playerchatmessage, ChatMessageType.a chatmessagetype_a) { @@ -1214,7 +1215,7 @@ this.send(new ClientboundPlayerChatPacket(playerchatmessage.link().sender(), playerchatmessage.link().index(), playerchatmessage.signature(), playerchatmessage.signedBody().pack(this.messageSignatureCache), playerchatmessage.unsignedContent(), playerchatmessage.filterMask(), chatmessagetype_a.toNetwork(this.player.level().registryAccess()))); this.addPendingMessage(playerchatmessage); } -@@ -1603,6 +2334,7 @@ +@@ -1603,6 +2335,7 @@ @Override public void handleInteract(PacketPlayInUseEntity packetplayinuseentity) { PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinuseentity, this, this.player.serverLevel()); @@ -1222,7 +1223,7 @@ final WorldServer worldserver = this.player.serverLevel(); final Entity entity = packetplayinuseentity.getTarget(worldserver); -@@ -1617,13 +2349,51 @@ +@@ -1617,13 +2350,51 @@ if (axisalignedbb.distanceToSqr(this.player.getEyePosition()) < PlayerConnection.MAX_INTERACTION_DISTANCE) { packetplayinuseentity.dispatch(new PacketPlayInUseEntity.c() { @@ -1275,7 +1276,7 @@ if (enuminteractionresult.consumesAction()) { CriterionTriggers.PLAYER_INTERACTED_WITH_ENTITY.trigger(PlayerConnection.this.player, itemstack1, entity); if (enuminteractionresult.shouldSwing()) { -@@ -1636,23 +2406,29 @@ +@@ -1636,23 +2407,29 @@ @Override public void onInteraction(EnumHand enumhand) { @@ -1308,7 +1309,7 @@ } } else { PlayerConnection.this.disconnect(IChatBaseComponent.translatable("multiplayer.disconnect.invalid_entity_attacked")); -@@ -1675,14 +2451,14 @@ +@@ -1675,14 +2452,14 @@ case PERFORM_RESPAWN: if (this.player.wonGame) { this.player.wonGame = false; @@ -1325,7 +1326,7 @@ if (this.server.isHardcore()) { this.player.setGameMode(EnumGamemode.SPECTATOR); ((GameRules.GameRuleBoolean) this.player.level().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS)).set(false, this.server); -@@ -1698,15 +2474,21 @@ +@@ -1698,15 +2475,21 @@ @Override public void handleContainerClose(PacketPlayInCloseWindow packetplayinclosewindow) { PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinclosewindow, this, this.player.serverLevel()); @@ -1349,7 +1350,7 @@ this.player.containerMenu.sendAllDataToRemote(); } else if (!this.player.containerMenu.stillValid(this.player)) { PlayerConnection.LOGGER.debug("Player {} interacted with invalid menu {}", this.player, this.player.containerMenu); -@@ -1719,7 +2501,284 @@ +@@ -1719,7 +2502,284 @@ boolean flag = packetplayinwindowclick.getStateId() != this.player.containerMenu.getStateId(); this.player.containerMenu.suppressRemoteUpdates(); @@ -1635,7 +1636,28 @@ ObjectIterator objectiterator = Int2ObjectMaps.fastIterable(packetplayinwindowclick.getChangedSlots()).iterator(); while (objectiterator.hasNext()) { -@@ -1759,6 +2818,7 @@ +@@ -1749,9 +2809,18 @@ + if (!this.player.containerMenu.stillValid(this.player)) { + PlayerConnection.LOGGER.debug("Player {} interacted with invalid menu {}", this.player, this.player.containerMenu); + } else { +- this.server.getRecipeManager().byKey(packetplayinautorecipe.getRecipe()).ifPresent((irecipe) -> { +- ((ContainerRecipeBook) this.player.containerMenu).handlePlacement(packetplayinautorecipe.isShiftDown(), irecipe, this.player); ++ // CraftBukkit start - implement PlayerRecipeBookClickEvent ++ org.bukkit.inventory.Recipe recipe = this.cserver.getRecipe(CraftNamespacedKey.fromMinecraft(packetplayinautorecipe.getRecipe())); ++ if (recipe == null) { ++ return; ++ } ++ org.bukkit.event.player.PlayerRecipeBookClickEvent event = CraftEventFactory.callRecipeBookClickEvent(this.player, recipe, packetplayinautorecipe.isShiftDown()); ++ ++ // Cast to keyed should be safe as the recipe will never be a MerchantRecipe. ++ this.server.getRecipeManager().byKey(CraftNamespacedKey.toMinecraft(((org.bukkit.Keyed) event.getRecipe()).getKey())).ifPresent((irecipe) -> { ++ ((ContainerRecipeBook) this.player.containerMenu).handlePlacement(event.isShiftClick(), irecipe, this.player); + }); ++ // CraftBukkit end + } + } + } +@@ -1759,6 +2828,7 @@ @Override public void handleContainerButtonClick(PacketPlayInEnchantItem packetplayinenchantitem) { PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinenchantitem, this, this.player.serverLevel()); @@ -1643,7 +1665,7 @@ this.player.resetLastActionTime(); if (this.player.containerMenu.containerId == packetplayinenchantitem.getContainerId() && !this.player.isSpectator()) { if (!this.player.containerMenu.stillValid(this.player)) { -@@ -1801,6 +2861,43 @@ +@@ -1801,6 +2871,43 @@ boolean flag1 = packetplayinsetcreativeslot.getSlotNum() >= 1 && packetplayinsetcreativeslot.getSlotNum() <= 45; boolean flag2 = itemstack.isEmpty() || itemstack.getDamageValue() >= 0 && itemstack.getCount() <= 64 && !itemstack.isEmpty(); @@ -1687,7 +1709,7 @@ if (flag1 && flag2) { this.player.inventoryMenu.getSlot(packetplayinsetcreativeslot.getSlotNum()).setByPlayer(itemstack); -@@ -1823,6 +2920,7 @@ +@@ -1823,6 +2930,7 @@ } private void updateSignText(PacketPlayInUpdateSign packetplayinupdatesign, List list) { @@ -1695,7 +1717,7 @@ this.player.resetLastActionTime(); WorldServer worldserver = this.player.serverLevel(); BlockPosition blockposition = packetplayinupdatesign.getPos(); -@@ -1843,6 +2941,7 @@ +@@ -1843,6 +2951,7 @@ @Override public void handleKeepAlive(PacketPlayInKeepAlive packetplayinkeepalive) { @@ -1703,7 +1725,7 @@ if (this.keepAlivePending && packetplayinkeepalive.getId() == this.keepAliveChallenge) { int i = (int) (SystemUtils.getMillis() - this.keepAliveTime); -@@ -1857,7 +2956,17 @@ +@@ -1857,7 +2966,17 @@ @Override public void handlePlayerAbilities(PacketPlayInAbilities packetplayinabilities) { PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinabilities, this, this.player.serverLevel()); @@ -1722,7 +1744,7 @@ } @Override -@@ -1866,8 +2975,50 @@ +@@ -1866,8 +2985,50 @@ this.player.updateOptions(packetplayinsettings); } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index ae5439e1d..8e0335731 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -228,6 +228,7 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerItemBreakEvent; import org.bukkit.event.player.PlayerItemMendEvent; import org.bukkit.event.player.PlayerLevelChangeEvent; +import org.bukkit.event.player.PlayerRecipeBookClickEvent; import org.bukkit.event.player.PlayerRecipeDiscoverEvent; import org.bukkit.event.player.PlayerShearEntityEvent; import org.bukkit.event.player.PlayerStatisticIncrementEvent; @@ -244,6 +245,7 @@ import org.bukkit.event.world.EntitiesUnloadEvent; import org.bukkit.event.world.LootGenerateEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.Recipe; import org.bukkit.inventory.meta.BookMeta; import org.bukkit.potion.PotionEffect; import org.bukkit.util.Vector; @@ -1778,6 +1780,12 @@ public class CraftEventFactory { return !event.isCancelled(); } + public static PlayerRecipeBookClickEvent callRecipeBookClickEvent(EntityPlayer player, Recipe recipe, boolean shiftClick) { + PlayerRecipeBookClickEvent event = new PlayerRecipeBookClickEvent(player.getBukkitEntity(), recipe, shiftClick); + Bukkit.getPluginManager().callEvent(event); + return event; + } + public static EntityTeleportEvent callEntityTeleportEvent(Entity nmsEntity, double x, double y, double z) { CraftEntity entity = nmsEntity.getBukkitEntity(); Location to = new Location(entity.getWorld(), x, y, z, nmsEntity.getYRot(), nmsEntity.getXRot());