SnLib v1.21.0
Changes
Plugin-supplied stacks in menus. All three GUI bind surfaces now accept a ready-made ItemStack, so a menu can display contents the plugin did not author - crate rewards, kit contents, shop stock, lootbox previews - whose enchantments, custom model data, head texture and custom name no YAML item definition can re-express.
The split is: the stack supplies the appearance, the template keeps supplying the behaviour.
s.bind(22, gui.template("reward"), reward.icon(), Ph.of("chance", 25)); // manual bind
s.bindPaged("kit-item", kit.contents(), (i, ph) -> ph.stack(i)); // paged entry
s.bindEach("stock", offers, (o, e) -> e.template("offer").stack(o.item())); // region cellNew public methods:
GuiSession.bind(int slot, GuiTemplate template, ItemStack stack, Ph... phs)PhCollector.stack(ItemStack stack)GuiEntry.stack(ItemStack stack)
Overlay rules, identical on all three: a non-empty display-name replaces the stack's name, declared lore lines are appended after the stack's own lore, both resolved through the normal pipeline (viewer PAPI, local placeholders, colour, rgb). A template that declares neither leaves the stack visually untouched; nothing else of the template is applied.
Unchanged: view-requirements, the per-click matrix, click and deny actions, render precedence, itemAt, handleClick, the strict-clicks gate, bind lifetime across page changes, refreshes and inventory recreation, and the snlib_gui_item anti-theft stamp. A null stack is exactly the previous behaviour, so the surface is strictly additive: every consumer compiled against 1.20.3 keeps compiling and behaving identically.
SnApi.LEVEL 12 -> 13. The additive-only japicmp gate records three new methods and no removal.
Installation
Download the JAR below and place it in your plugins folder, replacing the previous SnLib.jar. Updating SnLib requires a server restart; never hot-reload it.