Solved ItemStack.getDurability doesn't work on the Poison Potion.

Discussion in 'Plugin Development' started by BadBoy6767, Nov 3, 2015.

Thread Status:
Not open for further replies.
  1. Offline

    BadBoy6767

    I have a plugin and I'm having trouble with it.
    I'm trying to catch a BrewEvent and trying to check if it's a poison potion.
    The things I've tried it using the methods getDurability and getting the potion damage values from the wiki.
    Another thing I've tried is creating a Potion instance (and make it's type the type from the damage value to make it automated) and comparing it's type to PotionTypes.
    The last thing I tried is comparing ItemStack durability to the PotionType's deprecated method getDamageValue().
    None of these things work and I would like to fix this as soon as I could (I know that is said alot here).
     
  2. Offline

    DeadlyScone

    You will need to call getContents() in the event, You might need to cast Potion to the return. Then you need to retrieve the PotionEffect from each potion
    so something kinda like this.
    Code:
    public void onBrewEvent(BrewEvent e){
         Potion[] potions = ((Potion)e.getContents());
         for(Potion pot : potions){
              if(pot.getType() == PotionEffectType.POISON){
                    //Do stuff
                   break;
              }
         }
    }
     
    Last edited: Nov 3, 2015
  3. Offline

    BadBoy6767

    I can't cast e.getContents() to Potion[], it's not inherited.
     
  4. Offline

    DoggyCode™

    Hey dosent har ide BukkitRunnable? Wouldnt that be safer?
     
  5. Offline

    Scimiguy

    getContents() returns a BrewerInventory.

    use getContents()
    and grab the ingredient from the inventory with getIngredient and check against potential ingredients
     
  6. Offline

    BadBoy6767

    I'm not sure what any of you mean.
    I'm just trying to restrict slowness, weakness, instant damage and poison, the only thing that doesn't work in this code is the poison:
    Code:
    
                        if (is.getDurability() == PotionType.SLOWNESS.getDamageValue()
                                || is.getDurability() == PotionType.INSTANT_DAMAGE.getDamageValue()
                                || is.getDurability() == PotionType.POISON.getDamageValue()
                                || is.getDurability() == PotionType.WEAKNESS.getDamageValue()) {
                            isNegativePotion = true;
                        }
    
     
  7. Offline

    Scimiguy

    @BadBoy6767
    Interesting
    Do us a favour;

    Log to console the damage value of the ItemStack, and the damage Value of the Poison Potion Type
    Then post it here so we can see
     
  8. Offline

    BadBoy6767

    @Scimiguy
    When I brew the potion, the ItemStack's durability was 16, and the potion of poisons durability is 4...
     
  9. Offline

    Scimiguy

    Neither of those really match anything.

    You're better off using getType() or something to get the PotionEffectType.
     
  10. Offline

    BadBoy6767

    How would I cast ItemStack to Potion?
     
  11. Offline

    Scimiguy

    Potion.fromItemStack(ItemStack)
     
  12. Offline

    BadBoy6767

    I now tried this code:
    Code:
    Potion potion = Potion.fromItemStack(is);
    if(potion != null && (potion.getType() == PotionType.INSTANT_DAMAGE || potion.getType() == PotionType.SLOWNESS
                                || potion.getType() == PotionType.POISON || potion.getType() == PotionType.WEAKNESS)) {
                            isNegativePotion = true;
                        }
    
    But to no avail.
     
  13. Offline

    Scimiguy

    Log to console what your potion type is, let us know
     
  14. Offline

    BadBoy6767

    @Scimiguy
    This line produces a NullPointerException:
    Code:
    Bukkit.broadcastMessage(potion.getType().toString());
    Probably the ItemStack is not a potion.
     
  15. Offline

    Scimiguy

    Well you never showed us the code you used to get it either so....
     
  16. Offline

    BadBoy6767

    @Scimiguy
    I did.
    No ideas?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Nov 4, 2015
  17. Offline

    Scimiguy

    I had to sleep
    How are you getting your itemstack?
     
  18. Offline

    BadBoy6767

    @Scimiguy
    Like this:
    The original code is taken from a private plugin made by some other person, the original code restricted the Strength II potion, and he asked me to also do that with all the debuffs.
    Code:
    
        @EventHandler
        public void onBrew(BrewEvent e) {
            boolean isStrength = false;
            boolean isGlowDust = false;
            boolean isNegativePotion = false;
            ItemStack[] arrayOfItemStack1;
            int j = (arrayOfItemStack1 = e.getContents().getContents()).length;
            for (int i = 0; i < j; i++) {
                ItemStack is = arrayOfItemStack1[i];
                if (is != null) {
                    if ((is.getType() != null) && (is.getType() == Material.POTION)) {
                        // My code begins here.
                        Potion potion = Potion.fromItemStack(is);
                      
                        if ((is.getDurability() == 8201) || (is.getDurability() == 8265) || (is.getDurability() == 16457)
                                || (is.getDurability() == 16393)) {
                            isStrength = true;
                        }
                    } else if ((is.getType() != null) && (is.getType() == Material.GLOWSTONE_DUST)) {
                        isGlowDust = true;
                    }
                }
            }
            if ((isStrength && isGlowDust) || (isNegativePotion && isNegativePotion)) {
                e.setCancelled(true);
                double radius = 5.0D;
                List<Player> near = e.getBlock().getLocation().getWorld().getPlayers();
                for (Player p : near) {
                    if (p.getLocation().distance(e.getBlock().getLocation()) <= radius) {
                        p.sendMessage(ChatColor.translateAlternateColorCodes('&', getConfig().getString("potionFail")));
                    }
                }
                ItemStack[] arrayOfItemStack2;
                int m = (arrayOfItemStack2 = e.getContents().getContents()).length;
                for (int k = 0; k < m; k++) {
                    ItemStack i = arrayOfItemStack2[k];
                    if ((i != null) && (i.getType() != null) && (i.getType() == Material.GLOWSTONE_DUST)) {
                        e.getBlock().getLocation().getWorld().dropItemNaturally(e.getBlock().getLocation(), i);
                        e.getContents().remove(i);
                    }
                }
            }
        }
     
  19. Offline

    Scimiguy

  20. Offline

    BadBoy6767

    @Scimiguy
    But a null check and a ItemStack type check is already there:
    Code:
                if (is != null) {
                    if ((is.getType() != null) && (is.getType() == Material.POTION)) {
     
  21. Offline

    Scimiguy

    Because it's checking the ingredient slot aswell.
    As well as the fact that the potions don't exist before the event completes.

    You need a runnable


    EDIT: Had 5 mins to work on it so I ended up making this:
    (Tested and works)
    Code:
    package tslat.antisnape;
    
    import java.util.HashSet;
    
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.inventory.BrewEvent;
    import org.bukkit.inventory.BrewerInventory;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.potion.Potion;
    import org.bukkit.potion.PotionType;
    import org.bukkit.scheduler.BukkitRunnable;
    
    public class AntiSnape extends JavaPlugin implements Listener{
    
        private HashSet<PotionType> bannedPots = new HashSet<PotionType>();
     
        @Override
        public void onEnable() {
            getServer().getPluginManager().registerEvents(this, this);
            bannedPots.add(PotionType.POISON);
        }
     
        @EventHandler(ignoreCancelled = true)
        public void brewing(BrewEvent e) {
            new BukkitRunnable() {
             
                @Override
                public void run() {
                    BrewerInventory inv = e.getContents();
                    for (int i = 0; i < 3; i++) {
                        if (bannedPots.contains(Potion.fromItemStack(inv.getItem(i)).getType())) {
                            inv.setItem(i, null);
                        }
                    }
                }
            }.runTaskLater(this, 1L);
        }
    }
    Feel free to use it as you wish, all you need to do is add PotionTypes to the bannedPots Set, it'll get rid of them when they brew.

    I'll make the rest of the plugin this afternoon if you don't want to do it yourself, I have work now
     
    Last edited: Nov 4, 2015
  22. Offline

    BadBoy6767

    So what am I exactly supposed to do?
     
  23. Offline

    Scimiguy

    Basically, check the item slots 0-2, don't check all of the contents of your BrewerInventory.
    Wrap it in a BukkitRunnable with a tick delay, because only then will the potions exist.

    Do your checking from there
     
  24. Offline

    BadBoy6767

    @Scimiguy
    I now did this:
    Code:
    new BukkitRunnable() {
                @Override
                public void run() {
                    boolean isStrength = false;
                    boolean isGlowDust = false;
                    boolean isNegativePotion = false;
                    ItemStack[] arrayOfItemStack1;
                    int j = (arrayOfItemStack1 = e.getContents().getContents()).length;
                    for (int i = 0; i < 4; i++) {
                        ItemStack is = arrayOfItemStack1[i];
                        if (is != null) {
                            Potion potion = Potion.fromItemStack(is);
                               
                            if ((is.getType() != null) && (is.getType() == Material.POTION)) {
                                if ((is.getDurability() == 8201) || (is.getDurability() == 8265) || (is.getDurability() == 16457)
                                        || (is.getDurability() == 16393)) {
                                    isStrength = true;
                                } else if(potion.getType() == PotionType.SLOWNESS || potion.getType() == PotionType.INSTANT_DAMAGE
                                        || potion.getType() == PotionType.WEAKNESS || potion.getType() == PotionType.POISON) {
                                    isNegativePotion = true;
                                }
                            } else if ((is.getType() != null) && (is.getType() == Material.GLOWSTONE_DUST)) {
                                isGlowDust = true;
                            }
                        }
                    }
                    if ((isStrength && isGlowDust) || (isNegativePotion && isNegativePotion)) {
                        e.setCancelled(true);
                        double radius = 5.0D;
                        List<Player> near = e.getBlock().getLocation().getWorld().getPlayers();
                        for (Player p : near) {
                            if (p.getLocation().distance(e.getBlock().getLocation()) <= radius) {
                                p.sendMessage(ChatColor.translateAlternateColorCodes('&', getConfig().getString("potionFail")));
                            }
                        }
                        ItemStack[] arrayOfItemStack2;
                        int m = (arrayOfItemStack2 = e.getContents().getContents()).length;
                        for (int k = 0; k < m; k++) {
                            ItemStack i = arrayOfItemStack2[k];
                            if ((i != null) && (i.getType() != null) && (i.getType() == Material.GLOWSTONE_DUST)) {
                                e.getBlock().getLocation().getWorld().dropItemNaturally(e.getBlock().getLocation(), i);
                                e.getContents().remove(i);
                            }
                        }
                    }
                }
            }.runTaskLater(this, 1l);
    Still makes the poison.
     
  25. Offline

    StevasaurousREX

    Code:
    EDIT::--snip-- bade code no more.
    
    Basically just checks if it is a potion then, if the durability is 16 (odd that it has both 4 for bukkit spawning and 16 for in-game brewing). Little hacky maybe but it works and only stops potion, to stop more then just poison then just add more durabilities to the list

    EDIT:: Also I didnt need to make it a BukkitRunnable


    EDIT2:: From what i can tell is the event is called when the potions are ready but before the player can access them. On my test server I have 3 brewing stands that are forever looping trying to make poison potions but right before they complete bukkit tells them no and so they keep everything and loop again.
     
    Last edited: Nov 4, 2015
  26. Offline

    BadBoy6767

  27. Offline

    StevasaurousREX

    Currently no Ill look for a way to.

    EDIT:: This way blocks more then just poison. Didnt test that till now Ill look for a work around.
     
    Last edited: Nov 4, 2015
  28. Offline

    Scimiguy

    *cough* PotionType
     
  29. Offline

    BadBoy6767

    @StevasaurousREX
    Thank you so much, it worked!

    @Scimiguy
    Oh, yeah :p.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Nov 4, 2015
  30. Offline

    StevasaurousREX

    Lol my bad, didnt know my potion types and never checked if 16 exists as something like idk awkward potion the base of the poison potion..


    So here is the new code that works and will work for all new brewed potions (if they get a potion of poison from somewhere else they can still extend it ect.)
    Also added the block for potion of weakness..
    Code:
        @EventHandler
        public void onBrew(BrewEvent e) {
            boolean basePotion = false;
            List<Material> badMat = new ArrayList<Material>();
            badMat.add(Material.SPIDER_EYE);
            badMat.add(Material.FERMENTED_SPIDER_EYE);
            List<Short> badDur = new ArrayList<Short>();
            badDur.add((short) 16); // Awkward
            badDur.add((short) 32); // Thick
            badDur.add((short) 64); // Mundane extended
            badDur.add((short) 8192); // Mundane
            ItemStack[] items = e.getContents().getContents();
            for(ItemStack item : items) {
                // Check if it is a potion and that it is one of the base potion types.
                if ((item.getType() == Material.POTION) && badDur.contains(item.getDurability())) {
                    basePotion = true;
                // This is to catch the final item and see if it is one of the ingredients that we don't allow in badMat
                } else if (badMat.contains(item.getType()) && basePotion) {
                    e.setCancelled(true);
                    break;
                }
            }
        }
     
    Last edited: Nov 4, 2015
Thread Status:
Not open for further replies.

Share This Page