How do you get a player who has never joined before?

Discussion in 'Plugin Development' started by RedKaneChironic, Nov 15, 2020.

  1. Offline

    RedKaneChironic

    For my plugin, I need to get a custom texture, which is represented by a custom head. For this, I used
    Code:
    ItemStack Item = new ItemStack(Material.PLAYER_HEAD);
                    SkullMeta meta = (SkullMeta) Item.getItemMeta();
                    meta.setOwningPlayer(Bukkit.getOfflinePlayer(UUID.fromString("c7c92b81-3987-4220-9069-207790a780d7")));
                    
    The problem with this is that it actually sets the skull's texture to a basic Alex head. Since .getOfflinePlayer calls .getServer.getOfflinePlayer and this player hasn't joined before, how would I get this player's skin?
     
  2. Offline

    KarimAKL

  3. Offline

    RedKaneChironic

    @KarimAKL After using the code in that thread, along with another piece of code to return the head, it looks like this:
    Code:
        public ItemStack getCustomSkull(String uuid) {
            String url = getSkinUrl(uuid);
            ItemStack head = new ItemStack(Material.PLAYER_HEAD);
            if (url.isEmpty()) return head;
            SkullMeta skullMeta = (SkullMeta) head.getItemMeta();
            GameProfile profile = new GameProfile(UUID.randomUUID(), null);
            profile.getProperties().put("textures", new Property("textures", url));
            try {
                Method mtd = skullMeta.getClass().getDeclaredMethod("setProfile", GameProfile.class);
                mtd.setAccessible(true);
                mtd.invoke(skullMeta, profile);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            head.setItemMeta(skullMeta);
            return head;
        }
        static private JsonParser parser = new JsonParser();
        static private String API_PROFILE_LINK = "https://sessionserver.mojang.com/session/minecraft/profile/";
        public static String getSkinUrl(String uuid){
                String json = getContent(API_PROFILE_LINK + uuid);
                JsonObject o = parser.parse(json).getAsJsonObject();
                String jsonBase64 = o.get("properties").getAsJsonArray().get(0).getAsJsonObject().get("value").getAsString();
        
                o = parser.parse(new String(Base64.getDecoder().decode(jsonBase64))).getAsJsonObject();
                String skinUrl = o.get("textures").getAsJsonObject().get("SKIN").getAsJsonObject().get("url").getAsString();
                return skinUrl;
        }
        public static String getContent(String link){
                try {
                    URL url = new URL(link);
                    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
                    BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                    String outputLine = "";
                
                    String inputLine;
                    while ((inputLine = br.readLine()) != null) {
                        outputLine += inputLine;
                    }
                    br.close();
                    return outputLine;
            
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
        }
    
    it still returns the standard Alex head.
    EDIT:
    The problem was that it wouldn't re-encode the texture link into Base64. I dug up some code online that did that, see
    Code:
    public ItemStack getSkull(String url, UUID uuid) {
            ItemStack skull = new ItemStack(Material.PLAYER_HEAD);
            if (url == null || url.isEmpty())
                return skull;
            SkullMeta skullMeta = (SkullMeta) skull.getItemMeta();
            GameProfile profile = new GameProfile(uuid, null);
            byte[] encodedData = Base64.encodeBase64(String.format("{textures:{SKIN:{url:\"%s\"}}}", url).getBytes());
            profile.getProperties().put("textures", new Property("textures", new String(encodedData)));
            Field profileField = null;
            try {
                profileField = skullMeta.getClass().getDeclaredField("profile");
            } catch (NoSuchFieldException | SecurityException e) {
                e.printStackTrace();
            }
            profileField.setAccessible(true);
            try {
                profileField.set(skullMeta, profile);
            } catch (IllegalArgumentException | IllegalAccessException e) {
                e.printStackTrace();
            }
            skull.setItemMeta(skullMeta);
            return skull;
        }
    
    Use the code above in conjunction with this one to get a head from player. Marking as solved.
     
    Last edited: Nov 21, 2020

Share This Page