diff --git a/src/main/java/com/laytonsmith/abstraction/MCItemMeta.java b/src/main/java/com/laytonsmith/abstraction/MCItemMeta.java index 913a97cda..f84c844de 100644 --- a/src/main/java/com/laytonsmith/abstraction/MCItemMeta.java +++ b/src/main/java/com/laytonsmith/abstraction/MCItemMeta.java @@ -122,6 +122,8 @@ public interface MCItemMeta extends AbstractionObject { MCBlockData getBlockData(MCMaterial material); + Map getExistingBlockData(); + boolean hasBlockData(); void setBlockData(MCBlockData blockData); diff --git a/src/main/java/com/laytonsmith/abstraction/bukkit/BukkitMCItemMeta.java b/src/main/java/com/laytonsmith/abstraction/bukkit/BukkitMCItemMeta.java index aab6389d9..3a4f053a5 100644 --- a/src/main/java/com/laytonsmith/abstraction/bukkit/BukkitMCItemMeta.java +++ b/src/main/java/com/laytonsmith/abstraction/bukkit/BukkitMCItemMeta.java @@ -2,6 +2,8 @@ import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; +import com.laytonsmith.PureUtilities.Common.ReflectionUtils; +import com.laytonsmith.PureUtilities.Common.ReflectionUtils.ReflectionException; import com.laytonsmith.abstraction.AbstractionObject; import com.laytonsmith.abstraction.MCAttributeModifier; import com.laytonsmith.abstraction.MCItemMeta; @@ -22,6 +24,10 @@ import com.laytonsmith.abstraction.enums.bukkit.BukkitMCEnchantment; import com.laytonsmith.abstraction.enums.bukkit.BukkitMCItemFlag; +import com.laytonsmith.core.MSLog; +import com.laytonsmith.core.MSLog.Tags; +import com.laytonsmith.core.constructs.Target; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeModifier; @@ -195,6 +201,20 @@ public MCBlockData getBlockData(MCMaterial material) { return new BukkitMCBlockData(((BlockDataMeta) this.im).getBlockData((Material) material.getHandle())); } + @Override + public Map getExistingBlockData() { + try { + Class clz = Class.forName(Bukkit.getServer().getClass().getPackage().getName() + ".inventory.CraftMetaItem"); + return (Map) ReflectionUtils.get(clz, this.im, "blockData"); + } catch (ClassNotFoundException e) { + MSLog.GetLogger().e(Tags.GENERAL, "Failed to get CraftMetaItem class.", Target.UNKNOWN); + return null; + } catch (ReflectionException ex) { + MSLog.GetLogger().e(Tags.GENERAL, "Failed to get blockData from CraftMetaItem.", Target.UNKNOWN); + return null; + } + } + @Override public boolean hasBlockData() { return ((BlockDataMeta) this.im).hasBlockData(); diff --git a/src/main/java/com/laytonsmith/core/ObjectGenerator.java b/src/main/java/com/laytonsmith/core/ObjectGenerator.java index 36c42803a..2b319a4e5 100644 --- a/src/main/java/com/laytonsmith/core/ObjectGenerator.java +++ b/src/main/java/com/laytonsmith/core/ObjectGenerator.java @@ -105,7 +105,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; +import java.util.Map.Entry; import java.util.Random; import java.util.Set; import java.util.UUID; @@ -490,7 +492,17 @@ public Construct itemMeta(MCItemStack is, Target t) { } else if(material.isBlock()) { // Block items only if(meta.hasBlockData()) { - ma.set("blockdata", blockData(meta.getBlockData(is.getType()), t), t); + if(Static.getServer().getMinecraftVersion().gte(MCVersion.MC1_20_6)) { + // return only existing states + Map blockData = meta.getExistingBlockData(); + if(blockData != null) { + ma.set("blockdata", blockData(is.getType(), blockData, t), t); + } else { + ma.set("blockdata", CNull.NULL, t); + } + } else { + ma.set("blockdata", blockData(meta.getBlockData(is.getType()), t), t); + } } else { ma.set("blockdata", CNull.NULL, t); } @@ -2510,9 +2522,18 @@ public CArray blockData(MCBlockData blockdata, Target t) { return ca; } + public CArray blockData(MCMaterial mat, Map blockData, Target t) { + CArray ca = CArray.GetAssociativeArray(t); + ca.set("block", new CString(mat.getName().toLowerCase(Locale.ROOT), t), t); + for(Entry entry : blockData.entrySet()) { + ca.set(entry.getKey(), blockState(entry.getValue()), t); + } + return ca; + } + private Construct blockState(String value) { - if(value.length() < 3 && Character.isDigit(value.charAt(0))) { - // integer states range from 0-25 + int ch = value.charAt(0); + if(ch >= '0' && ch <= '9') { try { return new CInt(Long.parseLong(value), Target.UNKNOWN); } catch (NumberFormatException e) {