Skip to content

Commit

Permalink
Add UUID and cached texture skull_skin support
Browse files Browse the repository at this point in the history
Hopefully we don't have to rely on this for too much longer
*cough*SPIGOT*cough*
  • Loading branch information
Morphan1 committed Feb 8, 2015
1 parent 7893bcb commit 8c5fe4a
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 20 deletions.
4 changes: 4 additions & 0 deletions src/main/java/net/aufdemrand/denizen/objects/dItem.java
Expand Up @@ -255,6 +255,10 @@ public ItemStack getItemStack() {
return item;
}

public void setItemStack(ItemStack item) {
this.item = item;
}

// Compare item to item.
// -1 indicates it is not a match
// 0 indicates it is a perfect match
Expand Down
27 changes: 25 additions & 2 deletions src/main/java/net/aufdemrand/denizen/objects/dLocation.java
@@ -1,5 +1,7 @@
package net.aufdemrand.denizen.objects;

import com.google.common.collect.Iterables;
import com.mojang.authlib.GameProfile;
import net.aufdemrand.denizen.Settings;
import net.aufdemrand.denizencore.objects.*;
import net.aufdemrand.denizencore.objects.notable.Notable;
Expand All @@ -15,12 +17,14 @@
import net.aufdemrand.denizen.utilities.Utilities;
import net.aufdemrand.denizen.utilities.debugging.dB;
import net.aufdemrand.denizen.utilities.entity.Rotation;
import net.minecraft.server.v1_8_R1.TileEntitySkull;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.*;
import org.bukkit.craftbukkit.v1_8_R1.CraftWorld;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
Expand Down Expand Up @@ -504,10 +508,29 @@ public String getAttribute(Attribute attribute) {
// @description
// Returns the skin the skull item is displaying - just the name or UUID as text, not a player object.
// -->
// <--[tag]
// @attribute <l@location.skull_skin.full>
// @returns Element|Element
// @mechanism dLocation.skull_skin
// @description
// Returns the skin the skull item is displaying - just the name or UUID as text, not a player object,
// along with the permanently cached texture property.
// -->
if (attribute.startsWith("skull_skin")) {
if (getBlock().getState() instanceof Skull) {
return new Element(((Skull) getBlock().getState()).getOwner())
.getAttribute(attribute.fulfill(1));
// TODO: use Bukkit Skull method when updated
GameProfile profile = ((TileEntitySkull) ((CraftWorld) getWorld())
.getTileEntityAt(getBlockX(), getBlockY(), getBlockZ())).getGameProfile();
String name = profile.getName();
UUID id = profile.getId();
com.mojang.authlib.properties.Property property = Iterables.getFirst(profile.getProperties().get("textures"), null);
attribute = attribute.fulfill(1);
if (attribute.startsWith("full")) {
return new Element((id != null ? id : name != null ? name : null)
+ (property != null ? "|" + property.getValue() : ""))
.getAttribute(attribute.fulfill(1));
}
return new Element(id != null ? id.toString() : name != null ? name : null).getAttribute(attribute);
}
else return "null";
}
Expand Down
@@ -1,14 +1,25 @@
package net.aufdemrand.denizen.objects.properties.item;

import com.google.common.collect.Iterables;
import com.mojang.authlib.GameProfile;
import net.aufdemrand.denizen.objects.dItem;
import net.aufdemrand.denizen.utilities.debugging.dB;
import net.aufdemrand.denizencore.objects.Element;
import net.aufdemrand.denizencore.objects.Mechanism;
import net.aufdemrand.denizen.objects.dItem;
import net.aufdemrand.denizencore.objects.dList;
import net.aufdemrand.denizencore.objects.dObject;
import net.aufdemrand.denizencore.objects.properties.Property;
import net.aufdemrand.denizencore.tags.Attribute;
import net.aufdemrand.denizen.utilities.debugging.dB;
import net.aufdemrand.denizencore.utilities.CoreUtilities;
import net.minecraft.server.v1_8_R1.GameProfileSerializer;
import net.minecraft.server.v1_8_R1.ItemStack;
import net.minecraft.server.v1_8_R1.MinecraftServer;
import net.minecraft.server.v1_8_R1.NBTTagCompound;
import org.bukkit.craftbukkit.v1_8_R1.inventory.CraftItemStack;
import org.bukkit.inventory.meta.SkullMeta;

import java.util.UUID;

public class ItemSkullskin implements Property {

public static boolean describes(dObject item) {
Expand Down Expand Up @@ -39,14 +50,29 @@ public String getAttribute(Attribute attribute) {
// @mechanism dItem.skull_skin
// @group properties
// @description
// Returns the name of the player whose skin a skull item uses.
// Returns the UUID of the player whose skin a skull item uses.
// Note: Item must be a 'skull_item' with a skin.
// -->
// <--[tag]
// @attribute <i@item.skin.full>
// @returns Element|Element
// @mechanism dItem.skull_skin
// @group properties
// @description
// Returns the UUID of the player whose skin a skull item uses, along
// with the permanently cached texture property.
// Note: Item must be a 'skull_item' with a skin.
// -->

if (attribute.startsWith("skin")) {
if (item.getItemStack().getDurability() == 3
&& ((SkullMeta)item.getItemStack().getItemMeta()).hasOwner())
return new Element(((SkullMeta)item.getItemStack().getItemMeta()).getOwner())
.getAttribute(attribute.fulfill(1));
String skin = getPropertyString();
if (item.getItemStack().getDurability() == 3 && skin != null) {
attribute = attribute.fulfill(1);
if (attribute.startsWith("full")) {
return new Element(skin).getAttribute(attribute.fulfill(1));
}
return new Element(CoreUtilities.split(skin, '|').get(0)).getAttribute(attribute);
}
else
dB.echoError("This skull_item does not have a skin set!");
}
Expand All @@ -61,8 +87,7 @@ public String getAttribute(Attribute attribute) {
// (Only for human 'skull_item's)
// -->
if (attribute.startsWith("has_skin"))
return new Element(item.getItemStack().getDurability() == 3
&& ((SkullMeta)item.getItemStack().getItemMeta()).hasOwner())
return new Element(item.getItemStack().getDurability() == 3 && getPropertyString() != null)
.getAttribute(attribute.fulfill(1));


Expand All @@ -72,11 +97,20 @@ public String getAttribute(Attribute attribute) {

@Override
public String getPropertyString() {
if (item.getItemStack().getDurability() == 3
&& ((SkullMeta)item.getItemStack().getItemMeta()).hasOwner())
return ((SkullMeta)item.getItemStack().getItemMeta()).getOwner();
else
return null;
// TODO: use Bukkit SkullMeta method when updated
if (item.getItemStack().getDurability() == 3) {
ItemStack itemStack = CraftItemStack.asNMSCopy(item.getItemStack());
if (itemStack.hasTag()) {
NBTTagCompound tag = itemStack.getTag();
if (tag.hasKeyOfType("SkullOwner", 10)) {
GameProfile profile = GameProfileSerializer.deserialize(tag.getCompound("SkullOwner"));
com.mojang.authlib.properties.Property property = Iterables.getFirst(profile.getProperties().get("textures"), null);
UUID uuid = profile.getId();
return (uuid != null ? uuid : profile.getName()) + (property != null ? "|" + property.getValue() : "");
}
}
}
return null;
}

@Override
Expand All @@ -90,21 +124,62 @@ public void adjust(Mechanism mechanism) {
// <--[mechanism]
// @object dItem
// @name skull_skin
// @input Element
// @input Element(|Element)
// @description
// Sets the player skin on a skull_item.
// Optionally, use the second Element for the skin texture cache.
// This will require the player's UUID, not their name.
// @tags
// <i@item.skin>
// <i@item.skin.full>
// <i@item.has_skin>
// -->

// TODO: use Bukkit SkullMeta method when updated
if (mechanism.matches("skull_skin")) {
if (item.getItemStack().getDurability() != 3)
item.getItemStack().setDurability((short)3);
SkullMeta meta = (SkullMeta) item.getItemStack().getItemMeta();
meta.setOwner(mechanism.getValue().asString());
item.getItemStack().setItemMeta(meta);
dList list = mechanism.getValue().asType(dList.class);
String idString = list.get(0);
ItemStack itemStack = CraftItemStack.asNMSCopy(item.getItemStack());
GameProfile profile;
if (idString.contains("-")) {
UUID uuid = UUID.fromString(idString);
profile = new GameProfile(uuid, null);
}
else {
profile = new GameProfile(null, idString);
}
profile = fillGameProfile(profile);
if (list.size() > 1) {
profile.getProperties().put("textures", new com.mojang.authlib.properties.Property("value", list.get(1)));
}
NBTTagCompound tag = itemStack.hasTag() ? itemStack.getTag() : new NBTTagCompound();
tag.set("SkullOwner", GameProfileSerializer.serialize(new NBTTagCompound(), profile));
itemStack.setTag(tag);
item.setItemStack(CraftItemStack.asBukkitCopy(itemStack));
}

}

private static GameProfile fillGameProfile(GameProfile gameProfile) {
if(gameProfile != null) {
GameProfile gameProfile1 = null;
if (gameProfile.getName() != null) {
gameProfile1 = MinecraftServer.getServer().getUserCache().getProfile(gameProfile.getName());
} else if (gameProfile.getId() != null) {
gameProfile1 = MinecraftServer.getServer().getUserCache().a(gameProfile.getId());
}
if (gameProfile1 == null) {
return gameProfile;
} else {
com.mojang.authlib.properties.Property property = Iterables.getFirst(gameProfile1.getProperties().get("textures"), null);
if (property == null) {
gameProfile1 = MinecraftServer.getServer().aB().fillProfileProperties(gameProfile1, true);
}
return gameProfile1;
}
}
return null;
}
}

0 comments on commit 8c5fe4a

Please sign in to comment.