diff --git a/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java b/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java
index e5c1958..5e7575f 100644
--- a/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java
+++ b/src/main/java/de/epiceric/shopchest/listeners/ShopInteractListener.java
@@ -660,7 +660,7 @@ public class ShopInteractListener implements Listener {
double newPrice = (shop.getSellPrice() / product.getAmount()) * newAmount;
- if (freeSpace >= product.getAmount() || (config.auto_calculate_item_amount && freeSpace >= newAmount)) {
+ if (freeSpace >= product.getAmount() || (config.auto_calculate_item_amount && freeSpace >= newAmount) || shop.getShopType() == ShopType.ADMIN) {
plugin.debug("Chest has enough inventory space for " + freeSpace + " items (#" + shop.getID() + ")");
ItemStack newProduct = new ItemStack(product);
@@ -775,7 +775,7 @@ public class ShopInteractListener implements Listener {
while (added < amount) {
ItemStack item = inventory.getItem(slot);
- if (item != null) {
+ if (item != null && item.getType() != Material.AIR) {
if (Utils.isItemSimilar(item, itemStack, false)) {
if (item.getAmount() != item.getMaxStackSize()) {
ItemStack newItemStack = new ItemStack(item);
@@ -833,7 +833,7 @@ public class ShopInteractListener implements Listener {
while (removed < amount) {
ItemStack item = inventory.getItem(slot);
- if (item != null) {
+ if (item != null && item.getType() != Material.AIR) {
if (Utils.isItemSimilar(item, itemStack, false)) {
if (item.getAmount() > 0) {
int newAmount = item.getAmount() - 1;
diff --git a/src/main/java/de/epiceric/shopchest/nms/CustomBookMeta.java b/src/main/java/de/epiceric/shopchest/nms/CustomBookMeta.java
new file mode 100644
index 0000000..e12f2bd
--- /dev/null
+++ b/src/main/java/de/epiceric/shopchest/nms/CustomBookMeta.java
@@ -0,0 +1,61 @@
+package de.epiceric.shopchest.nms;
+
+import de.epiceric.shopchest.ShopChest;
+import de.epiceric.shopchest.utils.Utils;
+import org.bukkit.inventory.ItemStack;
+
+import java.lang.reflect.InvocationTargetException;
+
+// For versions below 1.9.4, since Bukkit's BookMeta
+// didn't have generations in those versions
+
+public class CustomBookMeta {
+
+ public enum Generation {
+ ORIGINAL,
+ COPY_OF_ORIGINAL,
+ COPY_OF_COPY,
+ TATTERED
+ }
+
+ public static Generation getGeneration(ItemStack book) {
+ try {
+ Class> craftItemStackClass = Utils.getCraftClass("inventory.CraftItemStack");
+
+ if (craftItemStackClass == null) {
+ ShopChest.getInstance().debug("Failed to get NBTGeneration: Could not find CraftItemStack class");
+ return null;
+ }
+
+ Object nmsStack = craftItemStackClass.getMethod("asNMSCopy", ItemStack.class).invoke(null, book);
+
+ Object nbtTagCompound = nmsStack.getClass().getMethod("getTag").invoke(nmsStack);
+ if (nbtTagCompound == null) {
+ ShopChest.getInstance().debug("Failed to get NBTGeneration: getTag returned null");
+ return null;
+ }
+
+ Object generationObject = nbtTagCompound.getClass().getMethod("getInt", String.class).invoke(nbtTagCompound, "generation");
+ if (generationObject == null) {
+ ShopChest.getInstance().debug("Failed to get NBTGeneration: getInt returned null");
+ return null;
+ }
+
+ if (generationObject instanceof Integer) {
+ int generation = (Integer) generationObject;
+
+ if (generation > 3) generation = 3;
+
+ return Generation.values()[generation];
+ }
+
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+ ShopChest.getInstance().getLogger().severe("Failed to get NBTEntityID with reflection");
+ ShopChest.getInstance().debug("Failed to get NBTEntityID with reflection");
+ ShopChest.getInstance().debug(e);
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/main/java/de/epiceric/shopchest/utils/Utils.java b/src/main/java/de/epiceric/shopchest/utils/Utils.java
index a59cc29..f588f31 100644
--- a/src/main/java/de/epiceric/shopchest/utils/Utils.java
+++ b/src/main/java/de/epiceric/shopchest/utils/Utils.java
@@ -1,6 +1,7 @@
package de.epiceric.shopchest.utils;
import de.epiceric.shopchest.ShopChest;
+import de.epiceric.shopchest.nms.CustomBookMeta;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.configuration.InvalidConfigurationException;
@@ -11,6 +12,7 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.*;
import org.bukkit.material.MaterialData;
+import org.bukkit.potion.Potion;
import javax.xml.bind.DatatypeConverter;
import java.lang.reflect.InvocationTargetException;
@@ -72,7 +74,7 @@ public class Utils {
similar = (bannerMeta1.getBaseColor() == bannerMeta2.getBaseColor());
similar &= (bannerMeta1.getPatterns().equals(bannerMeta2.getPatterns()));
- } else if (itemMeta1 instanceof BlockStateMeta) {
+ } else if (!getServerVersion().equals("v1_8_R1") && itemMeta1 instanceof BlockStateMeta) {
BlockStateMeta bsMeta1 = (BlockStateMeta) itemMeta1;
BlockStateMeta bsMeta2 = (BlockStateMeta) itemMeta2;
@@ -88,7 +90,21 @@ public class Utils {
if (bookMeta1.hasTitle()) similar &= (bookMeta1.getTitle().equals(bookMeta2.getTitle()));
if (bookMeta1.hasPages()) similar &= (bookMeta1.getPages().equals(bookMeta2.getPages()));
- similar &= (bookMeta1.getGeneration() == bookMeta2.getGeneration());
+ if ((getMajorVersion() == 9 && getRevision() == 1) || getMajorVersion() == 8) {
+ CustomBookMeta.Generation generation1 = CustomBookMeta.getGeneration(itemStack1);
+ CustomBookMeta.Generation generation2 = CustomBookMeta.getGeneration(itemStack2);
+
+ if (generation1 == null) generation1 = CustomBookMeta.Generation.ORIGINAL;
+ if (generation2 == null) generation2 = CustomBookMeta.Generation.ORIGINAL;
+
+ similar &= (generation1 == generation2);
+
+ } else if (getMajorVersion() >= 10) {
+ if (!bookMeta1.hasGeneration()) bookMeta1.setGeneration(BookMeta.Generation.ORIGINAL);
+ if (!bookMeta2.hasGeneration()) bookMeta2.setGeneration(BookMeta.Generation.ORIGINAL);
+
+ similar &= (bookMeta1.getGeneration() == bookMeta2.getGeneration());
+ }
} else if (itemMeta1 instanceof EnchantmentStorageMeta) {
EnchantmentStorageMeta esMeta1 = (EnchantmentStorageMeta) itemMeta1;
@@ -124,7 +140,17 @@ public class Utils {
PotionMeta potionMeta2 = (PotionMeta) itemMeta2;
if (potionMeta1.hasCustomEffects()) similar = (potionMeta1.getCustomEffects().equals(potionMeta2.getCustomEffects()));
- similar &= (potionMeta1.getBasePotionData().equals(potionMeta2.getBasePotionData()));
+
+ if (getMajorVersion() >= 9) {
+ similar &= (potionMeta1.getBasePotionData().equals(potionMeta2.getBasePotionData()));
+ } else {
+ Potion potion1 = Potion.fromItemStack(itemStack1);
+ Potion potion2 = Potion.fromItemStack(itemStack2);
+
+ similar &= (potion1.getType() == potion2.getType());
+ similar &= (potion1.getEffects().equals(potion2.getEffects()));
+ similar &= (potion1.getLevel() == potion2.getLevel());
+ }
} else if (itemMeta1 instanceof SkullMeta) {
SkullMeta skullMeta1 = (SkullMeta) itemMeta1;
@@ -185,7 +211,7 @@ public class Utils {
if (inventory instanceof PlayerInventory) {
for (int i = 0; i < 36; i++) {
ItemStack item = inventory.getItem(i);
- if (item == null) {
+ if (item == null || item.getType() == Material.AIR) {
slotFree.put(i, itemStack.getMaxStackSize());
} else {
if (isItemSimilar(item, itemStack, false)) {
@@ -198,7 +224,7 @@ public class Utils {
if (getMajorVersion() >= 9) {
ItemStack item = inventory.getItem(40);
- if (item == null) {
+ if (item == null || item.getType() == Material.AIR) {
slotFree.put(40, itemStack.getMaxStackSize());
} else {
if (isItemSimilar(item, itemStack, false)) {
@@ -211,7 +237,7 @@ public class Utils {
} else {
for (int i = 0; i < inventory.getSize(); i++) {
ItemStack item = inventory.getItem(i);
- if (item == null) {
+ if (item == null || item.getType() == Material.AIR) {
slotFree.put(i, itemStack.getMaxStackSize());
} else {
if (isItemSimilar(item, itemStack, false)) {
@@ -346,11 +372,18 @@ public class Utils {
return packageName.substring(packageName.lastIndexOf('.') + 1);
}
+ /**
+ * @return The revision of the current server version (e.g. 2 for v1_9_R2, 1 for v1_10_R1)
+ */
+ public static int getRevision() {
+ return Integer.parseInt(getServerVersion().substring(getServerVersion().length() - 1));
+ }
+
/**
* @return The major version of the server (e.g. 9 for 1.9.2, 10 for 1.10)
*/
public static int getMajorVersion() {
- return Integer.valueOf(getServerVersion().split("_")[1]);
+ return Integer.parseInt(getServerVersion().split("_")[1]);
}
/**