/* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef _AUCTION_HOUSE_SEARCHER_H #define _AUCTION_HOUSE_SEARCHER_H #include "AuctionHouseMgr.h" #include "Common.h" #include "Item.h" #include "LockedQueue.h" #include "MPSCQueue.h" #include "PCQueue.h" #include #include #include #include struct ItemTemplate; enum AuctionSortOrder { AUCTION_SORT_MINLEVEL = 0, AUCTION_SORT_RARITY = 1, AUCTION_SORT_BUYOUT = 2, AUCTION_SORT_TIMELEFT = 3, AUCTION_SORT_UNK4 = 4, AUCTION_SORT_ITEM = 5, AUCTION_SORT_MINBIDBUY = 6, AUCTION_SORT_OWNER = 7, AUCTION_SORT_BID = 8, AUCTION_SORT_STACK = 9, AUCTION_SORT_BUYOUT_2 = 10, AUCTION_SORT_MAX }; struct AuctionSortInfo { AuctionSortInfo() = default; AuctionSortOrder sortOrder{ AUCTION_SORT_MAX }; bool isDesc{ true }; }; struct AuctionEntryItemEnchants { uint32 id; uint32 duration; uint32 charges; }; struct SearchableAuctionEntryItem { std::wstring itemName[TOTAL_LOCALES]; uint32 entry; AuctionEntryItemEnchants enchants[MAX_INSPECTED_ENCHANTMENT_SLOT]; int32 randomPropertyId; uint32 suffixFactor; uint32 count; int32 spellCharges; ItemTemplate const* itemTemplate; }; struct SearchableAuctionEntry { uint32 Id; ObjectGuid ownerGuid; std::string ownerName; uint32 buyout; time_t expire_time; uint32 startbid; uint32 bid; ObjectGuid bidderGuid; AuctionHouseFaction listFaction; SearchableAuctionEntryItem item; void BuildAuctionInfo(WorldPacket& data) const; void SetItemNames(); int CompareAuctionEntry(uint32 column, SearchableAuctionEntry const& auc, int loc_idx) const; }; typedef std::vector AuctionSortOrderVector; struct AuctionHouseSearchInfo { std::wstring wsearchedname; uint32 listfrom; uint8 levelmin; uint8 levelmax; bool usable; uint32 inventoryType; uint32 itemClass; uint32 itemSubClass; uint32 quality; bool getAll; AuctionSortOrderVector sorting; }; typedef std::unordered_map AuctionPlayerSkills; typedef std::unordered_set AuctionPlayerSpells; struct AuctionHouseUsablePlayerInfo { uint32 classMask; uint32 raceMask; uint8 level; AuctionPlayerSkills skills; // active skills only AuctionPlayerSpells spells; // active spells only bool PlayerCanUseItem(ItemTemplate const* proto) const; uint16 GetSkillValue(uint32 skill) const; bool HasSpell(uint32 spell) const; }; struct AuctionHousePlayerInfo { ObjectGuid playerGuid; uint32 faction; int loc_idx; int locdbc_idx; std::optional usablePlayerInfo; }; struct AuctionSearcherRequest { enum class Type : uint8 { LIST, OWNER_LIST, BIDDER_LIST }; AuctionSearcherRequest(Type const _requestType, AuctionHouseFaction _listFaction) : requestType(_requestType), listFaction(_listFaction) { } virtual ~AuctionSearcherRequest() = default; Type requestType; AuctionHouseFaction listFaction; }; struct AuctionSearchListRequest : AuctionSearcherRequest { AuctionSearchListRequest(AuctionHouseFaction _listFaction, AuctionHouseSearchInfo const&& _searchInfo, AuctionHousePlayerInfo const&& _playerInfo) : AuctionSearcherRequest(AuctionSearcherRequest::Type::LIST, _listFaction), searchInfo(_searchInfo), playerInfo(_playerInfo) { } AuctionHouseSearchInfo searchInfo; AuctionHousePlayerInfo playerInfo; }; struct AuctionSearchOwnerListRequest : AuctionSearcherRequest { AuctionSearchOwnerListRequest(AuctionHouseFaction _listFaction, ObjectGuid _ownerGuid) : AuctionSearcherRequest(AuctionSearcherRequest::Type::OWNER_LIST, _listFaction), ownerGuid(_ownerGuid) { } ObjectGuid ownerGuid; }; struct AuctionSearchBidderListRequest : AuctionSearcherRequest { AuctionSearchBidderListRequest(AuctionHouseFaction _listFaction, std::vector const&& _outbiddedAuctionIds, ObjectGuid _ownerGuid) : AuctionSearcherRequest(AuctionSearcherRequest::Type::BIDDER_LIST, _listFaction), outbiddedAuctionIds(_outbiddedAuctionIds), ownerGuid(_ownerGuid) { } std::vector outbiddedAuctionIds; ObjectGuid ownerGuid; }; struct AuctionSearcherResponse { ObjectGuid playerGuid; WorldPacket packet; }; struct AuctionSearcherUpdate { enum class Type : uint8 { ADD, REMOVE, UPDATE_BID }; AuctionSearcherUpdate(Type const _updateType, AuctionHouseFaction _listFaction) : updateType(_updateType), listFaction(_listFaction) { } virtual ~AuctionSearcherUpdate() = default; Type updateType; AuctionHouseFaction listFaction; }; struct AuctionSearchAdd : AuctionSearcherUpdate { AuctionSearchAdd(std::shared_ptr _searchableAuctionEntry) : AuctionSearcherUpdate(AuctionSearcherUpdate::Type::ADD, _searchableAuctionEntry->listFaction), searchableAuctionEntry(_searchableAuctionEntry) { } std::shared_ptr searchableAuctionEntry; }; struct AuctionSearchRemove : AuctionSearcherUpdate { AuctionSearchRemove(uint32 _auctionId, AuctionHouseFaction _listFaction) : AuctionSearcherUpdate(AuctionSearcherUpdate::Type::REMOVE, _listFaction), auctionId(_auctionId) { } uint32 auctionId; }; struct AuctionSearchUpdateBid : AuctionSearcherUpdate { AuctionSearchUpdateBid(uint32 _auctionId, AuctionHouseFaction _listFaction, uint32 _bid, ObjectGuid _bidderGuid) : AuctionSearcherUpdate(AuctionSearcherUpdate::Type::UPDATE_BID, _listFaction), auctionId(_auctionId), bid(_bid), bidderGuid(_bidderGuid) { } uint32 auctionId; uint32 bid; ObjectGuid bidderGuid; }; typedef std::unordered_map> SearchableAuctionEntriesMap; typedef std::vector SortableAuctionEntriesList; class AuctionSorter { public: AuctionSorter(AuctionSortOrderVector const* sort, int loc_idx) : _sort(sort), _loc_idx(loc_idx) {} bool operator()(SearchableAuctionEntry const* auc1, SearchableAuctionEntry const* auc2) const; private: AuctionSortOrderVector const* _sort; int _loc_idx; }; class AuctionHouseWorkerThread { public: AuctionHouseWorkerThread(ProducerConsumerQueue* requestQueue, MPSCQueue* responseQueue); void Stop(); void AddAuctionSearchUpdateToQueue(std::shared_ptr const auctionSearchUpdate); private: void Run(); void ProcessSearchUpdates(); void SearchUpdateAdd(AuctionSearchAdd const& auctionAdd); void SearchUpdateRemove(AuctionSearchRemove const& auctionRemove); void SearchUpdateBid(AuctionSearchUpdateBid const& auctionUpdateBid); void ProcessSearchRequests(); void SearchListRequest(AuctionSearchListRequest const& searchListRequest); void SearchOwnerListRequest(AuctionSearchOwnerListRequest const& searchOwnerListRequest); void SearchBidderListRequest(AuctionSearchBidderListRequest const& searchBidderListRequest); void BuildListAuctionItems(AuctionSearchListRequest const& searchRequest, SortableAuctionEntriesList& auctionEntries, SearchableAuctionEntriesMap const& auctionMap) const; SearchableAuctionEntriesMap& GetSearchableAuctionMap(AuctionHouseFaction faction) { return _searchableAuctionMap[static_cast(faction)]; }; SearchableAuctionEntriesMap _searchableAuctionMap[MAX_AUCTION_HOUSE_FACTIONS]; LockedQueue> _auctionUpdatesQueue; ProducerConsumerQueue* _requestQueue; MPSCQueue* _responseQueue; std::thread _workerThread; std::atomic _stopped; }; class AuctionHouseSearcher { public: AuctionHouseSearcher(); ~AuctionHouseSearcher(); void Update(); void QueueSearchRequest(AuctionSearcherRequest* searchRequestInfo); void AddAuction(AuctionEntry const* auctionEntry); void RemoveAuction(AuctionEntry const* auctionEntry); void UpdateBid(AuctionEntry const* auctionEntry); void NotifyAllWorkers(std::shared_ptr const auctionSearchUpdate); void NotifyOneWorker(std::shared_ptr const auctionSearchUpdate); private: ProducerConsumerQueue _requestQueue; MPSCQueue _responseQueue; std::vector> _workerThreads; }; #endif