From cda3a95fc25c2ad8224f6bff2bc3460aa7660173 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 2 Jul 2011 05:04:25 +0400 Subject: [PATCH] [11705] Allow have auction bid generated by server Some code cleanups also. Fir generation bids can be used auction->UpdateBid(price) call without player pointer. --- src/game/AuctionHouseHandler.cpp | 84 ++++++++------------------------ src/game/AuctionHouseMgr.cpp | 79 ++++++++++++++++++++++++------ src/game/AuctionHouseMgr.h | 10 ++-- src/game/WorldSession.h | 4 +- src/shared/revision_nr.h | 2 +- 5 files changed, 95 insertions(+), 84 deletions(-) diff --git a/src/game/AuctionHouseHandler.cpp b/src/game/AuctionHouseHandler.cpp index 827e66f72..c57fd93bc 100644 --- a/src/game/AuctionHouseHandler.cpp +++ b/src/game/AuctionHouseHandler.cpp @@ -120,12 +120,13 @@ void WorldSession::SendAuctionOwnerNotification(AuctionEntry* auction) data << uint32(auction->bid); // if 0, client shows ERR_AUCTION_EXPIRED_S, else ERR_AUCTION_SOLD_S (works only when guid==0) data << uint32(auction->GetAuctionOutBid()); // AuctionOutBid? - ObjectGuid guid = ObjectGuid(); + ObjectGuid bidder_guid = ObjectGuid(); if (!auction->moneyDeliveryTime) // not sold yet - guid = ObjectGuid(HIGHGUID_PLAYER, auction->bidder);// bidder==0 and moneyDeliveryTime==0 for expired auctions, so it will show error message properly + bidder_guid = ObjectGuid(HIGHGUID_PLAYER, auction->bidder); - // if guid!=0, client updates auctions with new bid, outbid and bidderGuid, else it shows error messages as described above - data << guid; // bidder guid + // bidder==0 and moneyDeliveryTime==0 for expired auctions, and client shows error messages as described above + // if bidder!=0 client updates auctions with new bid, outbid and bidderGuid + data << bidder_guid; // bidder guid data << uint32(auction->itemTemplate); // item entry data << uint32(auction->itemRandomPropertyId); @@ -154,7 +155,7 @@ void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction) Player *oldBidder = sObjectMgr.GetPlayer(oldBidder_guid); uint32 oldBidder_accId = 0; - if(!oldBidder) + if(!oldBidder && oldBidder_guid) oldBidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(oldBidder_guid); // old bidder exist @@ -179,7 +180,7 @@ void WorldSession::SendAuctionCancelledToBidderMail(AuctionEntry* auction) Player *bidder = sObjectMgr.GetPlayer(bidder_guid); uint32 bidder_accId = 0; - if (!bidder) + if (!bidder && bidder_guid) bidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(bidder_guid); // bidder exist @@ -415,10 +416,6 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) return; } - // cheating - if (price < auction->startbid) - return; - // cheating or client lags if (price <= auction->bid) { @@ -443,57 +440,16 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) return; } - if ((price < auction->buyout) || (auction->buyout == 0))// bid - { - if (pl->GetGUIDLow() == auction->bidder) - { - pl->ModifyMoney(-int32(price - auction->bid)); - } - else - { - pl->ModifyMoney(-int32(price)); - if (auction->bidder) // return money to old bidder if present - SendAuctionOutbiddedMail(auction); - } + // cheating + if (price < auction->startbid) + return; - auction->bidder = pl->GetGUIDLow(); - auction->bid = price; + SendAuctionCommandResult(auction, AUCTION_BID_PLACED, AUCTION_OK); - SendAuctionCommandResult(auction, AUCTION_BID_PLACED, AUCTION_OK); - - if (auction_owner) - auction_owner->GetSession()->SendAuctionOwnerNotification(auction); - - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); - - // 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); - } - else // buyout - { - if (pl->GetGUIDLow() == auction->bidder) - { - pl->ModifyMoney(-int32(auction->buyout - auction->bid)); - } - else - { - pl->ModifyMoney(-int32(auction->buyout)); - if (auction->bidder) // return money to old bidder if present - SendAuctionOutbiddedMail(auction); - } - - auction->bidder = pl->GetGUIDLow(); - auction->bid = auction->buyout; - - SendAuctionCommandResult(auction, AUCTION_BID_PLACED, AUCTION_OK); - - auction->AuctionBidWinning(); - - GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout); - } - CharacterDatabase.BeginTransaction(); - pl->SaveInventoryAndGoldToDB(); - CharacterDatabase.CommitTransaction(); + if (auction->UpdateBid(price, pl)) + pl->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); + else + pl->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout); } // this void is called when auction_owner cancels his auction @@ -536,13 +492,15 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data) return; } - if (auction->bidder > 0) // If we have a bidder, we have to send him the money he paid + if (auction->bid) // If we have a bid, we have to send him the money he paid { uint32 auctionCut = auction->GetAuctionCut(); - if (pl->GetMoney() < auctionCut) // player doesn't have enough money, maybe message needed + if (pl->GetMoney() < auctionCut) // player doesn't have enough money, maybe message needed return; - SendAuctionCancelledToBidderMail(auction); + if (auction->bidder) // if auction have real existed bidder send mail + SendAuctionCancelledToBidderMail(auction); + pl->ModifyMoney(-int32(auctionCut)); } // Return the item by mail @@ -550,7 +508,7 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data) msgAuctionCanceledOwner << auction->itemTemplate << ":0:" << AUCTION_CANCELED << ":0:0"; // item will deleted or added to received mail list - MailDraft(msgAuctionCanceledOwner.str(), "") // TODO: fix body + MailDraft(msgAuctionCanceledOwner.str(), "") // TODO: fix body .AddItem(pItem) .SendMailTo(pl, auction, MAIL_CHECK_MASK_COPIED); diff --git a/src/game/AuctionHouseMgr.cpp b/src/game/AuctionHouseMgr.cpp index 236701a77..727514859 100644 --- a/src/game/AuctionHouseMgr.cpp +++ b/src/game/AuctionHouseMgr.cpp @@ -94,7 +94,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction) // data for gm.log if (sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE)) { - uint32 bidder_security = 0; + AccountTypes bidder_security = SEC_PLAYER; std::string bidder_name; if (bidder) { @@ -104,8 +104,8 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction) } else { - bidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(bidder_guid); - bidder_security = sAccountMgr.GetSecurity(bidder_accId); + bidder_accId = bidder_guid ? sObjectMgr.GetPlayerAccountIdByGUID(bidder_guid) : 0; + bidder_security = bidder_accId ? sAccountMgr.GetSecurity(bidder_accId) : SEC_PLAYER; if (bidder_security > SEC_PLAYER) // not do redundant DB requests { @@ -128,7 +128,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction) bidder_name.c_str(), bidder_accId, auction->itemTemplate, auction->itemCount, auction->bid, owner_name.c_str(), owner_accid); } } - else if (!bidder) + else if (!bidder && bidder_guid) bidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(bidder_guid); if (auction_owner) @@ -621,18 +621,17 @@ void AuctionHouseObject::Update() if (curTime > itr->second->expireTime) { ///- perform the transaction if there was bidder - if (itr->second->bidder) - { + if (itr->second->bid) itr->second->AuctionBidWinning(); - continue; + ///- cancel the auction if there was no bidder and clear the auction + else + { + sAuctionMgr.SendAuctionExpiredMail(itr->second); + + itr->second->DeleteFromDB(); + delete itr->second; + RemoveAuction(itr->first); } - - ///- cancel the auction if there was no bidder - sAuctionMgr.SendAuctionExpiredMail(itr->second); - - itr->second->DeleteFromDB(); - delete itr->second; - RemoveAuction(itr->first); } } } @@ -1033,10 +1032,60 @@ void AuctionEntry::SaveToDB() const Id, auctionHouseEntry->houseId, itemGuidLow, itemTemplate, itemCount, itemRandomPropertyId, owner, buyout, (uint64)expireTime, (uint64)moneyDeliveryTime, bidder, bid, startbid, deposit); } -void AuctionEntry::AuctionBidWinning() +void AuctionEntry::AuctionBidWinning(Player* newbidder) { moneyDeliveryTime = time(NULL) + HOUR; + + CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("UPDATE auction SET itemguid = 0, moneyTime = '" UI64FMTD "', buyguid = '%u', lastbid = '%u' WHERE id = '%u'", (uint64)moneyDeliveryTime, bidder, bid, Id); + if (newbidder) + newbidder->SaveInventoryAndGoldToDB(); + CharacterDatabase.CommitTransaction(); sAuctionMgr.SendAuctionWonMail(this); } + +bool AuctionEntry::UpdateBid(uint32 newbid, Player* newbidder /*=NULL*/) +{ + Player* auction_owner = owner ? sObjectMgr.GetPlayer(ObjectGuid(HIGHGUID_PLAYER, owner)) : NULL; + + // bid can't be greater buyout + if (buyout && newbid > buyout) + newbid = buyout; + + if (newbidder && newbidder->GetGUIDLow() == bidder) + { + newbidder->ModifyMoney(-int32(newbid - bid)); + } + else + { + if (newbidder) + newbidder->ModifyMoney(-int32(newbid)); + + if (bidder) // return money to old bidder if present + WorldSession::SendAuctionOutbiddedMail(this); + } + + bidder = newbidder ? newbidder->GetGUIDLow() : 0; + bid = newbid; + + if ((newbid < buyout) || (buyout == 0)) // bid + { + + if (auction_owner) + auction_owner->GetSession()->SendAuctionOwnerNotification(this); + + // after this update we should save player's money ... + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("UPDATE auction SET buyguid = '%u', lastbid = '%u' WHERE id = '%u'", bidder, bid, Id); + if (newbidder) + newbidder->SaveInventoryAndGoldToDB(); + CharacterDatabase.CommitTransaction(); + return true; + } + else // buyout + { + AuctionBidWinning(newbidder); + return false; + } +} diff --git a/src/game/AuctionHouseMgr.h b/src/game/AuctionHouseMgr.h index dca14fe35..521adc9a2 100644 --- a/src/game/AuctionHouseMgr.h +++ b/src/game/AuctionHouseMgr.h @@ -62,12 +62,12 @@ struct AuctionEntry int32 itemRandomPropertyId; uint32 owner; // player low guid, can be 0 for server generated auction std::wstring ownerName; // cache name for sorting - uint32 startbid; // maybe useless - uint32 bid; + uint32 startbid; // start minimal bid value + uint32 bid; // current bid, =0 meaning no bids uint32 buyout; time_t expireTime; time_t moneyDeliveryTime; - uint32 bidder; + uint32 bidder; // current bidder player lowguid, can be 0 if bid generated by server, use 'bid'!=0 for check bid existance uint32 deposit; // deposit can be calculated only when creating auction AuctionHouseEntry const* auctionHouseEntry; // in AuctionHouse.dbc @@ -79,11 +79,13 @@ struct AuctionEntry bool BuildAuctionInfo(WorldPacket & data) const; void DeleteFromDB() const; void SaveToDB() const; - void AuctionBidWinning(); + void AuctionBidWinning(Player* bidder = NULL); // -1,0,+1 order result int CompareAuctionEntry(uint32 column, const AuctionEntry *auc, Player* viewPlayer) const; + + bool UpdateBid(uint32 newbid, Player* newbidder = NULL);// true if normal bid, false if buyout, bidder==NULL for generated bid }; //this class is used as auctionhouse instance diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index b78f1d935..b3cbad76a 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -356,7 +356,7 @@ class MANGOS_DLL_SPEC WorldSession void SendAuctionBidderNotification(AuctionEntry *auction); void SendAuctionOwnerNotification(AuctionEntry *auction); void SendAuctionRemovedNotification(AuctionEntry* auction); - void SendAuctionOutbiddedMail(AuctionEntry *auction); + static void SendAuctionOutbiddedMail(AuctionEntry *auction); void SendAuctionCancelledToBidderMail(AuctionEntry *auction); void BuildListAuctionItems(std::list &auctions, WorldPacket& data, std::wstring const& searchedname, uint32 listfrom, uint32 levelmin, uint32 levelmax, uint32 usable, uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality, uint32& count, uint32& totalcount, bool isFull); @@ -614,6 +614,8 @@ class MANGOS_DLL_SPEC WorldSession void HandleAuctionRemoveItem( WorldPacket & recv_data ); void HandleAuctionListOwnerItems( WorldPacket & recv_data ); void HandleAuctionPlaceBid( WorldPacket & recv_data ); + + void AuctionBind( uint32 price, AuctionEntry * auction, Player * pl, Player* auction_owner ); void HandleAuctionListPendingSales( WorldPacket & recv_data ); void HandleGetMailList( WorldPacket & recv_data ); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f30530a1b..bb1cc709d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11704" + #define REVISION_NR "11705" #endif // __REVISION_NR_H__