Skip to content

Releases

1.9.8

Choose a tag to compare

@github-actions github-actions released this 28 Oct 11:54

v1.9.8

  • 这一页同时覆盖 1.9.4–1.9.7 / This page also covers 1.9.4–1.9.7: 那四版只在测试机上滚过、没有单独发布,
    内容一并随本版出:国际版 6.7.1 全量重挂锚、历史记录服务进身份改写名单、详情页广告族新增一个开关,
    外加两处工程收尾(删掉已漂移的直播门控探针;构建入口先清空 class 输出目录,被删掉的匿名内部类不再进包)。
  • 6.7.1 全量重新挂锚 / Re-anchored across 6.7.1: 离线缓存的取流地址跟着换到下载器实现类的两个 enqueue
    首参(原先挂的 onStartCommand 与 spec 构造器在 6.7.1 上一次都不再走),直播后台播放门、首页推荐卡族与
    不自动刷新入口、fnval 位、听完守卫改按角色验收,各功能开关的开/关两腿(含总闸基线)真机各跑一遍;
    底栏隐藏「我的」在 6.7.1 的渲染层锚点也修了漂移。
  • 历史记录不再整条标「稿件失效」/ The history service joined the rewrite scope: svc=History 之前没进
    定域改写名单,真机开/关两腿各跑一遍,关掉后失效标记立刻回来。
  • 详情页广告族归到一个开关 / The detail-page ad family is now one switch: 播放器下方商品卡改挂在
    CM.hasCmUnderPlayer() 的返回值上(原先挂的两处回包回调在 6.7.1 上根本收不到稿件详情),同一条开关
    也管简介区楼层广告与「视频提及」里的游戏推广卡(只摘 MENTION_TYPE_GAME,UP 自己的课程/充电链接不动)。
  • 配置投递修三处 / Three config-delivery fixes: 宿主回前台就重读文件通道(不必再等冷启动)、应用成功后
    回一条投递回执让界面把「已保存」和「宿主真的用上了」分开说、conf 路径改按当前用户区与宿主包名拼——
    应用分身/安全文件夹/工作资料里「改了不生效、给了 root 也没用」正是这第三处造成的。
  • root/shell 兜底换了落点并加了两道锁 / The root/shell fallback moved and got two locks: KSU 域在宿主
    files 能删不能建,原来那份兜底等于没有,现在先落 /data/local/tmp(写完切回前台即生效,非 root 也能
    adb push);正因为那里世界可写,读侧要求 conf_key 防伪键、且只在没有可信副本压得住它时才采纳,
    兜底成败也一并挂进设置页状态行并写 logcat。

1.9.3

Choose a tag to compare

@github-actions github-actions released this 19 Oct 18:10

v1.9.3

  • 官方下发的地址不再被扔掉 / The URLs Bilibili handed out are no longer discarded: 国内档原先按
    「国内节点表」筛选 playurl 下发的地址,真机一次播放下发的 cosov(41 条流)与 akamai(12 条流)
    两条全被丢弃,候选于是 100% 变成「拿海外签名问大陆节点」,其中三个大陆镜像在本机连 DNS 记录都没有;
    现在任何模式都保留下发原址,并让它们排在换节点派生的地址之前。/ Mainland mode no longer drops the
    delivered URLs; they stay at the head of every candidate list.
  • 本机连不上的节点跨进程记账,只降级不删候选 / Nodes this machine cannot reach are remembered — demoted, never deleted:
    基线里 19 条 out=0 disk=0 net=0 全来自「DNS 查不到名字 / 连接被拒」这类链路侧失败,旧写法只在进程内退避,
    每次起播重新撞一遍同样的死节点(首字节 max 2962 ms);现在同一网络里攒够两次就把它挪到队尾,账本落在宿主
    files 目录、以本机网络身份为键(被动读一次网卡,不监听、不轮询),十分钟 TTL 自愈,
    节点交付过字节立刻销账;播放器中途挂断的那几次连不上也照样记账,不再白撞。/ Two link-side failures move a
    node to the tail, keyed by the machine's own network identity so a network change invalidates the ledger on its
    own; candidates are only re-ordered, never removed.
  • 两个进程记的账现在真的会相加 / The two processes now add up to the same count: 落盘前那趟读盘合并按「谁的
    时刻新听谁的整笔」覆盖,另一个进程较小的计数会把刚写下的降级进度顶回去,两次失败因此永远凑不齐门槛;现在
    「叫不应」和「空转」各按自己最新的一笔合并。/ Each counter merges by its own timestamp, so a later process
    continues the other's count instead of overwriting it.
  • 拨通了不吭声也算节点的问题 / A node that takes the call but never answers is charged too: 首字节超时原先
    只在进程内退避,每次起播照样重新撞一遍那个不吭声的地址;现在同一网络里三次这样的空转同样把它挪到队尾。
    4xx 与 416 不进这本账——缺一个文件不该让整台机器在所有视频里被降级。/ Three zero-byte idle tries demote a node
    as well, while HTTP errors stay out of the ledger.
  • 重连不再把退避记忆清零 / A reconnect no longer wipes the backoff memory: 解析器原先按「路径+签名」缓存,
    而播放器每重连一次就把整套 query 重签,于是几乎每次重连都新建一个解析器,刚学到的退避与封禁跟着旧的一起被
    淘汰;现在按文件路径复用同一个解析器,只把拨号用的签名换成刚下发的。/ Resolvers are cached by file path now,
    so backoff survives reconnects while the signature used for dialling is refreshed.
  • 412/429 之后三十秒内每条流只走一条连接 / A 412 or 429 drops every stream to one connection for 30 s:
    限速信号说的是这台机器的总请求速率,不是某条地址的错,按节点退避只换掉被拒的那一条、其余七路照样撞,
    一次被拒容易放大成整批重连(界面上的 0 KB);现在降速窗内窗口收成一块、探路与对冲都暂停,只降并发、不关加速。
    / The limit is charged globally for 30 s: the window collapses to one piece and probing/hedging pause, while
    acceleration itself stays on.
  • 一批稿件在国际版又能看了 / A batch of videos is watchable again: 「视频不见了哦」不是 IP 区域封锁
    (同一手机同一网络的其它客户端能播、PC 网页也能看),而是服务端按 mobi_app 裁剪这批稿件的下发;现在取稿件
    与取播放信息这两处(bilibili.app.viewunite.v1 / bilibili.app.playerunite.v1)沿用 IP 属地那一份身份声明,
    定域到这两个服务,不开全局档。/ The detail and play-info RPCs now carry the same domestic identity the
    IP-label feature already uses, scoped to those two services rather than switching on global mode.

1.9.2

Choose a tag to compare

@github-actions github-actions released this 10 Oct 12:01

v1.9.2

  • 起播卡 0 KB/s 的两条根因都收掉了 / Both causes of the 0 KB/s startup stall are fixed: 一是代理
    同时在流的上限只有 12,而真机播放器的并行 range 连接会冲到 13,一被打满就 503 拒客,播放器并不
    优雅回落而是整批拆连重连、重连又叠在没排干的旧连接上再次越过上限,形成「0 KB、偶尔跳 2 KB、隔几秒
    才自愈」的正反馈——上限提到 64,真正的上游并发本就由下载器的并发闸把关,这里只兜底防泄漏;二是节点
    空响应的封禁在进程内永不过期,宿主主进程连跑两天会把可用节点越缩越少直到代理被饿死(只有强停重启才
    恢复),现在给每次 strike 记时间戳、按 120 秒时效惰性淘汰,长命进程能自愈。/ The stream cap of 12
    tripped the player's own reconnect loop (raised to 64), and empty-reply node bans never expired
    in-process (now a 120 s strike TTL).
  • 干净卡片偶尔仍吃掉上传者名字 / Clean cards no longer drop the uploader name: 带角标那代小卡的
    底部名字行读的是 desc 而不是 args.up_name,服务端把名字放进 up_name、把这一行让给角标时 desc
    是空的,只清角标文字会让这行既无角标也无名字;现在清完角标把 up_name 回填进 desc,名字落回它本来
    的槽位。/ The badged card's name row reads desc, not args.up_name; after clearing the badge we
    now backfill desc from up_name so the name returns.

1.9.1

Choose a tag to compare

@github-actions github-actions released this 10 Oct 09:23

v1.9.1

  • 干净卡片不再把上传者名字一起清掉 / Clean cards keep the uploader name: 「推荐理由」那族数据原先
    整对象置 null,而宿主把这个对象同时当作「名字行要不要渲染」的信号,于是标签和名字一起消失;现在
    保留对象、只清里面的文字与配色,实机开启轮 6/6 张卡名字都在、屏上「××万点赞」这类标签一条不剩。
    / The reason-tag object doubled as the host's signal to draw the name row, so nulling it removed the
    name too; now only its text and colors are cleared.
  • 投递失败看得见 / A failed config delivery is now visible: 设置页原先在拉起宿主之前就显示
    「已保存,正在拉起」,拉起被 ROM 拦下时用户读到的是「开关不生效」;现在这一步的失败原因直接印在
    状态行和 Toast 上,并给出一条不依赖模块拉起的手动重挂路径(彻底退出 B 站再打开一次)。同一轮
    顺手删掉了首页那组早已用完的反编译探针,它每次启动打几十行、恰好把那行供人自查的 confSrc=
    冲出日志。/ Save no longer claims a delivery it did not complete; the reason and a manual fallback
    are shown, and the spent home-screen RE probe that drowned the self-check line is gone.
  • 配置代次单调化 / Config generation is now monotonic: 保存代次从「取当前时刻」改为
    「取当前时刻与已有最大代次 + 1 的较大者」,系统时钟回拨(换机、恢复备份、手动改时间)不会再让此后
    每一次保存都被宿主判成陈旧配置而永久丢弃。/ Generation is max(now, last+1), so a clock set
    backwards can no longer make every later save look stale to the host.

1.9.0

Choose a tag to compare

@github-actions github-actions released this 10 Oct 05:40

v1.9.0

  • 起播不再先跑一趟探路 / Startup no longer waits for a probe round trip: v1.8.0 把「问 1 个字节」的探路
    串在起播请求之前,首字节成了两段往返相加,候选全黑时还要把探路预算等满;现在第一条候选立刻开流、
    探路只在旁边问「还有谁活着、文件多大」(桌面回归 631→306 ms、929→5 ms)。剩下的快慢就看节点给字节有多快。
    / The first candidate now streams immediately while probing runs alongside it, so startup pays one
    round trip instead of two.
  • 新增两个开关 / Two new switches: 「关闭大卡片」(feed_no_large_card,按卡片类型名移除
    占满整屏宽度的轮播卡/大封面卡/内联播放卡,双列小卡一张不动;实测它与「只展示 UGC」重叠,
    但那条会连直播卡和广告卡一起删,这条只管大卡)与「干掉云视听小电视」
    (player_no_activity_meta,清空弹幕回包里的 activity_meta 活动浮层素材,移植自 MBGA);
    均出厂默认关。/ A big-card remover keyed on card type, and a switch clearing the dm reply's
    activity_meta activity-overlay payload; both off by default.
  • 「干掉云视听小电视」只证到清空、未证到界面消失 / clearing proven, disappearance not:
    挂点、命中、清空三步有实机日志,而浮层从屏上消失要在活动期拿同一稿件肉眼 A/B,本版不声称已证。
    / The hook fires and clears a real payload; the visual removal still needs an on-device A/B.

1.8.0

Choose a tag to compare

@github-actions github-actions released this 09 Oct 14:50

v1.8.0

  • 首页推荐流清洗三项(移植自 MBGA)/ Three feed-cleanup switches ported from MBGA:
    只展示 UGC(cardGoto≠av 的官方合集/活动/直播整卡移除)、干净的视频卡片(去推荐理由
    与竖屏角标,UP 入口沿用宿主自己的名字行)、禁止竖屏播放器(卡片路由 bilibili://story/<id>
    改写为横屏播放页自己的最小路由 bilibili://video/<id>);三项都会改变首页内容,出厂默认关。
    / UGC-only feed, clean video cards and no-portrait-player switches, all off by default.
  • 6.6.0 的卡片载体已实机取证 / The 6.6.0 card carrier is now proven on device:
    推荐流列表元素是 gson 直解、协议名齐全的混淆类(每种 card_type 一个类),旧版
    BasicIndexItem/SmallCoverV2Item 那套读写与点击链路口径都已失效;三项因此统一挂在
    同一个协议解析出口、按 @SerializedName 定位与写回,实机 A/B 三项各自读数通过。
    / Feed items are gson-built obfuscated classes, one per card type; all three switches act at
    one parse exit via protocol names, verified with on-device A/B runs.
  • 两处失败模式做进了实现 / Two failure modes are designed in: 只展示 UGC 带 fail-open
    (整批都不匹配判据时不过滤并告警一次,附 cardGoto 直方图);禁止竖屏播放器只保留 id、
    丢掉卡片自带的预载参数段——带着它会让横屏播放页在启动时崩掉宿主(PITFALLS #40),
    因此这一项只保留实测生效的数据层一路,6.4.0/6.5.0 那条 BasicIndexItem.getUri 兜底已撤
    (拿不到实机读数、同形改写又会崩,等于把未知风险留在包里),老宿主上它会静默不生效。
    / The UGC filter fails open with a one-shot histogram, and the player rewrite keeps only the
    id because the card's own preload query crashes the landscape player (PITFALLS #40).
  • 多线程加速的两处实机问题 / Two on-device accel fixes: 起播不再卡在 0 KB——首字节不再等
    「一整块 256 KiB 先下完」,改成先用 1 个字节问出活着的节点、再在一条连接上边收边吐(每口
    ≤64 KiB),并发 6–8 条播放流也不再互相抢光并发许可;拖回看过的区间不再重新加载——块清单
    原先只在连接关闭时落盘,播放中途进程被杀就没有清单可读,现在每 8 MiB 落一次,实机重开同一条
    视频的读数是 disk=1207864 net=0。 / The first byte no longer waits for a whole 256 KiB piece,
    and the block index is flushed every 8 MiB instead of only when a connection closes.
  • 签名密钥已更换,需要卸载重装 / New signing key, uninstall first: 本版用新密钥签名,与
    1.7.x 及更早版本不同源,原地升级会被系统拒绝(INSTALL_FAILED_UPDATE_INCOMPATIBLE),
    请先卸载旧版再装本版;卸载会清掉模块自己保存的开关设置,装好后重新勾一遍即可。
    / This build is signed with a new key, so updating in place is rejected — uninstall the old
    version first, then install; module settings are cleared by the uninstall.

1.7.14

Choose a tag to compare

@github-actions github-actions released this 01 Oct 12:54

v1.7.14

  • 首页直播板块解锁 / Home live channel unlocked: 国际版服务端按身份把顶栏「直播」那一格裁掉了,
    模块在「标题」与「页面」共用的那个收口处把它补回去,追加在末尾所以既有页的下标一个都不动,
    点「直播」进的就是直播流 / The server drops the live tab from the home top bar for the intl
    identity; the module re-adds it at the single funnel that feeds both the titles and the pager
    pages, appended last so existing page indices stay untouched.
  • 点头像进「我的」修好 / Avatar now opens the Mine page: 6.6.0 起底栏点击不走旧动作总线,
    模块改为直接投宿主自己那发「按深链切底栏页」的动作(匹配键从宿主下发的那格数据里现读,
    6.3.0–6.6.0 四版候选都在 apk 里逐个对读过),此前头像点开落到「动态」的那次几何错位一并修掉 /
    On 6.6.0 the bottom-bar click no longer goes through the old action bus, so the module now
    dispatches the host's own route-to-tab action; the earlier mis-tap that landed on the dynamic
    feed is fixed too.
  • 评论区/主页 IP 属地 6.6.0 复核 + 自检日志改用真键名 / IP location re-verified on 6.6.0:
    功能开/关各跑一轮实机对照(关闭时两个不同视频的属地标签都消失,开启时评论区与空间页正常显示属地),
    启动自检行现在打印 conf 的真实键名(ip_location_enabled= 而不是 ip=)/ On-device A/B on 6.6.0
    confirms the rewrite chain still delivers location, and the startup self-check line now prints
    the real conf key names so the log can't be copied into a conf file as a wrong key.

1.7.13

Choose a tag to compare

@github-actions github-actions released this 30 Sep 12:15

v1.7.13

本版含未单独发布的 v1.7.12;1.7.11 及以下直接覆盖安装。
Supersedes the never-published v1.7.12 — install directly over 1.7.11 or below.

  • 适配国际版 6.6.0(9130300)/ Adapted to host 6.6.0: 混淆锚点整族换名,每个落点都按「形状+角色」
    在 dex 里重定位、装机一行日志验收:fnval kJ1.a→aK1.a、听模式完成监听 CE1.f→lK1.j、
    feed 解析入口 request.g→request.h、直播后台门 HX.c$b.q1()→JX.b$b.m1()、
    gRPC 身份描述符族 kr1.*→xr1.*。旧名多数已被 R8 复用成无关类,故候选一律过形状校验;
    同时删掉 6.5.0 起就已断死的三条身份兜底链(ip1.h 标记、mq0.a/oq0.a、kr1.a/up1.a)。
    / Anchors renamed as a whole family on 6.6.0; each re-located by shape+role and confirmed on
    device, dead legacy fallbacks removed.
  • 多 CDN 加速的两处修复 / Accelerator: hole-in-stream and frozen-picture fixes: 节点把中段
    子块截短时,旧代码仍跳到「计划」的下一个起点,响应体留下空洞(真机:播到中段花屏,拖一下进度条才好);
    起播后某子块彻底失败时直接向上抛异常,而代理开口后抛异常等于把流砍尾(画面定格、进度条照走)。
    两处现在都「交付到事实边界,再从断点单连接续传到末尾」;候选全被退避挡光时兜底通道退回地址全集。
    桌面回归先复现两处错再修好,967 项断言全过。
    / A truncated middle piece used to leave a gap (mid-video artifacts) and a failed piece cut the
    stream off; both now resume from the real boundary on one connection.
  • 首页不自动刷新拦对类型 / Home no-auto-refresh now vetoes the right flush: 6.6.0 真正会发的自动
    刷新是 FLUSH_ON_BACK_PRESS(停在首页 tab 按返回键 → 整屏换推荐流),旧名单只拦 AUTO_BACK_*
    等于没拦。真机同一动作两侧各跑一次:关 → 首页 5 条标题全换(0 重合);开 → auto refresh blocked
    且 5/5 与基线一致;手动下拉不受影响。名单维持显式四条(宿主的 isUserRequest() 会把双击 tab、
    底部刷新按钮误判成非用户请求)。机制与取证订正见 PITFALLS #35。
    / On 6.6.0 the flush that actually fires is FLUSH_ON_BACK_PRESS; verified on device by an A/B
    on the same gesture (off: feed fully replaced — on: blocked, titles identical).

1.7.11

Choose a tag to compare

@github-actions github-actions released this 28 Sep 16:01

v1.7.11

本版包含未单独发布的 v1.7.10 全部变更;1.7.9 及以下用户直接安装本版。
This release supersedes the never-published v1.7.10 — install directly over 1.7.9 or below.

  • 修复:听完自动暂停在 6.5.0 听视频上不生效 / Fixed: pause-after-listen now works on
    6.5.0 listen mode
    : 旧实现挂在播放器的完成回调上吞事件——6.5.0 的听视频框架根本不用
    这个回调决定切集
    (真机取证:完成事件后 138ms 框架独立发起下一集加载,循环/顺序模式
    路径相同)。本版改为两层:完成事件到达时把播放器停在片尾前 0.8s 并暂停(用户可见的
    「听完暂停」),随后 6 秒守卫窗内拦截播放器实例上的一切加载/起播调用。真机验证:完成后
    138ms 框架试图起播下一集,被守卫精确拦下——下一集不会自动播放;注:框架自己的列表
    指针仍会前进(UI 显示切到下一集),守卫拦的是播放而非列表状态,这是当前语义。普通视频
    行为不受影响(播完原生即暂停)。零监听、零轮询。
    / The old hook swallowed the player's completion callback — but 6.5.0's listen mode
    decides episode switching independently (device evidence: the framework fired the
    next-episode load 138 ms after the completion event). Now: on completion the player is
    parked 0.8 s before the end and paused, and a 6-second guard window blocks every
    load/start call on the player instance, so the next episode never auto-plays. Note: the
    framework's own playlist pointer still advances (the UI jumps to the next episode) — the
    guard blocks playback, not the list state. Verified on device; normal (non-listen)
    playback is untouched. No listeners, no polling.
  • 修复:首页「不自动刷新」在 6.5.0 失效 / Fixed: no-home-auto-refresh ineffective on 6.5.0:
    6.5.0 把 feed 状态对象改成了嵌套结构(列表在 state.a.a 两层深),「已有内容」判定只扫
    直接字段,永远判成空状态 → 每次自动刷新都被放行。现改为深度受限的递归搜索,并加探针
    (fired / allowed-empty / blocked 三态首触日志)。真机验证:切后台返回时
    auto refresh blocked, type=AUTO_BACK_FROM_OTHER_PAGE。/ 6.5.0 nested the feed state
    object, so the has-content guard always saw "empty" and let every auto-refresh through.
    The guard now searches nested fields, with first-fire probes for tri-state diagnosis;
    verified on device (background-return refreshes are blocked).
  • 新增:直播后台播放入口(6.5.0)/ New: live background-play entry on 6.5.0:
    国际版 6.5.0 直播间的播放器设置面板里,「后台播放」(应用退至后台,可继续播放)一项被
    房间 specialType 判定跳过而不创建。本版把该判定强制放行——设置面板恢复显示「后台播放」
    开关,打开后退出到后台直播声音继续。真机验证:开关出现、后台播放正常(MediaSession
    PLAYING 持续)。注意这与「仅播声音」(观看中切纯音频)是两个特性,后者仍受限于播放器
    元数据检查,未在本版处理。/ On 6.5.0 the live-room settings panel skipped creating the
    "Background play" entry behind a room specialType check. The check is now forced open —
    the entry is back, and toggling it keeps live audio playing after leaving the app.
    Verified on device (MediaSession stays PLAYING in background). Note this is distinct
    from audio-only switching while watching, which remains gated and is not addressed here.
  • 修复:头像 →「我的」打开完整页面(6.5.0)/ Fixed: avatar → full Mine page on 6.5.0:
    6.5.0 上底栏 tab 选中动作类从 FC1.c 漂移为 jD1.b/jD1.c(HomeFrameViewModel.w0 参数
    接口同组换名,方法名未漂移)、tab_host 资源 id 从 0x7f0938b4 漂到 0x7f0938d3——真实
    派发、合成点击、tab 服务三级入口全部失守,头像降级为深链,打开的「我的」页面不完整。
    现在动作类按候选列表(jD1.c/FC1.c)+ 形状校验解析,全失败时把 w0 参数接口名打进日志
    (下次漂移一行日志定位);合成点击的 tab_host 查找失败时按资源名运行时解析兜底。
    实机验证:头像点击走真实派发,页面含离线缓存/历史/收藏/创作中心等完整功能区。
    / On 6.5.0 the bottom-bar tab-select action class drifted (FC1.c → jD1.c) and the
    tab_host resource id moved, so all three entry paths failed and the avatar fell back to
    the incomplete deep-link shell. The action class is now resolved from a candidate list
    with shape validation (falling back to logging the dispatch interface for the next
    drift), and the tab-host lookup falls back to resolving by resource name.
  • 移除:分享面板「分享到 QQ」/ Removed: Share-to-QQ entry: QQ 侧对重签名包的
    「非官方应用 25201」校验已覆盖全部宿主版本(6.3.0 也失效),该 hook 无存在意义,连同
    设置项一并删除。/ QQ now rejects repackaged builds on every supported host version, so
    the injection hook and its settings entry are removed.
  • IP 属地改写点加活体计数 / Liveness counters on the identity-rewrite point: 排查
    「评论区属地失效」时发现 once-per-process 探针会掩盖长会话中的钩子失效。改写点现在带
    滚动计数(每 200 次写打一条 alive,每 200 次实际改打一条心跳),与 moss RPC 计数对照
    即可分层定位:钩子死 / 服务端行为变 / 传输路径变。/ The rewrite hook now logs rolling
    counters so a mid-session hook death is distinguishable from a server-side change —
    the previous once-per-process probe could mask exactly that.
  • 构建 / Build: versionCode 23。

1.7.3

Choose a tag to compare

@github-actions github-actions released this 12 Sep 21:08

v1.7.3

  • 适配 6.5.0:评论区/主页 IP 属地修复 / 6.5.0 support: comment & profile IP location
    fixed
    : 宿主 App 自动升级 6.5.0 后身份链混淆锚点整组漂移,评论区 IP 属地失效
    (6.3.0 的 up1.a 在 6.5.0 已被无关类占用,旧 hook 挂在不相关类上静默失效)。
    本版把身份改写主路径上移到真名类 kntr.base.moss.ignet.impl.grpc.c.f(二进制身份头
    写入存储的唯一入口,6.3.0–6.5.0 均未漂移),对 x-bili-metadata-bin /
    x-bili-device-bin 做参数替换改写;6.3.0/6.4.0 的提供者层 hook 保留为兜底并新增
    严格形状校验(无参非抽象方法 + (String, byte[]) 构造器返回形状),杜绝撞名挂错。
    实机 6.5.0 验证:评论区属地(省份标签)恢复显示,非评论请求零改写。/ After the host
    app auto-updated to 6.5.0, the obfuscated identity-chain anchors drifted again (the
    6.3.0 up1.a name is now held by an unrelated class, so the old hook attached to the
    wrong class and silently died). The main rewrite path now hooks the stable,
    real-named kntr.base.moss.ignet.impl.grpc.c.f — the single entry through which
    binary identity headers enter the request context — and swaps the
    x-bili-metadata-bin / x-bili-device-bin bytes via argument replacement. The
    6.3.0/6.4.0 provider-level hooks remain as fallbacks, now with strict shape
    validation (non-abstract no-arg method + (String, byte[]) constructor on the return
    type) so name collisions can never attach a dead hook. Verified on a 6.5.0 device:
    province tags are back in the comment section; non-comment requests stay untouched.
  • 说明 / Note: 6.5.0 评论区主服务已迁移至 bilibili.main.community.reply.v2,
    服务名前缀判定天然覆盖。/ The 6.5.0 comment section mainly calls
    bilibili.main.community.reply.v2; the service-name prefix check covers it.
  • 6.5.0 全功能盘点与适配 / 6.5.0 full audit & adaptation: 解码/音质/HDR 的 fnval
    计算类漂移(FG1.b→GI1.e→kJ1.a,三类同构),新候选加入后 int/long 双钩实测触发;
    听视频播完暂停的完成监听器(RI1.l→CE1.f,R8 横向合并成 (Object,int) 合成类但签名
    未变)加入候选;底栏渲染隐藏「我的」为 6.3.0/6.4.0 专属:6.5.0 容器已 lambda 化且
    存在不可靠的首帧竞态,新版上不安装该 hook(「我的」tab 保持 App 默认显示,开关其余
    行为不受影响)。6.3.0/6.4.0 的全部旧锚点保留为候选,单 APK 继续跨三版本。
    / The fnval calculator drifted (FG1.b→GI1.e→kJ1.a, structurally identical);
    the new candidate hooks int/long variants, verified firing on device. The
    listen-mode completion listener gained CE1.f as 6.5.0 candidate (R8 horizontally
    merged the old listeners into an (Object,int) synthetic class, signatures
    unchanged). The experimental bottom-bar "hide Mine" stays 6.3.0/6.4.0-only: on
    6.5.0 the container is a compose lambda with an unreliable first-frame race, so the
    hook is deliberately not installed there (the Mine tab simply stays visible as in
    the stock app). All 6.3.0/6.4.0 anchors remain in the candidate lists — one APK
    across three versions.
  • 构建 / Build: versionCode 15。