diff --git a/legend/城镇.png b/legend/城镇.png deleted file mode 100644 index 0af3413..0000000 Binary files a/legend/城镇.png and /dev/null differ diff --git a/legend/城镇_欢迎回来.png b/legend/城镇_欢迎回来.png new file mode 100644 index 0000000..b44cc74 Binary files /dev/null and b/legend/城镇_欢迎回来.png differ diff --git a/legend/慕慕_工具栏.png b/legend/慕慕_工具栏.png index 99d6d14..ce4ae7d 100644 Binary files a/legend/慕慕_工具栏.png and b/legend/慕慕_工具栏.png differ diff --git a/legend/野外_搜索.png b/legend/野外_搜索.png index 4a889c8..10615e1 100644 Binary files a/legend/野外_搜索.png and b/legend/野外_搜索.png differ diff --git a/src/main/java/com/example/jmacro/wjdr/JMacro.java b/src/main/java/com/example/jmacro/wjdr/JMacro.java index 8980298..7b860ee 100644 --- a/src/main/java/com/example/jmacro/wjdr/JMacro.java +++ b/src/main/java/com/example/jmacro/wjdr/JMacro.java @@ -210,7 +210,7 @@ public class JMacro { // 进行全像素匹配 double similar = Imager.calcSimilar(x - xMin, y - yMin, pic.getHeight(), pic.getWidth(), screenData, picData); if (similar >= minSimilar) { - return new ScreenRect(x - xMin, y - yMin, x + pic.getWidth(), y + pic.getHeight()); + return new ScreenRect(x - xMin, y - yMin, x + pic.getWidth(), y + pic.getHeight(), similar); } } } @@ -237,7 +237,7 @@ public class JMacro { } public ScreenRect waitAndFindPic(ScreenRect rect, File file, double minSimilar) { - return waitAndFindPic(rect, file, minSimilar, 20, TimeUnit.SECONDS); + return waitAndFindPic(rect, file, minSimilar, 10, TimeUnit.SECONDS); } public ScreenRect waitAndFindPic(ScreenRect rect, File file, double minSimilar, long time, TimeUnit unit) { diff --git a/src/main/java/com/example/jmacro/wjdr/Main.java b/src/main/java/com/example/jmacro/wjdr/Main.java index 839acca..e4333d4 100644 --- a/src/main/java/com/example/jmacro/wjdr/Main.java +++ b/src/main/java/com/example/jmacro/wjdr/Main.java @@ -66,23 +66,27 @@ public class Main { Logger.info("游戏线程启动成功"); // 获取游戏窗口返回 gameScreen = new ScreenRect(); - gameScreen.setLeft(mumu.getLeft() - 190); - gameScreen.setTop(mumu.getTop() - 7); - gameScreen.setRight(mumu.getRight() + 194); - gameScreen.setBottom(mumu.getBottom() + 950); + 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()); } @Override public void run() { // 获取启动图标 + Logger.info("定位启动图标"); ScreenRect launch = jMacro.waitAndFindPic(gameScreen, new File("legend", "启动图标.png"), 0.8, 5, TimeUnit.SECONDS); if (launch != null) { Logger.info("启动图标坐标:", launch.toString()); Logger.info("启动程序"); jMacro.mouseLeftClick(launch); + } else { + Logger.info("启动图标失败,继续定位游戏主界面"); } - Logger.info("扫描游戏主界面:"); + Logger.info("定位游戏主界面"); ScreenRect 城镇 = TaskUtil.timeTask(() -> { while (true) { ScreenRect screenRect1 = locationHome(jMacro, gameScreen); @@ -126,13 +130,22 @@ public class Main { ScreenRect rect = jMacro.findPic(gameScreen, image, 0.95d); if (rect != null) { jMacro.mouseLeftClick(rect); - Logger.info("检测到弹框,关闭弹框"); + Logger.info("检测到广告弹框,关闭弹框"); + } + } + + { // 定位离线收益弹框,关闭弹框 + BufferedImage image = Imager.load(new File("legend", "城镇_欢迎回来.png")); + ScreenRect rect = jMacro.findPic(gameScreen, image, 0.95d); + if (rect != null) { + jMacro.mouseLeftClick(new ScreenPoint(rect.getCenter()[0], rect.getBottom())); + Logger.info("检测到欢迎回来弹框,关闭弹框"); } } { // 定位主程序 - BufferedImage legend = Imager.load(new File("legend", "城镇.png")); - ScreenRect rect = jMacro.findPic(gameScreen, legend, 0.2d); + BufferedImage legend = Imager.load(new File("legend", "城镇_野外.png")); + ScreenRect rect = jMacro.findPic(gameScreen, legend, 0.90d); if (rect != null) { Logger.info("程序主界面已就绪"); return rect; diff --git a/src/main/java/com/example/jmacro/wjdr/base/ScreenRect.java b/src/main/java/com/example/jmacro/wjdr/base/ScreenRect.java index 8339d6e..89309cd 100644 --- a/src/main/java/com/example/jmacro/wjdr/base/ScreenRect.java +++ b/src/main/java/com/example/jmacro/wjdr/base/ScreenRect.java @@ -10,6 +10,11 @@ public class ScreenRect { private int right; private int bottom; + /** + * 相似度 + */ + private double similar; + public ScreenRect() { } @@ -20,6 +25,14 @@ public class ScreenRect { this.bottom = bottom; } + public ScreenRect(int left, int top, int right, int bottom, double similar) { + this.left = left; + this.top = top; + this.right = right; + this.bottom = bottom; + this.similar = similar; + } + public int getLeft() { return left; } diff --git a/src/main/java/com/example/jmacro/wjdr/task/TaskMining.java b/src/main/java/com/example/jmacro/wjdr/task/TaskMining.java index 20e8816..8309dfc 100644 --- a/src/main/java/com/example/jmacro/wjdr/task/TaskMining.java +++ b/src/main/java/com/example/jmacro/wjdr/task/TaskMining.java @@ -1,5 +1,6 @@ package com.example.jmacro.wjdr.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; @@ -18,25 +19,34 @@ public class TaskMining { } public void start() { - Logger.info("自动采矿"); + Logger.info("》》》自动采矿开始》》》"); + + Logger.info("定位【野外】"); ScreenRect 野外 = jMacro.waitAndFindPic(screenRect, new File("legend", "城镇_野外.png"), 0.99); if (野外 == null) { - Logger.error("未检测到【野外】,采矿终止"); + Logger.error("定位【野外】失败,采矿终止"); return; } + Logger.error("定位【野外】成功,{}", 野外.toString()); - Logger.info("城镇_野外坐标:" + 野外.toString()); - Logger.info("进入野外成功"); + Logger.info("点击【野外】,坐标{}", JSONUtil.toJsonStr(野外.getCenter())); jMacro.mouseLeftClick(野外); Logger.info("定位野外按钮成功"); - ScreenRect 野外搜索 = jMacro.waitAndFindPic(screenRect, new File("legend", "野外_搜索.png"), 0.9); + Logger.info("定位资源搜索按钮"); + ScreenRect 野外搜索 = jMacro.waitAndFindPic(screenRect, new File("legend", "野外_搜索.png"), 1); + if (野外搜索 == null) { + Logger.error("未检测到【资源搜索按钮】,采矿终止"); + return; + } + Logger.info("定位资源搜索按钮成功:{}", 野外搜索.toString()); jMacro.mouseLeftClick(野外搜索); String[] types = new String[]{ "生肉", "木材", "煤矿", "铁矿" }; for (String type : types) { + Logger.info("搜索资源【{}】", type); boolean collect = collect(type, 0); if (collect) { // 中断采集 break; @@ -54,7 +64,8 @@ public class TaskMining { Logger.error("未检测到【城镇】,采矿终止"); return; } - Logger.error("采矿完成,返回城镇"); + + Logger.info("》》》自动采矿结束,返回城镇》》》"); } /** @@ -63,7 +74,14 @@ public class TaskMining { * @return 采集是否结束(满队则返回true,接下来的采集也不需要了) */ private boolean collect(String type, int level) { + Logger.info("定位【{}】图标", type); ScreenRect typeRect = jMacro.waitAndFindPic(screenRect, 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); if (level == 0) { @@ -107,7 +125,11 @@ public class TaskMining { return false; } Logger.info("出征{}{}级矿", type, level); - jMacro.mouseLeftClick(采集); + jMacro.mouseLeftClick(出征); return true; } + + public static void main(String[] args) { + + } } 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 919206f..88627de 100644 --- a/src/main/java/com/example/jmacro/wjdr/util/ColorUtil.java +++ b/src/main/java/com/example/jmacro/wjdr/util/ColorUtil.java @@ -24,32 +24,39 @@ public class ColorUtil { double distance = Math.sqrt(diffR + diffG + diffB); // 计算两个颜色之间的相似度(距离越小,相似度越高) - double similarity = 1 - distance / Math.sqrt(3 * 255 * 255); - - return similarity; + return 1 - distance / Math.sqrt(3 * 255 * 255); } public static boolean isSimilar(int colorInt1, int colorInt2) { // 透明色认为相似 - if ("ffffff".equals(Integer.toHexString(colorInt1))) { + if ((colorInt1>>24 & 0xff )== 0) { return true; } - if ("ffffff".equals(Integer.toHexString(colorInt2))) { + // 图例中的透明色认为相似 + if ((colorInt2>>24 & 0xff )== 0) { return true; } - return calculateSimilarity(colorInt1, colorInt2) > 0.90d; + return calculateSimilarity(colorInt1, colorInt2) > 0.95d; } public static void main(String[] args) { - BufferedImage image = Imager.load(new File("legend", "首页_广告关闭按钮 - 副本.png")); - int[][] imageRGB = Imager.getImageRGB(image); - - - int color1 = 0xffffff; // 白色 - int color2 = 0xfefefe; // 非常接近白色的颜色 - - double similarity = calculateSimilarity(color1, color2); - System.out.println("Similarity: " + similarity); // 输出相似度 +// BufferedImage legend = Imager.load(new File("legend", "未标题-1.png")); +// int[][] imageRGB = Imager.getImageRGB(legend); +// for (int[] ints : imageRGB) { +// +// for (int anInt : ints) { +// +// int alpha = anInt>>24 & 0xff; +// System.out.println("alpha="+alpha); +// System.out.println(Integer.toHexString(anInt)); +// } +// } +// +// int color1 = 0xffffff; // 白色 +// int color2 = 0xfefefe; // 非常接近白色的颜色 +// +// double similarity = calculateSimilarity(color1, color2); +// System.out.println("Similarity: " + similarity); // 输出相似度 } } diff --git a/src/main/java/com/example/jmacro/wjdr/util/Imager.java b/src/main/java/com/example/jmacro/wjdr/util/Imager.java index c0dbf93..6efdd1d 100644 --- a/src/main/java/com/example/jmacro/wjdr/util/Imager.java +++ b/src/main/java/com/example/jmacro/wjdr/util/Imager.java @@ -2,7 +2,6 @@ package com.example.jmacro.wjdr.util; import cn.hutool.core.img.ImgUtil; -import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.util.ArrayList; @@ -63,19 +62,16 @@ public class Imager { public static int[][] getImageRGB(BufferedImage bfImage) { int width = bfImage.getWidth(); int height = bfImage.getHeight(); - boolean b = bfImage.getColorModel().hasAlpha(); int[][] result = new int[width][height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { // 对某个像素点的RGB编码并存入数据库 - int rgb = bfImage.getRGB(x, y); - result[x][y] = rgb & 0xFFFFFF; -// System.out.println(Integer.toHexString(rgb)); -// System.out.println(alpha); - // 单独获取每一个像素点的Red,Green,和Blue的值。 - // int r = (bfImage.getRGB(x, y) & 0xFF0000) >> 16; - // int g = (bfImage.getRGB(x, y) & 0xFF00) >> 8; - // int b = bfImage.getRGB(x, y) & 0xFF; + result[x][y] = bfImage.getRGB(x, y); + // 单独获取每一个像素点的Alpha, Red,Green,和Blue的值。 + // int a = rgb>>24 & 0xff; + // int r = rgb>>16 & 0xff; + // int g = rgb>>8 & 0xff; + // int b = rgb & 0xff; } } return result; 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 8b305d1..85749b6 100644 --- a/src/main/java/com/example/jmacro/wjdr/util/Logger.java +++ b/src/main/java/com/example/jmacro/wjdr/util/Logger.java @@ -1,5 +1,6 @@ package com.example.jmacro.wjdr.util; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; public class Logger { @@ -12,16 +13,16 @@ public class Logger { public static void debug(String log, Object... arg) { if (isDebug) { - System.out.println(StrUtil.format(log, arg)); + System.out.println(DateUtil.date() + " " + StrUtil.format(log, arg)); } } public static void info(String log, Object... arg) { - System.out.println(StrUtil.format(log, arg)); + System.out.println(DateUtil.date() + " " + StrUtil.format(log, arg)); } public static void error(String log, Object... arg) { - System.err.println(StrUtil.format(log, arg)); + System.err.println(DateUtil.date() + " " + StrUtil.format(log, arg)); } }