From 436e8415a298fece1b35a2b35d7c4243a060f83f Mon Sep 17 00:00:00 2001 From: qtaxm <17772864223@163.com> Date: Thu, 9 Apr 2026 10:09:03 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20v4.5=20=E4=BF=AE=E5=A4=8D=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E7=AA=97=E5=8F=A3=E4=B8=8D=E5=BC=B9=E5=87=BA=20?= =?UTF-8?q?=E2=80=94=20=E6=94=B9=E4=B8=BA=E5=89=8D=E7=AB=AF=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E8=A7=A6=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 核心改动: startProactive不再自己调retry 而是设proactive=true后点击按钮,让前端发fetch 拦截器内完成重试,响应直接返回给前端的fetch调用 前端代码路径完整,支付窗口正常弹出 - 记住用户最初点击的按钮 - 多种点击方式(mousedown/mouseup/click) - 拦截器内成功后发送浏览器通知 --- glm-rush-v4.user.js | 68 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/glm-rush-v4.user.js b/glm-rush-v4.user.js index 8ea9cbd..8188a90 100644 --- a/glm-rush-v4.user.js +++ b/glm-rush-v4.user.js @@ -385,7 +385,11 @@ body: init?.body, headers: extractHeaders(init?.headers), }); + setState({ proactive: false }); if (result.ok) { + log('拦截器内抢购成功! 返回响应给前端...'); + try { new Notification('GLM 抢购成功!', { body: `bizId=${state.bizId}` }); } catch {} + // 直接返回给前端的 fetch 调用 → 前端会正常弹出支付窗口 return new Response(result.text, { status: result.status, headers: { 'Content-Type': 'application/json' } }); } return _fetch.apply(this, [input, init]); @@ -452,6 +456,11 @@ if (state.proactive || state.status === 'retrying') { log('抢购中, 启动重试 (XHR)...'); retry(url, { method: this._m, body, headers: this._h || {} }).then(result => { + setState({ proactive: false }); + if (result.ok) { + log('XHR拦截器内抢购成功! 返回响应给前端...'); + try { new Notification('GLM 抢购成功!', { body: `bizId=${state.bizId}` }); } catch {} + } fakeXHR(self, result.ok ? result.text : '{"code":-1,"msg":"重试失败"}'); }); return; @@ -630,7 +639,11 @@ // ═══════════════════════════════════════════ // 主动抢购 & 定时 // ═══════════════════════════════════════════ + let _lastClickedBtn = null; // 记住用户点的那个按钮 + function findBuyButton() { + // 优先返回用户上次点击的同一个按钮 + if (_lastClickedBtn && _lastClickedBtn.offsetParent !== null) return _lastClickedBtn; for (const el of document.querySelectorAll('button, a, [role="button"], div[class*="btn"], span[class*="btn"]')) { const t = el.textContent.trim(); if (/购买|抢购|立即|下单|订阅/.test(t) && t.length < 20 && el.offsetParent !== null) return el; @@ -638,6 +651,24 @@ return null; } + // 监听用户点击,记住是哪个按钮 + document.addEventListener('click', e => { + const t = (e.target.textContent || '').trim(); + if (/购买|抢购|立即|下单|订阅/.test(t) && t.length < 20) { + _lastClickedBtn = e.target.closest('button') || e.target; + log('记住按钮: ' + t); + } + }, true); + + function clickButton(btn) { + // 多种方式触发点击,确保前端框架能响应 + btn.focus(); + btn.dispatchEvent(new MouseEvent('mousedown', { bubbles: true })); + btn.dispatchEvent(new MouseEvent('mouseup', { bubbles: true })); + btn.dispatchEvent(new MouseEvent('click', { bubbles: true })); + btn.click(); + } + async function startProactive() { if (!state.captured) { log('请先手动点一次购买按钮'); @@ -648,23 +679,32 @@ log('已经抢到了, 不重复抢购'); return; } + + // 核心策略: 设置 proactive=true,然后点击按钮 + // 让前端自己发 fetch → 拦截器检测到 proactive → 启动重试 + // 响应直接返回给前端的 fetch 调用 → 前端正常弹出支付窗口 setState({ proactive: true }); - log(`极速抢购启动! 前${CFG.turboSec}秒${CFG.turboConcurrency}路并发, 之后${CFG.concurrency}路`); + log(`极速抢购启动! 点击按钮触发前端请求...`); - const { url, method, body, headers } = state.captured; - const result = await retry(url, { method, body, headers }); - setState({ proactive: false }); + const btn = findBuyButton(); + if (btn) { + clickButton(btn); + log('已点击购买按钮, 等待拦截器重试...'); + // 拦截器会在 fetch/XHR 中自动处理重试 + // proactive 会在拦截器成功后由 retry 结束时保持 + } else { + // 找不到按钮 → 降级为直接调用方式 + log('未找到按钮, 降级为直接请求模式...'); + const { url, method, body, headers } = state.captured; + const result = await retry(url, { method, body, headers }); + setState({ proactive: false }); - if (result.ok) { - setState({ cache: { text: result.text, data: result.data } }); - log('抢购成功! 触发支付...'); - // 自动通知 - try { new Notification('GLM 抢购成功!', { body: `bizId=${state.bizId}` }); } catch {} - const errDlg = findErrorDialog(); - if (errDlg) { dismissDialog(errDlg); await sleep(300); } - const btn = findBuyButton(); - if (btn) { btn.click(); log('已自动点击购买按钮'); } - else { alert('已获取到商品! 请立即点击购买按钮!'); } + if (result.ok) { + setState({ cache: { text: result.text, data: result.data } }); + log('抢购成功! 请立即手动点击购买按钮!'); + try { new Notification('GLM 抢购成功!', { body: `bizId=${state.bizId}` }); } catch {} + alert('已抢到! 请立即手动点击「特惠订阅」按钮完成支付!'); + } } }