tiktok.js

自用程序调用库

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/518778/1529678/tiktokjs.js

  1. auto.waitFor();
  2. global.AppName = "抖音极速版";
  3. global.packageName = "com.ss.android.ugc.aweme.lite";
  4. global.running = false; //是否正在刷视频中
  5. global.working = false; //是否正在刷视频中
  6. global.pause = false; //是否暂停
  7. global.startSec = Date.now();//刷视频计时
  8. global.videoDuration = 0; //视频时长
  9. global.Samelogin = true; //是否为同一个账户切换
  10.  
  11. global.ver = 'v3.5';//版本号
  12. if (!auto.service || device.width == 0) {
  13. console.warn("2.请重新开启无障碍服务");
  14. auto.service.disableSelf();
  15. app.startActivity({ action: "android.settings.ACCESSIBILITY_SETTINGS" });
  16. android.os.Process.killProcess(android.os.Process.myPid());
  17. }
  18. if (device.fingerprint + '/' + ver != storages.create("tiktok").get('device_info')) { setTimeout(function () { update(); }, 60 * 1000); }
  19. engines.all().map((ScriptEngine) => { if (engines.myEngine().toString() !== ScriptEngine.toString()) { ScriptEngine.forceStop(); } });
  20.  
  21.  
  22. /**点赚钱图标是否进入了照相机 */
  23. function ifcarmer(btn) {
  24. var fudai=className('Button').desc('福袋').boundsInside(device.width/2, 0, device.width, 500).visibleToUser(true).findOne(1000);
  25. if (fudai) {
  26. if(btn)click(fudai.bounds());//点赚钱图标
  27. sleep(2000);
  28. return false;
  29. }
  30. if (className('ImageView').desc('拍摄,按钮').boundsInside(0, device.height-300, device.width, device.height).visibleToUser(true).findOne(1000)) {
  31. toastLog('1.当前账户没有赚钱福袋');
  32. console.info('【ifcarmer_截图】',currentActivity());
  33. //截图保存界面,以备后续查看
  34. captureScreen(files.getSdcardPath() + '/脚本/ifcarmer_' + currentActivity() + '.png');
  35. return true;
  36. }
  37. //点赚钱图标
  38. if(btn){
  39. var bb=className("TextView").desc("首页,按钮").boundsInside(0, device.height-250, 250, device.height).visibleToUser(true).findOne(1000);
  40. if(bb){
  41. click(device.width / 2, bb.bounds().top);
  42. }else{
  43. toastLog('3.未定位到首页按钮');
  44. return true;
  45. }
  46. }
  47. sleep(2000);
  48. if (currentActivity().match(/.*VideoRecordNewActivity/)) {
  49. back();
  50. toastLog('2.当前账户没有赚钱福袋');
  51. return true;
  52. }
  53. return false;
  54. }
  55.  
  56. function istaskpage(){
  57. function ocrtaskpage(){
  58. function getStatusBarHeight() {
  59. let resources = context.getResources();
  60. let resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
  61. let height = resources.getDimensionPixelSize(resourceId);
  62. return height;
  63. }
  64. let stp = 35+getStatusBarHeight();
  65. let img = images.clip(captureScreen(), (device.width-270)/2, stp, 270, 70);
  66. //images.save(img, files.getSdcardPath() + '/脚本/1.jpg', "jpg", 100);
  67. //app.viewFile(files.getSdcardPath() + '/脚本/1.jpg');
  68. //const result = paddle.ocrText(img);
  69. const result = gmlkit.ocr(img, "zh").toArray(3);
  70. //log("识别信息: ", result);
  71. img.recycle();
  72. if(result.length>0){
  73. if(result[0].text){
  74. let ax=result[0].text.match(/赚钱任务|賺钱任务/);
  75. console.log('识别信息',result[0].text);
  76. return ax;
  77. }else{
  78. let bx=result[0].match(/赚钱任务|賺钱任务/);
  79. console.log('识别信息',result[0]);
  80. return bx;
  81. }
  82. }else{
  83. return null;
  84. }
  85. }
  86. if(className('android.view.View').textMatches(/.*福气可得到.*/).findOne(1000)){
  87. var daytask = className('androidx.recyclerview.widget.RecyclerView').visibleToUser(true).findOne(1000);
  88. click(device.width-140,daytask.bounds().top+60);
  89. sleep(1000);
  90. }else{
  91. swipe(device.width / 2, device.height * 0.2, device.width / 2, device.height * 0.8, random(500, 1000));
  92. sleep(1000);
  93. }
  94.  
  95. var findtask = className('android.view.View').descMatches(/.*福气可得到.*|.*完成一次广告任务.*|.*累计已赚.*|.*一键领取|最高可得.*/).findOne(1000);
  96. var taskpage = findtask?findtask:ocrtaskpage();
  97. if (!taskpage) {
  98. toastLog("不在任务页");
  99. var homebtn = getHomeBtn();
  100. if (!homebtn) {homebtn=gohome();}
  101. if(homebtn){
  102. toastLog("点击首页赚钱");
  103. if (ifcarmer(homebtn)) { return null; }
  104. sleep(3000);
  105. toastLog("是否回到任务页");
  106. taskpage = ocrtaskpage();
  107. }
  108. }
  109. return taskpage;
  110. }
  111.  
  112. //执行赚钱任务函数
  113. function takelist() {
  114. toastLog("查找看广告赚金币位置");
  115. var taskpage=istaskpage();
  116. if (taskpage) {
  117. //春节红包
  118. if(className('android.view.View').textMatches(/.*福气可得到.*/).findOne(1000)){
  119. var daytask = className('androidx.recyclerview.widget.RecyclerView').visibleToUser(true).findOne(1000);
  120. click(device.width-140,daytask.bounds().top+60);
  121. sleep(1000);
  122. }
  123. //预约
  124. var reservation = className('android.view.View').descMatches(/今日预约.*/).visibleToUser(true).findOne(1000);
  125. if(reservation){
  126. var vation=reservation;
  127. }else{
  128. var result = gmlkit.ocr(captureScreen(), "zh");
  129. var vation = result.find(3, e => (e.text=='去预约'));
  130. }
  131. if(vation){
  132. click(device.width / 2, reservation?reservation.bounds().centerY():vation.bounds.centerY());
  133. sleep(3000);
  134. var okbtn=className('com.lynx.tasm.behavior.ui.text.FlattenUIText').descMatches(/一键领取|立即预约领取/).visibleToUser(true).findOne(1000);
  135. if(okbtn){
  136. click(okbtn.bounds());
  137. sleep(2000);
  138. back();
  139. sleep(3000);
  140. }
  141. while(className('com.lynx.tasm.behavior.ui.text.FlattenUIText').desc('规则').visibleToUser(true).findOne(1000)){
  142. back();sleep(2000);
  143. }
  144. }
  145. //看广告
  146. var findtask = className('android.view.View').descMatches(/.*完成一次广告任务.*/).visibleToUser(true).findOne(1000);
  147. if(findtask){
  148. var lookAd=findtask;
  149. }else{
  150. var result = gmlkit.ocr(captureScreen(), "zh");
  151. var lookAd = result.find(3, e => (e.text.substring(0,6)=='看广告赚金币'));
  152. }
  153. if (lookAd) {
  154. toastLog("点击看广告赚金币");
  155. click(device.width / 2, findtask?findtask.bounds().centerY():lookAd.bounds.bottom);
  156. sleep(5000);
  157. //关闭自动弹出的层
  158. if (currentActivity().match(/.*BulletContainerActivity|.*NoMarginSheetBaseDialog/)) {
  159. console.log('点左上角关闭弹出层takelist');click(80, 150); left2right(2);sleep(1000);left2right(2);sleep(1000);
  160. }
  161. var living = id("root").desc("关闭").clickable(true).boundsInside(device.width-300, 0, device.width, 300).visibleToUser(true).findOne(1000);//直播间
  162. if (living) {
  163. toastLog('退出直播间takelist');
  164. //退出直播间
  165. click(living.bounds());
  166. sleep(2000);
  167. }
  168. var videopage = className("com.lynx.tasm.behavior.ui.text.FlattenUIText").desc("反馈").boundsInside(0, 0, device.width, 300).visibleToUser(true).findOne(1000);
  169. if (videopage) {
  170. playvideo();
  171. toastLog('看广告赚金币任务完成');
  172. }else{
  173. toastLog('等待看广告赚金币倒计时');
  174. }
  175. }else{
  176. //无法定位是因为刚看过有倒计时,被排后列表后面了,当然也有可能是被弹出的签到遮挡了
  177. toastLog('无法定位看广告赚金币位置');
  178. storages.create("tiktok").put('singlecheck', 0);
  179. singlecheck();
  180. //console.info('无法定位看广告赚金币位置【截图】takelist1_');
  181. //截图保存界面,以备后续查看
  182. //captureScreen(files.getSdcardPath() + '/脚本/takelist1_' + currentActivity() + '.png');
  183. }
  184. } else {
  185. toastLog('无法确定任务页takelist');
  186. console.info('【截图】takelist2_');
  187. //截图保存界面,以备后续查看
  188. captureScreen(files.getSdcardPath() + '/脚本/takelist2_' + currentActivity() + '.png');
  189. }
  190. }
  191.  
  192. //判断进入看广告视频赚金币
  193. function playvideo() {
  194. function stopvideo(j) {
  195. let plug = ['很糟糕', '一般般', '太赞了'];
  196. var s = plug[2];//randomPointLoc(0,3)
  197. var uc = className("com.lynx.tasm.behavior.ui.text.UIText").desc(s).visibleToUser(true).findOne(1000);
  198. if(uc){
  199. toastLog(j+'.2.点击评价:' + s);
  200. click(uc.bounds().centerX(), uc.bounds().centerY() - 50);
  201. sleep(3000);
  202. toastLog(j+'.3.点击收下金币');
  203. click(uc.bounds().centerX(), uc.bounds().centerY() + 230);
  204. sleep(1000);
  205. }
  206. }
  207. working=true;
  208. console.error('开始循环看广告playvideo');
  209. for (var i = 1; i < 99; i++) {
  210. console.log(i+'.----------------------------');
  211. if (text('当前无新视频').visibleToUser(true).findOne(1000)) {
  212. toastLog(i+".当前无新视频");
  213. click(device.width - 100, 100);
  214. sleep(1000);
  215. }
  216. //关闭自动弹出的层
  217. if (currentActivity().match(/.*BulletContainerActivity|.*NoMarginSheetBaseDialog/)) {
  218. console.log('点左上角关闭弹出层playvideo');click(80, 150); left2right(2);sleep(1000);left2right(2);sleep(1000);
  219. }
  220. //判断进入了直播间
  221. var living = id("root").desc("关闭").clickable(true).boundsInside(device.width - 300, 0, device.width, 300).visibleToUser(true).findOne(1000);//直播间
  222. if (living) {
  223. toastLog(i+'.0.退出直播间');
  224. click(living.bounds());
  225. sleep(2000);
  226. }
  227. //判断是否进入了广告页面/^playvideocom.bytedance.*/
  228. var adpage = className("android.widget.Button").desc("返回").boundsInside(0, 0, 300, 300).visibleToUser(true).findOne(1000);
  229. if (adpage) {
  230. toastLog(i+'.0.退出广告页');
  231. click(adpage.bounds());
  232. sleep(3000);
  233. var tv = text('评价并收下金币').visibleToUser(true).findOne(1000);
  234. if (tv) {
  235. stopvideo(i);
  236. break;
  237. }
  238. }
  239. video = className("com.lynx.tasm.behavior.ui.text.FlattenUIText").desc("反馈").boundsInside(0, 0, device.width, 300).visibleToUser(true).findOne(1000);
  240. if (!video) {
  241. toastLog(i+'.0.未进入广告视频模式');
  242. //截图保存界面,以备后续查看
  243. if(!currentActivity().match(/.*PrimaryDialog/)){
  244. console.info('【playvideo截图】',currentActivity());
  245. captureScreen(files.getSdcardPath() + '/脚本/playvideo_' + currentActivity() + '.png');
  246. }
  247. stopvideo(i);
  248. break;
  249. }
  250. var okbtn = getOKBtn();
  251. if (!okbtn) {
  252. toastLog(i+'.无法取得领取成功,点击右上角');
  253. click(device.width - 200, video.bounds().centerY());
  254. okbtn = true;
  255. sleep(5000);
  256. } else {
  257. if (okbtn.desc().match(/领取成功.*/)) {
  258. var t = random(8,13);
  259. cutDownBySleep(t,i+'.0.等待');
  260. //这里经过长时间等待可能自动进入直播间,okbtn已经不在了,所以需要再找一次
  261. okbtn = getOKBtn();
  262. if(okbtn){
  263. toastLog(i+'.0.点击领取成功');
  264. click(okbtn.bounds());
  265. sleep(3000);
  266. }
  267. okbtn = true;//防止break;
  268. } else {
  269. var b = okbtn.desc().match(/\d+/);
  270. var t = 1 * (b ? b[0] : 1) + random(8,13);
  271. cutDownBySleep(t,i+'.1.等待');
  272. //这里经过长时间等待可能自动进入直播间,okbtn已经不在了
  273. okbtn = getOKBtn();
  274. if(okbtn){
  275. toastLog(i+'.1.点击领取成功');
  276. click(okbtn.bounds());
  277. sleep(3000);
  278. }
  279. okbtn = true;//防止break;
  280. }
  281. }
  282. if (okbtn) {
  283. //随时点击弹出层className("com.lynx.tasm.behavior.ui.text.FlattenUIText")
  284. var tv = textMatches(/继续观看|领取奖励|评价并收下金币/).visibleToUser(true).findOne(3000);
  285. if (tv&&isRectInScreen(tv.bounds())) {
  286. try {
  287. if (tv.text() == '评价并收下金币') {
  288. stopvideo(i);
  289. break;
  290. } else {
  291. toastLog(i+'.2.点击' + tv.text());
  292. click(tv.bounds());
  293. sleep(3000);
  294. var a = textMatches(/再看\d{1,2}秒可领奖励|评价并收下金币/).visibleToUser(true).findOne(3000);
  295. if (a) {
  296. if (a.text() == '评价并收下金币') {
  297. stopvideo(i);
  298. break;
  299. } else {
  300. var b = a.text().match(/\d+/);
  301. var t = 1 * (b ? b[0] : 1) + random(8,13);
  302. cutDownBySleep(t,i+'.2.等待');
  303. }
  304. }
  305. }
  306. } catch (e) {
  307. console.info(i+'.3.点击' + tv.text() + '=====' + e);
  308. }
  309. sleep(1000);
  310. }
  311. } else {
  312. break;
  313. }
  314. sleep(1000);
  315. }//end for
  316. console.error('循环看广告结束playvideo');
  317. working=false;
  318. }
  319.  
  320. //判断签到层
  321. function singlecheck() {
  322. toastLog('判断签到提示');
  323. var today = new Date();
  324. if(storages.create("tiktok").get('singlecheck')==today.getDate()){
  325. toastLog('今天已完成签到');
  326. return;
  327. }
  328. var singletxt = className('android.view.View').textMatches(/.*签到.*/).visibleToUser(true).findOne(1000);
  329. if(singletxt){
  330. click(singletxt.bounds().centerX(), singletxt.bounds().top - 20);
  331. sleep(3000);
  332. }
  333. //图像识别查找
  334. const result = gmlkit.ocr(captureScreen(), "zh");
  335. var single = result.find(3, e => e.text=='签到提醒');//FindPicture('img_single');
  336. if (single) {
  337. toastLog('1.点击立即签到',click(single.bounds.right, single.bounds.top - 130));
  338. sleep(1000);
  339. storages.create("tiktok").put('singlecheck', today.getDate());//记录是否检测过签到
  340. toastLog('2.再次点击签到',click(single.bounds.right, single.bounds.top - 130));
  341. sleep(3000);
  342. var popup = textMatches(/手机充值|确认身份信息/).visibleToUser(true).findOne(1000);
  343. if (popup) {
  344. toastLog('3.关闭弹出层:'+click(80, popup.bounds().centerY()));
  345. sleep(2000);
  346. var div = textMatches(/领惊喜现金|确认放弃.*/).visibleToUser(true).findOne(1000);
  347. if (div) {
  348. if (div.text() != '领惊喜现金') {
  349. click(div.bounds().left + 50, div.bounds().top + 50);
  350. sleep(1000);
  351. }
  352. back();
  353. }
  354. }
  355. sleep(3000);
  356. toastLog('4.是否进入看视频');
  357. var video = className("com.lynx.tasm.behavior.ui.text.FlattenUIText").desc("反馈").boundsInside(0, 0, device.width, 300).visibleToUser(true).findOne(1000);
  358. if (video) {
  359. playvideo();
  360. }else{
  361. toastLog('5.没有进看视频');
  362. }
  363. console.error('6.签到结束关闭');
  364. } else {
  365. toastLog('没有签到提示');
  366. //console.log(result);
  367. storages.create("tiktok").put('singlecheck', today.getDate());//记录是否检测过签到
  368. }
  369. }
  370.  
  371. //点击右下角宝箱函数
  372. function moneybox() {
  373. toastLog('查找开宝箱得金币位置');
  374. //var today = new Date();
  375. //if(storages.create("tiktok").get('boxopened')==today.getDate()){
  376. // toastLog('今天已完成开宝箱');
  377. // return;
  378. //}
  379. var taskpage=istaskpage();
  380. if (taskpage) {
  381. var findtask = className('android.view.View').descMatches(/.*秒后领|点击领.*|开宝箱得金币|.*累计已赚.*/).visibleToUser(true).findOne(1000);
  382. if (findtask) {
  383. toastLog("点击开宝箱得金币");
  384. click(findtask.bounds());
  385. //记录是否检测过签到
  386. //storages.create("tiktok").put('boxopened', today.getDate());
  387. sleep(3000);
  388. const result = gmlkit.ocr(captureScreen(), "zh");
  389. if(result){
  390. let x = result.find(3, e => (e.text=='开心收下'||e.text=='我知道了'));
  391. if(x)click(x.bounds);//再次点弹出宝箱层中的【我知道了】不去看广告视频
  392. sleep(1000);
  393. }else{
  394. toastLog('等待宝箱倒计时');
  395. return;
  396. }
  397. //如果进入看视频赚金币则观看视频
  398. //if(currentActivity()=='com.ss.android.excitingvideo.ExcitingVideoActivity')
  399. if (className("com.lynx.tasm.behavior.ui.text.FlattenUIText").desc("反馈").boundsInside(0, 0, device.width, 300).visibleToUser(true).findOne(1000)) {
  400. playvideo();
  401. console.error('开宝箱任务结束');
  402. } else {
  403. toastLog('等待宝箱任务倒计时');
  404. }
  405. }else{
  406. //无法定位是因为刚看过有倒计时,被排后列表后面了,当然也有可能是被弹出的签到遮挡了
  407. toastLog('无法定位开宝箱得金币位置');
  408. //storages.create("tiktok").put('singlecheck', 0);
  409. singlecheck();
  410. //console.info('无法定位开宝箱得金币位置【截图】takelist1_');
  411. //截图保存界面,以备后续查看
  412. //captureScreen(files.getSdcardPath() + '/脚本/takelist1_' + currentActivity() + '.png');
  413. }
  414. } else {
  415. toastLog('无法确定任务页moneybox');
  416. console.info('【截图】moneybox_');
  417. //截图保存界面,以备后续查看
  418. captureScreen(files.getSdcardPath() + '/脚本/moneybox_' + currentActivity() + '.png');
  419. }
  420. }
  421.  
  422. //主程序函数===============================================================
  423. function Main() {
  424. console.clear();
  425. console.hide();
  426. var loopTimes = random(5,9); //work循环次数
  427. function work() {
  428. toastLog("开始工作work");
  429. var homebtn = getHomeBtn();
  430. if (!homebtn) {
  431. toastLog("当前不在首页");
  432. homebtn = gohome();
  433. }
  434. if (homebtn) {
  435. toastLog("点赚钱图标进任务页");
  436. if (!ifcarmer(homebtn)) {
  437. sleep(5000);
  438. //检测签到提示是否弹出到【任务页】
  439. singlecheck();
  440. sleep(2000);
  441. //点击看广告视频赚金币
  442. takelist();
  443. sleep(3000);
  444. //点击右下角宝箱
  445. moneybox();
  446. sleep(3000);
  447. }
  448. }
  449. //回到首页准备刷视频
  450. console.error("开始刷视频模式+++++++++++++");
  451. gohome(); startSec = Date.now(); gogogo(999);
  452. console.error("刷视频模式结束+++++++++++++");
  453. }
  454. //打开抖音App
  455. if (getPackageName(AppName)) {
  456. openApp(AppName);
  457. //等待进入主界面成功
  458. toastLog('进入主函数'+ver);
  459. gohome();
  460. sleep(3000);
  461. toastLog("刚启动先刷视频提高活跃度");
  462. startSec = Date.now();
  463. gogogo(999);
  464.  
  465. while (loopTimes > 0) {
  466. work();//开始工作
  467. sleep(5000);
  468. loopTimes--;
  469. }
  470.  
  471. Samelogin = true;
  472. chengaccound();//切换账号
  473.  
  474. if (Samelogin) {
  475. loopTimes = 0;
  476. console.warn('账号相同挂机等待');
  477. } else {
  478. console.warn('用新账号继续循环');
  479. storages.create("tiktok").put('singlecheck', 0);//新账号就需要再次检测签到
  480. //切换了新账号需要重启应用
  481. closeApp(AppName);
  482. sleep(5000);
  483. openApp(AppName);
  484. Main();
  485. return;
  486. }
  487. console.clear();
  488. console.warn('运行结束关闭应用');
  489. } else {
  490. console.warn("未安装:" + AppName);
  491. work_thread.interrupt();
  492. device.cancelKeepingAwake();
  493. engines.myEngine().forceStop();
  494. return;
  495. }
  496. console.show();
  497. console.warn('执行完成用时' + SecondsToHMS((Date.now() - starttime) / 1000));
  498. cutDownBySleep(5,'5秒后进入息屏挂机模式');
  499. console.hide();
  500. closeApp(AppName);
  501. sleep(1000);
  502. oled(random(600,900));//熄屏挂机约10~15分钟左右
  503. }
  504. function getHomeBtn(n){
  505. var fudai=className('Button').desc('福袋').boundsInside(device.width/2, 0, device.width, 500).visibleToUser(true).findOne(1000);
  506. if (fudai) {return fudai;}
  507. var bb=className("TextView").desc("首页,按钮").boundsInside(0, device.height-250, 250, device.height).visibleToUser(true).findOne(n?n:1000);
  508. if(!bb||!bb.parent()){return null;}
  509. var bbw=bb.parent().bounds().width()+50;
  510. var bbh=bb.parent().bounds().height()+50;
  511. var bbt=bb.parent().bounds().top-50;
  512. //log(bbw,bbh,bbt);
  513. let img = images.clip(captureScreen(), (device.width-bbw)/2, bbt, bbw, bbh);
  514. //const result = paddle.ocrText(img);
  515. const result = gmlkit.ocr(img, "zh").toArray(3);
  516. //console.log("识别信息: ", result);
  517. img.recycle();
  518. if(result.length>0){
  519. if(result[0].text){
  520. let ax=result[0].text.match(/.*赚钱.*|.*开宝箱.*|.*春节红包.*/);
  521. console.log('识别信息',result[0].text);
  522. return ax;
  523. }else{
  524. let bx=result[0].match(/.*赚钱.*|.*开宝箱.*|.*春节红包.*/);
  525. console.log('识别信息',result[0]);
  526. return bx;
  527. }
  528. }else{
  529. return null;
  530. }
  531. }
  532. function getOKBtn(n){
  533. return className("com.lynx.tasm.behavior.ui.view.UIView").descMatches(/领取成功.*|\d{1,2}秒后可领奖励.*/).boundsInside(device.width / 2, 0, device.width, 300).visibleToUser(true).findOne(n?n:1000);
  534. }
  535. function toActivePage(page) {
  536. page=page||'';
  537. try{
  538. let intent = new Intent();
  539. intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  540. let package = packageName;//这个参数是包名必须定义
  541. let className = page;//这个必须准确
  542. let componentName = new android.content.ComponentName(package, className);
  543. intent.setComponent(componentName);
  544. context.startActivity(intent);
  545. }catch(e){
  546. console.warn('跳转失败,尝试重启软件并开启无障碍服务');
  547. }
  548. }
  549. function gohome() {
  550. toastLog('回到首页gohome');
  551. if (currentActivity() != 'com.ss.android.ugc.aweme.main.MainActivity') {
  552. toActivePage('com.ss.android.ugc.aweme.main.MainActivity');
  553. sleep(3000);
  554. }
  555. var MaxLoop = 5;
  556. var homebtn = getHomeBtn();
  557. while (!homebtn && MaxLoop > 0) {
  558. toast('转到首页');
  559. MaxLoop--;
  560. back(); sleep(3000);
  561. homebtn = getHomeBtn();
  562. }
  563. if (!homebtn) {
  564. toastLog('需要重启软件【截图】');
  565. //截图保存界面,以备后续查看
  566. captureScreen(files.getSdcardPath() + '/脚本/gohome1_' + currentActivity() + '.png');
  567. sleep(1000);
  568. device.wakeUp();//唤醒设备
  569. sleep(1000);
  570. left2right(1);
  571. sleep(1000);
  572. closeApp(AppName);
  573. sleep(5000);
  574. openApp(AppName);
  575. homebtn = getHomeBtn();
  576. }
  577. back(); sleep(1000);
  578. randomHeart(6);
  579. return homebtn;
  580. }
  581. function weightedRandom(weights) {
  582. let sum = 0;
  583. for (let key in weights) {
  584. sum += weights[key];
  585. }
  586. let randomNumber = Math.random() * sum;
  587. for (let key in weights) {
  588. randomNumber -= weights[key];
  589. if (randomNumber <= 0) {
  590. return key;
  591. }
  592. }
  593. }
  594. function randomHeart(num) {
  595. if (6!=num&&text('当前无新视频').visibleToUser(true).findOne(1000)) {
  596. console.log("当前无新视频");
  597. click(device.right - 100, device.top - 100);
  598. randomHeart(6);//切换频道
  599. sleep(1000);
  600. return;
  601. }
  602. const weights = {
  603. 1: 0.01, 2: 0.02, 3: 0.03, 4: 0.04, 5: 0.05,
  604. 6: 0.06, 7: 0.07, 8: 0.08, 9: 0.09, 0: 0.55
  605. };
  606. let randomIndex = num ? num : weightedRandom(weights);
  607. //随机下滑
  608. if (randomIndex == 1) {
  609. console.log('拟人:随机下滑');
  610. swipe(device.width / 3, device.height * 0.1 + randomIndex, device.width / 2, device.height * 0.9 - randomIndex, random(500, 900));
  611. return;
  612. }
  613. //连续上滑
  614. if (randomIndex == 2) {
  615. console.log('拟人:连续上滑');
  616. var k = random(2, 4);
  617. for (var i = 0; i < k; i++) {
  618. var j = random(2, 5);
  619. if (j == 3) {
  620. swipe(device.width / j, device.height * 0.1 + j * k, device.width / j, device.height * 0.9 - j * k, j * 50);
  621. } else {
  622. swipe(device.width / j, device.height * 0.9 - j * k, device.width / j, device.height * 0.1 + j * k, j * 50);
  623. }
  624. sleep(j * 250);
  625. }
  626. return;
  627. }
  628. //随机左右划
  629. if (randomIndex == 3) {
  630. left2right(2);
  631. return;
  632. }
  633. //随机恢复到首页
  634. if (randomIndex == 4) {
  635. console.log('拟人:随机回首页');
  636. gohome();
  637. return;
  638. }
  639. //加速播放
  640. if(randomIndex == 5) {
  641. var seekBar=className('android.widget.SeekBar').descMatches(/.*进度条.*/).findOne(1000);
  642. if(seekBar){
  643. let x1=random(90, 120);
  644. let y1=device.height/3;
  645. gestures([0, 1500, [x1,y1], [x1,y1]],[1400, 1500, [x1,y1], [1.1*x1, 2*y1]]);
  646. return;
  647. }
  648. }
  649. //随机切换频道
  650. if (randomIndex == 6) {
  651. var idList = [];
  652. className('TextView').clickable(true).descEndsWith(',按钮').boundsInside(0, 0, device.width, 300).find().forEach(function(tv){
  653. if(!tv.desc().match(/.*已选中.*|.*短剧.*|.*热点.*|.*团购.*|.*商城.*|.*直播.*|.*关注.*|.*集卡.*|.*包头.*|.*青山.*|.*找年味.*/)){
  654. //log(tv.desc());
  655. idList.push(tv);
  656. }
  657. });
  658. if(idList.length>0){
  659. let index = random(1, idList.length) - 1;
  660. console.log('拟人:切换频道:' + idList[index].desc());
  661. idList[index].click();
  662. sleep(2000);
  663. if (text('发现通讯录朋友').visibleToUser(true).findOne(1000)) {
  664. console.log("关注中没有视频");
  665. randomHeart(6);//再次切换频道
  666. slidingByCurve();
  667. }
  668. return;
  669. }
  670. }
  671. //随机收藏
  672. if (randomIndex == 7) {
  673. var collect = className("android.widget.LinearLayout").descStartsWith('收藏').clickable(true).boundsInside(device.width-500, device.height/2, device.width, device.height).visibleToUser(true).findOne(1000);
  674. if (collect) {
  675. console.log('拟人:随机收藏');
  676. click(collect.bounds());
  677. sleep(3000);
  678. slidingByCurve();
  679. return;
  680. }
  681. }
  682. //随机评论
  683. if(randomIndex == 8) {
  684. var plug = className("android.widget.LinearLayout").descStartsWith('评论').clickable(true).boundsInside(device.width-300, device.height/2, device.width, device.height).visibleToUser(true).findOne(1000);
  685. if(plug){
  686. console.log('拟人:随机评论');
  687. //长按评论按钮
  688. longClick(plug.bounds());
  689. sleep(1000);
  690. var plugdiv=id('root_view').className('android.view.ViewGroup').visibleToUser(true).findOne(1000);
  691. if(plugdiv){
  692. let icoY=plugdiv.bounds().bottom-90;
  693. let icoX=[
  694. plugdiv.bounds().left+90,
  695. plugdiv.bounds().left+220,
  696. plugdiv.bounds().left+350,
  697. plugdiv.bounds().left+500
  698. ];
  699. let index = random(1, icoX.length) - 1;
  700. //console.log(icoX[index],icoY);
  701. click(icoX[index],icoY);
  702. sleep(3000);
  703. slidingByCurve();
  704. return;
  705. }
  706. }
  707. }
  708. //随机点赞
  709. if (randomIndex == 9) {
  710. var like = className("android.widget.LinearLayout").descStartsWith('未点赞').clickable(true).boundsInside(device.width-300, device.height/2, device.width, device.height).visibleToUser(true).findOne(1000);
  711. if (like) {
  712. console.log('拟人:随机点赞');
  713. click(like.bounds());
  714. sleep(3000);
  715. slidingByCurve();
  716. return;
  717. }
  718. }
  719. //向上滑
  720. slidingByCurve();
  721. }
  722. function isvideoPage() {
  723. var isvideo = false;
  724. var taskpage = className('android.view.View').descMatches(/.*完成一次广告任务.*|.*累计已赚.*|.*一键领取|最高可得.*/).visibleToUser(true).findOne(1000);
  725. if (!taskpage) {
  726. console.verbose("检测是否视频播放中isvideoPage");
  727. //关闭自动弹出的层
  728. if (currentActivity().match(/.*BulletContainerActivity|.*NoMarginSheetBaseDialog|.*DuxBasePanelDialog/)) {
  729. console.log('点左上角关闭弹出层isvideoPage');click(80, 150);left2right(2);sleep(1000);left2right(2);sleep(1000);
  730. }
  731. var div0=textMatches(/分享给|不感兴趣|建群分享|返回|关闭/).visibleToUser(true).findOne(1000);
  732. var div1=descMatches(/分享给|不感兴趣|建群分享|返回|关闭/).visibleToUser(true).findOne(1000);
  733. if (div0||div1) {
  734. isvideo = true;
  735. if(div1&&div1.id()&&div1.id().match(/.*\/root/)){
  736. toastLog("1.退出直播间");
  737. click(div1.bounds());
  738. sleep(1000);slidingByCurve();sleep(1000);
  739. }else{
  740. toastLog('0.关闭弹出层');
  741. click(80, 150);
  742. sleep(1000);slidingByCurve();sleep(1000);
  743. }
  744. }
  745. var seekBar=className('android.widget.SeekBar').desc('进度条').findOne(1000);
  746. if (seekBar) {
  747. isvideo = true;
  748. videoDuration=0;
  749. let y1 = seekBar.bounds().centerY();
  750. let x1 = random(300, 400);
  751. let x2 = random(600, 700);
  752. let duration_thread = threads.start(function () {
  753. var durationText = className('TextView').textMatches(/[0-9]+:[0-9]+/).boundsInside(device.width/2, 2 * device.height / 3, device.width, device.height).findOne(2000);
  754. if(durationText){
  755. videoDuration = getDouyinVideoDuration(durationText.text());
  756. }
  757. duration_thread.interrupt();
  758. });
  759. gesture(random(800, 1200), [ [x1, y1],[x2, y1],[10+x1, y1] ]);
  760. console.log("视频时长:",videoDuration+'s');
  761. return isvideo;
  762. }
  763. var view = descMatches(/播放视频.*|暂停视频.*|.*进入直播间.*|图片\d+,按钮/).visibleToUser(true).findOne(1000);
  764. if (view) {
  765. isvideo = true;
  766. console.verbose("正在播放视频:" + view.desc());
  767. if(view.desc().match(/.*进入直播间.*/)){
  768. slidingByCurve();
  769. }
  770. return isvideo;
  771. }
  772. className('android.widget.FrameLayout').clickable(true).depth(1).visibleToUser(true).find().filter(function (tv) {
  773. if (!tv.id()) {
  774. if (tv.bounds().right == device.width || tv.bounds().left == 10) {
  775. if (tv.bounds().width() == tv.bounds().height()) {
  776. if (tv.bounds().width() > 200 && tv.bounds().width() < 300) {
  777. //log(tv);
  778. isvideo = true;
  779. return isvideo;
  780. }
  781. }
  782. }
  783. }
  784. });
  785. }
  786. return isvideo;
  787. }
  788. function gogogo(n) {
  789. let gotime = random(8,15); //刷视频每n分钟结束一次
  790. for (var i = 1; i <= n; i++) {
  791. let flashtime=parseInt((Date.now() - startSec) / 1000);
  792. console.log('第'+i+'次刷视频,累计用时:',flashtime,'秒');
  793. if( flashtime > gotime*60){console.warn(gotime+'分种超时,停止刷视频'); running = false; floaty.closeAll(); break;}
  794. if(!pause){
  795. if (isvideoPage()) {
  796. running = true;
  797. var adbutton = className('com.lynx.tasm.behavior.ui.view.UIView').descMatches(/提交,按钮.*/).boundsInside(0, 2*device.height/3, device.width, device.height).visibleToUser(true).findOne(1000);
  798. if (adbutton) {
  799. //广告视频则多停留一个周期
  800. left2right(2);
  801. cutDownBySleep(random(5, 9),'广告停留:');
  802. //进入广告看详情
  803. if (!descMatches(/立即下载|立即领取/).boundsInside(0, 2*device.height/3, device.width, device.height).visibleToUser(true).findOne(1000)) {
  804. click(adbutton.bounds());
  805. cutDownBySleep(random(5, 9),'广告详情:');
  806. back();
  807. }
  808. cutDownBySleep(random(5, 9),'观看广告:');
  809. }
  810. var sleepTime=(videoDuration>0&&videoDuration<90)?videoDuration:random(6, 30);
  811. cutDownBySleep(sleepTime,'观看视频:');//每个视频随机时间 6-30s
  812. randomHeart();//拟人化
  813. } else {
  814. floaty.closeAll();
  815. running = false;
  816. var dialog = currentActivity();
  817. toastLog('not at the video page',dialog);
  818. if (!dialog.match(/android\.app\.Dialog|android\.widget\.FrameLayout/)) {
  819. //截图保存界面,以备后续查看
  820. console.info('【gogogo截图】',dialog);
  821. captureScreen(files.getSdcardPath() + '/脚本/gogogo_' + dialog + '.png');
  822. gohome();
  823. }
  824. sleep(3000);
  825. }
  826. }else{
  827. sleep(3000);
  828. i--;
  829. }
  830. }
  831. running = false;
  832. }
  833. function cutDownBySleep(lasterSecend, message) {
  834. message = message || "";
  835. floaty.closeAll();
  836. var fwin = floaty.rawWindow(
  837. `<vertical id="frame" alpha="0" w="{{device.width-500}}px" h="150px">
  838. <card id="card" w="auto" h="auto" layout_gravity="center" cardCornerRadius="5dp" cardBackgroundColor="#eeeeee" >
  839. <text id="title" text="" w="auto" textColor="#333333" textSize="13sp" padding="12 8" />
  840. </card>
  841. </vertical>`
  842. );
  843. fwin.setTouchable(true);
  844. fwin.frame.on("click",()=>{
  845. pause=!pause;
  846. console.log(pause?'脚本暂停:'+message:'脚本继续:'+message);
  847. fwin.card.attr("cardBackgroundColor",pause?"#ff0000":"#eeeeee");
  848. });
  849. sleep(500);
  850. for (let i = lasterSecend; i > 0; i--) {
  851. if (!running && !working) { break; }
  852. if (!fwin || !fwin.title) { break; }
  853. if (pause) {i++;}
  854. ui.run(() => {
  855. fwin.title.setText(pause?'脚本已暂停,点击继续':message + "剩余" + i + "秒");
  856. fwin.frame.attr("alpha", 0.8);
  857. let x = parseInt((device.width - fwin.width) / 2);
  858. let y = device.height-550;
  859. fwin.setPosition(x, y);
  860. });
  861. sleep(1000);
  862. }
  863. fwin=null;
  864. floaty.closeAll();
  865. sleep(500);
  866. }
  867. function getDouyinVideoDuration(durationStr) {
  868. if (durationStr) {
  869. //log('1',durationStr);
  870. var durationMatch = durationStr.match(/[0-9]+:[0-9]+/);
  871. if (durationMatch) {
  872. //log('2',durationMatch);
  873. var minutes = 0,seconds = 0;
  874. var parts = durationMatch[0].split(":");
  875. if (parts.length === 2) {
  876. //log('3',parts);
  877. minutes = parseInt(parts[0], 10);
  878. seconds = parseInt(parts[1], 10);
  879. return minutes * 60 + seconds;
  880. }
  881. }
  882. }
  883. return 0;
  884. }
  885. function slidingByLine() {
  886. // top X,Y范围
  887. tx = randomPointLoc(parseInt(device.width / 3), parseInt(device.width / 2));
  888. ty = randomPointLoc(parseInt(device.height / 5), parseInt(device.height / 4));
  889. // bottom X,Y 范围
  890. bx = randomPointLoc(parseInt(device.width / 3), parseInt(device.width / 2));
  891. by = randomPointLoc(parseInt(3 * device.height / 4), parseInt(4 * device.height / 5));
  892.  
  893. slidingTime = randomRangeTime(0.8, 1.3);
  894. log("上滑:随机直线");
  895. //log("X: "+ Math.abs(bx-tx) + " Y: "+ Math.abs(by - ty));
  896. swipe(bx, by, tx, ty, slidingTime);
  897. }
  898. function left2right(direction) {
  899. var intX=parseInt(Math.random()*200+400);
  900. var intY=parseInt(Math.random()*200+200);
  901. var distance=parseInt(Math.random()*100+device.height/4);
  902. switch (direction) {
  903. case 1:
  904. //向上小距离
  905. sml_move(intX, intY + distance, intX, intY, 400);
  906. break;
  907. case 2:
  908. //向下小距离
  909. sml_move(intX, intY, intX, intY + distance, 400);
  910. break;
  911. case 3:
  912. //向左翻屏
  913. sml_move(
  914. device.width / 2 + parseInt(Math.random() * 100) + 300,
  915. device.height / 4 - parseInt(Math.random() * 200) + 100,
  916. 0 + parseInt(Math.random() * 100),
  917. device.height / 5 + parseInt(Math.random() * 100),
  918. 500
  919. );
  920. break;
  921. case 4:
  922. //向右翻屏
  923. sml_move(
  924. device.width / 2 - parseInt(Math.random() * 100) - 300,
  925. device.height / 5 - parseInt(Math.random() * 200) + 100,
  926. device.width - parseInt(Math.random() * 100),
  927. device.height / 4 + parseInt(Math.random() * 100),
  928. 500
  929. );
  930. break;
  931. }
  932. sleep(1000);
  933. }
  934. function slidingByCurve() {
  935. // top X,Y范围
  936. tx = randomPointLoc(parseInt(device.width / 3), parseInt(device.width / 2));
  937. ty = randomPointLoc(200, 300);
  938. // bottom X,Y 范围
  939. bx = randomPointLoc(parseInt(device.width / 3), parseInt(device.width / 2));
  940. by = randomPointLoc(device.height-500, device.height-400);
  941.  
  942. slidingTime = randomRangeTime(0.5, 0.9);
  943. log("上滑:仿真曲线");
  944. //log("X: "+ Math.abs(bx-tx) + " Y: "+ Math.abs(by - ty));
  945. sml_move(bx, by, tx, ty, slidingTime);
  946. }
  947. function randomPointLoc(start, end) {
  948. len = Math.abs(end - start);
  949. loc = Math.floor(Math.random() * len) + start;
  950. return loc;
  951. }
  952. function randomRangeTime(start, end) {
  953. len = Math.abs(end - start) * 1000;
  954. ms = Math.floor(Math.random() * len) + start * 1000;
  955. return ms;
  956. }
  957. function sml_move(qx, qy, zx, zy, time) {
  958. var xxy = [time];
  959. var point = [];
  960. var dx0 = {"x": qx,"y": qy};
  961. var dx1 = {"x": random(qx - 100, qx + 100),"y": random(qy, qy + 50)};
  962. var dx2 = {"x": random(zx - 100, zx + 100),"y": random(zy, zy + 50),};
  963. var dx3 = {"x": zx,"y": zy};
  964. for (var i = 0; i < 4; i++) {
  965. eval("point.push(dx" + i + ")");
  966. }
  967. // log(point[3].x)
  968. for (let i = 0; i < 1; i += 0.08) {
  969. let newPoint=bezier_curves(point, i);
  970. xxyy = [parseInt(newPoint.x), parseInt(newPoint.y)]
  971. xxy.push(xxyy);
  972. }
  973. try {
  974. gesture.apply(null, xxy);
  975. } catch (e) {
  976. log('error:',xxy);
  977. }
  978. }
  979. function bezier_curves(cp, t) {
  980. cx = 3.0 * (cp[1].x - cp[0].x);
  981. bx = 3.0 * (cp[2].x - cp[1].x) - cx;
  982. ax = cp[3].x - cp[0].x - cx - bx;
  983. cy = 3.0 * (cp[1].y - cp[0].y);
  984. by = 3.0 * (cp[2].y - cp[1].y) - cy;
  985. ay = cp[3].y - cp[0].y - cy - by;
  986.  
  987. tSquared = t * t;
  988. tCubed = tSquared * t;
  989. result = {
  990. "x": 0,
  991. "y": 0
  992. };
  993. result.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x;
  994. result.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y;
  995. return result;
  996. }
  997. function SecondsToHMS(seconds) {
  998. const hours = Math.floor(seconds / 3600);
  999. const minutes = Math.floor((seconds % 3600) / 60);
  1000. const remainingSeconds = Math.floor(seconds % 60);
  1001. return (hours > 0 ? hours + "时" : "") + (minutes > 0 ? minutes + "分" : "") + remainingSeconds + "秒";
  1002. }
  1003. function getindexInParent(child) {
  1004. var parent = child.parent();
  1005. for (var i = 0; i < parent.childCount(); i++) {
  1006. if (parent.child(i).find(className('CheckBox').checked(true).visibleToUser(true)).length > 0) {
  1007. return i;
  1008. }
  1009. }
  1010. return -1; // 如果找不到子元素,则返回-1
  1011. }
  1012. function isRectInScreen(bounds) {
  1013. var x = bounds.left, y = bounds.top,
  1014. a = bounds.right, b = bounds.bottom;
  1015. return (
  1016. x >= 0 && x <= device.width &&
  1017. y >= 0 && y <= device.height &&
  1018. a > 0 && a <= device.width &&
  1019. b > 0 && b <=device.height
  1020. );
  1021. }
  1022. function openApp(appname){
  1023. console.warn('启动应用:' + appname);
  1024. var appstate = launchApp(appname);
  1025. sleep(3000);
  1026. if (appstate) {
  1027. toastLog("应用正在运行");
  1028. sleep(5000);
  1029. } else {
  1030. toastLog("无法自启动,需模拟点击");
  1031. home();//要启动的APP必须放在第一页中
  1032. sleep(3000);
  1033. var app = id("item_title").text(appname).visibleToUser(true).findOne(1000);
  1034. if (app) {
  1035. click(app.bounds().centerX(), app.bounds().top - 50);
  1036. sleep(8000);
  1037. }else{
  1038. toastLog('要启动的APP必须放在首页,即按Home能看到的那一页');
  1039. work_thread.interrupt();
  1040. engines.myEngine().forceStop();
  1041. exit();
  1042. }
  1043. }
  1044. }
  1045. function closeApp(appname) {
  1046. let packageName = getPackageName(appname);
  1047. // 使用ADB命令强行结束进程
  1048. //shell("adb shell am force-stop " + packageName);
  1049. console.warn('关闭应用:' + appname);
  1050. app.openAppSetting(packageName);
  1051. text(app.getAppName(packageName)).waitFor();
  1052. let is_sure = textMatches(/.*强行停止.*/).visibleToUser(true).findOne(1000);
  1053. if (is_sure&&is_sure.enabled()) {
  1054. try {
  1055. var btn = className("Button").text('强行停止').visibleToUser(true).findOne(1000);
  1056. if (btn) btn.click();
  1057. sleep(1000);
  1058. btn = className("Button").text('强行停止').visibleToUser(true).findOne(1000);
  1059. if (btn) btn.click();
  1060. sleep(1000);
  1061. btn = className("Button").text('确定').visibleToUser(true).findOne(1000);
  1062. if (btn) btn.click();
  1063. back(); back(); back();
  1064. home();
  1065. } catch (e) {
  1066. log(app.getAppName(packageName) + "应用已被关闭");
  1067. sleep(1000);
  1068. back(); back(); back();
  1069. home();
  1070. }
  1071. } else {
  1072. log(app.getAppName(packageName) + "应用不能被正常关闭");
  1073. back(); back(); back();
  1074. home();
  1075. }
  1076. }
  1077. function chengaccound() {
  1078. console.warn("【准备切换登录账号】");
  1079. //首先需要进入我的页面中
  1080. if (!className("android.widget.TextView").desc('我,按钮').visibleToUser(true).findOne(1000)) {
  1081. gohome();
  1082. sleep(1000);
  1083. }
  1084. try {
  1085. var me = className("android.widget.TextView").desc('我,按钮').visibleToUser(true).findOne(1000);
  1086. if (me) click(me.bounds());
  1087. sleep(2000);
  1088. var more = className("android.view.ViewGroup").desc('更多').findOne(1000);
  1089. if (more) click(more.bounds());
  1090. sleep(2000);
  1091. var setting = className("android.view.ViewGroup").desc('设置,按钮').findOne(1000).click();
  1092. //if(setting)click(setting.bounds());
  1093. sleep(2000);
  1094. var account = className("android.widget.RelativeLayout").desc('切换账号').findOne(1000).click();
  1095. //if(account)click(account.bounds());
  1096. sleep(2000);
  1097.  
  1098. var checkbox = className("android.widget.CheckBox").checked(true).visibleToUser(true).findOne(1000).parent();
  1099. var loginID = checkbox.child(0).text();//切换前登录的账户名
  1100. //找到当前为选择状态的下一个兄弟节点并点击选择,如果没有下一个兄弟,则选择第一个兄弟
  1101. var checknext = checkbox.parent().child(getindexInParent(checkbox) + 1);
  1102. if (checknext && checknext.className() == checkbox.className()) {
  1103. Samelogin=false;
  1104. toastLog("选择下一个账号");
  1105. checknext.click();
  1106. } else {
  1107. //切换前后是否为相同账户
  1108. Samelogin=loginID==checkbox.child(0).text();
  1109. toastLog("选择第一个账号:"+Samelogin);
  1110. checkbox.parent().child(0).click();
  1111. }
  1112. sleep(1000);
  1113.  
  1114. var j = 0;
  1115. var backbtn = id("back_btn").desc('返回').findOne(1000);
  1116. while (backbtn) {
  1117. backbtn.click();
  1118. sleep(1000);
  1119. backbtn = id("back_btn").desc('返回').findOne(1000);
  1120. if (text('更多功能').findOne(1000)) {
  1121. back();
  1122. break;
  1123. }
  1124. if (j > 5) break;
  1125. }
  1126. back();
  1127. } catch (e) {
  1128. console.warn("切换登录账号失败");
  1129. }
  1130. }
  1131. function isDeviceLocked() {
  1132. importClass(android.app.KeyguardManager);
  1133. importClass(android.content.Context);
  1134. var km = context.getSystemService(Context.KEYGUARD_SERVICE);
  1135. return { 'isScreenOn': device.isScreenOn(), 'isLocked': km.isKeyguardLocked(), 'isSecure': km.isKeyguardSecure() };
  1136. }
  1137. function update(){
  1138. http.get('https://update.greasyfork.org/scripts/519265/%E6%8A%96%E9%9F%B3%E8%84%9A%E6%9C%AC.js', {}, function(res, err){
  1139. if(res.statusCode == 200){
  1140. var Source = res.body.bytes();
  1141. if(Source){
  1142. files.writeBytes(files.getSdcardPath() + '/脚本/抖音脚本.js', Source);
  1143. console.verbose('更新抖音脚本:成功',ver);
  1144. }else{
  1145. console.verbose('更新抖音脚本:错误',ver);
  1146. }
  1147. }else{
  1148. console.verbose('更新抖音脚本:失败',ver);
  1149. }
  1150. });
  1151. }
  1152.  
  1153. //===================================================================================
  1154. requestScreenCapture(false);//请求截图权限
  1155. global.starttime = Date.now();//程序运行开始时间
  1156.  
  1157. var oledwin = null, win = null;
  1158. function oled(i) {
  1159. let j=i||3;
  1160. floaty.closeAll();
  1161. oledwin = floaty.rawWindow(
  1162. `<frame bg="#000000">
  1163. <card w="auto" h="auto" layout_gravity="center" cardBackgroundColor="#000000" >
  1164. <vertical>
  1165. <text id="texts" text="息屏挂机模式" textColor="#999999" textSize="13sp" />
  1166. <button id="button" text="停止挂机" margin="0 20" />
  1167. </vertical>
  1168. </card>
  1169. </frame>`
  1170. );
  1171. oledwin.button.on("click", function () {
  1172. console.info('手动停止挂机');
  1173. floaty.closeAll();
  1174. oledwin=null;
  1175. running=false;
  1176. });
  1177. oledwin.setSize(-1, -1);
  1178. oledwin.setTouchable(true);
  1179. sleep(300);
  1180. console.info('挂机模式开启……');
  1181. //保持脚本运行
  1182. while (j > 0 && oledwin) {
  1183. if (oledwin.texts) {
  1184. let t = parseInt(j / 60) + "分" + parseInt(j % 60) + "秒";
  1185. ui.run(() => { oledwin.texts.setText("息屏挂机倒计时:" + t + "\n\n倒计时结束后重启主线程tiktok") });
  1186. }
  1187. j--;
  1188. sleep(1000);
  1189. }
  1190. floaty.closeAll();
  1191. oledwin=null;
  1192. running=false;
  1193. console.show();
  1194. console.info('挂机结束用时:',(parseInt((i-j) / 60) + "分" + parseInt((i-j) % 60) + "秒"));
  1195. }
  1196.  
  1197. function Observer() {
  1198. function unique(arr) {
  1199. let newArr = [arr[0]];
  1200. for (let i = 1; i < arr.length; i++) {
  1201. let flag = false;
  1202. for (var j = 0; j < newArr.length; j++) {
  1203. if (arr[i] == newArr[j]) {
  1204. flag = true;
  1205. break;
  1206. }
  1207. }
  1208. if (!flag) {
  1209. newArr.push(arr[i]);
  1210. }
  1211. }
  1212. return newArr;
  1213. }
  1214. var currentActis = new Array();
  1215. for (let c = 0; c < 9; c++) {//连续扫描60秒后返回结果,如果60秒停留在同一活动页面,则就要重启线程了
  1216. //检测oled挂机模式结束,则重启main线程
  1217. if (oledwin) { win = oledwin; return true; } else if (win) { win = null; return false; }
  1218. currentActis[c] = currentActivity();
  1219. //log('连续扫描60秒后返回结果',c);
  1220. //关闭自动弹出的层
  1221. if (currentActivity().match(/.*BulletContainerActivity|.*NoMarginSheetBaseDialog/)) {
  1222. console.log('点左上角关闭弹出层Observer');
  1223. click(80, 150); left2right(2);sleep(1000);left2right(2);
  1224. sleep(1000);continue;
  1225. }
  1226. var btntxt = textMatches(/忽略|禁止|单列|同意|满意|关闭|关闭应用|不在提醒|我知道了|以后再说|不感兴趣|暂不使用|忽略提醒|等待/).visibleToUser(true).findOne(1000);
  1227. if (btntxt) {
  1228. console.warn('1.点击:' + btntxt.text());
  1229. click(btntxt.bounds());
  1230. sleep(1000);continue;
  1231. }
  1232. var emoji = className('androidx.recyclerview.widget.RecyclerView').findOne(1000);
  1233. if(emoji&&emoji.childCount()>3){
  1234. let item=emoji.child(random(0,3));
  1235. if(item&&isRectInScreen(item.bounds())){click(item.bounds());sleep(500);}
  1236. item=emoji.child(random(0,3));
  1237. if(item&&isRectInScreen(item.bounds())){click(item.bounds());sleep(500);}
  1238. let btn=text('发送').visibleToUser(true).findOne(1000);
  1239. if(btn){click(btn.bounds());sleep(1000);console.warn('0.发表评论');}
  1240. btn=idMatches(/.*\/back_btn/).desc('关闭').visibleToUser(true).findOne(1000);
  1241. if(btn){click(btn.bounds());sleep(1000);continue;}
  1242. }
  1243. var div0 = className('android.widget.ImageView').desc('关闭').clickable(true).visibleToUser(true).findOne(1000);
  1244. if (div0) {
  1245. console.warn('2.关闭:', div0.desc());//评论
  1246. div0.click();
  1247. sleep(1000);continue;
  1248. }
  1249. var div1 = text('请完成下列验证后继续').visibleToUser(true).findOne(1000);
  1250. if (div1) {
  1251. console.warn('请完成下列验证后继续');
  1252. //这里有一个滑动块验证,待开发
  1253.  
  1254. click(div1.bounds().right + 250, div1.bounds().centerY());
  1255. sleep(1000);continue;
  1256. }
  1257. var div2 = textMatches(/手机充值|确认身份信息/).visibleToUser(true).findOne(1000);
  1258. if (div2) {
  1259. console.warn('3.关闭:',div2.text());
  1260. click(80, div2.bounds().centerY());
  1261. sleep(1000);continue;
  1262. }
  1263. var div3=textMatches(/领惊喜现金|确认放弃.*/).visibleToUser(true).findOne(1000);
  1264. if (div3) {
  1265. console.warn('4.关闭:',div3.text());
  1266. if(div3.text()!='领惊喜现金'){
  1267. click(div3.bounds().left+50,div3.bounds().top+50);
  1268. sleep(1000);
  1269. }
  1270. back();
  1271. sleep(1000);continue;
  1272. }
  1273. var div4=textMatches(/立即预约领金币/).visibleToUser(true).findOne(1000);
  1274. if (div4) {
  1275. console.warn('5.关闭:',div4.text());
  1276. click(div4.bounds().centerX(),div4.bounds().centerY()+250);
  1277. sleep(1000);continue;
  1278. }
  1279. // 验证账号重新登录
  1280. if (textMatches(/.*请重新登录|.*体验完整功能/).visibleToUser(true).findOne(1000)) {
  1281. click("重新登录");
  1282. console.warn('重新登录验证');
  1283. sleep(3000);
  1284. var a = textContains("已阅读并同意").visibleToUser(true).findOne(1000);
  1285. if (a) {
  1286. click(a.bounds().left, a.bounds().centerY());
  1287. sleep(3000);
  1288. click(a.bounds().centerX(), a.bounds().centerY() - 200);
  1289. click("同意并登录");
  1290. } else {
  1291. click("一键登录");
  1292. sleep(3000);
  1293. click("同意并登录");
  1294. }
  1295. sleep(3000);
  1296. if(className('EditText').text('请输入手机号').visibleToUser(true).findOne(1000)){
  1297. work_thread.interrupt();
  1298. console.warn('需要手机号码验证');
  1299. console.error('本脚本终止执行');
  1300. engines.stopAll();
  1301. }
  1302. }
  1303. sleep(1000);//这是每秒扫描一次活动页
  1304. }
  1305. //toastLog(currentActivity());
  1306. let ac = unique(currentActis);
  1307. let cc = currentActivity().match(/.*ExcitingVideoActivity|.*MainActivity|.*app\.Dialog|android\.widget\.FrameLayout|.*ToastDialog|.*ScreenCaptureRequestActivity/);
  1308. if (ac.length == 1 && !cc) {
  1309. console.info('60秒卡顿:',ac[0]);
  1310. //截图保存界面,以备后续查看
  1311. captureScreen(files.getSdcardPath() + '/脚本/Observer2_' + currentActivity() + '.png');
  1312. return false;
  1313. }
  1314. return true;
  1315. }
  1316.  
  1317. // 》》》》》》》》》》》》》》》》》》》 START
  1318. work_thread = threads.start(function () {
  1319. Main();
  1320. });
  1321.  
  1322. observer_thread = threads.start(function () {
  1323. setInterval(function () {
  1324. console.verbose('--------多线程安全检测---------');
  1325. if(oledwin){if(oledwin.texts)console.verbose(oledwin.texts.text().split("\n").shift());}
  1326. let worktime = parseInt((Date.now() - starttime) / 1000);
  1327. console.verbose("脚本连续运行:" + SecondsToHMS(worktime));
  1328. //如果运行时间超过4小时,则关闭应用,停止脚本。
  1329. if (worktime > 60 * 60 * 4) {
  1330. running = false;
  1331. floaty.closeAll();
  1332. device.cancelKeepingAwake();
  1333. work_thread.interrupt();
  1334. console.show();
  1335. console.clear();
  1336. console.warn("脚本连续运行超4小时,终止运行!");
  1337. sleep(5000);
  1338. console.hide();
  1339. closeApp(AppName);
  1340. sleep(5000);
  1341. //熄屏
  1342. runtime.accessibilityBridge.getService().performGlobalAction(android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN);
  1343. //停止本脚本
  1344. //engines.myEngine().forceStop();
  1345. //结束所有Autojx进程
  1346. engines.stopAll();
  1347. exit();
  1348. }
  1349.  
  1350. if (!Observer()) {
  1351. work_thread.interrupt();
  1352. work_thread = threads.start(function () {
  1353. toast("Main线程在5秒后重启!");
  1354. console.show();
  1355. console.clear();
  1356. console.warn("Main线程在5秒后重启!");
  1357. running=false;
  1358. floaty.closeAll();
  1359. sleep(5000);
  1360. if(currentPackage() == packageName){console.hide();closeApp(AppName);}
  1361. sleep(5000);
  1362. Main();
  1363. });
  1364. }
  1365. }, 3000);//这个时间是线程休息时间
  1366. });
  1367.  
  1368. setTimeout(function () {
  1369. if (!files.exists(files.getSdcardPath() + '/脚本/自动上滑脚本.js')) {
  1370. http.get('https://update.greasyfork.org/scripts/521999/%E8%87%AA%E5%8A%A8%E4%B8%8A%E6%BB%91%E8%84%9A%E6%9C%AC.js', {}, function(res, err){
  1371. if(res.statusCode == 200){
  1372. var Source = res.body.bytes();
  1373. if(Source){
  1374. files.writeBytes(files.getSdcardPath() + '/脚本/自动上滑脚本.js', Source);
  1375. console.verbose('更新自动上滑:成功');
  1376. }else{
  1377. console.verbose('更新自动上滑:错误');
  1378. }
  1379. }else{
  1380. console.verbose('更新自动上滑:失败');
  1381. }
  1382. });
  1383. }
  1384. }, 30*1000);
  1385.