Enhance user prompts, add temporary dir handling

This commit is contained in:
Hoang Hong Quan
2025-10-22 00:59:12 +07:00
parent c4ed8bb4fe
commit 542ad9623c
8 changed files with 197 additions and 168 deletions
+1 -3
View File
@@ -3331,9 +3331,7 @@ DefinitionBlock ("", "SSDT", 2, "ZPSS", "WMIS", 0x00000000)
if kext.checked:
line = "\033[1;32m{}\033[0m".format(line)
contents.append(line)
contents.append("\033[1;36m")
contents.append("Note: You can select multiple kexts by entering their indices separated by commas (e.g., '1, 2, 3').")
contents.append("\033[0m")
contents.append("\033[1;93mNote:\033[0m You can select multiple kexts by entering their indices separated by commas (e.g., '1, 2, 3').")
contents.append("B. Back")
contents.append("Q. Quit")
contents.append("")
+3 -3
View File
@@ -221,7 +221,7 @@ class CompatibilityChecker:
print("{}- Audio Endpoint{}: {}".format(" "*6, "s" if len(audio_endpoints) > 1 else "", ", ".join(audio_endpoints)))
def check_biometric_compatibility(self):
print(" \033[93mNote:\033[0m Biometric authentication in macOS requires Apple T2 Chip,")
print(" \033[1;93mNote:\033[0m Biometric authentication in macOS requires Apple T2 Chip,")
print(" which is not available for Hackintosh systems.")
print("")
for biometric_device, biometric_props in self.hardware_report.get("Biometric", {}).items():
@@ -273,10 +273,10 @@ class CompatibilityChecker:
print("{}- Continuity Support: \033[1;32mFull\033[0m (AirDrop, Handoff, Universal Clipboard, Instant Hotspot,...)".format(" "*6))
elif device_id in pci_data.IntelWiFiIDs:
print("{}- Continuity Support: \033[1;33mPartial\033[0m (Handoff and Universal Clipboard with AirportItlwm)".format(" "*6))
print("{}\033[93mNote:\033[0m AirDrop, Universal Clipboard, Instant Hotspot,... not available".format(" "*6))
print("{}\033[1;93mNote:\033[0m AirDrop, Universal Clipboard, Instant Hotspot,... not available".format(" "*6))
elif device_id in pci_data.AtherosWiFiIDs:
print("{}- Continuity Support: \033[1;31mLimited\033[0m (No Continuity features available)".format(" "*6))
print("{}\033[93mNote:\033[0m Atheros cards are not recommended for macOS".format(" "*6))
print("{}\033[1;93mNote:\033[0m Atheros cards are not recommended for macOS".format(" "*6))
if "OCLP Compatibility" in device_props:
print("{}- OCLP Compatibility: {}".format(" "*6, self.show_macos_compatibility(device_props.get("OCLP Compatibility"))))
+1 -1
View File
@@ -286,7 +286,7 @@ class ConfigProdigy:
else:
contents.append(line)
contents.append("")
contents.append("\033[93mNote:\033[0m")
contents.append("\033[1;93mNote:\033[0m")
contents.append("- The default layout may not be optimal.")
contents.append("- Test different layouts to find what works best for your system.")
contents.append("")
+1 -2
View File
@@ -3,7 +3,6 @@ from Scripts import kext_maestro
from Scripts import resource_fetcher
from Scripts import utils
import os
import tempfile
import shutil
import subprocess
import platform
@@ -21,7 +20,7 @@ class gatheringFiles:
self.amd_vanilla_patches_url = "https://raw.githubusercontent.com/AMD-OSX/AMD_Vanilla/beta/patches.plist"
self.aquantia_macos_patches_url = "https://raw.githubusercontent.com/CaseySJ/Aquantia-macOS-Patches/refs/heads/main/CaseySJ-Aquantia-Patch-Sets-1-and-2.plist"
self.hyper_threading_patches_url = "https://github.com/b00t0x/CpuTopologyRebuild/raw/refs/heads/master/patches_ht.plist"
self.temporary_dir = tempfile.mkdtemp()
self.temporary_dir = self.utils.get_temporary_dir()
self.ock_files_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "OCK_Files")
self.bootloader_kexts_data_path = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "bootloader_kexts_data.json")
self.download_history_file = os.path.join(self.ock_files_dir, "history.json")
+18 -18
View File
@@ -122,7 +122,7 @@ class KextMaestro:
for codec_properties in hardware_report.get("Sound", {}).values():
if codec_properties.get("Device ID") in codec_layouts.data:
if self.utils.parse_darwin_version(macos_version) >= self.utils.parse_darwin_version("25.0.0"):
print("\n\033[93mNote:\033[0m Since macOS Tahoe 26 DP2, Apple has removed AppleHDA kext and uses the Apple T2 chip for audio management.")
print("\n\033[1;93mNote:\033[0m Since macOS Tahoe 26 DP2, Apple has removed AppleHDA kext and uses the Apple T2 chip for audio management.")
print("To use AppleALC, you must rollback AppleHDA. Alternatively, you can use VoodooHDA.")
print("")
print("1. \033[1mAppleALC\033[0m - Requires AppleHDA rollback with \033[1;93mOpenCore Legacy Patcher\033[0m")
@@ -179,8 +179,8 @@ class KextMaestro:
recommended_option = 1
recommended_name = "NootRX"
max_option = 3
print("\033[93mNote:\033[0m - Since macOS Tahoe 26, WhateverGreen has known connector patching issues for AMD {} GPUs.".format(gpu_props.get("Codename")))
print(" - To avoid this, you can use NootRX or choose not to install a GPU kext.")
print("\033[1;93mNote:\033[0m Since macOS Tahoe 26, WhateverGreen has known connector patching issues for AMD {} GPUs.".format(gpu_props.get("Codename")))
print("To avoid this, you can use NootRX or choose not to install a GPU kext.")
print("")
print("1. \033[1mNootRX\033[0m - Uses latest GPU firmware")
print("2. \033[1mWhateverGreen\033[0m - Uses original Apple firmware")
@@ -189,16 +189,17 @@ class KextMaestro:
recommended_option = 2
recommended_name = "WhateverGreen"
max_option = 2
print("\033[93mNote:\033[0m - AMD {} GPUs have two available kext options:".format(gpu_props.get("Codename")))
print(" - You can try different kexts after installation to find the best one for your system")
print("\033[1;93mNote:\033[0m")
print("- AMD {} GPUs have two available kext options:".format(gpu_props.get("Codename")))
print("- You can try different kexts after installation to find the best one for your system")
print("")
print("1. \033[1mNootRX\033[0m - Uses latest GPU firmware")
print("2. \033[1mWhateverGreen\033[0m - Uses original Apple firmware")
print("")
if any(other_gpu_props.get("Manufacturer") == "Intel" for other_gpu_props in hardware_report.get("GPU", {}).values()):
print("\033[91mImportant:\033[0m - NootRX kext is not compatible with Intel GPUs")
print(" - Automatically selecting WhateverGreen kext due to Intel GPU compatibility")
print("\033[91mImportant:\033[0m NootRX kext is not compatible with Intel GPUs")
print("Automatically selecting WhateverGreen kext due to Intel GPU compatibility")
print("")
self.utils.request_input("Press Enter to continue...")
continue
@@ -221,9 +222,9 @@ class KextMaestro:
if self.utils.parse_darwin_version(macos_version) >= self.utils.parse_darwin_version("25.0.0"):
print("\n*** Found {} is AMD {} GPU.".format(gpu_name, gpu_props.get("Codename")))
print("")
print("\033[93mNote:\033[0m - Since macOS Tahoe 26, WhateverGreen has known connector patching issues for AMD GPUs.")
print(" - The current recommendation is to not use WhateverGreen.")
print(" - However, you can still try adding it to see if it works on your system.")
print("\033[1;93mNote:\033[0m Since macOS Tahoe 26, WhateverGreen has known connector patching issues for AMD GPUs.")
print("The current recommendation is to not use WhateverGreen.")
print("However, you can still try adding it to see if it works on your system.")
print("")
self.utils.request_input("Press Enter to continue...")
break
@@ -254,7 +255,7 @@ class KextMaestro:
elif device_id in pci_data.IntelWiFiIDs:
print("\n*** Found {} is Intel WiFi device.".format(network_name))
print("")
print("\033[93mNote:\033[0m Intel WiFi devices have two available kext options:")
print("\033[1;93mNote:\033[0m Intel WiFi devices have two available kext options:")
print("")
print("1. \033[1mAirportItlwm\033[0m - Uses native WiFi settings menu")
print(" • Provides Handoff, Universal Clipboard, Location Services, Instant Hotspot support")
@@ -303,7 +304,7 @@ class KextMaestro:
selected_kexts.append("IOSkywalkFamily")
elif self.utils.parse_darwin_version(macos_version) >= self.utils.parse_darwin_version("23.0.0"):
print("")
print("\033[93mNote:\033[0m Since macOS Sonoma 14, iServices won't work with AirportItlwm without patches")
print("\033[1;93mNote:\033[0m Since macOS Sonoma 14, iServices won't work with AirportItlwm without patches")
print("")
while True:
option = self.utils.request_input("Apply OCLP root patch to fix iServices? (yes/No): ").strip().lower()
@@ -651,11 +652,10 @@ class KextMaestro:
for index, (kext_name, is_lilu_dependent) in enumerate(incompatible_kexts, start=1):
print("{:2}. {:25}{}".format(index, kext_name, " - Lilu Plugin" if is_lilu_dependent else ""))
print("\n\033[1;36m")
print("Note:")
print("\n\033[1;93mNote:\033[0m")
print("- With Lilu plugins, using the \"-lilubetaall\" boot argument will force them to load.")
print("- Forcing unsupported kexts can cause system instability. \033[0;31mProceed with caution.\033[0m")
print("\033[0m")
print("")
option = self.utils.request_input("Do you want to force load {} on the unsupported macOS version? (yes/No): ".format("these kexts" if len(incompatible_kexts) > 1 else "this kext"))
@@ -684,12 +684,12 @@ class KextMaestro:
elif not self.utils.parse_darwin_version(kext.min_darwin_version) <= self.utils.parse_darwin_version(macos_version) <= self.utils.parse_darwin_version(kext.max_darwin_version):
line = "\033[90m{}\033[0m".format(line)
contents.append(line)
contents.append("\033[1;36m")
contents.append("Note:")
contents.append("")
contents.append("\033[1;93mNote:\033[0m")
contents.append("- Lines in gray indicate kexts that are not supported by the current macOS version ({}).".format(macos_version))
contents.append("- When a plugin of a kext is selected, the entire kext will be automatically selected.")
contents.append("- You can select multiple kexts by entering their indices separated by commas (e.g., '1, 2, 3').")
contents.append("\033[0m")
contents.append("")
contents.append("B. Back")
contents.append("Q. Quit")
contents.append("")
+63 -36
View File
@@ -8,11 +8,30 @@ import binascii
import subprocess
import pathlib
import zipfile
import tempfile
class Utils:
def __init__(self, script_name = "OpCore Simplify"):
self.script_name = script_name
self.clean_temporary_dir()
def clean_temporary_dir(self):
temporary_dir = tempfile.gettempdir()
for file in os.listdir(temporary_dir):
if file.startswith("ocs_"):
if not os.path.isdir(os.path.join(temporary_dir, file)):
continue
try:
shutil.rmtree(os.path.join(temporary_dir, file))
except Exception as e:
pass
def get_temporary_dir(self):
return tempfile.mkdtemp(prefix="ocs_")
def write_file(self, file_path, data):
file_extension = os.path.splitext(file_path)[1]
@@ -78,18 +97,13 @@ class Utils:
def hex_to_bytes(self, string):
try:
# Remove non-hex characters (e.g., hyphens)
hex_string = re.sub(r'[^0-9a-fA-F]', '', string)
if len(re.sub(r"\s+", "", string)) != len(hex_string):
return string
# Convert hex string to bytes
bytes_data = binascii.unhexlify(hex_string)
return bytes_data
return binascii.unhexlify(hex_string)
except binascii.Error:
# Handle invalid hex string
return string
def int_to_hex(self, number):
@@ -98,9 +112,7 @@ class Utils:
def to_little_endian_hex(self, hex_string):
hex_string = hex_string.lower().lstrip("0x")
little_endian_hex = ''.join(reversed([hex_string[i:i+2] for i in range(0, len(hex_string), 2)]))
return little_endian_hex.upper()
return ''.join(reversed([hex_string[i:i+2] for i in range(0, len(hex_string), 2)])).upper()
def string_to_hex(self, string):
return ''.join(format(ord(char), '02X') for char in string)
@@ -118,29 +130,20 @@ class Utils:
return next((item for item in data[start:end] if item.lower() in search_item.lower()), None)
def normalize_path(self, path):
# Remove all surrounding quotes if present
path = re.sub(r'^[\'"]+|[\'"]+$', '', path)
# Remove trailing spaces
path = path.strip()
# Expand ~ to the user's home directory
path = os.path.expanduser(path)
# Normalize path separators for the target operating system
if os.name == 'nt': # Windows
# Replace single backslashes with forward slashes
if os.name == 'nt':
path = path.replace('\\', '/')
# Remove redundant slashes
path = re.sub(r'/+', '/', path)
else:
# Remove backslashes
path = path.replace('\\', '')
# Normalize the path
path = os.path.normpath(path)
# Convert the path to an absolute path and normalize it according to the OS
return str(pathlib.Path(path).resolve())
def parse_darwin_version(self, darwin_version):
@@ -155,36 +158,47 @@ class Utils:
subprocess.run(['xdg-open', folder_path])
elif os.name == 'nt':
os.startfile(folder_path)
else:
raise NotImplementedError("This function is only supported on macOS, Windows, and Linux.")
def request_input(self, prompt="Press Enter to continue..."):
try:
user_response = input(prompt)
except NameError:
if sys.version_info[0] < 3:
user_response = raw_input(prompt)
else:
user_response = input(prompt)
if not isinstance(user_response, str):
user_response = str(user_response)
return user_response
def clear_screen(self):
os.system('cls' if os.name=='nt' else 'clear')
def progress_bar(self, title, steps, current_step_index, done=False):
self.head(title)
print("")
if done:
for step in steps:
print(" [\033[92m✓\033[0m] {}".format(step))
else:
for i, step in enumerate(steps):
if i < current_step_index:
print(" [\033[92m✓\033[0m] {}".format(step))
elif i == current_step_index:
print(" [\033[1;93m>\033[0m] {}...".format(step))
else:
print(" [ ] {}".format(step))
print("")
def head(self, text = None, width = 68, resize=True):
if resize:
self.adjust_window_size()
self.clear_screen()
os.system('cls' if os.name=='nt' else 'clear')
if text == None:
text = self.script_name
separator = "#" * width
separator = "" * (width - 2)
title = " {} ".format(text)
if len(title) > width - 2:
title = title[:width-4] + "..."
title = title.center(width - 2) # Center the title within the width minus 2 for the '#' characters
title = title.center(width - 2)
print("{}\n#{}#\n{}".format(separator, title, separator))
print("{}\n{}\n{}".format(separator, title, separator))
def adjust_window_size(self, content=""):
lines = content.splitlines()
@@ -194,14 +208,27 @@ class Utils:
def exit_program(self):
self.head()
width = 68
print("")
print("For more information, to report errors, or to contribute to the product:")
print("* Facebook: https://www.facebook.com/macforce2601")
print("* Telegram: https://t.me/lzhoang2601")
print("* GitHub: https://github.com/lzhoang2801/OpCore-Simplify")
print("For more information, to report errors, or to contribute to the product:".center(width))
print("")
print("Thank you for using our program!")
separator = "" * (width - 4)
print(f"{separator}")
contacts = {
"Facebook": "https://www.facebook.com/macforce2601",
"Telegram": "https://t.me/lzhoang2601",
"GitHub": "https://github.com/lzhoang2801/OpCore-Simplify"
}
for platform, link in contacts.items():
line = f" * {platform}: {link}"
print(f"{line.ljust(width - 4)}")
print(f"{separator}")
print("")
self.request_input("Press Enter to exit.")
print("Thank you for using our program!".center(width))
print("")
self.request_input("Press Enter to exit.".center(width))
sys.exit(0)
+1 -1
View File
@@ -226,7 +226,7 @@ class WifiProfileExtractor:
self.utils.head("WiFi Profile Extractor")
print("")
print("\033[93mNote:\033[0m")
print("\033[1;93mNote:\033[0m")
print("- When using itlwm kext, WiFi appears as Ethernet in macOS")
print("- You'll need Heliport app to manage WiFi connections in macOS")
print("- This step will enable auto WiFi connections at boot time")