import os from colorama import Fore, Style, init import time import random from browser import BrowserManager from control import BrowserControl from cursor_auth import CursorAuth from reset_machine_manual import MachineIDResetter os.environ["PYTHONVERBOSE"] = "0" os.environ["PYINSTALLER_VERBOSE"] = "0" # 初始化colorama init() # 定义emoji常量 EMOJI = { 'START': '🚀', 'FORM': '📝', 'VERIFY': '🔄', 'PASSWORD': '🔑', 'CODE': '📱', 'DONE': '✨', 'ERROR': '❌', 'WAIT': '⏳', 'SUCCESS': '✅', 'MAIL': '📧', 'KEY': '🔐', 'UPDATE': '🔄', 'INFO': 'ℹ️' } class CursorRegistration: def __init__(self, translator=None): self.translator = translator # 设置为显示模式 os.environ['BROWSER_HEADLESS'] = 'False' self.browser_manager = BrowserManager() self.browser = None self.controller = None self.mail_url = "https://yopmail.com/zh/email-generator" self.sign_up_url = "https://authenticator.cursor.sh/sign-up" self.settings_url = "https://www.cursor.com/settings" self.email_address = None self.signup_tab = None self.email_tab = None # 账号信息 self.password = self._generate_password() self.first_name = self._generate_name() self.last_name = self._generate_name() def _generate_password(self, length=12): """Generate Random Password""" chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*" 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): """设置邮箱""" try: print(f"{Fore.CYAN}{EMOJI['START']} {self.translator.get('register.browser_start')}...{Style.RESET_ALL}") self.browser = self.browser_manager.init_browser() self.controller = BrowserControl(self.browser, self.translator) # 打开邮箱生成器页面(第一个标签页) self.controller.navigate_to(self.mail_url) self.email_tab = self.browser # 保存邮箱标签页 self.controller.email_tab = self.email_tab # 同时保存到controller # 生成新邮箱 self.controller.generate_new_email() # 选择随机域名 self.controller.select_email_domain() # 获取邮箱地址 self.email_address = self.controller.copy_and_get_email() if self.email_address: print(f"{EMOJI['MAIL']}{Fore.CYAN} {self.translator.get('register.get_email_address')}: {self.email_address}{Style.RESET_ALL}") # 进入邮箱 if self.controller.view_mailbox(): return True return False except Exception as e: print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.setup_error', error=str(e))}{Style.RESET_ALL}") return False def register_cursor(self): """注册 Cursor""" browser_tab = None try: print(f"{Fore.CYAN}{EMOJI['START']} {self.translator.get('register.register_start')}...{Style.RESET_ALL}") # 直接使用 new_signup.py 进行注册 from new_signup import main as new_signup_main # 执行新的注册流程,传入 translator result, browser_tab = new_signup_main( email=self.email_address, password=self.password, first_name=self.first_name, last_name=self.last_name, email_tab=self.email_tab, controller=self.controller, translator=self.translator ) if result: # 使用返回的浏览器实例获取账户信息 self.signup_tab = browser_tab # 保存浏览器实例 success = self._get_account_info() # 获取信息后关闭浏览器 if browser_tab: try: browser_tab.quit() except: pass return success return False except Exception as e: print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.register_process_error', error=str(e))}{Style.RESET_ALL}") return False finally: # 确保在任何情况下都关闭浏览器 if browser_tab: try: browser_tab.quit() except: pass def _get_account_info(self): """获取账户信息和 Token""" try: self.signup_tab.get(self.settings_url) time.sleep(2) usage_selector = ( "css:div.col-span-2 > div > div > div > div > " "div:nth-child(1) > div.flex.items-center.justify-between.gap-2 > " "span.font-mono.text-sm\\/\\[0\\.875rem\\]" ) usage_ele = self.signup_tab.ele(usage_selector) total_usage = "未知" if usage_ele: total_usage = usage_ele.text.split("/")[-1].strip() print(f"{Fore.CYAN}{EMOJI['WAIT']} {self.translator.get('register.get_token')}...{Style.RESET_ALL}") max_attempts = 30 retry_interval = 2 attempts = 0 while attempts < max_attempts: try: cookies = self.signup_tab.cookies() for cookie in cookies: if cookie.get("name") == "WorkosCursorSessionToken": token = cookie["value"].split("%3A%3A")[1] print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('register.token_success')}{Style.RESET_ALL}") self._save_account_info(token, total_usage) return True attempts += 1 if attempts < max_attempts: print(f"{Fore.YELLOW}{EMOJI['WAIT']} {self.translator.get('register.token_attempt', attempt=attempts, time=retry_interval)}{Style.RESET_ALL}") time.sleep(retry_interval) else: print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.token_max_attempts', max=max_attempts)}{Style.RESET_ALL}") except Exception as e: print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.token_failed', error=str(e))}{Style.RESET_ALL}") attempts += 1 if attempts < max_attempts: print(f"{Fore.YELLOW}{EMOJI['WAIT']} {self.translator.get('register.token_attempt', attempt=attempts, time=retry_interval)}{Style.RESET_ALL}") time.sleep(retry_interval) return False except Exception as e: print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.account_error', error=str(e))}{Style.RESET_ALL}") return False def _save_account_info(self, token, total_usage): """保存账户信息到文件""" try: # 先更新认证信息 print(f"{Fore.CYAN}{EMOJI['KEY']} {self.translator.get('register.update_cursor_auth_info')}...{Style.RESET_ALL}") if self.update_cursor_auth(email=self.email_address, access_token=token, refresh_token=token): print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('register.cursor_auth_info_updated')}...{Style.RESET_ALL}") else: print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.cursor_auth_info_update_failed')}...{Style.RESET_ALL}") # 重置机器ID print(f"{Fore.CYAN}{EMOJI['UPDATE']} {self.translator.get('register.reset_machine_id')}...{Style.RESET_ALL}") resetter = MachineIDResetter(self.translator) # 创建实例时传入translator if not resetter.reset_machine_ids(): # 直接调用reset_machine_ids方法 raise Exception("Failed to reset machine ID") # 保存账户信息到文件 with open('cursor_accounts.txt', 'a', encoding='utf-8') as f: f.write(f"\n{'='*50}\n") f.write(f"Email: {self.email_address}\n") f.write(f"Password: {self.password}\n") f.write(f"Token: {token}\n") f.write(f"Usage Limit: {total_usage}\n") f.write(f"{'='*50}\n") print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('register.account_info_saved')}...{Style.RESET_ALL}") return True except Exception as e: print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.save_account_info_failed', error=str(e))}{Style.RESET_ALL}") return False def start(self): """启动注册流程""" try: if self.setup_email(): if self.register_cursor(): print(f"\n{Fore.GREEN}{EMOJI['DONE']} {self.translator.get('register.cursor_registration_completed')}...{Style.RESET_ALL}") return True return False finally: if self.browser_manager: self.browser_manager.quit() def update_cursor_auth(self, email=None, access_token=None, refresh_token=None): """更新Cursor的认证信息的便捷函数""" auth_manager = CursorAuth(translator=self.translator) return auth_manager.update_auth(email, access_token, refresh_token) def main(translator=None): """Main function to be called from main.py""" print(f"\n{Fore.CYAN}{'='*50}{Style.RESET_ALL}") print(f"{Fore.CYAN}{EMOJI['START']} {translator.get('register.title')}{Style.RESET_ALL}") print(f"{Fore.CYAN}{'='*50}{Style.RESET_ALL}") registration = CursorRegistration(translator) registration.start() print(f"\n{Fore.CYAN}{'='*50}{Style.RESET_ALL}") input(f"{EMOJI['INFO']} {translator.get('register.press_enter')}...") if __name__ == "__main__": from main import translator as main_translator main(main_translator)