kai 1 year ago
parent
commit
1f7a301de5
  1. 241
      src/index.ts
  2. 0
      src/lib/event.ts
  3. 20
      src/lib/index.ts
  4. 103
      src/lib/utils.ts

241
src/index.ts

@ -1,113 +1,223 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { DPStarter, DPTask } from './base/index';
import { clickForce, clickForceXY, isNextElement, findPrevElement, withMakeSure } from './lib/utils';
import { DPStarter, DPTask } from './lib/index';
import { clickForce, clickForceXY, isNextElement, findPrevElement, withMakeSure, swipeToCenter } from './lib/utils';
// 弹窗关闭按钮
const modalCloseBtn = className('com.lynx.tasm.behavior.ui.LynxFlattenUI')
const = className('com.lynx.tasm.behavior.ui.LynxFlattenUI')
.boundsInside(100, device.height / 2, device.width - 100, device.height)
.clickable(true)
.text('');
// 福利界面底部栏入口按钮
const welfareEntry = id('di1').text('福利').visibleToUser();
const = id('di1').text('福利').visibleToUser();
const lookTime = 60 * 8; // 看剧时间 默认8小时
class Hongguo extends DPStarter {
doInit() {
withMakeSure('打开红果', () => app.launch('com.phoenix.read'), {
landOver: [() => welfareEntry.findOne(500)] // 确认是否到达目的页
landOver: [() => .findOne(500)] // 确认是否到达目的页
});
const widget = welfareEntry.findOne(500);
widget && clickForce(widget);
clickForce(.findOne(500));
}
}
const hongguo = new Hongguo();
const task1 = new DPTask(hongguo, '新人见面礼');
const task2 = new DPTask(hongguo, '日常福利-签到');
const task3 = new DPTask(hongguo, '看广告视频');
const task4 = new DPTask(hongguo, '看短剧');
const task = new DPTask(hongguo, '新人见面礼');
const task = new DPTask(hongguo, '日常福利-吃饭补贴');
const task = new DPTask(hongguo, '日常福利-签到');
const 广task = new DPTask(hongguo, '看广告视频');
const task = new DPTask(hongguo, '看短剧');
// 新人见面礼立即领取
task1.run(() => {
const startBtn = className('com.lynx.tasm.behavior.ui.text.FlattenUIText')
task.run((task) => {
swipe(device.width / 2, device.height * 0.2, device.width / 2, device.height * 0.9, 500);
swipe(device.width / 2, device.height * 0.2, device.width / 2, device.height * 0.9, 500);
const = 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 overBtn = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('明日再来').visibleToUser();
console.log('task1');
const = 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').text('明日再来').visibleToUser();
const stepBtn1 = withMakeSure(
'立即领取',
const = withMakeSure(
'点击立即领取',
() => {
clickForce(startBtn.findOne(500));
return startBtn;
clickForce(.findOne(500));
return ;
},
{
landOver: [() => modalCloseBtn.findOne(500), () => getGoldNext.findOne(500)], // 确认是否到达目的页
landOver: [() => .findOne(500), () => .findOne(500)], // 确认是否到达目的页
retry: 2
}
);
if (stepBtn1) {
if (overBtn.findOne(500)) {
return clickForce(overBtn.findOne(500));
if () {
if (.findOne(500)) {
return clickForce(.findOne(500));
}
withMakeSure('立即领取inModal', () => clickForce(getBtn.findOne(500)), {
withMakeSure('弹窗里立即领取', () => clickForce(.findOne(500)), {
landOver: [
() => modalCloseBtn.findOne(500),
() => isNextElement(overBtn, getGoldNext, 'com.lynx.tasm.behavior.ui.text.FlattenUIText')
() => .findOne(500),
() => isNextElement(, , 'com.lynx.tasm.behavior.ui.text.FlattenUIText')
] // 确认是否到达目的页
});
return clickForce(overBtn.findOne(500));
return clickForce(.findOne(500));
} else {
// 如果没有找到说明任务已经做了
task.log('新人任务已经做过了');
}
});
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);
}
task.run(() => {
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('吃饭补贴').visibleToUser();
withMakeSure('确保在吃饭补贴区域', () => .findOne(500), {
landOver: [() => .findOne(500)], // 确认是否到达目的页
auxAction: [
(makeSure) => {
// 如果有这个控件 直接划到可视区域
makeSure && swipe(makeSure.bounds().centerX(), makeSure.bounds().centerY(), makeSure.bounds().centerX(), 0, 500);
},
() => {
// 如果没有 滑到顶部
swipe(device.width / 2, device.height * 0.2, device.width / 2, device.height * 0.9, 500);
},
() => {
// 如果没有 往下滑动
swipe(device.width / 2, device.height * 0.7, device.width / 2, 0, 500);
}
]
});
swipeToCenter(.findOne(500)!);
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('去领取').visibleToUser();
const = className('com.lynx.tasm.behavior.ui.text.UIText').textContains('早饭').visibleToUser();
const = className('com.lynx.tasm.behavior.ui.text.UIText').textContains('午饭').visibleToUser();
const = className('com.lynx.tasm.behavior.ui.text.UIText').textContains('晚饭').visibleToUser();
const = className('com.lynx.tasm.behavior.ui.text.UIText').textContains('夜宵').visibleToUser();
withMakeSure('签到', () => clickForce(.findOne(500)), {
landOver: [() => .findOne(500)], // 确认是否到达目的页
retry: 2
});
const eat = (ele: UiSelector) => {
clickForce(ele.findOne(500), false);
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').textContains('后可领取奖励').visibleToUser();
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').textContains('看视频再领').visibleToUser();
sleep(3000);
if (.exists()) {
lookAD();
sleep(3000);
if (.exists()) {
clickForce(.findOne(1500), false);
lookAD();
}
}
};
eat();
eat();
eat();
eat();
back();
});
task.run((task) => {
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('日常福利').visibleToUser();
withMakeSure('确保在日常福利区域', () => .findOne(500), {
landOver: [() => .findOne(500)], // 确认是否到达目的页
auxAction: [
(makeSure) => {
// 如果有这个控件 直接划到可视区域
makeSure && swipe(makeSure.bounds().centerX(), makeSure.bounds().centerY(), makeSure.bounds().centerX(), 0, 500);
},
() => {
// 如果没有 滑到顶部
swipe(device.width / 2, device.height * 0.2, device.width / 2, device.height * 0.9, 500);
},
() => {
// 如果没有 往下滑动
swipe(device.width / 2, device.height * 0.7, device.width / 2, 0, 500);
}
]
});
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)) {
task.log('签到任务已经做过了');
return;
}
withMakeSure('签到', () => clickForce(Btn.findOne(500)), {
landOver: [() => modalCloseBtn.findOne(500)], // 确认是否到达目的页
landOver: [() => .findOne(500)], // 确认是否到达目的页
retry: 2
});
clickForce(.findOne(1500));
clickForce(.findOne(1500), false);
clickForce(.findOne(3000), false);
lookAD();
clickForce(modalCloseBtn.findOne(1500));
clickForce(.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));
广task.run(() => {
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('日常福利').visibleToUser();
withMakeSure('确保在日常福利区域', () => .findOne(500), {
landOver: [() => .findOne(500)], // 确认是否到达目的页
auxAction: [
(makeSure) => {
// 如果有这个控件 直接划到可视区域
makeSure && swipe(makeSure.bounds().centerX(), makeSure.bounds().centerY(), makeSure.bounds().centerX(), 0, 500);
},
() => {
// 如果没有 滑到顶部
swipe(device.width / 2, device.height * 0.2, device.width / 2, device.height * 0.9, 500);
},
() => {
// 如果没有 往下滑动
swipe(device.width / 2, device.height * 0.7, device.width / 2, 0, 500);
}
]
});
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').textContains('看视频立得').visibleToUser();
swipeToCenter(.findOne(500)!);
const = findPrevElement(, 'com.lynx.tasm.behavior.ui.text.FlattenUIText');
clickForce();
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) {}
task.run(() => {
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('日常福利').visibleToUser();
withMakeSure('确保在日常福利区域', () => .findOne(500), {
landOver: [() => .findOne(500)], // 确认是否到达目的页
auxAction: [
(makeSure) => {
// 如果有这个控件 直接划到可视区域
makeSure && swipe(makeSure.bounds().centerX(), makeSure.bounds().centerY(), makeSure.bounds().centerX(), 0, 500);
},
() => {
// 如果没有 滑到顶部
swipe(device.width / 2, device.height * 0.2, device.width / 2, device.height * 0.9, 500);
},
() => {
// 如果没有 往下滑动
swipe(device.width / 2, device.height * 0.7, device.width / 2, 0, 500);
}
]
});
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').textContains('去看剧').visibleToUser();
clickForce(.findOne(500));
@ -126,8 +236,8 @@ task4.run(() => {
retry: 2,
landOver: [() => .findOne(500)]
});
const current立即领 = findPrevElement(, 'com.lynx.tasm.behavior.ui.text.FlattenUIText');
clickForce(current立即领);
const = findPrevElement(, 'com.lynx.tasm.behavior.ui.text.FlattenUIText');
clickForce();
if (.exists()) {
clickForce(.findOne(1500), false);
lookAD();
@ -137,7 +247,7 @@ task4.run(() => {
const = className('com.lynx.tasm.behavior.ui.text.FlattenUIText').text('开宝箱得金币');
if (.exists()) {
withMakeSure('开宝箱', () => clickForce(.findOne(500)), {
landOver: [() => modalCloseBtn.findOne(500)], // 确认是否到达目的页
landOver: [() => .findOne(500)], // 确认是否到达目的页
retry: 2
});
if (.exists()) {
@ -145,36 +255,49 @@ task4.run(() => {
lookAD();
}
}
clickForce(modalCloseBtn.findOne(1500));
clickForce(.findOne(1500));
clickForce(.findOne(500));
}
if (!.exists()) {
looking = false;
}
sleep(30000);
console.log(`已经看了${(new Date().getTime() - startTime) / 1000 / 60}分钟`);
console.log(`已经看了${((new Date().getTime() - startTime) / 1000 / 60).toFixed(1)}分钟`);
// 8小时结束
if (new Date().getTime() - startTime > 1000 * 60 * 60 * 8) {
if (new Date().getTime() - startTime > 1000 * 60 * lookTime) {
looking = false;
}
}
back();
});
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);
sleep(3000);
let ok = false;
let times = 0;
while (!ok) {
if (times > 100) {
break;
}
ok = .exists();
console.log('广告ing');
sleep(2000);
times++;
}
if (!ok) {
console.log('看广告失败');
return;
}
const bounds = .findOne(500)!.bounds();
click(bounds.right + 5, bounds.top + 5);
sleep(1000);
if (.exists()) {
clickForce(.findOne(500), false);
console.log('看第二个广告再次领取奖励');
lookAD();
}
}

0
src/base/event.ts → src/lib/event.ts

20
src/base/index.ts → src/lib/index.ts

@ -24,7 +24,6 @@ export abstract class DPStarter extends DPEvent<DPStarterEvents> {
this.init();
this.on('over', (task: DPTask) => {
const index = this._tasks.indexOf(task);
console.log('index:', index);
if (this._tasks[index + 1]) {
this.doInit(); // 回到初始界面状态
this._tasks[index + 1].start();
@ -62,8 +61,8 @@ export enum TaskStatus {
}
export class DPTask extends DPEvent {
private _fn: (() => void) | undefined;
run(fn: () => void) {
private _fn: ((task: this) => void) | undefined;
run(fn: (task: this) => void) {
this._fn = fn;
}
// 任务状态
@ -99,6 +98,13 @@ export class DPTask extends DPEvent {
this.owner.addTask(this);
}
log(...args: any[]) {
console.log(`task-${this.name}`, ...args);
}
error(...args: any[]) {
console.error(`task-error-${this.name}`, ...args);
}
init() {
this.status = TaskStatus.Init;
}
@ -106,16 +112,16 @@ export class DPTask extends DPEvent {
start() {
this.status = TaskStatus.Running;
if (!this._fn) {
console.error(`task-${this.name}任务未设置执行函数`);
this.error(`任务未设置执行函数`);
return;
}
console.log(`task-${this.name}开始执行`);
this._fn();
this.log(`开始执行`);
this._fn(this);
this.stop();
}
private stop() {
console.log(`task-${this.name}结束`);
this.log(`结束`);
this.status = TaskStatus.Stopped;
}
}

103
src/lib/utils.ts

@ -1,4 +1,8 @@
// 找到控件区域点击
/**
* @description: -
* @param {UiObject | null} ele
* @param {boolean} muilt
*/
export function clickForce(ele: UiObject | null, muilt = true) {
if (!ele) {
console.log('控件不存在');
@ -14,7 +18,14 @@ export function clickForce(ele: UiObject | null, muilt = true) {
}
}
export function clickForceXY(x: number, y: number, width: number, height: number) {
/**
* @description: -
* @param {number} x
* @param {number} y
* @param {number} width
* @param {number} height
*/
export function clickForceXY(x: number, y: number, width?: number, height?: number) {
width ? (x = x + width / 2) : (x = x + 2);
height ? (y = y + height / 2) : (y = y + 2);
click(x, y);
@ -22,6 +33,13 @@ export function clickForceXY(x: number, y: number, width: number, height: number
click(x + 1, y - 1);
}
/**
* @description:
* @param {string} ele
* @param {string} classNameString
* @param {number} step
* @return {boolean}
*/
export function isNextElement(ele: UiSelector, nextEle: UiSelector, classNameString: string, step = 1) {
const findit = ele.findOne(500);
const finditNext = nextEle.findOne(500);
@ -45,6 +63,13 @@ export function isNextElement(ele: UiSelector, nextEle: UiSelector, classNameStr
return false;
}
/**
* @description:
* @param {string} ele
* @param {string} classNameString
* @param {number} step
* @return {boolean}
*/
export function isPrevElement(ele: UiSelector, prevEle: UiSelector, classNameString: string, step = 1) {
const findit = ele.findOne(500);
const finditPrev = prevEle.findOne(500);
@ -68,6 +93,13 @@ export function isPrevElement(ele: UiSelector, prevEle: UiSelector, classNameStr
return false;
}
/**
* @description:
* @param {string} ele
* @param {string} classNameString
* @param {number} step
* @return {UiObject | null}
*/
export function findPrevElement(ele: UiSelector, classNameString: string, step = 1) {
const findit = ele.findOne(500);
if (!findit) {
@ -82,6 +114,13 @@ export function findPrevElement(ele: UiSelector, classNameString: string, step =
return eles[index - step];
}
/**
* @description:
* @param {string} ele
* @param {string} classNameString
* @param {number} step
* @return {UiObject | null}
*/
export function findNextElement(ele: UiSelector, classNameString: string, step = 1) {
const findit = ele.findOne(500);
if (!findit) {
@ -96,26 +135,50 @@ export function findNextElement(ele: UiSelector, classNameString: string, step =
return eles[index + step];
}
export interface MakeSureOptions {
hasModal?: (() => UiObject | null)[];
retry?: number;
landOver?: (() => void)[];
export function swipeToCenter(ele: UiObject) {
if (!ele) {
console.log('控件不存在');
return;
}
const bound = ele.bounds();
const x = bound.centerX();
const y = bound.centerY();
swipe(x, y, device.width / 2, device.height / 2, 500);
}
export function withMakeSure<T>(
name: string,
fn: () => T | null,
options: { hasModal?: (() => UiObject | null)[]; retry?: number; whileTimes?: number; landOver?: (() => any)[] }
) {
const { hasModal, landOver, retry = 3, whileTimes = 5 } = options;
interface MakeSureOptions<T> {
hasModal?: (() => UiObject | null)[]; // 期间有弹窗会被主动关掉
retry?: number; // 重试次数
whileTimes?: number; // 确认次数
landOver?: (() => any)[]; // 确认是否到达目的页
auxAction?: ((makeSure: T) => void)[]; // 辅助操作 使用这个参数 必须要传landOver
}
/**
* @description:
* @param {string} name
* @param {() => UiObject | null} mainFn
* @param {MakeSureOptions} options
* @return {T | null}
* @example:
* withMakeSure('弹窗里立即领取', () => clickForce(.findOne(500)), {
* landOver: [
* () => .findOne(500),
* () => isNextElement(, , 'com.lynx.tasm.behavior.ui.text.FlattenUIText')
* ] // 确认是否到达目的页
* });
*/
export function withMakeSure<T>(name: string, mainFn: () => T, options: MakeSureOptions<T>) {
const { hasModal, landOver, auxAction, retry = 3, whileTimes = 5 } = options;
if (auxAction && !landOver) throw new Error('auxAction 必须与 landOver 一起使用');
let result: boolean | T = false;
let forNum = 0;
for (let i = 0; i < retry; i++) {
result = fn() || true;
const res = mainFn();
result = res || true;
console.log(name, 'fn:', result);
console.log(name);
let whileNum = 0;
let ok = false;
@ -138,6 +201,18 @@ export function withMakeSure<T>(
} else {
ok = true;
}
if (!ok && auxAction) {
for (let i = 0; i < auxAction.length; i++) {
const action = auxAction[i];
action(res);
sleep(500);
ok = landOver!.every((fn) => !!fn());
if (ok) {
break;
}
}
}
whileNum++;
sleep(500);
}

Loading…
Cancel
Save