HarmonyPatchExtensions
Adds mixin like patching to Harmony
模組介紹 作者原文
Harmony.PatchExtensions
Attribute based extensions for Harmony that lets you define mixin style patches.
Features
- Attribute based patches
- Injection points: HEAD (prefix), POSTFIX, RETURN (At every return), INVOKE (insert before call), REDIRECT (replace call), AFTER (after call), FINALLY, ARG, LOOP_BEFORE/TOP/BOTTOM/AFTER, BRANCH_TRUE/FALSE, LOCAL_WRITE/READ, ARG_WRITE/READ, FIELD_WRITE/READ
- Occurrence and start-index targeting
- Conflict detection
- Optional wrapper for overwriting prefixes that return the target's return type
- Patching variable declarations in methods
Install
Use one of the following:
- Reference the project directly in your solution
- Install the published NuGet package: (Insert package when uploaded here)
- If using publicizers add `` to an ItemGroup so documentations shows up in the code editor
Quick Start
using System.Reflection;
using HarmonyLib;
using HarmonyLib.PatchExtensions;
public static class Program
{
public static void Main()
{
var harmony = new Harmony("example.patching");
MixinLoader.ApplyPatches(harmony, Assembly.GetExecutingAssembly());
// Or for using a single patch class
// MixinLoader.ApplyPatches(harmony, Assembly.GetExecutingAssembly(), typeof(Patches));
}
}
Patch Examples
HEAD (prefix)
using HarmonyLib.PatchExtensions;
public static class Patches
{
[Patch(typeof(Target), "Add", AT.HEAD)]
public static void AddPrefix(int a, int b)
{
// Will run before Target.Add
a += 1;
}
}
Result:
public class Target
{
public int Add(int a, int b)
{
+ a += 1;
return a + b;
}
}
HEAD overwrite (skip original)
If overwriting: true, the patch can return bool (Harmony style) or the same return type as the target.
using HarmonyLib.PatchExtensions;
public static class OverwritePatches
{
[Patch(typeof(Target), "Add", AT.HEAD, overwriting: true)]
public static int AddOverwrite(int a, int b)
{
return 68; // the wrapper sets __result and skips original automatically
}
}
Result:
public class Target
{
public int Add(int a, int b)
{
+ return 68;
- return a + b;
}
}
POSTFIX (Just harmony postfix)
using HarmonyLib.PatchExtensions;
public static class PostfixPatches
{
[Patch(typeof(Target), "Add", AT.POSTFIX)]
public static void AddPostfix(int a, int b, ref int __result)
{
__result += 1;
}
}
Result:
public class Target
{
public int Add(int a, int b)
{
- return a + b;
+ __result = a + b;
+ __result += 1;
return __result;
}
}
RETURN
using HarmonyLib.PatchExtensions;
public static class ReturnPatches
{
[Patch(typeof(Target), "Foo", AT.RETURN)]
public static void AddReturn(int a, int b, bool c, ref int __result)
{
__result += 1;
}
}
Result:
public class Target
{
public int Foo(int a, int b, bool c)
{
if (c)
{
__result = a;
+ __result += 1;
return __result;
}
else
{
__result = b;
+ __result += 1;
return __result;
}
}
}
INVOKE (insert before call)
using HarmonyLib.PatchExtensions;
public static class InvokePatches
{
[Patch(typeof(TargetCalls), "Foo", AT.INVOKE, target: "Helper.DoThing", occurrence: 2)] // occurrence: 0 matches all
public static void BeforeSecondCall()
{
// Injected before the 2nd call to Helper.DoThing
}
}
Result:
public class TargetCalls
{
public void Foo()
{
Helper.DoThing();
+ InvokePatches.BeforeSecondCall();
Helper.DoThing();
}
}
REDIRECT (replace call)
using HarmonyLib.PatchExtensions;
public static class RedirectPatches
{
[Patch(typeof(TargetCalls), "Foo", AT.REDIRECT, target: "Helper.DoThing", occurrence: 0)] // occurrence can also be specified to target
public static void ReplaceCall()
{
// Replaces Helper.DoThing with this method
}
}
Result:
public class TargetCalls
{
public void Foo()
{
- Helper.DoThing();
- Helper.DoThing();
+ RedirectPatches.ReplaceCall();
+ RedirectPatches.ReplaceCall();
}
}
REDIRECT with occurrence
using HarmonyLib.PatchExtensions;
public static class RedirectPatches
{
[Patch(typeof(TargetCalls), "Foo", AT.REDIRECT, target: "Helper.DoThing", occurrence: 1)] // occurrence
安裝與使用 安裝:BepInEx 外掛
- 本站下載的壓縮包就是模組本體,通常是 BepInEx 外掛(解壓後得到 .dll 或外掛資料夾)。
- 建議流程:用社群模組管理器(如 r2modman)選中本遊戲後匯入該模組,管理器會自動裝好 BepInEx 前置並處理依賴。
- 手動流程:先在遊戲目錄裝好 BepInEx 載入器,再把解壓出的 .dll 或外掛資料夾放進 BepInEx/plugins/。
- 啟動遊戲,BepInEx 控制台會列印載入日誌;確認這個模組出現在日誌裡即為安裝成功。
帶「前置依賴」的模組需要一併安裝,否則不會載入。功能開關通常在遊戲內或外掛自帶的設定檔裡調整。
下面這些內容需要先安裝,否則該模組不會生效: