diff --git a/src/tools/account-register/sites/windsurf.js b/src/tools/account-register/sites/windsurf.js index f1ade8f..816c42b 100644 --- a/src/tools/account-register/sites/windsurf.js +++ b/src/tools/account-register/sites/windsurf.js @@ -47,8 +47,11 @@ class WindsurfRegister { { id: 4, name: '跳过问卷', method: 'step4_skipSurvey' }, { id: 5, name: '选择计划', method: 'step5_selectPlan' }, { id: 6, name: '填写支付信息', method: 'step6_fillPayment' }, - // 根据实际注册流程继续添加 + { id: 7, name: '获取订阅信息', method: 'step7_getSubscriptionInfo' }, ]; + + // 记录注册时间 + this.registrationTime = null; } /** @@ -274,16 +277,55 @@ class WindsurfRegister { logger.success(this.siteName, '✓ AdsPower 浏览器连接成功'); logger.info(this.siteName, '✓ 使用真实指纹,可同时绕过 Cloudflare 和 Stripe'); - // 提示:AdsPower 中需要手动安装 CapSolver 扩展 - if (this.capsolverKey) { - logger.info(this.siteName, ''); - logger.info(this.siteName, '💡 重要提示:'); - logger.info(this.siteName, ' 请在 AdsPower 配置中手动安装 CapSolver 扩展'); - logger.info(this.siteName, ' 扩展路径: extensions/capsolver'); - logger.info(this.siteName, ' 这样可以自动处理 Cloudflare Turnstile 验证'); - logger.info(this.siteName, ''); + // 清除所有浏览器数据(类似 Ctrl+Shift+Delete) + logger.info(this.siteName, ' → 清除所有浏览器数据(Cookies、Cache、Storage等)...'); + try { + // 使用 Chrome DevTools Protocol 进行深度清理 + const client = await this.page.target().createCDPSession(); + + // 1. 清除浏览器 Cookies + await client.send('Network.clearBrowserCookies'); + logger.success(this.siteName, ' → ✓ 已清除所有 Cookies'); + + // 2. 清除浏览器缓存 + await client.send('Network.clearBrowserCache'); + logger.success(this.siteName, ' → ✓ 已清除浏览器缓存'); + + // 3. 清除所有存储数据(localStorage, sessionStorage, IndexedDB, WebSQL, Cache Storage, Service Workers) + await client.send('Storage.clearDataForOrigin', { + origin: '*', + storageTypes: 'all' + }); + logger.success(this.siteName, ' → ✓ 已清除所有存储数据'); + + // 4. 额外清理:访问目标网站并清除其存储 + await this.page.goto('https://windsurf.com', { waitUntil: 'domcontentloaded' }); + await this.page.evaluate(() => { + try { + localStorage.clear(); + sessionStorage.clear(); + } catch (e) {} + }); + + // 5. 关闭 CDP 会话 + await client.detach(); + + logger.success(this.siteName, ' → ✓ 浏览器数据清除完成(全新状态)'); + + } catch (e) { + logger.warn(this.siteName, ` → 清除浏览器数据失败: ${e.message}`); } + // 提示:AdsPower 中需要手动安装 CapSolver 扩展 + logger.info(this.siteName, ''); + logger.info(this.siteName, '💡 提示:'); + logger.info(this.siteName, ' AdsPower 指纹浏览器已启动'); + if (this.capsolverKey) { + logger.info(this.siteName, ' 请确保已在 AdsPower 配置中安装 CapSolver 扩展'); + logger.info(this.siteName, ' 扩展路径: extensions/capsolver'); + } + logger.info(this.siteName, ''); + logger.info(this.siteName, '等待浏览器完全准备...'); await this.human.randomDelay(2000, 3000); @@ -501,7 +543,7 @@ class WindsurfRegister { // 如果配置了 CapSolver 扩展,等待扩展自动处理验证 if (this.capsolverKey) { logger.info(this.siteName, ' → 检测到 Cloudflare Turnstile 验证'); - logger.info(this.siteName, ' → CapSolver 扩展将自动处理(预计 10-20 秒)...'); + logger.info(this.siteName, ' → 等待 CapSolver 扩展处理(请确保已在 AdsPower 中安装扩展)...'); const startTime = Date.now(); let elapsed = 0; @@ -1624,8 +1666,23 @@ class WindsurfRegister { await submitButton.click(); logger.success(this.siteName, ' → ✓ 已点击订阅按钮'); - // 等待处理 - await this.human.randomDelay(5000, 7000); + // 等待跳转到支付成功页面 + logger.info(this.siteName, ' → 等待支付处理...'); + try { + await this.page.waitForFunction( + () => window.location.href.includes('/billing/payment-success'), + { timeout: 60000 } + ); + + // 记录注册时间(支付成功的时间) + this.registrationTime = new Date(); + logger.success(this.siteName, ' → ✓ 支付成功!'); + logger.info(this.siteName, ` → 注册时间: ${this.registrationTime.toLocaleString('zh-CN')}`); + + await this.human.randomDelay(2000, 3000); + } catch (e) { + logger.warn(this.siteName, ` → 等待支付成功页面超时: ${e.message}`); + } this.currentStep = 6; logger.success(this.siteName, `步骤 6 完成`); @@ -1640,6 +1697,151 @@ class WindsurfRegister { } } + /** + * 步骤7: 获取订阅信息 + */ + async step7_getSubscriptionInfo() { + logger.info(this.siteName, `[步骤 7/${this.getTotalSteps()}] 获取订阅信息`); + + try { + // 0. 检查并关闭可能存在的弹窗("要打开 Windsurf 吗?") + logger.info(this.siteName, ' → 检查是否有弹窗需要关闭...'); + try { + await this.page.waitForTimeout(2000); // 等待弹窗出现 + + // 尝试查找并点击"取消"或"打开Windsurf"按钮 + const closeDialog = await this.page.evaluate(() => { + // 查找包含"取消"或"打开Windsurf"的按钮 + const buttons = Array.from(document.querySelectorAll('button')); + const cancelBtn = buttons.find(btn => + btn.textContent.includes('取消') || + btn.textContent.includes('打开Windsurf') || + btn.textContent.includes('Cancel') + ); + + if (cancelBtn) { + // 优先点击"取消"按钮 + const actualCancelBtn = buttons.find(btn => + btn.textContent.includes('取消') || + btn.textContent.includes('Cancel') + ); + if (actualCancelBtn) { + actualCancelBtn.click(); + return '取消'; + } else { + cancelBtn.click(); + return '打开Windsurf'; + } + } + return null; + }); + + if (closeDialog) { + logger.success(this.siteName, ` → ✓ 已关闭弹窗(点击了"${closeDialog}")`); + await this.human.randomDelay(1000, 2000); + } else { + logger.info(this.siteName, ' → 未检测到弹窗'); + } + } catch (e) { + logger.info(this.siteName, ' → 未检测到弹窗或已自动关闭'); + } + + // 1. 跳转到订阅使用页面 + logger.info(this.siteName, ' → 跳转到订阅使用页面...'); + await this.page.goto('https://windsurf.com/subscription/usage', { + waitUntil: 'networkidle2', + timeout: 30000 + }); + + // 等待页面加载 + await this.human.randomDelay(3000, 5000); + + // 2. 获取配额信息 + logger.info(this.siteName, ' → 获取配额信息...'); + const quotaInfo = await this.page.evaluate(() => { + // 查找包含配额的 p 标签 + const quotaElement = document.querySelector('p.caption1.font-medium.text-sk-black\\/80'); + if (!quotaElement) return null; + + const spans = quotaElement.querySelectorAll('span.caption3 span'); + if (spans.length >= 2) { + const used = spans[0].textContent.trim(); + const total = spans[1].textContent.trim().replace('/', '').trim(); + return { used, total }; + } + return null; + }); + + if (quotaInfo) { + logger.success(this.siteName, ` → ✓ 配额: ${quotaInfo.used} / ${quotaInfo.total} used`); + } else { + logger.warn(this.siteName, ' → ⚠️ 未找到配额信息'); + } + + // 3. 获取下次账单日期信息 + logger.info(this.siteName, ' → 获取账单周期信息...'); + const billingInfo = await this.page.evaluate(() => { + // 查找包含 "Next billing cycle" 的 p 标签 + const billingElement = Array.from(document.querySelectorAll('p.caption1')) + .find(p => p.textContent.includes('Next billing cycle')); + + if (!billingElement) return null; + + // 提取天数 + const daysMatch = billingElement.textContent.match(/(\d+)\s+days?/); + const dateMatch = billingElement.textContent.match(/on\s+([A-Za-z]+\s+\d+,\s+\d{4})/); + + return { + days: daysMatch ? daysMatch[1] : null, + date: dateMatch ? dateMatch[1] : null, + fullText: billingElement.textContent.trim() + }; + }); + + if (billingInfo && billingInfo.days) { + logger.success(this.siteName, ` → ✓ 下次账单: ${billingInfo.days} 天后 (${billingInfo.date})`); + } else { + logger.warn(this.siteName, ' → ⚠️ 未找到账单周期信息'); + } + + // 4. 汇总打印所有信息 + logger.info(this.siteName, ''); + logger.info(this.siteName, '┌─────────────────────────────────────────────────────┐'); + logger.info(this.siteName, '│ 订阅信息汇总 │'); + logger.info(this.siteName, '└─────────────────────────────────────────────────────┘'); + + if (this.registrationTime) { + logger.info(this.siteName, `📅 注册时间: ${this.registrationTime.toLocaleString('zh-CN', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + hour: '2-digit', + minute: '2-digit', + second: '2-digit' + })}`); + } + + if (quotaInfo) { + logger.info(this.siteName, `📊 使用配额: ${quotaInfo.used} / ${quotaInfo.total}`); + logger.info(this.siteName, `💎 剩余配额: ${quotaInfo.total - parseFloat(quotaInfo.used)}`); + } + + if (billingInfo && billingInfo.days) { + logger.info(this.siteName, `🔄 下次账单: ${billingInfo.days} 天后`); + logger.info(this.siteName, `📆 账单日期: ${billingInfo.date}`); + } + + logger.info(this.siteName, ''); + + this.currentStep = 7; + logger.success(this.siteName, `步骤 7 完成`); + + } catch (error) { + logger.error(this.siteName, `获取订阅信息失败: ${error.message}`); + throw error; + } + } + /** * 执行注册流程 * @param {Object} options - 选项