2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "Database/DatabaseEnv.h"
21 #include "Database/SQLStorage.h"
22 #include "DBCStores.h"
23 #include "ProgressBar.h"
25 #include "AccountMgr.h"
26 #include "AuctionHouseMgr.h"
30 #include "ObjectMgr.h"
33 #include "WorldPacket.h"
34 #include "WorldSession.h"
36 #include "Policies/SingletonImp.h"
38 INSTANTIATE_SINGLETON_1( AuctionHouseMgr
);
40 AuctionHouseMgr::AuctionHouseMgr()
44 AuctionHouseMgr::~AuctionHouseMgr()
46 for(ItemMap::const_iterator itr
= mAitems
.begin(); itr
!= mAitems
.end(); ++itr
)
50 AuctionHouseObject
* AuctionHouseMgr::GetAuctionsMap( uint32 factionTemplateId
)
52 if(sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION
))
53 return &mNeutralAuctions
;
55 // team have linked auction houses
56 FactionTemplateEntry
const* u_entry
= sFactionTemplateStore
.LookupEntry(factionTemplateId
);
58 return &mNeutralAuctions
;
59 else if(u_entry
->ourMask
& FACTION_MASK_ALLIANCE
)
60 return &mAllianceAuctions
;
61 else if(u_entry
->ourMask
& FACTION_MASK_HORDE
)
62 return &mHordeAuctions
;
64 return &mNeutralAuctions
;
67 uint32
AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry
const* entry
, uint32 time
, Item
*pItem
)
69 uint32 deposit
= pItem
->GetProto()->SellPrice
* pItem
->GetCount() * (time
/ MIN_AUCTION_TIME
);
71 return uint32(deposit
* entry
->depositPercent
* 3 * sWorld
.getRate(RATE_AUCTION_DEPOSIT
) / 100.0f
);
75 void AuctionHouseMgr::SendAuctionWonMail( AuctionEntry
*auction
)
77 Item
*pItem
= GetAItem(auction
->item_guidlow
);
81 uint64 bidder_guid
= MAKE_NEW_GUID(auction
->bidder
, 0, HIGHGUID_PLAYER
);
82 Player
*bidder
= objmgr
.GetPlayer(bidder_guid
);
84 uint32 bidder_accId
= 0;
87 if( sWorld
.getConfig(CONFIG_GM_LOG_TRADE
) )
89 uint32 bidder_security
= 0;
90 std::string bidder_name
;
93 bidder_accId
= bidder
->GetSession()->GetAccountId();
94 bidder_security
= bidder
->GetSession()->GetSecurity();
95 bidder_name
= bidder
->GetName();
99 bidder_accId
= objmgr
.GetPlayerAccountIdByGUID(bidder_guid
);
100 bidder_security
= accmgr
.GetSecurity(bidder_accId
);
102 if(bidder_security
> SEC_PLAYER
) // not do redundant DB requests
104 if(!objmgr
.GetPlayerNameByGUID(bidder_guid
,bidder_name
))
105 bidder_name
= objmgr
.GetMangosStringForDBCLocale(LANG_UNKNOWN
);
109 if( bidder_security
> SEC_PLAYER
)
111 std::string owner_name
;
112 if(!objmgr
.GetPlayerNameByGUID(auction
->owner
,owner_name
))
113 owner_name
= objmgr
.GetMangosStringForDBCLocale(LANG_UNKNOWN
);
115 uint32 owner_accid
= objmgr
.GetPlayerAccountIdByGUID(auction
->owner
);
117 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)",
118 bidder_name
.c_str(),bidder_accId
,pItem
->GetProto()->Name1
,pItem
->GetEntry(),pItem
->GetCount(),auction
->bid
,owner_name
.c_str(),owner_accid
);
122 bidder_accId
= objmgr
.GetPlayerAccountIdByGUID(bidder_guid
);
125 if(bidder
|| bidder_accId
)
127 std::ostringstream msgAuctionWonSubject
;
128 msgAuctionWonSubject
<< auction
->item_template
<< ":0:" << AUCTION_WON
;
130 std::ostringstream msgAuctionWonBody
;
131 msgAuctionWonBody
.width(16);
132 msgAuctionWonBody
<< std::right
<< std::hex
<< auction
->owner
;
133 msgAuctionWonBody
<< std::dec
<< ":" << auction
->bid
<< ":" << auction
->buyout
;
134 sLog
.outDebug( "AuctionWon body string : %s", msgAuctionWonBody
.str().c_str() );
136 //prepare mail data... :
137 uint32 itemTextId
= objmgr
.CreateItemText( msgAuctionWonBody
.str() );
139 // set owner to bidder (to prevent delete item with sender char deleting)
140 // owner in `data` will set at mail receive and item extracting
141 CharacterDatabase
.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction
->bidder
,pItem
->GetGUIDLow());
142 CharacterDatabase
.CommitTransaction();
145 mi
.AddItem(auction
->item_guidlow
, auction
->item_template
, pItem
);
148 bidder
->GetSession()->SendAuctionBidderNotification( auction
->GetHouseId(), auction
->Id
, bidder_guid
, 0, 0, auction
->item_template
);
150 RemoveAItem(pItem
->GetGUIDLow()); // we have to remove the item, before we delete it !!
152 // will delete item or place to receiver mail list
153 WorldSession::SendMailTo(bidder
, MAIL_AUCTION
, MAIL_STATIONERY_AUCTION
, auction
->GetHouseId(), auction
->bidder
, msgAuctionWonSubject
.str(), itemTextId
, &mi
, 0, 0, MAIL_CHECK_MASK_AUCTION
);
155 // receiver not exist
158 CharacterDatabase
.PExecute("DELETE FROM item_instance WHERE guid='%u'", pItem
->GetGUIDLow());
159 RemoveAItem(pItem
->GetGUIDLow()); // we have to remove the item, before we delete it !!
164 void AuctionHouseMgr::SendAuctionSalePendingMail( AuctionEntry
* auction
)
166 uint64 owner_guid
= MAKE_NEW_GUID(auction
->owner
, 0, HIGHGUID_PLAYER
);
167 Player
*owner
= objmgr
.GetPlayer(owner_guid
);
169 // owner exist (online or offline)
170 if(owner
|| objmgr
.GetPlayerAccountIdByGUID(owner_guid
))
172 std::ostringstream msgAuctionSalePendingSubject
;
173 msgAuctionSalePendingSubject
<< auction
->item_template
<< ":0:" << AUCTION_SALE_PENDING
;
175 std::ostringstream msgAuctionSalePendingBody
;
176 uint32 auctionCut
= auction
->GetAuctionCut();
178 time_t distrTime
= time(NULL
) + HOUR
;
180 msgAuctionSalePendingBody
.width(16);
181 msgAuctionSalePendingBody
<< std::right
<< std::hex
<< auction
->bidder
;
182 msgAuctionSalePendingBody
<< std::dec
<< ":" << auction
->bid
<< ":" << auction
->buyout
;
183 msgAuctionSalePendingBody
<< ":" << auction
->deposit
<< ":" << auctionCut
<< ":0:";
184 msgAuctionSalePendingBody
<< secsToTimeBitFields(distrTime
);
186 sLog
.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody
.str().c_str());
188 uint32 itemTextId
= objmgr
.CreateItemText( msgAuctionSalePendingBody
.str() );
190 WorldSession::SendMailTo(owner
, MAIL_AUCTION
, MAIL_STATIONERY_AUCTION
, auction
->GetHouseId(), auction
->owner
, msgAuctionSalePendingSubject
.str(), itemTextId
, NULL
, 0, 0, MAIL_CHECK_MASK_AUCTION
);
194 //call this method to send mail to auction owner, when auction is successful, it does not clear ram
195 void AuctionHouseMgr::SendAuctionSuccessfulMail( AuctionEntry
* auction
)
197 uint64 owner_guid
= MAKE_NEW_GUID(auction
->owner
, 0, HIGHGUID_PLAYER
);
198 Player
*owner
= objmgr
.GetPlayer(owner_guid
);
200 uint32 owner_accId
= 0;
202 owner_accId
= objmgr
.GetPlayerAccountIdByGUID(owner_guid
);
205 if(owner
|| owner_accId
)
207 std::ostringstream msgAuctionSuccessfulSubject
;
208 msgAuctionSuccessfulSubject
<< auction
->item_template
<< ":0:" << AUCTION_SUCCESSFUL
;
210 std::ostringstream auctionSuccessfulBody
;
211 uint32 auctionCut
= auction
->GetAuctionCut();
213 auctionSuccessfulBody
.width(16);
214 auctionSuccessfulBody
<< std::right
<< std::hex
<< auction
->bidder
;
215 auctionSuccessfulBody
<< std::dec
<< ":" << auction
->bid
<< ":" << auction
->buyout
;
216 auctionSuccessfulBody
<< ":" << auction
->deposit
<< ":" << auctionCut
;
218 sLog
.outDebug("AuctionSuccessful body string : %s", auctionSuccessfulBody
.str().c_str());
220 uint32 itemTextId
= objmgr
.CreateItemText( auctionSuccessfulBody
.str() );
222 uint32 profit
= auction
->bid
+ auction
->deposit
- auctionCut
;
226 //FIXME: what do if owner offline
227 owner
->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD
, auction
->bid
);
228 //send auction owner notification, bidder must be current!
229 owner
->GetSession()->SendAuctionOwnerNotification( auction
);
232 WorldSession::SendMailTo(owner
, MAIL_AUCTION
, MAIL_STATIONERY_AUCTION
, auction
->GetHouseId(), auction
->owner
, msgAuctionSuccessfulSubject
.str(), itemTextId
, NULL
, profit
, 0, MAIL_CHECK_MASK_AUCTION
, HOUR
);
237 void AuctionHouseMgr::SendAuctionExpiredMail( AuctionEntry
* auction
)
238 { //return an item in auction to its owner by mail
239 Item
*pItem
= GetAItem(auction
->item_guidlow
);
242 sLog
.outError("Auction item (GUID: %u) not found, and lost.",auction
->item_guidlow
);
246 uint64 owner_guid
= MAKE_NEW_GUID(auction
->owner
, 0, HIGHGUID_PLAYER
);
247 Player
*owner
= objmgr
.GetPlayer(owner_guid
);
249 uint32 owner_accId
= 0;
251 owner_accId
= objmgr
.GetPlayerAccountIdByGUID(owner_guid
);
254 if(owner
|| owner_accId
)
256 std::ostringstream subject
;
257 subject
<< auction
->item_template
<< ":0:" << AUCTION_EXPIRED
;
260 owner
->GetSession()->SendAuctionOwnerNotification( auction
);
262 RemoveAItem(pItem
->GetGUIDLow()); // we have to remove the item, before we delete it !!
265 mi
.AddItem(auction
->item_guidlow
, auction
->item_template
, pItem
);
267 // will delete item or place to receiver mail list
268 WorldSession::SendMailTo(owner
, MAIL_AUCTION
, MAIL_STATIONERY_AUCTION
, auction
->GetHouseId(), GUID_LOPART(owner_guid
), subject
.str(), 0, &mi
, 0, 0, MAIL_CHECK_MASK_NONE
);
273 CharacterDatabase
.PExecute("DELETE FROM item_instance WHERE guid='%u'",pItem
->GetGUIDLow());
274 RemoveAItem(pItem
->GetGUIDLow()); // we have to remove the item, before we delete it !!
279 void AuctionHouseMgr::LoadAuctionItems()
281 // data needs to be at first place for Item::LoadFromDB
282 QueryResult
*result
= CharacterDatabase
.Query( "SELECT data,itemguid,item_template FROM auctionhouse JOIN item_instance ON itemguid = guid" );
289 sLog
.outString(">> Loaded 0 auction items");
293 barGoLink
bar( result
->GetRowCount() );
302 fields
= result
->Fetch();
303 uint32 item_guid
= fields
[1].GetUInt32();
304 uint32 item_template
= fields
[2].GetUInt32();
306 ItemPrototype
const *proto
= objmgr
.GetItemPrototype(item_template
);
310 sLog
.outError( "ObjectMgr::LoadAuctionItems: Unknown item (GUID: %u id: #%u) in auction, skipped.", item_guid
,item_template
);
314 Item
*item
= NewItemOrBag(proto
);
316 if(!item
->LoadFromDB(item_guid
,0, result
))
325 while( result
->NextRow() );
329 sLog
.outString( ">> Loaded %u auction items", count
);
332 void AuctionHouseMgr::LoadAuctions()
334 QueryResult
*result
= CharacterDatabase
.Query("SELECT COUNT(*) FROM auctionhouse");
340 sLog
.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
344 Field
*fields
= result
->Fetch();
345 uint32 AuctionCount
=fields
[0].GetUInt32();
353 sLog
.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
357 result
= CharacterDatabase
.Query( "SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit FROM auctionhouse" );
363 sLog
.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
367 barGoLink
bar( AuctionCount
);
373 fields
= result
->Fetch();
377 aItem
= new AuctionEntry
;
378 aItem
->Id
= fields
[0].GetUInt32();
379 aItem
->auctioneer
= fields
[1].GetUInt32();
380 aItem
->item_guidlow
= fields
[2].GetUInt32();
381 aItem
->item_template
= fields
[3].GetUInt32();
382 aItem
->owner
= fields
[4].GetUInt32();
383 aItem
->buyout
= fields
[5].GetUInt32();
384 aItem
->expire_time
= fields
[6].GetUInt32();
385 aItem
->bidder
= fields
[7].GetUInt32();
386 aItem
->bid
= fields
[8].GetUInt32();
387 aItem
->startbid
= fields
[9].GetUInt32();
388 aItem
->deposit
= fields
[10].GetUInt32();
390 CreatureData
const* auctioneerData
= objmgr
.GetCreatureData(aItem
->auctioneer
);
393 aItem
->DeleteFromDB();
394 sLog
.outError("Auction %u has not a existing auctioneer (GUID : %u)", aItem
->Id
, aItem
->auctioneer
);
399 CreatureInfo
const* auctioneerInfo
= objmgr
.GetCreatureTemplate(auctioneerData
->id
);
402 aItem
->DeleteFromDB();
403 sLog
.outError("Auction %u has not a existing auctioneer (GUID : %u Entry: %u)", aItem
->Id
, aItem
->auctioneer
,auctioneerData
->id
);
408 aItem
->auctionHouseEntry
= AuctionHouseMgr::GetAuctionHouseEntry(auctioneerInfo
->faction_A
);
409 if(!aItem
->auctionHouseEntry
)
411 aItem
->DeleteFromDB();
412 sLog
.outError("Auction %u has auctioneer (GUID : %u Entry: %u) with wrong faction %u",
413 aItem
->Id
, aItem
->auctioneer
,auctioneerData
->id
,auctioneerInfo
->faction_A
);
418 // check if sold item exists for guid
419 // and item_template in fact (GetAItem will fail if problematic in result check in ObjectMgr::LoadAuctionItems)
420 if ( !GetAItem( aItem
->item_guidlow
) )
422 aItem
->DeleteFromDB();
423 sLog
.outError("Auction %u has not a existing item : %u", aItem
->Id
, aItem
->item_guidlow
);
428 GetAuctionsMap( auctioneerInfo
->faction_A
)->AddAuction(aItem
);
430 } while (result
->NextRow());
434 sLog
.outString( ">> Loaded %u auctions", AuctionCount
);
437 void AuctionHouseMgr::AddAItem( Item
* it
)
440 ASSERT( mAitems
.find(it
->GetGUIDLow()) == mAitems
.end());
441 mAitems
[it
->GetGUIDLow()] = it
;
444 bool AuctionHouseMgr::RemoveAItem( uint32 id
)
446 ItemMap::iterator i
= mAitems
.find(id
);
447 if (i
== mAitems
.end())
455 void AuctionHouseMgr::Update()
457 mHordeAuctions
.Update();
458 mAllianceAuctions
.Update();
459 mNeutralAuctions
.Update();
462 AuctionHouseEntry
const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTemplateId
)
464 uint32 houseid
= 1; // dwarf auction house (used for normal cut/etc percents)
466 if(!sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION
))
468 //FIXME: found way for proper auctionhouse selection by another way
469 // AuctionHo use.dbc have faction field with _player_ factions associated with auction house races.
470 // but no easy way convert creature faction to player race faction for specific city
471 switch(factionTemplateId
)
473 case 12: houseid
= 1; break; // human
474 case 29: houseid
= 6; break; // orc, and generic for horde
475 case 55: houseid
= 2; break; // dwarf, and generic for alliance
476 case 68: houseid
= 4; break; // undead
477 case 80: houseid
= 3; break; // n-elf
478 case 104: houseid
= 5; break; // trolls
479 case 120: houseid
= 7; break; // booty bay, neutral
480 case 474: houseid
= 7; break; // gadgetzan, neutral
481 case 855: houseid
= 7; break; // everlook, neutral
482 case 1604: houseid
= 6; break; // b-elfs,
483 default: // for unknown case
485 FactionTemplateEntry
const* u_entry
= sFactionTemplateStore
.LookupEntry(factionTemplateId
);
487 houseid
= 7; // goblin auction house
488 else if(u_entry
->ourMask
& FACTION_MASK_ALLIANCE
)
489 houseid
= 1; // human auction house
490 else if(u_entry
->ourMask
& FACTION_MASK_HORDE
)
491 houseid
= 6; // orc auction house
493 houseid
= 7; // goblin auction house
499 return sAuctionHouseStore
.LookupEntry(houseid
);
502 void AuctionHouseObject::Update()
504 time_t curTime
= sWorld
.GetGameTime();
505 ///- Handle expired auctions
506 AuctionEntryMap::iterator next
;
507 for (AuctionEntryMap::iterator itr
= AuctionsMap
.begin(); itr
!= AuctionsMap
.end();itr
= next
)
511 if (curTime
> (itr
->second
->expire_time
))
513 ///- Either cancel the auction if there was no bidder
514 if (itr
->second
->bidder
== 0)
516 auctionmgr
.SendAuctionExpiredMail( itr
->second
);
518 ///- Or perform the transaction
521 //we should send an "item sold" message if the seller is online
522 //we send the item to the winner
523 //we send the money to the seller
524 auctionmgr
.SendAuctionSuccessfulMail( itr
->second
);
525 auctionmgr
.SendAuctionWonMail( itr
->second
);
528 ///- In any case clear the auction
529 itr
->second
->DeleteFromDB();
530 auctionmgr
.RemoveAItem(itr
->second
->item_guidlow
);
532 RemoveAuction(itr
->first
);
537 void AuctionHouseObject::BuildListBidderItems(WorldPacket
& data
, Player
* player
, uint32
& count
, uint32
& totalcount
)
539 for (AuctionEntryMap::const_iterator itr
= AuctionsMap
.begin();itr
!= AuctionsMap
.end();++itr
)
541 AuctionEntry
*Aentry
= itr
->second
;
542 if( Aentry
&& Aentry
->bidder
== player
->GetGUIDLow() )
544 if (itr
->second
->BuildAuctionInfo(data
))
551 void AuctionHouseObject::BuildListOwnerItems(WorldPacket
& data
, Player
* player
, uint32
& count
, uint32
& totalcount
)
553 for (AuctionEntryMap::const_iterator itr
= AuctionsMap
.begin();itr
!= AuctionsMap
.end();++itr
)
555 AuctionEntry
*Aentry
= itr
->second
;
556 if( Aentry
&& Aentry
->owner
== player
->GetGUIDLow() )
558 if(Aentry
->BuildAuctionInfo(data
))
565 void AuctionHouseObject::BuildListAuctionItems(WorldPacket
& data
, Player
* player
,
566 std::wstring
const& wsearchedname
, uint32 listfrom
, uint32 levelmin
, uint32 levelmax
, uint32 usable
,
567 uint32 inventoryType
, uint32 itemClass
, uint32 itemSubClass
, uint32 quality
,
568 uint32
& count
, uint32
& totalcount
)
570 int loc_idx
= player
->GetSession()->GetSessionDbLocaleIndex();
572 for (AuctionEntryMap::const_iterator itr
= AuctionsMap
.begin();itr
!= AuctionsMap
.end();++itr
)
574 AuctionEntry
*Aentry
= itr
->second
;
575 Item
*item
= auctionmgr
.GetAItem(Aentry
->item_guidlow
);
579 ItemPrototype
const *proto
= item
->GetProto();
581 if (itemClass
!= 0xffffffff && proto
->Class
!= itemClass
)
584 if (itemSubClass
!= 0xffffffff && proto
->SubClass
!= itemSubClass
)
587 if (inventoryType
!= 0xffffffff && proto
->InventoryType
!= inventoryType
)
590 if (quality
!= 0xffffffff && proto
->Quality
!= quality
)
593 if (levelmin
!= 0x00 && (proto
->RequiredLevel
< levelmin
|| (levelmax
!= 0x00 && proto
->RequiredLevel
> levelmax
)))
596 if (usable
!= 0x00 && player
->CanUseItem( item
) != EQUIP_ERR_OK
)
599 std::string name
= proto
->Name1
;
606 ItemLocale
const *il
= objmgr
.GetItemLocale(proto
->ItemId
);
609 if (il
->Name
.size() > size_t(loc_idx
) && !il
->Name
[loc_idx
].empty())
610 name
= il
->Name
[loc_idx
];
614 if (!wsearchedname
.empty() && !Utf8FitTo(name
, wsearchedname
) )
617 if (count
< 50 && totalcount
>= listfrom
)
620 Aentry
->BuildAuctionInfo(data
);
626 //this function inserts to WorldPacket auction's data
627 bool AuctionEntry::BuildAuctionInfo(WorldPacket
& data
) const
629 Item
*pItem
= auctionmgr
.GetAItem(item_guidlow
);
632 sLog
.outError("auction to item, that doesn't exist !!!!");
636 data
<< uint32(pItem
->GetEntry());
638 for (uint8 i
= 0; i
< MAX_INSPECTED_ENCHANTMENT_SLOT
; ++i
)
640 data
<< uint32(pItem
->GetEnchantmentId(EnchantmentSlot(i
)));
641 data
<< uint32(pItem
->GetEnchantmentDuration(EnchantmentSlot(i
)));
642 data
<< uint32(pItem
->GetEnchantmentCharges(EnchantmentSlot(i
)));
645 data
<< uint32(pItem
->GetItemRandomPropertyId()); //random item property id
646 data
<< uint32(pItem
->GetItemSuffixFactor()); //SuffixFactor
647 data
<< uint32(pItem
->GetCount()); //item->count
648 data
<< uint32(pItem
->GetSpellCharges()); //item->charge FFFFFFF
649 data
<< uint32(0); //Unknown
650 data
<< uint64(owner
); //Auction->owner
651 data
<< uint32(startbid
); //Auction->startbid (not sure if useful)
652 data
<< uint32(bid
? GetAuctionOutBid() : 0);
654 data
<< uint32(buyout
); //auction->buyout
655 data
<< uint32((expire_time
-time(NULL
))*IN_MILISECONDS
);//time left
656 data
<< uint64(bidder
) ; //auction->bidder current
657 data
<< uint32(bid
); //current bid
661 uint32
AuctionEntry::GetAuctionCut() const
663 return uint32(auctionHouseEntry
->cutPercent
* bid
* sWorld
.getRate(RATE_AUCTION_CUT
) / 100.0f
);
666 /// the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c
667 uint32
AuctionEntry::GetAuctionOutBid() const
669 uint32 outbid
= (bid
/ 100) * 5;
675 void AuctionEntry::DeleteFromDB() const
677 //No SQL injection (Id is integer)
678 CharacterDatabase
.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",Id
);
681 void AuctionEntry::SaveToDB() const
683 //No SQL injection (no strings)
684 CharacterDatabase
.PExecute("INSERT INTO auctionhouse (id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit) "
685 "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '" UI64FMTD
"', '%u', '%u', '%u', '%u')",
686 Id
, auctioneer
, item_guidlow
, item_template
, owner
, buyout
, (uint64
)expire_time
, bidder
, bid
, startbid
, deposit
);