Skip to content

Commit 2de4a41

Browse files
committed
test: insomnia hack
1 parent 7b7cbd1 commit 2de4a41

1 file changed

Lines changed: 58 additions & 0 deletions

File tree

PlayTools/PlayLoader.m

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// PlayTools
44
//
55

6+
#include <Foundation/Foundation.h>
67
#include <errno.h>
78
#include <sys/sysctl.h>
89

@@ -230,11 +231,60 @@ static int pt_unlink(char const* path) {
230231
return unlink(ue_fix_filename(path));
231232
}
232233

234+
static NSMutableDictionary *thread_sleep_counters = nil;
235+
static NSMutableDictionary *last_sleep_attempts = nil;
236+
static dispatch_once_t thread_sleep_once;
237+
static NSLock *thread_sleep_lock = nil;
238+
239+
static int pt_usleep(useconds_t time) {
240+
dispatch_once(&thread_sleep_once, ^{
241+
thread_sleep_counters = [NSMutableDictionary dictionary];
242+
last_sleep_attempts = [NSMutableDictionary dictionary];
243+
thread_sleep_lock = [[NSLock alloc] init];
244+
[thread_sleep_lock lock];
245+
});
246+
247+
int thread_id = pthread_mach_thread_np(pthread_self());
248+
NSNumber *threadKey = @(thread_id);
249+
250+
int thread_sleep_counter = [thread_sleep_counters[threadKey] intValue];
251+
int last_sleep_attempt = [last_sleep_attempts[threadKey] intValue];
252+
253+
if (time == 100000) {
254+
int timestamp = (int)[[NSDate date] timeIntervalSince1970];
255+
// If it sleeps too fast, increase counter
256+
if (timestamp - last_sleep_attempt < 2) {
257+
thread_sleep_counter++;
258+
} else {
259+
thread_sleep_counter = 1;
260+
}
261+
last_sleep_attempt = timestamp;
262+
thread_sleep_counters[threadKey] = @(thread_sleep_counter);
263+
last_sleep_attempts[threadKey] = @(last_sleep_attempt);
264+
265+
}
266+
267+
if (thread_sleep_counter > 100) {
268+
// Stop this thread from spamming usleep calls
269+
NSLog(@"[PC] Thread %i exceeded usleep limit. Seem sus, stopping this "
270+
@"thread FOREVER",
271+
thread_id);
272+
273+
[thread_sleep_lock lock];
274+
[thread_sleep_lock unlock];
275+
276+
return 0;
277+
}
278+
279+
return usleep(time);
280+
}
281+
233282
DYLD_INTERPOSE(pt_open, open)
234283
DYLD_INTERPOSE(pt_stat, stat)
235284
DYLD_INTERPOSE(pt_access, access)
236285
DYLD_INTERPOSE(pt_rename, rename)
237286
DYLD_INTERPOSE(pt_unlink, unlink)
287+
DYLD_INTERPOSE(pt_usleep, usleep)
238288

239289
@implementation PlayLoader
240290

@@ -250,6 +300,14 @@ static void __attribute__((constructor)) initialize(void) {
250300
if (ue_status == 2) {
251301
[PlayKeychain debugLogger: [NSString stringWithFormat:@"UnrealEngine Hooked"]];
252302
}
303+
304+
// Add an observer so we can unlock threads on app termination
305+
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationWillTerminateNotification
306+
object:nil
307+
queue:[NSOperationQueue mainQueue]
308+
usingBlock:^(NSNotification * _Nonnull note) {
309+
[thread_sleep_lock unlock];
310+
}];
253311
}
254312

255313
@end

0 commit comments

Comments
 (0)