Browse Source

第一个任务

master
kai 1 year ago
parent
commit
9e39125ee9
  1. 32
      src/base/index.ts
  2. 59
      src/index.ts
  3. 89
      src/lib/utils.ts

32
src/base/index.ts

@ -1,4 +1,3 @@
import { clickForce } from '../lib/utils';
import { DPEvent } from './event';
type DPStarterEvents = {
@ -15,16 +14,6 @@ export abstract class DPStarter extends DPEvent<DPStarterEvents> {
init() {
console.log('init');
const texts = className('android.widget.TextView')
.find()
.map((item) => item.text());
console.log(texts);
if (texts.includes('启动应用')) {
console.log('启动应用');
clickForce(id('button1').findOne());
}
this.doInit();
}
@ -35,31 +24,32 @@ export abstract class DPStarter extends DPEvent<DPStarterEvents> {
this.init();
this.on('over', (task: DPTask) => {
const index = this._tasks.indexOf(task);
task.removeAllListeners();
this.removeTask(task);
if (index < this._tasks.length - 1) {
this.doInit(); // 回到初始界面状态
this._tasks[index + 1].start();
}
if (index === this._tasks.length - 1) {
this.emit('exit');
}
task.removeAllListeners();
this.removeTask(task);
});
this._tasks[0]?.start();
}
addTask(task: DPTask) {
this._tasks.push(task);
}
removeTask(task: DPTask) {
private removeTask(task: DPTask) {
const index = this._tasks.indexOf(task);
if (index >= 0) {
this._tasks.splice(index, 1);
}
}
clearTasks() {
private clearTasks() {
this._tasks = [];
}
}
@ -73,6 +63,10 @@ export enum TaskStatus {
}
export class DPTask extends DPEvent {
private _fn: (() => void) | undefined;
run(fn: () => void) {
this._fn = fn;
}
// 任务状态
private _status: TaskStatus = TaskStatus.Init;
@ -101,6 +95,7 @@ export class DPTask extends DPEvent {
constructor(owner: DPStarter) {
super();
this.owner = owner;
this.owner.addTask(this);
}
init() {
@ -111,6 +106,11 @@ export class DPTask extends DPEvent {
start() {
console.log('start');
this.status = TaskStatus.Running;
if (!this._fn) {
console.error('任务未设置执行函数');
return;
}
this._fn();
}
pause() {

59
src/index.ts

@ -1,15 +1,26 @@
import { DPStarter, DPTask } from './base/index';
import { clickForce } from './lib/utils';
import { clickForce, findNextElement, withMakeSure } from './lib/utils';
// 弹窗关闭按钮
const modalCloseBtn = className('com.lynx.tasm.behavior.ui.LynxFlattenUI')
.boundsInside(100, device.height / 2, device.width - 100, device.height)
.clickable(true)
.text('');
// 可能出现的是否打开app弹窗确定按钮
const openAppModal = id('android:id/button1');
// 福利界面底部栏入口按钮
const welfareEntry = id('di1').text('福利').visibleToUser().selected(false);
class Hongguo extends DPStarter {
doInit() {
console.log('初始化!');
makeSure(app.launch('com.phoenix.read'), {
closeBtns: ['android:id/button1'],
landing: [id('di1').text('福利').visibleToUser().selected(false).findOne(1000)]
withMakeSure(() => app.launch('com.phoenix.read'), {
hasModal: [() => openAppModal.findOne(500), () => modalCloseBtn.findOne(500)], // 有可能出现的弹窗
landOver: [() => welfareEntry.findOne(500)] // 确认是否到达目的页
});
const widget = id('di1').text('福利').visibleToUser().selected(false).findOne(1000);
const widget = welfareEntry.findOne(500);
widget && clickForce(widget);
}
}
@ -17,17 +28,29 @@ class Hongguo extends DPStarter {
const hongguo = new Hongguo();
const task1 = new DPTask(hongguo);
// 新人见面礼立即领取
task1.run(() => {
const startBtn = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').textContains('立即领取').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();
console.log('task1 新人见面礼立即领取');
hongguo.start();
function makeSure(result: any, options: any) {
if (!result) {
console.log('result is null');
return;
}
if (options.closeBtns) {
options.closeBtns.forEach((cid: string) => {
const btn = id(cid).findOne(1000);
btn && clickForce(btn);
});
withMakeSure(() => clickForce(startBtn.findOne(500)), {
landOver: [() => modalCloseBtn.findOne(500), () => getGoldNext.findOne(500)] // 确认是否到达目的页
});
if (overBtn.findOne(500)) {
return clickForce(overBtn.findOne(500));
}
}
withMakeSure(() => clickForce(startBtn.findOne(500)), {
landOver: [
() => modalCloseBtn.findOne(500),
() => findNextElement(overBtn, getGoldNext, 'com.lynx.tasm.behavior.ui.text.FlattenUIText')
] // 确认是否到达目的页
});
return clickForce(overBtn.findOne(500));
});
hongguo.start();

89
src/lib/utils.ts

@ -1,5 +1,5 @@
// 找到控件区域点击
export function clickForce(ele: UiObject) {
export function clickForce(ele: UiObject | null) {
if (!ele) {
console.log('控件不存在');
return;
@ -19,3 +19,90 @@ 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) {
const findit = ele.findOne(500);
const finditNext = nextEle.findOne(500);
if (!findit || !finditNext) {
return false;
}
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;
}
});
if (
eles[index + step].bounds().centerX() === finditNext.bounds().centerX() &&
eles[index + step].bounds().width() === finditNext.bounds().width() &&
eles[index + step].bounds().height() === finditNext.bounds().height() &&
eles[index + step].bounds().centerY() === finditNext.bounds().centerY()
) {
return true;
}
return false;
}
export function findPrevElement(ele: UiSelector, prevEle: UiSelector, classNameString: string, step: number = 1) {
const findit = ele.findOne(500);
const finditPrev = prevEle.findOne(500);
if (!findit || !finditPrev) {
return false;
}
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;
}
});
if (
eles[index - step].bounds().centerX() === finditPrev.bounds().centerX() &&
eles[index - step].bounds().width() === finditPrev.bounds().width() &&
eles[index - step].bounds().height() === finditPrev.bounds().height() &&
eles[index - step].bounds().centerY() === finditPrev.bounds().centerY()
) {
return true;
}
return false;
}
export interface MakeSureOptions {
hasModal?: (() => UiObject | null)[];
retry?: number;
landOver?: (() => void)[];
}
export function withMakeSure<T>(
fn: () => T | null,
options: { hasModal?: (() => UiObject | null)[]; retry?: number; landOver?: (() => void)[] }
) {
const { hasModal, landOver, retry = 5 } = options;
let result = fn() || true;
let whileNum = 0;
let ok = false;
while (!ok) {
whileNum++;
if (whileNum > retry) {
result = false;
break;
}
if (hasModal) {
const modals = hasModal.map((fn) => fn());
if (modals.length) {
modals.forEach((modal) => {
modal && clickForce(modal);
});
}
}
if (landOver) {
ok = landOver.every((fn) => fn());
} else {
ok = true;
}
sleep(500);
}
console.log('fn:', fn, 'whileNum:', whileNum, 'result:', result);
return result as T;
}

Loading…
Cancel
Save