示例#1
0
        public static void HandleAuraUpdate(Packet packet)
        {
            var guid = packet.ReadPackedGuid("GUID");

            var auras = new List<Aura>();
            while (packet.CanRead())
            {
                var aura = ReadAuraUpdateBlock(ref packet);
                auras.Add(aura);
            }

            // This only works if the parser saw UPDATE_OBJECT before this packet
            if (Storage.Objects.ContainsKey(guid))
            {
                var unit = Storage.Objects[guid] as Unit;
                if (unit != null)
                {
                    // If this is the first packet that sends auras
                    // (hopefully at spawn time) add it to the "Auras" field,
                    // if not create another row of auras in AddedAuras
                    // (similar to ChangedUpdateFields)

                    if (unit.Auras == null)
                        unit.Auras = auras;
                    else if (unit.AddedAuras == null)
                        unit.AddedAuras = new List<List<Aura>> { auras };
                    else
                        unit.AddedAuras.Add(auras);
                }
            }
        }
示例#2
0
        public static void HandleContactList(Packet packet)
        {
            packet.ReadInt32E<ContactListFlag>("List Flags");
            var count = packet.ReadInt32("Count");

            for (var i = 0; i < count; i++)
            {
                packet.ReadGuid("GUID");
                packet.ReadInt32("Realm Id");
                packet.ReadInt32("Realm Id");
                var flag = packet.ReadInt32E<ContactEntryFlag>("Flags");
                packet.ReadCString("Note");

                if (!flag.HasAnyFlag(ContactEntryFlag.Friend))
                    continue;

                var status = packet.ReadByteE<ContactStatus>("Status");
                if (status == 0) // required any flag
                    continue;

                packet.ReadInt32<AreaId>("Area");
                packet.ReadInt32("Level");
                packet.ReadInt32E<Class>("Class");
            }

            // still needed?
            if (packet.CanRead())
                CoreParsers.WardenHandler.ReadCheatCheckDecryptionBlock(packet);
        }
        public static void HandleContactList(Packet packet)
        {
            packet.ReadEnum<ContactListFlag>("List Flags", TypeCode.Int32);
            var count = packet.ReadInt32("Count");

            for (var i = 0; i < count; i++)
            {
                packet.ReadGuid("GUID");
                packet.ReadInt32("Unk int1");
                packet.ReadInt32("Unk int2");
                var flag = packet.ReadEnum<ContactEntryFlag>("Flags", TypeCode.Int32);
                packet.ReadCString("Note");

                if (!flag.HasAnyFlag(ContactEntryFlag.Friend))
                    continue;

                var status = packet.ReadEnum<ContactStatus>("Status", TypeCode.Byte);
                if (status == 0) // required any flag
                    continue;

                packet.ReadEntry<Int32>(StoreNameType.Area, "Area");
                packet.ReadInt32("Level");
                packet.ReadEnum<Class>("Class", TypeCode.Int32);
            }

            // still needed?
            if (packet.CanRead())
                CoreParsers.WardenHandler.ReadCheatCheckDecryptionBlock(ref packet);
        }
示例#4
0
        public static void HandleAuraUpdate(Packet packet)
        {
            var guid = packet.ReadPackedGuid("GUID");
            var i = 0;
            var auras = new List<Aura>();
            while (packet.CanRead())
            {
                Aura aura;
                if (ClientVersion.AddedInVersion(ClientVersionBuild.V5_0_5_16048))
                    aura = ReadAuraUpdateBlock505(packet, i++);
                else
                    aura = ReadAuraUpdateBlock(packet, i++);

                if (aura != null)
                    auras.Add(aura);
            }

            // This only works if the parser saw UPDATE_OBJECT before this packet
            if (Storage.Objects.ContainsKey(guid))
            {
                var unit = Storage.Objects[guid].Item1 as Unit;
                if (unit != null)
                {
                    // If this is the first packet that sends auras
                    // (hopefully at spawn time) add it to the "Auras" field,
                    // if not create another row of auras in AddedAuras
                    // (similar to ChangedUpdateFields)

                    if (unit.Auras == null)
                        unit.Auras = auras;
                    else
                        unit.AddedAuras.Add(auras);
                }
            }
        }
示例#5
0
 public static void HandleShowTaxiNodes(Packet packet)
 {
     packet.ReadUInt32("Unk UInt32 1");
     packet.ReadGuid("GUID");
     packet.ReadUInt32("Node ID");
     var i = 0;
     while (packet.CanRead())
         packet.ReadUInt32("NodeMask", i++);
 }
示例#6
0
        public static void HandleNpcGossipSelectOption(Packet packet)
        {
            packet.ReadGuid("GUID");
            packet.ReadUInt32("Menu Id");
            packet.ReadUInt32("Gossip Id");

            if (packet.CanRead()) // if ( byte_F3777C[v3] & 1 )
                packet.ReadCString("Box Text");
        }
        public static void HandleArenaTeamEvent(Packet packet)
        {
            packet.ReadEnum<ArenaEvent>("Event", TypeCode.Byte);
            var count = packet.ReadByte("Count");
            for (var i = 0; i < count; ++i)
                packet.ReadCString("Param", i);

            if (packet.CanRead())
                packet.ReadGuid("GUID");
        }
        public static void HandleArenaTeamEvent(Packet packet)
        {
            packet.ReadByte("Event"); // FIXME: Use enum
            var count = packet.ReadByte("Count");
            for (var i = 0; i < count; ++i)
                packet.ReadCString("Param", i);

            if (packet.CanRead())
                packet.ReadGuid("GUID");
        }
示例#9
0
        public static void HandleAuraUpdate(Packet packet)
        {
            packet.ReadPackedGuid("GUID");

            /*var aura = new Aura(); */
            while (packet.CanRead())
                /*aura =*/
                ReadAuraUpdateBlock(ref packet);
            // TODO: Add this aura to a list of objects (searching by guid)
        }
示例#10
0
        public static void HandleInspectTalent(Packet packet)
        {
            if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_0_6a_13623))
                packet.ReadGuid("GUID");
            else
                packet.ReadPackedGuid("GUID");

            if (packet.Opcode == Opcodes.GetOpcode(Opcode.SMSG_INSPECT_TALENT))
                ReadTalentInfo(ref packet);

            var slotMask = packet.ReadUInt32("Slot Mask");
            var slot = 0;
            while (slotMask > 0)
            {
                if ((slotMask & 0x1) > 0)
                {
                    var name = "[" + (EquipmentSlotType)slot + "] ";
                    packet.ReadEntryWithName<UInt32>(StoreNameType.Item, name + "Item Entry");
                    var enchantMask = packet.ReadUInt16();
                    if (enchantMask > 0)
                    {
                        var enchantName = name + "Item Enchantments: ";
                        while (enchantMask > 0)
                        {
                            if ((enchantMask & 0x1) > 0)
                            {
                                enchantName += packet.ReadUInt16();
                                if (enchantMask > 1)
                                        enchantName += ", ";
                            }
                            enchantMask >>= 1;
                        }
                        packet.WriteLine(enchantName);
                    }
                    packet.ReadUInt16(name + "Unk Uint16");
                    packet.ReadPackedGuid(name + "Creator GUID");
                    packet.ReadUInt32(name + "Unk Uint32");
                }
                ++slot;
                slotMask >>= 1;
            }

            if (packet.Opcode == Opcodes.GetOpcode(Opcode.SMSG_INSPECT_TALENT)
                && packet.CanRead()) // otherwise it would fail for players without a guild
            {
                packet.ReadGuid("Guild GUID");
                packet.ReadUInt32("Guild Level");
                packet.ReadUInt64("Guild Xp");
                packet.ReadUInt32("Guild Members");
            }
        }
示例#11
0
        public static void HandlePetActionFeedback(Packet packet)
        {
            var state = packet.ReadEnum<PetFeedback>("Pet state", TypeCode.Byte);

            switch (state)
            {
                case PetFeedback.NothingToAttack:
                    if (ClientVersion.AddedInVersion(ClientType.Cataclysm) || packet.CanRead())
                        packet.ReadEntryWithName<Int32>(StoreNameType.Spell, "Spell ID");
                    break;
                case PetFeedback.CantAttackTarget:
                    if (ClientVersion.AddedInVersion(ClientType.Cataclysm))
                        packet.ReadInt32("Unk int32");
                    break;
            }
        }
示例#12
0
        public static void HandlePetActionFeedback(Packet packet)
        {
            var state = packet.ReadEnum<PetFeedback>("Pet state", TypeCode.Byte);

            switch (state)
            {
                case PetFeedback.NothingToAttack:
                    if (ClientVersion.AddedInVersion(ClientType.Cataclysm) || packet.CanRead())
                        packet.ReadEntry<Int32>(StoreNameType.Spell, "Spell ID");
                    break;
                case PetFeedback.CantAttackTarget:
                    if (ClientVersion.AddedInVersion(ClientType.Cataclysm))
                        packet.ReadEntry<Int32>(StoreNameType.Spell, "Spell ID");    // sub_8ADA60 2nd parameter is SpellID, check sub_8B22C0
                    break;
            }
        }
示例#13
0
        public static void HandlePetActionFeedback(Packet packet)
        {
            var state = packet.ReadByteE<PetFeedback>("Response");

            switch (state)
            {
                case PetFeedback.NothingToAttack:
                    if (ClientVersion.AddedInVersion(ClientType.Cataclysm) || packet.CanRead())
                        packet.ReadInt32<SpellId>("SpellID");
                    break;
                case PetFeedback.CantAttackTarget:
                    if (ClientVersion.AddedInVersion(ClientType.Cataclysm))
                        packet.ReadInt32<SpellId>("SpellID");    // sub_8ADA60 2nd parameter is SpellID, check sub_8B22C0
                    break;
            }
        }
示例#14
0
        public static void HandleInspectTalent(Packet packet)
        {
            if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_0_6a_13623))
                packet.ReadGuid("GUID");
            else
                packet.ReadPackedGuid("GUID");

            ReadTalentInfo(ref packet);
            ReadInspectPart(ref packet);

            if (packet.CanRead()) // otherwise it would fail for players without a guild
            {
                packet.ReadGuid("Guild GUID");
                packet.ReadUInt32("Guild Level");
                packet.ReadUInt64("Guild Xp");
                packet.ReadUInt32("Guild Members");
            }
        }
示例#15
0
        public static void HandleAuraUpdate(Packet packet)
        {
            Guid guid = packet.ReadPackedGuid("GUID");

            /*Aura aura = null; */
            while (packet.CanRead())
            {
                /*aura =*/
                Aura aura = ReadAuraUpdateBlock(ref packet);

                if (aura != null && guid.HasEntry() && guid.GetObjectType() == ObjectType.Unit)
                {
                    if (packet.SniffFileInfo.Stuffing.auraPackets.ContainsKey(guid))
                        packet.SniffFileInfo.Stuffing.auraPackets[guid].auraPackets.Enqueue(new AuraPacket(packet.Time, packet.Number, aura));
                    else
                        packet.SniffFileInfo.Stuffing.auraPackets.TryAdd(guid, new AuraPackets(new AuraPacket(packet.Time, packet.Number, aura)));
                }
                // TODO: Add this aura to a list of objects (searching by guid)
            }
        }
示例#16
0
        public static void HandleContactList(Packet packet)
        {
            packet.ReadInt32E<ContactListFlag>("List Flags");

            var count = packet.ReadInt32("Count");

            for (var i = 0; i < count; i++)
            {
                packet.ReadGuid("GUID");

                var flag = packet.ReadInt32E<ContactEntryFlag>("Flags");

                packet.ReadCString("Note");

                if (!flag.HasAnyFlag(ContactEntryFlag.Friend))
                    continue;

                ReadSingleContactBlock(packet, true);
            }

            if (packet.CanRead())
                WardenHandler.ReadCheatCheckDecryptionBlock(packet);
        }
示例#17
0
 public static void HandlePetSetAction(Packet packet)
 {
     var i = 0;
     packet.ReadGuid("GUID");
     while (packet.CanRead())
     {
         packet.ReadUInt32("Position", i);
         var action = (uint)packet.ReadUInt16() + (packet.ReadByte() << 16);
         packet.WriteLine("[{0}] Action: {1}", i, action);
         packet.ReadEnum<ActionButtonType>("Type", TypeCode.Byte, i++);
     }
 }
        public static void HandleAuctionSellItem(Packet packet)
        {
            packet.ReadGuid("Auctioneer GUID");

            if (ClientVersion.RemovedInVersion(ClientVersionBuild.V3_2_2a_10505))
            {
                packet.ReadGuid("Item Guid");
                packet.ReadUInt32("Item Count");
            }
            else
            {
                if (!packet.CanRead()) // dword_F4955C <= (unsigned int)dword_F49578[v13]
                    return;

                var count = packet.ReadUInt32("Count");
                for (int i = 0; i < count; ++i)
                {
                    packet.ReadGuid("Item Guid", i);
                    packet.ReadInt32("", i);
                }
            }

            if (ClientVersion.AddedInVersion(ClientType.Cataclysm))
            {
                packet.ReadUInt64("Bid");
                packet.ReadUInt64("Buyout");
            }
            else
            {
                packet.ReadUInt32("Bid");
                packet.ReadUInt32("Buyout");
            }

            packet.ReadUInt32("Expire Time");
        }
示例#19
0
        public static void HandleTransferPending(Packet packet)
        {
            packet.ReadInt32<MapId>("Map ID");

            if (!packet.CanRead())
                return;

            packet.ReadInt32("Transport Entry");
            packet.ReadInt32<MapId>("Transport Map ID");
        }
示例#20
0
        public static void HandleServerWardenData(Packet packet)
        {
            var opcode = packet.ReadEnum<WardenServerOpcode>("Warden Server Opcode", TypeCode.Byte);

            packet.SetPosition(0);

            switch (opcode)
            {
                case WardenServerOpcode.ModuleInfo:
                {
                    packet.ReadByte();

                    var md5 = packet.ReadBytes(16);
                    packet.WriteLine("Module MD5: " + Utilities.ByteArrayToHexString(md5));

                    var rc4 = packet.ReadBytes(16);
                    packet.WriteLine("Module RC4: " + Utilities.ByteArrayToHexString(rc4));

                    packet.ReadUInt32("Module Length");
                    break;
                }
                case WardenServerOpcode.ModuleChunk:
                {
                    packet.ReadByte();

                    var length = packet.ReadUInt16("Chunk Length");

                    var chunk = packet.ReadBytes(length);
                    packet.WriteLine("Module Chunk: " + Utilities.ByteArrayToHexString(chunk));
                    break;
                }
                case WardenServerOpcode.CheatChecks:
                {
                    packet.ReadByte();

                    byte length;
                    while ((length = packet.ReadByte()) != 0)
                    {
                        var strBytes = packet.ReadBytes(length);
                        var str = Encoding.ASCII.GetString(strBytes);
                        packet.WriteLine("String: " + str);
                    }

                    // var rest = (int)(packet.GetLength() - packet.GetPosition());
                    break;
                }
                case WardenServerOpcode.Data:
                {
                    while (packet.CanRead())
                    {
                        packet.ReadByte();

                        var length = packet.ReadUInt16("Data Length");

                        packet.ReadInt32("Data Checksum");

                        var data = packet.ReadBytes(length);
                        packet.WriteLine("Data: " + Utilities.ByteArrayToHexString(data));
                    }
                    break;
                }
                case WardenServerOpcode.Seed:
                {
                    packet.ReadByte();

                    var seed = packet.ReadBytes(16);
                    packet.WriteLine("Seed: " + Utilities.ByteArrayToHexString(seed));
                    break;
                }
            }
        }
        public static void HandleMultiplePackets2(Packet packet)
        {
            if (ClientVersion.AddedInVersion(ClientType.Cataclysm))
            {
                packet.ReadToEnd();
                throw new NotImplementedException("This opcode heavily relies on ALL" +
                                                  "of its contained packets to be parsed successfully");
                // Some sort of infinite loop happens here...
            }

            packet.WriteLine("{");
            var i = 0;
            while (packet.CanRead())
            {
                packet.Opcode = packet.ReadUInt16();

                if (i > 0)
                    packet.WriteLine();

                packet.Write("[{0}] ", i++);

                Handler.Parse(packet, isMultiple: true);
            }
            packet.WriteLine("}");
        }
        public static void HandleMultiplePackets(Packet packet)
        {
            //packet.WriteLine("Starting Multiple_packets handler");
            //packet.AsHex();
            // Testing: packet.WriteLine(packet.AsHex());
            packet.WriteLine("{");
            var i = 0;
            while (packet.CanRead())
            {
                var opcode = 0;
                var len = 0;
                byte[] bytes = null;
                if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_3_0_15005))
                {
                    opcode = packet.ReadUInt16();
                    // Why are there so many 0s in some packets? Should we have some check if opcode == 0 here?
                    len = packet.ReadUInt16();
                    bytes = packet.ReadBytes(len);
                }
                else if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_2_2_14545))
                {
                    len = packet.ReadUInt16();
                    opcode = packet.ReadUInt16();
                    bytes = packet.ReadBytes(len - 2);
                }
                else
                {
                    packet.ReadToEnd();
                }

                if (bytes == null || len == 0)
                    continue;

                if (i > 0)
                    packet.WriteLine();

                packet.Write("[{0}] ", i++);

                using (var newpacket = new Packet(bytes, opcode, packet.Time, packet.Direction, packet.Number, packet.Writer, packet.FileName))
                    Handler.Parse(newpacket, true);

            }
            packet.WriteLine("}");
        }
示例#23
0
        public static void HandleTransferPending(Packet packet)
        {
            packet.ReadEntryWithName<Int32>(StoreNameType.Map, "Map ID");

            if (!packet.CanRead())
                return;

            packet.ReadInt32("Transport Entry");
            packet.ReadEntryWithName<Int32>(StoreNameType.Map, "Transport Map ID");
        }
示例#24
0
        public static void HandleMirrorImageData(Packet packet)
        {
            packet.ReadGuid("GUID");
            packet.ReadUInt32("Display ID");
            var race = packet.ReadByteE<Race>("Race");

            if (race == Race.None)
                return;

            packet.ReadByteE<Gender>("Gender");
            packet.ReadByteE<Class>("Class");

            if (!packet.CanRead())
                return;

            packet.ReadByte("Skin");
            packet.ReadByte("Face");
            packet.ReadByte("Hair Style");
            packet.ReadByte("Hair Color");
            packet.ReadByte("Facial Hair");
            if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_2_2_14545))
                packet.ReadGuid("Guild Guid");
            else
                packet.ReadUInt32("Guild Id");

            EquipmentSlotType[] slots = {
                EquipmentSlotType.Head, EquipmentSlotType.Shoulders, EquipmentSlotType.Shirt,
                EquipmentSlotType.Chest, EquipmentSlotType.Waist, EquipmentSlotType.Legs,
                EquipmentSlotType.Feet, EquipmentSlotType.Wrists, EquipmentSlotType.Hands,
                EquipmentSlotType.Back, EquipmentSlotType.Tabard };

            for (var i = 0; i < 11; ++i)
                packet.ReadUInt32<ItemId>("ItemEntry", slots[i]);
        }
示例#25
0
        public static void HandleDispelFailed(Packet packet)
        {
            packet.ReadGuid("Caster GUID");
            packet.ReadGuid("Target GUID");
            packet.ReadUInt32<SpellId>("Dispelling Spell ID");

            for (var i = 0; packet.CanRead(); i++)
                packet.ReadUInt32<SpellId>("Dispelled Spell ID", i);
        }
示例#26
0
        public static void HandleGuildEvent(Packet packet)
        {
            if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_2_2_14545))
                packet.ReadEnum<GuildEventType442>("Event Type", TypeCode.Byte);
            else
                packet.ReadEnum<GuildEventType>("Event Type", TypeCode.Byte);

            var size = packet.ReadByte("Param Count");
            for (var i = 0; i < size; i++)
                packet.ReadCString("Param", i);

            if (packet.CanRead()) // FIXME 4 5 6 16 17 (GuildEventType changed for 4.2.2)
                packet.ReadGuid("GUID");
        }
        public static void HandleBattlefieldStatusServer(Packet packet)
        {
            var slot = packet.ReadUInt32("Queue Slot");
            if (slot >= 2)
            {
                packet.ReadToEnd(); // Client does this too
                return;
            }

            packet.ReadGuid("GUID");

            if (!packet.CanRead())
                return;

            if (ClientVersion.AddedInVersion(ClientVersionBuild.V3_3_0_10958))
            {
                packet.ReadByte("Min Level");
                packet.ReadByte("Max Level");
            }

            if (!packet.CanRead())
                return;

            packet.ReadUInt32("Client Instance ID");
            packet.ReadBoolean("Rated");
            var status = packet.ReadEnum<BattlegroundStatus>("Status", TypeCode.UInt32);
            switch (status)
            {
                case BattlegroundStatus.WaitQueue:
                    packet.ReadUInt32("Average Wait Time");
                    packet.ReadUInt32("Time in queue");
                    break;
                case BattlegroundStatus.WaitJoin:
                    packet.ReadEntryWithName<Int32>(StoreNameType.Map, "Map ID");

                    if (ClientVersion.AddedInVersion(ClientVersionBuild.V3_3_5_12213))
                        packet.ReadGuid("GUID");

                    packet.ReadUInt32("Time left");
                    break;
                case BattlegroundStatus.InProgress:
                    packet.ReadEntryWithName<Int32>(StoreNameType.Map, "Map ID");

                    if (ClientVersion.AddedInVersion(ClientVersionBuild.V3_3_5_12213))
                        packet.ReadGuid("GUID");

                    packet.ReadUInt32("Instance Expiration");
                    packet.ReadUInt32("Instance Start Time");
                    packet.ReadByte("Arena faction");
                    break;
            }
        }
示例#28
0
 public static void HandleSpellCooldown(Packet packet)
 {
     packet.ReadGuid("GUID");
     packet.ReadByte("Unk mask");
     while (packet.CanRead())
     {
         packet.ReadUInt32<SpellId>("Spell ID");
         packet.ReadInt32("Time");
     }
 }
示例#29
0
        public static void HandleTradeStatusExtended(Packet packet)
        {
            packet.ReadByte("Trader");
            packet.ReadUInt32("Trade Id");
            packet.ReadUInt32("Unk Slot 1");
            packet.ReadUInt32("Unk Slot 2");
            packet.ReadUInt32("Gold");
            packet.ReadEntryWithName<Int32>(StoreNameType.Spell, "Spell ID");

            while (packet.CanRead())
            {
                var slot = packet.ReadByte("Slot Index");
                packet.ReadEntryWithName<UInt32>(StoreNameType.Item, "Item Entry", slot);
                packet.ReadUInt32("Item Display ID", slot);
                packet.ReadUInt32("Item Count", slot);
                packet.ReadUInt32("Item Wrapped", slot);
                packet.ReadGuid("Item Gift Creator GUID", slot);
                packet.ReadUInt32("Item Perm Enchantment Id", slot);
                for (var i = 0; i < 3; ++i)
                    packet.ReadUInt32("Item Enchantment Id", slot, i);
                packet.ReadGuid("Item Creator GUID", slot);
                packet.ReadInt32("Item Spell Charges", slot);
                packet.ReadInt32("Item Suffix Factor", slot);
                packet.ReadInt32("Item Random Property ID", slot);
                packet.ReadUInt32("Item Lock ID", slot);
                packet.ReadUInt32("Item Max Durability", slot);
                packet.ReadUInt32("Item Durability", slot);
            }
        }
示例#30
0
        public static void HandleCastFailed(Packet packet)
        {
            if (ClientVersion.AddedInVersion(ClientType.WrathOfTheLichKing))
                packet.ReadByte("Cast count");

            packet.ReadUInt32<SpellId>("Spell ID");

            var result = packet.ReadByteE<SpellCastFailureReason>("Reason");

            if (ClientVersion.RemovedInVersion(ClientType.WrathOfTheLichKing))
                packet.ReadByte("Cast count");

            switch (result)
            {
                case SpellCastFailureReason.NeedExoticAmmo:
                    if (packet.CanRead())
                        packet.ReadUInt32("Item SubclassMask");
                    break;
                case SpellCastFailureReason.TooManyOfItem:
                    if (packet.CanRead())
                        packet.ReadUInt32("Limit");
                    break;
                case SpellCastFailureReason.Totems:
                case SpellCastFailureReason.TotemCategory:
                    if (packet.CanRead())
                        packet.ReadUInt32("Totem 1");
                    if (packet.CanRead())
                        packet.ReadUInt32("Totem 2");
                    break;
                case SpellCastFailureReason.Reagents:
                    if (packet.CanRead())
                        packet.ReadUInt32("Reagent ID");
                    break;
                case SpellCastFailureReason.RequiresSpellFocus:
                    if (packet.CanRead())
                        packet.ReadUInt32("Spell Focus");
                    break;
                case SpellCastFailureReason.RequiresArea:
                    if (packet.CanRead())
                        packet.ReadUInt32<AreaId>("Area ID");
                    break;
                case SpellCastFailureReason.CustomError:
                    if (packet.CanRead())
                        packet.ReadUInt32("Error ID");
                    break;
                case SpellCastFailureReason.PreventedByMechanic:
                    if (packet.CanRead())
                        packet.ReadUInt32E<SpellMechanic>("Mechanic");
                    break;
                case SpellCastFailureReason.EquippedItemClass:
                case SpellCastFailureReason.EquippedItemClassMainhand:
                case SpellCastFailureReason.EquippedItemClassOffhand:
                    if (packet.CanRead())
                        packet.ReadUInt32E<ItemClass>("Class");
                    if (packet.CanRead())
                        packet.ReadUInt32("SubclassMask");
                    break;
                case SpellCastFailureReason.MinSkill:
                    if (packet.CanRead())
                        packet.ReadUInt32("Skill Type"); // SkillLine.dbc
                    if (packet.CanRead())
                        packet.ReadUInt32("Required Amount");
                    break;
                case SpellCastFailureReason.FishingTooLow:
                    if (packet.CanRead())
                        packet.ReadUInt32("Required fishing skill");
                    break;
                // Following is post 3.3.5a
                case SpellCastFailureReason.NotReady:
                    if (packet.CanRead())
                        packet.ReadInt32("Extra Cast Number");
                    break;
                case SpellCastFailureReason.Silenced:
                case SpellCastFailureReason.NotStanding:
                    if (packet.CanRead())
                        packet.ReadInt32("Unk");
                    break;
                default:
                    if (packet.CanRead())
                        packet.ReadUInt32("Unknown1");
                    if (packet.CanRead())
                        packet.ReadUInt32("Unknown2");
                    break;
            }
        }