解放你的双手,陪爸妈看春晚去!

前段时间接触了下Auto.js(https://github.com/hyb1996/Auto.js),很好上手而且挺有意思,于是写了个微信红包监测脚本,完整代码见文末

大概思路是,不断获取手机屏幕截图,发现新消息则进入,如果进一步发现了红包,则点击红包并打开

由于Auto.js只能在安卓上安装,所以脚本同样仅适用于安卓

Auto.js简介

  • 适用于安卓的脚本工具
  • 一个主要由无障碍服务实现的,不需要Root权限的自动操作软件
  • 可以实现自动点击、滑动、输入文字、打开应用等功能

更详细的介绍可以参考项目官方Github

下载链接如下,https://github.com/hyb1996/Auto.js/releases,下载最新的apk文件到手机并安装即可

软件界面如下,包括多个标签页:

  • 脚本:查看当前已有的脚本(Scripts)
  • 教程:Auto.js官方文档
  • 社区:Auto.js交流社区
  • 示例:大量的示例代码
  • 管理:对当前运行中的脚本进行管理,例如全部终止等

简而言之,你可以按照Auto.js的语法(主要是JavaScript)来编写脚本,然后通过Auto.js运行,从而完成一些手机上的自动化任务

使用方法

让微信回到主界面,即不让要微信处于聊天页、朋友圈等状态

在手机上运行Auto.js软件,点击左上角的三条横线,在菜单栏中打开 无障碍服务 和 稳定模式,便于Auto.js完成截屏、模拟按压等自动化操作

回到软件主界面,在 脚本 标签页中,点击右下角的加号,选择 文件,名称取为 微信红包,点 确定 保存,即可进入脚本的编辑页面

将完整代码复制到脚本中,点击 保存,之后点击 运行 即可

手机会自动跳转到微信中,首先检测一些相关参数(例如消息起始位置、每行消息的高度等),然后便会按照代码中定义的时间间隔(即倒数第三行sleep函数中的数字,以毫秒为单位),不断监测新消息并执行操作

完整代码

console.show(); // 设备信息 var WIDTH = device.width, HEIGHT = device.height, TYPE = device.brand + ' ' + device.model; device.keepScreenOn(); log('欢迎使用微信红包辅助'); console.setSize(parseInt(WIDTH * 0.58), parseInt(WIDTH * 0.7)); console.setPosition(parseInt(WIDTH * 0.36), 0); // 获取截图权限 if (!requestScreenCapture()) { toast('请求截图失败,程序结束'); exit(); } // 启动微信 launchApp('微信'); sleep(1000); var check = false; // 是否检测过布局 var lineHeight; // 每行消息的高度 var redX = 0; // 消息红点X坐标 var startX; // 每行消息开始的X坐标 var startY; // 第一行消息开始的Y坐标 var white = 255; // 消息行背景色 var gray = 153; // 文字的颜色 var totalCount = 0; // 总共获取的红包数量 var loopCount = 0; // 已循环的次数 do { // 获取截图 var img = captureScreen(); // 检测布局 if (!check) { log('===== 检测布局中 ====='); // 寻找有像素的X起点 var sx = 0; for (let c = 0; c < WIDTH; c++) { if (colors.red(images.pixel(img, c, parseInt(HEIGHT * 0.4))) > 0 && colors.red(images.pixel(img, c, parseInt(HEIGHT * 0.6))) > 0) { sx = c; break; } } // 寻找startY for (let r = 0; r < HEIGHT; r++) { var point = images.pixel(img, sx, r); var red = colors.red(point), green = colors.green(point), blue = colors.blue(point); if (Math.abs(red - white) + Math.abs(green - white) + Math.abs(blue - white) <= 15) { // 找到startY startY = r; log('第一行起始Y坐标', startY); break; } } // 寻找lineHeight var jump = false; for (let r = startY; r < HEIGHT; r++) { var point = images.pixel(img, sx, r); var red = colors.red(point), green = colors.green(point), blue = colors.blue(point); if (Math.abs(red - white) + Math.abs(green - white) + Math.abs(blue - white) > 60) { jump = true; } if (Math.abs(red - white) + Math.abs(green - white) + Math.abs(blue - white) <= 15 && jump) { // 找到lineHeight lineHeight = r - startY; log('每行高度:', lineHeight); break; } } // 寻找startX var y1 = startY + parseInt(lineHeight * 0.581), y2 = startY + parseInt(lineHeight * 0.806); var error = {}; for (let c = lineHeight; c < parseInt(WIDTH * 0.5); c++) { error[c] = 0; // 每列的颜色误差 for (let y = y1; y < y2; y++) { var point = images.pixel(img, c, y); var red = colors.red(point), green = colors.green(point), blue = colors.blue(point); error[c] += Math.abs(red - white) + Math.abs(green - white) + Math.abs(blue - white); } if (error[c] == 0 && redX == 0) { // 找到redX redX = c; log('红点X坐标:', redX); } if (c > lineHeight && error[c - 1] <= 15 * (y2 - y1) && error[c] > error[c - 1]) { // 找到startX startX = c; log('消息起始X坐标', startX); break; } } log('===== 布局检测完毕 ====='); check = true; } // 检查前三条消息 for (let m = 0; m < 3; m++) { var redY = startY + parseInt((0.12 + m) * lineHeight) var point = images.pixel(img, redX, redY); var red = colors.red(point), green = colors.green(point), blue = colors.blue(point); if (red > 240 && green < 80 && blue < 80) { // 有未读消息 click(redX, redY + parseInt(0.5 * lineHeight)); sleep(600); // 寻找红包颜色 var chat = captureScreen(); for (let k = parseInt(HEIGHT * 0.9); k > parseInt(HEIGHT * 0.1); k--) { var point = images.pixel(chat, parseInt(WIDTH * 0.5), k); var red = colors.red(point), green = colors.green(point), blue = colors.blue(point); if (Math.abs(red - 250) + Math.abs(green - 158) + Math.abs(blue - 59) <= 15) { // 找到红包 click(parseInt(WIDTH * 0.5), k); sleep(800); // 寻找“开” chat = captureScreen(); var count = 0; for (let y = parseInt(HEIGHT * 0.4); y < parseInt(HEIGHT * 0.8); y++) { var point = images.pixel(chat, parseInt(WIDTH * 0.5), y); var red = colors.red(point), green = colors.green(point), blue = colors.blue(point); if (Math.abs(red - 235) + Math.abs(green - 205) + Math.abs(blue - 153) <= 15) { count += 1; } } if (count > HEIGHT * 0.4 * 0.1) { // 有“开”,点击! click(parseInt(WIDTH * 0.5), parseInt(HEIGHT * 0.55)); sleep(1000); // 查看是否抢到了 chat = captureScreen(); var count = 0; for (let y = parseInt(HEIGHT * 0.4); y < parseInt(HEIGHT * 0.8); y++) { var point = images.pixel(chat, parseInt(WIDTH * 0.5), y); var red = colors.red(point), green = colors.green(point), blue = colors.blue(point); if (Math.abs(red - 255) + Math.abs(green - 255) + Math.abs(blue - 255) <= 15) { count += 1; } } if (count > HEIGHT * 0.4 * 0.3) { totalCount += 1; } } back(); sleep(600); break; } } back(); sleep(600); } } loopCount += 1; log('已监测', loopCount, '次,抢到', totalCount, '个'); sleep(1000); // break; } while (true);

Have Fun !

原文发布于微信公众号 - 宏伦工作室(HonlanFarm)

原文发表时间:2018-02-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏angularejs学习篇

angularjs学习第四天笔记(第一篇:简单的表单验证)

您好,我是一名后端开发工程师,由于工作需要,现在系统的从0开始学习前端js框架之angular,每天把学习的一些心得分享出来,如果有什么说的不对的地方,请多多指...

1112
来自专栏GIS讲堂

lzugis——Arcgis Server for JavaScript API之POI

POI(Point Of Interest),感兴趣点,其实呢,严格意义上说应该不是POI,但是单位就这样叫了,我也就这样叫了,其实现的功能大致是这样的:用过百...

1002
来自专栏搞前端的李蚊子

ReactJs移动端兼容问题汇总

A:初步怀疑是css属性没有加前缀引发的兼容问题,但添加后发现也不行,通过webview调试后控制台输出Set is undefined,搜索后发现React依...

2235
来自专栏偏前端工程师的驿站

JS魔法堂:获取当前脚本文件的绝对路径

一、前言                           当写模块加载器时,获取当前脚本文件的绝对路径作为基础路径是必不可少的一步,下面我们一起来探讨一下这...

2776
来自专栏移动开发之家

Flutter完整开发实战详解(四、 Redux、主题、国际化)

作为系列文章的第四篇,本篇主要介绍 Flutter 中 Redux 的使用,并结合Redux 完成实时的主题切换与多语言切换功能。

2452
来自专栏Python攻城狮

使用Selenium抓取QQ空间好友说说1.安装Selenium2.在Python中使用Selenium获取QQ空间好友说说3.代码实现(基于Python3)

通过Robo 3T(数据库MongoDB的一款功能强大的数据库管理工具)可以看到我们已经将拿到的数据库存储于数据库中

1022
来自专栏Flutter入门

Flutter入门三部曲(1) - 基础认识

看到整体的架构图,它是由dart完成上层的framework,然后由通过skia来完成图形的绘制。

1320
来自专栏腾讯NEXT学位

Vue.js最佳实践(五招让你成为Vue.js大师)

5597
来自专栏葡萄城控件技术团队

MultiRow发现之旅(七)- 套打和打印

前文回顾 MultiRow发现之旅(一)- 高效模板设计器 MultiRow发现之旅(二)- 详解属性管理器 MultiRow发现之旅(三)- 模板管理器和Ta...

1908
来自专栏ionic3+

ionic3应该善用组件和指令

其实ionic3(angualr4)和ionic2(angular2)差不多,但和ionic1(angular1)就差别非常大了,可以说基本是推倒了重来。在an...

1044

扫码关注云+社区

领取腾讯云代金券