From d152a058c485979b75cdd81f27f0a6f718a6d32c Mon Sep 17 00:00:00 2001 From: 82Flex <82flex@gmail.com> Date: Tue, 18 Jun 2024 01:55:27 +0800 Subject: [PATCH] feat: add optional prefs Signed-off-by: 82Flex <82flex@gmail.com> --- .clang-format | 6 + Makefile | 4 +- prefs/Makefile | 16 +++ prefs/Resources/Info.plist | 24 ++++ prefs/Resources/Root.plist | 131 ++++++++++++++++++ .../Resources/en.lproj}/Root.strings | 2 + prefs/Resources/icon.png | Bin 0 -> 3063 bytes prefs/Resources/icon@2x.png | Bin 0 -> 8073 bytes prefs/Resources/icon@3x.png | Bin 0 -> 15144 bytes prefs/Resources/zh_Hans.lproj/Root.strings | 11 ++ prefs/TSPrefsRootListController.h | 5 + prefs/TSPrefsRootListController.m | 58 ++++++++ .../Preferences/TrollSpeedPrefs.plist | 21 +++ sources/HUDRootViewController.mm | 60 +++++++- 14 files changed, 332 insertions(+), 6 deletions(-) create mode 100644 .clang-format create mode 100644 prefs/Makefile create mode 100644 prefs/Resources/Info.plist create mode 100644 prefs/Resources/Root.plist rename {Resources/Settings.bundle/es.lproj => prefs/Resources/en.lproj}/Root.strings (82%) create mode 100644 prefs/Resources/icon.png create mode 100644 prefs/Resources/icon@2x.png create mode 100644 prefs/Resources/icon@3x.png create mode 100644 prefs/Resources/zh_Hans.lproj/Root.strings create mode 100644 prefs/TSPrefsRootListController.h create mode 100644 prefs/TSPrefsRootListController.m create mode 100644 prefs/layout/Library/PreferenceLoader/Preferences/TrollSpeedPrefs.plist diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..eb4c853 --- /dev/null +++ b/.clang-format @@ -0,0 +1,6 @@ +# clang-format +BasedOnStyle: LLVM +IndentWidth: 4 +AccessModifierOffset: -4 +ContinuationIndentWidth: 4 +ColumnLimit: 120 \ No newline at end of file diff --git a/Makefile b/Makefile index 426d942..ff6c79f 100644 --- a/Makefile +++ b/Makefile @@ -36,11 +36,13 @@ TrollSpeed_CODESIGN_FLAGS += -Ssupports/entitlements.plist include $(THEOS_MAKE_PATH)/application.mk +SUBPROJECTS += prefs ifneq ($(FINALPACKAGE),1) SUBPROJECTS += memory_pressure -include $(THEOS_MAKE_PATH)/aggregate.mk endif +include $(THEOS_MAKE_PATH)/aggregate.mk + before-all:: $(ECHO_NOTHING)defaults write $(LAUNCHD_PLIST) ProgramArguments -array "$(THEOS_PACKAGE_INSTALL_PREFIX)/Applications/TrollSpeed.app/TrollSpeed" "-hud" || true$(ECHO_END) $(ECHO_NOTHING)plutil -convert xml1 $(LAUNCHD_PLIST)$(ECHO_END) diff --git a/prefs/Makefile b/prefs/Makefile new file mode 100644 index 0000000..9079039 --- /dev/null +++ b/prefs/Makefile @@ -0,0 +1,16 @@ +ARCHS := arm64 arm64e +TARGET := iphone:clang:15.6:14.0 +INSTALL_TARGET_PROCESSES := Preferences + +include $(THEOS)/makefiles/common.mk + +BUNDLE_NAME += TrollSpeedPrefs + +TrollSpeedPrefs_FILES += TSPrefsRootListController.m +TrollSpeedPrefs_FRAMEWORKS += UIKit +TrollSpeedPrefs_PRIVATE_FRAMEWORKS += Preferences +TrollSpeedPrefs_INSTALL_PATH += /Library/PreferenceBundles +TrollSpeedPrefs_CFLAGS += -fobjc-arc +TrollSpeedPrefs_CFLAGS += -I../supports/ + +include $(THEOS_MAKE_PATH)/bundle.mk diff --git a/prefs/Resources/Info.plist b/prefs/Resources/Info.plist new file mode 100644 index 0000000..4c87111 --- /dev/null +++ b/prefs/Resources/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + TrollSpeedPrefs + CFBundleIdentifier + ch.xxtou.hudapp.prefs + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + NSPrincipalClass + TSPrefsRootListController + + diff --git a/prefs/Resources/Root.plist b/prefs/Resources/Root.plist new file mode 100644 index 0000000..558df27 --- /dev/null +++ b/prefs/Resources/Root.plist @@ -0,0 +1,131 @@ + + + + + items + + + cell + PSGroupCell + label + Custom Font Size + + + cell + PSSwitchCell + default + + defaults + ch.xxtou.hudapp.prefs + key + usesCustomFontSize + label + Uses Custom Font Size + PostNotification + ch.xxtou.notification.hud.reload + + + cell + PSSliderCell + default + 9 + defaults + ch.xxtou.hudapp.prefs + key + realCustomFontSize + label + Custom Font Size + max + 12 + min + 8 + showValue + + PostNotification + ch.xxtou.notification.hud.reload + + + cell + PSGroupCell + label + Custom Offset + + + cell + PSSwitchCell + default + + defaults + ch.xxtou.hudapp.prefs + key + usesCustomOffset + label + Uses Custom Offset + PostNotification + ch.xxtou.notification.hud.reload + + + cell + PSSliderCell + default + 0 + defaults + ch.xxtou.hudapp.prefs + key + realCustomOffsetX + label + Custom Offset X + max + 100 + min + -100 + showValue + + PostNotification + ch.xxtou.notification.hud.reload + + + cell + PSSliderCell + default + 0 + defaults + ch.xxtou.hudapp.prefs + key + realCustomOffsetY + label + Custom Offset Y + max + 100 + min + -100 + showValue + + PostNotification + ch.xxtou.notification.hud.reload + + + cell + PSGroupCell + label + + footerText + Made with ♥ by @Lessica and @jmpews + + + cell + PSButtonCell + label + Reset to Default + action + resetToDefaults: + defaults + ch.xxtou.hudapp.prefs + PostNotification + ch.xxtou.notification.hud.reload + + + title + TrollSpeed + + diff --git a/Resources/Settings.bundle/es.lproj/Root.strings b/prefs/Resources/en.lproj/Root.strings similarity index 82% rename from Resources/Settings.bundle/es.lproj/Root.strings rename to prefs/Resources/en.lproj/Root.strings index 472b507..53dce7d 100644 --- a/Resources/Settings.bundle/es.lproj/Root.strings +++ b/prefs/Resources/en.lproj/Root.strings @@ -7,3 +7,5 @@ "Custom Offset" = "Custom Offset"; "Uses Custom Offset" = "Uses Custom Offset"; + +"Reset to Default" = "Reset to Default"; diff --git a/prefs/Resources/icon.png b/prefs/Resources/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..30c11da630c6c5d55f3c0b7f3ddcd2917a52f7f8 GIT binary patch literal 3063 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 VPiD`){rSNxE2$(=EoKt>e*h$-{2%}T literal 0 HcmV?d00001 diff --git a/prefs/Resources/icon@3x.png b/prefs/Resources/icon@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..82cbf58f7ec5206b4845ad0fbac78072b80049b1 GIT binary patch literal 15144 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 + +@interface TSPrefsRootListController : PSListController + +@end diff --git a/prefs/TSPrefsRootListController.m b/prefs/TSPrefsRootListController.m new file mode 100644 index 0000000..33f3d9d --- /dev/null +++ b/prefs/TSPrefsRootListController.m @@ -0,0 +1,58 @@ +#import +#import + +#import + +#import "TSPrefsRootListController.h" + +@implementation TSPrefsRootListController + +- (NSArray *)specifiers { + if (!_specifiers) { + _specifiers = [self loadSpecifiersFromPlistName:@"Root" target:self]; + } + return _specifiers; +} + +- (id)readPreferenceValue:(PSSpecifier *)specifier { + NSString *containerPath = + [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject]; + NSString *path = [NSString + stringWithFormat:ROOT_PATH_NS("%@/Preferences/%@.plist"), containerPath, specifier.properties[@"defaults"]]; + NSMutableDictionary *settings = [NSMutableDictionary dictionary]; + [settings addEntriesFromDictionary:[NSDictionary dictionaryWithContentsOfFile:path]]; + return (settings[specifier.properties[@"key"]]) ?: specifier.properties[@"default"]; +} + +- (void)setPreferenceValue:(id)value specifier:(PSSpecifier *)specifier { + NSString *containerPath = + [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject]; + NSString *path = [NSString + stringWithFormat:ROOT_PATH_NS("%@/Preferences/%@.plist"), containerPath, specifier.properties[@"defaults"]]; + NSMutableDictionary *settings = [NSMutableDictionary dictionary]; + [settings addEntriesFromDictionary:[NSDictionary dictionaryWithContentsOfFile:path]]; + [settings setObject:value forKey:specifier.properties[@"key"]]; + [settings writeToFile:path atomically:YES]; + CFStringRef notificationName = (__bridge CFStringRef)specifier.properties[@"PostNotification"]; + if (notificationName) { + CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), notificationName, NULL, NULL, + YES); + } +} + +- (void)resetToDefaults:(PSSpecifier *)specifier { + NSString *containerPath = + [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject]; + NSString *path = [NSString + stringWithFormat:ROOT_PATH_NS("%@/Preferences/%@.plist"), containerPath, specifier.properties[@"defaults"]]; + NSMutableDictionary *settings = [NSMutableDictionary dictionary]; + [settings writeToFile:path atomically:YES]; + CFStringRef notificationName = (__bridge CFStringRef)specifier.properties[@"PostNotification"]; + if (notificationName) { + CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), notificationName, NULL, NULL, + YES); + } + [self reloadSpecifiers]; +} + +@end diff --git a/prefs/layout/Library/PreferenceLoader/Preferences/TrollSpeedPrefs.plist b/prefs/layout/Library/PreferenceLoader/Preferences/TrollSpeedPrefs.plist new file mode 100644 index 0000000..e338e97 --- /dev/null +++ b/prefs/layout/Library/PreferenceLoader/Preferences/TrollSpeedPrefs.plist @@ -0,0 +1,21 @@ + + + + + entry + + bundle + TrollSpeedPrefs + cell + PSLinkCell + detail + TSPrefsRootListController + icon + icon.png + isController + + label + TrollSpeed + + + diff --git a/sources/HUDRootViewController.mm b/sources/HUDRootViewController.mm index 925f447..0cb71c8 100644 --- a/sources/HUDRootViewController.mm +++ b/sources/HUDRootViewController.mm @@ -10,6 +10,7 @@ #import #import #import +#import #import "HUDPresetPosition.h" #import "HUDRootViewController.h" @@ -686,11 +687,60 @@ - (void)setCurrentLandscapePositionY:(CGFloat)positionY } #if !NO_TROLL -- (BOOL)usesCustomFontSize { return [GetStandardUserDefaults() boolForKey:HUDUserDefaultsKeyUsesCustomFontSize]; } -- (CGFloat)realCustomFontSize { return [GetStandardUserDefaults() doubleForKey:HUDUserDefaultsKeyRealCustomFontSize]; } -- (BOOL)usesCustomOffset { return [GetStandardUserDefaults() boolForKey:HUDUserDefaultsKeyUsesCustomOffset]; } -- (CGFloat)realCustomOffsetX { return [GetStandardUserDefaults() doubleForKey:HUDUserDefaultsKeyRealCustomOffsetX]; } -- (CGFloat)realCustomOffsetY { return [GetStandardUserDefaults() doubleForKey:HUDUserDefaultsKeyRealCustomOffsetY]; } +#define PREFS_PATH "/var/mobile/Library/Preferences/ch.xxtou.hudapp.prefs.plist" + +- (NSDictionary *)extraUserDefaultsDictionary { + static BOOL isJailbroken = NO; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + isJailbroken = [[NSFileManager defaultManager] + fileExistsAtPath:ROOT_PATH_NS("/Library/PreferenceBundles/TrollSpeedPrefs.bundle")]; + }); + if (!isJailbroken) { + return nil; + } + return [NSDictionary dictionaryWithContentsOfFile:ROOT_PATH_NS(PREFS_PATH)]; +} + +- (BOOL)usesCustomFontSize { + NSDictionary *extraUserDefaults = [self extraUserDefaultsDictionary]; + if (extraUserDefaults) { + return [extraUserDefaults[HUDUserDefaultsKeyUsesCustomFontSize] boolValue]; + } + return [GetStandardUserDefaults() boolForKey:HUDUserDefaultsKeyUsesCustomFontSize]; +} + +- (CGFloat)realCustomFontSize { + NSDictionary *extraUserDefaults = [self extraUserDefaultsDictionary]; + if (extraUserDefaults) { + return [extraUserDefaults[HUDUserDefaultsKeyRealCustomFontSize] doubleValue]; + } + return [GetStandardUserDefaults() doubleForKey:HUDUserDefaultsKeyRealCustomFontSize]; +} + +- (BOOL)usesCustomOffset { + NSDictionary *extraUserDefaults = [self extraUserDefaultsDictionary]; + if (extraUserDefaults) { + return [extraUserDefaults[HUDUserDefaultsKeyUsesCustomOffset] boolValue]; + } + return [GetStandardUserDefaults() boolForKey:HUDUserDefaultsKeyUsesCustomOffset]; +} + +- (CGFloat)realCustomOffsetX { + NSDictionary *extraUserDefaults = [self extraUserDefaultsDictionary]; + if (extraUserDefaults) { + return [extraUserDefaults[HUDUserDefaultsKeyRealCustomOffsetX] doubleValue]; + } + return [GetStandardUserDefaults() doubleForKey:HUDUserDefaultsKeyRealCustomOffsetX]; +} + +- (CGFloat)realCustomOffsetY { + NSDictionary *extraUserDefaults = [self extraUserDefaultsDictionary]; + if (extraUserDefaults) { + return [extraUserDefaults[HUDUserDefaultsKeyRealCustomOffsetY] doubleValue]; + } + return [GetStandardUserDefaults() doubleForKey:HUDUserDefaultsKeyRealCustomOffsetY]; +} #else - (BOOL)usesCustomFontSize { return NO; } - (CGFloat)realCustomFontSize { return HUD_FONT_SIZE; }