protected Item ParseItem(List<byte> data) { Item item = new Item(); item.packet = data.ToArray(); //try { BitReader reader = new BitReader(item.packet); byte packet = (byte)reader.Read(8); item.action = (uint)reader.Read(8); item.category = (uint)reader.Read(8); byte validSize = (byte)reader.Read(8); item.id = (uint)reader.Read(32); if (packet == 0x9d) reader.Read(40); item.equipped = reader.ReadBit(); reader.ReadBit(); reader.ReadBit(); item.in_socket = reader.ReadBit(); item.identified = reader.ReadBit(); reader.ReadBit(); item.switched_in = reader.ReadBit(); item.switched_out = reader.ReadBit(); item.broken = reader.ReadBit(); reader.ReadBit(); item.potion = reader.ReadBit(); item.has_sockets = reader.ReadBit(); reader.ReadBit(); item.in_store = reader.ReadBit(); item.not_in_a_socket = reader.ReadBit(); reader.ReadBit(); item.ear = reader.ReadBit(); item.start_item = reader.ReadBit(); reader.ReadBit(); reader.ReadBit(); reader.ReadBit(); item.simple_item = reader.ReadBit(); item.ethereal = reader.ReadBit(); reader.ReadBit(); item.personalised = reader.ReadBit(); item.gambling = reader.ReadBit(); item.rune_word = reader.ReadBit(); reader.Read(5); item.version = (Item.VersionType)(reader.Read(8)); reader.Read(2); byte destination = (byte)reader.Read(3); item.ground = (destination == 0x03); if (item.ground) { item.x = (UInt16)reader.Read(16); item.y = (UInt16)reader.Read(16); } else { item.directory = (byte)reader.Read(4); item.x = (byte)reader.Read(4); item.y = (byte)reader.Read(3); item.container = (Item.ContainerType)(reader.Read(4)); } item.unspecified_directory = false; if (item.action == (uint)Item.Action.add_to_shop || item.action == (uint)Item.Action.remove_from_shop) { long container = (long)(item.container); container |= 0x80; if ((container & 1) != 0) { container--; //remove first bit item.y += 8; } item.container = (Item.ContainerType)(container); } else if (item.container == Item.ContainerType.unspecified) { if (item.directory == (uint)Item.DirectoryType.not_applicable) { if (item.in_socket) //y is ignored for this container type, x tells you the index item.container = Item.ContainerType.item; else if (item.action == (uint)Item.Action.put_in_belt || item.action == (uint)Item.Action.remove_from_belt) { item.container = Item.ContainerType.belt; item.y = item.x / 4; item.x %= 4; } } else item.unspecified_directory = true; } if (item.ear) { //item.ear_character_class = (GameData.CharacterClassType) reader.Read(3); item.ear_level = (byte)reader.Read(7); item.ear_name = "F**k Off"; reader.Read(16 * 7); return item; } byte[] code_bytes = new byte[4]; for (int i = 0; i < code_bytes.Length; i++) code_bytes[i] = (byte)(reader.Read(8)); code_bytes[3] = 0; item.type = System.Text.Encoding.ASCII.GetString(code_bytes).Substring(0, 3); ItemEntry entry; if (!m_owner.m_dm.m_itemData.Get(item.type, out entry)) { Console.WriteLine("Failed to look up item in item data table"); return item; } item.name = entry.Name; item.width = (int)entry.Width; item.height = (int)entry.Height; item.is_gold = (item.type == "gld"); if (item.is_gold) { bool big_pile = reader.ReadBit(); if (big_pile) item.amount = (uint)reader.Read(32); else item.amount = (uint)reader.Read(12); return item; } item.used_sockets = (byte)reader.Read(3); item.quality = Item.QualityType.normal; if (item.simple_item || item.gambling) return item; item.level = (byte)reader.Read(7); item.quality = (Item.QualityType)(reader.Read(4)); // EVERYTHING AFTER THIS NEEDS FIXING! // Item mods will NOT be read/parsed in current version. // Item code and quality is enough for a hacky beta pickit. //return item; item.has_graphic = reader.ReadBit(); ; if (item.has_graphic) item.graphic = (byte)reader.Read(3); item.has_colour = reader.ReadBit(); if (item.has_colour) item.colour = (UInt16)reader.Read(11); if (item.identified) { switch (item.quality) { case Item.QualityType.inferior: item.prefix = (byte)reader.Read(3); break; case Item.QualityType.superior: item.superiority = (Item.SuperiorItemClassType)(reader.Read(3)); break; case Item.QualityType.magical: item.prefix = (uint)reader.Read(11); item.suffix = (uint)reader.Read(11); break; case Item.QualityType.crafted: case Item.QualityType.rare: item.prefix = (uint)reader.Read(8) - 156; item.suffix = (uint)reader.Read(8) - 1; if (ClientlessBot.debugging) { /* std::cout << "Rare prefix: " << item.prefix << std::endl; std::cout << "Rare suffix: " << item.suffix << std::endl; std::cout << get_char_array_string(data) << std::endl; */ } break; case Item.QualityType.set: item.set_code = (uint)reader.Read(12); break; case Item.QualityType.unique: if (item.type != "std") //standard of heroes exception? item.unique_code = (uint)reader.Read(12); break; } } if (item.quality == Item.QualityType.rare || item.quality == Item.QualityType.crafted) { for (ulong i = 0; i < 3; i++) { if (reader.ReadBit()) item.prefixes.Add((uint)reader.Read(11)); if (reader.ReadBit()) item.suffixes.Add((uint)reader.Read(11)); } } if (item.rune_word) { item.runeword_id = (uint)reader.Read(12); item.runeword_parameter = (byte)reader.Read(4); //std::cout << "runeword_id: " << item.runeword_id << ", parameter: " << item.runeword_parameter << std::endl; } if (item.personalised) { item.personalised_name = "F**k off"; reader.Read(7 * 16); } item.is_armor = entry.IsArmor(); item.is_weapon = entry.IsWeapon(); if (item.is_armor) item.defense = (uint)reader.Read(11) - 10; /*if(entry.throwable) { reader.Read(9); reader.Read(17); } //special case: indestructible phase blade else */ if (item.type == "7cr") reader.Read(8); else if (item.is_armor || item.is_weapon) { item.maximum_durability = (byte)reader.Read(8); item.indestructible = (uint)((item.maximum_durability == 0) ? 1 : 0); /* if(!item.indestructible) { item.durability = reader.Read(8); reader.ReadBit(); } */ //D2Hackit always reads it, hmmm. Appears to work. item.durability = (byte)reader.Read(8); reader.ReadBit(); } if (item.has_sockets) item.sockets = (byte)reader.Read(4); if (!item.identified) return item; if (entry.Stackable) { if (entry.Usable) reader.Read(5); item.amount = (uint)reader.Read(9); } uint set_mods = 0; if (item.quality == Item.QualityType.set) set_mods = (byte)reader.Read(5); //reader.debugging = debugging; return item; while (true) { //if(debugging) // std::cout << "Reading stat ID" << std::endl; uint stat_id = (uint)reader.Read(9); if (stat_id == 0x1ff) { //if(debugging) // std::cout << "Stat terminator encountered" << std::endl; break; } Item.PropertyType item_property; //process_item_stat(stat_id, reader, item_property); //item.properties.Add(item_property); } //std::cout << pretty_item_stats(item) << std::endl; } //catch(Exception e) { // Console.WriteLine("Error occured: "); } return item; }
protected void NpcAssignment(byte type, List <byte> data) { byte[] packet = data.ToArray(); NpcEntity output; //try //{ BitReader br = new BitReader(data.ToArray()); br.ReadBitsLittleEndian(8); UInt32 id = (uint)br.Read(32); UInt16 npctype = (ushort)br.Read(16); UInt16 x = (ushort)br.Read(16); UInt16 y = (ushort)br.Read(16); byte life = (byte)br.Read(8); byte size = (byte)br.Read(8); output = new NpcEntity(id, npctype, life, x, y); if (ClientlessBot.debugging) { Console.WriteLine("NPC id: {3}, Type: {0:X}, Life: {1:X}, Size: {2:X}", npctype, life, data.Count, id); } int informationLength = 16; String[] entries; if (!m_owner.m_dm.m_monsterFields.Get(npctype, out entries)) { Console.WriteLine("Failed to read monstats data for NPC of type {0}", type); } if (entries.Length != informationLength) { Console.WriteLine("Invalid monstats entry for NPC of type {0}", type); } bool lookupName = false; if (data.Count > 0x10) { br.Read(4); if (br.ReadBit()) { for (int i = 0; i < informationLength; i++) { int temp; int value = Int32.Parse(entries[i]); if (!BitScanReverse(out temp, (uint)value - 1)) { temp = 0; } if (temp == 31) { temp = 0; } //Console.WriteLine("BSR: {0} Bitcount: {1}", temp+1, bitCount); int bits = br.Read(temp + 1); } } output.SuperUnique = false; output.HasFlags = br.ReadBit(); if (output.HasFlags) { output.Champion = br.ReadBit(); output.Unique = br.ReadBit(); output.SuperUnique = br.ReadBit(); output.IsMinion = br.ReadBit(); output.Ghostly = br.ReadBit(); //Console.WriteLine("{0} {1} {2} {3} {4}", output.Champion, output.Unique, output.SuperUnique, output.IsMinion, output.Ghostly); } if (output.SuperUnique) { output.SuperUniqueId = br.ReadBitsLittleEndian(16); String name; if (!m_owner.m_dm.m_superUniques.Get(output.SuperUniqueId, out name)) { Console.WriteLine("Failed to lookup super unique monster name for {0}", output.SuperUniqueId); output.Name = "invalid"; } else { output.Name = name; //Console.WriteLine("NPC: {0}", name); } } else { lookupName = true; } if (data.Count > 17 && lookupName != true && output.Name != "invalid") { output.IsLightning = false; while (true) { byte mod = (byte)br.ReadBitsLittleEndian(8); if (mod == 0) { break; } if (mod == 0x11) { output.IsLightning = true; } } } } else { lookupName = true; } if (lookupName) { String name; if (!m_owner.m_dm.m_monsterNames.Get((int)output.Type, out name)) { Console.WriteLine("Failed to Look up monster name for {0}", output.Type); } else { output.Name = name; } //Console.WriteLine("NPC: {0}", name); } NpcEntity tempnpc; if (m_owner.BotGameData.Npcs.TryGetValue(id, out tempnpc)) { m_owner.BotGameData.Npcs[id] = output; } else { m_owner.BotGameData.Npcs.Add(id, output); } // } // catch // { // } }
protected void NpcAssignment(byte type, List<byte> data) { byte[] packet = data.ToArray(); NpcEntity output; //try //{ BitReader br = new BitReader(data.ToArray()); br.ReadBitsLittleEndian(8); UInt32 id = (uint)br.Read(32); UInt16 npctype = (ushort)br.Read(16); UInt16 x = (ushort)br.Read(16); UInt16 y = (ushort)br.Read(16); byte life = (byte)br.Read(8); byte size = (byte)br.Read(8); output = new NpcEntity(id, npctype, life, x, y); if(ClientlessBot.debugging) Console.WriteLine("NPC id: {3}, Type: {0:X}, Life: {1:X}, Size: {2:X}", npctype, life, data.Count, id); int informationLength = 16; String[] entries; if (!m_owner.m_dm.m_monsterFields.Get(npctype, out entries)) Console.WriteLine("Failed to read monstats data for NPC of type {0}", type); if(entries.Length != informationLength) Console.WriteLine("Invalid monstats entry for NPC of type {0}", type); bool lookupName = false; if (data.Count > 0x10) { br.Read(4); if (br.ReadBit()) { for (int i = 0; i < informationLength; i++) { int temp; int value = Int32.Parse(entries[i]); if (!BitScanReverse(out temp, (uint)value - 1)) temp = 0; if (temp == 31) temp = 0; //Console.WriteLine("BSR: {0} Bitcount: {1}", temp+1, bitCount); int bits = br.Read(temp+1); } } output.SuperUnique = false; output.HasFlags = br.ReadBit(); if (output.HasFlags) { output.Champion = br.ReadBit(); output.Unique = br.ReadBit(); output.SuperUnique = br.ReadBit(); output.IsMinion = br.ReadBit(); output.Ghostly = br.ReadBit(); //Console.WriteLine("{0} {1} {2} {3} {4}", output.Champion, output.Unique, output.SuperUnique, output.IsMinion, output.Ghostly); } if (output.SuperUnique) { output.SuperUniqueId = br.ReadBitsLittleEndian(16); String name; if (!m_owner.m_dm.m_superUniques.Get(output.SuperUniqueId, out name)) { Console.WriteLine("Failed to lookup super unique monster name for {0}", output.SuperUniqueId); output.Name = "invalid"; } else { output.Name = name; //Console.WriteLine("NPC: {0}", name); } } else lookupName = true; if (data.Count > 17 && lookupName != true && output.Name != "invalid") { output.IsLightning = false; while (true) { byte mod = (byte)br.ReadBitsLittleEndian(8); if (mod == 0) break; if (mod == 0x11) output.IsLightning = true; } } } else lookupName = true; if (lookupName) { String name; if (!m_owner.m_dm.m_monsterNames.Get((int)output.Type, out name)) Console.WriteLine("Failed to Look up monster name for {0}", output.Type); else output.Name = name; //Console.WriteLine("NPC: {0}", name); } NpcEntity tempnpc; if (m_owner.BotGameData.Npcs.TryGetValue(id, out tempnpc)) m_owner.BotGameData.Npcs[id] = output; else m_owner.BotGameData.Npcs.Add(id, output); // } // catch // { // } }
protected Item ParseItem(List <byte> data) { Item item = new Item(); item.packet = data.ToArray(); //try { BitReader reader = new BitReader(item.packet); byte packet = (byte)reader.Read(8); item.action = (uint)reader.Read(8); item.category = (uint)reader.Read(8); byte validSize = (byte)reader.Read(8); item.id = (uint)reader.Read(32); if (packet == 0x9d) { reader.Read(40); } item.equipped = reader.ReadBit(); reader.ReadBit(); reader.ReadBit(); item.in_socket = reader.ReadBit(); item.identified = reader.ReadBit(); reader.ReadBit(); item.switched_in = reader.ReadBit(); item.switched_out = reader.ReadBit(); item.broken = reader.ReadBit(); reader.ReadBit(); item.potion = reader.ReadBit(); item.has_sockets = reader.ReadBit(); reader.ReadBit(); item.in_store = reader.ReadBit(); item.not_in_a_socket = reader.ReadBit(); reader.ReadBit(); item.ear = reader.ReadBit(); item.start_item = reader.ReadBit(); reader.ReadBit(); reader.ReadBit(); reader.ReadBit(); item.simple_item = reader.ReadBit(); item.ethereal = reader.ReadBit(); reader.ReadBit(); item.personalised = reader.ReadBit(); item.gambling = reader.ReadBit(); item.rune_word = reader.ReadBit(); reader.Read(5); item.version = (Item.VersionType)(reader.Read(8)); reader.Read(2); byte destination = (byte)reader.Read(3); item.ground = (destination == 0x03); if (item.ground) { item.x = (UInt16)reader.Read(16); item.y = (UInt16)reader.Read(16); } else { item.directory = (byte)reader.Read(4); item.x = (byte)reader.Read(4); item.y = (byte)reader.Read(3); item.container = (Item.ContainerType)(reader.Read(4)); } item.unspecified_directory = false; if (item.action == (uint)Item.Action.add_to_shop || item.action == (uint)Item.Action.remove_from_shop) { long container = (long)(item.container); container |= 0x80; if ((container & 1) != 0) { container--; //remove first bit item.y += 8; } item.container = (Item.ContainerType)(container); } else if (item.container == Item.ContainerType.unspecified) { if (item.directory == (uint)Item.DirectoryType.not_applicable) { if (item.in_socket) { //y is ignored for this container type, x tells you the index item.container = Item.ContainerType.item; } else if (item.action == (uint)Item.Action.put_in_belt || item.action == (uint)Item.Action.remove_from_belt) { item.container = Item.ContainerType.belt; item.y = item.x / 4; item.x %= 4; } } else { item.unspecified_directory = true; } } if (item.ear) { //item.ear_character_class = (GameData.CharacterClassType) reader.Read(3); item.ear_level = (byte)reader.Read(7); item.ear_name = "F**k Off"; reader.Read(16 * 7); return(item); } byte[] code_bytes = new byte[4]; for (int i = 0; i < code_bytes.Length; i++) { code_bytes[i] = (byte)(reader.Read(8)); } code_bytes[3] = 0; item.type = System.Text.Encoding.ASCII.GetString(code_bytes).Substring(0, 3); ItemEntry entry; if (!m_owner.m_dm.m_itemData.Get(item.type, out entry)) { Console.WriteLine("Failed to look up item in item data table"); return(item); } item.name = entry.Name; item.width = (int)entry.Width; item.height = (int)entry.Height; item.is_gold = (item.type == "gld"); if (item.is_gold) { bool big_pile = reader.ReadBit(); if (big_pile) { item.amount = (uint)reader.Read(32); } else { item.amount = (uint)reader.Read(12); } return(item); } item.used_sockets = (byte)reader.Read(3); item.quality = Item.QualityType.normal; if (item.simple_item || item.gambling) { return(item); } item.level = (byte)reader.Read(7); item.quality = (Item.QualityType)(reader.Read(4)); // EVERYTHING AFTER THIS NEEDS FIXING! // Item mods will NOT be read/parsed in current version. // Item code and quality is enough for a hacky beta pickit. //return item; item.has_graphic = reader.ReadBit();; if (item.has_graphic) { item.graphic = (byte)reader.Read(3); } item.has_colour = reader.ReadBit(); if (item.has_colour) { item.colour = (UInt16)reader.Read(11); } if (item.identified) { switch (item.quality) { case Item.QualityType.inferior: item.prefix = (byte)reader.Read(3); break; case Item.QualityType.superior: item.superiority = (Item.SuperiorItemClassType)(reader.Read(3)); break; case Item.QualityType.magical: item.prefix = (uint)reader.Read(11); item.suffix = (uint)reader.Read(11); break; case Item.QualityType.crafted: case Item.QualityType.rare: item.prefix = (uint)reader.Read(8) - 156; item.suffix = (uint)reader.Read(8) - 1; if (ClientlessBot.debugging) { /* * std::cout << "Rare prefix: " << item.prefix << std::endl; * std::cout << "Rare suffix: " << item.suffix << std::endl; * std::cout << get_char_array_string(data) << std::endl; */ } break; case Item.QualityType.set: item.set_code = (uint)reader.Read(12); break; case Item.QualityType.unique: if (item.type != "std") //standard of heroes exception? { item.unique_code = (uint)reader.Read(12); } break; } } if (item.quality == Item.QualityType.rare || item.quality == Item.QualityType.crafted) { for (ulong i = 0; i < 3; i++) { if (reader.ReadBit()) { item.prefixes.Add((uint)reader.Read(11)); } if (reader.ReadBit()) { item.suffixes.Add((uint)reader.Read(11)); } } } if (item.rune_word) { item.runeword_id = (uint)reader.Read(12); item.runeword_parameter = (byte)reader.Read(4); //std::cout << "runeword_id: " << item.runeword_id << ", parameter: " << item.runeword_parameter << std::endl; } if (item.personalised) { item.personalised_name = "F**k off"; reader.Read(7 * 16); } item.is_armor = entry.IsArmor(); item.is_weapon = entry.IsWeapon(); if (item.is_armor) { item.defense = (uint)reader.Read(11) - 10; } /*if(entry.throwable) * { * reader.Read(9); * reader.Read(17); * } * //special case: indestructible phase blade * else */ if (item.type == "7cr") { reader.Read(8); } else if (item.is_armor || item.is_weapon) { item.maximum_durability = (byte)reader.Read(8); item.indestructible = (uint)((item.maximum_durability == 0) ? 1 : 0); /* * if(!item.indestructible) * { * item.durability = reader.Read(8); * reader.ReadBit(); * } */ //D2Hackit always reads it, hmmm. Appears to work. item.durability = (byte)reader.Read(8); reader.ReadBit(); } if (item.has_sockets) { item.sockets = (byte)reader.Read(4); } if (!item.identified) { return(item); } if (entry.Stackable) { if (entry.Usable) { reader.Read(5); } item.amount = (uint)reader.Read(9); } uint set_mods = 0; if (item.quality == Item.QualityType.set) { set_mods = (byte)reader.Read(5); } //reader.debugging = debugging; return(item); while (true) { //if(debugging) // std::cout << "Reading stat ID" << std::endl; uint stat_id = (uint)reader.Read(9); if (stat_id == 0x1ff) { //if(debugging) // std::cout << "Stat terminator encountered" << std::endl; break; } Item.PropertyType item_property; //process_item_stat(stat_id, reader, item_property); //item.properties.Add(item_property); } //std::cout << pretty_item_stats(item) << std::endl; } //catch(Exception e) { // Console.WriteLine("Error occured: "); } return(item); }