Java tutorial
/******************************************************************************* * Copyright (C) 2014 Travis Ralston (turt2live) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package com.turt2live.xmail.mail.attachment; import com.turt2live.xmail.XMail; import com.turt2live.xmail.entity.XMailEntity; import com.turt2live.xmail.entity.XMailPlayer; import com.turt2live.xmail.mail.Mail; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.command.CommandSender; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.BookMeta; import org.bukkit.inventory.meta.ItemMeta; import org.json.simple.JSONValue; import org.json.simple.parser.ContainerFactory; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import java.util.*; import java.util.Map.Entry; public class ItemAttachment extends Attachment { /** * Represents a key used in JSON serialization (internal use) */ public static final String CLASS_KEY = "XMAIL-SERIAL-DESERIAL-CLASS"; private static final long serialVersionUID = -1476657368786253041L; private ItemStack item; public ItemAttachment(ItemStack item) { if (item == null) { throw new IllegalArgumentException(); } this.item = item; } @Override public Attachment clone() { return new ItemAttachment(item); } @Override public Object getContent() { return item; } /** * Gets an EDITABLE item stack object. * * @return the item stack, editable */ public ItemStack getItemStack() { return item; } @Override public Object getSerializedContent() { Map<String, Object> serial = item.serialize(); if (serial.get("meta") != null) { ItemMeta itemmeta = item.getItemMeta(); Map<String, Object> meta = itemmeta.serialize(); Map<String, Object> meta2 = new HashMap<String, Object>(); for (String key : meta.keySet()) { meta2.put(key, meta.get(key)); } for (String key : meta2.keySet()) { Object o = meta2.get(key); if (o instanceof ConfigurationSerializable) { ConfigurationSerializable serial1 = (ConfigurationSerializable) o; Map<String, Object> serialed = recursiveSerialization(serial1); meta2.put(key, serialed); } } meta = meta2; serial.put("meta", meta); } return JSONValue.toJSONString(serial); } @Override public AttachmentType getType() { return AttachmentType.ITEM; } @Override public boolean giveTo(XMailEntity entity) { if (entity instanceof XMailPlayer) { XMailPlayer xp = (XMailPlayer) entity; CommandSender sender = xp.getOwner(); if (sender instanceof Player) { Player pl = (Player) sender; HashMap<Integer, ItemStack> overflow = pl.getInventory().addItem(item); if (overflow.isEmpty()) { return true; } } } return false; } @Override public void onGive(XMailEntity to, Mail mail) { if (to instanceof XMailPlayer && item.getType() == XMail.EXPLOSIVE_MATERIAL && item.getDurability() == XMail.EXPLOSIVE_DATA_VALUE) { int explosive = item.getAmount(); int explosionSize = explosive > 16 ? 16 : explosive; if (explosionSize > 0) { Player target = (Player) to.getOwner(); Location loc = target.getLocation(); target.getWorld().createExplosion(loc.getX(), loc.getY(), loc.getZ(), explosionSize * 2, false, false); Random random = new Random(System.currentTimeMillis()); for (int i = 0; i < 50; i++) { target.playSound(loc, Sound.GHAST_SCREAM, 1.0f, (random.nextFloat() - random.nextFloat()) * 0.2F + 1.0F); } } } } private Map<String, Object> recursiveSerialization(ConfigurationSerializable o) { Map<String, Object> map = o.serialize(); Map<String, Object> map2 = new HashMap<String, Object>(); for (String key : map.keySet()) { Object o2 = map.get(key); map2.put(key, o2); if (o2 instanceof ConfigurationSerializable) { ConfigurationSerializable serialObj = (ConfigurationSerializable) o2; Map<String, Object> newMap = recursiveSerialization(serialObj); newMap.put(CLASS_KEY, ConfigurationSerialization.getAlias(serialObj.getClass())); map2.put(key, newMap); } } map2.put(CLASS_KEY, ConfigurationSerialization.getAlias(o.getClass())); return map2; } @SuppressWarnings("unchecked") public static ItemAttachment deserializeFromJson(String content) { JSONParser parser = new JSONParser(); ContainerFactory containerFactory = new ContainerFactory() { @Override public List<Object> creatArrayContainer() { return new LinkedList<Object>(); } @Override public Map<String, Object> createObjectContainer() { return new LinkedHashMap<String, Object>(); } }; Map<String, Object> keys = new HashMap<String, Object>(); try { Map<?, ?> json = (Map<?, ?>) parser.parse(content, containerFactory); Iterator<?> iter = json.entrySet().iterator(); // Type check while (iter.hasNext()) { Entry<?, ?> entry = (Entry<?, ?>) iter.next(); if (!(entry.getKey() instanceof String)) { throw new IllegalArgumentException("Not in <String, Object> format"); } } keys = (Map<String, Object>) json; } catch (ParseException e) { e.printStackTrace(); return new ItemAttachment(new ItemStack(Material.GRASS, 1)); } catch (IllegalArgumentException e) { e.printStackTrace(); return new ItemAttachment(new ItemStack(Material.GRASS, 1)); } // Repair Gson thinking int == double if (keys.get("amount") != null) { Double d = (Double) keys.get("amount"); Integer i = d.intValue(); keys.put("amount", i); } ItemStack item = null; try { item = ItemStack.deserialize(keys); } catch (Exception e) { return null; } // Handle item meta if (keys.containsKey("meta")) { Map<String, Object> itemmeta = (Map<String, Object>) keys.get("meta"); // Convert doubles -> ints itemmeta = recursiveDoubleToInteger(itemmeta); // Deserilize everything itemmeta = recursiveDeserialization(itemmeta); // Create the Item Meta ItemMeta meta = (ItemMeta) ConfigurationSerialization.deserializeObject(itemmeta, ConfigurationSerialization.getClassByAlias("ItemMeta")); // Colorize everything if (meta.hasDisplayName()) { meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', meta.getDisplayName())); } if (meta.hasLore()) { List<String> lore = meta.getLore(); for (int i = 0; i < lore.size(); i++) { String line = lore.get(i); line = ChatColor.translateAlternateColorCodes('?', line); line = ChatColor.translateAlternateColorCodes('&', line); lore.set(i, line); } meta.setLore(lore); } if (meta instanceof BookMeta) { BookMeta book = (BookMeta) meta; if (book.hasAuthor()) { book.setAuthor(ChatColor.translateAlternateColorCodes('&', book.getAuthor())); } if (book.hasTitle()) { book.setTitle(ChatColor.translateAlternateColorCodes('&', book.getTitle())); } if (book.hasPages()) { List<String> pages = new ArrayList<String>(); pages.addAll(book.getPages()); for (int i = 0; i < pages.size(); i++) { String line = pages.get(i); line = ChatColor.translateAlternateColorCodes('&', line); pages.set(i, line); } book.setPages(pages); } } // Assign the item meta item.setItemMeta(meta); } return new ItemAttachment(item); } private static Map<String, Object> recursiveDeserialization(Map<String, Object> map) { Map<String, Object> map2 = new HashMap<String, Object>(); for (String key : map.keySet()) { Object o = map.get(key); map2.put(key, o); if (o instanceof Map) { @SuppressWarnings("unchecked") Map<String, Object> map3 = (Map<String, Object>) o; if (map3.containsKey(CLASS_KEY)) { String alias = (String) map3.get(CLASS_KEY); Object deserialed = ConfigurationSerialization.deserializeObject(map3, ConfigurationSerialization.getClassByAlias(alias)); map2.put(key, deserialed); } // else: ignore } } return map2; } private static Map<String, Object> recursiveDoubleToInteger(Map<String, Object> map) { Map<String, Object> map2 = new HashMap<String, Object>(); for (String key : map.keySet()) { Object o = map.get(key); map2.put(key, o); if (o instanceof Double) { Double d = (Double) o; Integer i = d.intValue(); map2.put(key, i); } else if (o instanceof Map) { @SuppressWarnings("unchecked") Map<String, Object> map3 = (Map<String, Object>) o; map2.put(key, recursiveDoubleToInteger(map3)); } } return map2; } }