Skip to content

Commit

Permalink
Improve event handling
Browse files Browse the repository at this point in the history
This fixes some regressions that occurred, mainly issues with GUI items being able to be stolen through certain click types/actions. It also allows the user to perform certain actions that would normally be blocked if the GUI would allow such changes to it to be made. See the documentation within these changes for specific details.
  • Loading branch information
APickledWalrus committed Aug 21, 2021
1 parent 3584c77 commit 30455aa
Showing 1 changed file with 47 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
import ch.njol.skript.SkriptEventHandler;
import io.github.apickledwalrus.skriptgui.SkriptGUI;
import io.github.apickledwalrus.skriptgui.gui.GUI;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;

public class GUIEvents implements Listener {

Expand All @@ -27,16 +28,15 @@ public GUIEvents() {
public void onInventoryClick(InventoryClickEvent event) {
// Don't handle this event if it's from an unsupported click type
switch (event.getClick()) {
case UNKNOWN:
case WINDOW_BORDER_RIGHT:
case WINDOW_BORDER_LEFT:
case CREATIVE:
return;
}

// Don't handle this event if the clicked inventory is the bottom inventory
// No inventory was clicked
Inventory clickedInventory = event.getClickedInventory();
if (clickedInventory == null || clickedInventory.equals(event.getView().getBottomInventory())) {
if (clickedInventory == null) {
return;
}

Expand All @@ -46,14 +46,56 @@ public void onInventoryClick(InventoryClickEvent event) {
return;
}

// Don't process unknown clicks for safety reasons - cancel them to prevent unwanted GUI changes
if (event.getClick() == ClickType.UNKNOWN) {
event.setCancelled(true);
return;
}

// Don't handle this event if the clicked inventory is the bottom inventory, as we want users to be able to interact with their inventory
// However, there are some cases where interaction with the bottom inventory may cause changes to the top inventory
// Because of this, we will cancel the event for some click types
if (clickedInventory.equals(event.getView().getBottomInventory())) {
switch (event.getClick()) {
case SHIFT_LEFT:
case SHIFT_RIGHT:
event.setCancelled(true);
return;
case DOUBLE_CLICK:
// Only cancel if this will cause a change to the GUI itself
// We are checking if our GUI contains an item that could be merged with the event item
// If that item is mergeable but it isn't stealable, we will cancel the event now
Inventory guiInventory = gui.getInventory();
int size = guiInventory.getSize();
ItemStack cursor = event.getWhoClicked().getItemOnCursor();
for (int slot = 0; slot < size; slot++) {
ItemStack item = guiInventory.getItem(slot);
if (item != null && item.isSimilar(cursor) && !gui.isStealable(gui.convert(slot))) {
event.setCancelled(true);
break;
}
}
return;
default:
return;
}
}

gui.getEventHandler().onClick(event);
}

@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onInventoryDrag(InventoryDragEvent e) {
GUI gui = SkriptGUI.getGUIManager().getGUI(e.getInventory());
if (gui != null) {
gui.getEventHandler().onDrag(e);
// Check if any slots in the actual GUI were changed. We don't care if only the player's inventory was changed.
int lastSlotIndex = gui.getInventory().getSize() - 1;
for (int slot : e.getRawSlots()) {
if (slot <= lastSlotIndex) { // A slot in the actual GUI was interacted with
gui.getEventHandler().onDrag(e);
break;
}
}
}
}

Expand Down

0 comments on commit 30455aa

Please sign in to comment.