ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Pure Live WebDAV 选择性恢复:仅恢复关注列表的实现审计与源码解析

Pure Live WebDAV 选择性恢复:仅恢复关注列表的实现审计与源码解析
  • 音视频
  • 直播
  • 移动开发

【免费下载链接】pure_live

纯粹直播:哔哩哔哩/虎牙/斗鱼/快手/抖音/网易cc/YY直播/Twitch直播/SOOP直播/M38自定义源应有尽有。

项目地址:https://gitcode.com/gh_mirrors/pur/pure_live
点击查看免费下载

本篇技术指南围绕 Pure Live(纯粹直播)Issue #865 的源码审计结论展开,剖析 3.1.3 版本暴露出的“WebDAV 恢复只能全量覆盖本机设置”问题,以及提交a36ee8fa如何引入“恢复全部设置”与“仅恢复关注列表”两个明确动作,并沿导入合同、界面合同、回归验证三层逐一拆解实现细节。读者读完后,可以完整掌握 Pure Live 备份导入层的 section 隔离机制、关注列表规范化合同、恢复事务与并发门禁的源码级原理,以及后续backupScope: favorites专用格式的演进路径。

问题背景:3.1.3 的恢复路径只有全量

关联审计文档 记录的 Issue #865 指出:Pure Live3.1.3的 WebDAV 恢复只能覆盖全部配置,用户希望增加“只恢复关注列表、同时保留其余本机设置”的选择。审计结论确认,修复前的源码同样只有“同步到本地”这一条全量恢复路径——文件下载后直接导入整份备份,主题、播放器、弹幕屏蔽词、Cookie、WebDAV 凭据等全部本机状态都会被备份内容整体替换。

这一诉求的典型场景是跨设备同步:用户在 Android 手机上维护了关注的主播与分区,希望把这份关注列表迁移到 Windows 桌面端,却不希望桌面端本地已经调好的主题、画质、代理、IPTV 源等配置被手机备份覆盖。全量恢复语义无法满足这种“只换关注、其余不动”的需求。

修复提交:从模糊的“同步到本地”到两个明确动作

提交a36ee8faae03ee07aa605d9b6c4e998d23faec28(已核对为origin/master当前指针)在备份导入层引入了两个语义明确的动作:

  • 恢复全部设置:等价于原有全量路径,导入备份中所有 section;
  • 仅恢复关注列表:只读取备份中的favoriteRooms与favoriteAreas,弹幕屏蔽词、屏蔽用户、首页平台可见范围、首选平台、主题、播放器、历史记录、账号 Cookie、WebDAV 凭据及其他设置均保持当前本机值。

该请求在审计账本中被归类为implemented-in-current-source / native-recheck-pending——即源码层面已实现,但尚未把源码回归结果外推为已安装候选上的原生(真机 GUI)验收结果,相关状态可见 Issue 分诊账本 中 #865 的记录(标记为already-fixed(v3.2.0))。

从当前源码看,这一“范围选择”能力在BackupController(备份控制器)中体现为两层机制:

  • _metaKeys集合(backup_controller.dart)包含backupVersion、backupScope、sensitiveDataIncluded三个元字段,backupScope用于标记专用关注文件的恢复范围;
  • filterBackupSections(backup_controller.dart)按调用方传入的 section 白名单过滤导出/导入数据,restoreAllSettings与importAllSettings都接受sections参数并透传到过滤层。

导入合同逐条拆解

1. 关注数据的来源格式:section 化与旧版平铺兼容

当前版本(backupVersion3)的备份从favoritesection 精确提取房间与分区关注列表;旧版平铺备份(无backupVersion或 v1/v2 的扁平结构)继续读取根级favoriteRooms/favoriteAreas。两种格式均支持对象与既有 JSON 字符串记录。

这一点在FavoriteRoomController(关注房间控制器)中得到印证:

  • toJson()(favorite_room_controller.dart)输出favoriteRooms与favoriteAreas两个列表字段;
  • parseFavoriteLists(favorite_room_controller.dart)是关注恢复专用的解析入口:若数据中既无favoriteRooms也无favoriteAreas,直接抛出FormatException('No favorite lists in backup');
  • 解析统一走BackupMigrationUtil.parseObjectList(json['favoriteRooms'], LiveRoom.fromJson, strict: true),即同时兼容对象数组与既有 JSON 字符串形式的记录。

2. 校验先于变更:任一列表损坏都不产生部分覆盖

目标 section 类型、至少一个关注键及目标列表结构会在任何关注列表变更之前完成校验;当一个目标列表损坏时,另一个列表也不会被部分覆盖。这保证了恢复的原子可见性——要么两份列表都按新值生效,要么本机维持原值。

实现上,parseFavoriteLists先行完成严格解析与类型校验,只有全部通过后restoreFavoriteLists(favorite_room_controller.dart)才分别写回favoriteRooms.v与favoriteAreas.v,并在写回房间列表后执行_normalizeFavoriteRoomIdentities()规范化。

3. 选择性恢复的隔离性:不解析目标之外的 section

选择性恢复只解析目标 section,因此其他 section 即使来自未来版本或结构损坏,也不会阻断有效关注数据的导入。这一设计显著提升了恢复的健壮性:备份文件可能由更新版本生成、包含未知字段,但只要favoriteRooms/favoriteAreas本身合法,关注恢复即可成功,无需理解文件中的其余内容。

4. 身份规范化合同:空白清理与按规范身份去重

恢复后的房间身份沿用现有规范化合同:清理平台与房间号空白,并按规范身份去重。FavoriteRoomController中的实现证据包括:

  • _normalizeFavoriteRoomIdentities()(favorite_room_controller.dart)对每个房间调用normalizedIdentityCopy(),剔除平台/房间号为空的非法记录,并以identityKey去重;
  • _isValidFavoriteRoom(favorite_room_controller.dart)额外拒绝0、null、undefined、nan、none等占位房间号;
  • 分区数据沿用现有LiveArea反序列化合同(LiveArea.fromJson+identityKey判重)。

5. 并发与持久化:单门禁 + 批量提交

全量恢复与仅关注恢复共用同一个_restoreInProgress标志和HivePrefUtil.persistBatch,不会交错写入;Future 只在目标列表写入持久层完成后结束。对应实现:

  • BackupController._restoreInProgress(backup_controller.dart)作为进程内互斥门禁,_persistRestore(backup_controller.dart)在进入时检查StateError('A settings restore is already running'),退出时在finally中复位;
  • HivePrefUtil.persistBatch(hive_pref_util.dart)在同步导入期间收集所有 Rx 通知对应的键值写入,等异步流排空后统一putAll并flush(),避免读者观察到多键状态转换的中间态;
  • 恢复失败时_persistRestore会用恢复前的完整快照(exportAllSettings(includeSensitiveData: true))再走一次persistBatch回滚内存控制器图与存储。

WebDAV 界面合同

按审计文档的界面合同,修复后的备份文件菜单不再用含义模糊的“本地同步”动作代表恢复范围,而是明确显示三项:恢复全部设置、仅恢复关注列表和删除。当前源码中的菜单项由 web_dav_page.dart 的PopupMenuButton提供,界面文案可在 中文本地化文件 中核对:webdav_restore_all_settings为“恢复全部设置”,webdav_confirm_restore_item明确提示“下一步可以勾选要恢复的内容”,webdav_restoring为“正在下载并恢复配置”。

界面合同的其余要点:

  • 仅关注确认弹窗显示完整文件名,并明确说明其他本机设置保持不变;取消和系统返回都发生在远端下载及本机变更之前;
  • 两种恢复拥有各自的进行中标签与成功反馈,等待期间继续复用现有文件操作门禁,阻止重复恢复、上传或删除交错;
  • 320×480、3.0 倍文字夹具确认两个恢复入口、长文件名、范围说明、取消及确认动作均可达;成功夹具进一步证明下载内容只进入选择性导入器。

下载恢复的调用链在 web_dav_controller.dart 中完整可见:downloadFile先经confirmRestore确认,再service.readFile下载远端字节,随后在本地变更前的“围栏”检查(服务所有权 epoch 与目录路径一致性)通过后,jsonDecode得到备份 Map,经BackupController.presentSections枚举可用 section,再由selectSections(即 backup_section_picker.dart 的pickBackupSections)让用户勾选导入范围,最后调用restoreAllSettings(backup, sections: sections)落库。

回归验证与质量记录

审计文档给出的验证数据如下:

层级结果
初始合同红灯restoreFavoriteSettings、BackupRestoreScope与scope参数不存在;首轮记录同时发现并修正测试夹具缺少 Rx 扩展的问题,因此不把该轮汇总数字作为产品基线
首轮质量记录local-artifacts/build-records/20260915T104224269Z-quality-focused.json
直接四文件回归83/83 PASS
最终六文件回归104/104 PASS
当前静态分析No issues found(38.1 秒,本批一次 analyze)
最终质量记录local-artifacts/build-records/20260915T104729052Z-quality-focused.json
仓库审计local-artifacts/repository-audits/20260915T104606395Z-focused.json,0 error / 2 warning
GitHub 同步origin/master已精确核对为a36ee8faae03ee07aa605d9b6c4e998d23faec28

该批工作没有构建候选、启动 Windows GUI、连接 ADB、操作设备或发布,Astra Light 使用 0 次——即验证严格停留在源码与单元/组件回归层面。

后续原生边界

审计文档明确列出仍未闭环的原生验收项,等待在含a36ee8fa的 Android/Windows 累计候选上执行:

  • 用同时含关注直播间、关注分区及其他设置的真实 WebDAV 备份,分别执行取消、仅恢复关注、全量恢复、损坏目标与重复触发五类操作;
  • 对仅恢复前后的 Hive/界面状态留证,确认关注房间与分区更新,而屏蔽项、平台选择、主题、播放器、历史记录及敏感配置保持原值;
  • 该源码增量不改变宏观验收账本:20 PASS / 42 RUN / 0 NR,共 42 组未闭环;A1-05、A2-01 与 W1-01 保持RUN。

后续演进:#874 补齐发送端与本地文件通道

值得说明的是,#865 只覆盖了 WebDAV 的接收端选择性恢复,而 Issue #874 关注列表单独同步审计(2026-09-23)在此基础上补齐了成对的发送端与本地文件入口,形成完整的闭环:

  • WebDAV 页“更多操作 → 仅上传关注列表”输出purelive_favorites_<时间>_<UUID>.txt;普通悬浮按钮继续输出完整配置;接收端沿用“仅恢复关注列表”;
  • 本地备份页增加“仅导出关注列表 / 仅导入关注列表”;
  • 专用格式保留 v3backupVersion,增加backupScope: favorites;favoritesection 精确包含favoriteRooms与favoriteAreas,不包含 Cookie、WebDAV 凭据、历史、IPTV 源或其他设备设置;
  • 完整恢复入口检查范围标记,若误选专用文件则在任何配置写入前报格式错误——这正是 backup_controller.dart 与 backup_controller.dart 中data['backupScope'] == 'favorites'抛FormatException('Favorites-only backup requires favorites restore')的保护逻辑;
  • 新增 backup_roundtrip_test.dart 的跨层测试,让生产关注列表导出经真实WebDAVService的 OPTIONS/PUT/PROPFIND/GET 在本机回环 WebDAV 服务器往返,再由生产关注恢复事务导入,断言远端文件仅含 v3backupVersion、backupScope: favorites与两组关注数据,不含发送端 Cookie。

综合操作指引可参见 WebDAV 配置与排查:跨 Windows、Android、iOS 设备只交换关注时,在 WebDAV 页右上角“更多操作”选择“仅上传关注列表”,到另一台设备的文件菜单选择“仅恢复关注列表”;本地离线交换则使用“设置 → 备份与还原 → 仅导出关注列表 / 仅导入关注列表”。需要提醒的是,即使专用关注文件不包含 Cookie 与 WebDAV 凭据,它仍可能包含个人关注信息,应按敏感文件保管。

  • 音视频
  • 直播
  • 移动开发

【免费下载链接】pure_live

纯粹直播:哔哩哔哩/虎牙/斗鱼/快手/抖音/网易cc/YY直播/Twitch直播/SOOP直播/M38自定义源应有尽有。

项目地址:https://gitcode.com/gh_mirrors/pur/pure_live
点击查看免费下载

相关推荐

上一篇:RIOT 中 LIS3DH 加速度计驱动的手动测试应用:参数初始化、FIFO 读取与中断回调全解析
下一篇:Hister Extractors 完全指南:从原始 HTML 到可搜索内容的领域专属解析体系

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进