Skip to content

Block the game's Aliyun telemetry in Chromium capture mode - #291

Merged
shinkuan merged 2 commits into
v3from
feat/cdp-block-telemetry
Oct 16, 2026
Merged

shinkuan merged 2 commits into
v3from
feat/cdp-block-telemetry

Conversation

@shinkuan

Copy link
Copy Markdown
Owner

Problem

In Chromium (CDP) capture mode the game's Aliyun SLS web-tracking beacons (*.log.aliyuncs.com) leave the machine unchanged. Only the MITM proxy blocked them ([proxy] block_telemetry), and that block is not in the path in Chromium mode: the launched browser connects directly, and only one capture backend runs at a time. Past Chromium-mode sessions show login_stats, game_status, certificate_info, mj_connect_success, emo_stats and game_network_stats beacons going out. The web client sends a CORS preflight before each one, and that preflight's URL already carries the full query-string payload.

Change

  • New setting [capture.chromium] block_telemetry (default on), with a toggle in the Chromium section of Settings → Capture and a hint in all four locales. A config written before the field existed gets the default.
  • cdp.rs:
    • Every attached page now arms request-stage Fetch patterns for the SLS domain (*log.aliyuncs.com/*, *log.aliyuncs.com:*). They go in the same Fetch.enable call as the existing Tenhou client rewrite, because each call replaces the previous patterns.
    • A paused request whose host is an SLS host is failed with BlockedByClient, which gives the page net::ERR_BLOCKED_BY_CLIENT, the same error an ad blocker produces. Anything else the globs catch is continued untouched.
    • Request-stage and response-stage pauses are told apart by the protocol's responseStatusCode / responseErrorReason fields.
  • Timeline: a blocked request keeps its sls_beacon annotation and also gets an akagi_blocked marker, as on the MITM leg. Each block is also logged under akagi::capture::http, without the query string.
  • capture::telemetry::is_sls_host: the SLS domain check moves out of the MITM CONNECT refusal so both backends share it. MITM behavior is unchanged.
  • async-trait 0.1.89 → 0.1.92: clippy 1.99 reports clippy::double_must_use on every #[async_trait] method because 0.1.89 adds #[must_use] to an already-must_use return type. 0.1.92 no longer does, so clippy -D warnings passes on current stable again.

Coverage and limits

A page-scoped Fetch.enable also pauses the beacon XHR's CORS preflight and requests from the page's dedicated workers, so all of those are blocked. Worker requests are blocked but are not recorded on the timeline: page-scoped Network events do not report them.

Requests a tab makes before the page poll attaches to it are not covered. That window is up to about a second. In recorded sessions the game sends its first beacon at login, several seconds after attach.

Testing

  • Unit tests:

    • interception patterns per stage
    • the globs cover every SLS URL shape
    • the host check rejects URLs that only mention the domain
    • stage detection
    • config default and backward compatibility
  • tests/chromium_telemetry_block.rs runs the real cdp::run loop against headless Chromium. Host-resolver rules send *.log.aliyuncs.com to a local sink, and the test page fires an XHR (with preflight), an <img>, sendBeacon and a worker fetch:

    • with blocking on, the sink receives nothing and the timeline carries sls_beacon + akagi_blocked
    • with blocking off, the same page reaches the sink, so the mapping is shown to work

    It needs a browser, so it is #[ignore]d. Run it with cargo test --test chromium_telemetry_block -- --ignored. It passes locally on Chrome 155.

  • Locally on the latest stable toolchain: cargo fmt --check, cargo clippy --all-targets -- -D warnings, cargo test --lib, cargo test --tests, cargo test --no-run --all-targets --locked, npm run lint, tsc -b.

Chromium capture let the game's analytics beacons (*.log.aliyuncs.com)
out unchanged; only the MITM proxy dropped them. Arm request-stage Fetch
patterns for the SLS domain on every attached page and fail matching
requests as BlockedByClient, alongside the existing Tenhou client
rewrite in the same Fetch.enable call. Page-scoped interception also
pauses CORS preflights and dedicated-worker requests.

New setting [capture.chromium] block_telemetry (default on) with a
Settings toggle. Blocked requests keep their sls_beacon annotation on
the timeline plus an akagi_blocked marker. The SLS host check moves to
capture::telemetry and is shared with the MITM CONNECT refusal.

tests/chromium_telemetry_block.rs drives the real CDP loop against a
headless browser (ignored by default: needs a browser).
clippy 1.99 flags clippy::double_must_use on every #[async_trait] trait
method, because async-trait 0.1.89 adds #[must_use] to a method whose
Pin<Box<dyn Future>> return type is already must_use. 0.1.92 no longer
emits the attribute, so cargo clippy --all-targets -D warnings passes on
the latest stable toolchain again.
@shinkuan
shinkuan merged commit e78f1bc into v3 Oct 16, 2026
4 checks passed
@shinkuan
shinkuan deleted the feat/cdp-block-telemetry branch October 16, 2026 07:53
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.

1 participant