// this function inserts to WorldPacket auction's data bool AuctionEntry::BuildAuctionInfo(WorldPacket & data) const { Item *pItem = sAuctionMgr.GetAItem(itemGuidLow); if (!pItem) { sLog.outError("auction to item, that doesn't exist !!!!"); return false; } data << uint32(Id); data << uint32(pItem->GetEntry()); for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; ++i) { data << uint32(pItem->GetEnchantmentId(EnchantmentSlot(i))); data << uint32(pItem->GetEnchantmentDuration(EnchantmentSlot(i))); data << uint32(pItem->GetEnchantmentCharges(EnchantmentSlot(i))); } data << uint32(pItem->GetItemRandomPropertyId()); // random item property id data << uint32(pItem->GetItemSuffixFactor()); // SuffixFactor data << uint32(pItem->GetCount()); // item->count data << uint32(pItem->GetSpellCharges()); // item->charge FFFFFFF data << uint32(0); // item flags (dynamic?) (0x04 no lockId?) data << ObjectGuid(HIGHGUID_PLAYER, owner); // Auction->owner data << uint32(startbid); // Auction->startbid (not sure if useful) data << uint32(bid ? GetAuctionOutBid() : 0); // minimal outbid data << uint32(buyout); // auction->buyout data << uint32((expireTime-time(NULL))*IN_MILLISECONDS);// time left data << ObjectGuid(HIGHGUID_PLAYER, bidder); // auction->bidder current data << uint32(bid); // current bid return true; }
//this function inserts to WorldPacket auction's data bool WorldSession::SendAuctionInfo(WorldPacket & data, AuctionEntry* auction) { Item *pItem = objmgr.GetAItem(auction->item_guidlow); if (!pItem) { sLog.outError("auction to item, that doesn't exist !!!!"); return false; } data << auction->Id; data << pItem->GetUInt32Value(OBJECT_FIELD_ENTRY); for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; i++) { data << (uint32) pItem->GetEnchantmentId(EnchantmentSlot(i)); data << (uint32) pItem->GetEnchantmentDuration(EnchantmentSlot(i)); data << (uint32) pItem->GetEnchantmentCharges(EnchantmentSlot(i)); } data << (uint32) pItem->GetItemRandomPropertyId(); //random item property id data << (uint32) pItem->GetItemSuffixFactor(); //SuffixFactor data << (uint32) pItem->GetCount(); //item->count data << (uint32) pItem->GetSpellCharges(); //item->charge FFFFFFF data << (uint32) 0; //Unknown data << (uint64) auction->owner; //Auction->owner data << (uint32) auction->startbid; //Auction->startbid (not sure if useful) data << (uint32) ((auction->bid)? objmgr.GetAuctionOutBid(auction->bid) : 0); //minimal outbid data << (uint32) auction->buyout; //auction->buyout data << (uint32) (auction->time - time(NULL)) * 1000; //time left data << (uint64) auction->bidder; //auction->bidder current data << (uint32) auction->bid; //current bid return true; }
//this function inserts to WorldPacket auction's data bool AuctionEntry::BuildAuctionInfo(WorldPacket& data) const { Item* item = sAuctionMgr->GetAItem(item_guidlow); if (!item) { sLog->outError("AuctionEntry::BuildAuctionInfo: Auction %u has a non-existent item: %u", Id, item_guidlow); return false; } data << uint32(Id); data << uint32(item->GetEntry()); for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; ++i) { data << uint32(item->GetEnchantmentId(EnchantmentSlot(i))); data << uint32(item->GetEnchantmentDuration(EnchantmentSlot(i))); data << uint32(item->GetEnchantmentCharges(EnchantmentSlot(i))); } data << int32(item->GetItemRandomPropertyId()); //random item property id data << uint32(item->GetItemSuffixFactor()); //SuffixFactor data << uint32(item->GetCount()); //item->count data << uint32(item->GetSpellCharges()); //item->charge FFFFFFF data << uint32(0); //Unknown data << uint64(owner); //Auction->owner data << uint64(startbid); //Auction->startbid (not sure if useful) data << uint64(bid ? GetAuctionOutBid() : 0); //minimal outbid data << uint64(buyout); //auction->buyout data << uint32((expire_time-time(NULL)) * IN_MILLISECONDS);//time left data << uint64(bidder); //auction->bidder current data << uint64(bid); //current bid return true; }
//this function inserts to WorldPacket auction's data bool AuctionEntry::BuildAuctionInfo(WorldPacket& data) const { Item* item = sAuctionMgr->GetAItem(itemGUIDLow); if (!item) { sLog->outError(LOG_FILTER_GENERAL, "AuctionEntry::BuildAuctionInfo: Auction %u has a non-existent item: %u", Id, itemGUIDLow); return false; } data << uint32(Id); data << uint32(item->GetEntry()); for (uint8 i = 0; i < PROP_ENCHANTMENT_SLOT_0; ++i) // PROP_ENCHANTMENT_SLOT_0 = 8 { data << uint32(item->GetEnchantmentId(EnchantmentSlot(i))); data << uint32(item->GetEnchantmentDuration(EnchantmentSlot(i))); data << uint32(item->GetEnchantmentCharges(EnchantmentSlot(i))); } data << uint32(0); data << int32(item->GetItemRandomPropertyId()); // Random item property id data << uint32(item->GetItemSuffixFactor()); // SuffixFactor data << uint32(item->GetCount()); // item->count data << uint32(item->GetSpellCharges()); // item->charge FFFFFFF data << uint32(0); // Unk data << uint64(MAKE_NEW_GUID(owner, 0, HIGHGUID_PLAYER)); // Auction->owner data << uint64(startbid); // Auction->startbid (not sure if useful) data << uint64(bid ? GetAuctionOutBid() : 0); // Minimal outbid data << uint64(buyout); // Auction->buyout data << uint32((expire_time - time(NULL)) * IN_MILLISECONDS); // time left data << uint64(MAKE_NEW_GUID(bidder, 0, HIGHGUID_PLAYER)); // auction->bidder current data << uint64(bid); // current bid return true; }
//this function inserts to WorldPacket auction's data bool AuctionEntry::BuildAuctionInfo(WorldPacket & data) const { Item *pItem = auctionmgr.GetAItem(item_guidlow); if (!pItem) { sLog.outError("auction to item, that doesn't exist !!!!"); return false; } data << (uint32) Id; data << (uint32) pItem->GetEntry(); for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; i++) { data << (uint32) pItem->GetEnchantmentId(EnchantmentSlot(i)); data << (uint32) pItem->GetEnchantmentDuration(EnchantmentSlot(i)); data << (uint32) pItem->GetEnchantmentCharges(EnchantmentSlot(i)); } data << (uint32) pItem->GetItemRandomPropertyId(); //random item property id data << (uint32) pItem->GetItemSuffixFactor(); //SuffixFactor data << (uint32) pItem->GetCount(); //item->count data << (uint32) pItem->GetSpellCharges(); //item->charge FFFFFFF data << (uint32) 0; //Unknown data << (uint64) owner; //Auction->owner data << (uint32) startbid; //Auction->startbid (not sure if useful) data << (uint32) (bid ? GetAuctionOutBid() : 0); //minimal outbid data << (uint32) buyout; //auction->buyout data << (uint32) (expire_time - time(NULL))* 1000; //time left data << (uint64) bidder; //auction->bidder current data << (uint32) bid; //current bid return true; }
//this function inserts to WorldPacket auction's data bool AuctionEntry::BuildAuctionInfo(WorldPacket& data) const { Item* item = sAuctionMgr->GetAItem(itemGUIDLow); if (!item) { TC_LOG_ERROR("misc", "AuctionEntry::BuildAuctionInfo: Auction %u has a non-existent item: %u", autcionId, itemGUIDLow); return false; } ObjectGuid ownerGUID = MAKE_NEW_GUID(owner, 0, HIGHGUID_PLAYER); ObjectGuid bidderGUID = MAKE_NEW_GUID(bidder, 0, HIGHGUID_PLAYER); ObjectGuid itemGUID = MAKE_NEW_GUID(itemGUIDLow, 0, HIGHGUID_ITEM); ObjectGuid ownerAccountID = 0; // Owner Account ID -- Added in WoD // Write Item Instances data << uint32(item->GetEntry()); data << uint32(item->GetItemSuffixFactor()); data << uint32(item->GetItemRandomPropertyId()); data.FlushBits(); data.WriteBit(0); // HasItemBonus -- Added in WoD data.WriteBit(0); // HasModifications -- Added in WoD data << int32(item->GetCount()); data << int32(item->GetSpellCharges()); data << int32(PROP_ENCHANTMENT_SLOT_0); data << int32(0); // flags -- Added in WoD??? data << int32(autcionId); data << ownerGUID; data << uint64(startbid); data << uint64(bid ? GetAuctionOutBid() : 0); data << uint64(buyout); data << int32((expire_time - time(NULL)) * IN_MILLISECONDS); data << uint8(0); // Delete Reason -- Added in WoD for (uint8 i = 0; i < PROP_ENCHANTMENT_SLOT_0; ++i) { data << int32(item->GetEnchantmentId(EnchantmentSlot(i))); data << uint32(item->GetEnchantmentDuration(EnchantmentSlot(i))); data << int32(item->GetEnchantmentCharges(EnchantmentSlot(i))); data << uint8(0); // Slot } data.FlushBits(); data.WriteBit(1); // ServerSideInfo -- Disable for more check data.WriteBit(0); // BidInfo /* ServerSideInfo Added In WoD data << _itemGUID; data << _ownerAccountID; data << uint32((expire_time) * IN_MILLISECONDS); */ data << bidderGUID; data << int64(bid); return true; }
//called when player lists his received mails void WorldSession::HandleGetMail(WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,8); uint64 mailbox; recv_data >> mailbox; //GameObject* obj = ObjectAccessor::GetGameObject(_player, mailbox); //if(!obj || !obj->IsMailBox()) // return; Player* pl = _player; //load players mails, and mailed items if(!pl->m_mailsLoaded) pl ->_LoadMail(); // client can't work with packets > max int16 value const uint32 maxPacketSize = 32767; uint32 mails_count = 0; // real send to client mails amount WorldPacket data(SMSG_MAIL_LIST_RESULT, (200)); // guess size data << uint8(0); // mail's count time_t cur_time = time(NULL); for(PlayerMails::iterator itr = pl->GetmailBegin(); itr != pl->GetmailEnd(); ++itr) { // skip deleted or not delivered (deliver delay not expired) mails if ((*itr)->state == MAIL_STATE_DELETED || cur_time < (*itr)->deliver_time) continue; uint8 item_count = (*itr)->items.size(); // max count is MAX_MAIL_ITEMS (12) size_t next_mail_size = 2+4+1+8+4*8+((*itr)->subject.size()+1)+1+item_count*(1+4+4+6*3*4+4+4+1+4+4+4); if(data.wpos()+next_mail_size > maxPacketSize) break; data << (uint16) 0x0040; // unknown 2.3.0, different values data << (uint32) (*itr)->messageID; // Message ID data << (uint8) (*itr)->messageType; // Message Type switch((*itr)->messageType) { case MAIL_NORMAL: // sender guid data << uint64(MAKE_NEW_GUID((*itr)->sender, 0, HIGHGUID_PLAYER)); break; case MAIL_CREATURE: case MAIL_GAMEOBJECT: case MAIL_AUCTION: data << (uint32) (*itr)->sender; // creature/gameobject entry, auction id break; case MAIL_ITEM: // item entry (?) sender = "Unknown", NYI break; } data << (uint32) (*itr)->COD; // COD data << (uint32) (*itr)->itemTextId; // sure about this data << (uint32) 0; // unknown data << (uint32) (*itr)->stationery; // stationery (Stationery.dbc) data << (uint32) (*itr)->money; // Gold data << (uint32) 0x04; // unknown, 0x4 - auction, 0x10 - normal // Time data << (float) ((*itr)->expire_time-time(NULL))/DAY; data << (uint32) (*itr)->mailTemplateId; // mail template (MailTemplate.dbc) data << (*itr)->subject; // Subject string - once 00, when mail type = 3 data << (uint8) item_count; for(uint8 i = 0; i < item_count; ++i) { Item *item = pl->GetMItem((*itr)->items[i].item_guid); // item index (0-6?) data << (uint8) i; // item guid low? data << (uint32) (item ? item->GetGUIDLow() : 0); // entry data << (uint32) (item ? item->GetEntry() : 0); for(uint8 j = 0; j < 6; ++j) { // unsure data << (uint32) (item ? item->GetEnchantmentCharges((EnchantmentSlot)j) : 0); // unsure data << (uint32) (item ? item->GetEnchantmentDuration((EnchantmentSlot)j) : 0); // unsure data << (uint32) (item ? item->GetEnchantmentId((EnchantmentSlot)j) : 0); } // can be negative data << (uint32) (item ? item->GetItemRandomPropertyId() : 0); // unk data << (uint32) (item ? item->GetItemSuffixFactor() : 0); // stack count data << (uint8) (item ? item->GetCount() : 0); // charges data << (uint32) (item ? item->GetSpellCharges() : 0); // durability data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0); // durability data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0); } mails_count += 1; } data.put<uint8>(0, mails_count); // set real send mails to client SendPacket(&data); // recalculate m_nextMailDelivereTime and unReadMails _player->UpdateNextMailTimeAndUnreads(); }
//called when player lists his received mails void WorldSession::HandleGetMailList(WorldPacket & recv_data) { uint64 mailbox; recv_data >> mailbox; if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; Player* pl = _player; //load players mails, and mailed items if (!pl->m_mailsLoaded) pl ->_LoadMail(); // client can't work with packets > max int16 value const uint32 maxPacketSize = 32767; uint32 mailsCount = 0; // real send to client mails amount uint32 realCount = 0; // real mails amount WorldPacket data(SMSG_MAIL_LIST_RESULT, (200)); data << uint32(0); // real mail's count data << uint8(0); // mail's count time_t cur_time = time(NULL); for (PlayerMails::iterator itr = pl->GetMailBegin(); itr != pl->GetMailEnd(); ++itr) { // packet send mail count as uint8, prevent overflow if (mailsCount >= 254) { realCount += 1; continue; } // skip deleted or not delivered (deliver delay not expired) mails if ((*itr)->state == MAIL_STATE_DELETED || cur_time < (*itr)->deliver_time) continue; uint8 item_count = (*itr)->items.size(); // max count is MAX_MAIL_ITEMS (12) size_t next_mail_size = 2+4+1+((*itr)->messageType == MAIL_NORMAL ? 8 : 4)+4*8+((*itr)->subject.size()+1)+((*itr)->body.size()+1)+1+item_count*(1+4+4+7*3*4+4+4+4+4+4+4+1); if (data.wpos()+next_mail_size > maxPacketSize) { realCount += 1; continue; } data << uint16(next_mail_size); // Message size data << uint32((*itr)->messageID); // Message ID data << uint8((*itr)->messageType); // Message Type switch((*itr)->messageType) { case MAIL_NORMAL: // sender guid data << uint64(MAKE_NEW_GUID((*itr)->sender, 0, HIGHGUID_PLAYER)); break; case MAIL_CREATURE: case MAIL_GAMEOBJECT: case MAIL_AUCTION: data << uint32((*itr)->sender); // creature/gameobject entry, auction id break; case MAIL_ITEM: // item entry (?) sender = "Unknown", NYI data << uint32(0); // item entry break; } data << uint64((*itr)->COD); // COD data << uint32(0); // probably changed in 3.3.3 data << uint32((*itr)->stationery); // stationery (Stationery.dbc) data << uint64((*itr)->money); // Gold data << uint32((*itr)->checked); // flags data << float(((*itr)->expire_time-time(NULL))/DAY); // Time data << uint32((*itr)->mailTemplateId); // mail template (MailTemplate.dbc) data << (*itr)->subject; // Subject string - once 00, when mail type = 3, max 256 data << (*itr)->body; // message? max 8000 data << uint8(item_count); // client limit is 0x10 for (uint8 i = 0; i < item_count; ++i) { Item *item = pl->GetMItem((*itr)->items[i].item_guid); // item index (0-6?) data << uint8(i); // item guid low? data << uint32((item ? item->GetGUIDLow() : 0)); // entry data << uint32((item ? item->GetEntry() : 0)); for (uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j) { data << uint32((item ? item->GetEnchantmentId((EnchantmentSlot)j) : 0)); data << uint32((item ? item->GetEnchantmentDuration((EnchantmentSlot)j) : 0)); data << uint32((item ? item->GetEnchantmentCharges((EnchantmentSlot)j) : 0)); } for (uint8 j = 0; j < 2; ++j) { data << uint32(0); data << uint32(0); data << uint32(0); } // can be negative data << int32((item ? item->GetItemRandomPropertyId() : 0)); // unk data << uint32((item ? item->GetItemSuffixFactor() : 0)); // stack count data << uint32((item ? item->GetCount() : 0)); // charges data << uint32((item ? item->GetSpellCharges() : 0)); // durability data << uint32((item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0)); // durability data << uint32((item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0)); // unknown wotlk data << uint8(0); } realCount += 1; mailsCount += 1; } data.put<uint32>(0, realCount); // this will display warning about undelivered mail to player if realCount > mailsCount data.put<uint8>(4, mailsCount); // set real send mails to client SendPacket(&data); // recalculate m_nextMailDelivereTime and unReadMails _player->UpdateNextMailTimeAndUnreads(); }
//called when player lists his received mails void WorldSession::HandleGetMailList(WorldPacket& recvData) { ObjectGuid mailbox; recvData >> mailbox; if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; Player* player = _player; //load players mails, and mailed items if (!player->m_mailsLoaded) player->_LoadMail(); // client can't work with packets > max int16 value const uint32 maxPacketSize = 32767; uint32 mailCount = 0; uint32 realCount = 0; // true mail count (includes any skipped mail) time_t cur_time = time(NULL); ByteBuffer mailData; WorldPacket data(SMSG_MAIL_LIST_RESULT, 200); // guess size data << uint32(0); // placeholder size_t mailCountPos = data.bitwpos(); data.WriteBits(0, 18); // placeholder for (PlayerMails::iterator itr = player->GetMailBegin(); itr != player->GetMailEnd(); ++itr) { Mail* mail = *itr; // Only first 50 mails are displayed if (mailCount >= 50) { realCount += 1; continue; } // skip deleted or not delivered (deliver delay not expired) mails if (mail->state == MAIL_STATE_DELETED || cur_time < mail->deliver_time) continue; // skip mail with more than MAX_MAIL_ITEMS items (should not occur) uint8 itemCount = mail->items.size(); if (itemCount > MAX_MAIL_ITEMS) { realCount += 1; continue; } // skip mail if the packet has become too large (should not occur) size_t nextMailSize = 6 + 1 + 8 + itemCount * (4 + 4 + 4 + 4 + 4 + MAX_INSPECTED_ENCHANTMENT_SLOT * (4 + 4 + 4) + 4 + 4 + 4 + 4 + 1 + 4) + mail->body.size() + mail->subject.size() + 4 + 4 + 8 + 4 + 8 + 4 + 4 + 1 + 4; if (data.wpos() + nextMailSize > maxPacketSize) { realCount += 1; continue; } data.WriteBit(mail->messageType != MAIL_NORMAL ? 1 : 0); data.WriteBits(mail->subject.size(), 8); data.WriteBits(mail->body.size(), 13); data.WriteBit(0); data.WriteBit(0); size_t itemCountPos = data.bitwpos(); data.WriteBits(0, 17); // placeholder data.WriteBit(1); // has guid ObjectGuid guid = mail->messageType == MAIL_NORMAL ? MAKE_NEW_GUID(mail->sender, 0, HIGHGUID_PLAYER) : 0; data << guid; uint8 trueItemCount = 0; for (uint8 i = 0; i < itemCount; i++) { Item* item = player->GetMItem(mail->items[i].item_guid); if (!item) continue; data.WriteBit(0); mailData << uint32(item->GetGUIDLow()); mailData << uint32(4); // unknown mailData << uint32(item->GetSpellCharges()); mailData << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY)); mailData << uint32(0); // unknown for (uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; j++) { mailData << uint32(item->GetEnchantmentCharges((EnchantmentSlot)j)); mailData << uint32(item->GetEnchantmentDuration((EnchantmentSlot)j)); mailData << uint32(item->GetEnchantmentId((EnchantmentSlot)j)); } mailData << uint32(item->GetItemSuffixFactor()); mailData << int32(item->GetItemRandomPropertyId()); mailData << uint32(item->GetUInt32Value(ITEM_FIELD_MAX_DURABILITY)); mailData << uint32(item->GetCount()); mailData << uint8(i); mailData << uint32(item->GetEntry()); trueItemCount++; } data.PutBits(itemCountPos, trueItemCount, 17); mailData.WriteString(mail->body); mailData << uint32(mail->messageID); mailData << guid; mailData << uint32(mail->mailTemplateId); mailData << uint64(mail->COD); mailData.WriteString(mail->subject); mailData << uint32(mail->stationery); mailData << float(float(mail->expire_time - time(NULL)) / DAY); mailData << uint64(mail->money); mailData << uint32(mail->checked); if (mail->messageType != MAIL_NORMAL) mailData << uint32(mail->sender); mailData << uint8(mail->messageType); mailData << uint32(0); // unknown realCount++; mailCount++; } data.FlushBits(); data.append(mailData); data.put<uint32>(0, realCount); data.PutBits(mailCountPos, mailCount, 18); SendPacket(&data); // recalculate m_nextMailDelivereTime and unReadMails _player->UpdateNextMailTimeAndUnreads(); }
/** * Handles the packet sent by the client when requesting the current mail list. * It will send a list of all available mails in the players mailbox to the client. */ void WorldSession::HandleGetMailList(WorldPacket& recv_data) { ObjectGuid mailboxGuid; recv_data >> mailboxGuid; if (!CheckMailBox(mailboxGuid)) return; // client can't work with packets > max int16 value const uint32 maxPacketSize = 32767; uint32 mailsCount = 0; // send to client mails amount WorldPacket data(SMSG_MAIL_LIST_RESULT, (200)); // guess size data << uint8(0); // mail's count time_t cur_time = time(nullptr); for (PlayerMails::iterator itr = _player->GetMailBegin(); itr != _player->GetMailEnd(); ++itr) { // packet send mail count as uint8, prevent overflow if (mailsCount >= 254) break; // skip deleted or not delivered (deliver delay not expired) mails if ((*itr)->state == MAIL_STATE_DELETED || cur_time < (*itr)->deliver_time) continue; uint8 item_count = (*itr)->items.size(); // max count is MAX_MAIL_ITEMS (12) size_t next_mail_size = 2 + 4 + 1 + 8 + 4 * 8 + ((*itr)->subject.size() + 1) + 1 + item_count * (1 + 4 + 4 + 6 * 3 * 4 + 4 + 4 + 1 + 4 + 4 + 4); if (data.wpos() + next_mail_size > maxPacketSize) break; data << uint16(next_mail_size); // Message size data << uint32((*itr)->messageID); // Message ID data << uint8((*itr)->messageType); // Message Type switch ((*itr)->messageType) { case MAIL_NORMAL: // sender guid data << ObjectGuid(HIGHGUID_PLAYER, (*itr)->sender); break; case MAIL_CREATURE: case MAIL_GAMEOBJECT: case MAIL_AUCTION: data << uint32((*itr)->sender); // creature/gameobject entry, auction id break; case MAIL_ITEM: // item entry (?) sender = "Unknown", NYI data << uint32(0); // item entry break; } data << uint32((*itr)->COD); // COD data << uint32((*itr)->itemTextId); // item text data << uint32(0); // unknown data << uint32((*itr)->stationery); // stationery (Stationery.dbc) data << uint32((*itr)->money); // copper data << uint32((*itr)->checked); // flags data << float(float((*itr)->expire_time - time(nullptr)) / float(DAY));// Time data << uint32((*itr)->mailTemplateId); // mail template (MailTemplate.dbc) data << (*itr)->subject; // Subject string - once 00, when mail type = 3, max 256 data << (uint8)item_count; for (uint8 i = 0; i < item_count; ++i) { Item* item = _player->GetMItem((*itr)->items[i].item_guid); // item index (0-6?) data << uint8(i); // item guid low? data << uint32(item ? item->GetGUIDLow() : 0); // entry data << uint32(item ? item->GetEntry() : 0); for (uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j) { // unsure data << uint32(item ? item->GetEnchantmentCharges((EnchantmentSlot)j) : 0); // unsure data << uint32(item ? item->GetEnchantmentDuration((EnchantmentSlot)j) : 0); // unsure data << uint32(item ? item->GetEnchantmentId((EnchantmentSlot)j) : 0); } // can be negative data << uint32(item ? item->GetItemRandomPropertyId() : 0); // unk data << uint32(item ? item->GetItemSuffixFactor() : 0); // stack count data << (uint8)(item ? item->GetCount() : 0); // charges data << uint32(item ? item->GetSpellCharges() : 0); // durability data << uint32(item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0); // durability data << uint32(item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0); } mailsCount += 1; } data.put<uint8>(0, mailsCount); // set real send mails to client SendPacket(data); // recalculate m_nextMailDelivereTime and unReadMails _player->UpdateNextMailTimeAndUnreads(); }
WorldPacket* Mailbox::BuildMailboxListingPacket() { WorldPacket* data = new WorldPacket(SMSG_MAIL_LIST_RESULT, 200); MessageMap::iterator itr; uint8 i = 0; uint32 realCount = 0; uint32 mailsCount = 0; uint32 t = (uint32)UNIXTIME; *data << uint32(0); // real mail's count *data << uint8(0); // mail's count for (itr = Messages.begin(); itr != Messages.end(); ++itr) { if (itr->second.expire_time && t > itr->second.expire_time) continue; // expired mail -> skip it if ((uint32)UNIXTIME < itr->second.delivery_time) continue; // undelivered if (mailsCount >= 50) //VLack: We could calculate message sizes instead of this, but the original code did a break at 50, so I won't fix this up if no one felt the need to do so before ;-) { realCount += 1; continue; } uint8 item_count = itr->second.items.size(); // max count is MAX_MAIL_ITEMS (12) size_t next_mail_size = 2 + 4 + 1 + (itr->second.message_type == NORMAL ? 8 : 4) + 4 * 8 + (itr->second.subject.size() + 1) + (itr->second.body.size() + 1) + 1 + item_count*(1 + 4 + 4 + MAX_INSPECTED_ENCHANTMENT_SLOT * 3 * 4 + 4 + 4 + 4 + 4 + 4 + 4 + 1); *data << uint16(next_mail_size); // Message size *data << uint32(itr->second.message_id); // Message ID *data << uint8(itr->second.message_type); // Message Type switch (itr->second.message_type) { case NORMAL: *data << uint64((itr->second.sender_guid)); break; case COD: case AUCTION: case ITEM: *data << uint32(Arcemu::Util::GUID_LOPART((itr->second.sender_guid))); break; case GAMEOBJECT: case CREATURE: *data << uint32(static_cast<uint32>((itr->second.sender_guid))); break; } *data << uint64(itr->second.cod); // COD *data << uint32(0); // Package.dbc ID ? *data << uint32(itr->second.stationery); // stationery (Stationery.dbc) *data << uint64(itr->second.money); // Gold *data << uint32(itr->second.checked_flag); // flags *data << float(float((itr->second.expire_time - uint32(UNIXTIME)) / DAY)); // Time *data << uint32(itr->second.message_id); // mail template (MailTemplate.dbc) *data << itr->second.subject; // Subject string - once 00, when mail type = 3, max 256 *data << itr->second.body; // message? max 8000 *data << uint8(item_count); // client limit is 0x10 Item* pItem; std::vector<uint32>::iterator itr2; for (uint8 i = 0; i < item_count; ++i) { pItem = objmgr.LoadItem(itr->second.items[i]); // item index (0-6?) *data << uint8(i); // item guid low? *data << uint32((pItem ? pItem->GetLowGUID() : 0)); // entry *data << uint32((pItem ? pItem->GetEntry() : 0)); for (uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j) { *data << uint32((pItem ? pItem->GetEnchantmentId((EnchantmentSlot)j) : 0)); *data << uint32((pItem ? pItem->GetEnchantmentDuration((EnchantmentSlot)j) : 0)); *data << uint32((pItem ? pItem->GetEnchantmentCharges((EnchantmentSlot)j) : 0)); } // can be negative *data << int32((pItem ? pItem->GetItemRandomPropertyId() : 0)); // unk *data << uint32((pItem ? pItem->GetItemRandomSuffixFactor() : 0)); // stack count *data << uint32((pItem ? pItem->GetStackCount() : 0)); // charges *data << uint32((pItem ? pItem->GetChargesLeft() : 0)); // durability *data << uint32((pItem ? pItem->GetDurabilityMax() : 0)); // durability *data << uint32((pItem ? pItem->GetDurability() : 0)); // unknown wotlk *data << uint8(0); } ++realCount; ++mailsCount; } data->put<uint32>(0, realCount); // this will display warning about undelivered mail to player if realCount > mailsCount data->put<uint8>(4, mailsCount); // set real send mails to client // do cleanup on request mail CleanupExpiredMessages(); return data; }
//this function inserts to WorldPacket auction's data void AuctionEntry::BuildAuctionInfo(std::vector<WorldPackets::AuctionHouse::AuctionItem>& items, bool listAuctionItems) const { Item* item = sAuctionMgr->GetAItem(itemGUIDLow); if (!item) { TC_LOG_ERROR("misc", "AuctionEntry::BuildAuctionInfo: Auction %u has a non-existent item: " UI64FMTD, Id, itemGUIDLow); return; } WorldPackets::AuctionHouse::AuctionItem auctionItem; auctionItem.AuctionItemID = Id; auctionItem.Item.Initialize(item); auctionItem.BuyoutPrice = buyout; auctionItem.CensorBidInfo = false; auctionItem.CensorServerSideInfo = listAuctionItems; auctionItem.Charges = item->GetSpellCharges(); auctionItem.Count = item->GetCount(); auctionItem.DeleteReason = 0; // Always 0 ? auctionItem.DurationLeft = (expire_time - time(NULL)) * IN_MILLISECONDS; auctionItem.EndTime = expire_time; auctionItem.Flags = 0; // todo auctionItem.ItemGuid = item->GetGUID(); auctionItem.MinBid = startbid; auctionItem.Owner = ObjectGuid::Create<HighGuid::Player>(owner); auctionItem.OwnerAccountID = ObjectGuid::Create<HighGuid::WowAccount>(ObjectMgr::GetPlayerAccountIdByGUID(auctionItem.Owner)); auctionItem.MinIncrement = bidder ? GetAuctionOutBid() : 0; auctionItem.Bidder = bidder ? ObjectGuid::Create<HighGuid::Player>(bidder) : ObjectGuid::Empty; auctionItem.BidAmount = bidder ? bid : 0; for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; i++) { if (!item->GetEnchantmentId((EnchantmentSlot) i)) continue; auctionItem.Enchantments.emplace_back(item->GetEnchantmentId((EnchantmentSlot) i), item->GetEnchantmentDuration((EnchantmentSlot) i), item->GetEnchantmentCharges((EnchantmentSlot) i), i); } items.emplace_back(auctionItem); }