ios-hooks/AppRunMan/server/FloatingWindow.m
2025-12-01 17:42:45 +08:00

356 lines
13 KiB
Objective-C

//
// FloatingWindow.m
// nochange
//
// Created by mac on 2024/7/29.
//
#import "FloatingWindow.h"
#import "IPhoneHertbeat.h"
#import "MyAdTask2.h"
#import "MyEventBus.h"
#import "UIView+Toast.h"
#import "XSHelper.h"
#import "XSPhoneConfig.h"
#import "XSPhoneInfo.h"
#import <Foundation/Foundation.h>
@interface FloatingWindow () {
NSMutableArray *loadTimestamps;
NSMutableArray *showTimestamps;
NSTimer *updateTimer;
}
@end
@implementation FloatingWindow
- (instancetype)initWithFrame {
CGRect screenBounds = [UIScreen mainScreen].bounds;
CGFloat floatingWindowWidth = 180;
CGFloat floatingWindowHeight = 160;
CGFloat xPosition = 0;
CGFloat yPosition = screenBounds.size.height - floatingWindowHeight;
CGRect frame = CGRectMake(xPosition, yPosition, floatingWindowWidth,
floatingWindowHeight);
self = [super initWithFrame:frame];
if (self) {
UIPanGestureRecognizer *panRecognizer =
[[UIPanGestureRecognizer alloc] initWithTarget:self
action:@selector(detectPan:)];
[self addGestureRecognizer:panRecognizer];
self.backgroundColor = [UIColor grayColor]; // 默认灰色背景
self.layer.cornerRadius = 10;
self.clipsToBounds = YES;
[self setupUI];
[self updateInfo];
self.http = [[XSHttpHelper alloc] init];
[[MyEventBus sharedInstance] registerSubscriber:self];
loadTimestamps = [[NSMutableArray alloc] init];
showTimestamps = [[NSMutableArray alloc] init];
[self startUpdatingCounts]; // 启动定时任务
}
return self;
}
- (void)dealloc {
[[MyEventBus sharedInstance] unregisterSubscriber:self];
[self stopUpdatingCounts]; // 停止定时任务
}
// 定时任务方法
- (void)startUpdatingCounts {
updateTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:@selector(updateCounts)
userInfo:nil
repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:updateTimer forMode:NSRunLoopCommonModes];
}
// 停止定时任务
- (void)stopUpdatingCounts {
if ([updateTimer isValid]) {
[updateTimer invalidate];
updateTimer = nil;
}
}
// 更新文件夹中的文件数量
- (void)updateCounts {
NSString *loadDir = @"/User/Documents/ad/load";
NSString *showDir = @"/User/Documents/ad/show";
NSInteger loadCount = [self countAndCleanFilesInDirectory:loadDir];
NSInteger showCount = [self countAndCleanFilesInDirectory:showDir];
dispatch_async(dispatch_get_main_queue(), ^{
self.infoLabel.text = [NSString stringWithFormat:@"S:%@ / L:%@", @(showCount), @(loadCount)];
[self updateBackgroundColorByShowCount:showCount];
});
}
// 统计文件数量并删除一小时前的文件
- (NSInteger)countAndCleanFilesInDirectory:(NSString *)directoryPath {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *files = [fileManager contentsOfDirectoryAtPath:directoryPath error:nil];
NSDate *oneHourAgo = [NSDate dateWithTimeIntervalSinceNow:-3600];
NSInteger count = 0;
for (NSString *file in files) {
NSString *filePath = [directoryPath stringByAppendingPathComponent:file];
NSDictionary *attributes = [fileManager attributesOfItemAtPath:filePath error:nil];
NSDate *modificationDate = attributes[NSFileModificationDate];
if ([modificationDate compare:oneHourAgo] == NSOrderedDescending) {
count++;
} else {
[fileManager removeItemAtPath:filePath error:nil]; // 删除过期文件
}
}
return count;
}
// 添加清理过期数据的辅助方法
- (void)cleanExpiredTimestamps:(NSMutableArray *)timestamps {
NSDate *now = [NSDate date];
NSTimeInterval oneHourAgo = [now timeIntervalSince1970] - 3600; // 3600秒 = 1小时
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(NSDate *timestamp, NSDictionary *bindings) {
return [timestamp timeIntervalSince1970] > oneHourAgo;
}];
NSArray *validTimestamps = [timestamps filteredArrayUsingPredicate:predicate];
[timestamps removeAllObjects];
[timestamps addObjectsFromArray:validTimestamps];
}
// 更新背景颜色
- (void)updateBackgroundColorByShowCount:(NSInteger)showCount {
UIColor *color;
if (showCount < 80) {
// 蓝色 #07A6E4
color = [UIColor colorWithRed:7/255.0 green:166/255.0 blue:228/255.0 alpha:1.0];
} else if (showCount < 160) {
// 红色 #D92727
color = [UIColor colorWithRed:217/255.0 green:39/255.0 blue:39/255.0 alpha:1.0];
} else if (showCount < 240) {
// 橙黄 #EF811C
color = [UIColor colorWithRed:239/255.0 green:129/255.0 blue:28/255.0 alpha:1.0];
} else {
// 绿色 #08C951
color = [UIColor colorWithRed:8/255.0 green:201/255.0 blue:81/255.0 alpha:1.0];
}
dispatch_async(dispatch_get_main_queue(), ^{
self.backgroundColor = color;
});
}
// 添加 onEventLoad 方法
- (void)onEventLoad:(id)data {
@synchronized(loadTimestamps) {
[loadTimestamps addObject:[NSDate date]];
[self cleanExpiredTimestamps:loadTimestamps];
NSInteger loadCount = loadTimestamps.count;
NSInteger showCount = showTimestamps.count;
dispatch_async(dispatch_get_main_queue(), ^{
self.infoLabel.text = [NSString stringWithFormat:@"S:%@ / L:%@", @(showCount), @(loadCount)];
});
NSLog(@"Load event: total in last hour = %ld", (long)loadCount);
}
}
// 添加 onEventShow 方法
- (void)onEventShow:(id)data {
@synchronized(showTimestamps) {
[showTimestamps addObject:[NSDate date]];
[self cleanExpiredTimestamps:showTimestamps];
NSInteger showCount = showTimestamps.count;
NSInteger loadCount = loadTimestamps.count;
dispatch_async(dispatch_get_main_queue(), ^{
self.infoLabel.text = [NSString stringWithFormat:@"S:%@ / L:%@", @(showCount), @(loadCount)];
});
// 根据 show 数量更新背景颜色
[self updateBackgroundColorByShowCount:showCount];
NSLog(@"Show event: total in last hour = %ld", (long)showCount);
}
}
- (void)setupUI {
// Name Label
self.nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 180, 18)];
self.nameLabel.textColor = [UIColor whiteColor];
self.nameLabel.font = [UIFont systemFontOfSize:14.0];
[self addSubview:self.nameLabel];
// IP Label
self.ipLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 35, 180, 20)];
[self addSubview:self.ipLabel];
self.infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 55, 180, 20)];
[self addSubview:self.infoLabel];
// Device Type Label
self.deviceTypeLabel =
[[UILabel alloc] initWithFrame:CGRectMake(10, 75, 180, 30)];
self.deviceTypeLabel.textColor = [UIColor whiteColor];
self.deviceTypeLabel.numberOfLines = 0;
self.deviceTypeLabel.font = [UIFont systemFontOfSize:12.0];
[self addSubview:self.deviceTypeLabel];
// Action Button
self.actionButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.actionButton.frame = CGRectMake(10, 120, 70, 30);
[self.actionButton setTitleColor:[UIColor whiteColor]
forState:UIControlStateNormal];
[self.actionButton setTitleColor:[UIColor redColor]
forState:UIControlStateHighlighted];
// 'rgb(113, 201, 206)'
self.actionButton.backgroundColor = [UIColor colorWithRed:113 / 255.0
green:201 / 255.0
blue:206 / 255.0
alpha:1.0];
// self.actionButton.layer.borderWidth = 1.0;
// self.actionButton.layer.borderColor = [UIColor blueColor].CGColor;
self.actionButton.layer.cornerRadius = 4.0;
NSString *btnTitle = @"已停止";
[self.actionButton setTitle:btnTitle forState:UIControlStateNormal];
[self.actionButton addTarget:self
action:@selector(actionButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.actionButton];
// Settings Button
self.settingsButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.settingsButton.frame = CGRectMake(90, 120, 70, 30);
[self.settingsButton setTitleColor:[UIColor whiteColor]
forState:UIControlStateNormal];
[self.settingsButton setTitleColor:[UIColor redColor]
forState:UIControlStateHighlighted];
self.settingsButton.backgroundColor = [UIColor colorWithRed:113 / 255.0
green:201 / 255.0
blue:206 / 255.0
alpha:1.0];
// self.actionButton.layer.borderWidth = 1.0;
// self.actionButton.layer.borderColor = [UIColor blueColor].CGColor;
self.settingsButton.layer.cornerRadius = 4.0;
[self.settingsButton setTitle:@"刷新" forState:UIControlStateNormal];
[self.settingsButton addTarget:self
action:@selector(settingsButtonTapped)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.settingsButton];
self.infoLabel.text = @"S:0 / L:0";
// self.center = CGPointMake(90, self.superview.bounds.size.height - 100);
}
- (void)updateInfo {
XSPhoneConfig *info = [XSPhoneConfig sharedInstance];
self.nameLabel.text = [NSString stringWithFormat:@"%@", [info IPhoneName]];
self.ipLabel.text = [NSString
stringWithFormat:@"IP: %@", [[XSPhoneInfo sharedInstance] IPAddress]];
self.deviceTypeLabel.text = @"unknow";
}
- (void)onEventUpdateStatus:(id)data {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
weakSelf.deviceTypeLabel.text = [NSString stringWithFormat:@"%@", data];
});
}
- (void)onEventUpdateRunStatus:(id)data {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
// BOOL b = data;
NSString *btnTitle = ([data isEqual:@(YES)] ? @"运行中" : @"已停止");
NSLog(@"onEventUpdateRunStatus: %@,%@", data, btnTitle);
[weakSelf.actionButton setTitle:btnTitle forState:UIControlStateNormal];
});
}
- (void)showMyToast:(NSString *)msg {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
// UIView usage
[weakSelf makeToast:msg];
});
}
- (void)onEventUpdateName:(id)data {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
XSPhoneConfig *info = [XSPhoneConfig sharedInstance];
weakSelf.nameLabel.text =
[NSString stringWithFormat:@"%@", [info IPhoneName]];
});
}
- (void)actionButtonTapped:(UIButton *)sender {
NSLog(@"Action button tapped");
MyAdTask2Mangger *man = [MyAdTask2Mangger sharedInstance];
// MyAdTaskManager *man = [MyAdTaskManager sharedInstance];
// IPhoneHertbeat *hertBeat = [IPhoneHertbeat sharedInstance];
NSString *status = [man toggle]; // @"已停止";
/*
if ([self.actionButton.titleLabel.text isEqual:@"运行中"]) {
[man stop];
} else {
[man start];
status = @"运行中";
}
*/
//[self.actionButton setTitle:status forState:UIControlStateNormal];
}
- (void)settingsButtonTapped {
NSLog(@"Settings button tapped");
[self updateInfo];
//[self appendLog:@"设置按钮被按下"];
}
- (void)changeBackgroundColor {
self.backgroundColor = [UIColor colorWithRed:arc4random_uniform(256) / 255.0
green:arc4random_uniform(256) / 255.0
blue:arc4random_uniform(256) / 255.0
alpha:1.0];
}
- (void)appendLog:(NSString *)logMessage {
NSString *timestamp =
[NSDateFormatter localizedStringFromDate:[NSDate date]
dateStyle:NSDateFormatterNoStyle
timeStyle:NSDateFormatterMediumStyle];
NSString *fullLogMessage =
[NSString stringWithFormat:@"%@: %@\n", timestamp, logMessage];
self.logTextView.text =
[self.logTextView.text stringByAppendingString:fullLogMessage];
[self.logTextView
scrollRangeToVisible:NSMakeRange(self.logTextView.text.length - 1, 1)];
}
- (void)detectPan:(UIPanGestureRecognizer *)panGesture {
UIWindow *floatingWindow = (UIWindow *)panGesture.view;
CGPoint translation = [panGesture translationInView:floatingWindow];
floatingWindow.center = CGPointMake(floatingWindow.center.x + translation.x,
floatingWindow.center.y + translation.y);
[panGesture setTranslation:CGPointZero inView:floatingWindow];
}
@end