package org.bukkit.craftbukkit.block; import com.google.common.base.Preconditions; import com.mojang.authlib.GameProfile; import net.minecraft.server.MinecraftServer; import net.minecraft.server.TileEntitySkull; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.OfflinePlayer; import org.bukkit.SkullType; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.Skull; import org.bukkit.craftbukkit.CraftWorld; public class CraftSkull extends CraftBlockState implements Skull { private static final int MAX_OWNER_LENGTH = 16; private final TileEntitySkull skull; private GameProfile profile; private SkullType skullType; private byte rotation; public CraftSkull(final Block block) { super(block); CraftWorld world = (CraftWorld) block.getWorld(); skull = (TileEntitySkull) world.getTileEntityAt(getX(), getY(), getZ()); profile = skull.getGameProfile(); skullType = getSkullType(skull.getSkullType()); rotation = (byte) skull.rotation; } public CraftSkull(final Material material, final TileEntitySkull te) { super(material); skull = te; profile = skull.getGameProfile(); skullType = getSkullType(skull.getSkullType()); rotation = (byte) skull.rotation; } static SkullType getSkullType(int id) { switch (id) { default: case 0: return SkullType.SKELETON; case 1: return SkullType.WITHER; case 2: return SkullType.ZOMBIE; case 3: return SkullType.PLAYER; case 4: return SkullType.CREEPER; case 5: return SkullType.DRAGON; } } static int getSkullType(SkullType type) { switch(type) { default: case SKELETON: return 0; case WITHER: return 1; case ZOMBIE: return 2; case PLAYER: return 3; case CREEPER: return 4; case DRAGON: return 5; } } static byte getBlockFace(BlockFace rotation) { switch (rotation) { case NORTH: return 0; case NORTH_NORTH_EAST: return 1; case NORTH_EAST: return 2; case EAST_NORTH_EAST: return 3; case EAST: return 4; case EAST_SOUTH_EAST: return 5; case SOUTH_EAST: return 6; case SOUTH_SOUTH_EAST: return 7; case SOUTH: return 8; case SOUTH_SOUTH_WEST: return 9; case SOUTH_WEST: return 10; case WEST_SOUTH_WEST: return 11; case WEST: return 12; case WEST_NORTH_WEST: return 13; case NORTH_WEST: return 14; case NORTH_NORTH_WEST: return 15; default: throw new IllegalArgumentException("Invalid BlockFace rotation: " + rotation); } } static BlockFace getBlockFace(byte rotation) { switch (rotation) { case 0: return BlockFace.NORTH; case 1: return BlockFace.NORTH_NORTH_EAST; case 2: return BlockFace.NORTH_EAST; case 3: return BlockFace.EAST_NORTH_EAST; case 4: return BlockFace.EAST; case 5: return BlockFace.EAST_SOUTH_EAST; case 6: return BlockFace.SOUTH_EAST; case 7: return BlockFace.SOUTH_SOUTH_EAST; case 8: return BlockFace.SOUTH; case 9: return BlockFace.SOUTH_SOUTH_WEST; case 10: return BlockFace.SOUTH_WEST; case 11: return BlockFace.WEST_SOUTH_WEST; case 12: return BlockFace.WEST; case 13: return BlockFace.WEST_NORTH_WEST; case 14: return BlockFace.NORTH_WEST; case 15: return BlockFace.NORTH_NORTH_WEST; default: throw new AssertionError(rotation); } } @Override public boolean hasOwner() { return profile != null; } @Override public String getOwner() { return hasOwner() ? profile.getName() : null; } @Override public boolean setOwner(String name) { if (name == null || name.length() > MAX_OWNER_LENGTH) { return false; } GameProfile profile = MinecraftServer.getServer().getUserCache().getReactor().requestProfile(name); if (profile == null) { return false; } if (skullType != SkullType.PLAYER) { skullType = SkullType.PLAYER; } this.profile = profile; return true; } @Override public OfflinePlayer getOwningPlayer() { if (profile != null) { if (profile.getId() != null) { return Bukkit.getOfflinePlayer(profile.getId()); } if (profile.getName() != null) { return Bukkit.getOfflinePlayer(profile.getName()); } } return null; } @Override public void setOwningPlayer(OfflinePlayer player) { Preconditions.checkNotNull(player, "player"); if (skullType != SkullType.PLAYER) { skullType = SkullType.PLAYER; } this.profile = new GameProfile(player.getUniqueId(), player.getName()); } @Override public BlockFace getRotation() { return getBlockFace(rotation); } @Override public void setRotation(BlockFace rotation) { this.rotation = getBlockFace(rotation); } @Override public SkullType getSkullType() { return skullType; } @Override public void setSkullType(SkullType skullType) { this.skullType = skullType; if (skullType != SkullType.PLAYER) { profile = null; } } @Override public boolean update(boolean force, boolean applyPhysics) { boolean result = super.update(force, applyPhysics); if (result) { if (skullType == SkullType.PLAYER) { skull.setGameProfile(profile); } else { skull.setSkullType(getSkullType(skullType)); } skull.setRotation(rotation); skull.update(); } return result; } @Override public TileEntitySkull getTileEntity() { return skull; } }