2018-02-19 20:55:50 -05:00
|
|
|
import java.awt.AWTException;
|
2018-02-24 10:49:49 -05:00
|
|
|
import java.awt.Graphics2D;
|
2018-02-19 20:55:50 -05:00
|
|
|
import java.awt.Point;
|
2018-02-22 09:28:21 -05:00
|
|
|
import java.awt.Rectangle;
|
|
|
|
import java.awt.Robot;
|
|
|
|
import java.awt.image.BufferedImage;
|
2018-02-23 17:04:28 -05:00
|
|
|
import java.awt.image.DataBufferByte;
|
2018-02-22 09:28:21 -05:00
|
|
|
import java.io.File;
|
2018-02-19 20:55:50 -05:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
2018-02-22 09:28:21 -05:00
|
|
|
import javax.imageio.ImageIO;
|
|
|
|
|
2018-02-24 10:49:49 -05:00
|
|
|
import org.opencv.core.Core;
|
|
|
|
import org.opencv.core.CvType;
|
2018-02-23 17:04:28 -05:00
|
|
|
import org.opencv.core.Mat;
|
2018-02-23 09:26:15 -05:00
|
|
|
import org.opencv.core.Rect2d;
|
2018-02-23 16:43:57 -05:00
|
|
|
import org.opencv.tracking.Tracker;
|
2018-02-24 14:42:05 -05:00
|
|
|
import org.opencv.tracking.TrackerBoosting;
|
|
|
|
import org.opencv.tracking.TrackerGOTURN;
|
2018-02-23 16:43:57 -05:00
|
|
|
import org.opencv.tracking.TrackerKCF;
|
2018-02-24 14:42:05 -05:00
|
|
|
import org.opencv.tracking.TrackerMOSSE;
|
2018-02-23 09:26:15 -05:00
|
|
|
|
2018-02-19 20:55:50 -05:00
|
|
|
public class IronMiner {
|
|
|
|
|
2018-02-23 16:43:57 -05:00
|
|
|
public static final int IRON_ORE_MINING_TIME_MILLISECONDS = 1320;
|
2018-02-22 09:28:21 -05:00
|
|
|
public static final int MAXIMUM_DISTANCE_TO_WALK_TO_IRON_ORE = 400;
|
2018-02-23 09:26:15 -05:00
|
|
|
public static final Point GAME_WINDOW_CENTER = new Point(Constants.GAME_WINDOW_WIDTH / 2, Constants.GAME_WINDOW_HEIGHT / 2);
|
2018-02-19 20:55:50 -05:00
|
|
|
|
|
|
|
Cursor cursor;
|
|
|
|
CursorTask cursorTask;
|
|
|
|
Inventory inventory;
|
2018-02-22 09:28:21 -05:00
|
|
|
ObjectDetector objectDetector;
|
|
|
|
Robot robot;
|
|
|
|
Randomizer randomizer;
|
2018-02-19 20:55:50 -05:00
|
|
|
|
|
|
|
public IronMiner() throws AWTException, IOException
|
|
|
|
{
|
2018-03-04 18:08:04 -05:00
|
|
|
cursor = new Cursor();
|
|
|
|
cursorTask = new CursorTask();
|
|
|
|
inventory = new Inventory();
|
2018-02-22 09:28:21 -05:00
|
|
|
objectDetector = new ObjectDetector();
|
|
|
|
robot = new Robot();
|
|
|
|
randomizer = new Randomizer();
|
2018-02-19 20:55:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public void run() throws Exception {
|
2018-03-05 05:20:29 -05:00
|
|
|
long startTime = System.currentTimeMillis();
|
2018-03-05 06:24:11 -05:00
|
|
|
long garbageCollectionTime = System.currentTimeMillis() + 60 * 5 * 1000;
|
2018-03-05 05:20:29 -05:00
|
|
|
int framesWithoutObjects = 0;
|
|
|
|
|
|
|
|
while (((System.currentTimeMillis() - startTime) / 1000.0 / 60) < 85) {
|
2018-03-04 18:08:04 -05:00
|
|
|
long frameStartTime = System.currentTimeMillis();
|
2018-02-23 16:43:57 -05:00
|
|
|
BufferedImage screenCapture = objectDetector.captureScreenshotGameWindow();
|
2018-03-03 20:04:03 -05:00
|
|
|
System.out.println("looking for iron ores");
|
2018-03-05 05:20:29 -05:00
|
|
|
|
|
|
|
ArrayList<DetectedObject> detectedObjects = objectDetector.getObjectsInImage(screenCapture, 0.30);
|
|
|
|
ArrayList<DetectedObject> ironOres = objectDetector.getObjectsOfClassInList(detectedObjects, "ironOre");
|
2018-03-04 18:08:04 -05:00
|
|
|
System.out.println("Found " + detectedObjects.size() + " objects.");
|
2018-02-24 10:49:49 -05:00
|
|
|
|
2018-03-05 05:20:29 -05:00
|
|
|
if (ironOres.size() == 0) {
|
|
|
|
framesWithoutObjects++;
|
|
|
|
System.out.println("no objects found!");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
framesWithoutObjects = 0;
|
|
|
|
}
|
|
|
|
if (framesWithoutObjects > 50) {
|
|
|
|
CameraCalibrator cameraCalibrator = new CameraCalibrator();
|
|
|
|
cameraCalibrator.rotateUntilObjectFound("ironOre");
|
|
|
|
}
|
|
|
|
|
|
|
|
DetectedObject closestIronOre = getClosestObjectToCharacter(ironOres);
|
2018-02-23 16:43:57 -05:00
|
|
|
if (closestIronOre != null) {
|
2018-02-24 10:49:49 -05:00
|
|
|
Rect2d boundingBox = closestIronOre.getBoundingRect2d();
|
2018-02-28 00:16:57 -05:00
|
|
|
ObjectTracker ironOreTracker = new ObjectTracker(screenCapture, boundingBox);
|
2018-02-23 17:04:28 -05:00
|
|
|
|
2018-02-28 00:16:57 -05:00
|
|
|
cursor.moveAndLeftClickAtCoordinatesWithRandomness(closestIronOre.getCenterForClicking(), 10, 10);
|
2018-02-23 16:43:57 -05:00
|
|
|
|
2018-02-28 00:16:57 -05:00
|
|
|
long miningStartTime = System.currentTimeMillis();
|
2018-03-05 05:20:29 -05:00
|
|
|
int maxTimeToMine = randomizer.nextGaussianWithinRange(3400, 4519);
|
2018-02-23 16:43:57 -05:00
|
|
|
|
2018-02-28 00:16:57 -05:00
|
|
|
boolean objectTrackingFailure = false;
|
2018-03-05 05:20:29 -05:00
|
|
|
boolean oreAvailable = true;
|
|
|
|
int oreLostCount = 0;
|
|
|
|
while (!objectTrackingFailure && oreLostCount < 3 && !isTimeElapsedOverLimit(miningStartTime, maxTimeToMine)) {
|
|
|
|
long trackingFrameStartTime = System.currentTimeMillis();
|
|
|
|
|
2018-02-28 00:16:57 -05:00
|
|
|
screenCapture = objectDetector.captureScreenshotGameWindow();
|
2018-03-05 05:20:29 -05:00
|
|
|
detectedObjects = objectDetector.getObjectsInImage(screenCapture, 0.15);
|
|
|
|
ironOres = objectDetector.getObjectsOfClassInList(detectedObjects, "ironOre");
|
2018-02-28 00:16:57 -05:00
|
|
|
objectTrackingFailure = ironOreTracker.update(screenCapture, boundingBox);
|
2018-03-05 05:20:29 -05:00
|
|
|
oreAvailable = objectDetector.isObjectPresentInBoundingBoxInImage(ironOres, boundingBox, "ironOre");
|
|
|
|
if (!oreAvailable) {
|
|
|
|
oreLostCount++;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
oreLostCount = 0;
|
|
|
|
}
|
|
|
|
System.out.println("Tracking timespan: " + (System.currentTimeMillis() - trackingFrameStartTime));
|
2018-02-23 16:43:57 -05:00
|
|
|
}
|
2018-03-05 05:20:29 -05:00
|
|
|
}
|
|
|
|
|
2018-03-04 18:08:04 -05:00
|
|
|
|
2018-03-05 05:20:29 -05:00
|
|
|
// Garbage Collection
|
2018-03-05 06:24:11 -05:00
|
|
|
if (((System.currentTimeMillis() - garbageCollectionTime) / 1000.0 / 60) > 0) {
|
2018-03-05 05:20:29 -05:00
|
|
|
System.out.println("Running garbage collection.");
|
|
|
|
System.gc();
|
2018-03-05 06:24:11 -05:00
|
|
|
garbageCollectionTime = System.currentTimeMillis() + randomizer.nextGaussianWithinRange(8500, 19340) * 60;
|
2018-03-05 05:20:29 -05:00
|
|
|
}
|
|
|
|
dropInventoryIfFull();
|
2018-02-22 09:28:21 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void dropInventoryIfFull() throws Exception {
|
2018-03-05 05:20:29 -05:00
|
|
|
inventory.updateLastSlot();
|
|
|
|
if (inventory.isLastSlotInInventoryFull()) {
|
2018-02-22 09:28:21 -05:00
|
|
|
cursorTask.optimizedDropAllItemsInInventory(cursor, inventory);
|
2018-02-19 20:55:50 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-28 00:16:57 -05:00
|
|
|
private boolean isTimeElapsedOverLimit(long startTime, int timeLimit) {
|
|
|
|
return (System.currentTimeMillis() - startTime) > timeLimit;
|
2018-02-19 20:55:50 -05:00
|
|
|
}
|
|
|
|
|
2018-02-23 09:26:15 -05:00
|
|
|
private DetectedObject getClosestObjectToCharacter(ArrayList<DetectedObject> detectedObjects) {
|
|
|
|
int closestDistanceToCharacter = Integer.MAX_VALUE;
|
|
|
|
DetectedObject closestObjectToCharacter = null;
|
|
|
|
|
|
|
|
for (DetectedObject detectedObject : detectedObjects) {
|
|
|
|
int objectDistanceToCharacter = getDistanceBetweenPoints(GAME_WINDOW_CENTER, detectedObject.getCenterForClicking());
|
|
|
|
if (objectDistanceToCharacter < closestDistanceToCharacter) {
|
|
|
|
closestDistanceToCharacter = objectDistanceToCharacter;
|
|
|
|
closestObjectToCharacter = detectedObject;
|
2018-02-19 20:55:50 -05:00
|
|
|
}
|
|
|
|
}
|
2018-02-23 09:26:15 -05:00
|
|
|
if (closestObjectToCharacter != null && closestDistanceToCharacter < MAXIMUM_DISTANCE_TO_WALK_TO_IRON_ORE) {
|
|
|
|
return closestObjectToCharacter;
|
2018-02-19 20:55:50 -05:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getDistanceBetweenPoints(Point startingPoint, Point goalPoint) {
|
|
|
|
return (int) (Math.hypot(goalPoint.x - startingPoint.x, goalPoint.y - startingPoint.y));
|
|
|
|
}
|
|
|
|
}
|