#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.py 传 self._resolve_m9a_log_path)。
过零点后 BGI 写入新文件,监控仍在轮询昨天那份:st_size <= offset 走「无变化」分支,latest_time 冻结在午夜前最后一行,check_log 里 datetime.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_process 的 elevated 分支静默丢弃 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_settings 在 tests/ 下 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.json(selectedChannelName="CNB"、删除旧 ScriptConfig 键),不在快照/还原范围内。注释说明是有意为之,仅提示该改动不可逆。
version.json 的 BetterGI 条目是全表唯一没有 by [@author] 署名的。
one_dragon_report.py 文件末尾无换行。
- 三处跨模块私有导入:
account_switch._GROUP_NAME、one_dragon._GLOBAL_CONFIG_LOCK、one_dragon_report._parse_one_dragon_report。
- 前端
parseList 的 Boolean(x.enabled) 默认 false,后端 parse_custom_groups 的 bool(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 处理。
#410 合入后复查 BetterGI 专项,列一下发现的问题。按处理优先级排。
一、建议尽快修
1. 日志监控用固定路径,但 BGI 日志按天滚动 —— 跨零点的运行必然误判超时
AutoProxy.py把日志路径求值一次存成script_log_path,两处监控都传这个固定Path:LogMonitor.monitor_file支持传Callable[[], Path]每轮重解析,注释里点名的就是这个场景;M9A 已经这么用了(M9A/AutoProxy.py传self._resolve_m9a_log_path)。过零点后 BGI 写入新文件,监控仍在轮询昨天那份:
st_size <= offset走「无变化」分支,latest_time冻结在午夜前最后一行,check_log里datetime.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:「配置 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 整个脚本仓库「脚本目录不存在」不止是误删场景 —— 第一次启用切号的所有用户都会命中。对已在使用 BGI 脚本仓库的人,这会把整个本地克隆连同其它已订阅脚本的元数据一起删掉,依赖下次 BGI 启动重新浅克隆;代码自己的提示文案就是「首次克隆/仓库冷启动,可能耗时较长」。网络不通时直接卡在这里。
建议加条件:仅当订阅清单里已有该脚本且上一轮检出确实失败过才重建,或先试普通更新、失败再降级。
二、需要定夺的取舍
4.
elevated=True三处写死,无开关AutoProxy(启动一条龙 / 切号)与ScriptConfig全部硬编码,走ShellExecute "runas"。MAS 本身非管理员运行时,每次启动 BGI 都弹 UAC,无人值守的定时任务会挂在search_process(..., 60.0)上然后失败。开发环境习惯以管理员启动,正好把这个问题遮住。另外
open_process的elevated分支静默丢弃stdout/stderr/null_stream_to_pipe(当前无调用方受影响,但是个 API 陷阱)。5.
frontend/.yarnrc.yml把 npmmirror registry 提交进了仓库与 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_settings在tests/下 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.json(selectedChannelName="CNB"、删除旧ScriptConfig键),不在快照/还原范围内。注释说明是有意为之,仅提示该改动不可逆。version.json的 BetterGI 条目是全表唯一没有by [@author]署名的。one_dragon_report.py文件末尾无换行。account_switch._GROUP_NAME、one_dragon._GLOBAL_CONFIG_LOCK、one_dragon_report._parse_one_dragon_report。parseList的Boolean(x.enabled)默认false,后端parse_custom_groups的bool(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 处理。