From 1166c7c5273eabb258006a41ebffe08aee4c2bff Mon Sep 17 00:00:00 2001 From: zeb <37308742+zeb139@users.noreply.github.com> Date: Fri, 26 Sep 2025 21:50:19 -0400 Subject: [PATCH 1/3] added CyclesBetweenBuyOrSell variance --- conf/mod_ahbot.conf.dist | 11 +++++++---- src/AuctionHouseBot.cpp | 27 ++++++++++++++++++++++++--- src/AuctionHouseBot.h | 4 +++- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/conf/mod_ahbot.conf.dist b/conf/mod_ahbot.conf.dist index 65598e1..58b2db7 100644 --- a/conf/mod_ahbot.conf.dist +++ b/conf/mod_ahbot.conf.dist @@ -11,10 +11,13 @@ # 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 ) +# Default: 1 # # AuctionHouseBot.EnableSeller # Enable/Disable the part of AHBot that puts items up for auction diff --git a/src/AuctionHouseBot.cpp b/src/AuctionHouseBot.cpp index 67936ef..47743ee 100644 --- a/src/AuctionHouseBot.cpp +++ b/src/AuctionHouseBot.cpp @@ -41,7 +41,8 @@ AuctionHouseBot::AuctionHouseBot() : debug_Out_Filters(false), SellingBotEnabled(false), BuyingBotEnabled(false), - CyclesBetweenBuyOrSell(1), + CyclesBetweenBuyOrSellMin(1), + CyclesBetweenBuyOrSellMax(1), MaxBuyoutPriceInCopper(1000000000), BuyoutVariationReducePercent(0.15f), BuyoutVariationAddPercent(0.25f), @@ -1173,7 +1174,7 @@ void AuctionHouseBot::Update() // Only update if the update cycle has been hit LastCycleCount++; - if (LastCycleCount < CyclesBetweenBuyOrSell) + if (LastCycleCount < urand(CyclesBetweenBuyOrSellMin, CyclesBetweenBuyOrSellMax)) return; LastCycleCount = 0; @@ -1226,7 +1227,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); @@ -1463,6 +1464,26 @@ uint32 AuctionHouseBot::GetRandomStackIncrementValue(std::string configKeyString return stackIncrementValue; } +void AuctionHouseBot::SetCyclesBetweenBuyOrSell() +{ + std::string cyclesConfigString = sConfigMgr->GetOption("AuctionHouseBot.AuctionHouseManagerCyclesBetweenBuyOrSell", "1"); + size_t pos = cyclesConfigString.find(':'); + if (pos != std::string::npos) + { + CyclesBetweenBuyOrSellMin = std::stoi(cyclesConfigString.substr(0, pos)); + CyclesBetweenBuyOrSellMax = std::stoi(cyclesConfigString.substr(pos + 1)); + + if (CyclesBetweenBuyOrSellMin < 1) + CyclesBetweenBuyOrSellMin = 1; + if (CyclesBetweenBuyOrSellMax < CyclesBetweenBuyOrSellMin) + CyclesBetweenBuyOrSellMax = CyclesBetweenBuyOrSellMin; + } + else + { + CyclesBetweenBuyOrSellMin = CyclesBetweenBuyOrSellMax = std::stoi(cyclesConfigString); + } +} + void AuctionHouseBot::AddCharacters(std::string characterGUIDString) { AHCharacters.clear(); diff --git a/src/AuctionHouseBot.h b/src/AuctionHouseBot.h index d187414..4c7efec 100644 --- a/src/AuctionHouseBot.h +++ b/src/AuctionHouseBot.h @@ -128,7 +128,8 @@ private: bool SellingBotEnabled; bool BuyingBotEnabled; - int CyclesBetweenBuyOrSell; + int CyclesBetweenBuyOrSellMin; + int CyclesBetweenBuyOrSellMax; uint32 MaxBuyoutPriceInCopper; float BuyoutVariationReducePercent; float BuyoutVariationAddPercent; @@ -290,6 +291,7 @@ public: void InitializeConfiguration(); uint32 GetRandomStackValue(std::string configKeyString, uint32 defaultValue); uint32 GetRandomStackIncrementValue(std::string configKeyString, uint32 defaultValue); + void SetCyclesBetweenBuyOrSell(); 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); From e0a465811de32b07e95cea51cbc03bd39f8e93a0 Mon Sep 17 00:00:00 2001 From: zeb <37308742+zeb139@users.noreply.github.com> Date: Fri, 26 Sep 2025 22:54:54 -0400 Subject: [PATCH 2/3] added BuyCandidatesPerBuyCycle variance --- conf/mod_ahbot.conf.dist | 16 ++++++++----- src/AuctionHouseBot.cpp | 49 ++++++++++++++++++++++++---------------- src/AuctionHouseBot.h | 11 +++++---- 3 files changed, 47 insertions(+), 29 deletions(-) diff --git a/conf/mod_ahbot.conf.dist b/conf/mod_ahbot.conf.dist index 58b2db7..027eb6c 100644 --- a/conf/mod_ahbot.conf.dist +++ b/conf/mod_ahbot.conf.dist @@ -16,7 +16,8 @@ # 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 ) +# 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 @@ -142,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 47743ee..9bfb64f 100644 --- a/src/AuctionHouseBot.cpp +++ b/src/AuctionHouseBot.cpp @@ -49,7 +49,8 @@ AuctionHouseBot::AuctionHouseBot() : BidVariationHighReducePercent(0), BidVariationLowReducePercent(0.25f), BuyoutBelowVendorVariationAddPercent(0.25f), - BuyingBotBuyCandidatesPerBuyCycle(1), + BuyingBotBuyCandidatesPerBuyCycleMin(1), + BuyingBotBuyCandidatesPerBuyCycleMax(1), ListingExpireTimeInSecondsMin(900), ListingExpireTimeInSecondsMax(86400), BuyingBotAcceptablePriceModifier(1), @@ -798,7 +799,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); } } @@ -1002,15 +1003,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; } @@ -1191,16 +1193,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); @@ -1255,7 +1257,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); @@ -1467,21 +1469,30 @@ uint32 AuctionHouseBot::GetRandomStackIncrementValue(std::string configKeyString void AuctionHouseBot::SetCyclesBetweenBuyOrSell() { std::string cyclesConfigString = sConfigMgr->GetOption("AuctionHouseBot.AuctionHouseManagerCyclesBetweenBuyOrSell", "1"); - size_t pos = cyclesConfigString.find(':'); + GetConfigMinAndMax(cyclesConfigString, 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) { - CyclesBetweenBuyOrSellMin = std::stoi(cyclesConfigString.substr(0, pos)); - CyclesBetweenBuyOrSellMax = std::stoi(cyclesConfigString.substr(pos + 1)); + min = std::stoul(config.substr(0, pos)); + max = std::stoul(config.substr(pos + 1)); - if (CyclesBetweenBuyOrSellMin < 1) - CyclesBetweenBuyOrSellMin = 1; - if (CyclesBetweenBuyOrSellMax < CyclesBetweenBuyOrSellMin) - CyclesBetweenBuyOrSellMax = CyclesBetweenBuyOrSellMin; + if (min < 1) + min = 1; + if (max < min) + max = min; } else - { - CyclesBetweenBuyOrSellMin = CyclesBetweenBuyOrSellMax = std::stoi(cyclesConfigString); - } + min = max = std::stoul(config); } void AuctionHouseBot::AddCharacters(std::string characterGUIDString) diff --git a/src/AuctionHouseBot.h b/src/AuctionHouseBot.h index 4c7efec..ff98a33 100644 --- a/src/AuctionHouseBot.h +++ b/src/AuctionHouseBot.h @@ -128,15 +128,16 @@ private: bool SellingBotEnabled; bool BuyingBotEnabled; - int CyclesBetweenBuyOrSellMin; - int CyclesBetweenBuyOrSellMax; + uint32 CyclesBetweenBuyOrSellMin; + 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; @@ -272,7 +273,7 @@ private: FactionSpecificAuctionHouseConfig HordeConfig; FactionSpecificAuctionHouseConfig NeutralConfig; - int LastCycleCount; + uint32 LastCycleCount; int ActiveListMultipleItemID; int RemainingListMultipleCount; @@ -292,6 +293,8 @@ public: 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); From cb2c196c8be624d5dc7b93fd89c2ab86acd4410e Mon Sep 17 00:00:00 2001 From: zeb <37308742+zeb139@users.noreply.github.com> Date: Fri, 26 Sep 2025 23:04:20 -0400 Subject: [PATCH 3/3] calculate new CyclesBetweenBuyOrSell only if update cycle is hit --- src/AuctionHouseBot.cpp | 5 ++++- src/AuctionHouseBot.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/AuctionHouseBot.cpp b/src/AuctionHouseBot.cpp index 9bfb64f..3028645 100644 --- a/src/AuctionHouseBot.cpp +++ b/src/AuctionHouseBot.cpp @@ -42,6 +42,7 @@ AuctionHouseBot::AuctionHouseBot() : SellingBotEnabled(false), BuyingBotEnabled(false), CyclesBetweenBuyOrSellMin(1), + CyclesBetweenBuyOrSell(1), CyclesBetweenBuyOrSellMax(1), MaxBuyoutPriceInCopper(1000000000), BuyoutVariationReducePercent(0.15f), @@ -1176,9 +1177,10 @@ void AuctionHouseBot::Update() // Only update if the update cycle has been hit LastCycleCount++; - if (LastCycleCount < urand(CyclesBetweenBuyOrSellMin, CyclesBetweenBuyOrSellMax)) + 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); @@ -1470,6 +1472,7 @@ void AuctionHouseBot::SetCyclesBetweenBuyOrSell() { std::string cyclesConfigString = sConfigMgr->GetOption("AuctionHouseBot.AuctionHouseManagerCyclesBetweenBuyOrSell", "1"); GetConfigMinAndMax(cyclesConfigString, CyclesBetweenBuyOrSellMin, CyclesBetweenBuyOrSellMax); + CyclesBetweenBuyOrSell = urand(CyclesBetweenBuyOrSellMin, CyclesBetweenBuyOrSellMax); } void AuctionHouseBot::SetBuyingBotBuyCandidatesPerBuyCycle() diff --git a/src/AuctionHouseBot.h b/src/AuctionHouseBot.h index ff98a33..bb39ca0 100644 --- a/src/AuctionHouseBot.h +++ b/src/AuctionHouseBot.h @@ -129,6 +129,7 @@ private: bool SellingBotEnabled; bool BuyingBotEnabled; uint32 CyclesBetweenBuyOrSellMin; + uint32 CyclesBetweenBuyOrSell; uint32 CyclesBetweenBuyOrSellMax; uint32 MaxBuyoutPriceInCopper; float BuyoutVariationReducePercent;