Skip to content

feat(evaluate): 基质分配链路优化、自定义基质优先及扫描后自动刷新 - #191

Merged
jiubook merged 15 commits into
Logical-Byte:devfrom
jiubook:fixProfilesSync
Aug 8, 2026
Merged

feat(evaluate): 基质分配链路优化、自定义基质优先及扫描后自动刷新#191
jiubook merged 15 commits into
Logical-Byte:devfrom
jiubook:fixProfilesSync

Conversation

@jiubook

@jiubook jiubook commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

基质分配与同步优化(evaluate)

  • 重构 _apply_stat_group_limit:按武器优先级逐一分配基质,共享计数器用
    stat_key,最佳等级用 weapon_id 记录
  • 新增非降级原则过滤与虚拟武器机制,两种分组模式均可用
  • 修复 [BUG] 关闭同类型宝藏限制后扫描不更新 profiles.json #195:关闭同类型数量上限后仍按武器分配同步宝藏基质到 profiles
  • 自定义基质(custom:{id})优先于内置武器认领,作为独立武器参与按武器划分
    的上限,BY_STAT 下命中等级同样写入自定义条目
  • BY_STAT 数量上限分支补齐等级优劣检查,防止更差基质覆盖已保存等级导致
    profile 降级

扫描结果自动刷新

  • 新增 EventService 事件广播(/ws/events WebSocket),扫描同步完成后发布
    profiles_changed 事件,前端订阅后自动刷新宝藏基质等页面,无需手动刷新

其他

  • 启动横幅显示当前版本号,便于用户反馈 logs 时判断版本
  • 简化重合检测武器切换目标的标签文案

  - 重构 _apply_stat_group_limit:按武器优先级逐一分配基质,共享计数器用 stat_key,最佳等级用 weapon_id 记录
  - 新增非降级原则过滤:按武器已有基质等级筛选可升级目标,无法升级任何武器的基质标记为养成材料
  - 新增虚拟武器机制:真实武器配额用完后,用虚拟武器接收剩余配额并支持留大弃小
  - 移除按武器划分时对非降级过滤的禁用限制,改为两种模式均可用
  - 更新设置页提示文案,补充按基质划分时的数量说明
jiubook added 7 commits August 7, 2026 14:11
# Conflicts:
#	frontend/src/pages/settings.vue
修复 issue Logical-Byte#195:关闭「同类型宝藏数量上限」后,扫描结果不再同步到
profiles.json。

根因:限制关闭时 _apply_same_type_treasure_limit 提前返回,只把匹配武器
加入 _updated_this_scan,但未写入 _same_type_best_levels,引擎同步循环
读到 None 等级,导致扫描后不落盘。原 PR Logical-Byte#194 的「全量写入」方案会为每把
匹配武器写入同一份数据,违背单武器分配语义,故改为复用按武器分配逻辑:

- _apply_same_type_treasure_limit 限制关闭时改走 _apply_weapon_group_limit
  (每把武器上限 1 枚),套用用户设置的非降级原则过滤与留大弃小
- 留大弃小仅应用留大(更优替换并同步落盘),不应用弃小:认领耗尽或非降级
  过滤后无可用武器时,通过新增的 exhausted_policy="keep" 保留原判定结果
  (不标记养成材料、不落盘),修复日志先报「养成材料」再改口「保留」的矛盾
- keep_best 关闭时无等级比较,按武器优先级首枚锁定

前端设置页同步调整:
- 非降级原则过滤、留大弃小、等级比较方式解除对「数量上限」总开关的禁用
  依赖(等级比较方式仍依赖留大弃小开关),使关闭限制时用户可预设这些规则
- 更新相关提示文案,说明关闭限制后的分配与落盘行为

新增 7 个测试用例覆盖:单武器认领、多武器按优先级分配、留大升级与更差
保留、首枚锁定、认领耗尽保留、非降级过滤拦截/通过。
后端新增 EventService 事件广播服务并挂载 /ws/events WebSocket,
publish 支持跨线程调用(经 asyncio.Queue 转交事件循环广播)。

ScannerService 将武器同步到宝藏基质后发布 profiles_changed 事件;
前端新增 useProfilesEvents 订阅该事件并刷新 useProfiles 全局数据,
使宝藏基质/基质规划等依赖 profiles 的页面在扫描完成后自动更新,
无需手动刷新。

含后端 test_event_service 与前端 useProfilesEvents 单测。
  - 新增 _order_candidate_ids:自定义基质(custom:{id})排在候选列表最前,
    耗尽后回退到内置武器
  - 新增 _custom_stat_display:自定义基质的显示名称回退
  - evaluate_essence 中将 custom:{id} 加入候选集,使自定义基质作为独立武器
    参与按武器划分的上限(与内置武器各计各的)
  - _claim_as_owned 追踪 custom: 前缀的 key 变更,确保 profile 同步
  - scanner_service 落盘缓存和日志展示适配自定义基质 ID
  - 新增 5 个测试覆盖 BY_WEAPON/BY_STAT 下的优先认领、上限回退、留大弃小
  BY_STAT 模式的数量上限分支缺少等级优劣检查,劣于已保存等级的基质会
  直接覆盖更高等级,导致 profile 降级。

  在 count < limit 分支中新增等级比较,劣于已保存时 continue 跳过该
  武器尝试下一把,所有武器都跳过后由虚拟槽接收,与 BY_WEAPON 的
  _claim_by_limit 行为对齐。
@jiubook jiubook changed the title feat(evaluate): 按武器划分基质分配优化及非降级过滤扩展 feat(evaluate): 基质分配链路优化、自定义基质优先及扫描后自动刷新 Aug 7, 2026
jiubook added 7 commits August 7, 2026 20:33
  - 虚拟武器分支改为遍历已认领槽+一个空闲槽:已认领槽仅允许更优等级覆盖,更差/相等跳过,避免覆盖已保存的更高等级
  - 数量未满但等级劣于已保存最佳时,使用 _make_trash_by_worse_level 而非
  _make_trash_by_limit,提示"低于已保存"而非"达到上限",且不消耗数量配额
  - 新增两个测试覆盖:虚拟槽不被更差基质覆盖、等级劣于已保存时的提示文案与配额行为
  - 为重合检测对话框中的"移除"和"切换"按钮添加 tooltip 说明
    - 移除:删除该自定义基质,不再作为宝藏判定条件
    - 切换:删除自定义基质,并将其等级与优先级转移给内置武器
  - 统一OverlapDetectionDialog中所有 v-tooltip 添加 transition="none" 禁用过渡动画
  前端:
  - 彩虹环修改回悬停时显示,使用mask实现2px渐变环
  - 调整彩虹环位置和圆角,避免覆盖图标和名称

  后端:
  - 提取format_weapon_description函数,支持自定义基质格式化
  - 自定义基质命中时日志统一为"完美契合武器…"格式
  - 自定义基质显示为"名称(自定义基质)",内置武器显示为"名称(稀有度★ 类型)"

  测试:
  - 添加test_evaluate_custom_matrix_logs_unified_weapon_format验证日志格式
  - 提取 buildStatKey 统一内置武器与自定义基质的属性组合键格式
  - WeaponOverview 新增 getSameStatCustomWeaponIds 扫描自定义基质的同类匹配
  - 连线逻辑改为同时包含内置武器和自定义基质作为目标
  武器数据随游戏版本更新后,个别武器的 weapon_id 可能变化(如中文 ID
  规范为 wpn_xxx)。profile 中以旧 ID 保存的引用在新数据中查不到,导致
  宝藏基质页条目被静默过滤、武器总览误判未拥有、扫描在旧引用旁新增重复条目。

  新增 migrate_stale_weapon_ids 方法:按武器名称把旧 ID 改写为最新 ID,
  名称是条目里唯一稳定的标识。未缓存名称时退化为用旧 ID 本身当名称匹配
  (旧中文 ID 通常就是武器名称)。匹配不到的名称保持原样,不丢弃用户数据。
  自定义基质引用由 migrate_custom_stat_ids 处理,不在此列。
  之前用户在重合检测弹窗中选择「不再提示」后,该条目在手动触发「检查自定义基质重合」时也会被隐藏,导致误选后无法通过界面找回。

  - checkCustomOverlap 新增 includeSuppressed 选项:自动检测(进入页面时)尊重标记跳过已抑制条目;手动检测传入
  includeSuppressed: true 始终显示全部
  - 将页面自动检测拆为 checkCustomOverlapAuto,手动入口保持 checkCustomOverlap 并透传 includeSuppressed
  - 「不再提示」chip 添加 tooltip 说明其仅约束自动弹窗,手动检查仍可见
  - 补充三组单元测试覆盖:自动跳过已标记、全部标记时不弹窗、手动检测显示已标记条目
  之前同类基质数量上限只统计扫描中新增的条目,profile 已保存的存量不占
  名额,导致限额形同虚设(已保存 N 枚不占位,扫描时又因「相等跳过」不
  重复计数,等于永远多出 N 个空位)。

  - engine: 初始化时将 profile 存量条数写入 _same_type_treasure_counts
  - engine: 自定义基质条目(custom:xxx)按配置属性组合正确初始化 stat_key 计数
  - evaluate: 无匹配武器分支重构等级比较逻辑,更劣基质一律拒绝(与 keep_best 无关)
  - evaluate: BY_STAT 模式认领时同步写入按武器的计数,修复引擎按 weapon_id 同步时计数永远为 0 的 bug
  - lifespan: 静态数据缺失时跳过武器 ID 迁移,不阻断服务启动
@jiubook
jiubook merged commit dc7b0ce into Logical-Byte:dev Aug 8, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant