Beispiel #1
0
  /**
   * Set the contents of an ItemArray.
   *
   * @param itemArray
   * @param contents
   */
  public static void setContents(ItemArray<?> itemArray, Item[] contents) {
    int size = itemArray.getContentsSize();

    for (int i = 0; i < size; i++) {
      if (contents[i] == null) {
        itemArray.removeItem(i);
      } else {
        itemArray.setSlot(contents[i], i);
      }
    }
  }
  /**
   * The class is called to determine behavior of program based on instruction at current position.
   * The function is part of indirect recursion with method runInstructions which is called when the
   * conditional split is required.
   *
   * <p>The function covers basic operands for pushing integers and (string) objects stack as long
   * as retrieving them back. Also it covers conditions for not null and null operations which
   * results into separate execution of both branches conditioned on item on stack.
   *
   * @param instruction "on the stack"
   * @return 0 - no dangerous, end; 1 - continue in check
   * @throws DangerousPatternException when dangerous pattern found
   */
  private int watchOpcode(InstructionHandle instruction) throws DangerousPatternException {

    short opcode = instruction.getInstruction().getOpcode();
    ItemInt tempItemInt;
    Item temp;
    switch (opcode) {
      case ICONST_0:
        tempItemInt = new ItemInt(false);
        tempItemInt.setValue(0);
        this.push(tempItemInt);
        break;
      case ICONST_1:
        tempItemInt = new ItemInt(false);
        tempItemInt.setValue(1);
        this.push(tempItemInt);
        break;
      case ICONST_2:
        tempItemInt = new ItemInt(false);
        tempItemInt.setValue(2);
        this.push(tempItemInt);
        break;
      case ICONST_M1:
        tempItemInt = new ItemInt(false);
        tempItemInt.setValue(-1);
        this.push(tempItemInt);
        break;
      case RETURN:
        return 0;
      case ARETURN:
      case IRETURN:
        this.pop();
        return 0;
      case ACONST_NULL:
        temp = new Item(true);
        this.push(temp);
        break;
      case ALOAD_1:
        this.push(this.takeFromItemPool(1));
        break;
      case ALOAD_2:
        this.push(this.takeFromItemPool(2));
        break;
      case ALOAD_3:
        this.push(this.takeFromItemPool(3));
        break;
      case ALOAD:
        this.push(this.takeFromItemPool(this.parseValue(instruction, " ")));
        break;
      case AALOAD:
        // TODO: Rework. Outer variables would be nicer!
        tempItemInt = (ItemInt) this.pop();
        temp = this.pop();
        ItemArray list;

        if (temp instanceof ItemArray) {
          list = (ItemArray) temp;
          this.push(list.getItem(tempItemInt.getValue()));
        } else {
          list = new ItemArray();
          list.setAddress(temp.getAddress());
          this.putToItemPool(list);
          temp.setAddress(-1);
          this.push(temp);
        }

        break;
      case AASTORE:
        Item value = this.pop();
        tempItemInt = (ItemInt) this.pop();
        temp = this.pop();
        ItemArray list2;

        if (temp instanceof ItemArray) {
          list2 = (ItemArray) temp;
          list2.putItem(tempItemInt.getValue(), value);
        } else {
          list2 = new ItemArray();
          list2.setAddress(temp.getAddress());
          list2.putItem(tempItemInt.getValue(), value);
          this.putToItemPool(list2);
        }
        break;
      case LDC:
        temp = new Item(false);
        this.push(temp);
        break;
      case ASTORE_1:
        temp = this.pop();
        temp.setAddress(1);
        this.putToItemPool(temp);
        break;
      case ASTORE_2:
        temp = this.pop();
        temp.setAddress(2);
        this.putToItemPool(temp);
        break;
      case ASTORE_3:
        temp = this.pop();
        temp.setAddress(3);
        this.putToItemPool(temp);
        break;
      case ASTORE:
        temp = this.pop();
        temp.setAddress(this.parseValue(instruction, " "));
        this.putToItemPool(temp);
        break;
      case INVOKEVIRTUAL:
        if (this.lookAtStack().isDangerous()) {
          throw new DangerousPatternException("Possibility of invoking method on null object");
        }
        break;
      case IFNONNULL:
        temp = this.pop();
        // TODO: make local variable fot that item, this is ugly
        if (temp.isDangerous()) {
          temp.setDangerous(false);
          this.putToItemPool(temp);
          this.runInstructions(this.parseValue(instruction, " -> "));
          temp.setDangerous(true);
        } else {
          this.putToItemPool(temp);
          this.runInstructions(this.parseValue(instruction, " -> "));
          return 0;
        }
        break;
      case IFNULL:
        temp = this.pop();
        if (temp.isDangerous()) {
          this.putToItemPool(temp);
          this.runInstructions(this.parseValue(instruction, " -> "));
          return 0;
        } else {
          this.putToItemPool(temp);
        }
        break;
      case POP:
        this.pop();
        break;
      default:
        Logger.getLogger(BugPatternDetectorImpl.class.getName())
            .log(
                Level.WARNING,
                "The unknown opcode called: " + instruction.getInstruction().getName());
        break;
    }
    return 1;
  }
Beispiel #3
0
  public static void moveItemArrayToChestBag(
      ItemArray<?> from, NearbyChestBlockBag bag, int itemType, int itemColor, int itemAmount) {

    Item[] fromItems = from.getContents();
    Inventory[] inventories = bag.getInventories();
    int invenIndex = 0;
    boolean changed = false;

    int currentAmount = 0;

    try {
      for (int cartSlot = 0; cartSlot < fromItems.length; cartSlot++) {
        Item cartItem = fromItems[cartSlot];

        if (cartItem == null
            || cartItem.getAmount() == 0
            || (itemType > 0
                && (itemType != cartItem.getItemId()
                    || (itemColor != -1 && itemColor != cartItem.getDamage())))) {
          continue;
        }

        currentAmount += cartItem.getAmount();
        Item itemCopy = null;

        if (itemAmount > 0 && currentAmount > itemAmount) {
          itemCopy =
              new Item(
                  cartItem.getItemId(),
                  currentAmount - itemAmount,
                  cartItem.getSlot(),
                  cartItem.getDamage());

          cartItem.setAmount(cartItem.getAmount() - itemCopy.getAmount());
        }

        try {
          for (; invenIndex < inventories.length; invenIndex++) {
            Item[] chestItems = inventories[invenIndex].getContents();

            for (int chestSlot = 0; chestSlot < chestItems.length; chestSlot++) {
              Item chestItem = chestItems[chestSlot];

              if (chestItem == null) {
                chestItems[chestSlot] = cartItem;
                fromItems[cartSlot] = null;
                setContents(inventories[invenIndex], chestItems);
                changed = true;
                throw new TransferredItemException();
              } else {

                int maxStack = getStackMax(chestItem);

                if (chestItem.getItemId() == cartItem.getItemId()
                    && isSameColor(chestItem, cartItem)
                    && chestItem.getAmount() < maxStack
                    && chestItem.getAmount() >= 0) {
                  int spaceAvailable = maxStack - chestItem.getAmount();

                  if (spaceAvailable >= cartItem.getAmount()) {
                    chestItem.setAmount(chestItem.getAmount() + cartItem.getAmount());
                    fromItems[cartSlot] = null;
                    setContents(inventories[invenIndex], chestItems);
                    changed = true;
                    throw new TransferredItemException();
                  } else {
                    cartItem.setAmount(cartItem.getAmount() - spaceAvailable);
                    chestItem.setAmount(maxStack);
                    changed = true;
                  }
                }
              }
            }

            if (changed) {
              setContents(inventories[invenIndex], chestItems);
            }
          }

          throw new TargetFullException();
        } catch (TransferredItemException e) {
        }

        if (itemAmount > 0 && currentAmount >= itemAmount) {
          if (itemCopy != null) {
            if (fromItems[cartSlot] != null) {
              itemCopy.setAmount(itemCopy.getAmount() + fromItems[cartSlot].getAmount());
            }

            fromItems[cartSlot] = itemCopy;
          }
          break;
        }
      }
    } catch (TargetFullException e) {
    }

    if (changed) {
      setContents(from, fromItems);
    }
  }
Beispiel #4
0
  /*
   * M4411K4: redoing code here because the last code from
   * I guess sk89q, didn't work properly and used more resources
   * than should have (using exceptions to break? o_O)
   */
  public static void moveChestBagToItemArray(
      ItemArray<?> to, NearbyChestBlockBag bag, int itemType, int itemColor, int itemAmount) {

    Item[] toItems = to.getContents();
    Inventory[] bags = bag.getInventories();
    boolean changed = false;
    int currentAmount = 0;

    for (int toSlot = 0; toSlot < toItems.length; toSlot++) {
      Item toItem = toItems[toSlot];
      int maxStack = 0;
      if (toItem != null) {
        maxStack = getStackMax(toItem);
        if (toItem.getAmount() >= maxStack
            || (itemType > 0
                && (itemType != toItem.getItemId()
                    || (itemColor != -1 && itemColor != toItem.getDamage())))) {
          continue;
        }
      }

      boolean moved = false;

      for (Inventory inventory : bags) {
        Item[] chestItems = inventory.getContents();
        for (int chestSlot = 0; chestSlot < chestItems.length; chestSlot++) {
          Item chestItem = chestItems[chestSlot];
          if (chestItem == null
              || chestItem.getAmount() == 0
              || (toItem != null
                  && (chestItem.getItemId() != toItem.getItemId()
                      || chestItem.getDamage() != toItem.getDamage()))
              || (itemType > 0
                  && (itemType != chestItem.getItemId()
                      || (itemColor != -1 && itemColor != chestItem.getDamage())))) {
            // empty or not the same item so move on to next slot
            continue;
          }

          currentAmount += chestItem.getAmount();
          Item itemCopy = null;
          if (itemAmount > 0 && currentAmount > itemAmount) {
            itemCopy =
                new Item(
                    chestItem.getItemId(),
                    currentAmount - itemAmount,
                    chestItem.getSlot(),
                    chestItem.getDamage());

            chestItem.setAmount(chestItem.getAmount() - itemCopy.getAmount());
          }

          // can move to slot
          if (toItem == null) {
            toItems[toSlot] = chestItem;
            chestItems[chestSlot] = null;
          } else {
            // maxStack should have correct value since toItem is not null
            int spaceAvailable = maxStack - toItem.getAmount();
            if (spaceAvailable >= chestItem.getAmount()) {
              // everything fits
              toItem.setAmount(toItem.getAmount() + chestItem.getAmount());
              chestItems[chestSlot] = null;
            } else {
              // doesn't fit into slot
              toItem.setAmount(maxStack);
              chestItem.setAmount(chestItem.getAmount() - spaceAvailable);
            }
          }

          // if not max, re-check slot
          maxStack = getStackMax(toItems[toSlot]);
          if (toItems[toSlot].getAmount() < maxStack) {
            toSlot--;
          }

          if (itemCopy != null) {
            if (chestItems[chestSlot] != null) {
              itemCopy.setAmount(itemCopy.getAmount() + chestItems[chestSlot].getAmount());
            }

            chestItems[chestSlot] = itemCopy;
          }

          moved = true;
          changed = true;
          break;
        }

        if (moved || (itemAmount > 0 && currentAmount >= itemAmount)) {
          // set chest items with new values
          setContents(inventory, chestItems);

          // go to next item slot
          break;
        }
      }

      if (itemAmount > 0 && currentAmount >= itemAmount) {
        break;
      }
    }

    if (changed) {
      setContents(to, toItems);
    }
  }