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); } }
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); } } } } }
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); } }
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); } } }
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); } }
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); }