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卡文件

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

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

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

adb shell input tap $x $y  

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;
        }
    }
}

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)
    }

}

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;
    }
}

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.检测当前能不能加速,
     * 能
     * 则看广告加速
     * 不能,
     * 看看是图疙瘩还是古董,
     * 土疙瘩
     * 关闭
     * 古董
     * 捐赠
     * <p>
     * 2.if(处理完毕土疙瘩和古董)
     * 查看加速是否结束
     * 没有,继续等待
     * 有,继续加速
     * <p>
     * 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);
        }
    }
}

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;
    }
}

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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值