add project
@@ -0,0 +1,17 @@
|
||||
TARGET := iphone:clang:14.5:14.0
|
||||
INSTALL_TARGET_PROCESSES = TrollStorePersistenceHelper
|
||||
|
||||
include $(THEOS)/makefiles/common.mk
|
||||
|
||||
APPLICATION_NAME = TrollStorePersistenceHelper
|
||||
|
||||
TrollStorePersistenceHelper_FILES = $(wildcard *.m) ../Helper/Shared.m ../Store/TSUtil.m
|
||||
TrollStorePersistenceHelper_FRAMEWORKS = UIKit CoreGraphics CoreServices
|
||||
TrollStorePersistenceHelper_PRIVATE_FRAMEWORKS = Preferences
|
||||
TrollStorePersistenceHelper_CFLAGS = -fobjc-arc
|
||||
TrollStorePersistenceHelper_CODESIGN_FLAGS = -Sentitlements.plist
|
||||
|
||||
include $(THEOS_MAKE_PATH)/application.mk
|
||||
|
||||
internal-stage::
|
||||
ldid -S -M -K../_compile/cert.p12 $(THEOS_STAGING_DIR)/Applications/TrollStorePersistenceHelper.app/TrollStorePersistenceHelper
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 8.7 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 21 KiB |
@@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>TrollStorePersistenceHelper</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>TrollHelper</string>
|
||||
<key>CFBundleIcons</key>
|
||||
<dict>
|
||||
<key>CFBundlePrimaryIcon</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>AppIcon29x29</string>
|
||||
<string>AppIcon40x40</string>
|
||||
<string>AppIcon57x57</string>
|
||||
<string>AppIcon60x60</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>CFBundleIcons~ipad</key>
|
||||
<dict>
|
||||
<key>CFBundlePrimaryIcon</key>
|
||||
<dict>
|
||||
<key>CFBundleIconFiles</key>
|
||||
<array>
|
||||
<string>AppIcon29x29</string>
|
||||
<string>AppIcon40x40</string>
|
||||
<string>AppIcon57x57</string>
|
||||
<string>AppIcon60x60</string>
|
||||
<string>AppIcon50x50</string>
|
||||
<string>AppIcon72x72</string>
|
||||
<string>AppIcon76x76</string>
|
||||
</array>
|
||||
<key>UIPrerenderedIcon</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.opa334.trollstorepersistencehelper</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>iPhoneOS</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>1</integer>
|
||||
<integer>2</integer>
|
||||
</array>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UILaunchImageFile</key>
|
||||
<string>LaunchImage</string>
|
||||
<key>UILaunchImages</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UILaunchImageMinimumOSVersion</key>
|
||||
<string>7.0</string>
|
||||
<key>UILaunchImageName</key>
|
||||
<string>LaunchImage</string>
|
||||
<key>UILaunchImageOrientation</key>
|
||||
<string>Portrait</string>
|
||||
<key>UILaunchImageSize</key>
|
||||
<string>{320, 480}</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UILaunchImageMinimumOSVersion</key>
|
||||
<string>7.0</string>
|
||||
<key>UILaunchImageName</key>
|
||||
<string>LaunchImage-700-568h</string>
|
||||
<key>UILaunchImageOrientation</key>
|
||||
<string>Portrait</string>
|
||||
<key>UILaunchImageSize</key>
|
||||
<string>{320, 568}</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UILaunchImageMinimumOSVersion</key>
|
||||
<string>7.0</string>
|
||||
<key>UILaunchImageName</key>
|
||||
<string>LaunchImage-Portrait</string>
|
||||
<key>UILaunchImageOrientation</key>
|
||||
<string>Portrait</string>
|
||||
<key>UILaunchImageSize</key>
|
||||
<string>{768, 1024}</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UILaunchImageMinimumOSVersion</key>
|
||||
<string>7.0</string>
|
||||
<key>UILaunchImageName</key>
|
||||
<string>LaunchImage-Landscape</string>
|
||||
<key>UILaunchImageOrientation</key>
|
||||
<string>Landscape</string>
|
||||
<key>UILaunchImageSize</key>
|
||||
<string>{768, 1024}</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UILaunchImageMinimumOSVersion</key>
|
||||
<string>8.0</string>
|
||||
<key>UILaunchImageName</key>
|
||||
<string>LaunchImage-800-667h</string>
|
||||
<key>UILaunchImageOrientation</key>
|
||||
<string>Portrait</string>
|
||||
<key>UILaunchImageSize</key>
|
||||
<string>{375, 667}</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UILaunchImageMinimumOSVersion</key>
|
||||
<string>8.0</string>
|
||||
<key>UILaunchImageName</key>
|
||||
<string>LaunchImage-800-Portrait-736h</string>
|
||||
<key>UILaunchImageOrientation</key>
|
||||
<string>Portrait</string>
|
||||
<key>UILaunchImageSize</key>
|
||||
<string>{414, 736}</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UILaunchImageMinimumOSVersion</key>
|
||||
<string>8.0</string>
|
||||
<key>UILaunchImageName</key>
|
||||
<string>LaunchImage-800-Landscape-736h</string>
|
||||
<key>UILaunchImageOrientation</key>
|
||||
<string>Landscape</string>
|
||||
<key>UILaunchImageSize</key>
|
||||
<string>{414, 736}</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,8 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface TSPHAppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
@property (nonatomic, strong) UINavigationController *rootViewController;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,14 @@
|
||||
#import "TSPHAppDelegate.h"
|
||||
#import "TSPHRootViewController.h"
|
||||
|
||||
@implementation TSPHAppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
_rootViewController = [[UINavigationController alloc] initWithRootViewController:[[TSPHRootViewController alloc] init]];
|
||||
_window.rootViewController = _rootViewController;
|
||||
[_window makeKeyAndVisible];
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,9 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <Preferences/PSListController.h>
|
||||
#import <Preferences/PSSpecifier.h>
|
||||
|
||||
@interface TSPHRootViewController : PSListController
|
||||
{
|
||||
UIAlertController* _activityController;
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,218 @@
|
||||
#import "TSPHRootViewController.h"
|
||||
#import "../Helper/Shared.h"
|
||||
#import "../Store/TSUtil.h"
|
||||
|
||||
@implementation TSPHRootViewController
|
||||
|
||||
- (void)loadView
|
||||
{
|
||||
[super loadView];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadSpecifiers) name:UIApplicationWillEnterForegroundNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)startActivity:(NSString*)activity
|
||||
{
|
||||
if(_activityController) return;
|
||||
|
||||
_activityController = [UIAlertController alertControllerWithTitle:activity message:@"" preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIActivityIndicatorView* activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(5,5,50,50)];
|
||||
activityIndicator.hidesWhenStopped = YES;
|
||||
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium;
|
||||
[activityIndicator startAnimating];
|
||||
[_activityController.view addSubview:activityIndicator];
|
||||
|
||||
[self presentViewController:_activityController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)stopActivityWithCompletion:(void (^)(void))completion
|
||||
{
|
||||
if(!_activityController) return;
|
||||
|
||||
[_activityController dismissViewControllerAnimated:YES completion:^
|
||||
{
|
||||
_activityController = nil;
|
||||
if(completion)
|
||||
{
|
||||
completion();
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (NSMutableArray*)specifiers
|
||||
{
|
||||
if(!_specifiers)
|
||||
{
|
||||
_specifiers = [NSMutableArray new];
|
||||
|
||||
PSSpecifier* infoGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
||||
infoGroupSpecifier.name = @"Info";
|
||||
[_specifiers addObject:infoGroupSpecifier];
|
||||
|
||||
PSSpecifier* infoSpecifier = [PSSpecifier preferenceSpecifierNamed:@"TrollStore"
|
||||
target:self
|
||||
set:nil
|
||||
get:@selector(getTrollStoreInfoString)
|
||||
detail:nil
|
||||
cell:PSTitleValueCell
|
||||
edit:nil];
|
||||
infoSpecifier.identifier = @"info";
|
||||
[infoSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
|
||||
[_specifiers addObject:infoSpecifier];
|
||||
|
||||
PSSpecifier* utilitiesGroupSpecifier = [PSSpecifier emptyGroupSpecifier];
|
||||
[_specifiers addObject:utilitiesGroupSpecifier];
|
||||
|
||||
if(trollStoreAppPath())
|
||||
{
|
||||
PSSpecifier* refreshAppRegistrationsSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Refresh App Registrations"
|
||||
target:self
|
||||
set:nil
|
||||
get:nil
|
||||
detail:nil
|
||||
cell:PSButtonCell
|
||||
edit:nil];
|
||||
refreshAppRegistrationsSpecifier.identifier = @"refreshAppRegistrations";
|
||||
[refreshAppRegistrationsSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
refreshAppRegistrationsSpecifier.buttonAction = @selector(refreshAppRegistrations);
|
||||
[_specifiers addObject:refreshAppRegistrationsSpecifier];
|
||||
}
|
||||
else
|
||||
{
|
||||
PSSpecifier* installTrollStoreSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Install TrollStore"
|
||||
target:self
|
||||
set:nil
|
||||
get:nil
|
||||
detail:nil
|
||||
cell:PSButtonCell
|
||||
edit:nil];
|
||||
installTrollStoreSpecifier.identifier = @"installTrollStore";
|
||||
[installTrollStoreSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
installTrollStoreSpecifier.buttonAction = @selector(installTrollStorePressed);
|
||||
[_specifiers addObject:installTrollStoreSpecifier];
|
||||
}
|
||||
|
||||
if(![NSBundle.mainBundle.bundleIdentifier hasPrefix:@"com.opa334."])
|
||||
{
|
||||
[_specifiers addObject:[PSSpecifier emptyGroupSpecifier]];
|
||||
|
||||
PSSpecifier* uninstallPersistenceHelperSpecifier = [PSSpecifier preferenceSpecifierNamed:@"Uninstall Persistence Helper"
|
||||
target:self
|
||||
set:nil
|
||||
get:nil
|
||||
detail:nil
|
||||
cell:PSButtonCell
|
||||
edit:nil];
|
||||
uninstallPersistenceHelperSpecifier.identifier = @"uninstallPersistenceHelper";
|
||||
[uninstallPersistenceHelperSpecifier setProperty:@YES forKey:@"enabled"];
|
||||
[uninstallPersistenceHelperSpecifier setProperty:NSClassFromString(@"PSDeleteButtonCell") forKey:@"cellClass"];
|
||||
uninstallPersistenceHelperSpecifier.buttonAction = @selector(uninstallPersistenceHelperPressed);
|
||||
[_specifiers addObject:uninstallPersistenceHelperSpecifier];
|
||||
}
|
||||
}
|
||||
|
||||
[(UINavigationItem *)self.navigationItem setTitle:@"TrollStore Helper"];
|
||||
return _specifiers;
|
||||
}
|
||||
|
||||
- (NSString*)getTrollStoreInfoString
|
||||
{
|
||||
NSString* trollStore = trollStoreAppPath();
|
||||
if(!trollStore)
|
||||
{
|
||||
return @"Not Installed";
|
||||
}
|
||||
else
|
||||
{
|
||||
NSBundle* trollStoreBundle = [NSBundle bundleWithPath:trollStore];
|
||||
NSString* version = [trollStoreBundle objectForInfoDictionaryKey:@"CFBundleVersion"];
|
||||
return [NSString stringWithFormat:@"Installed, %@", version];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)refreshAppRegistrations
|
||||
{
|
||||
[self startActivity:@"Refreshing"];
|
||||
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
|
||||
{
|
||||
spawnRoot(helperPath(), @[@"refresh"]);
|
||||
respring();
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
[self stopActivityWithCompletion:nil];
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
- (void)installTrollStorePressed
|
||||
{
|
||||
NSURL* trollStoreURL = [NSURL URLWithString:@"https://github.com/opa334/TrollStore/releases/latest/download/TrollStore.tar"];
|
||||
NSURLRequest* trollStoreRequest = [NSURLRequest requestWithURL:trollStoreURL];
|
||||
|
||||
[self startActivity:@"Installing TrollStore"];
|
||||
|
||||
NSURLSessionDownloadTask* downloadTask = [NSURLSession.sharedSession downloadTaskWithRequest:trollStoreRequest completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error)
|
||||
{
|
||||
if(error)
|
||||
{
|
||||
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:@"Error" message:[NSString stringWithFormat:@"Error downloading TrollStore: %@", error] preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
|
||||
[errorAlert addAction:closeAction];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
[self stopActivityWithCompletion:^
|
||||
{
|
||||
[self presentViewController:errorAlert animated:YES completion:nil];
|
||||
}];
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
int ret = spawnRoot(helperPath(), @[@"install-trollstore", location.path]);
|
||||
dispatch_async(dispatch_get_main_queue(), ^
|
||||
{
|
||||
[self stopActivityWithCompletion:^
|
||||
{
|
||||
[self reloadSpecifiers];
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
respring();
|
||||
}
|
||||
else
|
||||
{
|
||||
UIAlertController* errorAlert = [UIAlertController alertControllerWithTitle:@"Error" message:[NSString stringWithFormat:@"Error installing TrollStore: trollstorehelper returned %d", ret] preferredStyle:UIAlertControllerStyleAlert];
|
||||
UIAlertAction* closeAction = [UIAlertAction actionWithTitle:@"Close" style:UIAlertActionStyleDefault handler:nil];
|
||||
[errorAlert addAction:closeAction];
|
||||
[self presentViewController:errorAlert animated:YES completion:nil];
|
||||
}
|
||||
}];
|
||||
});
|
||||
}
|
||||
}];
|
||||
|
||||
[downloadTask resume];
|
||||
}
|
||||
|
||||
|
||||
- (void)uninstallPersistenceHelperPressed
|
||||
{
|
||||
UIAlertController* uninstallWarningAlert = [UIAlertController alertControllerWithTitle:@"Warning" message:@"Uninstalling the persistence helper will revert this app back to it's original state, you will however no longer be able to persistently refresh the TrollStore app registrations. Continue?" preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil];
|
||||
[uninstallWarningAlert addAction:cancelAction];
|
||||
|
||||
UIAlertAction* continueAction = [UIAlertAction actionWithTitle:@"Continue" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action)
|
||||
{
|
||||
spawnRoot(helperPath(), @[@"uninstall-persistence-helper"]);
|
||||
exit(0);
|
||||
}];
|
||||
[uninstallWarningAlert addAction:continueAction];
|
||||
|
||||
[self presentViewController:uninstallWarningAlert animated:YES completion:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,8 @@
|
||||
Package: com.opa334.trollstorehelper
|
||||
Name: TrollStore Helper
|
||||
Version: 1.0
|
||||
Architecture: iphoneos-arm
|
||||
Description: Helper app to install and manage TrollStore!
|
||||
Maintainer: opa334
|
||||
Author: opa334
|
||||
Section: Utilities
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>application-identifier</key>
|
||||
<string>com.opa334.TrollStore</string>
|
||||
<key>platform-application</key>
|
||||
<true/>
|
||||
<key>com.apple.security.exception.files.absolute-path.read-write</key>
|
||||
<array>
|
||||
<string>/</string>
|
||||
</array>
|
||||
<key>com.apple.private.security.no-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.private.persona-mgmt</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.system-application</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.container-manager</key>
|
||||
<true/>
|
||||
<key>com.apple.private.coreservices.canmaplsdatabase</key>
|
||||
<true/>
|
||||
<key>com.apple.lsapplicationworkspace.rebuildappdatabases</key>
|
||||
<true/>
|
||||
<key>com.apple.private.MobileContainerManager.allowed</key>
|
||||
<true/>
|
||||
<key>com.apple.private.MobileInstallationHelperService.InstallDaemonOpsEnabled</key>
|
||||
<true/>
|
||||
<key>com.apple.private.MobileInstallationHelperService.allowed</key>
|
||||
<true/>
|
||||
<key>com.apple.private.uninstall.deletion</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,10 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TSPHAppDelegate.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
@autoreleasepool {
|
||||
NSBundle* mcmBundle = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/MobileContainerManager.framework"];
|
||||
[mcmBundle load];
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass(TSPHAppDelegate.class));
|
||||
}
|
||||
}
|
||||