Files
macm1new/cursor_account_manager.py

203 lines
6.5 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import platform
import json
import sys
import hashlib
import subprocess
import uuid
import requests
from exit_cursor import ExitCursor
from logger import logging
from cursor_auth_manager import CursorAuthManager
import go_cursor_help
import patch_cursor_get_machine_id
from reset_machine import MachineIDResetter
from logo import print_logo
# 定义 EMOJI 字典
EMOJI = {"ERROR": "", "WARNING": "⚠️", "INFO": ""}
def check_cursor_version():
"""检查cursor版本"""
pkg_path, main_path = patch_cursor_get_machine_id.get_cursor_paths()
with open(pkg_path, "r", encoding="utf-8") as f:
version = json.load(f)["version"]
return patch_cursor_get_machine_id.version_check(version, min_version="0.45.0")
def reset_machine_id(greater_than_0_45):
if greater_than_0_45:
# 提示请手动执行脚本 https://github.com/chengazhen/cursor-auto-free/blob/main/patch_cursor_get_machine_id.py
go_cursor_help.go_cursor_help()
else:
MachineIDResetter().reset_machine_ids()
def print_end_message():
logging.info("\n\n\n\n\n")
logging.info("=" * 30)
logging.info("所有操作已完成")
def get_account_from_api() -> tuple[bool, dict]:
"""从API获取账号信息
Returns:
tuple[bool, dict]: (是否成功, 账号信息)
"""
try:
# 获取设备唯一ID
hardware_id = get_mac_unique_id()
logging.info(f"设备唯一ID: {hardware_id}")
endpoint = "https://cursorapi.nosqli.com/admin/api.account/getUnused"
data = {
"machine_id": hardware_id
}
headers = {
"Content-Type": "application/json"
}
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
request_kwargs = {
"json": data,
"headers": headers,
"timeout": 30,
"verify": False
}
try:
try:
response = requests.post(endpoint, **request_kwargs)
except requests.exceptions.SSLError:
import ssl
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
session = requests.Session()
session.verify = False
response = session.post(endpoint, **request_kwargs)
response_data = response.json()
if response_data.get("code") == 200:
account_data = response_data.get("data", {})
return True, account_data
else:
error_msg = response_data.get("msg", "未知错误")
logging.error(f"获取未使用账号失败: {error_msg}")
return False, {}
except Exception as e:
logging.error(f"API请求失败: {str(e)}")
return False, {}
except Exception as e:
logging.error(f"获取账号过程出错: {str(e)}")
return False, {}
def get_mac_unique_id() -> str:
"""
获取Mac设备的唯一ID32位MD5
组合以下信息生成唯一标识:
1. 硬件UUID
2. 系统序列号
3. 主板序列号
4. CPU信息
"""
def run_cmd(cmd: str) -> str:
try:
result = subprocess.check_output(cmd, shell=True).decode('utf-8').strip()
return result
except:
return ""
# 收集系统信息
identifiers = []
# 1. 获取硬件UUID
hw_uuid = run_cmd("ioreg -d2 -c IOPlatformExpertDevice | awk -F\\\" '/IOPlatformUUID/{print $(NF-1)}'")
identifiers.append(hw_uuid)
# 2. 获取系统序列号
serial = run_cmd("ioreg -d2 -c IOPlatformExpertDevice | awk -F\\\" '/IOPlatformSerialNumber/{print $(NF-1)}'")
identifiers.append(serial)
# 3. 获取主板信息
board_id = run_cmd("ioreg -d2 -c IOPlatformExpertDevice | awk -F\\\" '/board-id/{print $(NF-1)}'")
identifiers.append(board_id)
# 4. 获取CPU信息
cpu_info = run_cmd("sysctl -n machdep.cpu.brand_string")
identifiers.append(cpu_info)
# 如果以上方法都失败,使用备用方法
if not any(identifiers):
# 使用 UUID 模块获取 UUID不太稳定仅作为备用
identifiers = [
str(uuid.getnode()), # MAC 地址的整数表示
platform.machine(), # CPU 架构
platform.system(), # 操作系统名称
platform.version() # 操作系统版本
]
# 组合所有标识符并生成MD5
unique_string = "".join(filter(None, identifiers))
return hashlib.md5(unique_string.encode()).hexdigest()
if __name__ == "__main__":
print_logo()
greater_than_0_45 = check_cursor_version()
browser_manager = None
try:
logging.info("\n=== 初始化程序 ===")
# ExitCursor()
logging.info("正在从API获取账号信息...")
success, account_data = get_account_from_api()
if not success:
logging.error("获取账号信息失败")
sys.exit(1)
email = account_data.get("email", "")
access_token = account_data.get("access_token", "")
refresh_token = account_data.get("refresh_token", "")
expire_time = account_data.get("expire_time", "")
days_left = account_data.get("days_left", 0)
if not all([email, access_token, refresh_token]):
logging.error("账号信息不完整")
sys.exit(1)
logging.info(f"获取到账号信息:\n邮箱: {email}\n到期时间: {expire_time}\n剩余天数: {days_left}")
# 更新认证信息
logging.info("正在更新认证信息...")
auth_manager = CursorAuthManager()
if auth_manager.update_auth(email, access_token, refresh_token):
logging.info("认证信息更新成功")
# 重置机器码
logging.info("正在重置机器码...")
reset_machine_id(greater_than_0_45)
logging.info("所有操作已完成")
print_end_message()
else:
logging.error("更新认证信息失败")
except Exception as e:
logging.error(f"程序执行出现错误: {str(e)}")
import traceback
logging.error(traceback.format_exc())
finally:
if browser_manager:
browser_manager.quit()
input("\n程序执行完毕,按回车键退出...")