Solved [1.14] Crossbows returning nothing in hand

Discussion in 'Spigot Plugin Development' started by BrendanLeeT, Aug 15, 2019.

  1. Hello everyone! So I've been working on my EnchantShop plugin and a user reported an issue to me that the plugin returns "you have no item in your hand" whilst holding a crossbow and attempting to purchase an enchantment. It might be a really stupid thing I've done but I cannot figure out why it is happening. I've tried both player.getItemInHand() which I know is an outdated method but I still tried as well as player.getInventory().getItemInMainHand().

    The Spigot I'm using is
    <version>1.14.2-R0.1-SNAPSHOT</version>

    I appreciate anyone who tries to help me with this weird issue.

    Code:
    Code (Java):
     @EventHandler
        public void onSignInteract(PlayerInteractEvent event) {
            Player player = event.getPlayer();
            if (event.getClickedBlock() != null && PlayerUtility.isRightClickBlock(event.getAction()) && event.getClickedBlock().getState() instanceof Sign) {
                Sign sign = (Sign) event.getClickedBlock().getState();
                if (getPlugin().getEnchantManager().isEnchantSign(sign)) {
                    Enchantment enchantment = getPlugin().getEnchantManager().getEnchant(sign);
                    if (enchantment == null) {
                        player.sendMessage(MessagesConfig.getMessages().get("enchant-not-found"));
                        DebugUtility.debug("Couldn't find the enchantment " + sign.getLine(1));
                        return;
                    }

                    Bukkit.broadcastMessage("Hand: " + (player.getInventory().getItemInMainHand().getType() == Material.AIR ? "Nothing" : player.getInventory().getItemInMainHand().getType()));

                    if (player.getItemInHand() == null || player.getItemInHand().getType() == Material.AIR) {
                        player.sendMessage(MessagesConfig.getMessages().get("no-item-in-hand"));
                        DebugUtility.debug(new TextComponent(player.getName() + " tried to apply an enchantment but they have no item in their hand"),
                                "Item in hand: " + (player.getItemInHand() == null ? "nothing" : player.getItemInHand().getType()));
                        return;
                    }

                    if (!enchantment.canEnchantItem(player.getItemInHand())) {
                        player.sendMessage(MessagesConfig.getMessages().get("cannot-add-enchantment")
                                .replace("{enchantment}", StringUtility.getEnchantName(enchantment.getName())));
                        DebugUtility.debug(player.getName() + " tried to apply enchantment " + enchantment.getName() + " to " + player.getItemInHand().getType() + " but failed");
                        return;
                    }

                    if (player.getItemInHand().containsEnchantment(enchantment) && player.getItemInHand().getEnchantmentLevel(enchantment) >= getPlugin().getEnchantManager().getEnchantLevel(sign)) {
                        player.sendMessage(MessagesConfig.getMessages().get("attempted-downgrade"));
                        DebugUtility.debug(new TextComponent(player.getName() + " tried to downgrade their item"),
                                "Item: {item}|Enchant: {enchant}|{calc}"
                                        .replace("{item}", player.getItemInHand().getType().name())
                                        .replace("{calc}", player.getItemInHand().getEnchantmentLevel(enchantment) + ">=" + getPlugin().getEnchantManager().getEnchantLevel(sign))
                                        .replace("{enchant}", enchantment.getName())
                                        .replace("|", StringUtility.newLine()));
                        return;
                    }

                    if (getPlugin().getEnchantManager().shouldPayWithCash(sign)) {
                        getPlugin().getMoneyTransaction().doTransaction(player, sign);
                        DebugUtility.debug(player.getName() + " has called the transaction method for money");
                    } else {
                        getPlugin().getXpLevelTransaction().doTransaction(player, sign);
                        DebugUtility.debug(player.getName() + " has called the transaction method for XP");
                    }
                }
            }
        }
     
  2. You should use ItemStack is=player.getInventory().getItemInMainHand(); instead of player.getItemInHand() every time, one important reason is that this second is deprecated.
     
  3. Find a way to generate a constant for v1.8 and v1.9 (i think 1.9 added offhand?) & create yourself an utility method that branches based on that. If you use the 1.14 api it will be safe (since it only enters the mainhand branch should it exist.)

    Do not use getiteminhand as an all solution.
     
  4. I'm aware the player.getItemInHand() is outdated but my other debug with the Bukkit.broadcastMessage uses player.getInventory().getItemInMainHand() and it still doesn't work
     
  5. The plugin was originally built on 1.8 so I updated to 1.14 but player.getInventory().getItemInMainHand() still returns as nothing. Weird but this issue only appears to be with the crossbow
     
  6. I've tried and I can't seem to reproduce the issue in the latest 1.14.4 build (maybe a bug with 1.14.2?).
    What other plugins do you have enabled?
     
  7. EssentialsX due to a bug with my plugin colliding with it, EnchantShop (one in development) and vault. I will use the latest 1.14 spigot and get back to you soon, a bit caught up with some real life things right now.
     
  8. Alright I was stupid and after digging around I realized that I didn't specify an api version in the plugin.yml. This issue has now been resolved and I appreciate everyone who tried to help out :)

    Really I should have looked around even more but I guess I was in a rush and wasn't thinking clearly, thank you to those who gave up your time to help with this issue.