aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp94
1 files changed, 66 insertions, 28 deletions
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index ca785cea3da..6662f6f790c 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -1642,7 +1642,26 @@ bool AuctionHouseObject::BuyCommodity(CharacterDatabaseTransaction trans, Player
Optional<ObjectGuid> uniqueSeller;
// prepare items
- std::vector<Item*> items;
+ struct MailedItemsBatch
+ {
+ std::array<Item*, MAX_MAIL_ITEMS> Items = { };
+ uint64 TotalPrice = 0;
+ uint32 Quantity = 0;
+
+ std::size_t ItemsCount = 0;
+
+ bool IsFull() const { return ItemsCount >= Items.size(); }
+ void AddItem(Item* item, uint64 unitPrice)
+ {
+ Items[ItemsCount++] = item;
+ Quantity += item->GetCount();
+ TotalPrice += unitPrice * item->GetCount();
+ }
+ };
+
+ std::vector<MailedItemsBatch> items;
+ items.emplace_back();
+
remainingQuantity = quantity;
std::vector<std::size_t> removedItemsFromAuction;
@@ -1658,7 +1677,14 @@ bool AuctionHouseObject::BuyCommodity(CharacterDatabaseTransaction trans, Player
std::size_t removedItems = 0;
for (Item* auctionItem : auction->Items)
{
- if (auctionItem->GetCount() >= remainingQuantity)
+ MailedItemsBatch* itemsBatch = &items.back();
+ if (itemsBatch->IsFull())
+ {
+ items.emplace_back();
+ itemsBatch = &items.back();
+ }
+
+ if (auctionItem->GetCount() > remainingQuantity)
{
Item* clonedItem = auctionItem->CloneItem(remainingQuantity, player);
if (!clonedItem)
@@ -1670,14 +1696,14 @@ bool AuctionHouseObject::BuyCommodity(CharacterDatabaseTransaction trans, Player
auctionItem->SetCount(auctionItem->GetCount() - remainingQuantity);
auctionItem->FSetState(ITEM_CHANGED);
auctionItem->SaveToDB(trans);
- items.push_back(clonedItem);
+ itemsBatch->AddItem(clonedItem, auction->BuyoutOrUnitPrice);
boughtFromAuction += remainingQuantity;
remainingQuantity = 0;
auctionItr = bucketItr->second.Auctions.end();
break;
}
- items.push_back(auctionItem);
+ itemsBatch->AddItem(auctionItem, auction->BuyoutOrUnitPrice);
boughtFromAuction += auctionItem->GetCount();
remainingQuantity -= auctionItem->GetCount();
++removedItems;
@@ -1693,13 +1719,13 @@ bool AuctionHouseObject::BuyCommodity(CharacterDatabaseTransaction trans, Player
ownerName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN);
sLog->outCommand(bidderAccId, "GM %s (Account: %u) bought commodity in auction: %s (Entry: %u Count: %u) and pay money: " UI64FMTD ". Original owner %s (Account: %u)",
- player->GetName().c_str(), bidderAccId, items[0]->GetNameForLocaleIdx(sWorld->GetDefaultDbcLocale()).c_str(),
- items[0]->GetEntry(), boughtFromAuction, auction->BuyoutOrUnitPrice * boughtFromAuction, ownerName.c_str(),
+ player->GetName().c_str(), bidderAccId, items[0].Items[0]->GetNameForLocaleIdx(sWorld->GetDefaultDbcLocale()).c_str(),
+ items[0].Items[0]->GetEntry(), boughtFromAuction, auction->BuyoutOrUnitPrice * boughtFromAuction, ownerName.c_str(),
sCharacterCache->GetCharacterAccountIdByGuid(auction->Owner));
}
uint64 auctionHouseCut = CalcualteAuctionHouseCut(auction->BuyoutOrUnitPrice * boughtFromAuction);
- uint64 depositPart = AuctionHouseMgr::GetCommodityAuctionDeposit(items[0]->GetTemplate(), std::chrono::duration_cast<Minutes>(auction->EndTime - auction->StartTime),
+ uint64 depositPart = AuctionHouseMgr::GetCommodityAuctionDeposit(items[0].Items[0]->GetTemplate(), std::chrono::duration_cast<Minutes>(auction->EndTime - auction->StartTime),
boughtFromAuction);
uint64 profit = auction->BuyoutOrUnitPrice * boughtFromAuction + depositPart - auctionHouseCut;
@@ -1716,24 +1742,27 @@ bool AuctionHouseObject::BuyCommodity(CharacterDatabaseTransaction trans, Player
.SendMailTo(trans, MailReceiver(ObjectAccessor::FindConnectedPlayer(auction->Owner), auction->Owner), this, MAIL_CHECK_MASK_COPIED, sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY));
}
- MailDraft mail(AuctionHouseMgr::BuildCommodityAuctionMailSubject(AuctionMailType::Won, itemId, quantity),
- AuctionHouseMgr::BuildAuctionWonMailBody(*uniqueSeller, totalPrice, quantity));
-
- for (Item* item : items)
+ for (MailedItemsBatch const& batch : items)
{
- CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_AUCTION_ITEMS_BY_ITEM);
- stmt->setUInt64(0, item->GetGUID().GetCounter());
- trans->Append(stmt);
+ MailDraft mail(AuctionHouseMgr::BuildCommodityAuctionMailSubject(AuctionMailType::Won, itemId, batch.Quantity),
+ AuctionHouseMgr::BuildAuctionWonMailBody(*uniqueSeller, batch.TotalPrice, batch.Quantity));
- item->SetOwnerGUID(player->GetGUID());
- item->SaveToDB(trans);
- mail.AddItem(item);
- }
+ for (std::size_t i = 0; i < batch.ItemsCount; ++i)
+ {
+ CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_AUCTION_ITEMS_BY_ITEM);
+ stmt->setUInt64(0, batch.Items[i]->GetGUID().GetCounter());
+ trans->Append(stmt);
- mail.SendMailTo(trans, player, this, MAIL_CHECK_MASK_COPIED);
+ batch.Items[i]->SetOwnerGUID(player->GetGUID());
+ batch.Items[i]->SaveToDB(trans);
+ mail.AddItem(batch.Items[i]);
+ }
+
+ mail.SendMailTo(trans, player, this, MAIL_CHECK_MASK_COPIED);
+ }
WorldPackets::AuctionHouse::AuctionWonNotification packet;
- packet.Info.Initialize(auctions[0], items[0]);
+ packet.Info.Initialize(auctions[0], items[0].Items[0]);
player->SendDirectMessage(packet.Write());
for (std::size_t i = 0; i < auctions.size(); ++i)
@@ -1891,12 +1920,17 @@ void AuctionHouseObject::SendAuctionExpired(AuctionPosting const* auction, Chara
if (owner)
owner->GetSession()->SendAuctionClosedNotification(auction, 0.0f, false);
- MailDraft mail(AuctionHouseMgr::BuildItemAuctionMailSubject(AuctionMailType::Expired, auction), "");
- for (Item* item : auction->Items)
- mail.AddItem(item);
+ auto itemItr = auction->Items.begin();
+ while (itemItr != auction->Items.end())
+ {
+ MailDraft mail(AuctionHouseMgr::BuildItemAuctionMailSubject(AuctionMailType::Expired, auction), "");
+
+ for (std::size_t i = 0; i < MAX_MAIL_ITEMS && itemItr != auction->Items.end(); ++i, ++itemItr)
+ mail.AddItem(*itemItr);
- mail.SendMailTo(trans, MailReceiver(owner, auction->Owner), this, MAIL_CHECK_MASK_COPIED, 0);
+ mail.SendMailTo(trans, MailReceiver(owner, auction->Owner), this, MAIL_CHECK_MASK_COPIED, 0);
+ }
}
else
{
@@ -1908,12 +1942,16 @@ void AuctionHouseObject::SendAuctionExpired(AuctionPosting const* auction, Chara
void AuctionHouseObject::SendAuctionRemoved(AuctionPosting const* auction, Player* owner, CharacterDatabaseTransaction trans)
{
- MailDraft draft(AuctionHouseMgr::BuildItemAuctionMailSubject(AuctionMailType::Cancelled, auction), "");
+ auto itemItr = auction->Items.begin();
+ while (itemItr != auction->Items.end())
+ {
+ MailDraft draft(AuctionHouseMgr::BuildItemAuctionMailSubject(AuctionMailType::Cancelled, auction), "");
- for (Item* item : auction->Items)
- draft.AddItem(item);
+ for (std::size_t i = 0; i < MAX_MAIL_ITEMS && itemItr != auction->Items.end(); ++i, ++itemItr)
+ draft.AddItem(*itemItr);
- draft.SendMailTo(trans, owner, this, MAIL_CHECK_MASK_COPIED);
+ draft.SendMailTo(trans, owner, this, MAIL_CHECK_MASK_COPIED);
+ }
}
//this function sends mail, when auction is cancelled to old bidder