User reported captcha visible but takes very long to reach backend (OCR itself
only 24ms). The main-page captcha IIFE polled every 1200ms, adding up to 1.2s
delay before processing starts. Reduce to 200ms so detection is near-instant.
The iframe IIFE already runs at 50ms; this brings the main-page path in line.
When all packages show '抢购人数过多,请刷新再试', the script used to
auto-refresh via location.replace - too aggressive, triggers heavier risk
control. Now it stops and tells the user to manually refresh (F5) until they
see the '特惠订阅' button. State set to DONE so the script pauses cleanly;
page reload on manual refresh restarts the scan fresh.
#32: canBuy/isSoldOut regex was only catching 售罄/补货/暂时; buttons showing
'抢购人数过多,请刷新再试' still passed canBuy -> wasted clicks. Add those +
'请稍后' to the block regex so the script skips and waits instead of clicking
a button that won't go through.
#33: macos-setup.md already had python-tk but framed as optional; Tk is actually
required (one-click-start.command launches a Tk GUI). Reword to make it clear
Tk is required, mention python.org installer bundles tkinter, list the error
messages users see when it's missing.
Also: CRLF fix from earlier, Linux support (PR #34), version bump 23.5 -> 23.6.
The @description shows on Greasy Fork/Tampermonkey list and update notices -
first thing users see. Add: (1) PP-OCRv6 in parens, (2) the risk-control
workaround one-liner '订阅入口被风控拦截时手动点特惠订阅即可,验证码自动打'.
OCR is now so fast (v6 tens of ms) that the first character click can land
before the captcha DOM finishes rendering/animating -> first click misses.
Previously the inter-click delay only applied between characters; the first
click had zero wait. Add a configurable pre-first-click random delay (default
150-300ms): new CAPTCHA_FIRST_CLICK_DELAY_MIN_MS/MAX_MS config, exposed in the
config panel under '验证码点字延时策略' as '首击前延时', passed through
getCaptchaDirectDelayConfig + normalize, slept at the start of
clickCaptchaDirectCoords. Set to 0 to disable.
Repro: auto-mode -> F8 pause -> manually close invalid popup -> F8 resume
-> stuck in WAITING for full timeout. Root cause: tick returns immediately
while paused, so taskClickTime stays frozen at the pre-pause click; on resume
elapsed includes pause duration. Worse, the manually-closed popup is gone,
so findRLModal/isPayDialog return null and WAITING has no branch to detect
'the popup I was waiting for is gone' -> falls through to the timeout tail.
Fix in setRuntimePaused(resume): if currently WAITING, reset taskClickTime to
now (re-count elapsed from resume); if no popup present anymore (closed during
pause), drop straight to IDLE to retry instead of waiting out the timeout.
Explains why not-closing-the-popup was fine (popup still detectable on resume).
The 30s wait (rare but should never happen) came from layered captcha-state
guessing (captchaSeen/GM counter/PS.inProgress branches) that misjudged some
edge cases as 'captcha in progress, wait patiently'. Strip all of it: after
click, just wait for a result (preview response / dialog), hard cap 10s. Normal
recognition (even on slow CPU) finishes in 5-8s; over 10s = stuck = retry.
Backend:
- Default OCR model PP-OCRv5_server_rec -> PP-OCRv6_tiny_rec (~14x faster,
83ms/img vs 1189ms on 379 real captchas, accuracy still 100%)
- Configurable via config.json ocr_model or env CNCAPTCHA_CPU_OCR_MODEL/GLM_OCR_MODEL
- GUI OCR model choices updated to v6 (tiny/medium) + v5 server fallback
- worker.py: split 3 crops into independent OCR tasks for parallel recognition
- ppocr_worker.py: batch forward (predict_batch_*) + single-crop path
- server.py: partial results aggregation + OCR_MODEL env passthrough
- requirements: paddleocr>=3.7.0 / paddlex>=3.7.0 (v6 requires)
Userscript v23.3:
- Fix: auto-click subscribe then wait 15s when click didn't trigger captcha.
Synthetic click sometimes gets swallowed by Zhipu frontend (button DOM ready
but component state machine not ready), no captcha pops up, main loop stuck in
WAITING until MODAL_WAIT=15000 timeout.
- Fix: use 'iframe got new prompt+bg image' as the signal. iframe increments GM
counter glm_captcha_seen_seq each time it sees a new captcha (prompt or bg
changed); main loop records baseline at click time, compares in WAITING -
counter increased = captcha popped, wait patiently; no increase after 1.5s =
click didn't trigger captcha, immediately retry subscribe. Counter is
monotonic, no residue, no timestamp race.
Root cause: v8.21 added a top-level `function jitterDelay()` helper.
In some Tampermonkey/cache scenarios the helper is undefined inside
the `handleCaptchaDirectInPage` async closure, throwing
`ReferenceError: jitterDelay is not defined`. The catch block then
resets `captchaSent = false` and `lastCaptchaText = ''`, so the
`setInterval(checkCaptchaPrompt, 50)` loop resends the same captcha
to the backend every 50ms ("dead loop sending captcha").
Fix: inline the ±20% jitter math at both call sites
(line 1814 and 1117), drop the helper entirely. Also added
`Number(...) || default` guards so a stale `CFG.CAPTCHA_CLICK_DELAY`
or `CFG.RL_RETRY_DELAY` of NaN/null/undefined falls back to the
DEF value rather than making `setTimeout(NaN)` fire instantly.
Side effect that confirmed the bug: the captcha bg element lost
its layout during the storm, so `rect.width = 0` and
`nx * rect.width = 0`, but `rect.left` was ~-9992 from a stale
frame ref — hence the marker spamming `(-9992, -10029)`.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PR #17 was merged as v8.19 (matching the rush mode feature label),
but our v8.19 was already the golden-time extension. Bump to v8.20
to reflect the combined feature set: golden-time 9:30-11:00 + rush
mode + tabEl 1-index fix + findAndClickConfirm payment-button guard.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
isGoldenTime() now covers 9:30-11:00 (was 9:30-10:10) so late-morning
restock windows are treated as rush mode: no page refresh, no MAX_RL
cap on 555 retries. Bump userscript to v8.19 and add CHANGELOG entry.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- change openMultipleWindows prompt default from 3 to 2 (max stays 10)
- add prominent RPM warning box in README rush section after GLM upgraded RPM limits
- strengthen language in step 5 and 重要提醒 from "may trigger" to "has caused widespread failure"
- sync root and scripts/userscripts/ copies
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
4 network functions changed to try fetch() first, fallback to GM_xmlhttpRequest:
- fetchImageDataUrl
- postDirect
- serverRequest
- fetchCaptchaImageDirect
fetch() has no 6-connection limit per domain (unlike GM_xmlhttpRequest),
eliminating the bottleneck when multiple windows/iframes hit localhost:8888.
GM_xmlhttpRequest is kept as fallback for CORS-restricted contexts.
Both userscript copies synced, SHA256 identical, trailing whitespace cleaned.