diff options
author | Intel <chemicstry@gmail.com> | 2014-11-24 20:50:19 +0200 |
---|---|---|
committer | Intel <chemicstry@gmail.com> | 2014-11-24 21:39:56 +0200 |
commit | d1c21a03b845ba4eeba61128ddfb43f7ac1e8667 (patch) | |
tree | 76df1bdbd275053d6c86f5feace70c6d0f5afa3e /src | |
parent | 92085d5deaaa0dc441c6b0c26d58b862972a7fbf (diff) |
Core/Packets: Added the following packets:
CMSG_BANKER_ACTIVATE
CMSG_BINDER_ACTIVATE
CMSG_GOSSIP_HELLO
CMSG_LIST_INVENTORY
CMSG_TRAINER_LIST
SMSG_GOSSIP_MESSAGE
SMSG_LIST_INVENTORY
CMSG_NPC_TEXT_QUERY
SMSG_NPC_TEXT_UPDATE
Implemented CMSG_DB_QUERY_BULK and SMSG_DB_REPLY and removed unused CMSG_REQUEST_HOTFIX
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 2 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Structure.h | 84 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2fmt.h | 6 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/GossipDef.cpp | 55 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/ItemHandler.cpp | 127 | ||||
-rw-r--r-- | src/server/game/Handlers/MiscHandler.cpp | 68 | ||||
-rw-r--r-- | src/server/game/Handlers/NPCHandler.cpp | 38 | ||||
-rw-r--r-- | src/server/game/Handlers/QueryHandler.cpp | 114 | ||||
-rw-r--r-- | src/server/game/Server/Packets/ItemPackets.cpp | 31 | ||||
-rw-r--r-- | src/server/game/Server/Packets/ItemPackets.h | 18 | ||||
-rw-r--r-- | src/server/game/Server/Packets/NPCPackets.cpp | 92 | ||||
-rw-r--r-- | src/server/game/Server/Packets/NPCPackets.h | 107 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QueryPackets.cpp | 55 | ||||
-rw-r--r-- | src/server/game/Server/Packets/QueryPackets.h | 59 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 24 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.h | 3 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 23 |
18 files changed, 518 insertions, 390 deletions
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index c4d47e26468..51669deef9d 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -145,7 +145,7 @@ void LoadDB2Stores(std::string const& dataPath) for (uint32 i = 0; i < sItemAppearanceStore.GetNumRows(); ++i) if (ItemAppearanceEntry const* entry = sItemAppearanceStore.LookupEntry(i)) - sItemDisplayIDMap[entry->AppearanceID] = entry->DisplayID; + sItemDisplayIDMap[entry->FileDataID] = entry->DisplayID; for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index 054118be481..249f95d80e4 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -61,15 +61,15 @@ struct ItemEntry int32 Material; // 4 uint32 InventoryType; // 5 uint32 Sheath; // 6 - uint32 AppearanceID; // 7 (ItemAppearance.db2) - //uint32 Unk; // 8 + uint32 FileDataID; // 7 + uint32 GroupSoundsID; // 8 }; struct ItemAppearanceEntry { uint32 ID; // 0 (reference to ItemModifiedAppearance.db2?) uint32 DisplayID; // 1 - uint32 AppearanceID; // 2 + uint32 FileDataID; // 2 }; struct ItemCurrencyCostEntry @@ -154,77 +154,7 @@ struct ItemSparseEntry float StatScalingFactor; // 98 uint32 CurrencySubstitutionID; // 99 uint32 CurrencySubstitutionCount; // 100 - //uint32 Unk3; // 101 - - /*uint32 ID; // 0 - uint32 Quality; // 1 - uint32 Flags; // 2 - uint32 Flags2; // 3 - float Unk430_1; - float Unk430_2; - uint32 BuyCount; - uint32 BuyPrice; // 4 - uint32 SellPrice; // 5 - uint32 InventoryType; // 6 - int32 AllowableClass; // 7 - int32 AllowableRace; // 8 - uint32 ItemLevel; // 9 - int32 RequiredLevel; // 10 - uint32 RequiredSkill; // 11 - uint32 RequiredSkillRank; // 12 - uint32 RequiredSpell; // 13 - uint32 RequiredHonorRank; // 14 - uint32 RequiredCityRank; // 15 - uint32 RequiredReputationFaction; // 16 - uint32 RequiredReputationRank; // 17 - uint32 MaxCount; // 18 - uint32 Stackable; // 19 - uint32 ContainerSlots; // 20 - int32 ItemStatType[MAX_ITEM_PROTO_STATS]; // 21 - 30 - uint32 ItemStatValue[MAX_ITEM_PROTO_STATS]; // 31 - 40 - int32 ItemStatUnk1[MAX_ITEM_PROTO_STATS]; // 41 - 50 - int32 ItemStatUnk2[MAX_ITEM_PROTO_STATS]; // 51 - 60 - uint32 ScalingStatDistribution; // 61 - uint32 DamageType; // 62 - uint32 Delay; // 63 - float RangedModRange; // 64 - int32 SpellId[MAX_ITEM_PROTO_SPELLS]; // 65 - 69 - int32 SpellTrigger[MAX_ITEM_PROTO_SPELLS]; // 70 - 74 - int32 SpellCharges[MAX_ITEM_PROTO_SPELLS]; // 75 - 79 - int32 SpellCooldown[MAX_ITEM_PROTO_SPELLS]; // 80 - 84 - int32 SpellCategory[MAX_ITEM_PROTO_SPELLS]; // 85 - 89 - int32 SpellCategoryCooldown[MAX_ITEM_PROTO_SPELLS]; // 90 - 94 - uint32 Bonding; // 95 - LocalizedString* Name; // 96 - LocalizedString* Name2; // 97 - LocalizedString* Name3; // 98 - LocalizedString* Name4; // 99 - LocalizedString* Description; // 100 - uint32 PageText; // 101 - uint32 LanguageID; // 102 - uint32 PageMaterial; // 103 - uint32 StartQuest; // 104 - uint32 LockID; // 105 - int32 Material; // 106 - uint32 Sheath; // 107 - uint32 RandomProperty; // 108 - uint32 RandomSuffix; // 109 - uint32 ItemSet; // 110 - uint32 Area; // 112 - uint32 Map; // 113 - uint32 BagFamily; // 114 - uint32 TotemCategory; // 115 - uint32 Color[MAX_ITEM_PROTO_SOCKETS]; // 116 - 118 - uint32 Content[MAX_ITEM_PROTO_SOCKETS]; // 119 - 121 - int32 SocketBonus; // 122 - uint32 GemProperties; // 123 - float ArmorDamageModifier; // 124 - uint32 Duration; // 125 - uint32 ItemLimitCategory; // 126 - uint32 HolidayId; // 127 - float StatScalingFactor; // 128 - int32 CurrencySubstitutionId; // 129 - int32 CurrencySubstitutionCount; // 130*/ + uint32 ItemNameDescriptionID; // 101 }; #define MAX_ITEM_EXT_COST_ITEMS 5 @@ -233,13 +163,13 @@ struct ItemSparseEntry struct ItemExtendedCostEntry { uint32 ID; // 0 extended-cost entry id - //uint32 reqhonorpoints; // 1 required honor points - //uint32 reqarenapoints; // 2 required arena points + uint32 RequiredHonorPoints; // 1 required honor points + uint32 RequiredArenaPoints; // 2 required arena points uint32 RequiredArenaSlot; // 3 arena slot restrictions (min slot value) uint32 RequiredItem[MAX_ITEM_EXT_COST_ITEMS]; // 4-8 required item id uint32 RequiredItemCount[MAX_ITEM_EXT_COST_ITEMS]; // 9-13 required count of 1st item uint32 RequiredPersonalArenaRating; // 14 required personal arena rating - //uint32 ItemPurchaseGroup; // 15 + uint32 ItemPurchaseGroup; // 15 uint32 RequiredCurrency[MAX_ITEM_EXT_COST_CURRENCIES];// 16-20 required curency id uint32 RequiredCurrencyCount[MAX_ITEM_EXT_COST_CURRENCIES];// 21-25 required curency count uint32 RequiredFactionId; diff --git a/src/server/game/DataStores/DB2fmt.h b/src/server/game/DataStores/DB2fmt.h index 5d2f374f2a7..f47efa43f89 100644 --- a/src/server/game/DataStores/DB2fmt.h +++ b/src/server/game/DataStores/DB2fmt.h @@ -19,11 +19,11 @@ #define TRINITY_DB2SFRM_H char const HolidaysEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiixxsiix"; -char const Itemfmt[]="niiiiiiix"; +char const Itemfmt[]="niiiiiiii"; char const ItemAppearanceEntryfmt[]="nii"; char const ItemCurrencyCostfmt[]="xn"; -char const ItemSparsefmt[]="niiiiffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifisssssiiiiiiiiiiiiiiiiiiifiiifiix"; -char const ItemExtendedCostEntryfmt[]="nxxiiiiiiiiiiiixiiiiiiiiiiiiii"; +char const ItemSparsefmt[]="niiiiffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifisssssiiiiiiiiiiiiiiiiiiifiiifiii"; +char const ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii"; char const ItemEffectEntryfmt[]="niiiiiiii"; char const KeyChainfmt[]="nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; char const OverrideSpellDataEntryfmt[] = "niiiiiiiiiixx"; diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index c947d4f49da..2b07683d335 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -24,6 +24,7 @@ #include "WorldSession.h" #include "Formulas.h" #include "QuestPackets.h" +#include "NPCPackets.h" GossipMenu::GossipMenu() { @@ -193,44 +194,45 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID) { _gossipMenu.SetSenderGUID(objectGUID); - WorldPacket data(SMSG_GOSSIP_MESSAGE, 100); // guess size - data << objectGUID; - data << uint32(_gossipMenu.GetMenuId()); // new 2.4.0 - data << uint32(titleTextId); - data << uint32(_gossipMenu.GetMenuItemCount()); // max count 0x10 + WorldPackets::NPC::GossipMessage packet; + packet.GossipGUID = objectGUID; + packet.TextID = titleTextId; + packet.GossipOptions.resize(_gossipMenu.GetMenuItems().size()); + uint32 count = 0; for (GossipMenuItemContainer::const_iterator itr = _gossipMenu.GetMenuItems().begin(); itr != _gossipMenu.GetMenuItems().end(); ++itr) { + WorldPackets::NPC::ClientGossipOptions& opt = packet.GossipOptions[count]; GossipMenuItem const& item = itr->second; - data << uint32(itr->first); - data << uint8(item.MenuItemIcon); - data << uint8(item.IsCoded); // makes pop up box password - data << uint32(item.BoxMoney); // money required to open menu, 2.0.3 - data << item.Message; // text for gossip item - data << item.BoxMessage; // accept text (related to money) pop up box, 2.0.3 + opt.ClientOption = itr->first; + opt.OptionNPC = item.MenuItemIcon; + opt.OptionFlags = item.IsCoded; // makes pop up box password + opt.OptionCost = item.BoxMoney; // money required to open menu, 2.0.3 + opt.Text = item.Message; // text for gossip item + opt.Confirm = item.BoxMessage; // accept text (related to money) pop up box, 2.0.3 + ++count; } - size_t count_pos = data.wpos(); - data << uint32(0); // max count 0x20 - uint32 count = 0; - // Store this instead of checking the Singleton every loop iteration bool questLevelInTitle = sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS); + packet.GossipText.resize(_questMenu.GetMenuItemCount()); + count = 0; for (uint8 i = 0; i < _questMenu.GetMenuItemCount(); ++i) { QuestMenuItem const& item = _questMenu.GetItem(i); uint32 questID = item.QuestId; if (Quest const* quest = sObjectMgr->GetQuestTemplate(questID)) { - ++count; - data << uint32(questID); - data << uint32(item.QuestIcon); - data << int32(quest->GetQuestLevel()); - data << uint32(quest->GetFlags()); // 3.3.3 quest flags - data << uint8(0); // 3.3.3 changes icon: blue question or yellow exclamation - std::string title = quest->GetTitle(); + WorldPackets::NPC::ClientGossipText& text = packet.GossipText[count]; + text.QuestID = questID; + text.QuestType = item.QuestIcon; + text.QuestLevel = quest->GetQuestLevel(); + text.QuestFlags[0] = quest->GetFlags(); + text.QuestFlags[1] = 0; + text.Repeatable = quest->IsRepeatable(); + std::string title = quest->GetTitle(); int32 locale = _session->GetSessionDbLocaleIndex(); if (locale >= 0) if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(questID)) @@ -239,12 +241,15 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID) if (questLevelInTitle) AddQuestLevelToTitle(title, quest->GetQuestLevel()); - data << title; // max 0x200 + text.QuestTitle = title; + ++count; } } - data.put<uint8>(count_pos, count); - _session->SendPacket(&data); + // Shrink to the real size + packet.GossipText.resize(count); + + _session->SendPacket(packet.Write()); } void PlayerMenu::SendCloseGossip() diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 52cfad8e46c..b624926df3b 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2508,7 +2508,7 @@ void ObjectMgr::LoadItemTemplates() itemTemplate.SubClass = db2Data->SubClass; itemTemplate.SoundOverrideSubclass = db2Data->SoundOverrideSubclass; itemTemplate.Name1 = sparse->Name->Str[sWorld->GetDefaultDbcLocale()]; - itemTemplate.DisplayInfoID = GetItemDisplayID(db2Data->AppearanceID); + itemTemplate.DisplayInfoID = GetItemDisplayID(db2Data->FileDataID); itemTemplate.Quality = sparse->Quality; memcpy(itemTemplate.Flags, sparse->Flags, sizeof(itemTemplate.Flags)); itemTemplate.Unk1 = sparse->Unk1; diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 95bcecbfdeb..54fb865c017 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -28,6 +28,8 @@ #include "ObjectAccessor.h" #include "SpellInfo.h" #include "DB2Stores.h" +#include "NPCPackets.h" +#include "ItemPackets.h" #include <vector> void WorldSession::HandleSplitItemOpcode(WorldPacket& recvData) @@ -560,18 +562,14 @@ void WorldSession::HandleBuyItemOpcode(WorldPacket& recvData) TC_LOG_DEBUG("network", "WORLD: received wrong itemType (%u) in HandleBuyItemOpcode", itemType); } -void WorldSession::HandleListInventoryOpcode(WorldPacket& recvData) +void WorldSession::HandleListInventoryOpcode(WorldPackets::NPC::Hello& packet) { - ObjectGuid guid; - - recvData >> guid; + TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_LIST_INVENTORY"); if (!GetPlayer()->IsAlive()) return; - TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_LIST_INVENTORY"); - - SendListInventory(guid); + SendListInventory(packet.Unit); } void WorldSession::SendListInventory(ObjectGuid vendorGuid) @@ -597,12 +595,10 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid) VendorItemData const* vendorItems = vendor->GetVendorItems(); uint32 rawItemCount = vendorItems ? vendorItems->GetItemCount() : 0; - //if (rawItemCount > 300), - // rawItemCount = 300; // client cap but uint8 max value is 255 + WorldPackets::NPC::VendorInventory packet; + packet.Vendor = vendor->GetGUID(); - ByteBuffer itemsData(32 * rawItemCount); - std::vector<bool> enablers; - enablers.reserve(2 * rawItemCount); + packet.Items.resize(rawItemCount); const float discountMod = _player->GetReputationPriceDiscount(vendor); uint8 count = 0; @@ -612,13 +608,15 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid) if (!vendorItem) continue; + WorldPackets::NPC::VendorItem& item = packet.Items[count]; + if (vendorItem->Type == ITEM_VENDOR_TYPE_ITEM) { ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(vendorItem->item); if (!itemTemplate) continue; - uint32 leftInStock = !vendorItem->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(vendorItem); + int32 leftInStock = !vendorItem->maxcount ? -1 : vendor->GetVendorItemCurrentCount(vendorItem); if (!_player->IsGameMaster()) // ignore conditions if GM on { // Respect allowed class @@ -647,29 +645,15 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid) if (int32 priceMod = _player->GetTotalAuraModifier(SPELL_AURA_MOD_VENDOR_ITEMS_PRICES)) price -= CalculatePct(price, priceMod); - itemsData << uint32(slot + 1); // client expects counting to start at 1 - itemsData << uint32(itemTemplate->MaxDurability); + item.MuID = slot + 1; // client expects counting to start at 1 + item.Durability = itemTemplate->MaxDurability; + item.ExtendedCostID = vendorItem->ExtendedCost; + item.Type = vendorItem->Type; + item.Quantity = leftInStock; + item.StackCount = itemTemplate->BuyCount; + item.Price = price; - if (vendorItem->ExtendedCost) - { - enablers.push_back(0); - itemsData << uint32(vendorItem->ExtendedCost); - } - else - enablers.push_back(1); - - enablers.push_back(1); // item is unlocked - - itemsData << uint32(vendorItem->item); - itemsData << uint32(vendorItem->Type); // 1 is items, 2 is currency - itemsData << uint32(price); - itemsData << uint32(itemTemplate->DisplayInfoID); - // if (!unk "enabler") data << uint32(something); - itemsData << int32(leftInStock); - itemsData << uint32(itemTemplate->BuyCount); - - if (++count >= MAX_VENDOR_ITEMS) - break; + item.Item.ItemID = vendorItem->item; } else if (vendorItem->Type == ITEM_VENDOR_TYPE_CURRENCY) { @@ -680,70 +664,23 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid) if (!vendorItem->ExtendedCost) continue; // there's no price defined for currencies, only extendedcost is used - itemsData << uint32(slot + 1); // client expects counting to start at 1 - itemsData << uint32(0); // max durability - - enablers.push_back(0); - itemsData << uint32(vendorItem->ExtendedCost); - - enablers.push_back(1); // item is unlocked - - itemsData << uint32(vendorItem->item); - itemsData << uint32(vendorItem->Type); // 1 is items, 2 is currency - itemsData << uint32(0); // price, only seen currency types that have Extended cost - itemsData << uint32(0); // displayId - // if (!unk "enabler") data << uint32(something); - itemsData << int32(-1); - itemsData << uint32(vendorItem->maxcount); - - if (++count >= MAX_VENDOR_ITEMS) - break; + item.MuID = slot + 1; // client expects counting to start at 1 + item.ExtendedCostID = vendorItem->ExtendedCost; + item.Item.ItemID = vendorItem->item; + item.Type = vendorItem->Type; + item.StackCount = vendorItem->maxcount; } - // else error - } - - ObjectGuid guid = vendorGuid; - - WorldPacket data(SMSG_LIST_INVENTORY, 12 + itemsData.size()); - - data.WriteBit(guid[1]); - data.WriteBit(guid[0]); - - data.WriteBits(count, 21); // item count - - data.WriteBit(guid[3]); - data.WriteBit(guid[6]); - data.WriteBit(guid[5]); - data.WriteBit(guid[2]); - data.WriteBit(guid[7]); - - for (std::vector<bool>::const_iterator itr = enablers.begin(); itr != enablers.end(); ++itr) - data.WriteBit(*itr); - - data.WriteBit(guid[4]); + else + continue; - data.FlushBits(); - data.append(itemsData); - - data.WriteByteSeq(guid[5]); - data.WriteByteSeq(guid[4]); - data.WriteByteSeq(guid[1]); - data.WriteByteSeq(guid[0]); - data.WriteByteSeq(guid[6]); - - // It doesn't matter what value is used here (PROBABLY its full vendor size) - // What matters is that if count of items we can see is 0 and this field is 1 - // then client will open the vendor list, otherwise it won't - if (rawItemCount) - data << uint8(rawItemCount); - else - data << uint8(vendor->IsArmorer()); + if (++count >= MAX_VENDOR_ITEMS) + break; + } - data.WriteByteSeq(guid[2]); - data.WriteByteSeq(guid[3]); - data.WriteByteSeq(guid[7]); + // Resize vector to real size (some items can be skipped due to checks) + packet.Items.resize(count); - SendPacket(&data); + SendPacket(packet.Write()); } void WorldSession::HandleAutoStoreBagItemOpcode(WorldPacket& recvData) diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 91ffa3aff87..3a48c29ce03 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1864,74 +1864,6 @@ void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket) _player->SetPendingBind(0, 0); } -void WorldSession::HandleRequestHotfix(WorldPacket& recvPacket) -{ - uint32 type, count; - recvPacket >> type; - - DB2StorageBase const* store = GetDB2Storage(type); - if (!store) - { - TC_LOG_ERROR("network", "CMSG_REQUEST_HOTFIX: Received unknown hotfix type: %u", type); - recvPacket.rfinish(); - return; - } - - count = recvPacket.ReadBits(23); - - ObjectGuid* guids = new ObjectGuid[count]; - for (uint32 i = 0; i < count; ++i) - { - guids[i][0] = recvPacket.ReadBit(); - guids[i][4] = recvPacket.ReadBit(); - guids[i][7] = recvPacket.ReadBit(); - guids[i][2] = recvPacket.ReadBit(); - guids[i][5] = recvPacket.ReadBit(); - guids[i][3] = recvPacket.ReadBit(); - guids[i][6] = recvPacket.ReadBit(); - guids[i][1] = recvPacket.ReadBit(); - } - - uint32 entry; - for (uint32 i = 0; i < count; ++i) - { - recvPacket.ReadByteSeq(guids[i][5]); - recvPacket.ReadByteSeq(guids[i][6]); - recvPacket.ReadByteSeq(guids[i][7]); - recvPacket.ReadByteSeq(guids[i][0]); - recvPacket.ReadByteSeq(guids[i][1]); - recvPacket.ReadByteSeq(guids[i][3]); - recvPacket.ReadByteSeq(guids[i][4]); - recvPacket >> entry; - recvPacket.ReadByteSeq(guids[i][2]); - - if (!store->HasRecord(entry)) - { - WorldPacket data(SMSG_DB_REPLY, 4 * 4); - data << -int32(entry); - data << uint32(store->GetHash()); - data << uint32(time(NULL)); - data << uint32(0); - SendPacket(&data); - continue; - } - - WorldPacket data(SMSG_DB_REPLY); - data << int32(entry); - data << uint32(store->GetHash()); - data << uint32(sObjectMgr->GetHotfixDate(entry, store->GetHash())); - - size_t sizePos = data.wpos(); - data << uint32(0); // size of next block - store->WriteRecord(entry, uint32(GetSessionDbcLocale()), data); - data.put<uint32>(sizePos, data.wpos() - sizePos - 4); - - SendPacket(&data); - } - - delete[] guids; -} - void WorldSession::HandleUpdateMissileTrajectory(WorldPacket& recvPacket) { TC_LOG_DEBUG("network", "WORLD: CMSG_UPDATE_MISSILE_TRAJECTORY"); diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index cc82063e074..0e7ea73700c 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -37,6 +37,7 @@ #include "ScriptMgr.h" #include "CreatureAI.h" #include "SpellInfo.h" +#include "NPCPackets.h" enum StableResultCode { @@ -75,18 +76,14 @@ void WorldSession::SendTabardVendorActivate(ObjectGuid guid) SendPacket(&data); } -void WorldSession::HandleBankerActivateOpcode(WorldPacket& recvData) +void WorldSession::HandleBankerActivateOpcode(WorldPackets::NPC::Hello& packet) { - ObjectGuid guid; - TC_LOG_DEBUG("network", "WORLD: Received CMSG_BANKER_ACTIVATE"); - recvData >> guid; - - Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_BANKER); + Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_BANKER); if (!unit) { - TC_LOG_DEBUG("network", "WORLD: HandleBankerActivateOpcode - %s not found or you can not interact with him.", guid.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleBankerActivateOpcode - %s not found or you can not interact with him.", packet.Unit.ToString().c_str()); return; } @@ -94,7 +91,7 @@ void WorldSession::HandleBankerActivateOpcode(WorldPacket& recvData) if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - SendShowBank(guid); + SendShowBank(packet.Unit); } void WorldSession::SendShowBank(ObjectGuid guid) @@ -112,12 +109,9 @@ void WorldSession::SendShowMailBox(ObjectGuid guid) SendPacket(&data); } -void WorldSession::HandleTrainerListOpcode(WorldPacket& recvData) +void WorldSession::HandleTrainerListOpcode(WorldPackets::NPC::Hello& packet) { - ObjectGuid guid; - - recvData >> guid; - SendTrainerList(guid); + SendTrainerList(packet.Unit); } void WorldSession::SendTrainerList(ObjectGuid guid) @@ -312,17 +306,14 @@ void WorldSession::SendTrainerBuyFailed(ObjectGuid guid, uint32 spellId, uint32 SendPacket(&data); } -void WorldSession::HandleGossipHelloOpcode(WorldPacket& recvData) +void WorldSession::HandleGossipHelloOpcode(WorldPackets::NPC::Hello& packet) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GOSSIP_HELLO"); - ObjectGuid guid; - recvData >> guid; - - Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE); + Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_NONE); if (!unit) { - TC_LOG_DEBUG("network", "WORLD: HandleGossipHelloOpcode - %s not found or you can not interact with him.", guid.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleGossipHelloOpcode - %s not found or you can not interact with him.", packet.Unit.ToString().c_str()); return; } @@ -453,18 +444,15 @@ void WorldSession::SendSpiritResurrect() _player->UpdateObjectVisibility(); } -void WorldSession::HandleBinderActivateOpcode(WorldPacket& recvData) +void WorldSession::HandleBinderActivateOpcode(WorldPackets::NPC::Hello& packet) { - ObjectGuid npcGUID; - recvData >> npcGUID; - if (!GetPlayer()->IsInWorld() || !GetPlayer()->IsAlive()) return; - Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(npcGUID, UNIT_NPC_FLAG_INNKEEPER); + Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_INNKEEPER); if (!unit) { - TC_LOG_DEBUG("network", "WORLD: HandleBinderActivateOpcode - %s not found or you can not interact with him.", npcGUID.ToString().c_str()); + TC_LOG_DEBUG("network", "WORLD: HandleBinderActivateOpcode - %s not found or you can not interact with him.", packet.Unit.ToString().c_str()); return; } diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index f432ff70275..6cb1bfe15bc 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -239,88 +239,27 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket& /*recvData*/) SendPacket(&data); } -void WorldSession::HandleNpcTextQueryOpcode(WorldPacket& recvData) +void WorldSession::HandleNpcTextQueryOpcode(WorldPackets::Query::QueryNPCText& packet) { - uint32 textID; - uint64 guid; + TC_LOG_DEBUG("network", "WORLD: CMSG_NPC_TEXT_QUERY TextId: %u", packet.TextID); - recvData >> textID; - TC_LOG_DEBUG("network", "WORLD: CMSG_NPC_TEXT_QUERY TextId: %u", textID); + GossipText const* gossip = sObjectMgr->GetGossipText(packet.TextID); - recvData >> guid; - - GossipText const* gossip = sObjectMgr->GetGossipText(textID); - - WorldPacket data(SMSG_NPC_TEXT_UPDATE, 100); // guess size - data << textID; - - if (!gossip) + WorldPackets::Query::QueryNPCTextResponse response; + response.TextID = packet.TextID; + + if (gossip) { for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) { - data << float(0); - data << "Greetings $N"; - data << "Greetings $N"; - data << uint32(0); - data << uint32(0); - data << uint32(0); - data << uint32(0); - data << uint32(0); - data << uint32(0); - data << uint32(0); + response.Probabilities[i] = gossip->Options[i].Probability; + response.BroadcastTextID[i] = gossip->Options[i].BroadcastTextID; } - } - else - { - std::string text0[MAX_GOSSIP_TEXT_OPTIONS], text1[MAX_GOSSIP_TEXT_OPTIONS]; - LocaleConstant locale = GetSessionDbLocaleIndex(); - - for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) - { - BroadcastText const* bct = sObjectMgr->GetBroadcastText(gossip->Options[i].BroadcastTextID); - if (bct) - { - text0[i] = bct->GetText(locale, GENDER_MALE, true); - text1[i] = bct->GetText(locale, GENDER_FEMALE, true); - } - else - { - text0[i] = gossip->Options[i].Text_0; - text1[i] = gossip->Options[i].Text_1; - } - - if (locale != DEFAULT_LOCALE && !bct) - { - if (NpcTextLocale const* npcTextLocale = sObjectMgr->GetNpcTextLocale(textID)) - { - ObjectMgr::GetLocaleString(npcTextLocale->Text_0[i], locale, text0[i]); - ObjectMgr::GetLocaleString(npcTextLocale->Text_1[i], locale, text1[i]); - } - } - - data << gossip->Options[i].Probability; - - if (text0[i].empty()) - data << text1[i]; - else - data << text0[i]; - - if (text1[i].empty()) - data << text0[i]; - else - data << text1[i]; - - data << gossip->Options[i].Language; - for (uint8 j = 0; j < MAX_GOSSIP_TEXT_EMOTES; ++j) - { - data << gossip->Options[i].Emotes[j]._Delay; - data << gossip->Options[i].Emotes[j]._Emote; - } - } + response.Allow = true; } - SendPacket(&data); + SendPacket(response.Write()); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_NPC_TEXT_UPDATE"); } @@ -492,3 +431,34 @@ void WorldSession::HandleQuestPOIQuery(WorldPacket& recvData) SendPacket(&data); } + +void WorldSession::HandleDBQueryBulk(WorldPackets::Query::DBQueryBulk& packet) +{ + DB2StorageBase const* store = GetDB2Storage(packet.TableHash); + if (!store) + { + TC_LOG_ERROR("network", "CMSG_REQUEST_HOTFIX: Received unknown hotfix type: %u", packet.TableHash); + return; + } + + for (WorldPackets::Query::DBQueryRecord const& rec : packet.Queries) + { + WorldPackets::Query::DBReply response; + response.TableHash = packet.TableHash; + + if (store->HasRecord(rec.RecordID)) + { + response.RecordID = rec.RecordID; + response.Locale = GetSessionDbcLocale(); + response.Timestamp = sObjectMgr->GetHotfixDate(rec.RecordID, packet.TableHash); + response.Data = store; + } + else + { + response.RecordID = -rec.RecordID; + response.Timestamp = time(NULL); + } + + SendPacket(response.Write()); + } +} diff --git a/src/server/game/Server/Packets/ItemPackets.cpp b/src/server/game/Server/Packets/ItemPackets.cpp index b89b7524f20..4ba9beb016e 100644 --- a/src/server/game/Server/Packets/ItemPackets.cpp +++ b/src/server/game/Server/Packets/ItemPackets.cpp @@ -24,3 +24,34 @@ WorldPacket const* WorldPackets::Item::SetProficiency::Write() return &_worldPacket; } + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData const& itemBonusInstanceData) +{ + data << itemBonusInstanceData.Context; + data << uint32(itemBonusInstanceData.BonusListIDs.size()); + for (uint32 bonusID : itemBonusInstanceData.BonusListIDs) + data << bonusID; + + return data; +} + +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemInstance const& itemInstance) +{ + data << itemInstance.ItemID; + data << itemInstance.RandomPropertiesSeed; + data << itemInstance.RandomPropertiesID; + + data.WriteBit(itemInstance.ItemBonus.HasValue); + data.WriteBit(!itemInstance.Modifications.empty()); + data.FlushBits(); + + if (itemInstance.ItemBonus.HasValue) + data << itemInstance.ItemBonus.Value; + + if (!itemInstance.Modifications.empty()) + { + data << uint32(itemInstance.Modifications.size() * sizeof(uint32)); + for (uint32 itemMod : itemInstance.Modifications) + data << itemMod; + } +} diff --git a/src/server/game/Server/Packets/ItemPackets.h b/src/server/game/Server/Packets/ItemPackets.h index 498bc939812..cb87bc0c586 100644 --- a/src/server/game/Server/Packets/ItemPackets.h +++ b/src/server/game/Server/Packets/ItemPackets.h @@ -34,7 +34,25 @@ namespace WorldPackets uint32 ProficiencyMask; uint8 ProficiencyClass; }; + + struct ItemBonusInstanceData + { + uint8 Context = 0; + std::vector<int32> BonusListIDs; + }; + + struct ItemInstance + { + uint32 ItemID = 0; + uint32 RandomPropertiesSeed = 0; + uint32 RandomPropertiesID = 0; + Optional<ItemBonusInstanceData> ItemBonus; + std::vector<int32> Modifications; + }; } } +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData const& itemBonusInstanceData); +ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemInstance const& itemInstance); + #endif // ItemPackets_h__ diff --git a/src/server/game/Server/Packets/NPCPackets.cpp b/src/server/game/Server/Packets/NPCPackets.cpp new file mode 100644 index 00000000000..9a738d70010 --- /dev/null +++ b/src/server/game/Server/Packets/NPCPackets.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "NPCPackets.h" +#include "ItemPackets.h" + +void WorldPackets::NPC::Hello::Read() +{ + _worldPacket >> Unit; +} + +WorldPacket const* WorldPackets::NPC::GossipMessage::Write() +{ + _worldPacket << GossipGUID; + _worldPacket << GossipID; + _worldPacket << FriendshipFactionID; + _worldPacket << TextID; + + _worldPacket << int32(GossipOptions.size()); + _worldPacket << int32(GossipText.size()); + + for (ClientGossipOptions const& options : GossipOptions) + { + _worldPacket << options.ClientOption; + _worldPacket << options.OptionNPC; + _worldPacket << options.OptionFlags; + _worldPacket << options.OptionCost; + + _worldPacket.WriteBits(options.Text.size(), 12); + _worldPacket.WriteBits(options.Confirm.size(), 12); + _worldPacket.FlushBits(); + + _worldPacket.WriteString(options.Text); + _worldPacket.WriteString(options.Confirm); + } + + for (ClientGossipText const& text : GossipText) + { + _worldPacket << text.QuestID; + _worldPacket << text.QuestType; + _worldPacket << text.QuestLevel; + _worldPacket << text.QuestFlags[0]; + _worldPacket << text.QuestFlags[1]; + + _worldPacket.WriteBit(text.Repeatable); + _worldPacket.WriteBits(text.QuestTitle.size(), 9); + _worldPacket.FlushBits(); + + _worldPacket.WriteString(text.QuestTitle); + } + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::NPC::VendorInventory::Write() +{ + _worldPacket << Vendor; + _worldPacket << Reason; + + _worldPacket << int32(Items.size()); + for (VendorItem const& item : Items) + { + _worldPacket << item.MuID; + _worldPacket << item.Type; + _worldPacket << item.Item; + _worldPacket << item.Quantity; + _worldPacket << item.Price; + _worldPacket << item.Durability; + _worldPacket << item.StackCount; + _worldPacket << item.ExtendedCostID; + _worldPacket << item.PlayerConditionFailed; + + _worldPacket.WriteBit(item.DoNotFilterOnVendor); + _worldPacket.FlushBits(); + } + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/NPCPackets.h b/src/server/game/Server/Packets/NPCPackets.h new file mode 100644 index 00000000000..b8dbc913b49 --- /dev/null +++ b/src/server/game/Server/Packets/NPCPackets.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef NPCPackets_h__ +#define NPCPackets_h__ + +#include "Packet.h" +#include "ItemPackets.h" + +namespace WorldPackets +{ + namespace NPC + { + // CMSG_BANKER_ACTIVATE + // CMSG_BINDER_ACTIVATE + // CMSG_BINDER_CONFIRM + // CMSG_GOSSIP_HELLO + // CMSG_LIST_INVENTORY + // CMSG_TRAINER_LIST + class Hello final : public ClientPacket + { + public: + Hello(WorldPacket&& packet) : ClientPacket(std::move(packet)) { } + + void Read() override; + + ObjectGuid Unit; + }; + + struct ClientGossipOptions + { + int32 ClientOption = 0; + uint8 OptionNPC = 0; + uint8 OptionFlags = 0; + int32 OptionCost = 0; + std::string Text; + std::string Confirm; + }; + + struct ClientGossipText + { + int32 QuestID = 0; + int32 QuestType = 0; + int32 QuestLevel = 0; + bool Repeatable = false; + std::string QuestTitle; + int32 QuestFlags[2]; + }; + + class GossipMessage final : public ServerPacket + { + public: + GossipMessage() : ServerPacket(SMSG_GOSSIP_MESSAGE, 200) { } + + WorldPacket const* Write() override; + + std::vector<ClientGossipOptions> GossipOptions; + int32 FriendshipFactionID = 0; + ObjectGuid GossipGUID; + std::vector<ClientGossipText> GossipText; + int32 TextID = 0; + int32 GossipID = 0; + }; + + struct VendorItem + { + int32 MuID = 0; + int32 Type = 0; + WorldPackets::Item::ItemInstance Item; + int32 Quantity = -1; + int32 Price = 0; + int32 Durability = 0; + int32 StackCount = 0; + int32 ExtendedCostID = 0; + int32 PlayerConditionFailed = 0; + bool DoNotFilterOnVendor = false; + }; + + class VendorInventory final : public ServerPacket + { + public: + VendorInventory() : ServerPacket(SMSG_LIST_INVENTORY, 600) { } + + WorldPacket const* Write() override; + + uint8 Reason = 0; + std::vector<VendorItem> Items; + ObjectGuid Vendor; + }; + } +} + +#endif // NPCPackets_h__ diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp index a84c53f7771..335d261651a 100644 --- a/src/server/game/Server/Packets/QueryPackets.cpp +++ b/src/server/game/Server/Packets/QueryPackets.cpp @@ -153,3 +153,58 @@ WorldPacket const* WorldPackets::Query::QueryPageTextResponse::Write() return &_worldPacket; } + +void WorldPackets::Query::QueryNPCText::Read() +{ + _worldPacket >> TextID; + _worldPacket >> Guid; +} + +WorldPacket const* WorldPackets::Query::QueryNPCTextResponse::Write() +{ + _worldPacket << TextID; + _worldPacket.WriteBit(Allow); + + if (Allow) + { + _worldPacket << int32(MAX_GOSSIP_TEXT_OPTIONS * (4 + 4)); + for (uint32 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) + _worldPacket << Probabilities[i]; + for (uint32 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i) + _worldPacket << BroadcastTextID[i]; + } + + return &_worldPacket; +} + +void WorldPackets::Query::DBQueryBulk::Read() +{ + _worldPacket >> TableHash; + + uint32 count = _worldPacket.ReadBits(13); + _worldPacket.ResetBitPos(); + + Queries.resize(count); + for (uint32 i = 0; i < count; ++i) + { + _worldPacket >> Queries[i].GUID; + _worldPacket >> Queries[i].RecordID; + } +} + +WorldPacket const* WorldPackets::Query::DBReply::Write() +{ + _worldPacket << TableHash; + _worldPacket << RecordID; + _worldPacket << Timestamp; + + size_t sizePos = _worldPacket.wpos(); + _worldPacket << int32(0); // size of next block + + if (Data) + Data->WriteRecord(RecordID, Locale, _worldPacket); + + _worldPacket.put<int32>(sizePos, _worldPacket.wpos() - sizePos - 4); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/QueryPackets.h b/src/server/game/Server/Packets/QueryPackets.h index b7c57e94747..b9e04ec4260 100644 --- a/src/server/game/Server/Packets/QueryPackets.h +++ b/src/server/game/Server/Packets/QueryPackets.h @@ -20,6 +20,8 @@ #include "Packet.h" #include "Creature.h" +#include "NPCHandler.h" +#include "DB2Stores.h" namespace WorldPackets { @@ -141,6 +143,63 @@ namespace WorldPackets PageTextInfo Info; uint32 PageTextID = 0; }; + + class QueryNPCText final : public ClientPacket + { + public: + QueryNPCText(WorldPacket&& packet) : ClientPacket(CMSG_NPC_TEXT_QUERY, std::move(packet)) { } + + void Read() override; + + ObjectGuid Guid; + uint32 TextID = 0; + }; + + class QueryNPCTextResponse final : public ServerPacket + { + public: + QueryNPCTextResponse() : ServerPacket(SMSG_NPC_TEXT_UPDATE, 73) { } + + WorldPacket const* Write() override; + + uint32 TextID = 0; + bool Allow = false; + float Probabilities[MAX_GOSSIP_TEXT_OPTIONS]; + uint32 BroadcastTextID[MAX_GOSSIP_TEXT_OPTIONS]; + }; + + struct DBQueryRecord + { + ObjectGuid GUID; + uint32 RecordID; + }; + + class DBQueryBulk final : public ClientPacket + { + public: + DBQueryBulk(WorldPacket&& packet) : ClientPacket(CMSG_DB_QUERY_BULK, std::move(packet)) { } + + void Read() override; + + uint32 TableHash; + std::vector<DBQueryRecord> Queries; + }; + + class DBReply final : public ServerPacket + { + public: + DBReply() : ServerPacket(SMSG_DB_REPLY, 12) { } + + WorldPacket const* Write() override; + + uint32 TableHash = 0; + uint32 Timestamp = 0; + int32 RecordID = 0; + + // These are not sent directly + uint32 Locale = 0; + DB2StorageBase const* Data = nullptr; + }; } } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index bb97c1b3e38..5d508f814c3 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -27,6 +27,7 @@ #include "Packets/GuildPackets.h" #include "Packets/MiscPackets.h" #include "Packets/MovementPackets.h" +#include "Packets/NPCPackets.h" #include "Packets/QueryPackets.h" #include "Packets/QuestPackets.h" #include "Packets/TalentPackets.h" @@ -158,7 +159,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOSTORE_BANK_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBankItemOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOSTORE_LOOT_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutostoreLootItemOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTO_DECLINE_GUILD_INVITES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoDeclineGuildInvites ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_BANKER_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBankerActivateOpcode ); + DEFINE_HANDLER(CMSG_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleBankerActivateOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_LEAVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBattlefieldLeaveOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldListOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBfEntryInviteResponse ); @@ -179,7 +180,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PET_NAME_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PET_SET_BATTLE_SLOT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BEGIN_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBeginTradeOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_BINDER_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBinderActivateOpcode ); + DEFINE_HANDLER(CMSG_BINDER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleBinderActivateOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_BUG, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBugOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BUSY_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBusyTradeOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_BUYBACK_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBuybackItem ); @@ -264,7 +265,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_CORPSE_MAP_POSITION_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseMapPositionQuery ); DEFINE_HANDLER(CMSG_CREATURE_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Query::QueryCreature, &WorldSession::HandleCreatureQuery); DEFINE_OPCODE_HANDLER_OLD(CMSG_DANCE_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_DB_QUERY_BULK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_HANDLER(CMSG_DB_QUERY_BULK, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Query::DBQueryBulk, &WorldSession::HandleDBQueryBulk); DEFINE_OPCODE_HANDLER_OLD(CMSG_DEL_FRIEND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleDelFriendOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_DEL_IGNORE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleDelIgnoreOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_DEL_MUTE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -298,7 +299,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_GMTICKET_SYSTEMSTATUS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketSystemStatusOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_GMTICKET_UPDATETEXT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketUpdateOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GM_REPORT_LAG, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleReportLag ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_GOSSIP_HELLO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGossipHelloOpcode ); + DEFINE_HANDLER(CMSG_GOSSIP_HELLO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleGossipHelloOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_GOSSIP_SELECT_OPTION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGossipSelectOptionOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GRANT_LEVEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGrantLevel ); DEFINE_OPCODE_HANDLER_OLD(CMSG_GROUP_ASSISTANT_LEADER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupAssistantLeaderOpcode); @@ -389,7 +390,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_POST_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderPostRequest ); DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_REMOVE_RECRUIT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderRemoveRecruit ); DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_SET_GUILD_POST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderSetGuildPost ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_LIST_INVENTORY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleListInventoryOpcode ); + DEFINE_HANDLER(CMSG_LIST_INVENTORY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleListInventoryOpcode); DEFINE_HANDLER(CMSG_LOAD_SCREEN, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::LoadingScreenNotify, &WorldSession::HandleLoadScreenOpcode); DEFINE_HANDLER(CMSG_LOGOUT_CANCEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::LogoutCancel, &WorldSession::HandleLogoutCancelOpcode); DEFINE_HANDLER(CMSG_LOGOUT_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::LogoutRequest, &WorldSession::HandleLogoutRequestOpcode); @@ -479,7 +480,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_MOVE_WORLDPORT_ACK, STATUS_TRANSFER, PROCESS_THREADUNSAFE, WorldPackets::Movement::WorldPortAck, &WorldSession::HandleMoveWorldportAckOpcode); DEFINE_HANDLER(CMSG_NAME_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryPlayerName, &WorldSession::HandleNameQueryOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_NEXT_CINEMATIC_CAMERA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleNextCinematicCamera ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_NPC_TEXT_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleNpcTextQueryOpcode ); + DEFINE_HANDLER(CMSG_NPC_TEXT_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryNPCText, &WorldSession::HandleNpcTextQueryOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_OBJECT_UPDATE_FAILED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleObjectUpdateFailedOpcode ); DEFINE_OPCODE_HANDLER_OLD(CMSG_OBJECT_UPDATE_RESCUED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_OFFER_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleOfferPetitionOpcode ); @@ -549,7 +550,6 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_REQUEST_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::ClientConfig::RequestAccountData, &WorldSession::HandleRequestAccountData); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_CATEGORY_COOLDOWNS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleRequestCategoryCooldowns ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_CEMETERY_LIST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleRequestCemeteryList ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_HOTFIX, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleRequestHotfix ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_INSPECT_RATED_BG_STATS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PARTY_MEMBER_STATS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPartyMemberStatsOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PET_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPetInfoOpcode ); @@ -631,7 +631,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER_OLD(CMSG_TOGGLE_PVP, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTogglePvP ); DEFINE_OPCODE_HANDLER_OLD(CMSG_TOTEM_DESTROYED, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTotemDestroyed ); DEFINE_OPCODE_HANDLER_OLD(CMSG_TRAINER_BUY_SPELL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerBuySpellOpcode ); - DEFINE_OPCODE_HANDLER_OLD(CMSG_TRAINER_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerListOpcode ); + DEFINE_HANDLER(CMSG_TRAINER_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleTrainerListOpcode); DEFINE_OPCODE_HANDLER_OLD(CMSG_TRANSMOGRIFY_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTransmogrifyItems ); DEFINE_OPCODE_HANDLER_OLD(CMSG_TURN_IN_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTurnInPetitionOpcode ); DEFINE_HANDLER(CMSG_TUTORIAL_FLAG, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::TutorialSetFlag, &WorldSession::HandleTutorialFlag); @@ -863,7 +863,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_DAMAGE_CALC_LOG, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DANCE_QUERY_RESPONSE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DANCE_STUDIO_CREATE_RESULT, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_DB_REPLY, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_DB_REPLY, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEATH_RELEASE_LOC, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEBUG_RUNE_REGEN, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEFENSE_MESSAGE, STATUS_UNHANDLED); @@ -938,7 +938,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_TICKET_SYSTEM_STATUS, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GODMODE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_COMPLETE, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_MESSAGE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_MESSAGE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_POI, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUPACTION_THROTTLED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_CANCEL, STATUS_UNHANDLED); @@ -1056,7 +1056,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_MEMBERSHIP_LIST_UPDATED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_POST_UPDATED, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_RECRUIT_LIST_UPDATED, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_LIST_INVENTORY, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_LIST_INVENTORY, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_CUF_PROFILES, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGIN_SETTIMESPEED, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGIN_VERIFY_WORLD, STATUS_NEVER); @@ -1148,7 +1148,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFICATION, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFY_DANCE, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFY_DEST_LOC_SPELL_CAST, STATUS_UNHANDLED); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_NPC_TEXT_UPDATE, STATUS_UNHANDLED); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_NPC_TEXT_UPDATE, STATUS_NEVER); DEFINE_SERVER_OPCODE_HANDLER(SMSG_OFFER_PETITION_ERROR, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, STATUS_UNHANDLED); DEFINE_SERVER_OPCODE_HANDLER(SMSG_OPEN_CONTAINER, STATUS_UNHANDLED); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index cf98d5335db..7af9a02fa9b 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -335,7 +335,7 @@ enum OpcodeClient : uint32 CMSG_LF_GUILD_POST_REQUEST = 0xBADD, CMSG_LF_GUILD_REMOVE_RECRUIT = 0xBADD, CMSG_LF_GUILD_SET_GUILD_POST = 0xBADD, - CMSG_LIST_INVENTORY = 0xBADD, + CMSG_LIST_INVENTORY = 0x0B39, CMSG_LOAD_SCREEN = 0x0B08, CMSG_LOGOUT_CANCEL = 0x03C2, CMSG_LOGOUT_REQUEST = 0x1911, @@ -509,7 +509,6 @@ enum OpcodeClient : uint32 CMSG_REQUEST_ACCOUNT_DATA = 0x0F3E, CMSG_REQUEST_CATEGORY_COOLDOWNS = 0xBADD, CMSG_REQUEST_CEMETERY_LIST = 0x10A2, - CMSG_REQUEST_HOTFIX = 0xBADD, CMSG_REQUEST_INSPECT_RATED_BG_STATS = 0xBADD, CMSG_REQUEST_PARTY_MEMBER_STATS = 0xBADD, CMSG_REQUEST_PET_INFO = 0xBADD, diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 6bb4daf9fc3..baeace23b40 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -156,11 +156,18 @@ namespace WorldPackets class TutorialSetFlag; } + namespace NPC + { + class Hello; + } + namespace Query { class QueryCreature; class QueryPlayerName; class QueryPageText; + class QueryNPCText; + class DBQueryBulk; } namespace Quest @@ -675,10 +682,9 @@ class WorldSession void HandleGameobjectReportUse(WorldPacket& recvPacket); void HandleNameQueryOpcode(WorldPackets::Query::QueryPlayerName& packet); - void HandleQueryTimeOpcode(WorldPacket& recvPacket); - void HandleCreatureQuery(WorldPackets::Query::QueryCreature& packet); + void HandleDBQueryBulk(WorldPackets::Query::DBQueryBulk& packet); void HandleGameObjectQueryOpcode(WorldPacket& recvPacket); @@ -777,16 +783,16 @@ class WorldSession void SendActivateTaxiReply(ActivateTaxiReply reply); void HandleTabardVendorActivateOpcode(WorldPacket& recvPacket); - void HandleBankerActivateOpcode(WorldPacket& recvPacket); + void HandleBankerActivateOpcode(WorldPackets::NPC::Hello& packet); void HandleBuyBankSlotOpcode(WorldPacket& recvPacket); - void HandleTrainerListOpcode(WorldPacket& recvPacket); + void HandleTrainerListOpcode(WorldPackets::NPC::Hello& packet); void HandleTrainerBuySpellOpcode(WorldPacket& recvPacket); void HandlePetitionShowListOpcode(WorldPacket& recvPacket); - void HandleGossipHelloOpcode(WorldPacket& recvPacket); + void HandleGossipHelloOpcode(WorldPackets::NPC::Hello& packet); void HandleGossipSelectOptionOpcode(WorldPacket& recvPacket); void HandleSpiritHealerActivateOpcode(WorldPacket& recvPacket); - void HandleNpcTextQueryOpcode(WorldPacket& recvPacket); - void HandleBinderActivateOpcode(WorldPacket& recvPacket); + void HandleNpcTextQueryOpcode(WorldPackets::Query::QueryNPCText& packet); + void HandleBinderActivateOpcode(WorldPackets::NPC::Hello& packet); void HandleListStabledPetsOpcode(WorldPacket& recvPacket); void HandleStablePet(WorldPacket& recvPacket); void HandleStablePetCallback(PreparedQueryResult result); @@ -841,7 +847,7 @@ class WorldSession void HandleSellItemOpcode(WorldPacket& recvPacket); void HandleBuyItemInSlotOpcode(WorldPacket& recvPacket); void HandleBuyItemOpcode(WorldPacket& recvPacket); - void HandleListInventoryOpcode(WorldPacket& recvPacket); + void HandleListInventoryOpcode(WorldPackets::NPC::Hello& packet); void HandleAutoStoreBagItemOpcode(WorldPacket& recvPacket); void HandleReadItem(WorldPacket& recvPacket); void HandleAutoEquipItemSlotOpcode(WorldPacket& recvPacket); @@ -1132,7 +1138,6 @@ class WorldSession void HandleEjectPassenger(WorldPacket& data); void HandleEnterPlayerVehicle(WorldPacket& data); void HandleUpdateProjectilePosition(WorldPacket& recvPacket); - void HandleRequestHotfix(WorldPacket& recvPacket); void HandleUpdateMissileTrajectory(WorldPacket& recvPacket); void HandleViolenceLevel(WorldPackets::Misc::ViolenceLevel& violenceLevel); void HandleObjectUpdateFailedOpcode(WorldPacket& recvPacket); |