How do I completely lock a custom GUI slot in Bukkit (like a crafting result)?

Natthapoom

Feedback score
0
Posts
1
Reactions
0
Resources
0
I’m writing a Bukkit/Spigot plugin that opens a custom Inventory as a GUI for players. In this GUI I have two special slots defined in GuiUtils:

  • PAPER_SLOT – players may insert paper here

  • COIN_SLOT – players may remove coins here
I want to completely lock COIN_SLOT so no item can ever be placed into it—no cursor-drag, no shift-click, no double-click, nothing—just like the result slot of a crafting table.

My current attempt cancels clicks and drags on that slot, but a clever player can still shift-click a stack into it, immediately shift it back out on the next tick, or drag to the cursor and back.

Here’s a simplified version of my listener:

EventHandler
public void onInventoryClick(InventoryClickEvent e) {
if (!(e.getWhoClicked() instanceof Player)) return;
Player player = (Player) e.getWhoClicked();
UUID uuid = player.getUniqueId();

// If this player isn’t using our GUI, ignore
if (!plugin.isUsingGui(uuid)) return;
Inventory gui = plugin.getPlayerGui(uuid);
if (gui == null || e.getClickedInventory() != gui) return;

int slot = e.getSlot();

// Attempt to block all placement into COIN_SLOT
if (slot == GuiUtils.COIN_SLOT) {
e.setCancelled(true);
return;
}

// Other GUI logic...
}

I also cancel InventoryDragEvent for that slot:

EventHandler
public void onInventoryDrag(InventoryDragEvent e) {
if (!(e.getWhoClicked() instanceof Player)) return;
UUID uuid = ((Player)e.getWhoClicked()).getUniqueId();
if (!plugin.isUsingGui(uuid)) return;
Inventory gui = plugin.getPlayerGui(uuid);
if (gui == null) return;

// Cancel any drag placing items into COIN_SLOT
for (int rawSlot : e.getRawSlots()) {
if (rawSlot == GuiUtils.COIN_SLOT) {
e.setCancelled(true);
return;
}
}
}

Despite this, players can still sneak in items via shift-click from their inventory, or by quickly placing and picking them back up.

What I’ve tried

  • Cancelling InventoryClickEvent for MOVE_TO_OTHER_INVENTORY actions

  • Cancelling DOUBLE_CLICK when the clicked slot is COIN_SLOT

  • Cancelling drags (as shown above)

  • Listening to InventoryCloseEvent and cleaning up… but that only runs after the fact
Desired behavior
No matter what the player does—shift-click, double-click, drag, number-key swap—they must never be able to place any item into COIN_SLOT. Ideally, the slot should function identically to the output slot of a crafting table: you can take items out, but you can never put anything in.
 
Type
Requesting
Provided by
Individual
Top