From 468d4d6d736e465cfc838498ca09c160f0a57b2f Mon Sep 17 00:00:00 2001 From: dengqichen Date: Mon, 17 Nov 2025 20:26:17 +0800 Subject: [PATCH] aaaaa --- src/tools/account-register/sites/windsurf.js | 226 +++++++++++++------ 1 file changed, 154 insertions(+), 72 deletions(-) diff --git a/src/tools/account-register/sites/windsurf.js b/src/tools/account-register/sites/windsurf.js index b3b4cc3..164b0bc 100644 --- a/src/tools/account-register/sites/windsurf.js +++ b/src/tools/account-register/sites/windsurf.js @@ -1048,7 +1048,7 @@ class WindsurfRegister { } /** - * 提交支付(递归重试) + * 提交支付(递归重试,轮询检测) */ async submitPayment(retryCount = 0, maxRetries = 5) { if (retryCount >= maxRetries) { @@ -1068,43 +1068,105 @@ class WindsurfRegister { await submitButton.click(); logger.success(this.siteName, ' → ✓ 已点击订阅按钮'); - await this.human.randomDelay(3000, 5000); - // 处理验证码 - await this.handleHCaptcha(); + // 等待一下让 Stripe 开始处理 await this.human.randomDelay(2000, 3000); - // 检查卡是否被拒绝 - const cardRejected = await this.checkCardRejected(); - if (cardRejected) { - logger.warn(this.siteName, ` → ⚠️ 银行卡被拒绝!(第 ${retryCount + 1}/${maxRetries} 次)`); - - // 生成新卡 - logger.info(this.siteName, ' → 生成新的银行卡信息...'); - const cardGen = new CardGenerator(); - const newCard = cardGen.generate('unionpay'); - logger.info(this.siteName, ` → 新卡号: ${newCard.number}`); - - this.cardInfo = { - number: newCard.number, - month: newCard.month, - year: newCard.year, - cvv: newCard.cvv, - country: 'MO' - }; - - // 重新填写卡信息 - await this.fillCardForm(newCard, true); - logger.success(this.siteName, ' → ✓ 已更新银行卡信息'); - await this.human.randomDelay(2000, 3000); - - // 递归重试 - return await this.submitPayment(retryCount + 1, maxRetries); + // 检查是否有验证码(快速检查) + const hasHCaptcha = await this.page.evaluate(() => { + return !!( + document.querySelector('iframe[src*="hcaptcha.com"]') || + document.querySelector('.h-captcha') + ); + }); + + if (hasHCaptcha) { + logger.info(this.siteName, ' → 检测到验证码,处理中...'); + await this.handleHCaptcha(); + await this.human.randomDelay(1000, 2000); } - // 等待支付成功 - await this.waitForPaymentSuccess(); - return true; + // 开始轮询检测:同时等待成功或失败 + logger.info(this.siteName, ' → 轮询检测支付结果...'); + const startTime = Date.now(); + const maxWait = 30000; // 最多等待30秒 + let checkCount = 0; + + while (Date.now() - startTime < maxWait) { + checkCount++; + + // 1. 优先检查是否有错误(卡被拒绝) + const cardRejected = await this.checkCardRejected(); + if (cardRejected) { + logger.warn(this.siteName, ` → ⚠️ 银行卡被拒绝!(第 ${retryCount + 1}/${maxRetries} 次,检测了 ${checkCount} 次)`); + + // 生成新卡 + logger.info(this.siteName, ' → 生成新的银行卡信息...'); + const cardGen = new CardGenerator(); + const newCard = cardGen.generate('unionpay'); + logger.info(this.siteName, ` → 新卡号: ${newCard.number}`); + + this.cardInfo = { + number: newCard.number, + month: newCard.month, + year: newCard.year, + cvv: newCard.cvv, + country: 'MO' + }; + + // 重新填写卡信息 + await this.fillCardForm(newCard, true); + logger.success(this.siteName, ' → ✓ 已更新银行卡信息'); + await this.human.randomDelay(2000, 3000); + + // 递归重试 + return await this.submitPayment(retryCount + 1, maxRetries); + } + + // 2. 检查是否支付成功(跳转离开 Stripe) + const currentUrl = this.page.url(); + if (!currentUrl.includes('stripe.com') && !currentUrl.includes('checkout.stripe.com')) { + const totalTime = ((Date.now() - startTime) / 1000).toFixed(1); + this.registrationTime = new Date(); + logger.success(this.siteName, ` → ✓ 支付成功!(耗时: ${totalTime}秒,检测了 ${checkCount} 次)`); + logger.info(this.siteName, ` → 当前页面: ${currentUrl}`); + return true; + } + + // 3. 每5秒输出一次进度 + const elapsed = Date.now() - startTime; + if (elapsed > 0 && elapsed % 5000 === 0) { + logger.info(this.siteName, ` → 支付处理中... (${(elapsed/1000).toFixed(0)}秒,已检测 ${checkCount} 次)`); + } + + // 4. 等待500ms后继续检测 + await new Promise(resolve => setTimeout(resolve, 500)); + } + + // 超时:视为可能失败,生成新卡重试 + logger.warn(this.siteName, ` → ⚠️ 支付超时(${maxWait/1000}秒),共检测 ${checkCount} 次`); + logger.info(this.siteName, ` → 将生成新卡重试 (第 ${retryCount + 1}/${maxRetries} 次)`); + + // 生成新卡 + const cardGen = new CardGenerator(); + const newCard = cardGen.generate('unionpay'); + logger.info(this.siteName, ` → 新卡号: ${newCard.number}`); + + this.cardInfo = { + number: newCard.number, + month: newCard.month, + year: newCard.year, + cvv: newCard.cvv, + country: 'MO' + }; + + // 重新填写卡信息 + await this.fillCardForm(newCard, true); + logger.success(this.siteName, ' → ✓ 已更新银行卡信息'); + await this.human.randomDelay(2000, 3000); + + // 递归重试 + return await this.submitPayment(retryCount + 1, maxRetries); } /** @@ -1155,55 +1217,75 @@ class WindsurfRegister { logger.info(this.siteName, `[步骤 7/${this.getTotalSteps()}] 获取订阅信息`); try { - // 0. 检查并关闭可能存在的弹窗("要打开 Windsurf 吗?") - logger.info(this.siteName, ' → 检查是否有弹窗需要关闭...'); + // 0. 先关闭多余的窗口/标签页 + logger.info(this.siteName, ' → 检查并关闭多余窗口...'); try { - await new Promise(resolve => setTimeout(resolve, 2000)); // 等待弹窗出现 + const pages = await this.browser.pages(); + logger.info(this.siteName, ` → 当前共有 ${pages.length} 个页面`); - // 方法1: 尝试按ESC键关闭浏览器原生对话框 - logger.info(this.siteName, ' → 尝试按ESC键关闭原生对话框...'); - await this.page.keyboard.press('Escape'); - await this.human.randomDelay(500, 1000); - - // 方法2: 尝试查找并点击网页内的按钮(如果是HTML弹窗) - 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 (pages.length > 1) { + // 保留一个 windsurf.com 的页面,关闭其他 + let validPage = null; + const pagesToClose = []; - if (cancelBtn) { - // 优先点击"取消"按钮 - const actualCancelBtn = buttons.find(btn => - btn.textContent.includes('取消') || - btn.textContent.includes('Cancel') - ); - if (actualCancelBtn) { - actualCancelBtn.click(); - return '取消'; - } else { - cancelBtn.click(); - return '打开Windsurf'; + for (const page of pages) { + try { + const url = page.url(); + if (url.includes('windsurf.com') && !validPage) { + validPage = page; + logger.info(this.siteName, ` → ✓ 保留: ${url}`); + } else { + pagesToClose.push(page); + logger.info(this.siteName, ` → ✗ 关闭: ${url}`); + } + } catch (e) { + pagesToClose.push(page); } } - return null; - }); - - if (closeDialog) { - logger.success(this.siteName, ` → ✓ 已关闭HTML弹窗(点击了"${closeDialog}")`); - await this.human.randomDelay(1000, 2000); - } else { - logger.success(this.siteName, ' → ✓ 已尝试关闭原生对话框(ESC键)'); + + // 如果没找到 windsurf 页面,保留第一个 + if (!validPage && pages.length > 0) { + validPage = pages[0]; + pagesToClose.shift(); + } + + // 关闭多余页面 + for (const page of pagesToClose) { + try { + await page.close(); + } catch (e) { + // 忽略 + } + } + + this.page = validPage; + logger.success(this.siteName, ` → ✓ 已关闭 ${pagesToClose.length} 个多余页面`); } } catch (e) { - logger.info(this.siteName, ` → 关闭弹窗时出错: ${e.message}`); + logger.warn(this.siteName, ` → 关闭窗口失败: ${e.message}`); } - // 1. 跳转到订阅使用页面 + await this.human.randomDelay(1000, 2000); + + // 1. 持续按ESC关闭弹窗(循环5次,确保关闭) + logger.info(this.siteName, ' → 关闭可能存在的对话框...'); + for (let i = 0; i < 5; i++) { + try { + await this.page.keyboard.press('Escape'); + await new Promise(resolve => setTimeout(resolve, 300)); + } catch (e) { + // 忽略 + } + } + logger.success(this.siteName, ' → ✓ 已按5次ESC键'); + + await this.human.randomDelay(500, 1000); + + // 2. 跳转到订阅使用页面 logger.info(this.siteName, ' → 跳转到订阅使用页面...'); + const currentUrl = this.page.url(); + logger.info(this.siteName, ` → 当前页面: ${currentUrl}`); + await this.page.goto('https://windsurf.com/subscription/usage', { waitUntil: 'networkidle2', timeout: 30000