mirror of
https://git.axenov.dev/mirrors/cursor-free-vip.git
synced 2026-01-03 09:19:27 +03:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cce3025f7f | ||
|
|
fe3e27561b | ||
|
|
bf2bea71eb | ||
|
|
77a61647dd | ||
|
|
813dd4431e | ||
|
|
d7116b8cf3 | ||
|
|
f5a7acc4e3 | ||
|
|
479933844a | ||
|
|
93046d7f03 | ||
|
|
e7ca31b710 |
2
.github/workflows/build.yml
vendored
2
.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.4.01'
|
default: '1.4.07'
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
|
|||||||
14
CHANGELOG.md
14
CHANGELOG.md
@@ -1,5 +1,19 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## v1.5.02
|
||||||
|
1. Add: Generate Random Name Alias | 增加生成隨機真實姓名
|
||||||
|
2. Add: Realistic Name Input | 增加真實姓名輸入
|
||||||
|
3. Optimize: Error Handling | 優化錯誤處理
|
||||||
|
4. Optimize: Translation | 優化翻譯
|
||||||
|
5. Optimize: Performance | 優化性能
|
||||||
|
|
||||||
|
## v1.5.01
|
||||||
|
1. Add: Check Latest Version | 增加檢查最新版本
|
||||||
|
2. Add: Update Command | 增加更新命令
|
||||||
|
|
||||||
|
## v1.4.08
|
||||||
|
1. Add: Print Some Account Info | 增加打印一些賬號信息
|
||||||
|
|
||||||
## v1.4.07
|
## v1.4.07
|
||||||
1. Add Removed break statements after each operation | 修改結束event後的break暫停應用
|
1. Add Removed break statements after each operation | 修改結束event後的break暫停應用
|
||||||
2. Added print_menu() calls to show the menu again | 添加print_menu()調用以再次顯示菜單
|
2. Added print_menu() calls to show the menu again | 添加print_menu()調用以再次顯示菜單
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# ➤ Cursor Free VIP
|
# ➤ Cursor Free VIP
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="./images/logo.png" alt="Cursor Pro Logo" width="200"/>
|
<img src="./images/logo.png" alt="Cursor Pro Logo" width="200" style="border-radius: 6px;"/>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@@ -19,7 +19,7 @@ This is a tool to automatically register , support Windows and macOS systems, co
|
|||||||
這是一個自動化工具,自動註冊 ,支持 Windows 和 macOS 系統,完成Auth驗證,重置Cursor的配置。
|
這是一個自動化工具,自動註冊 ,支持 Windows 和 macOS 系統,完成Auth驗證,重置Cursor的配置。
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="./images/pronew_2025-02-13_15-01-32.png" alt="new" width="400"/><br>
|
<img src="./images/new_2025-02-27_10-42-44.png" alt="new" width="400" style="border-radius: 6px;"/><br>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
##### If you dont have google chrome , you can download it from [here](https://www.google.com/intl/en_pk/chrome/)
|
##### If you dont have google chrome , you can download it from [here](https://www.google.com/intl/en_pk/chrome/)
|
||||||
|
|||||||
59
control.py
59
control.py
@@ -45,65 +45,6 @@ class BrowserControl:
|
|||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('control.create_new_tab_failed', error=str(e))}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('control.create_new_tab_failed', error=str(e))}{Style.RESET_ALL}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def switch_to_tab(self, browser):
|
|
||||||
"""切换到指定浏览器窗口"""
|
|
||||||
try:
|
|
||||||
self.browser = browser
|
|
||||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('control.switch_tab_success')}{Style.RESET_ALL}")
|
|
||||||
return True
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('control.switch_tab_failed', error=str(e))}{Style.RESET_ALL}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_current_tab(self):
|
|
||||||
"""获取当前标签页"""
|
|
||||||
return self.browser
|
|
||||||
|
|
||||||
def wait_for_page_load(self, seconds=2):
|
|
||||||
"""等待页面加载"""
|
|
||||||
time.sleep(seconds)
|
|
||||||
|
|
||||||
def navigate_to(self, url):
|
|
||||||
"""导航到指定URL"""
|
|
||||||
try:
|
|
||||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('control.navigate_to', url=url)}...{Style.RESET_ALL}")
|
|
||||||
self.browser.get(url)
|
|
||||||
self.wait_for_page_load()
|
|
||||||
return True
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('control.browser_error', error=str(e))}{Style.RESET_ALL}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_verification_code(self):
|
|
||||||
"""从邮件中获取验证码"""
|
|
||||||
try:
|
|
||||||
# 尝试所有可能的样式组合
|
|
||||||
selectors = [
|
|
||||||
# 新样式
|
|
||||||
'xpath://div[contains(@style, "font-family:-apple-system") and contains(@style, "font-size:28px") and contains(@style, "letter-spacing:2px") and contains(@style, "color:#202020")]',
|
|
||||||
# 带行高的样式
|
|
||||||
'xpath://div[contains(@style, "font-size:28px") and contains(@style, "letter-spacing:2px") and contains(@style, "line-height:30px")]',
|
|
||||||
# rgba 颜色样式
|
|
||||||
'xpath://div[contains(@style, "font-size: 28px") and contains(@style, "letter-spacing: 2px") and contains(@style, "color: rgba(32, 32, 32, 1)")]',
|
|
||||||
# 宽松样式
|
|
||||||
'xpath://div[contains(@style, "font-size:28px") and contains(@style, "letter-spacing:2px")]'
|
|
||||||
]
|
|
||||||
|
|
||||||
# 依次尝试每个选择器
|
|
||||||
for selector in selectors:
|
|
||||||
code_div = self.browser.ele(selector)
|
|
||||||
if code_div:
|
|
||||||
verification_code = code_div.text.strip()
|
|
||||||
if verification_code.isdigit() and len(verification_code) == 6:
|
|
||||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('control.found_verification_code')}: {verification_code}{Style.RESET_ALL}")
|
|
||||||
return verification_code
|
|
||||||
|
|
||||||
print(f"{Fore.YELLOW}{EMOJI['ERROR']} {self.translator.get('control.no_valid_verification_code')}{Style.RESET_ALL}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('control.get_verification_code_error', error=str(e))}{Style.RESET_ALL}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def fill_verification_code(self, code):
|
def fill_verification_code(self, code):
|
||||||
"""填写验证码"""
|
"""填写验证码"""
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ from reset_machine_manual import MachineIDResetter
|
|||||||
os.environ["PYTHONVERBOSE"] = "0"
|
os.environ["PYTHONVERBOSE"] = "0"
|
||||||
os.environ["PYINSTALLER_VERBOSE"] = "0"
|
os.environ["PYINSTALLER_VERBOSE"] = "0"
|
||||||
|
|
||||||
# 初始化colorama
|
# Initialize colorama
|
||||||
init()
|
init()
|
||||||
|
|
||||||
# 定义emoji常量
|
# Define emoji constants
|
||||||
EMOJI = {
|
EMOJI = {
|
||||||
'START': '🚀',
|
'START': '🚀',
|
||||||
'FORM': '📝',
|
'FORM': '📝',
|
||||||
@@ -33,7 +33,7 @@ EMOJI = {
|
|||||||
class CursorRegistration:
|
class CursorRegistration:
|
||||||
def __init__(self, translator=None):
|
def __init__(self, translator=None):
|
||||||
self.translator = translator
|
self.translator = translator
|
||||||
# 设置为显示模式
|
# Set to display mode
|
||||||
os.environ['BROWSER_HEADLESS'] = 'False'
|
os.environ['BROWSER_HEADLESS'] = 'False'
|
||||||
self.browser_manager = BrowserManager()
|
self.browser_manager = BrowserManager()
|
||||||
self.browser = None
|
self.browser = None
|
||||||
@@ -47,38 +47,49 @@ class CursorRegistration:
|
|||||||
|
|
||||||
# 账号信息
|
# 账号信息
|
||||||
self.password = self._generate_password()
|
self.password = self._generate_password()
|
||||||
self.first_name = self._generate_name()
|
# Generate first name and last name separately
|
||||||
self.last_name = self._generate_name()
|
first_name = random.choice([
|
||||||
|
"James", "John", "Robert", "Michael", "William", "David", "Joseph", "Thomas",
|
||||||
|
"Emma", "Olivia", "Ava", "Isabella", "Sophia", "Mia", "Charlotte", "Amelia",
|
||||||
|
"Liam", "Noah", "Oliver", "Elijah", "Lucas", "Mason", "Logan", "Alexander"
|
||||||
|
])
|
||||||
|
self.last_name = random.choice([
|
||||||
|
"Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis",
|
||||||
|
"Anderson", "Wilson", "Taylor", "Thomas", "Moore", "Martin", "Jackson", "Lee",
|
||||||
|
"Thompson", "White", "Harris", "Clark", "Lewis", "Walker", "Hall", "Young"
|
||||||
|
])
|
||||||
|
|
||||||
|
# Modify first letter of first name
|
||||||
|
new_first_letter = random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||||
|
self.first_name = new_first_letter + first_name[1:]
|
||||||
|
|
||||||
|
print(f"\n{Fore.CYAN}{EMOJI['PASSWORD']} {self.translator.get('register.password')}: {self.password} {Style.RESET_ALL}")
|
||||||
|
print(f"{Fore.CYAN}{EMOJI['FORM']} {self.translator.get('register.first_name')}: {self.first_name} {Style.RESET_ALL}")
|
||||||
|
print(f"{Fore.CYAN}{EMOJI['FORM']} {self.translator.get('register.last_name')}: {self.last_name} {Style.RESET_ALL}")
|
||||||
|
|
||||||
def _generate_password(self, length=12):
|
def _generate_password(self, length=12):
|
||||||
"""Generate Random Password"""
|
"""Generate Random Password"""
|
||||||
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*"
|
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*"
|
||||||
return ''.join(random.choices(chars, k=length))
|
return ''.join(random.choices(chars, k=length))
|
||||||
|
|
||||||
def _generate_name(self, length=6):
|
|
||||||
"""Generate Random Name"""
|
|
||||||
first_letter = random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
|
||||||
rest_letters = ''.join(random.choices("abcdefghijklmnopqrstuvwxyz", k=length-1))
|
|
||||||
return first_letter + rest_letters
|
|
||||||
|
|
||||||
def setup_email(self):
|
def setup_email(self):
|
||||||
"""设置邮箱"""
|
"""Setup Email"""
|
||||||
try:
|
try:
|
||||||
print(f"{Fore.CYAN}{EMOJI['START']} {self.translator.get('register.browser_start')}...{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{EMOJI['START']} {self.translator.get('register.browser_start')}...{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 使用 new_tempemail 创建临时邮箱,传入 translator
|
# Create a temporary email using new_tempemail, passing translator
|
||||||
from new_tempemail import NewTempEmail
|
from new_tempemail import NewTempEmail
|
||||||
self.temp_email = NewTempEmail(self.translator) # 传入 translator
|
self.temp_email = NewTempEmail(self.translator) # Pass translator
|
||||||
|
|
||||||
# 创建临时邮箱
|
# Create a temporary email
|
||||||
email_address = self.temp_email.create_email()
|
email_address = self.temp_email.create_email()
|
||||||
if not email_address:
|
if not email_address:
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.email_create_failed')}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.email_create_failed')}{Style.RESET_ALL}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# 保存邮箱地址
|
# Save email address
|
||||||
self.email_address = email_address
|
self.email_address = email_address
|
||||||
self.email_tab = self.temp_email # 传递 NewTempEmail 实例
|
self.email_tab = self.temp_email # Pass NewTempEmail instance
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -92,10 +103,10 @@ class CursorRegistration:
|
|||||||
try:
|
try:
|
||||||
print(f"{Fore.CYAN}{EMOJI['START']} {self.translator.get('register.register_start')}...{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{EMOJI['START']} {self.translator.get('register.register_start')}...{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 直接使用 new_signup.py 进行注册
|
# Directly use new_signup.py to sign up
|
||||||
from new_signup import main as new_signup_main
|
from new_signup import main as new_signup_main
|
||||||
|
|
||||||
# 执行新的注册流程,传入 translator
|
# Execute the new registration process, passing translator
|
||||||
result, browser_tab = new_signup_main(
|
result, browser_tab = new_signup_main(
|
||||||
email=self.email_address,
|
email=self.email_address,
|
||||||
password=self.password,
|
password=self.password,
|
||||||
@@ -107,11 +118,11 @@ class CursorRegistration:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
# 使用返回的浏览器实例获取账户信息
|
# Use the returned browser instance to get account information
|
||||||
self.signup_tab = browser_tab # 保存浏览器实例
|
self.signup_tab = browser_tab # Save browser instance
|
||||||
success = self._get_account_info()
|
success = self._get_account_info()
|
||||||
|
|
||||||
# 获取信息后关闭浏览器
|
# Close browser after getting information
|
||||||
if browser_tab:
|
if browser_tab:
|
||||||
try:
|
try:
|
||||||
browser_tab.quit()
|
browser_tab.quit()
|
||||||
@@ -126,7 +137,7 @@ class CursorRegistration:
|
|||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.register_process_error', error=str(e))}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.register_process_error', error=str(e))}{Style.RESET_ALL}")
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
# 确保在任何情况下都关闭浏览器
|
# Ensure browser is closed in any case
|
||||||
if browser_tab:
|
if browser_tab:
|
||||||
try:
|
try:
|
||||||
browser_tab.quit()
|
browser_tab.quit()
|
||||||
@@ -134,7 +145,7 @@ class CursorRegistration:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def _get_account_info(self):
|
def _get_account_info(self):
|
||||||
"""获取账户信息和 Token"""
|
"""Get Account Information and Token"""
|
||||||
try:
|
try:
|
||||||
self.signup_tab.get(self.settings_url)
|
self.signup_tab.get(self.settings_url)
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
@@ -149,6 +160,7 @@ class CursorRegistration:
|
|||||||
if usage_ele:
|
if usage_ele:
|
||||||
total_usage = usage_ele.text.split("/")[-1].strip()
|
total_usage = usage_ele.text.split("/")[-1].strip()
|
||||||
|
|
||||||
|
print(f"Total Usage: {total_usage}\n")
|
||||||
print(f"{Fore.CYAN}{EMOJI['WAIT']} {self.translator.get('register.get_token')}...{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{EMOJI['WAIT']} {self.translator.get('register.get_token')}...{Style.RESET_ALL}")
|
||||||
max_attempts = 30
|
max_attempts = 30
|
||||||
retry_interval = 2
|
retry_interval = 2
|
||||||
@@ -185,7 +197,7 @@ class CursorRegistration:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def _save_account_info(self, token, total_usage):
|
def _save_account_info(self, token, total_usage):
|
||||||
"""保存账户信息到文件"""
|
"""Save Account Information to File"""
|
||||||
try:
|
try:
|
||||||
# 先更新认证信息
|
# 先更新认证信息
|
||||||
print(f"{Fore.CYAN}{EMOJI['KEY']} {self.translator.get('register.update_cursor_auth_info')}...{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{EMOJI['KEY']} {self.translator.get('register.update_cursor_auth_info')}...{Style.RESET_ALL}")
|
||||||
@@ -200,7 +212,7 @@ class CursorRegistration:
|
|||||||
if not resetter.reset_machine_ids(): # 直接调用reset_machine_ids方法
|
if not resetter.reset_machine_ids(): # 直接调用reset_machine_ids方法
|
||||||
raise Exception("Failed to reset machine ID")
|
raise Exception("Failed to reset machine ID")
|
||||||
|
|
||||||
# 保存账户信息到文件
|
# Save account information to file
|
||||||
with open('cursor_accounts.txt', 'a', encoding='utf-8') as f:
|
with open('cursor_accounts.txt', 'a', encoding='utf-8') as f:
|
||||||
f.write(f"\n{'='*50}\n")
|
f.write(f"\n{'='*50}\n")
|
||||||
f.write(f"Email: {self.email_address}\n")
|
f.write(f"Email: {self.email_address}\n")
|
||||||
@@ -217,7 +229,7 @@ class CursorRegistration:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
"""启动注册流程"""
|
"""Start Registration Process"""
|
||||||
try:
|
try:
|
||||||
if self.setup_email():
|
if self.setup_email():
|
||||||
if self.register_cursor():
|
if self.register_cursor():
|
||||||
@@ -225,7 +237,7 @@ class CursorRegistration:
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
# 关闭邮箱标签页
|
# Close email tab
|
||||||
if hasattr(self, 'temp_email'):
|
if hasattr(self, 'temp_email'):
|
||||||
try:
|
try:
|
||||||
self.temp_email.close()
|
self.temp_email.close()
|
||||||
@@ -233,7 +245,7 @@ class CursorRegistration:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def update_cursor_auth(self, email=None, access_token=None, refresh_token=None):
|
def update_cursor_auth(self, email=None, access_token=None, refresh_token=None):
|
||||||
"""更新Cursor的认证信息的便捷函数"""
|
"""Update Cursor Auth Info"""
|
||||||
auth_manager = CursorAuth(translator=self.translator)
|
auth_manager = CursorAuth(translator=self.translator)
|
||||||
return auth_manager.update_auth(email, access_token, refresh_token)
|
return auth_manager.update_auth(email, access_token, refresh_token)
|
||||||
|
|
||||||
|
|||||||
@@ -44,22 +44,33 @@ class CursorRegistration:
|
|||||||
self.signup_tab = None
|
self.signup_tab = None
|
||||||
self.email_tab = None
|
self.email_tab = None
|
||||||
|
|
||||||
# Account information
|
# Generate account information
|
||||||
self.password = self._generate_password()
|
self.password = self._generate_password()
|
||||||
self.first_name = self._generate_name()
|
# Generate first name and last name separately
|
||||||
self.last_name = self._generate_name()
|
first_name = random.choice([
|
||||||
|
"James", "John", "Robert", "Michael", "William", "David", "Joseph", "Thomas",
|
||||||
|
"Emma", "Olivia", "Ava", "Isabella", "Sophia", "Mia", "Charlotte", "Amelia",
|
||||||
|
"Liam", "Noah", "Oliver", "Elijah", "Lucas", "Mason", "Logan", "Alexander"
|
||||||
|
])
|
||||||
|
self.last_name = random.choice([
|
||||||
|
"Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis",
|
||||||
|
"Anderson", "Wilson", "Taylor", "Thomas", "Moore", "Martin", "Jackson", "Lee",
|
||||||
|
"Thompson", "White", "Harris", "Clark", "Lewis", "Walker", "Hall", "Young"
|
||||||
|
])
|
||||||
|
|
||||||
|
# Modify first letter of first name
|
||||||
|
new_first_letter = random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||||
|
self.first_name = new_first_letter + first_name[1:]
|
||||||
|
|
||||||
|
print(f"\n{Fore.CYAN}{EMOJI['PASSWORD']} {self.translator.get('register.password')}: {self.password} {Style.RESET_ALL}")
|
||||||
|
print(f"{Fore.CYAN}{EMOJI['FORM']} {self.translator.get('register.first_name')}: {self.first_name} {Style.RESET_ALL}")
|
||||||
|
print(f"{Fore.CYAN}{EMOJI['FORM']} {self.translator.get('register.last_name')}: {self.last_name} {Style.RESET_ALL}")
|
||||||
|
|
||||||
def _generate_password(self, length=12):
|
def _generate_password(self, length=12):
|
||||||
"""Generate Random Password"""
|
"""Generate Random Password"""
|
||||||
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*"
|
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*"
|
||||||
return ''.join(random.choices(chars, k=length))
|
return ''.join(random.choices(chars, k=length))
|
||||||
|
|
||||||
def _generate_name(self, length=6):
|
|
||||||
"""Generate Random Name"""
|
|
||||||
first_letter = random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
|
||||||
rest_letters = ''.join(random.choices("abcdefghijklmnopqrstuvwxyz", k=length-1))
|
|
||||||
return first_letter + rest_letters
|
|
||||||
|
|
||||||
def setup_email(self):
|
def setup_email(self):
|
||||||
"""Setup Email"""
|
"""Setup Email"""
|
||||||
try:
|
try:
|
||||||
@@ -70,6 +81,7 @@ class CursorRegistration:
|
|||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.invalid_email') if self.translator else '无效的邮箱地址'}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.invalid_email') if self.translator else '无效的邮箱地址'}{Style.RESET_ALL}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
print(f"{Fore.CYAN}{EMOJI['MAIL']} {self.translator.get('register.email_address')}: {self.email_address}\n{Style.RESET_ALL}")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -155,6 +167,7 @@ class CursorRegistration:
|
|||||||
if usage_ele:
|
if usage_ele:
|
||||||
total_usage = usage_ele.text.split("/")[-1].strip()
|
total_usage = usage_ele.text.split("/")[-1].strip()
|
||||||
|
|
||||||
|
print(f"Total Usage: {total_usage}\n")
|
||||||
print(f"{Fore.CYAN}{EMOJI['WAIT']} {self.translator.get('register.get_token')}...{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{EMOJI['WAIT']} {self.translator.get('register.get_token')}...{Style.RESET_ALL}")
|
||||||
max_attempts = 30
|
max_attempts = 30
|
||||||
retry_interval = 2
|
retry_interval = 2
|
||||||
|
|||||||
BIN
images/new_2025-02-27_10-42-44.png
Normal file
BIN
images/new_2025-02-27_10-42-44.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 116 KiB |
@@ -131,7 +131,12 @@
|
|||||||
"register_process_error": "Register Process Error: {error}",
|
"register_process_error": "Register Process Error: {error}",
|
||||||
"setting_password": "Setting Password",
|
"setting_password": "Setting Password",
|
||||||
"manual_code_input": "Manual Code Input",
|
"manual_code_input": "Manual Code Input",
|
||||||
"manual_email_input": "Manual Email Input"
|
"manual_email_input": "Manual Email Input",
|
||||||
|
"password": "Password",
|
||||||
|
"first_name": "First Name",
|
||||||
|
"last_name": "Last Name",
|
||||||
|
"exit_signal": "Exit Signal",
|
||||||
|
"email_address": "Email Address"
|
||||||
},
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"title": "Cursor Auth Manager",
|
"title": "Cursor Auth Manager",
|
||||||
@@ -233,5 +238,13 @@
|
|||||||
"directory_removed": "Directory Removed",
|
"directory_removed": "Directory Removed",
|
||||||
"creating_block_file": "Creating Block File",
|
"creating_block_file": "Creating Block File",
|
||||||
"block_file_created": "Block File Created"
|
"block_file_created": "Block File Created"
|
||||||
|
},
|
||||||
|
"updater": {
|
||||||
|
"checking": "Checking for updates...",
|
||||||
|
"new_version_available": "New version available! (Current: {current}, Latest: {latest})",
|
||||||
|
"updating": "Updating to the latest version. The program will restart automatically.",
|
||||||
|
"up_to_date": "You are using the latest version.",
|
||||||
|
"check_failed": "Failed to check for updates: {error}",
|
||||||
|
"continue_anyway": "Continuing with current version..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,12 @@
|
|||||||
"update_cursor_auth_info": "更新Cursor认证信息",
|
"update_cursor_auth_info": "更新Cursor认证信息",
|
||||||
"setting_password": "设置密码",
|
"setting_password": "设置密码",
|
||||||
"manual_code_input": "手动输入验证码",
|
"manual_code_input": "手动输入验证码",
|
||||||
"manual_email_input": "手动输入邮箱"
|
"manual_email_input": "手动输入邮箱",
|
||||||
|
"password": "密码",
|
||||||
|
"first_name": "名字",
|
||||||
|
"last_name": "姓氏",
|
||||||
|
"exit_signal": "退出信号",
|
||||||
|
"email_address": "邮箱地址"
|
||||||
},
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"title": "Cursor 认证管理器",
|
"title": "Cursor 认证管理器",
|
||||||
@@ -230,5 +235,13 @@
|
|||||||
"directory_removed": "目录已删除",
|
"directory_removed": "目录已删除",
|
||||||
"creating_block_file": "创建阻止文件",
|
"creating_block_file": "创建阻止文件",
|
||||||
"block_file_created": "阻止文件已创建"
|
"block_file_created": "阻止文件已创建"
|
||||||
|
},
|
||||||
|
"updater": {
|
||||||
|
"checking": "检查更新...",
|
||||||
|
"new_version_available": "有新版本可用! (当前版本: {current}, 最新版本: {latest})",
|
||||||
|
"updating": "正在更新到最新版本。程序将自动重启。",
|
||||||
|
"up_to_date": "您使用的是最新版本。",
|
||||||
|
"check_failed": "检查更新失败: {error}",
|
||||||
|
"continue_anyway": "继续使用当前版本..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,7 +112,12 @@
|
|||||||
"update_cursor_auth_info": "更新Cursor認證信息",
|
"update_cursor_auth_info": "更新Cursor認證信息",
|
||||||
"setting_password": "設置密碼",
|
"setting_password": "設置密碼",
|
||||||
"manual_code_input": "手動輸入驗證碼",
|
"manual_code_input": "手動輸入驗證碼",
|
||||||
"manual_email_input": "手動輸入郵箱地址"
|
"manual_email_input": "手動輸入郵箱地址",
|
||||||
|
"password": "密碼",
|
||||||
|
"first_name": "名字",
|
||||||
|
"last_name": "姓氏",
|
||||||
|
"exit_signal": "退出信號",
|
||||||
|
"email_address": "郵箱地址"
|
||||||
},
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"title": "Cursor 認證管理器",
|
"title": "Cursor 認證管理器",
|
||||||
@@ -211,5 +216,13 @@
|
|||||||
"directory_removed": "目錄已刪除",
|
"directory_removed": "目錄已刪除",
|
||||||
"creating_block_file": "創建阻止文件",
|
"creating_block_file": "創建阻止文件",
|
||||||
"block_file_created": "阻止文件已創建"
|
"block_file_created": "阻止文件已創建"
|
||||||
|
},
|
||||||
|
"updater": {
|
||||||
|
"checking": "檢查更新...",
|
||||||
|
"new_version_available": "有新版本可用! (當前版本: {current}, 最新版本: {latest})",
|
||||||
|
"updating": "正在更新到最新版本。程序將自動重啟。",
|
||||||
|
"up_to_date": "您使用的是最新版本。",
|
||||||
|
"check_failed": "檢查更新失敗: {error}",
|
||||||
|
"continue_anyway": "繼續使用當前版本..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
35
main.py
35
main.py
@@ -3,10 +3,12 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
from logo import print_logo
|
from logo import print_logo, version
|
||||||
from colorama import Fore, Style, init
|
from colorama import Fore, Style, init
|
||||||
import locale
|
import locale
|
||||||
import platform
|
import platform
|
||||||
|
import requests
|
||||||
|
import subprocess
|
||||||
|
|
||||||
# 只在 Windows 系统上导入 windll
|
# 只在 Windows 系统上导入 windll
|
||||||
if platform.system() == 'Windows':
|
if platform.system() == 'Windows':
|
||||||
@@ -203,8 +205,39 @@ def select_language():
|
|||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.invalid_choice')}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.invalid_choice')}{Style.RESET_ALL}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def check_latest_version():
|
||||||
|
"""Check if current version matches the latest release version"""
|
||||||
|
try:
|
||||||
|
print(f"\n{Fore.CYAN}{EMOJI['UPDATE']} {translator.get('updater.checking')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
# Get latest version from GitHub API with timeout
|
||||||
|
response = requests.get("https://api.github.com/repos/yeongpin/cursor-free-vip/releases/latest", timeout=5)
|
||||||
|
latest_version = response.json()["tag_name"].lstrip('v')
|
||||||
|
|
||||||
|
if latest_version != version:
|
||||||
|
print(f"\n{Fore.YELLOW}{EMOJI['INFO']} {translator.get('updater.new_version_available', current=version, latest=latest_version)}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
# Execute update command based on platform
|
||||||
|
if platform.system() == 'Windows':
|
||||||
|
update_command = 'irm https://raw.githubusercontent.com/yeongpin/cursor-free-vip/main/scripts/install.ps1 | iex'
|
||||||
|
subprocess.run(['powershell', '-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', update_command], check=True)
|
||||||
|
else:
|
||||||
|
update_command = 'curl -fsSL https://raw.githubusercontent.com/yeongpin/cursor-free-vip/main/scripts/install.sh -o install.sh && chmod +x install.sh && ./install.sh'
|
||||||
|
subprocess.Popen(update_command, shell=True)
|
||||||
|
|
||||||
|
print(f"\n{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('updater.updating')}{Style.RESET_ALL}")
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('updater.up_to_date')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('updater.check_failed', error=str(e))}{Style.RESET_ALL}")
|
||||||
|
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('updater.continue_anyway')}{Style.RESET_ALL}")
|
||||||
|
return # Continue with the program instead of blocking
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
print_logo()
|
print_logo()
|
||||||
|
check_latest_version() # Add version check before showing menu
|
||||||
print_menu()
|
print_menu()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|||||||
Reference in New Issue
Block a user