public override void Patch(ReiPatcher.Patch.PatcherArguments args) { try { AssemblyDefinition ta = args.Assembly; AssemblyDefinition da = PatcherHelper.GetAssemblyDefinition(args, "CM3D2.MaidVoicePitch.Managed.dll"); string m = "CM3D2.MaidVoicePitch.Managed."; // TBody.LateUpdateの処理終了後にCM3D2.MaidVoicePitch.Managed.Callbacks.TBody.LateUpdate.Invokeを呼び出す PatcherHelper.SetHook(PatcherHelper.HookType.PostCall, ta, "TBody", "LateUpdate", da, m + "Callbacks.TBody.LateUpdate", "Invoke"); // TBody.MoveHeadAndEyeの処理を完全に乗っ取り、CM3D2.MaidVoicePitch.Managed.Callbacks.TBody.MoveHeadAndEye.Invokeの呼び出しに置き換える PatcherHelper.SetHook(PatcherHelper.HookType.PreJump, ta, "TBody", "MoveHeadAndEye", da, m + "Callbacks.TBody.MoveHeadAndEye", "Invoke"); // BoneMorph_.Blendの処理終了後にCM3D2.MaidVoicePitch.Managed.Callbacks.BoneMorph_.Blend.Invokeを呼び出す PatcherHelper.SetHook(PatcherHelper.HookType.PostCall, ta, "BoneMorph_", "Blend", da, m + "Callbacks.BoneMorph_.Blend", "Invoke"); // AudioSourceMgr.Playの処理終了後にCM3D2.MaidVoicePitch.Managed.Callbacks.AudioSourceMgr.Play.Invokeを呼び出す PatcherHelper.SetHook(PatcherHelper.HookType.PostCall, ta, "AudioSourceMgr", "Play", da, m + "Callbacks.AudioSourceMgr.Play", "Invoke"); // AudioSourceMgr.PlayOneShotの処理終了後にCM3D2.MaidVoicePitch.Managed.Callbacks.AudioSourceMgr.PlayOneShot.Invokeを呼び出す PatcherHelper.SetHook(PatcherHelper.HookType.PostCall, ta, "AudioSourceMgr", "PlayOneShot", da, m + "Callbacks.AudioSourceMgr.PlayOneShot", "Invoke"); SetPatchedAttribute(args.Assembly, patchTag); } catch (Exception e) { Helper.ShowException(e); throw; } }
public override void Patch(ReiPatcher.Patch.PatcherArguments args) { try { AssemblyDefinition ta = args.Assembly; AssemblyDefinition da = PatcherHelper.GetAssemblyDefinition(args, "CM3D2.VoiceNormalizer.Managed.dll"); string m = "CM3D2.VoiceNormalizer.Managed."; // 引数の型 string[] targetArgTypes = { "System.String", "System.Boolean" }; string[] calleeArgTypes = { "AudioSourceMgr", "System.String", "System.Boolean" }; PatcherHelper.SetHook( PatcherHelper.HookType.PreCall, ta, "AudioSourceMgr.LoadFromWf", targetArgTypes, da, m + "Callbacks.AudioSourceMgr.LoadFromWf.Invoke", calleeArgTypes); } catch (Exception e) { Helper.ShowException(e); throw; } }
public override void Patch(ReiPatcher.Patch.PatcherArguments args) { AssemblyDefinition ta = args.Assembly; AssemblyDefinition da = PatcherHelper.GetAssemblyDefinition(args, "CM3D2.ExternalSaveData.Managed.dll"); // GameMain.OnInitializeの処理後、CM3D2.略.ExSaveData.DummyInitializeを呼ぶ PatcherHelper.SetHook( PatcherHelper.HookType.PostCall, ta, "GameMain.OnInitialize", da, "CM3D2.ExternalSaveData.Managed.ExSaveData.DummyInitialize"); // GameMain.Deserializeの処理後、CM3D2.略.GameMainCallbacks.Deserialize.Invokeを呼ぶ PatcherHelper.SetHook( PatcherHelper.HookType.PostCall, ta, "GameMain.Deserialize", da, "CM3D2.ExternalSaveData.Managed.GameMainCallbacks.Deserialize.Invoke"); // GameMain.Deserializeの処理後、CM3D2.略.GameMainCallbacks.Serialize.Invokeを呼ぶ PatcherHelper.SetHook( PatcherHelper.HookType.PostCall, ta, "GameMain.Serialize", da, "CM3D2.ExternalSaveData.Managed.GameMainCallbacks.Serialize.Invoke"); // GameMain.DeleteSerializeDataの処理後、CM3D2.略.GameMainCallbacks.DeleteSerializeData.Invokeを呼ぶ PatcherHelper.SetHook( PatcherHelper.HookType.PostCall, ta, "GameMain.DeleteSerializeData", da, "CM3D2.ExternalSaveData.Managed.GameMainCallbacks.DeleteSerializeData.Invoke"); SetPatchedAttribute(args.Assembly, patchTag); }
public static AssemblyDefinition GetAssemblyDefinition(ReiPatcher.Patch.PatcherArguments args, string assemblyName) { var directoryName = Path.GetDirectoryName(args.Location); var filename = Path.Combine(directoryName, assemblyName); AssemblyDefinition ad = AssemblyDefinition.ReadAssembly(filename); if (ad == null) { throw new Exception(string.Format("{0} not found", assemblyName)); } return ad; }
public override void Patch(ReiPatcher.Patch.PatcherArguments args) { this.args = args; AssemblyDefinition ta = args.Assembly; AssemblyDefinition da = GetAssemblyDefinition(args, "CM3D2.ExternalSaveData.Managed.dll"); string m = "CM3D2.ExternalSaveData.Managed."; SetHook(HookType.PostCall, ta, "GameMain", "OnInitialize", da, m + "ExSaveData", "DummyInitialize"); SetHook(HookType.PostCall, ta, "GameMain", "Deserialize", da, m + "GameMainCallbacks.Deserialize", "Invoke"); SetHook(HookType.PostCall, ta, "GameMain", "Serialize", da, m + "GameMainCallbacks.Serialize", "Invoke"); SetHook(HookType.PostCall, ta, "GameMain", "DeleteSerializeData", da, m + "GameMainCallbacks.DeleteSerializeData", "Invoke"); SetPatchedAttribute(args.Assembly, patchTag); }
public override void Patch(ReiPatcher.Patch.PatcherArguments args) { try { AssemblyDefinition ta = args.Assembly; AssemblyDefinition da = PatcherHelper.GetAssemblyDefinition(args, "CM3D2.VoiceNormalizer.Managed.dll"); string m = "CM3D2.VoiceNormalizer.Managed."; PatcherHelper.SetHook( PatcherHelper.HookType.PreCall, ta, "AudioSourceMgr.LoadFromWf", da, m + "Callbacks.AudioSourceMgr.LoadFromWf.Invoke"); } catch (Exception e) { Helper.ShowException(e); throw; } }
public override void Patch(ReiPatcher.Patch.PatcherArguments args) { try { AssemblyDefinition ta = args.Assembly; AssemblyDefinition da = PatcherHelper.GetAssemblyDefinition(args, "CM3D2.ShaderWorkbench.Managed.dll"); PatcherHelper.SetHook( PatcherHelper.HookType.PostCallRet, ta, "ImportCM.ReadMaterial", da, "CM3D2.ShaderWorkbench.Managed.Callbacks.ImportCM.ReadMaterial.Invoke"); SetPatchedAttribute(args.Assembly, PatchTag); } catch (Exception e) { DetailedException.Show(e); throw; } }
public override void Patch(ReiPatcher.Patch.PatcherArguments args) { TypeDefinition gameuty = args.Assembly.MainModule.GetType("GameUty"); var initmethod = gameuty.Methods.First((MethodDefinition def) => def.Name == "Init"); foreach (var il in initmethod.Body.Instructions) { if (il.OpCode == OpCodes.Newobj) { MethodReference oprnd = (MethodReference)il.Operand; if (oprnd.DeclaringType.ToString() == "FileSystemArchive") { var defHook_ctor = hookdef.MainModule.GetType("CM3D2.ArchiveReplacer.Hook.HookArchive") .Methods.First((MethodDefinition def) => def.Name == ".ctor"); il.Operand = args.Assembly.MainModule.Import(defHook_ctor); } } } base.SetPatchedAttribute(args.Assembly, patchTag); }
public override bool CanPatch(ReiPatcher.Patch.PatcherArguments args) { return args.Assembly.Name.Name == "Assembly-CSharp" && !base.GetPatchedAttributes(args.Assembly).Any(a => a.Info == patchTag); }
public override void Patch(ReiPatcher.Patch.PatcherArguments args) { PatchGetAnyMouseAndKey(GetMethod( args.Assembly.MainModule.GetType("SceneLogo"), "GetAnyMouseAndKey")); PatchGetAnyMouseAndKey(GetMethod( args.Assembly.MainModule.GetType("SceneWarning"), "GetAnyMouseAndKey")); TypeDefinition tCameraMain = args.Assembly.MainModule.GetType("CameraMain"); PatchIsForceSkip(GetMethod(tCameraMain, "FadeIn")); PatchIsForceSkip(GetMethod(tCameraMain, "FadeInNoUI")); PatchIsForceSkip(GetMethod(tCameraMain, "FadeOut")); PatchIsForceSkip(GetMethod(tCameraMain, "FadeOutNoUI")); { // セーブロード画面のフェードアウト MethodDefinition targetMethod = GetMethod( args.Assembly.MainModule.GetType("TweenAlpha"), "Begin"); Mono.Cecil.Rocks.MethodBodyRocks.SimplifyMacros(targetMethod.Body); foreach (Instruction inst in targetMethod.Body.Instructions) { // 第二引数 (duration) の値の代わりに DefaultUiFadeInTime を積む if (inst.OpCode == OpCodes.Ldarg && ((ParameterDefinition)inst.Operand).Index == 1) { inst.OpCode = OpCodes.Ldc_R4; inst.Operand = DefaultUiFadeInTime; } } Mono.Cecil.Rocks.MethodBodyRocks.OptimizeMacros(targetMethod.Body); } { // セーブロード画面のフェードイン // ldc.r4 0.0 // stfld float32 TweenAlpha::from // を // ldc.r4 1.0 // stfld float32 TweenAlpha::from // に書き換える MethodDefinition targetMethod = GetMethod( args.Assembly.MainModule.GetType("BasePanelMgr"), "FadeInPanel"); Mono.Cecil.Rocks.MethodBodyRocks.SimplifyMacros(targetMethod.Body); foreach (Instruction inst in targetMethod.Body.Instructions) { if (inst.OpCode == OpCodes.Stfld && inst.Operand.ToString().Contains("TweenAlpha::from")) { inst.Previous.Operand = 1.0f; } } Mono.Cecil.Rocks.MethodBodyRocks.OptimizeMacros(targetMethod.Body); } { // 日付アイキャッチ画面スキップ // Input.anyKeyの戻り値を破棄して、常にtrueにする MethodDefinition targetMethod = GetMethod( args.Assembly.MainModule.GetType("StartDailyMgr"), "Update"); Mono.Cecil.Rocks.MethodBodyRocks.SimplifyMacros(targetMethod.Body); Instruction inst = targetMethod.Body.Instructions.First( i => i.OpCode == OpCodes.Call && i.Operand.ToString().Contains("Input::get_anyKey")); ILProcessor l = targetMethod.Body.GetILProcessor(); Instruction instInsertPoint = inst.Next; InsertInstDelegate o = newInst => { l.InsertBefore(instInsertPoint, newInst); }; o(l.Create(OpCodes.Pop)); o(l.Create(OpCodes.Ldc_I4, 1)); Mono.Cecil.Rocks.MethodBodyRocks.OptimizeMacros(targetMethod.Body); } SetPatchedAttribute(args.Assembly, patchTag); }
void Patch_SceneEdit_SlideCallback(ReiPatcher.Patch.PatcherArguments args) { // SceneEdit.SlideCallback の補間式を変更し、 // タブ等を変更してスライダーがアクティブになる度に // 負の値が 0 に近づくのを抑制する // // 元の補間式は以下のようになっている // // (int) (prop1.min + (prop1.max - prop1.min) * UIProgressBar.current.value + 0.5) // // 例えば prop1.min = -100, prop1.max = 100, UIProgressBar.current.value = 0 の場合、 // 以下のようになる // // (int) (-100 + (100+100) * 0 + 0.5) // = (int) (-99.5) // = -99 // // double -> int のキャストについては右記を参照 : https://msdn.microsoft.com/en-us/library/yht2cx7b.aspx // // この値は期待する値 -100 になっていないので、これを以下のように修正したい // // (int) Math.Round(prop1.min + (prop1.max - prop1.min) * UIProgressBar.current.value) // // ILレベルでは、該当部分は以下のようになっているので // // IL_004a: callvirt instance float32 UIProgressBar::get_value() // IL_004f: mul // IL_0050: add // --> IL_0051: ldc.r4 0.5 // --> IL_0056: add // IL_0057: conv.i4 // // これを以下のように改変する // // IL_004a: callvirt instance float32 UIProgressBar::get_value() // IL_004f: mul // IL_0050: add // --> IL_0051: call float64 [mscorlib]System.Math::Round(float64) // --> IL_0056: nop // IL_0057: conv.i4 // [Assembly-CSharp] SceneEdit.SlideCallback() を取得 var method = GetMethod( args.Assembly, // Assembly-CSharp.dll "SceneEdit", // クラス名 "SlideCallback", // メソッド名 new string[] { } // メソッドの引数の型 (void) ); // [mscorlib.dll] System.Math.Round(System.Double) を取得 var methodReference = GetMethod( args, "mscorlib.dll", // DLL 名 "System.Math", // クラス名 "Round", // メソッド名 new string[] { "System.Double" } // メソッドの引数の型 ); Mono.Cecil.Rocks.MethodBodyRocks.SimplifyMacros(method.Body); // SlideCallback内で ldc.r4 0.5 (IL_0051の命令) を探す var inst = method.Body.Instructions.First( i => i.OpCode == OpCodes.Ldc_R4 && (float)i.Operand == 0.5f); // 見つけた場所の命令を Call に書き換え inst.OpCode = OpCodes.Call; inst.Operand = args.Assembly.MainModule.Import(methodReference); // 次の命令を Nop に書き換え inst.Next.OpCode = OpCodes.Nop; Mono.Cecil.Rocks.MethodBodyRocks.OptimizeMacros(method.Body); }
MethodDefinition GetMethod( ReiPatcher.Patch.PatcherArguments rpArgs, string dllFileName, string typeName, string methodName, params string[] args) { AssemblyDefinition ad = PatcherHelper.GetAssemblyDefinition(rpArgs, dllFileName); return GetMethod(ad, typeName, methodName, args); }
static AssemblyDefinition GetAssemblyDefinition(ReiPatcher.Patch.PatcherArguments args, string assemblyName) { var directoryName = Path.GetDirectoryName(args.Location); var filename = Path.Combine(directoryName, assemblyName); return AssemblyDefinition.ReadAssembly(filename); }