Core/PacketIO: Updated AH and mail packets

This commit is contained in:
Shauren
2016-06-14 21:28:48 +02:00
parent d2733eb6f1
commit 27e08e48e1
12 changed files with 234 additions and 111 deletions
@@ -660,8 +660,7 @@ void AuctionHouseObject::BuildListOwnerItems(WorldPackets::AuctionHouse::Auction
}
void AuctionHouseObject::BuildListAuctionItems(WorldPackets::AuctionHouse::AuctionListItemsResult& packet, Player* player,
std::wstring const& wsearchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, uint8 usable,
uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality, uint32& totalcount)
std::wstring const& searchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, bool usable, Optional<AuctionSearchFilters> const& filters, uint32 quality)
{
time_t curTime = sWorld->GetGameTime();
@@ -677,15 +676,24 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPackets::AuctionHouse::Aucti
continue;
ItemTemplate const* proto = item->GetTemplate();
if (filters)
{
// if we dont want any class filters, Optional is not initialized
// if we dont want this class included, SubclassMask is set to FILTER_SKIP_CLASS
// if we want this class and did not specify and subclasses, its set to FILTER_SKIP_SUBCLASS
// otherwise full restrictions apply
if (filters->Classes[proto->GetClass()].SubclassMask == AuctionSearchFilters::FILTER_SKIP_CLASS)
continue;
if (itemClass != 0xffffffff && proto->GetClass() != itemClass)
continue;
if (filters->Classes[proto->GetClass()].SubclassMask != AuctionSearchFilters::FILTER_SKIP_SUBCLASS)
{
if (!(filters->Classes[proto->GetClass()].SubclassMask & (1 << proto->GetSubClass())))
continue;
if (itemSubClass != 0xffffffff && proto->GetSubClass() != itemSubClass)
continue;
if (inventoryType != 0xffffffff && proto->GetInventoryType() != InventoryType(inventoryType))
continue;
if (!(filters->Classes[proto->GetClass()].InvTypes[proto->GetSubClass()] & (1 << proto->GetInventoryType())))
continue;
}
}
if (quality != 0xffffffff && proto->GetQuality() != quality)
continue;
@@ -693,12 +701,12 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPackets::AuctionHouse::Aucti
if (levelmin != 0 && (proto->GetBaseRequiredLevel() < levelmin || (levelmax != 0 && proto->GetBaseRequiredLevel() > levelmax)))
continue;
if (usable != 0 && player->CanUseItem(item) != EQUIP_ERR_OK)
if (usable && player->CanUseItem(item) != EQUIP_ERR_OK)
continue;
// Allow search by suffix (ie: of the Monkey) or partial name (ie: Monkey)
// No need to do any of this if no search term was entered
if (!wsearchedname.empty())
if (!searchedname.empty())
{
std::string name = proto->GetName(player->GetSession()->GetSessionDbcLocale());
if (name.empty())
@@ -741,15 +749,15 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPackets::AuctionHouse::Aucti
}
// Perform the search (with or without suffix)
if (!Utf8FitTo(name, wsearchedname))
if (!Utf8FitTo(name, searchedname))
continue;
}
// Add the item if no search term or if entered search term was found
if (packet.Items.size() < 50 && totalcount >= listfrom)
if (packet.Items.size() < 50 && packet.TotalCount >= listfrom)
Aentry->BuildAuctionInfo(packet.Items, true, item);
++totalcount;
++packet.TotalCount;
}
}
@@ -837,6 +845,18 @@ void AuctionEntry::BuildAuctionInfo(std::vector<WorldPackets::AuctionHouse::Auct
auctionItem.Enchantments.emplace_back(item->GetEnchantmentId((EnchantmentSlot) i), item->GetEnchantmentDuration((EnchantmentSlot) i), item->GetEnchantmentCharges((EnchantmentSlot) i), i);
}
for (std::size_t i = 0; i < item->GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).size(); ++i)
{
uint32 gemItemId = item->GetDynamicValue(ITEM_DYNAMIC_FIELD_GEMS, i);
if (!gemItemId)
continue;
WorldPackets::Item::ItemGemInstanceData gem;
gem.Slot = i;
gem.Item.ItemID = gemItemId;
auctionItem.Gems.push_back(gem);
}
items.emplace_back(auctionItem);
}
+19 -2
View File
@@ -96,6 +96,24 @@ struct TC_GAME_API AuctionEntry
};
struct AuctionSearchFilters
{
enum FilterType : uint32
{
FILTER_SKIP_CLASS = 0,
FILTER_SKIP_SUBCLASS = 0xFFFFFFFF,
FILTER_SKIP_INVTYPE = 0xFFFFFFFF
};
struct SubclassFilter
{
uint32 SubclassMask = FILTER_SKIP_CLASS;
std::array<uint32, MAX_ITEM_SUBCLASS_TOTAL> InvTypes;
};
std::array<SubclassFilter, MAX_ITEM_CLASS> Classes;
};
//this class is used as auctionhouse instance
class TC_GAME_API AuctionHouseObject
{
@@ -140,8 +158,7 @@ class TC_GAME_API AuctionHouseObject
void BuildListBidderItems(WorldPackets::AuctionHouse::AuctionListBidderItemsResult& packet, Player* player, uint32& totalcount);
void BuildListOwnerItems(WorldPackets::AuctionHouse::AuctionListOwnerItemsResult& packet, Player* player, uint32& totalcount);
void BuildListAuctionItems(WorldPackets::AuctionHouse::AuctionListItemsResult& packet, Player* player,
std::wstring const& searchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, uint8 usable,
uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality, uint32& totalcount);
std::wstring const& searchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, bool usable, Optional<AuctionSearchFilters> const& filters, uint32 quality);
void BuildReplicate(WorldPackets::AuctionHouse::AuctionReplicateResponse& auctionReplicateResult, Player* player,
uint32 global, uint32 cursor, uint32 tombstone, uint32 count);
@@ -653,6 +653,8 @@ const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] =
MAX_ITEM_SUBCLASS_GLYPH
};
#define MAX_ITEM_SUBCLASS_TOTAL 21
#define MIN_ITEM_LEVEL 1
#define MAX_ITEM_LEVEL 1000
+2 -2
View File
@@ -17262,7 +17262,7 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
Field* fields = result->Fetch();
if (Item* item = _LoadItem(trans, zoneId, timeDiff, fields))
{
ObjectGuid bagGuid = fields[21].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[24].GetUInt64()) : ObjectGuid::Empty;
ObjectGuid bagGuid = fields[24].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[24].GetUInt64()) : ObjectGuid::Empty;
uint8 slot = fields[25].GetUInt8();
GetSession()->GetCollectionMgr()->CheckHeirloomUpgrades(item);
@@ -17591,7 +17591,7 @@ void Player::_LoadMailedItems(Mail* mail)
Item* item = NewItemOrBag(proto);
ObjectGuid ownerGuid = fields[21].GetUInt64() ? ObjectGuid::Create<HighGuid::Player>(fields[21].GetUInt64()) : ObjectGuid::Empty;
ObjectGuid ownerGuid = fields[24].GetUInt64() ? ObjectGuid::Create<HighGuid::Player>(fields[24].GetUInt64()) : ObjectGuid::Empty;
if (!item->LoadFromDB(itemGuid, ownerGuid, fields, itemEntry))
{
TC_LOG_ERROR("entities.player", "Player::_LoadMailedItems: Item (GUID: " UI64FMTD ") in mail (%u) doesn't exist, deleted from mail.", itemGuid, mail->messageID);
@@ -616,10 +616,8 @@ void WorldSession::HandleAuctionListItems(WorldPackets::AuctionHouse::AuctionLis
AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction());
TC_LOG_DEBUG("auctionHouse", "Auctionhouse search (%s), searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u",
packet.Auctioneer.ToString().c_str(), packet.Name.c_str(), packet.MinLevel, packet.MaxLevel , packet.InvType, packet.ItemClass, packet.ItemSubclass, packet.Quality, packet.OnlyUsable);
WorldPackets::AuctionHouse::AuctionListItemsResult result;
TC_LOG_DEBUG("auctionHouse", "Auctionhouse search (%s), searchedname: %s, levelmin: %u, levelmax: %u, quality: %u, usable: %u",
packet.Auctioneer.ToString().c_str(), packet.Name.c_str(), packet.MinLevel, packet.MaxLevel , packet.Quality, packet.OnlyUsable);
// converting string that we try to find to lower case
std::wstring wsearchedname;
@@ -628,9 +626,29 @@ void WorldSession::HandleAuctionListItems(WorldPackets::AuctionHouse::AuctionLis
wstrToLower(wsearchedname);
auctionHouse->BuildListAuctionItems(result, _player,
wsearchedname, packet.Offset, packet.MinLevel, packet.MaxLevel, packet.OnlyUsable,
packet.InvType, packet.ItemClass, packet.ItemSubclass, packet.Quality, result.TotalCount);
Optional<AuctionSearchFilters> filters;
WorldPackets::AuctionHouse::AuctionListItemsResult result;
if (packet.ClassFilters.empty())
{
filters = boost::in_place();
for (auto const& classFilter : packet.ClassFilters)
{
if (!classFilter.SubClassFilters.empty())
{
for (auto const& subClassFilter : classFilter.SubClassFilters)
{
filters->Classes[classFilter.ItemClass].SubclassMask |= 1 << subClassFilter.ItemSubclass;
filters->Classes[classFilter.ItemClass].InvTypes[subClassFilter.ItemSubclass] = subClassFilter.InvTypeMask;
}
}
else
filters->Classes[classFilter.ItemClass].SubclassMask = AuctionSearchFilters::FILTER_SKIP_SUBCLASS;
}
}
auctionHouse->BuildListAuctionItems(result, _player, wsearchedname, packet.Offset, packet.MinLevel, packet.MaxLevel, packet.OnlyUsable, filters, packet.Quality);
result.DesiredDelay = sWorld->getIntConfig(CONFIG_AUCTION_SEARCH_DELAY);
result.OnlyUsable = packet.OnlyUsable;
@@ -24,7 +24,6 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::AuctionHouse::AuctionItem
data << auctionItem.Item; // ItemInstance
data << int32(auctionItem.Count);
data << int32(auctionItem.Charges);
data << int32(auctionItem.Enchantments.size());
data << int32(auctionItem.Flags);
data << int32(auctionItem.AuctionItemID);
data << auctionItem.Owner;
@@ -33,8 +32,16 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::AuctionHouse::AuctionItem
data << uint64(auctionItem.BuyoutPrice);
data << int32(auctionItem.DurationLeft);
data << uint8(auctionItem.DeleteReason);
data.WriteBits(auctionItem.Enchantments.size(), 4);
data.WriteBits(auctionItem.Gems.size(), 2);
data.WriteBit(auctionItem.CensorServerSideInfo);
data.WriteBit(auctionItem.CensorBidInfo);
data.FlushBits();
for (auto const& enchant : auctionItem.Enchantments)
for (auto const& gem : auctionItem.Gems)
data << gem;
for (WorldPackets::AuctionHouse::AuctionItem::AuctionItemEnchant const& enchant : auctionItem.Enchantments)
{
data << int32(enchant.ID);
data << uint32(enchant.Expiration);
@@ -42,19 +49,14 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::AuctionHouse::AuctionItem
data << uint8(enchant.Slot);
}
data.FlushBits();
bool censorServerSideInfo = !data.WriteBit(auctionItem.CensorServerSideInfo);
bool censorBidInfo = !data.WriteBit(auctionItem.CensorBidInfo);
if (censorServerSideInfo)
if (!auctionItem.CensorServerSideInfo)
{
data << auctionItem.ItemGuid;
data << auctionItem.OwnerAccountID;
data << int32(auctionItem.EndTime);
}
if (censorBidInfo)
if (!auctionItem.CensorBidInfo)
{
data << auctionItem.Bidder;
data << uint64(auctionItem.BidAmount);
@@ -195,14 +197,12 @@ WorldPacket const* WorldPackets::AuctionHouse::AuctionListItemsResult::Write()
_worldPacket << int32(Items.size());
_worldPacket << int32(TotalCount);
_worldPacket << int32(DesiredDelay);
for (auto const& item : Items)
_worldPacket << item;
_worldPacket.FlushBits();
_worldPacket.WriteBit(OnlyUsable);
_worldPacket.FlushBits();
for (AuctionItem const& item : Items)
_worldPacket << item;
return &_worldPacket;
}
@@ -212,7 +212,7 @@ WorldPacket const* WorldPackets::AuctionHouse::AuctionListOwnerItemsResult::Writ
_worldPacket << uint32(TotalCount);
_worldPacket << uint32(DesiredDelay);
for (auto const& item : Items)
for (AuctionItem const& item : Items)
_worldPacket << item;
return &_worldPacket;
@@ -224,7 +224,7 @@ WorldPacket const* WorldPackets::AuctionHouse::AuctionListBidderItemsResult::Wri
_worldPacket << uint32(TotalCount);
_worldPacket << uint32(DesiredDelay);
for (auto const& item : Items)
for (AuctionItem const& item : Items)
_worldPacket << item;
return &_worldPacket;
@@ -236,25 +236,36 @@ void WorldPackets::AuctionHouse::AuctionListItems::Read()
_worldPacket >> Auctioneer;
_worldPacket >> MinLevel;
_worldPacket >> MaxLevel;
_worldPacket >> InvType;
_worldPacket >> ItemClass;
_worldPacket >> ItemSubclass;
_worldPacket >> Quality;
_worldPacket >> SortCount;
KnownPets.resize(_worldPacket.read<uint32>());
_worldPacket >> MaxPetLevel;
for (std::size_t i = 0; i < KnownPets.size(); ++i)
_worldPacket >> KnownPets[i];
_worldPacket.FlushBits();
uint32 nameLength = _worldPacket.ReadBits(8);
Name = _worldPacket.ReadString(nameLength);
Name = _worldPacket.ReadString(_worldPacket.ReadBits(8));
ClassFilters.resize(_worldPacket.ReadBits(3));
OnlyUsable = _worldPacket.ReadBit();
ExactMatch = _worldPacket.ReadBit();
for (ClassFilter& classFilter : ClassFilters)
{
_worldPacket >> classFilter.ItemClass;
classFilter.SubClassFilters.resize(_worldPacket.ReadBits(5));
for (ClassFilter::SubClassFilter& subclassFilter : classFilter.SubClassFilters)
{
_worldPacket >> subclassFilter.ItemSubclass;
_worldPacket >> subclassFilter.InvTypeMask;
}
}
_worldPacket.read_skip<uint32>(); // DataSize = (SortCount * 2)
for (int32 i = 0; i < SortCount; i++)
{
WorldPackets::AuctionHouse::AuctionListItems::Sort sort;
_worldPacket >> sort.UnkByte1;
_worldPacket >> sort.UnkByte2;
DataSort.emplace_back(sort);
_worldPacket >> sort.Type;
_worldPacket >> sort.Direction;
DataSort.push_back(sort);
}
}
@@ -266,7 +277,7 @@ void WorldPackets::AuctionHouse::AuctionListOwnerItems::Read()
WorldPacket const* WorldPackets::AuctionHouse::AuctionListPendingSalesResult::Write()
{
_worldPacket << int32(Mails.size());
_worldPacket << uint32(Mails.size());
_worldPacket << int32(TotalNumRecords);
for (auto const& mail : Mails)
@@ -312,12 +323,12 @@ WorldPacket const* WorldPackets::AuctionHouse::AuctionOutBidNotification::Write(
WorldPacket const* WorldPackets::AuctionHouse::AuctionReplicateResponse::Write()
{
_worldPacket << int32(Result);
_worldPacket << int32(DesiredDelay);
_worldPacket << int32(ChangeNumberGlobal);
_worldPacket << int32(ChangeNumberCursor);
_worldPacket << int32(ChangeNumberTombstone);
_worldPacket << int32(Items.size());
_worldPacket << uint32(Result);
_worldPacket << uint32(DesiredDelay);
_worldPacket << uint32(ChangeNumberGlobal);
_worldPacket << uint32(ChangeNumberCursor);
_worldPacket << uint32(ChangeNumberTombstone);
_worldPacket << uint32(Items.size());
for (auto const& item : Items)
_worldPacket << item;
@@ -59,6 +59,7 @@ namespace WorldPackets
uint32 EndTime = 0;
ObjectGuid Bidder;
uint64 BidAmount = 0;
std::vector<Item::ItemGemInstanceData> Gems;
};
struct AuctionOwnerNotification
@@ -254,25 +255,37 @@ namespace WorldPackets
public:
struct Sort
{
uint8 UnkByte1 = 0;
uint8 UnkByte2 = 0;
uint8 Type = 0;
uint8 Direction = 0;
};
struct ClassFilter
{
struct SubClassFilter
{
int32 ItemSubclass;
uint32 InvTypeMask;
};
int32 ItemClass;
Array<SubClassFilter, 31> SubClassFilters;
};
AuctionListItems(WorldPacket&& packet) : ClientPacket(CMSG_AUCTION_LIST_ITEMS, std::move(packet)) { }
void Read() override;
ObjectGuid Auctioneer;
uint8 SortCount = 0;
uint8 MaxLevel = 100;
uint32 Offset = 0;
int32 ItemClass = 0;
ObjectGuid Auctioneer;
uint8 MinLevel = 1;
int32 InvType = 0;
uint8 MaxLevel = 100;
int32 Quality = 0;
int32 ItemSubclass = 0;
bool ExactMatch = true;
uint8 SortCount = 0;
Array<uint8> KnownPets;
int8 MaxPetLevel;
std::string Name;
Array<ClassFilter, 7> ClassFilters;
bool ExactMatch = true;
bool OnlyUsable = false;
std::vector<Sort> DataSort;
};
+24 -10
View File
@@ -165,7 +165,7 @@ WorldPacket const* WorldPackets::Item::SetProficiency::Write()
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData const& itemBonusInstanceData)
{
data << itemBonusInstanceData.Context;
data << uint8(itemBonusInstanceData.Context);
data << uint32(itemBonusInstanceData.BonusListIDs.size());
for (uint32 bonusID : itemBonusInstanceData.BonusListIDs)
data << bonusID;
@@ -173,20 +173,18 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceDa
return data;
}
ByteBuffer& operator>>(ByteBuffer& data, Optional<WorldPackets::Item::ItemBonusInstanceData>& itemBonusInstanceData)
ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData& itemBonusInstanceData)
{
uint32 bonusListIdSize;
itemBonusInstanceData = boost::in_place();
data >> itemBonusInstanceData->Context;
data >> itemBonusInstanceData.Context;
data >> bonusListIdSize;
for (uint32 i = 0u; i < bonusListIdSize; ++i)
{
uint32 bonusId;
data >> bonusId;
itemBonusInstanceData->BonusListIDs.push_back(bonusId);
itemBonusInstanceData.BonusListIDs.push_back(bonusId);
}
return data;
@@ -221,18 +219,34 @@ ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemInstance& itemI
bool const hasModifications = data.ReadBit();
if (hasItemBonus)
data >> itemInstance.ItemBonus;
{
itemInstance.ItemBonus = boost::in_place();
data >> *itemInstance.ItemBonus;
}
if (hasModifications)
{
WorldPackets::CompactArray<int32> modifications;
data >> modifications;
itemInstance.Modifications = std::move(modifications);
itemInstance.Modifications = boost::in_place();
data >> *itemInstance.Modifications;
}
return data;
}
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemGemInstanceData const& itemGemInstanceData)
{
data << uint8(itemGemInstanceData.Slot);
data << itemGemInstanceData.Item;
return data;
}
ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemGemInstanceData& itemGemInstanceData)
{
data >> itemGemInstanceData.Slot;
data >> itemGemInstanceData.Item;
return data;
}
ByteBuffer& WorldPackets::Item::operator>>(ByteBuffer& data, InvUpdate& invUpdate)
{
invUpdate.Items.resize(data.ReadBits(2));
@@ -53,6 +53,12 @@ namespace WorldPackets
bool operator!=(ItemInstance const& r) const { return !(*this == r); }
};
struct ItemGemInstanceData
{
uint8 Slot;
ItemInstance Item;
};
class BuyBackItem final : public ClientPacket
{
public:
@@ -533,5 +539,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceDa
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);
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemGemInstanceData const& itemGemInstanceData);
ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Item::ItemGemInstanceData& itemGemInstanceData);
#endif // ItemPackets_h__
+37 -19
View File
@@ -33,32 +33,54 @@ WorldPackets::Mail::MailAttachedItem::MailAttachedItem(::Item const* item, uint8
for (uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; j++)
{
Enchants[j].Enchant = item->GetEnchantmentId((EnchantmentSlot)j);
Enchants[j].Duration = item->GetEnchantmentDuration((EnchantmentSlot)j);
Enchants[j].Charges = item->GetEnchantmentCharges((EnchantmentSlot)j);
if (!item->GetEnchantmentId((EnchantmentSlot)j))
continue;
MailAttachedItemEnchant enchant;
enchant.Enchant = item->GetEnchantmentId((EnchantmentSlot)j);
enchant.Duration = item->GetEnchantmentDuration((EnchantmentSlot)j);
enchant.Charges = item->GetEnchantmentCharges((EnchantmentSlot)j);
enchant.Slot = j;
Enchants.push_back(enchant);
}
for (std::size_t i = 0; i < item->GetDynamicValues(ITEM_DYNAMIC_FIELD_GEMS).size(); ++i)
{
uint32 gemItemId = item->GetDynamicValue(ITEM_DYNAMIC_FIELD_GEMS, i);
if (!gemItemId)
continue;
Item::ItemGemInstanceData gem;
gem.Slot = i;
gem.Item.ItemID = gemItemId;
Gems.push_back(gem);
}
}
ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Mail::MailAttachedItem const& att)
{
data << uint8(att.Position);
data << uint32(att.AttachID);
data << int32(att.AttachID);
data << int32(att.Count);
data << int32(att.Charges);
data << uint32(att.MaxDurability);
data << int32(att.Durability);
data << att.Item;
data.WriteBits(att.Enchants.size(), 4);
data.WriteBits(att.Gems.size(), 2);
data.WriteBit(att.Unlocked);
data.FlushBits();
for (auto const& gem : att.Gems)
data << gem;
for (auto const& en : att.Enchants)
{
data << int32(en.Enchant);
data << int32(en.Duration);
data << uint32(en.Duration);
data << int32(en.Charges);
}
data << int32(att.Count);
data << int32(att.Charges);
data << int32(att.MaxDurability);
data << int32(att.Durability);
data.WriteBit(att.Unlocked);
data.FlushBits();
return data;
}
@@ -100,26 +122,22 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Mail::MailListEntry const
{
data << int32(entry.MailID);
data << int8(entry.SenderType);
data << int64(entry.Cod);
data << int32(entry.StationeryID);
data << int64(entry.SentMoney);
data << int32(entry.Flags);
data << float(entry.DaysLeft);
data << int32(entry.MailTemplateID);
data << int32(entry.Attachments.size());
for (auto const& att : entry.Attachments)
data << att;
data.WriteBit(entry.SenderCharacter.is_initialized());
data.WriteBit(entry.AltSenderID.is_initialized());
data.WriteBits(entry.Subject.size(), 8);
data.WriteBits(entry.Body.size(), 13);
data.FlushBits();
for (auto const& att : entry.Attachments)
data << att;
if (entry.SenderCharacter)
data << *entry.SenderCharacter;
+5 -3
View File
@@ -32,8 +32,9 @@ namespace WorldPackets
struct MailAttachedItemEnchant
{
int32 Enchant = 0;
int32 Duration = 0;
uint32 Duration = 0;
int32 Charges = 0;
uint8 Slot = 0;
};
struct MailAttachedItem
@@ -45,10 +46,11 @@ namespace WorldPackets
Item::ItemInstance Item;
int32 Count = 0;
int32 Charges = 0;
int32 MaxDurability = 0;
uint32 MaxDurability = 0;
int32 Durability = 0;
bool Unlocked = false;
MailAttachedItemEnchant Enchants[8];
std::vector<MailAttachedItemEnchant> Enchants;
std::vector<Item::ItemGemInstanceData> Gems;
};
struct MailListEntry
+13 -13
View File
@@ -138,7 +138,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_ATTACK_SWING, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Combat::AttackSwing, &WorldSession::HandleAttackSwingOpcode);
DEFINE_HANDLER(CMSG_AUCTION_HELLO_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionHelloRequest, &WorldSession::HandleAuctionHelloOpcode);
DEFINE_HANDLER(CMSG_AUCTION_LIST_BIDDER_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionListBidderItems, &WorldSession::HandleAuctionListBidderItems);
DEFINE_HANDLER(CMSG_AUCTION_LIST_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionListItems, &WorldSession::HandleAuctionListItems);
DEFINE_HANDLER(CMSG_AUCTION_LIST_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionListItems, &WorldSession::HandleAuctionListItems);
DEFINE_HANDLER(CMSG_AUCTION_LIST_OWNER_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionListOwnerItems, &WorldSession::HandleAuctionListOwnerItems);
DEFINE_HANDLER(CMSG_AUCTION_LIST_PENDING_SALES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionListPendingSales, &WorldSession::HandleAuctionListPendingSales);
DEFINE_HANDLER(CMSG_AUCTION_PLACE_BID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::AuctionHouse::AuctionPlaceBid, &WorldSession::HandleAuctionPlaceBid);
@@ -686,7 +686,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_SELL_WOW_TOKEN_CONFIRM, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_SELL_WOW_TOKEN_START, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_SEND_CONTACT_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Social::SendContactList, &WorldSession::HandleContactListOpcode);
DEFINE_HANDLER(CMSG_SEND_MAIL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Mail::SendMail, &WorldSession::HandleSendMail);
DEFINE_HANDLER(CMSG_SEND_MAIL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Mail::SendMail, &WorldSession::HandleSendMail);
DEFINE_HANDLER(CMSG_SEND_SOR_REQUEST_VIA_ADDRESS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_SEND_TEXT_EMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::CTextEmote, &WorldSession::HandleTextEmoteOpcode);
DEFINE_HANDLER(CMSG_SET_ACHIEVEMENTS_HIDDEN, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
@@ -857,17 +857,17 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACK_STOP, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACK_SWING_ERROR, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACK_SWING_LANDED_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_CLOSED_NOTIFICATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_CLOSED_NOTIFICATION, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_COMMAND_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_HELLO_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_BIDDER_ITEMS_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_ITEMS_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_OWNER_ITEMS_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_PENDING_SALES_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_OUTBID_NOTIFICATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_OWNER_BID_NOTIFICATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_REPLICATE_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_WON_NOTIFICATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_BIDDER_ITEMS_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_ITEMS_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_OWNER_ITEMS_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_PENDING_SALES_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_OUTBID_NOTIFICATION, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_OWNER_BID_NOTIFICATION, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_REPLICATE_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_WON_NOTIFICATION, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AURA_POINTS_DEPLETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AURA_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUTH_CHALLENGE, STATUS_NEVER, CONNECTION_TYPE_REALM);
@@ -1318,7 +1318,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_ROLL_WON, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOSS_OF_CONTROL_AURA_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAIL_COMMAND_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAIL_LIST_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAIL_LIST_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAIL_QUERY_NEXT_TIME_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAP_OBJECTIVES_INIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAP_OBJ_EVENTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1573,7 +1573,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_RANGED_COMBAT_TIMER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_WEEKLY_CURRENCY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESPEC_WIPE_CONFIRM, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_CAST_BAR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_COMMS, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_TOKEN, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);