22 * FileRedirectDylib - tweak.m
33 *
44 * Hooks file-access functions so that when the game reads from its .app bundle,
5- * it checks Documents/disk/ first. If a replacement file exists there, the
5+ * it checks the Documents folder first. If a replacement file exists there, the
66 * hooked function transparently returns that path instead.
77 *
88 * Works on non-jailbroken iOS (sideloaded IPAs) using Facebook's fishhook
1111 * Usage:
1212 * 1. Build as a dylib for iOS arm64.
1313 * 2. Inject into the target IPA (insert_dylib / optool).
14- * 3. Place your modded game files in:
15- * <AppContainer>/ Documents/disk/
16- * mirroring the directory structure of the .app bundle.
14+ * 3. Place your modded game files in Documents/, mirroring the .app structure.
15+ * For Bully: Documents/BullyOrig/Scripts/yourscript.sc
16+ * For GTA SA: Documents/texdb/gta3.txd (or whatever path the file has in .app)
1717 * 4. The game will transparently load your files instead of the originals.
1818 */
1919
3131// Globals
3232// ---------------------------------------------------------------------------
3333
34- static NSString *g_bundlePath = nil ; // e.g. /var/containers/…/MyApp.app
34+ static NSString *g_bundlePath = nil ; // e.g. /var/containers/…/MyApp.app
3535static NSString *g_documentsPath = nil ; // e.g. /var/containers/…/Documents
36- static NSString *g_diskPath = nil ; // e.g. /var/containers/…/Documents/disk
3736
3837// Set to 1 to log every redirected access (useful for debugging).
3938// In production you probably want this off (0).
@@ -52,14 +51,14 @@ static void redirect_log(const char *func, const char *original, const char *red
5251// ---------------------------------------------------------------------------
5352
5453static const char *redirected_path_if_exists (const char *path) {
55- if (!path || !g_bundlePath || !g_diskPath ) return NULL ;
54+ if (!path || !g_bundlePath || !g_documentsPath ) return NULL ;
5655
5756 NSString *nsPath = [NSString stringWithUTF8String: path];
5857 if (![nsPath hasPrefix: g_bundlePath]) return NULL ;
5958
60- // Strip the bundle prefix and prepend the disk path
59+ // Strip the bundle prefix and prepend the Documents path
6160 NSString *relative = [nsPath substringFromIndex: [g_bundlePath length ]];
62- NSString *candidate = [g_diskPath stringByAppendingString: relative];
61+ NSString *candidate = [g_documentsPath stringByAppendingString: relative];
6362
6463 // Check existence
6564 if ([[NSFileManager defaultManager ] fileExistsAtPath: candidate]) {
@@ -70,11 +69,11 @@ static void redirect_log(const char *func, const char *original, const char *red
7069
7170// Same helper but returns an NSString (for ObjC hooks)
7271static NSString *redirected_nspath_if_exists (NSString *path) {
73- if (!path || !g_bundlePath || !g_diskPath ) return nil ;
72+ if (!path || !g_bundlePath || !g_documentsPath ) return nil ;
7473 if (![path hasPrefix: g_bundlePath]) return nil ;
7574
7675 NSString *relative = [path substringFromIndex: [g_bundlePath length ]];
77- NSString *candidate = [g_diskPath stringByAppendingString: relative];
76+ NSString *candidate = [g_documentsPath stringByAppendingString: relative];
7877
7978 if ([[NSFileManager defaultManager ] fileExistsAtPath: candidate]) {
8079 return candidate;
@@ -231,25 +230,24 @@ static void file_redirect_init(void) {
231230 NSArray *docPaths = NSSearchPathForDirectoriesInDomains (
232231 NSDocumentDirectory, NSUserDomainMask, YES );
233232 g_documentsPath = [docPaths firstObject ];
234- g_diskPath = [g_documentsPath stringByAppendingPathComponent: @" disk" ];
235233
236234 NSLog (@" [FileRedirect] === Initializing ===" );
237235 NSLog (@" [FileRedirect] Bundle path: %@ " , g_bundlePath);
238236 NSLog (@" [FileRedirect] Documents path: %@ " , g_documentsPath);
239- NSLog (@" [FileRedirect] Disk path: %@ " , g_diskPath);
240237
241- // Create the disk folder if it doesn't exist
238+ // Auto-create BullyOrig/Scripts/ in Documents for convenience
242239 NSFileManager *fm = [NSFileManager defaultManager ];
243- if (![fm fileExistsAtPath: g_diskPath]) {
240+ NSString *bullyScripts = [g_documentsPath stringByAppendingPathComponent: @" BullyOrig/Scripts" ];
241+ if (![fm fileExistsAtPath: bullyScripts]) {
244242 NSError *err = nil ;
245- [fm createDirectoryAtPath: g_diskPath
243+ [fm createDirectoryAtPath: bullyScripts
246244 withIntermediateDirectories: YES
247245 attributes: nil
248246 error: &err];
249247 if (err) {
250- NSLog (@" [FileRedirect] Failed to create disk dir : %@ " , err);
248+ NSLog (@" [FileRedirect] Failed to create BullyOrig/Scripts : %@ " , err);
251249 } else {
252- NSLog (@" [FileRedirect] Created disk directory at %@ " , g_diskPath );
250+ NSLog (@" [FileRedirect] Created Documents/BullyOrig/Scripts/ " );
253251 }
254252 }
255253
@@ -280,6 +278,6 @@ static void file_redirect_init(void) {
280278 @selector (fr_contentsAtPath: ));
281279
282280 NSLog (@" [FileRedirect] ObjC swizzles installed (NSBundle, NSFileManager)" );
283- NSLog (@" [FileRedirect] === Ready! Place mod files in Documents/disk/ ===" );
281+ NSLog (@" [FileRedirect] === Ready! Place mod files in Documents/ (e.g. Documents/BullyOrig/Scripts/) ===" );
284282 }
285283}
0 commit comments