diff --git a/conf/mod_ahbot.conf.dist b/conf/mod_ahbot.conf.dist index 65598e1..027eb6c 100644 --- a/conf/mod_ahbot.conf.dist +++ b/conf/mod_ahbot.conf.dist @@ -11,10 +11,14 @@ # Default: false (disabled) # # AuctionHouseBot.AuctionHouseManagerCyclesBetweenBuyOrSell -# How many cycles to wait between executing any buying or selling logic -# - At this time, the AzerothCore has it set as 1 minute inside the -# AuctionHouseMgr.cpp file -# Default 1 (once per AuctionHouseMgr.cpp update cycle) +# How many cycles to wait between executing any buying and selling logic. +# At this time, AzerothCore waits 1 minute between cycles as defined by +# the AuctionHouseMgr.cpp file. +# Value can be a single number in order to wait X cycles between buying +# and selling, or a pair of numbers separated by a ':' to wait a random +# number of cycles between X and Y before buying and selling (e.g. 3:15 to +# wait 3-15 minutes between cycles). +# Default: 1 # # AuctionHouseBot.EnableSeller # Enable/Disable the part of AHBot that puts items up for auction @@ -139,11 +143,14 @@ AuctionHouseBot.Neutral.MaxItems = 15000 # How many to items to price and attempt to buy. Note, this number of # items will be selected from each of the auction house types (Alliance, # Horde, Neutral). Meaning if you set this as 10, then up to 10 items -# from will be selected (total of 30). Whole numbers only. Very large -# values can impact server performance, and is generally not neccessary. -# This runs every minute (which is the auction house update loop time, -# defined by azerothcore core inside the AuctionHouseMgr.cpp file). -# Default: 1 (1 item per auction house is considered per minute) +# from each AH will be selected (total of 30). Whole numbers only. +# Very large values can impact server performance, and is generally +# not neccessary. This runs once every Buy/Sell cycle as defined +# by AuctionHouseBot.AuctionHouseManagerCyclesBetweenBuyOrSell. +# Value can be a single number in order to consider buying X items each +# Buy/Sell cycle, or a pair of numbers separated by a ':' to consider +# buying a random number between X and Y items. (e.g. 1:5 to consider 1-5 items) +# Default: 1 (1 item per auction house is considered per Buy/Sell cycle) # # AuctionHouseBot.Buyer.AcceptablePriceModifier # The buyer bot calculates item prices the same way the selling diff --git a/src/AuctionHouseBot.cpp b/src/AuctionHouseBot.cpp index 67936ef..3028645 100644 --- a/src/AuctionHouseBot.cpp +++ b/src/AuctionHouseBot.cpp @@ -41,14 +41,17 @@ AuctionHouseBot::AuctionHouseBot() : debug_Out_Filters(false), SellingBotEnabled(false), BuyingBotEnabled(false), + CyclesBetweenBuyOrSellMin(1), CyclesBetweenBuyOrSell(1), + CyclesBetweenBuyOrSellMax(1), MaxBuyoutPriceInCopper(1000000000), BuyoutVariationReducePercent(0.15f), BuyoutVariationAddPercent(0.25f), BidVariationHighReducePercent(0), BidVariationLowReducePercent(0.25f), BuyoutBelowVendorVariationAddPercent(0.25f), - BuyingBotBuyCandidatesPerBuyCycle(1), + BuyingBotBuyCandidatesPerBuyCycleMin(1), + BuyingBotBuyCandidatesPerBuyCycleMax(1), ListingExpireTimeInSecondsMin(900), ListingExpireTimeInSecondsMax(86400), BuyingBotAcceptablePriceModifier(1), @@ -797,7 +800,7 @@ void AuctionHouseBot::PopulateItemCandidatesAndProportions() ListProportionNode curNode = ItemListProportionNodesSeed[i]; if (ItemCandidatesByItemClassAndQuality[curNode.ItemClassID][curNode.ItemQualityID].size() > 0) { - for (int j = 0; j < curNode.Proportion; j++) + for (uint32 j = 0; j < curNode.Proportion; j++) ItemListProportionNodesLookup.push_back(curNode); } } @@ -1001,15 +1004,16 @@ void AuctionHouseBot::AddNewAuctionBuyerBotBid(Player* AHBplayer, FactionSpecifi { uint32 tmpdata = result->Fetch()->Get(); possibleBids.push_back(tmpdata); - }while (result->NextRow()); + } while (result->NextRow()); - for (uint32 count = 1; count <= BuyingBotBuyCandidatesPerBuyCycle; ++count) + int randBuyingBotBuyCandidatesPerBuyCycle = urand(BuyingBotBuyCandidatesPerBuyCycleMin, BuyingBotBuyCandidatesPerBuyCycleMax); + for (int count = 1; count <= randBuyingBotBuyCandidatesPerBuyCycle; ++count) { // Do we have anything to bid? If not, stop here. if (possibleBids.empty()) { //if (debug_Out) sLog->outError( "AHBuyer: I have no newItemsToListCount to bid on."); - count = BuyingBotBuyCandidatesPerBuyCycle; + count = randBuyingBotBuyCandidatesPerBuyCycle; continue; } @@ -1176,6 +1180,7 @@ void AuctionHouseBot::Update() if (LastCycleCount < CyclesBetweenBuyOrSell) return; LastCycleCount = 0; + CyclesBetweenBuyOrSell = urand(CyclesBetweenBuyOrSellMin, CyclesBetweenBuyOrSellMax); // Randomly select the bot to load, and load it uint32 botIndex = urand(0, AHCharacters.size() - 1); @@ -1190,16 +1195,16 @@ void AuctionHouseBot::Update() if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) { AddNewAuctions(&_AHBplayer, &AllianceConfig); - if (BuyingBotBuyCandidatesPerBuyCycle > 0) + if (BuyingBotBuyCandidatesPerBuyCycleMin > 0) AddNewAuctionBuyerBotBid(&_AHBplayer, &AllianceConfig); AddNewAuctions(&_AHBplayer, &HordeConfig); - if (BuyingBotBuyCandidatesPerBuyCycle > 0) + if (BuyingBotBuyCandidatesPerBuyCycleMin > 0) AddNewAuctionBuyerBotBid(&_AHBplayer, &HordeConfig); } AddNewAuctions(&_AHBplayer, &NeutralConfig); - if (BuyingBotBuyCandidatesPerBuyCycle > 0) + if (BuyingBotBuyCandidatesPerBuyCycleMin > 0) AddNewAuctionBuyerBotBid(&_AHBplayer, &NeutralConfig); ObjectAccessor::RemoveObject(&_AHBplayer); @@ -1226,7 +1231,7 @@ void AuctionHouseBot::InitializeConfiguration() AddCharacters(charString); // Buyer & Seller core properties - CyclesBetweenBuyOrSell = sConfigMgr->GetOption("AuctionHouseBot.AuctionHouseManagerCyclesBetweenBuyOrSell", 1); + SetCyclesBetweenBuyOrSell(); ItemsPerCycle = sConfigMgr->GetOption("AuctionHouseBot.ItemsPerCycle", 75); MaxBuyoutPriceInCopper = sConfigMgr->GetOption("AuctionHouseBot.MaxBuyoutPriceInCopper", 1000000000); BuyoutVariationReducePercent = sConfigMgr->GetOption("AuctionHouseBot.BuyoutVariationReducePercent", 0.15f); @@ -1254,7 +1259,7 @@ void AuctionHouseBot::InitializeConfiguration() } // Buyer Bot - BuyingBotBuyCandidatesPerBuyCycle = sConfigMgr->GetOption("AuctionHouseBot.Buyer.BuyCandidatesPerBuyCycle", 1); + SetBuyingBotBuyCandidatesPerBuyCycle(); BuyingBotAcceptablePriceModifier = sConfigMgr->GetOption("AuctionHouseBot.Buyer.AcceptablePriceModifier", 1); BuyingBotAlwaysBidMaxCalculatedPrice = sConfigMgr->GetOption("AuctionHouseBot.Buyer.AlwaysBidMaxCalculatedPrice", false); PreventOverpayingForVendorItems = sConfigMgr->GetOption("AuctionHouseBot.Buyer.PreventOverpayingForVendorItems", true); @@ -1463,6 +1468,36 @@ uint32 AuctionHouseBot::GetRandomStackIncrementValue(std::string configKeyString return stackIncrementValue; } +void AuctionHouseBot::SetCyclesBetweenBuyOrSell() +{ + std::string cyclesConfigString = sConfigMgr->GetOption("AuctionHouseBot.AuctionHouseManagerCyclesBetweenBuyOrSell", "1"); + GetConfigMinAndMax(cyclesConfigString, CyclesBetweenBuyOrSellMin, CyclesBetweenBuyOrSellMax); + CyclesBetweenBuyOrSell = urand(CyclesBetweenBuyOrSellMin, CyclesBetweenBuyOrSellMax); +} + +void AuctionHouseBot::SetBuyingBotBuyCandidatesPerBuyCycle() +{ + std::string candidatesPerCycleString = sConfigMgr->GetOption("AuctionHouseBot.Buyer.BuyCandidatesPerBuyCycle", "1"); + GetConfigMinAndMax(candidatesPerCycleString, BuyingBotBuyCandidatesPerBuyCycleMin, BuyingBotBuyCandidatesPerBuyCycleMax); +} + +void AuctionHouseBot::GetConfigMinAndMax(std::string config, uint32& min, uint32& max) +{ + size_t pos = config.find(':'); + if (pos != std::string::npos) + { + min = std::stoul(config.substr(0, pos)); + max = std::stoul(config.substr(pos + 1)); + + if (min < 1) + min = 1; + if (max < min) + max = min; + } + else + min = max = std::stoul(config); +} + void AuctionHouseBot::AddCharacters(std::string characterGUIDString) { AHCharacters.clear(); diff --git a/src/AuctionHouseBot.h b/src/AuctionHouseBot.h index d187414..bb39ca0 100644 --- a/src/AuctionHouseBot.h +++ b/src/AuctionHouseBot.h @@ -128,14 +128,17 @@ private: bool SellingBotEnabled; bool BuyingBotEnabled; - int CyclesBetweenBuyOrSell; + uint32 CyclesBetweenBuyOrSellMin; + uint32 CyclesBetweenBuyOrSell; + uint32 CyclesBetweenBuyOrSellMax; uint32 MaxBuyoutPriceInCopper; float BuyoutVariationReducePercent; float BuyoutVariationAddPercent; float BidVariationHighReducePercent; float BidVariationLowReducePercent; float BuyoutBelowVendorVariationAddPercent; - uint32 BuyingBotBuyCandidatesPerBuyCycle; + uint32 BuyingBotBuyCandidatesPerBuyCycleMin; + uint32 BuyingBotBuyCandidatesPerBuyCycleMax; uint32 ListingExpireTimeInSecondsMin; uint32 ListingExpireTimeInSecondsMax; float BuyingBotAcceptablePriceModifier; @@ -271,7 +274,7 @@ private: FactionSpecificAuctionHouseConfig HordeConfig; FactionSpecificAuctionHouseConfig NeutralConfig; - int LastCycleCount; + uint32 LastCycleCount; int ActiveListMultipleItemID; int RemainingListMultipleCount; @@ -290,6 +293,9 @@ public: void InitializeConfiguration(); uint32 GetRandomStackValue(std::string configKeyString, uint32 defaultValue); uint32 GetRandomStackIncrementValue(std::string configKeyString, uint32 defaultValue); + void SetCyclesBetweenBuyOrSell(); + void SetBuyingBotBuyCandidatesPerBuyCycle(); + void GetConfigMinAndMax(std::string config, uint32& min, uint32& max); void AddCharacters(std::string characterGUIDString); void AddItemIDsFromString(std::set& workingItemIDSet, std::string itemString, const char* parentOperationName); void AddToItemIDSet(std::set& workingItemIDSet, uint32 itemID, const char* parentOperationName);