Skip to content

Commit

Permalink
Include only existing states in blockdata meta (Fixes #1350)
Browse files Browse the repository at this point in the history
This is only fixed in 1.20.6 or later. Setting only specified blockdata meta was fixed upstream in 1.21.3.
  • Loading branch information
PseudoKnight committed Dec 16, 2024
1 parent 275ad80 commit a29fee5
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/main/java/com/laytonsmith/abstraction/MCItemMeta.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ public interface MCItemMeta extends AbstractionObject {

MCBlockData getBlockData(MCMaterial material);

Map<String, String> getExistingBlockData();

boolean hasBlockData();

void setBlockData(MCBlockData blockData);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -195,6 +201,20 @@ public MCBlockData getBlockData(MCMaterial material) {
return new BukkitMCBlockData(((BlockDataMeta) this.im).getBlockData((Material) material.getHandle()));
}

@Override
public Map<String, String> getExistingBlockData() {
try {
Class clz = Class.forName(Bukkit.getServer().getClass().getPackage().getName() + ".inventory.CraftMetaItem");
return (Map<String, String>) 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();
Expand Down
27 changes: 24 additions & 3 deletions src/main/java/com/laytonsmith/core/ObjectGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<String, String> 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);
}
Expand Down Expand Up @@ -2510,9 +2522,18 @@ public CArray blockData(MCBlockData blockdata, Target t) {
return ca;
}

public CArray blockData(MCMaterial mat, Map<String, String> blockData, Target t) {
CArray ca = CArray.GetAssociativeArray(t);
ca.set("block", new CString(mat.getName().toLowerCase(Locale.ROOT), t), t);
for(Entry<String, String> 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) {
Expand Down

0 comments on commit a29fee5

Please sign in to comment.