Uploaded image for project: 'Spigot'
  1. Spigot
  2. SPIGOT-7902

PotionMeta 'custom-effects' does not persist if empty.

XMLWordPrintable

    • CraftBukkit version 4316-Spigot-a759b62-8a6f8b6 (MC: 1.21.1) (Implementing API version 1.21.1-R0.1-SNAPSHOT)
    • Yes

      The PotionMeta of a new ItemStack(Material.SPLASH_POTION) does not contain an empty array for `custom-effects` when there are no custom effects.

      However, the PotionMeta within ItemStacks returned by events, such as  PotionSplashEvent#getPotion().getItem(), will contain an empty array for `custom-effects,` even when there are none. This inconsistency makes it difficult to compare and distinguish between two identical ItemStacks using methods like ItemStack#isSimilar() and ItemStack#equals()

      Note I had to trim the following outputs because it was messing with formating, if you need the full output use the demo plugin.
      Here is the trimed output for of ItemStack#toString() for a newly created splash potion.

      ItemFlags=[HIDE_ADDITIONAL_TOOLTIP], custom-color=Color:[argb0xFFF28E1C]

      And here is the trimed output of ItemStack#toString() for the same exact ItemStack after it's thrown and returned by PotionSplashEvent#getPotion().getItem()

      ItemFlags=[HIDE_ADDITIONAL_TOOLTIP], custom-color=Color:[argb0xFFF28E1C], custom-effects=[]

      As a result, checks such as this "event.getPotion().getItem().isSimilar(MOLOTOV_ITEM)" will fail, despite the exact same constant being used to give the player the item. 

      I provided both a demo plugin and source code example.

      Update
      After looking through the code, I don't think we actually need to change how the custom effect array is initialized.

      It seems like the root of the problem is just the CraftMetaPotion#hasCustomEffects() method.
      Patching it to "return customEffects != null && !customEffects.isEmpty();" accurately fixes both issues without unintentionally changing any unknown behaviors. It's low risk because it restores previous and expected behavior of hasCustomEffects() without changing any underlying tags.

      In my testing this fixes the issues I experienced when comparing items using ItemStack#equals() and ItemStack#isSimilar()
      Additionally, this corrects toString() since it now serializes appropriately to match the change in #hasCustomEffects()

            Unassigned Unassigned
            beanp02@yahoo.com James Perry
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: