Merge branch 'main' into main

This commit is contained in:
Mykola Grymalyuk
2023-03-28 14:15:56 -06:00
committed by GitHub
45 changed files with 1827 additions and 1423 deletions

View File

@@ -1,5 +1,17 @@
# OpenCore Legacy Patcher changelog # OpenCore Legacy Patcher changelog
## 0.6.3
- Update non-Metal Binaries:
- Resolves Safari 16.4 rendering issue
- Resolves left side menubar selections
- Implements automatic menubar text color
- New Menubar implementation can be disabled via `defaults write -g Amy.MenuBar2Beta -bool false`
- Implement full IOUSBHostFamily downgrade for UHCI/OHCI
- Resolves panics on certain iMac models
- Resolve unused KDKs not being properly cleaned up
- Increment Binaries:
- PatcherSupportPkg 0.9.2 - release
## 0.6.2 ## 0.6.2
- Work around Black Box rendering issues on certain Display Color Profiles - Work around Black Box rendering issues on certain Display Color Profiles
- Limited to Ventura currently due to limitations with other color profiles - Limited to Ventura currently due to limitations with other color profiles
@@ -19,14 +31,21 @@
- Fixed System Settings hover effects, including Bluetooth connect button - Fixed System Settings hover effects, including Bluetooth connect button
- Add Books hacks (reimplement cover image generation, disable broken page curl animation) - Add Books hacks (reimplement cover image generation, disable broken page curl animation)
- Fixed unresponsive buttons - Fixed unresponsive buttons
- Implement Hardware Encoding support for AMD Polaris and Vega GPUs - Implement Hardware Encoding support for AMD GCN 1-3, Polaris and Vega GPUs
- Applicable for pre-Haswell Macs on macOS Ventura - Applicable for pre-Haswell Macs on macOS Ventura
- Resolves DRM playback issues on Netflix, Disney+, etc. - Resolves DRM playback issues on Netflix, Disney+, etc.
- Note: GCN 1-3 DRM is functional, however hardware video encoding is still experimental
- AppleTV+ may be unstable due to this
- Implement support for AMD Navi and Lexa MXM GPUs in 2009-2011 iMacs - Implement support for AMD Navi and Lexa MXM GPUs in 2009-2011 iMacs
- Primarily applicable for MXM 3.0 variants of AMD WX3200 (0x6981) and AMD RX5500XT (0x7340) - Primarily applicable for MXM 3.0 variants of AMD WX3200 (0x6981) and AMD RX5500XT (0x7340)
- Credit to [Ausdauersportler](https://github.com/Ausdauersportler) for implementation - Credit to [Ausdauersportler](https://github.com/Ausdauersportler) for implementation
- Implement Continuity Camera Unlocking for pre-Kaby Lake CPUs - Implement Continuity Camera Unlocking for pre-Kaby Lake CPUs
- Applicable for all legacy Macs in macOS Ventura - Applicable for all legacy Macs in macOS Ventura
- Resolve boot support for 3802-based GPUs with macOS 13.3
- Applicable for following GPUs:
- Intel Ivy Bridge and Haswell iGPUs
- Nvidia Kepler dGPUs
- Note: patchset now requires AMFI to be disabled, patchset still in active development to remove this requirement
- Backend Changes: - Backend Changes:
- Refactored kdk_handler.py - Refactored kdk_handler.py
- Prioritizes KdkSupportPkg repository for downloads - Prioritizes KdkSupportPkg repository for downloads
@@ -34,7 +53,7 @@
- Support local loose matching when no network connection is available - Support local loose matching when no network connection is available
- Implement pkg receipt verification to validate integrity of KDKs - Implement pkg receipt verification to validate integrity of KDKs
- Implemented logging framework usage for more reliable logging - Implemented logging framework usage for more reliable logging
- Logs are stored under `~/OpenCore-Patcher.log` - Logs are stored under `~/Library/Logs/OpenCore-Patcher.log`
- Subsequent runs are appended to the log, allowing for easy debugging - Subsequent runs are appended to the log, allowing for easy debugging
- Implemented new network_handler.py module - Implemented new network_handler.py module
- Allows for more reliable network calls and downloads - Allows for more reliable network calls and downloads
@@ -54,9 +73,14 @@
- pyinstaller - 5.7.0 - pyinstaller - 5.7.0
- packaging - 23.0 - packaging - 23.0
- Increment Binaries: - Increment Binaries:
- PatcherSupportPkg 0.8.4 - release - PatcherSupportPkg 0.8.7 - release
- AutoPkgInstaller 1.0.2 - release - AutoPkgInstaller 1.0.2 - release
- FeatureUnlock 1.1.4 - rolling (0e8d87f) - FeatureUnlock 1.1.4 - rolling (0e8d87f)
- Lilu 1.6.4 - release
- WhateverGreen 1.6.4 - release
- NVMeFix 1.1.0 - release
- Innie 1.3.1 - release
- OpenCorePkg 0.9.0 - release
## 0.6.1 ## 0.6.1
- Avoid usage of KDKlessWorkaround on hardware not requiring it - Avoid usage of KDKlessWorkaround on hardware not requiring it

File diff suppressed because it is too large Load Diff

View File

@@ -2699,6 +2699,8 @@
<true/> <true/>
<key>ResizeGpuBars</key> <key>ResizeGpuBars</key>
<integer>-1</integer> <integer>-1</integer>
<key>ResizeUsePciRbIo</key>
<false/>
<key>TscSyncTimeout</key> <key>TscSyncTimeout</key>
<integer>0</integer> <integer>0</integer>
<key>UnblockFsConnect</key> <key>UnblockFsConnect</key>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,253 @@
#!/usr/bin/env python3
import os
import subprocess
from pathlib import Path
import requests
import packaging.version
import tempfile
# For kexts with basic handling requirements
KEXT_DICTIONARY = {
"Acidanthera": {
"AirportBrcmFixup": {
"Repository": "https://github.com/acidanthera/AirportBrcmFixup",
"Constants Variable": "self.airportbcrmfixup_version",
},
# Due to issues with legacy Macs, don't update
# "AppleALC": {
# "Repository": "https://github.com/acidanthera/AppleALC",
# "Constants Variable": "self.applealc_version",
# },
"BlueToolFixup": {
"Repository": "https://github.com/acidanthera/BrcmPatchRAM",
"Constants Variable": "self.bluetoolfixup_version",
"Override": "BrcmPatchRAM",
},
"CPUFriend": {
"Repository": "https://github.com/acidanthera/CPUFriend",
"Constants Variable": "self.cpufriend_version",
},
"CryptexFixup": {
"Repository": "https://github.com/acidanthera/CryptexFixup",
"Constants Variable": "self.cryptexfixup_version",
},
"DebugEnhancer": {
"Repository": "https://github.com/acidanthera/DebugEnhancer",
"Constants Variable": "self.debugenhancer_version",
},
"FeatureUnlock": {
"Repository": "https://github.com/acidanthera/FeatureUnlock",
"Constants Variable": "self.featureunlock_version",
},
"Lilu": {
"Repository": "https://github.com/acidanthera/Lilu",
"Constants Variable": "self.lilu_version",
},
"NVMeFix": {
"Repository": "https://github.com/acidanthera/NVMeFix",
"Constants Variable": "self.nvmefix_version",
},
"RestrictEvents": {
"Repository": "https://github.com/acidanthera/RestrictEvents",
"Constants Variable": "self.restrictevents_version",
},
"RSRHelper": {
"Repository": "https://github.com/khronokernel/RSRHelper",
"Constants Variable": "self.rsrhelper_version",
},
"WhateverGreen": {
"Repository": "https://github.com/acidanthera/WhateverGreen",
"Constants Variable": "self.whatevergreen_version",
},
},
"Misc": {
"Innie": {
"Repository": "https://github.com/cdf/Innie",
"Constants Variable": "self.innie_version",
},
},
}
class GenerateKexts:
def __init__(self):
self.weg_version = None
self.weg_old = None
self.lilu_version = None
self._set_cwd()
self._iterate_over_kexts()
self._special_kext_handling()
def _set_cwd(self):
# Set working directory to script location
script_path = Path(__file__).parent.absolute()
os.chdir(script_path)
def _special_kext_handling(self):
# Generate custom WhateverGreen
if self.weg_version is None or self.lilu_version is None or self.weg_old is None:
raise Exception("Unable to find latest WEG version!")
if packaging.version.parse(self.weg_version) <= packaging.version.parse(self.weg_old):
print(" WEG is up to date!")
return
# WhateverGreen
print("Building modified WhateverGreen...")
# We have to compile WEG ourselves
weg_source_url = f"https://github.com/acidanthera/WhateverGreen/archive/refs/tags/{self.weg_version}.zip"
lilu_url = f"https://github.com/acidanthera/Lilu/releases/download/{self.lilu_version}/Lilu-{self.lilu_version}-DEBUG.zip"
with tempfile.TemporaryDirectory() as temp_dir:
# Download source
weg_source_zip = f"{temp_dir}/WhateverGreen-{self.weg_version}.zip"
subprocess.run(["curl", "-L", weg_source_url, "-o", weg_source_zip], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Unzip source
subprocess.run(["unzip", weg_source_zip, "-d", temp_dir], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Git clone MacKernelSDK into source
subprocess.run(["git", "clone", "https://github.com/acidanthera/MacKernelSDK", f"{temp_dir}/WhateverGreen-{self.weg_version}/MacKernelSDK"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Grab latest Lilu release, debug version
lilu_zip = f"{temp_dir}/Lilu-{self.lilu_version}-DEBUG.zip"
subprocess.run(["curl", "-L", lilu_url, "-o", lilu_zip], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Unzip Lilu into WEG source
subprocess.run(["unzip", lilu_zip, "-d", f"{temp_dir}/WhateverGreen-{self.weg_version}"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Apply patch
patch_path = Path("./Acidanthera/WhateverGreen-Navi-Backlight.patch").absolute()
subprocess.run(["git", "apply", patch_path], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=f"{temp_dir}/WhateverGreen-{self.weg_version}")
# Build WEG
for variant in ["Release", "Debug"]:
subprocess.run(["xcodebuild", "-configuration", variant], cwd=f"{temp_dir}/WhateverGreen-{self.weg_version}", check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Zip Release
for variant in ["RELEASE", "DEBUG"]:
dst_path = Path(f"./Acidanthera/WhateverGreen-v{self.weg_version}-Navi-{variant}.zip").absolute()
subprocess.run(["zip", "-r", dst_path, "WhateverGreen.kext"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=f"{temp_dir}/WhateverGreen-{self.weg_version}/build/{'Release' if variant == 'RELEASE' else 'Debug'}")
if Path(f"./Acidanthera/WhateverGreen-v{self.weg_old}-Navi-{variant}.zip").exists():
subprocess.run(["rm", f"./Acidanthera/WhateverGreen-v{self.weg_old}-Navi-{variant}.zip"], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
self._update_constants_file("self.whatevergreen_navi_version", f"{self.weg_old}-Navi", f"{self.weg_version}-Navi")
def _iterate_over_kexts(self):
for kext_folder in KEXT_DICTIONARY:
for kext_name in KEXT_DICTIONARY[kext_folder]:
print(f"Checking {kext_name}...")
if "Override" in KEXT_DICTIONARY[kext_folder][kext_name]:
self._get_latest_release(kext_folder, kext_name, override_kext_zip_name=KEXT_DICTIONARY[kext_folder][kext_name]["Override"])
else:
self._get_latest_release(kext_folder, kext_name)
def _get_latest_release(self, kext_folder, kext_name, override_kext_zip_name=None):
# Get latest release from GitHub API
repo_url = KEXT_DICTIONARY[kext_folder][kext_name]["Repository"].replace("https://github.com", "https://api.github.com/repos")
latest_release = requests.get(f"{repo_url}/releases/latest").json()
for variant in ["RELEASE", "DEBUG"]:
if "tag_name" not in latest_release:
print(f" Error: {latest_release['message']}")
continue
remote_version = latest_release["tag_name"]
if remote_version.startswith("v"):
remote_version = remote_version[1:]
if kext_name == "WhateverGreen":
self.weg_version = remote_version
elif kext_name == "Lilu":
self.lilu_version = remote_version
local_version = self._get_local_version(kext_folder, kext_name, variant)
if kext_name == "WhateverGreen":
self.weg_old = local_version
if packaging.version.parse(remote_version) <= packaging.version.parse(local_version):
print(f" {kext_name} {variant} is up to date: v{local_version}")
continue
for asset in latest_release["assets"]:
if not asset["name"].endswith(f"{variant}.zip"):
continue
print(f" Downloading {kext_name} {variant}: v{remote_version}...")
zip_name = f"{override_kext_zip_name}-v{remote_version}-{variant}.zip" if override_kext_zip_name else f"{kext_name}-v{remote_version}-{variant}.zip"
self._download_file(asset["browser_download_url"], f"./{kext_folder}/{zip_name}", f"{kext_name}.kext")
if Path(f"./{kext_folder}/{zip_name}").exists():
subprocess.run(["rm", "-rf", f"./{kext_folder}/{zip_name.replace(f'v{remote_version}', f'v{local_version}')}"])
self._update_constants_file(KEXT_DICTIONARY[kext_folder][kext_name]["Constants Variable"], local_version, remote_version)
if override_kext_zip_name:
# rename zip file
os.rename(f"./{kext_folder}/{zip_name}", f"./{kext_folder}/{kext_name}-v{remote_version}-{variant}.zip")
subprocess.run(["rm", "-rf", f"./{kext_folder}/{kext_name}-v{local_version}-{variant}.zip"])
def _get_local_version(self, kext_folder, kext_name, variant):
loose_name_start = f"{kext_name}-v"
loose_name_end = f"-{variant}.zip"
for file in Path(f"./{kext_folder}").iterdir():
if file.name.startswith(loose_name_start) and file.name.endswith(loose_name_end):
local_version = file.name.replace(loose_name_start, "").replace(loose_name_end, "")
if local_version.startswith("v"):
local_version = local_version[1:]
return local_version[:5]
raise Exception(f"Could not find local version for {kext_name} {variant}")
def _download_file(self, url, file_path, file):
# Download file
if Path(file_path).exists():
os.remove(file_path)
with tempfile.TemporaryDirectory() as temp_dir:
download = requests.get(url)
with open(f"{temp_dir}/temp.zip", "wb") as f:
f.write(download.content)
# Unzip file
subprocess.run(["unzip", "-q", f"{temp_dir}/temp.zip", "-d", f"{temp_dir}"], check=True)
print(f" Moving {file} to {file_path}...")
# Zip file
subprocess.run(["zip", "-q", "-r", Path(file_path).name, file], cwd=f"{temp_dir}", check=True)
# Move file
subprocess.run(["mv", f"{temp_dir}/{Path(file_path).name}", file_path], check=True)
def _update_constants_file(self, variable_name, old_version, new_version):
print(f" Updating {variable_name} to {new_version}...")
constants_file = Path("../../resources/constants.py")
if not constants_file.exists():
raise Exception("Constants file does not exist")
constants_file_contents = constants_file.read_text()
# Replace version
for line in constants_file_contents.splitlines():
if variable_name in line:
constants_file_contents = constants_file_contents.replace(line, line.replace(old_version, new_version))
break
# Write file
constants_file.write_text(constants_file_contents)
if __name__ == '__main__':
GenerateKexts()

Binary file not shown.

Binary file not shown.

View File

@@ -28,7 +28,7 @@ class AmfiConfigurationDetection:
""" """
def __init__(self): def __init__(self) -> None:
self.AMFI_ALLOW_TASK_FOR_PID: bool = False self.AMFI_ALLOW_TASK_FOR_PID: bool = False
self.AMFI_ALLOW_INVALID_SIGNATURE: bool = False self.AMFI_ALLOW_INVALID_SIGNATURE: bool = False
self.AMFI_LV_ENFORCE_THIRD_PARTY: bool = False self.AMFI_LV_ENFORCE_THIRD_PARTY: bool = False
@@ -45,7 +45,7 @@ class AmfiConfigurationDetection:
self._parse_oclp_configuration() self._parse_oclp_configuration()
def _init_nvram_dicts(self): def _init_nvram_dicts(self) -> None:
""" """
Initialize the boot-args and OCLP-Settings NVRAM dictionaries Initialize the boot-args and OCLP-Settings NVRAM dictionaries
""" """
@@ -60,7 +60,7 @@ class AmfiConfigurationDetection:
self.oclp_args = oclp_args.split(" ") self.oclp_args = oclp_args.split(" ")
def _parse_amfi_bitmask(self): def _parse_amfi_bitmask(self) -> None:
""" """
Parse the AMFI bitmask from boot-args Parse the AMFI bitmask from boot-args
See data/amfi_data.py for more information See data/amfi_data.py for more information
@@ -96,7 +96,7 @@ class AmfiConfigurationDetection:
self.AMFI_ALLOW_INVALID_SIGNATURE = True self.AMFI_ALLOW_INVALID_SIGNATURE = True
def _parse_amfi_boot_args(self): def _parse_amfi_boot_args(self) -> None:
""" """
Parse the AMFI boot-args Parse the AMFI boot-args
""" """
@@ -121,7 +121,7 @@ class AmfiConfigurationDetection:
self.AMFI_ALLOW_INVALID_SIGNATURE = True self.AMFI_ALLOW_INVALID_SIGNATURE = True
def _parse_oclp_configuration(self): def _parse_oclp_configuration(self) -> None:
""" """
Parse the OCLP configuration Parse the OCLP configuration
""" """
@@ -130,16 +130,16 @@ class AmfiConfigurationDetection:
self.SKIP_LIBRARY_VALIDATION = True self.SKIP_LIBRARY_VALIDATION = True
def check_config(self, level: int): def check_config(self, level: int) -> bool:
""" """
Check the AMFI configuration based on provided AMFI level Check the AMFI configuration based on provided AMFI level
See AmfiConfigLevel enum for valid levels See AmfiConfigLevel enum for valid levels
Parameters: Parameters:
level (int): The level of AMFI checks to check for level (int): The level of AMFI checks to check for
Returns: Returns:
bool: True if the AMFI configuration matches the level, False otherwise bool: True if the AMFI configuration matches the level, False otherwise
""" """
if level == AmfiConfigDetectLevel.NO_CHECK: if level == AmfiConfigDetectLevel.NO_CHECK:

View File

@@ -12,7 +12,7 @@ from data import model_array
# Generic building args # Generic building args
class arguments: class arguments:
def __init__(self, global_constants: constants.Constants): def __init__(self, global_constants: constants.Constants) -> None:
self.constants: constants.Constants = global_constants self.constants: constants.Constants = global_constants
self.args = utilities.check_cli_args() self.args = utilities.check_cli_args()
@@ -20,7 +20,7 @@ class arguments:
self._parse_arguments() self._parse_arguments()
def _parse_arguments(self): def _parse_arguments(self) -> None:
""" """
Parses arguments passed to the patcher Parses arguments passed to the patcher
""" """
@@ -46,7 +46,7 @@ class arguments:
return return
def _validation_handler(self): def _validation_handler(self) -> None:
""" """
Enter validation mode Enter validation mode
""" """
@@ -54,7 +54,7 @@ class arguments:
validation.PatcherValidation(self.constants) validation.PatcherValidation(self.constants)
def _sys_patch_handler(self): def _sys_patch_handler(self) -> None:
""" """
Start root volume patching Start root volume patching
""" """
@@ -71,7 +71,7 @@ class arguments:
sys_patch.PatchSysVolume(self.constants.custom_model or self.constants.computer.real_model, self.constants, None).start_patch() sys_patch.PatchSysVolume(self.constants.custom_model or self.constants.computer.real_model, self.constants, None).start_patch()
def _sys_unpatch_handler(self): def _sys_unpatch_handler(self) -> None:
""" """
Start root volume unpatching Start root volume unpatching
""" """
@@ -79,7 +79,7 @@ class arguments:
sys_patch.PatchSysVolume(self.constants.custom_model or self.constants.computer.real_model, self.constants, None).start_unpatch() sys_patch.PatchSysVolume(self.constants.custom_model or self.constants.computer.real_model, self.constants, None).start_unpatch()
def _sys_patch_auto_handler(self): def _sys_patch_auto_handler(self) -> None:
""" """
Start root volume auto patching Start root volume auto patching
""" """
@@ -88,7 +88,7 @@ class arguments:
sys_patch_auto.AutomaticSysPatch(self.constants).start_auto_patch() sys_patch_auto.AutomaticSysPatch(self.constants).start_auto_patch()
def _build_handler(self): def _build_handler(self) -> None:
""" """
Start config building process Start config building process
""" """
@@ -109,10 +109,6 @@ If you plan to create the USB for another machine, please select the "Change Mod
logging.info(f"- Using detected model: {self.constants.computer.real_model}") logging.info(f"- Using detected model: {self.constants.computer.real_model}")
defaults.GenerateDefaults(self.constants.custom_model, True, self.constants) defaults.GenerateDefaults(self.constants.custom_model, True, self.constants)
if self.args.disk:
logging.info(f"- Install Disk set: {self.args.disk}")
self.constants.disk = self.args.disk
if self.args.verbose: if self.args.verbose:
logging.info("- Set verbose configuration") logging.info("- Set verbose configuration")
self.constants.verbose_debug = True self.constants.verbose_debug = True

View File

@@ -5,7 +5,7 @@ import plistlib
class ParseCommitInfo: class ParseCommitInfo:
def __init__(self, binary_path: str): def __init__(self, binary_path: str) -> None:
""" """
Parameters: Parameters:
binary_path (str): Path to binary binary_path (str): Path to binary
@@ -15,7 +15,7 @@ class ParseCommitInfo:
self.plist_path = self._convert_binary_path_to_plist_path() self.plist_path = self._convert_binary_path_to_plist_path()
def _convert_binary_path_to_plist_path(self): def _convert_binary_path_to_plist_path(self) -> str or None:
""" """
Resolve Info.plist path from binary path Resolve Info.plist path from binary path
""" """
@@ -27,7 +27,7 @@ class ParseCommitInfo:
return None return None
def generate_commit_info(self): def generate_commit_info(self) -> tuple:
""" """
Generate commit info from Info.plist Generate commit info from Info.plist

View File

@@ -1,5 +1,5 @@
# pylint: disable=multiple-statements # pylint: disable=multiple-statements
# Define Files # Defines versioning, file paths and other settings for the patcher
# Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk # Copyright (C) 2020-2023, Dhinak G, Mykola Grymalyuk
from pathlib import Path from pathlib import Path
@@ -10,212 +10,217 @@ from data import os_data
class Constants: class Constants:
def __init__(self): def __init__(self) -> None:
# Patcher Versioning # Patcher Versioning
self.patcher_version = "0.6.2" # OpenCore-Legacy-Patcher self.patcher_version: str = "0.6.3" # OpenCore-Legacy-Patcher
self.patcher_support_pkg_version = "0.8.5" # PatcherSupportPkg self.patcher_support_pkg_version: str = "0.9.2" # PatcherSupportPkg
self.url_patcher_support_pkg = "https://github.com/dortania/PatcherSupportPkg/releases/download/" self.copyright_date: str = "Copyright © 2020-2023 Dortania"
self.nightly_url_patcher_support_pkg = "https://nightly.link/dortania/PatcherSupportPkg/workflows/build/master/"
self.discord_link = "https://discord.gg/rqdPgH8xSN" # URLs
self.guide_link = "https://dortania.github.io/OpenCore-Legacy-Patcher/" self.url_patcher_support_pkg: str = "https://github.com/dortania/PatcherSupportPkg/releases/download/"
self.repo_link = "https://github.com/dortania/OpenCore-Legacy-Patcher" self.discord_link: str = "https://discord.gg/rqdPgH8xSN"
self.repo_link_latest = f"{self.repo_link}/releases/tag/{self.patcher_version}" self.guide_link: str = "https://dortania.github.io/OpenCore-Legacy-Patcher/"
self.copyright_date = "Copyright © 2020-2023 Dortania" self.repo_link: str = "https://github.com/dortania/OpenCore-Legacy-Patcher"
self.installer_pkg_url = f"{self.repo_link}/releases/download/{self.patcher_version}/AutoPkg-Assets.pkg" self.installer_pkg_url: str = f"{self.repo_link}/releases/download/{self.patcher_version}/AutoPkg-Assets.pkg"
self.installer_pkg_url_nightly = "http://nightly.link/dortania/OpenCore-Legacy-Patcher/workflows/build-app-wxpython/main/AutoPkg-Assets.pkg.zip" self.installer_pkg_url_nightly: str = "http://nightly.link/dortania/OpenCore-Legacy-Patcher/workflows/build-app-wxpython/main/AutoPkg-Assets.pkg.zip"
# OpenCore Versioning # OpenCore Versioning
# https://github.com/acidanthera/OpenCorePkg # https://github.com/acidanthera/OpenCorePkg
self.opencore_commit = "a753334 - 01-02-2023" self.opencore_commit: str = "e4f0ba1 - 03-06-2023"
self.opencore_version = "0.8.8" self.opencore_version: str = "0.9.0"
# Kext Versioning # Kext Versioning
## Acidanthera ## Acidanthera
## https://github.com/acidanthera ## https://github.com/acidanthera
self.lilu_version = "1.6.3" # Lilu self.lilu_version: str = "1.6.4" # Lilu
self.whatevergreen_version = "1.6.3" # WhateverGreen self.whatevergreen_version: str = "1.6.4" # WhateverGreen
self.whatevergreen_navi_version = "1.6.3-Navi" # WhateverGreen (Navi Patch) self.whatevergreen_navi_version: str = "1.6.4-Navi" # WhateverGreen (Navi Patch)
self.airportbcrmfixup_version = "2.1.6" # AirPortBrcmFixup self.airportbcrmfixup_version: str = "2.1.6" # AirPortBrcmFixup
self.nvmefix_version = "1.0.9" # NVMeFix self.nvmefix_version: str = "1.1.0" # NVMeFix
self.applealc_version = "1.6.3" # AppleALC self.applealc_version: str = "1.6.3" # AppleALC
self.restrictevents_version = "1.0.9" # RestrictEvents self.restrictevents_version: str = "1.0.9" # RestrictEvents
self.featureunlock_version = "1.1.4" # FeatureUnlock self.featureunlock_version: str = "1.1.4" # FeatureUnlock
self.debugenhancer_version = "1.0.7" # DebugEnhancer self.debugenhancer_version: str = "1.0.7" # DebugEnhancer
self.cpufriend_version = "1.2.6" # CPUFriend self.cpufriend_version: str = "1.2.6" # CPUFriend
self.bluetool_version = "2.6.4" # BlueToolFixup (BrcmPatchRAM) self.bluetool_version: str = "2.6.4" # BlueToolFixup (BrcmPatchRAM)
self.cslvfixup_version = "2.6.1" # CSLVFixup self.cslvfixup_version: str = "2.6.1" # CSLVFixup
self.autopkg_version = "1.0.2" # AutoPkgInstaller self.autopkg_version: str = "1.0.2" # AutoPkgInstaller
self.cryptexfixup_version = "1.0.1" # CryptexFixup self.cryptexfixup_version: str = "1.0.1" # CryptexFixup
## Apple ## Apple
## https://www.apple.com ## https://www.apple.com
self.marvel_version = "1.0.1" # MarvelYukonEthernet self.marvel_version: str = "1.0.1" # MarvelYukonEthernet
self.nforce_version = "1.0.1" # nForceEthernet self.nforce_version: str = "1.0.1" # nForceEthernet
self.piixata_version = "1.0.1" # AppleIntelPIIXATA self.piixata_version: str = "1.0.1" # AppleIntelPIIXATA
self.fw_kext = "1.0.1" # IOFireWireFamily self.fw_kext: str = "1.0.1" # IOFireWireFamily
self.apple_trackpad = "1.0.1" # AppleUSBTrackpad self.apple_trackpad: str = "1.0.1" # AppleUSBTrackpad
self.apple_isight_version = "1.0.0" # AppleiSight self.apple_isight_version: str = "1.0.0" # AppleiSight
self.apple_raid_version = "1.0.0" # AppleRAIDCard self.apple_raid_version: str = "1.0.0" # AppleRAIDCard
self.apfs_zlib_version = "12.3.1" # NoAVXFSCompressionTypeZlib self.apfs_zlib_version: str = "12.3.1" # NoAVXFSCompressionTypeZlib
self.apfs_zlib_v2_version = "12.6" # NoAVXFSCompressionTypeZlib (patched with AVXpel) self.apfs_zlib_v2_version: str = "12.6" # NoAVXFSCompressionTypeZlib (patched with AVXpel)
self.multitouch_version = "1.0.0" # AppleUSBMultitouch self.multitouch_version: str = "1.0.0" # AppleUSBMultitouch
self.topcase_version = "1.0.0" # AppleUSBTopCase self.topcase_version: str = "1.0.0" # AppleUSBTopCase
self.intel_82574l_version = "1.0.0" # Intel82574L self.intel_82574l_version: str = "1.0.0" # Intel82574L
self.intel_8254x_version = "1.0.0" # AppleIntel8254XEthernet self.intel_8254x_version: str = "1.0.0" # AppleIntel8254XEthernet
self.apple_usb_11_injector = "1.0.0" # AppleUSBUHCI/OHCI self.apple_usb_11_injector: str = "1.0.0" # AppleUSBUHCI/OHCI
self.aicpupm_version = "1.0.0" # AppleIntelCPUPowerManagement/Client self.aicpupm_version: str = "1.0.0" # AppleIntelCPUPowerManagement/Client
## Apple - Dortania Modified ## Apple - Dortania Modified
self.bcm570_version = "1.0.2" # CatalinaBCM5701Ethernet self.bcm570_version: str = "1.0.2" # CatalinaBCM5701Ethernet
self.i210_version = "1.0.0" # CatalinaIntelI210Ethernet self.i210_version: str = "1.0.0" # CatalinaIntelI210Ethernet
self.corecaptureelcap_version = "1.0.1" # corecaptureElCap self.corecaptureelcap_version: str = "1.0.1" # corecaptureElCap
self.io80211elcap_version = "2.0.0" # IO80211ElCap self.io80211elcap_version: str = "2.0.0" # IO80211ElCap
self.bigsursdxc_version = "1.0.0" # BigSurSDXC self.bigsursdxc_version: str = "1.0.0" # BigSurSDXC
self.monterey_ahci_version = "1.0.0" # CatalinaAHCI self.monterey_ahci_version: str = "1.0.0" # CatalinaAHCI
## Dortania ## Dortania
## https://github.com/dortania ## https://github.com/dortania
self.backlight_injector_version = "1.1.0" # BacklightInjector self.backlight_injector_version: str = "1.1.0" # BacklightInjector
self.backlight_injectorA_version = "1.0.0" # BacklightInjector iMac9,1 self.backlight_injectorA_version: str = "1.0.0" # BacklightInjector (iMac9,1)
self.smcspoof_version = "1.0.0" # SMC-Spoof self.smcspoof_version: str = "1.0.0" # SMC-Spoof
self.mce_version = "1.0.0" # AppleMCEReporterDisabler self.mce_version: str = "1.0.0" # AppleMCEReporterDisabler
self.btspoof_version = "1.0.0" # Bluetooth-Spoof self.btspoof_version: str = "1.0.0" # Bluetooth-Spoof
self.aspp_override_version = "1.0.1" # ACPI_SMC_PlatformPlugin Override self.aspp_override_version: str = "1.0.1" # ACPI_SMC_PlatformPlugin Override
self.rsrhelper_version = "1.0.0" # RSRHelper self.rsrhelper_version: str = "1.0.0" # RSRHelper
## Syncretic ## Syncretic
## https://forums.macrumors.com/members/syncretic.1173816/ ## https://forums.macrumors.com/members/syncretic.1173816/
## https://github.com/reenigneorcim/latebloom ## https://github.com/reenigneorcim/latebloom
self.mousse_version = "0.95-Dortania" # MouSSE self.mousse_version: str = "0.95-Dortania" # MouSSE
self.telemetrap_version = "1.0.0" # telemetrap self.telemetrap_version: str = "1.0.0" # telemetrap
## cdf ## cdf
## https://github.com/cdf/Innie ## https://github.com/cdf/Innie
self.innie_version = "1.3.0" # Innie self.innie_version: str = "1.3.1" # Innie
## arter97 ## arter97
## https://github.com/arter97/SimpleMSR/ ## https://github.com/arter97/SimpleMSR/
self.simplemsr_version = "1.0.0" # SimpleMSR self.simplemsr_version: str = "1.0.0" # SimpleMSR
## blackgate ## blackgate
## https://github.com/blackgate/AMDGPUWakeHandler ## https://github.com/blackgate/AMDGPUWakeHandler
self.gpu_wake_version = "1.0.0" self.gpu_wake_version: str = "1.0.0"
## flagersgit ## flagersgit
## https://github.com/flagersgit/KDKlessWorkaround ## https://github.com/flagersgit/KDKlessWorkaround
self.kdkless_version = "1.0.0" self.kdkless_version: str = "1.0.0"
# Get resource path # Get resource path
self.current_path = Path(__file__).parent.parent.resolve() self.current_path: Path = Path(__file__).parent.parent.resolve()
self.payload_path = self.current_path / Path("payloads") self.payload_path: Path = self.current_path / Path("payloads")
# Patcher Settings # Patcher Settings
self.allow_oc_everywhere = False # Set whether Patcher can be run on unsupported Macs ## Internal settings
self.gui_mode = False # Determine whether running in a GUI or TUI self.allow_oc_everywhere: bool = False # Set whether Patcher can be run on unsupported Macs
self.disk = "" # Set installation ESP self.gui_mode: bool = False # Determine whether running in a GUI or TUI
self.patch_disk = "" # Set Root Volume to patch self.cli_mode: bool = False # Determine if running in CLI mode
self.validate = False # Enable validation testing for CI self.validate: bool = False # Enable validation testing for CI
self.recovery_status = False # Detect if booted into RecoveryOS self.recovery_status: bool = False # Detect if booted into RecoveryOS
self.launcher_binary = None # Determine launch binary (ie. Python vs PyInstaller) self.ignore_updates: bool = False # Ignore OCLP updates
self.launcher_script = None # Determine launch file (if run via Python) self.wxpython_variant: bool = False # Determine if using wxPython variant
self.ignore_updates = False # Ignore OCLP updates self.has_checked_updates: bool = False # Determine if check for updates has been run
self.wxpython_variant = False # Determine if using wxPython variant self.root_patcher_succeeded: bool = False # Determine if root patcher succeeded
self.unpack_thread = None # Determine if unpack thread finished self.start_build_install: bool = False # Determine if build install should be started
self.cli_mode = False # Determine if running in CLI mode self.host_is_non_metal: bool = False # Determine if host is non-metal (ie. enable UI hacks)
self.should_nuke_kdks = True # Determine if KDKs should be nuked if unused in /L*/D*/KDKs self.needs_to_open_preferences: bool = False # Determine if preferences need to be opened
self.has_checked_updates = False # Determine if check for updates has been run self.host_is_hackintosh: bool = False # Determine if host is Hackintosh
self.should_nuke_kdks: bool = True # Determine if KDKs should be nuked if unused in /L*/D*/KDKs
self.launcher_binary: str = None # Determine launch binary path (ie. Python vs PyInstaller)
self.launcher_script: str = None # Determine launch file path (None if PyInstaller)
self.booted_oc_disk: str = None # Determine current disk OCLP booted from
self.unpack_thread = None # Determine if unpack thread finished (threading.Thread)
self.commit_info: tuple = (None, None, None) # Commit info (Branch, Commit Date, Commit URL)
## Hardware ## Hardware
self.computer: device_probe.Computer = None # type: ignore self.computer: device_probe.Computer = None # type: ignore
self.custom_model: Optional[str] = None self.custom_model: Optional[str] = None
## OpenCore Settings ## OpenCore Settings
self.opencore_debug = False self.opencore_debug: bool = False # Enable OpenCore debug
self.opencore_build = "RELEASE" self.boot_efi: bool = False # Use EFI/BOOT/BOOTx64.efi vs boot.efi bootstrap
self.showpicker = True # Show or Hide OpenCore's Boot Picker self.showpicker: bool = True # Show or Hide OpenCore's Boot Picker
self.boot_efi = False # Use EFI/BOOT/BOOTx64.efi bootstrap self.nvram_write: bool = True # Write to hardware NVRAM
self.nvram_write = True # Write to hardware NVRAM self.oc_timeout: int = 5 # Set OpenCore timeout
self.opencore_build: str = "RELEASE"
## Kext Settings ## Kext Settings
self.kext_debug = False # Enables Lilu debug and DebugEnhancer self.kext_debug: bool = False # Enables Lilu debug and DebugEnhancer
self.kext_variant = "RELEASE" self.kext_variant: str = "RELEASE"
## NVRAM Settings ## NVRAM Settings
self.verbose_debug = False # -v self.verbose_debug: bool = False # -v
## SMBIOS Settings ## SMBIOS Settings
self.custom_cpu_model = 2 # Patch type value self.serial_settings: str = "None" # Set SMBIOS level used
self.custom_cpu_model_value = "" # New CPU name within About This Mac self.override_smbios: str = "Default" # Set SMBIOS model used
self.serial_settings = "None" # Set SMBIOS level used self.allow_native_spoofs: bool = False # Allow native models to recieve spoofs
self.override_smbios = "Default" # Set SMBIOS model used
self.allow_native_spoofs = False # Allow native models to recieve spoofs ### RestrictEvents CPU renaming
self.custom_serial_number = "" # Set SMBIOS serial number self.custom_cpu_model: int = 2 # Patch type value
self.custom_board_serial_number = "" # Set SMBIOS board serial number self.custom_cpu_model_value: str = "" # New CPU name within About This Mac
### Serial Number Overrides
self.custom_serial_number: str = "" # Set SMBIOS serial number
self.custom_board_serial_number: str = "" # Set SMBIOS board serial number
## FeatureUnlock Settings ## FeatureUnlock Settings
self.fu_status = True # Enable FeatureUnlock self.fu_status: bool = True # Enable FeatureUnlock
self.fu_arguments = None # Set FeatureUnlock arguments self.fu_arguments: str = None # Set FeatureUnlock arguments
## Security Settings ## Security Settings
self.apecid_support = False # ApECID self.sip_status: bool = True # System Integrity Protection
self.sip_status = True # System Integrity Protection self.secure_status: bool = False # Secure Boot Model
self.secure_status = False # Secure Boot Model self.vault: bool = False # EFI Vault
self.vault = False # EFI Vault self.disable_cs_lv: bool = False # Disable Library validation
self.disable_cs_lv = False # Disable Library validation self.disable_amfi: bool = False # Disable AMFI
self.disable_amfi = False # Disable AMFI
## OS Settings ## OS Settings
self.os_support = 12.0 self.os_support: float = 12.0
self.detected_os = 0 # Major Kernel Version self.detected_os: int = 0 # Major Kernel Version
self.detected_os_minor = 0 # Minor Kernel Version self.detected_os_minor: int = 0 # Minor Kernel Version
self.detected_os_build = "" # OS Build self.detected_os_build: str = "" # OS Build
self.detected_os_version = "" # OS Version self.detected_os_version: str = "" # OS Version
## Boot Volume Settings ## Boot Volume Settings
self.firewire_boot = False # Allow macOS FireWire Boot self.firewire_boot: bool = False # Allow macOS FireWire Boot (kernel)
self.nvme_boot = False # Allow UEFI NVMe Boot self.nvme_boot: bool = False # Allow UEFI NVMe Boot
self.xhci_boot = False self.xhci_boot: bool = False # Allow UEFI XHCI Boot
## Graphics Settings ## Graphics Settings
self.metal_build = False # Set MXM Build support self.allow_ts2_accel: bool = True # Set TeraScale 2 Acceleration support
self.imac_vendor = "None" # Set MXM GPU vendor self.drm_support: bool = False # Set iMac14,x DRM support
self.imac_model = "" # Set MXM GPU model self.force_nv_web: bool = False # Force Nvidia Web Drivers on Tesla and Kepler
self.drm_support = False # Set iMac14,x DRM support self.force_output_support: bool = False # Force Output support for Mac Pros with PC VBIOS
self.allow_ts2_accel = True # Set TeraScale 2 Acceleration support self.amd_gop_injection: bool = False # Set GOP Injection support
self.force_nv_web = False # Force Nvidia Web Drivers on Tesla and Kepler self.nvidia_kepler_gop_injection: bool = False # Set Kepler GOP Injection support
self.force_output_support = False # Force Output support for Mac Pros with PC VBIOS
self.amd_gop_injection = False # Set GOP Injection support
self.nvidia_kepler_gop_injection = False # Set Kepler GOP Injection support
## Miscellaneous ### MXM GPU Support
self.disallow_cpufriend = False # Disable CPUFriend self.metal_build: bool = False # Set MXM Build support
self.enable_wake_on_wlan = False # Allow Wake on WLAN for modern Broadcom self.imac_vendor: str = "None" # Set MXM GPU vendor
self.disable_tb = False # Disable Thunderbolt Controller self.imac_model: str = "" # Set MXM GPU model
self.set_alc_usage = True # Set AppleALC usage
self.dGPU_switch = False # Set Display GPU Switching for Windows
self.force_surplus = False # Force SurPlus patch in newer OSes
self.force_latest_psp = False # Force latest PatcherSupportPkg
self.disable_msr_power_ctl = False # Disable MSR Power Control (missing battery throttling)
self.software_demux = False # Enable Software Demux patch set
self.force_vmm = False # Force VMM patch
self.custom_sip_value = None # Set custom SIP value
self.walkthrough = False # Enable Walkthrough
self.disable_connectdrivers = False # Disable ConnectDrivers (hibernation)
self.allow_3rd_party_drives = True # Allow ThridPartyDrives quirk
self.set_content_caching = False # Set Content Caching
self.allow_nvme_fixing = True # Allow NVMe Kernel Space Patches
self.disable_xcpm = False # Disable XCPM (X86PlatformPlugin.kext)
self.root_patcher_succeeded = False # Determine if root patcher succeeded
self.booted_oc_disk = None # Determine current disk OCLP booted from
self.start_build_install = False # Determine if build install should be started
self.host_is_non_metal = False # Determine if host is non-metal (ie. enable UI hacks)
self.needs_to_open_preferences = False # Determine if preferences need to be opened
self.host_is_hackintosh = False # Determine if host is Hackintosh
self.commit_info = (None, None, None)
self.set_vmm_cpuid = False # Set VMM bit inside CPUID
self.oc_timeout = 5 # Set OpenCore timeout
self.apfs_trim_timeout = True # Set APFS Trim timeout
## Miscellaneous build settings
self.disallow_cpufriend: bool = False # Disable CPUFriend
self.enable_wake_on_wlan: bool = False # Allow Wake on WLAN for modern Broadcom
self.disable_tb: bool = False # Disable Thunderbolt Controller
self.dGPU_switch: bool = False # Set Display GPU Switching for Windows
self.force_surplus: bool = False # Force SurPlus patch in newer OSes
self.force_latest_psp: bool = False # Force latest PatcherSupportPkg
self.disable_msr_power_ctl: bool = False # Disable MSR Power Control (missing battery throttling)
self.software_demux: bool = False # Enable Software Demux patch set
self.force_vmm: bool = False # Force VMM patch
self.disable_connectdrivers: bool = False # Disable ConnectDrivers (hibernation)
self.set_content_caching: bool = False # Set Content Caching
self.disable_xcpm: bool = False # Disable XCPM (X86PlatformPlugin.kext)
self.set_vmm_cpuid: bool = False # Set VMM bit inside CPUID
self.set_alc_usage: bool = True # Set AppleALC usage
self.allow_3rd_party_drives: bool = True # Allow ThridPartyDrives quirk
self.allow_nvme_fixing: bool = True # Allow NVMe Kernel Space Patches
self.apfs_trim_timeout: bool = True # Set APFS Trim timeout
self.custom_sip_value: int = None # Set custom SIP value
## Non-Metal OS support
self.legacy_accel_support = [ self.legacy_accel_support = [
os_data.os_data.big_sur, os_data.os_data.big_sur,
os_data.os_data.monterey, os_data.os_data.monterey,
@@ -283,10 +288,6 @@ class Constants:
def link_rate_driver_path(self): def link_rate_driver_path(self):
return self.payload_path / Path("Drivers/FixPCIeLinkRate.efi") return self.payload_path / Path("Drivers/FixPCIeLinkRate.efi")
@property
def list_txt_path(self):
return self.payload_path / Path("List.txt")
@property @property
def installer_sh_path(self): def installer_sh_path(self):
return self.payload_path / Path("Installer.sh") return self.payload_path / Path("Installer.sh")
@@ -466,7 +467,7 @@ class Constants:
@property @property
def innie_path(self): def innie_path(self):
return self.payload_kexts_path / Path(f"Misc/Innie-v{self.innie_version}.zip") return self.payload_kexts_path / Path(f"Misc/Innie-v{self.innie_version}-{self.kext_variant}.zip")
@property @property
def simplemsr_path(self): def simplemsr_path(self):

View File

@@ -17,7 +17,7 @@ from data import (
class GenerateDefaults: class GenerateDefaults:
def __init__(self, model: str, host_is_target: bool, global_constants: constants.Constants): def __init__(self, model: str, host_is_target: bool, global_constants: constants.Constants) -> None:
self.constants: constants.Constants = global_constants self.constants: constants.Constants = global_constants
self.model: str = model self.model: str = model
@@ -51,7 +51,7 @@ class GenerateDefaults:
self._smbios_probe() self._smbios_probe()
def _general_probe(self): def _general_probe(self) -> None:
""" """
General probe for data General probe for data
""" """
@@ -93,7 +93,7 @@ class GenerateDefaults:
self.constants.should_nuke_kdks = False self.constants.should_nuke_kdks = False
def _smbios_probe(self): def _smbios_probe(self) -> None:
""" """
SMBIOS specific probe SMBIOS specific probe
""" """
@@ -128,7 +128,7 @@ class GenerateDefaults:
self.constants.force_vmm = False self.constants.force_vmm = False
def _nvram_probe(self): def _nvram_probe(self) -> None:
""" """
NVRAM specific probe NVRAM specific probe
""" """
@@ -153,7 +153,7 @@ class GenerateDefaults:
self.constants.custom_cpu_model_value = custom_cpu_model_value.split("%00")[0] self.constants.custom_cpu_model_value = custom_cpu_model_value.split("%00")[0]
def _networking_probe(self): def _networking_probe(self) -> None:
""" """
Networking specific probe Networking specific probe
""" """
@@ -195,7 +195,7 @@ class GenerateDefaults:
self.constants.fu_arguments = " -disable_sidecar_mac" self.constants.fu_arguments = " -disable_sidecar_mac"
def _misc_hardwares_probe(self): def _misc_hardwares_probe(self) -> None:
""" """
Misc probe Misc probe
""" """
@@ -211,7 +211,7 @@ class GenerateDefaults:
break break
def _gpu_probe(self): def _gpu_probe(self) -> None:
""" """
Graphics specific probe Graphics specific probe
""" """
@@ -245,6 +245,13 @@ class GenerateDefaults:
device_probe.AMD.Archs.Vega, device_probe.AMD.Archs.Vega,
device_probe.AMD.Archs.Navi, device_probe.AMD.Archs.Navi,
]: ]:
if gpu in [
device_probe.Intel.Archs.Ivy_Bridge,
device_probe.Intel.Archs.Haswell,
device_probe.NVIDIA.Archs.Kepler,
]:
self.constants.disable_amfi = True
if gpu in [ if gpu in [
device_probe.AMD.Archs.Legacy_GCN_7000, device_probe.AMD.Archs.Legacy_GCN_7000,
device_probe.AMD.Archs.Legacy_GCN_8000, device_probe.AMD.Archs.Legacy_GCN_8000,
@@ -302,7 +309,8 @@ class GenerateDefaults:
# Only disable AMFI if we officially support Ventura # Only disable AMFI if we officially support Ventura
self.constants.disable_amfi = True self.constants.disable_amfi = True
# Enable BetaBlur if user hasn't disabled it for key in ["Moraea_BlurBeta", "Amy.MenuBar2Beta"]:
is_blur_enabled = subprocess.run(["defaults", "read", "-g", "Moraea_BlurBeta"], stdout=subprocess.PIPE).stdout.decode("utf-8").strip() # Enable BetaBlur if user hasn't disabled it
if is_blur_enabled in ["false", "0"]: is_key_enabled = subprocess.run(["defaults", "read", "-g", key], stdout=subprocess.PIPE).stdout.decode("utf-8").strip()
subprocess.run(["defaults", "write", "-g", "Moraea_BlurBeta", "-bool", "true"]) if is_key_enabled not in ["false", "0"]:
subprocess.run(["defaults", "write", "-g", key, "-bool", "true"])

View File

@@ -15,7 +15,7 @@ class GlobalEnviromentSettings:
Library for querying and writing global enviroment settings Library for querying and writing global enviroment settings
""" """
def __init__(self): def __init__(self) -> None:
self.file_name: str = ".com.dortania.opencore-legacy-patcher.plist" self.file_name: str = ".com.dortania.opencore-legacy-patcher.plist"
self.global_settings_folder: str = "/Users/Shared" self.global_settings_folder: str = "/Users/Shared"
self.global_settings_plist: str = f"{self.global_settings_folder}/{self.file_name}" self.global_settings_plist: str = f"{self.global_settings_folder}/{self.file_name}"
@@ -25,7 +25,7 @@ class GlobalEnviromentSettings:
self._fix_file_permission() self._fix_file_permission()
def read_property(self, property_name: str): def read_property(self, property_name: str) -> str or None:
""" """
Reads a property from the global settings file Reads a property from the global settings file
""" """
@@ -37,7 +37,7 @@ class GlobalEnviromentSettings:
return None return None
def write_property(self, property_name: str, property_value): def write_property(self, property_name: str, property_value) -> None:
""" """
Writes a property to the global settings file Writes a property to the global settings file
""" """
@@ -51,7 +51,7 @@ class GlobalEnviromentSettings:
logging.info("- Failed to write to global settings file") logging.info("- Failed to write to global settings file")
def _generate_settings_file(self): def _generate_settings_file(self) -> None:
if Path(self.global_settings_plist).exists(): if Path(self.global_settings_plist).exists():
return return
try: try:
@@ -60,7 +60,7 @@ class GlobalEnviromentSettings:
logging.info("- Permission error: Unable to write to global settings file") logging.info("- Permission error: Unable to write to global settings file")
def _convert_defaults_to_global_settings(self): def _convert_defaults_to_global_settings(self) -> None:
""" """
Converts legacy defaults to global settings Converts legacy defaults to global settings
""" """
@@ -86,7 +86,7 @@ class GlobalEnviromentSettings:
logging.info("- Permission error: Unable to delete defaults plist") logging.info("- Permission error: Unable to delete defaults plist")
def _fix_file_permission(self): def _fix_file_permission(self) -> None:
""" """
Fixes file permission for log file Fixes file permission for log file

View File

@@ -1142,6 +1142,32 @@ class wx_python_gui:
) )
) )
i = i + self.patch_label.GetSize().height + 3 i = i + self.patch_label.GetSize().height + 3
i += 10
if self.constants.host_is_hackintosh is False:
self.patch_label = wx.StaticText(self.frame_modal, label="Please run 'Build and Install OpenCore' and reboot")
self.patch_label.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
self.patch_label.SetPosition(
wx.Point(
self.subheader.GetPosition().x,
self.subheader.GetPosition().y + self.subheader.GetSize().height + 3 + i
)
)
self.patch_label.Centre(wx.HORIZONTAL)
i = i + self.patch_label.GetSize().height + 3
self.patch_label = wx.StaticText(self.frame_modal, label="to remove these errors.")
self.patch_label.SetFont(wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
self.patch_label.SetPosition(
wx.Point(
self.subheader.GetPosition().x,
self.subheader.GetPosition().y + self.subheader.GetSize().height + 3 + i
)
)
self.patch_label.Centre(wx.HORIZONTAL)
i = i + self.patch_label.GetSize().height + 3
else: else:
if self.constants.computer.oclp_sys_version and self.constants.computer.oclp_sys_date: if self.constants.computer.oclp_sys_version and self.constants.computer.oclp_sys_date:
date = self.constants.computer.oclp_sys_date.split(" @") date = self.constants.computer.oclp_sys_date.split(" @")
@@ -1941,7 +1967,7 @@ class wx_python_gui:
with Path(self.constants.payload_path / Path("InstallAssistant.pkg")).open("rb") as f: with Path(self.constants.payload_path / Path("InstallAssistant.pkg")).open("rb") as f:
for chunk in chunks: for chunk in chunks:
status = hashlib.sha256(f.read(chunk["length"])).digest() status = hashlib.sha256(f.read(chunk["length"])).digest()
if not status == chunk["checksum"]: if status != chunk["checksum"]:
logging.info(f"Chunk {chunks.index(chunk) + 1} checksum status FAIL: chunk sum {binascii.hexlify(chunk['checksum']).decode()}, calculated sum {binascii.hexlify(status).decode()}") logging.info(f"Chunk {chunks.index(chunk) + 1} checksum status FAIL: chunk sum {binascii.hexlify(chunk['checksum']).decode()}, calculated sum {binascii.hexlify(status).decode()}")
self.popup = wx.MessageDialog( self.popup = wx.MessageDialog(
self.frame, self.frame,

View File

@@ -49,7 +49,7 @@ class KernelDebugKitObject:
""" """
def __init__(self, global_constants: constants.Constants, host_build: str, host_version: str, ignore_installed: bool = False, passive: bool = False): def __init__(self, global_constants: constants.Constants, host_build: str, host_version: str, ignore_installed: bool = False, passive: bool = False) -> None:
self.constants: constants.Constants = global_constants self.constants: constants.Constants = global_constants
self.host_build: str = host_build # ex. 20A5384c self.host_build: str = host_build # ex. 20A5384c
@@ -83,7 +83,7 @@ class KernelDebugKitObject:
self._get_latest_kdk() self._get_latest_kdk()
def _get_remote_kdks(self): def _get_remote_kdks(self) -> list or None:
""" """
Fetches a list of available KDKs from the KdkSupportPkg API Fetches a list of available KDKs from the KdkSupportPkg API
Additionally caches the list for future use, avoiding extra API calls Additionally caches the list for future use, avoiding extra API calls
@@ -119,7 +119,7 @@ class KernelDebugKitObject:
return KDK_ASSET_LIST return KDK_ASSET_LIST
def _get_latest_kdk(self, host_build: str = None, host_version: str = None): def _get_latest_kdk(self, host_build: str = None, host_version: str = None) -> None:
""" """
Fetches the latest KDK for the current macOS version Fetches the latest KDK for the current macOS version
@@ -229,7 +229,7 @@ class KernelDebugKitObject:
self.success = True self.success = True
def retrieve_download(self, override_path: str = ""): def retrieve_download(self, override_path: str = "") -> network_handler.DownloadObject or None:
""" """
Returns a DownloadObject for the KDK Returns a DownloadObject for the KDK
@@ -263,7 +263,7 @@ class KernelDebugKitObject:
return network_handler.DownloadObject(self.kdk_url, kdk_download_path) return network_handler.DownloadObject(self.kdk_url, kdk_download_path)
def _generate_kdk_info_plist(self, plist_path: str): def _generate_kdk_info_plist(self, plist_path: str) -> None:
""" """
Generates a KDK Info.plist Generates a KDK Info.plist
@@ -285,7 +285,7 @@ class KernelDebugKitObject:
logging.error(f"- Failed to generate KDK Info.plist: {e}") logging.error(f"- Failed to generate KDK Info.plist: {e}")
def _local_kdk_valid(self, kdk_path: Path): def _local_kdk_valid(self, kdk_path: Path) -> bool:
""" """
Validates provided KDK, ensure no corruption Validates provided KDK, ensure no corruption
@@ -334,7 +334,7 @@ class KernelDebugKitObject:
return True return True
def _local_kdk_valid_legacy(self, kdk_path: Path): def _local_kdk_valid_legacy(self, kdk_path: Path) -> bool:
""" """
Legacy variant of validating provided KDK Legacy variant of validating provided KDK
Uses best guess of files that should be present Uses best guess of files that should be present
@@ -363,7 +363,7 @@ class KernelDebugKitObject:
return True return True
def _local_kdk_installed(self, match: str = None, check_version: bool = False): def _local_kdk_installed(self, match: str = None, check_version: bool = False) -> str or None:
""" """
Checks if KDK matching build is installed Checks if KDK matching build is installed
If so, validates it has not been corrupted If so, validates it has not been corrupted
@@ -429,7 +429,7 @@ class KernelDebugKitObject:
return None return None
def _remove_kdk(self, kdk_path: str): def _remove_kdk(self, kdk_path: str) -> None:
""" """
Removes provided KDK Removes provided KDK
@@ -448,19 +448,18 @@ class KernelDebugKitObject:
logging.warning(f"- KDK does not exist: {kdk_path}") logging.warning(f"- KDK does not exist: {kdk_path}")
return return
rm_args = ["rm", "-f", kdk_path] rm_args = ["rm", "-rf" if Path(kdk_path).is_dir() else "-f", kdk_path]
if Path(kdk_path).is_dir():
rm_args = ["rm", "-rf", kdk_path]
result = utilities.elevated(rm_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) result = utilities.elevated(rm_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if result.returncode != 0: if result.returncode != 0:
logging.warning(f"- Failed to remove KDK: {kdk_path}") logging.warning(f"- Failed to remove KDK: {kdk_path}")
logging.warning(f"- {result.stdout.decode('utf-8')}") logging.warning(f"- {result.stdout.decode('utf-8')}")
return
logging.info(f"- Successfully removed KDK: {kdk_path}") logging.info(f"- Successfully removed KDK: {kdk_path}")
def _remove_unused_kdks(self, exclude_builds: list = None): def _remove_unused_kdks(self, exclude_builds: list = None) -> None:
""" """
Removes KDKs that are not in use Removes KDKs that are not in use
@@ -486,21 +485,20 @@ class KernelDebugKitObject:
logging.info("- Cleaning unused KDKs") logging.info("- Cleaning unused KDKs")
for kdk_folder in Path(KDK_INSTALL_PATH).iterdir(): for kdk_folder in Path(KDK_INSTALL_PATH).iterdir():
if kdk_folder.is_dir(): if kdk_folder.name.endswith(".kdk") or kdk_folder.name.endswith(".pkg"):
if kdk_folder.name.endswith(".kdk") or kdk_folder.name.endswith(".pkg"): should_remove = True
should_remove = True for build in exclude_builds:
for build in exclude_builds: if build == "":
if build != "":
continue
if kdk_folder.name.endswith(f"{build}.kdk") or kdk_folder.name.endswith(f"{build}.pkg"):
should_remove = False
break
if should_remove is False:
continue continue
self._remove_kdk(kdk_folder) if kdk_folder.name.endswith(f"_{build}.kdk") or kdk_folder.name.endswith(f"_{build}.pkg"):
should_remove = False
break
if should_remove is False:
continue
self._remove_kdk(kdk_folder)
def validate_kdk_checksum(self, kdk_dmg_path: str = None): def validate_kdk_checksum(self, kdk_dmg_path: str = None) -> bool:
""" """
Validates KDK DMG checksum Validates KDK DMG checksum
@@ -542,11 +540,11 @@ class KernelDebugKitUtilities:
""" """
def __init__(self): def __init__(self) -> None:
pass pass
def install_kdk_pkg(self, kdk_path: Path): def install_kdk_pkg(self, kdk_path: Path) -> bool:
""" """
Installs provided KDK packages Installs provided KDK packages
@@ -577,7 +575,7 @@ class KernelDebugKitUtilities:
return True return True
def install_kdk_dmg(self, kdk_path: Path): def install_kdk_dmg(self, kdk_path: Path) -> bool:
""" """
Installs provided KDK disk image Installs provided KDK disk image
@@ -617,7 +615,7 @@ class KernelDebugKitUtilities:
logging.info("- Successfully installed KDK") logging.info("- Successfully installed KDK")
return True return True
def _unmount_disk_image(self, mount_point): def _unmount_disk_image(self, mount_point) -> None:
""" """
Unmounts provided disk image silently Unmounts provided disk image silently
@@ -627,7 +625,7 @@ class KernelDebugKitUtilities:
subprocess.run(["hdiutil", "detach", mount_point], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) subprocess.run(["hdiutil", "detach", mount_point], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
def _create_backup(self, kdk_path: Path, kdk_info_plist: Path): def _create_backup(self, kdk_path: Path, kdk_info_plist: Path) -> None:
""" """
Creates a backup of the KDK Creates a backup of the KDK

View File

@@ -26,7 +26,7 @@ class InitializeLoggingSupport:
""" """
def __init__(self): def __init__(self) -> None:
self.log_filename: str = "OpenCore-Patcher.log" self.log_filename: str = "OpenCore-Patcher.log"
self.log_filepath: Path = None self.log_filepath: Path = None
@@ -43,11 +43,11 @@ class InitializeLoggingSupport:
self._fix_file_permission() self._fix_file_permission()
def __del__(self): def __del__(self) -> None:
self._restore_original_excepthook() self._restore_original_excepthook()
def _initialize_logging_path(self): def _initialize_logging_path(self) -> None:
""" """
Initialize logging framework storage path Initialize logging framework storage path
""" """
@@ -62,7 +62,7 @@ class InitializeLoggingSupport:
print(f" - Log file: {self.log_filepath}") print(f" - Log file: {self.log_filepath}")
def _clean_log_file(self): def _clean_log_file(self) -> None:
""" """
Determine if log file should be cleaned Determine if log file should be cleaned
@@ -87,7 +87,7 @@ class InitializeLoggingSupport:
print(f"- Failed to clean log file: {e}") print(f"- Failed to clean log file: {e}")
def _fix_file_permission(self): def _fix_file_permission(self) -> None:
""" """
Fixes file permission for log file Fixes file permission for log file
@@ -105,7 +105,7 @@ class InitializeLoggingSupport:
print(result.stderr.decode("utf-8")) print(result.stderr.decode("utf-8"))
def _initialize_logging_configuration(self, log_to_file: bool = True): def _initialize_logging_configuration(self, log_to_file: bool = True) -> None:
""" """
Initialize logging framework configuration Initialize logging framework configuration
@@ -130,7 +130,7 @@ class InitializeLoggingSupport:
logging.getLogger().handlers[1].maxBytes = self.max_file_size logging.getLogger().handlers[1].maxBytes = self.max_file_size
def _attempt_initialize_logging_configuration(self): def _attempt_initialize_logging_configuration(self) -> None:
""" """
Attempt to initialize logging framework configuration Attempt to initialize logging framework configuration
@@ -145,18 +145,18 @@ class InitializeLoggingSupport:
self._initialize_logging_configuration(log_to_file=False) self._initialize_logging_configuration(log_to_file=False)
def _implement_custom_traceback_handler(self): def _implement_custom_traceback_handler(self) -> None:
""" """
Reroute traceback to logging module Reroute traceback to logging module
""" """
def custom_excepthook(type, value, tb): def custom_excepthook(type, value, tb) -> None:
""" """
Reroute traceback in main thread to logging module Reroute traceback in main thread to logging module
""" """
logging.error("Uncaught exception in main thread", exc_info=(type, value, tb)) logging.error("Uncaught exception in main thread", exc_info=(type, value, tb))
def custom_thread_excepthook(args): def custom_thread_excepthook(args) -> None:
""" """
Reroute traceback in spawned thread to logging module Reroute traceback in spawned thread to logging module
""" """
@@ -166,7 +166,7 @@ class InitializeLoggingSupport:
threading.excepthook = custom_thread_excepthook threading.excepthook = custom_thread_excepthook
def _restore_original_excepthook(self): def _restore_original_excepthook(self) -> None:
""" """
Restore original traceback handlers Restore original traceback handlers
""" """

View File

@@ -23,13 +23,19 @@ tmp_dir = tempfile.TemporaryDirectory()
class InstallerCreation(): class InstallerCreation():
def __init__(self): def __init__(self) -> None:
pass pass
def install_macOS_installer(self, download_path: str): def install_macOS_installer(self, download_path: str) -> bool:
""" """
Installs InstallAssistant.pkg Installs InstallAssistant.pkg
Parameters:
download_path (str): Path to InstallAssistant.pkg
Returns:
bool: True if successful, False otherwise
""" """
logging.info("- Extracting macOS installer from InstallAssistant.pkg\n This may take some time") logging.info("- Extracting macOS installer from InstallAssistant.pkg\n This may take some time")
@@ -52,7 +58,7 @@ class InstallerCreation():
return True return True
def generate_installer_creation_script(self, tmp_location, installer_path, disk): def generate_installer_creation_script(self, tmp_location: str, installer_path: str, disk: str) -> bool:
""" """
Creates installer.sh to be piped to OCLP-Helper and run as admin Creates installer.sh to be piped to OCLP-Helper and run as admin
@@ -67,6 +73,9 @@ class InstallerCreation():
tmp_location (str): Path to temporary directory tmp_location (str): Path to temporary directory
installer_path (str): Path to InstallAssistant.pkg installer_path (str): Path to InstallAssistant.pkg
disk (str): Disk to install to disk (str): Disk to install to
Returns:
bool: True if successful, False otherwise
""" """
additional_args = "" additional_args = ""
@@ -136,7 +145,8 @@ fi
return True return True
return False return False
def list_disk_to_format(self):
def list_disk_to_format(self) -> dict:
""" """
List applicable disks for macOS installer creation List applicable disks for macOS installer creation
Only lists disks that are: Only lists disks that are:
@@ -191,14 +201,20 @@ fi
return list_disks return list_disks
class SeedType(enum.Enum): class SeedType(enum.IntEnum):
""" """
Enum for catalog types Enum for catalog types
Variants:
DeveloperSeed: Developer Beta (Part of the Apple Developer Program)
PublicSeed: Public Beta
CustomerSeed: AppleSeed Program (Generally mirrors DeveloperSeed)
PublicRelease: Public Release
""" """
DeveloperSeed = 0 DeveloperSeed: int = 0
PublicSeed = 1 PublicSeed: int = 1
CustomerSeed = 2 CustomerSeed: int = 2
PublicRelease = 3 PublicRelease: int = 3
class RemoteInstallerCatalog: class RemoteInstallerCatalog:
@@ -206,7 +222,7 @@ class RemoteInstallerCatalog:
Parses Apple's Software Update catalog and finds all macOS installers. Parses Apple's Software Update catalog and finds all macOS installers.
""" """
def __init__(self, seed_override: SeedType = SeedType.PublicRelease): def __init__(self, seed_override: SeedType = SeedType.PublicRelease) -> None:
self.catalog_url: str = self._construct_catalog_url(seed_override) self.catalog_url: str = self._construct_catalog_url(seed_override)
@@ -214,12 +230,15 @@ class RemoteInstallerCatalog:
self.available_apps_latest: dict = self._list_newest_installers_only() self.available_apps_latest: dict = self._list_newest_installers_only()
def _construct_catalog_url(self, seed_type: SeedType): def _construct_catalog_url(self, seed_type: SeedType) -> str:
""" """
Constructs the catalog URL based on the seed type Constructs the catalog URL based on the seed type
Args: Parameters:
seed_type (SeedType): The seed type to use seed_type (SeedType): The seed type to use
Returns:
str: The catalog URL
""" """
@@ -237,7 +256,7 @@ class RemoteInstallerCatalog:
return url return url
def _fetch_catalog(self): def _fetch_catalog(self) -> dict:
""" """
Fetches the catalog from Apple's servers Fetches the catalog from Apple's servers
@@ -257,7 +276,13 @@ class RemoteInstallerCatalog:
return catalog return catalog
def _parse_catalog(self): def _parse_catalog(self) -> dict:
"""
Parses the catalog and returns a dictionary of available installers
Returns:
dict: Dictionary of available installers
"""
available_apps: dict = {} available_apps: dict = {}
catalog: dict = self._fetch_catalog() catalog: dict = self._fetch_catalog()
@@ -358,7 +383,7 @@ class RemoteInstallerCatalog:
return available_apps return available_apps
def _list_newest_installers_only(self): def _list_newest_installers_only(self) -> dict:
""" """
Returns a dictionary of the newest macOS installers only. Returns a dictionary of the newest macOS installers only.
Primarily used to avoid overwhelming the user with a list of Primarily used to avoid overwhelming the user with a list of
@@ -449,11 +474,11 @@ class LocalInstallerCatalog:
Finds all macOS installers on the local machine. Finds all macOS installers on the local machine.
""" """
def __init__(self): def __init__(self) -> None:
self.available_apps: dict = self._list_local_macOS_installers() self.available_apps: dict = self._list_local_macOS_installers()
def _list_local_macOS_installers(self): def _list_local_macOS_installers(self) -> dict:
""" """
Searches for macOS installers in /Applications Searches for macOS installers in /Applications
@@ -537,7 +562,7 @@ class LocalInstallerCatalog:
return application_list return application_list
def _parse_sharedsupport_version(self, sharedsupport_path: Path): def _parse_sharedsupport_version(self, sharedsupport_path: Path) -> tuple:
""" """
Determine true version of macOS installer by parsing SharedSupport.dmg Determine true version of macOS installer by parsing SharedSupport.dmg
This is required due to Info.plist reporting the application version, not the OS version This is required due to Info.plist reporting the application version, not the OS version

View File

@@ -25,7 +25,7 @@ class OpenCoreLegacyPatcher:
Initial entry point for starting OpenCore Legacy Patcher Initial entry point for starting OpenCore Legacy Patcher
""" """
def __init__(self): def __init__(self) -> None:
logging_handler.InitializeLoggingSupport() logging_handler.InitializeLoggingSupport()
self.constants: constants.Constants = constants.Constants() self.constants: constants.Constants = constants.Constants()
@@ -40,7 +40,7 @@ class OpenCoreLegacyPatcher:
gui_main.wx_python_gui(self.constants).main_menu(None) gui_main.wx_python_gui(self.constants).main_menu(None)
def _generate_base_data(self): def _generate_base_data(self) -> None:
""" """
Generate base data required for the patcher to run Generate base data required for the patcher to run
""" """

View File

@@ -32,14 +32,14 @@ class NetworkUtilities:
Utilities for network related tasks, primarily used for downloading files Utilities for network related tasks, primarily used for downloading files
""" """
def __init__(self, url: str = None): def __init__(self, url: str = None) -> None:
self.url: str = url self.url: str = url
if self.url is None: if self.url is None:
self.url = "https://github.com" self.url = "https://github.com"
def verify_network_connection(self): def verify_network_connection(self) -> bool:
""" """
Verifies that the network is available Verifies that the network is available
@@ -58,8 +58,13 @@ class NetworkUtilities:
): ):
return False return False
def validate_link(self): def validate_link(self) -> bool:
# Check if link is 404 """
Check for 404 error
Returns:
bool: True if link is valid, False otherwise
"""
try: try:
response = SESSION.head(self.url, timeout=5, allow_redirects=True) response = SESSION.head(self.url, timeout=5, allow_redirects=True)
if response.status_code == 404: if response.status_code == 404:
@@ -93,7 +98,7 @@ class DownloadObject:
""" """
def __init__(self, url: str, path: str): def __init__(self, url: str, path: str) -> None:
self.url: str = url self.url: str = url
self.status: str = DownloadStatus.INACTIVE self.status: str = DownloadStatus.INACTIVE
self.error_msg: str = "" self.error_msg: str = ""
@@ -121,11 +126,11 @@ class DownloadObject:
self._populate_file_size() self._populate_file_size()
def __del__(self): def __del__(self) -> None:
self.stop() self.stop()
def download(self, display_progress: bool = False, spawn_thread: bool = True, verify_checksum: bool = False): def download(self, display_progress: bool = False, spawn_thread: bool = True, verify_checksum: bool = False) -> None:
""" """
Download the file Download the file
@@ -152,7 +157,8 @@ class DownloadObject:
self.should_checksum = verify_checksum self.should_checksum = verify_checksum
self._download(display_progress) self._download(display_progress)
def download_simple(self, verify_checksum: bool = False):
def download_simple(self, verify_checksum: bool = False) -> str or bool:
""" """
Alternative to download(), mimics utilities.py's old download_file() function Alternative to download(), mimics utilities.py's old download_file() function
@@ -176,7 +182,7 @@ class DownloadObject:
return self.checksum.hexdigest() if self.checksum else True return self.checksum.hexdigest() if self.checksum else True
def _get_filename(self): def _get_filename(self) -> str:
""" """
Get the filename from the URL Get the filename from the URL
@@ -187,7 +193,7 @@ class DownloadObject:
return Path(self.url).name return Path(self.url).name
def _populate_file_size(self): def _populate_file_size(self) -> None:
""" """
Get the file size of the file to be downloaded Get the file size of the file to be downloaded
@@ -206,7 +212,7 @@ class DownloadObject:
self.total_file_size = 0.0 self.total_file_size = 0.0
def _update_checksum(self, chunk: bytes): def _update_checksum(self, chunk: bytes) -> None:
""" """
Update checksum with new chunk Update checksum with new chunk
@@ -216,7 +222,7 @@ class DownloadObject:
self._checksum_storage.update(chunk) self._checksum_storage.update(chunk)
def _prepare_working_directory(self, path: Path): def _prepare_working_directory(self, path: Path) -> bool:
""" """
Validates working enviroment, including free space and removing existing files Validates working enviroment, including free space and removing existing files
@@ -253,7 +259,7 @@ class DownloadObject:
return True return True
def _download(self, display_progress: bool = False): def _download(self, display_progress: bool = False) -> None:
""" """
Download the file Download the file
@@ -306,7 +312,7 @@ class DownloadObject:
utilities.enable_sleep_after_running() utilities.enable_sleep_after_running()
def get_percent(self): def get_percent(self) -> float:
""" """
Query the download percent Query the download percent
@@ -320,7 +326,7 @@ class DownloadObject:
return self.downloaded_file_size / self.total_file_size * 100 return self.downloaded_file_size / self.total_file_size * 100
def get_speed(self): def get_speed(self) -> float:
""" """
Query the download speed Query the download speed
@@ -331,7 +337,7 @@ class DownloadObject:
return self.downloaded_file_size / (time.time() - self.start_time) return self.downloaded_file_size / (time.time() - self.start_time)
def get_time_remaining(self): def get_time_remaining(self) -> float:
""" """
Query the time remaining for the download Query the time remaining for the download
@@ -345,7 +351,7 @@ class DownloadObject:
return (self.total_file_size - self.downloaded_file_size) / self.get_speed() return (self.total_file_size - self.downloaded_file_size) / self.get_speed()
def get_file_size(self): def get_file_size(self) -> float:
""" """
Query the file size of the file to be downloaded Query the file size of the file to be downloaded
@@ -356,7 +362,7 @@ class DownloadObject:
return self.total_file_size return self.total_file_size
def is_active(self): def is_active(self) -> bool:
""" """
Query if the download is active Query if the download is active
@@ -369,12 +375,11 @@ class DownloadObject:
return False return False
def stop(self): def stop(self) -> None:
""" """
Stop the download Stop the download
Returns: If the download is active, this function will hold the thread until stopped
boolean: If the download is active, this function will hold the thread until stopped
""" """
self.should_stop = True self.should_stop = True

View File

@@ -10,11 +10,11 @@ class OSProbe:
Library for querying OS information specific to macOS Library for querying OS information specific to macOS
""" """
def __init__(self): def __init__(self) -> None:
self.uname_data = platform.uname() self.uname_data = platform.uname()
def detect_kernel_major(self): def detect_kernel_major(self) -> int:
""" """
Detect the booted major kernel version Detect the booted major kernel version
@@ -25,7 +25,7 @@ class OSProbe:
return int(self.uname_data.release.partition(".")[0]) return int(self.uname_data.release.partition(".")[0])
def detect_kernel_minor(self): def detect_kernel_minor(self) -> int:
""" """
Detect the booted minor kernel version Detect the booted minor kernel version
@@ -36,7 +36,7 @@ class OSProbe:
return int(self.uname_data.release.partition(".")[2].partition(".")[0]) return int(self.uname_data.release.partition(".")[2].partition(".")[0])
def detect_os_version(self): def detect_os_version(self) -> str:
""" """
Detect the booted OS version Detect the booted OS version
@@ -51,7 +51,7 @@ class OSProbe:
return result.stdout.decode().strip() return result.stdout.decode().strip()
def detect_os_build(self, rsr: bool = False): def detect_os_build(self, rsr: bool = False) -> str:
""" """
Detect the booted OS build Detect the booted OS build

View File

@@ -13,13 +13,13 @@ from resources import constants
class RoutePayloadDiskImage: class RoutePayloadDiskImage:
def __init__(self, global_constants: constants.Constants): def __init__(self, global_constants: constants.Constants) -> None:
self.constants: constants.Constants = global_constants self.constants: constants.Constants = global_constants
self._setup_tmp_disk_image() self._setup_tmp_disk_image()
def _setup_tmp_disk_image(self): def _setup_tmp_disk_image(self) -> None:
""" """
Initialize temp directory and mount payloads.dmg Initialize temp directory and mount payloads.dmg
Create overlay for patcher to write to Create overlay for patcher to write to
@@ -55,7 +55,7 @@ class RoutePayloadDiskImage:
logging.info(f"Return Code: {output.returncode}") logging.info(f"Return Code: {output.returncode}")
def _unmount_active_dmgs(self, unmount_all_active=True): def _unmount_active_dmgs(self, unmount_all_active=True) -> None:
""" """
Unmounts disk images associated with OCLP Unmounts disk images associated with OCLP

View File

@@ -120,6 +120,8 @@ class DetectRootPatch:
self.supports_metal = True self.supports_metal = True
if self.constants.detected_os >= os_data.os_data.ventura: if self.constants.detected_os >= os_data.os_data.ventura:
self.amfi_must_disable = True self.amfi_must_disable = True
if (self.constants.detected_os == os_data.os_data.ventura and self.constants.detected_os_minor >= 4) or self.constants.detected_os > os_data.os_data.ventura:
self.amfi_shim_bins = True
elif gpu.arch in [ elif gpu.arch in [
device_probe.NVIDIA.Archs.Fermi, device_probe.NVIDIA.Archs.Fermi,
device_probe.NVIDIA.Archs.Kepler, device_probe.NVIDIA.Archs.Kepler,
@@ -205,11 +207,15 @@ class DetectRootPatch:
self.ivy_gpu = True self.ivy_gpu = True
if self.constants.detected_os >= os_data.os_data.ventura: if self.constants.detected_os >= os_data.os_data.ventura:
self.amfi_must_disable = True self.amfi_must_disable = True
if (self.constants.detected_os == os_data.os_data.ventura and self.constants.detected_os_minor >= 4) or self.constants.detected_os > os_data.os_data.ventura:
self.amfi_shim_bins = True
self.supports_metal = True self.supports_metal = True
elif gpu.arch == device_probe.Intel.Archs.Haswell: elif gpu.arch == device_probe.Intel.Archs.Haswell:
if self.constants.detected_os > os_data.os_data.monterey: if self.constants.detected_os > os_data.os_data.monterey:
self.haswell_gpu = True self.haswell_gpu = True
self.amfi_must_disable = True self.amfi_must_disable = True
if (self.constants.detected_os == os_data.os_data.ventura and self.constants.detected_os_minor >= 4) or self.constants.detected_os > os_data.os_data.ventura:
self.amfi_shim_bins = True
self.supports_metal = True self.supports_metal = True
elif gpu.arch == device_probe.Intel.Archs.Broadwell: elif gpu.arch == device_probe.Intel.Archs.Broadwell:
if self.constants.detected_os > os_data.os_data.monterey: if self.constants.detected_os > os_data.os_data.monterey:
@@ -738,7 +744,7 @@ class DetectRootPatch:
dict: Dictionary of patches to be applied from sys_patch_dict.py dict: Dictionary of patches to be applied from sys_patch_dict.py
""" """
all_hardware_patchset: dict = sys_patch_dict.SystemPatchDictionary(self.constants.detected_os, self.constants.detected_os_minor, self.constants.legacy_accel_support) all_hardware_patchset: dict = sys_patch_dict.SystemPatchDictionary(self.constants.detected_os, self.constants.detected_os_minor, self.constants.legacy_accel_support).patchset_dict
required_patches: dict = {} required_patches: dict = {}
utilities.cls() utilities.cls()
@@ -752,13 +758,16 @@ class DetectRootPatch:
if hardware_details["Graphics: Intel Sandy Bridge"] is True: if hardware_details["Graphics: Intel Sandy Bridge"] is True:
required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]}) required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]})
required_patches.update({"Non-Metal ColorSync Workaround": all_hardware_patchset["Graphics"]["Non-Metal ColorSync Workaround"]})
required_patches.update({"High Sierra GVA": all_hardware_patchset["Graphics"]["High Sierra GVA"]}) required_patches.update({"High Sierra GVA": all_hardware_patchset["Graphics"]["High Sierra GVA"]})
required_patches.update({"WebKit Monterey Common": all_hardware_patchset["Graphics"]["WebKit Monterey Common"]}) required_patches.update({"WebKit Monterey Common": all_hardware_patchset["Graphics"]["WebKit Monterey Common"]})
required_patches.update({"Intel Sandy Bridge": all_hardware_patchset["Graphics"]["Intel Sandy Bridge"]}) required_patches.update({"Intel Sandy Bridge": all_hardware_patchset["Graphics"]["Intel Sandy Bridge"]})
# Patchset breaks Display Profiles, don't install if primary GPU is AMD
if self.constants.computer.real_model not in ["Macmini5,2", "iMac12,1", "iMac12,2"]:
required_patches.update({"Non-Metal ColorSync Workaround": all_hardware_patchset["Graphics"]["Non-Metal ColorSync Workaround"]})
if hardware_details["Graphics: Intel Ivy Bridge"] is True: if hardware_details["Graphics: Intel Ivy Bridge"] is True:
required_patches.update({"Metal 3802 Common": all_hardware_patchset["Graphics"]["Metal 3802 Common"]}) required_patches.update({"Metal 3802 Common": all_hardware_patchset["Graphics"]["Metal 3802 Common"]})
required_patches.update({"Metal 3802 Common Extended": all_hardware_patchset["Graphics"]["Metal 3802 Common Extended"]})
required_patches.update({"Catalina GVA": all_hardware_patchset["Graphics"]["Catalina GVA"]}) required_patches.update({"Catalina GVA": all_hardware_patchset["Graphics"]["Catalina GVA"]})
required_patches.update({"Monterey OpenCL": all_hardware_patchset["Graphics"]["Monterey OpenCL"]}) required_patches.update({"Monterey OpenCL": all_hardware_patchset["Graphics"]["Monterey OpenCL"]})
required_patches.update({"Big Sur OpenCL": all_hardware_patchset["Graphics"]["Big Sur OpenCL"]}) required_patches.update({"Big Sur OpenCL": all_hardware_patchset["Graphics"]["Big Sur OpenCL"]})
@@ -767,6 +776,7 @@ class DetectRootPatch:
if hardware_details["Graphics: Intel Haswell"] is True: if hardware_details["Graphics: Intel Haswell"] is True:
required_patches.update({"Metal 3802 Common": all_hardware_patchset["Graphics"]["Metal 3802 Common"]}) required_patches.update({"Metal 3802 Common": all_hardware_patchset["Graphics"]["Metal 3802 Common"]})
required_patches.update({"Metal 3802 Common Extended": all_hardware_patchset["Graphics"]["Metal 3802 Common Extended"]})
required_patches.update({"Monterey GVA": all_hardware_patchset["Graphics"]["Monterey GVA"]}) required_patches.update({"Monterey GVA": all_hardware_patchset["Graphics"]["Monterey GVA"]})
required_patches.update({"Monterey OpenCL": all_hardware_patchset["Graphics"]["Monterey OpenCL"]}) required_patches.update({"Monterey OpenCL": all_hardware_patchset["Graphics"]["Monterey OpenCL"]})
required_patches.update({"Intel Haswell": all_hardware_patchset["Graphics"]["Intel Haswell"]}) required_patches.update({"Intel Haswell": all_hardware_patchset["Graphics"]["Intel Haswell"]})
@@ -795,8 +805,8 @@ class DetectRootPatch:
required_patches.update({"Non-Metal Enforcement": all_hardware_patchset["Graphics"]["Non-Metal Enforcement"]}) required_patches.update({"Non-Metal Enforcement": all_hardware_patchset["Graphics"]["Non-Metal Enforcement"]})
if hardware_details["Graphics: Nvidia Kepler"] is True: if hardware_details["Graphics: Nvidia Kepler"] is True:
required_patches.update({"Revert Metal Downgrade": all_hardware_patchset["Graphics"]["Revert Metal Downgrade"]})
required_patches.update({"Metal 3802 Common": all_hardware_patchset["Graphics"]["Metal 3802 Common"]}) required_patches.update({"Metal 3802 Common": all_hardware_patchset["Graphics"]["Metal 3802 Common"]})
required_patches.update({"Metal 3802 Common Extended": all_hardware_patchset["Graphics"]["Metal 3802 Common Extended"]})
required_patches.update({"Catalina GVA": all_hardware_patchset["Graphics"]["Catalina GVA"]}) required_patches.update({"Catalina GVA": all_hardware_patchset["Graphics"]["Catalina GVA"]})
required_patches.update({"Monterey OpenCL": all_hardware_patchset["Graphics"]["Monterey OpenCL"]}) required_patches.update({"Monterey OpenCL": all_hardware_patchset["Graphics"]["Monterey OpenCL"]})
required_patches.update({"Big Sur OpenCL": all_hardware_patchset["Graphics"]["Big Sur OpenCL"]}) required_patches.update({"Big Sur OpenCL": all_hardware_patchset["Graphics"]["Big Sur OpenCL"]})
@@ -827,7 +837,6 @@ class DetectRootPatch:
del(required_patches["AMD TeraScale 2"]["Install"]["/System/Library/Extensions"]["AMDRadeonX3000.kext"]) del(required_patches["AMD TeraScale 2"]["Install"]["/System/Library/Extensions"]["AMDRadeonX3000.kext"])
if hardware_details["Graphics: AMD Legacy GCN"] is True or hardware_details["Graphics: AMD Legacy Polaris"] is True: if hardware_details["Graphics: AMD Legacy GCN"] is True or hardware_details["Graphics: AMD Legacy Polaris"] is True:
required_patches.update({"Revert Metal Downgrade": all_hardware_patchset["Graphics"]["Revert Metal Downgrade"]})
required_patches.update({"Monterey GVA": all_hardware_patchset["Graphics"]["Monterey GVA"]}) required_patches.update({"Monterey GVA": all_hardware_patchset["Graphics"]["Monterey GVA"]})
required_patches.update({"Monterey OpenCL": all_hardware_patchset["Graphics"]["Monterey OpenCL"]}) required_patches.update({"Monterey OpenCL": all_hardware_patchset["Graphics"]["Monterey OpenCL"]})
if hardware_details["Graphics: AMD Legacy GCN"] is True: if hardware_details["Graphics: AMD Legacy GCN"] is True:

View File

@@ -11,14 +11,14 @@ REPO_LATEST_RELEASE_URL: str = "https://api.github.com/repos/dortania/OpenCore-L
class CheckBinaryUpdates: class CheckBinaryUpdates:
def __init__(self, global_constants: constants.Constants): def __init__(self, global_constants: constants.Constants) -> None:
self.constants: constants.Constants = global_constants self.constants: constants.Constants = global_constants
self.binary_version = self.constants.patcher_version self.binary_version = self.constants.patcher_version
self.binary_version_array = [int(x) for x in self.binary_version.split(".")] self.binary_version_array = [int(x) for x in self.binary_version.split(".")]
def _check_if_build_newer(self, remote_version: list = None, local_version: list = None): def _check_if_build_newer(self, remote_version: list = None, local_version: list = None) -> bool:
""" """
Check if the remote version is newer than the local version Check if the remote version is newer than the local version
@@ -50,7 +50,7 @@ class CheckBinaryUpdates:
return False return False
def _determine_local_build_type(self): def _determine_local_build_type(self) -> str:
""" """
Check if the local build is a GUI or TUI build Check if the local build is a GUI or TUI build
@@ -64,7 +64,7 @@ class CheckBinaryUpdates:
return "TUI" return "TUI"
def _determine_remote_type(self, remote_name: str): def _determine_remote_type(self, remote_name: str) -> str:
""" """
Check if the remote build is a GUI or TUI build Check if the remote build is a GUI or TUI build
@@ -83,7 +83,7 @@ class CheckBinaryUpdates:
return "Unknown" return "Unknown"
def check_binary_updates(self): def check_binary_updates(self) -> dict:
""" """
Check if any updates are available for the OpenCore Legacy Patcher binary Check if any updates are available for the OpenCore Legacy Patcher binary

View File

@@ -422,9 +422,19 @@ def find_disk_off_uuid(uuid):
return None return None
def get_free_space(disk=None): def get_free_space(disk=None):
"""
Get free space on disk in bytes
Parameters:
disk (str): Path to mounted disk (or folder on disk)
Returns:
int: Free space in bytes
"""
if disk is None: if disk is None:
disk = "/" disk = "/"
total, used, free = shutil.disk_usage("/")
total, used, free = shutil.disk_usage(disk)
return free return free
def grab_mount_point_from_disk(disk): def grab_mount_point_from_disk(disk):

View File

@@ -15,7 +15,7 @@ class PatcherValidation:
Primarily for Continuous Integration Primarily for Continuous Integration
""" """
def __init__(self, global_constants: constants.Constants): def __init__(self, global_constants: constants.Constants) -> None:
self.constants: constants.Constants = global_constants self.constants: constants.Constants = global_constants
self.constants.validate = True self.constants.validate = True
@@ -54,7 +54,7 @@ class PatcherValidation:
self._validate_sys_patch() self._validate_sys_patch()
def _build_prebuilt(self): def _build_prebuilt(self) -> None:
""" """
Generate a build for each predefined model Generate a build for each predefined model
Then validate against ocvalidate Then validate against ocvalidate
@@ -73,7 +73,7 @@ class PatcherValidation:
logging.info(f"Validation succeeded for predefined model: {model}") logging.info(f"Validation succeeded for predefined model: {model}")
def _build_dumps(self): def _build_dumps(self) -> None:
""" """
Generate a build for each predefined model Generate a build for each predefined model
Then validate against ocvalidate Then validate against ocvalidate
@@ -93,12 +93,16 @@ class PatcherValidation:
logging.info(f"Validation succeeded for predefined model: {self.constants.computer.real_model}") logging.info(f"Validation succeeded for predefined model: {self.constants.computer.real_model}")
def _validate_root_patch_files(self, major_kernel, minor_kernel): def _validate_root_patch_files(self, major_kernel: int, minor_kernel: int) -> None:
""" """
Validate that all files in the patchset are present in the payload Validate that all files in the patchset are present in the payload
Parameters:
major_kernel (int): Major kernel version
minor_kernel (int): Minor kernel version
""" """
patchset = sys_patch_dict.SystemPatchDictionary(major_kernel, minor_kernel, self.constants.legacy_accel_support) patchset = sys_patch_dict.SystemPatchDictionary(major_kernel, minor_kernel, self.constants.legacy_accel_support).patchset_dict
host_os_float = float(f"{major_kernel}.{minor_kernel}") host_os_float = float(f"{major_kernel}.{minor_kernel}")
for patch_subject in patchset: for patch_subject in patchset:
@@ -124,7 +128,7 @@ class PatcherValidation:
Path(self.constants.payload_path / f"OpenCore-Legacy-Patcher-{major_kernel}.{minor_kernel}.plist").unlink() Path(self.constants.payload_path / f"OpenCore-Legacy-Patcher-{major_kernel}.{minor_kernel}.plist").unlink()
def _validate_sys_patch(self): def _validate_sys_patch(self) -> None:
""" """
Validates sys_patch modules Validates sys_patch modules
""" """
@@ -160,7 +164,7 @@ class PatcherValidation:
logging.info("- Skipping Root Patch File integrity validation") logging.info("- Skipping Root Patch File integrity validation")
def _validate_configs(self): def _validate_configs(self) -> None:
""" """
Validates build modules Validates build modules
""" """