1
头图

背景

技术栈:Auto.js + 安卓设备无障碍访问 不需Root

实现功能:【三国杀十周年】公会自动擂鼓,暂时只实现了这个。后续有空再更新其他任务逻辑

思路概览:借助OCR功能,进行页面控件拆解,以及页面状态分析(任务完成情况),然后通过Auto.js进行按钮点击,完成相应任务。

项目目录

.
├── README.md
├── main.js // 入口逻辑
├── package.json
├── project.json
├── secret.js // 百度Token 
└── src
    ├── asset // 资源文件
    │   ├── demo // OCR测试使用
    │   │   └── index.js
    │   ├── img
    │   │   ├── WechatIMG604.jpeg
    │   │   └── WechatIMG605.jpeg
    │   └── page // 页面配置信息,通过OCR对页面进行分析生成,主要是JSON格式,记录控件信息
    │       ├── README.md
    │       ├── gonghui //公会页面
    │       │   ├── gonghui.js
    │       │   └── huodong.js
    │       ├── shouye.js // 首页
    │       └── wujiang // 武将页面
    │           └── wujiang.js
    ├── config.js
    ├── lib
    │   └── utilTool.js // 常用方法
    └── task // 任务逻辑 互相隔离
        ├── gonghui.js // 公会任务逻辑
        ├── renwu.js // 以下均为其他任务,未完成
        ├── weixin.js
        └── zhuolu.js

逻辑实现

公会任务逻辑

var utilJS = require("../lib/utilTool");
var utilTool = utilJS.utilTool;

var shouye = require("../asset/page/shouye");
var gonghui = require("../asset/page/gonghui/gonghui");
var huodong = require("../asset/page/gonghui/huodong");

// 公会任务
function GonghuiTask() {}

GonghuiTask.prototype.init = function () {
    utilTool.clickButton(shouye, "公会"); // 内部方法,点击某控件
    utilTool.clickButton(gonghui, "活动");

    while (!utilTool.findText("消耗元宝20")) { // 如果有 消耗元宝20 等字样,说明免费擂鼓已经到达上限
        // 说明还可以擂鼓
        utilTool.clickButton(huodong, "擂鼓");
    }

    utilTool.clickBack();
};

module.exports = {
    gonghuiTask: new GonghuiTask(),
};

功能比较简单,就是进入首页后,点击公会、活动等按钮,成功进入到擂鼓任务页面。

然后检测当前的任务状态,是否可以擂鼓。

utilTool.findText("消耗元宝20")这一行,详细方法如下

UtilTool.prototype.findText = function (text) {
    var page = this.captureWithOcr("basic"); // 内部封装方法,获取当前页面截图,并启用OCR分析,查看当前页面的相关文字描述
    var result = page.find(function (item) {
        if (item.words == text) {
            return true;
        }
    });
    return result;
};

难点分析

手游版三国杀,无法通过Auto.js自带的工具进行控件分析,也无法通过click("活动")框架方法,点击某按钮控件。

整个游戏页面都进行包装,且所有的属性都没有暴露出来,因此通过text("xx文案") 或者其他方法,都没法很好的定位到各个控件。因此本脚本,是采取了百度OCR的网络图片功能,进行分析

百度OCR有好几个不同的场景,经调试,网络图片的OCR在此场景下最为精确,基本能精确转译90%的文字内容

OCR调用后,返回的数据内容,都存储在/asset/page/文件夹下(OCR价格较贵,且返回时间过长,因此事先进行了数据缓存,而非每次脚本运行时调用)。数据格式如下

module.exports = [
    {
        words: "信件",
        location: { top: 31, left: 1976, width: 68, height: 33 },
        chars: [],
    },
    {
        words: "充值",
        location: { top: 29, left: 2136, width: 65, height: 32 },
        chars: [],
    },
    {
        words: "世界",
        location: { top: 996, left: 130, width: 70, height: 34 },
        chars: [],
    },
    {
        words: "迹的来,可焚城",
        location: { top: 1007, left: 271, width: 182, height: 26 },
        chars: [],
    },
    {
        words: "更多",
        location: { top: 1031, left: 1021, width: 54, height: 30 },
        chars: [],
    },
    {
        words: "包裹",
        location: { top: 1031, left: 1142, width: 55, height: 29 },
        chars: [],
    },
    {
        words: "好友",
        location: { top: 1032, left: 1264, width: 57, height: 28 },
        chars: [],
    },
        ...
];

数据内容主要是涵盖了对应的文字内容,以及文字位置,大小等。有了这个数据,就可以达到我们想要的效果,借助Auto.js,让脚本按照我们所想,进行某个区域的点击,具体方法如下

// 遍历位置,点击按钮
UtilTool.prototype.clickButton = function (arrays, name) {
    var flag = false;
    for (var i = 0; i < arrays.length; i++) {
        var item = arrays[i];
        if (item.words.includes(name)) {
            // 说明存在当前按钮
            click(
                item.location.left + item.location.width / 2,
                item.location.top + item.location.height / 2
            );
            toast("点击了按钮:" + name);
            flag = true;
            sleep(1000);
            break;
        }
    }
    if (!flag) {
        toast("没有遍历到按钮");
    }
};

至此,整个脚本的主要逻辑介绍完毕

结语

本代码仅为了试验 OCR + Auto.js,能实现怎么样的脚本功能。现在看来效果应该还不错,其他的APP应用,也可以参照此逻辑,快速进行脚本开发。

另,像这种简单的任务,也可以借助XX录屏精灵等工具进行实现,但对比起来,通过脚本的方式开发,会更加灵活。比如当我们想判断当前的任务状态,或者页面逻辑时,可以借助脚本+OCR的功能,快速分析,以便实施我们想要的逻辑。

代码仓库:https://github.com/qiangzi772... 后续应该不会再更新此仓库,仅为验证使用。

注:本仓库拉取到本地后,无法正常运行,缺少相关百度Token


上啊比卡丘
660 声望41 粉丝