add-recipe single inserts a duplicate when the civ already knows the recipe
維護者通常 2 天內回覆
還沒有人認領這個 Issue。
評估
研究方向
從 add-recipe.lua 開始,並比較 single 插入迴圈與用來保護批次插入的 addItems 檢查。報告將 historical_entity.resources 中的重複項目認定為已確認的錯誤;請驗證其行為,並確保完成代表重複執行 single 命令不會再新增一份副本。digger 路由和 nil 檢查是同一個檔案中的其他發現,可能需要另外界定範圍。
由索引模型根據 Issue 內容生成。
描述
add-recipe single <TYPE>:<ID> appends to the civ's resource vector without checking whether the subtype is already in there. Run it twice for the same item and you get two copies in historical_entity.resources.<x>_type.
Confirmed in game (DF + DFHack, fortress mode). Running
add-recipe single SHOES:ITEM_SHOES_BOOTS
twice on an item the civ already knew gave me a visible duplicate entry.
The single path in add-recipe.lua is upfront about skipping the check:
local addedItem = nil
--assume the user knows what they're doing, so no need for sanity checks
for _, item in ipairs(all) do
if (item.id == itemId) then
known:insert('#', item.subtype)
addedItem = item
break
end
end
The bulk paths are fine. addItems guards with not checkKnown(known, subtype) before inserting, so this is specific to single.
The duplicates are mostly cosmetic, but they stick around in the save and there's no in-game way to see them or get rid of them.
Adding a checkKnown(known, item.subtype) call in that loop would make it behave like all/native.
Two smaller things in the same file, from reading it rather than playing. Happy to split either out into its own issue.
1. single doesn't route diggers. It looks the category up in the categories table, and there's no digger entry there, so WEAPON:ITEM_WEAPON_PICK ends up in resources.weapon_type. addItems deliberately sends mining weapons to resources.digger_type instead, with the comment "prevents picks from being duplicated, and puts great picks in correct category". Something does read that field: internal/quickfort/stockflow.lua:306 uses resources.digger_type to build MakeWeapon orders for diggers. So the two vectors aren't interchangeable.
Partial in-game note: add-recipe single WEAPON:ITEM_WEAPON_PICK on a civ that already knew picks did not produce a duplicate among the known diggers, which is what you'd expect if the subtype went into weapon_type instead. I did not separately confirm that it appeared under weapons, so treat that half as unverified.
2. Two nil checks that can't fire. Lines 4-12:
local resources = df.historical_entity.find(df.global.plotinfo.civ_id).resources
local civ = df.historical_entity.find(df.global.plotinfo.civ_id).entity_raw
...
if (resources == nil) then
qerror("Could not find entity resources")
elseif (civ == nil) then
If find returns nil, line 4 has already thrown attempt to index a nil value. So running add-recipe with no fortress loaded gets you a Lua traceback instead of either of the qerror messages that were meant to come out.
I checked whether this is a general pattern before bringing it up: of the 439 scripts in DFHack/scripts, 70 sites dereference a find() result in the same expression, and add-recipe.lua is the only one that then nil-tests the result. The rest either guard first or have an argument that can't be nil. So it's one file, not a sweep.
Context: this came out of review on DFHack/scripts#1603, where @chdoc asked for it to be filed rather than worked around in the GUI.
Disclosure: I used AI assistance (Claude) for the code reading and for drafting this write-up. I verified the main bug in game myself, and I'm the one filing it.
- 主要語言
- C++
- 星號
- 2.1k
- 分支
- 509
- 平均合併
- 2 天 13 小時
- 30 天內合併 PR
- 28
環境準備
- 沒有 Dockerfile 或 Docker Compose 檔案
- 有 Pull Request 範本
- 閱讀貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
DFHack/dfhack 的其他 Issue
-
難度 2/5 1-3 小時 新手友好度 66/100
維護者通常 2 天內回覆
-
RemoteFortressReader: GetCreatureRaws sends CP437 (not UTF-8) strings, which breaks protobuf decoding可能已有人在做 @dwmuller 於 1 天前認領。 未關閉
難度 2/5 1-3 小時 新手友好度 20/100
維護者通常 2 天內回覆
-
難度 5/5 一週以上 新手友好度 25/100
維護者通常 2 天內回覆
-
難度 5/5 一週以上 新手友好度 25/100
維護者通常 2 天內回覆
-
難度 3/5 1-2 天 新手友好度 35/100
維護者通常 2 天內回覆
相似的 Issue
-
(S1 - Need confirmation)
難度 2/5 1-3 小時 新手友好度 68/100
CleverRaven/Cataclysm-DDA#89212 ·
維護者通常 1 天內回覆
-
Status: Needs confirmation Status: Needs triage
難度 2/5 1-3 小時 新手友好度 70/100
維護者通常 1 天內回覆
-
ai_p2 comp-dictionary
難度 2/5 1-3 小時 新手友好度 78/100
ClickHouse/ClickHouse#127261 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 82/100
NVIDIA-Omniverse/usd-brep#23 ·
-
難度 2/5 1-3 小時 新手友好度 68/100
qbittorrent/qBittorrent#25121 ·
維護者通常 2 天內回覆