[SPIGOT-5964] ItemStacks created pre Spigot 1.16 don't match ItemStacks created in Spigot 1.16 Created: 08/Jul/20  Updated: 08/Oct/20

Status: Open
Project: Spigot
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: blablubbabc Assignee: Unassigned
Resolution: Unresolved Votes: 9
Labels: 1.16.1, itemmeta, itemstack, serialization

Version: This server is running CraftBukkit version git-Spigot-ad703da-e2403a3 (MC: 1.16.1) (Implementing API version 1.16.1-R0.1-SNAPSHOT)
Guidelines Read: Yes

 Description   

I originally mentioned this issue as part of https://hub.spigotmc.org/jira/browse/SPIGOT-5063. However, even though the issues are related, a fix for one of these issues won't necessarily also resolve the other issue. So I moved this into a separate ticket.

During the update for MC 1.16 Spigot has made some changes to how they convert from legacy item display names and lore to Minecraft text component format.

Eg. an item which previously had the internal nbt data

{display:{Name:'{"text":"Bla"}'}}

will now be created by Spigot with the the data

{display: {Name: '{"extra":[{"text":"Bla"}],"text":""}}}

If color codes are involved the change between Spigot versions is as follows:

{display:{Name:'{"text":"§cBla"}'}}

This becomes:

{"extra":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"red","text":"Bla"}],"text":""}

This issue can be encountered whenever a plugin creates an ItemStack via the Bukkit API (eg. using ItemMeta#setDisplayName), or when a plugin deserializes ItemStacks from a configuration file (during deserialization CraftBukkit invokes CraftMetaItem#setDisplayName as well to convert from the stored legacy text to Minecraft text components).

The actual issue with this change in internal text representation is now that items created by plugins on previous server versions will not match items created on Spigot 1.16 (i.e. ItemStack#isSimilar(ItemStack) fails for these items). Since minecraft itself considers these items to be different as well, they will also not stack.

Edit: This new text representation is also an issue with blocks picked up in creative mode. Minecraft will add a lore to the picked up ItemStacks with text

'{"text":"(+NBT)"}'

After a plugin has serialized and then deserializes the ItemStack to/from a config the text representation of that lore has changed to

{{'{"extra":[{"text":"(+NBT)"}],"text":""}'}}

, making it no longer stack with any original items (reference: http://prntscr.com/tf4xba).

 

I am not completely sure what a fix for this could look like.

  • One could look into somehow reverting this change in representation (i.e. try to make the conversion produce nbt which more closely matches the previous data format). For simple texts this could mean avoiding creating the unneccessary extra tag and producing the more compact representation, similar to before. This would also mean that ItemStacks created by users via Minecraft mechanisms (eg. give commands, loottables, etc.) are more likely match Spigot's internal data format and therefore compatible.
    However, avoiding legacy color codes inside the produced components is probably a good change. Nevetheless, for the same reason as above, the produced component text could probably be more compact by only outputting those entries that are actually needed.
  • A different solution could be to automatically convert items to Spigot's data format. However, this would need to happen within the Minecraft server itself for any items that have already been created in the past.
    Paper seems to have recently made some change to do something like this: https://github.com/PaperMC/Paper/pull/3741/files
    However, this seems to only convert the item data if it contains legacy color codes, but the issues also affects items without color codes as shown above.
    However, since this would then affect all ItemStacks, a potential issue with this could be incompatibilities with any vanilla setup/contraption (eg. involving command blocks or similar) which somehow check for items with specific nbt data / expect the items produced via Minecraft mechanisms to keep there exact internal representation.
  • A combination of these two points could be to:
    • Create a more compact json representation for plain text without color codes. Maybe it is also possible to create a more compact representation for text with colors, but I am currently not sure if there is maybe a reason to produce this verbose output.
    • Convert any minecraft itemstacks which contain legacy color codes. Any items created by minecraft or via minecraft mechanisms will then not be affected by this Spigot conversion (since those items are not expected to contain legacy color codes).
    • However, since Spigot 1.16 has been out for a while now there may already be quite a few items with text in the verbose format (using the extra tag and an empty text tag at the end) which don't use colors. It might make sense to also convert any of these items (if this pattern is matched). It is unlikely that players have explicitly created items in this verbose format, so the impact on items not created by Spigot should be limited.

 



 Comments   
Comment by KyuBe Fairy [ 08/Oct/20 ]

+1

Comment by Pitrex111 [ 06/Oct/20 ]

Could it be moved as major, a lot of stuff breaks because of this change :/

Comment by KyuBe Fairy [ 11/Jul/20 ]

Thanks Dyens, maybe this'll help me work around the problem later. (I'm very busy for the next 2 weeks, so either this resolves itself by a spigot fix until then or I could look into your deserialization trick.)

Comment by Dyens [ 10/Jul/20 ]

This bug is caused at this moment bu the deserialization making use of CraftChatMessage#fromString() that is usefull for showing text to a player, but does not reconstruct the data the same. This is due to it appending the Components to a new ChatComponentText("") thus being stored as children components (extra data), when the first component should be the parent and the rest the children. But there al several cass where even that will not work.

 

I have fixed this problem in my server by deserializing the data as a Stringified JSON Chat Component, the same you will get with the /data, instead of a legacy string. I think this is what makes more sense since now Spigot finally handles the display data as IChatBaseComponent instead of legacy strings. For this issue to be completly fixed, in the case of the String not being a JSON element, it should be loaded as it was loaded on 1.15.2. Making it this way, it should prevent new issues related to item display serialization and fix the current ones.

A bit out of the clarification, but even this being a "Minor" issue, for survival servers this does have a great impact on Log (e.g. CoreProtect) and Shop (e.g. Shopkeepers) plugins.

I would like to make a PR for at least show my aproach, but my CLA is pending for review.

Comment by KyuBe Fairy [ 10/Jul/20 ]

Actually this doesn't match to all versions of Spigot 1.16.
I first noticed this when I tried to update my early version from 25th of June to a version available at 30th of June.
(I don't know the exact version numbers, but I can look them up, if it's important.)

Well, I wouldn't call this bug minor, 'cause (after a slightly painful rollback when players noticed their special items turned into crap) I'm stuck at the early and buggy version now. (Until I have time for legacy support / workaround my plugin.)
So. I guess its to late now to change the Spigot behavior back since this "bug" has been around for so long and created so many "new" items? Or maybe it has to be the way it is right now? Maybe because there are some changes to colors?
If not - I'd be happy to get the old behavior back.

Generated at Sat Dec 13 15:21:24 UTC 2025 using Jira 10.3.13#10030013-sha1:56dd970ae30ebfeda3a697d25be1f6388b68a422.