差分
このページの2つのバージョン間の差分を表示します。
| 両方とも前のリビジョン 前のリビジョン 次のリビジョン | 前のリビジョン | ||
|
appendix:harmonyがある時 [2024/12/18 15:11] fumble |
appendix:harmonyがある時 [2024/12/29 00:31] (現在) fumble |
||
|---|---|---|---|
| 行 62: | 行 62: | ||
| static void ILManipulator(ILContext il, MethodBase original, ILLabel retLabel) | static void ILManipulator(ILContext il, MethodBase original, ILLabel retLabel) | ||
| static void SomeOtherILManipulator(ILContext ctx, MethodBase orig) | static void SomeOtherILManipulator(ILContext ctx, MethodBase orig) | ||
| + | </ | ||
| + | |||
| + | 渡すときはHarmonyMethod(MethodInfo method)の変換、つまりコンストラクターを呼んで変換させる。 | ||
| + | <code csharp> | ||
| + | var transpilermethod = typeof(トランスパイラーのあるクラス).GetMethod(トランスパイラーのメソッド名); | ||
| + | var transpiler = Activator.CreateInstance(typeHarmonyMethod, | ||
| </ | </ | ||
| 問題が起こりそうなのはTranspilerとILManipulatorのパターンでCodeInstructionがHarmonyの中で、ILLabelがMonoMod.Cliの中で宣言されているので参照出来ない状況だと面倒になる。\\ | 問題が起こりそうなのはTranspilerとILManipulatorのパターンでCodeInstructionがHarmonyの中で、ILLabelがMonoMod.Cliの中で宣言されているので参照出来ない状況だと面倒になる。\\ | ||
| - | ILContextはMono.CecilなのでSybaris2/ | + | ※ILContextはMono.CecilなのでSybaris2/ |
| 特に面倒が起こりそうな Transpiler の実装方法を示す。 | 特に面倒が起こりそうな Transpiler の実装方法を示す。 | ||
| <code csharp> | <code csharp> | ||
| - | static object Transpiler(IEnumerable< | + | static object Transpiler(IEnumerable instructions) |
| { | { | ||
| - | var type = instructions.First().GetType(); | + | var enumerator |
| - | | + | |
| - | var fldOperand | + | |
| - | var newInstructions = Activator.CreateInstance(typeof(List<> | + | |
| - | foreach (var instruction in instructions) | + | |
| { | { | ||
| - | var opecode = fldOpecode.GetValue(instruction); | + | |
| - | var operand = fldOperand.GetValue(instruction); | + | var fldOpecode = type.GetField(" |
| - | if (opecode.Equals(変えたいところのOpCode) && operand.Equals(変えたいところのOperand)) | + | var fldOperand = type.GetField(" |
| - | newInstructions.Add(Activator.CreateInstance(type, | + | var newInstructions = Activator.CreateInstance(typeof(List<> |
| - | else | + | foreach (var instruction in instructions) |
| - | newInstructions.Add(instruction); | + | { |
| + | | ||
| + | var operand = fldOperand.GetValue(instruction); | ||
| + | if (opecode.Equals(変えたいところのOpCode) | ||
| + | newInstructions.Add(Activator.CreateInstance(type, | ||
| + | else | ||
| + | newInstructions.Add(instruction); | ||
| + | } | ||
| } | } | ||
| return newInstructions; | return newInstructions; | ||
| } | } | ||
| </ | </ | ||
| + | 引数をIEnumerableで受けて戻り値をobjectとかで宣言してしまいます。\\ | ||
| + | 引数で貰った IEnumerable< | ||
| + | |||
| + | <code csharp> | ||
| + | var newInstructions = Activator.CreateInstance(typeof(List<> | ||
| + | return newInstructions; | ||
| + | </ | ||
| + | |||
| + | こんなのでいいの?って思うかもしれませんが多分これで良いのです。\\ | ||
| + | あとは変えたいところだけ、全部変えたいなら全部詰め直して返せば良いです。\\ | ||
| + | OpCodeはSystem.Reflection.Emit.OpCodeっぽいのでこれを参照すればHarmonyLibの参照はなしでいけます。\\ | ||
| + | ILManipulatorの方もILLabel retLabelをobjectで受けてリフレクションを使えばいけると思います、必要が無い限りILLabelのない方を使えばいいと思います。\\ | ||
| - | 引数も戻り値も大嘘で宣言します。: | ||