WorldPacket* Mailbox::BuildMailboxListingPacket() { WorldPacket* data = new WorldPacket(SMSG_MAIL_LIST_RESULT, 200); uint32_t realCount = 0; uint8_t mailsCount = 0; uint32_t t = (uint32_t)UNIXTIME; *data << uint32_t(0); // real mail's count *data << uint8_t(0); // mail's count for (MessageMap::iterator itr = Messages.begin(); itr != Messages.end(); ++itr) { if (itr->second.expire_time && t > itr->second.expire_time) continue; // expired mail -> skip it if ((uint32_t)UNIXTIME < itr->second.delivery_time) continue; // undelivered if (mailsCount >= 50) { realCount += 1; continue; } uint8_t item_count = static_cast<uint8_t>(itr->second.items.size()); size_t next_mail_size = 2 + 4 + 1 + (itr->second.message_type == MAIL_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_t(next_mail_size); // Message size *data << uint32_t(itr->second.message_id); // Message ID *data << uint8_t(itr->second.message_type); // Message Type switch (itr->second.message_type) { case MAIL_TYPE_NORMAL: *data << uint64_t((itr->second.sender_guid)); break; case MAIL_TYPE_COD: case MAIL_TYPE_AUCTION: case MAIL_TYPE_ITEM: *data << uint32_t(Arcemu::Util::GUID_LOPART((itr->second.sender_guid))); break; case MAIL_TYPE_GAMEOBJECT: case MAIL_TYPE_CREATURE: *data << uint32_t(static_cast<uint32_t>((itr->second.sender_guid))); break; } *data << uint64_t(itr->second.cod); *data << uint32_t(0); // Package.dbc ID ? *data << uint32_t(itr->second.stationery); // stationery (Stationery.dbc) *data << uint64_t(itr->second.money); *data << uint32_t(itr->second.checked_flag); *data << float(float((itr->second.expire_time - uint32_t(UNIXTIME)) / DAY)); *data << uint32_t(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_t(item_count); // client limit is 0x10 std::vector<uint32_t>::iterator itr2; for (uint8_t i = 0; i < item_count; ++i) { Item * pItem = objmgr.LoadItem(itr->second.items[i]); *data << uint8_t(i); // item index (0-6) *data << uint32_t((pItem ? pItem->getGuidLow() : 0)); *data << uint32_t((pItem ? pItem->getEntry() : 0)); for (uint8_t j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j) { *data << uint32_t((pItem ? pItem->getEnchantmentId((EnchantmentSlot)j) : 0)); *data << uint32_t((pItem ? pItem->getEnchantmentDuration((EnchantmentSlot)j) : 0)); *data << uint32_t((pItem ? pItem->getEnchantmentCharges((EnchantmentSlot)j) : 0)); } *data << int32_t((pItem ? pItem->getRandomPropertiesId() : 0)); // can be negative *data << uint32_t((pItem ? pItem->getPropertySeed() : 0)); *data << uint32_t((pItem ? pItem->getStackCount() : 0)); *data << uint32_t((pItem ? pItem->GetChargesLeft() : 0)); *data << uint32_t((pItem ? pItem->getMaxDurability() : 0)); *data << uint32_t((pItem ? pItem->getDurability() : 0)); *data << uint8_t(0); } ++realCount; ++mailsCount; } data->put<uint32_t>(0, realCount); // this will display warning about undelivered mail to player if realCount > mailsCount data->put<uint8_t>(4, mailsCount); // set real send mails to client // do cleanup on request mail CleanupExpiredMessages(); return data; }
/// \todo refactoring bool MailMessage::AddMessageDataToPacket(WorldPacket& data) { uint8 i = 0; uint32 j; std::vector<uint32>::iterator itr; Item* pItem; // add stuff if (deleted_flag) return false; uint8 guidsize; if (message_type == 0) guidsize = 8; else guidsize = 4; size_t msize = 2 + 4 + 1 + guidsize + 7 * 4 + (subject.size() + 1) + (body.size() + 1) + 1 + (items.size() * (1 + 2 * 4 + 7 * (3 * 4) + 6 * 4 + 1)); data << uint16(msize); // message size data << uint32(message_id); data << uint8(message_type); switch (message_type) { case NORMAL: data << uint64(sender_guid); break; case COD: case AUCTION: case GAMEOBJECT: case ITEM: data << uint32(Arcemu::Util::GUID_LOPART(sender_guid)); break; case CREATURE: data << uint32(Arcemu::Util::GET_CREATURE_ENTRY_FROM_GUID(sender_guid)); break; } data << uint32(cod); // cod data << uint32(0); data << uint32(stationery); data << uint32(money); // money data << uint32(checked_flag); // "checked" flag data << float((expire_time - uint32(UNIXTIME)) / 86400.0f); data << uint32(0); // mail template data << subject; data << body; data << uint8(items.size()); // item count if (!items.empty()) { for (itr = items.begin(); itr != items.end(); ++itr) { pItem = objmgr.LoadItem(*itr); if (pItem == NULL) continue; data << uint8(i++); data << uint32(pItem->GetLowGUID()); data << uint32(pItem->GetEntry()); for (j = 0; j < 7; ++j) { data << uint32(pItem->GetEnchantmentId(j)); data << uint32(pItem->GetEnchantmentDuration(j)); data << uint32(0); } data << uint32(pItem->GetItemRandomPropertyId()); data << uint32(pItem->GetItemRandomSuffixFactor()); data << uint32(pItem->GetStackCount()); data << uint32(pItem->GetChargesLeft()); data << uint32(pItem->GetDurabilityMax()); data << uint32(pItem->GetDurability()); data << uint8(0); // unknown delete pItem; } } return true; }
bool MailMessage::AddMessageDataToPacket(WorldPacket& data) { uint8 i = 0; uint32 j; size_t pos; vector<uint64>::iterator itr; Item * pItem; // add stuff if(deleted_flag) return false; data << uint16(0x0032); data << message_id; data << uint8(message_type); if(message_type) data << uint32(sender_guid); else data << sender_guid; data << cod; // cod data << message_id; // itempageid data << uint32(0); data << stationary; data << money; // money data << uint32(0x10); data << float(float(expire_time - (uint32)UNIXTIME) / 86400.0f); data << uint32(0); data << subject; pos = data.wpos(); data << uint8(items.empty() ? 0 : items.size()); // item count if( !items.empty( ) ) { for( itr = items.begin( ); itr != items.end( ); ++itr ) { pItem = objmgr.LoadItem( *itr ); if( pItem == NULL ) continue; data << uint8(i++); data << pItem->GetUInt32Value(OBJECT_FIELD_GUID); data << pItem->GetEntry(); for( j = 0; j < 6; ++j ) { data << pItem->GetUInt32Value( ITEM_FIELD_ENCHANTMENT + ( j * 3 ) ); data << pItem->GetUInt32Value( ITEM_FIELD_ENCHANTMENT_01 + ( j * 3 ) ); data << pItem->GetUInt32Value( ITEM_FIELD_ENCHANTMENT_02 + ( j * 3 ) ); } data << pItem->GetUInt32Value( ITEM_FIELD_RANDOM_PROPERTIES_ID ); if( ( (int32)pItem->GetUInt32Value( ITEM_FIELD_RANDOM_PROPERTIES_ID ) ) < 0 ) data << pItem->GetItemRandomSuffixFactor(); else data << uint32( 0 ); data << uint8( pItem->GetUInt32Value(ITEM_FIELD_STACK_COUNT) ); data << uint32( pItem->GetChargesLeft() ); data << pItem->GetUInt32Value( ITEM_FIELD_MAXDURABILITY ); data << pItem->GetUInt32Value( ITEM_FIELD_DURABILITY ); } data.put< uint8 >( pos, i ); } return true; /* data << uint16(0); data << message_id; data << uint8(message_type); if(message_type) data << uint32(sender_guid); else data << sender_guid; data << subject; data << message_id; // itempageid data << message_id; data << stationary; uint32 itementry = 0, itemcount = 0; uint32 charges = 0, durability = 0, maxdurability = 0; if(attached_item_guid) { QueryResult * result = CharacterDatabase.Query("SELECT `entry`, `count`, `charges`, `durability` FROM playeritems WHERE guid='%u'", GUID_LOPART(attached_item_guid)); if(result) { itementry = result->Fetch()[0].GetUInt32(); itemcount = result->Fetch()[1].GetUInt32(); charges = result->Fetch()[2].GetUInt32(); durability = result->Fetch()[3].GetUInt32(); ItemPrototype * it = ItemPrototypeStorage.LookupEntry(itementry); maxdurability = it ? it->MaxDurability : durability; delete result; } } if(external_attached_item_guid) { QueryResult * result = CharacterDatabase.Query("SELECT `entry`, `count`, `charges`, `durability` FROM playeritems_external WHERE guid='%u'", GUID_LOPART(external_attached_item_guid)); if(result) { itementry = result->Fetch()[0].GetUInt32(); itemcount = result->Fetch()[1].GetUInt32(); charges = result->Fetch()[2].GetUInt32(); durability = result->Fetch()[3].GetUInt32(); ItemPrototype * it = ItemPrototypeStorage.LookupEntry(itementry); maxdurability = it ? it->MaxDurability : durability; delete result; } } data << itementry; data << uint32(0); // unk data << uint32(0); // unk data << uint32(0); // unk for(uint32 i = 0; i < 17; ++i) data << uint32(0); data << (itemcount ? uint8(itemcount) : uint8(1)); data << charges; data << maxdurability; data << durability; data << money; data << cod; data << uint32(read_flag); if(expire_time) data << float(float(expire_time - (uint32)UNIXTIME) / 86400.0f); else data << float(0); data << uint32(0); return true;*/ }
bool Mailbox::AddMessageToListingPacket(WorldPacket& data,MailMessage *msg) { uint8 i = 0; uint32 j; size_t pos; vector<uint64>::iterator itr; Item* pItem; // add stuff if(msg->deleted_flag || msg->Expired() || (uint32)UNIXTIME < msg->delivery_time) return false; data << uint16(0x0032); data << msg->message_id; data << uint8(msg->message_type); if(msg->message_type) data << uint32(msg->sender_guid); else data << msg->sender_guid; data << msg->cod; data << uint32(0); data << msg->stationary; data << msg->money; // money data << uint32(0); data << uint32(0x10); data << uint32((msg->expire_time - uint32(UNIXTIME)) / 86400.0f); data << msg->subject; data << msg->body; // subjectbody pos = data.wpos(); data << uint8(0); // item count if( !msg->items.empty( ) ) { for( itr = msg->items.begin( ); itr != msg->items.end( ); ++itr ) { pItem = objmgr.LoadItem( *itr ); if( pItem == NULL ) continue; data << uint8(i++); data << pItem->GetUInt32Value(OBJECT_FIELD_GUID); data << pItem->GetEntry(); for( j = 0; j < 7; ++j ) { data << pItem->GetUInt32Value( ITEM_FIELD_ENCHANTMENT_1_1 + ( j * 3 ) ); data << pItem->GetUInt32Value( (ITEM_FIELD_ENCHANTMENT_1_1 + 1) + ( j * 3 ) ); data << pItem->GetUInt32Value( ITEM_FIELD_ENCHANTMENT_1_3 + ( j * 3 ) ); } data << pItem->GetUInt32Value( ITEM_FIELD_RANDOM_PROPERTIES_ID ); if( ( (int32)pItem->GetUInt32Value( ITEM_FIELD_RANDOM_PROPERTIES_ID ) ) < 0 ) data << pItem->GetItemRandomSuffixFactor(); else data << uint32( 0 ); data << uint8( pItem->GetUInt32Value(ITEM_FIELD_STACK_COUNT) ); data << uint32( pItem->GetChargesLeft() ); data << pItem->GetUInt32Value( ITEM_FIELD_MAXDURABILITY ); data << pItem->GetUInt32Value( ITEM_FIELD_DURABILITY ); data << uint32(0); delete pItem; } data.put< uint8 >( pos, i ); } return true; }
/// \todo refactoring bool MailMessage::AddMessageDataToPacket(WorldPacket& data) { uint8 i = 0; std::vector<uint32>::iterator itr; Item* pItem; // add stuff if (deleted_flag) return false; uint8 guidsize; if (message_type == 0) guidsize = 8; else guidsize = 4; size_t msize = 2 + 4 + 1 + guidsize + 4 * 8 + (subject.size() + 1) + (body.size() + 1) + 1 + (items.size() * (1 + 2 * 4 + 7 * (3 * 4) + 6 * 4 + 1)); data << uint16(msize); // message size data << uint32(message_id); data << uint8(message_type); switch (message_type) { case MAIL_TYPE_NORMAL: data << uint64(sender_guid); break; case MAIL_TYPE_COD: case MAIL_TYPE_AUCTION: case MAIL_TYPE_ITEM: data << uint32(Arcemu::Util::GUID_LOPART(sender_guid)); break; case MAIL_TYPE_GAMEOBJECT: case MAIL_TYPE_CREATURE: data << uint32(static_cast<uint32>(sender_guid)); break; } data << uint32(cod); // cod data << uint32(0); data << uint32(stationery); data << uint32(money); // money data << uint32(checked_flag); // "checked" flag data << float((expire_time - uint32(UNIXTIME)) / 86400.0f); data << uint32(0); // mail template data << subject; data << body; data << uint8(items.size()); // item count if (!items.empty()) { for (itr = items.begin(); itr != items.end(); ++itr) { pItem = objmgr.LoadItem(*itr); if (pItem == nullptr) continue; data << uint8(i++); data << uint32(pItem->getGuidLow()); data << uint32(pItem->getEntry()); for (uint8_t j = 0; j < MAX_ENCHANTMENT_SLOT; ++j) { data << uint32(pItem->getEnchantmentId(j)); data << uint32(pItem->getEnchantmentDuration(j)); data << uint32(0); } data << uint32(pItem->getRandomPropertiesId()); data << uint32(pItem->getPropertySeed()); data << uint32(pItem->getStackCount()); data << uint32(pItem->GetChargesLeft()); data << uint32(pItem->getMaxDurability()); data << uint32(pItem->getDurability()); data << uint8(0); // unknown delete pItem; } } return true; }
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; }