// general sorting by (in that order): before, after, priority and index public static int PriorityComparer(object obj, int index, int priority, string[] before, string[] after) { var trv = Traverse.Create(obj); var theirOwner = trv.Field("owner").GetValue <string>(); var theirPriority = trv.Field("priority").GetValue <int>(); var theirIndex = trv.Field("index").GetValue <int>(); if (before != null && Array.IndexOf(before, theirOwner) > -1) { return(-1); } if (after != null && Array.IndexOf(after, theirOwner) > -1) { return(1); } if (priority != theirPriority) { return(-(priority.CompareTo(theirPriority))); } return(index.CompareTo(theirIndex)); }
public static IEnumerable <CodeInstruction> ConvertToOurInstructions(IEnumerable instructions, List <object> originalInstructions, Dictionary <object, Dictionary <string, object> > unassignedValues) { var result = new List <CodeInstruction>(); var newInstructions = instructions.Cast <object>().ToList(); var index = -1; foreach (var op in newInstructions) { index++; var elementTo = new CodeInstruction(OpCodes.Nop, null); Traverse.IterateFields(op, elementTo, (name, trvFrom, trvDest) => { var val = trvFrom.GetValue(); if (name == nameof(ILInstruction.blocks)) { val = ConvertBlocks(val, trvDest.GetValueType()); } trvDest.SetValue(val); }); 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); } }
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); }