fix: v4.3 前20秒全速不降速, 上限改2000次, 超20秒连续售罄才降速

This commit is contained in:
qtaxm
2026-04-08 11:48:29 +08:00
parent ba6369699c
commit 47a7ae227c
2 changed files with 62 additions and 6 deletions

View File

@@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name 智谱 GLM Coding 抢购助手 v4.0 // @name 智谱 GLM Coding 抢购助手 v4.0
// @namespace http://tampermonkey.net/ // @namespace http://tampermonkey.net/
// @version 4.1 // @version 4.3
// @description 并发重试 + 自适应间隔 + 反检测 + check校验 + 弹窗恢复 + 定时触发 + 配置持久化 // @description 并发重试 + 自适应间隔 + 反检测 + check校验 + 弹窗恢复 + 定时触发 + 配置持久化
// @author Assistant // @author Assistant
// @match *://www.bigmodel.cn/* // @match *://www.bigmodel.cn/*
@@ -18,7 +18,7 @@
// ═══════════════════════════════════════════ // ═══════════════════════════════════════════
const DEFAULT_CFG = { const DEFAULT_CFG = {
concurrency: 3, // 并发路数 concurrency: 3, // 并发路数
maxRetry: 500, // 最大重试次数 maxRetry: 2000, // 最大重试次数
burstCount: 10, // 前N次零延迟爆发 burstCount: 10, // 前N次零延迟爆发
fastDelay: 50, // 爆发后的快速间隔 fastDelay: 50, // 爆发后的快速间隔
slowDelay: 150, // 后期随机间隔中值 slowDelay: 150, // 后期随机间隔中值
@@ -202,6 +202,7 @@
let totalAttempt = 0; let totalAttempt = 0;
let consecutiveErrors = 0; let consecutiveErrors = 0;
let throttleCount = 0; let throttleCount = 0;
let consecutiveSoldOut = 0;
while (totalAttempt < CFG.maxRetry && !stopRequested) { while (totalAttempt < CFG.maxRetry && !stopRequested) {
const batchSize = Math.min(CFG.concurrency, CFG.maxRetry - totalAttempt); const batchSize = Math.min(CFG.concurrency, CFG.maxRetry - totalAttempt);
@@ -286,9 +287,29 @@
// EXPIRE → 立即重试不等待 // EXPIRE → 立即重试不等待
if (reasons.every(r => r === 'EXPIRE')) continue; if (reasons.every(r => r === 'EXPIRE')) continue;
// 前20秒全速冲之后才考虑降速
const elapsedSec = (performance.now() - state.stats.startTime) / 1000;
if (elapsedSec > 20) {
// 超过20秒 — 检测是否该降速
const soldOutCount = reasons.filter(r => r === '售罄').length;
if (soldOutCount === batchSize) {
consecutiveSoldOut++;
} else {
consecutiveSoldOut = 0;
}
// 连续10轮全售罄 → 可能已经抢完了
if (consecutiveSoldOut >= 10) {
if (consecutiveSoldOut === 10) log('连续售罄, 可能已抢完, 降速 (2s)...');
await sleep(2000);
continue;
}
}
// 日志 (前5次 + 每20次) // 日志 (前5次 + 每20次)
if (totalAttempt <= 5 * CFG.concurrency || totalAttempt % (20 * CFG.concurrency) === 0) { if (totalAttempt <= 5 * CFG.concurrency || totalAttempt % (20 * CFG.concurrency) === 0) {
log(`#${totalAttempt} ${reasons[0]}`); const sec = elapsedSec.toFixed(0);
log(`#${totalAttempt} ${reasons[0]} (${sec}s)`);
} }
// 自适应延迟 // 自适应延迟
@@ -706,7 +727,7 @@
.keys{font-size:10px;color:#636e72;text-align:center;margin-top:6px} .keys{font-size:10px;color:#636e72;text-align:center;margin-top:6px}
</style> </style>
<div class="panel"> <div class="panel">
<div class="hd" id="drag"><b>GLM v4.1</b><button class="mn" id="min">-</button></div> <div class="hd" id="drag"><b>GLM v4.3</b><button class="mn" id="min">-</button></div>
<div class="bd" id="bd"> <div class="bd" id="bd">
<div class="st st-idle" id="st">等待中</div> <div class="st st-idle" id="st">等待中</div>
<div class="cap" id="cap">${state.captured ? '已恢复上次捕获的请求' : '请先点一次购买按钮'}</div> <div class="cap" id="cap">${state.captured ? '已恢复上次捕获的请求' : '请先点一次购买按钮'}</div>

View File

@@ -6,7 +6,7 @@
// ═══════════════════════════════════════════ // ═══════════════════════════════════════════
const DEFAULT_CFG = { const DEFAULT_CFG = {
concurrency: 3, // 并发路数 concurrency: 3, // 并发路数
maxRetry: 500, // 最大重试次数 maxRetry: 2000, // 最大重试次数
burstCount: 10, // 前N次零延迟爆发 burstCount: 10, // 前N次零延迟爆发
fastDelay: 50, // 爆发后的快速间隔 fastDelay: 50, // 爆发后的快速间隔
slowDelay: 150, // 后期随机间隔中值 slowDelay: 150, // 后期随机间隔中值
@@ -190,6 +190,8 @@
let totalAttempt = 0; let totalAttempt = 0;
let consecutiveErrors = 0; let consecutiveErrors = 0;
let throttleCount = 0; let throttleCount = 0;
let consecutiveSoldOut = 0;
let consecutiveBusy = 0;
while (totalAttempt < CFG.maxRetry && !stopRequested) { while (totalAttempt < CFG.maxRetry && !stopRequested) {
const batchSize = Math.min(CFG.concurrency, CFG.maxRetry - totalAttempt); const batchSize = Math.min(CFG.concurrency, CFG.maxRetry - totalAttempt);
@@ -274,6 +276,39 @@
// EXPIRE → 立即重试不等待 // EXPIRE → 立即重试不等待
if (reasons.every(r => r === 'EXPIRE')) continue; if (reasons.every(r => r === 'EXPIRE')) continue;
// 连续售罄检测 — 非抢购时间不要浪费重试
const soldOutCount = reasons.filter(r => r === '售罄').length;
const busyCount = reasons.filter(r => r === '系统繁忙').length;
if (soldOutCount === batchSize) {
consecutiveSoldOut++;
} else {
consecutiveSoldOut = 0;
}
// 连续全部返回系统繁忙 → 可能不在抢购时间
if (busyCount === batchSize) {
consecutiveBusy++;
} else {
consecutiveBusy = 0;
}
// 连续5轮全售罄 → 放慢重试 (2秒一次)
if (consecutiveSoldOut >= 5) {
if (consecutiveSoldOut === 5) log('连续售罄, 降速重试 (2s间隔)...');
await sleep(2000);
continue;
}
// 连续5轮全系统繁忙 → 可能不在抢购窗口, 放慢到5秒
if (consecutiveBusy >= 5) {
if (consecutiveBusy === 5) log('连续系统繁忙, 可能未到抢购时间, 降速 (5s间隔)...');
await sleep(5000);
// 每30轮检查一次是否恢复
if (consecutiveBusy % 30 === 0) {
log(`仍在等待... 已重试${totalAttempt}次 (系统繁忙)`);
}
continue;
}
// 日志 (前5次 + 每20次) // 日志 (前5次 + 每20次)
if (totalAttempt <= 5 * CFG.concurrency || totalAttempt % (20 * CFG.concurrency) === 0) { if (totalAttempt <= 5 * CFG.concurrency || totalAttempt % (20 * CFG.concurrency) === 0) {
log(`#${totalAttempt} ${reasons[0]}`); log(`#${totalAttempt} ${reasons[0]}`);
@@ -694,7 +729,7 @@
.keys{font-size:10px;color:#636e72;text-align:center;margin-top:6px} .keys{font-size:10px;color:#636e72;text-align:center;margin-top:6px}
</style> </style>
<div class="panel"> <div class="panel">
<div class="hd" id="drag"><b>GLM v4.0</b><button class="mn" id="min">-</button></div> <div class="hd" id="drag"><b>GLM v4.2</b><button class="mn" id="min">-</button></div>
<div class="bd" id="bd"> <div class="bd" id="bd">
<div class="st st-idle" id="st">等待中</div> <div class="st st-idle" id="st">等待中</div>
<div class="cap" id="cap">${state.captured ? '已恢复上次捕获的请求' : '请先点一次购买按钮'}</div> <div class="cap" id="cap">${state.captured ? '已恢复上次捕获的请求' : '请先点一次购买按钮'}</div>