├── .gitignore ├── README.MD ├── _common.js ├── dnf_helper.js ├── dnf_lite.js ├── docs ├── .nojekyll ├── HTMLSet │ ├── coverpage.md │ └── sidebar.md ├── README.md └── index.html ├── fat_zong.js ├── hello_voice.js ├── mojieren.js ├── qq.js ├── wegame.js ├── wx_dnf_checkin.js └── xinyue.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | 3 | _test.js 4 | wx_yuyue_guahao.js 5 | 6 | test*.js -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # 简介 2 | 基于auto.js实现的dnf蚊子腿相关自动化脚本 3 | 4 | # 使用须知 5 | 目前为了方便编写,大部分操作都是通过点击特定坐标的方式来实现的,目前版本是基于小米 MIX 2(2160 X 1080)的屏幕适配的。 6 | 如果使用该系列脚本,请自行调整各个坐标。 7 | > 目前在初始化时调用了setScreenMetrics函数,理论上如果其他分辨率设备上布局是等比缩放,可以无需调整 8 | 9 | > 基于坐标的脚本通常会有分辨率的问题,这时可以通过setScreenMetrics()函数来进行自动坐标放缩。这个函数会影响本章节的所有点击、长按、滑动等函数。通过设定脚本设计时的分辨率,使得脚本在其他分辨率下自动放缩坐标。 10 | 11 | ## 获取坐标的参考流程 12 | 1. 在手机上打开开发者模式(具体手机操作方法请百度) 13 | 2. 找到【指标位置】的开关,打开以使屏幕叠加层显示当前触摸点坐标。 14 | > MIUI系统应该是这个名称,其他手机请自行百度对应名称。 15 | 16 | ## 其他问题 17 | 更多关于autojs的信息,请查询autojs的[官方文档](https://github.com/hyb1996/AutoJs-Docs) 18 | 19 | # auto.js下载地址 20 | 由于auto.js被各种黑产使用,原作者停止发布auto.js,而是开发与发布加了一些限制的auto.js pro(限制指无法对国内一些app操作,如支付宝、微信、淘宝啥的)。
21 | 为了方便使用,推荐使用之前版本的auto.js。
22 | 以下链接为酷安评论区【点石斋废喵】网友使用之前免费版本源码编译出的apk包,目前我用的也是这个(不提供任何担保,仅方便各位快速找到可用版本)
23 | 1. [点石斋废喵 网友发布的github下载链接](https://github.com/Ericwyn/Auto.js/releases) 24 | 2. [我从他这下载后上传到蓝奏云的链接](https://fzls.lanzous.com/s/djc-helper) 25 | 26 | # 设置自动运行 27 | 可使用autojs自带的定时操作或者使用tasker来定期运行各个脚本~ 28 | 29 | ## auto.js文档中关于定时运行的描述 30 | * 如何定时运行脚本 31 | > 点击脚本右边的菜单按钮->更多->定时任务即可定时运行脚本,但是必须保持Auto.js后台运行(自启动白名单、电源管理白名单等)。同时,可以在脚本的开头使用device.wakeUp()来唤醒屏幕;但是,Auto.js没有解锁屏幕的功能,因此难以在有锁屏密码的设备上达到效果。 32 | 33 | # 各脚本功能简介 34 | ## _common.js 35 | 对auto.js进行的一些封装操作,简化脚本使用流程 36 | 37 | ## dnf_helper.js 38 | dnf助手排行榜活动自动化完成获取鲜花任务以及编年史相关任务脚本 39 | 1. 阅读文字咨询 40 | 2. 阅读视频咨询 41 | 3. 阅读动态 42 | 4. 访问他人主页并关注社区好友 43 | 5. 分享周报 44 | 45 | ## hello_voice.js 46 | hello语音dnf活动自动化脚本 47 | 1. 登录DNF助手以获取Hello贝 48 | 2. 阿拉德勇士征集令活动的投票助力及累积奖励领取 49 | 3. 阿拉德勇士征集令活动的签到、分享、抽奖 50 | 51 | ## wegame.js 52 | 掌上WeGame 每日签到与明日宝藏脚本 53 | 1. 进入福利中心进行自动签到 54 | 2. 限时兑换1-5Q币 55 | 3. 明日宝藏参与明日活动以及领取昨日奖励 56 | 57 | ## wx_dnf_checkin.js 58 | 微信dnf签到活动自动化脚本 59 | 1. 打开文件助手 60 | 2. 打开签到页面(默认文件助手最新一条为签到网页消息) 61 | 3. 签到 62 | 63 | ## xinyue.js 64 | 心悦app G分脚本 65 | 1. G分签到 66 | 2. 自动领取周礼包并抽完全部免费抽奖次数 67 | 3. 兑换复活币到首个角色 68 | 4. 心悦猫咪战斗、历练以及领取历练奖励 -------------------------------------------------------------------------------- /_common.js: -------------------------------------------------------------------------------- 1 | // auto.js参考文档:https://hyb1996.github.io/AutoJs-Docs/ 2 | 3 | module.exports = { 4 | // 所有辅助脚本初始化的操作 5 | init: function (operationName) { 6 | // 当前所有脚本中的坐标都是基于小米 MIX 2(2160 X 1080)的屏幕适配,通过调用该函数,可实现在其他分辨率的设备上自动进行坐标缩放 7 | setScreenMetrics(1080, 2160) 8 | this.log("准备解锁屏幕~") 9 | 10 | // 确保无障碍服务已启用 11 | auto.waitFor() 12 | 13 | // 若处于锁屏状态,则解锁 14 | if (!device.isScreenOn()) { 15 | device.wakeUp() 16 | sleep(1000) 17 | this.swipe("下拉状态栏", 180, 75, 180, 1200, 300) 18 | this.click("点击时间", 150, 170) 19 | } 20 | 21 | this.sleep_default_with_msg("即将开始运行 " + operationName) 22 | }, 23 | 24 | // 双击退出当前应用 25 | exit_current_app: function (msg) { 26 | this.log(msg) 27 | // 双击back,退出当前应用 28 | back() 29 | back() 30 | }, 31 | 32 | // -- 对常用函数的一些封装 -- 33 | launchPackage: function (msg, packageName) { 34 | this.log(msg) 35 | launchPackage(packageName) 36 | this.sleep_long() 37 | this.sleep("额外等待一会", 12) 38 | }, 39 | reLaunchPackage: function (msg, packageName) { 40 | // 先尝试关闭应用 41 | this.shutdownPackage(packageName) 42 | // 然后重新打开 43 | this.launchPackage(msg, packageName) 44 | }, 45 | shutdownPackage: function (packageName) { 46 | appName = app.getAppName(packageName) 47 | 48 | app.openAppSetting(packageName) 49 | this.sleep_default_with_msg("打开" + appName + "的设置界面") 50 | text(appName).waitFor() 51 | 52 | shuwdownBtn = text("结束运行").findOne() 53 | if (shuwdownBtn.enabled()) { 54 | this.click_text("点击 [结束运行] 按钮", "结束运行") 55 | this.click_text("点击 [确定] 按钮", "确定") 56 | } else { 57 | this.sleep_default_with_msg(appName + "目前未在运行,不需要关闭") 58 | } 59 | this.back() 60 | }, 61 | 62 | click: function (msg, x, y) { 63 | this.log(msg) 64 | click(x, y) 65 | this.sleep_default() 66 | }, 67 | click_sleep_long: function (msg, x, y) { 68 | this.log(msg) 69 | click(x, y) 70 | this.sleep_long() 71 | }, 72 | double_click: function (msg, x, y) { 73 | this.log(msg) 74 | click(x, y) 75 | click(x, y) 76 | this.sleep_default() 77 | }, 78 | click_text: function (msg, textToClick) { 79 | this.log(msg) 80 | click(textToClick, 0) 81 | this.sleep_default() 82 | }, 83 | swipe: function (msg, x1, y1, x2, y2, duration) { 84 | this.log(msg) 85 | swipe(x1, y1, x2, y2, duration) 86 | this.sleep_default() 87 | }, 88 | 89 | // 退出到最顶层 90 | back_to_top: function (msg, maxLevel, waitMillSeconds) { 91 | this.log(msg) 92 | for (let i = 0; i < maxLevel; i++) { 93 | back() 94 | sleep(waitMillSeconds) 95 | } 96 | }, 97 | back: function () { 98 | this.log("回到上一层") 99 | back() 100 | this.sleep_default() 101 | }, 102 | 103 | // -- 一些辅助函数 -- 104 | 105 | headline: function (msg) { 106 | sideMsg = "--" 107 | this.log(sideMsg + " " + msg + " " + sideMsg) 108 | sleep(1000) 109 | }, 110 | 111 | foot: function () { 112 | this.log("操作完成,请看看是否ok") 113 | this.sleep_default_with_msg("三秒后将锁屏~") 114 | KeyCode("KEYCODE_POWER"); 115 | }, 116 | 117 | // 在命令行和toast输出日志 118 | log: function log(msg) { 119 | console.info(msg) 120 | toast(msg) 121 | }, 122 | 123 | // 通用等待逻辑 124 | sleep: function (msg, seconds) { 125 | this.log(msg + "(等待" + seconds + "秒)") 126 | sleep(seconds * 1000) 127 | }, 128 | sleep_default: function () { 129 | sleep(5000) 130 | }, 131 | sleep_default_with_msg: function (msg) { 132 | this.log(msg) 133 | this.sleep_default() 134 | }, 135 | sleep_long: function () { 136 | sleep(8000) 137 | }, 138 | } 139 | -------------------------------------------------------------------------------- /dnf_helper.js: -------------------------------------------------------------------------------- 1 | let common = require("_common.js") 2 | 3 | common.init("dnf助手自动完成编年史相关任务脚本") 4 | 5 | common.reLaunchPackage("重新打开 助手app", "com.tencent.gamehelper.dnf") 6 | 7 | common.headline("阅读资讯") 8 | common.click("点击 [资讯] tab", 140, 2080) 9 | common.click("点击 [精选] 分页", 88, 244) 10 | common.click("点击 [第一条资讯]", 650, 1150) 11 | common.back_to_top("返回首页", 2, 3000) 12 | 13 | common.headline("阅读视频资讯") 14 | common.click("点击 [资讯] tab", 140, 2080) 15 | common.log("视频分页在屏幕外面,所以需要先用 关注 中转一下") 16 | common.click("点击 [关注] 分页", 965, 244) 17 | common.click("点击 [视频] 分页", 715, 244) 18 | 19 | let commentBtns = className("android.widget.TextView").id("info_coment_count").find() 20 | for (let i=0; i< commentBtns.length;i++) { 21 | let commentBtn = commentBtns[i] 22 | titleTextView = commentBtn.parent().parent().parent().parent().parent().child(0) 23 | if (commentBtn.text() !== "" && titleTextView.text() !== "") { 24 | commentBtn.click() 25 | common.sleep_default_with_msg("点击 [某条视频资讯评论按钮以进入详情页],视频标题为【" + titleTextView.text() + "】") 26 | break 27 | } 28 | } 29 | 30 | common.back_to_top("返回首页", 2, 3000) 31 | common.log("需要额外点击分页以回到最初分页,确保后续执行初始状态一致") 32 | common.click("点击 [百科] 分页", 110, 244) 33 | common.click("点击 [作品] 分页", 365, 244) 34 | common.click("点击 [精选] 分页", 88, 244) 35 | 36 | common.headline("阅读动态") 37 | common.click("点击 [动态] tab", 400, 2080) 38 | common.click("点击 [第一条动态]", 650, 1150) 39 | common.back_to_top("返回首页", 2, 3000) 40 | 41 | common.headline("访问他人主页并关注社区好友") 42 | common.click("点击 [动态] tab", 400, 2080) 43 | common.click("点击 [第一条动态的发送者头像] 以进入其主页", 95, 1050) 44 | common.click("点击 [加好友] 关注他", 1000, 345) 45 | common.click("点击 [...] 打开选项框", 1013, 138) 46 | common.click_text("点击 [删除好友] 取消关注", "删除好友") 47 | common.back_to_top("返回首页", 2, 3000) 48 | 49 | common.headline("分享周报") 50 | common.click("点击 [我的] tab", 940, 2080) 51 | common.click("点击 [游戏数据/周报] 图标", 165, 1920) 52 | common.sleep_default_with_msg("额外等待一会") 53 | common.swipe("下滑到第4页", 540, 600, 540, 1600, 1000) 54 | common.click_text("点击 [立即分享]", "立即分享") 55 | common.click("点击 [空白处] 跳回,无需实际分享", 725, 1100) 56 | // common.click("点击 [QQ好友]", 620, 1818) 57 | // common.sleep_default_with_msg("等待几秒后,直接返回即可,无需实际分享") 58 | // common.back() 59 | // common.click_text("点击 [小号群]", "小号群") 60 | // common.click("点击 [发送]", 745, 1580) 61 | // common.click("点击 [返回DNF助手]", 340, 1205) 62 | for (let i = 1; i <= 6; i++) { 63 | common.click("第" + i + "次点击 [空白处] 以避免多次分享的bug", 725, 1100) 64 | } 65 | common.back_to_top("返回首页", 2, 3000) 66 | 67 | common.foot() 68 | -------------------------------------------------------------------------------- /dnf_lite.js: -------------------------------------------------------------------------------- 1 | // by 泡@842155114 2 | let common = require("_common.js") 3 | 4 | common.init("dnf助手 Lite") 5 | 6 | common.launchPackage("打开助手app并等待一段时间", "com.tencent.gamehelper.dnf") 7 | common.back_to_top("按多次back,确保跳到最顶层", 5, 3000) 8 | 9 | common.headline("打开DNF Lite") 10 | common.click("点击 [三横杠] 进入左侧栏", device.width*0.065, device.height*0.06) 11 | common.click("点击 [DNF Lite]", device.width*0.075, device.height*0.47) 12 | common.sleep_default() 13 | common.click("点击 [开始]", device.width*0.5, device.height*0.945) 14 | 15 | main() 16 | 17 | // common.click("点击 [抽一次]", 335, 1500) 18 | // common.click("点击 [抽十次]", 775, 1500) 19 | 20 | function main(){ 21 | var stop = false 22 | // 抽奖并挑战 23 | while(!stop){ 24 | freeLottery() 25 | var flag = payLottery() 26 | if(!flag) 27 | stop = start() 28 | } 29 | } 30 | 31 | function start(){ 32 | var flag = true 33 | common.click("点击 [地下城]", 500, 1850) 34 | var sences = ["继续挑战","进入阿拉德","进入天界"] 35 | for (sence of sences) { 36 | while(text(sence).exists()){ 37 | common.click_text("点击 [挑战]",sence) 38 | sleep(3000) 39 | if(text("挑战地下城").exists()){ 40 | break 41 | } 42 | challenge() 43 | flag = false 44 | } 45 | } 46 | common.click("点击 [关闭]", device.width*0.5, device.height*0.86) 47 | return flag 48 | } 49 | 50 | function challenge(){ 51 | while(desc("GO>").exists()){ 52 | // common.click("点击 [摇色子]", 550, 1970) 53 | desc("GO>").click() 54 | sleep(6000) 55 | fighting() 56 | } 57 | } 58 | 59 | function fighting(){ 60 | if(click("挑战")){ 61 | sleep(8000) 62 | if(text("跳过").exists()) 63 | common.click_text("点击 [跳过]","跳过") 64 | while(!desc("GO>").exists()){ 65 | sleep(1000) 66 | common.click("点击屏幕", device.width*0.51, device.height*0.59) 67 | if(text("挑战地下城").exists()) 68 | break 69 | } 70 | } 71 | } 72 | 73 | function freeLottery(){ 74 | let free = className("android.view.View").text("免费").find() 75 | for (let item of free) { 76 | item.parent().child(0).click() 77 | sleep(3000) 78 | while(text("获得道具").exists()||text("获得角色").exists()||text("获得武器").exists()){ 79 | common.click("点击 [空白处]", device.width*0.8, device.height*0.4) 80 | sleep(1000) 81 | } 82 | } 83 | } 84 | 85 | function payLottery(){ 86 | common.click("点击 [抽十次]", device.width*0.72, device.height*0.68) 87 | // 判断是否还有金币抽奖 88 | sleep(3000) 89 | if(!(text("获得道具").exists()||text("获得角色").exists()||text("获得武器").exists())) 90 | return false 91 | while(text("获得道具").exists()||text("获得角色").exists()||text("获得武器").exists()){ 92 | common.click("点击 [空白处]", device.width*0.8, device.height*0.4) 93 | sleep(1000) 94 | } 95 | return true 96 | } 97 | 98 | // common.back_to_top("返回首页", 2, 3000) 99 | 100 | engines.myEngine().forceStop(); 101 | 102 | // common.foot() 103 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fzls/autojs/bd93aa3f7bdb209a9bf06ccd83ab699eef5ad9a4/docs/.nojekyll -------------------------------------------------------------------------------- /docs/HTMLSet/coverpage.md: -------------------------------------------------------------------------------- 1 | ![avatar](https://s1.ax1x.com/2020/11/02/BrG0C4.jpg) 2 | 3 | # DNF蚊子腿小助手 auto.js版本 4 | 5 | > DNF蚊子腿小助手的补充内容,使用auto.js来模拟手动操作以完成一些无法通过模拟发请求完成的流程或很难模拟的流程 6 | 7 | - JavaScript编写 8 | - 由风之凌殇独立实现 9 | - 需要基于auto.js运行 10 | - 总访问量 11 | - 总访客 12 | 13 | [软件介绍](#main) 14 | [相关源码](https://github.com/fzls/autojs) 15 | -------------------------------------------------------------------------------- /docs/HTMLSet/sidebar.md: -------------------------------------------------------------------------------- 1 | - **入门** 2 | - [程序简介](./README.md) 3 | - [使用教程](https://hyb1996.github.io/AutoJs-Docs/#/) 4 | - [B站教程](https://space.bilibili.com/1851177) 5 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # 简介 2 | 基于auto.js实现的dnf蚊子腿相关自动化脚本 3 | 4 | # 使用须知 5 | 目前为了方便编写,大部分操作都是通过点击特定坐标的方式来实现的,目前版本是基于小米 MIX 2(2160 X 1080)的屏幕适配的。 6 | 如果使用该系列脚本,请自行调整各个坐标。 7 | > 目前在初始化时调用了setScreenMetrics函数,理论上如果其他分辨率设备上布局是等比缩放,可以无需调整 8 | 9 | > 基于坐标的脚本通常会有分辨率的问题,这时可以通过setScreenMetrics()函数来进行自动坐标放缩。这个函数会影响本章节的所有点击、长按、滑动等函数。通过设定脚本设计时的分辨率,使得脚本在其他分辨率下自动放缩坐标。 10 | 11 | ## 获取坐标的参考流程 12 | 1. 在手机上打开开发者模式(具体手机操作方法请百度) 13 | 2. 找到【指标位置】的开关,打开以使屏幕叠加层显示当前触摸点坐标。 14 | > MIUI系统应该是这个名称,其他手机请自行百度对应名称。 15 | 16 | ## 其他问题 17 | 更多关于autojs的信息,请查询autojs的[官方文档](https://github.com/hyb1996/AutoJs-Docs) 18 | 19 | # auto.js下载地址 20 | 由于auto.js被各种黑产使用,原作者停止发布auto.js,而是开发与发布加了一些限制的auto.js pro(限制指无法对国内一些app操作,如支付宝、微信、淘宝啥的)。
21 | 为了方便使用,推荐使用之前版本的auto.js。
22 | 以下链接为酷安评论区【点石斋废喵】网友使用之前免费版本源码编译出的apk包,目前我用的也是这个(不提供任何担保,仅方便各位快速找到可用版本)
23 | 1. [点石斋废喵 网友发布的github下载链接](https://github.com/Ericwyn/Auto.js/releases) 24 | 2. [我从他这下载后上传到蓝奏云的链接](https://fzls.lanzous.com/s/djc-helper) 25 | 26 | # 设置自动运行 27 | 可使用autojs自带的定时操作或者使用tasker来定期运行各个脚本~ 28 | 29 | ## auto.js文档中关于定时运行的描述 30 | * 如何定时运行脚本 31 | > 点击脚本右边的菜单按钮->更多->定时任务即可定时运行脚本,但是必须保持Auto.js后台运行(自启动白名单、电源管理白名单等)。同时,可以在脚本的开头使用device.wakeUp()来唤醒屏幕;但是,Auto.js没有解锁屏幕的功能,因此难以在有锁屏密码的设备上达到效果。 32 | 33 | # 各脚本功能简介 34 | ## _common.js 35 | 对auto.js进行的一些封装操作,简化脚本使用流程 36 | 37 | ## dnf_helper.js 38 | dnf助手排行榜活动自动化完成获取鲜花任务以及编年史相关任务脚本 39 | 1. 阅读文字咨询 40 | 2. 阅读视频咨询 41 | 3. 阅读动态 42 | 4. 访问他人主页并关注社区好友 43 | 5. 分享周报 44 | 45 | ## hello_voice.js 46 | hello语音dnf活动自动化脚本 47 | 1. 登录DNF助手以获取Hello贝 48 | 2. 阿拉德勇士征集令活动的投票助力及累积奖励领取 49 | 3. 阿拉德勇士征集令活动的签到、分享、抽奖 50 | 51 | ## wegame.js 52 | 掌上WeGame 每日签到与明日宝藏脚本 53 | 1. 进入福利中心进行自动签到 54 | 2. 限时兑换1-5Q币 55 | 3. 明日宝藏参与明日活动以及领取昨日奖励 56 | 57 | ## wx_dnf_checkin.js 58 | 微信dnf签到活动自动化脚本 59 | 1. 打开文件助手 60 | 2. 打开签到页面(默认文件助手最新一条为签到网页消息) 61 | 3. 签到 62 | 63 | ## xinyue.js 64 | 心悦app G分脚本 65 | 1. G分签到 66 | 2. 自动领取周礼包并抽完全部免费抽奖次数 67 | 3. 兑换复活币到首个角色 68 | 4. 心悦猫咪战斗、历练以及领取历练奖励 -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | DNF蚊子腿小助手 auto.js版本 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 34 | 35 | 36 | 37 |
38 | 39 |
40 | 41 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /fat_zong.js: -------------------------------------------------------------------------------- 1 | let common = require("_common.js") 2 | 3 | common.log("肥腙大战魔界小脚本") 4 | 5 | skill_x_list = [250, 560, 880, 1200] 6 | skill_y = 2625 7 | wait_seconds = 0.5 8 | 9 | while (true) { 10 | for (let idx = 1; idx <= skill_x_list.length; ++idx) { 11 | skill_x = skill_x_list[idx-1] 12 | 13 | common.log( "双击第 " + idx + " 个技能,然后等待 " + wait_seconds + " 秒") 14 | click(skill_x, skill_y) 15 | click(skill_x, skill_y) 16 | sleep(wait_seconds * 1000) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /hello_voice.js: -------------------------------------------------------------------------------- 1 | let common = require("_common.js") 2 | 3 | common.init("hello语音dnf活动自动化脚本") 4 | 5 | common.reLaunchPackage("重新打开 hello语音", "com.yy.huanju") 6 | 7 | common.click("处理可能弹出的开屏活动页", 935, 420) 8 | common.back() 9 | common.sleep("等待签到界面弹出", 10) 10 | common.click("处理首次登录会弹出的签到按钮", 540, 1425) 11 | common.click("处理可能弹出的青少年模式提示", 540, 1360) 12 | common.back_to_top("按多次back,确保跳到最顶层", 5, 3000) 13 | 14 | common.headline("获取Hello贝") 15 | common.click("点击 [首页] Tab", 105, 2050) 16 | common.click("点击 [游戏] 分页", 78, 160) 17 | common.click_sleep_long("点击 [游戏中心]", 200, 720) 18 | common.click_text("点击 [福利与活动]", "福利与活动") 19 | common.click_text("点击 [我的hello贝]", "我的hello贝") 20 | common.click("点击 登录DNF助手 右侧的 [去完成]", 930, 2100) 21 | common.sleep_default_with_msg("等待助手进入完毕") 22 | common.exit_current_app("退出DNF助手,回到Hello语音") 23 | common.sleep_default_with_msg("等待助手退出完毕") 24 | common.click("点击 登录DNF助手 右侧的 [领取]", 930, 2100) 25 | common.back_to_top("返回首页", 2, 3000) 26 | 27 | // common.headline("获取Hello贝") 28 | // common.click("点击 [首页] Tab", 105, 2050) 29 | // common.click("点击 [游戏] 分页", 78, 160) 30 | // common.click_sleep_long("点击 [游戏中心]", 200, 720) 31 | // common.click_text("点击 [DNF家族]", "DNF家族") 32 | // common.click_text("点击 [回家]", "回家") 33 | // common.click_sleep_long("点击 [签到]", 185, 1370) 34 | // common.back_to_top("返回首页", 4, 3000) 35 | 36 | common.foot() 37 | -------------------------------------------------------------------------------- /mojieren.js: -------------------------------------------------------------------------------- 1 | let common = require("_common.js") 2 | 3 | common.init("点击微信支付按钮来尝试购买魔界人粘土人") 4 | 5 | common.launchPackage("打开chrome", "com.android.chrome") 6 | 7 | const initDuration = 10 8 | const waitDuration = 5 9 | const payUrl = "https://dnfcity.qq.com/mobile/html/cart_pay.html####" 10 | 11 | common.sleep("请在 " + initDuration + " 秒内打开魔界人支付界面(需要先在购物车页面完成登录),以便脚本进行点击尝试。链接为 " + payUrl + "", initDuration) 12 | 13 | let tryIndex = 0; 14 | while (true) { 15 | tryIndex += 1 16 | common.click_text("[ " + tryIndex + " ] 点击 [微信支付],并在 " + waitDuration + " 秒后重试", "微信支付") 17 | } 18 | 19 | common.foot() 20 | -------------------------------------------------------------------------------- /qq.js: -------------------------------------------------------------------------------- 1 | let common = require("_common.js") 2 | 3 | common.init("基于手机QQ做的网页活动") 4 | 5 | common.reLaunchPackage("重新打开QQ", "com.tencent.mobileqq") 6 | 7 | common.headline("预购活动每日免费抽奖") 8 | 9 | // QQ暂时没找到直接定位一个对话框的法子,换一个思路,改为从搜索栏入手 10 | common.sleep("重新打开QQ需要等待半分钟,等待必要内容加载完毕,否则搜索功能会没有结果", 60) 11 | let searchBar = className("android.widget.TextView").text("搜索").findOne() 12 | common.click("点击 [搜索] 框", searchBar.bounds().centerX(), searchBar.bounds().centerY()) 13 | common.back() 14 | 15 | let newSearchEdit = className("android.widget.EditText").text("搜索").findOne() 16 | newSearchEdit.setText("我的电脑") 17 | common.sleep("搜索 [我的电脑],需要耗费一些时间,等待若干时间", 30) 18 | 19 | let myComputer = className("android.widget.TextView").text("我的电脑").findOne() 20 | common.click("点击 [我的电脑] 对话框", myComputer.bounds().centerX(), myComputer.bounds().centerY()) 21 | 22 | let activityUrlTextView = className("android.widget.TextView").text("https://pay.qq.com/h5/activity/dnf_dqgylb_lottery.php").findOne() 23 | common.click("点击 [预购活动链接] 聊天记录", activityUrlTextView.bounds().centerX(), activityUrlTextView.bounds().centerY()) 24 | 25 | common.swipe("1/2 上滑直至[领取抽奖券]界面完全展现", 540, 2000, 540, 300, 1000) 26 | common.swipe("2/2 上滑直至[领取抽奖券]界面完全展现", 540, 2000, 540, 300, 1000) 27 | 28 | let takeDailyLoginTicketBtn = className("android.view.View").text("每日登录抽奖券×1").findOne().parent().parent().child(2) 29 | common.click("点击 [立即领取] 每日登录抽奖券×1", takeDailyLoginTicketBtn.bounds().centerX(), takeDailyLoginTicketBtn.bounds().centerY()) 30 | common.click_text("点击 [确定]", "确定") 31 | 32 | let takeLuckyTicketBtn = className("android.view.View").text("幸运用户抽奖券×1").findOne().parent().parent().child(2) 33 | common.click("点击 [立即领取] 幸运用户抽奖券×1", takeLuckyTicketBtn.bounds().centerX(), takeLuckyTicketBtn.bounds().centerY()) 34 | common.click_text("点击 [确定]", "确定") 35 | 36 | common.swipe("1/2 上滑直至[抽奖界面]界面完全展现", 540, 2000, 540, 300, 1000) 37 | 38 | // 为了保险起见,多点几次 39 | for (let i = 0; i < 3; i++) { 40 | common.click("第" + (i+1) + "次点击 [立即开奖] 按钮", 550, 1100) 41 | common.sleep_default_with_msg("额外等待一会,确保抽奖动画完毕") 42 | common.click("第" + (i+1) + "次点击 [关闭奖励展示] 按钮(可能需要调整)", 550, 1405) 43 | } 44 | 45 | common.back_to_top("跳回主界面", 3, 3000) 46 | 47 | common.foot() 48 | -------------------------------------------------------------------------------- /wegame.js: -------------------------------------------------------------------------------- 1 | let common = require("_common.js") 2 | 3 | common.init("掌上WeGame 每日签到与明日宝藏脚本") 4 | 5 | common.launchPackage("打开掌上WeGame", "com.tencent.tgp") 6 | common.click("点击 [首页] tab以跳过开屏推送", 135, 2080) 7 | 8 | common.headline("进入福利中心进行自动签到") 9 | common.click("点击 [首页] tab", 135, 2080) 10 | common.click("点击 [福利中心] 图标", 1015, 130) 11 | 12 | let myWelfare = className("android.view.View").text("我的福利").findOne() 13 | let signResult = myWelfare.parent().child(myWelfare.indexInParent() + 1).child(0).child(1) 14 | common.sleep_default_with_msg("签到信息:" + signResult.text()) 15 | 16 | // 获取banner view,进而获取y轴信息 17 | let hotActivities = className("android.view.View").text("热门活动").findOne() 18 | let bannerRecycleView = hotActivities.parent().child(hotActivities.indexInParent() + 1) 19 | let bannerY = bannerRecycleView.bounds().centerY() 20 | common.sleep_default_with_msg("活动页面图标的Y轴中心为 " + bannerY) 21 | 22 | let firstActivityXPosition = 150 23 | let activityWidth = 350 24 | let secondActivityPosition = firstActivityXPosition + activityWidth 25 | let thirdActivityPosition = firstActivityXPosition + 2 * activityWidth 26 | let processedActivities = [] 27 | let currentMyPoints = 0 28 | 29 | // 点击前三个活动 30 | let activityXPositions = [firstActivityXPosition, secondActivityPosition, thirdActivityPosition] 31 | for (let i = 0; i < activityXPositions.length; i++) { 32 | currentMyPoints = parseInt(myWelfare.parent().child(myWelfare.indexInParent() + 1).child(1).child(2).text(), 10) 33 | common.click("点击 第" + (i + 1) + "个 活动图标", activityXPositions[i], bannerY) 34 | doActivity() 35 | } 36 | // 点击后面几个活动。目前实际只有五个活动页面,为了保险起见,多处理俩 37 | for (let i = 4; i <= 7; i++) { 38 | currentMyPoints = parseInt(myWelfare.parent().child(myWelfare.indexInParent() + 1).child(1).child(2).text(), 10) 39 | common.swipe("向左滑动一个活动图标的距离,使下一个滑动滑动到当前最后一个活动的位置", thirdActivityPosition, bannerY, secondActivityPosition, bannerY, 1000) 40 | common.click("点击 第" + i + "个 活动图标", thirdActivityPosition, bannerY) 41 | doActivity() 42 | } 43 | 44 | // 统计一下处理的活动列表 45 | common.sleep_default_with_msg("本次共处理了以下活动: " + processedActivities) 46 | 47 | let tomorrowTreasureProcessed = false 48 | 49 | // 根据当前活动页面title,决定不同的处理方式 50 | function doActivity() { 51 | // 获取活动页面的title 52 | let title = className("android.widget.LinearLayout").id("actionbar_middle_container").findOne().child(0).text() 53 | 54 | if (processedActivities.indexOf(title) === -1) { 55 | processedActivities.push(title) 56 | 57 | common.sleep("当前页面标题为:" + title + " ,多等待一会,确保加载完毕", 10) 58 | 59 | switch (title) { 60 | case "福利中心-限时兑换": 61 | common.headline("限时兑换1-5Q币") 62 | // 兑换完对应Q币,须确保剩余积分不少于这个数 63 | needLeftAtLeast = 0 64 | if (!tomorrowTreasureProcessed) { 65 | // 如果今天的明日宝藏尚未投资,则至少需要保留1000的积分 66 | needLeftAtLeast += 1000 67 | } 68 | 69 | // 首先尝试使用1500积分兑换5Q币 70 | if (currentMyPoints >= needLeftAtLeast + 1500) { 71 | common.click("点击 [1500积分兑换] 5Q币", 800, 1120) 72 | common.click("点击 [确定] 按钮", 540, 1320) 73 | currentMyPoints -= 1500 74 | } else { 75 | common.sleep_default_with_msg("当前积分为" + currentMyPoints + "分,为了确保能兑换明日宝藏,当前应至少有" + (needLeftAtLeast + 1500) + "分,故而不使用1500积分兑换本次的5Q币") 76 | } 77 | // 然后再尝试使用300积分兑换1Q币 78 | if (currentMyPoints >= needLeftAtLeast + 300) { 79 | common.click("点击 [300积分兑换] 1Q币", 800, 725) 80 | common.click("点击 [确定] 按钮", 540, 1320) 81 | currentMyPoints -= 300 82 | } else { 83 | common.sleep_default_with_msg("当前积分为" + currentMyPoints + "分,为了确保能兑换明日宝藏,当前应至少有" + (needLeftAtLeast + 300) + "分,故而不使用300积分兑换本次的1Q币") 84 | } 85 | break 86 | 87 | case "活动中心": 88 | common.headline("明日宝藏") 89 | common.headline("进入后将自动领取昨日参与的宝箱,将在明天自动开启~") 90 | common.headline("参与明日的宝藏") 91 | common.click("点击 [我要参加] 按钮(无昨日宝箱)", 700, 1420) 92 | common.click("点击 [我要参加] 按钮(有昨日宝箱)", 700, 1600) 93 | common.click("点击 [空白处] 干掉输入框", 700, 1400) 94 | // 通过我的积分来向上跳三层找到表格组件 95 | formDialogView = className("android.view.View").text("我的积分 :").findOne().parent().parent().parent() 96 | let currentScores = parseInt(formDialogView.child(0).child(1).child(1).text(), 10) 97 | let actualUseScore = Math.min(currentScores, 1000) 98 | common.sleep_default_with_msg("当前积分为:" + currentScores + "分") 99 | if (actualUseScore >= 10) { 100 | formDialogView.child(0).child(2).child(1).setText(actualUseScore) 101 | common.sleep_default_with_msg("投入积分(上限1000):" + actualUseScore) 102 | formDialogView.child(6).click() 103 | common.sleep_default_with_msg("点击 [确定] 按钮 参与明日的宝藏活动") 104 | common.click("点击 [确定] 按钮", 550, 1440) 105 | } else { 106 | common.sleep_default_with_msg("当前积分为" + actualUseScore + "分,参与活动至少需要10分~") 107 | } 108 | 109 | tomorrowTreasureProcessed = true 110 | break 111 | 112 | default: 113 | common.sleep_default_with_msg("活动 【" + title + "】目前尚未支持,将跳过~") 114 | } 115 | } else { 116 | common.sleep_default_with_msg("活动 【" + title + "】 已经处理过了,将直接跳过~") 117 | } 118 | 119 | common.back() 120 | } 121 | 122 | 123 | common.back_to_top("返回首页", 1, 3000) 124 | 125 | common.foot() 126 | -------------------------------------------------------------------------------- /wx_dnf_checkin.js: -------------------------------------------------------------------------------- 1 | let common = require("_common.js") 2 | 3 | let clickLeftTopBackButton = function (totalCount) { 4 | for (let i = 0; i < totalCount; i++) { 5 | common.click("点击左上角返回键", 50, 135) 6 | } 7 | } 8 | 9 | common.init("微信dnf公众号相关活动自动化脚本") 10 | 11 | common.launchPackage("打开微信", "com.tencent.mm") 12 | 13 | common.log("先确保跳到首页") 14 | clickLeftTopBackButton(5) 15 | common.click("点击 [微信] tab", 140, 2075) 16 | common.double_click("双击跳到最上方", 50, 135) 17 | 18 | // common.headline("每日签到") 19 | // common.click_text("点击 [文件传输助手] 对话框", "文件传输助手") 20 | // common.click_text("点击 [签到页面] 聊天记录", "每日签到") 21 | // // 为了保险起见,多点几次 22 | // for (let i = 0; i < 3; i++) { 23 | // common.click("第" + i + "次点击 [签到] 按钮", 535, 1370) 24 | // } 25 | // clickLeftTopBackButton(2) 26 | 27 | common.headline("微信答题") 28 | common.click_text("点击 [地下城与勇士] 对话框", "地下城与勇士") 29 | let switchToTextInputBtn = className("android.widget.ImageView").desc("消息").findOne() 30 | common.click("点击 左下角的 [文字输入] 按钮", switchToTextInputBtn.bounds().centerX(), switchToTextInputBtn.bounds().centerY()) 31 | // hack: 版本更新的时候需要调整这个id 32 | let inputArea = className("android.widget.ImageView").desc("服务按钮").findOne() // 左下角按钮 ImageView 33 | .parent().parent() // 最下方tab容器 LinearLayout 34 | .child(1) // 除左下角按钮外的右侧控件的容器 LinearLayout 35 | .child(1) // 中间控件容器 LinearLayout 36 | .child(0) // ScrollView 37 | .child(0) // LinearLayout 38 | .child(0) // FrameLayout 39 | .child(0) // EditText 40 | 41 | let possibleAnswers = ["dta", "dtb", "dtc", "dtd"] 42 | for (let idx = 0; idx < possibleAnswers.length; idx++) { 43 | answer = possibleAnswers[idx] 44 | 45 | inputArea.setText(answer) 46 | common.sleep_default_with_msg("输入 " + answer) 47 | 48 | let sendBtn = className("android.widget.Button").text("发送").findOne() 49 | common.click("点击 [发送] 按钮", sendBtn.bounds().centerX(), sendBtn.bounds().centerY()) 50 | } 51 | common.back() 52 | common.click_text("点击 [文件传输助手] 对话框", "文件传输助手") 53 | common.click_text("点击 [抽奖] 聊天记录", "抽奖") 54 | // 为了保险起见,多点几次 55 | for (let i = 1; i <= 3; i++) { 56 | common.click("第" + i + "次点击 [抽奖] 按钮", 545, 1770) 57 | common.click("第" + i + "次点击 [确定] 按钮", 400, 1235) 58 | } 59 | clickLeftTopBackButton(2) 60 | 61 | common.foot() 62 | -------------------------------------------------------------------------------- /xinyue.js: -------------------------------------------------------------------------------- 1 | let common = require("_common.js") 2 | 3 | common.init("心悦app G分脚本") 4 | 5 | common.reLaunchPackage("打开心悦app", "com.tencent.tgclub") 6 | common.click("点击 [屏幕中央] 以进入可能存在的开屏推送", 500, 1400) 7 | common.back() 8 | 9 | common.headline("G分相关内容") 10 | common.click("点击 [权益] Tab", 950, 2100) 11 | common.click("点击 [G分] 按钮", 740, 600) 12 | 13 | common.headline("G分签到") 14 | common.click("点击 [立即签到] 按钮", 540, 475) 15 | common.click("点击 [确认] 按钮", 550, 1360) 16 | 17 | common.headline("赚G分") 18 | // 为了保险起见,多滑动几次 19 | for (let i = 0; i < 2; i++) { 20 | common.swipe("上滑直至[赚G分]内容完全展现", 540, 2100, 540, 150, 1000) 21 | } 22 | 23 | xPositions = [400, 950] 24 | for (let i = 0; i < xPositions.length; i++) { 25 | common.click("点击 [赚G分活动] 区域 x=" + xPositions[i], xPositions[i], 1900) 26 | 27 | let webview_title = className("android.widget.TextView").findOne().text() 28 | switch (webview_title) { 29 | case "心悦周礼包": 30 | common.headline("周礼包已经在小助手中实现,这里将直接跳过~") 31 | // common.headline("周礼包") 32 | // common.click("点击 [一键领取] 按钮", 900, 1615) 33 | // common.click("点击 [X] 以关闭领取成功", 925, 875) 34 | // common.click("点击 [X] 以关闭待领取通知", 925, 990) 35 | // let remainingLotteryCount = parseInt(className("android.view.View").depth(9).findOne().text(), 10) 36 | // common.sleep_default_with_msg("剩余免费抽奖次数为" + remainingLotteryCount + "次") 37 | // for (let i = 0; i < remainingLotteryCount; i++) { 38 | // common.click("点击 [免费抽奖] 按钮", 540, 1375) 39 | // common.click("点击 [稍后查看] 按钮", 365, 1475) 40 | // } 41 | break 42 | case "理财礼卡": 43 | common.headline("理财礼卡已经在小助手中实现,这里将直接跳过~") 44 | // common.headline("理财礼卡") 45 | // common.swipe("上滑直至[四个礼包]内容居中", 540, 1600, 540, 1100, 1000) 46 | // common.click("点击 [600G分购买] 升级版月卡", 750, 1777) 47 | // common.click("点击 [确认购买] 升级版月卡", 350, 1250) 48 | // common.click("点击 [确认]", 550, 1435) 49 | // common.click("点击 [确认购买] 升级版月卡", 350, 1250) 50 | // common.click("点击 [确认]", 550, 1435) 51 | break 52 | default: 53 | common.sleep_default_with_msg("未找到活动【" + webview_title + "】的处理函数") 54 | } 55 | 56 | common.back() 57 | } 58 | 59 | common.headline("游戏礼包") 60 | for (let i = 0; i < 2; i++) { 61 | common.swipe("下滑直至[游戏礼包]内容完全展现", 540, 500, 540, 2100, 1000) 62 | } 63 | 64 | // 获取一下最新G分数值,供后续逻辑使用 65 | let currentGPoints = parseInt(className("android.widget.TextView").id("new_integral_value_txt").findOne().text(), 10) 66 | common.sleep_default_with_msg("当前G分为" + currentGPoints) 67 | 68 | common.click_text("点击 [游戏礼包] 区域", "游戏礼包") 69 | // common.swipe("因为其他手游,dnf被刷到下面,需要滑动一下", 540, 1480, 540, 680, 1000) 70 | 71 | // 只有在G分不低于600(妆容-贤德昭仪)+300(装饰-小橘子)+600(理财礼卡-升级版月卡)+300(理财礼卡-体验版月卡)+本次兑换所需G分时,才尝试进行本次的兑换 72 | let needLeftAtLeast = 600 + 300 + 600 + 300 73 | if (currentGPoints >= needLeftAtLeast + 44) { 74 | let exchangeFuHuoCoinButton = className("android.widget.TextView").textContains("复活币*5").findOne().parent().parent().child(2) 75 | let buttonY = exchangeFuHuoCoinButton.bounds().centerY() 76 | common.sleep_default_with_msg("复活币所在Y轴为" + buttonY) 77 | 78 | common.click("点击 [复活币*5] 右侧的兑换按钮", 930, buttonY) 79 | common.click("点击 [确认兑换] 按钮", 760, 1430) 80 | common.click("点击 [确认] 按钮", 550, 1360) 81 | currentGPoints -= 44 82 | } else { 83 | common.sleep_default_with_msg("当前G分为" + currentGPoints + "分,为了确保能购买心悦猫咪的妆容和装饰,当前应至少有" + (needLeftAtLeast + 44) + "分,故而不使用44G分兑换本次的复活币*5") 84 | } 85 | 86 | common.back() 87 | 88 | let enable_xinyue_cat = false 89 | if (enable_xinyue_cat) { 90 | common.headline("心悦猫咪") 91 | 92 | common.headline("领取历练奖励") 93 | common.click_text("点击 [心悦猫咪] 区域", "心悦猫咪") 94 | common.sleep("加载很慢,多等一段时间", 25) 95 | common.click("点击 [领取礼包] 按钮", 170, 1725) 96 | common.click("点击 [好的] 按钮", 550, 1380) 97 | common.back() 98 | 99 | common.headline("尝试购买妆容和装饰") 100 | common.click_text("点击 [心悦猫咪] 区域", "心悦猫咪") 101 | common.sleep("加载很慢,多等一段时间", 25) 102 | common.click("点击 [商店] 按钮", 910, 1725) 103 | 104 | // 小橘子的七日收益率较高,故而先尝试购买小橘子 105 | // 成本 300 106 | // 收益 30*2*7=420 107 | // 净利润 120 108 | // 收益率 120/300 = 40% 109 | common.click("点击 [装饰] 按钮", 790, 390) 110 | decorationMap = { 111 | "喷香猫粮": "icon-00", 112 | "飞车酷比": "icon-01", 113 | "飞车墨汁": "icon-02", 114 | "炫舞粉66": "icon-03", 115 | "炫舞酷66": "icon-04", 116 | "云裳茶壶": "icon-05", 117 | "云裳童心饰": "icon-06", 118 | "小橘子": "icon-07", 119 | } 120 | // common.sleep_default_with_msg("目前G分不太够,先不购买300G分的小橘子。等俩月卡都买完再开启") 121 | locateItemAndTryBuyIt("小橘子", decorationMap) 122 | 123 | // 贤德昭仪的七日收益率较低,故而在后面买 124 | // 成本 600 125 | // 收益 50*2*7=700 126 | // 净利润 100 127 | // 收益率 100/600 = 16.66% 128 | common.click("点击 [妆容] 按钮", 290, 390) 129 | makeupMap = { 130 | "富贵士绅": "icon-01", 131 | "加班女仆": "icon-02", 132 | "浪子刀客": "icon-03", 133 | "世家公子": "icon-04", 134 | "偶像歌手": "icon-05", 135 | "煮饭仙人": "icon-06", 136 | "古玩大亨": "icon-07", 137 | "杰克国王": "icon-08", 138 | "贤德昭仪": "icon-09", 139 | "名射击手": "icon-11", 140 | "尾灯少女": "icon-12", 141 | "屠龙勇士": "icon-13", 142 | "赤子仙童": "icon-14", 143 | "鸾舞佳人": "icon-15", 144 | "王牌地主": "icon-16", 145 | "月半半": "icon-17", 146 | "魔力娃娃": "icon-18", 147 | "雪豹战士": "icon-20", 148 | "沉甸甸": "icon-21", 149 | "节奏大师": "icon-22", 150 | "Carry猫": "icon-23", 151 | } 152 | // common.sleep_default_with_msg("目前G分不太够,先不购买600G分的贤德昭仪。等俩月卡都买完再开启") 153 | locateItemAndTryBuyIt("贤德昭仪", makeupMap) 154 | 155 | function locateItemAndTryBuyIt(targetName, nameToIconTextMap) { 156 | iconText = nameToIconTextMap[targetName] 157 | let notOwnText = className("android.view.View").text("未拥有").findOne() 158 | let itemList = notOwnText.parent().parent().parent().child(1).child(0) 159 | for (let i = 0; i < itemList.childCount(); i++) { 160 | item = itemList.child(i) 161 | 162 | let image_icon = item.child(item.childCount() - 2).child(0).text() 163 | if (image_icon !== iconText) { 164 | continue 165 | } 166 | 167 | item.click() 168 | common.sleep_default_with_msg("已定位到【" + targetName + "】,并完成点击,等待一会确保状态显示完成") 169 | 170 | let infoPanel = notOwnText.parent().parent().parent().parent().parent().child(1) 171 | let buyButton = infoPanel.child(1) 172 | if (buyButton.text() === "已拥有") { 173 | common.sleep_default_with_msg("已经拥有 " + targetName + " ,本次不尝试购买") 174 | } else { 175 | common.sleep_default_with_msg("尚未拥有 " + targetName + " ,即将尝试进行购买") 176 | common.click("点击购买 " + targetName, buyButton.bounds().centerX(), buyButton.bounds().centerY()) 177 | // common.click("点击 取消", 350,1250) 178 | common.click("点击 确定", 735, 1250) 179 | } 180 | 181 | // 找到目标后停止处理 182 | break 183 | } 184 | } 185 | 186 | common.back() 187 | 188 | common.headline("穿戴妆容和装饰") 189 | common.click_text("点击 [心悦猫咪] 区域", "心悦猫咪") 190 | common.sleep("加载很慢,多等一段时间", 25) 191 | common.click("点击 [仓库] 按钮", 990, 815) 192 | 193 | common.click("点击 [装饰] 按钮", 790, 390) 194 | locateItemAndTryUseIt("小橘子", decorationMap) 195 | 196 | common.click("点击 [妆容] 按钮", 290, 390) 197 | locateItemAndTryUseIt("贤德昭仪", makeupMap) 198 | 199 | function locateItemAndTryUseIt(targetName, nameToIconTextMap) { 200 | iconText = nameToIconTextMap[targetName] 201 | let returnBtnView = className("android.view.View").text("返回按钮").findOne() 202 | let itemList = returnBtnView.parent().child(3).child(0).child(0) 203 | let found = false 204 | for (let i = 0; i < itemList.childCount(); i++) { 205 | item = itemList.child(i) 206 | 207 | let imageView = item.child(0) 208 | // 一般图标是最后一个子元素 209 | let image_icon = imageView.child(imageView.childCount() - 1) 210 | if (image_icon.childCount() === 0) { 211 | // 有时候会是倒数第二个 212 | image_icon = imageView.child(imageView.childCount() - 2) 213 | } 214 | if (image_icon.child(0).text() !== iconText) { 215 | continue 216 | } 217 | 218 | // 已穿戴|穿戴 219 | // 已装饰|装饰 220 | let statusBtn = item.child(1) 221 | let status = statusBtn.text() 222 | if (status === "穿戴" || status === "装饰") { 223 | // 点击穿戴/装饰 224 | statusBtn.click() 225 | common.sleep_default_with_msg("尚未" + status + targetName + ",点击 " + status + " 按钮进行" + status) 226 | 227 | let useBtnView = returnBtnView.parent().child(4).child(0).child(1).child(2) 228 | common.click("点击" + status + targetName, useBtnView.bounds().centerX(), useBtnView.bounds().centerY()) 229 | 230 | let closeBtnView = useBtnView.parent().parent().child(0) 231 | common.click(status + "完成,点击右上角关闭按钮", closeBtnView.bounds().centerX(), closeBtnView.bounds().centerY()) 232 | } else if (status === "到期续费") { 233 | statusBtn.click() 234 | common.sleep_default_with_msg(targetName + "已过期,点击 " + status + " 按钮进行续费") 235 | 236 | let buyBtnView = returnBtnView.parent().child(4).child(0).child(1).child(2) 237 | common.click("点击 续期按钮 续期" + targetName, buyBtnView.bounds().centerX(), buyBtnView.bounds().centerY()) 238 | 239 | common.click("点击 确定 进行购买", 735, 1250) 240 | 241 | common.click("点击 好的", 540, 1320) 242 | 243 | let useBtnView = returnBtnView.parent().child(4).child(0).child(1).child(2) 244 | common.click("点击" + status + targetName, useBtnView.bounds().centerX(), useBtnView.bounds().centerY()) 245 | 246 | let closeBtnView = useBtnView.parent().parent().child(0) 247 | common.click(status + "完成,点击右上角关闭按钮", closeBtnView.bounds().centerX(), closeBtnView.bounds().centerY()) 248 | } else { 249 | common.sleep_default_with_msg(status + targetName + ",本次无需额外操作~") 250 | } 251 | 252 | // 找到目标后停止处理 253 | found = true 254 | break 255 | } 256 | 257 | if (!found) { 258 | common.sleep_default_with_msg("未能找到 " + targetName + ",应该是尚未购买~") 259 | } 260 | } 261 | 262 | common.back() 263 | 264 | common.headline("战斗与历练") 265 | common.click_text("点击 [心悦猫咪] 区域", "心悦猫咪") 266 | common.sleep("加载很慢,多等一段时间", 25) 267 | let infoListView = className("android.widget.ListView").depth(11).rowCount(3).findOne() 268 | let gPoints = parseInt(infoListView.child(0).text(), 10) 269 | let fightingCapacity = parseInt(infoListView.child(1).text(), 10) 270 | let yuanQi = parseInt(infoListView.child(2).text(), 10) 271 | 272 | let totalFightCount = Math.floor(yuanQi / 20) 273 | common.headline("将进行战斗次数为:" + totalFightCount) 274 | if (totalFightCount > 0) { 275 | let fightUsingTime = 15 276 | 277 | common.click("点击 [战斗] 按钮,触发首次战斗", 420, 1725) 278 | common.sleep("等待猫咪战斗结束", fightUsingTime) 279 | 280 | for (let i = 2; i <= totalFightCount; i++) { 281 | common.click("点击 [我还能打] 按钮,触发第" + i + "次战斗", 710, 1350) 282 | common.sleep("等待猫咪战斗结束", fightUsingTime) 283 | } 284 | 285 | common.click("点击 [不了怕了] 按钮", 370, 1350) 286 | } else { 287 | common.sleep_default_with_msg("元气不足20,无法进行战斗") 288 | } 289 | 290 | common.headline("历练") 291 | if (fightingCapacity >= 15) { 292 | common.click("点击 [历练] 按钮", 170, 1725) 293 | levels = [ 294 | {stage: 1, x: 850, y: 1750}, 295 | {stage: 2, x: 250, y: 1200}, 296 | {stage: 3, x: 875, y: 900}, 297 | {stage: 4, x: 500, y: 575}, 298 | ] 299 | stage = 1 300 | if (15 <= fightingCapacity && fightingCapacity < 55) { 301 | stage = 1 302 | } else if (55 <= fightingCapacity && fightingCapacity < 90) { 303 | stage = 2 304 | } else if (90 <= fightingCapacity && fightingCapacity < 130) { 305 | stage = 3 306 | } else if (130 <= fightingCapacity) { 307 | stage = 4 308 | } 309 | common.sleep_default_with_msg("当前战力为 " + fightingCapacity + ", 最高可打第" + stage + "关,将依次尝试该关一直到第二关,直到找到一个可以进行的关卡") 310 | do { 311 | let levelPos = levels[stage - 1] 312 | common.click("点击 [第" + levelPos.stage + "关] 按钮", levelPos.x, levelPos.y) 313 | common.click("点击 [去吧] 按钮 或 当该关卡无剩余次数时出现的 [好的] 按钮", 700, 1500) 314 | common.click("若提示关卡已经猫满为患,点击 [好的] 按钮", 700, 1320) 315 | 316 | stage -= 1 317 | } while (stage >= 2) 318 | } else { 319 | common.sleep_default_with_msg("战力不足15,无法进行历练~") 320 | } 321 | common.back() 322 | } else { 323 | common.sleep_default_with_msg("心悦猫咪在小助手中实现了,因此脚本内增加开关,并默认关闭心悦猫咪逻辑") 324 | } 325 | 326 | common.back() 327 | 328 | common.foot() 329 | --------------------------------------------------------------------------------