aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBlipi <gpascualg93@gmail.com>2012-12-20 05:39:35 +0100
committerRochet2 <tqbattlenet@gmail.com>2014-08-25 22:15:59 +0300
commita7d1394c2e55ef99c9643338b073860a256c565f (patch)
treebe3432450f49d2003752a569fbddc0a7385853ac /src
parent1c1f4fe33d75ca00fa6fd3370ff0f13731523f14 (diff)
Core/AHBot: Implemented AHBot based on MaNGOS code
Warning: CMake must be rerun Apply if you have crashes Rewrite Seller prices, add random properties and implement some suggestions on price calculations Core/AHBot: Update to latest suggestions Fix SQLs after merge, split the AH bot to spearate headers and cpps, fix the config default values Remove case 8 from GetBuyModifier. It was not correct Fix Gray Grey GRAY typos Change message config name Fix non pch build Fix switch ident, also earlier removed whitespace. Add missing include for non pch build Fix possible crash: if (forplayer || GetOwnerGUID()) changed to if (forplayer) Apply Nayd.diff - Code style fixes Fix leftovers from nayd Correct SQL transaction and change one SQL query to C++ instead Make loot items distinct
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 4de9cb34df6..5607b875cfe 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"
@@ -1254,6 +1255,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);
@@ -1739,6 +1743,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
@@ -1766,6 +1773,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();
@@ -1998,6 +2008,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 cb87e1739c2..5b4811af01c 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
};
@@ -332,6 +333,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 d98a061b9f3..d2e871e9bcc 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -2622,6 +2622,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
#
@@ -2718,6 +3070,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