Merge pull request #76 from leminlimez/18_1-beta5

v4.0
This commit is contained in:
leminlimez
2024-10-28 10:43:44 -04:00
committed by GitHub
17 changed files with 4258 additions and 692 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -1,11 +1,11 @@
# Nugget
Unlock your device's full potential! Works on all versions iOS 17.0-18.1 beta 4
Unlock your device's full potential!
Sparserestore was patched in iOS 18.1 beta 5. It will not be supported, please stop asking.
Sparserestore works on all versions iOS 17.0-17.7 and iOS 18.0-18.1 beta 4. There is partial support for iOS 17.7.1 and iOS 18.1 beta 5+.
This uses the sparserestore exploit to write to files outside of the intended restore location, like mobilegestalt.
Note: I am not responsible if your device bootloops. Please back up your data before using.
Note: I am not responsible if your device bootloops. Please back up your data before using!
## Features
- Enable Dynamic Island on any device
@@ -27,14 +27,20 @@ Note: I am not responsible if your device bootloops. Please back up your data be
- Enabling lock screen clock animation, lock screen page duplication button, and more!
- Disabling the new iOS 18 Photos UI
- EU Enabler
- AI Enabler
- Springboard Options (from Cowabunga Lite)
- Internal Options (from Cowabunga Lite)
## Running the Program
Requirements:
**Requirements:**
- pymobiledevice3
- Python 3.8 or newer
- **Windows:**
- Either [Apple Devices (from Microsoft Store)](https://apps.microsoft.com/detail/9np83lwlpz9k%3Fhl%3Den-US%26gl%3DUS&ved=2ahUKEwjE-svo7qyJAxWTlYkEHQpbH3oQFnoECBoQAQ&usg=AOvVaw0rZTXCFmRaHAifkEEu9tMI) app or [iTunes (from Apple website)](https://support.apple.com/en-us/106372)
- **Linux:**
- [usbmuxd](https://github.com/libimobiledevice/usbmuxd) and [libimobiledevice](https://github.com/libimobiledevice/libimobiledevice)
Note: It is highly recommended to use a virtual environment:
```
python3 -m venv .env # only needed once
@@ -67,4 +73,5 @@ The application itself can be compiled by running `compile.py`.
- [JJTech](https://github.com/JJTech0130) for Sparserestore/[TrollRestore](https://github.com/JJTech0130/TrollRestore)
- [pymobiledevice3](https://github.com/doronz88/pymobiledevice3)
- [disfordottie](https://x.com/disfordottie) for some global flag features
- [sneakyf1shy](https://github.com/f1shy-dev) for [AI Enabler](https://gist.github.com/f1shy-dev/23b4a78dc283edd30ae2b2e6429129b5)

View File

@@ -9,6 +9,13 @@ from pymobiledevice3.lockdown import LockdownClient
from . import backup
def reboot_device(reboot: bool = False, lockdown_client: LockdownClient = None):
if reboot and lockdown_client != None:
print("Success! Rebooting your device...")
with DiagnosticsService(lockdown_client) as diagnostics_service:
diagnostics_service.restart()
print("Remember to turn Find My back on!")
def perform_restore(backup: backup.Backup, reboot: bool = False, lockdown_client: LockdownClient = None):
try:
with TemporaryDirectory() as backup_dir:
@@ -18,6 +25,8 @@ def perform_restore(backup: backup.Backup, reboot: bool = False, lockdown_client
lockdown_client = create_using_usbmux()
with Mobilebackup2Service(lockdown_client) as mb:
mb.restore(backup_dir, system=True, reboot=False, copy=False, source=".")
# reboot the device
reboot_device(reboot, lockdown_client)
except PyMobileDevice3Exception as e:
if "Find My" in str(e):
print("Find My must be disabled in order to use this tool.")
@@ -26,8 +35,4 @@ def perform_restore(backup: backup.Backup, reboot: bool = False, lockdown_client
elif "crash_on_purpose" not in str(e):
raise e
else:
if reboot and lockdown_client != None:
print("Success! Rebooting your device...")
with DiagnosticsService(lockdown_client) as diagnostics_service:
diagnostics_service.restart()
print("Remember to turn Find My back on!")
reboot_device(reboot, lockdown_client)

View File

@@ -3,12 +3,81 @@ from pymobiledevice3.lockdown import LockdownClient
import os
class FileToRestore:
def __init__(self, contents: str, restore_path: str, owner: int = 501, group: int = 501):
def __init__(self, contents: str, restore_path: str, domain: str = None, owner: int = 501, group: int = 501):
self.contents = contents
self.restore_path = restore_path
self.domain = domain
self.owner = owner
self.group = group
def concat_exploit_file(file: FileToRestore, files_list: list[FileToRestore], last_domain: str) -> str:
base_path = "/var/backup"
# set it to work in the separate volumes (prevents a bootloop)
if file.restore_path.startswith("/var/mobile/"):
# required on iOS 17.0+ since /var/mobile is on a separate partition
base_path = "/var/mobile/backup"
elif file.restore_path.startswith("/private/var/mobile/"):
base_path = "/private/var/mobile/backup"
elif file.restore_path.startswith("/private/var/"):
base_path = "/private/var/backup"
# don't append the directory if it has already been added (restore will fail)
path, name = os.path.split(file.restore_path)
domain_path = f"SysContainerDomain-../../../../../../../..{base_path}{path}/"
new_last_domain = last_domain
if last_domain != domain_path:
files_list.append(backup.Directory(
"",
f"{domain_path}/",
owner=file.owner,
group=file.group
))
new_last_domain = domain_path
files_list.append(backup.ConcreteFile(
"",
f"{domain_path}/{name}",
owner=file.owner,
group=file.group,
contents=file.contents
))
return new_last_domain
def concat_regular_file(file: FileToRestore, files_list: list[FileToRestore], last_domain: str, last_path: str):
path, name = os.path.split(file.restore_path)
paths = path.split("/")
new_last_domain = last_domain
# append the domain first
if last_domain != file.domain:
files_list.append(backup.Directory(
"",
file.domain,
owner=file.owner,
group=file.group
))
new_last_domain = file.domain
# append each part of the path if it is not already there
full_path = ""
for path_item in paths:
if full_path != "":
full_path += "/"
full_path += path_item
if not last_path.startswith(full_path):
files_list.append(backup.Directory(
full_path,
file.domain,
owner=file.owner,
group=file.group
))
last_path = full_path
# finally, append the file
files_list.append(backup.ConcreteFile(
f"{full_path}/{name}",
file.domain,
owner=file.owner,
group=file.group,
contents=file.contents
))
return new_last_domain, full_path
# files is a list of FileToRestore objects
def restore_files(files: list, reboot: bool = False, lockdown_client: LockdownClient = None):
# create the files to be backed up
@@ -17,35 +86,18 @@ def restore_files(files: list, reboot: bool = False, lockdown_client: LockdownCl
sorted_files = sorted(files, key=lambda x: x.restore_path, reverse=True)
# add the file paths
last_domain = ""
last_path = ""
exploit_only = True
for file in sorted_files:
base_path = "/var/backup"
# set it to work in the separate volumes (prevents a bootloop)
if file.restore_path.startswith("/var/mobile/"):
# required on iOS 17.0+ since /var/mobile is on a separate partition
base_path = "/var/mobile/backup"
elif file.restore_path.startswith("/private/var/mobile/"):
base_path = "/private/var/mobile/backup"
elif file.restore_path.startswith("/private/var/"):
base_path = "/private/var/backup"
# don't append the directory if it has already been added (restore will fail)
path, name = os.path.split(file.restore_path)
domain_path = f"SysContainerDomain-../../../../../../../..{base_path}{path}/"
if last_domain != domain_path:
files_list.append(backup.Directory(
"",
f"{domain_path}/",
owner=file.owner,
group=file.group
))
last_domain = domain_path
files_list.append(backup.ConcreteFile(
"",
f"{domain_path}/{name}",
owner=file.owner,
group=file.group,
contents=file.contents
))
files_list.append(backup.ConcreteFile("", "SysContainerDomain-../../../../../../../.." + "/crash_on_purpose", contents=b""))
if file.domain == None:
last_domain = concat_exploit_file(file, files_list, last_domain)
else:
last_domain, last_path = concat_regular_file(file, files_list, last_domain, last_path)
exploit_only = False
# crash the restore to skip the setup (only works for exploit files)
if exploit_only:
files_list.append(backup.ConcreteFile("", "SysContainerDomain-../../../../../../../.." + "/crash_on_purpose", contents=b""))
# create the backup
back = backup.Backup(files=files_list)
@@ -53,6 +105,7 @@ def restore_files(files: list, reboot: bool = False, lockdown_client: LockdownCl
perform_restore(backup=back, reboot=reboot, lockdown_client=lockdown_client)
# DEPRICATED
def restore_file(fp: str, restore_path: str, restore_name: str, reboot: bool = False, lockdown_client: LockdownClient = None):
# open the file and read the contents
contents = open(fp, "rb").read()

View File

@@ -1,233 +0,0 @@
from Sparserestore.restore import restore_files, FileToRestore, restore_file
from tweaks.tweaks import tweaks, TweakModifyType, FeatureFlagTweak, EligibilityTweak, AITweak, BasicPlistTweak, RdarFixTweak
from tweaks.basic_plist_locations import FileLocationsList
from devicemanagement.constants import Device
from pymobiledevice3.exceptions import PyMobileDevice3Exception
from pymobiledevice3.services.diagnostics import DiagnosticsService
from pymobiledevice3 import usbmux
from pymobiledevice3.lockdown import create_using_usbmux
from pathlib import Path
import plistlib
import traceback
running = True
passed_check = False
num_tweaks = len(tweaks)
gestalt_path = Path.joinpath(Path.cwd(), "com.apple.MobileGestalt.plist")
flags_path = Path.joinpath(Path.cwd(), "Global.plist")
device = None
def print_option(num: int, active: bool, message: str):
txt = str(num) + ". "
if active:
txt = txt + "[Y] "
txt = txt + message
print(txt)
def get_apply_number(num: int) -> int:
return num + 5-num%5
while running:
print("""\n\n\n\n
,--.
,--.'| ___
,--,: : | ,--.'|_
,`--.'`| ' : ,--, | | :,'
| : : | | ,'_ /| ,----._,. ,----._,. : : ' :
: | \\ | : .--. | | : / / ' / / / ' / ,---. .;__,' /
| : ' '; |,'_ /| : . || : || : | / \\ | | |
' ' ;. ;| ' | | . .| | .\\ .| | .\\ . / / |:__,'| :
| | | \\ || | ' | | |. ; '; |. ; '; |. ' / | ' : |__
' : | ; .': | : ; ; |' . . |' . . |' ; /| | | '.'|
| | '`--' ' : `--' \\`---`-'| | `---`-'| |' | / | ; : ;
' : | : , .-./.'__/\\_: | .'__/\\_: || : | | , /
; |.' `--`----' | : : | : : \\ \\ / ---`-'
'---' \\ \\ / \\ \\ / `----'
`--`-' `--`-'
""")
print("CLI v3.0")
print("by LeminLimez")
print("Thanks @disfordottie for the clock animation and @lrdsnow for EU Enabler\n")
print("Please back up your device before using!")
while device == None:
connected_devices = usbmux.list_devices()
# Connect via usbmuxd
for current_device in connected_devices:
if current_device.is_usb:
try:
ld = create_using_usbmux(serial=current_device.serial)
vals = ld.all_values
device = Device(uuid=current_device.serial, name=vals['DeviceName'], version=vals['ProductVersion'], model=vals['ProductType'], locale=ld.locale, ld=ld)
tweaks["RdarFix"].get_rdar_mode()
except Exception as e:
print(traceback.format_exc())
input("Press Enter to continue...")
if device == None:
print("Please connect your device and try again!")
input("Press Enter to continue...")
print(f"Connected to {device.name}\niOS {device.version}\n")
if not passed_check and Path.exists(gestalt_path) and Path.is_file(gestalt_path):
passed_check = True
if passed_check:
count = 0
for key in tweaks:
count += 1
# do not show if the tweak is not compatible
if tweaks[key].is_compatible(device.version):
print_option(count, tweaks[key].enabled, tweaks[key].label)
if tweaks[key].divider_below:
print()
# apply will still be the number of tweaks just to keep consistency
print(f"\n{get_apply_number(num_tweaks + 1)}. Apply")
print(f"{get_apply_number(num_tweaks + 1) + 1}. Remove All Tweaks")
print(f"{get_apply_number(num_tweaks + 1) + 2}. Reset Mobile Gestalt")
print("0. Exit\n")
page = int(input("Enter a number: "))
if page == get_apply_number(num_tweaks + 1) or page == get_apply_number(num_tweaks + 1) + 1:
# either apply or reset tweaks
print()
resetting = page == (get_apply_number(num_tweaks + 1) + 1)
# set the tweaks and apply
# first open the file in read mode
with open(gestalt_path, 'rb') as in_fp:
gestalt_plist = plistlib.load(in_fp)
# create the other plists
flag_plist: dict = {}
eligibility_files = None
ai_file = None
basic_plists: dict = {}
# verify the device credentials before continuing
if gestalt_plist["CacheExtra"]["qNNddlUK+B/YlooNoymwgA"] != device.version or gestalt_plist["CacheExtra"]["0+nc/Udy4WNG8S+Q7a/s1A"] != device.model:
print("com.apple.mobilegestalt.plist does not match the device!")
print("Please make sure you are using the correct file!")
print("If you believe this is a mistake, you can override this check.")
override = input("Do you want to overrride? (y/n) ")
if override.lower() != 'y':
continue # break applying and return to the main page
# set the plist keys
if not resetting:
for tweak in tweaks.values:
if isinstance(tweak, FeatureFlagTweak):
flag_plist = tweak.apply_tweak(flag_plist)
elif isinstance(tweak, EligibilityTweak):
tweak.set_region_code(device.locale[-2:])
eligibility_files = tweak.apply_tweak()
elif isinstance(tweak, AITweak):
ai_file = tweak.apply_tweak()
elif isinstance(tweak, BasicPlistTweak) or isinstance(tweak, RdarFixTweak):
basic_plists = tweak.apply_tweak(basic_plists)
else:
gestalt_plist = tweak.apply_tweak(gestalt_plist)
# create the restore file list
files_to_restore = [
FileToRestore(
contents=plistlib.dumps(gestalt_plist),
restore_path="/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library/Caches/com.apple.MobileGestalt.plist",
),
FileToRestore(
contents=plistlib.dumps(flag_plist),
restore_path="/var/preferences/FeatureFlags/Global.plist",
)
]
if eligibility_files != None:
files_to_restore += eligibility_files
if ai_file != None:
files_to_restore.append(ai_file)
for location, plist in basic_plists.items():
files_to_restore.append(FileToRestore(
contents=plistlib.dumps(plist),
restore_path=location.value
))
# reset basic tweaks
if resetting:
empty_data = plistlib.dumps({})
for location in FileLocationsList:
files_to_restore.append(FileToRestore(
contents=empty_data,
restore_path=location.value
))
# restore to the device
try:
restore_files(files=files_to_restore, reboot=True, lockdown_client=device.ld)
except Exception as e:
print(traceback.format_exc())
finally:
input("Press Enter to exit...")
running = False
elif page == get_apply_number(num_tweaks + 1) + 2:
# reset mobilegestalt
# restore to the device
try:
restore_files(files=[FileToRestore(
contents=b"",
restore_path="/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library/Caches/com.apple.MobileGestalt.plist",
)], reboot=True, lockdown_client=device.ld)
except Exception as e:
print(traceback.format_exc())
finally:
input("Press Enter to exit...")
running = False
elif page == 0:
# exit the panel
print("Goodbye!")
running = False
else:
tweak = list(tweaks.values())[page-1]
if page > 0 and page <= num_tweaks and tweak.is_compatible(device.version):
if tweak.edit_type == TweakModifyType.TEXT:
# text input
inp_txt = ""
print(f"\n\n{tweak.label}")
print("Leave blank to turn off.\n")
if tweak.label == "Set Device Model Name":
inp_txt = "Enter Model Name: "
elif tweak.label == "Set Lock Screen Footnote Text":
inp_txt = "Enter Footnote: "
new_txt = input(inp_txt)
if new_txt == "":
tweak.set_enabled(False)
else:
tweak.set_value(new_txt)
elif tweak.edit_type == TweakModifyType.PICKER:
# pick between values
print("\n\nSelect a value.")
print("If you do not know which to try, start with the first option.")
values = tweak.value
for option in range(len(values)):
print_option(
num=option+1,
active=(tweak.enabled and tweak.get_selected_option() == option),
message=str(values[option])
)
print_option(num=len(values)+1, active=(not tweak.enabled), message="Disable")
picker_choice = int(input("Select option: "))
if picker_choice > 0 and picker_choice <= len(values):
tweak.set_selected_option(picker_choice-1)
tweaks["RdarFix"].set_di_type(values[tweak.get_selected_option()])
elif picker_choice == len(values)+1:
tweak.set_enabled(False)
else:
tweak.toggle_enabled()
else:
print("No MobileGestalt file found!")
print(f"Please place the file in \'{Path.cwd()}\' with the name \'com.apple.MobileGestalt.plist\'")
print("Remember to make a backup of the file!!\n")
print("1. Retry")
print("2. Enter path\n")
choice = int(input("Enter number: "))
if choice == 2:
new_path = input("Enter new path to file: ")
gestalt_path = Path(new_path)

View File

@@ -11,15 +11,19 @@ class Device:
self.locale = locale
self.ld = ld
def supported(self) -> bool:
def has_exploit(self) -> bool:
parsed_ver: Version = Version(self.version)
if (parsed_ver < Version("17.0")) or (parsed_ver > Version("18.1")):
# make sure versions past 17.7.1 but before 18.0 aren't supported
if (parsed_ver >= Version("17.7.1") and parsed_ver < Version("18.0")):
return False
if (parsed_ver == Version("18.1")
and self.build != "22B5007p" and self.build == "22B5023e"
and self.build == "22B5034e" and self.build == "22B5045g"):
return False
return True
if (parsed_ver < Version("18.1")
or self.build == "22B5007p" or self.build == "22B5023e"
or self.build == "22B5034e" or self.build == "22B5045g"):
return True
return False
def supported(self) -> bool:
return self.has_exploit()
class Version:
def __init__(self, major: int, minor: int = 0, patch: int = 0):

View File

@@ -3,6 +3,7 @@ import plistlib
from pathlib import Path
from PySide6.QtWidgets import QMessageBox
from PySide6.QtCore import QSettings
from pymobiledevice3 import usbmux
from pymobiledevice3.lockdown import create_using_usbmux
@@ -11,6 +12,7 @@ from devicemanagement.constants import Device, Version
from devicemanagement.data_singleton import DataSingleton
from tweaks.tweaks import tweaks, FeatureFlagTweak, EligibilityTweak, AITweak, BasicPlistTweak, RdarFixTweak
from tweaks.custom_gestalt_tweaks import CustomGestaltTweaks
from tweaks.basic_plist_locations import FileLocationsList
from Sparserestore.restore import restore_files, FileToRestore
@@ -28,31 +30,56 @@ class DeviceManager:
self.devices: list[Device] = []
self.data_singleton = DataSingleton()
self.current_device_index = 0
# preferences
self.apply_over_wifi = True
self.skip_setup = True
self.auto_reboot = True
def get_devices(self):
def get_devices(self, settings: QSettings):
self.devices.clear()
connected_devices = usbmux.list_devices()
# handle errors when failing to get connected devices
try:
connected_devices = usbmux.list_devices()
except:
show_error_msg(
"""
Failed to get device list. Click \"Show Details\" for the traceback.
If you are on Windows, make sure you have the \"Apple Devices\" app from the Microsoft Store or iTunes from Apple's website.
If you are on Linux, make sure you have usbmuxd and libimobiledevice installed.
"""
)
# Connect via usbmuxd
for device in connected_devices:
if self.apply_over_wifi or device.is_usb:
try:
ld = create_using_usbmux(serial=device.serial)
vals = ld.all_values
model = vals['ProductType']
try:
product_type = settings.value(device.serial + "_model", "", type=str)
if product_type == "":
# save the new product type
settings.setValue(device.serial + "_model", model)
else:
model = product_type
except:
pass
dev = Device(
uuid=device.serial,
name=vals['DeviceName'],
version=vals['ProductVersion'],
build=vals['BuildVersion'],
model=vals['ProductType'],
model=model,
locale=ld.locale,
ld=ld
)
tweaks["RdarFix"].get_rdar_mode(vals['ProductType'])
tweaks["RdarFix"].get_rdar_mode(model)
self.devices.append(dev)
except Exception as e:
print(f"ERROR with lockdown device with UUID {device.serial}")
show_error_msg(type(e).__name__)
show_error_msg(type(e).__name__ + ": " + repr(e))
if len(connected_devices) > 0:
self.set_current_device(index=0)
@@ -66,6 +93,7 @@ class DeviceManager:
self.data_singleton.device_available = False
self.data_singleton.gestalt_path = None
self.current_device_index = 0
tweaks["SpoofModel"].value[0] = "Placeholder"
else:
self.data_singleton.current_device = self.devices[index]
if Version(self.devices[index].version) < Version("17.0"):
@@ -73,6 +101,7 @@ class DeviceManager:
self.data_singleton.gestalt_path = None
else:
self.data_singleton.device_available = True
tweaks["SpoofModel"].value[0] = self.data_singleton.current_device.model
self.current_device_index = index
def get_current_device_name(self) -> str:
@@ -87,6 +116,12 @@ class DeviceManager:
else:
return self.data_singleton.current_device.version
def get_current_device_build(self) -> str:
if self.data_singleton.current_device == None:
return ""
else:
return self.data_singleton.current_device.build
def get_current_device_uuid(self) -> str:
if self.data_singleton.current_device == None:
return ""
@@ -98,7 +133,72 @@ class DeviceManager:
return False
else:
return self.data_singleton.current_device.supported()
def reset_device_pairing(self):
# first, unpair it
if self.data_singleton.current_device == None:
return
self.data_singleton.current_device.ld.unpair()
# next, pair it again
self.data_singleton.current_device.ld.pair()
QMessageBox.information(None, "Pairing Reset", "Your device's pairing was successfully reset. Refresh the device list before applying.")
def add_skip_setup(self, files_to_restore: list[FileToRestore]):
if self.skip_setup and not self.get_current_device_supported():
# add the 2 skip setup files
cloud_config_plist: dict = {
"SkipSetup": ["WiFi", "Location", "Restore", "SIMSetup", "Android", "AppleID", "IntendedUser", "TOS", "Siri", "ScreenTime", "Diagnostics", "SoftwareUpdate", "Passcode", "Biometric", "Payment", "Zoom", "DisplayTone", "MessagingActivationUsingPhoneNumber", "HomeButtonSensitivity", "CloudStorage", "ScreenSaver", "TapToSetup", "Keyboard", "PreferredLanguage", "SpokenLanguage", "WatchMigration", "OnBoarding", "TVProviderSignIn", "TVHomeScreenSync", "Privacy", "TVRoom", "iMessageAndFaceTime", "AppStore", "Safety", "Multitasking", "ActionButton", "TermsOfAddress", "AccessibilityAppearance", "Welcome", "Appearance", "RestoreCompleted", "UpdateCompleted"],
"CloudConfigurationUIComplete": True,
"IsSupervised": False
}
files_to_restore.append(FileToRestore(
contents=plistlib.dumps(cloud_config_plist),
restore_path="systemgroup.com.apple.configurationprofiles/Library/ConfigurationProfiles/CloudConfigurationDetails.plist",
domain="SysSharedContainerDomain-."
))
purplebuddy_plist: dict = {
"SetupDone": True,
"SetupFinishedAllSteps": True,
"UserChoseLanguage": True
}
files_to_restore.append(FileToRestore(
contents=plistlib.dumps(purplebuddy_plist),
restore_path="mobile/com.apple.purplebuddy.plist",
domain="ManagedPreferencesDomain"
))
def get_domain_for_path(self, path: str) -> str:
mappings: dict = {
"/var/Managed Preferences/": "ManagedPreferencesDomain",
"/var/root/": "RootDomain",
"/var/preferences/": "SystemPreferencesDomain",
"/var/MobileDevice/": "MobileDeviceDomain",
"/var/mobile/": "HomeDomain",
"/var/db/": "DatabaseDomain",
"/var/containers/Shared/SystemGroup/": "SysSharedContainerDomain-.",
"/var/containers/Data/SystemGroup/": "SysContainerDomain-."
}
for mapping in mappings.keys():
if path.startswith(mapping):
new_path = path.replace(mapping, "")
return mappings[mapping], new_path
return None, path
def concat_file(self, contents: str, path: str, files_to_restore: list[FileToRestore]):
if self.get_current_device_supported():
files_to_restore.append(FileToRestore(
contents=contents,
restore_path=path
))
else:
domain, file_path = self.get_domain_for_path(path)
files_to_restore.append(FileToRestore(
contents=contents,
restore_path=file_path,
domain=domain
))
## APPLYING OR REMOVING TWEAKS AND RESTORING
def apply_changes(self, resetting: bool = False, update_label=lambda x: None):
@@ -130,6 +230,9 @@ class DeviceManager:
else:
if gestalt_plist != None:
gestalt_plist = tweak.apply_tweak(gestalt_plist)
# set the custom gestalt keys
if gestalt_plist != None:
gestalt_plist = CustomGestaltTweaks.apply_tweaks(gestalt_plist)
gestalt_data = None
if resetting:
@@ -140,40 +243,63 @@ class DeviceManager:
# Generate backup
update_label("Generating backup...")
# create the restore file list
files_to_restore = [
FileToRestore(
contents=plistlib.dumps(flag_plist),
restore_path="/var/preferences/FeatureFlags/Global.plist",
)
files_to_restore: dict[FileToRestore] = [
]
self.concat_file(
contents=plistlib.dumps(flag_plist),
path="/var/preferences/FeatureFlags/Global.plist",
files_to_restore=files_to_restore
)
self.add_skip_setup(files_to_restore)
if gestalt_data != None:
files_to_restore.append(FileToRestore(
self.concat_file(
contents=gestalt_data,
restore_path="/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library/Caches/com.apple.MobileGestalt.plist",
))
path="/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library/Caches/com.apple.MobileGestalt.plist",
files_to_restore=files_to_restore
)
if eligibility_files:
files_to_restore += eligibility_files
new_eligibility_files: dict[FileToRestore] = []
if not self.get_current_device_supported():
# update the files
for file in eligibility_files:
self.concat_file(
contents=file.contents,
path=file.restore_path,
files_to_restore=new_eligibility_files
)
else:
new_eligibility_files = eligibility_files
files_to_restore += new_eligibility_files
if ai_file != None:
files_to_restore.append(ai_file)
self.concat_file(
contents=ai_file.contents,
path=ai_file.restore_path,
files_to_restore=files_to_restore
)
for location, plist in basic_plists.items():
files_to_restore.append(FileToRestore(
self.concat_file(
contents=plistlib.dumps(plist),
restore_path=location.value
))
path=location.value,
files_to_restore=files_to_restore
)
# reset basic tweaks
if resetting:
empty_data = plistlib.dumps({})
for location in FileLocationsList:
files_to_restore.append(FileToRestore(
self.concat_file(
contents=empty_data,
restore_path=location.value
))
path=location.value,
files_to_restore=files_to_restore
)
# restore to the device
update_label("Restoring to device...")
try:
restore_files(files=files_to_restore, reboot=True, lockdown_client=self.data_singleton.current_device.ld)
QMessageBox.information(None, "Success!", "All done! Your device will now restart.")
restore_files(files=files_to_restore, reboot=self.auto_reboot, lockdown_client=self.data_singleton.current_device.ld)
msg = "Your device will now restart."
if not self.auto_reboot:
msg = "Please restart your device to see changes."
QMessageBox.information(None, "Success!", "All done! " + msg)
update_label("Success!")
except Exception as e:
if "Find My" in str(e):
@@ -186,18 +312,25 @@ class DeviceManager:
else:
print(traceback.format_exc())
update_label("Failed to restore")
show_error_msg(type(e).__name__)
show_error_msg(type(e).__name__ + ": " + repr(e))
## RESETTING MOBILE GESTALT
def reset_mobilegestalt(self, update_label=lambda x: None):
def reset_mobilegestalt(self, settings: QSettings, update_label=lambda x: None):
# restore to the device
update_label("Restoring to device...")
try:
# remove the saved device model
settings.setValue(self.data_singleton.current_device.uuid + "_model", "")
domain, file_path = self.get_domain_for_path("/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library/Caches/com.apple.MobileGestalt.plist")
restore_files(files=[FileToRestore(
contents=b"",
restore_path="/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library/Caches/com.apple.MobileGestalt.plist",
)], reboot=True, lockdown_client=self.data_singleton.current_device.ld)
QMessageBox.information(None, "Success!", "All done! Your device will now restart.")
restore_path=file_path,
domain=domain
)], reboot=self.auto_reboot, lockdown_client=self.data_singleton.current_device.ld)
msg = "Your device will now restart."
if not self.auto_reboot:
msg = "Please restart your device to see changes."
QMessageBox.information(None, "Success!", "All done! " + msg)
update_label("Success!")
except Exception as e:
if "Find My" in str(e):
@@ -210,4 +343,4 @@ class DeviceManager:
else:
print(traceback.format_exc())
update_label("Failed to restore")
show_error_msg(type(e).__name__)
show_error_msg(type(e).__name__ + ": " + repr(e))

View File

@@ -1,37 +0,0 @@
from Sparserestore import backup, perform_restore
from pymobiledevice3 import usbmux
from pymobiledevice3.lockdown import create_using_usbmux
from pymobiledevice3.lockdown import LockdownClient
lockdown = None
while lockdown == None:
connected_devices = usbmux.list_devices()
# Connect via usbmuxd
for current_device in connected_devices:
if current_device.is_usb:
lockdown = create_using_usbmux(serial=current_device.serial)
if lockdown == None:
print("Please connect your device and try again!")
input("Press Enter to continue...")
restore_path = "/var/Managed Preferences/mobile/"
restore_name = "com.apple.purplebuddy.plist"
back = backup.Backup(files=[
backup.Directory(
"",
f"SysContainerDomain-../../../../../../../../var/backup{restore_path}",
owner=501,
group=501
),
backup.ConcreteFile(
"",
f"SysContainerDomain-../../../../../../../../var/backup{restore_path}{restore_name}",
owner=501,
group=501,
contents=b""
),
backup.ConcreteFile("", "SysContainerDomain-../../../../../../../.." + "/crash_on_purpose", contents=b""),
])
perform_restore(backup=back, reboot=True, lockdown_client=lockdown)

View File

@@ -1,4 +1,4 @@
from PySide6 import QtCore, QtWidgets
from PySide6 import QtCore, QtWidgets, QtGui
from enum import Enum
import webbrowser
import plistlib
@@ -13,6 +13,7 @@ from devicemanagement.device_manager import DeviceManager
from gui.gestalt_dialog import GestaltDialog
from tweaks.tweaks import tweaks
from tweaks.custom_gestalt_tweaks import CustomGestaltTweaks, ValueTypeStrings
class Page(Enum):
Home = 0
@@ -76,7 +77,7 @@ class MainWindow(QtWidgets.QMainWindow):
self.ui.enableAIChk.toggled.connect(self.on_enableAIChk_toggled)
self.ui.languageTxt.textEdited.connect(self.on_languageTxt_textEdited)
self.ui.spoofModelChk.toggled.connect(self.on_spoofModelChk_toggled)
self.ui.spoofedModelDrp.activated.connect(self.on_spoofedModelDrp_activated)
## FEATURE FLAGS PAGE
self.ui.clockAnimChk.toggled.connect(self.on_clockAnimChk_toggled)
@@ -115,6 +116,13 @@ class MainWindow(QtWidgets.QMainWindow):
self.ui.chooseGestaltBtn.clicked.connect(self.on_chooseGestaltBtn_clicked)
self.ui.resetGestaltBtn.clicked.connect(self.on_resetGestaltBtn_clicked)
## SETTINGS PAGE ACTIONS
self.ui.allowWifiApplyingChk.toggled.connect(self.on_allowWifiApplyingChk_toggled)
self.ui.skipSetupChk.toggled.connect(self.on_skipSetupChk_toggled)
self.ui.autoRebootChk.toggled.connect(self.on_autoRebootChk_toggled)
self.ui.resetPairBtn.clicked.connect(self.on_resetPairBtn_clicked)
## MOBILE GESTALT PAGE ACTIONS
self.ui.dynamicIslandDrp.activated.connect(self.on_dynamicIslandDrp_activated)
self.ui.rdarFixChk.clicked.connect(self.on_rdarFixChk_clicked)
@@ -138,7 +146,8 @@ class MainWindow(QtWidgets.QMainWindow):
self.ui.internalStorageChk.clicked.connect(self.on_internalStorageChk_clicked)
self.ui.collisionSOSChk.clicked.connect(self.on_collisionSOSChk_clicked)
self.ui.aodChk.clicked.connect(self.on_aodChk_clicked)
self.ui.sleepApneaChk.clicked.connect(self.on_sleepApneaChk_clicked)
self.ui.addGestaltKeyBtn.clicked.connect(self.on_addGestaltKeyBtn_clicked)
## GENERAL INTERFACE FUNCTIONS
@@ -151,7 +160,7 @@ class MainWindow(QtWidgets.QMainWindow):
@QtCore.Slot()
def refresh_devices(self):
# get the devices
self.device_manager.get_devices()
self.device_manager.get_devices(self.settings)
# clear the picker
self.ui.devicePicker.clear()
self.ui.restoreProgressBar.hide()
@@ -174,6 +183,8 @@ class MainWindow(QtWidgets.QMainWindow):
self.ui.sidebarDiv2.hide()
self.ui.applyPageBtn.hide()
self.ui.resetPairBtn.hide()
else:
self.ui.devicePicker.setEnabled(True)
# populate the ComboBox with device names
@@ -185,8 +196,6 @@ class MainWindow(QtWidgets.QMainWindow):
self.ui.locSimPageBtn.hide()
self.ui.sidebarDiv1.show()
self.ui.gestaltPageBtn.show()
# self.ui.featureFlagsPageBtn.show()
self.ui.euEnablerPageBtn.show()
self.ui.springboardOptionsPageBtn.show()
self.ui.internalOptionsPageBtn.show()
@@ -198,19 +207,27 @@ class MainWindow(QtWidgets.QMainWindow):
self.ui.euEnablerPageContent.setDisabled(False)
self.ui.springboardOptionsPageContent.setDisabled(False)
self.ui.internalOptionsPageContent.setDisabled(False)
self.ui.resetPairBtn.show()
# update the selected device
self.ui.devicePicker.setCurrentIndex(0)
self.change_selected_device(0)
# update the interface
self.updateInterfaceForNewDevice()
def change_selected_device(self, index):
if len(self.device_manager.devices) > 0:
self.device_manager.set_current_device(index=index)
# hide options that are for newer versions
# remove the new dynamic island options
MinTweakVersions = {
"exploit": [("18.0", self.ui.featureFlagsPageBtn)],
"18.1": [self.ui.enableAIChk, self.ui.aiEnablerContent],
"18.0": [self.ui.aodChk, self.ui.iphone16SettingsChk]
}
MaxTweakVersions = {
"17.7": [self.ui.euEnablerContent]
}
try:
self.ui.dynamicIslandDrp.removeItem(6)
self.ui.dynamicIslandDrp.removeItem(5)
@@ -222,42 +239,62 @@ class MainWindow(QtWidgets.QMainWindow):
else:
self.ui.rdarFixChk.show()
self.ui.rdarFixChk.setText(f"{rdar_title} (modifies resolution)")
if Version(self.device_manager.data_singleton.current_device.version) >= Version("18.1"):
self.ui.enableAIChk.show()
self.ui.languageLbl.hide()
self.ui.languageTxt.hide()
self.ui.aiInfoLabel.hide()
self.ui.spoofModelChk.hide()
else:
self.ui.enableAIChk.hide()
self.ui.languageLbl.hide()
self.ui.languageTxt.hide()
self.ui.aiInfoLabel.hide()
self.ui.spoofModelChk.hide()
if Version(self.device_manager.data_singleton.current_device.version) >= Version("18.0"):
self.ui.aodChk.show()
self.ui.iphone16SettingsChk.show()
self.ui.sleepApneaChk.show()
self.ui.featureFlagsPageBtn.show()
device_ver = Version(self.device_manager.data_singleton.current_device.version)
# toggle option visibility for the minimum versions
for version in MinTweakVersions.keys():
if version == "exploit":
# disable if the exploit is not available
for pair in MinTweakVersions[version]:
if self.device_manager.data_singleton.current_device.has_exploit() and device_ver >= Version(pair[0]):
pair[1].show()
else:
pair[1].hide()
else:
# show views if the version is higher
parsed_ver = Version(version)
for view in MinTweakVersions[version]:
if device_ver >= parsed_ver:
view.show()
else:
view.hide()
# toggle option visibility for the max versions
for version in MaxTweakVersions.keys():
parsed_ver = Version(version)
for view in MaxTweakVersions[version]:
if device_ver <= parsed_ver:
view.show()
else:
view.hide()
if device_ver >= Version("18.0"):
# show the other dynamic island options
self.ui.dynamicIslandDrp.addItem("2622 (iPhone 16 Pro Dynamic Island)")
self.ui.dynamicIslandDrp.addItem("2868 (iPhone 16 Pro Max Dynamic Island)")
# eligibility page button
if device_ver >= Version("17.4") and (device_ver <= Version("17.7") or device_ver >= Version("18.1")):
self.ui.euEnablerPageBtn.show()
else:
self.ui.aodChk.hide()
self.ui.iphone16SettingsChk.hide()
self.ui.sleepApneaChk.hide()
self.ui.featureFlagsPageBtn.hide()
self.ui.euEnablerPageBtn.hide()
else:
self.device_manager.set_current_device(index=None)
self.ui.featureFlagsPageBtn.hide()
# update the interface
self.updateInterfaceForNewDevice()
def loadSettings(self):
self.settings = QtCore.QSettings()
try:
# load the settings
apply_over_wifi = self.settings.value("apply_over_wifi", True, type=bool)
skip_setup = self.settings.value("skip_setup", True, type=bool)
auto_reboot = self.settings.value("auto_reboot", True, type=bool)
self.ui.allowWifiApplyingChk.setChecked(apply_over_wifi)
self.ui.skipSetupChk.setChecked(skip_setup)
self.ui.autoRebootChk.setChecked(auto_reboot)
self.device_manager.apply_over_wifi = apply_over_wifi
self.device_manager.skip_setup = skip_setup
self.device_manager.auto_reboot = auto_reboot
except:
pass
@@ -300,9 +337,10 @@ class MainWindow(QtWidgets.QMainWindow):
self.ui.phoneNameLbl.setText(self.device_manager.get_current_device_name())
# version label
ver = self.device_manager.get_current_device_version()
build = self.device_manager.get_current_device_build()
self.show_uuid = False
if ver != "":
self.show_version_text(version=ver)
self.show_version_text(version=ver, build=build)
else:
self.ui.phoneVersionLbl.setText("Please connect a device.")
@@ -310,19 +348,23 @@ class MainWindow(QtWidgets.QMainWindow):
if self.show_uuid:
self.show_uuid = False
ver = self.device_manager.get_current_device_version()
build = self.device_manager.get_current_device_build()
if ver != "":
self.show_version_text(version=ver)
self.show_version_text(version=ver, build=build)
else:
self.show_uuid = True
uuid = self.device_manager.get_current_device_uuid()
if uuid != "":
self.ui.phoneVersionLbl.setText(f"<a style=\"text-decoration:none; color: white\" href=\"#\">{uuid}</a>")
def show_version_text(self, version: str):
def show_version_text(self, version: str, build: str):
support_str: str = "<span style=\"color: #32d74b;\">Supported!</span></a>"
if not self.device_manager.get_current_device_supported():
if Version(version) < Version("17.0"):
support_str = "<span style=\"color: #ff0000;\">Not Supported.</span></a>"
self.ui.phoneVersionLbl.setText(f"<a style=\"text-decoration:none; color: white;\" href=\"#\">iOS {version} {support_str}")
elif not self.device_manager.get_current_device_supported():
# sparserestore partially patched
support_str = "<span style=\"color: #ffff00;\">Supported, YMMV.</span></a>"
self.ui.phoneVersionLbl.setText(f"<a style=\"text-decoration:none; color: white;\" href=\"#\">iOS {version} ({build}) {support_str}")
## HOME PAGE LINKS
def on_bigMilkBtn_clicked(self):
@@ -406,8 +448,66 @@ class MainWindow(QtWidgets.QMainWindow):
tweaks["CollisionSOS"].set_enabled(checked)
def on_aodChk_clicked(self, checked: bool):
tweaks["AOD"].set_enabled(checked)
def on_sleepApneaChk_clicked(self, checked: bool):
tweaks["SleepApnea"].set_enabled(checked)
def update_custom_gestalt_value_type(self, id, idx, valueField: QtWidgets.QLineEdit):
new_str = CustomGestaltTweaks.set_tweak_value_type(id, idx)
# update the value
valueField.setText(new_str)
def delete_custom_gestalt_key(self, id: int, widget: QtWidgets.QWidget):
CustomGestaltTweaks.deactivate_tweak(id)
self.ui.customKeysLayout.removeWidget(widget)
widget.setParent(None)
def on_addGestaltKeyBtn_clicked(self):
# create a blank gestalt value with default value of 1
key_identifier = CustomGestaltTweaks.create_tweak()
widget = QtWidgets.QWidget()
widget.setFixedHeight(35)
widget.setStyleSheet("QWidget { background: none; border: 1px solid #3b3b3b; border-radius: 8px; }")
hlayout = QtWidgets.QHBoxLayout(widget)
hlayout.setContentsMargins(9, 2, 9, 2)
# create the key field
keyField = QtWidgets.QLineEdit(widget)
# keyField.setMaximumWidth(200)
keyField.setPlaceholderText("Key")
keyField.setAlignment(QtCore.Qt.AlignmentFlag.AlignLeft)
keyField.setTextMargins(5, 0, 5, 0)
keyField.textEdited.connect(lambda txt, id=key_identifier: CustomGestaltTweaks.set_tweak_key(id, txt))
hlayout.addWidget(keyField)
# create the delete button
delBtn = QtWidgets.QToolButton(widget)
delBtn.setIcon(QtGui.QIcon(":/icon/trash.svg"))
delBtn.setStyleSheet("QToolButton { margin-right: 8px; background: none; border: none; }\nQToolButton:pressed { background: none; color: #FFFFFF; }")
delBtn.clicked.connect(lambda _, id=key_identifier, w=widget: self.delete_custom_gestalt_key(id, w))
hlayout.addWidget(delBtn)
# create the type dropdown
valueTypeDrp = QtWidgets.QComboBox(widget)
valueTypeDrp.setStyleSheet("QComboBox {\n background-color: #3b3b3b;\n border: none;\n color: #e8e8e8;\n font-size: 14px;\n padding-left: 8px;\n border-radius: 8px;\n}\n\nQComboBox::drop-down {\n image: url(:/icon/caret-down-fill.svg);\n icon-size: 16px;\n subcontrol-position: right center;\n margin-right: 8px;\n}\n\nQComboBox QAbstractItemView {\n background-color: #3b3b3b;\n outline: none;\n margin-top: 1px;\n}\n\nQComboBox QAbstractItemView::item {\n background-color: #3b3b3b;\n color: #e8e8e8;\n padding-left: 8px;\n}\n\nQComboBox QAbstractItemView::item:hover {\n background-color: #535353;\n color: #ffffff;\n}")
valueTypeDrp.setFixedWidth(120)
valueTypeDrp.addItems(ValueTypeStrings)
valueTypeDrp.setCurrentIndex(0)
# create the value edit field
valueField = QtWidgets.QLineEdit(widget)
valueField.setMaximumWidth(175)
valueField.setPlaceholderText("Value")
valueField.setText("1")
valueField.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight)
valueField.setTextMargins(5, 0, 5, 0)
valueField.textEdited.connect(lambda txt, id=key_identifier: CustomGestaltTweaks.set_tweak_value(id, txt))
valueTypeDrp.activated.connect(lambda idx, id=key_identifier, vf=valueField: self.update_custom_gestalt_value_type(id, idx, vf))
hlayout.addWidget(valueTypeDrp)
hlayout.addWidget(valueField)
# add it to the main widget
widget.setDisabled(False)
self.ui.customKeysLayout.addWidget(widget)
## FEATURE FLAGS PAGE
@@ -435,19 +535,13 @@ class MainWindow(QtWidgets.QMainWindow):
tweaks["AIGestalt"].set_enabled(checked)
# change the visibility of stuff
if checked:
self.ui.languageLbl.show()
self.ui.languageTxt.show()
self.ui.aiInfoLabel.show()
self.ui.spoofModelChk.show()
self.ui.aiEnablerContent.show()
else:
self.ui.languageLbl.hide()
self.ui.languageTxt.hide()
self.ui.aiInfoLabel.hide()
self.ui.spoofModelChk.hide()
self.ui.aiEnablerContent.hide()
def on_languageTxt_textEdited(self, text: str):
tweaks["AIEligibility"].set_language_code(text)
def on_spoofModelChk_toggled(self, checked: bool):
tweaks["SpoofModel"].set_enabled(checked)
def on_spoofedModelDrp_activated(self, index: int):
tweaks["SpoofModel"].set_selected_option(index)
## SPRINGBOARD OPTIONS PAGE
@@ -506,6 +600,18 @@ class MainWindow(QtWidgets.QMainWindow):
self.device_manager.apply_over_wifi = checked
# save the setting
self.settings.setValue("apply_over_wifi", checked)
def on_skipSetupChk_toggled(self, checked: bool):
self.device_manager.skip_setup = checked
# save the setting
self.settings.setValue("skip_setup", checked)
def on_autoRebootChk_toggled(self, checked: bool):
self.device_manager.auto_reboot = checked
# save the setting
self.settings.setValue("auto_reboot", checked)
# Device Options
def on_resetPairBtn_clicked(self):
self.device_manager.reset_device_pairing()
## APPLY PAGE
@@ -548,7 +654,7 @@ class MainWindow(QtWidgets.QMainWindow):
# TODO: Add safety here
self.device_manager.apply_changes(resetting=True, update_label=self.update_label)
def on_resetGestaltBtn_clicked(self):
self.device_manager.reset_mobilegestalt(update_label=self.update_label)
self.device_manager.reset_mobilegestalt(self.settings, update_label=self.update_label)
@QtCore.Slot()
def on_applyTweaksBtn_clicked(self):

View File

@@ -7,7 +7,6 @@ from devicemanagement.device_manager import DeviceManager
if __name__ == "__main__":
app = QtWidgets.QApplication([])
dm = DeviceManager()
dm.get_devices()
widget = MainWindow(device_manager=dm)
widget.resize(800, 600)

2822
mainwindow_ui.py Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1566,7 +1566,7 @@ QToolButton:pressed {
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Nugget GUI - Version 3.0</string>
<string>Nugget GUI - Version 4.0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@@ -1759,7 +1759,7 @@ QToolButton:pressed {
<item>
<widget class="QWidget" name="gestaltPageContent" native="true">
<property name="enabled">
<bool>false</bool>
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
<property name="leftMargin">
@@ -1931,24 +1931,6 @@ QComboBox QAbstractItemView::item:hover {
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="horizontalWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item>
<widget class="Line" name="line_7">
<property name="styleSheet">
@@ -2064,13 +2046,6 @@ QComboBox QAbstractItemView::item:hover {
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="sleepApneaChk">
<property name="text">
<string>Enable Sleep Apnea (real) [for Apple Watches]</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="aodChk">
<property name="text">
@@ -2078,6 +2053,93 @@ QComboBox QAbstractItemView::item:hover {
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_22">
<property name="styleSheet">
<string notr="true">QFrame {
color: #414141;
}</string>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_10">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Custom Gestalt Keys</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="addGestaltKeyBtn">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string> Add Key</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/icon/plus.svg</normaloff>:/icon/plus.svg</iconset>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_12">
<property name="text">
<string>Warning: Using this feature incorrectly can lead to bootloops and data loss. Only use if you know
what you are doing.</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_23">
<property name="styleSheet">
<string notr="true">QFrame {
color: #414141;
}</string>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="customKeysCnt" native="true">
<property name="enabled">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_32">
<item>
<layout class="QVBoxLayout" name="customKeysLayout"/>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
@@ -2448,13 +2510,6 @@ QComboBox QAbstractItemView::item:hover {
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="euEnablerEnabledChk">
<property name="text">
<string>Enable EU Enabler</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="euEnablerPageContent" native="true">
<property name="enabled">
@@ -2474,22 +2529,44 @@ QComboBox QAbstractItemView::item:hover {
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Method Type</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="methodChoiceDrp">
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QComboBox {
<widget class="QWidget" name="euEnablerContent" native="true">
<layout class="QVBoxLayout" name="verticalLayout_36">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="euEnablerEnabledChk">
<property name="text">
<string>Enable EU Enabler</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Method Type</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="methodChoiceDrp">
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QComboBox {
background-color: #3b3b3b;
border: none;
color: #e8e8e8;
@@ -2521,49 +2598,52 @@ QComboBox QAbstractItemView::item:hover {
background-color: #535353;
color: #ffffff;
}</string>
</property>
<item>
<property name="text">
<string>Method 1</string>
</property>
</item>
<item>
<property name="text">
<string>Method 2</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>Region Code (Should be 2 letters)</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="regionCodeTxt">
<property name="placeholderText">
<string>Region Code (Default: US)</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_16">
<property name="enabled">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">QFrame {
</property>
<item>
<property name="text">
<string>Method 1</string>
</property>
</item>
<item>
<property name="text">
<string>Method 2</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>Region Code (Should be 2 letters)</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="regionCodeTxt">
<property name="placeholderText">
<string>Region Code (Default: US)</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_16">
<property name="enabled">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">QFrame {
color: #414141;
}</string>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
@@ -2574,44 +2654,157 @@ QComboBox QAbstractItemView::item:hover {
</widget>
</item>
<item>
<widget class="QLabel" name="languageLbl">
<property name="text">
<string>Language Code (not needed for English)</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="languageTxt">
<property name="placeholderText">
<string>Language Code (i.e. en)</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="aiInfoLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>In order to download the AI model, you must spoof the device model. This will break Face ID until
<widget class="QWidget" name="aiEnablerContent" native="true">
<layout class="QVBoxLayout" name="verticalLayout_34">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QLabel" name="languageLbl">
<property name="text">
<string>Language Code (not needed for English)</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="languageTxt">
<property name="placeholderText">
<string>Language Code (i.e. en)</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_21">
<property name="styleSheet">
<string notr="true">QFrame {
color: #414141;
}</string>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="aiInfoLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>In order to download the AI model, you must spoof the device model. This will break Face ID until
you revert.
Once the model has downloaded, disable &quot;Spoof Device Model&quot; and click the &quot;Apply Tweaks&quot;
Once the model has downloaded, set &quot;Spoofed Device Model&quot; to &quot;None&quot; and click the &quot;Apply Tweaks&quot;
button on the &quot;Apply&quot; page again to fix Face ID.</string>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="spoofModelChk">
<property name="text">
<string>Spoof Device Model</string>
</property>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>Spoofed Device Model</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="spoofedModelDrp">
<property name="maximumSize">
<size>
<width>325</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QComboBox {
background-color: #3b3b3b;
border: none;
color: #e8e8e8;
font-size: 14px;
padding-left: 8px;
border-radius: 8px;
}
QComboBox::drop-down {
image: url(:/icon/caret-down-fill.svg);
icon-size: 16px;
subcontrol-position: right center;
margin-right: 8px;
}
QComboBox QAbstractItemView {
background-color: #3b3b3b;
outline: none;
margin-top: 1px;
}
QComboBox QAbstractItemView::item {
background-color: #3b3b3b;
color: #e8e8e8;
padding-left: 8px;
}
QComboBox QAbstractItemView::item:hover {
background-color: #535353;
color: #ffffff;
}</string>
</property>
<property name="currentText">
<string>None</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>None</string>
</property>
</item>
<item>
<property name="text">
<string>iPhone16,2 (iPhone 15 Pro)</string>
</property>
</item>
<item>
<property name="text">
<string>iPhone17,4 (iPhone 16 Plus)</string>
</property>
</item>
<item>
<property name="text">
<string>iPhone17,3 (iPhone 16 Pro)</string>
</property>
</item>
<item>
<property name="text">
<string>iPhone17,2 (iPhone 16 Pro Max)</string>
</property>
</item>
<item>
<property name="text">
<string>iPad16,3 (iPad Pro M4)</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
@@ -3705,6 +3898,78 @@ button on the &quot;Apply&quot; page again to fix Face ID.</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="skipSetupChk">
<property name="text">
<string>Skip Setup * (non-exploit files only)</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="autoRebootChk">
<property name="text">
<string>Auto Reboot After Applying</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_21">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_15">
<property name="text">
<string>* Note: Skip Setup may cause issues with configuration profiles. Turn it off if you need that.</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_20">
<property name="styleSheet">
<string notr="true">QFrame {
color: #414141;
}</string>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="deviceSettingsBtns">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="resetPairBtn">
<property name="text">
<string>Reset Device Pairing</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">

View File

@@ -953,7 +953,7 @@ class Ui_Nugget(object):
self.verticalLayout_9.setContentsMargins(0, 0, 0, 0)
self.gestaltPageContent = QWidget(self.scrollAreaWidgetContents)
self.gestaltPageContent.setObjectName(u"gestaltPageContent")
self.gestaltPageContent.setEnabled(False)
self.gestaltPageContent.setEnabled(True)
self.verticalLayout_8 = QVBoxLayout(self.gestaltPageContent)
self.verticalLayout_8.setObjectName(u"verticalLayout_8")
self.verticalLayout_8.setContentsMargins(0, 0, 0, 0)
@@ -1049,14 +1049,6 @@ class Ui_Nugget(object):
self.verticalLayout_8.addWidget(self.parallaxChk)
self.horizontalWidget4 = QWidget(self.gestaltPageContent)
self.horizontalWidget4.setObjectName(u"horizontalWidget4")
self.horizontalLayout_10 = QHBoxLayout(self.horizontalWidget4)
self.horizontalLayout_10.setObjectName(u"horizontalLayout_10")
self.horizontalLayout_10.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_8.addWidget(self.horizontalWidget4)
self.line_7 = QFrame(self.gestaltPageContent)
self.line_7.setObjectName(u"line_7")
self.line_7.setStyleSheet(u"QFrame {\n"
@@ -1137,16 +1129,72 @@ class Ui_Nugget(object):
self.verticalLayout_8.addWidget(self.collisionSOSChk)
self.sleepApneaChk = QCheckBox(self.gestaltPageContent)
self.sleepApneaChk.setObjectName(u"sleepApneaChk")
self.verticalLayout_8.addWidget(self.sleepApneaChk)
self.aodChk = QCheckBox(self.gestaltPageContent)
self.aodChk.setObjectName(u"aodChk")
self.verticalLayout_8.addWidget(self.aodChk)
self.line_22 = QFrame(self.gestaltPageContent)
self.line_22.setObjectName(u"line_22")
self.line_22.setStyleSheet(u"QFrame {\n"
" color: #414141;\n"
"}")
self.line_22.setFrameShadow(QFrame.Plain)
self.line_22.setFrameShape(QFrame.HLine)
self.verticalLayout_8.addWidget(self.line_22)
self.horizontalLayout_11 = QHBoxLayout()
self.horizontalLayout_11.setObjectName(u"horizontalLayout_11")
self.horizontalLayout_11.setContentsMargins(-1, -1, -1, 0)
self.label_10 = QLabel(self.gestaltPageContent)
self.label_10.setObjectName(u"label_10")
self.label_10.setEnabled(True)
self.horizontalLayout_11.addWidget(self.label_10)
self.addGestaltKeyBtn = QToolButton(self.gestaltPageContent)
self.addGestaltKeyBtn.setObjectName(u"addGestaltKeyBtn")
self.addGestaltKeyBtn.setEnabled(True)
icon18 = QIcon()
icon18.addFile(u":/icon/plus.svg", QSize(), QIcon.Normal, QIcon.Off)
self.addGestaltKeyBtn.setIcon(icon18)
self.addGestaltKeyBtn.setCheckable(False)
self.addGestaltKeyBtn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.horizontalLayout_11.addWidget(self.addGestaltKeyBtn)
self.verticalLayout_8.addLayout(self.horizontalLayout_11)
self.label_12 = QLabel(self.gestaltPageContent)
self.label_12.setObjectName(u"label_12")
self.verticalLayout_8.addWidget(self.label_12)
self.line_23 = QFrame(self.gestaltPageContent)
self.line_23.setObjectName(u"line_23")
self.line_23.setStyleSheet(u"QFrame {\n"
" color: #414141;\n"
"}")
self.line_23.setFrameShadow(QFrame.Plain)
self.line_23.setFrameShape(QFrame.HLine)
self.verticalLayout_8.addWidget(self.line_23)
self.customKeysCnt = QWidget(self.gestaltPageContent)
self.customKeysCnt.setObjectName(u"customKeysCnt")
self.customKeysCnt.setEnabled(True)
self.verticalLayout_32 = QVBoxLayout(self.customKeysCnt)
self.verticalLayout_32.setObjectName(u"verticalLayout_32")
self.customKeysLayout = QVBoxLayout()
self.customKeysLayout.setObjectName(u"customKeysLayout")
self.verticalLayout_32.addLayout(self.customKeysLayout)
self.verticalLayout_8.addWidget(self.customKeysCnt)
self.verticalSpacer_3 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.verticalLayout_8.addItem(self.verticalSpacer_3)
@@ -1326,23 +1374,28 @@ class Ui_Nugget(object):
self.verticalLayout_17.addWidget(self.line_13)
self.euEnablerEnabledChk = QCheckBox(self.euEnablerPage)
self.euEnablerEnabledChk.setObjectName(u"euEnablerEnabledChk")
self.verticalLayout_17.addWidget(self.euEnablerEnabledChk)
self.euEnablerPageContent = QWidget(self.euEnablerPage)
self.euEnablerPageContent.setObjectName(u"euEnablerPageContent")
self.euEnablerPageContent.setEnabled(False)
self.verticalLayout_16 = QVBoxLayout(self.euEnablerPageContent)
self.verticalLayout_16.setObjectName(u"verticalLayout_16")
self.verticalLayout_16.setContentsMargins(0, 0, 0, 0)
self.label_5 = QLabel(self.euEnablerPageContent)
self.euEnablerContent = QWidget(self.euEnablerPageContent)
self.euEnablerContent.setObjectName(u"euEnablerContent")
self.verticalLayout_36 = QVBoxLayout(self.euEnablerContent)
self.verticalLayout_36.setObjectName(u"verticalLayout_36")
self.verticalLayout_36.setContentsMargins(0, 0, 0, 0)
self.euEnablerEnabledChk = QCheckBox(self.euEnablerContent)
self.euEnablerEnabledChk.setObjectName(u"euEnablerEnabledChk")
self.verticalLayout_36.addWidget(self.euEnablerEnabledChk)
self.label_5 = QLabel(self.euEnablerContent)
self.label_5.setObjectName(u"label_5")
self.verticalLayout_16.addWidget(self.label_5)
self.verticalLayout_36.addWidget(self.label_5)
self.methodChoiceDrp = QComboBox(self.euEnablerPageContent)
self.methodChoiceDrp = QComboBox(self.euEnablerContent)
self.methodChoiceDrp.addItem("")
self.methodChoiceDrp.addItem("")
self.methodChoiceDrp.setObjectName(u"methodChoiceDrp")
@@ -1380,19 +1433,19 @@ class Ui_Nugget(object):
" color: #ffffff;\n"
"}")
self.verticalLayout_16.addWidget(self.methodChoiceDrp)
self.verticalLayout_36.addWidget(self.methodChoiceDrp)
self.label_6 = QLabel(self.euEnablerPageContent)
self.label_6 = QLabel(self.euEnablerContent)
self.label_6.setObjectName(u"label_6")
self.verticalLayout_16.addWidget(self.label_6)
self.verticalLayout_36.addWidget(self.label_6)
self.regionCodeTxt = QLineEdit(self.euEnablerPageContent)
self.regionCodeTxt = QLineEdit(self.euEnablerContent)
self.regionCodeTxt.setObjectName(u"regionCodeTxt")
self.verticalLayout_16.addWidget(self.regionCodeTxt)
self.verticalLayout_36.addWidget(self.regionCodeTxt)
self.line_16 = QFrame(self.euEnablerPageContent)
self.line_16 = QFrame(self.euEnablerContent)
self.line_16.setObjectName(u"line_16")
self.line_16.setEnabled(False)
self.line_16.setStyleSheet(u"QFrame {\n"
@@ -1401,35 +1454,100 @@ class Ui_Nugget(object):
self.line_16.setFrameShadow(QFrame.Plain)
self.line_16.setFrameShape(QFrame.HLine)
self.verticalLayout_16.addWidget(self.line_16)
self.verticalLayout_36.addWidget(self.line_16)
self.verticalLayout_16.addWidget(self.euEnablerContent)
self.enableAIChk = QCheckBox(self.euEnablerPageContent)
self.enableAIChk.setObjectName(u"enableAIChk")
self.verticalLayout_16.addWidget(self.enableAIChk)
self.languageLbl = QLabel(self.euEnablerPageContent)
self.aiEnablerContent = QWidget(self.euEnablerPageContent)
self.aiEnablerContent.setObjectName(u"aiEnablerContent")
self.verticalLayout_34 = QVBoxLayout(self.aiEnablerContent)
self.verticalLayout_34.setObjectName(u"verticalLayout_34")
self.verticalLayout_34.setContentsMargins(0, 5, 0, 5)
self.languageLbl = QLabel(self.aiEnablerContent)
self.languageLbl.setObjectName(u"languageLbl")
self.verticalLayout_16.addWidget(self.languageLbl)
self.verticalLayout_34.addWidget(self.languageLbl)
self.languageTxt = QLineEdit(self.euEnablerPageContent)
self.languageTxt = QLineEdit(self.aiEnablerContent)
self.languageTxt.setObjectName(u"languageTxt")
self.verticalLayout_16.addWidget(self.languageTxt)
self.verticalLayout_34.addWidget(self.languageTxt)
self.aiInfoLabel = QLabel(self.euEnablerPageContent)
self.line_21 = QFrame(self.aiEnablerContent)
self.line_21.setObjectName(u"line_21")
self.line_21.setStyleSheet(u"QFrame {\n"
" color: #414141;\n"
"}")
self.line_21.setFrameShadow(QFrame.Plain)
self.line_21.setFrameShape(QFrame.HLine)
self.verticalLayout_34.addWidget(self.line_21)
self.aiInfoLabel = QLabel(self.aiEnablerContent)
self.aiInfoLabel.setObjectName(u"aiInfoLabel")
sizePolicy1.setHeightForWidth(self.aiInfoLabel.sizePolicy().hasHeightForWidth())
self.aiInfoLabel.setSizePolicy(sizePolicy1)
self.aiInfoLabel.setTextFormat(Qt.AutoText)
self.verticalLayout_16.addWidget(self.aiInfoLabel)
self.verticalLayout_34.addWidget(self.aiInfoLabel)
self.spoofModelChk = QCheckBox(self.euEnablerPageContent)
self.spoofModelChk.setObjectName(u"spoofModelChk")
self.label_8 = QLabel(self.aiEnablerContent)
self.label_8.setObjectName(u"label_8")
self.verticalLayout_16.addWidget(self.spoofModelChk)
self.verticalLayout_34.addWidget(self.label_8)
self.spoofedModelDrp = QComboBox(self.aiEnablerContent)
self.spoofedModelDrp.addItem("")
self.spoofedModelDrp.addItem("")
self.spoofedModelDrp.addItem("")
self.spoofedModelDrp.addItem("")
self.spoofedModelDrp.addItem("")
self.spoofedModelDrp.addItem("")
self.spoofedModelDrp.setObjectName(u"spoofedModelDrp")
self.spoofedModelDrp.setMaximumSize(QSize(325, 16777215))
self.spoofedModelDrp.setStyleSheet(u"QComboBox {\n"
" background-color: #3b3b3b;\n"
" border: none;\n"
" color: #e8e8e8;\n"
" font-size: 14px;\n"
" padding-left: 8px;\n"
" border-radius: 8px;\n"
"}\n"
"\n"
"QComboBox::drop-down {\n"
" image: url(:/icon/caret-down-fill.svg);\n"
" icon-size: 16px;\n"
" subcontrol-position: right center;\n"
" margin-right: 8px;\n"
"}\n"
"\n"
"QComboBox QAbstractItemView {\n"
" background-color: #3b3b3b;\n"
" outline: none;\n"
" margin-top: 1px;\n"
"}\n"
"\n"
"QComboBox QAbstractItemView::item {\n"
" background-color: #3b3b3b;\n"
" color: #e8e8e8;\n"
" padding-left: 8px;\n"
"}\n"
"\n"
"QComboBox QAbstractItemView::item:hover {\n"
" background-color: #535353;\n"
" color: #ffffff;\n"
"}")
self.verticalLayout_34.addWidget(self.spoofedModelDrp)
self.verticalLayout_16.addWidget(self.aiEnablerContent)
self.verticalSpacer_7 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
@@ -1839,9 +1957,9 @@ class Ui_Nugget(object):
self.horizontalLayout_7.setContentsMargins(-1, 10, -1, 0)
self.chooseGestaltBtn = QToolButton(self.verticalWidget2)
self.chooseGestaltBtn.setObjectName(u"chooseGestaltBtn")
icon18 = QIcon()
icon18.addFile(u":/icon/folder.svg", QSize(), QIcon.Normal, QIcon.Off)
self.chooseGestaltBtn.setIcon(icon18)
icon19 = QIcon()
icon19.addFile(u":/icon/folder.svg", QSize(), QIcon.Normal, QIcon.Off)
self.chooseGestaltBtn.setIcon(icon19)
self.chooseGestaltBtn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.horizontalLayout_7.addWidget(self.chooseGestaltBtn)
@@ -1849,12 +1967,12 @@ class Ui_Nugget(object):
self.verticalLayout_24.addLayout(self.horizontalLayout_7)
self.horizontalWidget5 = QWidget(self.verticalWidget2)
self.horizontalWidget5.setObjectName(u"horizontalWidget5")
self.horizontalLayout_17 = QHBoxLayout(self.horizontalWidget5)
self.horizontalWidget4 = QWidget(self.verticalWidget2)
self.horizontalWidget4.setObjectName(u"horizontalWidget4")
self.horizontalLayout_17 = QHBoxLayout(self.horizontalWidget4)
self.horizontalLayout_17.setObjectName(u"horizontalLayout_17")
self.horizontalLayout_17.setContentsMargins(0, 0, 0, 0)
self.applyTweaksBtn = QToolButton(self.horizontalWidget5)
self.applyTweaksBtn = QToolButton(self.horizontalWidget4)
self.applyTweaksBtn.setObjectName(u"applyTweaksBtn")
self.applyTweaksBtn.setIcon(icon9)
self.applyTweaksBtn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
@@ -1862,7 +1980,7 @@ class Ui_Nugget(object):
self.horizontalLayout_17.addWidget(self.applyTweaksBtn)
self.verticalLayout_24.addWidget(self.horizontalWidget5)
self.verticalLayout_24.addWidget(self.horizontalWidget4)
self.statusLbl = QLabel(self.verticalWidget2)
self.statusLbl.setObjectName(u"statusLbl")
@@ -1884,21 +2002,21 @@ class Ui_Nugget(object):
self.verticalLayout_24.addItem(self.verticalSpacer_2)
self.horizontalWidget6 = QWidget(self.verticalWidget2)
self.horizontalWidget6.setObjectName(u"horizontalWidget6")
self.horizontalLayout_25 = QHBoxLayout(self.horizontalWidget6)
self.horizontalWidget5 = QWidget(self.verticalWidget2)
self.horizontalWidget5.setObjectName(u"horizontalWidget5")
self.horizontalLayout_25 = QHBoxLayout(self.horizontalWidget5)
self.horizontalLayout_25.setObjectName(u"horizontalLayout_25")
self.horizontalLayout_25.setContentsMargins(0, 0, 0, 0)
self.horizontalSpacer_14 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
self.horizontalLayout_25.addItem(self.horizontalSpacer_14)
self.removeTweaksBtn = QToolButton(self.horizontalWidget6)
self.removeTweaksBtn = QToolButton(self.horizontalWidget5)
self.removeTweaksBtn.setObjectName(u"removeTweaksBtn")
self.horizontalLayout_25.addWidget(self.removeTweaksBtn)
self.resetGestaltBtn = QToolButton(self.horizontalWidget6)
self.resetGestaltBtn = QToolButton(self.horizontalWidget5)
self.resetGestaltBtn.setObjectName(u"resetGestaltBtn")
self.horizontalLayout_25.addWidget(self.resetGestaltBtn)
@@ -1908,7 +2026,7 @@ class Ui_Nugget(object):
self.horizontalLayout_25.addItem(self.horizontalSpacer_16)
self.verticalLayout_24.addWidget(self.horizontalWidget6)
self.verticalLayout_24.addWidget(self.horizontalWidget5)
self.verticalLayout_6.addWidget(self.verticalWidget2)
@@ -1988,6 +2106,48 @@ class Ui_Nugget(object):
self._21.addWidget(self.allowWifiApplyingChk)
self.skipSetupChk = QCheckBox(self.settingsPageContent)
self.skipSetupChk.setObjectName(u"skipSetupChk")
self.skipSetupChk.setChecked(True)
self._21.addWidget(self.skipSetupChk)
self.autoRebootChk = QCheckBox(self.settingsPageContent)
self.autoRebootChk.setObjectName(u"autoRebootChk")
self.autoRebootChk.setChecked(True)
self._21.addWidget(self.autoRebootChk)
self.verticalSpacer_21 = QSpacerItem(20, 10, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Fixed)
self._21.addItem(self.verticalSpacer_21)
self.label_15 = QLabel(self.settingsPageContent)
self.label_15.setObjectName(u"label_15")
self._21.addWidget(self.label_15)
self.line_20 = QFrame(self.settingsPageContent)
self.line_20.setObjectName(u"line_20")
self.line_20.setStyleSheet(u"QFrame {\n"
" color: #414141;\n"
"}")
self.line_20.setFrameShadow(QFrame.Plain)
self.line_20.setFrameShape(QFrame.HLine)
self._21.addWidget(self.line_20)
self.deviceSettingsBtns = QHBoxLayout()
self.deviceSettingsBtns.setObjectName(u"deviceSettingsBtns")
self.deviceSettingsBtns.setContentsMargins(-1, -1, -1, 0)
self.resetPairBtn = QToolButton(self.settingsPageContent)
self.resetPairBtn.setObjectName(u"resetPairBtn")
self.deviceSettingsBtns.addWidget(self.resetPairBtn)
self._21.addLayout(self.deviceSettingsBtns)
self.verticalSpacer_51 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self._21.addItem(self.verticalSpacer_51)
@@ -2101,18 +2261,18 @@ class Ui_Nugget(object):
self.verticalLayout_29.addWidget(self.longitudeTxt)
self.horizontalWidget7 = QWidget(self.verticalWidget3)
self.horizontalWidget7.setObjectName(u"horizontalWidget7")
self.horizontalLayout_3 = QHBoxLayout(self.horizontalWidget7)
self.horizontalWidget6 = QWidget(self.verticalWidget3)
self.horizontalWidget6.setObjectName(u"horizontalWidget6")
self.horizontalLayout_3 = QHBoxLayout(self.horizontalWidget6)
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
self.setLocationBtn = QToolButton(self.horizontalWidget7)
self.setLocationBtn = QToolButton(self.horizontalWidget6)
self.setLocationBtn.setObjectName(u"setLocationBtn")
self.horizontalLayout_3.addWidget(self.setLocationBtn)
self.verticalLayout_29.addWidget(self.horizontalWidget7)
self.verticalLayout_29.addWidget(self.horizontalWidget6)
self.horizontalWidget_22 = QWidget(self.verticalWidget3)
self.horizontalWidget_22.setObjectName(u"horizontalWidget_22")
@@ -2159,9 +2319,9 @@ class Ui_Nugget(object):
" padding-right: 5px;\n"
" border-radius: 0px;\n"
"}")
icon19 = QIcon()
icon19.addFile(u":/icon/pencil.svg", QSize(), QIcon.Normal, QIcon.Off)
self.toolButton_12.setIcon(icon19)
icon20 = QIcon()
icon20.addFile(u":/icon/pencil.svg", QSize(), QIcon.Normal, QIcon.Off)
self.toolButton_12.setIcon(icon20)
self.toolButton_12.setIconSize(QSize(25, 25))
self.horizontalLayout_22.addWidget(self.toolButton_12)
@@ -2222,9 +2382,9 @@ class Ui_Nugget(object):
self.importOperationBtn = QToolButton(self.customOperationsPageContent)
self.importOperationBtn.setObjectName(u"importOperationBtn")
self.importOperationBtn.setEnabled(True)
icon20 = QIcon()
icon20.addFile(u":/icon/import.svg", QSize(), QIcon.Normal, QIcon.Off)
self.importOperationBtn.setIcon(icon20)
icon21 = QIcon()
icon21.addFile(u":/icon/import.svg", QSize(), QIcon.Normal, QIcon.Off)
self.importOperationBtn.setIcon(icon21)
self.importOperationBtn.setIconSize(QSize(20, 20))
self.importOperationBtn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
@@ -2236,9 +2396,7 @@ class Ui_Nugget(object):
sizePolicy2.setHeightForWidth(self.newOperationBtn.sizePolicy().hasHeightForWidth())
self.newOperationBtn.setSizePolicy(sizePolicy2)
self.newOperationBtn.setMinimumSize(QSize(0, 35))
icon21 = QIcon()
icon21.addFile(u":/icon/plus.svg", QSize(), QIcon.Normal, QIcon.Off)
self.newOperationBtn.setIcon(icon21)
self.newOperationBtn.setIcon(icon18)
self.newOperationBtn.setIconSize(QSize(16, 16))
self.newOperationBtn.setCheckable(False)
self.newOperationBtn.setAutoExclusive(True)
@@ -2379,12 +2537,12 @@ class Ui_Nugget(object):
self.horizontalLayout_23.addItem(self.horizontalSpacer_10)
self.horizontalWidget8 = QWidget(self.horizontalWidget_8)
self.horizontalWidget8.setObjectName(u"horizontalWidget8")
self.horizontalLayout_26 = QHBoxLayout(self.horizontalWidget8)
self.horizontalWidget7 = QWidget(self.horizontalWidget_8)
self.horizontalWidget7.setObjectName(u"horizontalWidget7")
self.horizontalLayout_26 = QHBoxLayout(self.horizontalWidget7)
self.horizontalLayout_26.setObjectName(u"horizontalLayout_26")
self.horizontalLayout_26.setContentsMargins(0, 0, 0, 0)
self.importThemeBtn = QToolButton(self.horizontalWidget8)
self.importThemeBtn = QToolButton(self.horizontalWidget7)
self.importThemeBtn.setObjectName(u"importThemeBtn")
self.importThemeBtn.setEnabled(False)
self.importThemeBtn.setStyleSheet(u"QToolButton {\n"
@@ -2393,13 +2551,13 @@ class Ui_Nugget(object):
self.horizontalLayout_26.addWidget(self.importThemeBtn)
self.importThemeFolderBtn = QToolButton(self.horizontalWidget8)
self.importThemeFolderBtn = QToolButton(self.horizontalWidget7)
self.importThemeFolderBtn.setObjectName(u"importThemeFolderBtn")
self.importThemeFolderBtn.setIcon(icon18)
self.importThemeFolderBtn.setIcon(icon19)
self.horizontalLayout_26.addWidget(self.importThemeFolderBtn)
self.importThemeZipBtn = QToolButton(self.horizontalWidget8)
self.importThemeZipBtn = QToolButton(self.horizontalWidget7)
self.importThemeZipBtn.setObjectName(u"importThemeZipBtn")
icon22 = QIcon()
icon22.addFile(u":/icon/file-earmark-zip.svg", QSize(), QIcon.Normal, QIcon.Off)
@@ -2408,7 +2566,7 @@ class Ui_Nugget(object):
self.horizontalLayout_26.addWidget(self.importThemeZipBtn)
self.horizontalLayout_23.addWidget(self.horizontalWidget8)
self.horizontalLayout_23.addWidget(self.horizontalWidget7)
self.verticalLayout_23.addWidget(self.horizontalWidget_8)
@@ -2458,26 +2616,26 @@ class Ui_Nugget(object):
self.verticalLayout_22.addItem(self.verticalSpacer_9)
self.horizontalWidget9 = QWidget(self.themesPageContent)
self.horizontalWidget9.setObjectName(u"horizontalWidget9")
self.horizontalLayout_16 = QHBoxLayout(self.horizontalWidget9)
self.horizontalWidget8 = QWidget(self.themesPageContent)
self.horizontalWidget8.setObjectName(u"horizontalWidget8")
self.horizontalLayout_16 = QHBoxLayout(self.horizontalWidget8)
self.horizontalLayout_16.setObjectName(u"horizontalLayout_16")
self.horizontalLayout_16.setContentsMargins(0, 0, 0, 0)
self.hideNamesBtn = QToolButton(self.horizontalWidget9)
self.hideNamesBtn = QToolButton(self.horizontalWidget8)
self.hideNamesBtn.setObjectName(u"hideNamesBtn")
sizePolicy2.setHeightForWidth(self.hideNamesBtn.sizePolicy().hasHeightForWidth())
self.hideNamesBtn.setSizePolicy(sizePolicy2)
self.horizontalLayout_16.addWidget(self.hideNamesBtn)
self.borderAllBtn = QToolButton(self.horizontalWidget9)
self.borderAllBtn = QToolButton(self.horizontalWidget8)
self.borderAllBtn.setObjectName(u"borderAllBtn")
sizePolicy2.setHeightForWidth(self.borderAllBtn.sizePolicy().hasHeightForWidth())
self.borderAllBtn.setSizePolicy(sizePolicy2)
self.horizontalLayout_16.addWidget(self.borderAllBtn)
self.addAllBtn = QToolButton(self.horizontalWidget9)
self.addAllBtn = QToolButton(self.horizontalWidget8)
self.addAllBtn.setObjectName(u"addAllBtn")
sizePolicy2.setHeightForWidth(self.addAllBtn.sizePolicy().hasHeightForWidth())
self.addAllBtn.setSizePolicy(sizePolicy2)
@@ -2485,7 +2643,7 @@ class Ui_Nugget(object):
self.horizontalLayout_16.addWidget(self.addAllBtn)
self.verticalLayout_22.addWidget(self.horizontalWidget9)
self.verticalLayout_22.addWidget(self.horizontalWidget8)
self.verticalLayout_23.addWidget(self.themesPageContent)
@@ -2507,6 +2665,7 @@ class Ui_Nugget(object):
self.devicePicker.setCurrentIndex(-1)
self.pages.setCurrentIndex(0)
self.dynamicIslandDrp.setCurrentIndex(0)
self.spoofedModelDrp.setCurrentIndex(0)
QMetaObject.connectSlotsByName(Nugget)
@@ -2559,7 +2718,7 @@ class Ui_Nugget(object):
self.toolButton_15.setText(QCoreApplication.translate("Nugget", u"Additional Thanks", None))
self.libiBtn.setText(QCoreApplication.translate("Nugget", u"pymobiledevice3", None))
self.qtBtn.setText(QCoreApplication.translate("Nugget", u"Qt Creator", None))
self.label.setText(QCoreApplication.translate("Nugget", u"Nugget GUI - Version 3.0", None))
self.label.setText(QCoreApplication.translate("Nugget", u"Nugget GUI - Version 4.0", None))
self.statusBarLbl.setText(QCoreApplication.translate("Nugget", u"Mobile Gestalt", None))
self.label_9.setText(QCoreApplication.translate("Nugget", u"Device Subtype Preset", None))
self.dynamicIslandDrp.setItemText(0, QCoreApplication.translate("Nugget", u"None", None))
@@ -2589,8 +2748,11 @@ class Ui_Nugget(object):
self.internalInstallChk.setText(QCoreApplication.translate("Nugget", u"Set as Apple Internal Install (ie Metal HUD in any app)", None))
self.internalStorageChk.setText(QCoreApplication.translate("Nugget", u"Enable Internal Storage (WARNING: risky for some devices, mainly iPads)", None))
self.collisionSOSChk.setText(QCoreApplication.translate("Nugget", u"Enable Collision SOS", None))
self.sleepApneaChk.setText(QCoreApplication.translate("Nugget", u"Enable Sleep Apnea (real) [for Apple Watches]", None))
self.aodChk.setText(QCoreApplication.translate("Nugget", u"Enable Always On Display", None))
self.label_10.setText(QCoreApplication.translate("Nugget", u"Custom Gestalt Keys", None))
self.addGestaltKeyBtn.setText(QCoreApplication.translate("Nugget", u" Add Key", None))
self.label_12.setText(QCoreApplication.translate("Nugget", u"Warning: Using this feature incorrectly can lead to bootloops and data loss. Only use if you know\n"
"what you are doing.", None))
self.internalOptionsLbl.setText(QCoreApplication.translate("Nugget", u"Feature Flags", None))
self.clockAnimChk.setText(QCoreApplication.translate("Nugget", u"Enable Lockscreen Clock Animation", None))
self.lockscreenChk.setText(QCoreApplication.translate("Nugget", u"Enable Duplicate Lockscreen Button and Lockscreen Quickswitch", None))
@@ -2610,9 +2772,17 @@ class Ui_Nugget(object):
self.aiInfoLabel.setText(QCoreApplication.translate("Nugget", u"In order to download the AI model, you must spoof the device model. This will break Face ID until\n"
"you revert.\n"
"\n"
"Once the model has downloaded, disable \"Spoof Device Model\" and click the \"Apply Tweaks\"\n"
"Once the model has downloaded, set \"Spoofed Device Model\" to \"None\" and click the \"Apply Tweaks\"\n"
"button on the \"Apply\" page again to fix Face ID.", None))
self.spoofModelChk.setText(QCoreApplication.translate("Nugget", u"Spoof Device Model", None))
self.label_8.setText(QCoreApplication.translate("Nugget", u"Spoofed Device Model", None))
self.spoofedModelDrp.setItemText(0, QCoreApplication.translate("Nugget", u"None", None))
self.spoofedModelDrp.setItemText(1, QCoreApplication.translate("Nugget", u"iPhone16,2 (iPhone 15 Pro)", None))
self.spoofedModelDrp.setItemText(2, QCoreApplication.translate("Nugget", u"iPhone17,4 (iPhone 16 Plus)", None))
self.spoofedModelDrp.setItemText(3, QCoreApplication.translate("Nugget", u"iPhone17,3 (iPhone 16 Pro)", None))
self.spoofedModelDrp.setItemText(4, QCoreApplication.translate("Nugget", u"iPhone17,2 (iPhone 16 Pro Max)", None))
self.spoofedModelDrp.setItemText(5, QCoreApplication.translate("Nugget", u"iPad16,3 (iPad Pro M4)", None))
self.spoofedModelDrp.setCurrentText(QCoreApplication.translate("Nugget", u"None", None))
self.springboardOptionsLbl.setText(QCoreApplication.translate("Nugget", u"Springboard Options", None))
self.label_13.setText(QCoreApplication.translate("Nugget", u"Lock Screen Footnote Text", None))
self.footnoteTxt.setPlaceholderText(QCoreApplication.translate("Nugget", u"Footnote Text", None))
@@ -2648,6 +2818,10 @@ class Ui_Nugget(object):
self.resetGestaltBtn.setText(QCoreApplication.translate("Nugget", u"Reset Mobile Gestalt", None))
self.springboardOptionsLbl1.setText(QCoreApplication.translate("Nugget", u"Nugget Settings", None))
self.allowWifiApplyingChk.setText(QCoreApplication.translate("Nugget", u"Allow Applying Over WiFi", None))
self.skipSetupChk.setText(QCoreApplication.translate("Nugget", u"Skip Setup * (non-exploit files only)", None))
self.autoRebootChk.setText(QCoreApplication.translate("Nugget", u"Auto Reboot After Applying", None))
self.label_15.setText(QCoreApplication.translate("Nugget", u"* Note: Skip Setup may cause issues with configuration profiles. Turn it off if you need that.", None))
self.resetPairBtn.setText(QCoreApplication.translate("Nugget", u"Reset Device Pairing", None))
self.statusBarLbl_2.setText(QCoreApplication.translate("Nugget", u"Location Simulation", None))
self.label_4.setText("")
self.loadLocSimBtn.setText(QCoreApplication.translate("Nugget", u"Start Location Simulation", None))

View File

@@ -953,7 +953,7 @@ class Ui_Nugget(object):
self.verticalLayout_9.setContentsMargins(0, 0, 0, 0)
self.gestaltPageContent = QWidget(self.scrollAreaWidgetContents)
self.gestaltPageContent.setObjectName(u"gestaltPageContent")
self.gestaltPageContent.setEnabled(False)
self.gestaltPageContent.setEnabled(True)
self.verticalLayout_8 = QVBoxLayout(self.gestaltPageContent)
self.verticalLayout_8.setObjectName(u"verticalLayout_8")
self.verticalLayout_8.setContentsMargins(0, 0, 0, 0)
@@ -1049,14 +1049,6 @@ class Ui_Nugget(object):
self.verticalLayout_8.addWidget(self.parallaxChk)
self.horizontalWidget4 = QWidget(self.gestaltPageContent)
self.horizontalWidget4.setObjectName(u"horizontalWidget4")
self.horizontalLayout_10 = QHBoxLayout(self.horizontalWidget4)
self.horizontalLayout_10.setObjectName(u"horizontalLayout_10")
self.horizontalLayout_10.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_8.addWidget(self.horizontalWidget4)
self.line_7 = QFrame(self.gestaltPageContent)
self.line_7.setObjectName(u"line_7")
self.line_7.setStyleSheet(u"QFrame {\n"
@@ -1137,16 +1129,72 @@ class Ui_Nugget(object):
self.verticalLayout_8.addWidget(self.collisionSOSChk)
self.sleepApneaChk = QCheckBox(self.gestaltPageContent)
self.sleepApneaChk.setObjectName(u"sleepApneaChk")
self.verticalLayout_8.addWidget(self.sleepApneaChk)
self.aodChk = QCheckBox(self.gestaltPageContent)
self.aodChk.setObjectName(u"aodChk")
self.verticalLayout_8.addWidget(self.aodChk)
self.line_22 = QFrame(self.gestaltPageContent)
self.line_22.setObjectName(u"line_22")
self.line_22.setStyleSheet(u"QFrame {\n"
" color: #414141;\n"
"}")
self.line_22.setFrameShadow(QFrame.Plain)
self.line_22.setFrameShape(QFrame.Shape.HLine)
self.verticalLayout_8.addWidget(self.line_22)
self.horizontalLayout_11 = QHBoxLayout()
self.horizontalLayout_11.setObjectName(u"horizontalLayout_11")
self.horizontalLayout_11.setContentsMargins(-1, -1, -1, 0)
self.label_10 = QLabel(self.gestaltPageContent)
self.label_10.setObjectName(u"label_10")
self.label_10.setEnabled(True)
self.horizontalLayout_11.addWidget(self.label_10)
self.addGestaltKeyBtn = QToolButton(self.gestaltPageContent)
self.addGestaltKeyBtn.setObjectName(u"addGestaltKeyBtn")
self.addGestaltKeyBtn.setEnabled(True)
icon18 = QIcon()
icon18.addFile(u":/icon/plus.svg", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.addGestaltKeyBtn.setIcon(icon18)
self.addGestaltKeyBtn.setCheckable(False)
self.addGestaltKeyBtn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.horizontalLayout_11.addWidget(self.addGestaltKeyBtn)
self.verticalLayout_8.addLayout(self.horizontalLayout_11)
self.label_12 = QLabel(self.gestaltPageContent)
self.label_12.setObjectName(u"label_12")
self.verticalLayout_8.addWidget(self.label_12)
self.line_23 = QFrame(self.gestaltPageContent)
self.line_23.setObjectName(u"line_23")
self.line_23.setStyleSheet(u"QFrame {\n"
" color: #414141;\n"
"}")
self.line_23.setFrameShadow(QFrame.Plain)
self.line_23.setFrameShape(QFrame.Shape.HLine)
self.verticalLayout_8.addWidget(self.line_23)
self.customKeysCnt = QWidget(self.gestaltPageContent)
self.customKeysCnt.setObjectName(u"customKeysCnt")
self.customKeysCnt.setEnabled(True)
self.verticalLayout_32 = QVBoxLayout(self.customKeysCnt)
self.verticalLayout_32.setObjectName(u"verticalLayout_32")
self.customKeysLayout = QVBoxLayout()
self.customKeysLayout.setObjectName(u"customKeysLayout")
self.verticalLayout_32.addLayout(self.customKeysLayout)
self.verticalLayout_8.addWidget(self.customKeysCnt)
self.verticalSpacer_3 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self.verticalLayout_8.addItem(self.verticalSpacer_3)
@@ -1326,23 +1374,28 @@ class Ui_Nugget(object):
self.verticalLayout_17.addWidget(self.line_13)
self.euEnablerEnabledChk = QCheckBox(self.euEnablerPage)
self.euEnablerEnabledChk.setObjectName(u"euEnablerEnabledChk")
self.verticalLayout_17.addWidget(self.euEnablerEnabledChk)
self.euEnablerPageContent = QWidget(self.euEnablerPage)
self.euEnablerPageContent.setObjectName(u"euEnablerPageContent")
self.euEnablerPageContent.setEnabled(False)
self.verticalLayout_16 = QVBoxLayout(self.euEnablerPageContent)
self.verticalLayout_16.setObjectName(u"verticalLayout_16")
self.verticalLayout_16.setContentsMargins(0, 0, 0, 0)
self.label_5 = QLabel(self.euEnablerPageContent)
self.euEnablerContent = QWidget(self.euEnablerPageContent)
self.euEnablerContent.setObjectName(u"euEnablerContent")
self.verticalLayout_36 = QVBoxLayout(self.euEnablerContent)
self.verticalLayout_36.setObjectName(u"verticalLayout_36")
self.verticalLayout_36.setContentsMargins(0, 0, 0, 0)
self.euEnablerEnabledChk = QCheckBox(self.euEnablerContent)
self.euEnablerEnabledChk.setObjectName(u"euEnablerEnabledChk")
self.verticalLayout_36.addWidget(self.euEnablerEnabledChk)
self.label_5 = QLabel(self.euEnablerContent)
self.label_5.setObjectName(u"label_5")
self.verticalLayout_16.addWidget(self.label_5)
self.verticalLayout_36.addWidget(self.label_5)
self.methodChoiceDrp = QComboBox(self.euEnablerPageContent)
self.methodChoiceDrp = QComboBox(self.euEnablerContent)
self.methodChoiceDrp.addItem("")
self.methodChoiceDrp.addItem("")
self.methodChoiceDrp.setObjectName(u"methodChoiceDrp")
@@ -1380,19 +1433,19 @@ class Ui_Nugget(object):
" color: #ffffff;\n"
"}")
self.verticalLayout_16.addWidget(self.methodChoiceDrp)
self.verticalLayout_36.addWidget(self.methodChoiceDrp)
self.label_6 = QLabel(self.euEnablerPageContent)
self.label_6 = QLabel(self.euEnablerContent)
self.label_6.setObjectName(u"label_6")
self.verticalLayout_16.addWidget(self.label_6)
self.verticalLayout_36.addWidget(self.label_6)
self.regionCodeTxt = QLineEdit(self.euEnablerPageContent)
self.regionCodeTxt = QLineEdit(self.euEnablerContent)
self.regionCodeTxt.setObjectName(u"regionCodeTxt")
self.verticalLayout_16.addWidget(self.regionCodeTxt)
self.verticalLayout_36.addWidget(self.regionCodeTxt)
self.line_16 = QFrame(self.euEnablerPageContent)
self.line_16 = QFrame(self.euEnablerContent)
self.line_16.setObjectName(u"line_16")
self.line_16.setEnabled(False)
self.line_16.setStyleSheet(u"QFrame {\n"
@@ -1401,35 +1454,100 @@ class Ui_Nugget(object):
self.line_16.setFrameShadow(QFrame.Plain)
self.line_16.setFrameShape(QFrame.Shape.HLine)
self.verticalLayout_16.addWidget(self.line_16)
self.verticalLayout_36.addWidget(self.line_16)
self.verticalLayout_16.addWidget(self.euEnablerContent)
self.enableAIChk = QCheckBox(self.euEnablerPageContent)
self.enableAIChk.setObjectName(u"enableAIChk")
self.verticalLayout_16.addWidget(self.enableAIChk)
self.languageLbl = QLabel(self.euEnablerPageContent)
self.aiEnablerContent = QWidget(self.euEnablerPageContent)
self.aiEnablerContent.setObjectName(u"aiEnablerContent")
self.verticalLayout_34 = QVBoxLayout(self.aiEnablerContent)
self.verticalLayout_34.setObjectName(u"verticalLayout_34")
self.verticalLayout_34.setContentsMargins(0, 5, 0, 5)
self.languageLbl = QLabel(self.aiEnablerContent)
self.languageLbl.setObjectName(u"languageLbl")
self.verticalLayout_16.addWidget(self.languageLbl)
self.verticalLayout_34.addWidget(self.languageLbl)
self.languageTxt = QLineEdit(self.euEnablerPageContent)
self.languageTxt = QLineEdit(self.aiEnablerContent)
self.languageTxt.setObjectName(u"languageTxt")
self.verticalLayout_16.addWidget(self.languageTxt)
self.verticalLayout_34.addWidget(self.languageTxt)
self.aiInfoLabel = QLabel(self.euEnablerPageContent)
self.line_21 = QFrame(self.aiEnablerContent)
self.line_21.setObjectName(u"line_21")
self.line_21.setStyleSheet(u"QFrame {\n"
" color: #414141;\n"
"}")
self.line_21.setFrameShadow(QFrame.Plain)
self.line_21.setFrameShape(QFrame.Shape.HLine)
self.verticalLayout_34.addWidget(self.line_21)
self.aiInfoLabel = QLabel(self.aiEnablerContent)
self.aiInfoLabel.setObjectName(u"aiInfoLabel")
sizePolicy1.setHeightForWidth(self.aiInfoLabel.sizePolicy().hasHeightForWidth())
self.aiInfoLabel.setSizePolicy(sizePolicy1)
self.aiInfoLabel.setTextFormat(Qt.AutoText)
self.verticalLayout_16.addWidget(self.aiInfoLabel)
self.verticalLayout_34.addWidget(self.aiInfoLabel)
self.spoofModelChk = QCheckBox(self.euEnablerPageContent)
self.spoofModelChk.setObjectName(u"spoofModelChk")
self.label_8 = QLabel(self.aiEnablerContent)
self.label_8.setObjectName(u"label_8")
self.verticalLayout_16.addWidget(self.spoofModelChk)
self.verticalLayout_34.addWidget(self.label_8)
self.spoofedModelDrp = QComboBox(self.aiEnablerContent)
self.spoofedModelDrp.addItem("")
self.spoofedModelDrp.addItem("")
self.spoofedModelDrp.addItem("")
self.spoofedModelDrp.addItem("")
self.spoofedModelDrp.addItem("")
self.spoofedModelDrp.addItem("")
self.spoofedModelDrp.setObjectName(u"spoofedModelDrp")
self.spoofedModelDrp.setMaximumSize(QSize(325, 16777215))
self.spoofedModelDrp.setStyleSheet(u"QComboBox {\n"
" background-color: #3b3b3b;\n"
" border: none;\n"
" color: #e8e8e8;\n"
" font-size: 14px;\n"
" padding-left: 8px;\n"
" border-radius: 8px;\n"
"}\n"
"\n"
"QComboBox::drop-down {\n"
" image: url(:/icon/caret-down-fill.svg);\n"
" icon-size: 16px;\n"
" subcontrol-position: right center;\n"
" margin-right: 8px;\n"
"}\n"
"\n"
"QComboBox QAbstractItemView {\n"
" background-color: #3b3b3b;\n"
" outline: none;\n"
" margin-top: 1px;\n"
"}\n"
"\n"
"QComboBox QAbstractItemView::item {\n"
" background-color: #3b3b3b;\n"
" color: #e8e8e8;\n"
" padding-left: 8px;\n"
"}\n"
"\n"
"QComboBox QAbstractItemView::item:hover {\n"
" background-color: #535353;\n"
" color: #ffffff;\n"
"}")
self.verticalLayout_34.addWidget(self.spoofedModelDrp)
self.verticalLayout_16.addWidget(self.aiEnablerContent)
self.verticalSpacer_7 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
@@ -1839,9 +1957,9 @@ class Ui_Nugget(object):
self.horizontalLayout_7.setContentsMargins(-1, 10, -1, 0)
self.chooseGestaltBtn = QToolButton(self.verticalWidget2)
self.chooseGestaltBtn.setObjectName(u"chooseGestaltBtn")
icon18 = QIcon()
icon18.addFile(u":/icon/folder.svg", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.chooseGestaltBtn.setIcon(icon18)
icon19 = QIcon()
icon19.addFile(u":/icon/folder.svg", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.chooseGestaltBtn.setIcon(icon19)
self.chooseGestaltBtn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.horizontalLayout_7.addWidget(self.chooseGestaltBtn)
@@ -1849,12 +1967,12 @@ class Ui_Nugget(object):
self.verticalLayout_24.addLayout(self.horizontalLayout_7)
self.horizontalWidget5 = QWidget(self.verticalWidget2)
self.horizontalWidget5.setObjectName(u"horizontalWidget5")
self.horizontalLayout_17 = QHBoxLayout(self.horizontalWidget5)
self.horizontalWidget4 = QWidget(self.verticalWidget2)
self.horizontalWidget4.setObjectName(u"horizontalWidget4")
self.horizontalLayout_17 = QHBoxLayout(self.horizontalWidget4)
self.horizontalLayout_17.setObjectName(u"horizontalLayout_17")
self.horizontalLayout_17.setContentsMargins(0, 0, 0, 0)
self.applyTweaksBtn = QToolButton(self.horizontalWidget5)
self.applyTweaksBtn = QToolButton(self.horizontalWidget4)
self.applyTweaksBtn.setObjectName(u"applyTweaksBtn")
self.applyTweaksBtn.setIcon(icon9)
self.applyTweaksBtn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
@@ -1862,7 +1980,7 @@ class Ui_Nugget(object):
self.horizontalLayout_17.addWidget(self.applyTweaksBtn)
self.verticalLayout_24.addWidget(self.horizontalWidget5)
self.verticalLayout_24.addWidget(self.horizontalWidget4)
self.statusLbl = QLabel(self.verticalWidget2)
self.statusLbl.setObjectName(u"statusLbl")
@@ -1884,21 +2002,21 @@ class Ui_Nugget(object):
self.verticalLayout_24.addItem(self.verticalSpacer_2)
self.horizontalWidget6 = QWidget(self.verticalWidget2)
self.horizontalWidget6.setObjectName(u"horizontalWidget6")
self.horizontalLayout_25 = QHBoxLayout(self.horizontalWidget6)
self.horizontalWidget5 = QWidget(self.verticalWidget2)
self.horizontalWidget5.setObjectName(u"horizontalWidget5")
self.horizontalLayout_25 = QHBoxLayout(self.horizontalWidget5)
self.horizontalLayout_25.setObjectName(u"horizontalLayout_25")
self.horizontalLayout_25.setContentsMargins(0, 0, 0, 0)
self.horizontalSpacer_14 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
self.horizontalLayout_25.addItem(self.horizontalSpacer_14)
self.removeTweaksBtn = QToolButton(self.horizontalWidget6)
self.removeTweaksBtn = QToolButton(self.horizontalWidget5)
self.removeTweaksBtn.setObjectName(u"removeTweaksBtn")
self.horizontalLayout_25.addWidget(self.removeTweaksBtn)
self.resetGestaltBtn = QToolButton(self.horizontalWidget6)
self.resetGestaltBtn = QToolButton(self.horizontalWidget5)
self.resetGestaltBtn.setObjectName(u"resetGestaltBtn")
self.horizontalLayout_25.addWidget(self.resetGestaltBtn)
@@ -1908,7 +2026,7 @@ class Ui_Nugget(object):
self.horizontalLayout_25.addItem(self.horizontalSpacer_16)
self.verticalLayout_24.addWidget(self.horizontalWidget6)
self.verticalLayout_24.addWidget(self.horizontalWidget5)
self.verticalLayout_6.addWidget(self.verticalWidget2)
@@ -1988,6 +2106,48 @@ class Ui_Nugget(object):
self._21.addWidget(self.allowWifiApplyingChk)
self.skipSetupChk = QCheckBox(self.settingsPageContent)
self.skipSetupChk.setObjectName(u"skipSetupChk")
self.skipSetupChk.setChecked(True)
self._21.addWidget(self.skipSetupChk)
self.autoRebootChk = QCheckBox(self.settingsPageContent)
self.autoRebootChk.setObjectName(u"autoRebootChk")
self.autoRebootChk.setChecked(True)
self._21.addWidget(self.autoRebootChk)
self.verticalSpacer_21 = QSpacerItem(20, 10, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Fixed)
self._21.addItem(self.verticalSpacer_21)
self.label_15 = QLabel(self.settingsPageContent)
self.label_15.setObjectName(u"label_15")
self._21.addWidget(self.label_15)
self.line_20 = QFrame(self.settingsPageContent)
self.line_20.setObjectName(u"line_20")
self.line_20.setStyleSheet(u"QFrame {\n"
" color: #414141;\n"
"}")
self.line_20.setFrameShadow(QFrame.Plain)
self.line_20.setFrameShape(QFrame.Shape.HLine)
self._21.addWidget(self.line_20)
self.deviceSettingsBtns = QHBoxLayout()
self.deviceSettingsBtns.setObjectName(u"deviceSettingsBtns")
self.deviceSettingsBtns.setContentsMargins(-1, -1, -1, 0)
self.resetPairBtn = QToolButton(self.settingsPageContent)
self.resetPairBtn.setObjectName(u"resetPairBtn")
self.deviceSettingsBtns.addWidget(self.resetPairBtn)
self._21.addLayout(self.deviceSettingsBtns)
self.verticalSpacer_51 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
self._21.addItem(self.verticalSpacer_51)
@@ -2101,18 +2261,18 @@ class Ui_Nugget(object):
self.verticalLayout_29.addWidget(self.longitudeTxt)
self.horizontalWidget7 = QWidget(self.verticalWidget3)
self.horizontalWidget7.setObjectName(u"horizontalWidget7")
self.horizontalLayout_3 = QHBoxLayout(self.horizontalWidget7)
self.horizontalWidget6 = QWidget(self.verticalWidget3)
self.horizontalWidget6.setObjectName(u"horizontalWidget6")
self.horizontalLayout_3 = QHBoxLayout(self.horizontalWidget6)
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
self.setLocationBtn = QToolButton(self.horizontalWidget7)
self.setLocationBtn = QToolButton(self.horizontalWidget6)
self.setLocationBtn.setObjectName(u"setLocationBtn")
self.horizontalLayout_3.addWidget(self.setLocationBtn)
self.verticalLayout_29.addWidget(self.horizontalWidget7)
self.verticalLayout_29.addWidget(self.horizontalWidget6)
self.horizontalWidget_22 = QWidget(self.verticalWidget3)
self.horizontalWidget_22.setObjectName(u"horizontalWidget_22")
@@ -2159,9 +2319,9 @@ class Ui_Nugget(object):
" padding-right: 5px;\n"
" border-radius: 0px;\n"
"}")
icon19 = QIcon()
icon19.addFile(u":/icon/pencil.svg", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.toolButton_12.setIcon(icon19)
icon20 = QIcon()
icon20.addFile(u":/icon/pencil.svg", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.toolButton_12.setIcon(icon20)
self.toolButton_12.setIconSize(QSize(25, 25))
self.horizontalLayout_22.addWidget(self.toolButton_12)
@@ -2222,9 +2382,9 @@ class Ui_Nugget(object):
self.importOperationBtn = QToolButton(self.customOperationsPageContent)
self.importOperationBtn.setObjectName(u"importOperationBtn")
self.importOperationBtn.setEnabled(True)
icon20 = QIcon()
icon20.addFile(u":/icon/import.svg", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.importOperationBtn.setIcon(icon20)
icon21 = QIcon()
icon21.addFile(u":/icon/import.svg", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.importOperationBtn.setIcon(icon21)
self.importOperationBtn.setIconSize(QSize(20, 20))
self.importOperationBtn.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
@@ -2236,9 +2396,7 @@ class Ui_Nugget(object):
sizePolicy2.setHeightForWidth(self.newOperationBtn.sizePolicy().hasHeightForWidth())
self.newOperationBtn.setSizePolicy(sizePolicy2)
self.newOperationBtn.setMinimumSize(QSize(0, 35))
icon21 = QIcon()
icon21.addFile(u":/icon/plus.svg", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.newOperationBtn.setIcon(icon21)
self.newOperationBtn.setIcon(icon18)
self.newOperationBtn.setIconSize(QSize(16, 16))
self.newOperationBtn.setCheckable(False)
self.newOperationBtn.setAutoExclusive(True)
@@ -2379,12 +2537,12 @@ class Ui_Nugget(object):
self.horizontalLayout_23.addItem(self.horizontalSpacer_10)
self.horizontalWidget8 = QWidget(self.horizontalWidget_8)
self.horizontalWidget8.setObjectName(u"horizontalWidget8")
self.horizontalLayout_26 = QHBoxLayout(self.horizontalWidget8)
self.horizontalWidget7 = QWidget(self.horizontalWidget_8)
self.horizontalWidget7.setObjectName(u"horizontalWidget7")
self.horizontalLayout_26 = QHBoxLayout(self.horizontalWidget7)
self.horizontalLayout_26.setObjectName(u"horizontalLayout_26")
self.horizontalLayout_26.setContentsMargins(0, 0, 0, 0)
self.importThemeBtn = QToolButton(self.horizontalWidget8)
self.importThemeBtn = QToolButton(self.horizontalWidget7)
self.importThemeBtn.setObjectName(u"importThemeBtn")
self.importThemeBtn.setEnabled(False)
self.importThemeBtn.setStyleSheet(u"QToolButton {\n"
@@ -2393,13 +2551,13 @@ class Ui_Nugget(object):
self.horizontalLayout_26.addWidget(self.importThemeBtn)
self.importThemeFolderBtn = QToolButton(self.horizontalWidget8)
self.importThemeFolderBtn = QToolButton(self.horizontalWidget7)
self.importThemeFolderBtn.setObjectName(u"importThemeFolderBtn")
self.importThemeFolderBtn.setIcon(icon18)
self.importThemeFolderBtn.setIcon(icon19)
self.horizontalLayout_26.addWidget(self.importThemeFolderBtn)
self.importThemeZipBtn = QToolButton(self.horizontalWidget8)
self.importThemeZipBtn = QToolButton(self.horizontalWidget7)
self.importThemeZipBtn.setObjectName(u"importThemeZipBtn")
icon22 = QIcon()
icon22.addFile(u":/icon/file-earmark-zip.svg", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
@@ -2408,7 +2566,7 @@ class Ui_Nugget(object):
self.horizontalLayout_26.addWidget(self.importThemeZipBtn)
self.horizontalLayout_23.addWidget(self.horizontalWidget8)
self.horizontalLayout_23.addWidget(self.horizontalWidget7)
self.verticalLayout_23.addWidget(self.horizontalWidget_8)
@@ -2458,26 +2616,26 @@ class Ui_Nugget(object):
self.verticalLayout_22.addItem(self.verticalSpacer_9)
self.horizontalWidget9 = QWidget(self.themesPageContent)
self.horizontalWidget9.setObjectName(u"horizontalWidget9")
self.horizontalLayout_16 = QHBoxLayout(self.horizontalWidget9)
self.horizontalWidget8 = QWidget(self.themesPageContent)
self.horizontalWidget8.setObjectName(u"horizontalWidget8")
self.horizontalLayout_16 = QHBoxLayout(self.horizontalWidget8)
self.horizontalLayout_16.setObjectName(u"horizontalLayout_16")
self.horizontalLayout_16.setContentsMargins(0, 0, 0, 0)
self.hideNamesBtn = QToolButton(self.horizontalWidget9)
self.hideNamesBtn = QToolButton(self.horizontalWidget8)
self.hideNamesBtn.setObjectName(u"hideNamesBtn")
sizePolicy2.setHeightForWidth(self.hideNamesBtn.sizePolicy().hasHeightForWidth())
self.hideNamesBtn.setSizePolicy(sizePolicy2)
self.horizontalLayout_16.addWidget(self.hideNamesBtn)
self.borderAllBtn = QToolButton(self.horizontalWidget9)
self.borderAllBtn = QToolButton(self.horizontalWidget8)
self.borderAllBtn.setObjectName(u"borderAllBtn")
sizePolicy2.setHeightForWidth(self.borderAllBtn.sizePolicy().hasHeightForWidth())
self.borderAllBtn.setSizePolicy(sizePolicy2)
self.horizontalLayout_16.addWidget(self.borderAllBtn)
self.addAllBtn = QToolButton(self.horizontalWidget9)
self.addAllBtn = QToolButton(self.horizontalWidget8)
self.addAllBtn.setObjectName(u"addAllBtn")
sizePolicy2.setHeightForWidth(self.addAllBtn.sizePolicy().hasHeightForWidth())
self.addAllBtn.setSizePolicy(sizePolicy2)
@@ -2485,7 +2643,7 @@ class Ui_Nugget(object):
self.horizontalLayout_16.addWidget(self.addAllBtn)
self.verticalLayout_22.addWidget(self.horizontalWidget9)
self.verticalLayout_22.addWidget(self.horizontalWidget8)
self.verticalLayout_23.addWidget(self.themesPageContent)
@@ -2507,6 +2665,7 @@ class Ui_Nugget(object):
self.devicePicker.setCurrentIndex(-1)
self.pages.setCurrentIndex(0)
self.dynamicIslandDrp.setCurrentIndex(0)
self.spoofedModelDrp.setCurrentIndex(0)
QMetaObject.connectSlotsByName(Nugget)
@@ -2559,7 +2718,7 @@ class Ui_Nugget(object):
self.toolButton_15.setText(QCoreApplication.translate("Nugget", u"Additional Thanks", None))
self.libiBtn.setText(QCoreApplication.translate("Nugget", u"pymobiledevice3", None))
self.qtBtn.setText(QCoreApplication.translate("Nugget", u"Qt Creator", None))
self.label.setText(QCoreApplication.translate("Nugget", u"Nugget GUI - Version 3.0", None))
self.label.setText(QCoreApplication.translate("Nugget", u"Nugget GUI - Version 4.0", None))
self.statusBarLbl.setText(QCoreApplication.translate("Nugget", u"Mobile Gestalt", None))
self.label_9.setText(QCoreApplication.translate("Nugget", u"Device Subtype Preset", None))
self.dynamicIslandDrp.setItemText(0, QCoreApplication.translate("Nugget", u"None", None))
@@ -2589,8 +2748,11 @@ class Ui_Nugget(object):
self.internalInstallChk.setText(QCoreApplication.translate("Nugget", u"Set as Apple Internal Install (ie Metal HUD in any app)", None))
self.internalStorageChk.setText(QCoreApplication.translate("Nugget", u"Enable Internal Storage (WARNING: risky for some devices, mainly iPads)", None))
self.collisionSOSChk.setText(QCoreApplication.translate("Nugget", u"Enable Collision SOS", None))
self.sleepApneaChk.setText(QCoreApplication.translate("Nugget", u"Enable Sleep Apnea (real) [for Apple Watches]", None))
self.aodChk.setText(QCoreApplication.translate("Nugget", u"Enable Always On Display", None))
self.label_10.setText(QCoreApplication.translate("Nugget", u"Custom Gestalt Keys", None))
self.addGestaltKeyBtn.setText(QCoreApplication.translate("Nugget", u" Add Key", None))
self.label_12.setText(QCoreApplication.translate("Nugget", u"Warning: Using this feature incorrectly can lead to bootloops and data loss. Only use if you know\n"
"what you are doing.", None))
self.internalOptionsLbl.setText(QCoreApplication.translate("Nugget", u"Feature Flags", None))
self.clockAnimChk.setText(QCoreApplication.translate("Nugget", u"Enable Lockscreen Clock Animation", None))
self.lockscreenChk.setText(QCoreApplication.translate("Nugget", u"Enable Duplicate Lockscreen Button and Lockscreen Quickswitch", None))
@@ -2610,9 +2772,17 @@ class Ui_Nugget(object):
self.aiInfoLabel.setText(QCoreApplication.translate("Nugget", u"In order to download the AI model, you must spoof the device model. This will break Face ID until\n"
"you revert.\n"
"\n"
"Once the model has downloaded, disable \"Spoof Device Model\" and click the \"Apply Tweaks\"\n"
"Once the model has downloaded, set \"Spoofed Device Model\" to \"None\" and click the \"Apply Tweaks\"\n"
"button on the \"Apply\" page again to fix Face ID.", None))
self.spoofModelChk.setText(QCoreApplication.translate("Nugget", u"Spoof Device Model", None))
self.label_8.setText(QCoreApplication.translate("Nugget", u"Spoofed Device Model", None))
self.spoofedModelDrp.setItemText(0, QCoreApplication.translate("Nugget", u"None", None))
self.spoofedModelDrp.setItemText(1, QCoreApplication.translate("Nugget", u"iPhone16,2 (iPhone 15 Pro)", None))
self.spoofedModelDrp.setItemText(2, QCoreApplication.translate("Nugget", u"iPhone17,4 (iPhone 16 Plus)", None))
self.spoofedModelDrp.setItemText(3, QCoreApplication.translate("Nugget", u"iPhone17,3 (iPhone 16 Pro)", None))
self.spoofedModelDrp.setItemText(4, QCoreApplication.translate("Nugget", u"iPhone17,2 (iPhone 16 Pro Max)", None))
self.spoofedModelDrp.setItemText(5, QCoreApplication.translate("Nugget", u"iPad16,3 (iPad Pro M4)", None))
self.spoofedModelDrp.setCurrentText(QCoreApplication.translate("Nugget", u"None", None))
self.springboardOptionsLbl.setText(QCoreApplication.translate("Nugget", u"Springboard Options", None))
self.label_13.setText(QCoreApplication.translate("Nugget", u"Lock Screen Footnote Text", None))
self.footnoteTxt.setPlaceholderText(QCoreApplication.translate("Nugget", u"Footnote Text", None))
@@ -2648,6 +2818,10 @@ class Ui_Nugget(object):
self.resetGestaltBtn.setText(QCoreApplication.translate("Nugget", u"Reset Mobile Gestalt", None))
self.springboardOptionsLbl1.setText(QCoreApplication.translate("Nugget", u"Nugget Settings", None))
self.allowWifiApplyingChk.setText(QCoreApplication.translate("Nugget", u"Allow Applying Over WiFi", None))
self.skipSetupChk.setText(QCoreApplication.translate("Nugget", u"Skip Setup * (non-exploit files only)", None))
self.autoRebootChk.setText(QCoreApplication.translate("Nugget", u"Auto Reboot After Applying", None))
self.label_15.setText(QCoreApplication.translate("Nugget", u"* Note: Skip Setup may cause issues with configuration profiles. Turn it off if you need that.", None))
self.resetPairBtn.setText(QCoreApplication.translate("Nugget", u"Reset Device Pairing", None))
self.statusBarLbl_2.setText(QCoreApplication.translate("Nugget", u"Location Simulation", None))
self.label_4.setText("")
self.loadLocSimBtn.setText(QCoreApplication.translate("Nugget", u"Start Location Simulation", None))

View File

@@ -0,0 +1,94 @@
from enum import Enum
from json import loads
from .tweak_classes import MobileGestaltTweak
class ValueType(Enum):
Integer = "Integer"
Float = "Float"
String = "String"
Array = "Array"
Dictionary = "Dictionary"
ValueTypeStrings: list[ValueType] = [
ValueType.Integer.value, ValueType.Float.value,
ValueType.String.value,
ValueType.Array.value, ValueType.Dictionary.value
]
class CustomGestaltTweak:
def __init__(self, tweak: MobileGestaltTweak, value_type: ValueType):
self.tweak = tweak
self.value_type = value_type
self.deactivated = False
# TODO: change everything to not return the dict since it is passed by reference
def apply_tweak(self, plist: dict) -> dict:
if self.deactivated or self.tweak.key == "":
# key was not set, don't apply (maybe user added it by accident)
return plist
self.tweak.enabled = True
# set the value to be as the specified value type
if self.value_type == ValueType.Integer:
self.tweak.value = int(self.tweak.value)
elif self.value_type == ValueType.Float:
self.tweak.value = float(self.tweak.value)
elif self.value_type == ValueType.Array or self.value_type == ValueType.Dictionary:
# json convert string to array/dict
self.tweak.value = loads(self.tweak.value)
# apply the tweak after updating the value
plist = self.tweak.apply_tweak(plist)
return plist
class CustomGestaltTweaks:
custom_tweaks: list[CustomGestaltTweak] = []
def create_tweak(key: str="", value: str="1", value_type: ValueType = ValueType.Integer) -> int:
new_tweak = MobileGestaltTweak("", key, value=value)
CustomGestaltTweaks.custom_tweaks.append(CustomGestaltTweak(new_tweak, value_type))
# return the tweak id
return len(CustomGestaltTweaks.custom_tweaks) - 1
def set_tweak_key(id: int, key: str):
CustomGestaltTweaks.custom_tweaks[id].tweak.key = key
def set_tweak_value(id: int, value: str):
CustomGestaltTweaks.custom_tweaks[id].tweak.value = value
def set_tweak_value_type(id: int, value_type) -> str:
new_value_type = value_type
if isinstance(value_type, str):
# based on string value
new_value_type = ValueType(value_type)
elif isinstance(value_type, int):
# based on index of the string
new_value_type = ValueType(ValueTypeStrings[value_type])
CustomGestaltTweaks.custom_tweaks[id].value_type = new_value_type
# update the value to be of the new type
new_value = 1
new_str = "1"
if new_value_type == ValueType.Float:
new_value = 1.0
new_str = "1.0"
elif new_value_type == ValueType.String:
new_value = ""
new_str = ""
elif new_value_type == ValueType.Array:
new_value = []
new_str = "[ ]"
elif new_value_type == ValueType.Dictionary:
new_value = {}
new_str = "{ }"
CustomGestaltTweaks.custom_tweaks[id].tweak.value = new_value
return new_str
def deactivate_tweak(id: int):
CustomGestaltTweaks.custom_tweaks[id].deactivated = True
CustomGestaltTweaks.custom_tweaks[id].tweak = None
def apply_tweaks(plist: dict):
for tweak in CustomGestaltTweaks.custom_tweaks:
plist = tweak.apply_tweak(plist)
return plist

View File

@@ -147,7 +147,7 @@ class MobileGestaltPickerTweak(Tweak):
self.selected_option = 0 # index of the selected option
def apply_tweak(self, plist: dict):
if not self.enabled:
if not self.enabled or self.value[self.selected_option] == "Placeholder":
return plist
new_value = self.value[self.selected_option]
if self.subkey == None:

View File

@@ -42,7 +42,7 @@ tweaks = {
## AI Enabler
"AIEligibility": AITweak(),
"AIGestalt": MobileGestaltTweak("Enable Apple Intelligence (for Unsupported Devices) (Gestalt)", "A62OafQ85EJAiiqKn4agtg", min_version=Version("18.1")),
"SpoofModel": MobileGestaltTweak("Spoof Device Model", "h9jDsbgj7xIVeIQ8S3/X3Q", value="iPhone17,3", min_version=Version("18.1"), divider_below=True),
"SpoofModel": MobileGestaltPickerTweak("Spoofed Device Model", "h9jDsbgj7xIVeIQ8S3/X3Q", values=["Placeholder", "iPhone16,2", "iPhone17,4", "iPhone17,3", "iPhone17,2", "iPad16,3"], min_version=Version("18.1"), divider_below=True),
## Springboard Tweaks
"LockScreenFootnote": BasicPlistTweak(