From db389cb76dc46d5e9973892c13fb7b9dfceacac4 Mon Sep 17 00:00:00 2001 From: wangbing Date: Sun, 1 Sep 2024 23:53:43 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E9=87=87=E9=9B=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- legend/城镇_欢迎新成员_L199,773.png | Bin 0 -> 7482 bytes legend/城镇_避难者_L3,174.png | Bin 0 -> 20346 bytes legend/野外_搜索_L226,879.png | Bin 0 -> 3365 bytes legend/野外_搜索_L33,636.png | Bin 444 -> 0 bytes legend/野外_资源_搜索.png | Bin 3929 -> 0 bytes .../java/com/example/jmacro/wjdr/JMacro.java | 117 ++++++++---- .../com/example/jmacro/wjdr/JMacroThread.java | 49 ------ .../example/jmacro/wjdr/JMainApplication.java | 4 +- .../example/jmacro/wjdr/JMainController.java | 23 ++- .../com/example/jmacro/wjdr/JMainService.java | 74 ++++---- .../example/jmacro/wjdr/base/ViewPoint.java | 8 + .../example/jmacro/wjdr/base/ViewRect.java | 2 +- .../{DemoThread.java => MacroForWJDR.java} | 65 +++---- .../jmacro/wjdr/demo/task/BaseTask.java | 18 +- .../wjdr/demo/task/Task_收留避难者.java | 39 ++++ .../wjdr/demo/task/Task_自动采矿.java | 15 +- .../jmacro/wjdr/{util => tool}/Capture.java | 3 +- .../example/jmacro/wjdr/tool/Location.java | 166 ++++++++++++++++++ src/main/resources/main.fxml | 4 + 19 files changed, 424 insertions(+), 163 deletions(-) create mode 100644 legend/城镇_欢迎新成员_L199,773.png create mode 100644 legend/城镇_避难者_L3,174.png create mode 100644 legend/野外_搜索_L226,879.png delete mode 100644 legend/野外_搜索_L33,636.png delete mode 100644 legend/野外_资源_搜索.png delete mode 100644 src/main/java/com/example/jmacro/wjdr/JMacroThread.java rename src/main/java/com/example/jmacro/wjdr/demo/{DemoThread.java => MacroForWJDR.java} (68%) create mode 100644 src/main/java/com/example/jmacro/wjdr/demo/task/Task_收留避难者.java rename src/main/java/com/example/jmacro/wjdr/{util => tool}/Capture.java (98%) create mode 100644 src/main/java/com/example/jmacro/wjdr/tool/Location.java diff --git a/legend/城镇_欢迎新成员_L199,773.png b/legend/城镇_欢迎新成员_L199,773.png new file mode 100644 index 0000000000000000000000000000000000000000..2f7dbf21f4a4631a5292482c9c540d3430483409 GIT binary patch literal 7482 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∓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 literal 0 HcmV?d00001 diff --git a/legend/野外_搜索_L226,879.png b/legend/野外_搜索_L226,879.png new file mode 100644 index 0000000000000000000000000000000000000000..6a2a982e6b9065e0ad8ad6fac046f21d4bb2d3f1 GIT binary patch literal 3365 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 literal 0 HcmV?d00001 diff --git a/legend/野外_搜索_L33,636.png b/legend/野外_搜索_L33,636.png deleted file mode 100644 index beeec4341ad2d4001b5ca516ae469ed911461ee6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 444 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 { + 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) { mouseMove(rect); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - delayTap(); + robot.delay(100); robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); } @@ -159,11 +188,11 @@ public class JMacro { */ public void mouseLeftDrag(ViewPoint start, ViewPoint end, boolean smooth) { mouseMove(start, smooth); - delayTap(); + delayUnstable(); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - delayTap(); + delayUnstable(); mouseMove(end, smooth); - delayTap(); + delayUnstable(); robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); } @@ -186,11 +215,11 @@ public class JMacro { */ public void mouseRightDrag(ViewPoint start, ViewPoint end, boolean smooth) { mouseMove(start, smooth); - delayTap(); + delayUnstable(); robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); - delayTap(); + delayUnstable(); mouseMove(end, smooth); - delayTap(); + delayUnstable(); robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); } @@ -200,11 +229,11 @@ public class JMacro { * @param rect 矩形区域 */ public void mouseWheelClick(ViewRect rect) { - delayTap(); + delayUnstable(); robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]); - delayTap(); + delayUnstable(); robot.mousePress(InputEvent.BUTTON2_DOWN_MASK); - delayTap(); + delayUnstable(); robot.mouseRelease(InputEvent.BUTTON2_DOWN_MASK); } @@ -214,11 +243,11 @@ public class JMacro { * @param rect 矩形区域 */ public void mouseRightClick(ViewRect rect) { - delayTap(); + delayUnstable(); robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]); - delayTap(); + delayUnstable(); robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); - delayTap(); + delayUnstable(); robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); } @@ -228,9 +257,9 @@ public class JMacro { * @param rect 矩形区域 */ public void mouseLeftDoubleClick(ViewRect rect) { - delayTap(); + delayUnstable(); robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]); - delayTap(); + delayUnstable(); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); robot.delay(100); 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())); } + /** + * 获取聚焦区域 + */ + public ViewRect getFocusRect() { + return focusRect; + } + /** * 获取屏幕范围 */ @@ -277,7 +313,7 @@ public class JMacro { * @return 匹配图片区域 */ 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 匹配图片区域 */ 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 匹配图片区域 */ 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()) { Logger.error("视口尺寸小于图片"); @@ -373,22 +413,27 @@ public class JMacro { } public void delay() { - delayNormal(); + delay(100); } - public void delayTap() { - int i = RandomUtil.randomInt(100, 500); - robot.delay(i); + public void delay(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } - public void delayNormal() { - int i = RandomUtil.randomInt(500, 1000); - robot.delay(i); + public void delayUnstable() { + delayUnstable(500); } - public void delayLong() { - int i = RandomUtil.randomInt(1000, 2000); - robot.delay(i); + public void delayUnstable(long millis) { + if (millis < 200) { + delay(millis); + return; + } + delay(RandomUtil.randomLong(millis - 100, millis + 100)); } /** @@ -399,7 +444,7 @@ public class JMacro { * @return 匹配图片区域 */ 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 匹配图片区域 */ 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) { - delayTap(); + delayUnstable(); ViewRect pic = findPic(rect, image, minSimilar); if (pic != null) { return pic; @@ -503,7 +548,7 @@ public class JMacro { if (!legendName.endsWith(".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 匹配图片区域 */ 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) { return TaskUtil.timeTask(() -> { + // TODO: 2024/9/1 因为另起线程,导致发起线程已停止,但此线程未停止 while (true) { ViewRect matchPic = matchPic(rect, file, minSimilar); if (matchPic != null) { @@ -548,6 +594,9 @@ public class JMacro { * @return 匹配图片 */ 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()) { Logger.error("file [{}] not exist", file.getAbsolutePath()); return null; diff --git a/src/main/java/com/example/jmacro/wjdr/JMacroThread.java b/src/main/java/com/example/jmacro/wjdr/JMacroThread.java deleted file mode 100644 index 1433662..0000000 --- a/src/main/java/com/example/jmacro/wjdr/JMacroThread.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.example.jmacro.wjdr; - -import com.example.jmacro.wjdr.base.ViewRect; -import com.example.jmacro.wjdr.util.TaskUtil; - -import java.util.concurrent.Callable; -import java.util.concurrent.TimeUnit; - -/** - * 脚本线程 - * - * @author wangbing - * @version 0.0.1 - * @since 1.8 - */ -public abstract class JMacroThread implements Runnable { - - /** - * 脚本对象 - */ - protected JMacro macro; - - /** - * 视口区域 - */ - protected ViewRect viewRect; - - public JMacroThread(JMacro macro) { - this.macro = macro; - TaskUtil.asyncTask(() -> { - viewRect = TaskUtil.timeTask(this::location, 10, TimeUnit.SECONDS); - }); - } - - /** - * 获取视口区域 - * - * @return 视口区域 - */ - public abstract ViewRect location(); - - public ViewRect getViewRect() { - return viewRect; - } - - public JMacro getMacro() { - return macro; - } -} diff --git a/src/main/java/com/example/jmacro/wjdr/JMainApplication.java b/src/main/java/com/example/jmacro/wjdr/JMainApplication.java index 5158272..909019f 100644 --- a/src/main/java/com/example/jmacro/wjdr/JMainApplication.java +++ b/src/main/java/com/example/jmacro/wjdr/JMainApplication.java @@ -1,6 +1,6 @@ package com.example.jmacro.wjdr; -import com.example.jmacro.wjdr.demo.DemoThread; +import com.example.jmacro.wjdr.demo.MacroForWJDR; import com.example.jmacro.wjdr.ui.FXMLUtil; import com.example.jmacro.wjdr.util.Logger; import com.example.jmacro.wjdr.util.ResourceUtil; @@ -45,7 +45,7 @@ public class JMainApplication extends Application { stage.show(); JMainApplication.primaryStage = stage; // 服务初始化 - JMainService.init(new DemoThread(new JMacro())); + JMainService.init(new MacroForWJDR()); } 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 83436b3..5108a5a 100644 --- a/src/main/java/com/example/jmacro/wjdr/JMainController.java +++ b/src/main/java/com/example/jmacro/wjdr/JMainController.java @@ -1,7 +1,8 @@ package com.example.jmacro.wjdr; import com.example.jmacro.wjdr.base.ViewRect; -import com.example.jmacro.wjdr.util.Capture; +import com.example.jmacro.wjdr.tool.Capture; +import com.example.jmacro.wjdr.tool.Location; import com.example.jmacro.wjdr.util.Dialog; import javafx.fxml.FXML; import javafx.scene.control.Button; @@ -33,7 +34,7 @@ public class JMainController { */ @FXML private void onCapture() { - ViewRect screen = JMainService.getInstance().getMacroThread().getViewRect(); + ViewRect screen = JMainService.getInstance().getMacro().getFocusRect(); File legend = JMainService.getInstance().getMacro().getLegend(); if (screen == null) { Dialog.alert("未定位到视口,请稍后再试!"); @@ -46,6 +47,24 @@ public class JMainController { } } + /** + * 截图 + */ + @FXML + private void onLocation() { + ViewRect screen = JMainService.getInstance().getMacro().getFocusRect(); + File legend = JMainService.getInstance().getMacro().getLegend(); + if (screen == null) { + Dialog.alert("未定位到视口,请稍后再试!"); + return; + } + try { + new Location(screen.getLeft(), screen.getTop()); + } catch (AWTException awtException) { + awtException.printStackTrace(); + } + } + /** * 截图 */ diff --git a/src/main/java/com/example/jmacro/wjdr/JMainService.java b/src/main/java/com/example/jmacro/wjdr/JMainService.java index e7219e8..faade1e 100644 --- a/src/main/java/com/example/jmacro/wjdr/JMainService.java +++ b/src/main/java/com/example/jmacro/wjdr/JMainService.java @@ -1,7 +1,7 @@ package com.example.jmacro.wjdr; import cn.hutool.core.thread.ThreadUtil; -import com.example.jmacro.wjdr.demo.DemoThread; +import com.example.jmacro.wjdr.demo.MacroForWJDR; import com.example.jmacro.wjdr.util.Dialog; import com.example.jmacro.wjdr.util.Logger; @@ -16,11 +16,6 @@ import java.io.File; */ public class JMainService { - /** - * 服务运行状态 - */ - private boolean run; - /** * 单例对象 */ @@ -33,56 +28,61 @@ public class JMainService { return instance; } + /** + * 服务运行状态 + */ + public boolean run; + /** * 守护线程 */ public DaemonThread daemonThread; /** - * 脚本线程 + * 脚本 */ - private JMacroThread macroThread; + private JMacro macro; /** * 服务内部构造器 */ private JMainService() { Logger.info("初始化服务"); - this.daemonThread = new DaemonThread(); - Logger.info("初始化守护线程"); - this.daemonThread.setDaemon(true); } - public void setMacroThread(JMacroThread macroThread) { - this.macroThread = macroThread; + public JMacro getMacro() { + return macro; } - public JMacroThread getMacroThread() { - return macroThread; + public static void init(JMacro macro) { + getInstance().macro = macro; } - public JMacro getMacro() { - return macroThread.getMacro(); - } + public void createDaemon() { + this.daemonThread = new DaemonThread(); + Logger.info("初始化守护线程"); + this.daemonThread.setDaemon(true); - public static void init(JMacroThread macroThread) { - getInstance().macroThread = macroThread; + // 启动守护线程 + this.run = true; + this.daemonThread.start(); } public static boolean start() { - if (JMainService.getInstance().macroThread.getViewRect() == null) { - Dialog.alert("未定位到视口,请稍后再试!"); + if (JMainService.getInstance().macro.getFocusRect() == null) { + JMainService.getInstance().macro.startFocus(); + Dialog.alert("未聚焦到视口,请稍后再试!"); return false; } if (JMainService.getInstance().run) { Logger.error("服务已启动"); return false; } + // 启动服务 Logger.info("启动服务"); - // 启动守护线程 - JMainService.getInstance().run = true; - JMainService.getInstance().daemonThread.start(); + // 创建守护线程 + JMainService.getInstance().createDaemon(); return true; } @@ -105,27 +105,31 @@ public class JMainService { * @param legend 图例路径 */ public static void setLegend(File legend) { - if (getInstance().macroThread != null) { - getInstance().macroThread.getMacro().setLegend(legend); + if (getInstance().macro != null) { + getInstance().macro.setLegend(legend); } } /** * 守护线程 */ - class DaemonThread extends Thread { + private class DaemonThread extends Thread { @Override public void run() { + if (macro == null) { + Logger.error("脚本未设置"); + return; + } while (run) { - Logger.info("守护线程ID={}", Thread.currentThread().getId()); - ThreadUtil.sleep(1000); - if (macroThread == null) { - Logger.error("脚本线程未设置"); - continue; + try { + macro.run(); + ThreadUtil.sleep(1000); + } catch (Exception e) { + Logger.error("异常中断"); } - macroThread.run(); } + Logger.info("服务停止,守护线程已退出"); } } @@ -133,7 +137,7 @@ public class JMainService { * 服务启动入口 */ public static void main(String[] args) { - JMainService.init(new DemoThread(new JMacro())); + JMainService.init(new MacroForWJDR()); JMainService.start(); } } diff --git a/src/main/java/com/example/jmacro/wjdr/base/ViewPoint.java b/src/main/java/com/example/jmacro/wjdr/base/ViewPoint.java index 4b75ea4..67fccef 100644 --- a/src/main/java/com/example/jmacro/wjdr/base/ViewPoint.java +++ b/src/main/java/com/example/jmacro/wjdr/base/ViewPoint.java @@ -42,4 +42,12 @@ public class ViewPoint { public void setY(int y) { this.y = y; } + + @Override + public String toString() { + return "ViewPoint{" + + "x=" + x + + ", y=" + y + + '}'; + } } diff --git a/src/main/java/com/example/jmacro/wjdr/base/ViewRect.java b/src/main/java/com/example/jmacro/wjdr/base/ViewRect.java index caa3cd7..5f18f5b 100644 --- a/src/main/java/com/example/jmacro/wjdr/base/ViewRect.java +++ b/src/main/java/com/example/jmacro/wjdr/base/ViewRect.java @@ -83,7 +83,7 @@ public class ViewRect { @Override public String toString() { - return "ScreenRect{" + + return "ViewRect{" + "left=" + left + ", top=" + top + ", right=" + right + diff --git a/src/main/java/com/example/jmacro/wjdr/demo/DemoThread.java b/src/main/java/com/example/jmacro/wjdr/demo/MacroForWJDR.java similarity index 68% rename from src/main/java/com/example/jmacro/wjdr/demo/DemoThread.java rename to src/main/java/com/example/jmacro/wjdr/demo/MacroForWJDR.java index 955a4d3..c7b8623 100644 --- a/src/main/java/com/example/jmacro/wjdr/demo/DemoThread.java +++ b/src/main/java/com/example/jmacro/wjdr/demo/MacroForWJDR.java @@ -3,25 +3,22 @@ package com.example.jmacro.wjdr.demo; import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUtil; import com.example.jmacro.wjdr.JMacro; -import com.example.jmacro.wjdr.JMacroThread; +import com.example.jmacro.wjdr.JMainService; import com.example.jmacro.wjdr.base.ViewRect; -import com.example.jmacro.wjdr.demo.task.Task_探险领取; -import com.example.jmacro.wjdr.demo.task.Task_离线收益; -import com.example.jmacro.wjdr.demo.task.Task_自动采矿; -import com.example.jmacro.wjdr.demo.task.Task_采矿被攻击; +import com.example.jmacro.wjdr.demo.task.*; import com.example.jmacro.wjdr.util.Logger; import com.example.jmacro.wjdr.util.TaskUtil; import java.util.concurrent.TimeUnit; /** - * 实例工作线程 + * 无尽冬日脚本 * * @author wangbing * @version 0.0.1 * @since 1.8 */ -public class DemoThread extends JMacroThread { +public class MacroForWJDR extends JMacro { /** * 工作开始时间 @@ -38,15 +35,11 @@ public class DemoThread extends JMacroThread { */ private final long workTime = 30 * 60 * 1000; - public DemoThread(JMacro macro) { - super(macro); - } - @Override - public synchronized ViewRect location() { + public synchronized ViewRect focus() { // 定位窗口 Logger.info("定位窗口"); - ViewRect mumu = macro.findPic("慕慕_工具栏", 0.95d); + ViewRect mumu = findPic("慕慕_工具栏", 0.95d); if (mumu == null) { Logger.error("定位窗口失败"); return null; @@ -70,12 +63,12 @@ public class DemoThread extends JMacroThread { Logger.info("任务线程ID={}", Thread.currentThread().getId()); // 获取启动图标 Logger.info("定位启动图标"); - ViewRect launch = macro.waitAndFindPic(viewRect, "启动图标", 0.9, 10, TimeUnit.SECONDS); + ViewRect launch = waitAndFindPic(focusRect, "启动图标", 0.9, 10, TimeUnit.SECONDS); if (launch != null) { Logger.info("启动图标坐标:", launch.toString()); Logger.info("启动程序"); - macro.delay(); - macro.mouseLeftClick(launch); + delay(); + mouseLeftClick(launch); } else { Logger.error("未定位到图标,可能已进入游戏"); Logger.info("继续定位城镇"); @@ -85,31 +78,31 @@ public class DemoThread extends JMacroThread { // 定位城镇 Boolean inMain = TaskUtil.retryTask(() -> { { // 定位弹框,关闭弹框 - ViewRect rect = macro.matchPic(viewRect, "城镇_充值_L448,36", 0.8d); + ViewRect rect = matchPic(focusRect, "城镇_充值_L448,36", 0.8d); if (rect != null) { - macro.mouseLeftClick(rect); + mouseLeftClick(rect); Logger.info("检测到充值广告弹框,关闭弹框"); } } {// 定位离线收益 - ViewRect rect = macro.matchPic(viewRect, "城镇_离线收益_L204,734", 0.9); + ViewRect rect = matchPic(focusRect, "城镇_离线收益_L204,734", 0.9); if (rect != null) { - macro.mouseLeftClick(rect); + mouseLeftClick(rect); Logger.info("检测到离线收益弹框,关闭弹框"); } } // 定位城镇 { - ViewRect rect = macro.matchPic(viewRect, "城镇_L456,887", 0.9); + ViewRect rect = matchPic(focusRect, "城镇_L456,887", 0.9); if (rect != null) { Logger.info("当前区域【野外】"); Logger.info("返回区域【城镇】"); - macro.mouseLeftClick(rect); + mouseLeftClick(rect); return false; } } {// 定位野外 - ViewRect rect = macro.matchPic(viewRect, "野外_L444,888", 0.9); + ViewRect rect = matchPic(focusRect, "野外_L444,888", 0.9); if (rect != null) { Logger.info("当前区域【城镇】"); return true; @@ -126,22 +119,30 @@ public class DemoThread extends JMacroThread { Logger.info("进入城镇成功"); Logger.info("领取探险奖励"); - macro.delay(); - new Task_离线收益(macro, viewRect).run(); + delay(); + new Task_离线收益(this, focusRect).run(); + + Logger.info("收留避难者"); + delay(); + new Task_收留避难者(this, focusRect).run(); Logger.info("启动循环任务"); - while (!Thread.currentThread().isInterrupted()) { + while (JMainService.getInstance().run) { // 矿场攻击检测任务 - macro.delay(); - new Task_采矿被攻击(macro, viewRect).run(); + delayUnstable(1000); + new Task_采矿被攻击(this, focusRect).run(); + + // 避难者 + delayUnstable(1000); + new Task_收留避难者(this, focusRect).run(); // 矿场攻击检测任务 - macro.delay(); - new Task_探险领取(macro, viewRect).run(); + delayUnstable(1000); + new Task_探险领取(this, focusRect).run(); // 自动采矿任务 - macro.delay(); - new Task_自动采矿(macro, viewRect).run(); +// delayUnstable(1000); +// new Task_自动采矿(this, focusRect).run(); } } } diff --git a/src/main/java/com/example/jmacro/wjdr/demo/task/BaseTask.java b/src/main/java/com/example/jmacro/wjdr/demo/task/BaseTask.java index 0e99d29..d16a2bd 100644 --- a/src/main/java/com/example/jmacro/wjdr/demo/task/BaseTask.java +++ b/src/main/java/com/example/jmacro/wjdr/demo/task/BaseTask.java @@ -1,6 +1,7 @@ package com.example.jmacro.wjdr.demo.task; import com.example.jmacro.wjdr.JMacro; +import com.example.jmacro.wjdr.JMainService; import com.example.jmacro.wjdr.base.ViewRect; import com.example.jmacro.wjdr.util.Logger; @@ -25,14 +26,19 @@ public abstract class BaseTask { } public void run() { - Logger.info("守护线程ID={}", Thread.currentThread().getId()); - if (Thread.currentThread().isInterrupted()) { + if (!JMainService.getInstance().run) { + Logger.error("服务中断"); return; } - String name = getClass().getName(); - Logger.info("》》》任务[{}]开始》》》", name); - this.task(macro, viewRect); - Logger.info("》》》任务[{}]结束》》》", name); + String name = getClass().getSimpleName(); + try { + Logger.info("》》》任务[{}]开始》》》", name); + this.task(macro, viewRect); + Logger.info("》》》任务[{}]结束》》》", name); + } catch (Exception e) { + Logger.info("》》》任务[{}]异常中断》》》", name); + throw e; + } } /** diff --git a/src/main/java/com/example/jmacro/wjdr/demo/task/Task_收留避难者.java b/src/main/java/com/example/jmacro/wjdr/demo/task/Task_收留避难者.java new file mode 100644 index 0000000..e305ff3 --- /dev/null +++ b/src/main/java/com/example/jmacro/wjdr/demo/task/Task_收留避难者.java @@ -0,0 +1,39 @@ +package com.example.jmacro.wjdr.demo.task; + +import com.example.jmacro.wjdr.JMacro; +import com.example.jmacro.wjdr.base.ViewRect; +import com.example.jmacro.wjdr.util.Logger; + +public class Task_收留避难者 extends BaseTask { + + public Task_收留避难者(JMacro macro, ViewRect viewRect) { + super(macro, viewRect); + } + + @Override + public void task(JMacro macro, ViewRect viewRect) { + ViewRect rect = macro.waitAndMatchPic(viewRect, "城镇_避难者_L3,174", 0.9); + if (rect == null) { + Logger.info("未发现避难者"); + return; + } + Logger.info("发现避难者"); + + Logger.info("收留避难者"); + macro.mouseLeftClick(rect); + + macro.delayUnstable(); + ViewRect rect1 = macro.waitAndMatchPic(viewRect, "城镇_欢迎新成员_L199,773", 0.9); + if (rect1 == null) { + Logger.info("收留避难者异常"); + return; + } + + macro.delayUnstable(); + Logger.info("欢迎新成员"); + macro.mouseLeftClick(rect1); + + macro.delayUnstable(); + Logger.info("返回城镇"); + } +} diff --git a/src/main/java/com/example/jmacro/wjdr/demo/task/Task_自动采矿.java b/src/main/java/com/example/jmacro/wjdr/demo/task/Task_自动采矿.java index 9a0d47a..b8476c2 100644 --- a/src/main/java/com/example/jmacro/wjdr/demo/task/Task_自动采矿.java +++ b/src/main/java/com/example/jmacro/wjdr/demo/task/Task_自动采矿.java @@ -45,6 +45,18 @@ public class Task_自动采矿 extends BaseTask { Logger.info("定位资源搜索按钮成功:{}", 野外搜索.toString()); macro.mouseLeftClick(野外搜索); + // 定位木材 + + + // 因为搜索按钮透明,不好比对,通过定位其下面的任务图标定位 + ViewRect 野外_搜索 = macro.waitAndMatchPic(this.viewRect, "野外_搜索_L226,879", 0.9); + if (野外_搜索 == null) { + Logger.error("未检测到【野外_搜索】,采矿终止"); + return; + } + + // todo + String[] types = new String[]{ "生肉", "木材", "煤矿", "铁矿" }; @@ -81,6 +93,7 @@ public class Task_自动采矿 extends BaseTask { ViewRect typeRect = macro.waitAndFindPic(viewRect, new File("legend", "野外_" + type + ".png"), 0.9); if (typeRect == null) { Logger.error("定位【{}】图标失败", type); + return false; } Logger.info("定位【{}】图标成功", type); @@ -90,7 +103,7 @@ public class Task_自动采矿 extends BaseTask { if (level == 0) { ViewRect 等级减 = macro.waitAndFindPic(viewRect, new File("legend", "野外_资源_-.png"), 0.98); while (等级减 != null) { - macro.delayTap(); + macro.delayUnstable(); macro.mouseLeftClick(等级减); 等级减 = macro.waitAndFindPic(viewRect, new File("legend", "野外_资源_-.png"), 0.98); } diff --git a/src/main/java/com/example/jmacro/wjdr/util/Capture.java b/src/main/java/com/example/jmacro/wjdr/tool/Capture.java similarity index 98% rename from src/main/java/com/example/jmacro/wjdr/util/Capture.java rename to src/main/java/com/example/jmacro/wjdr/tool/Capture.java index 082d9a0..7af7cbb 100644 --- a/src/main/java/com/example/jmacro/wjdr/util/Capture.java +++ b/src/main/java/com/example/jmacro/wjdr/tool/Capture.java @@ -1,7 +1,8 @@ -package com.example.jmacro.wjdr.util; +package com.example.jmacro.wjdr.tool; import cn.hutool.core.img.ImgUtil; import cn.hutool.log.StaticLog; +import com.example.jmacro.wjdr.util.Logger; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; diff --git a/src/main/java/com/example/jmacro/wjdr/tool/Location.java b/src/main/java/com/example/jmacro/wjdr/tool/Location.java new file mode 100644 index 0000000..9a16d16 --- /dev/null +++ b/src/main/java/com/example/jmacro/wjdr/tool/Location.java @@ -0,0 +1,166 @@ +package com.example.jmacro.wjdr.tool; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.log.StaticLog; +import com.example.jmacro.wjdr.util.Dialog; +import com.example.jmacro.wjdr.util.Logger; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.image.BufferedImage; + +/** + * 采集坐标工具 + * + * @author wangbing + * @version 0.0.1 + * @since 1.8 + */ +public class Location extends JFrame { + + /** + * 参照原点x坐标 + */ + private int originX; + /** + * 参照原点y坐标 + */ + private int originY; + + /** + * x坐标 + */ + private int x; + /** + * y坐标 + */ + private int y; + + /** + * 全屏幕截图 + */ + private BufferedImage capture; + + /** + * 背景蒙层 + */ + private Color mask = new Color(0, 0, 0, 0.2f); + + /** + * 有参照原点的构造器 + * + * @param originX 原点x + * @param originY 原点y + * @throws AWTException + */ + public Location(int originX, int originY) throws AWTException { + this(); + this.originX = originX; + this.originY = originY; + } + + public Location() throws AWTException { + init(); + } + + private void init() throws AWTException { + setExtendedState(Frame.MAXIMIZED_BOTH); + setLocation(0, 0);//位置 + setUndecorated(true); + setAlwaysOnTop(true); + setBackground(mask); + setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); + + // 获取屏幕截图 + Robot robot = new Robot(); + Toolkit tk = Toolkit.getDefaultToolkit(); + capture = robot.createScreenCapture(new Rectangle(0, 0, tk.getScreenSize().width, tk.getScreenSize().height)); + + // 监听窗口关闭 + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + // 关闭应用时要释放资源 + dispose(); + System.exit(0);//0正常退出,1非正常退出 + } + }); + + addMouseListener(new MouseAdapter() { + + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + x = e.getX(); + y = e.getY(); + Logger.info("屏幕坐标:[{},{}]", x, y); + Logger.info("相对坐标:[{},{}]", x - originX, y - originY); + close(); + Dialog.confirm(StrUtil.format("屏幕坐标:[{},{}]\n相对坐标:[{},{}]", x, y, x - originX, y - originY)); + } + }); + + addMouseMotionListener(new MouseMotionAdapter() { + + @Override + public void mouseMoved(MouseEvent e) { + super.mouseMoved(e); + x = e.getX(); + y = e.getY(); + repaint(); + } + }); + + addKeyListener(new KeyAdapter() { + + @Override + public void keyReleased(KeyEvent e) { + switch (e.getKeyCode()) { + case KeyEvent.VK_ESCAPE: { + StaticLog.info("exit."); + close(); + } + break; + } + + } + }); + + setVisible(true); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + Graphics2D g2d = (Graphics2D) g; + g2d.drawImage(capture, 0, 0, capture.getWidth(), capture.getHeight(), this); + + // 在背景图上加个蒙层 + g2d.setColor(mask); + g2d.fillRect(0, 0, capture.getWidth(), capture.getHeight()); + + g2d.setColor(Color.WHITE); + g2d.fillRect(x + 5, y + 5, 120, 35); + + g2d.setColor(Color.DARK_GRAY); + g2d.drawString(StrUtil.format("屏幕坐标[{},{}]", x, y), x + 10, y + 20); + g2d.drawString(StrUtil.format("相对坐标[{},{}]", x - originX, y - originY), x + 10, y + 35); + } + + public void close() { + setVisible(false); + dispose(); + } + + /** + * 工具入口 + * + * @param args + * @throws AWTException + */ + public static void main(String[] args) throws AWTException { + // 运行坐标图例截图工具 + new Location(5, 5); + } +} diff --git a/src/main/resources/main.fxml b/src/main/resources/main.fxml index 2fd1206..8077d1b 100644 --- a/src/main/resources/main.fxml +++ b/src/main/resources/main.fxml @@ -36,6 +36,10 @@