diff --git a/legend/城镇_L449,887.png b/legend/城镇#L449,887.png similarity index 100% rename from legend/城镇_L449,887.png rename to legend/城镇#L449,887.png diff --git a/legend/城镇_L456,887.png b/legend/城镇#L456,887.png similarity index 100% rename from legend/城镇_L456,887.png rename to legend/城镇#L456,887.png diff --git a/legend/城镇_充值_L448,36.png b/legend/城镇#充值_L448,36.png similarity index 100% rename from legend/城镇_充值_L448,36.png rename to legend/城镇#充值_L448,36.png diff --git a/legend/城镇_广告.png b/legend/城镇#广告.png similarity index 100% rename from legend/城镇_广告.png rename to legend/城镇#广告.png diff --git a/legend/城镇_探险_L35,881.png b/legend/城镇_探险#L35,881.png similarity index 100% rename from legend/城镇_探险_L35,881.png rename to legend/城镇_探险#L35,881.png diff --git a/legend/城镇_欢迎新成员_L199,773.png b/legend/城镇_欢迎新成员#L199,773.png similarity index 100% rename from legend/城镇_欢迎新成员_L199,773.png rename to legend/城镇_欢迎新成员#L199,773.png diff --git a/legend/城镇_离线收益_L204,734.png b/legend/城镇_离线收益#L204,734.png similarity index 100% rename from legend/城镇_离线收益_L204,734.png rename to legend/城镇_离线收益#L204,734.png diff --git a/legend/城镇_避难者_L3,174.png b/legend/城镇_避难者#L3,174.png similarity index 100% rename from legend/城镇_避难者_L3,174.png rename to legend/城镇_避难者#L3,174.png diff --git a/legend/探险_不可领取_L420,667.png b/legend/探险_不可领取#L420,667.png similarity index 100% rename from legend/探险_不可领取_L420,667.png rename to legend/探险_不可领取#L420,667.png diff --git a/legend/探险_按钮_L240,854.png b/legend/探险_按钮#L240,854.png similarity index 100% rename from legend/探险_按钮_L240,854.png rename to legend/探险_按钮#L240,854.png diff --git a/legend/探险_获得奖励_L196,218.png b/legend/探险_获得奖励#L196,218.png similarity index 100% rename from legend/探险_获得奖励_L196,218.png rename to legend/探险_获得奖励#L196,218.png diff --git a/legend/探险_返回_L4,4.png b/legend/探险_返回#L4,4.png similarity index 100% rename from legend/探险_返回_L4,4.png rename to legend/探险_返回#L4,4.png diff --git a/legend/探险_领取_L426,667.png b/legend/探险_领取#L426,667.png similarity index 100% rename from legend/探险_领取_L426,667.png rename to legend/探险_领取#L426,667.png diff --git a/legend/探险_领取2_L230,664.png b/legend/探险_领取2#L230,664.png similarity index 100% rename from legend/探险_领取2_L230,664.png rename to legend/探险_领取2#L230,664.png diff --git a/legend/野外_L444,888.png b/legend/野外#L444,888.png similarity index 100% rename from legend/野外_L444,888.png rename to legend/野外#L444,888.png diff --git a/legend/野外_任务_L16,759.png b/legend/野外_任务#L16,759.png similarity index 100% rename from legend/野外_任务_L16,759.png rename to legend/野外_任务#L16,759.png diff --git a/legend/野外_搜索_L226,879.png b/legend/野外_搜索#L226,879.png similarity index 100% rename from legend/野外_搜索_L226,879.png rename to legend/野外_搜索#L226,879.png diff --git a/legend/野外_木材.png b/legend/野外_木材.png deleted file mode 100644 index bf77b43..0000000 Binary files a/legend/野外_木材.png and /dev/null differ diff --git a/legend/野外_煤矿.png b/legend/野外_煤矿.png deleted file mode 100644 index 72a73a3..0000000 Binary files a/legend/野外_煤矿.png and /dev/null differ diff --git a/legend/野外_生肉.png b/legend/野外_生肉.png deleted file mode 100644 index 8f05f7e..0000000 Binary files a/legend/野外_生肉.png and /dev/null differ diff --git a/legend/野外_资源_+.png b/legend/野外_资源_+.png deleted file mode 100644 index 047491c..0000000 Binary files a/legend/野外_资源_+.png and /dev/null differ diff --git a/legend/野外_资源_-.png b/legend/野外_资源_-.png deleted file mode 100644 index f01387e..0000000 Binary files a/legend/野外_资源_-.png and /dev/null differ diff --git a/legend/野外_资源_出征.png b/legend/野外_资源_出征.png deleted file mode 100644 index cca1085..0000000 Binary files a/legend/野外_资源_出征.png and /dev/null differ diff --git a/legend/野外_资源_采集.png b/legend/野外_资源_采集.png deleted file mode 100644 index 3624116..0000000 Binary files a/legend/野外_资源_采集.png and /dev/null differ diff --git a/legend/野外_资源_采集队伍满.png b/legend/野外_资源_采集队伍满.png deleted file mode 100644 index 012d989..0000000 Binary files a/legend/野外_资源_采集队伍满.png and /dev/null differ diff --git a/legend/野外_铁矿.png b/legend/野外_铁矿.png deleted file mode 100644 index 2957c35..0000000 Binary files a/legend/野外_铁矿.png and /dev/null differ diff --git a/legend/首页_广告关闭按钮.png b/legend/首页_广告关闭按钮.png deleted file mode 100644 index 651b74a..0000000 Binary files a/legend/首页_广告关闭按钮.png and /dev/null differ diff --git a/src/main/java/com/example/jmacro/wjdr/JMacro.java b/src/main/java/com/example/jmacro/wjdr/JMacro.java index 1674a36..169adb6 100644 --- a/src/main/java/com/example/jmacro/wjdr/JMacro.java +++ b/src/main/java/com/example/jmacro/wjdr/JMacro.java @@ -1,8 +1,7 @@ package com.example.jmacro.wjdr; -import cn.hutool.core.convert.Convert; import cn.hutool.core.util.RandomUtil; -import cn.hutool.core.util.ReUtil; +import com.example.jmacro.wjdr.base.Legend; import com.example.jmacro.wjdr.base.ViewPoint; import com.example.jmacro.wjdr.base.ViewRect; import com.example.jmacro.wjdr.util.ColorUtil; @@ -35,48 +34,32 @@ public abstract class JMacro { */ protected ViewRect focusRect; - /** - * 图例目录 - */ - private File legend; - public JMacro() { try { // 机器人初始化 this.robot = new Robot(); - this.robot.setAutoDelay(100); - this.legend = new File("legend"); + this.robot.setAutoDelay(30); this.startFocus(); } catch (AWTException e) { throw new RuntimeException(e); } } - public JMacro(File legend) { - this(); - this.legend = legend; - } - public Robot getRobot() { return robot; } - public File getLegend() { - return legend; - } - - public void setLegend(File legend) { - this.legend = legend; - } - /** - * 获取视口区域 - * - * @return 视口区域 + * 开始聚焦 */ public void startFocus() { TaskUtil.asyncTask(() -> { focusRect = TaskUtil.timeTask(this::focus, 10, TimeUnit.SECONDS); + if (focusRect != null) { + Logger.info("聚焦成功"); + } else { + Logger.error("聚焦失败"); + } }); } @@ -145,7 +128,7 @@ public abstract class JMacro { int dx = (int) (startX + (point.getX() - startX) * d); int dy = (int) (startY + (point.getY() - startY) * d); robot.mouseMove(dx, dy); - robot.delay(RandomUtil.randomInt(interval - 10, interval + 10)); + delay(RandomUtil.randomInt(interval - 10, interval + 10)); } } else { robot.mouseMove(point.getX(), point.getY()); @@ -160,7 +143,7 @@ public abstract class JMacro { public void mouseLeftClick(ViewPoint rect) { mouseMove(rect); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - robot.delay(100); + delay(100); robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); } @@ -265,11 +248,11 @@ public abstract class JMacro { robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]); delayUnstable(); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - robot.delay(100); + delay(100); robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); - robot.delay(100); + delay(100); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - robot.delay(100); + delay(100); robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); } @@ -284,86 +267,88 @@ public abstract class JMacro { * 获取聚焦区域 */ public ViewRect getFocusRect() { - return focusRect; + if (focusRect != null) { + return focusRect; + } + // 返回屏幕区域 + return getScreenRect(); } /** - * 获取屏幕范围 + * 获取聚焦区域 */ public ViewRect getScreenRect() { + if (focusRect != null) { + return focusRect; + } + // 返回屏幕区域 Toolkit tk = Toolkit.getDefaultToolkit(); return new ViewRect(0, 0, tk.getScreenSize().width, tk.getScreenSize().height); } /** - * 全屏查找图片 - * - * @param legendName 图例名称 - * @param minSimilar 最低相似度 - * @return 匹配图片区域 + * 延迟 */ - public ViewRect findPic(String legendName, double minSimilar) { - if (!legendName.endsWith(".png")) { - legendName = legendName + ".png"; + public void delay() { + delay(100); + } + + /** + * 延迟 + */ + public void delay(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + throw new RuntimeException(e); } - return findPic(new File(legend, legendName), minSimilar); } /** - * 全屏查找图片 - * - * @param pic 图片 - * @param minSimilar 最低相似度 - * @return 匹配图片区域 + * 抖动延迟 */ - public ViewRect findPic(File pic, double minSimilar) { - return findPic(getFocusRect(), ImageUtil.load(pic), minSimilar); + public void delayUnstable() { + delayUnstable(500); } /** - * 全屏查找图片 - * - * @param pic 图片 - * @param minSimilar 最低相似度 - * @return 匹配图片区域 + * 抖动延迟 */ - public ViewRect findPic(BufferedImage pic, double minSimilar) { - return findPic(getFocusRect(), pic, minSimilar); + public void delayUnstable(long millis) { + if (millis < 200) { + delay(millis); + return; + } + delay(RandomUtil.randomLong(millis - 100, millis + 100)); } /** - * 应用视口查找图例 + * 全屏查找图片 * - * @param viewRect 应用视口 - * @param legendName 图例名称 + * @param pic 图片 * @param minSimilar 最低相似度 * @return 匹配图片区域 */ - public ViewRect findPic(ViewRect viewRect, String legendName, double minSimilar) { - if (!legendName.endsWith(".png")) { - legendName = legendName + ".png"; - } - return findPic(viewRect, new File(legend, legendName), minSimilar); + public ViewRect findPic(File pic, double minSimilar) { + return findPic(getFocusRect(), ImageUtil.load(pic), minSimilar); } - /** - * 应用视口查找图例 + * 全屏查找图片 * - * @param viewRect 应用视口 - * @param legend 图例文件 + * @param pic 图片 * @param minSimilar 最低相似度 * @return 匹配图片区域 */ - public ViewRect findPic(ViewRect viewRect, File legend, double minSimilar) { - return findPic(viewRect, ImageUtil.load(legend), minSimilar); + public ViewRect findPic(BufferedImage pic, double minSimilar) { + return findPic(getFocusRect(), pic, minSimilar); } /** - * 获取定位 + * 查找图片 * - * @param pic 参考图 - * @param viewRect 查找范围 + * @param viewRect 查找范围(不设时,取全屏) + * @param pic 待查找图片 * @param minSimilar 相似度 * @return 匹配图片区域 */ @@ -377,6 +362,9 @@ public abstract class JMacro { Logger.error("视口尺寸小于图片"); return null; } + if (minSimilar > 1) { + throw new RuntimeException("this minSimilar must be less than 1"); + } // 获取实时屏幕 BufferedImage screen = capture(robot, viewRect); @@ -407,281 +395,297 @@ public abstract class JMacro { if (lt && rt && lb && rb && cc) { // 统计相似点数 int samePixels = 0; - // 统计不相似点数 - int diffPixels = 0; for (int smallY = 0; smallY < pic.getHeight(); smallY++) { for (int smallX = 0; smallX < pic.getWidth(); smallX++) { if (ColorUtil.isSimilar(screenData[x + smallX][y + smallY], picData[smallX][smallY])) { samePixels++; - } else { - diffPixels++; } } } - // 计算目前相似度 + // 计算相似度 double similar = (double) samePixels / (pic.getWidth() * pic.getHeight()); if (similar >= minSimilar) { return new ViewRect(x, y, x + pic.getWidth(), y + pic.getHeight(), similar); } - // 计算目前最大相似度 - // 根据不相似像素点数推断本次可能达到的最大相似度,如果可能达到的最大相似度都小于预取相似度就不用比下去了 - double maxSimilar = 1.0d - (double) diffPixels / (pic.getWidth() * pic.getHeight()); - if (maxSimilar < minSimilar) { - return null; - } } } } return null; } - public void delay() { - delay(100); - } - - public void delay(long millis) { - try { - Thread.sleep(millis); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - - public void delayUnstable() { - delayUnstable(500); + /** + * 等待并查找图片 + * + * @param pic 图片 + * @param minSimilar 最低相似度 + * @return 匹配图片区域 + */ + public ViewRect waitAndFindPic(File pic, double minSimilar) { + return waitAndFindPic(getFocusRect(), pic, minSimilar, 10); } - public void delayUnstable(long millis) { - if (millis < 200) { - delay(millis); - return; - } - delay(RandomUtil.randomLong(millis - 100, millis + 100)); + /** + * 等待并查找图片 + * + * @param pic 图片 + * @param minSimilar 最低相似度 + * @return 匹配图片区域 + */ + public ViewRect waitAndFindPic(BufferedImage pic, double minSimilar) { + return waitAndFindPic(getFocusRect(), pic, minSimilar, 10); } /** * 等待并查找图片 * - * @param file 图例 + * @param pic 图片 * @param minSimilar 最低相似度 + * @param seconds 最长等待秒数 * @return 匹配图片区域 */ - public ViewRect waitAndFindPic(File file, double minSimilar) { - return waitAndFindPic(getFocusRect(), file, minSimilar, 10, TimeUnit.SECONDS); + public ViewRect waitAndFindPic(File pic, double minSimilar, long seconds) { + return waitAndFindPic(getFocusRect(), pic, minSimilar, seconds); } /** * 等待并查找图片 * - * @param rect 查找区域 - * @param file 图例 + * @param pic 图片 * @param minSimilar 最低相似度 + * @param seconds 最长等待秒数 * @return 匹配图片区域 */ - public ViewRect waitAndFindPic(ViewRect rect, File file, double minSimilar) { - return waitAndFindPic(rect, file, minSimilar, 10, TimeUnit.SECONDS); + public ViewRect waitAndFindPic(BufferedImage pic, double minSimilar, long seconds) { + return waitAndFindPic(getFocusRect(), pic, minSimilar, seconds); } /** * 等待并查找图片 * * @param rect 查找区域 - * @param legendName 图例名称 + * @param pic 图片 * @param minSimilar 最低相似度 * @return 匹配图片区域 */ - public ViewRect waitAndFindPic(ViewRect rect, String legendName, double minSimilar) { - if (!legendName.endsWith(".png")) { - legendName = legendName + ".png"; - } - return waitAndFindPic(rect, new File(legend, legendName), minSimilar, 10, TimeUnit.SECONDS); + public ViewRect waitAndFindPic(ViewRect rect, File pic, double minSimilar) { + return waitAndFindPic(rect, pic, minSimilar, 10); } /** * 等待并查找图片 * - * @param file 图例 + * @param rect 查找区域 + * @param pic 图片 * @param minSimilar 最低相似度 - * @param time 最长等待时间 - * @param unit 最长等待时间单位 + * @param seconds 最长等待秒数 * @return 匹配图片区域 */ - public ViewRect waitAndFindPic(File file, double minSimilar, long time, TimeUnit unit) { - return waitAndFindPic(getFocusRect(), file, minSimilar, time, unit); + public ViewRect waitAndFindPic(ViewRect rect, File pic, double minSimilar, long seconds) { + return waitAndFindPic(rect, ImageUtil.load(pic), minSimilar, seconds); } /** * 等待并查找图片 * * @param rect 查找区域 - * @param legendName 图例名称 + * @param pic 图片 * @param minSimilar 最低相似度 - * @param time 最长等待时间 - * @param unit 最长等待时间单位 * @return 匹配图片区域 */ - public ViewRect waitAndFindPic(ViewRect rect, String legendName, double minSimilar, long time, TimeUnit unit) { - if (!legendName.endsWith(".png")) { - legendName = legendName + ".png"; - } - return waitAndFindPic(rect, new File(legend, legendName), minSimilar, time, unit); + public ViewRect waitAndFindPic(ViewRect rect, BufferedImage pic, double minSimilar) { + return waitAndFindPic(rect, pic, minSimilar, 10); } /** * 等待并查找图片 * * @param rect 查找区域 - * @param file 图例 + * @param pic 图片 * @param minSimilar 最低相似度 - * @param time 最长等待时间 - * @param unit 最长等待时间单位 + * @param seconds 最长等待秒数 * @return 匹配图片区域 */ - public ViewRect waitAndFindPic(ViewRect rect, File file, double minSimilar, long time, TimeUnit unit) { + public ViewRect waitAndFindPic(ViewRect rect, BufferedImage pic, double minSimilar, long seconds) { + if (rect.getWidth() < pic.getWidth()) { + Logger.error("查找图片区域宽度{}小于图片宽度{}", rect.getWidth(), pic.getWidth()); + return null; + } + if (rect.getHeight() < pic.getHeight()) { + Logger.error("查找图片区域宽度{}小于图片宽度{}", rect.getHeight(), pic.getHeight()); + return null; + } return TaskUtil.timeTask(() -> { - BufferedImage image = ImageUtil.load(file); - if (rect.getWidth() < image.getWidth()) { - Logger.error("查找图片区域宽度{}小于图片宽度{}", rect.getWidth(), image.getWidth()); - return null; - } - if (rect.getHeight() < image.getHeight()) { - Logger.error("查找图片区域宽度{}小于图片宽度{}", rect.getHeight(), image.getHeight()); - return null; - } - - while (true) { + while (JMainService.getInstance().run) { delayUnstable(); - ViewRect pic = findPic(rect, image, minSimilar); - if (pic != null) { - return pic; + ViewRect result = findPic(rect, pic, minSimilar); + if (result != null) { + return result; } } - }, time, unit); + return null; + }, seconds, TimeUnit.SECONDS); } /** - * 等待并匹配图例 + * 匹配图片 * - * @param rect 参照区域 - * @param legendName 图例名称 + * @param pic 图片 + * @param location 定位 * @param minSimilar 最低相似度 - * @return 匹配图片区域 + * @return 匹配图片 */ - public ViewRect waitAndMatchPic(ViewRect rect, String legendName, double minSimilar) { - if (!legendName.endsWith(".png")) { - legendName = legendName + ".png"; + public ViewRect matchPic(File pic, ViewPoint location, double minSimilar) { + if (!pic.exists()) { + Logger.error("file [{}] not exist", pic.getAbsolutePath()); + return null; } - return waitAndMatchPic(rect, new File(legend, legendName), minSimilar, 3, TimeUnit.SECONDS); + return matchPic(ImageUtil.load(pic), location, minSimilar); + } + + public ViewRect matchPic(BufferedImage pic, ViewPoint location, double minSimilar) { + ViewRect focusRect = getFocusRect(); + int offsetX = location.getX(); + int offsetY = location.getY(); + ViewRect viewRect = new ViewRect(); + viewRect.setLeft(focusRect.getLeft() + offsetX); + viewRect.setTop(focusRect.getTop() + offsetY); + viewRect.setRight(viewRect.getLeft() + pic.getWidth()); + viewRect.setBottom(viewRect.getTop() + pic.getHeight()); + ImageUtil.show(viewRect); + return findPic(viewRect, pic, minSimilar); } /** - * 等待并匹配图例 + * 等待并匹配图片 * - * @param rect 参照区域 - * @param file 图例 + * @param pic 图片 * @param minSimilar 最低相似度 * @return 匹配图片区域 */ - public ViewRect waitAndMatchPic(ViewRect rect, File file, double minSimilar) { - return waitAndMatchPic(rect, file, minSimilar, 3, TimeUnit.SECONDS); + public ViewRect waitAndMatchPic(File pic, ViewPoint location, double minSimilar) { + return waitAndMatchPic(ImageUtil.load(pic), location, minSimilar); } /** - * 等待并匹配图例 + * 等待并匹配图片 + * + * @param pic 图片 + * @param minSimilar 最低相似度 + * @return 匹配图片区域 + */ + public ViewRect waitAndMatchPic(BufferedImage pic, ViewPoint location, double minSimilar) { + return waitAndMatchPic(pic, location, minSimilar, 10); + } + + /** + * 等待并匹配图片 * - * @param rect 参照区域 - * @param file 图例 + * @param pic 图片 * @param minSimilar 最低相似度 - * @param time 最长等待时间 - * @param unit 最长等待时间单位 + * @param seconds 最长等待秒数 * @return 匹配图片区域 */ - public ViewRect waitAndMatchPic(ViewRect rect, File file, double minSimilar, long time, TimeUnit unit) { + public ViewRect waitAndMatchPic(File pic, ViewPoint location, double minSimilar, long seconds) { + return waitAndMatchPic(ImageUtil.load(pic), location, minSimilar, seconds); + } + + /** + * 等待并匹配图片 + * + * @param pic 图片 + * @param minSimilar 最低相似度 + * @param seconds 最长等待秒数 + * @return 匹配图片区域 + */ + public ViewRect waitAndMatchPic(BufferedImage pic, ViewPoint location, double minSimilar, long seconds) { return TaskUtil.timeTask(() -> { while (JMainService.getInstance().run) { - ViewRect matchPic = matchPic(rect, file, minSimilar); + ViewRect matchPic = matchPic(pic, location, minSimilar); if (matchPic != null) { return matchPic; } } return null; - }, time, unit); + }, seconds, TimeUnit.SECONDS); + } + + /** + * 匹配图例 + * + * @param legend 图例 + * @param minSimilar 最低相似度 + * @return 匹配图片 + */ + public ViewRect matchLegend(String legend, double minSimilar) { + return matchLegend(Legend.inflate(legend), minSimilar); } /** * 匹配图片 * - * @param rect 程序窗口(参照系) - * @param file 图例 + * @param legend 图例 * @param minSimilar 最低相似度 * @return 匹配图片 */ - public ViewRect matchPic(ViewRect rect, File file, double minSimilar) { + public ViewRect matchLegend(Legend legend, double minSimilar) { if (minSimilar > 1) { throw new RuntimeException("this minSimilar must be less than 1"); } - if (!file.exists()) { - Logger.error("file [{}] not exist", file.getAbsolutePath()); - return null; - } - String name = file.getName(); - int offsetX = 0; - int offsetY = 0; - if (name.matches("[\\S\\s]+_L[0-9]+,[0-9]+\\.png")) { - offsetX = Convert.toInt(ReUtil.get("[\\S\\s]+_L([0-9]+),[0-9]+\\.png", name, 1), 0); - offsetY = Convert.toInt(ReUtil.get("[\\S\\s]+_L[0-9]+,([0-9]+)\\.png", name, 1), 0); - } + int offsetX = legend.getLocation().getX(); + int offsetY = legend.getLocation().getY(); ViewRect viewRect = new ViewRect(); - viewRect.setLeft(rect.getLeft() + offsetX); - viewRect.setTop(rect.getTop() + offsetY); - BufferedImage image = ImageUtil.load(file); + viewRect.setLeft(getFocusRect().getLeft() + offsetX); + viewRect.setTop(getFocusRect().getTop() + offsetY); + BufferedImage image = ImageUtil.load(legend.getFile()); viewRect.setRight(viewRect.getLeft() + image.getWidth()); viewRect.setBottom(viewRect.getTop() + image.getHeight()); - - ViewRect pic = findPic(viewRect, image, minSimilar); ImageUtil.show(viewRect); - return pic; + return findPic(viewRect, image, minSimilar); } /** - * 匹配图片 + * 等待并匹配图例 * - * @param rect 程序窗口(参照系) - * @param legendName 图例名称 + * @param legend 图例 * @param minSimilar 最低相似度 - * @return 匹配图片 + * @return 匹配图片区域 */ - public ViewRect matchPic(ViewRect rect, String legendName, double minSimilar) { - if (!legendName.endsWith(".png")) { - legendName = legendName + ".png"; - } - return matchPic(rect, new File(legend, legendName), minSimilar); + public ViewRect waitAndMatchLegend(String legend, double minSimilar) { + return waitAndMatchLegend(Legend.inflate(legend), minSimilar); } /** - * 是否匹配图片 + * 等待并匹配图例 * - * @param rect 程序窗口(参照系) - * @param file 图例 + * @param legend 图例 * @param minSimilar 最低相似度 - * @return 匹配图片 + * @return 匹配图片区域 */ - public boolean isMatchPic(ViewRect rect, File file, double minSimilar) { - return matchPic(rect, file, minSimilar) != null; + public ViewRect waitAndMatchLegend(Legend legend, double minSimilar) { + return waitAndMatchLegend(legend, minSimilar, 5); } /** - * 是否匹配图片 + * 等待并匹配图例 * - * @param rect 程序窗口(参照系) - * @param legendName 图例名称 + * @param legend 图例 * @param minSimilar 最低相似度 - * @return 匹配图片 + * @param seconds 最长等待秒数 + * @return 匹配图片区域 */ - public boolean isMatchPic(ViewRect rect, String legendName, double minSimilar) { - if (!legendName.endsWith(".png")) { - legendName = legendName + ".png"; - } - return matchPic(rect, new File(legend, legendName), minSimilar) != null; + public ViewRect waitAndMatchLegend(String legend, double minSimilar, long seconds) { + return waitAndMatchLegend(Legend.inflate(legend), minSimilar, seconds); + } + + /** + * 等待并匹配图例 + * + * @param legend 图例 + * @param minSimilar 最低相似度 + * @param seconds 最长等待秒数 + * @return 匹配图片区域 + */ + public ViewRect waitAndMatchLegend(Legend legend, double minSimilar, long seconds) { + return waitAndMatchPic(legend.getFile(), legend.getLocation(), minSimilar, seconds); } -} +} \ No newline at end of file diff --git a/src/main/java/com/example/jmacro/wjdr/JMainApplication.java b/src/main/java/com/example/jmacro/wjdr/JMainApplication.java index 0eaec08..a7ce499 100644 --- a/src/main/java/com/example/jmacro/wjdr/JMainApplication.java +++ b/src/main/java/com/example/jmacro/wjdr/JMainApplication.java @@ -1,15 +1,19 @@ package com.example.jmacro.wjdr; -import com.example.jmacro.wjdr.demo.MacroForWJDR; +import com.example.jmacro.wjdr.base.ViewRect; import com.example.jmacro.wjdr.ui.FXMLUtil; import com.example.jmacro.wjdr.util.Logger; import com.example.jmacro.wjdr.util.ResourceUtil; +import com.melloware.jintellitype.JIntellitype; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.stage.Stage; +import java.awt.event.KeyEvent; +import java.io.File; + /** * UI入口 * @@ -19,6 +23,9 @@ import javafx.stage.Stage; */ public class JMainApplication extends Application { + public static final int F1_SHORTCUT = 1; // 开始快捷键 + public static final int F2_SHORTCUT = 2; // 结束快捷键 + public static Stage primaryStage; public static JMainController mainController; @@ -44,8 +51,35 @@ public class JMainApplication extends Application { // 展示UI stage.show(); JMainApplication.primaryStage = stage; + + JIntellitype.getInstance().registerHotKey(F1_SHORTCUT, 0, KeyEvent.VK_F1); + JIntellitype.getInstance().registerHotKey(F2_SHORTCUT, 0, KeyEvent.VK_F2); + JIntellitype.getInstance().addHotKeyListener(identifier -> { + switch (identifier) { + case F1_SHORTCUT: + mainController.onStart(); + break; + case F2_SHORTCUT: + mainController.onStop(); + break; + } + }); + // 服务初始化 - JMainService.init(new MacroForWJDR()); + JMainService.init(new JMacro() { + @Override + public ViewRect focus() { + return new ViewRect(0, 0, 200, 200); + } + + @Override + public void run() { + ViewRect pic = matchLegend("回收站", 0.9); + if (pic != null) { + mouseLeftDoubleClick(pic); + } + } + }, new File("legend")); } public static void main(String[] args) { diff --git a/src/main/java/com/example/jmacro/wjdr/JMainController.java b/src/main/java/com/example/jmacro/wjdr/JMainController.java index 9f171da..d3ce3b6 100644 --- a/src/main/java/com/example/jmacro/wjdr/JMainController.java +++ b/src/main/java/com/example/jmacro/wjdr/JMainController.java @@ -1,5 +1,6 @@ package com.example.jmacro.wjdr; +import com.example.jmacro.wjdr.base.Legend; import com.example.jmacro.wjdr.base.ViewRect; import com.example.jmacro.wjdr.tool.Capture; import com.example.jmacro.wjdr.tool.Location; @@ -9,7 +10,6 @@ import javafx.scene.control.Button; import javafx.scene.image.ImageView; import java.awt.*; -import java.io.File; /** * UI控制器 @@ -33,15 +33,14 @@ public class JMainController { * 截图 */ @FXML - private void onCapture() { + public void onCapture() { ViewRect screen = JMainService.getInstance().getMacro().getFocusRect(); - File legend = JMainService.getInstance().getMacro().getLegend(); if (screen == null) { DialogUtil.alert("未定位到视口,请稍后再试!"); return; } try { - new Capture(screen.getLeft(), screen.getTop(), legend); + new Capture(screen.getLeft(), screen.getTop(), Legend.getDefaultBase()); } catch (AWTException awtException) { awtException.printStackTrace(); } @@ -51,9 +50,8 @@ public class JMainController { * 截图 */ @FXML - private void onLocation() { + public void onLocation() { ViewRect screen = JMainService.getInstance().getMacro().getFocusRect(); - File legend = JMainService.getInstance().getMacro().getLegend(); if (screen == null) { DialogUtil.alert("未定位到视口,请稍后再试!"); return; @@ -69,7 +67,7 @@ public class JMainController { * 截图 */ @FXML - private void onStart() { + public void onStart() { boolean start = JMainService.start(); this.start.setDisable(start); this.stop.setDisable(!start); @@ -79,7 +77,7 @@ public class JMainController { * 截图 */ @FXML - private void onStop() { + public void onStop() { boolean stop = JMainService.stop(); this.start.setDisable(!stop); this.stop.setDisable(stop); diff --git a/src/main/java/com/example/jmacro/wjdr/JMainService.java b/src/main/java/com/example/jmacro/wjdr/JMainService.java index d25c02a..ad9ea18 100644 --- a/src/main/java/com/example/jmacro/wjdr/JMainService.java +++ b/src/main/java/com/example/jmacro/wjdr/JMainService.java @@ -1,6 +1,7 @@ package com.example.jmacro.wjdr; import cn.hutool.core.thread.ThreadUtil; +import com.example.jmacro.wjdr.base.Legend; import com.example.jmacro.wjdr.demo.MacroForWJDR; import com.example.jmacro.wjdr.util.DialogUtil; import com.example.jmacro.wjdr.util.Logger; @@ -54,8 +55,9 @@ public class JMainService { return macro; } - public static void init(JMacro macro) { + public static void init(JMacro macro, File legendDir) { getInstance().macro = macro; + Legend.setDefaultBase(legendDir); } public void createDaemon() { @@ -99,17 +101,6 @@ public class JMainService { return true; } - /** - * 设置图例路径 - * - * @param legend 图例路径 - */ - public static void setLegend(File legend) { - if (getInstance().macro != null) { - getInstance().macro.setLegend(legend); - } - } - /** * 守护线程 */ @@ -123,9 +114,10 @@ public class JMainService { } while (run) { try { - macro.run(); ThreadUtil.sleep(1000); + macro.run(); } catch (Exception e) { + e.printStackTrace(); Logger.error("异常中断"); } } @@ -137,7 +129,7 @@ public class JMainService { * 服务启动入口 */ public static void main(String[] args) { - JMainService.init(new MacroForWJDR()); + JMainService.init(new MacroForWJDR(), new File("legend")); JMainService.start(); } } diff --git a/src/main/java/com/example/jmacro/wjdr/base/Legend.java b/src/main/java/com/example/jmacro/wjdr/base/Legend.java new file mode 100644 index 0000000..4713378 --- /dev/null +++ b/src/main/java/com/example/jmacro/wjdr/base/Legend.java @@ -0,0 +1,119 @@ +package com.example.jmacro.wjdr.base; + +import cn.hutool.cache.Cache; +import cn.hutool.cache.CacheUtil; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.ReUtil; + +import java.io.File; +import java.util.List; + +/** + * 图例 + *
+ * 图例分带坐标和不带坐标图例 + *
+ * 其中带坐标图例,通过将坐标融合进文件名称实现,定义如下
+ * 以something#L0,0.png为例
+ * 图例名称:something
+ * 图例坐标:#L0,0(在实例化时转为location)
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 1.8
+ */
+public class Legend {
+
+ /**
+ * 默认图例目录
+ */
+ private static File defaultBase = new File("legend");
+
+ /**
+ * 图例缓存
+ */
+ public static Cache