diff --git a/sql/333/2_mail.sql b/sql/333/2_mail.sql new file mode 100644 index 000000000..54b4ea92f --- /dev/null +++ b/sql/333/2_mail.sql @@ -0,0 +1,3 @@ +alter table `characters`.`mail` drop column `itemTextId`; + +--- UPDATE `mail` SET `body`=(SELECT `text` FROM `item_text` WHERE `id`=`mail`.`itemtextid`) --- well i'm not good in SQL... diff --git a/src/game/AuctionHouseHandler.cpp b/src/game/AuctionHouseHandler.cpp index 8c2e4f8a2..d68f1789f 100644 --- a/src/game/AuctionHouseHandler.cpp +++ b/src/game/AuctionHouseHandler.cpp @@ -29,13 +29,13 @@ #include "Mail.h" #include "Util.h" -//please DO NOT use iterator++, because it is slower than ++iterator!!! -//post-incrementation is always slower than pre-incrementation ! +// please DO NOT use iterator++, because it is slower than ++iterator!!! +// post-incrementation is always slower than pre-incrementation ! -//void called when player click on auctioneer npc +// void called when player click on auctioneer npc void WorldSession::HandleAuctionHelloOpcode( WorldPacket & recv_data ) { - uint64 guid; //NPC guid + uint64 guid; // NPC guid recv_data >> guid; Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER); @@ -52,7 +52,7 @@ void WorldSession::HandleAuctionHelloOpcode( WorldPacket & recv_data ) SendAuctionHello(guid, unit); } -//this void causes that auction window is opened +// this void causes that auction window is opened void WorldSession::SendAuctionHello( uint64 guid, Creature* unit ) { AuctionHouseEntry const* ahEntry = AuctionHouseMgr::GetAuctionHouseEntry(unit->getFaction()); @@ -66,19 +66,19 @@ void WorldSession::SendAuctionHello( uint64 guid, Creature* unit ) SendPacket( &data ); } -//call this method when player bids, creates, or deletes auction +// call this method when player bids, creates, or deletes auction void WorldSession::SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError ) { WorldPacket data( SMSG_AUCTION_COMMAND_RESULT, 16 ); - data << auctionId; - data << Action; - data << ErrorCode; + data << uint32(auctionId); + data << uint32(Action); + data << uint32(ErrorCode); if ( !ErrorCode && Action ) - data << bidError; // when bid, then send 0, once... + data << uint32(bidError); // when bid, then send 0, once... SendPacket(&data); } -//this function sends notification, if bidder is online +// this function sends notification, if bidder is online void WorldSession::SendAuctionBidderNotification( uint32 location, uint32 auctionId, uint64 bidder, uint32 bidSum, uint32 diff, uint32 item_template) { WorldPacket data(SMSG_AUCTION_BIDDER_NOTIFICATION, (8*4)); @@ -92,21 +92,21 @@ void WorldSession::SendAuctionBidderNotification( uint32 location, uint32 auctio SendPacket(&data); } -//this void causes on client to display: "Your auction sold" +// this void causes on client to display: "Your auction sold" void WorldSession::SendAuctionOwnerNotification( AuctionEntry* auction) { WorldPacket data(SMSG_AUCTION_OWNER_NOTIFICATION, (7*4)); - data << auction->Id; - data << auction->bid; - data << (uint32) 0; //unk - data << (uint32) 0; //unk - data << (uint32) 0; //unk - data << auction->item_template; - data << (uint32) 0; //unk + data << uint32(auction->Id); + data << uint32(auction->bid); + data << uint32(0); // unk + data << uint32(0); // unk + data << uint32(0); // unk + data << uint32(auction->item_template); + data << uint32(0); // unk SendPacket(&data); } -//this function sends mail to old bidder +// this function sends mail to old bidder void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPrice) { uint64 oldBidder_guid = MAKE_NEW_GUID(auction->bidder,0, HIGHGUID_PLAYER); @@ -125,13 +125,13 @@ void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPri if (oldBidder) oldBidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), auction->Id, _player->GetGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template); - MailDraft(msgAuctionOutbiddedSubject.str(), "", 0) + MailDraft(msgAuctionOutbiddedSubject.str(), "") // TODO: fix body .AddMoney(auction->bid) .SendMailTo(MailReceiver(oldBidder, auction->bidder), auction); } } -//this function sends mail, when auction is cancelled to old bidder +// this function sends mail, when auction is cancelled to old bidder void WorldSession::SendAuctionCancelledToBidderMail( AuctionEntry* auction ) { uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER); @@ -147,13 +147,13 @@ void WorldSession::SendAuctionCancelledToBidderMail( AuctionEntry* auction ) std::ostringstream msgAuctionCancelledSubject; msgAuctionCancelledSubject << auction->item_template << ":0:" << AUCTION_CANCELLED_TO_BIDDER << ":0:0"; - MailDraft(msgAuctionCancelledSubject.str(), "", 0) + MailDraft(msgAuctionCancelledSubject.str(), "") // TODO: fix body .AddMoney(auction->bid) .SendMailTo(MailReceiver(bidder, auction->bidder), auction); } } -//this void creates new auction and adds auction to some auctionhouse +// this void creates new auction and adds auction to some auctionhouse void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) { uint64 auctioneer, item; @@ -169,9 +169,9 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) Player *pl = GetPlayer(); if (!item || !bid || !etime) - return; //check for cheaters + return; // check for cheaters - Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER); + Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug( "WORLD: HandleAuctionSellItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)) ); @@ -243,7 +243,7 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) if( GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE) ) { sLog.outCommand(GetAccountId(),"GM %s (Account: %u) create auction: %s (Entry: %u Count: %u)", - GetPlayerName(),GetAccountId(),it->GetProto()->Name1,it->GetEntry(),it->GetCount()); + GetPlayerName(), GetAccountId(), it->GetProto()->Name1, it->GetEntry(), it->GetCount()); } pl->ModifyMoney( -int32(deposit) ); @@ -282,7 +282,7 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1); } -//this function is called when client bids or buys out auction +// this function is called when client bids or buys out auction void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) { uint64 auctioneer; @@ -292,7 +292,7 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) recv_data >> auctionId >> price; if (!auctionId || !price) - return; //check for cheaters + return; // check for cheaters Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) @@ -312,7 +312,7 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) if( !auction || auction->owner == pl->GetGUIDLow() ) { - //you cannot bid your own auction: + // you cannot bid your own auction: SendAuctionCommandResult( 0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR ); return; } @@ -321,7 +321,7 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) Player* auction_owner = sObjectMgr.GetPlayer(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)); if( !auction_owner && sObjectMgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)) == pl->GetSession()->GetAccountId()) { - //you cannot bid your another character auction: + // you cannot bid your another character auction: SendAuctionCommandResult( 0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR ); return; } @@ -334,14 +334,14 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) if ((price < auction->buyout || auction->buyout == 0) && price < auction->bid + auction->GetAuctionOutBid()) { - //auction has already higher bid, client tests it! + // auction has already higher bid, client tests it! return; } if (price > pl->GetMoney()) { - //you don't have enought money!, client tests! - //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???); + // you don't have enough money!, client tests! + // SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???); return; } @@ -375,7 +375,7 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) } else { - //buyout: + // buyout: if (pl->GetGUIDLow() == auction->bidder ) { pl->ModifyMoney(-int32(auction->buyout - auction->bid)); @@ -383,7 +383,7 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) else { pl->ModifyMoney(-int32(auction->buyout)); - if ( auction->bidder ) //buyout for bidded auction .. + if ( auction->bidder ) // buyout for bidded auction .. { SendAuctionOutbiddedMail( auction, auction->buyout ); } @@ -409,7 +409,7 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data ) CharacterDatabase.CommitTransaction(); } -//this void is called when auction_owner cancels his auction +// this void is called when auction_owner cancels his auction void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data ) { uint64 auctioneer; @@ -418,7 +418,7 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data ) recv_data >> auctionId; //sLog.outDebug( "Cancel AUCTION AuctionID: %u", auctionId); - Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer,UNIT_NPC_FLAG_AUCTIONEER); + Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug( "WORLD: HandleAuctionRemoveItem - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer)) ); @@ -453,7 +453,7 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data ) msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED << ":0:0"; // item will deleted or added to received mail list - MailDraft(msgAuctionCanceledOwner.str(), "", 0) + MailDraft(msgAuctionCanceledOwner.str(), "") // TODO: fix body .AddItem(pItem) .SendMailTo(pl, auction); } @@ -487,9 +487,9 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data ) //called when player lists his bids void WorldSession::HandleAuctionListBidderItems( WorldPacket & recv_data ) { - uint64 guid; //NPC guid - uint32 listfrom; //page of auctions - uint32 outbiddedCount; //count of outbidded auctions + uint64 guid; // NPC guid + uint32 listfrom; // page of auctions + uint32 outbiddedCount; // count of outbidded auctions recv_data >> guid; recv_data >> listfrom; // not used in fact (this list not have page control in client) @@ -515,10 +515,10 @@ void WorldSession::HandleAuctionListBidderItems( WorldPacket & recv_data ) WorldPacket data( SMSG_AUCTION_BIDDER_LIST_RESULT, (4+4+4) ); Player *pl = GetPlayer(); - data << (uint32) 0; //add 0 as count + data << uint32(0); // add 0 as count uint32 count = 0; uint32 totalcount = 0; - while ( outbiddedCount > 0) //add all data, which client requires + while ( outbiddedCount > 0) // add all data, which client requires { --outbiddedCount; uint32 outbiddedAuctionId; @@ -531,14 +531,14 @@ void WorldSession::HandleAuctionListBidderItems( WorldPacket & recv_data ) } } - auctionHouse->BuildListBidderItems(data,pl,count,totalcount); + auctionHouse->BuildListBidderItems(data, pl, count, totalcount); data.put( 0, count ); // add count to placeholder - data << totalcount; - data << (uint32)300; //unk 2.3.0 + data << uint32(totalcount); + data << uint32(300); // unk 2.3.0 delay for next list request? SendPacket(&data); } -//this void sends player info about his auctions +// this void sends player info about his auctions void WorldSession::HandleAuctionListOwnerItems( WorldPacket & recv_data ) { uint32 listfrom; @@ -547,7 +547,7 @@ void WorldSession::HandleAuctionListOwnerItems( WorldPacket & recv_data ) recv_data >> guid; recv_data >> listfrom; // not used in fact (this list not have page control in client) - Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER); + Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug( "WORLD: HandleAuctionListOwnerItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); @@ -566,10 +566,10 @@ void WorldSession::HandleAuctionListOwnerItems( WorldPacket & recv_data ) uint32 count = 0; uint32 totalcount = 0; - auctionHouse->BuildListOwnerItems(data,_player,count,totalcount); + auctionHouse->BuildListOwnerItems(data, _player, count, totalcount); data.put(0, count); - data << (uint32) totalcount; - data << (uint32) 0; + data << uint32(totalcount); + data << uint32(0); // 2.3.0 delay for next list request? SendPacket(&data); } @@ -591,7 +591,7 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data ) recv_data.read_skip(16); // unknown 16 bytes: 00 07 01 00 00 01 05 00 06 00 09 01 08 00 03 00 - Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER); + Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog.outDebug( "WORLD: HandleAuctionListItems - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); @@ -610,7 +610,7 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data ) WorldPacket data( SMSG_AUCTION_LIST_RESULT, (4+4+4) ); uint32 count = 0; uint32 totalcount = 0; - data << (uint32) 0; + data << uint32(0); // converting string that we try to find to lower case std::wstring wsearchedname; @@ -619,14 +619,14 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data ) wstrToLower(wsearchedname); - auctionHouse->BuildListAuctionItems(data,_player, + auctionHouse->BuildListAuctionItems(data, _player, wsearchedname, listfrom, levelmin, levelmax, usable, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, - count,totalcount); + count, totalcount); data.put(0, count); - data << (uint32) totalcount; - data << (uint32) 300; // unk 2.3.0 const? + data << uint32(totalcount); + data << uint32(300); // 2.3.0 delay for next list request? SendPacket(&data); } @@ -634,7 +634,7 @@ void WorldSession::HandleAuctionListPendingSales( WorldPacket & recv_data ) { sLog.outDebug("CMSG_AUCTION_LIST_PENDING_SALES"); - recv_data.read_skip(); // auctioner guid + recv_data.read_skip(); // auctioneer guid uint32 count = 0; diff --git a/src/game/AuctionHouseMgr.cpp b/src/game/AuctionHouseMgr.cpp index 792c73762..8bfaf9c0a 100644 --- a/src/game/AuctionHouseMgr.cpp +++ b/src/game/AuctionHouseMgr.cpp @@ -264,7 +264,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail( AuctionEntry * auction ) RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !! // will delete item or place to receiver mail list - MailDraft(subject.str(), "", 0) + MailDraft(subject.str(), "") // TODO: fix body .AddItem(pItem) .SendMailTo(MailReceiver(owner,auction->owner), auction); } diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index b9561045b..e17af582e 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -963,8 +963,7 @@ void BattleGround::SendRewardMarkByMail(Player *plr,uint32 mark, uint32 count) // text std::string textFormat = plr->GetSession()->GetMangosString(LANG_BG_MARK_BY_MAIL); char textBuf[300]; - snprintf(textBuf,300,textFormat.c_str(),GetName(),GetName()); - uint32 itemTextId = sObjectMgr.CreateItemText( textBuf ); + snprintf(textBuf, 300, textFormat.c_str(), GetName(), GetName()); MailDraft(subject, textBuf) .AddItem(markItem) diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h index 4ee283117..0c74dcba1 100644 --- a/src/game/ItemPrototype.h +++ b/src/game/ItemPrototype.h @@ -119,6 +119,7 @@ enum ITEM_FLAGS ITEM_FLAGS_REFUNDABLE = 0x00001000, // item cost can be refunded within 2 hours after purchase ITEM_FLAGS_CHARTER = 0x00002000, // arena/guild charter ITEM_FLAGS_REFUNDABLE_2 = 0x00008000, // ? + ITEM_FLAGS_UNK1 = 0x00010000, ITEM_FLAGS_PROSPECTABLE = 0x00040000, ITEM_FLAGS_UNIQUE_EQUIPPED = 0x00080000, ITEM_FLAGS_USEABLE_IN_ARENA = 0x00200000, diff --git a/src/game/Mail.cpp b/src/game/Mail.cpp index 116486cd9..bbae0239d 100644 --- a/src/game/Mail.cpp +++ b/src/game/Mail.cpp @@ -234,14 +234,12 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data ) pl->SendMailResult(0, MAIL_SEND, MAIL_OK); - uint32 itemTextId = !body.empty() ? sObjectMgr.CreateItemText( body ) : 0; - pl->ModifyMoney( -int32(reqmoney) ); pl->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost); bool needItemDelay = false; - MailDraft draft(subject, body, itemTextId); + MailDraft draft(subject, body); if (items_count > 0 || money > 0) { @@ -400,7 +398,7 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data ) // send back only to players and simple drop for other cases if (m->messageType == MAIL_NORMAL) { - MailDraft draft(m->subject, m->body, m->itemTextId); + MailDraft draft(m->subject, m->body); if (m->mailTemplateId) draft = MailDraft(m->mailTemplateId,false); // items already included @@ -499,7 +497,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data ) // check player existence if(receive || sender_accId) { - MailDraft(m->subject, "", 0) + MailDraft(m->subject, "") .AddMoney(m->COD) .SendMailTo(MailReceiver(receive,m->sender),MailSender(MAIL_NORMAL,m->receiver), MAIL_CHECK_MASK_COD_PAYMENT); } @@ -634,7 +632,7 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data ) } data << uint32((*itr)->COD); // COD - data << uint32((*itr)->itemTextId); // probably changed in 3.3.3 + data << uint32(0); // probably changed in 3.3.3 data << uint32((*itr)->stationery); // stationery (Stationery.dbc) data << uint32((*itr)->money); // Gold data << uint32(show_flags); // unknown, 0x4 - auction, 0x10 - normal @@ -699,19 +697,18 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data ) */ void WorldSession::HandleItemTextQuery(WorldPacket & recv_data ) { - uint32 itemTextId; - uint32 mailId; // this value can be item id in bag, but it is also mail id - uint32 unk; // maybe something like state - 0x70000000 + uint64 itemGuid; + recv_data >> itemGuid; - recv_data >> itemTextId >> mailId >> unk; + Item *item = _player->GetItemByGuid(itemGuid); + if(!item) + return; - ///TODO: some check needed, if player has item with guid mailId, or has mail with id mailId - - sLog.outDebug("CMSG_ITEM_TEXT_QUERY itemguid: %u, mailId: %u, unk: %u", itemTextId, mailId, unk); + sLog.outDebug("CMSG_ITEM_TEXT_QUERY itemguid: %u", item->GetGUIDLow()); WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, (4+10));// guess size - data << uint32(itemTextId); - data << sObjectMgr.GetItemText( itemTextId ); + data << uint64(itemGuid); + data << sObjectMgr.GetItemText(item->GetGUIDLow()); SendPacket(&data); } @@ -736,27 +733,12 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data ) Player *pl = _player; Mail* m = pl->GetMail(mailId); - if (!m || (!m->itemTextId && !m->mailTemplateId) || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) + if (!m || (m->body.empty() && !m->mailTemplateId) || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) { pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_ERR_INTERNAL_ERROR); return; } - uint32 itemTextId = m->itemTextId; - - // in mail template case we need create new text id - if(!itemTextId) - { - MailTemplateEntry const* mailTemplateEntry = sMailTemplateStore.LookupEntry(m->mailTemplateId); - if(!mailTemplateEntry) - { - pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_ERR_INTERNAL_ERROR); - return; - } - - itemTextId = sObjectMgr.CreateItemText(mailTemplateEntry->content[GetSessionDbcLocale()]); - } - Item *bodyItem = new Item; // This is not bag and then can be used new Item. if(!bodyItem->Create(sObjectMgr.GenerateLowGuid(HIGHGUID_ITEM), MAIL_BODY_ITEM_TEMPLATE, pl)) { @@ -764,21 +746,34 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data ) return; } - //bodyItem->SetUInt32Value( ITEM_FIELD_ITEM_TEXT_ID, itemTextId ); - bodyItem->SetUInt32Value( ITEM_FIELD_CREATOR, m->sender); + // in mail template case we need create new item text + if(m->mailTemplateId) + { + MailTemplateEntry const* mailTemplateEntry = sMailTemplateStore.LookupEntry(m->mailTemplateId); + if(!mailTemplateEntry) + { + pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_ERR_INTERNAL_ERROR); + return; + } - sLog.outDetail("HandleMailCreateTextItem mailid=%u",mailId); + sObjectMgr.CreateItemText(bodyItem->GetGUIDLow(), mailTemplateEntry->content[GetSessionDbcLocale()]); + } + else + sObjectMgr.CreateItemText(bodyItem->GetGUIDLow(), m->body); + + bodyItem->SetUInt32Value(ITEM_FIELD_CREATOR, m->sender); + bodyItem->SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPER | ITEM_FLAGS_REFUNDABLE_2 | ITEM_FLAGS_UNK1); + + sLog.outDetail("HandleMailCreateTextItem mailid=%u", mailId); ItemPosCountVec dest; uint8 msg = _player->CanStoreItem( NULL_BAG, NULL_SLOT, dest, bodyItem, false ); if( msg == EQUIP_ERR_OK ) { - m->itemTextId = 0; m->state = MAIL_STATE_CHANGED; pl->m_mailsUpdated = true; pl->StoreItem(dest, bodyItem, true); - //bodyItem->SetState(ITEM_NEW, pl); is set automatically pl->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_OK); } else @@ -907,18 +902,6 @@ MailReceiver::MailReceiver( Player* receiver,uint32 receiver_lowguid ) : m_recei ASSERT(!receiver || receiver->GetGUIDLow() == receiver_lowguid); } -/** - * Creates a new MailDraft object using subject and content texts. - * - * @param subject The subject of the mail. - * @param itemText The text of the body of the mail. - */ -MailDraft::MailDraft( std::string subject, std::string text ) : m_mailTemplateId(0), m_mailTemplateItemsNeed(false), m_subject(subject), m_body(text), -m_bodyId(!text.empty() ? sObjectMgr.CreateItemText(text) : 0), m_money(0), m_COD(0) -{ - -} - /** * Adds an item to the MailDraft. * @@ -927,7 +910,8 @@ m_bodyId(!text.empty() ? sObjectMgr.CreateItemText(text) : 0), m_money(0), m_COD */ MailDraft& MailDraft::AddItem( Item* item ) { - m_items[item->GetGUIDLow()] = item; return *this; + m_items[item->GetGUIDLow()] = item; + return *this; } /** * Prepares the items in a MailDraft. @@ -1064,9 +1048,9 @@ void MailDraft::SendMailTo(MailReceiver const& receiver, MailSender const& sende CharacterDatabase.BeginTransaction(); CharacterDatabase.escape_string(safe_body); - CharacterDatabase.PExecute("INSERT INTO mail (id,messageType,stationery,mailTemplateId,sender,receiver,subject,body,itemTextId,has_items,expire_time,deliver_time,money,cod,checked) " + CharacterDatabase.PExecute("INSERT INTO mail (id,messageType,stationery,mailTemplateId,sender,receiver,subject,body,has_items,expire_time,deliver_time,money,cod,checked) " "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%s', '%s', '%u', '%u', '" UI64FMTD "','" UI64FMTD "', '%u', '%u', '%d')", - mailId, sender.GetMailMessageType(), sender.GetStationery(), GetMailTemplateId(), sender.GetSenderId(), receiver.GetPlayerGUIDLow(), safe_subject.c_str(), safe_body.c_str(), GetBodyId(), (m_items.empty() ? 0 : 1), (uint64)expire_time, (uint64)deliver_time, m_money, m_COD, checked); + mailId, sender.GetMailMessageType(), sender.GetStationery(), GetMailTemplateId(), sender.GetSenderId(), receiver.GetPlayerGUIDLow(), safe_subject.c_str(), safe_body.c_str(), (m_items.empty() ? 0 : 1), (uint64)expire_time, (uint64)deliver_time, m_money, m_COD, checked); for(MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter) { @@ -1085,7 +1069,6 @@ void MailDraft::SendMailTo(MailReceiver const& receiver, MailSender const& sende m->mailTemplateId = GetMailTemplateId(); m->subject = GetSubject(); m->body = GetBody(); - m->itemTextId = GetBodyId(); m->money = GetMoney(); m->COD = GetCOD(); diff --git a/src/game/Mail.h b/src/game/Mail.h index 58f9dce7e..075bbd532 100644 --- a/src/game/Mail.h +++ b/src/game/Mail.h @@ -184,23 +184,16 @@ class MailDraft * */ explicit MailDraft(uint16 mailTemplateId, bool need_items = true) - : m_mailTemplateId(mailTemplateId), m_mailTemplateItemsNeed(need_items), m_bodyId(0), m_money(0), m_COD(0) + : m_mailTemplateId(mailTemplateId), m_mailTemplateItemsNeed(need_items), m_money(0), m_COD(0) {} - /** - * Creates a new MailDraft object using subject text and content text id. - * - * @param subject The subject of the mail. - * @param itemTextId The id of the body of the mail. - */ - MailDraft(std::string subject, std::string body, uint32 itemTextId) - : m_mailTemplateId(0), m_mailTemplateItemsNeed(false), m_subject(subject), m_body(body), m_bodyId(itemTextId), m_money(0), m_COD(0) {} /** * Creates a new MailDraft object using subject and content texts. * * @param subject The subject of the mail. * @param itemText The text of the body of the mail. */ - MailDraft(std::string subject, std::string text); + MailDraft(std::string subject, std::string body) + : m_mailTemplateId(0), m_mailTemplateItemsNeed(false), m_subject(subject), m_body(body), m_money(0), m_COD(0) {} public: // Accessors /// Returns the template ID used for this MailDraft. uint16 GetMailTemplateId() const { return m_mailTemplateId; } @@ -208,8 +201,6 @@ class MailDraft std::string const& GetSubject() const { return m_subject; } /// Returns the subject of this MailDraft. std::string const& GetBody() const { return m_body; } - /// Returns the ID of the text of this MailDraft. - uint32 GetBodyId() const { return m_bodyId; } /// Returns the amount of money in this MailDraft. uint32 GetMoney() const { return m_money; } /// Returns the Cost of delivery of this MailDraft. @@ -243,8 +234,6 @@ class MailDraft std::string m_subject; /// The body of the MailDraft. std::string m_body; - /// The ID of the body of the MailDraft. - uint32 m_bodyId; /// A map of items in this MailDraft. MailItemMap m_items; ///< Keep the items in a map to avoid duplicate guids (which can happen), store only low part of guid @@ -282,8 +271,6 @@ struct Mail std::string subject; /// the body of the mail std::string body; - /// The ID of the itemtext. - uint32 itemTextId; /// A vector containing Information about the items in this mail. std::vector items; /// A vector containing Information about the items that where already take from this mail. diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index f863a4cff..ddca78032 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -4859,8 +4859,8 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) //delete all old mails without item and without body immediately, if starting server if (!serverUp) CharacterDatabase.PExecute("DELETE FROM mail WHERE expire_time < '" UI64FMTD "' AND has_items = '0' AND itemTextId = 0", (uint64)basetime); - // 0 1 2 3 4 5 6 7 8 9 - QueryResult* result = CharacterDatabase.PQuery("SELECT id,messageType,sender,receiver,itemTextId,has_items,expire_time,cod,checked,mailTemplateId FROM mail WHERE expire_time < '" UI64FMTD "'", (uint64)basetime); + // 0 1 2 3 4 5 6 7 8 + QueryResult* result = CharacterDatabase.PQuery("SELECT id,messageType,sender,receiver,has_items,expire_time,cod,checked,mailTemplateId FROM mail WHERE expire_time < '" UI64FMTD "'", (uint64)basetime); if ( !result ) { barGoLink bar(1); @@ -4889,13 +4889,12 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) m->messageType = fields[1].GetUInt8(); m->sender = fields[2].GetUInt32(); m->receiver = fields[3].GetUInt32(); - m->itemTextId = fields[4].GetUInt32(); - bool has_items = fields[5].GetBool(); - m->expire_time = (time_t)fields[6].GetUInt64(); + bool has_items = fields[4].GetBool(); + m->expire_time = (time_t)fields[5].GetUInt64(); m->deliver_time = 0; - m->COD = fields[7].GetUInt32(); - m->checked = fields[8].GetUInt32(); - m->mailTemplateId = fields[9].GetInt16(); + m->COD = fields[6].GetUInt32(); + m->checked = fields[7].GetUInt32(); + m->mailTemplateId = fields[8].GetInt16(); Player *pl = 0; if (serverUp) @@ -4941,9 +4940,6 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) } } - if (m->itemTextId) - CharacterDatabase.PExecute("DELETE FROM item_text WHERE id = '%u'", m->itemTextId); - //deletemail = true; //delmails << m->messageID << ", "; CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", m->messageID); @@ -5789,18 +5785,17 @@ void ObjectMgr::SetHighestGuids() } } -uint32 ObjectMgr::CreateItemText(std::string text) +void ObjectMgr::CreateItemText(uint32 guid, std::string text) { - uint32 newItemTextId = GenerateItemTextID(); - //insert new itempage to container - mItemTexts[ newItemTextId ] = text; - //save new itempage + // insert new item text to container + mItemTexts[ guid ] = text; + + // save new item text CharacterDatabase.escape_string(text); - //any Delete query needed, itemTextId is maximum of all ids + std::ostringstream query; - query << "INSERT INTO item_text (id,text) VALUES ( '" << newItemTextId << "', '" << text << "')"; - CharacterDatabase.Execute(query.str().c_str()); //needs to be run this way, because mail body may be more than 1024 characters - return newItemTextId; + query << "INSERT INTO item_text (id,text) VALUES ( '" << guid << "', '" << text << "')"; + CharacterDatabase.Execute(query.str().c_str()); // needs to be run this way, because mail body may be more than 1024 characters } uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh) diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 0cd054708..3d3b1c0c5 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -675,12 +675,12 @@ class ObjectMgr uint64 GenerateEquipmentSetGuid() { return m_EquipmentSetIds.Generate(); } uint32 GenerateGuildId() { return m_GuildIds.Generate(); } uint32 GenerateGroupId() { return m_GroupIds.Generate(); } - uint32 GenerateItemTextID() { return m_ItemGuids.Generate(); } + //uint32 GenerateItemTextID() { return m_ItemGuids.Generate(); } uint32 GenerateMailID() { return m_MailIds.Generate(); } uint32 GeneratePetNumber() { return m_PetNumbers.Generate(); } - uint32 CreateItemText(std::string text); - void AddItemText(uint32 itemTextId, std::string text) { mItemTexts[itemTextId] = text; } + void CreateItemText(uint32 guid, std::string text); + void AddItemText(uint32 guid, std::string text) { mItemTexts[guid] = text; } std::string GetItemText( uint32 id ) { ItemTextMap::const_iterator itr = mItemTexts.find( id ); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index d4c5b4d8a..79db76901 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -4005,8 +4005,8 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC // remove signs from petitions (also remove petitions if owner); RemovePetitionsAndSigns(playerguid, 10); - // return back all mails with COD and Item 0 1 2 3 4 5 6 7 8 - QueryResult *resultMail = CharacterDatabase.PQuery("SELECT id,messageType,mailTemplateId,sender,subject,body,itemTextId,money,has_items FROM mail WHERE receiver='%u' AND has_items<>0 AND cod<>0", guid); + // return back all mails with COD and Item 0 1 2 3 4 5 6 7 + QueryResult *resultMail = CharacterDatabase.PQuery("SELECT id,messageType,mailTemplateId,sender,subject,body,money,has_items FROM mail WHERE receiver='%u' AND has_items<>0 AND cod<>0", guid); if(resultMail) { do @@ -4019,9 +4019,8 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC uint32 sender = fields[3].GetUInt32(); std::string subject = fields[4].GetCppString(); std::string body = fields[5].GetCppString(); - uint32 itemTextId = fields[6].GetUInt32(); - uint32 money = fields[7].GetUInt32(); - bool has_items = fields[8].GetBool(); + uint32 money = fields[6].GetUInt32(); + bool has_items = fields[7].GetBool(); //we can return mail now //so firstly delete the old one @@ -4035,7 +4034,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC continue; } - MailDraft draft(subject, body, itemTextId); + MailDraft draft(subject, body); if (mailTemplateId) draft = MailDraft(mailTemplateId, false); // items already included @@ -15638,7 +15637,7 @@ void Player::_LoadInventory(QueryResult *result, uint32 timediff) std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM); // fill mail - MailDraft draft(subject, "There's were problems with equipping item.", 0); + MailDraft draft(subject, "There's were problems with equipping item(s)."); for(int i = 0; !problematicItems.empty() && i < MAX_MAIL_ITEMS; ++i) { @@ -15701,8 +15700,8 @@ void Player::_LoadMailedItems(Mail *mail) void Player::_LoadMail() { m_mail.clear(); - //mails are in right order 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 - QueryResult *result = CharacterDatabase.PQuery("SELECT id,messageType,sender,receiver,subject,body,itemTextId,has_items,expire_time,deliver_time,money,cod,checked,stationery,mailTemplateId FROM mail WHERE receiver = '%u' ORDER BY id DESC", GetGUIDLow()); + //mails are in right order 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + QueryResult *result = CharacterDatabase.PQuery("SELECT id,messageType,sender,receiver,subject,body,has_items,expire_time,deliver_time,money,cod,checked,stationery,mailTemplateId FROM mail WHERE receiver = '%u' ORDER BY id DESC", GetGUIDLow()); if(result) { do @@ -15715,15 +15714,14 @@ void Player::_LoadMail() m->receiver = fields[3].GetUInt32(); m->subject = fields[4].GetCppString(); m->body = fields[5].GetCppString(); - m->itemTextId = fields[6].GetUInt32(); - bool has_items = fields[7].GetBool(); - m->expire_time = (time_t)fields[8].GetUInt64(); - m->deliver_time = (time_t)fields[9].GetUInt64(); - m->money = fields[10].GetUInt32(); - m->COD = fields[11].GetUInt32(); - m->checked = fields[12].GetUInt32(); - m->stationery = fields[13].GetUInt8(); - m->mailTemplateId = fields[14].GetInt16(); + bool has_items = fields[6].GetBool(); + m->expire_time = (time_t)fields[7].GetUInt64(); + m->deliver_time = (time_t)fields[8].GetUInt64(); + m->money = fields[9].GetUInt32(); + m->COD = fields[10].GetUInt32(); + m->checked = fields[11].GetUInt32(); + m->stationery = fields[12].GetUInt8(); + m->mailTemplateId = fields[13].GetInt16(); if(m->mailTemplateId && !sMailTemplateStore.LookupEntry(m->mailTemplateId)) { @@ -15749,7 +15747,7 @@ void Player::LoadPet() if(IsInWorld()) { Pet *pet = new Pet; - if(!pet->LoadPetFromDB(this,0,0,true)) + if(!pet->LoadPetFromDB(this, 0, 0, true)) delete pet; } } @@ -16630,8 +16628,8 @@ void Player::_SaveMail() Mail *m = (*itr); if (m->state == MAIL_STATE_CHANGED) { - CharacterDatabase.PExecute("UPDATE mail SET itemTextId = '%u',has_items = '%u',expire_time = '" UI64FMTD "', deliver_time = '" UI64FMTD "',money = '%u',cod = '%u',checked = '%u' WHERE id = '%u'", - m->itemTextId, m->HasItems() ? 1 : 0, (uint64)m->expire_time, (uint64)m->deliver_time, m->money, m->COD, m->checked, m->messageID); + CharacterDatabase.PExecute("UPDATE mail SET has_items = '%u',expire_time = '" UI64FMTD "', deliver_time = '" UI64FMTD "',money = '%u',cod = '%u',checked = '%u' WHERE id = '%u'", + m->HasItems() ? 1 : 0, (uint64)m->expire_time, (uint64)m->deliver_time, m->money, m->COD, m->checked, m->messageID); if(m->removedItems.size()) { for(std::vector::const_iterator itr2 = m->removedItems.begin(); itr2 != m->removedItems.end(); ++itr2) @@ -16645,8 +16643,7 @@ void Player::_SaveMail() if (m->HasItems()) for(std::vector::const_iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2) CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", itr2->item_guid); - if (m->itemTextId) - CharacterDatabase.PExecute("DELETE FROM item_text WHERE id = '%u'", m->itemTextId); + CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", m->messageID); CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_id = '%u'", m->messageID); } @@ -19634,7 +19631,7 @@ void Player::AutoUnequipOffhandIfNeed() CharacterDatabase.CommitTransaction(); std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM); - MailDraft(subject, "There's were problems with equipping this item.", 0).AddItem(offItem).SendMailTo(this, MailSender(this, MAIL_STATIONERY_GM)); + MailDraft(subject, "There's were problems with equipping this item.").AddItem(offItem).SendMailTo(this, MailSender(this, MAIL_STATIONERY_GM)); } }