|
@@ -11,7 +11,46 @@ namespace COM3D2.CacheEditMenu.Patcher
|
|
public static readonly string[] TargetAssemblyNames = { "Assembly-CSharp.dll" };
|
|
public static readonly string[] TargetAssemblyNames = { "Assembly-CSharp.dll" };
|
|
|
|
|
|
public static readonly string SybarisPath = Path.GetDirectoryName(typeof(Patcher).Assembly.Location);
|
|
public static readonly string SybarisPath = Path.GetDirectoryName(typeof(Patcher).Assembly.Location);
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ private static void PatchHelper(MethodDefinition target, MethodReference prefix, MethodReference postix, params int[] ldargs)
|
|
|
|
+ {
|
|
|
|
+ var il = target.Body.GetILProcessor();
|
|
|
|
+ var resultVar = target.ReturnType.FullName != "System.Void" ? new VariableDefinition(target.Module.ImportReference(target.ReturnType)) : null;
|
|
|
|
+ if(resultVar != null)
|
|
|
|
+ target.Body.Variables.Add(resultVar);
|
|
|
|
+
|
|
|
|
+ var ins = target.Body.Instructions[0];
|
|
|
|
+
|
|
|
|
+ if(resultVar != null)
|
|
|
|
+ il.InsertBefore(ins, il.Create(OpCodes.Ldloca, resultVar));
|
|
|
|
+ foreach (var ldarg in ldargs)
|
|
|
|
+ il.InsertBefore(ins, il.Create(OpCodes.Ldarg, ldarg));
|
|
|
|
+ il.InsertBefore(ins, il.Create(OpCodes.Call, target.Module.ImportReference(prefix)));
|
|
|
|
+ il.InsertBefore(ins, il.Create(OpCodes.Brtrue, ins));
|
|
|
|
+ if(resultVar != null)
|
|
|
|
+ il.InsertBefore(ins, il.Create(OpCodes.Ldloc, resultVar));
|
|
|
|
+ il.InsertBefore(ins, il.Create(OpCodes.Ret));
|
|
|
|
+
|
|
|
|
+ if (postix == null)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ ins = il.Create(OpCodes.Nop);
|
|
|
|
+
|
|
|
|
+ foreach (var bodyInstruction in target.Body.Instructions.Where(bodyInstruction => bodyInstruction.OpCode == OpCodes.Ret).Skip(1))
|
|
|
|
+ {
|
|
|
|
+ bodyInstruction.OpCode = OpCodes.Br;
|
|
|
|
+ bodyInstruction.Operand = ins;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ il.Append(ins);
|
|
|
|
+ ins = il.Create(OpCodes.Ret);
|
|
|
|
+ il.Append(ins);
|
|
|
|
+
|
|
|
|
+ foreach (var ldarg in ldargs)
|
|
|
|
+ il.InsertBefore(ins, il.Create(OpCodes.Ldarg, ldarg));
|
|
|
|
+ il.InsertBefore(ins, il.Create(OpCodes.Call, target.Module.ImportReference(postix)));
|
|
|
|
+ }
|
|
|
|
+
|
|
public static void Patch(AssemblyDefinition ad)
|
|
public static void Patch(AssemblyDefinition ad)
|
|
{
|
|
{
|
|
var hookAd = AssemblyDefinition.ReadAssembly(
|
|
var hookAd = AssemblyDefinition.ReadAssembly(
|
|
@@ -21,51 +60,29 @@ namespace COM3D2.CacheEditMenu.Patcher
|
|
var sceneEdit = ad.MainModule.GetType("SceneEdit");
|
|
var sceneEdit = ad.MainModule.GetType("SceneEdit");
|
|
var getMenuItemSetUp = sceneEdit.Methods.FirstOrDefault(m => m.Name == "GetMenuItemSetUP");
|
|
var getMenuItemSetUp = sceneEdit.Methods.FirstOrDefault(m => m.Name == "GetMenuItemSetUP");
|
|
|
|
|
|
|
|
+ var importCm = ad.MainModule.GetType("ImportCM");
|
|
|
|
+ var createTexture = importCm.Methods.FirstOrDefault(m => m.Name == "CreateTexture" && m.Parameters.Count == 1);
|
|
|
|
+
|
|
var hookType = hookAd.MainModule.GetType("COM3D2.CacheEditMenu.Hooks");
|
|
var hookType = hookAd.MainModule.GetType("COM3D2.CacheEditMenu.Hooks");
|
|
var getMenuItemSetUpPrefix = hookType.Methods.FirstOrDefault(m => m.Name == "Prefix");
|
|
var getMenuItemSetUpPrefix = hookType.Methods.FirstOrDefault(m => m.Name == "Prefix");
|
|
var getMenuItemSetUpPostfix = hookType.Methods.FirstOrDefault(m => m.Name == "Postfix");
|
|
var getMenuItemSetUpPostfix = hookType.Methods.FirstOrDefault(m => m.Name == "Postfix");
|
|
|
|
|
|
- var il = getMenuItemSetUp.Body.GetILProcessor();
|
|
|
|
- var resultVar = new VariableDefinition(ad.MainModule.ImportReference(typeof(bool)));
|
|
|
|
- getMenuItemSetUp.Body.Variables.Add(resultVar);
|
|
|
|
- var ins = getMenuItemSetUp.Body.Instructions[0];
|
|
|
|
-
|
|
|
|
- il.InsertBefore(ins, il.Create(OpCodes.Ldloca, resultVar));
|
|
|
|
- il.InsertBefore(ins, il.Create(OpCodes.Ldarg_0));
|
|
|
|
- il.InsertBefore(ins, il.Create(OpCodes.Ldarg_1));
|
|
|
|
- il.InsertBefore(ins, il.Create(OpCodes.Call, ad.MainModule.ImportReference(getMenuItemSetUpPrefix)));
|
|
|
|
- il.InsertBefore(ins, il.Create(OpCodes.Brtrue, ins));
|
|
|
|
- il.InsertBefore(ins, il.Create(OpCodes.Ldloc, resultVar));
|
|
|
|
- il.InsertBefore(ins, il.Create(OpCodes.Ret));
|
|
|
|
-
|
|
|
|
- ins = il.Create(OpCodes.Nop);
|
|
|
|
-
|
|
|
|
- foreach (var bodyInstruction in getMenuItemSetUp.Body.Instructions.Where(bodyInstruction => bodyInstruction.OpCode == OpCodes.Ret).Skip(1))
|
|
|
|
- {
|
|
|
|
- bodyInstruction.OpCode = OpCodes.Br;
|
|
|
|
- bodyInstruction.Operand = ins;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- il.Append(ins);
|
|
|
|
- ins = il.Create(OpCodes.Ret);
|
|
|
|
- il.Append(ins);
|
|
|
|
-
|
|
|
|
- il.InsertBefore(ins, il.Create(OpCodes.Ldarg_0));
|
|
|
|
- il.InsertBefore(ins, il.Create(OpCodes.Ldarg_1));
|
|
|
|
- il.InsertBefore(ins, il.Create(OpCodes.Call, ad.MainModule.ImportReference(getMenuItemSetUpPostfix)));
|
|
|
|
-
|
|
|
|
|
|
+ var createTexturePrefix = hookType.Methods.FirstOrDefault(m => m.Name == "CreateTexturePrefix");
|
|
|
|
+
|
|
|
|
+ PatchHelper(getMenuItemSetUp, getMenuItemSetUpPrefix, getMenuItemSetUpPostfix, 0, 1);
|
|
|
|
+ PatchHelper(createTexture, createTexturePrefix, null, 0);
|
|
|
|
|
|
var buffer = new byte[4096];
|
|
var buffer = new byte[4096];
|
|
using(var s = typeof(Patcher).Assembly.GetManifestResourceStream(
|
|
using(var s = typeof(Patcher).Assembly.GetManifestResourceStream(
|
|
"COM3D2.CacheEditMenu.Patcher.COM3D2.CacheEditMenu.dll"))
|
|
"COM3D2.CacheEditMenu.Patcher.COM3D2.CacheEditMenu.dll"))
|
|
- using (var ms = new MemoryStream())
|
|
|
|
- {
|
|
|
|
- int read;
|
|
|
|
- while ((read = s.Read(buffer, 0, buffer.Length)) > 0)
|
|
|
|
- ms.Write(buffer, 0, read);
|
|
|
|
|
|
+ using (var ms = new MemoryStream())
|
|
|
|
+ {
|
|
|
|
+ int read;
|
|
|
|
+ while ((read = s.Read(buffer, 0, buffer.Length)) > 0)
|
|
|
|
+ ms.Write(buffer, 0, read);
|
|
|
|
|
|
- Assembly.Load(ms.ToArray());
|
|
|
|
- }
|
|
|
|
|
|
+ Assembly.Load(ms.ToArray());
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|