ios-hooks/AppRunMan/server/MyScriptTask.m
2025-11-03 09:30:59 +08:00

623 lines
18 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// MyScriptTask.m
// nochange
//
// Created by mac on 2024/7/23.
//
#import "MyScriptTask.h"
#import "XSHelper.h"
#import "XSPhoneConfig.h"
#import "XSPhoneInfo.h"
#import "MyEventBus.h"
#import "XSHackIos.h"
#define total_ad_click 3
@interface MyScriptTask()
{
@private
// 单次app任务
NSString* _taskId;
NSString* _appId;
BOOL _lastAppTaskComplete;
NSTimeInterval _lastAppTaskTime;
NSTimeInterval _lastOcrTime;
int _lastAppTaskCount;
int _total;
BOOL _stop;
int _taskTimeout;
int _workType;
BOOL _lastTaskComplete; // 一个点击任务是否完成,按钮点击,广告展示,广告点击,广告回到页面
NSTimeInterval _lastTaskTime;
int _step; // 0 等待点击 1: 点击完成2: 点击广告3广告点击完成
int _adTouchBefore;
int _count;
int _safeTop;
NSMutableDictionary *_adShows;
NSString *_idfa;
CGFloat device_screen_width;
CGFloat device_screen_height;
int _loadCount;
}
@property (nonatomic, strong) NSMutableArray *inStack;
@property (nonatomic, strong) NSMutableArray *outStack;
@property (nonatomic, strong) dispatch_queue_t concurrentQueue;
@end
@implementation MyScriptTask
- (instancetype)init {
self = [super init];
if (self) {
_currentId = 0;
_concurrentQueue = dispatch_queue_create("com.xyzshell.adtask.queue", DISPATCH_QUEUE_CONCURRENT);
_inStack = [NSMutableArray array];
_outStack = [NSMutableArray array];
_adShows = [[NSMutableDictionary alloc] init];
_taskTimeout = 30;
_workType = 1;
_lastTaskComplete = YES;
_stop = NO;
_total = 0;
_count = 0;
_lastAppTaskComplete = YES;
_lastAppTaskTime = [self getCurTime];
_lastAppTaskCount = 0;
_safeTop = 20;
_adTouchBefore = 3;
_taskId = @"0";
_appId = @"";
_loadCount = 0;
_lastOcrTime = [self getCurTime];
NSLog(@"OhNo Server Start %@", [[XSPhoneConfig sharedInstance] IPhoneName]);
CGFloat screen_scale = [[UIScreen mainScreen] scale];
self->device_screen_width = [UIScreen mainScreen].bounds.size.width * screen_scale;
self->device_screen_height = [UIScreen mainScreen].bounds.size.height * screen_scale;
}
return self;
}
- (void) showStatus: (NSString *)data {
[[MyEventBus sharedInstance] postEvent:@"UpdateStatus" withObject:data];
}
- (void) start {
_stop = NO;
[self runStartApp];
}
- (void) stop {
_stop = YES;
}
- (int64_t)nextId {
@synchronized (self) {
self.currentId++;
return self.currentId;
}
}
- (int)enqueue:(id)item {
int load = 0;
dispatch_barrier_async(self.concurrentQueue, ^{
NSDictionary *dic = item;
NSLog(@"-ad log- add task:\n %@", dic);
NSMutableDictionary *taskDic = [[NSMutableDictionary alloc] initWithDictionary:dic];
[taskDic setValue:@([self nextId]) forKey:@"_id"];
[self->_adShows setValue: dic[@"ad_time"] forKey:dic[@"adId"]];
self ->_adTouchBefore = [dic[@"ad_touchBeforeMs"] intValue];
[self.inStack addObject:taskDic];
self->_count++;
[self showStatus:[NSString stringWithFormat: @"队列任务数量:%d, loads:%@", self->_count, dic[@"ad_loads"]]];
});
return load;
}
- (id)dequeue {
__block id result = nil;
dispatch_barrier_sync(self.concurrentQueue, ^{
if ([self.outStack count] == 0) {
NSUInteger count = [self.inStack count];
while (count > 0) {
[self.outStack addObject:[self.inStack lastObject]];
[self.inStack removeLastObject];
count--;
}
}
if ([self.outStack count] > 0) {
result = [self.outStack lastObject];
[self.outStack removeLastObject];
}
});
return result;
}
- (void) reset {
_lastTaskComplete = YES;
_lastTaskTime = [self getCurTime];
}
- (BOOL) isRun {
return !_stop;;
}
- (void) run {
dispatch_queue_t queue = dispatch_get_global_queue(0,0);
dispatch_async(queue, ^{
self.timer = [NSTimer timerWithTimeInterval:2 target:self selector:@selector(proc) userInfo:nil repeats:YES];
//timer 加入runloop
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
//开启runloop
[[NSRunLoop currentRunLoop] run];
});
}
- (void) completeTask {
_lastTaskComplete = YES;
_lastTaskTime = [self getCurTime];
_lastAppTaskCount++;
}
- (void) adClosed: (ScriptTask *)task {
[self showStatus:[NSString stringWithFormat:@"关闭:%@", task->adId]];
[self completeTask];
}
- (void) loadIncrCount {
self->_loadCount = self->_loadCount + 1;
}
-(void) restart {
dispatch_barrier_sync(self.concurrentQueue, ^{
_loadCount = 0;
_lastTaskComplete = YES;
_lastTaskTime = [self getCurTime];
_lastAppTaskComplete = YES;
_lastAppTaskTime = [self getCurTime];
_lastAppTaskCount = 0;
[self.outStack removeAllObjects];
[self.inStack removeAllObjects];
[_adShows removeAllObjects];
_count = 0;
});
}
- (void) killApp: (NSString *)pkgName {
XSKillAppByName(pkgName);
}
- (void) runStartApp {
[self restart];
NSLog(@"-ad log- runStartApp");
getChangeInfo(_idfa, ^(NSDictionary *dic) {
if (!dic || [dic isEqual: [NSNull null]]) {
NSLog(@"get change info dic is null");
return;
}
NSDictionary *workInfo = dic[@"workerInfo"];
if (!workInfo || [workInfo isEqual:[NSNull null]]) {
NSLog(@"-ad log- not have task");
return;
}
NSNumber *workType = workInfo[@"workType"];
self->_workType = [workType intValue];
if (self->_workType <= -1) {
NSLog(@"-ad log- not have task");
return;
}
self->_taskId = dic[@"id"];
self->_idfa = dic[@"idfa"];
saveChangeDataFile(dic);
// NSNumber *taskTimeout = workInfo[@"taskTimeout"];
self->_appId = dic[@"appId"];
NSLog(@"-ad log- change %@", self->_appId);
NSDictionary *safeAreaInsets = dic[@"safeAreaInsets"];
if (safeAreaInsets) {
NSString *top = safeAreaInsets[@"top"];
if (top) {
self->_safeTop = [top intValue];
}
}
// 获取任务,开始启动
//ScriptTask oldtask = {
// .appId = self->_appId
//};
[self killApp:self->_appId];
// [self runStopScript:&oldtask];
// 获取任务,开始启动
//ScriptTask task = {
// .appId = self->_appId,
//};
dispatch_async(dispatch_get_main_queue(), ^{
XSRemoteUnlock();
usleep(5000);
XSRemoteUnlock();
});
//[self runSystemRestartScript];
// TODO: 备份数据
NSString *appInfoPath = XSGetAppInfoPath(self->_appId);
NSDictionary *appInfo = XSGetAppInfo(appInfoPath);
XSClearAll(self->_appId);
XSSaveAppInfo(appInfo, appInfoPath);
[[UIApplication sharedApplication] performSelectorOnMainThread:@selector(beginIgnoringInteractionEvents) withObject:nil waitUntilDone:YES];
[[UIApplication sharedApplication] performSelectorOnMainThread:@selector(endIgnoringInteractionEvents) withObject:nil waitUntilDone:YES];
//[self runStartScript:&task];
XSBringAppForeground(self->_appId);
}, ^(NSError *err) {
});
}
- (void) proc {
@try {
[self _proc];
} @catch (NSException *exception) {
NSLog(@"-ad- erro");
}
}
- (void) _proc {
if (_stop) {
return;
}
NSLog(@"start proc task........");
if (_workType < 1) {
if (_count > 1 && ([self getCurTime] - _lastAppTaskTime) > 6) {
[self runStartApp];
} else if (([self getCurTime] - _lastAppTaskTime) > 20){
[self runStartApp];
}
return;
}
if (_workType == 4) {
if (_lastTaskComplete == YES) {
_lastTaskComplete = NO;
_lastTaskTime = [self getCurTime];
ScriptTask sctask = {
.idfa = _idfa,
.appId = _appId,
.ad = true,
.adId = @""
};
AdTaskLogData logData = {
.title = @"广告展示",
.idfa = _idfa,
.appid = _appId,
.adid = @"",
.message = @"",
.level = 1,
.ecpm = @(0)
};
self->_adTouchBefore = 10000;
[[MyScriptTask sharedInstance] saveAdTaskLog:&logData];
[[MyScriptTask sharedInstance] runAdTouchScript:&sctask];
return;
} else {
if (([self getCurTime] - _lastTaskTime) > 18) {
[self runStartApp];
return;
}
}
}
if (self->_loadCount > 0) {
if (_lastAppTaskCount >= self->_loadCount) {
sleep(2);
[self runStartApp];
return;
}
}
if (([self getCurTime] - _lastAppTaskTime) > 80) {
[self runStartApp];
return;
}
if (_lastTaskComplete == NO) {
// 上次任务没有执行完30秒不等待继续下一个任务
if (_lastTaskTime && ([self getCurTime] - _lastTaskTime) < _taskTimeout) {
NSLog(@"last task running");
return;
}
}
@try {
id task = [self dequeue];
if (task) {
_lastTaskComplete = NO;
if (_lastAppTaskComplete == YES) {
_lastAppTaskComplete = NO;
}
// 处理任务
_lastTaskTime = [self getCurTime];
NSMutableDictionary *taskData = task;
NSLog(@"pad roc task: \n%@", taskData);
NSString *type = taskData[@"type"];
if ([type isEqual:@"click_btn"]) {
NSLog(@"ad proc task: click_btn - begin");
[self showStatus:[NSString stringWithFormat:@"点击:%@", taskData[@"adId"]]];
NSNumber *x = taskData[@"x"];
NSNumber *y = taskData[@"y"];
FixedPoint point = {
.x = [x intValue],
.y = [y intValue]
};
ScriptTask st = { .btnLoc = &point, .appId=_appId };
[self runAdShowScript:&st];
}
} else {
if (_lastTaskTime && ([self getCurTime] - _lastTaskTime) > 20) {
[self runStartApp];
return;
}
}
}
@catch (NSException *exception) {
NSLog(@"ad proc ex name: %@", exception.name);
NSLog(@"ad proc ex reason: %@", exception.reason);
[self completeTask];
}
@finally {
NSLog(@"ad proc end");
}
}
- (BOOL) replaceScript: (NSString *)tplName scriptName: (NSString *)scriptName callback: (ScriptReplaceCallback)callback {
NSString *scriptTpl = [self readScript:tplName];
if (scriptTpl == nil) {
NSLog(@"ad read script is nil");
return NO;
}
NSLog(@"ad tpl script: %@", tplName);
NSMutableString *newScript = [NSMutableString stringWithString:scriptTpl];
callback(newScript);
// NSLog(@"ad new script: %@", newScript);
return [self saveScript:[newScript copy] name:scriptName];
}
- (void) runAdShowScript: (ScriptTask *) taskData {
// 1. 写入按钮点击脚本
NSLog(@"ad runAdShowScript");
NSString *curApp = XSFrontMostAppId();
if(![self->_appId isEqual:curApp]) {
XSBringAppForeground(self->_appId);
sleep(2);
}
usleep(5000);
int x = taskData->btnLoc->x * 2;
int y = taskData->btnLoc->y;
int ny = y * 2 + (self->_safeTop / 2) - 10;
/*
BOOL flag = [self replaceScript:SCRIPT_TOUCH_BTN_TPL scriptName:SCRIPT_TOUCH_BTN callback:^(NSMutableString *newScript) {
[MyHelper replaceMulStr:newScript oldStr:@"local btn_x = __BTN_X__" newStr:[NSString stringWithFormat:@"local btn_x = %d", x]];
[MyHelper replaceMulStr:newScript oldStr:@"local btn_y = __BTN_Y__" newStr:[NSString stringWithFormat:@"local btn_y = %d", ny]];
[MyHelper replaceMulStr:newScript oldStr:@"__APPID__" newStr:taskData->appId];
}];
// 2. 运行脚本
if (flag) {
NSLog(@"save script ok: %@", SCRIPT_TOUCH_BTN);
NSString *res = [self runScript:SCRIPT_TOUCH_BTN];
if (res) {
NSLog(@"ad run script success: %@", SCRIPT_TOUCH_BTN);
[self showStatus:[NSString stringWithFormat:@"运行点击按钮成功,%@",res]];
} else {
[self showStatus:[NSString stringWithFormat:@"运行点击按钮失败,%@",res]];
}
} else {
NSLog(@"save script error: %@", SCRIPT_TOUCH_BTN);
[self showStatus:@"保存按钮点击脚本失败"];
}
//*/
}
- (void) runStopScript: (ScriptTask *) taskData {
BOOL flag = [self replaceScript:SCRIPT_KILL_ALL_TPL scriptName:SCRIPT_KILL_ALL callback:^(NSMutableString *newScript) {
[XSHelper replaceMulStr:newScript oldStr:@"__APPID__" newStr:taskData->appId];
}];
if (flag) {
// 结束所有相关app
NSString *res = [self runScript:SCRIPT_KILL_ALL];
if (res) {
NSLog(@"-ad -log %@",res);
}
}
}
- (int) runAdTouchScript: (ScriptTask *) taskData {
if (!taskData->ad) {
// 没有广告展示
NSLog(@"-ad log- touch btn No ad");
[self completeTask];
[self showStatus: [NSString stringWithFormat:@"广告展示失败:%@", taskData->adId]];
return 0;
}
_lastTaskTime = [self getCurTime];
/*
NSLog(@"-ad log- run ad touch script: %@", SCRIPT_TOUCH_AD);
BOOL flag = [self replaceScript:SCRIPT_TOUCH_AD_TPL scriptName:SCRIPT_TOUCH_AD callback:^(NSMutableString *newScript) {
[MyHelper replaceMulStr:newScript oldStr:@"__APPID__" newStr:taskData->appId];
[MyHelper replaceMulStr:newScript oldStr:@"__BEFORE__" newStr:[NSString stringWithFormat:@"%d", self->_adTouchBefore]];
}];
if (flag) {
NSString *res = [self runScript:SCRIPT_TOUCH_AD];
if (res) {
NSLog(@"sc res: %@", res);
}
}
*/
[self runTouchAdJs:self->_adTouchBefore];
int show_ms = 5000;
if ([_adShows objectForKey:taskData->adId]) {
NSNumber *shows = _adShows[taskData->adId];
show_ms = [shows intValue];
}
[self showStatus: [NSString stringWithFormat:@"广告展,%@", taskData->adId]];
// 点击广告
return show_ms;
}
- (void) runStartScript: (ScriptTask *) taskData {
// 启动app 开始任务
// 清除队列里面所有任务, 重置状态
[self showStatus:@"start new task"];
_lastTaskTime = [self getCurTime];
BOOL flag = [self replaceScript:SCRIPT_START_TPL scriptName:SCRIPT_START callback:^(NSMutableString *newScript) {
[XSHelper replaceMulStr:newScript oldStr:@"__APPID__" newStr:taskData->appId];
}];
if (flag) {
NSString *res = [self runScript:SCRIPT_START];
if (res) {
NSLog(@"-ad- start task%@", res);
}
}
}
- (void) runSystemRestartScript {
NSString *res = [self runScript:@"close_not_now.lua"];
if (res) {
NSLog(@"kill a all");
}
}
- (NSString *) runScript: (NSString *)script {
/*
NSString *url = [NSString stringWithFormat:@"http://127.0.0.1:8080/control/start_playing?path=/%@", script];
[XSHelper doGET:url withCallback:^(NSData* _data) {
if (_data) {
NSString *res = [MyHelper data2str:_data];
[self showStatus:[NSString stringWithFormat: @"运行脚本成功,%@", res]];
}
} withError:^(NSError *err) {
NSLog(@"run autouch script error");
}];
NSLog(@"run autouch script error");
*/
return nil;
}
- (NSString *) stopScript: (NSString *)script {
/*
NSString *url = [NSString stringWithFormat:@"http://127.0.0.1:8080/control/stop_playing?path=/%@", script];
[_http doGET:url callback:^(NSData* _data) {
if (_data) {
NSString *res = [MyHelper data2str:_data];
[self showStatus:[NSString stringWithFormat: @"停止脚本成功,%@", res]];
}
}];
NSLog(@"run autouch script error");
*/
return nil;
}
- (NSString *) readScript: (NSString *)name {
NSString *scriptPath = [self getScriptPath:name];
return [XSHelper readFileText:scriptPath];
}
- (BOOL) saveScript: (NSString *)script name:(NSString *)name {
NSString *scriptPath = [self getScriptPath:name];
return [XSHelper saveFile:scriptPath text:script];
}
- (NSString *) getScriptPath: (NSString *) name {
return [NSString stringWithFormat:@"/var/mobile/Library/AutoTouch/Scripts/%@", name];
}
- (NSTimeInterval) getCurTime {
// 获取当前日期和时间
NSDate *now = [NSDate date];
return [now timeIntervalSince1970];
}
- (void) logServer: (NSString *) info title: (NSString *)title {
}
- (void) saveAdTaskLog: (AdTaskLogData *)data {
data->taskId = _taskId;
data->iphoneId = [[XSPhoneConfig sharedInstance] IPhoneName];
data->ipAddr = [[XSPhoneInfo sharedInstance] IPAddress];
pushAdTaskLog(data);
}
- (NSString*) statusStr {
NSString *runStatusStr = _stop ? @"已停止": @"运行中";
return [NSString stringWithFormat:@"%@", runStatusStr];
}
- (NSString*) appid {
return _appId;
}
- (void) runTouchAdJs: (NSInteger) befor {
/*
JsRunner *runner = [[JsRunner alloc] init];
NSString *tmpCode = @"var beforeTouch = %@;"
"var cur_app_id = \"%@\";"
"var screen_w = %@;"
"var screen_h = %@;";
NSString *code = [NSString stringWithFormat:tmpCode, @(befor / 1000), [self appid], @(self->device_screen_width), @(self->device_screen_height)];
NSLog(@"runTouchAdJs:%@", code);
[runner runCode:code];
[runner runJS:@"/var/mobile/Library/AutoTouch/Scripts/touch_ad.js" timeout:50 completion:^(JSValue *result, BOOL timedOut) {
NSLog(@"runTouchAdJs end");
}];
*/
}
+(instancetype)sharedInstance
{
static MyScriptTask* _sharedInstance = nil;
static dispatch_once_t oncePredicate;
dispatch_once (&oncePredicate, ^{
_sharedInstance = [[MyScriptTask alloc] init];
});
return _sharedInstance;
}
@end