|
|
@ -23,13 +23,18 @@ import java.util.concurrent.TimeUnit;
|
|
|
|
* @version 0.0.1
|
|
|
|
* @version 0.0.1
|
|
|
|
* @since 1.8
|
|
|
|
* @since 1.8
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public class JMacro {
|
|
|
|
public abstract class JMacro {
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 机器人操作实例
|
|
|
|
* 机器人操作实例
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private final Robot robot;
|
|
|
|
private final Robot robot;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 视口区域
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
protected ViewRect focusRect;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 图例目录
|
|
|
|
* 图例目录
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -41,12 +46,13 @@ public class JMacro {
|
|
|
|
this.robot = new Robot();
|
|
|
|
this.robot = new Robot();
|
|
|
|
this.robot.setAutoDelay(100);
|
|
|
|
this.robot.setAutoDelay(100);
|
|
|
|
this.legend = new File("legend");
|
|
|
|
this.legend = new File("legend");
|
|
|
|
|
|
|
|
this.startFocus();
|
|
|
|
} catch (AWTException e) {
|
|
|
|
} catch (AWTException e) {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public JMacro(File legend) throws AWTException {
|
|
|
|
public JMacro(File legend) {
|
|
|
|
this();
|
|
|
|
this();
|
|
|
|
this.legend = legend;
|
|
|
|
this.legend = legend;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -59,6 +65,29 @@ public class JMacro {
|
|
|
|
this.legend = legend;
|
|
|
|
this.legend = legend;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 获取视口区域
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @return 视口区域
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public void startFocus() {
|
|
|
|
|
|
|
|
TaskUtil.asyncTask(() -> {
|
|
|
|
|
|
|
|
focusRect = TaskUtil.timeTask(this::focus, 10, TimeUnit.SECONDS);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 获取视口区域
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @return 视口区域
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public abstract ViewRect focus();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 执行脚本
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public abstract void run();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 键盘按键组
|
|
|
|
* 键盘按键组
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -127,7 +156,7 @@ public class JMacro {
|
|
|
|
public void mouseLeftClick(ViewPoint rect) {
|
|
|
|
public void mouseLeftClick(ViewPoint rect) {
|
|
|
|
mouseMove(rect);
|
|
|
|
mouseMove(rect);
|
|
|
|
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
|
|
|
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
|
|
|
delayTap();
|
|
|
|
robot.delay(100);
|
|
|
|
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
|
|
|
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -159,11 +188,11 @@ public class JMacro {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public void mouseLeftDrag(ViewPoint start, ViewPoint end, boolean smooth) {
|
|
|
|
public void mouseLeftDrag(ViewPoint start, ViewPoint end, boolean smooth) {
|
|
|
|
mouseMove(start, smooth);
|
|
|
|
mouseMove(start, smooth);
|
|
|
|
delayTap();
|
|
|
|
delayUnstable();
|
|
|
|
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
|
|
|
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
|
|
|
delayTap();
|
|
|
|
delayUnstable();
|
|
|
|
mouseMove(end, smooth);
|
|
|
|
mouseMove(end, smooth);
|
|
|
|
delayTap();
|
|
|
|
delayUnstable();
|
|
|
|
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
|
|
|
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -186,11 +215,11 @@ public class JMacro {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public void mouseRightDrag(ViewPoint start, ViewPoint end, boolean smooth) {
|
|
|
|
public void mouseRightDrag(ViewPoint start, ViewPoint end, boolean smooth) {
|
|
|
|
mouseMove(start, smooth);
|
|
|
|
mouseMove(start, smooth);
|
|
|
|
delayTap();
|
|
|
|
delayUnstable();
|
|
|
|
robot.mousePress(InputEvent.BUTTON3_DOWN_MASK);
|
|
|
|
robot.mousePress(InputEvent.BUTTON3_DOWN_MASK);
|
|
|
|
delayTap();
|
|
|
|
delayUnstable();
|
|
|
|
mouseMove(end, smooth);
|
|
|
|
mouseMove(end, smooth);
|
|
|
|
delayTap();
|
|
|
|
delayUnstable();
|
|
|
|
robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK);
|
|
|
|
robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -200,11 +229,11 @@ public class JMacro {
|
|
|
|
* @param rect 矩形区域
|
|
|
|
* @param rect 矩形区域
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public void mouseWheelClick(ViewRect rect) {
|
|
|
|
public void mouseWheelClick(ViewRect rect) {
|
|
|
|
delayTap();
|
|
|
|
delayUnstable();
|
|
|
|
robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]);
|
|
|
|
robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]);
|
|
|
|
delayTap();
|
|
|
|
delayUnstable();
|
|
|
|
robot.mousePress(InputEvent.BUTTON2_DOWN_MASK);
|
|
|
|
robot.mousePress(InputEvent.BUTTON2_DOWN_MASK);
|
|
|
|
delayTap();
|
|
|
|
delayUnstable();
|
|
|
|
robot.mouseRelease(InputEvent.BUTTON2_DOWN_MASK);
|
|
|
|
robot.mouseRelease(InputEvent.BUTTON2_DOWN_MASK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -214,11 +243,11 @@ public class JMacro {
|
|
|
|
* @param rect 矩形区域
|
|
|
|
* @param rect 矩形区域
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public void mouseRightClick(ViewRect rect) {
|
|
|
|
public void mouseRightClick(ViewRect rect) {
|
|
|
|
delayTap();
|
|
|
|
delayUnstable();
|
|
|
|
robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]);
|
|
|
|
robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]);
|
|
|
|
delayTap();
|
|
|
|
delayUnstable();
|
|
|
|
robot.mousePress(InputEvent.BUTTON3_DOWN_MASK);
|
|
|
|
robot.mousePress(InputEvent.BUTTON3_DOWN_MASK);
|
|
|
|
delayTap();
|
|
|
|
delayUnstable();
|
|
|
|
robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK);
|
|
|
|
robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -228,9 +257,9 @@ public class JMacro {
|
|
|
|
* @param rect 矩形区域
|
|
|
|
* @param rect 矩形区域
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public void mouseLeftDoubleClick(ViewRect rect) {
|
|
|
|
public void mouseLeftDoubleClick(ViewRect rect) {
|
|
|
|
delayTap();
|
|
|
|
delayUnstable();
|
|
|
|
robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]);
|
|
|
|
robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]);
|
|
|
|
delayTap();
|
|
|
|
delayUnstable();
|
|
|
|
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
|
|
|
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
|
|
|
|
robot.delay(100);
|
|
|
|
robot.delay(100);
|
|
|
|
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
|
|
|
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
|
|
|
@ -247,6 +276,13 @@ public class JMacro {
|
|
|
|
return robot.createScreenCapture(new Rectangle(viewRect.getLeft(), viewRect.getTop(), viewRect.getWidth(), viewRect.getHeight()));
|
|
|
|
return robot.createScreenCapture(new Rectangle(viewRect.getLeft(), viewRect.getTop(), viewRect.getWidth(), viewRect.getHeight()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 获取聚焦区域
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public ViewRect getFocusRect() {
|
|
|
|
|
|
|
|
return focusRect;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 获取屏幕范围
|
|
|
|
* 获取屏幕范围
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -277,7 +313,7 @@ public class JMacro {
|
|
|
|
* @return 匹配图片区域
|
|
|
|
* @return 匹配图片区域
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public ViewRect findPic(File pic, double minSimilar) {
|
|
|
|
public ViewRect findPic(File pic, double minSimilar) {
|
|
|
|
return findPic(getScreenRect(), ImageUtil.load(pic), minSimilar);
|
|
|
|
return findPic(getFocusRect(), ImageUtil.load(pic), minSimilar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -288,7 +324,7 @@ public class JMacro {
|
|
|
|
* @return 匹配图片区域
|
|
|
|
* @return 匹配图片区域
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public ViewRect findPic(BufferedImage pic, double minSimilar) {
|
|
|
|
public ViewRect findPic(BufferedImage pic, double minSimilar) {
|
|
|
|
return findPic(getScreenRect(), pic, minSimilar);
|
|
|
|
return findPic(getFocusRect(), pic, minSimilar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -328,6 +364,10 @@ public class JMacro {
|
|
|
|
* @return 匹配图片区域
|
|
|
|
* @return 匹配图片区域
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public ViewRect findPic(ViewRect viewRect, BufferedImage pic, double minSimilar) {
|
|
|
|
public ViewRect findPic(ViewRect viewRect, BufferedImage pic, double minSimilar) {
|
|
|
|
|
|
|
|
// 当聚焦区域为null时,默认全屏查找
|
|
|
|
|
|
|
|
if (viewRect == null) {
|
|
|
|
|
|
|
|
viewRect = getFocusRect() != null ? getFocusRect() : getScreenRect();
|
|
|
|
|
|
|
|
}
|
|
|
|
// 当查找区域比图片还小时,直接返回失败
|
|
|
|
// 当查找区域比图片还小时,直接返回失败
|
|
|
|
if (viewRect.getWidth() < pic.getWidth() || viewRect.getHeight() < pic.getHeight()) {
|
|
|
|
if (viewRect.getWidth() < pic.getWidth() || viewRect.getHeight() < pic.getHeight()) {
|
|
|
|
Logger.error("视口尺寸小于图片");
|
|
|
|
Logger.error("视口尺寸小于图片");
|
|
|
@ -373,22 +413,27 @@ public class JMacro {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void delay() {
|
|
|
|
public void delay() {
|
|
|
|
delayNormal();
|
|
|
|
delay(100);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void delayTap() {
|
|
|
|
public void delay(long millis) {
|
|
|
|
int i = RandomUtil.randomInt(100, 500);
|
|
|
|
try {
|
|
|
|
robot.delay(i);
|
|
|
|
Thread.sleep(millis);
|
|
|
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void delayNormal() {
|
|
|
|
public void delayUnstable() {
|
|
|
|
int i = RandomUtil.randomInt(500, 1000);
|
|
|
|
delayUnstable(500);
|
|
|
|
robot.delay(i);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void delayLong() {
|
|
|
|
public void delayUnstable(long millis) {
|
|
|
|
int i = RandomUtil.randomInt(1000, 2000);
|
|
|
|
if (millis < 200) {
|
|
|
|
robot.delay(i);
|
|
|
|
delay(millis);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
delay(RandomUtil.randomLong(millis - 100, millis + 100));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -399,7 +444,7 @@ public class JMacro {
|
|
|
|
* @return 匹配图片区域
|
|
|
|
* @return 匹配图片区域
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public ViewRect waitAndFindPic(File file, double minSimilar) {
|
|
|
|
public ViewRect waitAndFindPic(File file, double minSimilar) {
|
|
|
|
return waitAndFindPic(getScreenRect(), file, minSimilar, 10, TimeUnit.SECONDS);
|
|
|
|
return waitAndFindPic(getFocusRect(), file, minSimilar, 10, TimeUnit.SECONDS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -439,7 +484,7 @@ public class JMacro {
|
|
|
|
* @return 匹配图片区域
|
|
|
|
* @return 匹配图片区域
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public ViewRect waitAndFindPic(File file, double minSimilar, long time, TimeUnit unit) {
|
|
|
|
public ViewRect waitAndFindPic(File file, double minSimilar, long time, TimeUnit unit) {
|
|
|
|
return waitAndFindPic(getScreenRect(), file, minSimilar, time, unit);
|
|
|
|
return waitAndFindPic(getFocusRect(), file, minSimilar, time, unit);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -482,7 +527,7 @@ public class JMacro {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
while (true) {
|
|
|
|
delayTap();
|
|
|
|
delayUnstable();
|
|
|
|
ViewRect pic = findPic(rect, image, minSimilar);
|
|
|
|
ViewRect pic = findPic(rect, image, minSimilar);
|
|
|
|
if (pic != null) {
|
|
|
|
if (pic != null) {
|
|
|
|
return pic;
|
|
|
|
return pic;
|
|
|
@ -503,7 +548,7 @@ public class JMacro {
|
|
|
|
if (!legendName.endsWith(".png")) {
|
|
|
|
if (!legendName.endsWith(".png")) {
|
|
|
|
legendName = legendName + ".png";
|
|
|
|
legendName = legendName + ".png";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return waitAndMatchPic(rect, new File(legend, legendName), minSimilar, 10, TimeUnit.SECONDS);
|
|
|
|
return waitAndMatchPic(rect, new File(legend, legendName), minSimilar, 3, TimeUnit.SECONDS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -515,7 +560,7 @@ public class JMacro {
|
|
|
|
* @return 匹配图片区域
|
|
|
|
* @return 匹配图片区域
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public ViewRect waitAndMatchPic(ViewRect rect, File file, double minSimilar) {
|
|
|
|
public ViewRect waitAndMatchPic(ViewRect rect, File file, double minSimilar) {
|
|
|
|
return waitAndMatchPic(rect, file, minSimilar, 10, TimeUnit.SECONDS);
|
|
|
|
return waitAndMatchPic(rect, file, minSimilar, 3, TimeUnit.SECONDS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -530,6 +575,7 @@ public class JMacro {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public ViewRect waitAndMatchPic(ViewRect rect, File file, double minSimilar, long time, TimeUnit unit) {
|
|
|
|
public ViewRect waitAndMatchPic(ViewRect rect, File file, double minSimilar, long time, TimeUnit unit) {
|
|
|
|
return TaskUtil.timeTask(() -> {
|
|
|
|
return TaskUtil.timeTask(() -> {
|
|
|
|
|
|
|
|
// TODO: 2024/9/1 因为另起线程,导致发起线程已停止,但此线程未停止
|
|
|
|
while (true) {
|
|
|
|
while (true) {
|
|
|
|
ViewRect matchPic = matchPic(rect, file, minSimilar);
|
|
|
|
ViewRect matchPic = matchPic(rect, file, minSimilar);
|
|
|
|
if (matchPic != null) {
|
|
|
|
if (matchPic != null) {
|
|
|
@ -548,6 +594,9 @@ public class JMacro {
|
|
|
|
* @return 匹配图片
|
|
|
|
* @return 匹配图片
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public ViewRect matchPic(ViewRect rect, File file, double minSimilar) {
|
|
|
|
public ViewRect matchPic(ViewRect rect, File file, double minSimilar) {
|
|
|
|
|
|
|
|
if (minSimilar > 1) {
|
|
|
|
|
|
|
|
throw new RuntimeException("this minSimilar must be less than 1");
|
|
|
|
|
|
|
|
}
|
|
|
|
if (!file.exists()) {
|
|
|
|
if (!file.exists()) {
|
|
|
|
Logger.error("file [{}] not exist", file.getAbsolutePath());
|
|
|
|
Logger.error("file [{}] not exist", file.getAbsolutePath());
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
|