package com.nisovin.magicspells.util; import java.io.File; import java.io.FileOutputStream; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Color; import org.bukkit.DyeColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.banner.Pattern; import org.bukkit.block.banner.PatternType; import org.bukkit.command.CommandSender; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.*; import org.bukkit.material.*; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; import com.nisovin.magicspells.MagicSpells; import com.nisovin.magicspells.Spell; import com.nisovin.magicspells.Spellbook; import com.nisovin.magicspells.materials.ItemNameResolver.ItemTypeAndData; import com.nisovin.magicspells.materials.MagicMaterial; public class Util { public static Map<String, ItemStack> predefinedItems = new HashMap<String, ItemStack>(); private static Random random = new Random(); public static int getRandomInt(int bound) { return random.nextInt(bound); } public static ItemStack getItemStackFromString(String string) { try { if (predefinedItems.containsKey(string)) return predefinedItems.get(string).clone(); ItemStack item; String s = string; String name = null; String[] lore = null; HashMap<Enchantment, Integer> enchants = null; int color = -1; if (s.contains("|")) { String[] temp = s.split("\\|"); s = temp[0]; if (temp.length == 1) { name = ""; } else { name = ChatColor.translateAlternateColorCodes('&', temp[1].replace("__", " ")); if (temp.length > 2) { lore = Arrays.copyOfRange(temp, 2, temp.length); for (int i = 0; i < lore.length; i++) { lore[i] = ChatColor.translateAlternateColorCodes('&', lore[i].replace("__", " ")); } } } } if (s.contains(";")) { String[] temp = s.split(";", 2); s = temp[0]; enchants = new HashMap<Enchantment, Integer>(); if (temp[1].length() > 0) { String[] split = temp[1].split("\\+"); for (int i = 0; i < split.length; i++) { String[] enchantData = split[i].split("-"); Enchantment ench; if (enchantData[0].matches("[0-9]+")) { ench = Enchantment.getById(Integer.parseInt(enchantData[0])); } else { ench = Enchantment.getByName(enchantData[0].toUpperCase()); } if (ench != null && enchantData[1].matches("[0-9]+")) { enchants.put(ench, Integer.parseInt(enchantData[1])); } } } } if (s.contains("#")) { String[] temp = s.split("#"); s = temp[0]; if (temp[1].matches("[0-9A-Fa-f]+")) { color = Integer.parseInt(temp[1], 16); } } ItemTypeAndData itemTypeAndData = MagicSpells.getItemNameResolver().resolve(s); if (itemTypeAndData != null) { item = new ItemStack(itemTypeAndData.id, 1, itemTypeAndData.data); } else { return null; } if (name != null || lore != null || color >= 0) { try { ItemMeta meta = item.getItemMeta(); if (name != null) { meta.setDisplayName(name); } if (lore != null) { meta.setLore(Arrays.asList(lore)); } if (color >= 0 && meta instanceof LeatherArmorMeta) { ((LeatherArmorMeta)meta).setColor(Color.fromRGB(color)); } item.setItemMeta(meta); } catch (Exception e) { MagicSpells.error("Failed to process item meta for item: " + s); } } if (enchants != null) { if (enchants.size() > 0) { item.addUnsafeEnchantments(enchants); } else { item = MagicSpells.getVolatileCodeHandler().addFakeEnchantment(item); } } return item; } catch (Exception e) { MagicSpells.handleException(e); return null; } } public static ItemStack getItemStackFromConfig(ConfigurationSection config) { try { if (!config.contains("type")) return null; // basic item MagicMaterial material = MagicSpells.getItemNameResolver().resolveItem(config.getString("type")); if (material == null) return null; ItemStack item = material.toItemStack(); ItemMeta meta = item.getItemMeta(); // name and lore if (config.contains("name") && config.isString("name")) { meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', config.getString("name"))); } if (config.contains("lore")) { if (config.isList("lore")) { List<String> lore = config.getStringList("lore"); for (int i = 0; i < lore.size(); i++) { lore.set(i, ChatColor.translateAlternateColorCodes('&', lore.get(i))); } meta.setLore(lore); } else if (config.isString("lore")) { List<String> lore = new ArrayList<String>(); lore.add(ChatColor.translateAlternateColorCodes('&', config.getString("lore"))); meta.setLore(lore); } } // enchants boolean emptyEnchants = false; if (config.contains("enchants") && config.isList("enchants")) { List<String> enchants = config.getStringList("enchants"); for (String enchant : enchants) { String[] data = enchant.split(" "); Enchantment e = null; try { int id = Integer.parseInt(data[0]); e = Enchantment.getById(id); } catch (NumberFormatException ex) { e = Enchantment.getByName(data[0].toUpperCase()); } if (e != null) { int level = 0; if (data.length > 1) { try { level = Integer.parseInt(data[1]); } catch (NumberFormatException ex) { } } if (meta instanceof EnchantmentStorageMeta) { ((EnchantmentStorageMeta)meta).addStoredEnchant(e, level, true); } else { meta.addEnchant(e, level, true); } } } if (enchants.size() == 0) { emptyEnchants = true; } } // armor color if (config.contains("color") && config.isString("color") && meta instanceof LeatherArmorMeta) { try { int color = Integer.parseInt(config.getString("color").replace("#", ""), 16); ((LeatherArmorMeta)meta).setColor(Color.fromRGB(color)); } catch (NumberFormatException e) { } } // potion effects if (config.contains("potioneffects") && config.isList("potioneffects") && meta instanceof PotionMeta) { ((PotionMeta)meta).clearCustomEffects(); List<String> potionEffects = config.getStringList("potioneffects"); for (String potionEffect : potionEffects) { String[] data = potionEffect.split(" "); PotionEffectType t = null; try { int id = Integer.parseInt(data[0]); t = PotionEffectType.getById(id); } catch (NumberFormatException e) { t = PotionEffectType.getByName(data[0].toUpperCase()); } if (t != null) { int level = 0; if (data.length > 1) { try { level = Integer.parseInt(data[1]); } catch (NumberFormatException ex) { } } int duration = 600; if (data.length > 2) { try { duration = Integer.parseInt(data[2]); } catch (NumberFormatException ex) { } } boolean ambient = false; if (data.length > 3 && (data[3].equalsIgnoreCase("true") || data[3].equalsIgnoreCase("yes") || data[3].equalsIgnoreCase("ambient"))) { ambient = true; } ((PotionMeta)meta).addCustomEffect(new PotionEffect(t, duration, level, ambient), true); } } } // skull owner if (config.contains("skullowner") && config.isString("skullowner") && meta instanceof SkullMeta) { ((SkullMeta)meta).setOwner(config.getString("skullowner")); } // flower pot /*if (config.contains("flower") && item.getType() == Material.FLOWER_POT && meta instanceof BlockStateMeta) { MagicMaterial flower = MagicSpells.getItemNameResolver().resolveBlock(config.getString("flower")); BlockState state = ((BlockStateMeta)meta).getBlockState(); MaterialData data = state.getData(); if (data instanceof FlowerPot) { ((FlowerPot)data).setContents(new MaterialData(flower.getMaterial())); } state.setData(data); ((BlockStateMeta)meta).setBlockState(state); }*/ // repair cost if (config.contains("repaircost") && config.isInt("repaircost") && meta instanceof Repairable) { ((Repairable)meta).setRepairCost(config.getInt("repaircost")); } // written book if (meta instanceof BookMeta) { if (config.contains("title") && config.isString("title")) { ((BookMeta)meta).setTitle(ChatColor.translateAlternateColorCodes('&', config.getString("title"))); } if (config.contains("author") && config.isString("author")) { ((BookMeta)meta).setAuthor(ChatColor.translateAlternateColorCodes('&', config.getString("author"))); } if (config.contains("pages") && config.isList("pages")) { List<String> pages = config.getStringList("pages"); for (int i = 0; i < pages.size(); i++) { pages.set(i, ChatColor.translateAlternateColorCodes('&', pages.get(i))); } ((BookMeta)meta).setPages(pages); } } // banner if (meta instanceof BannerMeta) { if (config.contains("color") && config.isString("color")) { String s = config.getString("color").toLowerCase(); for (DyeColor c : DyeColor.values()) { if (c != null && c.name().replace("_", "").toLowerCase().equals(s)) { ((BannerMeta)meta).setBaseColor(c); break; } } } if (config.contains("patterns") && config.isList("patterns")) { List<String> patterns = config.getStringList("patterns"); for (String patternData : patterns) { if (patternData.contains(" ")) { String[] split = patternData.split(" "); DyeColor color = null; for (DyeColor c : DyeColor.values()) { if (c != null && c.name().replace("_", "").toLowerCase().equals(split[0].toLowerCase())) { color = c; break; } } PatternType pattern = PatternType.getByIdentifier(split[1]); if (pattern == null) { for (PatternType p : PatternType.values()) { if (p != null && p.name().equalsIgnoreCase(split[1])) { pattern = p; break; } } } if (color != null && pattern != null) { ((BannerMeta)meta).addPattern(new Pattern(color, pattern)); } } } } } // set meta item.setItemMeta(meta); // hide tooltip if (config.getBoolean("hide-tooltip", MagicSpells.hidePredefinedItemTooltips())) { item = MagicSpells.getVolatileCodeHandler().hideTooltipCrap(item); } // unbreakable if (config.getBoolean("unbreakable", false)) { item = MagicSpells.getVolatileCodeHandler().setUnbreakable(item); } // empty enchant if (emptyEnchants) { item = MagicSpells.getVolatileCodeHandler().addFakeEnchantment(item); } // attributes if (config.contains("attributes")) { Set<String> attrs = config.getConfigurationSection("attributes").getKeys(false); String[] attrNames = new String[attrs.size()]; String[] attrTypes = new String[attrs.size()]; double[] attrAmounts = new double[attrs.size()]; int[] attrOperations = new int[attrs.size()]; int i = 0; for (String attrName : attrs) { String[] attrData = config.getString("attributes." + attrName).split(" "); String attrType = attrData[0]; double attrAmt = 1; try { attrAmt = Double.parseDouble(attrData[1]); } catch (NumberFormatException e) {} int attrOp = 0; // add number if (attrData.length > 2) { if (attrData[2].toLowerCase().startsWith("mult")) { attrOp = 1; // multiply percent } else if (attrData[2].toLowerCase().contains("add") && attrData[2].toLowerCase().contains("perc")) { attrOp = 2; // add percent } } if (attrType != null) { attrNames[i] = attrName; attrTypes[i] = attrType; attrAmounts[i] = attrAmt; attrOperations[i] = attrOp; } i++; } item = MagicSpells.getVolatileCodeHandler().addAttributes(item, attrNames, attrTypes, attrAmounts, attrOperations); } return item; } catch (Exception e) { e.printStackTrace(); return null; } } public static void setLoreData(ItemStack item, String data) { ItemMeta meta = item.getItemMeta(); List<String> lore; if (meta.hasLore()) { lore = meta.getLore(); if (lore.size() > 0) { for (int i = 0; i < lore.size(); i++) { String s = ChatColor.stripColor(lore.get(i)); if (s.startsWith("MS$:")) { lore.remove(i); break; } } } } else { lore = new ArrayList<String>(); } lore.add(ChatColor.BLACK.toString() + ChatColor.MAGIC.toString() + "MS$:" + data); meta.setLore(lore); item.setItemMeta(meta); } public static String getLoreData(ItemStack item) { ItemMeta meta = item.getItemMeta(); if (meta != null && meta.hasLore()) { List<String> lore = meta.getLore(); if (lore.size() > 0) { for (int i = 0; i < lore.size(); i++) { String s = ChatColor.stripColor(lore.get(lore.size() - 1)); if (s.startsWith("MS$:")) { return s.substring(4); } } } } return null; } public static void removeLoreData(ItemStack item) { ItemMeta meta = item.getItemMeta(); List<String> lore; if (meta.hasLore()) { lore = meta.getLore(); if (lore.size() > 0) { boolean removed = false; for (int i = 0; i < lore.size(); i++) { String s = ChatColor.stripColor(lore.get(i)); if (s.startsWith("MS$:")) { lore.remove(i); removed = true; break; } } if (removed) { if (lore.size() > 0) { meta.setLore(lore); } else { meta.setLore(null); } item.setItemMeta(meta); } } } } static Map<String, EntityType> entityTypeMap = new HashMap<String, EntityType>(); static { for (EntityType type : EntityType.values()) { if (type != null && type.getName() != null) { entityTypeMap.put(type.getName().toLowerCase(), type); entityTypeMap.put(type.name().toLowerCase(), type); entityTypeMap.put(type.name().toLowerCase().replace("_", ""), type); } } entityTypeMap.put("zombiepig", EntityType.PIG_ZOMBIE); entityTypeMap.put("mooshroom", EntityType.MUSHROOM_COW); entityTypeMap.put("cat", EntityType.OCELOT); entityTypeMap.put("golem", EntityType.IRON_GOLEM); entityTypeMap.put("snowgolem", EntityType.SNOWMAN); entityTypeMap.put("dragon", EntityType.ENDER_DRAGON); Map<String, EntityType> toAdd = new HashMap<String, EntityType>(); for (String s : entityTypeMap.keySet()) { toAdd.put(s + "s", entityTypeMap.get(s)); } entityTypeMap.putAll(toAdd); entityTypeMap.put("endermen", EntityType.ENDERMAN); entityTypeMap.put("wolves", EntityType.WOLF); } public static EntityType getEntityType(String type) { if (type.equalsIgnoreCase("player")) return EntityType.PLAYER; return entityTypeMap.get(type.toLowerCase()); } public static PotionEffectType getPotionEffectType(String type) { if (type.matches("^[0-9]+$")) { return PotionEffectType.getById(Integer.parseInt(type)); } else { return PotionEffectType.getByName(type); } } public static Enchantment getEnchantmentType(String type) { if (type.matches("^[0-9]+$")) { return Enchantment.getById(Integer.parseInt(type)); } else { return Enchantment.getByName(type.toUpperCase()); } } public static void sendFakeBlockChange(Player player, Block block, MagicMaterial mat) { player.sendBlockChange(block.getLocation(), mat.getMaterial(), mat.getMaterialData().getData()); } public static void restoreFakeBlockChange(Player player, Block block) { player.sendBlockChange(block.getLocation(), block.getType(), block.getData()); } public static void setFacing(Player player, Vector vector) { Location loc = player.getLocation(); setLocationFacingFromVector(loc, vector); player.teleport(loc); } public static void setLocationFacingFromVector(Location location, Vector vector) { double yaw = getYawOfVector(vector); double pitch = Math.toDegrees(-Math.asin(vector.getY())); location.setYaw((float)yaw); location.setPitch((float)pitch); } public static double getYawOfVector(Vector vector) { return Math.toDegrees(Math.atan2(-vector.getX(), vector.getZ())); } public static boolean arrayContains(int[] array, int value) { for (int i : array) { if (i == value) { return true; } } return false; } public static boolean arrayContains(String[] array, String value) { for (String i : array) { if (i.equals(value)) { return true; } } return false; } public static boolean arrayContains(Object[] array, Object value) { for (Object i : array) { if (i != null && i.equals(value)) { return true; } } return false; } public static String arrayJoin(String[] array, char with) { if (array == null || array.length == 0) { return ""; } int len = array.length; StringBuilder sb = new StringBuilder(16 + len * 8); sb.append(array[0]); for (int i = 1; i < len; i++) { sb.append(with); sb.append(array[i]); } return sb.toString(); } public static String listJoin(List<String> list) { if (list == null || list.size() == 0) { return ""; } int len = list.size(); StringBuilder sb = new StringBuilder(len * 12); sb.append(list.get(0)); for (int i = 1; i < len; i++) { sb.append(' '); sb.append(list.get(i)); } return sb.toString(); } public static String[] splitParams(String string, int max) { String[] words = string.trim().split(" "); if (words.length <= 1) { return words; } ArrayList<String> list = new ArrayList<String>(); char quote = ' '; String building = ""; for (String word : words) { if (word.length() == 0) continue; if (max > 0 && list.size() == max - 1) { if (!building.isEmpty()) building += " "; building += word; } else if (quote == ' ') { if (word.length() == 1 || (word.charAt(0) != '"' && word.charAt(0) != '\'')) { list.add(word); } else { quote = word.charAt(0); if (quote == word.charAt(word.length() - 1)) { quote = ' '; list.add(word.substring(1, word.length() - 1)); } else { building = word.substring(1); } } } else { if (word.charAt(word.length() - 1) == quote) { list.add(building + " " + word.substring(0, word.length() - 1)); building = ""; quote = ' '; } else { building += " " + word; } } } if (!building.isEmpty()) { list.add(building); } return list.toArray(new String[list.size()]); } public static String[] splitParams(String string) { return splitParams(string, 0); } public static String[] splitParams(String[] split, int max) { return splitParams(arrayJoin(split, ' '), max); } public static String[] splitParams(String[] split) { return splitParams(arrayJoin(split, ' '), 0); } public static List<String> tabCompleteSpellName(CommandSender sender, String partial) { List<String> matches = new ArrayList<String>(); if (sender instanceof Player) { Spellbook spellbook = MagicSpells.getSpellbook((Player)sender); for (Spell spell : spellbook.getSpells()) { if (spellbook.canTeach(spell)) { if (spell.getName().toLowerCase().startsWith(partial)) { matches.add(spell.getName()); } else { String[] aliases = spell.getAliases(); if (aliases != null && aliases.length > 0) { for (String alias : aliases) { if (alias.toLowerCase().startsWith(partial)) { matches.add(alias); } } } } } } } else if (sender.isOp()) { for (Spell spell : MagicSpells.spells()) { if (spell.getName().toLowerCase().startsWith(partial)) { matches.add(spell.getName()); } else { String[] aliases = spell.getAliases(); if (aliases != null && aliases.length > 0) { for (String alias : aliases) { if (alias.toLowerCase().startsWith(partial)) { matches.add(alias); } } } } } } if (matches.size() > 0) { return matches; } return null; } public static boolean removeFromInventory(Inventory inventory, ItemStack item) { int amt = item.getAmount(); ItemStack[] items = inventory.getContents(); for (int i = 0; i < 36; i++) { if (items[i] != null && item.isSimilar(items[i])) { if (items[i].getAmount() > amt) { items[i].setAmount(items[i].getAmount() - amt); amt = 0; break; } else if (items[i].getAmount() == amt) { items[i] = null; amt = 0; break; } else { amt -= items[i].getAmount(); items[i] = null; } } } if (amt == 0) { inventory.setContents(items); return true; } else { return false; } } public static boolean addToInventory(Inventory inventory, ItemStack item, boolean stackExisting, boolean ignoreMaxStack) { int amt = item.getAmount(); ItemStack[] items = inventory.getContents(); if (stackExisting) { for (int i = 0; i < 36; i++) { if (items[i] != null && item.isSimilar(items[i])) { if (items[i].getAmount() + amt <= items[i].getMaxStackSize()) { items[i].setAmount(items[i].getAmount() + amt); amt = 0; break; } else { int diff = items[i].getMaxStackSize() - items[i].getAmount(); items[i].setAmount(items[i].getMaxStackSize()); amt -= diff; } } } } if (amt > 0) { for (int i = 0; i < 36; i++) { if (items[i] == null) { if (amt > item.getMaxStackSize() && !ignoreMaxStack) { items[i] = item.clone(); items[i].setAmount(item.getMaxStackSize()); amt -= item.getMaxStackSize(); } else { items[i] = item.clone(); items[i].setAmount(amt); amt = 0; break; } } } } if (amt == 0) { inventory.setContents(items); return true; } else { return false; } } public static void rotateVector(Vector v, float degrees) { double rad = Math.toRadians(degrees); double sin = Math.sin(rad); double cos = Math.cos(rad); double x = (v.getX() * cos) - (v.getZ() * sin); double z = (v.getX() * sin) + (v.getZ() * cos); v.setX(x); v.setZ(z); } public static boolean downloadFile(String url, File file) { try { URL website = new URL(url); ReadableByteChannel rbc = Channels.newChannel(website.openStream()); FileOutputStream fos = new FileOutputStream(file); fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); fos.close(); rbc.close(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public static void createFire(Block block, byte d) { block.setTypeIdAndData(Material.FIRE.getId(), d, false); } public static ItemStack getEggItemForEntityType(EntityType type) { return new ItemStack(Material.MONSTER_EGG, 1, type.getTypeId()); } public static String getStringNumber(double number, int places) { if (places < 0) return number+""; if (places == 0) return (int)Math.round(number) + ""; int x = (int)Math.pow(10, places); return ((double)Math.round(number * x) / x) + ""; } private static Map<String, String> uniqueIds = new HashMap<String, String>(); public static String getUniqueId(Player player) { String uid = player.getUniqueId().toString().replace("-", ""); uniqueIds.put(player.getName(), uid); return uid; } public static String getUniqueId(String playerName) { if (uniqueIds.containsKey(playerName)) { return uniqueIds.get(playerName); } Player player = Bukkit.getPlayerExact(playerName); if (player != null) { return getUniqueId(player); } return null; } }