Пример #1
0
 private byte[] GetProps(Node node, out long size)
 {
     if (buffer == null || buffer.Length < node.PropsSize)
     {
         buffer = new byte[node.PropsSize];
     }
     fileStream.Seek(node.Start + 1, SeekOrigin.Begin);
     fileStream.Read(buffer, 0, (int)node.PropsSize);
     uint j = 0;
     bool escaped = false;
     for (uint i = 0; i < node.PropsSize; ++i, ++j)
     {
         if (buffer[i] == Constants.Escape)
         {
             ++i;
             buffer[j] = buffer[i];
             escaped = true;
         }
         else if (escaped)
         {
             buffer[j] = buffer[i];
         }
     }
     size = j;
     return buffer;
 }
Пример #2
0
 public bool GetProps(Node node, out PropertyReader props)
 {
     long size;
     byte[] buff = GetProps(node, out size);
     if (buff == null)
     {
         props = null;
         return false;
     }
     else
     {
         props = new PropertyReader(new MemoryStream(buff, 0, (int)size));
         return true;
     }
 }
Пример #3
0
        public bool OpenFile(string fileName)
        {
            fileStream = File.Open(fileName, FileMode.Open);
            reader = new BinaryReader(fileStream);

            uint version = reader.ReadUInt32();

            root = new Node();
            root.Start = 4;

            if (reader.ReadByte() == Constants.NodeStart)
            {
                return ParseNode(root);
            }
            else
            {
                return false;
            }
        }
Пример #4
0
        private bool ParseTowns(Map map, FileLoader loader, Node node)
        {
            PropertyReader props;
            Node nodeTown = node.Child;
            while (nodeTown != null)
            {
                if (!loader.GetProps(nodeTown, out props))
                {
                    lastError = "Could not read town data.";
                    return false;
                }

                uint townid = props.ReadUInt32();
                string townName = props.GetString();
                ushort townTempleX = props.ReadUInt16();
                ushort townTempleY = props.ReadUInt16();
                byte townTempleZ = props.ReadByte();

                Town town = new Town(
                    townid,
                    townName,
                    new Location(townTempleX, townTempleY, townTempleZ));

                map.Towns.Add(town);

                nodeTown = nodeTown.Next;
            }
            return true;
        }
Пример #5
0
        private bool ParseTileArea(Map map, FileLoader loader, Node node)
        {
            PropertyReader props;
            if (!loader.GetProps(node, out props))
            {
                lastError = "Invalid map node.";
                return false;
            }

            int baseX = props.ReadUInt16();
            int baseY = props.ReadUInt16();
            int baseZ = props.ReadByte();

            Node nodeTile = node.Child;

            while (nodeTile != null)
            {
                if (nodeTile.Type == (long)OtbmNodeType.Tile ||
                    nodeTile.Type == (long)OtbmNodeType.HouseTile)
                {
                    loader.GetProps(nodeTile, out props);

                    int tileX = baseX + props.ReadByte();
                    int tileY = baseY + props.ReadByte();
                    int tileZ = baseZ;

                    Tile tile = new Tile();
                    tile.Location = new Location(tileX, tileY, tileZ);

                    // TODO: houses
                    if (nodeTile.Type == (long)OtbmNodeType.HouseTile)
                    {
                        uint houseId = props.ReadUInt32();
                    }

                    byte attribute;
                    while (props.PeekChar() != -1)
                    {
                        attribute = props.ReadByte();
                        switch ((OtbmAttribute)attribute)
                        {
                            case OtbmAttribute.TileFlags:
                            {
                                TileFlags flags = (TileFlags)props.ReadUInt32();
                                if ((flags & TileFlags.ProtectionZone) == TileFlags.ProtectionZone)
                                {
                                    tile.IsProtectionZone = true;
                                }
                                else if ((flags & TileFlags.NoPvpZone) == TileFlags.NoPvpZone)
                                {
                                    tile.IsNoPvpZone = true;
                                }
                                else if ((flags & TileFlags.PvpZone) == TileFlags.PvpZone)
                                {
                                    tile.IsPvpZone = true;
                                }

                                if ((flags & TileFlags.NoLogout) == TileFlags.NoLogout)
                                {
                                    tile.IsNoLogoutZone = true;
                                }

                                if ((flags & TileFlags.Refresh) == TileFlags.Refresh)
                                {
                                    // TODO: Warn about house
                                    tile.IsRefreshZone = true;
                                }
                                break;
                            }
                            case OtbmAttribute.Item:
                            {
                                ushort itemId = props.ReadUInt16();
                                Item item = Item.Create(itemId);

                                // TODO: if isHouseTile && !item.Info.IsMoveable

                                if (item.Info.Group == ItemGroup.Ground)
                                {
                                    tile.Ground = item;
                                }
                                else
                                {
                                    tile.AddItem(item);
                                }
                                break;
                            }
                            default:
                                lastError = tile.Location + " Unknown tile attribute.";
                                return false;
                        }
                    }

                    Node nodeItem = nodeTile.Child;

                    while (nodeItem != null)
                    {
                        if (nodeItem.Type == (long)OtbmNodeType.Item)
                        {
                            loader.GetProps(nodeItem, out props);
                            ushort itemId = props.ReadUInt16();

                            // TODO: subclass item, different deserializations
                            // for different types
                            Item item = Item.Create(itemId);
                            if (item.Info.Group == ItemGroup.Ground)
                            {
                                tile.Ground = item;
                            }
                            else
                            {
                                tile.AddItem(item);
                            }
                        }
                        else
                        {
                            lastError += tile.Location + " Unknown node type.";
                            return false;
                        }
                        nodeItem = nodeItem.Next;
                    }

                    map.SetTile(tile.Location, tile);
                }
                nodeTile = nodeTile.Next;
            }

            return true;
        }
Пример #6
0
        private bool ParseNode(Node node)
        {
            Node currentNode = node;
            int val;
            while (true)
            {
                // read node type
                val = fileStream.ReadByte();
                if (val != -1)
                {
                    currentNode.Type = val;
                    bool setPropSize = false;
                    while (true)
                    {
                        // search child and next node
                        val = fileStream.ReadByte();
                        if (val == -1)
                        {
                            break;
                        }
                        else if (val == Constants.NodeStart)
                        {
                            Node childNode = new Node();
                            childNode.Start = fileStream.Position;
                            setPropSize = true;
                            currentNode.PropsSize = fileStream.Position - currentNode.Start - 2;
                            currentNode.Child = childNode;
                            if (!ParseNode(childNode))
                            {
                                return false;
                            }
                        }
                        else if (val == Constants.NodeEnd)
                        {
                            if (!setPropSize)
                            {
                                currentNode.PropsSize = fileStream.Position - currentNode.Start - 2;
                            }

                            val = fileStream.ReadByte();

                            if (val != -1)
                            {
                                if (val == Constants.NodeStart)
                                {
                                    // start next node
                                    Node nextNode = new Node();
                                    nextNode.Start = fileStream.Position;
                                    currentNode.Next = nextNode;
                                    currentNode = nextNode;
                                    break;
                                }
                                else if (val == Constants.NodeEnd)
                                {
                                    // up 1 level and move 1 position back
                                    // safeTell(pos) && safeSeek(pos)
                                    fileStream.Seek(-1, SeekOrigin.Current);
                                    return true;
                                }
                                else
                                {
                                    // bad format
                                    return false;
                                }
                            }
                            else
                            {
                                // end of file?
                                return true;
                            }
                        }
                        else if (val == Constants.Escape)
                        {
                            fileStream.ReadByte();
                        }
                    }
                }
                else
                {
                    return false;
                }
            }
        }