Use PersistentDataContainer for dungeon items; #1035

This commit is contained in:
Daniel Saukel 2021-07-04 16:52:10 +02:00
parent e88487d639
commit 5862dd9dff
6 changed files with 57 additions and 122 deletions

View File

@ -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.
* <p>
* 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.
* <p>
* 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);
}

View File

@ -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.
*/

View File

@ -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);
if (Version.isAtLeast(Version.MC1_13)) {
addCommand(dungeonItem);
}
addCommand(edit);
addCommand(enter);
addCommand(escape);

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}