diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Pet/Pet.cpp | 13 | ||||
-rw-r--r-- | src/server/game/Entities/Pet/Pet.h | 6 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 59 | ||||
-rw-r--r-- | src/server/game/Handlers/NPCHandler.cpp | 56 | ||||
-rw-r--r-- | src/server/game/Handlers/PetHandler.cpp | 180 | ||||
-rw-r--r-- | src/server/game/Server/Packets/AllPackets.h | 1 | ||||
-rw-r--r-- | src/server/game/Server/Packets/PetPackets.cpp | 155 | ||||
-rw-r--r-- | src/server/game/Server/Packets/PetPackets.h | 157 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 14 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 10 | ||||
-rw-r--r-- | src/server/game/Spells/SpellHistory.cpp | 9 |
12 files changed, 441 insertions, 221 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 2b802a634e0..babf39ec3e5 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -619,7 +619,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() // Pet PrepareStatement(CHAR_SEL_PET_SLOTS, "SELECT owner, slot FROM character_pet WHERE owner = ? AND slot >= ? AND slot <= ? ORDER BY slot", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_PET_SLOTS_DETAIL, "SELECT owner, id, entry, level, name FROM character_pet WHERE owner = ? AND slot >= ? AND slot <= ? ORDER BY slot", CONNECTION_ASYNC); + PrepareStatement(CHAR_SEL_PET_SLOTS_DETAIL, "SELECT owner, id, entry, level, name, modelid FROM character_pet WHERE owner = ? AND slot >= ? AND slot <= ? ORDER BY slot", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_PET_ENTRY, "SELECT entry FROM character_pet WHERE owner = ? AND id = ? AND slot >= ? AND slot <= ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_PET_SLOT_BY_ID, "SELECT slot, entry FROM character_pet WHERE owner = ? AND id = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_PET_SPELL_LIST, "SELECT DISTINCT pet_spell.spell FROM pet_spell, character_pet WHERE character_pet.owner = ? AND character_pet.id = pet_spell.guid AND character_pet.id <> ?", CONNECTION_SYNCH); diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index d4db53634c2..deefff1423b 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -24,6 +24,7 @@ #include "ObjectMgr.h" #include "SpellMgr.h" #include "Pet.h" +#include "PetPackets.h" #include "SpellAuras.h" #include "SpellAuraEffects.h" #include "SpellHistory.h" @@ -1427,9 +1428,9 @@ bool Pet::learnSpell(uint32 spell_id) if (!m_loading) { - WorldPacket data(SMSG_PET_LEARNED_SPELLS, 4); - data << uint32(spell_id); - GetOwner()->GetSession()->SendPacket(&data); + WorldPackets::Pet::PetLearnedSpells packet; + packet.Spells.push_back(spell_id); + GetOwner()->GetSession()->SendPacket(packet.Write()); GetOwner()->PetSpellInitialize(); } return true; @@ -1478,9 +1479,9 @@ bool Pet::unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab) { if (!m_loading) { - WorldPacket data(SMSG_PET_UNLEARNED_SPELLS, 4); - data << uint32(spell_id); - GetOwner()->GetSession()->SendPacket(&data); + WorldPackets::Pet::PetUnlearnedSpells packet; + packet.Spells.push_back(spell_id); + GetOwner()->GetSession()->SendPacket(packet.Write()); } return true; } diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 7bbda7c76b6..bc989b515eb 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -32,6 +32,12 @@ struct PetSpell PetSpellType type; }; +enum PetStableinfo +{ + PET_STABLE_ACTIVE = 1, + PET_STABLE_INACTIVE = 2 +}; + typedef std::unordered_map<uint32, PetSpell> PetSpellMap; typedef std::vector<uint32> AutoSpellList; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index aecf3633c2c..59a4fcec8bb 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -74,6 +74,7 @@ #include "OutdoorPvP.h" #include "OutdoorPvPMgr.h" #include "Pet.h" +#include "PetPackets.h" #include "QuestDef.h" #include "QuestPackets.h" #include "ReputationMgr.h" @@ -19958,9 +19959,8 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent) if (pet->isControlled()) { - WorldPacket data(SMSG_PET_SPELLS_MESSAGE, 8); - data << uint64(0); - GetSession()->SendPacket(&data); + WorldPackets::Pet::PetSpells petSpellsPacket; + GetSession()->SendPacket(petSpellsPacket.Write()); if (GetGroup()) SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET); @@ -20107,22 +20107,17 @@ void Player::PetSpellInitialize() CharmInfo* charmInfo = pet->GetCharmInfo(); - WorldPacket data(SMSG_PET_SPELLS_MESSAGE, 8 + 2 + 4 + 4 + 4 * MAX_UNIT_ACTION_BAR_INDEX + 1 + 1); - data << pet->GetGUID(); - data << uint16(pet->GetCreatureTemplate()->family); // creature family (required for pet talents) - data << uint32(pet->GetDuration()); - data << uint8(pet->GetReactState()); - data << uint8(charmInfo->GetCommandState()); - data << uint16(0); // Flags, mostly unknown + WorldPackets::Pet::PetSpells petSpellsPacket; + petSpellsPacket.PetGUID = pet->GetGUID(); + petSpellsPacket.CreatureFamily = pet->GetCreatureTemplate()->family; // creature family (required for pet talents) + //petSpellsPacket.Specialization = pet->GetSpecialization(); NYI + petSpellsPacket.TimeLimit = pet->GetDuration(); + petSpellsPacket.ReactState = pet->GetReactState(); + petSpellsPacket.CommandState = charmInfo->GetCommandState(); // action bar loop - charmInfo->BuildActionBar(&data); - - size_t spellsCountPos = data.wpos(); - - // spells count - uint8 addlist = 0; - data << uint8(addlist); // placeholder + for (uint32 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) + petSpellsPacket.ActionButtons[i] = charmInfo->GetActionBarEntry(i)->packedData; if (pet->IsPermanentPetFor(this)) { @@ -20132,17 +20127,14 @@ void Player::PetSpellInitialize() if (itr->second.state == PETSPELL_REMOVED) continue; - data << uint32(MAKE_UNIT_ACTION_BUTTON(itr->first, itr->second.active)); - ++addlist; + petSpellsPacket.Actions.push_back(MAKE_UNIT_ACTION_BUTTON(itr->first, itr->second.active)); } } - data.put<uint8>(spellsCountPos, addlist); - // Cooldowns - //pet->GetSpellHistory()->WritePacket(&petSpells); + pet->GetSpellHistory()->WritePacket(&petSpellsPacket); - GetSession()->SendPacket(&data); + GetSession()->SendPacket(petSpellsPacket.Write()); } void Player::PossessSpellInitialize() @@ -20159,20 +20151,16 @@ void Player::PossessSpellInitialize() return; } - WorldPacket data(SMSG_PET_SPELLS_MESSAGE, 8 + 2 + 4 + 4 + 4 * MAX_UNIT_ACTION_BAR_INDEX + 1 + 1); - data << charm->GetGUID(); - data << uint16(0); - data << uint32(0); - data << uint32(0); - - charmInfo->BuildActionBar(&data); + WorldPackets::Pet::PetSpells petSpellsPacket; + petSpellsPacket.PetGUID = charm->GetGUID(); - data << uint8(0); // spells count + for (uint32 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) + petSpellsPacket.ActionButtons[i] = charmInfo->GetActionBarEntry(i)->packedData; // Cooldowns - //charm->GetSpellHistory()->WritePacket(&petSpells); + charm->GetSpellHistory()->WritePacket(&petSpellsPacket); - GetSession()->SendPacket(&data); + GetSession()->SendPacket(petSpellsPacket.Write()); } void Player::VehicleSpellInitialize() @@ -20284,9 +20272,8 @@ void Player::CharmSpellInitialize() void Player::SendRemoveControlBar() const { - WorldPacket data(SMSG_PET_SPELLS_MESSAGE, 8); - data << uint64(0); - GetSession()->SendPacket(&data); + WorldPackets::Pet::PetSpells packet; + GetSession()->SendPacket(packet.Write()); } bool Player::IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod, Spell* spell) const diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index 7590ef2b120..32cd3e6daa9 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -31,6 +31,7 @@ #include "ObjectAccessor.h" #include "Creature.h" #include "Pet.h" +#include "PetPackets.h" #include "ReputationMgr.h" #include "BattlegroundMgr.h" #include "Battleground.h" @@ -496,29 +497,27 @@ void WorldSession::SendStablePetCallback(PreparedQueryResult result, ObjectGuid if (!GetPlayer()) return; - WorldPacket data(SMSG_PET_STABLE_LIST, 200); // guess size + WorldPackets::Pet::PetStableList packet; - data << guid; + packet.StableMaster = guid; Pet* pet = _player->GetPet(); - size_t wpos = data.wpos(); - data << uint8(0); // place holder for slot show number - - data << uint8(GetPlayer()->m_stableSlots); - - uint8 num = 0; // counter for place holder - + int32 petSlot = 0; // not let move dead pet in slot if (pet && pet->IsAlive() && pet->getPetType() == HUNTER_PET) { - data << uint32(num); // 4.x unknown, some kind of order? - data << uint32(pet->GetCharmInfo()->GetPetNumber()); - data << uint32(pet->GetEntry()); - data << uint32(pet->getLevel()); - data << pet->GetName(); // petname - data << uint8(1); // 1 = current, 2/3 = in stable (any from 4, 5, ... create problems with proper show) - ++num; + WorldPackets::Pet::PetStableInfo stableEntry; + stableEntry.PetSlot = petSlot; + stableEntry.PetNumber = pet->GetCharmInfo()->GetPetNumber(); + stableEntry.CreatureID = pet->GetEntry(); + stableEntry.DisplayID = pet->GetDisplayId(); + stableEntry.ExperienceLevel = pet->getLevel(); + stableEntry.PetFlags = PET_STABLE_ACTIVE; + stableEntry.PetName = pet->GetName(); + ++petSlot; + + packet.Pets.push_back(stableEntry); } if (result) @@ -526,22 +525,23 @@ void WorldSession::SendStablePetCallback(PreparedQueryResult result, ObjectGuid do { Field* fields = result->Fetch(); - - data << uint32(num); - data << uint32(fields[1].GetUInt32()); // petnumber - data << uint32(fields[2].GetUInt32()); // creature entry - data << uint32(fields[3].GetUInt16()); // level - data << fields[4].GetString(); // name - data << uint8(2); // 1 = current, 2/3 = in stable (any from 4, 5, ... create problems with proper show) - - ++num; + WorldPackets::Pet::PetStableInfo stableEntry; + + stableEntry.PetSlot = petSlot; + stableEntry.PetNumber = fields[1].GetUInt32(); // petnumber + stableEntry.CreatureID = fields[2].GetUInt32(); // creature entry + stableEntry.DisplayID = fields[5].GetUInt32(); // creature displayid + stableEntry.ExperienceLevel = fields[3].GetUInt16(); // level + stableEntry.PetFlags = PET_STABLE_INACTIVE; + stableEntry.PetName = fields[4].GetString(); // Name + + ++petSlot; + packet.Pets.push_back(stableEntry); } while (result->NextRow()); } - data.put<uint8>(wpos, num); // set real data to placeholder - SendPacket(&data); - + SendPacket(packet.Write()); } void WorldSession::SendPetStableResult(uint8 res) diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 6f62fc7cd5a..a1e57ff087a 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -28,6 +28,7 @@ #include "CreatureAI.h" #include "Util.h" #include "Pet.h" +#include "PetPackets.h" #include "World.h" #include "Group.h" #include "SpellHistory.h" @@ -59,22 +60,13 @@ void WorldSession::HandleRequestPetInfo(WorldPackets::Pet::RequestPetInfo& /*pac { } -void WorldSession::HandlePetAction(WorldPacket& recvData) +void WorldSession::HandlePetAction(WorldPackets::Pet::PetAction& packet) { - ObjectGuid guid1; - uint32 data; - ObjectGuid guid2; - float x, y, z; - recvData >> guid1; //pet guid - recvData >> data; - recvData >> guid2; //tag guid - // Position - recvData >> x; - recvData >> y; - recvData >> z; - - uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data); - uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); //delete = 0x07 CastSpell = C1 + ObjectGuid guid1 = packet.PetGUID; //pet guid + ObjectGuid guid2 = packet.TargetGUID; //tag guid + + uint32 spellid = UNIT_ACTION_BUTTON_ACTION(packet.Action); + uint8 flag = UNIT_ACTION_BUTTON_TYPE(packet.Action); //delete = 0x07 CastSpell = C1 // used also for charmed creature Unit* pet = ObjectAccessor::GetUnit(*_player, guid1); @@ -106,7 +98,7 @@ void WorldSession::HandlePetAction(WorldPacket& recvData) return; if (GetPlayer()->m_Controlled.size() == 1) - HandlePetActionHelper(pet, guid1, spellid, flag, guid2, x, y, z); + HandlePetActionHelper(pet, guid1, spellid, flag, guid2, packet.ActionPosition.x, packet.ActionPosition.y, packet.ActionPosition.z); else { //If a pet is dismissed, m_Controlled will change @@ -115,7 +107,7 @@ void WorldSession::HandlePetAction(WorldPacket& recvData) if ((*itr)->GetEntry() == pet->GetEntry() && (*itr)->IsAlive()) controlled.push_back(*itr); for (std::vector<Unit*>::iterator itr = controlled.begin(); itr != controlled.end(); ++itr) - HandlePetActionHelper(*itr, guid1, spellid, flag, guid2, x, y, z); + HandlePetActionHelper(*itr, guid1, spellid, flag, guid2, packet.ActionPosition.x, packet.ActionPosition.y, packet.ActionPosition.z); } } @@ -462,13 +454,9 @@ bool WorldSession::CheckStableMaster(ObjectGuid guid) return true; } -void WorldSession::HandlePetSetAction(WorldPacket& recvData) +void WorldSession::HandlePetSetAction(WorldPackets::Pet::PetSetAction& packet) { - ObjectGuid petguid; - uint8 count; - - recvData >> petguid; - + ObjectGuid petguid = packet.PetGUID; Unit* pet = ObjectAccessor::GetUnit(*_player, petguid); if (!pet || pet != _player->GetFirstControlled()) @@ -484,110 +472,53 @@ void WorldSession::HandlePetSetAction(WorldPacket& recvData) return; } - count = (recvData.size() == 24) ? 2 : 1; - - uint32 position[2]; - uint32 data[2]; - bool move_command = false; + uint32 position = packet.Index; + uint32 actionData = packet.Action; - for (uint8 i = 0; i < count; ++i) - { - recvData >> position[i]; - recvData >> data[i]; + uint32 spell_id = UNIT_ACTION_BUTTON_ACTION(actionData); + uint8 act_state = UNIT_ACTION_BUTTON_TYPE(actionData); - uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]); - - //ignore invalid position - if (position[i] >= MAX_UNIT_ACTION_BAR_INDEX) - return; - - // in the normal case, command and reaction buttons can only be moved, not removed - // at moving count == 2, at removing count == 1 - // ignore attempt to remove command|reaction buttons (not possible at normal case) - if (act_state == ACT_COMMAND || act_state == ACT_REACTION) - { - if (count == 1) - return; + TC_LOG_DEBUG("network", "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", + _player->GetName().c_str(), position, spell_id, uint32(act_state)); - move_command = true; - } - } - - // check swap (at command->spell swap client remove spell first in another packet, so check only command move correctness) - if (move_command) + //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add + if (!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id))) { - uint8 act_state_0 = UNIT_ACTION_BUTTON_TYPE(data[0]); - if (act_state_0 == ACT_COMMAND || act_state_0 == ACT_REACTION) - { - uint32 spell_id_0 = UNIT_ACTION_BUTTON_ACTION(data[0]); - UnitActionBarEntry const* actionEntry_1 = charmInfo->GetActionBarEntry(position[1]); - if (!actionEntry_1 || spell_id_0 != actionEntry_1->GetAction() || - act_state_0 != actionEntry_1->GetType()) - return; - } - - uint8 act_state_1 = UNIT_ACTION_BUTTON_TYPE(data[1]); - if (act_state_1 == ACT_COMMAND || act_state_1 == ACT_REACTION) + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id)) { - uint32 spell_id_1 = UNIT_ACTION_BUTTON_ACTION(data[1]); - UnitActionBarEntry const* actionEntry_0 = charmInfo->GetActionBarEntry(position[0]); - if (!actionEntry_0 || spell_id_1 != actionEntry_0->GetAction() || - act_state_1 != actionEntry_0->GetType()) - return; - } - } - - for (uint8 i = 0; i < count; ++i) - { - uint32 spell_id = UNIT_ACTION_BUTTON_ACTION(data[i]); - uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data[i]); - - TC_LOG_DEBUG("network", "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", - _player->GetName().c_str(), position[i], spell_id, uint32(act_state)); - - //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add - if (!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id))) - { - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id)) + //sign for autocast + if (act_state == ACT_ENABLED) { - //sign for autocast - if (act_state == ACT_ENABLED) - { - if (pet->GetTypeId() == TYPEID_UNIT && pet->IsPet()) - ((Pet*)pet)->ToggleAutocast(spellInfo, true); - else - for (Unit::ControlList::iterator itr = GetPlayer()->m_Controlled.begin(); itr != GetPlayer()->m_Controlled.end(); ++itr) - if ((*itr)->GetEntry() == pet->GetEntry()) - (*itr)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, true); - } - //sign for no/turn off autocast - else if (act_state == ACT_DISABLED) - { - if (pet->GetTypeId() == TYPEID_UNIT && pet->IsPet()) - ((Pet*)pet)->ToggleAutocast(spellInfo, false); - else - for (Unit::ControlList::iterator itr = GetPlayer()->m_Controlled.begin(); itr != GetPlayer()->m_Controlled.end(); ++itr) - if ((*itr)->GetEntry() == pet->GetEntry()) - (*itr)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, false); - } + if (pet->GetTypeId() == TYPEID_UNIT && pet->IsPet()) + ((Pet*)pet)->ToggleAutocast(spellInfo, true); + else + for (Unit::ControlList::iterator itr = GetPlayer()->m_Controlled.begin(); itr != GetPlayer()->m_Controlled.end(); ++itr) + if ((*itr)->GetEntry() == pet->GetEntry()) + (*itr)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, true); + } + //sign for no/turn off autocast + else if (act_state == ACT_DISABLED) + { + if (pet->GetTypeId() == TYPEID_UNIT && pet->IsPet()) + ((Pet*)pet)->ToggleAutocast(spellInfo, false); + else + for (Unit::ControlList::iterator itr = GetPlayer()->m_Controlled.begin(); itr != GetPlayer()->m_Controlled.end(); ++itr) + if ((*itr)->GetEntry() == pet->GetEntry()) + (*itr)->GetCharmInfo()->ToggleCreatureAutocast(spellInfo, false); } - - charmInfo->SetActionBar(position[i], spell_id, ActiveStates(act_state)); } + + charmInfo->SetActionBar(position, spell_id, ActiveStates(act_state)); } } -void WorldSession::HandlePetRename(WorldPacket& recvData) +void WorldSession::HandlePetRename(WorldPackets::Pet::PetRename& packet) { - ObjectGuid petguid; - uint8 isdeclined; + ObjectGuid petguid = packet.RenameData.PetGUID; + bool isdeclined = packet.RenameData.HasDeclinedNames; - std::string name; - DeclinedName declinedname; - - recvData >> petguid; - recvData >> name; - recvData >> isdeclined; + std::string name = packet.RenameData.NewName; + DeclinedName declinedname = packet.RenameData.DeclinedNames; Pet* pet = ObjectAccessor::GetPet(*_player, petguid); // check it! @@ -617,11 +548,6 @@ void WorldSession::HandlePetRename(WorldPacket& recvData) if (isdeclined) { - for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) - { - recvData >> declinedname.name[i]; - } - std::wstring wname; if (!Utf8toWStr(name, wname)) return; @@ -788,13 +714,11 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPackets::Spells::PetCastSpell& void WorldSession::SendPetNameInvalid(uint32 error, const std::string& name, DeclinedName *declinedName) { - WorldPacket data(SMSG_PET_NAME_INVALID, 4 + name.size() + 1 + 1); - data << uint32(error); - data << name; - data << uint8(declinedName ? 1 : 0); - if (declinedName) - for (uint32 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) - data << declinedName->name[i]; - - SendPacket(&data); + WorldPackets::Pet::PetNameInvalid petNameInvalid; + petNameInvalid.Result = error; + petNameInvalid.RenameData.NewName = name; + for (int i = 0; i < MAX_DECLINED_NAME_CASES; i++) + petNameInvalid.RenameData.DeclinedNames.name[i] = declinedName[i].name[i]; + + SendPacket(petNameInvalid.Write()); } diff --git a/src/server/game/Server/Packets/AllPackets.h b/src/server/game/Server/Packets/AllPackets.h index caf895abe03..60dd2493b12 100644 --- a/src/server/game/Server/Packets/AllPackets.h +++ b/src/server/game/Server/Packets/AllPackets.h @@ -52,6 +52,7 @@ #include "PartyPackets.h" #include "PetPackets.h" #include "PetitionPackets.h" +#include "PetPackets.h" #include "QueryPackets.h" #include "QuestPackets.h" #include "ReferAFriendPackets.h" diff --git a/src/server/game/Server/Packets/PetPackets.cpp b/src/server/game/Server/Packets/PetPackets.cpp index 803b956b4ee..fb4e0bd2609 100644 --- a/src/server/game/Server/Packets/PetPackets.cpp +++ b/src/server/game/Server/Packets/PetPackets.cpp @@ -17,14 +17,137 @@ #include "PetPackets.h" -void WorldPackets::Pet::DismissCritter::Read() +WorldPacket const* WorldPackets::Pet::PetSpells::Write() { - _worldPacket >> CritterGUID; + _worldPacket << PetGUID; + _worldPacket << int16(CreatureFamily); + _worldPacket << int16(Specialization); + _worldPacket << int32(TimeLimit); + + uint32 petModeAndOrders = ReactState + (CommandState << 8) + (Flag << 16); + _worldPacket << uint32(petModeAndOrders); + + for (uint32 actionButton : ActionButtons) + _worldPacket << int32(actionButton); + + _worldPacket << int32(Actions.size()); + _worldPacket << int32(Cooldowns.size()); + _worldPacket << int32(SpellHistory.size()); + + for (uint32 action : Actions) + _worldPacket << action; + + for (PetSpellCooldown const& cooldown : Cooldowns) + { + _worldPacket << int32(cooldown.SpellID); + _worldPacket << int32(cooldown.Duration); + _worldPacket << int32(cooldown.CategoryDuration); + _worldPacket << int16(cooldown.Category); + } + + for (PetSpellHistory const& history : SpellHistory) + { + _worldPacket << int32(history.CategoryID); + _worldPacket << int32(history.RecoveryTime); + _worldPacket << int8(history.ConsumedCharges); + } + + return &_worldPacket; } -void WorldPackets::Pet::PetAbandon::Read() +WorldPacket const* WorldPackets::Pet::PetStableList::Write() +{ + _worldPacket << StableMaster; + + _worldPacket << uint32(Pets.size()); + for (PetStableInfo const& pet : Pets) + { + _worldPacket << int32(pet.PetSlot); + _worldPacket << int32(pet.PetNumber); + _worldPacket << int32(pet.CreatureID); + _worldPacket << int32(pet.DisplayID); + _worldPacket << int32(pet.ExperienceLevel); + _worldPacket << int32(pet.PetFlags); + + _worldPacket << int8(pet.PetName.length()); + _worldPacket.WriteString(pet.PetName); + } + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Pet::PetLearnedSpells::Write() +{ + _worldPacket << uint32(Spells.size()); + for (uint32 spell : Spells) + _worldPacket << int32(spell); + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Pet::PetUnlearnedSpells::Write() +{ + _worldPacket << uint32(Spells.size()); + for (uint32 spell : Spells) + _worldPacket << int32(spell); + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Pet::PetNameInvalid::Write() +{ + _worldPacket << RenameData.PetGUID; + _worldPacket << int32(RenameData.PetNumber); + + _worldPacket << uint8(RenameData.NewName.length()); + + _worldPacket.WriteBit(RenameData.HasDeclinedNames); + _worldPacket.FlushBits(); + + if (RenameData.HasDeclinedNames) + { + for (int32 i = 0; i < MAX_DECLINED_NAME_CASES; i++) + { + _worldPacket.WriteBits(RenameData.DeclinedNames.name[i].length(), 7); + _worldPacket.FlushBits(); + } + + for (int32 i = 0; i < MAX_DECLINED_NAME_CASES; i++) + _worldPacket << RenameData.DeclinedNames.name[i]; + } + + _worldPacket.WriteString(RenameData.NewName); + return &_worldPacket; +} + +void WorldPackets::Pet::PetRename::Read() { - _worldPacket >> Pet; + _worldPacket >> RenameData.PetGUID; + _worldPacket >> RenameData.PetNumber; + + int8 nameLen = 0; + _worldPacket >> nameLen; + + RenameData.HasDeclinedNames = _worldPacket.ReadBit(); + if (RenameData.HasDeclinedNames) + { + int32 count[MAX_DECLINED_NAME_CASES]; + for (int32 i = 0; i < MAX_DECLINED_NAME_CASES; i++) + count[i] = _worldPacket.ReadBits(7); + + for (int32 i = 0; i < MAX_DECLINED_NAME_CASES; i++) + RenameData.DeclinedNames.name[i] = _worldPacket.ReadString(count[i]); + } + + RenameData.NewName = _worldPacket.ReadString(nameLen); +} + +void WorldPackets::Pet::PetAction::Read() +{ + _worldPacket >> PetGUID; + + _worldPacket >> Action; + _worldPacket >> TargetGUID; + + _worldPacket >> ActionPosition; } void WorldPackets::Pet::PetStopAttack::Read() @@ -32,9 +155,33 @@ void WorldPackets::Pet::PetStopAttack::Read() _worldPacket >> PetGUID; } +void WorldPackets::Pet::PetSetAction::Read() +{ + _worldPacket >> PetGUID; + + _worldPacket >> Index; + _worldPacket >> Action; +} + +void WorldPackets::Pet::PetAbandon::Read() +{ + _worldPacket >> PetGUID; +} + void WorldPackets::Pet::PetSpellAutocast::Read() { _worldPacket >> PetGUID; _worldPacket >> SpellID; AutocastEnabled = _worldPacket.ReadBit(); } + +void WorldPackets::Pet::DismissCritter::Read() +{ + _worldPacket >> CritterGUID; +} + +void WorldPackets::Pet::PetCancelAura::Read() +{ + _worldPacket >> PetGUID; + _worldPacket >> SpellID; +} diff --git a/src/server/game/Server/Packets/PetPackets.h b/src/server/game/Server/Packets/PetPackets.h index 04af0d2bdd3..db33edb7d4c 100644 --- a/src/server/game/Server/Packets/PetPackets.h +++ b/src/server/game/Server/Packets/PetPackets.h @@ -20,6 +20,8 @@ #include "Packet.h" #include "ObjectGuid.h" +#include "Unit.h" +#include "WorldSession.h" namespace WorldPackets { @@ -39,7 +41,7 @@ namespace WorldPackets { public: RequestPetInfo(WorldPacket&& packet) : ClientPacket(CMSG_REQUEST_PET_INFO, std::move(packet)) { } - + void Read() override { } }; @@ -57,7 +59,7 @@ namespace WorldPackets { public: PetStopAttack(WorldPacket&& packet) : ClientPacket(CMSG_PET_STOP_ATTACK, std::move(packet)) { } - + void Read() override; ObjectGuid PetGUID; @@ -67,13 +69,162 @@ namespace WorldPackets { public: PetSpellAutocast(WorldPacket&& packet) : ClientPacket(CMSG_PET_SPELL_AUTOCAST, std::move(packet)) { } - + void Read() override; ObjectGuid PetGUID; uint32 SpellID = 0; bool AutocastEnabled = false; }; + + struct PetSpellCooldown + { + int32 SpellID = 0; + int32 Duration = 0; + int32 CategoryDuration = 0; + int Category = 0; + }; + + struct PetSpellHistory + { + int32 CategoryID = 0; + int32 RecoveryTime = 0; + int8 ConsumedCharges = 0; + }; + + class PetSpells final : public ServerPacket + { + public: + PetSpells() : ServerPacket(SMSG_PET_SPELLS_MESSAGE, 100) { } + + WorldPacket const* Write() override; + + ObjectGuid PetGUID; + uint16 CreatureFamily = 0; + uint16 Specialization = 0; + uint32 TimeLimit = 0; + uint8 ReactState = 0; + uint8 CommandState = 0; + uint16 Flag = 0; + + std::array<int, 10> ActionButtons; + + std::vector<uint32> Actions; + std::vector<PetSpellCooldown> Cooldowns; + std::vector<PetSpellHistory> SpellHistory; + }; + + struct PetStableInfo + { + uint32 PetSlot = 0; + uint32 PetNumber = 0; + uint32 CreatureID = 0; + uint32 DisplayID = 0; + uint32 ExperienceLevel = 0; + uint32 PetFlags = 0; + std::string PetName; + }; + + class PetStableList final : public ServerPacket + { + public: + PetStableList() : ServerPacket(SMSG_PET_STABLE_LIST, 18 + 2) { } + + WorldPacket const* Write() override; + + ObjectGuid StableMaster; + std::vector<PetStableInfo> Pets; + }; + + class PetLearnedSpells final : public ServerPacket + { + public: + PetLearnedSpells() : ServerPacket(SMSG_PET_LEARNED_SPELLS, 4) { } + + WorldPacket const* Write() override; + + std::vector<uint32> Spells; + }; + + class PetUnlearnedSpells final : public ServerPacket + { + public: + PetUnlearnedSpells() : ServerPacket(SMSG_PET_UNLEARNED_SPELLS, 4) { } + + WorldPacket const* Write() override; + + std::vector<uint32> Spells; + }; + + + struct PetRenameData + { + ObjectGuid PetGUID; + int32 PetNumber = 0; + std::string NewName; + bool HasDeclinedNames = false; + DeclinedName DeclinedNames; + }; + + class PetNameInvalid final : public ServerPacket + { + public: + PetNameInvalid() : ServerPacket(SMSG_PET_NAME_INVALID, 18 + 4 + 2 + 1 + 5 * 2 + 2) { } + + WorldPacket const* Write() override; + + PetRenameData RenameData; + + uint8 Result = 0; + }; + + class PetRename final : public ClientPacket + { + public: + PetRename(WorldPacket&& packet) : ClientPacket(CMSG_PET_RENAME, std::move(packet)) { } + + void Read() override; + + PetRenameData RenameData; + }; + + class PetAction final : public ClientPacket + { + public: + PetAction(WorldPacket&& packet) : ClientPacket(CMSG_PET_ACTION, std::move(packet)) { } + + void Read() override; + + ObjectGuid PetGUID; + uint32 Action = 0; + ObjectGuid TargetGUID; + G3D::Vector3 ActionPosition; + }; + + class PetSetAction final : public ClientPacket + { + public: + PetSetAction(WorldPacket&& packet) : ClientPacket(CMSG_PET_SET_ACTION, std::move(packet)) { } + + void Read() override; + + ObjectGuid PetGUID; + + uint32 Index = 0; + uint32 Action = 0; + }; + + class PetCancelAura final : public ClientPacket + { + public: + PetCancelAura(WorldPacket&& packet) : ClientPacket(CMSG_PET_CANCEL_AURA, std::move(packet)) { } + + void Read() override; + + ObjectGuid PetGUID; + int32 SpellID = 0; + }; + } } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index f917cffd5b4..5f189361d95 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -558,7 +558,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_PETITION_SHOW_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionShowList, &WorldSession::HandlePetitionShowList); DEFINE_HANDLER(CMSG_PETITION_SHOW_SIGNATURES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Petition::PetitionShowSignatures, &WorldSession::HandlePetitionShowSignatures); DEFINE_HANDLER(CMSG_PET_ABANDON, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Pet::PetAbandon ,&WorldSession::HandlePetAbandon); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_ACTION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAction ); + DEFINE_HANDLER(CMSG_PET_ACTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Pet::PetAction, &WorldSession::HandlePetAction); DEFINE_HANDLER(CMSG_PET_BATTLE_FINAL_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_PET_BATTLE_INPUT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_PET_BATTLE_QUEUE_PROPOSE_MATCH_RESULT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); @@ -570,8 +570,8 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_PET_BATTLE_SCRIPT_ERROR_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_PET_CANCEL_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::PetCancelAura, &WorldSession::HandlePetCancelAuraOpcode); DEFINE_HANDLER(CMSG_PET_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::PetCastSpell, &WorldSession::HandlePetCastSpellOpcode); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_RENAME, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetRename ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_SET_ACTION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetSetAction ); + DEFINE_HANDLER(CMSG_PET_RENAME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Pet::PetRename, &WorldSession::HandlePetRename); + DEFINE_HANDLER(CMSG_PET_SET_ACTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Pet::PetSetAction, &WorldSession::HandlePetSetAction ); DEFINE_HANDLER(CMSG_PET_SPELL_AUTOCAST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Pet::PetSpellAutocast, &WorldSession::HandlePetSpellAutocastOpcode); DEFINE_HANDLER(CMSG_PET_STOP_ATTACK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Pet::PetStopAttack, &WorldSession::HandlePetStopAttack); DEFINE_HANDLER(CMSG_PING, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPacket, &WorldSession::Handle_EarlyProccess); @@ -1427,15 +1427,15 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_DISMISS_SOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_GOD_MODE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_GUIDS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_LEARNED_SPELLS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_LEARNED_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_MODE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_NAME_INVALID, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_SLOT_UPDATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_SPELLS_MESSAGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_STABLE_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_SPELLS_MESSAGE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_STABLE_LIST, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_STABLE_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_TAME_FAILURE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_UNLEARNED_SPELLS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_UNLEARNED_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PHASE_SHIFT_CHANGE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYED_TIME, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_BOUND, STATUS_NEVER, CONNECTION_TYPE_REALM); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 857988313d0..9655968dcb3 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -490,6 +490,10 @@ namespace WorldPackets class PetAbandon; class PetStopAttack; class PetSpellAutocast; + class PetRename; + class PetAction; + class PetCancelAura; + class PetSetAction; } namespace Petition @@ -1472,13 +1476,13 @@ class WorldSession void HandleTutorialFlag(WorldPackets::Misc::TutorialSetFlag& packet); //Pet - void HandlePetAction(WorldPacket& recvData); + void HandlePetAction(WorldPackets::Pet::PetAction& packet); void HandlePetStopAttack(WorldPackets::Pet::PetStopAttack& packet); void HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spellid, uint16 flag, ObjectGuid guid2, float x, float y, float z); void HandleQueryPetName(WorldPackets::Query::QueryPetName& packet); - void HandlePetSetAction(WorldPacket& recvData); + void HandlePetSetAction(WorldPackets::Pet::PetSetAction& packet); void HandlePetAbandon(WorldPackets::Pet::PetAbandon& packet); - void HandlePetRename(WorldPacket& recvData); + void HandlePetRename(WorldPackets::Pet::PetRename& packet); void HandlePetCancelAuraOpcode(WorldPackets::Spells::PetCancelAura& packet); void HandlePetSpellAutocastOpcode(WorldPackets::Pet::PetSpellAutocast& packet); void HandlePetCastSpellOpcode(WorldPackets::Spells::PetCastSpell& petCastSpell); diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp index 0d97a1c431a..7de2c2a9d46 100644 --- a/src/server/game/Spells/SpellHistory.cpp +++ b/src/server/game/Spells/SpellHistory.cpp @@ -17,6 +17,7 @@ #include "SpellHistory.h" #include "Pet.h" +#include "PetPackets.h" #include "Player.h" #include "SpellInfo.h" #include "SpellPackets.h" @@ -335,16 +336,14 @@ void SpellHistory::WritePacket(WorldPackets::Spells::SendSpellCharges* sendSpell } } -/* template<> -void SpellHistory::WritePacket(WorldPackets::Pet::PetSpells* petSpells) +void SpellHistory::WritePacket(WorldPackets::Pet::PetSpells* petSpells) const { Clock::time_point now = Clock::now(); petSpells->Cooldowns.reserve(_spellCooldowns.size()); for (auto const& p : _spellCooldowns) { - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(p.first); WorldPackets::Pet::PetSpellCooldown petSpellCooldown; petSpellCooldown.SpellID = p.first; petSpellCooldown.Category = p.second.CategoryId; @@ -361,7 +360,7 @@ void SpellHistory::WritePacket(WorldPackets::Pet::PetSpells* petSpells) petSpellCooldown.CategoryDuration = uint32(categoryDuration.count()); } - petSpells->Cooldowns.push_back(historyEntry); + petSpells->Cooldowns.push_back(petSpellCooldown); } petSpells->SpellHistory.reserve(_categoryCharges.size()); @@ -382,7 +381,7 @@ void SpellHistory::WritePacket(WorldPackets::Pet::PetSpells* petSpells) } } } -*/ + void SpellHistory::StartCooldown(SpellInfo const* spellInfo, uint32 itemId, Spell* spell /*= nullptr*/, bool onHold /*= false*/) { |