diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..5610d2b3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,72 @@ +name: Bug report +description: Create a bug report to help us improve. +title: "Bug: " +body: + - type: textarea + id: current + attributes: + label: Current Behaviour + description: | + Description of the problem or issue here. + Include entries of affected creatures / items / quests / spells etc. + If this is a crash, post the crashlog (upload to https://gist.github.com/) and include the link here. + Never upload files! Use GIST for text and YouTube for videos! + validations: + required: true + - type: textarea + id: expected + attributes: + label: Expected Behaviour + description: | + Tell us what should happen instead. + validations: + required: true + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce the problem + description: | + What does someone else need to do to encounter the same bug? + placeholder: | + 1. Step 1 + 2. Step 2 + 3. Step 3 + validations: + required: true + - type: textarea + id: extra + attributes: + label: Extra Notes + description: | + Do you have any extra notes that can help solve the issue that does not fit any other field? + placeholder: | + None + validations: + required: false + - type: textarea + id: commit + attributes: + label: AC rev. hash/commit + description: | + Copy the result of the `.server debug` command (if you need to run it from the client get a prat addon) + validations: + required: true + - type: input + id: os + attributes: + label: Operating system + description: | + The Operating System the Server is running on. + i.e. Windows 11 x64, Debian 10 x64, macOS 12, Ubuntu 20.04 + validations: + required: true + - type: textarea + id: custom + attributes: + label: Custom changes or Modules + description: | + List which custom changes or modules you have applied, i.e. Eluna module, etc. + placeholder: | + None + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000..58f79ddb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,33 @@ +name: Feature request +description: Suggest an idea for this project +title: "Feature: " +body: + - type: markdown + attributes: + value: | + Thank you for taking your time to fill out a feature request. Remember to fill out all fields including the title above. + An issue that is not properly filled out will be closed. + - type: textarea + id: description + attributes: + label: Describe your feature request or suggestion in detail + description: | + A clear and concise description of what you want to happen. + validations: + required: true + - type: textarea + id: solution + attributes: + label: Describe a possible solution to your feature or suggestion in detail + description: | + A clear and concise description of any alternative solutions or features you've considered. + validations: + required: false + - type: textarea + id: additional + attributes: + label: Additional context + description: | + Add any other context or screenshots about the feature request here. + validations: + required: false diff --git a/.github/workflows/core-build.yml b/.github/workflows/core-build.yml new file mode 100644 index 00000000..921c9eb4 --- /dev/null +++ b/.github/workflows/core-build.yml @@ -0,0 +1,12 @@ +name: core-build +on: + push: + branches: + - 'master' + pull_request: + +jobs: + build: + uses: azerothcore/reusable-workflows/.github/workflows/core_build_modules.yml@main + with: + module_repo: ${{ github.event.repository.name }} diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 1bdce67c..00000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -CU_SET_PATH("CMAKE_MOD_AHBOT_DIR" "${CMAKE_CURRENT_LIST_DIR}") -CU_ADD_HOOK(AFTER_LOAD_CONF "${CMAKE_CURRENT_LIST_DIR}/cmake/after_load_conf.cmake") -CU_ADD_HOOK(BEFORE_GAME_LIBRARY "${CMAKE_CURRENT_LIST_DIR}/cmake/before_game_lib.cmake") -CU_ADD_HOOK(BEFORE_SCRIPTS_LIBRARY "${CMAKE_CURRENT_LIST_DIR}/cmake/before_scripts_lib.cmake") -CU_ADD_HOOK(AFTER_GAME_LIBRARY "${CMAKE_CURRENT_LIST_DIR}/cmake/after_game_lib.cmake") -AC_ADD_SCRIPT("${CMAKE_CURRENT_LIST_DIR}/src/cs_ah_bot.cpp") -AC_ADD_SCRIPT_LOADER("AHBotCommand" "${CMAKE_CURRENT_LIST_DIR}/src/loader_cs_ah_bot.h") -CU_ADD_HOOK(AFTER_WORLDSERVER_CMAKE "${CMAKE_CURRENT_LIST_DIR}/cmake/after_ws_install.cmake") \ No newline at end of file diff --git a/README.md b/README.md index 3a4028f5..4f6ce053 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,70 @@ -# Mod-AHBOT +# ![logo](https://raw.githubusercontent.com/azerothcore/azerothcore.github.io/master/images/logo-github.png) AzerothCore +## Mod-AHBOT +- Latest build status with azerothcore: [![Build Status](https://github.com/azerothcore/mod-ah-bot/workflows/core-build/badge.svg?branch=master&event=push)](https://github.com/azerothcore/mod-ah-bot) -## Description +## Important notes + +You have to use at least AzerothCore commit [9adba48](https://github.com/azerothcore/azerothcore-wotlk/commit/9adba482c236f1087d66a672e97a99f763ba74b3). -A ahbot module for azerothcore. +If you use an old version of this module please update the table structure using this SQL statement: +```sql +ALTER TABLE `auctionhousebot` RENAME TO `mod_auctionhousebot`; +``` + +## Description + +An auction house bot for the best core: AzerothCore. +This mod works by selling and bidding auctions in the factions auction house. It can be instructed to do both the operations independently. ## Installation ``` -1. Apply ahbot.patch to your core. -2. Simply place the module under the `modules` directory of your AzerothCore source. -3. Import the SQL manually to the right Database (auth, world or characters) or with the `db_assembler.sh` (if `include.sh` provided). -4. Re-run cmake and launch a clean build of AzerothCore. +1. Simply place the module under the `modules` directory of your AzerothCore source. +1. Import the SQL manually to the right Database (auth, world or characters). +1. Re-run cmake and launch a clean build of AzerothCore. ``` +## Usage + +Edit the module configuration and add a player account ID and a character ID. +This character will sell and buy items in the auction house so give him a good name. +If you only specify the account ID, all the characters created within that account will be involved in selling and bidding on the markets. + +Specify what operation must be performed (`EnableSeller`, `EnableBuyer` or both). + +Notes: +- The account used does not need any security level and can be a player account. +- The character used by the ahbot is not meant to be used ingame. If you use it to browse the auction house, you might have issues like "Searching for items..." displaying forever. + ## Edit module configuration (optional) -If you need to change the module configuration, go to your server configuration folder (where your `worldserver` or `worldserver.exe` is) -rename the file mod_ahbot.conf.dist to mod_ahbot.conf and edit it. +If you need to change the module configuration, go to your server configuration folder (where your `worldserver` or `worldserver.exe` is) in `modules` you will have to copy and rename (the copy) the file `mod_ahbot.conf.dist` to `mod_ahbot.conf` and edit it. This will change the overall behavior of the bot. + +If you need to change a more specific value (for example the quotas of item sold), you will need to update values int the `mod_auctionhousebot` table or use the command line. + +The default quotas of all the auction houses for trade goods are: +- Gray = 0 +- White = 27 +- Green = 12 +- Blue = 10 +- Purple = 1 +- Orange = 0 +- Yellow = 0 + +The default quotas of all the auction houses for non trade goods items are: +- Gray = 0 +- White = 10 +- Green = 30 +- Blue = 8 +- Purple = 2 +- Orange = 0 +- Yellow = 0 +The sum of the percentage for these categories must always be 100, or otherwise the defaults values will be used and the modifications will not be accepted. ## Credits -ayase +- Ayase: ported the bot to AzerothCore +- Other contributors (check the contributors list) diff --git a/ahbot.patch b/ahbot.patch deleted file mode 100644 index e197d1dc..00000000 --- a/ahbot.patch +++ /dev/null @@ -1,214 +0,0 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 32edeb3458..35385f2271 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -46,6 +46,27 @@ if(EXISTS "conf/config.cmake") - include(conf/config.cmake) - endif() - -+# -+# Loading dyn modules -+# -+ -+# add modules and dependencies -+CU_SUBDIRLIST(sub_DIRS "${CMAKE_SOURCE_DIR}/modules" FALSE FALSE) -+FOREACH(subdir ${sub_DIRS}) -+ -+ get_filename_component(MODULENAME ${subdir} NAME) -+ -+ if (";${DISABLED_AC_MODULES};" MATCHES ";${MODULENAME};") -+ continue() -+ endif() -+ -+ STRING(REGEX REPLACE "^${CMAKE_SOURCE_DIR}/" "" subdir_rel ${subdir}) -+ if(EXISTS "${subdir}/CMakeLists.txt") -+ message("Loading module: ${subdir_rel}") -+ add_subdirectory("${subdir_rel}") -+ endif() -+ENDFOREACH() -+ - CU_RUN_HOOK("AFTER_LOAD_CONF") - - # build in Release-mode by default if not explicitly set -@@ -107,26 +128,6 @@ if( TOOLS ) - add_subdirectory(src/tools) - endif() - --# --# Loading dyn modules --# -- --# add modules and dependencies --CU_SUBDIRLIST(sub_DIRS "${CMAKE_SOURCE_DIR}/modules" FALSE FALSE) --FOREACH(subdir ${sub_DIRS}) -- -- get_filename_component(MODULENAME ${subdir} NAME) -- -- if (";${DISABLED_AC_MODULES};" MATCHES ";${MODULENAME};") -- continue() -- endif() -- -- STRING(REGEX REPLACE "^${CMAKE_SOURCE_DIR}/" "" subdir_rel ${subdir}) -- if(EXISTS "${subdir}/CMakeLists.txt") -- message("Loading module: ${subdir_rel}") -- add_subdirectory("${subdir_rel}") -- endif() --ENDFOREACH() - - # - # Loading application sources -diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp -index 4aba5703b2..5c9a332016 100644 ---- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp -+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp -@@ -21,6 +21,9 @@ - #include - #include "AvgDiffTracker.h" - #include "AsyncAuctionListing.h" -+#ifdef MOD_AH_BOT -+#include "AuctionHouseBot.h" -+#endif - - enum eAuctionHouse - { -@@ -139,8 +142,11 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry* auction, SQLTransa - if (owner || owner_accId) - { - uint32 profit = auction->bid + auction->deposit - auction->GetAuctionCut(); -- -+#ifdef MOD_AH_BOT -+ if (owner && owner->GetGUIDLow() != auctionbot->GetAHBplayerGUID()) -+#else - if (owner) -+#endif - { - owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS, profit); - owner->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD, auction->bid); -@@ -183,7 +189,11 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry* auction, SQLTransacti - // owner exist - if (owner || owner_accId) - { -+#ifdef MOD_AH_BOT -+ if (owner && owner->GetGUIDLow() != auctionbot->GetAHBplayerGUID()) -+#else - if (owner) -+#endif - owner->GetSession()->SendAuctionOwnerNotification(auction); - - MailDraft(auction->BuildAuctionMailSubject(AUCTION_EXPIRED), AuctionEntry::BuildAuctionMailBody(0, 0, auction->buyout, auction->deposit, 0)) -@@ -207,6 +217,11 @@ void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 new - // old bidder exist - if (oldBidder || oldBidder_accId) - { -+#ifdef MOD_AH_BOT -+ if (oldBidder && !newBidder) -+ oldBidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, auctionbot->GetAHBplayerGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template); -+#endif // MOD_AH_BOT -+ - if (oldBidder && newBidder) - oldBidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, newBidder->GetGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template); - -@@ -407,10 +422,16 @@ void AuctionHouseObject::AddAuction(AuctionEntry* auction) - - AuctionsMap[auction->Id] = auction; - sScriptMgr->OnAuctionAdd(this, auction); -+#ifdef MOD_AH_BOT -+ auctionbot->IncrementItemCounts(auction); -+#endif - } - - bool AuctionHouseObject::RemoveAuction(AuctionEntry* auction) - { -+#ifdef MOD_AH_BOT -+ auctionbot->DecrementItemCounts(auction, auction->item_template); -+#endif - bool wasInMap = AuctionsMap.erase(auction->Id) ? true : false; - - sScriptMgr->OnAuctionRemove(this, auction); -diff --git a/src/server/game/Mails/Mail.cpp b/src/server/game/Mails/Mail.cpp -index ef72cbfe2c..2f57ac9687 100644 ---- a/src/server/game/Mails/Mail.cpp -+++ b/src/server/game/Mails/Mail.cpp -@@ -15,6 +15,9 @@ - #include "Item.h" - #include "AuctionHouseMgr.h" - #include "CalendarMgr.h" -+#ifdef MOD_AH_BOT -+#include "AuctionHouseBot.h" -+#endif - - MailSender::MailSender(Object* sender, MailStationery stationery) : m_stationery(stationery) - { -@@ -168,6 +171,15 @@ void MailDraft::SendMailTo(SQLTransaction& trans, MailReceiver const& receiver, - - uint32 mailId = sObjectMgr->GenerateMailID(); - -+#ifdef MOD_AH_BOT -+ if (receiver.GetPlayerGUIDLow() == auctionbot->GetAHBplayerGUID()) -+ { -+ if (sender.GetMailMessageType() == MAIL_AUCTION) // auction mail with items -+ deleteIncludedItems(trans, true); -+ return; -+ } -+#endif -+ - time_t deliver_time = time(NULL) + deliver_delay; - - //expire time if COD 3 days, if no COD 30 days, if auction sale pending 1 hour -diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp -index 01b1fe0acb..38b0e5fc90 100644 ---- a/src/server/game/World/World.cpp -+++ b/src/server/game/World/World.cpp -@@ -76,6 +76,9 @@ - #include "AsyncAuctionListing.h" - #include "SavingSystem.h" - #include -+#ifdef MOD_AH_BOT -+#include "AuctionHouseBot.h" -+#endif - - ACE_Atomic_Op World::m_stopEvent = false; - uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE; -@@ -1635,6 +1638,20 @@ void World::SetInitialWorldSettings() - sLog->outString("Loading Completed Achievements..."); - sAchievementMgr->LoadCompletedAchievements(); - -+#ifdef MOD_AH_BOT -+ std::string conf_path = _CONF_DIR; -+ std::string cfg_file = conf_path + "/mod_ahbot.conf"; -+#ifdef WIN32 -+ cfg_file = "mod_ahbot.conf"; -+#endif -+ std::string cfg_def_file = cfg_file + ".dist"; -+ sConfigMgr->LoadMore(cfg_def_file.c_str()); -+ sConfigMgr->LoadMore(cfg_file.c_str()); -+ -+ // Initialize AHBot settings before deleting expired auctions due to AHBot hooks -+ auctionbot->InitializeConfiguration(); -+#endif -+ - ///- Load dynamic data tables from the database - sLog->outString("Loading Item Auctions..."); - sAuctionMgr->LoadAuctionItems(); -@@ -1871,6 +1888,11 @@ void World::SetInitialWorldSettings() - mgr = ChannelMgr::forTeam(TEAM_HORDE); - mgr->LoadChannels(); - -+#ifdef MOD_AH_BOT -+ sLog->outString("Initialize AuctionHouseBot..."); -+ auctionbot->Initialize(); -+#endif -+ - uint32 startupDuration = GetMSTimeDiffToNow(startupBegin); - sLog->outString(); - sLog->outError("WORLD: World initialized in %u minutes %u seconds", (startupDuration / 60000), ((startupDuration % 60000) / 1000)); -@@ -2031,6 +2053,9 @@ void World::Update(uint32 diff) - // pussywizard: handle auctions when the timer has passed - if (m_timers[WUPDATE_AUCTIONS].Passed()) - { -+#ifdef MOD_AH_BOT -+ auctionbot->Update(); -+#endif - m_timers[WUPDATE_AUCTIONS].Reset(); - - // pussywizard: handle expired auctions, auctions expired when realm was offline are also handled here (not during loading when many required things aren't loaded yet) diff --git a/cmake/after_game_lib.cmake b/cmake/after_game_lib.cmake deleted file mode 100644 index f4667247..00000000 --- a/cmake/after_game_lib.cmake +++ /dev/null @@ -1 +0,0 @@ -include_directories(${CMAKE_MOD_AHBOT_DIR}/src) \ No newline at end of file diff --git a/cmake/after_load_conf.cmake b/cmake/after_load_conf.cmake deleted file mode 100644 index b2d70be3..00000000 --- a/cmake/after_load_conf.cmake +++ /dev/null @@ -1 +0,0 @@ -add_definitions(-DMOD_AH_BOT) \ No newline at end of file diff --git a/cmake/after_ws_install.cmake b/cmake/after_ws_install.cmake deleted file mode 100644 index eb28897f..00000000 --- a/cmake/after_ws_install.cmake +++ /dev/null @@ -1,15 +0,0 @@ -if( WIN32 ) - if ( MSVC ) - add_custom_command(TARGET worldserver - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_MOD_AHBOT_DIR}/conf/mod_ahbot.conf.dist" ${CMAKE_BINARY_DIR}/bin/$(ConfigurationName)/ - ) - elseif ( MINGW ) - add_custom_command(TARGET worldserver - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_MOD_AHBOT_DIR}/conf/mod_ahbot.conf.dist" ${CMAKE_BINARY_DIR}/bin/ - ) - endif() -endif() - -install(FILES "${CMAKE_MOD_AHBOT_DIR}/conf/mod_ahbot.conf.dist" DESTINATION ${CONF_DIR}) \ No newline at end of file diff --git a/cmake/before_game_lib.cmake b/cmake/before_game_lib.cmake deleted file mode 100644 index 657ee19d..00000000 --- a/cmake/before_game_lib.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(game_STAT_SRCS - ${game_STAT_SRCS} - ${CMAKE_MOD_AHBOT_DIR}/src/AuctionHouseBot.cpp - ${CMAKE_MOD_AHBOT_DIR}/src/AuctionHouseBot.h -) diff --git a/cmake/before_scripts_lib.cmake b/cmake/before_scripts_lib.cmake deleted file mode 100644 index f4667247..00000000 --- a/cmake/before_scripts_lib.cmake +++ /dev/null @@ -1 +0,0 @@ -include_directories(${CMAKE_MOD_AHBOT_DIR}/src) \ No newline at end of file diff --git a/conf/mod_ahbot.conf.dist b/conf/mod_ahbot.conf.dist index f03ffec6..1b12db7e 100644 --- a/conf/mod_ahbot.conf.dist +++ b/conf/mod_ahbot.conf.dist @@ -1,4 +1,5 @@ - +[worldserver] + ############################################################################### # AUCTION HOUSE BOT SETTINGS # @@ -6,10 +7,30 @@ # Enable/Disable Debugging output # Default 0 (disabled) # +# AuctionHouseBot.DEBUG_CONFIG +# Enable/Disable Debugging output from the configuration +# Default 0 (disabled) +# # AuctionHouseBot.DEBUG_FILTERS # Enable/Disable Debugging output from Filters # Default 0 (disabled) # +# AuctionHouseBot.DEBUG_BUYER +# Enable/Disable Debugging output from buyer +# Default 0 (disabled) +# +# AuctionHouseBot.DEBUG_SELLER +# Enable/Disable Debugging output from seller +# Default 0 (disabled) +# +# AuctionHouseBot.TRACE_SELLER +# Enable/Disable tracing for the sold items +# Default 0 (disabled) +# +# AuctionHouseBot.TRACE_BUYER +# Enable/Disable tracing for the bought items +# Default 0 (disabled) +# # AuctionHouseBot.EnableSeller # Enable/Disable the part of AHBot that puts items up for auction # Default 0 (disabled) @@ -26,6 +47,17 @@ # Should the Buyer use BuyPrice or SellPrice to determine Bid Prices # Default 0 (use SellPrice) # +# AuctionHouseBot.UseMarketPriceForSeller +# Should the Seller use the market price for its auctions? +# Default 0 (disabled) +# +# AuctionHouseBot.MarketResetThreshold +# How many auctions of the same item are necessary before the plain priceis adopted. +# Before reaching this threshold, the price increase/decrease according to an heuristic. +# Set this variable to a lower value to have a fast reacting market price, +# to an high value to smooth the oscillations in prices. +# Default 25 +# # Auction House Bot character data # AuctionHouseBot.Account is the account number # (in realmd->account table) of the player you want to run @@ -38,17 +70,53 @@ # Number of Items to Add/Remove from the AH during mass operations # Default 200 # +# AuctionHouseBot.ConsiderOnlyBotAuctions +# Ignore player auctions and consider only bot ones when keeping track of the numer of auctions in place. +# This allow to keep a background noise in the market even when lot of players are in. +# If this is not set, players acutions are counted in the valid auctions and you will need to greatly increase the maxitems SQL values to +# allow the bot to operate on the market. If this is set the players auctions will not be considered. +# Default 0 (False) +# +# AuctionHouseBot.DuplicatesCount +# The maximum amount of duplicates stacks present in the market sold by the bot. +# If set to zero then no limits are set in place. +# Default 0 +# +# AuctionHouseBot.DivisibleStacks +# Sell items in stack sizes which depends on the maximum amount per stack. +# For example, an item with max stack size 20 will be sold in 5, 10 15 and 20 stacks, and not at random. +# Default 0 (False) +# +# AuctionHouseBot.ElapsingTimeClass +# The elapsing time for the sold items. There are three classes: +# 0 = long, auctions last from 1 to 3 days +# 1 = medium, auctions last from 1 to 24 hours +# 2 = shorts, auctions last from 10 to 60 minutes +# Default 1 +# ############################################################################### AuctionHouseBot.DEBUG = 0 +AuctionHouseBot.DEBUG_CONFIG = 0 AuctionHouseBot.DEBUG_FILTERS = 0 +AuctionHouseBot.DEBUG_BUYER = 0 +AuctionHouseBot.DEBUG_SELLER = 0 +AuctionHouseBot.TRACE_SELLER = 0 +AuctionHouseBot.TRACE_BUYER = 0 + AuctionHouseBot.EnableSeller = 0 AuctionHouseBot.EnableBuyer = 0 AuctionHouseBot.UseBuyPriceForSeller = 0 AuctionHouseBot.UseBuyPriceForBuyer = 0 +AuctionHouseBot.UseMarketPriceForSeller = 0 +AuctionHouseBot.MarketResetThreshold = 25 AuctionHouseBot.Account = 0 AuctionHouseBot.GUID = 0 AuctionHouseBot.ItemsPerCycle = 200 +AuctionHouseBot.ConsiderOnlyBotAuctions = 0 +AuctionHouseBot.DuplicatesCount = 0 +AuctionHouseBot.DivisibleStacks = 0 +AuctionHouseBot.ElapsingTimeClass = 1 ############################################################################### # AUCTION HOUSE BOT FILTERS PART 1 @@ -77,6 +145,10 @@ AuctionHouseBot.ItemsPerCycle = 200 # Include misc. Trade Goods. # Default 0 (False) # +# AuctionHouseBot.ProfessionItems +# Include items that are necessary for professions +# Default 0 (False) +# # AuctionHouseBot.Bonding_types # Indicates which bonding types to allow seller to put up for auction # No_Bind @@ -90,10 +162,6 @@ AuctionHouseBot.ItemsPerCycle = 200 # Bind_Quest_Item # Default 0 (False) # -# AuctionHouseBot.DisableBeta_PTR_Unused -# Disable certain items that are usually unavailable to Players -# Default 0 (False) -# # AuctionHouseBot.DisablePermEnchant # Disable Items with a Permanent Enchantment # Default 0 (False) @@ -141,12 +209,12 @@ AuctionHouseBot.LootItems = 1 AuctionHouseBot.LootTradeGoods = 1 AuctionHouseBot.OtherItems = 0 AuctionHouseBot.OtherTradeGoods = 0 +AuctionHouseBot.ProfessionItems = 0 AuctionHouseBot.No_Bind = 1 AuctionHouseBot.Bind_When_Picked_Up = 0 AuctionHouseBot.Bind_When_Equipped = 1 AuctionHouseBot.Bind_When_Use = 1 AuctionHouseBot.Bind_Quest_Item = 0 -AuctionHouseBot.DisableBeta_PTR_Unused = 0 AuctionHouseBot.DisablePermEnchant = 0 AuctionHouseBot.DisableConjured = 0 AuctionHouseBot.DisableGems = 0 @@ -182,6 +250,10 @@ AuctionHouseBot.DisableDruidItems = 0 ############################################################################### # AUCTION HOUSE BOT FILTERS PART 3 # +# AuctionHouseBot.DisabledItems +# Prevent Seller from listing specific item(s) +# (not used anymore, see table "mod_auctionhousebot_disabled_items") +# # AuctionHouseBot.DisableItemsBelowLevel # Prevent Seller from listing Items below this Level # Default 0 (Off) @@ -264,3 +336,15 @@ AuctionHouseBot.DisableItemsBelowReqSkillRank = 0 AuctionHouseBot.DisableItemsAboveReqSkillRank = 0 AuctionHouseBot.DisableTGsBelowReqSkillRank = 0 AuctionHouseBot.DisableTGsAboveReqSkillRank = 0 + +############################################################################### +# AUCTION HOUSE BOT FILTERS PART 4 +# +# AuctionHouseBot.SellerWhiteList +# Bypass the values of the disabled items table and only allows selling of the selected items +# Values here must be the item template id separated with a comma (eg "1, 2, 3") +# Default "" (Empty) +# +############################################################################### + +AuctionHouseBot.SellerWhiteList = "" diff --git a/data/sql/db-world/auctionhousebot_professionItems.sql b/data/sql/db-world/auctionhousebot_professionItems.sql new file mode 100644 index 00000000..6e8077f0 --- /dev/null +++ b/data/sql/db-world/auctionhousebot_professionItems.sql @@ -0,0 +1,3723 @@ +-- phpMyAdmin SQL Dump +-- version 5.2.1 +-- https://www.phpmyadmin.net/ +-- +-- Generation Time: Oct 02, 2024 at 04:47 PM +-- Server version: 8.3.0 +-- PHP Version: 8.3.11 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- Database: `acore_world` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `auctionhousebot_professionItems` +-- + +CREATE TABLE `auctionhousebot_professionItems` ( + `Entry` int NOT NULL, + `Item` int NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Dumping data for table `auctionhousebot_professionItems` +-- + +INSERT INTO `auctionhousebot_professionItems` (`Entry`, `Item`) VALUES +(1, 2318), +(2, 2320), +(3, 2302), +(4, 2304), +(5, 2303), +(6, 2307), +(7, 2321), +(8, 2308), +(9, 2300), +(10, 2309), +(11, 2310), +(12, 2324), +(13, 2311), +(14, 4231), +(15, 2312), +(16, 2319), +(17, 2313), +(18, 2314), +(19, 4340), +(20, 2315), +(21, 2316), +(22, 2317), +(23, 2449), +(24, 765), +(25, 3371), +(26, 2454), +(27, 2447), +(28, 118), +(29, 785), +(30, 2455), +(31, 2456), +(32, 3355), +(33, 2452), +(34, 3372), +(35, 3390), +(36, 2458), +(37, 2450), +(38, 2459), +(39, 2460), +(40, 858), +(41, 2996), +(42, 2568), +(43, 2569), +(44, 2570), +(45, 2604), +(46, 2572), +(47, 2575), +(48, 2576), +(49, 6260), +(50, 2577), +(51, 2578), +(52, 2605), +(53, 2579), +(54, 2580), +(55, 2997), +(56, 2582), +(57, 2583), +(58, 2584), +(59, 2585), +(60, 2587), +(61, 2770), +(62, 2840), +(63, 2775), +(64, 2842), +(65, 3576), +(66, 2841), +(67, 2835), +(68, 2862), +(69, 2851), +(70, 2852), +(71, 2853), +(72, 3470), +(73, 2854), +(74, 2836), +(75, 2863), +(76, 2857), +(77, 1210), +(78, 2864), +(79, 2865), +(80, 2866), +(81, 2867), +(82, 3478), +(83, 2868), +(84, 2869), +(85, 2838), +(86, 2871), +(87, 1206), +(88, 1705), +(89, 5500), +(90, 2870), +(91, 2880), +(92, 2589), +(93, 2844), +(94, 2845), +(95, 2847), +(96, 2848), +(97, 2849), +(98, 2850), +(99, 2934), +(100, 2592), +(101, 3239), +(102, 3240), +(103, 3241), +(104, 3382), +(105, 3383), +(106, 3384), +(107, 3820), +(108, 3385), +(109, 1288), +(110, 2453), +(111, 3386), +(112, 8839), +(113, 8845), +(114, 8925), +(115, 3387), +(116, 3388), +(117, 3389), +(118, 3356), +(119, 3391), +(120, 2457), +(121, 818), +(122, 3487), +(123, 774), +(124, 3488), +(125, 3489), +(126, 3466), +(127, 3490), +(128, 3491), +(129, 3575), +(130, 3492), +(131, 2771), +(132, 2772), +(133, 2776), +(134, 3577), +(135, 3469), +(136, 3471), +(137, 3472), +(138, 3473), +(139, 3474), +(140, 3480), +(141, 3481), +(142, 3482), +(143, 3483), +(144, 3484), +(145, 5498), +(146, 3485), +(147, 3486), +(148, 929), +(149, 3818), +(150, 3823), +(151, 3369), +(152, 3824), +(153, 3821), +(154, 3825), +(155, 3357), +(156, 3826), +(157, 3827), +(158, 3358), +(159, 3828), +(160, 3819), +(161, 3829), +(162, 3848), +(163, 4234), +(164, 3849), +(165, 1529), +(166, 3850), +(167, 3851), +(168, 3852), +(169, 3859), +(170, 3853), +(171, 3854), +(172, 3855), +(173, 3864), +(174, 3856), +(175, 3835), +(176, 3836), +(177, 3837), +(178, 3840), +(179, 3841), +(180, 3842), +(181, 3843), +(182, 4255), +(183, 3844), +(184, 3845), +(185, 3846), +(186, 3847), +(187, 3857), +(188, 4237), +(189, 4238), +(190, 4239), +(191, 4240), +(192, 4241), +(193, 4242), +(194, 3719), +(195, 4243), +(196, 4244), +(197, 4246), +(198, 4247), +(199, 5373), +(200, 4248), +(201, 4233), +(202, 4249), +(203, 4250), +(204, 4251), +(205, 4252), +(206, 3182), +(207, 4253), +(208, 5637), +(209, 4254), +(210, 4236), +(211, 4256), +(212, 7071), +(213, 4257), +(214, 4258), +(215, 4259), +(216, 4291), +(217, 4260), +(218, 4262), +(219, 4096), +(220, 5633), +(221, 4264), +(222, 4265), +(223, 4305), +(224, 4245), +(225, 783), +(226, 4289), +(227, 4232), +(228, 4235), +(229, 4306), +(230, 4307), +(231, 4308), +(232, 4309), +(233, 4310), +(234, 4311), +(235, 4312), +(236, 4313), +(237, 4314), +(238, 4315), +(239, 4316), +(240, 4317), +(241, 4318), +(242, 4319), +(243, 4320), +(244, 4321), +(245, 4337), +(246, 4322), +(247, 4323), +(248, 4324), +(249, 4325), +(250, 4326), +(251, 4339), +(252, 4327), +(253, 4328), +(254, 4329), +(255, 4338), +(256, 4330), +(257, 4331), +(258, 4341), +(259, 4332), +(260, 4333), +(261, 4334), +(262, 4342), +(263, 4335), +(264, 2325), +(265, 4336), +(266, 4343), +(267, 4344), +(268, 4357), +(269, 4358), +(270, 8067), +(271, 4359), +(272, 4360), +(273, 4361), +(274, 4399), +(275, 4362), +(276, 4363), +(277, 4401), +(278, 4364), +(279, 8068), +(280, 4365), +(281, 4366), +(282, 159), +(283, 4367), +(284, 4368), +(285, 4369), +(286, 4404), +(287, 4370), +(288, 4371), +(289, 4400), +(290, 4372), +(291, 4373), +(292, 4374), +(293, 4375), +(294, 4402), +(295, 4376), +(296, 4377), +(297, 4378), +(298, 8069), +(299, 4379), +(300, 4380), +(301, 4381), +(302, 4382), +(303, 4383), +(304, 4384), +(305, 4385), +(306, 4386), +(307, 4387), +(308, 4388), +(309, 4403), +(310, 10558), +(311, 4389), +(312, 4390), +(313, 4391), +(314, 4392), +(315, 4393), +(316, 4394), +(317, 4395), +(318, 4396), +(319, 7191), +(320, 4397), +(321, 10505), +(322, 4398), +(323, 4405), +(324, 4406), +(325, 4407), +(326, 4461), +(327, 4455), +(328, 4456), +(329, 3164), +(330, 4596), +(331, 3858), +(332, 4623), +(333, 5082), +(334, 5081), +(335, 5507), +(336, 5540), +(337, 5541), +(338, 5542), +(339, 5635), +(340, 5631), +(341, 6370), +(342, 5634), +(343, 5739), +(344, 5762), +(345, 5763), +(346, 5766), +(347, 5770), +(348, 5764), +(349, 5765), +(350, 5784), +(351, 5780), +(352, 5781), +(353, 5785), +(354, 5782), +(355, 5783), +(356, 5957), +(357, 5958), +(358, 5961), +(359, 5962), +(360, 5963), +(361, 5964), +(362, 5965), +(363, 5966), +(364, 5996), +(365, 1710), +(366, 5997), +(367, 6042), +(368, 6043), +(369, 6040), +(370, 6041), +(371, 6051), +(372, 6048), +(373, 6371), +(374, 6049), +(375, 6050), +(376, 6052), +(377, 6214), +(378, 10940), +(379, 38679), +(380, 38766), +(381, 6217), +(382, 10938), +(383, 6218), +(384, 38767), +(385, 38768), +(386, 6219), +(387, 38769), +(388, 38770), +(389, 38771), +(390, 6238), +(391, 6241), +(392, 6239), +(393, 6240), +(394, 6242), +(395, 6243), +(396, 6263), +(397, 6264), +(398, 10978), +(399, 38772), +(400, 38773), +(401, 38774), +(402, 10939), +(403, 38775), +(404, 38776), +(405, 38777), +(406, 38778), +(407, 38779), +(408, 38780), +(409, 38781), +(410, 6338), +(411, 6339), +(412, 6350), +(413, 6358), +(414, 6359), +(415, 6372), +(416, 6373), +(417, 10998), +(418, 38782), +(419, 38783), +(420, 38784), +(421, 38785), +(422, 38786), +(423, 6384), +(424, 6385), +(425, 6470), +(426, 6466), +(427, 6467), +(428, 6471), +(429, 6468), +(430, 6522), +(431, 6662), +(432, 4611), +(433, 4852), +(434, 6709), +(435, 6712), +(436, 6714), +(437, 6730), +(438, 6731), +(439, 6733), +(440, 6786), +(441, 6787), +(442, 6795), +(443, 6796), +(444, 7046), +(445, 7048), +(446, 7050), +(447, 7067), +(448, 7051), +(449, 7070), +(450, 7052), +(451, 7068), +(452, 7069), +(453, 7054), +(454, 7055), +(455, 7057), +(456, 7026), +(457, 7027), +(458, 7047), +(459, 7049), +(460, 7065), +(461, 7053), +(462, 7056), +(463, 7058), +(464, 7059), +(465, 7072), +(466, 7060), +(467, 7061), +(468, 7062), +(469, 7063), +(470, 4304), +(471, 7064), +(472, 7166), +(473, 10026), +(474, 10559), +(475, 9061), +(476, 10560), +(477, 7189), +(478, 7276), +(479, 7277), +(480, 7278), +(481, 7279), +(482, 7280), +(483, 7281), +(484, 7282), +(485, 7286), +(486, 7283), +(487, 7287), +(488, 7284), +(489, 7285), +(490, 7348), +(491, 7349), +(492, 7352), +(493, 7358), +(494, 7359), +(495, 7371), +(496, 7372), +(497, 7373), +(498, 7374), +(499, 7392), +(500, 7375), +(501, 7377), +(502, 7378), +(503, 7386), +(504, 7387), +(505, 10285), +(506, 7390), +(507, 7391), +(508, 814), +(509, 7506), +(510, 6530), +(511, 6533), +(512, 7148), +(513, 7913), +(514, 7914), +(515, 7915), +(516, 7916), +(517, 7917), +(518, 7963), +(519, 7912), +(520, 7964), +(521, 7966), +(522, 7965), +(523, 3860), +(524, 7918), +(525, 7919), +(526, 7920), +(527, 7921), +(528, 7922), +(529, 7924), +(530, 6037), +(531, 7967), +(532, 7925), +(533, 7926), +(534, 7927), +(535, 7928), +(536, 7909), +(537, 7938), +(538, 7929), +(539, 7930), +(540, 7931), +(541, 7969), +(542, 7932), +(543, 7933), +(544, 7934), +(545, 7077), +(546, 7935), +(547, 7910), +(548, 7971), +(549, 7939), +(550, 7936), +(551, 7937), +(552, 7955), +(553, 7956), +(554, 7957), +(555, 7958), +(556, 7941), +(557, 7942), +(558, 7943), +(559, 7945), +(560, 7075), +(561, 7954), +(562, 7944), +(563, 7081), +(564, 7961), +(565, 7946), +(566, 7972), +(567, 7959), +(568, 7947), +(569, 7960), +(570, 7911), +(571, 8169), +(572, 8150), +(573, 8172), +(574, 8173), +(575, 8174), +(576, 8175), +(577, 8176), +(578, 8167), +(579, 8343), +(580, 8187), +(581, 8189), +(582, 8192), +(583, 8198), +(584, 8151), +(585, 8200), +(586, 8154), +(587, 8203), +(588, 8153), +(589, 8210), +(590, 8201), +(591, 8205), +(592, 8204), +(593, 8211), +(594, 8214), +(595, 8193), +(596, 8195), +(597, 8191), +(598, 8209), +(599, 8185), +(600, 8197), +(601, 8152), +(602, 8202), +(603, 8216), +(604, 8207), +(605, 8213), +(606, 8206), +(607, 8208), +(608, 8212), +(609, 8215), +(610, 8165), +(611, 8347), +(612, 8345), +(613, 7079), +(614, 8346), +(615, 8348), +(616, 17056), +(617, 8349), +(618, 8367), +(619, 6149), +(620, 8949), +(621, 8951), +(622, 4625), +(623, 8956), +(624, 9030), +(625, 8831), +(626, 9036), +(627, 9060), +(628, 9260), +(629, 8838), +(630, 3928), +(631, 9144), +(632, 9262), +(633, 9149), +(634, 8836), +(635, 9154), +(636, 9155), +(637, 9172), +(638, 9179), +(639, 9088), +(640, 9187), +(641, 9197), +(642, 8846), +(643, 9206), +(644, 9210), +(645, 9264), +(646, 9224), +(647, 9233), +(648, 9366), +(649, 10045), +(650, 10046), +(651, 10047), +(652, 10048), +(653, 9998), +(654, 9999), +(655, 10001), +(656, 10002), +(657, 10003), +(658, 10004), +(659, 10007), +(660, 10008), +(661, 10009), +(662, 6261), +(663, 10056), +(664, 10010), +(665, 10011), +(666, 10052), +(667, 10050), +(668, 10018), +(669, 10286), +(670, 10019), +(671, 10020), +(672, 10042), +(673, 10021), +(674, 10023), +(675, 10024), +(676, 10027), +(677, 10054), +(678, 10028), +(679, 10053), +(680, 10029), +(681, 10051), +(682, 10290), +(683, 10055), +(684, 4589), +(685, 10030), +(686, 10031), +(687, 10032), +(688, 10033), +(689, 10034), +(690, 10025), +(691, 10038), +(692, 10044), +(693, 10035), +(694, 10039), +(695, 10040), +(696, 10041), +(697, 10036), +(698, 10423), +(699, 10421), +(700, 10507), +(701, 10499), +(702, 10498), +(703, 10500), +(704, 10508), +(705, 10512), +(706, 10546), +(707, 10561), +(708, 10514), +(709, 10592), +(710, 10501), +(711, 10510), +(712, 10502), +(713, 10518), +(714, 10506), +(715, 10503), +(716, 10562), +(717, 10548), +(718, 10513), +(719, 10504), +(720, 10576), +(721, 10648), +(722, 10647), +(723, 10644), +(724, 10577), +(725, 10542), +(726, 10543), +(727, 10580), +(728, 10585), +(729, 10586), +(730, 10587), +(731, 10588), +(732, 12808), +(733, 10645), +(734, 10646), +(735, 10713), +(736, 10545), +(737, 10716), +(738, 10719), +(739, 10720), +(740, 10721), +(741, 10723), +(742, 10724), +(743, 10725), +(744, 10726), +(745, 10727), +(746, 38787), +(747, 38788), +(748, 38789), +(749, 38790), +(750, 38791), +(751, 38792), +(752, 11083), +(753, 38793), +(754, 11084), +(755, 38794), +(756, 11082), +(757, 38795), +(758, 38796), +(759, 38797), +(760, 38798), +(761, 38799), +(762, 38800), +(763, 38801), +(764, 38802), +(765, 38803), +(766, 38804), +(767, 11128), +(768, 11130), +(769, 11134), +(770, 38805), +(771, 11138), +(772, 38806), +(773, 38807), +(774, 38808), +(775, 38809), +(776, 38810), +(777, 38811), +(778, 38812), +(779, 38813), +(780, 38814), +(781, 38815), +(782, 11135), +(783, 11137), +(784, 38816), +(785, 38817), +(786, 38818), +(787, 38819), +(788, 11139), +(789, 38820), +(790, 38821), +(791, 38822), +(792, 38823), +(793, 38824), +(794, 11144), +(795, 11145), +(796, 38825), +(797, 11174), +(798, 38826), +(799, 38827), +(800, 38828), +(801, 38829), +(802, 38830), +(803, 38831), +(804, 38832), +(805, 38833), +(806, 38834), +(807, 38835), +(808, 38836), +(809, 11177), +(810, 38837), +(811, 7078), +(812, 38838), +(813, 11175), +(814, 11176), +(815, 38839), +(816, 38840), +(817, 38841), +(818, 38842), +(819, 11178), +(820, 38843), +(821, 38844), +(822, 38845), +(823, 38846), +(824, 38847), +(825, 38848), +(826, 38849), +(827, 38850), +(828, 38851), +(829, 4470), +(830, 11287), +(831, 11288), +(832, 11291), +(833, 11289), +(834, 11290), +(835, 11370), +(836, 11371), +(837, 8217), +(838, 8218), +(839, 11590), +(840, 11608), +(841, 11606), +(842, 11607), +(843, 11605), +(844, 11604), +(845, 14343), +(846, 11811), +(847, 11825), +(848, 11826), +(849, 12190), +(850, 12259), +(851, 12260), +(852, 10620), +(853, 12359), +(854, 12365), +(855, 12644), +(856, 14047), +(857, 12643), +(858, 12404), +(859, 12361), +(860, 12405), +(861, 12406), +(862, 12408), +(863, 12416), +(864, 8170), +(865, 12428), +(866, 12424), +(867, 12415), +(868, 12425), +(869, 12655), +(870, 12803), +(871, 12364), +(872, 12624), +(873, 7076), +(874, 12645), +(875, 12409), +(876, 12410), +(877, 12418), +(878, 12631), +(879, 12419), +(880, 12426), +(881, 12427), +(882, 12417), +(883, 12360), +(884, 7080), +(885, 12625), +(886, 12632), +(887, 12414), +(888, 12422), +(889, 12610), +(890, 12611), +(891, 12662), +(892, 12628), +(893, 12800), +(894, 12633), +(895, 12420), +(896, 12612), +(897, 12799), +(898, 12636), +(899, 12640), +(900, 12429), +(901, 12613), +(902, 12614), +(903, 12639), +(904, 12620), +(905, 12619), +(906, 12618), +(907, 12641), +(908, 12764), +(909, 12769), +(910, 12772), +(911, 12773), +(912, 12774), +(913, 12775), +(914, 12804), +(915, 12776), +(916, 12777), +(917, 12779), +(918, 12781), +(919, 12792), +(920, 12782), +(921, 12795), +(922, 12802), +(923, 12809), +(924, 12810), +(925, 12796), +(926, 12811), +(927, 12790), +(928, 12798), +(929, 12797), +(930, 12794), +(931, 12784), +(932, 12783), +(933, 16202), +(934, 12363), +(935, 13422), +(936, 13423), +(937, 13442), +(938, 13443), +(939, 13445), +(940, 13463), +(941, 13466), +(942, 13447), +(943, 13464), +(944, 13465), +(945, 13446), +(946, 13453), +(947, 7082), +(948, 13455), +(949, 13452), +(950, 13467), +(951, 13462), +(952, 13454), +(953, 13457), +(954, 13456), +(955, 13458), +(956, 13461), +(957, 13459), +(958, 13460), +(959, 13444), +(960, 25867), +(961, 25868), +(962, 22794), +(963, 23571), +(964, 13503), +(965, 13506), +(966, 13468), +(967, 13510), +(968, 13511), +(969, 13512), +(970, 13513), +(971, 14048), +(972, 14341), +(973, 13856), +(974, 13869), +(975, 13868), +(976, 14046), +(977, 14227), +(978, 13858), +(979, 13857), +(980, 14042), +(981, 13860), +(982, 14143), +(983, 13870), +(984, 14043), +(985, 14142), +(986, 14100), +(987, 14101), +(988, 14141), +(989, 13863), +(990, 14044), +(991, 14256), +(992, 14107), +(993, 14103), +(994, 14132), +(995, 14134), +(996, 13864), +(997, 13871), +(998, 14045), +(999, 14136), +(1000, 14108), +(1001, 13865), +(1002, 14104), +(1003, 14342), +(1004, 14137), +(1005, 14144), +(1006, 14111), +(1007, 13866), +(1008, 14155), +(1009, 14128), +(1010, 14138), +(1011, 14139), +(1012, 13867), +(1013, 14130), +(1014, 14106), +(1015, 14140), +(1016, 14112), +(1017, 13926), +(1018, 14146), +(1019, 14344), +(1020, 17012), +(1021, 14156), +(1022, 14154), +(1023, 14152), +(1024, 14153), +(1025, 8171), +(1026, 15409), +(1027, 15407), +(1028, 15408), +(1029, 15077), +(1030, 15083), +(1031, 15412), +(1032, 15045), +(1033, 15076), +(1034, 15084), +(1035, 15074), +(1036, 15414), +(1037, 15047), +(1038, 15091), +(1039, 15564), +(1040, 15054), +(1041, 15046), +(1042, 15061), +(1043, 15067), +(1044, 15073), +(1045, 15078), +(1046, 15092), +(1047, 15071), +(1048, 15057), +(1049, 15419), +(1050, 15064), +(1051, 15082), +(1052, 15086), +(1053, 15093), +(1054, 15072), +(1055, 15069), +(1056, 15079), +(1057, 15053), +(1058, 15415), +(1059, 15048), +(1060, 15060), +(1061, 15056), +(1062, 15065), +(1063, 15075), +(1064, 15094), +(1065, 15087), +(1066, 15417), +(1067, 15063), +(1068, 15416), +(1069, 15050), +(1070, 15066), +(1071, 15070), +(1072, 15080), +(1073, 15049), +(1074, 15058), +(1075, 15095), +(1076, 15088), +(1077, 15410), +(1078, 15138), +(1079, 15051), +(1080, 15059), +(1081, 15062), +(1082, 15085), +(1083, 15081), +(1084, 15055), +(1085, 15090), +(1086, 15096), +(1087, 15068), +(1088, 15141), +(1089, 15052), +(1090, 15802), +(1091, 15846), +(1092, 15869), +(1093, 15870), +(1094, 15871), +(1095, 15872), +(1096, 15992), +(1097, 15994), +(1098, 15993), +(1099, 15995), +(1100, 15996), +(1101, 15999), +(1102, 16000), +(1103, 16004), +(1104, 16005), +(1105, 15997), +(1106, 16023), +(1107, 16006), +(1108, 16009), +(1109, 16008), +(1110, 16022), +(1111, 16040), +(1112, 16007), +(1113, 38852), +(1114, 38853), +(1115, 16204), +(1116, 16203), +(1117, 38854), +(1118, 38855), +(1119, 38856), +(1120, 38857), +(1121, 38858), +(1122, 38859), +(1123, 38860), +(1124, 38861), +(1125, 38862), +(1126, 38863), +(1127, 38864), +(1128, 38865), +(1129, 38866), +(1130, 38867), +(1131, 38868), +(1132, 38869), +(1133, 38870), +(1134, 38871), +(1135, 38872), +(1136, 38873), +(1137, 38874), +(1138, 38875), +(1139, 16206), +(1140, 16207), +(1141, 17010), +(1142, 17011), +(1143, 16980), +(1144, 16979), +(1145, 16982), +(1146, 16983), +(1147, 16984), +(1148, 16989), +(1149, 16988), +(1150, 17014), +(1151, 17013), +(1152, 11382), +(1153, 17015), +(1154, 17016), +(1155, 17203), +(1156, 17193), +(1157, 17704), +(1158, 17708), +(1159, 38876), +(1160, 17202), +(1161, 17716), +(1162, 17721), +(1163, 17723), +(1164, 18232), +(1165, 18238), +(1166, 18251), +(1167, 18256), +(1168, 18253), +(1169, 38877), +(1170, 38878), +(1171, 18262), +(1172, 18263), +(1173, 18283), +(1174, 18282), +(1175, 18168), +(1176, 18294), +(1177, 18240), +(1178, 18258), +(1179, 18405), +(1180, 18407), +(1181, 18408), +(1182, 18409), +(1183, 18413), +(1184, 18486), +(1185, 18504), +(1186, 11754), +(1187, 18506), +(1188, 18512), +(1189, 18508), +(1190, 12607), +(1191, 18509), +(1192, 18510), +(1193, 12753), +(1194, 18511), +(1195, 18562), +(1196, 18567), +(1197, 17771), +(1198, 9318), +(1199, 9312), +(1200, 9313), +(1201, 18588), +(1202, 18641), +(1203, 18631), +(1204, 18634), +(1205, 18587), +(1206, 18637), +(1207, 18594), +(1208, 18638), +(1209, 18639), +(1210, 18645), +(1211, 18660), +(1212, 18662), +(1213, 18948), +(1214, 18984), +(1215, 18986), +(1216, 19026), +(1217, 19043), +(1218, 19048), +(1219, 19051), +(1220, 19057), +(1221, 19148), +(1222, 19164), +(1223, 19166), +(1224, 19167), +(1225, 19170), +(1226, 19168), +(1227, 19169), +(1228, 19047), +(1229, 19050), +(1230, 19056), +(1231, 19059), +(1232, 19156), +(1233, 19165), +(1234, 19044), +(1235, 19049), +(1236, 19052), +(1237, 19058), +(1238, 19149), +(1239, 19157), +(1240, 19162), +(1241, 19163), +(1242, 38879), +(1243, 38880), +(1244, 38881), +(1245, 38882), +(1246, 38883), +(1247, 38884), +(1248, 19726), +(1249, 19682), +(1250, 19683), +(1251, 19684), +(1252, 19767), +(1253, 19685), +(1254, 19686), +(1255, 19687), +(1256, 19768), +(1257, 19688), +(1258, 19689), +(1259, 19774), +(1260, 19690), +(1261, 19691), +(1262, 19692), +(1263, 19693), +(1264, 19694), +(1265, 19695), +(1266, 12938), +(1267, 19943), +(1268, 19931), +(1269, 19999), +(1270, 19998), +(1271, 20007), +(1272, 20002), +(1273, 20008), +(1274, 20004), +(1275, 20039), +(1276, 20295), +(1277, 20296), +(1278, 20381), +(1279, 20380), +(1280, 20500), +(1281, 20498), +(1282, 20481), +(1283, 20480), +(1284, 20479), +(1285, 20501), +(1286, 20476), +(1287, 20477), +(1288, 20478), +(1289, 20520), +(1290, 20538), +(1291, 20539), +(1292, 20537), +(1293, 20549), +(1294, 20551), +(1295, 20550), +(1296, 20575), +(1297, 22448), +(1298, 22446), +(1299, 21886), +(1300, 38885), +(1301, 38886), +(1302, 38887), +(1303, 38888), +(1304, 38889), +(1305, 22451), +(1306, 38890), +(1307, 38891), +(1308, 38892), +(1309, 38893), +(1310, 22456), +(1311, 38894), +(1312, 22452), +(1313, 38895), +(1314, 17034), +(1315, 20744), +(1316, 20745), +(1317, 17035), +(1318, 20746), +(1319, 20747), +(1320, 20750), +(1321, 20749), +(1322, 20748), +(1323, 20816), +(1324, 20817), +(1325, 20818), +(1326, 20821), +(1327, 20820), +(1328, 20823), +(1329, 20826), +(1330, 20827), +(1331, 20828), +(1332, 20831), +(1333, 20832), +(1334, 20833), +(1335, 20830), +(1336, 20907), +(1337, 20906), +(1338, 20909), +(1339, 20950), +(1340, 20954), +(1341, 20955), +(1342, 20956), +(1343, 20963), +(1344, 20958), +(1345, 20966), +(1346, 20959), +(1347, 20960), +(1348, 20961), +(1349, 20967), +(1350, 21277), +(1351, 21340), +(1352, 21341), +(1353, 21342), +(1354, 21546), +(1355, 21278), +(1356, 21154), +(1357, 21542), +(1358, 21558), +(1359, 21559), +(1360, 21557), +(1361, 21589), +(1362, 21590), +(1363, 21592), +(1364, 21571), +(1365, 21574), +(1366, 21576), +(1367, 21714), +(1368, 21716), +(1369, 21718), +(1370, 21569), +(1371, 21570), +(1372, 21877), +(1373, 21840), +(1374, 21841), +(1375, 22445), +(1376, 21842), +(1377, 21881), +(1378, 21843), +(1379, 21882), +(1380, 21844), +(1381, 21885), +(1382, 21845), +(1383, 24271), +(1384, 21884), +(1385, 21846), +(1386, 21847), +(1387, 21848), +(1388, 21858), +(1389, 24272), +(1390, 21869), +(1391, 21870), +(1392, 21871), +(1393, 21872), +(1394, 21873), +(1395, 21874), +(1396, 22457), +(1397, 21875), +(1398, 21876), +(1399, 21849), +(1400, 21850), +(1401, 21887), +(1402, 21851), +(1403, 21852), +(1404, 21853), +(1405, 21854), +(1406, 21855), +(1407, 21859), +(1408, 21860), +(1409, 21861), +(1410, 21862), +(1411, 21863), +(1412, 21864), +(1413, 21865), +(1414, 21866), +(1415, 21867), +(1416, 21868), +(1417, 21748), +(1418, 21756), +(1419, 20964), +(1420, 21758), +(1421, 21755), +(1422, 21752), +(1423, 20969), +(1424, 21760), +(1425, 21763), +(1426, 21764), +(1427, 21765), +(1428, 21754), +(1429, 21753), +(1430, 21766), +(1431, 21769), +(1432, 21767), +(1433, 21768), +(1434, 21774), +(1435, 21775), +(1436, 21790), +(1437, 21777), +(1438, 21778), +(1439, 21791), +(1440, 18335), +(1441, 21784), +(1442, 21789), +(1443, 21792), +(1444, 21929), +(1445, 21779), +(1446, 21793), +(1447, 21780), +(1448, 21931), +(1449, 21932), +(1450, 21933), +(1451, 21934), +(1452, 22202), +(1453, 22197), +(1454, 22203), +(1455, 22198), +(1456, 22196), +(1457, 22195), +(1458, 22194), +(1459, 22191), +(1460, 22246), +(1461, 22248), +(1462, 22249), +(1463, 11040), +(1464, 22251), +(1465, 22252), +(1466, 22385), +(1467, 22384), +(1468, 20725), +(1469, 22383), +(1470, 38896), +(1471, 38897), +(1472, 22447), +(1473, 38898), +(1474, 38899), +(1475, 38900), +(1476, 38901), +(1477, 22449), +(1478, 38902), +(1479, 38903), +(1480, 38904), +(1481, 38905), +(1482, 38906), +(1483, 22573), +(1484, 22574), +(1485, 22572), +(1486, 22578), +(1487, 38907), +(1488, 38908), +(1489, 38909), +(1490, 37603), +(1491, 22450), +(1492, 38910), +(1493, 38911), +(1494, 34054), +(1495, 38912), +(1496, 38913), +(1497, 38914), +(1498, 38915), +(1499, 38917), +(1500, 38918), +(1501, 38919), +(1502, 38920), +(1503, 38921), +(1504, 38922), +(1505, 38923), +(1506, 38924), +(1507, 38925), +(1508, 38926), +(1509, 38927), +(1510, 22791), +(1511, 22521), +(1512, 22792), +(1513, 22522), +(1514, 22460), +(1515, 22459), +(1516, 22682), +(1517, 22654), +(1518, 22652), +(1519, 22658), +(1520, 22655), +(1521, 22660), +(1522, 22661), +(1523, 22662), +(1524, 22663), +(1525, 22664), +(1526, 22666), +(1527, 22665), +(1528, 22669), +(1529, 22670), +(1530, 22671), +(1531, 22728), +(1532, 22762), +(1533, 22763), +(1534, 22764), +(1535, 22759), +(1536, 22760), +(1537, 22761), +(1538, 22756), +(1539, 22757), +(1540, 22758), +(1541, 22787), +(1542, 22785), +(1543, 22823), +(1544, 22824), +(1545, 22786), +(1546, 22825), +(1547, 22826), +(1548, 22790), +(1549, 22827), +(1550, 22789), +(1551, 22828), +(1552, 22829), +(1553, 22830), +(1554, 22831), +(1555, 22871), +(1556, 22832), +(1557, 22833), +(1558, 22834), +(1559, 22835), +(1560, 22836), +(1561, 22837), +(1562, 22838), +(1563, 22839), +(1564, 22840), +(1565, 22793), +(1566, 22841), +(1567, 22842), +(1568, 22844), +(1569, 22845), +(1570, 22846), +(1571, 22847), +(1572, 22848), +(1573, 22849), +(1574, 22850), +(1575, 22851), +(1576, 22853), +(1577, 22854), +(1578, 22861), +(1579, 22866), +(1580, 23077), +(1581, 23094), +(1582, 23095), +(1583, 23096), +(1584, 23097), +(1585, 23098), +(1586, 23099), +(1587, 23100), +(1588, 23101), +(1589, 23079), +(1590, 23103), +(1591, 23104), +(1592, 23105), +(1593, 23106), +(1594, 23107), +(1595, 23108), +(1596, 23109), +(1597, 23110), +(1598, 23111), +(1599, 23112), +(1600, 23113), +(1601, 23114), +(1602, 23115), +(1603, 23116), +(1604, 23117), +(1605, 23118), +(1606, 23119), +(1607, 23120), +(1608, 23121), +(1609, 23424), +(1610, 23445), +(1611, 23425), +(1612, 23446), +(1613, 23427), +(1614, 23447), +(1615, 23448), +(1616, 23426), +(1617, 23449), +(1618, 23482), +(1619, 23484), +(1620, 23487), +(1621, 23488), +(1622, 23489), +(1623, 23493), +(1624, 23491), +(1625, 23494), +(1626, 23490), +(1627, 23497), +(1628, 23498), +(1629, 23499), +(1630, 23502), +(1631, 23503), +(1632, 23504), +(1633, 23505), +(1634, 23506), +(1635, 23508), +(1636, 23507), +(1637, 23573), +(1638, 23510), +(1639, 23509), +(1640, 23511), +(1641, 23512), +(1642, 23515), +(1643, 23516), +(1644, 23514), +(1645, 23513), +(1646, 23517), +(1647, 23518), +(1648, 23519), +(1649, 23572), +(1650, 23532), +(1651, 23524), +(1652, 23523), +(1653, 23525), +(1654, 23520), +(1655, 23521), +(1656, 23522), +(1657, 23526), +(1658, 23527), +(1659, 23528), +(1660, 23529), +(1661, 23530), +(1662, 23531), +(1663, 23533), +(1664, 23534), +(1665, 23535), +(1666, 23536), +(1667, 23537), +(1668, 23538), +(1669, 23539), +(1670, 23540), +(1671, 23541), +(1672, 23542), +(1673, 23543), +(1674, 23544), +(1675, 23546), +(1676, 23554), +(1677, 23555), +(1678, 23556), +(1679, 23575), +(1680, 23576), +(1681, 23781), +(1682, 23782), +(1683, 23783), +(1684, 23784), +(1685, 23785), +(1686, 23786), +(1687, 23787), +(1688, 23736), +(1689, 23737), +(1690, 23742), +(1691, 23746), +(1692, 23747), +(1693, 23439), +(1694, 23748), +(1695, 23793), +(1696, 23758), +(1697, 23761), +(1698, 23762), +(1699, 23441), +(1700, 23763), +(1701, 23764), +(1702, 23440), +(1703, 23765), +(1704, 23438), +(1705, 23766), +(1706, 23767), +(1707, 23768), +(1708, 23769), +(1709, 23770), +(1710, 23771), +(1711, 23772), +(1712, 34504), +(1713, 23774), +(1714, 36913), +(1715, 41163), +(1716, 39681), +(1717, 23775), +(1718, 23819), +(1719, 23821), +(1720, 23820), +(1721, 33092), +(1722, 33093), +(1723, 23824), +(1724, 17020), +(1725, 23826), +(1726, 23827), +(1727, 23831), +(1728, 23836), +(1729, 23838), +(1730, 23839), +(1731, 23841), +(1732, 23835), +(1733, 23825), +(1734, 23832), +(1735, 23437), +(1736, 23828), +(1737, 23436), +(1738, 23829), +(1739, 24074), +(1740, 24075), +(1741, 24076), +(1742, 31079), +(1743, 24077), +(1744, 24078), +(1745, 24079), +(1746, 24080), +(1747, 24082), +(1748, 24085), +(1749, 24086), +(1750, 24087), +(1751, 24088), +(1752, 24089), +(1753, 24092), +(1754, 24093), +(1755, 24095), +(1756, 24097), +(1757, 24098), +(1758, 24106), +(1759, 24110), +(1760, 24114), +(1761, 24116), +(1762, 24117), +(1763, 24121), +(1764, 24122), +(1765, 24123), +(1766, 24124), +(1767, 24125), +(1768, 24126), +(1769, 24127), +(1770, 24128), +(1771, 24027), +(1772, 24028), +(1773, 24029), +(1774, 24030), +(1775, 24031), +(1776, 24032), +(1777, 24036), +(1778, 24033), +(1779, 24037), +(1780, 24039), +(1781, 24047), +(1782, 24048), +(1783, 24051), +(1784, 24050), +(1785, 24052), +(1786, 24053), +(1787, 24054), +(1788, 24055), +(1789, 24056), +(1790, 24057), +(1791, 24058), +(1792, 24059), +(1793, 24060), +(1794, 24061), +(1795, 24062), +(1796, 24066), +(1797, 24065), +(1798, 24067), +(1799, 24035), +(1800, 24273), +(1801, 24275), +(1802, 24274), +(1803, 24276), +(1804, 24249), +(1805, 24250), +(1806, 24251), +(1807, 24252), +(1808, 24253), +(1809, 24254), +(1810, 24255), +(1811, 24256), +(1812, 24257), +(1813, 24258), +(1814, 24259), +(1815, 24260), +(1816, 24261), +(1817, 24262), +(1818, 24263), +(1819, 24264), +(1820, 24266), +(1821, 24267), +(1822, 24270), +(1823, 24268), +(1824, 24269), +(1825, 25438), +(1826, 25439), +(1827, 25498), +(1828, 23559), +(1829, 25521), +(1830, 25649), +(1831, 25650), +(1832, 25651), +(1833, 25652), +(1834, 25653), +(1835, 25700), +(1836, 25654), +(1837, 25655), +(1838, 25656), +(1839, 25657), +(1840, 25662), +(1841, 25661), +(1842, 25660), +(1843, 25659), +(1844, 25669), +(1845, 25670), +(1846, 25668), +(1847, 25671), +(1848, 25673), +(1849, 25674), +(1850, 25675), +(1851, 25676), +(1852, 25679), +(1853, 29539), +(1854, 25680), +(1855, 25681), +(1856, 25683), +(1857, 25682), +(1858, 25707), +(1859, 25685), +(1860, 25686), +(1861, 25687), +(1862, 25708), +(1863, 25689), +(1864, 25690), +(1865, 25691), +(1866, 25699), +(1867, 25695), +(1868, 25697), +(1869, 25696), +(1870, 25694), +(1871, 25692), +(1872, 25693), +(1873, 25843), +(1874, 25844), +(1875, 25845), +(1876, 22461), +(1877, 22462), +(1878, 22463), +(1879, 25880), +(1880, 25881), +(1881, 25882), +(1882, 25883), +(1883, 25884), +(1884, 25886), +(1885, 25896), +(1886, 25897), +(1887, 25898), +(1888, 25899), +(1889, 25901), +(1890, 25890), +(1891, 25893), +(1892, 25894), +(1893, 25895), +(1894, 28100), +(1895, 28101), +(1896, 28102), +(1897, 28103), +(1898, 28104), +(1899, 38928), +(1900, 38929), +(1901, 38930), +(1902, 38931), +(1903, 38932), +(1904, 38933), +(1905, 38934), +(1906, 38935), +(1907, 38936), +(1908, 38937), +(1909, 38938), +(1910, 38939), +(1911, 38940), +(1912, 38941), +(1913, 38942), +(1914, 38943), +(1915, 38944), +(1916, 38945), +(1917, 38946), +(1918, 28290), +(1919, 23563), +(1920, 23564), +(1921, 28483), +(1922, 28484), +(1923, 28425), +(1924, 28426), +(1925, 28428), +(1926, 28429), +(1927, 28431), +(1928, 28432), +(1929, 28434), +(1930, 28435), +(1931, 28437), +(1932, 28438), +(1933, 28440), +(1934, 28441), +(1935, 28595), +(1936, 28420), +(1937, 28421), +(1938, 29157), +(1939, 29158), +(1940, 29159), +(1941, 29160), +(1942, 29201), +(1943, 29202), +(1944, 29203), +(1945, 29204), +(1946, 29483), +(1947, 29485), +(1948, 29486), +(1949, 29487), +(1950, 29488), +(1951, 29489), +(1952, 29490), +(1953, 29491), +(1954, 29493), +(1955, 29492), +(1956, 29540), +(1957, 29494), +(1958, 29495), +(1959, 29496), +(1960, 29497), +(1961, 29498), +(1962, 29499), +(1963, 29500), +(1964, 29532), +(1965, 29548), +(1966, 29531), +(1967, 29528), +(1968, 29529), +(1969, 29547), +(1970, 29530), +(1971, 29533), +(1972, 29535), +(1973, 29534), +(1974, 29536), +(1975, 29502), +(1976, 29503), +(1977, 29504), +(1978, 29505), +(1979, 29506), +(1980, 29507), +(1981, 29508), +(1982, 29512), +(1983, 29509), +(1984, 29510), +(1985, 29511), +(1986, 29514), +(1987, 29515), +(1988, 29516), +(1989, 29517), +(1990, 29519), +(1991, 29520), +(1992, 29521), +(1993, 29522), +(1994, 29524), +(1995, 29523), +(1996, 29525), +(1997, 29526), +(1998, 29527), +(1999, 29964), +(2000, 29970), +(2001, 29971), +(2002, 29973), +(2003, 29974), +(2004, 29975), +(2005, 30069), +(2006, 30070), +(2007, 30071), +(2008, 30072), +(2009, 30073), +(2010, 30074), +(2011, 30076), +(2012, 30077), +(2013, 30086), +(2014, 30087), +(2015, 30088), +(2016, 30089), +(2017, 30093), +(2018, 30183), +(2019, 23565), +(2020, 28485), +(2021, 28427), +(2022, 28430), +(2023, 28433), +(2024, 28436), +(2025, 28439), +(2026, 28442), +(2027, 30038), +(2028, 30036), +(2029, 30037), +(2030, 30035), +(2031, 30042), +(2032, 30040), +(2033, 30046), +(2034, 30044), +(2035, 30041), +(2036, 30039), +(2037, 30045), +(2038, 30043), +(2039, 30034), +(2040, 30032), +(2041, 30033), +(2042, 30031), +(2043, 30419), +(2044, 30420), +(2045, 30421), +(2046, 30422), +(2047, 30459), +(2048, 30460), +(2049, 30461), +(2050, 30465), +(2051, 30463), +(2052, 30464), +(2053, 30542), +(2054, 30544), +(2055, 30804), +(2056, 30825), +(2057, 30831), +(2058, 30837), +(2059, 30838), +(2060, 30839), +(2061, 24243), +(2062, 31080), +(2063, 31154), +(2064, 31364), +(2065, 31367), +(2066, 31368), +(2067, 31369), +(2068, 31370), +(2069, 31371), +(2070, 31398), +(2071, 31399), +(2072, 31679), +(2073, 31677), +(2074, 31676), +(2075, 31860), +(2076, 31861), +(2077, 31862), +(2078, 31864), +(2079, 31865), +(2080, 31863), +(2081, 31866), +(2082, 31869), +(2083, 31867), +(2084, 31868), +(2085, 32062), +(2086, 32063), +(2087, 32067), +(2088, 32068), +(2089, 32227), +(2090, 32193), +(2091, 32194), +(2092, 32195), +(2093, 32196), +(2094, 32197), +(2095, 32198), +(2096, 32199), +(2097, 32228), +(2098, 32200), +(2099, 32201), +(2100, 32202), +(2101, 32203), +(2102, 32229), +(2103, 32204), +(2104, 32205), +(2105, 32206), +(2106, 32207), +(2107, 32208), +(2108, 32209), +(2109, 32210), +(2110, 32230), +(2111, 32211), +(2112, 32212), +(2113, 32213), +(2114, 32214), +(2115, 32215), +(2116, 32216), +(2117, 32231), +(2118, 32217), +(2119, 32218), +(2120, 32219), +(2121, 32220), +(2122, 32221), +(2123, 32222), +(2124, 32249), +(2125, 32223), +(2126, 32224), +(2127, 32225), +(2128, 32226), +(2129, 32409), +(2130, 32410), +(2131, 32423), +(2132, 32413), +(2133, 32428), +(2134, 32398), +(2135, 32400), +(2136, 32397), +(2137, 32394), +(2138, 32395), +(2139, 32396), +(2140, 32393), +(2141, 32391), +(2142, 32392), +(2143, 32389), +(2144, 32390), +(2145, 32402), +(2146, 32403), +(2147, 32404), +(2148, 32401), +(2149, 32420), +(2150, 32461), +(2151, 24478), +(2152, 24479), +(2153, 32508), +(2154, 32568), +(2155, 32570), +(2156, 32571), +(2157, 32573), +(2158, 32582), +(2159, 32583), +(2160, 32580), +(2161, 32581), +(2162, 32574), +(2163, 32575), +(2164, 32577), +(2165, 32579), +(2166, 32586), +(2167, 32587), +(2168, 32584), +(2169, 32585), +(2170, 32756), +(2171, 32472), +(2172, 32473), +(2173, 32474), +(2174, 32476), +(2175, 32475), +(2176, 32478), +(2177, 32479), +(2178, 32480), +(2179, 32494), +(2180, 32495), +(2181, 32772), +(2182, 32774), +(2183, 32776), +(2184, 27860), +(2185, 32833), +(2186, 32836), +(2187, 32839), +(2188, 32849), +(2189, 32850), +(2190, 32851), +(2191, 32852), +(2192, 33122), +(2193, 33133), +(2194, 33134), +(2195, 33131), +(2196, 33135), +(2197, 33143), +(2198, 33140), +(2199, 33144), +(2200, 38947), +(2201, 27503), +(2202, 33173), +(2203, 33185), +(2204, 33204), +(2205, 33208), +(2206, 38948), +(2207, 33782), +(2208, 33791), +(2209, 20475), +(2210, 32854), +(2211, 34060), +(2212, 34249), +(2213, 34061), +(2214, 34099), +(2215, 25719), +(2216, 34100), +(2217, 34105), +(2218, 38949), +(2219, 34113), +(2220, 34055), +(2221, 36860), +(2222, 38950), +(2223, 38951), +(2224, 38953), +(2225, 35624), +(2226, 38954), +(2227, 38955), +(2228, 35627), +(2229, 38956), +(2230, 38959), +(2231, 38960), +(2232, 38961), +(2233, 38962), +(2234, 34052), +(2235, 38963), +(2236, 38964), +(2237, 38965), +(2238, 34056), +(2239, 38966), +(2240, 38967), +(2241, 38968), +(2242, 35622), +(2243, 38969), +(2244, 44815), +(2245, 35625), +(2246, 38972), +(2247, 38973), +(2248, 38974), +(2249, 38975), +(2250, 38976), +(2251, 38977), +(2252, 38978), +(2253, 38979), +(2254, 38980), +(2255, 38981), +(2256, 38982), +(2257, 38984), +(2258, 38985), +(2259, 38987), +(2260, 38988), +(2261, 38989), +(2262, 38990), +(2263, 38991), +(2264, 38992), +(2265, 34057), +(2266, 38993), +(2267, 35623), +(2268, 38995), +(2269, 38997), +(2270, 34106), +(2271, 34207), +(2272, 34220), +(2273, 34087), +(2274, 34086), +(2275, 34085), +(2276, 34330), +(2277, 34440), +(2278, 34482), +(2279, 34490), +(2280, 37101), +(2281, 39354), +(2282, 1180), +(2283, 35183), +(2284, 35185), +(2285, 35181), +(2286, 35182), +(2287, 35184), +(2288, 34847), +(2289, 34355), +(2290, 34356), +(2291, 34354), +(2292, 35128), +(2293, 34357), +(2294, 34353), +(2295, 34664), +(2296, 34362), +(2297, 34363), +(2298, 34361), +(2299, 34359), +(2300, 34360), +(2301, 34358), +(2302, 34366), +(2303, 34367), +(2304, 34364), +(2305, 34365), +(2306, 34372), +(2307, 34374), +(2308, 34370), +(2309, 34376), +(2310, 34371), +(2311, 34373), +(2312, 34369), +(2313, 34375), +(2314, 34380), +(2315, 34378), +(2316, 34379), +(2317, 34377), +(2318, 35315), +(2319, 35316), +(2320, 35318), +(2321, 38998), +(2322, 38999), +(2323, 35501), +(2324, 35503), +(2325, 35581), +(2326, 35693), +(2327, 35694), +(2328, 35700), +(2329, 35702), +(2330, 35703), +(2331, 35707), +(2332, 35748), +(2333, 35749), +(2334, 35750), +(2335, 35751), +(2336, 39000), +(2337, 35759), +(2338, 35758), +(2339, 35760), +(2340, 35761), +(2341, 35945), +(2342, 39001), +(2343, 39002), +(2344, 39003), +(2345, 39004), +(2346, 39005), +(2347, 39006), +(2348, 955), +(2349, 1181), +(2350, 43116), +(2351, 40924), +(2352, 43115), +(2353, 39774), +(2354, 37168), +(2355, 39469), +(2356, 37118), +(2357, 37503), +(2358, 36909), +(2359, 36916), +(2360, 36912), +(2361, 6836), +(2362, 38225), +(2363, 2290), +(2364, 43118), +(2365, 4419), +(2366, 43120), +(2367, 39501), +(2368, 10308), +(2369, 43122), +(2370, 27499), +(2371, 43124), +(2372, 33458), +(2373, 43126), +(2374, 39502), +(2375, 37091), +(2376, 37092), +(2377, 1712), +(2378, 4424), +(2379, 10306), +(2380, 27501), +(2381, 33460), +(2382, 37097), +(2383, 37098), +(2384, 1711), +(2385, 4422), +(2386, 10307), +(2387, 27502), +(2388, 33461), +(2389, 37093), +(2390, 37094), +(2391, 38277), +(2392, 38278), +(2393, 33568), +(2394, 38425), +(2395, 38408), +(2396, 38410), +(2397, 38411), +(2398, 38409), +(2399, 38407), +(2400, 38406), +(2401, 38400), +(2402, 38401), +(2403, 38402), +(2404, 38403), +(2405, 38404), +(2406, 38405), +(2407, 38414), +(2408, 38416), +(2409, 38424), +(2410, 38415), +(2411, 38413), +(2412, 38412), +(2413, 38420), +(2414, 38422), +(2415, 38417), +(2416, 38421), +(2417, 38419), +(2418, 38418), +(2419, 38375), +(2420, 38376), +(2421, 38561), +(2422, 38371), +(2423, 44128), +(2424, 38558), +(2425, 43102), +(2426, 38373), +(2427, 38372), +(2428, 38557), +(2429, 38374), +(2430, 38399), +(2431, 38347), +(2432, 37705), +(2433, 38590), +(2434, 37703), +(2435, 38591), +(2436, 38592), +(2437, 38433), +(2438, 38437), +(2439, 39086), +(2440, 39087), +(2441, 39088), +(2442, 39085), +(2443, 39084), +(2444, 39083), +(2445, 32399), +(2446, 39151), +(2447, 38682), +(2448, 39349), +(2449, 39690), +(2450, 39334), +(2451, 40199), +(2452, 40195), +(2453, 36918), +(2454, 39996), +(2455, 36917), +(2456, 39900), +(2457, 39905), +(2458, 39911), +(2459, 39906), +(2460, 36901), +(2461, 36906), +(2462, 33447), +(2463, 36905), +(2464, 33448), +(2465, 39671), +(2466, 36907), +(2467, 40067), +(2468, 36903), +(2469, 39666), +(2470, 37921), +(2471, 40068), +(2472, 36904), +(2473, 40070), +(2474, 39907), +(2475, 39908), +(2476, 39909), +(2477, 40072), +(2478, 40076), +(2479, 36920), +(2480, 39912), +(2481, 39914), +(2482, 39915), +(2483, 39916), +(2484, 39918), +(2485, 39917), +(2486, 36926), +(2487, 39934), +(2488, 39935), +(2489, 39942), +(2490, 39936), +(2491, 39941), +(2492, 39943), +(2493, 39945), +(2494, 39937), +(2495, 39944), +(2496, 39938), +(2497, 39939), +(2498, 39933), +(2499, 39940), +(2500, 36929), +(2501, 39947), +(2502, 39948), +(2503, 39949), +(2504, 39950), +(2505, 39951), +(2506, 39952), +(2507, 39953), +(2508, 39954), +(2509, 39955), +(2510, 39946), +(2511, 39956), +(2512, 39957), +(2513, 39958), +(2514, 39959), +(2515, 39960), +(2516, 39961), +(2517, 39962), +(2518, 39963), +(2519, 39964), +(2520, 39965), +(2521, 39966), +(2522, 39967), +(2523, 36932), +(2524, 39968), +(2525, 40077), +(2526, 40078), +(2527, 40079), +(2528, 40081), +(2529, 36908), +(2530, 40411), +(2531, 46376), +(2532, 37704), +(2533, 46379), +(2534, 46377), +(2535, 40087), +(2536, 40093), +(2537, 39974), +(2538, 39975), +(2539, 39976), +(2540, 39977), +(2541, 39978), +(2542, 39979), +(2543, 39980), +(2544, 39981), +(2545, 39982), +(2546, 39983), +(2547, 39984), +(2548, 39985), +(2549, 39986), +(2550, 39988), +(2551, 39989), +(2552, 39990), +(2553, 39991), +(2554, 39992), +(2555, 36923), +(2556, 39919), +(2557, 37701), +(2558, 40213), +(2559, 37702), +(2560, 40215), +(2561, 40217), +(2562, 40214), +(2563, 39920), +(2564, 39927), +(2565, 40216), +(2566, 39932), +(2567, 39997), +(2568, 39998), +(2569, 39999), +(2570, 40000), +(2571, 40001), +(2572, 40002), +(2573, 40003), +(2574, 36924), +(2575, 40008), +(2576, 40009), +(2577, 40010), +(2578, 40011), +(2579, 36921), +(2580, 40012), +(2581, 40013), +(2582, 40014), +(2583, 40015), +(2584, 40016), +(2585, 40017), +(2586, 36927), +(2587, 40022), +(2588, 40023), +(2589, 40024), +(2590, 40025), +(2591, 40026), +(2592, 40027), +(2593, 40028), +(2594, 40029), +(2595, 40030), +(2596, 40031), +(2597, 40032), +(2598, 40033), +(2599, 40034), +(2600, 36930), +(2601, 40037), +(2602, 40038), +(2603, 40039), +(2604, 40040), +(2605, 40043), +(2606, 40044), +(2607, 40045), +(2608, 40046), +(2609, 40047), +(2610, 40048), +(2611, 40049), +(2612, 40050), +(2613, 40051), +(2614, 40052), +(2615, 40053), +(2616, 40054), +(2617, 40055), +(2618, 40056), +(2619, 40057), +(2620, 40058), +(2621, 36933), +(2622, 40085), +(2623, 40086), +(2624, 40088), +(2625, 40089), +(2626, 40090), +(2627, 40091), +(2628, 40092), +(2629, 40095), +(2630, 40099), +(2631, 40102), +(2632, 40104), +(2633, 40094), +(2634, 40096), +(2635, 40100), +(2636, 40103), +(2637, 40105), +(2638, 40098), +(2639, 40101), +(2640, 40106), +(2641, 39910), +(2642, 40041), +(2643, 40248), +(2644, 40059), +(2645, 46378), +(2646, 40073), +(2647, 40097), +(2648, 40211), +(2649, 40212), +(2650, 39683), +(2651, 39684), +(2652, 40533), +(2653, 39688), +(2654, 40668), +(2655, 40669), +(2656, 40671), +(2657, 40672), +(2658, 40674), +(2659, 40673), +(2660, 40675), +(2661, 40670), +(2662, 40942), +(2663, 40949), +(2664, 40950), +(2665, 40951), +(2666, 40952), +(2667, 40953), +(2668, 40943), +(2669, 40954), +(2670, 40955), +(2671, 40956), +(2672, 40957), +(2673, 40958), +(2674, 40959), +(2675, 41117), +(2676, 41113), +(2677, 41114), +(2678, 41116), +(2679, 41126), +(2680, 41127), +(2681, 41128), +(2682, 41129), +(2683, 41181), +(2684, 41182), +(2685, 41183), +(2686, 41184), +(2687, 41185), +(2688, 41186), +(2689, 41187), +(2690, 41188), +(2691, 41189), +(2692, 41190), +(2693, 37700), +(2694, 41238), +(2695, 41239), +(2696, 41240), +(2697, 41241), +(2698, 41242), +(2699, 41243), +(2700, 41245), +(2701, 37663), +(2702, 36910), +(2703, 41264), +(2704, 40769), +(2705, 41355), +(2706, 41356), +(2707, 41357), +(2708, 41344), +(2709, 41345), +(2710, 41346), +(2711, 41354), +(2712, 41351), +(2713, 41352), +(2714, 41348), +(2715, 41349), +(2716, 41347), +(2717, 41353), +(2718, 41350), +(2719, 41257), +(2720, 41383), +(2721, 41384), +(2722, 41386), +(2723, 41387), +(2724, 41388), +(2725, 41391), +(2726, 41392), +(2727, 41394), +(2728, 41266), +(2729, 41377), +(2730, 41375), +(2731, 41378), +(2732, 41379), +(2733, 41285), +(2734, 41307), +(2735, 41333), +(2736, 41335), +(2737, 41339), +(2738, 41400), +(2739, 41334), +(2740, 41401), +(2741, 41395), +(2742, 41396), +(2743, 41397), +(2744, 41398), +(2745, 41380), +(2746, 41381), +(2747, 41382), +(2748, 41385), +(2749, 41389), +(2750, 41376), +(2751, 41611), +(2752, 41745), +(2753, 41974), +(2754, 41975), +(2755, 41976), +(2756, 33470), +(2757, 41509), +(2758, 41510), +(2759, 41511), +(2760, 38426), +(2761, 41548), +(2762, 41513), +(2763, 41515), +(2764, 44211), +(2765, 41520), +(2766, 41521), +(2767, 41522), +(2768, 36783), +(2769, 41523), +(2770, 41525), +(2771, 41528), +(2772, 41543), +(2773, 41546), +(2774, 41551), +(2775, 41549), +(2776, 41545), +(2777, 41550), +(2778, 41544), +(2779, 42253), +(2780, 41553), +(2781, 41554), +(2782, 41555), +(2783, 41248), +(2784, 41249), +(2785, 41251), +(2786, 41250), +(2787, 41252), +(2788, 41253), +(2789, 41254), +(2790, 41255), +(2791, 41594), +(2792, 41593), +(2793, 41595), +(2794, 41597), +(2795, 41600), +(2796, 41598), +(2797, 41599), +(2798, 41601), +(2799, 41602), +(2800, 41603), +(2801, 41604), +(2802, 41607), +(2803, 41608), +(2804, 36784), +(2805, 41609), +(2806, 41610), +(2807, 41984), +(2808, 41985), +(2809, 41986), +(2810, 42093), +(2811, 42095), +(2812, 42096), +(2813, 42100), +(2814, 42103), +(2815, 42101), +(2816, 42111), +(2817, 42102), +(2818, 42113), +(2819, 41519), +(2820, 41512), +(2821, 42225), +(2822, 42142), +(2823, 42143), +(2824, 42144), +(2825, 36766), +(2826, 42151), +(2827, 42152), +(2828, 42148), +(2829, 42153), +(2830, 42146), +(2831, 42158), +(2832, 42154), +(2833, 42150), +(2834, 42156), +(2835, 42149), +(2836, 36767), +(2837, 42145), +(2838, 42155), +(2839, 42157), +(2840, 42336), +(2841, 42337), +(2842, 42338), +(2843, 42339), +(2844, 42340), +(2845, 42341), +(2846, 42395), +(2847, 42413), +(2848, 42418), +(2849, 41367), +(2850, 42420), +(2851, 42421), +(2852, 42435), +(2853, 42443), +(2854, 42500), +(2855, 42508), +(2856, 40892), +(2857, 40771), +(2858, 40893), +(2859, 7005), +(2860, 2901), +(2861, 5956), +(2862, 40772), +(2863, 40536), +(2864, 39682), +(2865, 41112), +(2866, 40767), +(2867, 40865), +(2868, 44951), +(2869, 41121), +(2870, 41146), +(2871, 40768), +(2872, 40895), +(2873, 41164), +(2874, 41165), +(2875, 37567), +(2876, 42546), +(2877, 41167), +(2878, 41168), +(2879, 42549), +(2880, 42550), +(2881, 42552), +(2882, 42553), +(2883, 42554), +(2884, 42555), +(2885, 42642), +(2886, 42643), +(2887, 42644), +(2888, 42645), +(2889, 42646), +(2890, 42647), +(2891, 42641), +(2892, 40109), +(2893, 42701), +(2894, 42702), +(2895, 42723), +(2896, 42727), +(2897, 42729), +(2898, 42730), +(2899, 42724), +(2900, 42726), +(2901, 42725), +(2902, 42728), +(2903, 42551), +(2904, 40896), +(2905, 40899), +(2906, 40914), +(2907, 40920), +(2908, 40908), +(2909, 40919), +(2910, 40915), +(2911, 40900), +(2912, 40923), +(2913, 40903), +(2914, 40909), +(2915, 40912), +(2916, 40913), +(2917, 40902), +(2918, 40901), +(2919, 40921), +(2920, 40916), +(2921, 40906), +(2922, 40897), +(2923, 40922), +(2924, 44922), +(2925, 42734), +(2926, 42735), +(2927, 42736), +(2928, 42737), +(2929, 42738), +(2930, 42739), +(2931, 42741), +(2932, 42742), +(2933, 42743), +(2934, 42744), +(2935, 42745), +(2936, 42746), +(2937, 42747), +(2938, 42748), +(2939, 42749), +(2940, 42750), +(2941, 42751), +(2942, 42752), +(2943, 42753), +(2944, 42754), +(2945, 44920), +(2946, 44955), +(2947, 42897), +(2948, 42898), +(2949, 42899), +(2950, 42900), +(2951, 42901), +(2952, 42902), +(2953, 42903), +(2954, 42904), +(2955, 42905), +(2956, 42906), +(2957, 42907), +(2958, 42908), +(2959, 42909), +(2960, 42910), +(2961, 42911), +(2962, 42912), +(2963, 42913), +(2964, 42914), +(2965, 42915), +(2966, 42916), +(2967, 42917), +(2968, 41101), +(2969, 41104), +(2970, 41107), +(2971, 41096), +(2972, 41099), +(2973, 41098), +(2974, 41103), +(2975, 41105), +(2976, 41095), +(2977, 41097), +(2978, 41106), +(2979, 41092), +(2980, 41108), +(2981, 41100), +(2982, 41094), +(2983, 41110), +(2984, 41109), +(2985, 41102), +(2986, 42954), +(2987, 42955), +(2988, 42956), +(2989, 42957), +(2990, 42958), +(2991, 42959), +(2992, 42960), +(2993, 42961), +(2994, 42962), +(2995, 42963), +(2996, 42964), +(2997, 42965), +(2998, 42966), +(2999, 42967), +(3000, 42968), +(3001, 42969), +(3002, 42970), +(3003, 42971), +(3004, 42972), +(3005, 42973), +(3006, 42974), +(3007, 43420), +(3008, 43425), +(3009, 43412), +(3010, 43414), +(3011, 43415), +(3012, 43416), +(3013, 43417), +(3014, 43418), +(3015, 43419), +(3016, 43421), +(3017, 43422), +(3018, 43413), +(3019, 43423), +(3020, 43430), +(3021, 43424), +(3022, 43426), +(3023, 43427), +(3024, 43428), +(3025, 43429), +(3026, 43431), +(3027, 43432), +(3028, 42396), +(3029, 42397), +(3030, 42398), +(3031, 42399), +(3032, 42400), +(3033, 42401), +(3034, 42402), +(3035, 42403), +(3036, 42404), +(3037, 42405), +(3038, 42406), +(3039, 42407), +(3040, 42408), +(3041, 42409), +(3042, 42410), +(3043, 42411), +(3044, 42412), +(3045, 42414), +(3046, 42415), +(3047, 42416), +(3048, 42417), +(3049, 43533), +(3050, 43534), +(3051, 43535), +(3052, 43536), +(3053, 43537), +(3054, 43538), +(3055, 43541), +(3056, 43542), +(3057, 43539), +(3058, 43543), +(3059, 43544), +(3060, 43545), +(3061, 43546), +(3062, 43547), +(3063, 43548), +(3064, 43549), +(3065, 43550), +(3066, 43551), +(3067, 43552), +(3068, 43553), +(3069, 43554), +(3070, 43673), +(3071, 43671), +(3072, 43672), +(3073, 41517), +(3074, 41518), +(3075, 41524), +(3076, 41526), +(3077, 41527), +(3078, 41529), +(3079, 41530), +(3080, 41531), +(3081, 41532), +(3082, 41547), +(3083, 41533), +(3084, 41534), +(3085, 41535), +(3086, 41536), +(3087, 41537), +(3088, 41538), +(3089, 41539), +(3090, 41540), +(3091, 41552), +(3092, 41541), +(3093, 41542), +(3094, 44923), +(3095, 42453), +(3096, 42454), +(3097, 42455), +(3098, 42456), +(3099, 42457), +(3100, 42458), +(3101, 42459), +(3102, 42460), +(3103, 42461), +(3104, 42462), +(3105, 42463), +(3106, 42464), +(3107, 42465), +(3108, 42466), +(3109, 42467), +(3110, 42468), +(3111, 42469), +(3112, 42470), +(3113, 42471), +(3114, 42472), +(3115, 42473), +(3116, 43103), +(3117, 39338), +(3118, 43104), +(3119, 43117), +(3120, 39339), +(3121, 43105), +(3122, 43119), +(3123, 39340), +(3124, 43106), +(3125, 43121), +(3126, 39341), +(3127, 43107), +(3128, 43123), +(3129, 39342), +(3130, 43108), +(3131, 43125), +(3132, 39343), +(3133, 43109), +(3134, 43127), +(3135, 42740), +(3136, 43244), +(3137, 43245), +(3138, 43246), +(3139, 43247), +(3140, 43248), +(3141, 43249), +(3142, 43250), +(3143, 43251), +(3144, 43252), +(3145, 43253), +(3146, 43316), +(3147, 43334), +(3148, 43331), +(3149, 43332), +(3150, 43335), +(3151, 43355), +(3152, 43356), +(3153, 43338), +(3154, 43354), +(3155, 43350), +(3156, 43351), +(3157, 43339), +(3158, 43357), +(3159, 43359), +(3160, 43360), +(3161, 43364), +(3162, 43361), +(3163, 43365), +(3164, 43366), +(3165, 43367), +(3166, 43340), +(3167, 43368), +(3168, 43369), +(3169, 43342), +(3170, 43371), +(3171, 43370), +(3172, 43373), +(3173, 43372), +(3174, 43374), +(3175, 43379), +(3176, 43376), +(3177, 43377), +(3178, 43343), +(3179, 43378), +(3180, 43380), +(3181, 43381), +(3182, 43385), +(3183, 43344), +(3184, 43386), +(3185, 43388), +(3186, 43389), +(3187, 43390), +(3188, 43392), +(3189, 43393), +(3190, 43391), +(3191, 43394), +(3192, 43395), +(3193, 43396), +(3194, 43397), +(3195, 43398), +(3196, 43399), +(3197, 43400), +(3198, 3012), +(3199, 1477), +(3200, 4425), +(3201, 10309), +(3202, 27498), +(3203, 33457), +(3204, 43463), +(3205, 43464), +(3206, 954), +(3207, 2289), +(3208, 4426), +(3209, 10310), +(3210, 33462), +(3211, 43465), +(3212, 43466), +(3213, 43482), +(3214, 43498), +(3215, 43515), +(3216, 43570), +(3217, 43569), +(3218, 43582), +(3219, 43674), +(3220, 43725), +(3221, 43825), +(3222, 43826), +(3223, 43827), +(3224, 43850), +(3225, 43854), +(3226, 43853), +(3227, 43860), +(3228, 43864), +(3229, 43865), +(3230, 43870), +(3231, 43871), +(3232, 43654), +(3233, 43655), +(3234, 44142), +(3235, 43656), +(3236, 43657), +(3237, 44161), +(3238, 39350), +(3239, 43660), +(3240, 43661), +(3241, 44163), +(3242, 43663), +(3243, 43664), +(3244, 43666), +(3245, 43667), +(3246, 38322), +(3247, 44210), +(3248, 37602), +(3249, 43145), +(3250, 43146), +(3251, 44316), +(3252, 44317), +(3253, 44318), +(3254, 43867), +(3255, 43868), +(3256, 43869), +(3257, 43969), +(3258, 43974), +(3259, 43973), +(3260, 43970), +(3261, 41516), +(3262, 43972), +(3263, 43975), +(3264, 43971), +(3265, 44497), +(3266, 44493), +(3267, 43987), +(3268, 44063), +(3269, 44314), +(3270, 44315), +(3271, 44325), +(3272, 44327), +(3273, 44328), +(3274, 44329), +(3275, 44330), +(3276, 44331), +(3277, 44332), +(3278, 44322), +(3279, 44323), +(3280, 44324), +(3281, 38436), +(3282, 38440), +(3283, 44436), +(3284, 44437), +(3285, 44438), +(3286, 44449), +(3287, 38434), +(3288, 38438), +(3289, 44456), +(3290, 44440), +(3291, 44441), +(3292, 38971), +(3293, 44452), +(3294, 44442), +(3295, 44453), +(3296, 38435), +(3297, 38986), +(3298, 38439), +(3299, 44443), +(3300, 44444), +(3301, 44445), +(3302, 38441), +(3303, 43566), +(3304, 43565), +(3305, 44446), +(3306, 44447), +(3307, 44448), +(3308, 43129), +(3309, 43130), +(3310, 43131), +(3311, 44455), +(3312, 43132), +(3313, 43133), +(3314, 42731), +(3315, 44457), +(3316, 43255), +(3317, 43256), +(3318, 44458), +(3319, 43257), +(3320, 43258), +(3321, 44463), +(3322, 44465), +(3323, 43260), +(3324, 43433), +(3325, 43434), +(3326, 43435), +(3327, 43436), +(3328, 43437), +(3329, 44466), +(3330, 43438), +(3331, 43439), +(3332, 44467), +(3333, 43261), +(3334, 43262), +(3335, 43263), +(3336, 43264), +(3337, 43265), +(3338, 43266), +(3339, 43271), +(3340, 43273), +(3341, 43447), +(3342, 43449), +(3343, 43445), +(3344, 43444), +(3345, 43446), +(3346, 43442), +(3347, 43448), +(3348, 43443), +(3349, 43455), +(3350, 43457), +(3351, 43453), +(3352, 43452), +(3353, 43454), +(3354, 43450), +(3355, 43456), +(3356, 43451), +(3357, 43458), +(3358, 43459), +(3359, 43461), +(3360, 43469), +(3361, 43481), +(3362, 43484), +(3363, 43495), +(3364, 43502), +(3365, 44469), +(3366, 44470), +(3367, 44499), +(3368, 44501), +(3369, 44500), +(3370, 41508), +(3371, 44413), +(3372, 44504), +(3373, 44554), +(3374, 44558), +(3375, 43584), +(3376, 43583), +(3377, 43585), +(3378, 43590), +(3379, 43591), +(3380, 43592), +(3381, 43593), +(3382, 43594), +(3383, 43595), +(3384, 43586), +(3385, 43587), +(3386, 43588), +(3387, 44739), +(3388, 44740), +(3389, 44741), +(3390, 44742), +(3391, 44684), +(3392, 44928), +(3393, 44930), +(3394, 44931), +(3395, 44936), +(3396, 39970), +(3397, 44939), +(3398, 44943), +(3399, 44947), +(3400, 44946), +(3401, 44949), +(3402, 41814), +(3403, 44958), +(3404, 8827), +(3405, 44963), +(3406, 45054), +(3407, 45056), +(3408, 45060), +(3409, 45085), +(3410, 45087), +(3411, 45550), +(3412, 45559), +(3413, 45552), +(3414, 45561), +(3415, 45551), +(3416, 45560), +(3417, 45553), +(3418, 45562), +(3419, 45554), +(3420, 45563), +(3421, 45555), +(3422, 45564), +(3423, 45556), +(3424, 45565), +(3425, 45557), +(3426, 45566), +(3427, 45558), +(3428, 45567), +(3429, 45621), +(3430, 45626), +(3431, 45627), +(3432, 45628), +(3433, 45631), +(3434, 45773), +(3435, 45854), +(3436, 45849), +(3437, 45735), +(3438, 45778), +(3439, 45785), +(3440, 45734), +(3441, 45789), +(3442, 45747), +(3443, 45797), +(3444, 45733), +(3445, 45746), +(3446, 45793), +(3447, 45623), +(3448, 45740), +(3449, 45622), +(3450, 45760), +(3451, 45768), +(3452, 45775), +(3453, 45776), +(3454, 45804), +(3455, 45805), +(3456, 45601), +(3457, 45602), +(3458, 45625), +(3459, 45731), +(3460, 45736), +(3461, 45737), +(3462, 45738), +(3463, 45741), +(3464, 45742), +(3465, 45743), +(3466, 45753), +(3467, 45755), +(3468, 45756), +(3469, 45758), +(3470, 45761), +(3471, 45762), +(3472, 45764), +(3473, 45770), +(3474, 45771), +(3475, 45772), +(3476, 45779), +(3477, 45781), +(3478, 45790), +(3479, 45792), +(3480, 45799), +(3481, 45800), +(3482, 45803), +(3483, 45806), +(3484, 45795), +(3485, 45769), +(3486, 45732), +(3487, 45745), +(3488, 45604), +(3489, 45744), +(3490, 45757), +(3491, 45767), +(3492, 45783), +(3493, 45794), +(3494, 45603), +(3495, 45739), +(3496, 45766), +(3497, 45777), +(3498, 45782), +(3499, 45780), +(3500, 46026), +(3501, 46098), +(3502, 33567), +(3503, 45812), +(3504, 45813), +(3505, 45808), +(3506, 45809), +(3507, 45811), +(3508, 45810), +(3509, 46372), +(3510, 36934), +(3511, 40167), +(3512, 40168), +(3513, 40166), +(3514, 40175), +(3515, 40165), +(3516, 40164), +(3517, 40170), +(3518, 40169), +(3519, 40171), +(3520, 40176), +(3521, 40172), +(3522, 40181), +(3523, 40177), +(3524, 40174), +(3525, 40180), +(3526, 40179), +(3527, 40182), +(3528, 40178), +(3529, 40173), +(3530, 36919), +(3531, 40113), +(3532, 40111), +(3533, 40112), +(3534, 40114), +(3535, 40118), +(3536, 40117), +(3537, 40115), +(3538, 40116), +(3539, 36925), +(3540, 40119), +(3541, 40120), +(3542, 40122), +(3543, 40121), +(3544, 36922), +(3545, 40125), +(3546, 40124), +(3547, 40123), +(3548, 40126), +(3549, 40127), +(3550, 40128), +(3551, 36928), +(3552, 40136), +(3553, 40129), +(3554, 40132), +(3555, 40133), +(3556, 40130), +(3557, 40134), +(3558, 40138), +(3559, 40139), +(3560, 40141), +(3561, 40135), +(3562, 40140), +(3563, 40137), +(3564, 40131), +(3565, 36931), +(3566, 40151), +(3567, 40142), +(3568, 40147), +(3569, 40152), +(3570, 40153), +(3571, 40154), +(3572, 40143), +(3573, 40157), +(3574, 40155), +(3575, 40148), +(3576, 40162), +(3577, 40156), +(3578, 40161), +(3579, 40144), +(3580, 40158), +(3581, 40160), +(3582, 40145), +(3583, 40146), +(3584, 40150), +(3585, 40149), +(3586, 40163), +(3587, 40159), +(3588, 47499), +(3589, 47556), +(3590, 47605), +(3591, 47587), +(3592, 47603), +(3593, 47585), +(3594, 47597), +(3595, 47579), +(3596, 47595), +(3597, 47576), +(3598, 47602), +(3599, 47583), +(3600, 47599), +(3601, 47581), +(3602, 47591), +(3603, 47570), +(3604, 47589), +(3605, 47572), +(3606, 47593), +(3607, 47574), +(3608, 47592), +(3609, 47571), +(3610, 47590), +(3611, 47573), +(3612, 47594), +(3613, 47575), +(3614, 47598), +(3615, 47580), +(3616, 47596), +(3617, 47582), +(3618, 47601), +(3619, 47584), +(3620, 47600), +(3621, 47577), +(3622, 47606), +(3623, 47586), +(3624, 47604), +(3625, 47588), +(3626, 47828), +(3627, 48720), +(3628, 48933), +(3629, 49040), +(3630, 49084), +(3631, 49110), +(3632, 49632), +(3633, 49633), +(3634, 49634), +(3635, 49908), +(3636, 49891), +(3637, 49890), +(3638, 49892), +(3639, 49893), +(3640, 49898), +(3641, 49894), +(3642, 49899), +(3643, 49895), +(3644, 49900), +(3645, 49896), +(3646, 49901), +(3647, 49897), +(3648, 49902), +(3649, 49905), +(3650, 49903), +(3651, 49906), +(3652, 49904), +(3653, 49907), +(3654, 50125), +(3655, 50045), +(3656, 50077), +(3657, 50816), +(3658, 52020), +(3659, 52021), +(3660, 54797); + +-- +-- Indexes for dumped tables +-- + +-- +-- Indexes for table `auctionhousebot_professionItems` +-- +ALTER TABLE `auctionhousebot_professionItems` + ADD PRIMARY KEY (`Entry`); + +-- +-- AUTO_INCREMENT for dumped tables +-- + +-- +-- AUTO_INCREMENT for table `auctionhousebot_professionItems` +-- +ALTER TABLE `auctionhousebot_professionItems` + MODIFY `Entry` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3661; +COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/data/sql/db-world/mod_auctionhousebot.sql b/data/sql/db-world/mod_auctionhousebot.sql new file mode 100644 index 00000000..ead151d7 --- /dev/null +++ b/data/sql/db-world/mod_auctionhousebot.sql @@ -0,0 +1,382 @@ +-- +-- Main configuration for the auction houses +-- + +DROP TABLE IF EXISTS `mod_auctionhousebot`; +CREATE TABLE `mod_auctionhousebot` ( + `auctionhouse` int(11) NOT NULL DEFAULT '0' COMMENT 'mapID of the auctionhouse.', + `name` char(25) DEFAULT NULL COMMENT 'Text name of the auctionhouse.', + `minitems` int(11) DEFAULT '0' COMMENT 'This is the minimum number of items you want to keep in the auction house. a 0 here will make it the same as the maximum.', + `maxitems` int(11) DEFAULT '0' COMMENT 'This is the number of items you want to keep in the auction house.', + `percentgreytradegoods` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the Grey Trade Goods auction items', + `percentwhitetradegoods` int(11) DEFAULT '27' COMMENT 'Sets the percentage of the White Trade Goods auction items', + `percentgreentradegoods` int(11) DEFAULT '12' COMMENT 'Sets the percentage of the Green Trade Goods auction items', + `percentbluetradegoods` int(11) DEFAULT '10' COMMENT 'Sets the percentage of the Blue Trade Goods auction items', + `percentpurpletradegoods` int(11) DEFAULT '1' COMMENT 'Sets the percentage of the Purple Trade Goods auction items', + `percentorangetradegoods` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the Orange Trade Goods auction items', + `percentyellowtradegoods` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the Yellow Trade Goods auction items', + `percentgreyitems` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the non trade Grey auction items', + `percentwhiteitems` int(11) DEFAULT '10' COMMENT 'Sets the percentage of the non trade White auction items', + `percentgreenitems` int(11) DEFAULT '30' COMMENT 'Sets the percentage of the non trade Green auction items', + `percentblueitems` int(11) DEFAULT '8' COMMENT 'Sets the percentage of the non trade Blue auction items', + `percentpurpleitems` int(11) DEFAULT '2' COMMENT 'Sets the percentage of the non trade Purple auction items', + `percentorangeitems` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the non trade Orange auction items', + `percentyellowitems` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the non trade Yellow auction items', + `minpricegrey` int(11) DEFAULT '100' COMMENT 'Minimum price of Grey items (percentage).', + `maxpricegrey` int(11) DEFAULT '150' COMMENT 'Maximum price of Grey items (percentage).', + `minpricewhite` int(11) DEFAULT '150' COMMENT 'Minimum price of White items (percentage).', + `maxpricewhite` int(11) DEFAULT '250' COMMENT 'Maximum price of White items (percentage).', + `minpricegreen` int(11) DEFAULT '800' COMMENT 'Minimum price of Green items (percentage).', + `maxpricegreen` int(11) DEFAULT '1400' COMMENT 'Maximum price of Green items (percentage).', + `minpriceblue` int(11) DEFAULT '1250' COMMENT 'Minimum price of Blue items (percentage).', + `maxpriceblue` int(11) DEFAULT '1750' COMMENT 'Maximum price of Blue items (percentage).', + `minpricepurple` int(11) DEFAULT '2250' COMMENT 'Minimum price of Purple items (percentage).', + `maxpricepurple` int(11) DEFAULT '4550' COMMENT 'Maximum price of Purple items (percentage).', + `minpriceorange` int(11) DEFAULT '3250' COMMENT 'Minimum price of Orange items (percentage).', + `maxpriceorange` int(11) DEFAULT '5550' COMMENT 'Maximum price of Orange items (percentage).', + `minpriceyellow` int(11) DEFAULT '5250' COMMENT 'Minimum price of Yellow items (percentage).', + `maxpriceyellow` int(11) DEFAULT '6550' COMMENT 'Maximum price of Yellow items (percentage).', + `minbidpricegrey` int(11) DEFAULT '70' COMMENT 'Starting bid price of Grey items as a percentage of the randomly chosen buyout price. Default: 70', + `maxbidpricegrey` int(11) DEFAULT '100' COMMENT 'Starting bid price of Grey items as a percentage of the randomly chosen buyout price. Default: 100', + `minbidpricewhite` int(11) DEFAULT '70' COMMENT 'Starting bid price of White items as a percentage of the randomly chosen buyout price. Default: 70', + `maxbidpricewhite` int(11) DEFAULT '100' COMMENT 'Starting bid price of White items as a percentage of the randomly chosen buyout price. Default: 100', + `minbidpricegreen` int(11) DEFAULT '80' COMMENT 'Starting bid price of Green items as a percentage of the randomly chosen buyout price. Default: 80', + `maxbidpricegreen` int(11) DEFAULT '100' COMMENT 'Starting bid price of Green items as a percentage of the randomly chosen buyout price. Default: 100', + `minbidpriceblue` int(11) DEFAULT '75' COMMENT 'Starting bid price of Blue items as a percentage of the randomly chosen buyout price. Default: 75', + `maxbidpriceblue` int(11) DEFAULT '100' COMMENT 'Starting bid price of Blue items as a percentage of the randomly chosen buyout price. Default: 100', + `minbidpricepurple` int(11) DEFAULT '80' COMMENT 'Starting bid price of Purple items as a percentage of the randomly chosen buyout price. Default: 80', + `maxbidpricepurple` int(11) DEFAULT '100' COMMENT 'Starting bid price of Purple items as a percentage of the randomly chosen buyout price. Default: 100', + `minbidpriceorange` int(11) DEFAULT '80' COMMENT 'Starting bid price of Orange items as a percentage of the randomly chosen buyout price. Default: 80', + `maxbidpriceorange` int(11) DEFAULT '100' COMMENT 'Starting bid price of Orange items as a percentage of the randomly chosen buyout price. Default: 100', + `minbidpriceyellow` int(11) DEFAULT '80' COMMENT 'Starting bid price of Yellow items as a percentage of the randomly chosen buyout price. Default: 80', + `maxbidpriceyellow` int(11) DEFAULT '100' COMMENT 'Starting bid price of Yellow items as a percentage of the randomly chosen buyout price. Default: 100', + `maxstackgrey` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', + `maxstackwhite` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', + `maxstackgreen` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', + `maxstackblue` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', + `maxstackpurple` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', + `maxstackorange` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', + `maxstackyellow` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', + `buyerpricegrey` int(11) DEFAULT '1' COMMENT 'Multiplier to vendorprice when buying grey items from auctionhouse', + `buyerpricewhite` int(11) DEFAULT '3' COMMENT 'Multiplier to vendorprice when buying white items from auctionhouse', + `buyerpricegreen` int(11) DEFAULT '5' COMMENT 'Multiplier to vendorprice when buying green items from auctionhouse', + `buyerpriceblue` int(11) DEFAULT '12' COMMENT 'Multiplier to vendorprice when buying blue items from auctionhouse', + `buyerpricepurple` int(11) DEFAULT '15' COMMENT 'Multiplier to vendorprice when buying purple items from auctionhouse', + `buyerpriceorange` int(11) DEFAULT '20' COMMENT 'Multiplier to vendorprice when buying orange items from auctionhouse', + `buyerpriceyellow` int(11) DEFAULT '22' COMMENT 'Multiplier to vendorprice when buying yellow items from auctionhouse', + `buyerbiddinginterval` int(11) DEFAULT '1' COMMENT 'Interval how frequently AHB bids on each AH. Time in minutes', + `buyerbidsperinterval` int(11) DEFAULT '1' COMMENT 'number of bids to put in per bidding interval', + PRIMARY KEY (`auctionhouse`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- AHBot auction houses default configuration values +-- + +INSERT INTO `mod_auctionhousebot` (`auctionhouse`, `name`, `minitems`, `maxitems`, `percentgreytradegoods`, `percentwhitetradegoods`, `percentgreentradegoods`, `percentbluetradegoods`, `percentpurpletradegoods`, `percentorangetradegoods`, `percentyellowtradegoods`, `percentgreyitems`, `percentwhiteitems`, `percentgreenitems`, `percentblueitems`, `percentpurpleitems`, `percentorangeitems`, `percentyellowitems`, `minpricegrey`, `maxpricegrey`, `minpricewhite`, `maxpricewhite`, `minpricegreen`, `maxpricegreen`, `minpriceblue`, `maxpriceblue`, `minpricepurple`, `maxpricepurple`, `minpriceorange`, `maxpriceorange`, `minpriceyellow`, `maxpriceyellow`, `minbidpricegrey`, `maxbidpricegrey`, `minbidpricewhite`, `maxbidpricewhite`, `minbidpricegreen`, `maxbidpricegreen`, `minbidpriceblue`, `maxbidpriceblue`, `minbidpricepurple`, `maxbidpricepurple`, `minbidpriceorange`, `maxbidpriceorange`, `minbidpriceyellow`, `maxbidpriceyellow`, `maxstackgrey`, `maxstackwhite`, `maxstackgreen`, `maxstackblue`, `maxstackpurple`, `maxstackorange`, `maxstackyellow`, `buyerpricegrey`, `buyerpricewhite`, `buyerpricegreen`, `buyerpriceblue`, `buyerpricepurple`, `buyerpriceorange`, `buyerpriceyellow`, `buyerbiddinginterval`, `buyerbidsperinterval`) +VALUES +(2,'Alliance',250,250,0,27,12,10,1,0,0,0,10,30,8,2,0,0,100,150,150,250,800,1400,1250,1750,2250,4550,3250,5550,5250,6550,70,100,70,100,80,100,75,100,80,100,80,100,80,100,0,0,3,2,1,1,1,1,3,5,12,15,20,22,1,1), +(6,'Horde',250,250,0,27,12,10,1,0,0,0,10,30,8,2,0,0,100,150,150,250,800,1400,1250,1750,2250,4550,3250,5550,5250,6550,70,100,70,100,80,100,75,100,80,100,80,100,80,100,0,0,3,2,1,1,1,1,3,5,12,15,20,22,1,1), +(7,'Neutral',250,250,0,27,12,10,1,0,0,0,10,30,8,2,0,0,100,150,150,250,800,1400,1250,1750,2250,4550,3250,5550,5250,6550,70,100,70,100,80,100,75,100,80,100,80,100,80,100,0,0,3,2,1,1,1,1,3,5,12,15,20,22,1,1); + +-- +-- Items blacklist +-- + +DROP TABLE IF EXISTS `mod_auctionhousebot_disabled_items`; +CREATE TABLE `mod_auctionhousebot_disabled_items` ( + `item` mediumint(8) unsigned NOT NULL, + PRIMARY KEY (`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Blacklist default values +-- + +INSERT INTO `mod_auctionhousebot_disabled_items` +VALUES +(17), (3895), (1700), (862), (4196), (3934), (2275), (4213), (4988), (4989), (4990), (4110), (4111), (4116), (3463), (3068), +(913), (2016), (3738), (1189), (3222), (2664), (2273), (4763), (2444), (1041), (1133), (1134), (2413), (2415), (2927), (2932), +(2443), (1487), (1623), (3031), (3034), (3762), (3772), (4981), (2693), (2808), (1254), (2442), (3137), (4191), (4193), (931), +(1114), (1450), (2136), (1352), (2441), (3884), (4200), (2588), (2922), (3005), (3122), (1193), (1057), (3107), (3135), (3144), +(4273), (1113), (2288), (2556), (2921), (3004), (763), (1146), (1255), (2929), (4143), (2064), (3648), (1162), (1167), (2377), +(2920), (3003), (4965), (2497), (2499), (2501), (2599), (3320), (964), (2496), (2498), (2503), (2946), (3131), (1389), (2500), +(2502), (4959), (1166), (1386), (2133), (4930), (1029), (2055), (2128), (2481), (2484), (2487), (3260), (2482), (2483), (2485), +(2486), (2947), (3111), (37), (996), (119), (138), (734), (876), (895), (896), (900), (956), (958), (960), (997), +(1014), (1020), (1021), (1024), (1025), (1027), (1324), (1356), (1672), (1923), (1977), (2410), (2477), (2586), (2638), (2668), +(2755), (2891), (3316), (3513), (3516), (3536), (3584), (3686), (3707), (3744), (4278), (4524), (4703), (4704), (4749), (4851), +(4868), (192), (3958), (3978), (4014), (3952), (3981), (3991), (4011), (3957), (3979), (4012), (3959), (3982), (4010), (3954), +(3983), (3988), (4009), (3953), (3984), (4013), (3956), (3977), (4008), (3955), (3980), (4015), (2931), (3776), (1914), (4858), +(3713), (3777), (3063), (2918), (3046), (3052), (3062), (4912), (2995), (1028), (1192), (2692), (1298), (1363), (4688), (4774), +(4773), (4761), (2305), (2306), (4471), (88), (91), (100), (128), (143), (156), (813), (1222), (1259), (1902), (1911), +(2081), (2184), (2550), (2705), (2715), (2810), (3148), (3168), (3245), (3368), (3675), (3774), (5828), (9372), (8708), (8586), +(9240), (9380), (9484), (9417), (10579), (9718), (7187), (10978), (9685), (9214), (9653), (7987), (7988), (7986), (7550), (7547), +(7548), (7994), (7748), (7953), (9888), (5010), (7497), (7466), (5008), (8840), (5004), (5005), (7467), (7427), (7426), (7948), +(7949), (7950), (7951), (7952), (6589), (6360), (6376), (10049), (5821), (5822), (7188), (6478), (10998), (6345), (5748), (5255), +(5968), (8350), (10939), (6343), (9602), (10595), (8079), (8008), (9421), (8076), (8078), (10683), (8171), (8546), (10662), (10818), +(8007), (5510), (8075), (8077), (10664), (8147), (8993), (5663), (5874), (5875), (8583), (8589), (8590), (8627), (8628), (8630), +(8633), (9254), (10620), (5513), (5522), (6357), (8365), (8366), (5509), (6715), (5108), (5518), (6355), (5632), (5845), (6352), +(6359), (6363), (6364), (6647), (6766), (5654), (5657), (5511), (5105), (6354), (6366), (6374), (6650), (8964), (5232), (5517), +(5660), (5013), (5024), (5603), (5823), (6292), (6294), (6295), (6309), (6310), (6311), (6351), (6353), (6358), (6645), (6754), +(7678), (5150), (6651), (5512), (6182), (6183), (6619), (6649), (5229), (6356), (5235), (5043), (5044), (5349), (5350), (6216), +(6291), (6643), (6891), (7807), (7808), (6648), (5056), (5184), (5220), (5330), (5333), (5353), (5389), (5400), (5410), (5417), +(5418), (5455), (5515), (5531), (5562), (5563), (5639), (5645), (5646), (5681), (5768), (5769), (5833), (5859), (5878), (6130), +(6276), (6277), (6278), (6279), (6280), (6435), (6490), (6491), (6492), (6495), (6496), (6497), (6498), (6500), (6501), (6516), +(6544), (6623), (6717), (6718), (6834), (6927), (6988), (7134), (7206), (7208), (7268), (7271), (7286), (7287), (7333), (7392), +(7679), (7680), (7681), (7716), (7725), (7733), (7737), (7867), (7923), (7970), (8072), (8426), (9280), (9281), (9282), (9284), +(9316), (9319), (9325), (9330), (9365), (9593), (9594), (9595), (9596), (9597), (10464), (10691), (10692), (10693), (10694), (5495), +(5863), (6307), (7769), (7770), (7771), (8164), (8383), (8585), (9311), (9438), (9440), (9441), (9443), (10790), (5550), (5549), +(5555), (8368), (8688), (6951), (5560), (7428), (7190), (5625), (6174), (7170), (5106), (8427), (5379), (5259), (5283), (5362), +(5363), (5364), (5367), (5370), (5371), (5377), (5435), (5600), (6131), (6150), (6225), (6227), (6232), (6297), (6301), (6455), +(7135), (8425), (9700), (9701), (10457), (10450), (10791), (11264), (12947), (15780), (14550), (12302), (12303), (12330), (12351), (12353), +(12354), (13317), (13326), (13327), (13328), (13329), (15292), (15293), (12731), (12588), (12970), (13080), (13090), (13092), (13936), (13950), +(14543), (13148), (13164), (13173), (15410), (15769), (11768), (12105), (11743), (14344), (11671), (11672), (14343), (12469), (11178), (11177), +(13325), (11139), (11138), (11084), (12325), (12326), (12327), (13323), (13324), (12616), (12617), (12615), (12904), (12104), (12106), (12107), +(13175), (13242), (13247), (12866), (11175), (12258), (11174), (11135), (11134), (11082), (13727), (13728), (13730), (13731), (13736), (13737), +(13738), (13739), (13740), (13741), (13742), (13743), (13744), (13745), (13746), (13747), (13748), (13749), (13762), (13763), (13764), (13765), +(13766), (13767), (13768), (13769), (13770), (13771), (13772), (13773), (13775), (13776), (13777), (13778), (13779), (13780), (13781), (13782), +(13783), (13784), (13785), (13788), (13791), (13794), (13797), (13798), (13801), (13802), (13803), (13804), (13805), (13806), (13807), (13808), +(13809), (13603), (15756), (13701), (14488), (11950), (11951), (11952), (13480), (13888), (13889), (13890), (13891), (13893), (13901), (13902), +(13903), (13904), (13905), (13906), (13907), (13908), (13910), (13911), (13912), (13914), (13915), (13916), (13917), (13918), (14481), (13477), +(14894), (15409), (15415), (15417), (15419), (15886), (13602), (13700), (11176), (13422), (13754), (13755), (13756), (13758), (13759), (13760), +(13875), (13876), (13877), (13878), (13879), (13880), (13881), (13882), (13883), (13884), (13885), (13886), (13887), (11903), (14062), (15326), +(15327), (11111), (13699), (11137), (11083), (12238), (12446), (12447), (12448), (12449), (14891), (14083), (11024), (11131), (11149), (11170), +(11222), (11230), (11282), (11364), (11413), (11470), (11507), (11508), (11512), (11513), (11582), (11602), (11609), (11613), (11616), (11947), +(11949), (11954), (12064), (12241), (12263), (12347), (12349), (12563), (12567), (12648), (12649), (12723), (12847), (12885), (13155), (13159), +(13370), (13673), (13726), (13732), (13733), (13734), (13787), (13790), (13793), (13796), (14339), (14390), (14392), (14645), (15448), (15843), +(15845), (11270), (11283), (11511), (11514), (12468), (15422), (15423), (12348), (12787), (12943), (12991), (13316), (13337), (13612), (14586), +(18582), (18583), (18584), (17182), (17782), (18881), (17142), (17067), (17068), (18608), (18609), (18713), (18715), (17075), (18813), (17078), +(17064), (18205), (17223), (18538), (18970), (18241), (18242), (18243), (18244), (18245), (18246), (18247), (18248), (18768), (17886), (17982), +(16369), (16391), (16392), (16393), (16396), (16397), (16401), (16403), (16405), (16406), (16409), (16410), (16413), (16414), (16415), (16416), +(16417), (16418), (16419), (16420), (16421), (16422), (16423), (16424), (16425), (16426), (16427), (16428), (16429), (16430), (16431), (16432), +(16433), (16434), (16435), (16436), (16485), (16487), (16489), (16490), (16491), (16492), (16494), (16496), (16498), (16499), (16501), (16502), +(16503), (16504), (16505), (16506), (16507), (16508), (16509), (16510), (16513), (16514), (16515), (16516), (16518), (16519), (16521), (16522), +(16523), (16524), (16525), (16526), (16527), (16528), (16530), (16531), (17562), (17564), (17566), (17567), (17568), (17569), (17570), (17571), +(17572), (17573), (17576), (17577), (17594), (17596), (17598), (17599), (17600), (17601), (17610), (17611), (17612), (17613), (17616), (17617), +(16337), (17967), (17968), (16999), (17733), (16334), (16336), (16340), (18303), (18304), (18320), (18341), (18342), (16315), (16203), (17966), +(16664), (16202), (17769), (16792), (16165), (17224), (17364), (16026), (16339), (16350), (16366), (16374), (16896), (17012), (18142), (16320), +(16362), (16378), (16356), (16387), (16047), (16171), (16330), (16383), (18636), (16041), (16042), (16373), (16389), (18651), (16325), (16349), +(16361), (16895), (17024), (16319), (16355), (16365), (16386), (16377), (16382), (16082), (16085), (16971), (16329), (16372), (16360), (16390), +(17019), (16348), (16354), (16385), (16893), (16967), (16318), (16324), (16381), (16364), (16371), (16388), (17027), (16057), (16328), (16359), +(16376), (16353), (16380), (16384), (16347), (16892), (16317), (16368), (16323), (16358), (16379), (16327), (16352), (16363), (16375), (16346), +(18964), (16316), (16357), (16351), (16322), (16326), (16331), (16302), (17195), (17302), (17305), (17308), (18002), (16321), (16180), (16642), +(16643), (16644), (16968), (16969), (16970), (16973), (17126), (17242), (17262), (17323), (17324), (17325), (17333), (17353), (17362), (17363), +(17442), (17505), (17506), (17507), (17696), (17758), (17882), (17887), (18151), (18153), (18492), (18540), (18566), (18643), (18799), (18154), +(18642), (20880), (19158), (20142), (20329), (21584), (21587), (21588), (21594), (21612), (21613), (21614), (21339), (20487), (20488), (21124), +(21125), (21127), (21890), (19879), (19951), (19952), (19953), (19954), (19955), (19956), (19957), (19958), (19959), (20698), (20725), (20887), +(19875), (20720), (20721), (20722), (19105), (19110), (20696), (20706), (20368), (21281), (21282), (21283), (21293), (21302), (19986), (20003), +(20005), (20502), (20522), (20524), (21044), (20381), (21785), (21786), (21878), (21772), (21773), (20086), (20965), (19803), (19805), (19806), +(19808), (20591), (20596), (20962), (20957), (20953), (20829), (20952), (20825), (20822), (20819), (19213), (19322), (20256), (20560), (21992), +(21159), (21175), (19012), (19013), (19696), (20498), (20500), (20501), (19010), (19011), (19807), (20065), (21228), (21243), (21153), (19450), +(20067), (21150), (21164), (19008), (19009), (21113), (19006), (19007), (19054), (19055), (21071), (21168), (21212), (21043), (20708), (21162), +(19004), (19005), (20913), (20979), (20981), (19160), (19422), (19642), (19725), (19775), (19880), (19882), (20018), (20020), (20021), (20364), +(20393), (20416), (20418), (20419), (20420), (20432), (20433), (20435), (20436), (20447), (20448), (20449), (20450), (20454), (20455), (20456), +(20709), (20902), (20903), (20904), (20977), (20984), (21106), (21107), (21109), (21111), (21114), (21131), (21152), (21158), (21160), (21161), +(21171), (21442), (21519), (21536), (21560), (21577), (21578), (21591), (21815), (21816), (21817), (21818), (21819), (21820), (21821), (21822), +(21823), (21831), (21975), (21979), (21980), (21981), (19960), (21140), (19924), (20030), (21141), (22736), (22726), (22819), (22821), (22798), +(22799), (22802), (22812), (22691), (22947), (22954), (22800), (22801), (22804), (22807), (22808), (22809), (22811), (22816), (22818), (22820), +(22935), (22936), (22937), (22938), (22939), (22940), (22941), (22943), (22960), (22961), (22967), (22968), (22981), (22983), (22988), (22994), +(22803), (22806), (22810), (22813), (22814), (22815), (22942), (22805), (22817), (22450), (22349), (22350), (22351), (22352), (22353), (22354), +(22355), (22356), (22357), (22358), (22359), (22360), (22361), (22362), (22363), (22364), (22365), (22366), (22367), (22368), (22369), (22370), +(22371), (22372), (22373), (22374), (22375), (22376), (22891), (22230), (22273), (22446), (22447), (22782), (22018), (22019), (22103), (22104), +(22105), (22116), (22182), (22187), (22189), (22797), (22044), (22179), (22186), (22788), (22128), (22184), (22646), (22795), (22895), (22181), +(22185), (22190), (22183), (22180), (22188), (22972), (22710), (22020), (22042), (22045), (22140), (22141), (22142), (22143), (22144), (22145), +(22154), (22155), (22156), (22157), (22158), (22159), (22160), (22161), (22162), (22163), (22164), (22165), (22166), (22167), (22168), (22169), +(22170), (22171), (22172), (22178), (22202), (22260), (22262), (22263), (22283), (22284), (22285), (22286), (22287), (22288), (22289), (22290), +(22291), (22292), (22293), (22294), (22295), (22296), (22297), (22298), (22299), (22300), (22386), (22387), (22584), (22733), (22754), (22822), +(22896), (22899), (22058), (22059), (22709), (23051), (25596), (24526), (24561), (24567), (27965), (24550), (24557), (24265), (23053), (23057), +(23058), (23040), (23041), (23043), (23045), (23046), (23047), (23048), (23049), (23050), (23072), (23362), (23363), (23054), (23056), (23577), +(23242), (23000), (23001), (23025), (23027), (23037), (23038), (23042), (23069), (23070), (23219), (23220), (23663), (23664), (23665), (23666), +(23667), (23668), (23004), (23005), (23006), (23009), (23017), (23018), (23019), (23020), (23021), (23023), (23028), (23029), (23030), (23031), +(23032), (23033), (23034), (23035), (23036), (23039), (23044), (23068), (23071), (23073), (23075), (23221), (23226), (23237), (23238), (23014), +(23457), (23458), (23459), (23461), (23462), (23193), (23545), (23547), (23548), (23549), (23714), (23705), (23709), (23716), (23773), (24412), +(25641), (24137), (25667), (23854), (23855), (24288), (27388), (27446), (24071), (23885), (23882), (23364), (23366), (27774), (27811), (27002), +(27007), (26368), (26372), (26655), (26738), (26128), (26129), (26130), (26131), (26132), (26133), (26134), (26135), (26464), (26465), (26513), +(26527), (26541), (26569), (26765), (26779), (25573), (25574), (25575), (25576), (25580), (25581), (25582), (26235), (26792), (25627), (27196), +(27718), (27719), (27720), (26324), (25145), (25159), (25173), (25285), (26843), (26548), (26180), (26173), (26174), (26175), (27218), (23147), +(23151), (23153), (23229), (23076), (23157), (26015), (26029), (26041), (23420), (23421), (23422), (23432), (23433), (23434), (23233), (23234), +(23235), (27864), (26045), (27863), (24243), (23731), (23755), (23840), (24315), (25877), (23137), (23131), (23141), (23730), (23130), (23135), +(23140), (23144), (23148), (23152), (23162), (23194), (23195), (23196), (23684), (23745), (25469), (25699), (25700), (27422), (27437), (27481), +(27511), (27513), (23578), (25900), (23579), (23683), (23711), (23734), (23846), (23365), (23368), (24227), (24100), (23003), (23008), (23010), +(23011), (23012), (23013), (23016), (23024), (23055), (23214), (23227), (23248), (23340), (23341), (23342), (23350), (23352), (23360), (23378), +(23471), (23486), (23552), (23567), (23584), (23586), (23670), (23686), (23726), (23754), (23878), (23879), (23880), (24156), (24226), (24317), +(24494), (24538), (24573), (25635), (25677), (25747), (25748), (25749), (25750), (25754), (25755), (25756), (25757), (25850), (27317), (27419), +(27590), (23560), (23561), (23562), (23750), (23858), (23866), (23867), (23868), (25814), (27443), (25407), (24242), (27441), (24235), (24190), +(24234), (24188), (23330), (23355), (23952), (23980), (24283), (24506), (24509), (25813), (24140), (28294), (28295), (28297), (28298), (28299), +(28300), (28302), (28305), (28307), (28308), (28309), (28310), (28312), (28313), (28314), (28319), (28320), (28346), (28358), (28383), (28385), +(28402), (28404), (28409), (28410), (28422), (28423), (28443), (28444), (28446), (28447), (28449), (28450), (28476), (28629), (28630), (28639), +(28640), (28641), (28642), (28644), (28645), (28974), (28975), (28976), (28977), (28980), (28982), (28983), (28985), (28986), (28987), (28990), +(28991), (28993), (28994), (28995), (28997), (28998), (28355), (28356), (28357), (28244), (28245), (28381), (28405), (28411), (28424), (28445), +(28448), (28451), (28605), (28638), (28643), (28646), (28973), (28978), (28981), (28984), (28988), (28989), (28992), (28996), (28999), (28117), +(28122), (28388), (28389), (28482), (28293), (28613), (28614), (28615), (28616), (28617), (28618), (28619), (28620), (28622), (28623), (28624), +(28625), (28626), (28627), (28628), (28679), (28680), (28681), (28683), (28684), (28685), (28686), (28687), (28688), (28689), (28690), (28691), +(28692), (28693), (28694), (28695), (28696), (28697), (28698), (28699), (28700), (28701), (28702), (28703), (28704), (28705), (28706), (28707), +(28708), (28709), (28710), (28711), (28712), (28713), (28714), (28715), (28716), (28717), (28718), (28719), (28720), (28721), (28722), (28723), +(28724), (28805), (28806), (28807), (28808), (28809), (28811), (28812), (28813), (28814), (28815), (28817), (28818), (28819), (28820), (28821), +(28831), (28832), (28833), (28834), (28835), (28836), (28837), (28838), (28839), (28840), (28841), (28842), (28843), (28844), (28845), (28846), +(28847), (28848), (28849), (28850), (28851), (28852), (28853), (28854), (28855), (28856), (28857), (28858), (28859), (28860), (28861), (28862), +(28863), (28864), (28865), (28866), (28867), (28868), (28869), (28870), (28871), (28872), (28873), (28874), (28875), (28917), (28918), (28919), +(28920), (28921), (28922), (28923), (28924), (28925), (28926), (28928), (28929), (28930), (28931), (28933), (28935), (28937), (28938), (28939), +(28940), (28941), (28942), (28943), (28944), (28945), (28946), (28947), (28948), (28949), (28950), (28951), (28952), (28953), (28954), (28955), +(28956), (28957), (28959), (28960), (28043), (28044), (28045), (28291), (28408), (28145), (28073), (28112), (28068), (28596), (28072), (28110), +(28131), (28071), (28047), (28099), (28500), (28676), (28738), (28739), (28784), (28039), (28023), (28489), (28905), (30320), (29828), (31958), +(31959), (31965), (31966), (31978), (31984), (31985), (31986), (30448), (29000), (29001), (29003), (29004), (29005), (30491), (31594), (31595), +(31596), (31597), (29885), (29002), (29006), (31598), (31599), (29237), (30559), (29120), (29225), (31584), (31585), (31586), (31587), (31588), +(31589), (31590), (31591), (31592), (31593), (31620), (31621), (31622), (31623), (31624), (31625), (31626), (31627), (31628), (31629), (31630), +(31631), (31632), (31633), (31634), (31635), (31636), (31637), (31638), (31639), (31640), (31641), (31642), (31643), (31644), (31646), (31647), +(31648), (31649), (31650), (31942), (31490), (31491), (31802), (31492), (31493), (31494), (31246), (29210), (30418), (30287), (30288), (30289), +(31730), (30845), (29024), (30427), (30703), (30760), (29539), (29547), (29548), (29569), (30309), (30499), (29041), (29311), (29749), (29751), +(29769), (29839), (29840), (29841), (29842), (29852), (29856), (29857), (29860), (29861), (29863), (29868), (29871), (29872), (29874), (29887), +(29961), (29963), (30193), (30197), (30430), (30438), (30524), (30525), (30526), (30539), (30567), (30595), (30613), (30630), (30658), (30659), +(30717), (31122), (31123), (31130), (31252), (31266), (31346), (31365), (31518), (31607), (31665), (31813), (31843), (31845), (31849), (29790), +(29805), (30632), (30805), (31530), (29410), (29419), (29565), (29571), (29575), (29576), (29645), (29712), (30414), (31824), (32824), (32466), +(32419), (32760), (32761), (32956), (32959), (32416), (32003), (32014), (32025), (32026), (32027), (32028), (32044), (32045), (32046), (32052), +(32053), (32054), (32055), (32961), (32962), (32963), (32964), (32944), (32418), (32422), (32482), (32955), (32958), (32450), (32451), (32452), +(32974), (32975), (32976), (32978), (32982), (32984), (32985), (32987), (32992), (32993), (32995), (32996), (32415), (32417), (32954), (32957), +(32973), (32977), (32983), (32986), (32991), (32994), (32093), (32094), (32095), (32096), (32097), (32098), (32099), (32100), (32101), (32102), +(32103), (32104), (32105), (32106), (32107), (32108), (32109), (32110), (32111), (32112), (32113), (32114), (32115), (32116), (32117), (32118), +(32119), (32120), (32121), (32122), (32123), (32124), (32125), (32126), (32127), (32128), (32129), (32130), (32131), (32132), (32133), (32134), +(32135), (32136), (32137), (32138), (32139), (32140), (32141), (32142), (32143), (32144), (32145), (32146), (32147), (32148), (32149), (32150), +(32151), (32152), (32153), (32154), (32155), (32156), (32157), (32158), (32159), (32160), (32161), (32162), (32163), (32164), (32165), (32166), +(32167), (32168), (32169), (32170), (32171), (32172), (32173), (32174), (32175), (32176), (32177), (32178), (32179), (32180), (32181), (32182), +(32183), (32184), (32185), (32186), (32187), (32188), (32189), (32190), (32192), (32414), (32421), (32655), (32656), (32914), (32735), (32895), +(32896), (32407), (32658), (32659), (32660), (32661), (32662), (32663), (32664), (32665), (32949), (32950), (32412), (32915), (32917), (32918), +(32919), (32920), (32465), (32542), (32566), (32594), (32773), (32764), (32765), (32766), (32618), (32642), (32543), (32544), (32545), (32546), +(32547), (32548), (32549), (32550), (32551), (32552), (32553), (32554), (32555), (32556), (32557), (32558), (32559), (32560), (32561), (32595), +(32598), (32601), (32840), (32844), (32845), (32846), (32847), (32762), (32763), (32767), (32972), (32320), (32364), (32408), (32626), (32627), +(32628), (32629), (32630), (32631), (32688), (32689), (32690), (32691), (32692), (32693), (32700), (32701), (32702), (32703), (32704), (32705), +(32706), (32707), (32708), (32709), (32710), (32711), (32712), (32713), (32734), (32911), (32971), (32578), (32906), (32725), (32615), (32633), +(32841), (33475), (34146), (34149), (34145), (34148), (34144), (34147), (34219), (34335), (34209), (34212), (33668), (33671), (33674), (33676), +(33679), (33682), (33684), (33690), (33693), (33699), (33700), (33703), (33717), (33720), (33726), (33729), (33732), (33744), (33747), (33753), +(33767), (33770), (33920), (33921), (33922), (33923), (33076), (33077), (33078), (33309), (33313), (33937), (33940), (33943), (33946), (33949), +(33952), (34576), (34577), (34578), (34579), (34580), (33987), (33997), (33054), (33065), (33066), (33067), (33068), (33482), (33964), (33936), +(33939), (33942), (33945), (33948), (33951), (33957), (33959), (34073), (34074), (34075), (34622), (34057), (33132), (33137), (33138), (33139), +(33141), (33142), (33809), (34544), (33080), (33225), (33182), (33184), (34835), (33350), (34138), (34139), (33803), (34143), (34142), (34221), +(33060), (33147), (34627), (34967), (34415), (34107), (33224), (33993), (34955), (33017), (33018), (33019), (33020), (33021), (33176), (33183), +(33219), (33223), (34492), (34499), (34518), (34519), (33197), (34484), (34486), (33455), (34025), (34030), (33312), (34062), (34024), (34126), +(34469), (34735), (34737), (34738), (34739), (34740), (34741), (34742), (34743), (34744), (34745), (34746), (34864), (34865), (34867), (34868), +(33823), (33824), (34467), (34663), (33096), (33218), (33041), (33081), (33087), (33105), (33111), (33121), (33315), (33336), (33341), (33477), +(33558), (33599), (33604), (33610), (33614), (33615), (33616), (33617), (33634), (33781), (33784), (33839), (33848), (33850), (33929), (34044), +(34077), (34112), (34115), (34116), (34117), (34120), (34123), (34135), (34158), (34187), (34191), (34494), (34497), (34501), (34623), (34645), +(34647), (34716), (34718), (34842), (33051), (33063), (33797), (34171), (33316), (34476), (33089), (34589), (34590), (34591), (34694), (34784), +(34880), (34907), (36942), (35290), (35291), (35292), (35317), (35319), (35327), (35494), (35495), (35496), (35497), (35507), (35508), (35509), +(35511), (35514), (35213), (35539), (35541), (35545), (35546), (35549), (35550), (35202), (35209), (35226), (35517), (35518), (35519), (35520), +(35521), (35522), (35523), (35524), (35525), (35526), (35527), (35528), (35529), (35530), (35531), (35532), (35533), (35535), (35537), (35538), +(35544), (35548), (35551), (35553), (35555), (35664), (35665), (35666), (36866), (36867), (35728), (35729), (35730), (35731), (35225), (36941), +(36454), (36477), (36491), (36505), (36519), (36533), (36547), (36561), (36575), (36589), (36603), (36617), (36631), (36645), (36659), (36673), +(36687), (36701), (36715), (35876), (36910), (36915), (35626), (36899), (36900), (36970), (36892), (36893), (36894), (36965), (36897), (36955), +(36967), (36895), (36960), (36912), (36914), (36968), (36959), (36889), (36890), (36891), (36966), (36896), (36964), (35285), (35286), (35396), +(35397), (35398), (35399), (35400), (35417), (35418), (35419), (35420), (35421), (35422), (35423), (35424), (35425), (35426), (35427), (35428), +(35429), (35430), (35431), (35432), (35433), (35434), (35435), (35436), (35437), (35438), (35439), (35440), (35441), (35442), (35443), (35444), +(35445), (35446), (35447), (35448), (35449), (35450), (35451), (35452), (35453), (35454), (35455), (35456), (35457), (35458), (35459), (35460), +(35461), (35462), (35313), (35946), (35126), (35229), (35289), (35692), (35701), (35718), (35722), (35738), (35777), (35803), (35840), (35854), +(36733), (36748), (36765), (36768), (36772), (36799), (36828), (36836), (36846), (36848), (35512), (35792), (35806), (36862), (36863), (35757), +(36794), (36795), (36829), (36830), (38691), (37739), (37740), (37611), (37127), (37128), (37597), (38287), (38288), (38289), (38290), (38282), +(38307), (38377), (38378), (38265), (37598), (37719), (38576), (38484), (38309), (38310), (38311), (38312), (38313), (38314), (37174), (37175), +(37176), (37196), (37197), (37243), (37244), (37245), (37290), (37364), (37365), (37366), (37410), (37587), (37590), (37624), (37625), (37646), +(37647), (37648), (37649), (37671), (37672), (37673), (37697), (37698), (37699), (37799), (37800), (37801), (37856), (37857), (37858), (37109), +(38442), (38443), (38444), (38445), (38387), (38388), (38389), (38390), (38572), (38468), (38243), (38244), (38245), (38246), (38247), (38248), +(38471), (38480), (38481), (38469), (37430), (37311), (37313), (38292), (38538), (38658), (38683), (37164), (37827), (37893), (37894), (37895), +(37896), (37897), (37297), (37298), (38301), (38578), (38916), (37955), (37967), (37976), (38052), (38140), (38204), (38383), (38524), (38525), +(38527), (37210), (37225), (37273), (37278), (37279), (37281), (37284), (37285), (37286), (37295), (37296), (37315), (37316), (37317), (37318), +(37321), (37323), (37324), (37385), (37386), (37400), (37420), (37433), (37444), (37448), (37450), (37451), (37453), (37454), (37455), (37457), +(37466), (37468), (37469), (37470), (37472), (37473), (37474), (37477), (37485), (37510), (37511), (37534), (37536), (37544), (38164), (38254), +(38255), (38256), (37343), (37345), (37346), (37338), (37326), (37329), (37335), (37336), (37337), (37710), (37312), (37163), (37154), (37126), +(37348), (38640), (38970), (38994), (38996), (38983), (37706), (38958), (37452), (38270), (38271), (38272), (38561), (38597), (38643), (38625), +(38957), (38567), (37161), (37157), (37158), (37489), (37898), (37900), (37901), (37902), (37903), (37904), (37905), (37906), (37907), (37908), +(37909), (37100), (37250), (37303), (37372), (37501), (37815), (37837), (37859), (37860), (37925), (38089), (38186), (38233), (38266), (38324), +(38380), (38382), (38483), (38498), (38512), (38577), (38600), (38606), (38619), (38621), (38622), (38623), (38624), (38629), (38630), (38631), +(37063), (37089), (37090), (37148), (37301), (37711), (37742), (37878), (38333), (38587), (38644), (38687), (38448), (37839), (38497), (38496), +(38626), (37467), (37579), (38261), (38263), (38264), (38268), (38269), (38273), (38274), (38605), (40481), (41900), (41911), (41995), (40549), +(39715), (40406), (40407), (40408), (40409), (40410), (40412), (40414), (40650), (39263), (39427), (39467), (39468), (39470), (39472), (39473), +(40307), (40553), (40440), (40441), (40442), (40443), (40444), (39769), (41749), (41342), (39303), (40480), (41605), (41606), (40762), (40777), +(40599), (40727), (40754), (40832), (40839), (40725), (41403), (41404), (41405), (41406), (41407), (41408), (41409), (41410), (41411), (41412), +(41413), (41414), (41415), (41416), (41417), (41418), (41419), (41420), (41421), (41422), (41423), (41796), (41125), (39370), (40232), (41133), +(39364), (39410), (39440), (39460), (39819), (39828), (41756), (41757), (41758), (41759), (39707), (39708), (39709), (39710), (39711), (41178), +(41750), (41753), (39685), (41147), (41166), (41174), (41196), (39644), (39687), (39738), (39969), (40199), (40776), (41091), (41093), (41111), +(41118), (41173), (39526), (39527), (41195), (39148), (39213), (39343), (39692), (41741), (41800), (41801), (41802), (41803), (41804), (41805), +(41806), (41807), (41808), (41809), (41810), (41811), (41812), (41813), (41814), (40773), (41194), (39342), (40484), (40948), (41193), (41172), +(39341), (41192), (41171), (39340), (41169), (41191), (39339), (41170), (39338), (39302), (39334), (39151), (39162), (39163), (39314), (39575), +(39576), (39614), (39739), (39748), (39903), (39904), (40110), (40218), (40219), (40220), (40221), (40222), (40223), (40224), (40225), (40226), +(40227), (40228), (40229), (40230), (40231), (40389), (40686), (41132), (41585), (39506), (39883), (39153), (39743), (39754), (42000), (42007), +(42013), (42019), (42083), (42238), (42207), (42226), (42231), (42236), (42241), (42254), (42259), (42264), (42269), (42274), (42279), (42284), +(42289), (42316), (42321), (42326), (42331), (42345), (42351), (42359), (42383), (42389), (42449), (42484), (42489), (42494), (42501), (42512), +(42518), (42524), (42530), (42536), (42558), (42563), (42569), (42577), (42582), (42587), (42596), (42601), (42606), (42613), (42619), (42654), +(42655), (42656), (42657), (42658), (42851), (42664), (42665), (42666), (42667), (42668), (42625), (42626), (42627), (42628), (42629), (42659), +(42660), (42661), (42662), (42663), (42690), (42691), (42692), (42693), (42694), (42695), (42696), (42697), (42698), (42699), (42630), (42631), +(42632), (42633), (42634), (42635), (42636), (42637), (42638), (42639), (42669), (42670), (42671), (42672), (42673), (42674), (42675), (42676), +(42677), (42678), (42680), (42681), (42682), (42683), (42684), (42685), (42686), (42687), (42688), (42689), (42703), (42704), (42705), (42706), +(42707), (42708), (42709), (42710), (42711), (42712), (42713), (42714), (42715), (42716), (42717), (42718), (42719), (42720), (42721), (42722), +(42197), (42198), (42199), (42200), (42201), (42202), (42976), (42206), (42212), (42213), (42214), (42215), (42216), (42217), (42218), (42219), +(42220), (42221), (42222), (42223), (42224), (42294), (42295), (42296), (42297), (42343), (42344), (42356), (42382), (42388), (42444), (42445), +(42446), (42447), (42448), (42511), (42517), (42523), (42529), (42535), (42556), (42557), (42568), (42574), (42575), (42576), (42593), (42594), +(42595), (42611), (42612), (42618), (42755), (42953), (42975), (42977), (42978), (42979), (42980), (42981), (42982), (42983), (42875), (42885), +(42886), (42174), (42179), (42425), (42147), (42434), (42171), (42545), (42180), (42181), (42182), (42186), (42189), (42190), (42191), (42192), +(42193), (42194), (42195), (42196), (42432), (42433), (42170), (42986), (42590), (42474), (42440), (42894), (42733), (42342), (42350), (42381), +(42776), (42940), (43651), (43727), (43728), (43729), (43730), (43731), (43460), (43611), (43612), (43613), (43732), (43733), (43734), (43735), +(43736), (43737), (43738), (43739), (43740), (43741), (43742), (43743), (43744), (43745), (43746), (43747), (43748), (43749), (43750), (43751), +(43752), (43753), (43754), (43755), (43756), (43757), (43758), (43759), (43760), (43761), (43762), (43763), (43764), (43765), (43766), (43767), +(43768), (43769), (43770), (43771), (43772), (43773), (43774), (43775), (43776), (43777), (43778), (43779), (43780), (43781), (43782), (43783), +(43784), (43785), (43786), (43787), (43788), (43789), (43790), (43791), (43792), (43793), (43794), (43795), (43796), (43797), (43798), (43799), +(43800), (43801), (43802), (43803), (43804), (43805), (43806), (43807), (43808), (43809), (43810), (43811), (43812), (43813), (43814), (43815), +(43816), (43817), (43818), (43819), (43820), (43822), (43069), (43071), (43072), (43075), (43076), (43079), (43080), (43083), (43267), (43963), +(43964), (43475), (43476), (43302), (43303), (43304), (43949), (43517), (43698), (43648), (43848), (43878), (43895), (43922), (43936), (43938), +(43109), (43563), (43108), (43298), (43562), (43107), (43561), (43106), (43560), (43105), (43559), (43104), (43558), (43103), (43557), (43150), +(43523), (43087), (43097), (43518), (43468), (43571), (43572), (43614), (43620), (43621), (43647), (43652), (43038), (43646), (43002), (43099), +(43136), (43144), (43149), (43269), (43270), (43272), (43274), (43275), (43276), (43308), (43336), (43337), (43384), (43362), (43006), (43093), +(43288), (43307), (43471), (43486), (43489), (43617), (43618), (43619), (43627), (43628), (43629), (43630), (43631), (43632), (43633), (43634), +(43635), (43636), (43637), (43638), (43639), (43640), (43641), (43650), (43695), (43215), (43493), (43659), (43003), (43321), (43325), (43326), +(43328), (43329), (43330), (43333), (43341), (43576), (43577), (43643), (43644), (43645), (43653), (43658), (43675), (43676), (43677), (43678), +(43679), (43680), (43681), (43682), (43683), (43684), (43685), (43686), (43687), (43694), (43701), (43702), (43703), (43704), (43705), (43706), +(43707), (43708), (43709), (43710), (43711), (43712), (43713), (43714), (43715), (43716), (43717), (43718), (43719), (43720), (43721), (43722), +(43723), (44090), (44807), (45457), (45459), (45460), (45461), (45462), (45605), (45455), (45538), (45539), (45540), (45541), (45542), (45543), +(45544), (45547), (45548), (45549), (45350), (45464), (44310), (44311), (44333), (44417), (44418), (44869), (44870), (44926), (44948), (45924), +(44924), (44555), (44556), (44557), (44871), (44872), (44873), (44874), (44164), (44175), (45280), (45024), (45037), (45173), (44191), (44415), +(44416), (45172), (44505), (45174), (45175), (44391), (44392), (45850), (45851), (45852), (45853), (44945), (44563), (44875), (44876), (44877), +(44878), (44879), (44880), (44881), (44882), (44883), (44884), (45705), (44451), (44619), (44627), (44629), (44600), (44811), (44158), (44148), +(45180), (44260), (44261), (44262), (44263), (44264), (44265), (44266), (44267), (44268), (44269), (44270), (44271), (44272), (44273), (44274), +(44275), (44277), (44278), (44279), (44280), (44281), (44282), (44284), (44285), (44286), (44287), (44288), (44289), (44290), (44291), (44292), +(44293), (44866), (44972), (45063), (44703), (45575), (45126), (44428), (45052), (45050), (45629), (44849), (45127), (45229), (45230), (45231), +(45500), (44817), (44607), (45006), (45007), (45008), (45009), (44506), (44507), (45279), (45863), (45901), (45909), (44221), (44229), (44598), +(44608), (44609), (44475), (45276), (45277), (44432), (45908), (44743), (44604), (45942), (44462), (44480), (44508), (44620), (44646), (44680), +(44832), (44851), (44852), (44856), (44915), (44981), (44988), (44989), (44991), (44992), (44993), (44994), (44996), (44997), (45003), (45026), +(45028), (45029), (45030), (45031), (45032), (45033), (45036), (45045), (45049), (45082), (45120), (45278), (45328), (45569), (45728), (45729), +(45730), (45748), (45749), (45750), (45751), (45752), (45754), (45759), (45765), (45860), (45899), (45902), (45903), (45904), (45905), (44304), +(44434), (44656), (44718), (45034), (45035), (45568), (44299), (45630), (44728), (44236), (44298), (44300), (44578), (44580), (44705), (44755), +(44760), (44761), (44833), (45061), (45176), (45177), (45178), (45179), (45188), (45189), (45190), (45191), (45194), (45195), (45196), (45197), +(45198), (45199), (45200), (45201), (45202), (45900), (45907), (46105), (46104), (46214), (46215), (46217), (46218), (46219), (46220), (46222), +(46225), (46227), (46228), (46230), (46232), (46233), (46234), (46235), (46236), (46237), (46238), (46239), (46240), (46241), (46242), (46243), +(46244), (46245), (46246), (46248), (46255), (46256), (46257), (46273), (46274), (46275), (46276), (46277), (46288), (46289), (46290), (46291), +(46292), (46293), (46294), (46295), (46296), (46297), (46298), (46299), (46300), (46301), (46302), (46303), (46304), (46305), (46306), (46307), +(46103), (46213), (46216), (46221), (46223), (46224), (46226), (46231), (46247), (46249), (46250), (46251), (46252), (46253), (46254), (46258), +(46259), (46260), (46261), (46262), (46263), (46264), (46265), (46266), (46267), (46268), (46269), (46270), (46271), (46272), (46278), (46279), +(46280), (46281), (46282), (46283), (46284), (46285), (46286), (46287), (46309), (46339), (46340), (46341), (46342), (46343), (46344), (46345), +(46346), (46347), (46350), (46351), (47497), (47229), (46101), (46778), (46331), (47246), (46709), (46767), (46802), (46892), (46780), (46765), +(46766), (46849), (47507), (47395), (46399), (46400), (46401), (46402), (46403), (46055), (46847), (47030), (46887), (46054), (46735), (46069), +(46070), (46106), (46319), (46395), (46783), (46830), (46978), (47036), (46852), (46957), (49686), (48435), (48438), (48440), (48442), (48444), +(48507), (48509), (48511), (48513), (48515), (48517), (48519), (48521), (48523), (49191), (49497), (48725), (48726), (48727), (48728), (48729), +(48730), (48731), (48732), (48733), (48734), (48735), (48736), (48737), (48738), (48739), (48740), (48741), (48742), (48743), (48744), (48745), +(48746), (48747), (48748), (48749), (48750), (48751), (48752), (48753), (48754), (48755), (48756), (48757), (48758), (48759), (48760), (48761), +(48762), (48763), (48764), (48769), (48770), (48771), (48772), (48773), (48774), (48775), (48776), (48777), (48778), (48781), (48782), (48783), +(48784), (48785), (48786), (48787), (48788), (48789), (48790), (48794), (48795), (48796), (48797), (48798), (48799), (48800), (48801), (48802), +(48803), (48804), (48805), (48806), (48807), (48808), (48809), (48810), (48811), (48812), (48813), (48814), (48815), (48816), (48817), (48818), +(48819), (48820), (48821), (48822), (48823), (48824), (48825), (48826), (48827), (48828), (48829), (48830), (48831), (48832), (48833), (48836), +(48837), (48838), (48839), (48840), (48841), (48842), (48843), (48844), (48845), (48846), (48847), (48848), (48849), (48850), (48851), (48852), +(48853), (48854), (48855), (48860), (48861), (48862), (48863), (48864), (48865), (48866), (48867), (48868), (48869), (48870), (48871), (48872), +(48873), (48874), (48875), (48876), (48877), (48878), (48879), (48880), (48881), (48882), (48883), (48884), (48885), (48886), (48887), (48888), +(48889), (48890), (48891), (48892), (48893), (48894), (48895), (48896), (48897), (48898), (48899), (48900), (48901), (48902), (48903), (48904), +(48905), (48906), (48907), (48908), (48909), (48910), (48911), (48912), (48913), (48914), (48915), (48916), (48917), (48918), (48919), (48922), +(48923), (48924), (48925), (48926), (48927), (48928), (48929), (48930), (48931), (49301), (49312), (49313), (49314), (49852), (49853), (49854), +(49855), (49334), (49703), (49704), (49706), (48945), (49050), (48527), (49662), (49663), (49665), (49693), (49343), (49640), (49917), (48601), +(49288), (49289), (48679), (49362), (49223), (49278), (49340), (49373), (49655), (49680), (49739), (49750), (49915), (49916), (49209), (49645), +(49689), (49708), (49733), (49873), (49984), (50442), (50204), (51682), (51683), (51684), (51685), (51686), (51687), (51688), (51689), (51690), +(51691), (51692), (51693), (51694), (51695), (51696), (51697), (51698), (51699), (51700), (51701), (51702), (51703), (51704), (51705), (51706), +(51707), (51708), (51709), (51710), (51711), (51712), (51713), (51714), (51715), (51716), (51717), (51718), (51719), (51720), (51721), (51722), +(51723), (51724), (51725), (51726), (51727), (51728), (51729), (51730), (51731), (51732), (51733), (51734), (51735), (51736), (51737), (51738), +(51739), (51740), (51741), (51742), (51743), (51744), (51745), (51746), (51747), (51748), (51749), (51750), (51751), (51752), (51753), (51754), +(51755), (51756), (51757), (51758), (51759), (51760), (51761), (51762), (51763), (51764), (51765), (51766), (51767), (51768), (51769), (51770), +(51771), (51772), (51773), (51774), (51775), (51776), (53491), (53492), (53493), (53494), (53495), (53496), (53497), (53498), (53499), (53500), +(53501), (53502), (53503), (53504), (53505), (53506), (53507), (53508), (53509), (54592), (50315), (50318), (50319), (52567), (50815), (53889), +(53890), (54069), (54860), (50840), (53891), (53924), (51997), (51998), (54847), (54857), (56806), (54212), (54452), (54810), (50093), (54822), +(50289), (50301), (50307), (52189), (52202), (52272), (52275), (52276), (52345), (52562), (52563), (52565), (52729), (53510), (54218), (54455), +(54467), (50248), (50431), (52011), (52062), (54291), (54470); diff --git a/data/sql/db-world/z_filter_disabled_and_trash.sql b/data/sql/db-world/z_filter_disabled_and_trash.sql new file mode 100644 index 00000000..08b7b169 --- /dev/null +++ b/data/sql/db-world/z_filter_disabled_and_trash.sql @@ -0,0 +1,66 @@ + +INSERT IGNORE INTO mod_auctionhousebot_disabled_items (item) +SELECT entry +FROM item_template +WHERE ( + NAME LIKE '%tablet%' OR + NAME LIKE '%sulfuron%' OR + NAME LIKE '%nightcrawlers%' OR + NAME LIKE '%throwing dagger%' OR + NAME LIKE '%shot pouch%' OR + NAME LIKE '%brimstone%' OR + NAME LIKE '%small pouch%' OR + NAME LIKE '%dye%' OR + NAME LIKE '%ironwood seed%' OR + NAME LIKE '%stranglethorn seed%' OR + NAME LIKE '%simple wood%' OR + NAME LIKE '%bleach%' OR + NAME LIKE '%flour%' OR + NAME LIKE '%brew%' OR + NAME LIKE '%parchment%' OR + NAME LIKE '%light quiver%' OR + NAME LIKE '%honey%' OR + NAME LIKE '%/%' OR + NAME LIKE '%creeping anguish%' OR + NAME LIKE '%felcloth bag%' OR + NAME LIKE '%elementium ore%' OR + NAME LIKE '%unused%' OR + NAME LIKE '%lava core%' OR + NAME LIKE '%fiery core%' OR + NAME LIKE '%sulfuron ingot%' OR + NAME LIKE '%sak%' OR + NAME LIKE '%gigantique%' OR + NAME LIKE '%portable hole%' OR + NAME LIKE '%deptecated%' OR + NAME LIKE '%durability%' OR + NAME LIKE '%big sack%' OR + NAME LIKE '%decoded%' OR + NAME LIKE '%knowledge:%' OR + NAME LIKE '%manual%' OR + NAME LIKE '%gnome head%' OR + NAME LIKE '%critter enlarger%' OR + NAME LIKE '%box of%' OR + NAME LIKE '%summoning%' OR + NAME LIKE '%turtle egg%' OR + NAME LIKE '%heavy crate%' OR + NAME LIKE '%assasin throwing axe%' OR + NAME LIKE '%sack of gems%' OR + NAME LIKE '%plans: darkspear%' OR + NAME LIKE '%of swords%' OR + NAME LIKE '%gnomish alarm%' OR + NAME LIKE '%world enlarger%' OR + NAME LIKE '%tome%' OR + NAME LIKE '%ornate spyglass%' OR + NAME LIKE '%test%' OR + NAME LIKE '%darkmoon prize%' OR + NAME LIKE '%codex%' OR + NAME LIKE '%grimoire%' OR + NAME LIKE '%deprecated%' OR + NAME LIKE '%book%' OR + NAME LIKE '%libram%' OR + NAME LIKE '%guide%' +) +OR NAME COLLATE utf8mb4_bin LIKE '%OLD%' +OR UPPER(NAME) LIKE '%NPC%' +OR UPPER(NAME) LIKE '%QA%' +OR (CLASS = 0 AND SUBCLASS = 5 AND REQUIREDLEVEL < 40); diff --git a/pull_request_template.md b/pull_request_template.md new file mode 100644 index 00000000..21c92458 --- /dev/null +++ b/pull_request_template.md @@ -0,0 +1,25 @@ + + +## Changes Proposed: +- +- + +## Issues Addressed: + +- Closes + +## SOURCE: + + +## Tests Performed: + +- +- + + +## How to Test the Changes: + + +1. +2. +3. diff --git a/sql/auth/.gitkeep b/sql/auth/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/sql/characters/.gitkeep b/sql/characters/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/sql/world/.gitkeep b/sql/world/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/sql/world/auctionhousebot.sql b/sql/world/auctionhousebot.sql deleted file mode 100644 index aff7d928..00000000 --- a/sql/world/auctionhousebot.sql +++ /dev/null @@ -1,93 +0,0 @@ -/* -Navicat MySQL Data Transfer - -Source Server : localhost_3306 -Source Server Version : 50509 -Source Host : 127.0.0.1:3306 -Source Database : _test_world - -Target Server Type : MYSQL -Target Server Version : 50509 -File Encoding : 65001 - -Date: 2018-05-13 21:34:11 -*/ - -SET FOREIGN_KEY_CHECKS=0; - --- ---------------------------- --- Table structure for auctionhousebot --- ---------------------------- -DROP TABLE IF EXISTS `auctionhousebot`; -CREATE TABLE `auctionhousebot` ( - `auctionhouse` int(11) NOT NULL DEFAULT '0' COMMENT 'mapID of the auctionhouse.', - `name` char(25) DEFAULT NULL COMMENT 'Text name of the auctionhouse.', - `minitems` int(11) DEFAULT '0' COMMENT 'This is the minimum number of items you want to keep in the auction house. a 0 here will make it the same as the maximum.', - `maxitems` int(11) DEFAULT '0' COMMENT 'This is the number of items you want to keep in the auction house.', - `percentgreytradegoods` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the Grey Trade Goods auction items', - `percentwhitetradegoods` int(11) DEFAULT '27' COMMENT 'Sets the percentage of the White Trade Goods auction items', - `percentgreentradegoods` int(11) DEFAULT '12' COMMENT 'Sets the percentage of the Green Trade Goods auction items', - `percentbluetradegoods` int(11) DEFAULT '10' COMMENT 'Sets the percentage of the Blue Trade Goods auction items', - `percentpurpletradegoods` int(11) DEFAULT '1' COMMENT 'Sets the percentage of the Purple Trade Goods auction items', - `percentorangetradegoods` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the Orange Trade Goods auction items', - `percentyellowtradegoods` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the Yellow Trade Goods auction items', - `percentgreyitems` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the non trade Grey auction items', - `percentwhiteitems` int(11) DEFAULT '10' COMMENT 'Sets the percentage of the non trade White auction items', - `percentgreenitems` int(11) DEFAULT '30' COMMENT 'Sets the percentage of the non trade Green auction items', - `percentblueitems` int(11) DEFAULT '8' COMMENT 'Sets the percentage of the non trade Blue auction items', - `percentpurpleitems` int(11) DEFAULT '2' COMMENT 'Sets the percentage of the non trade Purple auction items', - `percentorangeitems` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the non trade Orange auction items', - `percentyellowitems` int(11) DEFAULT '0' COMMENT 'Sets the percentage of the non trade Yellow auction items', - `minpricegrey` int(11) DEFAULT '100' COMMENT 'Minimum price of Grey items (percentage).', - `maxpricegrey` int(11) DEFAULT '150' COMMENT 'Maximum price of Grey items (percentage).', - `minpricewhite` int(11) DEFAULT '150' COMMENT 'Minimum price of White items (percentage).', - `maxpricewhite` int(11) DEFAULT '250' COMMENT 'Maximum price of White items (percentage).', - `minpricegreen` int(11) DEFAULT '800' COMMENT 'Minimum price of Green items (percentage).', - `maxpricegreen` int(11) DEFAULT '1400' COMMENT 'Maximum price of Green items (percentage).', - `minpriceblue` int(11) DEFAULT '1250' COMMENT 'Minimum price of Blue items (percentage).', - `maxpriceblue` int(11) DEFAULT '1750' COMMENT 'Maximum price of Blue items (percentage).', - `minpricepurple` int(11) DEFAULT '2250' COMMENT 'Minimum price of Purple items (percentage).', - `maxpricepurple` int(11) DEFAULT '4550' COMMENT 'Maximum price of Purple items (percentage).', - `minpriceorange` int(11) DEFAULT '3250' COMMENT 'Minimum price of Orange items (percentage).', - `maxpriceorange` int(11) DEFAULT '5550' COMMENT 'Maximum price of Orange items (percentage).', - `minpriceyellow` int(11) DEFAULT '5250' COMMENT 'Minimum price of Yellow items (percentage).', - `maxpriceyellow` int(11) DEFAULT '6550' COMMENT 'Maximum price of Yellow items (percentage).', - `minbidpricegrey` int(11) DEFAULT '70' COMMENT 'Starting bid price of Grey items as a percentage of the randomly chosen buyout price. Default: 70', - `maxbidpricegrey` int(11) DEFAULT '100' COMMENT 'Starting bid price of Grey items as a percentage of the randomly chosen buyout price. Default: 100', - `minbidpricewhite` int(11) DEFAULT '70' COMMENT 'Starting bid price of White items as a percentage of the randomly chosen buyout price. Default: 70', - `maxbidpricewhite` int(11) DEFAULT '100' COMMENT 'Starting bid price of White items as a percentage of the randomly chosen buyout price. Default: 100', - `minbidpricegreen` int(11) DEFAULT '80' COMMENT 'Starting bid price of Green items as a percentage of the randomly chosen buyout price. Default: 80', - `maxbidpricegreen` int(11) DEFAULT '100' COMMENT 'Starting bid price of Green items as a percentage of the randomly chosen buyout price. Default: 100', - `minbidpriceblue` int(11) DEFAULT '75' COMMENT 'Starting bid price of Blue items as a percentage of the randomly chosen buyout price. Default: 75', - `maxbidpriceblue` int(11) DEFAULT '100' COMMENT 'Starting bid price of Blue items as a percentage of the randomly chosen buyout price. Default: 100', - `minbidpricepurple` int(11) DEFAULT '80' COMMENT 'Starting bid price of Purple items as a percentage of the randomly chosen buyout price. Default: 80', - `maxbidpricepurple` int(11) DEFAULT '100' COMMENT 'Starting bid price of Purple items as a percentage of the randomly chosen buyout price. Default: 100', - `minbidpriceorange` int(11) DEFAULT '80' COMMENT 'Starting bid price of Orange items as a percentage of the randomly chosen buyout price. Default: 80', - `maxbidpriceorange` int(11) DEFAULT '100' COMMENT 'Starting bid price of Orange items as a percentage of the randomly chosen buyout price. Default: 100', - `minbidpriceyellow` int(11) DEFAULT '80' COMMENT 'Starting bid price of Yellow items as a percentage of the randomly chosen buyout price. Default: 80', - `maxbidpriceyellow` int(11) DEFAULT '100' COMMENT 'Starting bid price of Yellow items as a percentage of the randomly chosen buyout price. Default: 100', - `maxstackgrey` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', - `maxstackwhite` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', - `maxstackgreen` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', - `maxstackblue` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', - `maxstackpurple` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', - `maxstackorange` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', - `maxstackyellow` int(11) DEFAULT '0' COMMENT 'Stack size limits for item qualities - a value of 0 will disable a maximum stack size for that quality, which will allow the bot to create items in stack as large as the item allows.', - `buyerpricegrey` int(11) DEFAULT '1' COMMENT 'Multiplier to vendorprice when buying grey items from auctionhouse', - `buyerpricewhite` int(11) DEFAULT '3' COMMENT 'Multiplier to vendorprice when buying white items from auctionhouse', - `buyerpricegreen` int(11) DEFAULT '5' COMMENT 'Multiplier to vendorprice when buying green items from auctionhouse', - `buyerpriceblue` int(11) DEFAULT '12' COMMENT 'Multiplier to vendorprice when buying blue items from auctionhouse', - `buyerpricepurple` int(11) DEFAULT '15' COMMENT 'Multiplier to vendorprice when buying purple items from auctionhouse', - `buyerpriceorange` int(11) DEFAULT '20' COMMENT 'Multiplier to vendorprice when buying orange items from auctionhouse', - `buyerpriceyellow` int(11) DEFAULT '22' COMMENT 'Multiplier to vendorprice when buying yellow items from auctionhouse', - `buyerbiddinginterval` int(11) DEFAULT '1' COMMENT 'Interval how frequently AHB bids on each AH. Time in minutes', - `buyerbidsperinterval` int(11) DEFAULT '1' COMMENT 'number of bids to put in per bidding interval', - PRIMARY KEY (`auctionhouse`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- ---------------------------- --- Records of auctionhousebot --- ---------------------------- -INSERT INTO `auctionhousebot` VALUES ('2', 'Alliance', '250', '250', '0', '27', '12', '10', '1', '0', '0', '0', '10', '30', '8', '2', '0', '0', '100', '150', '150', '250', '800', '1400', '1250', '1750', '2250', '4550', '3250', '5550', '5250', '6550', '70', '100', '70', '100', '80', '100', '75', '100', '80', '100', '80', '100', '80', '100', '0', '0', '3', '2', '1', '1', '1', '1', '3', '5', '12', '15', '20', '22', '1', '1'); -INSERT INTO `auctionhousebot` VALUES ('6', 'Horde', '250', '250', '0', '27', '12', '10', '1', '0', '0', '0', '10', '30', '8', '2', '0', '0', '100', '150', '150', '250', '800', '1400', '1250', '1750', '2250', '4550', '3250', '5550', '5250', '6550', '70', '100', '70', '100', '80', '100', '75', '100', '80', '100', '80', '100', '80', '100', '0', '0', '3', '2', '1', '1', '1', '1', '3', '5', '12', '15', '20', '22', '1', '1'); -INSERT INTO `auctionhousebot` VALUES ('7', 'Neutral', '250', '250', '0', '27', '12', '10', '1', '0', '0', '0', '10', '30', '8', '2', '0', '0', '100', '150', '150', '250', '800', '1400', '1250', '1750', '2250', '4550', '3250', '5550', '5250', '6550', '70', '100', '70', '100', '80', '100', '75', '100', '80', '100', '80', '100', '80', '100', '0', '0', '3', '2', '1', '1', '1', '1', '3', '5', '12', '15', '20', '22', '1', '1'); diff --git a/src/AuctionHouseBot.cpp b/src/AuctionHouseBot.cpp index d9fb142d..4b85a0de 100644 --- a/src/AuctionHouseBot.cpp +++ b/src/AuctionHouseBot.cpp @@ -19,1471 +19,1137 @@ #include "ObjectMgr.h" #include "AuctionHouseMgr.h" -#include "AuctionHouseBot.h" #include "Config.h" #include "Player.h" #include "WorldSession.h" -#include +#include "GameTime.h" +#include "DatabaseEnv.h" +#include "ScriptMgr.h" + +#include "AuctionHouseBot.h" +#include "AuctionHouseBotCommon.h" +#include "AuctionHouseSearcher.h" using namespace std; -vector npcItems; -vector lootItems; -vector greyTradeGoodsBin; -vector whiteTradeGoodsBin; -vector greenTradeGoodsBin; -vector blueTradeGoodsBin; -vector purpleTradeGoodsBin; -vector orangeTradeGoodsBin; -vector yellowTradeGoodsBin; -vector greyItemsBin; -vector whiteItemsBin; -vector greenItemsBin; -vector blueItemsBin; -vector purpleItemsBin; -vector orangeItemsBin; -vector yellowItemsBin; - -AuctionHouseBot::AuctionHouseBot() + +AuctionHouseBot::AuctionHouseBot(uint32 account, uint32 id) { - debug_Out = false; - debug_Out_Filters = false; - AHBSeller = false; - AHBBuyer = false; - - //Begin Filters - - Vendor_Items = false; - Loot_Items = false; - Other_Items = false; - Vendor_TGs = false; - Loot_TGs = false; - Other_TGs = false; - - No_Bind = false; - Bind_When_Picked_Up = false; - Bind_When_Equipped = false; - Bind_When_Use = false; - Bind_Quest_Item = false; - - DisablePermEnchant = false; - DisableConjured = false; - DisableGems = false; - DisableMoney = false; - DisableMoneyLoot = false; - DisableLootable = false; - DisableKeys = false; - DisableDuration = false; - DisableBOP_Or_Quest_NoReqLevel = false; - - DisableWarriorItems = false; - DisablePaladinItems = false; - DisableHunterItems = false; - DisableRogueItems = false; - DisablePriestItems = false; - DisableDKItems = false; - DisableShamanItems = false; - DisableMageItems = false; - DisableWarlockItems = false; - DisableUnusedClassItems = false; - DisableDruidItems = false; - - DisableItemsBelowLevel = 0; - DisableItemsAboveLevel = 0; - DisableTGsBelowLevel = 0; - DisableTGsAboveLevel = 0; - DisableItemsBelowGUID = 0; - DisableItemsAboveGUID = 0; - DisableTGsBelowGUID = 0; - DisableTGsAboveGUID = 0; - DisableItemsBelowReqLevel = 0; - DisableItemsAboveReqLevel = 0; - DisableTGsBelowReqLevel = 0; - DisableTGsAboveReqLevel = 0; - DisableItemsBelowReqSkillRank = 0; - DisableItemsAboveReqSkillRank = 0; - DisableTGsBelowReqSkillRank = 0; - DisableTGsAboveReqSkillRank = 0; - - //End Filters - - _lastrun_a = time(NULL); - _lastrun_h = time(NULL); - _lastrun_n = time(NULL); - - AllianceConfig = AHBConfig(2); - HordeConfig = AHBConfig(6); - NeutralConfig = AHBConfig(7); + _account = account; + _id = id; + + _lastrun_a_sec = time(NULL); + _lastrun_h_sec = time(NULL); + _lastrun_n_sec = time(NULL); + + _allianceConfig = NULL; + _hordeConfig = NULL; + _neutralConfig = NULL; } AuctionHouseBot::~AuctionHouseBot() { + // Nothing } -void AuctionHouseBot::addNewAuctions(Player *AHBplayer, AHBConfig *config) +uint32 AuctionHouseBot::getElement(std::set set, int index, uint32 botId, uint32 maxDup, AuctionHouseObject* auctionHouse) { - if (!AHBSeller) + std::set::iterator it = set.begin(); + std::advance(it, index); + + if (maxDup > 0) { - if (debug_Out) sLog->outString("AHSeller: Disabled"); - return; - } + uint32 noStacks = 0; - uint32 minItems = config->GetMinItems(); - uint32 maxItems = config->GetMaxItems(); + for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr) + { + AuctionEntry* Aentry = itr->second; - if (maxItems == 0) - { - //if (debug_Out) sLog->outString( "AHSeller: Auctions disabled"); - return; - } + if (Aentry->owner.GetCounter() == botId) + { + if (*it == Aentry->item_template) + { + noStacks++; + } + } + } - AuctionHouseEntry const* ahEntry = sAuctionMgr->GetAuctionHouseEntry(config->GetAHFID()); - if (!ahEntry) - { - return; - } - AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(config->GetAHFID()); - if (!auctionHouse) - { - return; + if (noStacks >= maxDup) + { + return 0; + } } - uint32 auctions = auctionHouse->Getcount(); - - uint32 items = 0; + return *it; +} - if (auctions >= minItems) +uint32 AuctionHouseBot::getStackCount(AHBConfig* config, uint32 max) +{ + if (max == 1) { - //if (debug_Out) sLog->outError( "AHSeller: Auctions above minimum"); - return; + return 1; } - if (auctions >= maxItems) + // + // Organize the stacks in a pseudo random way + // + + if (config->DivisibleStacks) { - //if (debug_Out) sLog->outError( "AHSeller: Auctions at or above maximum"); - return; - } + uint32 ret = 0; - if ((maxItems - auctions) >= ItemsPerCycle) - items = ItemsPerCycle; - else - items = (maxItems - auctions); + if (max % 5 == 0) // 5, 10, 15, 20 + { + ret = urand(1, 4) * 5; + } - if (debug_Out) sLog->outString("AHSeller: Adding %u Auctions", items); + if (max % 4 == 0) // 4, 8, 12, 16 + { + ret = urand(1, 4) * 4; + } - uint32 AuctioneerGUID = 0; + if (max % 3 == 0) // 3, 6, 9, 18 + { + ret = urand(1, 3) * 3; + } - switch (config->GetAHID()) - { - case 2: - AuctioneerGUID = 79707; //Human in stormwind. - break; - case 6: - AuctioneerGUID = 4656; //orc in Orgrimmar - break; - case 7: - AuctioneerGUID = 23442; //goblin in GZ - break; - default: - if (debug_Out) sLog->outError( "AHSeller: GetAHID() - Default switch reached"); - AuctioneerGUID = 23442; //default to neutral 7 - break; + if (ret > max) + { + ret = max; + } + + return ret; } - if (debug_Out) sLog->outError( "AHSeller: Current Auctineer GUID is %u", AuctioneerGUID); - - uint32 greyTGcount = config->GetPercents(AHB_GREY_TG); - uint32 whiteTGcount = config->GetPercents(AHB_WHITE_TG); - uint32 greenTGcount = config->GetPercents(AHB_GREEN_TG); - uint32 blueTGcount = config->GetPercents(AHB_BLUE_TG); - uint32 purpleTGcount = config->GetPercents(AHB_PURPLE_TG); - uint32 orangeTGcount = config->GetPercents(AHB_ORANGE_TG); - uint32 yellowTGcount = config->GetPercents(AHB_YELLOW_TG); - uint32 greyIcount = config->GetPercents(AHB_GREY_I); - uint32 whiteIcount = config->GetPercents(AHB_WHITE_I); - uint32 greenIcount = config->GetPercents(AHB_GREEN_I); - uint32 blueIcount = config->GetPercents(AHB_BLUE_I); - uint32 purpleIcount = config->GetPercents(AHB_PURPLE_I); - uint32 orangeIcount = config->GetPercents(AHB_ORANGE_I); - uint32 yellowIcount = config->GetPercents(AHB_YELLOW_I); -/* uint32 total = greyTGcount + whiteTGcount + greenTGcount + blueTGcount - + purpleTGcount + orangeTGcount + yellowTGcount - + whiteIcount + greenIcount + blueIcount + purpleIcount - + orangeIcount + yellowIcount; -*/ - uint32 greyTGoods = config->GetItemCounts(AHB_GREY_TG); - uint32 whiteTGoods = config->GetItemCounts(AHB_WHITE_TG); - uint32 greenTGoods = config->GetItemCounts(AHB_GREEN_TG); - uint32 blueTGoods = config->GetItemCounts(AHB_BLUE_TG); - uint32 purpleTGoods = config->GetItemCounts(AHB_PURPLE_TG); - uint32 orangeTGoods = config->GetItemCounts(AHB_ORANGE_TG); - uint32 yellowTGoods = config->GetItemCounts(AHB_YELLOW_TG); - - uint32 greyItems = config->GetItemCounts(AHB_GREY_I); - uint32 whiteItems = config->GetItemCounts(AHB_WHITE_I); - uint32 greenItems = config->GetItemCounts(AHB_GREEN_I); - uint32 blueItems = config->GetItemCounts(AHB_BLUE_I); - uint32 purpleItems = config->GetItemCounts(AHB_PURPLE_I); - uint32 orangeItems = config->GetItemCounts(AHB_ORANGE_I); - uint32 yellowItems = config->GetItemCounts(AHB_YELLOW_I); - if (debug_Out) sLog->outError( "AHSeller: %u items", items); - - // only insert a few at a time, so as not to peg the processor - for (uint32 cnt = 1; cnt <= items; cnt++) - { - if (debug_Out) sLog->outError( "AHSeller: %u count", cnt); - uint32 itemID = 0; - uint32 itemColor = 99; - uint32 loopbreaker = 0; - while (itemID == 0 && loopbreaker <= 50) - { - ++loopbreaker; - uint32 choice = urand(0, 13); - itemColor = choice; - switch (choice) - { - case 0: - { - if ((greyItemsBin.size() > 0) && (greyItems < greyIcount)) - itemID = greyItemsBin[urand(0, greyItemsBin.size() - 1)]; - else continue; - break; - } - case 1: - { - if ((whiteItemsBin.size() > 0) && (whiteItems < whiteIcount)) - itemID = whiteItemsBin[urand(0, whiteItemsBin.size() - 1)]; - else continue; - break; - } - case 2: - { - if ((greenItemsBin.size() > 0) && (greenItems < greenIcount)) - itemID = greenItemsBin[urand(0, greenItemsBin.size() - 1)]; - else continue; - break; - } - case 3: - { - if ((blueItemsBin.size() > 0) && (blueItems < blueIcount)) - itemID = blueItemsBin[urand(0, blueItemsBin.size() - 1)]; - else continue; - break; - } - case 4: - { - if ((purpleItemsBin.size() > 0) && (purpleItems < purpleIcount)) - itemID = purpleItemsBin[urand(0, purpleItemsBin.size() - 1)]; - else continue; - break; - } - case 5: - { - if ((orangeItemsBin.size() > 0) && (orangeItems < orangeIcount)) - itemID = orangeItemsBin[urand(0, orangeItemsBin.size() - 1)]; - else continue; - break; - } - case 6: - { - if ((yellowItemsBin.size() > 0) && (yellowItems < yellowIcount)) - itemID = yellowItemsBin[urand(0, yellowItemsBin.size() - 1)]; - else continue; - break; - } - case 7: - { - if ((greyTradeGoodsBin.size() > 0) && (greyTGoods < greyTGcount)) - itemID = greyTradeGoodsBin[urand(0, greyTradeGoodsBin.size() - 1)]; - else continue; - break; - } - case 8: - { - if ((whiteTradeGoodsBin.size() > 0) && (whiteTGoods < whiteTGcount)) - itemID = whiteTradeGoodsBin[urand(0, whiteTradeGoodsBin.size() - 1)]; - else continue; - break; - } - case 9: - { - if ((greenTradeGoodsBin.size() > 0) && (greenTGoods < greenTGcount)) - itemID = greenTradeGoodsBin[urand(0, greenTradeGoodsBin.size() - 1)]; - else continue; - break; - } - case 10: - { - if ((blueTradeGoodsBin.size() > 0) && (blueTGoods < blueTGcount)) - itemID = blueTradeGoodsBin[urand(0, blueTradeGoodsBin.size() - 1)]; - else continue; - break; - } - case 11: - { - if ((purpleTradeGoodsBin.size() > 0) && (purpleTGoods < purpleTGcount)) - itemID = purpleTradeGoodsBin[urand(0, purpleTradeGoodsBin.size() - 1)]; - else continue; - break; - } - case 12: - { - if ((orangeTradeGoodsBin.size() > 0) && (orangeTGoods < orangeTGcount)) - itemID = orangeTradeGoodsBin[urand(0, orangeTradeGoodsBin.size() - 1)]; - else continue; - break; - } - case 13: - { - if ((yellowTradeGoodsBin.size() > 0) && (yellowTGoods < yellowTGcount)) - itemID = yellowTradeGoodsBin[urand(0, yellowTradeGoodsBin.size() - 1)]; - else continue; - break; - } - default: - { - if (debug_Out) sLog->outError( "AHSeller: itemID Switch - Default Reached"); - break; - } - } + // + // Totally random + // - if (itemID == 0) - { - if (debug_Out) sLog->outError( "AHSeller: Item::CreateItem() - ItemID is 0"); - continue; - } + return urand(1, max); +} - ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(itemID); - if (prototype == NULL) - { - if (debug_Out) sLog->outError( "AHSeller: Huh?!?! prototype == NULL"); - continue; - } +uint32 AuctionHouseBot::getElapsedTime(uint32 timeClass) +{ + switch (timeClass) + { + case 2: + return urand(1, 6) * 600; // SHORT = From 10 to 60 minutes - Item* item = Item::CreateItem(itemID, 1, AHBplayer); - if (item == NULL) - { - if (debug_Out) sLog->outError( "AHSeller: Item::CreateItem() returned NULL"); - break; - } - item->AddToUpdateQueueOf(AHBplayer); + case 1: + return urand(1, 24) * 3600; // MEDIUM = From 1 to 24 hours - uint32 randomPropertyId = Item::GenerateItemRandomPropertyId(itemID); - if (randomPropertyId != 0) - item->SetItemRandomProperties(randomPropertyId); + default: + return urand(24, 72) * 3600; // LONG = From 1 to 3 days + } +} - uint64 buyoutPrice = 0; - uint64 bidPrice = 0; - uint32 stackCount = 1; +uint32 AuctionHouseBot::getNofAuctions(AHBConfig* config, AuctionHouseObject* auctionHouse, ObjectGuid guid) +{ + // + // All the auctions + // - switch (SellMethod) - { - case 0: - buyoutPrice = prototype->SellPrice; - break; - case 1: - buyoutPrice = prototype->BuyPrice; - break; - } + if (!config->ConsiderOnlyBotAuctions) + { + return auctionHouse->Getcount(); + } - if (prototype->Quality <= AHB_MAX_QUALITY) - { - if (config->GetMaxStack(prototype->Quality) > 1 && item->GetMaxStackCount() > 1) - stackCount = urand(1, minValue(item->GetMaxStackCount(), config->GetMaxStack(prototype->Quality))); - else if (config->GetMaxStack(prototype->Quality) == 0 && item->GetMaxStackCount() > 1) - stackCount = urand(1, item->GetMaxStackCount()); - else - stackCount = 1; - buyoutPrice *= urand(config->GetMinPrice(prototype->Quality), config->GetMaxPrice(prototype->Quality)); - buyoutPrice /= 100; - bidPrice = buyoutPrice * urand(config->GetMinBidPrice(prototype->Quality), config->GetMaxBidPrice(prototype->Quality)); - bidPrice /= 100; - } - else - { - // quality is something it shouldn't be, let's get out of here - if (debug_Out) sLog->outError( "AHBuyer: Quality %u not Supported", prototype->Quality); - item->RemoveFromUpdateQueueOf(AHBplayer); - continue; - } + // + // Just the one handled by the bot + // - 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; - } - item->SetCount(stackCount); - - uint32 dep = sAuctionMgr->GetAuctionDeposit(ahEntry, etime, item, stackCount); - - SQLTransaction trans = CharacterDatabase.BeginTransaction(); - AuctionEntry* auctionEntry = new AuctionEntry(); - auctionEntry->Id = sObjectMgr->GenerateAuctionID(); - auctionEntry->auctioneer = AuctioneerGUID; - auctionEntry->item_guidlow = item->GetGUIDLow(); - auctionEntry->item_template = item->GetEntry(); - auctionEntry->itemCount = item->GetCount(); - auctionEntry->owner = AHBplayer->GetGUIDLow(); - auctionEntry->startbid = bidPrice * stackCount; - auctionEntry->buyout = buyoutPrice * stackCount; - auctionEntry->bidder = 0; - auctionEntry->bid = 0; - auctionEntry->deposit = dep; - auctionEntry->expire_time = (time_t) etime + time(NULL); - auctionEntry->auctionHouseEntry = ahEntry; - item->SaveToDB(trans); - item->RemoveFromUpdateQueueOf(AHBplayer); - sAuctionMgr->AddAItem(item); - auctionHouse->AddAuction(auctionEntry); - auctionEntry->SaveToDB(trans); - CharacterDatabase.CommitTransaction(trans); + uint32 count = 0; - switch(itemColor) - { - case 0: - ++greyItems; - break; - case 1: - ++whiteItems; - break; - case 2: - ++greenItems; - break; - case 3: - ++blueItems; - break; - case 4: - ++purpleItems; - break; - case 5: - ++orangeItems; - break; - case 6: - ++yellowItems; - break; - case 7: - ++greyTGoods; - break; - case 8: - ++whiteTGoods; - break; - case 9: - ++greenTGoods; - break; - case 10: - ++blueTGoods; - break; - case 11: - ++purpleTGoods; - break; - case 12: - ++orangeTGoods; - break; - case 13: - ++yellowTGoods; - break; - default: - break; - } + for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr) + { + AuctionEntry* Aentry = itr->second; + + if (guid == Aentry->owner) + { + count++; } } + + return count; } -void AuctionHouseBot::addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *config, WorldSession *session) + +// ============================================================================= +// This routine performs the bidding/buyout operations for the bot +// ============================================================================= + +void AuctionHouseBot::Buy(Player* AHBplayer, AHBConfig* config, WorldSession* session) { - if (!AHBBuyer) + // + // Check if disabled + // + + if (!config->AHBBuyer) { - if (debug_Out) sLog->outError( "AHBuyer: Disabled"); return; } - QueryResult result = CharacterDatabase.PQuery("SELECT id FROM auctionhouse WHERE itemowner<>%u AND buyguid<>%u", AHBplayerGUID, AHBplayerGUID); + // + // Retrieve items not owned by the bot and not bought/bidded on by the bot + // + + QueryResult ahContentQueryResult = CharacterDatabase.Query("SELECT id FROM auctionhouse WHERE houseid={} AND itemowner<>{} AND buyguid<>{}", config->GetAHID(), _id, _id); - if (!result) + if (!ahContentQueryResult) + { return; + } - if (result->GetRowCount() == 0) + if (ahContentQueryResult->GetRowCount() == 0) + { return; + } - // Fetches content of selected AH - AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(config->GetAHFID()); - vector possibleBids; + if (config->DebugOutBuyer) + { + LOG_INFO("module", "AHBot [{}]: Performing Buy operations for AH={} nbOfAuctions={}", _id, config->GetAHID(), ahContentQueryResult->GetRowCount()); + } + + // + // Fetches content of selected AH to look for possible bids + // + + AuctionHouseObject* auctionHouseObject = sAuctionMgr->GetAuctionsMap(config->GetAHFID()); + std::set auctionsGuidsToConsider; do { - uint32 tmpdata = result->Fetch()->GetUInt32(); - possibleBids.push_back(tmpdata); - }while (result->NextRow()); + uint32 autionGuid = ahContentQueryResult->Fetch()->Get(); + auctionsGuidsToConsider.insert(autionGuid); + } while (ahContentQueryResult->NextRow()); - for (uint32 count = 1; count <= config->GetBidsPerInterval(); ++count) + // + // If it's not possible to bid stop here + // + + if (auctionsGuidsToConsider.empty()) { - // Do we have anything to bid? If not, stop here. - if (possibleBids.empty()) + if (config->DebugOutBuyer) { - //if (debug_Out) sLog->outError( "AHBuyer: I have no items to bid on."); - count = config->GetBidsPerInterval(); - continue; + LOG_INFO("module", "AHBot [{}]: no auctions to bid on has been recovered", _id); } - // Choose random auction from possible auctions - uint32 vectorPos = urand(0, possibleBids.size() - 1); - vector::iterator iter = possibleBids.begin(); - advance(iter, vectorPos); + return; + } + + // + // Perform the operation for a maximum amount of bids attempts configured + // + + if (config->TraceBuyer) + { + LOG_INFO("module", "AHBot [{}]: Considering {} auctions per interval to bid on.", _id, config->GetBidsPerInterval()); + } - // from auctionhousehandler.cpp, creates auction pointer & player pointer - AuctionEntry* auction = auctionHouse->GetAuction(*iter); + for (uint32 count = 1; count <= config->GetBidsPerInterval(); ++count) + { + if (auctionsGuidsToConsider.empty()) { + return; + } - // Erase the auction from the vector to prevent bidding on item in next iteration. - possibleBids.erase(iter); + std::set::iterator it = auctionsGuidsToConsider.begin(); + std::advance(it, 0); + uint32 auctionID = *it; + AuctionEntry* auction = auctionHouseObject->GetAuction(auctionID); + + // + // Prevent to bid again on the same auction + // + auctionsGuidsToConsider.erase(it); if (!auction) + { + if (config->DebugOutBuyer) + { + LOG_ERROR("module", "AHBot [{}]: Auction id: {} Possible entry to buy/bid from AH pool is invalid, this should not happen, moving on next auciton", _id, auctionID); + } + continue; + } + + // + // Prevent from buying items from the other bots + // + + if (gBotsId.find(auction->owner.GetCounter()) != gBotsId.end()) + { continue; + } + + // + // Get the item information + // + + Item* pItem = sAuctionMgr->GetAItem(auction->item_guid); - // get exact item information - Item *pItem = sAuctionMgr->GetAItem(auction->item_guidlow); if (!pItem) { - if (debug_Out) sLog->outError( "AHBuyer: Item %u doesn't exist, perhaps bought already?", auction->item_guidlow); + if (config->DebugOutBuyer) + { + LOG_ERROR("module", "AHBot [{}]: item {} doesn't exist, perhaps bought already?", _id, auction->item_guid.ToString()); + } + continue; } - // get item prototype + // + // Get the item prototype + // + ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(auction->item_template); - // check which price we have to use, startbid or if it is bidded already - uint32 currentprice; - if (auction->bid) - currentprice = auction->bid; - else - currentprice = auction->startbid; - // Prepare portion from maximum bid - double bidrate = static_cast(urand(1, 100)) / 100; - long double bidMax = 0; + // + // Determine current price. + // + + uint32 currentPrice = static_cast(auction->bid ? auction->bid : auction->startbid); + + // + // Determine maximum bid and skip auctions with too high a currentPrice. + // - // check that bid has acceptable value and take bid based on vendorprice, stacksize and quality - switch (BuyMethod) + uint32 basePrice = static_cast(config->UseBuyPriceForBuyer ? prototype->BuyPrice : prototype->SellPrice); + uint32 maximumBid = static_cast(basePrice * pItem->GetCount() * config->GetBuyerPrice(prototype->Quality)); + + if (config->TraceBuyer) { - case 0: - { - if (prototype->Quality <= AHB_MAX_QUALITY) - { - if (currentprice < prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(prototype->Quality)) - bidMax = prototype->SellPrice * pItem->GetCount() * config->GetBuyerPrice(prototype->Quality); - } - else - { - // quality is something it shouldn't be, let's get out of here - if (debug_Out) sLog->outError( "AHBuyer: Quality %u not Supported", prototype->Quality); - continue; - } - break; - } - case 1: + LOG_INFO("module", "-------------------------------------------------"); + LOG_INFO("module", "AHBot [{}]: Info for Auction #{}:", _id, auction->Id); + LOG_INFO("module", "AHBot [{}]: AuctionHouse: {}", _id, auction->GetHouseId()); + LOG_INFO("module", "AHBot [{}]: Owner: {}", _id, auction->owner.ToString()); + LOG_INFO("module", "AHBot [{}]: Bidder: {}", _id, auction->bidder.ToString()); + LOG_INFO("module", "AHBot [{}]: Starting Bid: {}", _id, auction->startbid); + LOG_INFO("module", "AHBot [{}]: Current Bid: {}", _id, currentPrice); + LOG_INFO("module", "AHBot [{}]: Buyout: {}", _id, auction->buyout); + LOG_INFO("module", "AHBot [{}]: Deposit: {}", _id, auction->deposit); + LOG_INFO("module", "AHBot [{}]: Expire Time: {}", _id, uint32(auction->expire_time)); + LOG_INFO("module", "AHBot [{}]: Bid Max: {}", _id, maximumBid); + LOG_INFO("module", "AHBot [{}]: Item GUID: {}", _id, auction->item_guid.ToString()); + LOG_INFO("module", "AHBot [{}]: Item Template: {}", _id, auction->item_template); + LOG_INFO("module", "AHBot [{}]: Item ID: {}", _id, prototype->ItemId); + LOG_INFO("module", "AHBot [{}]: Buy Price: {}", _id, prototype->BuyPrice); + LOG_INFO("module", "AHBot [{}]: Sell Price: {}", _id, prototype->SellPrice); + LOG_INFO("module", "AHBot [{}]: Bonding: {}", _id, prototype->Bonding); + LOG_INFO("module", "AHBot [{}]: Quality: {}", _id, prototype->Quality); + LOG_INFO("module", "AHBot [{}]: Item Level: {}", _id, prototype->ItemLevel); + LOG_INFO("module", "AHBot [{}]: Ammo Type: {}", _id, prototype->AmmoType); + LOG_INFO("module", "-------------------------------------------------"); + } + + if (currentPrice > maximumBid) + { + if (config->TraceBuyer) { - if (prototype->Quality <= AHB_MAX_QUALITY) - { - if (currentprice < prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(prototype->Quality)) - bidMax = prototype->BuyPrice * pItem->GetCount() * config->GetBuyerPrice(prototype->Quality); - } - else - { - // quality is something it shouldn't be, let's get out of here - if (debug_Out) sLog->outError( "AHBuyer: Quality %u not Supported", prototype->Quality); - continue; - } - break; + LOG_INFO("module", "AHBot [{}]: Current price too high, skipped.", _id); } + continue; } - // check some special items, and do recalculating to their prices + + // + // Recalculate the bid depending on the type of the item + // + switch (prototype->Class) { - // ammo - case 6: - bidMax = 0; + case ITEM_CLASS_PROJECTILE: + maximumBid = 0; + break; + case ITEM_CLASS_GENERIC: + maximumBid = 0; + break; + case ITEM_CLASS_MONEY: + maximumBid = 0; + break; + case ITEM_CLASS_PERMANENT: + maximumBid = 0; break; default: break; } - if (bidMax == 0) + // + // Make sure to skip the auction if maximum bid is 0. + // + + if (maximumBid == 0) { - // quality check failed to get bidmax, let's get out of here + if (config->TraceBuyer) + { + LOG_INFO("module", "AHBot [{}]: Maximum bid value for item class {} is 0, skipped.", _id, prototype->Class); + } continue; } + // // Calculate our bid - long double bidvalue = currentprice + ((bidMax - currentprice) * bidrate); - // Convert to uint32 - uint32 bidprice = static_cast(bidvalue); + // + double bidRate = static_cast(urand(1, 100)) / 100; + double bidValue = currentPrice + ((maximumBid - currentPrice) * bidRate); + uint32 bidPrice = static_cast(bidValue); + + + // // Check our bid is high enough to be valid. If not, correct it to minimum. - if ((currentprice + auction->GetAuctionOutBid()) > bidprice) - bidprice = currentprice + auction->GetAuctionOutBid(); + // + uint32 minimumOutbid = auction->GetAuctionOutBid(); + if ((currentPrice + minimumOutbid) > bidPrice) + { + bidPrice = static_cast(currentPrice + minimumOutbid); + } - if (debug_Out) + if (bidPrice > maximumBid) { - sLog->outString("-------------------------------------------------"); - sLog->outString("AHBuyer: Info for Auction #%u:", auction->Id); - sLog->outString("AHBuyer: AuctionHouse: %u", auction->GetHouseId()); - sLog->outString("AHBuyer: Auctioneer: %u", auction->auctioneer); - sLog->outString("AHBuyer: Owner: %u", auction->owner); - sLog->outString("AHBuyer: Bidder: %u", auction->bidder); - sLog->outString("AHBuyer: Starting Bid: %u", auction->startbid); - sLog->outString("AHBuyer: Current Bid: %u", currentprice); - sLog->outString("AHBuyer: Buyout: %u", auction->buyout); - sLog->outString("AHBuyer: Deposit: %u", auction->deposit); - sLog->outString("AHBuyer: Expire Time: %u", uint32(auction->expire_time)); - sLog->outString("AHBuyer: Bid Rate: %f", bidrate); - sLog->outString("AHBuyer: Bid Max: %Lf", bidMax); - sLog->outString("AHBuyer: Bid Value: %Lf", bidvalue); - sLog->outString("AHBuyer: Bid Price: %u", bidprice); - sLog->outString("AHBuyer: Item GUID: %u", auction->item_guidlow); - sLog->outString("AHBuyer: Item Template: %u", auction->item_template); - sLog->outString("AHBuyer: Item Info:"); - sLog->outString("AHBuyer: Item ID: %u", prototype->ItemId); - sLog->outString("AHBuyer: Buy Price: %u", prototype->BuyPrice); - sLog->outString("AHBuyer: Sell Price: %u", prototype->SellPrice); - sLog->outString("AHBuyer: Bonding: %u", prototype->Bonding); - sLog->outString("AHBuyer: Quality: %u", prototype->Quality); - sLog->outString("AHBuyer: Item Level: %u", prototype->ItemLevel); - sLog->outString("AHBuyer: Ammo Type: %u", prototype->AmmoType); - sLog->outString("-------------------------------------------------"); + if (config->TraceBuyer) + { + LOG_INFO("module", "AHBot [{}]: Bid was above bidMax for item={} AH={}", _id, auction->item_guid.ToString(), config->GetAHID()); + } + bidPrice = static_cast(maximumBid); } - // Check whether we do normal bid, or buyout - if ((bidprice < auction->buyout) || (auction->buyout == 0)) + if (config->DebugOutBuyer) { + LOG_INFO("module", "-------------------------------------------------"); + LOG_INFO("module", "AHBot [{}]: Bid Rate: {}", _id, bidRate); + LOG_INFO("module", "AHBot [{}]: Bid Value: {}", _id, bidValue); + LOG_INFO("module", "AHBot [{}]: Bid Price: {}", _id, bidPrice); + LOG_INFO("module", "AHBot [{}]: Minimum Outbid: {}", _id, minimumOutbid); + LOG_INFO("module", "-------------------------------------------------"); + } + - if (auction->bidder > 0) + // + // Check whether we do normal bid, or buyout + // + + if ((bidPrice < auction->buyout) || (auction->buyout == 0)) + { + // + // Return money to last bidder. + // + + if (auction->bidder) { - if (auction->bidder == AHBplayer->GetGUIDLow()) - { - //pl->ModifyMoney(-int32(price - auction->bid)); - } - else + if (auction->bidder != AHBplayer->GetGUID()) { - // mail to last bidder and return money - SQLTransaction trans = CharacterDatabase.BeginTransaction(); - sAuctionMgr->SendAuctionOutbiddedMail(auction , bidprice, session->GetPlayer(), trans); + // + // Mail to last bidder and return their money + // + + auto trans = CharacterDatabase.BeginTransaction(); + sAuctionMgr->SendAuctionOutbiddedMail(auction, bidPrice, session->GetPlayer(), trans); CharacterDatabase.CommitTransaction(trans); - //pl->ModifyMoney(-int32(price)); } - } - - auction->bidder = AHBplayer->GetGUIDLow(); - auction->bid = bidprice; - - // Saving auction into database - CharacterDatabase.PExecute("UPDATE auctionhouse SET buyguid = '%u',lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id); + } + + auction->bidder = AHBplayer->GetGUID(); + auction->bid = bidPrice; + + sAuctionMgr->GetAuctionHouseSearcher()->UpdateBid(auction); + + // + // update/save the auction into database + // + CharacterDatabase.Execute("UPDATE auctionhouse SET buyguid = '{}', lastbid = '{}' WHERE id = '{}'", auction->bidder.GetCounter(), auction->bid, auction->Id); + + if (config->TraceBuyer) + { + LOG_INFO("module", "AHBot [{}]: New bid, itemid={}, ah={}, auctionId={} item={}, start={}, current={}, buyout={}", _id, prototype->ItemId, auction->GetHouseId(), auction->Id, auction->item_template, auction->startbid, currentPrice, auction->buyout); + } } else { - SQLTransaction trans = CharacterDatabase.BeginTransaction(); - //buyout - if ((auction->bidder) && (AHBplayer->GetGUIDLow() != auction->bidder)) + // + // Perform the buyout + // + + auto trans = CharacterDatabase.BeginTransaction(); + + if ((auction->bidder) && (AHBplayer->GetGUID() != auction->bidder)) { + // + // Mail to last bidder and return their money + // + sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, session->GetPlayer(), trans); } - auction->bidder = AHBplayer->GetGUIDLow(); + + auction->bidder = AHBplayer->GetGUID(); auction->bid = auction->buyout; + // // Send mails to buyer & seller - //sAuctionMgr->SendAuctionSalePendingMail(auction, trans); + // + sAuctionMgr->SendAuctionSuccessfulMail(auction, trans); sAuctionMgr->SendAuctionWonMail(auction, trans); - auction->DeleteFromDB( trans); - sAuctionMgr->RemoveAItem(auction->item_guidlow); - auctionHouse->RemoveAuction(auction); + // + // Removes any trace of the item + // + + ScriptMgr::instance()->OnAuctionSuccessful(auctionHouseObject, auction); + auction->DeleteFromDB(trans); + sAuctionMgr->RemoveAItem(auction->item_guid); + auctionHouseObject->RemoveAuction(auction); + + CharacterDatabase.CommitTransaction(trans); + + if (config->TraceBuyer) + { + LOG_INFO("module", "AHBot [{}]: Bought , itemid={}, ah={}, item={}, start={}, current={}, buyout={}", _id, prototype->ItemId, AuctionHouseId(auction->GetHouseId()), auction->item_template, auction->startbid, currentPrice, auction->buyout); + } } } } -void AuctionHouseBot::Update() +// ============================================================================= +// This routine performs the selling operations for the bot +// ============================================================================= + +void AuctionHouseBot::Sell(Player* AHBplayer, AHBConfig* config) { - time_t _newrun = time(NULL); - if ((!AHBSeller) && (!AHBBuyer)) - return; + // + // Check if disabled + // - WorldSession _session(AHBplayerAccount, NULL, SEC_PLAYER, sWorld->getIntConfig(CONFIG_EXPANSION), 0, LOCALE_zhCN,0,false,false); - Player _AHBplayer(&_session); - _AHBplayer.Initialize(AHBplayerGUID); - sObjectAccessor->AddObject(&_AHBplayer); - - // Add New Bids - if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) + if (!config->AHBSeller) { - addNewAuctions(&_AHBplayer, &AllianceConfig); - if (((_newrun - _lastrun_a) >= (AllianceConfig.GetBiddingInterval() * MINUTE)) && (AllianceConfig.GetBidsPerInterval() > 0)) - { - //if (debug_Out) sLog->outError( "AHBuyer: %u seconds have passed since last bid", (_newrun - _lastrun_a)); - //if (debug_Out) sLog->outError( "AHBuyer: Bidding on Alliance Auctions"); - addNewAuctionBuyerBotBid(&_AHBplayer, &AllianceConfig, &_session); - _lastrun_a = _newrun; - } - - addNewAuctions(&_AHBplayer, &HordeConfig); - if (((_newrun - _lastrun_h) >= (HordeConfig.GetBiddingInterval() * MINUTE)) && (HordeConfig.GetBidsPerInterval() > 0)) - { - //if (debug_Out) sLog->outError( "AHBuyer: %u seconds have passed since last bid", (_newrun - _lastrun_h)); - //if (debug_Out) sLog->outError( "AHBuyer: Bidding on Horde Auctions"); - addNewAuctionBuyerBotBid(&_AHBplayer, &HordeConfig, &_session); - _lastrun_h = _newrun; - } + return; } - addNewAuctions(&_AHBplayer, &NeutralConfig); - if (((_newrun - _lastrun_n) >= (NeutralConfig.GetBiddingInterval() * MINUTE)) && (NeutralConfig.GetBidsPerInterval() > 0)) - { - //if (debug_Out) sLog->outError( "AHBuyer: %u seconds have passed since last bid", (_newrun - _lastrun_n)); - //if (debug_Out) sLog->outError( "AHBuyer: Bidding on Neutral Auctions"); - addNewAuctionBuyerBotBid(&_AHBplayer, &NeutralConfig, &_session); - _lastrun_n = _newrun; - } - sObjectAccessor->RemoveObject(&_AHBplayer); -} + // + // Check the given limits + // -void AuctionHouseBot::Initialize() -{ - std::string disabledItems = sConfigMgr->GetStringDefault("AuctionHouseBot.DisabledItems", ""); - DisableItemStore.clear(); - Tokenizer tokens(disabledItems, ' '); - for (Tokenizer::const_iterator iter = tokens.begin(); iter != tokens.end(); ++iter) + uint32 minTotalItems = config->GetMinItems(); + uint32 maxTotalItems = config->GetMaxItems(); + + if (maxTotalItems == 0) { - uint32 id = uint32(atol(*iter)); - DisableItemStore.insert(id); + return; } - //End Filters - if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) + // + // Retrieve the auction house situation + // + + AuctionHouseEntry const* ahEntry = sAuctionMgr->GetAuctionHouseEntryFromFactionTemplate(config->GetAHFID()); + + if (!ahEntry) { - LoadValues(&AllianceConfig); - LoadValues(&HordeConfig); + return; } - LoadValues(&NeutralConfig); - // - // check if the AHBot account/GUID in the config actually exists - // + AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(config->GetAHFID()); - if ((AHBplayerAccount != 0) || (AHBplayerGUID != 0)) + if (!auctionHouse) { - QueryResult result = CharacterDatabase.PQuery("SELECT 1 FROM characters WHERE account = %u AND guid = %u", AHBplayerAccount, AHBplayerGUID); - if (!result) - { - sLog->outError( "AuctionHouseBot: The account/GUID-information set for your AHBot is incorrect (account: %u guid: %u)", AHBplayerAccount, AHBplayerGUID); - return; - } + return; } - if (AHBSeller) + // don't mess with the AH update let server do it. + //auctionHouseObject->Update(); + + // + // Check if we are clear to proceed + // + + bool aboveMin = false; + bool aboveMax = false; + uint32 nbOfAuctions = getNofAuctions(config, auctionHouse, AHBplayer->GetGUID()); + uint32 nbItemsToSellThisCycle = 0; + + if (nbOfAuctions >= minTotalItems) { - QueryResult results = QueryResult(NULL); - char npcQuery[] = "SELECT distinct item FROM npc_vendor"; - results = WorldDatabase.Query(npcQuery); - if (results) - { - do - { - Field* fields = results->Fetch(); - npcItems.push_back(fields[0].GetUInt32()); + aboveMin = true; - } while (results->NextRow()); - } - else + if (config->DebugOutSeller) { - if (debug_Out) sLog->outError( "AuctionHouseBot: \"%s\" failed", npcQuery); + LOG_TRACE("module", "AHBot [{}]: Auctions above minimum", _id); } + } - char lootQuery[] = "SELECT item FROM creature_loot_template UNION " - "SELECT item FROM reference_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"; - - results = WorldDatabase.Query(lootQuery); - if (results) - { - do - { - Field* fields = results->Fetch(); - lootItems.push_back(fields[0].GetUInt32()); + if (nbOfAuctions >= maxTotalItems) + { + aboveMax = true; - } while (results->NextRow()); - } - else + if (config->DebugOutSeller) { - if (debug_Out) sLog->outError( "AuctionHouseBot: \"%s\" failed", lootQuery); + LOG_TRACE("module", "AHBot [{}]: Auctions at or above maximum", _id); } - ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore(); - for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr) - { + return; + } + if ((maxTotalItems - nbOfAuctions) >= config->ItemsPerCycle) + { + nbItemsToSellThisCycle = config->ItemsPerCycle; + } + else + { + nbItemsToSellThisCycle = (maxTotalItems - nbOfAuctions); + } + // + // Retrieve the configuration for this run + // + + uint32 maxGreyTG = config->GetMaximum(AHB_GREY_TG); + uint32 maxWhiteTG = config->GetMaximum(AHB_WHITE_TG); + uint32 maxGreenTG = config->GetMaximum(AHB_GREEN_TG); + uint32 maxBlueTG = config->GetMaximum(AHB_BLUE_TG); + uint32 maxPurpleTG = config->GetMaximum(AHB_PURPLE_TG); + uint32 maxOrangeTG = config->GetMaximum(AHB_ORANGE_TG); + uint32 maxYellowTG = config->GetMaximum(AHB_YELLOW_TG); + + uint32 maxGreyI = config->GetMaximum(AHB_GREY_I); + uint32 maxWhiteI = config->GetMaximum(AHB_WHITE_I); + uint32 maxGreenI = config->GetMaximum(AHB_GREEN_I); + uint32 maxBlueI = config->GetMaximum(AHB_BLUE_I); + uint32 maxPurpleI = config->GetMaximum(AHB_PURPLE_I); + uint32 maxOrangeI = config->GetMaximum(AHB_ORANGE_I); + uint32 maxYellowI = config->GetMaximum(AHB_YELLOW_I); + + uint32 currentGreyTG = config->GetItemCounts(AHB_GREY_TG); + uint32 currentWhiteTG = config->GetItemCounts(AHB_WHITE_TG); + uint32 currentGreenTG = config->GetItemCounts(AHB_GREEN_TG); + uint32 currentBlueTG = config->GetItemCounts(AHB_BLUE_TG); + uint32 currentPurpleTG = config->GetItemCounts(AHB_PURPLE_TG); + uint32 currentOrangeTG = config->GetItemCounts(AHB_ORANGE_TG); + uint32 currentYellowTG = config->GetItemCounts(AHB_YELLOW_TG); + + uint32 currentGreyItems = config->GetItemCounts(AHB_GREY_I); + uint32 currentWhiteItems = config->GetItemCounts(AHB_WHITE_I); + uint32 currentGreenItems = config->GetItemCounts(AHB_GREEN_I); + uint32 currentBlueItems = config->GetItemCounts(AHB_BLUE_I); + uint32 currentPurpleItems = config->GetItemCounts(AHB_PURPLE_I); + uint32 currentOrangeItems = config->GetItemCounts(AHB_ORANGE_I); + uint32 currentYellowItems = config->GetItemCounts(AHB_YELLOW_I); - switch (itr->second.Bonding) - { - case NO_BIND: - if (!No_Bind) - continue; - break; - case BIND_WHEN_PICKED_UP: - if (!Bind_When_Picked_Up) - continue; - break; - case BIND_WHEN_EQUIPED: - if (!Bind_When_Equipped) - continue; - break; - case BIND_WHEN_USE: - if (!Bind_When_Use) - continue; - break; - case BIND_QUEST_ITEM: - if (!Bind_Quest_Item) - continue; - break; - default: - continue; - break; - } + // + // Loop variables + // - switch (SellMethod) - { - case 0: - if (itr->second.SellPrice == 0) - continue; - break; - case 1: - if (itr->second.BuyPrice == 0) - continue; - break; - } + uint32 nbSold = 0; // Tracing counter + uint32 binEmpty = 0; // Tracing counter + uint32 noNeed = 0; // Tracing counter + uint32 tooMany = 0; // Tracing counter + uint32 loopBrk = 0; // Tracing counter + uint32 err = 0; // Tracing counter - if (itr->second.Quality > 6) - continue; + for (uint32 cnt = 1; cnt <= nbItemsToSellThisCycle; cnt++) + { + uint32 itemTypeSelectedToSell = 0; + uint32 itemID = 0; + uint32 loopbreaker = 0; - if ((Vendor_Items == 0) && !(itr->second.Class == ITEM_CLASS_TRADE_GOODS)) - { - bool isVendorItem = false; + // + // Select, in rarity order, a new random item + // - for (unsigned int i = 0; (i < npcItems.size()) && (!isVendorItem); i++) - { - if (itr->second.ItemId == npcItems[i]) - isVendorItem = true; - } + while (itemID == 0 && loopbreaker <= AUCTION_HOUSE_BOT_LOOP_BREAKER) + { + loopbreaker++; - if (isVendorItem) - continue; - } + // Poor - if ((Vendor_TGs == 0) && (itr->second.Class == ITEM_CLASS_TRADE_GOODS)) + if ((config->GreyItemsBin.size() > 0) && (currentGreyItems < maxGreyI)) { - bool isVendorTG = false; - - for (unsigned int i = 0; (i < npcItems.size()) && (!isVendorTG); i++) - { - if (itr->second.ItemId == npcItems[i]) - isVendorTG = true; - } - - if (isVendorTG) - continue; + itemTypeSelectedToSell = AHB_GREY_I; + itemID = getElement(config->GreyItemsBin, urand(0, config->GreyItemsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); } - if ((Loot_Items == 0) && !(itr->second.Class == ITEM_CLASS_TRADE_GOODS)) + if (itemID == 0 && (config->GreyTradeGoodsBin.size() > 0) && (currentGreyTG < maxGreyTG)) { - bool isLootItem = false; - - for (unsigned int i = 0; (i < lootItems.size()) && (!isLootItem); i++) - { - if (itr->second.ItemId == lootItems[i]) - isLootItem = true; - } - - if (isLootItem) - continue; + itemTypeSelectedToSell = AHB_GREY_TG; + itemID = getElement(config->GreyTradeGoodsBin, urand(0, config->GreyTradeGoodsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); } - if ((Loot_TGs == 0) && (itr->second.Class == ITEM_CLASS_TRADE_GOODS)) - { - bool isLootTG = false; - - for (unsigned int i = 0; (i < lootItems.size()) && (!isLootTG); i++) - { - if (itr->second.ItemId == lootItems[i]) - isLootTG = true; - } + // Normal - if (isLootTG) - continue; - } - - if ((Other_Items == 0) && !(itr->second.Class == ITEM_CLASS_TRADE_GOODS)) + if (itemID == 0 && (config->WhiteItemsBin.size() > 0) && (currentWhiteItems < maxWhiteI)) { - bool isVendorItem = false; - bool isLootItem = false; - - for (unsigned int i = 0; (i < npcItems.size()) && (!isVendorItem); i++) - { - if (itr->second.ItemId == npcItems[i]) - isVendorItem = true; - } - for (unsigned int i = 0; (i < lootItems.size()) && (!isLootItem); i++) - { - if (itr->second.ItemId == lootItems[i]) - isLootItem = true; - } - if ((!isLootItem) && (!isVendorItem)) - continue; + itemTypeSelectedToSell = AHB_WHITE_I; + itemID = getElement(config->WhiteItemsBin, urand(0, config->WhiteItemsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); } - if ((Other_TGs == 0) && (itr->second.Class == ITEM_CLASS_TRADE_GOODS)) + if (itemID == 0 && (config->WhiteTradeGoodsBin.size() > 0) && (currentWhiteTG < maxWhiteTG)) { - bool isVendorTG = false; - bool isLootTG = false; - - for (unsigned int i = 0; (i < npcItems.size()) && (!isVendorTG); i++) - { - if (itr->second.ItemId == npcItems[i]) - isVendorTG = true; - } - for (unsigned int i = 0; (i < lootItems.size()) && (!isLootTG); i++) - { - if (itr->second.ItemId == lootItems[i]) - isLootTG = true; - } - if ((!isLootTG) && (!isVendorTG)) - continue; + itemTypeSelectedToSell = AHB_WHITE_TG; + itemID = getElement(config->WhiteTradeGoodsBin, urand(0, config->WhiteTradeGoodsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); } - // Disable items by Id - if (DisableItemStore.find(itr->second.ItemId) != DisableItemStore.end()) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (PTR/Beta/Unused Item)", itr->second.ItemId); - continue; - } + // Uncommon - // Disable permanent enchants items - if ((DisablePermEnchant) && (itr->second.Class == ITEM_CLASS_PERMANENT)) + if (itemID == 0 && (config->GreenItemsBin.size() > 0) && (currentGreenItems < maxGreenI)) { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Permanent Enchant Item)", itr->second.ItemId); - continue; + itemTypeSelectedToSell = AHB_GREEN_I; + itemID = getElement(config->GreenItemsBin, urand(0, config->GreenItemsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); } - // Disable conjured items - if ((DisableConjured) && (itr->second.IsConjuredConsumable())) + if (itemID == 0 && (config->GreenTradeGoodsBin.size() > 0) && (currentGreenTG < maxGreenTG)) { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Conjured Consumable)", itr->second.ItemId); - continue; + itemTypeSelectedToSell = AHB_GREEN_TG; + itemID = getElement(config->GreenTradeGoodsBin, urand(0, config->GreenTradeGoodsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); } - // Disable gems - if ((DisableGems) && (itr->second.Class == ITEM_CLASS_GEM)) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Gem)", itr->second.ItemId); - continue; - } + // Rare - // Disable money - if ((DisableMoney) && (itr->second.Class == ITEM_CLASS_MONEY)) + if (itemID == 0 && (config->BlueItemsBin.size() > 0) && (currentBlueItems < maxBlueI)) { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Money)", itr->second.ItemId); - continue; + itemTypeSelectedToSell = AHB_BLUE_I; + itemID = getElement(config->BlueItemsBin, urand(0, config->BlueItemsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); } - // Disable moneyloot - if ((DisableMoneyLoot) && (itr->second.MinMoneyLoot > 0)) + if (itemID == 0 && (config->BlueTradeGoodsBin.size() > 0) && (currentBlueTG < maxBlueTG)) { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (MoneyLoot)", itr->second.ItemId); - continue; + itemTypeSelectedToSell = AHB_BLUE_TG; + itemID = getElement(config->BlueTradeGoodsBin, urand(0, config->BlueTradeGoodsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); } - // Disable lootable items - if ((DisableLootable) && (itr->second.Flags & 4)) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Lootable Item)", itr->second.ItemId); - continue; - } + // Epic - // Disable Keys - if ((DisableKeys) && (itr->second.Class == ITEM_CLASS_KEY)) + if (itemID == 0 && (config->PurpleItemsBin.size() > 0) && (currentPurpleItems < maxPurpleI)) { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Quest Item)", itr->second.ItemId); - continue; + itemTypeSelectedToSell = AHB_PURPLE_I; + itemID = getElement(config->PurpleItemsBin, urand(0, config->PurpleItemsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); } - // Disable items with duration - if ((DisableDuration) && (itr->second.Duration > 0)) + if (itemID == 0 && (config->PurpleTradeGoodsBin.size() > 0) && (currentPurpleTG < maxPurpleTG)) { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Has a Duration)", itr->second.ItemId); - continue; + itemTypeSelectedToSell = AHB_PURPLE_TG; + itemID = getElement(config->PurpleTradeGoodsBin, urand(0, config->PurpleTradeGoodsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); } - // Disable items which are BOP or Quest Items and have a required level lower than the item level - if ((DisableBOP_Or_Quest_NoReqLevel) && ((itr->second.Bonding == BIND_WHEN_PICKED_UP || itr->second.Bonding == BIND_QUEST_ITEM) && (itr->second.RequiredLevel < itr->second.ItemLevel))) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (BOP or BQI and Required Level is less than Item Level)", itr->second.ItemId); - continue; - } + // Legendary - // Disable items specifically for Warrior - if ((DisableWarriorItems) && (itr->second.AllowableClass == 1)) + if (itemID == 0 && (config->OrangeItemsBin.size() > 0) && (currentOrangeItems < maxOrangeI)) { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Warrior Item)", itr->second.ItemId); - continue; + itemTypeSelectedToSell = AHB_ORANGE_I; + itemID = getElement(config->OrangeItemsBin, urand(0, config->OrangeItemsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); } - // Disable items specifically for Paladin - if ((DisablePaladinItems) && (itr->second.AllowableClass == 2)) + if (itemID == 0 && (config->OrangeTradeGoodsBin.size() > 0) && (currentOrangeTG < maxOrangeTG)) { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Paladin Item)", itr->second.ItemId); - continue; + itemTypeSelectedToSell = AHB_ORANGE_TG; + itemID = getElement(config->OrangeTradeGoodsBin, urand(0, config->OrangeTradeGoodsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); } - // Disable items specifically for Hunter - if ((DisableHunterItems) && (itr->second.AllowableClass == 4)) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Hunter Item)", itr->second.ItemId); - continue; - } + // Artifact - // Disable items specifically for Rogue - if ((DisableRogueItems) && (itr->second.AllowableClass == 8)) + if (itemID == 0 && (config->YellowItemsBin.size() > 0) && (currentYellowItems < maxYellowI)) { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Rogue Item)", itr->second.ItemId); - continue; + itemTypeSelectedToSell = AHB_YELLOW_I; + itemID = getElement(config->YellowItemsBin, urand(0, config->YellowItemsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); } - // Disable items specifically for Priest - if ((DisablePriestItems) && (itr->second.AllowableClass == 16)) + if (itemID == 0 && (config->YellowTradeGoodsBin.size() > 0) && (currentYellowTG < maxYellowTG)) { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Priest Item)", itr->second.ItemId); - continue; + itemTypeSelectedToSell = AHB_YELLOW_TG; + itemID = getElement(config->YellowTradeGoodsBin, urand(0, config->YellowTradeGoodsBin.size() - 1), _id, config->DuplicatesCount, auctionHouse); } - // Disable items specifically for DK - if ((DisableDKItems) && (itr->second.AllowableClass == 32)) + if (itemID == 0) { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (DK Item)", itr->second.ItemId); - continue; + binEmpty++; + + if (config->DebugOutSeller) + { + LOG_ERROR("module", "AHBot [{}]: No item could be selected from the bins", _id); + } + + break; } + } - // Disable items specifically for Shaman - if ((DisableShamanItems) && (itr->second.AllowableClass == 64)) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Shaman Item)", itr->second.ItemId); - continue; - } + if (itemID == 0 || loopbreaker > AUCTION_HOUSE_BOT_LOOP_BREAKER) + { + loopBrk++; + continue; + } - // Disable items specifically for Mage - if ((DisableMageItems) && (itr->second.AllowableClass == 128)) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Mage Item)", itr->second.ItemId); - continue; - } + // + // Retrieve information about the selected item + // - // Disable items specifically for Warlock - if ((DisableWarlockItems) && (itr->second.AllowableClass == 256)) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Warlock Item)", itr->second.ItemId); - continue; - } + ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(itemID); - // Disable items specifically for Unused Class - if ((DisableUnusedClassItems) && (itr->second.AllowableClass == 512)) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Unused Item)", itr->second.ItemId); - continue; - } + if (prototype == NULL) + { + err++; - // Disable items specifically for Druid - if ((DisableDruidItems) && (itr->second.AllowableClass == 1024)) + if (config->DebugOutSeller) { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Druid Item)", itr->second.ItemId); - continue; + LOG_ERROR("module", "AHBot [{}]: could not get prototype of item {}", _id, itemID); } - // Disable Items below level X - if ((DisableItemsBelowLevel) && (itr->second.Class != ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemLevel < DisableItemsBelowLevel)) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Item Level = %u)", itr->second.ItemId, itr->second.ItemLevel); - continue; - } + continue; + } - // Disable Items above level X - if ((DisableItemsAboveLevel) && (itr->second.Class != ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemLevel > DisableItemsAboveLevel)) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Item Level = %u)", itr->second.ItemId, itr->second.ItemLevel); - continue; - } + Item* item = Item::CreateItem(itemID, 1, AHBplayer); - // Disable Trade Goods below level X - if ((DisableTGsBelowLevel) && (itr->second.Class == ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemLevel < DisableTGsBelowLevel)) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Trade Good %u disabled (Trade Good Level = %u)", itr->second.ItemId, itr->second.ItemLevel); - continue; - } + if (item == NULL) + { + err++; - // Disable Trade Goods above level X - if ((DisableTGsAboveLevel) && (itr->second.Class == ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemLevel > DisableTGsAboveLevel)) + if (config->DebugOutSeller) { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Trade Good %u disabled (Trade Good Level = %u)", itr->second.ItemId, itr->second.ItemLevel); - continue; + LOG_ERROR("module", "AHBot [{}]: could not create item from prototype {}", _id, itemID); } - // Disable Items below GUID X - if ((DisableItemsBelowGUID) && (itr->second.Class != ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemId < DisableItemsBelowGUID)) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Item Level = %u)", itr->second.ItemId, itr->second.ItemLevel); - continue; - } + continue; + } - // Disable Items above GUID X - if ((DisableItemsAboveGUID) && (itr->second.Class != ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemId > DisableItemsAboveGUID)) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Item Level = %u)", itr->second.ItemId, itr->second.ItemLevel); - continue; - } + // + // Start interacting with the item by adding a random property + // - // Disable Trade Goods below GUID X - if ((DisableTGsBelowGUID) && (itr->second.Class == ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemId < DisableTGsBelowGUID)) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Trade Good Level = %u)", itr->second.ItemId, itr->second.ItemLevel); - continue; - } + item->AddToUpdateQueueOf(AHBplayer); - // Disable Trade Goods above GUID X - if ((DisableTGsAboveGUID) && (itr->second.Class == ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemId > DisableTGsAboveGUID)) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (Trade Good Level = %u)", itr->second.ItemId, itr->second.ItemLevel); - continue; - } + uint32 randomPropertyId = Item::GenerateItemRandomPropertyId(itemID); - // Disable Items for level lower than X - if ((DisableItemsBelowReqLevel) && (itr->second.RequiredLevel < DisableItemsBelowReqLevel)) - { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (RequiredLevel = %u)", itr->second.ItemId, itr->second.RequiredLevel); - continue; - } + if (randomPropertyId != 0) + { + item->SetItemRandomProperties(randomPropertyId); + } + + if (prototype->Quality > AHB_MAX_QUALITY) + { + err++; - // Disable Items for level higher than X - if ((DisableItemsAboveReqLevel) && (itr->second.RequiredLevel > DisableItemsAboveReqLevel)) + if (config->DebugOutSeller) { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (RequiredLevel = %u)", itr->second.ItemId, itr->second.RequiredLevel); - continue; + LOG_ERROR("module", "AHBot [{}]: Quality {} TOO HIGH for item {}", _id, prototype->Quality, itemID); } - // Disable Trade Goods for level lower than X - if ((DisableTGsBelowReqLevel) && (itr->second.RequiredLevel < DisableTGsBelowReqLevel)) + item->RemoveFromUpdateQueueOf(AHBplayer); + continue; + } + + // + // Determine the price + // + + uint64 buyoutPrice = 0; + uint64 bidPrice = 0; + uint32 stackCount = 1; + + if (config->SellAtMarketPrice) + { + buyoutPrice = config->GetItemPrice(itemID); + } + + if (buyoutPrice == 0) + { + if (config->UseBuyPriceForSeller) { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Trade Good %u disabled (RequiredLevel = %u)", itr->second.ItemId, itr->second.RequiredLevel); - continue; + buyoutPrice = prototype->BuyPrice; } - - // Disable Trade Goods for level higher than X - if ((DisableTGsAboveReqLevel) && (itr->second.RequiredLevel > DisableTGsAboveReqLevel)) + else { - if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Trade Good %u disabled (RequiredLevel = %u)", itr->second.ItemId, itr->second.RequiredLevel); - continue; + buyoutPrice = prototype->SellPrice; } + } - // Disable Items that require skill lower than X - // if ((DisableItemsBelowReqSkillRank) && (itr->second.RequiredSkillRank < DisableItemsBelowReqSkillRank)) - // { - // if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (RequiredSkillRank = %u)", itr->second.ItemId, itr->second.RequiredSkillRank); - // continue; - // } - - // Disable Items that require skill higher than X - // if ((DisableItemsAboveReqSkillRank) && (itr->second.RequiredSkillRank > DisableItemsAboveReqSkillRank)) - // { - // if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (RequiredSkillRank = %u)", itr->second.ItemId, itr->second.RequiredSkillRank); - // continue; - // } - - // Disable Trade Goods that require skill lower than X - // if ((DisableTGsBelowReqSkillRank) && (itr->second.RequiredSkillRank < DisableTGsBelowReqSkillRank)) - // { - // if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (RequiredSkillRank = %u)", itr->second.ItemId, itr->second.RequiredSkillRank); - // continue; - // } - - // Disable Trade Goods that require skill higher than X - // if ((DisableTGsAboveReqSkillRank) && (itr->second.?RequiredSkillRank > DisableTGsAboveReqSkillRank)) - // { - // if (debug_Out_Filters) sLog->outError( "AuctionHouseBot: Item %u disabled (RequiredSkillRank = %u)", itr->second.ItemId, itr->second.RequiredSkillRank); - // continue; - // } - - switch (itr->second.Quality) - { - case AHB_GREY: - if (itr->second.Class == ITEM_CLASS_TRADE_GOODS) - greyTradeGoodsBin.push_back(itr->second.ItemId); - else - greyItemsBin.push_back(itr->second.ItemId); - break; + buyoutPrice = buyoutPrice * urand(config->GetMinPrice(prototype->Quality), config->GetMaxPrice(prototype->Quality)); + buyoutPrice = buyoutPrice / 100; - case AHB_WHITE: - if (itr->second.Class == ITEM_CLASS_TRADE_GOODS) - whiteTradeGoodsBin.push_back(itr->second.ItemId); - else - whiteItemsBin.push_back(itr->second.ItemId); - break; + bidPrice = buyoutPrice * urand(config->GetMinBidPrice(prototype->Quality), config->GetMaxBidPrice(prototype->Quality)); + bidPrice = bidPrice / 100; - case AHB_GREEN: - if (itr->second.Class == ITEM_CLASS_TRADE_GOODS) - greenTradeGoodsBin.push_back(itr->second.ItemId); - else - greenItemsBin.push_back(itr->second.ItemId); - break; + // + // Determine the stack size + // - case AHB_BLUE: - if (itr->second.Class == ITEM_CLASS_TRADE_GOODS) - blueTradeGoodsBin.push_back(itr->second.ItemId); - else - blueItemsBin.push_back(itr->second.ItemId); - break; + if (config->GetMaxStack(prototype->Quality) > 1 && item->GetMaxStackCount() > 1) + { + stackCount = minValue(getStackCount(config, item->GetMaxStackCount()), config->GetMaxStack(prototype->Quality)); + } + else if (config->GetMaxStack(prototype->Quality) == 0 && item->GetMaxStackCount() > 1) + { + stackCount = getStackCount(config, item->GetMaxStackCount()); + } + else + { + stackCount = 1; + } - case AHB_PURPLE: - if (itr->second.Class == ITEM_CLASS_TRADE_GOODS) - purpleTradeGoodsBin.push_back(itr->second.ItemId); - else - purpleItemsBin.push_back(itr->second.ItemId); - break; + item->SetCount(stackCount); - case AHB_ORANGE: - if (itr->second.Class == ITEM_CLASS_TRADE_GOODS) - orangeTradeGoodsBin.push_back(itr->second.ItemId); - else - orangeItemsBin.push_back(itr->second.ItemId); - break; + // + // Determine the auction time + // - case AHB_YELLOW: - if (itr->second.Class == ITEM_CLASS_TRADE_GOODS) - yellowTradeGoodsBin.push_back(itr->second.ItemId); - else - yellowItemsBin.push_back(itr->second.ItemId); - break; - } + uint32 elapsingTime = getElapsedTime(config->ElapsingTimeClass); + + // + // Determine the deposit + // + + uint32 deposit = sAuctionMgr->GetAuctionDeposit(ahEntry, elapsingTime, item, stackCount); + + // + // Perform the auction + // + + auto trans = CharacterDatabase.BeginTransaction(); + + AuctionEntry* auctionEntry = new AuctionEntry(); + auctionEntry->Id = sObjectMgr->GenerateAuctionID(); + auctionEntry->houseId = AuctionHouseId(config->GetAHID()); + auctionEntry->item_guid = item->GetGUID(); + auctionEntry->item_template = item->GetEntry(); + auctionEntry->itemCount = item->GetCount(); + auctionEntry->owner = AHBplayer->GetGUID(); + auctionEntry->startbid = bidPrice * stackCount; + auctionEntry->buyout = buyoutPrice * stackCount; + auctionEntry->bid = 0; + auctionEntry->deposit = deposit; + auctionEntry->expire_time = (time_t)elapsingTime + time(NULL); + auctionEntry->auctionHouseEntry = ahEntry; + + item->SaveToDB(trans); + item->RemoveFromUpdateQueueOf(AHBplayer); + sAuctionMgr->AddAItem(item); + auctionHouse->AddAuction(auctionEntry); + auctionEntry->SaveToDB(trans); + + CharacterDatabase.CommitTransaction(trans); + + // + // Increments the number of items presents in the auction + // + + // todo: reread config for actual values, maybe an array to not rely on local count that could potentially be mismatched from config. + // config is updated from callback received after auctionHouseObject->AddAuction(auctionEntry); + // or maybe reparse the server actual value each update cycle, would need profiling. + switch (itemTypeSelectedToSell) + { + case AHB_GREY_I: + ++currentGreyItems; + break; + + case AHB_WHITE_I: + ++currentWhiteItems; + break; + + case AHB_GREEN_I: + ++currentGreenItems; + break; + + case AHB_BLUE_I: + ++currentBlueItems; + break; + + case AHB_PURPLE_I: + ++currentPurpleItems; + break; + + case AHB_ORANGE_I: + ++currentOrangeItems; + break; + + case AHB_YELLOW_I: + ++currentYellowItems; + break; + + case AHB_GREY_TG: + ++currentGreyTG; + break; + + case AHB_WHITE_TG: + ++currentWhiteTG; + break; + + case AHB_GREEN_TG: + ++currentGreenTG; + break; + + case AHB_BLUE_TG: + ++currentBlueTG; + break; + + case AHB_PURPLE_TG: + ++currentPurpleTG; + break; + + case AHB_ORANGE_TG: + ++currentOrangeTG; + break; + + case AHB_YELLOW_TG: + ++currentYellowTG; + break; + + default: + break; } - if ((greyTradeGoodsBin.size() == 0) && - (whiteTradeGoodsBin.size() == 0) && - (greenTradeGoodsBin.size() == 0) && - (blueTradeGoodsBin.size() == 0) && - (purpleTradeGoodsBin.size() == 0) && - (orangeTradeGoodsBin.size() == 0) && - (yellowTradeGoodsBin.size() == 0) && - (greyItemsBin.size() == 0) && - (whiteItemsBin.size() == 0) && - (greenItemsBin.size() == 0) && - (blueItemsBin.size() == 0) && - (purpleItemsBin.size() == 0) && - (orangeItemsBin.size() == 0) && - (yellowItemsBin.size() == 0)) + nbSold++; + + if (config->TraceSeller) { - sLog->outError( "AuctionHouseBot: No items"); - AHBSeller = 0; + LOG_INFO("module", "AHBot [{}]: New stack ah={}, id={}, stack={}, bid={}, buyout={}", _id, config->GetAHID(), itemID, stackCount, auctionEntry->startbid, auctionEntry->buyout); } + } - sLog->outString("AuctionHouseBot:"); - sLog->outString("loaded %u grey trade goods", uint32(greyTradeGoodsBin.size())); - sLog->outString("loaded %u white trade goods", uint32(whiteTradeGoodsBin.size())); - sLog->outString("loaded %u green trade goods", uint32(greenTradeGoodsBin.size())); - sLog->outString("loaded %u blue trade goods", uint32(blueTradeGoodsBin.size())); - sLog->outString("loaded %u purple trade goods", uint32(purpleTradeGoodsBin.size())); - sLog->outString("loaded %u orange trade goods", uint32(orangeTradeGoodsBin.size())); - sLog->outString("loaded %u yellow trade goods", uint32(yellowTradeGoodsBin.size())); - sLog->outString("loaded %u grey items", uint32(greyItemsBin.size())); - sLog->outString("loaded %u white items", uint32(whiteItemsBin.size())); - sLog->outString("loaded %u green items", uint32(greenItemsBin.size())); - sLog->outString("loaded %u blue items", uint32(blueItemsBin.size())); - sLog->outString("loaded %u purple items", uint32(purpleItemsBin.size())); - sLog->outString("loaded %u orange items", uint32(orangeItemsBin.size())); - sLog->outString("loaded %u yellow items", uint32(yellowItemsBin.size())); + if (config->TraceSeller) + { + LOG_INFO("module", "AHBot [{}]: auctionhouse {}, req={}, sold={}, aboveMin={}, aboveMax={}, loopBrk={}, noNeed={}, tooMany={}, binEmpty={}, err={}", _id, config->GetAHID(), nbItemsToSellThisCycle, nbSold, aboveMin, aboveMax, loopBrk, noNeed, tooMany, binEmpty, err); } - sLog->outString("AuctionHouseBot and AuctionHouseBuyer have been loaded."); } -void AuctionHouseBot::InitializeConfiguration() -{ - debug_Out = sConfigMgr->GetBoolDefault("AuctionHouseBot.DEBUG", false); - debug_Out_Filters = sConfigMgr->GetBoolDefault("AuctionHouseBot.DEBUG_FILTERS", false); - - AHBSeller = sConfigMgr->GetBoolDefault("AuctionHouseBot.EnableSeller", false); - AHBBuyer = sConfigMgr->GetBoolDefault("AuctionHouseBot.EnableBuyer", false); - SellMethod = sConfigMgr->GetBoolDefault("AuctionHouseBot.UseBuyPriceForSeller", false); - BuyMethod = sConfigMgr->GetBoolDefault("AuctionHouseBot.UseBuyPriceForBuyer", false); - - AHBplayerAccount = sConfigMgr->GetIntDefault("AuctionHouseBot.Account", 0); - AHBplayerGUID = sConfigMgr->GetIntDefault("AuctionHouseBot.GUID", 0); - ItemsPerCycle = sConfigMgr->GetIntDefault("AuctionHouseBot.ItemsPerCycle", 200); - - //Begin Filters - - Vendor_Items = sConfigMgr->GetBoolDefault("AuctionHouseBot.VendorItems", false); - Loot_Items = sConfigMgr->GetBoolDefault("AuctionHouseBot.LootItems", true); - Other_Items = sConfigMgr->GetBoolDefault("AuctionHouseBot.OtherItems", false); - Vendor_TGs = sConfigMgr->GetBoolDefault("AuctionHouseBot.VendorTradeGoods", false); - Loot_TGs = sConfigMgr->GetBoolDefault("AuctionHouseBot.LootTradeGoods", true); - Other_TGs = sConfigMgr->GetBoolDefault("AuctionHouseBot.OtherTradeGoods", false); - - No_Bind = sConfigMgr->GetBoolDefault("AuctionHouseBot.No_Bind", true); - Bind_When_Picked_Up = sConfigMgr->GetBoolDefault("AuctionHouseBot.Bind_When_Picked_Up", false); - Bind_When_Equipped = sConfigMgr->GetBoolDefault("AuctionHouseBot.Bind_When_Equipped", true); - Bind_When_Use = sConfigMgr->GetBoolDefault("AuctionHouseBot.Bind_When_Use", true); - Bind_Quest_Item = sConfigMgr->GetBoolDefault("AuctionHouseBot.Bind_Quest_Item", false); - - DisablePermEnchant = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisablePermEnchant", false); - DisableConjured = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableConjured", false); - DisableGems = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableGems", false); - DisableMoney = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableMoney", false); - DisableMoneyLoot = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableMoneyLoot", false); - DisableLootable = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableLootable", false); - DisableKeys = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableKeys", false); - DisableDuration = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableDuration", false); - DisableBOP_Or_Quest_NoReqLevel = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableBOP_Or_Quest_NoReqLevel", false); - - DisableWarriorItems = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableWarriorItems", false); - DisablePaladinItems = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisablePaladinItems", false); - DisableHunterItems = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableHunterItems", false); - DisableRogueItems = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableRogueItems", false); - DisablePriestItems = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisablePriestItems", false); - DisableDKItems = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableDKItems", false); - DisableShamanItems = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableShamanItems", false); - DisableMageItems = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableMageItems", false); - DisableWarlockItems = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableWarlockItems", false); - DisableUnusedClassItems = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableUnusedClassItems", false); - DisableDruidItems = sConfigMgr->GetBoolDefault("AuctionHouseBot.DisableDruidItems", false); - - DisableItemsBelowLevel = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableItemsBelowLevel", 0); - DisableItemsAboveLevel = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableItemsAboveLevel", 0); - DisableTGsBelowLevel = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableTGsBelowLevel", 0); - DisableTGsAboveLevel = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableTGsAboveLevel", 0); - DisableItemsBelowGUID = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableItemsBelowGUID", 0); - DisableItemsAboveGUID = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableItemsAboveGUID", 0); - DisableTGsBelowGUID = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableTGsBelowGUID", 0); - DisableTGsAboveGUID = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableTGsAboveGUID", 0); - DisableItemsBelowReqLevel = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableItemsBelowReqLevel", 0); - DisableItemsAboveReqLevel = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableItemsAboveReqLevel", 0); - DisableTGsBelowReqLevel = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableTGsBelowReqLevel", 0); - DisableTGsAboveReqLevel = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableTGsAboveReqLevel", 0); - DisableItemsBelowReqSkillRank = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableItemsBelowReqSkillRank", 0); - DisableItemsAboveReqSkillRank = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableItemsAboveReqSkillRank", 0); - DisableTGsBelowReqSkillRank = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableTGsBelowReqSkillRank", 0); - DisableTGsAboveReqSkillRank = sConfigMgr->GetIntDefault("AuctionHouseBot.DisableTGsAboveReqSkillRank", 0); -} +// ============================================================================= +// Perform an update cycle +// ============================================================================= -void AuctionHouseBot::IncrementItemCounts(AuctionEntry* ah) +void AuctionHouseBot::Update() { - // from auctionhousehandler.cpp, creates auction pointer & player pointer + time_t _newrun = time(NULL); + + // + // If no configuration is associated, then stop here + // - // get exact item information - Item *pItem = sAuctionMgr->GetAItem(ah->item_guidlow); - if (!pItem) + if (!_allianceConfig && !_hordeConfig && !_neutralConfig) { - if (debug_Out) sLog->outError( "AHBot: Item %u doesn't exist, perhaps bought already?", ah->item_guidlow); return; } - // get item prototype - ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(ah->item_template); + // + // Preprare for operation + // - AHBConfig *config; + std::string accountName = "AuctionHouseBot" + std::to_string(_account); - FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(ah->GetHouseFaction()); - if (!u_entry) - { - if (debug_Out) sLog->outError( "AHBot: %u returned as House Faction. Neutral", ah->GetHouseFaction()); - config = &NeutralConfig; - } - else if (u_entry->ourMask & FACTION_MASK_ALLIANCE) - { - if (debug_Out) sLog->outError( "AHBot: %u returned as House Faction. Alliance", ah->GetHouseFaction()); - config = &AllianceConfig; - } - else if (u_entry->ourMask & FACTION_MASK_HORDE) - { - if (debug_Out) sLog->outError( "AHBot: %u returned as House Faction. Horde", ah->GetHouseFaction()); - config = &HordeConfig; - } - else - { - if (debug_Out) sLog->outError( "AHBot: %u returned as House Faction. Neutral", ah->GetHouseFaction()); - config = &NeutralConfig; - } + WorldSession _session(_account, std::move(accountName), 0, nullptr, SEC_PLAYER, sWorld->getIntConfig(CONFIG_EXPANSION), 0, LOCALE_enUS, 0, false, false, 0); - config->IncItemCounts(prototype->Class, prototype->Quality); -} + Player _AHBplayer(&_session); + _AHBplayer.Initialize(_id); -void AuctionHouseBot::DecrementItemCounts(AuctionEntry* ah, uint32 itemEntry) -{ - // get item prototype - ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(itemEntry); + ObjectAccessor::AddObject(&_AHBplayer); - AHBConfig *config; + LOG_INFO("module", "AHBot [{}]: Begin Performing Update Cycle", _id); - FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(ah->GetHouseFaction()); - if (!u_entry) - { - if (debug_Out) sLog->outError( "AHBot: %u returned as House Faction. Neutral", ah->GetHouseFaction()); - config = &NeutralConfig; - } - else if (u_entry->ourMask & FACTION_MASK_ALLIANCE) - { - if (debug_Out) sLog->outError( "AHBot: %u returned as House Faction. Alliance", ah->GetHouseFaction()); - config = &AllianceConfig; - } - else if (u_entry->ourMask & FACTION_MASK_HORDE) + // + // Perform update for the factions markets + // + + if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) { - if (debug_Out) sLog->outError( "AHBot: %u returned as House Faction. Horde", ah->GetHouseFaction()); - config = &HordeConfig; + // + // Alliance + // + + if (_allianceConfig) + { + if (_allianceConfig->TraceSeller) + { + LOG_INFO("module", "AHBot [{}]: Begin Sell for Alliance...", _id); + } + + Sell(&_AHBplayer, _allianceConfig); + + if (((_newrun - _lastrun_a_sec) >= (_allianceConfig->GetBiddingInterval() * MINUTE)) && (_allianceConfig->GetBidsPerInterval() > 0)) + { + if (_allianceConfig->TraceBuyer) + { + LOG_INFO("module", "AHBot [{}]: Begin Buy for Alliance...", _id); + } + + Buy(&_AHBplayer, _allianceConfig, &_session); + _lastrun_a_sec = _newrun; + } + } + + // + // Horde + // + + if (_hordeConfig) + { + if (_hordeConfig->TraceSeller) + { + LOG_INFO("module", "AHBot [{}]: Begin Sell for Horde...", _id); + } + Sell(&_AHBplayer, _hordeConfig); + + if (((_newrun - _lastrun_h_sec) >= (_hordeConfig->GetBiddingInterval() * MINUTE)) && (_hordeConfig->GetBidsPerInterval() > 0)) + { + if (_hordeConfig->TraceBuyer) + { + LOG_INFO("module", "AHBot [{}]: Begin Buy for Horde...", _id); + } + Buy(&_AHBplayer, _hordeConfig, &_session); + _lastrun_h_sec = _newrun; + } + } + } - else + + // + // Neutral + // + + if (_neutralConfig) { - if (debug_Out) sLog->outError( "AHBot: %u returned as House Faction. Neutral", ah->GetHouseFaction()); - config = &NeutralConfig; + if (_neutralConfig->TraceSeller) + { + LOG_INFO("module", "AHBot [{}]: Begin Sell for Neutral...", _id); + } + Sell(&_AHBplayer, _neutralConfig); + + if (((_newrun - _lastrun_n_sec) >= (_neutralConfig->GetBiddingInterval() * MINUTE)) && (_neutralConfig->GetBidsPerInterval() > 0)) + { + if (_neutralConfig->TraceBuyer) + { + LOG_INFO("module", "AHBot [{}]: Begin Buy for Neutral...", _id); + } + Buy(&_AHBplayer, _neutralConfig, &_session); + _lastrun_n_sec = _newrun; + } } - config->DecItemCounts(prototype->Class, prototype->Quality); + ObjectAccessor::RemoveObject(&_AHBplayer); } -void AuctionHouseBot::Commands(uint32 command, uint32 ahMapID, uint32 col, char* args) +// ============================================================================= +// Execute commands coming from the console +// ============================================================================= + +void AuctionHouseBot::Commands(AHBotCommand command, uint32 ahMapID, uint32 col, char* args) { + // + // Retrieve the auction house configuration + // + AHBConfig *config = NULL; + switch (ahMapID) { case 2: - config = &AllianceConfig; + config = _allianceConfig; break; case 6: - config = &HordeConfig; + config = _hordeConfig; break; - case 7: - config = &NeutralConfig; + default: + config = _neutralConfig; break; } + + // + // Retrive the item quality + // + std::string color; + switch (col) { case AHB_GREY: @@ -1510,389 +1176,297 @@ void AuctionHouseBot::Commands(uint32 command, uint32 ahMapID, uint32 col, char* default: break; } + + // + // Perform the command + // + switch (command) { - case 0: //ahexpire - { - AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(config->GetAHFID()); - - AuctionHouseObject::AuctionEntryMap::iterator itr; - itr = auctionHouse->GetAuctionsBegin(); + case AHBotCommand::buyer: + { + char* param1 = strtok(args, " "); + uint32 state = (uint32)strtoul(param1, NULL, 0); - while (itr != auctionHouse->GetAuctionsEnd()) - { - if (itr->second->owner == AHBplayerGUID) - { - itr->second->expire_time = sWorld->GetGameTime(); - uint32 id = itr->second->Id; - uint32 expire_time = itr->second->expire_time; - CharacterDatabase.PExecute("UPDATE auctionhouse SET time = '%u' WHERE id = '%u'", expire_time, id); - } - ++itr; - } - } - break; - case 1: //min items + if (state == 0) { - char * param1 = strtok(args, " "); - uint32 minItems = (uint32) strtoul(param1, NULL, 0); - WorldDatabase.PExecute("UPDATE auctionhousebot SET minitems = '%u' WHERE auctionhouse = '%u'", minItems, ahMapID); - config->SetMinItems(minItems); + _allianceConfig->AHBBuyer = false; + _hordeConfig->AHBBuyer = false; + _neutralConfig->AHBBuyer = false; } - break; - case 2: //max items + else { - char * param1 = strtok(args, " "); - uint32 maxItems = (uint32) strtoul(param1, NULL, 0); - WorldDatabase.PExecute("UPDATE auctionhousebot SET maxitems = '%u' WHERE auctionhouse = '%u'", maxItems, ahMapID); - config->SetMaxItems(maxItems); - config->CalculatePercents(); + _allianceConfig->AHBBuyer = true; + _hordeConfig->AHBBuyer = true; + _neutralConfig->AHBBuyer = true; } + break; - case 3: //min time Deprecated (Place holder for future commands) - break; - case 4: //max time Deprecated (Place holder for future commands) - break; - case 5: //percentages + } + case AHBotCommand::seller: + { + char* param1 = strtok(args, " "); + uint32 state = (uint32)strtoul(param1, NULL, 0); + + if (state == 0) { - char * param1 = strtok(args, " "); - char * param2 = strtok(NULL, " "); - char * param3 = strtok(NULL, " "); - char * param4 = strtok(NULL, " "); - char * param5 = strtok(NULL, " "); - char * param6 = strtok(NULL, " "); - char * param7 = strtok(NULL, " "); - char * param8 = strtok(NULL, " "); - char * param9 = strtok(NULL, " "); - char * param10 = strtok(NULL, " "); - char * param11 = strtok(NULL, " "); - char * param12 = strtok(NULL, " "); - char * param13 = strtok(NULL, " "); - char * param14 = strtok(NULL, " "); - uint32 greytg = (uint32) strtoul(param1, NULL, 0); - uint32 whitetg = (uint32) strtoul(param2, NULL, 0); - uint32 greentg = (uint32) strtoul(param3, NULL, 0); - uint32 bluetg = (uint32) strtoul(param4, NULL, 0); - uint32 purpletg = (uint32) strtoul(param5, NULL, 0); - uint32 orangetg = (uint32) strtoul(param6, NULL, 0); - uint32 yellowtg = (uint32) strtoul(param7, NULL, 0); - uint32 greyi = (uint32) strtoul(param8, NULL, 0); - uint32 whitei = (uint32) strtoul(param9, NULL, 0); - uint32 greeni = (uint32) strtoul(param10, NULL, 0); - uint32 bluei = (uint32) strtoul(param11, NULL, 0); - uint32 purplei = (uint32) strtoul(param12, NULL, 0); - uint32 orangei = (uint32) strtoul(param13, NULL, 0); - uint32 yellowi = (uint32) strtoul(param14, NULL, 0); - - SQLTransaction trans = WorldDatabase.BeginTransaction(); - trans->PAppend("UPDATE auctionhousebot SET percentgreytradegoods = '%u' WHERE auctionhouse = '%u'", greytg, ahMapID); - trans->PAppend("UPDATE auctionhousebot SET percentwhitetradegoods = '%u' WHERE auctionhouse = '%u'", whitetg, ahMapID); - trans->PAppend("UPDATE auctionhousebot SET percentgreentradegoods = '%u' WHERE auctionhouse = '%u'", greentg, ahMapID); - trans->PAppend("UPDATE auctionhousebot SET percentbluetradegoods = '%u' WHERE auctionhouse = '%u'", bluetg, ahMapID); - trans->PAppend("UPDATE auctionhousebot SET percentpurpletradegoods = '%u' WHERE auctionhouse = '%u'", purpletg, ahMapID); - trans->PAppend("UPDATE auctionhousebot SET percentorangetradegoods = '%u' WHERE auctionhouse = '%u'", orangetg, ahMapID); - trans->PAppend("UPDATE auctionhousebot SET percentyellowtradegoods = '%u' WHERE auctionhouse = '%u'", yellowtg, ahMapID); - trans->PAppend("UPDATE auctionhousebot SET percentgreyitems = '%u' WHERE auctionhouse = '%u'", greyi, ahMapID); - trans->PAppend("UPDATE auctionhousebot SET percentwhiteitems = '%u' WHERE auctionhouse = '%u'", whitei, ahMapID); - trans->PAppend("UPDATE auctionhousebot SET percentgreenitems = '%u' WHERE auctionhouse = '%u'", greeni, ahMapID); - trans->PAppend("UPDATE auctionhousebot SET percentblueitems = '%u' WHERE auctionhouse = '%u'", bluei, ahMapID); - trans->PAppend("UPDATE auctionhousebot SET percentpurpleitems = '%u' WHERE auctionhouse = '%u'", purplei, ahMapID); - trans->PAppend("UPDATE auctionhousebot SET percentorangeitems = '%u' WHERE auctionhouse = '%u'", orangei, ahMapID); - trans->PAppend("UPDATE auctionhousebot SET percentyellowitems = '%u' WHERE auctionhouse = '%u'", yellowi, ahMapID); - WorldDatabase.CommitTransaction(trans); - config->SetPercentages(greytg, whitetg, greentg, bluetg, purpletg, orangetg, yellowtg, greyi, whitei, greeni, bluei, purplei, orangei, yellowi); + _allianceConfig->AHBSeller = false; + _hordeConfig->AHBSeller = false; + _neutralConfig->AHBSeller = false; } - break; - case 6: //min prices + else { - char * param1 = strtok(args, " "); - uint32 minPrice = (uint32) strtoul(param1, NULL, 0); - WorldDatabase.PExecute("UPDATE auctionhousebot SET minprice%s = '%u' WHERE auctionhouse = '%u'", color.c_str(), minPrice, ahMapID); - config->SetMinPrice(col, minPrice); + _allianceConfig->AHBSeller = true; + _hordeConfig->AHBSeller = true; + _neutralConfig->AHBSeller = true; } + break; - case 7: //max prices + } + case AHBotCommand::useMarketPrice: + { + char* param1 = strtok(args, " "); + uint32 state = (uint32)strtoul(param1, NULL, 0); + + if (state == 0) { - char * param1 = strtok(args, " "); - uint32 maxPrice = (uint32) strtoul(param1, NULL, 0); - WorldDatabase.PExecute("UPDATE auctionhousebot SET maxprice%s = '%u' WHERE auctionhouse = '%u'", color.c_str(), maxPrice, ahMapID); - config->SetMaxPrice(col, maxPrice); + _allianceConfig->SellAtMarketPrice = false; + _hordeConfig->SellAtMarketPrice = false; + _neutralConfig->SellAtMarketPrice = false; } - break; - case 8: //min bid price + else { - char * param1 = strtok(args, " "); - uint32 minBidPrice = (uint32) strtoul(param1, NULL, 0); - WorldDatabase.PExecute("UPDATE auctionhousebot SET minbidprice%s = '%u' WHERE auctionhouse = '%u'", color.c_str(), minBidPrice, ahMapID); - config->SetMinBidPrice(col, minBidPrice); + _allianceConfig->SellAtMarketPrice = true; + _hordeConfig->SellAtMarketPrice = true; + _neutralConfig->SellAtMarketPrice = true; } + break; - case 9: //max bid price + } + case AHBotCommand::ahexpire: + { + AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(config->GetAHFID()); + + AuctionHouseObject::AuctionEntryMap::iterator itr; + itr = auctionHouse->GetAuctionsBegin(); + + // + // Iterate through all the autions and if they belong to the bot, make them expired + // + + while (itr != auctionHouse->GetAuctionsEnd()) { - char * param1 = strtok(args, " "); - uint32 maxBidPrice = (uint32) strtoul(param1, NULL, 0); - WorldDatabase.PExecute("UPDATE auctionhousebot SET maxbidprice%s = '%u' WHERE auctionhouse = '%u'", color.c_str(), maxBidPrice, ahMapID); - config->SetMaxBidPrice(col, maxBidPrice); + if (itr->second->owner.GetCounter() == _id) + { + // Expired NOW. + itr->second->expire_time = GameTime::GetGameTime().count(); + + uint32 id = itr->second->Id; + uint32 expire_time = itr->second->expire_time; + + CharacterDatabase.Execute("UPDATE auctionhouse SET time = '{}' WHERE id = '{}'", expire_time, id); + } + + ++itr; } + break; - case 10: //max stacks - { - char * param1 = strtok(args, " "); - uint32 maxStack = (uint32) strtoul(param1, NULL, 0); - WorldDatabase.PExecute("UPDATE auctionhousebot SET maxstack%s = '%u' WHERE auctionhouse = '%u'", color.c_str(), maxStack, ahMapID); - config->SetMaxStack(col, maxStack); - } + } + case AHBotCommand::minitems: + { + char * param1 = strtok(args, " "); + uint32 minItems = (uint32) strtoul(param1, NULL, 0); + + WorldDatabase.Execute("UPDATE mod_auctionhousebot SET minitems = '{}' WHERE auctionhouse = '{}'", minItems, ahMapID); + + config->SetMinItems(minItems); + break; - case 11: //buyer bid prices - { - char * param1 = strtok(args, " "); - uint32 buyerPrice = (uint32) strtoul(param1, NULL, 0); - WorldDatabase.PExecute("UPDATE auctionhousebot SET buyerprice%s = '%u' WHERE auctionhouse = '%u'", color.c_str(), buyerPrice, ahMapID); - config->SetBuyerPrice(col, buyerPrice); - } + } + case AHBotCommand::maxitems: + { + char * param1 = strtok(args, " "); + uint32 maxItems = (uint32) strtoul(param1, NULL, 0); + + WorldDatabase.Execute("UPDATE mod_auctionhousebot SET maxitems = '{}' WHERE auctionhouse = '{}'", maxItems, ahMapID); + + config->SetMaxItems(maxItems); + config->CalculatePercents(); break; - case 12: //buyer bidding interval - { - char * param1 = strtok(args, " "); - uint32 bidInterval = (uint32) strtoul(param1, NULL, 0); - WorldDatabase.PExecute("UPDATE auctionhousebot SET buyerbiddinginterval = '%u' WHERE auctionhouse = '%u'", bidInterval, ahMapID); - config->SetBiddingInterval(bidInterval); - } + } + case AHBotCommand::percentages: + { + char * param1 = strtok(args, " "); + char * param2 = strtok(NULL, " "); + char * param3 = strtok(NULL, " "); + char * param4 = strtok(NULL, " "); + char * param5 = strtok(NULL, " "); + char * param6 = strtok(NULL, " "); + char * param7 = strtok(NULL, " "); + char * param8 = strtok(NULL, " "); + char * param9 = strtok(NULL, " "); + char * param10 = strtok(NULL, " "); + char * param11 = strtok(NULL, " "); + char * param12 = strtok(NULL, " "); + char * param13 = strtok(NULL, " "); + char * param14 = strtok(NULL, " "); + + uint32 greytg = (uint32) strtoul(param1, NULL, 0); + uint32 whitetg = (uint32) strtoul(param2, NULL, 0); + uint32 greentg = (uint32) strtoul(param3, NULL, 0); + uint32 bluetg = (uint32) strtoul(param4, NULL, 0); + uint32 purpletg = (uint32) strtoul(param5, NULL, 0); + uint32 orangetg = (uint32) strtoul(param6, NULL, 0); + uint32 yellowtg = (uint32) strtoul(param7, NULL, 0); + uint32 greyi = (uint32) strtoul(param8, NULL, 0); + uint32 whitei = (uint32) strtoul(param9, NULL, 0); + uint32 greeni = (uint32) strtoul(param10, NULL, 0); + uint32 bluei = (uint32) strtoul(param11, NULL, 0); + uint32 purplei = (uint32) strtoul(param12, NULL, 0); + uint32 orangei = (uint32) strtoul(param13, NULL, 0); + uint32 yellowi = (uint32) strtoul(param14, NULL, 0); + + // + // Setup the percentage in the configuration first, so validity test can be performed + // + + config->SetPercentages(greytg, whitetg, greentg, bluetg, purpletg, orangetg, yellowtg, greyi, whitei, greeni, bluei, purplei, orangei, yellowi); + + // + // Save the results into the database (after the tests) + // + + auto trans = WorldDatabase.BeginTransaction(); + + trans->Append("UPDATE mod_auctionhousebot SET percentgreytradegoods = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_GREY_TG) , ahMapID); + trans->Append("UPDATE mod_auctionhousebot SET percentwhitetradegoods = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_WHITE_TG) , ahMapID); + trans->Append("UPDATE mod_auctionhousebot SET percentgreentradegoods = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_GREEN_TG) , ahMapID); + trans->Append("UPDATE mod_auctionhousebot SET percentbluetradegoods = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_BLUE_TG) , ahMapID); + trans->Append("UPDATE mod_auctionhousebot SET percentpurpletradegoods = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_PURPLE_TG), ahMapID); + trans->Append("UPDATE mod_auctionhousebot SET percentorangetradegoods = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_ORANGE_TG), ahMapID); + trans->Append("UPDATE mod_auctionhousebot SET percentyellowtradegoods = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_YELLOW_TG), ahMapID); + trans->Append("UPDATE mod_auctionhousebot SET percentgreyitems = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_GREY_I) , ahMapID); + trans->Append("UPDATE mod_auctionhousebot SET percentwhiteitems = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_WHITE_I) , ahMapID); + trans->Append("UPDATE mod_auctionhousebot SET percentgreenitems = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_GREEN_I) , ahMapID); + trans->Append("UPDATE mod_auctionhousebot SET percentblueitems = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_BLUE_I) , ahMapID); + trans->Append("UPDATE mod_auctionhousebot SET percentpurpleitems = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_PURPLE_I) , ahMapID); + trans->Append("UPDATE mod_auctionhousebot SET percentorangeitems = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_ORANGE_I) , ahMapID); + trans->Append("UPDATE mod_auctionhousebot SET percentyellowitems = '{}' WHERE auctionhouse = '{}'", config->GetPercentages(AHB_YELLOW_I) , ahMapID); + + WorldDatabase.CommitTransaction(trans); + break; - case 13: //buyer bids per interval - { - char * param1 = strtok(args, " "); - uint32 bidsPerInterval = (uint32) strtoul(param1, NULL, 0); - WorldDatabase.PExecute("UPDATE auctionhousebot SET buyerbidsperinterval = '%u' WHERE auctionhouse = '%u'", bidsPerInterval, ahMapID); - config->SetBidsPerInterval(bidsPerInterval); - } + } + case AHBotCommand::minprice: + { + char * param1 = strtok(args, " "); + uint32 minPrice = (uint32) strtoul(param1, NULL, 0); + + WorldDatabase.Execute("UPDATE mod_auctionhousebot SET minprice{} = '{}' WHERE auctionhouse = '{}'", color, minPrice, ahMapID); + + config->SetMinPrice(col, minPrice); + break; - default: + } + case AHBotCommand::maxprice: + { + char * param1 = strtok(args, " "); + uint32 maxPrice = (uint32) strtoul(param1, NULL, 0); + + WorldDatabase.Execute("UPDATE mod_auctionhousebot SET maxprice{} = '{}' WHERE auctionhouse = '{}'", color, maxPrice, ahMapID); + + config->SetMaxPrice(col, maxPrice); + break; } -} + case AHBotCommand::minbidprice: + { + char * param1 = strtok(args, " "); + uint32 minBidPrice = (uint32) strtoul(param1, NULL, 0); -void AuctionHouseBot::LoadValues(AHBConfig *config) -{ - if (debug_Out) - sLog->outError( "Start Settings for %s Auctionhouses:", WorldDatabase.PQuery("SELECT name FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetCString()); - if (AHBSeller) + WorldDatabase.Execute("UPDATE mod_auctionhousebot SET minbidprice{} = '{}' WHERE auctionhouse = '{}'", color, minBidPrice, ahMapID); + + config->SetMinBidPrice(col, minBidPrice); + + break; + } + case AHBotCommand::maxbidprice: { - //load min and max items - config->SetMinItems(WorldDatabase.PQuery("SELECT minitems FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxItems(WorldDatabase.PQuery("SELECT maxitems FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - //load percentages - uint32 greytg = WorldDatabase.PQuery("SELECT percentgreytradegoods FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32(); - uint32 whitetg = WorldDatabase.PQuery("SELECT percentwhitetradegoods FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32(); - uint32 greentg = WorldDatabase.PQuery("SELECT percentgreentradegoods FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32(); - uint32 bluetg = WorldDatabase.PQuery("SELECT percentbluetradegoods FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32(); - uint32 purpletg = WorldDatabase.PQuery("SELECT percentpurpletradegoods FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32(); - uint32 orangetg = WorldDatabase.PQuery("SELECT percentorangetradegoods FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32(); - uint32 yellowtg = WorldDatabase.PQuery("SELECT percentyellowtradegoods FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32(); - uint32 greyi = WorldDatabase.PQuery("SELECT percentgreyitems FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32(); - uint32 whitei = WorldDatabase.PQuery("SELECT percentwhiteitems FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32(); - uint32 greeni = WorldDatabase.PQuery("SELECT percentgreenitems FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32(); - uint32 bluei = WorldDatabase.PQuery("SELECT percentblueitems FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32(); - uint32 purplei = WorldDatabase.PQuery("SELECT percentpurpleitems FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32(); - uint32 orangei = WorldDatabase.PQuery("SELECT percentorangeitems FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32(); - uint32 yellowi = WorldDatabase.PQuery("SELECT percentyellowitems FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32(); - config->SetPercentages(greytg, whitetg, greentg, bluetg, purpletg, orangetg, yellowtg, greyi, whitei, greeni, bluei, purplei, orangei, yellowi); - //load min and max prices - config->SetMinPrice(AHB_GREY, WorldDatabase.PQuery("SELECT minpricegrey FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxPrice(AHB_GREY, WorldDatabase.PQuery("SELECT maxpricegrey FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMinPrice(AHB_WHITE, WorldDatabase.PQuery("SELECT minpricewhite FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxPrice(AHB_WHITE, WorldDatabase.PQuery("SELECT maxpricewhite FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMinPrice(AHB_GREEN, WorldDatabase.PQuery("SELECT minpricegreen FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxPrice(AHB_GREEN, WorldDatabase.PQuery("SELECT maxpricegreen FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMinPrice(AHB_BLUE, WorldDatabase.PQuery("SELECT minpriceblue FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxPrice(AHB_BLUE, WorldDatabase.PQuery("SELECT maxpriceblue FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMinPrice(AHB_PURPLE, WorldDatabase.PQuery("SELECT minpricepurple FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxPrice(AHB_PURPLE, WorldDatabase.PQuery("SELECT maxpricepurple FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMinPrice(AHB_ORANGE, WorldDatabase.PQuery("SELECT minpriceorange FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxPrice(AHB_ORANGE, WorldDatabase.PQuery("SELECT maxpriceorange FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMinPrice(AHB_YELLOW, WorldDatabase.PQuery("SELECT minpriceyellow FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxPrice(AHB_YELLOW, WorldDatabase.PQuery("SELECT maxpriceyellow FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - //load min and max bid prices - config->SetMinBidPrice(AHB_GREY, WorldDatabase.PQuery("SELECT minbidpricegrey FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxBidPrice(AHB_GREY, WorldDatabase.PQuery("SELECT maxbidpricegrey FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMinBidPrice(AHB_WHITE, WorldDatabase.PQuery("SELECT minbidpricewhite FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxBidPrice(AHB_WHITE, WorldDatabase.PQuery("SELECT maxbidpricewhite FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMinBidPrice(AHB_GREEN, WorldDatabase.PQuery("SELECT minbidpricegreen FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxBidPrice(AHB_GREEN, WorldDatabase.PQuery("SELECT maxbidpricegreen FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMinBidPrice(AHB_BLUE, WorldDatabase.PQuery("SELECT minbidpriceblue FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxBidPrice(AHB_BLUE, WorldDatabase.PQuery("SELECT maxbidpriceblue FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMinBidPrice(AHB_PURPLE, WorldDatabase.PQuery("SELECT minbidpricepurple FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxBidPrice(AHB_PURPLE, WorldDatabase.PQuery("SELECT maxbidpricepurple FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMinBidPrice(AHB_ORANGE, WorldDatabase.PQuery("SELECT minbidpriceorange FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxBidPrice(AHB_ORANGE, WorldDatabase.PQuery("SELECT maxbidpriceorange FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMinBidPrice(AHB_YELLOW, WorldDatabase.PQuery("SELECT minbidpriceyellow FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxBidPrice(AHB_YELLOW, WorldDatabase.PQuery("SELECT maxbidpriceyellow FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - //load max stacks - config->SetMaxStack(AHB_GREY, WorldDatabase.PQuery("SELECT maxstackgrey FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxStack(AHB_WHITE, WorldDatabase.PQuery("SELECT maxstackwhite FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxStack(AHB_GREEN, WorldDatabase.PQuery("SELECT maxstackgreen FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxStack(AHB_BLUE, WorldDatabase.PQuery("SELECT maxstackblue FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxStack(AHB_PURPLE, WorldDatabase.PQuery("SELECT maxstackpurple FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxStack(AHB_ORANGE, WorldDatabase.PQuery("SELECT maxstackorange FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetMaxStack(AHB_YELLOW, WorldDatabase.PQuery("SELECT maxstackyellow FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - if (debug_Out) - { - sLog->outError( "minItems = %u", config->GetMinItems()); - sLog->outError( "maxItems = %u", config->GetMaxItems()); - sLog->outError( "percentGreyTradeGoods = %u", config->GetPercentages(AHB_GREY_TG)); - sLog->outError( "percentWhiteTradeGoods = %u", config->GetPercentages(AHB_WHITE_TG)); - sLog->outError( "percentGreenTradeGoods = %u", config->GetPercentages(AHB_GREEN_TG)); - sLog->outError( "percentBlueTradeGoods = %u", config->GetPercentages(AHB_BLUE_TG)); - sLog->outError( "percentPurpleTradeGoods = %u", config->GetPercentages(AHB_PURPLE_TG)); - sLog->outError( "percentOrangeTradeGoods = %u", config->GetPercentages(AHB_ORANGE_TG)); - sLog->outError( "percentYellowTradeGoods = %u", config->GetPercentages(AHB_YELLOW_TG)); - sLog->outError( "percentGreyItems = %u", config->GetPercentages(AHB_GREY_I)); - sLog->outError( "percentWhiteItems = %u", config->GetPercentages(AHB_WHITE_I)); - sLog->outError( "percentGreenItems = %u", config->GetPercentages(AHB_GREEN_I)); - sLog->outError( "percentBlueItems = %u", config->GetPercentages(AHB_BLUE_I)); - sLog->outError( "percentPurpleItems = %u", config->GetPercentages(AHB_PURPLE_I)); - sLog->outError( "percentOrangeItems = %u", config->GetPercentages(AHB_ORANGE_I)); - sLog->outError( "percentYellowItems = %u", config->GetPercentages(AHB_YELLOW_I)); - sLog->outError( "minPriceGrey = %u", config->GetMinPrice(AHB_GREY)); - sLog->outError( "maxPriceGrey = %u", config->GetMaxPrice(AHB_GREY)); - sLog->outError( "minPriceWhite = %u", config->GetMinPrice(AHB_WHITE)); - sLog->outError( "maxPriceWhite = %u", config->GetMaxPrice(AHB_WHITE)); - sLog->outError( "minPriceGreen = %u", config->GetMinPrice(AHB_GREEN)); - sLog->outError( "maxPriceGreen = %u", config->GetMaxPrice(AHB_GREEN)); - sLog->outError( "minPriceBlue = %u", config->GetMinPrice(AHB_BLUE)); - sLog->outError( "maxPriceBlue = %u", config->GetMaxPrice(AHB_BLUE)); - sLog->outError( "minPricePurple = %u", config->GetMinPrice(AHB_PURPLE)); - sLog->outError( "maxPricePurple = %u", config->GetMaxPrice(AHB_PURPLE)); - sLog->outError( "minPriceOrange = %u", config->GetMinPrice(AHB_ORANGE)); - sLog->outError( "maxPriceOrange = %u", config->GetMaxPrice(AHB_ORANGE)); - sLog->outError( "minPriceYellow = %u", config->GetMinPrice(AHB_YELLOW)); - sLog->outError( "maxPriceYellow = %u", config->GetMaxPrice(AHB_YELLOW)); - sLog->outError( "minBidPriceGrey = %u", config->GetMinBidPrice(AHB_GREY)); - sLog->outError( "maxBidPriceGrey = %u", config->GetMaxBidPrice(AHB_GREY)); - sLog->outError( "minBidPriceWhite = %u", config->GetMinBidPrice(AHB_WHITE)); - sLog->outError( "maxBidPriceWhite = %u", config->GetMaxBidPrice(AHB_WHITE)); - sLog->outError( "minBidPriceGreen = %u", config->GetMinBidPrice(AHB_GREEN)); - sLog->outError( "maxBidPriceGreen = %u", config->GetMaxBidPrice(AHB_GREEN)); - sLog->outError( "minBidPriceBlue = %u", config->GetMinBidPrice(AHB_BLUE)); - sLog->outError( "maxBidPriceBlue = %u", config->GetMinBidPrice(AHB_BLUE)); - sLog->outError( "minBidPricePurple = %u", config->GetMinBidPrice(AHB_PURPLE)); - sLog->outError( "maxBidPricePurple = %u", config->GetMaxBidPrice(AHB_PURPLE)); - sLog->outError( "minBidPriceOrange = %u", config->GetMinBidPrice(AHB_ORANGE)); - sLog->outError( "maxBidPriceOrange = %u", config->GetMaxBidPrice(AHB_ORANGE)); - sLog->outError( "minBidPriceYellow = %u", config->GetMinBidPrice(AHB_YELLOW)); - sLog->outError( "maxBidPriceYellow = %u", config->GetMaxBidPrice(AHB_YELLOW)); - sLog->outError( "maxStackGrey = %u", config->GetMaxStack(AHB_GREY)); - sLog->outError( "maxStackWhite = %u", config->GetMaxStack(AHB_WHITE)); - sLog->outError( "maxStackGreen = %u", config->GetMaxStack(AHB_GREEN)); - sLog->outError( "maxStackBlue = %u", config->GetMaxStack(AHB_BLUE)); - sLog->outError( "maxStackPurple = %u", config->GetMaxStack(AHB_PURPLE)); - sLog->outError( "maxStackOrange = %u", config->GetMaxStack(AHB_ORANGE)); - sLog->outError( "maxStackYellow = %u", config->GetMaxStack(AHB_YELLOW)); - } - //AuctionHouseEntry const* ahEntry = sAuctionMgr->GetAuctionHouseEntry(config->GetAHFID()); - AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(config->GetAHFID()); + char * param1 = strtok(args, " "); + uint32 maxBidPrice = (uint32) strtoul(param1, NULL, 0); - config->ResetItemCounts(); - uint32 auctions = auctionHouse->Getcount(); + WorldDatabase.Execute("UPDATE mod_auctionhousebot SET maxbidprice{} = '{}' WHERE auctionhouse = '{}'", color, maxBidPrice, ahMapID); - if (auctions) - { - for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr) - { - AuctionEntry *Aentry = itr->second; - Item *item = sAuctionMgr->GetAItem(Aentry->item_guidlow); - if (item) - { - ItemTemplate const *prototype = item->GetTemplate(); - if (prototype) - { - switch (prototype->Quality) - { - case 0: - if (prototype->Class == ITEM_CLASS_TRADE_GOODS) - config->IncItemCounts(AHB_GREY_TG); - else - config->IncItemCounts(AHB_GREY_I); - break; - case 1: - if (prototype->Class == ITEM_CLASS_TRADE_GOODS) - config->IncItemCounts(AHB_WHITE_TG); - else - config->IncItemCounts(AHB_WHITE_I); - break; - case 2: - if (prototype->Class == ITEM_CLASS_TRADE_GOODS) - config->IncItemCounts(AHB_GREEN_TG); - else - config->IncItemCounts(AHB_GREEN_I); - break; - case 3: - if (prototype->Class == ITEM_CLASS_TRADE_GOODS) - config->IncItemCounts(AHB_BLUE_TG); - else - config->IncItemCounts(AHB_BLUE_I); - break; - case 4: - if (prototype->Class == ITEM_CLASS_TRADE_GOODS) - config->IncItemCounts(AHB_PURPLE_TG); - else - config->IncItemCounts(AHB_PURPLE_I); - break; - case 5: - if (prototype->Class == ITEM_CLASS_TRADE_GOODS) - config->IncItemCounts(AHB_ORANGE_TG); - else - config->IncItemCounts(AHB_ORANGE_I); - break; - case 6: - if (prototype->Class == ITEM_CLASS_TRADE_GOODS) - config->IncItemCounts(AHB_YELLOW_TG); - else - config->IncItemCounts(AHB_YELLOW_I); - break; - } - } - } - } - } - if (debug_Out) - { - sLog->outError( "Current Settings for %s Auctionhouses:", WorldDatabase.PQuery("SELECT name FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetCString()); - sLog->outError( "Grey Trade Goods\t%u\tGrey Items\t%u", config->GetItemCounts(AHB_GREY_TG), config->GetItemCounts(AHB_GREY_I)); - sLog->outError( "White Trade Goods\t%u\tWhite Items\t%u", config->GetItemCounts(AHB_WHITE_TG), config->GetItemCounts(AHB_WHITE_I)); - sLog->outError( "Green Trade Goods\t%u\tGreen Items\t%u", config->GetItemCounts(AHB_GREEN_TG), config->GetItemCounts(AHB_GREEN_I)); - sLog->outError( "Blue Trade Goods\t%u\tBlue Items\t%u", config->GetItemCounts(AHB_BLUE_TG), config->GetItemCounts(AHB_BLUE_I)); - sLog->outError( "Purple Trade Goods\t%u\tPurple Items\t%u", config->GetItemCounts(AHB_PURPLE_TG), config->GetItemCounts(AHB_PURPLE_I)); - sLog->outError( "Orange Trade Goods\t%u\tOrange Items\t%u", config->GetItemCounts(AHB_ORANGE_TG), config->GetItemCounts(AHB_ORANGE_I)); - sLog->outError( "Yellow Trade Goods\t%u\tYellow Items\t%u", config->GetItemCounts(AHB_YELLOW_TG), config->GetItemCounts(AHB_YELLOW_I)); - } + config->SetMaxBidPrice(col, maxBidPrice); + + break; } - if (AHBBuyer) + case AHBotCommand::maxstack: { - //load buyer bid prices - config->SetBuyerPrice(AHB_GREY, WorldDatabase.PQuery("SELECT buyerpricegrey FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetBuyerPrice(AHB_WHITE, WorldDatabase.PQuery("SELECT buyerpricewhite FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetBuyerPrice(AHB_GREEN, WorldDatabase.PQuery("SELECT buyerpricegreen FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetBuyerPrice(AHB_BLUE, WorldDatabase.PQuery("SELECT buyerpriceblue FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetBuyerPrice(AHB_PURPLE, WorldDatabase.PQuery("SELECT buyerpricepurple FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetBuyerPrice(AHB_ORANGE, WorldDatabase.PQuery("SELECT buyerpriceorange FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - config->SetBuyerPrice(AHB_YELLOW, WorldDatabase.PQuery("SELECT buyerpriceyellow FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - //load bidding interval - config->SetBiddingInterval(WorldDatabase.PQuery("SELECT buyerbiddinginterval FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - //load bids per interval - config->SetBidsPerInterval(WorldDatabase.PQuery("SELECT buyerbidsperinterval FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetUInt32()); - if (debug_Out) - { - sLog->outError( "buyerPriceGrey = %u", config->GetBuyerPrice(AHB_GREY)); - sLog->outError( "buyerPriceWhite = %u", config->GetBuyerPrice(AHB_WHITE)); - sLog->outError( "buyerPriceGreen = %u", config->GetBuyerPrice(AHB_GREEN)); - sLog->outError( "buyerPriceBlue = %u", config->GetBuyerPrice(AHB_BLUE)); - sLog->outError( "buyerPricePurple = %u", config->GetBuyerPrice(AHB_PURPLE)); - sLog->outError( "buyerPriceOrange = %u", config->GetBuyerPrice(AHB_ORANGE)); - sLog->outError( "buyerPriceYellow = %u", config->GetBuyerPrice(AHB_YELLOW)); - sLog->outError( "buyerBiddingInterval = %u", config->GetBiddingInterval()); - sLog->outError( "buyerBidsPerInterval = %u", config->GetBidsPerInterval()); - } + char * param1 = strtok(args, " "); + uint32 maxStack = (uint32) strtoul(param1, NULL, 0); + + WorldDatabase.Execute("UPDATE mod_auctionhousebot SET maxstack{} = '{}' WHERE auctionhouse = '{}'", color, maxStack, ahMapID); + + config->SetMaxStack(col, maxStack); + + break; + } + case AHBotCommand::buyerprice: + { + char * param1 = strtok(args, " "); + uint32 buyerPrice = (uint32) strtoul(param1, NULL, 0); + + WorldDatabase.Execute("UPDATE mod_auctionhousebot SET buyerprice{} = '{}' WHERE auctionhouse = '{}'", color, buyerPrice, ahMapID); + + config->SetBuyerPrice(col, buyerPrice); + + break; + } + case AHBotCommand::bidinterval: + { + char * param1 = strtok(args, " "); + uint32 bidInterval = (uint32) strtoul(param1, NULL, 0); + + WorldDatabase.Execute("UPDATE mod_auctionhousebot SET buyerbiddinginterval = '{}' WHERE auctionhouse = '{}'", bidInterval, ahMapID); + + config->SetBiddingInterval(bidInterval); + + break; + } + case AHBotCommand::bidsperinterval: + { + char * param1 = strtok(args, " "); + uint32 bidsPerInterval = (uint32) strtoul(param1, NULL, 0); + + WorldDatabase.Execute("UPDATE mod_auctionhousebot SET buyerbidsperinterval = '{}' WHERE auctionhouse = '{}'", bidsPerInterval, ahMapID); + + config->SetBidsPerInterval(bidsPerInterval); + + break; + } + default: + break; } - if (debug_Out) sLog->outError( "End Settings for %s Auctionhouses:", WorldDatabase.PQuery("SELECT name FROM auctionhousebot WHERE auctionhouse = %u", config->GetAHID())->Fetch()->GetCString()); +} + +// ============================================================================= +// Initialization of the bot +// ============================================================================= + +void AuctionHouseBot::Initialize(AHBConfig* allianceConfig, AHBConfig* hordeConfig, AHBConfig* neutralConfig) +{ + // + // Save the pointer for the configurations + // + + _allianceConfig = allianceConfig; + _hordeConfig = hordeConfig; + _neutralConfig = neutralConfig; + + // + // Done + // + + LOG_INFO("module", "AHBot [{}]: initialization complete", uint32(_id)); } diff --git a/src/AuctionHouseBot.h b/src/AuctionHouseBot.h index 123cfc8a..0c379c92 100644 --- a/src/AuctionHouseBot.h +++ b/src/AuctionHouseBot.h @@ -21,1238 +21,59 @@ #define AUCTION_HOUSE_BOT_H #include "Common.h" +#include "ObjectGuid.h" +#include "AuctionHouseMgr.h" -struct AuctionEntry; -class Player; -class WorldSession; - -#include "ItemPrototype.h" -#define AHB_GREY 0 -#define AHB_WHITE 1 -#define AHB_GREEN 2 -#define AHB_BLUE 3 -#define AHB_PURPLE 4 -#define AHB_ORANGE 5 -#define AHB_YELLOW 6 -#define AHB_MAX_QUALITY 6 -#define AHB_GREY_TG 0 -#define AHB_WHITE_TG 1 -#define AHB_GREEN_TG 2 -#define AHB_BLUE_TG 3 -#define AHB_PURPLE_TG 4 -#define AHB_ORANGE_TG 5 -#define AHB_YELLOW_TG 6 -#define AHB_GREY_I 7 -#define AHB_WHITE_I 8 -#define AHB_GREEN_I 9 -#define AHB_BLUE_I 10 -#define AHB_PURPLE_I 11 -#define AHB_ORANGE_I 12 -#define AHB_YELLOW_I 13 - -class AHBConfig -{ -private: - uint32 AHID; - uint32 AHFID; - uint32 minItems; - uint32 maxItems; - uint32 percentGreyTradeGoods; - uint32 percentWhiteTradeGoods; - uint32 percentGreenTradeGoods; - uint32 percentBlueTradeGoods; - uint32 percentPurpleTradeGoods; - uint32 percentOrangeTradeGoods; - uint32 percentYellowTradeGoods; - uint32 percentGreyItems; - uint32 percentWhiteItems; - uint32 percentGreenItems; - uint32 percentBlueItems; - uint32 percentPurpleItems; - uint32 percentOrangeItems; - uint32 percentYellowItems; - uint32 minPriceGrey; - uint32 maxPriceGrey; - uint32 minBidPriceGrey; - uint32 maxBidPriceGrey; - uint32 maxStackGrey; - uint32 minPriceWhite; - uint32 maxPriceWhite; - uint32 minBidPriceWhite; - uint32 maxBidPriceWhite; - uint32 maxStackWhite; - uint32 minPriceGreen; - uint32 maxPriceGreen; - uint32 minBidPriceGreen; - uint32 maxBidPriceGreen; - uint32 maxStackGreen; - uint32 minPriceBlue; - uint32 maxPriceBlue; - uint32 minBidPriceBlue; - uint32 maxBidPriceBlue; - uint32 maxStackBlue; - uint32 minPricePurple; - uint32 maxPricePurple; - uint32 minBidPricePurple; - uint32 maxBidPricePurple; - uint32 maxStackPurple; - uint32 minPriceOrange; - uint32 maxPriceOrange; - uint32 minBidPriceOrange; - uint32 maxBidPriceOrange; - uint32 maxStackOrange; - uint32 minPriceYellow; - uint32 maxPriceYellow; - uint32 minBidPriceYellow; - uint32 maxBidPriceYellow; - uint32 maxStackYellow; - - uint32 buyerPriceGrey; - uint32 buyerPriceWhite; - uint32 buyerPriceGreen; - uint32 buyerPriceBlue; - uint32 buyerPricePurple; - uint32 buyerPriceOrange; - uint32 buyerPriceYellow; - uint32 buyerBiddingInterval; - uint32 buyerBidsPerInterval; - - uint32 greytgp; - uint32 whitetgp; - uint32 greentgp; - uint32 bluetgp; - uint32 purpletgp; - uint32 orangetgp; - uint32 yellowtgp; - uint32 greyip; - uint32 whiteip; - uint32 greenip; - uint32 blueip; - uint32 purpleip; - uint32 orangeip; - uint32 yellowip; - - uint32 greyTGoods; - uint32 whiteTGoods; - uint32 greenTGoods; - uint32 blueTGoods; - uint32 purpleTGoods; - uint32 orangeTGoods; - uint32 yellowTGoods; - - uint32 greyItems; - uint32 whiteItems; - uint32 greenItems; - uint32 blueItems; - uint32 purpleItems; - uint32 orangeItems; - uint32 yellowItems; - -public: - AHBConfig(uint32 ahid) - { - AHID = ahid; - switch(ahid) - { - case 2: - AHFID = 55; - break; - case 6: - AHFID = 29; - break; - case 7: - AHFID = 120; - break; - default: - AHFID = 120; - break; - } - } - AHBConfig() - { - } - uint32 GetAHID() - { - return AHID; - } - uint32 GetAHFID() - { - return AHFID; - } - void SetMinItems(uint32 value) - { - minItems = value; - } - uint32 GetMinItems() - { - if ((minItems == 0) && (maxItems)) - return maxItems; - else if ((maxItems) && (minItems > maxItems)) - return maxItems; - else - return minItems; - } - void SetMaxItems(uint32 value) - { - maxItems = value; - // CalculatePercents() needs to be called, but only if - // SetPercentages() has been called at least once already. - } - uint32 GetMaxItems() - { - return maxItems; - } - void SetPercentages(uint32 greytg, uint32 whitetg, uint32 greentg, uint32 bluetg, uint32 purpletg, uint32 orangetg, uint32 yellowtg, uint32 greyi, uint32 whitei, uint32 greeni, uint32 bluei, uint32 purplei, uint32 orangei, uint32 yellowi) - { - uint32 totalPercent = greytg + whitetg + greentg + bluetg + purpletg + orangetg + yellowtg + greyi + whitei + greeni + bluei + purplei + orangei + yellowi; - - if (totalPercent == 0) - { - maxItems = 0; - } - else if (totalPercent != 100) - { - greytg = 0; - whitetg = 27; - greentg = 12; - bluetg = 10; - purpletg = 1; - orangetg = 0; - yellowtg = 0; - greyi = 0; - whitei = 10; - greeni = 30; - bluei = 8; - purplei = 2; - orangei = 0; - yellowi = 0; - } - percentGreyTradeGoods = greytg; - percentWhiteTradeGoods = whitetg; - percentGreenTradeGoods = greentg; - percentBlueTradeGoods = bluetg; - percentPurpleTradeGoods = purpletg; - percentOrangeTradeGoods = orangetg; - percentYellowTradeGoods = yellowtg; - percentGreyItems = greyi; - percentWhiteItems = whitei; - percentGreenItems = greeni; - percentBlueItems = bluei; - percentPurpleItems = purplei; - percentOrangeItems = orangei; - percentYellowItems = yellowi; - CalculatePercents(); - } - uint32 GetPercentages(uint32 color) - { - switch(color) - { - case AHB_GREY_TG: - return percentGreyTradeGoods; - break; - case AHB_WHITE_TG: - return percentWhiteTradeGoods; - break; - case AHB_GREEN_TG: - return percentGreenTradeGoods; - break; - case AHB_BLUE_TG: - return percentBlueTradeGoods; - break; - case AHB_PURPLE_TG: - return percentPurpleTradeGoods; - break; - case AHB_ORANGE_TG: - return percentOrangeTradeGoods; - break; - case AHB_YELLOW_TG: - return percentYellowTradeGoods; - break; - case AHB_GREY_I: - return percentGreyItems; - break; - case AHB_WHITE_I: - return percentWhiteItems; - break; - case AHB_GREEN_I: - return percentGreenItems; - break; - case AHB_BLUE_I: - return percentBlueItems; - break; - case AHB_PURPLE_I: - return percentPurpleItems; - break; - case AHB_ORANGE_I: - return percentOrangeItems; - break; - case AHB_YELLOW_I: - return percentYellowItems; - break; - default: - return 0; - break; - } - } - void SetMinPrice(uint32 color, uint32 value) - { - switch(color) - { - case AHB_GREY: - minPriceGrey = value; - break; - case AHB_WHITE: - minPriceWhite = value; - break; - case AHB_GREEN: - minPriceGreen = value; - break; - case AHB_BLUE: - minPriceBlue = value; - break; - case AHB_PURPLE: - minPricePurple = value; - break; - case AHB_ORANGE: - minPriceOrange = value; - break; - case AHB_YELLOW: - minPriceYellow = value; - break; - default: - break; - } - } - uint32 GetMinPrice(uint32 color) - { - switch(color) - { - case AHB_GREY: - { - if (minPriceGrey == 0) - return 100; - else if (minPriceGrey > maxPriceGrey) - return maxPriceGrey; - else - return minPriceGrey; - break; - } - case AHB_WHITE: - { - if (minPriceWhite == 0) - return 150; - else if (minPriceWhite > maxPriceWhite) - return maxPriceWhite; - else - return minPriceWhite; - break; - } - case AHB_GREEN: - { - if (minPriceGreen == 0) - return 200; - else if (minPriceGreen > maxPriceGreen) - return maxPriceGreen; - else - return minPriceGreen; - break; - } - case AHB_BLUE: - { - if (minPriceBlue == 0) - return 250; - else if (minPriceBlue > maxPriceBlue) - return maxPriceBlue; - else - return minPriceBlue; - break; - } - case AHB_PURPLE: - { - if (minPricePurple == 0) - return 300; - else if (minPricePurple > maxPricePurple) - return maxPricePurple; - else - return minPricePurple; - break; - } - case AHB_ORANGE: - { - if (minPriceOrange == 0) - return 400; - else if (minPriceOrange > maxPriceOrange) - return maxPriceOrange; - else - return minPriceOrange; - break; - } - case AHB_YELLOW: - { - if (minPriceYellow == 0) - return 500; - else if (minPriceYellow > maxPriceYellow) - return maxPriceYellow; - else - return minPriceYellow; - break; - } - default: - { - return 0; - break; - } - } - } - void SetMaxPrice(uint32 color, uint32 value) - { - switch(color) - { - case AHB_GREY: - maxPriceGrey = value; - break; - case AHB_WHITE: - maxPriceWhite = value; - break; - case AHB_GREEN: - maxPriceGreen = value; - break; - case AHB_BLUE: - maxPriceBlue = value; - break; - case AHB_PURPLE: - maxPricePurple = value; - break; - case AHB_ORANGE: - maxPriceOrange = value; - break; - case AHB_YELLOW: - maxPriceYellow = value; - break; - default: - break; - } - } - uint32 GetMaxPrice(uint32 color) - { - switch(color) - { - case AHB_GREY: - { - if (maxPriceGrey == 0) - return 150; - else - return maxPriceGrey; - break; - } - case AHB_WHITE: - { - if (maxPriceWhite == 0) - return 250; - else - return maxPriceWhite; - break; - } - case AHB_GREEN: - { - if (maxPriceGreen == 0) - return 300; - else - return maxPriceGreen; - break; - } - case AHB_BLUE: - { - if (maxPriceBlue == 0) - return 350; - else - return maxPriceBlue; - break; - } - case AHB_PURPLE: - { - if (maxPricePurple == 0) - return 450; - else - return maxPricePurple; - break; - } - case AHB_ORANGE: - { - if (maxPriceOrange == 0) - return 550; - else - return maxPriceOrange; - break; - } - case AHB_YELLOW: - { - if (maxPriceYellow == 0) - return 650; - else - return maxPriceYellow; - break; - } - default: - { - return 0; - break; - } - } - } - void SetMinBidPrice(uint32 color, uint32 value) - { - switch(color) - { - case AHB_GREY: - minBidPriceGrey = value; - break; - case AHB_WHITE: - minBidPriceWhite = value; - break; - case AHB_GREEN: - minBidPriceGreen = value; - break; - case AHB_BLUE: - minBidPriceBlue = value; - break; - case AHB_PURPLE: - minBidPricePurple = value; - break; - case AHB_ORANGE: - minBidPriceOrange = value; - break; - case AHB_YELLOW: - minBidPriceYellow = value; - break; - default: - break; - } - } - uint32 GetMinBidPrice(uint32 color) - { - switch(color) - { - case AHB_GREY: - { - if (minBidPriceGrey > 100) - return 100; - else - return minBidPriceGrey; - break; - } - case AHB_WHITE: - { - if (minBidPriceWhite > 100) - return 100; - else - return minBidPriceWhite; - break; - } - case AHB_GREEN: - { - if (minBidPriceGreen > 100) - return 100; - else - return minBidPriceGreen; - break; - } - case AHB_BLUE: - { - if (minBidPriceBlue > 100) - return 100; - else - return minBidPriceBlue; - break; - } - case AHB_PURPLE: - { - if (minBidPricePurple > 100) - return 100; - else - return minBidPricePurple; - break; - } - case AHB_ORANGE: - { - if (minBidPriceOrange > 100) - return 100; - else - return minBidPriceOrange; - break; - } - case AHB_YELLOW: - { - if (minBidPriceYellow > 100) - return 100; - else - return minBidPriceYellow; - break; - } - default: - { - return 0; - break; - } - } - } - void SetMaxBidPrice(uint32 color, uint32 value) - { - switch(color) - { - case AHB_GREY: - maxBidPriceGrey = value; - break; - case AHB_WHITE: - maxBidPriceWhite = value; - break; - case AHB_GREEN: - maxBidPriceGreen = value; - break; - case AHB_BLUE: - maxBidPriceBlue = value; - break; - case AHB_PURPLE: - maxBidPricePurple = value; - break; - case AHB_ORANGE: - maxBidPriceOrange = value; - break; - case AHB_YELLOW: - maxBidPriceYellow = value; - break; - default: - break; - } - } - uint32 GetMaxBidPrice(uint32 color) - { - switch(color) - { - case AHB_GREY: - { - if (maxBidPriceGrey > 100) - return 100; - else - return maxBidPriceGrey; - break; - } - case AHB_WHITE: - { - if (maxBidPriceWhite > 100) - return 100; - else - return maxBidPriceWhite; - break; - } - case AHB_GREEN: - { - if (maxBidPriceGreen > 100) - return 100; - else - return maxBidPriceGreen; - break; - } - case AHB_BLUE: - { - if (maxBidPriceBlue > 100) - return 100; - else - return maxBidPriceBlue; - break; - } - case AHB_PURPLE: - { - if (maxBidPricePurple > 100) - return 100; - else - return maxBidPricePurple; - break; - } - case AHB_ORANGE: - { - if (maxBidPriceOrange > 100) - return 100; - else - return maxBidPriceOrange; - break; - } - case AHB_YELLOW: - { - if (maxBidPriceYellow > 100) - return 100; - else - return maxBidPriceYellow; - break; - } - default: - { - return 0; - break; - } - } - } - void SetMaxStack(uint32 color, uint32 value) - { - switch(color) - { - case AHB_GREY: - maxStackGrey = value; - break; - case AHB_WHITE: - maxStackWhite = value; - break; - case AHB_GREEN: - maxStackGreen = value; - break; - case AHB_BLUE: - maxStackBlue = value; - break; - case AHB_PURPLE: - maxStackPurple = value; - break; - case AHB_ORANGE: - maxStackOrange = value; - break; - case AHB_YELLOW: - maxStackYellow = value; - break; - default: - break; - } - } - uint32 GetMaxStack(uint32 color) - { - switch(color) - { - case AHB_GREY: - { - return maxStackGrey; - break; - } - case AHB_WHITE: - { - return maxStackWhite; - break; - } - case AHB_GREEN: - { - return maxStackGreen; - break; - } - case AHB_BLUE: - { - return maxStackBlue; - break; - } - case AHB_PURPLE: - { - return maxStackPurple; - break; - } - case AHB_ORANGE: - { - return maxStackOrange; - break; - } - case AHB_YELLOW: - { - return maxStackYellow; - break; - } - default: - { - return 0; - break; - } - } - } - void SetBuyerPrice(uint32 color, uint32 value) - { - switch(color) - { - case AHB_GREY: - buyerPriceGrey = value; - break; - case AHB_WHITE: - buyerPriceWhite = value; - break; - case AHB_GREEN: - buyerPriceGreen = value; - break; - case AHB_BLUE: - buyerPriceBlue = value; - break; - case AHB_PURPLE: - buyerPricePurple = value; - break; - case AHB_ORANGE: - buyerPriceOrange = value; - break; - case AHB_YELLOW: - buyerPriceYellow = value; - break; - default: - break; - } - } - uint32 GetBuyerPrice(uint32 color) - { - switch(color) - { - case AHB_GREY: - return buyerPriceGrey; - break; - case AHB_WHITE: - return buyerPriceWhite; - break; - case AHB_GREEN: - return buyerPriceGreen; - break; - case AHB_BLUE: - return buyerPriceBlue; - break; - case AHB_PURPLE: - return buyerPricePurple; - break; - case AHB_ORANGE: - return buyerPriceOrange; - break; - case AHB_YELLOW: - return buyerPriceYellow; - break; - default: - return 0; - break; - } - } - void SetBiddingInterval(uint32 value) - { - buyerBiddingInterval = value; - } - uint32 GetBiddingInterval() - { - return buyerBiddingInterval; - } - void CalculatePercents() - { - greytgp = (uint32) (((double)percentGreyTradeGoods / 100.0) * maxItems); - whitetgp = (uint32) (((double)percentWhiteTradeGoods / 100.0) * maxItems); - greentgp = (uint32) (((double)percentGreenTradeGoods / 100.0) * maxItems); - bluetgp = (uint32) (((double)percentBlueTradeGoods / 100.0) * maxItems); - purpletgp = (uint32) (((double)percentPurpleTradeGoods / 100.0) * maxItems); - orangetgp = (uint32) (((double)percentOrangeTradeGoods / 100.0) * maxItems); - yellowtgp = (uint32) (((double)percentYellowTradeGoods / 100.0) * maxItems); - greyip = (uint32) (((double)percentGreyItems / 100.0) * maxItems); - whiteip = (uint32) (((double)percentWhiteItems / 100.0) * maxItems); - greenip = (uint32) (((double)percentGreenItems / 100.0) * maxItems); - blueip = (uint32) (((double)percentBlueItems / 100.0) * maxItems); - purpleip = (uint32) (((double)percentPurpleItems / 100.0) * maxItems); - orangeip = (uint32) (((double)percentOrangeItems / 100.0) * maxItems); - yellowip = (uint32) (((double)percentYellowItems / 100.0) * maxItems); - uint32 total = greytgp + whitetgp + greentgp + bluetgp + purpletgp + orangetgp + yellowtgp + greyip + whiteip + greenip + blueip + purpleip + orangeip + yellowip; - int32 diff = (maxItems - total); - if (diff < 0) - { - if ((whiteip - diff) > 0) - whiteip -= diff; - else if ((greenip - diff) > 0) - greenip -= diff; - } - else if (diff < 0) - { - whiteip += diff; - } - } - uint32 GetPercents(uint32 color) - { - switch(color) - { - case AHB_GREY_TG: - return greytgp; - break; - case AHB_WHITE_TG: - return whitetgp; - break; - case AHB_GREEN_TG: - return greentgp; - break; - case AHB_BLUE_TG: - return bluetgp; - break; - case AHB_PURPLE_TG: - return purpletgp; - break; - case AHB_ORANGE_TG: - return orangetgp; - break; - case AHB_YELLOW_TG: - return yellowtgp; - break; - case AHB_GREY_I: - return greyip; - break; - case AHB_WHITE_I: - return whiteip; - break; - case AHB_GREEN_I: - return greenip; - break; - case AHB_BLUE_I: - return blueip; - break; - case AHB_PURPLE_I: - return purpleip; - break; - case AHB_ORANGE_I: - return orangeip; - break; - case AHB_YELLOW_I: - return yellowip; - break; - default: - return 0; - break; - } - } - - void DecItemCounts(uint32 Class, uint32 Quality) - { - switch(Class) - { - case ITEM_CLASS_TRADE_GOODS: - DecItemCounts(Quality); - break; - default: - DecItemCounts(Quality + 7); - break; - } - } - - void DecItemCounts(uint32 color) - { - switch(color) - { - case AHB_GREY_TG: - --greyTGoods; - break; - case AHB_WHITE_TG: - --whiteTGoods; - break; - case AHB_GREEN_TG: - --greenTGoods; - break; - case AHB_BLUE_TG: - --blueTGoods; - break; - case AHB_PURPLE_TG: - --purpleTGoods; - break; - case AHB_ORANGE_TG: - --orangeTGoods; - break; - case AHB_YELLOW_TG: - --yellowTGoods; - break; - case AHB_GREY_I: - --greyItems; - break; - case AHB_WHITE_I: - --whiteItems; - break; - case AHB_GREEN_I: - --greenItems; - break; - case AHB_BLUE_I: - --blueItems; - break; - case AHB_PURPLE_I: - --purpleItems; - break; - case AHB_ORANGE_I: - --orangeItems; - break; - case AHB_YELLOW_I: - --yellowItems; - break; - default: - break; - } - } - - void IncItemCounts(uint32 Class, uint32 Quality) - { - switch(Class) - { - case ITEM_CLASS_TRADE_GOODS: - IncItemCounts(Quality); - break; - default: - IncItemCounts(Quality + 7); - break; - } - } - - void IncItemCounts(uint32 color) - { - switch(color) - { - case AHB_GREY_TG: - ++greyTGoods; - break; - case AHB_WHITE_TG: - ++whiteTGoods; - break; - case AHB_GREEN_TG: - ++greenTGoods; - break; - case AHB_BLUE_TG: - ++blueTGoods; - break; - case AHB_PURPLE_TG: - ++purpleTGoods; - break; - case AHB_ORANGE_TG: - ++orangeTGoods; - break; - case AHB_YELLOW_TG: - ++yellowTGoods; - break; - case AHB_GREY_I: - ++greyItems; - break; - case AHB_WHITE_I: - ++whiteItems; - break; - case AHB_GREEN_I: - ++greenItems; - break; - case AHB_BLUE_I: - ++blueItems; - break; - case AHB_PURPLE_I: - ++purpleItems; - break; - case AHB_ORANGE_I: - ++orangeItems; - break; - case AHB_YELLOW_I: - ++yellowItems; - break; - default: - break; - } - } - - void ResetItemCounts() - { - greyTGoods = 0; - whiteTGoods = 0; - greenTGoods = 0; - blueTGoods = 0; - purpleTGoods = 0; - orangeTGoods = 0; - yellowTGoods = 0; +#include "AuctionHouseBotCommon.h" +#include "AuctionHouseBotConfig.h" - greyItems = 0; - whiteItems = 0; - greenItems = 0; - blueItems = 0; - purpleItems = 0; - orangeItems = 0; - yellowItems = 0; - } - - uint32 TotalItemCounts() - { - return( - greyTGoods + - whiteTGoods + - greenTGoods + - blueTGoods + - purpleTGoods + - orangeTGoods + - yellowTGoods + +struct AuctionEntry; +class Player; +class WorldSession; - greyItems + - whiteItems + - greenItems + - blueItems + - purpleItems + - orangeItems + - yellowItems); - } +#define AUCTION_HOUSE_BOT_LOOP_BREAKER 32 - uint32 GetItemCounts(uint32 color) - { - switch(color) - { - case AHB_GREY_TG: - return greyTGoods; - break; - case AHB_WHITE_TG: - return whiteTGoods; - break; - case AHB_GREEN_TG: - return greenTGoods; - break; - case AHB_BLUE_TG: - return blueTGoods; - break; - case AHB_PURPLE_TG: - return purpleTGoods; - break; - case AHB_ORANGE_TG: - return orangeTGoods; - break; - case AHB_YELLOW_TG: - return yellowTGoods; - break; - case AHB_GREY_I: - return greyItems; - break; - case AHB_WHITE_I: - return whiteItems; - break; - case AHB_GREEN_I: - return greenItems; - break; - case AHB_BLUE_I: - return blueItems; - break; - case AHB_PURPLE_I: - return purpleItems; - break; - case AHB_ORANGE_I: - return orangeItems; - break; - case AHB_YELLOW_I: - return yellowItems; - break; - default: - return 0; - break; - } - } - void SetBidsPerInterval(uint32 value) - { - buyerBidsPerInterval = value; - } - uint32 GetBidsPerInterval() - { - return buyerBidsPerInterval; - } - ~AHBConfig() - { - } -}; class AuctionHouseBot { private: + uint32 _account; + uint32 _id; - bool debug_Out; - bool debug_Out_Filters; - - bool AHBSeller; - bool AHBBuyer; - bool BuyMethod; - bool SellMethod; - - uint32 AHBplayerAccount; - uint32 AHBplayerGUID; - uint32 ItemsPerCycle; - - //Begin Filters - - bool Vendor_Items; - bool Loot_Items; - bool Other_Items; - bool Vendor_TGs; - bool Loot_TGs; - bool Other_TGs; - - bool No_Bind; - bool Bind_When_Picked_Up; - bool Bind_When_Equipped; - bool Bind_When_Use; - bool Bind_Quest_Item; - - bool DisablePermEnchant; - bool DisableConjured; - bool DisableGems; - bool DisableMoney; - bool DisableMoneyLoot; - bool DisableLootable; - bool DisableKeys; - bool DisableDuration; - bool DisableBOP_Or_Quest_NoReqLevel; + AHBConfig* _allianceConfig; + AHBConfig* _hordeConfig; + AHBConfig* _neutralConfig; - bool DisableWarriorItems; - bool DisablePaladinItems; - bool DisableHunterItems; - bool DisableRogueItems; - bool DisablePriestItems; - bool DisableDKItems; - bool DisableShamanItems; - bool DisableMageItems; - bool DisableWarlockItems; - bool DisableUnusedClassItems; - bool DisableDruidItems; + time_t _lastrun_a_sec; + time_t _lastrun_h_sec; + time_t _lastrun_n_sec; - uint32 DisableItemsBelowLevel; - uint32 DisableItemsAboveLevel; - uint32 DisableTGsBelowLevel; - uint32 DisableTGsAboveLevel; - uint32 DisableItemsBelowGUID; - uint32 DisableItemsAboveGUID; - uint32 DisableTGsBelowGUID; - uint32 DisableTGsAboveGUID; - uint32 DisableItemsBelowReqLevel; - uint32 DisableItemsAboveReqLevel; - uint32 DisableTGsBelowReqLevel; - uint32 DisableTGsAboveReqLevel; - uint32 DisableItemsBelowReqSkillRank; - uint32 DisableItemsAboveReqSkillRank; - uint32 DisableTGsBelowReqSkillRank; - uint32 DisableTGsAboveReqSkillRank; + // + // Main operations + // + void Sell(Player *AHBplayer, AHBConfig *config); + void Buy (Player *AHBplayer, AHBConfig *config, WorldSession *session); - std::set DisableItemStore; - - //End Filters - - AHBConfig AllianceConfig; - AHBConfig HordeConfig; - AHBConfig NeutralConfig; - - time_t _lastrun_a; - time_t _lastrun_h; - time_t _lastrun_n; + // + // Utilities + // inline uint32 minValue(uint32 a, uint32 b) { return a <= b ? a : b; }; - void addNewAuctions(Player *AHBplayer, AHBConfig *config); - void addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *config, WorldSession *session); -// friend class ACE_Singleton; - AuctionHouseBot(); + uint32 getNofAuctions(AHBConfig* config, AuctionHouseObject* auctionHouse, ObjectGuid guid); + uint32 getStackCount(AHBConfig* config, uint32 max); + uint32 getElapsedTime(uint32 timeClass); + uint32 getElement(std::set set, int index, uint32 botId, uint32 maxDup, AuctionHouseObject* auctionHouse); public: - static AuctionHouseBot* instance() - { - static AuctionHouseBot instance; - return &instance; - } - + AuctionHouseBot(uint32 account, uint32 id); ~AuctionHouseBot(); + + void Initialize(AHBConfig* allianceConfig, AHBConfig* hordeConfig, AHBConfig* neutralConfig); void Update(); - void Initialize(); - void InitializeConfiguration(); - void LoadValues(AHBConfig*); - void DecrementItemCounts(AuctionEntry* ah, uint32 itemEntry); - void IncrementItemCounts(AuctionEntry* ah); - void Commands(uint32, uint32, uint32, char*); - uint32 GetAHBplayerGUID() { return AHBplayerGUID; }; -}; -#define auctionbot AuctionHouseBot::instance() + void Commands(AHBotCommand command, uint32 ahMapID, uint32 col, char* args); + + ObjectGuid::LowType GetAHBplayerGUID() { return _id; }; +}; -#endif +#endif // AUCTION_HOUSE_BOT_H diff --git a/src/AuctionHouseBotAuctionHouseScript.cpp b/src/AuctionHouseBotAuctionHouseScript.cpp new file mode 100644 index 00000000..08afbb53 --- /dev/null +++ b/src/AuctionHouseBotAuctionHouseScript.cpp @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE + */ + +#include "AuctionHouseMgr.h" +#include "GameTime.h" + +#include "AuctionHouseBot.h" +#include "AuctionHouseBotCommon.h" +#include "AuctionHouseBotAuctionHouseScript.h" + +AHBot_AuctionHouseScript::AHBot_AuctionHouseScript() : AuctionHouseScript("AHBot_AuctionHouseScript", { + AUCTIONHOUSEHOOK_ON_BEFORE_AUCTIONHOUSEMGR_SEND_AUCTION_SUCCESSFUL_MAIL, + AUCTIONHOUSEHOOK_ON_BEFORE_AUCTIONHOUSEMGR_SEND_AUCTION_EXPIRED_MAIL, + AUCTIONHOUSEHOOK_ON_BEFORE_AUCTIONHOUSEMGR_SEND_AUCTION_OUTBIDDED_MAIL, + AUCTIONHOUSEHOOK_ON_AUCTION_ADD, + AUCTIONHOUSEHOOK_ON_AUCTION_REMOVE, + AUCTIONHOUSEHOOK_ON_AUCTION_SUCCESSFUL, + AUCTIONHOUSEHOOK_ON_AUCTION_EXPIRE, + AUCTIONHOUSEHOOK_ON_BEFORE_AUCTIONHOUSEMGR_UPDATE +}) +{ + +} + +void AHBot_AuctionHouseScript::OnBeforeAuctionHouseMgrSendAuctionSuccessfulMail( + AuctionHouseMgr*, /*auctionHouseMgr*/ + AuctionEntry*, /*auction*/ + Player* owner, + uint32&, /*owner_accId*/ + uint32&, /*profit*/ + bool& sendNotification, + bool& updateAchievementCriteria, + bool& /*sendMail*/) +{ + if (owner && gBotsId.find(owner->GetGUID().GetCounter()) != gBotsId.end()) + { + sendNotification = false; + updateAchievementCriteria = false; + } +} + +void AHBot_AuctionHouseScript::OnBeforeAuctionHouseMgrSendAuctionExpiredMail( + AuctionHouseMgr*, /* auctionHouseMgr */ + AuctionEntry*, /* auction */ + Player* owner, + uint32&, /* owner_accId */ + bool& sendNotification, + bool& /* sendMail */) +{ + if (owner && gBotsId.find(owner->GetGUID().GetCounter()) != gBotsId.end()) + { + sendNotification = false; + } +} + +void AHBot_AuctionHouseScript::OnBeforeAuctionHouseMgrSendAuctionOutbiddedMail( + AuctionHouseMgr*, /* auctionHouseMgr */ + AuctionEntry* auction, + Player* oldBidder, + uint32&, /* oldBidder_accId */ + Player* newBidder, + uint32& newPrice, + bool&, /* sendNotification */ + bool& /* sendMail */) +{ + if (oldBidder && !newBidder) + { + if (gBotsId.size() > 0) + { + // + // Use a random bot id + // + + uint32 randBot = urand(0, gBotsId.size() - 1); + std::set::iterator it = gBotsId.begin(); + std::advance(it, randBot); + + oldBidder->GetSession()->SendAuctionBidderNotification( + (uint32)auction->GetHouseId(), + auction->Id, + ObjectGuid::Create(*it), + newPrice, + auction->GetAuctionOutBid(), + auction->item_template); + } + } +} + +void AHBot_AuctionHouseScript::OnAuctionAdd(AuctionHouseObject* /*ah*/, AuctionEntry* auction) +{ + // + // The the configuration for the auction house + // + + AuctionHouseEntry const* ahEntry = sAuctionMgr->GetAuctionHouseEntryFromHouse(auction->GetHouseId()); + AHBConfig* config = gNeutralConfig; + + if (ahEntry) + { + if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Alliance) + { + config = gAllianceConfig; + } + else if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Horde) + { + config = gHordeConfig; + } + } + + // + // Consider only those auctions handled by the bots + // + + if (config->ConsiderOnlyBotAuctions) + { + if (gBotsId.find(auction->owner.GetCounter()) != gBotsId.end()) + { + return; + } + } + + // + // Verify if we can operate on the item + // + + Item* pItem = sAuctionMgr->GetAItem(auction->item_guid); + + if (!pItem) + { + if (config->DebugOut) + { + LOG_ERROR("module", "AHBot: Item {} for entryiD={} doesn't exist, perhaps bought already?", auction->item_guid.ToString(), auction->Id); + } + + return; + } + + // + // Keeps updated the amount of items in the auction + // + + ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(auction->item_template); + + config->IncItemCounts(prototype->Class, prototype->Quality); + + if (config->DebugOut) + { + LOG_INFO("module", "AHBot: Auction Added ah={}, auctionId={}, totalAHItems = {}", AuctionHouseId(ahEntry->houseId), auction->Id, config->TotalItemCounts()); + } +} + +// this is called after the auction has been removed from the DB +void AHBot_AuctionHouseScript::OnAuctionRemove(AuctionHouseObject* /*ah*/, AuctionEntry* auction) +{ + // + // Get the configuration for the auction house + // + AuctionHouseEntry const* ahEntry = sAuctionMgr->GetAuctionHouseEntryFromHouse(auction->GetHouseId()); + AHBConfig* config = gNeutralConfig; + + if (ahEntry) + { + if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Alliance) + { + config = gAllianceConfig; + } + else if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Horde) + { + config = gHordeConfig; + } + } + + // Consider only those auctions handled by the bots + if (config->ConsiderOnlyBotAuctions) + { + if (gBotsId.find(auction->owner.GetCounter()) != gBotsId.end()) + { + return; + } + } + + // only get the prototype as actual item has already been removed from server AH in this callback + ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(auction->item_template); + + if (prototype) + { + config->DecItemCounts(prototype->Class, prototype->Quality); + if (config->DebugOut) + { + LOG_INFO("module", "AHBot: Auction removed ah={}, auctionId={}, Bot totalAHItems={}", AuctionHouseId(ahEntry->houseId), auction->Id, config->TotalItemCounts()); + } + } + else + { + // should never happen + if (config->DebugOut) + { + LOG_ERROR("module", "AHBot: Item was removed but no prototype was found"); + } + } +} + +void AHBot_AuctionHouseScript::OnAuctionSuccessful(AuctionHouseObject* /*ah*/, AuctionEntry* auction) +{ + // + // Get the configuration for the auction house + // + + AuctionHouseEntry const* ahEntry = sAuctionMgr->GetAuctionHouseEntryFromHouse(auction->GetHouseId()); + AHBConfig* config = gNeutralConfig; + + if (ahEntry) + { + if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Alliance) + { + config = gAllianceConfig; + } + else if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Horde) + { + config = gHordeConfig; + } + } + + // + // If the auction has been won, it means that it has been accepted by the market. + // Use the buyout as a reference since the price for the bid is downgraded during selling. + // + + if (config->DebugOut) + { + LOG_INFO("module", "AHBot: Auction successful ah={}, auctionId={}, Bot totalAHItems={}", AuctionHouseId(ahEntry->houseId), auction->Id, config->TotalItemCounts()); + } + + config->UpdateItemStats(auction->item_template, auction->itemCount, auction->buyout); + +} + +void AHBot_AuctionHouseScript::OnAuctionExpire(AuctionHouseObject* /*ah*/, AuctionEntry* auction) +{ + // + // Get the configuration for the auction house + // + + if (!auction) + { + LOG_ERROR("module", "AHBot: AHBot_AuctionHouseScript::OnAuctionExpire invalid AuctionEntry"); + } + + AuctionHouseEntry const* ahEntry = sAuctionMgr->GetAuctionHouseEntryFromHouse(auction->GetHouseId()); + AHBConfig* config = gNeutralConfig; + + if (ahEntry) + { + if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Alliance) + { + config = gAllianceConfig; + } + else if (AuctionHouseId(ahEntry->houseId) == AuctionHouseId::Horde) + { + config = gHordeConfig; + } + } + + // + // If the auction expired, then it means that the bid was unwanted by the market. + // Bid price is usually less or equal to the buyout, so this likely will bring the price down. + // + + config->UpdateItemStats(auction->item_template, auction->itemCount, auction->bid); + + if (config->DebugOut) + { + LOG_INFO("module", "AHBot: Auction Expired ah={}, auctionId={} Bot totalAHItems={}", AuctionHouseId(ahEntry->houseId), auction->Id, config->TotalItemCounts()); + } +} + +void AHBot_AuctionHouseScript::OnBeforeAuctionHouseMgrUpdate() +{ + // + // For every registered bot, perform an update + // + + for (AuctionHouseBot* bot: gBots) + { + bot->Update(); + } +} diff --git a/src/AuctionHouseBotAuctionHouseScript.h b/src/AuctionHouseBotAuctionHouseScript.h new file mode 100644 index 00000000..1ff5468e --- /dev/null +++ b/src/AuctionHouseBotAuctionHouseScript.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE + */ + +#ifndef AUCTION_HOUSE_BOT_AUCTION_HOUSE_SCRIPT_H +#define AUCTION_HOUSE_BOT_AUCTION_HOUSE_SCRIPT_H + +#include "Player.h" +#include "ScriptMgr.h" + +// ============================================================================= +// Interaction with the auction house core mechanisms +// ============================================================================= + +class AHBot_AuctionHouseScript : public AuctionHouseScript +{ +public: + AHBot_AuctionHouseScript(); + + void OnBeforeAuctionHouseMgrSendAuctionSuccessfulMail(AuctionHouseMgr* auctionHouseMgr, AuctionEntry* auction, Player* owner, uint32& owner_accId, uint32& profit, bool& sendNotification, bool& updateAchievementCriteria, bool& sendMail) override; + void OnBeforeAuctionHouseMgrSendAuctionExpiredMail (AuctionHouseMgr* auctionHouseMgr, AuctionEntry* auction, Player* owner, uint32& owner_accId, bool& sendNotification, bool& sendMail) override; + void OnBeforeAuctionHouseMgrSendAuctionOutbiddedMail (AuctionHouseMgr* auctionHouseMgr, AuctionEntry* auction, Player* oldBidder, uint32& oldBidder_accId, Player* newBidder, uint32& newPrice, bool& sendNotification, bool& sendMail) override; + + void OnAuctionAdd (AuctionHouseObject* ah, AuctionEntry* auction) override; + void OnAuctionRemove (AuctionHouseObject* ah, AuctionEntry* auction) override; + void OnAuctionSuccessful(AuctionHouseObject* ah, AuctionEntry* auction) override; + void OnAuctionExpire (AuctionHouseObject* ah, AuctionEntry* auction) override; + + void OnBeforeAuctionHouseMgrUpdate() override; +}; + +#endif /* AUCTION_HOUSE_BOT_AUCTION_HOUSE_SCRIPT_H */ diff --git a/src/AuctionHouseBotCommon.cpp b/src/AuctionHouseBotCommon.cpp new file mode 100644 index 00000000..640c7753 --- /dev/null +++ b/src/AuctionHouseBotCommon.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE + */ + +#include "AuctionHouseBot.h" +#include "AuctionHouseBotCommon.h" +#include "AuctionHouseBotConfig.h" + +// +// Configuration used globally by all the bots instances +// + +AHBConfig* gAllianceConfig = new AHBConfig(2); +AHBConfig* gHordeConfig = new AHBConfig(6); +AHBConfig* gNeutralConfig = new AHBConfig(7); + +// +// Active bots +// + +std::set gBotsId; +std::set gBots; diff --git a/src/AuctionHouseBotCommon.h b/src/AuctionHouseBotCommon.h new file mode 100644 index 00000000..26b477cc --- /dev/null +++ b/src/AuctionHouseBotCommon.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2008-2010 Trinity + * Copyright (C) 2005-2009 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 + */ + +#ifndef AUCTION_HOUSE_BOT_COMMON_H +#define AUCTION_HOUSE_BOT_COMMON_H + +#include + +#include "Common.h" + +class AuctionHouseBot; + +// +// Item quality +// + +#define AHB_GREY ITEM_QUALITY_POOR +#define AHB_WHITE ITEM_QUALITY_NORMAL +#define AHB_GREEN ITEM_QUALITY_UNCOMMON +#define AHB_BLUE ITEM_QUALITY_RARE +#define AHB_PURPLE ITEM_QUALITY_EPIC +#define AHB_ORANGE ITEM_QUALITY_LEGENDARY +#define AHB_YELLOW ITEM_QUALITY_ARTIFACT +#define AHB_MAX_QUALITY ITEM_QUALITY_ARTIFACT + +#define AHB_CLASS_WARRIOR 1 +#define AHB_CLASS_PALADIN 2 +#define AHB_CLASS_HUNTER 4 +#define AHB_CLASS_ROGUE 8 +#define AHB_CLASS_PRIEST 16 +#define AHB_CLASS_DK 32 +#define AHB_CLASS_SHAMAN 64 +#define AHB_CLASS_MAGE 128 +#define AHB_CLASS_WARLOCK 256 +#define AHB_CLASS_UNUSED 512 +#define AHB_CLASS_DRUID 1024 + +// +// Items classification +// + +#define AHB_GREY_TG 0 +#define AHB_WHITE_TG 1 +#define AHB_GREEN_TG 2 +#define AHB_BLUE_TG 3 +#define AHB_PURPLE_TG 4 +#define AHB_ORANGE_TG 5 +#define AHB_YELLOW_TG 6 + +#define AHB_GREY_I 7 +#define AHB_WHITE_I 8 +#define AHB_GREEN_I 9 +#define AHB_BLUE_I 10 +#define AHB_PURPLE_I 11 +#define AHB_ORANGE_I 12 +#define AHB_YELLOW_I 13 + +#define AHB_ITEM_TYPE_OFFSET 7 + +// +// Chat GM commands +// + +enum class AHBotCommand : uint32 +{ + buyer, + seller, + useMarketPrice, + + ahexpire, + minitems, + maxitems, + percentages, + minprice, + maxprice, + minbidprice, + maxbidprice, + maxstack, + buyerprice, + bidinterval, + bidsperinterval +}; + +// +// Globals +// + +extern std::set gBotsId; // Active bots players ids +extern std::set gBots; // Active bots + +#endif // AUCTION_HOUSE_BOT_COMMON_H diff --git a/src/AuctionHouseBotConfig.cpp b/src/AuctionHouseBotConfig.cpp new file mode 100644 index 00000000..b47b07a5 --- /dev/null +++ b/src/AuctionHouseBotConfig.cpp @@ -0,0 +1,3460 @@ +/* + * Copyright (C) 2008-2010 Trinity + * Copyright (C) 2005-2009 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 + */ + +#include "AuctionHouseMgr.h" +#include "Common.h" +#include "Config.h" +#include "DatabaseEnv.h" +#include "Item.h" +#include "ItemTemplate.h" +#include "Log.h" +#include "ObjectMgr.h" +#include "QueryResult.h" +#include "WorldSession.h" + +#include "AuctionHouseBotCommon.h" +#include "AuctionHouseBotConfig.h" + +using namespace std; + +AHBConfig::AHBConfig() +{ + Reset(); +} + +AHBConfig::AHBConfig(uint32 ahid) +{ + Reset(); + + AHID = ahid; + + switch (ahid) + { + case 2: + AHFID = 55; // Alliance + break; + + case 6: + AHFID = 29; // Horde + break; + + case 7: + AHFID = 120; // Neutral + break; + + default: + AHFID = 120; // Neutral + break; + } +} + +AHBConfig::AHBConfig(uint32 ahid, AHBConfig* conf) +{ + Reset(); + + // + // Ids + // + + AHID = ahid; + + switch (ahid) + { + case 2: + AHFID = 55; // Alliance + break; + + case 6: + AHFID = 29; // Horde + break; + + case 7: + AHFID = 120; // Neutral + break; + + default: + AHFID = 120; // Neutral + break; + } + + // + // Copy the private values + // + + minItems = conf->minItems; + maxItems = conf->maxItems; + percentGreyTradeGoods = conf->percentGreyTradeGoods; + percentWhiteTradeGoods = conf->percentWhiteTradeGoods; + percentGreenTradeGoods = conf->percentGreenTradeGoods; + percentBlueTradeGoods = conf->percentBlueTradeGoods; + percentPurpleTradeGoods = conf->percentPurpleTradeGoods; + percentOrangeTradeGoods = conf->percentOrangeTradeGoods; + percentYellowTradeGoods = conf->percentYellowTradeGoods; + percentGreyItems = conf->percentGreyItems; + percentWhiteItems = conf->percentWhiteItems; + percentGreenItems = conf->percentGreenItems; + percentBlueItems = conf->percentBlueItems; + percentPurpleItems = conf->percentPurpleItems; + percentOrangeItems = conf->percentOrangeItems; + percentYellowItems = conf->percentYellowItems; + minPriceGrey = conf->minPriceGrey; + maxPriceGrey = conf->maxPriceGrey; + minBidPriceGrey = conf->minBidPriceGrey; + maxBidPriceGrey = conf->maxBidPriceGrey; + maxStackGrey = conf->maxStackGrey; + maxPriceWhite = conf->maxPriceWhite; + minBidPriceWhite = conf->minBidPriceWhite; + maxBidPriceWhite = conf->maxBidPriceWhite; + maxStackWhite = conf->maxStackWhite; + minPriceGreen = conf->minPriceGreen; + maxPriceGreen = conf->maxPriceGreen; + minBidPriceGreen = conf->minBidPriceGreen; + maxBidPriceGreen = conf->maxBidPriceGreen; + maxStackGreen = conf->maxStackGreen; + minPriceBlue = conf->minPriceBlue; + maxPriceBlue = conf->maxPriceBlue; + minBidPriceBlue = conf->minBidPriceBlue; + maxBidPriceBlue = conf->maxBidPriceBlue; + maxStackBlue = conf->maxStackBlue; + minPricePurple = conf->minPricePurple; + maxPricePurple = conf->maxPricePurple; + minBidPricePurple = conf->minBidPricePurple; + maxBidPricePurple = conf->maxBidPricePurple; + maxStackPurple = conf->maxStackPurple; + minPriceOrange = conf->minPriceOrange; + maxPriceOrange = conf->maxPriceOrange; + minBidPriceOrange = conf->minBidPriceOrange; + maxBidPriceOrange = conf->maxBidPriceOrange; + maxStackOrange = conf->maxStackOrange; + minPriceYellow = conf->minPriceYellow; + maxPriceYellow = conf->maxPriceYellow; + minBidPriceYellow = conf->minBidPriceYellow; + maxBidPriceYellow = conf->maxBidPriceYellow; + maxStackYellow = conf->maxStackYellow; + buyerPriceGrey = conf->buyerPriceGrey; + buyerPriceWhite = conf->buyerPriceWhite; + buyerPriceGreen = conf->buyerPriceGreen; + buyerPriceBlue = conf->buyerPriceBlue; + buyerPricePurple = conf->buyerPricePurple; + buyerPriceOrange = conf->buyerPriceOrange; + buyerPriceYellow = conf->buyerPriceYellow; + buyerBiddingInterval = conf->buyerBiddingInterval; + buyerBidsPerInterval = conf->buyerBidsPerInterval; + + // This part is acquired thorugh initialization + // + // greytgp = conf->greytgp; + // whitetgp = conf->whitetgp; + // greentgp = conf->greentgp; + // bluetgp = conf->bluetgp; + // purpletgp = conf->purpletgp; + // orangetgp = conf->orangetgp; + // yellowtgp = conf->yellowtgp; + // greyip = conf->greyip; + // whiteip = conf->whiteip; + // greenip = conf->greenip; + // blueip = conf->blueip; + // purpleip = conf->purpleip; + // orangeip = conf->orangeip; + // yellowip = conf->yellowip; + // greyTGoods = conf->greyTGoods; + // whiteTGoods = conf->whiteTGoods; + // greenTGoods = conf->greenTGoods; + // blueTGoods = conf->blueTGoods; + // purpleTGoods = conf->purpleTGoods; + // orangeTGoods = conf->orangeTGoods; + // yellowTGoods = conf->yellowTGoods; + // greyItems = conf->greyItems; + // whiteItems = conf->whiteItems; + // greenItems = conf->greenItems; + // blueItems = conf->blueItems; + // purpleItems = conf->purpleItems; + // orangeItems = conf->orangeItems; + // yellowItems = conf->yellowItems; + + // + // Copy the public properties + // + + DebugOut = conf->DebugOut; + DebugOutConfig = conf->DebugOutConfig; + DebugOutFilters = conf->DebugOutFilters; + DebugOutBuyer = conf->DebugOutBuyer; + DebugOutSeller = conf->DebugOutSeller; + TraceSeller = conf->TraceSeller; + TraceBuyer = conf->TraceBuyer; + AHBSeller = conf->AHBSeller; + AHBBuyer = conf->AHBBuyer; + UseBuyPriceForBuyer = conf->UseBuyPriceForBuyer; + UseBuyPriceForSeller = conf->UseBuyPriceForSeller; + ConsiderOnlyBotAuctions = conf->ConsiderOnlyBotAuctions; + ItemsPerCycle = conf->ItemsPerCycle; + Vendor_Items = conf->Vendor_Items; + Loot_Items = conf->Loot_Items; + Other_Items = conf->Other_Items; + Vendor_TGs = conf->Vendor_TGs; + Loot_TGs = conf->Loot_TGs; + Other_TGs = conf->Other_TGs; + Profession_Items = conf->Profession_Items; + No_Bind = conf->No_Bind; + Bind_When_Picked_Up = conf->Bind_When_Picked_Up; + Bind_When_Equipped = conf->Bind_When_Equipped; + Bind_When_Use = conf->Bind_When_Use; + Bind_Quest_Item = conf->Bind_Quest_Item; + DuplicatesCount = conf->DuplicatesCount; + ElapsingTimeClass = conf->ElapsingTimeClass; + DivisibleStacks = conf->DivisibleStacks; + DisablePermEnchant = conf->DisablePermEnchant; + DisableConjured = conf->DisableConjured; + DisableGems = conf->DisableGems; + DisableMoney = conf->DisableMoney; + DisableMoneyLoot = conf->DisableMoneyLoot; + DisableLootable = conf->DisableLootable; + DisableKeys = conf->DisableKeys; + DisableDuration = conf->DisableDuration; + DisableBOP_Or_Quest_NoReqLevel = conf->DisableBOP_Or_Quest_NoReqLevel; + DisableWarriorItems = conf->DisableWarriorItems; + DisablePaladinItems = conf->DisablePaladinItems; + DisableHunterItems = conf->DisableHunterItems; + DisableRogueItems = conf->DisableRogueItems; + DisablePriestItems = conf->DisablePriestItems; + DisableDKItems = conf->DisableDKItems; + DisableShamanItems = conf->DisableShamanItems; + DisableMageItems = conf->DisableMageItems; + DisableWarlockItems = conf->DisableWarlockItems; + DisableUnusedClassItems = conf->DisableUnusedClassItems; + DisableDruidItems = conf->DisableDruidItems; + DisableItemsBelowLevel = conf->DisableItemsBelowLevel; + DisableItemsAboveLevel = conf->DisableItemsAboveLevel; + DisableTGsBelowLevel = conf->DisableTGsBelowLevel; + DisableTGsAboveLevel = conf->DisableTGsAboveLevel; + DisableItemsBelowGUID = conf->DisableItemsBelowGUID; + DisableItemsAboveGUID = conf->DisableItemsAboveGUID; + DisableTGsBelowGUID = conf->DisableTGsBelowGUID; + DisableTGsAboveGUID = conf->DisableTGsAboveGUID; + DisableItemsBelowReqLevel = conf->DisableItemsBelowReqLevel; + DisableItemsAboveReqLevel = conf->DisableItemsAboveReqLevel; + DisableTGsBelowReqLevel = conf->DisableTGsBelowReqLevel; + DisableTGsAboveReqLevel = conf->DisableTGsAboveReqLevel; + DisableItemsBelowReqSkillRank = conf->DisableItemsBelowReqSkillRank; + DisableItemsAboveReqSkillRank = conf->DisableItemsAboveReqSkillRank; + DisableTGsBelowReqSkillRank = conf->DisableTGsBelowReqSkillRank; + DisableTGsAboveReqSkillRank = conf->DisableTGsAboveReqSkillRank; + + // + // Copy the sets + // + + NpcItems.clear(); + for (uint32 id: conf->NpcItems) + { + NpcItems.insert(id); + } + + LootItems.clear(); + for (uint32 id: conf->LootItems) + { + LootItems.insert(id); + } + + DisableItemStore.clear(); + for (uint32 id: conf->DisableItemStore) + { + DisableItemStore.insert(id); + } + + SellerWhiteList.clear(); + for (uint32 id: conf->SellerWhiteList) + { + SellerWhiteList.insert(id); + } + + GreyTradeGoodsBin.clear(); + for (uint32 id: conf->GreyTradeGoodsBin) + { + GreyTradeGoodsBin.insert(id); + } + + WhiteTradeGoodsBin.clear(); + for (uint32 id: conf->WhiteTradeGoodsBin) + { + WhiteTradeGoodsBin.insert(id); + } + + GreenTradeGoodsBin.clear(); + for (uint32 id: conf->GreenTradeGoodsBin) + { + GreenTradeGoodsBin.insert(id); + } + + BlueTradeGoodsBin.clear(); + for (uint32 id: conf->BlueTradeGoodsBin) + { + BlueTradeGoodsBin.insert(id); + } + + PurpleTradeGoodsBin.clear(); + for (uint32 id: conf->PurpleTradeGoodsBin) + { + PurpleTradeGoodsBin.insert(id); + } + + OrangeTradeGoodsBin.clear(); + for (uint32 id: conf->OrangeTradeGoodsBin) + { + OrangeTradeGoodsBin.insert(id); + } + + YellowTradeGoodsBin.clear(); + for (uint32 id: conf->YellowTradeGoodsBin) + { + YellowTradeGoodsBin.insert(id); + } + + + // + // Bins for items + // + + GreyItemsBin.clear(); + for (uint32 id: conf->GreyItemsBin) + { + GreyItemsBin.insert(id); + } + + WhiteItemsBin.clear(); + for (uint32 id: conf->WhiteItemsBin) + { + WhiteItemsBin.insert(id); + } + + GreenItemsBin.clear(); + for (uint32 id: conf->GreenItemsBin) + { + GreenItemsBin.insert(id); + } + + BlueItemsBin.clear(); + for (uint32 id: conf->BlueItemsBin) + { + BlueItemsBin.insert(id); + } + + PurpleItemsBin.clear(); + for (uint32 id: conf->PurpleItemsBin) + { + PurpleItemsBin.insert(id); + } + + OrangeItemsBin.clear(); + for (uint32 id: conf->OrangeItemsBin) + { + OrangeItemsBin.insert(id); + } + + YellowItemsBin.clear(); + for (uint32 id: conf->YellowItemsBin) + { + YellowItemsBin.insert(id); + } +} + +AHBConfig::~AHBConfig() +{ +} + +void AHBConfig::Reset() +{ + // + // Private variables + // + + AHID = 0; + AHFID = 0; + + minItems = 0; + maxItems = 0; + + percentGreyTradeGoods = 0; + percentWhiteTradeGoods = 0; + percentGreenTradeGoods = 0; + percentBlueTradeGoods = 0; + percentPurpleTradeGoods = 0; + percentOrangeTradeGoods = 0; + percentYellowTradeGoods = 0; + + percentGreyItems = 0; + percentWhiteItems = 0; + percentGreenItems = 0; + percentBlueItems = 0; + percentPurpleItems = 0; + percentOrangeItems = 0; + percentYellowItems = 0; + + minPriceGrey = 0; + maxPriceGrey = 0; + minBidPriceGrey = 0; + maxBidPriceGrey = 0; + maxStackGrey = 0; + + minPriceWhite = 0; + maxPriceWhite = 0; + minBidPriceWhite = 0; + maxBidPriceWhite = 0; + maxStackWhite = 0; + + minPriceGreen = 0; + maxPriceGreen = 0; + minBidPriceGreen = 0; + maxBidPriceGreen = 0; + maxStackGreen = 0; + + minPriceBlue = 0; + maxPriceBlue = 0; + minBidPriceBlue = 0; + maxBidPriceBlue = 0; + maxStackBlue = 0; + + minPricePurple = 0; + maxPricePurple = 0; + minBidPricePurple = 0; + maxBidPricePurple = 0; + maxStackPurple = 0; + + minPriceOrange = 0; + maxPriceOrange = 0; + minBidPriceOrange = 0; + maxBidPriceOrange = 0; + maxStackOrange = 0; + + minPriceYellow = 0; + maxPriceYellow = 0; + minBidPriceYellow = 0; + maxBidPriceYellow = 0; + maxStackYellow = 0; + + buyerPriceGrey = 0; + buyerPriceWhite = 0; + buyerPriceGreen = 0; + buyerPriceBlue = 0; + buyerPricePurple = 0; + buyerPriceOrange = 0; + buyerPriceYellow = 0; + + buyerBiddingInterval = 0; + buyerBidsPerInterval = 0; + + greytgp = 0; + whitetgp = 0; + greentgp = 0; + bluetgp = 0; + purpletgp = 0; + orangetgp = 0; + yellowtgp = 0; + + greyip = 0; + whiteip = 0; + greenip = 0; + blueip = 0; + purpleip = 0; + orangeip = 0; + yellowip = 0; + + greyTGoods = 0; + whiteTGoods = 0; + greenTGoods = 0; + blueTGoods = 0; + purpleTGoods = 0; + orangeTGoods = 0; + yellowTGoods = 0; + + greyItems = 0; + whiteItems = 0; + greenItems = 0; + blueItems = 0; + purpleItems = 0; + orangeItems = 0; + yellowItems = 0; + + // + // Public properties + // + + DebugOut = false; + DebugOutConfig = false; + DebugOutFilters = false; + DebugOutBuyer = false; + DebugOutSeller = false; + + TraceSeller = false; + TraceBuyer = false; + + AHBSeller = false; + AHBBuyer = false; + + UseBuyPriceForBuyer = false; + UseBuyPriceForSeller = false; + SellAtMarketPrice = false; + ConsiderOnlyBotAuctions = false; + ItemsPerCycle = 200; + + Vendor_Items = false; + Loot_Items = true; + Other_Items = false; + Vendor_TGs = false; + Loot_TGs = true; + Other_TGs = false; + Profession_Items = false; + + No_Bind = true; + Bind_When_Picked_Up = true; + Bind_When_Equipped = false; + Bind_When_Use = false; + Bind_Quest_Item = false; + DuplicatesCount = 0; + ElapsingTimeClass = 1; + DivisibleStacks = false; + + DisablePermEnchant = false; + DisableConjured = false; + DisableGems = false; + DisableMoney = false; + DisableMoneyLoot = false; + DisableLootable = false; + DisableKeys = false; + DisableDuration = false; + DisableBOP_Or_Quest_NoReqLevel = false; + + DisableWarriorItems = false; + DisablePaladinItems = false; + DisableHunterItems = false; + DisableRogueItems = false; + DisablePriestItems = false; + DisableDKItems = false; + DisableShamanItems = false; + DisableMageItems = false; + DisableWarlockItems = false; + DisableUnusedClassItems = false; + DisableDruidItems = false; + + DisableItemsBelowLevel = false; + DisableItemsAboveLevel = false; + DisableTGsBelowLevel = false; + DisableTGsAboveLevel = false; + DisableItemsBelowGUID = false; + DisableItemsAboveGUID = false; + DisableTGsBelowGUID = false; + DisableTGsAboveGUID = false; + DisableItemsBelowReqLevel = false; + DisableItemsAboveReqLevel = false; + DisableTGsBelowReqLevel = false; + DisableTGsAboveReqLevel = false; + DisableItemsBelowReqSkillRank = false; + DisableItemsAboveReqSkillRank = false; + DisableTGsBelowReqSkillRank = false; + DisableTGsAboveReqSkillRank = false; + + // + // Sets + // + + NpcItems.clear(); + LootItems.clear(); + + DisableItemStore.clear(); + SellerWhiteList.clear(); + + GreyTradeGoodsBin.clear(); + WhiteTradeGoodsBin.clear(); + GreenTradeGoodsBin.clear(); + BlueTradeGoodsBin.clear(); + PurpleTradeGoodsBin.clear(); + OrangeTradeGoodsBin.clear(); + YellowTradeGoodsBin.clear(); + + GreyItemsBin.clear(); + WhiteItemsBin.clear(); + GreenItemsBin.clear(); + BlueItemsBin.clear(); + PurpleItemsBin.clear(); + OrangeItemsBin.clear(); + YellowItemsBin.clear(); + + itemsCount.clear(); + itemsSum.clear(); + itemsPrice.clear(); +} + +uint32 AHBConfig::GetAHID() +{ + return AHID; +} + +uint32 AHBConfig::GetAHFID() +{ + return AHFID; +} + +void AHBConfig::SetMinItems(uint32 value) +{ + minItems = value; +} + +uint32 AHBConfig::GetMinItems() +{ + if ((minItems == 0) && (maxItems)) + { + return maxItems; + } + else if ((maxItems) && (minItems > maxItems)) + { + return maxItems; + } + else + { + return minItems; + } +} + +void AHBConfig::SetMaxItems(uint32 value) +{ + maxItems = value; + // CalculatePercents() needs to be called, but only if + // SetPercentages() has been called at least once already. +} + +uint32 AHBConfig::GetMaxItems() +{ + return maxItems; +} + +void AHBConfig::SetPercentages( + uint32 greytg, + uint32 whitetg, + uint32 greentg, + uint32 bluetg, + uint32 purpletg, + uint32 orangetg, + uint32 yellowtg, + uint32 greyi, + uint32 whitei, + uint32 greeni, + uint32 bluei, + uint32 purplei, + uint32 orangei, + uint32 yellowi) +{ + uint32 totalPercent = + greytg + + whitetg + + greentg + + bluetg + + purpletg + + orangetg + + yellowtg + + greyi + + whitei + + greeni + + bluei + + purplei + + orangei + + yellowi; + + if (totalPercent == 0) + { + maxItems = 0; + } + else if (totalPercent != 100) + { + greytg = 0; + whitetg = 27; + greentg = 12; + bluetg = 10; + purpletg = 1; + orangetg = 0; + yellowtg = 0; + + greyi = 0; + whitei = 10; + greeni = 30; + bluei = 8; + purplei = 2; + orangei = 0; + yellowi = 0; + } + + percentGreyTradeGoods = greytg; + percentWhiteTradeGoods = whitetg; + percentGreenTradeGoods = greentg; + percentBlueTradeGoods = bluetg; + percentPurpleTradeGoods = purpletg; + percentOrangeTradeGoods = orangetg; + percentYellowTradeGoods = yellowtg; + percentGreyItems = greyi; + percentWhiteItems = whitei; + percentGreenItems = greeni; + percentBlueItems = bluei; + percentPurpleItems = purplei; + percentOrangeItems = orangei; + percentYellowItems = yellowi; + + CalculatePercents(); +} + +uint32 AHBConfig::GetPercentages(uint32 color) +{ + switch (color) + { + case AHB_GREY_TG: + return percentGreyTradeGoods; + break; + + case AHB_WHITE_TG: + return percentWhiteTradeGoods; + break; + + case AHB_GREEN_TG: + return percentGreenTradeGoods; + break; + + case AHB_BLUE_TG: + return percentBlueTradeGoods; + break; + + case AHB_PURPLE_TG: + return percentPurpleTradeGoods; + break; + + case AHB_ORANGE_TG: + return percentOrangeTradeGoods; + break; + + case AHB_YELLOW_TG: + return percentYellowTradeGoods; + break; + + case AHB_GREY_I: + return percentGreyItems; + break; + + case AHB_WHITE_I: + return percentWhiteItems; + break; + + case AHB_GREEN_I: + return percentGreenItems; + break; + + case AHB_BLUE_I: + return percentBlueItems; + break; + + case AHB_PURPLE_I: + return percentPurpleItems; + break; + + case AHB_ORANGE_I: + return percentOrangeItems; + break; + + case AHB_YELLOW_I: + return percentYellowItems; + break; + + default: + return 0; + break; + } +} + +void AHBConfig::SetMinPrice(uint32 color, uint32 value) +{ + switch (color) + { + case AHB_GREY: + minPriceGrey = value; + break; + + case AHB_WHITE: + minPriceWhite = value; + break; + + case AHB_GREEN: + minPriceGreen = value; + break; + + case AHB_BLUE: + minPriceBlue = value; + break; + + case AHB_PURPLE: + minPricePurple = value; + break; + + case AHB_ORANGE: + minPriceOrange = value; + break; + + case AHB_YELLOW: + minPriceYellow = value; + break; + + default: + break; + } +} + +uint32 AHBConfig::GetMinPrice(uint32 color) +{ + switch (color) + { + case AHB_GREY: + { + if (minPriceGrey == 0) + { + return 100; + } + else if (minPriceGrey > maxPriceGrey) + { + return maxPriceGrey; + } + else + { + return minPriceGrey; + } + + break; + } + + case AHB_WHITE: + { + if (minPriceWhite == 0) + { + return 150; + } + else if (minPriceWhite > maxPriceWhite) + { + return maxPriceWhite; + } + else + { + return minPriceWhite; + } + + break; + } + + case AHB_GREEN: + { + if (minPriceGreen == 0) + { + return 200; + } + else if (minPriceGreen > maxPriceGreen) + { + return maxPriceGreen; + } + else + { + return minPriceGreen; + } + + break; + } + + case AHB_BLUE: + { + if (minPriceBlue == 0) + { + return 250; + } + else if (minPriceBlue > maxPriceBlue) + { + return maxPriceBlue; + } + else + { + return minPriceBlue; + } + + break; + } + + case AHB_PURPLE: + { + if (minPricePurple == 0) + { + return 300; + } + else if (minPricePurple > maxPricePurple) + { + return maxPricePurple; + } + else + { + return minPricePurple; + } + + break; + } + + case AHB_ORANGE: + { + if (minPriceOrange == 0) + { + return 400; + } + else if (minPriceOrange > maxPriceOrange) + { + return maxPriceOrange; + } + else + { + return minPriceOrange; + } + + break; + } + + case AHB_YELLOW: + { + if (minPriceYellow == 0) + { + return 500; + } + else if (minPriceYellow > maxPriceYellow) + { + return maxPriceYellow; + } + else + { + return minPriceYellow; + } + + break; + } + + default: + return 0; + } +} + +void AHBConfig::SetMaxPrice(uint32 color, uint32 value) +{ + switch (color) + { + case AHB_GREY: + maxPriceGrey = value; + break; + + case AHB_WHITE: + maxPriceWhite = value; + break; + + case AHB_GREEN: + maxPriceGreen = value; + break; + + case AHB_BLUE: + maxPriceBlue = value; + break; + + case AHB_PURPLE: + maxPricePurple = value; + break; + + case AHB_ORANGE: + maxPriceOrange = value; + break; + + case AHB_YELLOW: + maxPriceYellow = value; + break; + + default: + break; + } +} + +uint32 AHBConfig::GetMaxPrice(uint32 color) +{ + switch (color) + { + case AHB_GREY: + { + if (maxPriceGrey == 0) + { + return 150; + } + else + { + return maxPriceGrey; + } + + break; + } + + case AHB_WHITE: + { + if (maxPriceWhite == 0) + { + return 250; + } + else + { + return maxPriceWhite; + } + + break; + } + + case AHB_GREEN: + { + if (maxPriceGreen == 0) + { + return 300; + } + else + { + return maxPriceGreen; + } + + break; + } + + case AHB_BLUE: + { + if (maxPriceBlue == 0) + { + return 350; + } + else + { + return maxPriceBlue; + } + + break; + } + + case AHB_PURPLE: + { + if (maxPricePurple == 0) + { + return 450; + } + else + { + return maxPricePurple; + } + + break; + } + + case AHB_ORANGE: + { + if (maxPriceOrange == 0) + { + return 550; + } + else + { + return maxPriceOrange; + } + + break; + } + + case AHB_YELLOW: + { + if (maxPriceYellow == 0) + { + return 650; + } + else + { + return maxPriceYellow; + } + + break; + } + + default: + return 0; + + } +} + +void AHBConfig::SetMinBidPrice(uint32 color, uint32 value) +{ + switch (color) + { + case AHB_GREY: + minBidPriceGrey = value; + break; + + case AHB_WHITE: + minBidPriceWhite = value; + break; + + case AHB_GREEN: + minBidPriceGreen = value; + break; + + case AHB_BLUE: + minBidPriceBlue = value; + break; + + case AHB_PURPLE: + minBidPricePurple = value; + break; + + case AHB_ORANGE: + minBidPriceOrange = value; + break; + + case AHB_YELLOW: + minBidPriceYellow = value; + break; + + default: + break; + } +} + +uint32 AHBConfig::GetMinBidPrice(uint32 color) +{ + switch (color) + { + case AHB_GREY: + { + if (minBidPriceGrey > 100) + { + return 100; + } + else + { + return minBidPriceGrey; + } + + break; + } + + case AHB_WHITE: + { + if (minBidPriceWhite > 100) + { + return 100; + } + else + { + return minBidPriceWhite; + } + + break; + } + + case AHB_GREEN: + { + if (minBidPriceGreen > 100) + { + return 100; + } + else + { + return minBidPriceGreen; + } + + break; + } + + case AHB_BLUE: + { + if (minBidPriceBlue > 100) + { + return 100; + } + else + { + return minBidPriceBlue; + } + + break; + } + + case AHB_PURPLE: + { + if (minBidPricePurple > 100) + { + return 100; + } + else + { + return minBidPricePurple; + } + + break; + } + + case AHB_ORANGE: + { + if (minBidPriceOrange > 100) + { + return 100; + } + else + { + return minBidPriceOrange; + } + + break; + } + + case AHB_YELLOW: + { + if (minBidPriceYellow > 100) + { + return 100; + } + else + { + return minBidPriceYellow; + } + + break; + } + + default: + return 0; + } +} + +void AHBConfig::SetMaxBidPrice(uint32 color, uint32 value) +{ + switch (color) + { + case AHB_GREY: + maxBidPriceGrey = value; + break; + + case AHB_WHITE: + maxBidPriceWhite = value; + break; + + case AHB_GREEN: + maxBidPriceGreen = value; + break; + + case AHB_BLUE: + maxBidPriceBlue = value; + break; + + case AHB_PURPLE: + maxBidPricePurple = value; + break; + + case AHB_ORANGE: + maxBidPriceOrange = value; + break; + + case AHB_YELLOW: + maxBidPriceYellow = value; + break; + + default: + break; + } + +} +uint32 AHBConfig::GetMaxBidPrice(uint32 color) +{ + switch (color) + { + case AHB_GREY: + { + if (maxBidPriceGrey > 100) + { + return 100; + } + else + { + return maxBidPriceGrey; + } + + break; + } + + case AHB_WHITE: + { + if (maxBidPriceWhite > 100) + { + return 100; + } + else + { + return maxBidPriceWhite; + } + + break; + } + + case AHB_GREEN: + { + if (maxBidPriceGreen > 100) + { + return 100; + } + else + { + return maxBidPriceGreen; + } + + break; + } + + case AHB_BLUE: + { + if (maxBidPriceBlue > 100) + { + return 100; + } + else + { + return maxBidPriceBlue; + } + + break; + } + + case AHB_PURPLE: + { + if (maxBidPricePurple > 100) + { + return 100; + } + else + { + return maxBidPricePurple; + } + + break; + } + + case AHB_ORANGE: + { + if (maxBidPriceOrange > 100) + { + return 100; + } + else + { + return maxBidPriceOrange; + } + + break; + } + + case AHB_YELLOW: + { + if (maxBidPriceYellow > 100) + { + return 100; + } + else + { + return maxBidPriceYellow; + } + + break; + } + + default: + return 0; + } +} + +void AHBConfig::SetMaxStack(uint32 color, uint32 value) +{ + switch (color) + { + case AHB_GREY: + maxStackGrey = value; + break; + + case AHB_WHITE: + maxStackWhite = value; + break; + + case AHB_GREEN: + maxStackGreen = value; + break; + + case AHB_BLUE: + maxStackBlue = value; + break; + + case AHB_PURPLE: + maxStackPurple = value; + break; + + case AHB_ORANGE: + maxStackOrange = value; + break; + + case AHB_YELLOW: + maxStackYellow = value; + break; + + default: + break; + } +} + +uint32 AHBConfig::GetMaxStack(uint32 color) +{ + switch (color) + { + case AHB_GREY: + { + return maxStackGrey; + break; + } + + case AHB_WHITE: + { + return maxStackWhite; + break; + } + + case AHB_GREEN: + { + return maxStackGreen; + break; + } + + case AHB_BLUE: + { + return maxStackBlue; + break; + } + + case AHB_PURPLE: + { + return maxStackPurple; + break; + } + + case AHB_ORANGE: + { + return maxStackOrange; + break; + } + + case AHB_YELLOW: + { + return maxStackYellow; + break; + } + + default: + return 0; + } +} + +void AHBConfig::SetBuyerPrice(uint32 color, uint32 value) +{ + switch (color) + { + case AHB_GREY: + buyerPriceGrey = value; + break; + + case AHB_WHITE: + buyerPriceWhite = value; + break; + + case AHB_GREEN: + buyerPriceGreen = value; + break; + + case AHB_BLUE: + buyerPriceBlue = value; + break; + + case AHB_PURPLE: + buyerPricePurple = value; + break; + + case AHB_ORANGE: + buyerPriceOrange = value; + break; + + case AHB_YELLOW: + buyerPriceYellow = value; + break; + + default: + break; + } +} + +uint32 AHBConfig::GetBuyerPrice(uint32 color) +{ + switch (color) + { + case AHB_GREY: + return buyerPriceGrey; + break; + + case AHB_WHITE: + return buyerPriceWhite; + break; + + case AHB_GREEN: + return buyerPriceGreen; + break; + + case AHB_BLUE: + return buyerPriceBlue; + break; + + case AHB_PURPLE: + return buyerPricePurple; + break; + + case AHB_ORANGE: + return buyerPriceOrange; + break; + + case AHB_YELLOW: + return buyerPriceYellow; + break; + + default: + return 0; + break; + } +} + +void AHBConfig::SetBiddingInterval(uint32 value) +{ + buyerBiddingInterval = value; +} + +uint32 AHBConfig::GetBiddingInterval() +{ + return buyerBiddingInterval; +} + +void AHBConfig::CalculatePercents() +{ + // + // Use the percent values to setup the maximum amount of items per category + // to be sold in the market + // + + greytgp = (uint32)(((double)percentGreyTradeGoods / 100.0) * maxItems); + whitetgp = (uint32)(((double)percentWhiteTradeGoods / 100.0) * maxItems); + greentgp = (uint32)(((double)percentGreenTradeGoods / 100.0) * maxItems); + bluetgp = (uint32)(((double)percentBlueTradeGoods / 100.0) * maxItems); + purpletgp = (uint32)(((double)percentPurpleTradeGoods / 100.0) * maxItems); + orangetgp = (uint32)(((double)percentOrangeTradeGoods / 100.0) * maxItems); + yellowtgp = (uint32)(((double)percentYellowTradeGoods / 100.0) * maxItems); + + greyip = (uint32)(((double)percentGreyItems / 100.0) * maxItems); + whiteip = (uint32)(((double)percentWhiteItems / 100.0) * maxItems); + greenip = (uint32)(((double)percentGreenItems / 100.0) * maxItems); + blueip = (uint32)(((double)percentBlueItems / 100.0) * maxItems); + purpleip = (uint32)(((double)percentPurpleItems / 100.0) * maxItems); + orangeip = (uint32)(((double)percentOrangeItems / 100.0) * maxItems); + yellowip = (uint32)(((double)percentYellowItems / 100.0) * maxItems); + + uint32 total = + greytgp + + whitetgp + + greentgp + + bluetgp + + purpletgp + + orangetgp + + yellowtgp + + greyip + + whiteip + + greenip + + blueip + + purpleip + + orangeip + + yellowip; + + int32 diff = (maxItems - total); + + if (diff < 0) + { + if ((whiteip - diff) > 0) + { + whiteip -= diff; + } + else if ((greenip - diff) > 0) + { + greenip -= diff; + } + } +} + +uint32 AHBConfig::GetMaximum(uint32 ahbotItemType) +{ + switch (ahbotItemType) + { + case AHB_GREY_TG: + return greytgp; + + case AHB_WHITE_TG: + return whitetgp; + + case AHB_GREEN_TG: + return greentgp; + + case AHB_BLUE_TG: + return bluetgp; + + case AHB_PURPLE_TG: + return purpletgp; + + case AHB_ORANGE_TG: + return orangetgp; + + case AHB_YELLOW_TG: + return yellowtgp; + + case AHB_GREY_I: + return greyip; + + case AHB_WHITE_I: + return whiteip; + + case AHB_GREEN_I: + return greenip; + + case AHB_BLUE_I: + return blueip; + + case AHB_PURPLE_I: + return purpleip; + + case AHB_ORANGE_I: + return orangeip; + + case AHB_YELLOW_I: + return yellowip; + + default: + { + LOG_ERROR("module", "AHBot AHBConfig::GetMaximum() invalid param"); + return 0; + } + } +} + +void AHBConfig::DecItemCounts(uint32 Class, uint32 Quality) +{ + switch (Class) + { + case ITEM_CLASS_TRADE_GOODS: + DecItemCounts(Quality); + break; + + default: + DecItemCounts(Quality + AHB_ITEM_TYPE_OFFSET); + break; + } +} + +void AHBConfig::DecItemCounts(uint32 ahbotItemType) +{ + switch (ahbotItemType) + { + case AHB_GREY_TG: + if (greyTGoods > 0) + { + --greyTGoods; + } + break; + + case AHB_WHITE_TG: + if (whiteTGoods > 0) + { + --whiteTGoods; + } + break; + + case AHB_GREEN_TG: + if (greenTGoods > 0) + { + --greenTGoods; + } + break; + + case AHB_BLUE_TG: + if (blueTGoods > 0) + { + --blueTGoods; + } + break; + + case AHB_PURPLE_TG: + if (purpleTGoods > 0) + { + --purpleTGoods; + } + break; + + case AHB_ORANGE_TG: + if (orangeTGoods > 0) + { + --orangeTGoods; + } + break; + + case AHB_YELLOW_TG: + if (yellowTGoods > 0) + { + --yellowTGoods; + } + break; + + case AHB_GREY_I: + if (greyItems > 0) + { + --greyItems; + } + break; + + case AHB_WHITE_I: + if (whiteItems > 0) + { + --whiteItems; + } + break; + + case AHB_GREEN_I: + if (greenItems > 0) + { + --greenItems; + } + break; + + case AHB_BLUE_I: + if (blueItems > 0) + { + --blueItems; + } + break; + + case AHB_PURPLE_I: + if (purpleItems > 0) + { + --purpleItems; + } + break; + + case AHB_ORANGE_I: + if (orangeItems > 0) + { + --orangeItems; + } + break; + + case AHB_YELLOW_I: + if (yellowItems > 0) + { + --yellowItems; + } + break; + + default: + break; + } +} + +void AHBConfig::IncItemCounts(uint32 Class, uint32 Quality) +{ + switch (Class) + { + case ITEM_CLASS_TRADE_GOODS: + IncItemCounts(Quality); + break; + + default: + IncItemCounts(Quality + 7); + break; + } +} + +void AHBConfig::IncItemCounts(uint32 ahbotItemType) +{ + switch (ahbotItemType) + { + case AHB_GREY_TG: + ++greyTGoods; + break; + + case AHB_WHITE_TG: + ++whiteTGoods; + break; + + case AHB_GREEN_TG: + ++greenTGoods; + break; + + case AHB_BLUE_TG: + ++blueTGoods; + break; + + case AHB_PURPLE_TG: + ++purpleTGoods; + break; + + case AHB_ORANGE_TG: + ++orangeTGoods; + break; + + case AHB_YELLOW_TG: + ++yellowTGoods; + break; + + case AHB_GREY_I: + ++greyItems; + break; + + case AHB_WHITE_I: + ++whiteItems; + break; + + case AHB_GREEN_I: + ++greenItems; + break; + + case AHB_BLUE_I: + ++blueItems; + break; + + case AHB_PURPLE_I: + ++purpleItems; + break; + + case AHB_ORANGE_I: + ++orangeItems; + break; + + case AHB_YELLOW_I: + ++yellowItems; + break; + + default: + break; + } +} + +void AHBConfig::ResetItemCounts() +{ + greyTGoods = 0; + whiteTGoods = 0; + greenTGoods = 0; + blueTGoods = 0; + purpleTGoods = 0; + orangeTGoods = 0; + yellowTGoods = 0; + + greyItems = 0; + whiteItems = 0; + greenItems = 0; + blueItems = 0; + purpleItems = 0; + orangeItems = 0; + yellowItems = 0; +} + +uint32 AHBConfig::TotalItemCounts() +{ + return( + greyTGoods + + whiteTGoods + + greenTGoods + + blueTGoods + + purpleTGoods + + orangeTGoods + + yellowTGoods + + + greyItems + + whiteItems + + greenItems + + blueItems + + purpleItems + + orangeItems + + yellowItems); +} + +uint32 AHBConfig::GetItemCounts(uint32 color) +{ + switch (color) + { + case AHB_GREY_TG: + return greyTGoods; + break; + + case AHB_WHITE_TG: + return whiteTGoods; + break; + + case AHB_GREEN_TG: + return greenTGoods; + break; + + case AHB_BLUE_TG: + return blueTGoods; + break; + + case AHB_PURPLE_TG: + return purpleTGoods; + break; + + case AHB_ORANGE_TG: + return orangeTGoods; + break; + + case AHB_YELLOW_TG: + return yellowTGoods; + break; + + case AHB_GREY_I: + return greyItems; + break; + + case AHB_WHITE_I: + return whiteItems; + break; + + case AHB_GREEN_I: + return greenItems; + break; + + case AHB_BLUE_I: + return blueItems; + break; + + case AHB_PURPLE_I: + return purpleItems; + break; + + case AHB_ORANGE_I: + return orangeItems; + break; + + case AHB_YELLOW_I: + return yellowItems; + break; + + default: + return 0; + break; + } +} + +void AHBConfig::SetBidsPerInterval(uint32 value) +{ + buyerBidsPerInterval = value; +} + +uint32 AHBConfig::GetBidsPerInterval() +{ + return buyerBidsPerInterval; +} + +void AHBConfig::UpdateItemStats(uint32 id, uint32 stackSize, uint64 buyout) +{ + if (!stackSize) + { + return; + } + + // + // Collects information about the item bought + // + + uint32 perUnit = buyout / stackSize; + + if (itemsCount.count(id) == 0) + { + itemsCount[id] = 1; + itemsSum[id] = perUnit; + itemsPrice[id] = perUnit; + } + else + { + itemsCount[id]++; + + // + // Reset the statistics to force adapt to the market price. + // Adds a little of randomness by adding/removing a range of 9 to the threshold. + // + + if (itemsCount[id] > MarketResetThreshold + (urand(1, 19) - 10)) + { + itemsCount[id] = 1; + itemsSum[id] = perUnit; + itemsPrice[id] = perUnit; + } + else + { + // + // Here is decided the price for single unit: + // right now is a plain, boring average of the ~100 previous auctions. + // + + itemsSum[id] = (itemsSum[id] + perUnit); + itemsPrice[id] = itemsSum[id] / itemsCount[id]; + } + } + + if (DebugOutConfig) + { + LOG_INFO("module", "Updating market price item={}, price={}", id, itemsPrice[id]); + } +} + +uint64 AHBConfig::GetItemPrice(uint32 id) +{ + if (itemsCount.count(id) != 0) + { + return itemsPrice[id]; + } + + return 0; +} + +void AHBConfig::Initialize(std::set botsIds) +{ + InitializeFromFile(); + InitializeFromSql(botsIds); + InitializeBins(); +} + +void AHBConfig::InitializeFromFile() +{ + // + // Load from, the configuration file + // + + DebugOut = sConfigMgr->GetOption ("AuctionHouseBot.DEBUG" , false); + DebugOutConfig = sConfigMgr->GetOption ("AuctionHouseBot.DEBUG_CONFIG" , false); + DebugOutFilters = sConfigMgr->GetOption ("AuctionHouseBot.DEBUG_FILTERS", false); + DebugOutBuyer = sConfigMgr->GetOption ("AuctionHouseBot.DEBUG_BUYER" , false); + DebugOutSeller = sConfigMgr->GetOption ("AuctionHouseBot.DEBUG_SELLER" , false); + + TraceSeller = sConfigMgr->GetOption ("AuctionHouseBot.TRACE_SELLER" , false); + TraceBuyer = sConfigMgr->GetOption ("AuctionHouseBot.TRACE_BUYER" , false); + + AHBSeller = sConfigMgr->GetOption ("AuctionHouseBot.EnableSeller" , false); + AHBBuyer = sConfigMgr->GetOption ("AuctionHouseBot.EnableBuyer" , false); + UseBuyPriceForSeller = sConfigMgr->GetOption ("AuctionHouseBot.UseBuyPriceForSeller" , false); + UseBuyPriceForBuyer = sConfigMgr->GetOption ("AuctionHouseBot.UseBuyPriceForBuyer" , false); + SellAtMarketPrice = sConfigMgr->GetOption ("AuctionHouseBot.UseMarketPriceForSeller", false); + MarketResetThreshold = sConfigMgr->GetOption("AuctionHouseBot.MarketResetThreshold" , 25); + DuplicatesCount = sConfigMgr->GetOption("AuctionHouseBot.DuplicatesCount" , 0); + DivisibleStacks = sConfigMgr->GetOption ("AuctionHouseBot.DivisibleStacks" , false); + ElapsingTimeClass = sConfigMgr->GetOption("AuctionHouseBot.ElapsingTimeClass" , 1); + ConsiderOnlyBotAuctions = sConfigMgr->GetOption ("AuctionHouseBot.ConsiderOnlyBotAuctions", false); + ItemsPerCycle = sConfigMgr->GetOption("AuctionHouseBot.ItemsPerCycle" , 200); + + // + // Flags: item types + // + + Vendor_Items = sConfigMgr->GetOption ("AuctionHouseBot.VendorItems" , false); + Loot_Items = sConfigMgr->GetOption ("AuctionHouseBot.LootItems" , true); + Other_Items = sConfigMgr->GetOption ("AuctionHouseBot.OtherItems" , false); + Vendor_TGs = sConfigMgr->GetOption ("AuctionHouseBot.VendorTradeGoods" , false); + Loot_TGs = sConfigMgr->GetOption ("AuctionHouseBot.LootTradeGoods" , true); + Other_TGs = sConfigMgr->GetOption ("AuctionHouseBot.OtherTradeGoods" , false); + Profession_Items = sConfigMgr->GetOption ("AuctionHouseBot.ProfessionItems" , false); + + // + // Flags: items binding + // + + No_Bind = sConfigMgr->GetOption ("AuctionHouseBot.No_Bind" , true); + Bind_When_Picked_Up = sConfigMgr->GetOption ("AuctionHouseBot.Bind_When_Picked_Up" , false); + Bind_When_Equipped = sConfigMgr->GetOption ("AuctionHouseBot.Bind_When_Equipped" , true); + Bind_When_Use = sConfigMgr->GetOption ("AuctionHouseBot.Bind_When_Use" , true); + Bind_Quest_Item = sConfigMgr->GetOption ("AuctionHouseBot.Bind_Quest_Item" , false); + + // + // Flags: misc + // + + DisableConjured = sConfigMgr->GetOption ("AuctionHouseBot.DisableConjured" , false); + DisableGems = sConfigMgr->GetOption ("AuctionHouseBot.DisableGems" , false); + DisableMoney = sConfigMgr->GetOption ("AuctionHouseBot.DisableMoney" , false); + DisableMoneyLoot = sConfigMgr->GetOption ("AuctionHouseBot.DisableMoneyLoot" , false); + DisableLootable = sConfigMgr->GetOption ("AuctionHouseBot.DisableLootable" , false); + DisableKeys = sConfigMgr->GetOption ("AuctionHouseBot.DisableKeys" , false); + DisableDuration = sConfigMgr->GetOption ("AuctionHouseBot.DisableDuration" , false); + DisableBOP_Or_Quest_NoReqLevel = sConfigMgr->GetOption ("AuctionHouseBot.DisableBOP_Or_Quest_NoReqLevel", false); + + // + // Flags: items per class + // + + DisableWarriorItems = sConfigMgr->GetOption ("AuctionHouseBot.DisableWarriorItems" , false); + DisablePaladinItems = sConfigMgr->GetOption ("AuctionHouseBot.DisablePaladinItems" , false); + DisableHunterItems = sConfigMgr->GetOption ("AuctionHouseBot.DisableHunterItems" , false); + DisableRogueItems = sConfigMgr->GetOption ("AuctionHouseBot.DisableRogueItems" , false); + DisablePriestItems = sConfigMgr->GetOption ("AuctionHouseBot.DisablePriestItems" , false); + DisableDKItems = sConfigMgr->GetOption ("AuctionHouseBot.DisableDKItems" , false); + DisableShamanItems = sConfigMgr->GetOption ("AuctionHouseBot.DisableShamanItems" , false); + DisableMageItems = sConfigMgr->GetOption ("AuctionHouseBot.DisableMageItems" , false); + DisableWarlockItems = sConfigMgr->GetOption ("AuctionHouseBot.DisableWarlockItems" , false); + DisableUnusedClassItems = sConfigMgr->GetOption ("AuctionHouseBot.DisableUnusedClassItems", false); + DisableDruidItems = sConfigMgr->GetOption ("AuctionHouseBot.DisableDruidItems" , false); + + // + // Items level and skills + // + + DisableItemsBelowLevel = sConfigMgr->GetOption("AuctionHouseBot.DisableItemsBelowLevel" , 0); + DisableItemsAboveLevel = sConfigMgr->GetOption("AuctionHouseBot.DisableItemsAboveLevel" , 0); + DisableItemsBelowGUID = sConfigMgr->GetOption("AuctionHouseBot.DisableItemsBelowGUID" , 0); + DisableItemsAboveGUID = sConfigMgr->GetOption("AuctionHouseBot.DisableItemsAboveGUID" , 0); + DisableItemsBelowReqLevel = sConfigMgr->GetOption("AuctionHouseBot.DisableItemsBelowReqLevel" , 0); + DisableItemsAboveReqLevel = sConfigMgr->GetOption("AuctionHouseBot.DisableItemsAboveReqLevel" , 0); + DisableItemsBelowReqSkillRank = sConfigMgr->GetOption("AuctionHouseBot.DisableItemsBelowReqSkillRank", 0); + DisableItemsAboveReqSkillRank = sConfigMgr->GetOption("AuctionHouseBot.DisableItemsAboveReqSkillRank", 0); + + // + // Trade goods level and skills + // + + DisableTGsBelowLevel = sConfigMgr->GetOption("AuctionHouseBot.DisableTGsBelowLevel" , 0); + DisableTGsAboveLevel = sConfigMgr->GetOption("AuctionHouseBot.DisableTGsAboveLevel" , 0); + DisableTGsBelowGUID = sConfigMgr->GetOption("AuctionHouseBot.DisableTGsBelowGUID" , 0); + DisableTGsAboveGUID = sConfigMgr->GetOption("AuctionHouseBot.DisableTGsAboveGUID" , 0); + DisableTGsBelowReqLevel = sConfigMgr->GetOption("AuctionHouseBot.DisableTGsBelowReqLevel" , 0); + DisableTGsAboveReqLevel = sConfigMgr->GetOption("AuctionHouseBot.DisableTGsAboveReqLevel" , 0); + DisableTGsBelowReqSkillRank = sConfigMgr->GetOption("AuctionHouseBot.DisableTGsBelowReqSkillRank", 0); + DisableTGsAboveReqSkillRank = sConfigMgr->GetOption("AuctionHouseBot.DisableTGsAboveReqSkillRank", 0); + + // + // Whitelists + // + + SellerWhiteList = getCommaSeparatedIntegers(sConfigMgr->GetOption("AuctionHouseBot.SellerWhiteList", "")); +} + +void AHBConfig::InitializeFromSql(std::set botsIds) +{ + // + // Load min and max items + // + + SetMinItems(WorldDatabase.Query("SELECT minitems FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxItems(WorldDatabase.Query("SELECT maxitems FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + + // + // Load percentages + // + + uint32 greytg = WorldDatabase.Query("SELECT percentgreytradegoods FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get(); + uint32 whitetg = WorldDatabase.Query("SELECT percentwhitetradegoods FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get(); + uint32 greentg = WorldDatabase.Query("SELECT percentgreentradegoods FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get(); + uint32 bluetg = WorldDatabase.Query("SELECT percentbluetradegoods FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get(); + uint32 purpletg = WorldDatabase.Query("SELECT percentpurpletradegoods FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get(); + uint32 orangetg = WorldDatabase.Query("SELECT percentorangetradegoods FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get(); + uint32 yellowtg = WorldDatabase.Query("SELECT percentyellowtradegoods FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get(); + + uint32 greyi = WorldDatabase.Query("SELECT percentgreyitems FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get(); + uint32 whitei = WorldDatabase.Query("SELECT percentwhiteitems FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get(); + uint32 greeni = WorldDatabase.Query("SELECT percentgreenitems FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get(); + uint32 bluei = WorldDatabase.Query("SELECT percentblueitems FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get(); + uint32 purplei = WorldDatabase.Query("SELECT percentpurpleitems FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get(); + uint32 orangei = WorldDatabase.Query("SELECT percentorangeitems FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get(); + uint32 yellowi = WorldDatabase.Query("SELECT percentyellowitems FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get(); + + SetPercentages(greytg, whitetg, greentg, bluetg, purpletg, orangetg, yellowtg, greyi, whitei, greeni, bluei, purplei, orangei, yellowi); + + // + // Load min and max prices + // + + SetMinPrice(AHB_GREY , WorldDatabase.Query("SELECT minpricegrey FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxPrice(AHB_GREY , WorldDatabase.Query("SELECT maxpricegrey FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMinPrice(AHB_WHITE , WorldDatabase.Query("SELECT minpricewhite FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxPrice(AHB_WHITE , WorldDatabase.Query("SELECT maxpricewhite FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMinPrice(AHB_GREEN , WorldDatabase.Query("SELECT minpricegreen FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxPrice(AHB_GREEN , WorldDatabase.Query("SELECT maxpricegreen FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMinPrice(AHB_BLUE , WorldDatabase.Query("SELECT minpriceblue FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxPrice(AHB_BLUE , WorldDatabase.Query("SELECT maxpriceblue FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMinPrice(AHB_PURPLE, WorldDatabase.Query("SELECT minpricepurple FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxPrice(AHB_PURPLE, WorldDatabase.Query("SELECT maxpricepurple FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMinPrice(AHB_ORANGE, WorldDatabase.Query("SELECT minpriceorange FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxPrice(AHB_ORANGE, WorldDatabase.Query("SELECT maxpriceorange FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMinPrice(AHB_YELLOW, WorldDatabase.Query("SELECT minpriceyellow FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxPrice(AHB_YELLOW, WorldDatabase.Query("SELECT maxpriceyellow FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + + // + // Load min and max bid prices + // + + SetMinBidPrice(AHB_GREY , WorldDatabase.Query("SELECT minbidpricegrey FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxBidPrice(AHB_GREY , WorldDatabase.Query("SELECT maxbidpricegrey FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMinBidPrice(AHB_WHITE , WorldDatabase.Query("SELECT minbidpricewhite FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxBidPrice(AHB_WHITE , WorldDatabase.Query("SELECT maxbidpricewhite FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMinBidPrice(AHB_GREEN , WorldDatabase.Query("SELECT minbidpricegreen FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxBidPrice(AHB_GREEN , WorldDatabase.Query("SELECT maxbidpricegreen FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMinBidPrice(AHB_BLUE , WorldDatabase.Query("SELECT minbidpriceblue FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxBidPrice(AHB_BLUE , WorldDatabase.Query("SELECT maxbidpriceblue FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMinBidPrice(AHB_PURPLE, WorldDatabase.Query("SELECT minbidpricepurple FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxBidPrice(AHB_PURPLE, WorldDatabase.Query("SELECT maxbidpricepurple FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMinBidPrice(AHB_ORANGE, WorldDatabase.Query("SELECT minbidpriceorange FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxBidPrice(AHB_ORANGE, WorldDatabase.Query("SELECT maxbidpriceorange FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMinBidPrice(AHB_YELLOW, WorldDatabase.Query("SELECT minbidpriceyellow FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxBidPrice(AHB_YELLOW, WorldDatabase.Query("SELECT maxbidpriceyellow FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + + // + // Load max stacks + // + + SetMaxStack(AHB_GREY , WorldDatabase.Query("SELECT maxstackgrey FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxStack(AHB_WHITE , WorldDatabase.Query("SELECT maxstackwhite FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxStack(AHB_GREEN , WorldDatabase.Query("SELECT maxstackgreen FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxStack(AHB_BLUE , WorldDatabase.Query("SELECT maxstackblue FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxStack(AHB_PURPLE, WorldDatabase.Query("SELECT maxstackpurple FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxStack(AHB_ORANGE, WorldDatabase.Query("SELECT maxstackorange FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetMaxStack(AHB_YELLOW, WorldDatabase.Query("SELECT maxstackyellow FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + + if (DebugOutConfig) + { + LOG_INFO("module", "Settings for Auctionhouse {}", GetAHID()); + + LOG_INFO("module", "minItems = {}", GetMinItems()); + LOG_INFO("module", "maxItems = {}", GetMaxItems()); + + LOG_INFO("module", "percentGreyTradeGoods = {}", GetPercentages(AHB_GREY_TG)); + LOG_INFO("module", "percentWhiteTradeGoods = {}", GetPercentages(AHB_WHITE_TG)); + LOG_INFO("module", "percentGreenTradeGoods = {}", GetPercentages(AHB_GREEN_TG)); + LOG_INFO("module", "percentBlueTradeGoods = {}", GetPercentages(AHB_BLUE_TG)); + LOG_INFO("module", "percentPurpleTradeGoods = {}", GetPercentages(AHB_PURPLE_TG)); + LOG_INFO("module", "percentOrangeTradeGoods = {}", GetPercentages(AHB_ORANGE_TG)); + LOG_INFO("module", "percentYellowTradeGoods = {}", GetPercentages(AHB_YELLOW_TG)); + LOG_INFO("module", "percentGreyItems = {}", GetPercentages(AHB_GREY_I)); + LOG_INFO("module", "percentWhiteItems = {}", GetPercentages(AHB_WHITE_I)); + LOG_INFO("module", "percentGreenItems = {}", GetPercentages(AHB_GREEN_I)); + LOG_INFO("module", "percentBlueItems = {}", GetPercentages(AHB_BLUE_I)); + LOG_INFO("module", "percentPurpleItems = {}", GetPercentages(AHB_PURPLE_I)); + LOG_INFO("module", "percentOrangeItems = {}", GetPercentages(AHB_ORANGE_I)); + LOG_INFO("module", "percentYellowItems = {}", GetPercentages(AHB_YELLOW_I)); + + LOG_INFO("module", "minPriceGrey = {}", GetMinPrice(AHB_GREY)); + LOG_INFO("module", "maxPriceGrey = {}", GetMaxPrice(AHB_GREY)); + LOG_INFO("module", "minPriceWhite = {}", GetMinPrice(AHB_WHITE)); + LOG_INFO("module", "maxPriceWhite = {}", GetMaxPrice(AHB_WHITE)); + LOG_INFO("module", "minPriceGreen = {}", GetMinPrice(AHB_GREEN)); + LOG_INFO("module", "maxPriceGreen = {}", GetMaxPrice(AHB_GREEN)); + LOG_INFO("module", "minPriceBlue = {}", GetMinPrice(AHB_BLUE)); + LOG_INFO("module", "maxPriceBlue = {}", GetMaxPrice(AHB_BLUE)); + LOG_INFO("module", "minPricePurple = {}", GetMinPrice(AHB_PURPLE)); + LOG_INFO("module", "maxPricePurple = {}", GetMaxPrice(AHB_PURPLE)); + LOG_INFO("module", "minPriceOrange = {}", GetMinPrice(AHB_ORANGE)); + LOG_INFO("module", "maxPriceOrange = {}", GetMaxPrice(AHB_ORANGE)); + LOG_INFO("module", "minPriceYellow = {}", GetMinPrice(AHB_YELLOW)); + LOG_INFO("module", "maxPriceYellow = {}", GetMaxPrice(AHB_YELLOW)); + + LOG_INFO("module", "minBidPriceGrey = {}", GetMinBidPrice(AHB_GREY)); + LOG_INFO("module", "maxBidPriceGrey = {}", GetMaxBidPrice(AHB_GREY)); + LOG_INFO("module", "minBidPriceWhite = {}", GetMinBidPrice(AHB_WHITE)); + LOG_INFO("module", "maxBidPriceWhite = {}", GetMaxBidPrice(AHB_WHITE)); + LOG_INFO("module", "minBidPriceGreen = {}", GetMinBidPrice(AHB_GREEN)); + LOG_INFO("module", "maxBidPriceGreen = {}", GetMaxBidPrice(AHB_GREEN)); + LOG_INFO("module", "minBidPriceBlue = {}", GetMinBidPrice(AHB_BLUE)); + LOG_INFO("module", "maxBidPriceBlue = {}", GetMinBidPrice(AHB_BLUE)); + LOG_INFO("module", "minBidPricePurple = {}", GetMinBidPrice(AHB_PURPLE)); + LOG_INFO("module", "maxBidPricePurple = {}", GetMaxBidPrice(AHB_PURPLE)); + LOG_INFO("module", "minBidPriceOrange = {}", GetMinBidPrice(AHB_ORANGE)); + LOG_INFO("module", "maxBidPriceOrange = {}", GetMaxBidPrice(AHB_ORANGE)); + LOG_INFO("module", "minBidPriceYellow = {}", GetMinBidPrice(AHB_YELLOW)); + LOG_INFO("module", "maxBidPriceYellow = {}", GetMaxBidPrice(AHB_YELLOW)); + + LOG_INFO("module", "maxStackGrey = {}", GetMaxStack(AHB_GREY)); + LOG_INFO("module", "maxStackWhite = {}", GetMaxStack(AHB_WHITE)); + LOG_INFO("module", "maxStackGreen = {}", GetMaxStack(AHB_GREEN)); + LOG_INFO("module", "maxStackBlue = {}", GetMaxStack(AHB_BLUE)); + LOG_INFO("module", "maxStackPurple = {}", GetMaxStack(AHB_PURPLE)); + LOG_INFO("module", "maxStackOrange = {}", GetMaxStack(AHB_ORANGE)); + LOG_INFO("module", "maxStackYellow = {}", GetMaxStack(AHB_YELLOW)); + } + + // + // Reset the situation of the auction house + // + + ResetItemCounts(); + + // + // Update the situation of the auction house + // + + AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(GetAHFID()); + uint32 numberOfAuctions = auctionHouse->Getcount(); + + if (numberOfAuctions > 0) + { + for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr) + { + AuctionEntry* Aentry = itr->second; + Item* item = sAuctionMgr->GetAItem(Aentry->item_guid); + + // + // If it has to only consider the bots auctions, skip the ones belonging to the players + // + + if (ConsiderOnlyBotAuctions) + { + if (botsIds.find(Aentry->owner.GetCounter()) == botsIds.end()) + { + continue; + } + } + + if (item) + { + ItemTemplate const* prototype = item->GetTemplate(); + + if (prototype) + { + switch (prototype->Quality) + { + case AHB_GREY: + if (prototype->Class == ITEM_CLASS_TRADE_GOODS) + { + IncItemCounts(AHB_GREY_TG); + } + else + { + IncItemCounts(AHB_GREY_I); + } + break; + + case AHB_WHITE: + if (prototype->Class == ITEM_CLASS_TRADE_GOODS) + { + IncItemCounts(AHB_WHITE_TG); + } + else + { + IncItemCounts(AHB_WHITE_I); + } + + break; + + case AHB_GREEN: + if (prototype->Class == ITEM_CLASS_TRADE_GOODS) + { + IncItemCounts(AHB_GREEN_TG); + } + else + { + IncItemCounts(AHB_GREEN_I); + } + + break; + + case AHB_BLUE: + if (prototype->Class == ITEM_CLASS_TRADE_GOODS) + { + IncItemCounts(AHB_BLUE_TG); + } + else + { + IncItemCounts(AHB_BLUE_I); + } + + break; + + case AHB_PURPLE: + if (prototype->Class == ITEM_CLASS_TRADE_GOODS) + { + IncItemCounts(AHB_PURPLE_TG); + } + else + { + IncItemCounts(AHB_PURPLE_I); + } + + break; + + case AHB_ORANGE: + if (prototype->Class == ITEM_CLASS_TRADE_GOODS) + { + IncItemCounts(AHB_ORANGE_TG); + } + else + { + IncItemCounts(AHB_ORANGE_I); + } + + break; + + case AHB_YELLOW: + if (prototype->Class == ITEM_CLASS_TRADE_GOODS) + { + IncItemCounts(AHB_YELLOW_TG); + } + else + { + IncItemCounts(AHB_YELLOW_I); + } + + break; + } + } + } + } + } + + if (DebugOutConfig) + { + LOG_INFO("module", "Current situation for the auctionhouse {}", GetAHID()); + LOG_INFO("module", " Grey Trade Goods {}", GetItemCounts(AHB_GREY_TG)); + LOG_INFO("module", " White Trade Goods {}", GetItemCounts(AHB_WHITE_TG)); + LOG_INFO("module", " Green Trade Goods {}", GetItemCounts(AHB_GREEN_TG)); + LOG_INFO("module", " Blue Trade Goods {}", GetItemCounts(AHB_BLUE_TG)); + LOG_INFO("module", " Purple Trade Goods {}", GetItemCounts(AHB_PURPLE_TG)); + LOG_INFO("module", " Orange Trade Goods {}", GetItemCounts(AHB_ORANGE_TG)); + LOG_INFO("module", " Yellow Trade Goods {}", GetItemCounts(AHB_YELLOW_TG)); + LOG_INFO("module", " Grey Items {}", GetItemCounts(AHB_GREY_I)); + LOG_INFO("module", " White Items {}", GetItemCounts(AHB_WHITE_I)); + LOG_INFO("module", " Green Items {}", GetItemCounts(AHB_GREEN_I)); + LOG_INFO("module", " Blue Items {}", GetItemCounts(AHB_BLUE_I)); + LOG_INFO("module", " Purple Items {}", GetItemCounts(AHB_PURPLE_I)); + LOG_INFO("module", " Orange Items {}", GetItemCounts(AHB_ORANGE_I)); + LOG_INFO("module", " Yellow Items {}", GetItemCounts(AHB_YELLOW_I)); + } + + // + // Auctions buyer + // + + SetBuyerPrice(AHB_GREY , WorldDatabase.Query("SELECT buyerpricegrey FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetBuyerPrice(AHB_WHITE , WorldDatabase.Query("SELECT buyerpricewhite FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetBuyerPrice(AHB_GREEN , WorldDatabase.Query("SELECT buyerpricegreen FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetBuyerPrice(AHB_BLUE , WorldDatabase.Query("SELECT buyerpriceblue FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetBuyerPrice(AHB_PURPLE, WorldDatabase.Query("SELECT buyerpricepurple FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetBuyerPrice(AHB_ORANGE, WorldDatabase.Query("SELECT buyerpriceorange FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + SetBuyerPrice(AHB_YELLOW, WorldDatabase.Query("SELECT buyerpriceyellow FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + + // + // Load bidding interval + // + + SetBiddingInterval(WorldDatabase.Query("SELECT buyerbiddinginterval FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + + // + // Load bids per interval + // + + SetBidsPerInterval(WorldDatabase.Query("SELECT buyerbidsperinterval FROM mod_auctionhousebot WHERE auctionhouse = {}", GetAHID())->Fetch()->Get()); + + if (DebugOutConfig) + { + LOG_INFO("module", "Current Settings for Auctionhouse {} buyer", GetAHID()); + LOG_INFO("module", "buyerPriceGrey = {}", GetBuyerPrice(AHB_GREY)); + LOG_INFO("module", "buyerPriceWhite = {}", GetBuyerPrice(AHB_WHITE)); + LOG_INFO("module", "buyerPriceGreen = {}", GetBuyerPrice(AHB_GREEN)); + LOG_INFO("module", "buyerPriceBlue = {}", GetBuyerPrice(AHB_BLUE)); + LOG_INFO("module", "buyerPricePurple = {}", GetBuyerPrice(AHB_PURPLE)); + LOG_INFO("module", "buyerPriceOrange = {}", GetBuyerPrice(AHB_ORANGE)); + LOG_INFO("module", "buyerPriceYellow = {}", GetBuyerPrice(AHB_YELLOW)); + LOG_INFO("module", "buyerBiddingInterval = {}", GetBiddingInterval()); + LOG_INFO("module", "buyerBidsPerInterval = {}", GetBidsPerInterval()); + } + + // + // Reload the list of disabled items + // + + DisableItemStore.clear(); + + QueryResult result = WorldDatabase.Query("SELECT item FROM mod_auctionhousebot_disabled_items"); + + if (result) + { + do + { + Field* fields = result->Fetch(); + DisableItemStore.insert(fields[0].Get()); + } while (result->NextRow()); + } + + if (DebugOutConfig) + { + LOG_INFO("module", "Loaded {} items from the disabled item store", uint32(DisableItemStore.size())); + } + + // + // Reload the list of npc items + // + + NpcItems.clear(); + + QueryResult npcResults = WorldDatabase.Query("SELECT distinct item FROM npc_vendor"); + + if (npcResults) + { + do + { + Field* fields = npcResults->Fetch(); + NpcItems.insert(fields[0].Get()); + + } while (npcResults->NextRow()); + } + else + { + if (DebugOutConfig) + { + LOG_ERROR("module", "AuctionHouseBot: failed to retrieve npc items"); + } + } + + if (DebugOutConfig) + { + LOG_INFO("module", "Loaded {} items from NPCs", uint32(NpcItems.size())); + } + + // + // Reload the list from the lootable items + // + + LootItems.clear(); + + QueryResult itemsResults = WorldDatabase.Query( + "SELECT item FROM creature_loot_template UNION " + "SELECT item FROM reference_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"); + + if (itemsResults) + { + do + { + Field* fields = itemsResults->Fetch(); + LootItems.insert(fields[0].Get()); + + } while (itemsResults->NextRow()); + } + else + { + if (DebugOutConfig) + { + LOG_ERROR("module", "AuctionHouseBot: failed to retrieve loot items"); + } + } + + // + // Include profession items + // + + if (Profession_Items) + { + itemsResults = WorldDatabase.Query( + "SELECT item FROM auctionhousebot_professionItems"); + + if (itemsResults) + { + do + { + Field* fields = itemsResults->Fetch(); + uint32 item = fields[0].Get(); + + if(LootItems.find(item) == LootItems.end()) + { + LootItems.insert(fields[0].Get()); + } + } while (itemsResults->NextRow()); + } + } + + if (DebugOutConfig) + { + LOG_INFO("module", "Loaded {} items from lootable items", uint32(LootItems.size())); + } +} + +void AHBConfig::InitializeBins() +{ + // + // Exclude items depending on the configuration; whatever passes all the tests is put in the lists. + // + + ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore(); + + for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr) + { + + // + // Exclude items with the blocked binding type + // + + if (itr->second.Bonding == NO_BIND && !No_Bind) + { + continue; + } + + if (itr->second.Bonding == BIND_WHEN_PICKED_UP && !Bind_When_Picked_Up) + { + continue; + } + + if (itr->second.Bonding == BIND_WHEN_EQUIPPED && !Bind_When_Equipped) + { + continue; + } + + if (itr->second.Bonding == BIND_WHEN_USE && !Bind_When_Use) + { + continue; + } + + if (itr->second.Bonding == BIND_QUEST_ITEM && !Bind_Quest_Item) + { + continue; + } + + // + // Exclude items with no possible price + // + + if (UseBuyPriceForSeller) + { + if (itr->second.BuyPrice == 0) + { + continue; + } + } + else + { + if (itr->second.SellPrice == 0) + { + continue; + } + } + + // + // Exclude items with no costs associated, in any case + // + + if ((itr->second.BuyPrice == 0) && (itr->second.SellPrice == 0)) + { + continue; + } + + // + // Exlude items superior to the limit quality + // + + if (itr->second.Quality > 6) + { + continue; + } + + // + // Exclude trade goods items + // + + if (itr->second.Class == ITEM_CLASS_TRADE_GOODS) + { + bool isNpc = false; + bool isLoot = false; + bool exclude = false; + + if (NpcItems.find(itr->second.ItemId) != NpcItems.end()) + { + isNpc = true; + + if (!Vendor_TGs) + { + exclude = true; + } + } + + if (!exclude) + { + if (LootItems.find(itr->second.ItemId) != LootItems.end()) + { + isLoot = true; + + if (!Loot_TGs) + { + exclude = true; + } + } + } + + if (exclude) + { + continue; + } + + if (!Other_TGs) + { + if (!isNpc && !isLoot) + { + continue; + } + } + } + + // + // Exclude loot items + // + + if (itr->second.Class != ITEM_CLASS_TRADE_GOODS) + { + bool isNpc = false; + bool isLoot = false; + bool exclude = false; + + if (NpcItems.find(itr->second.ItemId) != NpcItems.end()) + { + isNpc = true; + + if (!Vendor_Items) + { + exclude = true; + } + } + + if (!exclude) + { + if (LootItems.find(itr->second.ItemId) != LootItems.end()) + { + isLoot = true; + + if (!Loot_Items) + { + exclude = true; + } + } + } + + if (exclude) + { + continue; + } + + if (!Other_Items) + { + if (!isNpc && !isLoot) + { + continue; + } + } + } + + // + // Verify if the item is disabled or not in the whitelist + // + + if (SellerWhiteList.size() == 0) + { + if (DisableItemStore.find(itr->second.ItemId) != DisableItemStore.end()) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (PTR/Beta/Unused Item)", itr->second.ItemId); + } + + continue; + } + } + else + { + if (SellerWhiteList.find(itr->second.ItemId) == SellerWhiteList.end()) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (not in the whitelist)", itr->second.ItemId); + } + + continue; + } + } + + // + // Disable permanent enchants items + // + + if ((DisablePermEnchant) && (itr->second.Class == ITEM_CLASS_PERMANENT)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Permanent Enchant Item)", itr->second.ItemId); + } + + continue; + } + + // + // Disable conjured items + // + + if ((DisableConjured) && (itr->second.IsConjuredConsumable())) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Conjured Consumable)", itr->second.ItemId); + } + + continue; + } + + // + // Disable gems + // + + if ((DisableGems) && (itr->second.Class == ITEM_CLASS_GEM)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Gem)", itr->second.ItemId); + } + + continue; + } + + // + // Disable money + // + + if ((DisableMoney) && (itr->second.Class == ITEM_CLASS_MONEY)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Money)", itr->second.ItemId); + } + + continue; + } + + // + // Disable moneyloot + // + + if ((DisableMoneyLoot) && (itr->second.MinMoneyLoot > 0)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (MoneyLoot)", itr->second.ItemId); + } + + continue; + } + + // + // Disable lootable items + // + + if ((DisableLootable) && (itr->second.Flags & 4)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Lootable Item)", itr->second.ItemId); + } + + continue; + } + + // + // Disable Keys + // + + if ((DisableKeys) && (itr->second.Class == ITEM_CLASS_KEY)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Quest Item)", itr->second.ItemId); + } + + continue; + } + + // + // Disable items with duration + // + + if ((DisableDuration) && (itr->second.Duration > 0)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Has a Duration)", itr->second.ItemId); + } + + continue; + } + + // + // Disable items which are BOP or Quest Items and have a required level lower than the item level + // + + if ((DisableBOP_Or_Quest_NoReqLevel) && ((itr->second.Bonding == BIND_WHEN_PICKED_UP || itr->second.Bonding == BIND_QUEST_ITEM) && (itr->second.RequiredLevel < itr->second.ItemLevel))) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (BOP or BQI and Required Level is less than Item Level)", itr->second.ItemId); + } + + continue; + } + + // + // Disable items specifically for Warrior + // + + if ((DisableWarriorItems) && (itr->second.AllowableClass == AHB_CLASS_WARRIOR)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Warrior Item)", itr->second.ItemId); + } + + continue; + } + + // + // Disable items specifically for Paladin + // + + if ((DisablePaladinItems) && (itr->second.AllowableClass == AHB_CLASS_PALADIN)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Paladin Item)", itr->second.ItemId); + } + + continue; + } + + // + // Disable items specifically for Hunter + // + + if ((DisableHunterItems) && (itr->second.AllowableClass == AHB_CLASS_HUNTER)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Hunter Item)", itr->second.ItemId); + } + + continue; + } + + // + // Disable items specifically for Rogue + // + + if ((DisableRogueItems) && (itr->second.AllowableClass == AHB_CLASS_ROGUE)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Rogue Item)", itr->second.ItemId); + } + + continue; + } + + // + // Disable items specifically for Priest + // + + if ((DisablePriestItems) && (itr->second.AllowableClass == AHB_CLASS_PRIEST)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Priest Item)", itr->second.ItemId); + } + + continue; + } + + // + // Disable items specifically for DK + // + + if ((DisableDKItems) && (itr->second.AllowableClass == AHB_CLASS_DK)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (DK Item)", itr->second.ItemId); + } + + continue; + } + + // + // Disable items specifically for Shaman + // + + if ((DisableShamanItems) && (itr->second.AllowableClass == AHB_CLASS_SHAMAN)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Shaman Item)", itr->second.ItemId); + } + + continue; + } + + // + // Disable items specifically for Mage + // + + if ((DisableMageItems) && (itr->second.AllowableClass == AHB_CLASS_MAGE)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Mage Item)", itr->second.ItemId); + } + + continue; + } + + // + // Disable items specifically for Warlock + // + + if ((DisableWarlockItems) && (itr->second.AllowableClass == AHB_CLASS_WARLOCK)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Warlock Item)", itr->second.ItemId); + } + + continue; + } + + // + // Disable items specifically for Unused Class + // + + if ((DisableUnusedClassItems) && (itr->second.AllowableClass == AHB_CLASS_UNUSED)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Unused Item)", itr->second.ItemId); + } + + continue; + } + + // + // Disable items specifically for Druid + // + + if ((DisableDruidItems) && (itr->second.AllowableClass == AHB_CLASS_DRUID)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Druid Item)", itr->second.ItemId); + } + + continue; + } + + // + // Disable Items below level X + // + + if ((DisableItemsBelowLevel) && (itr->second.Class != ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemLevel < DisableItemsBelowLevel)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Item Level = {})", itr->second.ItemId, itr->second.ItemLevel); + } + + continue; + } + + // + // Disable Items above level X + // + + if ((DisableItemsAboveLevel) && (itr->second.Class != ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemLevel > DisableItemsAboveLevel)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Item Level = {})", itr->second.ItemId, itr->second.ItemLevel); + } + + continue; + } + + // + // Disable Trade Goods below level X + // + + if ((DisableTGsBelowLevel) && (itr->second.Class == ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemLevel < DisableTGsBelowLevel)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Trade Good {} disabled (Trade Good Level = {})", itr->second.ItemId, itr->second.ItemLevel); + } + + continue; + } + + // + // Disable Trade Goods above level X + // + + if ((DisableTGsAboveLevel) && (itr->second.Class == ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemLevel > DisableTGsAboveLevel)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Trade Good {} disabled (Trade Good Level = {})", itr->second.ItemId, itr->second.ItemLevel); + } + + continue; + } + + // + // Disable Items below GUID X + // + + if ((DisableItemsBelowGUID) && (itr->second.Class != ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemId < DisableItemsBelowGUID)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Item Level = {})", itr->second.ItemId, itr->second.ItemLevel); + } + + continue; + } + + // + // Disable Items above GUID X + // + + if ((DisableItemsAboveGUID) && (itr->second.Class != ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemId > DisableItemsAboveGUID)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Item Level = {})", itr->second.ItemId, itr->second.ItemLevel); + } + + continue; + } + + // + // Disable Trade Goods below GUID X + // + + if ((DisableTGsBelowGUID) && (itr->second.Class == ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemId < DisableTGsBelowGUID)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Trade Good Level = {})", itr->second.ItemId, itr->second.ItemLevel); + } + + continue; + } + + // + // Disable Trade Goods above GUID X + // + + if ((DisableTGsAboveGUID) && (itr->second.Class == ITEM_CLASS_TRADE_GOODS) && (itr->second.ItemId > DisableTGsAboveGUID)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (Trade Good Level = {})", itr->second.ItemId, itr->second.ItemLevel); + } + + continue; + } + + // + // Disable Items for level lower than X + // + + if ((DisableItemsBelowReqLevel) && (itr->second.Class != ITEM_CLASS_TRADE_GOODS) && (itr->second.RequiredLevel < DisableItemsBelowReqLevel)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (RequiredLevel = {})", itr->second.ItemId, itr->second.RequiredLevel); + } + + continue; + } + + // + // Disable Items for level higher than X + // + + if ((DisableItemsAboveReqLevel) && (itr->second.Class != ITEM_CLASS_TRADE_GOODS) && (itr->second.RequiredLevel > DisableItemsAboveReqLevel)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (RequiredLevel = {})", itr->second.ItemId, itr->second.RequiredLevel); + } + + continue; + } + + // + // Disable Trade Goods for level lower than X + // + + if ((DisableTGsBelowReqLevel) && (itr->second.Class == ITEM_CLASS_TRADE_GOODS) && (itr->second.RequiredLevel < DisableTGsBelowReqLevel)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Trade Good {} disabled (RequiredLevel = {})", itr->second.ItemId, itr->second.RequiredLevel); + } + + continue; + } + + // + // Disable Trade Goods for level higher than X + // + + if ((DisableTGsAboveReqLevel) && (itr->second.Class == ITEM_CLASS_TRADE_GOODS) && (itr->second.RequiredLevel > DisableTGsAboveReqLevel)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Trade Good {} disabled (RequiredLevel = {})", itr->second.ItemId, itr->second.RequiredLevel); + } + + continue; + } + + // + // Disable Items that require skill lower than X + // + + if ((DisableItemsBelowReqSkillRank) && (itr->second.Class != ITEM_CLASS_TRADE_GOODS) && (itr->second.RequiredSkillRank < DisableItemsBelowReqSkillRank)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (RequiredSkillRank = {})", itr->second.ItemId, itr->second.RequiredSkillRank); + } + + continue; + } + + // + // Disable Items that require skill higher than X + // + + if ((DisableItemsAboveReqSkillRank) && (itr->second.Class != ITEM_CLASS_TRADE_GOODS) && (itr->second.RequiredSkillRank > DisableItemsAboveReqSkillRank)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (RequiredSkillRank = {})", itr->second.ItemId, itr->second.RequiredSkillRank); + } + + continue; + } + + // + // Disable Trade Goods that require skill lower than X + // + + if ((DisableTGsBelowReqSkillRank) && (itr->second.Class == ITEM_CLASS_TRADE_GOODS) && (itr->second.RequiredSkillRank < DisableTGsBelowReqSkillRank)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (RequiredSkillRank = {})", itr->second.ItemId, itr->second.RequiredSkillRank); + } + + continue; + } + + // + // Disable Trade Goods that require skill higher than X + // + + if ((DisableTGsAboveReqSkillRank) && (itr->second.Class == ITEM_CLASS_TRADE_GOODS) && (itr->second.RequiredSkillRank > DisableTGsAboveReqSkillRank)) + { + if (DebugOutFilters) + { + LOG_ERROR("module", "AuctionHouseBot: Item {} disabled (RequiredSkillRank = {})", itr->second.ItemId, itr->second.RequiredSkillRank); + } + + continue; + } + + // + // Now that the items passed all the tests, organize it by quality + // + + if (itr->second.Class == ITEM_CLASS_TRADE_GOODS) + { + switch (itr->second.Quality) + { + case AHB_GREY: + GreyTradeGoodsBin.insert(itr->second.ItemId); + break; + + case AHB_WHITE: + WhiteTradeGoodsBin.insert(itr->second.ItemId); + break; + + case AHB_GREEN: + GreenTradeGoodsBin.insert(itr->second.ItemId); + break; + + case AHB_BLUE: + BlueTradeGoodsBin.insert(itr->second.ItemId); + break; + + case AHB_PURPLE: + PurpleTradeGoodsBin.insert(itr->second.ItemId); + break; + + case AHB_ORANGE: + OrangeTradeGoodsBin.insert(itr->second.ItemId); + break; + + case AHB_YELLOW: + YellowTradeGoodsBin.insert(itr->second.ItemId); + break; + } + } + else + { + switch (itr->second.Quality) + { + case AHB_GREY: + GreyItemsBin.insert(itr->second.ItemId); + break; + + case AHB_WHITE: + WhiteItemsBin.insert(itr->second.ItemId); + break; + + case AHB_GREEN: + GreenItemsBin.insert(itr->second.ItemId); + break; + + case AHB_BLUE: + BlueItemsBin.insert(itr->second.ItemId); + break; + + case AHB_PURPLE: + PurpleItemsBin.insert(itr->second.ItemId); + break; + + case AHB_ORANGE: + OrangeItemsBin.insert(itr->second.ItemId); + break; + + case AHB_YELLOW: + YellowItemsBin.insert(itr->second.ItemId); + break; + } + } + } + + // + // Perform reporting and the last check: if no items are disabled or in the whitelist clear the bin making the selling useless + // + + LOG_INFO("module", "AHBot: Configuration for ah {}", AHID); + + if (SellerWhiteList.size() == 0) + { + if (DisableItemStore.size() == 0) + { + LOG_ERROR("module", "AHBot: No items are disabled or in the whitelist! Selling will be disabled!"); + + GreyTradeGoodsBin.clear(); + WhiteTradeGoodsBin.clear(); + GreenTradeGoodsBin.clear(); + BlueTradeGoodsBin.clear(); + PurpleTradeGoodsBin.clear(); + OrangeTradeGoodsBin.clear(); + YellowTradeGoodsBin.clear(); + GreyItemsBin.clear(); + WhiteItemsBin.clear(); + GreenItemsBin.clear(); + BlueItemsBin.clear(); + PurpleItemsBin.clear(); + OrangeItemsBin.clear(); + YellowItemsBin.clear(); + + AHBSeller = false; + + return; + } + + LOG_INFO("module", "AHBot: {} disabled items", uint32(DisableItemStore.size())); + } + else + { + LOG_INFO("module", "AHBot: Using a whitelist of {} items", uint32(SellerWhiteList.size())); + } + + LOG_INFO("module", "AHBot: loaded {} grey trade goods", uint32(GreyTradeGoodsBin.size())); + LOG_INFO("module", "AHBot: loaded {} white trade goods", uint32(WhiteTradeGoodsBin.size())); + LOG_INFO("module", "AHBot: loaded {} green trade goods", uint32(GreenTradeGoodsBin.size())); + LOG_INFO("module", "AHBot: loaded {} blue trade goods", uint32(BlueTradeGoodsBin.size())); + LOG_INFO("module", "AHBot: loaded {} purple trade goods", uint32(PurpleTradeGoodsBin.size())); + LOG_INFO("module", "AHBot: loaded {} orange trade goods", uint32(OrangeTradeGoodsBin.size())); + LOG_INFO("module", "AHBot: loaded {} yellow trade goods", uint32(YellowTradeGoodsBin.size())); + LOG_INFO("module", "AHBot: loaded {} grey items" , uint32(GreyItemsBin.size())); + LOG_INFO("module", "AHBot: loaded {} white items" , uint32(WhiteItemsBin.size())); + LOG_INFO("module", "AHBot: loaded {} green items" , uint32(GreenItemsBin.size())); + LOG_INFO("module", "AHBot: loaded {} blue items" , uint32(BlueItemsBin.size())); + LOG_INFO("module", "AHBot: loaded {} purple items" , uint32(PurpleItemsBin.size())); + LOG_INFO("module", "AHBot: loaded {} orange items" , uint32(OrangeItemsBin.size())); + LOG_INFO("module", "AHBot: loaded {} yellow items" , uint32(YellowItemsBin.size())); +} + +std::set AHBConfig::getCommaSeparatedIntegers(std::string text) +{ + std::string value; + std::stringstream stream; + std::set ret; + + stream.str(text); + + // + // Continue to precess comma separated values + // + + while (std::getline(stream, value, ',')) + { + ret.insert(atoi(value.c_str())); + } + + return ret; +} diff --git a/src/AuctionHouseBotConfig.h b/src/AuctionHouseBotConfig.h new file mode 100644 index 00000000..17cbab42 --- /dev/null +++ b/src/AuctionHouseBotConfig.h @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2008-2010 Trinity + * Copyright (C) 2005-2009 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 + */ + +#ifndef AUCTION_HOUSE_BOT_CONFIG_H +#define AUCTION_HOUSE_BOT_CONFIG_H + +#include +#include +#include + +#include "ObjectMgr.h" + +class AHBConfig +{ +private: + uint32 AHID; // Id + uint32 AHFID; // Faction id + + uint32 minItems; + uint32 maxItems; + + uint32 percentGreyTradeGoods; + uint32 percentWhiteTradeGoods; + uint32 percentGreenTradeGoods; + uint32 percentBlueTradeGoods; + uint32 percentPurpleTradeGoods; + uint32 percentOrangeTradeGoods; + uint32 percentYellowTradeGoods; + + uint32 percentGreyItems; + uint32 percentWhiteItems; + uint32 percentGreenItems; + uint32 percentBlueItems; + uint32 percentPurpleItems; + uint32 percentOrangeItems; + uint32 percentYellowItems; + + uint32 minPriceGrey; + uint32 maxPriceGrey; + uint32 minBidPriceGrey; + uint32 maxBidPriceGrey; + uint32 maxStackGrey; + + uint32 minPriceWhite; + uint32 maxPriceWhite; + uint32 minBidPriceWhite; + uint32 maxBidPriceWhite; + uint32 maxStackWhite; + + uint32 minPriceGreen; + uint32 maxPriceGreen; + uint32 minBidPriceGreen; + uint32 maxBidPriceGreen; + uint32 maxStackGreen; + + uint32 minPriceBlue; + uint32 maxPriceBlue; + uint32 minBidPriceBlue; + uint32 maxBidPriceBlue; + uint32 maxStackBlue; + + uint32 minPricePurple; + uint32 maxPricePurple; + uint32 minBidPricePurple; + uint32 maxBidPricePurple; + uint32 maxStackPurple; + + uint32 minPriceOrange; + uint32 maxPriceOrange; + uint32 minBidPriceOrange; + uint32 maxBidPriceOrange; + uint32 maxStackOrange; + + uint32 minPriceYellow; + uint32 maxPriceYellow; + uint32 minBidPriceYellow; + uint32 maxBidPriceYellow; + uint32 maxStackYellow; + + uint32 buyerPriceGrey; + uint32 buyerPriceWhite; + uint32 buyerPriceGreen; + uint32 buyerPriceBlue; + uint32 buyerPricePurple; + uint32 buyerPriceOrange; + uint32 buyerPriceYellow; + uint32 buyerBiddingInterval; + uint32 buyerBidsPerInterval; + + // + // Amount of items to be sold in absolute values + // + + uint32 greytgp; + uint32 whitetgp; + uint32 greentgp; + uint32 bluetgp; + uint32 purpletgp; + uint32 orangetgp; + uint32 yellowtgp; + + uint32 greyip; + uint32 whiteip; + uint32 greenip; + uint32 blueip; + uint32 purpleip; + uint32 orangeip; + uint32 yellowip; + + // + // Situation of the auction house + // + + uint32 greyTGoods; + uint32 whiteTGoods; + uint32 greenTGoods; + uint32 blueTGoods; + uint32 purpleTGoods; + uint32 orangeTGoods; + uint32 yellowTGoods; + + uint32 greyItems; + uint32 whiteItems; + uint32 greenItems; + uint32 blueItems; + uint32 purpleItems; + uint32 orangeItems; + uint32 yellowItems; + + // + // Per-item statistics + // + + std::map itemsCount; + std::map itemsSum; + std::map itemsPrice; + + void InitializeFromFile(); + void InitializeFromSql(std::set botsIds); + + std::set getCommaSeparatedIntegers(std::string text); + + void DecItemCounts(uint32 ahbotItemType); + void IncItemCounts(uint32 ahbotItemType); + +public: + // + // Debugging + // + + bool DebugOut; + bool DebugOutConfig; + bool DebugOutFilters; + bool DebugOutBuyer; + bool DebugOutSeller; + + // + // Tracing + // + + bool TraceSeller; + bool TraceBuyer; + + // + // Setup + // + + bool AHBSeller; + bool AHBBuyer; + bool UseBuyPriceForBuyer; + bool UseBuyPriceForSeller; + bool SellAtMarketPrice; + uint32 MarketResetThreshold; + bool ConsiderOnlyBotAuctions; + uint32 ItemsPerCycle; + + // + // Filters + // + + bool Vendor_Items; + bool Loot_Items; + bool Other_Items; + bool Vendor_TGs; + bool Loot_TGs; + bool Other_TGs; + bool Profession_Items; + + bool No_Bind; + bool Bind_When_Picked_Up; + bool Bind_When_Equipped; + bool Bind_When_Use; + bool Bind_Quest_Item; + + uint32 DuplicatesCount; + uint32 ElapsingTimeClass; + + bool DivisibleStacks; + bool DisablePermEnchant; + bool DisableConjured; + bool DisableGems; + bool DisableMoney; + bool DisableMoneyLoot; + bool DisableLootable; + bool DisableKeys; + bool DisableDuration; + bool DisableBOP_Or_Quest_NoReqLevel; + + bool DisableWarriorItems; + bool DisablePaladinItems; + bool DisableHunterItems; + bool DisableRogueItems; + bool DisablePriestItems; + bool DisableDKItems; + bool DisableShamanItems; + bool DisableMageItems; + bool DisableWarlockItems; + bool DisableUnusedClassItems; + bool DisableDruidItems; + + uint32 DisableItemsBelowLevel; + uint32 DisableItemsAboveLevel; + + uint32 DisableTGsBelowLevel; + uint32 DisableTGsAboveLevel; + + uint32 DisableItemsBelowGUID; + uint32 DisableItemsAboveGUID; + + uint32 DisableTGsBelowGUID; + uint32 DisableTGsAboveGUID; + + uint32 DisableItemsBelowReqLevel; + uint32 DisableItemsAboveReqLevel; + + uint32 DisableTGsBelowReqLevel; + uint32 DisableTGsAboveReqLevel; + + uint32 DisableItemsBelowReqSkillRank; + uint32 DisableItemsAboveReqSkillRank; + + uint32 DisableTGsBelowReqSkillRank; + uint32 DisableTGsAboveReqSkillRank; + + // + // Items validity for selling purposes + // + + std::set NpcItems; + std::set LootItems; + std::set DisableItemStore; + std::set SellerWhiteList; + + // + // Bins for trade goods. + // + + std::set GreyTradeGoodsBin; + std::set WhiteTradeGoodsBin; + std::set GreenTradeGoodsBin; + std::set BlueTradeGoodsBin; + std::set PurpleTradeGoodsBin; + std::set OrangeTradeGoodsBin; + std::set YellowTradeGoodsBin; + + // + // Bins for items + // + + std::set GreyItemsBin; + std::set WhiteItemsBin; + std::set GreenItemsBin; + std::set BlueItemsBin; + std::set PurpleItemsBin; + std::set OrangeItemsBin; + std::set YellowItemsBin; + + // + // Constructors/destructors + // + + AHBConfig(uint32 ahid, AHBConfig* conf); + AHBConfig(uint32 ahid); + AHBConfig(); + ~AHBConfig(); + + // + // Ruotines + // + + void Initialize(std::set botsIds); + void InitializeBins(); + void Reset(); + + uint32 GetAHID(); + uint32 GetAHFID(); + + void SetMinItems (uint32 value); + uint32 GetMinItems (); + + void SetMaxItems (uint32 value); + uint32 GetMaxItems (); + + void SetPercentages (uint32 greytg, uint32 whitetg, uint32 greentg, uint32 bluetg, uint32 purpletg, uint32 orangetg, uint32 yellowtg, + uint32 greyi , uint32 whitei , uint32 greeni , uint32 bluei , uint32 purplei , uint32 orangei , uint32 yellowi); + uint32 GetPercentages (uint32 color); + + void SetMinPrice (uint32 color, uint32 value); + uint32 GetMinPrice (uint32 color); + + void SetMaxPrice (uint32 color, uint32 value); + uint32 GetMaxPrice (uint32 color); + + void SetMinBidPrice (uint32 color, uint32 value); + uint32 GetMinBidPrice (uint32 color); + + void SetMaxBidPrice (uint32 color, uint32 value); + uint32 GetMaxBidPrice (uint32 color); + + void SetMaxStack (uint32 color, uint32 value); + uint32 GetMaxStack (uint32 color); + + void SetBuyerPrice (uint32 color, uint32 value); + uint32 GetBuyerPrice (uint32 color); + + void SetBiddingInterval(uint32 value); + uint32 GetBiddingInterval(); + + void SetBidsPerInterval(uint32 value); + uint32 GetBidsPerInterval(); + + void CalculatePercents (); + // max number of items of type in AH based on maxItems + uint32 GetMaximum (uint32 ahbotItemType); + + void DecItemCounts (uint32 Class, uint32 Quality); + + void IncItemCounts (uint32 Class, uint32 Quality); + + + void ResetItemCounts (); + uint32 TotalItemCounts (); + + uint32 GetItemCounts (uint32 color); + + void UpdateItemStats (uint32 id, uint32 stackSize, uint64 buyout); + uint64 GetItemPrice (uint32 id); +}; + +// +// Globally defined configurations +// + +extern AHBConfig* gAllianceConfig; +extern AHBConfig* gHordeConfig; +extern AHBConfig* gNeutralConfig; + +#endif // AUCTION_HOUSE_BOT_CONFIG_H diff --git a/src/AuctionHouseBotMailScript.cpp b/src/AuctionHouseBotMailScript.cpp new file mode 100644 index 00000000..1a115de5 --- /dev/null +++ b/src/AuctionHouseBotMailScript.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE + */ + +#include "AuctionHouseBot.h" +#include "AuctionHouseBotCommon.h" +#include "AuctionHouseBotMailScript.h" + +AHBot_MailScript::AHBot_MailScript() : MailScript("AHBot_MailScript", { + MAILHOOK_ON_BEFORE_MAIL_DRAFT_SEND_MAIL_TO +}) +{ + +} + +void AHBot_MailScript::OnBeforeMailDraftSendMailTo( + MailDraft*, /* mailDraft */ + MailReceiver const& receiver, + MailSender const& sender, + MailCheckMask&, /* checked */ + uint32&, /* deliver_delay */ + uint32&, /* custom_expiration */ + bool& deleteMailItemsFromDB, + bool& sendMail) +{ + // + // If the mail is for the bot, then remove it and delete the items bought + // + + if (gBotsId.find(receiver.GetPlayerGUIDLow()) != gBotsId.end()) + { + if (sender.GetMailMessageType() == MAIL_AUCTION) + { + deleteMailItemsFromDB = true; + } + + sendMail = false; + } +} diff --git a/src/AuctionHouseBotMailScript.h b/src/AuctionHouseBotMailScript.h new file mode 100644 index 00000000..bc906945 --- /dev/null +++ b/src/AuctionHouseBotMailScript.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE + */ + +#ifndef AUCTION_HOUSE_BOT_MAIL_SCRIPT_H +#define AUCTION_HOUSE_BOT_MAIL_SCRIPT_H + +#include "ScriptMgr.h" +#include "Mail.h" + +// ============================================================================= +// Interaction with the mailing systems +// ============================================================================= + +class AHBot_MailScript : public MailScript +{ +public: + AHBot_MailScript(); + + void OnBeforeMailDraftSendMailTo(MailDraft* mailDraft, MailReceiver const& receiver, MailSender const& sender, MailCheckMask& checked, uint32& deliver_delay, uint32& custom_expiration, bool& deleteMailItemsFromDB, bool& sendMail) override; +}; + +#endif /* AUCTION_HOUSE_BOT_MAIL_SCRIPT_H */ diff --git a/src/AuctionHouseBotScript.cpp b/src/AuctionHouseBotScript.cpp new file mode 100644 index 00000000..46bcbeae --- /dev/null +++ b/src/AuctionHouseBotScript.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE + */ + +#include "AuctionHouseBot.h" +#include "AuctionHouseBotAuctionHouseScript.h" +#include "AuctionHouseBotMailScript.h" +#include "AuctionHouseBotWorldScript.h" + +// ============================================================================= +// This provides the effective startup of the module by istanciating the scripts +// ============================================================================= + +void AddAHBotScripts() +{ + new AHBot_WorldScript(); + new AHBot_AuctionHouseScript(); + new AHBot_MailScript(); +} diff --git a/src/AuctionHouseBotWorldScript.cpp b/src/AuctionHouseBotWorldScript.cpp new file mode 100644 index 00000000..5ea95dad --- /dev/null +++ b/src/AuctionHouseBotWorldScript.cpp @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE + */ + +#include "Config.h" +#include "Log.h" + +#include "AuctionHouseBot.h" +#include "AuctionHouseBotCommon.h" +#include "AuctionHouseBotWorldScript.h" + +// ============================================================================= +// Initialization of the bot during the world startup +// ============================================================================= + +AHBot_WorldScript::AHBot_WorldScript() : WorldScript("AHBot_WorldScript", { + WORLDHOOK_ON_BEFORE_CONFIG_LOAD, + WORLDHOOK_ON_STARTUP +}) +{ + +} + +void AHBot_WorldScript::OnBeforeConfigLoad(bool reload) +{ + // + // Retrieve how many bots shall be operating on the auction market + // + + bool debug = sConfigMgr->GetOption ("AuctionHouseBot.DEBUG" , false); + uint32 account = sConfigMgr->GetOption("AuctionHouseBot.Account", 0); + uint32 player = sConfigMgr->GetOption("AuctionHouseBot.GUID" , 0); + + // + // All the bots bound to the provided account will be used for auctioning, if GUID is zero. + // Otherwise only the specified character is used. + // + + if (account == 0 && player == 0) + { + LOG_ERROR("server.loading", "AHBot: Account id and player id missing from configuration; is that the right file?"); + return; + } + else + { + QueryResult result = CharacterDatabase.Query("SELECT guid FROM characters WHERE account = {}", account); + + if (result) + { + gBotsId.clear(); + + do + { + Field* fields = result->Fetch(); + uint32 botId = fields[0].Get(); + + if (player == 0) + { + if (debug) + { + LOG_INFO("server.loading", "AHBot: New bot to start, account={} character={}", account, botId); + } + + gBotsId.insert(botId); + } + else + { + if (player == botId) + { + if (debug) + { + LOG_INFO("server.loading", "AHBot: Starting only one bot, account={} character={}", account, botId); + } + + gBotsId.insert(botId); + break; + } + } + + } while (result->NextRow()); + } + else + { + LOG_ERROR("server.loading", "AHBot: Could not query the database for characters of account {}", account); + return; + } + } + + if (gBotsId.size() == 0) + { + LOG_ERROR("server.loading", "AHBot: no characters registered for account {}", account); + return; + } + + // + // Start the bots only if the operation is a reload, otherwise let the OnStartup do the job + // + + if (reload) + { + if (debug) + { + LOG_INFO("module", "AHBot: Reloading the bots"); + } + + // + // Clear the bots array; this way they wont be used anymore during the initialization stage. + // + + DeleteBots(); + + // + // Reload the configuration for the auction houses + // + + gAllianceConfig->Initialize(gBotsId); + gHordeConfig->Initialize (gBotsId); + gNeutralConfig->Initialize (gBotsId); + + // + // Start again the bots + // + + PopulateBots(); + } +} + +void AHBot_WorldScript::OnStartup() +{ + LOG_INFO("server.loading", "Initialize AuctionHouseBot..."); + + // + // Initialize the configuration (done only once at startup) + // + + gAllianceConfig->Initialize(gBotsId); + gHordeConfig->Initialize (gBotsId); + gNeutralConfig->Initialize (gBotsId); + + // + // Starts the bots + // + + PopulateBots(); +} + +void AHBot_WorldScript::DeleteBots() +{ + // + // Save the old bots references. + // + + std::set oldBots; + + for (AuctionHouseBot* bot: gBots) + { + oldBots.insert(bot); + } + + // + // Clear the bot list + // + + gBots.clear(); + + // + // Free the resources used up by the old bots + // + + for (AuctionHouseBot* bot: oldBots) + { + delete bot; + } +} + + +void AHBot_WorldScript::PopulateBots() +{ + uint32 account = sConfigMgr->GetOption("AuctionHouseBot.Account", 0); + + // + // Insert the bot in the list used for auction house iterations + // + + gBots.clear(); + + for (uint32 id: gBotsId) + { + AuctionHouseBot* bot = new AuctionHouseBot(account, id); + bot->Initialize(gAllianceConfig, gHordeConfig, gNeutralConfig); + + gBots.insert(bot); + } +} diff --git a/src/AuctionHouseBotWorldScript.h b/src/AuctionHouseBotWorldScript.h new file mode 100644 index 00000000..069b0493 --- /dev/null +++ b/src/AuctionHouseBotWorldScript.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE + */ + +#ifndef AUCTION_HOUSE_BOT_WORLD_SCRIPT_H +#define AUCTION_HOUSE_BOT_WORLD_SCRIPT_H + +#include "ScriptMgr.h" + +// ============================================================================= +// Interaction with the world core mechanisms +// ============================================================================= + +class AHBot_WorldScript : public WorldScript +{ +private: + void DeleteBots(); + void PopulateBots(); + +public: + AHBot_WorldScript(); + + void OnBeforeConfigLoad(bool reload) override; + void OnStartup() override; +}; + +#endif /* AUCTION_HOUSE_BOT_WORLD_SCRIPT_H */ diff --git a/src/ah_bot_loader.cpp b/src/ah_bot_loader.cpp new file mode 100644 index 00000000..08c40df9 --- /dev/null +++ b/src/ah_bot_loader.cpp @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE + * Copyright (C) 2021+ WarheadCore + */ + +// From SC +void AddAHBotCommandScripts(); +void AddAHBotScripts(); + +// Add all +void Addmod_ah_botScripts() +{ + AddAHBotCommandScripts(); + AddAHBotScripts(); +} diff --git a/src/cs_ah_bot.cpp b/src/cs_ah_bot.cpp index e11d24be..5826d6c8 100644 --- a/src/cs_ah_bot.cpp +++ b/src/cs_ah_bot.cpp @@ -27,29 +27,156 @@ EndScriptData */ #include "AuctionHouseBot.h" #include "Config.h" +#if AC_COMPILER == AC_COMPILER_GNU +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + +using namespace Acore::ChatCommands; + class ah_bot_commandscript : public CommandScript { +private: + static ItemQualities stringToItemQualities(const char* name, int length) + { + // + // Translates a string into ItemQualities enum + // + + if (strncmp(name, "grey", length) == 0) + { + return ITEM_QUALITY_POOR; + } + + if (strncmp(name, "white", length) == 0) + { + return ITEM_QUALITY_NORMAL; + } + + if (strncmp(name, "green", length) == 0) + { + return ITEM_QUALITY_UNCOMMON; + } + + if (strncmp(name, "blue", length) == 0) + { + return ITEM_QUALITY_RARE; + } + + if (strncmp(name, "purple", length) == 0) + { + return ITEM_QUALITY_EPIC; + } + + if (strncmp(name, "orange", length) == 0) + { + return ITEM_QUALITY_LEGENDARY; + } + + if (strncmp(name, "yellow", length) == 0) + { + return ITEM_QUALITY_ARTIFACT; + } + + return static_cast(-1); // Invalid + } + public: - ah_bot_commandscript() : CommandScript("ah_bot_commandscript") { } + ah_bot_commandscript() : CommandScript("ah_bot_commandscript") + { + + } std::vector GetCommands() const override { static std::vector commandTable = { - { "ahbotoptions", SEC_GAMEMASTER, true, &HandleAHBotOptionsCommand, "" }, + { "ahbotoptions", HandleAHBotOptionsCommand, SEC_GAMEMASTER, Console::Yes } }; + return commandTable; } static bool HandleAHBotOptionsCommand(ChatHandler* handler, const char*args) { uint32 ahMapID = 0; - char* opt = strtok((char*)args, " "); + char* opt = strtok((char*)args, " "); + + if (!opt) + { + handler->PSendSysMessage("Invalid syntax"); + handler->PSendSysMessage("Try ahbotoptions help to see a list of options."); + + return false; + } + + // + // Commands which does not requires an AH + // + + int l = strlen(opt); + + if (strncmp(opt, "buyer", l) == 0) + { + char* param1 = strtok(NULL, " "); + + if (!param1) + { + handler->PSendSysMessage("Syntax is: ahbotoptions buyer $state (0 off 1 on)"); + return false; + } + + for (AuctionHouseBot* bot: gBots) + { + bot->Commands(AHBotCommand::buyer, 0, 0, param1); + } + + return true; + } + else if (strncmp(opt, "seller", l) == 0) + { + char* param1 = strtok(NULL, " "); + + if (!param1) + { + handler->PSendSysMessage("Syntax is: ahbotoptions seller $state (0 off 1 on)"); + return false; + } + + for (AuctionHouseBot* bot: gBots) + { + bot->Commands(AHBotCommand::seller, 0, 0, param1); + } + + return true; + } + else if (strncmp(opt, "usemarketprice", l) == 0) + { + char* param1 = strtok(NULL, " "); + + if (!param1) + { + handler->PSendSysMessage("Syntax is: ahbotoptions useMarketPrice $state (0 off 1 on)"); + return false; + } + + for (AuctionHouseBot* bot : gBots) + { + bot->Commands(AHBotCommand::useMarketPrice, 0, 0, param1); + } + + return true; + } + + // + // Retrieve the auction house type + // + char* ahMapIdStr = strtok(NULL, " "); if (ahMapIdStr) { ahMapID = uint32(strtoul(ahMapIdStr, NULL, 0)); + switch (ahMapID) { case 2: @@ -62,32 +189,39 @@ class ah_bot_commandscript : public CommandScript } } + // + // Syntax check + // + if (!opt) { - handler->PSendSysMessage("Syntax is: ahbotoptions $option $ahMapID (2, 6 or 7) $parameter"); - handler->PSendSysMessage("Try ahbotoptions help to see a list of options."); + handler->PSendSysMessage("Invalid syntax; the auction house id must be 2, 6 or 7"); return false; } - int l = strlen(opt); + // + // Commands that do requires an AH id to be performed + // if (strncmp(opt, "help", l) == 0) { handler->PSendSysMessage("AHBot commands:"); - handler->PSendSysMessage("ahexpire"); - handler->PSendSysMessage("minitems"); - handler->PSendSysMessage("maxitems"); - //handler->PSendSysMessage(""); - //handler->PSendSysMessage(""); - handler->PSendSysMessage("percentages"); - handler->PSendSysMessage("minprice"); - handler->PSendSysMessage("maxprice"); - handler->PSendSysMessage("minbidprice"); - handler->PSendSysMessage("maxbidprice"); - handler->PSendSysMessage("maxstack"); - handler->PSendSysMessage("buyerprice"); - handler->PSendSysMessage("bidinterval"); - handler->PSendSysMessage("bidsperinterval"); + handler->PSendSysMessage("buyer - enable/disable buyer"); + handler->PSendSysMessage("seller - enable/disabler seller"); + handler->PSendSysMessage("usemarketprice - enable/disabler selling at market price"); + handler->PSendSysMessage("ahexpire - remove all bot auctions"); + handler->PSendSysMessage("minitems - set min auctions"); + handler->PSendSysMessage("maxitems - set max auctions"); + handler->PSendSysMessage("percentages - set selling percentages"); + handler->PSendSysMessage("minprice - set min price"); + handler->PSendSysMessage("maxprice - set max price"); + handler->PSendSysMessage("minbidprice - set min bid price for buyer"); + handler->PSendSysMessage("maxbidprice - set max bid price for buyer"); + handler->PSendSysMessage("maxstack - set max stack"); + handler->PSendSysMessage("buyerprice - set the buyer price policy"); + handler->PSendSysMessage("bidinterval - set the bid interval for buyer"); + handler->PSendSysMessage("bidsperinterval - set the bid amount for buyer"); + return true; } else if (strncmp(opt, "ahexpire", l) == 0) @@ -98,71 +232,52 @@ class ah_bot_commandscript : public CommandScript return false; } - auctionbot->Commands(0, ahMapID, NULL, NULL); + for (AuctionHouseBot* bot: gBots) + { + bot->Commands(AHBotCommand::ahexpire, ahMapID, 0, NULL); + } } else if (strncmp(opt, "minitems", l) == 0) { char* param1 = strtok(NULL, " "); + if (!ahMapIdStr || !param1) { handler->PSendSysMessage("Syntax is: ahbotoptions minitems $ahMapID (2, 6 or 7) $minItems"); return false; } - auctionbot->Commands(1, ahMapID, NULL, param1); - } - else if (strncmp(opt, "maxitems", l) == 0) - { - char* param1 = strtok(NULL, " "); - if (!ahMapIdStr || !param1) + for (AuctionHouseBot* bot : gBots) { - handler->PSendSysMessage("Syntax is: ahbotoptions maxitems $ahMapID (2, 6 or 7) $maxItems"); - return false; + bot->Commands(AHBotCommand::minitems, ahMapID, 0, param1); } - - auctionbot->Commands(2, ahMapID, NULL, param1); } - else if (strncmp(opt, "mintime", l) == 0) + else if (strncmp(opt, "maxitems", l) == 0) { - handler->PSendSysMessage("ahbotoptions mintime has been deprecated"); - return false; - /* char* param1 = strtok(NULL, " "); + if (!ahMapIdStr || !param1) { - PSendSysMessage("Syntax is: ahbotoptions mintime $ahMapID (2, 6 or 7) $mintime"); + handler->PSendSysMessage("Syntax is: ahbotoptions maxitems $ahMapID (2, 6 or 7) $maxItems"); return false; } - auctionbot.Commands(3, ahMapID, NULL, param1); - */ - } - else if (strncmp(opt, "maxtime", l) == 0) - { - handler->PSendSysMessage("ahbotoptions maxtime has been deprecated"); - return false; - /* - char* param1 = strtok(NULL, " "); - if (!ahMapIdStr || !param1) + for (AuctionHouseBot* bot: gBots) { - PSendSysMessage("Syntax is: ahbotoptions maxtime $ahMapID (2, 6 or 7) $maxtime"); - return false; + bot->Commands(AHBotCommand::maxitems, ahMapID, 0, param1); } - - auctionbot.Commands(4, ahMapID, NULL, param1); - */ } else if (strncmp(opt, "percentages", l) == 0) { - char* param1 = strtok(NULL, " "); - char* param2 = strtok(NULL, " "); - char* param3 = strtok(NULL, " "); - char* param4 = strtok(NULL, " "); - char* param5 = strtok(NULL, " "); - char* param6 = strtok(NULL, " "); - char* param7 = strtok(NULL, " "); - char* param8 = strtok(NULL, " "); - char* param9 = strtok(NULL, " "); + char* param1 = strtok(NULL, " "); + char* param2 = strtok(NULL, " "); + char* param3 = strtok(NULL, " "); + char* param4 = strtok(NULL, " "); + char* param5 = strtok(NULL, " "); + char* param6 = strtok(NULL, " "); + char* param7 = strtok(NULL, " "); + char* param8 = strtok(NULL, " "); + char* param9 = strtok(NULL, " "); char* param10 = strtok(NULL, " "); char* param11 = strtok(NULL, " "); char* param12 = strtok(NULL, " "); @@ -175,38 +290,36 @@ class ah_bot_commandscript : public CommandScript handler->PSendSysMessage("1 GreyTradeGoods 2 WhiteTradeGoods 3 GreenTradeGoods 4 BlueTradeGoods 5 PurpleTradeGoods"); handler->PSendSysMessage("6 OrangeTradeGoods 7 YellowTradeGoods 8 GreyItems 9 WhiteItems 10 GreenItems 11 BlueItems"); handler->PSendSysMessage("12 PurpleItems 13 OrangeItems 14 YellowItems"); - handler->PSendSysMessage("The total must add up to 100%%"); + return false; } - uint32 greytg = uint32(strtoul(param1, NULL, 0)); - uint32 whitetg = uint32(strtoul(param2, NULL, 0)); - uint32 greentg = uint32(strtoul(param3, NULL, 0)); - uint32 bluetg = uint32(strtoul(param3, NULL, 0)); - uint32 purpletg = uint32(strtoul(param5, NULL, 0)); - uint32 orangetg = uint32(strtoul(param6, NULL, 0)); - uint32 yellowtg = uint32(strtoul(param7, NULL, 0)); - uint32 greyi = uint32(strtoul(param8, NULL, 0)); - uint32 whitei = uint32(strtoul(param9, NULL, 0)); - uint32 greeni = uint32(strtoul(param10, NULL, 0)); - uint32 bluei = uint32(strtoul(param11, NULL, 0)); - uint32 purplei = uint32(strtoul(param12, NULL, 0)); - uint32 orangei = uint32(strtoul(param13, NULL, 0)); - uint32 yellowi = uint32(strtoul(param14, NULL, 0)); + uint32 greytg = uint32(strtoul(param1 , NULL, 0)); + uint32 whitetg = uint32(strtoul(param2 , NULL, 0)); + uint32 greentg = uint32(strtoul(param3 , NULL, 0)); + uint32 bluetg = uint32(strtoul(param4 , NULL, 0)); + uint32 purpletg = uint32(strtoul(param5 , NULL, 0)); + uint32 orangetg = uint32(strtoul(param6 , NULL, 0)); + uint32 yellowtg = uint32(strtoul(param7 , NULL, 0)); + uint32 greyi = uint32(strtoul(param8 , NULL, 0)); + uint32 whitei = uint32(strtoul(param9 , NULL, 0)); + uint32 greeni = uint32(strtoul(param10, NULL, 0)); + uint32 bluei = uint32(strtoul(param11, NULL, 0)); + uint32 purplei = uint32(strtoul(param12, NULL, 0)); + uint32 orangei = uint32(strtoul(param13, NULL, 0)); + uint32 yellowi = uint32(strtoul(param14, NULL, 0)); + uint32 totalPercent = greytg + whitetg + greentg + bluetg + purpletg + orangetg + yellowtg + greyi + whitei + greeni + bluei + purplei + orangei + yellowi; if (totalPercent == 0 || totalPercent != 100) { - handler->PSendSysMessage("Syntax is: ahbotoptions percentages $ahMapID (2, 6 or 7) $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14"); - handler->PSendSysMessage("1 GreyTradeGoods 2 WhiteTradeGoods 3 GreenTradeGoods 4 BlueTradeGoods 5 PurpleTradeGoods"); - handler->PSendSysMessage("6 OrangeTradeGoods 7 YellowTradeGoods 8 GreyItems 9 WhiteItems 10 GreenItems 11 BlueItems"); - handler->PSendSysMessage("12 PurpleItems 13 OrangeItems 14 YellowItems"); handler->PSendSysMessage("The total must add up to 100%%"); + return false; } - char param[100]; - param[0] = '\0'; + char param[100] = { 0 }; + strcat(param, param1); strcat(param, " "); strcat(param, param2); @@ -234,7 +347,11 @@ class ah_bot_commandscript : public CommandScript strcat(param, param13); strcat(param, " "); strcat(param, param14); - auctionbot->Commands(5, ahMapID, NULL, param); + + for (AuctionHouseBot* bot: gBots) + { + bot->Commands(AHBotCommand::percentages, ahMapID, 0, param); + } } else if (strncmp(opt, "minprice", l) == 0) { @@ -247,20 +364,15 @@ class ah_bot_commandscript : public CommandScript return false; } - if (strncmp(param1, "grey", l) == 0) - auctionbot->Commands(6, ahMapID, AHB_GREY, param2); - else if (strncmp(param1, "white", l) == 0) - auctionbot->Commands(6, ahMapID, AHB_WHITE, param2); - else if (strncmp(param1, "green", l) == 0) - auctionbot->Commands(6, ahMapID, AHB_GREEN, param2); - else if (strncmp(param1, "blue", l) == 0) - auctionbot->Commands(6, ahMapID, AHB_BLUE, param2); - else if (strncmp(param1, "purple", l) == 0) - auctionbot->Commands(6, ahMapID, AHB_PURPLE, param2); - else if (strncmp(param1, "orange", l) == 0) - auctionbot->Commands(6, ahMapID, AHB_ORANGE, param2); - else if (strncmp(param1, "yellow", l) == 0) - auctionbot->Commands(6, ahMapID, AHB_YELLOW, param2); + auto quality = stringToItemQualities(param1, l); + + if (quality != static_cast(-1)) + { + for (AuctionHouseBot* bot: gBots) + { + bot->Commands(AHBotCommand::minprice, ahMapID, quality, param2); + } + } else { handler->PSendSysMessage("Syntax is: ahbotoptions minprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); @@ -271,25 +383,22 @@ class ah_bot_commandscript : public CommandScript { char* param1 = strtok(NULL, " "); char* param2 = strtok(NULL, " "); + if (!ahMapIdStr || !param1 || !param2) { handler->PSendSysMessage("Syntax is: ahbotoptions maxprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); return false; } - if (strncmp(param1, "grey", l) == 0) - auctionbot->Commands(7, ahMapID, AHB_GREY, param2); - else if (strncmp(param1, "white", l) == 0) - auctionbot->Commands(7, ahMapID, AHB_WHITE, param2); - else if (strncmp(param1, "green", l) == 0) - auctionbot->Commands(7, ahMapID, AHB_GREEN, param2); - else if (strncmp(param1, "blue", l) == 0) - auctionbot->Commands(7, ahMapID, AHB_BLUE, param2); - else if (strncmp(param1, "purple", l) == 0) - auctionbot->Commands(7, ahMapID, AHB_PURPLE, param2); - else if (strncmp(param1, "orange",l) == 0) - auctionbot->Commands(7, ahMapID, AHB_ORANGE, param2); - else if (strncmp(param1, "yellow", l) == 0) - auctionbot->Commands(7, ahMapID, AHB_YELLOW, param2); + + auto quality = stringToItemQualities(param1, l); + + if (quality != static_cast(-1)) + { + for (AuctionHouseBot* bot: gBots) + { + bot->Commands(AHBotCommand::maxprice, ahMapID, quality, param2); + } + } else { handler->PSendSysMessage("Syntax is: ahbotoptions maxprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); @@ -308,26 +417,22 @@ class ah_bot_commandscript : public CommandScript } uint32 minBidPrice = uint32(strtoul(param2, NULL, 0)); + if (minBidPrice < 1 || minBidPrice > 100) { handler->PSendSysMessage("The min bid price multiplier must be between 1 and 100"); return false; } - if (strncmp(param1, "grey", l) == 0) - auctionbot->Commands(8, ahMapID, AHB_GREY, param2); - else if (strncmp(param1, "white", l) == 0) - auctionbot->Commands(8, ahMapID, AHB_WHITE, param2); - else if (strncmp(param1, "green", l) == 0) - auctionbot->Commands(8, ahMapID, AHB_GREEN, param2); - else if (strncmp(param1, "blue", l) == 0) - auctionbot->Commands(8, ahMapID, AHB_BLUE, param2); - else if (strncmp(param1, "purple", l) == 0) - auctionbot->Commands(8, ahMapID, AHB_PURPLE, param2); - else if (strncmp(param1, "orange", l) == 0) - auctionbot->Commands(8, ahMapID, AHB_ORANGE, param2); - else if (strncmp(param1, "yellow", l) == 0) - auctionbot->Commands(8, ahMapID, AHB_YELLOW, param2); + auto quality = stringToItemQualities(param1, l); + + if (quality != static_cast(-1)) + { + for (AuctionHouseBot* bot: gBots) + { + bot->Commands(AHBotCommand::minbidprice, ahMapID, quality, param2); + } + } else { handler->PSendSysMessage("Syntax is: ahbotoptions minbidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); @@ -346,26 +451,22 @@ class ah_bot_commandscript : public CommandScript } uint32 maxBidPrice = uint32(strtoul(param2, NULL, 0)); + if (maxBidPrice < 1 || maxBidPrice > 100) { handler->PSendSysMessage("The max bid price multiplier must be between 1 and 100"); return false; } - if (strncmp(param1, "grey", l) == 0) - auctionbot->Commands(9, ahMapID, AHB_GREY, param2); - else if (strncmp(param1, "white", l) == 0) - auctionbot->Commands(9, ahMapID, AHB_WHITE, param2); - else if (strncmp(param1, "green", l) == 0) - auctionbot->Commands(9, ahMapID, AHB_GREEN, param2); - else if (strncmp(param1, "blue", l) == 0) - auctionbot->Commands(9, ahMapID, AHB_BLUE, param2); - else if (strncmp(param1, "purple", l) == 0) - auctionbot->Commands(9, ahMapID, AHB_PURPLE, param2); - else if (strncmp(param1, " orange", l) == 0) - auctionbot->Commands(9, ahMapID, AHB_ORANGE, param2); - else if (strncmp(param1, "yellow", l) == 0) - auctionbot->Commands(9, ahMapID, AHB_YELLOW, param2); + auto quality = stringToItemQualities(param1, l); + + if (quality != static_cast(-1)) + { + for (AuctionHouseBot* bot: gBots) + { + bot->Commands(AHBotCommand::maxbidprice, ahMapID, quality, param2); + } + } else { handler->PSendSysMessage("Syntax is: ahbotoptions max bidprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $price"); @@ -390,20 +491,15 @@ class ah_bot_commandscript : public CommandScript // return false; // } - if (strncmp(param1, "grey",l) == 0) - auctionbot->Commands(10, ahMapID, AHB_GREY, param2); - else if (strncmp(param1, "white", l) == 0) - auctionbot->Commands(10, ahMapID, AHB_WHITE, param2); - else if (strncmp(param1, "green", l) == 0) - auctionbot->Commands(10, ahMapID, AHB_GREEN, param2); - else if (strncmp(param1, "blue", l) == 0) - auctionbot->Commands(10, ahMapID, AHB_BLUE, param2); - else if (strncmp(param1, "purple", l) == 0) - auctionbot->Commands(10, ahMapID, AHB_PURPLE, param2); - else if (strncmp(param1, "orange", l) == 0) - auctionbot->Commands(10, ahMapID, AHB_ORANGE, param2); - else if (strncmp(param1, "yellow", l) == 0) - auctionbot->Commands(10, ahMapID, AHB_YELLOW, param2); + auto quality = stringToItemQualities(param1, l); + + if (quality != static_cast(-1)) + { + for (AuctionHouseBot* bot: gBots) + { + bot->Commands(AHBotCommand::maxstack, ahMapID, quality, param2); + } + } else { handler->PSendSysMessage("Syntax is: ahbotoptions maxstack $ahMapID (2, 6 or 7) $color (grey, white, green, blue, purple, orange or yellow) $value"); @@ -421,20 +517,15 @@ class ah_bot_commandscript : public CommandScript return false; } - if (strncmp(param1, "grey", l) == 0) - auctionbot->Commands(11, ahMapID, AHB_GREY, param2); - else if (strncmp(param1, "white", l) == 0) - auctionbot->Commands(11, ahMapID, AHB_WHITE, param2); - else if (strncmp(param1, "green", l) == 0) - auctionbot->Commands(11, ahMapID, AHB_GREEN, param2); - else if (strncmp(param1, "blue", l) == 0) - auctionbot->Commands(11, ahMapID, AHB_BLUE, param2); - else if (strncmp(param1, "purple", l) == 0) - auctionbot->Commands(11, ahMapID, AHB_PURPLE, param2); - else if (strncmp(param1, "orange", l) == 0) - auctionbot->Commands(11, ahMapID, AHB_ORANGE, param2); - else if (strncmp(param1, "yellow", l) == 0) - auctionbot->Commands(11, ahMapID, AHB_YELLOW, param2); + auto quality = stringToItemQualities(param1, l); + + if (quality != static_cast(-1)) + { + for (AuctionHouseBot* bot: gBots) + { + bot->Commands(AHBotCommand::buyerprice, ahMapID, quality, param2); + } + } else { handler->PSendSysMessage("Syntax is: ahbotoptions buyerprice $ahMapID (2, 6 or 7) $color (grey, white, green, blue or purple) $price"); @@ -451,7 +542,10 @@ class ah_bot_commandscript : public CommandScript return false; } - auctionbot->Commands(12, ahMapID, NULL, param1); + for (AuctionHouseBot* bot: gBots) + { + bot->Commands(AHBotCommand::bidinterval, ahMapID, 0, param1); + } } else if (strncmp(opt, "bidsperinterval", l) == 0) { @@ -463,20 +557,24 @@ class ah_bot_commandscript : public CommandScript return false; } - auctionbot->Commands(13, ahMapID, NULL, param1); + for (AuctionHouseBot* bot: gBots) + { + bot->Commands(AHBotCommand::bidsperinterval, ahMapID, 0, param1); + } } else { - handler->PSendSysMessage("Syntax is: ahbotoptions $option $ahMapID (2, 6 or 7) $parameter"); + handler->PSendSysMessage("Invalid syntax"); handler->PSendSysMessage("Try ahbotoptions help to see a list of options."); return false; } + handler->PSendSysMessage("Done"); return true; } }; -void AddSC_ah_bot_commandscript() +void AddAHBotCommandScripts() { new ah_bot_commandscript(); } diff --git a/src/loader_cs_ah_bot.h b/src/loader_cs_ah_bot.h deleted file mode 100644 index cb0a5750..00000000 --- a/src/loader_cs_ah_bot.h +++ /dev/null @@ -1,6 +0,0 @@ -void AddSC_ah_bot_commandscript(); - -void AddAHBotCommandScripts() -{ - AddSC_ah_bot_commandscript(); -}