use of org.bukkit.event.inventory.InventoryClickEvent in project PyrCore by PYRRH4.
the class MultipleGUI method createNewPage.
// Create new page
public GUI createNewPage() {
final int pageNumber = pages.size() + 1;
final GUI page = new GUI(plugin, name + (pageNumber == 1 ? "" : " - p" + pageNumber), size, addItemMaxSlot, allowBottomInventoryClick, false, duplicateTolerance) {
@Override
public void preload() {
}
@Override
public void onClick(InventoryClickEvent event, Player player, InventoryClickType clickType, ItemStack clickedStack, ItemData clickedData, ItemStack cursorStack, ItemData cursorData) {
// Page selectors
if (clickedData != null && clickedData.getId().equals(MultipleGUI.this.itemPreviousPage.getId())) {
GUI page = getPage(pageNumber - 1);
if (page != null) {
page.open(player, isWatcher(player));
}
} else if (clickedData != null && clickedData.getId().equals(MultipleGUI.this.itemNextPage.getId())) {
GUI page = getPage(pageNumber + 1);
if (page != null) {
page.open(player, isWatcher(player));
}
} else // Other
{
MultipleGUI.this.onClick(event, this, pageNumber, player, clickType, clickedStack, clickedData, cursorStack, cursorData);
}
}
@Override
protected void onClose(InventoryCloseEvent event, final Player player) {
MultipleGUI.this.onClose(event, this, pageNumber, player);
// unregister
if (unregisterOnClose) {
new BukkitRunnable() {
@Override
public void run() {
for (GUI page : getPages()) {
if (!page.getTotalViewers().isEmpty()) {
return;
}
}
MultipleGUI.this.unregister(false);
}
}.runTaskLater(plugin, 20L);
}
}
@Override
protected void onCloseDisable(Inventory inventory, Player player) {
MultipleGUI.this.onCloseDisable(inventory, this, pageNumber, player);
}
};
pages.add(page);
preload(page, pageNumber);
updatePageSelectors();
return page;
}
use of org.bukkit.event.inventory.InventoryClickEvent in project TriggerReactor by wysohn.
the class JavaPluginBridge method createInterrupterForInv.
@Override
public ProcessInterrupter createInterrupterForInv(Object e, Interpreter interpreter, Map<UUID, Long> cooldowns, Map<IInventory, InventoryTrigger> inventoryMap) {
return new ProcessInterrupter() {
@Override
public boolean onNodeProcess(Node node) {
if (interpreter.isCooldown()) {
if (e instanceof InventoryInteractEvent) {
HumanEntity he = ((InventoryInteractEvent) e).getWhoClicked();
if (he instanceof Player) {
Player player = (Player) he;
UUID uuid = player.getUniqueId();
cooldowns.put(uuid, interpreter.getCooldownEnd());
}
}
return false;
}
// is still running after the inventory is closed.
if (e instanceof InventoryOpenEvent || e instanceof InventoryClickEvent) {
Inventory inv = ((InventoryEvent) e).getInventory();
// it's not GUI so stop execution
if (!inventoryMap.containsKey(new BukkitInventory(inv)))
return true;
}
return false;
}
@Override
public boolean onCommand(Object context, String command, Object[] args) {
if ("CALL".equals(command)) {
if (args.length < 1)
throw new RuntimeException("Need parameter [String] or [String, boolean]");
if (args[0] instanceof String) {
Trigger trigger = getNamedTriggerManager().getTriggerForName((String) args[0]);
if (trigger == null)
throw new RuntimeException("No trigger found for Named Trigger " + args[0]);
if (args.length > 1 && args[1] instanceof Boolean) {
trigger.setSync((boolean) args[1]);
} else {
trigger.setSync(true);
}
if (trigger.isSync()) {
trigger.activate(e, interpreter.getVars());
} else {
// use snapshot to avoid concurrent modification
trigger.activate(e, new HashMap<>(interpreter.getVars()));
}
return true;
} else {
throw new RuntimeException("Parameter type not match; it should be a String." + " Make sure to put double quotes, if you provided String literal.");
}
} else if ("CANCELEVENT".equals(command)) {
if (!interpreter.isSync())
throw new RuntimeException("CANCELEVENT is illegal in async mode!");
if (context instanceof Cancellable) {
((Cancellable) context).setCancelled(true);
return true;
} else {
throw new RuntimeException(context + " is not a Cancellable event!");
}
}
return false;
}
};
}
use of org.bukkit.event.inventory.InventoryClickEvent in project Glowstone by GlowstoneMC.
the class WindowClickHandler method process.
private boolean process(GlowPlayer player, WindowClickMessage message) {
int viewSlot = message.getSlot();
InventoryView view = player.getOpenInventory();
GlowInventory top = (GlowInventory) view.getTopInventory();
GlowInventory bottom = (GlowInventory) view.getBottomInventory();
ItemStack slotItem = InventoryUtil.itemOrEmpty(view.getItem(viewSlot));
ItemStack cursor = player.getItemOnCursor();
// check that the player has a correct view of the item
if (!Objects.equals(message.getItem(), slotItem) && (message.getMode() == 0 || message.getMode() == 1)) {
// in mode 3 (get) and 4 (drop), client does not send item in slot under cursor
if (message.getMode() == 0 || !InventoryUtil.isEmpty(message.getItem())) {
// recipe slot is not synced by design
if (view.getTopInventory().getType() != InventoryType.CRAFTING || viewSlot >= view.getTopInventory().getSize() || ((GlowInventory) view.getTopInventory()).getSlot(viewSlot).getType() != SlotType.RESULT) {
player.sendItemChange(viewSlot, slotItem);
return false;
}
}
}
// determine inventory and slot clicked, used in some places
// todo: attempt to allow for users to implement their own inventory?
// CraftBukkit does not allow this but it may be worth the trouble for
// the extensibility.
GlowInventory inv;
if (viewSlot < top.getSize()) {
inv = top;
} else {
inv = bottom;
}
int invSlot = view.convertSlot(viewSlot);
if (invSlot == -1 || viewSlot == -1) {
return true;
}
SlotType slotType = inv.getSlotType(invSlot);
// handle dragging
if (message.getMode() == 5) {
// 5 0 * start left drag
// 5 1 add slot left drag
// 5 2 * end left drag
// 5 4 * start right drag
// 5 5 add slot right drag
// 5 6 * end right drag
DragTracker drag = player.getInventory().getDragTracker();
boolean right = message.getButton() >= 4;
switch(message.getButton()) {
// start left drag
case 0:
case // start right drag
4:
return drag.start(right);
// add slot left
case 1:
case // add slot right
5:
return drag.addSlot(right, message.getSlot());
// end left drag
case 2:
case // end right drag
6:
List<Integer> slots = drag.finish(right);
if (slots == null || InventoryUtil.isEmpty(cursor)) {
return false;
}
ItemStack newCursor = cursor.clone();
Map<Integer, ItemStack> newSlots = new HashMap<>();
int perSlot = right ? 1 : cursor.getAmount() / slots.size();
for (int dragSlot : slots) {
ItemStack oldItem = view.getItem(dragSlot);
if (InventoryUtil.isEmpty(oldItem) || cursor.isSimilar(oldItem)) {
Inventory dragInv = dragSlot < top.getSize() ? top : bottom;
int oldItemAmount = InventoryUtil.itemOrEmpty(oldItem).getAmount();
int transfer = Math.min(Math.min(perSlot, cursor.getAmount()), maxStack(dragInv, cursor.getType()) - oldItemAmount);
ItemStack newItem = combine(oldItem, cursor, transfer);
newSlots.put(dragSlot, newItem);
newCursor = amountOrEmpty(newCursor, newCursor.getAmount() - transfer);
if (InventoryUtil.isEmpty(newCursor)) {
break;
}
}
}
InventoryDragEvent event = new InventoryDragEvent(view, newCursor, cursor, right, newSlots);
EventFactory.getInstance().callEvent(event);
if (event.isCancelled()) {
return false;
}
for (Entry<Integer, ItemStack> entry : newSlots.entrySet()) {
view.setItem(entry.getKey(), entry.getValue());
}
player.setItemOnCursor(newCursor);
return true;
default:
return false;
}
}
// determine what action will be taken and fire event
ClickType clickType = WindowClickLogic.getClickType(message.getMode(), message.getButton(), viewSlot);
InventoryAction action = WindowClickLogic.getAction(clickType, slotType, cursor, slotItem);
if (clickType == ClickType.UNKNOWN || action == InventoryAction.UNKNOWN) {
// show a warning for unknown click type
GlowServer.logger.warning(player.getName() + ": mystery window click " + clickType + "/" + action + ": " + message);
}
// deny CLONE_STACK for non-creative mode players
if (action == InventoryAction.CLONE_STACK && player.getGameMode() != GameMode.CREATIVE) {
action = InventoryAction.NOTHING;
}
// determine whether NO_AI, HOTBAR_MOVE_AND_READD or HOTBAR_SWAP should be executed
if (clickType == ClickType.NUMBER_KEY) {
ItemStack destItem = bottom.getItem(message.getButton());
if (InventoryUtil.isEmpty(slotItem)) {
if (InventoryUtil.isEmpty(destItem) || !inv.itemPlaceAllowed(invSlot, destItem)) {
// both items are empty, do nothing
// or, current item is empty and destItem cannot be moved into current slot
action = InventoryAction.NOTHING;
}
} else if (inv != bottom || !inv.itemPlaceAllowed(invSlot, destItem)) {
// target and source inventory are different or destItem cannot be placed in
// current slot
action = InventoryAction.HOTBAR_MOVE_AND_READD;
}
}
if (WindowClickLogic.isPlaceAction(action)) {
// check whether item can be dropped into the clicked slot
if (!inv.itemPlaceAllowed(invSlot, cursor)) {
// placement not allowed
if (!InventoryUtil.isEmpty(slotItem) && slotItem.isSimilar(cursor)) {
// item in slot is the same as item on cursor
if (cursor.getAmount() + 1 == cursor.getMaxStackSize()) {
// There is still space under the cursor for one item
action = InventoryAction.PICKUP_ONE;
} else if (cursor.getAmount() < cursor.getMaxStackSize()) {
// There is still some space under the cursor
action = InventoryAction.PICKUP_SOME;
}
} else {
action = InventoryAction.NOTHING;
}
}
}
InventoryClickEvent event = null;
if (top == inv && top instanceof GlowCraftingInventory && top.getSlotType(invSlot) == SlotType.RESULT) {
// Clicked on output slot of crafting inventory
if (InventoryUtil.isEmpty(slotItem)) {
// No crafting recipe result, don't do anything
action = InventoryAction.NOTHING;
}
int cursorAmount = InventoryUtil.itemOrEmpty(cursor).getAmount();
if (message.getMode() == 0 && slotItem.isSimilar(cursor)) {
if (!InventoryUtil.isEmpty(slotItem) && cursorAmount + slotItem.getAmount() <= slotItem.getMaxStackSize()) {
// if the player can take the whole result
if (WindowClickLogic.isPickupAction(action) || WindowClickLogic.isPlaceAction(action)) {
// always take the whole crafting result out of the crafting inventories
action = InventoryAction.PICKUP_ALL;
} else if (action == InventoryAction.DROP_ONE_SLOT) {
// always drop the whole stack, not just single items
action = InventoryAction.DROP_ALL_SLOT;
}
} else {
// if their cursor is full, do nothing
action = InventoryAction.NOTHING;
}
}
// this ignores whether the crafting process actually happens (full inventory, etc.)
if (action != InventoryAction.NOTHING) {
Recipe recipe = ((CraftingInventory) inv).getRecipe();
if (clickType == ClickType.NUMBER_KEY) {
event = new CraftItemEvent(recipe, view, slotType, viewSlot, clickType, action, message.getButton());
} else {
event = new CraftItemEvent(recipe, view, slotType, viewSlot, clickType, action);
}
}
}
if (event == null) {
if (clickType == ClickType.NUMBER_KEY) {
event = new InventoryClickEvent(view, slotType, viewSlot, clickType, action, message.getButton());
} else {
event = new InventoryClickEvent(view, slotType, viewSlot, clickType, action);
}
}
EventFactory.getInstance().callEvent(event);
if (event.isCancelled()) {
int slot = event.getSlot();
player.getSession().send(new SetWindowSlotMessage(player.getOpenWindowId(), slot, event.getInventory().getItem(slot)));
player.getSession().send(new SetWindowSlotMessage(-1, -1, player.getItemOnCursor()));
return true;
}
boolean handled = true;
switch(action) {
case NOTHING:
break;
case UNKNOWN:
// any action the client tried to take should be denied
return false;
// PICKUP_*
case PICKUP_ALL:
view.setItem(viewSlot, InventoryUtil.createEmptyStack());
int cursorAmount = InventoryUtil.itemOrEmpty(cursor).getAmount();
player.setItemOnCursor(amountOrEmpty(slotItem, cursorAmount + slotItem.getAmount()));
break;
case PICKUP_HALF:
// pick up half (favor picking up)
int keepAmount = slotItem.getAmount() / 2;
ItemStack newCursor = slotItem.clone();
newCursor.setAmount(slotItem.getAmount() - keepAmount);
inv.setItem(invSlot, amountOrEmpty(slotItem, keepAmount));
player.setItemOnCursor(newCursor);
break;
case PICKUP_SOME:
// pick up as many items as possible
int pickUp = Math.min(cursor.getMaxStackSize() - cursor.getAmount(), slotItem.getAmount());
view.setItem(viewSlot, amountOrEmpty(slotItem, slotItem.getAmount() - pickUp));
player.setItemOnCursor(amountOrEmpty(cursor, cursor.getAmount() + pickUp));
break;
case PICKUP_ONE:
view.setItem(invSlot, amountOrEmpty(slotItem, slotItem.getAmount() - 1));
player.setItemOnCursor(amountOrEmpty(cursor, cursor.getAmount() + 1));
break;
// PLACE_*
case PLACE_ALL:
view.setItem(viewSlot, combine(slotItem, cursor, cursor.getAmount()));
player.setItemOnCursor(InventoryUtil.createEmptyStack());
break;
case PLACE_SOME:
{
// slotItem *should* never be empty in this situation?
int transfer = Math.min(cursor.getAmount(), maxStack(inv, slotItem.getType()) - slotItem.getAmount());
view.setItem(viewSlot, combine(slotItem, cursor, transfer));
player.setItemOnCursor(amountOrEmpty(cursor, cursor.getAmount() - transfer));
break;
}
case PLACE_ONE:
view.setItem(viewSlot, combine(slotItem, cursor, 1));
player.setItemOnCursor(amountOrEmpty(cursor, cursor.getAmount() - 1));
break;
case SWAP_WITH_CURSOR:
view.setItem(viewSlot, cursor);
player.setItemOnCursor(slotItem);
break;
// DROP_*
case DROP_ALL_CURSOR:
if (!InventoryUtil.isEmpty(cursor)) {
drop(player, cursor);
player.setItemOnCursor(InventoryUtil.createEmptyStack());
}
break;
case DROP_ONE_CURSOR:
if (!InventoryUtil.isEmpty(cursor)) {
drop(player, amountOrEmpty(cursor.clone(), 1));
player.setItemOnCursor(amountOrEmpty(cursor, cursor.getAmount() - 1));
}
break;
case DROP_ALL_SLOT:
if (!InventoryUtil.isEmpty(slotItem)) {
drop(player, slotItem);
view.setItem(viewSlot, InventoryUtil.createEmptyStack());
}
break;
case DROP_ONE_SLOT:
if (InventoryUtil.isEmpty(slotItem)) {
drop(player, amountOrEmpty(slotItem.clone(), 1));
view.setItem(viewSlot, amountOrEmpty(slotItem, slotItem.getAmount() - 1));
}
break;
// shift-click
case MOVE_TO_OTHER_INVENTORY:
if (!InventoryUtil.isEmpty(slotItem)) {
inv.handleShiftClick(player, view, viewSlot, slotItem);
}
break;
case HOTBAR_MOVE_AND_READD:
case HOTBAR_SWAP:
GlowPlayerInventory playerInv = player.getInventory();
int hotbarSlot = message.getButton();
ItemStack destItem = playerInv.getItem(hotbarSlot);
if (InventoryUtil.isEmpty(slotItem)) {
// nothing in current slot
if (InventoryUtil.isEmpty(destItem)) {
// no action
return false;
} else {
// do nothing if current slots does not accept the item
if (action == InventoryAction.HOTBAR_SWAP) {
inv.setItem(invSlot, destItem);
playerInv.setItem(hotbarSlot, InventoryUtil.createEmptyStack());
}
return true;
}
} else {
if (InventoryUtil.isEmpty(destItem)) {
// move from current slot to hotbar
playerInv.setItem(hotbarSlot, slotItem);
inv.setItem(invSlot, InventoryUtil.createEmptyStack());
return true;
} else {
// both are non-empty, swap them
playerInv.setItem(hotbarSlot, slotItem);
if (action == InventoryAction.HOTBAR_SWAP) {
inv.setItem(invSlot, destItem);
} else {
inv.setItem(invSlot, InventoryUtil.createEmptyStack());
playerInv.addItem(destItem);
}
return true;
}
}
case CLONE_STACK:
// only in creative and with no item on cursor handled earlier
// copy and maximize item
ItemStack stack = slotItem.clone();
stack.setAmount(stack.getType().getMaxStackSize());
player.setItemOnCursor(stack);
break;
case COLLECT_TO_CURSOR:
if (InventoryUtil.isEmpty(cursor)) {
return false;
}
int slotCount = view.countSlots();
for (int i = 0; i < slotCount && cursor.getAmount() < maxStack(inv, cursor.getType()); ++i) {
ItemStack item = view.getItem(i);
SlotType type = (i < top.getSize() ? top : bottom).getSlotType(view.convertSlot(i));
if (InventoryUtil.isEmpty(item) || !cursor.isSimilar(item) || type == SlotType.RESULT) {
continue;
}
int transfer = Math.min(item.getAmount(), maxStack(inv, cursor.getType()) - cursor.getAmount());
cursor.setAmount(cursor.getAmount() + transfer);
view.setItem(i, amountOrEmpty(item, item.getAmount() - transfer));
}
break;
default:
handled = false;
}
if (handled && top == inv && top instanceof GlowCraftingInventory && top.getSlotType(invSlot) == SlotType.RESULT && action != MOVE_TO_OTHER_INVENTORY && action != NOTHING) {
// If we are crafting (but not using shift click because no more items can be crafted
// for the given pattern. If a new item can be crafted with another pattern, a new
// click is required).
final GlowCraftingInventory glowCraftingInventory = (GlowCraftingInventory) top;
glowCraftingInventory.craft();
// Notify the player the result slot changed
player.sendItemChange(viewSlot, glowCraftingInventory.getResult());
}
if (!handled) {
GlowServer.logger.warning(player.getName() + ": unhandled click action " + action + " for " + message);
}
return handled;
}
use of org.bukkit.event.inventory.InventoryClickEvent in project AuthMeReloaded by AuthMe.
the class PlayerListenerTest method shouldCancelInventoryClickEvent.
@Test
public void shouldCancelInventoryClickEvent() {
// given
InventoryClickEvent event = mock(InventoryClickEvent.class);
HumanEntity player = mock(Player.class);
given(event.getWhoClicked()).willReturn(player);
given(listenerService.shouldCancelEvent(player)).willReturn(true);
// when
listener.onPlayerInventoryClick(event);
// then
verify(event).setCancelled(true);
}
use of org.bukkit.event.inventory.InventoryClickEvent in project AuthMeReloaded by AuthMe.
the class PlayerListenerTest method shouldAllowInventoryClickEvent.
@Test
public void shouldAllowInventoryClickEvent() {
// given
InventoryClickEvent event = mock(InventoryClickEvent.class);
HumanEntity player = mock(Player.class);
given(event.getWhoClicked()).willReturn(player);
given(listenerService.shouldCancelEvent(player)).willReturn(false);
// when
listener.onPlayerInventoryClick(event);
// then
verify(event, only()).getWhoClicked();
}
Aggregations