zijunchiang
|
eadc2d4de1
|
V1.5.0: 修复"公放切歌失效"——上一版清空歌曲缓存把公放曲库删了(新设备回归)
现象: 新设备公放时按「切歌」没有任何反应。
根因(我上一版引入的回归):
- 1.4.10 为了让"被当成歌曲缓存下来的广告视频"消失,在启动时做了一次
**整目录清理**(删 cloud-song 下所有 .ts/.ls/.mp4/.mkv)。
- 但 MuseDatabase.songDirectories() **只有 cloudSongsDir 一个目录**,
SongOkDownloadManager.getLocalFile() 也落在那里 —— 那等于**把公放曲库整个删掉**。
- 后果链: 库空 → playRandomLocalSong() 里 allLocalSongs 为空 →
RandomPlayQueue.next() 返回 null → 状态栏"本地暂无可播放歌曲"、currentSong 保持 null
→ 按「切歌」时 advancePlayback 落进「取消随机续播、进入空闲态」分支 → 按钮无反应。
(RandomPlayQueue.next 本身有"只剩一首也能播"的兜底,队列逻辑没问题。)
修复:
- 删除整目录清理,改为 purgeInjectedAdDuplicatesOnce(): **只删能证明是注入广告的文件** ——
广告对每首歌下发同一个视频,特征是"多首不同歌曲的本地文件内容完全相同"
(按文件大小 + 头部 4MB 指纹分组,只清理 size>=2 的完全相同组)。
正常歌曲内容各不相同,绝不会被误删;公放曲库得以保留。
同时按用户要求,复查"老设备适配期间改动对新设备的影响",另修正两处:
- SongApiClient.getSongDownloadUrl 的主线程分支: 1.4.7 起会先走 resolveNatively()
(最多 7 个源 × 8 秒超时的阻塞网络请求)—— 一旦有主线程调用者就会卡死 UI 到 ANR。
现在主线程只做本地 DB 兜底,网络取址一律留在后台线程。
- KtvJsBridge 裸 Socket 的 HTTPS 分支: 1.4.6 改用了无参 createSocket(),拿到的 SSLSocket
**不带主机名**(影响 SNI 与证书主机名校验,共享 CDN/反代多证书时会握手失败)。
改为先 connect 普通 socket(保留显式连接超时)再 createSocket(plain, host, port, true)。
- buildDownloadUrl 的文件名比对只在点歌编号"可信"时启用: 只有从 song.filename 推出的编号才
参与比对;song.id 可能是数据库主键,拿它比对会误杀正常地址(真源被判"文件名不符")。
(另已实测 7 个源: 可用的 5 个真源 URL 文件名全部严格等于点歌编号,规则不会误杀。)
顺带记录用户给出的版本号约定(已写入 AGENTS.md):
versionName = <major>.<minor>.<patch>,patch 0~10、minor 1~10;
1.4.10 之后是 1.5.0,1.10.1 之后是 2.1.0;versionCode 始终 +1。
版本 1.4.10(30) → 1.5.0(31);签名证书不变。测试 8 例全通过。
|
2026-09-26 21:25:37 +08:00 |
|
zijunchiang
|
669766ba60
|
V1.4.10: 修复广告过滤失效(gz.ac16.vip 广告被当成歌曲下载播放)
现场事故(新设备 SM-S9180 / Android 16,WebView 正常 → 走 JS 取址):
277 JS [KtvApi] URL OK: 7303235 ls=1 via http://w.w345.my
278 点歌编号=7303235 标题=情歌(HD) 请求源=http://w.w345.my 状态=成功 urlHost=gz.ac16.vip
279 PLAY id=7303235 title=情歌(HD) src=local
即 gz.ac16.vip 的广告视频被当成歌曲下载、缓存并播放。
三处漏洞叠加:
1. ktv_api.js 的 isDemoUrl 不认识广告域名;且"ts 文件名与编号比对"用的是
/\/(\d+)\.ts/,只匹配纯数字名 —— my_ad_video.ts 这类非数字名字直接放行;
2. SongOkDownloadManager.buildDownloadUrl 的**成功分支完全没有广告校验**
(AdVideoFilter.isAdVideo 全项目只在"缓存地址"与"原生解析"两处被调用);
3. SongApiClient.fetchFromDb 只做 isLikelyDemoUrl(纯 IP / r2.dev),挡不住广告域名。
且**内容校验挡不住广告**: 该广告通过 SongFileValidator(≥6MB/≥60s/TS 包完整),
被 isDownloaded() 一直复用,广告会反复播。
修复(单一闸门,全链路把关):
- AdVideoFilter 新增 isTrustedSongUrl(url, musicno):非 http(s)、命中广告特征
(路径 /ad_files/、my_ad_video、**域名 *.ac16.vip**)、或 URL 里 .ts 文件名不等于
点歌编号 → 一律不可信。真源恒为 /<musicno>.ts(已实测 txog.ktvsky.com 与
download.origjoy.com 两个 CDN 域共 6 首全部相符)。
- 该闸门接入全部出入口: JS isDemoUrl(同步加固 + KTV_BRIDGE_API 8→9)、
SongUrlResolver.isValidSongUrl、SongApiClient.fetchFromDb、
以及最终兜底 SongOkDownloadManager.buildDownloadUrl(成功/缓存两条分支)。
- 判定不可信时**同时删除已落盘的歌曲文件**(purgeCachedSongFile),
否则 isDownloaded() 会一直复用那个广告文件。
- 新增 SongOkDownloadManager.purgeLegacySongCacheOnce(): 升级后一次性清理历史遗留的
可疑歌曲缓存(marker: filesDir/song_cache_purged_v1)。只是让歌曲重新下载,不动用户数据。
- 新增回归测试 AdVideoFilterTest(6 例,用日志里的真实 URL 形态,含两个真源 CDN 域);
该测试当场抓到本修复自身的一个 bug:正则把扩展名也捕获进去导致真源被误杀,已修正。
版本 1.4.9(29) 到 1.4.10(30);签名证书不变。
|
2026-09-26 21:17:04 +08:00 |
|
zijunchiang
|
40d1fec719
|
V1.4.1: 修复 Android 5.1.1 设备一打开就闪退(API 守卫缺失)
根因(极米 H1S / MStar 6A928 / GMUI2.0 / Android 5.1.1):
- MainActivity 把 API 23 才有的 android.media.AudioDeviceCallback 写成了
**字段初始化器**(private val micDeviceCallback = object : ...)。
字段初始化在 Activity 构造期执行,早于 onCreate 里的 SDK_INT 判断,
于是下面的 registerMicInputWatcher() 版本守卫形同虚设 ——
构造 MainActivity 即抛 NoClassDefFoundError,表现为一打开就闪退。
- 顺带修复 36 处同类未守卫的高版本 API 调用(lint NewApi 全量清零):
* AudioDeviceCallback / AudioDeviceInfo.isSource/getType (API 23)
→ 改为可空字段 + 仅在 SDK_INT>=23 分支按需创建(@TargetApi)
* HashMap.putIfAbsent ×5 (API 24) → MutableMap.getOrPut
* Comparator.comparing ×3 + comparingInt ×1 (API 24) → Kotlin compareBy
(同时移除 java.util.function 导入)
* ConcurrentHashMap.newKeySet ×2 (API 24) → Collections.newSetFromMap
(连带 16 处 KeySetView.add/remove/contains)
* ConcurrentHashMap.computeIfAbsent (API 24) → ConcurrentHashMap.putIfAbsent(API 1)
* URLConnection.getContentLengthLong ×5 (API 24) → 新增 Compat.contentLengthCompat()
* ByteArrayOutputStream.toString(Charset) (API 33) → String(bytes, UTF_8)
防回归:
- app/build.gradle 打开 lint 闸门: checkReleaseBuilds true + abortOnError true +
fatal += NewApi(并 disable ExpiredTargetSdkVersion,避免它挤占闸门)。
已实测: 植入一个 NewApi 违规后 assembleRelease 直接 FAILED。
- AGENTS.md 新增「低版本设备闪退(API 守卫)」条目,记录根因、替代写法与自查命令。
版本号 1.4.0(16) → 1.4.1(17);签名证书不变,可覆盖安装。
|
2026-09-26 13:59:51 +08:00 |
|
zijunchiang
|
942ec527f1
|
V1.4.0: 修复断网重连后无法下载 + 网络状态检测维护
根因(断网重连后再也下载不了、日志却显示"歌曲源获取成功"):
SongApiClient.clearTokenCache() 一直是**空实现**。JS 侧 window.api.tokens 与
_apiInitPromise 因此被一直复用; 而歌曲源按「出口 IP + device」识别、试用窗口
也记在出口 IP 上(见 Eac19WindowGuard), 断网/重连(尤其换出口 IP)后旧 token 已失效 ——
取址这一步看起来成功, 真正下载却 403/失败。
1) 网络状态检测(新增 KtvNetworkMonitor)
走 ConnectivityManager 回调(不轮询)维护全局 online, 状态变化才回调主线程;
全局可读 online 供下载层判断失败是否由断网引起。
2) 播放页右上角「网络未连接」提示
全屏播放页控制层 header 内、标题右侧新增红色徽标(不遮挡右上角二维码),
断网显示、恢复自动隐藏。
3) 网络恢复/换网后的统一维护 refreshNetworkState()
- 重建歌曲源会话: clearTokenCache() 真正下发 KtvJsBridge.resetApiSession()
(置空 window.api 与 _apiInitPromise, 下次取址重新构造 API 实例、回到默认源顺序
并重新登录拿新 token);
- 复位 Eac19WindowGuard 窗口守卫; 重解析网卡 MAC + 刷新日志上下文;
- 重启本地点歌服务并刷新二维码;
- 自动重试断网期间失败的下载(最多 8 首)。
断网恢复走该路径(带提示), 换网换 IP 也走同一路径(静默)。
4) 下载层网络失败跟踪(SongOkDownloadManager)
结合 KtvNetworkMonitor.online 与异常类型(UnknownHost/Connect/SocketTimeout/
NoRouteToHost/SSL/EOF)及 HTTP 0 判定网络类失败, 记入 networkFailed;
成功后清除、手动取消不入集合; retryNetworkFailed() 供恢复时调用。
5) 顺带修掉一个隐患: 离线时 localIp() 为空会让 remoteNetworkMonitor 每 5s 误判
"IP 变化"而反复重启本地点歌服务; 现已加空值短路, 离线只等网络回调。
版本号 1.3.9 -> 1.4.0(versionCode 15 -> 16)。按约定本次不发布 Release, 仅本地打包测试。
|
2026-09-21 03:34:29 +08:00 |
|
zijunchiang
|
2d3751064f
|
歌曲源: 新增6源(desktok.top/mm.kk456.top/w.w345.my:66/z.w345.my/b.sktv.top/w345.my) + 多源自动排序
- ktv_api.js: HOSTS 扩为 7 源(同后台多入口), 缓存标记 7→8
- 自动排序: 解析失败的源 demote 到队尾, 成功源 promote 到队首(sourceOrder 运行时可变)
- JS→Kotlin 上报实际命中源(reportSongResult), 远程日志请求源不再写死
- SongApiClient/KtvJsBridge: lastSongSourceHost 供日志使用
|
2026-09-04 23:06:05 +08:00 |
|
zijunchiang
|
0c26f6da68
|
麦动KTV: 移除Gitee数据库(改官方Muse同步), 歌曲源切w.w345.my, 远程日志+广告屏蔽
- DatabaseBootstrapper: 删除 Gitee 分片/manifest/blob 下载逻辑, 曲库只走官方 MuseDbSync
- build.gradle: 移除 GITEE_DATABASE_* 构建参数
- MainActivity: 重置数据库文案改为官方同步
- ktv_api.js: 歌曲源仅 w.w345.my, 缓存标记 7, 广告/错号资源拦截+重试
- 远程日志: 点歌记录 编号/标题/请求源/状态
|
2026-09-04 21:23:21 +08:00 |
|