public static void WriteNodes(Stream output, IEnumerable <BaseNode> nodes, ILogger logger)
        {
            Contract.Requires(output != null);
            Contract.Requires(nodes != null);
            Contract.Requires(Contract.ForAll(nodes, n => n != null));
            Contract.Requires(logger != null);

            using (var project = new ReClassNetProject())
            {
                Action <BaseReferenceNode> recursiveAddReferences = null;
                recursiveAddReferences = delegate(BaseReferenceNode referenceNode)
                {
                    if (project.ContainsClass(referenceNode.InnerNode.Uuid))
                    {
                        return;
                    }

                    project.AddClass(referenceNode.InnerNode);

                    foreach (var reference in referenceNode.InnerNode.Nodes.OfType <BaseReferenceNode>())
                    {
                        recursiveAddReferences(reference);
                    }
                };

                var serialisationClass = new ClassNode(false)
                {
                    Name = SerialisationClassName
                };

                project.AddClass(serialisationClass);

                foreach (var node in nodes)
                {
                    var classNode = node as ClassNode;
                    if (classNode != null)
                    {
                        project.AddClass(classNode);

                        continue;
                    }

                    var referenceNode = node as BaseReferenceNode;
                    if (referenceNode != null)
                    {
                        recursiveAddReferences(referenceNode);
                    }

                    serialisationClass.AddNode(node);
                }

                var file = new ReClassNetFile(project);
                file.Save(output, logger);
            }
        }
Esempio n. 2
0
        private void PasteNodeFromClipboardToSelection()
        {
            var result = ReClassClipboard.Paste(project, Program.Logger);

            foreach (var classNode in result.Item1)
            {
                if (!project.ContainsClass(classNode.Uuid))
                {
                    project.AddClass(classNode);
                }
            }

            if (selectedNodes.Count == 1)
            {
                var selectedNode = selectedNodes.First().Node;
                var parent       = selectedNode.ParentNode as ClassNode;
                if (parent != null)
                {
                    foreach (var node in result.Item2)
                    {
                        if (IsCycleFree(parent, node))
                        {
                            parent.InsertNode(selectedNode, node);
                        }
                    }
                }
            }
        }
Esempio n. 3
0
        public void Load(string filePath, ILogger logger)
        {
            var document = XDocument.Load(filePath);

            var classes = new List <Tuple <XElement, ClassNode> >();

            foreach (var element in document.Root
                     .Elements("Namespace")
                     .SelectMany(ns => ns.Elements("Class"))
                     .DistinctBy(e => e.Attribute("ClassId")?.Value))
            {
                var node = new ClassNode(false)
                {
                    Name           = element.Attribute("Name")?.Value ?? string.Empty,
                    AddressFormula = ParseAddressString(element)
                };

                project.AddClass(node);

                classes.Add(Tuple.Create(element, node));
            }

            var classMap = classes.ToDictionary(c => c.Item1.Attribute("ClassId")?.Value, c => c.Item2);

            foreach (var t in classes)
            {
                ReadNodeElements(
                    t.Item1.Elements("Node"),
                    t.Item2,
                    classMap,
                    logger
                    ).ForEach(t.Item2.AddNode);
            }
        }
Esempio n. 4
0
        public void Load(string filePath, ILogger logger)
        {
            using (var connection = new SQLiteConnection($@"Data Source={filePath}"))
            {
                connection.Open();

                var classes = new Dictionary <int, ClassNode>();
                var vtables = new Dictionary <int, VTableNode>();

                foreach (var row in Query(connection, "SELECT tbl_name FROM sqlite_master WHERE tbl_name LIKE 'class%'"))
                {
                    var id = Convert.ToInt32(row["tbl_name"].ToString().Substring(5));

                    var classRow = Query(connection, $"SELECT variable, comment FROM class{id} WHERE type = 2 LIMIT 1").FirstOrDefault();
                    if (classRow == null)
                    {
                        continue;
                    }

                    // Skip the vtable classes.
                    if (classRow["variable"].ToString() == "VTABLE")
                    {
                        var vtableNode = new VTableNode();

                        Query(connection, $"SELECT variable, comment FROM class{id} WHERE type = 16")
                        .Select(e => new VMethodNode
                        {
                            Name    = Convert.ToString(e["variable"]) ?? string.Empty,
                            Comment = Convert.ToString(e["comment"]) ?? string.Empty
                        })
                        .ForEach(vtableNode.AddNode);

                        foreach (var method in vtableNode.Nodes)
                        {
                            if (method.Name == "void function()")
                            {
                                method.Name = string.Empty;
                            }
                        }

                        vtables.Add(id, vtableNode);

                        continue;
                    }

                    var node = new ClassNode(false)
                    {
                        Name    = classRow["variable"].ToString(),
                        Comment = classRow["comment"].ToString()
                    };

                    project.AddClass(node);

                    classes.Add(id, node);
                }

                foreach (var kv in classes)
                {
                    ReadNodeRows(
                        Query(connection, $"SELECT variable, comment, type, length, ref FROM class{kv.Key} WHERE type != 2"),
                        kv.Value,
                        classes,
                        vtables,
                        logger
                        ).ForEach(kv.Value.AddNode);
                }
            }
        }
Esempio n. 5
0
        public void Load(string filePath, ILogger logger)
        {
            var document = XDocument.Load(filePath);

            if (document.Root == null)
            {
                return;
            }

            Type[] typeMap = null;

            if (document.Root.FirstNode is XComment versionComment)
            {
                switch (versionComment.Value.Substring(0, 12).ToLower())
                {
                case "reclass 2011":
                case "reclass 2013":
                    typeMap = typeMap2013;
                    break;

                case "reclass 2015":
                case "reclass 2016":
                    typeMap = typeMap2016;
                    break;

                default:
                    logger.Log(LogLevel.Warning, $"Unknown file version: {versionComment.Value}");
                    logger.Log(LogLevel.Warning, "Defaulting to ReClass 2016.");

                    typeMap = typeMap2016;
                    break;
                }
            }

            var classes = new List <Tuple <XElement, ClassNode> >();

            foreach (var element in document.Root
                     .Elements("Class")
                     .DistinctBy(e => e.Attribute("Name")?.Value))
            {
                var node = new ClassNode(false)
                {
                    Name           = element.Attribute("Name")?.Value ?? string.Empty,
                    AddressFormula = TransformAddressString(element.Attribute("strOffset")?.Value ?? string.Empty)
                };

                project.AddClass(node);

                classes.Add(Tuple.Create(element, node));
            }

            var classMap = classes.ToDictionary(t => t.Item2.Name, t => t.Item2);

            foreach (var(classElement, classNode) in classes)
            {
                ReadNodeElements(
                    classElement.Elements("Node"),
                    classNode,
                    classMap,
                    typeMap,
                    logger
                    ).ForEach(classNode.AddNode);
            }
        }
Esempio n. 6
0
        public static void SerializeNodesToStream(Stream output, IEnumerable <BaseNode> nodes, ILogger logger)
        {
            Contract.Requires(output != null);
            Contract.Requires(nodes != null);
            Contract.Requires(Contract.ForAll(nodes, n => n != null));
            Contract.Requires(logger != null);

            using var project = new ReClassNetProject();

            void RecursiveAddClasses(BaseNode node)
            {
                ClassNode classNode = null;

                switch (node)
                {
                case ClassNode c1:
                    classNode = c1;
                    break;

                case BaseWrapperNode wrapperNode when wrapperNode.ResolveMostInnerNode() is ClassNode c2:
                    classNode = c2;

                    break;
                }

                if (classNode == null || project.ContainsClass(classNode.Uuid))
                {
                    return;
                }

                project.AddClass(classNode);

                foreach (var wrapperNodeChild in classNode.Nodes.OfType <BaseWrapperNode>())
                {
                    RecursiveAddClasses(wrapperNodeChild);
                }
            }

            var serialisationClass = new ClassNode(false)
            {
                Name = SerializationClassName
            };

            var needsSerialisationClass = true;

            foreach (var node in nodes)
            {
                RecursiveAddClasses(node);

                if (!(node is ClassNode))
                {
                    if (needsSerialisationClass)
                    {
                        needsSerialisationClass = false;

                        project.AddClass(serialisationClass);
                    }

                    serialisationClass.AddNode(node);
                }
            }

            var file = new ReClassNetFile(project);

            file.Save(output, logger);
        }