自動(dòng)偷取螞蟻森林能量

之前寫(xiě)的微信搶紅包軟件效果還可以,反正過(guò)年家里的群里面的紅包永遠(yuǎn)是我第一個(gè)搶到;其實(shí)微信搶紅包還是比較簡(jiǎn)單的,稍微理一下邏輯也是比較容易實(shí)現(xiàn)的,基本上沒(méi)什么難點(diǎn)。但是想要實(shí)現(xiàn)自動(dòng)偷取螞蟻森林的能量還是有點(diǎn)難度的,這里分享一下實(shí)現(xiàn)思路。

要實(shí)現(xiàn)的功能

功能是這樣的,運(yùn)行輔助軟件后,自動(dòng)跳轉(zhuǎn)到支付寶頁(yè)面,然后我們手動(dòng)打開(kāi)螞蟻森林,手動(dòng)進(jìn)入好友總排名,然后輔助就開(kāi)始找到那些可以收取能量的好友,進(jìn)去收取能量,然后返回來(lái)繼續(xù)。其實(shí)是可以實(shí)現(xiàn)全自動(dòng)的,但是我實(shí)現(xiàn)以后覺(jué)得有點(diǎn)蠢,還是只實(shí)現(xiàn)偷好友能量這步比較好。

未標(biāo)題-1.png-113.8kB

實(shí)現(xiàn)方法

螞蟻森林的界面都是一個(gè)標(biāo)題欄加一個(gè)網(wǎng)頁(yè),內(nèi)容都在網(wǎng)頁(yè)里面。單純的靠Android輔助功能是無(wú)法獲取里面控件,無(wú)法實(shí)現(xiàn)這個(gè)功能的;圖象識(shí)別配合模擬點(diǎn)擊是萬(wàn)能的;只要識(shí)別出頁(yè)面中這個(gè)可收取的能量的這個(gè)手的圖標(biāo)的位置,再通過(guò)模擬點(diǎn)擊,就可以進(jìn)入朋友的森林界面,再次通過(guò)圖象識(shí)別,識(shí)別出可以收取的能量的位置,就可以進(jìn)行能量的收取;

屏幕截圖

首先是獲取屏幕的截圖,獲取截圖可以使用Android的錄屏功能來(lái)實(shí)現(xiàn),在開(kāi)啟輔助前,開(kāi)啟錄屏功能,然后到這個(gè)界面的時(shí)候,通過(guò)當(dāng)前頁(yè)面的類(lèi)名和標(biāo)題是可以知道當(dāng)前處于總排行榜界面的,這時(shí)候獲取當(dāng)前界面的截屏,然后進(jìn)行圖象識(shí)別,獲取到第一個(gè)可收取能量的圖標(biāo)的位置,點(diǎn)擊進(jìn)入朋友的森林界面,進(jìn)行能量的收取,然后返回,返回的時(shí)候,重新截圖識(shí)別,找下一個(gè)可收取能量的圖標(biāo);當(dāng)識(shí)別不到可收取的圖標(biāo)的時(shí)候,模擬滑動(dòng)進(jìn)行翻頁(yè),然后繼續(xù)進(jìn)行識(shí)別。

    //螞蟻森林界面的標(biāo)題控件
        nodeInfo = findViewByID(ANT_FOREST_TITLE_ID);
        String title = null;
        if (nodeInfo != null && nodeInfo.getText() != null) {
            title = nodeInfo.getText().toString();
        }
        //標(biāo)題存在,且在朋友列表
        if (title != null && ANT_FOREST_TITLE.equals(title)) {
            nodeInfo = findViewByID(ANT_FOREST_BACK_ID);
            if (nodeInfo != null) {
                //在更多好友界面,判斷界面是處于非滑動(dòng)狀態(tài)
                if (!uiScrolling) {
                    //找到可以收取能量的按鈕進(jìn)行點(diǎn)擊
                    findEnergyItem();
                    return;
                }
            } 

圖像識(shí)別

圖象識(shí)別的話,之前有使用過(guò)openCV,里面的模板匹配應(yīng)該比較符合這里的用法;這樣的圖象識(shí)別在做輔助軟件的時(shí)候特別容易用到,之前都是根據(jù)需要寫(xiě)的一些用顏色作為識(shí)別的算法,每次都要重新寫(xiě),比較操心,所以我自己想寫(xiě)一些通用的、簡(jiǎn)單的圖象識(shí)別方法,可以復(fù)用,類(lèi)似兩張圖片,找出小的圖片在大圖中的位置這種模板匹配;自己利用圖象上的點(diǎn)的顏色來(lái)進(jìn)行對(duì)比判斷寫(xiě)了個(gè)識(shí)別方法(如果兩張圖片每個(gè)點(diǎn)顏色都相同,那圖片肯定就一樣了呀),還行能用,識(shí)別一張圖片2960x1440的大概需要700毫秒左右;如下圖,識(shí)別出圖標(biāo)的位置,我使用半透明的黃色標(biāo)志了一下位置

/**
     * 找有能量的item
     */
    @RequiresApi(api = Build.VERSION_CODES.N)
    private void findEnergyItem() {
        //進(jìn)行截屏
        Bitmap bitmap = ScreenRecordUtil.getInstance().getScreenShot();
        //進(jìn)行圖象識(shí)別
        List<Rect> rects = cross.matching(bitmap, template);
        if (rects.size() > 0) {
            Rect rect = rects.get(0);
            //點(diǎn)擊識(shí)別出的坐標(biāo),進(jìn)入下一個(gè)界面,觸發(fā)下一個(gè)界面的方法進(jìn)行處理
            clickOnScreen((rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2, 10, null);
            SystemClock.sleep(1000);
            return;
        }
        //未找到按鈕
        uiScrolling = true;
        //進(jìn)行滑動(dòng)操作
        performScrollDownward(ScreenUtil.SCREEN_HEIGHT - 100, ScreenUtil.SCREEN_HEIGHT / 2, new AccessibilityService.GestureResultCallback() {
            @Override
            public void onCompleted(GestureDescription gestureDescription) {
                super.onCompleted(gestureDescription);
                //滑動(dòng)完成繼續(xù)識(shí)別
                uiScrolling = false;
            }
        });
    }
未標(biāo)題-2.png-92.5kB

在好友的森林界面的偷能量,也是通過(guò)當(dāng)前頁(yè)面的類(lèi)名和標(biāo)題去判斷當(dāng)前界面處于好友的森林界面

 if (nodeInfo != null) {
            //在好友的森林里面
            if (title != null && !title.equals(ANT_FOREST_TITLE) && title.contains(ANT_FOREST_TITLE)) {
                //進(jìn)行偷能量操作
                if (!isCollecting) {
                    getEnergy();
                    //返回上一頁(yè)
                    performBackClick();
                    SystemClock.sleep(WAIT_SLIPPING_TIME);
                    isCollecting = false;
                }
            }
        }

顏色識(shí)別偷能量

未標(biāo)題-3.png-83.6kB

偷能量的操作,也是圖象識(shí)別去實(shí)現(xiàn),看圖可以知道可收取的能量的顏色有些不同,寫(xiě)個(gè)簡(jiǎn)單的算法,通過(guò)顏色來(lái)判斷一個(gè)點(diǎn)是否有可以獲取的能量,然后模擬點(diǎn)擊進(jìn)行收取

/**
     * 收取能量
     */
    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);
                //顏色對(duì)比可收取能量
                if (labColorLike.isLike(ENERGY_COLOR, currentColor, 10)) {
                    //點(diǎn)擊收取能量
                    clickOnScreen(x, y - 40, 10, null);
                    SystemClock.sleep(50);
                }
            }
        }
    }

總體效果還是不錯(cuò)的,收收能量沒(méi)什么問(wèn)題;其實(shí)也實(shí)現(xiàn)也比較簡(jiǎn)單,就是圖像識(shí)別加上模擬點(diǎn)擊。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容