diff --git a/pom.xml b/pom.xml index b10a10a..c75ffd4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.modnmetl virtualrealty - 2.5.5 + 2.5.6 jar A plot creation and management plugin for Minecraft @@ -184,7 +184,7 @@ de.tr7zw item-nbt-api - 2.12.0 + 2.12.1 compile diff --git a/src/main/java/com/modnmetl/virtualrealty/model/plot/Plot.java b/src/main/java/com/modnmetl/virtualrealty/model/plot/Plot.java index 6298791..f6d233d 100644 --- a/src/main/java/com/modnmetl/virtualrealty/model/plot/Plot.java +++ b/src/main/java/com/modnmetl/virtualrealty/model/plot/Plot.java @@ -210,7 +210,7 @@ public void removeMember(PlotMember plotMember) { } public void removeAllMembers() { - for (PlotMember member : members) { + for (PlotMember member : new LinkedList<>(members)) { removeMember(member); } } diff --git a/src/main/java/com/modnmetl/virtualrealty/model/plot/PlotItem.java b/src/main/java/com/modnmetl/virtualrealty/model/plot/PlotItem.java index 7b5c6b9..4d9b0b2 100644 --- a/src/main/java/com/modnmetl/virtualrealty/model/plot/PlotItem.java +++ b/src/main/java/com/modnmetl/virtualrealty/model/plot/PlotItem.java @@ -128,7 +128,8 @@ public static PlotItem fromItemStack(ItemStack itemStack) { public static UUID getPlotItemUuid(ItemStack itemStack) { NBTItem nbtItem = new NBTItem(itemStack); String string = nbtItem.getString(NBT_PREFIX + "stack_uuid"); - if (string == null) return UUID.randomUUID(); + if (string == null || string.isEmpty()) + return UUID.randomUUID(); return UUID.fromString(string); } diff --git a/src/main/java/com/modnmetl/virtualrealty/util/data/SkullUtil.java b/src/main/java/com/modnmetl/virtualrealty/util/data/SkullUtil.java index 9042bfe..fa2959d 100644 --- a/src/main/java/com/modnmetl/virtualrealty/util/data/SkullUtil.java +++ b/src/main/java/com/modnmetl/virtualrealty/util/data/SkullUtil.java @@ -1,91 +1,44 @@ package com.modnmetl.virtualrealty.util.data; import com.modnmetl.virtualrealty.VirtualRealty; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; +import de.tr7zw.changeme.nbtapi.NBT; +import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.SkullMeta; -import java.lang.reflect.Field; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Base64; -import java.util.Objects; -import java.util.Random; import java.util.UUID; -import java.util.concurrent.ThreadLocalRandom; public class SkullUtil { - public static ItemStack getSkull(String url) { - ItemStack skull; + public static ItemStack getSkull(String texture, UUID uuid) { + final String textureValue = getBase64Value(texture); + ItemStack item; if (VirtualRealty.legacyVersion) { - skull = new ItemStack(Objects.requireNonNull(Material.getMaterial("SKULL_ITEM")), 1, (short) 3); + item = new ItemStack(Material.valueOf("SKULL_ITEM")); + item.setDurability((short) 3); } else { - skull = new ItemStack(Material.PLAYER_HEAD, 1, (short) 3); - } - if (url == null || url.isEmpty()) - return skull; - SkullMeta skullMeta = (SkullMeta) skull.getItemMeta(); - - GameProfile profile = new GameProfile(UUID.randomUUID(), generateRandomUsername(16)); - byte[] encodedData = Base64.getEncoder().encode(String.format("{textures:{SKIN:{url:\"%s\"}}}", "http://textures.minecraft.net/texture/" + url).getBytes()); - profile.getProperties().put("textures", new Property("textures", new String(encodedData))); - Field profileField = null; - try { - profileField = skullMeta.getClass().getDeclaredField("profile"); - } catch (NoSuchFieldException | SecurityException e) { - e.printStackTrace(); + item = new ItemStack(Material.PLAYER_HEAD); } - profileField.setAccessible(true); - try { - profileField.set(skullMeta, profile); - } catch (IllegalArgumentException | IllegalAccessException e) { - e.printStackTrace(); - } - skull.setItemMeta(skullMeta); - return skull; + NBT.modify(item, nbt -> { + final ReadWriteNBT skullOwnerCompound = nbt.getOrCreateCompound("SkullOwner"); + skullOwnerCompound.setUUID("Id", uuid); + skullOwnerCompound.getOrCreateCompound("Properties") + .getCompoundList("textures") + .addCompound() + .setString("Value", textureValue); + }); + return item; } - - public static ItemStack getSkull(String url, UUID uuid) { - ItemStack skull; - if (VirtualRealty.legacyVersion) { - skull = new ItemStack(Objects.requireNonNull(Material.getMaterial("SKULL_ITEM")), 1, (short) 3); - } else { - skull = new ItemStack(Material.PLAYER_HEAD, 1, (short) 3); - } - if (url == null || url.isEmpty()) - return skull; - SkullMeta skullMeta = (SkullMeta) skull.getItemMeta(); - GameProfile profile = new GameProfile(uuid, generateRandomUsername(16)); - byte[] encodedData = Base64.getEncoder().encode(String.format("{textures:{SKIN:{url:\"%s\"}}}", "http://textures.minecraft.net/texture/" + url).getBytes()); - profile.getProperties().put("textures", new Property("textures", new String(encodedData))); - Field profileField = null; - try { - profileField = skullMeta.getClass().getDeclaredField("profile"); - } catch (NoSuchFieldException | SecurityException e) { - e.printStackTrace(); - } - profileField.setAccessible(true); - try { - profileField.set(skullMeta, profile); - } catch (IllegalArgumentException | IllegalAccessException e) { - e.printStackTrace(); - } - skull.setItemMeta(skullMeta); - return skull; + public static ItemStack getSkull(String url) { + return getSkull(url, UUID.randomUUID()); } - private static String generateRandomUsername(int length) { - // Random username for GameProfile - int leftLimit = 'A'; // letter 'a' - int rightLimit = 'Z'; // letter 'z' - return ThreadLocalRandom.current().ints(leftLimit, rightLimit + 1) - .limit(length) - .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) - .toString(); + private static String getBase64Value(String texture) { + String original = "{\"textures\":{\"SKIN\":{\"url\":\"http://textures.minecraft.net/texture/" + texture + "\"}}}"; + return Base64.getEncoder().encodeToString(original.getBytes(StandardCharsets.UTF_8)); } -} +} \ No newline at end of file