Пример #1
0
        public void Write(Stream stream, Story story)
        {
            using (Writer = new OsiWriter(stream))
            {
                Writer.MajorVersion = story.MajorVersion;
                Writer.MinorVersion = story.MinorVersion;

                var header = new OsirisHeader();
                header.Version = "Osiris save file dd. 02/10/15 12:44:13. Version 1.5.";
                header.MajorVersion = story.MajorVersion;
                header.MinorVersion = story.MinorVersion;
                header.BigEndian = false;
                header.Unused = 0;
                // Debug flags used in D:OS EE
                header.DebugFlags = 0x000CA010;
                header.Write(Writer);

                if (Writer.MajorVersion > 1 || (Writer.MajorVersion == 1 && Writer.MinorVersion > 7))
                {
                    var msg = String.Format(
                        "Osiris version v{0}.{1} unsupported; this tool supports versions up to v1.7.",
                        Writer.MajorVersion, Writer.MinorVersion
                    );
                    throw new InvalidDataException(msg);
                }

                if (Writer.MajorVersion > 1 || (Writer.MajorVersion == 1 && Writer.MinorVersion >= 4))
                    Writer.Scramble = 0xAD;


                if (Writer.MajorVersion > 1 || (Writer.MajorVersion == 1 && Writer.MinorVersion >= 5))
                    WriteTypes(story.Types);

                Writer.WriteList(story.DivObjects);
                Writer.WriteList(story.Functions);
                WriteNodes(story.Nodes);
                WriteAdapters(story.Adapters);
                WriteDatabases(story.Databases);
                WriteGoals(story.Goals);
                Writer.WriteList(story.GlobalActions);
            }
        }
Пример #2
0
        public Story Read(Stream stream)
        {
            using (var reader = new OsiReader(stream))
            {
                var story = new Story();
                var header = new OsirisHeader();
                header.Read(reader);
                reader.MinorVersion = header.MinorVersion;
                reader.MajorVersion = header.MajorVersion;
                story.MinorVersion = header.MinorVersion;
                story.MajorVersion = header.MajorVersion;

                if (reader.MajorVersion > 1 || (reader.MajorVersion == 1 && reader.MinorVersion > 7))
                {
                    var msg = String.Format(
                        "Osiris version v{0}.{1} unsupported; this tool supports versions up to v1.7.",
                        reader.MajorVersion, reader.MinorVersion
                    );
                    throw new InvalidDataException(msg);
                }

                if (reader.MajorVersion > 1 || (reader.MajorVersion == 1 && reader.MinorVersion >= 4))
                    reader.Scramble = 0xAD;

                if (reader.MajorVersion > 1 || (reader.MajorVersion == 1 && reader.MinorVersion >= 5))
                    story.Types = ReadTypes(reader);
                else
                    story.Types = new Dictionary<uint, OsirisType>();

                story.Types[0] = new OsirisType();
                story.Types[0].Index = 0;
                story.Types[0].Name = "UNKNOWN";
                story.Types[1] = new OsirisType();
                story.Types[1].Index = 1;
                story.Types[1].Name = "INTEGER";
                story.Types[2] = new OsirisType();
                story.Types[2].Index = 2;
                story.Types[2].Name = "FLOAT";
                story.Types[3] = new OsirisType();
                story.Types[3].Index = 3;
                story.Types[3].Name = "STRING";

                story.DivObjects = reader.ReadList<OsirisDivObject>();
                story.Functions = reader.ReadList<Function>();
                story.Nodes = ReadNodes(reader);
                story.Adapters = ReadAdapters(reader);
                story.Databases = ReadDatabases(reader);
                story.Goals = ReadGoals(reader);
                story.GlobalActions = reader.ReadList<Call>();

                foreach (var node in story.Nodes)
                {
                    if (node.Value.DatabaseRef.IsValid())
                    {
                        var database = story.Databases[node.Value.DatabaseRef.DatabaseIndex];
                        if (database.OwnerNode != null)
                        {
                            throw new InvalidDataException("A database cannot be assigned to multiple database nodes!");
                        }

                        database.OwnerNode = node.Value;
                    }

                    if (node.Value is RuleNode)
                    {
                        // Remove the __DEF__ postfix that is added to the end of Query nodes
                        var rule = node.Value as RuleNode;
                        if (rule.IsQuery)
                        {
                            var ruleRoot = rule.GetRoot(story);
                            if (ruleRoot.Name != null && 
                                ruleRoot.Name.Length > 7 &&
                                ruleRoot.Name.Substring(ruleRoot.Name.Length - 7) == "__DEF__")
                            {
                                ruleRoot.Name = ruleRoot.Name.Substring(0, ruleRoot.Name.Length - 7);
                            }
                        }
                    }

                    if (node.Value is DataNode)
                    {
                        var data = node.Value as DataNode;
                        foreach (var reference in data.ReferencedBy)
                        {
                            if (reference.NodeRef.IsValid())
                            {
                                var ruleNode = story.Nodes[reference.NodeRef.NodeIndex];
                                if (reference.GoalId > 0 &&
                                    ruleNode is RuleNode)
                                {
                                    (ruleNode as RuleNode).DerivedGoalId = reference.GoalId;
                                }
                            }
                        }
                    }

                    if (node.Value is TreeNode)
                    {
                        var tree = node.Value as TreeNode;
                        if (tree.NextNode.NodeRef.IsValid())
                        {
                            var nextNode = story.Nodes[tree.NextNode.NodeRef.NodeIndex];
                            if (nextNode is RuleNode)
                            {
                                (nextNode as RuleNode).DerivedGoalId = tree.NextNode.GoalId;
                            }
                        }
                    }
                    
                    if (node.Value is RelNode)
                    {
                        var rel = node.Value as RelNode;
                        if (rel.AdapterRef.IsValid())
                        {
                            var adapter = story.Adapters[rel.AdapterRef.AdapterIndex];
                            if (adapter.OwnerNode != null)
                            {
                                throw new InvalidDataException("An adapter cannot be assigned to multiple join/rel nodes!");
                            }

                            adapter.OwnerNode = node.Value;
                        }
                    }
                    else if (node.Value is JoinNode)
                    {
                        var join = node.Value as JoinNode;
                        if (join.Adapter1Ref.IsValid())
                        {
                            var adapter = story.Adapters[join.Adapter1Ref.AdapterIndex];
                            if (adapter.OwnerNode != null)
                            {
                                throw new InvalidDataException("An adapter cannot be assigned to multiple join/rel nodes!");
                            }

                            adapter.OwnerNode = node.Value;
                        }

                        if (join.Adapter2Ref.IsValid())
                        {
                            var adapter = story.Adapters[join.Adapter2Ref.AdapterIndex];
                            if (adapter.OwnerNode != null)
                            {
                                throw new InvalidDataException("An adapter cannot be assigned to multiple join/rel nodes!");
                            }

                            adapter.OwnerNode = node.Value;
                        }
                    }
                }

                return story;
            }
        }