internal static IEnumerable ConvertToOurInstructions(IEnumerable instructions, Type codeInstructionType, List <object> originalInstructions, Dictionary <object, Dictionary <string, object> > unassignedValues) { var newInstructions = instructions.Cast <object>().ToList(); var index = -1; foreach (var op in newInstructions) { index++; var elementTo = AccessTools.MakeDeepCopy(op, codeInstructionType); if (unassignedValues.TryGetValue(op, out var fields)) { var addExceptionInfo = ShouldAddExceptionInfo(op, index, originalInstructions, newInstructions, unassignedValues); var trv = Traverse.Create(elementTo); foreach (var field in fields) { if (addExceptionInfo || field.Key != nameof(CodeInstruction.blocks)) { _ = trv.Field(field.Key).SetValue(field.Value); } } } yield return(elementTo); } }
internal static AttributePatch Create(MethodInfo patch) { if (patch == null) { throw new NullReferenceException("Patch method cannot be null"); } var allAttributes = patch.GetCustomAttributes(true); var methodName = patch.Name; var type = GetPatchType(methodName, allAttributes); if (type != HarmonyPatchType.ReversePatch && patch.IsStatic == false) { throw new ArgumentException("Patch method " + patch.FullDescription() + " must be static"); } var harmonyPatchName = typeof(HarmonyPatch).FullName; var list = allAttributes .Where(attr => attr.GetType().FullName == harmonyPatchName) .Select(attr => { var f_info = AccessTools.Field(attr.GetType(), nameof(HarmonyAttribute.info)); return(f_info.GetValue(attr)); }) .Select(harmonyInfo => AccessTools.MakeDeepCopy <HarmonyMethod>(harmonyInfo)) .ToList(); var info = HarmonyMethod.Merge(list); info.method = patch; return(new AttributePatch() { info = info, type = type }); }
internal static IEnumerable <AttributePatch> Create(MethodInfo patch, bool collectIncomplete = false) { if (patch is null) { throw new NullReferenceException("Patch method cannot be null"); } var allAttributes = patch.GetCustomAttributes(true); var methodName = patch.Name; var type = GetPatchType(methodName, allAttributes); if (type is null) { return(Enumerable.Empty <AttributePatch>()); } if (type != HarmonyPatchType.ReversePatch && patch.IsStatic is false) { throw new ArgumentException("Patch method " + patch.FullDescription() + " must be static"); } var list = allAttributes .Where(attr => attr.GetType().BaseType.FullName == harmonyAttributeName) .Select(attr => { var f_info = AccessTools.Field(attr.GetType(), nameof(HarmonyAttribute.info)); return(f_info.GetValue(attr)); }) .Select(harmonyInfo => AccessTools.MakeDeepCopy <HarmonyMethod>(harmonyInfo)) .ToList(); var completeMethods = new List <HarmonyMethod>();
static HarmonyArgument[] AllHarmonyArguments(object[] attributes) { return(attributes.Select(attr => { if (attr.GetType().Name != nameof(HarmonyArgument)) { return null; } return AccessTools.MakeDeepCopy <HarmonyArgument>(attr); }) .Where(harg => harg != null) .ToArray()); }
static HarmonyMethod GetHarmonyMethodInfo(object attribute) { var f_info = attribute.GetType().GetField(nameof(HarmonyAttribute.info), AccessTools.all); if (f_info == null) { return(null); } if (f_info.FieldType.FullName != typeof(HarmonyMethod).FullName) { return(null); } var info = f_info.GetValue(attribute); return(AccessTools.MakeDeepCopy <HarmonyMethod>(info)); }
internal static object ConvertInstruction(Type type, object instruction, out Dictionary<string, object> unassigned) { var nonExisting = new Dictionary<string, object>(); var elementTo = AccessTools.MakeDeepCopy(instruction, type, (namePath, trvSrc, trvDest) => { var value = trvSrc.GetValue(); if (trvDest.FieldExists() == false) { nonExisting[namePath] = value; return null; } if (namePath == nameof(CodeInstruction.opcode)) return ReplaceShortJumps((OpCode)value); return value; }); unassigned = nonExisting; return elementTo; }