mirror of
https://github.com/davpapp/PowerMiner
synced 2024-12-22 07:58:48 -05:00
Major refactoring work
This commit is contained in:
parent
c24f8588de
commit
e6ab945729
BIN
bin/Cursor.class
BIN
bin/Cursor.class
Binary file not shown.
Binary file not shown.
BIN
bin/CursorPathTest.class
Normal file
BIN
bin/CursorPathTest.class
Normal file
Binary file not shown.
Binary file not shown.
BIN
bin/CursorPointTest.class
Normal file
BIN
bin/CursorPointTest.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -27,7 +27,7 @@ public class Cursor {
|
|||||||
|
|
||||||
|
|
||||||
private Robot robot;
|
private Robot robot;
|
||||||
private Random random = new Random();
|
private Randomizer randomizer;
|
||||||
|
|
||||||
private ArrayList<ArrayList<CursorPath>> cursorPathsByDistance;
|
private ArrayList<ArrayList<CursorPath>> cursorPathsByDistance;
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ public class Cursor {
|
|||||||
initializeCursorPathsByDistanceFromFile("/home/dpapp/GhostMouse/coordinates.txt");
|
initializeCursorPathsByDistanceFromFile("/home/dpapp/GhostMouse/coordinates.txt");
|
||||||
|
|
||||||
robot = new Robot();
|
robot = new Robot();
|
||||||
random = new Random();
|
randomizer = new Randomizer();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeCursorPathsByDistanceFromFile(String path) {
|
private void initializeCursorPathsByDistanceFromFile(String path) {
|
||||||
@ -72,7 +72,7 @@ public class Cursor {
|
|||||||
|
|
||||||
// TODO: make sure these are reasonable
|
// TODO: make sure these are reasonable
|
||||||
private int getRandomClickLength() {
|
private int getRandomClickLength() {
|
||||||
return random.nextInt(MAXIMUM_CLICK_LENGTH - MINIMUM_CLICK_LENGTH) + MINIMUM_CLICK_LENGTH;
|
return randomizer.nextGaussianWithinRange(MINIMUM_CLICK_LENGTH, MAXIMUM_CLICK_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void leftClickCursor() throws InterruptedException {
|
public void leftClickCursor() throws InterruptedException {
|
||||||
@ -114,12 +114,12 @@ public class Cursor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void moveCursorToCoordinates(Point goalPoint) throws InterruptedException {
|
public void moveCursorToCoordinates(Point goalPoint) throws InterruptedException {
|
||||||
Point startingCursorPoint = getCurrentCursorPoint();
|
Point startingPoint = getCurrentCursorPoint();
|
||||||
int distanceToMoveCursor = calculateDistanceBetweenPoints(startingCursorPoint, goalPoint);
|
int distanceToMoveCursor = (int) startingPoint.distance(goalPoint);
|
||||||
if (distanceToMoveCursor == 0) {
|
if (distanceToMoveCursor == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
double angleToMoveCursor = calculateThetaBetweenPoints(startingCursorPoint, goalPoint);
|
double angleToMoveCursor = getThetaBetweenPoints(startingPoint, goalPoint);
|
||||||
|
|
||||||
// TODO: check if exists
|
// TODO: check if exists
|
||||||
CursorPath cursorPathToFollow = chooseCursorPathToFollowBasedOnDistance(distanceToMoveCursor);
|
CursorPath cursorPathToFollow = chooseCursorPathToFollowBasedOnDistance(distanceToMoveCursor);
|
||||||
@ -127,20 +127,20 @@ public class Cursor {
|
|||||||
followCursorPath(startingCursorPoint, angleToTranslatePathBy, cursorPathToFollow);
|
followCursorPath(startingCursorPoint, angleToTranslatePathBy, cursorPathToFollow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: fix
|
||||||
|
private double getThetaBetweenPoints(Point startingPoint, Point goalPoint) {
|
||||||
|
return Math.atan2(startingPoint.x * goalPoint.y, 1.0 * goalPoint.x);
|
||||||
|
}
|
||||||
|
|
||||||
private void followCursorPath(Point startingCursorPoint, double angleToTranslatePathBy, CursorPath cursorPathToFollow) throws InterruptedException {
|
private void followCursorPath(Point startingCursorPoint, double angleToTranslatePathBy, CursorPath cursorPathToFollow) throws InterruptedException {
|
||||||
for (CursorPoint untranslatedCursorPoint : cursorPathToFollow.getCursorPathPoints()) {
|
for (CursorPoint untranslatedCursorPoint : cursorPathToFollow.getCursorPathPoints()) {
|
||||||
Point translatedPointToClick = translatePoint(startingCursorPoint, angleToTranslatePathBy, untranslatedCursorPoint);
|
Point translatedPointToClick = translatePoint(startingCursorPoint, angleToTranslatePathBy, untranslatedCursorPoint);
|
||||||
robotMouseMove(translatedPointToClick);
|
robotMouseMove(translatedPointToClick);
|
||||||
Thread.sleep(untranslatedCursorPoint.postMillisecondDelay);
|
Thread.sleep(untranslatedCursorPoint.delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Point translatePoint(Point startingCursorPoint, double angleToTranslateBy, CursorPoint untranslatedCursorPoint) {
|
|
||||||
int x = (int) (startingCursorPoint.x + Math.cos(angleToTranslateBy) * untranslatedCursorPoint.x - Math.sin(angleToTranslateBy) * untranslatedCursorPoint.y);
|
|
||||||
int y = (int) (startingCursorPoint.y + Math.sin(angleToTranslateBy) * untranslatedCursorPoint.x + Math.cos(angleToTranslateBy) * untranslatedCursorPoint.y);
|
|
||||||
return new Point(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void robotMouseMove(Point pointToMoveCursorTo) {
|
public void robotMouseMove(Point pointToMoveCursorTo) {
|
||||||
robot.mouseMove(pointToMoveCursorTo.x, pointToMoveCursorTo.y);
|
robot.mouseMove(pointToMoveCursorTo.x, pointToMoveCursorTo.y);
|
||||||
}
|
}
|
||||||
@ -154,7 +154,7 @@ public class Cursor {
|
|||||||
double scaleFactor = getScaleFactor(newDistanceToMoveCursor, distanceToMoveCursor);
|
double scaleFactor = getScaleFactor(newDistanceToMoveCursor, distanceToMoveCursor);
|
||||||
|
|
||||||
ArrayList<CursorPath> cursorPathsWithSameDistance = cursorPathsByDistance.get(newDistanceToMoveCursor);
|
ArrayList<CursorPath> cursorPathsWithSameDistance = cursorPathsByDistance.get(newDistanceToMoveCursor);
|
||||||
CursorPath scaledCursorPath = cursorPathsWithSameDistance.get(random.nextInt(cursorPathsWithSameDistance.size())).getScaledCopyOfCursorPath(1.0);
|
CursorPath scaledCursorPath = cursorPathsWithSameDistance.get(new Random().nextInt(cursorPathsWithSameDistance.size())).getScaledCopyOfCursorPath(1.0);
|
||||||
return scaledCursorPath;
|
return scaledCursorPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,24 +175,14 @@ public class Cursor {
|
|||||||
return (1.0 * newDistanceToMoveCursor / distanceToMoveCursor);
|
return (1.0 * newDistanceToMoveCursor / distanceToMoveCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int calculateDistanceBetweenPoints(Point a, Point b) {
|
|
||||||
return (int) (Math.hypot(a.x - b.x, a.y - b.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
public double calculateThetaBetweenPoints(Point a, Point b) {
|
|
||||||
return Math.atan2(1.0 * (b.y - a.y), 1.0 * (b.x - a.x));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Point getCurrentCursorPoint() {
|
public Point getCurrentCursorPoint() {
|
||||||
return MouseInfo.getPointerInfo().getLocation();
|
return MouseInfo.getPointerInfo().getLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getRandomIntSigned(int tolerance) {
|
|
||||||
return random.nextInt(tolerance) - tolerance / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Point randomizePoint(Point goalPoint, int xTolerance, int yTolerance) {
|
private Point randomizePoint(Point goalPoint, int xTolerance, int yTolerance) {
|
||||||
return new Point(goalPoint.x + getRandomIntSigned(xTolerance), goalPoint.y + getRandomIntSigned(yTolerance));
|
Randomizer randomizer = new Randomizer();
|
||||||
|
return new Point(goalPoint.x + randomizer.nextGaussianWithinRange(-xTolerance, xTolerance), goalPoint.y + randomizer.nextGaussianWithinRange(-yTolerance, yTolerance));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void displayCursorPaths() {
|
public void displayCursorPaths() {
|
||||||
|
@ -6,70 +6,86 @@ import java.util.ArrayList;
|
|||||||
|
|
||||||
public class CursorPath {
|
public class CursorPath {
|
||||||
|
|
||||||
private ArrayList<CursorPoint> pathCursorPoints;
|
private ArrayList<CursorPoint> cursorPoints;
|
||||||
private int pathNumPoints;
|
private double theta;
|
||||||
private int pathDistance;
|
private int distance;
|
||||||
private double pathTheta;
|
private int timespan;
|
||||||
private int pathTimespanMilliseconds;
|
|
||||||
|
|
||||||
public CursorPath(ArrayList<CursorPoint> cursorPoints)
|
public CursorPath(ArrayList<CursorPoint> cursorPoints)
|
||||||
{
|
{
|
||||||
this.pathCursorPoints = copyCursorPointsWithOffset(cursorPoints);
|
this.cursorPoints = initializePathOfCursorPoints(cursorPoints);
|
||||||
this.pathNumPoints = cursorPoints.size();
|
this.distance = calculateCursorPathDistance();
|
||||||
this.pathDistance = calculateCursorPathDistance();
|
this.theta = calculateCursorPathTheta();
|
||||||
this.pathTheta = calculateCursorPathTheta();
|
this.timespan = calculateCursorPathTimespan();
|
||||||
this.pathTimespanMilliseconds = calculateCursorPathTimespan();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<CursorPoint> copyCursorPointsWithOffset(ArrayList<CursorPoint> cursorPoints) {
|
private ArrayList<CursorPoint> initializePathOfCursorPoints(ArrayList<CursorPoint> cursorPoints) {
|
||||||
ArrayList<CursorPoint> cursorPointsCopy = new ArrayList<CursorPoint>(cursorPoints.size());
|
|
||||||
CursorPoint startingCursorPoint = cursorPoints.get(0);
|
CursorPoint startingCursorPoint = cursorPoints.get(0);
|
||||||
|
ArrayList<CursorPoint> translatedCursorPoints = getTranslatedCopyOfCursorPath(cursorPoints, startingCursorPoint);
|
||||||
|
ArrayList<CursorPoint> normalizedDelayCursorPoints = getNormalizedDelayCopyOfCursorPath(translatedCursorPoints);
|
||||||
|
return normalizedDelayCursorPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<CursorPoint> getTranslatedCopyOfCursorPath(ArrayList<CursorPoint> cursorPoints, CursorPoint cursorPointToTranslateBy) {
|
||||||
|
ArrayList<CursorPoint> offsetCursorPath = new ArrayList<CursorPoint>();
|
||||||
for (CursorPoint cursorPoint : cursorPoints) {
|
for (CursorPoint cursorPoint : cursorPoints) {
|
||||||
cursorPointsCopy.add(getOffsetCursorPoint(cursorPoint, startingCursorPoint));
|
offsetCursorPath.add(cursorPoint.getCursorPointTranslatedBy(cursorPointToTranslateBy));
|
||||||
}
|
}
|
||||||
calculatePostMillisecondDelays(cursorPointsCopy);
|
return offsetCursorPath;
|
||||||
return cursorPointsCopy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void calculatePostMillisecondDelays(ArrayList<CursorPoint> cursorPoints) {
|
private ArrayList<CursorPoint> getNormalizedDelayCopyOfCursorPath(ArrayList<CursorPoint> cursorPoints) {
|
||||||
for (int i = 1; i < cursorPoints.size(); i++) {
|
ArrayList<CursorPoint> normalizedDelayCursorPoints = new ArrayList<CursorPoint>();
|
||||||
cursorPoints.get(i - 1).setPostMillisecondDelay(cursorPoints.get(i).postMillisecondDelay - cursorPoints.get(i - 1).postMillisecondDelay);
|
for (int i = 0; i < cursorPoints.size() - 1; i++) {
|
||||||
|
CursorPoint cursorPoint = cursorPoints.get(i);
|
||||||
|
CursorPoint nextCursorPoint = cursorPoints.get(i + 1);
|
||||||
|
normalizedDelayCursorPoints.add(cursorPoint.getCursorPointWithNewDelay(nextCursorPoint.delay - cursorPoint.delay));
|
||||||
}
|
}
|
||||||
cursorPoints.get(cursorPoints.size() - 1).setPostMillisecondDelay(0);
|
normalizedDelayCursorPoints.add(cursorPoints.get(cursorPoints.size() - 1).getCursorPointWithNewDelay(0));
|
||||||
|
return normalizedDelayCursorPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CursorPoint getOffsetCursorPoint(CursorPoint cursorPoint, CursorPoint offsetPoint) {
|
|
||||||
return new CursorPoint(cursorPoint.x - offsetPoint.x, cursorPoint.y - offsetPoint.y, cursorPoint.postMillisecondDelay);
|
public ArrayList<CursorPoint> getScaledCopyOfCursorPath(double factorToScaleBy) {
|
||||||
|
ArrayList<CursorPoint> scaledCursorPath = new ArrayList<CursorPoint>();
|
||||||
|
for (CursorPoint cursorPoint : this.cursorPoints) {
|
||||||
|
scaledCursorPath.add(cursorPoint.getCursorPointScaledBy(factorToScaleBy));
|
||||||
|
}
|
||||||
|
return scaledCursorPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<CursorPoint> getRotatedCopyOfCursorPath(double angleToRotateBy) {
|
||||||
|
ArrayList<CursorPoint> rotatedCursorPath = new ArrayList<CursorPoint>();
|
||||||
|
for (CursorPoint cursorPoint : this.cursorPoints) {
|
||||||
|
rotatedCursorPath.add(cursorPoint.getCursorPointRotatedBy(angleToRotateBy));
|
||||||
|
}
|
||||||
|
return rotatedCursorPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int calculateCursorPathTimespan() {
|
private int calculateCursorPathTimespan() {
|
||||||
int sumPathTimespanMilliseconds = 0;
|
int sumPathTimespanMilliseconds = 0;
|
||||||
for (CursorPoint cursorPoint : this.pathCursorPoints) {
|
for (CursorPoint cursorPoint : this.cursorPoints) {
|
||||||
sumPathTimespanMilliseconds += cursorPoint.postMillisecondDelay;
|
sumPathTimespanMilliseconds += cursorPoint.delay;
|
||||||
}
|
}
|
||||||
return sumPathTimespanMilliseconds;
|
return sumPathTimespanMilliseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int calculateCursorPathDistance() {
|
private int calculateCursorPathDistance() {
|
||||||
return (int) calculateDistanceBetweenCursorPoints(getStartingCursorPoint(), getEndingCursorPoint());
|
return (int) (getStartingCursorPoint().getDistanceFrom(getEndingCursorPoint()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private double calculateCursorPathTheta() {
|
private double calculateCursorPathTheta() {
|
||||||
CursorPoint endingCursorPoint = getEndingCursorPoint();
|
return getStartingCursorPoint().getThetaFrom(getEndingCursorPoint());
|
||||||
return Math.atan2(1.0 * endingCursorPoint.y, 1.0 * endingCursorPoint.x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private CursorPoint getStartingCursorPoint() {
|
public CursorPoint getStartingCursorPoint() {
|
||||||
return pathCursorPoints.get(0);
|
return this.cursorPoints.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CursorPoint getEndingCursorPoint() {
|
public CursorPoint getEndingCursorPoint() {
|
||||||
return pathCursorPoints.get(pathNumPoints - 1);
|
return this.cursorPoints.get(this.cursorPoints.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private double calculateDistanceBetweenCursorPoints(CursorPoint a, CursorPoint b) {
|
|
||||||
return Math.hypot(a.x - b.x, a.y - b.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCursorPathReasonable() {
|
public boolean isCursorPathReasonable() {
|
||||||
return isCursorPathTimespanReasonable() && isCursorPathDistanceReasonable() &&
|
return isCursorPathTimespanReasonable() && isCursorPathDistanceReasonable() &&
|
||||||
@ -77,42 +93,35 @@ public class CursorPath {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isCursorPathTimespanReasonable() {
|
private boolean isCursorPathTimespanReasonable() {
|
||||||
return (this.pathTimespanMilliseconds > 50 && this.pathTimespanMilliseconds < 400);
|
return (this.timespan > 50 && this.timespan < 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isCursorPathDistanceReasonable() {
|
private boolean isCursorPathDistanceReasonable() {
|
||||||
return (this.pathDistance > 0 && this.pathDistance < 1000);
|
return (this.distance > 0 && this.distance < 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isCursorPathNumPointsReasonable() {
|
private boolean isCursorPathNumPointsReasonable() {
|
||||||
return (this.pathNumPoints > 0 && this.pathNumPoints < 50);
|
return (this.cursorPoints.size() > 0 && this.cursorPoints.size() < 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<CursorPoint> getCursorPathPoints() {
|
public ArrayList<CursorPoint> getCursorPathPoints() {
|
||||||
return pathCursorPoints;
|
return cursorPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCursorPathDistance() {
|
public int getCursorPathDistance() {
|
||||||
return pathDistance;
|
return distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getCursorPathTheta() {
|
public double getCursorPathTheta() {
|
||||||
return pathTheta;
|
return theta;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CursorPath getScaledCopyOfCursorPath(double scaleFactor) {
|
|
||||||
ArrayList<CursorPoint> scaledCursorPath = new ArrayList<CursorPoint>();
|
|
||||||
for (CursorPoint cursorPoint : this.pathCursorPoints) {
|
|
||||||
scaledCursorPath.add(new CursorPoint((int) (cursorPoint.x * scaleFactor), (int) (cursorPoint.y * scaleFactor), (int) (cursorPoint.postMillisecondDelay * scaleFactor)));
|
|
||||||
}
|
|
||||||
return new CursorPath(scaledCursorPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void displayCursorPoints() {
|
public void displayCursorPoints() {
|
||||||
for (CursorPoint p : pathCursorPoints) {
|
for (CursorPoint p : this.cursorPoints) {
|
||||||
p.display();
|
p.display();
|
||||||
}
|
}
|
||||||
System.out.println("Length:" + pathNumPoints + ", Timespan:" + pathTimespanMilliseconds);
|
System.out.println("Number of points:" + this.cursorPoints.size() + ", Timespan:" + this.timespan);
|
||||||
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~ End of Path ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~ End of Path ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||||
}
|
}
|
||||||
}
|
}
|
78
src/CursorPathTest.java
Normal file
78
src/CursorPathTest.java
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class CursorPathTest {
|
||||||
|
|
||||||
|
ArrayList<CursorPath> cursorPaths;
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCursorPathOffset() {
|
||||||
|
initializeCursorPath();
|
||||||
|
|
||||||
|
for (CursorPath cursorPath : cursorPaths) {
|
||||||
|
testCursorPathStartsAtOrigin(cursorPath);
|
||||||
|
testEndingCursorPointInCursorPathHasZeroDelay(cursorPath);
|
||||||
|
//testCursorPathLocations(cursorPath);
|
||||||
|
testCursorPathRotation(cursorPath, 15);
|
||||||
|
testCursorPathScaling(cursorPath, 1.15);
|
||||||
|
cursorPath.displayCursorPoints();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testCursorPathStartsAtOrigin(CursorPath cursorPath) {
|
||||||
|
CursorPoint startingCursorPoint = cursorPath.getStartingCursorPoint();
|
||||||
|
assertTrue(startingCursorPoint.x == 0 && startingCursorPoint.y == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testEndingCursorPointInCursorPathHasZeroDelay(CursorPath cursorPath) {
|
||||||
|
CursorPoint endingCursorPoint = cursorPath.getEndingCursorPoint();
|
||||||
|
assertEquals(endingCursorPoint.delay, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*private void testCursorPathLocations(CursorPath cursorPath) {
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void testCursorPathRotation(CursorPath cursorPath, double angleToRotateBy) {
|
||||||
|
ArrayList<CursorPoint> cursorPoints = cursorPath.getCursorPathPoints();
|
||||||
|
ArrayList<CursorPoint> rotatedCursorPoints = cursorPath.getRotatedCopyOfCursorPath(angleToRotateBy);
|
||||||
|
assertEquals(cursorPoints.size(), rotatedCursorPoints.size());
|
||||||
|
CursorPoint startingPoint = cursorPoints.get(0);
|
||||||
|
for (int i = 1; i < cursorPoints.size(); i++) {
|
||||||
|
double originalThetaOfCursorPoint = cursorPoints.get(i).getThetaFrom(startingPoint);
|
||||||
|
double rotatedThetaOfCursorPoint = rotatedCursorPoints.get(i).getThetaFrom(startingPoint);
|
||||||
|
System.out.println(originalThetaOfCursorPoint + ", " + rotatedThetaOfCursorPoint);
|
||||||
|
assertInRangeByAbsoluteValue(originalThetaOfCursorPoint + angleToRotateBy, rotatedThetaOfCursorPoint, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void testCursorPathScaling(CursorPath cursorPath, double factorToScaleBy) {
|
||||||
|
ArrayList<CursorPoint> cursorPoints = cursorPath.getCursorPathPoints();
|
||||||
|
ArrayList<CursorPoint> scaledCursorPoints = cursorPath.getScaledCopyOfCursorPath(factorToScaleBy);
|
||||||
|
assertEquals(cursorPoints.size(), scaledCursorPoints.size());
|
||||||
|
CursorPoint startingPoint = cursorPoints.get(0);
|
||||||
|
for (int i = 0; i < cursorPoints.size(); i++) {
|
||||||
|
double originalDistanceOfCursorPoint = cursorPoints.get(i).getDistanceFrom(startingPoint);
|
||||||
|
double scaledDistanceOfCursorPoint = scaledCursorPoints.get(i).getDistanceFrom(startingPoint);
|
||||||
|
assertInRangeByAbsoluteValue(originalDistanceOfCursorPoint * factorToScaleBy, scaledDistanceOfCursorPoint, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void initializeCursorPath() {
|
||||||
|
CursorDataFileParser cursorDataFileParser = new CursorDataFileParser("/home/dpapp/eclipse-workspace/RunescapeAI/testfiles/cursorPathTest.txt");
|
||||||
|
this.cursorPaths = cursorDataFileParser.getArrayListOfCursorPathsFromFile();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertInRangeByRatio(double valueToTest, double expectation, double toleranceRatio) {
|
||||||
|
assertTrue((valueToTest <= (expectation * (1 + toleranceRatio))) && (valueToTest >= (expectation * (1 - toleranceRatio))));
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertInRangeByAbsoluteValue(double valueToTest, double expectation, double toleranceAbsolute) {
|
||||||
|
assertTrue((valueToTest <= (expectation + toleranceAbsolute)) && (valueToTest >= (expectation * (1 - toleranceAbsolute))));
|
||||||
|
}
|
||||||
|
}
|
@ -1,20 +1,44 @@
|
|||||||
|
import java.awt.Point;
|
||||||
|
|
||||||
public class CursorPoint {
|
public class CursorPoint {
|
||||||
|
|
||||||
public int x;
|
public int x;
|
||||||
public int y;
|
public int y;
|
||||||
public int postMillisecondDelay; // how much to sleep for after moving here
|
public int delay;
|
||||||
|
|
||||||
public CursorPoint(int x, int y, int postMillisecondDelay) {
|
public CursorPoint(int x, int y, int delay) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.postMillisecondDelay = postMillisecondDelay;
|
this.delay = delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPostMillisecondDelay(int postMillisecondDelay) {
|
public double getDistanceFrom(CursorPoint b) {
|
||||||
this.postMillisecondDelay = postMillisecondDelay;
|
return Math.hypot(this.x - b.x, this.y - b.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getThetaFrom(CursorPoint b) {
|
||||||
|
return Math.atan2(1.0 * b.y, 1.0 * b.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CursorPoint getCursorPointTranslatedBy(CursorPoint startingCursorPoint) {
|
||||||
|
return new CursorPoint(this.x - startingCursorPoint.x, this.y - startingCursorPoint.y, this.delay - startingCursorPoint.delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CursorPoint getCursorPointScaledBy(double scaleFactor) {
|
||||||
|
return (new CursorPoint((int) (this.x * scaleFactor), (int) (this.y * scaleFactor), (int) (this.delay * scaleFactor)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CursorPoint getCursorPointRotatedBy(double angleOfRotation) {
|
||||||
|
int rotatedX = (int) (this.x + Math.cos(angleOfRotation) * this.x - Math.sin(angleOfRotation) * this.y);
|
||||||
|
int rotatedY = (int) (this.y + Math.sin(angleOfRotation) * this.x + Math.cos(angleOfRotation) * this.y);
|
||||||
|
return (new CursorPoint(rotatedX, rotatedY, this.delay));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CursorPoint getCursorPointWithNewDelay(int delay) {
|
||||||
|
return (new CursorPoint(this.x, this.y, delay));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void display() {
|
public void display() {
|
||||||
System.out.println("Point: (" + x + "," + y + "), delay: " + postMillisecondDelay);
|
System.out.println("Point: (" + x + "," + y + "), delay: " + delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
43
src/CursorPointTest.java
Normal file
43
src/CursorPointTest.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class CursorPointTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDistanceFrom() {
|
||||||
|
CursorPoint a = new CursorPoint(0, 0, 0);
|
||||||
|
CursorPoint b = new CursorPoint(3, 4, 0);
|
||||||
|
CursorPoint c = new CursorPoint(500, 750, 0);
|
||||||
|
CursorPoint d = new CursorPoint(284, 848, 0);
|
||||||
|
|
||||||
|
assertTrue(withinRangeByRatio(a.getDistanceFrom(b), 5, 0.0001));
|
||||||
|
assertTrue(withinRangeByRatio(a.getDistanceFrom(c), 901.387818866, 0.0001));
|
||||||
|
assertTrue(withinRangeByRatio(a.getDistanceFrom(d), 894.293016857, 0.0001));
|
||||||
|
assertTrue(withinRangeByRatio(b.getDistanceFrom(c), 896.395560007, 0.0001));
|
||||||
|
assertTrue(withinRangeByRatio(c.getDistanceFrom(d), 237.191905427, 0.0001));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCursorPointRotation() {
|
||||||
|
CursorPoint a = new CursorPoint(0, 0, 0);
|
||||||
|
CursorPoint b = new CursorPoint(10, 0, 0);
|
||||||
|
//CursorPoint c = new CursorPoint(10, 20, 0);
|
||||||
|
CursorPoint d = a.getCursorPointRotatedBy(Math.PI / 4);
|
||||||
|
CursorPoint e = b.getCursorPointRotatedBy(Math.PI / 2);
|
||||||
|
//CursorPoint f = c.getCursorPointRotatedBy(90);
|
||||||
|
|
||||||
|
//System.out.println(a.getThetaFrom(a));
|
||||||
|
//System.out.println(b.getThetaFrom(a));
|
||||||
|
assertTrue(d.x == 0 && d.y == 0);
|
||||||
|
System.out.println(e.x + ", " + e.y);
|
||||||
|
//assertTrue(e.x == 5);
|
||||||
|
|
||||||
|
//assertTrue(withinRangeByRatio())
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean withinRangeByRatio(double actual, double expectation, double toleranceRatio) {
|
||||||
|
return ((actual <= (expectation * (1 + toleranceRatio))) && (actual >= (expectation * (1 - toleranceRatio))));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,30 +0,0 @@
|
|||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
class MousePathTest {
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void mousePathLengthTest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void mousePathTimespanTest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void mousePathStartingPointTest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void mousePathEndingPointTest() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Things to test:
|
|
||||||
* - Invalid regex expression
|
|
||||||
* - Empty paths (mouse jumps)
|
|
||||||
* - Short paths
|
|
||||||
* - No input file
|
|
||||||
* - Long paths
|
|
||||||
*/
|
|
||||||
|
|
||||||
class MouseTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMouseLengths() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -10,18 +10,20 @@ public class Randomizer {
|
|||||||
random = new Random();
|
random = new Random();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int nextGaussianWithinThreeSTDs(int mean, int STD) {
|
public int nextGaussianWithinRange(double rangeBegin, double rangeEnd) {
|
||||||
int result = (int) (random.nextGaussian() * STD + mean);
|
double rangeMean = (rangeEnd - rangeBegin) / 2.0;
|
||||||
while (result > (mean + 3 * STD) || result < (mean - 3 * STD)) {
|
double rangeSTD = (rangeEnd - rangeMean) / 3.0;
|
||||||
result = (int) random.nextGaussian() * STD + mean;
|
double result = random.nextGaussian() * rangeSTD + rangeMean;
|
||||||
|
while (result > rangeEnd || result < rangeBegin) {
|
||||||
|
result = random.nextGaussian() * rangeSTD + rangeMean;
|
||||||
}
|
}
|
||||||
return result;
|
return (int) result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Point generatePeakForTransformationParabola(int pathDistance) {
|
public Point generatePeakForTransformationParabola(int pathDistance) {
|
||||||
double maxTransformationScale = 0.2;
|
double maxTransformationScale = 0.2;
|
||||||
int peakX = nextGaussianWithinThreeSTDs(pathDistance / 2, pathDistance / 6);
|
int peakX = nextGaussianWithinRange(0, pathDistance);
|
||||||
int peakY = (int) (random.nextGaussian() * maxTransformationScale);
|
int peakY = nextGaussianWithinRange(0, pathDistance * maxTransformationScale);
|
||||||
return new Point(peakX, peakY);
|
return new Point(peakX, peakY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
553
testfiles/cursorPathTest.txt
Normal file
553
testfiles/cursorPathTest.txt
Normal file
@ -0,0 +1,553 @@
|
|||||||
|
1527,568,2
|
||||||
|
1527,568,10
|
||||||
|
1527,568,15
|
||||||
|
1527,568,21
|
||||||
|
1527,568,28
|
||||||
|
1527,568,34
|
||||||
|
1527,568,41
|
||||||
|
1527,568,47
|
||||||
|
1527,568,54
|
||||||
|
1527,568,60
|
||||||
|
1527,568,67
|
||||||
|
1527,568,74
|
||||||
|
1527,568,81
|
||||||
|
1527,568,89
|
||||||
|
1527,568,95
|
||||||
|
1527,568,101
|
||||||
|
1527,568,106
|
||||||
|
1527,568,112
|
||||||
|
1527,568,118
|
||||||
|
1527,568,125
|
||||||
|
1527,568,131
|
||||||
|
1527,568,138
|
||||||
|
1527,568,145
|
||||||
|
1527,568,152
|
||||||
|
1527,568,158
|
||||||
|
1527,568,164
|
||||||
|
1527,568,170
|
||||||
|
1527,568,177
|
||||||
|
1527,568,184
|
||||||
|
1527,568,189
|
||||||
|
1527,568,194
|
||||||
|
1527,568,200
|
||||||
|
1527,568,206
|
||||||
|
1527,568,213
|
||||||
|
1527,568,220
|
||||||
|
1527,568,227
|
||||||
|
1527,568,232
|
||||||
|
1527,568,238
|
||||||
|
1527,568,245
|
||||||
|
1527,568,251
|
||||||
|
1527,568,257
|
||||||
|
1527,568,264
|
||||||
|
1527,568,271
|
||||||
|
1527,568,278
|
||||||
|
1527,568,285
|
||||||
|
1527,568,292
|
||||||
|
1527,568,299
|
||||||
|
1527,568,304
|
||||||
|
1527,568,310
|
||||||
|
1527,568,316
|
||||||
|
1527,568,321
|
||||||
|
1527,568,328
|
||||||
|
1527,568,334
|
||||||
|
1527,568,342
|
||||||
|
1527,568,350
|
||||||
|
1527,568,357
|
||||||
|
1527,568,364
|
||||||
|
1527,568,371
|
||||||
|
1527,568,376
|
||||||
|
1527,568,381
|
||||||
|
1527,568,387
|
||||||
|
1527,568,393
|
||||||
|
1527,568,398
|
||||||
|
1527,568,404
|
||||||
|
1527,568,409
|
||||||
|
1527,568,416
|
||||||
|
1527,568,422
|
||||||
|
1527,568,429
|
||||||
|
1527,568,435
|
||||||
|
1527,568,441
|
||||||
|
1527,568,447
|
||||||
|
1527,568,452
|
||||||
|
1527,568,458
|
||||||
|
1527,568,463
|
||||||
|
1527,568,469
|
||||||
|
1527,568,476
|
||||||
|
1527,568,483
|
||||||
|
1527,568,490
|
||||||
|
1527,568,497
|
||||||
|
1527,568,504
|
||||||
|
1527,568,512
|
||||||
|
1527,568,518
|
||||||
|
1527,568,524
|
||||||
|
1527,568,531
|
||||||
|
1527,568,538
|
||||||
|
1527,568,545
|
||||||
|
1527,568,552
|
||||||
|
1527,568,558
|
||||||
|
1527,568,565
|
||||||
|
1527,568,572
|
||||||
|
1527,568,579
|
||||||
|
1527,568,585
|
||||||
|
1527,568,592
|
||||||
|
1527,568,600
|
||||||
|
1527,568,606
|
||||||
|
1527,568,614
|
||||||
|
1527,568,621
|
||||||
|
1527,568,627
|
||||||
|
1527,568,633
|
||||||
|
1527,568,639
|
||||||
|
1527,568,646
|
||||||
|
1527,568,651
|
||||||
|
1527,568,656
|
||||||
|
1527,568,662
|
||||||
|
1527,568,669
|
||||||
|
1527,568,676
|
||||||
|
1527,568,683
|
||||||
|
1527,568,689
|
||||||
|
1527,568,695
|
||||||
|
1527,568,701
|
||||||
|
1527,568,707
|
||||||
|
1527,568,713
|
||||||
|
1527,568,719
|
||||||
|
1527,568,724
|
||||||
|
1527,568,730
|
||||||
|
1527,568,736
|
||||||
|
1527,568,742
|
||||||
|
1527,568,748
|
||||||
|
1527,568,754
|
||||||
|
1527,568,760
|
||||||
|
1527,568,768
|
||||||
|
1527,568,774
|
||||||
|
1527,568,781
|
||||||
|
1527,568,788
|
||||||
|
1527,568,794
|
||||||
|
1527,568,800
|
||||||
|
1527,568,806
|
||||||
|
1527,568,813
|
||||||
|
1527,568,820
|
||||||
|
1527,568,828
|
||||||
|
1527,568,834
|
||||||
|
1527,568,840
|
||||||
|
1527,568,848
|
||||||
|
1527,568,855
|
||||||
|
1527,568,861
|
||||||
|
1527,568,868
|
||||||
|
1527,568,874
|
||||||
|
1527,568,882
|
||||||
|
1527,568,888
|
||||||
|
1527,568,894
|
||||||
|
1527,568,899
|
||||||
|
1527,568,906
|
||||||
|
1527,568,912
|
||||||
|
1527,568,920
|
||||||
|
1527,568,927
|
||||||
|
1527,568,933
|
||||||
|
1527,568,939
|
||||||
|
1527,568,945
|
||||||
|
1527,568,952
|
||||||
|
1527,568,960
|
||||||
|
1527,568,966
|
||||||
|
1527,568,973
|
||||||
|
1527,568,980
|
||||||
|
1527,568,986
|
||||||
|
1527,568,994
|
||||||
|
1527,568,1002
|
||||||
|
1527,568,1008
|
||||||
|
1527,568,1014
|
||||||
|
1527,568,1020
|
||||||
|
1527,568,1026
|
||||||
|
1527,568,1032
|
||||||
|
1527,568,1039
|
||||||
|
1527,568,1045
|
||||||
|
1527,568,1052
|
||||||
|
1527,568,1059
|
||||||
|
1527,568,1066
|
||||||
|
1527,568,1073
|
||||||
|
1527,568,1080
|
||||||
|
1527,568,1086
|
||||||
|
1527,568,1095
|
||||||
|
1527,568,1102
|
||||||
|
1527,568,1108
|
||||||
|
1527,568,1114
|
||||||
|
1527,568,1121
|
||||||
|
1527,568,1128
|
||||||
|
1353,641,1135
|
||||||
|
1193,719,1157
|
||||||
|
1193,719,1165
|
||||||
|
1051,799,1173
|
||||||
|
1051,799,1180
|
||||||
|
931,872,1187
|
||||||
|
830,928,1193
|
||||||
|
830,928,1199
|
||||||
|
735,976,1206
|
||||||
|
735,976,1213
|
||||||
|
650,1021,1218
|
||||||
|
650,1021,1225
|
||||||
|
590,1056,1231
|
||||||
|
590,1056,1238
|
||||||
|
566,1079,1244
|
||||||
|
566,1079,1248
|
||||||
|
559,1079,1253
|
||||||
|
559,1079,1259
|
||||||
|
558,1079,1264
|
||||||
|
558,1079,1270
|
||||||
|
558,1079,1277
|
||||||
|
558,1079,1283
|
||||||
|
559,1079,1289
|
||||||
|
559,1079,1296
|
||||||
|
605,1076,1302
|
||||||
|
605,1076,1308
|
||||||
|
706,1022,1315
|
||||||
|
706,1022,1322
|
||||||
|
848,934,1329
|
||||||
|
848,934,1335
|
||||||
|
982,850,1343
|
||||||
|
1079,774,1349
|
||||||
|
1079,774,1357
|
||||||
|
1141,707,1364
|
||||||
|
1172,653,1371
|
||||||
|
1172,653,1379
|
||||||
|
1187,613,1385
|
||||||
|
1187,613,1392
|
||||||
|
1190,577,1398
|
||||||
|
1190,577,1404
|
||||||
|
1190,563,1411
|
||||||
|
1190,563,1417
|
||||||
|
1190,563,1422
|
||||||
|
1190,563,1428
|
||||||
|
1190,563,1434
|
||||||
|
1190,563,1440
|
||||||
|
1190,563,1446
|
||||||
|
1190,563,1451
|
||||||
|
1190,563,1457
|
||||||
|
1190,563,1462
|
||||||
|
1190,563,1468
|
||||||
|
1190,563,1474
|
||||||
|
1190,563,1481
|
||||||
|
1190,563,1488
|
||||||
|
1190,563,1495
|
||||||
|
1190,563,1502
|
||||||
|
1190,563,1509
|
||||||
|
1190,563,1516
|
||||||
|
1190,563,1524
|
||||||
|
1190,563,1530
|
||||||
|
1190,563,1536
|
||||||
|
1190,563,1543
|
||||||
|
1190,563,1548
|
||||||
|
1190,563,1554
|
||||||
|
1190,563,1561
|
||||||
|
1190,563,1568
|
||||||
|
1190,563,1575
|
||||||
|
1190,541,1581
|
||||||
|
1190,526,1589
|
||||||
|
1190,526,1595
|
||||||
|
1186,497,1601
|
||||||
|
1186,497,1607
|
||||||
|
1140,449,1614
|
||||||
|
1140,449,1622
|
||||||
|
1083,407,1629
|
||||||
|
1083,407,1635
|
||||||
|
1005,386,1641
|
||||||
|
936,377,1648
|
||||||
|
936,377,1656
|
||||||
|
866,377,1662
|
||||||
|
866,377,1668
|
||||||
|
805,377,1674
|
||||||
|
805,377,1681
|
||||||
|
746,383,1688
|
||||||
|
746,383,1695
|
||||||
|
701,397,1702
|
||||||
|
701,397,1708
|
||||||
|
681,406,1713
|
||||||
|
681,406,1719
|
||||||
|
672,415,1726
|
||||||
|
671,421,1733
|
||||||
|
671,421,1740
|
||||||
|
671,428,1745
|
||||||
|
671,428,1751
|
||||||
|
671,437,1757
|
||||||
|
671,437,1764
|
||||||
|
676,445,1770
|
||||||
|
676,445,1776
|
||||||
|
689,455,1782
|
||||||
|
689,455,1789
|
||||||
|
713,473,1795
|
||||||
|
713,473,1802
|
||||||
|
743,495,1808
|
||||||
|
743,495,1814
|
||||||
|
772,514,1820
|
||||||
|
772,514,1826
|
||||||
|
808,523,1832
|
||||||
|
808,523,1838
|
||||||
|
844,528,1843
|
||||||
|
844,528,1849
|
||||||
|
886,528,1856
|
||||||
|
886,528,1862
|
||||||
|
953,512,1870
|
||||||
|
1053,455,1877
|
||||||
|
1053,455,1884
|
||||||
|
1149,386,1891
|
||||||
|
1149,386,1897
|
||||||
|
1210,321,1903
|
||||||
|
1210,321,1910
|
||||||
|
1224,278,1916
|
||||||
|
1224,278,1922
|
||||||
|
1224,235,1928
|
||||||
|
1224,235,1934
|
||||||
|
1224,191,1941
|
||||||
|
1224,148,1948
|
||||||
|
1224,148,1955
|
||||||
|
1188,104,1961
|
||||||
|
1188,104,1966
|
||||||
|
1188,104,1972
|
||||||
|
1133,80,1978
|
||||||
|
1133,80,1984
|
||||||
|
1051,73,1990
|
||||||
|
953,73,1997
|
||||||
|
953,73,2005
|
||||||
|
850,99,2010
|
||||||
|
745,160,2021
|
||||||
|
745,160,2028
|
||||||
|
669,229,2032
|
||||||
|
669,229,2040
|
||||||
|
640,291,2046
|
||||||
|
640,291,2052
|
||||||
|
640,333,2059
|
||||||
|
640,333,2065
|
||||||
|
640,374,2071
|
||||||
|
640,374,2078
|
||||||
|
648,411,2085
|
||||||
|
669,447,2093
|
||||||
|
669,447,2098
|
||||||
|
697,494,2104
|
||||||
|
697,494,2114
|
||||||
|
731,531,2119
|
||||||
|
731,531,2125
|
||||||
|
790,559,2131
|
||||||
|
790,559,2138
|
||||||
|
855,571,2146
|
||||||
|
855,571,2152
|
||||||
|
943,571,2158
|
||||||
|
943,571,2162
|
||||||
|
1049,555,2170
|
||||||
|
1162,513,2178
|
||||||
|
1162,513,2183
|
||||||
|
1162,513,2191
|
||||||
|
1248,472,2197
|
||||||
|
1281,445,2202
|
||||||
|
1281,445,2208
|
||||||
|
1286,432,2214
|
||||||
|
1286,432,2223
|
||||||
|
1297,415,2229
|
||||||
|
1305,401,2235
|
||||||
|
1305,401,2244
|
||||||
|
1317,382,2250
|
||||||
|
1317,382,2259
|
||||||
|
1328,364,2265
|
||||||
|
1332,355,2271
|
||||||
|
1332,355,2277
|
||||||
|
1332,352,2283
|
||||||
|
1332,352,2293
|
||||||
|
1332,350,2297
|
||||||
|
1332,350,2303
|
||||||
|
1332,350,2309
|
||||||
|
1332,350,2315
|
||||||
|
1332,348,2321
|
||||||
|
1332,348,2327
|
||||||
|
1324,348,2333
|
||||||
|
1324,348,2339
|
||||||
|
1308,348,2345
|
||||||
|
1308,348,2350
|
||||||
|
1287,348,2357
|
||||||
|
1287,348,2364
|
||||||
|
1261,354,2372
|
||||||
|
1261,354,2379
|
||||||
|
1233,387,2386
|
||||||
|
1204,430,2394
|
||||||
|
1204,430,2399
|
||||||
|
1185,481,2404
|
||||||
|
1185,481,2411
|
||||||
|
1179,536,2417
|
||||||
|
1179,536,2423
|
||||||
|
1179,579,2429
|
||||||
|
1179,579,2435
|
||||||
|
1179,621,2441
|
||||||
|
1179,621,2448
|
||||||
|
1179,659,2454
|
||||||
|
1179,659,2461
|
||||||
|
1199,682,2466
|
||||||
|
1199,682,2472
|
||||||
|
1233,696,2480
|
||||||
|
1233,696,2486
|
||||||
|
1266,705,2492
|
||||||
|
1266,705,2498
|
||||||
|
1300,709,2505
|
||||||
|
1345,709,2511
|
||||||
|
1345,709,2518
|
||||||
|
1384,709,2525
|
||||||
|
1384,709,2532
|
||||||
|
1384,709,2538
|
||||||
|
1384,709,2543
|
||||||
|
1384,709,2550
|
||||||
|
1384,709,2556
|
||||||
|
1384,709,2563
|
||||||
|
1384,709,2569
|
||||||
|
1384,709,2576
|
||||||
|
1384,709,2583
|
||||||
|
1384,709,2589
|
||||||
|
1384,709,2595
|
||||||
|
1384,709,2600
|
||||||
|
1384,709,2605
|
||||||
|
1384,709,2611
|
||||||
|
1384,709,2617
|
||||||
|
1384,709,2624
|
||||||
|
1384,709,2632
|
||||||
|
1384,709,2640
|
||||||
|
1384,709,2646
|
||||||
|
1384,709,2651
|
||||||
|
1384,709,2657
|
||||||
|
1384,709,2662
|
||||||
|
1384,709,2669
|
||||||
|
1384,709,2675
|
||||||
|
1384,709,2682
|
||||||
|
1384,709,2689
|
||||||
|
1384,709,2696
|
||||||
|
1384,709,2702
|
||||||
|
1384,709,2709
|
||||||
|
1384,709,2717
|
||||||
|
1384,709,2723
|
||||||
|
1384,709,2729
|
||||||
|
1384,709,2736
|
||||||
|
1384,709,2744
|
||||||
|
1384,709,2750
|
||||||
|
1384,709,2757
|
||||||
|
1384,709,2764
|
||||||
|
1384,709,2772
|
||||||
|
1380,709,2780
|
||||||
|
1365,710,2787
|
||||||
|
1365,710,2793
|
||||||
|
1336,715,2801
|
||||||
|
1336,715,2808
|
||||||
|
1290,720,2814
|
||||||
|
1290,720,2820
|
||||||
|
1228,722,2827
|
||||||
|
1228,722,2833
|
||||||
|
1140,727,2838
|
||||||
|
1140,727,2844
|
||||||
|
1030,729,2850
|
||||||
|
1030,729,2857
|
||||||
|
904,729,2864
|
||||||
|
804,729,2871
|
||||||
|
804,729,2877
|
||||||
|
742,729,2883
|
||||||
|
742,729,2890
|
||||||
|
693,723,2896
|
||||||
|
693,723,2903
|
||||||
|
629,707,2910
|
||||||
|
629,707,2917
|
||||||
|
561,694,2925
|
||||||
|
499,678,2931
|
||||||
|
499,678,2937
|
||||||
|
499,678,2944
|
||||||
|
458,661,2950
|
||||||
|
428,644,2957
|
||||||
|
428,644,2964
|
||||||
|
400,621,2969
|
||||||
|
400,621,2974
|
||||||
|
378,597,2980
|
||||||
|
378,597,2987
|
||||||
|
365,578,2994
|
||||||
|
365,578,3002
|
||||||
|
358,564,3008
|
||||||
|
358,564,3013
|
||||||
|
356,559,3020
|
||||||
|
356,556,3026
|
||||||
|
356,556,3033
|
||||||
|
356,556,3039
|
||||||
|
356,556,3046
|
||||||
|
356,556,3053
|
||||||
|
356,556,3058
|
||||||
|
356,556,3065
|
||||||
|
356,556,3071
|
||||||
|
356,556,3078
|
||||||
|
356,556,3084
|
||||||
|
356,556,3091
|
||||||
|
356,556,3096
|
||||||
|
356,556,3102
|
||||||
|
356,556,3109
|
||||||
|
356,556,3116
|
||||||
|
356,556,3123
|
||||||
|
356,556,3130
|
||||||
|
356,556,3136
|
||||||
|
356,556,3143
|
||||||
|
356,556,3150
|
||||||
|
356,556,3157
|
||||||
|
356,556,3164
|
||||||
|
356,556,3170
|
||||||
|
356,556,3177
|
||||||
|
356,556,3184
|
||||||
|
356,556,3191
|
||||||
|
356,547,3197
|
||||||
|
356,547,3205
|
||||||
|
353,536,3212
|
||||||
|
353,536,3218
|
||||||
|
344,500,3224
|
||||||
|
344,500,3228
|
||||||
|
320,439,3235
|
||||||
|
320,439,3240
|
||||||
|
299,376,3246
|
||||||
|
299,376,3253
|
||||||
|
274,324,3259
|
||||||
|
274,324,3264
|
||||||
|
251,284,3269
|
||||||
|
251,284,3274
|
||||||
|
231,254,3279
|
||||||
|
231,254,3286
|
||||||
|
214,234,3292
|
||||||
|
214,234,3298
|
||||||
|
204,226,3305
|
||||||
|
204,226,3313
|
||||||
|
200,223,3319
|
||||||
|
200,223,3326
|
||||||
|
199,223,3333
|
||||||
|
199,223,3340
|
||||||
|
199,223,3346
|
||||||
|
199,223,3352
|
||||||
|
199,223,3358
|
||||||
|
199,223,3364
|
||||||
|
199,223,3369
|
||||||
|
199,223,3374
|
||||||
|
199,223,3380
|
||||||
|
199,223,3385
|
||||||
|
202,224,3391
|
||||||
|
202,224,3398
|
||||||
|
212,230,3405
|
||||||
|
235,242,3412
|
||||||
|
235,242,3419
|
||||||
|
268,256,3425
|
||||||
|
268,256,3431
|
||||||
|
331,271,3438
|
||||||
|
331,271,3444
|
||||||
|
439,293,3450
|
||||||
|
439,293,3456
|
||||||
|
590,326,3463
|
||||||
|
750,359,3470
|
||||||
|
750,359,3478
|
||||||
|
905,391,3485
|
||||||
|
905,391,3491
|
||||||
|
1051,425,3499
|
||||||
|
1051,425,3505
|
||||||
|
1178,460,3510
|
||||||
|
1178,460,3515
|
||||||
|
1282,492,3522
|
||||||
|
1282,492,3527
|
||||||
|
1363,517,3533
|
||||||
|
1363,517,3540
|
||||||
|
1406,526,3546
|
||||||
|
1406,526,3553
|
||||||
|
1417,528,3560
|
||||||
|
1420,528,3566
|
||||||
|
1420,528,3572
|
||||||
|
1420,528,3578
|
Loading…
Reference in New Issue
Block a user