diff --git a/glm-coding-helper.user.js b/glm-coding-helper.user.js
index a18a64a..020cbe8 100644
--- a/glm-coding-helper.user.js
+++ b/glm-coding-helper.user.js
@@ -1,7 +1,7 @@
// ==UserScript==
// @name 智谱 GLM Coding Plan 抢购助手 + 本地 OCR 自动验证码
// @namespace http://tampermonkey.net/
-// @version 8.21.3
+// @version 8.19
// @description GLM Coding Rush / 智谱 GLM Coding Plan 抢购助手,一键抢购油猴脚本 / Tampermonkey userscript,配合本地 CPU/GPU OCR 自动识别中文点选验证码并点击,支持多窗口并发、限流重试和支付页安全保护
// @author mumumi
// @include https://*bigmodel.cn/glm-coding*
@@ -19,9 +19,7 @@
// @grant GM_xmlhttpRequest
// @connect localhost
// @connect localhost:8888
-// @connect localhost
// @connect 127.0.0.1:8888
-// @connect 127.0.0.1
// @connect gtimg.com
// @connect *.gtimg.com
// @connect captcha.qcloud.com
@@ -510,14 +508,6 @@
AUTO_CLICK_SUB : true,
AUTO_CAPTCHA_CLICK : true,
AUTO_CAPTCHA_CONFIRM: false,
- RUSH_ENABLED : false,
- RUSH_TARGET_HOUR : 9,
- RUSH_TARGET_MIN : 59,
- RUSH_TARGET_SEC : 58,
- // v8.21: 高级模式(默认关闭;开启后可调点击/限流重试间隔,加 ±20% 随机抖动防风控)
- ADVANCED_MODE : false,
- CAPTCHA_CLICK_DELAY : 220, // 验证码三个字之间的间隔(ms)
- RL_RETRY_DELAY : 1000, // 限流弹窗关闭后多久再点购买(ms)
};
function loadCfg() { try { const s = GM_getValue(STORAGE_KEY, null); return s ? { ...DEF, ...JSON.parse(s) } : { ...DEF }; } catch { return { ...DEF }; } }
function saveCfg(c) { GM_setValue(STORAGE_KEY, JSON.stringify(c)); }
@@ -632,7 +622,7 @@
return time >= start && time <= end;
}
// ── DOM 访问 ──────────────────────────────────────────────────────────────
- const tabEl = n => document.querySelectorAll('#switchTabBox .switch-tab-item')[n - 1];
+ const tabEl = n => document.querySelectorAll('#switchTabBox .switch-tab-item')[n];
const btnEl = n => document.querySelector(`.glm-coding-package-list > div:nth-child(${n}) > div > .package-card-btn-box > button`);
const canBuy = b => b && !b.disabled && !b.classList.contains('is-disabled') && !b.classList.contains('disabled') && !/售罄|补货|暂时/.test(b.innerText || '');
const isSoldOut = b => /售罄|补货|暂时/.test(b?.innerText || '');
@@ -705,13 +695,8 @@
function checkPayDialog() {
const dlg = getPayDialog();
if (!dlg) return 'keep';
- // 抢购模式锁定:抢购确认后永不自动关闭支付弹窗
- if (window.__glmRushConfirmed) {
- window.__glmRushDialogSeen = 1;
- return 'keep';
- }
- // 绝对安全锁:成功过且当前 bizId 有效才不关
- if (everSucceeded && PS.bizId) return 'keep';
+ // 绝对安全锁:本次会话中只要成功过一次,永不关闭
+ if (everSucceeded) return 'keep';
// 接口还没返回
if (PS.inProgress) return 'keep';
// ── 情况 A:接口 555 系统繁忙 → 关弹窗试下一个
@@ -866,37 +851,6 @@
?
-
@@ -909,9 +863,6 @@
const getPkgs = buildTransferBox(document.getElementById('glm-wp'), PKGS_MAP, CFG.PACKAGES_PRIORITY, '套餐优先级');
const getTabs = buildTransferBox(document.getElementById('glm-wt'), TABS_MAP, CFG.TABS_PRIORITY, '订阅周期优先级');
panel.querySelector('#glm-cc').onclick = () => ov.remove();
- panel.querySelector('#glm-advanced').onchange = (e) => {
- panel.querySelector('#glm-advanced-panel').style.display = e.target.checked ? 'block' : 'none';
- };
panel.querySelector('#glm-multi').onclick = () => { openMultipleWindows(); };
panel.querySelector('#glm-cs').onclick = () => {
const p = getPkgs(), t = getTabs();
@@ -925,13 +876,6 @@
AUTO_CLICK_SUB : panel.querySelector('#glm-acs').checked,
AUTO_CAPTCHA_CLICK: panel.querySelector('#glm-acc').checked,
AUTO_CAPTCHA_CONFIRM: panel.querySelector('#glm-acf').checked,
- RUSH_ENABLED: panel.querySelector('#glm-re').checked,
- RUSH_TARGET_HOUR: parseInt(panel.querySelector('#glm-rh').value, 10),
- RUSH_TARGET_MIN: parseInt(panel.querySelector('#glm-rm').value, 10),
- RUSH_TARGET_SEC: parseInt(panel.querySelector('#glm-rs').value, 10),
- ADVANCED_MODE: panel.querySelector('#glm-advanced').checked,
- CAPTCHA_CLICK_DELAY: Math.max(50, parseInt(panel.querySelector('#glm-ccd').value, 10) || 220),
- RL_RETRY_DELAY: Math.max(100, parseInt(panel.querySelector('#glm-rld').value, 10) || 1000),
SAFE_DEFAULTS_VERSION,
});
ov.remove(); alert('已保存,即将刷新。'); location.reload();
@@ -943,16 +887,7 @@
// ═══════════════════════════════════════════════════════════════════════════
function tick() {
if (state === 'DONE') return;
- if (window.__glmRushConfirmed && window.__glmRushDialogSeen && !getPayDialog()) {
- window.__glmRushConfirmed = 0; window.__glmRushDialogSeen = 0;
- console.log('[GLM] rush lock cleared');
- }
if (ensureDiscountEntry()) return;
- // v8.21: 黄金时间内每天首条提示建议试试无痕模式(sessionStorage 去重)
- if (isGoldenTime() && !sessionStorage.getItem('glm_nudge_incognito_v1')) {
- sessionStorage.setItem('glm_nudge_incognito_v1', '1');
- setBar('🕶️ 抢不到?试试无痕窗口(Ctrl+Shift+N)!没有历史 Cookie/缓存/Service Worker,可能消除隐形的风控标记。Tampermonkey 需在扩展详情页允许在无痕中启用。', '#722ed1');
- }
if (state === 'SLEEPING') {
const rem = sleepUntil - Date.now();
if (rem <= 0) {
@@ -1107,14 +1042,7 @@
return;
}
setBar(`⚠️ 限流 ${taskRLCount}/${MAX_RL},自动关闭后重试...`, '#d46b08');
- // v8.21: 高级模式可调限流重试间隔(带 ±20% 抖动防风控)
- // 期间用 WAITING_RL 状态占位,避免下一轮 tick 重复关弹窗
- var _rld = Number(CFG.RL_RETRY_DELAY) || 1000;
- var _rldDelta = _rld * 0.2;
- var _rlDelay = Math.max(1, Math.round(_rld + (Math.random() * 2 - 1) * _rldDelta));
- taskPhase = 'WAITING_RL';
- setTimeout(() => { taskPhase = 'IDLE'; }, _rlDelay);
- return;
+ taskPhase = 'IDLE'; return;
}
if (isPayDialog()) {
const verdict = checkPayDialog();
@@ -1142,9 +1070,9 @@
return;
}
const prices = readDialogPrices();
- if (everSucceeded && PS.bizId || prices?.any) {
+ if (everSucceeded || prices?.any) {
state = 'DONE';
- if (everSucceeded && PS.bizId) showPayAlarm();
+ if (everSucceeded) showPayAlarm();
setBar('💳 支付弹窗已出现!请立即扫码支付! 脚本已停止。', '#16a34a');
} else {
setBar(`🔄 ${TABS_MAP[tab]}·${PKGS_MAP[pkg]} 弹窗等待确认...`, '#1677ff');
@@ -1221,24 +1149,15 @@
'use strict';
if (window.__glmCaptchaPromptBridge === 1) return;
window.__glmCaptchaPromptBridge = 1;
- const RUSH_CFG = (() => {
- try {
- const raw = GM_getValue('glm_coding_config_v5', '{}');
- const cfg = JSON.parse(raw || '{}');
- const ph = parseInt(cfg.RUSH_TARGET_HOUR, 10); const pm = parseInt(cfg.RUSH_TARGET_MIN, 10); const ps = parseInt(cfg.RUSH_TARGET_SEC, 10);
- return {
- enabled: cfg.RUSH_ENABLED === true,
- targetHour: Number.isFinite(ph) ? ph : 9,
- targetMin: Number.isFinite(pm) ? pm : 59,
- targetSec: Number.isFinite(ps) ? ps : 58,
- staggerMs: 2000,
- pollInterval: 50,
- pollTimeout: 20000,
- };
- } catch {
- return { enabled: false, targetHour: 9, targetMin: 59, targetSec: 58, staggerMs: 2000, pollInterval: 50, pollTimeout: 20000 };
- }
- })();
+ const RUSH_CONFIG = {
+ enabled: true,
+ targetHour: 10,
+ targetMin: 0,
+ targetSec: 0,
+ staggerMs: 2000,
+ pollInterval: 50,
+ pollTimeout: 20000,
+ };
const CAPTCHA_CFG = (() => {
try {
const raw = GM_getValue('glm_coding_config_v5', '{}');
@@ -1247,13 +1166,6 @@
return { AUTO_CAPTCHA_CLICK: true, AUTO_CAPTCHA_CONFIRM: false };
}
})();
- // v8.21.3: captcha IIFE 没有 CFG 闭包,必须走 CAPTCHA_CFG 拿点击/重试间隔
- const _ccd = Number(CAPTCHA_CFG.CAPTCHA_CLICK_DELAY) || 220;
- const _cdDelta = _ccd * 0.2;
- const _clickDelay = Math.max(1, Math.round(_ccd + (Math.random() * 2 - 1) * _cdDelta));
- const _rld = Number(CAPTCHA_CFG.RL_RETRY_DELAY) || 1000;
- const _rldDelta = _rld * 0.2;
- const _rlDelay = Math.max(1, Math.round(_rld + (Math.random() * 2 - 1) * _rldDelta));
function getWindowIndex() {
const params = new URLSearchParams(location.search);
return parseInt(params.get('wi') || '0', 10);
@@ -1261,8 +1173,8 @@
function getTargetTimestamp() {
const now = new Date();
const target = new Date(now.getFullYear(), now.getMonth(), now.getDate(),
- RUSH_CFG.targetHour, RUSH_CFG.targetMin, RUSH_CFG.targetSec, 0);
- const offset = getWindowIndex() * RUSH_CFG.staggerMs;
+ RUSH_CONFIG.targetHour, RUSH_CONFIG.targetMin, RUSH_CONFIG.targetSec, 0);
+ const offset = getWindowIndex() * RUSH_CONFIG.staggerMs;
return target.getTime() + offset;
}
let lastCaptchaText = '';
@@ -1301,14 +1213,14 @@
return new Promise((resolve, reject) => {
const start = Date.now();
function poll() {
- if (Date.now() - start > RUSH_CFG.pollTimeout) {
+ if (Date.now() - start > RUSH_CONFIG.pollTimeout) {
reject(new Error('poll timeout'));
return;
}
serverRequest('POST', '/result', { ts: ts }).then(d => {
if (d.has_result) resolve(d.result);
- else setTimeout(poll, RUSH_CFG.pollInterval);
- }).catch(() => setTimeout(poll, RUSH_CFG.pollInterval));
+ else setTimeout(poll, RUSH_CONFIG.pollInterval);
+ }).catch(() => setTimeout(poll, RUSH_CONFIG.pollInterval));
}
poll();
});
@@ -1331,6 +1243,8 @@
var selectors = [
'.tencent-captcha-dy__btn-confirm',
'.tencent-captcha-dy__footer .btn',
+ '.pay-dialog button.el-button--primary',
+ '.el-dialog__wrapper:not([style*="display: none"]) .el-button--primary',
'[class*="captcha"] [class*="confirm"]',
'[class*="captcha"] [class*="submit"]',
];
@@ -1805,8 +1719,6 @@
if (!result || !result.success || !Array.isArray(result.click_coords)) {
throw new Error('bad direct result: ' + JSON.stringify(resp).substring(0, 180));
}
- // v8.21.2: 成功后锁定 30 秒,期间同一张图不再重发(即使 catch 被异常触发)
- window.__glmSentLockUntil = Date.now() + 30000;
var rect = bgEl.getBoundingClientRect();
console.log('[captcha-direct-page] click result:', JSON.stringify(result).substring(0, 260));
for (var i = 0; i < result.click_coords.length; i++) {
@@ -1817,40 +1729,24 @@
if (!Number.isFinite(ny) && Number.isFinite(Number(c.rel_y))) ny = Number(c.rel_y) / rect.height;
if (!Number.isFinite(nx) || !Number.isFinite(ny)) continue;
dispatchClickAt(bgEl, nx * rect.width, ny * rect.height, c.char || String(i + 1));
- await new Promise(function(r) { setTimeout(r, _clickDelay); });
+ await new Promise(function(r) { setTimeout(r, 220); });
}
await new Promise(function(r) { setTimeout(r, 350); });
- rushState = 'idle';
- if (RUSH_CFG.enabled) {
- var targetTs = getTargetTimestamp();
- if (Date.now() < targetTs) {
- console.log('[captcha-rush] waiting ' + ((targetTs - Date.now())/1000).toFixed(1) + 's until target...');
- await waitForTargetTime();
- console.log('[captcha-rush] target time reached, confirming...');
- var clicked = findAndClickConfirm();
- if (clicked) { window.__glmRushConfirmed = Date.now(); }
- } else {
- var clicked = findAndClickConfirm();
- if (clicked) { window.__glmRushConfirmed = Date.now(); }
- }
- } else if (CAPTCHA_CFG.AUTO_CAPTCHA_CONFIRM) {
+ if (CAPTCHA_CFG.AUTO_CAPTCHA_CONFIRM) {
findAndClickConfirm();
} else {
console.log('[captcha-direct-page] captcha confirm is disabled; waiting for manual confirm');
}
} catch (e) {
console.error('[captcha-direct-page] error:', e);
- // v8.21.3: 出错时不再立即重置 captchaSent,避免 50ms tick 死循环。
- // 改为加 30s 冷却:期间相同 prompt 不再重发;prompt 变化时 checkCaptchaPrompt 自然会重置。
- window.__glmCaptchaCooldownUntil = Date.now() + 30000;
+ captchaSent = false;
+ lastCaptchaText = '';
} finally {
rushState = 'idle';
}
}
async function checkCaptchaPrompt() {
if (rushState === 'solving') return;
- // v8.21.3: 出错后 30s 冷却,期间不再触发 handleCaptchaDirectInPage
- if (window.__glmCaptchaCooldownUntil && Date.now() < window.__glmCaptchaCooldownUntil) return;
var found = findCaptchaPromptElement();
if (!found) { captchaSent = false; return; }
var payloadText = found.chars.join('');
@@ -1867,7 +1763,7 @@
console.log('[captcha] page direct solver:', payloadText);
handleCaptchaDirectInPage(found.chars).catch(function(e) { console.error('[captcha-direct-page] unhandled:', e); });
return;
- if (RUSH_CFG.enabled) {
+ if (RUSH_CONFIG.enabled) {
handleCaptchaRush(found.chars).catch(function(e) { console.error('[captcha-rush] unhandled:', e); });
} else {
serverRequest('POST', '/captcha', { text: payloadText, ts: Date.now() })
@@ -1877,5 +1773,5 @@
}
}
setInterval(checkCaptchaPrompt, 50);
- console.log('[captcha] bridge v2 started | rush=' + RUSH_CFG.enabled + ' | wi=' + getWindowIndex() + ' | target=10:' + String(RUSH_CFG.targetSec).padStart(2,'0') + '+' + (getWindowIndex() * RUSH_CFG.staggerMs / 1000) + 's');
+ console.log('[captcha] bridge v2 started | rush=' + RUSH_CONFIG.enabled + ' | wi=' + getWindowIndex() + ' | target=10:' + String(RUSH_CONFIG.targetSec).padStart(2,'0') + '+' + (getWindowIndex() * RUSH_CONFIG.staggerMs / 1000) + 's');
})();
diff --git a/scripts/userscripts/glm-coding-helper.user.js b/scripts/userscripts/glm-coding-helper.user.js
index a18a64a..020cbe8 100644
--- a/scripts/userscripts/glm-coding-helper.user.js
+++ b/scripts/userscripts/glm-coding-helper.user.js
@@ -1,7 +1,7 @@
// ==UserScript==
// @name 智谱 GLM Coding Plan 抢购助手 + 本地 OCR 自动验证码
// @namespace http://tampermonkey.net/
-// @version 8.21.3
+// @version 8.19
// @description GLM Coding Rush / 智谱 GLM Coding Plan 抢购助手,一键抢购油猴脚本 / Tampermonkey userscript,配合本地 CPU/GPU OCR 自动识别中文点选验证码并点击,支持多窗口并发、限流重试和支付页安全保护
// @author mumumi
// @include https://*bigmodel.cn/glm-coding*
@@ -19,9 +19,7 @@
// @grant GM_xmlhttpRequest
// @connect localhost
// @connect localhost:8888
-// @connect localhost
// @connect 127.0.0.1:8888
-// @connect 127.0.0.1
// @connect gtimg.com
// @connect *.gtimg.com
// @connect captcha.qcloud.com
@@ -510,14 +508,6 @@
AUTO_CLICK_SUB : true,
AUTO_CAPTCHA_CLICK : true,
AUTO_CAPTCHA_CONFIRM: false,
- RUSH_ENABLED : false,
- RUSH_TARGET_HOUR : 9,
- RUSH_TARGET_MIN : 59,
- RUSH_TARGET_SEC : 58,
- // v8.21: 高级模式(默认关闭;开启后可调点击/限流重试间隔,加 ±20% 随机抖动防风控)
- ADVANCED_MODE : false,
- CAPTCHA_CLICK_DELAY : 220, // 验证码三个字之间的间隔(ms)
- RL_RETRY_DELAY : 1000, // 限流弹窗关闭后多久再点购买(ms)
};
function loadCfg() { try { const s = GM_getValue(STORAGE_KEY, null); return s ? { ...DEF, ...JSON.parse(s) } : { ...DEF }; } catch { return { ...DEF }; } }
function saveCfg(c) { GM_setValue(STORAGE_KEY, JSON.stringify(c)); }
@@ -632,7 +622,7 @@
return time >= start && time <= end;
}
// ── DOM 访问 ──────────────────────────────────────────────────────────────
- const tabEl = n => document.querySelectorAll('#switchTabBox .switch-tab-item')[n - 1];
+ const tabEl = n => document.querySelectorAll('#switchTabBox .switch-tab-item')[n];
const btnEl = n => document.querySelector(`.glm-coding-package-list > div:nth-child(${n}) > div > .package-card-btn-box > button`);
const canBuy = b => b && !b.disabled && !b.classList.contains('is-disabled') && !b.classList.contains('disabled') && !/售罄|补货|暂时/.test(b.innerText || '');
const isSoldOut = b => /售罄|补货|暂时/.test(b?.innerText || '');
@@ -705,13 +695,8 @@
function checkPayDialog() {
const dlg = getPayDialog();
if (!dlg) return 'keep';
- // 抢购模式锁定:抢购确认后永不自动关闭支付弹窗
- if (window.__glmRushConfirmed) {
- window.__glmRushDialogSeen = 1;
- return 'keep';
- }
- // 绝对安全锁:成功过且当前 bizId 有效才不关
- if (everSucceeded && PS.bizId) return 'keep';
+ // 绝对安全锁:本次会话中只要成功过一次,永不关闭
+ if (everSucceeded) return 'keep';
// 接口还没返回
if (PS.inProgress) return 'keep';
// ── 情况 A:接口 555 系统繁忙 → 关弹窗试下一个
@@ -866,37 +851,6 @@
?
-
-
-
- 目标时间:
-
- :
-
- :
-
-
-
-
-
@@ -909,9 +863,6 @@
const getPkgs = buildTransferBox(document.getElementById('glm-wp'), PKGS_MAP, CFG.PACKAGES_PRIORITY, '套餐优先级');
const getTabs = buildTransferBox(document.getElementById('glm-wt'), TABS_MAP, CFG.TABS_PRIORITY, '订阅周期优先级');
panel.querySelector('#glm-cc').onclick = () => ov.remove();
- panel.querySelector('#glm-advanced').onchange = (e) => {
- panel.querySelector('#glm-advanced-panel').style.display = e.target.checked ? 'block' : 'none';
- };
panel.querySelector('#glm-multi').onclick = () => { openMultipleWindows(); };
panel.querySelector('#glm-cs').onclick = () => {
const p = getPkgs(), t = getTabs();
@@ -925,13 +876,6 @@
AUTO_CLICK_SUB : panel.querySelector('#glm-acs').checked,
AUTO_CAPTCHA_CLICK: panel.querySelector('#glm-acc').checked,
AUTO_CAPTCHA_CONFIRM: panel.querySelector('#glm-acf').checked,
- RUSH_ENABLED: panel.querySelector('#glm-re').checked,
- RUSH_TARGET_HOUR: parseInt(panel.querySelector('#glm-rh').value, 10),
- RUSH_TARGET_MIN: parseInt(panel.querySelector('#glm-rm').value, 10),
- RUSH_TARGET_SEC: parseInt(panel.querySelector('#glm-rs').value, 10),
- ADVANCED_MODE: panel.querySelector('#glm-advanced').checked,
- CAPTCHA_CLICK_DELAY: Math.max(50, parseInt(panel.querySelector('#glm-ccd').value, 10) || 220),
- RL_RETRY_DELAY: Math.max(100, parseInt(panel.querySelector('#glm-rld').value, 10) || 1000),
SAFE_DEFAULTS_VERSION,
});
ov.remove(); alert('已保存,即将刷新。'); location.reload();
@@ -943,16 +887,7 @@
// ═══════════════════════════════════════════════════════════════════════════
function tick() {
if (state === 'DONE') return;
- if (window.__glmRushConfirmed && window.__glmRushDialogSeen && !getPayDialog()) {
- window.__glmRushConfirmed = 0; window.__glmRushDialogSeen = 0;
- console.log('[GLM] rush lock cleared');
- }
if (ensureDiscountEntry()) return;
- // v8.21: 黄金时间内每天首条提示建议试试无痕模式(sessionStorage 去重)
- if (isGoldenTime() && !sessionStorage.getItem('glm_nudge_incognito_v1')) {
- sessionStorage.setItem('glm_nudge_incognito_v1', '1');
- setBar('🕶️ 抢不到?试试无痕窗口(Ctrl+Shift+N)!没有历史 Cookie/缓存/Service Worker,可能消除隐形的风控标记。Tampermonkey 需在扩展详情页允许在无痕中启用。', '#722ed1');
- }
if (state === 'SLEEPING') {
const rem = sleepUntil - Date.now();
if (rem <= 0) {
@@ -1107,14 +1042,7 @@
return;
}
setBar(`⚠️ 限流 ${taskRLCount}/${MAX_RL},自动关闭后重试...`, '#d46b08');
- // v8.21: 高级模式可调限流重试间隔(带 ±20% 抖动防风控)
- // 期间用 WAITING_RL 状态占位,避免下一轮 tick 重复关弹窗
- var _rld = Number(CFG.RL_RETRY_DELAY) || 1000;
- var _rldDelta = _rld * 0.2;
- var _rlDelay = Math.max(1, Math.round(_rld + (Math.random() * 2 - 1) * _rldDelta));
- taskPhase = 'WAITING_RL';
- setTimeout(() => { taskPhase = 'IDLE'; }, _rlDelay);
- return;
+ taskPhase = 'IDLE'; return;
}
if (isPayDialog()) {
const verdict = checkPayDialog();
@@ -1142,9 +1070,9 @@
return;
}
const prices = readDialogPrices();
- if (everSucceeded && PS.bizId || prices?.any) {
+ if (everSucceeded || prices?.any) {
state = 'DONE';
- if (everSucceeded && PS.bizId) showPayAlarm();
+ if (everSucceeded) showPayAlarm();
setBar('💳 支付弹窗已出现!请立即扫码支付! 脚本已停止。', '#16a34a');
} else {
setBar(`🔄 ${TABS_MAP[tab]}·${PKGS_MAP[pkg]} 弹窗等待确认...`, '#1677ff');
@@ -1221,24 +1149,15 @@
'use strict';
if (window.__glmCaptchaPromptBridge === 1) return;
window.__glmCaptchaPromptBridge = 1;
- const RUSH_CFG = (() => {
- try {
- const raw = GM_getValue('glm_coding_config_v5', '{}');
- const cfg = JSON.parse(raw || '{}');
- const ph = parseInt(cfg.RUSH_TARGET_HOUR, 10); const pm = parseInt(cfg.RUSH_TARGET_MIN, 10); const ps = parseInt(cfg.RUSH_TARGET_SEC, 10);
- return {
- enabled: cfg.RUSH_ENABLED === true,
- targetHour: Number.isFinite(ph) ? ph : 9,
- targetMin: Number.isFinite(pm) ? pm : 59,
- targetSec: Number.isFinite(ps) ? ps : 58,
- staggerMs: 2000,
- pollInterval: 50,
- pollTimeout: 20000,
- };
- } catch {
- return { enabled: false, targetHour: 9, targetMin: 59, targetSec: 58, staggerMs: 2000, pollInterval: 50, pollTimeout: 20000 };
- }
- })();
+ const RUSH_CONFIG = {
+ enabled: true,
+ targetHour: 10,
+ targetMin: 0,
+ targetSec: 0,
+ staggerMs: 2000,
+ pollInterval: 50,
+ pollTimeout: 20000,
+ };
const CAPTCHA_CFG = (() => {
try {
const raw = GM_getValue('glm_coding_config_v5', '{}');
@@ -1247,13 +1166,6 @@
return { AUTO_CAPTCHA_CLICK: true, AUTO_CAPTCHA_CONFIRM: false };
}
})();
- // v8.21.3: captcha IIFE 没有 CFG 闭包,必须走 CAPTCHA_CFG 拿点击/重试间隔
- const _ccd = Number(CAPTCHA_CFG.CAPTCHA_CLICK_DELAY) || 220;
- const _cdDelta = _ccd * 0.2;
- const _clickDelay = Math.max(1, Math.round(_ccd + (Math.random() * 2 - 1) * _cdDelta));
- const _rld = Number(CAPTCHA_CFG.RL_RETRY_DELAY) || 1000;
- const _rldDelta = _rld * 0.2;
- const _rlDelay = Math.max(1, Math.round(_rld + (Math.random() * 2 - 1) * _rldDelta));
function getWindowIndex() {
const params = new URLSearchParams(location.search);
return parseInt(params.get('wi') || '0', 10);
@@ -1261,8 +1173,8 @@
function getTargetTimestamp() {
const now = new Date();
const target = new Date(now.getFullYear(), now.getMonth(), now.getDate(),
- RUSH_CFG.targetHour, RUSH_CFG.targetMin, RUSH_CFG.targetSec, 0);
- const offset = getWindowIndex() * RUSH_CFG.staggerMs;
+ RUSH_CONFIG.targetHour, RUSH_CONFIG.targetMin, RUSH_CONFIG.targetSec, 0);
+ const offset = getWindowIndex() * RUSH_CONFIG.staggerMs;
return target.getTime() + offset;
}
let lastCaptchaText = '';
@@ -1301,14 +1213,14 @@
return new Promise((resolve, reject) => {
const start = Date.now();
function poll() {
- if (Date.now() - start > RUSH_CFG.pollTimeout) {
+ if (Date.now() - start > RUSH_CONFIG.pollTimeout) {
reject(new Error('poll timeout'));
return;
}
serverRequest('POST', '/result', { ts: ts }).then(d => {
if (d.has_result) resolve(d.result);
- else setTimeout(poll, RUSH_CFG.pollInterval);
- }).catch(() => setTimeout(poll, RUSH_CFG.pollInterval));
+ else setTimeout(poll, RUSH_CONFIG.pollInterval);
+ }).catch(() => setTimeout(poll, RUSH_CONFIG.pollInterval));
}
poll();
});
@@ -1331,6 +1243,8 @@
var selectors = [
'.tencent-captcha-dy__btn-confirm',
'.tencent-captcha-dy__footer .btn',
+ '.pay-dialog button.el-button--primary',
+ '.el-dialog__wrapper:not([style*="display: none"]) .el-button--primary',
'[class*="captcha"] [class*="confirm"]',
'[class*="captcha"] [class*="submit"]',
];
@@ -1805,8 +1719,6 @@
if (!result || !result.success || !Array.isArray(result.click_coords)) {
throw new Error('bad direct result: ' + JSON.stringify(resp).substring(0, 180));
}
- // v8.21.2: 成功后锁定 30 秒,期间同一张图不再重发(即使 catch 被异常触发)
- window.__glmSentLockUntil = Date.now() + 30000;
var rect = bgEl.getBoundingClientRect();
console.log('[captcha-direct-page] click result:', JSON.stringify(result).substring(0, 260));
for (var i = 0; i < result.click_coords.length; i++) {
@@ -1817,40 +1729,24 @@
if (!Number.isFinite(ny) && Number.isFinite(Number(c.rel_y))) ny = Number(c.rel_y) / rect.height;
if (!Number.isFinite(nx) || !Number.isFinite(ny)) continue;
dispatchClickAt(bgEl, nx * rect.width, ny * rect.height, c.char || String(i + 1));
- await new Promise(function(r) { setTimeout(r, _clickDelay); });
+ await new Promise(function(r) { setTimeout(r, 220); });
}
await new Promise(function(r) { setTimeout(r, 350); });
- rushState = 'idle';
- if (RUSH_CFG.enabled) {
- var targetTs = getTargetTimestamp();
- if (Date.now() < targetTs) {
- console.log('[captcha-rush] waiting ' + ((targetTs - Date.now())/1000).toFixed(1) + 's until target...');
- await waitForTargetTime();
- console.log('[captcha-rush] target time reached, confirming...');
- var clicked = findAndClickConfirm();
- if (clicked) { window.__glmRushConfirmed = Date.now(); }
- } else {
- var clicked = findAndClickConfirm();
- if (clicked) { window.__glmRushConfirmed = Date.now(); }
- }
- } else if (CAPTCHA_CFG.AUTO_CAPTCHA_CONFIRM) {
+ if (CAPTCHA_CFG.AUTO_CAPTCHA_CONFIRM) {
findAndClickConfirm();
} else {
console.log('[captcha-direct-page] captcha confirm is disabled; waiting for manual confirm');
}
} catch (e) {
console.error('[captcha-direct-page] error:', e);
- // v8.21.3: 出错时不再立即重置 captchaSent,避免 50ms tick 死循环。
- // 改为加 30s 冷却:期间相同 prompt 不再重发;prompt 变化时 checkCaptchaPrompt 自然会重置。
- window.__glmCaptchaCooldownUntil = Date.now() + 30000;
+ captchaSent = false;
+ lastCaptchaText = '';
} finally {
rushState = 'idle';
}
}
async function checkCaptchaPrompt() {
if (rushState === 'solving') return;
- // v8.21.3: 出错后 30s 冷却,期间不再触发 handleCaptchaDirectInPage
- if (window.__glmCaptchaCooldownUntil && Date.now() < window.__glmCaptchaCooldownUntil) return;
var found = findCaptchaPromptElement();
if (!found) { captchaSent = false; return; }
var payloadText = found.chars.join('');
@@ -1867,7 +1763,7 @@
console.log('[captcha] page direct solver:', payloadText);
handleCaptchaDirectInPage(found.chars).catch(function(e) { console.error('[captcha-direct-page] unhandled:', e); });
return;
- if (RUSH_CFG.enabled) {
+ if (RUSH_CONFIG.enabled) {
handleCaptchaRush(found.chars).catch(function(e) { console.error('[captcha-rush] unhandled:', e); });
} else {
serverRequest('POST', '/captcha', { text: payloadText, ts: Date.now() })
@@ -1877,5 +1773,5 @@
}
}
setInterval(checkCaptchaPrompt, 50);
- console.log('[captcha] bridge v2 started | rush=' + RUSH_CFG.enabled + ' | wi=' + getWindowIndex() + ' | target=10:' + String(RUSH_CFG.targetSec).padStart(2,'0') + '+' + (getWindowIndex() * RUSH_CFG.staggerMs / 1000) + 's');
+ console.log('[captcha] bridge v2 started | rush=' + RUSH_CONFIG.enabled + ' | wi=' + getWindowIndex() + ' | target=10:' + String(RUSH_CONFIG.targetSec).padStart(2,'0') + '+' + (getWindowIndex() * RUSH_CONFIG.staggerMs / 1000) + 's');
})();