Merge pull request #25 from zeb139/feature-cycles-variance

Add Buy/Sell cycle timing variance + Add BuyCandidatesPerBuyCycle variance
This commit is contained in:
Nathan Handley
2025-09-27 09:46:37 -05:00
committed by GitHub
3 changed files with 70 additions and 22 deletions

View File

@@ -11,10 +11,14 @@
# Default: false (disabled) # Default: false (disabled)
# #
# AuctionHouseBot.AuctionHouseManagerCyclesBetweenBuyOrSell # AuctionHouseBot.AuctionHouseManagerCyclesBetweenBuyOrSell
# How many cycles to wait between executing any buying or selling logic # How many cycles to wait between executing any buying and selling logic.
# - At this time, the AzerothCore has it set as 1 minute inside the # At this time, AzerothCore waits 1 minute between cycles as defined by
# AuctionHouseMgr.cpp file # the AuctionHouseMgr.cpp file.
# Default 1 (once per AuctionHouseMgr.cpp update cycle) # 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 # AuctionHouseBot.EnableSeller
# Enable/Disable the part of AHBot that puts items up for auction # 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 # 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, # 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 # 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 # from each AH will be selected (total of 30). Whole numbers only.
# values can impact server performance, and is generally not neccessary. # Very large values can impact server performance, and is generally
# This runs every minute (which is the auction house update loop time, # not neccessary. This runs once every Buy/Sell cycle as defined
# defined by azerothcore core inside the AuctionHouseMgr.cpp file). # by AuctionHouseBot.AuctionHouseManagerCyclesBetweenBuyOrSell.
# Default: 1 (1 item per auction house is considered per minute) # 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 # AuctionHouseBot.Buyer.AcceptablePriceModifier
# The buyer bot calculates item prices the same way the selling # The buyer bot calculates item prices the same way the selling

View File

@@ -41,14 +41,17 @@ AuctionHouseBot::AuctionHouseBot() :
debug_Out_Filters(false), debug_Out_Filters(false),
SellingBotEnabled(false), SellingBotEnabled(false),
BuyingBotEnabled(false), BuyingBotEnabled(false),
CyclesBetweenBuyOrSellMin(1),
CyclesBetweenBuyOrSell(1), CyclesBetweenBuyOrSell(1),
CyclesBetweenBuyOrSellMax(1),
MaxBuyoutPriceInCopper(1000000000), MaxBuyoutPriceInCopper(1000000000),
BuyoutVariationReducePercent(0.15f), BuyoutVariationReducePercent(0.15f),
BuyoutVariationAddPercent(0.25f), BuyoutVariationAddPercent(0.25f),
BidVariationHighReducePercent(0), BidVariationHighReducePercent(0),
BidVariationLowReducePercent(0.25f), BidVariationLowReducePercent(0.25f),
BuyoutBelowVendorVariationAddPercent(0.25f), BuyoutBelowVendorVariationAddPercent(0.25f),
BuyingBotBuyCandidatesPerBuyCycle(1), BuyingBotBuyCandidatesPerBuyCycleMin(1),
BuyingBotBuyCandidatesPerBuyCycleMax(1),
ListingExpireTimeInSecondsMin(900), ListingExpireTimeInSecondsMin(900),
ListingExpireTimeInSecondsMax(86400), ListingExpireTimeInSecondsMax(86400),
BuyingBotAcceptablePriceModifier(1), BuyingBotAcceptablePriceModifier(1),
@@ -797,7 +800,7 @@ void AuctionHouseBot::PopulateItemCandidatesAndProportions()
ListProportionNode curNode = ItemListProportionNodesSeed[i]; ListProportionNode curNode = ItemListProportionNodesSeed[i];
if (ItemCandidatesByItemClassAndQuality[curNode.ItemClassID][curNode.ItemQualityID].size() > 0) 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); ItemListProportionNodesLookup.push_back(curNode);
} }
} }
@@ -1001,15 +1004,16 @@ void AuctionHouseBot::AddNewAuctionBuyerBotBid(Player* AHBplayer, FactionSpecifi
{ {
uint32 tmpdata = result->Fetch()->Get<uint32>(); uint32 tmpdata = result->Fetch()->Get<uint32>();
possibleBids.push_back(tmpdata); 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. // Do we have anything to bid? If not, stop here.
if (possibleBids.empty()) if (possibleBids.empty())
{ {
//if (debug_Out) sLog->outError( "AHBuyer: I have no newItemsToListCount to bid on."); //if (debug_Out) sLog->outError( "AHBuyer: I have no newItemsToListCount to bid on.");
count = BuyingBotBuyCandidatesPerBuyCycle; count = randBuyingBotBuyCandidatesPerBuyCycle;
continue; continue;
} }
@@ -1176,6 +1180,7 @@ void AuctionHouseBot::Update()
if (LastCycleCount < CyclesBetweenBuyOrSell) if (LastCycleCount < CyclesBetweenBuyOrSell)
return; return;
LastCycleCount = 0; LastCycleCount = 0;
CyclesBetweenBuyOrSell = urand(CyclesBetweenBuyOrSellMin, CyclesBetweenBuyOrSellMax);
// Randomly select the bot to load, and load it // Randomly select the bot to load, and load it
uint32 botIndex = urand(0, AHCharacters.size() - 1); uint32 botIndex = urand(0, AHCharacters.size() - 1);
@@ -1190,16 +1195,16 @@ void AuctionHouseBot::Update()
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION))
{ {
AddNewAuctions(&_AHBplayer, &AllianceConfig); AddNewAuctions(&_AHBplayer, &AllianceConfig);
if (BuyingBotBuyCandidatesPerBuyCycle > 0) if (BuyingBotBuyCandidatesPerBuyCycleMin > 0)
AddNewAuctionBuyerBotBid(&_AHBplayer, &AllianceConfig); AddNewAuctionBuyerBotBid(&_AHBplayer, &AllianceConfig);
AddNewAuctions(&_AHBplayer, &HordeConfig); AddNewAuctions(&_AHBplayer, &HordeConfig);
if (BuyingBotBuyCandidatesPerBuyCycle > 0) if (BuyingBotBuyCandidatesPerBuyCycleMin > 0)
AddNewAuctionBuyerBotBid(&_AHBplayer, &HordeConfig); AddNewAuctionBuyerBotBid(&_AHBplayer, &HordeConfig);
} }
AddNewAuctions(&_AHBplayer, &NeutralConfig); AddNewAuctions(&_AHBplayer, &NeutralConfig);
if (BuyingBotBuyCandidatesPerBuyCycle > 0) if (BuyingBotBuyCandidatesPerBuyCycleMin > 0)
AddNewAuctionBuyerBotBid(&_AHBplayer, &NeutralConfig); AddNewAuctionBuyerBotBid(&_AHBplayer, &NeutralConfig);
ObjectAccessor::RemoveObject(&_AHBplayer); ObjectAccessor::RemoveObject(&_AHBplayer);
@@ -1226,7 +1231,7 @@ void AuctionHouseBot::InitializeConfiguration()
AddCharacters(charString); AddCharacters(charString);
// Buyer & Seller core properties // Buyer & Seller core properties
CyclesBetweenBuyOrSell = sConfigMgr->GetOption<uint32>("AuctionHouseBot.AuctionHouseManagerCyclesBetweenBuyOrSell", 1); SetCyclesBetweenBuyOrSell();
ItemsPerCycle = sConfigMgr->GetOption<uint32>("AuctionHouseBot.ItemsPerCycle", 75); ItemsPerCycle = sConfigMgr->GetOption<uint32>("AuctionHouseBot.ItemsPerCycle", 75);
MaxBuyoutPriceInCopper = sConfigMgr->GetOption<uint32>("AuctionHouseBot.MaxBuyoutPriceInCopper", 1000000000); MaxBuyoutPriceInCopper = sConfigMgr->GetOption<uint32>("AuctionHouseBot.MaxBuyoutPriceInCopper", 1000000000);
BuyoutVariationReducePercent = sConfigMgr->GetOption<float>("AuctionHouseBot.BuyoutVariationReducePercent", 0.15f); BuyoutVariationReducePercent = sConfigMgr->GetOption<float>("AuctionHouseBot.BuyoutVariationReducePercent", 0.15f);
@@ -1254,7 +1259,7 @@ void AuctionHouseBot::InitializeConfiguration()
} }
// Buyer Bot // Buyer Bot
BuyingBotBuyCandidatesPerBuyCycle = sConfigMgr->GetOption<uint32>("AuctionHouseBot.Buyer.BuyCandidatesPerBuyCycle", 1); SetBuyingBotBuyCandidatesPerBuyCycle();
BuyingBotAcceptablePriceModifier = sConfigMgr->GetOption<float>("AuctionHouseBot.Buyer.AcceptablePriceModifier", 1); BuyingBotAcceptablePriceModifier = sConfigMgr->GetOption<float>("AuctionHouseBot.Buyer.AcceptablePriceModifier", 1);
BuyingBotAlwaysBidMaxCalculatedPrice = sConfigMgr->GetOption<bool>("AuctionHouseBot.Buyer.AlwaysBidMaxCalculatedPrice", false); BuyingBotAlwaysBidMaxCalculatedPrice = sConfigMgr->GetOption<bool>("AuctionHouseBot.Buyer.AlwaysBidMaxCalculatedPrice", false);
PreventOverpayingForVendorItems = sConfigMgr->GetOption<bool>("AuctionHouseBot.Buyer.PreventOverpayingForVendorItems", true); PreventOverpayingForVendorItems = sConfigMgr->GetOption<bool>("AuctionHouseBot.Buyer.PreventOverpayingForVendorItems", true);
@@ -1463,6 +1468,36 @@ uint32 AuctionHouseBot::GetRandomStackIncrementValue(std::string configKeyString
return stackIncrementValue; return stackIncrementValue;
} }
void AuctionHouseBot::SetCyclesBetweenBuyOrSell()
{
std::string cyclesConfigString = sConfigMgr->GetOption<std::string>("AuctionHouseBot.AuctionHouseManagerCyclesBetweenBuyOrSell", "1");
GetConfigMinAndMax(cyclesConfigString, CyclesBetweenBuyOrSellMin, CyclesBetweenBuyOrSellMax);
CyclesBetweenBuyOrSell = urand(CyclesBetweenBuyOrSellMin, CyclesBetweenBuyOrSellMax);
}
void AuctionHouseBot::SetBuyingBotBuyCandidatesPerBuyCycle()
{
std::string candidatesPerCycleString = sConfigMgr->GetOption<string>("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) void AuctionHouseBot::AddCharacters(std::string characterGUIDString)
{ {
AHCharacters.clear(); AHCharacters.clear();

View File

@@ -128,14 +128,17 @@ private:
bool SellingBotEnabled; bool SellingBotEnabled;
bool BuyingBotEnabled; bool BuyingBotEnabled;
int CyclesBetweenBuyOrSell; uint32 CyclesBetweenBuyOrSellMin;
uint32 CyclesBetweenBuyOrSell;
uint32 CyclesBetweenBuyOrSellMax;
uint32 MaxBuyoutPriceInCopper; uint32 MaxBuyoutPriceInCopper;
float BuyoutVariationReducePercent; float BuyoutVariationReducePercent;
float BuyoutVariationAddPercent; float BuyoutVariationAddPercent;
float BidVariationHighReducePercent; float BidVariationHighReducePercent;
float BidVariationLowReducePercent; float BidVariationLowReducePercent;
float BuyoutBelowVendorVariationAddPercent; float BuyoutBelowVendorVariationAddPercent;
uint32 BuyingBotBuyCandidatesPerBuyCycle; uint32 BuyingBotBuyCandidatesPerBuyCycleMin;
uint32 BuyingBotBuyCandidatesPerBuyCycleMax;
uint32 ListingExpireTimeInSecondsMin; uint32 ListingExpireTimeInSecondsMin;
uint32 ListingExpireTimeInSecondsMax; uint32 ListingExpireTimeInSecondsMax;
float BuyingBotAcceptablePriceModifier; float BuyingBotAcceptablePriceModifier;
@@ -271,7 +274,7 @@ private:
FactionSpecificAuctionHouseConfig HordeConfig; FactionSpecificAuctionHouseConfig HordeConfig;
FactionSpecificAuctionHouseConfig NeutralConfig; FactionSpecificAuctionHouseConfig NeutralConfig;
int LastCycleCount; uint32 LastCycleCount;
int ActiveListMultipleItemID; int ActiveListMultipleItemID;
int RemainingListMultipleCount; int RemainingListMultipleCount;
@@ -290,6 +293,9 @@ public:
void InitializeConfiguration(); void InitializeConfiguration();
uint32 GetRandomStackValue(std::string configKeyString, uint32 defaultValue); uint32 GetRandomStackValue(std::string configKeyString, uint32 defaultValue);
uint32 GetRandomStackIncrementValue(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 AddCharacters(std::string characterGUIDString);
void AddItemIDsFromString(std::set<uint32>& workingItemIDSet, std::string itemString, const char* parentOperationName); void AddItemIDsFromString(std::set<uint32>& workingItemIDSet, std::string itemString, const char* parentOperationName);
void AddToItemIDSet(std::set<uint32>& workingItemIDSet, uint32 itemID, const char* parentOperationName); void AddToItemIDSet(std::set<uint32>& workingItemIDSet, uint32 itemID, const char* parentOperationName);