123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- //
- // XenonSDK-Load.m
- // XenonSDK
- //
- // Created by SAGESSE on 2019/3/11.
- // Copyright © 2019 SAGESSE. All rights reserved.
- //
- #import <UIKit/UIKit.h>
- #import <objc/runtime.h>
- /// Load the file from the Forwarder.
- id sdk_load_mapper = nil;
- id sdk_load_root = nil;
- //unsigned char* sdk_load_data(const char* name, const char* mode, size_t* osize) {
- //
- // printf("loader: %s - %s\n", name, mode);
- //
- // FILE* fp = fopen(name, mode);
- //
- // if (fp == nil) {
- // *osize = 0;
- // return nil;
- // }
- //
- // fseek(fp,0,SEEK_END);
- // ssize_t size = ftell(fp);
- // fseek(fp,0,SEEK_SET);
- //
- // unsigned char* buffer = malloc(size + 1);
- // size_t readed = fread(buffer, 1, size, fp);
- //
- // if (readed >= 0) {
- // buffer[readed] = '\0';
- // }
- //
- // *osize = readed;
- // fclose(fp);
- // return buffer;
- //}
- //// Register methods with NSFileManager.
- //@implementation NSFileManager (XenonSDK)
- //
- //- (BOOL)sdk_fileExistsAtPath:(NSString*)path {
- // //printf("chcker: %s\n", path.UTF8String);;
- //
- // // Find the path after removing the bundle.
- // if (sdk_load_root != nil ) {
- // NSString* root = NSBundle.mainBundle.bundlePath;
- // if ([path hasPrefix:root]) {
- // NSString* relative = [path stringByReplacingOccurrencesOfString:root withString:@""];
- // NSDictionary* descriptor = [sdk_load_mapper objectForKeyedSubscript:relative];
- // if (descriptor != nil) {
- // relative = [descriptor objectForKeyedSubscript:@"path"];
- // path = [sdk_load_root stringByAppendingPathComponent: relative];
- // }
- // }
- // }
- //
- // return [self sdk_fileExistsAtPath:path];
- //}
- //
- //@end
- // Register methods with NSBundle.
- @implementation NSBundle (XenonSDK)
- + (void)load {
-
- // Load mapper.
- NSURL* url = [NSBundle.mainBundle.executableURL URLByAppendingPathExtension:@"plist"];
- NSDictionary* mapper = [NSDictionary dictionaryWithContentsOfURL:url];
-
- // If the mapper file fails to load, ignore it.
- if (mapper == nil) {
- return;
- }
-
- // Save the map table.
- sdk_load_mapper = mapper;
- // Check if the app is unity project.
- if ([mapper[@"*"] isEqual:@"u"] || [mapper[@"*"] isEqual:@"k"]) {
-
- NSString* realBundlePath = NSBundle.mainBundle.bundlePath;
- NSString* linkBundlePath = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSAllDomainsMask, YES) firstObject] stringByAppendingPathComponent:realBundlePath.lastPathComponent];
-
- NSError* error = nil;
- NSFileManager* fileManager = [NSFileManager defaultManager];
- // The relink each time to prevent changes.
- [fileManager removeItemAtPath:linkBundlePath error:&error];
- [fileManager createDirectoryAtPath:linkBundlePath withIntermediateDirectories:YES attributes:nil error:&error];
-
- // Create the connection file the first time you install it.
- [mapper enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, NSDictionary* obj, BOOL * _Nonnull stop) {
- if ([key isEqual:@"*"]) {
- return;
- }
-
- NSString* src = [realBundlePath stringByAppendingPathComponent:obj[@"path"]];
- NSString* dest = [linkBundlePath stringByAppendingPathComponent:key];
-
- BOOL isDirectory = NO;
- NSError* suberror = nil;
-
- // If the file does not exist, ignore it.
- if (![fileManager fileExistsAtPath:src isDirectory:&isDirectory]) {
- return ;
- }
-
- // If this is a directory file, create it directly.
- if (isDirectory) {
- [fileManager createDirectoryAtPath:dest withIntermediateDirectories:YES attributes:nil error:&suberror];
- return;
- }
-
- // Check that the root directory exists, and if it does not, create it.
- if (![fileManager fileExistsAtPath:dest.stringByDeletingLastPathComponent]) {
- [fileManager createDirectoryAtPath:dest.stringByDeletingLastPathComponent withIntermediateDirectories:YES attributes:nil error:&suberror];
- }
-
- // Create file a soft link.
- [fileManager createSymbolicLinkAtPath:dest withDestinationPath:src error:&suberror];
- }];
-
- if ([mapper[@"*"] isEqual:@"k"]) {
- sdk_load_root = linkBundlePath;
- Method m1 = class_getInstanceMethod(self, @selector(URLForResource:withExtension:subdirectory:));
- Method m2 = class_getInstanceMethod(self, @selector(sdk_URLForResource:withExtension:subdirectory:));
- method_exchangeImplementations(m1, m2);
- // Method m3 = class_getInstanceMethod(NSFileManager.class, @selector(fileExistsAtPath:));
- // Method m4 = class_getInstanceMethod(NSFileManager.class, @selector(sdk_fileExistsAtPath:));
- // method_exchangeImplementations(m3, m4);
- return;
- }
-
- // Register with the project class.
- Class tmp = objc_allocateClassPair(NSObject.class, "XCBundle", 0);
- objc_registerClassPair(tmp);
- class_addMethod(objc_getMetaClass("XCBundle"), @selector(bundlePath), imp_implementationWithBlock((id)^{ return linkBundlePath; }), "@:");
-
- return;
- }
-
- // Check if the app is cocos project.
- if ([mapper[@"*"] isEqual:@"c"]) {
- Method m1 = class_getInstanceMethod(self, @selector(URLForResource:withExtension:subdirectory:));
- Method m2 = class_getInstanceMethod(self, @selector(sdk_URLForResource:withExtension:subdirectory:));
- method_exchangeImplementations(m1, m2);
- }
- }
- - (NSURL*)sdk_URLForResource:(NSString*)resource withExtension:(NSString*)extension subdirectory:(NSString*)subdirectory {
-
- NSString* path = resource;
-
- if (subdirectory != nil) {
- path = [subdirectory stringByAppendingPathComponent:path];
- }
- if (extension != nil) {
- path = [path stringByAppendingPathExtension:extension];
- }
- if (path.length != 0 && [path hasPrefix:@"/"]) {
- path = [path substringFromIndex:1];
- }
-
- NSDictionary* descriptor = [sdk_load_mapper objectForKeyedSubscript:path];
-
- if (descriptor != nil) {
- if (sdk_load_root != nil) {
- return [NSURL URLWithString:[sdk_load_root stringByAppendingPathComponent:path]];
- }
- path = [descriptor objectForKeyedSubscript:@"path"];
- if (path != nil) {
- return [self sdk_URLForResource:path withExtension:nil subdirectory:nil];
- }
- }
- return [self sdk_URLForResource:resource withExtension:extension subdirectory:subdirectory];
- }
- @end
- //// Register methods with NSObject.
- //@implementation NSObject (XenonSDK)
- //
- //+ (void*)XCForwarderInit {
- // printf("loader: init\n");
- //
- //// Method m1 = class_getInstanceMethod(NSBundle.class, @selector(pathForResource:ofType:inDirectory:));
- //// Method m2 = class_getInstanceMethod(NSBundle.class, @selector(sdk_pathForResource:ofType:inDirectory:));
- //// method_exchangeImplementations(m1, m2);
- //
- //// Method m3 = class_getInstanceMethod(NSBundle.class, @selector(fileExistsAtPath:));
- //// Method m4 = class_getInstanceMethod(NSBundle.class, @selector(sdk_fileExistsAtPath:));
- //// method_exchangeImplementations(m3, m4);
- //
- //// return &sdk_load_data;
- // return nil;
- //}
- //
- //@end
|