Package org.rsbot.script.methods

Source Code of org.rsbot.script.methods.Interfaces

package org.rsbot.script.methods;

import org.rsbot.script.wrappers.RSComponent;
import org.rsbot.script.wrappers.RSInterface;

import java.util.*;
import java.util.List;

/**
* Provides access to interfaces.
*/
public class Interfaces extends MethodProvider {
  Interfaces(final MethodContext ctx) {
    super(ctx);
  }

  // A cache of all the interfaces. Only as big as the maximum size of the
  // client's cache.
  private RSInterface[] mainCache = new RSInterface[0];
  // If it doesn't fit in the above cache.
  private final Map<Integer, RSInterface> sparseMap = new HashMap<Integer, RSInterface>();

  /**
   * @return <code>RSInterface</code> array containing all valid interfaces.
   */
  public synchronized RSInterface[] getAll() {
    enlargeCache();
    final org.rsbot.client.RSInterface[][] inters = methods.client
        .getRSInterfaceCache();
    if (inters == null) {
      return new RSInterface[0];
    }
    final List<RSInterface> out = new ArrayList<RSInterface>();
    for (int i = 0; i < inters.length; i++) {
      if (inters[i] != null) {
        final RSInterface in = get(i);
        if (in.isValid()) {
          out.add(in);
        }
      }
    }
    return out.toArray(new RSInterface[out.size()]);
  }

  /**
   * @param index The index of the interface.
   * @return The <tt>RSInterface</tt> for the given index.
   */
  public synchronized RSInterface get(final int index) {
    RSInterface inter;
    final int cacheLen = mainCache.length;
    if (index < cacheLen) {
      inter = mainCache[index];
      if (inter == null) {
        inter = new RSInterface(methods, index);
        mainCache[index] = inter;
      }
    } else {
      inter = sparseMap.get(index);
      if (inter == null) {
        enlargeCache();
        if (index < cacheLen) {
          inter = mainCache[index];
          if (inter == null) {
            inter = new RSInterface(methods, index);
            mainCache[index] = inter;
          }
        } else {
          inter = new RSInterface(methods, index);
          sparseMap.put(index, inter);
        }
      }
    }
    return inter;
  }

  /**
   * @param index      The parent interface index
   * @param childIndex The component index
   * @return <tt>RSComponent</tt> for the given index and child index.
   */
  public RSComponent getComponent(final int index, final int childIndex) {
    return get(index).getComponent(childIndex);
  }

  /**
   * @param id The packed interface index ((x << 16) | (y & 0xFFFF)).
   * @return <tt>RSComponent</tt> for the given interface id.
   */
  public RSComponent getComponent(final int id) {
    final int x = id >> 16;
    final int y = id & 0xFFFF;
    return get(x).getComponent(y);
  }

  /**
   * @return The maximum known interface cache size.
   */
  public synchronized int getMaxCacheSize() {
    enlargeCache();
    return mainCache.length;
  }

  /**
   * @return <tt>true</tt> if continue component is valid; otherwise
   *         <tt>false</tt>.
   */
  public boolean canContinue() {
    return getContinueComponent() != null;
  }

  /**
   * @return <tt>true</tt> if continue component was clicked; otherwise
   *         <tt>false</tt>.
   */
  public boolean clickContinue() {
    final RSComponent cont = getContinueComponent();
    return cont != null && cont.isValid() && cont.doClick(true);
  }

  /**
   * @return <tt>RSComponent</tt> containing "Click here to continue";
   *         otherwise null.
   */
  public RSComponent getContinueComponent() {
    if (methods.client.getRSInterfaceCache() == null) {
      return null;
    }
    final RSInterface[] valid = getAll();
    for (final RSInterface iface : valid) {
      if (iface.getIndex() == 137 || iface.getIndex() == 752)
        continue;
      for (final RSComponent c : iface.getComponents()) {
        if (c.containsText("Click here to continue") && c.isValid() && c.getAbsoluteX() > 10 && c.getAbsoluteY() > 300) {
          return c;
        }
      }
    }
    return null;
  }

  /**
   * Performs the given action on this RSInterfaceChild if it is showing
   * (valid).
   *
   * @param c      The component to interact with.
   * @param action The menu action to click.
   * @return <tt>true</tt> if the action was clicked; otherwise <tt>false</tt>.
   *
   * @deprecated Use RSComponent.interact(String action) instead.
   */
  public boolean clickComponent(final RSComponent c, final String action) {
    return c.interact(action);
  }

  /**
   * Clicks the dialogue option that contains the desired string.
   *
   * @param inter  The interface of the dialogue menu.
   * @param option The text we want to click.
   * @return <tt>true</tt> if the option was clicked; otherwise <tt>false</tt>
   *         .
   */
  public boolean clickDialogueOption(final RSInterface inter, String option) {
    // This is superfluous but it just makes life a little easier
    // so you don't have to look up the component.
    // Just grab the interface and the text you want to click.
    if (inter.isValid()) {
      option = option.toLowerCase();
      for (final RSComponent c : inter.getComponents()) {
        if (c.getText().toLowerCase().contains(option)) {
          return c.doClick();
        }
      }
    }
    return false;
  }

  /**
   * @param text The text to search each interface for.
   * @return <tt>RSInterface</tt> array of the interfaces containing specified
   *         text.
   */
  public RSInterface[] getAllContaining(final String text) {
    final java.util.List<RSInterface> results = new LinkedList<RSInterface>();
    for (final RSInterface iface : getAll()) {
      if (iface.getText().toLowerCase().contains(text.toLowerCase())) {
        results.add(iface);
      }
    }
    return results.toArray(new RSInterface[results.size()]);
  }

  /**
   * Scrolls to the component
   *
   * @param component   component to scroll to
   * @param scrollBarID scrollbar to scroll with
   * @return true when scrolled successfully
   */
  public boolean scrollTo(final RSComponent component, final int scrollBarID) {
    final RSComponent scrollBar = getComponent(scrollBarID);

    return scrollTo(component, scrollBar);
  }

  /**
   * Scrolls to the component
   *
   * @param component component to scroll to
   * @param scrollBar scrollbar to scroll with
   * @return true when scrolled successfully
   */
  public boolean scrollTo(final RSComponent component, final RSComponent scrollBar) {
    // Check arguments
    if (component == null || scrollBar == null || !component.isValid()) {
      return false;
    }

    if (scrollBar.getComponents().length != 6) {
      return true; // no scrollbar, so probably not scrollable
    }

    // Find scrollable area
    RSComponent scrollableArea = component;
    while (scrollableArea.getScrollableContentHeight() == 0
        && scrollableArea.getParentID() != -1) {
      scrollableArea = getComponent(scrollableArea.getParentID());
    }

    // Check scrollable area
    if (scrollableArea.getScrollableContentHeight() == 0) {
      return false;
    }

    // Get scrollable area height
    final int areaY = scrollableArea.getAbsoluteY();
    final int areaHeight = scrollableArea.getRealHeight();

    // Check if the component is already visible
    if (component.getAbsoluteY() >= areaY
        && component.getAbsoluteY() <= areaY + areaHeight
        - component.getRealHeight()) {
      return true;
    }

    // Calculate scroll bar position to click
    final RSComponent scrollBarArea = scrollBar.getComponent(0);
    final int contentHeight = scrollableArea.getScrollableContentHeight();

    int pos = (int) ((float) scrollBarArea.getRealHeight() / contentHeight * (component.getRelativeY() + random(-areaHeight / 2, areaHeight / 2 - component.getRealHeight())));
    if (pos < 0) // inner
    {
      pos = 0;
    } else if (pos >= scrollBarArea.getRealHeight()) {
      pos = scrollBarArea.getRealHeight() - 1; // outer
    }

    // Click on the scrollbar
    methods.mouse.click(scrollBarArea.getAbsoluteX() + random(0, scrollBarArea.getRealWidth()), scrollBarArea.getAbsoluteY() + pos, true);

    // Wait a bit
    sleep(random(200, 400));

    // Scroll to it if we missed it
    while (component.getAbsoluteY() < areaY || component.getAbsoluteY() > areaY + areaHeight - component.getRealHeight()) {
      final boolean scrollUp = component.getAbsoluteY() < areaY;
      scrollBar.getComponent(scrollUp ? 4 : 5).interact("");

      sleep(random(100, 200));
    }

    // Return whether or not the component is visible now.
    return component.getAbsoluteY() >= areaY && component.getAbsoluteY() <= areaY + areaHeight - component.getRealHeight();
  }

  /**
   * Enlarges the cache if there are more interfaces than the cache size.
   */
  private synchronized void enlargeCache() {
    final org.rsbot.client.RSInterface[][] inters = methods.client.getRSInterfaceCache();
    if (inters != null && mainCache.length < inters.length) { // enlarge
      // cache
      mainCache = Arrays.copyOf(mainCache, inters.length);
      for (int i = mainCache.length; i < mainCache.length; i++) {
        final RSInterface tmp = sparseMap.get(i);
        if (tmp != null) {
          sparseMap.remove(i);
          mainCache[i] = tmp;
        }
      }
    }
  }

  /**
   * Waits for an interface to be closed/opened.
   *
   * @param iface The interface to wait for.
   * @param valid True if open, false if close.
   * @param timer Milliseconds to wait for the interface to open/close.
   * @return <tt>true</tt> if the interface was successfully closed/opened.
   */
  public boolean waitFor(final RSInterface iface, final boolean valid, final int timer) {
    for (int w = 0; w < timer && iface.isValid() == valid; w++) {
      sleep(1);
    }
    return iface.isValid() == valid;
  }
}
TOP

Related Classes of org.rsbot.script.methods.Interfaces

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.