一. 前言
经过前面8节的学习,我们已经可以制作很多种mod,但是在开发中,总会出现一点意外情况,比如,我想修改的数据是private的怎么办?如果你对C#有些经验,第一反应应该是,反射。是的,在C#中访问和修改私有成员需要使用反射,对于mod来说,我们不可避免的总是需要访问一些被设置为私有的成员或者还有一些特别的需要,所以,Harmony为我们准备了几个工具类,让我们更方便的完成需求。
二. AccessTools
这是Harmony为了简化反射为我们准备的类,通过它我们可以轻松的访问这个成员,因为所有的方法都使用完整的绑定标志,无论它是私有还是静态的等等都可以访问。
常用方法
public static Type TypeByName(string name) //根据名字获取类型
public static FieldInfo Field(Type type, string name) //根据类型和名字获取字段
public static PropertyInfo Property(Type type, string name) //根据类型和名字获取属性
public static MethodInfo Method(Type type, string name, Type[] parameters = null, Type[] generics = null) //根据类型和名字和(参数、泛型 可选)来获取方法
public static ConstructorInfo Constructor(Type type, Type[] parameters = null) //根据类型和参数来获取构造函数
public static Type Inner(Type type, string name) //根据类型和名字来获取内部类型
三. Traverse
上面AccessTools获取到的都是宏观的信息,我们通常需要得到的是具体的数据,这个时候就到了Traverse出场的时候了。
// 从类型或者实例来创建Traverse
public static Traverse Create(Type type)
public static Traverse Create<T>()
public static Traverse CreateWithType(string name)
// 继续深入我们需要的数据
public Traverse Type(string name)
public Traverse Field(string name)
public Traverse Property(string name, object[] index = null)
public Traverse Method(string name, params object[] arguments)
public Traverse Method(string name, Type[] paramTypes, object[] arguments = null)
// 获取数据
public object GetValue()
public T GetValue<T>()
public object GetValue(params object[] arguments)
public T GetValue<T>(params object[] arguments)
public override string ToString()
// 设置值
public Traverse SetValue(object value)
// 迭代
public static void IterateFields(object source, Action<Traverse> action)
public static void IterateFields(object source, object target, Action<Traverse, Traverse> action)
public static void IterateProperties(object source, Action<Traverse> action)
public static void IterateProperties(object source, object target, Action<Traverse, Traverse> action)
例子:假设游戏中有一个类People,它是这样的
public class People
{
public string Name;
public int Age;
private string address;
...
}
People的地址是私有的,我们不能直接访问它,这个时候我们使用Traverse。
// 游戏中某个地方的People
People p = new People();
//我们获取p.address的值
string address = Traverse.Create(p).Field("address").GetValue<string>();
四. FileLog
为了简单和快速的记录日志用以开发调试,Harmony准备了FileLog类,它只有3个方法,非常简单。
//创建一个新的日志文件,名为"harmony.log.txt",保存在电脑的桌面上,如果已经存在这个文件,则会将str添加到文件末尾
public static void Log(string str)
//删除日志文件
public static void Reset()
//用法相当于Log(string str),但是以16进制保存
public static unsafe void LogBytes(long ptr, int len)