# Bookshelf - v2.1.5 ## Packet Menus + Console Chat + Item Tooling ### API UPDATES - **Packet-based menus** — New `TopMenuBuilder.setPacketBased(boolean)` toggle. Marked menus can no longer be drained by players grabbing items during TPS lag; the click pipeline is bypassed at the network layer. - **Per-slot menu mode** — `RowBuilder.setPacketSlot`, `setServerSlot`, and `setEmptyServerSlot` let a single menu mix decorative packet-only buttons with real server-side interactive slots and drop zones. - **`PacketMenuHandler`** — Platform hook on `IMenuManager` so the server module can supply the packet pipeline. Plugins do not interact with this directly. - **`Menu.getPlayer()`** — Public accessor for the player a menu was opened for. - **`ItemBuilder.skull(String)` modernized** — Accepts both the base64 textures property value and raw `https://textures.minecraft.net/texture/...` URLs. Now uses Bukkit's `PlayerProfile` API so behavior is stable across Paper's component-based item refactor (1.20.5+). - **`ChatType` enum** — New enum (`PUBLIC`, `STAFF`, `TEAM`, `NETWORK`, `CHANNEL`) exposed from `PlayerChatEvent` via `getChatType()` / `setChatType()`. Downstream plugins can now categorize chat messages without inspecting the channel string. - **`PlayerChatEvent` channel accessor** — Added `getChannel()` / `setChannel()` alongside chat type, populated from the player's current chat channel when the event fires. - **`PlayerMessageEvent` message content** — Added two constructor overloads accepting the message string, plus `getMessage()` / `setMessage()`. Whisper and reply call sites now supply message content, enabling listeners to read and log DMs. - **`IChatManager.broadcastChannelMessage`** — One-off send into any chat channel as a given sender name. Used by the console chat path and `/chat <channel> <message>`. - **Packet menu live refresh** — `Menu#syncSlotFromServer(int, ItemStack)` and `Menu#isPacketPlaceholder(ItemStack)` let the platform pipeline forward direct `Inventory#setItem` calls on packet-based menus through to the client without needing `update()` or re-open. `Menu.PACKET_PLACEHOLDER_KEY` is the sentinel PDC key used to distinguish the placeholder from user-set items. - **`ItemStack` PDC convention** — `ItemBuilder` and `APICustomItemManager` now read the persistent data container straight off `ItemStack` and write through `editPersistentDataContainer`, dropping the older `getItemMeta().getPersistentDataContainer()` round-trip. - **Hybrid packet bottom inventory** — Bottom-row slots can now be flagged packet-only without touching the player's real items. `RowBuilder.setEmptyPacketSlot` and `MenuBuilder.setEmptyPacket` add empty packet slots; `MenuBuilder.hideAll()` overlays an empty bottom inventory in one call. New `Menu#hideBottomInventory()` and `Menu#restoreBottomInventory()` toggle the overlay live. `Menu#requiresPacketHandler()` now activates the listener for top-packet OR any-bottom-packet menus. ### PLUGIN UPDATES - **Console chat support** — Console can now use `/chat <channel> <message>` to broadcast into any channel, and `/whisper`, `/tell`, `/msg`, `/w`, `/pm`, `/reply`, `/r` to message online players. Player `/r` recognizes a whisper from console and replies back to it. - **`/chat <channel> <message>` one-off form** — Players can send a single message into any channel they have permission for without switching their default channel. - **`/itemdata`** — New command (aliases `/idata`, `/itemnbt`) that dumps the held item's NBT to chat as a click-to-copy message. Optional dot-path argument drills into a sub-compound or leaf (e.g. `display.Name`); `-f` / `--formatted` pretty-prints the output. - **`/upgrade` tiers** — Now recognizes spears as a tool type and copper as a tier between stone and iron. Missing tiers are skipped on server versions where they don't exist, so a stone sword still upgrades straight to iron on older versions. - **Packet menu controller** — Bookshelf-Paper installs a controller on enable that handles every packet-flagged menu opened through the API. No configuration needed. - **`ChatManager` populates chat type** — `PlayerChatEvent` now fires with `chatType` and `channel` set based on the sender's current chat channel (`ALL` → `PUBLIC`, `NETWORK` → `NETWORK`, custom → `CHANNEL`). - **Whisper / Reply pass message content** — `WhisperCommand`, `ReplyCommand`, and the cross-server Redis receiver in `BookshelfPlugin` all emit `PlayerMessageEvent` with the message string. - **Packet menu redraws from `Inventory#setItem`** — Menus marked packet-based now reflect direct slot writes on the open inventory immediately on the client. Plugins built against Bookshelf no longer need a special refresh call to update toggle/cycle buttons. - **Bottom-inventory packet pipeline** — `WINDOW_ITEMS` and `SET_SLOT` rewriting extends to the bottom inventory range. Packet-flagged bottom slots show the menu's display item to the client; unflagged bottom slots pass through so real player items render normally. Clicks on packet bottom slots are dropped at the network layer and dispatched as synthetic events. Shift-clicks within the bottom inventory are cancelled when the menu has any packet bottom slot, preventing vanilla shuffles from moving real items into hidden slots. ### INTERNAL UPDATES - Bumped **Bookshelf-API** to `1.2.37`. - Bumped **Bookshelf-Paper** to `2.1.5`. - Bumped **Bookshelf-Events** to `1.1.2`. - Targets **paper-api 1.21.4** (was 1.20.4). Build toolchain bumped to **Java 21** across pom, JitPack, and CI workflow.