|
11 | 11 | import io.papermc.paper.FeatureHooks; |
12 | 12 | import io.papermc.paper.connection.PlayerGameConnection; |
13 | 13 | import io.papermc.paper.connection.PluginMessageBridgeImpl; |
| 14 | +import io.papermc.paper.datacomponent.DataComponentTypes; |
| 15 | +import io.papermc.paper.datacomponent.item.WrittenBookContent; |
14 | 16 | import io.papermc.paper.dialog.Dialog; |
15 | 17 | import io.papermc.paper.dialog.PaperDialog; |
16 | 18 | import io.papermc.paper.entity.LookAnchor; |
|
48 | 50 | import java.util.stream.Collectors; |
49 | 51 | import net.kyori.adventure.dialog.DialogLike; |
50 | 52 | import net.kyori.adventure.identity.Identity; |
| 53 | +import net.kyori.adventure.inventory.Book; |
51 | 54 | import net.kyori.adventure.pointer.PointersSupplier; |
52 | 55 | import net.kyori.adventure.util.TriState; |
53 | 56 | import net.md_5.bungee.api.chat.BaseComponent; |
|
69 | 72 | import net.minecraft.network.protocol.game.ClientboundBlockDestructionPacket; |
70 | 73 | import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; |
71 | 74 | import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; |
| 75 | +import net.minecraft.network.protocol.game.ClientboundBundlePacket; |
72 | 76 | import net.minecraft.network.protocol.game.ClientboundClearTitlesPacket; |
73 | 77 | import net.minecraft.network.protocol.game.ClientboundCustomChatCompletionsPacket; |
74 | 78 | import net.minecraft.network.protocol.game.ClientboundGameEventPacket; |
75 | 79 | import net.minecraft.network.protocol.game.ClientboundHurtAnimationPacket; |
76 | 80 | import net.minecraft.network.protocol.game.ClientboundLevelEventPacket; |
77 | 81 | import net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket; |
78 | 82 | import net.minecraft.network.protocol.game.ClientboundMapItemDataPacket; |
| 83 | +import net.minecraft.network.protocol.game.ClientboundOpenBookPacket; |
79 | 84 | import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket; |
80 | 85 | import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; |
81 | 86 | import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; |
|
90 | 95 | import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; |
91 | 96 | import net.minecraft.network.protocol.game.ClientboundSetExperiencePacket; |
92 | 97 | import net.minecraft.network.protocol.game.ClientboundSetHealthPacket; |
| 98 | +import net.minecraft.network.protocol.game.ClientboundSetPlayerInventoryPacket; |
93 | 99 | import net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket; |
94 | 100 | import net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket; |
95 | 101 | import net.minecraft.network.protocol.game.ClientboundSetTitlesAnimationPacket; |
|
108 | 114 | import net.minecraft.server.players.UserWhiteListEntry; |
109 | 115 | import net.minecraft.sounds.SoundEvent; |
110 | 116 | import net.minecraft.util.ProblemReporter; |
| 117 | +import net.minecraft.world.InteractionHand; |
111 | 118 | import net.minecraft.world.entity.Entity; |
112 | 119 | import net.minecraft.world.entity.EntitySpawnReason; |
113 | 120 | import net.minecraft.world.entity.ai.attributes.AttributeInstance; |
|
201 | 208 | import org.bukkit.inventory.EquipmentSlot; |
202 | 209 | import org.bukkit.inventory.InventoryView.Property; |
203 | 210 | import org.bukkit.inventory.ItemStack; |
| 211 | +import org.bukkit.inventory.ItemType; |
204 | 212 | import org.bukkit.map.MapCursor; |
205 | 213 | import org.bukkit.map.MapView; |
206 | 214 | import org.bukkit.metadata.MetadataValue; |
@@ -2709,17 +2717,6 @@ public void updateCommands() { |
2709 | 2717 | this.server.getServer().getCommands().sendCommands(this.getHandle()); |
2710 | 2718 | } |
2711 | 2719 |
|
2712 | | - @Override |
2713 | | - public void openBook(ItemStack book) { |
2714 | | - Preconditions.checkArgument(book != null, "ItemStack cannot be null"); |
2715 | | - Preconditions.checkArgument(book.getType() == Material.WRITTEN_BOOK, "ItemStack Material (%s) must be Material.WRITTEN_BOOK", book.getType()); |
2716 | | - |
2717 | | - ItemStack hand = this.getInventory().getItemInMainHand(); |
2718 | | - this.getInventory().setItemInMainHand(book); |
2719 | | - this.getHandle().openItemGui(org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(book), net.minecraft.world.InteractionHand.MAIN_HAND); |
2720 | | - this.getInventory().setItemInMainHand(hand); |
2721 | | - } |
2722 | | - |
2723 | 2720 | @Override |
2724 | 2721 | public void openSign(@NonNull Sign sign, @NonNull Side side) { |
2725 | 2722 | CraftSign.openSign(sign, this, side); |
@@ -2958,17 +2955,30 @@ public void stopSound(final net.kyori.adventure.sound.SoundStop stop) { |
2958 | 2955 | } |
2959 | 2956 |
|
2960 | 2957 | @Override |
2961 | | - public void openBook(final net.kyori.adventure.inventory.Book book) { |
2962 | | - final java.util.Locale locale = this.getHandle().adventure$locale; |
2963 | | - final net.minecraft.world.item.ItemStack item = io.papermc.paper.adventure.PaperAdventure.asItemStack(book, locale); |
2964 | | - final ServerPlayer player = this.getHandle(); |
2965 | | - final ServerGamePacketListenerImpl connection = player.connection; |
2966 | | - final net.minecraft.world.entity.player.Inventory inventory = player.getInventory(); |
2967 | | - final int slot = inventory.getNonEquipmentItems().size() + inventory.getSelectedSlot(); |
2968 | | - final int stateId = getHandle().containerMenu.getStateId(); |
2969 | | - connection.send(new net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket(0, stateId, slot, item)); |
2970 | | - connection.send(new net.minecraft.network.protocol.game.ClientboundOpenBookPacket(net.minecraft.world.InteractionHand.MAIN_HAND)); |
2971 | | - connection.send(new net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket(0, stateId, slot, inventory.getSelectedItem())); |
| 2958 | + public void openBook(ItemStack book) { |
| 2959 | + Preconditions.checkArgument(book != null, "ItemStack cannot be null"); |
| 2960 | + Preconditions.checkArgument(book.hasData(DataComponentTypes.WRITTEN_BOOK_CONTENT), "ItemStack must have a 'written_book_content' component"); |
| 2961 | + |
| 2962 | + final ItemStack previousItem = this.getInventory().getItemInMainHand(); |
| 2963 | + this.getInventory().setItemInMainHand(book); |
| 2964 | + this.getHandle().openItemGui(CraftItemStack.asNMSCopy(book), InteractionHand.MAIN_HAND); |
| 2965 | + this.getInventory().setItemInMainHand(previousItem); |
| 2966 | + } |
| 2967 | + |
| 2968 | + @Override |
| 2969 | + public void openBook(final Book book) { |
| 2970 | + final ItemStack mutatedItem = ItemType.WRITTEN_BOOK.createItemStack(); // dummy item |
| 2971 | + mutatedItem.setData(DataComponentTypes.WRITTEN_BOOK_CONTENT, WrittenBookContent.writtenBookContent("", "").addPages(book.pages())); |
| 2972 | + |
| 2973 | + final net.minecraft.world.item.ItemStack selectedItem = this.getHandle().getInventory().getSelectedItem(); |
| 2974 | + final int slot = this.getHandle().getInventory().getSelectedSlot(); |
| 2975 | + this.getHandle().connection.send(new ClientboundBundlePacket( |
| 2976 | + List.of( |
| 2977 | + new ClientboundSetPlayerInventoryPacket(slot, CraftItemStack.unwrap(mutatedItem)), |
| 2978 | + new ClientboundOpenBookPacket(InteractionHand.MAIN_HAND), |
| 2979 | + new ClientboundSetPlayerInventoryPacket(slot, selectedItem) |
| 2980 | + ) |
| 2981 | + )); |
2972 | 2982 | } |
2973 | 2983 |
|
2974 | 2984 | @Override |
|
0 commit comments