OregonCore  revision 3611e8a-git
Your Favourite TBC server
AuctionHouseMgr.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "Common.h"
19 #include "ObjectMgr.h"
20 #include "Player.h"
21 #include "World.h"
22 #include "WorldPacket.h"
23 #include "WorldSession.h"
24 #include "Database/DatabaseEnv.h"
25 #include "Database/SQLStorage.h"
26 #include "DBCStores.h"
27 
28 #include "AccountMgr.h"
29 #include "AuctionHouseMgr.h"
30 #include "Item.h"
31 #include "Language.h"
32 #include "Log.h"
33 
34 using namespace std;
35 
37 {
38 }
39 
41 {
42  for (ItemMap::const_iterator itr = mAitems.begin(); itr != mAitems.end(); ++itr)
43  delete itr->second;
44 }
45 
47 {
49  return &mNeutralAuctions;
50 
51  // team have linked auction houses
52  FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(factionTemplateId);
53  if (!u_entry)
54  return &mNeutralAuctions;
55  else if (u_entry->ourMask & FACTION_MASK_ALLIANCE)
56  return &mAllianceAuctions;
57  else if (u_entry->ourMask & FACTION_MASK_HORDE)
58  return &mHordeAuctions;
59  else
60  return &mNeutralAuctions;
61 }
62 
64 {
65  uint32 MSV = pItem->GetProto()->SellPrice;
66  double deposit;
67  double faction_pct;
68  if (MSV > 0)
69  {
71  faction_pct = (0.75 * (double)sWorld.getRate(RATE_AUCTION_DEPOSIT));
72  else
73  {
74  FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(entry->houseId);
75  if (!u_entry)
76  faction_pct = (0.75 * (double)sWorld.getRate(RATE_AUCTION_DEPOSIT));
77  else if (u_entry->ourMask & FACTION_MASK_ALLIANCE)
78  faction_pct = (0.15 * (double)sWorld.getRate(RATE_AUCTION_DEPOSIT));
79  else if (u_entry->ourMask & FACTION_MASK_HORDE)
80  faction_pct = (0.15 * (double)sWorld.getRate(RATE_AUCTION_DEPOSIT));
81  else
82  faction_pct = (0.75 * (double)sWorld.getRate(RATE_AUCTION_DEPOSIT));
83  }
84  deposit = ((double)MSV * faction_pct * (double)pItem->GetCount()) * (double)(time / MIN_AUCTION_TIME);
85  }
86  else
87  {
88  faction_pct = 0.0f;
89  deposit = 0.0f;
90  }
91  sLog.outDebug("SellPrice:\t\t%u", MSV);
92  sLog.outDebug("Deposit Percent:\t%f", faction_pct);
93  sLog.outDebug("Auction Time1:\t\t%u", time);
94  sLog.outDebug("Auction Time2:\t\t%u", MIN_AUCTION_TIME);
95  sLog.outDebug("Auction Time3:\t\t%u", (time / MIN_AUCTION_TIME));
96  sLog.outDebug("Count:\t\t\t%u", pItem->GetCount());
97  sLog.outDebug("Deposit:\t\t%f", deposit);
98  if (deposit > 0)
99  return (uint32)deposit;
100  else
101  return 0;
102 }
103 
104 // does not clear ram
106 {
107  Item* pItem = GetAItem(auction->item_guidlow);
108  if (!pItem)
109  return;
110 
111  uint32 bidder_accId = 0;
112  uint32 bidder_security = 0;
113  uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER);
114  Player* bidder = sObjectMgr.GetPlayer(bidder_guid);
115  // data for gm.log
116  if (sWorld.getConfig(CONFIG_GM_LOG_TRADE))
117  {
118  std::string bidder_name;
119  if (bidder)
120  {
121  bidder_accId = bidder->GetSession()->GetAccountId();
122  bidder_security = bidder->GetSession()->GetSecurity();
123  bidder_name = bidder->GetName();
124  }
125  else
126  {
127  bidder_accId = sObjectMgr.GetPlayerAccountIdByGUID(bidder_guid);
128  bidder_security = sAccountMgr->GetSecurity(bidder_accId);
129 
130  if (bidder_security > SEC_PLAYER) // not do redundant DB requests
131  {
132  if (!sObjectMgr.GetPlayerNameByGUID(bidder_guid, bidder_name))
133  bidder_name = sObjectMgr.GetOregonStringForDBCLocale(LANG_UNKNOWN);
134  }
135  }
136  if (bidder_security > SEC_PLAYER)
137  {
138  std::string owner_name;
139  if (!sObjectMgr.GetPlayerNameByGUID(auction->owner, owner_name))
140  owner_name = sObjectMgr.GetOregonStringForDBCLocale(LANG_UNKNOWN);
141 
142  uint32 owner_accid = sObjectMgr.GetPlayerAccountIdByGUID(auction->owner);
143 
144  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)",
145  bidder_name.c_str(), bidder_accId, pItem->GetProto()->Name1, pItem->GetEntry(), pItem->GetCount(), auction->bid, owner_name.c_str(), owner_accid);
146  }
147  }
148 
149  // receiver exist
150  if (bidder || bidder_accId)
151  {
152  std::ostringstream msgAuctionWonSubject;
153  msgAuctionWonSubject << auction->item_template << ":0:" << AUCTION_WON;
154 
155  std::ostringstream msgAuctionWonBody;
156  msgAuctionWonBody.width(16);
157  msgAuctionWonBody << std::right << std::hex << auction->owner;
158  msgAuctionWonBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
159  sLog.outDebug("AuctionWon body string : %s", msgAuctionWonBody.str().c_str());
160 
161  // prepare mail data... :
162  uint32 itemTextId = sObjectMgr.CreateItemText(msgAuctionWonBody.str());
163 
164  // set owner to bidder (to prevent delete item with sender char deleting)
165  // owner in data will set at mail receive and item extracting
166  CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", auction->bidder, pItem->GetGUIDLow());
167 
168  if (bidder)
169  bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->item_template);
170 
171  MailDraft(msgAuctionWonSubject.str(), itemTextId)
172  .AddItem(pItem)
173  .SendMailTo(MailReceiver(bidder, auction->bidder), auction, MAIL_CHECK_MASK_COPIED);
174  }
175 }
176 
178 {
179  uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
180  Player* owner = sObjectMgr.GetPlayer(owner_guid);
181  uint32 owner_accId = sObjectMgr.GetPlayerAccountIdByGUID(owner_guid);
182  // owner exist (online or offline)
183  if (owner || owner_accId)
184  {
185  std::ostringstream msgAuctionSalePendingSubject;
186  msgAuctionSalePendingSubject << auction->item_template << ":0:" << AUCTION_SALE_PENDING;
187 
188  std::ostringstream msgAuctionSalePendingBody;
189  uint32 auctionCut = auction->GetAuctionCut();
190 
191  time_t distrTime = time(NULL) + sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY);
192 
193  msgAuctionSalePendingBody.width(16);
194  msgAuctionSalePendingBody << std::right << std::hex << auction->bidder;
195  msgAuctionSalePendingBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
196  msgAuctionSalePendingBody << ":" << auction->deposit << ":" << auctionCut << ":0:";
197  msgAuctionSalePendingBody << secsToTimeBitFields(distrTime);
198 
199  sLog.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody.str().c_str());
200 
201  uint32 itemTextId = sObjectMgr.CreateItemText(msgAuctionSalePendingBody.str());
202 
203  MailDraft(msgAuctionSalePendingSubject.str(), itemTextId)
204  .SendMailTo(MailReceiver(owner, auction->owner), auction, MAIL_CHECK_MASK_COPIED);
205  }
206 }
207 
208 // call this method to send mail to auction owner, when auction is successful, it does not clear ram
210 {
211  uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
212  Player* owner = sObjectMgr.GetPlayer(owner_guid);
213  uint32 owner_accId = sObjectMgr.GetPlayerAccountIdByGUID(owner_guid);
214  // owner exist
215  if (owner || owner_accId)
216  {
217  std::ostringstream msgAuctionSuccessfulSubject;
218  msgAuctionSuccessfulSubject << auction->item_template << ":0:" << AUCTION_SUCCESSFUL;
219 
220  std::ostringstream auctionSuccessfulBody;
221  uint32 auctionCut = auction->GetAuctionCut();
222 
223  auctionSuccessfulBody.width(16);
224  auctionSuccessfulBody << std::right << std::hex << auction->bidder;
225  auctionSuccessfulBody << std::dec << ":" << auction->bid << ":" << auction->buyout;
226  auctionSuccessfulBody << ":" << auction->deposit << ":" << auctionCut;
227 
228  sLog.outDebug("AuctionSuccessful body string : %s", auctionSuccessfulBody.str().c_str());
229 
230  uint32 itemTextId = sObjectMgr.CreateItemText(auctionSuccessfulBody.str());
231 
232  uint32 profit = auction->bid + auction->deposit - auctionCut;
233 
234  if (owner && owner->GetGUIDLow() != auctionbot.GetAHBplayerGUID())
235  {
236  // send auction owner notification, bidder must be current!
237  owner->GetSession()->SendAuctionOwnerNotification(auction);
238  }
239 
240  MailDraft(msgAuctionSuccessfulSubject.str(), itemTextId)
241  .AddMoney(profit)
242  .SendMailTo(MailReceiver(owner, auction->owner), auction, MAIL_CHECK_MASK_COPIED, HOUR);
243  }
244 }
245 
246 // does not clear ram
248 {
249  // return an item in auction to its owner by mail
250  Item* pItem = GetAItem(auction->item_guidlow);
251  if (!pItem)
252  return;
253 
254  uint64 owner_guid = MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER);
255  Player* owner = sObjectMgr.GetPlayer(owner_guid);
256  uint32 owner_accId = sObjectMgr.GetPlayerAccountIdByGUID(owner_guid);
257  // owner exist
258  if (owner || owner_accId)
259  {
260  std::ostringstream subject;
261  subject << auction->item_template << ":0:" << AUCTION_EXPIRED;
262 
263  if (owner && owner->GetGUIDLow() != auctionbot.GetAHBplayerGUID())
264  owner->GetSession()->SendAuctionOwnerNotification(auction);
265 
266  MailDraft(subject.str())
267  .AddItem(pItem)
268  .SendMailTo(MailReceiver(owner, auction->owner), auction, MAIL_CHECK_MASK_COPIED);
269  }
270 }
271 
273 {
274  // data needs to be at first place for Item::LoadFromDB
275  QueryResult_AutoPtr result = CharacterDatabase.Query("SELECT itemEntry, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, itemTextId, itemguid, item_template FROM auctionhouse JOIN item_instance ON itemguid = guid");
276 
277  if (!result)
278  {
279  sLog.outString(">> Loaded 0 auction items");
280  return;
281  }
282 
283 
284  uint32 count = 0;
285 
286  Field* fields;
287  do
288  {
289 
290  fields = result->Fetch();
291  uint32 item_guid = fields[11].GetUInt32();
292  uint32 item_template = fields[12].GetUInt32();
293 
294  ItemTemplate const* proto = sObjectMgr.GetItemTemplate(item_template);
295 
296  if (!proto)
297  {
298  sLog.outError("AuctionHouseMgr::LoadAuctionItems: Unknown item (GUID: %u id: #%u) in auction, skipped.", item_guid, item_template);
299  continue;
300  }
301 
302  Item* item = NewItemOrBag(proto);
303 
304  if (!item->LoadFromDB(item_guid, 0, fields))
305  {
306  delete item;
307  continue;
308  }
309  AddAItem(item);
310 
311  ++count;
312  }
313  while (result->NextRow());
314 
315  sLog.outString(">> Loaded %u auction items", count);
316 }
317 
319 {
320  QueryResult_AutoPtr result = CharacterDatabase.Query("SELECT COUNT(*) FROM auctionhouse");
321  if (!result)
322  {
323  sLog.outString(">> Loaded 0 auctions. DB table auctionhouse is empty.");
324  return;
325  }
326 
327  Field* fields = result->Fetch();
328  uint32 AuctionCount = fields[0].GetUInt32();
329 
330  if (!AuctionCount)
331  {
332  sLog.outString(">> Loaded 0 auctions. DB table auctionhouse is empty.");
333  return;
334  }
335 
336  result = CharacterDatabase.Query("SELECT id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit FROM auctionhouse");
337  if (!result)
338  {
339  sLog.outString(">> Loaded 0 auctions. DB table auctionhouse is empty.");
340  return;
341  }
342 
343 
344  AuctionEntry* aItem;
345 
346  do
347  {
348  fields = result->Fetch();
349 
350 
351  aItem = new AuctionEntry;
352  aItem->Id = fields[0].GetUInt32();
353  aItem->auctioneer = fields[1].GetUInt32();
354  aItem->item_guidlow = fields[2].GetUInt32();
355  aItem->item_template = fields[3].GetUInt32();
356  aItem->owner = fields[4].GetUInt32();
357  aItem->buyout = fields[5].GetUInt32();
358  aItem->expire_time = fields[6].GetUInt32();
359  aItem->bidder = fields[7].GetUInt32();
360  aItem->bid = fields[8].GetUInt32();
361  aItem->startbid = fields[9].GetUInt32();
362  aItem->deposit = fields[10].GetUInt32();
363 
364  CreatureData const* auctioneerData = sObjectMgr.GetCreatureData(aItem->auctioneer);
365  if (!auctioneerData)
366  {
367  aItem->DeleteFromDB();
368  sLog.outError("Auction %u has invalid auctioneer (GUID : %u)", aItem->Id, aItem->auctioneer);
369  delete aItem;
370  continue;
371  }
372 
373  CreatureInfo const* auctioneerInfo = sObjectMgr.GetCreatureTemplate(auctioneerData->id);
374  if (!auctioneerInfo)
375  {
376  aItem->DeleteFromDB();
377  sLog.outError("Auction %u has invalid auctioneer (GUID : %u Entry: %u)", aItem->Id, aItem->auctioneer, auctioneerData->id);
378  delete aItem;
379  continue;
380  }
381 
383  if (!aItem->auctionHouseEntry)
384  {
385  aItem->DeleteFromDB();
386  sLog.outError("Auction %u has auctioneer (GUID : %u Entry: %u) with wrong faction %u",
387  aItem->Id, aItem->auctioneer, auctioneerData->id, auctioneerInfo->faction);
388  delete aItem;
389  continue;
390  }
391 
392  // check if sold item exists for guid
393  // and item_template in fact (GetAItem will fail if problematic in result check in AuctionHouseMgr::LoadAuctionItems)
394  if (!GetAItem(aItem->item_guidlow))
395  {
396  aItem->DeleteFromDB();
397  sLog.outError("Auction %u has invalid item : %u", aItem->Id, aItem->item_guidlow);
398  delete aItem;
399  continue;
400  }
401 
402  GetAuctionsMap(auctioneerInfo->faction)->AddAuction(aItem);
403 
404  }
405  while (result->NextRow());
406 
407  sLog.outString(">> Loaded %u auctions", AuctionCount);
408 }
409 
411 {
412  ASSERT(it);
413  ASSERT(mAitems.find(it->GetGUIDLow()) == mAitems.end());
414  mAitems[it->GetGUIDLow()] = it;
415 }
416 
418 {
419  ItemMap::iterator i = mAitems.find(id);
420  if (i == mAitems.end())
421  return false;
422 
423  mAitems.erase(i);
424  return true;
425 }
426 
428 {
429  mHordeAuctions.Update();
430  mAllianceAuctions.Update();
431  mNeutralAuctions.Update();
432 }
433 
435 {
436  uint32 houseid = 7; // goblin auction house
437 
439  {
440  // FIXME: found way for proper auctionhouse selection by another way
441  // AuctionHouse.dbc have faction field with _player_ factions associated with auction house races.
442  // but no easy way convert creature faction to player race faction for specific city
443  switch (factionTemplateId)
444  {
445  case 12:
446  houseid = 1;
447  break; // human
448  case 29:
449  houseid = 6;
450  break; // orc, and generic for horde
451  case 55:
452  houseid = 2;
453  break; // dwarf, and generic for alliance
454  case 68:
455  houseid = 4;
456  break; // undead
457  case 80:
458  houseid = 3;
459  break; // n-elf
460  case 104:
461  houseid = 5;
462  break; // trolls
463  case 120:
464  houseid = 7;
465  break; // booty bay, neutral
466  case 474:
467  houseid = 7;
468  break; // gadgetzan, neutral
469  case 855:
470  houseid = 7;
471  break; // everlook, neutral
472  case 1604:
473  houseid = 6;
474  break; // b-elfs,
475  default: // for unknown case
476  {
477  FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(factionTemplateId);
478  if (!u_entry)
479  houseid = 7; // goblin auction house
480  else if (u_entry->ourMask & FACTION_MASK_ALLIANCE)
481  houseid = 1; // human auction house
482  else if (u_entry->ourMask & FACTION_MASK_HORDE)
483  houseid = 6; // orc auction house
484  else
485  houseid = 7; // goblin auction house
486  break;
487  }
488  }
489  }
490 
491  return sAuctionHouseStore.LookupEntry(houseid);
492 }
494 {
495  ASSERT(ah);
496  AuctionsMap[ah->Id] = ah;
497  auctionbot.IncrementItemCounts(ah);
498 }
499 
501 {
502  auctionbot.DecrementItemCounts(auction, item_template);
503  bool wasInMap = AuctionsMap.erase(auction->Id) ? true : false;
504 
505  // we need to delete the entry, it is not referenced any more
506  delete auction;
507  return wasInMap;
508 }
509 
511 {
512  time_t curTime = sWorld.GetGameTime();
513  // Handle expired auctions
514 
515  // If storage is empty, no need to update. next == NULL in this case.
516  if (AuctionsMap.empty())
517  return;
518 
519  QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT id FROM auctionhouse WHERE time <= %u ORDER BY TIME ASC", (uint32)curTime + 60);
520 
521  if (!result)
522  return;
523 
524  if (result->GetRowCount() == 0)
525  return;
526 
527  vector<uint32> expiredAuctions;
528 
529  do
530  {
531  uint32 tmpdata = result->Fetch()->GetUInt32();
532  expiredAuctions.push_back(tmpdata);
533  }
534  while (result->NextRow());
535 
536  while (!expiredAuctions.empty())
537  {
538  vector<uint32>::iterator iter = expiredAuctions.begin();
539 
540  // from auctionhousehandler.cpp, creates auction pointer & player pointer
541  AuctionEntry* auction = GetAuction(*iter);
542 
543  // Erase the auction from the vector.
544  expiredAuctions.erase(iter);
545 
546  if (!auction)
547  continue;
548 
550  if (auction->bidder == 0)
551  sAuctionMgr->SendAuctionExpiredMail(auction);
553  else
554  {
555  //we should send an "item sold" message if the seller is online
556  //we send the item to the winner
557  //we send the money to the seller
558  sAuctionMgr->SendAuctionSuccessfulMail(auction);
559  sAuctionMgr->SendAuctionWonMail(auction);
560  }
561 
564  auction->DeleteFromDB();
565  uint32 item_template = auction->item_template;
566  sAuctionMgr->RemoveAItem(auction->item_guidlow);
567  RemoveAuction(auction, item_template);
569  }
570 }
571 
573 {
574  for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr)
575  {
576  AuctionEntry* Aentry = itr->second;
577  if (Aentry && Aentry->bidder == player->GetGUIDLow())
578  {
579  if (itr->second->BuildAuctionInfo(data))
580  ++count;
581 
582  ++totalcount;
583  }
584  }
585 }
586 
587 void AuctionHouseObject::BuildListOwnerItems(WorldPacket& data, Player* player, uint32& count, uint32& totalcount)
588 {
589  for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr)
590  {
591  AuctionEntry* Aentry = itr->second;
592  if (Aentry && Aentry->owner == player->GetGUIDLow())
593  {
594  if (Aentry->BuildAuctionInfo(data))
595  ++count;
596  ++totalcount;
597  }
598  }
599 }
600 
602  std::wstring const& wsearchedname, uint32 listfrom, uint32 levelmin, uint32 levelmax, uint32 usable,
603  uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality,
604  uint32& count, uint32& totalcount)
605 {
606  int loc_idx = player->GetSession()->GetSessionDbLocaleIndex();
607 
608  time_t curTime = sWorld.GetGameTime();
609 
610  for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr)
611  {
612  AuctionEntry* Aentry = itr->second;
613  // Skip expired auctions
614  if (Aentry->expire_time < curTime)
615  continue;
616 
617  Item* item = sAuctionMgr->GetAItem(Aentry->item_guidlow);
618  if (!item)
619  continue;
620 
621  ItemTemplate const* proto = item->GetProto();
622 
623  if (itemClass != 0xffffffff && proto->Class != itemClass)
624  continue;
625 
626  if (itemSubClass != 0xffffffff && proto->SubClass != itemSubClass)
627  continue;
628 
629  if (inventoryType != 0xffffffff && proto->InventoryType != inventoryType)
630  continue;
631 
632  if (quality != 0xffffffff && proto->Quality < quality)
633  continue;
634 
635  if (levelmin != 0x00 && (proto->RequiredLevel < levelmin || (levelmax != 0x00 && proto->RequiredLevel > levelmax)))
636  continue;
637 
638  if (usable != 0x00)
639  {
640  if (player->CanUseItem(item) != EQUIP_ERR_OK)
641  continue;
642 
643  if (proto->Class == ITEM_CLASS_RECIPE)
644  if (player->HasSpell(proto->Spells[1].SpellId))
645  continue;
646  }
647 
648  std::string name = proto->Name1;
649  if (name.empty())
650  continue;
651 
652  // local name
653  if (loc_idx >= 0)
654  {
655  ItemLocale const* il = sObjectMgr.GetItemLocale(proto->ItemId);
656  if (il)
657  {
658  if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty())
659  name = il->Name[loc_idx];
660  }
661  }
662 
663  if (!wsearchedname.empty() && !Utf8FitTo(name, wsearchedname))
664  continue;
665 
666  if (count < 50 && totalcount >= listfrom)
667  {
668  ++count;
669  Aentry->BuildAuctionInfo(data);
670  }
671  ++totalcount;
672  }
673 }
674 
675 // this function inserts to WorldPacket auction's data
677 {
678  Item* pItem = sAuctionMgr->GetAItem(item_guidlow);
679  if (!pItem)
680  {
681  sLog.outError("auction to item, that doesn't exist !!!!");
682  return false;
683  }
684  data << uint32(Id);
685  data << uint32(pItem->GetEntry());
686 
687  for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; ++i)
688  {
689  data << uint32(pItem->GetEnchantmentId(EnchantmentSlot(i)));
690  data << uint32(pItem->GetEnchantmentDuration(EnchantmentSlot(i)));
691  data << uint32(pItem->GetEnchantmentCharges(EnchantmentSlot(i)));
692  }
693 
694  data << uint32(pItem->GetItemRandomPropertyId()); // random item property id
695  data << uint32(pItem->GetItemSuffixFactor()); // SuffixFactor
696  data << uint32(pItem->GetCount()); // item->count
697  data << uint32(pItem->GetSpellCharges()); // item->charge FFFFFFF
698  data << uint32(0); // Unknown
699  data << uint64(owner); // Auction->owner
700  data << uint32(startbid); // Auction->startbid (not sure if useful)
701  data << uint32(bid ? GetAuctionOutBid() : 0);
702  // minimal outbid
703  data << uint32(buyout); // auction->buyout
704  data << uint32((expire_time - time(NULL))*IN_MILLISECONDS); // time left
705  data << uint64(bidder) ; // auction->bidder current
706  data << uint32(bid); // current bid
707  return true;
708 }
709 
711 {
712  return uint32(CalculatePct(sWorld.getRate(RATE_AUCTION_CUT), auctionHouseEntry->cutPercent)) * bid;
713 }
714 
715 // the sum of outbid is (1% from current bid)*5, if bid is very small, it is 1c
717 {
718  uint32 outbid = CalculatePct(bid, 5);
719  return outbid ? outbid : 1;
720 }
721 
723 {
724  // No SQL injection (Id is integer)
725  CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE id = '%u'", Id);
726 }
727 
729 {
730  // No SQL injection (no strings)
731  CharacterDatabase.PExecute("INSERT INTO auctionhouse (id,auctioneerguid,itemguid,item_template,itemowner,buyoutprice,time,buyguid,lastbid,startbid,deposit) "
732  "VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '" UI64FMTD "', '%u', '%u', '%u', '%u')",
733  Id, auctioneer, item_guidlow, item_template, owner, buyout, (uint64)expire_time, bidder, bid, startbid, deposit);
734 }
735 
void SaveToDB() const
bool Utf8FitTo(const std::string &str, std::wstring search)
Definition: Util.cpp:458
void AddAuction(AuctionEntry *ah)
uint32 GetCount() const
Definition: Item.h:251
ItemTemplate const * GetProto() const
Definition: Item.cpp:460
uint32 InventoryType
int32 GetSpellCharges(uint8 index=0) const
Definition: Item.h:330
bool BuildAuctionInfo(WorldPacket &data) const
void BuildListAuctionItems(WorldPacket &data, Player *player, std::wstring const &searchedname, uint32 listfrom, uint32 levelmin, uint32 levelmax, uint32 usable, uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality, uint32 &count, uint32 &totalcount)
void BuildListOwnerItems(WorldPacket &data, Player *player, uint32 &count, uint32 &totalcount)
uint32 item_guidlow
uint32 id
Definition: Creature.h:271
uint32 GetItemSuffixFactor() const
Definition: Item.h:302
bool BeginTransaction()
Definition: Database.cpp:533
uint32 SellPrice
std::vector< std::string > Name
_Spell Spells[5]
#define auctionbot
void BuildListBidderItems(WorldPacket &data, Player *player, uint32 &count, uint32 &totalcount)
QueryResult_AutoPtr PQuery(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:400
Definition: Field.h:24
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
#define sLog
Log class singleton.
Definition: Log.h:187
STL namespace.
void DeleteFromDB() const
QueryResult_AutoPtr Query(const char *sql)
Definition: Database.cpp:383
uint32 SpellId
uint32 GetAccountId() const
Definition: WorldSession.h:100
uint32 GetGUIDLow() const
Definition: Object.h:160
void SendAuctionSalePendingMail(AuctionEntry *auction)
int32 GetItemRandomPropertyId() const
Definition: Item.h:298
#define sObjectMgr
Definition: ObjectMgr.h:1285
bool CommitTransaction()
Definition: Database.cpp:551
AuctionHouseEntry const * auctionHouseEntry
uint32 GetEnchantmentDuration(EnchantmentSlot slot) const
Definition: Item.h:317
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3813
ACE_UINT8 uint8
Definition: Define.h:73
#define UI64FMTD
Definition: Common.h:149
Item * NewItemOrBag(ItemTemplate const *proto)
Definition: Bag.h:70
uint32 faction
Definition: Creature.h:150
AuctionHouseObject * GetAuctionsMap(uint32 factionTemplateId)
void AddAItem(Item *it)
#define MAKE_NEW_GUID(l, e, h)
Definition: ObjectGuid.h:80
Definition: Item.h:196
uint32 RequiredLevel
static uint32 GetAuctionDeposit(AuctionHouseEntry const *entry, uint32 time, Item *pItem)
void SendAuctionOwnerNotification(AuctionEntry *auction)
uint32 secsToTimeBitFields(time_t secs)
Definition: Util.h:36
void SendAuctionExpiredMail(AuctionEntry *auction)
bool RemoveAItem(uint32 id)
time_t expire_time
DBCStorage< AuctionHouseEntry > sAuctionHouseStore(AuctionHouseEntryfmt)
void SendMailTo(MailReceiver const &receiver, MailSender const &sender, MailCheckMask checked=MAIL_CHECK_MASK_NONE, uint32 deliver_delay=0)
Definition: Mail.cpp:978
bool PExecute(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:441
#define sAccountMgr
Definition: AccountMgr.h:60
T CalculatePct(T base, U pct)
Definition: Util.h:103
uint32 GetAuctionCut() const
uint32 item_template
uint32 GetHouseId() const
const char * GetName() const
Definition: Object.h:692
virtual bool LoadFromDB(uint32 guid, uint64 owner_guid, Field *fields)
Definition: Item.cpp:369
ACE_UINT64 uint64
Definition: Define.h:70
uint32 GetEnchantmentCharges(EnchantmentSlot slot) const
Definition: Item.h:321
ACE_Refcounted_Auto_Ptr< QueryResult, ACE_Null_Mutex > QueryResult_AutoPtr
Definition: QueryResult.h:113
int GetSessionDbLocaleIndex() const
Definition: WorldSession.h:237
Definition: Common.h:180
void SendAuctionWonMail(AuctionEntry *auction)
void SendAuctionSuccessfulMail(AuctionEntry *auction)
EnchantmentSlot
Definition: Item.h:147
#define sAuctionMgr
#define ASSERT
Definition: Errors.h:33
bool RemoveAuction(AuctionEntry *auction, uint32 item_template)
uint32 GetEntry() const
Definition: Object.h:186
WorldSession * GetSession() const
Definition: Player.h:1959
#define sWorld
Definition: World.h:860
uint8 CanUseItem(Item *pItem, bool not_loading=true) const
Definition: Player.cpp:10128
DatabaseType CharacterDatabase
Accessor to the character database.
Definition: Main.cpp:54
void uint32 GetSecurity() const
Definition: WorldSession.h:96
ACE_UINT32 uint32
Definition: Define.h:71
#define MIN_AUCTION_TIME
Definition: Player.h:922
uint32 GetAuctionOutBid() const
void SendAuctionBidderNotification(uint32 location, uint32 auctionId, uint64 bidder, uint32 bidSum, uint32 diff, uint32 item_template)
static AuctionHouseEntry const * GetAuctionHouseEntry(uint32 factionTemplateId)
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition: Item.h:313