Browse Source

完成

master
kavil 1 year ago
parent
commit
8339d390b0
  1. 31
      src/base/index.ts
  2. 162
      src/index.ts
  3. 65
      src/lib/utils.ts

31
src/base/index.ts

@ -13,7 +13,7 @@ export abstract class DPStarter extends DPEvent<DPStarterEvents> {
} }
init() { init() {
console.log('init'); console.log('初始化!');
this.doInit(); this.doInit();
} }
@ -24,9 +24,8 @@ export abstract class DPStarter extends DPEvent<DPStarterEvents> {
this.init(); this.init();
this.on('over', (task: DPTask) => { this.on('over', (task: DPTask) => {
const index = this._tasks.indexOf(task); const index = this._tasks.indexOf(task);
task.removeAllListeners(); console.log('index:', index);
this.removeTask(task); if (this._tasks[index + 1]) {
if (index < this._tasks.length - 1) {
this.doInit(); // 回到初始界面状态 this.doInit(); // 回到初始界面状态
this._tasks[index + 1].start(); this._tasks[index + 1].start();
} }
@ -92,39 +91,31 @@ export class DPTask extends DPEvent {
this._name = name; this._name = name;
} }
constructor(owner: DPStarter) { constructor(owner: DPStarter, name = '') {
super(); super();
this.owner = owner; this.owner = owner;
this._name = name;
console.log('task created:', name);
this.owner.addTask(this); this.owner.addTask(this);
} }
init() { init() {
console.log('init');
this.status = TaskStatus.Init; this.status = TaskStatus.Init;
} }
start() { start() {
console.log('start');
this.status = TaskStatus.Running; this.status = TaskStatus.Running;
if (!this._fn) { if (!this._fn) {
console.error('任务未设置执行函数'); console.error(`task-${this.name}:任务未设置执行函数`);
return; return;
} }
console.log(`task-${this.name}:开始执行`);
this._fn(); this._fn();
this.stop();
} }
pause() { private stop() {
console.log('pause'); console.log(`task-${this.name}:结束`);
this.status = TaskStatus.Paused;
}
stop() {
console.log('stop');
this.status = TaskStatus.Stopped; this.status = TaskStatus.Stopped;
} }
restart() {
console.log('restart');
this.status = TaskStatus.Running;
}
} }

162
src/index.ts

@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { DPStarter, DPTask } from './base/index'; import { DPStarter, DPTask } from './base/index';
import { clickForce, findNextElement, withMakeSure } from './lib/utils'; import { clickForce, clickForceXY, isNextElement, findPrevElement, withMakeSure } from './lib/utils';
// 弹窗关闭按钮 // 弹窗关闭按钮
const modalCloseBtn = className('com.lynx.tasm.behavior.ui.LynxFlattenUI') const modalCloseBtn = className('com.lynx.tasm.behavior.ui.LynxFlattenUI')
@ -7,17 +8,12 @@ const modalCloseBtn = className('com.lynx.tasm.behavior.ui.LynxFlattenUI')
.clickable(true) .clickable(true)
.text(''); .text('');
// 可能出现的是否打开app弹窗确定按钮
const openAppModal = id('android:id/button1');
// 福利界面底部栏入口按钮 // 福利界面底部栏入口按钮
const welfareEntry = id('di1').text('福利').visibleToUser().selected(false); const welfareEntry = id('di1').text('福利').visibleToUser();
class Hongguo extends DPStarter { class Hongguo extends DPStarter {
doInit() { doInit() {
console.log('初始化!'); withMakeSure('打开红果', () => app.launch('com.phoenix.read'), {
withMakeSure(() => app.launch('com.phoenix.read'), {
hasModal: [() => openAppModal.findOne(500), () => modalCloseBtn.findOne(500)], // 有可能出现的弹窗
landOver: [() => welfareEntry.findOne(500)] // 确认是否到达目的页 landOver: [() => welfareEntry.findOne(500)] // 确认是否到达目的页
}); });
const widget = welfareEntry.findOne(500); const widget = welfareEntry.findOne(500);
@ -27,30 +23,160 @@ class Hongguo extends DPStarter {
const hongguo = new Hongguo(); const hongguo = new Hongguo();
const task1 = new DPTask(hongguo); const task1 = new DPTask(hongguo, '新人见面礼');
const task2 = new DPTask(hongguo, '日常福利-签到');
const task3 = new DPTask(hongguo, '看广告视频');
const task4 = new DPTask(hongguo, '看短剧');
// 新人见面礼立即领取 // 新人见面礼立即领取
task1.run(() => { task1.run(() => {
const startBtn = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').textContains('立即领取').visibleToUser(); const startBtn = className('com.lynx.tasm.behavior.ui.text.FlattenUIText')
.boundsInside(0, 0, device.width / 2, device.height / 2)
.text('立即领取')
.visibleToUser();
const getBtn = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('立即领取').visibleToUser();
const getGoldNext = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('金币奖励可在「福利」查看').visibleToUser(); const getGoldNext = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('金币奖励可在「福利」查看').visibleToUser();
const overBtn = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').textContains('明日再来').visibleToUser(); const overBtn = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('明日再来').visibleToUser();
console.log('task1 新人见面礼立即领取'); console.log('task1');
withMakeSure(() => clickForce(startBtn.findOne(500)), { const stepBtn1 = withMakeSure(
landOver: [() => modalCloseBtn.findOne(500), () => getGoldNext.findOne(500)] // 确认是否到达目的页 '立即领取',
}); () => {
clickForce(startBtn.findOne(500));
return startBtn;
},
{
landOver: [() => modalCloseBtn.findOne(500), () => getGoldNext.findOne(500)], // 确认是否到达目的页
retry: 2
}
);
if (stepBtn1) {
if (overBtn.findOne(500)) { if (overBtn.findOne(500)) {
return clickForce(overBtn.findOne(500)); return clickForce(overBtn.findOne(500));
} }
withMakeSure('立即领取inModal', () => clickForce(getBtn.findOne(500)), {
withMakeSure(() => clickForce(startBtn.findOne(500)), {
landOver: [ landOver: [
() => modalCloseBtn.findOne(500), () => modalCloseBtn.findOne(500),
() => findNextElement(overBtn, getGoldNext, 'com.lynx.tasm.behavior.ui.text.FlattenUIText') () => isNextElement(overBtn, getGoldNext, 'com.lynx.tasm.behavior.ui.text.FlattenUIText')
] // 确认是否到达目的页 ] // 确认是否到达目的页
}); });
return clickForce(overBtn.findOne(500)); return clickForce(overBtn.findOne(500));
}
});
task2.run(() => {
console.log('task2');
try {
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('日常福利').visibleToUser().findOne(500)!;
swipe(.bounds().centerX(), .bounds().centerY(), .bounds().centerX(), 0, 500);
} catch (e) {
console.log(e);
}
const Btn = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('去签到').visibleToUser();
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('已签到').visibleToUser();
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').textContains('立即签到').visibleToUser();
const = className('com.lynx.tasm.behavior.ui.text.UIText').textContains('看视频最高再领').visibleToUser();
if (.findOne(500)) {
return;
}
withMakeSure('签到', () => clickForce(Btn.findOne(500)), {
landOver: [() => modalCloseBtn.findOne(500)], // 确认是否到达目的页
retry: 2
});
clickForce(.findOne(1500));
clickForce(.findOne(1500), false);
lookAD();
clickForce(modalCloseBtn.findOne(1500));
});
task3.run(() => {
try {
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('日常福利').visibleToUser().findOne(500)!;
swipe(.bounds().centerX(), .bounds().centerY(), .bounds().centerX(), 0, 500);
} catch (e) {}
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').textContains('立即领取').visibleToUser();
clickForce(.findOne(500));
lookAD();
});
task4.run(() => {
try {
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('日常福利').visibleToUser().findOne(500)!;
swipe(.bounds().centerX(), .bounds().centerY(), .bounds().centerX(), 0, 500);
} catch (e) {}
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').textContains('去看剧').visibleToUser();
clickForce(.findOne(500));
const = id('com.phoenix.read:id/nj').textContains('金币').visibleToUser();
const = className('android.widget.TextView').text('追剧');
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('立即领取').visibleToUser();
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').textContains('再攒').visibleToUser();
const = className('com.lynx.tasm.behavior.ui.text.UIText').textContains('看视频').visibleToUser();
const startTime = new Date().getTime();
let looking = true;
while (looking) {
if (.exists()) {
withMakeSure('领金币', () => clickForce(.findOne(500)), {
retry: 2,
landOver: [() => .findOne(500)]
}); });
const current立即领取 = findPrevElement(, 'com.lynx.tasm.behavior.ui.text.FlattenUIText');
clickForce(current立即领取);
if (.exists()) {
clickForce(.findOne(1500), false);
lookAD();
}
console.log('task0');
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('开宝箱得金币');
if (.exists()) {
withMakeSure('开宝箱', () => clickForce(.findOne(500)), {
landOver: [() => modalCloseBtn.findOne(500)], // 确认是否到达目的页
retry: 2
});
if (.exists()) {
clickForce(.findOne(1500), false);
lookAD();
}
}
clickForce(modalCloseBtn.findOne(1500));
clickForce(.findOne(500));
}
if (!.exists()) {
looking = false;
}
sleep(30000);
console.log(`已经看了${(new Date().getTime() - startTime) / 1000 / 60}分钟`);
// 8小时结束
if (new Date().getTime() - startTime > 1000 * 60 * 60 * 8) {
looking = false;
}
}
});
function lookAD() {
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('领取成功').visibleToUser();
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('领取奖励').visibleToUser();
sleep(5000);
let ok = false;
while (!ok) {
ok = .exists();
console.log('广告ing');
sleep(2000);
}
const bounds = .findOne(500)!.bounds();
click(bounds.right + 5, bounds.top + 5);
sleep(1000);
if (.exists()) {
clickForce(.findOne(500), false);
lookAD();
}
}
hongguo.start(); hongguo.start();

65
src/lib/utils.ts

@ -1,5 +1,5 @@
// 找到控件区域点击 // 找到控件区域点击
export function clickForce(ele: UiObject | null) { export function clickForce(ele: UiObject | null, muilt = true) {
if (!ele) { if (!ele) {
console.log('控件不存在'); console.log('控件不存在');
return; return;
@ -8,9 +8,11 @@ export function clickForce(ele: UiObject | null) {
const x = bound.centerX(); const x = bound.centerX();
const y = bound.centerY(); const y = bound.centerY();
click(x, y); click(x, y);
if (muilt) {
click(x - 1, y + 1); click(x - 1, y + 1);
click(x + 1, y - 1); click(x + 1, y - 1);
} }
}
export function clickForceXY(x: number, y: number, width: number, height: number) { export function clickForceXY(x: number, y: number, width: number, height: number) {
width ? (x = x + width / 2) : (x = x + 2); width ? (x = x + width / 2) : (x = x + 2);
@ -20,7 +22,7 @@ export function clickForceXY(x: number, y: number, width: number, height: number
click(x + 1, y - 1); click(x + 1, y - 1);
} }
export function findNextElement(ele: UiSelector, nextEle: UiSelector, classNameString: string, step: number = 1) { export function isNextElement(ele: UiSelector, nextEle: UiSelector, classNameString: string, step = 1) {
const findit = ele.findOne(500); const findit = ele.findOne(500);
const finditNext = nextEle.findOne(500); const finditNext = nextEle.findOne(500);
if (!findit || !finditNext) { if (!findit || !finditNext) {
@ -43,7 +45,7 @@ export function findNextElement(ele: UiSelector, nextEle: UiSelector, classNameS
return false; return false;
} }
export function findPrevElement(ele: UiSelector, prevEle: UiSelector, classNameString: string, step: number = 1) { export function isPrevElement(ele: UiSelector, prevEle: UiSelector, classNameString: string, step = 1) {
const findit = ele.findOne(500); const findit = ele.findOne(500);
const finditPrev = prevEle.findOne(500); const finditPrev = prevEle.findOne(500);
if (!findit || !finditPrev) { if (!findit || !finditPrev) {
@ -66,6 +68,34 @@ export function findPrevElement(ele: UiSelector, prevEle: UiSelector, classNameS
return false; return false;
} }
export function findPrevElement(ele: UiSelector, classNameString: string, step = 1) {
const findit = ele.findOne(500);
if (!findit) {
return null;
}
const eles = className(classNameString).find();
const index = eles.findIndex((ele) => {
if (ele.bounds().centerX() === findit.bounds().centerX() && ele.bounds().centerY() === findit.bounds().centerY()) {
return ele;
}
});
return eles[index - step];
}
export function findNextElement(ele: UiSelector, classNameString: string, step = 1) {
const findit = ele.findOne(500);
if (!findit) {
return null;
}
const eles = className(classNameString).find();
const index = eles.findIndex((ele) => {
if (ele.bounds().centerX() === findit.bounds().centerX() && ele.bounds().centerY() === findit.bounds().centerY()) {
return ele;
}
});
return eles[index + step];
}
export interface MakeSureOptions { export interface MakeSureOptions {
hasModal?: (() => UiObject | null)[]; hasModal?: (() => UiObject | null)[];
retry?: number; retry?: number;
@ -73,18 +103,25 @@ export interface MakeSureOptions {
} }
export function withMakeSure<T>( export function withMakeSure<T>(
name: string,
fn: () => T | null, fn: () => T | null,
options: { hasModal?: (() => UiObject | null)[]; retry?: number; landOver?: (() => void)[] } options: { hasModal?: (() => UiObject | null)[]; retry?: number; whileTimes?: number; landOver?: (() => any)[] }
) { ) {
const { hasModal, landOver, retry = 5 } = options; const { hasModal, landOver, retry = 3, whileTimes = 5 } = options;
let result = fn() || true;
let result: boolean | T = false;
let forNum = 0;
for (let i = 0; i < retry; i++) {
result = fn() || true;
console.log(name, 'fn:', result);
let whileNum = 0; let whileNum = 0;
let ok = false; let ok = false;
while (!ok) { while (!ok) {
whileNum++; if (whileNum > whileTimes) {
if (whileNum > retry) {
result = false; result = false;
break; break;
} }
@ -97,12 +134,20 @@ export function withMakeSure<T>(
} }
} }
if (landOver) { if (landOver) {
ok = landOver.every((fn) => fn()); ok = landOver.every((fn) => !!fn());
} else { } else {
ok = true; ok = true;
} }
whileNum++;
sleep(500); sleep(500);
} }
console.log('fn:', fn, 'whileNum:', whileNum, 'result:', result);
if (ok) {
break;
}
forNum++;
}
console.log(name, 'retry:', forNum, 'result:', result);
return result as T; return result as T;
} }

Loading…
Cancel
Save