Paper
Paper copied to clipboard
Paper Item Property API
Very much WIP, but is the coming of future sponge-inspired ways to manipulate items/entity data.
The current approach to edit items has poorly aged, and in general, creates a lot of issues due to it acting as its own implementation. This PR aims to prevent the API from interacting with items unless necessary, preventing unnecessary parsing and in general useless reparsing for each item.
ItemMeta is still very important as it allows plugin developers to have a more friendly way of editing items. In this PR, it is proposed that we add a new property API that allows developers to ALSO directly edit values themselves. This area of the API would be marked as experimental and in general, would be subject to changes if Mojang changes nbt tags.
(WIP WIP WIP)
ItemStack itemstack = ItemStack.of(Material.STONE);
itemstack.getPropertyHolder().set(ItemProperties.DAMAGE, 0);
// Same thing as (but more performant since it directly edits the item)
ItemMeta meta = itemstack.getItemMeta(); // Clones the item nbt compound to a meta wrapper
meta.setDamage(0); // modifies that wrapped meta
itemstack.setItemMeta(meta); // overrides the wrapped meta
Using the property system, you can directly modify a value without needing to do any sort of cloning, it's a 1:1 operation. ItemMeta has also been improved in this, as now it will instead act as a wrapper that uses this item property api internally. This means that the behavior of the property/meta api will be consistent. For legacy reasons item meta will still need to be cloned, so it will have a small overhead as it clones the underlying NBT tag. After that, however, it is still much faster and prevents parsing the entire item.
Future goals:
- [ ] Figure out what to do about things that need api only itemstacks.
- [ ] Use this same property system to allow for entity nbt manipulation. (For example, making a zombie a baby in spawn egg)
- [ ] Thoroughly test
- [ ] Finalize design points
- [ ] Always use a compound based stack
- [ ] ItemStack interface maybe?
Fixes: #4708 #5071 #6719 #6689 #6437 #6414 #7747 #7335
To fix: https://github.com/PaperMC/Paper/issues/4787
Download the paperclip jar for this pull request: paper-8711.zip
Is this still being worked on at all? It looks really promising
For those wanting to play around, this now adds support for most ItemMeta stuff. Some isn't implemented yet... Note: API item stacks are not supported nor tested yet.
No longer wrapped in values
Now uses SNBT for bukkit item serialization. Note that in the future we will probably move the count/material field out. Although, TBD.
test:
==: org.bukkit.inventory.ItemStack
v: 3337
type: PLAYER_HEAD
meta:
==: ItemMeta
meta-type: PAPER_META
snbt: |-
{
Count: 1b,
id: "minecraft:player_head",
tag: {
CustomModelData: 1,
Enchantments: [
{
id: "minecraft:respiration",
lvl: 1s
}
],
HideFlags: 2,
SkullOwner: {
Id: [I; 1065279268, -1351007849, -1353122767, -455512511],
Name: "Owen1212055",
Properties: {
textures: [
{
Signature: "tlahGxBeyXBBe7FZ247LVUEzozL98moRaj1UFkAt5RSk73RvyAa/bv+JmHJi7orRtzoSKxF0+Zfx7t1jr2jrwIqptnuv1poxRrrdNR+rio9ni06D0NNxW/xJH2IflPRvpaRg2QdX9+ci8RnL1Wj6xyljFzu/8WK7FggqxkxHCrGf5OOTTWADMXphWS8hepn0+j+EXyQk3XVBT5H95CVY07Y3EpDymJ4/kMRoRRT6TqzQ0wYw2vxpHS6kzFnmqE12gV2SSQzCVxVcVmtikMmn80AzmJ3uU0PHZYz3oWU7H8OUoEwDQor+MHzJrteVFlMQhFV669QIOCKVwf0aAz5D4LvdZ8tW1ZNmBDUWtmAYizrbjKh7eGmxhfQL0U0XaBZPGjQPcpo/jrALqvOIqPrwdE+DiU060BfZuYi0uHMg/AdaVeyTHLSX3YlWfI+1UMbgPdZ0QxgE0AhMFw4RwuBGQTSUAWlhLOQJdYCI/mGtaO3uIFhiHhg9+r5VWk0gqJl+nVkvgi1f4uBr35JOX7xH9OhuVTaUB+Uen1gp05fbYjzDDkwgSdNv7RPTDC7ME8rwbIq3R8lflRUGRG98G0Q152kUjLpjcmKMwPupUHVNnM4HIpY6iMMIQZnj+hdWX5F6aDOEF7s8MibdoYhoHAFNgO9zdTha/bRJ6SIOrOFhsHA=",
Value: "ewogICJ0aW1lc3RhbXAiIDogMTY3OTk1MzExODA1NywKICAicHJvZmlsZUlkIiA6ICIzZjdlZGYyNGFmNzk0MTk3YWY1OGZjMzFlNGQ5NmU0MSIsCiAgInByb2ZpbGVOYW1lIiA6ICJPd2VuMTIxMjA1NSIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS83OWY2OTc5NmU3N2U2ZmM0YWM0MWU0YTEyZmE1Mjc1YjcyNzlkMzZlM2I5NDI1NWVlYmI0NzgzNGZhNjJjYTZlIgogICAgfSwKICAgICJDQVBFIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9lN2RmZWExNmRjODNjOTdkZjAxYTEyZmFiYmQxMjE2MzU5YzBjZDBlYTQyZjk5OTliNmU5N2M1ODQ5NjNlOTgwIgogICAgfQogIH0KfQ=="
}
]
}
},
Unbreakable: 1b,
display: {
Lore: [
'{"text":"real"}'
],
Name: '{"text":"GET REAL!"}'
}
}
}
This now passes all tests.
Feel free to use the download jar to test and play around. Mostly, try to see how this works with plugins using the item meta api.
When testing with this build and our custom item plugin, I'm experiencing some "desync" of player head textures in creative mode. I need to do some further investigating what's exactly causing the issue, since we are doing a lot of item modifications during the InventoryCreativeEvent to provide custom lore text etc. for items taken out the creative inventory. But when I click a player head, the skull texture gets invisible, until I relog for example. That does not happen without our plugin, and does not happen with current "normal" paper builds. But as I said, I need to first track down what exactly is causing the problem, which I probably won't have time for today. I will let you know as soon as I figure it out.
There was some issues with skullmeta, should be fixed, so would love to see how it works now.
The issue @aerulion describes should be resolved. This was an issue with meta migration logic.
The skull texture issue is fixed now, thank you!
But I noticed something else, that doesn't quite work: Setting the custom color of a potion will result in the wrong nbt tag set. Also, the resulting nbt tags differ between this build and the current "normal" paper build.
The red item was generated using this build, the green one using the current normal paper build.
Code used to get the item:
final @NotNull ItemStack itemStack = new ItemStack(Material.POTION);
if (itemStack.getItemMeta() instanceof final @NotNull PotionMeta potionMeta) {
potionMeta.setColor(Color.fromRGB(0x25a55f));
itemStack.setItemMeta(potionMeta);
}
event.getPlayer().getInventory().addItem(itemStack);
@aerulion Thanks for the report! It should now correctly set the correct tag. Additionally, I also fixed an issue with the PublicBukkitValues being written when not needed.
It seems the Potion
tag is no longer written, and has the same behavior as a potion item with no tag. This will most likely be some of the (many) differences that this recode will bring. Because the old ItemMeta system wrote a lot of things when not needed.
Using /give command to give potion
What old ItemMeta would have given
I can't really say that it's fixed, the color tag is now no longer set in the display compound, but it's still set as color
instead of CustomPotionColor
.
I guess the empty effect tag not getting set is completely fine, as in vanilla / single player the give command results in an item without any tags too.
Didn't even realize it was a different property, oops.
The custom potion colors work correctly now, thanks!
This PR will not include entity property stuff initially most likely.
Right now there seems to be no way to check if a certain item can hold certain data nor any validation on setting the data. Is that planned or intentionally not included and if so why not?
The thinking here is that with the ItemMeta system it is possible to instantly know which values can be set on a specific item and which can't which makes it not only easy to work with for beginners but also ensures that non-valid, potentially client-breaking data isn't set.
This is an intentional part of the property system. The system is not intended to be used for beginners. In fact, these keys are not going to be most likely backwards compatible, and will represent the most current internal representation of how items are stored.
ItemMeta will be continued to be offered as a backwards compatible and more beginner friendly API to use instead. This property api allows for more fine tuning, and also allows us to move our meta implementations to not directly use NMS.
Vanilla does not have a source of truth for what item stacks support what NBT tags, so there are no real means for adding validation
Support has been added for inlined armor trims (kinda)
Any news?
This PR is officially blocked by snapshot changes as item components will cause this to be reimplemented. Most likely this PR will be repurposed completely.
Superceded by https://github.com/PaperMC/Paper/pull/10613