mirror of
https://github.com/dortania/OpenCore-Legacy-Patcher.git
synced 2026-06-17 21:00:00 +10:00
Merge branch 'main' into vault_2
This commit is contained in:
@@ -215,12 +215,13 @@ class BuildFirmware:
|
||||
# CSM check
|
||||
# For model support, check for GUID in firmware and as well as Bootcamp Assistant's Info.plist ('PreUEFIModels' key)
|
||||
# Ref: https://github.com/acidanthera/OpenCorePkg/blob/0.9.5/Platform/OpenLegacyBoot/OpenLegacyBoot.c#L19
|
||||
# if smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.CPUGen.ivy_bridge.value and self.model != "MacPro6,1":
|
||||
# logging.info("- Enabling CSM support")
|
||||
# support.BuildSupport(self.model, self.constants, self.config).get_efi_binary_by_path("OpenLegacyBoot.efi", "UEFI", "Drivers")["Enabled"] = True
|
||||
# else:
|
||||
# # Shipped alongside OpenCorePkg, so remove if unused
|
||||
# (self.constants.drivers_path / Path("OpenLegacyBoot.efi")).unlink()
|
||||
if Path(self.constants.drivers_path / Path("OpenLegacyBoot.efi")).exists():
|
||||
if smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.CPUGen.ivy_bridge.value and self.model != "MacPro6,1":
|
||||
logging.info("- Enabling CSM support")
|
||||
support.BuildSupport(self.model, self.constants, self.config).get_efi_binary_by_path("OpenLegacyBoot.efi", "UEFI", "Drivers")["Enabled"] = True
|
||||
else:
|
||||
# Shipped alongside OpenCorePkg, so remove if unused
|
||||
(self.constants.drivers_path / Path("OpenLegacyBoot.efi")).unlink()
|
||||
|
||||
def _firmware_compatibility_handling(self) -> None:
|
||||
"""
|
||||
@@ -232,7 +233,7 @@ class BuildFirmware:
|
||||
# Patches IOPCIConfigurator.cpp's IOPCIIsHotplugPort to skip configRead16/32 calls
|
||||
# Credit to CaseySJ for original discovery:
|
||||
# - Patch: https://github.com/AMD-OSX/AMD_Vanilla/pull/196
|
||||
# - Source: https://github.com/apple-oss-distributions/IOPCIFamily/blob/main/IOPCIConfigurator.cpp#L968-L1022
|
||||
# - Source: https://github.com/apple-oss-distributions/IOPCIFamily/blob/IOPCIFamily-583.40.1/IOPCIConfigurator.cpp#L968-L1022
|
||||
#
|
||||
# Currently all pre-Sandy Bridge Macs lacking an iGPU benefit from this patch as well as MacPro6,1
|
||||
# Otherwise some graphics hardware will fail to wake, macOS will misreport hardware as ExpressCard-based,
|
||||
@@ -247,7 +248,7 @@ class BuildFirmware:
|
||||
logging.info("- Adding PCI Bus Enumeration Patch")
|
||||
support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "CaseySJ - Fix PCI bus enumeration (Ventura)")["Enabled"] = True
|
||||
# Sonoma slightly adjusted this line specifically
|
||||
# - https://github.com/apple-oss-distributions/IOPCIFamily/blob/main/IOPCIConfigurator.cpp#L1009
|
||||
# - https://github.com/apple-oss-distributions/IOPCIFamily/blob/IOPCIFamily-583.40.1/IOPCIConfigurator.cpp#L1009
|
||||
support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Patch"], "Comment", "Fix PCI bus enumeration (Sonoma)")["Enabled"] = True
|
||||
|
||||
if self.constants.set_vmm_cpuid is True:
|
||||
|
||||
@@ -43,6 +43,7 @@ class BuildMiscellaneous:
|
||||
self._debug_handling()
|
||||
self._cpu_friend_handling()
|
||||
self._general_oc_handling()
|
||||
self._t1_handling()
|
||||
|
||||
|
||||
def _feature_unlock_handling(self) -> None:
|
||||
@@ -280,6 +281,12 @@ class BuildMiscellaneous:
|
||||
# - Ref: https://techcommunity.microsoft.com/t5/microsoft-usb-blog/reasons-to-avoid-companion-controllers/ba-p/270710
|
||||
#
|
||||
# To be paired for sys_patch_dict.py's 'Legacy USB 1.1' patchset
|
||||
#
|
||||
# Note: With macOS 14.1, injection of these kexts causes a panic.
|
||||
# To avoid this, a MaxKernel is configured with XNU 23.0.0 (macOS 14.0).
|
||||
# Additionally sys_patch.py stack will now patches the bins onto disk for 14.1+.
|
||||
# Reason for keeping the dual logic is due to potential conflicts of in-cache vs injection if we start
|
||||
# patching pre-14.1 hosts.
|
||||
if (
|
||||
smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.CPUGen.penryn.value or \
|
||||
self.model in ["MacPro4,1", "MacPro5,1", "Xserve3,1"]
|
||||
@@ -349,9 +356,8 @@ class BuildMiscellaneous:
|
||||
logging.info("- Enabling T1 Security Chip support")
|
||||
|
||||
support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Block"], "Identifier", "com.apple.driver.AppleSSE")["Enabled"] = True
|
||||
support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Block"], "Identifier", "com.apple.driver.AppleCredentialManager")["Enabled"] = True
|
||||
support.BuildSupport(self.model, self.constants, self.config).get_item_by_kv(self.config["Kernel"]["Block"], "Identifier", "com.apple.driver.AppleKeyStore")["Enabled"] = True
|
||||
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("corecrypto_T1.kext", self.constants.t1_corecrypto_version, self.constants.t1_corecrypto_path)
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("AppleSSE.kext", self.constants.t1_sse_version, self.constants.t1_sse_path)
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("AppleCredentialManager.kext", self.constants.t1_credential_version, self.constants.t1_credential_path)
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("AppleKeyStore.kext", self.constants.t1_key_store_version, self.constants.t1_key_store_path)
|
||||
@@ -77,6 +77,6 @@ class BuildSecurity:
|
||||
if self.constants.secure_status is False:
|
||||
logging.info("- Disabling SecureBootModel")
|
||||
self.config["Misc"]["Security"]["SecureBootModel"] = "Disabled"
|
||||
|
||||
|
||||
logging.info("- Enabling AMFIPass")
|
||||
support.BuildSupport(self.model, self.constants, self.config).enable_kext("AMFIPass.kext", self.constants.amfipass_version, self.constants.amfipass_path)
|
||||
|
||||
@@ -14,7 +14,7 @@ class Constants:
|
||||
def __init__(self) -> None:
|
||||
# Patcher Versioning
|
||||
self.patcher_version: str = "1.1.0" # OpenCore-Legacy-Patcher
|
||||
self.patcher_support_pkg_version: str = "1.3.4" # PatcherSupportPkg
|
||||
self.patcher_support_pkg_version: str = "1.4.2" # PatcherSupportPkg
|
||||
self.copyright_date: str = "Copyright © 2020-2023 Dortania"
|
||||
self.patcher_name: str = "OpenCore Legacy Patcher"
|
||||
|
||||
@@ -36,7 +36,7 @@ class Constants:
|
||||
self.lilu_version: str = "1.6.7" # Lilu
|
||||
self.whatevergreen_version: str = "1.6.6" # WhateverGreen
|
||||
self.whatevergreen_navi_version: str = "1.6.6-Navi" # WhateverGreen (Navi Patch)
|
||||
self.airportbcrmfixup_version: str = "2.1.7" # AirPortBrcmFixup
|
||||
self.airportbcrmfixup_version: str = "2.1.8" # AirPortBrcmFixup
|
||||
self.nvmefix_version: str = "1.1.1" # NVMeFix
|
||||
self.applealc_version: str = "1.6.3" # AppleALC
|
||||
self.restrictevents_version: str = "1.1.3" # RestrictEvents
|
||||
@@ -67,9 +67,9 @@ class Constants:
|
||||
self.aicpupm_version: str = "1.0.0" # AppleIntelCPUPowerManagement/Client
|
||||
self.s3x_nvme_version: str = "1.0.0" # IONVMeFamily (14.0 Beta 1, S1X and S3X classes)
|
||||
self.apple_camera_version: str = "1.0.0" # AppleCameraInterface (14.0 Beta 1)
|
||||
self.t1_credential_version: str = "1.0.0" # AppleCredentialManager (13.5 - T1 support)
|
||||
self.t1_sse_version: str = "1.0.0" # AppleSSE (13.5 - T1 support)
|
||||
self.t1_key_store_version: str = "1.0.0" # AppleKeyStore (13.5 - T1 support)
|
||||
self.t1_sse_version: str = "1.1.0" # AppleSSE (13.6 - T1 support)
|
||||
self.t1_key_store_version: str = "1.1.0" # AppleKeyStore (13.6 - T1 support)
|
||||
self.t1_corecrypto_version: str = "1.0.0" # corecrypto (13.6 - T1 support)
|
||||
|
||||
## Apple - Dortania Modified
|
||||
self.bcm570_version: str = "1.0.2" # CatalinaBCM5701Ethernet
|
||||
@@ -439,14 +439,14 @@ class Constants:
|
||||
def t1_key_store_path(self):
|
||||
return self.payload_kexts_path / Path(f"Misc/AppleKeyStore-v{self.t1_key_store_version}.zip")
|
||||
|
||||
@property
|
||||
def t1_credential_path(self):
|
||||
return self.payload_kexts_path / Path(f"Misc/AppleCredentialManager-v{self.t1_credential_version}.zip")
|
||||
|
||||
@property
|
||||
def t1_sse_path(self):
|
||||
return self.payload_kexts_path / Path(f"Misc/AppleSSE-v{self.t1_sse_version}.zip")
|
||||
|
||||
@property
|
||||
def t1_corecrypto_path(self):
|
||||
return self.payload_kexts_path / Path(f"Misc/corecrypto_T1-v{self.t1_corecrypto_version}.zip")
|
||||
|
||||
@property
|
||||
def mousse_path(self):
|
||||
return self.payload_kexts_path / Path(f"SSE/AAAMouSSE-v{self.mousse_version}.zip")
|
||||
|
||||
@@ -634,6 +634,7 @@ class Computer:
|
||||
ambient_light_sensor: Optional[bool] = False
|
||||
third_party_sata_ssd: Optional[bool] = False
|
||||
pcie_webcam: Optional[bool] = False
|
||||
t1_chip: Optional[bool] = False
|
||||
secure_boot_model: Optional[str] = None
|
||||
secure_boot_policy: Optional[int] = None
|
||||
oclp_sys_version: Optional[str] = None
|
||||
@@ -659,6 +660,7 @@ class Computer:
|
||||
computer.cpu_probe()
|
||||
computer.bluetooth_probe()
|
||||
computer.topcase_probe()
|
||||
computer.t1_probe()
|
||||
computer.ambient_light_sensor_probe()
|
||||
computer.pcie_webcam_probe()
|
||||
computer.sata_disk_probe()
|
||||
@@ -936,6 +938,18 @@ class Computer:
|
||||
elif usb_device.device_id in usb_data.AppleIDs.AppleUSBMultiTouch:
|
||||
self.trackpad_type = "Modern"
|
||||
|
||||
def t1_probe(self):
|
||||
if not self.usb_devices:
|
||||
return
|
||||
|
||||
for usb_device in self.usb_devices:
|
||||
if usb_device.vendor_id != 0x5ac:
|
||||
continue
|
||||
if usb_device.device_id != 0x8600:
|
||||
continue
|
||||
self.t1_chip = True
|
||||
break
|
||||
|
||||
def sata_disk_probe(self):
|
||||
# Get all SATA Controllers/Disks from 'system_profiler SPSerialATADataType'
|
||||
# Determine whether SATA SSD is present and Apple-made
|
||||
|
||||
@@ -665,12 +665,16 @@ class PatchSysVolume:
|
||||
self._preflight_checks(required_patches, source_files_path)
|
||||
for patch in required_patches:
|
||||
logging.info("- Installing Patchset: " + patch)
|
||||
if "Remove" in required_patches[patch]:
|
||||
for remove_patch_directory in required_patches[patch]["Remove"]:
|
||||
logging.info("- Remove Files at: " + remove_patch_directory)
|
||||
for remove_patch_file in required_patches[patch]["Remove"][remove_patch_directory]:
|
||||
destination_folder_path = str(self.mount_location) + remove_patch_directory
|
||||
self._remove_file(destination_folder_path, remove_patch_file)
|
||||
for method_remove in ["Remove", "Remove Non-Root"]:
|
||||
if method_remove in required_patches[patch]:
|
||||
for remove_patch_directory in required_patches[patch][method_remove]:
|
||||
logging.info("- Remove Files at: " + remove_patch_directory)
|
||||
for remove_patch_file in required_patches[patch][method_remove][remove_patch_directory]:
|
||||
if method_remove == "Remove":
|
||||
destination_folder_path = str(self.mount_location) + remove_patch_directory
|
||||
else:
|
||||
destination_folder_path = str(self.mount_location_data) + remove_patch_directory
|
||||
self._remove_file(destination_folder_path, remove_patch_file)
|
||||
|
||||
|
||||
for method_install in ["Install", "Install Non-Root"]:
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# Copyright (C) 2022, Mykola Grymalyuk
|
||||
# Copyright (c) 2023 Jazzzny
|
||||
|
||||
import wx
|
||||
import wx.html2
|
||||
import requests
|
||||
import markdown2
|
||||
import logging
|
||||
import plistlib
|
||||
import subprocess
|
||||
@@ -51,19 +55,85 @@ class AutomaticSysPatch:
|
||||
logging.info(f"- Found new version: {version}")
|
||||
|
||||
app = wx.App()
|
||||
frame = wx.Frame(None, -1, "OpenCore Legacy Patcher")
|
||||
dialog = wx.MessageDialog(
|
||||
parent=frame,
|
||||
message=f"Current Version: {self.constants.patcher_version}{' (Nightly)' if not self.constants.commit_info[0].startswith('refs/tags') else ''}\nNew version: {version}\nWould you like to update?",
|
||||
caption="Update Available for OpenCore Legacy Patcher!",
|
||||
style=wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION
|
||||
)
|
||||
dialog.SetYesNoCancelLabels("Download and install", "View on Github", "Ignore")
|
||||
response = dialog.ShowModal()
|
||||
if response == wx.ID_YES:
|
||||
gui_entry.EntryPoint(self.constants).start(entry=gui_entry.SupportedEntryPoints.UPDATE_APP)
|
||||
elif response == wx.ID_NO:
|
||||
mainframe = wx.Frame(None, -1, "OpenCore Legacy Patcher")
|
||||
|
||||
ID_GITHUB = wx.NewId()
|
||||
ID_UPDATE = wx.NewId()
|
||||
|
||||
url = "https://api.github.com/repos/dortania/OpenCore-Legacy-Patcher/releases/latest"
|
||||
response = requests.get(url).json()
|
||||
changelog = response["body"].split("## Asset Information")[0]
|
||||
|
||||
html_markdown = markdown2.markdown(changelog)
|
||||
html_css = """
|
||||
<style>
|
||||
body {
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-size: 13px;
|
||||
margin-top: 20px;
|
||||
background-color: rgb(238,238,238);
|
||||
}
|
||||
h2 {
|
||||
line-height: 0.5;
|
||||
padding-left: 10px;
|
||||
}
|
||||
a {
|
||||
color: -apple-system-control-accent;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
color: #fff;
|
||||
background-color: rgb(47,47,47);
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
"""
|
||||
frame = wx.Dialog(None, -1, title="", size=(600, 500))
|
||||
frame.SetMinSize((600, 500))
|
||||
frame.SetWindowStyle(wx.STAY_ON_TOP)
|
||||
panel = wx.Panel(frame)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.AddSpacer(10)
|
||||
self.title_text = wx.StaticText(panel, label="A new version of OpenCore Legacy Patcher is available!")
|
||||
self.description = wx.StaticText(panel, label=f"OpenCore Legacy Patcher {version} is now available - You have {self.constants.patcher_version}. Would you like to update?")
|
||||
self.title_text.SetFont(wx.Font(19, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ".AppleSystemUIFont"))
|
||||
self.description.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont"))
|
||||
self.web_view = wx.html2.WebView.New(panel, style=wx.BORDER_SUNKEN)
|
||||
html_code = html_css+html_markdown.replace("<a href=", "<a target='_blank' href=")
|
||||
self.web_view.SetPage(html_code, "")
|
||||
self.web_view.Bind(wx.html2.EVT_WEBVIEW_NEWWINDOW, self._onWebviewNav)
|
||||
self.web_view.EnableContextMenu(False)
|
||||
self.close_button = wx.Button(panel, label="Ignore")
|
||||
self.close_button.Bind(wx.EVT_BUTTON, lambda event: frame.EndModal(wx.ID_CANCEL))
|
||||
self.view_button = wx.Button(panel, ID_GITHUB, label="View on GitHub")
|
||||
self.view_button.Bind(wx.EVT_BUTTON, lambda event: frame.EndModal(ID_GITHUB))
|
||||
self.install_button = wx.Button(panel, label="Download and Install")
|
||||
self.install_button.Bind(wx.EVT_BUTTON, lambda event: frame.EndModal(ID_UPDATE))
|
||||
self.install_button.SetDefault()
|
||||
|
||||
buttonsizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
buttonsizer.Add(self.close_button, 0, wx.ALIGN_CENTRE | wx.RIGHT, 5)
|
||||
buttonsizer.Add(self.view_button, 0, wx.ALIGN_CENTRE | wx.LEFT|wx.RIGHT, 5)
|
||||
buttonsizer.Add(self.install_button, 0, wx.ALIGN_CENTRE | wx.LEFT, 5)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.Add(self.title_text, 0, wx.ALIGN_CENTRE | wx.TOP, 20)
|
||||
sizer.Add(self.description, 0, wx.ALIGN_CENTRE | wx.BOTTOM, 20)
|
||||
sizer.Add(self.web_view, 1, wx.EXPAND | wx.LEFT|wx.RIGHT, 10)
|
||||
sizer.Add(buttonsizer, 0, wx.ALIGN_RIGHT | wx.ALL, 20)
|
||||
panel.SetSizer(sizer)
|
||||
frame.Centre()
|
||||
|
||||
result = frame.ShowModal()
|
||||
|
||||
|
||||
if result == ID_GITHUB:
|
||||
webbrowser.open(dict["Github Link"])
|
||||
elif result == ID_UPDATE:
|
||||
gui_entry.EntryPoint(self.constants).start(entry=gui_entry.SupportedEntryPoints.UPDATE_APP)
|
||||
|
||||
|
||||
return
|
||||
|
||||
if utilities.check_seal() is True:
|
||||
@@ -127,6 +197,9 @@ class AutomaticSysPatch:
|
||||
if self._determine_if_versions_match():
|
||||
self._determine_if_boot_matches()
|
||||
|
||||
def _onWebviewNav(self, event):
|
||||
url = event.GetURL()
|
||||
webbrowser.open(url)
|
||||
|
||||
def _determine_if_versions_match(self):
|
||||
"""
|
||||
|
||||
@@ -53,6 +53,7 @@ class DetectRootPatch:
|
||||
self.legacy_keyboard_backlight = False
|
||||
self.legacy_uhci_ohci = False
|
||||
self.legacy_pcie_webcam = False
|
||||
self.legacy_t1_chip = False
|
||||
|
||||
# Patch Requirements
|
||||
self.amfi_must_disable = False
|
||||
@@ -540,6 +541,10 @@ class DetectRootPatch:
|
||||
|
||||
if self.constants.detected_os >= os_data.os_data.sonoma:
|
||||
self.legacy_pcie_webcam = self.constants.computer.pcie_webcam
|
||||
self.legacy_t1_chip = self.constants.computer.t1_chip
|
||||
|
||||
if self.legacy_t1_chip is True:
|
||||
self.amfi_must_disable = True
|
||||
|
||||
if self._check_uhci_ohci() is True:
|
||||
self.legacy_uhci_ohci = True
|
||||
@@ -622,6 +627,7 @@ class DetectRootPatch:
|
||||
"Miscellaneous: Legacy Keyboard Backlight": self.legacy_keyboard_backlight,
|
||||
"Miscellaneous: Legacy USB 1.1": self.legacy_uhci_ohci,
|
||||
"Miscellaneous: PCIe FaceTime Camera": self.legacy_pcie_webcam,
|
||||
"Miscellaneous: T1 Security Chip": self.legacy_t1_chip,
|
||||
"Settings: Requires AMFI exemption": self.amfi_must_disable,
|
||||
"Settings: Supports Auxiliary Cache": not self.requires_root_kc,
|
||||
"Settings: Kernel Debug Kit missing": self.missing_kdk if self.constants.detected_os >= os_data.os_data.ventura.value else False,
|
||||
|
||||
@@ -176,10 +176,14 @@ class GenerateRootPatchSets:
|
||||
|
||||
if self.hardware_details["Miscellaneous: Legacy USB 1.1"] is True:
|
||||
required_patches.update({"Legacy USB 1.1": all_hardware_patchset["Miscellaneous"]["Legacy USB 1.1"]})
|
||||
required_patches.update({"Legacy USB 1.1 Extended": all_hardware_patchset["Miscellaneous"]["Legacy USB 1.1 Extended"]})
|
||||
|
||||
if self.hardware_details["Miscellaneous: PCIe FaceTime Camera"] is True:
|
||||
required_patches.update({"PCIe FaceTime Camera": all_hardware_patchset["Miscellaneous"]["PCIe FaceTime Camera"]})
|
||||
|
||||
if self.hardware_details["Miscellaneous: T1 Security Chip"] is True:
|
||||
required_patches.update({"T1 Security Chip": all_hardware_patchset["Miscellaneous"]["T1 Security Chip"]})
|
||||
|
||||
if required_patches:
|
||||
host_os_float = float(f"{self.constants.detected_os}.{self.constants.detected_os_minor}")
|
||||
|
||||
|
||||
@@ -60,8 +60,8 @@ def seconds_to_readable_time(seconds) -> str:
|
||||
seconds = int(seconds)
|
||||
time = ""
|
||||
|
||||
if seconds == 0:
|
||||
return "0m "
|
||||
if 0 <= seconds < 60:
|
||||
return "Less than a minute "
|
||||
if seconds < 0:
|
||||
return "Indeterminate time "
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class DownloadFrame(wx.Frame):
|
||||
title_label.SetFont(gui_support.font_factory(19, wx.FONTWEIGHT_BOLD))
|
||||
title_label.Centre(wx.HORIZONTAL)
|
||||
|
||||
progress_bar = wx.Gauge(frame, range=100, pos=(-1, title_label.GetPosition()[1] + title_label.GetSize()[1] + 5), size=(300, 20))
|
||||
progress_bar = wx.Gauge(frame, range=100, pos=(-1, title_label.GetPosition()[1] + title_label.GetSize()[1] + 5), size=(300, 20), style=wx.GA_SMOOTH|wx.GA_PROGRESS)
|
||||
progress_bar.Centre(wx.HORIZONTAL)
|
||||
|
||||
label_amount = wx.StaticText(frame, label="Preparing download", pos=(-1, progress_bar.GetPosition()[1] + progress_bar.GetSize()[1]))
|
||||
@@ -68,7 +68,9 @@ class DownloadFrame(wx.Frame):
|
||||
self.download_obj.download()
|
||||
while self.download_obj.is_active():
|
||||
|
||||
percentage: int = self.download_obj.get_percent()
|
||||
percentage: int = round(self.download_obj.get_percent())
|
||||
if percentage == 0:
|
||||
percentage = 1
|
||||
|
||||
if percentage == -1:
|
||||
amount_str = f"{utilities.human_fmt(self.download_obj.downloaded_file_size)} downloaded ({utilities.human_fmt(self.download_obj.get_speed())}/s)"
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# Generate GUI for main menu
|
||||
# Portions of this file Copyright (c) 2023 Jazzzny
|
||||
|
||||
import wx
|
||||
import wx.html2
|
||||
import markdown2
|
||||
import requests
|
||||
import sys
|
||||
import logging
|
||||
import threading
|
||||
@@ -271,7 +276,7 @@ class MainFrame(wx.Frame):
|
||||
def _check_for_updates(self):
|
||||
if self.constants.has_checked_updates is True:
|
||||
return
|
||||
|
||||
|
||||
ignore_updates = global_settings.GlobalEnviromentSettings().read_property("IgnoreAppUpdates")
|
||||
if ignore_updates is True:
|
||||
self.constants.ignore_updates = True
|
||||
@@ -285,20 +290,8 @@ class MainFrame(wx.Frame):
|
||||
|
||||
version = dict["Version"]
|
||||
logging.info(f"New version: {version}")
|
||||
dialog = wx.MessageDialog(
|
||||
parent=self,
|
||||
message=f"Current Version: {self.constants.patcher_version}{' (Nightly)' if not self.constants.commit_info[0].startswith('refs/tags') else ''}\nNew version: {version}\nWould you like to update?",
|
||||
caption="Update Available for OpenCore Legacy Patcher!",
|
||||
style=wx.YES_NO | wx.CANCEL | wx.ICON_QUESTION
|
||||
)
|
||||
dialog.SetYesNoCancelLabels("Download and install", "Ignore", "View on Github")
|
||||
response = dialog.ShowModal()
|
||||
|
||||
if response == wx.ID_YES:
|
||||
wx.CallAfter(self.on_update, dict["Link"], version)
|
||||
elif response == wx.ID_CANCEL:
|
||||
webbrowser.open(dict["Github Link"])
|
||||
|
||||
|
||||
wx.CallAfter(self.on_update, dict["Link"], version, dict["Github Link"])
|
||||
|
||||
def on_build_and_install(self, event: wx.Event = None):
|
||||
self.Hide()
|
||||
@@ -345,12 +338,90 @@ class MainFrame(wx.Frame):
|
||||
screen_location=self.GetPosition()
|
||||
)
|
||||
|
||||
def on_update(self, oclp_url: str, oclp_version: str):
|
||||
gui_update.UpdateFrame(
|
||||
def on_update(self, oclp_url: str, oclp_version: str, oclp_github_url: str):
|
||||
|
||||
ID_GITHUB = wx.NewId()
|
||||
ID_UPDATE = wx.NewId()
|
||||
|
||||
url = "https://api.github.com/repos/dortania/OpenCore-Legacy-Patcher/releases/latest"
|
||||
response = requests.get(url).json()
|
||||
changelog = response["body"].split("## Asset Information")[0]
|
||||
|
||||
html_markdown = markdown2.markdown(changelog)
|
||||
html_css = """
|
||||
<style>
|
||||
body {
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-size: 13px;
|
||||
margin-top: 20px;
|
||||
background-color: rgb(238,238,238);
|
||||
}
|
||||
h2 {
|
||||
line-height: 0.5;
|
||||
}
|
||||
a {
|
||||
color: -apple-system-control-accent;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
color: #fff;
|
||||
background-color: rgb(47,47,47);
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
"""
|
||||
frame = wx.Dialog(None, -1, title="", size=(600, 500))
|
||||
frame.SetMinSize((600, 500))
|
||||
frame.SetWindowStyle(wx.STAY_ON_TOP)
|
||||
panel = wx.Panel(frame)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.AddSpacer(10)
|
||||
self.title_text = wx.StaticText(panel, label="A new version of OpenCore Legacy Patcher is available!")
|
||||
self.description = wx.StaticText(panel, label=f"OpenCore Legacy Patcher {oclp_version} is now available - You have {self.constants.patcher_version}. Would you like to update?")
|
||||
self.title_text.SetFont(wx.Font(19, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, ".AppleSystemUIFont"))
|
||||
self.description.SetFont(wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, ".AppleSystemUIFont"))
|
||||
self.web_view = wx.html2.WebView.New(panel, style=wx.BORDER_SUNKEN)
|
||||
html_code = html_css+html_markdown.replace("<a href=", "<a target='_blank' href=")
|
||||
self.web_view.SetPage(html_code, "")
|
||||
self.web_view.Bind(wx.html2.EVT_WEBVIEW_NEWWINDOW, self._onWebviewNav)
|
||||
self.web_view.EnableContextMenu(False)
|
||||
self.close_button = wx.Button(panel, label="Dismiss")
|
||||
self.close_button.Bind(wx.EVT_BUTTON, lambda event: frame.EndModal(wx.ID_CANCEL))
|
||||
self.view_button = wx.Button(panel, ID_GITHUB, label="View on GitHub")
|
||||
self.view_button.Bind(wx.EVT_BUTTON, lambda event: frame.EndModal(ID_GITHUB))
|
||||
self.install_button = wx.Button(panel, label="Download and Install")
|
||||
self.install_button.Bind(wx.EVT_BUTTON, lambda event: frame.EndModal(ID_UPDATE))
|
||||
self.install_button.SetDefault()
|
||||
|
||||
buttonsizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
buttonsizer.Add(self.close_button, 0, wx.ALIGN_CENTRE | wx.RIGHT, 5)
|
||||
buttonsizer.Add(self.view_button, 0, wx.ALIGN_CENTRE | wx.LEFT|wx.RIGHT, 5)
|
||||
buttonsizer.Add(self.install_button, 0, wx.ALIGN_CENTRE | wx.LEFT, 5)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.Add(self.title_text, 0, wx.ALIGN_CENTRE | wx.TOP, 20)
|
||||
sizer.Add(self.description, 0, wx.ALIGN_CENTRE | wx.BOTTOM, 20)
|
||||
sizer.Add(self.web_view, 1, wx.EXPAND | wx.LEFT|wx.RIGHT, 10)
|
||||
sizer.Add(buttonsizer, 0, wx.ALIGN_RIGHT | wx.ALL, 20)
|
||||
panel.SetSizer(sizer)
|
||||
frame.Centre()
|
||||
|
||||
result = frame.ShowModal()
|
||||
|
||||
|
||||
if result == ID_GITHUB:
|
||||
webbrowser.open(oclp_github_url)
|
||||
elif result == ID_UPDATE:
|
||||
gui_update.UpdateFrame(
|
||||
parent=self,
|
||||
title=self.title,
|
||||
global_constants=self.constants,
|
||||
screen_location=self.GetPosition(),
|
||||
url=oclp_url,
|
||||
version_label=oclp_version
|
||||
)
|
||||
)
|
||||
|
||||
def _onWebviewNav(self, event):
|
||||
url = event.GetURL()
|
||||
webbrowser.open(url)
|
||||
Reference in New Issue
Block a user