Exemplo n.º 1
0
 protected void _RecursExecuter(Difference.DifferenceNode node, Action <Difference.DifferenceNode> action)
 {
     foreach (Difference.DifferenceNode child in node.Children)
     {
         _RecursExecuter(child, action);
     }
     action(node);
 }
Exemplo n.º 2
0
        public DifferenceModel(Savegame.Savegame left, Savegame.Savegame right)
        {
            Root          = new DifferenceNode(@"\", "", "");
            LeftSavegame  = left;
            RightSavegame = right;

            Root.IsExpanded = true;
        }
 private D.DifferenceNode _AddOrGetClass(D.DifferenceNode parent, string fullname, string classname)
 {
     if (_classes.ContainsKey(fullname))
     {
         return(_classes[fullname]);
     }
     D.DifferenceNode class_item = new D.DifferenceNode(classname, "", "");
     if (parent == null)
     {
         _differences.Root.Add(class_item);
     }
     else
     {
         _AddSorted(parent, class_item);
     }
     _classes.Add(fullname, class_item);
     return(class_item);
 }
        public void AddDifference(D.DifferenceNode node)
        {
            P.Property prop = ((node.Left != null) ? node.Left : node.Right) as P.Property;
            if (prop != null)
            {
                string           label      = null;
                D.DifferenceNode class_node = _AddClassRecurs(null, "/", prop, out label);
                if (class_node != null)
                {
                    if (!string.IsNullOrEmpty(label))
                    {
                        node.Title = label;
                    }
                    _AddSorted(class_node, node);
                    return;
                }
            }

            _differences.Add(node);
        }
        private void _AddSorted(D.DifferenceNode dest, D.DifferenceNode node)
        {
            int index = 0;

            while (index < dest.Children.Count)
            {
                if ((dest.Children[index] as D.DifferenceNode).Title.CompareTo(node.Title) > 0)
                {
                    break;
                }
                ++index;
            }

            if (index < dest.Children.Count)
            {
                dest.Children.Insert(index, node);
            }
            else
            {
                dest.Children.Add(node);
            }
        }
Exemplo n.º 6
0
 public DifferenceNode Add(DifferenceNode node)
 {
     Children.Add(node);
     return(node);
 }
Exemplo n.º 7
0
 public DifferenceNode Add(DifferenceNode node)
 {
     Root.Add(node);
     return(node);
 }
        //HINT: Methods following are copied from TreePanel.cs, ensure to update those if TreePanel.cs changes!
        private D.DifferenceNode _AddClassRecurs(D.DifferenceNode parent, string path, P.Property prop, out string out_title)
        {
            string classname, fullname, label;

            D.DifferenceNode class_item;

            string ClassName, PathName;

            if (prop is P.Actor)
            {
                P.Actor actor = prop as P.Actor;
                ClassName = actor.ClassName.ToString();
                PathName  = actor.PathName.ToString();
            }
            else if (prop is P.Object)
            {
                P.Object obj = prop as P.Object;
                ClassName = obj.ClassName.ToString();
                PathName  = obj.PathName.ToString();
            }
            else
            {
                out_title = null;
                return(null);
            }

            string remain = ClassName.Substring(path.Length);

            if (remain.Contains('/'))
            {
                classname  = remain.Split('/')[0];
                fullname   = path + classname + "/";
                class_item = _AddOrGetClass(parent, fullname, classname);
                return(_AddClassRecurs(class_item, fullname, prop, out out_title));
            }
            if (remain.Contains('.'))
            {
                string[] classnames = remain.Split('.');
                if (classnames.Length == 2)
                {
                    label = PathName;
                    label = label.Substring(label.LastIndexOf('.') + 1);

                    // Before adding more sub-classes, check for both BP_... and FG... condition
                    if ("BP_" + label != classnames[0] && "FG_" + label != classnames[0])
                    {
                        fullname   = path + classnames[0] + ".";
                        class_item = _AddOrGetClass(parent, fullname, classnames[0]);

                        // Ignore [1] or add both?
                        if (classnames[0] + "_C" != classnames[1])
                        {
                            fullname  += classnames[1];
                            class_item = _AddOrGetClass(class_item, fullname, classnames[1]);
                        }

                        // To collect things following into a sub node ('BP_PlayerState_C_0' with data below):
                        //		.PathName = str:'Persistent_Level:PersistentLevel.BP_PlayerState_C_0.FGRecipeShortcut_#'
                        // with # = [0,9]
                        // Or following ('Char_Player_C_0' with data below):
                        //		.PathName = str:'Persistent_Level:PersistentLevel.Char_Player_C_0.BackSlot'
                        //		.PathName = str:'Persistent_Level:PersistentLevel.Char_Player_C_0.ArmSlot'
                        // Will also take care of showing actual entity in case we're showing
                        // something like an inventory:
                        //		.PathName = str:'Persistent_Level:PersistentLevel.Char_Player_C_0.inventory'
                        string[] labels = PathName.Split('.');
                        if (labels.Length == 3)
                        {
                            fullname  += "." + labels[1];
                            class_item = _AddOrGetClass(class_item, fullname, labels[1]);
                        }
                    }
                    else
                    {
                        class_item = parent;
                    }

                    //return _AddItem(class_item, label, null, null);
                    out_title = label;
                    return(class_item);
                }
                Log.Warning("AddClassRecurs: What to do with '{0}'?", ClassName);
            }

            // At the end of our path, add property
            label = PathName;
            label = label.Substring(label.IndexOf('.') + 1);
            //return _AddItem(parent, label, null, null);
            out_title = label;
            return(parent);
        }
        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 D.DifferenceNode _Compare(P.Property left, P.Property right)
        {
            D.DifferenceNode node = new D.DifferenceNode(left.ToString(), left, right);
            D.DifferenceNode sub;

            if ((left == null || right == null) && (left != right))
            {
                return(node);
            }

            // Do some by-name blacklisting to skips things like delta timestamps
            if (left is P.ValueProperty)
            {
                P.ValueProperty val_prop = left as P.ValueProperty;
                if (val_prop.Name != null)
                {
                    string name = val_prop.Name.ToString();
                    if (_blacklisted.Contains(name))
                    {
                        return(null);
                    }
                }
            }

            Dictionary <string, object> left_childs  = new Dictionary <string, object>(left.GetChilds());
            Dictionary <string, object> right_childs = new Dictionary <string, object>(right.GetChilds());

            while (left_childs.Count > 0)
            {
                var pair = left_childs.First();

                object left_sub = pair.Value;
                left_childs.Remove(pair.Key);

                object right_sub = null;
                if (right_childs.ContainsKey(pair.Key))
                {
                    right_sub = right_childs[pair.Key];
                    right_childs.Remove(pair.Key);
                }

                if (_blacklisted.Contains(pair.Key))
                {
                    continue;
                }

                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 = pair.Key;
                    node.Add(sub);
                }
            }

            foreach (var pair in right_childs)
            {
                if (!_blacklisted.Contains(pair.Key))
                {
                    node.Add(pair.Key, null, pair.Value);
                }
            }

            return((node.ChildCount > 0) ? node : 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);
        }