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 HandleSpellStart(Packet packet) { var casterGUID = new byte[8]; var casterUnitGUID = new byte[8]; var itemTargetGUID = new byte[8]; var guid4 = new byte[8]; var guid5 = new byte[8]; var unkGUID = new byte[8]; var targetGUID = new byte[8]; var guid8 = new byte[8]; var bits44 = packet.ReadBits("bits44", 24); casterGUID[5] = packet.ReadBit(); var guid9 = new byte[bits44][]; //18+ for (var i = 0; i < bits44; ++i) { guid9[i] = new byte[8]; packet.StartBitStream(guid9[i], 1, 0, 7, 2, 4, 3, 6, 5); } var hasSplineElevation = !packet.ReadBit("hasSplineElevation");//384 packet.ReadBit(); //fake bit casterUnitGUID[4] = packet.ReadBit(); casterGUID[2] = packet.ReadBit(); var runeCooldownPassedCount = (int)packet.ReadBits(3);//340 casterUnitGUID[2] = packet.ReadBit(); casterUnitGUID[6] = packet.ReadBit(); var missTypeCount = (int)packet.ReadBits(25); //84 var bits11 = (int)packet.ReadBits(13); casterGUID[4] = packet.ReadBit(); var hitcountPos = (int)packet.ReadBits(24); //52 casterUnitGUID[7] = packet.ReadBit(); var guid11 = new byte[hitcountPos][]; //14+ for (var i = 0; i < hitcountPos; ++i) { guid11[i] = new byte[8]; packet.StartBitStream(guid11[i], 5, 0, 3, 4, 7, 2, 6, 1); } var hasSourceLocation = packet.ReadBit("hasSourceLocation"); //152 var predictedPowerCount = (int)packet.ReadBits(21); //320 packet.StartBitStream(itemTargetGUID, 3, 0, 1, 7, 2, 6, 4, 5); //120-127 var hasElevation = !packet.ReadBit("hasElevation"); //90 var hasTargetString = !packet.ReadBit("hasTargetString"); var hasAmmoInventoryType = !packet.ReadBit("hasAmmoInventoryType");//368 var hasDestLocation = packet.ReadBit("hasDestLocation");//184 var hasDelayTime = !packet.ReadBit("hasDelayTime"); //89 casterGUID[3] = packet.ReadBit(); if (hasDestLocation) packet.StartBitStream(guid4, 1, 6, 2, 7, 0, 3, 5, 4); //160-167 var hasAmmoDisplayId = !packet.ReadBit("hasAmmoDisplayId"); //91 if (hasSourceLocation) packet.StartBitStream(guid5, 4, 3, 5, 1, 7, 0, 6, 2); //128-135 packet.ReadBit(); //fake bit 104 casterGUID[6] = packet.ReadBit(); packet.StartBitStream(unkGUID, 2, 1, 7, 6, 0, 5, 3, 4); //416-423 var hasTargetFlags = !packet.ReadBit("hasTargetFlags"); if (hasTargetFlags) packet.ReadBitsE<TargetFlag>("Target Flags", 20); casterGUID[1] = packet.ReadBit(); var hasPredictedHeal = !packet.ReadBit("hasPredictedHeal"); //106 var hasRunesStateBefore = !packet.ReadBit("hasRunesStateBefore"); //336 var hasCastSchoolImmunities = !packet.ReadBit("hasCastSchoolImmunities"); //101 casterUnitGUID[5] = packet.ReadBit(); packet.ReadBit(); //28 fake bit var extraTargetCount = (int)packet.ReadBits("extraTargetCount", 20);//388 var guid10 = new byte[extraTargetCount][]; for (var i = 0; i < extraTargetCount; ++i) //388 { guid10[i] = new byte[8]; packet.StartBitStream(guid10[i], 1, 6, 2, 3, 5, 7, 0, 4); //98+ } packet.StartBitStream(targetGUID, 1, 4, 6, 7, 5, 3, 0, 2); //112-119 casterGUID[0] = packet.ReadBit(); casterUnitGUID[3] = packet.ReadBit(); var hasRunesStateAfter = !packet.ReadBit("hasRunesStateAfter");//337 var bitsC0 = 0u; if (hasTargetString) bitsC0 = packet.ReadBits(7);//192 for (var i = 0; i < missTypeCount; ++i) { if (packet.ReadBits("bits22[0]", 4, i) == 11) packet.ReadBits("bits22[1]", 4, i); } var hasUnkMovementField = !packet.ReadBit("hasUnkMovementField"); // 102 casterUnitGUID[1] = packet.ReadBit(); var hasVisualChain = packet.ReadBit("hasVisualChain");//380 casterGUID[7] = packet.ReadBit(); var hasPredictedType = !packet.ReadBit("hasPredictedType");//428 casterUnitGUID[0] = packet.ReadBit(); packet.ParseBitStream(itemTargetGUID, 1, 7, 6, 0, 4, 2, 3, 5); //120-127 packet.WriteGuid("Guid3", itemTargetGUID); for (var i = 0; i < hitcountPos; ++i) { packet.ParseBitStream(guid11[i], 4, 5, 3, 0, 6, 2, 1, 7);//14+ packet.WriteGuid("Guid11", guid11[i]); } packet.ParseBitStream(targetGUID, 4, 5, 1, 7, 6, 3, 2, 0); //112-119 packet.WriteGuid("Guid7", targetGUID); packet.ReadInt32("CastTime"); //12 packet.ParseBitStream(unkGUID, 4, 5, 3, 2, 1, 6, 7, 0); //416-423 packet.WriteGuid("Guid6", unkGUID); if (hasDestLocation) { packet.ReadXORByte(guid4, 4); //160-167 packet.ReadXORByte(guid4, 0); packet.ReadXORByte(guid4, 5); packet.ReadXORByte(guid4, 7); packet.ReadXORByte(guid4, 1); packet.ReadXORByte(guid4, 2); packet.ReadXORByte(guid4, 3); packet.ReadSingle("Position Y"); packet.ReadSingle("Position Z"); packet.ReadXORByte(guid4, 6); packet.ReadSingle("Position X"); packet.WriteGuid("Guid4", guid4); } for (var i = 0; i < extraTargetCount; ++i) { packet.ReadXORByte(guid10[i], 0); //98+ packet.ReadSingle("Float186"); packet.ReadXORByte(guid10[i], 1); packet.ReadXORByte(guid10[i], 5); packet.ReadXORByte(guid10[i], 4); packet.ReadXORByte(guid10[i], 7); packet.ReadSingle("Float187"); packet.ReadXORByte(guid10[i], 3); packet.ReadSingle("Float188"); packet.ReadXORByte(guid10[i], 6); packet.ReadXORByte(guid10[i], 2); packet.WriteGuid("Guid10", guid10[i]); } if (hasSourceLocation) { packet.ReadXORByte(unkGUID, 0); //128-135 packet.ReadXORByte(unkGUID, 5); packet.ReadXORByte(unkGUID, 4); packet.ReadXORByte(unkGUID, 7); packet.ReadXORByte(unkGUID, 3); packet.ReadXORByte(unkGUID, 6); packet.ReadSingle("Position X"); packet.ReadXORByte(unkGUID, 2); packet.ReadSingle("Position Z"); packet.ReadXORByte(unkGUID, 1); packet.ReadSingle("Position Y"); packet.WriteGuid("Guid6", unkGUID); } packet.ReadXORByte(casterGUID, 4); for (var i = 0; i < bits44; ++i) { packet.ParseBitStream(guid9[i], 4, 2, 0, 6, 1, 7, 3, 5); //18+ packet.WriteGuid("Guid9", guid9[i]); } if (hasCastSchoolImmunities) // 101 packet.ReadUInt32("hasCastSchoolImmunities"); packet.ReadXORByte(casterGUID, 2); if (hasUnkMovementField) // 102 packet.ReadUInt32("hasUnkMovementField"); if (hasVisualChain) //380 { packet.ReadInt32("Int174"); packet.ReadInt32("Int178"); } for (var i = 0; i < predictedPowerCount; ++i) { packet.ReadInt32("Value", i); packet.ReadByteE<PowerType>("Power type", i); } if (hasRunesStateBefore) //336 packet.ReadByte("hasRunesStateBefore"); var flags = packet.ReadInt32E<CastFlag>("Cast Flags"); //10 packet.ReadXORByte(casterGUID, 5); packet.ReadXORByte(casterGUID, 7); packet.ReadXORByte(casterGUID, 1); packet.ReadByte("CastCount"); packet.ReadXORByte(casterUnitGUID, 7); packet.ReadXORByte(casterUnitGUID, 0); packet.ReadXORByte(casterGUID, 6); packet.ReadXORByte(casterGUID, 0); packet.ReadXORByte(casterUnitGUID, 1); if (hasAmmoInventoryType) //368 packet.ReadByte("AmmoInventoryType"); if (hasPredictedHeal) //106 packet.ReadUInt32("hasPredictedHeal"); packet.ReadXORByte(casterUnitGUID, 6); packet.ReadXORByte(casterUnitGUID, 3); if (hasSplineElevation) //384 packet.ReadByte("Byte180"); if (hasDelayTime) //89 packet.ReadUInt32("hasDelayTime"); var spellId = packet.ReadInt32<SpellId>("Spell ID"); //9 if (hasAmmoDisplayId) //91 packet.ReadUInt32("hasAmmoDisplayId"); packet.ReadXORByte(casterUnitGUID, 4); packet.ReadXORByte(casterUnitGUID, 5); if (hasRunesStateAfter)//337 packet.ReadByte("hasRunesStateAfter"); packet.ReadXORByte(casterUnitGUID, 2); packet.ReadWoWString("Text", bitsC0); if (hasPredictedType) //428 packet.ReadByte("hasPredictedType"); packet.ReadXORByte(casterGUID, 3); if (hasElevation) //90 packet.ReadSingle("Elevation"); for (var i = 0; i < runeCooldownPassedCount; ++i) //340 packet.ReadByte("runeCooldownPassedCount", i); if (flags.HasAnyFlag(CastFlag.Unknown21)) { var spellClick = new NpcSpellClick(); spellClick.SpellId = (uint)spellId; spellClick.CasterGUID = new WowGuid64(BitConverter.ToUInt64(casterGUID, 0)); spellClick.TargetGUID =new WowGuid64(BitConverter.ToUInt64(targetGUID, 0)); Storage.SpellClicks.Add(spellClick, packet.TimeSpan); } packet.WriteGuid("casterUnitGUID", casterUnitGUID); packet.WriteGuid("CasterGUID", casterGUID); packet.WriteGuid("targetGUID", targetGUID); packet.WriteGuid("ItemTargetGUID", itemTargetGUID); packet.WriteGuid("UnkGUID", unkGUID); }