// Get all named value properties
 public static List <string> Names(this P.Properties props)
 {
     return(props
            .Where(prop => (prop is P.ValueProperty) && !str.IsNullOrEmpty((prop as P.ValueProperty).Name))
            .Select(prop => {
         P.ValueProperty val = prop as P.ValueProperty;
         string s = val.Name.ToString();
         if (val.Index != 0)
         {
             s += "#" + val.Index;
         }
         return s;
     })
            .ToList()
            );
 }
        internal P.Property _FindMatchByName(P.Property left, P.Properties right_coll)
        {
            string name = left.GetName();

            if (!string.IsNullOrEmpty(name))
            {
                foreach (P.Property right in right_coll)
                {
                    if (right.GetName() == name)
                    {
                        return(right);
                    }
                }
            }

            return(null);
        }
        public static P.Property FindByPathName(this P.Properties props, string pathname, bool case_insensitive = false)
        {
            if (case_insensitive)
            {
                string _pathname = pathname.ToLower();
                return(props.Find(prop => {
                    return ((prop is P.Object) && (prop as P.Object).PathName.ToString().ToLower() == _pathname) ||
                    ((prop is P.Actor) && (prop as P.Actor).PathName.ToString().ToLower() == _pathname)
                    ;
                }));
            }

            return(props.Find(prop => {
                return ((prop is P.Object) && (prop as P.Object).PathName.ToString() == pathname) ||
                ((prop is P.Actor) && (prop as P.Actor).PathName.ToString() == pathname)
                ;
            }));
        }
        // Find name of value instance passed, or null if not found
        public static string FindName(this P.Properties props, object value)
        {
            string name = null;

            foreach (P.Property prop in props)
            {
                if (prop is P.ValueProperty && prop == value)
                {
                    P.ValueProperty v = (prop as P.ValueProperty);
                    if (!str.IsNullOrEmpty(v.Name))
                    {
                        name = v.Name.ToString();
                    }
                    break;
                }
            }
            return(null);
        }
        internal P.Property _FindMatchByPath(P.Property left, P.Properties right_coll)
        {
            string left_pathname = left.GetPathName();

            if (!string.IsNullOrEmpty(left_pathname))
            {
                foreach (P.Property right in right_coll)
                {
                    string right_pathname = right.GetPathName();
                    if (left_pathname.Equals(right_pathname))
                    {
                        return(right);
                    }
                }
            }

            return(null);
        }
        // Find a value property by name
        public static P.Property Named(this P.Properties props, string name, int index = -1)
        {
            if (index < 0)
            {
                int pos = name.IndexOf('#');
                if (pos > 0)
                {
                    string idx = name.Substring(pos + 1);
                    name = name.Substring(0, pos);
                    if (!int.TryParse(idx, out index))
                    {
                        return(null);
                    }
                }
            }
            if (index >= 0)
            {
                return(props.FirstOrDefault(prop => {
                    if (prop is P.ValueProperty)
                    {
                        P.ValueProperty val = prop as P.ValueProperty;
                        str prop_name = val.Name;
                        if (!str.IsNullOrEmpty(prop_name))
                        {
                            return (val.Index == index) && (prop_name.ToString() == name);
                        }
                    }
                    return false;
                }));
            }

            return(props.FirstOrDefault(prop => {
                if (prop is P.ValueProperty)
                {
                    str prop_name = (prop as P.ValueProperty).Name;
                    if (!str.IsNullOrEmpty(prop_name))
                    {
                        return prop_name.ToString() == name;
                    }
                }
                return false;
            }));
        }
        internal P.Property _FindMatch(P.Property left, P.Properties right_coll)
        {
            if (!string.IsNullOrEmpty(left.GetName()))
            {
                return(_FindMatchByName(left, right_coll));
            }

            if (!string.IsNullOrEmpty(left.GetPathName()))
            {
                return(_FindMatchByPath(left, right_coll));
            }

            if (right_coll.Count > 0)
            {
                return(right_coll.First());
            }

            return(null);
        }
 // Find a property by it's path name
 public static P.Property FindByPathName(this P.Properties props, str pathname, bool case_insensitive = false)
 {
     return(props.FindByPathName(pathname.ToString(), case_insensitive));
 }
Пример #9
0
        private void _Process(P.Property prop)
        {
            //-> [Actor] Persistent_Level:PersistentLevel.Char_Player_C_0
            //  .ClassName = str:'/Game/FactoryGame/Character/Player/Char_Player.Char_Player_C'
            //  .PathName = str:'Persistent_Level:PersistentLevel.Char_Player_C_0'
            //  .EntityObj =
            //	-> [NamedEntity]
            //	  .Children =
            //		/ List with 5 elements:
            //		|-> [Name]
            //		|  .LevelName = str:'Persistent_Level'
            //		|  .PathName = str:'Persistent_Level:PersistentLevel.Char_Player_C_0.TrashSlot'
            //		|  ...
            //		|-> [Name]
            //		|  .LevelName = str:'Persistent_Level'
            //		|  .PathName = str:'Persistent_Level:PersistentLevel.Char_Player_C_0.inventory'
            //		\ end of list

            P.Actor actor = prop as P.Actor;
            if (actor == null)
            {
                return;
            }

            if (str.IsNullOrEmpty(actor.ClassName))
            {
                return;
            }
            string actor_class = actor.ClassName.ToString();

            P.NamedEntity entity = actor.EntityObj as P.NamedEntity;
            if (entity == null)
            {
                return;
            }

            var childs = entity.GetChilds();

            if (!childs.ContainsKey("Children"))
            {
                return;
            }

            P.Properties props = childs["Children"] as P.Properties;
            if (props == null || props.Count == 0)
            {
                return;
            }

            List <P.NamedEntity.Name> names = props.ListOf <P.NamedEntity.Name>();

            foreach (P.NamedEntity.Name name in names)
            {
                string pathname = "";
                if (!str.IsNullOrEmpty(name.PathName))
                {
                    pathname = name.PathName.LastName();
                }

                List <string> classes;
                if (!_classes.ContainsKey(pathname))
                {
                    classes = new List <string>();
                    _classes.Add(pathname, classes);
                }
                else
                {
                    classes = _classes[pathname];
                }
                if (!classes.Contains(actor_class))
                {
                    classes.Add(actor_class);
                }
            }
        }
        internal D.DifferenceNode _CompareObject(object left, object right)
        {
            Func <bool, D.DifferenceNode> state = (b) => {
                return(b ? null : new D.DifferenceNode(null, left, right));
            };

            if (left == null || right == null)
            {
                return(state(left == right));
            }
            if (!left.GetType().Equals(right.GetType()))
            {
                return(state(false));
            }

            if (left is byte)
            {
                return(state(((int)(byte)left - (int)(byte)right) == 0));
            }
            if (left is int)
            {
                return(state(((int)left - (int)right) == 0));
            }
            if (left is long)
            {
                return(state(((long)left - (long)right) == 0));
            }
            if (left is float)
            {
                return(state(((float)left - (float)right).IsNearZero(1e-5f)));
            }
            //if (left is double)
            //	return state(((double)left - (double)right).IsNearZero(1e-5));
            if (left is string)
            {
                return(state(((string)left).CompareTo((string)right) == 0));
            }

            if (left is F.str)
            {
                string left_str  = (left  as F.str).ToString();
                string right_str = (right as F.str).ToString();
                return(state(left_str.CompareTo(right_str) == 0));
            }

            if (left is P.Properties)
            {
                D.DifferenceNode node = new D.DifferenceNode(null, left, right);
                D.DifferenceNode sub;

                Func <P.Properties, P.Properties> clone = (src) => {
                    P.Properties dst = new P.Properties();
                    foreach (P.Property prop in src)
                    {
                        dst.Add(prop);
                    }
                    return(dst);
                };
                P.Properties left_coll  = clone(left as P.Properties);
                P.Properties right_coll = clone(right as P.Properties);

                for (int index = 0; index < left_coll.Count; ++index)
                {
                    P.Property left_sub  = left_coll[index];
                    P.Property right_sub = _FindMatch(left_sub, right_coll);
                    if (right_sub != null)
                    {
                        right_coll.Remove(right_sub);
                    }

                    sub = _Compare(left_sub, right_sub);
                    if (sub != null)
                    {
                        string title = left_sub.PrettyName();
                        if (string.IsNullOrEmpty(title))
                        {
                            title = index.ToString();
                        }
                        sub.Title = title;
                        node.Add(sub);
                    }
                }
                for (int index = 0; index < right_coll.Count; ++index)
                {
                    P.Property right_sub = right_coll[index];
                    if (right_sub != null)
                    {
                        string name = right_sub.GetName();
                        if (_blacklisted.Contains(name))
                        {
                            continue;
                        }

                        string title = right_sub.PrettyName();
                        if (string.IsNullOrEmpty(title))
                        {
                            title = index.ToString();
                        }
                        node.Add(title, null, right_sub);
                    }
                }

                return(node.ChildCount > 0 ? node : null);
            }

            if (left is IDictionary)
            {
                D.DifferenceNode node = new D.DifferenceNode(null, left, right);
                D.DifferenceNode sub;

                Func <IDictionary, IDictionary> clone = (src) => {
                    Dictionary <object, object> dst = new Dictionary <object, object>();
                    foreach (object key in src.Keys)
                    {
                        dst.Add(key, src[key]);
                    }
                    return(dst);
                };
                IDictionary left_coll  = clone(left as IDictionary);
                IDictionary right_coll = clone(right as IDictionary);

                foreach (object key in left_coll.Keys)
                {
                    object left_sub  = left_coll[key];
                    object right_sub = null;
                    if (right_coll.Contains(key))
                    {
                        right_sub = right_coll[key];
                        right_coll.Remove(key);
                    }

                    if (right_sub == null && left_sub != null)
                    {
                        sub = new D.DifferenceNode(null, left_sub, null);
                    }
                    else if (left_sub is P.Property)
                    {
                        sub = _Compare(left_sub as P.Property, right_sub as P.Property);
                    }
                    else
                    {
                        sub = _CompareObject(left_sub, right_sub);
                    }
                    if (sub != null)
                    {
                        sub.Title = key.ToString();
                        node.Add(sub);
                    }
                }
                foreach (object key in right_coll)
                {
                    node.Add(key.ToString(), null, right_coll[key]);
                }

                return(node.ChildCount > 0 ? node : null);
            }

            if (left is ICollection)
            {
                D.DifferenceNode node = new D.DifferenceNode(null, left, right);
                D.DifferenceNode sub;

                Func <ICollection, List <object> > clone = (src) => {
                    List <object> dst = new List <object>();
                    foreach (object val in src)
                    {
                        dst.Add(val);
                    }
                    return(dst);
                };
                List <object> left_coll  = clone(left as ICollection);
                List <object> right_coll = clone(right as ICollection);

                for (int index = 0; index < left_coll.Count; ++index)
                {
                    object left_sub  = left_coll[index];
                    object right_sub = null;
                    if (index < right_coll.Count)
                    {
                        right_sub         = right_coll[index];
                        right_coll[index] = null;
                    }

                    if (right_sub == null && left_sub != null)
                    {
                        sub = new D.DifferenceNode(null, left_sub, null);
                    }
                    else if (left_sub is P.Property)
                    {
                        sub = _Compare(left_sub as P.Property, right_sub as P.Property);
                    }
                    else
                    {
                        sub = _CompareObject(left_sub, right_sub);
                    }
                    if (sub != null)
                    {
                        string title = left_sub.PrettyName();
                        if (string.IsNullOrEmpty(title))
                        {
                            title = index.ToString();
                        }
                        sub.Title = title;
                        node.Add(sub);
                    }
                }
                for (int index = 0; index < right_coll.Count; ++index)
                {
                    object right_sub = right_coll[index];
                    if (right_sub != null)
                    {
                        string title = right_sub.PrettyName();
                        if (string.IsNullOrEmpty(title))
                        {
                            title = index.ToString();
                        }
                        node.Add(title, null, right_sub);
                    }
                }

                return(node.ChildCount > 0 ? node : null);
            }

            return(null);
        }
        internal bool _CompareAll()
        {
            int total = _left_save.TotalElements + _right_save.TotalElements;

            Log.Info("Comparing a ~{0} elements ...", total);
            _cbStart(total, Translate._("Action.Compare.Progress"), "");

            D.DifferenceNode        node;
            D.DifferenceNode        sub;
            List <D.DifferenceNode> nodes = new List <D.DifferenceNode>();
            int differences = 0;

            Func <P.Properties, P.Properties> clone = (src) => {
                P.Properties dst = new P.Properties();
                foreach (P.Property prop in src)
                {
                    dst.Add(prop);
                }
                return(dst);
            };


            node = _Compare(_left_save.Header, _right_save.Header);
            if (node != null)
            {
                node.Title = "Header";
                _differences.Add(node);
                ++differences;
            }


            P.Properties left_objects  = clone(_left_save.Objects);
            P.Properties right_objects = clone(_right_save.Objects);
            while (left_objects.Count > 0)
            {
                P.Property left = left_objects[0];
                left_objects.RemoveAt(0);

                _cbUpdate(null, left.ToString());

                P.Property right = _FindMatchByPath(left, right_objects);
                if (right == null)
                {
                    sub = new D.DifferenceNode(left.ToString(), left, null);
                }
                else
                {
                    right_objects.Remove(right);
                    sub = _Compare(left, right);
                }
                if (sub != null)
                {
                    sub.Title = left.ToString();
                    nodes.Add(sub);
                }
            }
            foreach (P.Property right in right_objects)
            {
                nodes.Add(new D.DifferenceNode(right.ToString(), null, right));
            }
            if (nodes.Count > 0)
            {
                differences += nodes.Count;
                foreach (D.DifferenceNode child in nodes)
                {
                    AddDifference(child);
                }
                nodes.Clear();
            }


            P.Properties left_coll  = clone(_left_save.Collected);
            P.Properties right_coll = clone(_right_save.Collected);
            while (left_coll.Count > 0)
            {
                P.Property left = left_coll[0];
                left_coll.RemoveAt(0);

                _cbUpdate(null, left.ToString());

                P.Property right = _FindMatchByPath(left, right_coll);
                if (right == null)
                {
                    sub = new D.DifferenceNode(left.ToString(), left, null);
                }
                else
                {
                    right_coll.Remove(right);
                    sub = _Compare(left, right);
                }
                if (sub != null)
                {
                    sub.Title = left.ToString();
                    nodes.Add(sub);
                }
            }
            foreach (P.Property right in right_coll)
            {
                nodes.Add(new D.DifferenceNode(right.ToString(), null, right));
            }
            if (nodes.Count > 0)
            {
                differences += nodes.Count;
                foreach (D.DifferenceNode child in nodes)
                {
                    AddDifference(child);
                }
            }


            //if (_left_save.Missing != null && _left_save.Missing.Length > 0)
            //{
            //	//...
            //}


            _cbStop(Translate._("Action.Done"), "");
            Log.Info("... done comparing, differences={0}", differences);

            return(differences == 0);
        }