[11704] Resolve possible crash in auction code for paiment pending state.

Source of crash in sharing item object for sent mail to new owner
and in same time use it in still existed auction for show pending paiment.
Crash possible if new onwer get mail in less hour delay and will drop item
at receive.

Solution: Added fields in memory auction object and table `auction` for
store item stack size and random property id. This let not use auction item
except points where item send to owner at expire and new owner at
buyout/timeout auction with bid.
This commit is contained in:
VladimirMangos 2011-07-02 03:31:09 +04:00
parent 0daf12a348
commit 0f0fa22607
7 changed files with 129 additions and 103 deletions

View file

@ -107,11 +107,7 @@ void WorldSession::SendAuctionBidderNotification(AuctionEntry* auction)
data << uint32(auction->moneyDeliveryTime ? 0 : auction->bid);
data << uint32(auction->GetAuctionOutBid()); // AuctionOutBid?
data << uint32(auction->itemTemplate);
Item *item = sAuctionMgr.GetAItem(auction->itemGuidLow);
uint32 randomId = item ? item->GetItemRandomPropertyId() : 0;
data << uint32(randomId); // random property (value > 0) or suffix (value < 0)
data << int32(auction->itemRandomPropertyId);
SendPacket(&data);
}
@ -131,11 +127,7 @@ void WorldSession::SendAuctionOwnerNotification(AuctionEntry* auction)
// if guid!=0, client updates auctions with new bid, outbid and bidderGuid, else it shows error messages as described above
data << guid; // bidder guid
data << uint32(auction->itemTemplate); // item entry
Item *item = sAuctionMgr.GetAItem(auction->itemGuidLow);
uint32 randomId = item ? item->GetItemRandomPropertyId() : 0;
data << uint32(randomId); // random property (value > 0) or suffix (value < 0)
data << uint32(auction->itemRandomPropertyId);
float timeLeft = float(auction->moneyDeliveryTime - time(NULL)) / float(DAY);
@ -150,11 +142,7 @@ void WorldSession::SendAuctionRemovedNotification(AuctionEntry* auction)
WorldPacket data(SMSG_AUCTION_REMOVED_NOTIFICATION, (3*4));
data << uint32(auction->Id);
data << uint32(auction->itemTemplate);
Item *item = sAuctionMgr.GetAItem(auction->itemGuidLow);
uint32 randomId = item ? item->GetItemRandomPropertyId() : 0;
data << uint32(randomId); // random property (value > 0) or suffix (value < 0)
data << uint32(auction->itemRandomPropertyId);
SendPacket(&data);
}
@ -471,6 +459,8 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
auction->bidder = pl->GetGUIDLow();
auction->bid = price;
SendAuctionCommandResult(auction, AUCTION_BID_PLACED, AUCTION_OK);
if (auction_owner)
auction_owner->GetSession()->SendAuctionOwnerNotification(auction);
@ -478,8 +468,6 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
// after this update we should save player's money ...
CharacterDatabase.PExecute("UPDATE auction SET buyguid = '%u', lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id);
SendAuctionCommandResult(auction, AUCTION_BID_PLACED, AUCTION_OK);
}
else // buyout
{
@ -497,15 +485,11 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
auction->bidder = pl->GetGUIDLow();
auction->bid = auction->buyout;
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout);
auction->moneyDeliveryTime = time(NULL) + HOUR;
sAuctionMgr.SendAuctionWonMail(auction);
SendAuctionCommandResult(auction, AUCTION_BID_PLACED, AUCTION_OK);
CharacterDatabase.PExecute("UPDATE auction SET moneyTime = '" UI64FMTD "', buyguid = '%u', lastbid = '%u' WHERE id = '%u'", (uint64)auction->moneyDeliveryTime, auction->bidder, auction->bid, auction->Id);
auction->AuctionBidWinning();
GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout);
}
CharacterDatabase.BeginTransaction();
pl->SaveInventoryAndGoldToDB();