private static CArray deepClone(CArray array, Target t, ArrayList<CArray[]> cloneRefs) { // Return the clone reference if this array has been cloned before (both clones will have the // same reference). for (CArray[] refCouple : cloneRefs) { if (refCouple[0] == array) { return refCouple[1]; } } // Create the clone to put array in and add it to the cloneRefs list. CArray clone = new CArray(t, (int) array.size()); clone.associative_mode = array.associative_mode; cloneRefs.add(new CArray[] {array, clone}); // Iterate over the array, recursively calling this method to perform a deep clone. for (Construct key : array.keySet()) { Construct value = array.get(key, t); if (value instanceof CArray) { value = deepClone((CArray) value, t, cloneRefs); } clone.set(key, value, t); } return clone; }
/** * Gets an MCItemStack from a given item "object". Supports both the old and new formats currently * * @param i * @param line_num * @param f * @return */ public MCItemStack item(Construct i, Target t) { if (i instanceof CNull) { return EmptyItem(); } if (!(i instanceof CArray)) { throw new ConfigRuntimeException("Expected an array!", ExceptionType.FormatException, t); } CArray item = (CArray) i; int type = 0; int data = 0; int qty = 1; Map<MCEnchantment, Integer> enchants = new HashMap<MCEnchantment, Integer>(); MCItemMeta meta = null; if (item.containsKey("type")) { try { if (item.get("type").val().contains(":")) { // We're using the combo addressing method String[] split = item.get("type").val().split(":"); item.set("type", split[0]); item.set("data", split[1]); } type = Integer.parseInt(item.get("type").val()); } catch (NumberFormatException e) { throw new ConfigRuntimeException( "Could not get item information from given information (" + item.get("type").val() + ")", ExceptionType.FormatException, t, e); } } else { throw new ConfigRuntimeException( "Could not find item type!", ExceptionType.FormatException, t); } if (item.containsKey("data")) { try { data = Integer.parseInt(item.get("data").val()); } catch (NumberFormatException e) { throw new ConfigRuntimeException( "Could not get item data from given information (" + item.get("data").val() + ")", ExceptionType.FormatException, t, e); } } if (item.containsKey("qty")) { // This is the qty String sqty = "notanumber"; if (item.containsKey("qty")) { sqty = item.get("qty").val(); } try { qty = Integer.parseInt(sqty); } catch (NumberFormatException e) { throw new ConfigRuntimeException( "Could not get qty from given information (" + sqty + ")", ExceptionType.FormatException, t, e); } } if (item.containsKey("enchants")) { CArray enchantArray = null; try { if (item.containsKey("enchants")) { enchantArray = (CArray) item.get("enchants"); } if (enchantArray == null) { throw new NullPointerException(); } } catch (Exception e) { throw new ConfigRuntimeException( "Could not get enchantment data from given information.", ExceptionType.FormatException, t, e); } for (String index : enchantArray.keySet()) { try { CArray enchantment = (CArray) enchantArray.get(index); String setype = null; String selevel = null; if (enchantment.containsKey("etype")) { setype = enchantment.get("etype").val(); } if (enchantment.containsKey("elevel")) { selevel = enchantment.get("elevel").val(); } if (setype == null || selevel == null) { throw new ConfigRuntimeException( "Could not get enchantment data from given information.", ExceptionType.FormatException, t); } int elevel = 0; try { elevel = Integer.parseInt(selevel); } catch (NumberFormatException e) { throw new ConfigRuntimeException( "Could not get enchantment data from given information.", ExceptionType.FormatException, t); } MCEnchantment etype = StaticLayer.GetEnchantmentByName(setype); enchants.put(etype, elevel); } catch (ClassCastException e) { throw new ConfigRuntimeException( "Could not get enchantment data from given information.", ExceptionType.FormatException, t, e); } } } if (item.containsKey("meta")) { meta = itemMeta(item.get("meta"), type, t); } MCItemStack ret = StaticLayer.GetItemStack(type, qty); ret.setData(data); ret.setDurability((short) data); if (meta != null) { ret.setItemMeta(meta); } for (Map.Entry<MCEnchantment, Integer> entry : enchants.entrySet()) { ret.addUnsafeEnchantment(entry.getKey(), entry.getValue()); } // Giving them air crashes the client, so just clear the inventory slot if (ret.getTypeId() == 0) { ret = EmptyItem(); } return ret; }