一个小型BepInEx补丁器,用于 英灵神殿 1.0(极北之地)它重新添加了两个游戏方法,其签名在1.0版本中发生了改变,改变方式是 添加可选尾随参数,因此为旧版游戏制作的模组仍能继续使用 不修改他们的文件:
| 恢复(旧版)过载 | 转发至 (1.0) |
|---|---|
角色.消息(类型, 消息, 数量, 图标) |
消息(type, msg, amount, icon, log = false) |
SEMan.AddStatusEffect(哈希, 重置时间, 物品等级, 技能等级) |
相同 + 变体 = 0 |
Smoothbrain的挖矿、畜牧和ComfortTweaks等旧模组需要它。一旦这些模组作者更新,就不再需要这个包了。如果游戏已经有了旧的过载,它不会做任何事情,而且它失败也不会阻止游戏启动。
注意: 添加重载会使该方法的查找变得 仅按名称 含糊不清,所以这里只针对这两个方法做兼容。那些不带参数类型修补这些方法的模组可能会受影响。
AI 披露: 此补丁程序是在AI(Anthropic的Claude)协助下编写的,随后在Valheim 1.0正式版专用服务器上进行了测试。
MIT 许可。源代码(整个修补程序):
这是BepInEx预加载器补丁:通过给末尾参数添加默认值,恢复Valheim 1.0(Deep North)所移除的API重载,使为旧版游戏构建的模组无需修改其DLL即可继续工作。此为本项目自有代码,不再分发任何模组。每个恢复的重载都会转发到新方法,并用新末尾参数声明的默认值(或default(T))填充它们。仅处理下方白名单中的方法。注意:每添加一个重载,都会使对该方法仅按名称进行的反射/Harmony查找产生歧义。using System; using System.Collections.Generic; using System.Linq; using Mono.Cecil; using Mono.Cecil.Cil; public static class MistookenCompatPatcher { // 类型、方法、模组仍会调用的旧参数类型(完整名称)。 static readonly string[][] Shims = new string[][] { new string[] { "Character", "Message", "MessageHud/MessageType", "System.String", "System.Int32", "UnityEngine.Sprite" }, new string[] { "SEMan", "AddStatusEffect", "System.Int32", "System.Boolean", "System.Int32", "System.Single" }, // 有意不进行兼容处理:Piece.SetCreator、EffectList.Create、PlayerProfile.IncrementStat。保持更新的模组 //(例如PlantEverything)会按名称对这些方法打补丁;第二个重载会使Harmony的查找产生歧义并导致它们损坏。 }; public static IEnumerable<string> TargetDLLs { get { yield return "assembly_valheim.dll"; } } public static void Patch(AssemblyDefinition assembly) { foreach (string[] s in Shims) { try { AddForwardingOverload(assembly.MainModule, s[0], s[1], s.Skip(2).ToArray()); } catch (Exception) { /* 某个兼容处理失败绝不能阻止游戏启动 */ } } } static bool ParamsMatch(MethodDefinition m, string[] oldTypes, int count) { if (m.Parameters.Count != count) return false; for (int i = 0; i < oldTypes.Length && i < count; i++) if (m.Parameters[i].ParameterType.FullName != oldTypes[i]) return false; return true; } static void AddForwardingOverload(ModuleDefinition module, string typeName, string methodName, string[] oldTypes) { TypeDefinition type = module.GetType(typeName); if (type == null) return; if (type.Methods.Any(m => m.Name == methodName && ParamsMatch(m, oldTypes, oldTypes.Length))) return; // 已存在 MethodDefinition target = type.Methods.FirstOrDefault(m => m.Name == methodName && m.Parameters.Count > oldTypes.Length && ParamsMatch(m, oldTypes, m.Parameters.Count)); if (target == null) return; MethodAttributes attrs = MethodAttributes.Public | MethodAttributes.HideBySig; if (target.IsStatic) attrs |= MethodAttributes.Static; MethodDefinition shim = new MethodDefinition(methodName, attrs, target.ReturnType); shim.HasThis = !target.IsStatic; for (int i = 0; i < oldTypes.Length; i++) shim.Parameters.Add(new ParameterDefinition(target.Parameters[i].Name, ParameterAttributes.None, target.Parameters[i].ParameterType)); shim.Body.InitLocals = true; ILProcessor il = shim.Body.GetILProcessor(); if (!target.IsStatic) il.Emit(OpCodes.Ldarg_0); for (int i = 0; i < oldTypes.Length; i++) il.Emit(OpCodes.Ldarg, shim.Parameters[i]); for (int i = oldTypes.Length; i < target.Parameters.Count; i++) EmitDefault(shim, il, target.Parameters[i]); il.Emit(target.IsStatic || !target.IsVirtual ? OpCodes.Call : OpCodes.Callvirt, target); il.Emit(OpCodes.Ret); type.Methods.Add(shim); } static void EmitDefault(MethodDefinition shim, ILProcessor il, ParameterDefinition p) { if (p.HasConstant && p.Constant != null) { object c = p.Constant; if (c is bool) { il.Emit(((bool)c) ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); return; } if (c is int) { il.Emit(OpCodes.Ldc_I4, (int)c); return; } if (c is short) { il.Emit(OpCodes.Ldc_I4, (int)(short)c); return; } if (c is byte) { il.Emit(OpCodes.Ldc_I4, (int)(byte)c); return; } if (c is float) { il.Emit(OpCodes.Ldc_R4, (float)c); return; } } TypeDefinition def = p.ParameterType.Resolve(); if (def != null && def.IsValueType) { VariableDefinition loc = new VariableDefinition(p.ParameterType); shim.Body.Variables.Add(loc); il.Emit(OpCodes.Ldloca, loc); il.Emit(OpCodes.Initobj, p.ParameterType); il.Emit(OpCodes.Ldloc, loc); } else il.Emit(OpCodes.Ldnull); } }

修改前置工具
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
为弓术玩法添加了许多功能和改动,包括全新的箭袋系统、可回收的箭矢、更精准的瞄准以及逼真的箭矢物理效果。