Кодировка патрубка, инвентарь

Сделал простой плагин для действий. У меня одна проблема. Когда игрок нажимает Shift и быстро закрывает инвентарь, он может получить предмет бесплатно. Мне нужно это исправить, что мне делать?

Код ниже:

@EventHandler public void inventoryHandler(InventoryClickEvent e) throws Exception {
    for (AuctionInventory[] inventories : inventoryMap.values()){
        for (AuctionInventory inventory : inventories){
            if (inventory.getInventoryType().equals(AuctionInventoryType.MAIN)) {
                if (e.getClickedInventory().equals(inventory.getSource())) {
                    e.setResult(Event.Result.DENY);
                    e.setCancelled(true);
                    if (e.getCurrentItem().getType() != Material.AIR) {
                        Player p = (Player) e.getWhoClicked();
                        for (Button button : buttonList){
                            if (button.getItem().equals(e.getCurrentItem())){
                                button.doLogic(inventory.getSource(), p);
                                e.setResult(Event.Result.DENY);
                            }
                        }
                        IProduct product = InventoryUtil.getProductByItem(getProducts().values(), e.getCurrentItem());
                        if ((product != null)) {
                            buyProduct(p, product);
                        }
                    }
                }
            }
        }
    }
}

@Override @Deprecated @SuppressWarnings("all")
public boolean buyProduct(Player p, IProduct product) throws Exception {
    if (!product.getSeller().equals(p.getUniqueId())) {
        if (Economy.getMoney(p.getName()) < product.getPrice()) {
            return false;
        }
        p.getInventory().addItem(product.getItem());
        removeProduct(product);
        Economy.setMoney(p.getName(), Economy.getMoney(p.getName()) - product.getPrice());            Economy.setMoney(Bukkit.getOfflinePlayer(product.getSeller()).getName(), Economy.getMoney(Bukkit.getOfflinePlayer(product.getSeller()).getName()) + product.getPrice());
        return true;
    }
    return false;
}

Вау ... это работает, но только с режимом выживания.

N0TrixPM 27.07.2018 12:31

вы не должны использовать Economy.setMoney для подобных транзакций, в хранилище есть специальный метод приема / передачи денег игроку. А что, если предметы не поместятся в инвентаре игрока?

GotoFinal 27.07.2018 13:17
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
636
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Трудно сказать, если ваша логика, связанная с проверкой инвентаря, в порядке, я бы сказал, что вы пропустили InventoryDragEvent. Вам также необходимо реализовать это событие и заблокировать любые взаимодействия, связанные с вашими запасами. Также в своем ClickEvent вы должны заблокировать взаимодействие, если ваш инвентарь открыт, включая клики внутри инвентаря игрока, поскольку есть взаимодействия, которые могут перемещать предметы из открытого инвентаря, щелкая внутри собственного инвентаря. Также getClickedInventory() может возвращать null. Поэтому вам просто нужно проверить event.getView().getTopInventory(), не является ли он нулевым и является ли это вашим инвентарем.

Кроме того, ваш цикл for с кнопками не прерывается / не возвращается, поэтому даже если игрок нажмет кнопку, вы все равно попытаетесь найти предмет для продажи, что тоже может вызвать некоторые проблемы. Также я заметил здесь несколько других проблем, вам не следует использовать функцию .setMoney, если вы используете Vault API, так как это может нарушить совместимость с другими плагинами, то же самое с проверкой денег с помощью getMoney.
Существует специальный метод public boolean has(OfflinePlayer player, double amount);, чтобы проверить, достаточно ли у игрока денег, так как эта функция будет хорошо работать с плагинами, которые допускают отрицательные суммы или платят другим способом. Затем вы должны взять деньги с плеера с помощью: public EconomyResponse withdrawPlayer(OfflinePlayer player, double amount);, а затем проверить ответ, чтобы убедиться, что он был успешным.

p.getInventory().addItem(product.getItem()); что делать, если плееру не хватает места в инвентаре? Обратите внимание, что этот метод возвращает Map<Integer, ItemStack>, где ключ - это индекс элемента из аргумента метода (так как это varargs, в вашем случае ключ может быть только 0, поскольку вы передаете только один аргумент) и элемент, который не поместился в инвентарь. (обратите внимание, что может быть добавлена ​​одна часть стопки, например, 12 из 43 элементов в стопке)

Другие вопросы по теме