• Java实现自动玩王铲铲的致富之路小程序游戏


    前言

    最近坐车刷到一个小游戏,王铲铲的致富之路,就是一个人拿着铁锹,背着背篓挖地,随着级别的提升,可以雇佣更多人一起挖地,挖出的土可以出售给工厂获得收益(游戏货币),货币可以用来升级人物,升级仓库,升级工厂,升级运输队,后面还可以获得一辆挖掘机,加快挖掘速度。
    在这里插入图片描述

    游戏中挖掘机需要加油,这个只能每天领取5桶,再需要加油就得看视频广告来获得了,虚拟货币无法购买。挖掘可以加速,但是也需要看视频广告,看完基本只能看着大家挖土,久而久之,等待很乏味,于是就有了编写个辅助自己玩的想法。

    基本思路就是Java调用adb连接手机,查看对应按钮的位置,模拟点击加延时操作,逐渐实现了,连续加速功能,加速结束后,接着点击加速,在等待加速的过程中会出现挖出的古董,可以直接点击捐赠,挖出的土疙瘩,直接关闭页面,这样不影响游戏的流程。

    硬件方面:android系统手机一个,电脑(Windows,Linux,Mac均可)一个,usb调试线(wifi也行)
    软件方面:jdk8,android8.0,Ubuntu20.04
    前置知识:什么是adb,如何使用adb命令

    1.调用adb命令截屏并读取到电脑

    不啰嗦了,直接上代码了。这个类有Java版,参考:链接: Java 调用 ADB 命令截取安卓手机屏幕到PC,详细代码见文章最后。

    核心原理

    adb shell screencap -p /sdcard/scrsnp.png
    # 截屏用时:3231 ms
    adb pull /sdcard/scrsnp.png ./capture/a.png
    # pull文件用时:215 ms
    adb shell rm /sdcard/scrsnp.png
    #删除sd卡文件
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.打开游戏,提前截几个图,准备好相应的按钮位置颜色

      这个步骤,打开游戏,截屏即可,主要关注右下角的超级加速按钮,广告页面的关闭按钮,底部中间的关闭按钮,古董捐赠按钮,等等按钮的位置,可以参考代码。

      为了方便查找触摸坐标,开启了触摸位置显示。
    在这里插入图片描述

    3.根据图片路径和x,y坐标,读取图片相应位置的颜色值

    void getColor() {
            try {
                // 读取图片文件
                BufferedImage image = ImageIO.read(
                        new File("/home/xxx/图片/wcc/screenshotwcc02.png")
                );
    
                // 定义需要提取颜色的坐标
                int x = 302;
                int y = 314;
    
                // 提取坐标颜色
                int color = image.getRGB(x, y);
    
                // 打印颜色值
                System.out.println("The color at (" + x + ", " + y + ") is: " + color);
    
                int alpha = (color >> 24) & 0xff;
                int red = (color >> 16) & 0xff;
                int green = (color >> 8) & 0xff;
                int blue = color & 0xff;
                System.out.printf("argb:%x,%x,%x,%x,", alpha, red, green, blue);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    4.根据颜色值判断如何进行触摸操作

    核心原理如下,Java代码在后面

    adb shell input tap $x $y  
    
    • 1

    5.程序效果分析

    把这2个类复制到IDE中,运行即可实现功能。

    • 经过实际测试发现,基于固定坐标颜色判定的辅助方式,在关闭土疙瘩和捐赠挖掘到的古董方面还是很稳定的,基本没有遇到错误。

    • 然而在点击加速的时候就很不靠谱了,首先广告有多种:视频、直播、小说;有的时候是分享,并不是看广告,这块处理起来比较麻烦。

    • 有条件的可以试试图片文字识别,这样更稳定一些,还有不太好判断游戏是否在前台,游戏退后台了,不加判断,容易误触。

    5.存在的问题

      基于颜色识别准确度不可靠,有时候游戏退后台了,程序还在敬业的点击操作,点击位置已经是驴唇不对马嘴了。而且胡乱点击也比较危险。

    6.改进思路

      后续应该改为图片文字识别,借助Tess4J或者百度ai的开放api,这样更加准确和可靠。下面是代码:Wcc.java

      这个类用到了上面的截屏类ScreenCapture.kt。代码比较简陋,基本实现了所需功能,可靠性还有待提升。本文代码取色代码部分参考文心一言。

    package learn;
    
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    
    /**
     * 王铲铲的致富之路Java辅助
     */
    public class Wcc {
    
        Color COLOR_TUGEDA = new Color(0xF0, 0xE1, 0x53);
        Color COLOR_GUDONG = new Color(0xCC, 0x5E, 0x5B);
        Color COLOR_CJJS = new Color(0xE1, 0x90, 0x25);
        Color COLOR_JSLQ = new Color(0x60, 0x34, 0x2c);
        private int c = 0;
    
    
        public static void main(String[] args) {
            Wcc wcc = new Wcc();
            wcc.digHole();
        }
    
        /**
         * 1.检测当前能不能加速,
         * 能
         *   则看广告加速
         * 不能,
         *   看看是图疙瘩还是古董,
         *   土疙瘩
         *     关闭
         *   古董
         *     捐赠
         *
         * 2.if(处理完毕土疙瘩和古董)
         *     查看加速是否结束
         *     没有,继续等待
         *     有,继续加速
         *
         * 3.(每30s检查一次土疙瘩和古董)
         */
        private void digHole() {
        //读取设备,准备adb操作。
            ScreenCapture capture = new ScreenCapture();
            String[] ds = capture.getDevices();
            System.out.println("设备列表容量:" + ds.length);
    
    
            if (ds.length > 0) {
                String model = capture.getModel(ds[0]);
                System.out.println("手机型号:" + model);
    
                while (true) {
                    long beginTime = System.currentTimeMillis();
                    System.out.println("---------------------------------------------");
                    System.out.println("集中火力干事业,把钱花在刀把上");
    
                    System.out.println("第" + (++c) + "次任务开始:" + getDateTime());
                    capture.snapshot(ds[0], "./capture", "a.png");
                    cmp(capture);
    
                    System.out.println("睡觉去了,30秒后起床");
                    //睡眠30s,相当于每隔30s处理一下土疙瘩和古董
                    sleep(30);
                    //睡眠10分钟,等待加速效果结束
    //                sleep(60 * 10);
                }
            }
        }
    
        String getDateTime() {
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            //    println(formatDateTime)
            return now.format(formatter);
        }
    
        void cmp(ScreenCapture capture) {
            File f = new File("./capture/a.png");
            System.out.println(f.toString());
            if (f.exists()) {
                System.out.println("文件存在");
                //加速坐标,超级加速
                int jsX = 968;
                int jsY = 1819;
                Color colorGet = getColor(f.getPath(), jsX, jsY);
                double similarity = ColorSimilarity.compare(COLOR_CJJS, colorGet);
                System.out.println("超级加速相似度:" + similarity);
    
    
                //加速冷却按钮,小于0.9表示可点击,否则是冷却状态,不可点击
                Color colorGetJslq = getColor(f.getPath(), 448, 1837);
                double similarityJslq = ColorSimilarity.compare(COLOR_JSLQ, colorGetJslq);
                System.out.println("加速冷却相似度:" + similarityJslq);
                if (similarityJslq < 0.9) {
                    System.out.println("加速可点击,可以点击超级加速");
                } else {
                    System.out.println("加速冷却中……现在不可加速");
                }
    
                if (similarity >= 0.90 && similarityJslq < 0.9) {//点击超级加速
                    System.out.println("超级加速颜色相似度OK,点击超级加速");
                    /* 这里面没有考虑分享功能,尚待改进 */
                    /* 还有小说广告、直播广告没有考虑 */
                    //此时位于游戏主页面,可以点击超级加速
                    capture.touchXY(903, 1825);
                    sleep(2);
                    //点击观看
                    capture.touchXY(575, 1219);
                    //等待视频播放结束
                    sleep(40);
                    //点击视频完成后的关闭按钮
                    capture.touchXY(977, 105);
                    sleep(5);
    
                    // 点击放弃奖励按钮(只考虑5分钟的情况)
                    capture.touchXY(550, 1308);
                    sleep(5);
    
    //                //点击第二次观看
    //                capture.touchXY(575, 1219);
    //                //等待视频播放结束
    //                sleep(40);
    //                //点击视频完成后的关闭按钮
    //                capture.touchXY(977, 105);
    //                sleep(3);
                } else {//土疙瘩点击返回,古董点击捐赠,新材料点击知道了
                    System.out.println("颜色相似度不符,目前不能点击超级加速,看看是土疙瘩还是古董");
                    //游戏被弹出窗口挡住了
                    //根据横条的颜色坐标,判断是土疙瘩还是古董
                    int htX = 302;
                    int htY = 314;
                    Color colorGetTG = getColor(f.getPath(), htX, htY);
                    double similarityTG = ColorSimilarity.compare(COLOR_TUGEDA, colorGetTG);
                    System.out.println("土疙瘩颜色相似度:" + similarityTG);
    
                    if (similarityTG >= 0.9) {//是土疙瘩
                        System.out.println("是土疙瘩,关闭即可:");
                        //点击返回按钮关闭土疙瘩
                        capture.touchXY(76, 121);
                        sleep(3);
                    } else {
                        similarityTG = ColorSimilarity.compare(COLOR_GUDONG, colorGetTG);
                        System.out.println("古董颜色相似度:" + similarityTG);
                        if (similarityTG >= 0.9) {//是古董
                            System.out.println("是古董,点击捐赠按钮");
                            //点击捐赠按钮
                            capture.touchXY(376, 1777);
                            sleep(3);
                        } else {//意外
                            System.out.println("不能加速,不是土疙瘩,不是古董,这就奇怪了...莫不是正在加速?");
                        }
                    }
                }
            } else {
                System.out.println("截图读取失败,得检查一下问题再继续");
            }
        }
    
        private static void sleep(int seconds) {
            try {
                Thread.sleep(1000 * seconds);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    
        Color getColor(String filePath, int x, int y) {
            try {
                // 读取图片文件
                BufferedImage image = ImageIO.read(
                        new File(filePath)
                );
    
                // 提取坐标颜色
                int color = image.getRGB(x, y);
    
                // 打印颜色值
                System.out.println("The color at (" + x + ", " + y + ") is: " + color);
    
                int alpha = (color >> 24) & 0xff;
                int red = (color >> 16) & 0xff;
                int green = (color >> 8) & 0xff;
                int blue = color & 0xff;
                System.out.printf("argb:%x,%x,%x,%x,", alpha, red, green, blue);
    
                Color color2 = new Color(red, green, blue);
    
                return color2;
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    package learn
    
    import java.io.*
    import java.time.LocalDateTime
    import java.time.format.DateTimeFormatter
    import java.util.*
    
    class ScreenCapture {
        val devices: Array<String>
            get() {
                val command = "adb devices"
                println(command)
                val devices = ArrayList<String>()
                try {
                    val process = Runtime.getRuntime().exec(command)
                    val bufferedReader = BufferedReader(InputStreamReader(process.inputStream))
                    var line = bufferedReader.readLine()
                    while (line != null) {
                        println(line)
                        if (line.endsWith("device")) {
                            val device = line.substring(0, line.length - "device".length).trim { it <= ' ' }
                            devices.add(device)
                        }
                        line = bufferedReader.readLine()
                    }
                    process.destroy()
                } catch (e: Exception) {
                    e.printStackTrace()
                }
                return devices.toArray(arrayOf())
            }
    
        fun getModel(device: String): String? {
            val command = "adb -s $device shell getprop"
            println(command)
            var model: String? = null
            try {
                val process = Runtime.getRuntime().exec(command)
                val bufferedReader = BufferedReader(InputStreamReader(process.inputStream))
                var line = bufferedReader.readLine()
                while (line != null) {
                    if (line.contains("[ro.product.model]:")) {
                        model = line.substring("[ro.product.model]:".length).trim { it <= ' ' }
                        model = model.substring(1, model.length - 1)
                        break
                    }
                    line = bufferedReader.readLine()
                }
                process.destroy()
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return model
        }
    
        fun snapshot(device: String, toPath: String, toFile: String) {
    //        var f = File(toFile)
    //        println(f.toString())
    //        if (f.exists()) {
    //            var delete = f.delete()
    //            println("同名文件已经存在,删除它,结果${delete}")
    //        }
            val temp = "scrsnp.png"
            val t0 = Date().time
            val command1 = "adb -s $device shell screencap -p /sdcard/$temp"
            println(command1)
            cmdExecute(command1)
            val t1 = Date().time
            println("截屏用时:${t1 - t0} ms")
            val command2 = "adb -s $device pull /sdcard/$temp $toPath/$toFile"
            println(command2)
            cmdExecute(command2)
            val t2 = Date().time
            println("pull文件用时:${t2 - t1} ms")
            val command3 = "adb -s $device shell rm /sdcard/$temp"
            println(command3)
            cmdExecute(command3)
            val t3 = Date().time
            println("删除sd卡图片用时:${t3 - t2} ms")
        }
    
        private fun cmdExecute(command: String) {
            try {
                val process = Runtime.getRuntime().exec(command)
                process.waitFor()
                process.destroy()
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    
        fun touchXY(x: Int, y: Int) {
            //adb shell input tap $kspx $kspy
            var device = devices[0]
            var cmd = "adb -s $device shell input tap $x $y"
            cmdExecute(cmd)
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    7.改进版本,待续……

    7.1完善了看广告的判断,依然是基于颜色值,基于ocr的版本估计够呛了

    基于颜色判断目前,基本满足了需求

    package learn;
    
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    
    /**
     * 王铲铲的致富之路Java辅助
     */
    public class Wcc {
    
        Color COLOR_TUGEDA = new Color(0xF0, 0xE1, 0x53);
        Color COLOR_GUDONG = new Color(0xCC, 0x5E, 0x5B);
        Color COLOR_CJJS = new Color(0xE1, 0x90, 0x25);
        Color COLOR_JSLQ = new Color(0x60, 0x34, 0x2c);
        Color COLOR_XCL = new Color(0xCC, 0x5E, 0x5B);
        private int c = 0;
    
    
        public static void main(String[] args) {
            Wcc wcc = new Wcc();
            wcc.digHole();
        }
    
        /**
         * 1.检测当前能不能加速,
         * 能
         *   则看广告加速
         * 不能,
         *   看看是图疙瘩还是古董,
         *   土疙瘩
         *     关闭
         *   古董
         *     捐赠
         *
         * 2.if(处理完毕土疙瘩和古董)
         *     查看加速是否结束
         *     没有,继续等待
         *     有,继续加速
         *
         * 3.(每30s检查一次土疙瘩和古董)
         */
        private void digHole() {
            ScreenCapture capture = new ScreenCapture();
            String[] ds = capture.getDevices();
            System.out.println("设备列表容量:" + ds.length);
    
    
            if (ds.length > 0) {
                String model = capture.getModel(ds[0]);
                System.out.println("手机型号:" + model);
    
                while (true) {
                    long beginTime = System.currentTimeMillis();
                    System.out.println("---------------------------------------------");
                    System.out.println("集中火力干事业,把钱花在刀把上");
    
                    System.out.println("第" + (++c) + "次任务开始:" + getDateTime());
                    capture.snapshot(ds[0], "./capture", "a.png");
                    cmp(capture);
    
                    System.out.println("睡觉去了,30秒后起床");
                    //睡眠30s,相当于每隔30s处理一下土疙瘩和古董
                    sleep(30);
                    //睡眠10分钟,等待加速效果结束
    //                sleep(60 * 10);
                }
            }
        }
    
        String getDateTime() {
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            //    println(formatDateTime)
            return now.format(formatter);
        }
    
        void cmp(ScreenCapture capture) {
            File f = new File("./capture/a.png");
            System.out.println(f.toString());
            if (f.exists()) {
                System.out.println("文件存在");
                //加速坐标,超级加速
                int jsX = 968;
                int jsY = 1819;
                Color colorGet = getColor(f.getPath(), jsX, jsY);
                double similarity = ColorSimilarity.compare(COLOR_CJJS, colorGet);
                System.out.println("超级加速相似度:" + similarity);
    
    
                //加速冷却按钮,小于0.9表示可点击,否则是冷却状态,不可点击
                Color colorGetJslq = getColor(f.getPath(), 448, 1837);
                double similarityJslq = ColorSimilarity.compare(COLOR_JSLQ, colorGetJslq);
                System.out.println("加速冷却相似度:" + similarityJslq);
                if (similarityJslq < 0.9) {
                    System.out.println("加速可点击,可以点击超级加速");
                } else {
                    System.out.println("加速冷却中……现在不可加速");
                }
    
                if (similarity >= 0.90 && similarityJslq < 0.9) {//点击超级加速
                    System.out.println("超级加速颜色相似度OK,点击超级加速");
                    /* 这里面没有考虑分享功能,尚待改进 */
                    /* 还有小说广告、直播广告没有考虑 */
    //                //此时位于游戏主页面,可以点击超级加速
    //                capture.touchXY(903, 1825);
    //                sleep(2);
    //                //点击观看
    //                capture.touchXY(575, 1219);
    //                //等待视频播放结束
    //                sleep(40);
    //                //点击视频完成后的关闭按钮
    //                capture.touchXY(977, 105);
    //                sleep(5);
    //
    //                // 点击放弃奖励按钮(只考虑5分钟的情况)
    //                capture.touchXY(550, 1308);
    //                sleep(5);
    
    
                    /begin增强逻辑判断
                    //此时位于游戏主页面,可以点击超级加速
                    capture.touchXY(903, 1825);
                    sleep(2);
                    //点击观看,然后等待5秒
                    capture.touchXY(575, 1219);
                    sleep(5);
                    //再次截屏判断分享、小说、视频
                    capture.snapshot(capture.getDevices()[0], "./capture", "b.png");
                    File fb = new File("./capture/b.png");
                    // 读取图片文件
                    BufferedImage image = getBufferedImage(fb.getPath());
    
                    //判断顺序,1.分享2.小说3.视频
                    BufferedImage subimage = image.getSubimage(150, 40, 400, 70);
                    Color wx = new Color(0xEC, 0xEC, 0xEC);
                    boolean bWx = hasOnlyExpectedColor(subimage, wx);
                    Color novel = Color.BLACK;
                    boolean bNov = hasOnlyExpectedColor(subimage, novel);
                    System.out.println("是微信分享吗:"+bWx + ", 是小说吗:"+bNov);
                    if (bWx) {
                        System.out.println("是微信分享");
                        //点击微信分享完成后的关闭按钮
                        capture.touchXY(50, 135);
                        sleep(5);
    
                        // 点击放弃奖励按钮(只考虑5分钟的情况)
                        capture.touchXY(550, 1308);
                        sleep(5);
                    } else if (bNov) {
                        System.out.println("是小说广告");
                        //点击小说广告完成后的关闭按钮
                        capture.touchXY(91, 89);
                        sleep(5);
    
                        // 点击放弃奖励按钮(只考虑5分钟的情况)
                        capture.touchXY(550, 1308);
                        sleep(5);
                    } else { // 视频广告
                        System.out.println("是视频广告");
                        //等待视频播放结束,时间缩短,前面休眠时间挺长了
                        sleep(32);
                        //点击视频完成后的关闭按钮
                        capture.touchXY(977, 105);
                        sleep(5);
    
                        // 点击放弃奖励按钮(只考虑5分钟的情况)
                        capture.touchXY(550, 1308);
                        sleep(5);
                    }
    
                    /end增强逻辑判断
    
    
    //                //点击第二次观看
    //                capture.touchXY(575, 1219);
    //                //等待视频播放结束
    //                sleep(40);
    //                //点击视频完成后的关闭按钮
    //                capture.touchXY(977, 105);
    //                sleep(3);
                } else {//土疙瘩点击返回,古董点击捐赠,新材料点击知道了
                    System.out.println("颜色相似度不符,目前不能点击超级加速,看看是土疙瘩还是古董");
                    //游戏被弹出窗口挡住了
                    //根据横条的颜色坐标,判断是土疙瘩还是古董
                    int htX = 302;
                    int htY = 314;
                    Color colorGetTG = getColor(f.getPath(), htX, htY);
                    double similarityTG = ColorSimilarity.compare(COLOR_TUGEDA, colorGetTG);
                    System.out.println("土疙瘩颜色相似度:" + similarityTG);
    
                    if (similarityTG >= 0.9) {//是土疙瘩
                        System.out.println("是土疙瘩,关闭即可:");
                        //点击返回按钮关闭土疙瘩
                        capture.touchXY(76, 121);
                        sleep(3);
                    } else {
                        similarityTG = ColorSimilarity.compare(COLOR_GUDONG, colorGetTG);
                        System.out.println("古董颜色相似度:" + similarityTG);
                        if (similarityTG >= 0.9) {//是古董
                            System.out.println("是古董,点击捐赠按钮");
                            //点击捐赠按钮
                            capture.touchXY(376, 1777);
                            sleep(3);
                        } else {//看看是不是新材料出现了
                            //根据新材料的条幅位置判断颜色是否是新材料
                            int newX = 210;
                            int newY = 400;
                            Color colorNew = getColor(f.getPath(), newX, newY);
                            double similarityNew = ColorSimilarity.compare(COLOR_XCL, colorNew);
                            System.out.println("新材料颜色相似度:" + similarityNew);
                            if (similarityNew >= 0.9) {
                                System.out.println("是新材料,点击知道了按钮");
                                //点击知道了按钮
                                capture.touchXY(530, 1410);
                                sleep(3);
                            } else {//意外
                                System.out.println("不能加速,不是土疙瘩,不是古董,不是新材料,这就奇怪了...莫不是正在加速?");
                            }
                        }
                    }
                }
            } else {
                System.out.println("截图读取失败,得检查一下问题再继续");
            }
        }
    
        private static void sleep(int seconds) {
            try {
                Thread.sleep(1000 * seconds);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    
        Color getColor(String filePath, int x, int y) {
            // 读取图片文件
            BufferedImage image = getBufferedImage(filePath);
    
            // 提取坐标颜色
            int color = image.getRGB(x, y);
    
            // 打印颜色值
            System.out.println("The color at (" + x + ", " + y + ") is: " + color);
    
            int alpha = (color >> 24) & 0xff;
            int red = (color >> 16) & 0xff;
            int green = (color >> 8) & 0xff;
            int blue = color & 0xff;
            System.out.printf("argb:%x,%x,%x,%x,", alpha, red, green, blue);
    
            Color color2 = new Color(red, green, blue);
    
            return color2;
        }
    
        BufferedImage getBufferedImage(String filePath) {
            // 读取图片文件
            try {
                BufferedImage image = ImageIO.read(new File(filePath));
                return image;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    
        /**
         * 图片只包含期望的颜色,用来判断小说、视频、分享
         * @param image
         * @param expColor
         * @return
         */
        boolean hasOnlyExpectedColor(BufferedImage image, Color expColor) {
            int expectedColor = expColor.getRGB();
            int c = 0;
            for (int i = 0; i < image.getWidth(); i++) {
                for (int j = 0; j < image.getHeight(); j++) {
                    int actualColor = image.getRGB(i, j);
                    if (actualColor != expectedColor) {
                        System.out.println("The image contains other colors.");
                        System.out.println("but the found expected color numbers have:" + c);
                        return false;
                    } else {
                        c++;
                    }
                }
            }
            System.out.println("The image contains only the expected color.");
            return true;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296

    7.2version1.2

      1)点击超级加速弹窗,根据按钮图表颜色值进行判断是分享还是视频等广告。很明显图案不同。由此获得了一波改进,毕竟视频广告和分享是最多的。下一步的计划是把小说、直播也能搞定,其实这个无非就是找到页面的关闭按钮在哪里,等待30秒点击关闭即可,难的是不好找关闭按钮。

      2)这个时候如果能把OpenCV用起来,必然能轻松搞定,而且有了OpenCV下一步能做的事情就更多了,考虑到工作量,暂不考虑。version1也是根据土疙瘩和古董顶部横条颜色来处理的判断。
    在这里插入图片描述在这里插入图片描述
    Wcc.java

    package learn;
    
    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    
    /**
     * 王铲铲的致富之路Java辅助
     */
    public class Wcc {
    
        Color COLOR_TUGEDA = new Color(0xF0, 0xE1, 0x53);
        Color COLOR_GUDONG = new Color(0xCC, 0x5E, 0x5B);
        Color COLOR_CJJS = new Color(0xE1, 0x90, 0x25);
        Color COLOR_JSLQ = new Color(0x60, 0x34, 0x2c);
        Color COLOR_XCL = new Color(0xCC, 0x5E, 0x5B);
        private int c = 0;
    
    
        public static void main(String[] args) {
            Wcc wcc = new Wcc();
            wcc.digHole();
        }
    
        /**
         * 1.检测当前能不能加速,
         * 能
         * 则看广告加速
         * 不能,
         * 看看是图疙瘩还是古董,
         * 土疙瘩
         * 关闭
         * 古董
         * 捐赠
         * 

    * 2.if(处理完毕土疙瘩和古董) * 查看加速是否结束 * 没有,继续等待 * 有,继续加速 *

    * 3.(每30s检查一次土疙瘩和古董) */ private void digHole() { ScreenCapture capture = new ScreenCapture(); String[] ds = capture.getDevices(); System.out.println("设备列表容量:" + ds.length); if (ds.length > 0) { String model = capture.getModel(ds[0]); System.out.println("手机型号:" + model); while (true) { long beginTime = System.currentTimeMillis(); System.out.println("---------------------------------------------"); System.out.println("集中火力干事业,把钱花在刀把上"); System.out.println("第" + (++c) + "次任务开始:" + getDateTime()); capture.snapshot(ds[0], "./capture", "a.png"); cmp(capture); System.out.println("睡觉去了,30秒后起床"); //睡眠30s,相当于每隔30s处理一下土疙瘩和古董 sleep(30); //睡眠10分钟,等待加速效果结束 // sleep(60 * 10); } } } String getDateTime() { LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // println(formatDateTime) return now.format(formatter); } void cmp(ScreenCapture capture) { File f = new File("./capture/a.png"); System.out.println(f.toString()); if (f.exists()) { System.out.println("文件存在"); //加速坐标,超级加速 int jsX = 968; int jsY = 1819; Color colorGet = getColor(f.getPath(), jsX, jsY); double similarity = ColorSimilarity.compare(COLOR_CJJS, colorGet); System.out.println("超级加速相似度:" + similarity); //加速冷却按钮,小于0.9表示可点击,否则是冷却状态,不可点击 Color colorGetJslq = getColor(f.getPath(), 448, 1837); double similarityJslq = ColorSimilarity.compare(COLOR_JSLQ, colorGetJslq); System.out.println("加速冷却相似度:" + similarityJslq); if (similarityJslq < 0.9) { System.out.println("加速可点击,可以点击超级加速"); } else { System.out.println("加速冷却中……现在不可加速"); } if (similarity >= 0.90 && similarityJslq < 0.9) {//点击超级加速 System.out.println("超级加速颜色相似度OK,点击超级加速"); /* 这里面没有考虑分享功能,尚待改进 */ /* 还有小说广告、直播、视频广告没有考虑 */ // //此时位于游戏主页面,可以点击超级加速 // capture.touchXY(903, 1825); // sleep(2); // //点击观看 // capture.touchXY(575, 1219); // //等待视频播放结束 // sleep(40); // //点击视频完成后的关闭按钮 // capture.touchXY(977, 105); // sleep(5); // // // 点击放弃奖励按钮(只考虑5分钟的情况) // capture.touchXY(550, 1308); // sleep(5); /begin增强逻辑判断 //此时位于游戏主页面,可以点击超级加速 capture.touchXY(903, 1825); sleep(2); //再次截屏判断分享或其他:小说、视频... capture.snapshot(capture.getDevices()[0], "./capture", "b.png"); File fb = new File("./capture/b.png"); String path = fb.getPath(); int[] arr = {479, 1219, 503, 1202, 510, 1235}; GetColorKt colorKt = new GetColorKt(); Color p1 = colorKt.getColor(path, new int[]{arr[0], arr[1]}); Color p2 = colorKt.getColor(path, new int[]{arr[2], arr[3]}); Color p3 = colorKt.getColor(path, new int[]{arr[4], arr[5]}); //如果3个点的颜色均大于0.9,那么就是微信分享 //否则就是其他(视频、直播、小说) double sim1 = colorKt.cmp(Color.WHITE, p1); double sim2 = colorKt.cmp(Color.WHITE, p2); double sim3 = colorKt.cmp(Color.WHITE, p3); if (sim1 >= 0.9 && sim2 >= 0.9 && sim3 >= 0.9) { System.out.println("这次是微信分享"); //点击观看,然后等待5秒 capture.touchXY(575, 1219); sleep(5); //点击微信分享完成后的关闭按钮 capture.touchXY(50, 135); sleep(5); } else { System.out.println("这次是视频、小说、直播,有待改进"); //点击观看,然后等待5秒 capture.touchXY(575, 1219); sleep(5); //等待视频播放结束 sleep(37); //点击视频完成后的关闭按钮 capture.touchXY(977, 105); sleep(5); } // 点击放弃奖励按钮(只考虑5分钟的情况) capture.touchXY(550, 1308); sleep(5); /end增强逻辑判断 // //点击第二次观看 // capture.touchXY(575, 1219); // //等待视频播放结束 // sleep(40); // //点击视频完成后的关闭按钮 // capture.touchXY(977, 105); // sleep(3); } else {//土疙瘩点击返回,古董点击捐赠,新材料点击知道了 System.out.println("颜色相似度不符,目前不能点击超级加速,看看是土疙瘩还是古董"); //游戏被弹出窗口挡住了 //根据横条的颜色坐标,判断是土疙瘩还是古董 int htX = 302; int htY = 314; Color colorGetTG = getColor(f.getPath(), htX, htY); double similarityTG = ColorSimilarity.compare(COLOR_TUGEDA, colorGetTG); System.out.println("土疙瘩颜色相似度:" + similarityTG); if (similarityTG >= 0.9) {//是土疙瘩 System.out.println("是土疙瘩,关闭即可:"); //点击返回按钮关闭土疙瘩 capture.touchXY(76, 121); sleep(3); } else { similarityTG = ColorSimilarity.compare(COLOR_GUDONG, colorGetTG); System.out.println("古董颜色相似度:" + similarityTG); if (similarityTG >= 0.9) {//是古董 System.out.println("是古董,点击捐赠按钮"); //点击捐赠按钮 capture.touchXY(376, 1777); sleep(3); } else {//看看是不是新材料出现了 //根据新材料的条幅位置判断颜色是否是新材料 int newX = 210; int newY = 400; Color colorNew = getColor(f.getPath(), newX, newY); double similarityNew = ColorSimilarity.compare(COLOR_XCL, colorNew); System.out.println("新材料颜色相似度:" + similarityNew); if (similarityNew >= 0.9) { System.out.println("是新材料,点击知道了按钮"); //点击知道了按钮 capture.touchXY(530, 1410); sleep(3); } else {//意外 System.out.println("不能加速,不是土疙瘩,不是古董,不是新材料,这就奇怪了...莫不是正在加速?"); } } } } } else { System.out.println("截图读取失败,得检查一下问题再继续"); } } private static void sleep(int seconds) { try { Thread.sleep(1000 * seconds); } catch (InterruptedException e) { throw new RuntimeException(e); } } Color getColor(String filePath, int x, int y) { // 读取图片文件 BufferedImage image = getBufferedImage(filePath); // 提取坐标颜色 int color = image.getRGB(x, y); // 打印颜色值 System.out.println("The color at (" + x + ", " + y + ") is: " + color); int alpha = (color >> 24) & 0xff; int red = (color >> 16) & 0xff; int green = (color >> 8) & 0xff; int blue = color & 0xff; System.out.printf("argb:%x,%x,%x,%x,", alpha, red, green, blue); Color color2 = new Color(red, green, blue); return color2; } BufferedImage getBufferedImage(String filePath) { // 读取图片文件 try { BufferedImage image = ImageIO.read(new File(filePath)); return image; } catch (IOException e) { throw new RuntimeException(e); } } }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265

    ColorSimilarity.java

    package learn;
    
    import java.awt.Color;
    
    public class ColorSimilarity {
        public static double compare(Color c1, Color c2) {
            float[] hsv1 = new float[3];
            float[] hsv2 = new float[3];
            Color.RGBtoHSB(c1.getRed(), c1.getGreen(), c1.getBlue(), hsv1);
            Color.RGBtoHSB(c2.getRed(), c2.getGreen(), c2.getBlue(), hsv2);
            double len = Math.sqrt(Math.pow(hsv1[0] - hsv2[0], 2) + Math.pow(hsv1[1] - hsv2[1], 2) + Math.pow(hsv1[2] - hsv2[2], 2));
            if (len > 1) {
                len = 1.0;
            }
            return (1.0 - len) / 1.0;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    GetColorKt.kt

    package learn
    
    import java.awt.Color
    import java.io.File
    import java.io.IOException
    import javax.imageio.ImageIO
    
    /**
     * @Class GetColorKt
     * @Description
     * @Author xsc
     * @Date 2023/9/10 下午11:05
     * @Version 1.0
     */
    class GetColorKt {
    
        fun getColor(path: String, intArray: IntArray): Color {
            try {
                // 读取图片文件
                val input = File(path)
                println(input.exists())
                val image = ImageIO.read(input)
    
                // 定义需要提取颜色的坐标
                val x = intArray[0]
                val y = intArray[1]
    
                // 提取坐标颜色
                val color = image.getRGB(x, y)
    
                // 打印颜色值
                println("The color at ($x, $y) is: $color")
                val alpha = color shr 24 and 0xff
                val red = color shr 16 and 0xff
                val green = color shr 8 and 0xff
                val blue = color and 0xff
                System.out.printf("argb:%x,%x,%x,%x,\n", alpha, red, green, blue)
                return Color(red, green, blue)
            } catch (e: IOException) {
                e.printStackTrace()
                return Color(0, 0, 0, 0)
            }
        }
    
        public fun cmp(color1: Color, color2: Color): Double {
    //        val color1 = Color(0x97, 0x38, 0x2f) //.RED;
    //        val color2 = Color(0x5c, 0x24, 0x1e) //.ORANGE;
            val similarity = ColorSimilarity.compare(color1, color2)
            println("相似度:$similarity")
            return similarity
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
  • 相关阅读:
    百度安全X盈科全球数据合规服务中心:推进数据安全及合规智能化创新领域深化合作
    bootstrap样式
    显示屏没有信号monitor no signal from device
    知识变现海哥:如何把知识卖的更贵、更多、更酷
    Java8--Stream的各种用法(二):collect、Collectors
    Leetcode 667. 优美的排列 II
    MySQL-Redis进阶生成全局唯一ID
    Vue3-自定义hook函数
    [附源码]JAVA毕业设计会议室租赁管理系统(系统+LW)
    C++基础篇考题
  • 原文地址:https://blog.csdn.net/ximen250/article/details/132775983