appendix:harmonyがある時

文書の過去の版を表示しています。


SybarisプラグインだけどBepInEx環境で動いていて、HarmonyLib(HarmonyX)が使える場合での Harmony.Patch を呼ぶ方法。
Harmony.Patch が呼べるのであれば、任意のタイミングでパッチあてが行えるので強力な外道行為が行える。

あるかないかわからないHarmonyLib(HarmonyX)を参照するわけにはいかないので1)、リフレクションを駆使してインスタンスを作成する。

// HarmonyLib.Harmonyを探せ!
foreach (var loadedAssembly in AppDomain.CurrentDomain.GetAssemblies())
{
    var typeHarmony = loadedAssembly.GetType("HarmonyLib.Harmony");
    var typeHarmonyMethod = assembly.GetType("HarmonyLib.HarmonyMethod");
    // あったか!?
    if (typeHarmony != null && typeHarmonyMethod != null)
    {
        // あったぞ!!
        var harmony = Activator.CreateInstance(typeHarmony, "GUIDとか");
    }
}

これは簡単でGetMethodしてしまえばいいが、オーバーロードがあるので引数を指定してとる。

if (harmony != null)
{
    // 作れたぞ!!
    var harmonyPatch = typeHarmony.GetMethod("Patch", new Type[]
    {
        typeof(System.Reflection.MethodBase),   // original
        typeHarmonyMethod,                      // prefix
        typeHarmonyMethod,                      // postfix
        typeHarmonyMethod,                      // transpiler
        typeHarmonyMethod,                      // finalizer
        typeHarmonyMethod,                      // ilmanipulator
    });
}

1つめはMethodBaseなので単純にGetMethod取得すれば良い、残りはHarmonyMethod型だがMethodInfoとDelegateからの変換が用意されているのでGetMethod(Delegateがあるのでラムダ式でも可)で解決出来る。

public static implicit operator HarmonyMethod(MethodInfo method) => new(method);
public static implicit operator HarmonyMethod(Delegate @delegate) => new(@delegate);

それぞれ渡すべきプロトタイプは

static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)

1)
いっそ参照してりぞるばで解決しても良いかもだけど

コメント

コメントを入力:
 
  • appendix/harmonyがある時.1734500822.txt.gz
  • 最終更新: 2024/12/18 14:47
  • by fumble