吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7515|回复: 85
上一主题 下一主题
收起左侧

[其他原创] 又一个起点福利中心的AutoX.js脚本

  [复制链接]
跳转到指定楼层
楼主
lq2007 发表于 2023-10-30 02:48 回帖奖励
本帖最后由 lq2007 于 2024-8-13 11:06 编辑

起因是我发现大号的签到和小号的不同了,新版的福利界面旧脚本不匹配,就自己重写了个。目前可以兼容两个版本的福利中心。

该版本支持玩游戏挂机,并会在挂机时保持屏幕常亮,注意手机电量充足。

目前仍有一些问题,首页签到没有制作(不打算做,和另一个跳过广告的工具冲突)


// 初始化
console.show();
auto.waitFor();

const regex_ad_1 = /观看视频(\d+)秒后,可获得奖励/
const regex_ad_2 = /收听(\d+)秒有声书可获得奖励/
const regex_game = /(\d+)\/(\d+)分钟/
let textView;

// 启动起点
app.launchPackage('com.qidian.QDReader');
waitForPackage('com.qidian.QDReader');
waitForActivity('com.qidian.QDReader.ui.activity.MainGroupActivity');
waitView("书架").click();
log("应用已识别");

// #region 签到
log("签到 开始");
while (textContains("登录领奖").exists()) {
    log("  等待登录状态...");
    sleep(500);
}
if (textView = findView("签到")) {
    clickButton(textView);
    sleep(1000);
    back();
}
log("签到 结束");
// #endregion

// 我 [- 青少年模式] - 福利中心
clickButton(findView("我"));
sleep(1000)
if (textView = findView('我知道了')) {
    clickButton(textView)
}
clickButton(waitView("福利中心"));
waitForActivity("com.qidian.QDReader.ui.activity.QDBrowserActivity");
waitView("限时彩蛋");

// #region 每日福利
log("每日福利 开始");
while ((textView = findView("看第\\d+个视频", "match")) 
 || (textView = findView("看视频领福利")) 
 || (textView = findView("看视频开宝箱"))) {
    clickButton(textView);
    watchAds();
    sleep(500);
}
log("每日福利 结束");
// #endregion

// #region 限时彩蛋
log("限时彩蛋 开始");
while(textView = findView("看视频")) {
    clickButton(textView);
    watchAds();
    sleep(1000);
}
log("限时彩蛋 结束");
// #endregion

// 领奖励
log("领奖励 开始");
while(textView = findView("领奖励")) {
    clickButton(textView);
    sleep(1000);
    if (textView = findView("我知道了")) {
        clickButton(textView);
    }
}
log("领奖励 结束");

// #region 玩游戏
log("玩游戏 开始");
if (textView = findView("当日玩游戏10分钟")) {
    let layout = textView.parent();
    let playView = layout.findOne(text("去完成"));
    if (playView) {
        // 计算剩余时间
        textView = layout.findOne(text("/10分钟")).parent();
        views = textView.find(className("TextView"));
        views.forEach(o => log(o));
        textView = views[views.length - 2];

        let gameTimes = parseInt(textView.text());
        let playMinutes = Math.max(10 - gameTimes, 1);
        log(playMinutes);
        // 玩游戏
        clickButton(playView);
        waitForActivity("com.qidian.QDReader.ui.activity.QDBrowserActivity");
        clickButton(waitView("新游"));
        waitForActivity("com.qidian.QDReader.ui.activity.GameBrowserActivity");
        clickButton(waitView("在线玩"));
        sleep(1000);
        for (let i = playMinutes + 1; i > 0; --i) {
            log(`剩余 ${i}min`);
            for (let j = 0; j < 60; ++j) {
                sleep(1100);
                device.wakeUpIfNeeded();
            }
        }
        device.vibrate(500);
        // 游戏页(无标题) - 新游 - 游戏中心 - 福利中心
        while (!findView("福利中心")) {
            back();
            sleep(1000);
        }
    }
}
sleep(1000);
log("玩游戏 结束");
// #endregion

// 领奖励
log("领奖励 开始");
while(textView = findView("领奖励")) {
    clickButton(textView);
    sleep(1000);
    if (textView = findView("我知道了")) {
        clickButton(textView);
    }
}
log("领奖励 结束");

// 结束
log("返回书架");
back();
waitForActivity('com.qidian.QDReader.ui.activity.MainGroupActivity');
clickButton(waitView("书架"));

log("运行结束");
sleep(5000);
console.hide();

/**
 * 根据正则表达式查找字符串中的值
 * @param {string} str 字符串
 * @param {RegExp} regex 正则表达式
 * @param {number|undefined} count 结果个数
 * @returns 当数量不少于需要的个数时,返回以 1 开头的数组
 */
function findValueFromString(str, regex, count) {
    if (!count) count = 1;
    let m = regex.exec(str);
    return (m && m.length >= count + 1) ? m : undefined;
}

/**
 * 查找带有某个文本的控件
 * @param {string} content 查找文本
 * @param {string} mode 查找方式,详见 findViewBy
 * @returns 第一个符合条件的控件,不存在返回 undefined
 */
function findView(content, mode) {
    log(`查找控件 ${content}`);
    let find = findViewBy(content, mode);
    return find && find.exists() ? find.findOnce() : undefined;
}

/**
 * 查找带有某个文本的控件
 * @param {string} content 查找文本
 * @param {string} mode 查找方式,详见 findViewBy
 * @returns 第一个符合条件的控件
 */
function waitView(content, mode) {
    log(`等待控件 ${content}`);
    let view = findViewBy(content, mode);
    view.waitFor();
    return view.findOnce();
}

/**
 * 查找控件
 * @param {string} content 查找文本 
 * @param {string} mode 查找方式,默认 text,可选 match,id
 * @returns selector 
 */
function findViewBy(content, mode) {
    let find;
    if (mode === 'class') {
        find = className(content)
    } else if (mode === 'match') {
        find = textMatches(content);
    } else if (mode === 'id') {
        find = id(content)
    } else {
        find = text(content);
    }
    return find;
}

/**
 * 根据文字查找按钮并点击
 * @param {UiObject} view 按钮上的文字所在 view
 * @returns 是否成功点击
 */
function clickButton(view) {
    log("点击 " + view.text());
    // 查找按钮所在控件
    let btn = view;
    while (btn && !btn.clickable()) {
        btn = btn.parent();
    }
    // 点击
    if (btn) {
        btn.click();
        return true;
    }
    return false;
}

/**
 * 看广告,等待广告结束并关闭广告
 * @returns 是否播放完成
 */
function watchAds() {
    let times = 0;
    let adType = 0;
    while (true) {
        log("等待广告中 " + times.toString());
        if (textView = findView("观看视频\\d+秒后,可获得奖励", 'match')) {
            let adTime = findValueFromString(textView.text(), regex_ad_1);
            // 应该不会有比 45s 更长的广告了吧
            adTime = adTime ? adTime[1] : 45;
            log(`广告时间:${adTime}+3s`);
            sleep(adTime * 1000);
            sleep(3000); // 额外休眠 3s
            break;
        } else if (textView = findView("收听\\d+秒有声书可获得奖励", 'match')) {
            let adTime = findValueFromString(textView.text(), regex_ad_2);
            adType = 1;
            // 这个一般就十几秒,取 20s
            adTime = adTime ? adTime[1] : 20;
            log(`广告时间:${adTime}+3s`);
            // 有些广告默认暂停
            if (textView = findView('')) {
                log("开始播放");
                clickButton(textView)
            }
            sleep(adTime * 1000);
            sleep(3000); // 额外休眠 3s
            break;
        } else if (textView = findView("观看完视频,可获得奖励")) {
            while ((textView = findView("跳过广告"))) {
                sleep(1000);
            }
            break;
        } else if (textView = findView("跳过视频")) {
            clickButton(textView);
            log("广告观看失败");
            return false;
        }
        sleep(500);
        times++;
        if (times > 50) {
            device.vibrate(300);
            log("广告识别出现问题, 请检查是否正常继续进行");
            return false;
        }
    }
    // 结束
    if (adType == 1) {
        let adView = findView('com.tencent.tbs.core.webkit.WebView', 'class')
        if (adView) {
            while (!adView.children().isEmpty()) {
                adView = adView.children()[0]
            }
            clickButton(adView)
            clickButton(findView("我"));
            clickButton(waitView("福利中心"));
            waitForActivity("com.qidian.QDReader.ui.activity.QDBrowserActivity");
            waitView("限时彩蛋");
        } else if (adView = findView('')) {
            clickButton(adView)
        } else {
            className('Button').text('').findOne().click();
        }
    } else if (textView = findView("跳过广告")) {
        clickButton(textView);
    } else {
        let closeButton = className("ImageView").filter(o => o.clickable()).findOnce();
        if (closeButton) closeButton.click();
        else return false;
    }
    // 等待 我知道了
    sleep(1000);
    if (textView = findView("我知道了")) {
        clickButton(textView);
    }
    log("广告已结束")
    return true;
}

// #region Debug

/**
 * 在控制台输出某个视图及所有子视图
 * @param {UiObject} view 视图
 * @param {number|undefined} level 空格等级
 */
function logView(view, level) {
    if (!level) level = 0;
    let s = "";
    for (let i = 0; i < level; ++i) s += " ";
    log(`${s}${view}`);
    view.children().forEach(v => logView(v, level + 2));
}

/**
 * 在控制台输出当前屏幕所有视图的内容
 * @param {UiObject} child 内部任意一个子视图
 */
function logRootView(child) {
    if (!child) {
        child = classNameContains("").findOnce()
    }

    let pl = 0;
    let pv = child.parent();
    while (pv) {
        pl++;
        child = pv;
        pv = child.parent();
    }
    log(pl);
    logView(child);
}

// #endregion```






更新:

2024/02/20 起点新的广告比之前的方便多了,顺便把游戏也改了改。源代码已上传github:https://github.com/luiqn2007/qidian_qiandao/tree/master
2024/02/21 添加了部分延迟和遗漏的 我知道了 的点击
2024/02/29 修复部分 我知道了 按钮点击错误
2024/03/15 修改广告检查过程,运行失败震动提示
2024/03/16 调整广告后延迟 3s,尽量保证广告播放完成
2024/04/11 适配有声书广告
2024/08/02 修复有声书广告
2024/08/13 修复有声书广告,(测试)跳过青少年模式

免费评分

参与人数 13吾爱币 +19 热心值 +12 收起 理由
wataxi + 1 谢谢@Thanks!
「指尖﹏独舞」 + 1 + 1 热心回复!
恰恰恰 + 1 + 1 谢谢@Thanks!
Fzero + 1 + 1 谢谢@Thanks!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Marr + 1 + 1 热心回复!
wu0o0pj + 1 + 1 我很赞同!
laotun + 1 + 1 我很赞同!
小学生一枚 + 1 + 1 谢谢@Thanks!
potato614 + 1 + 1 大佬牛逼,,这玩意非常需要
manwu + 1 + 1 我很赞同!
ingdear + 1 + 1 虽然不明白是干什么的,但并不影响我高喊牛B。
衍东子 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
 楼主| lq2007 发表于 2023-10-31 00:03 |楼主

GitHub找kkevsekk1/AutoX,安装后把脚本导入即可
推荐
marco527 发表于 2023-10-30 07:57
推荐
 楼主| lq2007 发表于 2024-3-15 01:49 |楼主
3#
twj007 发表于 2023-10-30 08:19
没看明白是干什么用的
4#
kgdwfn 发表于 2023-10-30 08:26

感谢楼主的分享.
5#
ashergo 发表于 2023-10-30 08:38
感谢楼主分享,学习学习
6#
syz87 发表于 2023-10-30 08:47
有成品就更好了
7#
hfhdkh 发表于 2023-10-30 09:01
谢谢分享,哦那个用用看
8#
yh2023 发表于 2023-10-30 09:08
感谢楼主分享
9#
lxf001002 发表于 2023-10-30 09:13
这个怎么用的
10#
ydna1234 发表于 2023-10-30 09:27
感谢LZ分享~~~~
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 06:05

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表