diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Accounts/RBAC.h | 16 | ||||
-rw-r--r-- | src/server/game/AuctionHouseBot/AuctionHouseBot.cpp | 428 | ||||
-rw-r--r-- | src/server/game/AuctionHouseBot/AuctionHouseBot.h | 280 | ||||
-rw-r--r-- | src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp | 432 | ||||
-rw-r--r-- | src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h | 96 | ||||
-rw-r--r-- | src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp | 1029 | ||||
-rw-r--r-- | src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h | 147 | ||||
-rw-r--r-- | src/server/game/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.cpp | 10 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/Language.h | 22 | ||||
-rw-r--r-- | src/server/game/Scripting/ScriptLoader.cpp | 2 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 17 | ||||
-rw-r--r-- | src/server/game/World/World.h | 2 | ||||
-rw-r--r-- | src/server/scripts/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_ahbot.cpp | 251 | ||||
-rw-r--r-- | src/server/worldserver/worldserver.conf.dist | 353 |
16 files changed, 3085 insertions, 4 deletions
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index 855ffd51bb8..0a4ec3ab033 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -681,6 +681,22 @@ enum RBACPermissions RBAC_PERM_COMMAND_MODIFY_CURRENCY = 775, // only 4.3.4 RBAC_PERM_COMMAND_DEBUG_PHASE = 776, // only 4.3.4 RBAC_PERM_COMMAND_MAILBOX = 777, + RBAC_PERM_COMMAND_AHBOT = 778, + RBAC_PERM_COMMAND_AHBOT_ITEMS = 779, + RBAC_PERM_COMMAND_AHBOT_ITEMS_GRAY = 780, + RBAC_PERM_COMMAND_AHBOT_ITEMS_WHITE = 781, + RBAC_PERM_COMMAND_AHBOT_ITEMS_GREEN = 782, + RBAC_PERM_COMMAND_AHBOT_ITEMS_BLUE = 783, + RBAC_PERM_COMMAND_AHBOT_ITEMS_PURPLE = 784, + RBAC_PERM_COMMAND_AHBOT_ITEMS_ORANGE = 785, + RBAC_PERM_COMMAND_AHBOT_ITEMS_YELLOW = 786, + RBAC_PERM_COMMAND_AHBOT_RATIO = 787, + RBAC_PERM_COMMAND_AHBOT_RATIO_ALLIANCE = 788, + RBAC_PERM_COMMAND_AHBOT_RATIO_HORDE = 789, + RBAC_PERM_COMMAND_AHBOT_RATIO_NEUTRAL = 790, + RBAC_PERM_COMMAND_AHBOT_REBUILD = 791, + RBAC_PERM_COMMAND_AHBOT_RELOAD = 792, + RBAC_PERM_COMMAND_AHBOT_STATUS = 793, // custom permissions 1000+ RBAC_PERM_MAX diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp new file mode 100644 index 00000000000..707e143ac39 --- /dev/null +++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp @@ -0,0 +1,428 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "Log.h" +#include "Item.h" +#include "World.h" +#include "Config.h" +#include "AuctionHouseMgr.h" +#include "AuctionHouseBot.h" +#include "AuctionHouseBotBuyer.h" +#include "AuctionHouseBotSeller.h" + +bool AuctionBotConfig::Initialize() +{ + GetConfigFromFile(); + + if (!GetConfig(CONFIG_AHBOT_BUYER_ENABLED) && !GetConfig(CONFIG_AHBOT_SELLER_ENABLED)) + { + TC_LOG_INFO("ahbot", "AHBOT is Disabled."); + return false; + } + + if (GetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO) == 0 && GetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO) == 0 && GetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO) == 0 && + !GetConfig(CONFIG_AHBOT_BUYER_ALLIANCE_ENABLED) && !GetConfig(CONFIG_AHBOT_BUYER_HORDE_ENABLED) && !GetConfig(CONFIG_AHBOT_BUYER_NEUTRAL_ENABLED)) + { + TC_LOG_INFO("ahbot", "All feature of AuctionHouseBot are disabled!"); + return false; + } + + if (GetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO) == 0 && GetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO) == 0 && GetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO) == 0) + TC_LOG_INFO("ahbot", "AuctionHouseBot SELLER is disabled!"); + + if (!GetConfig(CONFIG_AHBOT_BUYER_ALLIANCE_ENABLED) && !GetConfig(CONFIG_AHBOT_BUYER_HORDE_ENABLED) && !GetConfig(CONFIG_AHBOT_BUYER_NEUTRAL_ENABLED)) + TC_LOG_INFO("ahbot", "AuctionHouseBot BUYER is disabled!"); + + _itemsPerCycleBoost = GetConfig(CONFIG_AHBOT_ITEMS_PER_CYCLE_BOOST); + _itemsPerCycleNormal = GetConfig(CONFIG_AHBOT_ITEMS_PER_CYCLE_NORMAL); + + return true; +} + +void AuctionBotConfig::SetConfig(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue) +{ + SetConfig(index, sConfigMgr->GetIntDefault(fieldname, defvalue)); + + if (int32(GetConfig(index)) < 0) + { + TC_LOG_ERROR("ahbot", "AHBot: %s (%i) can't be negative. Using %u instead.", fieldname, int32(GetConfig(index)), defvalue); + SetConfig(index, defvalue); + } +} + +void AuctionBotConfig::SetConfigMax(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue, uint32 maxvalue) +{ + SetConfig(index, sConfigMgr->GetIntDefault(fieldname, defvalue)); + + if (GetConfig(index) > maxvalue) + { + TC_LOG_ERROR("ahbot", "AHBot: %s (%u) must be in range 0...%u. Using %u instead.", fieldname, GetConfig(index), maxvalue, maxvalue); + SetConfig(index, maxvalue); + } +} + +void AuctionBotConfig::SetConfigMinMax(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue, uint32 minvalue, uint32 maxvalue) +{ + SetConfig(index, sConfigMgr->GetIntDefault(fieldname, defvalue)); + + if (GetConfig(index) > maxvalue) + { + TC_LOG_ERROR("ahbot", "AHBot: %s (%u) must be in range %u...%u. Using %u instead.", fieldname, GetConfig(index), minvalue, maxvalue, maxvalue); + SetConfig(index, maxvalue); + } + + if (GetConfig(index) < minvalue) + { + TC_LOG_ERROR("ahbot", "AHBot: %s (%u) must be in range %u...%u. Using %u instead.", fieldname, GetConfig(index), minvalue, maxvalue, minvalue); + SetConfig(index, minvalue); + } +} + +void AuctionBotConfig::SetConfig(AuctionBotConfigBoolValues index, char const* fieldname, bool defvalue) +{ + SetConfig(index, sConfigMgr->GetBoolDefault(fieldname, defvalue)); +} + +//Get AuctionHousebot configuration file +void AuctionBotConfig::GetConfigFromFile() +{ + SetConfigMax(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO, "AuctionHouseBot.Alliance.Items.Amount.Ratio", 100, 10000); + SetConfigMax(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO, "AuctionHouseBot.Horde.Items.Amount.Ratio", 100, 10000); + SetConfigMax(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO, "AuctionHouseBot.Neutral.Items.Amount.Ratio", 100, 10000); + + SetAHBotIncludes(sConfigMgr->GetStringDefault("AuctionHouseBot.forceIncludeItems", "")); + SetAHBotExcludes(sConfigMgr->GetStringDefault("AuctionHouseBot.forceExcludeItems", "")); + + SetConfig(CONFIG_AHBOT_BUYER_ALLIANCE_ENABLED, "AuctionHouseBot.Buyer.Alliance.Enabled", false); + SetConfig(CONFIG_AHBOT_BUYER_HORDE_ENABLED, "AuctionHouseBot.Buyer.Horde.Enabled", false); + SetConfig(CONFIG_AHBOT_BUYER_NEUTRAL_ENABLED, "AuctionHouseBot.Buyer.Neutral.Enabled", false); + + SetConfig(CONFIG_AHBOT_ITEMS_VENDOR, "AuctionHouseBot.Items.Vendor", false); + SetConfig(CONFIG_AHBOT_ITEMS_LOOT, "AuctionHouseBot.Items.Loot", true); + SetConfig(CONFIG_AHBOT_ITEMS_MISC, "AuctionHouseBot.Items.Misc", false); + + SetConfig(CONFIG_AHBOT_BIND_NO, "AuctionHouseBot.Bind.No", true); + SetConfig(CONFIG_AHBOT_BIND_PICKUP, "AuctionHouseBot.Bind.Pickup", false); + SetConfig(CONFIG_AHBOT_BIND_EQUIP, "AuctionHouseBot.Bind.Equip", true); + SetConfig(CONFIG_AHBOT_BIND_USE, "AuctionHouseBot.Bind.Use", true); + SetConfig(CONFIG_AHBOT_BIND_QUEST, "AuctionHouseBot.Bind.Quest", false); + SetConfig(CONFIG_AHBOT_LOCKBOX_ENABLED, "AuctionHouseBot.LockBox.Enabled", false); + + SetConfig(CONFIG_AHBOT_BUYPRICE_SELLER, "AuctionHouseBot.BuyPrice.Seller", true); + + SetConfig(CONFIG_AHBOT_ITEMS_PER_CYCLE_BOOST, "AuctionHouseBot.ItemsPerCycle.Boost", 1000); + SetConfig(CONFIG_AHBOT_ITEMS_PER_CYCLE_NORMAL, "AuctionHouseBot.ItemsPerCycle.Normal", 20); + + SetConfig(CONFIG_AHBOT_ITEM_MIN_ITEM_LEVEL, "AuctionHouseBot.Items.ItemLevel.Min", 0); + SetConfig(CONFIG_AHBOT_ITEM_MAX_ITEM_LEVEL, "AuctionHouseBot.Items.ItemLevel.Max", 0); + SetConfig(CONFIG_AHBOT_ITEM_MIN_REQ_LEVEL, "AuctionHouseBot.Items.ReqLevel.Min", 0); + SetConfig(CONFIG_AHBOT_ITEM_MAX_REQ_LEVEL, "AuctionHouseBot.Items.ReqLevel.Max", 0); + SetConfig(CONFIG_AHBOT_ITEM_MIN_SKILL_RANK, "AuctionHouseBot.Items.ReqSkill.Min", 0); + SetConfig(CONFIG_AHBOT_ITEM_MAX_SKILL_RANK, "AuctionHouseBot.Items.ReqSkill.Max", 0); + + SetConfig(CONFIG_AHBOT_ITEM_GRAY_AMOUNT, "AuctionHouseBot.Items.Amount.Gray", 0); + SetConfig(CONFIG_AHBOT_ITEM_WHITE_AMOUNT, "AuctionHouseBot.Items.Amount.White", 2000); + SetConfig(CONFIG_AHBOT_ITEM_GREEN_AMOUNT, "AuctionHouseBot.Items.Amount.Green", 2500); + SetConfig(CONFIG_AHBOT_ITEM_BLUE_AMOUNT, "AuctionHouseBot.Items.Amount.Blue", 1500); + SetConfig(CONFIG_AHBOT_ITEM_PURPLE_AMOUNT, "AuctionHouseBot.Items.Amount.Purple", 500); + SetConfig(CONFIG_AHBOT_ITEM_ORANGE_AMOUNT, "AuctionHouseBot.Items.Amount.Orange", 0); + SetConfig(CONFIG_AHBOT_ITEM_YELLOW_AMOUNT, "AuctionHouseBot.Items.Amount.Yellow", 0); + + SetConfigMax(CONFIG_AHBOT_CLASS_CONSUMABLE_AMOUNT, "AuctionHouseBot.Class.Consumable", 6, 10); + SetConfigMax(CONFIG_AHBOT_CLASS_CONTAINER_AMOUNT, "AuctionHouseBot.Class.Container", 4, 10); + SetConfigMax(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT, "AuctionHouseBot.Class.Weapon", 8, 10); + SetConfigMax(CONFIG_AHBOT_CLASS_GEM_AMOUNT, "AuctionHouseBot.Class.Gem", 3, 10); + SetConfigMax(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT, "AuctionHouseBot.Class.Armor", 8, 10); + SetConfigMax(CONFIG_AHBOT_CLASS_REAGENT_AMOUNT, "AuctionHouseBot.Class.Reagent", 1, 10); + SetConfigMax(CONFIG_AHBOT_CLASS_PROJECTILE_AMOUNT, "AuctionHouseBot.Class.Projectile", 2, 10); + SetConfigMax(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT, "AuctionHouseBot.Class.TradeGood", 10, 10); + SetConfigMax(CONFIG_AHBOT_CLASS_GENERIC_AMOUNT, "AuctionHouseBot.Class.Generic", 1, 10); + SetConfigMax(CONFIG_AHBOT_CLASS_RECIPE_AMOUNT, "AuctionHouseBot.Class.Recipe", 6, 10); + SetConfigMax(CONFIG_AHBOT_CLASS_QUIVER_AMOUNT, "AuctionHouseBot.Class.Quiver", 1, 10); + SetConfigMax(CONFIG_AHBOT_CLASS_QUEST_AMOUNT, "AuctionHouseBot.Class.Quest", 1, 10); + SetConfigMax(CONFIG_AHBOT_CLASS_KEY_AMOUNT, "AuctionHouseBot.Class.Key", 1, 10); + SetConfigMax(CONFIG_AHBOT_CLASS_MISC_AMOUNT, "AuctionHouseBot.Class.Misc", 5, 10); + SetConfigMax(CONFIG_AHBOT_CLASS_GLYPH_AMOUNT, "AuctionHouseBot.Class.Glyph", 3, 10); + + SetConfig(CONFIG_AHBOT_ALLIANCE_PRICE_RATIO, "AuctionHouseBot.Alliance.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_HORDE_PRICE_RATIO, "AuctionHouseBot.Horde.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_NEUTRAL_PRICE_RATIO, "AuctionHouseBot.Neutral.Price.Ratio", 100); + + SetConfig(CONFIG_AHBOT_ITEM_GRAY_PRICE_RATIO, "AuctionHouseBot.Items.Gray.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_ITEM_WHITE_PRICE_RATIO, "AuctionHouseBot.Items.White.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_ITEM_GREEN_PRICE_RATIO, "AuctionHouseBot.Items.Green.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_ITEM_BLUE_PRICE_RATIO, "AuctionHouseBot.Items.Blue.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_ITEM_PURPLE_PRICE_RATIO, "AuctionHouseBot.Items.Purple.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_ITEM_ORANGE_PRICE_RATIO, "AuctionHouseBot.Items.Orange.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_ITEM_YELLOW_PRICE_RATIO, "AuctionHouseBot.Items.Yellow.Price.Ratio", 100); + + SetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_PRICE_RATIO, "AuctionHouseBot.Class.Consumable.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_CLASS_CONTAINER_PRICE_RATIO, "AuctionHouseBot.Class.Container.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_CLASS_WEAPON_PRICE_RATIO, "AuctionHouseBot.Class.Weapon.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_CLASS_GEM_PRICE_RATIO, "AuctionHouseBot.Class.Gem.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_CLASS_ARMOR_PRICE_RATIO, "AuctionHouseBot.Class.Armor.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_CLASS_REAGENT_PRICE_RATIO, "AuctionHouseBot.Class.Reagent.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_PRICE_RATIO, "AuctionHouseBot.Class.Projectile.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_PRICE_RATIO, "AuctionHouseBot.Class.TradeGood.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_CLASS_GENERIC_PRICE_RATIO, "AuctionHouseBot.Class.Generic.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_CLASS_RECIPE_PRICE_RATIO, "AuctionHouseBot.Class.Recipe.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_CLASS_QUIVER_PRICE_RATIO, "AuctionHouseBot.Class.Quiver.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_CLASS_QUEST_PRICE_RATIO, "AuctionHouseBot.Class.Quest.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_CLASS_KEY_PRICE_RATIO, "AuctionHouseBot.Class.Key.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_CLASS_MISC_PRICE_RATIO, "AuctionHouseBot.Class.Misc.Price.Ratio", 100); + SetConfig(CONFIG_AHBOT_CLASS_GLYPH_PRICE_RATIO, "AuctionHouseBot.Class.Glyph.Price.Ratio", 100); + + SetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_ALLOW_ZERO, "AuctionHouseBot.Class.Consumable.Allow.Zero", false); + SetConfig(CONFIG_AHBOT_CLASS_CONTAINER_ALLOW_ZERO, "AuctionHouseBot.Class.Container.Allow.Zero", false); + SetConfig(CONFIG_AHBOT_CLASS_WEAPON_ALLOW_ZERO, "AuctionHouseBot.Class.Weapon.Allow.Zero", false); + SetConfig(CONFIG_AHBOT_CLASS_GEM_ALLOW_ZERO, "AuctionHouseBot.Class.Gem.Allow.Zero", false); + SetConfig(CONFIG_AHBOT_CLASS_ARMOR_ALLOW_ZERO, "AuctionHouseBot.Class.Armor.Allow.Zero", false); + SetConfig(CONFIG_AHBOT_CLASS_REAGENT_ALLOW_ZERO, "AuctionHouseBot.Class.Reagent.Allow.Zero", false); + SetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_ALLOW_ZERO, "AuctionHouseBot.Class.Projectile.Allow.Zero", false); + SetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_ALLOW_ZERO, "AuctionHouseBot.Class.TradeGood.Allow.Zero", false); + SetConfig(CONFIG_AHBOT_CLASS_RECIPE_ALLOW_ZERO, "AuctionHouseBot.Class.Recipe.Allow.Zero", false); + SetConfig(CONFIG_AHBOT_CLASS_QUIVER_ALLOW_ZERO, "AuctionHouseBot.Class.Quiver.Allow.Zero", false); + SetConfig(CONFIG_AHBOT_CLASS_QUEST_ALLOW_ZERO, "AuctionHouseBot.Class.Quest.Allow.Zero", false); + SetConfig(CONFIG_AHBOT_CLASS_KEY_ALLOW_ZERO, "AuctionHouseBot.Class.Key.Allow.Zero", false); + SetConfig(CONFIG_AHBOT_CLASS_MISC_ALLOW_ZERO, "AuctionHouseBot.Class.Misc.Allow.Zero", false); + SetConfig(CONFIG_AHBOT_CLASS_GLYPH_ALLOW_ZERO, "AuctionHouseBot.Class.Glyph.Allow.Zero", false); + + SetConfig(CONFIG_AHBOT_MINTIME, "AuctionHouseBot.MinTime", 1); + SetConfig(CONFIG_AHBOT_MAXTIME, "AuctionHouseBot.MaxTime", 72); + + SetConfigMinMax(CONFIG_AHBOT_BUYER_CHANCE_RATIO_ALLIANCE, "AuctionHouseBot.Buyer.Alliance.Chance.Ratio", 3, 1, 100); + SetConfigMinMax(CONFIG_AHBOT_BUYER_CHANCE_RATIO_HORDE, "AuctionHouseBot.Buyer.Horde.Chance.Ratio", 3, 1, 100); + SetConfigMinMax(CONFIG_AHBOT_BUYER_CHANCE_RATIO_NEUTRAL, "AuctionHouseBot.Buyer.Neutral.Chance.Ratio", 3, 1, 100); + SetConfigMinMax(CONFIG_AHBOT_BUYER_RECHECK_INTERVAL, "AuctionHouseBot.Buyer.Recheck.Interval", 20, 1, DAY / MINUTE); + + SetConfig(CONFIG_AHBOT_SELLER_ENABLED, "AuctionHouseBot.Seller.Enabled", false); + SetConfig(CONFIG_AHBOT_BUYER_ENABLED, "AuctionHouseBot.Buyer.Enabled", false); + SetConfig(CONFIG_AHBOT_BUYPRICE_BUYER, "AuctionHouseBot.Buyer.Buyprice", true); + + SetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MIN_REQ_LEVEL, "AuctionHouseBot.Class.Misc.Mount.ReqLevel.Min", 0); + SetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MAX_REQ_LEVEL, "AuctionHouseBot.Class.Misc.Mount.ReqLevel.Max", 0); + SetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MIN_SKILL_RANK, "AuctionHouseBot.Class.Misc.Mount.ReqSkill.Min", 0); + SetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MAX_SKILL_RANK, "AuctionHouseBot.Class.Misc.Mount.ReqSkill.Max", 0); + SetConfig(CONFIG_AHBOT_CLASS_GLYPH_MIN_REQ_LEVEL, "AuctionHouseBot.Class.Glyph.ReqLevel.Min", 0); + SetConfig(CONFIG_AHBOT_CLASS_GLYPH_MAX_REQ_LEVEL, "AuctionHouseBot.Class.Glyph.ReqLevel.Max", 0); + SetConfig(CONFIG_AHBOT_CLASS_GLYPH_MIN_ITEM_LEVEL, "AuctionHouseBot.Class.Glyph.ItemLevel.Min", 0); + SetConfig(CONFIG_AHBOT_CLASS_GLYPH_MAX_ITEM_LEVEL, "AuctionHouseBot.Class.Glyph.ItemLevel.Max", 0); + SetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_MIN_ITEM_LEVEL, "AuctionHouseBot.Class.TradeGood.ItemLevel.Min", 0); + SetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_MAX_ITEM_LEVEL, "AuctionHouseBot.Class.TradeGood.ItemLevel.Max", 0); + SetConfig(CONFIG_AHBOT_CLASS_CONTAINER_MIN_ITEM_LEVEL, "AuctionHouseBot.Class.Container.ItemLevel.Min", 0); + SetConfig(CONFIG_AHBOT_CLASS_CONTAINER_MAX_ITEM_LEVEL, "AuctionHouseBot.Class.Container.ItemLevel.Max", 0); +} + +char const* AuctionBotConfig::GetHouseTypeName(AuctionHouseType houseType) +{ + static char const* names[MAX_AUCTION_HOUSE_TYPE] = { "Alliance", "Horde", "Neutral" }; + return names[houseType]; +} + +uint32 AuctionBotConfig::GetConfigItemAmountRatio(AuctionHouseType houseType) const +{ + switch (houseType) + { + case AUCTION_HOUSE_ALLIANCE: + return GetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO); + case AUCTION_HOUSE_HORDE: + return GetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO); + default: + return GetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO); + } +} + +bool AuctionBotConfig::GetConfigBuyerEnabled(AuctionHouseType houseType) const +{ + switch (houseType) + { + case AUCTION_HOUSE_ALLIANCE: + return GetConfig(CONFIG_AHBOT_BUYER_ALLIANCE_ENABLED); + case AUCTION_HOUSE_HORDE: + return GetConfig(CONFIG_AHBOT_BUYER_HORDE_ENABLED); + default: + return GetConfig(CONFIG_AHBOT_BUYER_NEUTRAL_ENABLED); + } +} + +uint32 AuctionBotConfig::GetConfigItemQualityAmount(AuctionQuality quality) const +{ + switch (quality) + { + case AUCTION_QUALITY_GRAY: + return GetConfig(CONFIG_AHBOT_ITEM_GRAY_AMOUNT); + case AUCTION_QUALITY_WHITE: + return GetConfig(CONFIG_AHBOT_ITEM_WHITE_AMOUNT); + case AUCTION_QUALITY_GREEN: + return GetConfig(CONFIG_AHBOT_ITEM_GREEN_AMOUNT); + case AUCTION_QUALITY_BLUE: + return GetConfig(CONFIG_AHBOT_ITEM_BLUE_AMOUNT); + case AUCTION_QUALITY_PURPLE: + return GetConfig(CONFIG_AHBOT_ITEM_PURPLE_AMOUNT); + case AUCTION_QUALITY_ORANGE: + return GetConfig(CONFIG_AHBOT_ITEM_ORANGE_AMOUNT); + default: + return GetConfig(CONFIG_AHBOT_ITEM_YELLOW_AMOUNT); + } +} + +AuctionHouseBot::AuctionHouseBot(): _buyer(nullptr), _seller(nullptr), _operationSelector(0) +{ +} + +AuctionHouseBot::~AuctionHouseBot() +{ + delete _buyer; + delete _seller; +} + +void AuctionHouseBot::InitializeAgents() +{ + if (sAuctionBotConfig->GetConfig(CONFIG_AHBOT_SELLER_ENABLED)) + { + if (_seller) + delete _seller; + + _seller = new AuctionBotSeller(); + if (!_seller->Initialize()) + { + delete _seller; + _seller = nullptr; + } + } + + if (sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYER_ENABLED)) + { + if (_buyer) + delete _buyer; + + _buyer = new AuctionBotBuyer(); + if (!_buyer->Initialize()) + { + delete _buyer; + _buyer = nullptr; + } + } +} + +void AuctionHouseBot::Initialize() +{ + if (sAuctionBotConfig->Initialize()) + InitializeAgents(); +} + +void AuctionHouseBot::SetItemsRatio(uint32 al, uint32 ho, uint32 ne) +{ + if (_seller) + _seller->SetItemsRatio(al, ho, ne); +} + +void AuctionHouseBot::SetItemsRatioForHouse(AuctionHouseType house, uint32 val) +{ + if (_seller) + _seller->SetItemsRatioForHouse(house, val); +} + +void AuctionHouseBot::SetItemsAmount(uint32(&vals)[MAX_AUCTION_QUALITY]) +{ + if (_seller) + _seller->SetItemsAmount(vals); +} + +void AuctionHouseBot::SetItemsAmountForQuality(AuctionQuality quality, uint32 val) +{ + if (_seller) + _seller->SetItemsAmountForQuality(quality, val); +} + +void AuctionHouseBot::ReloadAllConfig() +{ + sAuctionBotConfig->Reload(); + InitializeAgents(); +} + +void AuctionHouseBot::PrepareStatusInfos(AuctionHouseBotStatusInfo& statusInfo) +{ + for (uint32 i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i) + { + statusInfo[i].ItemsCount = 0; + + for (int j = 0; j < MAX_AUCTION_QUALITY; ++j) + statusInfo[i].QualityInfo[j] = 0; + + AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(AuctionHouseType(i)); + for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr) + { + AuctionEntry* auctionEntry = itr->second; + if (Item* item = sAuctionMgr->GetAItem(auctionEntry->itemGUIDLow)) + { + ItemTemplate const* prototype = item->GetTemplate(); + if (!auctionEntry->owner) // Add only ahbot items + { + if (prototype->Quality < MAX_AUCTION_QUALITY) + ++statusInfo[i].QualityInfo[prototype->Quality]; + + ++statusInfo[i].ItemsCount; + } + } + } + } +} + +void AuctionHouseBot::Rebuild(bool all) +{ + for (uint32 i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i) + { + AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(AuctionHouseType(i)); + for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr) + if (!itr->second->owner) // ahbot auction + if (all || itr->second->bid == 0) // expire now auction if no bid or forced + itr->second->expire_time = sWorld->GetGameTime(); + } +} + +void AuctionHouseBot::Update() +{ + // nothing do... + if (!_buyer && !_seller) + return; + + // scan all possible update cases until first success + for (uint32 count = 0; count < 2 * MAX_AUCTION_HOUSE_TYPE; ++count) + { + bool successStep = false; + + if (_operationSelector < MAX_AUCTION_HOUSE_TYPE) + { + if (_seller) + successStep = _seller->Update(AuctionHouseType(_operationSelector)); + } + else + { + if (_buyer) + successStep = _buyer->Update(AuctionHouseType(_operationSelector - MAX_AUCTION_HOUSE_TYPE)); + } + + ++_operationSelector; + if (_operationSelector >= 2 * MAX_AUCTION_HOUSE_TYPE) + _operationSelector = 0; + + // one success update per call + if (successStep) + break; + } +} diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.h b/src/server/game/AuctionHouseBot/AuctionHouseBot.h new file mode 100644 index 00000000000..8c1a2425f7c --- /dev/null +++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.h @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef AUCTION_HOUSE_BOT_H +#define AUCTION_HOUSE_BOT_H + +#include "Define.h" + +class AuctionBotSeller; +class AuctionBotBuyer; + +// shadow of ItemQualities with skipped ITEM_QUALITY_HEIRLOOM, anything after ITEM_QUALITY_ARTIFACT(6) in fact +enum AuctionQuality +{ + AUCTION_QUALITY_GRAY = ITEM_QUALITY_POOR, + AUCTION_QUALITY_WHITE = ITEM_QUALITY_NORMAL, + AUCTION_QUALITY_GREEN = ITEM_QUALITY_UNCOMMON, + AUCTION_QUALITY_BLUE = ITEM_QUALITY_RARE, + AUCTION_QUALITY_PURPLE = ITEM_QUALITY_EPIC, + AUCTION_QUALITY_ORANGE = ITEM_QUALITY_LEGENDARY, + AUCTION_QUALITY_YELLOW = ITEM_QUALITY_ARTIFACT, +}; + +#define MAX_AUCTION_QUALITY 7 + +enum AuctionHouseType +{ + AUCTION_HOUSE_ALLIANCE = 0, + AUCTION_HOUSE_HORDE = 1, + AUCTION_HOUSE_NEUTRAL = 2 +}; + +#define MAX_AUCTION_HOUSE_TYPE 3 + +enum AuctionBotConfigUInt32Values +{ + CONFIG_AHBOT_MAXTIME, + CONFIG_AHBOT_MINTIME, + CONFIG_AHBOT_ITEMS_PER_CYCLE_BOOST, + CONFIG_AHBOT_ITEMS_PER_CYCLE_NORMAL, + CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO, + CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO, + CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO, + CONFIG_AHBOT_ITEM_MIN_ITEM_LEVEL, + CONFIG_AHBOT_ITEM_MAX_ITEM_LEVEL, + CONFIG_AHBOT_ITEM_MIN_REQ_LEVEL, + CONFIG_AHBOT_ITEM_MAX_REQ_LEVEL, + CONFIG_AHBOT_ITEM_MIN_SKILL_RANK, + CONFIG_AHBOT_ITEM_MAX_SKILL_RANK, + CONFIG_AHBOT_ITEM_GRAY_AMOUNT, + CONFIG_AHBOT_ITEM_WHITE_AMOUNT, + CONFIG_AHBOT_ITEM_GREEN_AMOUNT, + CONFIG_AHBOT_ITEM_BLUE_AMOUNT, + CONFIG_AHBOT_ITEM_PURPLE_AMOUNT, + CONFIG_AHBOT_ITEM_ORANGE_AMOUNT, + CONFIG_AHBOT_ITEM_YELLOW_AMOUNT, + CONFIG_AHBOT_CLASS_CONSUMABLE_AMOUNT, + CONFIG_AHBOT_CLASS_CONTAINER_AMOUNT, + CONFIG_AHBOT_CLASS_WEAPON_AMOUNT, + CONFIG_AHBOT_CLASS_GEM_AMOUNT, + CONFIG_AHBOT_CLASS_ARMOR_AMOUNT, + CONFIG_AHBOT_CLASS_REAGENT_AMOUNT, + CONFIG_AHBOT_CLASS_PROJECTILE_AMOUNT, + CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT, + CONFIG_AHBOT_CLASS_GENERIC_AMOUNT, + CONFIG_AHBOT_CLASS_RECIPE_AMOUNT, + CONFIG_AHBOT_CLASS_QUIVER_AMOUNT, + CONFIG_AHBOT_CLASS_QUEST_AMOUNT, + CONFIG_AHBOT_CLASS_KEY_AMOUNT, + CONFIG_AHBOT_CLASS_MISC_AMOUNT, + CONFIG_AHBOT_CLASS_GLYPH_AMOUNT, + CONFIG_AHBOT_ALLIANCE_PRICE_RATIO, + CONFIG_AHBOT_HORDE_PRICE_RATIO, + CONFIG_AHBOT_NEUTRAL_PRICE_RATIO, + CONFIG_AHBOT_ITEM_GRAY_PRICE_RATIO, + CONFIG_AHBOT_ITEM_WHITE_PRICE_RATIO, + CONFIG_AHBOT_ITEM_GREEN_PRICE_RATIO, + CONFIG_AHBOT_ITEM_BLUE_PRICE_RATIO, + CONFIG_AHBOT_ITEM_PURPLE_PRICE_RATIO, + CONFIG_AHBOT_ITEM_ORANGE_PRICE_RATIO, + CONFIG_AHBOT_ITEM_YELLOW_PRICE_RATIO, + CONFIG_AHBOT_CLASS_CONSUMABLE_PRICE_RATIO, + CONFIG_AHBOT_CLASS_CONTAINER_PRICE_RATIO, + CONFIG_AHBOT_CLASS_WEAPON_PRICE_RATIO, + CONFIG_AHBOT_CLASS_GEM_PRICE_RATIO, + CONFIG_AHBOT_CLASS_ARMOR_PRICE_RATIO, + CONFIG_AHBOT_CLASS_REAGENT_PRICE_RATIO, + CONFIG_AHBOT_CLASS_PROJECTILE_PRICE_RATIO, + CONFIG_AHBOT_CLASS_TRADEGOOD_PRICE_RATIO, + CONFIG_AHBOT_CLASS_GENERIC_PRICE_RATIO, + CONFIG_AHBOT_CLASS_RECIPE_PRICE_RATIO, + CONFIG_AHBOT_CLASS_MONEY_PRICE_RATIO, + CONFIG_AHBOT_CLASS_QUIVER_PRICE_RATIO, + CONFIG_AHBOT_CLASS_QUEST_PRICE_RATIO, + CONFIG_AHBOT_CLASS_KEY_PRICE_RATIO, + CONFIG_AHBOT_CLASS_PERMANENT_PRICE_RATIO, + CONFIG_AHBOT_CLASS_MISC_PRICE_RATIO, + CONFIG_AHBOT_CLASS_GLYPH_PRICE_RATIO, + CONFIG_AHBOT_BUYER_CHANCE_RATIO_ALLIANCE, + CONFIG_AHBOT_BUYER_CHANCE_RATIO_HORDE, + CONFIG_AHBOT_BUYER_CHANCE_RATIO_NEUTRAL, + CONFIG_AHBOT_BUYER_RECHECK_INTERVAL, + CONFIG_AHBOT_CLASS_MISC_MOUNT_MIN_REQ_LEVEL, + CONFIG_AHBOT_CLASS_MISC_MOUNT_MAX_REQ_LEVEL, + CONFIG_AHBOT_CLASS_MISC_MOUNT_MIN_SKILL_RANK, + CONFIG_AHBOT_CLASS_MISC_MOUNT_MAX_SKILL_RANK, + CONFIG_AHBOT_CLASS_GLYPH_MIN_REQ_LEVEL, + CONFIG_AHBOT_CLASS_GLYPH_MAX_REQ_LEVEL, + CONFIG_AHBOT_CLASS_GLYPH_MIN_ITEM_LEVEL, + CONFIG_AHBOT_CLASS_GLYPH_MAX_ITEM_LEVEL, + CONFIG_AHBOT_CLASS_TRADEGOOD_MIN_ITEM_LEVEL, + CONFIG_AHBOT_CLASS_TRADEGOOD_MAX_ITEM_LEVEL, + CONFIG_AHBOT_CLASS_CONTAINER_MIN_ITEM_LEVEL, + CONFIG_AHBOT_CLASS_CONTAINER_MAX_ITEM_LEVEL, + CONFIG_UINT32_AHBOT_UINT32_COUNT +}; + +enum AuctionBotConfigBoolValues +{ + CONFIG_AHBOT_BUYER_ALLIANCE_ENABLED, + CONFIG_AHBOT_BUYER_HORDE_ENABLED, + CONFIG_AHBOT_BUYER_NEUTRAL_ENABLED, + CONFIG_AHBOT_ITEMS_VENDOR, + CONFIG_AHBOT_ITEMS_LOOT, + CONFIG_AHBOT_ITEMS_MISC, + CONFIG_AHBOT_BIND_NO, + CONFIG_AHBOT_BIND_PICKUP, + CONFIG_AHBOT_BIND_EQUIP, + CONFIG_AHBOT_BIND_USE, + CONFIG_AHBOT_BIND_QUEST, + CONFIG_AHBOT_BUYPRICE_SELLER, + CONFIG_AHBOT_BUYPRICE_BUYER, + CONFIG_AHBOT_SELLER_ENABLED, + CONFIG_AHBOT_BUYER_ENABLED, + CONFIG_AHBOT_LOCKBOX_ENABLED, + CONFIG_AHBOT_CLASS_CONSUMABLE_ALLOW_ZERO, + CONFIG_AHBOT_CLASS_CONTAINER_ALLOW_ZERO, + CONFIG_AHBOT_CLASS_WEAPON_ALLOW_ZERO, + CONFIG_AHBOT_CLASS_GEM_ALLOW_ZERO, + CONFIG_AHBOT_CLASS_ARMOR_ALLOW_ZERO, + CONFIG_AHBOT_CLASS_REAGENT_ALLOW_ZERO, + CONFIG_AHBOT_CLASS_PROJECTILE_ALLOW_ZERO, + CONFIG_AHBOT_CLASS_TRADEGOOD_ALLOW_ZERO, + CONFIG_AHBOT_CLASS_RECIPE_ALLOW_ZERO, + CONFIG_AHBOT_CLASS_QUIVER_ALLOW_ZERO, + CONFIG_AHBOT_CLASS_QUEST_ALLOW_ZERO, + CONFIG_AHBOT_CLASS_KEY_ALLOW_ZERO, + CONFIG_AHBOT_CLASS_MISC_ALLOW_ZERO, + CONFIG_AHBOT_CLASS_GLYPH_ALLOW_ZERO, + CONFIG_UINT32_AHBOT_BOOL_COUNT +}; + +// All basic config data used by other AHBot classes for self-configure. +class AuctionBotConfig +{ +private: + AuctionBotConfig() {} + ~AuctionBotConfig() {} + AuctionBotConfig(const AuctionBotConfig&); + AuctionBotConfig& operator=(const AuctionBotConfig&); + +public: + static AuctionBotConfig* instance() + { + static AuctionBotConfig instance; + return &instance; + } + + bool Initialize(); + const std::string& GetAHBotIncludes() const { return _AHBotIncludes; } + const std::string& GetAHBotExcludes() const { return _AHBotExcludes; } + + uint32 GetConfig(AuctionBotConfigUInt32Values index) const { return _configUint32Values[index]; } + bool GetConfig(AuctionBotConfigBoolValues index) const { return _configBoolValues[index]; } + void SetConfig(AuctionBotConfigBoolValues index, bool value) { _configBoolValues[index] = value; } + void SetConfig(AuctionBotConfigUInt32Values index, uint32 value) { _configUint32Values[index] = value; } + + uint32 GetConfigItemAmountRatio(AuctionHouseType houseType) const; + bool GetConfigBuyerEnabled(AuctionHouseType houseType) const; + uint32 GetConfigItemQualityAmount(AuctionQuality quality) const; + + uint32 GetItemPerCycleBoost() const { return _itemsPerCycleBoost; } + uint32 GetItemPerCycleNormal() const { return _itemsPerCycleNormal; } + void Reload() { GetConfigFromFile(); } + + static char const* GetHouseTypeName(AuctionHouseType houseType); + +private: + std::string _AHBotIncludes; + std::string _AHBotExcludes; + uint32 _itemsPerCycleBoost; + uint32 _itemsPerCycleNormal; + + uint32 _configUint32Values[CONFIG_UINT32_AHBOT_UINT32_COUNT]; + bool _configBoolValues[CONFIG_UINT32_AHBOT_BOOL_COUNT]; + + void SetAHBotIncludes(const std::string& AHBotIncludes) { _AHBotIncludes = AHBotIncludes; } + void SetAHBotExcludes(const std::string& AHBotExcludes) { _AHBotExcludes = AHBotExcludes; } + + void SetConfig(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue); + void SetConfigMax(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue, uint32 maxvalue); + void SetConfigMinMax(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue, uint32 minvalue, uint32 maxvalue); + void SetConfig(AuctionBotConfigBoolValues index, char const* fieldname, bool defvalue); + void GetConfigFromFile(); +}; + +#define sAuctionBotConfig AuctionBotConfig::instance() + +class AuctionBotAgent +{ +public: + AuctionBotAgent() {} + virtual ~AuctionBotAgent() {} + virtual bool Initialize() = 0; + virtual bool Update(AuctionHouseType houseType) = 0; +}; + +struct AuctionHouseBotStatusInfoPerType +{ + uint32 ItemsCount; + uint32 QualityInfo[MAX_AUCTION_QUALITY]; +}; + +typedef AuctionHouseBotStatusInfoPerType AuctionHouseBotStatusInfo[MAX_AUCTION_HOUSE_TYPE]; + +// This class handle both Selling and Buying method +// (holder of AuctionBotBuyer and AuctionBotSeller objects) +class AuctionHouseBot +{ +private: + AuctionHouseBot(); + ~AuctionHouseBot(); + AuctionHouseBot(const AuctionHouseBot&); + AuctionHouseBot& operator=(const AuctionHouseBot&); + +public: + static AuctionHouseBot* instance() + { + static AuctionHouseBot instance; + return &instance; + } + + void Update(); + void Initialize(); + + // Followed method is mainly used by cs_ahbot.cpp for in-game/console command + void SetItemsRatio(uint32 al, uint32 ho, uint32 ne); + void SetItemsRatioForHouse(AuctionHouseType house, uint32 val); + void SetItemsAmount(uint32(&vals)[MAX_AUCTION_QUALITY]); + void SetItemsAmountForQuality(AuctionQuality quality, uint32 val); + void ReloadAllConfig(); + void Rebuild(bool all); + + void PrepareStatusInfos(AuctionHouseBotStatusInfo& statusInfo); +private: + void InitializeAgents(); + + AuctionBotBuyer* _buyer; + AuctionBotSeller* _seller; + + uint32 _operationSelector; // 0..2*MAX_AUCTION_HOUSE_TYPE-1 +}; + +#define sAuctionBot AuctionHouseBot::instance() + +#endif diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp new file mode 100644 index 00000000000..f7c8003fc76 --- /dev/null +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp @@ -0,0 +1,432 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "Log.h" +#include "Item.h" +#include "ItemPrototype.h" +#include "AuctionHouseBotBuyer.h" + +AuctionBotBuyer::AuctionBotBuyer() +{ + // Define faction for our main data class. + for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i) + _houseConfig[i].Initialize(AuctionHouseType(i)); +} + +AuctionBotBuyer::~AuctionBotBuyer() +{ +} + +bool AuctionBotBuyer::Initialize() +{ + LoadConfig(); + + bool activeHouse = false; + for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i) + { + if (_houseConfig[i].BuyerEnabled) + { + activeHouse = true; + break; + } + } + + if (!activeHouse) + return false; + + //load Check interval + _checkInterval = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYER_RECHECK_INTERVAL) * MINUTE; + TC_LOG_INFO("ahbot", "AHBot buyer interval between 2 check = %u", _checkInterval); + return true; +} + +void AuctionBotBuyer::LoadBuyerValues(BuyerConfiguration& config) +{ + uint32 factionChance; + + switch (config.GetHouseType()) + { + case AUCTION_HOUSE_ALLIANCE: + config.BuyerPriceRatio = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ALLIANCE_PRICE_RATIO) + 50; + factionChance = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYER_CHANCE_RATIO_ALLIANCE); + break; + case AUCTION_HOUSE_HORDE: + config.BuyerPriceRatio = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_HORDE_PRICE_RATIO) + 50; + factionChance = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYER_CHANCE_RATIO_HORDE); + break; + default: + config.BuyerPriceRatio = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_NEUTRAL_PRICE_RATIO) + 50; + factionChance = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYER_CHANCE_RATIO_NEUTRAL); + break; + } + + config.FactionChance = 5000 * factionChance; +} + +void AuctionBotBuyer::LoadConfig() +{ + for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i) + { + _houseConfig[i].BuyerEnabled = sAuctionBotConfig->GetConfigBuyerEnabled(AuctionHouseType(i)); + if (_houseConfig[i].BuyerEnabled) + LoadBuyerValues(_houseConfig[i]); + } +} + +uint32 AuctionBotBuyer::GetBuyableEntry(BuyerConfiguration& config) +{ + config.SameItemInfo.clear(); + uint32 count = 0; + time_t now = time(nullptr); + + AuctionHouseObject* house = sAuctionMgr->GetAuctionsMap(config.GetHouseType()); + for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = house->GetAuctionsBegin(); itr != house->GetAuctionsEnd(); ++itr) + { + AuctionEntry* entry = itr->second; + Item* item = sAuctionMgr->GetAItem(entry->itemGUIDLow); + if (item) + { + ItemTemplate const * prototype = item->GetTemplate(); + if (prototype) + { + ++config.SameItemInfo[item->GetEntry()].ItemCount; // Structure constructor will make sure Element are correctly initialized if entry is created here. + config.SameItemInfo[item->GetEntry()].BuyPrice = config.SameItemInfo[item->GetEntry()].BuyPrice + (itr->second->buyout / item->GetCount()); + config.SameItemInfo[item->GetEntry()].BidPrice = config.SameItemInfo[item->GetEntry()].BidPrice + (itr->second->startbid / item->GetCount()); + if (itr->second->buyout != 0) + { + if (itr->second->buyout / item->GetCount() < config.SameItemInfo[item->GetEntry()].MinBuyPrice) + config.SameItemInfo[item->GetEntry()].MinBuyPrice = itr->second->buyout / item->GetCount(); + else if (config.SameItemInfo[item->GetEntry()].MinBuyPrice == 0) + config.SameItemInfo[item->GetEntry()].MinBuyPrice = itr->second->buyout / item->GetCount(); + } + if (itr->second->startbid / item->GetCount() < config.SameItemInfo[item->GetEntry()].MinBidPrice) + config.SameItemInfo[item->GetEntry()].MinBidPrice = itr->second->startbid / item->GetCount(); + else if (config.SameItemInfo[item->GetEntry()].MinBidPrice == 0) + config.SameItemInfo[item->GetEntry()].MinBidPrice = itr->second->startbid / item->GetCount(); + + if (!entry->owner) + { + + if (entry->bid != 0 && entry->bidder) // Add bid by player + { + config.CheckedEntry[entry->Id].LastExist = now; + config.CheckedEntry[entry->Id].AuctionId = entry->Id; + ++count; + } + } + else + { + if (entry->bid != 0) + { + if (entry->bidder) + { + config.CheckedEntry[entry->Id].LastExist = now; + config.CheckedEntry[entry->Id].AuctionId = entry->Id; + ++count; + } + } + else + { + config.CheckedEntry[entry->Id].LastExist = now; + config.CheckedEntry[entry->Id].AuctionId = entry->Id; + ++count; + } + } + } + } + } + + TC_LOG_INFO("ahbot", "AHBot: %u items added to buyable vector for ah type: %u", count, config.GetHouseType()); + TC_LOG_INFO("ahbot", "AHBot: SameItemInfo size = %u", (uint32)config.SameItemInfo.size()); + return count; +} + +void AuctionBotBuyer::PrepareListOfEntry(BuyerConfiguration& config) +{ + time_t now = time(nullptr) - 5; + + for (CheckEntryMap::iterator itr = config.CheckedEntry.begin(); itr != config.CheckedEntry.end();) + { + if (itr->second.LastExist < (now - 5)) + config.CheckedEntry.erase(itr++); + else + ++itr; + } + + TC_LOG_INFO("ahbot", "AHBot: CheckedEntry size = %u", (uint32)config.CheckedEntry.size()); +} + +bool AuctionBotBuyer::IsBuyableEntry(uint32 buyoutPrice, double inGameBuyPrice, double maxBuyablePrice, uint32 minBuyPrice, uint32 maxChance, uint32 chanceRatio) +{ + double ratio = 0; + uint32 chance = 0; + + if (buyoutPrice <= minBuyPrice) + { + if (buyoutPrice <= maxBuyablePrice) + chance = maxChance; + else + { + + if (buyoutPrice > 0 && maxBuyablePrice > 0) + { + ratio = buyoutPrice / maxBuyablePrice; + if (ratio < 10) + chance = maxChance - (ratio * maxChance / 10); + else + chance = 1; + } + } + } + else if (buyoutPrice <= inGameBuyPrice) + { + if (buyoutPrice <= maxBuyablePrice) + chance = maxChance / 5; + else + { + + if (buyoutPrice > 0 && maxBuyablePrice > 0) + { + ratio = buyoutPrice / maxBuyablePrice; + if (ratio < 10) + chance = (maxChance / 5) - (ratio * maxChance / 50); + else + chance = 1; + } + } + } + else if (buyoutPrice <= maxBuyablePrice) + chance = maxChance / 10; + else + { + if (buyoutPrice > 0 && maxBuyablePrice > 0) + { + ratio = buyoutPrice / maxBuyablePrice; + if (ratio < 10) + chance = (maxChance / 5) - (ratio* maxChance / 50); + else + chance = 0; + } + else + chance = 0; + } + + if (urand(1, chanceRatio) <= chance) + { + TC_LOG_INFO("ahbot", "AHBot: WIN BUY! Chance = %u, num = %u.", chance, chanceRatio); + return true; + } + else + { + TC_LOG_INFO("ahbot", "AHBot: LOOSE BUY! Chance = %u, num = %u.", chance, chanceRatio); + return false; + } +} + +bool AuctionBotBuyer::IsBidableEntry(uint32 bidPrice, double inGameBuyPrice, double maxBidablePrice, uint32 minBidPrice, uint32 maxChance, uint32 chanceRatio) +{ + double ratio = 0; + uint32 chance = 0; + + if (bidPrice <= minBidPrice) + { + if (inGameBuyPrice != 0 && bidPrice < inGameBuyPrice - (inGameBuyPrice / 30)) + chance = maxChance; + else + { + if (bidPrice < maxBidablePrice) + { + ratio = maxBidablePrice / bidPrice; + if (ratio < 3) + chance = maxChance / 500 * ratio; + else + chance = maxChance / 500; + } + } + } + else if (bidPrice < (inGameBuyPrice - (inGameBuyPrice / 30))) + chance = (maxChance / 10); + else + { + if (bidPrice < maxBidablePrice) + { + ratio = maxBidablePrice / bidPrice; + if (ratio < 4) + chance = maxChance / 1000 * ratio; + else + chance = maxChance / 1000; + } + } + + if (urand(1, chanceRatio) <= chance) + { + TC_LOG_INFO("ahbot", "AHBot: WIN BID! Chance = %u, num = %u.", chance, chanceRatio); + return true; + } + else + { + TC_LOG_INFO("ahbot", "AHBot: LOOSE BID! Chance = %u, num = %u.", chance, chanceRatio); + return false; + } +} + +void AuctionBotBuyer::PlaceBidToEntry(AuctionEntry* auction, uint32 bidPrice) +{ + TC_LOG_INFO("ahbot", "AHBot: Bid placed to entry %u, %.2fg", auction->Id, float(bidPrice) / 10000.0f); + auction->bid = bidPrice; +} + +void AuctionBotBuyer::BuyEntry(AuctionEntry* auction) +{ + TC_LOG_INFO("ahbot", "AHBot: Entry %u bought at %.2fg", auction->Id, float(auction->buyout) / 10000.0f); + auction->bid = auction->buyout; +} + +void AuctionBotBuyer::AddNewAuctionBuyerBotBid(BuyerConfiguration& config) +{ + AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(config.GetHouseType()); + + PrepareListOfEntry(config); + + time_t now = time(nullptr); + uint32 buyCycles; + if (config.CheckedEntry.size() > sAuctionBotConfig->GetItemPerCycleBoost()) + { + buyCycles = sAuctionBotConfig->GetItemPerCycleBoost(); + TC_LOG_INFO("ahbot", "AHBot: Boost value used for Buyer! (if this happens often adjust both ItemsPerCycle in worldserver.conf)"); + } + else + buyCycles = sAuctionBotConfig->GetItemPerCycleNormal(); + + for (CheckEntryMap::iterator itr = config.CheckedEntry.begin(); itr != config.CheckedEntry.end();) + { + AuctionEntry* auction = auctionHouse->GetAuction(itr->second.AuctionId); + if (!auction) // is auction not active now + { + TC_LOG_INFO("ahbot", "AHBot: Entry %u on ah %u doesn't exists, perhaps bought already?", + itr->second.AuctionId, auction->GetHouseId()); + + config.CheckedEntry.erase(itr++); + continue; + } + + if (itr->second.LastChecked != 0 && (now - itr->second.LastChecked) <= _checkInterval) + { + TC_LOG_INFO("ahbot", "AHBot: In time interval wait for entry %u!", auction->Id); + ++itr; + continue; + } + + if (buyCycles == 0) + break; + + uint32 maxChance = 5000; + + Item* item = sAuctionMgr->GetAItem(auction->itemGUIDLow); + if (!item) // auction item not accessible, possible auction in payment pending mode + { + config.CheckedEntry.erase(itr++); + continue; + } + + ItemTemplate const* prototype = item->GetTemplate(); + + uint32 basePrice = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYPRICE_BUYER) ? prototype->BuyPrice : prototype->SellPrice; + basePrice *= item->GetCount(); + + double maxBuyablePrice = (basePrice * config.BuyerPriceRatio) / 100; + BuyerItemInfoMap::iterator sameItemItr = config.SameItemInfo.find(item->GetEntry()); + uint32 buyoutPrice = auction->buyout / item->GetCount(); + + uint32 bidPrice; + uint32 bidPriceByItem; + if (auction->bid >= auction->startbid) + { + bidPrice = auction->GetAuctionOutBid(); + bidPriceByItem = auction->bid / item->GetCount(); + } + else + { + bidPrice = auction->startbid; + bidPriceByItem = auction->startbid / item->GetCount(); + } + + double inGameBuyPrice; + double inGameBidPrice; + if (sameItemItr == config.SameItemInfo.end()) + { + inGameBuyPrice = 0; + inGameBidPrice = 0; + } + else + { + if (sameItemItr->second.ItemCount == 1) + maxBuyablePrice = maxBuyablePrice * 5; // if only one item exist can be bought if the price is high too. + inGameBuyPrice = sameItemItr->second.BuyPrice / sameItemItr->second.ItemCount; + inGameBidPrice = sameItemItr->second.BidPrice / sameItemItr->second.ItemCount; + } + + double maxBidablePrice = maxBuyablePrice - (maxBuyablePrice / 30); // Max Bidable price defined to 70% of max buyable price + + TC_LOG_INFO("ahbot", "AHBot: Auction added with data:"); + TC_LOG_INFO("ahbot", "AHBot: MaxPrice of Entry %u is %.1fg.", itr->second.AuctionId, maxBuyablePrice / 10000); + TC_LOG_INFO("ahbot", "AHBot: GamePrice buy=%.1fg, bid=%.1fg.", inGameBuyPrice / 10000, inGameBidPrice / 10000); + TC_LOG_INFO("ahbot", "AHBot: Minimal price see in AH Buy=%ug, Bid=%ug.", + sameItemItr->second.MinBuyPrice / 10000, sameItemItr->second.MinBidPrice / 10000); + TC_LOG_INFO("ahbot", "AHBot: Actual Entry price, Buy=%ug, Bid=%ug.", buyoutPrice / 10000, bidPrice / 10000); + + if (!auction->owner) // Original auction owner + maxChance = maxChance / 5; // if Owner is AHBot this mean player placed bid on this auction. We divide by 5 chance for AhBuyer to place bid on it. (This make more challenge than ignore entry) + if (auction->buyout != 0) // Is the item directly buyable? + { + if (IsBuyableEntry(buyoutPrice, inGameBuyPrice, maxBuyablePrice, sameItemItr->second.MinBuyPrice, maxChance, config.FactionChance)) + { + if (IsBidableEntry(bidPriceByItem, inGameBuyPrice, maxBidablePrice, sameItemItr->second.MinBidPrice, maxChance / 2, config.FactionChance)) + { + if (urand(0, 5) == 0) + PlaceBidToEntry(auction, bidPrice); + else + BuyEntry(auction); + } + else + BuyEntry(auction); + } + else if (IsBidableEntry(bidPriceByItem, inGameBuyPrice, maxBidablePrice, sameItemItr->second.MinBidPrice, maxChance / 2, config.FactionChance)) + PlaceBidToEntry(auction, bidPrice); + } + else if (IsBidableEntry(bidPriceByItem, inGameBuyPrice, maxBidablePrice, sameItemItr->second.MinBidPrice, maxChance, config.FactionChance)) + PlaceBidToEntry(auction, bidPrice); + + itr->second.LastChecked = now; + --buyCycles; + + ++itr; + } +} + +bool AuctionBotBuyer::Update(AuctionHouseType houseType) +{ + if (sAuctionBotConfig->GetConfigBuyerEnabled(houseType)) + { + TC_LOG_INFO("ahbot", "AHBot: %s buying ...", AuctionBotConfig::GetHouseTypeName(houseType)); + if (GetBuyableEntry(_houseConfig[houseType]) > 0) + AddNewAuctionBuyerBotBid(_houseConfig[houseType]); + return true; + } + + return false; +} diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h new file mode 100644 index 00000000000..89be1b8b052 --- /dev/null +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef AUCTION_HOUSE_BOT_BUYER_H +#define AUCTION_HOUSE_BOT_BUYER_H + +#include "Define.h" +#include "AuctionHouseMgr.h" +#include "AuctionHouseBot.h" + +struct BuyerAuctionEval +{ + BuyerAuctionEval(): AuctionId(0), LastChecked(0), LastExist(0) {} + + uint32 AuctionId; + time_t LastChecked; + time_t LastExist; +}; + +struct BuyerItemInfo +{ + BuyerItemInfo(): ItemCount(0), BuyPrice(0), BidPrice(0), MinBuyPrice(0), MinBidPrice(0) {} + + uint32 ItemCount; + double BuyPrice; + double BidPrice; + uint32 MinBuyPrice; + uint32 MinBidPrice; +}; + +typedef std::map<uint32, BuyerItemInfo> BuyerItemInfoMap; +typedef std::map<uint32, BuyerAuctionEval> CheckEntryMap; + +struct BuyerConfiguration +{ + BuyerConfiguration(): _houseType(AUCTION_HOUSE_NEUTRAL) {} + + void Initialize(AuctionHouseType houseType) + { + _houseType = houseType; + } + + AuctionHouseType GetHouseType() const { return _houseType; } + + BuyerItemInfoMap SameItemInfo; + CheckEntryMap CheckedEntry; + uint32 FactionChance; + bool BuyerEnabled; + uint32 BuyerPriceRatio; + +private: + AuctionHouseType _houseType; +}; + +// This class handle all Buyer method +// (holder of AuctionBotConfig for each auction house type) +class AuctionBotBuyer : public AuctionBotAgent +{ +public: + AuctionBotBuyer(); + ~AuctionBotBuyer() override; + + bool Initialize() override; + bool Update(AuctionHouseType houseType) override; + + void LoadConfig(); + void AddNewAuctionBuyerBotBid(BuyerConfiguration& config); + +private: + uint32 _checkInterval; + BuyerConfiguration _houseConfig[MAX_AUCTION_HOUSE_TYPE]; + + void LoadBuyerValues(BuyerConfiguration& config); + bool IsBuyableEntry(uint32 buyoutPrice, double inGameBuyPrice, double maxBuyablePrice, uint32 minBuyPrice, uint32 maxChance, uint32 chanceRatio); + bool IsBidableEntry(uint32 bidPrice, double inGameBuyPrice, double maxBidablePrice, uint32 minBidPrice, uint32 maxChance, uint32 chanceRatio); + void PlaceBidToEntry(AuctionEntry* auction, uint32 bidPrice); + void BuyEntry(AuctionEntry* auction); + void PrepareListOfEntry(BuyerConfiguration& config); + uint32 GetBuyableEntry(BuyerConfiguration& config); +}; + +#endif diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp new file mode 100644 index 00000000000..053b110e525 --- /dev/null +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp @@ -0,0 +1,1029 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "Log.h" +#include "DBCStores.h" +#include "ObjectMgr.h" +#include "AuctionHouseMgr.h" +#include "AuctionHouseBotSeller.h" + +AuctionBotSeller::AuctionBotSeller() +{ + // Define faction for our main data class. + for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i) + _houseConfig[i].Initialize(AuctionHouseType(i)); +} + +AuctionBotSeller::~AuctionBotSeller() +{ +} + +bool AuctionBotSeller::Initialize() +{ + std::vector<uint32> npcItems; + std::vector<uint32> lootItems; + std::vector<uint32> includeItems; + std::vector<uint32> excludeItems; + + TC_LOG_INFO("ahbot", "AHBot seller filters:"); + + { + std::stringstream includeStream(sAuctionBotConfig->GetAHBotIncludes()); + std::string temp; + while (getline(includeStream, temp, ',')) + includeItems.push_back(atoi(temp.c_str())); + } + + { + std::stringstream excludeStream(sAuctionBotConfig->GetAHBotExcludes()); + std::string temp; + while (getline(excludeStream, temp, ',')) + excludeItems.push_back(atoi(temp.c_str())); + } + + TC_LOG_INFO("ahbot", "Forced Inclusion %u items", (uint32)includeItems.size()); + TC_LOG_INFO("ahbot", "Forced Exclusion %u items", (uint32)excludeItems.size()); + + TC_LOG_INFO("ahbot", "Loading npc vendor items for filter.."); + const CreatureTemplateContainer* creatures = sObjectMgr->GetCreatureTemplates(); + std::set<uint32> tempItems; + for (CreatureTemplateContainer::const_iterator it = creatures->begin(); it != creatures->end(); ++it) + { + if (const VendorItemData* data = sObjectMgr->GetNpcVendorItemList(it->first)) + { + for (VendorItemList::const_iterator it2 = data->m_items.begin(); it2 != data->m_items.end(); ++it2) + tempItems.insert((*it2)->item); + } + } + for (std::set<uint32>::const_iterator it = tempItems.begin(); it != tempItems.end(); ++it) + npcItems.push_back(*it); + + TC_LOG_INFO("ahbot", "Npc vendor filter has %u items", (uint32)npcItems.size()); + + TC_LOG_INFO("ahbot", "Loading loot items for filter.."); + QueryResult result = WorldDatabase.PQuery( + "SELECT `item` FROM `creature_loot_template` UNION " + "SELECT `item` FROM `disenchant_loot_template` UNION " + "SELECT `item` FROM `fishing_loot_template` UNION " + "SELECT `item` FROM `gameobject_loot_template` UNION " + "SELECT `item` FROM `item_loot_template` UNION " + "SELECT `item` FROM `milling_loot_template` UNION " + "SELECT `item` FROM `pickpocketing_loot_template` UNION " + "SELECT `item` FROM `prospecting_loot_template` UNION " + "SELECT `item` FROM `skinning_loot_template` UNION " + "SELECT `item` FROM `spell_loot_template`"); + + if (result) + { + do + { + Field* fields = result->Fetch(); + + uint32 entry = fields[0].GetUInt32(); + if (!entry) + continue; + + lootItems.push_back(entry); + } while (result->NextRow()); + } + + TC_LOG_INFO("ahbot", "Loot filter has %u items", (uint32)lootItems.size()); + TC_LOG_INFO("ahbot", "Sorting and cleaning items for AHBot seller..."); + + uint32 itemsAdded = 0; + + for (uint32 itemId = 0; itemId < sItemStore.GetNumRows(); ++itemId) + { + ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(itemId); + + if (!prototype) + continue; + + // skip items with too high quality (code can't properly work with its) + if (prototype->Quality >= MAX_AUCTION_QUALITY) + continue; + + // forced exclude filter + bool isExcludeItem = false; + for (size_t i = 0; i < excludeItems.size() && !isExcludeItem; ++i) + if (itemId == excludeItems[i]) + isExcludeItem = true; + + if (isExcludeItem) + continue; + + // forced include filter + bool isForcedIncludeItem = false; + for (size_t i = 0; i < includeItems.size() && !isForcedIncludeItem; ++i) + if (itemId == includeItems[i]) + isForcedIncludeItem = true; + + if (isForcedIncludeItem) + { + _itemPool[prototype->Quality][prototype->Class].push_back(itemId); + ++itemsAdded; + continue; + } + + // bounding filters + switch (prototype->Bonding) + { + case NO_BIND: + if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BIND_NO)) + continue; + break; + case BIND_WHEN_PICKED_UP: + if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BIND_PICKUP)) + continue; + break; + case BIND_WHEN_EQUIPED: + if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BIND_EQUIP)) + continue; + break; + case BIND_WHEN_USE: + if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BIND_USE)) + continue; + break; + case BIND_QUEST_ITEM: + if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BIND_QUEST)) + continue; + break; + default: + continue; + } + + bool allowZero = false; + switch (prototype->Class) + { + case ITEM_CLASS_CONSUMABLE: + allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_ALLOW_ZERO); break; + case ITEM_CLASS_CONTAINER: + allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_ALLOW_ZERO); break; + case ITEM_CLASS_WEAPON: + allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_ALLOW_ZERO); break; + case ITEM_CLASS_GEM: + allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GEM_ALLOW_ZERO); break; + case ITEM_CLASS_ARMOR: + allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_ALLOW_ZERO); break; + case ITEM_CLASS_REAGENT: + allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_REAGENT_ALLOW_ZERO); break; + case ITEM_CLASS_PROJECTILE: + allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_ALLOW_ZERO); break; + case ITEM_CLASS_TRADE_GOODS: + allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_ALLOW_ZERO); break; + case ITEM_CLASS_RECIPE: + allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RECIPE_ALLOW_ZERO); break; + case ITEM_CLASS_QUIVER: + allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUIVER_ALLOW_ZERO); break; + case ITEM_CLASS_QUEST: + allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_ALLOW_ZERO); break; + case ITEM_CLASS_KEY: + allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_KEY_ALLOW_ZERO); break; + case ITEM_CLASS_MISC: + allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_ALLOW_ZERO); break; + case ITEM_CLASS_GLYPH: + allowZero = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_ALLOW_ZERO); break; + default: + allowZero = false; + } + + // Filter out items with no buy/sell price unless otherwise flagged in the config. + if (!allowZero) + { + if (sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYPRICE_SELLER)) + { + if (prototype->BuyPrice == 0) + continue; + } + else + { + if (prototype->SellPrice == 0) + continue; + } + } + + // vendor filter + if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEMS_VENDOR)) + { + bool isVendorItem = false; + for (size_t i = 0; i < npcItems.size() && !isVendorItem; ++i) + if (itemId == npcItems[i]) + isVendorItem = true; + + if (isVendorItem) + continue; + } + + // loot filter + if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEMS_LOOT)) + { + bool isLootItem = false; + for (size_t i = 0; i < lootItems.size() && !isLootItem; ++i) + if (itemId == lootItems[i]) + isLootItem = true; + + if (isLootItem) + continue; + } + + // not vendor/loot filter + if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEMS_MISC)) + { + bool isVendorItem = false; + bool isLootItem = false; + + for (size_t i = 0; i < npcItems.size() && !isVendorItem; ++i) + if (itemId == npcItems[i]) + isVendorItem = true; + + for (size_t i = 0; i < lootItems.size() && !isLootItem; ++i) + if (itemId == lootItems[i]) + isLootItem = true; + + if (!isLootItem && !isVendorItem) + continue; + } + + // item class/subclass specific filters + switch (prototype->Class) + { + case ITEM_CLASS_ARMOR: + case ITEM_CLASS_WEAPON: + { + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_ITEM_LEVEL)) + if (prototype->ItemLevel < value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MAX_ITEM_LEVEL)) + if (prototype->ItemLevel > value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_REQ_LEVEL)) + if (prototype->RequiredLevel < value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MAX_REQ_LEVEL)) + if (prototype->RequiredLevel > value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_SKILL_RANK)) + if (prototype->RequiredSkillRank < value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MAX_SKILL_RANK)) + if (prototype->RequiredSkillRank > value) + continue; + break; + } + case ITEM_CLASS_RECIPE: + case ITEM_CLASS_CONSUMABLE: + case ITEM_CLASS_PROJECTILE: + { + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_REQ_LEVEL)) + if (prototype->RequiredLevel < value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MAX_REQ_LEVEL)) + if (prototype->RequiredLevel > value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MIN_SKILL_RANK)) + if (prototype->RequiredSkillRank < value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_MAX_SKILL_RANK)) + if (prototype->RequiredSkillRank > value) + continue; + break; + } + case ITEM_CLASS_MISC: + if (prototype->SubClass == ITEM_SUBCLASS_JUNK_MOUNT) + { + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MIN_REQ_LEVEL)) + if (prototype->RequiredLevel < value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MAX_REQ_LEVEL)) + if (prototype->RequiredLevel > value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MIN_SKILL_RANK)) + if (prototype->RequiredSkillRank < value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_MOUNT_MAX_SKILL_RANK)) + if (prototype->RequiredSkillRank > value) + continue; + } + + if (prototype->Flags & ITEM_FLAG_UNLOCKED) + { + // skip any not locked lootable items (mostly quest specific or reward cases) + if (!prototype->LockID) + continue; + + if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_LOCKBOX_ENABLED)) + continue; + } + + break; + case ITEM_CLASS_GLYPH: + { + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_MIN_REQ_LEVEL)) + if (prototype->RequiredLevel < value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_MAX_REQ_LEVEL)) + if (prototype->RequiredLevel > value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_MIN_ITEM_LEVEL)) + if (prototype->RequiredLevel < value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_MAX_ITEM_LEVEL)) + if (prototype->RequiredLevel > value) + continue; + break; + } + case ITEM_CLASS_TRADE_GOODS: + { + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_MIN_ITEM_LEVEL)) + if (prototype->ItemLevel < value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_MAX_ITEM_LEVEL)) + if (prototype->ItemLevel > value) + continue; + break; + } + case ITEM_CLASS_CONTAINER: + case ITEM_CLASS_QUIVER: + { + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_MIN_ITEM_LEVEL)) + if (prototype->ItemLevel < value) + continue; + if (uint32 value = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_MAX_ITEM_LEVEL)) + if (prototype->ItemLevel > value) + continue; + break; + } + } + + _itemPool[prototype->Quality][prototype->Class].push_back(itemId); + ++itemsAdded; + } + + if (!itemsAdded) + { + TC_LOG_ERROR("ahbot", "AuctionHouseBot seller not have items, disabled."); + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO, 0); + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO, 0); + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO, 0); + return false; + } + + TC_LOG_INFO("ahbot", "AuctionHouseBot seller will use %u items to fill auction house (according your config choices)", itemsAdded); + + LoadConfig(); + + TC_LOG_INFO("ahbot", "Items loaded \tGray\tWhite\tGreen\tBlue\tPurple\tOrange\tYellow"); + for (uint32 i = 0; i < MAX_ITEM_CLASS; ++i) + TC_LOG_INFO("ahbot", "\t\t%u\t%u\t%u\t%u\t%u\t%u\t%u", + (uint32)_itemPool[0][i].size(), (uint32)_itemPool[1][i].size(), (uint32)_itemPool[2][i].size(), + (uint32)_itemPool[3][i].size(), (uint32)_itemPool[4][i].size(), (uint32)_itemPool[5][i].size(), + (uint32)_itemPool[6][i].size()); + + TC_LOG_INFO("ahbot", "AHBot seller configuration data loaded and initialized"); + return true; +} + +void AuctionBotSeller::LoadConfig() +{ + for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i) + if (sAuctionBotConfig->GetConfigItemAmountRatio(AuctionHouseType(i))) + LoadSellerValues(_houseConfig[i]); +} + +void AuctionBotSeller::LoadItemsQuantity(SellerConfiguration& config) +{ + uint32 ratio = sAuctionBotConfig->GetConfigItemAmountRatio(config.GetHouseType()); + + config.SetItemsAmountPerQuality(AUCTION_QUALITY_GRAY, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GRAY_AMOUNT) * ratio / 100); + config.SetItemsAmountPerQuality(AUCTION_QUALITY_WHITE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_WHITE_AMOUNT) * ratio / 100); + config.SetItemsAmountPerQuality(AUCTION_QUALITY_GREEN, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GREEN_AMOUNT) * ratio / 100); + config.SetItemsAmountPerQuality(AUCTION_QUALITY_BLUE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_BLUE_AMOUNT) * ratio / 100); + config.SetItemsAmountPerQuality(AUCTION_QUALITY_PURPLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_PURPLE_AMOUNT) * ratio / 100); + config.SetItemsAmountPerQuality(AUCTION_QUALITY_ORANGE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_ORANGE_AMOUNT) * ratio / 100); + config.SetItemsAmountPerQuality(AUCTION_QUALITY_YELLOW, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_YELLOW_AMOUNT) * ratio / 100); + + // Set quantity wanted but only on possible item color + // This avoid any no-exist class-color items selection by random items create function + // ============================================================================================ + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_CONSUMABLE, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_CONTAINER, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_GEM, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_REAGENT, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_PROJECTILE, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_GENERIC, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_RECIPE, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_QUIVER, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_KEY, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GRAY, ITEM_CLASS_GLYPH, 0); + + config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_CONSUMABLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_CONTAINER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_GEM, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GEM_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_REAGENT, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_REAGENT_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_PROJECTILE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_GENERIC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GENERIC_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_RECIPE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RECIPE_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_QUIVER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUIVER_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_KEY, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_KEY_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_WHITE, ITEM_CLASS_GLYPH, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_AMOUNT)); + + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_CONSUMABLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_CONTAINER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_GEM, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GEM_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_REAGENT, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_PROJECTILE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_GENERIC, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_RECIPE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RECIPE_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_QUIVER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUIVER_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_KEY, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_KEY_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_GREEN, ITEM_CLASS_GLYPH, 0); + + config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_CONSUMABLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_CONTAINER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_GEM, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GEM_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_REAGENT, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_PROJECTILE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_GENERIC, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_RECIPE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RECIPE_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_QUIVER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUIVER_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_KEY, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_BLUE, ITEM_CLASS_GLYPH, 0); + + config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_CONSUMABLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_CONTAINER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_GEM, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GEM_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_REAGENT, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_PROJECTILE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_GENERIC, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_RECIPE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RECIPE_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_QUIVER, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_KEY, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_PURPLE, ITEM_CLASS_GLYPH, 0); + + config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_CONSUMABLE, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_CONTAINER, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_GEM, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_REAGENT, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_PROJECTILE, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_GENERIC, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_RECIPE, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_QUIVER, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_QUEST, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_KEY, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_MISC, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_ORANGE, ITEM_CLASS_GLYPH, 0); + + config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_CONSUMABLE, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_CONTAINER, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_GEM, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT)); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_REAGENT, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_PROJECTILE, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_TRADE_GOODS, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_GENERIC, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_RECIPE, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_QUIVER, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_QUEST, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_KEY, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_MISC, 0); + config.SetItemsQuantityPerClass(AUCTION_QUALITY_YELLOW, ITEM_CLASS_GLYPH, 0); + // ============================================================================================ + + // Set the best value to get nearest amount of items wanted + for (uint32 j = 0; j < MAX_AUCTION_QUALITY; ++j) + { + uint32 index = config.GetItemsAmountPerQuality(AuctionQuality(j)) / + (sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_AMOUNT) + + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GEM_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_REAGENT_AMOUNT) + + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GENERIC_AMOUNT) + + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RECIPE_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUIVER_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_AMOUNT) + + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_KEY_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_AMOUNT) + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_AMOUNT)); + + for (uint32 i = 0; i < MAX_ITEM_CLASS; ++i) + config.SetItemsAmountPerClass(AuctionQuality(j), ItemClass(i), index); + } +} + +void AuctionBotSeller::LoadSellerValues(SellerConfiguration& config) +{ + LoadItemsQuantity(config); + uint32 PriceRatio; + switch (config.GetHouseType()) + { + case AUCTION_HOUSE_ALLIANCE: + PriceRatio = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ALLIANCE_PRICE_RATIO); + break; + case AUCTION_HOUSE_HORDE: + PriceRatio = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_HORDE_PRICE_RATIO); + break; + default: + PriceRatio = sAuctionBotConfig->GetConfig(CONFIG_AHBOT_NEUTRAL_PRICE_RATIO); + break; + } + + config.SetPriceRatioPerQuality(AUCTION_QUALITY_GRAY, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GRAY_PRICE_RATIO) / 100); + config.SetPriceRatioPerQuality(AUCTION_QUALITY_WHITE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_WHITE_PRICE_RATIO) / 100); + config.SetPriceRatioPerQuality(AUCTION_QUALITY_GREEN, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_GREEN_PRICE_RATIO) / 100); + config.SetPriceRatioPerQuality(AUCTION_QUALITY_BLUE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_BLUE_PRICE_RATIO) / 100); + config.SetPriceRatioPerQuality(AUCTION_QUALITY_PURPLE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_PURPLE_PRICE_RATIO) / 100); + config.SetPriceRatioPerQuality(AUCTION_QUALITY_ORANGE, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_ORANGE_PRICE_RATIO) / 100); + config.SetPriceRatioPerQuality(AUCTION_QUALITY_YELLOW, PriceRatio * sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ITEM_YELLOW_PRICE_RATIO) / 100); + + config.SetPriceRatioPerClass(ITEM_CLASS_CONSUMABLE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONSUMABLE_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_CONTAINER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_CONTAINER_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_WEAPON, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_WEAPON_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_GEM, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GEM_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_ARMOR, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_ARMOR_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_REAGENT, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_REAGENT_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_PROJECTILE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PROJECTILE_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_TRADE_GOODS, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_TRADEGOOD_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_GENERIC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GENERIC_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_RECIPE, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_RECIPE_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_MONEY, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MONEY_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_QUIVER, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUIVER_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_QUEST, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_QUEST_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_KEY, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_KEY_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_PERMANENT, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_PERMANENT_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_MISC, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_MISC_PRICE_RATIO)); + config.SetPriceRatioPerClass(ITEM_CLASS_GLYPH, sAuctionBotConfig->GetConfig(CONFIG_AHBOT_CLASS_GLYPH_PRICE_RATIO)); + + //load min and max auction times + config.SetMinTime(sAuctionBotConfig->GetConfig(CONFIG_AHBOT_MINTIME)); + config.SetMaxTime(sAuctionBotConfig->GetConfig(CONFIG_AHBOT_MAXTIME)); + + TC_LOG_INFO("ahbot", "AHBot: minTime = %u", config.GetMinTime()); + TC_LOG_INFO("ahbot", "AHBot: maxTime = %u", config.GetMaxTime()); + + TC_LOG_INFO("ahbot", "AHBot: For AH type %u", config.GetHouseType()); + TC_LOG_INFO("ahbot", "AHBot: GrayItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_GRAY)); + TC_LOG_INFO("ahbot", "AHBot: WhiteItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_WHITE)); + TC_LOG_INFO("ahbot", "AHBot: GreenItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_GREEN)); + TC_LOG_INFO("ahbot", "AHBot: BlueItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_BLUE)); + TC_LOG_INFO("ahbot", "AHBot: PurpleItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_PURPLE)); + TC_LOG_INFO("ahbot", "AHBot: OrangeItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_ORANGE)); + TC_LOG_INFO("ahbot", "AHBot: YellowItems = %u", config.GetItemsAmountPerQuality(AUCTION_QUALITY_YELLOW)); +} + +// Set static of items on one AH faction. +// Fill ItemInfos object with real content of AH. +uint32 AuctionBotSeller::SetStat(SellerConfiguration& config) +{ + AllItemsArray itemsSaved(MAX_AUCTION_QUALITY, std::vector<uint32>(MAX_ITEM_CLASS)); + + AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(config.GetHouseType()); + for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr) + { + AuctionEntry* auctionEntry = itr->second; + Item* item = sAuctionMgr->GetAItem(auctionEntry->itemGUIDLow); + if (item) + { + ItemTemplate const* prototype = item->GetTemplate(); + if (prototype) + if (!auctionEntry->owner) // Add only ahbot items + ++itemsSaved[prototype->Quality][prototype->Class]; + } + } + + uint32 count = 0; + for (uint32 j = 0; j < MAX_AUCTION_QUALITY; ++j) + { + for (uint32 i = 0; i < MAX_ITEM_CLASS; ++i) + { + config.SetMissedItemsPerClass((AuctionQuality)j, (ItemClass)i, itemsSaved[j][i]); + count += config.GetMissedItemsPerClass((AuctionQuality)j, (ItemClass)i); + } + } + + TC_LOG_INFO("ahbot", "AHBot: Missed Item \tGray\tWhite\tGreen\tBlue\tPurple\tOrange\tYellow"); + for (uint32 i = 0; i < MAX_ITEM_CLASS; ++i) + { + TC_LOG_INFO("ahbot", "AHBot: \t\t%u\t%u\t%u\t%u\t%u\t%u\t%u", + config.GetMissedItemsPerClass(AUCTION_QUALITY_GRAY, (ItemClass)i), + config.GetMissedItemsPerClass(AUCTION_QUALITY_WHITE, (ItemClass)i), + config.GetMissedItemsPerClass(AUCTION_QUALITY_GREEN, (ItemClass)i), + config.GetMissedItemsPerClass(AUCTION_QUALITY_BLUE, (ItemClass)i), + config.GetMissedItemsPerClass(AUCTION_QUALITY_PURPLE, (ItemClass)i), + config.GetMissedItemsPerClass(AUCTION_QUALITY_ORANGE, (ItemClass)i), + config.GetMissedItemsPerClass(AUCTION_QUALITY_YELLOW, (ItemClass)i)); + } + config.LastMissedItem = count; + + return count; +} + +// getRandomArray is used to make viable the possibility to add any of missed item in place of first one to last one. +bool AuctionBotSeller::GetItemsToSell(SellerConfiguration& config, ItemsToSellArray& itemsToSellArray, AllItemsArray const& addedItem) +{ + itemsToSellArray.clear(); + bool found = false; + + for (uint32 j = 0; j < MAX_AUCTION_QUALITY; ++j) + { + for (uint32 i = 0; i < MAX_ITEM_CLASS; ++i) + { + if (config.GetMissedItemsPerClass(AuctionQuality(j), ItemClass(i)) > addedItem[j][i] && !_itemPool[j][i].empty()) + { + ItemToSell miss_item; + miss_item.Color = j; + miss_item.Itemclass = i; + itemsToSellArray.push_back(miss_item); + found = true; + } + } + } + + return found; +} + +// Set items price. All important value are passed by address. +void AuctionBotSeller::SetPricesOfItem(ItemTemplate const* itemProto, SellerConfiguration& config, uint32& buyp, uint32& bidp, uint32 stackCount) +{ + uint32 classRatio = config.GetPriceRatioPerClass(ItemClass(itemProto->Class)); + uint32 qualityRatio = config.GetPriceRatioPerQuality(AuctionQuality(itemProto->Quality)); + uint32 priceRatio = (classRatio * qualityRatio) / 100; + + uint32 buyPrice = itemProto->BuyPrice; + uint32 sellPrice = itemProto->SellPrice; + + if (buyPrice == 0) + { + if (sellPrice > 0) + buyPrice = sellPrice * GetSellModifier(itemProto); + else + { + uint32 divisor = ((itemProto->Class == 2 || itemProto->Class == 4) ? 284 : 80); + uint32 tempLevel = (itemProto->ItemLevel == 0 ? 1 : itemProto->ItemLevel); + uint32 tempQuality = (itemProto->Quality == 0 ? 1 : itemProto->Quality); + + buyPrice = tempLevel * tempQuality * GetBuyModifier(itemProto)* tempLevel / divisor; + } + } + + if (sellPrice == 0) + sellPrice = (buyPrice > 10 ? buyPrice / GetSellModifier(itemProto) : buyPrice); + + if (!sAuctionBotConfig->GetConfig(CONFIG_AHBOT_BUYPRICE_SELLER)) + buyPrice = sellPrice; + + uint32 basePrice = (buyPrice * stackCount * priceRatio) / (itemProto->Class == 6 ? 200 : itemProto->BuyCount) / 100; + uint32 range = basePrice * 0.04; + + buyp = urand(basePrice - range, basePrice + range) + 1; + + basePrice = buyp * .5; + range = buyp * .4; + bidp = urand(basePrice - range, basePrice + range) + 1; +} + +// Determine the multiplier for the sell price of any weapon without a buy price. +uint32 AuctionBotSeller::GetSellModifier(ItemTemplate const* prototype) +{ + switch (prototype->Class) + { + case ITEM_CLASS_WEAPON: + case ITEM_CLASS_ARMOR: + case ITEM_CLASS_REAGENT: + case ITEM_CLASS_PROJECTILE: + return 5; + default: + return 4; + } +} + +// Return the modifier by which the item's level and quality will be modified by to derive a relatively accurate price. +uint32 AuctionBotSeller::GetBuyModifier(ItemTemplate const* prototype) +{ + switch (prototype->Class) + { + case ITEM_CLASS_CONSUMABLE: + { + switch (prototype->SubClass) + { + case ITEM_SUBCLASS_CONSUMABLE: + return 100; + case ITEM_SUBCLASS_FLASK: + return 400; + case ITEM_SUBCLASS_SCROLL: + return 15; + case ITEM_SUBCLASS_ITEM_ENHANCEMENT: + return 250; + case ITEM_SUBCLASS_BANDAGE: + return 125; + default: + return 300; + } + } + case ITEM_CLASS_WEAPON: + { + switch (prototype->SubClass) + { + case ITEM_SUBCLASS_WEAPON_AXE: + case ITEM_SUBCLASS_WEAPON_MACE: + case ITEM_SUBCLASS_WEAPON_SWORD: + case ITEM_SUBCLASS_WEAPON_FIST: + case ITEM_SUBCLASS_WEAPON_DAGGER: + return 1200; + case ITEM_SUBCLASS_WEAPON_AXE2: + case ITEM_SUBCLASS_WEAPON_MACE2: + case ITEM_SUBCLASS_WEAPON_POLEARM: + case ITEM_SUBCLASS_WEAPON_SWORD2: + case ITEM_SUBCLASS_WEAPON_STAFF: + return 1500; + case ITEM_SUBCLASS_WEAPON_THROWN: + return 350; + default: + return 1000; + } + } + case ITEM_CLASS_ARMOR: + { + switch (prototype->SubClass) + { + case ITEM_SUBCLASS_ARMOR_MISC: + case ITEM_SUBCLASS_ARMOR_CLOTH: + return 500; + case ITEM_SUBCLASS_ARMOR_LEATHER: + return 600; + case ITEM_SUBCLASS_ARMOR_MAIL: + return 700; + case ITEM_SUBCLASS_ARMOR_PLATE: + case ITEM_SUBCLASS_ARMOR_SHIELD: + return 800; + default: + return 400; + } + } + case ITEM_CLASS_REAGENT: + case ITEM_CLASS_PROJECTILE: + return 50; + case ITEM_CLASS_TRADE_GOODS: + { + switch (prototype->SubClass) + { + case ITEM_SUBCLASS_TRADE_GOODS: + case ITEM_SUBCLASS_PARTS: + case ITEM_SUBCLASS_MEAT: + return 50; + case ITEM_SUBCLASS_EXPLOSIVES: + return 250; + case ITEM_SUBCLASS_DEVICES: + return 500; + case ITEM_SUBCLASS_ELEMENTAL: + case ITEM_SUBCLASS_TRADE_GOODS_OTHER: + case ITEM_SUBCLASS_ENCHANTING: + return 300; + default: + return 100; + } + } + case ITEM_CLASS_QUEST: return 1000; + case ITEM_CLASS_KEY: return 3000; + default: + return 500; + } +} + +void AuctionBotSeller::SetItemsRatio(uint32 al, uint32 ho, uint32 ne) +{ + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO, std::max(al, 100000u)); + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO, std::max(ho, 100000u)); + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO, std::max(ne, 100000u)); + + for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i) + LoadItemsQuantity(_houseConfig[i]); +} + +void AuctionBotSeller::SetItemsRatioForHouse(AuctionHouseType house, uint32 val) +{ + val = std::max(val, 10000u); // apply same upper limit as used for config load + + switch (house) + { + case AUCTION_HOUSE_ALLIANCE: sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO, val); break; + case AUCTION_HOUSE_HORDE: sAuctionBotConfig->SetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO, val); break; + default: sAuctionBotConfig->SetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO, val); break; + } + + LoadItemsQuantity(_houseConfig[house]); +} + +void AuctionBotSeller::SetItemsAmount(uint32(&vals)[MAX_AUCTION_QUALITY]) +{ + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_GRAY_AMOUNT, vals[AUCTION_QUALITY_GRAY]); + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_WHITE_AMOUNT, vals[AUCTION_QUALITY_WHITE]); + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_GREEN_AMOUNT, vals[AUCTION_QUALITY_GREEN]); + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_BLUE_AMOUNT, vals[AUCTION_QUALITY_BLUE]); + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_PURPLE_AMOUNT, vals[AUCTION_QUALITY_PURPLE]); + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_ORANGE_AMOUNT, vals[AUCTION_QUALITY_ORANGE]); + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_YELLOW_AMOUNT, vals[AUCTION_QUALITY_YELLOW]); + + for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i) + LoadItemsQuantity(_houseConfig[i]); +} + +void AuctionBotSeller::SetItemsAmountForQuality(AuctionQuality quality, uint32 val) +{ + switch (quality) + { + case AUCTION_QUALITY_GRAY: + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_GRAY_AMOUNT, val); break; + case AUCTION_QUALITY_WHITE: + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_WHITE_AMOUNT, val); break; + case AUCTION_QUALITY_GREEN: + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_GREEN_AMOUNT, val); break; + case AUCTION_QUALITY_BLUE: + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_BLUE_AMOUNT, val); break; + case AUCTION_QUALITY_PURPLE: + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_PURPLE_AMOUNT, val); break; + case AUCTION_QUALITY_ORANGE: + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_ORANGE_AMOUNT, val); break; + default: + sAuctionBotConfig->SetConfig(CONFIG_AHBOT_ITEM_YELLOW_AMOUNT, val); break; + } + + for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i) + LoadItemsQuantity(_houseConfig[i]); +} + +// Add new auction to one of the factions. +// Faction and setting associated is defined passed argument ( config ) +void AuctionBotSeller::AddNewAuctions(SellerConfiguration& config) +{ + uint32 count = 0; + uint32 items = 0; + + // If there is large amount of items missed we can use boost value to get fast filled AH + if (config.LastMissedItem > sAuctionBotConfig->GetItemPerCycleBoost()) + { + items = sAuctionBotConfig->GetItemPerCycleBoost(); + TC_LOG_INFO("ahbot", "AHBot: Boost value used to fill AH! (if this happens often adjust both ItemsPerCycle in worldserver.conf)"); + } + else + items = sAuctionBotConfig->GetItemPerCycleNormal(); + + uint32 houseid; + uint32 auctioneer; + switch (config.GetHouseType()) + { + case AUCTION_HOUSE_ALLIANCE: + houseid = 1; auctioneer = 79707; break; + case AUCTION_HOUSE_HORDE: + houseid = 6; auctioneer = 4656; break; + default: + houseid = 7; auctioneer = 23442; break; + } + + AuctionHouseEntry const* ahEntry = sAuctionHouseStore.LookupEntry(houseid); + + AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(config.GetHouseType()); + + ItemsToSellArray itemsToSell; + AllItemsArray allItems(MAX_AUCTION_QUALITY, std::vector<uint32>(MAX_ITEM_CLASS)); + // Main loop + // getRandomArray will give what categories of items should be added (return true if there is at least 1 items missed) + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + while (GetItemsToSell(config, itemsToSell, allItems) && items > 0) + { + --items; + + // Select random position from missed items table + uint32 pos = urand(0, itemsToSell.size() - 1); + + // Set itemId with random item ID for selected categories and color, from _itemPool table + uint32 itemId = _itemPool[itemsToSell[pos].Color][itemsToSell[pos].Itemclass][urand(0, _itemPool[itemsToSell[pos].Color][itemsToSell[pos].Itemclass].size() - 1)]; + ++allItems[itemsToSell[pos].Color][itemsToSell[pos].Itemclass]; // Helper table to avoid rescan from DB in this loop. (has we add item in random orders) + + if (!itemId) + { + TC_LOG_INFO("ahbot", "AHBot: Item entry 0 auction creating attempt."); + continue; + } + + ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(itemId); + if (!prototype) + { + TC_LOG_INFO("ahbot", "AHBot: Unknown item %u auction creating attempt.", itemId); + continue; + } + + uint32 stackCount = urand(1, prototype->GetMaxStackSize()); + + Item* item = Item::CreateItem(itemId, stackCount); + if (!item) + { + TC_LOG_ERROR("ahbot", "AHBot: Item::CreateItem() returned NULL for item %u (stack: %u)", itemId, stackCount); + return; + } + + // Update the just created item so that if it needs random properties it has them. + // Ex: Notched Shortsword of Stamina will only generate as a Notched Shortsword without this. + if (int32 randomPropertyId = Item::GenerateItemRandomPropertyId(itemId)) + item->SetItemRandomProperties(randomPropertyId); + + uint32 buyoutPrice; + uint32 bidPrice = 0; + + // Price of items are set here + SetPricesOfItem(prototype, config, buyoutPrice, bidPrice, stackCount); + + // Deposit time + uint32 etime = urand(1, 3); + switch (etime) + { + case 1: + etime = 43200; + break; + case 2: + etime = 86400; + break; + case 3: + etime = 172800; + break; + default: + etime = 86400; + break; + } + + AuctionEntry* auctionEntry = new AuctionEntry(); + auctionEntry->Id = sObjectMgr->GenerateAuctionID(); + auctionEntry->owner = 0; + auctionEntry->itemGUIDLow = item->GetGUIDLow(); + auctionEntry->itemEntry = item->GetEntry(); + auctionEntry->startbid = bidPrice; + auctionEntry->buyout = buyoutPrice; + auctionEntry->auctioneer = auctioneer; + auctionEntry->bidder = 0; + auctionEntry->bid = 0; + auctionEntry->deposit = sAuctionMgr->GetAuctionDeposit(ahEntry, etime, item, stackCount); + auctionEntry->auctionHouseEntry = ahEntry; + auctionEntry->expire_time = time(NULL) + urand(config.GetMinTime(), config.GetMaxTime()) * HOUR; + + item->SaveToDB(trans); + sAuctionMgr->AddAItem(item); + auctionHouse->AddAuction(auctionEntry); + auctionEntry->SaveToDB(trans); + + auctionHouse->AddAuction(auctionEntry); + + ++count; + } + CharacterDatabase.CommitTransaction(trans); + + TC_LOG_INFO("ahbot", "AHBot: Added %u items to auction", count); +} + +bool AuctionBotSeller::Update(AuctionHouseType houseType) +{ + if (sAuctionBotConfig->GetConfigItemAmountRatio(houseType) > 0) + { + TC_LOG_INFO("ahbot", "AHBot: %s selling ...", AuctionBotConfig::GetHouseTypeName(houseType)); + if (SetStat(_houseConfig[houseType])) + AddNewAuctions(_houseConfig[houseType]); + return true; + } + else + return false; +} diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h new file mode 100644 index 00000000000..a1820196dc8 --- /dev/null +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef AUCTION_HOUSE_BOT_SELLER_H +#define AUCTION_HOUSE_BOT_SELLER_H + +#include "Define.h" +#include "ItemPrototype.h" +#include "AuctionHouseBot.h" + +struct ItemToSell +{ + uint32 Color; + uint32 Itemclass; +}; + +typedef std::vector<ItemToSell> ItemsToSellArray; +typedef std::vector<std::vector<uint32>> AllItemsArray; + +struct SellerItemClassInfo +{ + SellerItemClassInfo(): AmountOfItems(0), MissItems(0), Quantity(0), PriceRatio(0) {} + + uint32 AmountOfItems; + uint32 MissItems; + uint32 Quantity; + uint32 PriceRatio; +}; + +struct SellerItemInfo +{ + SellerItemInfo(): AmountOfItems(0), MissItems(0), PriceRatio(0) {} + + uint32 AmountOfItems; + uint32 MissItems; + uint32 PriceRatio; + + SellerItemClassInfo ItemClassInfos[MAX_ITEM_CLASS]; +}; + +class SellerConfiguration +{ +public: + SellerConfiguration(): _houseType(AUCTION_HOUSE_NEUTRAL) + { + } + + ~SellerConfiguration() {} + + void Initialize(AuctionHouseType houseType) + { + _houseType = houseType; + } + + AuctionHouseType GetHouseType() const { return _houseType; } + + uint32 LastMissedItem; + + void SetMinTime(uint32 value) + { + _minTime = value; + } + uint32 GetMinTime() const + { + return std::min(1u, std::min(_minTime, _maxTime)); + } + + void SetMaxTime(uint32 value) { _maxTime = value; } + uint32 GetMaxTime() const { return _maxTime; } + // Data access classified by item class and item quality + void SetItemsAmountPerClass(AuctionQuality quality, ItemClass itemclass, uint32 amount) { _ItemInfo[quality].ItemClassInfos[itemclass].AmountOfItems = amount * _ItemInfo[quality].ItemClassInfos[itemclass].Quantity; } + uint32 GetItemsAmountPerClass(AuctionQuality quality, ItemClass itemclass) const { return _ItemInfo[quality].ItemClassInfos[itemclass].AmountOfItems; } + void SetItemsQuantityPerClass(AuctionQuality quality, ItemClass itemclass, uint32 qty) { _ItemInfo[quality].ItemClassInfos[itemclass].Quantity = qty; } + uint32 GetItemsQuantityPerClass(AuctionQuality quality, ItemClass itemclass) const { return _ItemInfo[quality].ItemClassInfos[itemclass].Quantity; } + void SetMissedItemsPerClass(AuctionQuality quality, ItemClass itemclass, uint32 found) + { + if (_ItemInfo[quality].ItemClassInfos[itemclass].AmountOfItems > found) + _ItemInfo[quality].ItemClassInfos[itemclass].MissItems = _ItemInfo[quality].ItemClassInfos[itemclass].AmountOfItems - found; + else + _ItemInfo[quality].ItemClassInfos[itemclass].MissItems = 0; + } + uint32 GetMissedItemsPerClass(AuctionQuality quality, ItemClass itemclass) const { return _ItemInfo[quality].ItemClassInfos[itemclass].MissItems; } + + // Data for every quality of item + void SetItemsAmountPerQuality(AuctionQuality quality, uint32 cnt) { _ItemInfo[quality].AmountOfItems = cnt; } + uint32 GetItemsAmountPerQuality(AuctionQuality quality) const { return _ItemInfo[quality].AmountOfItems; } + void SetPriceRatioPerQuality(AuctionQuality quality, uint32 value) { _ItemInfo[quality].PriceRatio = value; } + uint32 GetPriceRatioPerQuality(AuctionQuality quality) const { return _ItemInfo[quality].PriceRatio; } + void SetPriceRatioPerClass(ItemClass item, uint32 value) { _ItemInfo[0].ItemClassInfos[item].PriceRatio = value; } + uint32 GetPriceRatioPerClass(ItemClass item) const { return _ItemInfo[0].ItemClassInfos[item].PriceRatio; } + +private: + AuctionHouseType _houseType; + uint32 _minTime; + uint32 _maxTime; + SellerItemInfo _ItemInfo[MAX_AUCTION_QUALITY]; +}; + +// This class handle all Selling method +// (holder of AHB_Seller_Config data for each auction house type) +class AuctionBotSeller : public AuctionBotAgent +{ +public: + typedef std::vector<uint32> ItemPool; + + AuctionBotSeller(); + ~AuctionBotSeller() override; + + bool Initialize() override; + bool Update(AuctionHouseType houseType) override; + + void AddNewAuctions(SellerConfiguration& config); + void SetItemsRatio(uint32 al, uint32 ho, uint32 ne); + void SetItemsRatioForHouse(AuctionHouseType house, uint32 val); + void SetItemsAmount(uint32(&vals)[MAX_AUCTION_QUALITY]); + void SetItemsAmountForQuality(AuctionQuality quality, uint32 val); + void LoadConfig(); + +private: + SellerConfiguration _houseConfig[MAX_AUCTION_HOUSE_TYPE]; + + ItemPool _itemPool[MAX_AUCTION_QUALITY][MAX_ITEM_CLASS]; + + void LoadSellerValues(SellerConfiguration& config); + uint32 SetStat(SellerConfiguration& config); + bool GetItemsToSell(SellerConfiguration& config, ItemsToSellArray& itemsToSellArray, AllItemsArray const& addedItem); + void SetPricesOfItem(ItemTemplate const* itemProto, SellerConfiguration& config, uint32& buyp, uint32& bidp, uint32 stackcnt); + void LoadItemsQuantity(SellerConfiguration& config); + static uint32 GetBuyModifier(ItemTemplate const* prototype); + static uint32 GetSellModifier(ItemTemplate const* itemProto); +}; + +#endif diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt index 532900c0438..d7d14e7bda4 100644 --- a/src/server/game/CMakeLists.txt +++ b/src/server/game/CMakeLists.txt @@ -13,6 +13,7 @@ file(GLOB_RECURSE sources_Achievements Achievements/*.cpp Achievements/*.h) file(GLOB_RECURSE sources_Addons Addons/*.cpp Addons/*.h) file(GLOB_RECURSE sources_AI AI/*.cpp AI/*.h) file(GLOB_RECURSE sources_AuctionHouse AuctionHouse/*.cpp AuctionHouse/*.h) +file(GLOB_RECURSE sources_AuctionHouseBot AuctionHouseBot/*.cpp AuctionHouseBot/*.h) file(GLOB_RECURSE sources_Battlefield Battlefield/*.cpp Battlefield/*.h) file(GLOB_RECURSE sources_Battlegrounds Battlegrounds/*.cpp Battlegrounds/*.h) file(GLOB_RECURSE sources_Calendar Calendar/*.cpp Calendar/*.h) @@ -63,6 +64,7 @@ set(game_STAT_SRCS ${sources_Addons} ${sources_AI} ${sources_AuctionHouse} + ${sources_AuctionHouseBot} ${sources_Battlefield} ${sources_Battlegrounds} ${sources_Calendar} @@ -136,6 +138,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/AI/ScriptedAI ${CMAKE_CURRENT_SOURCE_DIR}/AI/SmartScripts ${CMAKE_CURRENT_SOURCE_DIR}/AuctionHouse + ${CMAKE_CURRENT_SOURCE_DIR}/AuctionHouseBot ${CMAKE_CURRENT_SOURCE_DIR}/Battlefield ${CMAKE_CURRENT_SOURCE_DIR}/Battlefield/Zones ${CMAKE_CURRENT_SOURCE_DIR}/Battlegrounds diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 6894dd86493..5a4ef765a6e 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -690,8 +690,11 @@ void Item::SetState(ItemUpdateState state, Player* forplayer) if (uState == ITEM_NEW && state == ITEM_REMOVED) { // pretend the item never existed - RemoveFromUpdateQueueOf(forplayer); - forplayer->DeleteRefundReference(GetGUIDLow()); + if (forplayer) + { + RemoveFromUpdateQueueOf(forplayer); + forplayer->DeleteRefundReference(GetGUIDLow()); + } delete this; return; } @@ -701,7 +704,8 @@ void Item::SetState(ItemUpdateState state, Player* forplayer) if (uState != ITEM_NEW) uState = state; - AddToUpdateQueueOf(forplayer); + if (forplayer) + AddToUpdateQueueOf(forplayer); } else { diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index f4d1bc03144..06c4a43a802 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -941,7 +941,27 @@ enum TrinityStrings LANG_LIST_MAIL_INFO_3 = 1154, LANG_LIST_MAIL_INFO_ITEM = 1155, LANG_LIST_MAIL_NOT_FOUND = 1156, - // Room for more level 3 1157-1199 not used + LANG_AHBOT_RELOAD_OK = 1157, + LANG_AHBOT_STATUS_BAR_CONSOLE = 1158, + LANG_AHBOT_STATUS_MIDBAR_CONSOLE = 1159, + LANG_AHBOT_STATUS_TITLE1_CONSOLE = 1160, + LANG_AHBOT_STATUS_TITLE1_CHAT = 1161, + LANG_AHBOT_STATUS_FORMAT_CONSOLE = 1162, + LANG_AHBOT_STATUS_FORMAT_CHAT = 1163, + LANG_AHBOT_STATUS_ITEM_COUNT = 1164, + LANG_AHBOT_STATUS_ITEM_RATIO = 1165, + LANG_AHBOT_STATUS_TITLE2_CONSOLE = 1166, + LANG_AHBOT_STATUS_TITLE2_CHAT = 1167, + LANG_AHBOT_QUALITY_GRAY = 1168, + LANG_AHBOT_QUALITY_WHITE = 1169, + LANG_AHBOT_QUALITY_GREEN = 1170, + LANG_AHBOT_QUALITY_BLUE = 1171, + LANG_AHBOT_QUALITY_PURPLE = 1172, + LANG_AHBOT_QUALITY_ORANGE = 1173, + LANG_AHBOT_QUALITY_YELLOW = 1174, + LANG_AHBOT_ITEMS_AMOUNT = 1175, + LANG_AHBOT_ITEMS_RATIO = 1176, + // Room for more level 3 1177-1199 not used // Debug commands LANG_CINEMATIC_NOT_EXIST = 1200, diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index d036d438926..ed6c5430674 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -47,6 +47,7 @@ void AddSC_SmartScripts(); //Commands void AddSC_account_commandscript(); void AddSC_achievement_commandscript(); +void AddSC_ahbot_commandscript(); void AddSC_arena_commandscript(); void AddSC_ban_commandscript(); void AddSC_bf_commandscript(); @@ -749,6 +750,7 @@ void AddCommandScripts() { AddSC_account_commandscript(); AddSC_achievement_commandscript(); + AddSC_ahbot_commandscript(); AddSC_arena_commandscript(); AddSC_ban_commandscript(); AddSC_bf_commandscript(); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 184637b0a1d..f9c8c800ca5 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -23,6 +23,7 @@ #include "World.h" #include "AchievementMgr.h" #include "ArenaTeamMgr.h" +#include "AuctionHouseBot.h" #include "AuctionHouseMgr.h" #include "BattlefieldMgr.h" #include "BattlegroundMgr.h" @@ -1255,6 +1256,9 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_IP_BASED_ACTION_LOGGING] = sConfigMgr->GetBoolDefault("Allow.IP.Based.Action.Logging", false); + // AHBot + m_int_configs[CONFIG_AHBOT_UPDATE_INTERVAL] = sConfigMgr->GetIntDefault("AuctionHouseBot.Update.Interval", 20); + // call ScriptMgr if we're reloading the configuration if (reload) sScriptMgr->OnConfigLoad(reload); @@ -1740,6 +1744,9 @@ void World::SetInitialWorldSettings() m_timers[WUPDATE_AUTOBROADCAST].SetInterval(getIntConfig(CONFIG_AUTOBROADCAST_INTERVAL)); m_timers[WUPDATE_DELETECHARS].SetInterval(DAY*IN_MILLISECONDS); // check for chars to delete every day + // for AhBot + m_timers[WUPDATE_AHBOT].SetInterval(getIntConfig(CONFIG_AHBOT_UPDATE_INTERVAL) * IN_MILLISECONDS); // every 20 sec + m_timers[WUPDATE_PINGDB].SetInterval(getIntConfig(CONFIG_DB_PING_INTERVAL)*MINUTE*IN_MILLISECONDS); // Mysql ping time in minutes //to set mailtimer to return mails every day between 4 and 5 am @@ -1767,6 +1774,9 @@ void World::SetInitialWorldSettings() // Delete all characters which have been deleted X days before Player::DeleteOldCharacters(); + TC_LOG_INFO("server.loading", "Initialize AuctionHouseBot..."); + sAuctionBot->Initialize(); + // Delete all custom channels which haven't been used for PreserveCustomChannelDuration days. Channel::CleanOldChannelsInDB(); @@ -1999,6 +2009,13 @@ void World::Update(uint32 diff) sAuctionMgr->Update(); } + /// <li> Handle AHBot operations + if (m_timers[WUPDATE_AHBOT].Passed()) + { + sAuctionBot->Update(); + m_timers[WUPDATE_AHBOT].Reset(); + } + /// <li> Handle session updates when the timer has passed RecordTimeDiff(NULL); UpdateSessions(diff); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index fd31099a5ea..b77f8777bdc 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -76,6 +76,7 @@ enum WorldTimers WUPDATE_AUTOBROADCAST, WUPDATE_MAILBOXQUEUE, WUPDATE_DELETECHARS, + WUPDATE_AHBOT, WUPDATE_PINGDB, WUPDATE_COUNT }; @@ -333,6 +334,7 @@ enum WorldIntConfigs CONFIG_BG_REWARD_LOSER_HONOR_LAST, CONFIG_BIRTHDAY_TIME, CONFIG_CREATURE_PICKPOCKET_REFILL, + CONFIG_AHBOT_UPDATE_INTERVAL, INT_CONFIG_VALUE_COUNT }; diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt index ba2709f0a23..f193cf4aa6a 100644 --- a/src/server/scripts/CMakeLists.txt +++ b/src/server/scripts/CMakeLists.txt @@ -78,6 +78,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/game/AI/ScriptedAI ${CMAKE_SOURCE_DIR}/src/server/game/AI/SmartScripts ${CMAKE_SOURCE_DIR}/src/server/game/AuctionHouse + ${CMAKE_SOURCE_DIR}/src/server/game/AuctionHouseBot ${CMAKE_SOURCE_DIR}/src/server/game/Battlefield ${CMAKE_SOURCE_DIR}/src/server/game/Battlefield/Zones ${CMAKE_SOURCE_DIR}/src/server/game/Battlegrounds diff --git a/src/server/scripts/Commands/cs_ahbot.cpp b/src/server/scripts/Commands/cs_ahbot.cpp new file mode 100644 index 00000000000..04647d51ff0 --- /dev/null +++ b/src/server/scripts/Commands/cs_ahbot.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ScriptMgr.h" +#include "Chat.h" +#include "Language.h" +#include "AuctionHouseBot.h" + +static const uint32 ahbotQualityIds[MAX_AUCTION_QUALITY] = +{ + LANG_AHBOT_QUALITY_GRAY, LANG_AHBOT_QUALITY_WHITE, + LANG_AHBOT_QUALITY_GREEN, LANG_AHBOT_QUALITY_BLUE, + LANG_AHBOT_QUALITY_PURPLE, LANG_AHBOT_QUALITY_ORANGE, + LANG_AHBOT_QUALITY_YELLOW +}; + +class ahbot_commandscript : public CommandScript +{ +public: + ahbot_commandscript(): CommandScript("ahbot_commandscript") {} + + ChatCommand* GetCommands() const + { + static ChatCommand ahbotItemsAmountCommandTable[] = + { + { "gray", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_GRAY, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_GRAY>, "", NULL }, + { "white", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_WHITE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_WHITE>, "", NULL }, + { "green", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_GREEN, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_GREEN>, "", NULL }, + { "blue", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_BLUE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_BLUE>, "", NULL }, + { "purple", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_PURPLE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_PURPLE>, "", NULL }, + { "orange", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_ORANGE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_ORANGE>, "", NULL }, + { "yellow", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_YELLOW, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_YELLOW>, "", NULL }, + { "", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS, true, &HandleAHBotItemsAmountCommand, "", NULL }, + { NULL, 0, true, NULL, "", NULL } + }; + + static ChatCommand ahbotItemsRatioCommandTable[] = + { + { "alliance", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO_ALLIANCE, true, &HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_ALLIANCE>, "", NULL }, + { "horde", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO_HORDE, true, &HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_HORDE>, "", NULL }, + { "neutral", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO_NEUTRAL, true, &HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_NEUTRAL>, "", NULL }, + { "", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO, true, &HandleAHBotItemsRatioCommand, "", NULL }, + { NULL, 0, true, NULL, "", NULL } + }; + + static ChatCommand ahbotCommandTable[] = + { + { "items", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS, true, NULL, "", ahbotItemsAmountCommandTable }, + { "ratio", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO, true, NULL, "", ahbotItemsRatioCommandTable }, + { "rebuild", rbac::RBAC_PERM_COMMAND_AHBOT_REBUILD, true, &HandleAHBotRebuildCommand, "", NULL }, + { "reload", rbac::RBAC_PERM_COMMAND_AHBOT_RELOAD, true, &HandleAHBotReloadCommand, "", NULL }, + { "status", rbac::RBAC_PERM_COMMAND_AHBOT_STATUS, true, &HandleAHBotStatusCommand, "", NULL }, + { NULL, 0, true, NULL, "", NULL } + }; + + static ChatCommand commandTable[] = + { + { "ahbot", rbac::RBAC_PERM_COMMAND_AHBOT, false, NULL, "", ahbotCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + + return commandTable; + } + + static bool HandleAHBotItemsAmountCommand(ChatHandler* handler, const char* args) + { + uint32 qVals[MAX_AUCTION_QUALITY]; + char* arg = strtok((char*)args, " "); + for (int i = 0; i < MAX_AUCTION_QUALITY; ++i) + { + if (!arg) + return false; + qVals[i] = atoi(arg); + arg = strtok(NULL, " "); + } + + sAuctionBot->SetItemsAmount(qVals); + + for (int i = 0; i < MAX_AUCTION_QUALITY; ++i) + handler->PSendSysMessage(LANG_AHBOT_ITEMS_AMOUNT, handler->GetTrinityString(ahbotQualityIds[i]), sAuctionBotConfig->GetConfigItemQualityAmount(AuctionQuality(i))); + + return true; + } + + template <AuctionQuality Q> + static bool HandleAHBotItemsAmountQualityCommand(ChatHandler* handler, const char* args) + { + char* arg = strtok((char*)args, " "); + if (!arg) + return false; + uint32 qualityVal = atoi(arg); + + sAuctionBot->SetItemsAmountForQuality(Q, qualityVal); + handler->PSendSysMessage(LANG_AHBOT_ITEMS_AMOUNT, handler->GetTrinityString(ahbotQualityIds[Q]), + sAuctionBotConfig->GetConfigItemQualityAmount(Q)); + + return true; + } + + static bool HandleAHBotItemsRatioCommand(ChatHandler* handler, const char* args) + { + uint32 rVal[MAX_AUCTION_QUALITY]; + char* arg = strtok((char*)args, " "); + for (int i = 0; i < MAX_AUCTION_QUALITY; ++i) + { + if (!arg) + return false; + rVal[i] = atoi(arg); + arg = strtok(NULL, " "); + } + + sAuctionBot->SetItemsRatio(rVal[0], rVal[1], rVal[2]); + + for (int i = 0; i < MAX_AUCTION_HOUSE_TYPE; ++i) + handler->PSendSysMessage(LANG_AHBOT_ITEMS_RATIO, AuctionBotConfig::GetHouseTypeName(AuctionHouseType(i)), sAuctionBotConfig->GetConfigItemAmountRatio(AuctionHouseType(i))); + return true; + } + + template<AuctionHouseType H> + static bool HandleAHBotItemsRatioHouseCommand(ChatHandler* handler, const char* args) + { + char* arg = strtok((char*)args, " "); + if (!arg) + return false; + uint32 ratioVal = atoi(arg); + + sAuctionBot->SetItemsRatioForHouse(H, ratioVal); + handler->PSendSysMessage(LANG_AHBOT_ITEMS_RATIO, AuctionBotConfig::GetHouseTypeName(H), sAuctionBotConfig->GetConfigItemAmountRatio(H)); + return true; + } + + static bool HandleAHBotRebuildCommand(ChatHandler* /*handler*/, const char* args) + { + char* arg = strtok((char*)args, " "); + if (!arg) + return false; + + bool all = false; + if (strcmp(arg, "all") == 0) + all = true; + + sAuctionBot->Rebuild(all); + return true; + } + + static bool HandleAHBotReloadCommand(ChatHandler* handler, const char* /*args*/) + { + sAuctionBot->ReloadAllConfig(); + handler->SendSysMessage(LANG_AHBOT_RELOAD_OK); + return true; + } + + static bool HandleAHBotStatusCommand(ChatHandler* handler, const char* args) + { + char* arg = strtok((char*)args, " "); + if (!arg) + return false; + + bool all = false; + if (strcmp(arg, "all") == 0) + all = true; + + AuctionHouseBotStatusInfo statusInfo; + sAuctionBot->PrepareStatusInfos(statusInfo); + + WorldSession* session = handler->GetSession(); + + if (!session) + { + handler->SendSysMessage(LANG_AHBOT_STATUS_BAR_CONSOLE); + handler->SendSysMessage(LANG_AHBOT_STATUS_TITLE1_CONSOLE); + handler->SendSysMessage(LANG_AHBOT_STATUS_MIDBAR_CONSOLE); + } + else + handler->SendSysMessage(LANG_AHBOT_STATUS_TITLE1_CHAT); + + uint32 fmtId = session ? LANG_AHBOT_STATUS_FORMAT_CHAT : LANG_AHBOT_STATUS_FORMAT_CONSOLE; + + handler->PSendSysMessage(fmtId, handler->GetTrinityString(LANG_AHBOT_STATUS_ITEM_COUNT), + statusInfo[AUCTION_HOUSE_ALLIANCE].ItemsCount, + statusInfo[AUCTION_HOUSE_HORDE].ItemsCount, + statusInfo[AUCTION_HOUSE_NEUTRAL].ItemsCount, + statusInfo[AUCTION_HOUSE_ALLIANCE].ItemsCount + + statusInfo[AUCTION_HOUSE_HORDE].ItemsCount + + statusInfo[AUCTION_HOUSE_NEUTRAL].ItemsCount); + + if (all) + { + handler->PSendSysMessage(fmtId, handler->GetTrinityString(LANG_AHBOT_STATUS_ITEM_RATIO), + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO), + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO), + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO), + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO) + + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO) + + sAuctionBotConfig->GetConfig(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO)); + + if (!session) + { + handler->SendSysMessage(LANG_AHBOT_STATUS_BAR_CONSOLE); + handler->SendSysMessage(LANG_AHBOT_STATUS_TITLE2_CONSOLE); + handler->SendSysMessage(LANG_AHBOT_STATUS_MIDBAR_CONSOLE); + } + else + handler->SendSysMessage(LANG_AHBOT_STATUS_TITLE2_CHAT); + + for (int i = 0; i < MAX_AUCTION_QUALITY; ++i) + handler->PSendSysMessage(fmtId, handler->GetTrinityString(ahbotQualityIds[i]), + statusInfo[AUCTION_HOUSE_ALLIANCE].QualityInfo[i], + statusInfo[AUCTION_HOUSE_HORDE].QualityInfo[i], + statusInfo[AUCTION_HOUSE_NEUTRAL].QualityInfo[i], + sAuctionBotConfig->GetConfigItemQualityAmount(AuctionQuality(i))); + } + + if (!session) + handler->SendSysMessage(LANG_AHBOT_STATUS_BAR_CONSOLE); + + return true; + } + +}; + +template bool ahbot_commandscript::HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_GRAY>(ChatHandler* handler, const char*); +template bool ahbot_commandscript::HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_WHITE>(ChatHandler* handler, const char*); +template bool ahbot_commandscript::HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_GREEN>(ChatHandler* handler, const char*); +template bool ahbot_commandscript::HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_BLUE>(ChatHandler* handler, const char*); +template bool ahbot_commandscript::HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_PURPLE>(ChatHandler* handler, const char*); +template bool ahbot_commandscript::HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_ORANGE>(ChatHandler* handler, const char*); +template bool ahbot_commandscript::HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_YELLOW>(ChatHandler* handler, const char*); + +template bool ahbot_commandscript::HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_ALLIANCE>(ChatHandler* handler, const char*); +template bool ahbot_commandscript::HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_HORDE>(ChatHandler* handler, const char*); +template bool ahbot_commandscript::HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_NEUTRAL>(ChatHandler* handler, const char*); + +void AddSC_ahbot_commandscript() +{ + new ahbot_commandscript(); +} diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index ee6def23c3e..824a1ae475e 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -2630,6 +2630,358 @@ UI.ShowQuestLevelsInDialogs = 0 # ################################################################################################### +################################### +# Auction House Bot Configuration # +################################### + +################################################################################################################### +# AUCTION HOUSE BOT SETTINGS +# +# AuctionHouseBot.Update.Interval +# Description: Interval in seconds for AHBot to get updated +# Default: 20 +# + +AuctionHouseBot.Update.Interval = 20 + +# +# AuctionHouseBot.Seller.Enabled +# Description: General enable or disable AuctionHouseBot Seller functionality +# Default: 0 - (Disabled) +# 1 - (Enabled) + +AuctionHouseBot.Seller.Enabled = 0 + +# +# AuctionHouseBot.Alliance.Items.Amount.Ratio +# Description: Enable/Disable (disabled if 0) the part of AHBot that puts items up for auction on Alliance AH +# Default: 100 - (Enabled with 100% of items specified in AuctionHouse.Items.Amount.color section) + +AuctionHouseBot.Alliance.Items.Amount.Ratio = 100 + +# +# AuctionHouseBot.Horde.Items.Amount.Ratio +# Enable/Disable (disabled if 0) the part of AHBot that puts items up for auction on Horde AH +# Default: 100 (Enabled with 100% of items specified in AuctionHouse.Items.Amount.color section) + +AuctionHouseBot.Horde.Items.Amount.Ratio = 100 + +# +# AuctionHouseBot.Neutral.Items.Amount.Ratio +# Description: Enable/Disable (disabled if 0) the part of AHBot that puts items up for auction on Neutral AH +# Default: 100 - (Enabled with 100% of items specified in AuctionHouse.Items.Amount.color section) + +AuctionHouseBot.Neutral.Items.Amount.Ratio = 100 + +# +# AuctionHouseBot.MinTime +# Description: Minimum time for the new auction in hours +# Default: 1 - (Hour) + +AuctionHouseBot.MinTime = 1 + +# +# AuctionHouseBot.MaxTime +# Description: Maximum time for the new auction in hours +# Default: 72 - (Hours) + +AuctionHouseBot.MaxTime = 72 + +# +# AuctionHouseBot.Items.Vendor +# Description: Include items that can be bought from vendors. +# Default: 0 - (Disabled) +# 1 - (Enabled) + +AuctionHouseBot.Items.Vendor = 0 + +# +# AuctionHouseBot.Items.Loot +# Description: Include items that can be looted or fished for. +# Default: 1 - (Enabled) +# 0 - (Disabled) + +AuctionHouseBot.Items.Loot = 1 + +# +# AuctionHouseBot.Items.Misc +# Description: Include misc. items. +# Default: 0 - (Disabled) +# 1 - (Enabled) + +AuctionHouseBot.Items.Misc = 0 + +# +# AuctionHouseBot.Bind.* +# Description: Indicates which bonding types to allow the bot to put up for auction +# No - Items that don't bind Default 1 (Allowed) +# Pickup - Items that bind on pickup Default 0 (Not Allowed) +# Equip - Items that bind on equip Default 1 (Allowed) +# Use - Items that bind on use Default 1 (Allowed) +# Quest - Quest Items Default 0 (Not Allowed) +# Values: 0 - (Disabled) +# 1 - (Enabled) + +AuctionHouseBot.Bind.No = 1 +AuctionHouseBot.Bind.Pickup = 0 +AuctionHouseBot.Bind.Equip = 1 +AuctionHouseBot.Bind.Use = 1 +AuctionHouseBot.Bind.Quest = 0 + +# +# AuctionHouseBot.LockBox.Enabled +# Description: Enable or not lockbox in auctionhouse +# Default 0 - (Disabled) +# 1 - (Enabled) + +AuctionHouseBot.LockBox.Enabled = 0 + +# +# AuctionHouseBot.ItemsPerCycle.Boost +# Description: This value is used to fill DB faster than normal when there is more than this value on missed items (not auctioned items). +# Normaly this value is only used once on server start with empty auction table. +# Default: 1000 + +AuctionHouseBot.ItemsPerCycle.Boost = 1000 + +# +# AuctionHouseBot.ItemsPerCycle.Normal +# Description: This value is used to fill DB with way with less cpu/db using. +# Normaly this value is used always when auction table is already initialised. +# Default: 20 + +AuctionHouseBot.ItemsPerCycle.Normal = 20 + +# +# AuctionHouseBot.BuyPrice.Seller +# Description: Should the Seller use BuyPrice or SellPrice to determine Bid Prices +# Default: 1 - (use SellPrice) +# 0 - (use BuyPrice) + +AuctionHouseBot.BuyPrice.Seller = 1 + +# +# AuctionHouseBot.Alliance.Price.Ratio +# Description: Percentage by which the price of items selled on Alliance Auction House is incremented / decreased +# Default: 100 - (Not modify) + +AuctionHouseBot.Alliance.Price.Ratio = 100 + +# +# AuctionHouseBot.Horde.Price.Ratio +# Description: Percentage by which the price of items selled on Horde Auction House is incremented / decreased +# Default: 100 - (Not modify) + +AuctionHouseBot.Horde.Price.Ratio = 100 + +# +# AuctionHouseBot.Neutral.Price.Ratio +# Description: Percentage by which the price of items selled on Neutral Auction House is incremented / decreased +# Default: 100 - (Not modify) + +AuctionHouseBot.Neutral.Price.Ratio = 100 + +# +# AuctionHouseBot.Items.ItemLevel.* +# Description: Prevent seller from listing items below/above this item level +# Default: 0 - (Disabled) +# 1-80 (Levels) + +AuctionHouseBot.Items.ItemLevel.Min = 0 +AuctionHouseBot.Items.ItemLevel.Max = 0 + +# +# AuctionHouseBot.Items.ReqLevel.* +# Prevent seller from listing items below/above this required level +# Default: - 0 (Disabled) + +AuctionHouseBot.Items.ReqLevel.Min = 0 +AuctionHouseBot.Items.ReqLevel.Max = 0 + +# +# AuctionHouseBot.Items.ReqSkill.* +# Description: Prevent seller from listing items below/above this skill level +# Default: 0 - (Disabled) +# 1 - (Enabled) + +AuctionHouseBot.Items.ReqSkill.Min = 0 +AuctionHouseBot.Items.ReqSkill.Max = 0 + +# +# AuctionHouseBot.Items.Amount.* +# Description: Define here for every item qualities how many items you want to be shown in Auction House +# This value will be adjusted by AuctionHouseBot.FACTION.Items.Amount.Ratio to define the exact amount of +# items that will finally be shown on Auction House +# Default: 0, 2000, 2500, 1500, 1000, 0, 0 (Gray, white, green, blue, purple, orange, yellow) + +AuctionHouseBot.Items.Amount.Gray = 0 +AuctionHouseBot.Items.Amount.White = 2000 +AuctionHouseBot.Items.Amount.Green = 2500 +AuctionHouseBot.Items.Amount.Blue = 1500 +AuctionHouseBot.Items.Amount.Purple = 1000 +AuctionHouseBot.Items.Amount.Orange = 0 +AuctionHouseBot.Items.Amount.Yellow = 0 + +# +# AustionHouseBot.Class.* +# Description: Here you can set the class of items you prefer to be show on AH +# These value are sorted by preference, from 0 (disabled) to 10 (max. preference) +# Default: Consumable: 6 +# Container: 4 +# Weapon: 8 +# Gem: 3 +# Armor: 8 +# Reagent: 1 +# Projectile: 2 +# TradeGod: 10 +# Generic: 1 +# Recipe: 6 +# Quiver: 1 +# Quest: 1 +# Key: 1 +# Misc: 5 +# Glyph: 3 + +AuctionHouseBot.Class.Consumable = 6 +AuctionHouseBot.Class.Container = 4 +AuctionHouseBot.Class.Weapon = 8 +AuctionHouseBot.Class.Gem = 3 +AuctionHouseBot.Class.Armor = 8 +AuctionHouseBot.Class.Reagent = 1 +AuctionHouseBot.Class.Projectile = 2 +AuctionHouseBot.Class.TradeGood = 10 +AuctionHouseBot.Class.Generic = 1 +AuctionHouseBot.Class.Recipe = 6 +AuctionHouseBot.Class.Quiver = 1 +AuctionHouseBot.Class.Quest = 1 +AuctionHouseBot.Class.Key = 1 +AuctionHouseBot.Class.Misc = 5 +AuctionHouseBot.Class.Glyph = 3 + +################################################################################################################### +# +# AHBot ITEM FINE TUNING +# The following are usefull for limiting what character levels can +# benefit from the auction house +# +# AuctionHouseBot.Class.Misc.Mount.ReqLevel.* +# Description: Prevent seller from listing mounts below/above this required level +# Default: 0 + +AuctionHouseBot.Class.Misc.Mount.ReqLevel.Min = 0 +AuctionHouseBot.Class.Misc.Mount.ReqLevel.Max = 0 + +# +# AuctionHouseBot.Class.Misc.Mount.ReqSkill.* +# Description: Prevent seller from listing mounts below/above this skill level +# Default: 0 + +AuctionHouseBot.Class.Misc.Mount.ReqSkill.Min = 0 +AuctionHouseBot.Class.Misc.Mount.ReqSkill.Max = 0 + +# +# AuctionHouseBot.Class.Glyph.ReqLevel.* +# Description: Prevent seller from listing glyphs below/above this required level +# Default: 0 + +AuctionHouseBot.Class.Glyph.ReqLevel.Min = 0 +AuctionHouseBot.Class.Glyph.ReqLevel.Max = 0 + +# +# AuctionHouseBot.Class.Glyph.ItemLevel.* +# Description: Prevent seller from listing glyphs below/above this item level +# Default: 0 + +AuctionHouseBot.Class.Glyph.ItemLevel.Min = 0 +AuctionHouseBot.Class.Glyph.ItemLevel.Max = 0 + +# +# AuctionHouseBot.Class.TradeGood.ItemLevel.* +# Description: Prevent seller from listing trade good items below/above this item level +# Default: 0 + +AuctionHouseBot.Class.TradeGood.ItemLevel.Min = 0 +AuctionHouseBot.Class.TradeGood.ItemLevel.Max = 0 + +# +# AuctionHouseBot.Class.Container.ItemLevel.* +# Description: Prevent seller from listing contianers below/above this item level +# Default: 0 + +AuctionHouseBot.Class.Container.ItemLevel.Min = 0 +AuctionHouseBot.Class.Container.ItemLevel.Max = 0 + +# +# AuctionHouseBot.forceIncludeItems +# Description: Include these items and ignore ALL filters +# List of ids with delimiter ',' +# Default: "" + +AuctionHouseBot.forceIncludeItems = "" + +# +# AuctionHouseBot.forceExcludeItems +# Description: Exclude these items even if they would pass the filters +# List of ids with delimiter ',' +# Example: "21878,27774,27811,28117,28122,43949" (this removes old items) +# Default: "" +# + +AuctionHouseBot.forceExcludeItems = "" + +# +################################################################################################################### + +################################################################################################################### +# AHBot Buyer config +# +# AuctionHouseBot.Buyer.Enabled +# Description: General enable or disable AuctionHouseBot Buyer functionality +# Default: 0 - (Disabled) +# 1 - (Enabled) + +AuctionHouseBot.Buyer.Enabled = 0 + +# +# AuctionHouseBot.Buyer.FACTION.Enabled +# Description: Enable or disable buyer independently by faction +# Default: 0 - (Disabled) +# 1 - (Enabled) + +AuctionHouseBot.Buyer.Alliance.Enabled = 0 +AuctionHouseBot.Buyer.Horde.Enabled = 0 +AuctionHouseBot.Buyer.Neutral.Enabled = 0 + +# +# AuctionHouseBot.BuyPrice.Buyer +# Description: Should the Buyer use BuyPrice or SellPrice to determine Bid Prices +# Default: 1 - (use BuyPrice) +# 0 - (use SellPrice) + +AuctionHouseBot.Buyer.Buyprice = 1 + +# +# AuctionHouseBot.Buyer.Recheck.Interval +# Description: This specifies the time interval (in minutes) between two evaluations of the same selled item. +# The lesser this value is, the more chances you give for item to be bought by ahbot. +# Default: 20 (20min.) + +AuctionHouseBot.Buyer.Recheck.Interval = 20 + +# +# AuctionHouseBot.Buyer.Alliance.Chance.Ratio +# Description: Chance ratio for the buyer to buy an item. Higher the value, lesser the probability +# Example: 3 (1 out of 3 change, that is, 33%). +# Default: 3 +# + +AuctionHouseBot.Buyer.Alliance.Chance.Ratio = 3 +AuctionHouseBot.Buyer.Horde.Chance.Ratio = 3 +AuctionHouseBot.Buyer.Neutral.Chance.Ratio = 3 + +# +################################################################################################################### + ################################################################################################### # LOGGING SYSTEM SETTINGS # @@ -2726,6 +3078,7 @@ Logger.commands.gm=3,Console GM Logger.sql.sql=5,Console DBErrors #Logger.achievement=3,Console Server +#Logger.ahbot=3,Console Server #Logger.auctionHouse=3,Console Server #Logger.bg.arena=3,Console Server #Logger.bg.battlefield=3,Console Server |