中文本模组是给第三方模组 JStack424-堆叠大师 打出租车客户端补丁,含两个互相独立的修复项:
| 项 | 内容 | 性质 |
|---|---|---|
| A | 建造菜单 Alt + 左键(上游叫 快速拾取材料)拉取一整套材料时,箱子里的材料不扣减(等于复制) |
是 bug(在上游 1.2.0 上依然存在) |
| B | 上游 1.2.0 新增的「记住上次直接用过的箱子」回退:你把某个箱子清空后,在别处按 Alt + E(快速堆叠),刚取出来的东西会被原样塞回那个空箱 |
不是 bug,是上游有意做的特性(见下) |
上游 1.2.0 的更新日志明确写着这是有意添加的功能 —— 「快速堆叠会记住每种确切物品类型最近一次直接观察到的箱子, 即使那个宝箱库存归零后”,目的是方便“补货”:你有个装木材的箱子,把它用空了,下次快速堆叠时木材会自动回到那个箱子。
我认为“被我清空的箱子就应该保持空着”,所以用 禁用记忆宝箱 这个开关把它关掉。这只是个人习惯,不代表上游做错了。如果你觉得上游的行为挺好,请不要使用本补丁,或者将该开关设为 假 即可原样恢复上游行为。
禁用记忆宝箱 设为 假 即可。英语这是 客户端补丁 第三方模组 JStack424-栈主,与 两处独立修复:
Alt + 左键点击建筑部件):箱子从未被扣除,即物品复制。⚠️ B不是原模组中的漏洞。 上游1.2.0更新日志指出此行为是
故意的 (即使那个箱子库存归零后,也方便补货)。这个补丁只是 关闭该功能,因为我个人更喜欢空箱子保持为空. 如果你喜欢上游行为,请不要使用此补丁,或者设置
禁用记住宝箱 = false 将其完全恢复。
禁用记住宝箱 = false.🤖 本模组的代码由 AI 生成(AI 生成),需求、验证与发布由人类完成。
症状:把一个箱子里的东西取空 → 走到别的箱子按 Alt + E 快速堆叠 → 刚取出来的东西又被塞回那个空箱子。
根因(对 Stackmaster.dll 1.2.0 反汇编核对,316,416 B / sha256 be2fc8941b1abd96…):
已记住的宝箱位置:只要你直接打开/对准过某个箱子,就按"物品种类"把它记进本地 玩家偏好设置(上限 512 条、180 天过期)。
箱子被清空也不会抹掉这条记忆 —— 这是 changelog 里明写的有意设计。<>c__DisplayClass2_0::<PlanDeposits>b__1 的整个筛选逻辑就是
container.InitialCompatibilityKeys.Contains(source.CompatibilityKey)
⇒ 空箱子的候选键集合为空,永远进不了正常候选列表。存储转移计划.计划存入,IL 0x00FF-0x014A): 当剩余量 > 0 且本次一件都没搬走且 记住的.尝试获取值(堆叠Id, 输出 容器Id)
命中,且该箱子在当前发现范围内 ⇒ 把这一份放进那个箱子。 ⇒ 回退只可能发生在“这个箱子当前一件同类物品都没有”的时候。修改在
只读字典<string,string> Stackmaster.RememberedChestDestinations.ResolveFallbacks( 玩家, 物品栏快照, 发现结果)
上打一个 Postfix,把返回的 栈ID → 容器ID 回退表换成空表
⇒ 存款计划 的 如果字典中存在该键,则返回该键对应的值 永远未命中 ⇒ 回退永不触发。
影响面为什么是封闭的(脚本/验证堆叠大师修复.py 每次交付前自动核这四条):
| 核对项 | 实测结论 |
|---|---|
解析回退 全 DLL 调用点 |
只有 2 个:开始存储操作 与 <FinishAfterOwnership>d__17.MoveNext —— 都是快速堆叠存料路径 |
记忆数据读取点 已记住目的地状态:尝试获取 |
只被 回退解析 调用 1 次
⇒ 在返回值上拦截即完全封闭 |
| 是否影响合成扣料 / 快速取料(A 项) | 不影响,那是另外的类(附近资源 / 快速抓取材料动作) |
| 目标签名 | 3 个参数,返回类型恰好为 只读字典<字符串,字符串>,与 Postfix 的 参考 参数一字不差 |
刻意不做的事:
观察直接 / 玩家偏好设置 原样保留)。 ⇒ 本修复完全可逆把 禁用已记住的宝箱 设为 假 立刻恢复上游行为,不用重建记忆。存款失败警告)。⚠️ 须知副作用:上游 1.2.0 会对「合格但最终留在背包里」的物品临时打 数量! 红框(悬浮该物品一次即清除)。本修复让这部分物品真的留在背包里 ⇒ 红框出现的机会比以前多一点。 这是上游既有的提示机制,不是本补丁引入的新行为 —— 在离家老远、附近没箱子时按 Alt+E 本来就会满屏红框。配置:
| 键 | 默认 | 说明 |
|---|---|---|
禁用记忆宝箱 |
真 |
关闭「记忆箱子」回退。设置 假 = 完全恢复上游 1.2.0 行为。 |
新增配置节后需要重启游戏才会写出该节。
Stackmaster 1.1.5 自己修好了「用箱子材料合成/升级不扣料」。 依据:
……从每个已选中的自有 Container.GetInventory() 重新捕获,而不是从分离的 ZDO 库存快照中重新捕获……),并写明已在游戏内验证。附近资源服务 在执行期改用活库存重建运行时堆栈(附近资源.cs:1288 取 容器.获取物品栏(),:1294-1313 用它重建 handle,并在扣减前用 ReferenceEquals(runtime.Inventory, runtime.Container.Container.GetInventory())
做 fail-closed 身份校验(:1673-1681),另配精确扣减账本与逆序回滚。⇒ 本补丁最初针对 执行并回滚 的转译器已退化为恒等替换, 故 1.1.0 连同 从仓库修复制作 配置项一起删除。
⚠️ 但 1.1.5 的修复只覆盖制作:Quick Grab Materials 那条路径没动(见下),所以本补丁保留那一半。
2026-09-25 对上游 1.2.0 复核:这条路径依旧没修 —— 执行原子操作 里仍是
playerInventory.MoveItemToThis(runtime.Inventory, …),而那个 运行时.物品栏 仍来自
捕获以供快速抓取 → 捕获 → 发现(…, resourceReadOnly: true) 的分离 ZDO 快照 ⇒ 本补丁依然必需,没有可剔除的功能。
依赖因此升到
JStack424-Stackmaster-1.2.0。 ⚠️ 上游 1.2.0 把内部类远征套装动作改名快速抓取材料动作(1.2.0 更新日志将用户可见的“存放/补货”动作改为 Quick Stack,而“Quick Grab Materials”这一名称保持不变——改动的是内部类名)。本补丁 1.1.1 已跟随改成先试新名,再回退旧名, 两代上游都能装上。1.1.0 在 1.2.0 上会整体静默失效(找不到类型,180 秒后报错),请勿使用。
堆叠大师为了「不拿所有权也能读箱子」,把容器的序列化库存从 ZDO 解进一个临时背包
(新背包(真)),命名为 容器句柄.资源库存,作者注释自述
从不主张所有权或修改实时容器库存。
制作路径的执行期已经换成活库存了,但 快速拾取材料 没有:
QuickGrabMaterialsAction.Finish() → TryPrepare → CaptureForQuickGrab(player, true, true) → NearbyResources.Capture → ContainerDiscovery.Discover(…, resourceReadOnly: true) → ContainerDiscovery.Inspect:refreshed = !resourceReadOnly && … ⇒ false inventory = refreshed ? container.GetInventory() : null ⇒ null → 于是只解 ZDO 字节到 new Inventory(true),塞进 handle.ResourceInventory → NearbyResources.cs:1157 AddInventory(…, handle.ResourceInventory, …) ← runtimeStack 指向副本 → QuickGrabMaterialsAction.cs:656 MoveItemToThis(runtime.Inventory, …) ← 从副本里搬走
(制作专用 尝试占领已拥有的星球 / 可变捕获 从未被它调用。)
行号按 1.2.0 的源码给出;1.1.5 的对应位置在
远征工具包动作.cs里,内容一字不差 ——也就是说上游这次只是改了文件和类的名字,没改行为。
而 新背包(true) 的 临时背包 == true,游戏里 背包.已变更() 第一句就是
ldfld m_temoraryInventory; brfalse; ret ⇒ 永不发 已更改 ⇒ 不触发
容器.容器变化时 ⇒ 从不调用 容器.保存() ⇒ ZDO 里材料一点没少。 同时模组用 前 - 后 在同一个副本高出差值,必然判定成功 ⇒ 玩家白拿一套材料。
编译器只挂载一个目标方法:
| 目标方法 | 替换内容 |
|---|---|
堆叠大师.快速抓取材料动作::原子执行(上游 1.1.5 及更早叫 远征工具包操作) |
获取库存、获取物品 |
获取物品栏 → 真实容器的活库存(获取容器库存)获取物品 → 活库存里同一槽位的那个物品对象
(必须成对替换:移至此地 内部的扣减带 背包中是否包含该物品 的引用包含检查,只换 Inventory 不换 Item 会直接扣不动)容器.保存() + ZDO管理器.强制发送ZDO,确保写回权威数据安全取向:拿不到安全写入权(不是所有者()、容器已卸载、反射句柄缺失)时,返回一个空库存,让模组的 执行原子操作 自己判定失败并取消本次操作。
宁可取消,也不放行复制。
BepInEx/config/s6652289.StackmasterFix.cfg
| 项 | 默认 | 说明 |
|---|---|---|
修复探险工具包 |
真 |
修「建造菜单 Alt + 左键拉取一整套材料(上游叫 Quick Grab Materials)」的材料复制。键名沿用旧版的 修复远征工具包(上游 1.2.0 之前管它叫 expedition kit),改名会让已有配置失效,故不改 |
详细 |
真 |
打印每次重定向与强制写回的细节 |
旧版遗留在 cfg 里的
从仓库修复制作键已无用,可手动删除(不删也无副作用)。
日志(BepInEx/LogOutput.log里搜 修复:
[修复] 已打补丁:QuickGrabMaterialsAction.ExecuteAtomic(transpiler + 写回 postfix) [修复] transpiler 生效:QuickGrabMaterialsAction.ExecuteAtomic(N 条指令)→ get_Inventory 替换 4 处,get_Item 替换 5 处 [修复] 扣减重定向 → 真实容器 $piece_chest_blackmetal(Clone) uid=… 活库存总数=369 [修复] 已强制写回 ZDO: $piece_chest_blackmetal(Clone) uid=… 库存=368 zdoRev=1067
关键判据:拉一次材料后,箱子真的少了对应材料 修好了。 (在 1.1.5 及更早的上游上,日志里的名字会是 执行原子远征套装动作 —— 同一个方法,只是上游改过类名。) 若看到 [修复] ★transpiler 未匹配到任何目标指令 ⇒ Stackmaster 版本变了,本补丁失效,请反馈。
StackmasterFix.dll 放到 BepInEx/plugins/StackmasterFix/denikson-BepInExPack_Valheim + JStack424-堆叠大师(不需要 Jotunn、不联网、纯客户端)D:\WorkBuddy\StackmasterFix\(本地工作区)
运行时资源栈 / 执行原子操作 的结构,本补丁会打印
翻译器未匹配 并自然失效(不会造成新的破坏)。
修改前置工具
2026-09-12 14:33:53
修改前置工具

史诗战利品
randyknapp2026-09-09 21:20:10
为英灵神殿添加战利品掉落、魔法物品和附魔。

制作 建造 熔炼 烹饪 燃料 从容器中取出
aedenthorn2025-06-30 08:34:14
让你在制作、建造、使用熔炉和窑炉、添加燃料、烹饪食物等时,可以使用附近容器中的资源。

种植一切
Advize2025-09-09 11:15:37
重写了bkeyes93的种植增强模组。允许你的种植者种植浆果丛、蓟、蒲公英、蘑菇、此前无法获取的树种以及其他装饰性植物。还包括许多其他杂项功能(详见

无限制传送门
frostedplaything4102023-09-02 17:39:40
无限制传送门是一个客户端模组,允许玩家通过传送门传送任何物品。该模组提供广泛的自定义选项,让玩家能够控制物品限制、移除限制,

农场格子
Sarcenzzz2023-06-14 11:38:34
允许所有通过种植器种下的植物自动对齐并放置在网格中,确保它们有足够的生长空间。

更好的UI
MKMasa2021-04-15 09:19:42
这个模组对游戏界面做了一些细微的调整。你可以编辑并选择想要启用的更新内容。

更好的射箭
Ishid42026-09-10 16:16:51
为弓术玩法添加了许多功能和改动,包括全新的箭袋系统、可回收的箭矢、更精准的瞄准以及逼真的箭矢物理效果。