diff --git a/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java b/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java index e7bdfff5..0a870c26 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java +++ b/src/main/java/net/Indyuce/mmocore/gui/PlayerStats.java @@ -200,13 +200,15 @@ public class PlayerStats extends EditableInventory { @Override public ItemStack display(GeneratedInventory inv, int n) { - ItemStack item = super.display(inv, n); - if (item.getType() == VersionMaterial.PLAYER_HEAD.toMaterial()) { - SkullMeta meta = (SkullMeta) item.getItemMeta(); - meta.setOwningPlayer(inv.getPlayer()); - item.setItemMeta(meta); + ItemStack disp = super.display(inv, n); + if (disp.getType() == VersionMaterial.PLAYER_HEAD.toMaterial()) { + SkullMeta meta = (SkullMeta) disp.getItemMeta(); + inv.dynamicallyUpdateItem(this, n, disp, current -> { + meta.setOwningPlayer(inv.getPlayer()); + current.setItemMeta(meta); + }); } - return item; + return disp; } @Override diff --git a/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java b/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java index b3cca611..f01e98e2 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java +++ b/src/main/java/net/Indyuce/mmocore/gui/api/GeneratedInventory.java @@ -1,95 +1,112 @@ package net.Indyuce.mmocore.gui.api; import io.lumine.mythic.lib.MythicLib; +import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.gui.api.item.InventoryItem; import net.Indyuce.mmocore.gui.api.item.TriggerItem; import org.bukkit.Bukkit; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; public abstract class GeneratedInventory extends PluginInventory { - private final EditableInventory editable; - private final List loaded = new ArrayList<>(); + private final EditableInventory editable; + private final List loaded = new ArrayList<>(); - public GeneratedInventory(PlayerData playerData, EditableInventory editable) { - super(playerData); + private Inventory open; - this.editable = editable; - } + public GeneratedInventory(PlayerData playerData, EditableInventory editable) { + super(playerData); - public List getLoaded() { - return loaded; - } + this.editable = editable; + } - public EditableInventory getEditable() { - return editable; - } + public List getLoaded() { + return loaded; + } - public InventoryItem getByFunction(String function) { - for (InventoryItem item : loaded) - if (item.getFunction().equals(function)) - return item; - return null; - } + public EditableInventory getEditable() { + return editable; + } - public InventoryItem getBySlot(int slot) { - for (InventoryItem item : loaded) - if (item.getSlots().contains(slot)) - return item; - return null; - } + public InventoryItem getByFunction(String function) { + for (InventoryItem item : loaded) + if (item.getFunction().equals(function)) + return item; + return null; + } - /** - * This method must use an ordered collection because - * of GUI items overriding possibilities. Hence the use - * of an array list instead of a set - */ - public void addLoaded(InventoryItem item) { - loaded.add(0, item); - } + public InventoryItem getBySlot(int slot) { + for (InventoryItem item : loaded) + if (item.getSlots().contains(slot)) + return item; + return null; + } - @Override - public Inventory getInventory() { - Inventory inv = Bukkit.createInventory(this, editable.getSlots(), MythicLib.plugin.parseColors(calculateName())); + /** + * This method must use an ordered collection because + * of GUI items overriding possibilities. Hence the use + * of an array list instead of a set + */ + public void addLoaded(InventoryItem item) { + loaded.add(0, item); + } - for (InventoryItem item : editable.getItems()) - if (item.canDisplay(this)) - item.setDisplayed(inv, this); + @Override + public Inventory getInventory() { + Inventory inv = Bukkit.createInventory(this, editable.getSlots(), MythicLib.plugin.parseColors(calculateName())); - return inv; - } + for (InventoryItem item : editable.getItems()) + if (item.canDisplay(this)) + item.setDisplayed(inv, this); - public void open() { + return inv; + } - /* - * Very important, in order to prevent ghost items, the loaded items map - * must be cleared when the inventory is updated or open at least twice - */ - loaded.clear(); + public void open() { - getPlayer().openInventory(getInventory()); - } + /* + * Very important, in order to prevent ghost items, the loaded items map + * must be cleared when the inventory is updated or open at least twice + */ + loaded.clear(); - public void whenClicked(InventoryClickEvent event) { - event.setCancelled(true); + getPlayer().openInventory(open = getInventory()); + } - if (event.getClickedInventory() != null && event.getClickedInventory().equals(event.getInventory())) { - InventoryItem item = getBySlot(event.getSlot()); - if (item == null) - return; + /** + * @deprecated Not a fan of that implementation. + * Better work with {@link InventoryItem#setDisplayed(Inventory, GeneratedInventory)} + */ + @Deprecated + public void dynamicallyUpdateItem(InventoryItem item, int n, ItemStack placed, Consumer update) { + Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> { + update.accept(placed); + open.setItem(item.getSlots().get(n), placed); + }); + } - if (item instanceof TriggerItem) - ((TriggerItem) item).getTrigger().apply(getPlayerData()); - else - whenClicked(event, item); - } - } + public void whenClicked(InventoryClickEvent event) { + event.setCancelled(true); - public abstract String calculateName(); + if (event.getClickedInventory() != null && event.getClickedInventory().equals(event.getInventory())) { + InventoryItem item = getBySlot(event.getSlot()); + if (item == null) + return; - public abstract void whenClicked(InventoryClickEvent event, InventoryItem item); + if (item instanceof TriggerItem) + ((TriggerItem) item).getTrigger().apply(getPlayerData()); + else + whenClicked(event, item); + } + } + + public abstract String calculateName(); + + public abstract void whenClicked(InventoryClickEvent event, InventoryItem item); } diff --git a/src/main/java/net/Indyuce/mmocore/gui/api/item/InventoryItem.java b/src/main/java/net/Indyuce/mmocore/gui/api/item/InventoryItem.java index 395e2f7a..1de7b85d 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/api/item/InventoryItem.java +++ b/src/main/java/net/Indyuce/mmocore/gui/api/item/InventoryItem.java @@ -13,6 +13,8 @@ import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.SkullMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.lang.reflect.Field; import java.util.ArrayList; @@ -21,147 +23,160 @@ import java.util.UUID; import java.util.logging.Level; public abstract class InventoryItem { - private final String id, function; - private final List slots = new ArrayList<>(); + private final String id, function; + private final List slots = new ArrayList<>(); - private final Material material; - private final String name, texture; - private final List lore; - private final int modelData; - private final boolean placeholders, hideFlags; + @Nullable + private final InventoryItem parent; - public InventoryItem(ConfigurationSection config) { - this(Material.valueOf(config.getString("item", "").toUpperCase().replace(" ", "_").replace("-", "_")), config); - } + private final Material material; + private final String name, texture; + private final List lore; + private final int modelData; + private final boolean hideFlags; - public InventoryItem(Material material, ConfigurationSection config) { - this.id = config.getName(); - this.function = config.getString("function", ""); + public InventoryItem(ConfigurationSection config) { + this((InventoryItem) null, config); + } - this.material = material; - this.name = config.getString("name"); - this.lore = config.getStringList("lore"); - this.hideFlags = config.getBoolean("hide-flags"); - this.texture = config.getString("texture"); - this.placeholders = config.getBoolean("placeholders"); - this.modelData = config.getInt("custom-model-data"); + public InventoryItem(@Nullable InventoryItem parent, ConfigurationSection config) { + this(parent, Material.valueOf(config.getString("item", "").toUpperCase().replace(" ", "_").replace("-", "_")), config); + } - config.getStringList("slots").forEach(str -> slots.add(Integer.parseInt(str))); - } + public InventoryItem(@NotNull Material material, ConfigurationSection config) { + this(null, material, config); + } - public String getId() { - return id; - } + public InventoryItem(InventoryItem parent, Material material, ConfigurationSection config) { + this.id = config.getName(); + this.function = config.getString("function", ""); + this.parent = parent; - public String getFunction() { - return function; - } + this.material = material; + this.name = config.getString("name"); + this.lore = config.getStringList("lore"); + this.hideFlags = config.getBoolean("hide-flags"); + this.texture = config.getString("texture"); + this.modelData = config.getInt("custom-model-data"); - public boolean hasFunction() { - return !function.isEmpty(); - } + config.getStringList("slots").forEach(str -> slots.add(Integer.parseInt(str))); + } - public List getSlots() { - return slots; - } + public String getId() { + return id; + } - public Material getMaterial() { - return material; - } + @NotNull + public String getFunction() { + return parent == null ? function : parent.function; + } - public boolean hideFlags() { - return hideFlags; - } + public boolean hasFunction() { + return !getFunction().isEmpty(); + } - public boolean hasName() { - return name != null; - } + @NotNull + public List getSlots() { + return parent == null ? slots : parent.slots; + } - public String getName() { - return name; - } + public Material getMaterial() { + return material; + } - public boolean hasLore() { - return lore != null && !lore.isEmpty(); - } + public boolean hideFlags() { + return hideFlags; + } - public List getLore() { - return lore; - } + public boolean hasName() { + return name != null; + } - public int getModelData() { - return modelData; - } + public String getName() { + return name; + } - public void setDisplayed(Inventory inv, T generated) { - generated.addLoaded(this); + public boolean hasLore() { + return lore != null && !lore.isEmpty(); + } - if (!hasDifferentDisplay()) { - ItemStack display = display(generated); - for (int slot : getSlots()) - inv.setItem(slot, display); - } else - for (int j = 0; j < slots.size(); j++) - inv.setItem(slots.get(j), display(generated, j)); + public List getLore() { + return lore; + } - } + public int getModelData() { + return modelData; + } - public boolean hasDifferentDisplay() { - return false; - } + public void setDisplayed(Inventory inv, T generated) { + generated.addLoaded(this); - public boolean canDisplay(T inv) { - return true; - } + if (!hasDifferentDisplay()) { + ItemStack display = display(generated); + for (int slot : getSlots()) + inv.setItem(slot, display); + } else + for (int j = 0; j < slots.size(); j++) + inv.setItem(slots.get(j), display(generated, j)); - public ItemStack display(T inv) { - return display(inv, 0); - } + } - public ItemStack display(T inv, int n) { + public boolean hasDifferentDisplay() { + return false; + } - Placeholders placeholders = getPlaceholders(inv, n); - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); + public boolean canDisplay(T inv) { + return true; + } - if (texture != null && meta instanceof SkullMeta) - applyTexture(texture, (SkullMeta) meta); + public ItemStack display(T inv) { + return display(inv, 0); + } - if (hasName()) - meta.setDisplayName(placeholders.apply(inv.getPlayer(), getName())); + public ItemStack display(T inv, int n) { - if (hideFlags()) - meta.addItemFlags(ItemFlag.values()); + Placeholders placeholders = getPlaceholders(inv, n); + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); - if (hasLore()) { - List lore = new ArrayList<>(); - getLore().forEach(line -> lore.add(ChatColor.GRAY + placeholders.apply(inv.getPlayer(), line))); - meta.setLore(lore); - } + if (texture != null && meta instanceof SkullMeta) + applyTexture(texture, (SkullMeta) meta); - if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13)) - meta.setCustomModelData(getModelData()); + if (hasName()) + meta.setDisplayName(placeholders.apply(inv.getPlayer(), getName())); - item.setItemMeta(meta); - return item; - } + if (hideFlags()) + meta.addItemFlags(ItemFlag.values()); - private void applyTexture(String value, SkullMeta meta) { - try { - GameProfile profile = new GameProfile(UUID.randomUUID(), null); - profile.getProperties().put("textures", new Property("textures", value)); + if (hasLore()) { + List lore = new ArrayList<>(); + getLore().forEach(line -> lore.add(ChatColor.GRAY + placeholders.apply(inv.getPlayer(), line))); + meta.setLore(lore); + } - Field profileField = meta.getClass().getDeclaredField("profile"); - profileField.setAccessible(true); - profileField.set(meta, profile); - } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException exception) { - MMOCore.log(Level.WARNING, "Could not apply item texture value of " + getId()); - } - } + if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13)) + meta.setCustomModelData(getModelData()); - public Placeholders getPlaceholders(T inv) { - return getPlaceholders(inv, 0); - } + item.setItemMeta(meta); + return item; + } - public abstract Placeholders getPlaceholders(T inv, int n); + private void applyTexture(String value, SkullMeta meta) { + try { + GameProfile profile = new GameProfile(UUID.randomUUID(), null); + profile.getProperties().put("textures", new Property("textures", value)); + + Field profileField = meta.getClass().getDeclaredField("profile"); + profileField.setAccessible(true); + profileField.set(meta, profile); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException exception) { + MMOCore.log(Level.WARNING, "Could not apply item texture value of " + getId()); + } + } + + public Placeholders getPlaceholders(T inv) { + return getPlaceholders(inv, 0); + } + + public abstract Placeholders getPlaceholders(T inv, int n); } diff --git a/src/main/java/net/Indyuce/mmocore/gui/api/item/SimplePlaceholderItem.java b/src/main/java/net/Indyuce/mmocore/gui/api/item/SimplePlaceholderItem.java index 4f152333..57cf9f97 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/api/item/SimplePlaceholderItem.java +++ b/src/main/java/net/Indyuce/mmocore/gui/api/item/SimplePlaceholderItem.java @@ -5,6 +5,10 @@ import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; public class SimplePlaceholderItem extends InventoryItem { + public SimplePlaceholderItem(InventoryItem parent, ConfigurationSection config) { + super(parent, config); + } + public SimplePlaceholderItem(ConfigurationSection config) { super(config); } diff --git a/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendList.java b/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendList.java index 4b7ae05f..040ff023 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendList.java +++ b/src/main/java/net/Indyuce/mmocore/gui/social/friend/EditableFriendList.java @@ -1,7 +1,5 @@ package net.Indyuce.mmocore.gui.social.friend; -import io.lumine.mythic.lib.api.item.ItemTag; -import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerActivity; import net.Indyuce.mmocore.api.player.PlayerData; @@ -15,6 +13,7 @@ import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; import net.Indyuce.mmocore.manager.InventoryManager; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; import org.bukkit.OfflinePlayer; import org.bukkit.Sound; import org.bukkit.configuration.ConfigurationSection; @@ -24,10 +23,13 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.persistence.PersistentDataType; import java.util.UUID; public class EditableFriendList extends EditableInventory { + private static final NamespacedKey UUID_NAMESPACEDKEY = new NamespacedKey(MMOCore.plugin, "Uuid"); + public EditableFriendList() { super("friend-list"); } @@ -64,8 +66,8 @@ public class EditableFriendList extends EditableInventory { } public static class OfflineFriendItem extends InventoryItem { - public OfflineFriendItem(ConfigurationSection config) { - super(config); + public OfflineFriendItem(FriendItem parent, ConfigurationSection config) { + super(parent, config); } @Override @@ -82,27 +84,11 @@ public class EditableFriendList extends EditableInventory { holders.register("last_seen", new DelayFormat(2).format(System.currentTimeMillis() - friend.getLastPlayed())); return holders; } - - @Override - public ItemStack display(GeneratedInventory inv, int n) { - OfflinePlayer friend = Bukkit.getOfflinePlayer(inv.getPlayerData().getFriends().get(n)); - - ItemStack disp = super.display(inv, n); - ItemMeta meta = disp.getItemMeta(); - - if (meta instanceof SkullMeta) - Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> { - ((SkullMeta) meta).setOwningPlayer(friend); - disp.setItemMeta(meta); - }); - - return NBTItem.get(disp).addTag(new ItemTag("uuid", friend.getUniqueId().toString())).toItem(); - } } public static class OnlineFriendItem extends SimplePlaceholderItem { - public OnlineFriendItem(ConfigurationSection config) { - super(config); + public OnlineFriendItem(FriendItem parent, ConfigurationSection config) { + super(parent, config); } @Override @@ -123,22 +109,6 @@ public class EditableFriendList extends EditableInventory { holders.register("online_since", new DelayFormat(2).format(System.currentTimeMillis() - data.getLastLogin())); return holders; } - - @Override - public ItemStack display(GeneratedInventory inv, int n) { - Player friend = Bukkit.getPlayer(inv.getPlayerData().getFriends().get(n)); - - ItemStack disp = super.display(inv, n); - ItemMeta meta = disp.getItemMeta(); - - if (meta instanceof SkullMeta) - Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> { - ((SkullMeta) meta).setOwningPlayer(friend); - disp.setItemMeta(meta); - }); - - return NBTItem.get(disp).addTag(new ItemTag("uuid", friend.getUniqueId().toString())).toItem(); - } } public static class FriendItem extends SimplePlaceholderItem { @@ -151,14 +121,28 @@ public class EditableFriendList extends EditableInventory { Validate.notNull(config.contains("online"), "Could not load online config"); Validate.notNull(config.contains("offline"), "Could not load offline config"); - online = new OnlineFriendItem(config.getConfigurationSection("online")); - offline = new OfflineFriendItem(config.getConfigurationSection("offline")); + online = new OnlineFriendItem(this, config.getConfigurationSection("online")); + offline = new OfflineFriendItem(this, config.getConfigurationSection("offline")); } @Override public ItemStack display(GeneratedInventory inv, int n) { - return inv.getPlayerData().getFriends().size() <= n ? super.display(inv, n) - : Bukkit.getOfflinePlayer(inv.getPlayerData().getFriends().get(n)).isOnline() ? online.display(inv, n) : offline.display(inv, n); + if (inv.getPlayerData().getFriends().size() <= n) + return super.display(inv, n); + + ItemStack disp = Bukkit.getOfflinePlayer(inv.getPlayerData().getFriends().get(n)).isOnline() ? online.display(inv, n) : offline.display(inv, n); + Player friend = Bukkit.getPlayer(inv.getPlayerData().getFriends().get(n)); + ItemMeta meta = disp.getItemMeta(); + meta.getPersistentDataContainer().set(UUID_NAMESPACEDKEY, PersistentDataType.STRING, friend.getUniqueId().toString()); + + if (meta instanceof SkullMeta) + inv.dynamicallyUpdateItem(this, n, disp, current -> { + ((SkullMeta) meta).setOwningPlayer(friend); + current.setItemMeta(meta); + }); + + disp.setItemMeta(meta); + return disp; } @Override @@ -238,7 +222,7 @@ public class EditableFriendList extends EditableInventory { } if (item.getFunction().equals("friend") && event.getAction() == InventoryAction.PICKUP_HALF) { - String tag = NBTItem.get(event.getCurrentItem()).getString("uuid"); + String tag = event.getCurrentItem().getItemMeta().getPersistentDataContainer().get(UUID_NAMESPACEDKEY, PersistentDataType.STRING); if (tag == null || tag.isEmpty()) return; diff --git a/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildAdmin.java b/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildAdmin.java index d4ffc20a..accda5e7 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildAdmin.java +++ b/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildAdmin.java @@ -13,6 +13,7 @@ import net.Indyuce.mmocore.gui.api.item.Placeholders; import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; +import org.bukkit.NamespacedKey; import org.bukkit.OfflinePlayer; import org.bukkit.Sound; import org.bukkit.configuration.ConfigurationSection; @@ -22,10 +23,13 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.persistence.PersistentDataType; import java.util.UUID; public class EditableGuildAdmin extends EditableInventory { + private static final NamespacedKey UUID_NAMESPACEDKEY = new NamespacedKey(MMOCore.plugin, "Uuid"); + public EditableGuildAdmin() { super("guild-admin"); } @@ -40,8 +44,8 @@ public class EditableGuildAdmin extends EditableInventory { } public static class MemberDisplayItem extends InventoryItem { - public MemberDisplayItem(ConfigurationSection config) { - super(config); + public MemberDisplayItem(MemberItem memberItem, ConfigurationSection config) { + super(memberItem, config); } @Override @@ -65,19 +69,21 @@ public class EditableGuildAdmin extends EditableInventory { @Override public ItemStack display(GeneratedInventory inv, int n) { - PlayerData member = PlayerData.get(inv.getPlayerData().getGuild().getMembers().get(n)); + UUID uuid = inv.getPlayerData().getGuild().getMembers().get(n); + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid); ItemStack disp = super.display(inv, n); ItemMeta meta = disp.getItemMeta(); + meta.getPersistentDataContainer().set(UUID_NAMESPACEDKEY, PersistentDataType.STRING, uuid.toString()); - if (meta instanceof SkullMeta) - Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> { - if (!member.isOnline()) return; - ((SkullMeta) meta).setOwningPlayer(member.getPlayer()); - disp.setItemMeta(meta); + if (meta instanceof SkullMeta && offlinePlayer != null) + inv.dynamicallyUpdateItem(this, n, disp, current -> { + ((SkullMeta) meta).setOwningPlayer(offlinePlayer); + current.setItemMeta(meta); }); - return NBTItem.get(disp).addTag(new ItemTag("uuid", member.getUniqueId().toString())).toItem(); + disp.setItemMeta(meta); + return disp; } } @@ -92,7 +98,7 @@ public class EditableGuildAdmin extends EditableInventory { Validate.notNull(config.contains("member"), "Could not load member config"); empty = new SimplePlaceholderItem(config.getConfigurationSection("empty")); - member = new MemberDisplayItem(config.getConfigurationSection("member")); + member = new MemberDisplayItem(this, config.getConfigurationSection("member")); } @Override @@ -174,7 +180,7 @@ public class EditableGuildAdmin extends EditableInventory { if (!playerData.getGuild().getOwner().equals(playerData.getUniqueId())) return; - OfflinePlayer target = Bukkit.getOfflinePlayer(UUID.fromString(NBTItem.get(event.getCurrentItem()).getString("uuid"))); + OfflinePlayer target = Bukkit.getOfflinePlayer(UUID.fromString(event.getCurrentItem().getItemMeta().getPersistentDataContainer().get(UUID_NAMESPACEDKEY, PersistentDataType.STRING))); if (target.equals(player)) return; diff --git a/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildView.java b/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildView.java index 161dad7e..165b87e3 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildView.java +++ b/src/main/java/net/Indyuce/mmocore/gui/social/guild/EditableGuildView.java @@ -1,7 +1,5 @@ package net.Indyuce.mmocore.gui.social.guild; -import io.lumine.mythic.lib.api.item.ItemTag; -import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.OfflinePlayerData; import net.Indyuce.mmocore.api.player.PlayerData; @@ -13,10 +11,7 @@ import net.Indyuce.mmocore.gui.api.item.InventoryItem; import net.Indyuce.mmocore.gui.api.item.Placeholders; import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; import org.apache.commons.lang.Validate; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.OfflinePlayer; -import org.bukkit.Sound; +import org.bukkit.*; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryAction; @@ -24,10 +19,13 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.persistence.PersistentDataType; import java.util.UUID; public class EditableGuildView extends EditableInventory { + private static final NamespacedKey UUID_NAMESPACEDKEY = new NamespacedKey(MMOCore.plugin, "Uuid"); + public EditableGuildView() { super("guild-view"); } @@ -38,8 +36,8 @@ public class EditableGuildView extends EditableInventory { } public static class MemberDisplayItem extends InventoryItem { - public MemberDisplayItem(ConfigurationSection config) { - super(config); + public MemberDisplayItem(MemberItem memberItem, ConfigurationSection config) { + super(memberItem, config); } @Override @@ -71,14 +69,16 @@ public class EditableGuildView extends EditableInventory { ItemStack disp = super.display(inv, n); ItemMeta meta = disp.getItemMeta(); + meta.getPersistentDataContainer().set(UUID_NAMESPACEDKEY, PersistentDataType.STRING, uuid.toString()); if (meta instanceof SkullMeta) - Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> { + inv.dynamicallyUpdateItem(this, n, disp, current -> { ((SkullMeta) meta).setOwningPlayer(Bukkit.getOfflinePlayer(uuid)); - disp.setItemMeta(meta); + current.setItemMeta(meta); }); - return NBTItem.get(disp).addTag(new ItemTag("uuid", uuid.toString())).toItem(); + disp.setItemMeta(meta); + return disp; } } @@ -93,7 +93,7 @@ public class EditableGuildView extends EditableInventory { Validate.notNull(config.contains("member"), "Could not load member config"); empty = new SimplePlaceholderItem(config.getConfigurationSection("empty")); - member = new MemberDisplayItem(config.getConfigurationSection("member")); + member = new MemberDisplayItem(this, config.getConfigurationSection("member")); } @Override @@ -223,11 +223,15 @@ public class EditableGuildView extends EditableInventory { }); } - if (item.getFunction().equals("member") && event.getAction() == InventoryAction.PICKUP_HALF && !NBTItem.get(event.getCurrentItem()).getString("uuid").isEmpty()) { + if (item.getFunction().equals("member") && event.getAction() == InventoryAction.PICKUP_HALF) { if (!playerData.getGuild().getOwner().equals(playerData.getUniqueId())) return; - OfflinePlayer target = Bukkit.getOfflinePlayer(UUID.fromString(NBTItem.get(event.getCurrentItem()).getString("uuid"))); + String tag = event.getCurrentItem().getItemMeta().getPersistentDataContainer().get(UUID_NAMESPACEDKEY, PersistentDataType.STRING); + if (tag == null || tag.isEmpty()) + return; + + OfflinePlayer target = Bukkit.getOfflinePlayer(UUID.fromString(tag)); if (target.equals(player)) return; diff --git a/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java b/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java index a115dec2..ce442cf2 100644 --- a/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java +++ b/src/main/java/net/Indyuce/mmocore/gui/social/party/EditablePartyView.java @@ -1,7 +1,5 @@ package net.Indyuce.mmocore.gui.social.party; -import io.lumine.mythic.lib.api.item.ItemTag; -import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.util.input.PlayerInput.InputType; @@ -13,10 +11,7 @@ import net.Indyuce.mmocore.gui.api.item.Placeholders; import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; import net.Indyuce.mmocore.party.provided.Party; import org.apache.commons.lang.Validate; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.OfflinePlayer; -import org.bukkit.Sound; +import org.bukkit.*; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryAction; @@ -24,178 +19,178 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.persistence.PersistentDataType; import java.util.UUID; - public class EditablePartyView extends EditableInventory { - public EditablePartyView() { - super("party-view"); - } + private static final NamespacedKey UUID_NAMESPACEDKEY = new NamespacedKey(MMOCore.plugin, "Uuid"); - @Override - public InventoryItem load(String function, ConfigurationSection config) { - return function.equals("member") ? new MemberItem(config) : new SimplePlaceholderItem(config); - } + public EditablePartyView() { + super("party-view"); + } - public static class MemberDisplayItem extends InventoryItem { - public MemberDisplayItem(ConfigurationSection config) { - super(config); - } + @Override + public InventoryItem load(String function, ConfigurationSection config) { + return function.equals("member") ? new MemberItem(config) : new SimplePlaceholderItem(config); + } - @Override - public boolean hasDifferentDisplay() { - return true; - } + public static class MemberDisplayItem extends InventoryItem { + public MemberDisplayItem(MemberItem memberItem, ConfigurationSection config) { + super(memberItem, config); + } - @Override - public Placeholders getPlaceholders(GeneratedInventory inv, int n) { - Party party = (Party) inv.getPlayerData().getParty(); - PlayerData member = party.getMembers().get(n); + @Override + public boolean hasDifferentDisplay() { + return true; + } - Placeholders holders = new Placeholders(); - if (member.isOnline()) - holders.register("name", member.getPlayer().getName()); - holders.register("class", member.getProfess().getName()); - holders.register("level", "" + member.getLevel()); - holders.register("since", new DelayFormat(2).format(System.currentTimeMillis() - member.getLastLogin())); - return holders; - } + @Override + public Placeholders getPlaceholders(GeneratedInventory inv, int n) { + Party party = (Party) inv.getPlayerData().getParty(); + PlayerData member = party.getMembers().get(n); - @Override - public ItemStack display(GeneratedInventory inv, int n) { - Party party = (Party) inv.getPlayerData().getParty(); - PlayerData member = party.getMembers().get(n); + Placeholders holders = new Placeholders(); + if (member.isOnline()) + holders.register("name", member.getPlayer().getName()); + holders.register("class", member.getProfess().getName()); + holders.register("level", "" + member.getLevel()); + holders.register("since", new DelayFormat(2).format(System.currentTimeMillis() - member.getLastLogin())); + return holders; + } - ItemStack disp = super.display(inv, n); - ItemMeta meta = disp.getItemMeta(); + @Override + public ItemStack display(GeneratedInventory inv, int n) { + Party party = (Party) inv.getPlayerData().getParty(); + PlayerData member = party.getMembers().get(n); - /* - * run async to save performance - */ - if (meta instanceof SkullMeta) - Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> { - if (!member.isOnline()) return; - ((SkullMeta) meta).setOwningPlayer(member.getPlayer()); - disp.setItemMeta(meta); - }); + ItemStack disp = super.display(inv, n); + ItemMeta meta = disp.getItemMeta(); + meta.getPersistentDataContainer().set(UUID_NAMESPACEDKEY, PersistentDataType.STRING, member.getUniqueId().toString()); - return NBTItem.get(disp).addTag(new ItemTag("uuid", member.getUniqueId().toString())).toItem(); - } - } + if (meta instanceof SkullMeta) + inv.dynamicallyUpdateItem(this, n, disp, current -> { + ((SkullMeta) meta).setOwningPlayer(member.getPlayer()); + current.setItemMeta(meta); + }); - public static class MemberItem extends SimplePlaceholderItem { - private final InventoryItem empty; - private final MemberDisplayItem member; + disp.setItemMeta(meta); + return disp; + } + } - public MemberItem(ConfigurationSection config) { - super(Material.BARRIER, config); + public static class MemberItem extends SimplePlaceholderItem { + private final InventoryItem empty; + private final MemberDisplayItem member; - Validate.notNull(config.contains("empty"), "Could not load empty config"); - Validate.notNull(config.contains("member"), "Could not load member config"); + public MemberItem(ConfigurationSection config) { + super(Material.BARRIER, config); - empty = new SimplePlaceholderItem(config.getConfigurationSection("empty")); - member = new MemberDisplayItem(config.getConfigurationSection("member")); - } + Validate.notNull(config.contains("empty"), "Could not load empty config"); + Validate.notNull(config.contains("member"), "Could not load member config"); - @Override - public ItemStack display(GeneratedInventory inv, int n) { - Party party = (Party) inv.getPlayerData().getParty(); - return party.getMembers().size() > n ? member.display(inv, n) : empty.display(inv, n); - } + empty = new SimplePlaceholderItem(config.getConfigurationSection("empty")); + member = new MemberDisplayItem(this, config.getConfigurationSection("member")); + } - @Override - public boolean hasDifferentDisplay() { - return true; - } + @Override + public ItemStack display(GeneratedInventory inv, int n) { + Party party = (Party) inv.getPlayerData().getParty(); + return party.getMembers().size() > n ? member.display(inv, n) : empty.display(inv, n); + } - @Override - public boolean canDisplay(GeneratedInventory inv) { - return true; - } - } + @Override + public boolean hasDifferentDisplay() { + return true; + } - public GeneratedInventory newInventory(PlayerData data) { - return new PartyViewInventory(data, this); - } + @Override + public boolean canDisplay(GeneratedInventory inv) { + return true; + } + } - public class PartyViewInventory extends GeneratedInventory { - private final int max; + public GeneratedInventory newInventory(PlayerData data) { + return new PartyViewInventory(data, this); + } - public PartyViewInventory(PlayerData playerData, EditableInventory editable) { - super(playerData, editable); + public class PartyViewInventory extends GeneratedInventory { + private final int max; - max = editable.getByFunction("member").getSlots().size(); - } + public PartyViewInventory(PlayerData playerData, EditableInventory editable) { + super(playerData, editable); - @Override - public String calculateName() { - Party party = (Party) getPlayerData().getParty(); - return getName().replace("{max}", "" + max).replace("{players}", "" + party.getMembers().size()); - } + max = editable.getByFunction("member").getSlots().size(); + } - @Override - public void whenClicked(InventoryClickEvent event, InventoryItem item) { - Party party = (Party) playerData.getParty(); + @Override + public String calculateName() { + Party party = (Party) getPlayerData().getParty(); + return getName().replace("{max}", "" + max).replace("{players}", "" + party.getMembers().size()); + } - if (item.getFunction().equals("leave")) { - party.removeMember(playerData); - player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); - player.closeInventory(); - return; - } + @Override + public void whenClicked(InventoryClickEvent event, InventoryItem item) { + Party party = (Party) playerData.getParty(); - if (item.getFunction().equals("invite")) { + if (item.getFunction().equals("leave")) { + party.removeMember(playerData); + player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); + player.closeInventory(); + return; + } - if (party.getMembers().size() >= max) { - MMOCore.plugin.configManager.getSimpleMessage("party-is-full").send(player); - player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1); - return; - } + if (item.getFunction().equals("invite")) { - MMOCore.plugin.configManager.newPlayerInput(player, InputType.PARTY_INVITE, (input) -> { - Player target = Bukkit.getPlayer(input); - if (target == null) { - MMOCore.plugin.configManager.getSimpleMessage("not-online-player", "player", input).send(player); - player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1); - open(); - return; - } + if (party.getMembers().size() >= max) { + MMOCore.plugin.configManager.getSimpleMessage("party-is-full").send(player); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1); + return; + } - long remaining = party.getLastInvite(target) + 60 * 2 * 1000 - System.currentTimeMillis(); - if (remaining > 0) { - MMOCore.plugin.configManager.getSimpleMessage("party-invite-cooldown", "player", target.getName(), "cooldown", new DelayFormat().format(remaining)).send(player); - open(); - return; - } + MMOCore.plugin.configManager.newPlayerInput(player, InputType.PARTY_INVITE, (input) -> { + Player target = Bukkit.getPlayer(input); + if (target == null) { + MMOCore.plugin.configManager.getSimpleMessage("not-online-player", "player", input).send(player); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1); + open(); + return; + } - PlayerData targetData = PlayerData.get(target); - if (party.hasMember(target)) { - MMOCore.plugin.configManager.getSimpleMessage("already-in-party", "player", target.getName()).send(player); - player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1); - open(); - return; - } + long remaining = party.getLastInvite(target) + 60 * 2 * 1000 - System.currentTimeMillis(); + if (remaining > 0) { + MMOCore.plugin.configManager.getSimpleMessage("party-invite-cooldown", "player", target.getName(), "cooldown", new DelayFormat().format(remaining)).send(player); + open(); + return; + } - party.sendInvite(playerData, targetData); - MMOCore.plugin.configManager.getSimpleMessage("sent-party-invite", "player", target.getName()).send(player); - player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); - open(); - }); - } + PlayerData targetData = PlayerData.get(target); + if (party.hasMember(target)) { + MMOCore.plugin.configManager.getSimpleMessage("already-in-party", "player", target.getName()).send(player); + player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1); + open(); + return; + } - if (item.getFunction().equals("member") && event.getAction() == InventoryAction.PICKUP_HALF) { - if (!party.getOwner().equals(playerData)) - return; + party.sendInvite(playerData, targetData); + MMOCore.plugin.configManager.getSimpleMessage("sent-party-invite", "player", target.getName()).send(player); + player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); + open(); + }); + } - OfflinePlayer target = Bukkit.getOfflinePlayer(UUID.fromString(NBTItem.get(event.getCurrentItem()).getString("uuid"))); - if (target.equals(player)) - return; + if (item.getFunction().equals("member") && event.getAction() == InventoryAction.PICKUP_HALF) { + if (!party.getOwner().equals(playerData)) + return; - party.removeMember(PlayerData.get(target)); - MMOCore.plugin.configManager.getSimpleMessage("kick-from-party", "player", target.getName()).send(player); - player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); - } - } - } + OfflinePlayer target = Bukkit.getOfflinePlayer(UUID.fromString(event.getCurrentItem().getItemMeta().getPersistentDataContainer().get(UUID_NAMESPACEDKEY, PersistentDataType.STRING))); + if (target.equals(player)) + return; + + party.removeMember(PlayerData.get(target)); + MMOCore.plugin.configManager.getSimpleMessage("kick-from-party", "player", target.getName()).send(player); + player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); + } + } + } }