aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Accounts/RBAC.h16
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBot.cpp428
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBot.h280
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp432
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h96
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp1029
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotSeller.h147
-rw-r--r--src/server/game/CMakeLists.txt3
-rw-r--r--src/server/game/Entities/Item/Item.cpp10
-rw-r--r--src/server/game/Miscellaneous/Language.h22
-rw-r--r--src/server/game/Scripting/ScriptLoader.cpp2
-rw-r--r--src/server/game/World/World.cpp17
-rw-r--r--src/server/game/World/World.h2
-rw-r--r--src/server/scripts/CMakeLists.txt1
-rw-r--r--src/server/scripts/Commands/cs_ahbot.cpp251
-rw-r--r--src/server/worldserver/worldserver.conf.dist353
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