TrinityCore
AuctionHouseMgr.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore 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#ifndef _AUCTION_HOUSE_MGR_H
19#define _AUCTION_HOUSE_MGR_H
20
21#include "Define.h"
22#include "DatabaseEnvFwd.h"
23#include "Duration.h"
24#include "EnumFlag.h"
25#include "ItemTemplate.h"
26#include "ObjectGuid.h"
27#include "Optional.h"
28#include <map>
29#include <span>
30#include <unordered_map>
31
32class Item;
33class Player;
34class WorldPacket;
35
36namespace WorldPackets
37{
38 namespace AuctionHouse
39 {
40 struct AuctionBucketKey;
41 struct AuctionItem;
42 struct AuctionSortDef;
43 struct BucketInfo;
49 }
50}
51
52uint32 constexpr MIN_AUCTION_TIME = 12 * HOUR;
53
54enum class AuctionResult : int8
55{
56 Ok = 0,
57 Inventory = 1,
58 DatabaseError = 2,
60 ItemNotFound = 4,
61 HigherBid = 5,
62 BidIncrement = 7,
63 BidOwn = 10,
65 HasRestriction = 17,
69 ItemHasQuote = 23
70};
71
72enum class AuctionCommand : int8
73{
74 SellItem = 0,
75 Cancel = 1,
76 PlaceBid = 2
77};
78
80{
81 Outbid = 0,
82 Won = 1,
83 Sold = 2,
84 Expired = 3,
85 Removed = 4, // for bidder
86 Cancelled = 5, // for seller
87 Invoice = 6
88};
89
90enum class AuctionHouseResultLimits : std::size_t
91{
92 Browse = 500,
93 Items = 50
94};
95
96constexpr std::size_t MAX_FAVORITE_AUCTIONS = 100;
97
99{
100 None = 0x0,
101 UncollectedOnly = 0x1,
102 UsableOnly = 0x2,
103 UpgradesOnly = 0x4,
104 ExactMatch = 0x8,
105 PoorQuality = 0x10,
106 CommonQuality = 0x20,
107 UncommonQuality = 0x40,
108 RareQuality = 0x80,
109 EpicQuality = 0x100,
110 LegendaryQuality = 0x200,
111 ArtifactQuality = 0x400,
113};
114
116
118{
119 Price = 0,
120 Name = 1,
121 Level = 2,
122 Bid = 3,
123 Buyout = 4
124};
125
127{
128 Search = 0,
129 SpecificKeys = 1
130};
131
133{
134 Commodities = 1,
135 Items = 2
136};
137
139{
141 {
144 FILTER_SKIP_INVTYPE = 0xFFFFFFFF
145 };
146
148 {
150 std::array<uint64, MAX_ITEM_SUBCLASS_TOTAL> InvTypes = { };
151 };
152
153 std::array<SubclassFilter, MAX_ITEM_CLASS> Classes = { };
154};
155
157{
158 AuctionsBucketKey() = default;
159 AuctionsBucketKey(uint32 itemId, uint16 itemLevel, uint16 battlePetSpeciesId, uint16 suffixItemNameDescriptionId)
160 : ItemId(itemId), ItemLevel(itemLevel), BattlePetSpeciesId(battlePetSpeciesId), SuffixItemNameDescriptionId(suffixItemNameDescriptionId) { }
162
167
168 bool operator==(AuctionsBucketKey const& right) const = default;
169
170 friend std::strong_ordering operator<=>(AuctionsBucketKey const& left, AuctionsBucketKey const& right) = default;
171
172 static std::size_t Hash(AuctionsBucketKey const& key);
173 static AuctionsBucketKey ForItem(Item const* item);
174 static AuctionsBucketKey ForCommodity(ItemTemplate const* itemTemplate);
175};
176
177template<>
178struct std::hash<AuctionsBucketKey>
179{
180 size_t operator()(AuctionsBucketKey const& key) const noexcept
181 {
182 return AuctionsBucketKey::Hash(key);
183 }
184};
185
186struct AuctionPosting;
187
189{
191
192 // filter helpers
197 std::array<uint32, MAX_ITEM_QUALITY> QualityCounts = { };
198 uint64 MinPrice = 0; // for sort
199 std::array<std::pair<uint32, uint32>, 4> ItemModifiedAppearanceId = { }; // for uncollected search
200 uint8 RequiredLevel = 0; // for usable search
204 std::array<std::wstring, TOTAL_LOCALES> FullName = { };
205
206 std::vector<AuctionPosting*> Auctions;
207
208 void BuildBucketInfo(WorldPackets::AuctionHouse::BucketInfo* bucketInfo, Player const* player) const;
209
210 class Sorter;
211};
212
214{
215 None = 0x0,
216 GmLogBuyer = 0x1 // write transaction to gm log file for buyer (optimization flag - avoids querying database for offline player permissions)
217};
218
220
221// This structure represents the result of a single C_AuctionHouse.PostItem/PostCommodity call
223{
226
227 std::vector<Item*> Items;
235 SystemTimePoint StartTime = SystemTimePoint::min();
236 SystemTimePoint EndTime = SystemTimePoint::min();
238
240
241 bool IsCommodity() const;
243 void BuildAuctionItem(WorldPackets::AuctionHouse::AuctionItem* auctionItem, bool alwaysSendItem, bool sendKey, bool censorServerInfo, bool censorBidInfo) const;
244 static uint64 CalculateMinIncrement(uint64 bidAmount);
246
247 class Sorter;
248};
249
251{
254 TimePoint ValidTo = TimePoint::min();
255};
256
258{
261};
262
263//this class is used as auctionhouse instance
265{
266public:
267 explicit AuctionHouseObject(uint32 auctionHouseId);
273
275 {
277 uint32 Cursor = 0;
278 uint32 Tombstone = 0;
279 TimePoint NextAllowedReplication = TimePoint::min();
280
281 bool IsReplicationInProgress() const { return Cursor != Tombstone && Global != 0; }
282 };
283
284 uint32 GetAuctionHouseId() const;
285
286 std::map<uint32, AuctionPosting>::iterator GetAuctionsBegin() { return _itemsByAuctionId.begin(); }
287 std::map<uint32, AuctionPosting>::iterator GetAuctionsEnd() { return _itemsByAuctionId.end(); }
288
289 AuctionPosting* GetAuction(uint32 auctionId);
290
291 void AddAuction(CharacterDatabaseTransaction trans, AuctionPosting auction);
292
293 void RemoveAuction(CharacterDatabaseTransaction trans, AuctionPosting* auction, std::map<uint32, AuctionPosting>::iterator* auctionItr = nullptr);
294
295 void Update();
296
297 void BuildListBuckets(WorldPackets::AuctionHouse::AuctionListBucketsResult& listBucketsResult, Player const* player,
298 std::wstring const& name, uint8 minLevel, uint8 maxLevel, EnumFlag<AuctionHouseFilterMask> filters, Optional<AuctionSearchClassFilters> const& classFilters,
299 std::span<uint8 const> knownPetBits, uint8 maxKnownPetLevel,
300 uint32 offset, std::span<WorldPackets::AuctionHouse::AuctionSortDef const> sorts) const;
301 void BuildListBuckets(WorldPackets::AuctionHouse::AuctionListBucketsResult& listBucketsResult, Player const* player,
302 std::span<WorldPackets::AuctionHouse::AuctionBucketKey const> keys,
303 std::span<WorldPackets::AuctionHouse::AuctionSortDef const> sorts) const;
304 void BuildListBiddedItems(WorldPackets::AuctionHouse::AuctionListBiddedItemsResult& listBiddedItemsResult, Player const* player,
305 uint32 offset, std::span<WorldPackets::AuctionHouse::AuctionSortDef const> sorts) const;
306 void BuildListAuctionItems(WorldPackets::AuctionHouse::AuctionListItemsResult& listItemsResult, Player const* player, AuctionsBucketKey const& bucketKey,
307 uint32 offset, std::span<WorldPackets::AuctionHouse::AuctionSortDef const> sorts) const;
308 void BuildListAuctionItems(WorldPackets::AuctionHouse::AuctionListItemsResult& listItemsResult, Player const* player, uint32 itemId,
309 uint32 offset, std::span<WorldPackets::AuctionHouse::AuctionSortDef const> sorts) const;
310 void BuildListOwnedItems(WorldPackets::AuctionHouse::AuctionListOwnedItemsResult& listOwnedItemsResult, Player const* player,
311 uint32 offset, std::span<WorldPackets::AuctionHouse::AuctionSortDef const> sorts) const;
312 void BuildReplicate(WorldPackets::AuctionHouse::AuctionReplicateResponse& replicateResponse, Player* player,
313 uint32 global, uint32 cursor, uint32 tombstone, uint32 count);
314
315 uint64 CalculateAuctionHouseCut(uint64 bidAmount) const;
316
317 CommodityQuote const* CreateCommodityQuote(Player const* player, uint32 itemId, uint32 quantity);
318 void CancelCommodityQuote(ObjectGuid guid);
319 bool BuyCommodity(CharacterDatabaseTransaction trans, Player* player, uint32 itemId, uint32 quantity, Milliseconds delayForNextAction);
320
321 void SendAuctionOutbid(AuctionPosting const* auction, ObjectGuid newBidder, uint64 newBidAmount, CharacterDatabaseTransaction trans) const;
322 void SendAuctionWon(AuctionPosting const* auction, Player* bidder, CharacterDatabaseTransaction trans) const;
323 void SendAuctionSold(AuctionPosting const* auction, Player* owner, CharacterDatabaseTransaction trans) const;
324 void SendAuctionExpired(AuctionPosting const* auction, CharacterDatabaseTransaction trans) const;
325 void SendAuctionRemoved(AuctionPosting const* auction, Player* owner, CharacterDatabaseTransaction trans) const;
326 void SendAuctionCancelledToBidder(AuctionPosting const* auction, CharacterDatabaseTransaction trans) const;
327 void SendAuctionInvoice(AuctionPosting const* auction, Player* owner, CharacterDatabaseTransaction trans) const;
328
329private:
331
332 std::map<uint32, AuctionPosting> _itemsByAuctionId; // ordered for replicate
333 std::unordered_map<uint32, AuctionPosting> _soldItemsById;
334 std::map<AuctionsBucketKey, AuctionsBucketData> _buckets; // ordered for search by itemid only
335 std::unordered_map<ObjectGuid, CommodityQuote> _commodityQuotes;
336
337 std::unordered_multimap<ObjectGuid, uint32> _playerOwnedAuctions;
338 std::unordered_multimap<ObjectGuid, uint32> _playerBidderAuctions;
339
340 // Map of throttled players for GetAll, and throttle expiry time
341 // Stored here, rather than player object to maintain persistence after logout
342 std::unordered_map<ObjectGuid, PlayerReplicateThrottleData> _replicateThrottleMap;
343};
344
346{
347 private:
350
351 public:
356
357 static AuctionHouseMgr* instance();
358
359 AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId);
360 AuctionHouseObject* GetAuctionsById(uint32 auctionHouseId);
361
362 Item* GetAItem(ObjectGuid itemGuid);
363
364 static std::string BuildItemAuctionMailSubject(AuctionMailType type, AuctionPosting const* auction);
365 static std::string BuildCommodityAuctionMailSubject(AuctionMailType type, uint32 itemId, uint32 itemCount);
366 static std::string BuildAuctionMailSubject(uint32 itemId, AuctionMailType type, uint32 auctionId, uint32 itemCount, uint32 battlePetSpeciesId,
367 ItemContext context, std::vector<int32> const& bonusListIds);
368 static std::string BuildAuctionWonMailBody(ObjectGuid guid, uint64 bid, uint64 buyout);
369 static std::string BuildAuctionSoldMailBody(ObjectGuid guid, uint64 bid, uint64 buyout, uint32 deposit, uint64 consignment);
370 static std::string BuildAuctionInvoiceMailBody(ObjectGuid guid, uint64 bid, uint64 buyout, uint32 deposit, uint64 consignment, uint32 moneyDelay, uint32 eta);
371
372 static uint64 GetCommodityAuctionDeposit(ItemTemplate const* item, Minutes time, uint32 quantity);
373 static uint64 GetItemAuctionDeposit(Player const* player, Item const* item, Minutes time);
374 static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId, uint32* houseId);
375
376 public:
377
378 void LoadAuctions();
379
380 void AddAItem(Item* item);
381 bool RemoveAItem(ObjectGuid itemGuid, bool deleteItem = false, CharacterDatabaseTransaction* trans = nullptr);
382 bool PendingAuctionAdd(Player const* player, uint32 auctionHouseId, uint32 auctionId, uint64 deposit);
383 std::size_t PendingAuctionCount(Player const* player) const;
384 void PendingAuctionProcess(Player* player);
385 void UpdatePendingAuctions();
386 void Update();
387
388 uint32 GenerateReplicationId();
389
390 AuctionThrottleResult CheckThrottle(Player const* player, bool addonTainted, AuctionCommand command = AuctionCommand::SellItem);
391
392 private:
393
398
400 {
401 uint32 AuctionId = 0;
402 uint32 AuctionHouseId = 0;
403 uint64 Deposit = 0;
404 };
405
407 {
408 std::vector<PendingAuctionInfo> Auctions;
409 std::size_t LastAuctionsSize = 0;
410 };
411
413 {
415 uint8 QueriesRemaining = 100;
416 };
417
418 std::unordered_map<ObjectGuid, PlayerPendingAuctions> _pendingAuctionsByPlayer;
419
420 std::unordered_map<ObjectGuid, Item*> _itemsByGuid;
421
423
424 std::unordered_map<ObjectGuid, PlayerThrottleObject> _playerThrottleObjects;
426};
427
428#define sAuctionMgr AuctionHouseMgr::instance()
429
430#endif
AuctionHouseResultLimits
AuctionHouseListType
uint32 constexpr MIN_AUCTION_TIME
DEFINE_ENUM_FLAG(AuctionHouseFilterMask)
AuctionHouseSortOrder
AuctionHouseFilterMask
AuctionResult
constexpr std::size_t MAX_FAVORITE_AUCTIONS
AuctionHouseBrowseMode
AuctionPostingServerFlag
AuctionCommand
AuctionMailType
@ HOUR
Definition: Common.h:30
ItemContext
Definition: DBCEnums.h:1063
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
#define TC_GAME_API
Definition: Define.h:123
uint8_t uint8
Definition: Define.h:144
int8_t int8
Definition: Define.h:140
int32_t int32
Definition: Define.h:138
uint64_t uint64
Definition: Define.h:141
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
std::chrono::system_clock::time_point SystemTimePoint
Definition: Duration.h:42
std::chrono::steady_clock::time_point TimePoint
time_point shorthand typedefs
Definition: Duration.h:41
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:29
std::chrono::minutes Minutes
Minutes shorthand typedef.
Definition: Duration.h:35
ItemClass
Definition: ItemTemplate.h:419
InventoryType
Definition: ItemTemplate.h:378
std::unordered_set< ObjectGuid > GuidUnorderedSet
Definition: ObjectGuid.h:396
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
Classes
AuctionHouseMgr(AuctionHouseMgr &&)=delete
AuctionHouseMgr & operator=(AuctionHouseMgr &&)=delete
TimePoint _playerThrottleObjectsCleanupTime
AuctionHouseMgr(AuctionHouseMgr const &)=delete
AuctionHouseObject mGoblinAuctions
uint32 _replicateIdGenerator
AuctionHouseObject mNeutralAuctions
AuctionHouseObject mHordeAuctions
AuctionHouseObject mAllianceAuctions
std::unordered_map< ObjectGuid, PlayerThrottleObject > _playerThrottleObjects
AuctionHouseMgr & operator=(AuctionHouseMgr const &)=delete
std::unordered_map< ObjectGuid, PlayerPendingAuctions > _pendingAuctionsByPlayer
std::unordered_map< ObjectGuid, Item * > _itemsByGuid
std::map< uint32, AuctionPosting >::iterator GetAuctionsEnd()
std::unordered_multimap< ObjectGuid, uint32 > _playerBidderAuctions
std::unordered_map< ObjectGuid, CommodityQuote > _commodityQuotes
std::map< uint32, AuctionPosting > _itemsByAuctionId
std::unordered_multimap< ObjectGuid, uint32 > _playerOwnedAuctions
AuctionHouseObject(AuctionHouseObject &&)=delete
std::map< AuctionsBucketKey, AuctionsBucketData > _buckets
AuctionHouseObject(AuctionHouseObject const &)=delete
std::unordered_map< ObjectGuid, PlayerReplicateThrottleData > _replicateThrottleMap
AuctionHouseObject & operator=(AuctionHouseObject &&)=delete
AuctionHouseObject & operator=(AuctionHouseObject const &)=delete
AuctionHouseEntry const * _auctionHouse
std::unordered_map< uint32, AuctionPosting > _soldItemsById
std::map< uint32, AuctionPosting >::iterator GetAuctionsBegin()
Definition: Item.h:170
void Update(VignetteData &vignette, WorldObject const *owner)
Definition: Vignette.cpp:90
std::vector< PendingAuctionInfo > Auctions
bool IsCommodity() const
ObjectGuid Bidder
void BuildAuctionItem(WorldPackets::AuctionHouse::AuctionItem *auctionItem, bool alwaysSendItem, bool sendKey, bool censorServerInfo, bool censorBidInfo) const
std::vector< Item * > Items
AuctionsBucketData * Bucket
ObjectGuid Owner
EnumFlag< AuctionPostingServerFlag > ServerFlags
ObjectGuid OwnerAccount
uint64 BuyoutOrUnitPrice
SystemTimePoint StartTime
uint32 GetTotalItemCount() const
GuidUnorderedSet BidderHistory
uint64 CalculateMinIncrement() const
SystemTimePoint EndTime
std::array< uint64, MAX_ITEM_SUBCLASS_TOTAL > InvTypes
Milliseconds DelayUntilNext
AuctionsBucketKey Key
std::array< std::wstring, TOTAL_LOCALES > FullName
AuctionHouseFilterMask QualityMask
std::array< std::pair< uint32, uint32 >, 4 > ItemModifiedAppearanceId
void BuildBucketInfo(WorldPackets::AuctionHouse::BucketInfo *bucketInfo, Player const *player) const
std::vector< AuctionPosting * > Auctions
std::array< uint32, MAX_ITEM_QUALITY > QualityCounts
uint16 SuffixItemNameDescriptionId
AuctionsBucketKey(uint32 itemId, uint16 itemLevel, uint16 battlePetSpeciesId, uint16 suffixItemNameDescriptionId)
bool operator==(AuctionsBucketKey const &right) const =default
static AuctionsBucketKey ForCommodity(ItemTemplate const *itemTemplate)
static AuctionsBucketKey ForItem(Item const *item)
friend std::strong_ordering operator<=>(AuctionsBucketKey const &left, AuctionsBucketKey const &right)=default
AuctionsBucketKey()=default
static std::size_t Hash(AuctionsBucketKey const &key)
size_t operator()(AuctionsBucketKey const &key) const noexcept