Example #1
0
        public static void HandleSpellStart(Packet packet)
        {
            bool isSpellGo = packet.Opcode == Opcodes.GetOpcode(Opcode.SMSG_SPELL_GO, Direction.ServerToClient);

            var casterGUID = packet.ReadPackedGuid("Caster GUID");
            packet.ReadPackedGuid("Caster Unit GUID");

            if (ClientVersion.AddedInVersion(ClientVersionBuild.V3_0_2_9056))
                packet.ReadByte("Cast Count");

            var spellId = packet.ReadInt32<SpellId>("Spell ID");

            if (ClientVersion.RemovedInVersion(ClientVersionBuild.V3_0_2_9056) && !isSpellGo)
                packet.ReadByte("Cast Count");

            CastFlag flags;
            if (ClientVersion.AddedInVersion(ClientVersionBuild.V3_0_2_9056))
                flags = packet.ReadInt32E<CastFlag>("Cast Flags");
            else
                flags = packet.ReadUInt16E<CastFlag>("Cast Flags");

            packet.ReadUInt32("Time");
            if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_3_0_15005))
                packet.ReadUInt32("Time2");

            if (isSpellGo)
            {
                var hitCount = packet.ReadByte("Hit Count");
                for (var i = 0; i < hitCount; i++)
                    packet.ReadGuid("Hit GUID", i);

                var missCount = packet.ReadByte("Miss Count");
                for (var i = 0; i < missCount; i++)
                {
                    packet.ReadGuid("Miss GUID", i);

                    var missType = packet.ReadByteE<SpellMissType>("Miss Type", i);
                    if (missType == SpellMissType.Reflect)
                        packet.ReadByteE<SpellMissType>("Miss Reflect", i);
                }
            }

            var targetFlags = packet.ReadInt32E<TargetFlag>("Target Flags");

            WowGuid targetGUID = new WowGuid64();
            if (targetFlags.HasAnyFlag(TargetFlag.Unit | TargetFlag.CorpseEnemy | TargetFlag.GameObject |
                TargetFlag.CorpseAlly | TargetFlag.UnitMinipet))
                targetGUID = packet.ReadPackedGuid("Target GUID");

            if (targetFlags.HasAnyFlag(TargetFlag.Item | TargetFlag.TradeItem))
                packet.ReadPackedGuid("Item Target GUID");

            if (targetFlags.HasAnyFlag(TargetFlag.SourceLocation))
            {
                if (ClientVersion.AddedInVersion(ClientVersionBuild.V3_2_0_10192))
                    packet.ReadPackedGuid("Source Transport GUID");

                packet.ReadVector3("Source Position");
            }

            if (targetFlags.HasAnyFlag(TargetFlag.DestinationLocation))
            {
                if (ClientVersion.AddedInVersion(ClientVersionBuild.V3_0_8_9464))
                    packet.ReadPackedGuid("Destination Transport GUID");

                packet.ReadVector3("Destination Position");
            }

            if (targetFlags.HasAnyFlag(TargetFlag.NameString))
                packet.ReadCString("Target String");

            if (ClientVersion.AddedInVersion(ClientVersionBuild.V3_0_2_9056))
            {
                if (flags.HasAnyFlag(CastFlag.PredictedPower))
                {
                    if (ClientVersion.AddedInVersion(ClientVersionBuild.V5_1_0_16309))
                    {
                        var count = packet.ReadUInt32("Modified Power Count");
                        for (var i = 0; i < count; i++)
                        {
                            packet.ReadUInt32E<PowerType>("Power Type", i);
                            packet.ReadInt32("Power Value", i);
                        }
                    }
                    else
                        packet.ReadInt32("Rune Cooldown");
                }

                if (flags.HasAnyFlag(CastFlag.RuneInfo))
                {
                    var spellRuneState = packet.ReadByte("Spell Rune State");
                    var playerRuneState = packet.ReadByte("Player Rune State");

                    for (var i = 0; i < 6; i++)
                    {
                        if (ClientVersion.RemovedInVersion(ClientVersionBuild.V4_2_2_14545))
                        {
                            var mask = 1 << i;
                            if ((mask & spellRuneState) == 0)
                                continue;

                            if ((mask & playerRuneState) != 0)
                                continue;
                        }

                        packet.ReadByte("Rune Cooldown Passed", i);
                    }
                }

                if (isSpellGo)
                {
                    if (flags.HasAnyFlag(CastFlag.AdjustMissile))
                    {
                        packet.ReadSingle("Elevation");
                        packet.ReadInt32("Delay time");
                    }
                }
            }

            if (flags.HasAnyFlag(CastFlag.Projectile))
            {
                packet.ReadInt32("Ammo Display ID");
                packet.ReadInt32E<InventoryType>("Ammo Inventory Type");
            }

            if (ClientVersion.AddedInVersion(ClientVersionBuild.V3_0_2_9056))
            {
                if (isSpellGo)
                {
                    if (flags.HasAnyFlag(CastFlag.VisualChain))
                    {
                        packet.ReadInt32("Unk Int32 2");
                        packet.ReadInt32("Unk Int32 3");
                    }

                    if (targetFlags.HasAnyFlag(TargetFlag.DestinationLocation))
                        packet.ReadSByte("Unk Byte 2"); // Some count

                    if (targetFlags.HasAnyFlag(TargetFlag.ExtraTargets))
                    {
                        var targetCount = packet.ReadInt32("Extra Targets Count");
                        for (var i = 0; i < targetCount; i++)
                        {
                            packet.ReadVector3("Extra Target Position", i);
                            packet.ReadGuid("Extra Target GUID", i);
                        }
                    }
                }
                else
                {
                    if (flags.HasAnyFlag(CastFlag.Immunity))
                    {
                        packet.ReadInt32("CastSchoolImmunities");
                        packet.ReadInt32("CastImmunities");
                    }

                    if (flags.HasAnyFlag(CastFlag.HealPrediction))
                    {
                        packet.ReadInt32<SpellId>("Predicted Spell ID");

                        if (packet.ReadByte("Unk Byte") == 2)
                            packet.ReadPackedGuid("Unk Guid");
                    }
                }
            }

            if (flags.HasAnyFlag(CastFlag.Unknown21) && !isSpellGo)
            {
                NpcSpellClick spellClick = new NpcSpellClick
                {
                    SpellID = (uint) spellId,
                    CasterGUID = casterGUID,
                    TargetGUID = targetGUID
                };

                Storage.SpellClicks.Add(spellClick, packet.TimeSpan);
            }

            if (isSpellGo)
                packet.AddSniffData(StoreNameType.Spell, spellId, "SPELL_GO");
        }
Example #2
0
        public static void HandlePetSpells(Packet packet)
        {
            var guid = packet.ReadGuid("GUID");
            // Equal to "Clear spells" pre cataclysm
            if (guid.IsEmpty())
                return;

            if (ClientVersion.AddedInVersion(ClientVersionBuild.V3_1_0_9767))
                packet.ReadUInt16E<CreatureFamily>("Pet Family"); // vehicles -> 0

            if (ClientVersion.AddedInVersion(ClientVersionBuild.V5_1_0_16309))
                packet.ReadUInt16("Unk UInt16");

            packet.ReadUInt32("Expiration Time");

            ReadPetFlags(packet);

            var isPet = guid.GetHighType() == HighGuidType.Pet;
            var isVehicle = guid.GetHighType() == HighGuidType.Vehicle;
            var isMinion = guid.GetHighType() == HighGuidType.Creature;
            const int maxCreatureSpells = 10;
            var spells = new List<uint>(maxCreatureSpells);
            for (var i = 0; i < maxCreatureSpells; i++) // Read pet/vehicle spell ids
            {
                var spell16 = packet.ReadUInt16();
                var spell8 = packet.ReadByte();
                var spellId = spell16 + (spell8 << 16);
                var slot = packet.ReadByte("Slot", i);

                if (spellId <= 4)
                    packet.AddValue("Action", spellId, i);
                else
                    packet.AddValue("Spell", StoreGetters.GetName(StoreNameType.Spell, spellId), i);

                // Spells for pets are on DBCs; also no entry in guid
                // We don't need the actions sent for minions (slots lower than 8)
                if (!isPet && (isVehicle || (isMinion && slot >= 8)))
                    spells.Add((uint)spellId);
            }

            if (spells.Count != 0)
            {
                SpellsX spellsCr;
                spellsCr.Spells = spells.ToArray();
                Storage.SpellsX.Add(guid.GetEntry(), spellsCr, packet.TimeSpan);
            }

            var spellCount = packet.ReadByte("Spell Count"); // vehicles -> 0, pets -> != 0. Could this be auras?
            for (var i = 0; i < spellCount; i++)
            {
                packet.ReadUInt16<SpellId>("Spell", i);
                packet.ReadInt16("Active", i);
            }

            var cdCount = packet.ReadByte("Cooldown count");
            for (var i = 0; i < cdCount; i++)
            {
                if (ClientVersion.AddedInVersion(ClientVersionBuild.V3_1_0_9767))
                    packet.ReadUInt32<SpellId>("Spell", i);
                else
                    packet.ReadUInt16<SpellId>("Spell", i);

                packet.ReadUInt16("Category", i);
                packet.ReadUInt32("Cooldown", i);
                packet.ReadUInt32("Category Cooldown", i);
            }

            if (ClientVersion.AddedInVersion(ClientVersionBuild.V5_1_0_16309))
            {
                var unkLoopCounter = packet.ReadByte("Unk count");
                for (var i = 0; i < unkLoopCounter; i++)
                {
                    packet.ReadUInt32("Unk UInt32 1", i);
                    packet.ReadByte("Unk Byte", i);
                    packet.ReadUInt32("Unk UInt32 2", i);
                }
            }
        }
Example #3
0
        private static MovementInfo ReadMovementUpdateBlock(Packet packet, WowGuid guid, object index)
        {
            if (ClientVersion.AddedInVersion(ClientVersionBuild.V5_1_0_16309))
                return ReadMovementUpdateBlock510(packet, guid, index);

            if (ClientVersion.AddedInVersion(ClientVersionBuild.V5_0_4_16016))
                return ReadMovementUpdateBlock504(packet, guid, index);

            if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_3_3_15354))
                return ReadMovementUpdateBlock433(packet, guid, index);

            if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_3_2_15211))
                return ReadMovementUpdateBlock432(packet, guid, index);

            if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_3_0_15005))
                return ReadMovementUpdateBlock430(packet, guid, index);

            var moveInfo = new MovementInfo();

            UpdateFlag flags;
            if (ClientVersion.AddedInVersion(ClientVersionBuild.V3_1_0_9767))
                flags = packet.ReadUInt16E<UpdateFlag>("Update Flags", index);
            else
                flags = packet.ReadByteE<UpdateFlag>("Update Flags", index);

            if (flags.HasAnyFlag(UpdateFlag.Living))
            {
                moveInfo = MovementHandler.ReadMovementInfo(packet, guid, index);
                var moveFlags = moveInfo.Flags;

                for (var i = 0; i < 9; ++i)
                {
                    var speedType = (SpeedType)i;
                    var speed = packet.ReadSingle(speedType + " Speed", index);

                    switch (speedType)
                    {
                        case SpeedType.Walk:
                        {
                            moveInfo.WalkSpeed = speed / 2.5f;
                            break;
                        }
                        case SpeedType.Run:
                        {
                            moveInfo.RunSpeed = speed / 7.0f;
                            break;
                        }
                    }
                }

                // Movement flags seem incorrect for 4.2.2
                // guess in which version they stopped checking movement flag and used bits
                if ((ClientVersion.RemovedInVersion(ClientVersionBuild.V4_2_0_14333) && moveFlags.HasAnyFlag(MovementFlag.SplineEnabled)) || moveInfo.HasSplineData)
                {
                    // Temp solution
                    // TODO: Make Enums version friendly
                    if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_2_0_14333))
                    {
                        var splineFlags422 = packet.ReadInt32E<SplineFlag422>("Spline Flags", index);
                        if (splineFlags422.HasAnyFlag(SplineFlag422.FinalOrientation))
                        {
                            packet.ReadSingle("Final Spline Orientation", index);
                        }
                        else
                        {
                            if (splineFlags422.HasAnyFlag(SplineFlag422.FinalTarget))
                                packet.ReadGuid("Final Spline Target GUID", index);
                            else if (splineFlags422.HasAnyFlag(SplineFlag422.FinalPoint))
                                packet.ReadVector3("Final Spline Coords", index);
                        }
                    }
                    else
                    {
                        var splineFlags = packet.ReadInt32E<SplineFlag>("Spline Flags", index);
                        if (splineFlags.HasAnyFlag(SplineFlag.FinalTarget))
                            packet.ReadGuid("Final Spline Target GUID", index);
                        else if (splineFlags.HasAnyFlag(SplineFlag.FinalOrientation))
                            packet.ReadSingle("Final Spline Orientation", index);
                        else if (splineFlags.HasAnyFlag(SplineFlag.FinalPoint))
                            packet.ReadVector3("Final Spline Coords", index);
                    }

                    packet.ReadInt32("Spline Time", index);
                    packet.ReadInt32("Spline Full Time", index);
                    packet.ReadInt32("Spline ID", index);

                    if (ClientVersion.AddedInVersion(ClientVersionBuild.V3_1_0_9767))
                    {
                        packet.ReadSingle("Spline Duration Multiplier", index);
                        packet.ReadSingle("Spline Duration Multiplier Next", index);
                        packet.ReadSingle("Spline Vertical Acceleration", index);
                        packet.ReadInt32("Spline Start Time", index);
                    }

                    var splineCount = packet.ReadInt32();
                    for (var i = 0; i < splineCount; i++)
                        packet.ReadVector3("Spline Waypoint", index, i);

                    if (ClientVersion.AddedInVersion(ClientVersionBuild.V3_1_0_9767))
                        packet.ReadByteE<SplineMode>("Spline Mode", index);

                    packet.ReadVector3("Spline Endpoint", index);
                }
            }
            else // !UpdateFlag.Living
            {
                if (flags.HasAnyFlag(UpdateFlag.GOPosition))
                {
                    moveInfo.TransportGuid = packet.ReadPackedGuid("GO Transport GUID", index);

                    moveInfo.Position = packet.ReadVector3("GO Position", index);
                    moveInfo.TransportOffset.X = packet.ReadSingle();
                    moveInfo.TransportOffset.Y = packet.ReadSingle();
                    moveInfo.TransportOffset.Z = packet.ReadSingle();

                    moveInfo.Orientation = packet.ReadSingle("GO Orientation", index);
                    moveInfo.TransportOffset.O = moveInfo.Orientation;

                    packet.AddValue("GO Transport Position", moveInfo.TransportOffset, index);

                    packet.ReadSingle("Corpse Orientation", index);
                }
                else if (flags.HasAnyFlag(UpdateFlag.StationaryObject))
                {
                    moveInfo.Position = packet.ReadVector3("Stationary Position", index);
                    moveInfo.Orientation = packet.ReadSingle("O", index);
                }
            }

            if (ClientVersion.RemovedInVersion(ClientVersionBuild.V4_2_2_14545))
            {
                if (flags.HasAnyFlag(UpdateFlag.Unknown1))
                    packet.ReadUInt32("Unk Int32", index);

                if (flags.HasAnyFlag(UpdateFlag.LowGuid))
                    packet.ReadUInt32("Low GUID", index);
            }

            if (flags.HasAnyFlag(UpdateFlag.AttackingTarget))
                packet.ReadPackedGuid("Target GUID", index);

            if (flags.HasAnyFlag(UpdateFlag.Transport))
                packet.ReadUInt32("Transport unk timer", index);

            if (flags.HasAnyFlag(UpdateFlag.Vehicle))
            {
                moveInfo.VehicleId = packet.ReadUInt32("[" + index + "] Vehicle ID");
                packet.ReadSingle("Vehicle Orientation", index);
            }

            if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_2_2_14545))
            {
                if (flags.HasAnyFlag(UpdateFlag.AnimKits))
                {
                    packet.ReadInt16("Unk Int16", index);
                    packet.ReadInt16("Unk Int16", index);
                    packet.ReadInt16("Unk Int16", index);
                }
            }

            if (flags.HasAnyFlag(UpdateFlag.GORotation))
                moveInfo.Rotation = packet.ReadPackedQuaternion("GO Rotation", index);

            if (ClientVersion.AddedInVersion(ClientVersionBuild.V4_2_2_14545))
            {
                if (flags.HasAnyFlag(UpdateFlag.TransportUnkArray))
                {
                    var count = packet.ReadByte("Count", index);
                    for (var i = 0; i < count; i++)
                        packet.ReadInt32("Unk Int32", index, count);
                }
            }

            return moveInfo;
        }
Example #4
0
        public static void HandlePartyMemberStats422(Packet packet)
        {
            if (packet.Opcode == Opcodes.GetOpcode(Opcode.SMSG_PARTY_MEMBER_STATS_FULL, Direction.ServerToClient))
                packet.ReadBool("Add arena opponent");

            packet.ReadPackedGuid("GUID");
            var updateFlags = packet.ReadInt32E<GroupUpdateFlag422>("Update Flags");

            if (updateFlags.HasFlag(GroupUpdateFlag422.Status))
                packet.ReadInt16E<GroupMemberStatusFlag>("Status");

            if (updateFlags.HasFlag(GroupUpdateFlag422.CurrentHealth))
            {
                if (ClientVersion.AddedInVersion(ClientType.WrathOfTheLichKing))
                    packet.ReadInt32("Current Health");
                else
                    packet.ReadUInt16("Current Health");
            }

            if (updateFlags.HasFlag(GroupUpdateFlag422.MaxHealth))
            {
                if (ClientVersion.AddedInVersion(ClientType.WrathOfTheLichKing))
                    packet.ReadInt32("Max Health");
                else
                    packet.ReadUInt16("Max Health");
            }

            if (updateFlags.HasFlag(GroupUpdateFlag422.PowerType))
                packet.ReadByteE<PowerType>("Power type");

            if (updateFlags.HasFlag(GroupUpdateFlag422.CurrentPower))
                packet.ReadInt16("Current Power");

            if (updateFlags.HasFlag(GroupUpdateFlag422.MaxPower))
                packet.ReadInt16("Max Power");

            if (updateFlags.HasFlag(GroupUpdateFlag422.Level))
                packet.ReadInt16("Level");

            if (updateFlags.HasFlag(GroupUpdateFlag422.Zone))
                packet.ReadInt16<ZoneId>("Zone Id");

            if (updateFlags.HasFlag(GroupUpdateFlag422.Unk100))
                packet.ReadInt16("Unk");

            if (updateFlags.HasFlag(GroupUpdateFlag422.Position))
            {
                packet.ReadInt16("X");
                packet.ReadInt16("Y");
                packet.ReadInt16("Z");
            }

            if (updateFlags.HasFlag(GroupUpdateFlag422.Auras))
            {
                packet.ReadByte("Unk byte");
                var mask = packet.ReadUInt64("Aura mask");
                var cnt = packet.ReadUInt32("Aura count");
                for (var i = 0; i < cnt; ++i)
                {
                    if (mask == 0) // bad packet
                        break;

                    if ((mask & (1ul << i)) == 0)
                        continue;

                    packet.ReadUInt32<SpellId>("Spell Id", i);

                    var aflags = packet.ReadUInt16E<AuraFlag>("Aura Flags", i);
                    if (aflags.HasFlag(AuraFlag.Scalable))
                        for (var j = 0; j < 3; ++j)
                            packet.ReadInt32("Effect BasePoints", i, j);
                }
            }

            if (updateFlags.HasFlag(GroupUpdateFlag422.PetGuid))
                packet.ReadUInt64("Pet GUID");

            if (updateFlags.HasFlag(GroupUpdateFlag422.PetName))
                packet.ReadCString("Pet Name");

            if (updateFlags.HasFlag(GroupUpdateFlag422.PetModelId))
                packet.ReadUInt16("Pet Model Id");

            if (updateFlags.HasFlag(GroupUpdateFlag422.PetCurrentHealth))
                packet.ReadUInt32("Pet Current Health");

            if (updateFlags.HasFlag(GroupUpdateFlag422.PetMaxHealth))
                packet.ReadUInt32("Pet Max Health");

            if (updateFlags.HasFlag(GroupUpdateFlag422.PetPowerType))
                packet.ReadByteE<PowerType>("Pet Power type");

            if (updateFlags.HasFlag(GroupUpdateFlag422.PetCurrentPower))
                packet.ReadInt16("Pet Current Power");

            if (updateFlags.HasFlag(GroupUpdateFlag422.PetMaxPower))
                packet.ReadInt16("Pet Max Power");

            if (updateFlags.HasFlag(GroupUpdateFlag422.PetAuras))
            {
                packet.ReadByte("Unk byte");
                var mask = packet.ReadUInt64("Pet Aura mask");
                var cnt = packet.ReadUInt32("Pet Aura count");
                for (var i = 0; i < cnt; ++i)
                {
                    if ((mask & (1ul << i)) == 0)
                        continue;

                    packet.ReadUInt32<SpellId>("Spell Id", i);

                    var aflags = packet.ReadUInt16E<AuraFlag>("Aura Flags", i);
                    if (aflags.HasFlag(AuraFlag.Scalable))
                        for (var j = 0; j < 3; ++j)
                            packet.ReadInt32("Effect BasePoints", i, j);
                }
            }

            if (updateFlags.HasFlag(GroupUpdateFlag422.VehicleSeat))
                packet.ReadInt32("Vehicle Seat?");

            if (updateFlags.HasFlag(GroupUpdateFlag422.Phase))
            {
                packet.ReadInt32("Unk Int32");

                var count = packet.ReadInt32("Phase Count");
                for (var i = 0; i < count; ++i)
                    packet.ReadInt16("Phase Id");
            }
        }