private static Dictionary<int, UpdateField> ReadValuesUpdateBlock(ref Packet packet, ObjectType type, int index)
        {
            var maskSize = packet.ReadByte();

            var updateMask = new int[maskSize];
            for (var i = 0; i < maskSize; i++)
                updateMask[i] = packet.ReadInt32();

            var mask = new BitArray(updateMask);
            var dict = new Dictionary<int, UpdateField>();

            int objectEnd = UpdateFields.GetUpdateField(ObjectField.OBJECT_END);

            for (var i = 0; i < mask.Count; i++)
            {
                if (!mask[i])
                    continue;

                var blockVal = packet.ReadUpdateField();
                string key = "Block Value " + i;
                string value = blockVal.Int32Value + "/" + blockVal.SingleValue;

                if (i < objectEnd)
                    key = UpdateFields.GetUpdateFieldName(i, "ObjectField");
                else
                {
                    switch (type)
                    {
                        case ObjectType.Container:
                        {
                            if (i < UpdateFields.GetUpdateField(ItemField.ITEM_END))
                                goto case ObjectType.Item;

                            key = UpdateFields.GetUpdateFieldName(i, "ContainerField");
                            break;
                        }
                        case ObjectType.Item:
                        {
                            key = UpdateFields.GetUpdateFieldName(i, "ItemField");
                            break;
                        }
                        case ObjectType.Player:
                        {
                            if (i < UpdateFields.GetUpdateField(UnitField.UNIT_END))
                                goto case ObjectType.Unit;

                            key = UpdateFields.GetUpdateFieldName(i, "PlayerField");
                            break;
                        }
                        case ObjectType.Unit:
                        {
                            key = UpdateFields.GetUpdateFieldName(i, "UnitField");
                            break;
                        }
                        case ObjectType.GameObject:
                        {
                            key = UpdateFields.GetUpdateFieldName(i, "GameObjectField");
                            break;
                        }
                        case ObjectType.DynamicObject:
                        {
                            key = UpdateFields.GetUpdateFieldName(i, "DynamicObjectField");
                            break;
                        }
                        case ObjectType.Corpse:
                        {
                            key = UpdateFields.GetUpdateFieldName(i, "CorpseField");
                            break;
                        }
                    }
                }
                packet.Writer.WriteLine("[" + index + "] " + key + ": " + value);
                dict.Add(i, blockVal);
            }

            return dict;
        }
Beispiel #2
0
        public static void HandleDBReply(Packet packet)
        {
            packet.ReadTime("Hotfix date");
            var type = packet.ReadUInt32E<DB2Hash>("DB2 File");

            var size = packet.ReadInt32("Size");
            var data = packet.ReadBytes(size);
            var db2File = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);

            var entry = (uint)packet.ReadInt32("Entry");
            if ((int)entry < 0)
            {
                packet.WriteLine("Row {0} has been removed.", -(int)entry);
                return;
            }

            switch (type)
            {
                case DB2Hash.BroadcastText:
                {
                    BroadcastText broadcastText = new BroadcastText();

                    var id = db2File.ReadEntry("Id");
                    broadcastText.ID = (uint)id.Key;

                    broadcastText.Language = db2File.ReadInt32("Language");
                    if (db2File.ReadUInt16() > 0)
                        broadcastText.MaleText = db2File.ReadCString("Male Text");
                    if (db2File.ReadUInt16() > 0)
                        broadcastText.FemaleText = db2File.ReadCString("Female Text");

                    broadcastText.EmoteID = new uint?[3];
                    broadcastText.EmoteDelay = new uint?[3];
                    for (int i = 0; i < 3; ++i)
                        broadcastText.EmoteID[i] = (uint) db2File.ReadInt32("Emote ID", i);
                    for (int i = 0; i < 3; ++i)
                        broadcastText.EmoteDelay[i] = (uint) db2File.ReadInt32("Emote Delay", i);

                    broadcastText.SoundId = db2File.ReadUInt32("Sound Id");
                    broadcastText.UnkEmoteId = db2File.ReadUInt32("Unk MoP 1"); // unk emote
                    broadcastText.Type = db2File.ReadUInt32("Unk MoP 2"); // kind of type?

                    Storage.BroadcastTexts.Add(broadcastText, packet.TimeSpan);
                    packet.AddSniffData(StoreNameType.None, id.Key, "BROADCAST_TEXT");
                    break;
                }
                case DB2Hash.Creature: // New structure - 5.4.0
                {
                    db2File.ReadUInt32("Creature Id");
                    db2File.ReadUInt32("Item Id 1");
                    db2File.ReadUInt32("Item Id 2");
                    db2File.ReadUInt32("Item Id 3");
                    db2File.ReadUInt32("Mount");
                    for (int i = 0; i < 4; ++i)
                        db2File.ReadInt32("Display Id", i);

                    for (int i = 0; i < 4; ++i)
                        db2File.ReadSingle("Display Id Probability", i);

                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Name");

                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("SubName");

                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Female SubName");

                    db2File.ReadUInt32("Rank");
                    db2File.ReadUInt32("Inhabit Type");
                    break;
                }
                case DB2Hash.CreatureDifficulty:
                {
                    CreatureDifficulty creatureDifficulty = new CreatureDifficulty();

                    creatureDifficulty.ID = (uint)db2File.ReadEntry("Id").Key;

                    creatureDifficulty.CreatureID = db2File.ReadUInt32("Creature Id");
                    creatureDifficulty.FactionID = db2File.ReadUInt32("Faction Template Id");
                    creatureDifficulty.Expansion = db2File.ReadInt32("Expansion");
                    creatureDifficulty.MinLevel = db2File.ReadInt32("Min Level");
                    creatureDifficulty.MaxLevel = db2File.ReadInt32("Max Level");

                    creatureDifficulty.Flags = new uint?[5];
                    for (int i = 0; i < 5; ++i)
                        creatureDifficulty.Flags[i] = db2File.ReadUInt32("Flags", i);

                    Storage.CreatureDifficulties.Add(creatureDifficulty, packet.TimeSpan);
                    break;
                }
                case DB2Hash.GameObjects:
                {
                    db2File.ReadEntry("GameObject Id");

                    db2File.ReadUInt32("Map");

                    db2File.ReadUInt32("Display Id");

                    db2File.ReadSingle("Position X");
                    db2File.ReadSingle("Position Y");
                    db2File.ReadSingle("Position Z");
                    db2File.ReadSingle("Rotation X");
                    db2File.ReadSingle("Rotation Y");
                    db2File.ReadSingle("Rotation Z");
                    db2File.ReadSingle("Rotation W");

                    db2File.ReadSingle("Size");
                    db2File.ReadInt32E<GameObjectType>("Type");

                    for (int i = 0; i < 4; i++)
                        db2File.ReadInt32("Data", i);

                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Name");

                    break;
                }
                case DB2Hash.Item:
                {
                    ItemTemplate key = new ItemTemplate {Entry = entry};
                    ItemTemplate item = Storage.ItemTemplates.ContainsKey(key)
                        ? Storage.ItemTemplates[key].Item1
                        : new ItemTemplate();

                    db2File.ReadUInt32<ItemId>("Item Entry");
                    item.Class = db2File.ReadInt32E<ItemClass>("Class");
                    item.SubClass = db2File.ReadUInt32("Sub Class");
                    item.SoundOverrideSubclass = db2File.ReadInt32("Sound Override Subclass");
                    item.Material = db2File.ReadInt32E<Material>("Material");
                    item.DisplayID = db2File.ReadUInt32("Display ID");
                    item.InventoryType = db2File.ReadUInt32E<InventoryType>("Inventory Type");
                    item.SheathType = db2File.ReadInt32E<SheathType>("Sheath Type");

                    Storage.ItemTemplates.Add(item, packet.TimeSpan);
                    packet.AddSniffData(StoreNameType.Item, (int) entry, "DB_REPLY");
                    break;
                }
                case DB2Hash.ItemExtendedCost:
                {
                    db2File.ReadUInt32("Item Extended Cost Entry");
                    db2File.ReadUInt32("Required Honor Points");
                    db2File.ReadUInt32("Required Arena Points");
                    db2File.ReadUInt32("Required Arena Slot");
                    for (var i = 0; i < 5; ++i)
                        db2File.ReadUInt32("Required Item", i);

                    for (var i = 0; i < 5; ++i)
                        db2File.ReadUInt32("Required Item Count", i);

                    db2File.ReadUInt32("Required Personal Arena Rating");
                    db2File.ReadUInt32("Item Purchase Group");
                    for (var i = 0; i < 5; ++i)
                        db2File.ReadUInt32("Required Currency", i);

                    for (var i = 0; i < 5; ++i)
                        db2File.ReadUInt32("Required Currency Count", i);

                    db2File.ReadUInt32("Required Faction Id");
                    db2File.ReadUInt32("Required Faction Standing");
                    db2File.ReadUInt32("Requirement Flags");
                    db2File.ReadUInt32("Required Guild Level");
                    db2File.ReadInt32<AchievementId>("Required Achievement");
                    break;
                }
                case DB2Hash.Item_sparse:
                {
                    ItemTemplate key = new ItemTemplate {Entry = entry};
                    ItemTemplate item = Storage.ItemTemplates.ContainsKey(key)
                        ? Storage.ItemTemplates[key].Item1
                        : new ItemTemplate();

                    db2File.ReadUInt32<ItemId>("Item Sparse Entry");
                    item.Quality = db2File.ReadInt32E<ItemQuality>("Quality");
                    item.Flags = db2File.ReadUInt32E<ItemProtoFlags>("Flags 1");
                    item.FlagsExtra = db2File.ReadInt32E<ItemFlagExtra>("Flags 2");
                    db2File.ReadUInt32("Flags 3");
                    item.Unk430_1 = db2File.ReadSingle("Unk430_1");
                    item.Unk430_2 = db2File.ReadSingle("Unk430_2");
                    item.BuyCount = db2File.ReadUInt32("Buy count");
                    item.BuyPrice = db2File.ReadUInt32("Buy Price");
                    item.SellPrice = db2File.ReadUInt32("Sell Price");
                    item.InventoryType = db2File.ReadInt32E<InventoryType>("Inventory Type");
                    item.AllowedClasses = db2File.ReadInt32E<ClassMask>("Allowed Classes");
                    item.AllowedRaces = db2File.ReadInt32E<RaceMask>("Allowed Races");
                    item.ItemLevel = db2File.ReadUInt32("Item Level");
                    item.RequiredLevel = db2File.ReadUInt32("Required Level");
                    item.RequiredSkillId = db2File.ReadUInt32("Required Skill ID");
                    item.RequiredSkillLevel = db2File.ReadUInt32("Required Skill Level");
                    item.RequiredSpell = (uint) db2File.ReadInt32<SpellId>("Required Spell");
                    item.RequiredHonorRank = db2File.ReadUInt32("Required Honor Rank");
                    item.RequiredCityRank = db2File.ReadUInt32("Required City Rank");
                    item.RequiredRepFaction = db2File.ReadUInt32("Required Rep Faction");
                    item.RequiredRepValue = db2File.ReadUInt32("Required Rep Value");
                    item.MaxCount = db2File.ReadInt32("Max Count");
                    item.MaxStackSize = db2File.ReadInt32("Max Stack Size");
                    item.ContainerSlots = db2File.ReadUInt32("Container Slots");

                    item.StatTypes = new ItemModType?[10];
                    for (int i = 0; i < 10; i++)
                    {
                        ItemModType statType = db2File.ReadInt32E<ItemModType>("Stat Type", i);
                        item.StatTypes[i] = statType == ItemModType.None ? ItemModType.Mana : statType; // TDB
                    }

                    item.StatValues = new int?[10];
                    for (int i = 0; i < 10; i++)
                        item.StatValues[i] = db2File.ReadInt32("Stat Value", i);

                    item.ScalingValue = new int?[10];
                    for (int i = 0; i < 10; i++)
                        item.ScalingValue[i] = db2File.ReadInt32("Scaling Value", i);

                    item.SocketCostRate = new int?[10];
                    for (int i = 0; i < 10; i++)
                        item.SocketCostRate[i] = db2File.ReadInt32("Socket Cost Rate", i);

                    item.ScalingStatDistribution = db2File.ReadInt32("Scaling Stat Distribution");
                    item.DamageType = db2File.ReadInt32E<DamageType>("Damage Type");
                    item.Delay = db2File.ReadUInt32("Delay");
                    item.RangedMod = db2File.ReadSingle("Ranged Mod");

                    item.TriggeredSpellIds = new int?[5];
                    for (int i = 0; i < 5; i++)
                        item.TriggeredSpellIds[i] = db2File.ReadInt32<SpellId>("Triggered Spell ID", i);

                    item.TriggeredSpellTypes = new ItemSpellTriggerType?[5];
                    for (int i = 0; i < 5; i++)
                        item.TriggeredSpellTypes[i] = db2File.ReadInt32E<ItemSpellTriggerType>("Trigger Spell Type", i);

                    item.TriggeredSpellCharges = new int?[5];
                    for (int i = 0; i < 5; i++)
                        item.TriggeredSpellCharges[i] = db2File.ReadInt32("Triggered Spell Charges", i);

                    item.TriggeredSpellCooldowns = new int?[5];
                    for (int i = 0; i < 5; i++)
                        item.TriggeredSpellCooldowns[i] = db2File.ReadInt32("Triggered Spell Cooldown", i);

                    item.TriggeredSpellCategories = new uint?[5];
                    for (int i = 0; i < 5; i++)
                        item.TriggeredSpellCategories[i] = db2File.ReadUInt32("Triggered Spell Category", i);

                    item.TriggeredSpellCategoryCooldowns = new int?[5];
                    for (int i = 0; i < 5; i++)
                        item.TriggeredSpellCategoryCooldowns[i] = db2File.ReadInt32(
                            "Triggered Spell Category Cooldown", i);

                    item.Bonding = db2File.ReadInt32E<ItemBonding>("Bonding");

                    if (db2File.ReadUInt16() > 0)
                        item.Name = db2File.ReadCString("Name", 0);

                    for (int i = 1; i < 4; ++i)
                        if (db2File.ReadUInt16() > 0)
                            db2File.ReadCString("Name", i);

                    if (db2File.ReadUInt16() > 0)
                        item.Description = db2File.ReadCString("Description");

                    item.PageText = db2File.ReadUInt32("Page Text");
                    item.Language = db2File.ReadInt32E<Language>("Language");
                    item.PageMaterial = db2File.ReadInt32E<PageMaterial>("Page Material");
                    item.StartQuestId = (uint) db2File.ReadInt32<QuestId>("Start Quest");
                    item.LockId = db2File.ReadUInt32("Lock ID");
                    item.Material = db2File.ReadInt32E<Material>("Material");
                    item.SheathType = db2File.ReadInt32E<SheathType>("Sheath Type");
                    item.RandomPropery = db2File.ReadInt32("Random Property");
                    item.RandomSuffix = db2File.ReadUInt32("Random Suffix");
                    item.ItemSet = db2File.ReadUInt32("Item Set");
                    item.AreaID = db2File.ReadUInt32<AreaId>("Area");
                    item.MapID = db2File.ReadInt32<MapId>("Map ID");
                    item.TotemCategory = db2File.ReadInt32E<TotemCategory>("Totem Category");

                    item.ItemSocketColors = new ItemSocketColor?[3];
                    for (int i = 0; i < 3; i++)
                        item.ItemSocketColors[i] = db2File.ReadInt32E<ItemSocketColor>("Socket Color", i);

                    item.SocketContent = new uint?[3];
                    for (int i = 0; i < 3; i++)
                        item.SocketContent[i] = db2File.ReadUInt32("Socket Item", i);

                    item.SocketBonus = db2File.ReadInt32("Socket Bonus");
                    item.GemProperties = db2File.ReadInt32("Gem Properties");
                    item.ArmorDamageModifier = db2File.ReadSingle("Armor Damage Modifier");
                    item.Duration = db2File.ReadUInt32("Duration");
                    item.ItemLimitCategory = db2File.ReadInt32("Limit Category");
                    item.HolidayID = db2File.ReadInt32E<Holiday>("Holiday");
                    item.StatScalingFactor = db2File.ReadSingle("Stat Scaling Factor");
                    item.CurrencySubstitutionID = db2File.ReadUInt32("Currency Substitution Id");
                    item.CurrencySubstitutionCount = db2File.ReadUInt32("Currency Substitution Count");

                    Storage.ObjectNames.Add(new ObjectName {ObjectType = ObjectType.Item, ID = (int)entry, Name = item.Name},
                        packet.TimeSpan);
                    packet.AddSniffData(StoreNameType.Item, (int) entry, "DB_REPLY");
                    break;
                }
                case DB2Hash.KeyChain:
                {
                    db2File.ReadUInt32("Key Chain Id");
                    db2File.ReadBytes("Key", 32);
                    break;
                }
                case DB2Hash.SceneScript: // lua ftw!
                {
                    db2File.ReadUInt32("Scene Script Id");
                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Name");

                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Script");
                    db2File.ReadUInt32("Previous Scene Script Part");
                    db2File.ReadUInt32("Next Scene Script Part");
                    break;
                }
                case DB2Hash.Vignette:
                {
                    db2File.ReadUInt32("Vignette Entry");
                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Name");

                    db2File.ReadUInt32("Icon");
                    db2File.ReadUInt32("Flag"); // not 100% sure (8 & 32 as values only) - todo verify with more data
                    db2File.ReadSingle("Unk Float 1");
                    db2File.ReadSingle("Unk Float 2");
                    break;
                }
                case DB2Hash.WbAccessControlList:
                {
                    db2File.ReadUInt32("Id");

                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Address");

                    db2File.ReadUInt32("Unk MoP 1");
                    db2File.ReadUInt32("Unk MoP 2");
                    db2File.ReadUInt32("Unk MoP 3");
                    db2File.ReadUInt32("Unk MoP 4"); // flags?
                    break;
                }
                default:
                {
                    db2File.AddValue("Unknown DB2 file type", string.Format("{0} (0x{0:x})", type));
                    for (var i = 0;; ++i)
                    {
                        if (db2File.Length - 4 >= db2File.Position)
                        {
                            var blockVal = db2File.ReadUpdateField();
                            string key = "Block Value " + i;
                            string value = blockVal.UInt32Value + "/" + blockVal.SingleValue;
                            packet.AddValue(key, value);
                        }
                        else
                        {
                            var left = db2File.Length - db2File.Position;
                            for (var j = 0; j < left; ++j)
                            {
                                string key = "Byte Value " + i;
                                var value = db2File.ReadByte();
                                packet.AddValue(key, value);
                            }
                            break;
                        }
                    }
                    break;
                }
            }

            db2File.ClosePacket(false);
        }
        public static Dictionary<int, UpdateField> ReadValuesUpdateBlock(Packet packet, ObjectType type, object index, bool isCreating)
        {
            var maskSize = packet.ReadByte();

            var updateMask = new int[maskSize];
            for (var i = 0; i < maskSize; i++)
                updateMask[i] = packet.ReadInt32();

            var mask = new BitArray(updateMask);
            var dict = new Dictionary<int, UpdateField>();

            int objectEnd = UpdateFields.GetUpdateField(ObjectField.OBJECT_END);
            for (var i = 0; i < mask.Count; ++i)
            {
                if (!mask[i])
                    continue;

                var blockVal = packet.ReadUpdateField();

                // Don't spam 0 values at create
                if (isCreating && blockVal.UInt32Value == 0)
                    continue;

                string key = "Block Value " + i;
                string value = blockVal.UInt32Value + "/" + blockVal.SingleValue;

                if (i < objectEnd)
                    key = UpdateFields.GetUpdateFieldName<ObjectField>(i);
                else
                {
                    switch (type)
                    {
                        case ObjectType.Container:
                        {
                            if (i < UpdateFields.GetUpdateField(ItemField.ITEM_END))
                                goto case ObjectType.Item;

                            key = UpdateFields.GetUpdateFieldName<ContainerField>(i);
                            break;
                        }
                        case ObjectType.Item:
                        {
                            key = UpdateFields.GetUpdateFieldName<ItemField>(i);
                            break;
                        }
                        case ObjectType.Player:
                        {
                            if (i < UpdateFields.GetUpdateField(UnitField.UNIT_END) || i < UpdateFields.GetUpdateField(UnitField.UNIT_FIELD_END))
                                goto case ObjectType.Unit;

                            key = UpdateFields.GetUpdateFieldName<PlayerField>(i);
                            break;
                        }
                        case ObjectType.Unit:
                        {
                            key = UpdateFields.GetUpdateFieldName<UnitField>(i);
                            break;
                        }
                        case ObjectType.GameObject:
                        {
                            key = UpdateFields.GetUpdateFieldName<GameObjectField>(i);
                            break;
                        }
                        case ObjectType.DynamicObject:
                        {
                            key = UpdateFields.GetUpdateFieldName<DynamicObjectField>(i);
                            break;
                        }
                        case ObjectType.Corpse:
                        {
                            key = UpdateFields.GetUpdateFieldName<CorpseField>(i);
                            break;
                        }
                        case ObjectType.AreaTrigger:
                        {
                            key = UpdateFields.GetUpdateFieldName<AreaTriggerField>(i);
                            break;
                        }
                        case ObjectType.SceneObject:
                        {
                            key = UpdateFields.GetUpdateFieldName<SceneObjectField>(i);
                            break;
                        }
                        case ObjectType.Conversation:
                        {
                            key = UpdateFields.GetUpdateFieldName<ConversationField>(i);
                            break;
                        }
                    }
                }

                packet.AddValue(key, value, index);
                dict.Add(i, blockVal);
            }

            objectEnd = UpdateFields.GetUpdateField(ObjectDynamicField.OBJECT_DYNAMIC_END);
            if (ClientVersion.AddedInVersion(ClientVersionBuild.V5_0_4_16016))
            {
                maskSize = packet.ReadByte();
                updateMask = new int[maskSize];
                for (var i = 0; i < maskSize; i++)
                    updateMask[i] = packet.ReadInt32();

                mask = new BitArray(updateMask);
                for (var i = 0; i < mask.Count; ++i)
                {
                    if (!mask[i])
                        continue;

                    var flag = packet.ReadByte();

                    if ((flag & 0x80) != 0)
                        packet.ReadUInt16();

                    var cnt = flag & 0x7F;
                    var vals = new int[cnt];
                    for (var j = 0; j < cnt; ++j)
                        vals[j] = packet.ReadInt32();

                    string key = "Dynamic Block Value " + i;
                    if (i < objectEnd)
                        key = UpdateFields.GetUpdateFieldName<ObjectDynamicField>(i);
                    else
                    {
                        switch (type)
                        {
                            case ObjectType.Container:
                            {
                                if (i < UpdateFields.GetUpdateField(ItemDynamicField.ITEM_DYNAMIC_END))
                                    goto case ObjectType.Item;

                                key = UpdateFields.GetUpdateFieldName<ContainerDynamicField>(i);
                                break;
                            }
                            case ObjectType.Item:
                            {
                                key = UpdateFields.GetUpdateFieldName<ItemDynamicField>(i);
                                break;
                            }
                            case ObjectType.Player:
                            {
                                if (i < UpdateFields.GetUpdateField(UnitDynamicField.UNIT_DYNAMIC_END))
                                    goto case ObjectType.Unit;

                                key = UpdateFields.GetUpdateFieldName<PlayerDynamicField>(i);
                                break;
                            }
                            case ObjectType.Unit:
                            {
                                key = UpdateFields.GetUpdateFieldName<UnitDynamicField>(i);
                                break;
                            }
                            case ObjectType.GameObject:
                            {
                                key = UpdateFields.GetUpdateFieldName<GameObjectDynamicField>(i);
                                break;
                            }
                            case ObjectType.DynamicObject:
                            {
                                key = UpdateFields.GetUpdateFieldName<DynamicObjectDynamicField>(i);
                                break;
                            }
                            case ObjectType.Corpse:
                            {
                                key = UpdateFields.GetUpdateFieldName<CorpseDynamicField>(i);
                                break;
                            }
                            case ObjectType.AreaTrigger:
                            {
                                key = UpdateFields.GetUpdateFieldName<AreaTriggerDynamicField>(i);
                                break;
                            }
                            case ObjectType.SceneObject:
                            {
                                key = UpdateFields.GetUpdateFieldName<SceneObjectDynamicField>(i);
                                break;
                            }
                            case ObjectType.Conversation:
                            {
                                key = UpdateFields.GetUpdateFieldName<ConversationDynamicField>(i);
                                break;
                            }
                        }
                    }

                    var fieldMask = new BitArray(vals);
                    for (var j = 0; j < fieldMask.Count; ++j)
                    {
                        if (!fieldMask[j])
                            continue;

                        var blockVal = packet.ReadUpdateField();
                        string value = blockVal.UInt32Value + "/" + blockVal.SingleValue;
                        packet.AddValue(key, value, index, j);
                    }
                }
            }

            return dict;
        }
Beispiel #4
0
        private static Dictionary<int, UpdateField> ReadValuesUpdateBlock(ref Packet packet, ObjectType type, int index, bool isCreating)
        {
            var maskSize = packet.ReadByte();

            var updateMask = new int[maskSize];
            for (var i = 0; i < maskSize; i++)
                updateMask[i] = packet.ReadInt32();

            var mask = new BitArray(updateMask);
            var dict = new Dictionary<int, UpdateField>();

            int objectEnd = UpdateFields.GetUpdateField(ObjectField.OBJECT_END);
            for (var i = 0; i < mask.Count; i++)
            {
                if (!mask[i])
                    continue;

                var blockVal = packet.ReadUpdateField();

                // Don't spam 0 values at create
                if (isCreating && blockVal.UInt32Value == 0)
                    continue;

                string key = "Block Value " + i;
                string value = blockVal.UInt32Value + "/" + blockVal.SingleValue;

                if (i < objectEnd)
                    key = UpdateFields.GetUpdateFieldName<ObjectField>(i);
                else
                {
                    switch (type)
                    {
                        case ObjectType.Container:
                        {
                            if (i < UpdateFields.GetUpdateField(ItemField.ITEM_END))
                                goto case ObjectType.Item;

                            key = UpdateFields.GetUpdateFieldName<ContainerField>(i);
                            break;
                        }
                        case ObjectType.Item:
                        {
                            key = UpdateFields.GetUpdateFieldName<ItemField>(i);
                            break;
                        }
                        case ObjectType.Player:
                        {
                            if (i < UpdateFields.GetUpdateField(UnitField.UNIT_END))
                                goto case ObjectType.Unit;

                            key = UpdateFields.GetUpdateFieldName<PlayerField>(i);
                            break;
                        }
                        case ObjectType.Unit:
                        {
                            key = UpdateFields.GetUpdateFieldName<UnitField>(i);
                            break;
                        }
                        case ObjectType.GameObject:
                        {
                            key = UpdateFields.GetUpdateFieldName<GameObjectField>(i);
                            break;
                        }
                        case ObjectType.DynamicObject:
                        {
                            key = UpdateFields.GetUpdateFieldName<DynamicObjectField>(i);
                            break;
                        }
                        case ObjectType.Corpse:
                        {
                            key = UpdateFields.GetUpdateFieldName<CorpseField>(i);
                            break;
                        }
                        case ObjectType.AreaTrigger:
                        {
                            key = UpdateFields.GetUpdateFieldName<AreaTriggerField>(i);
                            break;
                        }
                    }
                }
                packet.WriteLine("[" + index + "] " + key + ": " + value);
                dict.Add(i, blockVal);
            }

            // Dynamic fields - NYI
            if (ClientVersion.AddedInVersion(ClientVersionBuild.V5_0_4_16016))
            {
                maskSize = packet.ReadByte();
                updateMask = new int[maskSize];
                for (var i = 0; i < maskSize; i++)
                    updateMask[i] = packet.ReadInt32();

                mask = new BitArray(updateMask);
                for (var i = 0; i < mask.Count; ++i)
                {
                    if (!mask[i])
                        continue;

                    var flag = packet.ReadByte();

                    if ((flag & 0x80) != 0)
                        packet.ReadUInt16();

                    var cnt = flag & 0x7F;
                    var vals = new uint[cnt];
                    for (var j = 0; j < cnt; ++j)
                        vals[j] = packet.ReadUInt32();

                    for (var j = 0; j < cnt; ++j)
                        if (vals[j] != 0)
                            for (var k = 0; k < 32; ++k)
                                if (((1 << k) & vals[j]) != 0)
                                    packet.ReadUInt32();
                }
            }

            return dict;
        }
Beispiel #5
0
        public static void HandleDBReply(Packet packet)
        {
            DB2Hash type = packet.ReadUInt32E<DB2Hash>("TableHash");
            uint entry = (uint)packet.ReadInt32("RecordID");
            bool allow = (int)entry >= 0;
            packet.ReadTime("Timestamp");
            if (ClientVersion.AddedInVersion(ClientVersionBuild.V6_2_0_20173))
                allow = packet.ReadBit("Allow");

            int size = packet.ReadInt32("Size");
            var data = packet.ReadBytes(size);
            Packet db2File = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);

            HotfixData hotfixData = new HotfixData
            {
                TableHash = type,
            };

            if (allow)
            {
                if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)))
                {
                    hotfixData.Deleted = false;
                    hotfixData.RecordID = (int)entry;
                    hotfixData.Timestamp =
                        Storage.HotfixDataStore[new Tuple<DB2Hash, int>(type, (int)entry)].Item1.Timestamp;
                    Storage.HotfixDatas.Add(hotfixData);
                }
            }
            else
            {
                if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, -(int)entry)))
                {
                    hotfixData.Deleted = true;
                    hotfixData.RecordID = -(int)entry;
                    hotfixData.Timestamp =
                        Storage.HotfixDataStore[new Tuple<DB2Hash, int>(type, -(int)entry)].Item1.Timestamp;
                    Storage.HotfixDatas.Add(hotfixData);
                }
                packet.WriteLine("Row {0} has been removed.", -(int) entry);
                return;
            }

            switch (type)
            {
                case DB2Hash.BroadcastText:
                {
                    BroadcastText broadcastText = new BroadcastText();

                    var id = db2File.ReadEntry("Id");
                    broadcastText.ID = (uint)id.Key;
                    broadcastText.Language = db2File.ReadInt32("Language");
                    ushort maletextLength = db2File.ReadUInt16();
                    broadcastText.MaleText = db2File.ReadWoWString("Male Text", maletextLength);
                    ushort femaletextLength = db2File.ReadUInt16();
                    broadcastText.FemaleText = db2File.ReadWoWString("Female Text", femaletextLength);

                    broadcastText.EmoteID = new uint?[3];
                    broadcastText.EmoteDelay = new uint?[3];
                    for (int i = 0; i < 3; ++i)
                        broadcastText.EmoteID[i] = (uint) db2File.ReadInt32("Emote ID", i);
                    for (int i = 0; i < 3; ++i)
                        broadcastText.EmoteDelay[i] = (uint) db2File.ReadInt32("Emote Delay", i);

                    broadcastText.SoundId = db2File.ReadUInt32("Sound Id");
                    broadcastText.UnkEmoteId = db2File.ReadUInt32("Unk MoP 1"); // unk emote
                    broadcastText.Type = db2File.ReadUInt32("Unk MoP 2"); // kind of type?

                    if (BinaryPacketReader.GetLocale() != LocaleConstant.enUS)
                    {
                        BroadcastTextLocale broadcastTextLocale = new BroadcastTextLocale
                        {
                            ID = (uint)id.Key,
                            Locale = BinaryPacketReader.GetClientLocale(),
                            MaleTextLang = broadcastText.MaleText,
                            FemaleTextLang = broadcastText.FemaleText
                        };

                        Storage.BroadcastTextLocales.Add(broadcastTextLocale, packet.TimeSpan);
                    }

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.BroadcastTexts.Add(broadcastText, packet.TimeSpan);
                    packet.AddSniffData(StoreNameType.None, id.Key, "BROADCAST_TEXT");
                    break;
                }
                case DB2Hash.Creature: // New structure - 6.0.2
                {
                    CreatureDB2 creature = new CreatureDB2();

                    creature.ID = (uint)db2File.ReadEntry("CreatureID").Key;
                    creature.Type = db2File.ReadUInt32E<CreatureType>("Type");

                    creature.ItemID = new uint?[5];
                    for (int i = 0; i < 3; ++i)
                        creature.ItemID[i] = db2File.ReadUInt32<ItemId>("ItemID", i);

                    creature.Mount = db2File.ReadUInt32("Mount");

                    creature.DisplayID = new uint?[5];
                    for (int i = 0; i < 4; ++i)
                        creature.DisplayID[i] = db2File.ReadUInt32("DisplayID", i);

                    creature.DisplayIDProbability = new float?[5];
                    for (int i = 0; i < 4; ++i)
                        creature.DisplayIDProbability[i] = db2File.ReadSingle("DisplayIDProbability", i);

                    if (db2File.ReadUInt16() > 0)
                        creature.Name = db2File.ReadCString("Name");

                    if (db2File.ReadUInt16() > 0)
                        creature.FemaleName = db2File.ReadCString("FemaleName");

                    if (db2File.ReadUInt16() > 0)
                        creature.SubName = db2File.ReadCString("SubName");

                    if (db2File.ReadUInt16() > 0)
                        creature.FemaleSubName = db2File.ReadCString("FemaleSubName");

                    creature.Rank = db2File.ReadUInt32("Rank");
                    creature.InhabitType = db2File.ReadUInt32("InhabitType");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.Creatures.Add(creature, packet.TimeSpan);
                    break;
                }
                case DB2Hash.CreatureDifficulty:
                {
                    CreatureDifficulty creatureDifficulty = new CreatureDifficulty();

                    creatureDifficulty.ID = (uint)db2File.ReadEntry("Id").Key;

                    creatureDifficulty.CreatureID = db2File.ReadUInt32("Creature Id");
                    creatureDifficulty.FactionID = db2File.ReadUInt32("Faction Template Id");
                    creatureDifficulty.Expansion = db2File.ReadInt32("Expansion");
                    creatureDifficulty.MinLevel = db2File.ReadInt32("Min Level");
                    creatureDifficulty.MaxLevel = db2File.ReadInt32("Max Level");

                    creatureDifficulty.Flags = new uint?[5];
                    for (int i = 0; i < 5; ++i)
                        creatureDifficulty.Flags[i] = db2File.ReadUInt32("Flags", i);

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.CreatureDifficulties.Add(creatureDifficulty, packet.TimeSpan);
                    break;
                }
                case DB2Hash.CriteriaTree:
                {
                    var id = db2File.ReadUInt32("ID");
                    db2File.ReadUInt32("CriteriaID");
                    db2File.ReadUInt64("Amount");
                    db2File.ReadUInt32("Operator");
                    db2File.ReadUInt32("Parent");
                    db2File.ReadUInt32("Flags");
                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Description");
                    db2File.ReadUInt32("OrderIndex");
                    break;
                }
                case DB2Hash.CurvePoint:
                {
                    CurvePoint curvePoint = new CurvePoint();

                    curvePoint.ID = db2File.ReadUInt32("ID");

                    curvePoint.CurveID = db2File.ReadUInt32("CurveID");
                    curvePoint.Index = db2File.ReadUInt32("Index");
                    curvePoint.X = db2File.ReadSingle("X");
                    curvePoint.Y = db2File.ReadSingle("Y");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.CurvePoints.Add(curvePoint, packet.TimeSpan);
                    break;
                }
                case DB2Hash.GameObjects: // New structure - 6.0.2
                {
                    GameObjects gameObjects = new GameObjects();

                    gameObjects.ID = (uint)db2File.ReadEntry("ID").Key;

                    gameObjects.MapID = db2File.ReadUInt32("Map");

                    gameObjects.DisplayID = db2File.ReadUInt32("DisplayID");

                    gameObjects.PositionX = db2File.ReadSingle("PositionX");
                    gameObjects.PositionY = db2File.ReadSingle("PositionY");
                    gameObjects.PositionZ = db2File.ReadSingle("PositionZ");
                    gameObjects.RotationX = db2File.ReadSingle("RotationX");
                    gameObjects.RotationY = db2File.ReadSingle("RotationY");
                    gameObjects.RotationZ = db2File.ReadSingle("RotationZ");
                    gameObjects.RotationW = db2File.ReadSingle("RotationW");

                    gameObjects.Size = db2File.ReadSingle("Size");

                    db2File.ReadInt32("Phase Use Flags");
                    gameObjects.PhaseID = db2File.ReadUInt32("PhaseID");
                    gameObjects.PhaseGroupID = db2File.ReadUInt32("PhaseGroupID");

                    gameObjects.Type = db2File.ReadInt32E<GameObjectType>("Type");

                    gameObjects.Data = new int?[8];
                    for (int i = 0; i < gameObjects.Data.Length; i++)
                        gameObjects.Data[i] = db2File.ReadInt32("Data", i);

                    if (db2File.ReadUInt16() > 0)
                        gameObjects.Name = db2File.ReadCString("Name");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.GameObjectsBag.Add(gameObjects, packet.TimeSpan);
                    break;
                }
                case DB2Hash.Item: // New structure - 6.0.2
                {
                    Item item = new Item();

                    item.ID = db2File.ReadUInt32<ItemId>("Item ID");

                    item.Class = db2File.ReadInt32E<ItemClass>("Class");
                    item.SubClass = db2File.ReadUInt32("Sub Class");
                    item.SoundOverrideSubclass = db2File.ReadInt32("Sound Override Subclass");
                    item.Material = db2File.ReadInt32E<Material>("Material");
                    item.InventoryType = db2File.ReadUInt32E<InventoryType>("Inventory Type");
                    item.Sheath = db2File.ReadUInt32E<SheathType>("Sheath");

                    item.FileDataID = db2File.ReadUInt32("FileDataID");
                    item.GroupSoundsID = db2File.ReadUInt32("GroupSoundsID");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.Items.Add(item, packet.TimeSpan);
                    packet.AddSniffData(StoreNameType.Item, (int) entry, "DB_REPLY");
                    break;
                }
                case DB2Hash.ItemEffect:
                {
                    ItemEffect itemEffect = new ItemEffect();

                    itemEffect.ID = db2File.ReadUInt32("ID");

                    itemEffect.ItemID = db2File.ReadUInt32<ItemId>("ItemID");
                    itemEffect.OrderIndex = db2File.ReadUInt32<ItemId>("OrderIndex");
                    itemEffect.SpellID = db2File.ReadUInt32<SpellId>("SpellID");
                    itemEffect.Trigger = db2File.ReadUInt32("Trigger");
                    itemEffect.Charges = db2File.ReadUInt32("Charges");
                    itemEffect.Cooldown = db2File.ReadInt32("Cooldown");
                    itemEffect.Category = db2File.ReadUInt32("Category");
                    itemEffect.CategoryCooldown = db2File.ReadInt32("CategoryCooldown");
                    if (ClientVersion.AddedInVersion(ClientVersionBuild.V6_2_0_20182))
                        itemEffect.ChrSpecializationID = db2File.ReadUInt32("ChrSpecializationID");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.ItemEffects.Add(itemEffect, packet.TimeSpan);
                    break;
                }
                case DB2Hash.ItemModifiedAppearance:
                {
                    ItemModifiedAppearance itemModifiedAppearance = new ItemModifiedAppearance();

                    itemModifiedAppearance.ID = db2File.ReadUInt32("ID");

                    itemModifiedAppearance.ItemID = db2File.ReadUInt32<ItemId>("ItemID");
                    itemModifiedAppearance.AppearanceModID = db2File.ReadUInt32<ItemId>("AppearanceModID");
                    itemModifiedAppearance.AppearanceID = db2File.ReadUInt32<SpellId>("AppearanceID");
                    itemModifiedAppearance.IconFileDataID = db2File.ReadUInt32("IconFileDataID");
                    itemModifiedAppearance.Index = db2File.ReadUInt32("Index");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.ItemModifiedAppearances.Add(itemModifiedAppearance, packet.TimeSpan);
                    break;
                }
                case DB2Hash.ItemExtendedCost: // New structure - 6.0.2
                {
                    ItemExtendedCost itemExtendedCost = new ItemExtendedCost();

                    itemExtendedCost.ID = db2File.ReadUInt32("ItemExtendedCostID");

                    if (ClientVersion.RemovedInVersion(ClientVersionBuild.V6_1_0_19678))
                    {
                        db2File.ReadUInt32("RequiredHonorPoints");
                        db2File.ReadUInt32("RequiredArenaPoints");
                    }

                    itemExtendedCost.RequiredArenaSlot = db2File.ReadUInt32("RequiredArenaSlot");

                    itemExtendedCost.RequiredItem = new uint?[5];
                    for (int i = 0; i < 5; ++i)
                        itemExtendedCost.RequiredItem[i] = db2File.ReadUInt32("RequiredItem", i);

                    itemExtendedCost.RequiredItemCount = new uint?[5];
                    for (int i = 0; i < 5; ++i)
                        itemExtendedCost.RequiredItemCount[i] = db2File.ReadUInt32("RequiredItemCount", i);

                    itemExtendedCost.RequiredPersonalArenaRating = db2File.ReadUInt32("RequiredPersonalArenaRating");
                    itemExtendedCost.ItemPurchaseGroup = db2File.ReadUInt32("ItemPurchaseGroup");

                    itemExtendedCost.RequiredCurrency = new uint?[5];
                    for (int i = 0; i < 5; ++i)
                        itemExtendedCost.RequiredCurrency[i] = db2File.ReadUInt32("RequiredCurrency", i);

                    itemExtendedCost.RequiredCurrencyCount = new uint?[5];
                    for (int i = 0; i < 5; ++i)
                        itemExtendedCost.RequiredCurrencyCount[i] = db2File.ReadUInt32("RequiredCurrencyCount", i);

                    itemExtendedCost.RequiredFactionId = db2File.ReadUInt32("RequiredFactionId");
                    itemExtendedCost.RequiredFactionStanding = db2File.ReadUInt32("RequiredFactionStanding");
                    itemExtendedCost.RequirementFlags = db2File.ReadUInt32("RequirementFlags");
                    itemExtendedCost.RequiredAchievement = db2File.ReadUInt32<AchievementId>("RequiredAchievement");
                    if (ClientVersion.AddedInVersion(ClientVersionBuild.V6_1_0_19678))
                        itemExtendedCost.RequiredMoney = db2File.ReadUInt32("RequiredMoney");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.ItemExtendedCosts.Add(itemExtendedCost, packet.TimeSpan);
                    break;
                }
                case DB2Hash.ItemCurrencyCost:
                {
                    ItemCurrencyCost itemCurrencyCost = new ItemCurrencyCost();

                    itemCurrencyCost.ID = db2File.ReadUInt32("ID");
                    itemCurrencyCost.ItemID = db2File.ReadUInt32<ItemId>("ItemID");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.ItemCurrencyCosts.Add(itemCurrencyCost, packet.TimeSpan);
                    break;
                }
                case DB2Hash.Mount:
                {
                    Mount mount = new Mount();

                    mount.ID = db2File.ReadUInt32("ID");

                    mount.MountTypeID = db2File.ReadUInt32("MountTypeId");
                    mount.DisplayID = db2File.ReadUInt32("DisplayId");
                    mount.Flags = db2File.ReadUInt32("Flags");

                    ushort nameLength = db2File.ReadUInt16();
                    mount.Name = db2File.ReadWoWString("Name", nameLength);

                    ushort descriptionLength = db2File.ReadUInt16();
                    mount.Description = db2File.ReadWoWString("Description", descriptionLength);

                    ushort sourceDescriptionLength = db2File.ReadUInt16();
                    mount.SourceDescription = db2File.ReadWoWString("SourceDescription", sourceDescriptionLength);

                    mount.Source = db2File.ReadUInt32("Source");
                    mount.SpellID = db2File.ReadUInt32<SpellId>("SpellID");
                    mount.PlayerConditionID = db2File.ReadUInt32("PlayerConditionId");

                    Storage.Mounts.Add(mount, packet.TimeSpan);
                    break;
                }
                case DB2Hash.RulesetItemUpgrade:
                {
                    db2File.ReadUInt32("ID");
                    db2File.ReadUInt32("Item Upgrade Level");
                    db2File.ReadUInt32("Item Upgrade ID");
                    db2File.ReadUInt32<ItemId>("Item ID");
                    break;
                }
                case DB2Hash.Holidays:
                {
                    Holidays holiday = new Holidays();

                    holiday.ID = db2File.ReadUInt32("ID");

                    holiday.Duration = new uint?[10];
                    for (int i = 0; i < 10; i++)
                        holiday.Duration[i] = db2File.ReadUInt32("Duration", i);

                    holiday.Date = new uint?[16];
                    for (int i = 0; i < 16; i++)
                        holiday.Date[i] = db2File.ReadUInt32("Date", i);

                    holiday.Region = db2File.ReadUInt32("Region");
                    holiday.Looping = db2File.ReadUInt32("Looping");

                    holiday.CalendarFlags = new uint?[10];
                    for (int i = 0; i < 10; i++)
                        holiday.CalendarFlags[i] = db2File.ReadUInt32("CalendarFlags", i);

                    holiday.HolidayNameID = db2File.ReadUInt32("HolidayNameID");
                    holiday.HolidayDescriptionID = db2File.ReadUInt32("HolidayDescriptionID");

                    ushort textureFilenameLength = db2File.ReadUInt16();
                    holiday.TextureFilename = db2File.ReadWoWString("SourceDescription", textureFilenameLength);

                    holiday.Priority = db2File.ReadUInt32("Priority");
                    holiday.CalendarFilterType = db2File.ReadUInt32("CalendarFilterType");
                    holiday.Flags = db2File.ReadUInt32("Flags");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.HolidaysBag.Add(holiday, packet.TimeSpan);
                    break;
                }
                case DB2Hash.ItemAppearance:
                {
                    ItemAppearance itemAppearance = new ItemAppearance();

                    itemAppearance.ID = db2File.ReadUInt32("ID");

                    itemAppearance.DisplayID = db2File.ReadUInt32("Display ID");
                    itemAppearance.IconFileDataID = db2File.ReadUInt32("File Data ID");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.ItemAppearances.Add(itemAppearance, packet.TimeSpan);
                    break;
                }
                case DB2Hash.ItemBonus:
                {
                    ItemBonus itemBonus = new ItemBonus();

                    itemBonus.ID = db2File.ReadUInt32("ID");

                    itemBonus.BonusListID = db2File.ReadUInt32("Bonus List ID");
                    itemBonus.Type = db2File.ReadUInt32("Type");

                    itemBonus.Value = new uint?[2];
                    for (int i = 0; i < 2; i++)
                        itemBonus.Value[i] = db2File.ReadUInt32("Value", i);

                    itemBonus.Index = db2File.ReadUInt32("Index");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.ItemBonuses.Add(itemBonus, packet.TimeSpan);
                    break;
                }
                case DB2Hash.ItemBonusTreeNode:
                {
                    ItemBonusTreeNode itemBonusTreeNode = new ItemBonusTreeNode();
                    itemBonusTreeNode.ID = db2File.ReadUInt32("ID");

                    itemBonusTreeNode.BonusTreeID = db2File.ReadUInt32("BonusTreeID");
                    itemBonusTreeNode.BonusTreeModID = db2File.ReadUInt32("BonusTreeModID");
                    itemBonusTreeNode.SubTreeID = db2File.ReadUInt32("SubTreeID");
                    itemBonusTreeNode.BonusListID = db2File.ReadUInt32("BonusListID");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.ItemBonusTreeNodes.Add(itemBonusTreeNode, packet.TimeSpan);
                    break;
                }
                case DB2Hash.Item_sparse: // New structure - 6.0.2
                {
                    ItemSparse item = new ItemSparse();

                    item.ID = db2File.ReadUInt32<ItemId>("Item Sparse Entry");

                    item.Quality = db2File.ReadInt32E<ItemQuality>("Quality");
                    item.Flags1 = db2File.ReadUInt32E<ItemProtoFlags>("Flags1");
                    item.Flags2 = db2File.ReadInt32E<ItemFlagExtra>("Flags2");
                    item.Flags3 = db2File.ReadUInt32("Flags3");
                    item.Unk1 = db2File.ReadSingle("Unk430_1");
                    item.Unk2 = db2File.ReadSingle("Unk430_2");
                    item.BuyCount = db2File.ReadUInt32("Buy count");
                    item.BuyPrice = db2File.ReadUInt32("Buy Price");
                    item.SellPrice = db2File.ReadUInt32("Sell Price");
                    item.InventoryType = db2File.ReadInt32E<InventoryType>("Inventory Type");
                    item.AllowedClasses = db2File.ReadInt32E<ClassMask>("Allowed Classes");
                    item.AllowedRaces = db2File.ReadInt32E<RaceMask>("Allowed Races");
                    item.ItemLevel = db2File.ReadUInt32("Item Level");
                    item.RequiredLevel = db2File.ReadUInt32("Required Level");
                    item.RequiredSkill = db2File.ReadUInt32("Required Skill");
                    item.RequiredSkillRank = db2File.ReadUInt32("Required Skill Rank");
                    item.RequiredSpell = db2File.ReadUInt32<SpellId>("Required Spell");
                    item.RequiredHonorRank = db2File.ReadUInt32("Required Honor Rank");
                    item.RequiredCityRank = db2File.ReadUInt32("Required City Rank");
                    item.RequiredReputationFaction = db2File.ReadUInt32("RequiredReputationFaction");
                    item.RequiredReputationRank = db2File.ReadUInt32("RequiredReputationRank");
                    item.MaxCount = db2File.ReadInt32("MaxCount");
                    item.Stackable = db2File.ReadInt32("Stackable");
                    item.ContainerSlots = db2File.ReadUInt32("ContainerSlots");

                    item.ItemStatType = new ItemModType?[10];
                    for (int i = 0; i < 10; i++)
                        item.ItemStatType[i] = db2File.ReadInt32E<ItemModType>("ItemStatType", i);

                    item.ItemStatValue = new int?[10];
                    for (int i = 0; i < 10; i++)
                        item.ItemStatValue[i] = db2File.ReadInt32("ItemStatValue", i);

                    item.ItemStatAllocation = new int?[10];
                    for (int i = 0; i < 10; i++)
                        item.ItemStatAllocation[i] = db2File.ReadInt32("ItemStatAllocation", i);

                    item.ItemStatSocketCostMultiplier = new float?[10];
                    for (int i = 0; i < 10; i++)
                        item.ItemStatSocketCostMultiplier[i] = db2File.ReadSingle("ItemStatSocketCostMultiplier", i);

                    item.ScalingStatDistribution = db2File.ReadInt32("ScalingStatDistribution");
                    item.DamageType = db2File.ReadInt32E<DamageType>("DamageType");
                    item.Delay = db2File.ReadUInt32("Delay");
                    item.RangedModRange = db2File.ReadSingle("RangedModRange");
                    item.Bonding = db2File.ReadInt32E<ItemBonding>("Bonding");

                    ushort nameLength = db2File.ReadUInt16();
                    item.Name = db2File.ReadWoWString("Name", nameLength);

                    ushort nameLength2 = db2File.ReadUInt16();
                    item.Name2 = db2File.ReadWoWString("Name2", nameLength2);

                    ushort nameLength3 = db2File.ReadUInt16();
                    item.Name3 = db2File.ReadWoWString("Name3", nameLength3);

                    ushort nameLength4 = db2File.ReadUInt16();
                    item.Name4 = db2File.ReadWoWString("Name4", nameLength4);

                    ushort descriptionLength = db2File.ReadUInt16();
                    item.Description = db2File.ReadWoWString("Description", descriptionLength);

                    item.PageText = db2File.ReadUInt32("PageText");
                    item.LanguageID = db2File.ReadInt32E<Language>("LanguageID");
                    item.PageMaterial = db2File.ReadInt32E<PageMaterial>("PageMaterial");
                    item.StartQuest = db2File.ReadUInt32<QuestId>("StartQuest");
                    item.LockID = db2File.ReadUInt32("LockID");
                    item.Material = db2File.ReadInt32E<Material>("Material");
                    item.Sheath = db2File.ReadInt32E<SheathType>("Sheath");
                    item.RandomProperty = db2File.ReadInt32("RandomProperty");
                    item.RandomSuffix = db2File.ReadUInt32("Random Suffix");
                    item.ItemSet = db2File.ReadUInt32("Item Set");
                    item.Area = db2File.ReadUInt32<AreaId>("Area");
                    item.Map = db2File.ReadInt32<MapId>("Map");
                    item.BagFamily = db2File.ReadInt32E<BagFamilyMask>("BagFamily");
                    item.TotemCategory = db2File.ReadInt32E<TotemCategory>("TotemCategory");

                    item.SocketColor = new ItemSocketColor?[3];
                    for (int i = 0; i < 3; i++)
                        item.SocketColor[i] = db2File.ReadInt32E<ItemSocketColor>("SocketColor", i);

                    item.SocketBonus = db2File.ReadInt32("SocketBonus");
                    item.GemProperties = db2File.ReadInt32("GemProperties");
                    item.ArmorDamageModifier = db2File.ReadSingle("ArmorDamageModifier");
                    item.Duration = db2File.ReadUInt32("Duration");
                    item.ItemLimitCategory = db2File.ReadInt32("LimitCategory");
                    item.HolidayID = db2File.ReadInt32E<Holiday>("HolidayID");
                    item.StatScalingFactor = db2File.ReadSingle("StatScalingFactor");
                    item.CurrencySubstitutionID = db2File.ReadUInt32("CurrencySubstitutionID");
                    item.CurrencySubstitutionCount = db2File.ReadUInt32("CurrencySubstitutionCount");
                    item.ItemNameDescriptionID = db2File.ReadUInt32("ItemNameDescriptionID");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.ItemSparses.Add(item, packet.TimeSpan);

                    Storage.ObjectNames.Add(new ObjectName {ObjectType = ObjectType.Item, ID = (int)entry, Name = item.Name}, packet.TimeSpan);
                    packet.AddSniffData(StoreNameType.Item, (int) entry, "DB_REPLY");
                    break;
                }
                case DB2Hash.KeyChain:
                {
                    KeyChain key = new KeyChain();

                    key.ID = db2File.ReadUInt32("ID");

                    key.Key = new byte?[32];
                    for (int i = 0; i < 32; i++)
                        key.Key[i] = db2File.ReadByte("Key", i);

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.KeyChains.Add(key, packet.TimeSpan);
                    break;
                }
                case DB2Hash.SceneScript: // lua ftw!
                {
                    SceneScript sceneScript = new SceneScript();

                    sceneScript.ID = db2File.ReadUInt32("SceneScriptID");

                    ushort nameLength = db2File.ReadUInt16();
                    sceneScript.Name = db2File.ReadWoWString("Name", nameLength);

                    ushort scriptLength = db2File.ReadUInt16();
                    sceneScript.Script = db2File.ReadWoWString("Script", scriptLength);

                    sceneScript.PreviousSceneScriptPart = db2File.ReadUInt32("PreviousSceneScriptPart");
                    sceneScript.NextSceneScriptPart = db2File.ReadUInt32("NextSceneScriptPart");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.SceneScripts.Add(sceneScript, packet.TimeSpan);
                    break;
                }
                case DB2Hash.SpellMisc: // New structure - 6.0.2
                {
                    SpellMisc spellMisc = new SpellMisc();

                    spellMisc.ID = (uint)db2File.ReadEntry("ID").Key;

                    spellMisc.Attributes = db2File.ReadUInt32("Attributes");
                    spellMisc.AttributesEx = db2File.ReadUInt32("AttributesEx");
                    spellMisc.AttributesExB = db2File.ReadUInt32("AttributesExB");
                    spellMisc.AttributesExC = db2File.ReadUInt32("AttributesExC");
                    spellMisc.AttributesExD = db2File.ReadUInt32("AttributesExD");
                    spellMisc.AttributesExE = db2File.ReadUInt32("AttributesExE");
                    spellMisc.AttributesExF = db2File.ReadUInt32("AttributesExF");
                    spellMisc.AttributesExG = db2File.ReadUInt32("AttributesExG");
                    spellMisc.AttributesExH = db2File.ReadUInt32("AttributesExH");
                    spellMisc.AttributesExI = db2File.ReadUInt32("AttributesExI");
                    spellMisc.AttributesExJ = db2File.ReadUInt32("AttributesExJ");
                    spellMisc.AttributesExK = db2File.ReadUInt32("AttributesExK");
                    spellMisc.AttributesExL = db2File.ReadUInt32("AttributesExL");
                    spellMisc.AttributesExM = db2File.ReadUInt32("AttributesExM");
                    spellMisc.CastingTimeIndex = db2File.ReadUInt32("CastingTimeIndex");
                    spellMisc.DurationIndex = db2File.ReadUInt32("DurationIndex");
                    spellMisc.RangeIndex = db2File.ReadUInt32("RangeIndex");
                    spellMisc.Speed = db2File.ReadSingle("Speed");

                    if (ClientVersion.RemovedInVersion(ClientVersionBuild.V6_2_0_20173))
                    {
                        for (int i = 0; i < 2; ++i)
                            db2File.ReadUInt32("SpellVisualID", i);
                    }

                    spellMisc.SpellIconID = db2File.ReadUInt32("SpellIconID");
                    spellMisc.ActiveIconID = db2File.ReadUInt32("ActiveIconID");
                    spellMisc.SchoolMask = db2File.ReadUInt32("SchoolMask");
                    spellMisc.MultistrikeSpeedMod = db2File.ReadSingle("MultistrikeSpeedMod");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.SpellMiscs.Add(spellMisc, packet.TimeSpan);
                    break;
                }
                case DB2Hash.SpellAuraRestrictions:
                {
                    SpellAuraRestrictions spellAuraRestrictions = new SpellAuraRestrictions();

                    spellAuraRestrictions.ID = (uint)db2File.ReadEntry("ID").Key;

                    spellAuraRestrictions.CasterAuraState = db2File.ReadUInt32("CasterAuraState");
                    spellAuraRestrictions.TargetAuraState = db2File.ReadUInt32("TargetAuraState");
                    spellAuraRestrictions.ExcludeCasterAuraState = db2File.ReadUInt32("ExcludeCasterAuraState");
                    spellAuraRestrictions.ExcludeTargetAuraState = db2File.ReadUInt32("ExcludeTargetAuraState");
                    spellAuraRestrictions.CasterAuraSpell = db2File.ReadUInt32("CasterAuraSpell");
                    spellAuraRestrictions.TargetAuraSpell = db2File.ReadUInt32("TargetAuraSpell");
                    spellAuraRestrictions.ExcludeCasterAuraSpell = db2File.ReadUInt32("ExcludeCasterAuraSpell");
                    spellAuraRestrictions.ExcludeTargetAuraSpell = db2File.ReadUInt32("ExcludeTargetAuraSpell");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.SpellAuraRestrictionsBag.Add(spellAuraRestrictions, packet.TimeSpan);
                    break;
                }
                case DB2Hash.SpellCastingRequirements:
                {
                    SpellCastingRequirements spellCastingRequirements = new SpellCastingRequirements();

                    spellCastingRequirements.ID = (uint)db2File.ReadEntry("ID").Key;

                    spellCastingRequirements.FacingCasterFlags = db2File.ReadUInt32("FacingCasterFlags");
                    spellCastingRequirements.MinFactionID = db2File.ReadUInt32("MinFactionID");
                    spellCastingRequirements.MinReputation = db2File.ReadUInt32("MinReputation");
                    spellCastingRequirements.RequiredAreasID = db2File.ReadUInt32("RequiredAreasID");
                    spellCastingRequirements.RequiredAuraVision = db2File.ReadUInt32("RequiredAuraVision");
                    spellCastingRequirements.RequiresSpellFocus = db2File.ReadUInt32("RequiresSpellFocus");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.SpellCastingRequirementsBag.Add(spellCastingRequirements, packet.TimeSpan);
                    break;
                }
                case DB2Hash.SpellClassOptions:
                {
                    SpellClassOptions spellClassOptions = new SpellClassOptions();

                    spellClassOptions.ID = (uint)db2File.ReadEntry("ID").Key;

                    spellClassOptions.ModalNextSpell = db2File.ReadUInt32("ModalNextSpell");

                    spellClassOptions.SpellClassMask = new uint?[4];
                    for (int i = 0; i < 2; ++i)
                        spellClassOptions.SpellClassMask[i] = db2File.ReadUInt32("SpellClassMask", i);

                    spellClassOptions.SpellClassSet = db2File.ReadUInt32("SpellClassSet");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.SpellClassOptionsBag.Add(spellClassOptions, packet.TimeSpan);
                    break;
                }
                case DB2Hash.SpellEffectGroupSize:
                {
                    SpellEffectGroupSize spellEffectGroupSize = new SpellEffectGroupSize();

                    spellEffectGroupSize.ID = (uint)db2File.ReadEntry("ID").Key;

                    spellEffectGroupSize.SpellEffectID = db2File.ReadUInt32("SpellEffectID");
                    spellEffectGroupSize.Size = db2File.ReadSingle("Size");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.SpellEffectGroupSizes.Add(spellEffectGroupSize, packet.TimeSpan);
                    break;
                }
                case DB2Hash.SpellLearnSpell:
                {
                    SpellLearnSpell spellLearnSpell = new SpellLearnSpell();

                    spellLearnSpell.ID = (uint)db2File.ReadEntry("ID").Key;

                    spellLearnSpell.LearnSpellID = db2File.ReadUInt32("LearnSpellID");
                    spellLearnSpell.SpellID = db2File.ReadUInt32<SpellId>("SpellID");
                    spellLearnSpell.OverridesSpellID = db2File.ReadUInt32("OverridesSpellID");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.SpellLearnSpells.Add(spellLearnSpell, packet.TimeSpan);
                    break;
                }
                case DB2Hash.SpellTotems:
                {
                    SpellTotems spellTotems = new SpellTotems();

                    spellTotems.ID = (uint)db2File.ReadEntry("ID").Key;

                    spellTotems.RequiredTotemCategoryID = new uint?[2];
                    for (int i = 0; i < 2; ++i)
                        spellTotems.RequiredTotemCategoryID[i] = db2File.ReadUInt32("RequiredTotemCategoryID", i);

                    spellTotems.Totem = new uint?[2];
                    for (int i = 0; i < 2; ++i)
                        spellTotems.Totem[i] = db2File.ReadUInt32("Totem", i);

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.SpellTotemsBag.Add(spellTotems, packet.TimeSpan);
                    break;
                }
                case DB2Hash.SpellPower:
                {
                    SpellPower spellPower = new SpellPower();

                    spellPower.ID = (uint)db2File.ReadEntry("ID").Key;

                    spellPower.SpellID = db2File.ReadUInt32<SpellId>("SpellID");
                    spellPower.PowerIndex = db2File.ReadUInt32("PowerIndex");
                    spellPower.ManaCost = db2File.ReadUInt32("ManaCost");
                    spellPower.ManaCostPerLevel = db2File.ReadUInt32("ManaCostPerLevel");
                    spellPower.ManaCostPerSecond = db2File.ReadUInt32("ManaCostPerSecond");
                    spellPower.ManaCostAdditional = db2File.ReadUInt32("ManaCostAdditional");
                    spellPower.PowerDisplayID = db2File.ReadUInt32("PowerDisplayID");
                    spellPower.UnitPowerBarID = db2File.ReadUInt32("UnitPowerBarID");

                    spellPower.ManaCostPercentage = db2File.ReadSingle("UnitPowerBarID");
                    spellPower.ManaCostPercentagePerSecond = db2File.ReadSingle("UnitPowerBarID");

                    spellPower.RequiredAura = db2File.ReadUInt32("RequiredAura");

                    spellPower.HealthCostPercentage = db2File.ReadSingle("HealthCostPercentage");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.SpellPowers.Add(spellPower, packet.TimeSpan);
                    break;
                }
                case DB2Hash.SpellReagents:
                {
                    SpellReagents spellReagents = new SpellReagents();

                    spellReagents.ID = (uint)db2File.ReadEntry("ID").Key;

                    spellReagents.Reagent = new int?[8];
                    for (int i = 0; i < 2; ++i)
                        spellReagents.Reagent[i] = db2File.ReadInt32("Reagent", i);

                    spellReagents.ReagentCount = new uint?[8];
                    for (int i = 0; i < 2; ++i)
                        spellReagents.ReagentCount[i] = db2File.ReadUInt32("ReagentCount", i);

                    spellReagents.CurrencyID = db2File.ReadUInt32("CurrencyID");
                    spellReagents.CurrencyCount = db2File.ReadUInt32("CurrencyCount");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.SpellReagentsBag.Add(spellReagents, packet.TimeSpan);
                    break;
                }
                case DB2Hash.SpellRuneCost:
                {
                    SpellRuneCost spellRuneCost = new SpellRuneCost();

                    spellRuneCost.ID = (uint)db2File.ReadEntry("ID").Key;

                    spellRuneCost.Blood = db2File.ReadUInt32("Blood");
                    spellRuneCost.Unholy = db2File.ReadUInt32("Unholy");
                    spellRuneCost.Frost = db2File.ReadUInt32("Frost");
                    spellRuneCost.Chromatic = db2File.ReadUInt32("Chromatic");
                    spellRuneCost.RunicPower = db2File.ReadUInt32("RunicPower");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.SpellRuneCosts.Add(spellRuneCost, packet.TimeSpan);
                    break;
                }
                case DB2Hash.Toy: // New structure - 6.0.2
                {
                    Toy toy = new Toy();

                    toy.ID = db2File.ReadUInt32("ID");

                    toy.ItemID = db2File.ReadUInt32<ItemId>("ItemID");
                    toy.Flags = db2File.ReadUInt32("Flags");

                    ushort descriptionLength = db2File.ReadUInt16();
                    toy.Description = db2File.ReadWoWString("Description", descriptionLength);

                    toy.SourceType = db2File.ReadInt32("SourceType");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.Toys.Add(toy, packet.TimeSpan);
                    break;
                }
                case DB2Hash.Vignette:
                {
                    db2File.ReadUInt32("ID");
                    ushort nameLength = db2File.ReadUInt16();
                    db2File.ReadWoWString("Name", nameLength);

                    db2File.ReadUInt32("Icon");
                    db2File.ReadUInt32("Flag"); // not 100% sure (8 & 32 as values only) - todo verify with more data
                    db2File.ReadSingle("Unk Float 1");
                    db2File.ReadSingle("Unk Float 2");
                    break;
                }
                case DB2Hash.WbAccessControlList:
                {
                    db2File.ReadUInt32("Id");

                    ushort addressLength = db2File.ReadUInt16();
                    db2File.ReadWoWString("Address", addressLength);

                    db2File.ReadUInt32("Unk MoP 1");
                    db2File.ReadUInt32("Unk MoP 2");
                    db2File.ReadUInt32("Unk MoP 3");
                    db2File.ReadUInt32("Unk MoP 4"); // flags?
                    break;
                }
                case DB2Hash.AreaPOI:
                {
                    AreaPOI areaPOI = new AreaPOI();

                    areaPOI.ID = db2File.ReadUInt32("Id");

                    areaPOI.Flags = db2File.ReadUInt32("Flags");
                    areaPOI.Importance = db2File.ReadUInt32("Importance");
                    areaPOI.FactionID = db2File.ReadUInt32("FactionID");
                    areaPOI.MapID = db2File.ReadUInt32("MapID");
                    areaPOI.AreaID = db2File.ReadUInt32("AreaID");
                    areaPOI.Icon = db2File.ReadUInt32("Icon");

                    areaPOI.PositionX = db2File.ReadSingle("PositionX");
                    areaPOI.PositionY = db2File.ReadSingle("PositionY");

                    ushort len1 = db2File.ReadUInt16();
                    areaPOI.Name = db2File.ReadWoWString("Name", len1);

                    ushort len2 = db2File.ReadUInt16();
                    areaPOI.Description = db2File.ReadWoWString("Description", len2);

                    areaPOI.WorldStateID = db2File.ReadUInt32("WorldStateID");
                    areaPOI.PlayerConditionID = db2File.ReadUInt32("PlayerConditionID");
                    areaPOI.WorldMapLink = db2File.ReadUInt32("WorldMapLink");
                    areaPOI.PortLocID = db2File.ReadUInt32("PortLocID");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.AreaPOIs.Add(areaPOI, packet.TimeSpan);
                    break;
                }
                case DB2Hash.AreaPOIState:
                {
                    AreaPOIState areaPOIState = new AreaPOIState();

                    areaPOIState.ID = db2File.ReadUInt32("Id");

                    areaPOIState.AreaPoiID = db2File.ReadUInt32("AreaPOIID");
                    areaPOIState.State = db2File.ReadUInt32("State");
                    areaPOIState.Icon = db2File.ReadUInt32("Icon");

                    ushort len2 = db2File.ReadUInt16();
                    areaPOIState.Description = db2File.ReadWoWString("Description", len2);

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.AreaPOIStates.Add(areaPOIState, packet.TimeSpan);
                    break;
                }
                case DB2Hash.TaxiNodes:
                {
                    TaxiNodes taxiNodes = new TaxiNodes();

                    taxiNodes.ID = db2File.ReadUInt32("Id");

                    taxiNodes.MapID = db2File.ReadUInt32("MapID");

                    taxiNodes.PosX = db2File.ReadSingle("PosX");
                    taxiNodes.PosY = db2File.ReadSingle("PosY");
                    taxiNodes.PosZ = db2File.ReadSingle("PosZ");

                    short len = db2File.ReadInt16();
                    taxiNodes.Name = db2File.ReadWoWString("Name", len);

                    taxiNodes.MountCreatureID = new uint?[2];
                    for (int i = 0; i < 2; ++i)
                        taxiNodes.MountCreatureID[i] = db2File.ReadUInt32("MountCreatureID", i);

                    taxiNodes.ConditionID = db2File.ReadUInt32("ConditionID");
                    taxiNodes.LearnableIndex = db2File.ReadUInt32("LearnableIndex");
                    taxiNodes.Flags = db2File.ReadUInt32("Flags");

                    taxiNodes.MapOffsetX = db2File.ReadSingle("MapOffsetX");
                    taxiNodes.MapOffsetY = db2File.ReadSingle("MapOffsetY");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.TaxiNodesBag.Add(taxiNodes, packet.TimeSpan);
                    break;
                }
                case DB2Hash.TaxiPathNode:
                {
                    TaxiPathNode taxiPathNode = new TaxiPathNode();

                    taxiPathNode.ID = db2File.ReadUInt32("Id");

                    taxiPathNode.PathID = db2File.ReadUInt32("PathID");
                    taxiPathNode.NodeIndex = db2File.ReadUInt32("NodeIndex");
                    taxiPathNode.MapID = db2File.ReadUInt32("MapID");

                    taxiPathNode.LocX = db2File.ReadSingle("LocX");
                    taxiPathNode.LocY = db2File.ReadSingle("LocY");
                    taxiPathNode.LocZ = db2File.ReadSingle("LocZ");

                    taxiPathNode.Flags = db2File.ReadUInt32("Flags");
                    taxiPathNode.Delay = db2File.ReadUInt32("Delay");
                    taxiPathNode.ArrivalEventID = db2File.ReadUInt32("ArrivalEventID");
                    taxiPathNode.DepartureEventID = db2File.ReadUInt32("DepartureEventID");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.TaxiPathNodes.Add(taxiPathNode, packet.TimeSpan);
                    break;
                }
                case DB2Hash.TaxiPath:
                {
                    TaxiPath taxiPath = new TaxiPath();

                    taxiPath.ID = db2File.ReadUInt32("Id");

                    taxiPath.From = db2File.ReadUInt32("From");
                    taxiPath.To = db2File.ReadUInt32("To");
                    taxiPath.Cost = db2File.ReadUInt32("Cost");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.TaxiPaths.Add(taxiPath, packet.TimeSpan);
                    break;
                }
                case DB2Hash.Location:
                {
                    Location location = new Location();

                    location.ID = db2File.ReadUInt32("Id");

                    location.LocX = db2File.ReadSingle("LocX");
                    location.LocY = db2File.ReadSingle("LocY");
                    location.LocZ = db2File.ReadSingle("LocZ");

                    location.Rotation = new float?[3];
                    for (int i = 0; i < 3; ++i)
                        location.Rotation[i] = db2File.ReadSingle("Rotation", i);

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.Locations.Add(location, packet.TimeSpan);
                    break;
                }
                case DB2Hash.ChrUpgradeTier:
                {
                    ChrUpgradeTier chrUpgradeTier = new ChrUpgradeTier();

                    chrUpgradeTier.ID = (uint)db2File.ReadEntry("Id").Key;

                    chrUpgradeTier.TierIndex = db2File.ReadUInt32("TierIndex");

                    ushort len = db2File.ReadUInt16();
                    chrUpgradeTier.Name = db2File.ReadWoWString("Name", len);

                    chrUpgradeTier.TalentTier = db2File.ReadUInt32("TalentTier");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.ChrUpgradeTiers.Add(chrUpgradeTier, packet.TimeSpan);
                    break;
                }
                case DB2Hash.ChrUpgradeBucket:
                {
                    ChrUpgradeBucket chrUpgradeBucket = new ChrUpgradeBucket();

                    chrUpgradeBucket.ID = (uint)db2File.ReadEntry("Id").Key;

                    chrUpgradeBucket.TierID = db2File.ReadUInt32("TierID");
                    chrUpgradeBucket.SpecializationID = db2File.ReadUInt32("SpecializationID");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.ChrUpgradeBuckets.Add(chrUpgradeBucket, packet.TimeSpan);
                    break;
                }
                case DB2Hash.ChrUpgradeBucketSpell:
                {
                    ChrUpgradeBucketSpell chrUpgradeBucketSpell = new ChrUpgradeBucketSpell();

                    chrUpgradeBucketSpell.ID = (uint)db2File.ReadEntry("Id").Key;

                    chrUpgradeBucketSpell.BucketID = db2File.ReadUInt32("BucketID");
                    chrUpgradeBucketSpell.SpellID = db2File.ReadUInt32<SpellId>("SpellID");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.ChrUpgradeBucketSpells.Add(chrUpgradeBucketSpell, packet.TimeSpan);
                    break;
                }
                case DB2Hash.BattlePetSpecies:
                {
                    BattlePetSpecies battlePetSpecies = new BattlePetSpecies();

                    battlePetSpecies.ID = (uint)db2File.ReadEntry("Id").Key;

                    battlePetSpecies.CreatureID = db2File.ReadUInt32("CreatureID");
                    battlePetSpecies.IconFileID = db2File.ReadUInt32("IconFileID");
                    battlePetSpecies.SummonSpellID = db2File.ReadUInt32("SummonSpellID");
                    battlePetSpecies.PetType = db2File.ReadInt32("PetType");
                    battlePetSpecies.Source = db2File.ReadUInt32("Source");
                    battlePetSpecies.Flags = db2File.ReadUInt32("Flags");

                    ushort len1 = db2File.ReadUInt16();
                    battlePetSpecies.SourceText = db2File.ReadWoWString("SourceText", len1);

                    ushort len2 = db2File.ReadUInt16();
                    battlePetSpecies.Description = db2File.ReadWoWString("Description", len2);

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.BattlePetSpeciesBag.Add(battlePetSpecies, packet.TimeSpan);
                    break;
                }
                case DB2Hash.OverrideSpellData:
                {
                    OverrideSpellData overrideSpellData = new OverrideSpellData();

                    overrideSpellData.ID = db2File.ReadUInt32("Id");

                    overrideSpellData.SpellID = new uint?[10];
                    for (int i = 0; i < 10; ++i)
                        overrideSpellData.SpellID[i] = db2File.ReadUInt32("SpellID", i);

                    overrideSpellData.Flags = db2File.ReadUInt32("Flags");
                    overrideSpellData.PlayerActionbarFileDataID = db2File.ReadUInt32("PlayerActionbarFileDataID");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.OverrideSpellDatas.Add(overrideSpellData, packet.TimeSpan);
                    break;
                }
                case DB2Hash.PhaseXPhaseGroup:
                {
                    PhaseXPhaseGroup phaseXPhaseGroup = new PhaseXPhaseGroup();

                    phaseXPhaseGroup.ID = db2File.ReadUInt32("Id");

                    phaseXPhaseGroup.PhaseID = db2File.ReadUInt32("PhaseID");
                    phaseXPhaseGroup.PhaseGroupID = db2File.ReadUInt32("PhaseGroupID");

                    if (Storage.HotfixDataStore.ContainsKey(Tuple.Create(type, (int)entry)) && Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data) ||
                        !Settings.HotfixSQLOutputFlag.HasAnyFlagBit(HotfixSQLOutput.hotfix_data))
                        Storage.PhaseXPhaseGroups.Add(phaseXPhaseGroup, packet.TimeSpan);
                    break;
                }
                default:
                {
                    db2File.AddValue("Unknown DB2 file type", string.Format("{0} (0x{0:x})", type));
                    for (int i = 0;; ++i)
                    {
                        if (db2File.Length - 4 >= db2File.Position)
                        {
                            UpdateField blockVal = db2File.ReadUpdateField();
                            string key = "Block Value " + i;
                            string value = blockVal.UInt32Value + "/" + blockVal.SingleValue;
                            packet.AddValue(key, value);
                        }
                        else
                        {
                            long left = db2File.Length - db2File.Position;
                            for (int j = 0; j < left; ++j)
                            {
                                string key = "Byte Value " + i;
                                byte value = db2File.ReadByte();
                                packet.AddValue(key, value);
                            }
                            break;
                        }
                    }
                    break;
                }
            }

            if (db2File.Length != db2File.Position)
            {
                packet.WriteLine(
                    $"Packet not fully read! Current position is {db2File.Position}, length is {db2File.Length}, and diff is {db2File.Length - db2File.Position}.");

                if (db2File.Length < 300) // If the packet isn't "too big" and it is not full read, print its hex table
                    packet.AsHex();

                packet.Status = ParsedStatus.WithErrors;
            }
        }
        public static void HandleDBReply(Packet packet)
        {
            var entry = (uint)packet.ReadInt32("Entry");
            packet.ReadTime("Hotfix date");
            var type = packet.ReadEnum<DB2Hash>("DB2 File", TypeCode.UInt32);

            var size = packet.ReadInt32("Size");
            var data = packet.ReadBytes(size);
            var db2File = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);

            if ((int)entry < 0)
            {
                packet.WriteLine("Row {0} has been removed.", -(int)entry);
                return;
            }

            switch (type)
            {
                case DB2Hash.BroadcastText:
                {
                    var broadcastText = new BroadcastText();

                    var Id = db2File.ReadEntry("Id");
                    broadcastText.language = db2File.ReadUInt32("Language");
                    if (db2File.ReadUInt16() > 0)
                        broadcastText.MaleText = db2File.ReadCString("Male Text");
                    if (db2File.ReadUInt16() > 0)
                        broadcastText.FemaleText = db2File.ReadCString("Female Text");

                    broadcastText.EmoteID = new uint[3];
                    broadcastText.EmoteDelay = new uint[3];
                    for (var i = 0; i < 3; ++i)
                        broadcastText.EmoteID[i] = (uint) db2File.ReadInt32("Emote ID", i);
                    for (var i = 0; i < 3; ++i)
                        broadcastText.EmoteDelay[i] = (uint) db2File.ReadInt32("Emote Delay", i);

                    broadcastText.soundId = db2File.ReadUInt32("Sound Id");
                    broadcastText.unk1 = db2File.ReadUInt32("Unk MoP 1"); // unk emote
                    broadcastText.unk2 = db2File.ReadUInt32("Unk MoP 2"); // kind of type?

                    Storage.BroadcastTexts.Add((uint) Id.Key, broadcastText, packet.TimeSpan);
                    packet.AddSniffData(StoreNameType.BroadcastText, Id.Key, "BROADCAST_TEXT");
                    break;
                }
                case DB2Hash.Creature: // New structure - 5.4.0
                {
                    db2File.ReadUInt32("Creature Id");
                    db2File.ReadUInt32("Item Id 1");
                    db2File.ReadUInt32("Item Id 2");
                    db2File.ReadUInt32("Item Id 3");
                    db2File.ReadUInt32("Mount");
                    for (var i = 0; i < 4; ++i)
                        db2File.ReadInt32("Display Id", i);

                    for (var i = 0; i < 4; ++i)
                        db2File.ReadSingle("Display Id Probability", i);

                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Name");

                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("SubName");

                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Female SubName");

                    db2File.ReadUInt32("Rank");
                    db2File.ReadUInt32("Inhabit Type");
                    break;
                }
                case DB2Hash.CreatureDifficulty:
                {
                    var creatureDifficulty = new CreatureDifficulty();

                    db2File.ReadUInt32("Id");
                    var Id = db2File.ReadEntry("Creature Id");
                    creatureDifficulty.faction = db2File.ReadUInt32("Faction Template Id");
                    creatureDifficulty.Expansion = db2File.ReadInt32("Expansion");
                    creatureDifficulty.MinLevel = db2File.ReadInt32("Min Level");
                    creatureDifficulty.MaxLevel = db2File.ReadInt32("Max Level");
                    db2File.ReadUInt32("Unk MoP 1");
                    db2File.ReadUInt32("Unk MoP 2");
                    db2File.ReadUInt32("Unk MoP 3");
                    db2File.ReadUInt32("Unk MoP 4");
                    db2File.ReadUInt32("Unk MoP 5");

                    Storage.CreatureDifficultys.Add((uint) Id.Key, creatureDifficulty, packet.TimeSpan);
                    break;
                }
                case DB2Hash.GameObjects:
                {
                    var gameObjectTemplateDB2 = new GameObjectTemplateDB2();
                    var gameObjectTemplatePositionDB2 = new GameObjectTemplatePositionDB2();

                    var Id = db2File.ReadEntry("GameObject Id");

                    gameObjectTemplatePositionDB2.map = db2File.ReadUInt32("Map");

                    gameObjectTemplateDB2.DisplayId = db2File.ReadUInt32("Display Id");

                    gameObjectTemplatePositionDB2.positionX = db2File.ReadSingle("Position X");
                    gameObjectTemplatePositionDB2.positionY = db2File.ReadSingle("Position Y");
                    gameObjectTemplatePositionDB2.positionZ = db2File.ReadSingle("Position Z");
                    gameObjectTemplatePositionDB2.rotationX = db2File.ReadSingle("Rotation X");
                    gameObjectTemplatePositionDB2.rotationY = db2File.ReadSingle("Rotation Y");
                    gameObjectTemplatePositionDB2.rotationZ = db2File.ReadSingle("Rotation Z");
                    gameObjectTemplatePositionDB2.rotationW = db2File.ReadSingle("Rotation W");

                    gameObjectTemplateDB2.Size = db2File.ReadSingle("Size");
                    gameObjectTemplateDB2.Type = db2File.ReadEnum<GameObjectType>("Type", TypeCode.Int32);

                    gameObjectTemplateDB2.Data = new int[4];
                    for (var i = 0; i < gameObjectTemplateDB2.Data.Length; i++)
                        gameObjectTemplateDB2.Data[i] = db2File.ReadInt32("Data", i);

                    if (db2File.ReadUInt16() > 0)
                        gameObjectTemplateDB2.Name = db2File.ReadCString("Name");

                    Storage.GameObjectTemplateDB2s.Add((uint) Id.Key, gameObjectTemplateDB2, packet.TimeSpan);
                    if (gameObjectTemplatePositionDB2.positionX != 0.0f &&
                        gameObjectTemplatePositionDB2.positionY != 0.0f &&
                        gameObjectTemplatePositionDB2.positionZ != 0.0f)
                        Storage.GameObjectTemplatePositionDB2s.Add((uint) Id.Key, gameObjectTemplatePositionDB2,
                            packet.TimeSpan);
                    break;
                }
                case DB2Hash.Item:
                {
                    var item = Storage.ItemTemplates.ContainsKey(entry)
                        ? Storage.ItemTemplates[entry].Item1
                        : new ItemTemplate();

                    db2File.ReadEntryWithName<UInt32>(StoreNameType.Item, "Item Entry");
                    item.Class = db2File.ReadEnum<ItemClass>("Class", TypeCode.Int32);
                    item.SubClass = db2File.ReadUInt32("Sub Class");
                    item.SoundOverrideSubclass = db2File.ReadInt32("Sound Override Subclass");
                    item.Material = db2File.ReadEnum<Material>("Material", TypeCode.Int32);
                    item.DisplayId = db2File.ReadUInt32("Display ID");
                    item.InventoryType = db2File.ReadEnum<InventoryType>("Inventory Type", TypeCode.UInt32);
                    item.SheathType = db2File.ReadEnum<SheathType>("Sheath Type", TypeCode.Int32);

                    Storage.ItemTemplates.Add(entry, item, packet.TimeSpan);
                    packet.AddSniffData(StoreNameType.Item, (int) entry, "DB_REPLY");
                    break;
                }
                case DB2Hash.ItemExtendedCost:
                {
                    db2File.ReadUInt32("Item Extended Cost Entry");
                    db2File.ReadUInt32("Required Honor Points");
                    db2File.ReadUInt32("Required Arena Points");
                    db2File.ReadUInt32("Required Arena Slot");
                    for (var i = 0; i < 5; ++i)
                        db2File.ReadUInt32("Required Item", i);

                    for (var i = 0; i < 5; ++i)
                        db2File.ReadUInt32("Required Item Count", i);

                    db2File.ReadUInt32("Required Personal Arena Rating");
                    db2File.ReadUInt32("Item Purchase Group");
                    for (var i = 0; i < 5; ++i)
                        db2File.ReadUInt32("Required Currency", i);

                    for (var i = 0; i < 5; ++i)
                        db2File.ReadUInt32("Required Currency Count", i);

                    db2File.ReadUInt32("Required Faction Id");
                    db2File.ReadUInt32("Required Faction Standing");
                    db2File.ReadUInt32("Requirement Flags");
                    db2File.ReadUInt32("Required Guild Level");
                    db2File.ReadUInt32("Required Achievement");
                    break;
                }
                case DB2Hash.ItemCurrencyCost:
                {
                    db2File.ReadUInt32("Id");
                    db2File.ReadEntryWithName<UInt32>(StoreNameType.Item, "Item Entry");
                    break;
                }
                case DB2Hash.RulesetItemUpgrade:
                {
                    db2File.ReadUInt32("Id");
                    db2File.ReadUInt32("Item Upgrade Level");
                    db2File.ReadUInt32("Item Upgrade Id");
                    db2File.ReadEntryWithName<UInt32>(StoreNameType.Item, "Item Entry");
                    break;
                }
                case DB2Hash.Item_sparse:
                {
                    var item = Storage.ItemTemplates.ContainsKey(entry)
                        ? Storage.ItemTemplates[entry].Item1
                        : new ItemTemplate();

                    db2File.ReadEntryWithName<UInt32>(StoreNameType.Item, "Item Sparse Entry");
                    item.Quality = db2File.ReadEnum<ItemQuality>("Quality", TypeCode.Int32);
                    item.Flags1 = db2File.ReadEnum<ItemProtoFlags>("Flags 1", TypeCode.UInt32);
                    item.Flags2 = db2File.ReadEnum<ItemFlagExtra>("Flags 2", TypeCode.Int32);
                    item.Flags3 = db2File.ReadUInt32("Flags 3");
                    item.Unk430_1 = db2File.ReadSingle("Unk430_1");
                    item.Unk430_2 = db2File.ReadSingle("Unk430_2");
                    item.BuyCount = db2File.ReadUInt32("Buy count");
                    item.BuyPrice = db2File.ReadUInt32("Buy Price");
                    item.SellPrice = db2File.ReadUInt32("Sell Price");
                    item.InventoryType = db2File.ReadEnum<InventoryType>("Inventory Type", TypeCode.Int32);
                    item.AllowedClasses = db2File.ReadEnum<ClassMask>("Allowed Classes", TypeCode.Int32);
                    item.AllowedRaces = db2File.ReadEnum<RaceMask>("Allowed Races", TypeCode.Int32);
                    item.ItemLevel = db2File.ReadUInt32("Item Level");
                    item.RequiredLevel = db2File.ReadUInt32("Required Level");
                    item.RequiredSkillId = db2File.ReadUInt32("Required Skill ID");
                    item.RequiredSkillLevel = db2File.ReadUInt32("Required Skill Level");
                    item.RequiredSpell = (uint) db2File.ReadEntryWithName<Int32>(StoreNameType.Spell, "Required Spell");
                    item.RequiredHonorRank = db2File.ReadUInt32("Required Honor Rank");
                    item.RequiredCityRank = db2File.ReadUInt32("Required City Rank");
                    item.RequiredRepFaction = db2File.ReadUInt32("Required Rep Faction");
                    item.RequiredRepValue = db2File.ReadUInt32("Required Rep Value");
                    item.MaxCount = db2File.ReadInt32("Max Count");
                    item.MaxStackSize = db2File.ReadInt32("Max Stack Size");
                    item.ContainerSlots = db2File.ReadUInt32("Container Slots");

                    item.StatTypes = new ItemModType[10];
                    for (var i = 0; i < 10; i++)
                    {
                        var statType = db2File.ReadEnum<ItemModType>("Stat Type", TypeCode.Int32, i);
                        item.StatTypes[i] = statType == ItemModType.None ? ItemModType.Mana : statType; // TDB
                    }

                    item.StatValues = new int[10];
                    for (var i = 0; i < 10; i++)
                        item.StatValues[i] = db2File.ReadInt32("Stat Value", i);

                    item.StatUnk1 = new int[10];
                    for (var i = 0; i < 10; i++)
                        item.StatUnk1[i] = db2File.ReadInt32("Unk UInt32 1", i);

                    item.StatUnk2 = new int[10];
                    for (var i = 0; i < 10; i++)
                        item.StatUnk2[i] = db2File.ReadInt32("Unk UInt32 2", i);

                    item.ScalingStatDistribution = db2File.ReadInt32("Scaling Stat Distribution");
                    item.DamageType = db2File.ReadEnum<DamageType>("Damage Type", TypeCode.Int32);
                    item.Delay = db2File.ReadUInt32("Delay");
                    item.RangedMod = db2File.ReadSingle("Ranged Mod");

                    item.TriggeredSpellIds = new int[5];
                    for (var i = 0; i < 5; i++)
                        item.TriggeredSpellIds[i] = db2File.ReadEntryWithName<Int32>(StoreNameType.Spell,
                            "Triggered Spell ID", i);

                    item.TriggeredSpellTypes = new ItemSpellTriggerType[5];
                    for (var i = 0; i < 5; i++)
                        item.TriggeredSpellTypes[i] = db2File.ReadEnum<ItemSpellTriggerType>("Trigger Spell Type",
                            TypeCode.Int32, i);

                    item.TriggeredSpellCharges = new int[5];
                    for (var i = 0; i < 5; i++)
                        item.TriggeredSpellCharges[i] = db2File.ReadInt32("Triggered Spell Charges", i);

                    item.TriggeredSpellCooldowns = new int[5];
                    for (var i = 0; i < 5; i++)
                        item.TriggeredSpellCooldowns[i] = db2File.ReadInt32("Triggered Spell Cooldown", i);

                    item.TriggeredSpellCategories = new uint[5];
                    for (var i = 0; i < 5; i++)
                        item.TriggeredSpellCategories[i] = db2File.ReadUInt32("Triggered Spell Category", i);

                    item.TriggeredSpellCategoryCooldowns = new int[5];
                    for (var i = 0; i < 5; i++)
                        item.TriggeredSpellCategoryCooldowns[i] = db2File.ReadInt32(
                            "Triggered Spell Category Cooldown", i);

                    item.Bonding = db2File.ReadEnum<ItemBonding>("Bonding", TypeCode.Int32);

                    if (db2File.ReadUInt16() > 0)
                        item.Name = db2File.ReadCString("Name", 0);

                    for (var i = 1; i < 4; ++i)
                        if (db2File.ReadUInt16() > 0)
                            db2File.ReadCString("Name", i);

                    if (db2File.ReadUInt16() > 0)
                        item.Description = db2File.ReadCString("Description");

                    item.PageText = db2File.ReadUInt32("Page Text");
                    item.Language = db2File.ReadEnum<Language>("Language", TypeCode.Int32);
                    item.PageMaterial = db2File.ReadEnum<PageMaterial>("Page Material", TypeCode.Int32);
                    item.StartQuestId = (uint) db2File.ReadEntryWithName<Int32>(StoreNameType.Quest, "Start Quest");
                    item.LockId = db2File.ReadUInt32("Lock ID");
                    item.Material = db2File.ReadEnum<Material>("Material", TypeCode.Int32);
                    item.SheathType = db2File.ReadEnum<SheathType>("Sheath Type", TypeCode.Int32);
                    item.RandomPropery = db2File.ReadInt32("Random Property");
                    item.RandomSuffix = db2File.ReadUInt32("Random Suffix");
                    item.ItemSet = db2File.ReadUInt32("Item Set");
                    item.AreaId = (uint) db2File.ReadEntryWithName<UInt32>(StoreNameType.Area, "Area");
                    // In this single (?) case, map 0 means no map
                    var map = db2File.ReadInt32();
                    item.MapId = map;
                    db2File.WriteLine("Map ID: " +
                                      (map != 0 ? StoreGetters.GetName(StoreNameType.Map, map) : map + " (No map)"));
                    item.BagFamily = db2File.ReadEnum<BagFamilyMask>("Bag Family", TypeCode.Int32);
                    item.TotemCategory = db2File.ReadEnum<TotemCategory>("Totem Category", TypeCode.Int32);

                    item.ItemSocketColors = new ItemSocketColor[3];
                    for (var i = 0; i < 3; i++)
                        item.ItemSocketColors[i] = db2File.ReadEnum<ItemSocketColor>("Socket Color", TypeCode.Int32, i);

                    item.SocketContent = new uint[3];
                    for (var i = 0; i < 3; i++)
                        item.SocketContent[i] = db2File.ReadUInt32("Socket Item", i);

                    item.SocketBonus = db2File.ReadInt32("Socket Bonus");
                    item.GemProperties = db2File.ReadInt32("Gem Properties");
                    item.ArmorDamageModifier = db2File.ReadSingle("Armor Damage Modifier");
                    item.Duration = db2File.ReadUInt32("Duration");
                    item.ItemLimitCategory = db2File.ReadInt32("Limit Category");
                    item.HolidayId = db2File.ReadEnum<Holiday>("Holiday", TypeCode.Int32);
                    item.StatScalingFactor = db2File.ReadSingle("Stat Scaling Factor");
                    item.CurrencySubstitutionId = db2File.ReadUInt32("Currency Substitution Id");
                    item.CurrencySubstitutionCount = db2File.ReadUInt32("Currency Substitution Count");

                    Storage.ObjectNames.Add(entry, new ObjectName {ObjectType = ObjectType.Item, Name = item.Name},
                        packet.TimeSpan);
                    packet.AddSniffData(StoreNameType.Item, (int) entry, "DB_REPLY");
                    break;
                }
                case DB2Hash.KeyChain:
                {
                    db2File.ReadUInt32("Key Chain Id");
                    db2File.WriteLine("Key: {0}", Utilities.ByteArrayToHexString(db2File.ReadBytes(32)));
                    break;
                }
                case DB2Hash.SceneScript: // lua ftw!
                {
                    db2File.ReadUInt32("Scene Script Id");
                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Name");

                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Script");
                    db2File.ReadUInt32("Previous Scene Script Part");
                    db2File.ReadUInt32("Next Scene Script Part");
                    break;
                }
                case DB2Hash.Vignette:
                {
                    db2File.ReadUInt32("Vignette Entry");
                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Name");

                    db2File.ReadUInt32("Icon");
                    db2File.ReadUInt32("Flag"); // not 100% sure (8 & 32 as values only) - todo verify with more data
                    db2File.ReadSingle("Unk Float 1");
                    db2File.ReadSingle("Unk Float 2");
                    break;
                }
                case DB2Hash.WbAccessControlList:
                {
                    db2File.ReadUInt32("Id");

                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Address");

                    db2File.ReadUInt32("Unk MoP 1");
                    db2File.ReadUInt32("Unk MoP 2");
                    db2File.ReadUInt32("Unk MoP 3");
                    db2File.ReadUInt32("Unk MoP 4"); // flags?
                    break;
                }
                default:
                {
                    db2File.WriteLine("Unknown DB2 file type: {0} (0x{0:x})", type);
                    for (var i = 0;; ++i)
                    {
                        if (db2File.Length - 4 >= db2File.Position)
                        {
                            var blockVal = db2File.ReadUpdateField();
                            string key = "Block Value " + i;
                            string value = blockVal.UInt32Value + "/" + blockVal.SingleValue;
                            packet.WriteLine(key + ": " + value);
                        }
                        else
                        {
                            var left = db2File.Length - db2File.Position;
                            for (var j = 0; j < left; ++j)
                            {
                                string key = "Byte Value " + i;
                                var value = db2File.ReadByte();
                                packet.WriteLine(key + ": " + value);
                            }
                            break;
                        }
                    }
                    break;
                }
            }

            db2File.ClosePacket();
        }
        public static void HandleDBReply(Packet packet)
        {
            var type = packet.ReadUInt32E<DB2Hash>("DB2 File");
            packet.ReadTime("Hotfix date");
            var size = packet.ReadInt32("Size");

            var data = packet.ReadBytes(size);
            var db2File = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);
            var entry = (uint)packet.ReadInt32("Entry");
            if ((int)entry < 0)
            {
                packet.WriteLine("Row {0} has been removed.", -(int)entry);
                return;
            }

            switch (type)
            {
                case DB2Hash.BroadcastText:
                    {
                        var broadcastText = new BroadcastText();

                        var id = db2File.ReadEntry("Broadcast Text Entry");
                        broadcastText.Language = db2File.ReadInt32("Language");
                        if (db2File.ReadUInt16() > 0)
                            broadcastText.MaleText = db2File.ReadCString("Male Text");
                        if (db2File.ReadUInt16() > 0)
                            broadcastText.FemaleText = db2File.ReadCString("Female Text");

                        broadcastText.EmoteID = new uint[3];
                        broadcastText.EmoteDelay = new uint[3];
                        for (var i = 0; i < 3; ++i)
                            broadcastText.EmoteID[i] = (uint)db2File.ReadInt32("Emote ID", i);
                        for (var i = 0; i < 3; ++i)
                            broadcastText.EmoteDelay[i] = (uint)db2File.ReadInt32("Emote Delay", i);

                        broadcastText.SoundId = db2File.ReadUInt32("Sound Id");
                        broadcastText.UnkEmoteId = db2File.ReadUInt32("Unk 1"); // emote unk
                        broadcastText.Type = db2File.ReadUInt32("Unk 2"); // kind of type?

                        Storage.BroadcastTexts.Add((uint)id.Key, broadcastText, packet.TimeSpan);
                        packet.AddSniffData(StoreNameType.BroadcastText, id.Key, "BROADCAST_TEXT");
                        break;
                    }
                case DB2Hash.Creature:
                    {
                        db2File.ReadUInt32("Creature Entry");
                        db2File.ReadUInt32("Item Entry 1");
                        db2File.ReadUInt32("Item Entry 2");
                        db2File.ReadUInt32("Item Entry 3");
                        db2File.ReadUInt32("Projectile Entry 1");
                        db2File.ReadUInt32("Projectile Entry 2");
                        db2File.ReadUInt32("Mount");
                        db2File.ReadUInt32("Display Id 1");
                        db2File.ReadUInt32("Display Id 2");
                        db2File.ReadUInt32("Display Id 3");
                        db2File.ReadUInt32("Display Id 4");
                        db2File.ReadSingle("Unk Float 1");
                        db2File.ReadSingle("Unk Float 2");
                        db2File.ReadSingle("Unk Float 3");
                        db2File.ReadSingle("Unk Float 4");
                        if (db2File.ReadUInt16() > 0)
                            db2File.ReadCString("Name");

                        db2File.ReadUInt32("Inhabit Type");
                        break;
                    }
                case DB2Hash.Item:
                    {
                        var item = Storage.ItemTemplates.ContainsKey(entry) ? Storage.ItemTemplates[entry].Item1 : new ItemTemplate();

                        db2File.ReadUInt32<ItemId>("Item Entry");
                        item.Class = db2File.ReadInt32E<ItemClass>("Class");
                        item.SubClass = db2File.ReadUInt32("Sub Class");
                        item.SoundOverrideSubclass = db2File.ReadInt32("Sound Override Subclass");
                        item.Material = db2File.ReadInt32E<Material>("Material");
                        item.DisplayId = db2File.ReadUInt32("Display ID");
                        item.InventoryType = db2File.ReadUInt32E<InventoryType>("Inventory Type");
                        item.SheathType = db2File.ReadInt32E<SheathType>("Sheath Type");

                        Storage.ItemTemplates.Add(entry, item, packet.TimeSpan);
                        packet.AddSniffData(StoreNameType.Item, (int)entry, "DB_REPLY");
                        break;
                    }
                case DB2Hash.Item_sparse:
                    {
                        var item = Storage.ItemTemplates.ContainsKey(entry) ? Storage.ItemTemplates[entry].Item1 : new ItemTemplate();

                        db2File.ReadUInt32<ItemId>("Item Sparse Entry");
                        item.Quality = db2File.ReadInt32E<ItemQuality>("Quality");
                        item.Flags1 = db2File.ReadUInt32E<ItemProtoFlags>("Flags 1");
                        item.Flags2 = db2File.ReadInt32E<ItemFlagExtra>("Flags 2");
                        item.Flags3 = db2File.ReadUInt32("Flags 3");
                        item.Unk430_1 = db2File.ReadSingle("Unk430_1");
                        item.Unk430_2 = db2File.ReadSingle("Unk430_2");
                        item.BuyCount = db2File.ReadUInt32("Buy count");
                        item.BuyPrice = db2File.ReadUInt32("Buy Price");
                        item.SellPrice = db2File.ReadUInt32("Sell Price");
                        item.InventoryType = db2File.ReadInt32E<InventoryType>("Inventory Type");
                        item.AllowedClasses = db2File.ReadInt32E<ClassMask>("Allowed Classes");
                        item.AllowedRaces = db2File.ReadInt32E<RaceMask>("Allowed Races");
                        item.ItemLevel = db2File.ReadUInt32("Item Level");
                        item.RequiredLevel = db2File.ReadUInt32("Required Level");
                        item.RequiredSkillId = db2File.ReadUInt32("Required Skill ID");
                        item.RequiredSkillLevel = db2File.ReadUInt32("Required Skill Level");
                        item.RequiredSpell = (uint)db2File.ReadInt32<SpellId>("Required Spell");
                        item.RequiredHonorRank = db2File.ReadUInt32("Required Honor Rank");
                        item.RequiredCityRank = db2File.ReadUInt32("Required City Rank");
                        item.RequiredRepFaction = db2File.ReadUInt32("Required Rep Faction");
                        item.RequiredRepValue = db2File.ReadUInt32("Required Rep Value");
                        item.MaxCount = db2File.ReadInt32("Max Count");
                        item.MaxStackSize = db2File.ReadInt32("Max Stack Size");
                        item.ContainerSlots = db2File.ReadUInt32("Container Slots");

                        item.StatTypes = new ItemModType[10];
                        for (var i = 0; i < 10; i++)
                        {
                            var statType = db2File.ReadInt32E<ItemModType>("Stat Type", i);
                            item.StatTypes[i] = statType == ItemModType.None ? ItemModType.Mana : statType; // TDB
                        }

                        item.StatValues = new int[10];
                        for (var i = 0; i < 10; i++)
                            item.StatValues[i] = db2File.ReadInt32("Stat Value", i);

                        item.ScalingValue = new int[10];
                        for (var i = 0; i < 10; i++)
                            item.ScalingValue[i] = db2File.ReadInt32("Scaling Value", i);

                        item.SocketCostRate = new int[10];
                        for (var i = 0; i < 10; i++)
                            item.SocketCostRate[i] = db2File.ReadInt32("Socket Cost Rate", i);

                        item.ScalingStatDistribution = db2File.ReadInt32("Scaling Stat Distribution");
                        item.DamageType = db2File.ReadInt32E<DamageType>("Damage Type");
                        item.Delay = db2File.ReadUInt32("Delay");
                        item.RangedMod = db2File.ReadSingle("Ranged Mod");

                        item.TriggeredSpellIds = new int[5];
                        for (var i = 0; i < 5; i++)
                            item.TriggeredSpellIds[i] = db2File.ReadInt32<SpellId>("Triggered Spell ID", i);

                        item.TriggeredSpellTypes = new ItemSpellTriggerType[5];
                        for (var i = 0; i < 5; i++)
                            item.TriggeredSpellTypes[i] = db2File.ReadInt32E<ItemSpellTriggerType>("Trigger Spell Type", i);

                        item.TriggeredSpellCharges = new int[5];
                        for (var i = 0; i < 5; i++)
                            item.TriggeredSpellCharges[i] = db2File.ReadInt32("Triggered Spell Charges", i);

                        item.TriggeredSpellCooldowns = new int[5];
                        for (var i = 0; i < 5; i++)
                            item.TriggeredSpellCooldowns[i] = db2File.ReadInt32("Triggered Spell Cooldown", i);

                        item.TriggeredSpellCategories = new uint[5];
                        for (var i = 0; i < 5; i++)
                            item.TriggeredSpellCategories[i] = db2File.ReadUInt32("Triggered Spell Category", i);

                        item.TriggeredSpellCategoryCooldowns = new int[5];
                        for (var i = 0; i < 5; i++)
                            item.TriggeredSpellCategoryCooldowns[i] = db2File.ReadInt32("Triggered Spell Category Cooldown", i);

                        item.Bonding = db2File.ReadInt32E<ItemBonding>("Bonding");

                        if (db2File.ReadUInt16() > 0)
                            item.Name = db2File.ReadCString("Name", 0);

                        for (var i = 1; i < 4; ++i)
                            if (db2File.ReadUInt16() > 0)
                                db2File.ReadCString("Name", i);

                        if (db2File.ReadUInt16() > 0)
                            item.Description = db2File.ReadCString("Description");

                        item.PageText = db2File.ReadUInt32("Page Text");
                        item.Language = db2File.ReadInt32E<Language>("Language");
                        item.PageMaterial = db2File.ReadInt32E<PageMaterial>("Page Material");
                        item.StartQuestId = (uint)db2File.ReadInt32<QuestId>("Start Quest");
                        item.LockId = db2File.ReadUInt32("Lock ID");
                        item.Material = db2File.ReadInt32E<Material>("Material");
                        item.SheathType = db2File.ReadInt32E<SheathType>("Sheath Type");
                        item.RandomPropery = db2File.ReadInt32("Random Property");
                        item.RandomSuffix = db2File.ReadUInt32("Random Suffix");
                        item.ItemSet = db2File.ReadUInt32("Item Set");
                        item.AreaId = db2File.ReadUInt32<AreaId>("Area");
                        var map = db2File.ReadInt32<MapId>("Map ID");
                        item.MapId = map;
                        item.BagFamily = db2File.ReadInt32E<BagFamilyMask>("Bag Family");
                        item.TotemCategory = db2File.ReadInt32E<TotemCategory>("Totem Category");

                        item.ItemSocketColors = new ItemSocketColor[3];
                        for (var i = 0; i < 3; i++)
                            item.ItemSocketColors[i] = db2File.ReadInt32E<ItemSocketColor>("Socket Color", i);

                        item.SocketContent = new uint[3];
                        for (var i = 0; i < 3; i++)
                            item.SocketContent[i] = db2File.ReadUInt32("Socket Item", i);

                        item.SocketBonus = db2File.ReadInt32("Socket Bonus");
                        item.GemProperties = db2File.ReadInt32("Gem Properties");
                        item.ArmorDamageModifier = db2File.ReadSingle("Armor Damage Modifier");
                        item.Duration = db2File.ReadUInt32("Duration");
                        item.ItemLimitCategory = db2File.ReadInt32("Limit Category");
                        item.HolidayId = db2File.ReadInt32E<Holiday>("Holiday");
                        item.StatScalingFactor = db2File.ReadSingle("Stat Scaling Factor");
                        item.CurrencySubstitutionId = db2File.ReadUInt32("Currency Substitution Id");
                        item.CurrencySubstitutionCount = db2File.ReadUInt32("Currency Substitution Count");

                        Storage.ObjectNames.Add(entry, new ObjectName { ObjectType = ObjectType.Item, Name = item.Name }, packet.TimeSpan);
                        packet.AddSniffData(StoreNameType.Item, (int)entry, "DB_REPLY");
                        break;
                    }
                case DB2Hash.KeyChain:
                    {
                        db2File.ReadUInt32("Key Chain Id");
                        db2File.ReadBytes("Key", 32);
                        break;
                    }
                default:
                    {
                        db2File.AddValue("Unknown DB2 file type", string.Format(": {0} (0x{0:x})", type));
                        for (var i = 0; ; ++i)
                        {
                            if (db2File.Length - 4 >= db2File.Position)
                            {
                                var blockVal = db2File.ReadUpdateField();
                                string value = blockVal.UInt32Value + "/" + blockVal.SingleValue;
                                packet.AddValue("Block Value " + i, value);
                            }
                            else
                            {
                                var left = db2File.Length - db2File.Position;
                                for (var j = 0; j < left; ++j)
                                {
                                    var value = db2File.ReadByte();
                                    packet.AddValue("Byte Value " + i, value);
                                }
                                break;
                            }
                        }
                        break;
                    }
            }

            db2File.ClosePacket(false);
        }
Beispiel #8
0
        public static void HandleDBReply(Packet packet)
        {
            var type = packet.ReadEnum<DB2Hash>("DB2 File", TypeCode.UInt32);
            packet.ReadTime("Hotfix date");
            var size = packet.ReadInt32("Size");

            var data = packet.ReadBytes(size);
            var db2File = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);
            var entry = (uint)packet.ReadInt32("Entry");
            if ((int)entry < 0)
            {
                packet.WriteLine("Row {0} has been removed.", -(int)entry);
                return;
            }

            switch (type)
            {
                case DB2Hash.Item:    // Item.db2
                    {
                        var item = Storage.ItemTemplates.ContainsKey(entry) ? Storage.ItemTemplates[entry].Item1 : new ItemTemplate();

                        db2File.ReadEntryWithName<UInt32>(StoreNameType.Item, "Entry");
                        item.Class = db2File.ReadEnum<ItemClass>("Class", TypeCode.Int32);
                        item.SubClass = db2File.ReadUInt32("Sub Class");
                        item.SoundOverrideSubclass = db2File.ReadInt32("Sound Override Subclass");
                        item.Material = db2File.ReadEnum<Material>("Material", TypeCode.Int32);
                        item.DisplayId = db2File.ReadUInt32("Display ID");
                        item.InventoryType = db2File.ReadEnum<InventoryType>("Inventory Type", TypeCode.UInt32);
                        item.SheathType = db2File.ReadEnum<SheathType>("Sheath Type", TypeCode.Int32);

                        Storage.ItemTemplates.Add(entry, item, packet.TimeSpan);
                        packet.AddSniffData(StoreNameType.Item, (int)entry, "DB_REPLY");
                        break;
                    }
                case DB2Hash.Item_sparse:    // Item-sparse.db2
                    {
                        var item = Storage.ItemTemplates.ContainsKey(entry) ? Storage.ItemTemplates[entry].Item1 : new ItemTemplate();

                        db2File.ReadEntryWithName<UInt32>(StoreNameType.Item, "Entry");
                        item.Quality = db2File.ReadEnum<ItemQuality>("Quality", TypeCode.Int32);
                        item.Flags = db2File.ReadEnum<ItemProtoFlags>("Flags", TypeCode.UInt32);
                        item.ExtraFlags = db2File.ReadEnum<ItemFlagExtra>("Extra Flags", TypeCode.Int32);
                        item.Unk430_1 = db2File.ReadSingle("Unk430_1");
                        item.Unk430_2 = db2File.ReadSingle("Unk430_2");
                        item.Unk530_1 = db2File.ReadSingle("Unk530_1");
                        item.BuyCount = db2File.ReadUInt32("Buy count");
                        item.BuyPrice = db2File.ReadUInt32("Buy Price");
                        item.SellPrice = db2File.ReadUInt32("Sell Price");
                        item.InventoryType = db2File.ReadEnum<InventoryType>("Inventory Type", TypeCode.Int32);
                        item.AllowedClasses = db2File.ReadEnum<ClassMask>("Allowed Classes", TypeCode.Int32);
                        item.AllowedRaces = db2File.ReadEnum<RaceMask>("Allowed Races", TypeCode.Int32);
                        item.ItemLevel = db2File.ReadUInt32("Item Level");
                        item.RequiredLevel = db2File.ReadUInt32("Required Level");
                        item.RequiredSkillId = db2File.ReadUInt32("Required Skill ID");
                        item.RequiredSkillLevel = db2File.ReadUInt32("Required Skill Level");
                        item.RequiredSpell = (uint)db2File.ReadEntryWithName<Int32>(StoreNameType.Spell, "Required Spell");
                        item.RequiredHonorRank = db2File.ReadUInt32("Required Honor Rank");
                        item.RequiredCityRank = db2File.ReadUInt32("Required City Rank");
                        item.RequiredRepFaction = db2File.ReadUInt32("Required Rep Faction");
                        item.RequiredRepValue = db2File.ReadUInt32("Required Rep Value");
                        item.MaxCount = db2File.ReadInt32("Max Count");
                        item.MaxStackSize = db2File.ReadInt32("Max Stack Size");
                        item.ContainerSlots = db2File.ReadUInt32("Container Slots");

                        item.StatTypes = new ItemModType[10];
                        for (var i = 0; i < 10; i++)
                        {
                            var statType = db2File.ReadEnum<ItemModType>("Stat Type", TypeCode.Int32, i);
                            item.StatTypes[i] = statType == ItemModType.None ? ItemModType.Mana : statType; // TDB
                        }

                        item.StatValues = new int[10];
                        for (var i = 0; i < 10; i++)
                            item.StatValues[i] = db2File.ReadInt32("Stat Value", i);

                        item.StatUnk1 = new int[10];
                        for (var i = 0; i < 10; i++)
                            item.StatUnk1[i] = db2File.ReadInt32("Unk UInt32 1", i);

                        item.StatUnk2 = new int[10];
                        for (var i = 0; i < 10; i++)
                            item.StatUnk2[i] = db2File.ReadInt32("Unk UInt32 2", i);

                        item.ScalingStatDistribution = db2File.ReadInt32("Scaling Stat Distribution");
                        item.DamageType = db2File.ReadEnum<DamageType>("Damage Type", TypeCode.Int32);
                        item.Delay = db2File.ReadUInt32("Delay");
                        item.RangedMod = db2File.ReadSingle("Ranged Mod");

                        item.TriggeredSpellIds = new int[5];
                        for (var i = 0; i < 5; i++)
                            item.TriggeredSpellIds[i] = db2File.ReadEntryWithName<Int32>(StoreNameType.Spell, "Triggered Spell ID", i);

                        item.TriggeredSpellTypes = new ItemSpellTriggerType[5];
                        for (var i = 0; i < 5; i++)
                            item.TriggeredSpellTypes[i] = db2File.ReadEnum<ItemSpellTriggerType>("Trigger Spell Type", TypeCode.Int32, i);

                        item.TriggeredSpellCharges = new int[5];
                        for (var i = 0; i < 5; i++)
                            item.TriggeredSpellCharges[i] = db2File.ReadInt32("Triggered Spell Charges", i);

                        item.TriggeredSpellCooldowns = new int[5];
                        for (var i = 0; i < 5; i++)
                            item.TriggeredSpellCooldowns[i] = db2File.ReadInt32("Triggered Spell Cooldown", i);

                        item.TriggeredSpellCategories = new uint[5];
                        for (var i = 0; i < 5; i++)
                            item.TriggeredSpellCategories[i] = db2File.ReadUInt32("Triggered Spell Category", i);

                        item.TriggeredSpellCategoryCooldowns = new int[5];
                        for (var i = 0; i < 5; i++)
                            item.TriggeredSpellCategoryCooldowns[i] = db2File.ReadInt32("Triggered Spell Category Cooldown", i);

                        item.Bonding = db2File.ReadEnum<ItemBonding>("Bonding", TypeCode.Int32);

                        if (db2File.ReadUInt16() > 0)
                            item.Name = db2File.ReadCString("Name", 0);

                        for (var i = 1; i < 4; ++i)
                            if (db2File.ReadUInt16() > 0)
                                db2File.ReadCString("Name", i);

                        if (db2File.ReadUInt16() > 0)
                            item.Description = db2File.ReadCString("Description");

                        item.PageText = db2File.ReadUInt32("Page Text");
                        item.Language = db2File.ReadEnum<Language>("Language", TypeCode.Int32);
                        item.PageMaterial = db2File.ReadEnum<PageMaterial>("Page Material", TypeCode.Int32);
                        item.StartQuestId = (uint)db2File.ReadEntryWithName<Int32>(StoreNameType.Quest, "Start Quest");
                        item.LockId = db2File.ReadUInt32("Lock ID");
                        item.Material = db2File.ReadEnum<Material>("Material", TypeCode.Int32);
                        item.SheathType = db2File.ReadEnum<SheathType>("Sheath Type", TypeCode.Int32);
                        item.RandomPropery = db2File.ReadInt32("Random Property");
                        item.RandomSuffix = db2File.ReadUInt32("Random Suffix");
                        item.ItemSet = db2File.ReadUInt32("Item Set");
                        item.AreaId = (uint)db2File.ReadEntryWithName<UInt32>(StoreNameType.Area, "Area");
                        // In this single (?) case, map 0 means no map
                        var map = db2File.ReadInt32();
                        item.MapId = map;
                        db2File.WriteLine("Map ID: " + (map != 0 ? StoreGetters.GetName(StoreNameType.Map, map) : map + " (No map)"));
                        item.BagFamily = db2File.ReadEnum<BagFamilyMask>("Bag Family", TypeCode.Int32);
                        item.TotemCategory = db2File.ReadEnum<TotemCategory>("Totem Category", TypeCode.Int32);

                        item.ItemSocketColors = new ItemSocketColor[3];
                        for (var i = 0; i < 3; i++)
                            item.ItemSocketColors[i] = db2File.ReadEnum<ItemSocketColor>("Socket Color", TypeCode.Int32, i);

                        item.SocketContent = new uint[3];
                        for (var i = 0; i < 3; i++)
                            item.SocketContent[i] = db2File.ReadUInt32("Socket Item", i);

                        item.SocketBonus = db2File.ReadInt32("Socket Bonus");
                        item.GemProperties = db2File.ReadInt32("Gem Properties");
                        item.ArmorDamageModifier = db2File.ReadSingle("Armor Damage Modifier");
                        item.Duration = db2File.ReadUInt32("Duration");
                        item.ItemLimitCategory = db2File.ReadInt32("Limit Category");
                        item.HolidayId = db2File.ReadEnum<Holiday>("Holiday", TypeCode.Int32);
                        item.StatScalingFactor = db2File.ReadSingle("Stat Scaling Factor");
                        item.CurrencySubstitutionId = db2File.ReadUInt32("Currency Substitution Id");
                        item.CurrencySubstitutionCount = db2File.ReadUInt32("Currency Substitution Count");

                        Storage.ObjectNames.Add(entry, new ObjectName { ObjectType = ObjectType.Item, Name = item.Name }, packet.TimeSpan);
                        packet.AddSniffData(StoreNameType.Item, (int)entry, "DB_REPLY");
                        break;
                    }
                case DB2Hash.KeyChain: // KeyChain.db2
                    {
                        db2File.ReadUInt32("Key Chain Id");
                        db2File.WriteLine("Key: {0}", Utilities.ByteArrayToHexString(db2File.ReadBytes(32)));
                        break;
                    }
                case DB2Hash.Creature: // Creature.db2
                    {
                        db2File.ReadUInt32("Npc Entry");
                        db2File.ReadUInt32("Item Entry 1");
                        db2File.ReadUInt32("Item Entry 2");
                        db2File.ReadUInt32("Item Entry 3");
                        db2File.ReadUInt32("Projectile Entry 1");
                        db2File.ReadUInt32("Projectile Entry 2");
                        db2File.ReadUInt32("Mount");
                        db2File.ReadUInt32("Display Id 1");
                        db2File.ReadUInt32("Display Id 2");
                        db2File.ReadUInt32("Display Id 3");
                        db2File.ReadUInt32("Display Id 4");
                        db2File.ReadSingle("Float1");
                        db2File.ReadSingle("Float2");
                        db2File.ReadSingle("Float3");
                        db2File.ReadSingle("Float4");
                        if (db2File.ReadUInt16() > 0)
                            db2File.ReadCString("Name");

                        db2File.ReadUInt32("InhabitType");
                        break;
                    }
                case DB2Hash.BroadcastText:
                    {
                        db2File.ReadUInt32("Broadcast Text Entry");
                        db2File.ReadUInt32("Language");
                        if (db2File.ReadUInt16() > 0)
                            db2File.ReadCString("Male Text");
                        if (db2File.ReadUInt16() > 0)
                            db2File.ReadCString("Female Text");

                        for (var i = 0; i < 3; ++i)
                            db2File.ReadInt32("Emote ID", i);
                        for (var i = 0; i < 3; ++i)
                            db2File.ReadInt32("Emote Delay", i);

                        db2File.ReadUInt32("Sound Id");
                        db2File.ReadUInt32("Unk0");
                        db2File.ReadUInt32("Unk1"); // kind of type?
                        break;
                    }
                default:
                    {
                        db2File.WriteLine("Unknown DB2 file type: {0} (0x{0:x})", type);
                        for (var i = 0; ; ++i)
                        {
                            if (db2File.Length - 4 >= db2File.Position)
                            {
                                var blockVal = db2File.ReadUpdateField();
                                string key = "Block Value " + i;
                                string value = blockVal.UInt32Value + "/" + blockVal.SingleValue;
                                packet.WriteLine(key + ": " + value);
                            }
                            else
                            {
                                var left = db2File.Length - db2File.Position;
                                for (var j = 0; j < left; ++j)
                                {
                                    string key = "Byte Value " + i;
                                    var value = db2File.ReadByte();
                                    packet.WriteLine(key + ": " + value);
                                }
                                break;
                            }
                        }
                        break;
                    }
            }
        }
        public static void HandleDBReply(Packet packet)
        {
            var type = packet.ReadUInt32E<DB2Hash>("DB2 File");
            var entry = (uint)packet.ReadInt32("Entry");
            packet.ReadTime("Hotfix date");

            var size = packet.ReadInt32("Size");
            var data = packet.ReadBytes(size);
            var db2File = new Packet(data, packet.Opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName);

            if ((int)entry < 0)
            {
                packet.WriteLine("Row {0} has been removed.", -(int)entry);
                return;
            }

            switch (type)
            {
                case DB2Hash.BroadcastText:
                {
                    var broadcastText = new BroadcastText();

                    var id = db2File.ReadEntry("Id");
                    broadcastText.Language = db2File.ReadInt32("Language");
                    var maletextLength = db2File.ReadUInt16();
                    broadcastText.MaleText = db2File.ReadWoWString("Male Text", maletextLength);
                    var femaletextLength = db2File.ReadUInt16();
                    broadcastText.FemaleText = db2File.ReadWoWString("Female Text", femaletextLength);

                    broadcastText.EmoteID = new uint[3];
                    broadcastText.EmoteDelay = new uint[3];
                    for (var i = 0; i < 3; ++i)
                        broadcastText.EmoteID[i] = (uint) db2File.ReadInt32("Emote ID", i);
                    for (var i = 0; i < 3; ++i)
                        broadcastText.EmoteDelay[i] = (uint) db2File.ReadInt32("Emote Delay", i);

                    broadcastText.SoundId = db2File.ReadUInt32("Sound Id");
                    broadcastText.UnkEmoteId = db2File.ReadUInt32("Unk MoP 1"); // unk emote
                    broadcastText.Type = db2File.ReadUInt32("Unk MoP 2"); // kind of type?

                    Storage.BroadcastTexts.Add((uint) id.Key, broadcastText, packet.TimeSpan);
                    packet.AddSniffData(StoreNameType.BroadcastText, id.Key, "BROADCAST_TEXT");
                    break;
                }
                case DB2Hash.Creature: // New structure - 6.0.2
                {
                    db2File.ReadUInt32("Creature ID");
                    db2File.ReadInt32E<CreatureType>("Type");

                    for (var i = 0; i < 3; ++i)
                        db2File.ReadUInt32<ItemId>("Item ID", i);

                    db2File.ReadUInt32("Mount");
                    for (var i = 0; i < 4; ++i)
                        db2File.ReadInt32("Display ID", i);

                    for (var i = 0; i < 4; ++i)
                        db2File.ReadSingle("Display ID Probability", i);

                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Name");

                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Female Name");

                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("SubName");

                    if (db2File.ReadUInt16() > 0)
                        db2File.ReadCString("Female SubName");

                    db2File.ReadUInt32("Rank");
                    db2File.ReadUInt32("Inhabit Type");
                    break;
                }
                case DB2Hash.CreatureDifficulty:
                {
                    var creatureDifficulty = new CreatureDifficulty();

                    var id = db2File.ReadEntry("Id");
                    creatureDifficulty.CreatureID = db2File.ReadUInt32("Creature Id");
                    creatureDifficulty.FactionID = db2File.ReadUInt32("Faction Template Id");
                    creatureDifficulty.Expansion = db2File.ReadInt32("Expansion");
                    creatureDifficulty.MinLevel = db2File.ReadInt32("Min Level");
                    creatureDifficulty.MaxLevel = db2File.ReadInt32("Max Level");

                    creatureDifficulty.Flags = new uint[5];
                    for (var i = 0; i < 5; ++i)
                        creatureDifficulty.Flags[i] = db2File.ReadUInt32("Flags", i);

                    Storage.CreatureDifficultys.Add((uint)id.Key, creatureDifficulty, packet.TimeSpan);
                    break;
                }
                case DB2Hash.CurvePoint:
                {
                    var curvePoint = new CurvePoint();
                    var id = db2File.ReadUInt32("ID");
                    curvePoint.CurveID = db2File.ReadUInt32("CurveID");
                    curvePoint.Index = db2File.ReadUInt32("Index");
                    curvePoint.X = db2File.ReadSingle("X");
                    curvePoint.Y = db2File.ReadSingle("Y");

                    Storage.CurvePoints.Add(id, curvePoint, packet.TimeSpan);
                    break;
                }
                case DB2Hash.GameObjects: // New structure - 6.0.2
                {
                    var gameObjectTemplateDB2 = new GameObjectTemplateDB2();

                    var id = db2File.ReadEntry("ID");

                    gameObjectTemplateDB2.MapID = db2File.ReadUInt32("Map");

                    gameObjectTemplateDB2.DisplayId = db2File.ReadUInt32("DisplayID");

                    gameObjectTemplateDB2.PositionX = db2File.ReadSingle("PositionX");
                    gameObjectTemplateDB2.PositionY = db2File.ReadSingle("PositionY");
                    gameObjectTemplateDB2.PositionZ = db2File.ReadSingle("PositionZ");
                    gameObjectTemplateDB2.RotationX = db2File.ReadSingle("RotationX");
                    gameObjectTemplateDB2.RotationY = db2File.ReadSingle("RotationY");
                    gameObjectTemplateDB2.RotationZ = db2File.ReadSingle("RotationZ");
                    gameObjectTemplateDB2.RotationW = db2File.ReadSingle("RotationW");

                    gameObjectTemplateDB2.Size = db2File.ReadSingle("Size");

                    db2File.ReadInt32("Phase Use Flags");
                    gameObjectTemplateDB2.PhaseId = db2File.ReadInt32("PhaseID");
                    gameObjectTemplateDB2.PhaseGroupId = db2File.ReadInt32("PhaseGroupID");

                    gameObjectTemplateDB2.Type = db2File.ReadInt32E<GameObjectType>("Type");

                    gameObjectTemplateDB2.Data = new int[8];
                    for (var i = 0; i < gameObjectTemplateDB2.Data.Length; i++)
                        gameObjectTemplateDB2.Data[i] = db2File.ReadInt32("Data", i);

                    if (db2File.ReadUInt16() > 0)
                        gameObjectTemplateDB2.Name = db2File.ReadCString("Name");

                    Storage.GameObjectTemplateDB2s.Add((uint)id.Key, gameObjectTemplateDB2, packet.TimeSpan);
                    break;
                }
                case DB2Hash.Item: // New structure - 6.0.2
                {
                    var item = Storage.ItemTemplates.ContainsKey(entry)
                        ? Storage.ItemTemplates[entry].Item1
                        : new ItemTemplate();

                    db2File.ReadUInt32<ItemId>("Item ID");
                    item.Class = db2File.ReadInt32E<ItemClass>("Class");
                    item.SubClass = db2File.ReadUInt32("Sub Class");
                    item.SoundOverrideSubclass = db2File.ReadInt32("Sound Override Subclass");
                    item.Material = db2File.ReadInt32E<Material>("Material");
                    item.InventoryType = db2File.ReadUInt32E<InventoryType>("Inventory Type");
                    item.SheathType = db2File.ReadInt32E<SheathType>("Sheath Type");
                    db2File.ReadInt32("Icon File Data ID");
                    db2File.ReadInt32("Item Group Sounds ID");

                    Storage.ItemTemplates.Add(entry, item, packet.TimeSpan);
                    packet.AddSniffData(StoreNameType.Item, (int) entry, "DB_REPLY");
                    break;
                }
                case DB2Hash.ItemExtendedCost: // New structure - 6.0.2
                {
                    db2File.ReadUInt32("Item Extended Cost ID");
                    if (ClientVersion.RemovedInVersion(ClientVersionBuild.V6_1_0_19678))
                    {
                        db2File.ReadUInt32("Required Honor Points");
                        db2File.ReadUInt32("Required Arena Points");
                    }

                    db2File.ReadUInt32("Required Arena Slot");
                    for (var i = 0; i < 5; ++i)
                        db2File.ReadUInt32("Required Item", i);

                    for (var i = 0; i < 5; ++i)
                        db2File.ReadUInt32("Required Item Count", i);

                    db2File.ReadUInt32("Required Personal Arena Rating");
                    db2File.ReadUInt32("Item Purchase Group");
                    for (var i = 0; i < 5; ++i)
                        db2File.ReadUInt32("Required Currency", i);

                    for (var i = 0; i < 5; ++i)
                        db2File.ReadUInt32("Required Currency Count", i);

                    db2File.ReadUInt32("Required Faction ID");
                    db2File.ReadUInt32("Required Faction Standing");
                    db2File.ReadUInt32("Requirement Flags");
                    db2File.ReadInt32<AchievementId>("Required Achievement");
                    if (ClientVersion.AddedInVersion(ClientVersionBuild.V6_1_0_19678))
                        db2File.ReadInt32("Unk1 Wod61x");
                    break;
                }
                case DB2Hash.ItemCurrencyCost:
                {
                    db2File.ReadUInt32("ID");
                    db2File.ReadUInt32<ItemId>("Item ID");
                    break;
                }
                case DB2Hash.Mount:
                {
                    var mount = new Mount();
                    var id = db2File.ReadUInt32("ID");
                    mount.MountTypeId = db2File.ReadUInt32("MountTypeId");
                    mount.DisplayId = db2File.ReadUInt32("DisplayId");
                    mount.Flags = db2File.ReadUInt32("Flags");

                    var NameLength = db2File.ReadUInt16();
                    mount.Name = db2File.ReadWoWString("Name", NameLength);

                    var DescriptionLength = db2File.ReadUInt16();
                    mount.Description = db2File.ReadWoWString("Description", DescriptionLength);

                    var SourceDescriptionLength = db2File.ReadUInt16();
                    mount.SourceDescription = db2File.ReadWoWString("SourceDescription", SourceDescriptionLength);

                    mount.Source = db2File.ReadUInt32("Source");
                    mount.SpellId = db2File.ReadUInt32("SpellId");
                    mount.PlayerConditionId = db2File.ReadUInt32("PlayerConditionId");

                    Storage.Mounts.Add(id, mount, packet.TimeSpan);
                    break;
                }
                case DB2Hash.RulesetItemUpgrade:
                {
                    db2File.ReadUInt32("ID");
                    db2File.ReadUInt32("Item Upgrade Level");
                    db2File.ReadUInt32("Item Upgrade ID");
                    db2File.ReadUInt32<ItemId>("Item ID");
                    break;
                }
                case DB2Hash.Holidays:
                {
                    var holiday = new HolidayData();

                    var id = db2File.ReadUInt32("ID");

                    holiday.Duration = new uint[10];
                    for (var i = 0; i < 10; i++)
                        holiday.Duration[i] = db2File.ReadUInt32("Duration", i);

                    holiday.Date = new uint[16];
                    for (var i = 0; i < 16; i++)
                        holiday.Date[i] = db2File.ReadUInt32("Date", i);

                    holiday.Region = db2File.ReadUInt32("Region");
                    holiday.Looping = db2File.ReadUInt32("Looping");

                    holiday.CalendarFlags = new uint[10];
                    for (var i = 0; i < 10; i++)
                        holiday.CalendarFlags[i] = db2File.ReadUInt32("CalendarFlags", i);

                    holiday.HolidayNameID = db2File.ReadUInt32("HolidayNameID");
                    holiday.HolidayDescriptionID = db2File.ReadUInt32("HolidayDescriptionID");

                    var TextureFilenameLength = db2File.ReadUInt16();
                    holiday.TextureFilename = db2File.ReadWoWString("SourceDescription", TextureFilenameLength);

                    holiday.Priority = db2File.ReadUInt32("Priority");
                    holiday.CalendarFilterType = db2File.ReadUInt32("CalendarFilterType");
                    holiday.Flags = db2File.ReadUInt32("Flags");

                    Storage.Holidays.Add(id, holiday, packet.TimeSpan);
                    break;
                }
                case DB2Hash.ItemAppearance:
                {
                    var itemAppearance = new ItemAppearance();

                    var id = db2File.ReadUInt32("ID");

                    itemAppearance.DisplayID = db2File.ReadUInt32("Display ID");
                    itemAppearance.IconFileDataID = db2File.ReadUInt32("File Data ID");

                    Storage.ItemAppearances.Add(id, itemAppearance, packet.TimeSpan);
                    break;
                }
                case DB2Hash.ItemBonus:
                {
                    var itemBonus = new ItemBonus();

                    var id = db2File.ReadUInt32("ID");

                    itemBonus.BonusListID = db2File.ReadUInt32("Bonus List ID");
                    itemBonus.Type = db2File.ReadUInt32("Type");

                    itemBonus.Value = new uint[2];
                    for (var i = 0; i < 2; i++)
                        itemBonus.Value[i] = db2File.ReadUInt32("Value", i);

                    itemBonus.Index = db2File.ReadUInt32("Index");

                    Storage.ItemBonuses.Add(id, itemBonus, packet.TimeSpan);
                    break;
                }
                case DB2Hash.ItemBonusTreeNode:
                {
                    var itemBonusTreeNode = new ItemBonusTreeNode();
                    var id = db2File.ReadUInt32("ID");

                    itemBonusTreeNode.BonusTreeID = db2File.ReadUInt32("BonusTreeID");
                    itemBonusTreeNode.BonusTreeModID = db2File.ReadUInt32("BonusTreeModID");
                    itemBonusTreeNode.SubTreeID = db2File.ReadUInt32("SubTreeID");
                    itemBonusTreeNode.BonusListID = db2File.ReadUInt32("BonusListID");

                    Storage.ItemBonusTreeNodes.Add(id, itemBonusTreeNode, packet.TimeSpan);
                    break;
                }
                case DB2Hash.Item_sparse: // New structure - 6.0.2
                {
                    var item = Storage.ItemTemplates.ContainsKey(entry)
                        ? Storage.ItemTemplates[entry].Item1
                        : new ItemTemplate();

                    db2File.ReadUInt32<ItemId>("Item Sparse Entry");
                    item.Quality = db2File.ReadInt32E<ItemQuality>("Quality");
                    item.Flags1 = db2File.ReadUInt32E<ItemProtoFlags>("Flags 1");
                    item.Flags2 = db2File.ReadInt32E<ItemFlagExtra>("Flags 2");
                    item.Flags3 = db2File.ReadUInt32("Flags 3");
                    item.Unk430_1 = db2File.ReadSingle("Unk430_1");
                    item.Unk430_2 = db2File.ReadSingle("Unk430_2");
                    item.BuyCount = db2File.ReadUInt32("Buy count");
                    item.BuyPrice = db2File.ReadUInt32("Buy Price");
                    item.SellPrice = db2File.ReadUInt32("Sell Price");
                    item.InventoryType = db2File.ReadInt32E<InventoryType>("Inventory Type");
                    item.AllowedClasses = db2File.ReadInt32E<ClassMask>("Allowed Classes");
                    item.AllowedRaces = db2File.ReadInt32E<RaceMask>("Allowed Races");
                    item.ItemLevel = db2File.ReadUInt32("Item Level");
                    item.RequiredLevel = db2File.ReadUInt32("Required Level");
                    item.RequiredSkillId = db2File.ReadUInt32("Required Skill ID");
                    item.RequiredSkillLevel = db2File.ReadUInt32("Required Skill Level");
                    item.RequiredSpell = (uint) db2File.ReadInt32<SpellId>("Required Spell");
                    item.RequiredHonorRank = db2File.ReadUInt32("Required Honor Rank");
                    item.RequiredCityRank = db2File.ReadUInt32("Required City Rank");
                    item.RequiredRepFaction = db2File.ReadUInt32("Required Rep Faction");
                    item.RequiredRepValue = db2File.ReadUInt32("Required Rep Value");
                    item.MaxCount = db2File.ReadInt32("Max Count");
                    item.MaxStackSize = db2File.ReadInt32("Max Stack Size");
                    item.ContainerSlots = db2File.ReadUInt32("Container Slots");

                    item.StatTypes = new ItemModType[10];
                    for (var i = 0; i < 10; i++)
                    {
                        var statType = db2File.ReadInt32E<ItemModType>("Stat Type", i);
                        item.StatTypes[i] = statType == ItemModType.None ? ItemModType.Mana : statType; // TDB
                    }

                    item.StatValues = new int[10];
                    for (var i = 0; i < 10; i++)
                        item.StatValues[i] = db2File.ReadInt32("Stat Value", i);

                    item.ScalingValue = new int[10];
                    for (var i = 0; i < 10; i++)
                        item.ScalingValue[i] = db2File.ReadInt32("Scaling Value", i);

                    item.SocketCostRate = new int[10];
                    for (var i = 0; i < 10; i++)
                        item.SocketCostRate[i] = db2File.ReadInt32("Socket Cost Rate", i);

                    item.ScalingStatDistribution = db2File.ReadInt32("Scaling Stat Distribution");
                    item.DamageType = db2File.ReadInt32E<DamageType>("Damage Type");
                    item.Delay = db2File.ReadUInt32("Delay");
                    item.RangedMod = db2File.ReadSingle("Ranged Mod");
                    item.Bonding = db2File.ReadInt32E<ItemBonding>("Bonding");

                    var nameLength = db2File.ReadUInt16();
                    item.Name = db2File.ReadWoWString("Name", nameLength, 0);

                    for (var i = 1; i < 4; ++i)
                        if (db2File.ReadUInt16() > 0)
                            db2File.ReadCString("Name", i);

                    var descriptionLength = db2File.ReadUInt16();
                    item.Description = db2File.ReadWoWString("Description", descriptionLength);

                    item.PageText = db2File.ReadUInt32("Page Text");
                    item.Language = db2File.ReadInt32E<Language>("Language");
                    item.PageMaterial = db2File.ReadInt32E<PageMaterial>("Page Material");
                    item.StartQuestId = (uint) db2File.ReadInt32<QuestId>("Start Quest");
                    item.LockId = db2File.ReadUInt32("Lock ID");
                    item.Material = db2File.ReadInt32E<Material>("Material");
                    item.SheathType = db2File.ReadInt32E<SheathType>("Sheath Type");
                    item.RandomPropery = db2File.ReadInt32("Random Property");
                    item.RandomSuffix = db2File.ReadUInt32("Random Suffix");
                    item.ItemSet = db2File.ReadUInt32("Item Set");
                    item.AreaId = db2File.ReadUInt32<AreaId>("Area");
                    item.MapId = db2File.ReadInt32<MapId>("Map ID");
                    item.BagFamily = db2File.ReadInt32E<BagFamilyMask>("Bag Family");
                    item.TotemCategory = db2File.ReadInt32E<TotemCategory>("Totem Category");

                    item.ItemSocketColors = new ItemSocketColor[3];
                    for (var i = 0; i < 3; i++)
                        item.ItemSocketColors[i] = db2File.ReadInt32E<ItemSocketColor>("Socket Color", i);

                    item.SocketBonus = db2File.ReadInt32("Socket Bonus");
                    item.GemProperties = db2File.ReadInt32("Gem Properties");
                    item.ArmorDamageModifier = db2File.ReadSingle("Armor Damage Modifier");
                    item.Duration = db2File.ReadUInt32("Duration");
                    item.ItemLimitCategory = db2File.ReadInt32("Limit Category");
                    item.HolidayId = db2File.ReadInt32E<Holiday>("Holiday");
                    item.StatScalingFactor = db2File.ReadSingle("Stat Scaling Factor");
                    item.CurrencySubstitutionId = db2File.ReadUInt32("Currency Substitution Id");
                    item.CurrencySubstitutionCount = db2File.ReadUInt32("Currency Substitution Count");
                    item.ItemNameDescriptionId = db2File.ReadUInt32("Item Name Description ID");

                    Storage.ObjectNames.Add(entry, new ObjectName {ObjectType = ObjectType.Item, Name = item.Name},
                        packet.TimeSpan);
                    packet.AddSniffData(StoreNameType.Item, (int) entry, "DB_REPLY");
                    break;
                }
                case DB2Hash.KeyChain:
                {
                    var key = new KeyChain();
                    var id = db2File.ReadUInt32("ID");

                    key.Key = new byte[32];
                    for (var i = 0; i < 32; i++)
                        key.Key[i] = db2File.ReadByte("Key", i);

                    Storage.KeyChains.Add(id, key, packet.TimeSpan);
                    break;
                }
                case DB2Hash.SceneScript: // lua ftw!
                {
                    db2File.ReadUInt32("Scene Script ID");
                    var nameLength = db2File.ReadUInt16();
                    db2File.ReadWoWString("Name", nameLength);

                    var scriptLength = db2File.ReadUInt16();
                    db2File.ReadWoWString("Script", scriptLength);
                    db2File.ReadUInt32("Previous Scene Script Part");
                    db2File.ReadUInt32("Next Scene Script Part");
                    break;
                }
                case DB2Hash.SpellMisc: // New structure - 6.0.2
                {
                    var spellMisc = new SpellMisc();

                    var id = db2File.ReadEntry("ID");

                    spellMisc.Attributes = db2File.ReadUInt32("Attributes");
                    spellMisc.AttributesEx = db2File.ReadUInt32("AttributesEx");
                    spellMisc.AttributesExB = db2File.ReadUInt32("AttributesExB");
                    spellMisc.AttributesExC = db2File.ReadUInt32("AttributesExC");
                    spellMisc.AttributesExD = db2File.ReadUInt32("AttributesExD");
                    spellMisc.AttributesExE = db2File.ReadUInt32("AttributesExE");
                    spellMisc.AttributesExF = db2File.ReadUInt32("AttributesExF");
                    spellMisc.AttributesExG = db2File.ReadUInt32("AttributesExG");
                    spellMisc.AttributesExH = db2File.ReadUInt32("AttributesExH");
                    spellMisc.AttributesExI = db2File.ReadUInt32("AttributesExI");
                    spellMisc.AttributesExJ = db2File.ReadUInt32("AttributesExJ");
                    spellMisc.AttributesExK = db2File.ReadUInt32("AttributesExK");
                    spellMisc.AttributesExL = db2File.ReadUInt32("AttributesExL");
                    spellMisc.AttributesExM = db2File.ReadUInt32("AttributesExM");
                    spellMisc.CastingTimeIndex = db2File.ReadUInt32("CastingTimeIndex");
                    spellMisc.DurationIndex = db2File.ReadUInt32("DurationIndex");
                    spellMisc.RangeIndex = db2File.ReadUInt32("RangeIndex");
                    spellMisc.Speed = db2File.ReadSingle("Speed");

                    spellMisc.SpellVisualID = new uint[2];
                    for (var i = 0; i < 2; ++i)
                        spellMisc.SpellVisualID[i] = db2File.ReadUInt32("SpellVisualID", i);

                    spellMisc.SpellIconID = db2File.ReadUInt32("SpellIconID");
                    spellMisc.ActiveIconID = db2File.ReadUInt32("ActiveIconID");
                    spellMisc.SchoolMask = db2File.ReadUInt32("SchoolMask");
                    spellMisc.MultistrikeSpeedMod = db2File.ReadSingle("MultistrikeSpeedMod");

                    Storage.SpellMiscs.Add((uint)id.Key, spellMisc, packet.TimeSpan);
                    break;
                }
                case DB2Hash.Toy: // New structure - 6.0.2
                {
                    db2File.ReadUInt32("ID");
                    db2File.ReadUInt32<ItemId>("Item ID");
                    db2File.ReadUInt32("Flags");

                    var descriptionLength = db2File.ReadUInt16();
                    db2File.ReadWoWString("Description", descriptionLength);

                    db2File.ReadInt32("Source Type");
                    break;
                }
                case DB2Hash.Vignette:
                {
                    db2File.ReadUInt32("Vignette ID");
                    var nameLength = db2File.ReadUInt16();
                    db2File.ReadWoWString("Name", nameLength);

                    db2File.ReadUInt32("Icon");
                    db2File.ReadUInt32("Flag"); // not 100% sure (8 & 32 as values only) - todo verify with more data
                    db2File.ReadSingle("Unk Float 1");
                    db2File.ReadSingle("Unk Float 2");
                    break;
                }
                case DB2Hash.WbAccessControlList:
                {
                    db2File.ReadUInt32("Id");

                    var addressLength = db2File.ReadUInt16();
                    db2File.ReadWoWString("Address", addressLength);

                    db2File.ReadUInt32("Unk MoP 1");
                    db2File.ReadUInt32("Unk MoP 2");
                    db2File.ReadUInt32("Unk MoP 3");
                    db2File.ReadUInt32("Unk MoP 4"); // flags?
                    break;
                }
                default:
                {
                    db2File.AddValue("Unknown DB2 file type", string.Format("{0} (0x{0:x})", type));
                    for (var i = 0;; ++i)
                    {
                        if (db2File.Length - 4 >= db2File.Position)
                        {
                            var blockVal = db2File.ReadUpdateField();
                            string key = "Block Value " + i;
                            string value = blockVal.UInt32Value + "/" + blockVal.SingleValue;
                            packet.AddValue(key, value);
                        }
                        else
                        {
                            var left = db2File.Length - db2File.Position;
                            for (var j = 0; j < left; ++j)
                            {
                                string key = "Byte Value " + i;
                                var value = db2File.ReadByte();
                                packet.AddValue(key, value);
                            }
                            break;
                        }
                    }
                    break;
                }
            }

            if (db2File.Length != db2File.Position)
            {
                packet.WriteLine("Packet not fully read! Current position is {0}, length is {1}, and diff is {2}.",
                    db2File.Position, db2File.Length, db2File.Length - db2File.Position);

                if (db2File.Length < 300) // If the packet isn't "too big" and it is not full read, print its hex table
                    packet.AsHex();

                packet.Status = ParsedStatus.WithErrors;
            }
        }