private static void ParseTileNode( ParsingTree parsingTree, ParsingNode tileNode, UInt16 areaStartingX, UInt16 areaStartingY, Byte areaZ ) { if (tileNode.Type != NodeType.NormalTile && tileNode.Type != NodeType.HouseTile) { throw new MalformedTileAreaNodeException("Unknow tile area node type."); } var stream = new ParsingStream(parsingTree, tileNode); var tileX = areaStartingX + stream.ReadByte(); var tileY = areaStartingY + stream.ReadByte(); Tile tile = null; if (tileNode.Type == NodeType.HouseTile) { tile = ParseHouseTile(ref stream, (ushort)tileX, (ushort)tileY, areaZ); // Improve this, remove casts } var tileFlags = ParseTileAttributes(ref parsingTree, ref stream, ref tile, tileNode); if (tile != null) { tile.Flags.AddFlags(tileFlags); } }
public static void ParseTileAreaNode(ParsingTree parsingTree, ParsingNode tileAreaNode) { if (parsingTree == null) { throw new ArgumentNullException(nameof(parsingTree)); } if (tileAreaNode == null) { throw new ArgumentNullException(nameof(tileAreaNode)); } var stream = new ParsingStream( tree: parsingTree, node: tileAreaNode); var areaStartingX = stream.ReadUInt16(); var areaStartingY = stream.ReadUInt16(); var areaZ = stream.ReadByte(); foreach (var tileNode in tileAreaNode.Children) { ParseTileNode( parsingTree: parsingTree, tileNode: tileNode, areaStartingX: areaStartingX, areaStartingY: areaStartingY, areaZ: areaZ); } }
private static TileFlags ParseTileFlags(ref ParsingStream stream) { var flags = (TileFlags)stream.ReadUInt32(); var tileFlags = TileFlags.None; if (TileFlagsExtensions.FlagsAreSet(flags, (TileFlags)OTBMTileFlag.NoLogout)) { TileFlagsExtensions.AddFlags(tileFlags, (TileFlags)OTBMTileFlag.NoLogout); } if (TileFlagsExtensions.FlagsAreSet(flags, (TileFlags)OTBMTileFlag.NoPvpZone)) { TileFlagsExtensions.AddFlags(tileFlags, (TileFlags)OTBMTileFlag.NoPvpZone); } else if (TileFlagsExtensions.FlagsAreSet(flags, (TileFlags)OTBMTileFlag.PvpZone)) { TileFlagsExtensions.AddFlags(tileFlags, (TileFlags)OTBMTileFlag.PvpZone); } else if (TileFlagsExtensions.FlagsAreSet(flags, (TileFlags)OTBMTileFlag.ProtectionZone)) { TileFlagsExtensions.AddFlags(tileFlags, (TileFlags)OTBMTileFlag.ProtectionZone); } return(tileFlags); }
private static void ParseTileItem(ref ParsingStream stream, ref Tile tile, bool isHouse = false) { var itemId = stream.ReadUInt16(); var item = new Items.Item(itemId); if (isHouse && item.IsMoveable()) { throw new MoveableItemInHouseException(); // Don't need to use Exception. Maybe just a warning with pos and don't place the item in tile is Okay } else { // if item.count <= 0; item.count = 1. But if always create with count = 0 this should only be item.count = 1, ou create with count = 1 if (tile != null) { //tile.AddInternalThing(null); // Item // item.StartDecaying(); // item.LoadedFromMap = true; } else if (item != null) // item is ground Tile // ground_item = item { } else { tile = new Tile(0, 0, 0); // XYZ //tile.AddInternalThing(null); // Item // item.StartDecaying(); // item.LoadedFromMap = true; } } }
private static Tile ParseHouseTile(ref ParsingStream stream, UInt16 tileX, UInt16 tileY, byte tileZ) { var houseId = stream.ReadUInt32(); var house = HouseManager.Instance.CreateHouseOrGetReference(houseId); var tile = HouseTile.CreateTileAndAddItToHouse(tileX, tileY, tileZ, house); return(tile); }
public static void ParseItemNode( ParsingTree parsingTree, ParsingNode parsingNode ) { if (parsingNode.Type != NodeType.Item) { throw new MalformedItemNodeException(); } var stream = new ParsingStream(parsingTree, parsingNode); var itemId = stream.ReadUInt16(); // var item = Item.CreateFromId(itemId); }
private void ParseOTBVersion(ref ParsingStream stream) { stream.UnderlayingStream.Skip(4); // Skip flags var attr = (OTBAttributes)stream.ReadByte(); if (attr == OTBAttributes.ROOT_VERSION) { var dataSize = stream.ReadUInt16(); if (dataSize != 140) // VersionInfo : 4 UInt32(4bytes) = 12 + 128 * 1 byte = 140 { throw new MalformedWorldException(); // Lets use this for now } _majorVersion = stream.ReadUInt32(); // Otb version _minorVersion = stream.ReadUInt32(); // Client version _buildVersion = stream.ReadUInt32(); // Build version stream.UnderlayingStream.Skip(128); // Skip CSD version } }
private void LoadFromOTB(string path) { var data = FileManager.ReadFileToByteArray(path); var parsingTree = WorldLoader.ParseWorld(data); var rootNode = parsingTree.Root; var stream = new ParsingStream(parsingTree, rootNode); ParseOTBVersion(ref stream); _sharedItems = new List <SharedItem>(rootNode.Children.Count); foreach (var itemNode in rootNode.Children) { var itemStream = new ParsingStream(parsingTree, itemNode); ParseItemNode(ref itemStream); } _sharedItems.TrimExcess(); }
public static WorldHeader GetWorldHeader(ParsingTree tree) { if (tree == null) { throw new ArgumentNullException(nameof(tree)); } var parsingStream = new ParsingStream(tree, tree.Root); var worldEncodingVersion = parsingStream.ReadUInt32(); var worldWidth = parsingStream.ReadUInt16(); var worldHeight = parsingStream.ReadUInt16(); var itemEncodingMajorVersion = parsingStream.ReadUInt32(); var itemEncodingMinorVersion = parsingStream.ReadUInt32(); return(new WorldHeader( worldEncodingVersion: worldEncodingVersion, worldWidth: worldWidth, worldHeight: worldHeight, itemEncodingMajorVersion: itemEncodingMajorVersion, itemEncodingMinorVersion: itemEncodingMinorVersion)); }
private static TileFlags ParseTileAttributes(ref ParsingTree parsingTree, ref ParsingStream stream, ref Tile tile, ParsingNode tileNode) { var tileFlags = new TileFlags(); NodeAttribute nodeAttribute; while (!stream.IsOver) { nodeAttribute = (NodeAttribute)stream.ReadByte(); switch (nodeAttribute) { case NodeAttribute.TileFlags: tileFlags = ParseTileFlags(ref stream); break; case NodeAttribute.Item: ParseTileItem(ref stream, ref tile, tileNode.Type == NodeType.HouseTile); break; default: throw new MalformedTileNodeException("Unknow node attribute " + nameof(nodeAttribute) + " of type " + nodeAttribute); } } foreach (var itemNode in tileNode.Children) { if (itemNode.Type != NodeType.Item) { throw new MalformedItemNodeException(); } var itemStream = new ParsingStream(parsingTree, itemNode); ParseTileItem(ref itemStream, ref tile, tileNode.Type == NodeType.HouseTile); } return(tileFlags); }
private static List <ItemAttribute> DeserializeAttribute(ref ParsingStream stream) { return(new List <ItemAttribute>()); }
private void ParseItemNode(ref ParsingStream stream) { var flags = (SharedItemFlags)stream.ReadUInt32(); var item = new SharedItem(flags); while (!stream.IsOver) { var attr = (OTBAttributes)stream.ReadByte(); var dataSize = stream.ReadUInt16(); switch (attr) { case OTBAttributes.ITEM_SERVERID: if (dataSize != sizeof(UInt16)) { throw new MalformedItemNodeException(); } item.Id = stream.ReadUInt16(); if (item.Id > 30000 && item.Id < 30100) { item.Id -= 30000; // Correct ID in wrong range I guess } break; case OTBAttributes.ITEM_CLIENTID: if (dataSize != sizeof(UInt16)) { throw new MalformedItemNodeException(); } item.ClientId = stream.ReadUInt16(); break; case OTBAttributes.ITEM_SPEED: if (dataSize != sizeof(UInt16)) { throw new MalformedItemNodeException(); } item.Speed = stream.ReadUInt16(); break; case OTBAttributes.ITEM_LIGHT2: if (dataSize != 2 * sizeof(UInt16)) // 2 UInt16 = 4 bytes { throw new MalformedItemNodeException(); } item.LightLevel = (Byte)stream.ReadUInt16(); // Read UInt16 item.LightColor = (Byte)stream.ReadUInt16(); // But range is only to 255 break; case OTBAttributes.ITEM_TOPORDER: if (dataSize != sizeof(Byte)) { throw new MalformedItemNodeException(); } item.AlwaysOnTopOrder = stream.ReadByte(); break; case OTBAttributes.ITEM_WAREID: if (dataSize != sizeof(UInt16)) { throw new MalformedItemNodeException(); } item.WareId = stream.ReadUInt16(); break; default: stream.Skip(dataSize); break; } } if (item.Id > _sharedItems.Capacity + 100 || item.Id < 100) { throw new IndexOutOfRangeException(); } _sharedItems.Insert(item.Id - 100, item); }
public static WorldAttributes GetWorldAttributes(ParsingTree tree) { if (tree == null) { throw new ArgumentNullException(nameof(tree)); } if (tree.Root.Children.Count != 1) { throw new MalformedWorldException(); } var worldDataNode = tree.Root.Children[0]; if ((NodeType)worldDataNode.Type != NodeType.WorldData) { throw new MalformedWorldException(); } var parsingStream = new ParsingStream(tree, worldDataNode); var worldDescription = new List <string>(); string spawnsFilename = null; string housesFilename = null; while (!parsingStream.IsOver) { var attribute = (NodeAttribute)parsingStream.ReadByte(); switch (attribute) { case NodeAttribute.WorldDescription: worldDescription.Add(parsingStream.ReadString()); break; case NodeAttribute.ExtensionFileForSpawns: if (spawnsFilename != null) { throw new MalformedWorldAttributesNodeException("Multiple filenames for world spawns."); } else { spawnsFilename = parsingStream.ReadString(); } break; case NodeAttribute.ExtensionFileForHouses: if (housesFilename != null) { throw new MalformedWorldAttributesNodeException("Multiple filenames for world houses."); } else { housesFilename = parsingStream.ReadString(); } break; default: throw new MalformedWorldAttributesNodeException("Unknown attribute found in world attributes note."); } } var formattedWorldDescription = string.Join( separator: Environment.NewLine, values: worldDescription); return(new WorldAttributes( worldDescription: formattedWorldDescription, spawnsFilename: spawnsFilename, housesFilename: housesFilename)); }