[SPIGOT-6312] Base components save extra and text properties in the wrong order Created: 11/Jan/21  Updated: 15/Jan/21  Resolved: 15/Jan/21

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

Type: Bug Priority: Minor
Reporter: steve Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

1.16.4 java 13


Version: 1.16.4
Plugin: Any usage of the basecomponent API (itemMeta.getLoreComponents() in this case)
Guidelines Read: Yes

 Description   

Chat component extra and text properties are saved in wrong order.

What behaviour is expected:
"extra" chat components should save before "text" properties, vanilla code: https://media.discordapp.net/attachments/555462289851940864/798259050840064020/unknown.png?width=1440&height=600

What behaviour is observed:
text properties save before extra chat components, net.md_5.bungee.api.chat code: https://media.discordapp.net/attachments/555462289851940864/798258968853348362/unknown.png?width=1440&height=393

This results in invalid, unstackable items.

vanilla NBT:   

{"extra":[{"text":"Some line in weapon lore"}],"text":""}

BaseComponent saved NBT:

{"text":"","extra":[{"text":"Some line in weapon lore"}]}

 

There may also need to be some kind of datafixer for pre-existing invalid items to reverse the save order back to vanilla.



 Comments   
Comment by md_5 [ 15/Jan/21 ]

Will be resolved with 1.16.5 tomorrow

Comment by steve [ 12/Jan/21 ]

One problem may be actually that BaseComponent api doesn't seem to be able to distinguish between the broken and working components?

wrong order:

TextComponent{text=, BaseComponent(color=, font=null, bold=null, italic=null, underlined=null, strikethrough=null, obfuscated=null, insertion=null, extra=[TextComponent{text=Some line in weapon lore, BaseComponent(color=, font=null, bold=null, italic=null, underlined=null, strikethrough=null, obfuscated=null, insertion=null, extra=null, clickEvent=null, hoverEvent=null)}], clickEvent=null, hoverEvent=null)}

correct order:

TextComponent{text=, BaseComponent(color=, font=null, bold=null, italic=null, underlined=null, strikethrough=null, obfuscated=null, insertion=null, extra=[TextComponent{text=Some line in weapon lore, BaseComponent(color=, font=null, bold=null, italic=null, underlined=null, strikethrough=null, obfuscated=null, insertion=null, extra=null, clickEvent=null, hoverEvent=null)}], clickEvent=null, hoverEvent=null)}

 

So im not sure how I would be able to detect items that have an incorrect order.

Comment by md_5 [ 12/Jan/21 ]

Agreed that there's no need to 'fix' existing items

Comment by blablubbabc [ 12/Jan/21 ]

This is probably something to fix inside the Bungee Chat API. From looking through the code, Minecraft seems to serialize component data in this order:

bold, italic, underlined, strikethrough, obfuscated, color, insertion, clickEvent (action, value), hoverEvent (action, contents), font, extra, text / <translate, with> / score (name, objective) / selector / keybind / <nbt, interpret, block / entity / storage>

Whereas Bungee Chat / Spigot components serialize their data in this order:

<text>, color, font, bold, italic, underlined, strikethrough, obfuscated, insertion, extra, clickEvent (action, value), hoverEvent (action, contents / value (legacy)), <translate, with> / keybind / score (name, objective, value) / selector

So this affects: text, color, font, extra
Bungee Chat API PR: https://github.com/SpigotMC/BungeeCord/pull/3018/

This affects any Spigot-specific API that allows setting display name, lore, or book pages as components. Only items modified via these APIs since the recent text related changes in CraftBukkit are affected (since previously, the Spigot components would be converted into Minecraft components, which would then be serialized via the Minecraft serializer when being applied to an item).

Another alternative would be to first convert the Spigot components into Minecraft components (by parsing the Json), and then using Minecraft's serializer to produce the Json that is being used for the item. But that would require additional back and forth conversions, which ideally should not be required.

Regarding a data fixer for existing items using this alternative ordering:
There is no strict ordering of these elements (either order is valid, they are just not equal). For Spigot's component API it makes sense to produce an order that matches Minecraft's order to avoid this sort of compatibility issue. However, players can in principal also specify the elements in a different order when they create items via vanilla commands (the Minecraft wiki, which is probably the reference for most of these players, also mentions no explicit ordering of these elements, nor does the order implicitly mentioned there match the order used by Minecraft). So a datafixer based on the order of these elements alone might break any existing items that are explicitly created with a different order and commands that rely on a specific order of this data (eg. via Minecraft's nbt target selector).

If we disregard that aspect, an option could be to add a conversion to Minecraft whenever an ItemStack is loaded (nms.ItemStack.load(NBTTagCompound)), and when an ItemStack is deserialized from a config. The conversion would essentially need to parse any potentially affected text data (display name, lore, book pages) into a component, and then serialize that component again. This would be invoked for every item, every time it is loaded again. Ideally this would be toggleable via a Spigot setting such as 'normalize-items' or similar (default disabled).

Once the serialization of Spigot components to Json is 'fixed', a plugin could also manually implement the conversion for specific items by getting the item's display name/lore/book pages as components (via the Spigot API) and then setting the display name/lore/book pages to these retrieved components.

 

Comment by md_5 [ 11/Jan/21 ]

blablubbabc

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