/**
  * Returns a CArray given an MCColor. It will be in the format array(r: 0, g: 0, b: 0)
  *
  * @param color
  * @param t
  * @return
  */
 public CArray color(MCColor color, Target t) {
   CArray ca = new CArray(t);
   ca.set("r", new CInt(color.getRed(), t), t);
   ca.set("g", new CInt(color.getGreen(), t), t);
   ca.set("b", new CInt(color.getBlue(), t), t);
   return ca;
 }
    @Override
    public Construct exec(Target t, Environment environment, Construct... args)
        throws ConfigRuntimeException {
      if (environment.getEnv(GlobalEnv.class).GetEvent() == null) {
        throw new ConfigRuntimeException(
            "lock must be called from within an event handler", ExceptionType.BindException, t);
      }

      BoundEvent.ActiveEvent e = environment.getEnv(GlobalEnv.class).GetEvent();
      Priority p = e.getBoundEvent().getPriority();
      List<String> params = new ArrayList<String>();
      if (args.length == 0) {
        e.lock(null);
      } else {
        if (args[0] instanceof CArray) {
          CArray ca = (CArray) args[1];
          for (int i = 0; i < ca.size(); i++) {
            params.add(ca.get(i, t).val());
          }
        } else {
          for (int i = 0; i < args.length; i++) {
            params.add(args[i].val());
          }
        }
      }
      for (String param : params) {
        e.lock(param);
      }
      return CVoid.VOID;
    }
 public CArray exception(ConfigRuntimeException e, Target t) {
   CArray ex = new CArray(t);
   ex.push(new CString(e.getExceptionType().toString(), t));
   ex.push(new CString(e.getMessage(), t));
   ex.push(new CString((e.getFile() != null ? e.getFile().getAbsolutePath() : "null"), t));
   ex.push(new CInt(e.getLineNum(), t));
   return ex;
 }
 private static String optimize0(ParseTree node) {
   if (node.getData() instanceof CFunction) {
     StringBuilder b = new StringBuilder();
     boolean first = true;
     b.append(((CFunction) node.getData()).val()).append("(");
     for (ParseTree child : node.getChildren()) {
       if (!first) {
         b.append(",");
       }
       first = false;
       b.append(optimize0(child));
     }
     b.append(")");
     return b.toString();
   } else if (node.getData() instanceof CString) {
     // strings
     return new StringBuilder()
         .append("'")
         .append(
             node.getData()
                 .val()
                 .replaceAll("\t", "\\t")
                 .replaceAll("\n", "\\n")
                 .replace("\\", "\\\\")
                 .replace("'", "\\'"))
         .append("'")
         .toString();
   } else if (node.getData() instanceof IVariable) {
     return ((IVariable) node.getData()).getName();
   } else if (node.getData() instanceof Variable) {
     return ((Variable) node.getData()).getName();
   } else if (node.getData() instanceof CSlice) {
     return node.getData().val();
   } else if (node.getData() instanceof CArray) {
     // It's a hardcoded array. This only happens in the course of optimization, if
     // the optimizer adds a new array. We still need to handle it appropriately though.
     // The values in the array will be constant, guaranteed.
     StringBuilder b = new StringBuilder();
     b.append("array(");
     boolean first = true;
     CArray n = (CArray) node.getData();
     for (String key : n.stringKeySet()) {
       if (!first) {
         b.append(",");
       }
       first = false;
       b.append(optimize0(new ParseTree(n.get(key), node.getFileOptions())));
     }
     b.append(")");
     return b.toString();
   } else {
     // static
     return node.getData().toString();
   }
 }
 @Override
 public Construct exec(Target t, Environment environment, Construct... args)
     throws ConfigRuntimeException {
   if (environment.getEnv(GlobalEnv.class).GetEvent() == null) {
     throw new ConfigRuntimeException(
         "event_meta must be called from within an event handler!",
         ExceptionType.BindException,
         t);
   }
   CArray history = new CArray(t);
   for (String entry : environment.getEnv(GlobalEnv.class).GetEvent().getHistory()) {
     history.push(new CString(entry, t), t);
   }
   return history;
 }
    public Construct exec(Target t, Env environment, Construct... args)
        throws ConfigRuntimeException {
      MCLocation l =
          ObjectGenerator.GetGenerator()
              .location(
                  args[0],
                  environment.GetPlayer() == null ? null : environment.GetPlayer().getWorld(),
                  t);
      if (l.getBlock().isSign()) {
        String line1 = "";
        String line2 = "";
        String line3 = "";
        String line4 = "";
        if (args.length == 2 && args[1] instanceof CArray) {
          CArray ca = (CArray) args[1];
          if (ca.size() >= 1) {
            line1 = ca.get(0, t).val();
          }
          if (ca.size() >= 2) {
            line2 = ca.get(1, t).val();
          }
          if (ca.size() >= 3) {
            line3 = ca.get(2, t).val();
          }
          if (ca.size() >= 4) {
            line4 = ca.get(3, t).val();
          }

        } else {
          if (args.length >= 2) {
            line1 = args[1].val();
          }
          if (args.length >= 3) {
            line2 = args[2].val();
          }
          if (args.length >= 4) {
            line3 = args[3].val();
          }
          if (args.length >= 5) {
            line4 = args[4].val();
          }
        }
        MCSign s = l.getBlock().getSign();
        s.setLine(0, line1);
        s.setLine(1, line2);
        s.setLine(2, line3);
        s.setLine(3, line4);
        return new CVoid(t);
      } else {
        throw new ConfigRuntimeException(
            "The block at the specified location is not a sign", ExceptionType.RangeException, t);
      }
    }
 public CArray velocity(MCEntity.Velocity v, Target t) {
   double x, y, z, mag;
   x = y = z = mag = 0;
   if (v != null) {
     x = v.x;
     y = v.y;
     z = v.z;
     mag = v.magnitude;
   }
   CArray ret = CArray.GetAssociativeArray(t);
   ret.set("magnitude", new CDouble(mag, t), t);
   ret.set("x", new CDouble(x, t), t);
   ret.set("y", new CDouble(y, t), t);
   ret.set("z", new CDouble(z, t), t);
   return ret;
 }
Exemple #8
0
 /**
  * Returns an array of the keys of all the values that are equal to the value specified
  *
  * @param value
  * @return
  */
 public CArray indexesOf(Construct value) {
   CArray ret = new CArray(Target.UNKNOWN);
   if (associative_mode) {
     for (String key : associative_array.keySet()) {
       if (BasicLogic.equals.doEquals(associative_array.get(key), value)) {
         ret.push(new CString(key, Target.UNKNOWN), Target.UNKNOWN);
       }
     }
   } else {
     for (int i = 0; i < array.size(); i++) {
       if (BasicLogic.equals.doEquals(array.get(i), value)) {
         ret.push(new CInt(i, Target.UNKNOWN), Target.UNKNOWN);
       }
     }
   }
   return ret;
 }
Exemple #9
0
 /**
  * This must be called every time the underlying model is changed, which sets the toString value
  * to dirty, which means that the value will be regenerated next time it is requested.
  */
 private void regenValue(Set<CArray> arrays) {
   if (arrays.contains(this)) {
     return; // Recursive, so don't continue.
   }
   arrays.add(this);
   valueDirty = true;
   if (parent != null) {
     parent.regenValue(arrays);
   }
 }
Exemple #10
0
 @Override
 public CArray clone() {
   CArray clone;
   try {
     clone = (CArray) super.clone();
   } catch (CloneNotSupportedException ex) {
     throw new RuntimeException(ex);
   }
   clone.associative_mode = associative_mode;
   if (!associative_mode) {
     if (array != null) {
       clone.array = new ArrayList<Construct>(this.array);
     }
   } else {
     if (associative_array != null) {
       clone.associative_array = new TreeMap<String, Construct>(this.associative_array);
     }
   }
   clone.regenValue(new HashSet<CArray>());
   return clone;
 }
Exemple #11
0
  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;
  }
 @Override
 public BindableEvent convert(CArray manualObject, Target t) {
   CmdlinePromptInput cpi = new CmdlinePromptInput(manualObject.get("command", t).val());
   return cpi;
 }
Exemple #13
0
 @Override
 public Construct exec(Target t, Environment environment, Construct... args)
     throws ConfigRuntimeException {
   try {
     Profiles.Profile profile;
     if (args[0] instanceof CArray) {
       Map<String, String> data = new HashMap<String, String>();
       for (String key : ((CArray) args[0]).keySet()) {
         data.put(key, ((CArray) args[0]).get(key).val());
       }
       profile = Profiles.getProfile(data);
     } else {
       Profiles profiles = environment.getEnv(GlobalEnv.class).getSQLProfiles();
       profile = profiles.getProfileById(args[0].val());
     }
     String query = args[1].val();
     Construct[] params = new Construct[args.length - 2];
     for (int i = 2; i < args.length; i++) {
       int index = i - 2;
       params[index] = args[i];
     }
     // Parameters are now all parsed into java objects.
     Connection conn = DriverManager.getConnection(profile.getConnectionString());
     PreparedStatement ps = null;
     try {
       ps = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
       for (int i = 0; i < params.length; i++) {
         int type = ps.getParameterMetaData().getParameterType(i + 1);
         if (params[i] == null) {
           if (ps.getParameterMetaData().isNullable(i + 1)
               == ParameterMetaData.parameterNoNulls) {
             throw new ConfigRuntimeException(
                 "Parameter "
                     + (i + 1)
                     + " cannot be set to null. Check your parameters and try again.",
                 ExceptionType.SQLException,
                 t);
           } else {
             ps.setNull(i + 1, type);
             continue;
           }
         }
         try {
           if (params[i] instanceof CInt) {
             ps.setLong(i + 1, Static.getInt(params[i], t));
           } else if (params[i] instanceof CDouble) {
             ps.setDouble(i + 1, (Double) Static.getDouble(params[i], t));
           } else if (params[i] instanceof CString) {
             ps.setString(i + 1, (String) params[i].val());
           } else if (params[i] instanceof CByteArray) {
             ps.setBytes(i + 1, ((CByteArray) params[i]).asByteArrayCopy());
           } else if (params[i] instanceof CBoolean) {
             ps.setBoolean(i + 1, Static.getBoolean(params[i]));
           } else {
             throw new ConfigRuntimeException(
                 "The type "
                     + params[i].getClass().getSimpleName()
                     + " of parameter "
                     + (i + 1)
                     + " is not supported.",
                 ExceptionType.CastException,
                 t);
           }
         } catch (ClassCastException ex) {
           throw new ConfigRuntimeException(
               "Could not cast parameter "
                   + (i + 1)
                   + " to "
                   + ps.getParameterMetaData().getParameterTypeName(i + 1)
                   + " from "
                   + params[i].getClass().getSimpleName()
                   + ".",
               ExceptionType.CastException,
               t,
               ex);
         }
       }
       boolean isResultSet = ps.execute();
       if (isResultSet) {
         // Result set
         CArray ret = new CArray(t);
         ResultSetMetaData md = ps.getMetaData();
         ResultSet rs = ps.getResultSet();
         while (rs.next()) {
           CArray row = new CArray(t);
           for (int i = 1; i <= md.getColumnCount(); i++) {
             Construct value;
             int columnType = md.getColumnType(i);
             if (columnType == Types.INTEGER
                 || columnType == Types.TINYINT
                 || columnType == Types.SMALLINT
                 || columnType == Types.BIGINT) {
               value = new CInt(rs.getLong(i), t);
             } else if (columnType == Types.FLOAT
                 || columnType == Types.DOUBLE
                 || columnType == Types.REAL
                 || columnType == Types.DECIMAL
                 || columnType == Types.NUMERIC) {
               value = new CDouble(rs.getDouble(i), t);
             } else if (columnType == Types.VARCHAR
                 || columnType == Types.CHAR
                 || columnType == Types.LONGVARCHAR) {
               value = new CString(rs.getString(i), t);
             } else if (columnType == Types.BLOB
                 || columnType == Types.BINARY
                 || columnType == Types.VARBINARY
                 || columnType == Types.LONGVARBINARY) {
               value = CByteArray.wrap(rs.getBytes(i), t);
             } else if (columnType == Types.DATE
                 || columnType == Types.TIME
                 || columnType == Types.TIMESTAMP) {
               if (md.getColumnTypeName(i).equals("YEAR")) {
                 value = new CInt(rs.getLong(i), t);
               } else {
                 value = new CInt(rs.getTimestamp(i).getTime(), t);
               }
             } else if (columnType == Types.BOOLEAN || columnType == Types.BIT) {
               value = new CBoolean(rs.getBoolean(i), t);
             } else {
               throw new ConfigRuntimeException(
                   "SQL returned a unhandled column type "
                       + md.getColumnTypeName(i)
                       + " for column "
                       + md.getColumnName(i)
                       + ".",
                   ExceptionType.CastException,
                   t);
             }
             row.set(md.getColumnName(i), value, t);
           }
           ret.push(row);
         }
         return ret;
       } else {
         ResultSet rs = ps.getGeneratedKeys();
         if (rs.next()) {
           // This was an insert or something that returned generated keys. So we return
           // that here.
           return new CInt(rs.getInt(1), t);
         }
         // Update count. Just return null.
         return new CNull(t);
       }
     } finally {
       if (ps != null) {
         ps.close();
       }
       if (conn != null) {
         conn.close();
       }
     }
   } catch (Profiles.InvalidProfileException ex) {
     throw new ConfigRuntimeException(ex.getMessage(), ExceptionType.SQLException, t, ex);
   } catch (SQLException ex) {
     throw new ConfigRuntimeException(ex.getMessage(), ExceptionType.SQLException, t, ex);
   }
 }
 /**
  * Gets a Location Object, given a MCLocation
  *
  * @param l
  * @return
  */
 public CArray location(MCLocation l) {
   CArray ca = CArray.GetAssociativeArray(Target.UNKNOWN);
   Construct x = new CDouble(l.getX(), Target.UNKNOWN);
   Construct y = new CDouble(l.getY(), Target.UNKNOWN);
   Construct z = new CDouble(l.getZ(), Target.UNKNOWN);
   Construct world = new CString(l.getWorld().getName(), Target.UNKNOWN);
   Construct yaw = new CDouble(l.getYaw(), Target.UNKNOWN);
   Construct pitch = new CDouble(l.getPitch(), Target.UNKNOWN);
   ca.set("0", x, Target.UNKNOWN);
   ca.set("1", y, Target.UNKNOWN);
   ca.set("2", z, Target.UNKNOWN);
   ca.set("3", world, Target.UNKNOWN);
   ca.set("4", yaw, Target.UNKNOWN);
   ca.set("5", pitch, Target.UNKNOWN);
   ca.set("x", x, Target.UNKNOWN);
   ca.set("y", y, Target.UNKNOWN);
   ca.set("z", z, Target.UNKNOWN);
   ca.set("world", world, Target.UNKNOWN);
   ca.set("yaw", yaw, Target.UNKNOWN);
   ca.set("pitch", pitch, Target.UNKNOWN);
   return ca;
 }
 public MCEntity.Velocity velocity(Construct c, Target t) {
   CArray va;
   double x, y, z, mag;
   x = y = z = mag = 0;
   if (c instanceof CArray) {
     va = (CArray) c;
     if (va.containsKey("x")) {
       x = Static.getDouble(va.get("x"), t);
     }
     if (va.containsKey("y")) {
       y = Static.getDouble(va.get("y"), t);
     }
     if (va.containsKey("z")) {
       z = Static.getDouble(va.get("z"), t);
     }
     if (!va.containsKey("x") && !va.containsKey("y") && !va.containsKey("z")) {
       switch ((int) va.size()) {
         case 4:
           z = Static.getDouble(va.get(3), t);
           y = Static.getDouble(va.get(2), t);
           x = Static.getDouble(va.get(1), t);
           break;
         case 3:
           z = Static.getDouble(va.get(2), t);
         case 2:
           y = Static.getDouble(va.get(1), t);
         case 1:
           x = Static.getDouble(va.get(0), t);
       }
     }
     return new MCEntity.Velocity(mag, x, y, z);
   } else {
     throw new Exceptions.FormatException("Expected an array but recieved " + c, t);
   }
 }
 /**
  * Returns an MCColor given a colorArray, which supports the following three format types (in this
  * order of priority) array(r: 0, g: 0, b: 0) array(red: 0, green: 0, blue: 0) array(0, 0, 0)
  *
  * @param color
  * @param t
  * @return
  */
 public MCColor color(CArray color, Target t) {
   int red;
   int green;
   int blue;
   if (color.containsKey("r")) {
     red = Static.getInt32(color.get("r"), t);
   } else if (color.containsKey("red")) {
     red = Static.getInt32(color.get("red"), t);
   } else {
     red = Static.getInt32(color.get(0), t);
   }
   if (color.containsKey("g")) {
     green = Static.getInt32(color.get("g"), t);
   } else if (color.containsKey("green")) {
     green = Static.getInt32(color.get("green"), t);
   } else {
     green = Static.getInt32(color.get(1), t);
   }
   if (color.containsKey("b")) {
     blue = Static.getInt32(color.get("b"), t);
   } else if (color.containsKey("blue")) {
     blue = Static.getInt32(color.get("blue"), t);
   } else {
     blue = Static.getInt32(color.get(2), t);
   }
   return StaticLayer.GetConvertor().GetColor(red, green, blue);
 }
  /**
   * An Item Object consists of data about a particular item stack. Information included is: type,
   * data, qty, and an array of enchantment objects (labeled enchants): etype (enchantment type) and
   * elevel (enchantment level). For backwards compatibility, this information is also listed in
   * numerical slots as well as associative slots. If the MCItemStack is null, or the underlying
   * item is nonexistant (or air) CNull is returned.
   *
   * @param is
   * @return
   */
  public Construct item(MCItemStack is, Target t) {
    if (is == null || is.getAmount() == 0) {
      return new CNull(t);
    }
    int type = is.getTypeId();

    int data;
    if (type < 256) {
      // Use the data
      data = (is.getData() != null ? is.getData().getData() : 0);
    } else {
      // Use the durability
      data = is.getDurability();
    }
    int qty = is.getAmount();
    CArray enchants = new CArray(t);
    for (Map.Entry<MCEnchantment, Integer> entry : is.getEnchantments().entrySet()) {
      CArray enchObj = CArray.GetAssociativeArray(t);
      enchObj.set("etype", new CString(entry.getKey().getName(), t), t);
      enchObj.set("elevel", new CInt(entry.getValue(), t), t);
      enchants.push(enchObj);
    }
    Construct meta = itemMeta(is, t);
    CArray ret = CArray.GetAssociativeArray(t);
    ret.set("type", Integer.toString(type));
    ret.set("data", Integer.toString(data));
    ret.set("qty", Integer.toString(qty));
    ret.set("enchants", enchants, t);
    ret.set("meta", meta, t);
    return ret;
  }
  /**
   * 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;
  }
 public MCItemMeta itemMeta(Construct c, int i, Target t) {
   MCItemMeta meta =
       Static.getServer().getItemFactory().getItemMeta(StaticLayer.GetConvertor().getMaterial(i));
   if (c instanceof CNull) {
     return meta;
   }
   CArray ma = null;
   if (c instanceof CArray) {
     ma = (CArray) c;
     try {
       if (ma.containsKey("display")) {
         Construct dni = ma.get("display");
         if (!(dni instanceof CNull)) {
           meta.setDisplayName(dni.val());
         }
       }
       if (ma.containsKey("lore")) {
         Construct li = ma.get("lore");
         if (li instanceof CNull) {
           // do nothing
         } else if (li instanceof CArray) {
           CArray la = (CArray) li;
           List<String> ll = new ArrayList<String>();
           for (int j = 0; j < la.size(); j++) {
             ll.add(la.get(j).val());
           }
           meta.setLore(ll);
         } else {
           throw new Exceptions.FormatException("Lore was expected to be an array.", t);
         }
       }
       if (meta instanceof MCLeatherArmorMeta) {
         if (ma.containsKey("color")) {
           Construct ci = ma.get("color");
           if (ci instanceof CNull) {
             // nothing
           } else if (ci instanceof CArray) {
             ((MCLeatherArmorMeta) meta).setColor(color((CArray) ci, t));
           } else {
             throw new Exceptions.FormatException("Color was expected to be an array.", t);
           }
         }
       }
       if (meta instanceof MCBookMeta) {
         if (ma.containsKey("title")) {
           Construct title = ma.get("title");
           if (!(title instanceof CNull)) {
             ((MCBookMeta) meta).setTitle(title.val());
           }
         }
         if (ma.containsKey("author")) {
           Construct author = ma.get("author");
           if (!(author instanceof CNull)) {
             ((MCBookMeta) meta).setAuthor(author.val());
           }
         }
         if (ma.containsKey("pages")) {
           Construct pages = ma.get("pages");
           if (pages instanceof CNull) {
             // nothing
           } else if (pages instanceof CArray) {
             CArray pa = (CArray) pages;
             List<String> pl = new ArrayList<String>();
             for (int j = 0; j < pa.size(); j++) {
               pl.add(pa.get(j).val());
             }
             ((MCBookMeta) meta).setPages(pl);
           } else {
             throw new Exceptions.FormatException("Pages field was expected to be an array.", t);
           }
         }
       }
       if (meta instanceof MCSkullMeta) {
         if (ma.containsKey("owner")) {
           Construct owner = ma.get("owner");
           if (!(owner instanceof CNull)) {
             ((MCSkullMeta) meta).setOwner(owner.val());
           }
         }
       }
       if (meta instanceof MCEnchantmentStorageMeta) {
         if (ma.containsKey("stored")) {
           Construct stored = ma.get("stored");
           if (stored instanceof CNull) {
             // Still doing nothing
           } else if (stored instanceof CArray) {
             for (String index : ((CArray) stored).keySet()) {
               try {
                 CArray earray = (CArray) ((CArray) stored).get(index);
                 MCEnchantment etype =
                     StaticLayer.GetConvertor().GetEnchantmentByName(earray.get("etype").val());
                 int elevel = Static.getInt32(earray.get("elevel"), t);
                 ((MCEnchantmentStorageMeta) meta).addStoredEnchant(etype, elevel, true);
               } catch (Exception bade) {
                 throw new Exceptions.FormatException(
                     "Could not get enchantment data from index " + index, t);
               }
             }
           } else {
             throw new Exceptions.FormatException(
                 "Stored field was expected to be an array of Enchantment arrays", t);
           }
         }
       }
     } catch (Exception ex) {
       throw new Exceptions.FormatException(
           "Could not get ItemMeta from the given information.", t);
     }
   } else {
     throw new Exceptions.FormatException(
         "An array was expected but recieved " + c + " instead.", t);
   }
   return meta;
 }
 /**
  * Given a Location Object, returns a MCLocation. If the optional world is not specified in the
  * object, the world provided is used instead. Location "objects" are MethodScript arrays that
  * represent a location in game. There are 4 usages:
  *
  * <ul>
  *   <li>(x, y, z)
  *   <li>(x, y, z, world)
  *   <li>(x, y, z, yaw, pitch)
  *   <li>(x, y, z, world, yaw, pitch)
  * </ul>
  *
  * In all cases, the pitch and yaw default to 0, and the world defaults to the specified world.
  * <em>More conveniently: ([world], x, y, z, [yaw, pitch])</em>
  */
 public MCLocation location(Construct c, MCWorld w, Target t) {
   if (!(c instanceof CArray)) {
     throw new ConfigRuntimeException(
         "Expecting an array, received " + c.getCType(), ExceptionType.FormatException, t);
   }
   CArray array = (CArray) c;
   MCWorld world = w;
   double x = 0;
   double y = 0;
   double z = 0;
   float yaw = 0;
   float pitch = 0;
   if (!array.inAssociativeMode()) {
     if (array.size() == 3) {
       // Just the xyz, with default yaw and pitch, and given world
       x = Static.getNumber(array.get(0, t), t);
       y = Static.getNumber(array.get(1, t), t);
       z = Static.getNumber(array.get(2, t), t);
     } else if (array.size() == 4) {
       // x, y, z, world
       x = Static.getNumber(array.get(0, t), t);
       y = Static.getNumber(array.get(1, t), t);
       z = Static.getNumber(array.get(2, t), t);
       world = Static.getServer().getWorld(array.get(3, t).val());
     } else if (array.size() == 5) {
       // x, y, z, yaw, pitch, with given world
       x = Static.getNumber(array.get(0, t), t);
       y = Static.getNumber(array.get(1, t), t);
       z = Static.getNumber(array.get(2, t), t);
       yaw = (float) Static.getNumber(array.get(3, t), t);
       pitch = (float) Static.getNumber(array.get(4, t), t);
     } else if (array.size() == 6) {
       // All have been given
       x = Static.getNumber(array.get(0, t), t);
       y = Static.getNumber(array.get(1, t), t);
       z = Static.getNumber(array.get(2, t), t);
       world = Static.getServer().getWorld(array.get(3, t).val());
       yaw = (float) Static.getNumber(array.get(4, t), t);
       pitch = (float) Static.getNumber(array.get(5, t), t);
     } else {
       throw new ConfigRuntimeException(
           "Expecting a Location array, but the array did not meet the format specifications",
           ExceptionType.FormatException,
           t);
     }
   }
   if (array.containsKey("x")) {
     x = Static.getNumber(array.get("x"), t);
   }
   if (array.containsKey("y")) {
     y = Static.getNumber(array.get("y"), t);
   }
   if (array.containsKey("z")) {
     z = Static.getNumber(array.get("z"), t);
   }
   if (array.containsKey("world")) {
     world = Static.getServer().getWorld(array.get("world").val());
   }
   if (array.containsKey("yaw")) {
     yaw = (float) Static.getDouble(array.get("yaw"), t);
   }
   if (array.containsKey("pitch")) {
     pitch = (float) Static.getDouble(array.get("pitch"), t);
   }
   // If world is still null at this point, it's an error
   if (world == null) {
     throw new ConfigRuntimeException(
         "The specified world doesn't exist, or no world was provided",
         ExceptionType.InvalidWorldException,
         t);
   }
   return StaticLayer.GetLocation(world, x, y, z, yaw, pitch);
 }
 public Construct itemMeta(MCItemStack is, Target t) {
   Construct ret, display, lore, color, title, author, pages, owner, stored;
   if (!is.hasItemMeta()) {
     ret = new CNull(t);
   } else {
     ret = CArray.GetAssociativeArray(t);
     MCItemMeta meta = is.getItemMeta();
     if (meta.hasDisplayName()) {
       display = new CString(meta.getDisplayName(), t);
     } else {
       display = new CNull(t);
     }
     if (meta.hasLore()) {
       lore = new CArray(t);
       for (String l : meta.getLore()) {
         ((CArray) lore).push(new CString(l, t));
       }
     } else {
       lore = new CNull(t);
     }
     ((CArray) ret).set("display", display, t);
     ((CArray) ret).set("lore", lore, t);
     if (meta instanceof MCLeatherArmorMeta) {
       color = color(((MCLeatherArmorMeta) meta).getColor(), t);
       ((CArray) ret).set("color", color, t);
     }
     if (meta instanceof MCBookMeta) {
       if (((MCBookMeta) meta).hasTitle()) {
         title = new CString(((MCBookMeta) meta).getTitle(), t);
       } else {
         title = new CNull(t);
       }
       if (((MCBookMeta) meta).hasAuthor()) {
         author = new CString(((MCBookMeta) meta).getAuthor(), t);
       } else {
         author = new CNull(t);
       }
       if (((MCBookMeta) meta).hasPages()) {
         pages = new CArray(t);
         for (String p : ((MCBookMeta) meta).getPages()) {
           ((CArray) pages).push(new CString(p, t));
         }
       } else {
         pages = new CNull(t);
       }
       ((CArray) ret).set("title", title, t);
       ((CArray) ret).set("author", author, t);
       ((CArray) ret).set("pages", pages, t);
     }
     if (meta instanceof MCSkullMeta) {
       if (((MCSkullMeta) meta).hasOwner()) {
         owner = new CString(((MCSkullMeta) meta).getOwner(), t);
       } else {
         owner = new CNull(t);
       }
       ((CArray) ret).set("owner", owner, t);
     }
     if (meta instanceof MCEnchantmentStorageMeta) {
       if (((MCEnchantmentStorageMeta) meta).hasStoredEnchants()) {
         stored = new CArray(t);
         for (Map.Entry<MCEnchantment, Integer> entry :
             ((MCEnchantmentStorageMeta) meta).getStoredEnchants().entrySet()) {
           CArray eObj = CArray.GetAssociativeArray(t);
           eObj.set("etype", new CString(entry.getKey().getName(), t), t);
           eObj.set("elevel", new CInt(entry.getValue(), t), t);
           ((CArray) stored).push(eObj);
         }
       } else {
         stored = new CNull(t);
       }
       ((CArray) ret).set("stored", stored, t);
     }
   }
   return ret;
 }