Fixed an issue with player head in parties/guilds/friends

This commit is contained in:
Indyuce 2022-03-20 16:38:49 +01:00
parent 5660a31d86
commit 045b349183
8 changed files with 416 additions and 389 deletions

View File

@ -200,13 +200,15 @@ public class PlayerStats extends EditableInventory {
@Override @Override
public ItemStack display(GeneratedInventory inv, int n) { public ItemStack display(GeneratedInventory inv, int n) {
ItemStack item = super.display(inv, n); ItemStack disp = super.display(inv, n);
if (item.getType() == VersionMaterial.PLAYER_HEAD.toMaterial()) { if (disp.getType() == VersionMaterial.PLAYER_HEAD.toMaterial()) {
SkullMeta meta = (SkullMeta) item.getItemMeta(); SkullMeta meta = (SkullMeta) disp.getItemMeta();
meta.setOwningPlayer(inv.getPlayer()); inv.dynamicallyUpdateItem(this, n, disp, current -> {
item.setItemMeta(meta); meta.setOwningPlayer(inv.getPlayer());
current.setItemMeta(meta);
});
} }
return item; return disp;
} }
@Override @Override

View File

@ -1,95 +1,112 @@
package net.Indyuce.mmocore.gui.api; package net.Indyuce.mmocore.gui.api;
import io.lumine.mythic.lib.MythicLib; import io.lumine.mythic.lib.MythicLib;
import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.gui.api.item.InventoryItem; import net.Indyuce.mmocore.gui.api.item.InventoryItem;
import net.Indyuce.mmocore.gui.api.item.TriggerItem; import net.Indyuce.mmocore.gui.api.item.TriggerItem;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
public abstract class GeneratedInventory extends PluginInventory { public abstract class GeneratedInventory extends PluginInventory {
private final EditableInventory editable; private final EditableInventory editable;
private final List<InventoryItem> loaded = new ArrayList<>(); private final List<InventoryItem> loaded = new ArrayList<>();
public GeneratedInventory(PlayerData playerData, EditableInventory editable) { private Inventory open;
super(playerData);
this.editable = editable; public GeneratedInventory(PlayerData playerData, EditableInventory editable) {
} super(playerData);
public List<InventoryItem> getLoaded() { this.editable = editable;
return loaded; }
}
public EditableInventory getEditable() { public List<InventoryItem> getLoaded() {
return editable; return loaded;
} }
public InventoryItem getByFunction(String function) { public EditableInventory getEditable() {
for (InventoryItem item : loaded) return editable;
if (item.getFunction().equals(function)) }
return item;
return null;
}
public InventoryItem getBySlot(int slot) { public InventoryItem getByFunction(String function) {
for (InventoryItem item : loaded) for (InventoryItem item : loaded)
if (item.getSlots().contains(slot)) if (item.getFunction().equals(function))
return item; return item;
return null; return null;
} }
/** public InventoryItem getBySlot(int slot) {
* This method must use an ordered collection because for (InventoryItem item : loaded)
* of GUI items overriding possibilities. Hence the use if (item.getSlots().contains(slot))
* of an array list instead of a set return item;
*/ return null;
public void addLoaded(InventoryItem item) { }
loaded.add(0, item);
}
@Override /**
public Inventory getInventory() { * This method must use an ordered collection because
Inventory inv = Bukkit.createInventory(this, editable.getSlots(), MythicLib.plugin.parseColors(calculateName())); * 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()) @Override
if (item.canDisplay(this)) public Inventory getInventory() {
item.setDisplayed(inv, this); 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;
}
/* public void open() {
* 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();
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) { getPlayer().openInventory(open = getInventory());
event.setCancelled(true); }
if (event.getClickedInventory() != null && event.getClickedInventory().equals(event.getInventory())) { /**
InventoryItem item = getBySlot(event.getSlot()); * @deprecated Not a fan of that implementation.
if (item == null) * Better work with {@link InventoryItem#setDisplayed(Inventory, GeneratedInventory)}
return; */
@Deprecated
public void dynamicallyUpdateItem(InventoryItem<?> item, int n, ItemStack placed, Consumer<ItemStack> update) {
Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> {
update.accept(placed);
open.setItem(item.getSlots().get(n), placed);
});
}
if (item instanceof TriggerItem) public void whenClicked(InventoryClickEvent event) {
((TriggerItem) item).getTrigger().apply(getPlayerData()); event.setCancelled(true);
else
whenClicked(event, item);
}
}
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);
} }

View File

@ -13,6 +13,8 @@ import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
@ -21,147 +23,160 @@ import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
public abstract class InventoryItem<T extends GeneratedInventory> { public abstract class InventoryItem<T extends GeneratedInventory> {
private final String id, function; private final String id, function;
private final List<Integer> slots = new ArrayList<>(); private final List<Integer> slots = new ArrayList<>();
private final Material material; @Nullable
private final String name, texture; private final InventoryItem<?> parent;
private final List<String> lore;
private final int modelData;
private final boolean placeholders, hideFlags;
public InventoryItem(ConfigurationSection config) { private final Material material;
this(Material.valueOf(config.getString("item", "").toUpperCase().replace(" ", "_").replace("-", "_")), config); private final String name, texture;
} private final List<String> lore;
private final int modelData;
private final boolean hideFlags;
public InventoryItem(Material material, ConfigurationSection config) { public InventoryItem(ConfigurationSection config) {
this.id = config.getName(); this((InventoryItem) null, config);
this.function = config.getString("function", ""); }
this.material = material; public InventoryItem(@Nullable InventoryItem<?> parent, ConfigurationSection config) {
this.name = config.getString("name"); this(parent, Material.valueOf(config.getString("item", "").toUpperCase().replace(" ", "_").replace("-", "_")), config);
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");
config.getStringList("slots").forEach(str -> slots.add(Integer.parseInt(str))); public InventoryItem(@NotNull Material material, ConfigurationSection config) {
} this(null, material, config);
}
public String getId() { public InventoryItem(InventoryItem parent, Material material, ConfigurationSection config) {
return id; this.id = config.getName();
} this.function = config.getString("function", "");
this.parent = parent;
public String getFunction() { this.material = material;
return function; 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() { config.getStringList("slots").forEach(str -> slots.add(Integer.parseInt(str)));
return !function.isEmpty(); }
}
public List<Integer> getSlots() { public String getId() {
return slots; return id;
} }
public Material getMaterial() { @NotNull
return material; public String getFunction() {
} return parent == null ? function : parent.function;
}
public boolean hideFlags() { public boolean hasFunction() {
return hideFlags; return !getFunction().isEmpty();
} }
public boolean hasName() { @NotNull
return name != null; public List<Integer> getSlots() {
} return parent == null ? slots : parent.slots;
}
public String getName() { public Material getMaterial() {
return name; return material;
} }
public boolean hasLore() { public boolean hideFlags() {
return lore != null && !lore.isEmpty(); return hideFlags;
} }
public List<String> getLore() { public boolean hasName() {
return lore; return name != null;
} }
public int getModelData() { public String getName() {
return modelData; return name;
} }
public void setDisplayed(Inventory inv, T generated) { public boolean hasLore() {
generated.addLoaded(this); return lore != null && !lore.isEmpty();
}
if (!hasDifferentDisplay()) { public List<String> getLore() {
ItemStack display = display(generated); return lore;
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 int getModelData() {
return modelData;
}
public boolean hasDifferentDisplay() { public void setDisplayed(Inventory inv, T generated) {
return false; generated.addLoaded(this);
}
public boolean canDisplay(T inv) { if (!hasDifferentDisplay()) {
return true; 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); public boolean canDisplay(T inv) {
ItemStack item = new ItemStack(material); return true;
ItemMeta meta = item.getItemMeta(); }
if (texture != null && meta instanceof SkullMeta) public ItemStack display(T inv) {
applyTexture(texture, (SkullMeta) meta); return display(inv, 0);
}
if (hasName()) public ItemStack display(T inv, int n) {
meta.setDisplayName(placeholders.apply(inv.getPlayer(), getName()));
if (hideFlags()) Placeholders placeholders = getPlaceholders(inv, n);
meta.addItemFlags(ItemFlag.values()); ItemStack item = new ItemStack(material);
ItemMeta meta = item.getItemMeta();
if (hasLore()) { if (texture != null && meta instanceof SkullMeta)
List<String> lore = new ArrayList<>(); applyTexture(texture, (SkullMeta) meta);
getLore().forEach(line -> lore.add(ChatColor.GRAY + placeholders.apply(inv.getPlayer(), line)));
meta.setLore(lore);
}
if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13)) if (hasName())
meta.setCustomModelData(getModelData()); meta.setDisplayName(placeholders.apply(inv.getPlayer(), getName()));
item.setItemMeta(meta); if (hideFlags())
return item; meta.addItemFlags(ItemFlag.values());
}
private void applyTexture(String value, SkullMeta meta) { if (hasLore()) {
try { List<String> lore = new ArrayList<>();
GameProfile profile = new GameProfile(UUID.randomUUID(), null); getLore().forEach(line -> lore.add(ChatColor.GRAY + placeholders.apply(inv.getPlayer(), line)));
profile.getProperties().put("textures", new Property("textures", value)); meta.setLore(lore);
}
Field profileField = meta.getClass().getDeclaredField("profile"); if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13))
profileField.setAccessible(true); meta.setCustomModelData(getModelData());
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) { item.setItemMeta(meta);
return getPlaceholders(inv, 0); 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);
} }

View File

@ -5,6 +5,10 @@ import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
public class SimplePlaceholderItem<T extends GeneratedInventory> extends InventoryItem<T> { public class SimplePlaceholderItem<T extends GeneratedInventory> extends InventoryItem<T> {
public SimplePlaceholderItem(InventoryItem<?> parent, ConfigurationSection config) {
super(parent, config);
}
public SimplePlaceholderItem(ConfigurationSection config) { public SimplePlaceholderItem(ConfigurationSection config) {
super(config); super(config);
} }

View File

@ -1,7 +1,5 @@
package net.Indyuce.mmocore.gui.social.friend; 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.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerActivity; import net.Indyuce.mmocore.api.player.PlayerActivity;
import net.Indyuce.mmocore.api.player.PlayerData; 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 net.Indyuce.mmocore.manager.InventoryManager;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
@ -24,10 +23,13 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.persistence.PersistentDataType;
import java.util.UUID; import java.util.UUID;
public class EditableFriendList extends EditableInventory { public class EditableFriendList extends EditableInventory {
private static final NamespacedKey UUID_NAMESPACEDKEY = new NamespacedKey(MMOCore.plugin, "Uuid");
public EditableFriendList() { public EditableFriendList() {
super("friend-list"); super("friend-list");
} }
@ -64,8 +66,8 @@ public class EditableFriendList extends EditableInventory {
} }
public static class OfflineFriendItem extends InventoryItem { public static class OfflineFriendItem extends InventoryItem {
public OfflineFriendItem(ConfigurationSection config) { public OfflineFriendItem(FriendItem parent, ConfigurationSection config) {
super(config); super(parent, config);
} }
@Override @Override
@ -82,27 +84,11 @@ public class EditableFriendList extends EditableInventory {
holders.register("last_seen", new DelayFormat(2).format(System.currentTimeMillis() - friend.getLastPlayed())); holders.register("last_seen", new DelayFormat(2).format(System.currentTimeMillis() - friend.getLastPlayed()));
return holders; 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 static class OnlineFriendItem extends SimplePlaceholderItem {
public OnlineFriendItem(ConfigurationSection config) { public OnlineFriendItem(FriendItem parent, ConfigurationSection config) {
super(config); super(parent, config);
} }
@Override @Override
@ -123,22 +109,6 @@ public class EditableFriendList extends EditableInventory {
holders.register("online_since", new DelayFormat(2).format(System.currentTimeMillis() - data.getLastLogin())); holders.register("online_since", new DelayFormat(2).format(System.currentTimeMillis() - data.getLastLogin()));
return holders; 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 { 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("online"), "Could not load online config");
Validate.notNull(config.contains("offline"), "Could not load offline config"); Validate.notNull(config.contains("offline"), "Could not load offline config");
online = new OnlineFriendItem(config.getConfigurationSection("online")); online = new OnlineFriendItem(this, config.getConfigurationSection("online"));
offline = new OfflineFriendItem(config.getConfigurationSection("offline")); offline = new OfflineFriendItem(this, config.getConfigurationSection("offline"));
} }
@Override @Override
public ItemStack display(GeneratedInventory inv, int n) { public ItemStack display(GeneratedInventory inv, int n) {
return inv.getPlayerData().getFriends().size() <= n ? super.display(inv, n) if (inv.getPlayerData().getFriends().size() <= n)
: Bukkit.getOfflinePlayer(inv.getPlayerData().getFriends().get(n)).isOnline() ? online.display(inv, n) : offline.display(inv, 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 @Override
@ -238,7 +222,7 @@ public class EditableFriendList extends EditableInventory {
} }
if (item.getFunction().equals("friend") && event.getAction() == InventoryAction.PICKUP_HALF) { 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()) if (tag == null || tag.isEmpty())
return; return;

View File

@ -13,6 +13,7 @@ import net.Indyuce.mmocore.gui.api.item.Placeholders;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
@ -22,10 +23,13 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.persistence.PersistentDataType;
import java.util.UUID; import java.util.UUID;
public class EditableGuildAdmin extends EditableInventory { public class EditableGuildAdmin extends EditableInventory {
private static final NamespacedKey UUID_NAMESPACEDKEY = new NamespacedKey(MMOCore.plugin, "Uuid");
public EditableGuildAdmin() { public EditableGuildAdmin() {
super("guild-admin"); super("guild-admin");
} }
@ -40,8 +44,8 @@ public class EditableGuildAdmin extends EditableInventory {
} }
public static class MemberDisplayItem extends InventoryItem { public static class MemberDisplayItem extends InventoryItem {
public MemberDisplayItem(ConfigurationSection config) { public MemberDisplayItem(MemberItem memberItem, ConfigurationSection config) {
super(config); super(memberItem, config);
} }
@Override @Override
@ -65,19 +69,21 @@ public class EditableGuildAdmin extends EditableInventory {
@Override @Override
public ItemStack display(GeneratedInventory inv, int n) { 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); ItemStack disp = super.display(inv, n);
ItemMeta meta = disp.getItemMeta(); ItemMeta meta = disp.getItemMeta();
meta.getPersistentDataContainer().set(UUID_NAMESPACEDKEY, PersistentDataType.STRING, uuid.toString());
if (meta instanceof SkullMeta) if (meta instanceof SkullMeta && offlinePlayer != null)
Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> { inv.dynamicallyUpdateItem(this, n, disp, current -> {
if (!member.isOnline()) return; ((SkullMeta) meta).setOwningPlayer(offlinePlayer);
((SkullMeta) meta).setOwningPlayer(member.getPlayer()); current.setItemMeta(meta);
disp.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"); Validate.notNull(config.contains("member"), "Could not load member config");
empty = new SimplePlaceholderItem(config.getConfigurationSection("empty")); empty = new SimplePlaceholderItem(config.getConfigurationSection("empty"));
member = new MemberDisplayItem(config.getConfigurationSection("member")); member = new MemberDisplayItem(this, config.getConfigurationSection("member"));
} }
@Override @Override
@ -174,7 +180,7 @@ public class EditableGuildAdmin extends EditableInventory {
if (!playerData.getGuild().getOwner().equals(playerData.getUniqueId())) if (!playerData.getGuild().getOwner().equals(playerData.getUniqueId()))
return; 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)) if (target.equals(player))
return; return;

View File

@ -1,7 +1,5 @@
package net.Indyuce.mmocore.gui.social.guild; 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.MMOCore;
import net.Indyuce.mmocore.api.player.OfflinePlayerData; import net.Indyuce.mmocore.api.player.OfflinePlayerData;
import net.Indyuce.mmocore.api.player.PlayerData; 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.Placeholders;
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem; import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit; import org.bukkit.*;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.Sound;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryAction; 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.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.persistence.PersistentDataType;
import java.util.UUID; import java.util.UUID;
public class EditableGuildView extends EditableInventory { public class EditableGuildView extends EditableInventory {
private static final NamespacedKey UUID_NAMESPACEDKEY = new NamespacedKey(MMOCore.plugin, "Uuid");
public EditableGuildView() { public EditableGuildView() {
super("guild-view"); super("guild-view");
} }
@ -38,8 +36,8 @@ public class EditableGuildView extends EditableInventory {
} }
public static class MemberDisplayItem extends InventoryItem { public static class MemberDisplayItem extends InventoryItem {
public MemberDisplayItem(ConfigurationSection config) { public MemberDisplayItem(MemberItem memberItem, ConfigurationSection config) {
super(config); super(memberItem, config);
} }
@Override @Override
@ -71,14 +69,16 @@ public class EditableGuildView extends EditableInventory {
ItemStack disp = super.display(inv, n); ItemStack disp = super.display(inv, n);
ItemMeta meta = disp.getItemMeta(); ItemMeta meta = disp.getItemMeta();
meta.getPersistentDataContainer().set(UUID_NAMESPACEDKEY, PersistentDataType.STRING, uuid.toString());
if (meta instanceof SkullMeta) if (meta instanceof SkullMeta)
Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> { inv.dynamicallyUpdateItem(this, n, disp, current -> {
((SkullMeta) meta).setOwningPlayer(Bukkit.getOfflinePlayer(uuid)); ((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"); Validate.notNull(config.contains("member"), "Could not load member config");
empty = new SimplePlaceholderItem(config.getConfigurationSection("empty")); empty = new SimplePlaceholderItem(config.getConfigurationSection("empty"));
member = new MemberDisplayItem(config.getConfigurationSection("member")); member = new MemberDisplayItem(this, config.getConfigurationSection("member"));
} }
@Override @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())) if (!playerData.getGuild().getOwner().equals(playerData.getUniqueId()))
return; 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)) if (target.equals(player))
return; return;

View File

@ -1,7 +1,5 @@
package net.Indyuce.mmocore.gui.social.party; 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.MMOCore;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.util.input.PlayerInput.InputType; 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.gui.api.item.SimplePlaceholderItem;
import net.Indyuce.mmocore.party.provided.Party; import net.Indyuce.mmocore.party.provided.Party;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit; import org.bukkit.*;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.Sound;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryAction; 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.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.persistence.PersistentDataType;
import java.util.UUID; import java.util.UUID;
public class EditablePartyView extends EditableInventory { public class EditablePartyView extends EditableInventory {
public EditablePartyView() { private static final NamespacedKey UUID_NAMESPACEDKEY = new NamespacedKey(MMOCore.plugin, "Uuid");
super("party-view");
}
@Override public EditablePartyView() {
public InventoryItem load(String function, ConfigurationSection config) { super("party-view");
return function.equals("member") ? new MemberItem(config) : new SimplePlaceholderItem(config); }
}
public static class MemberDisplayItem extends InventoryItem { @Override
public MemberDisplayItem(ConfigurationSection config) { public InventoryItem load(String function, ConfigurationSection config) {
super(config); return function.equals("member") ? new MemberItem(config) : new SimplePlaceholderItem(config);
} }
@Override public static class MemberDisplayItem extends InventoryItem {
public boolean hasDifferentDisplay() { public MemberDisplayItem(MemberItem memberItem, ConfigurationSection config) {
return true; super(memberItem, config);
} }
@Override @Override
public Placeholders getPlaceholders(GeneratedInventory inv, int n) { public boolean hasDifferentDisplay() {
Party party = (Party) inv.getPlayerData().getParty(); return true;
PlayerData member = party.getMembers().get(n); }
Placeholders holders = new Placeholders(); @Override
if (member.isOnline()) public Placeholders getPlaceholders(GeneratedInventory inv, int n) {
holders.register("name", member.getPlayer().getName()); Party party = (Party) inv.getPlayerData().getParty();
holders.register("class", member.getProfess().getName()); PlayerData member = party.getMembers().get(n);
holders.register("level", "" + member.getLevel());
holders.register("since", new DelayFormat(2).format(System.currentTimeMillis() - member.getLastLogin()));
return holders;
}
@Override Placeholders holders = new Placeholders();
public ItemStack display(GeneratedInventory inv, int n) { if (member.isOnline())
Party party = (Party) inv.getPlayerData().getParty(); holders.register("name", member.getPlayer().getName());
PlayerData member = party.getMembers().get(n); 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); @Override
ItemMeta meta = disp.getItemMeta(); public ItemStack display(GeneratedInventory inv, int n) {
Party party = (Party) inv.getPlayerData().getParty();
PlayerData member = party.getMembers().get(n);
/* ItemStack disp = super.display(inv, n);
* run async to save performance ItemMeta meta = disp.getItemMeta();
*/ meta.getPersistentDataContainer().set(UUID_NAMESPACEDKEY, PersistentDataType.STRING, member.getUniqueId().toString());
if (meta instanceof SkullMeta)
Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> {
if (!member.isOnline()) return;
((SkullMeta) meta).setOwningPlayer(member.getPlayer());
disp.setItemMeta(meta);
});
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 { disp.setItemMeta(meta);
private final InventoryItem empty; return disp;
private final MemberDisplayItem member; }
}
public MemberItem(ConfigurationSection config) { public static class MemberItem extends SimplePlaceholderItem {
super(Material.BARRIER, config); private final InventoryItem empty;
private final MemberDisplayItem member;
Validate.notNull(config.contains("empty"), "Could not load empty config"); public MemberItem(ConfigurationSection config) {
Validate.notNull(config.contains("member"), "Could not load member config"); super(Material.BARRIER, config);
empty = new SimplePlaceholderItem(config.getConfigurationSection("empty")); Validate.notNull(config.contains("empty"), "Could not load empty config");
member = new MemberDisplayItem(config.getConfigurationSection("member")); Validate.notNull(config.contains("member"), "Could not load member config");
}
@Override empty = new SimplePlaceholderItem(config.getConfigurationSection("empty"));
public ItemStack display(GeneratedInventory inv, int n) { member = new MemberDisplayItem(this, config.getConfigurationSection("member"));
Party party = (Party) inv.getPlayerData().getParty(); }
return party.getMembers().size() > n ? member.display(inv, n) : empty.display(inv, n);
}
@Override @Override
public boolean hasDifferentDisplay() { public ItemStack display(GeneratedInventory inv, int n) {
return true; Party party = (Party) inv.getPlayerData().getParty();
} return party.getMembers().size() > n ? member.display(inv, n) : empty.display(inv, n);
}
@Override @Override
public boolean canDisplay(GeneratedInventory inv) { public boolean hasDifferentDisplay() {
return true; return true;
} }
}
public GeneratedInventory newInventory(PlayerData data) { @Override
return new PartyViewInventory(data, this); public boolean canDisplay(GeneratedInventory inv) {
} return true;
}
}
public class PartyViewInventory extends GeneratedInventory { public GeneratedInventory newInventory(PlayerData data) {
private final int max; return new PartyViewInventory(data, this);
}
public PartyViewInventory(PlayerData playerData, EditableInventory editable) { public class PartyViewInventory extends GeneratedInventory {
super(playerData, editable); private final int max;
max = editable.getByFunction("member").getSlots().size(); public PartyViewInventory(PlayerData playerData, EditableInventory editable) {
} super(playerData, editable);
@Override max = editable.getByFunction("member").getSlots().size();
public String calculateName() { }
Party party = (Party) getPlayerData().getParty();
return getName().replace("{max}", "" + max).replace("{players}", "" + party.getMembers().size());
}
@Override @Override
public void whenClicked(InventoryClickEvent event, InventoryItem item) { public String calculateName() {
Party party = (Party) playerData.getParty(); Party party = (Party) getPlayerData().getParty();
return getName().replace("{max}", "" + max).replace("{players}", "" + party.getMembers().size());
}
if (item.getFunction().equals("leave")) { @Override
party.removeMember(playerData); public void whenClicked(InventoryClickEvent event, InventoryItem item) {
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); Party party = (Party) playerData.getParty();
player.closeInventory();
return;
}
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) { if (item.getFunction().equals("invite")) {
MMOCore.plugin.configManager.getSimpleMessage("party-is-full").send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1);
return;
}
MMOCore.plugin.configManager.newPlayerInput(player, InputType.PARTY_INVITE, (input) -> { if (party.getMembers().size() >= max) {
Player target = Bukkit.getPlayer(input); MMOCore.plugin.configManager.getSimpleMessage("party-is-full").send(player);
if (target == null) { player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1);
MMOCore.plugin.configManager.getSimpleMessage("not-online-player", "player", input).send(player); return;
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1); }
open();
return;
}
long remaining = party.getLastInvite(target) + 60 * 2 * 1000 - System.currentTimeMillis(); MMOCore.plugin.configManager.newPlayerInput(player, InputType.PARTY_INVITE, (input) -> {
if (remaining > 0) { Player target = Bukkit.getPlayer(input);
MMOCore.plugin.configManager.getSimpleMessage("party-invite-cooldown", "player", target.getName(), "cooldown", new DelayFormat().format(remaining)).send(player); if (target == null) {
open(); MMOCore.plugin.configManager.getSimpleMessage("not-online-player", "player", input).send(player);
return; player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1);
} open();
return;
}
PlayerData targetData = PlayerData.get(target); long remaining = party.getLastInvite(target) + 60 * 2 * 1000 - System.currentTimeMillis();
if (party.hasMember(target)) { if (remaining > 0) {
MMOCore.plugin.configManager.getSimpleMessage("already-in-party", "player", target.getName()).send(player); MMOCore.plugin.configManager.getSimpleMessage("party-invite-cooldown", "player", target.getName(), "cooldown", new DelayFormat().format(remaining)).send(player);
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1); open();
open(); return;
return; }
}
party.sendInvite(playerData, targetData); PlayerData targetData = PlayerData.get(target);
MMOCore.plugin.configManager.getSimpleMessage("sent-party-invite", "player", target.getName()).send(player); if (party.hasMember(target)) {
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); MMOCore.plugin.configManager.getSimpleMessage("already-in-party", "player", target.getName()).send(player);
open(); player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1);
}); open();
} return;
}
if (item.getFunction().equals("member") && event.getAction() == InventoryAction.PICKUP_HALF) { party.sendInvite(playerData, targetData);
if (!party.getOwner().equals(playerData)) MMOCore.plugin.configManager.getSimpleMessage("sent-party-invite", "player", target.getName()).send(player);
return; 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 (item.getFunction().equals("member") && event.getAction() == InventoryAction.PICKUP_HALF) {
if (target.equals(player)) if (!party.getOwner().equals(playerData))
return; return;
party.removeMember(PlayerData.get(target)); OfflinePlayer target = Bukkit.getOfflinePlayer(UUID.fromString(event.getCurrentItem().getItemMeta().getPersistentDataContainer().get(UUID_NAMESPACEDKEY, PersistentDataType.STRING)));
MMOCore.plugin.configManager.getSimpleMessage("kick-from-party", "player", target.getName()).send(player); if (target.equals(player))
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1, 1); 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);
}
}
}
} }