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"); }
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); } } }
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; }
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"); } }