上传备份

wjdr
王兵 1 year ago
parent 467ad6b040
commit b0445c77a5

@ -3,10 +3,10 @@ package com.example.jmacro.wjdr;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.ReUtil; import cn.hutool.core.util.ReUtil;
import com.example.jmacro.wjdr.base.ScreenPoint; import com.example.jmacro.wjdr.base.ViewPoint;
import com.example.jmacro.wjdr.base.ScreenRect; import com.example.jmacro.wjdr.base.ViewRect;
import com.example.jmacro.wjdr.util.ColorUtil; 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.Logger;
import com.example.jmacro.wjdr.util.TaskUtil; import com.example.jmacro.wjdr.util.TaskUtil;
@ -17,7 +17,7 @@ import java.io.File;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* Java *
* *
* @author wangbing * @author wangbing
* @version 0.0.1 * @version 0.0.1
@ -35,11 +35,15 @@ public class JMacro {
*/ */
private File legend; private File legend;
public JMacro() throws AWTException { public JMacro() {
// 机器人初始化 try {
this.robot = new Robot(); // 机器人初始化
this.robot.setAutoDelay(100); this.robot = new Robot();
this.legend = new File("legend"); this.robot.setAutoDelay(100);
this.legend = new File("legend");
} catch (AWTException e) {
throw new RuntimeException(e);
}
} }
public JMacro(File legend) throws AWTException { public JMacro(File legend) throws AWTException {
@ -77,7 +81,7 @@ public class JMacro {
* *
* @param point * @param point
*/ */
public void mouseMove(ScreenPoint point) { public void mouseMove(ViewPoint point) {
mouseMove(point, false); mouseMove(point, false);
} }
@ -87,7 +91,7 @@ public class JMacro {
* @param point * @param point
* @param smooth * @param smooth
*/ */
public void mouseMove(ScreenPoint point, boolean smooth) { public void mouseMove(ViewPoint point, boolean smooth) {
if (smooth) { if (smooth) {
// 获取当前鼠标位置 // 获取当前鼠标位置
Point mousePoint = MouseInfo.getPointerInfo().getLocation(); Point mousePoint = MouseInfo.getPointerInfo().getLocation();
@ -120,7 +124,7 @@ public class JMacro {
* *
* @param rect * @param rect
*/ */
public void mouseLeftClick(ScreenPoint rect) { public void mouseLeftClick(ViewPoint rect) {
mouseMove(rect); mouseMove(rect);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
delayTap(); delayTap();
@ -132,8 +136,8 @@ public class JMacro {
* *
* @param rect * @param rect
*/ */
public void mouseLeftClick(ScreenRect rect) { public void mouseLeftClick(ViewRect rect) {
mouseLeftClick(new ScreenPoint(rect.getCenter()[0], rect.getCenter()[1])); mouseLeftClick(new ViewPoint(rect.getCenter()[0], rect.getCenter()[1]));
} }
/** /**
@ -142,7 +146,7 @@ public class JMacro {
* @param start * @param start
* @param end * @param end
*/ */
public void mouseLeftDrag(ScreenPoint start, ScreenPoint end) { public void mouseLeftDrag(ViewPoint start, ViewPoint end) {
mouseLeftDrag(start, end, false); mouseLeftDrag(start, end, false);
} }
@ -153,7 +157,7 @@ public class JMacro {
* @param end * @param end
* @param smooth * @param smooth
*/ */
public void mouseLeftDrag(ScreenPoint start, ScreenPoint end, boolean smooth) { public void mouseLeftDrag(ViewPoint start, ViewPoint end, boolean smooth) {
mouseMove(start, smooth); mouseMove(start, smooth);
delayTap(); delayTap();
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
@ -169,7 +173,7 @@ public class JMacro {
* @param start * @param start
* @param end * @param end
*/ */
public void mouseRightDrag(ScreenPoint start, ScreenPoint end) { public void mouseRightDrag(ViewPoint start, ViewPoint end) {
mouseRightDrag(start, end, false); mouseRightDrag(start, end, false);
} }
@ -180,7 +184,7 @@ public class JMacro {
* @param end * @param end
* @param smooth * @param smooth
*/ */
public void mouseRightDrag(ScreenPoint start, ScreenPoint end, boolean smooth) { public void mouseRightDrag(ViewPoint start, ViewPoint end, boolean smooth) {
mouseMove(start, smooth); mouseMove(start, smooth);
delayTap(); delayTap();
robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); robot.mousePress(InputEvent.BUTTON3_DOWN_MASK);
@ -195,7 +199,7 @@ public class JMacro {
* *
* @param rect * @param rect
*/ */
public void mouseWheelClick(ScreenRect rect) { public void mouseWheelClick(ViewRect rect) {
delayTap(); delayTap();
robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]); robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]);
delayTap(); delayTap();
@ -209,7 +213,7 @@ public class JMacro {
* *
* @param rect * @param rect
*/ */
public void mouseRightClick(ScreenRect rect) { public void mouseRightClick(ViewRect rect) {
delayTap(); delayTap();
robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]); robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]);
delayTap(); delayTap();
@ -223,7 +227,7 @@ public class JMacro {
* *
* @param rect * @param rect
*/ */
public void mouseLeftDoubleClick(ScreenRect rect) { public void mouseLeftDoubleClick(ViewRect rect) {
delayTap(); delayTap();
robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]); robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]);
delayTap(); delayTap();
@ -239,16 +243,16 @@ public class JMacro {
/** /**
* *
*/ */
public BufferedImage capture(Robot robot, ScreenRect screenRect) { public BufferedImage capture(Robot robot, ViewRect viewRect) {
return robot.createScreenCapture(new Rectangle(screenRect.getLeft(), screenRect.getTop(), screenRect.getWidth(), screenRect.getHeight())); return robot.createScreenCapture(new Rectangle(viewRect.getLeft(), viewRect.getTop(), viewRect.getWidth(), viewRect.getHeight()));
} }
/** /**
* *
*/ */
public ScreenRect getScreenRect() { public ViewRect getScreenRect() {
Toolkit tk = Toolkit.getDefaultToolkit(); 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 * @param minSimilar
* @return * @return
*/ */
public ScreenRect findPic(String legendName, double minSimilar) { public ViewRect findPic(String legendName, double minSimilar) {
if (!legendName.endsWith(".png")) { if (!legendName.endsWith(".png")) {
legendName = legendName + ".png"; legendName = legendName + ".png";
} }
@ -272,8 +276,8 @@ public class JMacro {
* @param minSimilar * @param minSimilar
* @return * @return
*/ */
public ScreenRect findPic(File pic, double minSimilar) { public ViewRect findPic(File pic, double minSimilar) {
return findPic(getScreenRect(), Imager.load(pic), minSimilar); return findPic(getScreenRect(), ImageUtil.load(pic), minSimilar);
} }
/** /**
@ -283,65 +287,65 @@ public class JMacro {
* @param minSimilar * @param minSimilar
* @return * @return
*/ */
public ScreenRect findPic(BufferedImage pic, double minSimilar) { public ViewRect findPic(BufferedImage pic, double minSimilar) {
return findPic(getScreenRect(), pic, minSimilar); return findPic(getScreenRect(), pic, minSimilar);
} }
/** /**
* *
* *
* @param screenRect * @param viewRect
* @param legendName * @param legendName
* @param minSimilar * @param minSimilar
* @return * @return
*/ */
public ScreenRect findPic(ScreenRect screenRect, String legendName, double minSimilar) { public ViewRect findPic(ViewRect viewRect, String legendName, double minSimilar) {
if (!legendName.endsWith(".png")) { if (!legendName.endsWith(".png")) {
legendName = legendName + ".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 legend
* @param minSimilar * @param minSimilar
* @return * @return
*/ */
public ScreenRect findPic(ScreenRect screenRect, File legend, double minSimilar) { public ViewRect findPic(ViewRect viewRect, File legend, double minSimilar) {
return findPic(screenRect, Imager.load(legend), minSimilar); return findPic(viewRect, ImageUtil.load(legend), minSimilar);
} }
/** /**
* *
* *
* @param pic * @param pic
* @param screenRect * @param viewRect
* @param minSimilar * @param minSimilar
* @return * @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("视口尺寸小于图片"); Logger.error("视口尺寸小于图片");
return null; return null;
} }
// 获取实时屏幕 // 获取实时屏幕
BufferedImage screen = capture(robot, screenRect); BufferedImage screen = capture(robot, viewRect);
int[][] screenData = Imager.getImageRGB(screen); int[][] screenData = ImageUtil.getImageRGB(screen);
int[][] picData = Imager.getImageRGB(pic); int[][] picData = ImageUtil.getImageRGB(pic);
// 得到图片左上角范围 // 得到图片左上角范围
int xMin = screenRect.getLeft(); int xMin = viewRect.getLeft();
// 因为坐标取像素点是从0开始因此需要-1 // 因为坐标取像素点是从0开始因此需要-1
int xMax = screenRect.getRight() - pic.getWidth(); int xMax = viewRect.getRight() - pic.getWidth();
int yMin = screenRect.getTop(); int yMin = viewRect.getTop();
// 因为坐标取像素点是从0开始因此需要-1 // 因为坐标取像素点是从0开始因此需要-1
int yMax = screenRect.getBottom() - pic.getHeight(); int yMax = viewRect.getBottom() - pic.getHeight();
for (int y = yMin; y <= yMax; y++) { for (int y = yMin; y <= yMax; y++) {
for (int x = xMin; x <= xMax; x++) { 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]); 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) { 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) { 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(); delayNormal();
} }
public void delayTap() { public void delayTap() {
int i = RandomUtil.randomInt(100, 500); int i = RandomUtil.randomInt(100, 500);
robot.delay(i); robot.delay(i);
} }
public void delayNormal() { public void delayNormal() {
int i = RandomUtil.randomInt(500, 1500); int i = RandomUtil.randomInt(500, 1000);
robot.delay(i); robot.delay(i);
} }
public void delayLong() { public void delayLong() {
int i = RandomUtil.randomInt(1500, 3000); int i = RandomUtil.randomInt(1000, 2000);
robot.delay(i); robot.delay(i);
} }
@ -400,7 +403,7 @@ public class JMacro {
* @param minSimilar * @param minSimilar
* @return * @return
*/ */
public ScreenRect waitAndFindPic(File file, double minSimilar) { public ViewRect waitAndFindPic(File file, double minSimilar) {
return waitAndFindPic(getScreenRect(), file, minSimilar, 10, TimeUnit.SECONDS); return waitAndFindPic(getScreenRect(), file, minSimilar, 10, TimeUnit.SECONDS);
} }
@ -412,7 +415,7 @@ public class JMacro {
* @param minSimilar * @param minSimilar
* @return * @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); return waitAndFindPic(rect, file, minSimilar, 10, TimeUnit.SECONDS);
} }
@ -424,7 +427,7 @@ public class JMacro {
* @param minSimilar * @param minSimilar
* @return * @return
*/ */
public ScreenRect waitAndFindPic(ScreenRect rect, String legendName, double minSimilar) { public ViewRect waitAndFindPic(ViewRect rect, String legendName, double minSimilar) {
if (!legendName.endsWith(".png")) { if (!legendName.endsWith(".png")) {
legendName = legendName + ".png"; legendName = legendName + ".png";
} }
@ -440,7 +443,7 @@ public class JMacro {
* @param unit * @param unit
* @return * @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); return waitAndFindPic(getScreenRect(), file, minSimilar, time, unit);
} }
@ -454,7 +457,7 @@ public class JMacro {
* @param unit * @param unit
* @return * @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")) { if (!legendName.endsWith(".png")) {
legendName = legendName + ".png"; legendName = legendName + ".png";
} }
@ -471,9 +474,9 @@ public class JMacro {
* @param unit * @param unit
* @return * @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(() -> { return TaskUtil.timeTask(() -> {
BufferedImage image = Imager.load(file); BufferedImage image = ImageUtil.load(file);
if (rect.getWidth() < image.getWidth()) { if (rect.getWidth() < image.getWidth()) {
Logger.error("查找图片区域宽度{}小于图片宽度{}", rect.getWidth(), image.getWidth()); Logger.error("查找图片区域宽度{}小于图片宽度{}", rect.getWidth(), image.getWidth());
return null; return null;
@ -485,7 +488,7 @@ public class JMacro {
while (true) { while (true) {
delayTap(); delayTap();
ScreenRect pic = findPic(rect, image, minSimilar); ViewRect pic = findPic(rect, image, minSimilar);
if (pic != null) { if (pic != null) {
return pic; return pic;
} }
@ -501,7 +504,7 @@ public class JMacro {
* @param minSimilar * @param minSimilar
* @return * @return
*/ */
public ScreenRect waitAndMatchPic(ScreenRect rect, String legendName, double minSimilar) { public ViewRect waitAndMatchPic(ViewRect rect, String legendName, double minSimilar) {
if (!legendName.endsWith(".png")) { if (!legendName.endsWith(".png")) {
legendName = legendName + ".png"; legendName = legendName + ".png";
} }
@ -516,7 +519,7 @@ public class JMacro {
* @param minSimilar * @param minSimilar
* @return * @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); return waitAndMatchPic(rect, file, minSimilar, 10, TimeUnit.SECONDS);
} }
@ -530,11 +533,11 @@ public class JMacro {
* @param unit * @param unit
* @return * @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(() -> { return TaskUtil.timeTask(() -> {
while (true) { while (true) {
delayTap(); delayTap();
ScreenRect matchPic = matchPic(rect, file, minSimilar); ViewRect matchPic = matchPic(rect, file, minSimilar);
if (matchPic != null) { if (matchPic != null) {
return matchPic; return matchPic;
} }
@ -550,7 +553,7 @@ public class JMacro {
* @param minSimilar * @param minSimilar
* @return * @return
*/ */
public ScreenRect matchPic(ScreenRect rect, File file, double minSimilar) { public ViewRect matchPic(ViewRect rect, File file, double minSimilar) {
if (!file.exists()) { if (!file.exists()) {
Logger.error("file [{}] not exist", file.getAbsolutePath()); Logger.error("file [{}] not exist", file.getAbsolutePath());
return null; 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); 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); offsetY = Convert.toInt(ReUtil.get("[\\S\\s]+_L[0-9]+,([0-9]+)\\.png", name, 1), 0);
} }
ScreenRect screenRect = new ScreenRect(); ViewRect viewRect = new ViewRect();
screenRect.setLeft(rect.getLeft() + offsetX); viewRect.setLeft(rect.getLeft() + offsetX);
screenRect.setTop(rect.getTop() + offsetY); viewRect.setTop(rect.getTop() + offsetY);
BufferedImage image = Imager.load(file); BufferedImage image = ImageUtil.load(file);
screenRect.setRight(screenRect.getLeft() + image.getWidth()); viewRect.setRight(viewRect.getLeft() + image.getWidth());
screenRect.setBottom(screenRect.getTop() + image.getHeight()); viewRect.setBottom(viewRect.getTop() + image.getHeight());
return findPic(screenRect, image, minSimilar); return findPic(viewRect, image, minSimilar);
} }
/** /**
@ -579,7 +582,7 @@ public class JMacro {
* @param minSimilar * @param minSimilar
* @return * @return
*/ */
public ScreenRect matchPic(ScreenRect rect, String legendName, double minSimilar) { public ViewRect matchPic(ViewRect rect, String legendName, double minSimilar) {
if (!legendName.endsWith(".png")) { if (!legendName.endsWith(".png")) {
legendName = legendName + ".png"; legendName = legendName + ".png";
} }
@ -594,7 +597,7 @@ public class JMacro {
* @param minSimilar * @param minSimilar
* @return * @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; return matchPic(rect, file, minSimilar) != null;
} }
@ -606,7 +609,7 @@ public class JMacro {
* @param minSimilar * @param minSimilar
* @return * @return
*/ */
public boolean isMatchPic(ScreenRect rect, String legendName, double minSimilar) { public boolean isMatchPic(ViewRect rect, String legendName, double minSimilar) {
if (!legendName.endsWith(".png")) { if (!legendName.endsWith(".png")) {
legendName = legendName + ".png"; legendName = legendName + ".png";
} }

@ -1,9 +1,13 @@
package com.example.jmacro.wjdr; 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 * @author wangbing
* @version 0.0.1 * @version 0.0.1
@ -11,15 +15,21 @@ import com.example.jmacro.wjdr.base.ScreenRect;
*/ */
public abstract class JMacroThread implements Runnable { public abstract class JMacroThread implements Runnable {
protected JMacro jMacro; /**
protected ScreenRect screenRect; *
*/
protected JMacro macro;
/**
*
*/
protected ViewRect viewRect;
public JMacroThread(JMacro jMacro) { public JMacroThread(JMacro macro) {
this.jMacro = jMacro; this.macro = macro;
this.screenRect = location(); TaskUtil.asyncTask(() -> {
if (this.screenRect == null) { viewRect = TaskUtil.timeTask(this::location, 10, TimeUnit.SECONDS);
throw new RuntimeException("未定位到视口区域"); });
}
} }
/** /**
@ -27,13 +37,13 @@ public abstract class JMacroThread implements Runnable {
* *
* @return * @return
*/ */
public abstract ScreenRect location(); public abstract ViewRect location();
public ScreenRect getScreenRect() { public ViewRect getViewRect() {
return screenRect; return viewRect;
} }
public JMacro getMacro() { public JMacro getMacro() {
return jMacro; return macro;
} }
} }

@ -1,5 +1,6 @@
package com.example.jmacro.wjdr; package com.example.jmacro.wjdr;
import com.example.jmacro.wjdr.demo.DemoThread;
import com.example.jmacro.wjdr.ui.FXMLUtil; import com.example.jmacro.wjdr.ui.FXMLUtil;
import com.example.jmacro.wjdr.util.ResourceUtil; import com.example.jmacro.wjdr.util.ResourceUtil;
import javafx.application.Application; import javafx.application.Application;
@ -10,9 +11,15 @@ import javafx.stage.Stage;
/** /**
* UI * UI
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/ */
public class JMainApplication extends Application { public class JMainApplication extends Application {
public static Stage primaryStage;
@Override @Override
public void start(Stage stage) throws Exception { public void start(Stage stage) throws Exception {
stage.setTitle("无限工具"); stage.setTitle("无限工具");
@ -31,8 +38,9 @@ public class JMainApplication extends Application {
stage.getIcons().add(icon); stage.getIcons().add(icon);
// 展示UI // 展示UI
stage.show(); stage.show();
JMainApplication.primaryStage = stage;
// 服务初始化 // 服务初始化
JMainService.init(); JMainService.init(new DemoThread(new JMacro()));
} }
public static void main(String[] args) { public static void main(String[] args) {

@ -1,24 +1,39 @@
package com.example.jmacro.wjdr; 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.Capture;
import com.example.jmacro.wjdr.util.Logger; import com.example.jmacro.wjdr.util.Dialog;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.Button;
import java.awt.*; import java.awt.*;
import java.io.File; import java.io.File;
/**
* UI
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class JMainController { public class JMainController {
@FXML
private Button start;
@FXML
private Button stop;
@FXML
private Button capture;
/** /**
* *
*/ */
@FXML @FXML
private void onCapture() throws AWTException { private void onCapture() {
ScreenRect screen = JMainService.getInstance().getThread().getScreenRect(); ViewRect screen = JMainService.getInstance().getMacroThread().getViewRect();
File legend = JMainService.getInstance().getMacro().getLegend(); File legend = JMainService.getInstance().getMacro().getLegend();
if (screen == null) { if (screen == null) {
Logger.error("请等待窗口定位"); Dialog.alert("未定位到视口,请稍后再试!");
return; return;
} }
try { try {
@ -32,15 +47,19 @@ public class JMainController {
* *
*/ */
@FXML @FXML
private void onStart() throws AWTException { private void onStart() {
JMainService.start(); boolean start = JMainService.start();
this.start.setDisable(start);
this.stop.setDisable(!start);
} }
/** /**
* *
*/ */
@FXML @FXML
private void onStop() throws AWTException { private void onStop() {
JMainService.stop(); boolean stop = JMainService.stop();
this.start.setDisable(!stop);
this.stop.setDisable(stop);
} }
} }

@ -2,13 +2,13 @@ package com.example.jmacro.wjdr;
import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.thread.ThreadUtil;
import com.example.jmacro.wjdr.demo.DemoThread; import com.example.jmacro.wjdr.demo.DemoThread;
import com.example.jmacro.wjdr.util.Dialog;
import com.example.jmacro.wjdr.util.Logger; import com.example.jmacro.wjdr.util.Logger;
import java.awt.*;
import java.io.File; import java.io.File;
/** /**
* 线 * 线
* *
* @author wangbing * @author wangbing
* @version 0.0.1 * @version 0.0.1
@ -16,66 +16,87 @@ import java.io.File;
*/ */
public class JMainService { public class JMainService {
private static JMainService instance; /**
*
private JMacroThread thread; */
private boolean run;
private JMainService() throws AWTException { /**
// 脚本初始化 *
Logger.info("初始化脚本"); */
jMacro = new JMacro(); private static JMainService instance;
thread = new DemoThread(jMacro);
}
public static synchronized JMainService getInstance() throws AWTException { public static synchronized JMainService getInstance() {
if (instance == null) { if (instance == null) {
JMainService.instance = new JMainService(); JMainService.instance = new JMainService();
} }
return instance; return instance;
} }
public JMacroThread getThread() { /**
return thread; * 线
} */
public DaemonThread daemonThread;
public JMacro getMacro() {
return jMacro;
}
/** /**
* * 线
*/ */
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) { if (JMainService.getInstance().run) {
Logger.error("服务已启动"); Logger.error("服务已启动");
return; return false;
} }
// 启动服务 // 启动服务
Logger.info("启动服务"); Logger.info("启动服务");
// 启动守护线程
JMainService.getInstance().run = true; JMainService.getInstance().run = true;
// 启动后台线程 JMainService.getInstance().daemonThread.start();
JMainService.getInstance().serviceThread.start(); return true;
} }
public static void stop() throws AWTException { public static boolean stop() {
if (!JMainService.getInstance().run) { if (!JMainService.getInstance().run) {
Logger.error("服务未启动"); Logger.error("服务未启动");
return; return false;
} }
// 停止服务
Logger.info("停止服务"); Logger.info("停止服务");
// 关闭守护线程
JMainService.getInstance().run = false; JMainService.getInstance().run = false;
JMainService.getInstance().serviceThread.interrupt(); JMainService.getInstance().daemonThread.interrupt();
return true;
} }
/** /**
@ -83,54 +104,35 @@ public class JMainService {
* *
* @param legend * @param legend
*/ */
public void setLegend(File legend) { public static void setLegend(File legend) {
if (this.jMacro != null) { if (getInstance().macroThread != null) {
this.jMacro.setLegend(legend); getInstance().macroThread.getMacro().setLegend(legend);
} }
} }
/** /**
* 线 * 线
*/ */
public Thread serviceThread = new Thread() { class DaemonThread extends Thread {
@Override @Override
public void run() { public void run() {
while (run) { while (run) {
ThreadUtil.sleep(1000); ThreadUtil.sleep(1000);
if (thread == null) { if (macroThread == null) {
Logger.error("脚本线程未设置"); Logger.error("脚本线程未设置");
continue; continue;
} }
thread.run(); macroThread.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);
// }
} }
} }
}; }
/** /**
* *
*/ */
public static void main(String[] args) throws AWTException { public static void main(String[] args) {
new JMainService().start(); JMainService.init(new DemoThread(new JMacro()));
JMainService.start();
} }
} }

@ -1,17 +1,28 @@
package com.example.jmacro.wjdr.base; 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; private int x;
/**
* ()y
*/
private int y; private int y;
public ScreenPoint() { private ViewPoint() {
} }
public ScreenPoint(int x, int y) { public ViewPoint(int x, int y) {
this.x = x; this.x = x;
this.y = y; this.y = y;
} }

@ -1,9 +1,13 @@
package com.example.jmacro.wjdr.base; 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 left;
private int top; private int top;
@ -15,17 +19,17 @@ public class ScreenRect {
*/ */
private double similar; 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.left = left;
this.top = top; this.top = top;
this.right = right; this.right = right;
this.bottom = bottom; 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.left = left;
this.top = top; this.top = top;
this.right = right; this.right = right;

@ -2,7 +2,7 @@ package com.example.jmacro.wjdr.demo;
import com.example.jmacro.wjdr.JMacro; import com.example.jmacro.wjdr.JMacro;
import com.example.jmacro.wjdr.JMacroThread; 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_线; 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.Logger;
import com.example.jmacro.wjdr.util.TaskUtil; import com.example.jmacro.wjdr.util.TaskUtil;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/**
* 线
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class DemoThread extends JMacroThread { 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 final String workEnd = "24:00:00";
/** public DemoThread(JMacro macro) {
* super(macro);
*/
private boolean noDelay = true;
public DemoThread(JMacro jMacro) {
super(jMacro);
} }
@Override @Override
public synchronized ScreenRect location() { public synchronized ViewRect location() {
// 定位窗口 // 定位窗口
Logger.info("定位窗口"); Logger.info("定位窗口");
ScreenRect mumu = jMacro.findPic("慕慕_工具栏", 0.95d); ViewRect mumu = macro.findPic("慕慕_工具栏", 0.95d);
if (mumu == null) { if (mumu == null) {
Logger.error("定位窗口失败"); Logger.error("定位窗口失败");
return null; return null;
} }
Logger.info("定位慕慕窗口成功"); Logger.info("定位慕慕窗口成功");
// 计算应用窗口返回 // 计算应用窗口返回
ScreenRect gameScreen = new ScreenRect(); ViewRect gameScreen = new ViewRect();
gameScreen.setLeft(mumu.getLeft() - 428); gameScreen.setLeft(mumu.getLeft() - 428);
gameScreen.setTop(mumu.getBottom() + 7); gameScreen.setTop(mumu.getBottom() + 7);
gameScreen.setRight(mumu.getRight()); gameScreen.setRight(mumu.getRight());
@ -64,37 +60,37 @@ public class DemoThread extends JMacroThread {
public void run() { public void run() {
// 获取启动图标 // 获取启动图标
Logger.info("定位启动图标"); 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) { if (launch != null) {
Logger.info("启动图标坐标:", launch.toString()); Logger.info("启动图标坐标:", launch.toString());
Logger.info("启动程序"); Logger.info("启动程序");
jMacro.delay(); macro.delay();
jMacro.mouseLeftClick(launch); macro.mouseLeftClick(launch);
} else { } else {
Logger.info("启动图标失败,继续定位主界面"); Logger.info("启动图标失败,继续定位主界面");
} }
Logger.info("定位主界面"); Logger.info("定位主界面");
ScreenRect = TaskUtil.timeTask(() -> { ViewRect = TaskUtil.timeTask(() -> {
while (true) { 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) { if (rect != null) {
jMacro.mouseLeftClick(rect); macro.mouseLeftClick(rect);
Logger.info("检测到广告弹框,关闭弹框"); Logger.info("检测到广告弹框,关闭弹框");
} }
} }
{// 定位离线收益 {// 定位离线收益
jMacro.delay(); macro.delay();
ScreenRect rect = jMacro.matchPic(screenRect, "城镇_离线收益_L204,734", 0.9); ViewRect rect = macro.matchPic(viewRect, "城镇_离线收益_L204,734", 0.9);
if (rect != null) { if (rect != null) {
jMacro.mouseLeftClick(rect); macro.mouseLeftClick(rect);
Logger.info("检测到离线收益弹框,关闭弹框"); Logger.info("检测到离线收益弹框,关闭弹框");
} }
} }
{// 定位野外 {// 定位野外
jMacro.delay(); macro.delay();
ScreenRect rect = jMacro.matchPic(screenRect, "野外_L444,888", 0.9); ViewRect rect = macro.matchPic(viewRect, "野外_L444,888", 0.9);
if (rect != null) { if (rect != null) {
Logger.info("当前区域【城镇】"); Logger.info("当前区域【城镇】");
return rect; return rect;
@ -102,20 +98,18 @@ public class DemoThread extends JMacroThread {
} }
// 定位城镇 // 定位城镇
{ {
jMacro.delay(); macro.delay();
ScreenRect rect = jMacro.matchPic(screenRect, "城镇_L456,887", 0.9); ViewRect rect = macro.matchPic(viewRect, "城镇_L456,887", 0.9);
if (rect != null) { if (rect != null) {
Logger.info("当前区域【野外】"); Logger.info("当前区域【野外】");
Logger.info("返回区域【城镇】"); Logger.info("返回区域【城镇】");
jMacro.mouseLeftClick(rect); macro.mouseLeftClick(rect);
} }
} }
} }
}, 30, TimeUnit.SECONDS); }, 30, TimeUnit.SECONDS);
if ( == null && schedule != null) { if ( == null) {
schedule.cancel(true);
schedule = null;
Logger.info("未扫描到主界面:退出线程"); Logger.info("未扫描到主界面:退出线程");
return; return;
} }
@ -123,24 +117,22 @@ public class DemoThread extends JMacroThread {
Logger.info("进入主界面"); Logger.info("进入主界面");
Logger.info("进入任务线程"); Logger.info("进入任务线程");
TaskUtil.timeTask((Runnable) () -> { while (!Thread.currentThread().isInterrupted()) {
while (true) { // 欢迎回来弹框
// 欢迎回来弹框 macro.delayNormal();
jMacro.delayNormal(); new Task_线(macro, viewRect).run();
new Task_线(jMacro, screenRect).run();
// 矿场攻击检测任务
// 矿场攻击检测任务 macro.delayNormal();
jMacro.delayNormal(); new Task_(macro, viewRect).run();
new Task_(jMacro, screenRect).run();
// 矿场攻击检测任务
// 矿场攻击检测任务 macro.delayNormal();
jMacro.delayNormal(); new Task_(macro, viewRect).run();
new Task_(jMacro, screenRect).run();
// 自动采矿任务
// 自动采矿任务 macro.delayNormal();
jMacro.delayNormal(); new Task_(macro, viewRect).run();
new Task_(jMacro, screenRect).run(); }
}
}, 10, TimeUnit.MINUTES);
} }
} }

@ -1,22 +1,45 @@
package com.example.jmacro.wjdr.demo.task; package com.example.jmacro.wjdr.demo.task;
import com.example.jmacro.wjdr.JMacro; 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 { public abstract class BaseTask implements Runnable {
/** /**
* *
*/ */
protected JMacro jMacro; protected JMacro macro;
/** /**
* *
*/ */
protected ScreenRect screenRect; protected ViewRect viewRect;
public BaseTask(JMacro jMacro, ScreenRect screenRect) { public BaseTask(JMacro macro, ViewRect viewRect) {
this.jMacro = jMacro; this.macro = macro;
this.screenRect = screenRect; 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);
} }

@ -1,29 +1,27 @@
package com.example.jmacro.wjdr.demo.task; package com.example.jmacro.wjdr.demo.task;
import com.example.jmacro.wjdr.JMacro; 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; import com.example.jmacro.wjdr.util.Logger;
public class Task_ extends BaseTask { public class Task_ extends BaseTask {
public Task_(JMacro jMacro, ScreenRect screenRect) { public Task_(JMacro macro, ViewRect viewRect) {
super(jMacro, screenRect); super(macro, viewRect);
} }
@Override @Override
public void run() { public void task(JMacro macro, ViewRect viewRect) {
Logger.info("》》》探险奖励领取开始》》》");
Logger.info("定位【探险】按钮"); 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) { if (TAB_ == null) {
return; return;
} }
Logger.info("点击【探险】按钮"); 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) { if (_ == null) {
Logger.info("进入探险界面失败"); Logger.info("进入探险界面失败");
return; return;
@ -31,40 +29,38 @@ public class Task_探险领取 extends BaseTask {
Logger.info("进入探险界面成功"); Logger.info("进入探险界面成功");
Logger.info("定位领取按钮"); Logger.info("定位领取按钮");
ScreenRect _ = jMacro.waitAndMatchPic(this.screenRect, "探险_不可领取_L420,667", 0.8); ViewRect _ = macro.waitAndMatchPic(this.viewRect, "探险_不可领取_L420,667", 0.8);
if (_ != null) { if (_ != null) {
Logger.info("探险不可领取"); Logger.info("探险不可领取");
} else { } else {
Logger.info("定位领取按钮"); Logger.info("定位领取按钮");
ScreenRect _ = jMacro.waitAndMatchPic(this.screenRect, "探险_领取_L426,667", 0.8); ViewRect _ = macro.waitAndMatchPic(this.viewRect, "探险_领取_L426,667", 0.8);
if (_ == null) { if (_ == null) {
Logger.error("未检测到【探险_领取】领取终止"); Logger.error("未检测到【探险_领取】领取终止");
return; return;
} }
Logger.info("定位领取按钮成功,准备领取:{}", _.toString()); Logger.info("定位领取按钮成功,准备领取:{}", _.toString());
jMacro.mouseLeftClick(_); macro.mouseLeftClick(_);
ScreenRect _2 = jMacro.waitAndMatchPic(this.screenRect, "探险_领取2_L230,664", 0.8); ViewRect _2 = macro.waitAndMatchPic(this.viewRect, "探险_领取2_L230,664", 0.8);
if (_2 == null) { if (_2 == null) {
Logger.error("任务终止"); Logger.error("任务终止");
return; 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) { if (_ == null) {
Logger.error("任务终止"); Logger.error("任务终止");
return; 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) { if (_ == null) {
Logger.error("任务终止"); Logger.error("任务终止");
return; return;
} }
jMacro.mouseLeftClick(_); macro.mouseLeftClick(_);
Logger.info("》》》探险奖励领取结束,返回城镇》》》");
} }
} }

@ -1,25 +1,23 @@
package com.example.jmacro.wjdr.demo.task; package com.example.jmacro.wjdr.demo.task;
import com.example.jmacro.wjdr.JMacro; 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; import com.example.jmacro.wjdr.util.Logger;
public class Task_线 extends BaseTask { public class Task_线 extends BaseTask {
public Task_线(JMacro jMacro, ScreenRect screenRect) { public Task_线(JMacro macro, ViewRect viewRect) {
super(jMacro, screenRect); super(macro, viewRect);
} }
@Override @Override
public void run() { public void task(JMacro macro, ViewRect viewRect) {
Logger.info("》》》检测离线收益弹框开始》》》"); macro.delay();
jMacro.delay();
// 定位离线收益弹框,关闭弹框 // 定位离线收益弹框,关闭弹框
ScreenRect rect = jMacro.matchPic(screenRect, "城镇_离线收益_L204,734", 0.9); ViewRect rect = macro.matchPic(viewRect, "城镇_离线收益_L204,734", 0.9);
if (rect != null) { if (rect != null) {
jMacro.mouseLeftClick(rect); macro.mouseLeftClick(rect);
Logger.info("检测到离线收益弹框,关闭弹框"); Logger.info("检测到离线收益弹框,关闭弹框");
} }
Logger.info("》》》检测离线收益弹框结束》》》");
} }
} }

@ -2,29 +2,27 @@ package com.example.jmacro.wjdr.demo.task;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.example.jmacro.wjdr.JMacro; import com.example.jmacro.wjdr.JMacro;
import com.example.jmacro.wjdr.base.ScreenPoint; import com.example.jmacro.wjdr.base.ViewPoint;
import com.example.jmacro.wjdr.base.ScreenRect; import com.example.jmacro.wjdr.base.ViewRect;
import com.example.jmacro.wjdr.util.Logger; import com.example.jmacro.wjdr.util.Logger;
import java.io.File; import java.io.File;
public class Task_ extends BaseTask { public class Task_ extends BaseTask {
public Task_(JMacro jMacro, ScreenRect screenRect) { public Task_(JMacro macro, ViewRect viewRect) {
super(jMacro, screenRect); super(macro, viewRect);
} }
@Override @Override
public void run() { public void task(JMacro macro, ViewRect viewRect) {
Logger.info("》》》自动采矿开始》》》");
Logger.info("判断是否在野外"); Logger.info("判断是否在野外");
ScreenRect = jMacro.waitAndMatchPic(this.screenRect, "城镇_L449,887", 0.9); ViewRect = macro.waitAndMatchPic(this.viewRect, "城镇_L449,887", 0.9);
if ( != null) { if ( != null) {
Logger.info("当前界面【野外】"); Logger.info("当前界面【野外】");
} else { } else {
Logger.info("定位【野外】"); Logger.info("定位【野外】");
ScreenRect = jMacro.waitAndMatchPic(this.screenRect, "野外_L444,888", 0.99); ViewRect = macro.waitAndMatchPic(this.viewRect, "野外_L444,888", 0.99);
if ( == null) { if ( == null) {
Logger.error("定位【野外】失败,采矿终止"); Logger.error("定位【野外】失败,采矿终止");
return; return;
@ -32,18 +30,18 @@ public class Task_自动采矿 extends BaseTask {
Logger.info("定位【野外】成功,{}", .toString()); Logger.info("定位【野外】成功,{}", .toString());
Logger.info("点击【野外】,坐标{}", JSONUtil.toJsonStr(.getCenter())); Logger.info("点击【野外】,坐标{}", JSONUtil.toJsonStr(.getCenter()));
jMacro.mouseLeftClick(); macro.mouseLeftClick();
Logger.info("定位野外按钮成功"); Logger.info("定位野外按钮成功");
} }
Logger.info("定位资源搜索按钮"); Logger.info("定位资源搜索按钮");
ScreenRect = jMacro.waitAndMatchPic(this.screenRect, "野外_搜索_L33,636", 0.5); ViewRect = macro.waitAndMatchPic(this.viewRect, "野外_搜索_L33,636", 0.5);
if ( == null) { if ( == null) {
Logger.error("未检测到【资源搜索按钮】,采矿终止"); Logger.error("未检测到【资源搜索按钮】,采矿终止");
return; return;
} }
Logger.info("定位资源搜索按钮成功:{}", .toString()); Logger.info("定位资源搜索按钮成功:{}", .toString());
jMacro.mouseLeftClick(); macro.mouseLeftClick();
String[] types = new String[]{ 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) { if ( != null) {
Logger.info("退出资源搜索界面"); 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) { if (1 == null) {
Logger.error("未检测到【城镇】,采矿终止"); Logger.error("未检测到【城镇】,采矿终止");
return; return;
} }
Logger.info("返回城镇"); Logger.info("返回城镇");
Logger.info("》》》自动采矿结束,返回城镇》》》");
} }
/** /**
@ -79,57 +76,57 @@ public class Task_自动采矿 extends BaseTask {
*/ */
private boolean collect(String type, int level) { private boolean collect(String type, int level) {
Logger.info("定位【{}】图标", type); 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) { if (typeRect == null) {
Logger.error("定位【{}】图标失败", type); Logger.error("定位【{}】图标失败", type);
} }
Logger.info("定位【{}】图标成功", type); Logger.info("定位【{}】图标成功", type);
Logger.info("单击【{}】图标,坐标[{},{}]", type, typeRect.getCenter()[0], typeRect.getCenter()[1]); Logger.info("单击【{}】图标,坐标[{},{}]", type, typeRect.getCenter()[0], typeRect.getCenter()[1]);
jMacro.mouseLeftClick(typeRect); macro.mouseLeftClick(typeRect);
if (level == 0) { 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) { while ( != null) {
jMacro.delayTap(); macro.delayTap();
jMacro.mouseLeftClick(); macro.mouseLeftClick();
= jMacro.waitAndFindPic(screenRect, new File("legend", "野外_资源_-.png"), 0.98); = macro.waitAndFindPic(viewRect, new File("legend", "野外_资源_-.png"), 0.98);
} }
Logger.info("矿等级重置为1"); Logger.info("矿等级重置为1");
level = 1; level = 1;
} }
Logger.info("搜索{}{}级矿", type, level); Logger.info("搜索{}{}级矿", type, level);
ScreenRect = jMacro.waitAndFindPic(screenRect, new File("legend", "野外_资源_搜索.png"), 0.98); ViewRect = macro.waitAndFindPic(viewRect, new File("legend", "野外_资源_搜索.png"), 0.98);
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) { if ( == null) {
Logger.info("未搜索到{}{}级矿!", type, level); Logger.info("未搜索到{}{}级矿!", type, level);
ScreenRect = jMacro.waitAndFindPic(screenRect, new File("legend", "野外_资源_+.png"), 0.98); ViewRect = macro.waitAndFindPic(viewRect, new File("legend", "野外_资源_+.png"), 0.98);
jMacro.mouseLeftClick(); macro.mouseLeftClick();
return collect(type, level + 1); return collect(type, level + 1);
} }
Logger.info("搜索到{}{}级矿", type, level); Logger.info("搜索到{}{}级矿", type, level);
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) { if ( != null) {
Logger.info("出征队伍满,取消采集!"); Logger.info("出征队伍满,取消采集!");
Logger.info("关闭弹框!"); Logger.info("关闭弹框!");
jMacro.mouseLeftClick(new ScreenPoint(.getRight() - 17, .getBottom() - 20)); macro.mouseLeftClick(new ViewPoint(.getRight() - 17, .getBottom() - 20));
Logger.info("退出资源搜索!"); Logger.info("退出资源搜索!");
jMacro.mouseLeftClick(new ScreenPoint(.getRight() - 17, .getBottom() - 20)); macro.mouseLeftClick(new ViewPoint(.getRight() - 17, .getBottom() - 20));
return true; return true;
} }
ScreenRect = jMacro.waitAndFindPic(screenRect, new File("legend", "野外_资源_出征.png"), 0.98); ViewRect = macro.waitAndFindPic(viewRect, new File("legend", "野外_资源_出征.png"), 0.98);
if ( == null) { if ( == null) {
Logger.info("出征{}{}级矿失败!", type, level); Logger.info("出征{}{}级矿失败!", type, level);
return false; return false;
} }
Logger.info("出征{}{}级矿", type, level); Logger.info("出征{}{}级矿", type, level);
jMacro.mouseLeftClick(); macro.mouseLeftClick();
return true; return true;
} }
} }

@ -1,19 +1,17 @@
package com.example.jmacro.wjdr.demo.task; package com.example.jmacro.wjdr.demo.task;
import com.example.jmacro.wjdr.JMacro; 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; import com.example.jmacro.wjdr.util.Logger;
public class Task_ extends BaseTask { public class Task_ extends BaseTask {
public Task_(JMacro jMacro, ScreenRect screenRect) { public Task_(JMacro macro, ViewRect viewRect) {
super(jMacro, screenRect); super(macro, viewRect);
} }
@Override @Override
public void run() { public void task(JMacro macro, ViewRect viewRect) {
Logger.info("》》》检测被攻击状态开始》》》"); Logger.info("开发中...");
Logger.info("未实现,跳过");
Logger.info("》》》检测被攻击状态结束》》》");
} }
} }

@ -8,6 +8,10 @@ import java.net.URL;
/** /**
* FXML * FXML
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/ */
public class FXMLUtil { public class FXMLUtil {

@ -13,6 +13,10 @@ import java.util.prefs.Preferences;
/** /**
* *
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/ */
public class Capture extends JFrame { public class Capture extends JFrame {

@ -1,8 +1,12 @@
package com.example.jmacro.wjdr.util; 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 { public class ColorUtil {
/** /**
@ -29,11 +33,11 @@ public class ColorUtil {
public static boolean isSimilar(int colorInt1, int colorInt2) { public static boolean isSimilar(int colorInt1, int colorInt2) {
// 透明色认为相似 // 透明色认为相似
if ((colorInt1>>24 & 0xff )== 0) { if ((colorInt1 >> 24 & 0xff) == 0) {
return true; return true;
} }
// 图例中的透明色认为相似 // 图例中的透明色认为相似
if ((colorInt2>>24 & 0xff )== 0) { if ((colorInt2 >> 24 & 0xff) == 0) {
return true; return true;
} }
return calculateSimilarity(colorInt1, colorInt2) > 0.95d; return calculateSimilarity(colorInt1, colorInt2) > 0.95d;

@ -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> 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> 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<MouseEvent>() {
@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);
}
}

@ -10,9 +10,13 @@ import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* *
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/ */
public class Imager { public class ImageUtil {
private final static Map<String, BufferedImage> cache = new HashMap(); private final static Map<String, BufferedImage> cache = new HashMap();

@ -3,6 +3,12 @@ package com.example.jmacro.wjdr.util;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
/**
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class Logger { public class Logger {
private static boolean isDebug = false; private static boolean isDebug = false;

@ -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 { public class ResourceUtil extends cn.hutool.core.io.resource.ResourceUtil {

@ -9,12 +9,12 @@
<HBox alignment="CENTER_LEFT" prefHeight="40.0" prefWidth="400.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <HBox alignment="CENTER_LEFT" prefHeight="40.0" prefWidth="400.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children> <children>
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="40.0" prefWidth="60.0" text="任务" /> <Label alignment="CENTER" contentDisplay="CENTER" prefHeight="40.0" prefWidth="60.0" text="任务" />
<Button mnemonicParsing="false" onMouseClicked="#onStart" prefHeight="30.0" prefWidth="60.0" text="开始"> <Button mnemonicParsing="false" focusTraversable="false" fx:id="start" onMouseClicked="#onStart" prefHeight="30.0" prefWidth="60.0" text="开始">
<HBox.margin> <HBox.margin>
<Insets /> <Insets />
</HBox.margin> </HBox.margin>
</Button> </Button>
<Button mnemonicParsing="false" onMouseClicked="#onStop" prefHeight="30.0" prefWidth="60.0" text="停止"> <Button mnemonicParsing="false" focusTraversable="false" fx:id="stop" onMouseClicked="#onStop" disable="true" prefHeight="30.0" prefWidth="60.0" text="停止">
<HBox.margin> <HBox.margin>
<Insets left="10.0" /> <Insets left="10.0" />
</HBox.margin> </HBox.margin>
@ -25,14 +25,14 @@
<HBox alignment="CENTER_LEFT" prefHeight="40.0" prefWidth="400.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="41.0"> <HBox alignment="CENTER_LEFT" prefHeight="40.0" prefWidth="400.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="41.0">
<children> <children>
<Label alignment="CENTER" contentDisplay="CENTER" prefHeight="40.0" prefWidth="60.0" text="工具" /> <Label alignment="CENTER" contentDisplay="CENTER" prefHeight="40.0" prefWidth="60.0" text="工具" />
<Button mnemonicParsing="false" onMouseClicked="#onCapture" prefHeight="30.0" prefWidth="80.0" text="采集图例"> <Button mnemonicParsing="false" focusTraversable="false" fx:id="capture" onMouseClicked="#onCapture" prefHeight="30.0" prefWidth="60.0" text="采图">
<HBox.margin> <HBox.margin>
<Insets /> <Insets />
</HBox.margin> </HBox.margin>
</Button> </Button>
</children> </children>
</HBox> </HBox>
<Separator opacity="0.5" prefHeight="1.0" prefWidth="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="40.0" /> <Separator opacity="0.5" prefHeight="1.0" prefWidth="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="81.0" />
<GridPane layoutX="71.0" layoutY="139.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="82.0"> <GridPane layoutX="71.0" layoutY="139.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="82.0">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />

Loading…
Cancel
Save

Powered by TurnKey Linux.