From b87a44a6909059450d96f6f884eb8dcda558fffe Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Tue, 13 Feb 2018 19:11:16 -0600 Subject: [PATCH] Add support for game profile based player images --- pom.xml | 5 ++ .../dynmap/bukkit/BukkitVersionHelper.java | 5 ++ .../bukkit/BukkitVersionHelperGeneric.java | 77 ++++++++++++++++++- .../java/org/dynmap/bukkit/DynmapPlugin.java | 13 ++++ 4 files changed, 99 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 023639fa..077f7e85 100644 --- a/pom.xml +++ b/pom.xml @@ -150,6 +150,11 @@ bstats-bukkit 1.1 + + com.googlecode.json-simple + json-simple + 1.1.1 + 3.0-SNAPSHOT diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java b/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java index 3c65ffc9..be6b5f32 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java +++ b/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java @@ -143,4 +143,9 @@ public abstract class BukkitVersionHelper { * Test if broken unloadChunk */ public boolean isUnloadChunkBroken() { return false; } + /** + * Get skin URL for player + * @param player + */ + public String getSkinURL(Player player) { return null; } } diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGeneric.java b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGeneric.java index 54d98c3b..363002c6 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGeneric.java +++ b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGeneric.java @@ -3,6 +3,7 @@ package org.dynmap.bukkit; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.nio.charset.Charset; import java.util.Collection; import java.util.Collections; import java.util.Map; @@ -15,6 +16,14 @@ import org.bukkit.Server; import org.bukkit.World; import org.bukkit.entity.Player; import org.dynmap.Log; +import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; + +import com.google.common.base.Charsets; +import com.google.common.collect.ForwardingMultimap; +import com.google.common.collect.Iterables; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; /** * Helper for isolation of bukkit version specific issues @@ -95,6 +104,15 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper { protected Method server_getonlineplayers; /** Player */ protected Method player_gethealth; + // CraftPlayer + private Class obc_craftplayer; + private Method obcplayer_getprofile; + // GameProfile + private Class cma_gameprofile; + private Method cmaprofile_getproperties; + // Property + private Class cma_property; + private Method cmaproperty_getvalue; BukkitVersionHelperGeneric() { failed = false; @@ -120,7 +138,17 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper { server_getonlineplayers = getMethod(Server.class, new String[] { "getOnlinePlayers" }, new Class[0]); /** Player */ player_gethealth = getMethod(Player.class, new String[] { "getHealth" }, new Class[0]); - + + // CraftPlayer + obc_craftplayer = getOBCClass("org.bukkit.craftbukkit.entity.CraftPlayer"); + obcplayer_getprofile = getMethod(obc_craftplayer, new String[] { "getProfile" }, new Class[0]); + // GameProfile + cma_gameprofile = getOBCClass("com.mojang.authlib.GameProfile"); + cmaprofile_getproperties = getMethod(cma_gameprofile, new String[] { "getProperties" }, new Class[0]); + // Property + cma_property = getOBCClass("com.mojang.authlib.properties.Property"); + cmaproperty_getvalue = getMethod(cma_property, new String[] { "getValue" }, new Class[0]); + /* Get NMS classes and fields */ if(!failed) loadNMS(); @@ -482,5 +510,52 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper { return ((Double) health).intValue(); } } + + private static final Gson gson = new GsonBuilder().create(); + + public class TexturesPayload { + public long timestamp; + public String profileId; + public String profileName; + public boolean isPublic; + public Map textures; + + } + public class ProfileTexture { + public String url; + } + + /** + * Get skin URL for player + * @param player + */ + public String getSkinURL(Player player) { + String url = null; + Object profile = callMethod(player, obcplayer_getprofile, nullargs, null); + if (profile != null) { + Object propmap = callMethod(profile, cmaprofile_getproperties, nullargs, null); + if ((propmap != null) && (propmap instanceof ForwardingMultimap)) { + ForwardingMultimap fmm = (ForwardingMultimap) propmap; + Collection txt = fmm.get("textures"); + Object textureProperty = Iterables.getFirst(fmm.get("textures"), null); + if (textureProperty != null) { + String val = (String) callMethod(textureProperty, cmaproperty_getvalue, nullargs, null); + if (val != null) { + TexturesPayload result = null; + try { + String json = new String(Base64Coder.decode(val), Charsets.UTF_8); + result = gson.fromJson(json, TexturesPayload.class); + } catch (JsonParseException e) { + } + if ((result != null) && (result.textures != null) && (result.textures.containsKey("SKIN"))) { + url = result.textures.get("SKIN").url; + } + } + } + } + } + + return url; + } } diff --git a/src/main/java/org/dynmap/bukkit/DynmapPlugin.java b/src/main/java/org/dynmap/bukkit/DynmapPlugin.java index 6ef7a0fd..af54d3a2 100644 --- a/src/main/java/org/dynmap/bukkit/DynmapPlugin.java +++ b/src/main/java/org/dynmap/bukkit/DynmapPlugin.java @@ -10,6 +10,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; @@ -560,11 +561,15 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public class BukkitPlayer extends BukkitCommandSender implements DynmapPlayer { private Player player; private OfflinePlayer offplayer; + private String skinurl; + private UUID uuid; public BukkitPlayer(Player p) { super(p); player = p; offplayer = p.getPlayer(); + uuid = p.getUniqueId(); + skinurl = helper.getSkinURL(p); } public BukkitPlayer(OfflinePlayer p) { super(null); @@ -672,6 +677,14 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { sortWeights.put(getName(), wt); } } + @Override + public String getSkinURL() { + return skinurl; + } + @Override + public UUID getUUID() { + return uuid; + } } /* Handler for generic console command sender */ public class BukkitCommandSender implements DynmapCommandSender {