package de.robotricker.transportpipes.items; import com.comphenix.protocol.wrappers.WrappedGameProfile; import com.comphenix.protocol.wrappers.WrappedSignedProperty; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.RecipeChoice; import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.ShapelessRecipe; import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.SkullMeta; import java.lang.reflect.Field; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Locale; import java.util.Objects; import java.util.UUID; import java.util.stream.Collectors; import javax.inject.Inject; import de.robotricker.transportpipes.TransportPipes; import de.robotricker.transportpipes.config.GeneralConf; import de.robotricker.transportpipes.config.LangConf; import de.robotricker.transportpipes.duct.DuctRegister; import de.robotricker.transportpipes.duct.types.BaseDuctType; import de.robotricker.transportpipes.duct.types.DuctType; import de.robotricker.transportpipes.utils.NMSUtils; public class ItemService { private ItemStack wrench; private YamlConfiguration tempConf; @Inject public ItemService(GeneralConf generalConf) { Material wrenchMaterial = Material.getMaterial(generalConf.getWrenchItem().toUpperCase(Locale.ENGLISH)); Objects.requireNonNull(wrenchMaterial, "The material for the wrench item set in the config file is not valid."); wrench = generalConf.getWrenchGlowing() ? createGlowingItem(wrenchMaterial) : new ItemStack(wrenchMaterial); wrench = changeDisplayNameAndLoreConfig(wrench, LangConf.Key.WRENCH.getLines()); tempConf = new YamlConfiguration(); } public ItemStack getWrench() { return wrench; } public boolean isWrench(ItemStack item) { if (item == null || !item.hasItemMeta() || !item.getItemMeta().hasDisplayName()) { return false; } return item.getItemMeta().getDisplayName().equals(LangConf.Key.WRENCH.getLines().get(0)); } public ItemStack createModelledItem(int damage) { ItemStack woodenPickage = new ItemStack(Material.WOODEN_PICKAXE); ItemMeta meta = woodenPickage.getItemMeta(); ((Damageable) meta).setDamage(damage); meta.setUnbreakable(true); woodenPickage.setItemMeta(meta); return woodenPickage; } public ItemStack createGlowingItem(Material material) { ItemStack is = new ItemStack(material); ItemMeta im = is.getItemMeta(); im.addEnchant(Enchantment.PROTECTION_ENVIRONMENTAL, 1, true); im.addItemFlags(ItemFlag.HIDE_ENCHANTS); is.setItemMeta(im); return is; } public ItemStack changeDisplayName(ItemStack is, String displayName) { ItemMeta im = is.getItemMeta(); im.setDisplayName(displayName); is.setItemMeta(im); return is; } public ItemStack changeDisplayNameAndLore(ItemStack is, String... displayNameAndLore) { ItemMeta meta = is.getItemMeta(); if (displayNameAndLore.length > 0) meta.setDisplayName(displayNameAndLore[0]); if (displayNameAndLore.length > 1) meta.setLore(Arrays.asList(displayNameAndLore).subList(1, displayNameAndLore.length)); is.setItemMeta(meta); return is; } public ItemStack changeDisplayNameAndLoreConfig(ItemStack is, String displayName, List<String> lore) { ItemMeta meta = is.getItemMeta(); meta.setDisplayName(displayName); meta.setLore(lore); is.setItemMeta(meta); return is; } public ItemStack changeDisplayNameAndLoreConfig(ItemStack is, List<String> displayNameAndLore) { ItemMeta meta = is.getItemMeta(); if (displayNameAndLore.size() > 0) meta.setDisplayName(displayNameAndLore.get(0)); if (displayNameAndLore.size() > 1) meta.setLore(displayNameAndLore.subList(1, displayNameAndLore.size())); is.setItemMeta(meta); return is; } public ItemStack createHeadItem(String uuid, String textureValue, String textureSignature) { WrappedGameProfile wrappedProfile = new WrappedGameProfile(UUID.fromString(uuid), null); wrappedProfile.getProperties().put("textures", new WrappedSignedProperty("textures", textureValue, textureSignature)); ItemStack skull = new ItemStack(Material.PLAYER_HEAD); SkullMeta sm = (SkullMeta) skull.getItemMeta(); sm.setOwningPlayer(Bukkit.getOfflinePlayer(UUID.fromString(uuid))); Field profileField; try { profileField = sm.getClass().getDeclaredField("profile"); profileField.setAccessible(true); profileField.set(sm, wrappedProfile.getHandle()); } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e1) { e1.printStackTrace(); } skull.setItemMeta(sm); return skull; } public ItemStack setDuctNBTTags(DuctType dt, ItemStack item) { item = NMSUtils.manipulateItemStackNBT(item, "basicDuctType", dt.getBaseDuctType().getName(), String.class, "String"); item = NMSUtils.manipulateItemStackNBT(item, "ductType", dt.getName(), String.class, "String"); return item; } public DuctType readDuctNBTTags(ItemStack item, DuctRegister ductRegister) { String basicDuctTypeSerialized = (String) NMSUtils.readItemStackNBT(item, "basicDuctType", "String"); if (basicDuctTypeSerialized != null && !basicDuctTypeSerialized.isEmpty()) { BaseDuctType bdt = ductRegister.baseDuctTypeOf(basicDuctTypeSerialized); String ductTypeSerialized = (String) NMSUtils.readItemStackNBT(item, "ductType", "String"); if (ductTypeSerialized != null && !ductTypeSerialized.isEmpty()) { return bdt.ductTypeOf(ductTypeSerialized); } } else { //legacy ductType loading (with the gameprofile uuids of the skulls) if (item.getItemMeta() instanceof SkullMeta) { SkullMeta sm = (SkullMeta) item.getItemMeta(); try { Field profileField = sm.getClass().getDeclaredField("profile"); profileField.setAccessible(true); Object profile = profileField.get(sm); if (profile == null) return null; Field idField = Class.forName("com.mojang.authlib.GameProfile").getDeclaredField("id"); idField.setAccessible(true); UUID id = (UUID) idField.get(profile); if (id == null) return null; for (DuctType dt : ductRegister.baseDuctTypeOf("pipe").ductTypes()) { Object dtProfile = profileField.get(dt.getBaseDuctType().getItemManager().getItem(dt).getItemMeta()); UUID dtId = (UUID) idField.get(dtProfile); if (id.compareTo(dtId) == 0) { return dt; } } } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException | ClassNotFoundException e) { e.printStackTrace(); } } } return null; } public void populateInventoryLine(Inventory inv, int row, ItemStack... items) { for (int i = 0; i < 9; i++) { if (items.length > i && items[i] != null) { ItemStack is = items[i]; inv.setItem(row * 9 + i, is); } } } public ItemStack createWildcardItem(Material material) { ItemStack glassPane = new ItemStack(material); return changeDisplayNameAndLore(glassPane, ChatColor.RESET.toString()); } public ItemStack createBarrierItem() { return changeDisplayNameAndLore(new ItemStack(Material.BARRIER), ChatColor.RESET.toString()); } public boolean isItemWildcardOrBarrier(ItemStack item) { if (item != null) { switch (item.getType()) { case GRAY_STAINED_GLASS_PANE: case BLACK_STAINED_GLASS_PANE: case RED_STAINED_GLASS_PANE: case BLUE_STAINED_GLASS_PANE: case LIME_STAINED_GLASS_PANE: case WHITE_STAINED_GLASS_PANE: case YELLOW_STAINED_GLASS_PANE: case BROWN_STAINED_GLASS_PANE: case CYAN_STAINED_GLASS_PANE: case GREEN_STAINED_GLASS_PANE: case LIGHT_BLUE_STAINED_GLASS_PANE: case LIGHT_GRAY_STAINED_GLASS_PANE: case MAGENTA_STAINED_GLASS_PANE: case ORANGE_STAINED_GLASS_PANE: case PINK_STAINED_GLASS_PANE: case PURPLE_STAINED_GLASS_PANE: case BARRIER: if (item.hasItemMeta() && item.getItemMeta().hasDisplayName()) { return item.getItemMeta().getDisplayName().equals(ChatColor.RESET.toString()); } default: return false; } } return false; } public String serializeItemStack(ItemStack itemStack) { tempConf.set("itemStack", itemStack); String string = tempConf.saveToString(); tempConf.set("itemStack", null); return string; } public ItemStack deserializeItemStack(String string) { try { tempConf.loadFromString(string); } catch (InvalidConfigurationException e) { e.printStackTrace(); } ItemStack itemStack = tempConf.getItemStack("itemStack"); tempConf.set("itemStack", null); return itemStack; } public ShapedRecipe createShapedRecipe(TransportPipes transportPipes, String recipeKey, ItemStack resultItem, String[] shape, Object... ingredientMap) { ShapedRecipe recipe = new ShapedRecipe(new NamespacedKey(transportPipes, recipeKey), resultItem); recipe.shape(shape); for (int i = 0; i < ingredientMap.length; i += 2) { char c = (char) ingredientMap[i]; if (ingredientMap[i + 1] instanceof Material) { recipe.setIngredient(c, (Material) ingredientMap[i + 1]); } else { recipe.setIngredient(c, new RecipeChoice.MaterialChoice(((Collection<Material>) ingredientMap[i + 1]).stream().collect(Collectors.toList()))); } } return recipe; } public ShapelessRecipe createShapelessRecipe(TransportPipes transportPipes, String recipeKey, ItemStack resultItem, Material... ingredients) { ShapelessRecipe recipe = new ShapelessRecipe(new NamespacedKey(transportPipes, recipeKey), resultItem); for (int i = 0; i < ingredients.length; i += 2) { recipe.addIngredient(ingredients[i]); } return recipe; } }