Skip to content

Commit f8fa3ba

Browse files
committed
Fixes some edge-cases in the NBT and RawText APIs.
[NBT] * NEW: NBTCompound and NBTList: toString() now returns the NBT/JSON representation of the tag. * NEW: When putting a container tag into another, values are now properly linked rather than copied over. * BUG: The NBT API can now handle null CraftItemStack values (i.e. invalid item types). * BUG: NBTCompound and NBTList: Fixed parent tags management. [ITEM UTILITIES] * NEW: ItemBuilder.craftItem() is a new methods that returns the built item as a CraftBukkit CraftItemStack instead of the standard Bukkit ItemStack, allowing to assign NBT data directly on it. * BUG: ItemUtilities can now handle null CraftItemStack values (i.e. invalid item types). [RAW TEXT] * BUG: Fixed fallback mechanisms for item ids. [WORLD UTILITIES] * NEW: WorldUtils.get4thOrientation() is a new method that returns the blockFace orientation associated to a specified Location's yaw value.
1 parent 528a22a commit f8fa3ba

File tree

9 files changed

+123
-10
lines changed

9 files changed

+123
-10
lines changed

src/main/java/fr/zcraft/zlib/components/attributes/Attribute.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ public final void setUUID(UUID uuid)
155155

156156
/**
157157
* Returns the Minecraft NBT/JSON string representation of this attribute.
158-
* See {@link fr.zcraft.zlib.tools.nbt.NBT#toNBTJSONString(java.lang.Object) } for more information.
158+
* See {@link NBT#toNBTJSONString(java.lang.Object) } for more information.
159159
* @return the Minecraft NBT/JSON string representation of this attribute.
160160
*/
161161
@Override

src/main/java/fr/zcraft/zlib/components/nbt/NBT.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ static private void init() throws NMSException
190190
static private Object getMcNBTCompound(ItemStack item) throws NMSException
191191
{
192192
Object mcItemStack = ItemUtils.getNMSItemStack(item);
193+
if(mcItemStack == null) return null;
193194
try
194195
{
195196
return Reflection.getFieldValue(MC_ITEM_STACK, mcItemStack, "tag");

src/main/java/fr/zcraft/zlib/components/nbt/NBTCompound.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
public class NBTCompound implements Map<String, Object>
4646
{
4747
private Object nmsNbtTag;
48-
private Map<String, Object> nmsNbtMap;
48+
Map<String, Object> nmsNbtMap;
4949

5050
private final Object parent;
5151
private final Object parentKey;
@@ -66,7 +66,14 @@ public NBTCompound()
6666
NBTCompound(Object nativeNBTTag)
6767
{
6868
this.nmsNbtTag = nativeNBTTag;
69-
this.nmsNbtMap = (Map<String, Object>) NBTType.TAG_COMPOUND.getData(nmsNbtTag);
69+
if(nativeNBTTag == null)
70+
{
71+
this.nmsNbtMap = new HashMap<String, Object>();
72+
}
73+
else
74+
{
75+
this.nmsNbtMap = (Map<String, Object>) NBTType.TAG_COMPOUND.getData(nmsNbtTag);
76+
}
7077
this.parent = null;
7178
this.parentKey = null;
7279
}
@@ -99,6 +106,8 @@ private Map<String, Object> getNbtMap()
99106
else
100107
{
101108
nmsNbtTag = NBTType.TAG_COMPOUND.newTag(nmsNbtMap);
109+
NBTType.TAG_LIST.setData(nmsNbtTag, nmsNbtTag);
110+
102111
if(parent != null && parentKey != null)
103112
{
104113
if(parent instanceof NBTCompound)
@@ -247,6 +256,12 @@ public Collection<Object> values()
247256
}
248257
return list;
249258
}
259+
260+
@Override
261+
public String toString()
262+
{
263+
return NBT.toNBTJSONString(this);
264+
}
250265

251266
@Override
252267
public Set<Entry<String, Object>> entrySet()

src/main/java/fr/zcraft/zlib/components/nbt/NBTList.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
public class NBTList implements List<Object>
4646
{
4747
private Object nmsNbtTag;
48-
private List<Object> nmsNbtList;
48+
List<Object> nmsNbtList;
4949

5050
private final Object parent;
5151
private final Object parentKey;
@@ -62,7 +62,7 @@ public NBTList()
6262

6363
NBTList(Object nmsListTag)
6464
{
65-
this(nmsListTag, (List<Object>) NBTType.TAG_LIST.getData(nmsListTag));
65+
this(null, nmsListTag == null ? new ArrayList<>() : (List<Object>) NBTType.TAG_LIST.getData(nmsListTag));
6666
}
6767

6868
private NBTList(Object nmsListTag, List<Object> nmsNbtList)
@@ -101,6 +101,8 @@ private List<Object> getNbtList()
101101
else
102102
{
103103
nmsNbtTag = NBTType.TAG_LIST.newTag(nmsNbtList);
104+
NBTType.TAG_LIST.setData(nmsNbtTag, nmsNbtList);
105+
104106
if(parent != null && parentKey != null)
105107
{
106108
if(parent instanceof NBTCompound)
@@ -407,6 +409,12 @@ public <T> ListIterator<T> filter(Class<T> klass, int index)
407409
return new NBTListFilterIterator<T>(listIterator(index));
408410
}
409411

412+
@Override
413+
public String toString()
414+
{
415+
return NBT.toNBTJSONString(this);
416+
}
417+
410418
private class NBTListIterator implements ListIterator<Object>
411419
{
412420
private ListIterator<Object> iterator;

src/main/java/fr/zcraft/zlib/components/nbt/NBTType.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,25 @@ public Object newTag(Object value)
129129
{
130130
case TAG_COMPOUND:
131131
tag = Reflection.instantiate(getNMSClass());
132-
new NBTCompound(tag).putAll((Map) value);
132+
if(value instanceof NBTCompound)
133+
{
134+
setData(tag, ((NBTCompound)value).nmsNbtMap);
135+
}
136+
else
137+
{
138+
new NBTCompound(tag).putAll((Map) value);
139+
}
133140
break;
134141
case TAG_LIST:
135142
tag = Reflection.instantiate(getNMSClass());
136-
new NBTList(tag).addAll((List) value);
143+
if(value instanceof NBTList)
144+
{
145+
setData(tag, ((NBTList)value).nmsNbtList);
146+
}
147+
else
148+
{
149+
new NBTList(tag).addAll((List) value);
150+
}
137151
break;
138152
default:
139153
tag = Reflection.findConstructor(getNMSClass(), 1).newInstance(value);

src/main/java/fr/zcraft/zlib/components/rawtext/RawText.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,19 @@ static public String toJSONString(ItemStack item)
109109
{
110110
Map<String, Object> itemData = new HashMap<String, Object>();
111111

112+
String itemId = null;
112113
try
113114
{
114-
itemData.put("id", ItemUtils.getMinecraftId(item));
115+
itemId = ItemUtils.getMinecraftId(item);
115116
}
116117
catch (NMSException ex)
117118
{
118119
PluginLogger.warning("NMS Exception while parsing ItemStack to JSON String", ex);
119-
itemData.put("id", item.getTypeId());
120120
}
121121

122+
if(itemId == null) itemId = String.valueOf(item.getType().getId());
123+
itemData.put("id", itemId);
124+
122125
itemData.put("Damage", item.getDurability());
123126
try
124127
{

src/main/java/fr/zcraft/zlib/tools/items/ItemStackBuilder.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import fr.zcraft.zlib.components.gui.GuiUtils;
3434
import fr.zcraft.zlib.components.rawtext.RawText;
3535
import fr.zcraft.zlib.components.rawtext.RawTextPart;
36+
import fr.zcraft.zlib.tools.PluginLogger;
37+
import fr.zcraft.zlib.tools.reflection.NMSException;
3638
import org.bukkit.ChatColor;
3739
import org.bukkit.DyeColor;
3840
import org.bukkit.Material;
@@ -162,6 +164,33 @@ public ItemStack item()
162164

163165
return newItemStack;
164166
}
167+
168+
/**
169+
* Creates (or updates) the ItemStack, with all the previously provided
170+
* parameters, and returns it as a CraftItemStack (the Bukkit internal
171+
* ItemStack representation).
172+
*
173+
* Unlike ItemStacks, CraftItemStacks are registered into NMS, and therefore
174+
* will be able to hold NBT data (such as attributes and such).
175+
*
176+
* Note that the returned ItemStack WILL be a copy of the previously
177+
* provided one (if any).
178+
*
179+
* @return The new CraftItemStack.
180+
*/
181+
public ItemStack craftItem()
182+
{
183+
ItemStack bukkitItem = item();
184+
try
185+
{
186+
return (ItemStack) ItemUtils.asCraftCopy(item());
187+
}
188+
catch(NMSException ex)
189+
{
190+
PluginLogger.warning("CraftItem failed", ex);
191+
return bukkitItem;
192+
}
193+
}
165194

166195
/**
167196
* Defines the material of the ItemStack. This can only be defined once,

src/main/java/fr/zcraft/zlib/tools/items/ItemUtils.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,8 @@ static private Method getRegistryLookupMethod() throws NMSException
388388
* </p>
389389
*
390390
* @param item An item.
391-
* @return The Minecraft name of this item.
391+
* @return The Minecraft name of this item, or null if the item's material
392+
* is invalid.
392393
*
393394
* @throws NMSException
394395
*/
@@ -397,6 +398,8 @@ static public String getMinecraftId(ItemStack item) throws NMSException
397398
try
398399
{
399400
Object craftItemStack = asNMSCopy(item);
401+
if(craftItemStack == null) return null;
402+
400403
Object minecraftItem = Reflection.getFieldValue(craftItemStack, "item");
401404
Class<?> MinecraftItem = Reflection.getMinecraftClassByName("Item");
402405
Object ItemsRegistry = Reflection.getFieldValue(MinecraftItem, null, "REGISTRY");
@@ -449,6 +452,19 @@ static public Object asNMSCopy(ItemStack item) throws NMSException
449452
}
450453
}
451454

455+
static public Object asCraftCopy(ItemStack item) throws NMSException
456+
{
457+
try
458+
{
459+
Class CraftItemStack = Reflection.getBukkitClassByName("inventory.CraftItemStack");
460+
return CraftItemStack.getMethod("asCraftCopy", ItemStack.class).invoke(null, item);
461+
}
462+
catch(Exception ex)
463+
{
464+
throw new NMSException("Unable to retreive Craft copy", ex);
465+
}
466+
}
467+
452468
static public Object getNMSItemStack(ItemStack item) throws NMSException
453469
{
454470
try

src/main/java/fr/zcraft/zlib/tools/world/WorldUtils.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
package fr.zcraft.zlib.tools.world;
3131

3232
import org.bukkit.Location;
33+
import org.bukkit.block.BlockFace;
3334

3435
/**
3536
* Utility class for dealing with worlds and locations.
@@ -50,4 +51,30 @@ static public boolean blockEquals(Location loc1, Location loc2)
5051
&& loc1.getBlockY() == loc2.getBlockY()
5152
&& loc1.getBlockZ() == loc2.getBlockZ();
5253
}
54+
55+
/**
56+
* Returns the orientation of the specified location, as a BlockFace.
57+
* The precision of the returned BlockFace is restricted to NORTH, SOUTH,
58+
* EAST and WEST only.
59+
* @param loc The location.
60+
* @return the orientation of the specified location, as a BlockFace.
61+
*/
62+
static public BlockFace get4thOrientation(Location loc)
63+
{
64+
float yaw = Math.abs(loc.getYaw()) - 180f;
65+
66+
if(yaw <= 45 && yaw > -45)
67+
return BlockFace.NORTH;
68+
69+
if(yaw <= -45 && yaw > -135)
70+
return BlockFace.EAST;
71+
72+
if(yaw <= -135 || yaw > 135)
73+
return BlockFace.SOUTH;
74+
75+
if(yaw <= 135 && yaw > 45)
76+
return BlockFace.WEST;
77+
78+
return BlockFace.SELF;
79+
}
5380
}

0 commit comments

Comments
 (0)