#include "XUDPServer.h" #import #import "IPhoneHertbeat.h" #import "XSHackIos.h" #import "XSHelper.h" #import "XSPhoneInfo.h" #import "XSPhoneConfig.h" #import "MyAdServer.h" #import "MyAdTask2.h" #import "MyEventBus.h" BOOL myadTaskManualStop = NO; @interface MyAdTask2Mangger() { @private BOOL running; dispatch_source_t _timer; NSDate *lastRun; NSDate *lastGetCountry; NSString *_lastIdfa; NSString *taskId; NSString *taskAppId; int workType; int screen_w; int screen_h; int adAfter; NSString *linkId; NSString *dataId; NSString *remoteIp; NSString *country; } @property (nonatomic, assign) NSTimeInterval lastAppSwitchTime; // 新增属性 @end @implementation MyAdTask2Mangger +(instancetype)sharedInstance { static MyAdTask2Mangger* _sharedInstance = nil; static dispatch_once_t oncePredicate; dispatch_once(&oncePredicate, ^{ _sharedInstance = [[MyAdTask2Mangger alloc] init]; }); return _sharedInstance; } -(instancetype)init { if (self = [super init]) { self->running = NO; self->_lastIdfa = @""; self.manQueue = dispatch_queue_create("com.xyzshell.myadtask", DISPATCH_QUEUE_SERIAL); CGFloat screen_scale = [[UIScreen mainScreen] scale]; CGFloat device_screen_width = [UIScreen mainScreen].bounds.size.width * screen_scale; CGFloat device_screen_height = [UIScreen mainScreen].bounds.size.height * screen_scale; self->screen_w = device_screen_width; self->screen_h = device_screen_height; self->adAfter = 1000; self.lastAppSwitchTime = 0; // 初始化为0 return self; } return nil; } - (int)onShow:(NSDictionary *)dic { if(dic == nil || [dic isEqual:[NSNull null]] || [dic count] <= 0) { return 4000; } NSString *t_appid = [self getStr:@"appid" dic:dic]; NSString *t_idfa = [self getStr:@"idfa" dic:dic]; NSString *t_adId = [self getStr:@"id" dic:dic]; NSNumber *t_ecpm = [self getNum:@"ecpm" dic:dic]; BOOL ad = dic[@"ad"]; NSString *iphoneId = [[XSPhoneConfig sharedInstance] IPhoneName]; if(!ad) { NSLog(@"XS- no ad show"); return 0; } int close = 4000; AdLoadInfo adloadInfo = getAdLoadInfo(@{ @"idfa": t_idfa ?: @"", @"adId": t_adId ?: @"", @"ecpm": [NSString stringWithFormat:@"%@", t_ecpm], @"appId": t_appid ?: @"", @"deviceId":iphoneId ?: @"" }); close = [adloadInfo.adTime intValue]; int before = [adloadInfo.adTouchBeforeMs intValue]; if (before >= close) { before = 1000; } int after = [adloadInfo.adTouchAfterMs intValue]; if(after > 1000) { self->adAfter = after; } else { self->adAfter = 1000; } NSInteger random1 = arc4random_uniform(101); NSInteger tr = [adloadInfo.touchRate intValue]; if (tr > random1) { double beforeSec = before / 1000.0; __weak typeof(self) weakSelf = self; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(beforeSec * NSEC_PER_SEC)), self.manQueue, ^{ [weakSelf touchAppTask:0]; }); } return close; } - (void)showStatus:(NSString *)data { [[MyEventBus sharedInstance] postEvent:@"UpdateStatus" withObject:data]; } - (void)setRemoteInfo { NSString *url = @"https://ipapi.co/json/"; XSHttpHelper *http = [[XSHttpHelper alloc] init]; __weak typeof(self) weakSelf = self; [http doGET:url withCallback:^(NSData *data) { if(!data) { NSLog(@"!setRemoteInfo 1data"); [weakSelf showStatus:@"!setRemoteInfo 1data"]; return; } NSDictionary *dic = [XSHelper jsonData2Dictionary:data]; if (!dic) { NSLog(@"!setRemoteInfo dic"); [weakSelf showStatus:@"!setRemoteInfo dic"]; return; } NSString *isoCode = dic[@"country_code"]; NSString *ip = dic[@"ip"]; __strong typeof(weakSelf) strongSelf = weakSelf; if (!strongSelf) return; strongSelf->remoteIp = [ip copy]; strongSelf->country = [isoCode copy]; [XSPhoneInfo sharedInstance].remoteIp = [NSString stringWithFormat:@"%@:%@", isoCode, ip]; [weakSelf showStatus:[XSPhoneInfo sharedInstance].remoteIp]; } withError:^(NSError *err) { NSLog(@"!setRemoteInfo err:%@",err); [weakSelf showStatus:[NSString stringWithFormat:@"%@", err.description]]; }]; } - (void)setRemoteInfo1 { NSString *url = [[XSPhoneConfig sharedInstance] GetRemoteIPURL]; [self showStatus:url]; if (!url) { NSLog(@"!setRemoteInfo url"); return; } __weak typeof(self) weakSelf = self; XSHttpHelper *http = [[XSHttpHelper alloc] init]; [http doGET:url withCallback:^(NSData *data) { if(!data) { NSLog(@"!setRemoteInfo 1data"); [weakSelf showStatus:@"!setRemoteInfo 1data"]; return; } NSDictionary *dic = [XSHelper jsonData2Dictionary:data]; if (!dic) { NSLog(@"!setRemoteInfo dic"); [weakSelf showStatus:@"!setRemoteInfo dic"]; return; } NSDictionary *_data = dic[@"data"]; if(!_data) { NSLog(@"!setRemoteInfo data"); [weakSelf showStatus:@"!setRemoteInfo data"]; return; } NSString *isoCode = _data[@"isoCode"]; NSString *ip = _data[@"ip"]; NSLog(@"setRemoteInfo:%@", _data); __strong typeof(weakSelf) strongSelf = weakSelf; if (!strongSelf) return; strongSelf->remoteIp = [ip copy]; strongSelf->country = [isoCode copy]; [XSPhoneInfo sharedInstance].remoteIp = [NSString stringWithFormat:@"%@:%@", isoCode, ip]; [weakSelf showStatus:[XSPhoneInfo sharedInstance].remoteIp]; } withError:^(NSError *err) { NSLog(@"!setRemoteInfo err:%@",err); [weakSelf showStatus:[NSString stringWithFormat:@"%@", err.description]]; }]; } - (BOOL)onEnd:(NSDictionary *)dic { NSNumber *maxEcpm = dic[@"max_ecpm"]; int sec = self->adAfter / 1000; __weak typeof(self) weakSelf = self; if([maxEcpm doubleValue] <= 0.0) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, sec * NSEC_PER_SEC), self.manQueue, ^{ @autoreleasepool { [weakSelf startApp]; } }); return NO; } BOOL res = needAdContinue(self->taskAppId, self->_lastIdfa, maxEcpm); if(res) { return YES; } dispatch_after(dispatch_time(DISPATCH_TIME_NOW, sec * NSEC_PER_SEC), self.manQueue, ^{ @autoreleasepool { [weakSelf startApp]; } }); return NO; } - (void)startApp { @autoreleasepool { if(!self->running){ return; } self->lastRun = [NSDate date]; if (self->country == nil || [self->country isEqual:NULL] || [self->country isEqual:@""]) { [self setRemoteInfo]; self->lastGetCountry = [NSDate date]; } else { NSDate *curRunTime = [NSDate date]; NSTimeInterval elapsed = [curRunTime timeIntervalSinceDate:self->lastGetCountry]; if (elapsed >= 300) { [self setRemoteInfo]; self->lastGetCountry = [NSDate date]; } } __weak typeof(self) weakSelf = self; getChangeInfo(self->_lastIdfa, ^(NSDictionary *dic) { dispatch_async(weakSelf.manQueue, ^{ [weakSelf onChangeInfo:dic]; }); }, ^(NSError *err) { NSLog(@"XS- startTask NSError is null, %@", err); }); } } - (void)start { self->running = YES; myadTaskManualStop = NO; [[IPhoneHertbeat sharedInstance] setStatus:@"运行中"]; [self startApp]; __weak typeof(self) weakSelf = self; // 确保Timer在重新启动前被取消 if (_timer) { dispatch_source_cancel(_timer); _timer = nil; } // 使用 dispatch_source 创建timer _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.manQueue); dispatch_source_set_timer(_timer, dispatch_time(DISPATCH_TIME_NOW, 0), 10 * NSEC_PER_SEC, 1 * NSEC_PER_SEC); dispatch_source_set_event_handler(_timer, ^{ @autoreleasepool { [weakSelf proc]; } }); dispatch_resume(_timer); [[MyEventBus sharedInstance] postEvent:@"UpdateRunStatus" withObject:@(YES)]; } - (void)proc { if (!self->running) { return; } NSLog(@"XS- MyAdTaskManager proc"); NSDate* curRunTime = [NSDate date]; NSTimeInterval elapsed = [curRunTime timeIntervalSinceDate:self->lastRun]; if (elapsed >= 30) { //[self onStop]; [self start]; } else { NSString* appId = [ self frontMostAppId]; if (![appId isEqual: self->taskAppId]) { // 引入冷却时间,避免频繁切换应用 NSTimeInterval currentTime = [NSDate timeIntervalSinceReferenceDate]; if (currentTime - self.lastAppSwitchTime < 30) { // 30秒冷却时间 NSLog(@"XS- App switching throttled. Last switch was %.0f seconds ago.", currentTime - self.lastAppSwitchTime); return; } [self appKill:appId]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), self.manQueue, ^{ [self appRun:self->taskAppId]; self.lastAppSwitchTime = [NSDate timeIntervalSinceReferenceDate]; // 更新切换时间 }); } } } - (NSString *)toggle { if(self->running) { [self stop]; } else { [self start]; } return [IPhoneHertbeat sharedInstance].status; } - (void)stop { myadTaskManualStop = YES; self->running = NO; [IPhoneHertbeat sharedInstance].status = @"已停止"; if (_timer) { dispatch_source_cancel(_timer); _timer = nil; } [[MyEventBus sharedInstance] postEvent:@"UpdateRunStatus" withObject:@(NO)]; } - (void)onChangeInfo:(NSDictionary *)dic { NSString* t_idfa = [self getStr:@"idfa" dic:dic]; if (![XSHelper strIsEmpty:t_idfa]) { self->_lastIdfa = [t_idfa copy]; } else { NSLog(@"XS- startTask t_idfa is null"); return; } NSString *_linkId = [self getStr:@"linkId" dic:dic]; if (![XSHelper strIsEmpty:_linkId]) { self->linkId = [_linkId copy]; } NSString *_dataId = [self getStr:@"dataId" dic:dic]; if (![XSHelper strIsEmpty:_dataId]) { self->dataId = [_dataId copy]; } NSString* t_taskId = [self getStr:@"id" dic:dic]; if (![XSHelper strIsEmpty:t_taskId]) { self->taskId = [t_taskId copy]; } else { NSLog(@"XS- startTask t_taskId is null"); return; } NSString* t_taskAppId = [self getStr:@"appId" dic:dic]; if (![XSHelper strIsEmpty:t_taskAppId]) { self->taskAppId = [t_taskAppId copy]; [IPhoneHertbeat sharedInstance].appId = self->taskAppId; } else { NSLog(@"XS- startTask t_taskAppId is null"); return; } NSDictionary *workerInfo = dic[@"workerInfo"]; if(workerInfo && ![workerInfo isEqual:[NSNull null]]) { } else { NSLog(@"XS- startTask workerInfo is null"); return; } int t_workType = [self getInt:@"workType" dic:workerInfo]; if (t_workType > -99) { self->workType = t_workType; } else { NSLog(@"XS- startTask workType is null"); } __weak typeof(self) weakSelf = self; [self restart:^{ __strong typeof(weakSelf) strongSelf = weakSelf; if (!strongSelf) return; saveChangeDataFile(dic); strongSelf->running = YES; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), strongSelf.manQueue, ^{ __strong typeof(weakSelf) strongSelf2 = weakSelf; if (!strongSelf2) return; [strongSelf2 appRun:strongSelf2->taskAppId]; }); }]; } - (void)appKill:(NSString*)app { NSLog(@"XS- appKill"); XSKillAppByName(app); } - (void)unlock { NSLog(@"XS- unlock"); dispatch_async(dispatch_get_main_queue(), ^{ XSRemoteUnlock(); }); } - (void)resetApp:(NSString*)appId callback:(OnEndCallback)callback { NSLog(@"XS- JSApi resetApp"); NSString *appInfoPath = XSGetAppInfoPath(appId); NSDictionary *appInfo = XSGetAppInfo(appInfoPath); id bfaceDictKey = appInfo[@"bfaceDictKey"]; NSMutableDictionary *tempBfaceDictKey = nil; if(bfaceDictKey) { tempBfaceDictKey = [NSMutableDictionary dictionaryWithDictionary:bfaceDictKey]; } else { tempBfaceDictKey = [[NSMutableDictionary alloc] init]; } NSString *serverUrl = [[XSPhoneConfig sharedInstance] ServerURL]; [tempBfaceDictKey setValue:@"http://127.0.0.1:6000" forKey:@"adbrush_local_url"]; [tempBfaceDictKey setValue:serverUrl forKey:@"adbrush_base_url"]; __weak typeof(self) weakSelf = self; getLowEcpm(^(NSNumber *lowEcpm) { __strong typeof(weakSelf) strongSelf = weakSelf; if (!strongSelf) return; BOOL washParam = strongSelf->workType == 0 ? YES : NO; [tempBfaceDictKey setValue:@(washParam) forKey:@"washParam"]; [tempBfaceDictKey setValue:lowEcpm forKey:@"adbrush_ecpm"]; if(strongSelf->linkId) { [tempBfaceDictKey setValue:strongSelf->linkId forKey:@"linkId"]; } else { NSString *linkId = [[NSUUID UUID] UUIDString]; [tempBfaceDictKey setValue:linkId forKey:@"linkId"]; } if(strongSelf->dataId) { [tempBfaceDictKey setValue:strongSelf->dataId forKey:@"dataId"]; } else { NSString *dataId = @"0"; [tempBfaceDictKey setValue:dataId forKey:@"dataId"]; } if(strongSelf->remoteIp) { [tempBfaceDictKey setValue:strongSelf->remoteIp forKey:@"remoteIp"]; } uint16_t udp_port = [XUDPServer sharedInstance].udp_port; [tempBfaceDictKey setValue:@(udp_port) forKey:@"udp_port"]; NSLog(@"XS- resetApp 1"); NSMutableDictionary *tempAppInfo = [[NSMutableDictionary alloc] init]; [tempAppInfo setValue:tempBfaceDictKey forKey:@"bfaceDictKey"]; XSClearAll(appId); XSSaveAppInfo(tempAppInfo, appInfoPath); callback(); }); } - (NSString *)frontMostAppId { return XSFrontMostAppId(); } - (void)appRun:(NSString *)appId { if ([XSHelper strIsEmpty:appId]) return; dispatch_async(dispatch_get_main_queue(), ^{ @try { bringAppToForeground(appId); } @catch (NSException *exception) { NSLog(@"Error bringing app to foreground: %@", exception); } }); } - (void)tap:(int)i x:(int)x y:(int)y { } - (void)restart:(OnEndCallback)callback { __weak typeof(self) weakSelf = self; dispatch_async(self.manQueue, ^{ @try { __strong typeof(weakSelf) strongSelf = weakSelf; if (!strongSelf) return; [weakSelf appKill:@"com.apple.AppStore"]; [weakSelf appKill:@"com.apple.mobilesafari"]; if (strongSelf->taskAppId && ![strongSelf->taskAppId isEqual:[NSNull null]] && [strongSelf->taskAppId length] > 0) { [weakSelf appKill:strongSelf->taskAppId]; [weakSelf unlock]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), strongSelf.manQueue, ^{ [weakSelf unlock]; [weakSelf resetApp:strongSelf->taskAppId callback:callback]; }); } } @catch (NSException *exception) { NSLog(@"Error in restart: %@", exception); } }); } - (void)rndTouchApp { int times = [XSHelper random:2 and:4]; [self _rndTouchAppRecursive:0 totalTimes:times]; } - (void)_rndTouchAppRecursive:(int)currentIndex totalTimes:(int)times { if (currentIndex >= times) { return; } int x = [XSHelper random:40 and:screen_w - 20]; int y = [XSHelper random:50 and:screen_h - 240]; NSString* appId = [self frontMostAppId]; if ([appId isEqual:self->taskAppId]) { [self tap:1 x:x y:y]; __weak typeof(self) weakSelf = self; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.002 * NSEC_PER_SEC)), self.manQueue, ^{ [weakSelf _rndTouchAppRecursive:currentIndex + 1 totalTimes:times]; }); } } - (void)touchAppTask:(int)beforeTouch { __weak typeof(self) weakSelf = self; if (beforeTouch > 0) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(beforeTouch * NSEC_PER_SEC)), self.manQueue, ^{ [self rndTouchApp]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), self.manQueue, ^{ int x = [XSHelper random:40 and:screen_w - 20]; int y = [XSHelper random:50 and:screen_h - 240]; [self tap:1 x:x y:y]; NSString* appId = [ self frontMostAppId]; if (![appId isEqual: self->taskAppId]) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), self.manQueue, ^{ [self appRun:self->taskAppId]; }); } else { [self appRun:self->taskAppId]; } }); }); } else { [self rndTouchApp]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), self.manQueue, ^{ int x = [XSHelper random:40 and:screen_w - 20]; int y = [XSHelper random:50 and:screen_h - 240]; [self tap:1 x:x y:y]; NSString* appId = [ self frontMostAppId]; if (![appId isEqual: self->taskAppId]) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), self.manQueue, ^{ [self appRun:self->taskAppId]; }); } else { [self appRun:self->taskAppId]; } }); } } - (NSString*)getStr:(NSString *)key dic:(NSDictionary*)dic { NSLog(@"getStr: %@", key); id t_idfa = dic[key]; if (t_idfa && ![t_idfa isEqual:[NSNull null]] && ![t_idfa isEqual:@""]) { return [NSString stringWithFormat:@"%@", t_idfa]; } else { NSLog(@"XS- dic %@ is null", key); return @""; } } - (NSNumber*)getNum:(NSString *)key dic:(NSDictionary*)dic { NSLog(@"getNum: %@", key); id t_idfa = dic[key]; NSString *ecpm_str = [NSString stringWithFormat:@"%@", t_idfa]; NSNumber *ecpm = @0.0; if (ecpm_str && ![ecpm_str isEqual:[NSNull null]] && ![ecpm_str isEqual:@""]) { ecpm = [XSHelper str2num:ecpm_str]; } return ecpm; } - (int)getInt:(NSString *)key dic:(NSDictionary*)dic { NSLog(@"getInt: %@", key); id t_idfa = dic[key]; NSString *ecpm_str = [NSString stringWithFormat:@"%@", t_idfa]; NSNumber *ecpm = @(-99); if (ecpm_str && ![ecpm_str isEqual:[NSNull null]] && ![ecpm_str isEqual:@""]) { ecpm = [XSHelper str2num:ecpm_str]; } return [ecpm intValue]; } - (void)dealloc { [self stop]; } @end