自动偷取蚂蚁森林能量
之前写的微信抢红包软件效果还可以,反正过年家里的群里面的红包永远是我第一个抢到;其实微信抢红包还是比较简单的,稍微理一下逻辑也是比较容易实现的,基本上没什么难点。但是想要实现自动偷取蚂蚁森林的能量还是有点难度的,这里分享一下实现思路。
要实现的功能
功能是这样的,运行辅助软件后,自动跳转到支付宝页面,然后我们手动打开蚂蚁森林,手动进入好友总排名,然后辅助就开始找到那些可以收取能量的好友,进去收取能量,然后返回来继续。其实是可以实现全自动的,但是我实现以后觉得有点蠢,还是只实现偷好友能量这步比较好。
未标题-1.png-113.8kB实现方法
蚂蚁森林的界面都是一个标题栏加一个网页,内容都在网页里面。单纯的靠Android辅助功能是无法获取里面控件,无法实现这个功能的;图象识别配合模拟点击是万能的;只要识别出页面中这个可收取的能量的这个手的图标的位置,再通过模拟点击,就可以进入朋友的森林界面,再次通过图象识别,识别出可以收取的能量的位置,就可以进行能量的收取;
屏幕截图
首先是获取屏幕的截图,获取截图可以使用Android的录屏功能来实现,在开启辅助前,开启录屏功能,然后到这个界面的时候,通过当前页面的类名和标题是可以知道当前处于总排行榜界面的,这时候获取当前界面的截屏,然后进行图象识别,获取到第一个可收取能量的图标的位置,点击进入朋友的森林界面,进行能量的收取,然后返回,返回的时候,重新截图识别,找下一个可收取能量的图标;当识别不到可收取的图标的时候,模拟滑动进行翻页,然后继续进行识别。
//蚂蚁森林界面的标题控件
nodeInfo = findViewByID(ANT_FOREST_TITLE_ID);
String title = null;
if (nodeInfo != null && nodeInfo.getText() != null) {
title = nodeInfo.getText().toString();
}
//标题存在,且在朋友列表
if (title != null && ANT_FOREST_TITLE.equals(title)) {
nodeInfo = findViewByID(ANT_FOREST_BACK_ID);
if (nodeInfo != null) {
//在更多好友界面,判断界面是处于非滑动状态
if (!uiScrolling) {
//找到可以收取能量的按钮进行点击
findEnergyItem();
return;
}
}
图像识别
图象识别的话,之前有使用过openCV,里面的模板匹配应该比较符合这里的用法;这样的图象识别在做辅助软件的时候特别容易用到,之前都是根据需要写的一些用颜色作为识别的算法,每次都要重新写,比较操心,所以我自己想写一些通用的、简单的图象识别方法,可以复用,类似两张图片,找出小的图片在大图中的位置这种模板匹配;自己利用图象上的点的颜色来进行对比判断写了个识别方法(如果两张图片每个点颜色都相同,那图片肯定就一样了呀),还行能用,识别一张图片2960x1440的大概需要700毫秒左右;如下图,识别出图标的位置,我使用半透明的黄色标志了一下位置
/**
* 找有能量的item
*/
@RequiresApi(api = Build.VERSION_CODES.N)
private void findEnergyItem() {
//进行截屏
Bitmap bitmap = ScreenRecordUtil.getInstance().getScreenShot();
//进行图象识别
List<Rect> rects = cross.matching(bitmap, template);
if (rects.size() > 0) {
Rect rect = rects.get(0);
//点击识别出的坐标,进入下一个界面,触发下一个界面的方法进行处理
clickOnScreen((rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2, 10, null);
SystemClock.sleep(1000);
return;
}
//未找到按钮
uiScrolling = true;
//进行滑动操作
performScrollDownward(ScreenUtil.SCREEN_HEIGHT - 100, ScreenUtil.SCREEN_HEIGHT / 2, new AccessibilityService.GestureResultCallback() {
@Override
public void onCompleted(GestureDescription gestureDescription) {
super.onCompleted(gestureDescription);
//滑动完成继续识别
uiScrolling = false;
}
});
}
未标题-2.png-92.5kB
在好友的森林界面的偷能量,也是通过当前页面的类名和标题去判断当前界面处于好友的森林界面
if (nodeInfo != null) {
//在好友的森林里面
if (title != null && !title.equals(ANT_FOREST_TITLE) && title.contains(ANT_FOREST_TITLE)) {
//进行偷能量操作
if (!isCollecting) {
getEnergy();
//返回上一页
performBackClick();
SystemClock.sleep(WAIT_SLIPPING_TIME);
isCollecting = false;
}
}
}
颜色识别偷能量
未标题-3.png-83.6kB偷能量的操作,也是图象识别去实现,看图可以知道可收取的能量的颜色有些不同,写个简单的算法,通过颜色来判断一个点是否有可以获取的能量,然后模拟点击进行收取
/**
* 收取能量
*/
private void getEnergy() {
isCollecting = true;
//获取屏幕截屏
Bitmap bitmap = ScreenRecordUtil.getInstance().getScreenShot();
int width = bitmap.getWidth();
int startPointY = (int) (bitmap.getHeight() * START_HEIGHT_TOP_SCALE);
int endPointY = (int) (bitmap.getHeight() * START_HEIGHT_BOTTOM_SCALE);
for (int y = startPointY; y < endPointY; y = y + 25) {
for (int x = 0; x < width; x = x + 10) {
int currentColor = bitmap.getPixel(x, y);
//颜色对比可收取能量
if (labColorLike.isLike(ENERGY_COLOR, currentColor, 10)) {
//点击收取能量
clickOnScreen(x, y - 40, 10, null);
SystemClock.sleep(50);
}
}
}
}
总体效果还是不错的,收收能量没什么问题;其实也实现也比较简单,就是图像识别加上模拟点击。