Package net.suncrescent.clicker.robot

Source Code of net.suncrescent.clicker.robot.Robot

package net.suncrescent.clicker.robot;

import java.awt.AWTException;
import java.awt.Color;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

import net.suncrescent.clicker.robot.RobotInteractionProvider.RobotControlProvider;
import net.suncrescent.clicker.robot.RobotInteractionProvider.RobotEventProvider;
import net.suncrescent.clicker.robot.RobotInteractionProvider.RobotStatus;
import net.suncrescent.clicker.robot.RobotInteractionProvider.RobotStatusProvider;
import net.suncrescent.clicker.robot.action.Action;
import net.suncrescent.clicker.robot.action.Condition;

import org.apache.log4j.Logger;

public class Robot {

  private final static Logger log = Logger.getLogger(Robot.class);

  private final java.awt.Robot robot;

  private final ArrayList<Action> actionSequence = new ArrayList<Action>();

  private final RobotInteractionProvider interactionProvider;

  private Boolean previousConditionResult = null;
  private int repeatCount = 0;

  public Robot() throws AWTException {
    Robot.log.debug("Robot constructor");
    this.robot = new java.awt.Robot();
    this.robot.setAutoWaitForIdle(true);
    this.interactionProvider = new RobotInteractionProvider(this);
  }

  public RobotStatusProvider getStatusProvider() {
    return this.interactionProvider.getStatusProvider();
  }

  public RobotControlProvider getControlProvider() {
    return this.interactionProvider.getControlProvider();
  }

  public RobotEventProvider getEventProvider() {
    return this.interactionProvider.getEventProvider();
  }

  public void setActionSequence(final List<Action> actions) {
    this.statusCheck();
    this.actionSequence.clear();
    this.actionSequence.addAll(actions);
  }

  public void setRepeatCount(final int count) {
    this.statusCheck();
    this.repeatCount = count;
  }

  protected void executeWork() throws InterruptedException {

    Robot.log.info("Execute work started. Number of actions: " + this.actionSequence.size() + ". Repeat count: " + this.repeatCount);

    // loop
    while (this.hasWorkingStatus() && this.repeatCount > 0) {

      Robot.log.debug("Executing repeat count: " + this.repeatCount);

      for (final Action a : this.actionSequence) {

        Robot.log.debug("Executing action: " + a.toString());

        // check condition
        final Condition cond = a.getCondition();

        if (cond == null || this.evaluateCondition(cond)) {

          // position the pointer
          this.smoothMove(a.getX(), a.getY());

          this.robot.setAutoDelay(100 + (int) (Math.random() * 50));

          // do button action
          switch (a.getAction()) {
          case LEFT_DOWN:
            this.robot.mousePress(InputEvent.BUTTON1_MASK);
            break;
          case LEFT_UP:
            this.robot.mouseRelease(InputEvent.BUTTON1_MASK);
            break;
          case MIDDLE_DOWN:
            this.robot.mousePress(InputEvent.BUTTON2_MASK);
            break;
          case MIDDLE_UP:
            this.robot.mouseRelease(InputEvent.BUTTON2_MASK);
            break;
          case RIGHT_DOWN:
            this.robot.mousePress(InputEvent.BUTTON3_MASK);
            break;
          case RIGHT_UP:
            this.robot.mouseRelease(InputEvent.BUTTON3_MASK);
            break;
          case LEFT_CLICK:
            this.robot.mousePress(InputEvent.BUTTON1_MASK);
            this.robot.mouseRelease(InputEvent.BUTTON1_MASK);
            break;
          case MIDDLE_CLICK:
            this.robot.mousePress(InputEvent.BUTTON2_MASK);
            this.robot.mouseRelease(InputEvent.BUTTON2_MASK);
            break;
          case RIGHT_CLICK:
            this.robot.mousePress(InputEvent.BUTTON3_MASK);
            this.robot.mouseRelease(InputEvent.BUTTON3_MASK);
            break;
          case KEY_B:
            this.robot.keyPress(KeyEvent.VK_B);
            this.robot.keyRelease(KeyEvent.VK_B);
            break;
          case KEY_W:
            this.robot.keyPress(KeyEvent.VK_W);
            this.robot.keyRelease(KeyEvent.VK_W);
            break;
          case KEY_S:
            this.robot.keyPress(KeyEvent.VK_S);
            this.robot.keyRelease(KeyEvent.VK_S);
            break;
          case KEY_X:
            this.robot.keyPress(KeyEvent.VK_X);
            this.robot.keyRelease(KeyEvent.VK_X);
            break;
          case NONE:
            // nothing happens!
            break;
          }

          // pause?
          if (a.getPause() > 0) {
            int pause = a.getPause();
            Robot.log.debug("Pause of " + pause + "ms");
            while (pause > 0 && this.hasWorkingStatus()) {
              Thread.sleep(Math.min(pause, 100));
              pause -= 100;
            }
          }
        }

        if (!this.hasWorkingStatus()) {
          return;
        }

        // lets be polite
        Thread.yield();
      }

      this.interactionProvider.getEventProvider().notifyRepeatCountChange(--this.repeatCount);

      // paused by controller?
      while (this.hasWorkingStatus() && this.interactionProvider.getStatusProvider().getStatus() == RobotStatus.PAUSED) {
        Thread.sleep(100);
      }
    }

    Robot.log.info("Execute work complete");
  }

  private boolean evaluateCondition(final Condition condition) {

    Robot.log.debug("Condition evaluate. Type: " + condition.getConditionType());

    boolean result = false;

    final Object[] params = condition.getConditionParameters();

    // evaluate
    switch (condition.getConditionType()) {
    case PIXEL_COLOR_MATCHES:
      if (params != null && params.length == 2) {
        final Point position = (Point) params[0];
        final Color color = (Color) params[1];
        final Color pixelColor = this.robot.getPixelColor(position.x, position.y);
        Robot.log.debug("Position (" + position.x + ", " + position.y + "). Expected color: " + color.toString() + ". Pixel color: "
            + pixelColor.toString());
        result = (color.equals(pixelColor));
      }
      break;
    case PIXEL_COLOR_NOT_MATCHES:
      if (params != null && params.length == 2) {
        final Point position = (Point) params[0];
        final Color color = (Color) params[1];
        final Color pixelColor = this.robot.getPixelColor(position.x, position.y);
        Robot.log.debug("Position (" + position.x + ", " + position.y + "). Not expected color: " + color.toString() + ". Pixel color: "
            + pixelColor.toString());
        result = (!color.equals(pixelColor));
      }
      break;
    case PREVIOUS_CONDITION_TRUE:
      result = (this.previousConditionResult != null && this.previousConditionResult == true);
      break;
    case PREVIOUS_CONDITION_FALSE:
      result = (this.previousConditionResult == null || this.previousConditionResult == false);
      break;
    }

    // check for chained operation
    if (condition.getChainedCondition() != null) {

      switch (condition.getChainedOperator()) {
      default:
      case AND:
        result = (result && this.evaluateCondition(condition.getChainedCondition()));
        break;
      case EQUAL:
        result = (result == this.evaluateCondition(condition.getChainedCondition()));
        break;
      case NOT_EQUAL:
        result = (result != this.evaluateCondition(condition.getChainedCondition()));
        break;
      case OR:
        result = (result || this.evaluateCondition(condition.getChainedCondition()));
        break;
      case XOR:
        result = ((result == true && this.evaluateCondition(condition.getChainedCondition()) == false) || (result == false && this
            .evaluateCondition(condition.getChainedCondition()) == true));
        break;
      }
    }

    this.previousConditionResult = result;

    Robot.log.debug("Condition evaluates as: " + (result ? "true" : "false"));

    return result;
  }

  private void smoothMove(final int x, final int y) {

    Robot.log.info("Mouse move to (" + x + ", " + y + ")");

    final PointerInfo pInfo = MouseInfo.getPointerInfo();

    final Point origin = pInfo.getLocation();

    Robot.log.debug("Current pointer position (" + origin.getX() + ", " + origin.getY() + ")");

    int differenceX = (int) (x - origin.getX());
    int differenceY = (int) (y - origin.getY());

    if (x == -1) {
      differenceX = 0;
    }

    if (y == -1) {
      differenceY = 0;
    }

    if (differenceX != 0 || differenceY != 0) {

      final double step = (((int) Math.random() * 2 + 2) / Math.sqrt(Math.pow(differenceX, 2) + Math.pow(differenceY, 2)));

      this.robot.setAutoDelay(2);

      for (double current = 0.0; current < 1.0; current += step) {
        final int stepX = (int) (origin.getX() + (differenceX * current));
        final int stepY = (int) (origin.getY() + (differenceY * current));
        Robot.log.debug("Step to (" + stepX + ", " + stepY + ")");
        this.robot.mouseMove(stepX, stepY);
      }

      // just make sure we actually are at the right spot
      this.robot.setAutoDelay(450 + (int) (Math.random() * 100));
      this.robot.mouseMove(x, y);
      this.robot.setAutoDelay(0);
    }
  }

  private boolean hasWorkingStatus() {
    final RobotStatus status = this.interactionProvider.getStatusProvider().getStatus();
    return status == RobotStatus.PAUSED || status == RobotStatus.RUNNING;
  }

  private void statusCheck() throws IllegalStateException {
    if (this.hasWorkingStatus()) {
      throw new IllegalStateException("This method can not be called while the robot is in a running or paused state.");
    }
  }
}
TOP

Related Classes of net.suncrescent.clicker.robot.Robot

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.