Exposed additional config, added .conf.dist readme

This commit is contained in:
zeb
2025-10-08 11:54:59 -04:00
parent d7b742f47e
commit a9973cf8cb
4 changed files with 110 additions and 29 deletions

View File

@@ -46,11 +46,6 @@
# acore_characters.item_instance database table to grow over time.
# Default: false (disabled)
#
# AuctionHouseBot.Seller.UseDBDropRates.Enabled
# Enable/Disable the Seller using items' in-game drop rates from enemies
# and gameobjects to determine probability of listing the items on the AH.
# Default: false (disabled)
#
# AuctionHouseBot.GUIDs
# These are the character GUIDS (from characters->characters table) that
# will be used to create auctions and otherwise interact with auctions.
@@ -81,12 +76,42 @@ AuctionHouseBot.MinutesBetweenBuyCycle = 1
AuctionHouseBot.MinutesBetweenSellCycle = 1
AuctionHouseBot.EnableSeller = false
AuctionHouseBot.ReturnExpiredAuctionItemsToBot = false
AuctionHouseBot.Seller.UseDBDropRates.Enabled = false
AuctionHouseBot.GUIDs = 0
AuctionHouseBot.ItemsPerCycle = 150
AuctionHouseBot.ListingExpireTimeInSecondsMin = 900
AuctionHouseBot.ListingExpireTimeInSecondsMax = 86400
###############################################################################
# AuctionHouseBot.AdvancedListingRules.UseDropRates.Enabled
# Enable/Disable the Seller using items' in-game drop rates from Enemies
# and GameObjects to determine the probability of listing them on the AH.
# Attempts to simulate "live" AHs by making very powerful items appear less often.
# This setting respects ListProportion config. It can also result in more duplicate
# items appearing on the AH due to higher-drop-rate items being selected more often.
# Crafted items may also appear more often since their drop rate is effectively 100%.
# Default: false (disabled)
#
# AuctionHouseBot.AdvancedListingRules.UseDropRates.MinQuality
# The minimum quality that should be included by AdvancedListingRules.UseDropRates.
# Value should be the integer corresponding to the desired minimum rarity.
# Examples: Setting to 3 will apply to Rare, Epic, Legendary, and Heirloom.
# Setting to 1 will apply to Common, Uncommon, Rare, Epic, Legendary, and Heirloom.
# (0) Poor, (1) Common, (2) Uncommon, (3) Rare, (4) Epic, (5) Legendary, (6) Heirloom
# Default: 3
#
# AuctionHouseBot.Seller.AdvancedListingRules.UseDropRates.<Category>
# Toggle AdvancedListingRules.UseDropRates behavior for individual category.
# Only applied if AdvancedListingRules.UseDropRates.Enabled is true.
# Default: true (enabled)
###############################################################################
AuctionHouseBot.AdvancedListingRules.UseDropRates.Enabled = false
AuctionHouseBot.AdvancedListingRules.UseDropRates.MinQuality = 2
AuctionHouseBot.AdvancedListingRules.UseDropRates.Weapon = true
AuctionHouseBot.AdvancedListingRules.UseDropRates.Armor = true
AuctionHouseBot.AdvancedListingRules.UseDropRates.Recipe = true
###############################################################################
# AuctionHouseBot.MaxBuyoutPriceInCopper
# Maximum amount that a buyout on a listing can be in copper. Prevents

View File

@@ -157,7 +157,10 @@ AuctionHouseBot::AuctionHouseBot() :
ListedItemIDRestrictedEnabled(false),
ListedItemIDMin(0),
ListedItemIDMax(200000),
SellerUseDBDropRates(false),
AdvancedListingRuleUseDropRatesEnabled(false),
AdvancedListingRuleUseDropRatesWeaponEnabled(true),
AdvancedListingRuleUseDropRatesArmorEnabled(true),
AdvancedListingRuleUseDropRatesRecipeEnabled(true),
LastBuyCycleCount(0),
LastSellCycleCount(0),
ActiveListMultipleItemID(0),
@@ -1014,7 +1017,7 @@ void AuctionHouseBot::AddNewAuctions(std::vector<Player*> AHBPlayers, FactionSpe
}
// If current item is crafted, ineligible, or quest reward, ignore drop rates and continue to list it
if (SellerUseDBDropRates &&
if (AdvancedListingRuleUseDropRatesEnabled &&
IsItemEligibleForDBDropRates(prototype) &&
!IsItemCrafted(itemID) &&
!IsItemQuestReward(itemID))
@@ -1117,6 +1120,28 @@ void AuctionHouseBot::AddNewAuctions(std::vector<Player*> AHBPlayers, FactionSpe
LOG_INFO("module", "AHSeller: Added {} items", itemsGenerated);
}
std::string AuctionHouseBot::GetAdvancedListingRuleUseDropRatesEnabledCategoriesString()
{
std::vector<uint32> enabledCategories;
if (AdvancedListingRuleUseDropRatesWeaponEnabled)
enabledCategories.push_back(ITEM_CLASS_WEAPON);
if (AdvancedListingRuleUseDropRatesArmorEnabled)
enabledCategories.push_back(ITEM_CLASS_ARMOR);
if (AdvancedListingRuleUseDropRatesRecipeEnabled)
enabledCategories.push_back(ITEM_CLASS_RECIPE);
std::ostringstream oss;
for (size_t i = 0; i < enabledCategories.size(); ++i)
{
if (i > 0)
oss << ",";
oss << enabledCategories[i];
}
return oss.str();
}
void AuctionHouseBot::PopulateItemDropChances()
{
// Search creature loot templates, referenced loot_loot_template, group_loot tables, and object_loot tables for items' drop rates
@@ -1127,7 +1152,7 @@ void AuctionHouseBot::PopulateItemDropChances()
FROM creature_template ct
JOIN creature_loot_template clt ON clt.Entry = ct.lootid
JOIN item_template it ON it.entry = clt.Item
WHERE clt.Reference = 0 AND clt.GroupId = 0 AND it.class IN (2,4,9) AND it.quality > 2
WHERE clt.Reference = 0 AND clt.GroupId = 0 AND it.class IN ({}) AND it.quality >= {}
)SQL";
std::string referenceDropString = R"SQL(
@@ -1164,7 +1189,7 @@ void AuctionHouseBot::PopulateItemDropChances()
END AS reference_chance
FROM all_references ar
JOIN item_template it ON it.entry = ar.itemID
WHERE it.class IN (2,4,9) AND it.quality > 2
WHERE it.class IN ({}) AND it.quality >= {}
)SQL";
// This will lookup items in referenced_loot_template whose Reference entry is not associated with a creature_loot_template
@@ -1192,8 +1217,8 @@ void AuctionHouseBot::PopulateItemDropChances()
(1.0 / rd.groupCount) * COALESCE(NULLIF(rd.referenceChance, 0), 1) AS reference_chance
FROM reference_data rd
JOIN item_template it ON it.entry = rd.itemID
WHERE it.class IN (2, 4, 9)
AND it.quality > 2
WHERE it.class IN ({})
AND it.quality >= {}
)SQL";
std::string groupDropString = R"SQL(
@@ -1213,7 +1238,7 @@ void AuctionHouseBot::PopulateItemDropChances()
SELECT group_tables.*, COUNT(*) OVER (PARTITION BY loot_entry, group_id) AS item_count
FROM group_tables
) compute_item_count
WHERE itemClass IN (2,4,9) AND itemQuality > 2
WHERE itemClass IN ({}) AND itemQuality >= {}
)SQL";
std::string objectsDropString = R"SQL(
@@ -1222,24 +1247,33 @@ void AuctionHouseBot::PopulateItemDropChances()
0 AS reference_chance
FROM item_loot_template ilt
JOIN item_template it ON it.entry = ilt.Item
WHERE it.class IN (2,4,9) AND it.quality > 2 AND chance != 0
WHERE it.class IN ({}) AND it.quality >= {} AND chance != 0
UNION ALL
SELECT it.entry AS itemID,
golt.Chance AS direct_chance,
0 AS reference_chance
FROM gameobject_loot_template golt
JOIN item_template it ON it.entry = golt.Item
WHERE it.class IN (2,4,9) AND it.quality > 2 AND chance != 0
WHERE it.class IN ({}) AND it.quality >= {} AND chance != 0
)SQL";
QueryResult directResult = WorldDatabase.Query(directDropString);
QueryResult referenceResult = WorldDatabase.Query(referenceDropString);
QueryResult danglingReferenceResult = WorldDatabase.Query(danglingReferenceDropString);
QueryResult groupResult = WorldDatabase.Query(groupDropString);
QueryResult objectsDropResult = WorldDatabase.Query(objectsDropString);
std::string enabledCategories = GetAdvancedListingRuleUseDropRatesEnabledCategoriesString();
if (enabledCategories.empty())
{
LOG_ERROR("module", "AuctionHouseBot: No categories are enabled for AuctionHouseBot.Seller.AdvancedListingRules.UseDropRates");
return;
}
QueryResult directResult = WorldDatabase.Query(directDropString, enabledCategories, AdvancedListingRuleUseDropRatesMinQuality);
QueryResult referenceResult = WorldDatabase.Query(referenceDropString, enabledCategories, AdvancedListingRuleUseDropRatesMinQuality);
QueryResult danglingReferenceResult = WorldDatabase.Query(danglingReferenceDropString, enabledCategories, AdvancedListingRuleUseDropRatesMinQuality);
QueryResult groupResult = WorldDatabase.Query(groupDropString, enabledCategories, AdvancedListingRuleUseDropRatesMinQuality);
QueryResult objectsDropResult = WorldDatabase.Query(objectsDropString,
enabledCategories, AdvancedListingRuleUseDropRatesMinQuality,
enabledCategories, AdvancedListingRuleUseDropRatesMinQuality);
if (!directResult || !referenceResult || !danglingReferenceResult || !groupResult || !objectsDropResult)
{
LOG_ERROR("module", "AuctionHouseBot: PopulateItemDropChances() failed!");
LOG_ERROR("module", "AuctionHouseBot: PopulateItemDropChances() failed to query items' drop rates.");
return;
}
@@ -1688,7 +1722,11 @@ void AuctionHouseBot::InitializeConfiguration()
SetCyclesBetweenBuyOrSell();
ReturnExpiredAuctionItemsToBot = sConfigMgr->GetOption<bool>("AuctionHouseBot.ReturnExpiredAuctionItemsToBot", false);
ItemsPerCycle = sConfigMgr->GetOption<uint32>("AuctionHouseBot.ItemsPerCycle", 75);
SellerUseDBDropRates = sConfigMgr->GetOption<bool>("AuctionHouseBot.Seller.UseDBDropRates.Enabled", false);
AdvancedListingRuleUseDropRatesEnabled = sConfigMgr->GetOption<bool>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Enabled", false);
AdvancedListingRuleUseDropRatesWeaponEnabled = sConfigMgr->GetOption<bool>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Weapon", true);
AdvancedListingRuleUseDropRatesArmorEnabled = sConfigMgr->GetOption<bool>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Armor", true);
AdvancedListingRuleUseDropRatesRecipeEnabled = sConfigMgr->GetOption<bool>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Recipe", true);
AdvancedListingRuleUseDropRatesMinQuality = sConfigMgr->GetOption<int>("AuctionHouseBot.AdvancedListingRules.UseDropRates.MinQuality", 3);
MaxBuyoutPriceInCopper = sConfigMgr->GetOption<uint32>("AuctionHouseBot.MaxBuyoutPriceInCopper", 1000000000);
BuyoutVariationReducePercent = sConfigMgr->GetOption<float>("AuctionHouseBot.BuyoutVariationReducePercent", 0.15f);
BuyoutVariationAddPercent = sConfigMgr->GetOption<float>("AuctionHouseBot.BuyoutVariationAddPercent", 0.25f);
@@ -2311,8 +2349,21 @@ bool AuctionHouseBot::IsItemCrafted(uint32 itemID)
bool AuctionHouseBot::IsItemEligibleForDBDropRates(ItemTemplate const* proto)
{
return (proto->Quality >= ITEM_QUALITY_RARE &&
(proto->Class == ITEM_CLASS_WEAPON ||
proto->Class == ITEM_CLASS_ARMOR ||
proto->Class == ITEM_CLASS_RECIPE));
if (!AdvancedListingRuleUseDropRatesEnabled)
return false;
if (!proto || proto->Quality < AdvancedListingRuleUseDropRatesMinQuality)
return false;
switch (proto->Class)
{
case ITEM_CLASS_WEAPON:
return AdvancedListingRuleUseDropRatesWeaponEnabled;
case ITEM_CLASS_ARMOR:
return AdvancedListingRuleUseDropRatesArmorEnabled;
case ITEM_CLASS_RECIPE:
return AdvancedListingRuleUseDropRatesRecipeEnabled;
default:
return false;
}
}

View File

@@ -280,7 +280,11 @@ private:
bool PreventOverpayingForVendorItems;
std::unordered_map<uint32, double> CachedItemDropRates;
std::vector<uint32> ItemTiersByClassAndQuality[17][7][11]; // [Classes][Qualities][Tiers]
bool SellerUseDBDropRates;
bool AdvancedListingRuleUseDropRatesEnabled;
bool AdvancedListingRuleUseDropRatesWeaponEnabled;
bool AdvancedListingRuleUseDropRatesArmorEnabled;
bool AdvancedListingRuleUseDropRatesRecipeEnabled;
int AdvancedListingRuleUseDropRatesMinQuality;
std::unordered_set<uint32> QuestRewardItemIDs;
FactionSpecificAuctionHouseConfig AllianceConfig;
@@ -319,6 +323,7 @@ public:
uint32 GetStackSizeForItem(ItemTemplate const* itemProto) const;
void CalculateItemValue(ItemTemplate const* itemProto, uint64& outBidPrice, uint64& outBuyoutPrice);
void PopulateItemDropChances();
std::string GetAdvancedListingRuleUseDropRatesEnabledCategoriesString();
void PopulateQuestRewardItemIDs();
bool IsItemQuestReward(uint32 itemID);
bool IsItemCrafted(uint32 itemID);

View File

@@ -26,7 +26,7 @@ public:
LOG_INFO("server.loading", "AuctionHouseBot: (Re)populating item candidate lists ...");
auctionbot->PopulateItemCandidatesAndProportions();
if (sConfigMgr->GetOption<bool>("AuctionHouseBot.Seller.UseDBDropRates.Enabled", true))
if (sConfigMgr->GetOption<bool>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Enabled", true))
{
auctionbot->PopulateQuestRewardItemIDs();
auctionbot->PopulateItemDropChances();
@@ -38,7 +38,7 @@ public:
{
LOG_INFO("server.loading", "AuctionHouseBot: (Re)populating item candidate lists ...");
auctionbot->PopulateItemCandidatesAndProportions();
if (sConfigMgr->GetOption<bool>("AuctionHouseBot.Seller.UseDBDropRates.Enabled", true))
if (sConfigMgr->GetOption<bool>("AuctionHouseBot.AdvancedListingRules.UseDropRates.Enabled", true))
{
auctionbot->PopulateQuestRewardItemIDs();
auctionbot->PopulateItemDropChances();