From 77d0b0439b3e5a8b47055a32e952b27714cde804 Mon Sep 17 00:00:00 2001 From: zhaozm517 Date: Tue, 11 Feb 2025 23:05:01 +0800 Subject: [PATCH] Create change_cursor_id_pro.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 与原作者提供的脚本的主要区别: 模块化和简化: 路径处理:在新的脚本中,路径构建(get_storage_path 和 get_main_js_path)被提取为独立的函数,避免了重复代码,使得平台特定路径的处理更加清晰和简洁。 功能封装:每个功能(如更新 ID、修改 main.js 等)都被封装为独立函数,使得代码更模块化、易于理解和维护。 异常处理: 脚本使用了具体的异常捕获(如 OSError 和 json.JSONDecodeError),可以在发生错误时给出更清晰、详细的错误信息,而不是使用广泛的 Exception 捕获。这有助于更精确地处理不同的错误类型。 代码可读性和注释: 详细注释:新脚本中每一行都加上了详细的注释,解释了每一步操作的目的,增加了代码的可读性和可维护性。无论是路径处理、ID 生成还是文件备份,注释都非常明确,帮助开发者快速理解每个部分的作用。 简化的文件操作: 在新脚本中,文件的读取、更新、写入都使用了更简洁的方式,避免了复杂的文件指针管理,使得代码更简洁且减少了错误的可能性。 跨平台支持: 对于 Windows 和 macOS 系统的支持进行了优化,main.js 的路径和命令替换更加符合不同平台的特性,避免了不必要的操作系统差异。 函数功能单一性: 每个函数的职责更加明确和单一,增强了代码的可维护性和扩展性。例如,generate_random_id 和 generate_uuid 专注于 ID 生成,backup_file 专注于备份,避免了过于复杂的函数设计。 优点总结: 代码简洁且模块化:每个功能点(如路径获取、ID 生成、文件操作)都封装为独立的函数,提高了代码的可维护性,增强了代码的复用性。 跨平台兼容性:脚本能够根据不同操作系统(Windows、macOS、Linux)自动选择适当的路径和命令,确保操作系统差异不影响功能实现。 增强的错误处理:针对不同的错误类型提供了更精确的异常处理,使得程序在出现错误时能提供清晰的错误信息,帮助开发者快速定位问题。 详细的注释和清晰的逻辑:每行代码都有详细的注释,帮助开发者快速理解代码逻辑,特别适合新手学习和团队协作开发。 易于扩展:脚本的结构清晰,每个功能都独立封装,可以方便地进行扩展或修改。例如,新增对其他平台的支持、改进 ID 生成方式等,都能在原有基础上轻松实现。 --- change_cursor_id_pro.py | 197 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 change_cursor_id_pro.py diff --git a/change_cursor_id_pro.py b/change_cursor_id_pro.py new file mode 100644 index 0000000..07238a3 --- /dev/null +++ b/change_cursor_id_pro.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import json +import uuid +import shutil +import platform +import re +from datetime import datetime + +# 获取当前操作系统类型(Windows, macOS, Linux) +def get_platform(): + system = platform.system().lower() + return system + +# 获取配置文件路径 +def get_storage_path(): + """返回配置文件路径,根据操作系统不同,返回不同的路径""" + system = get_platform() + home = os.path.expanduser('~') # 获取当前用户的 home 目录 + + # 针对不同操作系统返回配置文件路径 + if system == 'windows': + return os.path.join(os.getenv('APPDATA'), 'Cursor', 'User', 'globalStorage', 'storage.json') + elif system == 'darwin': # macOS + return os.path.join(home, 'Library', 'Application Support', 'Cursor', 'User', 'globalStorage', 'storage.json') + else: # Linux + return os.path.join(home, '.config', 'Cursor', 'User', 'globalStorage', 'storage.json') + +# 获取 main.js 文件路径 +def get_main_js_path(): + """根据操作系统返回 main.js 文件路径""" + system = get_platform() + + if system == 'darwin': # macOS + return '/Applications/Cursor.app/Contents/Resources/app/out/main.js' + elif system == 'windows': # Windows + user_profile = os.getenv('LOCALAPPDATA') + if not user_profile: + return None + return os.path.join(user_profile, 'Programs', 'cursor', 'resources', 'app', 'out', 'main.js') + return None + +# 生成一个新的随机ID(64位十六进制字符串) +def generate_random_id(): + """生成一个64位十六进制随机ID""" + return uuid.uuid4().hex + uuid.uuid4().hex + +# 生成一个新的UUID +def generate_uuid(): + """生成UUID""" + return str(uuid.uuid4()) + +# 备份文件 +def backup_file(file_path): + """创建文件的备份""" + if os.path.exists(file_path): + # 根据当前时间生成备份文件名 + backup_path = '{}.backup_{}'.format(file_path, datetime.now().strftime('%Y%m%d_%H%M%S')) + shutil.copy2(file_path, backup_path) # 复制文件并保留元数据 + print(f'已创建备份文件: {backup_path}') + +# 确保目录存在,如果不存在则创建 +def ensure_dir_exists(path): + """确保路径的目录存在""" + if not os.path.exists(path): + os.makedirs(path) # 创建目录 + +# 更新 main.js 中的机器标识符生成方式 +def update_main_js(file_path): + """更新 main.js 文件中的 UUID 生成命令""" + if not os.path.exists(file_path): + print(f'警告: main.js 文件不存在: {file_path}') + return False + + # 创建备份文件 + backup_file(file_path) + + try: + with open(file_path, 'r') as f: + content = f.read() # 读取文件内容 + + system = get_platform() + + # 对于 macOS,替换 ioreg 命令 + if system == 'darwin': + new_content = re.sub( + r'ioreg -rd1 -c IOPlatformExpertDevice', + 'UUID=$(uuidgen | tr \'[:upper:]\' \'[:lower:]\');echo \\"IOPlatformUUID = \\"$UUID\\";', + content + ) + + # 对于 Windows,替换 REG.exe 命令 + elif system == 'windows': + old_cmd = r'${v5[s$()]}\\REG.exe QUERY HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography /v MachineGuid' + new_cmd = r'powershell -Command "[guid]::NewGuid().ToString().ToLower()"' + new_content = content.replace(old_cmd, new_cmd) + + else: + print(f'警告: 当前操作系统不支持自动修改 main.js') + return False + + # 将修改后的内容写回文件 + with open(file_path, 'w') as f: + f.write(new_content) + + # 验证文件是否已正确修改 + if system == 'darwin': + success_marker = 'UUID=$(uuidgen | tr \'[:upper:]\' \'[:lower:]\');echo \\"IOPlatformUUID = \\"$UUID\\";' + elif system == 'windows': + success_marker = 'powershell -Command "[guid]::NewGuid().ToString().ToLower()"' + + if success_marker in new_content: + print('main.js 文件修改成功') + return True + else: + print(f'警告: main.js 文件可能未被正确修改, 请检查备份文件: {file_path}.backup_*') + return False + + except Exception as e: + print(f'修改 main.js 时出错: {str(e)}') + return False + +# 更新存储文件中的 ID +def update_storage_file(file_path): + """更新配置文件中的机器 ID""" + # 生成新的随机 ID + new_machine_id = generate_random_id() + new_mac_machine_id = generate_random_id() + new_dev_device_id = generate_uuid() + + # 确保目录存在 + ensure_dir_exists(os.path.dirname(file_path)) + + try: + # 如果文件存在,读取其内容,否则初始化空字典 + if os.path.exists(file_path): + with open(file_path, 'r') as f: + data = json.load(f) + else: + data = {} + + # 更新 ID + data['telemetry.machineId'] = new_machine_id + data['telemetry.macMachineId'] = new_mac_machine_id + data['telemetry.devDeviceId'] = new_dev_device_id + data['telemetry.sqmId'] = '{' + str(uuid.uuid4()).upper() + '}' + + # 将更新后的数据写入配置文件 + with open(file_path, 'w') as f: + json.dump(data, f, indent=4) + + return new_machine_id, new_mac_machine_id, new_dev_device_id + + except (OSError, json.JSONDecodeError) as e: + print(f'读取或更新文件时出错: {str(e)}') + return None, None, None + +# 主程序执行函数 +def main(): + """主执行函数""" + try: + # 获取配置文件路径 + storage_path = get_storage_path() + print(f'配置文件路径: {storage_path}') + + # 备份原文件 + backup_file(storage_path) + + # 更新存储文件中的 ID + machine_id, mac_machine_id, dev_device_id = update_storage_file(storage_path) + + if not machine_id or not mac_machine_id or not dev_device_id: + print('更新ID时发生错误,程序退出。') + return + + # 输出新生成的 ID + print(f'\n已成功修改 ID:') + print(f'machineId: {machine_id}') + print(f'macMachineId: {mac_machine_id}') + print(f'devDeviceId: {dev_device_id}') + + # 获取并更新 main.js 文件 + system = get_platform() + if system in ['darwin', 'windows']: + main_js_path = get_main_js_path() + if main_js_path: + update_main_js(main_js_path) + + except Exception as e: + print(f'错误: {str(e)}', file=sys.stderr) + sys.exit(1) + +# 程序入口 +if __name__ == '__main__': + main()