Skip to content

fix: 修正了推荐中会有不存在的黑暗剑问题#1684

Merged
MistEO merged 2 commits intov2from
fix/essence
Mar 28, 2026
Merged

fix: 修正了推荐中会有不存在的黑暗剑问题#1684
MistEO merged 2 commits intov2from
fix/essence

Conversation

@Joe-Bao
Copy link
Copy Markdown
Contributor

@Joe-Bao Joe-Bao commented Mar 28, 2026

fix #1682

Summary by Sourcery

解析 energy_point_gems 数据以重新生成 EssenceFilter 的 location,并确保方案推荐只包含在各个 location 实际可行的武器。

Bug Fixes(错误修复):

  • 当某个 location 无法提供武器所需的 slot2 或 slot3 技能时,将该武器从该 location 的推荐结果中排除,避免推荐无法获得的武器。

Enhancements(功能增强):

  • 替换原有的 locations 构建器,从 energy_point_gems.json 而非 weapons_data.json 中推导 locations,并增加更严格的映射和基于当前 skill_pools 的校验。
  • 改进 EssenceFilter 的方案推荐逻辑:当任一 location 没有可用的 locations 或不存在任何可行方案时,记录日志并跳过输出。
  • 为从 energy_point_gems.json 生成 locations.json 的新 build_locations 工作流及解析规则编写文档。

Documentation(文档):

  • build_locations.py 添加 README 文档,包括用法、参数,以及基于 energy_point_gems.json 的解析规则。
Original summary in English

Summary by Sourcery

Parse energy_point_gems data to regenerate EssenceFilter locations and ensure plan recommendations only include weapons feasible at each location.

Bug Fixes:

  • Exclude weapons from location recommendations when their required slot2 or slot3 skills are unavailable at that location, avoiding recommendations of unattainable weapons.

Enhancements:

  • Replace the locations builder to derive locations from energy_point_gems.json instead of weapons_data.json, including stricter mapping and validation against current skill_pools.
  • Improve EssenceFilter plan recommendation logic to log and skip output when no locations or no feasible plans are available for any location.
  • Document the new build_locations workflow and parsing rules for generating locations.json from energy_point_gems.json.

Documentation:

  • Add README documentation for build_locations.py, including usage, parameters, and parsing rules based on energy_point_gems.json.

@Joe-Bao Joe-Bao marked this pull request as ready for review March 28, 2026 14:49
Copilot AI review requested due to automatic review settings March 28, 2026 14:49
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题,并且给出了一些高层反馈:

  • 在 build_locations.py 中你引入了 seen_names: set[str],这在 Python <3.9 上会出错;如果这个脚本需要在更旧版本上运行,请改用 typing 中的 Set[str],或者添加 from __future__ import annotations 以保证兼容性。
  • 在 Go 的 buildFeasibleWeaponSet 中,你用 Weapon.ChineseName 作为可行性映射的键;如果武器中文名可能重复,或者会因为本地化发生变化,建议使用稳定的标识符(例如武器 ID)作为键,以避免可行性判断与其它地方使用的索引之间出现不一致。
给 AI Agent 的提示词
Please address the comments from this code review:

## Overall Comments
- In build_locations.py you introduced `seen_names: set[str]`, which will break on Python <3.9; if this script is meant to run on older versions, switch to `Set[str]` from `typing` or add `from __future__ import annotations` for compatibility.
- In the Go `buildFeasibleWeaponSet` you key feasibility by `Weapon.ChineseName`; if there can be duplicate or localized name changes, consider keying by a stable identifier (e.g. weapon ID) to avoid mismatches between feasibility and the indices used elsewhere.

## Individual Comments

### Comment 1
<location path="tools/essence_filter/build_locations.py" line_range="88-89" />
<code_context>

-    pool2_by_id = {int(e["id"]): e for e in pool_slot2}
-    pool3_by_id = {int(e["id"]): e for e in pool_slot3}
+    pool2_by_cn = {_norm_key(e.get("cn") or ""): e for e in pool_slot2}
+    pool3_by_cn = {_norm_key(e.get("cn") or ""): e for e in pool_slot3}

-    locations_raw = wd.get("locations") or []
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Avoid using empty normalized keys in the CN → pool-entry maps to prevent accidental overwrites.

When `cn` is empty, `_norm_key` returns `""`, so all such entries share the same key and only the last one remains in `pool2_by_cn`/`pool3_by_cn`. Consider computing the normalized key first and only inserting when it’s non-empty to avoid collisions and silent overwrites.

```suggestion
    pool2_by_cn: Dict[str, Any] = {}
    for e in pool_slot2:
        cn_key = _norm_key(e.get("cn") or "")
        if not cn_key:
            # Skip entries with empty/invalid CN to avoid collisions on the "" key
            continue
        pool2_by_cn[cn_key] = e

    pool3_by_cn: Dict[str, Any] = {}
    for e in pool_slot3:
        cn_key = _norm_key(e.get("cn") or "")
        if not cn_key:
            # Skip entries with empty/invalid CN to avoid collisions on the "" key
            continue
        pool3_by_cn[cn_key] = e
```
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得这些 Review 有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的 Review。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • In build_locations.py you introduced seen_names: set[str], which will break on Python <3.9; if this script is meant to run on older versions, switch to Set[str] from typing or add from __future__ import annotations for compatibility.
  • In the Go buildFeasibleWeaponSet you key feasibility by Weapon.ChineseName; if there can be duplicate or localized name changes, consider keying by a stable identifier (e.g. weapon ID) to avoid mismatches between feasibility and the indices used elsewhere.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In build_locations.py you introduced `seen_names: set[str]`, which will break on Python <3.9; if this script is meant to run on older versions, switch to `Set[str]` from `typing` or add `from __future__ import annotations` for compatibility.
- In the Go `buildFeasibleWeaponSet` you key feasibility by `Weapon.ChineseName`; if there can be duplicate or localized name changes, consider keying by a stable identifier (e.g. weapon ID) to avoid mismatches between feasibility and the indices used elsewhere.

## Individual Comments

### Comment 1
<location path="tools/essence_filter/build_locations.py" line_range="88-89" />
<code_context>

-    pool2_by_id = {int(e["id"]): e for e in pool_slot2}
-    pool3_by_id = {int(e["id"]): e for e in pool_slot3}
+    pool2_by_cn = {_norm_key(e.get("cn") or ""): e for e in pool_slot2}
+    pool3_by_cn = {_norm_key(e.get("cn") or ""): e for e in pool_slot3}

-    locations_raw = wd.get("locations") or []
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Avoid using empty normalized keys in the CN → pool-entry maps to prevent accidental overwrites.

When `cn` is empty, `_norm_key` returns `""`, so all such entries share the same key and only the last one remains in `pool2_by_cn`/`pool3_by_cn`. Consider computing the normalized key first and only inserting when it’s non-empty to avoid collisions and silent overwrites.

```suggestion
    pool2_by_cn: Dict[str, Any] = {}
    for e in pool_slot2:
        cn_key = _norm_key(e.get("cn") or "")
        if not cn_key:
            # Skip entries with empty/invalid CN to avoid collisions on the "" key
            continue
        pool2_by_cn[cn_key] = e

    pool3_by_cn: Dict[str, Any] = {}
    for e in pool_slot3:
        cn_key = _norm_key(e.get("cn") or "")
        if not cn_key:
            # Skip entries with empty/invalid CN to avoid collisions on the "" key
            continue
        pool3_by_cn[cn_key] = e
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +88 to +89
pool2_by_cn = {_norm_key(e.get("cn") or ""): e for e in pool_slot2}
pool3_by_cn = {_norm_key(e.get("cn") or ""): e for e in pool_slot3}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): 避免在 CN → pool-entry 映射中使用空的归一化键,以防止意外覆盖。

cn 为空时,_norm_key 会返回 "",因此所有这类条目会共享同一个键,最终只有最后一个会保留在 pool2_by_cn/pool3_by_cn 中。建议先计算归一化后的键,只在其非空时再插入,以避免键冲突和静默覆盖。

Suggested change
pool2_by_cn = {_norm_key(e.get("cn") or ""): e for e in pool_slot2}
pool3_by_cn = {_norm_key(e.get("cn") or ""): e for e in pool_slot3}
pool2_by_cn: Dict[str, Any] = {}
for e in pool_slot2:
cn_key = _norm_key(e.get("cn") or "")
if not cn_key:
# Skip entries with empty/invalid CN to avoid collisions on the "" key
continue
pool2_by_cn[cn_key] = e
pool3_by_cn: Dict[str, Any] = {}
for e in pool_slot3:
cn_key = _norm_key(e.get("cn") or "")
if not cn_key:
# Skip entries with empty/invalid CN to avoid collisions on the "" key
continue
pool3_by_cn[cn_key] = e
Original comment in English

suggestion (bug_risk): Avoid using empty normalized keys in the CN → pool-entry maps to prevent accidental overwrites.

When cn is empty, _norm_key returns "", so all such entries share the same key and only the last one remains in pool2_by_cn/pool3_by_cn. Consider computing the normalized key first and only inserting when it’s non-empty to avoid collisions and silent overwrites.

Suggested change
pool2_by_cn = {_norm_key(e.get("cn") or ""): e for e in pool_slot2}
pool3_by_cn = {_norm_key(e.get("cn") or ""): e for e in pool_slot3}
pool2_by_cn: Dict[str, Any] = {}
for e in pool_slot2:
cn_key = _norm_key(e.get("cn") or "")
if not cn_key:
# Skip entries with empty/invalid CN to avoid collisions on the "" key
continue
pool2_by_cn[cn_key] = e
pool3_by_cn: Dict[str, Any] = {}
for e in pool_slot3:
cn_key = _norm_key(e.get("cn") or "")
if not cn_key:
# Skip entries with empty/invalid CN to avoid collisions on the "" key
continue
pool3_by_cn[cn_key] = e

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

该 PR 针对 Issue #1682「推荐预刻写方案数据错误」修正地点词条来源与推荐逻辑,避免在“某地点不可刷的词条/武器”仍被纳入推荐方案的问题。

Changes:

  • 改用 energy_point_gems.json 作为地点词条来源,重新生成并更新 locations.json
  • 更新 build_locations.py 的解析/映射规则与文档说明。
  • Go 端推荐逻辑按地点的 slot2/slot3 可用集合过滤,仅输出“该地点可行”的武器方案。

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tools/essence_filter/build_locations.py energy_point_gems.json 解析重度能量淤积点词条并映射到 skill_pools.json,生成 locations.json
tools/essence_filter/README.md 补充 build_locations.py 用法与解析规则说明
assets/data/EssenceFilter/locations.json 更新地点词条数据(含部分 JP 文本补全)
assets/data/EssenceFilter/energy_point_gems.json 新增能量淤积点原始数据,用于地点词条解析
agent/go-service/essencefilter/ui.go 推荐方案按地点可用 slot2/slot3 过滤,避免推荐不可行武器/方案

Comment on lines +292 to +299
locations := st.MatchEngine.Locations()
if len(locations) == 0 {
log.Info().
Str("component", "EssenceFilter").
Str("step", "PlanRecommend").
Msg("skip recommend output: no locations loaded")
return
}
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里在 locations 为空时直接 return,导致用户界面不会输出任何“方案推荐/未毕业武器”信息;但 HTML 模板本身允许 Sections 为空(仍可显示未毕业武器列表)。建议不要直接跳过渲染:即使没有 locations,也至少渲染 plan_recommend(Sections 置空),并可在 UI 上提示“地点数据未加载/无法生成地点方案”。

Copilot uses AI. Check for mistakes.
Comment on lines +338 to 344
if len(sections) == 0 {
log.Info().
Str("component", "EssenceFilter").
Str("step", "PlanRecommend").
Msg("skip recommend output: no feasible location plans")
return
}
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里在 sections 为空时直接 return,会让用户完全看不到“未毕业武器列表”等输出;而模板中 range .Sections 本来就可以为空(只是不会显示地点卡片)。建议仍然调用 plan_recommend 渲染(Sections 为空即可),并在必要时追加一条 UI 文案说明“当前没有可行地点方案”。

Suggested change
if len(sections) == 0 {
log.Info().
Str("component", "EssenceFilter").
Str("step", "PlanRecommend").
Msg("skip recommend output: no feasible location plans")
return
}

Copilot uses AI. Check for mistakes.
@MistEO MistEO merged commit 96f7eb6 into v2 Mar 28, 2026
18 checks passed
@MistEO MistEO deleted the fix/essence branch March 28, 2026 16:36
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.

推荐预刻写方案数据错误

3 participants