├── .gitignore
├── README.md
├── README_EN.md
├── enable_ai_old.sh
└── enable_ai.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # enableAppleAI
2 |
3 | [English README](README_EN.md) | [中文说明](README.md)
4 |
5 | 一种在MacOS上(目前测试MacOS 15.4+及26.1均可),无需长期运行后台服务,也无需长期禁用SIP,即可永久稳定开启中国销售Mac设备上Apple AI的方法。
6 |
7 |
8 |
9 | ## Star History
10 |
11 | [](https://www.star-history.com/#kanshurichard/enableappleai&type=date&legend=top-left)
12 |
13 | ## 最新3.21版本介绍
14 |
15 | - **新增“强制修改地区为美国”功能**:针对macOS 26.X,通过修改 `countryd` 配置文件,即使设备位于中国,也可开启 Siri 整合 ChatGPT、Apple News 及国际版苹果地图。(需配合受支持地区的网络环境)。
16 | - **新增 iPhone 镜像功能预警**:**重要提醒**,如果您使用 iPhone 镜像功能,必须在修改国家代码前先完成 iPhone 与 Mac 的配对,否则修改后可能导致无法配对。
17 | - 增加了方法2(来自 https://github.com/hyderay/AiOnMac 的启发):只需修改plist文件,不再需要使用lldb对系统进程进行任何调试——**建议方法1失败时尝试**。
18 | - 3.1+版本加入了对Foundation Model等功能的支持。
19 |
20 |
21 | ## 工作原理概述
22 |
23 | ### 方法1(修改更彻底,建议优先尝试)
24 |
25 | 尝试试绕过 Apple 对 Apple 智能的启用检查:
26 |
27 | 1. 用一个[来自这里](https://github.com/CatMe0w/zouxian)的代码,使用lldb暂时注入eligibiltyd,模拟美版LL机型,使其向系统数据库输出该机型支持AI的信息(具体功能请参考该脚本的源仓库)。
28 | 2. 修改 `/private/var/db/eligibilityd/eligibility.plist` 这个系统文件,特别是调整其中关于设备区域码 (OS_ELIGIBILITY_INPUT_DEVICE_REGION_CODE) 和外部启动盘 (OS_ELIGIBILITY_INPUT_EXTERNAL_BOOT_DRIVE) 的检查值,禁止系统用这些参数来作为功能开启的前提条件。
29 | 3. 通过修改文件权限和设置 `uchg` (immutable) 标记,锁定修改后的各个缓存文件状态,防止系统刷新缓存文件。
30 |
31 | ### 方法2(可解决方法1失败的奇怪问题)
32 |
33 | 1. 可以直接修改 `/private/var/db/eligibilityd/eligibility.plist` 等几个系统缓存文件,强制让MacOS系统认为设备符合开启Apple智能各项功能的要求。
34 | 2. 如果不使用lldb注入,可能会无法开启部分高级功能,但可以作为保底方案。
35 | 3. 同样通过 `uchg` 锁定文件。
36 |
37 | ### 附加功能:强制修改地区(Method 1 & 2 完成后可选)
38 |
39 | - 修改 `/private/var/db/com.apple.countryd/countryCodeCache.plist` 文件,将缓存的国家代码强制改为 `US`。
40 | - 这可以欺骗系统认为设备物理位于美国,从而解锁 ChatGPT 整合等基于地理位置限制的功能。
41 |
42 | ## 前置条件
43 |
44 | 1. 一台运行兼容 macOS 版本的 Mac (M1或以上CPU,macOS 15.1或以上版本)。
45 | 2. 管理员权限,因为脚本使用 `sudo` 执行特权命令。
46 | 3. **系统地区设置为“美国”,系统语言、Siri语言均设置为`简体中文(普通话)/中国`,`English(USA)`或其他任何受到Apple智能支持的语言和地区——设置为其他不支持Apple AI的区域会导致开启失败。**
47 | 4. 稳定的互联网连接以下载脚本。
48 | 5. SIP (System Integrity Protection) 已禁用。**(破解完成后可重新开启,不影响AI功能)**
49 |
50 | ## 执行步骤
51 |
52 | 请严格按照以下步骤操作:
53 |
54 | ### 步骤 1: 禁用 System Integrity Protection (SIP)
55 |
56 | 如果 SIP 已经禁用,可以跳过此步骤。如果未禁用,您必须手动禁用它:
57 |
58 | 1. **重启 Mac**。
59 | 2. 在 Mac 启动时,长按开机键,直到进入 macOS 恢复模式,途中你可能需要输入几次密码。
60 | 3. 在屏幕顶部的菜单栏中,选择 **实用工具 (Utilities)** > **终端 (Terminal)**。
61 | 4. 在终端窗口中,输入以下命令并按回车:
62 | ```bash
63 | csrutil disable
64 | ```
65 | 5. 按y键确认,之后您会看到一条 SIP 已禁用的消息。
66 | 6. 在终端中,输入 `reboot` 并按回车,或者从 Apple 菜单中选择 **重启 (Restart)** 退出恢复模式并启动 Mac。
67 |
68 | ### 步骤 2: 下载并运行脚本
69 |
70 |
71 | **单命令快速执行方法:**
72 |
73 | 如果您完全信任本脚本,可以使用以下单命令直接执行:
74 |
75 | **最新3.21脚本:**
76 |
77 | ```bash
78 | curl -sL https://raw.githubusercontent.com/kanshurichard/enableAppleAI/main/enable_ai.sh | bash
79 | ```
80 |
81 | **如果在国内访问困难,请尝试以下国内加速地址:**
82 |
83 | ```bash
84 | curl -sL https://cdn.jsdelivr.net/gh/kanshurichard/enableAppleAI@main/enable_ai.sh | bash
85 | ```
86 |
87 |
88 | 如果本版遇到问题,请您去提Issue,并可尝试2.13旧版:
89 |
90 | ```bash
91 | curl -sL https://raw.githubusercontent.com/kanshurichard/enableAppleAI/main/enable_ai_old.sh | bash
92 | ```
93 |
94 |
95 | **手动执行脚本:**
96 |
97 | 1. 打开 **终端 (Terminal)** 应用程序。
98 | 2. 使用 `curl` 下载脚本文件到当前目录:
99 | ```bash
100 | curl -O https://raw.githubusercontent.com/kanshurichard/enableAppleAI/main/enable_ai.sh
101 | ```
102 | 3. **审查脚本内容:** 使用文本编辑器或命令行工具(如 `cat enable_ai.sh`)仔细阅读下载的 `enable_ai.sh` 文件,确保您理解它将执行的操作。
103 | 4. 赋予脚本执行权限:
104 | ```bash
105 | chmod +x enable_ai.sh
106 | ```
107 | 5. 执行脚本:
108 | ```bash
109 | ./enable_ai.sh
110 | ```
111 |
112 | ### 步骤 3: 按照脚本提示操作
113 |
114 | 1. **选择语言**:支持中文和英文。
115 | 2. **选择操作**:选择“启用 Apple Intelligence”。
116 | 3. **选择方法**:建议优先尝试 **方法 1**。
117 | 4. **可选步骤**:如果您在 macOS 26上,脚本会询问是否强制修改地区为美国。**注意:如果您需要使用 iPhone 镜像,请务必在确认此步前完成配对!**
118 | 5. **重启**:脚本执行完毕后,重启 Mac。
119 | 6. **检查**:系统设置 -> Apple 智能与 Siri,查看是否已开启。
120 | 7. **恢复 SIP**:确认功能正常后,建议重新进入恢复模式执行 `csrutil enable` 启用 SIP。
121 |
122 | ## 故障排除与反馈
123 |
124 | * 如果脚本执行过程中遇到错误,请检查终端输出的错误信息。
125 | * 如果按照步骤执行后 Apple 智能未能成功启用,或者出现其他异常,您也可以在本项目的 GitHub Issues 中提交问题。
126 |
127 | ## 常见问题
128 |
129 | **问:如何卸载?**
130 | 答:运行脚本,在主菜单选择 `2. 解锁文件 (卸载)` 即可一键恢复文件权限和状态。
131 |
132 | **问:为什么新系统(如 macOS 16/26)新增的 AI 功能没有出现?**
133 | 答:请更新脚本到最新版(v3.21+)。新版脚本增加了对 `countryd` 的修改,这对解锁 ChatGPT 等功能至关重要。升级前建议先运行旧脚本的“卸载”功能。
134 |
135 | **问:iPhone 镜像(iPhone Mirroring)无法连接?**
136 | 答:如果您使用了“强制修改地区为美国”的功能,可能会导致 Mac 和 iPhone 的地区代码不匹配,从而无法配对。**解决方法**:运行脚本选择“卸载”恢复原状 -> 配对 iPhone -> 再次运行脚本启用 AI (此时修改地区不会影响已配对的连接)。
137 |
138 | **问:开启AI后,Siri调用的仍然是百度百科这类国内工具,ChatGPT也无法正常调用?**
139 | 答:请尝试使用脚本中的“方法2”或在“方法1”成功后,同意进行“强制修改地区为美国”的操作。这会将系统底层的地理位置缓存锁定为 US,从而绕过通过 IP 判断地区的限制(注意:仍需配合受支持地区节点的网络环境)。
140 |
141 | **问:图乐园(Image Playground)无法创建图片?**
142 | 答:图乐园在老版本系统中不支持中文语言下创建图片,或者需要 macOS 26.1+ 系统。在之前的版本,请尝试将系统语言临时改为英语(美国)。
143 |
144 | **问:是否能开启繁体中文(或其他非首发语言)的Apple智能?**
145 | 答:取决于 Apple 官方是否已下发该语言包。如果官方尚未支持,强制开启也没有用。
146 |
147 | ---
148 |
149 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | # enableAppleAI
2 |
3 | [English README](README_EN.md) | [中文说明](README.md)
4 |
5 | A method to permanently and stably enable Apple Intelligence on Mac devices sold in China, without running background services long-term or keeping SIP disabled permanently. (Tested on macOS 15.4+ and 26.1).
6 |
7 |
8 |
9 | ## Star History
10 |
11 | [](https://www.star-history.com/#kanshurichard/enableappleai&type=date&legend=top-left)
12 |
13 | ## Latest Version 3.21 Features
14 |
15 | - **New "Force US Location" Feature**: Targeting macOS 26.X, modifying the `countryd` configuration allows unlocking Siri integration with ChatGPT, Apple News, and International Apple Maps even if the device is physically in China (requires supported network environment).
16 | - **New iPhone Mirroring Warning**: **IMPORTANT**: If you use iPhone Mirroring, you **MUST** pair your iPhone with your Mac **BEFORE** changing the country code. Modification afterwards may prevent pairing.
17 | - **Method 2 Added** (Inspired by https://github.com/hyderay/AiOnMac): Simply modifies plist files without `lldb` injection. **Recommended to try if Method 1 fails.**
18 | - Version 3.1+ added support for Foundation Models, etc.
19 |
20 | ## How It Works
21 |
22 | ### Method 1 (More comprehensive, recommended first)
23 |
24 | Attempts to bypass Apple's eligibility checks for Apple Intelligence:
25 |
26 | 1. Uses [code from here](https://github.com/CatMe0w/zouxian) to temporarily inject into `eligibilityd` via `lldb`, simulating a US model (LL) to output AI support status to the system database.
27 | 2. Modifies `/private/var/db/eligibilityd/eligibility.plist`, specifically adjusting checks for device region code (`OS_ELIGIBILITY_INPUT_DEVICE_REGION_CODE`) and external boot drive (`OS_ELIGIBILITY_INPUT_EXTERNAL_BOOT_DRIVE`) to prevent them from blocking feature enablement.
28 | 3. Locks the modified cache files using file permissions and the `uchg` (immutable) flag to prevent the system from refreshing/overwriting them.
29 |
30 | ### Method 2 (Solves specific failures of Method 1)
31 |
32 | 1. Directly modifies system cache files like `/private/var/db/eligibilityd/eligibility.plist` to force macOS to believe the device meets Apple Intelligence requirements.
33 | 2. Does not use `lldb` injection. While it may not unlock every advanced feature in some edge cases, it serves as a robust fallback.
34 | 3. Also locks files using `uchg`.
35 |
36 | ### Additional Feature: Force US Location (Optional after Method 1 & 2)
37 |
38 | - Modifies `/private/var/db/com.apple.countryd/countryCodeCache.plist` to force the cached country code to `US`.
39 | - This tricks the system into believing the device is physically located in the US, unlocking location-restricted features like ChatGPT integration.
40 |
41 | ## Prerequisites
42 |
43 | 1. A Mac running a compatible macOS version (M1 or later CPU, macOS 15.1 or later).
44 | 2. Administrator privileges (the script uses `sudo`).
45 | 3. **System Region set to "United States". System Language and Siri Language set to "English (US)". (Setting to unsupported regions will cause failure).**
46 | * *Note: Original Chinese guide mentions Chinese is supported, but for global users, stick to US settings for best compatibility.*
47 | 4. Stable internet connection to download the script.
48 | 5. SIP (System Integrity Protection) disabled. **(Can be re-enabled after patching, AI features will remain)**.
49 |
50 | ## Installation Steps
51 |
52 | Please follow these steps strictly:
53 |
54 | ### Step 1: Disable System Integrity Protection (SIP)
55 |
56 | If SIP is already disabled, skip this. If not:
57 |
58 | 1. **Restart your Mac**.
59 | 2. Hold the power button during startup until you see "Loading startup options" to enter macOS Recovery. (You may need to enter your password).
60 | 3. From the utilities menu bar at the top, select **Utilities** > **Terminal**.
61 | 4. Type the following command and press Enter:
62 | ```bash
63 | csrutil disable
64 | ```
65 | 5. Type `y` to confirm. You should see a message stating SIP is disabled.
66 | 6. Type `reboot` and press Enter to restart.
67 |
68 | ### Step 2: Download and Run the Script
69 |
70 | **Quick One-Line Command:**
71 |
72 | If you trust this script, run:
73 |
74 | **Latest v3.21 Script:**
75 |
76 | ```bash
77 | curl -sL https://raw.githubusercontent.com/kanshurichard/enableAppleAI/main/enable_ai.sh | bash
78 | ```
79 |
80 | **Alternative (if GitHub is slow):**
81 |
82 | ```bash
83 | curl -sL https://cdn.jsdelivr.net/gh/kanshurichard/enableAppleAI@main/enable_ai.sh | bash
84 | ```
85 |
86 | **Manual Execution:**
87 |
88 | 1. Open **Terminal**.
89 | 2. Download the script:
90 | ```bash
91 | curl -O https://raw.githubusercontent.com/kanshurichard/enableAppleAI/main/enable_ai.sh
92 | ```
93 | 3. **Review the script:** Check `enable_ai.sh` content to understand what it does.
94 | 4. Make it executable:
95 | ```bash
96 | chmod +x enable_ai.sh
97 | ```
98 | 5. Run it:
99 | ```bash
100 | ./enable_ai.sh
101 | ```
102 |
103 | ### Step 3: Follow Script Prompts
104 |
105 | 1. **Select Language**: Choose English.
106 | 2. **Select Operation**: Choose "Enable Apple Intelligence".
107 | 3. **Select Method**: Recommended to try **Method 1** first.
108 | 4. **Optional Step**: On macOS 16+ (macOS 26), you will be asked to Force US Location. **WARNING: Pair iPhone Mirroring BEFORE confirming this!**
109 | 5. **Restart**: Reboot your Mac after the script finishes.
110 | 6. **Check**: Go to System Settings -> Apple Intelligence & Siri to see if it's enabled.
111 | 7. **Restore SIP**: Once confirmed working, recommended to re-enable SIP via Recovery Mode (`csrutil enable`).
112 |
113 | ## Troubleshooting & Feedback
114 |
115 | * Check terminal output for errors during execution.
116 | * If Apple Intelligence fails to enable, try Method 2.
117 | * Submit issues on GitHub if problems persist.
118 |
119 | ## FAQ
120 |
121 | **Q: How to uninstall?**
122 | A: Run the script and select `2. Unlock Files (Uninstall)` from the main menu. This restores file permissions and removes the locks.
123 |
124 | **Q: Why do new AI features not appear after a system update (e.g., macOS 16/26)?**
125 | A: Please update the script to the latest version (v3.21+). New scripts include necessary updates for `countryd` which are crucial for features like ChatGPT. Recommended: Uninstall using old script -> Reboot -> Run new script.
126 |
127 | **Q: iPhone Mirroring connection failed?**
128 | A: If you used "Force US Location", your Mac and iPhone region codes might mismatch. **Fix**: Run script -> Uninstall -> Pair iPhone -> Run script again and enable AI (changing region afterwards won't break existing pairing).
129 |
130 | **Q: Siri still uses local search instead of ChatGPT?**
131 | A: Try "Method 2" or ensure you accepted "Force US Location" in "Method 1". This locks the location cache to US. (Requires US-compatible network IP).
132 |
133 | **Q: Image Playground cannot generate images?**
134 | A: Image Playground currently doesn't support all languages/regions. Try changing system language to English (US) temporarily.
135 |
136 | **Q: Can I enable it for unsupported languages?**
137 | A: No. If Apple hasn't released the language pack/support for it, forcing it won't work.
138 |
139 | ---
140 |
--------------------------------------------------------------------------------
/enable_ai_old.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | # --- Initial Welcome ---
6 | echo "==================================================================="
7 | echo " macOS Apple Intelligence Enablement Script 2.13 by KanShuRichard"
8 | echo " macOS Apple 智能启用辅助脚本 2.13 by KanShuRichard"
9 | echo "==================================================================="
10 |
11 | # --- Language Selection ---
12 | echo "Please select your language:"
13 | echo "请选择你的语言:"
14 | echo ""
15 | echo "1. 中文 (Chinese)"
16 | echo "2. English"
17 | echo ""
18 |
19 | # Use < /dev/tty to ensure reading from the terminal even if script is piped
20 | while true; do
21 | read -r -p "Enter choice/输入你的选择 (默认为中文): " lang_choice < /dev/tty
22 | case "$lang_choice" in
23 | 2)
24 | LANG="en"
25 | break # Exit the loop
26 | ;;
27 | *)
28 | LANG="zh"
29 | break # Exit the loop
30 | ;;
31 | esac
32 | done
33 |
34 | # --- End Language Selection ---
35 |
36 |
37 | # --- Language Settings ---
38 | # Declare variables for messages (these will be assigned based on the selected LANG)
39 | MSG_TITLE=""
40 | MSG_PLISTBUDDY_WARN=""
41 | MSG_PLISTBUDDY_ERROR=""
42 | MSG_SIP_CHECK=""
43 | MSG_SIP_ENABLED_1=""
44 | MSG_SIP_ENABLED_2=""
45 | MSG_SIP_ENABLED_3=""
46 | MSG_SIP_ENABLED_4_1=""
47 | MSG_SIP_ENABLED_4_2=""
48 | MSG_SIP_ENABLED_4_3=""
49 | MSG_SIP_ENABLED_4_4=""
50 | MSG_SIP_ENABLED_5=""
51 | MSG_SIP_DISABLED=""
52 | MSG_START_STEPS=""
53 | MSG_PREPARE_MODIFY=""
54 | MSG_UNLOCK_PERMS=""
55 | MSG_WRITE_PERMISSION_ERROR=""
56 | MSG_BACKUP_START=""
57 | MSG_BACKUP_ERROR=""
58 | MSG_BACKUP_COMPLETE=""
59 | MSG_MODIFY_PLIST_START_1="" # Message for modifying the first plist
60 | MSG_MODIFY_PLIST_START_2="" # Message for modifying the second plist
61 | MSG_MODIFY_PLISTS_COMPLETE="" # Message for modifying both plists complete
62 | MSG_EXECUTE_ZOUXIAN="" # Retained message for logical step
63 | MSG_CHECK_AI_TITLE=""
64 | MSG_CHECK_AI_INSTR_1=""
65 | MSG_CHECK_AI_INSTR_2=""
66 | MSG_CHECK_AI_INSTR_3=""
67 | MSG_CHECK_AI_PROMPT=""
68 | MSG_SUCCESS_CONFIRMED_START=""
69 | MSG_SET_PERMS_444=""
70 | MSG_SET_UCHG=""
71 | MSG_FILE_LOCK_COMPLETE=""
72 | MSG_CLEANUP_BACKUPS="" # Message for cleaning up both backups
73 | MSG_OPERATION_COMPLETE=""
74 | MSG_RESTART_NOW=""
75 | MSG_CHECK_AI_AGAIN=""
76 | MSG_RECOMMEND_RE_ENABLE_SIP=""
77 | MSG_FAILURE_CONFIRMED_START=""
78 | MSG_RESTORE_START_1="" # Message for restoring the first plist
79 | MSG_RESTORE_START_2="" # Message for restoring the second plist
80 | MSG_RESTORE_WARNING_FAILED=""
81 | MSG_RESTORE_WARNING_MANUAL=""
82 | MSG_RESTORE_COMPLETE=""
83 | MSG_RESTORE_WARNING_NOT_FOUND=""
84 | MSG_ENSURE_NO_UCHG=""
85 | MSG_FAILURE_CONSIDER_STEPS=""
86 | MSG_FAILURE_STEP_1=""
87 | MSG_FAILURE_STEP_2=""
88 | MSG_FAILURE_STEP_3=""
89 | MSG_SCRIPT_END=""
90 | MSG_DISCLAIMER=""
91 |
92 |
93 | # Assign messages based on the selected language
94 | case "$LANG" in
95 | en*)
96 | MSG_TITLE="macOS Apple Intelligence Enablement Script 2.0 by KanShuRichard"
97 | MSG_PLISTBUDDY_WARN="Warning: PlistBuddy tool ($PLISTBUDDY) not found. Attempting default path."
98 | MSG_PLISTBUDDY_ERROR="Error: PlistBuddy tool not found. Ensure macOS Developer Tools or Xcode is installed."
99 | MSG_SIP_CHECK="Checking System Integrity Protection (SIP) status..."
100 | MSG_SIP_ENABLED_1="SIP (System Integrity Protection) is currently enabled."
101 | MSG_SIP_ENABLED_2="SIP must be disabled to continue."
102 | MSG_SIP_ENABLED_3="Please follow these steps:"
103 | MSG_SIP_ENABLED_4_1="1. Restart your Mac and press and hold the power button to enter Recovery Mode."
104 | MSG_SIP_ENABLED_4_2="2. In Recovery Mode, select 'Utilities' -> 'Terminal' from the menu bar."
105 | MSG_SIP_ENABLED_4_3="3. In the Terminal, type 'csrutil disable' and press Enter."
106 | MSG_SIP_ENABLED_4_4="4. Type 'reboot' and press Enter to restart your Mac."
107 | MSG_SIP_ENABLED_5="After disabling SIP, please run this script again."
108 | MSG_SIP_DISABLED="SIP (System Integrity Protection) is disabled, proceeding."
109 | MSG_START_STEPS="Starting Apple Intelligence enablement attempt steps..."
110 | MSG_PREPARE_MODIFY="Preparing to modify system files..."
111 | MSG_UNLOCK_PERMS="Removing immutable (uchg) flag and setting permissions to 777 for files in system eligibility directories..."
112 | MSG_WRITE_PERMISSION_ERROR="Error: Failed to get write permission for a necessary plist file. Please confirm SIP is disabled."
113 | MSG_BACKUP_START="Backing up original file " # Will append filename
114 | MSG_BACKUP_ERROR="Error: Failed to successfully back up " # Will append filename
115 | MSG_BACKUP_COMPLETE="Backup complete."
116 | MSG_RESTART_ELIGIBILITY="Restarting eligibility daemon to provide any errors..."
117 | MSG_MODIFY_PLIST_START_1="Modifying keys in $ELIGIBILITY_PLIST ..."
118 | MSG_MODIFY_PLIST_START_2="Modifying key in $OS_ELIGIBILITY_PLIST ..."
119 | MSG_MODIFY_PLISTS_COMPLETE="All necessary plist modifications complete."
120 | MSG_EXECUTE_ZOUXIAN="Executing eligibility patch logic..." # Modified message
121 | MSG_CHECK_AI_TITLE="6. Check Apple Intelligence Status"
122 | MSG_CHECK_AI_INSTR_1="Important: Please go to 'System Settings' -> 'Apple Intelligence' or 'Siri' now and check if the 'Apple Intelligence' option appears."
123 | MSG_CHECK_AI_INSTR_2="If 'Apple Intelligence' **does appear**, or you see signs of AI features (even if the main option is hidden), please enter Y below."
124 | MSG_CHECK_AI_INSTR_3="If 'Apple Intelligence' **does not appear**, or no AI features are evident, please enter N to exit and report."
125 | MSG_CHECK_AI_PROMPT="Confirm if Apple Intelligence appeared or partial functionality is enabled (Y/N): "
126 | MSG_SUCCESS_CONFIRMED_START="User confirmed success, completing setup and locking files..."
127 | MSG_SET_PERMS_444="Setting permissions for eligibility files to 444 (read-only)..."
128 | MSG_SET_UCHG="Setting immutable (uchg) flag for eligibility files..."
129 | MSG_FILE_LOCK_COMPLETE="File locking complete."
130 | MSG_CLEANUP_BACKUPS="Cleaning up backup files..."
131 | MSG_OPERATION_COMPLETE="Operation completed."
132 | MSG_RESTART_NOW="Please restart your computer immediately."
133 | MSG_CHECK_AI_AGAIN="After restarting, check Apple Intelligence status again."
134 | MSG_RECOMMEND_RE_ENABLE_SIP="If Apple Intelligence remains enabled and you wish to restore system security, it is strongly recommended to enter Recovery Mode again and run 'csrutil enable' to re-enable SIP."
135 | MSG_FAILURE_CONFIRMED_START="User confirmed failure, restoring files to previous state..."
136 | MSG_RESTORE_START_1="Restoring original file $ELIGIBILITY_PLIST from backup file $PLIST_BACKUP ..."
137 | MSG_RESTORE_START_2="Restoring original file $OS_ELIGIBILITY_PLIST from backup file $OS_PLIST_BACKUP ..."
138 | MSG_RESTORE_WARNING_FAILED="Warning: Failed to restore " # Will append filename
139 | MSG_RESTORE_WARNING_MANUAL="Manual intervention may be required!"
140 | MSG_RESTORE_COMPLETE=" restore complete." # Prepended by filename
141 | MSG_RESTORE_WARNING_NOT_FOUND="Warning: Backup file " # Will append filename
142 | MSG_ENSURE_NO_UCHG="Ensuring uchg flag is removed..."
143 | MSG_FAILURE_CONSIDER_STEPS="Apple Intelligence enablement attempt failed. Please consider the following steps:"
144 | MSG_FAILURE_STEP_1="1. Check your macOS version compatibility (currently tested with 15.4.1 and 15.5 beta)."
145 | MSG_FAILURE_STEP_2="2. Report the issue to the relevant community/repository." # Modified to be generic
146 | MSG_FAILURE_STEP_3="3. For system security, it is strongly recommended to restart and enter Recovery Mode again and run 'csrutil enable' to re-enable SIP."
147 | MSG_SCRIPT_END="Script execution finished."
148 | MSG_DISCLAIMER="Disclaimer: This script modifies system files and may cause instability or unexpected behavior. Use at your own risk."
149 | ;;
150 | *) # Default to Chinese
151 | MSG_TITLE="macOS Apple Intelligence 启用辅助脚本 2.0 by KanShuRichard"
152 | MSG_PLISTBUDDY_WARN="警告:找不到 PlistBuddy 工具 ($PLISTBUDDY)。尝试使用默认路径。"
153 | MSG_PLISTBUDDY_ERROR="错误:找不到 PlistBuddy 工具。请确保已安装 macOS 开发者工具或 Xcode。"
154 | MSG_SIP_CHECK="正在检测 System Integrity Protection (SIP) 状态..."
155 | MSG_SIP_ENABLED_1="SIP (System Integrity Protection) 当前已启用。"
156 | MSG_SIP_ENABLED_2="必须禁用 SIP 才能继续。"
157 | MSG_SIP_ENABLED_3="请按照以下步骤操作:"
158 | MSG_SIP_ENABLED_4_1="1. 重启 Mac,并长按开机键进入恢复模式。"
159 | MSG_SIP_ENABLED_4_2="2. 在恢复模式菜单栏中选择 '实用工具' -> '终端'。"
160 | MSG_SIP_ENABLED_4_3="3. 在终端中输入 'csrutil disable' 并按回车。"
161 | MSG_SIP_ENABLED_4_4="4. 输入 'reboot' 并按回车重启 Mac。"
162 | MSG_SIP_ENABLED_5="SIP 禁用后,请再次运行此脚本。"
163 | MSG_SIP_DISABLED="SIP (System Integrity Protection) 已禁用,可以继续。"
164 | MSG_START_STEPS="开始执行 Apple Intelligence 启用尝试步骤..."
165 | MSG_PREPARE_MODIFY="正在准备修改系统文件..."
166 | MSG_UNLOCK_PERMS="正在删除 /private/var/db/eligibilityd/ 和 /private/var/db/os_eligibility/ 目录下文件的 immutable (uchg) 标记并设置权限为 777..."
167 | MSG_WRITE_PERMISSION_ERROR="错误:未能获得必要的 plist 文件的写入权限。请再次确认已禁用 SIP。"
168 | MSG_BACKUP_START="正在备份原始文件 "
169 | MSG_BACKUP_ERROR="错误:未能成功备份 "
170 | MSG_BACKUP_COMPLETE="备份完成。"
171 | MSG_RESTART_ELIGIBILITY="正在重启eligibility守护进程,以避免出错..."
172 | MSG_MODIFY_PLIST_START_1="正在修改 $ELIGIBILITY_PLIST 中的特定键值..."
173 | MSG_MODIFY_PLIST_START_2="正在修改 $OS_ELIGIBILITY_PLIST 中的特定键值..."
174 | MSG_MODIFY_PLISTS_COMPLETE="所有必要的 plist 文件修改完成。"
175 | MSG_EXECUTE_ZOUXIAN="执行资格修补逻辑..." # Modified message
176 | MSG_CHECK_AI_TITLE="6. 请检查 Apple 智能状态"
177 | MSG_CHECK_AI_INSTR_1="重要:现在请去 '系统设置' -> 'Apple 智能' 或 'Siri' 检查'Apple智能'选项是否已经出现。"
178 | MSG_CHECK_AI_INSTR_2="如果 'Apple 智能' **已经出现**,或者你发现 Siri/Spotlight 已经具备 Apple 智能的某些功能(即使入口没出现),请在下面输入 Y。"
179 | MSG_CHECK_AI_INSTR_3="如果 'Apple 智能' **没有出现**,或者没有任何迹象表明功能已启用,请在下面输入 N。"
180 | MSG_CHECK_AI_PROMPT="请确认 Apple 智能是否已出现或部分功能已启用 (Y/N): "
181 | MSG_SUCCESS_CONFIRMED_START="用户确认成功,正在完成设置并锁定文件..."
182 | MSG_SET_PERMS_444="设置 eligibility 文件权限为 444 (只读)..."
183 | MSG_SET_UCHG="设置 eligibility 文件的 immutable (uchg) 标记..."
184 | MSG_FILE_LOCK_COMPLETE="文件锁定完成。"
185 | MSG_CLEANUP_BACKUPS="清理备份文件..."
186 | MSG_OPERATION_COMPLETE="操作已完成。"
187 | MSG_RESTART_NOW="请立即重启你的电脑。"
188 | MSG_CHECK_AI_AGAIN="重启后,再次检查 Apple 智能状态。"
189 | MSG_RECOMMEND_RE_ENABLE_SIP="如果 Apple 智能仍为开启,并且你希望恢复系统的安全性,强烈建议你再次进入恢复模式,执行 'csrutil enable' 重新打开 SIP。"
190 | MSG_FAILURE_CONFIRMED_START="用户确认失败,正在恢复文件到修改前状态..."
191 | MSG_RESTORE_START_1="正在从备份文件 $PLIST_BACKUP 恢复原始文件 $ELIGIBILITY_PLIST ..."
192 | MSG_RESTORE_START_2="正在从备份文件 $OS_PLIST_BACKUP 恢复原始文件 $OS_ELIGIBILITY_PLIST ..."
193 | MSG_RESTORE_WARNING_FAILED="警告:未能从备份文件恢复 "
194 | MSG_RESTORE_WARNING_MANUAL="可能需要手动恢复!"
195 | MSG_RESTORE_COMPLETE=" 恢复完成。"
196 | MSG_RESTORE_WARNING_NOT_FOUND="警告:备份文件 "
197 | MSG_ENSURE_NO_UCHG="确保没有uchg标记..."
198 | MSG_FAILURE_CONSIDER_STEPS="Apple 智能启用尝试失败。请考虑以下步骤:"
199 | MSG_FAILURE_STEP_1="1. 检查你的 macOS 版本是否兼容 (目前已测试15.4.1和15.5 beta)。"
200 | MSG_FAILURE_STEP_2="2. 向相关社区/仓库反馈问题。" # Modified to be generic
201 | MSG_FAILURE_STEP_3="3. 为了系统安全,强烈建议你重启后进入恢复模式,执行 'csrutil enable' 重新打开 SIP。"
202 | MSG_SCRIPT_END="脚本执行结束。"
203 | MSG_DISCLAIMER="免责声明:此脚本修改系统文件,可能导致不稳定或意外行为。请自行承担风险。"
204 | ;;
205 | esac
206 |
207 | # --- End Language Settings ---
208 |
209 |
210 | # Define key file and directory paths
211 | ELIGIBILITY_PLIST="/private/var/db/eligibilityd/eligibility.plist"
212 | ELIGIBILITY_DIR="/private/var/db/eligibilityd"
213 | PLIST_BACKUP="/tmp/eligibility.plist.bak" # Backup file path
214 |
215 | OS_ELIGIBILITY_PLIST="/private/var/db/os_eligibility/eligibility.plist" # Second plist path
216 | OS_ELIGIBILITY_DIR="/private/var/db/os_eligibility" # Second plist directory
217 | OS_PLIST_BACKUP="/tmp/os_eligibility.plist.bak" # Second backup file path
218 |
219 |
220 | PLISTBUDDY="/usr/libexec/PlistBuddy" # PlistBuddy tool path
221 |
222 | # Check if PlistBuddy exists
223 | if [ ! -f "$PLISTBUDDY" ]; then
224 | echo "$MSG_PLISTBUDDY_WARN"
225 | PLISTBUDDY="PlistBuddy"
226 | # Re-check if default path is available
227 | if ! command -v "$PLISTBUDDY" &> /dev/null; then
228 | echo "$MSG_PLISTBUDDY_ERROR"
229 | exit 1 # Exit if PlistBuddy is not found
230 | fi
231 | fi
232 |
233 |
234 | # 1. Check SIP status
235 | echo "$MSG_SIP_CHECK"
236 | sip_status=$(csrutil status)
237 |
238 | if [[ $sip_status != *"System Integrity Protection status: disabled"* ]]; then
239 | echo "$MSG_SIP_ENABLED_1"
240 | echo "$MSG_SIP_ENABLED_2"
241 | echo "$MSG_SIP_ENABLED_3"
242 | echo "$MSG_SIP_ENABLED_4_1"
243 | echo "$MSG_SIP_ENABLED_4_2"
244 | echo "$MSG_SIP_ENABLED_4_3"
245 | echo "$MSG_SIP_ENABLED_4_4"
246 | echo "$MSG_SIP_ENABLED_5"
247 | echo "=============================================="
248 | exit 1 # Exit if SIP is enabled
249 | else
250 | echo "$MSG_SIP_DISABLED"
251 | fi
252 |
253 | echo ""
254 | echo "=============================================="
255 | echo "$MSG_START_STEPS"
256 |
257 | # --- Prepare to modify files ---
258 | echo "$MSG_PREPARE_MODIFY"
259 |
260 | # 2. Unlock and set file permissions to 777 for both directories
261 | echo "$MSG_UNLOCK_PERMS"
262 | # Remove uchg flag (ignore errors as file might not have the flag) for both
263 | sudo chflags nouchg "$ELIGIBILITY_DIR"/* "$OS_ELIGIBILITY_DIR"/* || true
264 | # Set permissions to 777 for both
265 | sudo chmod 777 "$ELIGIBILITY_DIR"/* "$OS_ELIGIBILITY_DIR"/*
266 |
267 | # Ensure both plist files are writable
268 | if [ ! -w "$ELIGIBILITY_PLIST" ] || [ ! -w "$OS_ELIGIBILITY_PLIST" ]; then
269 | echo "$MSG_WRITE_PERMISSION_ERROR"
270 | exit 1 # Exit if write permission is not obtained
271 | fi
272 |
273 | # 3. Backup original plist files
274 | echo "$MSG_BACKUP_START$ELIGIBILITY_PLIST to $PLIST_BACKUP ..."
275 | sudo cp "$ELIGIBILITY_PLIST" "$PLIST_BACKUP"
276 | if [ $? -ne 0 ]; then
277 | echo "$MSG_BACKUP_ERROR$ELIGIBILITY_PLIST file. $MSG_RESTORE_WARNING_MANUAL"
278 | exit 1 # Failure to backup is critical, must exit
279 | fi
280 |
281 | echo "$MSG_BACKUP_START$OS_ELIGIBILITY_PLIST to $OS_PLIST_BACKUP ..."
282 | sudo cp "$OS_ELIGIBILITY_PLIST" "$OS_PLIST_BACKUP"
283 | if [ $? -ne 0 ]; then
284 | echo "$MSG_BACKUP_ERROR$OS_ELIGIBILITY_PLIST file. $MSG_RESTORE_WARNING_MANUAL"
285 | # Clean up the first backup if the second one fails
286 | sudo rm -f "$PLIST_BACKUP"
287 | exit 1 # Failure to backup is critical, must exit
288 | fi
289 | echo "$MSG_BACKUP_COMPLETE"
290 |
291 | # 4. Modify plist file contents
292 | echo "$MSG_MODIFY_PLIST_START_1"
293 | # Use PlistBuddy to set values (change 3 to 2) in the first plist
294 | # Note: PlistBuddy path checked/set at the beginning of the script
295 |
296 | # Modify values under OS_ELIGIBILITY_DOMAIN_GREYMATTER
297 | # Add || true to prevent script exit if the key does not exist
298 | sudo "$PLISTBUDDY" -c "Set :OS_ELIGIBILITY_DOMAIN_GREYMATTER:status:OS_ELIGIBILITY_INPUT_COUNTRY_BILLING 2" "$ELIGIBILITY_PLIST" || true
299 | sudo "$PLISTBUDDY" -c "Set :OS_ELIGIBILITY_DOMAIN_GREYMATTER:status:OS_ELIGIBILITY_INPUT_DEVICE_AND_SIRI_LANGUAGE_MATCH 2" "$ELIGIBILITY_PLIST" || true
300 | sudo "$PLISTBUDDY" -c "Set :OS_ELIGIBILITY_DOMAIN_GREYMATTER:status:OS_ELIGIBILITY_INPUT_DEVICE_REGION_CODE 2" "$ELIGIBILITY_PLIST" || true
301 | sudo "$PLISTBUDDY" -c "Set :OS_ELIGIBILITY_DOMAIN_GREYMATTER:status:OS_ELIGIBILITY_INPUT_EXTERNAL_BOOT_DRIVE 2" "$ELIGIBILITY_PLIST" || true
302 |
303 | # Modify values under OS_ELIGIBILITY_DOMAIN_CALCIUM
304 | # Add || true
305 | sudo "$PLISTBUDDY" -c "Set :OS_ELIGIBILITY_DOMAIN_CALCIUM:status:OS_ELIGIBILITY_INPUT_DEVICE_REGION_CODE 2" "$ELIGIBILITY_PLIST" || true
306 |
307 | echo "$MSG_MODIFY_PLIST_START_2"
308 | # Use PlistBuddy to set the value in the second plist
309 | # Add || true
310 | sudo "$PLISTBUDDY" -c "Set :OS_ELIGIBILITY_DOMAIN_STRONTIUM:os_eligibility_answer_t 4" "$OS_ELIGIBILITY_PLIST" || true
311 |
312 | echo "$MSG_MODIFY_PLISTS_COMPLETE"
313 |
314 |
315 | # 5. Execute eligibility patch logic (replaces zouxian execution)
316 | echo "$MSG_EXECUTE_ZOUXIAN" # Use the updated message
317 |
318 | # Original Author: CatMe0w
319 | # Source: https://github.com/CatMe0w/zouxian/blob/master/zouxian.sh
320 | # This embedded script logic waits for eligibilityd and patches it using lldb.
321 | MAX_WAIT_TIME=60
322 | CHECK_INTERVAL=1
323 | SECONDS_PASSED=0
324 | PROCESS_FOUND=0 # Flag to indicate if eligibilityd was found (0=not found, 1=found)
325 |
326 | # Restart Eligility Engine
327 | echo "$MSG_RESTART_ELIGIBILITY"
328 | # Stop eligibilityd to ensure it can be patched
329 | # Use sudo to ensure we have the necessary permissions
330 | sudo launchctl stop com.apple.eligibilityd
331 | sleep 0.5 # Wait for a few seconds to ensure eligibilityd has stopped
332 | # Start eligibilityd again to ensure it is running before we attempt to attach
333 | sudo launchctl start com.apple.eligibilityd
334 | # Wait for eligibilityd to start and then patch it
335 |
336 | while [ $SECONDS_PASSED -lt $MAX_WAIT_TIME ]; do
337 | PID=$(pgrep eligibilityd)
338 | if [ ! -z "$PID" ]; then
339 | echo "eligibilityd found with PID $PID"
340 | PROCESS_FOUND=1 # Mark that the process was found
341 | # Use sudo for lldb as it needs elevated privileges to attach to system processes
342 | # set -e will cause the script to exit if the sudo lldb command itself fails critically.
343 | sudo -E "$(xcrun --find lldb)" --batch \
344 | -o "process attach --name eligibilityd" \
345 | -o "expression (void) [[[InputManager sharedInstance] objectForInputValue:6] setValue:@\"LL\" forKey:@\"_deviceRegionCode\"]" \
346 | -o "expression (void) [[EligibilityEngine sharedInstance] recomputeAllDomainAnswers]" \
347 | -o "process detach" \
348 | -o quit
349 |
350 | # If we reach here, the lldb command itself completed (set -e didn't trigger).
351 | # Even if lldb exited with a non-zero status for non-critical reasons,
352 | # the attempt was made. We can now break the waiting loop.
353 | break # Exit the while loop after attempting the lldb patch
354 | fi
355 | sleep $CHECK_INTERVAL
356 | SECONDS_PASSED=$((SECONDS_PASSED + CHECK_INTERVAL))
357 | done
358 |
359 | # Check if the loop finished because it timed out (eligibilityd not found)
360 | if [ "$PROCESS_FOUND" -ne 1 ]; then
361 | echo "eligibilityd not found after $MAX_WAIT_TIME seconds"
362 | exit 1 # Exit the entire script if eligibilityd was never found within the timeout
363 | fi
364 |
365 | # If we reach this point, it means eligibilityd was found, and the lldb command was attempted.
366 | # The script will now continue to the next logical step (Step 6), where the user confirms success.
367 |
368 | # End of embedded eligibility patch logic
369 |
370 |
371 | echo ""
372 | echo "=============================================="
373 | echo "$MSG_CHECK_AI_TITLE"
374 | echo "$MSG_CHECK_AI_INSTR_1"
375 | echo "$MSG_CHECK_AI_INSTR_2"
376 | echo "$MSG_CHECK_AI_INSTR_3"
377 | echo "=============================================="
378 |
379 | # Use < /dev/tty to force reading input from the terminal, fixing the issue with read not pausing when executed via pipe
380 | read -r -p "$MSG_CHECK_AI_PROMPT" user_confirmation < /dev/tty
381 |
382 | # 7. Process based on user confirmation
383 | if [[ "$user_confirmation" =~ ^[Yy]$ ]]; then
384 | # --- User confirmed success path ---
385 | echo ""
386 | echo "=============================================="
387 | echo "$MSG_SUCCESS_CONFIRMED_START"
388 |
389 | # Set file permissions to 444 (read-only) for both directories
390 | echo "$MSG_SET_PERMS_444"
391 | sudo chmod 444 "$ELIGIBILITY_DIR"/* "$OS_ELIGIBILITY_DIR"/*
392 |
393 | # Set immutable (uchg) flag for both directories
394 | echo "$MSG_SET_UCHG"
395 | sudo chflags uchg "$ELIGIBILITY_DIR"/* "$OS_ELIGIBILITY_DIR"/*
396 | echo "$MSG_FILE_LOCK_COMPLETE"
397 |
398 | # Clean up backup files
399 | echo "$MSG_CLEANUP_BACKUPS"
400 | sudo rm -f "$PLIST_BACKUP" "$OS_PLIST_BACKUP" # Use -f to ignore errors if files don't exist
401 |
402 | echo ""
403 | echo "$MSG_OPERATION_COMPLETE"
404 | echo "$MSG_RESTART_NOW"
405 | echo "$MSG_CHECK_AI_AGAIN"
406 | echo "$MSG_RECOMMEND_RE_ENABLE_SIP"
407 | echo "=============================================="
408 |
409 | else
410 | # --- User confirmed failure path ---
411 | echo ""
412 | echo "=============================================="
413 | echo "$MSG_FAILURE_CONFIRMED_START"
414 |
415 | # Restore original plist files
416 | # Restore the first plist
417 | if [ -f "$PLIST_BACKUP" ]; then
418 | echo "$MSG_RESTORE_START_1"
419 | sudo rm -f "$ELIGIBILITY_PLIST"
420 | sudo cp "$PLIST_BACKUP" "$ELIGIBILITY_PLIST"
421 | if [ $? -ne 0 ]; then
422 | echo "$MSG_RESTORE_WARNING_FAILED$ELIGIBILITY_PLIST. $MSG_RESTORE_WARNING_MANUAL"
423 | else
424 | echo "$ELIGIBILITY_PLIST$MSG_RESTORE_COMPLETE"
425 | fi
426 | else
427 | echo "$MSG_RESTORE_WARNING_NOT_FOUND$PLIST_BACKUP. Cannot restore $ELIGIBILITY_PLIST file content."
428 | fi
429 |
430 | # Restore the second plist
431 | if [ -f "$OS_PLIST_BACKUP" ]; then
432 | echo "$MSG_RESTORE_START_2"
433 | sudo rm -f "$OS_ELIGIBILITY_PLIST"
434 | sudo cp "$OS_PLIST_BACKUP" "$OS_ELIGIBILITY_PLIST"
435 | if [ $? -ne 0 ]; then
436 | echo "$MSG_RESTORE_WARNING_FAILED$OS_ELIGIBILITY_PLIST. $MSG_RESTORE_WARNING_MANUAL"
437 | else
438 | echo "$OS_ELIGIBILITY_PLIST$MSG_RESTORE_COMPLETE"
439 | fi
440 | else
441 | echo "$MSG_RESTORE_WARNING_NOT_FOUND$OS_PLIST_BACKUP. Cannot restore $OS_ELIGIBILITY_PLIST file content."
442 | fi
443 |
444 |
445 | # Restore file permissions to 444 (read-only, a safe default state) for both directories
446 | echo "$MSG_SET_PERMS_444"
447 | sudo chmod 444 "$ELIGIBILITY_DIR"/* "$OS_ELIGIBILITY_DIR"/*
448 |
449 | # Ensure uchg flag is removed (in case it was set during a previous failed attempt) for both directories
450 | echo "$MSG_ENSURE_NO_UCHG"
451 | sudo chflags nouchg "$ELIGIBILITY_DIR"/* "$OS_ELIGIBILITY_DIR"/* || true
452 |
453 | # Clean up backup files
454 | echo "$MSG_CLEANUP_BACKUPS"
455 | sudo rm -f "$PLIST_BACKUP" "$OS_PLIST_BACKUP" # Use -f to ignore errors if files don't exist
456 |
457 | echo ""
458 | echo "$MSG_FAILURE_CONSIDER_STEPS"
459 | echo "$MSG_FAILURE_STEP_1"
460 | echo "$MSG_FAILURE_STEP_2"
461 | echo "$MSG_FAILURE_STEP_3"
462 | echo "=============================================="
463 |
464 | fi
465 |
466 |
467 | echo ""
468 | echo "=============================================="
469 | echo "$MSG_SCRIPT_END"
470 | echo "$MSG_DISCLAIMER"
471 | echo "=============================================="
472 |
473 | exit 0
474 |
--------------------------------------------------------------------------------
/enable_ai.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | # --- Colors ---
6 | BOLD="\033[1m"
7 | RED="\033[31m"
8 | GREEN="\033[32m"
9 | YELLOW="\033[33m"
10 | BLUE="\033[34m"
11 | CYAN="\033[36m"
12 | RESET="\033[0m"
13 |
14 | # --- Initial Welcome ---
15 | echo -e "${BLUE}===================================================================${RESET}"
16 | echo -e "${BOLD}${CYAN} macOS Apple Intelligence Enablement Script 3.21 by KanShuRichard${RESET}"
17 | echo -e "${BOLD}${CYAN} macOS Apple 智能启用辅助脚本 3.21 by KanShuRichard${RESET}"
18 | echo -e "${BLUE}===================================================================${RESET}"
19 | #!/bin/bash
20 |
21 | # --- Language Selection ---
22 | echo -e "${BOLD}Please select your language:${RESET}"
23 | echo -e "${BOLD}请选择你的语言:${RESET}"
24 | echo ""
25 | echo "1. 中文 (Chinese)"
26 | echo "2. English"
27 | echo ""
28 |
29 | # Use < /dev/tty to ensure reading from the terminal even if script is piped
30 | while true; do
31 | read -r -p "Enter choice/输入你的选择 (默认为中文): " lang_choice < /dev/tty
32 | case "$lang_choice" in
33 | 2)
34 | LANG="en"
35 | break # Exit the loop
36 | ;;
37 | *)
38 | LANG="zh"
39 | break # Exit the loop
40 | ;;
41 | esac
42 | done
43 |
44 | # --- End Language Settings ---
45 |
46 |
47 | # --- Language Settings ---
48 | # (Message variables remain the same as v4.1, only code logic is changed)
49 | # ... (Message definitions are omitted for brevity but are identical to the previous version)
50 | # Declare variables for messages
51 | # (Shared messages)
52 | MSG_SUDO_REQUIRED=""
53 | MSG_SUDO_PROMPT=""
54 | MSG_SUDO_SUCCESS=""
55 | MSG_SUDO_FAILED=""
56 | MSG_AGREEMENT_TITLE=""
57 | MSG_AGREEMENT_LINE1=""
58 | MSG_AGREEMENT_LINE2=""
59 | MSG_AGREEMENT_LINE3=""
60 | MSG_AGREEMENT_PROMPT=""
61 | MSG_AGREEMENT_CANCEL=""
62 | MSG_MODE_SELECT_TITLE=""
63 | MSG_MODE_SELECT_1=""
64 | MSG_MODE_SELECT_2=""
65 | MSG_MODE_SELECT_3=""
66 | MSG_MODE_PROMPT=""
67 | MSG_SUB_MENU_TITLE=""
68 | MSG_SUB_MENU_M1=""
69 | MSG_SUB_MENU_M1_DESC=""
70 | MSG_SUB_MENU_M2=""
71 | MSG_SUB_MENU_M2_DESC=""
72 | MSG_SUB_MENU_M3=""
73 | MSG_INVALID_MODE=""
74 | MSG_EXITING=""
75 | MSG_PLISTBUDDY_WARN=""
76 | MSG_PLISTBUDDY_ERROR=""
77 | MSG_SIP_CHECK=""
78 | MSG_SIP_ENABLED_1=""
79 | MSG_SIP_ENABLED_2=""
80 | MSG_SIP_ENABLED_3=""
81 | MSG_SIP_ENABLED_4_1=""
82 | MSG_SIP_ENABLED_4_2=""
83 | MSG_SIP_ENABLED_4_3=""
84 | MSG_SIP_ENABLED_4_4=""
85 | MSG_SIP_ENABLED_5=""
86 | MSG_SIP_DISABLED=""
87 | MSG_WRITE_PERMISSION_ERROR=""
88 | MSG_BACKUP_START=""
89 | MSG_BACKUP_ERROR=""
90 | MSG_BACKUP_COMPLETE=""
91 | MSG_FINALIZE_START=""
92 | MSG_SET_PERMS_444=""
93 | MSG_SET_UCHG=""
94 | MSG_FILE_LOCK_COMPLETE=""
95 | MSG_CLEANUP_BACKUPS=""
96 | MSG_RESTART_NOW=""
97 | MSG_RECOMMEND_RE_ENABLE_SIP=""
98 | MSG_UNLOCK_START=""
99 | MSG_UNLOCK_NOUCHG=""
100 | MSG_UNLOCK_CHMOD=""
101 | MSG_UNLOCK_COMPLETE=""
102 | MSG_SCRIPT_END=""
103 | MSG_SUPPORT_URL=""
104 | MSG_M1_FAIL_TRY_M2_PROMPT=""
105 |
106 | # (Method 2 specific messages)
107 | MSG2_START_STEPS=""
108 | MSG2_MODIFY_PLISTS_START=""
109 | MSG2_MODIFY_PLISTS_COMPLETE=""
110 | MSG2_OPERATION_COMPLETE=""
111 | MSG2_FORCE_US_PROMPT_TITLE=""
112 | MSG2_FORCE_US_PROMPT_BENEFITS=""
113 | MSG2_FORCE_US_PROMPT_WARNING=""
114 | MSG2_FORCE_US_PROMPT_CONFIRM=""
115 | MSG2_FORCE_US_START=""
116 | MSG2_FORCE_US_UNLOCKING=""
117 | MSG2_FORCE_US_BACKUP=""
118 | MSG2_FORCE_US_CONVERT_XML=""
119 | MSG2_FORCE_US_REPLACE=""
120 | MSG2_FORCE_US_CONVERT_BIN=""
121 | MSG2_FORCE_US_LOCKING=""
122 | MSG2_FORCE_US_LOCK_COMPLETE=""
123 | MSG2_FORCE_US_SUCCESS=""
124 | MSG2_FORCE_US_NOT_FOUND=""
125 | MSG2_UNLOCK_IPHONE_WARNING_TITLE=""
126 | MSG2_UNLOCK_IPHONE_WARNING_1=""
127 | MSG2_UNLOCK_IPHONE_WARNING_2=""
128 |
129 | # (Method 1 specific messages, prefixed with M1_)
130 | M1_START_STEPS=""
131 | M1_PREPARE_MODIFY=""
132 | M1_UNLOCK_PERMS=""
133 | M1_MODIFY_PLIST_START_1=""
134 | M1_MODIFY_PLIST_START_2=""
135 | M1_MODIFY_PLISTS_COMPLETE=""
136 | M1_EXECUTE_ZOUXIAN=""
137 | M1_RESTART_ELIGIBILITY=""
138 | M1_CHECK_AI_TITLE=""
139 | M1_CHECK_AI_INSTR_1=""
140 | M1_CHECK_AI_INSTR_2=""
141 | M1_CHECK_AI_INSTR_3=""
142 | M1_CHECK_AI_PROMPT=""
143 | M1_SUCCESS_CONFIRMED_START=""
144 | M1_OPERATION_COMPLETE=""
145 | M1_CHECK_AI_AGAIN=""
146 | M1_FAILURE_CONFIRMED_START=""
147 | M1_RESTORE_START_1=""
148 | M1_RESTORE_START_2=""
149 | M1_RESTORE_WARNING_FAILED=""
150 | M1_RESTORE_WARNING_MANUAL=""
151 | M1_RESTORE_COMPLETE=""
152 | M1_RESTORE_WARNING_NOT_FOUND=""
153 | M1_ENSURE_NO_UCHG=""
154 | M1_DISCLAIMER=""
155 |
156 | # Assign messages based on the selected language
157 | case "$LANG" in
158 | en*)
159 | # Shared
160 | MSG_SUDO_REQUIRED="${YELLOW}Administrator privileges are required for this operation.${RESET}"
161 | MSG_SUDO_PROMPT="Please enter your password to grant permissions: "
162 | MSG_SUDO_SUCCESS="${GREEN}Privileges granted. Continuing...${RESET}"
163 | MSG_SUDO_FAILED="${BOLD}${RED}Failed to obtain administrator privileges. Exiting.${RESET}"
164 | MSG_AGREEMENT_TITLE="${BOLD}${YELLOW}--- IMPORTANT: PLEASE READ BEFORE PROCEEDING ---${RESET}"
165 | MSG_AGREEMENT_LINE1="${BOLD}${YELLOW}[RISK]${RESET} This script modifies core system files. Incorrect use could potentially lead to system instability."
166 | MSG_AGREEMENT_LINE2="${BOLD}${YELLOW}[REQUIREMENT]${RESET} You MUST disable System Integrity Protection (SIP) from Recovery Mode before running the patch."
167 | MSG_AGREEMENT_LINE3="${BOLD}${YELLOW}[DISCLAIMER]${RESET} All operations are performed at your own risk."
168 | MSG_AGREEMENT_PROMPT="${BOLD}Do you understand the risks and wish to continue? (y/n): ${RESET}"
169 | MSG_AGREEMENT_CANCEL="Operation cancelled by user. Exiting."
170 | MSG_MODE_SELECT_TITLE="${BOLD}Please select an operation:${RESET}"
171 | MSG_MODE_SELECT_1="1. Enable Apple Intelligence"
172 | MSG_MODE_SELECT_2="2. Unlock Files (Uninstall)"
173 | MSG_MODE_SELECT_3="3. Exit"
174 | MSG_MODE_PROMPT="${BOLD}Enter your choice [1-3]: ${RESET}"
175 | MSG_SUB_MENU_TITLE="${BOLD}Please choose an enablement method:${RESET}"
176 | MSG_SUB_MENU_M1="1. Method 1 (Simulate US Model Code)"
177 | MSG_SUB_MENU_M1_DESC=" ${CYAN}More comprehensive. Recommended to try first.${RESET}"
178 | MSG_SUB_MENU_M2="2. Method 2 (Directly Force-Enable Features)"
179 | MSG_SUB_MENU_M2_DESC=" ${CYAN}If Method 1 fails, it is recommended to try Method 2.${RESET}"
180 | MSG_SUB_MENU_M3="3. Back to Main Menu"
181 | MSG_INVALID_MODE="${BOLD}${RED}Invalid choice. Exiting.${RESET}"
182 | MSG_EXITING="Exiting script."
183 | MSG_PLISTBUDDY_WARN="${YELLOW}Warning: PlistBuddy tool not found. Attempting default path.${RESET}"
184 | MSG_PLISTBUDDY_ERROR="${BOLD}${RED}Error: PlistBuddy tool not found. Ensure Xcode Command Line Tools are installed.${RESET}"
185 | MSG_SIP_CHECK="Checking System Integrity Protection (SIP) status..."
186 | MSG_SIP_ENABLED_1="${BOLD}${RED}SIP (System Integrity Protection) is currently enabled.${RESET}"
187 | MSG_SIP_ENABLED_2="${BOLD}${RED}SIP must be disabled for this operation to continue.${RESET}"
188 | MSG_SIP_ENABLED_3="Please follow these steps:"
189 | MSG_SIP_ENABLED_4_3="3. In the Terminal, type '${BOLD}${CYAN}csrutil disable${RESET}' and press Enter."
190 | MSG_SIP_ENABLED_4_4="4. Type '${BOLD}${CYAN}reboot${RESET}' and press Enter to restart your Mac."
191 | MSG_SIP_ENABLED_5="After disabling SIP, please run this script again."
192 | MSG_SIP_DISABLED="${GREEN}SIP (System Integrity Protection) is disabled, proceeding.${RESET}"
193 | MSG_WRITE_PERMISSION_ERROR="${BOLD}${RED}Error: Failed to get write permission. Please ensure SIP is disabled.${RESET}"
194 | MSG_BACKUP_START="Backing up original file "
195 | MSG_BACKUP_ERROR="${BOLD}${RED}Error: Failed to back up ${RESET}"
196 | MSG_BACKUP_COMPLETE="${GREEN}Backup complete.${RESET}"
197 | MSG_FINALIZE_START="Finalizing and locking files..."
198 | MSG_SET_PERMS_444="Setting permissions to read-only (444)..."
199 | MSG_SET_UCHG="Setting immutable (uchg) flag to prevent changes..."
200 | MSG_FILE_LOCK_COMPLETE="File locking complete."
201 | MSG_CLEANUP_BACKUPS="Cleaning up backup files..."
202 | MSG_RESTART_NOW="${BOLD}${YELLOW}A REBOOT IS REQUIRED for all changes to take effect. Please restart your Mac now.${RESET}"
203 | MSG_RECOMMEND_RE_ENABLE_SIP="After restarting, it is strongly recommended to re-enable SIP for system security."
204 | MSG_UNLOCK_START="Starting file unlock process (revert/uninstall)..."
205 | MSG_UNLOCK_NOUCHG="Removing immutable (uchg) flag from all related directories..."
206 | MSG_UNLOCK_CHMOD="Setting file permissions to default (644)..."
207 | MSG_UNLOCK_COMPLETE="${GREEN}All related files (eligibility and countryd) have been unlocked.${RESET}"
208 | MSG_SCRIPT_END="Script execution finished."
209 | MSG_SUPPORT_URL="If you encounter any issues, please submit an Issue at ${BOLD}https://github.com/kanshurichard/enableAppleAI${RESET}"
210 | MSG_M1_FAIL_TRY_M2_PROMPT="${BOLD}Method 1 failed. Would you like to try Method 2 now? (y/n): ${RESET}"
211 |
212 | # Method 2 specific
213 | MSG2_START_STEPS="Starting Apple Intelligence enablement steps..."
214 | MSG2_MODIFY_PLISTS_START="Patching eligibility plists (this may take a moment)..."
215 | MSG2_MODIFY_PLISTS_COMPLETE="${GREEN}Plist modifications complete.${RESET}"
216 | MSG2_OPERATION_COMPLETE="${GREEN}Apple Intelligence patch applied successfully.${RESET}"
217 | MSG2_FORCE_US_PROMPT_TITLE="${CYAN}--- Optional Step: Force Location to US ---${RESET}"
218 | MSG2_FORCE_US_PROMPT_BENEFITS="${BOLD}${YELLOW}[Benefits]${RESET} For macOS 26, this can unlock features like ChatGPT, Apple News, and international Apple Maps (requires a suitable network IP)."
219 | MSG2_FORCE_US_PROMPT_WARNING="${BOLD}${YELLOW}[Side Effect]${RESET} This will disable the Gaode version of Apple Maps used in mainland China."
220 | MSG2_FORCE_US_PROMPT_CONFIRM="${BOLD}Would you like to force your system's country code to US? (y/n): ${RESET}"
221 | MSG2_FORCE_US_START="-> Starting to modify countryd database..."
222 | MSG2_FORCE_US_UNLOCKING=" - Unlocking countryd file for writing..."
223 | MSG2_FORCE_US_BACKUP=" - Backed up original countryd plist."
224 | MSG2_FORCE_US_CONVERT_XML=" - Converted plist to XML for editing."
225 | MSG2_FORCE_US_REPLACE=" - Replaced country code with 'US'."
226 | MSG2_FORCE_US_CONVERT_BIN=" - Converted plist back to binary format."
227 | MSG2_FORCE_US_LOCKING=" - Locking countryd plist to prevent overwrites..."
228 | MSG2_FORCE_US_LOCK_COMPLETE=" - Lock complete."
229 | MSG2_FORCE_US_SUCCESS="${GREEN}✅ Location successfully forced to US and locked.${RESET}"
230 | MSG2_FORCE_US_NOT_FOUND="${YELLOW}⚠️ Warning: countryd plist not found. Skipping this step.${RESET}"
231 | MSG2_UNLOCK_IPHONE_WARNING_TITLE="${BOLD}${YELLOW}--- IMPORTANT: iPhone Mirroring Notice ---${RESET}"
232 | MSG2_UNLOCK_IPHONE_WARNING_1="${BOLD}${YELLOW}[Requirement]${RESET} If you use the iPhone Mirroring feature, you must pair your iPhone with this Mac ${BOLD}before${RESET} you change the country code."
233 | MSG2_UNLOCK_IPHONE_WARNING_2="${BOLD}${YELLOW}[Reason]${RESET} Changing the country code may cause a mismatch that can prevent pairing. Pair first, then proceed."
234 |
235 | # Method 1 specific
236 | M1_START_STEPS="Starting Apple Intelligence enablement (Method 1)..."
237 | M1_PREPARE_MODIFY="Preparing to modify system files..."
238 | M1_UNLOCK_PERMS="Unlocking system eligibility directories..."
239 | M1_MODIFY_PLIST_START_1="Modifying keys in eligibility.plist ..."
240 | M1_MODIFY_PLIST_START_2="Modifying key in os_eligibility.plist ..."
241 | M1_MODIFY_PLISTS_COMPLETE="${GREEN}All necessary plist modifications complete.${RESET}"
242 | M1_EXECUTE_ZOUXIAN="Executing eligibility patch logic with lldb..."
243 | M1_RESTART_ELIGIBILITY="Restarting eligibility daemon..."
244 | M1_CHECK_AI_TITLE="${BOLD}${CYAN}--- Please Check Apple Intelligence Status ---${RESET}"
245 | M1_CHECK_AI_INSTR_1="Go to 'System Settings' -> 'Apple Intelligence' or 'Siri' and check if the 'Apple Intelligence' option appears."
246 | M1_CHECK_AI_INSTR_2="If it ${BOLD}appears${RESET}, or you see new AI features, please enter Y."
247 | M1_CHECK_AI_INSTR_3="If it ${BOLD}does not appear${RESET}, please enter N."
248 | M1_CHECK_AI_PROMPT="${BOLD}Confirm if Apple Intelligence appeared (Y/N): ${RESET}"
249 | M1_SUCCESS_CONFIRMED_START="User confirmed success, completing setup..."
250 | M1_OPERATION_COMPLETE="${GREEN}Operation completed.${RESET}"
251 | M1_CHECK_AI_AGAIN="After restarting, check Apple Intelligence status again."
252 | M1_FAILURE_CONFIRMED_START="${YELLOW}User confirmed failure, restoring files...${RESET}"
253 | M1_RESTORE_START_1="Restoring original eligibility.plist from backup..."
254 | M1_RESTORE_START_2="Restoring original os_eligibility.plist from backup..."
255 | M1_RESTORE_WARNING_FAILED="${BOLD}${RED}Warning: Failed to restore ${RESET}"
256 | M1_RESTORE_WARNING_MANUAL="${BOLD}${RED}Manual intervention may be required!${RESET}"
257 | M1_RESTORE_COMPLETE=" restore complete."
258 | M1_RESTORE_WARNING_NOT_FOUND="${YELLOW}Warning: Backup file not found. Cannot restore.${RESET}"
259 | M1_ENSURE_NO_UCHG="Ensuring uchg flag is removed..."
260 | M1_DISCLAIMER="Disclaimer: This script modifies system files. Use at your own risk."
261 | ;;
262 | *) # Default to Chinese
263 | # Shared
264 | MSG_SUDO_REQUIRED="${YELLOW}此操作需要管理员权限。${RESET}"
265 | MSG_SUDO_PROMPT="请输入你的密码以授予权限: "
266 | MSG_SUDO_SUCCESS="${GREEN}权限已授予,继续执行...${RESET}"
267 | MSG_SUDO_FAILED="${BOLD}${RED}未能获取管理员权限,脚本退出。${RESET}"
268 | MSG_AGREEMENT_TITLE="${BOLD}${YELLOW}--- 重要:在继续前请仔细阅读 ---${RESET}"
269 | MSG_AGREEMENT_LINE1="${BOLD}${YELLOW}[风险]${RESET} 本脚本会修改核心系统文件。不当使用可能导致系统不稳定。"
270 | MSG_AGREEMENT_LINE2="${BOLD}${YELLOW}[要求]${RESET} 在执行修补前,您必须先从恢复模式禁用系统完整性保护 (SIP)。"
271 | MSG_AGREEMENT_LINE3="${BOLD}${YELLOW}[免责]${RESET} 所有操作的风险由您自行承担。"
272 | MSG_AGREEMENT_PROMPT="${BOLD}您是否理解并愿意承担以上风险,继续执行?(y/n): ${RESET}"
273 | MSG_AGREEMENT_CANCEL="用户取消操作,脚本退出。"
274 | MSG_MODE_SELECT_TITLE="${BOLD}请选择要执行的操作:${RESET}"
275 | MSG_MODE_SELECT_1="1. 启用 Apple Intelligence"
276 | MSG_MODE_SELECT_2="2. 解锁文件 (卸载)"
277 | MSG_MODE_SELECT_3="3. 退出"
278 | MSG_MODE_PROMPT="${BOLD}请输入你的选择 [1-3]: ${RESET}"
279 | MSG_SUB_MENU_TITLE="${BOLD}请选择启用方法:${RESET}"
280 | MSG_SUB_MENU_M1="1. 方法1 (模拟美国版机型代码)"
281 | MSG_SUB_MENU_M1_DESC=" ${CYAN}解锁更全面,建议用户优先尝试。15.7和26.2以上版本系统请【不要】选择方法1${RESET}"
282 | MSG_SUB_MENU_M2="2. 方法2 (直接强制开启相关功能)"
283 | MSG_SUB_MENU_M2_DESC=" ${CYAN}如果方法1失败,建议您尝试方法2。15.7和26.2以上版本系统直接选择方法2${RESET}"
284 | MSG_SUB_MENU_M3="3. 返回主菜单"
285 | MSG_INVALID_MODE="${BOLD}${RED}无效选择,脚本退出。${RESET}"
286 | MSG_EXITING="脚本退出。"
287 | MSG_PLISTBUDDY_WARN="${YELLOW}警告:找不到 PlistBuddy 工具。将尝试使用系统默认路径。${RESET}"
288 | MSG_PLISTBUDDY_ERROR="${BOLD}${RED}错误:找不到 PlistBuddy 工具。请确保已安装 Xcode 命令行工具。${RESET}"
289 | MSG_SIP_CHECK="正在检测系统完整性保护 (SIP) 状态..."
290 | MSG_SIP_ENABLED_1="${BOLD}${RED}SIP (系统完整性保护) 当前已启用。${RESET}"
291 | MSG_SIP_ENABLED_2="${BOLD}${RED}必须禁用 SIP 才能继续此操作。${RESET}"
292 | MSG_SIP_ENABLED_3="请按照以下步骤操作:"
293 | MSG_SIP_ENABLED_4_3="3. 在终端中输入 '${BOLD}${CYAN}csrutil disable${RESET}' 并按回车。"
294 | MSG_SIP_ENABLED_4_4="4. 输入 '${BOLD}${CYAN}reboot${RESET}' 并按回车重启 Mac。"
295 | MSG_SIP_ENABLED_5="禁用 SIP 后,请再次运行此脚本。"
296 | MSG_SIP_DISABLED="${GREEN}SIP (系统完整性保护) 已禁用,可以继续。${RESET}"
297 | MSG_WRITE_PERMISSION_ERROR="${BOLD}${RED}错误:未能获得写入权限。请确保 SIP 已禁用。${RESET}"
298 | MSG_BACKUP_START="正在备份原始文件 "
299 | MSG_BACKUP_ERROR="${BOLD}${RED}错误:未能成功备份 ${RESET}"
300 | MSG_BACKUP_COMPLETE="${GREEN}备份完成。${RESET}"
301 | MSG_FINALIZE_START="正在完成收尾工作并锁定文件..."
302 | MSG_SET_PERMS_444="正在设置文件权限为只读 (444)..."
303 | MSG_SET_UCHG="正在设置文件的系统保护标记 (uchg)..."
304 | MSG_FILE_LOCK_COMPLETE="文件锁定完成。"
305 | MSG_CLEANUP_BACKUPS="正在清理备份文件..."
306 | MSG_RESTART_NOW="${BOLD}${YELLOW}必须重启才能使所有更改生效。请立即重启您的 Mac。${RESET}"
307 | MSG_RECOMMEND_RE_ENABLE_SIP="重启后,强烈建议您重新启用 SIP 以保障系统安全。"
308 | MSG_UNLOCK_START="开始文件解锁流程 (恢复/卸载)..."
309 | MSG_UNLOCK_NOUCHG="正在移除所有相关目录文件的系统保护标记 (uchg)..."
310 | MSG_UNLOCK_CHMOD="正在恢复文件权限为系统默认 (644)..."
311 | MSG_UNLOCK_COMPLETE="${GREEN}所有相关文件 (eligibility 和 countryd) 均已解锁。${RESET}"
312 | MSG_SCRIPT_END="脚本执行结束。"
313 | MSG_SUPPORT_URL="如果遇到任何问题,请到 ${BOLD}https://github.com/kanshurichard/enableAppleAI${RESET} 提交Issue。"
314 | MSG_M1_FAIL_TRY_M2_PROMPT="${BOLD}方法1执行失败。是否立即尝试方法2? (y/n): ${RESET}"
315 |
316 | # Method 2 specific
317 | MSG2_START_STEPS="开始执行 Apple Intelligence 启用步骤..."
318 | MSG2_MODIFY_PLISTS_START="正在修补资格属性列表文件 (请稍候)..."
319 | MSG2_MODIFY_PLISTS_COMPLETE="${GREEN}属性列表文件修改完成。${RESET}"
320 | MSG2_OPERATION_COMPLETE="${GREEN}Apple Intelligence 修补程序已成功应用。${RESET}"
321 | MSG2_FORCE_US_PROMPT_TITLE="${CYAN}--- 可选步骤:强制修改地区为美国 ---${RESET}"
322 | MSG2_FORCE_US_PROMPT_BENEFITS="${BOLD}${YELLOW}[好处]${RESET} 在 macOS 26 系统中,此操作可解锁 ChatGPT、Apple News 及国际版苹果地图等功能(需配合相应的网络IP)。"
323 | MSG2_FORCE_US_PROMPT_WARNING="${BOLD}${YELLOW}[副作用]${RESET} 此操作将导致无法在中国大陆境内使用高德版苹果地图。"
324 | MSG2_FORCE_US_PROMPT_CONFIRM="${BOLD}您是否希望将系统的国家代码强制修改为美国 (US)?(y/n): ${RESET}"
325 | MSG2_FORCE_US_START="-> 开始修改 countryd 数据库..."
326 | MSG2_FORCE_US_UNLOCKING=" - 正在解锁 countryd 文件以便写入..."
327 | MSG2_FORCE_US_BACKUP=" - 已备份原始 countryd 文件。"
328 | MSG2_FORCE_US_CONVERT_XML=" - 已转换文件为 XML 格式以便编辑。"
329 | MSG2_FORCE_US_REPLACE=" - 已替换国家代码为 'US'。"
330 | MSG2_FORCE_US_CONVERT_BIN=" - 已转换文件回二进制格式。"
331 | MSG2_FORCE_US_LOCKING=" - 正在锁定 countryd 文件以防覆盖..."
332 | MSG2_FORCE_US_LOCK_COMPLETE=" - 锁定完成。"
333 | MSG2_FORCE_US_SUCCESS="${GREEN}✅ 系统地区已成功强制修改为美国并已锁定。${RESET}"
334 | MSG2_FORCE_US_NOT_FOUND="${YELLOW}⚠️ 警告:未找到 countryd 数据库文件,跳过此步骤。${RESET}"
335 | MSG2_UNLOCK_IPHONE_WARNING_TITLE="${BOLD}${YELLOW}--- 重要:关于 iPhone 镜像功能的提醒 ---${RESET}"
336 | MSG2_UNLOCK_IPHONE_WARNING_1="${BOLD}${YELLOW}[要求]${RESET} 如果您使用 iPhone 镜像功能,必须在修改国家代码前,先完成 iPhone 与这台 Mac 的配对。"
337 | MSG2_UNLOCK_IPHONE_WARNING_2="${BOLD}${YELLOW}[原因]${RESET} 修改国家代码可能导致 macOS 和 iPhone 的代码不匹配,从而阻止配对。请务必先配对,再继续。"
338 |
339 | # Method 1 specific
340 | M1_START_STEPS="开始执行 Apple Intelligence 启用尝试 (方法1)..."
341 | M1_PREPARE_MODIFY="正在准备修改系统文件..."
342 | M1_UNLOCK_PERMS="正在解锁系统资格目录..."
343 | M1_MODIFY_PLIST_START_1="正在修改 eligibility.plist 中的特定键值..."
344 | M1_MODIFY_PLIST_START_2="正在修改 os_eligibility.plist 中的特定键值..."
345 | M1_MODIFY_PLISTS_COMPLETE="${GREEN}所有必要的 plist 文件修改完成。${RESET}"
346 | M1_EXECUTE_ZOUXIAN="正在使用 lldb 执行资格修补逻辑..."
347 | M1_RESTART_ELIGIBILITY="正在重启 eligibility 守护进程..."
348 | M1_CHECK_AI_TITLE="${BOLD}${CYAN}--- 请检查 Apple 智能状态 ---${RESET}"
349 | M1_CHECK_AI_INSTR_1="请前往“系统设置” -> “Apple 智能”或“Siri”检查“Apple智能”选项是否已经出现。"
350 | M1_CHECK_AI_INSTR_2="如果 ${BOLD}已经出现${RESET},或发现新 AI 功能,请输入 Y。"
351 | M1_CHECK_AI_INSTR_3="如果 ${BOLD}没有出现${RESET},请输入 N。"
352 | M1_CHECK_AI_PROMPT="${BOLD}请确认 Apple 智能是否已出现 (Y/N): ${RESET}"
353 | M1_SUCCESS_CONFIRMED_START="用户确认成功,正在完成设置..."
354 | M1_OPERATION_COMPLETE="${GREEN}操作已完成。${RESET}"
355 | M1_CHECK_AI_AGAIN="重启后,再次检查 Apple 智能状态。"
356 | M1_FAILURE_CONFIRMED_START="${YELLOW}用户确认失败,正在恢复文件...${RESET}"
357 | M1_RESTORE_START_1="正在从备份恢复 eligibility.plist ..."
358 | M1_RESTORE_START_2="正在从备份恢复 os_eligibility.plist ..."
359 | M1_RESTORE_WARNING_FAILED="${BOLD}${RED}警告:未能从备份文件恢复 ${RESET}"
360 | M1_RESTORE_WARNING_MANUAL="${BOLD}${RED}可能需要手动恢复!${RESET}"
361 | M1_RESTORE_COMPLETE=" 恢复完成。"
362 | M1_RESTORE_WARNING_NOT_FOUND="${YELLOW}警告:未找到备份文件,无法恢复。${RESET}"
363 | M1_ENSURE_NO_UCHG="确保没有uchg标记..."
364 | M1_DISCLAIMER="免责声明:此脚本修改系统文件,可能导致不稳定或意外行为。请自行承担风险。"
365 | ;;
366 | esac
367 | # --- End Language Settings ---
368 |
369 |
370 | # --- SCRIPT CONSTANTS AND FUNCTIONS ---
371 | # ... (The rest of the script will follow)
372 | # ── File Paths & Dirs
373 | ELIGIBILITY_DIR="/private/var/db/eligibilityd"
374 | OS_ELIGIBILITY_DIR="/private/var/db/os_eligibility"
375 | COUNTRYD_PLIST="/private/var/db/com.apple.countryd/countryCodeCache.plist"
376 | PLISTBUDDY="/usr/libexec/PlistBuddy"
377 |
378 | # --- Function to ensure sudo credentials are cached, prompting if needed ---
379 | request_sudo_privileges() {
380 | if (( EUID == 0 )); then
381 | return
382 | fi
383 | echo ""
384 | echo -e "$MSG_SUDO_REQUIRED"
385 | if sudo -v -p "$MSG_SUDO_PROMPT"; then
386 | echo -e "$MSG_SUDO_SUCCESS"
387 | else
388 | echo -e "$MSG_SUDO_FAILED" >&2
389 | exit 1
390 | fi
391 | }
392 |
393 | # --- Function to check SIP status ---
394 | check_sip_status() {
395 | echo ""
396 | echo -e "${BLUE}==============================================${RESET}"
397 | echo -e "$MSG_SIP_CHECK"
398 | if [[ $(csrutil status) != *"System Integrity Protection status: disabled."* ]]; then
399 | echo -e "$MSG_SIP_ENABLED_1"; echo -e "$MSG_SIP_ENABLED_2"; echo -e "$MSG_SIP_ENABLED_3"
400 | echo -e "$MSG_SIP_ENABLED_4_1"; echo -e "$MSG_SIP_ENABLED_4_2"; echo -e "$MSG_SIP_ENABLED_4_3"
401 | echo -e "$MSG_SIP_ENABLED_4_4"; echo -e "$MSG_SIP_ENABLED_5"
402 | echo -e "${BLUE}==============================================${RESET}"
403 | exit 1
404 | else
405 | echo -e "$MSG_SIP_DISABLED"
406 | fi
407 | }
408 |
409 | # --- Function to set a plist value ONLY if the key already exists (for Method 2) ---
410 | set_existing_plist_key() {
411 | local file="$1"
412 | local key_path="$2"
413 | local value="$3"
414 | if sudo "$PLISTBUDDY" -c "Print :${key_path}" "$file" &>/dev/null; then
415 | sudo "$PLISTBUDDY" -c "Set :${key_path} ${value}" "$file"
416 | fi
417 | }
418 |
419 | # --- Function to Force Location to US ---
420 | force_us_location() {
421 | echo -e "$MSG2_FORCE_US_START"
422 | if [ ! -f "$COUNTRYD_PLIST" ]; then
423 | echo -e "$MSG2_FORCE_US_NOT_FOUND"
424 | return
425 | fi
426 | echo -e "$MSG2_FORCE_US_UNLOCKING"
427 | sudo chflags nouchg "$COUNTRYD_PLIST"
428 | sudo chmod 777 "$COUNTRYD_PLIST"
429 | local BACKUP_FILE="${COUNTRYD_PLIST}.bak"
430 | sudo cp "$COUNTRYD_PLIST" "$BACKUP_FILE"
431 | echo -e "$MSG2_FORCE_US_BACKUP"
432 | sudo plutil -convert xml1 "$COUNTRYD_PLIST"
433 | echo -e "$MSG2_FORCE_US_CONVERT_XML"
434 | local NEW_COUNTRY_CODE="US"
435 | local AWK_SCRIPT='/^[[:space:]]*[A-Z][A-Z]<\/string>[[:space:]]*$/{indent="";if(match($0,/^[[:space:]]*/)){indent=substr($0,RSTART,RLENGTH)}printf "%s%s\n",indent,"'"$NEW_COUNTRY_CODE"'";next}{print $0}'
436 | local TEMP_PLIST="/tmp/temp_countryd.plist"
437 | sudo awk "$AWK_SCRIPT" "$COUNTRYD_PLIST" > "$TEMP_PLIST"
438 | sudo mv "$TEMP_PLIST" "$COUNTRYD_PLIST"
439 | echo -e "$MSG2_FORCE_US_REPLACE"
440 | sudo plutil -convert binary1 "$COUNTRYD_PLIST"
441 | echo -e "$MSG2_FORCE_US_CONVERT_BIN"
442 | echo -e "$MSG2_FORCE_US_LOCKING"
443 | sudo chmod 444 "$COUNTRYD_PLIST"
444 | sudo chflags uchg "$COUNTRYD_PLIST"
445 | echo -e "$MSG2_FORCE_US_LOCK_COMPLETE"
446 | echo -e "$MSG2_FORCE_US_SUCCESS"
447 | }
448 |
449 | # --- New Function to handle Method 1 Failure ---
450 | handle_method_1_failure() {
451 | echo ""
452 | echo -e "${BLUE}==============================================${RESET}"
453 | read -r -p "$(echo -e "$MSG_M1_FAIL_TRY_M2_PROMPT")" try_m2 < /dev/tty
454 | if [[ "$try_m2" =~ ^[Yy]$ ]]; then
455 | enable_ai_method_2
456 | else
457 | echo -e "$MSG_EXITING"
458 | fi
459 | }
460 |
461 | # --- METHOD 1 FUNCTION (Simulate US Model) ---
462 | enable_ai_method_1() {
463 | request_sudo_privileges
464 | check_sip_status
465 |
466 | local ELIGIBILITY_PLIST="${ELIGIBILITY_DIR}/eligibility.plist"
467 | local OS_ELIGIBILITY_PLIST="${OS_ELIGIBILITY_DIR}/eligibility.plist"
468 | local PLIST_BACKUP="/tmp/eligibility.plist.bak.m1"
469 | local OS_PLIST_BACKUP="/tmp/os_eligibility.plist.bak.m1"
470 |
471 | echo ""
472 | echo -e "${BLUE}==============================================${RESET}"
473 | echo -e "$M1_START_STEPS"
474 |
475 | echo -e "$M1_PREPARE_MODIFY"
476 | echo -e "$M1_UNLOCK_PERMS"
477 | sudo chflags nouchg "${ELIGIBILITY_DIR}"/* "${OS_ELIGIBILITY_DIR}"/*
478 | sudo chmod 777 "${ELIGIBILITY_DIR}"/* "${OS_ELIGIBILITY_DIR}"/*
479 |
480 | if [ ! -w "$ELIGIBILITY_PLIST" ] || [ ! -w "$OS_ELIGIBILITY_PLIST" ]; then
481 | echo -e "$MSG_WRITE_PERMISSION_ERROR" >&2; exit 1
482 | fi
483 |
484 | echo -e "$MSG_BACKUP_START$ELIGIBILITY_PLIST..."
485 | sudo cp "$ELIGIBILITY_PLIST" "$PLIST_BACKUP"
486 | echo -e "$MSG_BACKUP_START$OS_ELIGIBILITY_PLIST..."
487 | sudo cp "$OS_ELIGIBILITY_PLIST" "$OS_PLIST_BACKUP"
488 | echo -e "$MSG_BACKUP_COMPLETE"
489 |
490 | echo -e "$M1_MODIFY_PLIST_START_1"
491 | sudo "$PLISTBUDDY" -c "Set :OS_ELIGIBILITY_DOMAIN_GREYMATTER:status:OS_ELIGIBILITY_INPUT_COUNTRY_BILLING 2" "$ELIGIBILITY_PLIST"
492 | sudo "$PLISTBUDDY" -c "Set :OS_ELIGIBILITY_DOMAIN_GREYMATTER:status:OS_ELIGIBILITY_INPUT_DEVICE_AND_SIRI_LANGUAGE_MATCH 2" "$ELIGIBILITY_PLIST"
493 | sudo "$PLISTBUDDY" -c "Set :OS_ELIGIBILITY_DOMAIN_GREYMATTER:status:OS_ELIGIBILITY_INPUT_DEVICE_REGION_CODE 2" "$ELIGIBILITY_PLIST"
494 | sudo "$PLISTBUDDY" -c "Set :OS_ELIGIBILITY_DOMAIN_GREYMATTER:status:OS_ELIGIBILITY_INPUT_EXTERNAL_BOOT_DRIVE 2" "$ELIGIBILITY_PLIST"
495 | sudo "$PLISTBUDDY" -c "Set :OS_ELIGIBILITY_DOMAIN_CALCIUM:status:OS_ELIGIBILITY_INPUT_DEVICE_REGION_CODE 2" "$ELIGIBILITY_PLIST"
496 | echo -e "$M1_MODIFY_PLIST_START_2"
497 | sudo "$PLISTBUDDY" -c "Set :OS_ELIGIBILITY_DOMAIN_STRONTIUM:os_eligibility_answer_t 4" "$OS_ELIGIBILITY_PLIST"
498 | echo -e "$M1_MODIFY_PLISTS_COMPLETE"
499 |
500 | echo -e "$M1_EXECUTE_ZOUXIAN"
501 | MAX_WAIT_TIME=60; CHECK_INTERVAL=1; SECONDS_PASSED=0; PROCESS_FOUND=0
502 | echo -e "$M1_RESTART_ELIGIBILITY"
503 | sudo launchctl stop com.apple.eligibilityd 2>/dev/null || true
504 | sleep 0.5
505 | sudo launchctl start com.apple.eligibilityd
506 |
507 | while [ $SECONDS_PASSED -lt $MAX_WAIT_TIME ]; do
508 | PID=$(pgrep eligibilityd)
509 | if [ ! -z "$PID" ]; then
510 | echo "eligibilityd found with PID $PID"
511 | PROCESS_FOUND=1
512 | sudo -E "$(xcrun --find lldb)" --batch \
513 | -o "process attach --name eligibilityd" \
514 | -o "expression (void) [[[InputManager sharedInstance] objectForInputValue:6] setValue:@\"LL\" forKey:@\"_deviceRegionCode\"]" \
515 | -o "expression (void) [[EligibilityEngine sharedInstance] recomputeAllDomainAnswers]" \
516 | -o "process detach" -o quit
517 | break
518 | fi
519 | sleep $CHECK_INTERVAL
520 | SECONDS_PASSED=$((SECONDS_PASSED + CHECK_INTERVAL))
521 | done
522 |
523 | if [ "$PROCESS_FOUND" -ne 1 ]; then
524 | echo -e "${RED}eligibilityd not found after $MAX_WAIT_TIME seconds. Method 1 failed.${RESET}"
525 | handle_method_1_failure
526 | return
527 | fi
528 |
529 | echo ""
530 | echo -e "${BLUE}==============================================${RESET}"
531 | echo -e "$M1_CHECK_AI_TITLE"
532 | echo -e "$M1_CHECK_AI_INSTR_1"
533 | echo -e "$M1_CHECK_AI_INSTR_2"
534 | echo -e "$M1_CHECK_AI_INSTR_3"
535 | echo -e "${BLUE}----------------------------------------------${RESET}"
536 | read -r -p "$(echo -e "$M1_CHECK_AI_PROMPT")" user_confirmation < /dev/tty
537 |
538 | if [[ "$user_confirmation" =~ ^[Yy]$ ]]; then
539 | echo ""
540 | echo -e "${BLUE}==============================================${RESET}"
541 | echo -e "$M1_SUCCESS_CONFIRMED_START"
542 | echo -e "$MSG_FINALIZE_START"
543 | echo -e "$MSG_SET_PERMS_444"
544 | sudo chmod 444 "${ELIGIBILITY_DIR}"/* "${OS_ELIGIBILITY_DIR}"/*
545 | echo -e "$MSG_SET_UCHG"
546 | sudo chflags uchg "${ELIGIBILITY_DIR}"/* "${OS_ELIGIBILITY_DIR}"/*
547 | echo -e "$MSG_FILE_LOCK_COMPLETE"
548 | echo -e "$MSG_CLEANUP_BACKUPS"
549 | sudo rm -f "$PLIST_BACKUP" "$OS_PLIST_BACKUP"
550 | echo -e "$M1_OPERATION_COMPLETE"
551 |
552 | echo ""
553 | echo -e "$MSG2_FORCE_US_PROMPT_TITLE"
554 | echo -e "$MSG2_FORCE_US_PROMPT_BENEFITS"
555 | echo -e "$MSG2_FORCE_US_PROMPT_WARNING"
556 | echo ""
557 | echo -e "$MSG2_UNLOCK_IPHONE_WARNING_TITLE"
558 | echo -e "$MSG2_UNLOCK_IPHONE_WARNING_1"
559 | echo -e "$MSG2_UNLOCK_IPHONE_WARNING_2"
560 | echo -e "${BLUE}----------------------------------------------------${RESET}"
561 | read -r -p "$(echo -e "$MSG2_FORCE_US_PROMPT_CONFIRM")" force_us < /dev/tty
562 | if [[ "$force_us" =~ ^[Yy]$ ]]; then
563 | force_us_location
564 | fi
565 |
566 | echo ""
567 | echo -e "${BLUE}==============================================${RESET}"
568 | echo -e "$MSG_RESTART_NOW"
569 | echo -e "$M1_CHECK_AI_AGAIN"
570 | echo -e "$MSG_RECOMMEND_RE_ENABLE_SIP"
571 | echo -e "${BLUE}==============================================${RESET}"
572 | else
573 | echo ""
574 | echo -e "${BLUE}==============================================${RESET}"
575 | echo -e "$M1_FAILURE_CONFIRMED_START"
576 | if [ -f "$PLIST_BACKUP" ]; then
577 | echo -e "$M1_RESTORE_START_1"
578 | sudo rm -f "$ELIGIBILITY_PLIST"
579 | sudo cp "$PLIST_BACKUP" "$ELIGIBILITY_PLIST"
580 | fi
581 | if [ -f "$OS_PLIST_BACKUP" ]; then
582 | echo -e "$M1_RESTORE_START_2"
583 | sudo rm -f "$OS_ELIGIBILITY_PLIST"
584 | sudo cp "$OS_PLIST_BACKUP" "$OS_ELIGIBILITY_PLIST"
585 | fi
586 | echo -e "$M1_ENSURE_NO_UCHG"
587 | sudo chflags nouchg "${ELIGIBILITY_DIR}"/* "${OS_ELIGIBILITY_DIR}"/*
588 | echo -e "$MSG_CLEANUP_BACKUPS"
589 | sudo rm -f "$PLIST_BACKUP" "$OS_PLIST_BACKUP"
590 |
591 | handle_method_1_failure
592 | fi
593 | }
594 |
595 | # --- METHOD 2 FUNCTION (Direct Force-Enable) ---
596 | enable_ai_method_2() {
597 | request_sudo_privileges
598 | local ELIGIBILITY_PLIST="${ELIGIBILITY_DIR}/eligibility.plist"
599 | local OS_ELIGIBILITY_PLIST="${OS_ELIGIBILITY_DIR}/eligibility.plist"
600 | check_sip_status
601 | if [[ ! -x $PLISTBUDDY ]]; then
602 | echo -e "$MSG_PLISTBUDDY_WARN"
603 | if command -v PlistBuddy >/dev/null 2>&1; then
604 | PLISTBUDDY="PlistBuddy"
605 | else
606 | echo -e "$MSG_PLISTBUDDY_ERROR" >&2
607 | exit 1
608 | fi
609 | fi
610 | echo ""
611 | echo -e "${BLUE}==============================================${RESET}"
612 | echo -e "$MSG2_START_STEPS"
613 | echo -e "$UNLOCK_PERMS"
614 | sudo chflags nouchg "${ELIGIBILITY_DIR}"/* "${OS_ELIGIBILITY_DIR}"/*
615 | sudo chmod 777 "${ELIGIBILITY_DIR}"/* "${OS_ELIGIBILITY_DIR}"/*
616 | if [ ! -w "$ELIGIBILITY_PLIST" ] || [ ! -w "$OS_ELIGIBILITY_PLIST" ]; then
617 | echo -e "$MSG_WRITE_PERMISSION_ERROR" >&2; exit 1
618 | fi
619 | local PLIST_BACKUP="/tmp/eligibility.plist.bak.m2"
620 | local OS_PLIST_BACKUP="/tmp/os_eligibility.plist.bak.m2"
621 | echo -e "$MSG_BACKUP_START$ELIGIBILITY_PLIST..."
622 | sudo cp "$ELIGIBILITY_PLIST" "$PLIST_BACKUP"
623 | echo -e "$MSG_BACKUP_START$OS_ELIGIBILITY_PLIST..."
624 | sudo cp "$OS_ELIGIBILITY_PLIST" "$OS_PLIST_BACKUP"
625 | echo -e "$MSG_BACKUP_COMPLETE"
626 | echo -e "$MSG2_MODIFY_PLISTS_START"
627 | set_existing_plist_key "$OS_ELIGIBILITY_PLIST" "OS_ELIGIBILITY_DOMAIN_STRONTIUM:os_eligibility_answer_t" "4"
628 | set_existing_plist_key "$OS_ELIGIBILITY_PLIST" "OS_ELIGIBILITY_DOMAIN_XCODE_LLM:os_eligibility_answer_t" "4"
629 | set_existing_plist_key "$ELIGIBILITY_PLIST" "OS_ELIGIBILITY_DOMAIN_GREYMATTER:os_eligibility_answer_t" "4"
630 | set_existing_plist_key "$ELIGIBILITY_PLIST" "OS_ELIGIBILITY_DOMAIN_FOUNDATION_MODELS:os_eligibility_answer_t" "4"
631 | echo -e "$MSG2_MODIFY_PLISTS_COMPLETE"
632 | echo -e "$MSG_FINALIZE_START"
633 | echo -e "$MSG_SET_PERMS_444"
634 | sudo chmod 444 "$ELIGIBILITY_PLIST" "$OS_ELIGIBILITY_PLIST"
635 | echo -e "$MSG_SET_UCHG"
636 | sudo chflags uchg "$ELIGIBILITY_PLIST" "$OS_ELIGIBILITY_PLIST"
637 | echo -e "$MSG_FILE_LOCK_COMPLETE"
638 | echo -e "$MSG_CLEANUP_BACKUPS"
639 | sudo rm -f "$PLIST_BACKUP" "$OS_PLIST_BACKUP"
640 | echo ""
641 | echo -e "${BLUE}==============================================${RESET}"
642 | echo -e "$MSG2_OPERATION_COMPLETE"
643 |
644 | echo ""
645 | echo -e "$MSG2_FORCE_US_PROMPT_TITLE"
646 | echo -e "$MSG2_FORCE_US_PROMPT_BENEFITS"
647 | echo -e "$MSG2_FORCE_US_PROMPT_WARNING"
648 | echo ""
649 | echo -e "$MSG2_UNLOCK_IPHONE_WARNING_TITLE"
650 | echo -e "$MSG2_UNLOCK_IPHONE_WARNING_1"
651 | echo -e "$MSG2_UNLOCK_IPHONE_WARNING_2"
652 | echo -e "${BLUE}----------------------------------------------------${RESET}"
653 | read -r -p "$(echo -e "$MSG2_FORCE_US_PROMPT_CONFIRM")" force_us < /dev/tty
654 | if [[ "$force_us" =~ ^[Yy]$ ]]; then
655 | force_us_location
656 | fi
657 |
658 | echo ""
659 | echo -e "${BLUE}==============================================${RESET}"
660 | echo -e "$MSG_RESTART_NOW"
661 | echo -e "$MSG_RECOMMEND_RE_ENABLE_SIP"
662 | echo -e "${BLUE}==============================================${RESET}"
663 | }
664 |
665 | # --- Function to Unlock Files (Revert/Uninstall) ---
666 | unlock_files() {
667 | request_sudo_privileges
668 | check_sip_status
669 | echo ""
670 | echo -e "${BLUE}==============================================${RESET}"
671 | echo -e "$MSG_UNLOCK_START"
672 | echo ""
673 | echo -e "$MSG_UNLOCK_NOUCHG"
674 | sudo chflags nouchg "${ELIGIBILITY_DIR}"/* "${OS_ELIGIBILITY_DIR}"/* "$COUNTRYD_PLIST"
675 | echo -e "$MSG_UNLOCK_CHMOD"
676 | sudo chmod 644 "${ELIGIBILITY_DIR}"/* "${OS_ELIGIBILITY_DIR}"/* "$COUNTRYD_PLIST"
677 | echo ""
678 | echo -e "$MSG_UNLOCK_COMPLETE"
679 | echo -e "${BLUE}==============================================${RESET}"
680 | }
681 |
682 |
683 | # --- MAIN SCRIPT EXECUTION ---
684 | # Show disclaimer and require agreement
685 | echo ""
686 | echo -e "$MSG_AGREEMENT_TITLE"
687 | echo -e "$MSG_AGREEMENT_LINE1"
688 | echo -e "$MSG_AGREEMENT_LINE2"
689 | echo -e "$MSG_AGREEMENT_LINE3"
690 | echo -e "${BLUE}----------------------------------------------------${RESET}"
691 | read -r -p "$(echo -e "$MSG_AGREEMENT_PROMPT")" agreement < /dev/tty
692 | if [[ ! "$agreement" =~ ^[Yy]$ ]]; then
693 | echo -e "$MSG_AGREEMENT_CANCEL"
694 | exit 1
695 | fi
696 |
697 | # Main menu loop
698 | while true; do
699 | echo ""
700 | echo -e "${BLUE}==============================================${RESET}"
701 | echo -e "$MSG_MODE_SELECT_TITLE"
702 | echo -e "$MSG_MODE_SELECT_1"
703 | echo -e "$MSG_MODE_SELECT_2"
704 | echo -e "$MSG_MODE_SELECT_3"
705 | echo -e "${BLUE}==============================================${RESET}"
706 | read -r -p "$(echo -e "$MSG_MODE_PROMPT")" mode_choice < /dev/tty
707 |
708 | case "$mode_choice" in
709 | 1)
710 | # Sub-menu for enabling AI
711 | echo ""
712 | echo -e "${BLUE}==============================================${RESET}"
713 | echo -e "$MSG_SUB_MENU_TITLE"
714 | echo -e "$MSG_SUB_MENU_M1"
715 | echo -e "$MSG_SUB_MENU_M1_DESC"
716 | echo -e "$MSG_SUB_MENU_M2"
717 | echo -e "$MSG_SUB_MENU_M2_DESC"
718 | echo -e "$MSG_SUB_MENU_M3"
719 | echo -e "${BLUE}==============================================${RESET}"
720 | read -r -p "$(echo -e "$MSG_MODE_PROMPT")" sub_choice < /dev/tty
721 |
722 | case "$sub_choice" in
723 | 1)
724 | enable_ai_method_1
725 | break
726 | ;;
727 | 2)
728 | enable_ai_method_2
729 | break
730 | ;;
731 | 3)
732 | continue # Go back to the main menu
733 | ;;
734 | *)
735 | echo -e "$MSG_INVALID_MODE" >&2
736 | exit 1
737 | ;;
738 | esac
739 | ;;
740 | 2)
741 | unlock_files
742 | break
743 | ;;
744 | 3)
745 | echo -e "$MSG_EXITING"
746 | exit 0
747 | ;;
748 | *)
749 | echo -e "$MSG_INVALID_MODE" >&2
750 | exit 1
751 | ;;
752 | esac
753 | done
754 |
755 | echo ""
756 | echo -e "$MSG_SCRIPT_END"
757 | echo -e "$MSG_SUPPORT_URL"
758 | echo -e "${BLUE}==============================================${RESET}"
759 |
760 | exit 0
761 |
--------------------------------------------------------------------------------