aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp43
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.h11
-rw-r--r--src/server/game/Handlers/AuctionHouseHandler.cpp8
-rw-r--r--src/server/game/World/World.cpp7
-rw-r--r--src/server/game/World/World.h2
-rw-r--r--src/server/worldserver/worldserver.conf.dist18
6 files changed, 79 insertions, 10 deletions
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index f3c20750069..035d9af4369 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -573,6 +573,14 @@ void AuctionHouseObject::Update()
if (AuctionsMap.empty())
return;
+ // Clear expired throttled players
+ for (PlayerGetAllThrottleMap::const_iterator itr = GetAllThrottleMap.begin(); itr != GetAllThrottleMap.end();)
+ {
+ if (itr->second <= curTime)
+ itr = GetAllThrottleMap.erase(itr);
+ else
+ ++itr;
+ }
SQLTransaction trans = CharacterDatabase.BeginTransaction();
@@ -648,13 +656,40 @@ void AuctionHouseObject::BuildListOwnerItems(WorldPacket& data, Player* player,
void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player,
std::wstring const& wsearchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, uint8 usable,
uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality,
- uint32& count, uint32& totalcount)
+ uint32& count, uint32& totalcount, bool getall)
{
int loc_idx = player->GetSession()->GetSessionDbLocaleIndex();
int locdbc_idx = player->GetSession()->GetSessionDbcLocale();
time_t curTime = sWorld->GetGameTime();
+ PlayerGetAllThrottleMap::const_iterator itr = GetAllThrottleMap.find(player->GetGUID());
+ time_t throttleTime = itr != GetAllThrottleMap.end() ? itr->second : curTime;
+
+ if (getall && throttleTime <= curTime)
+ {
+ for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr)
+ {
+ AuctionEntry* Aentry = itr->second;
+ // Skip expired auctions
+ if (Aentry->expire_time < curTime)
+ continue;
+
+ Item* item = sAuctionMgr->GetAItem(Aentry->itemGUIDLow);
+ if (!item)
+ continue;
+
+ ++count;
+ ++totalcount;
+ Aentry->BuildAuctionInfo(data, item);
+
+ if (count >= MAX_GETALL_RETURN)
+ break;
+ }
+ GetAllThrottleMap[player->GetGUID()] = curTime + sWorld->getIntConfig(CONFIG_AUCTION_GETALL_DELAY);
+ return;
+ }
+
for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr)
{
AuctionEntry* Aentry = itr->second;
@@ -744,16 +779,16 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player
if (count < 50 && totalcount >= listfrom)
{
++count;
- Aentry->BuildAuctionInfo(data);
+ Aentry->BuildAuctionInfo(data, item);
}
++totalcount;
}
}
//this function inserts to WorldPacket auction's data
-bool AuctionEntry::BuildAuctionInfo(WorldPacket& data) const
+bool AuctionEntry::BuildAuctionInfo(WorldPacket& data, Item* sourceItem) const
{
- Item* item = sAuctionMgr->GetAItem(itemGUIDLow);
+ Item* item = (sourceItem) ? sourceItem : sAuctionMgr->GetAItem(itemGUIDLow);
if (!item)
{
TC_LOG_ERROR("misc", "AuctionEntry::BuildAuctionInfo: Auction %u has a non-existent item: %u", Id, itemGUIDLow);
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h
index 4a2b79ab170..fe4b9ed07de 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.h
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h
@@ -30,6 +30,7 @@ class WorldPacket;
#define MIN_AUCTION_TIME (12*HOUR)
#define MAX_AUCTION_ITEMS 160
+#define MAX_GETALL_RETURN 55000
enum AuctionError
{
@@ -90,7 +91,7 @@ struct AuctionEntry
uint8 GetHouseId() const { return houseId; }
uint32 GetAuctionCut() const;
uint32 GetAuctionOutBid() const;
- bool BuildAuctionInfo(WorldPacket & data) const;
+ bool BuildAuctionInfo(WorldPacket & data, Item* sourceItem = nullptr) const;
void DeleteFromDB(SQLTransaction& trans) const;
void SaveToDB(SQLTransaction& trans) const;
bool LoadFromDB(Field* fields);
@@ -110,6 +111,7 @@ class AuctionHouseObject
}
typedef std::map<uint32, AuctionEntry*> AuctionEntryMap;
+ typedef std::unordered_map<ObjectGuid, time_t> PlayerGetAllThrottleMap;
uint32 Getcount() const { return AuctionsMap.size(); }
@@ -133,10 +135,15 @@ class AuctionHouseObject
void BuildListAuctionItems(WorldPacket& data, Player* player,
std::wstring const& searchedname, uint32 listfrom, uint8 levelmin, uint8 levelmax, uint8 usable,
uint32 inventoryType, uint32 itemClass, uint32 itemSubClass, uint32 quality,
- uint32& count, uint32& totalcount);
+ uint32& count, uint32& totalcount, bool getall = false);
private:
AuctionEntryMap AuctionsMap;
+
+ // Map of throttled players for GetAll, and throttle expiry time
+ // Stored here, rather than player object to maintain persistence after logout
+ PlayerGetAllThrottleMap GetAllThrottleMap;
+
};
class AuctionHouseMgr
diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp
index f23888cab03..efe0526baae 100644
--- a/src/server/game/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Handlers/AuctionHouseHandler.cpp
@@ -706,7 +706,7 @@ void WorldSession::HandleAuctionListItems(WorldPacket& recvData)
TC_LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_LIST_ITEMS");
std::string searchedname;
- uint8 levelmin, levelmax, usable;
+ uint8 levelmin, levelmax, usable, getAll;
uint32 listfrom, auctionSlotID, auctionMainCategory, auctionSubCategory, quality;
ObjectGuid guid;
@@ -718,7 +718,7 @@ void WorldSession::HandleAuctionListItems(WorldPacket& recvData)
recvData >> auctionSlotID >> auctionMainCategory >> auctionSubCategory;
recvData >> quality >> usable;
- recvData.read_skip<uint8>(); // unk
+ recvData >> getAll;
// this block looks like it uses some lame byte packing or similar...
uint8 unkCnt;
@@ -760,11 +760,11 @@ void WorldSession::HandleAuctionListItems(WorldPacket& recvData)
auctionHouse->BuildListAuctionItems(data, _player,
wsearchedname, listfrom, levelmin, levelmax, usable,
auctionSlotID, auctionMainCategory, auctionSubCategory, quality,
- count, totalcount);
+ count, totalcount, (getAll != 0 && sWorld->getIntConfig(CONFIG_AUCTION_GETALL_DELAY) != 0));
data.put<uint32>(0, count);
data << (uint32) totalcount;
- data << (uint32) 300; // unk 2.3.0 const?
+ data << (uint32) sWorld->getIntConfig(CONFIG_AUCTION_SEARCH_DELAY);
SendPacket(&data);
}
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 09cc9180a57..289a4d47666 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -575,6 +575,13 @@ void World::LoadConfigSettings(bool reload)
m_bool_configs[CONFIG_ADDON_CHANNEL] = sConfigMgr->GetBoolDefault("AddonChannel", true);
m_bool_configs[CONFIG_CLEAN_CHARACTER_DB] = sConfigMgr->GetBoolDefault("CleanCharacterDB", false);
m_int_configs[CONFIG_PERSISTENT_CHARACTER_CLEAN_FLAGS] = sConfigMgr->GetIntDefault("PersistentCharacterCleanFlags", 0);
+ m_int_configs[CONFIG_AUCTION_GETALL_DELAY] = sConfigMgr->GetIntDefault("Auction.GetAllScanDelay", 900);
+ m_int_configs[CONFIG_AUCTION_SEARCH_DELAY] = sConfigMgr->GetIntDefault("Auction.SearchDelay", 300);
+ if (m_int_configs[CONFIG_AUCTION_SEARCH_DELAY] < 100 || m_int_configs[CONFIG_AUCTION_SEARCH_DELAY] > 10000)
+ {
+ TC_LOG_ERROR("server.loading", "Auction.SearchDelay (%i) must be between 100 and 10000. Using default of 300ms", m_int_configs[CONFIG_AUCTION_SEARCH_DELAY]);
+ m_int_configs[CONFIG_AUCTION_SEARCH_DELAY] = 300;
+ }
m_int_configs[CONFIG_CHAT_CHANNEL_LEVEL_REQ] = sConfigMgr->GetIntDefault("ChatLevelReq.Channel", 1);
m_int_configs[CONFIG_CHAT_WHISPER_LEVEL_REQ] = sConfigMgr->GetIntDefault("ChatLevelReq.Whisper", 1);
m_int_configs[CONFIG_CHAT_SAY_LEVEL_REQ] = sConfigMgr->GetIntDefault("ChatLevelReq.Say", 1);
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index a624fd6e6a7..00b244c9efb 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -356,6 +356,8 @@ enum WorldIntConfigs
CONFIG_CHARTER_COST_ARENA_5v5,
CONFIG_NO_GRAY_AGGRO_ABOVE,
CONFIG_NO_GRAY_AGGRO_BELOW,
+ CONFIG_AUCTION_GETALL_DELAY,
+ CONFIG_AUCTION_SEARCH_DELAY,
INT_CONFIG_VALUE_COUNT
};
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 5b07dde22bb..217995cb88a 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -406,6 +406,24 @@ CleanCharacterDB = 0
PersistentCharacterCleanFlags = 0
#
+# Auction.GetAllScanDelay
+# Description: Sets the minimum time in seconds, a single player character can perform a getall scan.
+# The value is only held in memory so a server restart will clear it.
+# Setting this to zero, will disable GetAll functions completely.
+# Default: 900 - (GetAll scan limited to once every 15mins per player character)
+
+Auction.GetAllScanDelay = 900
+
+#
+# Auction.SearchDelay
+# Description: Sets the minimum time in milliseconds (seconds x 1000), that the client must wait between
+# auction search operations. This can be increased if somehow Auction House activity is causing
+# too much load.
+# Default: 300 - (Time delay between auction searches set to 0.3secs)
+
+Auction.SearchDelay = 300
+
+#
###################################################################################################
###################################################################################################