private void WriteNode(Node node) { writer.WriteStartElement("node"); writer.WriteAttributeString("id", node.Name); foreach (var attribute in node.Attributes) { writer.WriteStartElement("attribute"); writer.WriteAttributeString("id", attribute.Key); writer.WriteAttributeString("value", attribute.Value.ToString()); writer.WriteAttributeString("type", ((int)attribute.Value.Type).ToString()); if (attribute.Value.Type == NodeAttribute.DataType.DT_TranslatedString) writer.WriteAttributeString("handle", ((TranslatedString)attribute.Value.Value).Handle); writer.WriteEndElement(); } if (node.ChildCount > 0) { writer.WriteStartElement("children"); foreach (var children in node.Children) { foreach (var child in children.Value) WriteNode(child); } writer.WriteEndElement(); } writer.WriteEndElement(); }
private void ReadNode(Node node) { UInt32 nodeNameId = reader.ReadUInt32(); UInt32 attributeCount = reader.ReadUInt32(); UInt32 childCount = reader.ReadUInt32(); node.Name = staticStrings[nodeNameId]; for (UInt32 i = 0; i < attributeCount; i++) { UInt32 attrNameId = reader.ReadUInt32(); UInt32 attrTypeId = reader.ReadUInt32(); if (attrTypeId > (int)NodeAttribute.DataType.DT_Max) throw new InvalidFormatException(String.Format("Unsupported attribute data type: {0}", attrTypeId)); node.Attributes[staticStrings[attrNameId]] = ReadAttribute((NodeAttribute.DataType)attrTypeId); } for (UInt32 i = 0; i < childCount; i++) { Node child = new Node(); child.Parent = node; ReadNode(child); node.AppendChild(child); } }
private static MemoryStream LoadStoryStreamFromSave(String path) { using (var packageReader = new PackageReader(path)) { Package package = packageReader.Read(); AbstractFileInfo globalsFile = package.Files.FirstOrDefault(p => p.Name.ToLowerInvariant() == "globals.lsf"); if (globalsFile == null) { throw new Exception("Could not find globals.lsf in savegame archive."); } Resource resource; Stream rsrcStream = globalsFile.MakeStream(); try { using (var rsrcReader = new LSFReader(rsrcStream)) { resource = rsrcReader.Read(); } } finally { globalsFile.ReleaseStream(); } LSLib.LS.Node storyNode = resource.Regions["Story"].Children["Story"][0]; var storyBlob = storyNode.Attributes["Story"].Value as byte[]; var storyStream = new MemoryStream(storyBlob); return(storyStream); } }
private void WriteNode(Node node) { writer.Write(staticStrings[node.Name]); writer.Write((UInt32)node.Attributes.Count); writer.Write((UInt32)node.ChildCount); foreach (var attribute in node.Attributes) { writer.Write(staticStrings[attribute.Key]); writer.Write((UInt32)attribute.Value.Type); WriteAttribute(attribute.Value); } foreach (var children in node.Children) { foreach (var child in children.Value) WriteNode(child); } }
private static List <Node> FindTranslatedStringInNode(LSLib.LS.Node node) { List <Node> nodes = new List <Node>(); foreach (var att in node.Attributes) { if (att.Value.Value is TranslatedString translatedString) { nodes.Add(node); break; } } if (node.ChildCount > 0) { foreach (var c in node.Children) { var extraNodes = FindTranslatedStringsInNodeList(c); nodes.AddRange(extraNodes); } } return(nodes); }
public void AppendChild(Node child) { List<Node> children; if (!Children.TryGetValue(child.Name, out children)) { children = new List<Node>(); Children.Add(child.Name, children); } children.Add(child); }
private void RunTasks() { if (ExtractAll) { DoExtractPackage(); } if (ConvertToLsx) { DoLsxConversion(); } FileManager.TryToCreateDirectory(Path.Combine(DataDumpPath, "Dummy")); ReportProgress(50, "Loading meta.lsf ..."); SaveMeta = LoadPackagedResource("meta.lsf"); ReportProgress(52, "Loading globals.lsf ..."); SaveGlobals = LoadPackagedResource("globals.lsf"); ReportProgress(60, "Dumping mod list ..."); if (DumpModList) { var modListPath = Path.Combine(DataDumpPath, "ModList.txt"); DumpMods(modListPath); } ReportProgress(62, "Dumping variables ..."); if (DumpGlobalVars) { var varsPath = Path.Combine(DataDumpPath, "GlobalVars.txt"); DumpVariables(varsPath, true, false, false); } if (DumpCharacterVars) { var varsPath = Path.Combine(DataDumpPath, "CharacterVars.txt"); DumpVariables(varsPath, false, true, false); } if (DumpItemVars) { var varsPath = Path.Combine(DataDumpPath, "ItemVars.txt"); DumpVariables(varsPath, false, false, true); } ReportProgress(70, "Loading story ..."); LSLib.LS.Node storyNode = SaveGlobals.Regions["Story"].Children["Story"][0]; var storyStream = new MemoryStream(storyNode.Attributes["Story"].Value as byte[]); var reader = new StoryReader(); SaveStory = reader.Read(storyStream); if (DumpStoryGoals) { DumpGoals(); } if (DumpStoryDatabases) { ReportProgress(90, "Dumping databases ..."); var dbDumpPath = Path.Combine(DataDumpPath, "Databases.txt"); using (var dbDumpStream = new FileStream(dbDumpPath, FileMode.Create, FileAccess.Write, FileShare.Read)) { var dbDumper = new DatabaseDumper(dbDumpStream); dbDumper.DumpUnnamedDbs = IncludeUnnamedDatabases; dbDumper.DumpAll(SaveStory); } } ReportProgress(100, ""); }
private void CollectStaticStrings(Node node) { AddStaticString(node.Name); foreach (var attr in node.Attributes) { AddStaticString(attr.Key); } foreach (var children in node.Children) { foreach (var child in children.Value) CollectStaticStrings(child); } }
public Resource Read() { using (this.reader = XmlReader.Create(stream)) { Resource rsrc = new Resource(); Region currentRegion = null; List<Node> stack = new List<Node>(); while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { switch (reader.Name) { case "save": // Root element if (stack.Count() > 0) throw new InvalidFormatException("Node <save> was unexpected."); break; case "header": // LSX metadata part 1 string version = reader["version"]; if (version != InitialVersion && version != CurrentVersion) throw new InvalidFormatException(String.Format("Unsupported LSX version; expected {0}, found {1}", CurrentVersion, version)); rsrc.Metadata.timestamp = Convert.ToUInt64(reader["timestamp"]); break; case "version": // LSX metadata part 2 rsrc.Metadata.majorVersion = Convert.ToUInt32(reader["major"]); rsrc.Metadata.minorVersion = Convert.ToUInt32(reader["minor"]); rsrc.Metadata.revision = Convert.ToUInt32(reader["revision"]); rsrc.Metadata.buildNumber = Convert.ToUInt32(reader["build"]); break; case "region": if (currentRegion != null) throw new InvalidFormatException("A <region> can only start at the root level of a resource."); Debug.Assert(!reader.IsEmptyElement); var region = new Region(); region.RegionName = reader["id"]; Debug.Assert(region.RegionName != null); rsrc.Regions.Add(region.RegionName, region); currentRegion = region; break; case "node": if (currentRegion == null) throw new InvalidFormatException("A <node> must be located inside a region."); Node node; if (stack.Count() == 0) { // The node is the root node of the region node = currentRegion; } else { // New node under the current parent node = new Node(); node.Parent = stack.Last(); } node.Name = reader["id"]; Debug.Assert(node.Name != null); if (node.Parent != null) node.Parent.AppendChild(node); if (!reader.IsEmptyElement) stack.Add(node); break; case "attribute": var attrTypeId = Convert.ToUInt32(reader["type"]); var attrName = reader["id"]; var attrValue = reader["value"]; if (attrTypeId > (int)NodeAttribute.DataType.DT_Max) throw new InvalidFormatException(String.Format("Unsupported attribute data type: {0}", attrTypeId)); Debug.Assert(attrName != null); Debug.Assert(attrValue != null); var attr = new NodeAttribute((NodeAttribute.DataType)attrTypeId); attr.FromString(attrValue); if (attr.Type == NodeAttribute.DataType.DT_TranslatedString) { ((TranslatedString)attr.Value).Handle = reader["handle"]; Debug.Assert(((TranslatedString)attr.Value).Handle != null); } stack.Last().Attributes.Add(attrName, attr); break; case "children": // Child nodes are handled in the "node" case break; default: throw new InvalidFormatException(String.Format("Unknown element encountered: {0}", reader.Name)); } } else if (reader.NodeType == XmlNodeType.EndElement) { switch (reader.Name) { case "save": case "header": case "version": case "attribute": case "children": // These elements don't change the stack, just discard them break; case "region": Debug.Assert(stack.Count == 0); Debug.Assert(currentRegion != null); Debug.Assert(currentRegion.Name != null); currentRegion = null; break; case "node": stack.RemoveAt(stack.Count - 1); break; default: throw new InvalidFormatException(String.Format("Unknown element encountered: {0}", reader.Name)); } } } return rsrc; } }