mirror of
https://gitlab.com/phoenix-dvpmt/mmoitems.git
synced 2024-12-22 04:37:42 +01:00
Fixed 1.20+ skull texture application
This commit is contained in:
parent
79bb6d2d3c
commit
5de2a0003f
@ -1,19 +1,14 @@
|
||||
package net.Indyuce.mmoitems.api.item.util;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.UtilityMethods;
|
||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||
import io.lumine.mythic.lib.util.AdventureUtils;
|
||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CustomSkull extends ConfigItem {
|
||||
@ -31,19 +26,11 @@ public class CustomSkull extends ConfigItem {
|
||||
|
||||
public void updateItem() {
|
||||
setItem(VersionMaterial.PLAYER_HEAD.toItem());
|
||||
ItemMeta meta = getItem().getItemMeta();
|
||||
SkullMeta meta = (SkullMeta) getItem().getItemMeta();
|
||||
AdventureUtils.setDisplayName(meta, getName());
|
||||
meta.addItemFlags(ItemFlag.values());
|
||||
|
||||
GameProfile gameProfile = new GameProfile(UUID.randomUUID(), "SkullTexture");
|
||||
gameProfile.getProperties().put("textures", new Property("textures", textureValue));
|
||||
try {
|
||||
Field profileField = meta.getClass().getDeclaredField("profile");
|
||||
profileField.setAccessible(true);
|
||||
profileField.set(meta, gameProfile);
|
||||
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException exception) {
|
||||
MMOItems.plugin.getLogger().log(Level.WARNING, "Could not load skull texture");
|
||||
}
|
||||
UtilityMethods.setTextureValue(meta, textureValue);
|
||||
|
||||
if (hasLore())
|
||||
AdventureUtils.setLore(meta, getLore()
|
||||
|
@ -1,9 +1,9 @@
|
||||
package net.Indyuce.mmoitems.api.util;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
@ -20,12 +20,8 @@ import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.LeatherArmorMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class NoClipItem implements Listener {
|
||||
private final Item item;
|
||||
@ -115,18 +111,11 @@ public class NoClipItem implements Listener {
|
||||
}
|
||||
|
||||
// Copy Skull textures
|
||||
if (oldItem.getItemMeta() instanceof SkullMeta) {
|
||||
try {
|
||||
final Field oldProfileField = oldItem.getItemMeta().getClass().getDeclaredField("profile");
|
||||
oldProfileField.setAccessible(true);
|
||||
final GameProfile oldProfile = (GameProfile) oldProfileField.get(oldItem.getItemMeta());
|
||||
|
||||
final Field profileField = newItemMeta.getClass().getDeclaredField("profile");
|
||||
profileField.setAccessible(true);
|
||||
profileField.set(newItemMeta, oldProfile);
|
||||
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException exception) {
|
||||
MMOItems.plugin.getLogger().log(Level.WARNING, "Could not set skull texture on stripItemData method in the NoClipItem class. Please report this issue!");
|
||||
}
|
||||
if (oldItem.getItemMeta() instanceof SkullMeta) try {
|
||||
final Object oldProfile = MythicLib.plugin.getVersion().getWrapper().getProfile((SkullMeta) oldItem.getItemMeta());
|
||||
MythicLib.plugin.getVersion().getWrapper().setProfile((SkullMeta) newItemMeta, oldProfile);
|
||||
} catch (RuntimeException exception) {
|
||||
MMOItems.plugin.getLogger().log(Level.WARNING, "Could not set skull texture on stripItemData method in the NoClipItem class. Please report this issue!");
|
||||
}
|
||||
|
||||
// Copy Leather colors
|
||||
|
@ -1,7 +1,6 @@
|
||||
package net.Indyuce.mmoitems.stat;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||
import io.lumine.mythic.lib.api.util.AltChar;
|
||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||
@ -12,111 +11,110 @@ import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem;
|
||||
import net.Indyuce.mmoitems.gui.edition.EditionInventory;
|
||||
import net.Indyuce.mmoitems.stat.data.SkullTextureData;
|
||||
import net.Indyuce.mmoitems.stat.data.random.RandomStatData;
|
||||
import net.Indyuce.mmoitems.stat.data.type.StatData;
|
||||
import net.Indyuce.mmoitems.stat.type.ItemStat;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
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;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SkullTextureStat extends ItemStat<SkullTextureData, SkullTextureData> {
|
||||
public SkullTextureStat() {
|
||||
super("SKULL_TEXTURE", VersionMaterial.PLAYER_HEAD.toMaterial(), "Skull Texture",
|
||||
new String[] { "The head texture &nvalue&7.", "Can be found on heads databases." }, new String[] { "all" },
|
||||
VersionMaterial.PLAYER_HEAD.toMaterial());
|
||||
}
|
||||
public SkullTextureStat() {
|
||||
super("SKULL_TEXTURE", VersionMaterial.PLAYER_HEAD.toMaterial(), "Skull Texture", new String[]{"The skull texture &nvalue&7.", "Can be found on head databases."}, new String[]{"all"}, VersionMaterial.PLAYER_HEAD.toMaterial());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkullTextureData whenInitialized(Object object) {
|
||||
Validate.isTrue(object instanceof ConfigurationSection, "Must specify a config section");
|
||||
ConfigurationSection config = (ConfigurationSection) object;
|
||||
@Override
|
||||
public SkullTextureData whenInitialized(Object object) {
|
||||
Validate.isTrue(object instanceof ConfigurationSection, "Must specify a config section");
|
||||
ConfigurationSection config = (ConfigurationSection) object;
|
||||
|
||||
String value = config.getString("value");
|
||||
Validate.notNull(value, "Could not load skull texture value");
|
||||
final String value = config.getString("value");
|
||||
Validate.notNull(value, "Could not load skull texture value");
|
||||
|
||||
String format = config.getString("uuid");
|
||||
Validate.notNull(format, "Could not find skull texture UUID: re-enter your skull texture value and one will be selected randomly.");
|
||||
final String uuid = config.getString("uuid");
|
||||
Validate.notNull(uuid, "Could not find skull texture UUID: re-enter your skull texture value and one will be selected randomly.");
|
||||
|
||||
SkullTextureData skullTexture = new SkullTextureData(new GameProfile(UUID.fromString(format), "SkullTexture"));
|
||||
skullTexture.getGameProfile().getProperties().put("textures", new Property("textures", value));
|
||||
return skullTexture;
|
||||
}
|
||||
final Object profile = MythicLib.plugin.getVersion().getWrapper().newProfile(UUID.fromString(uuid), value);
|
||||
final SkullTextureData skullTexture = new SkullTextureData(profile);
|
||||
return skullTexture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenDisplayed(List<String> lore, Optional<SkullTextureData> statData) {
|
||||
lore.add(ChatColor.GRAY + "Current Value: " + (statData.isPresent() ? ChatColor.GREEN + "Texture value provided" : ChatColor.RED + "None"));
|
||||
lore.add("");
|
||||
lore.add(ChatColor.YELLOW + AltChar.listDash + " Left click to change this value.");
|
||||
lore.add(ChatColor.YELLOW + AltChar.listDash + " Right click to remove this value.");
|
||||
}
|
||||
@Override
|
||||
public void whenDisplayed(List<String> lore, Optional<SkullTextureData> statData) {
|
||||
lore.add(ChatColor.GRAY + "Current Value: " + (statData.isPresent() ? ChatColor.GREEN + "Texture value provided" : ChatColor.RED + "None"));
|
||||
lore.add("");
|
||||
lore.add(ChatColor.YELLOW + AltChar.listDash + " Left click to change this value.");
|
||||
lore.add(ChatColor.YELLOW + AltChar.listDash + " Right click to remove this value.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenInput(@NotNull EditionInventory inv, @NotNull String message, Object... info) {
|
||||
inv.getEditedSection().set("skull-texture.value", message);
|
||||
inv.getEditedSection().set("skull-texture.uuid", UUID.randomUUID().toString());
|
||||
inv.registerTemplateEdition();
|
||||
inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + getName() + " successfully changed to " + message + ".");
|
||||
}
|
||||
@Override
|
||||
public void whenInput(@NotNull EditionInventory inv, @NotNull String message, Object... info) {
|
||||
inv.getEditedSection().set("skull-texture.value", message);
|
||||
inv.getEditedSection().set("skull-texture.uuid", UUID.randomUUID().toString());
|
||||
inv.registerTemplateEdition();
|
||||
inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + getName() + " successfully changed to " + message + ".");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenApplied(@NotNull ItemStackBuilder item, @NotNull SkullTextureData data) {
|
||||
if (item.getItemStack().getType() != VersionMaterial.PLAYER_HEAD.toMaterial())
|
||||
return;
|
||||
@Override
|
||||
public void whenApplied(@NotNull ItemStackBuilder item, @NotNull SkullTextureData data) {
|
||||
if (item.getItemStack().getType() != VersionMaterial.PLAYER_HEAD.toMaterial()) return;
|
||||
|
||||
try {
|
||||
Field profileField = item.getMeta().getClass().getDeclaredField("profile");
|
||||
profileField.setAccessible(true);
|
||||
profileField.set(item.getMeta(), ((SkullTextureData) data).getGameProfile());
|
||||
} catch (NoSuchFieldException | IllegalAccessException exception) {
|
||||
throw new IllegalArgumentException(exception.getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* This stat is saved not as a custom tag, but as the vanilla HideFlag itself.
|
||||
* Alas this is an empty array
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrayList<ItemTag> getAppliedNBT(@NotNull SkullTextureData data) { return new ArrayList<>(); }
|
||||
if (data.getGameProfile() != null)
|
||||
MythicLib.plugin.getVersion().getWrapper().setProfile((SkullMeta) item.getMeta(), data.getGameProfile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenClicked(@NotNull EditionInventory inv, @NotNull InventoryClickEvent event) {
|
||||
if (event.getAction() == InventoryAction.PICKUP_HALF) {
|
||||
inv.getEditedSection().set(getPath(), null);
|
||||
inv.registerTemplateEdition();
|
||||
inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "Successfully removed " + getName() + ".");
|
||||
} else
|
||||
new StatEdition(inv, this).enable("Write in the chat the text you want.");
|
||||
}
|
||||
/**
|
||||
* This stat is saved not as a custom tag, but as the vanilla HideFlag itself.
|
||||
* Alas this is an empty array
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrayList<ItemTag> getAppliedNBT(@NotNull SkullTextureData data) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenLoaded(@NotNull ReadMMOItem mmoitem) {
|
||||
try {
|
||||
Field profileField = mmoitem.getNBT().getItem().getItemMeta().getClass().getDeclaredField("profile");
|
||||
profileField.setAccessible(true);
|
||||
mmoitem.setData(ItemStats.SKULL_TEXTURE, new SkullTextureData((GameProfile) profileField.get(mmoitem.getNBT().getItem().getItemMeta())));
|
||||
} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException ignored) {}
|
||||
}
|
||||
@Override
|
||||
public void whenClicked(@NotNull EditionInventory inv, @NotNull InventoryClickEvent event) {
|
||||
if (event.getAction() == InventoryAction.PICKUP_HALF) {
|
||||
inv.getEditedSection().set(getPath(), null);
|
||||
inv.registerTemplateEdition();
|
||||
inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + "Successfully removed " + getName() + ".");
|
||||
} else new StatEdition(inv, this).enable("Write in the chat the text you want.");
|
||||
}
|
||||
|
||||
/**
|
||||
* This stat is saved not as a custom tag, but as the vanilla Head Texture itself.
|
||||
* Alas this method returns null.
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public SkullTextureData getLoadedNBT(@NotNull ArrayList<ItemTag> storedTags) { return null; }
|
||||
@Override
|
||||
public void whenLoaded(@NotNull ReadMMOItem mmoitem) {
|
||||
try {
|
||||
final ItemMeta meta = mmoitem.getNBT().getItem().getItemMeta();
|
||||
Validate.isTrue(meta instanceof SkullMeta);
|
||||
final Object profile = MythicLib.plugin.getVersion().getWrapper().getProfile((SkullMeta) meta);
|
||||
mmoitem.setData(ItemStats.SKULL_TEXTURE, new SkullTextureData(profile));
|
||||
} catch (RuntimeException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SkullTextureData getClearStatData() { return new SkullTextureData(new GameProfile(UUID.fromString("df930b7b-a84d-4f76-90ac-33be6a5b6c88"), "gunging")); }
|
||||
/**
|
||||
* This stat is saved not as a custom tag, but as the vanilla Head Texture itself.
|
||||
* Alas this method returns null.
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public SkullTextureData getLoadedNBT(@NotNull ArrayList<ItemTag> storedTags) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SkullTextureData getClearStatData() {
|
||||
return new SkullTextureData(null);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.Indyuce.mmoitems.stat.data;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.Indyuce.mmoitems.api.item.build.MMOItemBuilder;
|
||||
import net.Indyuce.mmoitems.stat.data.random.RandomStatData;
|
||||
import net.Indyuce.mmoitems.stat.data.type.StatData;
|
||||
@ -8,18 +7,24 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class SkullTextureData implements StatData, RandomStatData<SkullTextureData> {
|
||||
private GameProfile profile;
|
||||
|
||||
public SkullTextureData(GameProfile profile) {
|
||||
/**
|
||||
* Spigot 1.20.2 introduced a PlayerProfile API which requires
|
||||
* to both support PlayerProfile and GameProfile objects as
|
||||
* reflection is no longer supported by >1.20.2
|
||||
*/
|
||||
private Object profile;
|
||||
|
||||
public SkullTextureData(Object profile) {
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GameProfile getGameProfile() {
|
||||
public Object getGameProfile() {
|
||||
return profile;
|
||||
}
|
||||
|
||||
public void setGameProfile(@Nullable GameProfile profile) {
|
||||
public void setGameProfile(@Nullable Object profile) {
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
package net.Indyuce.mmoitems.util;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.UtilityMethods;
|
||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||
@ -11,7 +9,6 @@ import io.lumine.mythic.lib.api.item.SupportedNBTTagValues;
|
||||
import io.lumine.mythic.lib.skill.trigger.TriggerType;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.api.Type;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.entity.Entity;
|
||||
@ -20,13 +17,11 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ -68,23 +63,6 @@ public class MMOUtils {
|
||||
return isNonEmpty(str) ? str : Objects.requireNonNull(fallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The skull texture URL from a given player head
|
||||
*/
|
||||
@Deprecated
|
||||
public static String getSkullTextureURL(ItemStack item) {
|
||||
try {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
Field profileField = meta.getClass().getDeclaredField("profile");
|
||||
profileField.setAccessible(true);
|
||||
Collection<Property> properties = ((GameProfile) profileField.get(item.getItemMeta())).getProperties().get("textures");
|
||||
Property property = properties.toArray(new Property[0])[0];
|
||||
return new String(Base64.decodeBase64(property.getValue())).replace("{textures:{SKIN:{url:\"", "").replace("\"}}}", "");
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static final String UNIVERSAL_REFERENCE = "all";
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user