From 4865efd9fb1da6bee7490cd4c8e09c75b8b1775c Mon Sep 17 00:00:00 2001 From: wangbing Date: Mon, 26 Aug 2024 10:00:15 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E5=A4=87=E4=BB=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/encodings.xml | 1 - pom.xml | 2 +- .../com/example/jmacro/wjdr/JGameThread.java | 13 --- .../java/com/example/jmacro/wjdr/JMacro.java | 96 ++++++++++++------- .../com/example/jmacro/wjdr/JMacroThread.java | 13 +++ .../jmacro/wjdr/{Main.java => MainTask.java} | 89 +++++++++++------ .../example/jmacro/wjdr/util/TaskUtil.java | 4 +- 7 files changed, 136 insertions(+), 82 deletions(-) delete mode 100644 src/main/java/com/example/jmacro/wjdr/JGameThread.java create mode 100644 src/main/java/com/example/jmacro/wjdr/JMacroThread.java rename src/main/java/com/example/jmacro/wjdr/{Main.java => MainTask.java} (71%) diff --git a/.idea/encodings.xml b/.idea/encodings.xml index 63574ec..0e1c064 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -2,7 +2,6 @@ - \ No newline at end of file diff --git a/pom.xml b/pom.xml index f84cbf8..3bc5a94 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ jar starter-jmacro-wjdr - project for Spring Boot + project for jmacro UTF-8 diff --git a/src/main/java/com/example/jmacro/wjdr/JGameThread.java b/src/main/java/com/example/jmacro/wjdr/JGameThread.java deleted file mode 100644 index 1282a5f..0000000 --- a/src/main/java/com/example/jmacro/wjdr/JGameThread.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.example.jmacro.wjdr; - -import cn.hutool.core.date.DateTime; -import cn.hutool.core.date.DateUtil; - -public abstract class JGameThread implements Runnable { - - protected JMacro jMacro; - - public JGameThread(JMacro jMacro) { - this.jMacro = jMacro; - } -} diff --git a/src/main/java/com/example/jmacro/wjdr/JMacro.java b/src/main/java/com/example/jmacro/wjdr/JMacro.java index 7b860ee..68805de 100644 --- a/src/main/java/com/example/jmacro/wjdr/JMacro.java +++ b/src/main/java/com/example/jmacro/wjdr/JMacro.java @@ -5,7 +5,6 @@ import com.example.jmacro.wjdr.base.ScreenPoint; import com.example.jmacro.wjdr.base.ScreenRect; import com.example.jmacro.wjdr.util.ColorUtil; import com.example.jmacro.wjdr.util.Imager; -import com.example.jmacro.wjdr.util.Logger; import com.example.jmacro.wjdr.util.TaskUtil; import java.awt.*; @@ -15,47 +14,62 @@ import java.io.File; import java.util.concurrent.TimeUnit; /** - * Java脚本 + * Java脚本精灵 */ public class JMacro { + public static void main(String[] args) throws AWTException { + JMacro jMacro = new JMacro(); + jMacro.mouseMove(new ScreenPoint(100, 100)); + } + /** - * 机器人 + * 机器人操作实例 */ - private Robot robot; - - private JGameThread thread; + private final Robot robot; public JMacro() throws AWTException { this.robot = new Robot(); } - public JGameThread getThread() { - return thread; - } - - public void setThread(JGameThread thread) { - this.thread = thread; + /** + * 鼠标移动 + * + * @param point 坐标点 + */ + public void mouseMove(ScreenPoint point) { + mouseMove(point, false); } /** * 鼠标移动 * - * @param point 屏幕点 + * @param point 坐标点 + * @param smooth 平滑移动 */ - public void mouseMove(ScreenPoint point) { - // 获取当前鼠标位置 - Point mousePoint = MouseInfo.getPointerInfo().getLocation(); - - int startX = mousePoint.x; - int startY = mousePoint.y; - // 分10次移动到指定点 - for (int i = 1; i <= 10; i++) { - float d = i / 10f; - int dx = (int) (startX + (point.getX() - startX) * d); - int dy = (int) (startY + (point.getY() - startY) * d); - robot.mouseMove(dx, dy); - robot.delay(RandomUtil.randomInt(30, 70)); + public void mouseMove(ScreenPoint point, boolean smooth) { + if (smooth) { + // 获取当前鼠标位置 + Point mousePoint = MouseInfo.getPointerInfo().getLocation(); + + int startX = mousePoint.x; + int startY = mousePoint.y; + + // 求两点距离 + double absX = Math.abs(startX - point.getX()); + double absY = Math.abs(startY - point.getY()); + double absZ = Math.sqrt(Math.pow(absX, 2) + Math.pow(absY, 2)); + int times = (int) (absZ / 30 + (absZ % 30 > 0 ? 1 : 0)); + // 分times次移动到指定点 + for (int i = 1; i <= times; i++) { + float d = i * 1.0f / times; + int dx = (int) (startX + (point.getX() - startX) * d); + int dy = (int) (startY + (point.getY() - startY) * d); + robot.mouseMove(dx, dy); + robot.delay(RandomUtil.randomInt(5, 20)); + } + } else { + robot.mouseMove(point.getX(), point.getY()); } } @@ -126,7 +140,6 @@ public class JMacro { robot.mouseRelease(InputEvent.BUTTON1_MASK); } - /** * 捕获指定区域屏幕 */ @@ -136,8 +149,6 @@ public class JMacro { /** * 获取屏幕范围 - * - * @return */ public ScreenRect getScreenRect() { Toolkit tk = Toolkit.getDefaultToolkit(); @@ -149,7 +160,7 @@ public class JMacro { * * @param pic 图片 * @param minSimilar 最低相似度 - * @return 匹配的图片区域 + * @return 匹配图片区域 */ public ScreenRect findPic(File pic, double minSimilar) { return findPic(getScreenRect(), Imager.load(pic), minSimilar); @@ -160,7 +171,7 @@ public class JMacro { * * @param pic 图片 * @param minSimilar 最低相似度 - * @return 匹配的图片区域 + * @return 匹配图片区域 */ public ScreenRect findPic(BufferedImage pic, double minSimilar) { return findPic(getScreenRect(), pic, minSimilar); @@ -172,7 +183,7 @@ public class JMacro { * @param pic 参考图 * @param screenRect 查找范围 * @param minSimilar 相似度 - * @return + * @return 匹配图片区域 */ public ScreenRect findPic(ScreenRect screenRect, BufferedImage pic, double minSimilar) { // 当查找区域比图片还小时,直接返回失败 @@ -220,26 +231,41 @@ public class JMacro { public void waitTap() { int i = RandomUtil.randomInt(100, 200); -// Logger.info("随机等待{}ms", i); robot.delay(i); } public void waitNormal() { int i = RandomUtil.randomInt(500, 1500); -// Logger.info("随机等待{}ms", i); robot.delay(i); } public void waitLong() { int i = RandomUtil.randomInt(2000, 5000); -// Logger.info("随机等待{}ms", i); robot.delay(i); } + /** + * 等待并查找图片 + * + * @param rect 查找区域 + * @param file 图例 + * @param minSimilar 最低相似度 + * @return 匹配图片区域 + */ public ScreenRect waitAndFindPic(ScreenRect rect, File file, double minSimilar) { return waitAndFindPic(rect, file, minSimilar, 10, TimeUnit.SECONDS); } + /** + * 等待并查找图片 + * + * @param rect 查找区域 + * @param file 图例 + * @param minSimilar 最低相似度 + * @param time 最长等待时间 + * @param unit 最长等待时间单位 + * @return 匹配图片区域 + */ public ScreenRect waitAndFindPic(ScreenRect rect, File file, double minSimilar, long time, TimeUnit unit) { return TaskUtil.timeTask(() -> { while (true) { diff --git a/src/main/java/com/example/jmacro/wjdr/JMacroThread.java b/src/main/java/com/example/jmacro/wjdr/JMacroThread.java new file mode 100644 index 0000000..884664b --- /dev/null +++ b/src/main/java/com/example/jmacro/wjdr/JMacroThread.java @@ -0,0 +1,13 @@ +package com.example.jmacro.wjdr; + +/** + * 脚本执行线程 + */ +public abstract class JMacroThread implements Runnable { + + protected JMacro jMacro; + + public JMacroThread(JMacro jMacro) { + this.jMacro = jMacro; + } +} diff --git a/src/main/java/com/example/jmacro/wjdr/Main.java b/src/main/java/com/example/jmacro/wjdr/MainTask.java similarity index 71% rename from src/main/java/com/example/jmacro/wjdr/Main.java rename to src/main/java/com/example/jmacro/wjdr/MainTask.java index e4333d4..d3c99a4 100644 --- a/src/main/java/com/example/jmacro/wjdr/Main.java +++ b/src/main/java/com/example/jmacro/wjdr/MainTask.java @@ -13,65 +13,86 @@ import com.example.jmacro.wjdr.util.TaskUtil; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; +import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; -public class Main { +public class MainTask { - public static void main(String[] args) throws AWTException { - Logger.info("启动脚本"); + /** + * 脚本线程 + */ + private static ScheduledFuture schedule; + + /** + * 工作开始时间 + */ + private final String workStart = "08:00:00"; + + /** + * 工作结束时间 + */ + private final String workEnd = "24:00:00"; + + private boolean noDelay = true; + + public void start() throws AWTException { Logger.setDebug(true); - boolean first = true; - Logger.info("初始化脚本..."); + Logger.info("初始化脚本"); JMacro jMacro = new JMacro(); - String workStart = "08:00:00"; - String workEnd = "24:00:00"; - while (true) { ThreadUtil.sleep(1000); - // 首次启动直接执行游戏线程 - if (first) { - first = false; - jMacro.setThread(new GameThread(jMacro)); - TaskUtil.schedule(jMacro.getThread(), 0, TimeUnit.SECONDS); + // 立即执行 + if (noDelay) { + if (schedule != null) { + schedule.cancel(true); + } + + noDelay = false; + Logger.info("启动线程"); + schedule = TaskUtil.schedule(new MacroThread(jMacro), 0, TimeUnit.SECONDS); continue; } - if (jMacro.getThread() != null) { -// Logger.debug("待机中..."); + if (schedule != null) { continue; } if (DateUtil.isIn(DateUtil.date(), DateUtil.parse(workStart), DateUtil.parse(workEnd))) { - int anInt = RandomUtil.randomInt(5, 20); - Logger.info("等待{}分钟后,重新启动游戏线程", anInt); - jMacro.setThread(new GameThread(jMacro)); - TaskUtil.schedule(jMacro.getThread(), anInt, TimeUnit.MINUTES); + int delay = RandomUtil.randomInt(5, 20); + Logger.info("等待{}分钟后,重新启动线程", delay); + schedule = TaskUtil.schedule(new MacroThread(jMacro), delay, TimeUnit.MINUTES); } } } - public static class GameThread extends JGameThread { + /** + * 主线程实现 + */ + public static class MacroThread extends JMacroThread { + /** + * 主屏幕区域 + */ private ScreenRect gameScreen; - public GameThread(JMacro jMacro) { + public MacroThread(JMacro jMacro) { super(jMacro); // 定位mumu bar ScreenRect mumu = locationMuMu(jMacro); if (mumu == null) { throw new IllegalStateException("未检测到MuMu,请开启MuMu模拟器"); } - Logger.info("游戏线程启动成功"); - // 获取游戏窗口返回 + Logger.info("线程启动成功"); + // 获取窗口返回 gameScreen = new ScreenRect(); gameScreen.setLeft(mumu.getLeft() - 428); gameScreen.setTop(mumu.getTop() - 8); gameScreen.setRight(mumu.getRight()); gameScreen.setBottom(mumu.getBottom() + 951); - Logger.info("游戏窗口位置:" + gameScreen.toString()); - Logger.info("游戏窗口大小:{}x{}", gameScreen.getRight()- gameScreen.getLeft(),gameScreen.getBottom()- gameScreen.getTop()); + Logger.info("窗口位置:" + gameScreen.toString()); + Logger.info("窗口大小:{}x{}", gameScreen.getRight() - gameScreen.getLeft(), gameScreen.getBottom() - gameScreen.getTop()); } @Override @@ -84,9 +105,9 @@ public class Main { Logger.info("启动程序"); jMacro.mouseLeftClick(launch); } else { - Logger.info("启动图标失败,继续定位游戏主界面"); + Logger.info("启动图标失败,继续定位主界面"); } - Logger.info("定位游戏主界面"); + Logger.info("定位主界面"); ScreenRect 城镇 = TaskUtil.timeTask(() -> { while (true) { ScreenRect screenRect1 = locationHome(jMacro, gameScreen); @@ -98,12 +119,13 @@ public class Main { }, 30 * 1000, TimeUnit.MILLISECONDS); if (城镇 == null) { - jMacro.setThread(null); - Logger.info("未扫描到游戏主界:退出线程"); + schedule.cancel(true); + schedule = null; + Logger.info("未扫描到主界面:退出线程"); return; } - Logger.info("进入游戏主界面"); + Logger.info("进入主界面"); Logger.info("进入任务线程"); TaskUtil.timeTask((Runnable) () -> { @@ -165,4 +187,11 @@ public class Main { public static void taskMineAttack(JMacro jMacro, ScreenRect screenRect) { } + + /** + * 启动入口 + */ + public static void main(String[] args) throws AWTException { + new MainTask().start(); + } } diff --git a/src/main/java/com/example/jmacro/wjdr/util/TaskUtil.java b/src/main/java/com/example/jmacro/wjdr/util/TaskUtil.java index e2fe93e..8eff4a3 100644 --- a/src/main/java/com/example/jmacro/wjdr/util/TaskUtil.java +++ b/src/main/java/com/example/jmacro/wjdr/util/TaskUtil.java @@ -34,11 +34,11 @@ public class TaskUtil extends CronUtil { * @param runnable Runnable任务 * @param delay 延时(ms) */ - public static void schedule(Runnable runnable, long delay, TimeUnit unit) { + public static ScheduledFuture schedule(Runnable runnable, long delay, TimeUnit unit) { if (service == null) { service = new ScheduledThreadPoolExecutor(1); } - service.schedule(runnable, delay, unit); + return service.schedule(runnable, delay, unit); } /**