forked from mirrors/cursor-free-vip
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f6f3fe814 | ||
|
|
54ecf2d752 | ||
|
|
1f1231d1a9 | ||
|
|
d10999a517 | ||
|
|
fb4be6334a | ||
|
|
786eba5371 | ||
|
|
41ddbf519e |
53
.github/workflows/build.yml
vendored
53
.github/workflows/build.yml
vendored
@@ -6,7 +6,7 @@ on:
|
|||||||
version:
|
version:
|
||||||
description: 'Version number (e.g. 1.0.9)'
|
description: 'Version number (e.g. 1.0.9)'
|
||||||
required: true
|
required: true
|
||||||
default: '1.7.03'
|
default: '1.7.05'
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
@@ -98,7 +98,7 @@ jobs:
|
|||||||
name: CursorFreeVIP_${{ env.VERSION }}_mac_arm64
|
name: CursorFreeVIP_${{ env.VERSION }}_mac_arm64
|
||||||
path: dist/CursorFreeVIP_${{ env.VERSION }}_mac_arm64
|
path: dist/CursorFreeVIP_${{ env.VERSION }}_mac_arm64
|
||||||
|
|
||||||
build-linux:
|
build-linux-x64:
|
||||||
needs: create-tag
|
needs: create-tag
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
@@ -120,20 +120,55 @@ jobs:
|
|||||||
pip install pyinstaller
|
pip install pyinstaller
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
|
|
||||||
- name: Build Linux executable
|
- name: Build Linux x64 executable
|
||||||
env:
|
env:
|
||||||
VERSION: ${{ env.VERSION }}
|
VERSION: ${{ env.VERSION }}
|
||||||
run: |
|
run: |
|
||||||
pyinstaller build.spec
|
pyinstaller build.spec
|
||||||
|
mv "dist/CursorFreeVIP_${{ env.VERSION }}_linux" "dist/CursorFreeVIP_${{ env.VERSION }}_linux_x64"
|
||||||
echo "Contents of dist directory:"
|
echo "Contents of dist directory:"
|
||||||
ls -la dist/
|
ls -la dist/
|
||||||
|
|
||||||
- name: Upload Linux artifact
|
- name: Upload Linux x64 artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: CursorFreeVIP_${{ env.VERSION }}_linux
|
name: CursorFreeVIP_${{ env.VERSION }}_linux_x64
|
||||||
path: dist/CursorFreeVIP_${{ env.VERSION }}_linux
|
path: dist/CursorFreeVIP_${{ env.VERSION }}_linux_x64
|
||||||
|
|
||||||
|
build-linux-arm64:
|
||||||
|
needs: create-tag
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
with:
|
||||||
|
platforms: arm64
|
||||||
|
|
||||||
|
- name: Set version
|
||||||
|
shell: bash
|
||||||
|
run: echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Build in ARM64 Docker container
|
||||||
|
run: |
|
||||||
|
docker run --rm --platform linux/arm64 -v ${{ github.workspace }}:/app -w /app arm64v8/python:3.9-slim bash -c "
|
||||||
|
apt-get update && apt-get install -y build-essential
|
||||||
|
pip install --upgrade pip
|
||||||
|
pip install pyinstaller
|
||||||
|
pip install -r requirements.txt
|
||||||
|
python -m PyInstaller build.spec
|
||||||
|
mv /app/dist/CursorFreeVIP_${{ env.VERSION }}_linux /app/dist/CursorFreeVIP_${{ env.VERSION }}_linux_arm64
|
||||||
|
"
|
||||||
|
echo "Contents of dist directory:"
|
||||||
|
ls -la dist/
|
||||||
|
|
||||||
|
- name: Upload Linux ARM64 artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: CursorFreeVIP_${{ env.VERSION }}_linux_arm64
|
||||||
|
path: dist/CursorFreeVIP_${{ env.VERSION }}_linux_arm64
|
||||||
|
|
||||||
build-macos-intel:
|
build-macos-intel:
|
||||||
needs: create-tag
|
needs: create-tag
|
||||||
@@ -171,9 +206,8 @@ jobs:
|
|||||||
name: CursorFreeVIP_${{ env.VERSION }}_mac_intel
|
name: CursorFreeVIP_${{ env.VERSION }}_mac_intel
|
||||||
path: dist/CursorFreeVIP_${{ env.VERSION }}_mac_intel
|
path: dist/CursorFreeVIP_${{ env.VERSION }}_mac_intel
|
||||||
|
|
||||||
|
|
||||||
create-release:
|
create-release:
|
||||||
needs: [build-windows, build-macos-arm64, build-linux, build-macos-intel]
|
needs: [build-windows, build-macos-arm64, build-linux-x64, build-linux-arm64, build-macos-intel]
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -201,7 +235,8 @@ jobs:
|
|||||||
files: |
|
files: |
|
||||||
artifacts/CursorFreeVIP_${{ env.VERSION }}_windows.exe/CursorFreeVIP_${{ env.VERSION }}_windows.exe
|
artifacts/CursorFreeVIP_${{ env.VERSION }}_windows.exe/CursorFreeVIP_${{ env.VERSION }}_windows.exe
|
||||||
artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_arm64/CursorFreeVIP_${{ env.VERSION }}_mac_arm64
|
artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_arm64/CursorFreeVIP_${{ env.VERSION }}_mac_arm64
|
||||||
artifacts/CursorFreeVIP_${{ env.VERSION }}_linux/CursorFreeVIP_${{ env.VERSION }}_linux
|
artifacts/CursorFreeVIP_${{ env.VERSION }}_linux_x64/CursorFreeVIP_${{ env.VERSION }}_linux_x64
|
||||||
|
artifacts/CursorFreeVIP_${{ env.VERSION }}_linux_arm64/CursorFreeVIP_${{ env.VERSION }}_linux_arm64
|
||||||
artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_intel/CursorFreeVIP_${{ env.VERSION }}_mac_intel
|
artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_intel/CursorFreeVIP_${{ env.VERSION }}_mac_intel
|
||||||
draft: false
|
draft: false
|
||||||
prerelease: false
|
prerelease: false
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## v1.7.05
|
||||||
|
1. Fix: Cursor Version Check | 修復Cursor版本檢查
|
||||||
|
2. Fix: Small Problem | 修復一些小問題
|
||||||
|
|
||||||
|
|
||||||
|
## v1.7.04
|
||||||
|
1. Hotfix: Small Problem | 修復一些小問題
|
||||||
|
|
||||||
## v1.7.03
|
## v1.7.03
|
||||||
1. Hotfix: Small Problem | 修復一些小問題
|
1. Hotfix: Small Problem | 修復一些小問題
|
||||||
|
|
||||||
|
|||||||
36
README.md
36
README.md
@@ -88,6 +88,8 @@ irm https://raw.githubusercontent.com/yeongpin/cursor-free-vip/main/scripts/rese
|
|||||||
|
|
||||||
📝 Config | 文件配置
|
📝 Config | 文件配置
|
||||||
`Win / Macos / Linux Path | 路徑 [Documents/.cursor-free-vip/config.ini]`
|
`Win / Macos / Linux Path | 路徑 [Documents/.cursor-free-vip/config.ini]`
|
||||||
|
<details>
|
||||||
|
<summary><b>⭐ Config | 文件配置</b></summary>
|
||||||
|
|
||||||
```
|
```
|
||||||
[Chrome]
|
[Chrome]
|
||||||
@@ -101,10 +103,44 @@ handle_turnstile_time = 2
|
|||||||
handle_turnstile_random_time = 1-3
|
handle_turnstile_random_time = 1-3
|
||||||
|
|
||||||
[OSPaths]
|
[OSPaths]
|
||||||
|
# Storage Path | 存儲路徑
|
||||||
storage_path = /Users/username/Library/Application Support/Cursor/User/globalStorage/storage.json
|
storage_path = /Users/username/Library/Application Support/Cursor/User/globalStorage/storage.json
|
||||||
|
# SQLite Path | SQLite路徑
|
||||||
sqlite_path = /Users/username/Library/Application Support/Cursor/User/globalStorage/state.vscdb
|
sqlite_path = /Users/username/Library/Application Support/Cursor/User/globalStorage/state.vscdb
|
||||||
|
# Machine ID Path | 機器ID路徑
|
||||||
machine_id_path = /Users/username/Library/Application Support/Cursor/machineId
|
machine_id_path = /Users/username/Library/Application Support/Cursor/machineId
|
||||||
|
|
||||||
|
[Timing]
|
||||||
|
# Min Random Time | 最小隨機時間
|
||||||
|
min_random_time = 0.1
|
||||||
|
# Max Random Time | 最大隨機時間
|
||||||
|
max_random_time = 0.8
|
||||||
|
# Page Load Wait | 頁面加載等待時間
|
||||||
|
page_load_wait = 0.1-0.8
|
||||||
|
# Input Wait | 輸入等待時間
|
||||||
|
input_wait = 0.3-0.8
|
||||||
|
# Submit Wait | 提交等待時間
|
||||||
|
submit_wait = 0.5-1.5
|
||||||
|
# Verification Code Input | 驗證碼輸入等待時間
|
||||||
|
verification_code_input = 0.1-0.3
|
||||||
|
# Verification Success Wait | 驗證成功等待時間
|
||||||
|
verification_success_wait = 2-3
|
||||||
|
# Verification Retry Wait | 驗證重試等待時間
|
||||||
|
verification_retry_wait = 2-3
|
||||||
|
# Email Check Initial Wait | 郵件檢查初始等待時間
|
||||||
|
email_check_initial_wait = 4-6
|
||||||
|
# Email Refresh Wait | 郵件刷新等待時間
|
||||||
|
email_refresh_wait = 2-4
|
||||||
|
# Settings Page Load Wait | 設置頁面加載等待時間
|
||||||
|
settings_page_load_wait = 1-2
|
||||||
|
# Failed Retry Time | 失敗重試時間
|
||||||
|
failed_retry_time = 0.5-1
|
||||||
|
# Retry Interval | 重試間隔
|
||||||
|
retry_interval = 8-12
|
||||||
|
# Max Timeout | 最大超時時間
|
||||||
|
max_timeout = 160
|
||||||
```
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
* Use administrator to run the script <br>請使用管理員身份運行腳本
|
* Use administrator to run the script <br>請使用管理員身份運行腳本
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,20 @@
|
|||||||
"permission_denied": "Permission Denied: {error}",
|
"permission_denied": "Permission Denied: {error}",
|
||||||
"backup_created": "Backup Created",
|
"backup_created": "Backup Created",
|
||||||
"update_success": "Update Success",
|
"update_success": "Update Success",
|
||||||
"update_failed": "Update Failed: {error}"
|
"update_failed": "Update Failed: {error}",
|
||||||
|
"windows_machine_guid_updated": "Windows Machine GUID Updated Successfully",
|
||||||
|
"reading_package_json": "Reading package.json {path}",
|
||||||
|
"invalid_json_object": "Invalid JSON Object",
|
||||||
|
"no_version_field": "No Version Field Found in package.json",
|
||||||
|
"version_field_empty": "Version Field is Empty",
|
||||||
|
"invalid_version_format": "Invalid Version Format: {version}",
|
||||||
|
"found_version": "Found Version: {version}",
|
||||||
|
"version_parse_error": "Version Parse Error: {error}",
|
||||||
|
"package_not_found": "Package.json Not Found: {path}",
|
||||||
|
"check_version_failed": "Check Version Failed: {error}",
|
||||||
|
"stack_trace": "Stack Trace",
|
||||||
|
"version_too_low": "Cursor Version Too Low: {version} < 0.45.0"
|
||||||
|
|
||||||
},
|
},
|
||||||
"register": {
|
"register": {
|
||||||
"title": "Cursor Registration Tool",
|
"title": "Cursor Registration Tool",
|
||||||
|
|||||||
@@ -72,7 +72,19 @@
|
|||||||
"permission_denied": "权限拒绝: {error}",
|
"permission_denied": "权限拒绝: {error}",
|
||||||
"backup_created": "备份已创建",
|
"backup_created": "备份已创建",
|
||||||
"update_success": "更新成功",
|
"update_success": "更新成功",
|
||||||
"update_failed": "更新失败: {error}"
|
"update_failed": "更新失败: {error}",
|
||||||
|
"windows_machine_guid_updated": "Windows机器GUID更新成功",
|
||||||
|
"reading_package_json": "读取package.json {path}",
|
||||||
|
"invalid_json_object": "JSON对象无效",
|
||||||
|
"no_version_field": "package.json中没有版本字段",
|
||||||
|
"version_field_empty": "版本字段为空",
|
||||||
|
"invalid_version_format": "版本格式无效: {version}",
|
||||||
|
"found_version": "找到版本: {version}",
|
||||||
|
"version_parse_error": "版本解析错误: {error}",
|
||||||
|
"package_not_found": "package.json未找到: {path}",
|
||||||
|
"check_version_failed": "检查版本失败: {error}",
|
||||||
|
"stack_trace": "堆栈跟踪",
|
||||||
|
"version_too_low": "Cursor版本太低: {version} < 0.45.0"
|
||||||
},
|
},
|
||||||
"register": {
|
"register": {
|
||||||
"title": "Cursor 注册工具",
|
"title": "Cursor 注册工具",
|
||||||
|
|||||||
@@ -72,8 +72,21 @@
|
|||||||
"permission_denied": "權限拒絕: {error}",
|
"permission_denied": "權限拒絕: {error}",
|
||||||
"backup_created": "備份已創建",
|
"backup_created": "備份已創建",
|
||||||
"update_success": "更新成功",
|
"update_success": "更新成功",
|
||||||
"update_failed": "更新失敗: {error}"
|
"update_failed": "更新失敗: {error}",
|
||||||
|
"windows_machine_guid_updated": "Windows機器GUID更新成功",
|
||||||
|
"reading_package_json": "讀取package.json {path}",
|
||||||
|
"invalid_json_object": "JSON對象無效",
|
||||||
|
"no_version_field": "package.json中沒有版本字段",
|
||||||
|
"version_field_empty": "版本字段為空",
|
||||||
|
"invalid_version_format": "版本格式無效: {version}",
|
||||||
|
"found_version": "找到版本: {version}",
|
||||||
|
"version_parse_error": "版本解析錯誤: {error}",
|
||||||
|
"package_not_found": "package.json未找到: {path}",
|
||||||
|
"check_version_failed": "檢查版本失敗: {error}",
|
||||||
|
"stack_trace": "堆疊跟踪",
|
||||||
|
"version_too_low": "Cursor版本太低: {version} < 0.45.0"
|
||||||
},
|
},
|
||||||
|
|
||||||
"register": {
|
"register": {
|
||||||
"title": "Cursor 註冊工具",
|
"title": "Cursor 註冊工具",
|
||||||
"start": "正在啟動註冊流程...",
|
"start": "正在啟動註冊流程...",
|
||||||
|
|||||||
8
main.py
8
main.py
@@ -285,6 +285,14 @@ def check_latest_version():
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
print_logo()
|
print_logo()
|
||||||
|
|
||||||
|
# 初始化配置
|
||||||
|
from new_signup import setup_config
|
||||||
|
config = setup_config(translator)
|
||||||
|
if not config:
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.config_init_failed')}{Style.RESET_ALL}")
|
||||||
|
return
|
||||||
|
|
||||||
check_latest_version() # Add version check before showing menu
|
check_latest_version() # Add version check before showing menu
|
||||||
print_menu()
|
print_menu()
|
||||||
|
|
||||||
|
|||||||
@@ -207,21 +207,25 @@ def setup_config(translator=None):
|
|||||||
default_config['WindowsPaths'] = {
|
default_config['WindowsPaths'] = {
|
||||||
'storage_path': os.path.join(appdata, "Cursor", "User", "globalStorage", "storage.json"),
|
'storage_path': os.path.join(appdata, "Cursor", "User", "globalStorage", "storage.json"),
|
||||||
'sqlite_path': os.path.join(appdata, "Cursor", "User", "globalStorage", "state.vscdb"),
|
'sqlite_path': os.path.join(appdata, "Cursor", "User", "globalStorage", "state.vscdb"),
|
||||||
'machine_id_path': os.path.join(os.getenv("APPDATA"), "Cursor", "machineId")
|
'machine_id_path': os.path.join(os.getenv("APPDATA"), "Cursor", "machineId"),
|
||||||
|
'cursor_path': os.path.join(os.getenv("LOCALAPPDATA", ""), "Programs", "Cursor", "resources", "app")
|
||||||
}
|
}
|
||||||
elif sys.platform == "darwin":
|
elif sys.platform == "darwin":
|
||||||
default_config['MacPaths'] = {
|
default_config['MacPaths'] = {
|
||||||
'storage_path': os.path.abspath(os.path.expanduser("~/Library/Application Support/Cursor/User/globalStorage/storage.json")),
|
'storage_path': os.path.abspath(os.path.expanduser("~/Library/Application Support/Cursor/User/globalStorage/storage.json")),
|
||||||
'sqlite_path': os.path.abspath(os.path.expanduser("~/Library/Application Support/Cursor/User/globalStorage/state.vscdb")),
|
'sqlite_path': os.path.abspath(os.path.expanduser("~/Library/Application Support/Cursor/User/globalStorage/state.vscdb")),
|
||||||
'machine_id_path': os.path.expanduser("~/Library/Application Support/Cursor/machineId")
|
'machine_id_path': os.path.expanduser("~/Library/Application Support/Cursor/machineId"),
|
||||||
|
'cursor_path': "/Applications/Cursor.app/Contents/Resources/app"
|
||||||
}
|
}
|
||||||
elif sys.platform == "linux":
|
elif sys.platform == "linux":
|
||||||
sudo_user = os.environ.get('SUDO_USER')
|
sudo_user = os.environ.get('SUDO_USER')
|
||||||
actual_home = f"/home/{sudo_user}" if sudo_user else os.path.expanduser("~")
|
actual_home = f"/home/{sudo_user}" if sudo_user else os.path.expanduser("~")
|
||||||
|
|
||||||
default_config['LinuxPaths'] = {
|
default_config['LinuxPaths'] = {
|
||||||
'storage_path': os.path.abspath(os.path.join(actual_home, ".config/Cursor/User/globalStorage/storage.json")),
|
'storage_path': os.path.abspath(os.path.join(actual_home, ".config/Cursor/User/globalStorage/storage.json")),
|
||||||
'sqlite_path': os.path.abspath(os.path.join(actual_home, ".config/Cursor/User/globalStorage/state.vscdb")),
|
'sqlite_path': os.path.abspath(os.path.join(actual_home, ".config/Cursor/User/globalStorage/state.vscdb")),
|
||||||
'machine_id_path': os.path.expanduser("~/.config/Cursor/machineId")
|
'machine_id_path': os.path.expanduser("~/.config/Cursor/machineId"),
|
||||||
|
'cursor_path': "/opt/Cursor/resources/app" # 默認路徑
|
||||||
}
|
}
|
||||||
|
|
||||||
if os.path.exists(config_file):
|
if os.path.exists(config_file):
|
||||||
@@ -568,9 +572,9 @@ def handle_verification_code(browser_tab, email_tab, controller, email, password
|
|||||||
# 获取验证码,设置超时
|
# 获取验证码,设置超时
|
||||||
verification_code = None
|
verification_code = None
|
||||||
max_attempts = 20
|
max_attempts = 20
|
||||||
retry_interval = float(config.get('Timing', 'retry_interval', fallback='10')) # 使用配置值
|
retry_interval = get_random_wait_time(config, 'retry_interval') # 使用 get_random_wait_time
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
timeout = float(config.get('Timing', 'max_timeout', fallback='160')) # 使用配置值
|
timeout = float(config.get('Timing', 'max_timeout', fallback='160')) # 這個可以保持不變因為是固定值
|
||||||
|
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.CYAN}{translator.get('register.start_getting_verification_code')}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{translator.get('register.start_getting_verification_code')}{Style.RESET_ALL}")
|
||||||
@@ -594,7 +598,7 @@ def handle_verification_code(browser_tab, email_tab, controller, email, password
|
|||||||
|
|
||||||
# 刷新邮箱
|
# 刷新邮箱
|
||||||
email_tab.refresh_inbox()
|
email_tab.refresh_inbox()
|
||||||
time.sleep(get_random_wait_time(config, 'retry_interval')) # 使用 get_random_wait_time
|
time.sleep(retry_interval) # 使用 get_random_wait_time
|
||||||
|
|
||||||
if verification_code:
|
if verification_code:
|
||||||
# 在注册页面填写验证码
|
# 在注册页面填写验证码
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ from colorama import Fore, Style, init
|
|||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
import configparser
|
import configparser
|
||||||
from new_signup import get_user_documents_path
|
from new_signup import get_user_documents_path
|
||||||
|
import traceback
|
||||||
|
|
||||||
# Initialize colorama
|
# Initialize colorama
|
||||||
init()
|
init()
|
||||||
@@ -29,42 +30,45 @@ EMOJI = {
|
|||||||
def get_cursor_paths(translator=None) -> Tuple[str, str]:
|
def get_cursor_paths(translator=None) -> Tuple[str, str]:
|
||||||
""" Get Cursor related paths"""
|
""" Get Cursor related paths"""
|
||||||
system = platform.system()
|
system = platform.system()
|
||||||
|
|
||||||
paths_map = {
|
# 讀取配置文件
|
||||||
"Darwin": {
|
config = configparser.ConfigParser()
|
||||||
"base": "/Applications/Cursor.app/Contents/Resources/app",
|
config_dir = os.path.join(get_user_documents_path(), ".cursor-free-vip")
|
||||||
"package": "package.json",
|
config_file = os.path.join(config_dir, "config.ini")
|
||||||
"main": "out/main.js",
|
|
||||||
},
|
if not os.path.exists(config_file):
|
||||||
"Windows": {
|
raise OSError(translator.get('reset.config_not_found') if translator else "找不到配置文件")
|
||||||
"base": os.path.join(
|
|
||||||
os.getenv("LOCALAPPDATA", ""), "Programs", "Cursor", "resources", "app"
|
config.read(config_file)
|
||||||
),
|
|
||||||
"package": "package.json",
|
# 根據系統獲取路徑
|
||||||
"main": "out/main.js",
|
if system == "Darwin":
|
||||||
},
|
section = 'MacPaths'
|
||||||
"Linux": {
|
elif system == "Windows":
|
||||||
"bases": ["/opt/Cursor/resources/app", "/usr/share/cursor/resources/app"],
|
section = 'WindowsPaths'
|
||||||
"package": "package.json",
|
elif system == "Linux":
|
||||||
"main": "out/main.js",
|
section = 'LinuxPaths'
|
||||||
},
|
else:
|
||||||
}
|
|
||||||
|
|
||||||
if system not in paths_map:
|
|
||||||
raise OSError(translator.get('reset.unsupported_os', system=system) if translator else f"不支持的操作系统: {system}")
|
raise OSError(translator.get('reset.unsupported_os', system=system) if translator else f"不支持的操作系统: {system}")
|
||||||
|
|
||||||
if system == "Linux":
|
if not config.has_section(section) or not config.has_option(section, 'cursor_path'):
|
||||||
for base in paths_map["Linux"]["bases"]:
|
raise OSError(translator.get('reset.path_not_configured') if translator else "未配置 Cursor 路徑")
|
||||||
pkg_path = os.path.join(base, paths_map["Linux"]["package"])
|
|
||||||
if os.path.exists(pkg_path):
|
base_path = config.get(section, 'cursor_path')
|
||||||
return (pkg_path, os.path.join(base, paths_map["Linux"]["main"]))
|
|
||||||
raise OSError(translator.get('reset.linux_path_not_found') if translator else "在 Linux 系统上未找到 Cursor 安装路径")
|
if not os.path.exists(base_path):
|
||||||
|
raise OSError(translator.get('reset.path_not_found', path=base_path) if translator else f"找不到 Cursor 路徑: {base_path}")
|
||||||
base_path = paths_map[system]["base"]
|
|
||||||
return (
|
pkg_path = os.path.join(base_path, "package.json")
|
||||||
os.path.join(base_path, paths_map[system]["package"]),
|
main_path = os.path.join(base_path, "out/main.js")
|
||||||
os.path.join(base_path, paths_map[system]["main"]),
|
|
||||||
)
|
# 檢查文件是否存在
|
||||||
|
if not os.path.exists(pkg_path):
|
||||||
|
raise OSError(translator.get('reset.package_not_found', path=pkg_path) if translator else f"找不到 package.json: {pkg_path}")
|
||||||
|
if not os.path.exists(main_path):
|
||||||
|
raise OSError(translator.get('reset.main_not_found', path=main_path) if translator else f"找不到 main.js: {main_path}")
|
||||||
|
|
||||||
|
return (pkg_path, main_path)
|
||||||
|
|
||||||
def get_cursor_machine_id_path(translator=None) -> str:
|
def get_cursor_machine_id_path(translator=None) -> str:
|
||||||
"""
|
"""
|
||||||
@@ -176,11 +180,60 @@ def check_cursor_version(translator) -> bool:
|
|||||||
"""Check Cursor version"""
|
"""Check Cursor version"""
|
||||||
try:
|
try:
|
||||||
pkg_path, _ = get_cursor_paths(translator)
|
pkg_path, _ = get_cursor_paths(translator)
|
||||||
with open(pkg_path, "r", encoding="utf-8") as f:
|
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('reset.reading_package_json', path=pkg_path)}{Style.RESET_ALL}")
|
||||||
version = json.load(f)["version"]
|
|
||||||
return version_check(version, min_version="0.45.0", translator=translator)
|
try:
|
||||||
|
with open(pkg_path, "r", encoding="utf-8") as f:
|
||||||
|
data = json.load(f)
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
# 如果 UTF-8 讀取失敗,嘗試其他編碼
|
||||||
|
with open(pkg_path, "r", encoding="latin-1") as f:
|
||||||
|
data = json.load(f)
|
||||||
|
|
||||||
|
if not isinstance(data, dict):
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('reset.invalid_json_object')}{Style.RESET_ALL}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if "version" not in data:
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('reset.no_version_field')}{Style.RESET_ALL}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
version = str(data["version"]).strip()
|
||||||
|
if not version:
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('reset.version_field_empty')}{Style.RESET_ALL}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('reset.found_version', version=version)}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
# 檢查版本格式
|
||||||
|
if not re.match(r"^\d+\.\d+\.\d+$", version):
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('reset.invalid_version_format', version=version)}{Style.RESET_ALL}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 比較版本
|
||||||
|
try:
|
||||||
|
current = tuple(map(int, version.split(".")))
|
||||||
|
min_ver = (0, 45, 0) # 直接使用元組而不是字符串
|
||||||
|
|
||||||
|
if current >= min_ver:
|
||||||
|
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('reset.version_check_passed', version=version, min_version='0.45.0')}{Style.RESET_ALL}")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('reset.version_too_low', version=version, min_version='0.45.0')}{Style.RESET_ALL}")
|
||||||
|
return False
|
||||||
|
except ValueError as e:
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('reset.version_parse_error', error=str(e))}{Style.RESET_ALL}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except FileNotFoundError as e:
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('reset.package_not_found', path=pkg_path)}{Style.RESET_ALL}")
|
||||||
|
return False
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('reset.invalid_json_object')}{Style.RESET_ALL}")
|
||||||
|
return False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('reset.check_version_failed', error=str(e))}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('reset.check_version_failed', error=str(e))}{Style.RESET_ALL}")
|
||||||
|
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('reset.stack_trace')}: {traceback.format_exc()}{Style.RESET_ALL}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def modify_workbench_js(file_path: str, translator=None) -> bool:
|
def modify_workbench_js(file_path: str, translator=None) -> bool:
|
||||||
@@ -576,12 +629,12 @@ class MachineIDResetter:
|
|||||||
### Remove In v1.7.02
|
### Remove In v1.7.02
|
||||||
# Check Cursor version and perform corresponding actions
|
# Check Cursor version and perform corresponding actions
|
||||||
|
|
||||||
# greater_than_0_45 = check_cursor_version(self.translator)
|
greater_than_0_45 = check_cursor_version(self.translator)
|
||||||
# if greater_than_0_45:
|
if greater_than_0_45:
|
||||||
# print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('reset.detecting_version')} >= 0.45.0,{self.translator.get('reset.patching_getmachineid')}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('reset.detecting_version')} >= 0.45.0,{self.translator.get('reset.patching_getmachineid')}{Style.RESET_ALL}")
|
||||||
# patch_cursor_get_machine_id(self.translator)
|
patch_cursor_get_machine_id(self.translator)
|
||||||
# else:
|
else:
|
||||||
# print(f"{Fore.YELLOW}{EMOJI['INFO']} {self.translator.get('reset.version_less_than_0_45')}{Style.RESET_ALL}")
|
print(f"{Fore.YELLOW}{EMOJI['INFO']} {self.translator.get('reset.version_less_than_0_45')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('reset.success')}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('reset.success')}{Style.RESET_ALL}")
|
||||||
print(f"\n{Fore.CYAN}{self.translator.get('reset.new_id')}:{Style.RESET_ALL}")
|
print(f"\n{Fore.CYAN}{self.translator.get('reset.new_id')}:{Style.RESET_ALL}")
|
||||||
|
|||||||
@@ -63,8 +63,15 @@ detect_os() {
|
|||||||
echo -e "${CYAN}ℹ️ Detected macOS Intel architecture${NC}"
|
echo -e "${CYAN}ℹ️ Detected macOS Intel architecture${NC}"
|
||||||
fi
|
fi
|
||||||
elif [[ "$(uname)" == "Linux" ]]; then
|
elif [[ "$(uname)" == "Linux" ]]; then
|
||||||
OS="linux"
|
# Detect Linux architecture
|
||||||
echo -e "${CYAN}ℹ️ Detected Linux system${NC}"
|
ARCH=$(uname -m)
|
||||||
|
if [[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]]; then
|
||||||
|
OS="linux_arm64"
|
||||||
|
echo -e "${CYAN}ℹ️ Detected Linux ARM64 architecture${NC}"
|
||||||
|
else
|
||||||
|
OS="linux_x64"
|
||||||
|
echo -e "${CYAN}ℹ️ Detected Linux x64 architecture${NC}"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
# Assume Windows
|
# Assume Windows
|
||||||
OS="windows"
|
OS="windows"
|
||||||
@@ -127,9 +134,19 @@ install_cursor_free_vip() {
|
|||||||
echo -e "${RED}❌ New download link does not exist${NC}"
|
echo -e "${RED}❌ New download link does not exist${NC}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
else
|
} elif [[ "$OS" == "linux_x64" || "$OS" == "linux_arm64" ]]; then
|
||||||
|
OS="linux"
|
||||||
|
binary_name="CursorFreeVIP_${VERSION}_${OS}"
|
||||||
|
download_url="https://github.com/yeongpin/cursor-free-vip/releases/download/v${VERSION}/${binary_name}"
|
||||||
|
echo -e "${CYAN}ℹ️ New download link: ${download_url}${NC}"
|
||||||
|
|
||||||
|
if ! curl --output /dev/null --silent --head --fail "$download_url"; then
|
||||||
|
echo -e "${RED}❌ New download link does not exist${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
} else {
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Download file
|
# Download file
|
||||||
|
|||||||
Reference in New Issue
Block a user