diff --git a/src/main/java/com/songoda/epicheads/listeners/LoginListeners.java b/src/main/java/com/songoda/epicheads/listeners/LoginListeners.java index 036402a..cb86150 100644 --- a/src/main/java/com/songoda/epicheads/listeners/LoginListeners.java +++ b/src/main/java/com/songoda/epicheads/listeners/LoginListeners.java @@ -5,14 +5,10 @@ import com.songoda.epicheads.head.Head; import com.songoda.epicheads.head.HeadManager; import com.songoda.epicheads.head.Tag; import com.songoda.epicheads.utils.Methods; -import com.songoda.epicheads.utils.ServerVersion; -import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerLoginEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.SkullMeta; import java.util.Optional; @@ -28,15 +24,9 @@ public class LoginListeners implements Listener { public void loginEvent(PlayerLoginEvent event) { HeadManager headManager = plugin.getHeadManager(); - ItemStack item = new ItemStack(plugin.isServerVersionAtLeast(ServerVersion.V1_13) - ? Material.PLAYER_HEAD : Material.valueOf("SKULL_ITEM"), 1, (byte) 3); - Player player = event.getPlayer(); - SkullMeta meta = (SkullMeta) item.getItemMeta(); - meta.setOwningPlayer(player); - item.setItemMeta(meta); - String encodededStr = Methods.getEncodedTexture(item); + String encodededStr = Methods.getEncodedTexture(player); String url = Methods.getDecodedTexture(encodededStr); diff --git a/src/main/java/com/songoda/epicheads/utils/Methods.java b/src/main/java/com/songoda/epicheads/utils/Methods.java index f2f6c9b..1ac9302 100644 --- a/src/main/java/com/songoda/epicheads/utils/Methods.java +++ b/src/main/java/com/songoda/epicheads/utils/Methods.java @@ -4,22 +4,30 @@ import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; import com.songoda.epicheads.EpicHeads; import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; +import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.SkullMeta; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.Base64; -import java.util.Iterator; import java.util.UUID; public class Methods { + private static Class clazzCraftPlayer; + private static Method methodGetProfile; + public static ItemStack addTexture(ItemStack item, String headURL) { SkullMeta meta = (SkullMeta) item.getItemMeta(); + if (headURL == null) return item; + GameProfile profile = new GameProfile(UUID.nameUUIDFromBytes(headURL.getBytes()), null); byte[] encodedData = Base64.getEncoder().encode(String.format("{textures:{SKIN:{url:\"http://textures.minecraft.net/texture/%s\"}}}", new Object[]{headURL}).getBytes()); profile.getProperties().put("textures", new Property("textures", new String(encodedData))); @@ -41,20 +49,36 @@ public class Methods { SkullMeta localSkullMeta = (SkullMeta) item.getItemMeta(); Field localField = localSkullMeta.getClass().getDeclaredField("profile"); localField.setAccessible(true); - GameProfile localGameProfile = (GameProfile) localField.get(localSkullMeta); - Iterator localIterator = localGameProfile.getProperties().get("textures").iterator(); - if (localIterator.hasNext()) { - Property localProperty = (Property) localIterator.next(); - return localProperty.getValue(); - } + GameProfile profile = (GameProfile) localField.get(localSkullMeta); + Property property = profile.getProperties().get("textures").iterator().next(); + return property.getValue(); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); } return null; } - public static String getDecodedTexture(String decoded) { - return StringUtils.substringBetween(new String(Base64.getDecoder().decode(decoded)), "texture/", "\""); + public static String getEncodedTexture(Player player) { + try { + if (clazzCraftPlayer == null) { + String ver = Bukkit.getServer().getClass().getPackage().getName().substring(23); + clazzCraftPlayer = Class.forName("org.bukkit.craftbukkit." + ver + ".entity.CraftPlayer"); + methodGetProfile = clazzCraftPlayer.getMethod("getProfile"); + } + Object craftPlayer = clazzCraftPlayer.cast(player); + Property property = ((GameProfile) methodGetProfile.invoke(craftPlayer)).getProperties().get("textures").iterator().next(); + return property.getValue(); + } catch (ClassNotFoundException + | NoSuchMethodException + | IllegalAccessException + | InvocationTargetException e) { + e.printStackTrace(); + return null; + } + } + + public static String getDecodedTexture(String encoded) { + return StringUtils.substringBetween(new String(Base64.getDecoder().decode(encoded)), "texture/", "\""); } public static ItemStack getGlass() {