SpigotMC / BungeeCord

BungeeCord, the 6th in a generation of server portal suites. Efficiently proxies and maintains connections and transport between multiple Minecraft servers.
https://www.spigotmc.org/go/bungeecord
Other
1.53k stars 1.09k forks source link

Sending components of an item in HoverEvent is not possible #3688

Open Brokkonaut opened 1 month ago

Brokkonaut commented 1 month ago

Bungeecord version

BungeeCord-Bootstrap:1.20-R0.3-SNAPSHOT:52ab21b:1844

Server version

No response

Client version

1.20.6

Bungeecord plugins

n/a

The bug

When creating a HoverEvent with a Item content the components of that item are not shown on the client (this also applies to spigot) I tried this on spigot with

            String itemTag = stack.getItemMeta().getAsString();
            msg.setHoverEvent(new HoverEvent(Action.SHOW_ITEM, new Item(stack.getType().getKey().toString(), 1, itemTag != null ? ItemTag.ofNbt(itemTag) : null)));

(i also tried stack.getItemMeta().getAsComponentString()) - both don't work, only the item type is shown but no enchantments, custom name or whatever. It was working in 1.20.4.

Log output (links)

No response

Checking

md-5 commented 1 month ago

cc/ @2008Choco

2008Choco commented 1 month ago

I'm unsure how you want to approach this now, but ItemSerializer tries to serialize it as id and tag, which doesn't exist anymore in vanilla. Id is now id (though I think we already serialize this), Count is now count, and tag is now components and is a Map of all the serialized components. So getAsComponentString() is correct, we're just not serializing it correctly in BungeeChat anymore. Do we want to have backwards compatibility for this?

An easily reproducible command is the followng:

/tellraw @p {"text":"[Hover me!]","hoverEvent":{"action":"show_item","contents":{"id": "minecraft:diamond_sword","count":1,"components":{"minecraft:enchantments":{"minecraft:sharpness":1}}}}}

EDIT: Because Mojang isn't consistent for whatever reason, getComponentsAsString() returns the components surrounded in [] brackets as that's the format that's expected by /give. But that of course isn't valid when you're passing it to components in a hover event because it needs to be an actual map object, not a string. This suddenly got way more annoying to support because ItemTag now can't be represented as a string, but has to be represented as an object capable of being serialized identically to how components are serialized. We would need a BungeeCord equivalent of ItemMeta...

We could probably solve this in a really ugly way for Bukkit's own personal use by introducing a HoverEventProvider interface and having ItemStack implement it, but that doesn't solve the issue of supporting that in BungeeCord. It's also probably still annoying to implement in Bukkit. CraftBukkit would be fine, Bukkit, not so much. Immediate hacky solution I can think of at least is to serialize everything down and then manually concatenate the serialized string into the serialized JSON where "components" should be...

Janmm14 commented 1 month ago

As it is a problem in (de-)serialization i have these suggestions:

andrewkm commented 2 weeks ago

Would love a fix on this. <3