Пример #1
0
        private byte[] GetProps(FileLoaderNode 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;
            var 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(FileLoaderNode node, out PropertyReader props)
        {
            long size;
            var buff = GetProps(node, out size);

            if (buff == null)
            {
                props = null;
                return false;
            }

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

            var version = _reader.ReadUInt32();

            if(version > 0)
            {
                Logger.Error("Invalid file version.");
                _reader.Close();
                return false;
            }

            if(SafeSeek(4))
            {
                _root = new FileLoaderNode {Start = 4};

                if (_reader.ReadByte() == Constants.NODE_START)
                    return ParseNode(_root);
            }

            return false;
        }
Пример #4
0
        private void ParseTowns(FileLoader loader, FileLoaderNode otbNode)
        {
            var nodeTown = otbNode.Child;

            while (nodeTown != null)
            {
                PropertyReader props;
                if (!loader.GetProps(nodeTown, out props))
                    throw new Exception("Could not read town data.");

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

                var town = new Town(townid, townName, new Position(townTempleX, townTempleY, townTempleZ));
                AddTown(town);

                nodeTown = nodeTown.Next;
            }
        }
Пример #5
0
        private static void ParseTileArea(FileLoader loader, FileLoaderNode otbNode)
        {
            PropertyReader props;
            if (!loader.GetProps(otbNode, out props))
                throw new Exception("Invalid map node.");

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

            var nodeTile = otbNode.Child;

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

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

                    bool isHouseTile = false;
                    //House* house = NULL;
                    //Tile tile = null;
                    //Item groundItem = null;
                    //TileFlags tileflags = TileFlags.None;

                    //var tile = new Tile(tileX, tileY, tileZ);

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

                    while (props.PeekChar() != -1)
                    {
                        byte attribute = props.ReadByte();
                        switch ((OtbmAttribute)attribute)
                        {
                            case OtbmAttribute.TileFlags:
                                {
                                    var flags = /*(TileFlags)*/props.ReadUInt32();
                                    //if ((flags & TileFlags.ProtectionZone) == TileFlags.ProtectionZone)
                                    //    tileflags |= TileFlags.ProtectionZone;
                                    //else if ((flags & TileFlags.NoPvpZone) == TileFlags.NoPvpZone)
                                    //    tileflags |= TileFlags.NoPvpZone;
                                    //else if ((flags & TileFlags.PvpZone) == TileFlags.PvpZone)
                                    //    tileflags |= TileFlags.PvpZone;

                                    //if ((flags & TileFlags.NoLogout) == TileFlags.NoLogout)
                                    //    tileflags |= TileFlags.NoLogout;

                                    //if ((flags & TileFlags.Refresh) == TileFlags.Refresh)
                                    //    tileflags |= TileFlags.Refresh;

                                    break;
                                }
                            case OtbmAttribute.Item:
                                {
                                    ushort itemId = props.ReadUInt16();
                                    //Item item = Item.Create(itemId);

                                    //if (item == null)
                                    //{
                                    //    Log.Error("Failed to create item.");
                                    //    return false;
                                    //}

                                    //if (tile != null)
                                    //{
                                    //    tile.InternalAddThing(item);
                                    //    item.StartDecaying();
                                    //}
                                    //else if (item.IsGround)
                                    //    groundItem = item;
                                    //else
                                    //{
                                    //    tile = CreateTile(groundItem, item, tileX, tileY, tileZ);
                                    //    tile.InternalAddThing(item);
                                    //    item.StartDecaying();
                                    //}

                                    break;
                                }
                            default:
                                throw new Exception(string.Format("{0} Unknown tile attribute.", new Position(tileX, tileY, tileZ)));
                        }
                    }

                    var nodeItem = nodeTile.Child;

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

                            //// TODO: subclass item, different deserializations
                            //// for different types
                            //Item item = Item.Create(itemId);

                            //if (tile != null)
                            //{
                            //    tile.InternalAddThing(item);
                            //    item.StartDecaying();
                            //}
                            //else if (item.IsGround)
                            //    groundItem = item;
                            //else
                            //{
                            //    // !tile
                            //    tile = CreateTile(groundItem, item, tileX, tileY, tileZ);
                            //    tile.InternalAddThing(item);
                            //    item.StartDecaying();
                            //}
                        }
                        else
                        {
                            throw new Exception(string.Format("{0} Unknown node type.", new Position(tileX, tileY, tileZ)));
                        }

                        nodeItem = nodeItem.Next;
                    }

                    //if (tile == null)
                    //    tile = CreateTile(groundItem, null, tileX, tileY, tileZ);

                    //tile.SetFlag(tileflags);
                    //SetTile(tileX, tileY, tileZ, tile);
                }

                nodeTile = nodeTile.Next;
            }
        }
Пример #6
0
        private bool ParseNode(FileLoaderNode node)
        {
            var currentNode = node;
            int val;

            while (true)
            {
                // read node type
                val = _fileStream.ReadByte();
                if (val != -1)
                {

                    currentNode.Type = val;
                    var setPropSize = false;

                    while (true)
                    {
                        // search child and next node
                        val = _fileStream.ReadByte();

                        if (val == Constants.NODE_START)
                        {
                            var childNode = new FileLoaderNode {Start = _fileStream.Position};
                            setPropSize = true;

                            currentNode.PropsSize = _fileStream.Position - currentNode.Start - 2;
                            currentNode.Child = childNode;

                            if (!ParseNode(childNode))
                                return false;
                        }
                        else if (val == Constants.NODE_END)
                        {
                            if (!setPropSize)
                                currentNode.PropsSize = _fileStream.Position - currentNode.Start - 2;

                            val = _fileStream.ReadByte();

                            if (val != -1)
                            {
                                if (val == Constants.NODE_START)
                                {
                                    // start next node
                                    var nextNode = new FileLoaderNode {Start = _fileStream.Position};
                                    currentNode.Next = nextNode;
                                    currentNode = nextNode;
                                    break;
                                }

                                if (val == Constants.NODE_END)
                                {
                                    // up 1 level and move 1 position back
                                    // safeTell(pos) && safeSeek(pos)
                                    _fileStream.Seek(-1, SeekOrigin.Current);
                                    return true;
                                }

                                // bad format
                                return false;

                            }

                            // end of file?
                            return true;
                        }
                        else if (val == Constants.ESCAPE)
                        {
                            _fileStream.ReadByte();
                        }
                    }
                }
                else
                {
                    return false;
                }
            }
        }