diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/GossipDef.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 142 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 2 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.h | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/QuestHandler.cpp | 33 | ||||
-rw-r--r-- | src/server/game/Server/Packets/CombatPackets.cpp | 118 | ||||
-rw-r--r-- | src/server/game/Server/Packets/CombatPackets.h | 123 | ||||
-rw-r--r-- | src/server/game/Server/Packets/SpellPackets.cpp | 17 | ||||
-rw-r--r-- | src/server/game/Server/Packets/SpellPackets.h | 16 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 25 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 10 |
13 files changed, 380 insertions, 134 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 7fb3822c888..3765c54b42a 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -51,6 +51,7 @@ #include "WaypointMovementGenerator.h" #include "World.h" #include "WorldPacket.h" +#include "CombatPackets.h" #include "Transport.h" @@ -1826,12 +1827,12 @@ Player* Creature::SelectNearestPlayer(float distance) const void Creature::SendAIReaction(AiReaction reactionType) { - WorldPacket data(SMSG_AI_REACTION, 12); + WorldPackets::Combat::AIReaction packet; - data << GetGUID(); - data << uint32(reactionType); + packet.UnitGUID = GetGUID(); + packet.Reaction = reactionType; - ((WorldObject*)this)->SendMessageToSet(&data, true); + ((WorldObject*)this)->SendMessageToSet(packet.Write(), true); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_AI_REACTION, type %u.", reactionType); } diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index 4d14ede70fe..c947d4f49da 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -23,6 +23,7 @@ #include "WorldPacket.h" #include "WorldSession.h" #include "Formulas.h" +#include "QuestPackets.h" GossipMenu::GossipMenu() { @@ -373,11 +374,11 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string void PlayerMenu::SendQuestGiverStatus(uint32 questStatus, ObjectGuid npcGUID) const { - WorldPacket data(SMSG_QUESTGIVER_STATUS, 8 + 4); - data << npcGUID; - data << uint32(questStatus); + WorldPackets::Quest::QuestGiverStatus packet; + packet.QuestGiver.Guid = npcGUID; + packet.QuestGiver.Status = questStatus; - _session->SendPacket(&data); + _session->SendPacket(packet.Write()); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC=%s, status=%u", npcGUID.ToString().c_str(), questStatus); } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 29c3af9d685..a11c75a2c6f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -89,6 +89,7 @@ #include "MiscPackets.h" #include "ChatPackets.h" #include "MovementPackets.h" +#include "ItemPackets.h" #define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS) @@ -20976,9 +20977,10 @@ void Player::SetSpellModTakingSpell(Spell* spell, bool apply) // send Proficiency void Player::SendProficiency(ItemClass itemClass, uint32 itemSubclassMask) { - WorldPacket data(SMSG_SET_PROFICIENCY, 1 + 4); - data << uint8(itemClass) << uint32(itemSubclassMask); - GetSession()->SendPacket(&data); + WorldPackets::Item::SetProficiency packet; + packet.ProficiencyMask = itemSubclassMask; + packet.ProficiencyClass = itemClass; + GetSession()->SendPacket(packet.Write()); } void Player::RemovePetitionsAndSigns(ObjectGuid guid, uint32 type) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index dac142f4044..77d5a28b1ce 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -64,6 +64,7 @@ #include "WorldSession.h" #include "ChatPackets.h" #include "MovementPackets.h" +#include "CombatPackets.h" #include <cmath> @@ -2110,24 +2111,24 @@ float Unit::CalculateLevelPenalty(SpellInfo const* spellProto) const void Unit::SendMeleeAttackStart(Unit* victim) { - WorldPacket data(SMSG_ATTACKSTART, 8 + 8); - data << GetGUID(); - data << victim->GetGUID(); - SendMessageToSet(&data, true); + WorldPackets::Combat::AttackStart packet; + packet.Attacker = GetGUID(); + packet.Victim = victim->GetGUID(); + SendMessageToSet(packet.Write(), true); TC_LOG_DEBUG("entities.unit", "WORLD: Sent SMSG_ATTACKSTART"); } void Unit::SendMeleeAttackStop(Unit* victim) { - WorldPacket data(SMSG_ATTACKSTOP, (8+8+4)); - data << GetPackGUID(); + WorldPackets::Combat::SAttackStop packet; + packet.Attacker = GetGUID(); if (victim) - data << victim->GetPackGUID(); - else - data << uint8(0); + { + packet.Victim = victim->GetGUID(); + packet.Dead = victim->isDead(); + } - data << uint32(0); //! Can also take the value 0x01, which seems related to updating rotation - SendMessageToSet(&data, true); + SendMessageToSet(packet.Write(), true); TC_LOG_DEBUG("entities.unit", "WORLD: Sent SMSG_ATTACKSTOP"); if (victim) @@ -4849,68 +4850,27 @@ void Unit::SendSpellDamageImmune(Unit* target, uint32 spellId) void Unit::SendAttackStateUpdate(CalcDamageInfo* damageInfo) { TC_LOG_DEBUG("entities.unit", "WORLD: Sending SMSG_ATTACKERSTATEUPDATE"); - - uint32 count = 1; - size_t maxsize = 4+5+5+4+4+1+4+4+4+4+4+1+4+4+4+4+4*12; - WorldPacket data(SMSG_ATTACKERSTATEUPDATE, maxsize); // we guess size - data << uint32(damageInfo->HitInfo); - data << damageInfo->attacker->GetPackGUID(); - data << damageInfo->target->GetPackGUID(); - data << uint32(damageInfo->damage); // Full damage + + WorldPackets::Combat::AttackerStateUpdate packet; + packet.HitInfo = damageInfo->HitInfo; + packet.AttackerGUID = damageInfo->attacker->GetGUID(); + packet.VictimGUID = damageInfo->target->GetGUID(); + packet.Damage = damageInfo->damage; int32 overkill = damageInfo->damage - damageInfo->target->GetHealth(); - data << uint32(overkill < 0 ? 0 : overkill); // Overkill - data << uint8(count); // Sub damage count - - for (uint32 i = 0; i < count; ++i) - { - data << uint32(damageInfo->damageSchoolMask); // School of sub damage - data << float(damageInfo->damage); // sub damage - data << uint32(damageInfo->damage); // Sub Damage - } - - if (damageInfo->HitInfo & (HITINFO_FULL_ABSORB | HITINFO_PARTIAL_ABSORB)) - { - for (uint32 i = 0; i < count; ++i) - data << uint32(damageInfo->absorb); // Absorb - } - - if (damageInfo->HitInfo & (HITINFO_FULL_RESIST | HITINFO_PARTIAL_RESIST)) - { - for (uint32 i = 0; i < count; ++i) - data << uint32(damageInfo->resist); // Resist - } - - data << uint8(damageInfo->TargetState); - data << uint32(0); // Unknown attackerstate - data << uint32(0); // Melee spellid + packet.OverDamage = (overkill < 0 ? -1 : overkill); - if (damageInfo->HitInfo & HITINFO_BLOCK) - data << uint32(damageInfo->blocked_amount); + WorldPackets::Combat::SubDamage& subDmg = packet.SubDmg.value; + subDmg.SchoolMask = damageInfo->damageSchoolMask; // School of sub damage + subDmg.FDamage = damageInfo->damage; // sub damage + subDmg.Damage = damageInfo->damage; // Sub Damage + subDmg.Absorbed = damageInfo->absorb; + subDmg.Resisted = damageInfo->resist; + packet.SubDmg.HasValue = true; - if (damageInfo->HitInfo & HITINFO_RAGE_GAIN) - data << uint32(0); - - //! Probably used for debugging purposes, as it is not known to appear on retail servers - if (damageInfo->HitInfo & HITINFO_UNK1) - { - data << uint32(0); - data << float(0); - data << float(0); - data << float(0); - data << float(0); - data << float(0); - data << float(0); - data << float(0); - data << float(0); - for (uint8 i = 0; i < 2; ++i) - { - data << float(0); - data << float(0); - } - data << uint32(0); - } + packet.VictimState = damageInfo->TargetState; + packet.BlockAmount = damageInfo->blocked_amount; - SendMessageToSet(&data, true); + SendMessageToSet(packet.Write(), true); } void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit* target, uint8 /*SwingType*/, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount) @@ -12905,10 +12865,10 @@ void Unit::SendPetAIReaction(ObjectGuid guid) if (!owner || owner->GetTypeId() != TYPEID_PLAYER) return; - WorldPacket data(SMSG_AI_REACTION, 8 + 4); - data << guid; - data << uint32(AI_REACTION_HOSTILE); - owner->ToPlayer()->GetSession()->SendPacket(&data); + WorldPackets::Combat::AIReaction packet; + packet.UnitGUID = guid; + packet.Reaction = AI_REACTION_HOSTILE; + owner->ToPlayer()->GetSession()->SendPacket(packet.Write()); } ///----------End of Pet responses methods---------- @@ -15969,16 +15929,17 @@ void Unit::SendThreatListUpdate() uint32 count = getThreatManager().getThreatList().size(); TC_LOG_DEBUG("entities.unit", "WORLD: Send SMSG_THREAT_UPDATE Message"); - WorldPacket data(SMSG_THREAT_UPDATE, 8 + count * 8); - data << GetPackGUID(); - data << uint32(count); + WorldPackets::Combat::ThreatUpdate packet; + packet.UnitGUID = GetGUID(); ThreatContainer::StorageType const &tlist = getThreatManager().getThreatList(); for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr) { - data << (*itr)->getUnitGuid().WriteAsPacked(); - data << uint32((*itr)->getThreat() * 100); + WorldPackets::Combat::ThreatInfo info; + info.UnitGUID = (*itr)->getUnitGuid(); + info.Threat = (*itr)->getThreat() * 100; + packet.ThreatList.push_back(info); } - SendMessageToSet(&data, false); + SendMessageToSet(packet.Write(), false); } } @@ -15989,17 +15950,18 @@ void Unit::SendChangeCurrentVictimOpcode(HostileReference* pHostileReference) uint32 count = getThreatManager().getThreatList().size(); TC_LOG_DEBUG("entities.unit", "WORLD: Send SMSG_HIGHEST_THREAT_UPDATE Message"); - WorldPacket data(SMSG_HIGHEST_THREAT_UPDATE, 8 + 8 + count * 8); - data << GetPackGUID(); - data << pHostileReference->getUnitGuid().WriteAsPacked(); - data << uint32(count); + WorldPackets::Combat::HighestThreatUpdate packet; + packet.UnitGUID = GetGUID(); + packet.HighestThreatGUID = pHostileReference->getUnitGuid(); ThreatContainer::StorageType const &tlist = getThreatManager().getThreatList(); for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr) { - data << (*itr)->getUnitGuid().WriteAsPacked(); - data << uint32((*itr)->getThreat()); + WorldPackets::Combat::ThreatInfo info; + info.UnitGUID = (*itr)->getUnitGuid(); + info.Threat = int32((*itr)->getThreat()); + packet.ThreatList.push_back(info); } - SendMessageToSet(&data, false); + SendMessageToSet(packet.Write(), false); } } @@ -16014,10 +15976,10 @@ void Unit::SendClearThreatListOpcode() void Unit::SendRemoveFromThreatListOpcode(HostileReference* pHostileReference) { TC_LOG_DEBUG("entities.unit", "WORLD: Send SMSG_THREAT_REMOVE Message"); - WorldPacket data(SMSG_THREAT_REMOVE, 8 + 8); - data << GetPackGUID(); - data << pHostileReference->getUnitGuid().WriteAsPacked(); - SendMessageToSet(&data, false); + WorldPackets::Combat::ThreatRemove packet; + packet.UnitGUID = GetGUID(); + packet.AboutGUID = pHostileReference->getUnitGuid(); + SendMessageToSet(packet.Write(), false); } // baseRage means damage taken when attacker = false diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index b28d26af2c9..1905f41e84e 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -309,7 +309,7 @@ enum HitInfo HITINFO_CRITICALHIT = 0x00000200, // critical hit // 0x00000400 // 0x00000800 - // 0x00001000 + HITINFO_UNK12 = 0x00001000, HITINFO_BLOCK = 0x00002000, // blocked damage // 0x00004000 // Hides worldtext for 0 damage // 0x00008000 // Related to blood visual diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 228b2e69566..e7191735ca1 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -679,7 +679,7 @@ bool normalizePlayerName(std::string& name); struct ExtendedPlayerName { - ExtendedPlayerName(std::string name, std::string realm) : Name(name), Realm(realm) {} + ExtendedPlayerName(std::string const& name, std::string const& realm) : Name(name), Realm(realm) {} std::string Name; std::string Realm; }; diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 26451751b5d..e259af0b604 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -31,17 +31,16 @@ #include "Battleground.h" #include "ScriptMgr.h" #include "GameObjectAI.h" +#include "QuestPackets.h" -void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData) +void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPackets::Quest::QuestGiverStatusQuery& packet) { - ObjectGuid guid; - recvData >> guid; uint32 questStatus = DIALOG_STATUS_NONE; - Object* questGiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT); + Object* questGiver = ObjectAccessor::GetObjectByTypeMask(*_player, packet.QuestGiverGUID, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT); if (!questGiver) { - TC_LOG_INFO("network", "Error in CMSG_QUESTGIVER_STATUS_QUERY, called for non-existing questgiver (%s)", guid.ToString().c_str()); + TC_LOG_INFO("network", "Error in CMSG_QUESTGIVER_STATUS_QUERY, called for non-existing questgiver (%s)", packet.QuestGiverGUID.ToString().c_str()); return; } @@ -66,7 +65,7 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData) } //inform client about status of quest - _player->PlayerTalkClass->SendQuestGiverStatus(questStatus, guid); + _player->PlayerTalkClass->SendQuestGiverStatus(questStatus, packet.QuestGiverGUID); } void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket& recvData) @@ -639,14 +638,13 @@ void WorldSession::HandleQuestPushResult(WorldPacket& recvPacket) } } -void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket*/) +void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPackets::Quest::QuestGiverStatusMultipleQuery& /*packet*/) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY"); uint32 count = 0; - WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4 + 8 + 4); - data << uint32(count); // placeholder + WorldPackets::Quest::QuestGiverStatusMultiple response; for (GuidSet::const_iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr) { @@ -663,9 +661,10 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket questStatus = _player->GetQuestDialogStatus(questgiver); - data << questgiver->GetGUID(); - data << uint32(questStatus); - ++count; + WorldPackets::Quest::QuestGiverInfo info; + info.Guid = questgiver->GetGUID(); + info.Status = questStatus; + response.QuestGiver.push_back(info); } else if (itr->IsGameObject()) { @@ -675,14 +674,14 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket questStatus = _player->GetQuestDialogStatus(questgiver); - data << questgiver->GetGUID(); - data << uint32(questStatus); - ++count; + WorldPackets::Quest::QuestGiverInfo info; + info.Guid = questgiver->GetGUID(); + info.Status = questStatus; + response.QuestGiver.push_back(info); } } - data.put<uint32>(0, count); // write real count - SendPacket(&data); + SendPacket(response.Write()); } void WorldSession::HandleQueryQuestsCompleted(WorldPacket& /*recvData*/) diff --git a/src/server/game/Server/Packets/CombatPackets.cpp b/src/server/game/Server/Packets/CombatPackets.cpp index 17c0599d266..3383435814c 100644 --- a/src/server/game/Server/Packets/CombatPackets.cpp +++ b/src/server/game/Server/Packets/CombatPackets.cpp @@ -16,8 +16,126 @@ */ #include "CombatPackets.h" +#include "SpellPackets.h" void WorldPackets::Combat::AttackSwing::Read() { _worldPacket >> Victim; } + +WorldPacket const* WorldPackets::Combat::AttackStart::Write() +{ + _worldPacket << Attacker; + _worldPacket << Victim; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Combat::SAttackStop::Write() +{ + _worldPacket << Attacker; + _worldPacket << Victim; + _worldPacket.WriteBit(Dead); + _worldPacket.FlushBits(); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Combat::ThreatUpdate::Write() +{ + _worldPacket << UnitGUID; + _worldPacket << int32(ThreatList.size()); + for (WorldPackets::Combat::ThreatInfo const& threatInfo : ThreatList) + { + _worldPacket << threatInfo.UnitGUID; + _worldPacket << threatInfo.Threat; + } + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Combat::HighestThreatUpdate::Write() +{ + _worldPacket << UnitGUID; + _worldPacket << HighestThreatGUID; + _worldPacket << int32(ThreatList.size()); + for (WorldPackets::Combat::ThreatInfo const& threatInfo : ThreatList) + { + _worldPacket << threatInfo.UnitGUID; + _worldPacket << threatInfo.Threat; + } + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Combat::ThreatRemove::Write() +{ + _worldPacket << UnitGUID; + _worldPacket << AboutGUID; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Combat::AIReaction::Write() +{ + _worldPacket << UnitGUID; + _worldPacket << Reaction; + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Combat::AttackerStateUpdate::Write() +{ + if (_worldPacket.WriteBit(LogData.HasValue)) + _worldPacket << LogData.value; + + // Placeholder for size which will be calculated at the end based on packet size + // Client uses this size to copy remaining packet to another CDataStore + _worldPacket << int32(0); + size_t pos = _worldPacket.wpos(); + + _worldPacket << HitInfo; + _worldPacket << AttackerGUID; + _worldPacket << VictimGUID; + _worldPacket << Damage; + _worldPacket << OverDamage; + if (_worldPacket.WriteBit(SubDmg.HasValue)) + { + _worldPacket << SubDmg.value.SchoolMask; + _worldPacket << SubDmg.value.FDamage; + _worldPacket << SubDmg.value.Damage; + if (HitInfo & (HITINFO_FULL_ABSORB|HITINFO_PARTIAL_ABSORB)) + _worldPacket << SubDmg.value.Absorbed; + if (HitInfo & (HITINFO_FULL_RESIST|HITINFO_PARTIAL_RESIST)) + _worldPacket << SubDmg.value.Resisted; + } + _worldPacket << VictimState; + _worldPacket << AttackerState; + _worldPacket << MeleeSpellID; + if (HitInfo & HITINFO_BLOCK) + _worldPacket << BlockAmount; + if (HitInfo & HITINFO_RAGE_GAIN) + _worldPacket << RageGained; + if (HitInfo & HITINFO_UNK1) + { + _worldPacket << UnkState.State1; + _worldPacket << UnkState.State2; + _worldPacket << UnkState.State3; + _worldPacket << UnkState.State4; + _worldPacket << UnkState.State5; + _worldPacket << UnkState.State6; + _worldPacket << UnkState.State7; + _worldPacket << UnkState.State8; + _worldPacket << UnkState.State9; + _worldPacket << UnkState.State10; + _worldPacket << UnkState.State11; + _worldPacket << UnkState.State12; + } + if (HitInfo & (HITINFO_BLOCK|HITINFO_UNK12)) + _worldPacket << Unk; + + // Update size placeholder + _worldPacket.put<int32>(pos-sizeof(int32), _worldPacket.wpos()-pos); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/CombatPackets.h b/src/server/game/Server/Packets/CombatPackets.h index 5c6576e68c5..14648297342 100644 --- a/src/server/game/Server/Packets/CombatPackets.h +++ b/src/server/game/Server/Packets/CombatPackets.h @@ -20,6 +20,7 @@ #include "Packet.h" #include "ObjectGuid.h" +#include "SpellPackets.h" namespace WorldPackets { @@ -42,6 +43,128 @@ namespace WorldPackets void Read() override { } }; + + class AttackStart final : public ServerPacket + { + public: + AttackStart() : ServerPacket(SMSG_ATTACKSTART, 16) { } + + WorldPacket const* Write() override; + + ObjectGuid Attacker; + ObjectGuid Victim; + }; + + class SAttackStop final : public ServerPacket + { + public: + SAttackStop() : ServerPacket(SMSG_ATTACKSTOP, 17) { } + + WorldPacket const* Write() override; + + ObjectGuid Attacker; + ObjectGuid Victim; + bool Dead = false; + }; + + struct ThreatInfo + { + ObjectGuid UnitGUID; + int32 Threat = 0; + }; + + class ThreatUpdate final : public ServerPacket + { + public: + ThreatUpdate() : ServerPacket(SMSG_THREAT_UPDATE, 24) { } + + WorldPacket const* Write() override; + + ObjectGuid UnitGUID; + std::vector<ThreatInfo> ThreatList; + }; + + class HighestThreatUpdate final : public ServerPacket + { + public: + HighestThreatUpdate() : ServerPacket(SMSG_HIGHEST_THREAT_UPDATE, 44) { } + + WorldPacket const* Write() override; + + ObjectGuid UnitGUID; + std::vector<ThreatInfo> ThreatList; + ObjectGuid HighestThreatGUID; + }; + + class ThreatRemove final : public ServerPacket + { + public: + ThreatRemove() : ServerPacket(SMSG_THREAT_REMOVE, 16) { } + + WorldPacket const* Write() override; + + ObjectGuid AboutGUID; // Unit to remove threat from (e.g. player, pet, guardian) + ObjectGuid UnitGUID; // Unit being attacked (e.g. creature, boss) + }; + + class AIReaction final : public ServerPacket + { + public: + AIReaction() : ServerPacket(SMSG_AI_REACTION, 12) { } + + WorldPacket const* Write() override; + + ObjectGuid UnitGUID; + uint32 Reaction = 0; + }; + + struct SubDamage + { + int32 SchoolMask = 0; + float FDamage = 0.0f; // Float damage (Most of the time equals to Damage) + int32 Damage = 0; + int32 Absorbed = 0; + int32 Resisted = 0; + }; + + struct UnkAttackerState + { + int32 State1 = 0; + float State2 = 0.0f; + float State3 = 0.0f; + float State4 = 0.0f; + float State5 = 0.0f; + float State6 = 0.0f; + float State7 = 0.0f; + float State8 = 0.0f; + float State9 = 0.0f; + float State10 = 0.0f; + float State11 = 0.0f; + int32 State12 = 0; + }; + + class AttackerStateUpdate final : public ServerPacket + { + public: + AttackerStateUpdate() : ServerPacket(SMSG_ATTACKERSTATEUPDATE, 70) { } + + WorldPacket const* Write() override; + + Optional<WorldPackets::Spell::SpellCastLogData> LogData; + uint32 HitInfo = 0; // Flags + ObjectGuid AttackerGUID; + ObjectGuid VictimGUID; + int32 Damage = 0; + int32 OverDamage = -1; // (damage - health) or -1 if unit is still alive + Optional<SubDamage> SubDmg; + uint8 VictimState = 0; + int32 AttackerState = -1; + int32 MeleeSpellID = 0; + int32 BlockAmount = 0; + int32 RageGained = 0; + UnkAttackerState UnkState; + float Unk = 0.0f; + }; } } diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp index 09914b292bb..6ca1012a51c 100644 --- a/src/server/game/Server/Packets/SpellPackets.cpp +++ b/src/server/game/Server/Packets/SpellPackets.cpp @@ -64,3 +64,20 @@ WorldPacket const* WorldPackets::Spell::SendUnlearnSpells::Write() return &_worldPacket; } +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spell::SpellCastLogData& spellCastLogData) +{ + data << spellCastLogData.Health; + data << spellCastLogData.AttackPower; + data << spellCastLogData.SpellPower; + data << int32(spellCastLogData.PowerData.size()); + for (WorldPackets::Spell::SpellLogPowerData const& powerData : spellCastLogData.PowerData) + { + data << powerData.PowerType; + data << powerData.Amount; + } + data.FlushBits(); + data.WriteBit(false); + // data << float // Unk data if bit is true + data.FlushBits(); +} + diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h index c02f5cc2a5f..0bfd979b6ca 100644 --- a/src/server/game/Server/Packets/SpellPackets.h +++ b/src/server/game/Server/Packets/SpellPackets.h @@ -84,7 +84,23 @@ namespace WorldPackets std::vector<uint32> Spells; }; + + struct SpellLogPowerData + { + int32 PowerType = 0; + int32 Amount = 0; + }; + + struct SpellCastLogData + { + int32 Health = 0; + int32 AttackPower = 0; + int32 SpellPower = 0; + std::vector<SpellLogPowerData> PowerData; + }; } } +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spell::SpellCastLogData& spellCastLogData); + #endif // SpellPackets_h__ diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 595e19cd7ef..ab4b768cfd4 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -27,6 +27,7 @@ #include "Packets/MiscPackets.h" #include "Packets/MovementPackets.h" #include "Packets/QueryPackets.h" +#include "Packets/QuestPackets.h" #include "Packets/TalentPackets.h" #include "Packets/TradePackets.h" @@ -524,8 +525,8 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_HELLO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverHelloOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_QUERY_QUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverQueryQuestOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_REQUEST_REWARD, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverRequestRewardOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverStatusMultipleQuery); - DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_STATUS_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleQuestgiverStatusQueryOpcode); + DEFINE_HANDLER(CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestGiverStatusMultipleQuery, &WorldSession::HandleQuestgiverStatusMultipleQuery); + DEFINE_HANDLER(CMSG_QUESTGIVER_STATUS_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Quest::QuestGiverStatusQuery, &WorldSession::HandleQuestgiverStatusQueryOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTLOG_REMOVE_QUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogRemoveQuest ); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_CONFIRM_ACCEPT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestConfirmAccept ); DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_NPC_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestNPCQuery ); @@ -701,7 +702,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACTIVATETAXIREPLY, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADDON_INFO, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADD_RUNE_POWER, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_AI_REACTION, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_AI_REACTION, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ALL_ACHIEVEMENT_DATA, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_SPIRIT_HEALER_TIME, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_MESSAGE, STATUS_UNHANDLED); @@ -715,9 +716,9 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_QUERY_RESPONSE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_ROSTER, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_STATS, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKERSTATEUPDATE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSTART, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSTOP, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKERSTATEUPDATE, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSTART, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSTOP, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSWING_BADFACING, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSWING_CANT_ATTACK, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSWING_DEADTARGET, STATUS_UNHANDLED); @@ -992,7 +993,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_XP, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_XP_GAIN, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_HEALTH_UPDATE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_HIGHEST_THREAT_UPDATE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_HIGHEST_THREAT_UPDATE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_INFO, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_NOTIFY, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIALIZE_FACTIONS, STATUS_NEVER); @@ -1210,8 +1211,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_INVALID, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_LIST, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_REQUEST_ITEMS, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS_MULTIPLE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS_MULTIPLE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTLOG_FULL, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTUPDATE_ADD_KILL, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTUPDATE_ADD_PVP_KILL, STATUS_UNHANDLED); @@ -1279,7 +1280,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PHASE_SHIFT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAY_HOVER_ANIM, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROFICIENCY, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROFICIENCY, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROJECTILE_POSITION, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_TIME_ZONE_INFORMATION, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOWTAXINODES, STATUS_UNHANDLED); @@ -1357,8 +1358,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_TEST_DROP_RATE_RESULT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TEXT_EMOTE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_CLEAR, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_REMOVE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_UPDATE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_REMOVE, STATUS_NEVER); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_UPDATE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TIME_ADJUSTMENT, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TIME_SYNC_REQ, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_TITLE_EARNED, STATUS_UNHANDLED); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 1b2d6c5762a..c176bf5a3b1 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -154,6 +154,12 @@ namespace WorldPackets class QueryPageText; } + namespace Quest + { + class QuestGiverStatusQuery; + class QuestGiverStatusMultipleQuery; + } + namespace Movement { class ClientPlayerMovement; @@ -833,8 +839,8 @@ class WorldSession void HandleUnlearnSkillOpcode(WorldPacket& recvPacket); void HandleSetSpecializationOpcode(WorldPackets::Talent::SetSpecialization& packet); - void HandleQuestgiverStatusQueryOpcode(WorldPacket& recvPacket); - void HandleQuestgiverStatusMultipleQuery(WorldPacket& recvPacket); + void HandleQuestgiverStatusQueryOpcode(WorldPackets::Quest::QuestGiverStatusQuery& packet); + void HandleQuestgiverStatusMultipleQuery(WorldPackets::Quest::QuestGiverStatusMultipleQuery& packet); void HandleQuestgiverHelloOpcode(WorldPacket& recvPacket); void HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvPacket); void HandleQuestgiverQueryQuestOpcode(WorldPacket& recvPacket); |