diff --git a/src/main/java/com/example/jmacro/wjdr/JMacro.java b/src/main/java/com/example/jmacro/wjdr/JMacro.java index a562dec..ebe7b3f 100644 --- a/src/main/java/com/example/jmacro/wjdr/JMacro.java +++ b/src/main/java/com/example/jmacro/wjdr/JMacro.java @@ -3,10 +3,10 @@ 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.ScreenPoint; -import com.example.jmacro.wjdr.base.ScreenRect; +import com.example.jmacro.wjdr.base.ViewPoint; +import com.example.jmacro.wjdr.base.ViewRect; import com.example.jmacro.wjdr.util.ColorUtil; -import com.example.jmacro.wjdr.util.Imager; +import com.example.jmacro.wjdr.util.ImageUtil; import com.example.jmacro.wjdr.util.Logger; import com.example.jmacro.wjdr.util.TaskUtil; @@ -17,7 +17,7 @@ import java.io.File; import java.util.concurrent.TimeUnit; /** - * Java脚本精灵 + * 脚本 * * @author wangbing * @version 0.0.1 @@ -35,11 +35,15 @@ public class JMacro { */ private File legend; - public JMacro() throws AWTException { - // 机器人初始化 - this.robot = new Robot(); - this.robot.setAutoDelay(100); - this.legend = new File("legend"); + public JMacro() { + try { + // 机器人初始化 + this.robot = new Robot(); + this.robot.setAutoDelay(100); + this.legend = new File("legend"); + } catch (AWTException e) { + throw new RuntimeException(e); + } } public JMacro(File legend) throws AWTException { @@ -77,7 +81,7 @@ public class JMacro { * * @param point 坐标点 */ - public void mouseMove(ScreenPoint point) { + public void mouseMove(ViewPoint point) { mouseMove(point, false); } @@ -87,7 +91,7 @@ public class JMacro { * @param point 坐标点 * @param smooth 平滑移动 */ - public void mouseMove(ScreenPoint point, boolean smooth) { + public void mouseMove(ViewPoint point, boolean smooth) { if (smooth) { // 获取当前鼠标位置 Point mousePoint = MouseInfo.getPointerInfo().getLocation(); @@ -120,7 +124,7 @@ public class JMacro { * * @param rect 点 */ - public void mouseLeftClick(ScreenPoint rect) { + public void mouseLeftClick(ViewPoint rect) { mouseMove(rect); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); delayTap(); @@ -132,8 +136,8 @@ public class JMacro { * * @param rect 矩形区域 */ - public void mouseLeftClick(ScreenRect rect) { - mouseLeftClick(new ScreenPoint(rect.getCenter()[0], rect.getCenter()[1])); + public void mouseLeftClick(ViewRect rect) { + mouseLeftClick(new ViewPoint(rect.getCenter()[0], rect.getCenter()[1])); } /** @@ -142,7 +146,7 @@ public class JMacro { * @param start 开始位置 * @param end 结束位置 */ - public void mouseLeftDrag(ScreenPoint start, ScreenPoint end) { + public void mouseLeftDrag(ViewPoint start, ViewPoint end) { mouseLeftDrag(start, end, false); } @@ -153,7 +157,7 @@ public class JMacro { * @param end 结束位置 * @param smooth 平滑移动 */ - public void mouseLeftDrag(ScreenPoint start, ScreenPoint end, boolean smooth) { + public void mouseLeftDrag(ViewPoint start, ViewPoint end, boolean smooth) { mouseMove(start, smooth); delayTap(); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); @@ -169,7 +173,7 @@ public class JMacro { * @param start 开始位置 * @param end 结束位置 */ - public void mouseRightDrag(ScreenPoint start, ScreenPoint end) { + public void mouseRightDrag(ViewPoint start, ViewPoint end) { mouseRightDrag(start, end, false); } @@ -180,7 +184,7 @@ public class JMacro { * @param end 结束位置 * @param smooth 平滑移动 */ - public void mouseRightDrag(ScreenPoint start, ScreenPoint end, boolean smooth) { + public void mouseRightDrag(ViewPoint start, ViewPoint end, boolean smooth) { mouseMove(start, smooth); delayTap(); robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); @@ -195,7 +199,7 @@ public class JMacro { * * @param rect 矩形区域 */ - public void mouseWheelClick(ScreenRect rect) { + public void mouseWheelClick(ViewRect rect) { delayTap(); robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]); delayTap(); @@ -209,7 +213,7 @@ public class JMacro { * * @param rect 矩形区域 */ - public void mouseRightClick(ScreenRect rect) { + public void mouseRightClick(ViewRect rect) { delayTap(); robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]); delayTap(); @@ -223,7 +227,7 @@ public class JMacro { * * @param rect 矩形区域 */ - public void mouseLeftDoubleClick(ScreenRect rect) { + public void mouseLeftDoubleClick(ViewRect rect) { delayTap(); robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]); delayTap(); @@ -239,16 +243,16 @@ public class JMacro { /** * 捕获指定区域屏幕 */ - public BufferedImage capture(Robot robot, ScreenRect screenRect) { - return robot.createScreenCapture(new Rectangle(screenRect.getLeft(), screenRect.getTop(), screenRect.getWidth(), screenRect.getHeight())); + public BufferedImage capture(Robot robot, ViewRect viewRect) { + return robot.createScreenCapture(new Rectangle(viewRect.getLeft(), viewRect.getTop(), viewRect.getWidth(), viewRect.getHeight())); } /** * 获取屏幕范围 */ - public ScreenRect getScreenRect() { + public ViewRect getScreenRect() { Toolkit tk = Toolkit.getDefaultToolkit(); - return new ScreenRect(0, 0, tk.getScreenSize().width, tk.getScreenSize().height); + return new ViewRect(0, 0, tk.getScreenSize().width, tk.getScreenSize().height); } /** @@ -258,7 +262,7 @@ public class JMacro { * @param minSimilar 最低相似度 * @return 匹配图片区域 */ - public ScreenRect findPic(String legendName, double minSimilar) { + public ViewRect findPic(String legendName, double minSimilar) { if (!legendName.endsWith(".png")) { legendName = legendName + ".png"; } @@ -272,8 +276,8 @@ public class JMacro { * @param minSimilar 最低相似度 * @return 匹配图片区域 */ - public ScreenRect findPic(File pic, double minSimilar) { - return findPic(getScreenRect(), Imager.load(pic), minSimilar); + public ViewRect findPic(File pic, double minSimilar) { + return findPic(getScreenRect(), ImageUtil.load(pic), minSimilar); } /** @@ -283,65 +287,65 @@ public class JMacro { * @param minSimilar 最低相似度 * @return 匹配图片区域 */ - public ScreenRect findPic(BufferedImage pic, double minSimilar) { + public ViewRect findPic(BufferedImage pic, double minSimilar) { return findPic(getScreenRect(), pic, minSimilar); } /** * 应用视口查找图例 * - * @param screenRect 应用视口 + * @param viewRect 应用视口 * @param legendName 图例名称 * @param minSimilar 最低相似度 * @return 匹配图片区域 */ - public ScreenRect findPic(ScreenRect screenRect, String legendName, double minSimilar) { + public ViewRect findPic(ViewRect viewRect, String legendName, double minSimilar) { if (!legendName.endsWith(".png")) { legendName = legendName + ".png"; } - return findPic(screenRect, new File(legend, legendName), minSimilar); + return findPic(viewRect, new File(legend, legendName), minSimilar); } /** * 应用视口查找图例 * - * @param screenRect 应用视口 + * @param viewRect 应用视口 * @param legend 图例文件 * @param minSimilar 最低相似度 * @return 匹配图片区域 */ - public ScreenRect findPic(ScreenRect screenRect, File legend, double minSimilar) { - return findPic(screenRect, Imager.load(legend), minSimilar); + public ViewRect findPic(ViewRect viewRect, File legend, double minSimilar) { + return findPic(viewRect, ImageUtil.load(legend), minSimilar); } /** * 获取定位 * * @param pic 参考图 - * @param screenRect 查找范围 + * @param viewRect 查找范围 * @param minSimilar 相似度 * @return 匹配图片区域 */ - public ScreenRect findPic(ScreenRect screenRect, BufferedImage pic, double minSimilar) { + public ViewRect findPic(ViewRect viewRect, BufferedImage pic, double minSimilar) { // 当查找区域比图片还小时,直接返回失败 - if (screenRect.getWidth() < pic.getWidth() || screenRect.getHeight() < pic.getHeight()) { + if (viewRect.getWidth() < pic.getWidth() || viewRect.getHeight() < pic.getHeight()) { Logger.error("视口尺寸小于图片"); return null; } // 获取实时屏幕 - BufferedImage screen = capture(robot, screenRect); - int[][] screenData = Imager.getImageRGB(screen); - int[][] picData = Imager.getImageRGB(pic); + BufferedImage screen = capture(robot, viewRect); + int[][] screenData = ImageUtil.getImageRGB(screen); + int[][] picData = ImageUtil.getImageRGB(pic); // 得到图片左上角范围 - int xMin = screenRect.getLeft(); + int xMin = viewRect.getLeft(); // 因为坐标取像素点是从0开始,因此需要-1 - int xMax = screenRect.getRight() - pic.getWidth(); - int yMin = screenRect.getTop(); + int xMax = viewRect.getRight() - pic.getWidth(); + int yMin = viewRect.getTop(); // 因为坐标取像素点是从0开始,因此需要-1 - int yMax = screenRect.getBottom() - pic.getHeight(); + int yMax = viewRect.getBottom() - pic.getHeight(); for (int y = yMin; y <= yMax; y++) { for (int x = xMin; x <= xMax; x++) { @@ -358,9 +362,9 @@ public class JMacro { boolean cc = ColorUtil.isSimilar(screenData[x - xMin + pic.getWidth() / 2][y - yMin + pic.getHeight() / 2], picData[pic.getWidth() / 2][pic.getHeight() / 2]); if (lt && rt && lb && rb && cc) { // 进行全像素匹配 - double similar = Imager.calcSimilar(x - xMin, y - yMin, pic.getHeight(), pic.getWidth(), screenData, picData); + double similar = ImageUtil.calcSimilar(x - xMin, y - yMin, pic.getHeight(), pic.getWidth(), screenData, picData); if (similar >= minSimilar) { - return new ScreenRect(x, y, x + pic.getWidth(), y + pic.getHeight(), similar); + return new ViewRect(x, y, x + pic.getWidth(), y + pic.getHeight(), similar); } } } @@ -377,19 +381,18 @@ public class JMacro { delayNormal(); } - public void delayTap() { int i = RandomUtil.randomInt(100, 500); robot.delay(i); } public void delayNormal() { - int i = RandomUtil.randomInt(500, 1500); + int i = RandomUtil.randomInt(500, 1000); robot.delay(i); } public void delayLong() { - int i = RandomUtil.randomInt(1500, 3000); + int i = RandomUtil.randomInt(1000, 2000); robot.delay(i); } @@ -400,7 +403,7 @@ public class JMacro { * @param minSimilar 最低相似度 * @return 匹配图片区域 */ - public ScreenRect waitAndFindPic(File file, double minSimilar) { + public ViewRect waitAndFindPic(File file, double minSimilar) { return waitAndFindPic(getScreenRect(), file, minSimilar, 10, TimeUnit.SECONDS); } @@ -412,7 +415,7 @@ public class JMacro { * @param minSimilar 最低相似度 * @return 匹配图片区域 */ - public ScreenRect waitAndFindPic(ScreenRect rect, File file, double minSimilar) { + public ViewRect waitAndFindPic(ViewRect rect, File file, double minSimilar) { return waitAndFindPic(rect, file, minSimilar, 10, TimeUnit.SECONDS); } @@ -424,7 +427,7 @@ public class JMacro { * @param minSimilar 最低相似度 * @return 匹配图片区域 */ - public ScreenRect waitAndFindPic(ScreenRect rect, String legendName, double minSimilar) { + public ViewRect waitAndFindPic(ViewRect rect, String legendName, double minSimilar) { if (!legendName.endsWith(".png")) { legendName = legendName + ".png"; } @@ -440,7 +443,7 @@ public class JMacro { * @param unit 最长等待时间单位 * @return 匹配图片区域 */ - public ScreenRect 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); } @@ -454,7 +457,7 @@ public class JMacro { * @param unit 最长等待时间单位 * @return 匹配图片区域 */ - public ScreenRect waitAndFindPic(ScreenRect rect, String legendName, double minSimilar, long time, TimeUnit unit) { + public ViewRect waitAndFindPic(ViewRect rect, String legendName, double minSimilar, long time, TimeUnit unit) { if (!legendName.endsWith(".png")) { legendName = legendName + ".png"; } @@ -471,9 +474,9 @@ public class JMacro { * @param unit 最长等待时间单位 * @return 匹配图片区域 */ - public ScreenRect waitAndFindPic(ScreenRect rect, File file, double minSimilar, long time, TimeUnit unit) { + public ViewRect waitAndFindPic(ViewRect rect, File file, double minSimilar, long time, TimeUnit unit) { return TaskUtil.timeTask(() -> { - BufferedImage image = Imager.load(file); + BufferedImage image = ImageUtil.load(file); if (rect.getWidth() < image.getWidth()) { Logger.error("查找图片区域宽度{}小于图片宽度{}", rect.getWidth(), image.getWidth()); return null; @@ -485,7 +488,7 @@ public class JMacro { while (true) { delayTap(); - ScreenRect pic = findPic(rect, image, minSimilar); + ViewRect pic = findPic(rect, image, minSimilar); if (pic != null) { return pic; } @@ -501,7 +504,7 @@ public class JMacro { * @param minSimilar 最低相似度 * @return 匹配图片区域 */ - public ScreenRect waitAndMatchPic(ScreenRect rect, String legendName, double minSimilar) { + public ViewRect waitAndMatchPic(ViewRect rect, String legendName, double minSimilar) { if (!legendName.endsWith(".png")) { legendName = legendName + ".png"; } @@ -516,7 +519,7 @@ public class JMacro { * @param minSimilar 最低相似度 * @return 匹配图片区域 */ - public ScreenRect waitAndMatchPic(ScreenRect rect, File file, double minSimilar) { + public ViewRect waitAndMatchPic(ViewRect rect, File file, double minSimilar) { return waitAndMatchPic(rect, file, minSimilar, 10, TimeUnit.SECONDS); } @@ -530,11 +533,11 @@ public class JMacro { * @param unit 最长等待时间单位 * @return 匹配图片区域 */ - public ScreenRect waitAndMatchPic(ScreenRect 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(() -> { while (true) { delayTap(); - ScreenRect matchPic = matchPic(rect, file, minSimilar); + ViewRect matchPic = matchPic(rect, file, minSimilar); if (matchPic != null) { return matchPic; } @@ -550,7 +553,7 @@ public class JMacro { * @param minSimilar 最低相似度 * @return 匹配图片 */ - public ScreenRect matchPic(ScreenRect rect, File file, double minSimilar) { + public ViewRect matchPic(ViewRect rect, File file, double minSimilar) { if (!file.exists()) { Logger.error("file [{}] not exist", file.getAbsolutePath()); return null; @@ -562,13 +565,13 @@ public class JMacro { 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); } - ScreenRect screenRect = new ScreenRect(); - screenRect.setLeft(rect.getLeft() + offsetX); - screenRect.setTop(rect.getTop() + offsetY); - BufferedImage image = Imager.load(file); - screenRect.setRight(screenRect.getLeft() + image.getWidth()); - screenRect.setBottom(screenRect.getTop() + image.getHeight()); - return findPic(screenRect, image, minSimilar); + ViewRect viewRect = new ViewRect(); + viewRect.setLeft(rect.getLeft() + offsetX); + viewRect.setTop(rect.getTop() + offsetY); + BufferedImage image = ImageUtil.load(file); + viewRect.setRight(viewRect.getLeft() + image.getWidth()); + viewRect.setBottom(viewRect.getTop() + image.getHeight()); + return findPic(viewRect, image, minSimilar); } /** @@ -579,7 +582,7 @@ public class JMacro { * @param minSimilar 最低相似度 * @return 匹配图片 */ - public ScreenRect matchPic(ScreenRect rect, String legendName, double minSimilar) { + public ViewRect matchPic(ViewRect rect, String legendName, double minSimilar) { if (!legendName.endsWith(".png")) { legendName = legendName + ".png"; } @@ -594,7 +597,7 @@ public class JMacro { * @param minSimilar 最低相似度 * @return 匹配图片 */ - public boolean isMatchPic(ScreenRect rect, File file, double minSimilar) { + public boolean isMatchPic(ViewRect rect, File file, double minSimilar) { return matchPic(rect, file, minSimilar) != null; } @@ -606,7 +609,7 @@ public class JMacro { * @param minSimilar 最低相似度 * @return 匹配图片 */ - public boolean isMatchPic(ScreenRect rect, String legendName, double minSimilar) { + public boolean isMatchPic(ViewRect rect, String legendName, double minSimilar) { if (!legendName.endsWith(".png")) { legendName = legendName + ".png"; } diff --git a/src/main/java/com/example/jmacro/wjdr/JMacroThread.java b/src/main/java/com/example/jmacro/wjdr/JMacroThread.java index 8936402..1433662 100644 --- a/src/main/java/com/example/jmacro/wjdr/JMacroThread.java +++ b/src/main/java/com/example/jmacro/wjdr/JMacroThread.java @@ -1,9 +1,13 @@ package com.example.jmacro.wjdr; -import com.example.jmacro.wjdr.base.ScreenRect; +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 @@ -11,15 +15,21 @@ import com.example.jmacro.wjdr.base.ScreenRect; */ public abstract class JMacroThread implements Runnable { - protected JMacro jMacro; - protected ScreenRect screenRect; + /** + * 脚本对象 + */ + protected JMacro macro; + + /** + * 视口区域 + */ + protected ViewRect viewRect; - public JMacroThread(JMacro jMacro) { - this.jMacro = jMacro; - this.screenRect = location(); - if (this.screenRect == null) { - throw new RuntimeException("未定位到视口区域"); - } + public JMacroThread(JMacro macro) { + this.macro = macro; + TaskUtil.asyncTask(() -> { + viewRect = TaskUtil.timeTask(this::location, 10, TimeUnit.SECONDS); + }); } /** @@ -27,13 +37,13 @@ public abstract class JMacroThread implements Runnable { * * @return 视口区域 */ - public abstract ScreenRect location(); + public abstract ViewRect location(); - public ScreenRect getScreenRect() { - return screenRect; + public ViewRect getViewRect() { + return viewRect; } public JMacro getMacro() { - return jMacro; + 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 f7e9ded..728396a 100644 --- a/src/main/java/com/example/jmacro/wjdr/JMainApplication.java +++ b/src/main/java/com/example/jmacro/wjdr/JMainApplication.java @@ -1,5 +1,6 @@ package com.example.jmacro.wjdr; +import com.example.jmacro.wjdr.demo.DemoThread; import com.example.jmacro.wjdr.ui.FXMLUtil; import com.example.jmacro.wjdr.util.ResourceUtil; import javafx.application.Application; @@ -10,9 +11,15 @@ import javafx.stage.Stage; /** * UI入口 + * + * @author wangbing + * @version 0.0.1 + * @since 1.8 */ public class JMainApplication extends Application { + public static Stage primaryStage; + @Override public void start(Stage stage) throws Exception { stage.setTitle("无限工具"); @@ -31,8 +38,9 @@ public class JMainApplication extends Application { stage.getIcons().add(icon); // 展示UI stage.show(); + JMainApplication.primaryStage = stage; // 服务初始化 - JMainService.init(); + JMainService.init(new DemoThread(new JMacro())); } 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 73409c3..334122f 100644 --- a/src/main/java/com/example/jmacro/wjdr/JMainController.java +++ b/src/main/java/com/example/jmacro/wjdr/JMainController.java @@ -1,24 +1,39 @@ package com.example.jmacro.wjdr; -import com.example.jmacro.wjdr.base.ScreenRect; +import com.example.jmacro.wjdr.base.ViewRect; import com.example.jmacro.wjdr.util.Capture; -import com.example.jmacro.wjdr.util.Logger; +import com.example.jmacro.wjdr.util.Dialog; import javafx.fxml.FXML; +import javafx.scene.control.Button; import java.awt.*; import java.io.File; +/** + * UI控制器 + * + * @author wangbing + * @version 0.0.1 + * @since 1.8 + */ public class JMainController { + @FXML + private Button start; + @FXML + private Button stop; + @FXML + private Button capture; + /** * 截图 */ @FXML - private void onCapture() throws AWTException { - ScreenRect screen = JMainService.getInstance().getThread().getScreenRect(); + private void onCapture() { + ViewRect screen = JMainService.getInstance().getMacroThread().getViewRect(); File legend = JMainService.getInstance().getMacro().getLegend(); if (screen == null) { - Logger.error("请等待窗口定位"); + Dialog.alert("未定位到视口,请稍后再试!"); return; } try { @@ -32,15 +47,19 @@ public class JMainController { * 截图 */ @FXML - private void onStart() throws AWTException { - JMainService.start(); + private void onStart() { + boolean start = JMainService.start(); + this.start.setDisable(start); + this.stop.setDisable(!start); } /** * 截图 */ @FXML - private void onStop() throws AWTException { - JMainService.stop(); + private 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 76bd530..2da88a9 100644 --- a/src/main/java/com/example/jmacro/wjdr/JMainService.java +++ b/src/main/java/com/example/jmacro/wjdr/JMainService.java @@ -2,13 +2,13 @@ package com.example.jmacro.wjdr; import cn.hutool.core.thread.ThreadUtil; import com.example.jmacro.wjdr.demo.DemoThread; +import com.example.jmacro.wjdr.util.Dialog; import com.example.jmacro.wjdr.util.Logger; -import java.awt.*; import java.io.File; /** - * 主线程 + * 服务线程 * * @author wangbing * @version 0.0.1 @@ -16,66 +16,87 @@ import java.io.File; */ public class JMainService { - private static JMainService instance; - - private JMacroThread thread; + /** + * 服务运行状态 + */ + private boolean run; - private JMainService() throws AWTException { - // 脚本初始化 - Logger.info("初始化脚本"); - jMacro = new JMacro(); - thread = new DemoThread(jMacro); - } + /** + * 单例对象 + */ + private static JMainService instance; - public static synchronized JMainService getInstance() throws AWTException { + public static synchronized JMainService getInstance() { if (instance == null) { JMainService.instance = new JMainService(); } return instance; } - public JMacroThread getThread() { - return thread; - } - - public JMacro getMacro() { - return jMacro; - } + /** + * 守护线程 + */ + public DaemonThread daemonThread; /** - * 脚本对象 + * 脚本线程 */ - private final JMacro jMacro; + private JMacroThread macroThread; /** - * 服务运行状态 + * 服务内部构造器 */ - private boolean run; + private JMainService() { + Logger.info("初始化服务"); + this.daemonThread = new DaemonThread(); + Logger.info("初始化守护线程"); + this.daemonThread.setDaemon(true); + } - public static void init() { + public void setMacroThread(JMacroThread macroThread) { + this.macroThread = macroThread; + } + public JMacroThread getMacroThread() { + return macroThread; } - public static void start() throws AWTException { + public JMacro getMacro() { + return macroThread.getMacro(); + } + + public static void init(JMacroThread macroThread) { + getInstance().macroThread = macroThread; + } + + public static boolean start() { + if (JMainService.getInstance().macroThread.getViewRect() == null) { + Dialog.alert("未定位到视口,请稍后再试!"); + return false; + } if (JMainService.getInstance().run) { Logger.error("服务已启动"); - return; + return false; } // 启动服务 Logger.info("启动服务"); + // 启动守护线程 JMainService.getInstance().run = true; - // 启动后台线程 - JMainService.getInstance().serviceThread.start(); + JMainService.getInstance().daemonThread.start(); + return true; } - public static void stop() throws AWTException { + public static boolean stop() { if (!JMainService.getInstance().run) { Logger.error("服务未启动"); - return; + return false; } + // 停止服务 Logger.info("停止服务"); + // 关闭守护线程 JMainService.getInstance().run = false; - JMainService.getInstance().serviceThread.interrupt(); + JMainService.getInstance().daemonThread.interrupt(); + return true; } /** @@ -83,54 +104,35 @@ public class JMainService { * * @param legend 图例路径 */ - public void setLegend(File legend) { - if (this.jMacro != null) { - this.jMacro.setLegend(legend); + public static void setLegend(File legend) { + if (getInstance().macroThread != null) { + getInstance().macroThread.getMacro().setLegend(legend); } } /** - * 服务线程 + * 守护线程 */ - public Thread serviceThread = new Thread() { + class DaemonThread extends Thread { @Override public void run() { while (run) { ThreadUtil.sleep(1000); - if (thread == null) { + if (macroThread == null) { Logger.error("脚本线程未设置"); continue; } - thread.run(); - // 立即执行 -// if (noDelay) { -// if (schedule != null) { -// schedule.cancel(true); -// } -// -// noDelay = false; -// Logger.info("启动线程"); -// schedule = TaskUtil.schedule(new MacroThread(jMacro), 0, TimeUnit.SECONDS); -// continue; -// } -// if (schedule != null) { -// continue; -// } -// -// if (DateUtil.isIn(DateUtil.date(), DateUtil.parse(workStart), DateUtil.parse(workEnd))) { -// int delay = RandomUtil.randomInt(5, 20); -// Logger.info("等待{}分钟后,重新启动线程", delay); -// schedule = TaskUtil.schedule(new MacroThread(jMacro), delay, TimeUnit.MINUTES); -// } + macroThread.run(); } } - }; + } /** - * 启动入口 + * 服务启动入口 */ - public static void main(String[] args) throws AWTException { - new JMainService().start(); + public static void main(String[] args) { + JMainService.init(new DemoThread(new JMacro())); + JMainService.start(); } } diff --git a/src/main/java/com/example/jmacro/wjdr/base/ScreenPoint.java b/src/main/java/com/example/jmacro/wjdr/base/ViewPoint.java similarity index 56% rename from src/main/java/com/example/jmacro/wjdr/base/ScreenPoint.java rename to src/main/java/com/example/jmacro/wjdr/base/ViewPoint.java index df67a62..4b75ea4 100644 --- a/src/main/java/com/example/jmacro/wjdr/base/ScreenPoint.java +++ b/src/main/java/com/example/jmacro/wjdr/base/ViewPoint.java @@ -1,17 +1,28 @@ package com.example.jmacro.wjdr.base; /** - * 屏幕点 + * 可视坐标点 + * + * @author wangbing + * @version 0.0.1 + * @since 1.8 */ -public class ScreenPoint { +public class ViewPoint { + /** + * 相对原点(左上)的x轴距离 + */ private int x; + /** + * 相对原点(左上)的y轴距离 + */ private int y; - public ScreenPoint() { + private ViewPoint() { + } - public ScreenPoint(int x, int y) { + public ViewPoint(int x, int y) { this.x = x; this.y = y; } diff --git a/src/main/java/com/example/jmacro/wjdr/base/ScreenRect.java b/src/main/java/com/example/jmacro/wjdr/base/ViewRect.java similarity index 84% rename from src/main/java/com/example/jmacro/wjdr/base/ScreenRect.java rename to src/main/java/com/example/jmacro/wjdr/base/ViewRect.java index 89309cd..caa3cd7 100644 --- a/src/main/java/com/example/jmacro/wjdr/base/ScreenRect.java +++ b/src/main/java/com/example/jmacro/wjdr/base/ViewRect.java @@ -1,9 +1,13 @@ package com.example.jmacro.wjdr.base; /** - * 屏幕区域 + * 视口区域 + * + * @author wangbing + * @version 0.0.1 + * @since 1.8 */ -public class ScreenRect { +public class ViewRect { private int left; private int top; @@ -15,17 +19,17 @@ public class ScreenRect { */ private double similar; - public ScreenRect() { + public ViewRect() { } - public ScreenRect(int left, int top, int right, int bottom) { + public ViewRect(int left, int top, int right, int bottom) { this.left = left; this.top = top; this.right = right; this.bottom = bottom; } - public ScreenRect(int left, int top, int right, int bottom, double similar) { + public ViewRect(int left, int top, int right, int bottom, double similar) { this.left = left; this.top = top; this.right = right; diff --git a/src/main/java/com/example/jmacro/wjdr/demo/DemoThread.java b/src/main/java/com/example/jmacro/wjdr/demo/DemoThread.java index 1c9c835..c4d3e58 100644 --- a/src/main/java/com/example/jmacro/wjdr/demo/DemoThread.java +++ b/src/main/java/com/example/jmacro/wjdr/demo/DemoThread.java @@ -2,7 +2,7 @@ package com.example.jmacro.wjdr.demo; import com.example.jmacro.wjdr.JMacro; import com.example.jmacro.wjdr.JMacroThread; -import com.example.jmacro.wjdr.base.ScreenRect; +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_自动采矿; @@ -10,16 +10,17 @@ import com.example.jmacro.wjdr.demo.task.Task_采矿被攻击; import com.example.jmacro.wjdr.util.Logger; import com.example.jmacro.wjdr.util.TaskUtil; -import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +/** + * 实例工作线程 + * + * @author wangbing + * @version 0.0.1 + * @since 1.8 + */ public class DemoThread extends JMacroThread { - /** - * 脚本线程 - */ - private static ScheduledFuture schedule; - /** * 工作开始时间 */ @@ -30,27 +31,22 @@ public class DemoThread extends JMacroThread { */ private final String workEnd = "24:00:00"; - /** - * 是否立即执行 - */ - private boolean noDelay = true; - - public DemoThread(JMacro jMacro) { - super(jMacro); + public DemoThread(JMacro macro) { + super(macro); } @Override - public synchronized ScreenRect location() { + public synchronized ViewRect location() { // 定位窗口 Logger.info("定位窗口"); - ScreenRect mumu = jMacro.findPic("慕慕_工具栏", 0.95d); + ViewRect mumu = macro.findPic("慕慕_工具栏", 0.95d); if (mumu == null) { Logger.error("定位窗口失败"); return null; } Logger.info("定位慕慕窗口成功"); // 计算应用窗口返回 - ScreenRect gameScreen = new ScreenRect(); + ViewRect gameScreen = new ViewRect(); gameScreen.setLeft(mumu.getLeft() - 428); gameScreen.setTop(mumu.getBottom() + 7); gameScreen.setRight(mumu.getRight()); @@ -64,37 +60,37 @@ public class DemoThread extends JMacroThread { public void run() { // 获取启动图标 Logger.info("定位启动图标"); - ScreenRect launch = jMacro.waitAndFindPic(screenRect, "启动图标", 0.9, 5, TimeUnit.SECONDS); + ViewRect launch = macro.waitAndFindPic(viewRect, "启动图标", 0.9, 5, TimeUnit.SECONDS); if (launch != null) { Logger.info("启动图标坐标:", launch.toString()); Logger.info("启动程序"); - jMacro.delay(); - jMacro.mouseLeftClick(launch); + macro.delay(); + macro.mouseLeftClick(launch); } else { Logger.info("启动图标失败,继续定位主界面"); } Logger.info("定位主界面"); - ScreenRect 城镇 = TaskUtil.timeTask(() -> { + ViewRect 城镇 = TaskUtil.timeTask(() -> { while (true) { - jMacro.delay(); + macro.delay(); { // 定位弹框,关闭弹框 - ScreenRect rect = jMacro.matchPic(screenRect, "城镇_充值_L448,36", 0.8d); + ViewRect rect = macro.matchPic(viewRect, "城镇_充值_L448,36", 0.8d); if (rect != null) { - jMacro.mouseLeftClick(rect); + macro.mouseLeftClick(rect); Logger.info("检测到广告弹框,关闭弹框"); } } {// 定位离线收益 - jMacro.delay(); - ScreenRect rect = jMacro.matchPic(screenRect, "城镇_离线收益_L204,734", 0.9); + macro.delay(); + ViewRect rect = macro.matchPic(viewRect, "城镇_离线收益_L204,734", 0.9); if (rect != null) { - jMacro.mouseLeftClick(rect); + macro.mouseLeftClick(rect); Logger.info("检测到离线收益弹框,关闭弹框"); } } {// 定位野外 - jMacro.delay(); - ScreenRect rect = jMacro.matchPic(screenRect, "野外_L444,888", 0.9); + macro.delay(); + ViewRect rect = macro.matchPic(viewRect, "野外_L444,888", 0.9); if (rect != null) { Logger.info("当前区域【城镇】"); return rect; @@ -102,20 +98,18 @@ public class DemoThread extends JMacroThread { } // 定位城镇 { - jMacro.delay(); - ScreenRect rect = jMacro.matchPic(screenRect, "城镇_L456,887", 0.9); + macro.delay(); + ViewRect rect = macro.matchPic(viewRect, "城镇_L456,887", 0.9); if (rect != null) { Logger.info("当前区域【野外】"); Logger.info("返回区域【城镇】"); - jMacro.mouseLeftClick(rect); + macro.mouseLeftClick(rect); } } } }, 30, TimeUnit.SECONDS); - if (城镇 == null && schedule != null) { - schedule.cancel(true); - schedule = null; + if (城镇 == null) { Logger.info("未扫描到主界面:退出线程"); return; } @@ -123,24 +117,22 @@ public class DemoThread extends JMacroThread { Logger.info("进入主界面"); Logger.info("进入任务线程"); - TaskUtil.timeTask((Runnable) () -> { - while (true) { - // 欢迎回来弹框 - jMacro.delayNormal(); - new Task_离线收益(jMacro, screenRect).run(); - - // 矿场攻击检测任务 - jMacro.delayNormal(); - new Task_采矿被攻击(jMacro, screenRect).run(); - - // 矿场攻击检测任务 - jMacro.delayNormal(); - new Task_探险领取(jMacro, screenRect).run(); - - // 自动采矿任务 - jMacro.delayNormal(); - new Task_自动采矿(jMacro, screenRect).run(); - } - }, 10, TimeUnit.MINUTES); + while (!Thread.currentThread().isInterrupted()) { + // 欢迎回来弹框 + macro.delayNormal(); + new Task_离线收益(macro, viewRect).run(); + + // 矿场攻击检测任务 + macro.delayNormal(); + new Task_采矿被攻击(macro, viewRect).run(); + + // 矿场攻击检测任务 + macro.delayNormal(); + new Task_探险领取(macro, viewRect).run(); + + // 自动采矿任务 + macro.delayNormal(); + new Task_自动采矿(macro, viewRect).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 71d0391..381bed5 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,22 +1,45 @@ package com.example.jmacro.wjdr.demo.task; import com.example.jmacro.wjdr.JMacro; -import com.example.jmacro.wjdr.base.ScreenRect; +import com.example.jmacro.wjdr.base.ViewRect; +import com.example.jmacro.wjdr.util.Logger; +/** + * 基础任务类 + */ public abstract class BaseTask implements Runnable { /** * 脚本持有对象 */ - protected JMacro jMacro; + protected JMacro macro; /** * 应用窗口 */ - protected ScreenRect screenRect; + protected ViewRect viewRect; - public BaseTask(JMacro jMacro, ScreenRect screenRect) { - this.jMacro = jMacro; - this.screenRect = screenRect; + public BaseTask(JMacro macro, ViewRect viewRect) { + this.macro = macro; + this.viewRect = viewRect; } + + @Override + public void run() { + if (Thread.currentThread().isInterrupted()) { + return; + } + String name = getClass().getName(); + Logger.info("》》》任务[{}]开始》》》", name); + this.task(macro, viewRect); + Logger.info("》》》任务[{}]结束》》》", name); + } + + /** + * 任务 + * + * @param macro 脚本 + * @param viewRect 视口 + */ + public abstract void task(JMacro macro, ViewRect viewRect); } 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 d1113b9..8845f00 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 @@ -1,29 +1,27 @@ package com.example.jmacro.wjdr.demo.task; import com.example.jmacro.wjdr.JMacro; -import com.example.jmacro.wjdr.base.ScreenRect; +import com.example.jmacro.wjdr.base.ViewRect; import com.example.jmacro.wjdr.util.Logger; public class Task_探险领取 extends BaseTask { - public Task_探险领取(JMacro jMacro, ScreenRect screenRect) { - super(jMacro, screenRect); + public Task_探险领取(JMacro macro, ViewRect viewRect) { + super(macro, viewRect); } @Override - public void run() { - Logger.info("》》》探险奖励领取开始》》》"); - + public void task(JMacro macro, ViewRect viewRect) { Logger.info("定位【探险】按钮"); - ScreenRect TAB_探险 = jMacro.waitAndMatchPic(this.screenRect, "城镇_探险_L35,881", 0.9); + ViewRect TAB_探险 = macro.waitAndMatchPic(this.viewRect, "城镇_探险_L35,881", 0.9); if (TAB_探险 == null) { return; } Logger.info("点击【探险】按钮"); - jMacro.mouseLeftClick(TAB_探险); + macro.mouseLeftClick(TAB_探险); - ScreenRect 探险_按钮 = jMacro.waitAndMatchPic(this.screenRect, "探险_按钮_L240,854", 0.9); + ViewRect 探险_按钮 = macro.waitAndMatchPic(this.viewRect, "探险_按钮_L240,854", 0.9); if (探险_按钮 == null) { Logger.info("进入探险界面失败"); return; @@ -31,40 +29,38 @@ public class Task_探险领取 extends BaseTask { Logger.info("进入探险界面成功"); Logger.info("定位领取按钮"); - ScreenRect 探险_不可领取 = jMacro.waitAndMatchPic(this.screenRect, "探险_不可领取_L420,667", 0.8); + ViewRect 探险_不可领取 = macro.waitAndMatchPic(this.viewRect, "探险_不可领取_L420,667", 0.8); if (探险_不可领取 != null) { Logger.info("探险不可领取"); } else { Logger.info("定位领取按钮"); - ScreenRect 探险_领取 = jMacro.waitAndMatchPic(this.screenRect, "探险_领取_L426,667", 0.8); + ViewRect 探险_领取 = macro.waitAndMatchPic(this.viewRect, "探险_领取_L426,667", 0.8); if (探险_领取 == null) { Logger.error("未检测到【探险_领取】,领取终止"); return; } Logger.info("定位领取按钮成功,准备领取:{}", 探险_领取.toString()); - jMacro.mouseLeftClick(探险_领取); - ScreenRect 探险_领取2 = jMacro.waitAndMatchPic(this.screenRect, "探险_领取2_L230,664", 0.8); + macro.mouseLeftClick(探险_领取); + ViewRect 探险_领取2 = macro.waitAndMatchPic(this.viewRect, "探险_领取2_L230,664", 0.8); if (探险_领取2 == null) { Logger.error("任务终止"); return; } - jMacro.mouseLeftClick(探险_领取2); + macro.mouseLeftClick(探险_领取2); - ScreenRect 探险_获得奖励 = jMacro.waitAndMatchPic(this.screenRect, "探险_获得奖励_L196,218", 0.8); + ViewRect 探险_获得奖励 = macro.waitAndMatchPic(this.viewRect, "探险_获得奖励_L196,218", 0.8); if (探险_获得奖励 == null) { Logger.error("任务终止"); return; } - jMacro.mouseLeftClick(探险_获得奖励); + macro.mouseLeftClick(探险_获得奖励); } - ScreenRect 探险_返回 = jMacro.waitAndMatchPic(this.screenRect, "探险_返回_L4,4", 0.8); + ViewRect 探险_返回 = macro.waitAndMatchPic(this.viewRect, "探险_返回_L4,4", 0.8); if (探险_返回 == null) { Logger.error("任务终止"); return; } - jMacro.mouseLeftClick(探险_返回); - - Logger.info("》》》探险奖励领取结束,返回城镇》》》"); + macro.mouseLeftClick(探险_返回); } } 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 79d82ba..8c84b14 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 @@ -1,25 +1,23 @@ package com.example.jmacro.wjdr.demo.task; import com.example.jmacro.wjdr.JMacro; -import com.example.jmacro.wjdr.base.ScreenRect; +import com.example.jmacro.wjdr.base.ViewRect; import com.example.jmacro.wjdr.util.Logger; public class Task_离线收益 extends BaseTask { - public Task_离线收益(JMacro jMacro, ScreenRect screenRect) { - super(jMacro, screenRect); + public Task_离线收益(JMacro macro, ViewRect viewRect) { + super(macro, viewRect); } @Override - public void run() { - Logger.info("》》》检测离线收益弹框开始》》》"); - jMacro.delay(); + public void task(JMacro macro, ViewRect viewRect) { + macro.delay(); // 定位离线收益弹框,关闭弹框 - ScreenRect rect = jMacro.matchPic(screenRect, "城镇_离线收益_L204,734", 0.9); + ViewRect rect = macro.matchPic(viewRect, "城镇_离线收益_L204,734", 0.9); if (rect != null) { - jMacro.mouseLeftClick(rect); + macro.mouseLeftClick(rect); Logger.info("检测到离线收益弹框,关闭弹框"); } - 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 0afe9a8..cb86df9 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 @@ -2,29 +2,27 @@ package com.example.jmacro.wjdr.demo.task; import cn.hutool.json.JSONUtil; import com.example.jmacro.wjdr.JMacro; -import com.example.jmacro.wjdr.base.ScreenPoint; -import com.example.jmacro.wjdr.base.ScreenRect; +import com.example.jmacro.wjdr.base.ViewPoint; +import com.example.jmacro.wjdr.base.ViewRect; import com.example.jmacro.wjdr.util.Logger; import java.io.File; public class Task_自动采矿 extends BaseTask { - public Task_自动采矿(JMacro jMacro, ScreenRect screenRect) { - super(jMacro, screenRect); + public Task_自动采矿(JMacro macro, ViewRect viewRect) { + super(macro, viewRect); } @Override - public void run() { - Logger.info("》》》自动采矿开始》》》"); - + public void task(JMacro macro, ViewRect viewRect) { Logger.info("判断是否在野外"); - ScreenRect 城镇 = jMacro.waitAndMatchPic(this.screenRect, "城镇_L449,887", 0.9); + ViewRect 城镇 = macro.waitAndMatchPic(this.viewRect, "城镇_L449,887", 0.9); if (城镇 != null) { Logger.info("当前界面【野外】"); } else { Logger.info("定位【野外】"); - ScreenRect 野外 = jMacro.waitAndMatchPic(this.screenRect, "野外_L444,888", 0.99); + ViewRect 野外 = macro.waitAndMatchPic(this.viewRect, "野外_L444,888", 0.99); if (野外 == null) { Logger.error("定位【野外】失败,采矿终止"); return; @@ -32,18 +30,18 @@ public class Task_自动采矿 extends BaseTask { Logger.info("定位【野外】成功,{}", 野外.toString()); Logger.info("点击【野外】,坐标{}", JSONUtil.toJsonStr(野外.getCenter())); - jMacro.mouseLeftClick(野外); + macro.mouseLeftClick(野外); Logger.info("定位野外按钮成功"); } Logger.info("定位资源搜索按钮"); - ScreenRect 野外搜索 = jMacro.waitAndMatchPic(this.screenRect, "野外_搜索_L33,636", 0.5); + ViewRect 野外搜索 = macro.waitAndMatchPic(this.viewRect, "野外_搜索_L33,636", 0.5); if (野外搜索 == null) { Logger.error("未检测到【资源搜索按钮】,采矿终止"); return; } Logger.info("定位资源搜索按钮成功:{}", 野外搜索.toString()); - jMacro.mouseLeftClick(野外搜索); + macro.mouseLeftClick(野外搜索); String[] types = new String[]{ "生肉", "木材", "煤矿", "铁矿" @@ -57,19 +55,18 @@ public class Task_自动采矿 extends BaseTask { } // 检测是否是搜索界面 - ScreenRect 搜索 = jMacro.waitAndMatchPic(this.screenRect, "野外_搜索_L18,633", 9); + ViewRect 搜索 = macro.waitAndMatchPic(this.viewRect, "野外_搜索_L18,633", 9); if (搜索 != null) { Logger.info("退出资源搜索界面"); - jMacro.mouseLeftClick(this.screenRect); + macro.mouseLeftClick(this.viewRect); } - ScreenRect 城1 = jMacro.waitAndMatchPic(this.screenRect, "城镇_L456,887", 0.9); + ViewRect 城1 = macro.waitAndMatchPic(this.viewRect, "城镇_L456,887", 0.9); if (城1 == null) { Logger.error("未检测到【城镇】,采矿终止"); return; } Logger.info("返回城镇"); - Logger.info("》》》自动采矿结束,返回城镇》》》"); } /** @@ -79,57 +76,57 @@ public class Task_自动采矿 extends BaseTask { */ private boolean collect(String type, int level) { Logger.info("定位【{}】图标", type); - ScreenRect typeRect = jMacro.waitAndFindPic(screenRect, new File("legend", "野外_" + type + ".png"), 0.9); + ViewRect typeRect = macro.waitAndFindPic(viewRect, new File("legend", "野外_" + type + ".png"), 0.9); if (typeRect == null) { Logger.error("定位【{}】图标失败", type); } Logger.info("定位【{}】图标成功", type); Logger.info("单击【{}】图标,坐标[{},{}]", type, typeRect.getCenter()[0], typeRect.getCenter()[1]); - jMacro.mouseLeftClick(typeRect); + macro.mouseLeftClick(typeRect); if (level == 0) { - ScreenRect 等级减 = jMacro.waitAndFindPic(screenRect, new File("legend", "野外_资源_-.png"), 0.98); + ViewRect 等级减 = macro.waitAndFindPic(viewRect, new File("legend", "野外_资源_-.png"), 0.98); while (等级减 != null) { - jMacro.delayTap(); - jMacro.mouseLeftClick(等级减); - 等级减 = jMacro.waitAndFindPic(screenRect, new File("legend", "野外_资源_-.png"), 0.98); + macro.delayTap(); + macro.mouseLeftClick(等级减); + 等级减 = macro.waitAndFindPic(viewRect, new File("legend", "野外_资源_-.png"), 0.98); } Logger.info("矿等级重置为1"); level = 1; } Logger.info("搜索{}{}级矿", type, level); - ScreenRect 搜索 = jMacro.waitAndFindPic(screenRect, new File("legend", "野外_资源_搜索.png"), 0.98); - jMacro.mouseLeftClick(搜索); - ScreenRect 采集 = jMacro.waitAndFindPic(screenRect, new File("legend", "野外_资源_采集.png"), 0.98); + ViewRect 搜索 = macro.waitAndFindPic(viewRect, new File("legend", "野外_资源_搜索.png"), 0.98); + macro.mouseLeftClick(搜索); + ViewRect 采集 = macro.waitAndFindPic(viewRect, new File("legend", "野外_资源_采集.png"), 0.98); if (采集 == null) { Logger.info("未搜索到{}{}级矿!", type, level); - ScreenRect 等级加 = jMacro.waitAndFindPic(screenRect, new File("legend", "野外_资源_+.png"), 0.98); - jMacro.mouseLeftClick(等级加); + ViewRect 等级加 = macro.waitAndFindPic(viewRect, new File("legend", "野外_资源_+.png"), 0.98); + macro.mouseLeftClick(等级加); return collect(type, level + 1); } Logger.info("搜索到{}{}级矿", type, level); Logger.info("采集{}{}级矿", type, level); - jMacro.mouseLeftClick(采集); + macro.mouseLeftClick(采集); - ScreenRect 采集队伍满 = jMacro.waitAndFindPic(screenRect, new File("legend", "野外_资源_采集队伍满.png"), 0.98); + ViewRect 采集队伍满 = macro.waitAndFindPic(viewRect, new File("legend", "野外_资源_采集队伍满.png"), 0.98); if (采集队伍满 != null) { Logger.info("出征队伍满,取消采集!"); Logger.info("关闭弹框!"); - jMacro.mouseLeftClick(new ScreenPoint(采集队伍满.getRight() - 17, 采集队伍满.getBottom() - 20)); + macro.mouseLeftClick(new ViewPoint(采集队伍满.getRight() - 17, 采集队伍满.getBottom() - 20)); Logger.info("退出资源搜索!"); - jMacro.mouseLeftClick(new ScreenPoint(采集队伍满.getRight() - 17, 采集队伍满.getBottom() - 20)); + macro.mouseLeftClick(new ViewPoint(采集队伍满.getRight() - 17, 采集队伍满.getBottom() - 20)); return true; } - ScreenRect 出征 = jMacro.waitAndFindPic(screenRect, new File("legend", "野外_资源_出征.png"), 0.98); + ViewRect 出征 = macro.waitAndFindPic(viewRect, new File("legend", "野外_资源_出征.png"), 0.98); if (出征 == null) { Logger.info("出征{}{}级矿失败!", type, level); return false; } Logger.info("出征{}{}级矿", type, level); - jMacro.mouseLeftClick(出征); + macro.mouseLeftClick(出征); return true; } } 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 20e3fe5..1fd6948 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 @@ -1,19 +1,17 @@ package com.example.jmacro.wjdr.demo.task; import com.example.jmacro.wjdr.JMacro; -import com.example.jmacro.wjdr.base.ScreenRect; +import com.example.jmacro.wjdr.base.ViewRect; import com.example.jmacro.wjdr.util.Logger; public class Task_采矿被攻击 extends BaseTask { - public Task_采矿被攻击(JMacro jMacro, ScreenRect screenRect) { - super(jMacro, screenRect); + public Task_采矿被攻击(JMacro macro, ViewRect viewRect) { + super(macro, viewRect); } @Override - public void run() { - Logger.info("》》》检测被攻击状态开始》》》"); - Logger.info("未实现,跳过"); - Logger.info("》》》检测被攻击状态结束》》》"); + public void task(JMacro macro, ViewRect viewRect) { + Logger.info("开发中..."); } } diff --git a/src/main/java/com/example/jmacro/wjdr/ui/FXMLUtil.java b/src/main/java/com/example/jmacro/wjdr/ui/FXMLUtil.java index 2d55f94..6528675 100644 --- a/src/main/java/com/example/jmacro/wjdr/ui/FXMLUtil.java +++ b/src/main/java/com/example/jmacro/wjdr/ui/FXMLUtil.java @@ -8,6 +8,10 @@ import java.net.URL; /** * FXML工具 + * + * @author wangbing + * @version 0.0.1 + * @since 1.8 */ public class FXMLUtil { diff --git a/src/main/java/com/example/jmacro/wjdr/util/Capture.java b/src/main/java/com/example/jmacro/wjdr/util/Capture.java index 2102082..082d9a0 100644 --- a/src/main/java/com/example/jmacro/wjdr/util/Capture.java +++ b/src/main/java/com/example/jmacro/wjdr/util/Capture.java @@ -13,6 +13,10 @@ import java.util.prefs.Preferences; /** * 辅助截屏工具 + * + * @author wangbing + * @version 0.0.1 + * @since 1.8 */ public class Capture extends JFrame { diff --git a/src/main/java/com/example/jmacro/wjdr/util/ColorUtil.java b/src/main/java/com/example/jmacro/wjdr/util/ColorUtil.java index 88627de..a15e4b2 100644 --- a/src/main/java/com/example/jmacro/wjdr/util/ColorUtil.java +++ b/src/main/java/com/example/jmacro/wjdr/util/ColorUtil.java @@ -1,8 +1,12 @@ package com.example.jmacro.wjdr.util; -import java.awt.image.BufferedImage; -import java.io.File; - +/** + * 颜色比对工具 + * + * @author wangbing + * @version 0.0.1 + * @since 1.8 + */ public class ColorUtil { /** @@ -29,11 +33,11 @@ public class ColorUtil { public static boolean isSimilar(int colorInt1, int colorInt2) { // 透明色认为相似 - if ((colorInt1>>24 & 0xff )== 0) { + if ((colorInt1 >> 24 & 0xff) == 0) { return true; } // 图例中的透明色认为相似 - if ((colorInt2>>24 & 0xff )== 0) { + if ((colorInt2 >> 24 & 0xff) == 0) { return true; } return calculateSimilarity(colorInt1, colorInt2) > 0.95d; diff --git a/src/main/java/com/example/jmacro/wjdr/util/Dialog.java b/src/main/java/com/example/jmacro/wjdr/util/Dialog.java new file mode 100644 index 0000000..9fae840 --- /dev/null +++ b/src/main/java/com/example/jmacro/wjdr/util/Dialog.java @@ -0,0 +1,269 @@ +package com.example.jmacro.wjdr.util; + +import cn.hutool.core.util.ClassUtil; +import com.example.jmacro.wjdr.JMainApplication; +import javafx.animation.KeyFrame; +import javafx.animation.Timeline; +import javafx.application.Platform; +import javafx.event.EventHandler; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.Node; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonBar; +import javafx.scene.control.ButtonType; +import javafx.scene.control.Label; +import javafx.scene.control.ProgressIndicator; +import javafx.scene.control.Tooltip; +import javafx.scene.image.Image; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.VBox; +import javafx.scene.paint.Color; +import javafx.scene.text.Font; +import javafx.stage.Modality; +import javafx.stage.Stage; +import javafx.util.Duration; + +import java.io.File; +import java.util.Optional; +import java.util.Timer; +import java.util.TimerTask; + +public class Dialog { + + private static Stage popup; + + public static void toast(String msg, long time) { + Label label = new Label(msg);//默认信息 + label.setStyle("-fx-background: rgba(56,56,56,0.7);-fx-border-radius: 25;-fx-background-radius: 25");//label透明,圆角 + label.setTextFill(Color.rgb(225, 255, 226));//消息字体颜色 + label.setPrefHeight(50); + label.setPadding(new Insets(15)); + label.setAlignment(Pos.CENTER);//居中 + label.setFont(new Font(20));//字体大小 + Scene scene = new Scene(label); + scene.setFill(null);//场景透明 + Stage stage = new Stage(); + stage.initModality(Modality.WINDOW_MODAL); + stage.setAlwaysOnTop(false); + stage.setScene(scene); + label.setText(msg); + TimerTask task = new TimerTask() { + @Override + public void run() { + Platform.runLater(stage::close); + } + }; + + Timer timer = new Timer(); + timer.schedule(task, time); + stage.show(); + } + + public static void showTimedDialog(final long time, String message) { + popup = new Stage(); + popup.setAlwaysOnTop(true); + popup.initModality(Modality.APPLICATION_MODAL); + final Button closeBtn = new Button("知道了"); + closeBtn.setOnAction(event -> popup.close()); + VBox root = new VBox(); + root.setPadding(new Insets(10)); + root.setAlignment(Pos.BASELINE_CENTER); + root.setSpacing(10); + root.getChildren().addAll(new Label(message), closeBtn); + Scene scene = new Scene(root); + popup.setScene(scene); + popup.setTitle("提示信息"); + popup.show(); + + Thread thread = new Thread(() -> { + try { + Thread.sleep(time); + if (popup.isShowing()) { + Platform.runLater(new Runnable() { + @Override + public void run() { + popup.close(); + } + }); + } + } catch (Exception exp) { + exp.printStackTrace(); + } + }); + thread.setDaemon(true); + thread.start(); + } + + public static void alert(String message) { + Platform.runLater(() -> { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); + stage.getIcons().add(new Image(ResourceUtil.getInput("icon.png"))); + stage.setAlwaysOnTop(true); + alert.setHeaderText(null); + alert.setTitle("提示"); + alert.setContentText(message); + alert.getButtonTypes().remove(ButtonType.CANCEL); + alert.setX(JMainApplication.primaryStage.getX() + JMainApplication.primaryStage.getWidth() / 2 - 213); + alert.setY(JMainApplication.primaryStage.getY() + JMainApplication.primaryStage.getHeight() / 2 - 70); + Optional buttonType = alert.showAndWait(); + }); + } + + public static void confirm(String message) { + confirm("提示", message, null); + } + + public static void confirm(String title, String message) { + confirm(title, message, null); + } + + public static void confirm(String title, String message, ConfirmCall call) { + Platform.runLater(() -> { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); + stage.getIcons().add(new Image(ResourceUtil.getInput("icon.png"))); + stage.setAlwaysOnTop(true); + alert.setHeaderText(null); + alert.setTitle(title); + alert.setContentText(message); + alert.setX(JMainApplication.primaryStage.getX() + JMainApplication.primaryStage.getWidth() / 2 - 213); + alert.setY(JMainApplication.primaryStage.getY() + JMainApplication.primaryStage.getHeight() / 2 - 70); + Optional buttonType = alert.showAndWait(); + if (call != null) { + if (ButtonBar.ButtonData.OK_DONE.getTypeCode().equals(buttonType.get().getButtonData().getTypeCode())) { + call.call(true); + } else { + call.call(false); + } + } + }); + } + + public static void error(String message) { + Platform.runLater(() -> { + Alert alert = new Alert(Alert.AlertType.ERROR); + Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); + stage.setAlwaysOnTop(true); + stage.getIcons().add(new Image(ResourceUtil.getInput("icon.png"))); + alert.setTitle("错误"); + alert.setX(JMainApplication.primaryStage.getX() + JMainApplication.primaryStage.getWidth() / 2 - 213); + alert.setY(JMainApplication.primaryStage.getY() + JMainApplication.primaryStage.getHeight() / 2 - 70); + alert.setHeaderText(""); + alert.setContentText(message); + alert.show(); + }); + } + + public static void success(String message) { + Platform.runLater(() -> { + Alert alert = new Alert(Alert.AlertType.INFORMATION); + Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); + stage.getIcons().add(new Image(ResourceUtil.getInput("icon.png"))); + alert.setTitle("消息"); + alert.setX(JMainApplication.primaryStage.getX() + JMainApplication.primaryStage.getWidth() / 2 - 213); + alert.setY(JMainApplication.primaryStage.getY() + JMainApplication.primaryStage.getHeight() / 2 - 70); + alert.setHeaderText(""); + alert.setContentText(message); + alert.show(); + }); + } + + private static javafx.scene.control.Dialog dialog = null; + + public static void loading(String message) { + loading(message, null); + } + + public static void loading(String message, CancelCall cancelCall) { + if (dialog != null) return; + Platform.runLater(() -> { + dialog = new javafx.scene.control.Dialog(); + dialog.setTitle("提示"); + Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow(); + stage.getIcons().add(new Image(ResourceUtil.getInput("icon.png"))); + dialog.setResult("1"); + dialog.setX(JMainApplication.primaryStage.getX() + JMainApplication.primaryStage.getWidth() / 2 - 68); + dialog.setY(JMainApplication.primaryStage.getY() + JMainApplication.primaryStage.getHeight() / 2 - 70); + GridPane gridPane = new GridPane(); + gridPane.setPrefWidth(200); + gridPane.setHgap(10); + gridPane.setVgap(10); + gridPane.setAlignment(Pos.CENTER); + gridPane.setPadding(new Insets(10, 10, 10, 10)); + dialog.getDialogPane().setContent(gridPane); + + ProgressIndicator indicator = new ProgressIndicator(); + indicator.setPrefSize(30, 30); + gridPane.add(indicator, 0, 0); + gridPane.add(new Label(message), 0, 1); + + if (cancelCall != null) { + Button cancel = new Button("取消"); + gridPane.add(cancel, 0, 2); + cancel.setOnMouseClicked(new EventHandler() { + @Override + public void handle(MouseEvent event) { + cancelCall.call(); + } + }); + } + dialog.show(); + }); + } + + public static void hideLoading() { + if (dialog == null) return; + Platform.runLater(new Runnable() { + @Override + public void run() { + dialog.close(); + dialog = null; + } + }); + } + + + public interface InputCall { + void call(String input); + } + + public interface ConfirmCall { + void call(boolean result); + } + + public interface DirectoryCall { + void call(File result); + } + + public interface CancelCall { + void call(); + } + + /** + * 给组件增加鼠标悬浮提示 + * + * @param node + * @param tip + */ + public static void installTip(Node node, String tip) { + Tooltip tooltip = new Tooltip(tip); + try { + java.lang.reflect.Field behavior = ClassUtil.getDeclaredField(Tooltip.class, "BEHAVIOR"); + behavior.setAccessible(true); + Object o = behavior.get(tooltip); + java.lang.reflect.Field activationTimer = ClassUtil.getDeclaredField(o.getClass(), "activationTimer"); + activationTimer.setAccessible(true); + Timeline timeline = (Timeline) activationTimer.get(o); + timeline.getKeyFrames().remove(0); + timeline.getKeyFrames().add(new KeyFrame(new Duration(10))); + } catch (Exception ignored) { + + } + Tooltip.install(node, tooltip); + } +} diff --git a/src/main/java/com/example/jmacro/wjdr/util/Imager.java b/src/main/java/com/example/jmacro/wjdr/util/ImageUtil.java similarity index 96% rename from src/main/java/com/example/jmacro/wjdr/util/Imager.java rename to src/main/java/com/example/jmacro/wjdr/util/ImageUtil.java index 6efdd1d..79a4f4e 100644 --- a/src/main/java/com/example/jmacro/wjdr/util/Imager.java +++ b/src/main/java/com/example/jmacro/wjdr/util/ImageUtil.java @@ -10,9 +10,13 @@ import java.util.List; import java.util.Map; /** - * 图片加载器 + * 图片加载工具 + * + * @author wangbing + * @version 0.0.1 + * @since 1.8 */ -public class Imager { +public class ImageUtil { private final static Map cache = new HashMap(); diff --git a/src/main/java/com/example/jmacro/wjdr/util/Logger.java b/src/main/java/com/example/jmacro/wjdr/util/Logger.java index 85749b6..01eb679 100644 --- a/src/main/java/com/example/jmacro/wjdr/util/Logger.java +++ b/src/main/java/com/example/jmacro/wjdr/util/Logger.java @@ -3,6 +3,12 @@ package com.example.jmacro.wjdr.util; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; +/** + * 日志记录器 + * @author wangbing + * @version 0.0.1 + * @since 1.8 + */ public class Logger { private static boolean isDebug = false; diff --git a/src/main/java/com/example/jmacro/wjdr/util/ResourceUtil.java b/src/main/java/com/example/jmacro/wjdr/util/ResourceUtil.java index 510d97e..b0a7965 100644 --- a/src/main/java/com/example/jmacro/wjdr/util/ResourceUtil.java +++ b/src/main/java/com/example/jmacro/wjdr/util/ResourceUtil.java @@ -11,6 +11,10 @@ import java.net.URL; /** * 资源工具 + * + * @author wangbing + * @version 0.0.1 + * @since 1.8 */ public class ResourceUtil extends cn.hutool.core.io.resource.ResourceUtil { diff --git a/src/main/resources/main.fxml b/src/main/resources/main.fxml index c2cff41..9876161 100644 --- a/src/main/resources/main.fxml +++ b/src/main/resources/main.fxml @@ -9,12 +9,12 @@ - +