-
-
Notifications
You must be signed in to change notification settings - Fork 506
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactored for release. This is v1.0.0
- Loading branch information
Showing
13 changed files
with
394 additions
and
160 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,82 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
|
||
namespace Harmony | ||
{ | ||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] | ||
public class HarmonyPatch : Attribute | ||
public class HarmonyAttribute : Attribute | ||
{ | ||
public Type type; | ||
public string methodName; | ||
public Type[] parameter; | ||
public HarmonyMethod info = new HarmonyMethod(); | ||
} | ||
|
||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] | ||
public class HarmonyPatch : HarmonyAttribute | ||
{ | ||
public HarmonyPatch() | ||
{ | ||
} | ||
|
||
public HarmonyPatch(Type type) | ||
{ | ||
this.type = type; | ||
info.originalType = type; | ||
} | ||
|
||
public HarmonyPatch(string methodName) | ||
{ | ||
this.methodName = methodName; | ||
info.methodName = methodName; | ||
} | ||
|
||
public HarmonyPatch(Type[] parameter) | ||
{ | ||
this.parameter = parameter; | ||
info.parameter = parameter; | ||
} | ||
} | ||
|
||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] | ||
public class HarmonyPriority : HarmonyAttribute | ||
{ | ||
public HarmonyPriority(int prioritiy) | ||
{ | ||
info.prioritiy = prioritiy; | ||
} | ||
} | ||
|
||
public static HarmonyPatch Merge(List<HarmonyPatch> attributes) | ||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] | ||
public class HarmonyBefore : HarmonyAttribute | ||
{ | ||
public HarmonyBefore(params string[] before) | ||
{ | ||
var result = new HarmonyPatch(); | ||
attributes.ForEach(attr => | ||
{ | ||
if (attr.type != null) result.type = attr.type; | ||
if (attr.methodName != null) result.methodName = attr.methodName; | ||
if (attr.parameter != null) result.parameter = attr.parameter; | ||
}); | ||
return result; | ||
info.before = before; | ||
} | ||
} | ||
|
||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] | ||
public class HarmonyAfter : HarmonyAttribute | ||
{ | ||
public HarmonyAfter(params string[] after) | ||
{ | ||
info.after = after; | ||
} | ||
} | ||
|
||
// If you don't want to use the special method names you can annotate | ||
// using the following attributes: | ||
|
||
[AttributeUsage(AttributeTargets.Method)] | ||
public class HarmonyPrefix : Attribute | ||
public class HarmonyPrepare : Attribute | ||
{ | ||
} | ||
|
||
[AttributeUsage(AttributeTargets.Method)] | ||
public class HarmonyPostfix : Attribute | ||
public class HarmonyTargetMethod : Attribute | ||
{ | ||
} | ||
|
||
[AttributeUsage(AttributeTargets.Method)] | ||
public class HarmonyPrepare : Attribute | ||
public class HarmonyPrefix : Attribute | ||
{ | ||
} | ||
|
||
[AttributeUsage(AttributeTargets.Method)] | ||
public class HarmonyPostfix : Attribute | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Reflection; | ||
|
||
namespace Harmony | ||
{ | ||
public class HarmonyMethod | ||
{ | ||
public MethodInfo method; // need to be called 'method' | ||
|
||
public Type originalType; | ||
public string methodName; | ||
public Type[] parameter; | ||
public int prioritiy = -1; | ||
public string[] before; | ||
public string[] after; | ||
|
||
public HarmonyMethod() | ||
{ | ||
} | ||
|
||
void ImportMethod(MethodInfo method) | ||
{ | ||
this.method = method; | ||
if (method != null) | ||
{ | ||
var infos = method.GetHarmonyMethods(); | ||
if (infos != null) | ||
Merge(infos).CopyTo(this); | ||
} | ||
} | ||
|
||
public HarmonyMethod(MethodInfo method) | ||
{ | ||
ImportMethod(method); | ||
} | ||
|
||
public HarmonyMethod(Type type, string name, Type[] parameters = null) | ||
{ | ||
ImportMethod(AccessTools.Method(type, name, parameters)); | ||
} | ||
|
||
public static List<string> HarmonyFields() | ||
{ | ||
return AccessTools | ||
.GetFieldNames(typeof(HarmonyMethod)) | ||
.Where(s => s != "method") | ||
.ToList(); | ||
} | ||
|
||
public static HarmonyMethod Merge(List<HarmonyMethod> attributes) | ||
{ | ||
var result = new HarmonyMethod(); | ||
if (attributes == null) return result; | ||
var resultTrv = Traverse.Create(result); | ||
attributes.ForEach(attribute => | ||
{ | ||
var trv = Traverse.Create(attribute); | ||
HarmonyFields().ForEach(f => | ||
{ | ||
var val = trv.Field(f).GetValue(); | ||
if (val != null) | ||
resultTrv.Field(f).SetValue(val); | ||
}); | ||
}); | ||
return result; | ||
} | ||
} | ||
|
||
public static class HarmonyMethodExtensions | ||
{ | ||
public static void CopyTo(this HarmonyMethod from, HarmonyMethod to) | ||
{ | ||
if (to == null) return; | ||
var fromTrv = Traverse.Create(from); | ||
var toTrv = Traverse.Create(to); | ||
HarmonyMethod.HarmonyFields().ForEach(f => | ||
{ | ||
var val = fromTrv.Field(f).GetValue(); | ||
if (val != null) toTrv.Field(f).SetValue(val); | ||
}); | ||
} | ||
|
||
public static HarmonyMethod Clone(this HarmonyMethod original) | ||
{ | ||
var result = new HarmonyMethod(); | ||
original.CopyTo(result); | ||
return result; | ||
} | ||
|
||
public static HarmonyMethod Merge(this HarmonyMethod master, HarmonyMethod detail) | ||
{ | ||
if (detail == null) return master; | ||
var result = new HarmonyMethod(); | ||
var resultTrv = Traverse.Create(result); | ||
var masterTrv = Traverse.Create(master); | ||
var detailTrv = Traverse.Create(detail); | ||
HarmonyMethod.HarmonyFields().ForEach(f => | ||
{ | ||
var baseValue = masterTrv.Field(f).GetValue(); | ||
var detailValue = detailTrv.Field(f).GetValue(); | ||
resultTrv.Field(f).SetValue(detailValue != null ? detailValue : baseValue); | ||
}); | ||
return result; | ||
} | ||
|
||
public static List<HarmonyMethod> GetHarmonyMethods(this Type type) | ||
{ | ||
return type.GetCustomAttributes(true) | ||
.Where(attr => attr is HarmonyAttribute) | ||
.Cast<HarmonyAttribute>() | ||
.Select(attr => attr.info) | ||
.ToList(); | ||
} | ||
|
||
public static List<HarmonyMethod> GetHarmonyMethods(this MethodInfo method) | ||
{ | ||
return method.GetCustomAttributes(true) | ||
.Where(attr => attr is HarmonyAttribute) | ||
.Cast<HarmonyAttribute>() | ||
.Select(attr => attr.info) | ||
.ToList(); | ||
} | ||
} | ||
} |
Oops, something went wrong.