Skip to content

BetterGI 专项(#410)合入后复查:日志跨零点误判超时、槽位残留、切号仓库重建等 #498

Description

@qiyinxi

#410 合入后复查 BetterGI 专项,列一下发现的问题。按处理优先级排。

一、建议尽快修

1. 日志监控用固定路径,但 BGI 日志按天滚动 —— 跨零点的运行必然误判超时

AutoProxy.py 把日志路径求值一次存成 script_log_path,两处监控都传这个固定 Path

# prepare()
self.script_log_path = self._build_log_path()   # better-genshin-impact{yyyyMMdd}.log
...
await self.log_monitor.start_monitor_file(self.script_log_path, self.log_start_time)
await switch_monitor.start_monitor_file(self.script_log_path, datetime.now())

LogMonitor.monitor_file 支持传 Callable[[], Path] 每轮重解析,注释里点名的就是这个场景;M9A 已经这么用了(M9A/AutoProxy.pyself._resolve_m9a_log_path)。

过零点后 BGI 写入新文件,监控仍在轮询昨天那份:st_size <= offset 走「无变化」分支,latest_time 冻结在午夜前最后一行,check_logdatetime.now() - latest_time > RunTimeLimit(默认 10 分钟)命中,判「BetterGI 运行超时」并杀掉一个健康的 BGI。三次重试都用同一条死路径,全灭。

一条龙动辄两小时以上,夜间队列跨零点是常态。

_build_log_path 本来就是无参方法,两处改成传 self._build_log_path 即可。

2. ScriptConfig 会话写了 MAS 槽位却从不删除

write_user_one_dragon 无条件写 User/OneDragon/MAS独立配置.json。全仓 remove_one_dragon_slot 只有 AutoProxy._restore_one_dragon_config 一个调用点,ScriptConfig.final_task 只做了 snapshot:

async def final_task(self) -> None:
    self.wait_event.set()
    await self._kill_processes()
    if not self.crashed:
        self._snapshot_one_dragon_config()   # 没有 remove_one_dragon_slot

「配置 BetterGI」开一次原生会话(独立配置模式),槽位文件就永久留在用户的 BGI 一条龙列表里。MAS 侧 list_one_dragon_configs 过滤掉了所以看不见,BGI GUI 里看得见 —— 正是设计注释承诺要避免的「使 BGI GUI 不残留 MAS 运行时配置」。

附带:use_mas_launch_slot 那个「防自伤」判断只影响 launch_config_name,不影响写入目标和删除目标。若用户存在一份名为「MAS独立配置」的配置,AutoProxy 会先覆盖它再删掉它。触发路径窄(下拉框已过滤该名字),但注释宣称的保护实际不成立。

3. ensure_switch_subscription 在「首次使用」这条正常路径上 rmtree 整个脚本仓库

if not switch_script_dir(root_path).is_dir():
    repo_dir = root_path / _REPO_REL_DIR
    if repo_dir.is_dir():
        shutil.rmtree(repo_dir, ignore_errors=True)

「脚本目录不存在」不止是误删场景 —— 第一次启用切号的所有用户都会命中。对已在使用 BGI 脚本仓库的人,这会把整个本地克隆连同其它已订阅脚本的元数据一起删掉,依赖下次 BGI 启动重新浅克隆;代码自己的提示文案就是「首次克隆/仓库冷启动,可能耗时较长」。网络不通时直接卡在这里。

建议加条件:仅当订阅清单里已有该脚本且上一轮检出确实失败过才重建,或先试普通更新、失败再降级。

二、需要定夺的取舍

4. elevated=True 三处写死,无开关

AutoProxy(启动一条龙 / 切号)与 ScriptConfig 全部硬编码,走 ShellExecute "runas"。MAS 本身非管理员运行时,每次启动 BGI 都弹 UAC,无人值守的定时任务会挂在 search_process(..., 60.0) 上然后失败。开发环境习惯以管理员启动,正好把这个问题遮住。

另外 open_processelevated 分支静默丢弃 stdout / stderr / null_stream_to_pipe(当前无调用方受影响,但是个 API 陷阱)。

5. frontend/.yarnrc.yml 把 npmmirror registry 提交进了仓库

npmRegistryServer: "https://registry.npmmirror.com"

与 BetterGI 适配无关(Sourcery 摘要也单列在 Build 下)。影响是所有贡献者和 CI 的依赖解析源都被改到镜像站。这类本机加速更适合放 .yarnrc.local.yml 或走 YARN_NPM_REGISTRY_SERVER 环境变量。yarn.lock 没跟着进这个 PR,暂时没有 lock 污染。

三、次要

  • 凭据相关函数零测试mask_account / scrub_switch_group / write_switch_group / resolve_switch_settingstests/ 下 0 命中;test_bettergi_account_switch.py 仅 2 个用例,都在测仓库订阅。脱敏是明文密码落盘后唯一的补救手段。注意 mask_account 对非手机号非邮箱的账号是原样返回的。
  • 重试后分步报告会重复final_task 把所有 log_record 拼成一条 combined_log 再解析,_parse_one_dragon_report 不按 run 分段;第一次失败第二次成功时,报告里会出现两轮 1/N…N/N。
  • _ensure_auto_update_on_cli 永久改写用户的 User/config.jsonselectedChannelName="CNB"、删除旧 ScriptConfig 键),不在快照/还原范围内。注释说明是有意为之,仅提示该改动不可逆。
  • version.json 的 BetterGI 条目是全表唯一没有 by [@author] 署名的。
  • one_dragon_report.py 文件末尾无换行。
  • 三处跨模块私有导入:account_switch._GROUP_NAMEone_dragon._GLOBAL_CONFIG_LOCKone_dragon_report._parse_one_dragon_report
  • 前端 parseListBoolean(x.enabled) 默认 false,后端 parse_custom_groupsbool(item.get("enabled", True)) 默认 True,同一份 JSON 两套默认值。
  • _step_duration 跨零点会算成 0 秒(max(0, total) 兜住了负数)。

四、已在处理

新增的两个前端页面 i18n 覆盖为 0:BetterGIUserEdit.vue(128 行含硬编码中文)、BetterGIScriptEdit.vue(43 行)、useBettergiCustomGroups.ts / useBettergiGuiSession.ts(35 行)都没有 useI18n / t(),对照 HSRUserEdit.vue 是 2 处 useI18n + 38 处 t()。词表这次只加了脚本类型名与描述。同版本 version.json 刚登记「各脚本/用户编辑页的界面文案接入词表」。

已另开 PR 处理。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions