[SPIGOT-5063] Deserialized items with colored names don't match original items Created: 11/Jun/19  Updated: 31/Dec/20  Resolved: 31/Dec/20

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

Type: Bug Priority: Minor
Reporter: blablubbabc Assignee: Unassigned
Resolution: Fixed Votes: 16
Labels: 1.16.1, item, serialization

Attachments: File Test.jar    
Issue Links:
Duplicate
is duplicated by SPIGOT-5213 §f is removed when using .getDisplayN... Resolved
is duplicated by SPIGOT-5304 Changing NBT data by opening your inv... Resolved
is duplicated by SPIGOT-5656 Item NBT being re-organized, creating... Resolved
Problem/Incident
causes SPIGOT-5351 Villager Trades by buying items with ... Resolved
Version: This server is running CraftBukkit version git-Spigot-baafee9-7cc7719 (MC: 1.14.2) (Implementing API version 1.14.2-R0.1-SNAPSHOT)
Guidelines Read: Yes

 Description   
  1. Using a command block to create an item with colored display name (I hope the command is correct / uses the regular format used for colored items): "give blablubbabc minecraft:stone{"display":{"Name":"[ {\"text\":\"Stone\",\"color\":\"gold\"}

    ]"}} 64"

  1. A plugin uses Bukkit's item serialization to store this item in a config file. The colored display name will be stored using the legacy color code: "§6Stone"
  2. The plugin loads the item again.
  3. The deserialized item will no longer match the previously serialized item. The display name will also no longer be in italic font (see screenshot:http://prntscr.com/o0gcp4 ).

Attached is a plugin for testing this: When holding an item in hand and interacting with air, it will save the item. It will also compare the item to the item currently in the offhand slot. When holding no item in hand, it will load the item from the config.

 
Edit: With MC 1.16 this issue seems to also affect items with very simple display names and lore, even if they don't contain any color/formatting.

Example:

/give @p minecraft:lime_dye{display:{Name:'{"text":"Bla"}'}} 1

This item will get converted to an item with tag

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

during item de/serialization.

Edit: A related issue is that with MC 1.16 Spigot has made some changes to how they convert between legacy text and Minecraft's text component format. This change of internal representation results in newly created items (eg. created via Bukkit's API and using ItemMeta#setDisplayName(String)) to no longer stack with items which have been created in the same way in a previous version of Spigot.

Edit: I created a separate issue for the change in Spigot's item data format: https://hub.spigotmc.org/jira/browse/SPIGOT-5964

Edit: One workaround seems to be to use legacy color codes in the give command, such as for example:

give @p minecraft:emerald{display:{Name:"{\"text\":\"\\u00A7a\\u00A7oEmerald Name\"}",Lore:["{\"text\":\"\\u00A76\\u00A7oLore\"}"]}} 1

Edit: Actually, this 'workaround' does not fully work (anymore?). It seems that the escape sequence 

\\u00A7

is not getting converted to the "§" character immediately. See https://prnt.sc/t3vms3

There are some situations in which this conversion occurs: CraftBukkit triggers this 'conversion' in cases such as when the item is getting serialized and deserialized or when handling certain events such as when the item is getting dragged around inside the inventory.
In vanilla Minecraft I have only found one occasion which triggers this conversion and that is specific to enchanted books getting disenchanted inside a grindstone. In other situations the item's display name will either remain as it was (and keep using 

\\u00A7

internally), or break (eg. when repairing these items inside an anvil without renaming them, see https://bugs.mojang.com/browse/MC-1443 (Mojang considers this 'as intended' since there is no need for them to support these legacy formatting codes anywhere inside the vanilla game)).

The items which got 'converted' will not match (ItemStack#isSimilar) any items which did not yet get converted.
So the current situation seems to be that Bukkit does not properly support items with non-legacy colors (eg. data not getting persisted correctly), while Minecraft does not properly support items with legacy color codes (see for example the issue linked above about repairing these items in anvils).

Offtopic: I might be wrong about this, but has there be a change regarding whether empty inventory slots return null or an AIR item? I know that minecraft uses the 'empty' item (of type air) for these slots internally, I just thought to remember that bukkit kept returning null for these anyways. During my testing I noticed that these slots return empty AIR items now.



 Comments   
Comment by wysohn [ 18/Dec/20 ]

Based on very simple tests, manually comparing Strings seems to be working: https://github.com/MillcreekServer/rapidframework/blob/a939fa3c944387c0aa322162e427db97f3feea55/src/main/java/io/github/wysohn/rapidframework3/bukkit/utils/InventoryUtil.java#L126

That's pretty obvious as the String part has to be extracted as plain text when getDisplayName or getLore is invoked, so resulting String must be the same regardless of their internal representation.

Hopefully this issue will be fixed soon!

Comment by wysohn [ 17/Dec/20 ]

So, I think this issue will take long time to fix, yet any suggestion to work around? Serializing and deserializing suggested by Pitrex111 doesn't seem to be an ideal solution either, and it actually doesn't work in my case: https://hub.spigotmc.org/jira/browse/SPIGOT-6260

Can this problem be avoided by not using any custom display name (and lore)?

Comment by Pitrex111 [ 04/Dec/20 ]

@Luke135 i created a command for players:

CommandExecutor executor4=new CommandExecutor(){CommandExecutor executor4=new CommandExecutor(){
 @Override public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { if(sender instanceof Player) { Player p = (Player) sender; ItemStack item = p.getInventory().getItemInMainHand(); YamlConfiguration sec = new YamlConfiguration(); sec.set("item", item); YamlConfiguration nsec = new YamlConfiguration(); try { nsec.loadFromString(sec.saveToString()); ItemStack refreshedItem = nsec.getItemStack("item"); p.getInventory().setItemInMainHand(refreshedItem);  } catch (InvalidConfigurationException e) { p.sendMessage("An error occured while trying to perform an action. " + e.getMessage()); } return true; } return false; }
 }; root.getCommand("refresh_item").setExecutor(executor4);

Simply I am just serializing and deserializing item in player main hand, this works for me because of the way how my server functions. If you need something spicier, you can always iterate over every item in player inventory on join and check every chest that is opened, but  this would eat resources and dampen performance. Unfortunatelly they won't really fix it i think

Comment by Lukáš Schwan [ 04/Dec/20 ]

What

Comment by 2005danyadanya2005 [ 04/Dec/20 ]

не жди фикса. они письку забили уже

Comment by Lukáš Schwan [ 04/Dec/20 ]

They need to fix this

Comment by Lukáš Schwan [ 04/Dec/20 ]

Can you PLEASE tell me how you did that? @Pitrex111

Comment by 2005danyadanya2005 [ 14/Nov/20 ]

really. are you asleep? fix faster please. half a year waiting

Comment by KyuBe Fairy [ 02/Nov/20 ]

Not an option for me since once I upgrade and any player "accidentally" places one of the special blocks (which surely happens), its special abilities are gone forever.
Well 'guess I'll start to rewrite everything now. Hopefully the patch isn't appearing exactly the day after I'm done. 😂

Comment by Pitrex111 [ 02/Nov/20 ]

Well i gave up and provided my players with command that would serialize and deserialize item on a whim

Comment by KyuBe Fairy [ 02/Nov/20 ]

Is there still a patch on the way or can I give up waiting? 😅

Comment by Dyens [ 06/Oct/20 ]

There is already a patch on the way to fix this, but there is a lot of things that neeed to be changed for it to work properly, so we will need to wait a bit more until its merged onto the main branch.

Comment by playbabeTheBookShelf [ 06/Oct/20 ]

Yeah and update locallang to translate already. I see you guys doing fine with 1.16 new text component but don't bother to fix the old one.

Comment by Pitrex111 [ 06/Oct/20 ]

Can it be actually changed to major? A lot of things on my server broke just because of it, and for some if them I have no walk around

Comment by 2005danyadanya2005 [ 27/Sep/20 ]

че вы уснули? исправляйте быстрее

Comment by john doe [ 01/Aug/20 ]

This is a very annoying issue, many of the items I had set up no longer work.

Comment by LaserSlime [ 01/Aug/20 ]

This is so annoying. My clickable Items from pre 1.16 no longer work, because the color codes aren't saved in the item names. The interact event check fails, because the display name of the item doesn't match the name i saved in the plugin.

Comment by Zrips [ 04/Jul/20 ]

This can be related to the issue where item names which contain hex color code format will only have NBT as

{"extra":[{"color":"#6600CC","text":"teal"}],"text":""}

while using basic color format as §3 will result into full output

{"extra":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"dark_aqua","text":"teal"}],"text":""}
Generated at Sat Dec 13 18:59:44 UTC 2025 using Jira 10.3.13#10030013-sha1:56dd970ae30ebfeda3a697d25be1f6388b68a422.