mirror of
https://github.com/yeongpin/cursor-free-vip.git
synced 2025-04-24 08:25:23 +00:00
Update version to 1.11.01 and enhance localization for OAuth profile selection. Added new features including Arabic language support, machine ID restoration from backup, and improved error handling in the update process. Updated menu options and fixed various issues for a better user experience.
This commit is contained in:
parent
296a69bf73
commit
da5bff5994
10
CHANGELOG.md
10
CHANGELOG.md
@ -1,5 +1,15 @@
|
||||
# Change Log
|
||||
|
||||
## v1.11.01
|
||||
1. Restore: Some Main Code | 恢復一些主程式碼
|
||||
2. Add: Arabic language | 增加阿拉伯語
|
||||
3. Add: Language configuration saved setting | 增加語言配置保存設定
|
||||
4. Add: Restore Machine ID from Backup | 增加從備份恢復機器ID
|
||||
5. Add: Owned Website Check Version | 增加擁有網站檢查版本
|
||||
6. Fix: use cursor_path from config_file | 修復使用 cursor_path 從 config_file
|
||||
7. Fix: macOS 'bypass_version.py' get product_json_path from config_file | 修復 macOS 'bypass_version.py' 從 config_file 獲取 product_json_path
|
||||
8. Fix: Some Issues | 修復一些問題
|
||||
|
||||
## v1.10.05
|
||||
1. Remove block_domain.txt | 移除 block_domain.txt
|
||||
2. Original Code In Github , If u afraid of virus, please clone the code and run locally | 原始碼在 Github 上,如果怕病毒,請複製原始碼並在本機運行
|
||||
|
@ -4,8 +4,8 @@
|
||||
"exit": "Exit Program",
|
||||
"reset": "Reset Machine ID",
|
||||
"register": "Register New Cursor Account",
|
||||
"register_google": "Register with Google Account",
|
||||
"register_github": "Register with GitHub Account",
|
||||
"register_google": "Register with Self Google Account",
|
||||
"register_github": "Register with Self GitHub Account",
|
||||
"register_manual": "Register Cursor with Custom Email",
|
||||
"quit": "Close Cursor Application",
|
||||
"select_language": "Change Language",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"exit": "退出程序",
|
||||
"reset": "重置机器ID",
|
||||
"register": "注册新的Cursor账户",
|
||||
"register_google": "使用Google账户注册",
|
||||
"register_github": "使用GitHub账户注册",
|
||||
"register_google": "使用自己的Google账户注册",
|
||||
"register_github": "使用自己的GitHub账户注册",
|
||||
"register_manual": "使用自定义邮箱注册Cursor",
|
||||
"quit": "关闭Cursor应用",
|
||||
"select_language": "更改语言",
|
||||
@ -627,7 +627,9 @@
|
||||
"using_configured_browser_path": "使用配置的 {browser} 路径: {path}",
|
||||
"browser_not_found_trying_chrome": "未找到 {browser},尝试使用 Chrome 代替",
|
||||
"found_chrome_at": "找到 Chrome: {path}",
|
||||
"found_browser_user_data_dir": "找到 {browser} 用户数据目录: {path}"
|
||||
"found_browser_user_data_dir": "找到 {browser} 用户数据目录: {path}",
|
||||
"select_profile": "选择要使用的 {browser} 配置文件:",
|
||||
"profile_list": "可用 {browser} 配置文件:"
|
||||
},
|
||||
"browser_profile": {
|
||||
"title": "浏览器配置文件选择",
|
||||
|
@ -4,8 +4,8 @@
|
||||
"exit": "退出程式",
|
||||
"reset": "重置機器ID",
|
||||
"register": "註冊新的Cursor帳戶",
|
||||
"register_google": "使用Google帳戶註冊",
|
||||
"register_github": "使用GitHub帳戶註冊",
|
||||
"register_google": "使用自己的Google帳戶註冊",
|
||||
"register_github": "使用自己的GitHub帳戶註冊",
|
||||
"register_manual": "使用自定義郵箱註冊Cursor",
|
||||
"quit": "關閉Cursor應用",
|
||||
"select_language": "更改語言",
|
||||
@ -601,7 +601,18 @@
|
||||
"warning_could_not_kill_existing_browser_processes": "警告: 無法殺死現有瀏覽器進程: {error}",
|
||||
"browser_failed_to_start": "瀏覽器啟動失敗: {error}",
|
||||
"browser_failed": "瀏覽器啟動失敗: {error}",
|
||||
"browser_failed_to_start_fallback": "瀏覽器啟動失敗: {error}"
|
||||
"browser_failed_to_start_fallback": "瀏覽器啟動失敗: {error}",
|
||||
"using_configured_browser_path": "使用配置的 {browser} 路徑: {path}",
|
||||
"found_browser_user_data_dir": "找到 {browser} 用戶數據目錄: {path}",
|
||||
"warning_browser_close": "警告:這將關閉所有正在執行的 {browser} 進程",
|
||||
"killing_browser_processes": "正在關閉 {browser} 進程...",
|
||||
"profile_selection_error": "配置文件選擇過程中出錯: {error}",
|
||||
"select_profile": "選擇要使用的 {browser} 配置文件:",
|
||||
"profile_list": "可用 {browser} 配置文件:",
|
||||
"no_profiles": "未找到 {browser} 配置文件",
|
||||
"error_loading": "載入 {browser} 配置文件時出錯:{error}",
|
||||
"profile_selected": "已選擇配置文件:{profile}",
|
||||
"invalid_selection": "選擇無效。請重試"
|
||||
},
|
||||
"chrome_profile": {
|
||||
"title": "Chrome配置檔案選擇",
|
||||
|
2
logo.py
2
logo.py
@ -83,7 +83,7 @@ muhammedfurkan plamkatawe Lucaszmv
|
||||
"""
|
||||
OTHER_INFO_TEXT = f"""{Fore.YELLOW}
|
||||
Github: https://github.com/yeongpin/cursor-free-vip{Fore.RED}
|
||||
Press 8 to change language | 按下 8 键切换语言{Style.RESET_ALL}"""
|
||||
Press 4 to change language | 按下 4 键切换语言{Style.RESET_ALL}"""
|
||||
|
||||
# center display LOGO and DESCRIPTION
|
||||
CURSOR_LOGO = center_multiline_text(LOGO_TEXT, handle_chinese=False)
|
||||
|
123
main.py
123
main.py
@ -366,14 +366,18 @@ def print_menu():
|
||||
2: f"{Fore.GREEN}2{Style.RESET_ALL}. {EMOJI['SUCCESS']} {translator.get('menu.register_manual')}",
|
||||
3: f"{Fore.GREEN}3{Style.RESET_ALL}. {EMOJI['ERROR']} {translator.get('menu.quit')}",
|
||||
4: f"{Fore.GREEN}4{Style.RESET_ALL}. {EMOJI['LANG']} {translator.get('menu.select_language')}",
|
||||
5: f"{Fore.GREEN}5{Style.RESET_ALL}. {EMOJI['UPDATE']} {translator.get('menu.disable_auto_update')}",
|
||||
6: f"{Fore.GREEN}6{Style.RESET_ALL}. {EMOJI['RESET']} {translator.get('menu.totally_reset')}",
|
||||
7: f"{Fore.GREEN}7{Style.RESET_ALL}. {EMOJI['CONTRIBUTE']} {translator.get('menu.contribute')}",
|
||||
8: f"{Fore.GREEN}8{Style.RESET_ALL}. {EMOJI['SETTINGS']} {translator.get('menu.config')}",
|
||||
9: f"{Fore.GREEN}9{Style.RESET_ALL}. {EMOJI['UPDATE']} {translator.get('menu.bypass_version_check', fallback='Bypass Cursor Version Check')}",
|
||||
10: f"{Fore.GREEN}10{Style.RESET_ALL}. {EMOJI['UPDATE']} {translator.get('menu.check_user_authorized', fallback='Check User Authorized')}",
|
||||
11: f"{Fore.GREEN}11{Style.RESET_ALL}. {EMOJI['UPDATE']} {translator.get('menu.bypass_token_limit', fallback='Bypass Token Limit')}",
|
||||
12: f"{Fore.GREEN}12{Style.RESET_ALL}. {EMOJI['BACKUP']} {translator.get('menu.restore_machine_id', fallback='Restore Machine ID from Backup')}"
|
||||
5: f"{Fore.GREEN}5{Style.RESET_ALL}. {EMOJI['SUN']} {translator.get('menu.register_google')}",
|
||||
6: f"{Fore.GREEN}6{Style.RESET_ALL}. {EMOJI['STAR']} {translator.get('menu.register_github')}",
|
||||
7: f"{Fore.GREEN}7{Style.RESET_ALL}. {EMOJI['UPDATE']} {translator.get('menu.disable_auto_update')}",
|
||||
8: f"{Fore.GREEN}8{Style.RESET_ALL}. {EMOJI['RESET']} {translator.get('menu.totally_reset')}",
|
||||
9: f"{Fore.GREEN}9{Style.RESET_ALL}. {EMOJI['CONTRIBUTE']} {translator.get('menu.contribute')}",
|
||||
10: f"{Fore.GREEN}10{Style.RESET_ALL}. {EMOJI['SETTINGS']} {translator.get('menu.config')}",
|
||||
11: f"{Fore.GREEN}11{Style.RESET_ALL}. {EMOJI['UPDATE']} {translator.get('menu.bypass_version_check')}",
|
||||
12: f"{Fore.GREEN}12{Style.RESET_ALL}. {EMOJI['UPDATE']} {translator.get('menu.check_user_authorized')}",
|
||||
13: f"{Fore.GREEN}13{Style.RESET_ALL}. {EMOJI['UPDATE']} {translator.get('menu.bypass_token_limit')}",
|
||||
14: f"{Fore.GREEN}14{Style.RESET_ALL}. {EMOJI['BACKUP']} {translator.get('menu.restore_machine_id')}",
|
||||
15: f"{Fore.GREEN}15{Style.RESET_ALL}. {EMOJI['ERROR']} {translator.get('menu.delete_google_account')}",
|
||||
16: f"{Fore.GREEN}16{Style.RESET_ALL}. {EMOJI['SETTINGS']} {translator.get('menu.select_chrome_profile')}"
|
||||
}
|
||||
|
||||
# Automatically calculate the number of menu items in the left and right columns
|
||||
@ -496,31 +500,67 @@ def check_latest_version():
|
||||
try:
|
||||
print(f"\n{Fore.CYAN}{EMOJI['UPDATE']} {translator.get('updater.checking')}{Style.RESET_ALL}")
|
||||
|
||||
# Get latest version from GitHub API with timeout and proper headers
|
||||
# First try GitHub API
|
||||
headers = {
|
||||
'Accept': 'application/vnd.github.v3+json',
|
||||
'User-Agent': 'CursorFreeVIP-Updater'
|
||||
}
|
||||
response = requests.get(
|
||||
"https://api.github.com/repos/yeongpin/cursor-free-vip/releases/latest",
|
||||
headers=headers,
|
||||
timeout=10
|
||||
)
|
||||
|
||||
# Check if rate limit exceeded
|
||||
if response.status_code == 403 and "rate limit exceeded" in response.text.lower():
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('updater.rate_limit_exceeded', fallback='GitHub API rate limit exceeded. Skipping update check.')}{Style.RESET_ALL}")
|
||||
return
|
||||
latest_version = None
|
||||
github_error = None
|
||||
|
||||
# Check if response is successful
|
||||
if response.status_code != 200:
|
||||
raise Exception(f"GitHub API returned status code {response.status_code}")
|
||||
# Try GitHub API first
|
||||
try:
|
||||
github_response = requests.get(
|
||||
"https://api.github.com/repos/yeongpin/cursor-free-vip/releases/latest",
|
||||
headers=headers,
|
||||
timeout=10
|
||||
)
|
||||
|
||||
response_data = response.json()
|
||||
if "tag_name" not in response_data:
|
||||
raise Exception("No version tag found in GitHub response")
|
||||
# Check if rate limit exceeded
|
||||
if github_response.status_code == 403 and "rate limit exceeded" in github_response.text.lower():
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('updater.rate_limit_exceeded', fallback='GitHub API rate limit exceeded. Trying backup API...')}{Style.RESET_ALL}")
|
||||
raise Exception("Rate limit exceeded")
|
||||
|
||||
latest_version = response_data["tag_name"].lstrip('v')
|
||||
# Check if response is successful
|
||||
if github_response.status_code != 200:
|
||||
raise Exception(f"GitHub API returned status code {github_response.status_code}")
|
||||
|
||||
github_data = github_response.json()
|
||||
if "tag_name" not in github_data:
|
||||
raise Exception("No version tag found in GitHub response")
|
||||
|
||||
latest_version = github_data["tag_name"].lstrip('v')
|
||||
|
||||
except Exception as e:
|
||||
github_error = str(e)
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('updater.github_api_failed', fallback='GitHub API failed, trying backup API...')}{Style.RESET_ALL}")
|
||||
|
||||
# If GitHub API fails, try backup API
|
||||
try:
|
||||
backup_headers = {
|
||||
'Accept': 'application/json',
|
||||
'User-Agent': 'CursorFreeVIP-Updater'
|
||||
}
|
||||
backup_response = requests.get(
|
||||
"https://pinnumber.rr.nu/badges/release/yeongpin/cursor-free-vip",
|
||||
headers=backup_headers,
|
||||
timeout=10
|
||||
)
|
||||
|
||||
# Check if response is successful
|
||||
if backup_response.status_code != 200:
|
||||
raise Exception(f"Backup API returned status code {backup_response.status_code}")
|
||||
|
||||
backup_data = backup_response.json()
|
||||
if "message" not in backup_data:
|
||||
raise Exception("No version tag found in backup API response")
|
||||
|
||||
latest_version = backup_data["message"].lstrip('v')
|
||||
|
||||
except Exception as backup_e:
|
||||
# If both APIs fail, raise the original GitHub error
|
||||
raise Exception(f"Both APIs failed. GitHub error: {github_error}, Backup error: {str(backup_e)}")
|
||||
|
||||
# Validate version format
|
||||
if not latest_version:
|
||||
@ -670,7 +710,7 @@ def main():
|
||||
|
||||
while True:
|
||||
try:
|
||||
choice_num = 12
|
||||
choice_num = 16
|
||||
choice = input(f"\n{EMOJI['ARROW']} {Fore.CYAN}{translator.get('menu.input_choice', choices=f'0-{choice_num}')}: {Style.RESET_ALL}")
|
||||
|
||||
match choice:
|
||||
@ -695,38 +735,55 @@ def main():
|
||||
print_menu()
|
||||
continue
|
||||
case "5":
|
||||
from oauth_auth import main as oauth_main
|
||||
oauth_main('google',translator)
|
||||
print_menu()
|
||||
case "6":
|
||||
from oauth_auth import main as oauth_main
|
||||
oauth_main('github',translator)
|
||||
print_menu()
|
||||
case "7":
|
||||
import disable_auto_update
|
||||
disable_auto_update.run(translator)
|
||||
print_menu()
|
||||
case "6":
|
||||
case "8":
|
||||
import totally_reset_cursor
|
||||
totally_reset_cursor.run(translator)
|
||||
# print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.fixed_soon')}{Style.RESET_ALL}")
|
||||
print_menu()
|
||||
case "7":
|
||||
case "9":
|
||||
import logo
|
||||
print(logo.CURSOR_CONTRIBUTORS)
|
||||
print_menu()
|
||||
case "8":
|
||||
case "10":
|
||||
from config import print_config
|
||||
print_config(get_config(), translator)
|
||||
print_menu()
|
||||
case "9":
|
||||
case "11":
|
||||
import bypass_version
|
||||
bypass_version.main(translator)
|
||||
print_menu()
|
||||
case "10":
|
||||
case "12":
|
||||
import check_user_authorized
|
||||
check_user_authorized.main(translator)
|
||||
print_menu()
|
||||
case "11":
|
||||
case "13":
|
||||
import bypass_token_limit
|
||||
bypass_token_limit.run(translator)
|
||||
print_menu()
|
||||
case "12":
|
||||
case "14":
|
||||
import restore_machine_id
|
||||
restore_machine_id.run(translator)
|
||||
print_menu()
|
||||
case "15":
|
||||
import delete_cursor_google
|
||||
delete_cursor_google.main(translator)
|
||||
print_menu()
|
||||
case "16":
|
||||
from oauth_auth import OAuthHandler
|
||||
oauth = OAuthHandler(translator)
|
||||
oauth._select_profile()
|
||||
print_menu()
|
||||
case _:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.invalid_choice')}{Style.RESET_ALL}")
|
||||
print_menu()
|
||||
|
@ -74,8 +74,8 @@ class OAuthHandler:
|
||||
|
||||
if self.translator:
|
||||
# 动态使用浏览器类型
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('browser_profile.select_profile', browser=browser_type_display)}{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{self.translator.get('browser_profile.profile_list', browser=browser_type_display)}{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('oauth.select_profile', browser=browser_type_display)}{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{self.translator.get('oauth.profile_list', browser=browser_type_display)}{Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} Select {browser_type_display} profile to use:{Style.RESET_ALL}")
|
||||
print(f"Available {browser_type_display} profiles:")
|
||||
@ -125,31 +125,31 @@ class OAuthHandler:
|
||||
self.selected_profile = selected_profile
|
||||
|
||||
if self.translator:
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('browser_profile.profile_selected', profile=selected_profile)}{Style.RESET_ALL}")
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('oauth.profile_selected', profile=selected_profile)}{Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Selected profile: {selected_profile}{Style.RESET_ALL}")
|
||||
return True
|
||||
else:
|
||||
if self.translator:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('browser_profile.invalid_selection')}{Style.RESET_ALL}")
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('oauth.invalid_selection')}{Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Invalid selection. Please try again.{Style.RESET_ALL}")
|
||||
return self._select_profile()
|
||||
except ValueError:
|
||||
if self.translator:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('browser_profile.invalid_selection')}{Style.RESET_ALL}")
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('oauth.invalid_selection')}{Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Invalid selection. Please try again.{Style.RESET_ALL}")
|
||||
return self._select_profile()
|
||||
else:
|
||||
# No Local State file, use Default profile
|
||||
print(f"{Fore.YELLOW}{EMOJI['WARNING']} {self.translator.get('browser_profile.no_profiles', browser=browser_type_display) if self.translator else f'No {browser_type_display} profiles found'}{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['WARNING']} {self.translator.get('oauth.no_profiles', browser=browser_type_display) if self.translator else f'No {browser_type_display} profiles found'}{Style.RESET_ALL}")
|
||||
self.selected_profile = "Default"
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
# Error loading profiles, use Default profile
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('browser_profile.error_loading', error=str(e), browser=browser_type_display) if self.translator else f'Error loading {browser_type_display} profiles: {str(e)}'}{Style.RESET_ALL}")
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('oauth.error_loading', error=str(e), browser=browser_type_display) if self.translator else f'Error loading {browser_type_display} profiles: {str(e)}'}{Style.RESET_ALL}")
|
||||
self.selected_profile = "Default"
|
||||
return True
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user