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/DBCStores.h"
22 #include "Database/SQLStorage.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::iterator itr
= mAitems
.begin(); itr
!= mAitems
.end(); ++itr
)
50 AuctionHouseObject
* AuctionHouseMgr::GetAuctionsMap( uint32 factionTemplateId
)
52 // team have linked auction houses
53 FactionTemplateEntry
const* u_entry
= sFactionTemplateStore
.LookupEntry(factionTemplateId
);
55 return &mNeutralAuctions
;
56 else if(u_entry
->ourMask
& FACTION_MASK_ALLIANCE
)
57 return &mAllianceAuctions
;
58 else if(u_entry
->ourMask
& FACTION_MASK_HORDE
)
59 return &mHordeAuctions
;
61 return &mNeutralAuctions
;
64 uint32
AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry
const* entry
, uint32 time
, Item
*pItem
)
66 uint32 deposit
= pItem
->GetProto()->SellPrice
* pItem
->GetCount() * (time
/ MIN_AUCTION_TIME
);
68 return uint32(deposit
* entry
->depositPercent
* 3 * sWorld
.getRate(RATE_AUCTION_DEPOSIT
) / 100.0f
);
72 void AuctionHouseMgr::SendAuctionWonMail( AuctionEntry
*auction
)
74 Item
*pItem
= GetAItem(auction
->item_guidlow
);
78 uint64 bidder_guid
= MAKE_NEW_GUID(auction
->bidder
, 0, HIGHGUID_PLAYER
);
79 Player
*bidder
= objmgr
.GetPlayer(bidder_guid
);
81 uint32 bidder_accId
= 0;
84 if( sWorld
.getConfig(CONFIG_GM_LOG_TRADE
) )
86 uint32 bidder_security
= 0;
87 std::string bidder_name
;
90 bidder_accId
= bidder
->GetSession()->GetAccountId();
91 bidder_security
= bidder
->GetSession()->GetSecurity();
92 bidder_name
= bidder
->GetName();
96 bidder_accId
= objmgr
.GetPlayerAccountIdByGUID(bidder_guid
);
97 bidder_security
= accmgr
.GetSecurity(bidder_accId
);
99 if(bidder_security
> SEC_PLAYER
) // not do redundant DB requests
101 if(!objmgr
.GetPlayerNameByGUID(bidder_guid
,bidder_name
))
102 bidder_name
= objmgr
.GetMangosStringForDBCLocale(LANG_UNKNOWN
);
106 if( bidder_security
> SEC_PLAYER
)
108 std::string owner_name
;
109 if(!objmgr
.GetPlayerNameByGUID(auction
->owner
,owner_name
))
110 owner_name
= objmgr
.GetMangosStringForDBCLocale(LANG_UNKNOWN
);
112 uint32 owner_accid
= objmgr
.GetPlayerAccountIdByGUID(auction
->owner
);
114 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)",
115 bidder_name
.c_str(),bidder_accId
,pItem
->GetProto()->Name1
,pItem
->GetEntry(),pItem
->GetCount(),auction
->bid
,owner_name
.c_str(),owner_accid
);
119 bidder_accId
= objmgr
.GetPlayerAccountIdByGUID(bidder_guid
);
122 if(bidder
|| bidder_accId
)
124 std::ostringstream msgAuctionWonSubject
;
125 msgAuctionWonSubject
<< auction
->item_template
<< ":0:" << AUCTION_WON
;
127 std::ostringstream msgAuctionWonBody
;
128 msgAuctionWonBody
.width(16);
129 msgAuctionWonBody
<< std::right
<< std::hex
<< auction
->owner
;
130 msgAuctionWonBody
<< std::dec
<< ":" << auction
->bid
<< ":" << auction
->buyout
;
131 sLog
.outDebug( "AuctionWon body string : %s", msgAuctionWonBody
.str().c_str() );
133 //prepare mail data... :
134 uint32 itemTextId
= objmgr
.CreateItemText( msgAuctionWonBody
.str() );
136 // set owner to bidder (to prevent delete item with sender char deleting)
137 // owner in `data` will set at mail receive and item extracting
138 CharacterDatabase
.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction
->bidder
,pItem
->GetGUIDLow());
139 CharacterDatabase
.CommitTransaction();
142 mi
.AddItem(auction
->item_guidlow
, auction
->item_template
, pItem
);
145 bidder
->GetSession()->SendAuctionBidderNotification( auction
->GetHouseId(), auction
->Id
, bidder_guid
, 0, 0, auction
->item_template
);
147 RemoveAItem(pItem
->GetGUIDLow()); // we have to remove the item, before we delete it !!
149 // will delete item or place to receiver mail list
150 WorldSession::SendMailTo(bidder
, MAIL_AUCTION
, MAIL_STATIONERY_AUCTION
, auction
->GetHouseId(), auction
->bidder
, msgAuctionWonSubject
.str(), itemTextId
, &mi
, 0, 0, MAIL_CHECK_MASK_AUCTION
);
152 // receiver not exist
155 CharacterDatabase
.PExecute("DELETE FROM item_instance WHERE guid='%u'", pItem
->GetGUIDLow());
156 RemoveAItem(pItem
->GetGUIDLow()); // we have to remove the item, before we delete it !!
161 void AuctionHouseMgr::SendAuctionSalePendingMail( AuctionEntry
* auction
)
163 uint64 owner_guid
= MAKE_NEW_GUID(auction
->owner
, 0, HIGHGUID_PLAYER
);
164 Player
*owner
= objmgr
.GetPlayer(owner_guid
);
166 // owner exist (online or offline)
167 if(owner
|| objmgr
.GetPlayerAccountIdByGUID(owner_guid
))
169 std::ostringstream msgAuctionSalePendingSubject
;
170 msgAuctionSalePendingSubject
<< auction
->item_template
<< ":0:" << AUCTION_SALE_PENDING
;
172 std::ostringstream msgAuctionSalePendingBody
;
173 uint32 auctionCut
= auction
->GetAuctionCut();
175 time_t distrTime
= time(NULL
) + HOUR
;
177 msgAuctionSalePendingBody
.width(16);
178 msgAuctionSalePendingBody
<< std::right
<< std::hex
<< auction
->bidder
;
179 msgAuctionSalePendingBody
<< std::dec
<< ":" << auction
->bid
<< ":" << auction
->buyout
;
180 msgAuctionSalePendingBody
<< ":" << auction
->deposit
<< ":" << auctionCut
<< ":0:";
181 msgAuctionSalePendingBody
<< secsToTimeBitFields(distrTime
);
183 sLog
.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody
.str().c_str());
185 uint32 itemTextId
= objmgr
.CreateItemText( msgAuctionSalePendingBody
.str() );
187 WorldSession::SendMailTo(owner
, MAIL_AUCTION
, MAIL_STATIONERY_AUCTION
, auction
->GetHouseId(), auction
->owner
, msgAuctionSalePendingSubject
.str(), itemTextId
, NULL
, 0, 0, MAIL_CHECK_MASK_AUCTION
);
191 //call this method to send mail to auction owner, when auction is successful, it does not clear ram
192 void AuctionHouseMgr::SendAuctionSuccessfulMail( AuctionEntry
* auction
)
194 uint64 owner_guid
= MAKE_NEW_GUID(auction
->owner
, 0, HIGHGUID_PLAYER
);
195 Player
*owner
= objmgr
.GetPlayer(owner_guid
);
197 uint32 owner_accId
= 0;
199 owner_accId
= objmgr
.GetPlayerAccountIdByGUID(owner_guid
);
202 if(owner
|| owner_accId
)
204 std::ostringstream msgAuctionSuccessfulSubject
;
205 msgAuctionSuccessfulSubject
<< auction
->item_template
<< ":0:" << AUCTION_SUCCESSFUL
;
207 std::ostringstream auctionSuccessfulBody
;
208 uint32 auctionCut
= auction
->GetAuctionCut();
210 auctionSuccessfulBody
.width(16);
211 auctionSuccessfulBody
<< std::right
<< std::hex
<< auction
->bidder
;
212 auctionSuccessfulBody
<< std::dec
<< ":" << auction
->bid
<< ":" << auction
->buyout
;
213 auctionSuccessfulBody
<< ":" << auction
->deposit
<< ":" << auctionCut
;
215 sLog
.outDebug("AuctionSuccessful body string : %s", auctionSuccessfulBody
.str().c_str());
217 uint32 itemTextId
= objmgr
.CreateItemText( auctionSuccessfulBody
.str() );
219 uint32 profit
= auction
->bid
+ auction
->deposit
- auctionCut
;
223 //send auction owner notification, bidder must be current!
224 owner
->GetSession()->SendAuctionOwnerNotification( auction
);
227 WorldSession::SendMailTo(owner
, MAIL_AUCTION
, MAIL_STATIONERY_AUCTION
, auction
->GetHouseId(), auction
->owner
, msgAuctionSuccessfulSubject
.str(), itemTextId
, NULL
, profit
, 0, MAIL_CHECK_MASK_AUCTION
, HOUR
);
232 void AuctionHouseMgr::SendAuctionExpiredMail( AuctionEntry
* auction
)
233 { //return an item in auction to its owner by mail
234 Item
*pItem
= GetAItem(auction
->item_guidlow
);
237 sLog
.outError("Auction item (GUID: %u) not found, and lost.",auction
->item_guidlow
);
241 uint64 owner_guid
= MAKE_NEW_GUID(auction
->owner
, 0, HIGHGUID_PLAYER
);
242 Player
*owner
= objmgr
.GetPlayer(owner_guid
);
244 uint32 owner_accId
= 0;
246 owner_accId
= objmgr
.GetPlayerAccountIdByGUID(owner_guid
);
249 if(owner
|| owner_accId
)
251 std::ostringstream subject
;
252 subject
<< auction
->item_template
<< ":0:" << AUCTION_EXPIRED
;
255 owner
->GetSession()->SendAuctionOwnerNotification( auction
);
257 RemoveAItem(pItem
->GetGUIDLow()); // we have to remove the item, before we delete it !!
260 mi
.AddItem(auction
->item_guidlow
, auction
->item_template
, pItem
);
262 // will delete item or place to receiver mail list
263 WorldSession::SendMailTo(owner
, MAIL_AUCTION
, MAIL_STATIONERY_AUCTION
, auction
->GetHouseId(), GUID_LOPART(owner_guid
), subject
.str(), 0, &mi
, 0, 0, MAIL_CHECK_MASK_NONE
);
268 CharacterDatabase
.PExecute("DELETE FROM item_instance WHERE guid='%u'",pItem
->GetGUIDLow());
269 RemoveAItem(pItem
->GetGUIDLow()); // we have to remove the item, before we delete it !!
274 void AuctionHouseMgr::LoadAuctionItems()
276 // data needs to be at first place for Item::LoadFromDB
277 QueryResult
*result
= CharacterDatabase
.Query( "SELECT data,itemguid,item_template FROM auctionhouse JOIN item_instance ON itemguid = guid" );
284 sLog
.outString(">> Loaded 0 auction items");
288 barGoLink
bar( result
->GetRowCount() );
297 fields
= result
->Fetch();
298 uint32 item_guid
= fields
[1].GetUInt32();
299 uint32 item_template
= fields
[2].GetUInt32();
301 ItemPrototype
const *proto
= objmgr
.GetItemPrototype(item_template
);
305 sLog
.outError( "ObjectMgr::LoadAuctionItems: Unknown item (GUID: %u id: #%u) in auction, skipped.", item_guid
,item_template
);
309 Item
*item
= NewItemOrBag(proto
);
311 if(!item
->LoadFromDB(item_guid
,0, result
))
320 while( result
->NextRow() );
324 sLog
.outString( ">> Loaded %u auction items", count
);
327 void AuctionHouseMgr::LoadAuctions()
329 QueryResult
*result
= CharacterDatabase
.Query("SELECT COUNT(*) FROM auctionhouse");
335 sLog
.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
339 Field
*fields
= result
->Fetch();
340 uint32 AuctionCount
=fields
[0].GetUInt32();
348 sLog
.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
352 result
= CharacterDatabase
.Query( "SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit FROM auctionhouse" );
358 sLog
.outString(">> Loaded 0 auctions. DB table `auctionhouse` is empty.");
362 barGoLink
bar( AuctionCount
);
368 fields
= result
->Fetch();
372 aItem
= new AuctionEntry
;
373 aItem
->Id
= fields
[0].GetUInt32();
374 aItem
->auctioneer
= fields
[1].GetUInt32();
375 aItem
->item_guidlow
= fields
[2].GetUInt32();
376 aItem
->item_template
= fields
[3].GetUInt32();
377 aItem
->owner
= fields
[4].GetUInt32();
378 aItem
->buyout
= fields
[5].GetUInt32();
379 aItem
->expire_time
= fields
[6].GetUInt32();
380 aItem
->bidder
= fields
[7].GetUInt32();
381 aItem
->bid
= fields
[8].GetUInt32();
382 aItem
->startbid
= fields
[9].GetUInt32();
383 aItem
->deposit
= fields
[10].GetUInt32();
385 CreatureData
const* auctioneerData
= objmgr
.GetCreatureData(aItem
->auctioneer
);
388 aItem
->DeleteFromDB();
389 sLog
.outError("Auction %u has not a existing auctioneer (GUID : %u)", aItem
->Id
, aItem
->auctioneer
);
394 CreatureInfo
const* auctioneerInfo
= objmgr
.GetCreatureTemplate(auctioneerData
->id
);
397 aItem
->DeleteFromDB();
398 sLog
.outError("Auction %u has not a existing auctioneer (GUID : %u Entry: %u)", aItem
->Id
, aItem
->auctioneer
,auctioneerData
->id
);
403 aItem
->auctionHouseEntry
= AuctionHouseMgr::GetAuctionHouseEntry(auctioneerInfo
->faction_A
);
404 if(!aItem
->auctionHouseEntry
)
406 aItem
->DeleteFromDB();
407 sLog
.outError("Auction %u has auctioneer (GUID : %u Entry: %u) with wrong faction %u",
408 aItem
->Id
, aItem
->auctioneer
,auctioneerData
->id
,auctioneerInfo
->faction_A
);
413 // check if sold item exists for guid
414 // and item_template in fact (GetAItem will fail if problematic in result check in ObjectMgr::LoadAuctionItems)
415 if ( !GetAItem( aItem
->item_guidlow
) )
417 aItem
->DeleteFromDB();
418 sLog
.outError("Auction %u has not a existing item : %u", aItem
->Id
, aItem
->item_guidlow
);
423 GetAuctionsMap( auctioneerInfo
->faction_A
)->AddAuction(aItem
);
425 } while (result
->NextRow());
429 sLog
.outString( ">> Loaded %u auctions", AuctionCount
);
432 void AuctionHouseMgr::AddAItem( Item
* it
)
435 ASSERT( mAitems
.find(it
->GetGUIDLow()) == mAitems
.end());
436 mAitems
[it
->GetGUIDLow()] = it
;
439 bool AuctionHouseMgr::RemoveAItem( uint32 id
)
441 ItemMap::iterator i
= mAitems
.find(id
);
442 if (i
== mAitems
.end())
450 void AuctionHouseMgr::Update()
452 mHordeAuctions
.Update();
453 mAllianceAuctions
.Update();
454 mNeutralAuctions
.Update();
457 AuctionHouseEntry
const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTemplateId
)
459 uint32 houseid
= 1; // human auction house
461 if(!sWorld
.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION
))
463 //FIXME: found way for proper auctionhouse selection by another way
464 // AuctionHo use.dbc have faction field with _player_ factions associated with auction house races.
465 // but no easy way convert creature faction to player race faction for specific city
466 switch(factionTemplateId
)
468 case 12: houseid
= 1; break; // human
469 case 29: houseid
= 6; break; // orc, and generic for horde
470 case 55: houseid
= 2; break; // dwarf, and generic for alliance
471 case 68: houseid
= 4; break; // undead
472 case 80: houseid
= 3; break; // n-elf
473 case 104: houseid
= 5; break; // trolls
474 case 120: houseid
= 7; break; // booty bay, neutral
475 case 474: houseid
= 7; break; // gadgetzan, neutral
476 case 855: houseid
= 7; break; // everlook, neutral
477 case 1604: houseid
= 6; break; // b-elfs,
478 default: // for unknown case
480 FactionTemplateEntry
const* u_entry
= sFactionTemplateStore
.LookupEntry(factionTemplateId
);
482 houseid
= 7; // goblin auction house
483 else if(u_entry
->ourMask
& FACTION_MASK_ALLIANCE
)
484 houseid
= 1; // human auction house
485 else if(u_entry
->ourMask
& FACTION_MASK_HORDE
)
486 houseid
= 6; // orc auction house
488 houseid
= 7; // goblin auction house
494 return sAuctionHouseStore
.LookupEntry(houseid
);
497 void AuctionHouseObject::Update()
499 time_t curTime
= sWorld
.GetGameTime();
500 ///- Handle expired auctions
501 AuctionEntryMap::iterator next
;
502 for (AuctionEntryMap::iterator itr
= AuctionsMap
.begin(); itr
!= AuctionsMap
.end();itr
= next
)
506 if (curTime
> (itr
->second
->expire_time
))
508 ///- Either cancel the auction if there was no bidder
509 if (itr
->second
->bidder
== 0)
511 auctionmgr
.SendAuctionExpiredMail( itr
->second
);
513 ///- Or perform the transaction
516 //we should send an "item sold" message if the seller is online
517 //we send the item to the winner
518 //we send the money to the seller
519 auctionmgr
.SendAuctionSuccessfulMail( itr
->second
);
520 auctionmgr
.SendAuctionWonMail( itr
->second
);
523 ///- In any case clear the auction
524 itr
->second
->DeleteFromDB();
525 auctionmgr
.RemoveAItem(itr
->second
->item_guidlow
);
527 RemoveAuction(itr
->first
);
532 void AuctionHouseObject::BuildListBidderItems(WorldPacket
& data
, Player
* player
, uint32
& count
, uint32
& totalcount
)
534 for (AuctionEntryMap::const_iterator itr
= AuctionsMap
.begin();itr
!= AuctionsMap
.end();++itr
)
536 AuctionEntry
*Aentry
= itr
->second
;
537 if( Aentry
&& Aentry
->bidder
== player
->GetGUIDLow() )
539 if (itr
->second
->BuildAuctionInfo(data
))
546 void AuctionHouseObject::BuildListOwnerItems(WorldPacket
& data
, Player
* player
, uint32
& count
, uint32
& totalcount
)
548 for (AuctionEntryMap::const_iterator itr
= AuctionsMap
.begin();itr
!= AuctionsMap
.end();++itr
)
550 AuctionEntry
*Aentry
= itr
->second
;
551 if( Aentry
&& Aentry
->owner
== player
->GetGUIDLow() )
553 if(Aentry
->BuildAuctionInfo(data
))
560 void AuctionHouseObject::BuildListAuctionItems(WorldPacket
& data
, Player
* player
,
561 std::wstring
const& wsearchedname
, uint32 listfrom
, uint32 levelmin
, uint32 levelmax
, uint32 usable
,
562 uint32 inventoryType
, uint32 itemClass
, uint32 itemSubClass
, uint32 quality
,
563 uint32
& count
, uint32
& totalcount
)
565 int loc_idx
= player
->GetSession()->GetSessionDbLocaleIndex();
567 for (AuctionEntryMap::const_iterator itr
= AuctionsMap
.begin();itr
!= AuctionsMap
.end();++itr
)
569 AuctionEntry
*Aentry
= itr
->second
;
570 Item
*item
= auctionmgr
.GetAItem(Aentry
->item_guidlow
);
574 ItemPrototype
const *proto
= item
->GetProto();
576 if (itemClass
!= (0xffffffff) && proto
->Class
!= itemClass
)
579 if (itemSubClass
!= (0xffffffff) && proto
->SubClass
!= itemSubClass
)
582 if (inventoryType
!= (0xffffffff) && proto
->InventoryType
!= inventoryType
)
585 if (quality
!= (0xffffffff) && proto
->Quality
!= quality
)
588 if( levelmin
!= (0x00) && (proto
->RequiredLevel
< levelmin
|| levelmax
!= (0x00) && proto
->RequiredLevel
> levelmax
) )
591 if( usable
!= (0x00) && player
->CanUseItem( item
) != EQUIP_ERR_OK
)
594 std::string name
= proto
->Name1
;
601 ItemLocale
const *il
= objmgr
.GetItemLocale(proto
->ItemId
);
604 if (il
->Name
.size() > size_t(loc_idx
) && !il
->Name
[loc_idx
].empty())
605 name
= il
->Name
[loc_idx
];
609 if( !wsearchedname
.empty() && !Utf8FitTo(name
, wsearchedname
) )
612 if ((count
< 50) && (totalcount
>= listfrom
))
615 Aentry
->BuildAuctionInfo(data
);
621 //this function inserts to WorldPacket auction's data
622 bool AuctionEntry::BuildAuctionInfo(WorldPacket
& data
) const
624 Item
*pItem
= auctionmgr
.GetAItem(item_guidlow
);
627 sLog
.outError("auction to item, that doesn't exist !!!!");
631 data
<< (uint32
) pItem
->GetEntry();
633 for (uint8 i
= 0; i
< MAX_INSPECTED_ENCHANTMENT_SLOT
; i
++)
635 data
<< (uint32
) pItem
->GetEnchantmentId(EnchantmentSlot(i
));
636 data
<< (uint32
) pItem
->GetEnchantmentDuration(EnchantmentSlot(i
));
637 data
<< (uint32
) pItem
->GetEnchantmentCharges(EnchantmentSlot(i
));
640 data
<< (uint32
) pItem
->GetItemRandomPropertyId(); //random item property id
641 data
<< (uint32
) pItem
->GetItemSuffixFactor(); //SuffixFactor
642 data
<< (uint32
) pItem
->GetCount(); //item->count
643 data
<< (uint32
) pItem
->GetSpellCharges(); //item->charge FFFFFFF
644 data
<< (uint32
) 0; //Unknown
645 data
<< (uint64
) owner
; //Auction->owner
646 data
<< (uint32
) startbid
; //Auction->startbid (not sure if useful)
647 data
<< (uint32
) (bid
? GetAuctionOutBid() : 0);
649 data
<< (uint32
) buyout
; //auction->buyout
650 data
<< (uint32
) (expire_time
- time(NULL
))* 1000; //time left
651 data
<< (uint64
) bidder
; //auction->bidder current
652 data
<< (uint32
) bid
; //current bid
656 uint32
AuctionEntry::GetAuctionCut() const
658 return uint32(auctionHouseEntry
->cutPercent
* bid
* sWorld
.getRate(RATE_AUCTION_CUT
) / 100.f
);
661 /// the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c
662 uint32
AuctionEntry::GetAuctionOutBid() const
664 uint32 outbid
= (bid
/ 100) * 5;
670 void AuctionEntry::DeleteFromDB() const
672 //No SQL injection (Id is integer)
673 CharacterDatabase
.PExecute("DELETE FROM auctionhouse WHERE id = '%u'",Id
);
676 void AuctionEntry::SaveToDB() const
678 //No SQL injection (no strings)
679 CharacterDatabase
.PExecute("INSERT INTO auctionhouse (id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit) "
680 "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '" I64FMTD
"', '%u', '%u', '%u', '%u')",
681 Id
, auctioneer
, item_guidlow
, item_template
, owner
, buyout
, (uint64
)expire_time
, bidder
, bid
, startbid
, deposit
);