mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
[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.
This commit is contained in:
parent
0f0fa22607
commit
cda3a95fc2
5 changed files with 95 additions and 84 deletions
|
|
@ -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->bid); // if 0, client shows ERR_AUCTION_EXPIRED_S, else ERR_AUCTION_SOLD_S (works only when guid==0)
|
||||||
data << uint32(auction->GetAuctionOutBid()); // AuctionOutBid?
|
data << uint32(auction->GetAuctionOutBid()); // AuctionOutBid?
|
||||||
|
|
||||||
ObjectGuid guid = ObjectGuid();
|
ObjectGuid bidder_guid = ObjectGuid();
|
||||||
if (!auction->moneyDeliveryTime) // not sold yet
|
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
|
// bidder==0 and moneyDeliveryTime==0 for expired auctions, and client shows error messages as described above
|
||||||
data << guid; // bidder guid
|
// 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->itemTemplate); // item entry
|
||||||
data << uint32(auction->itemRandomPropertyId);
|
data << uint32(auction->itemRandomPropertyId);
|
||||||
|
|
||||||
|
|
@ -154,7 +155,7 @@ void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction)
|
||||||
Player *oldBidder = sObjectMgr.GetPlayer(oldBidder_guid);
|
Player *oldBidder = sObjectMgr.GetPlayer(oldBidder_guid);
|
||||||
|
|
||||||
uint32 oldBidder_accId = 0;
|
uint32 oldBidder_accId = 0;
|
||||||
if(!oldBidder)
|
if(!oldBidder && oldBidder_guid)
|
||||||
oldBidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(oldBidder_guid);
|
oldBidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(oldBidder_guid);
|
||||||
|
|
||||||
// old bidder exist
|
// old bidder exist
|
||||||
|
|
@ -179,7 +180,7 @@ void WorldSession::SendAuctionCancelledToBidderMail(AuctionEntry* auction)
|
||||||
Player *bidder = sObjectMgr.GetPlayer(bidder_guid);
|
Player *bidder = sObjectMgr.GetPlayer(bidder_guid);
|
||||||
|
|
||||||
uint32 bidder_accId = 0;
|
uint32 bidder_accId = 0;
|
||||||
if (!bidder)
|
if (!bidder && bidder_guid)
|
||||||
bidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(bidder_guid);
|
bidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(bidder_guid);
|
||||||
|
|
||||||
// bidder exist
|
// bidder exist
|
||||||
|
|
@ -415,10 +416,6 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cheating
|
|
||||||
if (price < auction->startbid)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// cheating or client lags
|
// cheating or client lags
|
||||||
if (price <= auction->bid)
|
if (price <= auction->bid)
|
||||||
{
|
{
|
||||||
|
|
@ -443,57 +440,16 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((price < auction->buyout) || (auction->buyout == 0))// bid
|
// cheating
|
||||||
{
|
if (price < auction->startbid)
|
||||||
if (pl->GetGUIDLow() == auction->bidder)
|
return;
|
||||||
{
|
|
||||||
pl->ModifyMoney(-int32(price - auction->bid));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pl->ModifyMoney(-int32(price));
|
|
||||||
if (auction->bidder) // return money to old bidder if present
|
|
||||||
SendAuctionOutbiddedMail(auction);
|
|
||||||
}
|
|
||||||
|
|
||||||
auction->bidder = pl->GetGUIDLow();
|
|
||||||
auction->bid = price;
|
|
||||||
|
|
||||||
SendAuctionCommandResult(auction, AUCTION_BID_PLACED, AUCTION_OK);
|
SendAuctionCommandResult(auction, AUCTION_BID_PLACED, AUCTION_OK);
|
||||||
|
|
||||||
if (auction_owner)
|
if (auction->UpdateBid(price, pl))
|
||||||
auction_owner->GetSession()->SendAuctionOwnerNotification(auction);
|
pl->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price);
|
||||||
|
|
||||||
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
|
else
|
||||||
{
|
pl->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// this void is called when auction_owner cancels his auction
|
// this void is called when auction_owner cancels his auction
|
||||||
|
|
@ -536,13 +492,15 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket & recv_data)
|
||||||
return;
|
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();
|
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;
|
return;
|
||||||
|
|
||||||
|
if (auction->bidder) // if auction have real existed bidder send mail
|
||||||
SendAuctionCancelledToBidderMail(auction);
|
SendAuctionCancelledToBidderMail(auction);
|
||||||
|
|
||||||
pl->ModifyMoney(-int32(auctionCut));
|
pl->ModifyMoney(-int32(auctionCut));
|
||||||
}
|
}
|
||||||
// Return the item by mail
|
// Return the item by mail
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction)
|
||||||
// data for gm.log
|
// data for gm.log
|
||||||
if (sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE))
|
if (sWorld.getConfig(CONFIG_BOOL_GM_LOG_TRADE))
|
||||||
{
|
{
|
||||||
uint32 bidder_security = 0;
|
AccountTypes bidder_security = SEC_PLAYER;
|
||||||
std::string bidder_name;
|
std::string bidder_name;
|
||||||
if (bidder)
|
if (bidder)
|
||||||
{
|
{
|
||||||
|
|
@ -104,8 +104,8 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry *auction)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(bidder_guid);
|
bidder_accId = bidder_guid ? sObjectMgr.GetPlayerAccountIdByGUID(bidder_guid) : 0;
|
||||||
bidder_security = sAccountMgr.GetSecurity(bidder_accId);
|
bidder_security = bidder_accId ? sAccountMgr.GetSecurity(bidder_accId) : SEC_PLAYER;
|
||||||
|
|
||||||
if (bidder_security > SEC_PLAYER) // not do redundant DB requests
|
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);
|
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);
|
bidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(bidder_guid);
|
||||||
|
|
||||||
if (auction_owner)
|
if (auction_owner)
|
||||||
|
|
@ -621,13 +621,11 @@ void AuctionHouseObject::Update()
|
||||||
if (curTime > itr->second->expireTime)
|
if (curTime > itr->second->expireTime)
|
||||||
{
|
{
|
||||||
///- perform the transaction if there was bidder
|
///- perform the transaction if there was bidder
|
||||||
if (itr->second->bidder)
|
if (itr->second->bid)
|
||||||
{
|
|
||||||
itr->second->AuctionBidWinning();
|
itr->second->AuctionBidWinning();
|
||||||
continue;
|
///- cancel the auction if there was no bidder and clear the auction
|
||||||
}
|
else
|
||||||
|
{
|
||||||
///- cancel the auction if there was no bidder
|
|
||||||
sAuctionMgr.SendAuctionExpiredMail(itr->second);
|
sAuctionMgr.SendAuctionExpiredMail(itr->second);
|
||||||
|
|
||||||
itr->second->DeleteFromDB();
|
itr->second->DeleteFromDB();
|
||||||
|
|
@ -637,6 +635,7 @@ void AuctionHouseObject::Update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AuctionHouseObject::BuildListBidderItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount)
|
void AuctionHouseObject::BuildListBidderItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount)
|
||||||
{
|
{
|
||||||
|
|
@ -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);
|
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;
|
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);
|
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);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,12 +62,12 @@ struct AuctionEntry
|
||||||
int32 itemRandomPropertyId;
|
int32 itemRandomPropertyId;
|
||||||
uint32 owner; // player low guid, can be 0 for server generated auction
|
uint32 owner; // player low guid, can be 0 for server generated auction
|
||||||
std::wstring ownerName; // cache name for sorting
|
std::wstring ownerName; // cache name for sorting
|
||||||
uint32 startbid; // maybe useless
|
uint32 startbid; // start minimal bid value
|
||||||
uint32 bid;
|
uint32 bid; // current bid, =0 meaning no bids
|
||||||
uint32 buyout;
|
uint32 buyout;
|
||||||
time_t expireTime;
|
time_t expireTime;
|
||||||
time_t moneyDeliveryTime;
|
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
|
uint32 deposit; // deposit can be calculated only when creating auction
|
||||||
AuctionHouseEntry const* auctionHouseEntry; // in AuctionHouse.dbc
|
AuctionHouseEntry const* auctionHouseEntry; // in AuctionHouse.dbc
|
||||||
|
|
||||||
|
|
@ -79,11 +79,13 @@ struct AuctionEntry
|
||||||
bool BuildAuctionInfo(WorldPacket & data) const;
|
bool BuildAuctionInfo(WorldPacket & data) const;
|
||||||
void DeleteFromDB() const;
|
void DeleteFromDB() const;
|
||||||
void SaveToDB() const;
|
void SaveToDB() const;
|
||||||
void AuctionBidWinning();
|
void AuctionBidWinning(Player* bidder = NULL);
|
||||||
|
|
||||||
|
|
||||||
// -1,0,+1 order result
|
// -1,0,+1 order result
|
||||||
int CompareAuctionEntry(uint32 column, const AuctionEntry *auc, Player* viewPlayer) const;
|
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
|
//this class is used as auctionhouse instance
|
||||||
|
|
|
||||||
|
|
@ -356,7 +356,7 @@ class MANGOS_DLL_SPEC WorldSession
|
||||||
void SendAuctionBidderNotification(AuctionEntry *auction);
|
void SendAuctionBidderNotification(AuctionEntry *auction);
|
||||||
void SendAuctionOwnerNotification(AuctionEntry *auction);
|
void SendAuctionOwnerNotification(AuctionEntry *auction);
|
||||||
void SendAuctionRemovedNotification(AuctionEntry* auction);
|
void SendAuctionRemovedNotification(AuctionEntry* auction);
|
||||||
void SendAuctionOutbiddedMail(AuctionEntry *auction);
|
static void SendAuctionOutbiddedMail(AuctionEntry *auction);
|
||||||
void SendAuctionCancelledToBidderMail(AuctionEntry *auction);
|
void SendAuctionCancelledToBidderMail(AuctionEntry *auction);
|
||||||
void BuildListAuctionItems(std::list<AuctionEntry*> &auctions, WorldPacket& data, std::wstring const& searchedname, uint32 listfrom, uint32 levelmin,
|
void BuildListAuctionItems(std::list<AuctionEntry*> &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);
|
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 HandleAuctionRemoveItem( WorldPacket & recv_data );
|
||||||
void HandleAuctionListOwnerItems( WorldPacket & recv_data );
|
void HandleAuctionListOwnerItems( WorldPacket & recv_data );
|
||||||
void HandleAuctionPlaceBid( 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 HandleAuctionListPendingSales( WorldPacket & recv_data );
|
||||||
|
|
||||||
void HandleGetMailList( WorldPacket & recv_data );
|
void HandleGetMailList( WorldPacket & recv_data );
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "11704"
|
#define REVISION_NR "11705"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue