ich möchte die Util-Bibliothek heute noch um eine Klasse erweitern.
Hiermit möchte ich euch eine Klasse zur Verfügung stellen, die es möglich macht, eigene Skin-Köpfe in auf ItemStacks zu legen.
Diese können auch als TileEntities in der Welt platziert werden und behalten die eigene Textur.
Code
- Code: Alles auswählen
- package test;
- import java.lang.reflect.Constructor;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.util.Base64;
- import java.util.UUID;
- import org.bukkit.Bukkit;
- import org.bukkit.Location;
- import org.bukkit.Material;
- import org.bukkit.block.Block;
- import org.bukkit.inventory.ItemStack;
- import org.bukkit.inventory.meta.SkullMeta;
- import com.mojang.authlib.GameProfile;
- import com.mojang.authlib.properties.Property;
- public class ItemSkulls {
- private static Class<?> skullMetaClass, tileEntityClass, blockPositionClass;
- private static int mcVersion;
- static {
- String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
- mcVersion = Integer.parseInt(version.replaceAll("[^0-9]", ""));
- try {
- skullMetaClass = Class.forName("org.bukkit.craftbukkit." + version + ".inventory.CraftMetaSkull");
- tileEntityClass = Class.forName("net.minecraft.server." + version + ".TileEntitySkull");
- if (mcVersion > 174) {
- blockPositionClass = Class.forName("net.minecraft.server." + version + ".BlockPosition");
- } else {
- blockPositionClass = null;
- }
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
- /**
- *
- * @param skinURL The URL to the skin-image (full skin)
- * @return The itemstack (SKULL_ITEM) with the given look (skin-image)
- */
- public static ItemStack getSkull(String skinURL) {
- return getSkull(skinURL, 1);
- }
- /**
- *
- * @param skinURL The URL to the skin-image (full skin)
- * @param amount The amount of skulls (for ItemStack)
- * @return The itemstack (SKULL_ITEM) with the given look (skin-image)
- */
- public static ItemStack getSkull(String skinURL, int amount) {
- ItemStack skull = new ItemStack(Material.SKULL_ITEM, amount, (short) 3);
- SkullMeta meta = (SkullMeta) skull.getItemMeta();
- try {
- Field profileField = skullMetaClass.getDeclaredField("profile");
- profileField.setAccessible(true);
- profileField.set(meta, getProfile(skinURL));
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- skull.setItemMeta(meta);
- return skull;
- }
- /**
- *
- * @param loc The location to place the skull
- * @param skinURL The url to the skin-image
- * @return If the block at the given location was replaced with a skull
- */
- public static boolean setBlock(Location loc, String skinURL) {
- return setBlock(loc.getBlock(), skinURL);
- }
- /**
- *
- * @param block The block to set skull
- * @param skinURL The url to the skin-image
- * @return If the block at the given location was replaced with a skull
- */
- public static boolean setBlock(Block block, String skinURL) {
- boolean flag = block.getType() == Material.SKULL;
- if (!flag) {
- block.setType(Material.SKULL);
- }
- try {
- Object nmsWorld = block.getWorld().getClass().getMethod("getHandle").invoke(block.getWorld());
- Object tileEntity = null;
- if (mcVersion <= 174) {
- Method getTileEntity = nmsWorld.getClass().getMethod("getTileEntity", int.class, int.class, int.class);
- tileEntity = tileEntityClass.cast(getTileEntity.invoke(nmsWorld, block.getX(), block.getY(), block.getZ()));
- } else {
- Method getTileEntity = nmsWorld.getClass().getMethod("getTileEntity", blockPositionClass);
- tileEntity = tileEntityClass.cast(getTileEntity.invoke(nmsWorld, getBlockPositionFor(block.getX(), block.getY(), block.getZ())));
- }
- tileEntityClass.getMethod("setGameProfile", GameProfile.class).invoke(tileEntity, getProfile(skinURL));
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- return !flag;
- }
- private static GameProfile getProfile(String skinURL) {
- GameProfile profile = new GameProfile(UUID.randomUUID(), null);
- String base64encoded = Base64.getEncoder().encodeToString(new String("{textures:{SKIN:{url:\"" + skinURL + "\"}}}").getBytes());
- Property property = new Property("textures", base64encoded);
- profile.getProperties().put("textures", property);
- return profile;
- }
- private static Object getBlockPositionFor(int x, int y, int z) {
- Object blockPosition = null;
- try {
- Constructor<?> cons = blockPositionClass.getConstructor(int.class, int.class, int.class);
- blockPosition = cons.newInstance(x, y, z);
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- return blockPosition;
- }
- }
Verwendung
Diese Klasse besitzt zwei wichtige (statische) Methoden: getSkull(String) bzw. getSkull(String, int) und setBlock(Location, String) bzw. setBlock(Block, String).
Ich werde hier einfach mal ein Verwendungsbeispiel schreiben:
- Code: Alles auswählen
- ItemStack skull = ItemSkulls.getSkull("http://textures.minecraft.net/texture/a116e69a845e227f7ca1fdde8c357c8c821ebd4ba619382ea4a1f87d4ae94");
- p.getInventory().addItem(skull);
Effekt: Der Spieler bekommt einen Kopf mit der Textur von Notch ins Inventar gelegt. Statt der URL zum Skin von Notch lassen sich hier beliebige URLs angeben.
Der getSkull()-Methode kann auch noch ein Integer für die Anzahl der Items im ItemStack übergeben werden.
In einem Update wurde außerdem die setBlock-Methode neu implementiert. Sie ermöglicht es nun, Skulls in der Welt zu platzieren und diese zu verändern (auch hier sind eigene Texturen möglich).
Ein Methodenaufruf dazu könnte wie folgt aussehen:
- Code: Alles auswählen
- String skinURL = "http://textures.minecraft.net/texture/a116e69a845e227f7ca1f";
- ItemSkulls.setBlock(meineLocation, skinURL);
(Die URL zum Skin von Notch habe ich aus Übersichtsgründen stark gekürzt)
Effekt: An der gegebenen Location wird ein Skull mit der Textur von Notch platziert.
Die setBlock-Methode gibt außerdem noch einen boolean zurück. Dieser steht auf true, wenn ein anderer Block für den Skull ersetzt werden musste. Falls an der Location bereits ein Skull war, liefert die Methode false.
Die Klasse ist versionsunabhängig (getestet mit Spigot 1.8.3 und 1.8), sollte jedoch sowohl in älteren Versionen, als auch später in neueren Versionen problemlos funktionieren. Falls Probleme auftreten, freue ich mich über eine Info, sodass ich mich darum kümmern kann.
Das war's auch schon - viel Spaß damit!