Skip to content

Japscan: fix chapter list - #18111

Open
QuentinVdr wants to merge 9 commits into
keiyoushi:mainfrom
QuentinVdr:fix/japscan
Open

Japscan: fix chapter list#18111
QuentinVdr wants to merge 9 commits into
keiyoushi:mainfrom
QuentinVdr:fix/japscan

Conversation

@QuentinVdr

Copy link
Copy Markdown
Contributor

honeypot rows are rejected by hidden-style detection + slug/number binding. Pages are captured by loading the chapter in a detached WebView, letting the site's descrambler run, and reading the painted canvases — one driver for paginated (manga/bd/comic), one for webtoon (manhwa/manhua). Captures are spooled to cacheDir and served via an interceptor rather than held in memory.

Two things worth flagging:

  • Pages are re-encoded as JPEG. The originals are unreachable now, so this is unavoidable, but quality does drop vs v70.
  • Manual WebView instead of runWebView, which fixes the viewport to device metrics — the webtoon driver needs a forced 1920px viewport or the reader only renders one tile per page. Same pattern as the merged Comikey extension. Can add a viewport option to core/WebView.kt as a follow-up.

Closes : #17479 & #17968

Checklist:

  • Updated versionCode value in build.gradle.kts
  • Updated baseVersionCode in build.gradle.kts (if updated multisrc theme code)
  • Referenced all related issues in the PR body (e.g. "Closes #xyz")
  • Set the contentWarning configuration in build.gradle.kts appropriately
  • Have not changed source names
  • Have explicitly kept the id if a source's name or language were changed
  • Have tested the modifications by compiling and running the extension through Android Studio
  • Have removed web_hi_res_512.png when adding a new extension
  • This PR is AI-assisted, I have reviewed the changes manually and confirmed they are not slop

Starmania added a commit to Starmania/extensions-source that referenced this pull request Aug 11, 2026
Addresses the review findings on keiyoushi#18111. The first two are the blockers
that made the reader fail on the captcha path; the rest are robustness
items from the same review.

Blockers:

- Wait for the reader to mount before claiming the capture run.
  onPageFinished fires on the bare document when the WebView HTTP cache is
  warm — which it is after a long captcha solve — so the driver started
  before any reader script had run, found no #d-img containers, took the
  MISMATCH branch and called passDone(). That returned an empty page list
  reported as a successful load, and __japscanDriverStarted then locked out
  the real load when the reader did mount. Both drivers now poll for the
  reader DOM and only take the claim once it is there, standing down for a
  later fire otherwise. MISMATCH no longer calls passDone(), so a genuine
  mismatch surfaces as an error instead of a blank chapter.

- Start the idle watchdog after the captcha phase. lastActivity was stamped
  when JsInterface was constructed, before a captcha wait that can run to
  CF_MAX_POLLS * CF_POLL_INTERVAL_MS. The watchdog's first check therefore
  saw captchaPhase + 15s of "inactivity" against a 45s budget with nothing
  captured yet, aborting healthy runs whenever the solve took over ~30s.

Also:

- Constrain the page-cache interceptor to our own spool files. It read any
  absolute path handed to it under the sentinel host; these URLs are
  persisted with the page and outlive the run that produced them.
- Sniff PNG vs JPEG instead of always reporting image/jpeg: only the webtoon
  driver re-encodes, the paginated one stores the descrambler's blob as-is.
- Derive the WebView host allowlist from the base URL rather than hardcoding
  japscan.foo, which is already one rotation behind.
- Derive internalBaseUrl from baseUrl instead of repeating the origin as a
  second literal, so a domain rotation only has to touch build.gradle.kts.
  baseUrl itself still points at the popular listing, which is deliberate.
- Drop the "longest slug wins" chapter URL fallback. It fired exactly when
  the slug/number binding rejected every candidate, which is when a honeypot
  is the likely sole survivor.
- Give the spool a size ceiling as well as an age cutoff. One chapter
  measured 111 files / 12.4 MB and nothing was freed on read.
- Include the per-call random id in the spool session tag: the reader
  preloads the next chapter, so two captures starting in the same
  millisecond overwrote each other's tiles.
- Keep a partial capture instead of discarding it when the run ends on a
  timeout, and fail with a clear message when nothing was captured at all.
- Don't fail the chapter if dismissing the captcha WebView throws; the
  captcha is already solved by that point.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Japscan : error loading page

1 participant