From 350d9c1180f093cbae56fdd824935cca35a20afb Mon Sep 17 00:00:00 2001 From: wangbing Date: Tue, 27 Aug 2024 15:51:39 +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 - .../java/com/example/jmacro/wjdr/JMacro.java | 74 ++++-- .../com/example/jmacro/wjdr/MainTask.java | 7 +- .../com/example/jmacro/wjdr/util/Capture.java | 222 +++++++++++++++--- 4 files changed, 240 insertions(+), 64 deletions(-) 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/src/main/java/com/example/jmacro/wjdr/JMacro.java b/src/main/java/com/example/jmacro/wjdr/JMacro.java index 764e4f4..2c01dee 100644 --- a/src/main/java/com/example/jmacro/wjdr/JMacro.java +++ b/src/main/java/com/example/jmacro/wjdr/JMacro.java @@ -25,10 +25,6 @@ import java.util.concurrent.TimeUnit; */ public class JMacro { - public static void main(String[] args) throws AWTException { - System.out.println("L0,0-A.png".matches("L[0-9]+,[0-9]+-[\\S\\s]+")); - } - /** * 机器人操作实例 */ @@ -117,9 +113,9 @@ public class JMacro { */ public void mouseLeftClick(ScreenPoint rect) { mouseMove(rect); - robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); waitTap(); - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); } /** @@ -151,11 +147,11 @@ public class JMacro { public void mouseLeftDrag(ScreenPoint start, ScreenPoint end, boolean smooth) { mouseMove(start, smooth); waitTap(); - robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); waitTap(); mouseMove(end, smooth); waitTap(); - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); } /** @@ -178,11 +174,11 @@ public class JMacro { public void mouseRightDrag(ScreenPoint start, ScreenPoint end, boolean smooth) { mouseMove(start, smooth); waitTap(); - robot.mousePress(InputEvent.BUTTON3_MASK); + robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); waitTap(); mouseMove(end, smooth); waitTap(); - robot.mouseRelease(InputEvent.BUTTON3_MASK); + robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); } /** @@ -194,9 +190,9 @@ public class JMacro { waitTap(); robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]); waitTap(); - robot.mousePress(InputEvent.BUTTON2_MASK); + robot.mousePress(InputEvent.BUTTON2_DOWN_MASK); waitTap(); - robot.mouseRelease(InputEvent.BUTTON2_MASK); + robot.mouseRelease(InputEvent.BUTTON2_DOWN_MASK); } /** @@ -208,9 +204,9 @@ public class JMacro { waitTap(); robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]); waitTap(); - robot.mousePress(InputEvent.BUTTON3_MASK); + robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); waitTap(); - robot.mouseRelease(InputEvent.BUTTON3_MASK); + robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); } /** @@ -222,13 +218,13 @@ public class JMacro { waitTap(); robot.mouseMove(rect.getCenter()[0], rect.getCenter()[1]); waitTap(); - robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); robot.delay(100); - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); robot.delay(100); - robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); robot.delay(100); - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); } /** @@ -406,12 +402,12 @@ public class JMacro { /** * 匹配图片 * - * @param point 坐标原点(左上角) + * @param rect 程序窗口(参照系) * @param file 图例 * @param minSimilar 最低相似度 * @return 匹配图片 */ - public ScreenRect matchPic(ScreenPoint point, File file, double minSimilar) { + public ScreenRect matchPic(ScreenRect rect, File file, double minSimilar) { String name = file.getName(); int offsetX = 0; int offsetY = 0; @@ -420,8 +416,8 @@ public class JMacro { offsetY = Convert.toInt(ReUtil.get("L[0-9]+,([0-9]+)-[\\S\\s]+", name, 1), 0); } ScreenRect screenRect = new ScreenRect(); - screenRect.setLeft(point.getX() + offsetX); - screenRect.setTop(point.getY() + offsetY); + 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()); @@ -429,15 +425,43 @@ public class JMacro { return findPic(screenRect, image, minSimilar); } + /** + * 匹配图片 + * + * @param rect 程序窗口(参照系) + * @param legendName 图例名称 + * @param minSimilar 最低相似度 + * @return 匹配图片 + */ + public ScreenRect matchPic(ScreenRect rect, String legendName, double minSimilar) { + return matchPic(rect, new File(legend, legendName), minSimilar); + } + /** * 是否匹配图片 * - * @param point 坐标原点(左上角) + * @param rect 程序窗口(参照系) * @param file 图例 * @param minSimilar 最低相似度 * @return 匹配图片 */ - public boolean isMatchPic(ScreenPoint point, File file, double minSimilar) { - return matchPic(point, file, minSimilar) != null; + public boolean isMatchPic(ScreenRect rect, File file, double minSimilar) { + return matchPic(rect, file, minSimilar) != null; } + + /** + * 是否匹配图片 + * + * @param rect 程序窗口(参照系) + * @param legendName 图例名称 + * @param minSimilar 最低相似度 + * @return 匹配图片 + */ + public boolean isMatchPic(ScreenRect rect, String legendName, double minSimilar) { + if (!legendName.endsWith(".png")) { + legendName = legendName + ".png"; + } + return matchPic(rect, new File(legend, legendName), minSimilar) != null; + } + } diff --git a/src/main/java/com/example/jmacro/wjdr/MainTask.java b/src/main/java/com/example/jmacro/wjdr/MainTask.java index c5529ef..c722d77 100644 --- a/src/main/java/com/example/jmacro/wjdr/MainTask.java +++ b/src/main/java/com/example/jmacro/wjdr/MainTask.java @@ -3,7 +3,6 @@ package com.example.jmacro.wjdr; import cn.hutool.core.date.DateUtil; import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.util.RandomUtil; -import com.example.jmacro.wjdr.base.ScreenPoint; import com.example.jmacro.wjdr.base.ScreenRect; import com.example.jmacro.wjdr.task.TaskMining; import com.example.jmacro.wjdr.util.Imager; @@ -46,7 +45,7 @@ public class MainTask { Logger.setDebug(true); Logger.info("初始化脚本"); - JMacro jMacro = new JMacro(); + JMacro jMacro = new JMacro(new File("legend")); while (true) { ThreadUtil.sleep(1000); @@ -165,7 +164,7 @@ public class MainTask { } { // 定位离线收益弹框,关闭弹框 - ScreenRect rect = jMacro.matchPic(new ScreenPoint(gameScreen.getLeft(),gameScreen.getTop()), new File("legend", "L204,734-城镇_离线收益.png"), 0.9); + ScreenRect rect = jMacro.matchPic(gameScreen, new File("legend", "L204,734-城镇_离线收益.png"), 0.9); if (rect != null) { jMacro.mouseLeftClick(rect); Logger.info("检测到离线收益弹框,关闭弹框"); @@ -173,7 +172,7 @@ public class MainTask { } { // 定位主程序 - ScreenRect rect = jMacro.matchPic(new ScreenPoint(gameScreen.getLeft(),gameScreen.getTop()), new File("legend", "L444,888-野外.png"), 0.9); + ScreenRect rect = jMacro.matchPic(gameScreen, new File("legend", "L444,888-野外.png"), 0.9); if (rect != null) { Logger.info("程序主界面已就绪"); return rect; 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 a9dcf38..d987e83 100644 --- a/src/main/java/com/example/jmacro/wjdr/util/Capture.java +++ b/src/main/java/com/example/jmacro/wjdr/util/Capture.java @@ -1,34 +1,97 @@ package com.example.jmacro.wjdr.util; +import cn.hutool.core.img.ImgUtil; import cn.hutool.log.StaticLog; -import com.melloware.jintellitype.HotkeyListener; -import com.melloware.jintellitype.JIntellitype; import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.*; +import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.awt.image.BufferedImage; import java.io.File; +import java.util.prefs.Preferences; /** * 辅助截屏工具 */ public class Capture extends JFrame { - // 退出 - private final int KEY_MARK_ESC = 1; + private static final String LAST_PATH = "capture.last.path"; + + /** + * 参照原点x坐标 + */ + private int originX; + /** + * 参照原点y坐标 + */ + private int originY; + + /** + * 全屏幕截图 + */ + private BufferedImage capture; + + /** + * 背景蒙层 + */ + private Color mask = new Color(0, 0, 0, 0.2f); + + /** + * 聚焦框线条 + */ + private Stroke focusWindow = new BasicStroke(1.0f); + + /** + * 屏幕截图区域起始坐标 + */ + private Point start = new Point(0, 0); + + /** + * 屏幕截图区域结束坐标 + */ + private Point end = new Point(0, 0); + + private Preferences preferences; + + /** + * 有参照原点的构造器 + * + * @param originX 原点x + * @param originY 原点y + * @throws AWTException + */ + public Capture(int originX, int originY, File path) throws AWTException { + this(); + this.originX = originX; + this.originY = originY; + this.preferences.put(LAST_PATH, path.isDirectory() ? path.getAbsolutePath() : path.getParent()); + } - public Capture() { + public Capture() throws AWTException { init(); } - private void init() { + private void init() throws AWTException { setExtendedState(Frame.MAXIMIZED_BOTH); setLocation(0, 0);//位置 setUndecorated(true); setAlwaysOnTop(true); - setBackground(new Color(0, 0, 0, 0.4f)); + setBackground(mask); + + // 初始化偏好设置 + preferences = Preferences.userRoot().node(this.getClass().getName()); + + // 获取屏幕截图 + Robot robot = new Robot(); + Toolkit tk = Toolkit.getDefaultToolkit(); + capture = robot.createScreenCapture(new Rectangle(0, 0, tk.getScreenSize().width, tk.getScreenSize().height)); // 监听窗口关闭 addWindowListener(new WindowAdapter() { @@ -40,46 +103,137 @@ public class Capture extends JFrame { } }); - // 添加热键 - JIntellitype.getInstance().registerHotKey(KEY_MARK_ESC, 0, KeyEvent.VK_ESCAPE); - JIntellitype.getInstance().addHotKeyListener(hotkeyListener); + addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + super.mousePressed(e); + start.setLocation(e.getX(), e.getY()); + end.setLocation(e.getX(), e.getY()); + Logger.info("起始坐标:{}", start); + repaint(); + } - setVisible(true); - } + @Override + public void mouseReleased(MouseEvent e) { + super.mouseReleased(e); + end.setLocation(e.getX(), e.getY()); + Logger.info("结束坐标:{}", end); + save(); + } + }); - private final HotkeyListener hotkeyListener = new HotkeyListener() { - @Override - public void onHotKey(int i) { - switch (i) { - case KEY_MARK_ESC: { - StaticLog.info("exit."); - JIntellitype.getInstance().unregisterHotKey(KEY_MARK_ESC); - JIntellitype.getInstance().removeHotKeyListener(hotkeyListener); - close(); + addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseDragged(MouseEvent e) { + super.mouseDragged(e); + end.setLocation(e.getX(), e.getY()); + repaint(); + } + }); + + addKeyListener(new KeyAdapter() { + + @Override + public void keyReleased(KeyEvent e) { + switch (e.getKeyCode()) { + case KeyEvent.VK_ESCAPE: { + StaticLog.info("exit."); + close(); + } + break; } - break; + } - } - }; + }); + setVisible(true); + } - public void close() { - // 关闭应用时要释放资源 - dispose(); - System.exit(0); + @Override + public void doLayout() { + super.doLayout(); } + @Override + public void paint(Graphics g) { + super.paint(g); + Graphics2D g2d = (Graphics2D) g; + g2d.drawImage(capture, 0, 0, capture.getWidth(), capture.getHeight(), this); + + // 在背景图上加个蒙层 + g2d.setColor(mask); + g2d.fillRect(0, 0, capture.getWidth(), capture.getHeight()); + + int w = getCaptureWidth(); + int h = getCaptureHeight(); + if (w > 0 && h > 0) { + g2d.setStroke(focusWindow); + g2d.setColor(Color.green); + g2d.drawRect(getCaptureX(), getCaptureY(), w, h); + } + } - public static void main(String[] args) { - int originX = 0; - int originY = 0; + public int getCaptureX() { + return (int) Math.min(start.getX(), end.getX()) + originX; + } - File legend = new File("legend"); + public int getCaptureY() { + return (int) Math.min(start.getY(), end.getY()) + originY; + } + public int getCaptureWidth() { + return (int) Math.abs(start.getX() - end.getX()); + } - System.out.println("请将鼠标移动截图位置的左上角,并且按下Ctrl"); + public int getCaptureHeight() { + return (int) Math.abs(start.getY() - end.getY()); + } + public void save() { + // 上一次保存目录 + String lastPath = preferences.get(LAST_PATH, ""); + // 默认文件名 + String prefix = "L" + getCaptureX() + "," + getCaptureY() + "-"; + String filename = prefix + System.currentTimeMillis() + ".png"; + + + JFileChooser jFileChooser = new JFileChooser(); + jFileChooser.setFileFilter(new FileNameExtensionFilter("png", "png")); + jFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + jFileChooser.setCurrentDirectory(new File(lastPath)); + jFileChooser.setSelectedFile(new File(filename)); + int returnVal = jFileChooser.showSaveDialog(this); + if (returnVal == JFileChooser.APPROVE_OPTION) { + // 默认文件 + File file = jFileChooser.getSelectedFile(); + // 修正坐标 + filename = prefix + file.getName().replaceAll("L[0-9]+,[0-9]+-", ""); + file = new File(file.getParent(), filename); + + Logger.info("保存路径" + file); + ImgUtil.cut(capture, file, new Rectangle(getCaptureX(), getCaptureY(), getCaptureWidth(), getCaptureHeight())); + + preferences.put(LAST_PATH, file.getParent()); + Logger.info("保存目录" + file.getParent()); + Logger.info("保存地址" + file); + } + close(); + } + + public void close() { + // 关闭应用时要释放资源 + dispose(); + System.exit(0); + } - Capture capture = new Capture(); + /** + * 工具入口 + * + * @param args + * @throws AWTException + */ + public static void main(String[] args) throws AWTException { + // 运行坐标图例截图工具 + new Capture(5, 5, new File("legend")); } }