diff --git a/api/src/main/java/de/erethon/dungeonsxl/api/DungeonsAPI.java b/api/src/main/java/de/erethon/dungeonsxl/api/DungeonsAPI.java index cc176911..604bc5cf 100644 --- a/api/src/main/java/de/erethon/dungeonsxl/api/DungeonsAPI.java +++ b/api/src/main/java/de/erethon/dungeonsxl/api/DungeonsAPI.java @@ -36,6 +36,7 @@ import java.util.Collection; import org.bukkit.World; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; /** @@ -294,4 +295,25 @@ public interface DungeonsAPI extends Plugin { */ boolean isInstance(World world); + /** + * Returns if the given item stack is a dungeon item. + *

+ * Dungeon items are items that are removed from the inventory when the dungeon is finished. + * + * @param itemStack the item stack + * @return if the given item stack is a dungeon item + */ + boolean isDungeonItem(ItemStack itemStack); + + /** + * Sets the given item stack to be a dungeon item and returns a copy with the updated state. + *

+ * Dungeon items are items that are removed from the inventory when the dungeon is finished. + * + * @param itemStack the item stack + * @param dungeonItem if the item stack + * @return a copy of the item stack that is a dungeon item + */ + ItemStack setDungeonItem(ItemStack itemStack, boolean dungeonItem); + } diff --git a/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java b/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java index 59f8bf05..f4c93a0c 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java +++ b/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java @@ -98,11 +98,16 @@ import java.util.Set; import java.util.function.Predicate; import java.util.logging.Level; import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; import org.bukkit.World; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; import org.bukkit.scheduler.BukkitRunnable; /** @@ -782,6 +787,26 @@ public class DungeonsXL extends DREPlugin implements DungeonsAPI { return world.getName().startsWith("DXL_Game_") || world.getName().startsWith("DXL_Edit_"); } + @Override + public boolean isDungeonItem(ItemStack itemStack) { + if (!de.erethon.commons.compatibility.Version.isAtLeast(de.erethon.commons.compatibility.Version.MC1_13)) { + return false; + } + if (itemStack == null || !itemStack.hasItemMeta()) { + return false; + } + return itemStack.getItemMeta().getPersistentDataContainer().has(NamespacedKey.fromString("dungeon_item", this), PersistentDataType.BYTE); + } + + @Override + public ItemStack setDungeonItem(ItemStack itemStack, boolean dungeonItem) { + ItemStack dIStack = itemStack.clone(); + ItemMeta meta = dIStack.getItemMeta(); + meta.getPersistentDataContainer().set(NamespacedKey.fromString("dungeon_item", this), PersistentDataType.BYTE, (byte) 1); + dIStack.setItemMeta(meta); + return dIStack; + } + /** * Clean up all instances. */ diff --git a/core/src/main/java/de/erethon/dungeonsxl/command/DCommandCache.java b/core/src/main/java/de/erethon/dungeonsxl/command/DCommandCache.java index e0236342..2203ce35 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/command/DCommandCache.java +++ b/core/src/main/java/de/erethon/dungeonsxl/command/DCommandCache.java @@ -19,6 +19,7 @@ package de.erethon.dungeonsxl.command; import de.erethon.dungeonsxl.DungeonsXL; import de.erethon.dungeonsxl.util.commons.command.DRECommand; import de.erethon.dungeonsxl.util.commons.command.DRECommandCache; +import de.erethon.dungeonsxl.util.commons.compatibility.Version; /** * An enumeration of all command instances. @@ -100,7 +101,9 @@ public class DCommandCache extends DRECommandCache { addCommand(breakCmd); addCommand(create); addCommand(delete); - addCommand(dungeonItem); + if (Version.isAtLeast(Version.MC1_13)) { + addCommand(dungeonItem); + } addCommand(edit); addCommand(enter); addCommand(escape); diff --git a/core/src/main/java/de/erethon/dungeonsxl/command/DungeonItemCommand.java b/core/src/main/java/de/erethon/dungeonsxl/command/DungeonItemCommand.java index 91e9f1e0..d3013ec7 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/command/DungeonItemCommand.java +++ b/core/src/main/java/de/erethon/dungeonsxl/command/DungeonItemCommand.java @@ -19,7 +19,6 @@ package de.erethon.dungeonsxl.command; import de.erethon.dungeonsxl.DungeonsXL; import de.erethon.dungeonsxl.config.DMessage; import de.erethon.dungeonsxl.player.DPermission; -import de.erethon.dungeonsxl.util.NBTUtil; import de.erethon.dungeonsxl.util.commons.chat.MessageUtil; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -48,33 +47,25 @@ public class DungeonItemCommand extends DCommand { Player player = (Player) sender; PlayerInventory inv = player.getInventory(); - ItemStack bukkitStack = inv.getItemInHand(); - if (bukkitStack == null) { + ItemStack itemStack = inv.getItemInMainHand(); + if (itemStack.getType().isAir()) { MessageUtil.sendTitleMessage(player, DMessage.ERROR_NO_ITEM_IN_MAIN_HAND.getMessage()); return; } - Object tag = NBTUtil.getTag(bukkitStack); String action = args.length >= 2 ? args[1] : "info"; if (action.equalsIgnoreCase("true")) { - if (tag == null) { - tag = NBTUtil.createTag(); - } - NBTUtil.addBoolean(tag, NBTUtil.DUNGEON_ITEM_KEY, true); - inv.setItemInHand(NBTUtil.setTag(bukkitStack, tag)); + inv.setItemInMainHand(plugin.setDungeonItem(itemStack, true)); MessageUtil.sendMessage(sender, DMessage.CMD_DUNGEON_ITEM_SET_DUNGEON.getMessage()); MessageUtil.sendMessage(sender, DMessage.CMD_DUNGEON_ITEM_DUNGEON_ITEM_HELP.getMessage()); } else if (action.equalsIgnoreCase("false")) { - if (tag != null) { - NBTUtil.removeKey(tag, NBTUtil.DUNGEON_ITEM_KEY); - inv.setItemInHand(NBTUtil.setTag(bukkitStack, tag)); - } + inv.setItemInMainHand(plugin.setDungeonItem(itemStack, false)); MessageUtil.sendMessage(sender, DMessage.CMD_DUNGEON_ITEM_SET_GLOBAL.getMessage()); MessageUtil.sendMessage(sender, DMessage.CMD_DUNGEON_ITEM_GLOBAL_ITEM_HELP.getMessage()); } else { - if (tag != null && NBTUtil.hasKey(tag, NBTUtil.DUNGEON_ITEM_KEY)) { + if (plugin.isDungeonItem(itemStack)) { MessageUtil.sendMessage(sender, DMessage.CMD_DUNGEON_ITEM_INFO_DUNGEON.getMessage()); MessageUtil.sendMessage(sender, DMessage.CMD_DUNGEON_ITEM_DUNGEON_ITEM_HELP.getMessage()); } else { diff --git a/core/src/main/java/de/erethon/dungeonsxl/player/DGlobalPlayer.java b/core/src/main/java/de/erethon/dungeonsxl/player/DGlobalPlayer.java index 3888fcc9..af91d5c1 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/player/DGlobalPlayer.java +++ b/core/src/main/java/de/erethon/dungeonsxl/player/DGlobalPlayer.java @@ -32,7 +32,6 @@ import de.erethon.dungeonsxl.config.DMessage; import de.erethon.dungeonsxl.dungeon.DGame; import de.erethon.dungeonsxl.global.DPortal; import de.erethon.dungeonsxl.util.LocationString; -import de.erethon.dungeonsxl.util.NBTUtil; import de.erethon.dungeonsxl.util.commons.chat.MessageUtil; import de.erethon.dungeonsxl.util.commons.compatibility.Internals; import java.io.File; @@ -508,7 +507,7 @@ public class DGlobalPlayer implements GlobalPlayer { if (item == null) { continue; } - if (NBTUtil.isDungeonItem(item)) { + if (plugin.isDungeonItem(item)) { item.setAmount(0); } } diff --git a/core/src/main/java/de/erethon/dungeonsxl/util/NBTUtil.java b/core/src/main/java/de/erethon/dungeonsxl/util/NBTUtil.java deleted file mode 100644 index 346ab4fd..00000000 --- a/core/src/main/java/de/erethon/dungeonsxl/util/NBTUtil.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2012-2021 Frank Baumann - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package de.erethon.dungeonsxl.util; - -import static de.erethon.dungeonsxl.util.ReflectionUtil.*; -import org.bukkit.inventory.ItemStack; - -/** - * A minimalistic NMS ItemStack NBT util. - * - * @author Daniel Saukel - */ -public class NBTUtil { - - public static final String DUNGEON_ITEM_KEY = "DungeonItem"; - - /** - * Returns the NBT data of an ItemStack - * - * @param item the Bukkit representation of the ItemStack - * @return the NBT data of the ItemStack - */ - public static Object getTag(ItemStack item) { - return invoke(ITEM_STACK_GET_TAG, invoke(CRAFT_ITEM_STACK_AS_NMS_COPY, null, item)); - } - - /** - * Returns a new NBTTagCompound - * - * @return a new NBTTagCompound - */ - public static Object createTag() { - return newInstance(NBT_TAG_COMPOUND); - } - - /** - * Returns a copy of the ItemStack with the applied NBT data - * - * @param item the Bukkit representation of the ItemStack - * @param tag the NBT data to set - * @return a new copy of the Bukkit ItemStack with the applied changes - */ - public static ItemStack setTag(ItemStack item, Object tag) { - Object nmsStack = invoke(CRAFT_ITEM_STACK_AS_NMS_COPY, null, item); - invoke(ITEM_STACK_SET_TAG, nmsStack, tag); - return (ItemStack) invoke(CRAFT_ITEM_STACK_AS_BUKKIT_COPY, null, nmsStack); - } - - /** - * Returns if the NBTTagCompound contains the key - * - * @param tag the NBTTagCompound - * @param key a key - * @return if the NBTTagCompound contains the key - */ - public static boolean hasKey(Object tag, String key) { - return (boolean) invoke(NBT_TAG_COMPOUND_HAS_KEY, tag, key); - } - - /** - * Adds the key and its value to the NBTTagCompound - * - * @param tag the NBTTagCompound - * @param key the key to add - * @param value the value to add - */ - public static void addBoolean(Object tag, String key, boolean value) { - invoke(NBT_TAG_COMPOUND_SET_BOOLEAN, tag, key, value); - } - - /** - * Removes the key from the NBTTagCompound - * - * @param tag the NBTTagCompound - * @param key the key to remove - */ - public static void removeKey(Object tag, String key) { - invoke(NBT_TAG_COMPOUND_REMOVE, tag, key); - } - - /** - * Returns if the item is a dungeon item - * - * @param item a Bukkit ItemStack - * @return if the item is a dungeon item - */ - public static boolean isDungeonItem(ItemStack item) { - return getTag(item) != null && hasKey(getTag(item), DUNGEON_ITEM_KEY); - } - -}