VisionWallPaperOffline_Chec.../HDwallpaper/LuxADManager/ZZHUtils.m
2024-08-19 16:38:26 +08:00

710 lines
21 KiB
Objective-C

//
// ZZHUtils.m
// HD wallpaper
//
// Created by aaa on 2024/7/16.
//
#import "ZZHUtils.h"
#include <sys/sysctl.h>
#include <mach/mach_time.h>
#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>
#import <sys/utsname.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import <SystemConfiguration/CaptiveNetwork.h>
#import <netinet/in.h>
#import <UIKit/UIKit.h>
#import <sys/stat.h>
#import <AdSupport/AdSupport.h>
#import <CoreBluetooth/CoreBluetooth.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
#include <mach/mach_host.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_dl.h>
#import "ifaddrs.h"
#import <arpa/inet.h>
#import <Network/Network.h>
#import "resolv.h"
@implementation ZZHUtils
+ (long long)collectKernelBootTimeMillis {
struct timeval bootTime;
int mib[2] = {CTL_KERN,KERN_BOOTTIME};
size_t size = sizeof(bootTime);
if (sysctl(mib, 2, &bootTime, &size, NULL, 0) != -1) {
return bootTime.tv_sec * 1000;///秒
};
return 0;
}
+ (long long)collectMonotonicRawClockTimeMillis {
struct timespec tp;
if(clock_gettime(CLOCK_MONOTONIC_RAW, &tp) != -1) {
long xx = tp.tv_sec*1000 + tp.tv_nsec/1000000;
return xx;
}
return 0;
}
+ (unsigned long long)collectAccessibilityFeatures {
NSInteger features = 0;
if (UIAccessibilityIsClosedCaptioningEnabled()) {
features |= 0x2;
}
if (UIAccessibilityIsMonoAudioEnabled()) {
features |= 0x4;
}
if (UIAccessibilityIsReduceMotionEnabled()) {
features |= 0x8;
}
if (UIAccessibilityIsGuidedAccessEnabled()) {
features |= 0x10;
}
if (UIAccessibilityIsInvertColorsEnabled()) {
features |= 0x20;
}
if (UIAccessibilityIsVoiceOverRunning()) {
features |= 0x40;
}
if (UIAccessibilityDarkerSystemColorsEnabled()) {
features |= 0x80;
}
if (UIAccessibilityIsBoldTextEnabled()) {
features |= 0x100;
}
if (UIAccessibilityIsGrayscaleEnabled()) {
features |= 0x200;
}
if (UIAccessibilityIsReduceTransparencyEnabled()) {
features |= 0x400;
}
if (UIAccessibilityIsSpeakScreenEnabled()) {
features |= 0x800;
}
if (UIAccessibilityIsSpeakSelectionEnabled()) {
features |= 0x1000;
}
if (UIAccessibilityIsSwitchControlRunning()) {
features |= 0x2000;
}
if (UIAccessibilityIsShakeToUndoEnabled()) {
features |= 0x4000;
}
if (UIAccessibilityIsAssistiveTouchRunning()) {
features |= 0x8000;
}
if (UIAccessibilityHearingDevicePairedEar() != 0) {
features |= 0x400000;
}
if (@available(iOS 13.0, *)) {
if ([UITraitCollection currentTraitCollection].userInterfaceStyle == UIUserInterfaceStyleDark) {
features |= 0x10000;
}
if (UIAccessibilityIsOnOffSwitchLabelsEnabled()) {
features |= 0x20000;
}
if (UIAccessibilityIsVideoAutoplayEnabled()) {
features |= 0x40000;
}
if (UIAccessibilityShouldDifferentiateWithoutColor()) {
features |= 0x80000;
}
if (@available(iOS 14.0, *)) {
if (UIAccessibilityPrefersCrossFadeTransitions()) {
features |= 0x100000;
}
if (UIAccessibilityButtonShapesEnabled()) {
features |= 0x200000;
}
}
}
NSLog(@"features:\n%ld",features);
return features;
}
+ (NSString *)collectDeviceKeyboards{
NSArray *lanagues = [NSLocale preferredLanguages];
__block NSString *str = @"";
[lanagues enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (idx < lanagues.count-1) {
str = [str stringByAppendingFormat:@"%@,",obj];
}
else {
str = [str stringByAppendingFormat:@"%@",obj];
}
}];
return str;
}
+ (void)userAgent {
static WKWebView *webView = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
webView = [WKWebView new];
});
[webView evaluateJavaScript:@"function getAgent() {return navigator.userAgent;} getAgent(); " completionHandler:^(id _Nullable result, NSError * _Nullable error) {
NSLog(@"zzh the useragent:%@ ",result);
}];
// NSString *geoStr = @"if (\"geolocation\" in navigator) { navigator.geolocation.getCurrentPosition(function(position) { console.log(\"Latitude is :\", position.coords.latitude);console.log(\"Longitude is :\", position.coords.longitude);}, function(error) {console.error(\"Error Code = \" + error.code + \" - \" + error.message);});";
//
// [webView evaluateJavaScript:geoStr completionHandler:^(id _Nullable result, NSError * _Nullable error) {
// NSLog(@"zzh the geo err:%@ ",error);
// }];
}
+ (BOOL)isReachableViaWWAN {
SCNetworkReachabilityFlags flags;
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
if (SCNetworkReachabilityGetFlags(reachability, &flags)) {
if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN) {
return YES;
}
}
return NO;
}
+ (BOOL)isReachableViaWiFi {
SCNetworkReachabilityFlags flags;
BOOL result = NO;
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
if (SCNetworkReachabilityGetFlags(reachability, &flags)) {
BOOL isReachable = (flags & kSCNetworkReachabilityFlagsReachable) != 0;
BOOL needsConnection = (flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0;
BOOL isWiFi = (flags & kSCNetworkReachabilityFlagsIsWWAN) == 0;
result = isReachable && !needsConnection && isWiFi;
}
NSLog(@"result:%d",result);
return result;
}
+(BOOL)isReachable {
// 获取 SCNetworkReachabilityRef 对象
// 注意:这里直接从内存地址获取的方式在实际开发中是不安全的,
// 应该通过正确的途径获取该对象,例如使用 SCNetworkReachabilityCreateWithAddress 或 SCNetworkReachabilityCreateWithName
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
// 获取网络状态标志
SCNetworkReachabilityFlags flags;
BOOL success = SCNetworkReachabilityGetFlags(reachability, &flags);
if (!success) {
return NO;
}
// 判断网络是否可达,并调用 ALReachability 的方法
return [ZZHUtils isReachableWithFlags:flags];
}
+ (int)isReachableWithFlags:(int)arg2 {
int result = 5;
if ((result & ~arg2) != 0) {
result = (result != 0) ? 1 : 5;
}
return result & ((arg2 & 2) >> 1);
}
+ (id)collectTimeZoneOffset {
NSTimeZone *tz = [NSTimeZone localTimeZone];
NSInteger sec = [tz secondsFromGMT];
double hoursFromGMT = (double)sec / 3600.0;
return @(hoursFromGMT);
}
//获取电池数据
+ (NSDictionary *)collectBatteryInfoIfNeeded {
NSMutableDictionary *dictionary = [NSMutableDictionary new];
UIDevice *device = [UIDevice currentDevice];
BOOL originalBatteryMonitoringEnabled = device.isBatteryMonitoringEnabled;
[device setBatteryMonitoringEnabled:YES];
UIDeviceBatteryState batteryState = device.batteryState;
NSNumber *batteryStateNumber = [NSNumber numberWithInteger:batteryState];
[dictionary setObject:batteryStateNumber forKey:@"ict"];
float batteryLevel = device.batteryLevel;
int batteryPercentage = (int)(batteryLevel * 100);
if (batteryPercentage > 0) {
batteryPercentage = batteryPercentage ^ 0x10101010;
NSNumber *batteryLevelNumber = @(batteryPercentage);
[dictionary setObject:batteryLevelNumber forKey:@"icm"];
}
else {
[dictionary setObject:@"-1" forKey:@"icm"];
}
[device setBatteryMonitoringEnabled:originalBatteryMonitoringEnabled];
return dictionary;
}
+ (NSString *)collectModelRevision {
struct utsname systemInfo;
if (uname(&systemInfo) == 0) {
NSString *modelString = [NSString stringWithUTF8String:systemInfo.machine];
return modelString;
}
return nil;
}
+ (CGFloat)getScreenBrightness {
return [UIScreen mainScreen].brightness;
}
+ (CBManagerState)bluetoothState {
CBCentralManager *manager = [[CBCentralManager alloc] init];
return manager.state;
}
//设备型号
+ (NSDictionary *)collectModel {
NSMutableDictionary *arg2 = [NSMutableDictionary new];
UIDevice *device = [UIDevice currentDevice];
NSString *model = [device model];
[arg2 setObject:model forKeyedSubscript:@"model"];
return arg2;
}
+ (NSString *)collectSubplatform {
if (@available(iOS 14.0, *)) {
if ([[NSProcessInfo processInfo] isiOSAppOnMac]) {
return @"ios_on_mac";
}
}
if (@available(iOS 13.0, *)) {
if ([[NSProcessInfo processInfo] isMacCatalystApp]) {
return @"mac_catalyst";
}
}
return @"ios";
}
+ (id)collectOrientationLock {
// [[[[UIApplication sharedApplication] windows].firstObject windowScene] interfaceOrientation]
return nil;
}
+ (NSMutableDictionary *)collectScreenDimensions{
NSMutableDictionary *dict = [NSMutableDictionary new];
UIScreen *mainScreen = [UIScreen mainScreen];
CGRect bounds = [mainScreen bounds];
CGRect nativeBounds = [mainScreen nativeBounds];
CGFloat scale = [mainScreen scale];
[dict setObject:@(bounds.size.width) forKeyedSubscript:@"dx"];
[dict setObject:@(bounds.size.height) forKeyedSubscript:@"dy"];
[dict setObject:@(nativeBounds.size.width) forKeyedSubscript:@"ndx"];
[dict setObject:@(nativeBounds.size.height) forKeyedSubscript:@"ndy"];
[dict setObject:@(scale) forKeyedSubscript:@"scale"];
return dict;
}
+ (NSString *)systemVersion {
UIDevice *device = [UIDevice currentDevice];
NSString *version = [device systemVersion];
return version;
}
+ (NSMutableDictionary *)collectLocale{
NSMutableDictionary *arg2 = [NSMutableDictionary new];
NSLocale *currentLocale = [NSLocale currentLocale];
NSString *localeIdentifier = [currentLocale localeIdentifier];
[arg2 setObject:localeIdentifier forKeyedSubscript:@"locale"];
return arg2;
}
+ (NSNumber *)volume {
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
float outputVolume = [audioSession outputVolume];
NSNumber *volumeNumber = [NSNumber numberWithFloat:outputVolume];
return volumeNumber;
}
+ (void)appInfoFromBundle {
NSBundle *bundle = [NSBundle mainBundle];
NSArray *arr = [NSBundle allBundles];
NSArray *frameworks = [NSBundle allFrameworks];
NSURL *appStoreReceiptURL = [bundle appStoreReceiptURL];
NSLog(@"the bundle:%@",bundle);
}
+ (BOOL)isVPNConnected {
CFDictionaryRef proxySettings = CFNetworkCopySystemProxySettings();
if (proxySettings == NULL) {
return NO;
}
NSDictionary *settings = (__bridge_transfer NSDictionary *)proxySettings;
NSDictionary *scoped = settings[@"__SCOPED__"];
if (!scoped) {
return NO;
}
NSArray *allKeys = [scoped allKeys];
__block BOOL rr = NO;
[allKeys enumerateObjectsUsingBlock:^(NSString * _Nonnull interface, NSUInteger idx, BOOL * _Nonnull stop) {
if ([interface containsString:@"tun"] || [interface containsString:@"ppp"]) {
rr = YES;
} else {
rr = [interface containsString:@"ipsec"];
}
}];
return rr;
}
+ (SystemSoundID)muteSoundID {
SystemSoundID _muteSoundID = 0;
NSURL *soundURL = [[NSBundle mainBundle] URLForResource:@"mute" withExtension:@"aiff"];
if (soundURL) {
OSStatus status = AudioServicesCreateSystemSoundID((__bridge CFURLRef)soundURL, &_muteSoundID);
if (status == noErr) {
// 设置声音为静音
UInt32 yes = 1;
AudioServicesSetProperty(kAudioServicesPropertyIsUISound,
sizeof(_muteSoundID),
&_muteSoundID,
sizeof(yes),
&yes);
}
}
return _muteSoundID;
}
+ (NSString *)getIDFA {
if ([[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]) {
NSString *idfa = [[ASIdentifierManager sharedManager].advertisingIdentifier UUIDString];
return idfa;
} else {
return @"";
}
}
+ (NSString *)getIDFV {
NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
return idfv;
}
#pragma mark - 获取网络运营商
+ (NSString *)getCarrierName{
CTTelephonyNetworkInfo *telephonyInfo = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier *carrier = [telephonyInfo subscriberCellularProvider];
NSString *currentCountry=[carrier carrierName];
return currentCountry;
}
#pragma mark - 获取当前可用内存
/**
获取当前可用内存
@return 当前可用内存大小
*/
+(long long)getAvailableMemorySize
{
vm_statistics_data_t vmStats;
mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
kern_return_t kernReturn = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmStats, &infoCount);
if (kernReturn != KERN_SUCCESS)
{
return NSNotFound;
}
return ((vm_page_size * vmStats.free_count + vm_page_size * vmStats.inactive_count));
}
#pragma mark - 获取磁盘容量
/**
获取磁盘容量
@return 磁盘容量
*/
+(long long)getTotalDiskSize{
struct statfs buf;
unsigned long long freeSpace = -1;
if (statfs("/var", &buf) >= 0)
{
freeSpace = (unsigned long long)(buf.f_bsize * buf.f_blocks);
}
return freeSpace;
}
#pragma mark - 获取可用磁盘容量
/**
获取可用磁盘容量
@return 可用磁盘容量
*/
+(long long)getAvailableDiskSize{
struct statfs buf;
unsigned long long freeSpace = -1;
if (statfs("/var", &buf) >= 0)
{
freeSpace = (unsigned long long)(buf.f_bsize * buf.f_bavail);
}
return freeSpace;
}
/// 获取本机DNS服务器
/// libresolv.tbd需要添加这个库
+ (NSArray *)outPutDNSServers {
res_state res = malloc( sizeof(struct __res_state) );
NSMutableArray *dnsArray = [NSMutableArray new];
if (res_ninit(res) == 0) {
for (int i = 0; i < res->nscount; i++ ) {
NSString *s = [NSString stringWithUTF8String:inet_ntoa(res->nsaddr_list[i].sin_addr)];
[dnsArray addObject:s];
}
}
res_ndestroy(res);//!!改了这里
free(res);
return dnsArray.mutableCopy;
}
//是否有刘海屏
+ (BOOL)hasNotch {
return [UIScreen mainScreen].nativeBounds.size.height != UIScreen.mainScreen.bounds.size.height;
}
//获取系统字号
+ (NSNumber *)getSystemFontSize {
UIFont *font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
UIFontDescriptor *ctFont = font.fontDescriptor;
NSNumber *fontSize = [ctFont objectForKey:@"NSFontSizeAttribute"];
return fontSize;
}
//获取processInfo
+ (NSDictionary *)processInfo {
NSProcessInfo *processInfo = [NSProcessInfo processInfo];
return processInfo.environment;
}
#define IOS_CELLULAR @"pdp_ip0"//有些分配的地址为en0 有些分配的en1
#define IOS_WIFI2 @"en2"
#define IOS_WIFI1 @"en1"
#define IOS_WIFI @"en0"//
#define IOS_VPN @"utun0" vpn很少用到可以注释
#define IP_ADDR_IPv4 @"ipv4"
#define IP_ADDR_IPv6 @"ipv6"
//获取所有相关IP信息
+ (NSDictionary *)getIPAddresses{
NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
// retrieve the current interfaces - returns 0 on success
struct ifaddrs *interfaces;
if(!getifaddrs(&interfaces)) {
// Loop through linked list of interfaces
struct ifaddrs *interface;
for(interface=interfaces; interface; interface=interface->ifa_next) {
if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) {
continue; // deeply nested code harder to read
}
const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;
char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
NSString *type;
if(addr->sin_family == AF_INET) {
if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
type = IP_ADDR_IPv4;
}
} else {
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr;
if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {
type = IP_ADDR_IPv6;
}
}
if(type) {
NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
addresses[key] = [NSString stringWithUTF8String:addrBuf];
}
}
}
// Free memory
freeifaddrs(interfaces);
}
return [addresses count] ? addresses : nil;
}
#warning -----暂时还未去成功获取
+ (NSDictionary *)wifiInfo {
NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
NSLog(@"interfaces:%@",ifs);
NSDictionary *info = nil;
for (NSString *ifname in ifs) {
info = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifname);
NSLog(@"wifiInfo %@ => %@",ifname,info);
}
return info;
}
#warning -----暂时还未去处理的伪代码
//- (NSDictionary *)collectAdServerInfo {
// NSMutableDictionary *result = [NSMutableDictionary dictionary];
//
// // Server Cache
// [result setObject:[self.sdk stringForKey:[ALSetting serverCache]] forKeyedSubscript:@"sc"];
//
// // Server Cache 2
// [result setObject:[self.sdk stringForKey:[ALSetting serverCache2]] forKeyedSubscript:@"sc2"];
//
// // Server Cache 3
// [result setObject:[self.sdk stringForKey:[ALSetting serverCache3]] forKeyedSubscript:@"sc3"];
//
// // Server Installed At
// [result setObject:[self.sdk stringForKey:[ALSetting serverInstalledAt]] forKeyedSubscript:@"server_installed_at"];
//
// // Server Installed At V2
// [result setObject:[self.sdk stringForKey:[ALSetting serverInstalledAtV2]] forKeyedSubscript:@"server_installed_at_v2"];
//
// // Persisted Data
// NSString *persistedData = [[self.sdk userDefaults] stringForKey:[ALUserDefaultsKey persistedData]];
// [result al_setStringValueIfValid:persistedData forKey:@"persisted_data"];
//
// return [result copy];
//}
#warning ----还未检测到该方法的调用...
+ (NSString *)collectCurrentRadioAccessTechnologyIfNeeded{
return @"";
}
#pragma mark ----检测是否越狱
+ (BOOL)isJailbroken {
if ([self checkCommonJailbreakFiles] || [self checkSuspiciousApps] || [self canWriteToSystemDirectories]) {
return YES;
}
return NO;
}
+ (BOOL)checkCommonJailbreakFiles {
NSArray *jailbreakFiles = @[
@"/Applications/Cydia.app",
@"/Library/MobileSubstrate/MobileSubstrate.dylib",
@"/bin/bash",
@"/usr/sbin/sshd",
@"/etc/apt",
@"/private/var/lib/apt/"
];
for (NSString *path in jailbreakFiles) {
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
return YES;
}
}
return NO;
}
+ (BOOL)checkSuspiciousApps {
if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"cydia://package/com.example.package"]]) {
return YES;
}
return NO;
}
+ (BOOL)canWriteToSystemDirectories {
NSError *error;
NSString *stringToWrite = @"Jailbreak Test";
NSString *filePath = @"/private/jailbreakTest.txt";
[stringToWrite writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
if (error == nil) {
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
return YES;
}
return NO;
}
@end