/** * MaNGOS is a full featured server for World of Warcraft, supporting * the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8 * * Copyright (C) 2005-2022 MaNGOS * * 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * World of Warcraft, and all World of Warcraft or Warcraft art, images, * and lore are copyrighted by Blizzard Entertainment, Inc. */ #ifndef AUCTION_HOUSE_BOT_H #define AUCTION_HOUSE_BOT_H #include "Config/Config.h" #include "AuctionHouseMgr.h" #include "SharedDefines.h" #include "Item.h" /** * This is the AuctionHouseBot and it is used to make less populated servers * appear more populated than they actually are by having auctions created by * the mangos daemon itself instead of by players. * * This bot can both create auctions and buyout/bid on auctions to create a feel * of a very active AH. The key classes for creating and buying auctions are * \ref AuctionBotBuyer for buying and \ref AuctionBotSeller for selling. * * \todo Describe more of how it all works, ie algorithms etc. */ /** \addtogroup auctionbot * @{ * \file */ /** * @brief shadow of ItemQualities with skipped ITEM_QUALITY_HEIRLOOM, anything after ITEM_QUALITY_ARTIFACT(6) in fact * */ enum AuctionQuality { AUCTION_QUALITY_GREY = 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 /** * @brief * */ enum AuctionBotConfigUInt32Values { CONFIG_UINT32_AHBOT_MAXTIME, CONFIG_UINT32_AHBOT_MINTIME, CONFIG_UINT32_AHBOT_ITEMS_PER_CYCLE_BOOST, CONFIG_UINT32_AHBOT_ITEMS_PER_CYCLE_NORMAL, CONFIG_UINT32_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO, CONFIG_UINT32_AHBOT_HORDE_ITEM_AMOUNT_RATIO, CONFIG_UINT32_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO, CONFIG_UINT32_AHBOT_ITEM_MIN_ITEM_LEVEL, CONFIG_UINT32_AHBOT_ITEM_MAX_ITEM_LEVEL, CONFIG_UINT32_AHBOT_ITEM_MIN_REQ_LEVEL, CONFIG_UINT32_AHBOT_ITEM_MAX_REQ_LEVEL, CONFIG_UINT32_AHBOT_ITEM_MIN_SKILL_RANK, CONFIG_UINT32_AHBOT_ITEM_MAX_SKILL_RANK, CONFIG_UINT32_AHBOT_ITEM_GREY_AMOUNT, CONFIG_UINT32_AHBOT_ITEM_WHITE_AMOUNT, CONFIG_UINT32_AHBOT_ITEM_GREEN_AMOUNT, CONFIG_UINT32_AHBOT_ITEM_BLUE_AMOUNT, CONFIG_UINT32_AHBOT_ITEM_PURPLE_AMOUNT, CONFIG_UINT32_AHBOT_ITEM_ORANGE_AMOUNT, CONFIG_UINT32_AHBOT_ITEM_YELLOW_AMOUNT, CONFIG_UINT32_AHBOT_CLASS_CONSUMABLE_AMOUNT, CONFIG_UINT32_AHBOT_CLASS_CONTAINER_AMOUNT, CONFIG_UINT32_AHBOT_CLASS_WEAPON_AMOUNT, CONFIG_UINT32_AHBOT_CLASS_GEM_AMOUNT, CONFIG_UINT32_AHBOT_CLASS_ARMOR_AMOUNT, CONFIG_UINT32_AHBOT_CLASS_REAGENT_AMOUNT, CONFIG_UINT32_AHBOT_CLASS_PROJECTILE_AMOUNT, CONFIG_UINT32_AHBOT_CLASS_TRADEGOOD_AMOUNT, CONFIG_UINT32_AHBOT_CLASS_GENERIC_AMOUNT, CONFIG_UINT32_AHBOT_CLASS_RECIPE_AMOUNT, CONFIG_UINT32_AHBOT_CLASS_QUIVER_AMOUNT, CONFIG_UINT32_AHBOT_CLASS_QUEST_AMOUNT, CONFIG_UINT32_AHBOT_CLASS_KEY_AMOUNT, CONFIG_UINT32_AHBOT_CLASS_MISC_AMOUNT, CONFIG_UINT32_AHBOT_CLASS_GLYPH_AMOUNT, CONFIG_UINT32_AHBOT_ALLIANCE_PRICE_RATIO, CONFIG_UINT32_AHBOT_HORDE_PRICE_RATIO, CONFIG_UINT32_AHBOT_NEUTRAL_PRICE_RATIO, CONFIG_UINT32_AHBOT_BUYER_CHANCE_RATIO_ALLIANCE, CONFIG_UINT32_AHBOT_BUYER_CHANCE_RATIO_HORDE, CONFIG_UINT32_AHBOT_BUYER_CHANCE_RATIO_NEUTRAL, CONFIG_UINT32_AHBOT_BUYER_RECHECK_INTERVAL, CONFIG_UINT32_AHBOT_CLASS_MISC_MOUNT_MIN_REQ_LEVEL, CONFIG_UINT32_AHBOT_CLASS_MISC_MOUNT_MAX_REQ_LEVEL, CONFIG_UINT32_AHBOT_CLASS_MISC_MOUNT_MIN_SKILL_RANK, CONFIG_UINT32_AHBOT_CLASS_MISC_MOUNT_MAX_SKILL_RANK, CONFIG_UINT32_AHBOT_CLASS_GLYPH_MIN_REQ_LEVEL, CONFIG_UINT32_AHBOT_CLASS_GLYPH_MAX_REQ_LEVEL, CONFIG_UINT32_AHBOT_CLASS_GLYPH_MIN_ITEM_LEVEL, CONFIG_UINT32_AHBOT_CLASS_GLYPH_MAX_ITEM_LEVEL, CONFIG_UINT32_AHBOT_CLASS_TRADEGOOD_MIN_ITEM_LEVEL, CONFIG_UINT32_AHBOT_CLASS_TRADEGOOD_MAX_ITEM_LEVEL, CONFIG_UINT32_AHBOT_CLASS_CONTAINER_MIN_ITEM_LEVEL, CONFIG_UINT32_AHBOT_CLASS_CONTAINER_MAX_ITEM_LEVEL, CONFIG_UINT32_AHBOT_UINT32_COUNT }; /** * @brief * */ enum AuctionBotConfigBoolValues { CONFIG_BOOL_AHBOT_BUYER_ALLIANCE_ENABLED, CONFIG_BOOL_AHBOT_BUYER_HORDE_ENABLED, CONFIG_BOOL_AHBOT_BUYER_NEUTRAL_ENABLED, CONFIG_BOOL_AHBOT_ITEMS_VENDOR, CONFIG_BOOL_AHBOT_ITEMS_LOOT, CONFIG_BOOL_AHBOT_ITEMS_MISC, CONFIG_BOOL_AHBOT_BIND_NO, CONFIG_BOOL_AHBOT_BIND_PICKUP, CONFIG_BOOL_AHBOT_BIND_EQUIP, CONFIG_BOOL_AHBOT_BIND_USE, CONFIG_BOOL_AHBOT_BIND_QUEST, CONFIG_BOOL_AHBOT_BUYPRICE_SELLER, CONFIG_BOOL_AHBOT_BUYPRICE_BUYER, CONFIG_BOOL_AHBOT_DEBUG_SELLER, CONFIG_BOOL_AHBOT_DEBUG_BUYER, CONFIG_BOOL_AHBOT_SELLER_ENABLED, CONFIG_BOOL_AHBOT_BUYER_ENABLED, CONFIG_BOOL_AHBOT_LOCKBOX_ENABLED, CONFIG_UINT32_AHBOT_BOOL_COUNT }; /** * @brief All basic config data used by other AHBot classes for self-configure. * */ class AuctionBotConfig { public: /** * @brief * */ AuctionBotConfig(); /** * @brief * * @param filename */ void SetConfigFileName(char const* filename) { m_configFileName = filename; } /** * @brief * * @return bool */ bool Initialize(); /** * @brief * * @return const char */ const char* GetAHBotIncludes() const { return m_AHBotIncludes.c_str(); } /** * @brief * * @return const char */ const char* GetAHBotExcludes() const { return m_AHBotExcludes.c_str(); } /** * @brief * * @return uint32 - AH Bot ID */ uint32 GetAHBotId() const { return m_BotId; } /** * @brief * * @param index * @return uint32 */ uint32 getConfig(AuctionBotConfigUInt32Values index) const { return m_configUint32Values[index]; } /** * @brief * * @param index * @return bool */ bool getConfig(AuctionBotConfigBoolValues index) const { return m_configBoolValues[index]; } /** * @brief * * @param index * @param value */ void setConfig(AuctionBotConfigBoolValues index, bool value) { m_configBoolValues[index] = value; } /** * @brief * * @param index * @param value */ void setConfig(AuctionBotConfigUInt32Values index, uint32 value) { m_configUint32Values[index] = value; } /** * @brief Gets the ratio of items to sell for a given auctionhouse type * * @param houseType Type of the house. * @return uint32 a value between 0 and 10000 probably representing 0%-100% */ uint32 getConfigItemAmountRatio(AuctionHouseType houseType) const; /** * @brief Gets if a buyer is enabled for the given auctionhouse type * * @param houseType Type of the house, ie: alliance/horde/neutral * @return bool true if a buyer is enabled, false otherwise */ bool getConfigBuyerEnabled(AuctionHouseType houseType) const; /** * @brief Gets the ratio for the amount of items of a certain quality to be sold * * @param quality quality of the item you want to know the ratio for * @return uint32 probably a value between 0 and 10000 representing 0%-100% as the config values seem to be capped at this */ uint32 getConfigItemQualityAmount(AuctionQuality quality) const; /** * @brief * * @return uint32 */ uint32 GetItemPerCycleBoost() const { return m_ItemsPerCycleBoost; } /** * @brief * * @return uint32 */ uint32 GetItemPerCycleNormal() const { return m_ItemsPerCycleNormal; } /** * @brief Reloads the AhBot config. * * @return bool true if the config was successfully reloaded, false otherwise */ bool Reload(); /** * @brief Gets the name of the item class. * * @param itemclass class of the item you want to lookup name for * @return const char a string describing the name of the item class * \see ItemClass */ static char const* GetItemClassName(ItemClass itemclass); /** * @brief Does the same thing as \ref AuctionBotConfig::GetItemClassName converts a enum * value to a readable string * * @param houseType the housetype you would like to "translate" * @return const char the string representation of the num value */ static char const* GetHouseTypeName(AuctionHouseType houseType); private: std::string m_configFileName; /**< TODO */ std::string m_AHBotIncludes; /**< TODO */ std::string m_AHBotExcludes; /**< TODO */ Config m_AhBotCfg; /**< TODO */ uint32 m_ItemsPerCycleBoost; /**< TODO */ uint32 m_ItemsPerCycleNormal; /**< TODO */ uint32 m_BotId; uint32 m_configUint32Values[CONFIG_UINT32_AHBOT_UINT32_COUNT]; /**< TODO */ bool m_configBoolValues[CONFIG_UINT32_AHBOT_BOOL_COUNT]; /**< TODO */ /** * @brief * * @param AHBotIncludes */ void SetAHBotIncludes(const std::string& AHBotIncludes) { m_AHBotIncludes = AHBotIncludes; } /** * @brief * * @param AHBotExcludes */ void SetAHBotExcludes(const std::string& AHBotExcludes) { m_AHBotExcludes = AHBotExcludes; } /** * @brief * * @param AHBot Character Name */ void SetAHBotId(const std::string& BotCharName); /** * @brief Sets a certain config value to the given default value * * @param index index to set * @param fieldname name of the field to set, ie: how it is represented in the config file * @param defvalue the default value for the field */ void setConfig(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue); /** * @brief Sets a certain config value to given default value and a max it can have that it will cap at * * @param index index to set * @param fieldname name of the field to set, ie: how it is represented in the config file * @param defvalue the default value for the field * @param maxvalue the maximum value this config can have */ void setConfigMax(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue, uint32 maxvalue); /** * @brief Sets a certain config value to given default value and a max it can have that it will cap at * * @param index index to set * @param fieldname name of the field to set, ie: how it is represented in the config file * @param defvalue the default value for the field * @param minvalue the minimal value this config can have * @param maxvalue the maximum value this config can have */ void setConfigMinMax(AuctionBotConfigUInt32Values index, char const* fieldname, uint32 defvalue, uint32 minvalue, uint32 maxvalue); /** * @brief Sets a certain config value to the given default value * * @param index index to set * @param fieldname name of the field to set, ie: how it is represented in the config file * @param defvalue the default value for this field */ void setConfig(AuctionBotConfigBoolValues index, char const* fieldname, bool defvalue); /** * @brief Retrieves the configuration for the \ref AuctionHouseBot from a configuration file. * */ void GetConfigFromFile(); }; #define sAuctionBotConfig MaNGOS::Singleton::Instance() /** * @brief This is the base interface for the \ref AuctionBotSeller and \ref AuctionBotBuyer classes * which in itself only provides the possibility to use dynamic_cast in some of the * \ref AuctionHouseBot methods, ie: \ref AuctionHouseBot::SetItemsRatio uses it to cast it's * member AuctionHouseBot::m_Seller to a \ref AuctionBotSeller. * */ class AuctionBotAgent { public: /** * @brief * */ AuctionBotAgent() {} /** * @brief * */ virtual ~AuctionBotAgent() {} public: /** * @brief Initializes this agent/bot and makes sure that there's anything to actually do for it. * If there's not it will return false and there's really no interest in keeping it for * the moment, otherwise returns true and has atleast one active house where it will do * business. * * @return bool true if we intialized with at least one auction house to do business in, false otherwise */ virtual bool Initialize() = 0; /** * @brief This method updates what's going on on the AH for the bots, ie: if this is called for the * \ref AuctionBotBuyer it will place bids on items etc if there's a config file for it. If * the \ref AuctionBotSeller is called instead it would put up some new items if there's a * config file for it. * * @param houseType the house type we should work with while updating * @return bool true if any update was actually done, ie: we put some items up/bought some, false otherwise */ virtual bool Update(AuctionHouseType houseType) = 0; }; /** * @brief Structure used in \ref AuctionHouseBot::PrepareStatusInfos to show how many items there * are in each auction house and how many of each quality there are that were created by * one of the 2 agents \ref AuctionBotBuyer and \ref AuctionBotSeller * \see AuctionQuality * */ struct AuctionHouseBotStatusInfoPerType { uint32 ItemsCount; /**< How many items there are totally in this AH */ uint32 QualityInfo[MAX_AUCTION_QUALITY]; /**< How many items of each quality there are */ }; /** * @brief Used to get an array with all possible Action Houses, ie: neutral,ally,horde. * */ typedef AuctionHouseBotStatusInfoPerType AuctionHouseBotStatusInfo[MAX_AUCTION_HOUSE_TYPE]; /** * @brief This class handle both Selling and Buying method * (holder of AuctionBotBuyer and AuctionBotSeller objects) * (Taken from comments in source) * * \todo Better description here perhaps */ class AuctionHouseBot { public: /** * @brief Initializes a new instance of the \ref AuctionHouseBot class. * */ AuctionHouseBot(); /** * @brief Finalizes an instance of the \ref AuctionHouseBot class. * */ ~AuctionHouseBot(); /** * @brief Updates the \ref AuctionHouseBot by checking if either the \ref AuctionBotSeller or * \ref AuctionBotBuyer wants to sell/buy anything and in that case lets one of them do * that and the other one will have to wait until the next call to \ref AuctionHouseBot::Update * */ void Update(); /** * @brief Initializes this instance. * */ void Initialize(); // Followed method is mainly used by level3.cpp for ingame/console command /** * @brief Sets the items ratio which probably decides how many items should * appear in each of the auction houses * * @param al The alliance house ratio * @param ho The horde house ratio * @param ne The neutral house ratio */ void SetItemsRatio(uint32 al, uint32 ho, uint32 ne); /** * @brief Sets the items ratio for a specific house, like \ref AuctionHouseBot::SetItemsRatio but * only for one house. * * @param house The house * @param val The new ratio */ void SetItemsRatioForHouse(AuctionHouseType house, uint32 val); /** * @brief Sets the items amount. * * @param (vals)[] The vals. */ void SetItemsAmount(uint32(&vals) [MAX_AUCTION_QUALITY]); /** * @brief Changes the ratio for how often a certain quality of items should show up at the * AH. A specialised version of \ref AuctionHouseBot::SetItemsAmount * * @param quality quality of the items you want to change the ratio for * @param val the new ratio you want as a value between 0-10000 probably representing 0%-100% * \see AuctionQuality */ void SetItemsAmountForQuality(AuctionQuality quality, uint32 val); /** * @brief Reloads all the configurations, for the AH bot and for both \ref AuctionBotBuyer and * \ref AuctionBotSeller and ourselves * * @return bool true if it went well, false otherwise */ bool ReloadAllConfig(); /** * @brief Expires all the items currently created by the AH bot and they'll be replaced later on * again. If parameter all is false only auctions without a bid are removed. * * @param all Whether to expire all auctions or only those without a bid */ void Rebuild(bool all); /** * @brief Fills a status info structure with data about how many items of each there * currently are in the auction house that the auction bot has created * * @param statusInfo the structure to fill with data */ void PrepareStatusInfos(AuctionHouseBotStatusInfo& statusInfo); private: /** * @brief Initializes the agents, ie: the \ref AuctionBotBuyer and \ref AuctionBotSeller * */ void InitializeAgents(); AuctionBotAgent* m_Buyer; /**< The buyer (\ref AuctionBotBuyer) for this \ref AuctionHouseBot */ AuctionBotAgent* m_Seller; /**< The seller (\ref AuctionBotSeller) for this \ref AuctionHouseBot */ uint32 m_OperationSelector; /**< 0..2*MAX_AUCTION_HOUSE_TYPE-1 */ }; ///Convenience to easily access the singleton for the \ref AuctionHouseBot #define sAuctionBot MaNGOS::Singleton::Instance() /** @} */ #endif