TrinityCore
Loading...
Searching...
No Matches
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 = 0x0000,
101 UncollectedOnly = 0x0002,
102 UsableOnly = 0x0004,
103 CurrentExpansionOnly = 0x0008,
104 UpgradesOnly = 0x0010,
105 ExactMatch = 0x0020,
106 PoorQuality = 0x0040,
107 CommonQuality = 0x0080,
108 UncommonQuality = 0x0100,
109 RareQuality = 0x0200,
110 EpicQuality = 0x0400,
111 LegendaryQuality = 0x0800,
112 ArtifactQuality = 0x1000,
114};
115
117
119{
120 Price = 0,
121 Name = 1,
122 Level = 2,
123 Bid = 3,
124 Buyout = 4,
125 TimeRemaining = 5
126};
127
129{
130 Search = 0,
131 SpecificKeys = 1
132};
133
135{
136 Commodities = 1,
137 Items = 2
138};
139
141{
148
150 {
152 std::array<uint64, MAX_ITEM_SUBCLASS_TOTAL> InvTypes = { };
153 };
154
155 std::array<SubclassFilter, MAX_ITEM_CLASS> Classes = { };
156};
157
159{
160 AuctionsBucketKey() = default;
161 AuctionsBucketKey(uint32 itemId, uint16 itemLevel, uint16 battlePetSpeciesId, uint16 suffixItemNameDescriptionId)
162 : ItemId(itemId), ItemLevel(itemLevel), BattlePetSpeciesId(battlePetSpeciesId), SuffixItemNameDescriptionId(suffixItemNameDescriptionId) { }
164
169
170 bool operator==(AuctionsBucketKey const& right) const = default;
171
172 friend std::strong_ordering operator<=>(AuctionsBucketKey const& left, AuctionsBucketKey const& right) = default;
173
174 static std::size_t Hash(AuctionsBucketKey const& key);
175 static AuctionsBucketKey ForItem(Item const* item);
176 static AuctionsBucketKey ForCommodity(ItemTemplate const* itemTemplate);
177};
178
179template<>
180struct std::hash<AuctionsBucketKey>
181{
182 size_t operator()(AuctionsBucketKey const& key) const noexcept
183 {
184 return AuctionsBucketKey::Hash(key);
185 }
186};
187
188struct AuctionPosting;
189
191{
193
194 // filter helpers
199 std::array<uint32, MAX_ITEM_QUALITY> QualityCounts = { };
200 uint64 MinPrice = 0; // for sort
201 std::array<std::pair<uint32, uint32>, 4> ItemModifiedAppearanceId = { }; // for uncollected search
202 uint8 RequiredLevel = 0; // for usable search
206 std::array<std::wstring, TOTAL_LOCALES> FullName = { };
207
208 std::vector<AuctionPosting*> Auctions;
209
210 void BuildBucketInfo(WorldPackets::AuctionHouse::BucketInfo* bucketInfo, Player const* player) const;
211
212 class Sorter;
213};
214
216{
217 None = 0x0,
218 GmLogBuyer = 0x1 // write transaction to gm log file for buyer (optimization flag - avoids querying database for offline player permissions)
219};
220
222
223// This structure represents the result of a single C_AuctionHouse.PostItem/PostCommodity call
225{
228
229 std::vector<Item*> Items;
237 SystemTimePoint StartTime = SystemTimePoint::min();
238 SystemTimePoint EndTime = SystemTimePoint::min();
240
242
243 bool IsCommodity() const;
245 void BuildAuctionItem(WorldPackets::AuctionHouse::AuctionItem* auctionItem, bool alwaysSendItem, bool sendKey, bool censorServerInfo, bool censorBidInfo) const;
246 static uint64 CalculateMinIncrement(uint64 bidAmount);
248
249 class Sorter;
250};
251
253{
256 TimePoint ValidTo = TimePoint::min();
257};
258
264
265//this class is used as auctionhouse instance
267{
268public:
269 explicit AuctionHouseObject(uint32 auctionHouseId);
275
277 {
279 uint32 Cursor = 0;
280 uint32 Tombstone = 0;
281 TimePoint NextAllowedReplication = TimePoint::min();
282
283 bool IsReplicationInProgress() const { return Cursor != Tombstone && Global != 0; }
284 };
285
286 uint32 GetAuctionHouseId() const;
287
288 std::map<uint32, AuctionPosting>::iterator GetAuctionsBegin() { return _itemsByAuctionId.begin(); }
289 std::map<uint32, AuctionPosting>::iterator GetAuctionsEnd() { return _itemsByAuctionId.end(); }
290
291 AuctionPosting* GetAuction(uint32 auctionId);
292
293 void AddAuction(CharacterDatabaseTransaction trans, AuctionPosting auction);
294
295 std::map<uint32, AuctionPosting>::node_type RemoveAuction(CharacterDatabaseTransaction trans, AuctionPosting* auction,
296 std::map<uint32, AuctionPosting>::iterator* auctionItr = nullptr);
297
298 void Update();
299
300 void BuildListBuckets(WorldPackets::AuctionHouse::AuctionListBucketsResult& listBucketsResult, Player const* player,
301 std::wstring const& name, uint8 minLevel, uint8 maxLevel, EnumFlag<AuctionHouseFilterMask> filters, Optional<AuctionSearchClassFilters> const& classFilters,
302 std::span<uint8 const> knownPetBits, uint8 maxKnownPetLevel,
303 uint32 offset, std::span<WorldPackets::AuctionHouse::AuctionSortDef const> sorts) const;
304 void BuildListBuckets(WorldPackets::AuctionHouse::AuctionListBucketsResult& listBucketsResult, Player const* player,
305 std::span<WorldPackets::AuctionHouse::AuctionBucketKey const> keys,
306 std::span<WorldPackets::AuctionHouse::AuctionSortDef const> sorts) const;
307 void BuildListBiddedItems(WorldPackets::AuctionHouse::AuctionListBiddedItemsResult& listBiddedItemsResult, Player const* player,
308 uint32 offset, std::span<WorldPackets::AuctionHouse::AuctionSortDef const> sorts) const;
309 void BuildListAuctionItems(WorldPackets::AuctionHouse::AuctionListItemsResult& listItemsResult, Player const* player, AuctionsBucketKey const& bucketKey,
310 uint32 offset, std::span<WorldPackets::AuctionHouse::AuctionSortDef const> sorts) const;
311 void BuildListAuctionItems(WorldPackets::AuctionHouse::AuctionListItemsResult& listItemsResult, Player const* player, uint32 itemId,
312 uint32 offset, std::span<WorldPackets::AuctionHouse::AuctionSortDef const> sorts) const;
313 void BuildListOwnedItems(WorldPackets::AuctionHouse::AuctionListOwnedItemsResult& listOwnedItemsResult, Player const* player,
314 uint32 offset, std::span<WorldPackets::AuctionHouse::AuctionSortDef const> sorts) const;
315 void BuildReplicate(WorldPackets::AuctionHouse::AuctionReplicateResponse& replicateResponse, Player* player,
316 uint32 global, uint32 cursor, uint32 tombstone, uint32 count);
317
318 uint64 CalculateAuctionHouseCut(uint64 bidAmount) const;
319
320 CommodityQuote const* CreateCommodityQuote(Player const* player, uint32 itemId, uint32 quantity);
321 void CancelCommodityQuote(ObjectGuid guid);
322 bool BuyCommodity(CharacterDatabaseTransaction trans, Player* player, uint32 itemId, uint32 quantity, Milliseconds delayForNextAction);
323
324 void SendAuctionOutbid(AuctionPosting const* auction, ObjectGuid newBidder, uint64 newBidAmount, CharacterDatabaseTransaction trans) const;
325 void SendAuctionWon(AuctionPosting const* auction, Player* bidder, CharacterDatabaseTransaction trans) const;
326 void SendAuctionSold(AuctionPosting const* auction, Player* owner, CharacterDatabaseTransaction trans) const;
327 void SendAuctionExpired(AuctionPosting const* auction, CharacterDatabaseTransaction trans) const;
328 void SendAuctionRemoved(AuctionPosting const* auction, Player* owner, CharacterDatabaseTransaction trans) const;
329 void SendAuctionCancelledToBidder(AuctionPosting const* auction, CharacterDatabaseTransaction trans) const;
330 void SendAuctionInvoice(AuctionPosting const* auction, Player* owner, CharacterDatabaseTransaction trans) const;
331
332private:
334
335 std::map<uint32, AuctionPosting> _itemsByAuctionId; // ordered for replicate
336 std::unordered_map<uint32, AuctionPosting> _soldItemsById;
337 std::map<AuctionsBucketKey, AuctionsBucketData> _buckets; // ordered for search by itemid only
338 std::unordered_map<ObjectGuid, CommodityQuote> _commodityQuotes;
339
340 std::unordered_multimap<ObjectGuid, uint32> _playerOwnedAuctions;
341 std::unordered_multimap<ObjectGuid, uint32> _playerBidderAuctions;
342
343 // Map of throttled players for GetAll, and throttle expiry time
344 // Stored here, rather than player object to maintain persistence after logout
345 std::unordered_map<ObjectGuid, PlayerReplicateThrottleData> _replicateThrottleMap;
346};
347
349{
350 private:
353
354 public:
359
360 static AuctionHouseMgr* instance();
361
362 AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId);
363 AuctionHouseObject* GetAuctionsById(uint32 auctionHouseId);
364
365 Item* GetAItem(ObjectGuid itemGuid);
366
367 static std::string BuildItemAuctionMailSubject(AuctionMailType type, AuctionPosting const* auction);
368 static std::string BuildCommodityAuctionMailSubject(AuctionMailType type, uint32 itemId, uint32 itemCount);
369 static std::string BuildAuctionMailSubject(uint32 itemId, AuctionMailType type, uint32 auctionId, uint32 itemCount, uint32 battlePetSpeciesId,
370 ItemContext context, std::vector<int32> const& bonusListIds);
371 static std::string BuildAuctionWonMailBody(ObjectGuid guid, uint64 bid, uint64 buyout);
372 static std::string BuildAuctionSoldMailBody(ObjectGuid guid, uint64 bid, uint64 buyout, uint32 deposit, uint64 consignment);
373 static std::string BuildAuctionInvoiceMailBody(ObjectGuid guid, uint64 bid, uint64 buyout, uint32 deposit, uint64 consignment, uint32 moneyDelay, uint32 eta);
374
375 static uint64 GetCommodityAuctionDeposit(ItemTemplate const* item, Minutes time, uint32 quantity);
376 static uint64 GetItemAuctionDeposit(Player const* player, Item const* item, Minutes time);
377 static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId, uint32* houseId);
378
379 public:
380
381 void LoadAuctions();
382
383 void AddAItem(Item* item);
384 bool RemoveAItem(ObjectGuid itemGuid, bool deleteItem = false, CharacterDatabaseTransaction* trans = nullptr);
385 bool PendingAuctionAdd(Player const* player, uint32 auctionHouseId, uint32 auctionId, uint64 deposit);
386 std::size_t PendingAuctionCount(Player const* player) const;
387 void PendingAuctionProcess(Player* player);
388 void UpdatePendingAuctions();
389 void Update();
390
391 uint32 GenerateReplicationId();
392
393 AuctionThrottleResult CheckThrottle(Player const* player, bool addonTainted, AuctionCommand command = AuctionCommand::SellItem);
394
395 private:
396
401
403 {
404 uint32 AuctionId = 0;
405 uint32 AuctionHouseId = 0;
406 uint64 Deposit = 0;
407 };
408
410 {
411 std::vector<PendingAuctionInfo> Auctions;
412 std::size_t LastAuctionsSize = 0;
413 };
414
416 {
418 uint8 QueriesRemaining = 100;
419 };
420
421 std::unordered_map<ObjectGuid, PlayerPendingAuctions> _pendingAuctionsByPlayer;
422
423 std::unordered_map<ObjectGuid, Item*> _itemsByGuid;
424
426
427 std::unordered_map<ObjectGuid, PlayerThrottleObject> _playerThrottleObjects;
429};
430
431#define sAuctionMgr AuctionHouseMgr::instance()
432
433#endif
AuctionHouseResultLimits
AuctionHouseListType
uint32 constexpr MIN_AUCTION_TIME
AuctionHouseSortOrder
AuctionHouseFilterMask
AuctionResult
constexpr std::size_t MAX_FAVORITE_AUCTIONS
AuctionHouseBrowseMode
AuctionPostingServerFlag
AuctionCommand
AuctionMailType
@ HOUR
Definition Common.h:33
ItemContext
Definition DBCEnums.h:1315
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
#define TC_GAME_API
Definition Define.h:129
uint8_t uint8
Definition Define.h:156
int8_t int8
Definition Define.h:152
int32_t int32
Definition Define.h:150
uint64_t uint64
Definition Define.h:153
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
std::chrono::system_clock::time_point SystemTimePoint
Definition Duration.h:41
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
std::chrono::steady_clock::time_point TimePoint
time_point shorthand typedefs
Definition Duration.h:40
std::chrono::minutes Minutes
Minutes shorthand typedef.
Definition Duration.h:32
#define DEFINE_ENUM_FLAG(enumType)
Definition EnumFlag.h:26
ItemClass
InventoryType
std::unordered_set< ObjectGuid > GuidUnorderedSet
Definition ObjectGuid.h:435
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
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:179
std::vector< PendingAuctionInfo > Auctions
bool IsCommodity() const
void BuildAuctionItem(WorldPackets::AuctionHouse::AuctionItem *auctionItem, bool alwaysSendItem, bool sendKey, bool censorServerInfo, bool censorBidInfo) const
std::vector< Item * > Items
AuctionsBucketData * Bucket
EnumFlag< AuctionPostingServerFlag > ServerFlags
ObjectGuid OwnerAccount
SystemTimePoint StartTime
uint32 GetTotalItemCount() const
GuidUnorderedSet BidderHistory
uint64 CalculateMinIncrement() const
SystemTimePoint EndTime
std::array< uint64, MAX_ITEM_SUBCLASS_TOTAL > InvTypes
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