/// <summary> /// Will attempt to load object properties. /// </summary> /// <exception cref="Exception"></exception> private void LoadObjectProperties() { byte itemIdOffset = 100; string localDatFile = "ObjectProperties" + this.TibiaVersion + ".dat"; string datPath = this.TibiaProcess.MainModule.FileName; datPath = datPath.Substring(0, datPath.LastIndexOf(Path.DirectorySeparatorChar) + 1) + "Tibia.dat"; if (!File.Exists(datPath)) { throw new Exception("Could not load object properties since Tibia.dat could not be found in the client's directory." + "\nWithout object properties, modules like cavebot will not function properly."); } using (BinaryReader readerDatFile = new BinaryReader(File.OpenRead(datPath))) { bool queryServer = false, queryClient = false; System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create(); byte[] datHash = md5.ComputeHash(readerDatFile.BaseStream); readerDatFile.BaseStream.Position = 4; // first 4 bytes is file signature if (File.Exists(localDatFile)) { using (BinaryReader readerLocalFile = new BinaryReader(File.OpenRead(localDatFile))) { if (datHash.DataEquals(readerLocalFile.ReadBytes(datHash.Length))) { ushort count = readerLocalFile.ReadUInt16(); this.ObjectProperties = new Objects.ObjectProperties[count]; for (ushort i = 0; i < count; i++) { try { Objects.ObjectProperties objProperty = new Objects.ObjectProperties((ushort)(i + itemIdOffset)); objProperty.Flags = readerLocalFile.ReadUInt32(); this.ObjectProperties[i] = objProperty; if (this.ObjectPropertyRead != null) { this.ObjectPropertyRead(i, count); } } catch { queryServer = true; break; } } if (!queryClient && !queryServer) { if (this.ObjectPropertiesFinishedReading != null) { this.ObjectPropertiesFinishedReading(count); } return; } } else { queryServer = true; } } } else { queryServer = true; } if (queryServer) { try { TcpClient tc = new TcpClient(this.ObjectPropertiesServerIP, this.ObjectPropertiesServerPort); Objects.Packet p = new Objects.Packet(); p.AddBytes(datHash); p.AddLength(); p.Send(tc); p = Objects.Packet.GetNextPacket(tc.GetStream()); if (p.Length == 0) { queryClient = true; } else { p.GetUInt16(); byte[] hash = p.GetBytes(datHash.Length); ushort count = p.GetUInt16(); byte[] data = p.GetBytes(count * 4); tc.Close(); this.ObjectProperties = new Objects.ObjectProperties[count]; for (ushort i = 0; i < count; i++) { var objProps = new Objects.ObjectProperties((ushort)(itemIdOffset + i)); objProps.Flags = BitConverter.ToUInt32(data, i * 4); this.ObjectProperties[i] = objProps; if (this.ObjectPropertyRead != null) { this.ObjectPropertyRead(i, count); } } if (this.ObjectPropertiesFinishedReading != null) { this.ObjectPropertiesFinishedReading(count); } this.SaveObjectProperties(datHash); return; } } catch { queryClient = true; } } if (queryClient) { try { ushort itemCount = (ushort)(readerDatFile.ReadUInt16() - itemIdOffset); this.ObjectProperties = new Objects.ObjectProperties[itemCount]; for (int i = 0; i < itemCount; i++) { Objects.ObjectProperties objProperties = new ObjectProperties((ushort)(i + itemIdOffset)); switch (this.TibiaVersion) { case 772: if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.HasAutomapColor)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.HasAutomapColor); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.HasHelpLens)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.HasHelpLens); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsBlocking)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsBlocking); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsContainer)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsContainer); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsFloorChange)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsFloorChange); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsFluidContainer)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsFluidContainer); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsGround)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsGround); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsHangable)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsHangable); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsImmobile)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsImmobile); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsAlwaysTopUse)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsAlwaysTopUse); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsMissileBlocking)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsMissileBlocking); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsPathBlocking)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsPathBlocking); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsPickupable)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsPickupable); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsSplash)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsSplash); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsStackable)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsStackable); } //if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsTopOrder1)) objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsTopOrder1); if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsTopOrder2)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsTopUseIfOnly); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsTopOrder3)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsWalkThrough); } if (this.Packets.GetObjectProperty((ushort)(i + itemIdOffset), (byte)Enums.ObjectProperties772.IsUsable)) { objProperties.AddFlag(Enums.ObjectPropertiesFlags.IsUsable); } break; } this.ObjectProperties[i] = objProperties; if (this.ObjectPropertyRead != null) { this.ObjectPropertyRead(i + 1, itemCount); } } if (this.ObjectPropertiesFinishedReading != null) { this.ObjectPropertiesFinishedReading(itemCount); } this.SaveObjectProperties(datHash); } catch (Exception ex) { if (this.ObjectPropertiesFailed != null) { this.ObjectPropertiesFailed(ex); } } } } }