mirror of
https://github.com/leminlimez/Nugget.git
synced 2025-04-08 04:23:05 +08:00
15
README.md
15
README.md
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
|
||||
233
cli_app.py
233
cli_app.py
@@ -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)
|
||||
@@ -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):
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
@@ -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):
|
||||
|
||||
@@ -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
2822
mainwindow_ui.py
Normal file
File diff suppressed because it is too large
Load Diff
517
qt/mainwindow.ui
517
qt/mainwindow.ui
@@ -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 "Spoof Device Model" and click the "Apply Tweaks"
|
||||
Once the model has downloaded, set "Spoofed Device Model" to "None" and click the "Apply Tweaks"
|
||||
button on the "Apply" 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 "Apply" 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">
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
|
||||
94
tweaks/custom_gestalt_tweaks.py
Normal file
94
tweaks/custom_gestalt_tweaks.py
Normal 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
|
||||
@@ -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:
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user