Change the skin of players using NMS in Minecraft (Bukkit / Spigot)

I am currently working on a plugin that allows you to accept the identity of another player. It does this almost flawlessly: your UUID and username are changed to the username whose identity you accept on the server, and as far as possible to the server and plugins, you are such a player. You will have the same rank as theirs, the same permissions, that's all. The only thing I could not get is the skin. I thought the player’s skin would be changed for other players when the UUID was, but this does not seem to be the case. I use reflection to change the UUID in both GameProfile and EntityPlayer (the uniqueID field is inherited from Entity), and all methods to get the player’s UUID return the one that was set by the plugin. I dug the decompiled NMS and Bukkit / Spigot forums, but they all seem to indicate that the skin should change using the UUID.I am sending PlayerQuitEvent and PlayerJoinEvent for plugins to simulate the real player, the outgoing and the intended player, and send packets to all players to remove the old player from the tab and the game, and then add a new one. I would prefer not to use ProtocolLib if this can be avoided. Any help would be appreciated, can someone point me in the right direction?

Thanks in advance!

+4
source share
1 answer

I figured it out myself. It turns out GameProfile contains a skin texture. This texture must be requested from the Mojang session server. Here is the code:

public static boolean setSkin(GameProfile profile, UUID uuid) {
    try {
        HttpsURLConnection connection = (HttpsURLConnection) new URL(String.format("https://sessionserver.mojang.com/session/minecraft/profile/%s?unsigned=false", UUIDTypeAdapter.fromUUID(uuid))).openConnection();
        if (connection.getResponseCode() == HttpsURLConnection.HTTP_OK) {
            String reply = new BufferedReader(new InputStreamReader(connection.getInputStream())).readLine();
            String skin = reply.split("\"value\":\"")[1].split("\"")[0];
            String signature = reply.split("\"signature\":\"")[1].split("\"")[0];
            profile.getProperties().put("textures", new Property("textures", skin, signature));
            return true;
        } else {
            System.out.println("Connection could not be opened (Response code " + connection.getResponseCode() + ", " + connection.getResponseMessage() + ")");
            return false;
        }
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
}
+2
source

Source: https://habr.com/ru/post/1684186/


All Articles