mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
[3.3.5] AHBot Characters (#17885)
(cherry picked from commit 6dc0a9f04a)
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "AuctionHouseBot.h"
|
||||
#include "AuctionHouseMgr.h"
|
||||
#include "AuctionHousePackets.h"
|
||||
#include "AccountMgr.h"
|
||||
@@ -148,7 +149,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction&
|
||||
}
|
||||
|
||||
// receiver exist
|
||||
if (bidder || bidderAccId)
|
||||
if ((bidder || bidderAccId) && !sAuctionBotConfig->IsBotChar(auction->bidder))
|
||||
{
|
||||
// set owner to bidder (to prevent delete item with sender char deleting)
|
||||
// owner in `data` will set at mail receive and item extracting
|
||||
@@ -181,7 +182,7 @@ void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry* auction, SQLTrans
|
||||
Player* owner = ObjectAccessor::FindConnectedPlayer(owner_guid);
|
||||
uint32 owner_accId = ObjectMgr::GetPlayerAccountIdByGUID(owner_guid);
|
||||
// owner exist (online or offline)
|
||||
if (owner || owner_accId)
|
||||
if ((owner || owner_accId) && !sAuctionBotConfig->IsBotChar(auction->owner))
|
||||
MailDraft(auction->BuildAuctionMailSubject(AUCTION_SALE_PENDING), AuctionEntry::BuildAuctionMailBody(auction->bidder, auction->bid, auction->buyout, auction->deposit, auction->GetAuctionCut()))
|
||||
.SendMailTo(trans, MailReceiver(owner, auction->owner), auction, MAIL_CHECK_MASK_COPIED);
|
||||
}
|
||||
@@ -195,7 +196,7 @@ void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry* auction, SQLTransa
|
||||
Item* item = GetAItem(auction->itemGUIDLow);
|
||||
|
||||
// owner exist
|
||||
if (owner || owner_accId)
|
||||
if ((owner || owner_accId) && !sAuctionBotConfig->IsBotChar(auction->owner))
|
||||
{
|
||||
uint64 profit = auction->bid + auction->deposit - auction->GetAuctionCut();
|
||||
|
||||
@@ -226,7 +227,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry* auction, SQLTransacti
|
||||
Player* owner = ObjectAccessor::FindConnectedPlayer(owner_guid);
|
||||
uint32 owner_accId = ObjectMgr::GetPlayerAccountIdByGUID(owner_guid);
|
||||
// owner exist
|
||||
if (owner || owner_accId)
|
||||
if ((owner || owner_accId) && !sAuctionBotConfig->IsBotChar(auction->owner))
|
||||
{
|
||||
if (owner)
|
||||
owner->GetSession()->SendAuctionClosedNotification(auction, 0.0f, false, item);
|
||||
@@ -255,7 +256,7 @@ void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry* auction, uint64 /*n
|
||||
Item* item = GetAItem(auction->itemGUIDLow);
|
||||
|
||||
// old bidder exist
|
||||
if (oldBidder || oldBidder_accId)
|
||||
if ((oldBidder || oldBidder_accId) && !sAuctionBotConfig->IsBotChar(auction->bidder))
|
||||
{
|
||||
if (oldBidder && item)
|
||||
oldBidder->GetSession()->SendAuctionOutBidNotification(auction, item);
|
||||
@@ -278,7 +279,7 @@ void AuctionHouseMgr::SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQ
|
||||
bidder_accId = ObjectMgr::GetPlayerAccountIdByGUID(bidder_guid);
|
||||
|
||||
// bidder exist
|
||||
if (bidder || bidder_accId)
|
||||
if ((bidder || bidder_accId) && !sAuctionBotConfig->IsBotChar(auction->bidder))
|
||||
MailDraft(auction->BuildAuctionMailSubject(AUCTION_CANCELLED_TO_BIDDER), AuctionEntry::BuildAuctionMailBody(auction->owner, auction->bid, auction->buyout, auction->deposit, 0))
|
||||
.AddMoney(auction->bid)
|
||||
.SendMailTo(trans, MailReceiver(bidder, auction->bidder), auction, MAIL_CHECK_MASK_COPIED);
|
||||
|
||||
@@ -15,14 +15,15 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Log.h"
|
||||
#include "Item.h"
|
||||
#include "World.h"
|
||||
#include "Config.h"
|
||||
#include "AuctionHouseMgr.h"
|
||||
#include "AuctionHouseBot.h"
|
||||
#include "AuctionHouseBotBuyer.h"
|
||||
#include "AuctionHouseBotSeller.h"
|
||||
#include "Config.h"
|
||||
#include "Containers.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "Item.h"
|
||||
#include "Log.h"
|
||||
#include "World.h"
|
||||
|
||||
AuctionBotConfig* AuctionBotConfig::instance()
|
||||
{
|
||||
@@ -56,6 +57,31 @@ bool AuctionBotConfig::Initialize()
|
||||
_itemsPerCycleBoost = GetConfig(CONFIG_AHBOT_ITEMS_PER_CYCLE_BOOST);
|
||||
_itemsPerCycleNormal = GetConfig(CONFIG_AHBOT_ITEMS_PER_CYCLE_NORMAL);
|
||||
|
||||
if (GetConfig(CONFIG_AHBOT_ACCOUNT_ID))
|
||||
{
|
||||
// find account guids associated with ahbot account
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARS_BY_ACCOUNT_ID);
|
||||
stmt->setUInt32(0, GetConfig(CONFIG_AHBOT_ACCOUNT_ID));
|
||||
if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
|
||||
{
|
||||
do
|
||||
{
|
||||
_AHBotCharacters.push_back((*result)[0].GetUInt64());
|
||||
} while (result->NextRow());
|
||||
|
||||
TC_LOG_DEBUG("ahbot", "AuctionHouseBot found " UI64FMTD " characters", result->GetRowCount());
|
||||
}
|
||||
else
|
||||
{
|
||||
_AHBotCharacters.push_back(ObjectGuid::LowType(0));
|
||||
TC_LOG_WARN("ahbot", "AuctionHouseBot Account ID has no associated characters.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_AHBotCharacters.push_back(ObjectGuid::LowType(0));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -111,6 +137,8 @@ void AuctionBotConfig::SetConfig(AuctionBotConfigFloatValues index, char const*
|
||||
//Get AuctionHousebot configuration file
|
||||
void AuctionBotConfig::GetConfigFromFile()
|
||||
{
|
||||
SetConfig(CONFIG_AHBOT_ACCOUNT_ID, "AuctionHouseBot.Account", 0);
|
||||
|
||||
SetConfigMax(CONFIG_AHBOT_ALLIANCE_ITEM_AMOUNT_RATIO, "AuctionHouseBot.Alliance.Items.Amount.Ratio", 100, 10000);
|
||||
SetConfigMax(CONFIG_AHBOT_HORDE_ITEM_AMOUNT_RATIO, "AuctionHouseBot.Horde.Items.Amount.Ratio", 100, 10000);
|
||||
SetConfigMax(CONFIG_AHBOT_NEUTRAL_ITEM_AMOUNT_RATIO, "AuctionHouseBot.Neutral.Items.Amount.Ratio", 100, 10000);
|
||||
@@ -272,6 +300,35 @@ char const* AuctionBotConfig::GetHouseTypeName(AuctionHouseType houseType)
|
||||
return names[houseType];
|
||||
}
|
||||
|
||||
// Picks a random character from the list of AHBot chars
|
||||
ObjectGuid::LowType AuctionBotConfig::GetRandChar() const
|
||||
{
|
||||
return Trinity::Containers::SelectRandomContainerElement(_AHBotCharacters);
|
||||
}
|
||||
|
||||
// Picks a random AHBot character, but excludes a specific one. This is used
|
||||
// to have another character than the auction owner place bids
|
||||
ObjectGuid::LowType AuctionBotConfig::GetRandCharExclude(ObjectGuid::LowType exclude) const
|
||||
{
|
||||
// avoid freezing if only one ahbot char (which defeats the purpose but oh well)
|
||||
if (_AHBotCharacters.size() == 1)
|
||||
return _AHBotCharacters[0];
|
||||
|
||||
ObjectGuid::LowType result;
|
||||
do
|
||||
{
|
||||
result = GetRandChar();
|
||||
}
|
||||
while (result == exclude);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool AuctionBotConfig::IsBotChar(ObjectGuid::LowType characterID) const
|
||||
{
|
||||
return !characterID || std::find(_AHBotCharacters.begin(), _AHBotCharacters.end(), characterID) != _AHBotCharacters.end();
|
||||
}
|
||||
|
||||
uint32 AuctionBotConfig::GetConfigItemAmountRatio(AuctionHouseType houseType) const
|
||||
{
|
||||
switch (houseType)
|
||||
@@ -408,7 +465,7 @@ void AuctionHouseBot::PrepareStatusInfos(AuctionHouseBotStatusInfo& statusInfo)
|
||||
if (Item* item = sAuctionMgr->GetAItem(auctionEntry->itemGUIDLow))
|
||||
{
|
||||
ItemTemplate const* prototype = item->GetTemplate();
|
||||
if (!auctionEntry->owner) // Add only ahbot items
|
||||
if (!auctionEntry->owner || sAuctionBotConfig->IsBotChar(auctionEntry->owner)) // Add only ahbot items
|
||||
{
|
||||
if (prototype->GetQuality() < MAX_AUCTION_QUALITY)
|
||||
++statusInfo[i].QualityInfo[prototype->GetQuality()];
|
||||
@@ -426,7 +483,7 @@ void AuctionHouseBot::Rebuild(bool all)
|
||||
{
|
||||
AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(AuctionHouseType(i));
|
||||
for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = auctionHouse->GetAuctionsBegin(); itr != auctionHouse->GetAuctionsEnd(); ++itr)
|
||||
if (!itr->second->owner) // ahbot auction
|
||||
if (!itr->second->owner || sAuctionBotConfig->IsBotChar(itr->second->owner)) // ahbot auction
|
||||
if (all || itr->second->bid == 0) // expire now auction if no bid or forced
|
||||
itr->second->expire_time = sWorld->GetGameTime();
|
||||
}
|
||||
|
||||
@@ -153,6 +153,7 @@ enum AuctionBotConfigUInt32Values
|
||||
CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_KEY,
|
||||
CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_MISC,
|
||||
CONFIG_AHBOT_CLASS_RANDOMSTACKRATIO_GLYPH,
|
||||
CONFIG_AHBOT_ACCOUNT_ID,
|
||||
CONFIG_UINT32_AHBOT_UINT32_COUNT
|
||||
};
|
||||
|
||||
@@ -200,10 +201,10 @@ enum AuctionBotConfigFloatValues
|
||||
class TC_GAME_API AuctionBotConfig
|
||||
{
|
||||
private:
|
||||
AuctionBotConfig(): _itemsPerCycleBoost(1000), _itemsPerCycleNormal(20) {}
|
||||
~AuctionBotConfig() {}
|
||||
AuctionBotConfig(const AuctionBotConfig&);
|
||||
AuctionBotConfig& operator=(const AuctionBotConfig&);
|
||||
AuctionBotConfig(): _itemsPerCycleBoost(1000), _itemsPerCycleNormal(20) { }
|
||||
~AuctionBotConfig() { }
|
||||
AuctionBotConfig(AuctionBotConfig const&) = delete;
|
||||
AuctionBotConfig& operator=(AuctionBotConfig const&) = delete;
|
||||
|
||||
public:
|
||||
static AuctionBotConfig* instance();
|
||||
@@ -225,6 +226,9 @@ public:
|
||||
|
||||
uint32 GetItemPerCycleBoost() const { return _itemsPerCycleBoost; }
|
||||
uint32 GetItemPerCycleNormal() const { return _itemsPerCycleNormal; }
|
||||
ObjectGuid::LowType GetRandChar() const;
|
||||
ObjectGuid::LowType GetRandCharExclude(ObjectGuid::LowType exclude) const;
|
||||
bool IsBotChar(ObjectGuid::LowType characterID) const;
|
||||
void Reload() { GetConfigFromFile(); }
|
||||
|
||||
static char const* GetHouseTypeName(AuctionHouseType houseType);
|
||||
@@ -232,6 +236,7 @@ public:
|
||||
private:
|
||||
std::string _AHBotIncludes;
|
||||
std::string _AHBotExcludes;
|
||||
std::vector<ObjectGuid::LowType> _AHBotCharacters;
|
||||
uint32 _itemsPerCycleBoost;
|
||||
uint32 _itemsPerCycleNormal;
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ uint32 AuctionBotBuyer::GetItemInformation(BuyerConfiguration& config)
|
||||
{
|
||||
AuctionEntry* entry = itr->second;
|
||||
|
||||
if (!entry->owner)
|
||||
if (!entry->owner || sAuctionBotConfig->IsBotChar(entry->owner))
|
||||
continue; // Skip auctions owned by AHBot
|
||||
|
||||
Item* item = sAuctionMgr->GetAItem(entry->itemGUIDLow);
|
||||
@@ -220,7 +220,7 @@ bool AuctionBotBuyer::RollBidChance(const BuyerItemInfo* ahInfo, const Item* ite
|
||||
}
|
||||
|
||||
// If a player has bidded on item, have fifth of normal chance
|
||||
if (auction->bidder)
|
||||
if (auction->bidder && !sAuctionBotConfig->IsBotChar(auction->bidder))
|
||||
chance = chance / 5.f;
|
||||
|
||||
// Add config weigh in for quality
|
||||
@@ -393,11 +393,11 @@ void AuctionBotBuyer::BuyEntry(AuctionEntry* auction, AuctionHouseObject* auctio
|
||||
SQLTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
|
||||
// Send mail to previous bidder if any
|
||||
if (auction->bidder)
|
||||
if (auction->bidder && !sAuctionBotConfig->IsBotChar(auction->bidder))
|
||||
sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, NULL, trans);
|
||||
|
||||
// Set bot as bidder and set new bid amount
|
||||
auction->bidder = 0;
|
||||
auction->bidder = sAuctionBotConfig->GetRandCharExclude(auction->owner);
|
||||
auction->bid = auction->buyout;
|
||||
|
||||
// Mails must be under transaction control too to prevent data loss
|
||||
@@ -424,11 +424,11 @@ void AuctionBotBuyer::PlaceBidToEntry(AuctionEntry* auction, uint32 bidPrice)
|
||||
SQLTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
|
||||
// Send mail to previous bidder if any
|
||||
if (auction->bidder)
|
||||
if (auction->bidder && !sAuctionBotConfig->IsBotChar(auction->bidder))
|
||||
sAuctionMgr->SendAuctionOutbiddedMail(auction, bidPrice, NULL, trans);
|
||||
|
||||
// Set bot as bidder and set new bid amount
|
||||
auction->bidder = 0;
|
||||
auction->bidder = sAuctionBotConfig->GetRandCharExclude(auction->owner);
|
||||
auction->bid = bidPrice;
|
||||
|
||||
// Update auction to DB
|
||||
|
||||
@@ -641,7 +641,7 @@ uint32 AuctionBotSeller::SetStat(SellerConfiguration& config)
|
||||
{
|
||||
ItemTemplate const* prototype = item->GetTemplate();
|
||||
if (prototype)
|
||||
if (!auctionEntry->owner) // Add only ahbot items
|
||||
if (!auctionEntry->owner || sAuctionBotConfig->IsBotChar(auctionEntry->owner)) // Add only ahbot items
|
||||
++itemsSaved[prototype->GetQuality()][prototype->GetClass()];
|
||||
}
|
||||
}
|
||||
@@ -1017,7 +1017,7 @@ void AuctionBotSeller::AddNewAuctions(SellerConfiguration& config)
|
||||
|
||||
AuctionEntry* auctionEntry = new AuctionEntry();
|
||||
auctionEntry->Id = sObjectMgr->GenerateAuctionID();
|
||||
auctionEntry->owner = UI64LIT(0);
|
||||
auctionEntry->owner = sAuctionBotConfig->GetRandChar();
|
||||
auctionEntry->itemGUIDLow = item->GetGUID().GetCounter();
|
||||
auctionEntry->itemEntry = item->GetEntry();
|
||||
auctionEntry->startbid = bidPrice;
|
||||
|
||||
@@ -3218,6 +3218,15 @@ GameObject.CheckInvalidPosition = 0
|
||||
|
||||
###################################################################################################
|
||||
# AUCTION HOUSE BOT SETTINGS
|
||||
#
|
||||
# AuctionHouseBot.Account
|
||||
# Description: Account ID for AHBot characters. If non-zero, all auctions and bids associated
|
||||
# with the AHBot will randomly be assigned one of this account's characters.
|
||||
# Default: 0
|
||||
#
|
||||
|
||||
AuctionHouseBot.Account = 0
|
||||
|
||||
#
|
||||
# AuctionHouseBot.Update.Interval
|
||||
# Description: Interval in seconds for AHBot to get updated
|
||||
|
||||
Reference in New Issue
Block a user