在统一游戏中编写对函数的函数调用不起作用
Writing function calls to a function within a unity game does not work
我正在尝试为游戏编写 mod 引擎。
为了实现这一点,我决定在 Unity 的 Assembly-CSharp 游戏代码文件中添加对我的引擎 dll 的引用,然后使用 Mono.cecil 我将对引擎的调用写入游戏的函数之一加载时调用。
但是,这个(函数调用)不起作用,代码执行正常但我的引擎没有被调用。我也试过用 dnSpy 来做,但也没有用。我能够在那里添加代码,如果函数被调用,它会写入文件,这有效,所以要么引擎被调用(或引用)的方式出了问题,要么 unity 做了一些事情来阻止这种行为。
使用 mono.cecil 添加引用:
private void AddRef(string path)
{
var _Module = ModuleDefinition.ReadModule(Path.Combine(Application.StartupPath, @"Assembly-CSharp.dll"));
var nameReference = new AssemblyNameReference("ModEngine", new Version(1, 0, 0, 0));
_Module.AssemblyReferences.Add(nameReference);
}
添加对函数的调用(可能不是一种非常有效的方法):
private void ReWrite()
{
var path = Path.Combine(Application.StartupPath, "Assembly-CSharp.dll"); //Get path to asm
var assembly = AssemblyDefinition.ReadAssembly(path); //Load asm
//Get types that match criteria
var toInspect = assembly.MainModule.GetTypes().SelectMany(t => t.Methods.Select(m => new { t, m })).Where(x => x.m.HasBody);
toInspect = toInspect.Where(x => x.t.Name.EndsWith("GlobalStats") && x.m.Name == "LoadStatData");
foreach (var method in toInspect) //Get the type
{
var processor = method.m.Body.GetILProcessor(); //Get IL processor
var call = processor.Create(OpCodes.Call, method.m.Module.Import(typeof(WeNeedToModDeeperEngine.ModEngine).GetMethod("Main"))); //Create a call opcode to the engine
var lastInstruction = method.m.Body.Instructions[method.m.Body.Instructions.Count - 1]; //Get the last command
processor.InsertBefore(lastInstruction, call); //Write the call before the first command
}
assembly.Write("Assembly-CSharp-patched.dll"); //Write the assembly
}
关于如何让这个(调用 mod 引擎)工作有什么想法吗?
看来你不能因为统一性而弄乱 Assembly-CSharp 文件,相反我正在使用 UnityEngine.CoreModule.dll 并注入 Display 或 Input
我正在尝试为游戏编写 mod 引擎。
为了实现这一点,我决定在 Unity 的 Assembly-CSharp 游戏代码文件中添加对我的引擎 dll 的引用,然后使用 Mono.cecil 我将对引擎的调用写入游戏的函数之一加载时调用。
但是,这个(函数调用)不起作用,代码执行正常但我的引擎没有被调用。我也试过用 dnSpy 来做,但也没有用。我能够在那里添加代码,如果函数被调用,它会写入文件,这有效,所以要么引擎被调用(或引用)的方式出了问题,要么 unity 做了一些事情来阻止这种行为。
使用 mono.cecil 添加引用:
private void AddRef(string path)
{
var _Module = ModuleDefinition.ReadModule(Path.Combine(Application.StartupPath, @"Assembly-CSharp.dll"));
var nameReference = new AssemblyNameReference("ModEngine", new Version(1, 0, 0, 0));
_Module.AssemblyReferences.Add(nameReference);
}
添加对函数的调用(可能不是一种非常有效的方法):
private void ReWrite()
{
var path = Path.Combine(Application.StartupPath, "Assembly-CSharp.dll"); //Get path to asm
var assembly = AssemblyDefinition.ReadAssembly(path); //Load asm
//Get types that match criteria
var toInspect = assembly.MainModule.GetTypes().SelectMany(t => t.Methods.Select(m => new { t, m })).Where(x => x.m.HasBody);
toInspect = toInspect.Where(x => x.t.Name.EndsWith("GlobalStats") && x.m.Name == "LoadStatData");
foreach (var method in toInspect) //Get the type
{
var processor = method.m.Body.GetILProcessor(); //Get IL processor
var call = processor.Create(OpCodes.Call, method.m.Module.Import(typeof(WeNeedToModDeeperEngine.ModEngine).GetMethod("Main"))); //Create a call opcode to the engine
var lastInstruction = method.m.Body.Instructions[method.m.Body.Instructions.Count - 1]; //Get the last command
processor.InsertBefore(lastInstruction, call); //Write the call before the first command
}
assembly.Write("Assembly-CSharp-patched.dll"); //Write the assembly
}
关于如何让这个(调用 mod 引擎)工作有什么想法吗?
看来你不能因为统一性而弄乱 Assembly-CSharp 文件,相反我正在使用 UnityEngine.CoreModule.dll 并注入 Display 或 Input