Beispiel #1
0
        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();
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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);
            }
        }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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, "");
        }
Beispiel #8
0
        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);
            }
        }
Beispiel #9
0
        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;
            }
        }