Solved Item verification problems

Discussion in 'Spigot Plugin Development' started by ShadowMasterG23, May 31, 2017.

  1. I'm creating a plugin that mimics the Scroll of Icarian Flight from The Elder Scrolls: Morrowind. If you don't know what that is, then here is a link: http://elderscrolls.wikia.com/wiki/Scroll_of_Icarian_Flight
    Anyways, the problem that I have is verifying whether or not it is actually a Scroll.

    Here's my constructor method:
    Code (Text):

    public boolean isScroll(ItemStack item, Player player) {
            item = player.getInventory().getItemInMainHand();

            if ((item.getType() == Material.getMaterial(getConfig().getString("scroll.material")))) {
                if (item.getItemMeta().hasLore()) {
                    if (item.getItemMeta().getLore().toString().contains("FROM THE EARTH TO AETHER...AND BACK")) {
                        if (item.getItemMeta().hasDisplayName()) {
                            if (item.getItemMeta().getDisplayName().contains("Scroll") || item.getItemMeta().getDisplayName().contains("Icarian") || item.getItemMeta().getDisplayName().contains("Flight")) {
                                return true;
                            } else {
                                player.sendMessage(ChatColor.translateAlternateColorCodes('&', getConfig().getString("messages.invalid_scroll")));
                                return false;
                            }
                        } else {
                            return false;
                        }
                    } else {
                        player.sendMessage(ChatColor.translateAlternateColorCodes('&', getConfig().getString("messages.invalid_scroll")));
                        return false;
                    }
                } else {
                    return false;
                }
            }
            return false;
        }
     
    The problem is that I am also using another plugin called Banknotes and it is triggering the "invalid_scroll" message. Banknotes have a custom name and lore, so is there a way to get around this problem or will I have to call upon the Banknotes class and check to see if it is a banknote? I'm not sure if re-ordering the if statements would help considering that the Scrolls and Banknotes share the same attributes and I don't know how to call upon methods from other plugins, so I'm hoping that there is some workaround. Any suggestions?

    Misc:
    I'm coding using Java 8

    Note: I am relatively new to Java. You might be able to tell by the way I code, but nevertheless, I'm slowly learning, so if I respond asking you to define the terminology you used, don't be surprised. :p
     
  2. You could create your example Scroll (which you have stored in your config) ItemStack upon enabling the plugin and store it in cache.
    After that just use the #isSimilar() method to compare the example scroll with the ItemStack the player is using.
     
  3. Whenever I put the code in the onEnable() method I got an error saying that only final is permitted. I changed it from public to final and then I see that my reload method and my giveScroll method are now filled with errors because the ItemStack Scroll is no longer accessible.
     
  4. Gianluca

    Gianluca Retired Resource Staff
    Retired Patron

    This is a overcomplicated..

    To simplify it, what you could do is: build the ItemStack from the configuration in the onEnable and have a public getter method for it, so you can obtain it in other classes. Create a util class to check the value and return whether or not it is a scroll.

    Code (Text):
    public boolean isScroll(ItemStack itemStack) {
      return Main.get().getScroll().isSimilar(itemStack);
    }
    Be sure to replace "Main.get().getScroll()" with whatever you use to get the scroll item defined in the config
     
  5. Sorry it took so long to respond but some family related stuff came up and I couldn't implement your suggestion until today. I changed my code to what you suggested and it worked, but now there is another issue. If there are invalid scrolls and a player right clicks them, the invalid_scroll message won't show up at all. Also, it now doesn't matter what they name the scroll or what they put for the lore. I wanted for the plugin to have some restrictions on naming to retain the aspect of the plugin.
     
    #5 ShadowMasterG23, Jun 4, 2017
    Last edited: Jun 4, 2017
  6. This is a bump but I also thought that it might be a good idea to share some of the code.

    My onEnable() method:
    Code (Text):

    public ItemStack Scrolls;
       
        @Override
        public void onEnable() {
            Scrolls = createItem(Material.getMaterial(getConfig().getString("scroll.material", "PAPER")), 1, ChatColor.translateAlternateColorCodes('&', getConfig().getString("scroll.name")), getConfig().getStringList("scroll.lore"));
           
            new ScrollListener(this);

            this.getConfig().addDefault("messages.prefix", "&3&lScroll &7&l>> ");
            getConfig().options().copyDefaults(true);
            saveDefaultConfig();
            cfile = new File(getDataFolder(), "config.yml");
            dfile = new File(getDataFolder(), "data.yml");

            if (!getDataFolder().exists()) {
                try {
                    getDataFolder().createNewFile();
                }
                catch (IOException e) {
                    log.severe(ChatColor.RED + "Could not create the Scrolls Folder!");
                }
            }
           
            if (!cfile.exists()) {
                try {
                    cfile.createNewFile();
                }
                catch (IOException e2) {
                    log.severe(ChatColor.RED + "Could not create the config.yml!");
                }
            }
           
            if (!dfile.exists()) {
                try {
                    dfile.createNewFile();
                    saveResource("data.yml", true);
                }
                catch (IOException e3) {
                    log.severe(ChatColor.RED + "Could not create the data.yml!");
                }
            }
           
            reloadData();
        }
     

    The method I am using to get the Scroll:
    Code (Text):

    public ItemStack scrollGrabber() {
            return this.Scrolls;
        }
     

    The verification method (suggested):
    Code (Text):
    public boolean isScroll(ItemStack itemStack) {
      return scrollGrabber().isSimilar(itemStack);
    }

    The verification method (I am currently using):
    Code (Text):

    public boolean isScroll(ItemStack item, Player player) {
            item = player.getInventory().getItemInMainHand();

            if (scrollGrabber().isSimilar(item)) {
                if (item.getItemMeta().hasLore()) {
                    if (item.getItemMeta().getLore().toString().contains("FROM THE EARTH TO AETHER...AND BACK")) {
                        if (item.getItemMeta().hasDisplayName()) {
                            if (item.getItemMeta().getDisplayName().contains("Scroll") || item.getItemMeta().getDisplayName().contains("Icarian") || item.getItemMeta().getDisplayName().contains("Flight")) {
                                return true;
                            } else {
                                player.sendMessage(ChatColor.translateAlternateColorCodes('&', getConfig().getString("messages.invalid_scroll")));
                                return false;
                            }
                        }
                    } else {
                        player.sendMessage(ChatColor.translateAlternateColorCodes('&', getConfig().getString("messages.invalid_scroll")));
                        return false;
                    }
                }
            }
            return false;
        }
     

    Look, as of currently, things are working well. The Scrolls no longer interfere with Banknotes and the verification method is catching invalid scrolls. The only issue that I have left is that if you change the config settings for the scrolls, older scrolls will no longer trigger the invalid_scroll message. I've tried a couple things but then realized that I was still depending on the #isSimilar() method and nothing would work unless it was what was defined in the config. Am I dreaming too big here or is there some way to fix this issue?
     
  7. Which item do you use as scroll or do have the scrolls, unimportant if old or new, something in common, like a lore or name? I think an easy way to fix this would be a lore that every scroll has and after you checked for the common lore you check for the data from the config to determine if the scroll is invalid or not.
     
  8. You shouldn't send messages in #isScroll(). In your click event or whatever:
    Code (Text):
    if (!isScroll(yourItem)){
        player.sendMessage("not a scroll");
    }
     
  9. @ChristopherSend
    Code (Text):
    scroll:
      material: PAPER
      name: "&c&lScroll &7&lof &c&lIcarian Flight"
      lore:
      - "&7Right-Click Me!"
      - "&7FROM THE EARTH TO AETHER...AND BACK"
     
    @RobinMC I tried that and the invalid_scroll message triggers when I redeem a banknote.
     
  10. So every scroll has the Material.PAPER and a lore that contains &7Right-Click Me!. You could check these to dertermine if it is scroll and then the name and other lore rows to check if it is a valid one or not
     
  11. You see, I have already tried that; the first post shows the old verification method that I was using. The only problem with that method was that it was triggering the invalid_scroll message when I redeemed a banknote. Banknotes have a custom display name and lore, just like the Scrolls. If I check to see if the item has a specific lore and send the invalid_scroll message if it doesn't meet the criteria, then the banknotes will suffer from that choice.
     
  12. Mhm i see the problem here... You could check that your item isn't additionally a banknote and just output the invalid_scroll message if the item is not a scroll and not a banknote. Or you could just give your scrolls an entchantment.
     
  13. The enchantment sounds like the only workaround at this point and I'll explain why. I have tried to verify whether of not the item is a Banknote and not a Scroll through numerous different methods. I reordered the checks for Lore and DisplayNames. I tried to import the Banknote plugin and check to see if I could use the #isBanknote() method, but was unable to do so because I probably didn't do things correctly, but this is what I tried to access the plugin.
    Code (Text):
    BanknotePlugin banknote = (BanknotePlugin)getServer().getPluginManager().getPlugin("BanknotePlugin");
    After that, I put this code in my #isScroll() method:
    Code (Text):
    if (banknote.isBanknote(item)) {
        player.sendMessage("Tis a banknote");
    }
    I tested the code and the Scrolls broke. The banknotes still worked fine, it was just that every single time that someone right-clicked an item, it would spam the console with errors.

    I even tried to access the Banknote config.yml through this line of code:
    Code (Text):
    if (item.getItemMeta().getDisplayName().contains(banknote.getConfig().getString("note.name"))) {
      player.sendMessage("That's a banknote!");
    }
    The same thing happened again when I tested the new code. I did some more testing and found out that I can't cast from FileConfiguration to BanknotePlugin when I changed the access method. At that point, I changed things back to the old verification method at the beginning of this thread and decided to ask for help.
     
  14. And if you access the banknote config not via the instance of the plugin but through a direct Link to the yml file?
    Code (Text):
    FileConfiguration c = YamlConfiguration.loadConfiguration(new File("./plugins/Banknoteplugin", "config.yml"));
     
  15. I tried this in the #isScroll() method and nothing happened.
    Code (Text):

    FileConfiguration c = YamlConfiguration.loadConfiguration(new File("./plugins/Banknotes", "config.yml"));
      if (item.getItemMeta().getDisplayName().contains(c.getString("note.name"))) {
      player.sendMessage("Banknote");
    }
     
    Not quite sure if I did that right, but when I tested it I didn't receive the message. Everything still works and no errors are being sent to console.
     
  16. Sorry i think i made a mistake, the / have to be \
    Code (Text):
    FileConfiguration c = YamlConfiguration.loadConfiguration(new File(".\plugins\Banknoteplugin", "config.yml"));
    And you could also check, just for testing, what String the config returns
     
  17. Hmm, I changed the slashes and now Eclipse is giving me an error saying "Invalid escape sequence (valid ones are \b \t \n \f \r \" \' \\ )"

    EDIT: I tried the last suggestion \\ and nothing happened.
     
    #18 ShadowMasterG23, Jun 8, 2017
    Last edited: Jun 8, 2017
  18. Sorry my fault, tested it and works fine with /
    But have you already tested if it reads out the name out of the config correctly?
     
  19. That's ok, we all make mistakes, but I'm not exactly sure why it isn't working for me. I'm not getting any errors when I right click items, but I'm also not receiving the message.