Exemplo n.º 1
0
        // 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));
        }
Exemplo n.º 2
0
        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);
            }
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
 public Traverse(Traverse traverse)
 {
     this.traverse = traverse;
 }
Exemplo n.º 5
0
        /// <summary>Makes a deep copy of any object</summary>
        /// <param name="source">The original object</param>
        /// <param name="resultType">The type of the instance that should be created</param>
        /// <param name="processor">Optional value transformation function (taking a field name and src/dst traverse objects)</param>
        /// <param name="pathRoot">The optional path root to start with</param>
        /// <returns>The copy of the original object</returns>
        ///
        public static object MakeDeepCopy(object source, Type resultType, Func <string, Traverse, Traverse, object> processor = null, string pathRoot = "")
        {
            if (source == null)
            {
                return(null);
            }

            var type = source.GetType();

            if (type.IsPrimitive)
            {
                return(source);
            }

            if (type.IsEnum)
            {
                return(Enum.ToObject(resultType, (int)source));
            }

            if (type.IsGenericType && resultType.IsGenericType)
            {
                var addOperation = FirstMethod(resultType, m => m.Name == "Add" && m.GetParameters().Count() == 1);
                if (addOperation != null)
                {
                    var addableResult  = Activator.CreateInstance(resultType);
                    var addInvoker     = MethodInvoker.GetHandler(addOperation);
                    var newElementType = resultType.GetGenericArguments()[0];
                    var i = 0;
                    foreach (var element in source as IEnumerable)
                    {
                        var iStr       = (i++).ToString();
                        var path       = pathRoot.Length > 0 ? pathRoot + "." + iStr : iStr;
                        var newElement = MakeDeepCopy(element, newElementType, processor, path);
                        addInvoker(addableResult, new object[] { newElement });
                    }
                    return(addableResult);
                }

                // TODO: add dictionaries support
                // maybe use methods in Dictionary<KeyValuePair<TKey,TVal>>
            }

            if (type.IsArray && resultType.IsArray)
            {
                var elementType   = resultType.GetElementType();
                var length        = ((Array)source).Length;
                var arrayResult   = Activator.CreateInstance(resultType, new object[] { length }) as object[];
                var originalArray = source as object[];
                for (var i = 0; i < length; i++)
                {
                    var iStr = i.ToString();
                    var path = pathRoot.Length > 0 ? pathRoot + "." + iStr : iStr;
                    arrayResult[i] = MakeDeepCopy(originalArray[i], elementType, processor, path);
                }
                return(arrayResult);
            }

            var ns = type.Namespace;

            if (ns == "System" || (ns?.StartsWith("System.") ?? false))
            {
                return(source);
            }

            var result = CreateInstance(resultType);

            Traverse.IterateFields(source, result, (name, src, dst) =>
            {
                var path  = pathRoot.Length > 0 ? pathRoot + "." + name : name;
                var value = processor != null ? processor(path, src, dst) : src.GetValue();
                dst.SetValue(MakeDeepCopy(value, dst.GetValueType(), processor, path));
            });
            return(result);
        }
Exemplo n.º 6
0
 public Traverse(Traverse traverse)
 {
 }