PaperMC/patches/server/1037-Add-API-for-CanPlaceOn-and-CanDestroy-NBT-values.patch

156 lines
7.8 KiB
Diff
Raw Normal View History

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 12 Sep 2018 18:53:55 +0300
Subject: [PATCH] Add API for CanPlaceOn and CanDestroy NBT values
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
Updated Upstream (Bukkit/CraftBukkit/Spigot) (#11405) Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 1fc1020a PR-1049: Add MenuType API 8ae2e3be PR-1055: Expand riptiding API cac68bfb SPIGOT-7890: AttributeModifier#getUniqueId() doesn't match the UUID passed to its constructor 7004fcf2 SPIGOT-7886: Fix mistake in AttributeModifier UUID shim 1ac7f950 PR-1054: Add FireworkMeta#hasPower 4cfb565f SPIGOT-7873: Add powered state for skulls CraftBukkit Changes: bbb30e7a8 SPIGOT-7894: NPE when sending tile entity update ba21e9472 SPIGOT-7895: PlayerItemBreakEvent not firing 0fb24bbe0 SPIGOT-7875: Fix PlayerItemConsumeEvent cancellation causing client-side desync 815066449 SPIGOT-7891: Can't remove second ingredient of MerchantRecipe 45c206f2c PR-1458: Add MenuType API 19c8ef9ae SPIGOT-7867: Merchant instanceof AbstractVillager always returns false 4e006d28f PR-1468: Expand riptiding API bd8aded7d Ignore checks in CraftPlayerProfile for ResolvableProfile used in profile components 8679620b5 SPIGOT-7889: Fix tool component deserialisation without speed and/or correct-for-drops 8d5222691 SPIGOT-7882, PR-1467: Fix conversion of name in Profile Component to empty if it is missing 63f91669a SPIGOT-7887: Remove duplicate ProjectileHitEvent for fireballs 7070de8c8 SPIGOT-7878: Server#getLootTable does not return null on invalid loot table 060ee6cae SPIGOT-7876: Can't kick player or disconnect player in PlayerLoginEvent when checking for cookies 7ccb86cc0 PR-1465: Add FireworkMeta#hasPower 804ad6491 SPIGOT-7873: Add powered state for skulls f9610cdcb Improve minecart movement Spigot Changes: a759b629 Rebuild patches Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
2024-09-15 21:39:53 +02:00
index 042bfdd14c9ff4cc8ed3421f73565f0f03b11bcb..e0414b0a48a95f1f5e718070dd0e5f955052a898 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
@@ -2183,4 +2183,117 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
}
// Paper end
+ // Paper start - Add an API for can-place-on/can-break adventure mode predicates
+ @Override
+ public Set<Material> getCanDestroy() {
+ return !this.hasDestroyableKeys() ? Collections.emptySet() : convertToLegacyMaterial(this.canBreakPredicates);
+ }
+
+ @Override
+ public void setCanDestroy(final Set<Material> canDestroy) {
+ Preconditions.checkArgument(canDestroy != null, "Cannot replace with null set!");
+ this.canBreakPredicates = convertFromLegacyMaterial(canDestroy);
+ }
+
+ @Override
+ public Set<Material> getCanPlaceOn() {
+ return !this.hasPlaceableKeys() ? Collections.emptySet() : convertToLegacyMaterial(this.canPlaceOnPredicates);
+ }
+
+ @Override
+ public void setCanPlaceOn(final Set<Material> canPlaceOn) {
+ Preconditions.checkArgument(canPlaceOn != null, "Cannot replace with null set!");
+ this.canPlaceOnPredicates = convertFromLegacyMaterial(canPlaceOn);
+ }
+
+ private static List<net.minecraft.advancements.critereon.BlockPredicate> convertFromLegacyMaterial(final Collection<Material> materials) {
+ return materials.stream().map(m -> {
+ return net.minecraft.advancements.critereon.BlockPredicate.Builder.block().of(CraftBlockType.bukkitToMinecraft(m)).build();
+ }).toList();
+ }
+
+ private static Set<Material> convertToLegacyMaterial(final List<net.minecraft.advancements.critereon.BlockPredicate> predicates) {
+ return predicates.stream()
+ .flatMap(p -> p.blocks().map(net.minecraft.core.HolderSet::stream).orElse(java.util.stream.Stream.empty()))
+ .map(holder -> CraftBlockType.minecraftToBukkit(holder.value()))
+ .collect(java.util.stream.Collectors.toSet());
+ }
+
+ @Override
+ public Set<com.destroystokyo.paper.Namespaced> getDestroyableKeys() {
+ return !this.hasDestroyableKeys() ? Collections.emptySet() : convertToLegacyNamespaced(this.canBreakPredicates);
+ }
+
+ @Override
+ public void setDestroyableKeys(final Collection<com.destroystokyo.paper.Namespaced> canDestroy) {
+ Preconditions.checkArgument(canDestroy != null, "Cannot replace with null collection!");
+ Preconditions.checkArgument(ofAcceptableType(canDestroy), "Can only use NamespacedKey or NamespacedTag objects!");
+ this.canBreakPredicates = convertFromLegacyNamespaced(canDestroy);
+ }
+
+ @Override
+ public Set<com.destroystokyo.paper.Namespaced> getPlaceableKeys() {
+ return !this.hasPlaceableKeys() ? Collections.emptySet() : convertToLegacyNamespaced(this.canPlaceOnPredicates);
+ }
+
+ @Override
+ public void setPlaceableKeys(final Collection<com.destroystokyo.paper.Namespaced> canPlaceOn) {
+ Preconditions.checkArgument(canPlaceOn != null, "Cannot replace with null collection!");
+ Preconditions.checkArgument(ofAcceptableType(canPlaceOn), "Can only use NamespacedKey or NamespacedTag objects!");
+ this.canPlaceOnPredicates = convertFromLegacyNamespaced(canPlaceOn);
+ }
+
+ private static List<net.minecraft.advancements.critereon.BlockPredicate> convertFromLegacyNamespaced(final Collection<com.destroystokyo.paper.Namespaced> namespaceds) {
+ final List<net.minecraft.advancements.critereon.BlockPredicate> predicates = new ArrayList<>();
+ for (final com.destroystokyo.paper.Namespaced namespaced : namespaceds) {
+ if (namespaced instanceof final org.bukkit.NamespacedKey key) {
+ predicates.add(net.minecraft.advancements.critereon.BlockPredicate.Builder.block().of(CraftBlockType.bukkitToMinecraft(Objects.requireNonNull(org.bukkit.Registry.MATERIAL.get(key)))).build());
+ } else if (namespaced instanceof final com.destroystokyo.paper.NamespacedTag tag) {
+ predicates.add(net.minecraft.advancements.critereon.BlockPredicate.Builder.block().of(net.minecraft.tags.TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath(tag.getNamespace(), tag.getKey()))).build());
+ }
+ }
+ return predicates;
+ }
+
+ private static Set<com.destroystokyo.paper.Namespaced> convertToLegacyNamespaced(final Collection<net.minecraft.advancements.critereon.BlockPredicate> predicates) {
+ final Set<com.destroystokyo.paper.Namespaced> namespaceds = Sets.newHashSet();
+ for (final net.minecraft.advancements.critereon.BlockPredicate predicate : predicates) {
+ if (predicate.blocks().isEmpty()) {
+ continue;
+ }
+ final net.minecraft.core.HolderSet<net.minecraft.world.level.block.Block> holders = predicate.blocks().get();
+ if (holders instanceof final net.minecraft.core.HolderSet.Named<net.minecraft.world.level.block.Block> named) {
+ namespaceds.add(new com.destroystokyo.paper.NamespacedTag(named.key().location().getNamespace(), named.key().location().getPath()));
+ } else {
+ holders.forEach(h -> {
+ h.unwrapKey().ifPresent(key -> {
+ namespaceds.add(new org.bukkit.NamespacedKey(key.location().getNamespace(), key.location().getPath()));
+ });
+ });
+ }
+ }
+ return namespaceds;
+ }
+
+ @Override
+ public boolean hasPlaceableKeys() {
+ return this.canPlaceOnPredicates != null;
+ }
+
+ @Override
+ public boolean hasDestroyableKeys() {
+ return this.canBreakPredicates != null;
+ }
+
+ // not a fan of this
+ private static boolean ofAcceptableType(final Collection<com.destroystokyo.paper.Namespaced> namespacedResources) {
+ for (com.destroystokyo.paper.Namespaced resource : namespacedResources) {
+ if (!(resource instanceof org.bukkit.NamespacedKey || resource instanceof com.destroystokyo.paper.NamespacedTag)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ // Paper end - Add an API for can-place-on/can-break adventure mode predicates
}
diff --git a/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java b/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java
index 6930d0afb230a88aa813b02e4d55c95d3a049688..db8d8e2a07296d62c3097f02b03319e2e1ba9394 100644
--- a/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java
+++ b/src/main/java/org/bukkit/craftbukkit/legacy/MaterialRerouting.java
@@ -690,4 +690,22 @@ public class MaterialRerouting {
return ItemStack.of(material, amount);
}
// Paper end
+
+ // Paper start - methods added post 1.13, no-op (https://github.com/PaperMC/Paper/pull/1015)
+ public static Set<Material> getCanDestroy(final ItemMeta meta) {
+ return meta.getCanDestroy();
+ }
+
+ public static void setCanDestroy(final ItemMeta meta, final Set<Material> materials) {
+ meta.setCanDestroy(materials);
+ }
+
+ public static Set<Material> getCanPlaceOn(final ItemMeta meta) {
+ return meta.getCanPlaceOn();
+ }
+
+ public static void setCanPlaceOn(final ItemMeta meta, final Set<Material> materials) {
+ meta.setCanPlaceOn(materials);
+ }
+ // Paper end
}