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