2025-03-27 10:20:06 +08:00
|
|
|
|
import asyncio
|
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
|
|
# Windows平台特殊处理,强制使用SelectorEventLoop
|
|
|
|
|
|
if sys.platform.startswith('win'):
|
|
|
|
|
|
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
|
|
|
|
|
|
|
|
|
|
|
from typing import Dict, List
|
|
|
|
|
|
|
|
|
|
|
|
from core.config import Config
|
|
|
|
|
|
from core.database import DatabaseManager
|
|
|
|
|
|
from core.logger import setup_logger
|
|
|
|
|
|
from register.register_worker import RegisterWorker
|
|
|
|
|
|
from services.email_manager import EmailManager
|
|
|
|
|
|
from services.fetch_manager import FetchManager
|
|
|
|
|
|
from services.proxy_pool import ProxyPool
|
|
|
|
|
|
from services.token_pool import TokenPool
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CursorRegister:
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
|
self.config = Config.from_yaml()
|
|
|
|
|
|
self.logger = setup_logger(self.config)
|
|
|
|
|
|
self.db_manager = DatabaseManager(self.config)
|
|
|
|
|
|
self.fetch_manager = FetchManager(self.config)
|
|
|
|
|
|
self.proxy_pool = ProxyPool(self.config, self.fetch_manager)
|
|
|
|
|
|
self.token_pool = TokenPool(self.config)
|
|
|
|
|
|
self.email_manager = EmailManager(self.config, self.db_manager)
|
|
|
|
|
|
self.register_worker = RegisterWorker(
|
|
|
|
|
|
self.config,
|
|
|
|
|
|
self.fetch_manager,
|
|
|
|
|
|
self.email_manager
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
async def initialize(self):
|
|
|
|
|
|
"""初始化数据库"""
|
|
|
|
|
|
await self.db_manager.initialize()
|
2025-04-02 09:28:25 +08:00
|
|
|
|
# 确保EmailManager完成初始化
|
|
|
|
|
|
await self.email_manager.initialize()
|
2025-03-27 10:20:06 +08:00
|
|
|
|
|
|
|
|
|
|
async def cleanup(self):
|
|
|
|
|
|
"""清理资源"""
|
|
|
|
|
|
await self.db_manager.cleanup()
|
|
|
|
|
|
|
|
|
|
|
|
async def batch_register(self, num: int):
|
|
|
|
|
|
"""批量注册"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
self.logger.info(f"开始批量注册 {num} 个账号")
|
|
|
|
|
|
|
|
|
|
|
|
# 1. 先获取token对
|
|
|
|
|
|
token_pairs = await self.token_pool.batch_generate(num)
|
|
|
|
|
|
if not token_pairs:
|
|
|
|
|
|
self.logger.error("获取token失败,终止注册")
|
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
|
|
actual_num = len(token_pairs) # 根据实际获取到的token对数量调整注册数量
|
|
|
|
|
|
if actual_num < num:
|
|
|
|
|
|
self.logger.warning(f"只获取到 {actual_num} 对token,将减少注册数量")
|
|
|
|
|
|
num = actual_num
|
|
|
|
|
|
|
|
|
|
|
|
# 2. 获取邮箱账号
|
|
|
|
|
|
email_accounts = await self.email_manager.batch_get_accounts(num)
|
|
|
|
|
|
if len(email_accounts) < num:
|
|
|
|
|
|
self.logger.warning(f"可用邮箱账号不足,仅获取到 {len(email_accounts)} 个")
|
|
|
|
|
|
num = len(email_accounts)
|
|
|
|
|
|
|
|
|
|
|
|
# 3. 获取代理
|
|
|
|
|
|
proxies = await self.proxy_pool.batch_get(num)
|
|
|
|
|
|
|
|
|
|
|
|
# 在关键位置添加详细日志
|
|
|
|
|
|
self.logger.debug(f"代理列表: {proxies}")
|
|
|
|
|
|
self.logger.debug(f"邮箱账号: {[a.email for a in email_accounts]}")
|
|
|
|
|
|
self.logger.debug(f"尝试使用的token对数量: {len(token_pairs)}")
|
|
|
|
|
|
|
|
|
|
|
|
# 4. 创建注册任务
|
|
|
|
|
|
tasks = []
|
|
|
|
|
|
for account, proxy, token_pair in zip(email_accounts, proxies, token_pairs):
|
|
|
|
|
|
task = self.register_worker.register(proxy, token_pair, account)
|
|
|
|
|
|
tasks.append(task)
|
|
|
|
|
|
|
|
|
|
|
|
# 5. 并发执行
|
|
|
|
|
|
results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
|
|
|
|
|
|
|
|
|
|
# 6. 处理结果
|
|
|
|
|
|
successful = []
|
|
|
|
|
|
failed = []
|
|
|
|
|
|
skipped = 0
|
|
|
|
|
|
|
|
|
|
|
|
for i, result in enumerate(results):
|
|
|
|
|
|
if isinstance(result, Exception):
|
|
|
|
|
|
self.logger.error(f"注册任务 {i+1} 失败: {str(result)}")
|
|
|
|
|
|
failed.append(str(result))
|
|
|
|
|
|
elif result is None: # 跳过的账号
|
|
|
|
|
|
skipped += 1
|
|
|
|
|
|
else:
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 更新数据库
|
|
|
|
|
|
await self.email_manager.update_account(
|
|
|
|
|
|
result['account_id'],
|
|
|
|
|
|
result['cursor_password'],
|
|
|
|
|
|
result['cursor_cookie'],
|
|
|
|
|
|
result['cursor_jwt']
|
|
|
|
|
|
)
|
|
|
|
|
|
self.logger.debug(f"更新数据库成功 - 账号ID: {result['account_id']}")
|
|
|
|
|
|
successful.append(result)
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
self.logger.error(f"更新数据库失败 - 账号ID: {result['account_id']}, 错误: {str(e)}")
|
|
|
|
|
|
failed.append(str(e))
|
|
|
|
|
|
|
|
|
|
|
|
self.logger.info(f"注册完成: 成功 {len(successful)}, 失败 {len(failed)}, 跳过 {skipped}")
|
|
|
|
|
|
return successful
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
self.logger.error(f"批量注册失败: {str(e)}")
|
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
|
|
async def _process_results(self, results: List[Dict]):
|
|
|
|
|
|
"""处理注册结果"""
|
|
|
|
|
|
successful = []
|
|
|
|
|
|
failed = []
|
|
|
|
|
|
|
|
|
|
|
|
for result in results:
|
|
|
|
|
|
if isinstance(result, Exception):
|
|
|
|
|
|
failed.append(str(result))
|
|
|
|
|
|
else:
|
|
|
|
|
|
# 更新数据库
|
|
|
|
|
|
await self.email_manager.update_account(
|
|
|
|
|
|
result['account_id'],
|
|
|
|
|
|
result['cursor_password'],
|
|
|
|
|
|
result['cursor_cookie']
|
|
|
|
|
|
)
|
|
|
|
|
|
successful.append(result)
|
|
|
|
|
|
|
|
|
|
|
|
print(f"Successfully registered: {len(successful)}")
|
|
|
|
|
|
print(f"Failed registrations: {len(failed)}")
|
|
|
|
|
|
|
|
|
|
|
|
return successful
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def main():
|
|
|
|
|
|
register = CursorRegister()
|
|
|
|
|
|
await register.initialize()
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
batch_size = register.config.register_config.batch_size
|
|
|
|
|
|
total_registered = 0
|
|
|
|
|
|
|
|
|
|
|
|
while True:
|
2025-04-01 17:58:08 +08:00
|
|
|
|
# 直接检查数据库中是否有可用的邮箱账号
|
|
|
|
|
|
pending_count = await register.email_manager.count_pending_accounts()
|
|
|
|
|
|
if pending_count <= 0:
|
|
|
|
|
|
register.logger.info("没有可用的邮箱账号,注册完成")
|
2025-03-27 10:20:06 +08:00
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
# 执行批量注册
|
2025-04-01 17:58:08 +08:00
|
|
|
|
register.logger.info(f"发现 {pending_count} 个可用邮箱,开始新一轮批量注册,批次大小: {batch_size}")
|
2025-03-27 10:20:06 +08:00
|
|
|
|
results = await register.batch_register(batch_size)
|
|
|
|
|
|
|
|
|
|
|
|
# 统计结果
|
|
|
|
|
|
successful = len(results)
|
|
|
|
|
|
total_registered += successful
|
|
|
|
|
|
|
|
|
|
|
|
register.logger.info(f"当前总进度: 已注册 {total_registered} 个账号")
|
|
|
|
|
|
|
2025-04-02 09:28:25 +08:00
|
|
|
|
# 批次结束后等待3秒,确保所有数据库更新都已完成
|
|
|
|
|
|
register.logger.info("本批次注册完成,等待数据库状态完全更新...")
|
|
|
|
|
|
await asyncio.sleep(3)
|
|
|
|
|
|
|
2025-03-27 10:20:06 +08:00
|
|
|
|
# 如果本批次注册失败率过高,暂停一段时间
|
2025-04-01 17:58:08 +08:00
|
|
|
|
if successful < batch_size * 0.5 and successful > 0: # 成功率低于50%但不为零
|
2025-03-27 10:20:06 +08:00
|
|
|
|
register.logger.warning("本批次成功率过低,暂停60秒后继续")
|
|
|
|
|
|
await asyncio.sleep(60)
|
2025-04-01 17:58:08 +08:00
|
|
|
|
elif successful == 0 and batch_size > 0: # 完全失败
|
|
|
|
|
|
register.logger.error("本批次完全失败,可能存在系统问题,暂停120秒后继续")
|
|
|
|
|
|
await asyncio.sleep(120)
|
2025-03-27 10:20:06 +08:00
|
|
|
|
else:
|
|
|
|
|
|
# 正常等待一个较短的时间再继续下一批
|
|
|
|
|
|
await asyncio.sleep(5)
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
register.logger.error(f"程序执行出错: {str(e)}")
|
|
|
|
|
|
finally:
|
|
|
|
|
|
register.logger.info(f"程序结束,总共成功注册 {total_registered} 个账号")
|
|
|
|
|
|
await register.cleanup()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
asyncio.run(main())
|