Skip to content

Commit

Permalink
feat: Code refactor to handle both Windows and Mac
Browse files Browse the repository at this point in the history
  • Loading branch information
peavers committed Jul 2, 2021
1 parent 2e0aea2 commit 51d12b5
Show file tree
Hide file tree
Showing 14 changed files with 179 additions and 107 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ out/

### VS Code ###
.vscode/

### Debug stuff ###
.debug
19 changes: 12 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {

group = 'io.skyshard'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
sourceCompatibility = 16

configurations {
compileOnly {
Expand All @@ -20,6 +20,14 @@ repositories {
mavenCentral()
}

sonarqube {
properties {
property "sonar.projectKey", group
property "sonar.sourceEncoding", "UTF-8"
property "sonar.host.url", System.getenv("SONAR_HOST")
}
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.apache.commons:commons-lang3:3.12.0'
Expand All @@ -31,9 +39,6 @@ dependencies {
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
}

sonarqube {
properties {
property "sonar.projectKey", group
property "sonar.host.url", System.getenv("SONAR_HOST")
}
}



75 changes: 61 additions & 14 deletions src/main/java/io/skyshard/configuration/GrabConfig.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,77 @@
package io.skyshard.configuration;

import java.awt.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.SystemUtils;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.awt.*;

@Slf4j
@Configuration
public class GrabConfig {

@Bean
public FFmpegFrameGrabber grabber() {
/**
* Create a FFmpegFrameGrabber to capture that screen region. We use this instead of a more
* 'common' robot.createScreenCapture() approach as its faster, and works correctly on Mac OS.
*/
@Bean
public FFmpegFrameGrabber grabber() {

final Dimension dimension = getDimension();

final FFmpegFrameGrabber grabber = getSystemSpecificGrabber();

grabber.setFrameRate(30);
grabber.setImageWidth(dimension.width);
grabber.setImageHeight(dimension.height);
grabber.setOption("preset", "ultrafast");

return grabber;
}

/**
* Return a grabber for either windows or mac; If you're trying to run this on anything else it will most likely
* fail.
*/
private FFmpegFrameGrabber getSystemSpecificGrabber() {

if (SystemUtils.IS_OS_WINDOWS) {
return buildGrabber("desktop", "gdigrab");
}

if (SystemUtils.IS_OS_MAC) {

// 2:0 represents the screen you want to grab, if primary display set as 1:0, if external monitor 2:0.
return buildGrabber("2:0", "avfoundation");
}

throw new RuntimeException("Unsupported System. Exiting...");
}

/**
* Function to create a new grabber with predefined settings.
*/
private FFmpegFrameGrabber buildGrabber(final String filename, final String format) {

FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(filename);
grabber.setFormat(format);

return grabber;
}

/**
* Identify the resolution of the current monitor.
*/
private Dimension getDimension() {

final Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
final var dimension = Toolkit.getDefaultToolkit().getScreenSize();

log.info(
"Using screen dimensions {}x{} as reference points", dimension.width, dimension.height);
log.info(
"Using screen dimensions {}x{} as reference points", dimension.width, dimension.height);

final FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("desktop");
grabber.setFormat("gdigrab");
grabber.setFrameRate(1);
grabber.setImageWidth(dimension.width);
grabber.setImageHeight(dimension.height);
grabber.setOption("preset", "ultrafast");
return dimension;
}

return grabber;
}
}
10 changes: 7 additions & 3 deletions src/main/java/io/skyshard/configuration/RobotConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,20 @@
@Configuration
public class RobotConfig {

/**
* Create a singleton robot, the robot is used for moving the mouse pointer as well as keyboard
* inputs.
*/
@Bean
public Robot robot() {

try {
final Robot robot = new Robot();
final var robot = new Robot();
robot.setAutoWaitForIdle(true);

return robot;
} catch (final AWTException e) {
throw new RuntimeException(e.getMessage());
} catch (final Exception exception) {
throw new RuntimeException(exception.getMessage());
}
}
}
7 changes: 4 additions & 3 deletions src/main/java/io/skyshard/configuration/TemplateConfig.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package io.skyshard.configuration;

import io.skyshard.properties.AppProperties;
import java.io.File;
import java.io.FileNotFoundException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
Expand All @@ -12,9 +12,10 @@

@Slf4j
@Configuration
@RequiredArgsConstructor
public class TemplateConfig {

private final AppProperties appProperties = new AppProperties();
private final AppProperties appProperties;

/**
* Read in the matching template file from the resource directory. If this can't be found or its
Expand All @@ -24,7 +25,7 @@ public class TemplateConfig {
public Mat loadTemplate() {

try {
final File templateSource =
final var templateSource =
ResourceUtils.getFile(String.format("classpath:%s", appProperties.getTemplate()));

log.info("Using template file {}", templateSource.getAbsolutePath());
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/io/skyshard/domain/Target.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,26 @@
import lombok.Data;
import org.opencv.core.Point;

/** Represents where a target is found on the screen. */
@Data
@Builder
public class Target {

private Point point;

/**
* Get the X location of the point. Since we're talking about pixels here we don't care about the
* decimal point.
*/
public int x() {

return (int) Math.round(this.point.x);
}

/**
* Get the Y location of the point. Since we're talking about pixels here we don't care about the
* decimal point.
*/
public int y() {

return (int) Math.round(this.point.y);
Expand Down
3 changes: 0 additions & 3 deletions src/main/java/io/skyshard/services/AttackService.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package io.skyshard.services;

import io.skyshard.domain.Target;
import java.util.List;

public interface AttackService {

void attack(Target target);

void attack(List<Target> targets);
}
38 changes: 8 additions & 30 deletions src/main/java/io/skyshard/services/AttackServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,31 @@

import io.skyshard.domain.Target;
import io.skyshard.utils.MathUtils;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.awt.event.KeyEvent;

@Slf4j
@Service
@RequiredArgsConstructor
public class AttackServiceImpl implements AttackService {

private final Robot robot;

/**
* Move the mouse to the target location, then offset it slightly to counter the fact we always
* find the very bottom right/left corner of a template match. Once the mouse has been moved over
* the target, press the '1' keyboard button.
*/
@Override
public void attack(final Target target) {

process(target, false);
}

@Override
public void attack(final List<Target> targets) {

targets.forEach(target -> process(target, true));
}

private void process(final Target target, final boolean pause) {

if (target == null) {
return;
}

robot.mouseMove(target.x() - 5, target.y() - 5);
robot.keyPress(KeyEvent.VK_1);
robot.delay(MathUtils.random(25, 50));
robot.keyRelease(KeyEvent.VK_1);

if (pause) {
pause();
}
}

@SneakyThrows
private void pause() {

TimeUnit.MILLISECONDS.sleep(MathUtils.random(200, 300));
}
}
3 changes: 2 additions & 1 deletion src/main/java/io/skyshard/services/FindTargetService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

import io.skyshard.domain.Target;
import java.util.List;
import java.util.Optional;
import org.opencv.core.Mat;

public interface FindTargetService {

List<Target> findMultipleTarget(Mat source);

Target findSingleTarget(Mat source);
Optional<Target> findSingleTarget(Mat source);
}
Loading

0 comments on commit 51d12b5

Please sign in to comment.