Помогите Как исправить баг в эвенте InventoryClickEvent?

Статус
Закрыто для дальнейших ответов.

extThrower

Активный участник
Пользователь
Баллы
61
Идея плагина была запретить игрокам, всеми возможными способами класть в сундук кость, но после проверки плагина заметил, что когда я перемещаю кость из хотбара клавишами 0-9, кость перемещается в сундук, а обратно вернуть кость можно только сломав сундук. Не могу сделать так, чтобы кость не перемещалась из инвентаря в сундук клавишами 0-9.

Снимок.PNG
 
Код:
@EventHandler
public void onInvClick2(InventoryClickEvent e) {
      Player player = (Player) e.getWhoClicked();
      Inventory opened_inv = (Inventory) e.getView().getTopInventory();
       ItemStack item = e.getCurrentItem();
      if (opened_inv != null && e.getClickedInventory() != null && e.getClickedInventory() == player.getInventory()) {
          if (opened_inv.getType() == InventoryType.CHEST) {
              if (item != null && item.getType() == Material.BONE) {
                  e.setCancelled(true);
                  player.sendMessage("yourmessage");
               }
           }
       }
   }
Дело в том, что getInventory() возвращает верхний инвентарь (сундук), а не инвентарь игрока. Нужна проверка, что ты кликаешь в нужном инвентаре.
P.S. По крайней мере так написано в доках:
upload_2023-6-6_21-45-33.png
P.P.S. Код не проверял, не знаю, будет ли работать :p

Можно ещё через https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/inventory/InventoryMoveItemEvent.html попробовать.
 
Последнее редактирование:
Код:
   @EventHandler
   public void onInvClick(InventoryClickEvent e) {
       Player player = (Player) e.getWhoClicked();
       if (e.getClickedInventory() == player.getInventory()) {
           // Inventory player_inv = (Inventory) e.getView().getBottomInventory();
           Inventory opened_inv = (Inventory) e.getView().getTopInventory();
           ItemStack item = e.getCurrentItem();
           if (item != null && item.getType() == Material.BONE) {
               if (opened_inv.getType() == InventoryType.CHEST) {
                   if (item.getType() == Material.BONE) {
                       e.setCancelled(true);
                       player.sendMessage("yourmessage");
                   }
               }
           }
       }
   }
Дело в том, что getInventory() возвращает верхний инвентарь (сундук), а не инвентарь игрока. Нужна проверка, что ты кликаешь в нужном инвентаре.
P.S. По крайней мере так написано в доках:
Посмотреть вложение 65102
P.P.S. Код не проверял, хз будет ли работать :p

Можно ещё через https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/inventory/InventoryMoveItemEvent.html попробовать.

Он возвращает любой инвентарь, а не только сундука. Это у него указано что брать кость из сундук нельзя.
 
Он возвращает любой инвентарь, а не только сундука. Это у него указано что брать кость из сундук нельзя.
Насколько я понял, getInventory() возвращает верхний инвентарь, с которым взаимодействует игрок.

P.S. Он не писал, что нельзя будет из сундука доставать кость)
запретить всеми возможными способами класть в сундук кость

Кстати я тут заметил, что, по-моему, не сделал проверку на то, открыт ли просто инвентарь или открыт сундук.
 
Код:
@EventHandler
    public void onInventoryClick(InventoryClickEvent event) {
        if (event.getClickedInventory() != null && event.getClickedInventory().getType() == org.bukkit.event.inventory.InventoryType.CHEST) {
            // Проверяем, если перемещается кость
            ItemStack item = event.getCurrentItem();
            if (item != null && item.getType() == Material.BONE) {
                boolean isShiftClick = event.isShiftClick();
                boolean isNumberKey = event.getHotbarButton() >= 0 && event.getHotbarButton() <= 8;
                boolean isDragMode = event.getClick().isKeyboardClick() && event.getClick().isCreativeAction();

                if (isShiftClick || isNumberKey || isDragMode) {
                    event.setCancelled(true); // Отменяем событие перемещения
                    event.getWhoClicked().sendMessage("Перемещение кости в сундук запрещено!");
                }
            }
        }
    }

Проверяй
 
if (isShiftClick || isNumberKey || isDragMode) { event.setCancelled(true); // Отменяем событие перемещения event.getWhoClicked().sendMessage("Перемещение кости в сундук запрещено!"); }
Такие нажатия не определятся через метод getCurrentItem() ?

Насколько я понял, getInventory() возвращает верхний инвентарь, с которым взаимодействует игрок.
Это неверно, да?
 
Код:
@EventHandler
    public void onInventoryClick(InventoryClickEvent event) {
        if (event.getClickedInventory() != null && event.getClickedInventory().getType() == org.bukkit.event.inventory.InventoryType.CHEST) {
            // Проверяем, если перемещается кость
            ItemStack item = event.getCurrentItem();
            if (item != null && item.getType() == Material.BONE) {
                boolean isShiftClick = event.isShiftClick();
                boolean isNumberKey = event.getHotbarButton() >= 0 && event.getHotbarButton() <= 8;
                boolean isDragMode = event.getClick().isKeyboardClick() && event.getClick().isCreativeAction();

                if (isShiftClick || isNumberKey || isDragMode) {
                    event.setCancelled(true); // Отменяем событие перемещения
                    event.getWhoClicked().sendMessage("Перемещение кости в сундук запрещено!");
                }
            }
        }
    }

Проверяй
Не работает, получается перемещать всеми способами кроме того, где нужно зажать shift
 
Код:
@EventHandler
public void onInvClick2(InventoryClickEvent e) {
      Player player = (Player) e.getWhoClicked();
      Inventory opened_inv = (Inventory) e.getView().getTopInventory();
       ItemStack item = e.getCurrentItem();
      if (opened_inv != null && e.getClickedInventory() != null && e.getClickedInventory() == player.getInventory()) {
          if (opened_inv.getType() == InventoryType.CHEST) {
              if (item != null && item.getType() == Material.BONE) {
                  e.setCancelled(true);
                  player.sendMessage("yourmessage");
               }
           }
       }
   }
Дело в том, что getInventory() возвращает верхний инвентарь (сундук), а не инвентарь игрока. Нужна проверка, что ты кликаешь в нужном инвентаре.
P.S. По крайней мере так написано в доках:
Посмотреть вложение 65102
P.P.S. Код не проверял, не знаю, будет ли работать :p

Можно ещё через https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/inventory/InventoryMoveItemEvent.html попробовать.
Все работает, но как запретить перемещать предмет клавишами 0-9?
 
Все работает, но как запретить перемещать предмет клавишами 0-9?
А, всё-таки эти события он тот ивент не обрабатывает.

Тогда как SlenderMix писал попробуй добавить в мой код:
Код:
    @EventHandler
   public void onInvClick2(InventoryClickEvent e) {
      Player player = (Player) e.getWhoClicked();
      Inventory opened_inv = (Inventory) e.getView().getTopInventory();
       ItemStack item = e.getCurrentItem();
      if (opened_inv != null && e.getClickedInventory() != null && e.getClickedInventory() == player.getInventory()) {
          if (opened_inv.getType() == InventoryType.CHEST) {
              if (item != null && item.getType() == Material.BONE) {
                  boolean isShiftClick = e.isShiftClick();
                  boolean isNumberKey = e.getHotbarButton() >= 0 && e.getHotbarButton() <= 8;
                  boolean isDragMode = e.getClick().isKeyboardClick() && e.getClick().isCreativeAction();
                  if (isShiftClick || isNumberKey || isDragMode) {
                      e.setCancelled(true);
                      e.getWhoClicked().sendMessage("yourmessage");
                  }
                  e.setCancelled(true);
                  player.sendMessage("yourmessage");
               }
           }
       }
   }

Либо вот так попробуй:
Код:
    @EventHandler
   public void onInvClick2(InventoryClickEvent e) {
      Player player = (Player) e.getWhoClicked();
      Inventory opened_inv = (Inventory) e.getView().getTopInventory();
       ItemStack item = e.getCurrentItem();
      if (opened_inv != null && e.getClickedInventory() != null && e.getClickedInventory() == player.getInventory()) {
          if (opened_inv.getType() == InventoryType.CHEST) {
              if (item != null && item.getType() == Material.BONE) {
                  if (e.getClick().isCreativeAction() || e.getClick().isKeyboardClick() || e.getClick().isLeftClick() || e.getClick().isRightClick() || e.getClick().isShiftClick()) {
                      e.setCancelled(true);
                      e.getWhoClicked().sendMessage("yourmessage");
                  }
               }
           }
       }
   }
 
Последнее редактирование:
А, всё-таки эти события он тот ивент не обрабатывает.

Тогда как SlenderMix писал попробуй добавить в мой код:
Код:
    @EventHandler
   public void onInvClick2(InventoryClickEvent e) {
      Player player = (Player) e.getWhoClicked();
      Inventory opened_inv = (Inventory) e.getView().getTopInventory();
       ItemStack item = e.getCurrentItem();
      if (opened_inv != null && e.getClickedInventory() != null && e.getClickedInventory() == player.getInventory()) {
          if (opened_inv.getType() == InventoryType.CHEST) {
              if (item != null && item.getType() == Material.BONE) {
                  boolean isShiftClick = e.isShiftClick();
                  boolean isNumberKey = e.getHotbarButton() >= 0 && e.getHotbarButton() <= 8;
                  boolean isDragMode = e.getClick().isKeyboardClick() && e.getClick().isCreativeAction();
                  if (isShiftClick || isNumberKey || isDragMode) {
                      e.setCancelled(true);
                      e.getWhoClicked().sendMessage("yourmessage");
                  }
                  e.setCancelled(true);
                  player.sendMessage("yourmessage");
               }
           }
       }
   }

Либо вот так попробуй:
Код:
    @EventHandler
   public void onInvClick2(InventoryClickEvent e) {
      Player player = (Player) e.getWhoClicked();
      Inventory opened_inv = (Inventory) e.getView().getTopInventory();
       ItemStack item = e.getCurrentItem();
      if (opened_inv != null && e.getClickedInventory() != null && e.getClickedInventory() == player.getInventory()) {
          if (opened_inv.getType() == InventoryType.CHEST) {
              if (item != null && item.getType() == Material.BONE) {
                  if (e.getClick().isCreativeAction() || e.getClick().isKeyboardClick() || e.getClick().isLeftClick() || e.getClick().isRightClick() || e.getClick().isShiftClick()) {
                      e.setCancelled(true);
                      e.getWhoClicked().sendMessage("yourmessage");
                  }
               }
           }
       }
   }
Всёравно получается перемещать клавишами 0-9. Два кода попробовал
 
Баг понял, происходит из-за того, что мы обрабатываем предмет, на который кликнули (хотбар клики тоже).
Но если мы с помощью клавиш 1-9 перемещаем предмет в сундук, то мы на него не кликаем.
Кстати, если кликнуть на предмет в инвентаре клавишами хотбара (навестить и нажать 1-9), то ивент будет отменён как надо.
Как вариант использовать ивент https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/inventory/InventoryMoveItemEvent.html или через getAction() как-нибудь проверять. Как придумаю что-нибудь - обновлю сообщение.
 
Потому что в getCurrentItem стоит тот итем, который в слоте куда будет переноситься итем.


Код:
ItemStack item = event.getClick() == ClickType.NUMBER_KEY ? event.getWhoClicked().getInventory().getItem(event.getHotbarButton()) : event.getCurrentItem();
 
Статус
Закрыто для дальнейших ответов.
Назад
Верх