%88z)s7ig@VBxvN6^I?8A2$b8tVD0bKm0!i57tAFljAuGXP7d3$(&z
z>Zn{vq&)`<0vRYVb377fCtDj$}CKBLty&DL$*BW!ic%IHYhQCLo8A
zi%)|+p_EaG7E+LQhxg&OY<{2~c-kk|X-)bJ+>DG!f|j-N8L0pky~Ue2JHQ6oS9@$As>o-gbczP%0|6H}D(1sNzw8G);+sop
z!>DO27XjzMXF7nSl$vy<|7cGexT0?hi7J1in*ZiaKS{uX;B9;B`^?Ed=D5?!Xr@d5
zXG#p~)>l;Dex%L2mN3qw4_yqh?bVW|r@cFs*%6G%iGOXu?|^Kd0;o!J1MUvRZ01tu
zgO+tdQ49$x5@qdjm8eA1wvH85sVAh+$g4SOkd`Rir95jJRsB3jSHqPJ*$Te(^z~f+
z^Pp1Kt#k+_T)lVO?DS27H6MyV+A-JnL3dkbEIJ~@`SWnKaUvIt{4`||j|vkULGYw^
z*wdD`bfrXHu38k@FA{W!;t*Nfa+(8;+RFm|0mFh`{e>uRqnMn=SI
zSe?hr0Cx1Nn(>Xs%k7s9f0Ifd0rN*X+BcggY9AMKK_FBkJefz_{)T=pnITH#?-|5t
zj1P?&vUstX#Q_MWMGA#Dk{xf+smB)Zlh{eO3(-4HkMU5xek?*fu3tYas4Gz(RbYxK
ze5J8bQqfKN5SEl@p^cTEt5m)J6!QFi90s6t*a$MB7;)^46Ai=v~?7gGdDR6*LTX@turGZ$C1g6kbm
zh9ig+znlmlv1sGj@!YdBifF%76~`T2x*v=C^Ny%NtqfY6&IU{PmvWoz-e{ii=BOrR
zGOM4#65R??ClzMsf9gZ+ih=l{7Vh>{D=z17nn7+t2Mb_t3wpOZ@?t|H{GB|gYx-=V
zhZ2}Scnahjy7Db@jGPom`4>T}`8#>PEx39NKc*i*je|dH&4wG|AR*JQ!5T7=fcKg(
zCT(Rn*N?~6Yi`1@^$8lCmEZ0wcNm0p#};uo+c13MNSTQ>coLvLrvEgCXOgB}$b2pzu|
zW9ZkVw3L#dWcDJPvMbVYOPd!bIf*;mv~HzxD2@G*J3qE&b2@Z8cWm>0`4hsg#5}F-
z5XuaeX7f^I_(!^*R43fj^MY~e54ge;34zXQKe^=JEH9wVn|T1d$}q^>f|TDl1aWSXEIUW8(r?p)}#jI(N1LQK8|ZY{DwG^YOI+
z;$V5#IEy6gL_Gh{qaA@$NIW%5bXE3SmXKFOfPjOF-Lh$GG;cNiA5
zk`~`U5$<)`9Hl{=VZiv9>lcIfEnaiNRzaAMg`3}HAeqqLD|y)Jnz8pnbqPnS@`m}g
zbvJLFo8Wb4EJ&)`@Dk+pDf{)=?U;Hr1R?#{u~TPSE0&t+)0)DPrgn$ZnNmnDDlkWy
zdIel}CN@qQ62T(!-FXp$U*P22SI`GbY5`$xVk~+_@L)LeC}}F}mj_g*ZJtXnLALz-s7n8A1_6
ze@8?A&C^D|h_yoAWfCQvL2YT~<~x9)PkV(+?*>{v>V?^gPx&@Kt1eFG
zu?_Vl9YCwv!1FOOn}(V=$mD?TL#-Q}6-Rxt2>2qO#^%rrx6*qpEg(l~uq@F3{%c0x
zw}ijJE3RcS9gk;c@q>q8fSR#DY4wRy=HxtXLPT?k%F`Z;Pf#V>)!DW{bjaporVY7G
zI~Cm+c#D#^xtYtl#;qa3RVP?ai6L1dj8t=~O
zeC(U&3n--5)Y<#h+<7PeA^)LSz!Jj%BZk5(J#)UQK(KY+Z{Bz;Xm^;);q8tz^V|C}BHf->G(huoo{M8t)E-Z9Uklt@n9|U4*A|!p
z@UTuC6GTSWgam%Y7K$q$V{kzbCH$QE2JpW@3b@O5a=Fctnn`K$>4C5B+{N?Rhb=TP
ztMTH59MGoxN?>E}ac!Q9O2`rkzWW}nlYjX|ksG(2+PE<23=Z2=PQgle5YwBdQfSyv
zK&uS-)}uB1YL)7Ormpi)k2mdf24DK$H{1)+82anO|AcqAd#YC#Z!^b
zYOn{@cb#Yk^gKjFsjD~a(-U1^&N=8ip!}v>m@22I*E0WOkdp~7+cT)N~Mij`f*&_S8}3}$?KUYqAbc|A>C
zhAuiA7h94BZERoeD~5h{m`;~4zJ4V|#&o8f-KMvFE&y-fysi2W^KMr_eke~b>RF{t
zTpGh3hk&)G44YGZVquWhM9SPQIdBA-Ek~nzdiM0_ItzXrJAS7Z^ZCntLw7GZ?J6|#
zw3SZsg)@)SwJ6UEjtAx83xyXJ%msE?+(7+1MV)m9UF%Ztx8p`<)=^=TbgIb1^|-?f
z-XyvvKh+t*c`+M#((b_~{Df;|tYxY<=zffi#P^#_m>+SWDHE&|(d@wjU$0OY4QXdg
z9`?uWUU5}pV?}kl`sYIP4nxQ|-vt}e)6#0ZBP4gTvYR$6JWGvJC2vF~*aE^hX7S@4)7ALAYZOAe#B0&GMV>cs1+nz~>hrbv#v$aOiQ$tX@Q}b7!J9t^
zaOlGfvlTLITw|RUtwN>qiKSEA!GU0qx0;l|(ynoZVXBeziKmK)@!PnZ14VE#_B<{O
z-`G9(JDd1aaw+7r3H>j8)y`&4(AO@A?%0jei%a;E@Q
zcTZExZbHY3UEF0UKCJ$rNFS&?w2G5=(<$FNzyu83*N7k7Hde_ljwbqti7yJ8)7{Pw
zyUv+hBR;NK_+uKycpI%W>C+HHaQ%0_s8Z$RaQ38Hh<{n$5wV9h_+xmznw-Ud>H2M
z-e)u>)$@k$zROF(Mc?d{vVm}CMu>EIV2vno6eD#0tO7QUetz@%9J9GH4A-MfaY%-?
zp<>gZNLh%C^}Jy{slZoM7I0ykNs+2SWN7`JSaS=yO7GV8ju+51ca8DR_%S*^??fG!
z8`h?16Fs_+hAcvkeRNEY(3Xjgt*l*3YhOiRnbX+XTOR7!kT3~%`3k4qTcl6dnwp!s
znt0L&zl#dxQH*b)o3=3?Wy`eKSBSXhC&1h8(&^YWcH8)cpP)s4#nF@%xO!9B(@mB4
z3JX}KDUm%Povr=+HcJsX@l)nrnz5`*QBl1%9MA)7nns|4A$pP3c^Oal>`9Ni2RKyG
zG3y1EDt<95t(d0VW^$pox%q0_M9iF+)UKCQD>u)a*#$-0t=R9uAK4Zy<;!9kocibf
zRs?$bD`h`~8LexMhYX3Cfpk@j%wqqv+PIaDk;lEDDyA?u6KIuHv_H86XM8*Z<~hTb
z{|#=zXNe*8}fLrEo+scaP=k61;xwy!VoAuX?!b_dgaT89@YJcjIrMIhIkEDA$4K
z*Dw?F5RYld2(P!m&Qum>B2*D6r|(B9N`_4?)gML4V`{6pm_MRR2@ohKi_?#2gy}Rm
zyO!dnaVX(LQC@v71n$v_pqT2GJyTB@ox~gs9G%9qQAujL{(iwjqvHWTng0r
z#VTr%uSCR>R%=oIz{NaQ}-iEu9FZe7bikVy0Y|PSGh=OOqlM
zPpN4^37%|2Dn30+-HJ^g*OI^*#6ZZ2ru|MytidrD=4JIzn!Ff({}RUCAhdWnDDDE&
zdz_ArQa*yM&Fyoy3*Br*;xlCLjk?U4jGtC|fFib=SP{?mKyvBsXkg{ONhf|`XHyZ^
z(a*1*-G8^2cm@Lb$uFgql~8^Lf&(}E_dF9D{0Aqe9{oC!t?+!$yBqJW{D7^Ey2G8~
z0(usD`+_VpP*P5(9>@tqwen7{-NP&dr)fE$b^<@umf@eJ91}p)9xD|
zz_mJyX32#o+>Lc9HyyN~lnSsVz&Y38X?h8%OvH~PT}|(p!Xtsa-aLgeCHZ!~#~*fH
z3!hIY9(PMx+nk#lyApbc0I(i2SiL0zOnEqf+-exIO*?prvhFros8?3lycO^BNA#e=
zx2(%i^4(&v-)Lcimbh@1D#+be^U>`aZO2cd(NjoJViKa@9t%x8^OYBs8KvlVvx|CxZ1g#9_}Tjv8B;(o7kYziUkk>_&`YW&+t(qOH^|dS--?i^0_O&@te^<|>4KGW
za3-1wl|=eucAC%P0!+ctrZ(x=Do@LL{OoWoVxWFdJBPX#pN!^A*S#i0`vA#FP+&=Z
z+00dXsSXDNABV~6ldH01hFYq;n2*tr@$v|`hQaSV7=5-vX#6b&<)*0h?58P+tbshT
z+XF8$cQh1atv_w{M>Tdsl=2Z7vq;97%w~1p3um)}wY?i{OjEawJ=N~YQ@z4g7Qw~Rm!>-I&e~DR|@)ZC(A|^??rA
ztvIp#HVFDasXFs4myufwT2zGV`}LV^{6XLtB9M&dR
z0H$wtt6>!jBqs(sXt8xp2c~LEG4U7;y;5RA^jQz;VRPquUiJ6Hw*Vy9eUyMlrH#iV
zkFLU=PN$tq(=Zl+!k-RV_@M=5K%^UZtBiV?b1xvK4OX~IRE5G~g=tK>@GNC&J7<%n
zEzdCqrjOCz>Pj)!Eqo;b>E{;lx7K$VHxXK7_cH6}!X)3J4~4!W4B$T{{U
zB$2p=0squfLHkA_LZwX!4i{S3dnML|00eVz%m|#UoZW9*1Yas2-(XkVCT8-n$0A82
zITD@PdERoD-wxtqW*k12u115tO2WB(EJRkMHQzSmIZbY1#S~S-mlW@{GZk}JSNg=|
zE~1|CE5*koWM*@97D0{7FT1e5p+O=ZE2!|H^5un69COP$m8B@AXS?c@icRtVK$5;V
zPxp-=^CDQ!?wH#kp=HagLfk)UbxsBW8~s)WN2H)M>(9vvtl=3eZ3<2TBiJ-i>X^<2
zHvw{+3$|dR0yMU#ChvZ)=MI;f*KvHx}y!GlD#!MU|i{RG<>0fD7>Ke=a>B3$QDg42-oBCelp3C%0_0P0~Y7KUX
z&Kw*IOu7(MsRXVz==SGQ8;|EAExZElEQ%Gnvd%wgp=!o1o^b3x^B&)FN@@pdzIM$N
zPniVZKMJ1nknYt4JOnM@_GE1|yE>l#4z1&KQLM3P2quAp)^ua-~N?8B$9npe}-3M5^q(rUkAjPso=5{
zQUish#X0LDo7g?rucf8+vcZ&k{c;3*@|Sz
zs;e*4H=ju3faH@)#d&$!^R44DKIrNn*@#>o
zf3N
zvaDrCXZ*~OqFW||G+d2+?Fug^
zIoE8xfxf<;Oz45FWWtgLKjDA
+
+@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; }