How do I check if a player right clicks an item with Item Meta?

Discussion in 'Plugin Development' started by Xp10d3, Dec 2, 2019.

  1. Offline

    Xp10d3

    Hey, I'm having some trouble with my "Economy" plugin.

    What I currently have: Every time you kill a player, a config updates and adds 0.5 to their balance. In the config it shows gold and then the player's ID. I get that config whenever the player right clicks a gold nugget. It opens a GUI (using a command is too complex since I have to get the config) with a gold block that shows the player's balance.

    Where I am stuck: I want to check whether the player is right clicking that specific nugget that is renamed. Currently the nugget is called, "Balance" in gold with some lore. The lore is: "Right Click to display your balance. *next line* You get more money for every kill you get." I know there is something related to checking the Item Meta but I don't know how to use it. This isn't related to the main question so you don't have to answer but I am also stuck in how to disable the player from grabbing an item from the GUI and how to remove only gold since I want to add a withdrawing and depositing system.

    Code: https://sourceb.in/9db6e8b3f3 (I only use one class)
    I've also uploaded my source folder for those who don't have access to sourceb.in. That only contains the one class and not my .yml files.

    Thanks for the help!
    -Xp10d3
     

    Attached Files:

    • src.zip
      File size:
      2.8 KB
      Views:
      0
  2. Offline

    Strahan

    Get the ItemMeta, check for the display name. You can get meta by doing ItemMeta meta = (ItemStack object).getItemMeta(). Then you get the name via .getDisplayName().
     
  3. Offline

    yPedx

    @Xp10d3
    Code:
    @EventHandler
        public void click(InventoryClickEvent event) {
            Player player = (Player) event.getWhoClicked();
            if ((event.getCurrentItem().getType() == Material.RED_STAINED_GLASS_PANE) && event.getRawSlot() < event.getInventory().getSize()) {
                player.closeInventory();
            }
        }
    What if the item is null? You won't be able to get it's type.
    The same goes for your other events;
    Code:
    @EventHandler
        public void onItemPickup(InventoryClickEvent event) {
            Player player = (Player) event.getWhoClicked();
            if (event.getCurrentItem().getType() == Material.GOLD_BLOCK) {
                event.setCancelled(true);
            }
            player.sendMessage(ChatColor.RED + "Hey! You can't steal that Gold Block. Stop trying!");
        }


    Also, here are a few "nice to know" things;

    1. You don't need the @Override annotation for your onEnable and onDisable functions (The annotation makes no difference). There's also no need for you to log to the console on enable or disable, as Bukkit already does this for you. Of course you could do it if you still want a custom message though.

    2. The variable instance does not need to be public, because you've already got a getter for it that's public. Setting your variable to private makes it unavailable for other classes, and they have to use your getter. Doing this will result in other classes having less control over your main instance (which is good, don't get me wrong-- there's basically less security risks).

    3. Instead of repeatedly accessing your config file every time you need to change the gold value, you could use a HashMap to keep track of it. In your onEnable you could put all your config values into your HashMap, and then save all the keys and values (players and gold) to your config onDisable.

    4. If your players are capable of changing the displayname and lore of their items, checking those two are very insecure ways to differentiate between the real gold and the fake. If your server version is 1.14+, you could use this; https://www.spigotmc.org/threads/a-guide-to-1-14-persistentdataholder-api.371200/
    If you're using an older version, you could look into NBT tags, there are plenty of tutorials regarding them.
     
    Last edited: Dec 2, 2019
    Xp10d3 likes this.
  4. Offline

    Xp10d3


    Okay. Thanks for the help! That was very useful. I'll be sure to fix that in my code. I fixed the problem with the item being null (
    Code:
      else if ((event.getCurrentItem().getType() == null)) { return;} 
    ) which was a big problem since that caused the plugin to think that I was clicking a gold block when I wasn't xD Anyway, thanks again! Very helpful and solved a lot of bugs :)

    Thanks! I'll be sure to add that.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Dec 2, 2019
    yPedx likes this.
  5. Offline

    Strahan

    This. Please.. don't clutter server logs any more than necessary. Spigot's default message is fine.

    True, and I'd add that using dependency injection would be even better IMO.

    Just wanted to mention, config is cached by the system so it's not really any different.
     
  6. Offline

    Xp10d3

    Alright. Thanks; I'll keep that in mind. How would I use a dependency injection? Or HashMap for that matter? I've always been confused on HashMap and how it worked. I've seen many Spigot tutorials that use that but I've never been able to follow them because of it.
     
  7. Offline

    yPedx

    That's what I said xD

    Believe it or not, hashmaps are actually very easy to deal with.

    Let's take a look at the following line;
    Code:
    HashMap<UUID, String> myMap = new HashMap<>();
    (UUID) The type of keys it can store.
    (String) The type of values it can store.

    Think of it as a safe: you need a PIN to access the contents of the safe. A hashmap acts pretty much the same- you add a key along with a value, and to get the value later on you need the key.
    If I were to add the value "hello world!" to the hashmap, with a specified key like this;
    Code:
    UUID uuid = UUID.randomUUID();    // This just generates a random UUID (universally unique identifier).
    
    myMap.put(uuid, "hello world!");    //uuid is the key and "hello world!" is the value.
    Then I would need to re-use that UUID (the key) to retreive the value we stored in the hashmap.
    To do that, we have to do;
    Code:
    String text = myMap.get(uuid);
    Now, the value of text is "hello world!" because that's what we stored in myMap using the uuid key.
     
  8. Offline

    Xp10d3

    Thanks so much! That was extremely helpful. I think I understand HashMaps now ;)
     
    yPedx likes this.
  9. Offline

    Strahan

    Yes, ergo "this". I was agreeing :) It annoys me to no end when plugin authors spam my console lol
     
    Xp10d3 likes this.

Share This Page