V1.5.3: 远程日志不再静默失效(+本地日志文件);补 403 受限识别

现场两个问题分别定位:

一、"歌曲源全部失效" —— 已确认是**源站对该出口 IP 的授权/风控**,非客户端可修
- 实测(本机与设备同一出口 188.253.112.231):
  · 主源 http://w.w345.my/i.php → **HTTP 403 Forbidden**(nginx 拦截页);
  · 镜像源(desktok.top / mm.kk456.top / w.w345.my:66 / z.w345.my / b.sktv.top / w345.my)
    返回 200,但对**每一首歌(含不存在的编号 1111111/9999999)都返回同一个广告/测试资源**
    https://wb66.cn/f/d/7b7c9/10188555.ts;
  · 换全新随机设备身份(mac/sn)结果完全相同 → 限制在**出口 IP** 层面,与设备无关;
  · 7 host × ls=1~3 × (720/1080 × h265 0/1) 全组合探测:0 个真源;
  · 旧的试用领取接口 api.php 已 **404**,App 无法自行领取窗口。
- 结论:源站侧无有效授权(i.php 的 ordertype=0、mwsLogin 的 license_box_count=0 /
  license_duration=0 均指向此)。**需更换公网 IP 或与歌曲源服务方确认续订**。
  我们拒绝这些地址是正确行为(否则就是 1.4.10 修过的"广告被当成歌曲播放")。

二、"手动更新数据库后远程日志失效" —— 数据库没问题,日志客户端有隐患,两者都已处理
- 实测新曲库 day=261003(md5 300AFD957BF332F02C17ED94A9F4E4CF,431,530,367 字节,
  解压 1.01GB、69.5 万首): 用 App 的**真实 SQL**(SONG_SELECT/推荐/中文搜索/拼音搜索/
  歌手检索/歌单/语种/歌手列表)逐条跑通 → **结构完全兼容,更新曲库不会破坏 App**。
- 日志侧修复(原来确实可能"静默失效"):
  · MiliLog.init 改为**可重复调用并自动重启发送线程**(旧实现 `if (started.getAndSet(true)) return`,
    线程一旦退出就永久不再发送且无任何迹象);
  · sendLoop 整体加 catch(Throwable) 兜底,任何异常都不允许发送线程退出;
  · 新增**本地日志文件** <存储根>/logs/ktv.log(>1MB 滚动为 .prev),
    远程日志不可用时现场可直接取文件;启动打 APP-INIT 行给出路径;
  · MiliLog.init 提前到 KtvApplication.onCreate,早于 MainActivity,早期崩溃也有日志。
- 补 403 识别: KtvJsBridge 的 403 判定从仅 /music/do.php 扩展到 /i.php 也认
  (主源 i.php 就是 403);SongUrlResolver 记录本轮是否见过 403,全部失败且见过 403 时
  同样走 Eac19WindowGuard 提示换 IP。

AdVideoFilter: 仅保留高区分度标记 wb66,去掉过于宽松的 demo(避免误伤真源 URL 里的随机 token)。

版本 1.5.2(34) → 1.5.3(35);签名证书不变。测试 9 例全通过。
This commit is contained in:
zijunchiang
2026-10-03 21:03:07 +08:00
parent 3b75717c81
commit 96bad3bd68
7 changed files with 125 additions and 30 deletions
+18 -1
View File
@@ -165,7 +165,7 @@ $BT/apksigner verify 目标名.apk
### 版本号
- `app/build.gradle`:`versionName "1.5.2"` / `versionCode 34`(18~21 被本机临时诊断包占用过)
- `app/build.gradle`:`versionName "1.5.3"` / `versionCode 35`(18~21 被本机临时诊断包占用过)
- App 内显示统一用纯版本号(不加 `(versionCode)` 括号)
- ⚠️ **发布构建已开启 NewApi 闸门**(`lint { checkReleaseBuilds true; fatal += ['NewApi'] }`):
任何「调用了高于 `minSdk 21` 且未做版本守卫的 API」都会让 `assembleRelease` 直接失败。
@@ -357,6 +357,15 @@ $BT/apksigner verify 目标名.apk
5. **状态样本 + 事件**缺一不可:事件(点歌/失败)说明"发生了什么",但排查"随时间变化"的
问题(空间变少、曲库丢失、长期离线)需要状态样本 —— 现由 6 小时一条 `HEALTH ...`
(版本/在线/可用空间/曲库大小/根目录)提供。
- ⚠️ **远程日志绝不能静默失效**(2026-10 现场反馈"手动更新曲库后远程日志失效了"):
1. `MiliLog.init()` **可以重复调用并会自动重启发送线程**(旧实现是
`if (started.getAndSet(true)) return`,一旦线程退出就永久不再发送,且无从察觉);
2. `sendLoop` 整体包了 `catch (Throwable)` 兜底 —— 任何异常都不允许让发送线程退出;
3. **本地留档**:每行同时写入 `<存储根>/logs/ktv.log`(超 1MB 滚动为 `.prev`)。
远程日志不可用时,让现场直接把该文件发出来即可取证;启动时会打一行
`APP-INIT ... logFile=<路径>` 指明位置;
4. `MiliLog.init` 已提到 **`KtvApplication.onCreate`**(早于 `MainActivity`),
这样即使更早的初始化抛异常,也已经有日志可查。
- 一段典型现场日志应为:`BOOT` → `STORAGE` → (点歌)`点歌编号=... 请求源=... 状态=成功 urlHost=...`
→ `PLAY ... src=local` → 每 6h `HEALTH ...`;异常时才有 `RAW-ERR`/`NET-ERR`/`NATIVE-SONG ...失败`。
- **网络状态与断网恢复**:`KtvNetworkMonitor`(object,走 `ConnectivityManager` 回调、不轮询)
@@ -387,6 +396,14 @@ $BT/apksigner verify 目标名.apk
并调用 `Eac19WindowGuard.noteRiskBlocked()`(弹「歌曲源临时受限」引导重启光猫/路由器换 IP),
同时进入 3 分钟冷却(`BLOCKED_COOLDOWN_MS`)避免继续冲击源站;拿到真源立即解除。
- 现场处置:**更换公网出口 IP**(重启光猫/路由器重拨)即恢复;已下载的歌曲不受影响照常播。
- **403 也是受限信号**:2026-10 实测**主源 `w.w345.my/i.php` 直接返回 HTTP 403**、
镜像源返回 200 但只给固定广告文件 —— 两种形态会同时出现。因此
`KtvJsBridge.request` 的 403 判定已从"仅 `/music/do.php`"扩展到 **`/i.php` 也认**,
`SongUrlResolver` 也记录本轮是否见过 403(全部失败且见过 403 → 同样提示换 IP)。
- **旧的试用领取接口 `api.php` 已 404**(源站撤了),因此 App 无法自行"领取"试用窗口。
若换公网 IP 后仍只发广告,基本可判定为**服务/授权层面**问题(`i.php` 的
`ordertype=0`、`mwsLogin` 的 `license_box_count=0`/`license_duration=0` 都指向"无有效授权"),
需与歌曲源服务方确认续订,**不是客户端能修的**。
- ⚠️ 排查这类问题时**不要用生产身份/出口 IP 做密集探测**:源站按出口 IP 限流,
短时间内大量 `i.php`/`do.php`(多 host × 多参数组合)会加重受限,
把"能用"变成"只发广告"。少量、间隔式验证即可。