不会编程如何制作Android辅助功能?

最近一直在研究冰狐智能辅助,上次利用冰狐智能辅助实现了一个免费的个人收款系统,用起来还行,说实话刚开始我有怀疑过平台的稳定性,现在看来是有点多虑了。最近看官网更新了一个针对菜鸟设计的通过配置直接生成脚本功能「自动构建」,个人觉得很好奇,有点高大上,于是利用约会的时间研究了一把。用「自动构建」,没写一行代码,实现了一个薅羊毛程序(纯属个人兴趣研究,禁止用于任何商业用途),现把该薅羊毛程序作为例子进行讲解,分享菜鸟(不会编程的同学)是如何快速实现辅助功能的。

准备工作

  1. 手机端安装「冰狐智能辅助」,详细安装过程请看这里
  2. 手机端安装「爱奇艺极速版」v1.10.6,注意,必须安装这个版本,不同的版本操作界面可能不同,可能会导致辅助功能失效。点击这里从豌豆荚官网下载该版本
  3. 注册「爱奇艺极速版」用户并登陆。

制作辅助功能

  1. 进入「移动端」/「自动构建」,新建名为”爱奇艺极速版“的自动构建。
  2. 点击“配置源码”按钮,将如下json数据粘贴进去,保存。
    
         
         
    1. {
    2. "type": "root",
    3. "children": [{
    4. "type": "declareVar",
    5. "var": [{
    6. "name": "ret",
    7. "type": "normal",
    8. "initType": "null",
    9. "initValue": "null"
    10. }, {
    11. "name": "view",
    12. "type": "normal",
    13. "initType": "null",
    14. "initValue": "null"
    15. }, {
    16. "name": "viewContainer",
    17. "type": "normal",
    18. "initType": "null",
    19. "initValue": "null"
    20. }, {
    21. "name": "item",
    22. "type": "normal",
    23. "initType": "null",
    24. "initValue": "null"
    25. }],
    26. "desc": "变量声明"
    27. }, {
    28. "type": "launchApp",
    29. "packageName": "com.qiyi.video.lite",
    30. "findTag": "txt:首页-",
    31. "failed": "exitPopup",
    32. "maxStep": "30",
    33. "children": [{
    34. "type": "log",
    35. "log": "启动app成功",
    36. "desc": "启动成功日志",
    37. "info": [ "string-app启动成功"],
    38. "log_type": "log"
    39. }, {
    40. "type": "switchPage",
    41. "returnVar": "",
    42. "findTag": "txt:开宝箱-",
    43. "checkTag": "txt:活动规则-",
    44. "root": "",
    45. "click": "true",
    46. "failed": "exitPopupWithAD",
    47. "descendant": "[]",
    48. "duration": "500",
    49. "maxStep": "5",
    50. "beforeWait": "0",
    51. "afterWait": "0",
    52. "children": [{
    53. "type": "log",
    54. "desc": "开始日志",
    55. "log_type": "log",
    56. "info": [ "string-进入任务"]
    57. }, {
    58. "type": "task",
    59. "scrollCount": "2",
    60. "returnTag": "txt:活动规则-",
    61. "taskDeal": [{
    62. "key": "txt^:免费抽大奖-",
    63. "value": {
    64. "type": "switchPage",
    65. "desc": "切换到幸运大转盘",
    66. "returnVar": "",
    67. "findTag": "txt^:免费抽大奖-",
    68. "checkTag": "txt:幸运大转盘-",
    69. "root": "",
    70. "click": "true",
    71. "failed": "exitPopupWithAD",
    72. "descendant": [],
    73. "duration": "500",
    74. "maxStep": "5",
    75. "beforeWait": "0",
    76. "afterWait": "0",
    77. "children": [{
    78. "type": "loop",
    79. "desc": "循环多次处理抽奖",
    80. "class": "2",
    81. "startIndex": "0",
    82. "endIndex": "20",
    83. "children": [{
    84. "type": "findView",
    85. "desc": "搜索控件",
    86. "viewDeal": [{
    87. "key": "txt^:恭喜到账-traverse_one_by_one",
    88. "value": {
    89. "type": "loop",
    90. "desc": "退出到账",
    91. "class": "4",
    92. "container": "view",
    93. "descendant": "[-1,-1]",
    94. "children": [{
    95. "type": "if",
    96. "desc": "条件处理",
    97. "expr": "item.clickable",
    98. "children": [{
    99. "type": "log",
    100. "desc": "日志",
    101. "log_type": "log",
    102. "info": [ "string-click x,and exit"]
    103. }, {
    104. "type": "click",
    105. "desc": "点击控件",
    106. "class": "2",
    107. "click": "true",
    108. "descendant": [],
    109. "beforeWait": "0",
    110. "afterWait": "0",
    111. "target": "item"
    112. }, {
    113. "type": "break",
    114. "desc": "跳出循环"
    115. }]
    116. }]
    117. }
    118. }, {
    119. "key": "txt$:后再来-",
    120. "value": {
    121. "type": "break",
    122. "desc": "跳出循环"
    123. }
    124. }, {
    125. "key": "txt^:lottery-list-",
    126. "value": {
    127. "type": "custom",
    128. "desc": "抽奖",
    129. "code": "var txt = view.parent.parent.parent[2][0].text;\nconsole.log('txt:' + txt);\nvar num = parseInt(txt);\nif (num > 0) {\ngestureClick((view.left + view.right) / 2, (view.top + view.bottom) / 2, {afterWait: 8000});\nconsole.log('点击开始抽奖');\n} else {\nconsole.log('抽奖结束');\nbreak;\n}"
    130. }
    131. }, {
    132. "key": "txt^:lottery-list-",
    133. "value": {
    134. "type": "if",
    135. "desc": "条件处理",
    136. "expr": "parseInt(view.parent.parent.parent[2][0].text)>0",
    137. "children": [{
    138. "type": "click",
    139. "desc": "点击控件",
    140. "class": "4",
    141. "duration": "500",
    142. "beforeWait": "0",
    143. "afterWait": "8000",
    144. "x": "0",
    145. "y": "0",
    146. "unit": "px"
    147. }]
    148. }
    149. }],
    150. "root": "",
    151. "failed": "exitPopupWithAD",
    152. "duration": "500",
    153. "maxStep": "10",
    154. "beforeWait": "0",
    155. "afterWait": "0",
    156. "false": {
    157. "type": "break",
    158. "desc": "跳出循环"
    159. }
    160. }],
    161. "descendant": []
    162. }, {
    163. "type": "back2Page",
    164. "desc": "返回页面",
    165. "returnVar": "",
    166. "tag": "txt:我的|txt:活动规则-",
    167. "root": "",
    168. "backFirst": "true",
    169. "failed": "",
    170. "duration": "500",
    171. "maxStep": "5",
    172. "beforeWait": "0",
    173. "afterWait": "0"
    174. }],
    175. "false": {
    176. "type": "log",
    177. "desc": "日志",
    178. "log_type": "error",
    179. "info": [ "string-切换到大转盘失败"]
    180. }
    181. }
    182. }, {
    183. "key": "txt:开宝箱领金币|txt$:每日可领-",
    184. "value": {
    185. "type": "click",
    186. "desc": "点击控件",
    187. "class": "2",
    188. "click": "true",
    189. "descendant": [],
    190. "beforeWait": "0",
    191. "afterWait": "1000",
    192. "target": "view"
    193. }
    194. }],
    195. "maxDealCount": "8",
    196. "failed": "exitPopupWithAD",
    197. "desc": "任务处理",
    198. "removeTag": true
    199. }, {
    200. "type": "log",
    201. "desc": "结束日志",
    202. "log_type": "log",
    203. "info": [ "string-任务结束"]
    204. }],
    205. "desc": "切换到任务频道",
    206. "false": {
    207. "type": "log",
    208. "desc": "日志",
    209. "log_type": "error",
    210. "info": [ "string-进入任务失败"]
    211. }
    212. }, {
    213. "type": "switchPage",
    214. "returnVar": "",
    215. "findTag": "txt:首页-",
    216. "checkTag": "txt:电视剧-",
    217. "root": "",
    218. "click": "true",
    219. "failed": "exitPopupWithAD",
    220. "descendant": [],
    221. "duration": "500",
    222. "maxStep": "5",
    223. "beforeWait": "0",
    224. "afterWait": "0",
    225. "children": [{
    226. "type": "mainLoop",
    227. "minRunTime": "2",
    228. "maxRunTime": "5",
    229. "minScrollCount": "1",
    230. "maxScrollCount": "3",
    231. "containerTag": "cn:androidx.recyclerview.widget.RecyclerView-",
    232. "failed": "exitPopupWithAD",
    233. "children": [{
    234. "type": "log",
    235. "log": "开始看视频了哦",
    236. "desc": "日志",
    237. "info": [ "string-开始看电视了哦"],
    238. "log_type": "log"
    239. }, {
    240. "type": "loopPicker",
    241. "desc": "从循环中挑选某些项处理",
    242. "startIndex": "1",
    243. "lastIndex": "1",
    244. "random": true,
    245. "children": [{
    246. "type": "click",
    247. "desc": "点击电视",
    248. "class": "2",
    249. "click": "true",
    250. "descendant": [],
    251. "beforeWait": "0",
    252. "afterWait": "0",
    253. "target": "sChild"
    254. }, {
    255. "type": "findView",
    256. "desc": "查看是否进入电视",
    257. "returnVar": "",
    258. "tag": "txt*:/|txt:金蛋奖励-",
    259. "root": "",
    260. "failed": "exitPopup",
    261. "duration": "500",
    262. "maxStep": "5",
    263. "beforeWait": "0",
    264. "afterWait": "0",
    265. "children": [{
    266. "type": "loop",
    267. "desc": "看电视",
    268. "breakTag": "txt:完成-",
    269. "failed": "",
    270. "minRunTime": "0.5",
    271. "maxRunTime": "1.2",
    272. "class": 1
    273. }],
    274. "viewDeal": [{
    275. "key": "txt*:/|txt:金蛋奖励-",
    276. "value": {
    277. "type": "loop",
    278. "desc": "看电视",
    279. "class": 1,
    280. "breakTag": "txt:完成-",
    281. "failed": "exitPopup",
    282. "minRunTime": "0.7",
    283. "maxRunTime": "1.2",
    284. "descendant": [],
    285. "children": [{
    286. "type": "click",
    287. "desc": "关闭广告",
    288. "class": 1,
    289. "tag": "txt:关闭此广告-",
    290. "root": "",
    291. "click": "true",
    292. "failed": "",
    293. "descendant": [],
    294. "duration": "500",
    295. "maxStep": "5",
    296. "beforeWait": "0",
    297. "afterWait": "0"
    298. }]
    299. }
    300. }],
    301. "false": {
    302. "type": "log",
    303. "desc": "日志",
    304. "log_type": "log",
    305. "info": [ "string-进入电视失败"]
    306. }
    307. }, {
    308. "type": "click",
    309. "desc": "领金币",
    310. "class": 1,
    311. "tag": "txt:领金币-",
    312. "root": "",
    313. "click": "true",
    314. "failed": "",
    315. "descendant": [],
    316. "duration": "500",
    317. "maxStep": "5",
    318. "beforeWait": "0",
    319. "afterWait": "0"
    320. }, {
    321. "type": "click",
    322. "desc": "领不固定金币",
    323. "class": 1,
    324. "tag": "txt^:领-",
    325. "root": "",
    326. "click": "true",
    327. "failed": "",
    328. "descendant": [],
    329. "duration": "500",
    330. "maxStep": "5",
    331. "beforeWait": "0",
    332. "afterWait": "0"
    333. }, {
    334. "type": "back2Page",
    335. "desc": "返回页面",
    336. "returnVar": "",
    337. "tag": "txt:我的-",
    338. "root": "",
    339. "backFirst": "true",
    340. "failed": "",
    341. "duration": "500",
    342. "maxStep": "5",
    343. "beforeWait": "0",
    344. "afterWait": "0"
    345. }]
    346. }],
    347. "returnTag": "txt:我的-",
    348. "skipProb": "80",
    349. "desc": "滚动屏幕看电视",
    350. "findContainerFailed": {}
    351. }],
    352. "desc": "切换到电视剧频道",
    353. "false": {
    354. "type": "log",
    355. "desc": "日志",
    356. "log_type": "error",
    357. "info": [ "string-进入看电视失败"]
    358. }
    359. }, {
    360. "type": "switchPage",
    361. "desc": "切换到短视频",
    362. "returnVar": "",
    363. "findTag": "txt:短视频-",
    364. "checkTag": "txt:推荐-",
    365. "root": "",
    366. "click": "true",
    367. "failed": "exitPopupWithAD",
    368. "descendant": [],
    369. "duration": "500",
    370. "maxStep": "5",
    371. "beforeWait": "0",
    372. "afterWait": "0",
    373. "false": {
    374. "type": "log",
    375. "desc": "切换失败日志",
    376. "log_type": "error",
    377. "info": [ "string-切换短视频失败"]
    378. },
    379. "children": [{
    380. "type": "mainLoop",
    381. "desc": "主循环",
    382. "containerTag": "cn:androidx.recyclerview.widget.RecyclerView-",
    383. "returnTag": "-",
    384. "skipProb": "0",
    385. "failed": "exitPopup",
    386. "minRunTime": "2",
    387. "maxRunTime": "3",
    388. "minScrollCount": "1",
    389. "maxScrollCount": "1",
    390. "children": [{
    391. "type": "log",
    392. "desc": "日志",
    393. "log_type": "log",
    394. "info": [ "string-开始看小视频了"]
    395. }, {
    396. "type": "loop",
    397. "desc": "循环",
    398. "breakTag": "",
    399. "failed": "",
    400. "minRunTime": "0.1",
    401. "maxRunTime": "0.5",
    402. "class": 1
    403. }, {
    404. "type": "break",
    405. "desc": "跳出循环"
    406. }]
    407. }]
    408. }],
    409. "false": {
    410. "type": "log",
    411. "log": "启动APP失败",
    412. "desc": "日志",
    413. "log_type": "error",
    414. "info": [ "string-启动app失败"]
    415. },
    416. "desc": "启动APP"
    417. }, {
    418. "type": "popup",
    419. "name": "exitPopup",
    420. "exitPopupDeal": [{
    421. "key": "txt:暂不升级|txt:我知道了-",
    422. "value": {
    423. "type": "click",
    424. "desc": "点击控件",
    425. "class": "2",
    426. "click": "true",
    427. "descendant": [],
    428. "beforeWait": "0",
    429. "afterWait": "0",
    430. "target": "view"
    431. }
    432. }, {
    433. "key": "txt:猜你想看-",
    434. "value": {
    435. "type": "click",
    436. "desc": "点击控件",
    437. "class": 1,
    438. "tag": "txt:取消-",
    439. "root": "",
    440. "click": "true",
    441. "failed": "",
    442. "descendant": [],
    443. "duration": "500",
    444. "maxStep": "5",
    445. "beforeWait": "0",
    446. "afterWait": "0"
    447. }
    448. }, {
    449. "key": "txt^:再赚-",
    450. "value": {
    451. "type": "click",
    452. "desc": "点击控件",
    453. "class": "2",
    454. "click": "false",
    455. "descendant": [],
    456. "beforeWait": "0",
    457. "afterWait": "0",
    458. "target": "view"
    459. }
    460. }, {
    461. "key": "txt:恭喜获得-",
    462. "value": {
    463. "type": "click",
    464. "desc": "点击控件",
    465. "class": "2",
    466. "click": "true",
    467. "descendant": [- 1, 4],
    468. "beforeWait": "0",
    469. "afterWait": "0",
    470. "target": "view"
    471. }
    472. }, {
    473. "key": "txt^:恭喜到账-",
    474. "value": {
    475. "type": "click",
    476. "desc": "点击控件",
    477. "class": "2",
    478. "click": "true",
    479. "descendant": [- 1, 2, 0],
    480. "beforeWait": "0",
    481. "afterWait": "0",
    482. "target": "view"
    483. }
    484. }, {
    485. "key": "txt:继续赚钱-",
    486. "value": {
    487. "type": "click",
    488. "desc": "点击控件",
    489. "class": "2",
    490. "click": "true",
    491. "descendant": "[-1,-1,-1,1]",
    492. "beforeWait": "0",
    493. "afterWait": "0",
    494. "target": "view"
    495. }
    496. }, {
    497. "key": "txt^:打开日历提醒-",
    498. "value": {
    499. "type": "click",
    500. "desc": "点击控件",
    501. "class": "2",
    502. "click": "true",
    503. "descendant": "[-1,7]",
    504. "beforeWait": "0",
    505. "afterWait": "0",
    506. "target": "view"
    507. }
    508. }],
    509. "false": "[]",
    510. "desc": "处理弹窗"
    511. }, {
    512. "type": "popup",
    513. "name": "exitPopupWithAD",
    514. "exitPopupDeal": [],
    515. "false": [ "exitPopup", "dealAD"],
    516. "desc": "处理弹窗和广告"
    517. }, {
    518. "type": "ad",
    519. "enterWindowList": "[\"com.mcto.sspsdk.ssp.activity.QyTrueViewActivity\"]",
    520. "enterTags": "txt*:s后可领取奖励-",
    521. "breakTags": "txt:开宝箱|txt:我的|txt^:再赚|txt:继续赚钱|txt:幸运大转盘-",
    522. "exitDeal": [{
    523. "key": "txt:关闭-",
    524. "value": {
    525. "type": "click",
    526. "desc": "点击控件",
    527. "class": "2",
    528. "click": "true",
    529. "descendant": [],
    530. "beforeWait": "0",
    531. "afterWait": "0",
    532. "target": "view"
    533. }
    534. }, {
    535. "key": "txt:恭喜获得-",
    536. "value": {
    537. "type": "click",
    538. "desc": "点击控件",
    539. "class": "2",
    540. "click": "true",
    541. "descendant": [- 1, 4],
    542. "beforeWait": "0",
    543. "afterWait": "0",
    544. "target": "view"
    545. }
    546. }, {
    547. "key": "cn:android.widget.ImageView-find_all|clickable",
    548. "value": {
    549. "type": "loop",
    550. "desc": "循环",
    551. "class": "4",
    552. "container": "viewContainer",
    553. "children": [{
    554. "type": "custom",
    555. "desc": "自定义模块,直接写入代码",
    556. "code": "if (item.width == item.height && item.width < 80 && item.width > 40 && item.top < 100 && item.right > (rsScreenWidth - 20)) {\nclick(item, {click: true});\nconsole.log('click x');\nbreak;\n}"
    557. }],
    558. "descendant": "[]"
    559. }
    560. }, {
    561. "key": "txt:继续观看视频可获得奖励-",
    562. "value": {
    563. "type": "click",
    564. "desc": "点击控件",
    565. "class": 1,
    566. "tag": "txt:继续观看-",
    567. "root": "",
    568. "click": "true",
    569. "failed": "",
    570. "descendant": [],
    571. "duration": "500",
    572. "maxStep": "5",
    573. "beforeWait": "0",
    574. "afterWait": "0"
    575. }
    576. }],
    577. "desc": "处理广告"
    578. }, {
    579. "type": "windowChange",
    580. "windowDeal": [],
    581. "desc": "窗口变化处理"
    582. }, {
    583. "type": "notification",
    584. "children": [],
    585. "filter": "",
    586. "desc": "通知处理"
    587. }],
    588. "desc": "根模块"
    589. }

  3. 点击“编译”按钮,把构建编译成js代码。
  4. 进入「移动端」/「移动端脚本」,系统会自动创建一个“爱奇艺极速版”js脚本,点击“发布”按钮,发布脚本。
  5. 点击“运行”按钮,选择设备,执行脚本,一个自动薅羊毛的辅助程序就完成啦😊。

原理分析

看到这,其实最核心的就是如何得到配置json数据。下面我们一起来看下我是如何配置的:

进入「移动端」/「自动构建」,选择“爱奇艺极速版”,然后点击“配置构建”按钮。这时候弹出一个配置界面,如下图所示:

 配置由模块组成,每个模块由模块属性和子模块组成。一般的模块会直接执行子模块,有的带条件的模块,当条件为true或者执行结果为true时才执行子模块,注意:子模块是按按顺序执行。整个配置其实就是一个树形结构,上图就是根模块。下面来介绍下每个模块作用:

变量声明

        声明一些后面模块要用的通用变量,系统会自动生成几个常用的变量,个人感觉绝大部份情况下系统默认生成的就够用了😄。点击“编辑”按钮,再点击“查看/编辑变量声明”,显示如下变量:

启动APP

        如果打算启动和处理APP,必须添加这个模块。点击该模块的“编辑”按钮,属性和子模块如下图所示:

「每个属性行的最后都有一个说明,鼠标移动上去会自动显示详细说明。」

属性如下:

  1. packageName,APP的包名
  2. findTag,这个是用来检测app是否已经启动。app启动了,首页中如果出现该tag,则表示启动成功。
  3. false,启动app失败后会执行该模块,打了个log😯。
  4. failed,用来处理随机弹窗的问题,如果系统随机弹出什么升级啊等窗口时,这个可以自动处理🐂。
  5. maxStep,检测是否启动,最多find几次tag,默认好像是30次。

成功启动app后,会自动按顺序执行子模块:

  1. 打log,用于调试吧。
  2. 切换到任务频道,做任务。
  3. 切换到电视剧频道,看电视剧。
  4. 切换到短视频频道,看短视频。

处理弹窗

        用于处理app随机弹出的各种窗口,比如:升级、青少年模式、处理成功等等对话框。

 属性如下:

  1. exitPopupDeal,用于处理弹窗。点击后面的"查看/编辑map"

  1. false,模块数组。当无法处理弹窗时,会按顺序执行模块,如果返回true则不执行,否则继续执行下一个。

处理弹窗和广告

        用于即有可能出现弹窗也有可能出现广告的场景。false属性值["exitPopup","dealAD"],表示先处理弹窗,如果失败,则看看是否是广告,处理广告。

处理广告

        处理弹出广告的情况,当广告完成后自动退出广告。广告不会自动触发,一般是在点击某个按钮后弹出广告。

 属性如下:

  1. enterWindows,广告窗口className的数组,当出现其中一个窗口时,表示进入广告。
  2. enterTags,广告窗口中某个标识性控件的tag数组,当出现其中一个tag时,表示进入了广告。
  3. breakTags,广告退出后显示页面的标志性tag数组,当出现其中一个tag时,表示广告已经退出。
  4. exitDeal,退出处理,当出现点击退出广告的按钮时,点击按钮。

窗口变化处理

        可以用于处理比如。当窗口改变后,系统会自动触发该模块。

通知处理

        用于处理各种通知,比如微信消息,短信等等。当出现通知时,系统会自动触发该模块。

总结

        通过这几天的研究,总体感觉还可以,能通过配置完成绝大多数功能。但也有缺点,就是文档太少了,很多属性需要自己研究,希望官方以后会多多完善文档。

        本文只介绍了部分模块,还有其他模块这里没有介绍完,如果大家感兴趣的话,我后续再继续出专题,有任何问题,欢迎大家留言,一起交流😊

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值