又一个起点福利中心的AutoX.js脚本

文章正文
发布时间:2025-06-28 03:22

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

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

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

// 初始化 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```



Screenshot_20231030_023837.jpg (221.93 KB, 下载次数: 0)

下载附件

2023-10-30 02:46 上传



Screenshot_20231030_023827.jpg (222.45 KB, 下载次数: 0)

下载附件

2023-10-30 02:46 上传



更新:

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   感谢发布原创作品,吾爱破解论坛因你更精彩!  

查看全部评分