mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
Move auction related code from ObjectMgr to AuctionHouseMgr.
This commit is contained in:
parent
ef1c243187
commit
7c3ab4b453
12 changed files with 572 additions and 513 deletions
|
|
@ -81,7 +81,7 @@ void WorldSession::SendAuctionHello( uint64 guid, Creature* unit )
|
|||
//this function inserts to WorldPacket auction's data
|
||||
bool WorldSession::SendAuctionInfo(WorldPacket & data, AuctionEntry* auction)
|
||||
{
|
||||
Item *pItem = objmgr.GetAItem(auction->item_guidlow);
|
||||
Item *pItem = auctionmgr.GetAItem(auction->item_guidlow);
|
||||
if (!pItem)
|
||||
{
|
||||
sLog.outError("auction to item, that doesn't exist !!!!");
|
||||
|
|
@ -104,7 +104,7 @@ bool WorldSession::SendAuctionInfo(WorldPacket & data, AuctionEntry* auction)
|
|||
data << (uint32) 0; //Unknown
|
||||
data << (uint64) auction->owner; //Auction->owner
|
||||
data << (uint32) auction->startbid; //Auction->startbid (not sure if useful)
|
||||
data << (uint32) ((auction->bid)? objmgr.GetAuctionOutBid(auction->bid) : 0);
|
||||
data << (uint32) ((auction->bid)? auctionmgr.GetAuctionOutBid(auction->bid) : 0);
|
||||
//minimal outbid
|
||||
data << (uint32) auction->buyout; //auction->buyout
|
||||
data << (uint32) (auction->time - time(NULL)) * 1000; //time left
|
||||
|
|
@ -170,7 +170,7 @@ void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPri
|
|||
msgAuctionOutbiddedSubject << auction->item_template << ":0:" << AUCTION_OUTBIDDED;
|
||||
|
||||
if (oldBidder)
|
||||
oldBidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, _player->GetGUID(), newPrice, objmgr.GetAuctionOutBid(auction->bid), auction->item_template);
|
||||
oldBidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, _player->GetGUID(), newPrice, auctionmgr.GetAuctionOutBid(auction->bid), auction->item_template);
|
||||
|
||||
WorldSession::SendMailTo(oldBidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->bidder, msgAuctionOutbiddedSubject.str(), 0, NULL, auction->bid, 0, MAIL_CHECK_MASK_NONE);
|
||||
}
|
||||
|
|
@ -237,7 +237,7 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data )
|
|||
|
||||
Item *it = pl->GetItemByGuid( item );
|
||||
//do not allow to sell already auctioned items
|
||||
if(objmgr.GetAItem(GUID_LOPART(item)))
|
||||
if(auctionmgr.GetAItem(GUID_LOPART(item)))
|
||||
{
|
||||
sLog.outError("AuctionError, player %s is sending item id: %u, but item is already in another auction", pl->GetName(), GUID_LOPART(item));
|
||||
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR);
|
||||
|
|
@ -264,10 +264,10 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data )
|
|||
|
||||
AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction());
|
||||
AuctionHouseObject * mAuctions;
|
||||
mAuctions = objmgr.GetAuctionsMap( location );
|
||||
mAuctions = auctionmgr.GetAuctionsMap( location );
|
||||
|
||||
//we have to take deposit :
|
||||
uint32 deposit = objmgr.GetAuctionDeposit( location, etime, it );
|
||||
uint32 deposit = auctionmgr.GetAuctionDeposit( location, etime, it );
|
||||
if ( pl->GetMoney() < deposit )
|
||||
{
|
||||
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_NOT_ENOUGHT_MONEY);
|
||||
|
|
@ -301,7 +301,7 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data )
|
|||
sLog.outDetail("selling item %u to auctioneer %u with initial bid %u with buyout %u and with time %u (in sec) in location: %u", GUID_LOPART(item), GUID_LOPART(auctioneer), bid, buyout, auction_time, location);
|
||||
mAuctions->AddAuction(AH);
|
||||
|
||||
objmgr.AddAItem(it);
|
||||
auctionmgr.AddAItem(it);
|
||||
pl->MoveItemFromInventory( it->GetBagSlot(), it->GetSlot(), true);
|
||||
|
||||
CharacterDatabase.BeginTransaction();
|
||||
|
|
@ -344,7 +344,7 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data )
|
|||
AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction());
|
||||
|
||||
AuctionHouseObject * mAuctions;
|
||||
mAuctions = objmgr.GetAuctionsMap( location );
|
||||
mAuctions = auctionmgr.GetAuctionsMap( location );
|
||||
|
||||
AuctionEntry *auction = mAuctions->GetAuction(auctionId);
|
||||
Player *pl = GetPlayer();
|
||||
|
|
@ -371,7 +371,7 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data )
|
|||
|
||||
// price too low for next bid if not buyout
|
||||
if ((price < auction->buyout || auction->buyout == 0) &&
|
||||
price < auction->bid + objmgr.GetAuctionOutBid(auction->bid))
|
||||
price < auction->bid + auctionmgr.GetAuctionOutBid(auction->bid))
|
||||
{
|
||||
//auction has already higher bid, client tests it!
|
||||
return;
|
||||
|
|
@ -429,13 +429,13 @@ void WorldSession::HandleAuctionPlaceBid( WorldPacket & recv_data )
|
|||
auction->bidder = pl->GetGUIDLow();
|
||||
auction->bid = auction->buyout;
|
||||
|
||||
objmgr.SendAuctionSalePendingMail( auction );
|
||||
objmgr.SendAuctionSuccessfulMail( auction );
|
||||
objmgr.SendAuctionWonMail( auction );
|
||||
auctionmgr.SendAuctionSalePendingMail( auction );
|
||||
auctionmgr.SendAuctionSuccessfulMail( auction );
|
||||
auctionmgr.SendAuctionWonMail( auction );
|
||||
|
||||
SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK);
|
||||
|
||||
objmgr.RemoveAItem(auction->item_guidlow);
|
||||
auctionmgr.RemoveAItem(auction->item_guidlow);
|
||||
mAuctions->RemoveAuction(auction->Id);
|
||||
CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",auction->Id);
|
||||
|
||||
|
|
@ -471,19 +471,19 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data )
|
|||
AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction());
|
||||
|
||||
AuctionHouseObject * mAuctions;
|
||||
mAuctions = objmgr.GetAuctionsMap( location );
|
||||
mAuctions = auctionmgr.GetAuctionsMap( location );
|
||||
|
||||
AuctionEntry *auction = mAuctions->GetAuction(auctionId);
|
||||
Player *pl = GetPlayer();
|
||||
|
||||
if (auction && auction->owner == pl->GetGUIDLow())
|
||||
{
|
||||
Item *pItem = objmgr.GetAItem(auction->item_guidlow);
|
||||
Item *pItem = auctionmgr.GetAItem(auction->item_guidlow);
|
||||
if (pItem)
|
||||
{
|
||||
if (auction->bidder > 0) // If we have a bidder, we have to send him the money he paid
|
||||
{
|
||||
uint32 auctionCut = objmgr.GetAuctionCut( auction->location, auction->bid);
|
||||
uint32 auctionCut = auctionmgr.GetAuctionCut( auction->location, auction->bid);
|
||||
if ( pl->GetMoney() < auctionCut ) //player doesn't have enough money, maybe message needed
|
||||
return;
|
||||
//some auctionBidderNotification would be needed, but don't know that parts..
|
||||
|
|
@ -522,7 +522,7 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data )
|
|||
CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",auction->Id);
|
||||
pl->SaveInventoryAndGoldToDB();
|
||||
CharacterDatabase.CommitTransaction();
|
||||
objmgr.RemoveAItem( auction->item_guidlow );
|
||||
auctionmgr.RemoveAItem( auction->item_guidlow );
|
||||
mAuctions->RemoveAuction( auction->Id );
|
||||
delete auction;
|
||||
}
|
||||
|
|
@ -557,7 +557,7 @@ void WorldSession::HandleAuctionListBidderItems( WorldPacket & recv_data )
|
|||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction());
|
||||
AuctionHouseObject* mAuctions = objmgr.GetAuctionsMap( location );
|
||||
AuctionHouseObject* mAuctions = auctionmgr.GetAuctionsMap( location );
|
||||
|
||||
WorldPacket data( SMSG_AUCTION_BIDDER_LIST_RESULT, (4+4+4) );
|
||||
Player *pl = GetPlayer();
|
||||
|
|
@ -616,7 +616,7 @@ void WorldSession::HandleAuctionListOwnerItems( WorldPacket & recv_data )
|
|||
|
||||
AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction());
|
||||
|
||||
AuctionHouseObject* mAuctions = objmgr.GetAuctionsMap( location );
|
||||
AuctionHouseObject* mAuctions = auctionmgr.GetAuctionsMap( location );
|
||||
|
||||
WorldPacket data( SMSG_AUCTION_OWNER_LIST_RESULT, (4+4+4) );
|
||||
data << (uint32) 0; // amount place holder
|
||||
|
|
@ -672,7 +672,7 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )
|
|||
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
|
||||
|
||||
AuctionLocation location = AuctioneerFactionToLocation(pCreature->getFaction());
|
||||
AuctionHouseObject * mAuctions = objmgr.GetAuctionsMap( location );
|
||||
AuctionHouseObject * mAuctions = auctionmgr.GetAuctionsMap( location );
|
||||
|
||||
//sLog.outDebug("Auctionhouse search guid: " I64FMTD ", list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u", guid, listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable);
|
||||
|
||||
|
|
@ -691,7 +691,7 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )
|
|||
for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = mAuctions->GetAuctionsBegin();itr != mAuctions->GetAuctionsEnd();++itr)
|
||||
{
|
||||
AuctionEntry *Aentry = itr->second;
|
||||
Item *item = objmgr.GetAItem(Aentry->item_guidlow);
|
||||
Item *item = auctionmgr.GetAItem(Aentry->item_guidlow);
|
||||
if( item )
|
||||
{
|
||||
ItemPrototype const *proto = item->GetProto();
|
||||
|
|
|
|||
455
src/game/AuctionHouseMgr.cpp
Normal file
455
src/game/AuctionHouseMgr.cpp
Normal file
|
|
@ -0,0 +1,455 @@
|
|||
/*
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Common.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Database/SQLStorage.h"
|
||||
#include "ProgressBar.h"
|
||||
|
||||
#include "AccountMgr.h"
|
||||
#include "AuctionHouseMgr.h"
|
||||
#include "Item.h"
|
||||
#include "Language.h"
|
||||
#include "Log.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "World.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
#include "Policies/SingletonImp.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1( AuctionHouseMgr );
|
||||
|
||||
|
||||
AuctionHouseMgr::AuctionHouseMgr()
|
||||
{
|
||||
}
|
||||
|
||||
AuctionHouseMgr::~AuctionHouseMgr()
|
||||
{
|
||||
for(ItemMap::iterator itr = mAitems.begin(); itr != mAitems.end(); ++itr)
|
||||
delete itr->second;
|
||||
}
|
||||
|
||||
AuctionHouseObject * AuctionHouseMgr::GetAuctionsMap( AuctionLocation location )
|
||||
{
|
||||
switch ( location )
|
||||
{
|
||||
case AUCTION_HORDE:
|
||||
return & mHordeAuctions;
|
||||
break;
|
||||
case AUCTION_ALLIANCE:
|
||||
return & mAllianceAuctions;
|
||||
break;
|
||||
default: //neutral
|
||||
return & mNeutralAuctions;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 AuctionHouseMgr::GetAuctionCut(AuctionLocation location, uint32 highBid)
|
||||
{
|
||||
if (location == AUCTION_NEUTRAL && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
|
||||
return (uint32) (0.15f * highBid * sWorld.getRate(RATE_AUCTION_CUT));
|
||||
else
|
||||
return (uint32) (0.05f * highBid * sWorld.getRate(RATE_AUCTION_CUT));
|
||||
}
|
||||
|
||||
uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionLocation location, uint32 time, Item *pItem)
|
||||
{
|
||||
float percentance; // in 0..1
|
||||
if (location == AUCTION_NEUTRAL && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
|
||||
percentance = 0.75f;
|
||||
else
|
||||
percentance = 0.15f;
|
||||
|
||||
percentance *= sWorld.getRate(RATE_AUCTION_DEPOSIT);
|
||||
|
||||
return uint32( percentance * pItem->GetProto()->SellPrice * pItem->GetCount() * (time / MIN_AUCTION_TIME ) );
|
||||
}
|
||||
|
||||
/// the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c
|
||||
uint32 AuctionHouseMgr::GetAuctionOutBid(uint32 currentBid)
|
||||
{
|
||||
uint32 outbid = (currentBid / 100) * 5;
|
||||
if (!outbid)
|
||||
outbid = 1;
|
||||
return outbid;
|
||||
}
|
||||
|
||||
//does not clear ram
|
||||
void AuctionHouseMgr::SendAuctionWonMail( AuctionEntry *auction )
|
||||
{
|
||||
Item *pItem = GetAItem(auction->item_guidlow);
|
||||
if(!pItem)
|
||||
return;
|
||||
|
||||
uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER);
|
||||
Player *bidder = objmgr.GetPlayer(bidder_guid);
|
||||
|
||||
uint32 bidder_accId = 0;
|
||||
|
||||
// data for gm.log
|
||||
if( sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
|
||||
{
|
||||
uint32 bidder_security = 0;
|
||||
std::string bidder_name;
|
||||
if (bidder)
|
||||
{
|
||||
bidder_accId = bidder->GetSession()->GetAccountId();
|
||||
bidder_security = bidder->GetSession()->GetSecurity();
|
||||
bidder_name = bidder->GetName();
|
||||
}
|
||||
else
|
||||
{
|
||||
bidder_accId = objmgr.GetPlayerAccountIdByGUID(bidder_guid);
|
||||
bidder_security = accmgr.GetSecurity(bidder_accId);
|
||||
|
||||
if(bidder_security > SEC_PLAYER ) // not do redundant DB requests
|
||||
{
|
||||
if(!objmgr.GetPlayerNameByGUID(bidder_guid,bidder_name))
|
||||
bidder_name = objmgr.GetMangosStringForDBCLocale(LANG_UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
if( bidder_security > SEC_PLAYER )
|
||||
{
|
||||
std::string owner_name;
|
||||
if(!objmgr.GetPlayerNameByGUID(auction->owner,owner_name))
|
||||
owner_name = objmgr.GetMangosStringForDBCLocale(LANG_UNKNOWN);
|
||||
|
||||
uint32 owner_accid = objmgr.GetPlayerAccountIdByGUID(auction->owner);
|
||||
|
||||
sLog.outCommand(bidder_accId,"GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)",
|
||||
bidder_name.c_str(),bidder_accId,pItem->GetProto()->Name1,pItem->GetEntry(),pItem->GetCount(),auction->bid,owner_name.c_str(),owner_accid);
|
||||
}
|
||||
}
|
||||
else if(!bidder)
|
||||
bidder_accId = objmgr.GetPlayerAccountIdByGUID(bidder_guid);
|
||||
|
||||
// receiver exist
|
||||
if(bidder || bidder_accId)
|
||||
{
|
||||
std::ostringstream msgAuctionWonSubject;
|
||||
msgAuctionWonSubject << auction->item_template << ":0:" << AUCTION_WON;
|
||||
|
||||
std::ostringstream msgAuctionWonBody;
|
||||
msgAuctionWonBody.width(16);
|
||||
msgAuctionWonBody << std::right << std::hex << auction->owner;
|
||||
msgAuctionWonBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
|
||||
sLog.outDebug( "AuctionWon body string : %s", msgAuctionWonBody.str().c_str() );
|
||||
|
||||
//prepare mail data... :
|
||||
uint32 itemTextId = objmgr.CreateItemText( msgAuctionWonBody.str() );
|
||||
|
||||
// set owner to bidder (to prevent delete item with sender char deleting)
|
||||
// owner in `data` will set at mail receive and item extracting
|
||||
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow());
|
||||
CharacterDatabase.CommitTransaction();
|
||||
|
||||
MailItemsInfo mi;
|
||||
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
|
||||
|
||||
if (bidder)
|
||||
bidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, bidder_guid, 0, 0, auction->item_template);
|
||||
else
|
||||
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
||||
|
||||
// will delete item or place to receiver mail list
|
||||
WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->bidder, msgAuctionWonSubject.str(), itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_AUCTION);
|
||||
}
|
||||
// receiver not exist
|
||||
else
|
||||
{
|
||||
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", pItem->GetGUIDLow());
|
||||
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
||||
delete pItem;
|
||||
}
|
||||
}
|
||||
|
||||
void AuctionHouseMgr::SendAuctionSalePendingMail( AuctionEntry * auction )
|
||||
{
|
||||
uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
|
||||
Player *owner = objmgr.GetPlayer(owner_guid);
|
||||
|
||||
// owner exist (online or offline)
|
||||
if(owner || objmgr.GetPlayerAccountIdByGUID(owner_guid))
|
||||
{
|
||||
std::ostringstream msgAuctionSalePendingSubject;
|
||||
msgAuctionSalePendingSubject << auction->item_template << ":0:" << AUCTION_SALE_PENDING;
|
||||
|
||||
std::ostringstream msgAuctionSalePendingBody;
|
||||
uint32 auctionCut = GetAuctionCut(auction->location, auction->bid);
|
||||
|
||||
time_t distrTime = time(NULL) + HOUR;
|
||||
|
||||
msgAuctionSalePendingBody.width(16);
|
||||
msgAuctionSalePendingBody << std::right << std::hex << auction->bidder;
|
||||
msgAuctionSalePendingBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
|
||||
msgAuctionSalePendingBody << ":" << auction->deposit << ":" << auctionCut << ":0:";
|
||||
msgAuctionSalePendingBody << secsToTimeBitFields(distrTime);
|
||||
|
||||
sLog.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody.str().c_str());
|
||||
|
||||
uint32 itemTextId = objmgr.CreateItemText( msgAuctionSalePendingBody.str() );
|
||||
|
||||
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->owner, msgAuctionSalePendingSubject.str(), itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_AUCTION);
|
||||
}
|
||||
}
|
||||
|
||||
//call this method to send mail to auction owner, when auction is successful, it does not clear ram
|
||||
void AuctionHouseMgr::SendAuctionSuccessfulMail( AuctionEntry * auction )
|
||||
{
|
||||
uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
|
||||
Player *owner = objmgr.GetPlayer(owner_guid);
|
||||
|
||||
uint32 owner_accId = 0;
|
||||
if(!owner)
|
||||
owner_accId = objmgr.GetPlayerAccountIdByGUID(owner_guid);
|
||||
|
||||
// owner exist
|
||||
if(owner || owner_accId)
|
||||
{
|
||||
std::ostringstream msgAuctionSuccessfulSubject;
|
||||
msgAuctionSuccessfulSubject << auction->item_template << ":0:" << AUCTION_SUCCESSFUL;
|
||||
|
||||
std::ostringstream auctionSuccessfulBody;
|
||||
uint32 auctionCut = GetAuctionCut(auction->location, auction->bid);
|
||||
|
||||
auctionSuccessfulBody.width(16);
|
||||
auctionSuccessfulBody << std::right << std::hex << auction->bidder;
|
||||
auctionSuccessfulBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
|
||||
auctionSuccessfulBody << ":" << auction->deposit << ":" << auctionCut;
|
||||
|
||||
sLog.outDebug("AuctionSuccessful body string : %s", auctionSuccessfulBody.str().c_str());
|
||||
|
||||
uint32 itemTextId = objmgr.CreateItemText( auctionSuccessfulBody.str() );
|
||||
|
||||
uint32 profit = auction->bid + auction->deposit - auctionCut;
|
||||
|
||||
if (owner)
|
||||
{
|
||||
//send auction owner notification, bidder must be current!
|
||||
owner->GetSession()->SendAuctionOwnerNotification( auction );
|
||||
}
|
||||
|
||||
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->owner, msgAuctionSuccessfulSubject.str(), itemTextId, NULL, profit, 0, MAIL_CHECK_MASK_AUCTION, HOUR);
|
||||
}
|
||||
}
|
||||
|
||||
//does not clear ram
|
||||
void AuctionHouseMgr::SendAuctionExpiredMail( AuctionEntry * auction )
|
||||
{ //return an item in auction to its owner by mail
|
||||
Item *pItem = GetAItem(auction->item_guidlow);
|
||||
if(!pItem)
|
||||
{
|
||||
sLog.outError("Auction item (GUID: %u) not found, and lost.",auction->item_guidlow);
|
||||
return;
|
||||
}
|
||||
|
||||
uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
|
||||
Player *owner = objmgr.GetPlayer(owner_guid);
|
||||
|
||||
uint32 owner_accId = 0;
|
||||
if(!owner)
|
||||
owner_accId = objmgr.GetPlayerAccountIdByGUID(owner_guid);
|
||||
|
||||
// owner exist
|
||||
if(owner || owner_accId)
|
||||
{
|
||||
std::ostringstream subject;
|
||||
subject << auction->item_template << ":0:" << AUCTION_EXPIRED;
|
||||
|
||||
if ( owner )
|
||||
owner->GetSession()->SendAuctionOwnerNotification( auction );
|
||||
else
|
||||
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
||||
|
||||
MailItemsInfo mi;
|
||||
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
|
||||
|
||||
// will delete item or place to receiver mail list
|
||||
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, GUID_LOPART(owner_guid), subject.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
|
||||
}
|
||||
// owner not found
|
||||
else
|
||||
{
|
||||
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'",pItem->GetGUIDLow());
|
||||
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
||||
delete pItem;
|
||||
}
|
||||
}
|
||||
|
||||
void AuctionHouseMgr::LoadAuctionItems()
|
||||
{
|
||||
// data needs to be at first place for Item::LoadFromDB
|
||||
QueryResult *result = CharacterDatabase.Query( "SELECT data,itemguid,item_template FROM auctionhouse JOIN item_instance ON itemguid = guid" );
|
||||
|
||||
if( !result )
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Loaded 0 auction items");
|
||||
return;
|
||||
}
|
||||
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
Field *fields;
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
|
||||
fields = result->Fetch();
|
||||
uint32 item_guid = fields[1].GetUInt32();
|
||||
uint32 item_template = fields[2].GetUInt32();
|
||||
|
||||
ItemPrototype const *proto = objmgr.GetItemPrototype(item_template);
|
||||
|
||||
if(!proto)
|
||||
{
|
||||
sLog.outError( "ObjectMgr::LoadAuctionItems: Unknown item (GUID: %u id: #%u) in auction, skipped.", item_guid,item_template);
|
||||
continue;
|
||||
}
|
||||
|
||||
Item *item = NewItemOrBag(proto);
|
||||
|
||||
if(!item->LoadFromDB(item_guid,0, result))
|
||||
{
|
||||
delete item;
|
||||
continue;
|
||||
}
|
||||
AddAItem(item);
|
||||
|
||||
++count;
|
||||
}
|
||||
while( result->NextRow() );
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u auction items", count );
|
||||
}
|
||||
|
||||
void AuctionHouseMgr::LoadAuctions()
|
||||
{
|
||||
QueryResult *result = CharacterDatabase.Query("SELECT COUNT(*) FROM auctionhouse");
|
||||
if( !result )
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
Field *fields = result->Fetch();
|
||||
uint32 AuctionCount=fields[0].GetUInt32();
|
||||
delete result;
|
||||
|
||||
if(!AuctionCount)
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
result = CharacterDatabase.Query( "SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit,location FROM auctionhouse" );
|
||||
if( !result )
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
barGoLink bar( AuctionCount );
|
||||
|
||||
AuctionEntry *aItem;
|
||||
|
||||
do
|
||||
{
|
||||
fields = result->Fetch();
|
||||
|
||||
bar.step();
|
||||
|
||||
aItem = new AuctionEntry;
|
||||
aItem->Id = fields[0].GetUInt32();
|
||||
aItem->auctioneer = fields[1].GetUInt32();
|
||||
aItem->item_guidlow = fields[2].GetUInt32();
|
||||
aItem->item_template = fields[3].GetUInt32();
|
||||
aItem->owner = fields[4].GetUInt32();
|
||||
aItem->buyout = fields[5].GetUInt32();
|
||||
aItem->time = fields[6].GetUInt32();
|
||||
aItem->bidder = fields[7].GetUInt32();
|
||||
aItem->bid = fields[8].GetUInt32();
|
||||
aItem->startbid = fields[9].GetUInt32();
|
||||
aItem->deposit = fields[10].GetUInt32();
|
||||
|
||||
uint32 loc = fields[11].GetUInt8();
|
||||
if(!IsValidAuctionLocation(loc))
|
||||
{
|
||||
CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",aItem->Id);
|
||||
sLog.outError("Auction %u has wrong auction location (%u)", aItem->Id, loc);
|
||||
delete aItem;
|
||||
continue;
|
||||
}
|
||||
aItem->location = AuctionLocation(loc);
|
||||
|
||||
// check if sold item exists for guid
|
||||
// and item_template in fact (GetAItem will fail if problematic in result check in ObjectMgr::LoadAuctionItems)
|
||||
if ( !GetAItem( aItem->item_guidlow ) )
|
||||
{
|
||||
CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",aItem->Id);
|
||||
sLog.outError("Auction %u has not a existing item : %u", aItem->Id, aItem->item_guidlow);
|
||||
delete aItem;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(aItem->location)
|
||||
|
||||
GetAuctionsMap( aItem->location )->AddAuction(aItem);
|
||||
|
||||
} while (result->NextRow());
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u auctions", AuctionCount );
|
||||
}
|
||||
|
||||
void AuctionHouseMgr::AddAItem( Item* it )
|
||||
{
|
||||
ASSERT( it );
|
||||
ASSERT( mAitems.find(it->GetGUIDLow()) == mAitems.end());
|
||||
mAitems[it->GetGUIDLow()] = it;
|
||||
}
|
||||
|
||||
bool AuctionHouseMgr::RemoveAItem( uint32 id )
|
||||
{
|
||||
ItemMap::iterator i = mAitems.find(id);
|
||||
if (i == mAitems.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
mAitems.erase(i);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -16,10 +16,13 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _AUCTION_HOUSE_H
|
||||
#define _AUCTION_HOUSE_H
|
||||
#ifndef _AUCTION_HOUSE_MGR_H
|
||||
#define _AUCTION_HOUSE_MGR_H
|
||||
|
||||
#include "SharedDefines.h"
|
||||
#include "Policies/Singleton.h"
|
||||
|
||||
class Item;
|
||||
|
||||
#define MIN_AUCTION_TIME (12*HOUR)
|
||||
|
||||
|
|
@ -102,4 +105,51 @@ class AuctionHouseObject
|
|||
private:
|
||||
AuctionEntryMap AuctionsMap;
|
||||
};
|
||||
|
||||
class AuctionHouseMgr
|
||||
{
|
||||
public:
|
||||
AuctionHouseMgr();
|
||||
~AuctionHouseMgr();
|
||||
|
||||
typedef UNORDERED_MAP<uint32, Item*> ItemMap;
|
||||
|
||||
AuctionHouseObject * GetAuctionsMap( AuctionLocation location );
|
||||
|
||||
Item* GetAItem(uint32 id)
|
||||
{
|
||||
ItemMap::const_iterator itr = mAitems.find(id);
|
||||
if (itr != mAitems.end())
|
||||
{
|
||||
return itr->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AddAItem(Item* it);
|
||||
|
||||
bool RemoveAItem(uint32 id);
|
||||
|
||||
//auction messages
|
||||
void SendAuctionWonMail( AuctionEntry * auction );
|
||||
void SendAuctionSalePendingMail( AuctionEntry * auction );
|
||||
void SendAuctionSuccessfulMail( AuctionEntry * auction );
|
||||
void SendAuctionExpiredMail( AuctionEntry * auction );
|
||||
static uint32 GetAuctionCut( AuctionLocation location, uint32 highBid );
|
||||
static uint32 GetAuctionDeposit(AuctionLocation location, uint32 time, Item *pItem);
|
||||
static uint32 GetAuctionOutBid(uint32 currentBid);
|
||||
public:
|
||||
//load first auction items, because of check if item exists, when loading
|
||||
void LoadAuctionItems();
|
||||
void LoadAuctions();
|
||||
private:
|
||||
AuctionHouseObject mHordeAuctions;
|
||||
AuctionHouseObject mAllianceAuctions;
|
||||
AuctionHouseObject mNeutralAuctions;
|
||||
|
||||
ItemMap mAitems;
|
||||
};
|
||||
|
||||
#define auctionmgr MaNGOS::Singleton<AuctionHouseMgr>::Instance()
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ libmangosgame_a_SOURCES = \
|
|||
ArenaTeam.h \
|
||||
ArenaTeamHandler.cpp \
|
||||
AuctionHouseHandler.cpp \
|
||||
AuctionHouseMgr.cpp \
|
||||
AuctionHouseMgr.h \
|
||||
Bag.cpp \
|
||||
Bag.h \
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "Database/DatabaseEnv.h"
|
||||
#include "Database/SQLStorage.h"
|
||||
#include "Database/SQLStorageImpl.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
|
||||
#include "Log.h"
|
||||
#include "MapManager.h"
|
||||
|
|
@ -33,7 +34,6 @@
|
|||
#include "ArenaTeam.h"
|
||||
#include "Transports.h"
|
||||
#include "ProgressBar.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "Language.h"
|
||||
#include "GameEvent.h"
|
||||
#include "Spell.h"
|
||||
|
|
@ -121,9 +121,9 @@ ObjectMgr::ObjectMgr()
|
|||
m_hiPetNumber = 1;
|
||||
m_ItemTextId = 1;
|
||||
m_mailid = 1;
|
||||
m_auctionid = 1;
|
||||
m_guildId = 1;
|
||||
m_arenaTeamId = 1;
|
||||
m_auctionid = 1;
|
||||
|
||||
mGuildBankTabPrice.resize(GUILD_BANK_MAX_TABS);
|
||||
mGuildBankTabPrice[0] = 100;
|
||||
|
|
@ -173,9 +173,6 @@ ObjectMgr::~ObjectMgr()
|
|||
for (GuildSet::iterator itr = mGuildSet.begin(); itr != mGuildSet.end(); ++itr)
|
||||
delete (*itr);
|
||||
|
||||
for(ItemMap::iterator itr = mAitems.begin(); itr != mAitems.end(); ++itr)
|
||||
delete itr->second;
|
||||
|
||||
for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr)
|
||||
itr->second.Clear();
|
||||
|
||||
|
|
@ -265,254 +262,6 @@ void ObjectMgr::RemoveArenaTeam(ArenaTeam* arenaTeam)
|
|||
mArenaTeamMap.erase( arenaTeam->GetId() );
|
||||
}
|
||||
|
||||
AuctionHouseObject * ObjectMgr::GetAuctionsMap( AuctionLocation location )
|
||||
{
|
||||
switch ( location )
|
||||
{
|
||||
case AUCTION_HORDE:
|
||||
return & mHordeAuctions;
|
||||
break;
|
||||
case AUCTION_ALLIANCE:
|
||||
return & mAllianceAuctions;
|
||||
break;
|
||||
default: //neutral
|
||||
return & mNeutralAuctions;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 ObjectMgr::GetAuctionCut(AuctionLocation location, uint32 highBid)
|
||||
{
|
||||
if (location == AUCTION_NEUTRAL && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
|
||||
return (uint32) (0.15f * highBid * sWorld.getRate(RATE_AUCTION_CUT));
|
||||
else
|
||||
return (uint32) (0.05f * highBid * sWorld.getRate(RATE_AUCTION_CUT));
|
||||
}
|
||||
|
||||
uint32 ObjectMgr::GetAuctionDeposit(AuctionLocation location, uint32 time, Item *pItem)
|
||||
{
|
||||
float percentance; // in 0..1
|
||||
if (location == AUCTION_NEUTRAL && !sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
|
||||
percentance = 0.75f;
|
||||
else
|
||||
percentance = 0.15f;
|
||||
|
||||
percentance *= sWorld.getRate(RATE_AUCTION_DEPOSIT);
|
||||
|
||||
return uint32( percentance * pItem->GetProto()->SellPrice * pItem->GetCount() * (time / MIN_AUCTION_TIME ) );
|
||||
}
|
||||
|
||||
/// the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c
|
||||
uint32 ObjectMgr::GetAuctionOutBid(uint32 currentBid)
|
||||
{
|
||||
uint32 outbid = (currentBid / 100) * 5;
|
||||
if (!outbid)
|
||||
outbid = 1;
|
||||
return outbid;
|
||||
}
|
||||
|
||||
//does not clear ram
|
||||
void ObjectMgr::SendAuctionWonMail( AuctionEntry *auction )
|
||||
{
|
||||
Item *pItem = GetAItem(auction->item_guidlow);
|
||||
if(!pItem)
|
||||
return;
|
||||
|
||||
uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER);
|
||||
Player *bidder = GetPlayer(bidder_guid);
|
||||
|
||||
uint32 bidder_accId = 0;
|
||||
|
||||
// data for gm.log
|
||||
if( sWorld.getConfig(CONFIG_GM_LOG_TRADE) )
|
||||
{
|
||||
uint32 bidder_security = 0;
|
||||
std::string bidder_name;
|
||||
if (bidder)
|
||||
{
|
||||
bidder_accId = bidder->GetSession()->GetAccountId();
|
||||
bidder_security = bidder->GetSession()->GetSecurity();
|
||||
bidder_name = bidder->GetName();
|
||||
}
|
||||
else
|
||||
{
|
||||
bidder_accId = GetPlayerAccountIdByGUID(bidder_guid);
|
||||
bidder_security = accmgr.GetSecurity(bidder_accId);
|
||||
|
||||
if(bidder_security > SEC_PLAYER ) // not do redundant DB requests
|
||||
{
|
||||
if(!GetPlayerNameByGUID(bidder_guid,bidder_name))
|
||||
bidder_name = GetMangosStringForDBCLocale(LANG_UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
if( bidder_security > SEC_PLAYER )
|
||||
{
|
||||
std::string owner_name;
|
||||
if(!GetPlayerNameByGUID(auction->owner,owner_name))
|
||||
owner_name = GetMangosStringForDBCLocale(LANG_UNKNOWN);
|
||||
|
||||
uint32 owner_accid = GetPlayerAccountIdByGUID(auction->owner);
|
||||
|
||||
sLog.outCommand(bidder_accId,"GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)",
|
||||
bidder_name.c_str(),bidder_accId,pItem->GetProto()->Name1,pItem->GetEntry(),pItem->GetCount(),auction->bid,owner_name.c_str(),owner_accid);
|
||||
}
|
||||
}
|
||||
else if(!bidder)
|
||||
bidder_accId = GetPlayerAccountIdByGUID(bidder_guid);
|
||||
|
||||
// receiver exist
|
||||
if(bidder || bidder_accId)
|
||||
{
|
||||
std::ostringstream msgAuctionWonSubject;
|
||||
msgAuctionWonSubject << auction->item_template << ":0:" << AUCTION_WON;
|
||||
|
||||
std::ostringstream msgAuctionWonBody;
|
||||
msgAuctionWonBody.width(16);
|
||||
msgAuctionWonBody << std::right << std::hex << auction->owner;
|
||||
msgAuctionWonBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
|
||||
sLog.outDebug( "AuctionWon body string : %s", msgAuctionWonBody.str().c_str() );
|
||||
|
||||
//prepare mail data... :
|
||||
uint32 itemTextId = CreateItemText( msgAuctionWonBody.str() );
|
||||
|
||||
// set owner to bidder (to prevent delete item with sender char deleting)
|
||||
// owner in `data` will set at mail receive and item extracting
|
||||
CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow());
|
||||
CharacterDatabase.CommitTransaction();
|
||||
|
||||
MailItemsInfo mi;
|
||||
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
|
||||
|
||||
if (bidder)
|
||||
bidder->GetSession()->SendAuctionBidderNotification( auction->location, auction->Id, bidder_guid, 0, 0, auction->item_template);
|
||||
else
|
||||
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
||||
|
||||
// will delete item or place to receiver mail list
|
||||
WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->bidder, msgAuctionWonSubject.str(), itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_AUCTION);
|
||||
}
|
||||
// receiver not exist
|
||||
else
|
||||
{
|
||||
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", pItem->GetGUIDLow());
|
||||
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
||||
delete pItem;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectMgr::SendAuctionSalePendingMail( AuctionEntry * auction )
|
||||
{
|
||||
uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
|
||||
Player *owner = GetPlayer(owner_guid);
|
||||
|
||||
// owner exist (online or offline)
|
||||
if(owner || GetPlayerAccountIdByGUID(owner_guid))
|
||||
{
|
||||
std::ostringstream msgAuctionSalePendingSubject;
|
||||
msgAuctionSalePendingSubject << auction->item_template << ":0:" << AUCTION_SALE_PENDING;
|
||||
|
||||
std::ostringstream msgAuctionSalePendingBody;
|
||||
uint32 auctionCut = GetAuctionCut(auction->location, auction->bid);
|
||||
|
||||
time_t distrTime = time(NULL) + HOUR;
|
||||
|
||||
msgAuctionSalePendingBody.width(16);
|
||||
msgAuctionSalePendingBody << std::right << std::hex << auction->bidder;
|
||||
msgAuctionSalePendingBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
|
||||
msgAuctionSalePendingBody << ":" << auction->deposit << ":" << auctionCut << ":0:";
|
||||
msgAuctionSalePendingBody << secsToTimeBitFields(distrTime);
|
||||
|
||||
sLog.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody.str().c_str());
|
||||
|
||||
uint32 itemTextId = CreateItemText( msgAuctionSalePendingBody.str() );
|
||||
|
||||
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->owner, msgAuctionSalePendingSubject.str(), itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_AUCTION);
|
||||
}
|
||||
}
|
||||
|
||||
//call this method to send mail to auction owner, when auction is successful, it does not clear ram
|
||||
void ObjectMgr::SendAuctionSuccessfulMail( AuctionEntry * auction )
|
||||
{
|
||||
uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
|
||||
Player *owner = GetPlayer(owner_guid);
|
||||
|
||||
uint32 owner_accId = 0;
|
||||
if(!owner)
|
||||
owner_accId = GetPlayerAccountIdByGUID(owner_guid);
|
||||
|
||||
// owner exist
|
||||
if(owner || owner_accId)
|
||||
{
|
||||
std::ostringstream msgAuctionSuccessfulSubject;
|
||||
msgAuctionSuccessfulSubject << auction->item_template << ":0:" << AUCTION_SUCCESSFUL;
|
||||
|
||||
std::ostringstream auctionSuccessfulBody;
|
||||
uint32 auctionCut = GetAuctionCut(auction->location, auction->bid);
|
||||
|
||||
auctionSuccessfulBody.width(16);
|
||||
auctionSuccessfulBody << std::right << std::hex << auction->bidder;
|
||||
auctionSuccessfulBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
|
||||
auctionSuccessfulBody << ":" << auction->deposit << ":" << auctionCut;
|
||||
|
||||
sLog.outDebug("AuctionSuccessful body string : %s", auctionSuccessfulBody.str().c_str());
|
||||
|
||||
uint32 itemTextId = CreateItemText( auctionSuccessfulBody.str() );
|
||||
|
||||
uint32 profit = auction->bid + auction->deposit - auctionCut;
|
||||
|
||||
if (owner)
|
||||
{
|
||||
//send auction owner notification, bidder must be current!
|
||||
owner->GetSession()->SendAuctionOwnerNotification( auction );
|
||||
}
|
||||
|
||||
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->owner, msgAuctionSuccessfulSubject.str(), itemTextId, NULL, profit, 0, MAIL_CHECK_MASK_AUCTION, HOUR);
|
||||
}
|
||||
}
|
||||
|
||||
//does not clear ram
|
||||
void ObjectMgr::SendAuctionExpiredMail( AuctionEntry * auction )
|
||||
{ //return an item in auction to its owner by mail
|
||||
Item *pItem = GetAItem(auction->item_guidlow);
|
||||
if(!pItem)
|
||||
{
|
||||
sLog.outError("Auction item (GUID: %u) not found, and lost.",auction->item_guidlow);
|
||||
return;
|
||||
}
|
||||
|
||||
uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
|
||||
Player *owner = GetPlayer(owner_guid);
|
||||
|
||||
uint32 owner_accId = 0;
|
||||
if(!owner)
|
||||
owner_accId = GetPlayerAccountIdByGUID(owner_guid);
|
||||
|
||||
// owner exist
|
||||
if(owner || owner_accId)
|
||||
{
|
||||
std::ostringstream subject;
|
||||
subject << auction->item_template << ":0:" << AUCTION_EXPIRED;
|
||||
|
||||
if ( owner )
|
||||
owner->GetSession()->SendAuctionOwnerNotification( auction );
|
||||
else
|
||||
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
||||
|
||||
MailItemsInfo mi;
|
||||
mi.AddItem(auction->item_guidlow, auction->item_template, pItem);
|
||||
|
||||
// will delete item or place to receiver mail list
|
||||
WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, GUID_LOPART(owner_guid), subject.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
|
||||
}
|
||||
// owner not found
|
||||
else
|
||||
{
|
||||
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'",pItem->GetGUIDLow());
|
||||
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
|
||||
delete pItem;
|
||||
}
|
||||
}
|
||||
|
||||
CreatureInfo const* ObjectMgr::GetCreatureTemplate(uint32 id)
|
||||
{
|
||||
return sCreatureStorage.LookupEntry<CreatureInfo>(id);
|
||||
|
|
@ -1508,95 +1257,6 @@ uint32 ObjectMgr::GetPlayerAccountIdByPlayerName(const std::string& name) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadAuctions()
|
||||
{
|
||||
QueryResult *result = CharacterDatabase.Query("SELECT COUNT(*) FROM auctionhouse");
|
||||
if( !result )
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
Field *fields = result->Fetch();
|
||||
uint32 AuctionCount=fields[0].GetUInt32();
|
||||
delete result;
|
||||
|
||||
if(!AuctionCount)
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
result = CharacterDatabase.Query( "SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit,location FROM auctionhouse" );
|
||||
if( !result )
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
barGoLink bar( AuctionCount );
|
||||
|
||||
AuctionEntry *aItem;
|
||||
|
||||
do
|
||||
{
|
||||
fields = result->Fetch();
|
||||
|
||||
bar.step();
|
||||
|
||||
aItem = new AuctionEntry;
|
||||
aItem->Id = fields[0].GetUInt32();
|
||||
aItem->auctioneer = fields[1].GetUInt32();
|
||||
aItem->item_guidlow = fields[2].GetUInt32();
|
||||
aItem->item_template = fields[3].GetUInt32();
|
||||
aItem->owner = fields[4].GetUInt32();
|
||||
aItem->buyout = fields[5].GetUInt32();
|
||||
aItem->time = fields[6].GetUInt32();
|
||||
aItem->bidder = fields[7].GetUInt32();
|
||||
aItem->bid = fields[8].GetUInt32();
|
||||
aItem->startbid = fields[9].GetUInt32();
|
||||
aItem->deposit = fields[10].GetUInt32();
|
||||
|
||||
uint32 loc = fields[11].GetUInt8();
|
||||
if(!IsValidAuctionLocation(loc))
|
||||
{
|
||||
CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",aItem->Id);
|
||||
sLog.outError("Auction %u has wrong auction location (%u)", aItem->Id, loc);
|
||||
delete aItem;
|
||||
continue;
|
||||
}
|
||||
aItem->location = AuctionLocation(loc);
|
||||
|
||||
// check if sold item exists for guid
|
||||
// and item_template in fact (GetAItem will fail if problematic in result check in ObjectMgr::LoadAuctionItems)
|
||||
if ( !GetAItem( aItem->item_guidlow ) )
|
||||
{
|
||||
CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",aItem->Id);
|
||||
sLog.outError("Auction %u has not a existing item : %u", aItem->Id, aItem->item_guidlow);
|
||||
delete aItem;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(aItem->location)
|
||||
|
||||
GetAuctionsMap( aItem->location )->AddAuction(aItem);
|
||||
|
||||
} while (result->NextRow());
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u auctions", AuctionCount );
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadItemLocales()
|
||||
{
|
||||
mItemLocaleMap.clear(); // need for reload case
|
||||
|
|
@ -2022,59 +1682,6 @@ void ObjectMgr::LoadItemPrototypes()
|
|||
}
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadAuctionItems()
|
||||
{
|
||||
// data needs to be at first place for Item::LoadFromDB
|
||||
QueryResult *result = CharacterDatabase.Query( "SELECT data,itemguid,item_template FROM auctionhouse JOIN item_instance ON itemguid = guid" );
|
||||
|
||||
if( !result )
|
||||
{
|
||||
barGoLink bar(1);
|
||||
bar.step();
|
||||
sLog.outString("");
|
||||
sLog.outString(">> Loaded 0 auction items");
|
||||
return;
|
||||
}
|
||||
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
Field *fields;
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
|
||||
fields = result->Fetch();
|
||||
uint32 item_guid = fields[1].GetUInt32();
|
||||
uint32 item_template = fields[2].GetUInt32();
|
||||
|
||||
ItemPrototype const *proto = GetItemPrototype(item_template);
|
||||
|
||||
if(!proto)
|
||||
{
|
||||
sLog.outError( "ObjectMgr::LoadAuctionItems: Unknown item (GUID: %u id: #%u) in auction, skipped.", item_guid,item_template);
|
||||
continue;
|
||||
}
|
||||
|
||||
Item *item = NewItemOrBag(proto);
|
||||
|
||||
if(!item->LoadFromDB(item_guid,0, result))
|
||||
{
|
||||
delete item;
|
||||
continue;
|
||||
}
|
||||
AddAItem(item);
|
||||
|
||||
++count;
|
||||
}
|
||||
while( result->NextRow() );
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %u auction items", count );
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadPetLevelInfo()
|
||||
{
|
||||
// Loading levels data
|
||||
|
|
@ -5480,16 +5087,6 @@ uint32 ObjectMgr::GenerateArenaTeamId()
|
|||
return m_arenaTeamId++;
|
||||
}
|
||||
|
||||
uint32 ObjectMgr::GenerateGuildId()
|
||||
{
|
||||
if(m_guildId>=0xFFFFFFFE)
|
||||
{
|
||||
sLog.outError("Guild ids overflow!! Can't continue, shutting down server. ");
|
||||
World::StopNow(ERROR_EXIT_CODE);
|
||||
}
|
||||
return m_guildId++;
|
||||
}
|
||||
|
||||
uint32 ObjectMgr::GenerateAuctionID()
|
||||
{
|
||||
if(m_auctionid>=0xFFFFFFFE)
|
||||
|
|
@ -5500,6 +5097,16 @@ uint32 ObjectMgr::GenerateAuctionID()
|
|||
return m_auctionid++;
|
||||
}
|
||||
|
||||
uint32 ObjectMgr::GenerateGuildId()
|
||||
{
|
||||
if(m_guildId>=0xFFFFFFFE)
|
||||
{
|
||||
sLog.outError("Guild ids overflow!! Can't continue, shutting down server. ");
|
||||
World::StopNow(ERROR_EXIT_CODE);
|
||||
}
|
||||
return m_guildId++;
|
||||
}
|
||||
|
||||
uint32 ObjectMgr::GenerateMailID()
|
||||
{
|
||||
if(m_mailid>=0xFFFFFFFE)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
#include "ItemPrototype.h"
|
||||
#include "NPCHandler.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "AuctionHouseMgr.h"
|
||||
#include "Mail.h"
|
||||
#include "Map.h"
|
||||
#include "ObjectAccessor.h"
|
||||
|
|
@ -348,42 +347,6 @@ class ObjectMgr
|
|||
return sInstanceTemplate.LookupEntry<InstanceTemplate>(map);
|
||||
}
|
||||
|
||||
Item* GetAItem(uint32 id)
|
||||
{
|
||||
ItemMap::const_iterator itr = mAitems.find(id);
|
||||
if (itr != mAitems.end())
|
||||
{
|
||||
return itr->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void AddAItem(Item* it)
|
||||
{
|
||||
ASSERT( it );
|
||||
ASSERT( mAitems.find(it->GetGUIDLow()) == mAitems.end());
|
||||
mAitems[it->GetGUIDLow()] = it;
|
||||
}
|
||||
bool RemoveAItem(uint32 id)
|
||||
{
|
||||
ItemMap::iterator i = mAitems.find(id);
|
||||
if (i == mAitems.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
mAitems.erase(i);
|
||||
return true;
|
||||
}
|
||||
AuctionHouseObject * GetAuctionsMap( AuctionLocation location );
|
||||
|
||||
//auction messages
|
||||
void SendAuctionWonMail( AuctionEntry * auction );
|
||||
void SendAuctionSalePendingMail( AuctionEntry * auction );
|
||||
void SendAuctionSuccessfulMail( AuctionEntry * auction );
|
||||
void SendAuctionExpiredMail( AuctionEntry * auction );
|
||||
static uint32 GetAuctionCut( AuctionLocation location, uint32 highBid );
|
||||
static uint32 GetAuctionDeposit(AuctionLocation location, uint32 time, Item *pItem);
|
||||
static uint32 GetAuctionOutBid(uint32 currentBid);
|
||||
|
||||
PetLevelInfo const* GetPetLevelInfo(uint32 creature_id, uint32 level) const;
|
||||
|
||||
PlayerClassInfo const* GetPlayerClassInfo(uint32 class_) const
|
||||
|
|
@ -536,9 +499,6 @@ class ObjectMgr
|
|||
void LoadItemTexts();
|
||||
void LoadPageTexts();
|
||||
|
||||
//load first auction items, because of check if item exists, when loading
|
||||
void LoadAuctionItems();
|
||||
void LoadAuctions();
|
||||
void LoadPlayerInfo();
|
||||
void LoadPetLevelInfo();
|
||||
void LoadExplorationBaseXP();
|
||||
|
|
@ -571,12 +531,12 @@ class ObjectMgr
|
|||
|
||||
void SetHighestGuids();
|
||||
uint32 GenerateLowGuid(HighGuid guidhigh);
|
||||
uint32 GenerateAuctionID();
|
||||
uint32 GenerateMailID();
|
||||
uint32 GenerateItemTextID();
|
||||
uint32 GeneratePetNumber();
|
||||
uint32 GenerateArenaTeamId();
|
||||
uint32 GenerateAuctionID();
|
||||
uint32 GenerateGuildId();
|
||||
uint32 GenerateItemTextID();
|
||||
uint32 GenerateMailID();
|
||||
uint32 GeneratePetNumber();
|
||||
|
||||
uint32 CreateItemText(std::string text);
|
||||
std::string GetItemText( uint32 id )
|
||||
|
|
@ -768,11 +728,11 @@ class ObjectMgr
|
|||
protected:
|
||||
|
||||
// first free id for selected id type
|
||||
uint32 m_auctionid;
|
||||
uint32 m_mailid;
|
||||
uint32 m_ItemTextId;
|
||||
uint32 m_arenaTeamId;
|
||||
uint32 m_auctionid;
|
||||
uint32 m_guildId;
|
||||
uint32 m_ItemTextId;
|
||||
uint32 m_mailid;
|
||||
uint32 m_hiPetNumber;
|
||||
|
||||
// first free low guid for seelcted guid type
|
||||
|
|
@ -798,14 +758,9 @@ class ObjectMgr
|
|||
ArenaTeamMap mArenaTeamMap;
|
||||
|
||||
ItemMap mItems;
|
||||
ItemMap mAitems;
|
||||
|
||||
ItemTextMap mItemTexts;
|
||||
|
||||
AuctionHouseObject mHordeAuctions;
|
||||
AuctionHouseObject mAllianceAuctions;
|
||||
AuctionHouseObject mNeutralAuctions;
|
||||
|
||||
QuestAreaTriggerMap mQuestAreaTriggerMap;
|
||||
TavernAreaTriggerSet mTavernAreaTriggerSet;
|
||||
GameObjectForQuestSet mGameObjectForQuestSet;
|
||||
|
|
|
|||
|
|
@ -18,28 +18,7 @@
|
|||
|
||||
#ifndef _PLAYER_DUMP_H
|
||||
#define _PLAYER_DUMP_H
|
||||
/*
|
||||
#include "Log.h"
|
||||
#include "Object.h"
|
||||
#include "Bag.h"
|
||||
#include "Creature.h"
|
||||
#include "Player.h"
|
||||
#include "DynamicObject.h"
|
||||
#include "GameObject.h"
|
||||
#include "Corpse.h"
|
||||
#include "QuestDef.h"
|
||||
#include "Path.h"
|
||||
#include "ItemPrototype.h"
|
||||
#include "NPCHandler.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "AuctionHouseObject.h"
|
||||
#include "Mail.h"
|
||||
#include "Map.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectDefines.h"
|
||||
#include "Policies/Singleton.h"
|
||||
#include "Database/SQLStorage.h"
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "World.h"
|
||||
#include "AccountMgr.h"
|
||||
#include "AchievementMgr.h"
|
||||
#include "AuctionHouseMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "Chat.h"
|
||||
|
|
@ -1265,8 +1266,8 @@ void World::SetInitialWorldSettings()
|
|||
///- Load dynamic data tables from the database
|
||||
sLog.outString( "Loading Auctions..." );
|
||||
sLog.outString();
|
||||
objmgr.LoadAuctionItems();
|
||||
objmgr.LoadAuctions();
|
||||
auctionmgr.LoadAuctionItems();
|
||||
auctionmgr.LoadAuctions();
|
||||
sLog.outString( ">>> Auctions loaded" );
|
||||
sLog.outString();
|
||||
|
||||
|
|
@ -1477,13 +1478,13 @@ void World::Update(uint32 diff)
|
|||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
AuctionMap = objmgr.GetAuctionsMap(AUCTION_HORDE);
|
||||
AuctionMap = auctionmgr.GetAuctionsMap(AUCTION_HORDE);
|
||||
break;
|
||||
case 1:
|
||||
AuctionMap = objmgr.GetAuctionsMap(AUCTION_ALLIANCE);
|
||||
AuctionMap = auctionmgr.GetAuctionsMap(AUCTION_ALLIANCE);
|
||||
break;
|
||||
case 2:
|
||||
AuctionMap = objmgr.GetAuctionsMap(AUCTION_NEUTRAL);
|
||||
AuctionMap = auctionmgr.GetAuctionsMap(AUCTION_NEUTRAL);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1498,7 +1499,7 @@ void World::Update(uint32 diff)
|
|||
///- Either cancel the auction if there was no bidder
|
||||
if (itr->second->bidder == 0)
|
||||
{
|
||||
objmgr.SendAuctionExpiredMail( itr->second );
|
||||
auctionmgr.SendAuctionExpiredMail( itr->second );
|
||||
}
|
||||
///- Or perform the transaction
|
||||
else
|
||||
|
|
@ -1506,14 +1507,14 @@ void World::Update(uint32 diff)
|
|||
//we should send an "item sold" message if the seller is online
|
||||
//we send the item to the winner
|
||||
//we send the money to the seller
|
||||
objmgr.SendAuctionSuccessfulMail( itr->second );
|
||||
objmgr.SendAuctionWonMail( itr->second );
|
||||
auctionmgr.SendAuctionSuccessfulMail( itr->second );
|
||||
auctionmgr.SendAuctionWonMail( itr->second );
|
||||
}
|
||||
|
||||
///- In any case clear the auction
|
||||
//No SQL injection (Id is integer)
|
||||
CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",itr->second->Id);
|
||||
objmgr.RemoveAItem(itr->second->item_guidlow);
|
||||
auctionmgr.RemoveAItem(itr->second->item_guidlow);
|
||||
delete itr->second;
|
||||
AuctionMap->RemoveAuction(itr->first);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -503,6 +503,9 @@
|
|||
<File
|
||||
RelativePath="..\..\src\game\ArenaTeam.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\AuctionHouseMgr.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\AuctionHouseMgr.h">
|
||||
</File>
|
||||
|
|
|
|||
|
|
@ -842,6 +842,10 @@
|
|||
RelativePath="..\..\src\game\ArenaTeam.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\AuctionHouseMgr.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\AuctionHouseMgr.h"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -844,6 +844,10 @@
|
|||
RelativePath="..\..\src\game\ArenaTeam.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\AuctionHouseMgr.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\game\AuctionHouseMgr.h"
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue