Core/Packets: Fix and enable CMSG_BUY_ITEM, SMSG_BUY_FAILED and SMSG_BUY_SUCCEEDED

Closes #14127
This commit is contained in:
Duarte Duarte
2015-02-13 00:45:39 +00:00
parent 40dcc170d9
commit f68473aeff
9 changed files with 196 additions and 63 deletions
@@ -230,6 +230,7 @@ enum CurrencyCategory
enum ItemVendorType
{
ITEM_VENDOR_TYPE_NONE = 0,
ITEM_VENDOR_TYPE_ITEM = 1,
ITEM_VENDOR_TYPE_CURRENCY = 2,
};
+12 -12
View File
@@ -12997,12 +12997,11 @@ void Player::SendEquipError(InventoryResult msg, Item* item1 /*= nullptr*/, Item
void Player::SendBuyError(BuyResult msg, Creature* creature, uint32 item, uint32 /*param*/)
{
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_BUY_FAILED");
WorldPacket data(SMSG_BUY_FAILED, (8+4+4+1));
data << (creature ? creature->GetGUID() : ObjectGuid::Empty);
data << uint32(item);
data << uint8(msg);
GetSession()->SendPacket(&data);
WorldPackets::Item::BuyFailed packet;
packet.VendorGUID = creature ? creature->GetGUID() : ObjectGuid::Empty;
packet.Muid = item;
packet.Reason = msg;
GetSession()->SendPacket(packet.Write());
}
void Player::SendSellError(SellResult msg, Creature* creature, ObjectGuid guid)
@@ -21358,12 +21357,13 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c
{
uint32 new_count = pVendor->UpdateVendorItemCurrentCount(crItem, count);
WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4));
data << pVendor->GetGUID();
data << uint32(vendorslot + 1); // numbered from 1 at client
data << int32(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF);
data << uint32(count);
GetSession()->SendPacket(&data);
WorldPackets::Item::BuySucceeded packet;
packet.VendorGUID = pVendor->GetGUID();
packet.Muid = vendorslot + 1;
packet.NewQuantity = crItem->maxcount > 0 ? new_count : 0xFFFFFFFF;
packet.QuantityBought = count;
GetSession()->SendPacket(packet.Write());
SendNewItem(it, count, true, false, false);
if (!bStore)
+26 -23
View File
@@ -529,38 +529,41 @@ void WorldSession::HandleBuyItemInSlotOpcode(WorldPacket& recvData)
GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, bag, bagslot);
}
void WorldSession::HandleBuyItemOpcode(WorldPacket& recvData)
void WorldSession::HandleBuyItemOpcode(WorldPackets::Item::BuyItem& packet)
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_BUY_ITEM");
ObjectGuid vendorguid, bagGuid;
uint32 item, slot, count;
uint8 itemType; // 1 = item, 2 = currency
uint8 bagSlot;
recvData >> vendorguid >> itemType >> item >> slot >> count >> bagGuid >> bagSlot;
// client expects count starting at 1, and we send vendorslot+1 to client already
if (slot > 0)
--slot;
if (packet.Muid > 0)
--packet.Muid;
else
return; // cheating
if (itemType == ITEM_VENDOR_TYPE_ITEM)
switch (packet.ItemType)
{
Item* bagItem = _player->GetItemByGuid(bagGuid);
case ITEM_VENDOR_TYPE_ITEM:
{
Item* bagItem = _player->GetItemByGuid(packet.ContainerGUID);
uint8 bag = NULL_BAG;
if (bagItem && bagItem->IsBag())
bag = bagItem->GetSlot();
else if (bagGuid == GetPlayer()->GetGUID()) // The client sends the player guid when trying to store an item in the default backpack
bag = INVENTORY_SLOT_BAG_0;
uint8 bag = NULL_BAG;
if (bagItem && bagItem->IsBag())
bag = bagItem->GetSlot();
else if (packet.ContainerGUID == GetPlayer()->GetGUID()) // The client sends the player guid when trying to store an item in the default backpack
bag = INVENTORY_SLOT_BAG_0;
GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, bag, bagSlot);
GetPlayer()->BuyItemFromVendorSlot(packet.VendorGUID, packet.Muid, packet.Item.ItemID,
packet.Quantity, bag, packet.Slot);
break;
}
case ITEM_VENDOR_TYPE_CURRENCY:
{
GetPlayer()->BuyCurrencyFromVendorSlot(packet.VendorGUID, packet.Muid, packet.Item.ItemID, packet.Quantity);
break;
}
default:
{
TC_LOG_DEBUG("network", "WORLD: received wrong itemType (%u) in HandleBuyItemOpcode", packet.ItemType);
break;
}
}
else if (itemType == ITEM_VENDOR_TYPE_CURRENCY)
GetPlayer()->BuyCurrencyFromVendorSlot(vendorguid, slot, item, count);
else
TC_LOG_DEBUG("network", "WORLD: received wrong itemType (%u) in HandleBuyItemOpcode", itemType);
}
void WorldSession::HandleListInventoryOpcode(WorldPackets::NPC::Hello& packet)
+71 -5
View File
@@ -19,8 +19,39 @@
void WorldPackets::Item::BuyBackItem::Read()
{
_worldPacket >> VendorGUID;
_worldPacket >> Slot;
_worldPacket >> VendorGUID
>> Slot;
}
void WorldPackets::Item::BuyItem::Read()
{
_worldPacket >> VendorGUID
>> ContainerGUID
>> Item
>> Quantity
>> Muid
>> Slot;
ItemType = static_cast<ItemVendorType>(_worldPacket.ReadBits(2));
}
WorldPacket const* WorldPackets::Item::BuySucceeded::Write()
{
_worldPacket << VendorGUID
<< uint32(Muid)
<< int32(NewQuantity)
<< uint32(QuantityBought);
return &_worldPacket;
}
WorldPacket const* WorldPackets::Item::BuyFailed::Write()
{
_worldPacket << VendorGUID
<< uint32(Muid)
<< uint8(Reason);
return &_worldPacket;
}
void WorldPackets::Item::GetItemPurchaseData::Read()
@@ -68,11 +99,28 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceDa
return data;
}
ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData& itemBonusInstanceData)
{
uint32 bonusListIdSize;
data >> itemBonusInstanceData.Context;
data >> bonusListIdSize;
for (uint32 i = 0u; i < bonusListIdSize; ++i)
{
uint32 bonusId;
data >> bonusId;
itemBonusInstanceData.BonusListIDs.push_back(bonusId);
}
return data;
}
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemInstance const& itemInstance)
{
data << itemInstance.ItemID;
data << itemInstance.RandomPropertiesSeed;
data << itemInstance.RandomPropertiesID;
data << int32(itemInstance.ItemID);
data << int32(itemInstance.RandomPropertiesSeed);
data << int32(itemInstance.RandomPropertiesID);
data.WriteBit(itemInstance.ItemBonus.HasValue);
data.WriteBit(itemInstance.Modifications.HasValue);
@@ -87,6 +135,24 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemInstance const&
return data;
}
ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemInstance& itemInstance)
{
data >> itemInstance.ItemID;
data >> itemInstance.RandomPropertiesSeed;
data >> itemInstance.RandomPropertiesID;
itemInstance.ItemBonus.HasValue = data.ReadBit();
itemInstance.Modifications.HasValue = data.ReadBit();
if (itemInstance.ItemBonus.HasValue)
data >> itemInstance.ItemBonus.Value;
if (itemInstance.Modifications.HasValue)
data >> itemInstance.Modifications.Value;
return data;
}
ByteBuffer& WorldPackets::Item::operator>>(ByteBuffer& data, InvUpdate& invUpdate)
{
invUpdate.Items.resize(data.ReadBits(2));
+61 -18
View File
@@ -26,6 +26,24 @@ namespace WorldPackets
{
namespace Item
{
struct ItemBonusInstanceData
{
uint8 Context = 0;
std::vector<int32> BonusListIDs;
};
struct ItemInstance
{
void Initalize(::Item const* item);
void Initalize(::LootItem const& lootItem);
uint32 ItemID = 0;
uint32 RandomPropertiesSeed = 0;
uint32 RandomPropertiesID = 0;
Optional<ItemBonusInstanceData> ItemBonus;
Optional<CompactArray<int32>> Modifications;
};
class BuyBackItem final : public ClientPacket
{
public:
@@ -37,6 +55,47 @@ namespace WorldPackets
uint32 Slot = 0;
};
class BuyItem final : public ClientPacket
{
public:
BuyItem(WorldPacket&& packet) : ClientPacket(CMSG_BUY_ITEM, std::move(packet)) { }
void Read() override;
ObjectGuid VendorGUID;
ItemInstance Item;
uint32 Muid = 0u;
uint32 Slot = 0u;
ItemVendorType ItemType = ITEM_VENDOR_TYPE_NONE;
int32 Quantity = 0;
ObjectGuid ContainerGUID;
};
class BuySucceeded final : ServerPacket
{
public:
BuySucceeded() : ServerPacket(SMSG_BUY_SUCCEEDED, 16 + 4 + 4 + 4 + 4) { }
WorldPacket const* Write() override;
ObjectGuid VendorGUID;
uint32 Muid = 0u;
uint32 QuantityBought = 0u;
int32 NewQuantity = 0;
};
class BuyFailed final : ServerPacket
{
public:
BuyFailed() : ServerPacket(SMSG_BUY_FAILED, 16 + 4 + 1) { }
WorldPacket const* Write() override;
ObjectGuid VendorGUID;
uint32 Muid = 0u;
BuyResult Reason = BUY_ERR_CANT_FIND_ITEM;
};
class GetItemPurchaseData final : public ClientPacket
{
public:
@@ -93,24 +152,6 @@ namespace WorldPackets
uint8 ProficiencyClass = 0;
};
struct ItemBonusInstanceData
{
uint8 Context = 0;
std::vector<int32> BonusListIDs;
};
struct ItemInstance
{
void Initalize(::Item const* item);
void Initalize(::LootItem const& lootItem);
uint32 ItemID = 0;
uint32 RandomPropertiesSeed = 0;
uint32 RandomPropertiesID = 0;
Optional<ItemBonusInstanceData> ItemBonus;
Optional<CompactArray<int32>> Modifications;
};
struct InvUpdate
{
struct InvItem
@@ -222,6 +263,8 @@ namespace WorldPackets
}
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData const& itemBonusInstanceData);
ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData& itemBonusInstanceData);
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemInstance const& itemInstance);
ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemInstance& itemInstance);
#endif // ItemPackets_h__
@@ -73,4 +73,23 @@ namespace WorldPackets
return data;
}
template <typename T>
ByteBuffer& operator>>(ByteBuffer& data, CompactArray<T>& v)
{
uint32 mask;
data >> mask;
for (size_t index = 0; mask != 0; mask >>= 1, ++index)
{
if ((mask & 1) != 0)
{
T value;
data >> value;
v.Insert(index, value);
}
}
return data;
}
}
+3 -3
View File
@@ -229,7 +229,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_BUSY_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBusyTradeOpcode );
DEFINE_HANDLER(CMSG_BUY_BACK_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::BuyBackItem, &WorldSession::HandleBuybackItem);
DEFINE_OPCODE_HANDLER_OLD(CMSG_BUY_BANK_SLOT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyBankSlotOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BUY_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyItemOpcode );
DEFINE_HANDLER(CMSG_BUY_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::BuyItem, &WorldSession::HandleBuyItemOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_CAGE_BATTLE_PET, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_ADD_EVENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarAddEvent );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_ARENA_TEAM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarArenaTeam );
@@ -1056,8 +1056,8 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BONUS_ROLL_EMPTY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BREAK_TARGET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_BANK_SLOT_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_ITEM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_FAILED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_SUCCEEDED, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_ACTION_PENDING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_ARENA_TEAM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_CLEAR_PENDING_ACTION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+1 -1
View File
@@ -958,7 +958,7 @@ enum OpcodeServer : uint32
SMSG_BREAK_TARGET = 0x11A2,
SMSG_BUY_BANK_SLOT_RESULT = 0xBADD,
SMSG_BUY_FAILED = 0x013A,
SMSG_BUY_ITEM = 0x0BD1,
SMSG_BUY_SUCCEEDED = 0x0BD1,
SMSG_CALENDAR_ACTION_PENDING = 0xBADD,
SMSG_CALENDAR_ARENA_TEAM = 0xBADD,
SMSG_CALENDAR_CLEAR_PENDING_ACTION = 0x1E8A,
+2 -1
View File
@@ -180,6 +180,7 @@ namespace WorldPackets
{
class AutoEquipItem;
class AutoStoreBagItem;
class BuyItem;
class BuyBackItem;
class DestroyItem;
class GetItemPurchaseData;
@@ -984,7 +985,7 @@ class WorldSession
void HandleAutoEquipItemOpcode(WorldPackets::Item::AutoEquipItem& autoEquipItem);
void HandleSellItemOpcode(WorldPackets::Item::SellItem& packet);
void HandleBuyItemInSlotOpcode(WorldPacket& recvPacket);
void HandleBuyItemOpcode(WorldPacket& recvPacket);
void HandleBuyItemOpcode(WorldPackets::Item::BuyItem& packet);
void HandleListInventoryOpcode(WorldPackets::NPC::Hello& packet);
void HandleAutoStoreBagItemOpcode(WorldPackets::Item::AutoStoreBagItem& packet);
void HandleReadItem(WorldPacket& recvPacket);