diff --git a/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java b/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java index f2e814e5..c7a6fbbc 100644 --- a/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java +++ b/src/main/java/com/extendedclip/deluxemenus/config/DeluxeMenusConfig.java @@ -73,6 +73,7 @@ import java.util.stream.Collectors; import static com.extendedclip.deluxemenus.utils.Constants.PLACEHOLDER_PREFIX; +import static com.extendedclip.deluxemenus.utils.Constants.STACK_PREFIX; import static com.extendedclip.deluxemenus.utils.Constants.PLAYER_ITEMS; import static com.extendedclip.deluxemenus.utils.Constants.WATER_BOTTLE; @@ -90,6 +91,7 @@ public class DeluxeMenusConfig { VALID_MATERIALS.add(WATER_BOTTLE); VALID_MATERIAL_PREFIXES.add(PLACEHOLDER_PREFIX); + VALID_MATERIAL_PREFIXES.add(STACK_PREFIX); } private final String separator = File.separator; diff --git a/src/main/java/com/extendedclip/deluxemenus/menu/MenuItem.java b/src/main/java/com/extendedclip/deluxemenus/menu/MenuItem.java index 55b216e5..2e49d5cd 100644 --- a/src/main/java/com/extendedclip/deluxemenus/menu/MenuItem.java +++ b/src/main/java/com/extendedclip/deluxemenus/menu/MenuItem.java @@ -39,9 +39,13 @@ import org.bukkit.inventory.meta.trim.TrimMaterial; import org.bukkit.inventory.meta.trim.TrimPattern; import org.bukkit.potion.PotionEffect; +import org.bukkit.util.io.BukkitObjectInputStream; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.Base64; import java.util.Arrays; import java.util.ArrayList; import java.util.List; @@ -54,6 +58,7 @@ import static com.extendedclip.deluxemenus.utils.Constants.INVENTORY_ITEM_ACCESSORS; import static com.extendedclip.deluxemenus.utils.Constants.PLACEHOLDER_PREFIX; +import static com.extendedclip.deluxemenus.utils.Constants.STACK_PREFIX; public class MenuItem { @@ -65,6 +70,25 @@ public MenuItem(@NotNull final DeluxeMenus plugin, @NotNull final MenuItemOption this.options = options; } + public static ItemStack base64ToItemStack(String data) { + try { + byte[] bytes = Base64.getDecoder().decode(data); + ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); + BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream); + dataInput.close(); + Object object = dataInput.readObject(); + if (object instanceof ItemStack) { + return (ItemStack) object; + } + return null; + } catch (IllegalArgumentException e) { + return null; + } catch (IOException e) { + return null; + } catch (ClassNotFoundException e) { + return null; + } + } public ItemStack getItemStack(@NotNull final MenuHolder holder) { final Player viewer = holder.getViewer(); @@ -78,6 +102,16 @@ public ItemStack getItemStack(@NotNull final MenuHolder holder) { stringMaterial = holder.setPlaceholdersAndArguments(stringMaterial.substring(PLACEHOLDER_PREFIX.length())); lowercaseStringMaterial = stringMaterial.toLowerCase(Locale.ENGLISH); } + if (ItemUtils.isItemStackOption(lowercaseStringMaterial)) { + stringMaterial = holder.setPlaceholdersAndArguments(stringMaterial.substring(STACK_PREFIX.length())); + ItemStack base64Item = base64ToItemStack(stringMaterial); + if (base64Item != null) { + itemStack = base64Item; + amount = itemStack.getAmount(); + lowercaseStringMaterial = itemStack.getType().toString().toLowerCase(Locale.ENGLISH); + } + } + if (ItemUtils.isPlayerItem(lowercaseStringMaterial)) { final ItemStack playerItem = INVENTORY_ITEM_ACCESSORS.get(lowercaseStringMaterial).apply(viewer.getInventory()); diff --git a/src/main/java/com/extendedclip/deluxemenus/utils/Constants.java b/src/main/java/com/extendedclip/deluxemenus/utils/Constants.java index 432b73a9..1a84d92f 100644 --- a/src/main/java/com/extendedclip/deluxemenus/utils/Constants.java +++ b/src/main/java/com/extendedclip/deluxemenus/utils/Constants.java @@ -32,6 +32,7 @@ private Constants() { public static final String BASE64_HEAD_TYPE = "basehead"; public static final String HDB_HEAD_TYPE = "hdb"; + public static final String STACK_PREFIX = "stack-"; public static final String PLACEHOLDER_PREFIX = "placeholder-"; public static final String WATER_BOTTLE = "water_bottle"; diff --git a/src/main/java/com/extendedclip/deluxemenus/utils/ItemUtils.java b/src/main/java/com/extendedclip/deluxemenus/utils/ItemUtils.java index 5c404299..870e8312 100644 --- a/src/main/java/com/extendedclip/deluxemenus/utils/ItemUtils.java +++ b/src/main/java/com/extendedclip/deluxemenus/utils/ItemUtils.java @@ -11,6 +11,7 @@ import static com.extendedclip.deluxemenus.utils.Constants.INVENTORY_ITEM_ACCESSORS; import static com.extendedclip.deluxemenus.utils.Constants.PLACEHOLDER_PREFIX; +import static com.extendedclip.deluxemenus.utils.Constants.STACK_PREFIX; import static com.extendedclip.deluxemenus.utils.Constants.WATER_BOTTLE; public final class ItemUtils { @@ -29,6 +30,16 @@ public static boolean isPlaceholderOption(@NotNull final String material) { return material.toLowerCase(Locale.ROOT).startsWith(PLACEHOLDER_PREFIX); } + /** + * Checks if the string starts with the substring "stack-". The check is case-insensitive. + * + * @param itemstack The string to check + * @return true if the string starts with "stack-", false otherwise + */ + public static boolean isItemStackOption(@NotNull final String material) { + return material.toLowerCase(Locale.ROOT).startsWith(STACK_PREFIX); + } + /** * Checks if the string is a player item. The check is case-sensitive. * Player items are: "main_hand", "off_hand", "armor_helmet", "armor_chestplate", "armor_leggings", "armor_boots"