From e2bef829e767b4a79bd0693949563bdb38772ff8 Mon Sep 17 00:00:00 2001 From: XxFran10xX <318299142+XxFran10xX@users.noreply.github.com> Date: Sat, 26 Sep 2026 21:23:03 +0200 Subject: [PATCH] fix: refresh the clicked slot without the reopened view The click refresh ran a tick later and read the raw slot from whatever view was open then. When a menu closed in between, the index could pass the countSlots check yet be past the player's 46-slot menu, throwing IndexOutOfBoundsException. Keep the clicked inventory and its own slot index from the event instead. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../magic/listener/GearRefreshListener.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/tfminecraft/magic/listener/GearRefreshListener.java b/src/main/java/net/tfminecraft/magic/listener/GearRefreshListener.java index 02458fd..41e52ed 100644 --- a/src/main/java/net/tfminecraft/magic/listener/GearRefreshListener.java +++ b/src/main/java/net/tfminecraft/magic/listener/GearRefreshListener.java @@ -8,6 +8,7 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import net.tfminecraft.magic.Magic; @@ -39,16 +40,18 @@ public void onClick(InventoryClickEvent event) { if (!(event.getWhoClicked() instanceof Player player)) { return; } - int rawSlot = event.getRawSlot(); + // Keep the clicked inventory and its own slot index. The open view can change + // before next tick (a menu closes), so a raw view slot may no longer exist. + Inventory clicked = event.getClickedInventory(); + int slot = event.getSlot(); later(() -> { if (!player.isOnline()) { return; } - if (rawSlot >= 0 && rawSlot < player.getOpenInventory().countSlots()) { - ItemStack rebuilt = GearRefresher.refreshIfOutdated( - player.getOpenInventory().getItem(rawSlot), player); + if (clicked != null && slot >= 0 && slot < clicked.getSize()) { + ItemStack rebuilt = GearRefresher.refreshIfOutdated(clicked.getItem(slot), player); if (rebuilt != null) { - player.getOpenInventory().setItem(rawSlot, rebuilt); + clicked.setItem(slot, rebuilt); } } ItemStack cursor = GearRefresher.refreshIfOutdated(