2018-12-15 01:17:27 +00:00
|
|
|
From 1eb74e11de99c6807477c751d4ea094e73556cd4 Mon Sep 17 00:00:00 2001
|
2018-09-23 03:30:54 +00:00
|
|
|
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
|
|
|
Date: Wed, 12 Sep 2018 18:53:55 +0300
|
|
|
|
Subject: [PATCH] Implement an API for CanPlaceOn and CanDestroy NBT values
|
|
|
|
|
|
|
|
|
2018-11-11 08:30:57 +00:00
|
|
|
diff --git a/src/main/java/net/minecraft/server/ArgumentBlock.java b/src/main/java/net/minecraft/server/ArgumentBlock.java
|
|
|
|
index 35c436d19..fcfb17e4e 100644
|
|
|
|
--- a/src/main/java/net/minecraft/server/ArgumentBlock.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/ArgumentBlock.java
|
|
|
|
@@ -42,7 +42,7 @@ public class ArgumentBlock {
|
|
|
|
private final boolean j;
|
|
|
|
private final Map<IBlockState<?>, Comparable<?>> k = Maps.newHashMap();
|
|
|
|
private final Map<String, String> l = Maps.newHashMap();
|
|
|
|
- private MinecraftKey m = new MinecraftKey("");
|
|
|
|
+ private MinecraftKey m = new MinecraftKey(""); public MinecraftKey getBlockKey() { return this.m; } // Paper - OBFHELPER
|
|
|
|
private BlockStateList<Block, IBlockData> n;
|
|
|
|
private IBlockData o;
|
|
|
|
@Nullable
|
|
|
|
@@ -71,11 +71,13 @@ public class ArgumentBlock {
|
|
|
|
return this.p;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ public @Nullable MinecraftKey getTagKey() { return d(); } // Paper - OBFHELPER
|
|
|
|
@Nullable
|
|
|
|
public MinecraftKey d() {
|
|
|
|
return this.q;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ public ArgumentBlock parse(boolean parseTile) throws CommandSyntaxException { return this.a(parseTile); } // Paper - OBFHELPER
|
|
|
|
public ArgumentBlock a(boolean flag) throws CommandSyntaxException {
|
|
|
|
this.s = this::l;
|
|
|
|
if (this.i.canRead() && this.i.peek() == '#') {
|
|
|
|
@@ -135,7 +137,7 @@ public class ArgumentBlock {
|
|
|
|
if (this.q != null && !this.q.getKey().isEmpty()) {
|
|
|
|
Tag tag = TagsBlock.a().a(this.q);
|
|
|
|
if (tag != null) {
|
|
|
|
- for(Block block : tag.a()) {
|
|
|
|
+ for(Block block : (java.util.Collection<Block>) tag.a()) { // Paper - decompiler fix
|
|
|
|
for(IBlockState iblockstate : block.getStates().d()) {
|
|
|
|
if (!this.l.containsKey(iblockstate.a()) && iblockstate.a().startsWith(sx)) {
|
|
|
|
suggestionsbuilder.suggest(iblockstate.a() + '=');
|
|
|
|
@@ -163,7 +165,7 @@ public class ArgumentBlock {
|
|
|
|
if (this.q != null) {
|
|
|
|
Tag tag = TagsBlock.a().a(this.q);
|
|
|
|
if (tag != null) {
|
|
|
|
- for(Block block : tag.a()) {
|
|
|
|
+ for(Block block : (java.util.Collection<Block>) tag.a()) { // Paper - decompiler fix
|
|
|
|
if (block.isTileEntity()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
@@ -198,9 +200,9 @@ public class ArgumentBlock {
|
|
|
|
private static <T extends Comparable<T>> SuggestionsBuilder a(SuggestionsBuilder suggestionsbuilder, IBlockState<T> iblockstate) {
|
|
|
|
for(Comparable comparable : iblockstate.d()) {
|
|
|
|
if (comparable instanceof Integer) {
|
|
|
|
- suggestionsbuilder.suggest(comparable);
|
|
|
|
+ suggestionsbuilder.suggest((Integer) comparable); // Paper - decompiler fix
|
|
|
|
} else {
|
|
|
|
- suggestionsbuilder.suggest(iblockstate.a(comparable));
|
|
|
|
+ suggestionsbuilder.suggest(iblockstate.a((T) comparable)); // Paper - decompiler fix
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -213,7 +215,7 @@ public class ArgumentBlock {
|
|
|
|
Tag tag = TagsBlock.a().a(this.q);
|
|
|
|
if (tag != null) {
|
|
|
|
label40:
|
|
|
|
- for(Block block : tag.a()) {
|
|
|
|
+ for(Block block : (java.util.Collection<Block>) tag.a()) { // Paper - decompiler fix
|
|
|
|
IBlockState iblockstate = block.getStates().a(sx);
|
|
|
|
if (iblockstate != null) {
|
|
|
|
a(suggestionsbuilder, iblockstate);
|
|
|
|
@@ -254,7 +256,7 @@ public class ArgumentBlock {
|
|
|
|
boolean flag = false;
|
|
|
|
boolean flag1 = false;
|
|
|
|
|
|
|
|
- for(Block block : tag.a()) {
|
|
|
|
+ for(Block block : (java.util.Collection<Block>) tag.a()) { // Paper - decompiler fix
|
|
|
|
flag |= !block.getStates().d().isEmpty();
|
|
|
|
flag1 |= block.isTileEntity();
|
|
|
|
if (flag && flag1) {
|
|
|
|
@@ -453,8 +455,8 @@ public class ArgumentBlock {
|
|
|
|
private <T extends Comparable<T>> void a(IBlockState<T> iblockstate, String sx, int ix) throws CommandSyntaxException {
|
|
|
|
Optional optional = iblockstate.b(sx);
|
|
|
|
if (optional.isPresent()) {
|
|
|
|
- this.o = (IBlockData)this.o.set(iblockstate, (Comparable)optional.get());
|
|
|
|
- this.k.put(iblockstate, optional.get());
|
|
|
|
+ this.o = (IBlockData)this.o.set(iblockstate, (T)optional.get()); // Paper - decompiler fix
|
|
|
|
+ this.k.put(iblockstate, (Comparable<?>) optional.get()); // Paper - decompiler fix
|
|
|
|
} else {
|
|
|
|
this.i.setCursor(ix);
|
|
|
|
throw e.createWithContext(this.i, this.m.toString(), iblockstate.a(), sx);
|
|
|
|
@@ -489,7 +491,7 @@ public class ArgumentBlock {
|
|
|
|
private static <T extends Comparable<T>> void a(StringBuilder stringbuilder, IBlockState<T> iblockstate, Comparable<?> comparable) {
|
|
|
|
stringbuilder.append(iblockstate.a());
|
|
|
|
stringbuilder.append('=');
|
|
|
|
- stringbuilder.append(iblockstate.a(comparable));
|
|
|
|
+ stringbuilder.append(iblockstate.a((T) comparable)); // Paper - decompile fix
|
|
|
|
}
|
|
|
|
|
|
|
|
public CompletableFuture<Suggestions> a(SuggestionsBuilder suggestionsbuilder) {
|
2018-09-23 03:30:54 +00:00
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
2018-12-08 10:09:55 +00:00
|
|
|
index 197563552..d34b017f9 100644
|
2018-09-23 03:30:54 +00:00
|
|
|
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
|
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
2018-12-08 10:09:55 +00:00
|
|
|
@@ -81,6 +81,12 @@ import javax.annotation.Nullable;
|
2018-11-11 08:30:57 +00:00
|
|
|
import static org.spigotmc.ValidateUtils.*;
|
|
|
|
// Spigot end
|
|
|
|
|
|
|
|
+// Paper start
|
|
|
|
+import com.destroystokyo.paper.Namespaced;
|
|
|
|
+import com.destroystokyo.paper.NamespacedTag;
|
|
|
|
+import java.util.Collections;
|
|
|
|
+// Paper end
|
|
|
|
+
|
|
|
|
/**
|
|
|
|
* Children must include the following:
|
|
|
|
*
|
2018-12-08 10:09:55 +00:00
|
|
|
@@ -256,6 +262,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable {
|
2018-09-23 03:30:54 +00:00
|
|
|
@Specific(Specific.To.NBT)
|
|
|
|
static final ItemMetaKey DAMAGE = new ItemMetaKey("Damage");
|
2018-12-08 10:09:55 +00:00
|
|
|
static final ItemMetaKey BUKKIT_CUSTOM_TAG = new ItemMetaKey("PublicBukkitValues");
|
2018-09-23 03:30:54 +00:00
|
|
|
+ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values
|
|
|
|
+ static final ItemMetaKey CAN_DESTROY = new ItemMetaKey("CanDestroy");
|
|
|
|
+ static final ItemMetaKey CAN_PLACE_ON = new ItemMetaKey("CanPlaceOn");
|
|
|
|
+ // Paper end
|
|
|
|
|
|
|
|
private IChatBaseComponent displayName;
|
|
|
|
private IChatBaseComponent locName;
|
2018-12-08 10:09:55 +00:00
|
|
|
@@ -266,6 +276,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable {
|
2018-09-23 03:30:54 +00:00
|
|
|
private int hideFlag;
|
|
|
|
private boolean unbreakable;
|
|
|
|
private int damage;
|
|
|
|
+ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values
|
2018-11-11 08:30:57 +00:00
|
|
|
+ private Set<Namespaced> placeableKeys;
|
|
|
|
+ private Set<Namespaced> destroyableKeys;
|
2018-09-23 03:30:54 +00:00
|
|
|
+ // Paper end
|
|
|
|
|
|
|
|
private static final Set<String> HANDLED_TAGS = Sets.newHashSet();
|
2018-12-08 10:09:55 +00:00
|
|
|
private static final CraftCustomTagTypeRegistry TAG_TYPE_REGISTRY = new CraftCustomTagTypeRegistry();
|
|
|
|
@@ -298,6 +312,15 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable {
|
2018-09-23 03:30:54 +00:00
|
|
|
this.hideFlag = meta.hideFlag;
|
|
|
|
this.unbreakable = meta.unbreakable;
|
|
|
|
this.damage = meta.damage;
|
|
|
|
+ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values
|
2018-11-11 08:30:57 +00:00
|
|
|
+ if (meta.hasPlaceableKeys()) {
|
|
|
|
+ this.placeableKeys = new java.util.HashSet<>(meta.placeableKeys);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (meta.hasDestroyableKeys()) {
|
|
|
|
+ this.destroyableKeys = new java.util.HashSet<>(meta.destroyableKeys);
|
|
|
|
+ }
|
2018-09-23 03:30:54 +00:00
|
|
|
+ // Paper end
|
|
|
|
this.unhandledTags.putAll(meta.unhandledTags);
|
2018-12-08 10:09:55 +00:00
|
|
|
this.publicItemTagContainer.putAll(meta.publicItemTagContainer.getRaw());
|
2018-09-23 03:30:54 +00:00
|
|
|
|
2018-12-08 10:09:55 +00:00
|
|
|
@@ -361,6 +384,33 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable {
|
|
|
|
publicItemTagContainer.put(key, compound.get(key));
|
|
|
|
}
|
2018-09-23 03:30:54 +00:00
|
|
|
}
|
|
|
|
+ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values
|
|
|
|
+ if (tag.hasKey(CAN_DESTROY.NBT)) {
|
2018-11-11 08:30:57 +00:00
|
|
|
+ this.destroyableKeys = Sets.newHashSet();
|
2018-09-23 03:30:54 +00:00
|
|
|
+ NBTTagList list = tag.getList(CAN_DESTROY.NBT, CraftMagicNumbers.NBT.TAG_STRING);
|
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
2018-11-11 08:30:57 +00:00
|
|
|
+ Namespaced namespaced = this.deserializeNamespaced(list.getString(i));
|
|
|
|
+ if (namespaced == null) {
|
2018-10-03 02:53:27 +00:00
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
2018-11-11 08:30:57 +00:00
|
|
|
+ this.destroyableKeys.add(namespaced);
|
2018-09-23 03:30:54 +00:00
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (tag.hasKey(CAN_PLACE_ON.NBT)) {
|
2018-11-11 08:30:57 +00:00
|
|
|
+ this.placeableKeys = Sets.newHashSet();
|
2018-09-23 03:30:54 +00:00
|
|
|
+ NBTTagList list = tag.getList(CAN_PLACE_ON.NBT, CraftMagicNumbers.NBT.TAG_STRING);
|
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
2018-11-11 08:30:57 +00:00
|
|
|
+ Namespaced namespaced = this.deserializeNamespaced(list.getString(i));
|
|
|
|
+ if (namespaced == null) {
|
2018-10-03 02:53:27 +00:00
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
2018-11-11 08:30:57 +00:00
|
|
|
+ this.placeableKeys.add(namespaced);
|
2018-09-23 03:30:54 +00:00
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // Paper end
|
|
|
|
|
|
|
|
Set<String> keys = tag.getKeys();
|
|
|
|
for (String key : keys) {
|
2018-12-08 10:09:55 +00:00
|
|
|
@@ -482,6 +532,36 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable {
|
2018-11-11 08:30:57 +00:00
|
|
|
setDamage(damage);
|
|
|
|
}
|
|
|
|
|
|
|
|
+ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values
|
|
|
|
+ Iterable<?> canPlaceOnSerialized = SerializableMeta.getObject(Iterable.class, map, CAN_PLACE_ON.BUKKIT, true);
|
|
|
|
+ if (canPlaceOnSerialized != null) {
|
|
|
|
+ this.placeableKeys = Sets.newHashSet();
|
|
|
|
+ for (Object canPlaceOnElement : canPlaceOnSerialized) {
|
|
|
|
+ String canPlaceOnRaw = (String) canPlaceOnElement;
|
|
|
|
+ Namespaced value = this.deserializeNamespaced(canPlaceOnRaw);
|
|
|
|
+ if (value == null) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.placeableKeys.add(value);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Iterable<?> canDestroySerialized = SerializableMeta.getObject(Iterable.class, map, CAN_DESTROY.BUKKIT, true);
|
|
|
|
+ if (canDestroySerialized != null) {
|
|
|
|
+ this.destroyableKeys = Sets.newHashSet();
|
|
|
|
+ for (Object canDestroyElement : canDestroySerialized) {
|
|
|
|
+ String canDestroyRaw = (String) canDestroyElement;
|
|
|
|
+ Namespaced value = this.deserializeNamespaced(canDestroyRaw);
|
|
|
|
+ if (value == null) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.destroyableKeys.add(value);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // Paper end
|
|
|
|
+
|
|
|
|
String internal = SerializableMeta.getString(map, "internal", true);
|
|
|
|
if (internal != null) {
|
|
|
|
ByteArrayInputStream buf = new ByteArrayInputStream(Base64.decodeBase64(internal));
|
2018-12-08 10:09:55 +00:00
|
|
|
@@ -598,6 +678,23 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable {
|
2018-09-23 03:30:54 +00:00
|
|
|
if (hasDamage()) {
|
|
|
|
itemTag.setInt(DAMAGE.NBT, damage);
|
|
|
|
}
|
|
|
|
+ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values
|
2018-11-11 08:30:57 +00:00
|
|
|
+ if (hasPlaceableKeys()) {
|
|
|
|
+ List<String> items = this.placeableKeys.stream()
|
|
|
|
+ .map(this::serializeNamespaced)
|
2018-09-23 03:30:54 +00:00
|
|
|
+ .collect(java.util.stream.Collectors.toList());
|
|
|
|
+
|
|
|
|
+ itemTag.set(CAN_PLACE_ON.NBT, createStringList(items));
|
|
|
|
+ }
|
|
|
|
+
|
2018-11-11 08:30:57 +00:00
|
|
|
+ if (hasDestroyableKeys()) {
|
|
|
|
+ List<String> items = this.destroyableKeys.stream()
|
|
|
|
+ .map(this::serializeNamespaced)
|
2018-09-23 03:30:54 +00:00
|
|
|
+ .collect(java.util.stream.Collectors.toList());
|
|
|
|
+
|
|
|
|
+ itemTag.set(CAN_DESTROY.NBT, createStringList(items));
|
|
|
|
+ }
|
|
|
|
+ // Paper end
|
|
|
|
|
|
|
|
for (Map.Entry<String, NBTBase> e : unhandledTags.entrySet()) {
|
|
|
|
itemTag.set(e.getKey(), e.getValue());
|
2018-12-08 10:09:55 +00:00
|
|
|
@@ -696,7 +793,8 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable {
|
2018-11-11 08:30:57 +00:00
|
|
|
|
|
|
|
@Overridden
|
|
|
|
boolean isEmpty() {
|
2018-12-08 10:09:55 +00:00
|
|
|
- return !(hasDisplayName() || hasLocalizedName() || hasEnchants() || hasLore() || hasRepairCost() || !unhandledTags.isEmpty() || !publicItemTagContainer.isEmpty() || hideFlag != 0 || isUnbreakable() || hasDamage() || hasAttributeModifiers());
|
|
|
|
+ return !(hasDisplayName() || hasLocalizedName() || hasEnchants() || hasLore() || hasRepairCost() || !unhandledTags.isEmpty() || !publicItemTagContainer.isEmpty() || hideFlag != 0 || isUnbreakable() || hasDamage() || hasAttributeModifiers()
|
2018-11-11 08:30:57 +00:00
|
|
|
+ || hasPlaceableKeys() || hasDestroyableKeys()); // Paper - Implement an API for CanPlaceOn and CanDestroy NBT values
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getDisplayName() {
|
2018-12-08 10:09:55 +00:00
|
|
|
@@ -1038,7 +1136,11 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable {
|
|
|
|
&& (this.publicItemTagContainer.equals(that.publicItemTagContainer))
|
2018-11-11 08:30:57 +00:00
|
|
|
&& (this.hideFlag == that.hideFlag)
|
|
|
|
&& (this.isUnbreakable() == that.isUnbreakable())
|
|
|
|
- && (this.hasDamage() ? that.hasDamage() && this.damage == that.damage : !that.hasDamage());
|
|
|
|
+ && (this.hasDamage() ? that.hasDamage() && this.damage == that.damage : !that.hasDamage())
|
|
|
|
+ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values
|
|
|
|
+ && (this.hasPlaceableKeys() ? that.hasPlaceableKeys() && this.placeableKeys.equals(that.placeableKeys) : !that.hasPlaceableKeys())
|
|
|
|
+ && (this.hasDestroyableKeys() ? that.hasDestroyableKeys() && this.destroyableKeys.equals(that.destroyableKeys) : !that.hasDestroyableKeys());
|
|
|
|
+ // Paper end
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-12-08 10:09:55 +00:00
|
|
|
@@ -1070,6 +1172,10 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable {
|
2018-11-11 08:30:57 +00:00
|
|
|
hash = 61 * hash + (isUnbreakable() ? 1231 : 1237);
|
|
|
|
hash = 61 * hash + (hasDamage() ? this.damage : 0);
|
|
|
|
hash = 61 * hash + (hasAttributeModifiers() ? this.attributeModifiers.hashCode() : 0);
|
|
|
|
+ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values
|
|
|
|
+ hash = 61 * hash + (hasPlaceableKeys() ? this.placeableKeys.hashCode() : 0);
|
|
|
|
+ hash = 61 * hash + (hasDestroyableKeys() ? this.destroyableKeys.hashCode() : 0);
|
|
|
|
+ // Paper end
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
2018-12-08 10:09:55 +00:00
|
|
|
@@ -1090,6 +1196,15 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable {
|
2018-11-11 08:30:57 +00:00
|
|
|
clone.hideFlag = this.hideFlag;
|
|
|
|
clone.unbreakable = this.unbreakable;
|
|
|
|
clone.damage = this.damage;
|
|
|
|
+ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values
|
|
|
|
+ if (this.placeableKeys != null) {
|
|
|
|
+ clone.placeableKeys = Sets.newHashSet(this.placeableKeys);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.destroyableKeys != null) {
|
|
|
|
+ clone.destroyableKeys = Sets.newHashSet(this.destroyableKeys);
|
|
|
|
+ }
|
|
|
|
+ // Paper end
|
|
|
|
return clone;
|
|
|
|
} catch (CloneNotSupportedException e) {
|
|
|
|
throw new Error(e);
|
2018-12-08 10:09:55 +00:00
|
|
|
@@ -1139,6 +1254,24 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable {
|
2018-11-11 08:30:57 +00:00
|
|
|
builder.put(DAMAGE.BUKKIT, damage);
|
|
|
|
}
|
|
|
|
|
|
|
|
+ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values
|
|
|
|
+ if (hasPlaceableKeys()) {
|
|
|
|
+ List<String> cerealPlaceable = this.placeableKeys.stream()
|
|
|
|
+ .map(this::serializeNamespaced)
|
|
|
|
+ .collect(java.util.stream.Collectors.toList());
|
|
|
|
+
|
|
|
|
+ builder.put(CAN_PLACE_ON.BUKKIT, cerealPlaceable);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (hasDestroyableKeys()) {
|
|
|
|
+ List<String> cerealDestroyable = this.destroyableKeys.stream()
|
|
|
|
+ .map(this::serializeNamespaced)
|
|
|
|
+ .collect(java.util.stream.Collectors.toList());
|
|
|
|
+
|
|
|
|
+ builder.put(CAN_DESTROY.BUKKIT, cerealDestroyable);
|
|
|
|
+ }
|
|
|
|
+ // Paper end
|
|
|
|
+
|
|
|
|
final Map<String, NBTBase> internalTags = new HashMap<String, NBTBase>(unhandledTags);
|
|
|
|
serializeInternal(internalTags);
|
|
|
|
if (!internalTags.isEmpty()) {
|
2018-12-08 10:09:55 +00:00
|
|
|
@@ -1288,7 +1421,9 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable {
|
2018-09-23 03:30:54 +00:00
|
|
|
CraftMetaArmorStand.NO_BASE_PLATE.NBT,
|
|
|
|
CraftMetaArmorStand.SHOW_ARMS.NBT,
|
|
|
|
CraftMetaArmorStand.SMALL.NBT,
|
|
|
|
- CraftMetaArmorStand.MARKER.NBT
|
|
|
|
+ CraftMetaArmorStand.MARKER.NBT,
|
|
|
|
+ CAN_DESTROY.NBT,
|
|
|
|
+ CAN_PLACE_ON.NBT
|
|
|
|
// Paper end
|
|
|
|
));
|
|
|
|
}
|
2018-12-08 10:09:55 +00:00
|
|
|
@@ -1335,4 +1470,147 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable {
|
2018-09-23 03:30:54 +00:00
|
|
|
return spigot;
|
|
|
|
}
|
|
|
|
// Spigot end
|
|
|
|
+ // Paper start - Implement an API for CanPlaceOn and CanDestroy NBT values
|
|
|
|
+ @Override
|
2018-11-11 08:30:57 +00:00
|
|
|
+ @SuppressWarnings("deprecation")
|
2018-09-23 03:30:54 +00:00
|
|
|
+ public Set<Material> getCanDestroy() {
|
2018-11-11 08:30:57 +00:00
|
|
|
+ return this.destroyableKeys == null ? Collections.emptySet() : legacyGetMatsFromKeys(this.destroyableKeys);
|
2018-09-23 03:30:54 +00:00
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ @SuppressWarnings("deprecation")
|
|
|
|
+ public void setCanDestroy(Set<Material> canDestroy) {
|
2018-11-11 08:30:57 +00:00
|
|
|
+ Validate.notNull(canDestroy, "Cannot replace with null set!");
|
|
|
|
+ legacyClearAndReplaceKeys(this.destroyableKeys, canDestroy);
|
2018-09-23 03:30:54 +00:00
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
2018-11-11 08:30:57 +00:00
|
|
|
+ @SuppressWarnings("deprecation")
|
2018-09-23 03:30:54 +00:00
|
|
|
+ public Set<Material> getCanPlaceOn() {
|
2018-11-11 08:30:57 +00:00
|
|
|
+ return this.placeableKeys == null ? Collections.emptySet() : legacyGetMatsFromKeys(this.placeableKeys);
|
2018-09-23 03:30:54 +00:00
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ @SuppressWarnings("deprecation")
|
|
|
|
+ public void setCanPlaceOn(Set<Material> canPlaceOn) {
|
2018-11-11 08:30:57 +00:00
|
|
|
+ Validate.notNull(canPlaceOn, "Cannot replace with null set!");
|
|
|
|
+ legacyClearAndReplaceKeys(this.placeableKeys, canPlaceOn);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public Set<Namespaced> getDestroyableKeys() {
|
|
|
|
+ return this.destroyableKeys == null ? Collections.emptySet() : Sets.newHashSet(this.destroyableKeys);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void setDestroyableKeys(Collection<Namespaced> canDestroy) {
|
|
|
|
+ Validate.notNull(canDestroy, "Cannot replace with null collection!");
|
|
|
|
+ Validate.isTrue(ofAcceptableType(canDestroy), "Can only use NamespacedKey or NamespacedTag objects!");
|
|
|
|
+ this.destroyableKeys.clear();
|
|
|
|
+ this.destroyableKeys.addAll(canDestroy);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public Set<Namespaced> getPlaceableKeys() {
|
|
|
|
+ return this.placeableKeys == null ? Collections.emptySet() : Sets.newHashSet(this.placeableKeys);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void setPlaceableKeys(Collection<Namespaced> canPlaceOn) {
|
|
|
|
+ Validate.notNull(canPlaceOn, "Cannot replace with null collection!");
|
|
|
|
+ Validate.isTrue(ofAcceptableType(canPlaceOn), "Can only use NamespacedKey or NamespacedTag objects!");
|
|
|
|
+ this.placeableKeys.clear();
|
|
|
|
+ this.placeableKeys.addAll(canPlaceOn);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public boolean hasPlaceableKeys() {
|
|
|
|
+ return this.placeableKeys != null && !this.placeableKeys.isEmpty();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public boolean hasDestroyableKeys() {
|
|
|
|
+ return this.destroyableKeys != null && !this.destroyableKeys.isEmpty();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Deprecated
|
|
|
|
+ private void legacyClearAndReplaceKeys(Collection<Namespaced> toUpdate, Collection<Material> beingSet) {
|
|
|
|
+ if (beingSet.stream().anyMatch(Material::isLegacy)) {
|
|
|
|
+ throw new IllegalArgumentException("Set must not contain any legacy materials!");
|
2018-09-23 03:30:54 +00:00
|
|
|
+ }
|
2018-11-11 08:30:57 +00:00
|
|
|
+
|
|
|
|
+ toUpdate.clear();
|
|
|
|
+ toUpdate.addAll(beingSet.stream().map(Material::getKey).collect(java.util.stream.Collectors.toSet()));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Deprecated
|
|
|
|
+ private Set<Material> legacyGetMatsFromKeys(Collection<Namespaced> names) {
|
|
|
|
+ Set<Material> mats = Sets.newHashSet();
|
|
|
|
+ for (Namespaced key : names) {
|
|
|
|
+ if (!(key instanceof org.bukkit.NamespacedKey)) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Material material = Material.matchMaterial(key.toString(), false);
|
|
|
|
+ if (material != null) {
|
|
|
|
+ mats.add(material);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return mats;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private @Nullable Namespaced deserializeNamespaced(String raw) {
|
|
|
|
+ boolean isTag = raw.codePointAt(0) == '#';
|
|
|
|
+ net.minecraft.server.ArgumentBlock blockParser = new net.minecraft.server.ArgumentBlock(new com.mojang.brigadier.StringReader(raw), true);
|
|
|
|
+ try {
|
|
|
|
+ blockParser = blockParser.parse(false);
|
|
|
|
+ } catch (com.mojang.brigadier.exceptions.CommandSyntaxException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ net.minecraft.server.MinecraftKey key;
|
|
|
|
+ if (isTag) {
|
|
|
|
+ key = blockParser.getTagKey();
|
|
|
|
+ } else {
|
|
|
|
+ key = blockParser.getBlockKey();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (key == null) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // don't DC the player if something slips through somehow
|
|
|
|
+ Namespaced resource = null;
|
|
|
|
+ try {
|
|
|
|
+ if (isTag) {
|
|
|
|
+ resource = new NamespacedTag(key.b(), key.getKey());
|
|
|
|
+ } else {
|
|
|
|
+ resource = CraftNamespacedKey.fromMinecraft(key);
|
|
|
|
+ }
|
|
|
|
+ } catch (IllegalArgumentException ex) {
|
|
|
|
+ org.bukkit.Bukkit.getLogger().warning("Namespaced resource does not validate: " + key.toString());
|
|
|
|
+ ex.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return resource;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private @Nonnull String serializeNamespaced(Namespaced resource) {
|
|
|
|
+ return resource.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // not a fan of this
|
|
|
|
+ private boolean ofAcceptableType(Collection<Namespaced> namespacedResources) {
|
|
|
|
+ boolean valid = true;
|
|
|
|
+ for (Namespaced resource : namespacedResources) {
|
|
|
|
+ if (valid && !(resource instanceof org.bukkit.NamespacedKey || resource instanceof com.destroystokyo.paper.NamespacedTag)) {
|
|
|
|
+ valid = false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return valid;
|
2018-09-23 03:30:54 +00:00
|
|
|
+ }
|
|
|
|
+ // Paper end
|
|
|
|
}
|
|
|
|
--
|
2018-12-15 01:17:27 +00:00
|
|
|
2.20.0
|
2018-09-23 03:30:54 +00:00
|
|
|
|