Attributes.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. using System;
  2. using System.Collections.Generic;
  3. namespace Harmony
  4. {
  5. public enum MethodType
  6. {
  7. Normal,
  8. Getter,
  9. Setter,
  10. Constructor,
  11. StaticConstructor
  12. }
  13. [Obsolete("This enum will be removed in the next major version. To define special methods, use MethodType")]
  14. public enum PropertyMethod
  15. {
  16. Getter,
  17. Setter
  18. }
  19. public enum ArgumentType
  20. {
  21. Normal,
  22. Ref,
  23. Out,
  24. Pointer
  25. }
  26. public enum HarmonyPatchType
  27. {
  28. All,
  29. Prefix,
  30. Postfix,
  31. Transpiler
  32. }
  33. public class HarmonyAttribute : Attribute
  34. {
  35. public HarmonyMethod info = new HarmonyMethod();
  36. }
  37. [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
  38. public class HarmonyPatch : HarmonyAttribute
  39. {
  40. // no argument (for use with TargetMethod)
  41. public HarmonyPatch()
  42. {
  43. }
  44. // starting with 'Type'
  45. public HarmonyPatch(Type declaringType)
  46. {
  47. info.declaringType = declaringType;
  48. }
  49. public HarmonyPatch(Type declaringType, Type[] argumentTypes)
  50. {
  51. info.declaringType = declaringType;
  52. info.argumentTypes = argumentTypes;
  53. }
  54. public HarmonyPatch(Type declaringType, string methodName)
  55. {
  56. info.declaringType = declaringType;
  57. info.methodName = methodName;
  58. }
  59. public HarmonyPatch(Type declaringType, string methodName, params Type[] argumentTypes)
  60. {
  61. info.declaringType = declaringType;
  62. info.methodName = methodName;
  63. info.argumentTypes = argumentTypes;
  64. }
  65. public HarmonyPatch(Type declaringType, string methodName, Type[] argumentTypes, ArgumentType[] argumentVariations)
  66. {
  67. info.declaringType = declaringType;
  68. info.methodName = methodName;
  69. ParseSpecialArguments(argumentTypes, argumentVariations);
  70. }
  71. public HarmonyPatch(Type declaringType, MethodType methodType)
  72. {
  73. info.declaringType = declaringType;
  74. info.methodType = methodType;
  75. }
  76. public HarmonyPatch(Type declaringType, MethodType methodType, params Type[] argumentTypes)
  77. {
  78. info.declaringType = declaringType;
  79. info.methodType = methodType;
  80. info.argumentTypes = argumentTypes;
  81. }
  82. public HarmonyPatch(Type declaringType, MethodType methodType, Type[] argumentTypes, ArgumentType[] argumentVariations)
  83. {
  84. info.declaringType = declaringType;
  85. info.methodType = methodType;
  86. ParseSpecialArguments(argumentTypes, argumentVariations);
  87. }
  88. public HarmonyPatch(Type declaringType, string propertyName, MethodType methodType)
  89. {
  90. info.declaringType = declaringType;
  91. info.methodName = propertyName;
  92. info.methodType = methodType;
  93. }
  94. // starting with 'string'
  95. public HarmonyPatch(string methodName)
  96. {
  97. info.methodName = methodName;
  98. }
  99. public HarmonyPatch(string methodName, params Type[] argumentTypes)
  100. {
  101. info.methodName = methodName;
  102. info.argumentTypes = argumentTypes;
  103. }
  104. public HarmonyPatch(string methodName, Type[] argumentTypes, ArgumentType[] argumentVariations)
  105. {
  106. info.methodName = methodName;
  107. ParseSpecialArguments(argumentTypes, argumentVariations);
  108. }
  109. public HarmonyPatch(string propertyName, MethodType methodType)
  110. {
  111. info.methodName = propertyName;
  112. info.methodType = methodType;
  113. }
  114. // starting with 'MethodType'
  115. public HarmonyPatch(MethodType methodType)
  116. {
  117. info.methodType = methodType;
  118. }
  119. public HarmonyPatch(MethodType methodType, params Type[] argumentTypes)
  120. {
  121. info.methodType = methodType;
  122. info.argumentTypes = argumentTypes;
  123. }
  124. public HarmonyPatch(MethodType methodType, Type[] argumentTypes, ArgumentType[] argumentVariations)
  125. {
  126. info.methodType = methodType;
  127. ParseSpecialArguments(argumentTypes, argumentVariations);
  128. }
  129. // starting with 'Type[]'
  130. public HarmonyPatch(Type[] argumentTypes)
  131. {
  132. info.argumentTypes = argumentTypes;
  133. }
  134. public HarmonyPatch(Type[] argumentTypes, ArgumentType[] argumentVariations)
  135. {
  136. ParseSpecialArguments(argumentTypes, argumentVariations);
  137. }
  138. // Obsolete attributes
  139. [Obsolete("This attribute will be removed in the next major version. Use HarmonyPatch together with MethodType.Getter or MethodType.Setter instead")]
  140. public HarmonyPatch(string propertyName, PropertyMethod type)
  141. {
  142. info.methodName = propertyName;
  143. info.methodType = type == PropertyMethod.Getter ? MethodType.Getter : MethodType.Setter;
  144. }
  145. //
  146. private void ParseSpecialArguments(Type[] argumentTypes, ArgumentType[] argumentVariations)
  147. {
  148. if (argumentVariations == null || argumentVariations.Length == 0)
  149. {
  150. info.argumentTypes = argumentTypes;
  151. return;
  152. }
  153. if (argumentTypes.Length < argumentVariations.Length)
  154. throw new ArgumentException("argumentVariations contains more elements than argumentTypes", nameof(argumentVariations));
  155. var types = new List<Type>();
  156. for (var i = 0; i < argumentTypes.Length; i++)
  157. {
  158. var type = argumentTypes[i];
  159. switch (argumentVariations[i])
  160. {
  161. case ArgumentType.Ref:
  162. case ArgumentType.Out:
  163. type = type.MakeByRefType();
  164. break;
  165. case ArgumentType.Pointer:
  166. type = type.MakePointerType();
  167. break;
  168. }
  169. types.Add(type);
  170. }
  171. info.argumentTypes = types.ToArray();
  172. }
  173. }
  174. [AttributeUsage(AttributeTargets.Class)]
  175. public class HarmonyPatchAll : HarmonyAttribute
  176. {
  177. public HarmonyPatchAll()
  178. {
  179. }
  180. }
  181. [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
  182. public class HarmonyPriority : HarmonyAttribute
  183. {
  184. public HarmonyPriority(int prioritiy)
  185. {
  186. info.prioritiy = prioritiy;
  187. }
  188. }
  189. [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
  190. public class HarmonyBefore : HarmonyAttribute
  191. {
  192. public HarmonyBefore(params string[] before)
  193. {
  194. info.before = before;
  195. }
  196. }
  197. [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
  198. public class HarmonyAfter : HarmonyAttribute
  199. {
  200. public HarmonyAfter(params string[] after)
  201. {
  202. info.after = after;
  203. }
  204. }
  205. // If you don't want to use the special method names you can annotate
  206. // using the following attributes:
  207. [AttributeUsage(AttributeTargets.Method)]
  208. public class HarmonyPrepare : Attribute
  209. {
  210. }
  211. [AttributeUsage(AttributeTargets.Method)]
  212. public class HarmonyCleanup : Attribute
  213. {
  214. }
  215. [AttributeUsage(AttributeTargets.Method)]
  216. public class HarmonyTargetMethod : Attribute
  217. {
  218. }
  219. [AttributeUsage(AttributeTargets.Method)]
  220. public class HarmonyTargetMethods : Attribute
  221. {
  222. }
  223. [AttributeUsage(AttributeTargets.Method)]
  224. public class HarmonyPrefix : Attribute
  225. {
  226. }
  227. [AttributeUsage(AttributeTargets.Method)]
  228. public class HarmonyPostfix : Attribute
  229. {
  230. }
  231. [AttributeUsage(AttributeTargets.Method)]
  232. public class HarmonyTranspiler : Attribute
  233. {
  234. }
  235. [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
  236. public class HarmonyArgument : Attribute
  237. {
  238. public string OriginalName { get; private set; }
  239. public int Index { get; private set; }
  240. public string NewName { get; private set; }
  241. public HarmonyArgument(string originalName) : this(originalName, null)
  242. {
  243. }
  244. public HarmonyArgument(int index) : this(index, null)
  245. {
  246. }
  247. public HarmonyArgument(string originalName, string newName)
  248. {
  249. OriginalName = originalName;
  250. Index = -1;
  251. NewName = newName;
  252. }
  253. public HarmonyArgument(int index, string name)
  254. {
  255. OriginalName = null;
  256. Index = index;
  257. NewName = name;
  258. }
  259. }
  260. }