add method on ItemStack to edit pdc (#12022)

This commit is contained in:
Jake Potrebic
2025-02-16 11:01:37 -08:00
committed by GitHub
parent 00701267c8
commit 608f004a2c
3 changed files with 51 additions and 8 deletions

View File

@@ -1,16 +1,15 @@
package org.bukkit.inventory;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import io.papermc.paper.registry.RegistryKey;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.function.Consumer;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.Translatable;
import org.bukkit.UndefinedNullability;
import org.bukkit.Utility;
@@ -19,6 +18,7 @@ import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.material.MaterialData;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -64,10 +64,26 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
// Paper end
// Paper start - pdc
/**
* @see #editPersistentDataContainer(Consumer)
*/
@Override
public io.papermc.paper.persistence.@NotNull PersistentDataContainerView getPersistentDataContainer() {
return this.craftDelegate.getPersistentDataContainer();
}
/**
* Edits the {@link PersistentDataContainer} of this stack. The
* {@link PersistentDataContainer} instance is only valid inside the
* consumer.
*
* @param consumer the persistent data container consumer
* @return {@code true} if the edit was successful, {@code false} otherwise. Failure to edit the persistent data
* container may be caused by empty or invalid itemstacks.
*/
public boolean editPersistentDataContainer(@NotNull Consumer<PersistentDataContainer> consumer) {
return this.craftDelegate.editPersistentDataContainer(consumer);
}
// Paper end - pdc
@Utility

View File

@@ -2,10 +2,11 @@ package org.bukkit.craftbukkit.inventory;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import io.papermc.paper.adventure.PaperAdventure;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import io.papermc.paper.adventure.PaperAdventure;
import java.util.function.Consumer;
import net.kyori.adventure.text.Component;
import net.minecraft.advancements.critereon.ItemPredicate;
import net.minecraft.advancements.critereon.MinMaxBounds;
@@ -16,17 +17,21 @@ import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponentPredicate;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.component.PatchedDataComponentMap;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.ItemEnchantments;
import org.bukkit.Material;
import org.bukkit.configuration.serialization.DelegateDeserialization;
import org.bukkit.craftbukkit.enchantments.CraftEnchantment;
import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer;
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.material.MaterialData;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.NotNull;
@DelegateDeserialization(ItemStack.class)
@@ -159,7 +164,6 @@ public final class CraftItemStack extends ItemStack {
}
public net.minecraft.world.item.ItemStack handle;
private boolean isForInventoryDrop;
/**
* Mirror
@@ -522,7 +526,7 @@ public final class CraftItemStack extends ItemStack {
}
// Paper end
// Paper start - pdc
public static final String PDC_CUSTOM_DATA_KEY = "PublicBukkitValues";
private net.minecraft.nbt.CompoundTag getPdcTag() {
if (this.handle == null) {
return new net.minecraft.nbt.CompoundTag();
@@ -530,7 +534,7 @@ public final class CraftItemStack extends ItemStack {
final net.minecraft.world.item.component.CustomData customData = this.handle.getOrDefault(DataComponents.CUSTOM_DATA, net.minecraft.world.item.component.CustomData.EMPTY);
// getUnsafe is OK here because we are only ever *reading* the data so immutability is preserved
//noinspection deprecation
return customData.getUnsafe().getCompound("PublicBukkitValues");
return customData.getUnsafe().getCompound(PDC_CUSTOM_DATA_KEY);
}
private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
@@ -550,7 +554,30 @@ public final class CraftItemStack extends ItemStack {
public io.papermc.paper.persistence.PersistentDataContainerView getPersistentDataContainer() {
return this.pdcView;
}
// Paper end - pdc
@Override
public boolean editPersistentDataContainer(final Consumer<PersistentDataContainer> consumer) {
if (this.handle == null || this.handle.isEmpty()) return false;
final CraftPersistentDataContainer container = new CraftPersistentDataContainer(REGISTRY);
CustomData customData = this.handle.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
//noinspection deprecation // we copy only the pdc tag
final CompoundTag pdcTag = customData.getUnsafe().getCompound(PDC_CUSTOM_DATA_KEY).copy();
container.putAll(pdcTag);
consumer.accept(container);
final CompoundTag newPdcTag = container.toTagCompound();
if (!newPdcTag.isEmpty()) {
customData = customData.update(tag -> tag.put(PDC_CUSTOM_DATA_KEY, newPdcTag));
} else if (newPdcTag.isEmpty() && customData.contains(PDC_CUSTOM_DATA_KEY)) {
customData = customData.update(tag -> tag.remove(PDC_CUSTOM_DATA_KEY));
}
// mirror CraftMetaItem behavior of clearing component if it's empty.
this.handle.set(DataComponents.CUSTOM_DATA, customData.isEmpty() ? null : customData);
return true;
}
// Paper start - data component API
@Override
public <T> T getData(final io.papermc.paper.datacomponent.DataComponentType.Valued<T> type) {

View File

@@ -273,7 +273,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
static final ItemMetaKeyType<Integer> MAX_DAMAGE = new ItemMetaKeyType<>(DataComponents.MAX_DAMAGE, "max-damage");
@Specific(Specific.To.NBT)
static final ItemMetaKeyType<BlockItemStateProperties> BLOCK_DATA = new ItemMetaKeyType<>(DataComponents.BLOCK_STATE, "BlockStateTag");
static final ItemMetaKey BUKKIT_CUSTOM_TAG = new ItemMetaKey("PublicBukkitValues");
static final ItemMetaKey BUKKIT_CUSTOM_TAG = new ItemMetaKey(CraftItemStack.PDC_CUSTOM_DATA_KEY);
@Specific(Specific.To.NBT)
static final ItemMetaKeyType<Unit> HIDE_ADDITIONAL_TOOLTIP = new ItemMetaKeyType(DataComponents.HIDE_ADDITIONAL_TOOLTIP);
@Specific(Specific.To.NBT)