2 * Copyright (C) 2005-2010 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"
31 #include "ObjectDefines.h"
34 #include "WorldPacket.h"
35 #include "WorldSession.h"
37 #include "Policies/SingletonImp.h"
39 INSTANTIATE_SINGLETON_1( AuctionHouseMgr
);
41 AuctionHouseMgr::AuctionHouseMgr()
45 AuctionHouseMgr::~AuctionHouseMgr()
47 for(ItemMap::const_iterator itr
= mAitems
.begin(); itr
!= mAitems
.end(); ++itr
)
51 AuctionHouseObject
* AuctionHouseMgr::GetAuctionsMap( uint32 factionTemplateId
)
53 if(sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION
))
54 return &mNeutralAuctions
;
56 // team have linked auction houses
57 FactionTemplateEntry
const* u_entry
= sFactionTemplateStore
.LookupEntry(factionTemplateId
);
59 return &mNeutralAuctions
;
60 else if(u_entry
->ourMask
& FACTION_MASK_ALLIANCE
)
61 return &mAllianceAuctions
;
62 else if(u_entry
->ourMask
& FACTION_MASK_HORDE
)
63 return &mHordeAuctions
;
65 return &mNeutralAuctions
;
68 uint32
AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry
const* entry
, uint32 time
, Item
*pItem
)
70 uint32 deposit
= pItem
->GetProto()->SellPrice
* pItem
->GetCount() * (time
/ MIN_AUCTION_TIME
);
72 return uint32(deposit
* entry
->depositPercent
* 3 * sWorld
.getRate(RATE_AUCTION_DEPOSIT
) / 100.0f
);
76 void AuctionHouseMgr::SendAuctionWonMail( AuctionEntry
*auction
)
78 Item
*pItem
= GetAItem(auction
->item_guidlow
);
82 uint64 bidder_guid
= MAKE_NEW_GUID(auction
->bidder
, 0, HIGHGUID_PLAYER
);
83 Player
*bidder
= sObjectMgr
.GetPlayer(bidder_guid
);
85 uint32 bidder_accId
= 0;
88 if( sWorld
.getConfig(CONFIG_GM_LOG_TRADE
) )
90 uint32 bidder_security
= 0;
91 std::string bidder_name
;
94 bidder_accId
= bidder
->GetSession()->GetAccountId();
95 bidder_security
= bidder
->GetSession()->GetSecurity();
96 bidder_name
= bidder
->GetName();
100 bidder_accId
= sObjectMgr
.GetPlayerAccountIdByGUID(bidder_guid
);
101 bidder_security
= sAccountMgr
.GetSecurity(bidder_accId
);
103 if(bidder_security
> SEC_PLAYER
) // not do redundant DB requests
105 if(!sObjectMgr
.GetPlayerNameByGUID(bidder_guid
,bidder_name
))
106 bidder_name
= sObjectMgr
.GetMangosStringForDBCLocale(LANG_UNKNOWN
);
110 if( bidder_security
> SEC_PLAYER
)
112 std::string owner_name
;
113 if(!sObjectMgr
.GetPlayerNameByGUID(auction
->owner
,owner_name
))
114 owner_name
= sObjectMgr
.GetMangosStringForDBCLocale(LANG_UNKNOWN
);
116 uint32 owner_accid
= sObjectMgr
.GetPlayerAccountIdByGUID(auction
->owner
);
118 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)",
119 bidder_name
.c_str(),bidder_accId
,pItem
->GetProto()->Name1
,pItem
->GetEntry(),pItem
->GetCount(),auction
->bid
,owner_name
.c_str(),owner_accid
);
123 bidder_accId
= sObjectMgr
.GetPlayerAccountIdByGUID(bidder_guid
);
126 if(bidder
|| bidder_accId
)
128 std::ostringstream msgAuctionWonSubject
;
129 msgAuctionWonSubject
<< auction
->item_template
<< ":0:" << AUCTION_WON
;
131 std::ostringstream msgAuctionWonBody
;
132 msgAuctionWonBody
.width(16);
133 msgAuctionWonBody
<< std::right
<< std::hex
<< auction
->owner
;
134 msgAuctionWonBody
<< std::dec
<< ":" << auction
->bid
<< ":" << auction
->buyout
;
135 sLog
.outDebug( "AuctionWon body string : %s", msgAuctionWonBody
.str().c_str() );
137 //prepare mail data... :
138 uint32 itemTextId
= sObjectMgr
.CreateItemText( msgAuctionWonBody
.str() );
140 // set owner to bidder (to prevent delete item with sender char deleting)
141 // owner in `data` will set at mail receive and item extracting
142 CharacterDatabase
.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction
->bidder
,pItem
->GetGUIDLow());
143 CharacterDatabase
.CommitTransaction();
146 bidder
->GetSession()->SendAuctionBidderNotification( auction
->GetHouseId(), auction
->Id
, bidder_guid
, 0, 0, auction
->item_template
);
148 RemoveAItem(pItem
->GetGUIDLow()); // we have to remove the item, before we delete it !!
150 // will delete item or place to receiver mail list
151 MailDraft(msgAuctionWonSubject
.str(), itemTextId
)
153 .SendMailTo(MailReceiver(bidder
,auction
->bidder
), auction
, 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
= sObjectMgr
.GetPlayer(owner_guid
);
169 // owner exist (online or offline)
170 if(owner
|| sObjectMgr
.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
= sObjectMgr
.CreateItemText( msgAuctionSalePendingBody
.str() );
190 MailDraft(msgAuctionSalePendingSubject
.str(), itemTextId
)
191 .SendMailTo(MailReceiver(owner
,auction
->owner
), auction
, MAIL_CHECK_MASK_AUCTION
);
195 //call this method to send mail to auction owner, when auction is successful, it does not clear ram
196 void AuctionHouseMgr::SendAuctionSuccessfulMail( AuctionEntry
* auction
)
198 uint64 owner_guid
= MAKE_NEW_GUID(auction
->owner
, 0, HIGHGUID_PLAYER
);
199 Player
*owner
= sObjectMgr
.GetPlayer(owner_guid
);
201 uint32 owner_accId
= 0;
203 owner_accId
= sObjectMgr
.GetPlayerAccountIdByGUID(owner_guid
);
206 if(owner
|| owner_accId
)
208 std::ostringstream msgAuctionSuccessfulSubject
;
209 msgAuctionSuccessfulSubject
<< auction
->item_template
<< ":0:" << AUCTION_SUCCESSFUL
;
211 std::ostringstream auctionSuccessfulBody
;
212 uint32 auctionCut
= auction
->GetAuctionCut();
214 auctionSuccessfulBody
.width(16);
215 auctionSuccessfulBody
<< std::right
<< std::hex
<< auction
->bidder
;
216 auctionSuccessfulBody
<< std::dec
<< ":" << auction
->bid
<< ":" << auction
->buyout
;
217 auctionSuccessfulBody
<< ":" << auction
->deposit
<< ":" << auctionCut
;
219 sLog
.outDebug("AuctionSuccessful body string : %s", auctionSuccessfulBody
.str().c_str());
221 uint32 itemTextId
= sObjectMgr
.CreateItemText( auctionSuccessfulBody
.str() );
223 uint32 profit
= auction
->bid
+ auction
->deposit
- auctionCut
;
227 //FIXME: what do if owner offline
228 owner
->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD
, auction
->bid
);
229 //send auction owner notification, bidder must be current!
230 owner
->GetSession()->SendAuctionOwnerNotification( auction
);
233 MailDraft(msgAuctionSuccessfulSubject
.str(), itemTextId
)
235 .SendMailTo(MailReceiver(owner
,auction
->owner
), auction
, MAIL_CHECK_MASK_AUCTION
, HOUR
);
240 void AuctionHouseMgr::SendAuctionExpiredMail( AuctionEntry
* auction
)
241 { //return an item in auction to its owner by mail
242 Item
*pItem
= GetAItem(auction
->item_guidlow
);
245 sLog
.outError("Auction item (GUID: %u) not found, and lost.",auction
->item_guidlow
);
249 uint64 owner_guid
= MAKE_NEW_GUID(auction
->owner
, 0, HIGHGUID_PLAYER
);
250 Player
*owner
= sObjectMgr
.GetPlayer(owner_guid
);
252 uint32 owner_accId
= 0;
254 owner_accId
= sObjectMgr
.GetPlayerAccountIdByGUID(owner_guid
);
257 if(owner
|| owner_accId
)
259 std::ostringstream subject
;
260 subject
<< auction
->item_template
<< ":0:" << AUCTION_EXPIRED
;
263 owner
->GetSession()->SendAuctionOwnerNotification( auction
);
265 RemoveAItem(pItem
->GetGUIDLow()); // we have to remove the item, before we delete it !!
267 // will delete item or place to receiver mail list
268 MailDraft(subject
.str())
270 .SendMailTo(MailReceiver(owner
,auction
->owner
), auction
);
275 CharacterDatabase
.PExecute("DELETE FROM item_instance WHERE guid='%u'",pItem
->GetGUIDLow());
276 RemoveAItem(pItem
->GetGUIDLow()); // we have to remove the item, before we delete it !!
281 void AuctionHouseMgr::LoadAuctionItems()
283 // data needs to be at first place for Item::LoadFromDB
284 QueryResult
*result
= CharacterDatabase
.Query( "SELECT data,itemguid,item_template FROM auctionhouse JOIN item_instance ON itemguid = guid" );
291 sLog
.outString(">> Loaded 0 auction items");
295 barGoLink
bar( result
->GetRowCount() );
304 fields
= result
->Fetch();
305 uint32 item_guid
= fields
[1].GetUInt32();
306 uint32 item_template
= fields
[2].GetUInt32();
308 ItemPrototype
const *proto
= ObjectMgr::GetItemPrototype(item_template
);
312 sLog
.outError( "AuctionHouseMgr::LoadAuctionItems: Unknown item (GUID: %u id: #%u) in auction, skipped.", item_guid
,item_template
);
316 Item
*item
= NewItemOrBag(proto
);
318 if(!item
->LoadFromDB(item_guid
,0, result
))
327 while( result
->NextRow() );
331 sLog
.outString( ">> Loaded %u auction items", count
);
334 void AuctionHouseMgr::LoadAuctions()
336 QueryResult
*result
= CharacterDatabase
.Query("SELECT COUNT(*) FROM auctionhouse");
342 sLog
.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
346 Field
*fields
= result
->Fetch();
347 uint32 AuctionCount
=fields
[0].GetUInt32();
355 sLog
.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
359 result
= CharacterDatabase
.Query( "SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit FROM auctionhouse" );
365 sLog
.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
369 barGoLink
bar( AuctionCount
);
375 fields
= result
->Fetch();
379 aItem
= new AuctionEntry
;
380 aItem
->Id
= fields
[0].GetUInt32();
381 aItem
->auctioneer
= fields
[1].GetUInt32();
382 aItem
->item_guidlow
= fields
[2].GetUInt32();
383 aItem
->item_template
= fields
[3].GetUInt32();
384 aItem
->owner
= fields
[4].GetUInt32();
385 aItem
->buyout
= fields
[5].GetUInt32();
386 aItem
->expire_time
= fields
[6].GetUInt32();
387 aItem
->bidder
= fields
[7].GetUInt32();
388 aItem
->bid
= fields
[8].GetUInt32();
389 aItem
->startbid
= fields
[9].GetUInt32();
390 aItem
->deposit
= fields
[10].GetUInt32();
392 CreatureData
const* auctioneerData
= sObjectMgr
.GetCreatureData(aItem
->auctioneer
);
395 aItem
->DeleteFromDB();
396 sLog
.outError("Auction %u has not a existing auctioneer (GUID : %u)", aItem
->Id
, aItem
->auctioneer
);
401 CreatureInfo
const* auctioneerInfo
= ObjectMgr::GetCreatureTemplate(auctioneerData
->id
);
404 aItem
->DeleteFromDB();
405 sLog
.outError("Auction %u has not a existing auctioneer (GUID : %u Entry: %u)", aItem
->Id
, aItem
->auctioneer
,auctioneerData
->id
);
410 aItem
->auctionHouseEntry
= AuctionHouseMgr::GetAuctionHouseEntry(auctioneerInfo
->faction_A
);
411 if(!aItem
->auctionHouseEntry
)
413 aItem
->DeleteFromDB();
414 sLog
.outError("Auction %u has auctioneer (GUID : %u Entry: %u) with wrong faction %u",
415 aItem
->Id
, aItem
->auctioneer
,auctioneerData
->id
,auctioneerInfo
->faction_A
);
420 // check if sold item exists for guid
421 // and item_template in fact (GetAItem will fail if problematic in result check in AuctionHouseMgr::LoadAuctionItems)
422 if ( !GetAItem( aItem
->item_guidlow
) )
424 aItem
->DeleteFromDB();
425 sLog
.outError("Auction %u has not a existing item : %u", aItem
->Id
, aItem
->item_guidlow
);
430 GetAuctionsMap( auctioneerInfo
->faction_A
)->AddAuction(aItem
);
432 } while (result
->NextRow());
436 sLog
.outString( ">> Loaded %u auctions", AuctionCount
);
439 void AuctionHouseMgr::AddAItem( Item
* it
)
442 ASSERT( mAitems
.find(it
->GetGUIDLow()) == mAitems
.end());
443 mAitems
[it
->GetGUIDLow()] = it
;
446 bool AuctionHouseMgr::RemoveAItem( uint32 id
)
448 ItemMap::iterator i
= mAitems
.find(id
);
449 if (i
== mAitems
.end())
457 void AuctionHouseMgr::Update()
459 mHordeAuctions
.Update();
460 mAllianceAuctions
.Update();
461 mNeutralAuctions
.Update();
464 AuctionHouseEntry
const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTemplateId
)
466 uint32 houseid
= 1; // dwarf auction house (used for normal cut/etc percents)
468 if(!sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION
))
470 //FIXME: found way for proper auctionhouse selection by another way
471 // AuctionHo use.dbc have faction field with _player_ factions associated with auction house races.
472 // but no easy way convert creature faction to player race faction for specific city
473 switch(factionTemplateId
)
475 case 12: houseid
= 1; break; // human
476 case 29: houseid
= 6; break; // orc, and generic for horde
477 case 55: houseid
= 2; break; // dwarf, and generic for alliance
478 case 68: houseid
= 4; break; // undead
479 case 80: houseid
= 3; break; // n-elf
480 case 104: houseid
= 5; break; // trolls
481 case 120: houseid
= 7; break; // booty bay, neutral
482 case 474: houseid
= 7; break; // gadgetzan, neutral
483 case 855: houseid
= 7; break; // everlook, neutral
484 case 1604: houseid
= 6; break; // b-elfs,
485 default: // for unknown case
487 FactionTemplateEntry
const* u_entry
= sFactionTemplateStore
.LookupEntry(factionTemplateId
);
489 houseid
= 7; // goblin auction house
490 else if(u_entry
->ourMask
& FACTION_MASK_ALLIANCE
)
491 houseid
= 1; // human auction house
492 else if(u_entry
->ourMask
& FACTION_MASK_HORDE
)
493 houseid
= 6; // orc auction house
495 houseid
= 7; // goblin auction house
501 return sAuctionHouseStore
.LookupEntry(houseid
);
504 void AuctionHouseObject::Update()
506 time_t curTime
= sWorld
.GetGameTime();
507 ///- Handle expired auctions
508 AuctionEntryMap::iterator next
;
509 for (AuctionEntryMap::iterator itr
= AuctionsMap
.begin(); itr
!= AuctionsMap
.end();itr
= next
)
513 if (curTime
> (itr
->second
->expire_time
))
515 ///- Either cancel the auction if there was no bidder
516 if (itr
->second
->bidder
== 0)
518 sAuctionMgr
.SendAuctionExpiredMail( itr
->second
);
520 ///- Or perform the transaction
523 //we should send an "item sold" message if the seller is online
524 //we send the item to the winner
525 //we send the money to the seller
526 sAuctionMgr
.SendAuctionSuccessfulMail( itr
->second
);
527 sAuctionMgr
.SendAuctionWonMail( itr
->second
);
530 ///- In any case clear the auction
531 itr
->second
->DeleteFromDB();
532 sAuctionMgr
.RemoveAItem(itr
->second
->item_guidlow
);
534 RemoveAuction(itr
->first
);
539 void AuctionHouseObject::BuildListBidderItems(WorldPacket
& data
, Player
* player
, uint32
& count
, uint32
& totalcount
)
541 for (AuctionEntryMap::const_iterator itr
= AuctionsMap
.begin();itr
!= AuctionsMap
.end();++itr
)
543 AuctionEntry
*Aentry
= itr
->second
;
544 if( Aentry
&& Aentry
->bidder
== player
->GetGUIDLow() )
546 if (itr
->second
->BuildAuctionInfo(data
))
553 void AuctionHouseObject::BuildListOwnerItems(WorldPacket
& data
, Player
* player
, uint32
& count
, uint32
& totalcount
)
555 for (AuctionEntryMap::const_iterator itr
= AuctionsMap
.begin();itr
!= AuctionsMap
.end();++itr
)
557 AuctionEntry
*Aentry
= itr
->second
;
558 if( Aentry
&& Aentry
->owner
== player
->GetGUIDLow() )
560 if(Aentry
->BuildAuctionInfo(data
))
567 void AuctionHouseObject::BuildListAuctionItems(WorldPacket
& data
, Player
* player
,
568 std::wstring
const& wsearchedname
, uint32 listfrom
, uint32 levelmin
, uint32 levelmax
, uint32 usable
,
569 uint32 inventoryType
, uint32 itemClass
, uint32 itemSubClass
, uint32 quality
,
570 uint32
& count
, uint32
& totalcount
)
572 int loc_idx
= player
->GetSession()->GetSessionDbLocaleIndex();
574 for (AuctionEntryMap::const_iterator itr
= AuctionsMap
.begin();itr
!= AuctionsMap
.end();++itr
)
576 AuctionEntry
*Aentry
= itr
->second
;
577 Item
*item
= sAuctionMgr
.GetAItem(Aentry
->item_guidlow
);
581 ItemPrototype
const *proto
= item
->GetProto();
583 if (itemClass
!= 0xffffffff && proto
->Class
!= itemClass
)
586 if (itemSubClass
!= 0xffffffff && proto
->SubClass
!= itemSubClass
)
589 if (inventoryType
!= 0xffffffff && proto
->InventoryType
!= inventoryType
)
592 if (quality
!= 0xffffffff && proto
->Quality
!= quality
)
595 if (levelmin
!= 0x00 && (proto
->RequiredLevel
< levelmin
|| (levelmax
!= 0x00 && proto
->RequiredLevel
> levelmax
)))
598 if (usable
!= 0x00 && player
->CanUseItem( item
) != EQUIP_ERR_OK
)
601 std::string name
= proto
->Name1
;
608 ItemLocale
const *il
= sObjectMgr
.GetItemLocale(proto
->ItemId
);
611 if (il
->Name
.size() > size_t(loc_idx
) && !il
->Name
[loc_idx
].empty())
612 name
= il
->Name
[loc_idx
];
616 if (!wsearchedname
.empty() && !Utf8FitTo(name
, wsearchedname
) )
619 if (count
< 50 && totalcount
>= listfrom
)
622 Aentry
->BuildAuctionInfo(data
);
628 //this function inserts to WorldPacket auction's data
629 bool AuctionEntry::BuildAuctionInfo(WorldPacket
& data
) const
631 Item
*pItem
= sAuctionMgr
.GetAItem(item_guidlow
);
634 sLog
.outError("auction to item, that doesn't exist !!!!");
638 data
<< uint32(pItem
->GetEntry());
640 for (uint8 i
= 0; i
< MAX_INSPECTED_ENCHANTMENT_SLOT
; ++i
)
642 data
<< uint32(pItem
->GetEnchantmentId(EnchantmentSlot(i
)));
643 data
<< uint32(pItem
->GetEnchantmentDuration(EnchantmentSlot(i
)));
644 data
<< uint32(pItem
->GetEnchantmentCharges(EnchantmentSlot(i
)));
647 data
<< uint32(pItem
->GetItemRandomPropertyId()); //random item property id
648 data
<< uint32(pItem
->GetItemSuffixFactor()); //SuffixFactor
649 data
<< uint32(pItem
->GetCount()); //item->count
650 data
<< uint32(pItem
->GetSpellCharges()); //item->charge FFFFFFF
651 data
<< uint32(0); //Unknown
652 data
<< uint64(owner
); //Auction->owner
653 data
<< uint32(startbid
); //Auction->startbid (not sure if useful)
654 data
<< uint32(bid
? GetAuctionOutBid() : 0);
656 data
<< uint32(buyout
); //auction->buyout
657 data
<< uint32((expire_time
-time(NULL
))*IN_MILISECONDS
);//time left
658 data
<< uint64(bidder
) ; //auction->bidder current
659 data
<< uint32(bid
); //current bid
663 uint32
AuctionEntry::GetAuctionCut() const
665 return uint32(auctionHouseEntry
->cutPercent
* bid
* sWorld
.getRate(RATE_AUCTION_CUT
) / 100.0f
);
668 /// the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c
669 uint32
AuctionEntry::GetAuctionOutBid() const
671 uint32 outbid
= (bid
/ 100) * 5;
677 void AuctionEntry::DeleteFromDB() const
679 //No SQL injection (Id is integer)
680 CharacterDatabase
.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",Id
);
683 void AuctionEntry::SaveToDB() const
685 //No SQL injection (no strings)
686 CharacterDatabase
.PExecute("INSERT INTO auctionhouse (id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit) "
687 "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '" UI64FMTD
"', '%u', '%u', '%u', '%u')",
688 Id
, auctioneer
, item_guidlow
, item_template
, owner
, buyout
, (uint64
)expire_time
, bidder
, bid
, startbid
, deposit
);