6

I'm currently working on a plugin that lets you assume the identity of another player. It does this almost flawlessly: Your UUID and username are changed to that of the user whose identity you are assuming serverside, and as far as the server and plugins can tell, you appear to be that player. You will have the same rank as them, same permissions, everything. The one thing I haven't been able to get is the skin. I had thought that a player's skin would be changed for other players when the UUID was, but this doesn't seem to be the case. I'm using reflection to change the UUID in both the GameProfile and the EntityPlayer (the uniqueID field is inherited from Entity), and all methods of getting the player's UUID return the one that the plugin has set. I've dug through decompiled NMS and Bukkit/Spigot forums, but all of them seem to indicate that the skin should change with the UUID. I'm sending a PlayerQuitEvent and PlayerJoinEvent to plugins to simulate the real player leaving and the assumed player joining, and sending packets to all players to remove the old player from tab and ingame, then add the new one. I'd prefer to not use ProtocolLib if it can be avoided. Any help would be appreciated, can anyone point me in the right direction?

Thanks in advance!

Redempt
  • 169
  • 1
  • 1
  • 9
  • I do not think that Stackoverflow is a good place to seek Minecraft help. Maybe try the [forums](https://bukkit.org/forums/)? Also, is there a way to send `PlayerQuitEvent` and `PlayerJoinEvent` to the server itself instead of the plugins? That might do something... – Cardinal System Aug 22 '17 at 05:07
  • With the way events work, you can only have them handled when you call them yourself. You can call them, see the result, and do what you want with it. It won't make the event actually happen. I'll try the Spigot forums. – Redempt Aug 22 '17 at 05:10
  • Take a look at [this](https://gist.github.com/aadnk/0502e32369f203daaba9), it makes it possible to change a player's skin using protocollib. Maybe you could also change the skin manually when you change the rest? – LeoColman Aug 22 '17 at 14:04

2 Answers2

7

I figured it out myself. It turns out that a GameProfile contains a skin texture. This texture has to be requested from the Mojang session server. Here's 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;
    }
}
Redempt
  • 169
  • 1
  • 1
  • 9
  • Maybe I'm a bit late, but my Eclips doen't like URL (...), what do I need to import in order to use it. (Probably a dumb question ^^) – monamona Sep 23 '18 at 10:38
-2

Always use the Ctrl+Shift+O. It'll import all the stuff you need.

double-beep
  • 5,031
  • 17
  • 33
  • 41
  • 1
    I don't think this answers the question asked, as this is the Eclipse 'import' option, whereas the original solution is probably the accepted answer. The issue seems to be with recreating a request for a skin from the server when the player is transitioned into another player. – Randall Arms Apr 24 '19 at 23:36