diff --git a/README.md b/README.md index 810b8e7..9c0c917 100644 --- a/README.md +++ b/README.md @@ -16,29 +16,55 @@ 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. 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) or with the `db_assembler.sh` (if `include.sh` provided). +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. ``` -## 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. - ## 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. 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: ported the bot to AzerothCore diff --git a/conf/mod_ahbot.conf.dist b/conf/mod_ahbot.conf.dist index f4e3762..293b0f0 100644 --- a/conf/mod_ahbot.conf.dist +++ b/conf/mod_ahbot.conf.dist @@ -47,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 @@ -62,6 +73,8 @@ # 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 @@ -81,7 +94,6 @@ # 2 = shorts, auctions lasts within an hour # Default 1 # -# ############################################################################### AuctionHouseBot.DEBUG = 0 @@ -96,6 +108,8 @@ 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 diff --git a/data/sql/db-world/mod_auctionhousebot.sql b/data/sql/db-world/mod_auctionhousebot.sql index 12aaa00..ead151d 100644 --- a/data/sql/db-world/mod_auctionhousebot.sql +++ b/data/sql/db-world/mod_auctionhousebot.sql @@ -1,3 +1,7 @@ +-- +-- 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.', @@ -65,20 +69,30 @@ CREATE TABLE `mod_auctionhousebot` ( PRIMARY KEY (`auctionhouse`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -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; +-- +-- AHBot auction houses default configuration values +-- --- AHBot auctionhouse configuration 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 unavailable to players +-- +-- 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), diff --git a/src/AuctionHouseBot.cpp b/src/AuctionHouseBot.cpp index 65a6646..dc14815 100644 --- a/src/AuctionHouseBot.cpp +++ b/src/AuctionHouseBot.cpp @@ -82,7 +82,7 @@ uint32 AuctionHouseBot::getStackCount(AHBConfig* config, uint32 max) ret = urand(1, 4) * 4; } - if (max % 3 == 0) // 3, 6, 9 + if (max % 3 == 0) // 3, 6, 9, 18 { ret = urand(1, 3) * 3; } @@ -413,7 +413,7 @@ void AuctionHouseBot::Buy(Player* AHBplayer, AHBConfig* config, WorldSession* se // // Perform a new bid on the auction // - + if (auction->bidder) { if (auction->bidder != AHBplayer->GetGUID()) @@ -421,21 +421,21 @@ void AuctionHouseBot::Buy(Player* AHBplayer, AHBConfig* config, WorldSession* se // // Mail to last bidder and return their money // - + auto trans = CharacterDatabase.BeginTransaction(); - + sAuctionMgr->SendAuctionOutbiddedMail(auction, bidprice, session->GetPlayer(), trans); CharacterDatabase.CommitTransaction (trans); } } - + auction->bidder = AHBplayer->GetGUID(); auction->bid = bidprice; - + // // Save the auction into database // - + CharacterDatabase.Execute("UPDATE auctionhouse SET buyguid = '{}', lastbid = '{}' WHERE id = '{}'", auction->bidder.GetCounter(), auction->bid, auction->Id); } else @@ -487,11 +487,11 @@ void AuctionHouseBot::Buy(Player* AHBplayer, AHBConfig* config, WorldSession* se { if (bought) { - LOG_INFO("module", "AHBot [{}]: Bought , id={}, ah={}, item={}, start={}, current={}, buyout={}", _id, auction->Id, auction->GetHouseId(), auction->item_template, auction->startbid, currentprice, auction->buyout); + LOG_INFO("module", "AHBot [{}]: Bought , id={}, ah={}, item={}, start={}, current={}, buyout={}", _id, prototype->ItemId, auction->GetHouseId(), auction->item_template, auction->startbid, currentprice, auction->buyout); } else { - LOG_INFO("module", "AHBot [{}]: New bid, id={}, ah={}, item={}, start={}, current={}, buyout={}", _id, auction->Id, auction->GetHouseId(), auction->item_template, auction->startbid, currentprice, auction->buyout); + LOG_INFO("module", "AHBot [{}]: New bid, id={}, ah={}, item={}, start={}, current={}, buyout={}", _id, prototype->ItemId, auction->GetHouseId(), auction->item_template, auction->startbid, currentprice, auction->buyout); } } } @@ -938,54 +938,65 @@ void AuctionHouseBot::Sell(Player* AHBplayer, AHBConfig* config) item->SetItemRandomProperties(randomPropertyId); } + if (prototype->Quality > AHB_MAX_QUALITY) + { + err++; + + if (config->DebugOutSeller) + { + LOG_ERROR("module", "AHBot [{}]: Quality {} TOO HIGH for item {}", _id, prototype->Quality, itemID); + } + + item->RemoveFromUpdateQueueOf(AHBplayer); + continue; + } + // - // Determine the price and stack size + // Determine the price // uint64 buyoutPrice = 0; uint64 bidPrice = 0; uint32 stackCount = 1; - if (config->SellMethod) + if (config->SellAtMarketPrice) { - buyoutPrice = prototype->BuyPrice; - } - else - { - buyoutPrice = prototype->SellPrice; + buyoutPrice = config->GetItemPrice(itemID); } - if (prototype->Quality <= AHB_MAX_QUALITY) + if (buyoutPrice == 0) { - if (config->GetMaxStack(prototype->Quality) > 1 && item->GetMaxStackCount() > 1) + if (config->SellMethod) { - 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()); + buyoutPrice = prototype->BuyPrice; } else { - stackCount = 1; + buyoutPrice = prototype->SellPrice; } + } + + buyoutPrice = buyoutPrice * urand(config->GetMinPrice(prototype->Quality), config->GetMaxPrice(prototype->Quality)); + buyoutPrice = buyoutPrice / 100; + + bidPrice = buyoutPrice * urand(config->GetMinBidPrice(prototype->Quality), config->GetMaxBidPrice(prototype->Quality)); + bidPrice = bidPrice / 100; - 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; + // + // Determine the stack size + // + + 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 { - err++; - - if (config->DebugOutSeller) - { - LOG_ERROR("module", "AHBot [{}]: Quality {} TOO HIGH for item {}", _id, prototype->Quality, itemID); - } - - item->RemoveFromUpdateQueueOf(AHBplayer); - continue; + stackCount = 1; } item->SetCount(stackCount); @@ -1222,7 +1233,7 @@ void AuctionHouseBot::Commands(AHBotCommand command, uint32 ahMapID, uint32 col, case 6: config = _hordeConfig; break; - case 7: + default: config = _neutralConfig; break; } @@ -1273,13 +1284,15 @@ void AuctionHouseBot::Commands(AHBotCommand command, uint32 ahMapID, uint32 col, if (state == 0) { - config->AHBBuyer = false; - LOG_ERROR("module", "AHBot: Buyer disabled from console"); + _allianceConfig->AHBBuyer = false; + _hordeConfig->AHBBuyer = false; + _neutralConfig->AHBBuyer = false; } else { - config->AHBBuyer = true; - LOG_ERROR("module", "AHBot: Buyer enabled from console"); + _allianceConfig->AHBBuyer = true; + _hordeConfig->AHBBuyer = true; + _neutralConfig->AHBBuyer = true; } break; @@ -1291,13 +1304,35 @@ void AuctionHouseBot::Commands(AHBotCommand command, uint32 ahMapID, uint32 col, if (state == 0) { - config->AHBSeller = false; - LOG_ERROR("module", "AHBot: Seller disabled from console"); + _allianceConfig->AHBSeller = false; + _hordeConfig->AHBSeller = false; + _neutralConfig->AHBSeller = false; + } + else + { + _allianceConfig->AHBSeller = true; + _hordeConfig->AHBSeller = true; + _neutralConfig->AHBSeller = true; + } + + break; + } + case AHBotCommand::useMarketPrice: + { + char* param1 = strtok(args, " "); + uint32 state = (uint32)strtoul(param1, NULL, 0); + + if (state == 0) + { + _allianceConfig->SellAtMarketPrice = false; + _hordeConfig->SellAtMarketPrice = false; + _neutralConfig->SellAtMarketPrice = false; } else { - config->AHBSeller = true; - LOG_ERROR("module", "AHBot: Seller enabled from console"); + _allianceConfig->SellAtMarketPrice = true; + _hordeConfig->SellAtMarketPrice = true; + _neutralConfig->SellAtMarketPrice = true; } break; @@ -1309,6 +1344,10 @@ void AuctionHouseBot::Commands(AHBotCommand command, uint32 ahMapID, uint32 col, 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()) { if (itr->second->owner.GetCounter() == _id) @@ -1381,27 +1420,35 @@ void AuctionHouseBot::Commands(AHBotCommand command, uint32 ahMapID, uint32 col, 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 = '{}'", greytg, ahMapID); - trans->Append("UPDATE mod_auctionhousebot SET percentwhitetradegoods = '{}' WHERE auctionhouse = '{}'", whitetg, ahMapID); - trans->Append("UPDATE mod_auctionhousebot SET percentgreentradegoods = '{}' WHERE auctionhouse = '{}'", greentg, ahMapID); - trans->Append("UPDATE mod_auctionhousebot SET percentbluetradegoods = '{}' WHERE auctionhouse = '{}'", bluetg, ahMapID); - trans->Append("UPDATE mod_auctionhousebot SET percentpurpletradegoods = '{}' WHERE auctionhouse = '{}'", purpletg, ahMapID); - trans->Append("UPDATE mod_auctionhousebot SET percentorangetradegoods = '{}' WHERE auctionhouse = '{}'", orangetg, ahMapID); - trans->Append("UPDATE mod_auctionhousebot SET percentyellowtradegoods = '{}' WHERE auctionhouse = '{}'", yellowtg, ahMapID); - trans->Append("UPDATE mod_auctionhousebot SET percentgreyitems = '{}' WHERE auctionhouse = '{}'", greyi, ahMapID); - trans->Append("UPDATE mod_auctionhousebot SET percentwhiteitems = '{}' WHERE auctionhouse = '{}'", whitei, ahMapID); - trans->Append("UPDATE mod_auctionhousebot SET percentgreenitems = '{}' WHERE auctionhouse = '{}'", greeni, ahMapID); - trans->Append("UPDATE mod_auctionhousebot SET percentblueitems = '{}' WHERE auctionhouse = '{}'", bluei, ahMapID); - trans->Append("UPDATE mod_auctionhousebot SET percentpurpleitems = '{}' WHERE auctionhouse = '{}'", purplei, ahMapID); - trans->Append("UPDATE mod_auctionhousebot SET percentorangeitems = '{}' WHERE auctionhouse = '{}'", orangei, ahMapID); - trans->Append("UPDATE mod_auctionhousebot SET percentyellowitems = '{}' WHERE auctionhouse = '{}'", yellowi, ahMapID); + 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); - config->SetPercentages(greytg, whitetg, greentg, bluetg, purpletg, orangetg, yellowtg, greyi, whitei, greeni, bluei, purplei, orangei, yellowi); - break; } case AHBotCommand::minprice: diff --git a/src/AuctionHouseBotAuctionHouseScript.cpp b/src/AuctionHouseBotAuctionHouseScript.cpp index 1811b70..bab478f 100644 --- a/src/AuctionHouseBotAuctionHouseScript.cpp +++ b/src/AuctionHouseBotAuctionHouseScript.cpp @@ -1,4 +1,9 @@ +/* + * 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" @@ -138,9 +143,8 @@ void AHBot_AuctionHouseScript::OnAuctionAdd(AuctionHouseObject* /*ah*/, AuctionE void AHBot_AuctionHouseScript::OnAuctionRemove(AuctionHouseObject* /*ah*/, AuctionEntry* auction) { - // - // The the configuration for the auction house + // Get the configuration for the auction house // AuctionHouseEntry const* ahEntry = sAuctionHouseStore.LookupEntry(auction->GetHouseId()); @@ -200,6 +204,64 @@ void AHBot_AuctionHouseScript::OnAuctionRemove(AuctionHouseObject* /*ah*/, Aucti config->DecItemCounts(prototype->Class, prototype->Quality); } +void AHBot_AuctionHouseScript::OnAuctionSuccessful(AuctionHouseObject* /*ah*/, AuctionEntry* auction) +{ + // + // Get the configuration for the auction house + // + + AuctionHouseEntry const* ahEntry = sAuctionHouseStore.LookupEntry(auction->GetHouseId()); + AHBConfig* config = gNeutralConfig; + + if (ahEntry) + { + if (ahEntry->houseId == AUCTIONHOUSE_ALLIANCE) + { + config = gAllianceConfig; + } + else if (ahEntry->houseId == AUCTIONHOUSE_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. + // + + config->UpdateItemStats(auction->item_template, auction->itemCount, auction->buyout); +} + +void AHBot_AuctionHouseScript::OnAuctionExpire(AuctionHouseObject* /*ah*/, AuctionEntry* auction) +{ + // + // Get the configuration for the auction house + // + + AuctionHouseEntry const* ahEntry = sAuctionHouseStore.LookupEntry(auction->GetHouseId()); + AHBConfig* config = gNeutralConfig; + + if (ahEntry) + { + if (ahEntry->houseId == AUCTIONHOUSE_ALLIANCE) + { + config = gAllianceConfig; + } + else if (ahEntry->houseId == AUCTIONHOUSE_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); +} + void AHBot_AuctionHouseScript::OnBeforeAuctionHouseMgrUpdate() { // diff --git a/src/AuctionHouseBotAuctionHouseScript.h b/src/AuctionHouseBotAuctionHouseScript.h index 16ba1b5..1ff5468 100644 --- a/src/AuctionHouseBotAuctionHouseScript.h +++ b/src/AuctionHouseBotAuctionHouseScript.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 + * 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 @@ -21,10 +21,12 @@ class AHBot_AuctionHouseScript : public AuctionHouseScript 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 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 */ \ No newline at end of file +#endif /* AUCTION_HOUSE_BOT_AUCTION_HOUSE_SCRIPT_H */ diff --git a/src/AuctionHouseBotCommon.cpp b/src/AuctionHouseBotCommon.cpp index c0564c9..640c775 100644 --- a/src/AuctionHouseBotCommon.cpp +++ b/src/AuctionHouseBotCommon.cpp @@ -1,3 +1,7 @@ +/* + * 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" @@ -15,4 +19,4 @@ AHBConfig* gNeutralConfig = new AHBConfig(7); // std::set gBotsId; -std::set gBots; \ No newline at end of file +std::set gBots; diff --git a/src/AuctionHouseBotCommon.h b/src/AuctionHouseBotCommon.h index 1e32cd6..3031485 100644 --- a/src/AuctionHouseBotCommon.h +++ b/src/AuctionHouseBotCommon.h @@ -79,6 +79,7 @@ enum class AHBotCommand : uint32 { buyer, seller, + useMarketPrice, ahexpire, minitems, diff --git a/src/AuctionHouseBotConfig.cpp b/src/AuctionHouseBotConfig.cpp index b168361..0cb742a 100644 --- a/src/AuctionHouseBotConfig.cpp +++ b/src/AuctionHouseBotConfig.cpp @@ -508,6 +508,7 @@ void AHBConfig::Reset() BuyMethod = false; SellMethod = false; + SellAtMarketPrice = false; ConsiderOnlyBotAuctions = false; ItemsPerCycle = 200; @@ -591,6 +592,10 @@ void AHBConfig::Reset() PurpleItemsBin.clear(); OrangeItemsBin.clear(); YellowItemsBin.clear(); + + itemsCount.clear(); + itemsSum.clear(); + itemsPrice.clear(); } uint32 AHBConfig::GetAHID() @@ -1945,10 +1950,73 @@ 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() @@ -1970,6 +2038,8 @@ void AHBConfig::InitializeFromFile() AHBBuyer = sConfigMgr->GetOption ("AuctionHouseBot.EnableBuyer" , false); SellMethod = sConfigMgr->GetOption ("AuctionHouseBot.UseBuyPriceForSeller" , false); BuyMethod = 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.DuplicatesCount" , 1); @@ -3259,13 +3329,13 @@ void AHBConfig::InitializeBins() // 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", "Configuration for ah {}", AHID); + LOG_INFO("module", "AHBot: Configuration for ah {}", AHID); if (SellerWhiteList.size() == 0) { if (DisableItemStore.size() == 0) { - LOG_ERROR("module", "No items are disabled or in the whitelist! Selling will be disabled!"); + LOG_ERROR("module", "AHBot: No items are disabled or in the whitelist! Selling will be disabled!"); GreyTradeGoodsBin.clear(); WhiteTradeGoodsBin.clear(); @@ -3287,30 +3357,27 @@ void AHBConfig::InitializeBins() return; } - LOG_INFO("module", "{} disabled items", uint32(DisableItemStore.size())); + LOG_INFO("module", "AHBot: {} disabled items", uint32(DisableItemStore.size())); } else { - LOG_INFO("module", "Using a whitelist of {} items", uint32(SellerWhiteList.size())); - } - - // if (DebugOutConfig) - // { - LOG_INFO("module", "loaded {} grey trade goods", uint32(GreyTradeGoodsBin.size())); - LOG_INFO("module", "loaded {} white trade goods", uint32(WhiteTradeGoodsBin.size())); - LOG_INFO("module", "loaded {} green trade goods", uint32(GreenTradeGoodsBin.size())); - LOG_INFO("module", "loaded {} blue trade goods", uint32(BlueTradeGoodsBin.size())); - LOG_INFO("module", "loaded {} purple trade goods", uint32(PurpleTradeGoodsBin.size())); - LOG_INFO("module", "loaded {} orange trade goods", uint32(OrangeTradeGoodsBin.size())); - LOG_INFO("module", "loaded {} yellow trade goods", uint32(YellowTradeGoodsBin.size())); - LOG_INFO("module", "loaded {} grey items" , uint32(GreyItemsBin.size())); - LOG_INFO("module", "loaded {} white items" , uint32(WhiteItemsBin.size())); - LOG_INFO("module", "loaded {} green items" , uint32(GreenItemsBin.size())); - LOG_INFO("module", "loaded {} blue items" , uint32(BlueItemsBin.size())); - LOG_INFO("module", "loaded {} purple items" , uint32(PurpleItemsBin.size())); - LOG_INFO("module", "loaded {} orange items" , uint32(OrangeItemsBin.size())); - LOG_INFO("module", "loaded {} yellow items" , uint32(YellowItemsBin.size())); - // } + 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) diff --git a/src/AuctionHouseBotConfig.h b/src/AuctionHouseBotConfig.h index 13601c7..f649037 100644 --- a/src/AuctionHouseBotConfig.h +++ b/src/AuctionHouseBotConfig.h @@ -20,6 +20,7 @@ #ifndef AUCTION_HOUSE_BOT_CONFIG_H #define AUCTION_HOUSE_BOT_CONFIG_H +#include #include #include @@ -142,6 +143,14 @@ class AHBConfig uint32 orangeItems; uint32 yellowItems; + // + // Per-item statistics + // + + std::map itemsCount; + std::map itemsSum; + std::map itemsPrice; + void InitializeFromFile(); void InitializeFromSql(std::set botsIds); @@ -173,6 +182,8 @@ class AHBConfig bool AHBBuyer; bool BuyMethod; bool SellMethod; + bool SellAtMarketPrice; + uint32 MarketResetThreshold; bool ConsiderOnlyBotAuctions; uint32 ItemsPerCycle; @@ -343,6 +354,9 @@ class AHBConfig uint32 TotalItemCounts (); uint32 GetItemCounts (uint32 color); + + void UpdateItemStats (uint32 id, uint32 stackSize, uint64 buyout); + uint64 GetItemPrice (uint32 id); }; // diff --git a/src/AuctionHouseBotMailScript.cpp b/src/AuctionHouseBotMailScript.cpp index 5c3dee2..56cbb9c 100644 --- a/src/AuctionHouseBotMailScript.cpp +++ b/src/AuctionHouseBotMailScript.cpp @@ -1,3 +1,7 @@ +/* + * 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" diff --git a/src/AuctionHouseBotMailScript.h b/src/AuctionHouseBotMailScript.h index dbd0b8d..bc90694 100644 --- a/src/AuctionHouseBotMailScript.h +++ b/src/AuctionHouseBotMailScript.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 + * 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 @@ -20,4 +20,4 @@ class AHBot_MailScript : public 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 */ \ No newline at end of file +#endif /* AUCTION_HOUSE_BOT_MAIL_SCRIPT_H */ diff --git a/src/AuctionHouseBotScript.cpp b/src/AuctionHouseBotScript.cpp index 5cf7149..46bcbea 100644 --- a/src/AuctionHouseBotScript.cpp +++ b/src/AuctionHouseBotScript.cpp @@ -1,16 +1,11 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE */ -// #include "ScriptMgr.h" #include "AuctionHouseBot.h" #include "AuctionHouseBotAuctionHouseScript.h" #include "AuctionHouseBotMailScript.h" #include "AuctionHouseBotWorldScript.h" -// #include "Log.h" -// #include "Mail.h" -// #include "Player.h" -// #include "WorldSession.h" // ============================================================================= // This provides the effective startup of the module by istanciating the scripts diff --git a/src/AuctionHouseBotWorldScript.cpp b/src/AuctionHouseBotWorldScript.cpp index 5238fa2..2a36e17 100644 --- a/src/AuctionHouseBotWorldScript.cpp +++ b/src/AuctionHouseBotWorldScript.cpp @@ -1,3 +1,7 @@ +/* + * 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" @@ -14,7 +18,7 @@ AHBot_WorldScript::AHBot_WorldScript() : WorldScript("AHBot_WorldScript") } -void AHBot_WorldScript::OnBeforeConfigLoad(bool /*reload*/) +void AHBot_WorldScript::OnBeforeConfigLoad(bool reload) { // // Retrieve how many bots shall be operating on the auction market @@ -85,33 +89,98 @@ void AHBot_WorldScript::OnBeforeConfigLoad(bool /*reload*/) 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..."); + // - // Preparare the global configuration for all factions using the configuration just read + // Initialize the configuration (done only once at startup) // gAllianceConfig->Initialize(gBotsId); gHordeConfig->Initialize (gBotsId); gNeutralConfig->Initialize (gBotsId); + + // + // Starts the bots + // + + PopulateBots(); } -void AHBot_WorldScript::OnStartup() +void AHBot_WorldScript::DeleteBots() { - LOG_INFO("server.loading", "Initialize AuctionHouseBot..."); + // + // Save the old bots references. + // - // - // Initialize the configuration items bins here, when items has been handled by the object manager - // + std::set oldBots; - gAllianceConfig->InitializeBins(); - gHordeConfig->InitializeBins (); - gNeutralConfig->InitializeBins (); + for (AuctionHouseBot* bot: gBots) + { + oldBots.insert(bot); + } // - // Starts the amount of bots read furing the configuration phase + // 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); diff --git a/src/AuctionHouseBotWorldScript.h b/src/AuctionHouseBotWorldScript.h index e455595..069b049 100644 --- a/src/AuctionHouseBotWorldScript.h +++ b/src/AuctionHouseBotWorldScript.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 + * 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 @@ -13,6 +13,10 @@ class AHBot_WorldScript : public WorldScript { +private: + void DeleteBots(); + void PopulateBots(); + public: AHBot_WorldScript(); @@ -20,4 +24,4 @@ class AHBot_WorldScript : public WorldScript void OnStartup() override; }; -#endif /* AUCTION_HOUSE_BOT_WORLD_SCRIPT_H */ \ No newline at end of file +#endif /* AUCTION_HOUSE_BOT_WORLD_SCRIPT_H */ diff --git a/src/ah_bot_loader.cpp b/src/ah_bot_loader.cpp index 1344243..08c40df 100644 --- a/src/ah_bot_loader.cpp +++ b/src/ah_bot_loader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE * Copyright (C) 2021+ WarheadCore */ diff --git a/src/cs_ah_bot.cpp b/src/cs_ah_bot.cpp index d2941e4..5826d6c 100644 --- a/src/cs_ah_bot.cpp +++ b/src/cs_ah_bot.cpp @@ -35,6 +35,51 @@ 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") { @@ -64,50 +109,6 @@ class ah_bot_commandscript : public CommandScript return false; } - // - // Support function the item quality - // - - auto qualityStringToEnum = [](const char* qualityName, int maxCount) - { - if (strncmp(qualityName, "grey", maxCount) == 0) - { - return ITEM_QUALITY_POOR; - } - - if (strncmp(qualityName, "white", maxCount) == 0) - { - return ITEM_QUALITY_NORMAL; - } - - if (strncmp(qualityName, "green", maxCount) == 0) - { - return ITEM_QUALITY_UNCOMMON; - } - - if (strncmp(qualityName, "blue", maxCount) == 0) - { - return ITEM_QUALITY_RARE; - } - - if (strncmp(qualityName, "purple", maxCount) == 0) - { - return ITEM_QUALITY_EPIC; - } - - if (strncmp(qualityName, "orange", maxCount) == 0) - { - return ITEM_QUALITY_LEGENDARY; - } - - if (strncmp(qualityName, "yellow", maxCount) == 0) - { - return ITEM_QUALITY_ARTIFACT; - } - - return static_cast(-1); // Invalid - }; - // // Commands which does not requires an AH // @@ -148,6 +149,23 @@ class ah_bot_commandscript : public CommandScript 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 @@ -177,9 +195,7 @@ class ah_bot_commandscript : public CommandScript if (!opt) { - handler->PSendSysMessage("Invalid syntax"); - 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; } @@ -192,6 +208,7 @@ class ah_bot_commandscript : public CommandScript handler->PSendSysMessage("AHBot commands:"); 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"); @@ -230,7 +247,7 @@ class ah_bot_commandscript : public CommandScript return false; } - for (AuctionHouseBot* bot: gBots) + for (AuctionHouseBot* bot : gBots) { bot->Commands(AHBotCommand::minitems, ahMapID, 0, param1); } @@ -277,15 +294,15 @@ class ah_bot_commandscript : public CommandScript 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(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 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)); @@ -347,7 +364,7 @@ class ah_bot_commandscript : public CommandScript return false; } - auto quality = qualityStringToEnum(param1, l); + auto quality = stringToItemQualities(param1, l); if (quality != static_cast(-1)) { @@ -373,7 +390,7 @@ class ah_bot_commandscript : public CommandScript return false; } - auto quality = qualityStringToEnum(param1, l); + auto quality = stringToItemQualities(param1, l); if (quality != static_cast(-1)) { @@ -407,7 +424,7 @@ class ah_bot_commandscript : public CommandScript return false; } - auto quality = qualityStringToEnum(param1, l); + auto quality = stringToItemQualities(param1, l); if (quality != static_cast(-1)) { @@ -441,7 +458,7 @@ class ah_bot_commandscript : public CommandScript return false; } - auto quality = qualityStringToEnum(param1, l); + auto quality = stringToItemQualities(param1, l); if (quality != static_cast(-1)) { @@ -474,7 +491,7 @@ class ah_bot_commandscript : public CommandScript // return false; // } - auto quality = qualityStringToEnum(param1, l); + auto quality = stringToItemQualities(param1, l); if (quality != static_cast(-1)) { @@ -500,7 +517,7 @@ class ah_bot_commandscript : public CommandScript return false; } - auto quality = qualityStringToEnum(param1, l); + auto quality = stringToItemQualities(param1, l); if (quality != static_cast(-1)) {