From 2bc97d5a46b355aa14afe58d734f9e341c507546 Mon Sep 17 00:00:00 2001 From: NathanHandley Date: Sun, 9 Mar 2025 20:06:35 -0500 Subject: [PATCH] Fix crash by restricting to 1 bot per cycle --- conf/mod_ahbot.conf.dist | 13 ++--- src/AuctionHouseBot.cpp | 96 ++++++++++------------------------- src/AuctionHouseBot.h | 8 ++- src/AuctionHouseBotScript.cpp | 4 +- 4 files changed, 36 insertions(+), 85 deletions(-) diff --git a/conf/mod_ahbot.conf.dist b/conf/mod_ahbot.conf.dist index d7cc287..8abd320 100644 --- a/conf/mod_ahbot.conf.dist +++ b/conf/mod_ahbot.conf.dist @@ -27,14 +27,10 @@ # AuctionHouseBot.GUIDs = 3 <- Only character with GUID 3 # AuctionHouseBot.GUIDs = 3,4 <- Both characters with GUID 3 and 4 # -# AuctionHouseBot.BotsPerCycle -# If using more than one GUID, this is how many of them will come on -# to do auction behaviors each cycle. Too many might impact performance -# since the bot sessions are created and destroyed. -# Default 1 (single random bot from GUID list) -# # AuctionHouseBot.ItemsPerCycle -# How many items to post on the auction house every house update +# How many items to post on the auction house every house update. Items +# in a cycle will be posted by a single randomly selected bot, so Keep +# this value low if you want highly diverse postings # Default 75 ############################################################################### @@ -42,8 +38,7 @@ AuctionHouseBot.DEBUG = 0 AuctionHouseBot.DEBUG_FILTERS = 0 AuctionHouseBot.EnableSeller = 1 AuctionHouseBot.EnableBuyer = 1 -AuctionHouseBot.GUIDs = 3 -AuctionHouseBot.BotsPerCycle = 1 +AuctionHouseBot.GUIDs = 0 AuctionHouseBot.ItemsPerCycle = 75 ############################################################################### diff --git a/src/AuctionHouseBot.cpp b/src/AuctionHouseBot.cpp index 3a4a6a8..1e24b3b 100644 --- a/src/AuctionHouseBot.cpp +++ b/src/AuctionHouseBot.cpp @@ -419,7 +419,7 @@ void AuctionHouseBot::populateItemCandidateList() } } -void AuctionHouseBot::addNewAuctions(std::vector& playerSessions, AHBConfig *config) +void AuctionHouseBot::addNewAuctions(Player* AHBplayer, AHBConfig *config) { if (!AHBSeller) { @@ -432,10 +432,7 @@ void AuctionHouseBot::addNewAuctions(std::vector& playerSessions, AHBCo uint32 maxItems = config->GetMaxItems(); if (maxItems == 0) - { - //if (debug_Out) sLog->outString( "AHSeller: Auctions disabled"); return; - } AuctionHouseEntry const* ahEntry = sAuctionMgr->GetAuctionHouseEntryFromFactionTemplate(config->GetAHFID()); if (!ahEntry) @@ -483,9 +480,6 @@ void AuctionHouseBot::addNewAuctions(std::vector& playerSessions, AHBCo // only insert a few at a time, so as not to peg the processor for (uint32 cnt = 1; cnt <= items; cnt++) { - // Pick a random player session - Player* playerSession = playerSessions[urand(0, playerSessions.size() - 1)]; - if (debug_Out) LOG_ERROR("module", "AHSeller: {} count", cnt); @@ -511,14 +505,14 @@ void AuctionHouseBot::addNewAuctions(std::vector& playerSessions, AHBCo continue; } - Item* item = Item::CreateItem(itemID, 1, playerSession); + Item* item = Item::CreateItem(itemID, 1, AHBplayer); if (item == NULL) { if (debug_Out) LOG_ERROR("module", "AHSeller: Item::CreateItem() returned NULL"); break; } - item->AddToUpdateQueueOf(playerSession); + item->AddToUpdateQueueOf(AHBplayer); uint32 randomPropertyId = Item::GenerateItemRandomPropertyId(itemID); if (randomPropertyId != 0) @@ -545,7 +539,7 @@ void AuctionHouseBot::addNewAuctions(std::vector& playerSessions, AHBCo auctionEntry->item_guid = item->GetGUID(); auctionEntry->item_template = item->GetEntry(); auctionEntry->itemCount = item->GetCount(); - auctionEntry->owner = playerSession->GetGUID(); + auctionEntry->owner = AHBplayer->GetGUID(); auctionEntry->startbid = bidPrice * stackCount; auctionEntry->buyout = buyoutPrice * stackCount; auctionEntry->bid = 0; @@ -553,7 +547,7 @@ void AuctionHouseBot::addNewAuctions(std::vector& playerSessions, AHBCo auctionEntry->expire_time = (time_t) etime + time(NULL); auctionEntry->auctionHouseEntry = ahEntry; item->SaveToDB(trans); - item->RemoveFromUpdateQueueOf(playerSession); + item->RemoveFromUpdateQueueOf(AHBplayer); sAuctionMgr->AddAItem(item); auctionHouse->AddAuction(auctionEntry); auctionEntry->SaveToDB(trans); @@ -561,7 +555,7 @@ void AuctionHouseBot::addNewAuctions(std::vector& playerSessions, AHBCo } } -void AuctionHouseBot::addNewAuctionBuyerBotBid(std::vector& playerSessions, AHBConfig *config) +void AuctionHouseBot::addNewAuctionBuyerBotBid(Player* AHBplayer, AHBConfig *config) { if (!AHBBuyer) { @@ -590,9 +584,6 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(std::vector& playerSessi for (uint32 count = 1; count <= config->GetBidsPerInterval(); ++count) { - // Pick a random player session - Player* playerSession = playerSessions[urand(0, playerSessions.size() - 1)]; - // Do we have anything to bid? If not, stop here. if (possibleBids.empty()) { @@ -689,7 +680,7 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(std::vector& playerSessi // Return money of prior bidder if (auction->bidder) { - if (auction->bidder == playerSession->GetGUID()) + if (auction->bidder == AHBplayer->GetGUID()) { //pl->ModifyMoney(-int32(price - auction->bid)); } @@ -697,13 +688,13 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(std::vector& playerSessi { // mail to last bidder and return money auto trans = CharacterDatabase.BeginTransaction(); - sAuctionMgr->SendAuctionOutbiddedMail(auction, minBidPrice, playerSession, trans); + sAuctionMgr->SendAuctionOutbiddedMail(auction, minBidPrice, AHBplayer, trans); CharacterDatabase.CommitTransaction(trans); //pl->ModifyMoney(-int32(price)); } } - auction->bidder = playerSession->GetGUID(); + auction->bidder = AHBplayer->GetGUID(); auction->bid = minBidPrice; // Saving auction into database @@ -713,15 +704,14 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(std::vector& playerSessi { auto trans = CharacterDatabase.BeginTransaction(); //buyout - if ((auction->bidder) && (playerSession->GetGUID() != auction->bidder)) + if ((auction->bidder) && (AHBplayer->GetGUID() != auction->bidder)) { - sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, playerSession, trans); + sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, AHBplayer, trans); } - auction->bidder = playerSession->GetGUID(); + auction->bidder = AHBplayer->GetGUID(); auction->bid = auction->buyout; // Send mails to buyer & seller - //sAuctionMgr->SendAuctionSalePendingMail(auction, trans); sAuctionMgr->SendAuctionSuccessfulMail(auction, trans); sAuctionMgr->SendAuctionWonMail(auction, trans); auction->DeleteFromDB(trans); @@ -734,33 +724,6 @@ void AuctionHouseBot::addNewAuctionBuyerBotBid(std::vector& playerSessi } } -void AuctionHouseBot::LoadBotSessions(std::vector& outPlayerSessions) -{ - // Determine number to load - uint32 numOfBotsToLoad = BotsPerCycle; - if (AHCharacters.size() < BotsPerCycle) - numOfBotsToLoad = AHCharacters.size(); - - // Build a shufflebag for char indices to pick from - std::deque charIndicesBag; - for (AuctionHouseBotCharacter ahBot : AHCharacters) - charIndicesBag.push_back(ahBot.CharacterGUID); - - // Pluck out the guids and load them one at a time - for (uint32 i = 0; i < numOfBotsToLoad; i++) - { - uint32 index = urand(0, charIndicesBag.size()-1); - uint32 charIndex = charIndicesBag[index]; - charIndicesBag.erase(charIndicesBag.begin() + index); - std::string accountName = "AuctionHouseBotGUID" + std::to_string(AHCharacters[charIndex].CharacterGUID); - WorldSession _session(AHCharacters[charIndex].AccountID, std::move(accountName), nullptr, SEC_PLAYER, sWorld->getIntConfig(CONFIG_EXPANSION), 0, LOCALE_enUS, 0, false, false, 0); - Player playerSession(&_session); - playerSession.Initialize(AHCharacters[charIndex].CharacterGUID); - ObjectAccessor::AddObject(&playerSession); - outPlayerSessions.push_back(&playerSession); - } -} - void AuctionHouseBot::Update() { time_t _newrun = time(NULL); @@ -769,45 +732,41 @@ void AuctionHouseBot::Update() if (AHCharacters.size() == 0) return; - // Load the bots - std::vector playerSessions; - LoadBotSessions(playerSessions); + // Randomly select the bot to load, and load it + uint32 botIndex = urand(0, AHCharacters.size() - 1); + CurrentBotCharGUID = AHCharacters[botIndex].CharacterGUID; + std::string accountName = "AuctionHouseBot" + std::to_string(AHCharacters[botIndex].AccountID); + WorldSession _session(AHCharacters[botIndex].AccountID, std::move(accountName), nullptr, SEC_PLAYER, sWorld->getIntConfig(CONFIG_EXPANSION), 0, LOCALE_enUS, 0, false, false, 0); + Player _AHBplayer(&_session); + _AHBplayer.Initialize(AHCharacters[botIndex].CharacterGUID); + ObjectAccessor::AddObject(&_AHBplayer); // Add New Bids if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) { - addNewAuctions(playerSessions, &AllianceConfig); + addNewAuctions(&_AHBplayer, &AllianceConfig); if (((_newrun - _lastrun_a) >= (AllianceConfig.GetBiddingInterval() * MINUTE)) && (AllianceConfig.GetBidsPerInterval() > 0)) { - //if (debug_Out) sLog->outError( "AHBuyer: %u seconds have passed since last bid", (_newrun - _lastrun_a)); - //if (debug_Out) sLog->outError( "AHBuyer: Bidding on Alliance Auctions"); - addNewAuctionBuyerBotBid(playerSessions, &AllianceConfig); + addNewAuctionBuyerBotBid(&_AHBplayer, &AllianceConfig); _lastrun_a = _newrun; } - addNewAuctions(playerSessions, &HordeConfig); + addNewAuctions(&_AHBplayer, &HordeConfig); if (((_newrun - _lastrun_h) >= (HordeConfig.GetBiddingInterval() * MINUTE)) && (HordeConfig.GetBidsPerInterval() > 0)) { - //if (debug_Out) sLog->outError( "AHBuyer: %u seconds have passed since last bid", (_newrun - _lastrun_h)); - //if (debug_Out) sLog->outError( "AHBuyer: Bidding on Horde Auctions"); - addNewAuctionBuyerBotBid(playerSessions, &HordeConfig); + addNewAuctionBuyerBotBid(&_AHBplayer, &HordeConfig); _lastrun_h = _newrun; } } - addNewAuctions(playerSessions, &NeutralConfig); + addNewAuctions(&_AHBplayer, &NeutralConfig); if (((_newrun - _lastrun_n) >= (NeutralConfig.GetBiddingInterval() * MINUTE)) && (NeutralConfig.GetBidsPerInterval() > 0)) { - //if (debug_Out) sLog->outError( "AHBuyer: %u seconds have passed since last bid", (_newrun - _lastrun_n)); - //if (debug_Out) sLog->outError( "AHBuyer: Bidding on Neutral Auctions"); - addNewAuctionBuyerBotBid(playerSessions, &NeutralConfig); + addNewAuctionBuyerBotBid(&_AHBplayer, &NeutralConfig); _lastrun_n = _newrun; } - // Remove the player sessions - for (int i = 0; i < playerSessions.size(); i++) - ObjectAccessor::RemoveObject(playerSessions[i]); - playerSessions.clear(); + ObjectAccessor::RemoveObject(&_AHBplayer); } void AuctionHouseBot::Initialize() @@ -829,7 +788,6 @@ void AuctionHouseBot::InitializeConfiguration() if (AHCharacters.size() == 0) AddCharacters(sConfigMgr->GetOption("AuctionHouseBot.GUID", "0")); // Backwards compat ItemsPerCycle = sConfigMgr->GetOption("AuctionHouseBot.ItemsPerCycle", 75); - BotsPerCycle = sConfigMgr->GetOption("AuctionHouseBot.BotsPerCycle", 1); // Stack Ratios RandomStackRatioConsumable = GetRandomStackValue("AuctionHouseBot.RandomStackRatio.Consumable", 20); diff --git a/src/AuctionHouseBot.h b/src/AuctionHouseBot.h index f41a294..a012a19 100644 --- a/src/AuctionHouseBot.h +++ b/src/AuctionHouseBot.h @@ -135,6 +135,7 @@ class AuctionHouseBot { public: std::vector AHCharacters; + uint32 CurrentBotCharGUID; private: bool debug_Out; @@ -145,7 +146,6 @@ private: std::string AHCharactersGUIDsForQuery; uint32 ItemsPerCycle; - uint32 BotsPerCycle; bool DisabledItemTextFilter; std::set DisabledItems; uint32 RandomStackRatioConsumable; @@ -234,8 +234,8 @@ private: void populatetemClassSeedListForItemClass(uint32 itemClass, uint32 itemClassSeedWeight); void populateItemClassProportionList(); void populateItemCandidateList(); - void addNewAuctions(std::vector& playerSessions, AHBConfig *config); - void addNewAuctionBuyerBotBid(std::vector& playerSessions, AHBConfig *config); + void addNewAuctions(Player* AHBplayer, AHBConfig *config); + void addNewAuctionBuyerBotBid(Player* AHBplayer, AHBConfig *config); AuctionHouseBot(); @@ -256,8 +256,6 @@ public: void AddToDisabledItems(std::set& workingDisabledItemIDs, uint32 disabledItemID); void AddDisabledItems(std::string disabledItemIdString); void AddPriceMinimumOverrides(std::string priceMinimimOverridesString); - //ObjectGuid::LowType GetAHBplayerGUID() { return AHBplayerGUID; }; - void LoadBotSessions(std::vector& outPlayerSessions); }; #define auctionbot AuctionHouseBot::instance() diff --git a/src/AuctionHouseBotScript.cpp b/src/AuctionHouseBotScript.cpp index ee10beb..925cb1a 100644 --- a/src/AuctionHouseBotScript.cpp +++ b/src/AuctionHouseBotScript.cpp @@ -74,8 +74,8 @@ public: void OnBeforeAuctionHouseMgrSendAuctionOutbiddedMail(AuctionHouseMgr* /*auctionHouseMgr*/, AuctionEntry* auction, Player* oldBidder, uint32& /*oldBidder_accId*/, Player* newBidder, uint32& newPrice, bool& /*sendNotification*/, bool& /*sendMail*/) override { - //if (oldBidder && !newBidder) - // oldBidder->GetSession()->SendAuctionBidderNotification((uint32)auction->GetHouseId(), auction->Id, ObjectGuid::Create(auctionbot->GetAHBplayerGUID()), newPrice, auction->GetAuctionOutBid(), auction->item_template); + if (oldBidder && !newBidder) + oldBidder->GetSession()->SendAuctionBidderNotification((uint32)auction->GetHouseId(), auction->Id, ObjectGuid::Create(auctionbot->CurrentBotCharGUID), newPrice, auction->GetAuctionOutBid(), auction->item_template); } void OnBeforeAuctionHouseMgrUpdate() override