mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-13 00:58:33 +00:00
These contains various fixes, fixes that have history worked one in past more then once as person as group, aswell @Wishmaster117. But due various reasons we had to drop them due priority or simply timewise. These fixes have recollected again by @Regrad based on his crash logs. Most crash logs we have, i am talking 30+ of them, to many to post here. @Regrad running a larger server 100+ real players with bots, which means he will walk into issues that most of us wont or are extremely difficult to reproduce. @Regrad used LLM to solve them based on crash log and mentioned his server crashes almost disappeared, instead of redoing every single PR and pull them apart. I tried to keep his bunch of changes together as whole, reviewed them, some redone, verified again etc etc. This is not how would normally do this. But since i want @Regrad being able to confirm, we need this in a package as a whole. Pulling them apart in the current situation is simply to much, to complicated in the verification process. So this PR is open and in my opinion has priority above others, but @Regrad is only person who can give the green light for the mod-playerbot changes for now. I, we spend huge amount of time into these issues over last couple of months. I will put other PR's on hold for abit. --------- Signed-off-by: Engardium <regradius@gmail.com> Co-authored-by: Engardium <regradius@gmail.com>
244 lines
8.7 KiB
C++
244 lines
8.7 KiB
C++
/*
|
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
|
|
* and/or modify it under version 3 of the License, or (at your option), any later version.
|
|
*/
|
|
|
|
#ifndef _PLAYERBOT_RANDOMPLAYERBOTMGR_H
|
|
#define _PLAYERBOT_RANDOMPLAYERBOTMGR_H
|
|
|
|
#include "NewRpgInfo.h"
|
|
#include "ObjectGuid.h"
|
|
#include "PlayerbotMgr.h"
|
|
#include "GameTime.h"
|
|
|
|
struct BattlegroundInfo
|
|
{
|
|
std::vector<uint32> bgInstances;
|
|
std::vector<uint32> ratedArenaInstances;
|
|
std::vector<uint32> skirmishArenaInstances;
|
|
uint32 bgInstanceCount = 0;
|
|
uint32 ratedArenaInstanceCount = 0;
|
|
uint32 skirmishArenaInstanceCount = 0;
|
|
uint32 minLevel = 0;
|
|
uint32 maxLevel = 0;
|
|
uint32 activeRatedArenaQueue = 0; // 0 = Inactive, 1 = Active
|
|
uint32 activeSkirmishArenaQueue = 0; // 0 = Inactive, 1 = Active
|
|
uint32 activeBgQueue = 0; // 0 = Inactive, 1 = Active
|
|
|
|
// Bots (Arena)
|
|
uint32 ratedArenaBotCount = 0;
|
|
uint32 skirmishArenaBotCount = 0;
|
|
|
|
// Bots (Battleground)
|
|
uint32 bgHordeBotCount = 0;
|
|
uint32 bgAllianceBotCount = 0;
|
|
|
|
// Players (Arena)
|
|
uint32 ratedArenaPlayerCount = 0;
|
|
uint32 skirmishArenaPlayerCount = 0;
|
|
|
|
// Players (Battleground)
|
|
uint32 bgHordePlayerCount = 0;
|
|
uint32 bgAlliancePlayerCount = 0;
|
|
};
|
|
|
|
class ChatHandler;
|
|
class PerformanceMonitorOperation;
|
|
class WorldLocation;
|
|
|
|
struct CachedEvent
|
|
{
|
|
uint32 value = 0;
|
|
uint32 lastChangeTime = 0;
|
|
uint32 validIn = 0;
|
|
std::string data;
|
|
|
|
bool IsEmpty() const { return !lastChangeTime; }
|
|
};
|
|
|
|
struct BotEventCache
|
|
{
|
|
bool loaded = false;
|
|
std::unordered_map<std::string, CachedEvent> events;
|
|
};
|
|
|
|
// https://gist.github.com/bradley219/5373998
|
|
|
|
class botPIDImpl;
|
|
class botPID
|
|
{
|
|
public:
|
|
// Kp - proportional gain
|
|
// Ki - Integral gain
|
|
// Kd - derivative gain
|
|
// dt - loop interval time
|
|
// max - maximum value of manipulated variable
|
|
// min - minimum value of manipulated variable
|
|
botPID(double dt, double max, double min, double Kp, double Ki, double Kd);
|
|
void adjust(double Kp, double Ki, double Kd);
|
|
void reset();
|
|
|
|
double calculate(double setpoint, double pv);
|
|
~botPID();
|
|
|
|
private:
|
|
botPIDImpl* pimpl;
|
|
};
|
|
|
|
class RandomPlayerbotMgr : public PlayerbotHolder
|
|
{
|
|
public:
|
|
RandomPlayerbotMgr();
|
|
virtual ~RandomPlayerbotMgr();
|
|
static RandomPlayerbotMgr* instance()
|
|
{
|
|
static RandomPlayerbotMgr instance;
|
|
return &instance;
|
|
}
|
|
|
|
void LogPlayerLocation();
|
|
void UpdateAIInternal(uint32 elapsed, bool minimal = false) override;
|
|
|
|
uint32 activeBots = 0;
|
|
static bool HandlePlayerbotConsoleCommand(ChatHandler* handler, char const* args);
|
|
bool IsRandomBot(Player* bot);
|
|
bool IsRandomBot(ObjectGuid::LowType bot);
|
|
bool IsAddclassBot(Player* bot);
|
|
bool IsAddclassBot(ObjectGuid::LowType bot);
|
|
void Randomize(Player* bot);
|
|
void Clear(Player* bot);
|
|
void RandomizeFirst(Player* bot);
|
|
void RandomizeMin(Player* bot);
|
|
void IncreaseLevel(Player* bot);
|
|
void ScheduleTeleport(uint32 bot, uint32 time = 0);
|
|
void ScheduleChangeStrategy(uint32 bot, uint32 time = 0);
|
|
void HandleCommand(uint32 type, std::string const text, Player* fromPlayer, std::string channelName = "");
|
|
std::string const HandleRemoteCommand(std::string const request);
|
|
void OnPlayerLogout(Player* player);
|
|
void OnPlayerLogin(Player* player);
|
|
void OnPlayerLoginError(uint32 bot);
|
|
Player* GetRandomPlayer();
|
|
std::vector<Player*> GetPlayers() { return players; };
|
|
PlayerBotMap GetAllBots() { return playerBots; };
|
|
void PrintStats();
|
|
double GetBuyMultiplier(Player* bot);
|
|
double GetSellMultiplier(Player* bot);
|
|
void AddTradeDiscount(Player* bot, Player* master, int32 value);
|
|
void SetTradeDiscount(Player* bot, Player* master, uint32 value);
|
|
uint32 GetTradeDiscount(Player* bot, Player* master);
|
|
void Refresh(Player* bot);
|
|
void RandomTeleportForLevel(Player* bot);
|
|
void RandomTeleportGrindForLevel(Player* bot);
|
|
void RandomTeleportForRpg(Player* bot);
|
|
uint32 GetMaxAllowedBotCount();
|
|
bool ProcessBot(Player* player);
|
|
void Revive(Player* player);
|
|
void ChangeStrategy(Player* player);
|
|
void ChangeStrategyOnce(Player* player);
|
|
uint32 GetValue(Player* bot, std::string const& type);
|
|
uint32 GetValue(uint32 bot, std::string const& type);
|
|
std::string GetData(uint32 bot, std::string const& type);
|
|
void SetValue(uint32 bot, std::string const& type, uint32 value, std::string const& data = "");
|
|
void SetValue(Player* bot, std::string const& type, uint32 value, std::string const& data = "");
|
|
void Remove(Player* bot);
|
|
ObjectGuid GetBattleMasterGUID(Player* bot, BattlegroundTypeId bgTypeId);
|
|
CreatureData const* GetCreatureDataByEntry(uint32 entry);
|
|
void LoadBattleMastersCache();
|
|
std::map<uint32, std::map<uint32, BattlegroundInfo>> BattlegroundData;
|
|
std::map<uint32, std::map<uint32, std::map<TeamId, uint32>>> VisualBots;
|
|
std::map<uint32, std::map<uint32, std::map<uint32, uint32>>> Supporters;
|
|
std::map<TeamId, std::vector<uint32>> LfgDungeons;
|
|
void CheckBgQueue();
|
|
void CheckLfgQueue();
|
|
void CheckPlayers();
|
|
void LogBattlegroundInfo();
|
|
|
|
std::map<TeamId, std::map<BattlegroundTypeId, std::vector<uint32>>> getBattleMastersCache()
|
|
{
|
|
return BattleMastersCache;
|
|
}
|
|
|
|
float getActivityMod() { return activityMod; }
|
|
float getActivityPercentage() { return activityMod * 100.0f; }
|
|
void setActivityPercentage(float percentage) { activityMod = percentage / 100.0f; }
|
|
static uint8 GetTeamClassIdx(bool isAlliance, uint8 claz) { return isAlliance * 20 + claz; }
|
|
|
|
void PrepareAddclassCache();
|
|
void PrepareZone2LevelBracket();
|
|
void PrepareTeleportCache();
|
|
void Init();
|
|
std::map<uint8, std::unordered_set<ObjectGuid>> addclassCache;
|
|
std::map<uint8, std::vector<WorldLocation>> locsPerLevelCache;
|
|
std::map<uint8, std::vector<WorldLocation>> allianceStarterPerLevelCache;
|
|
std::map<uint8, std::vector<WorldLocation>> hordeStarterPerLevelCache;
|
|
std::vector<uint32> allianceFlightMasterCache;
|
|
std::vector<uint32> hordeFlightMasterCache;
|
|
struct LevelBracket {
|
|
uint32 low;
|
|
uint32 high;
|
|
bool InsideBracket(uint32 val) { return val >= low && val <= high; }
|
|
};
|
|
std::map<uint32, LevelBracket> zone2LevelBracket;
|
|
struct BankerLocation {
|
|
WorldLocation loc;
|
|
uint32 entry;
|
|
};
|
|
std::map<uint8, std::vector<BankerLocation>> bankerLocsPerLevelCache;
|
|
|
|
// Account type management
|
|
void AssignAccountTypes();
|
|
bool IsAccountType(uint32 accountId, uint8 accountType);
|
|
|
|
protected:
|
|
void OnBotLoginInternal(Player* const bot) override;
|
|
|
|
private:
|
|
// pid values are set in constructor
|
|
botPID pid = botPID(1, 50, -50, 0, 0, 0);
|
|
float activityMod = 0.25;
|
|
bool _isBotInitializing = true;
|
|
bool _isBotLogging = true;
|
|
NewRpgStatistic rpgStasticTotal;
|
|
CachedEvent* FindEvent(uint32 bot, std::string const& event);
|
|
uint32 GetEventValue(uint32 bot, std::string const& event);
|
|
std::string GetEventData(uint32 bot, std::string const& event);
|
|
uint32 SetEventValue(uint32 bot, std::string const& event, uint32 value, uint32 validIn,
|
|
std::string const& data = "");
|
|
void GetBots();
|
|
std::vector<uint32> GetBgBots(uint32 bracket);
|
|
time_t BgCheckTimer;
|
|
time_t LfgCheckTimer;
|
|
time_t PlayersCheckTimer;
|
|
time_t RealPlayerLastTimeSeen = 0;
|
|
time_t DelayLoginBotsTimer;
|
|
time_t printStatsTimer;
|
|
uint32 AddRandomBots();
|
|
bool ProcessBot(uint32 bot);
|
|
void ScheduleRandomize(uint32 bot, uint32 time);
|
|
void RandomTeleport(Player* bot);
|
|
void RandomTeleport(Player* bot, std::vector<WorldLocation>& locs, bool hearth = false);
|
|
uint32 GetZoneLevel(uint16 mapId, float teleX, float teleY, float teleZ);
|
|
typedef void (RandomPlayerbotMgr::*ConsoleCommandHandler)(Player*);
|
|
std::vector<Player*> players;
|
|
uint32 processTicks;
|
|
|
|
// std::map<uint32, std::vector<WorldLocation>> rpgLocsCache;
|
|
std::map<uint32, std::map<uint32, std::vector<WorldLocation>>> rpgLocsCacheLevel;
|
|
std::map<TeamId, std::map<BattlegroundTypeId, std::vector<uint32>>> BattleMastersCache;
|
|
std::unordered_map<uint32, BotEventCache> eventCache;
|
|
std::list<uint32> currentBots;
|
|
uint32 bgBotsCount;
|
|
uint32 playersLevel;
|
|
|
|
// Account lists
|
|
std::vector<uint32> rndBotTypeAccounts; // Accounts marked as RNDbot (type 1)
|
|
std::vector<uint32> addClassTypeAccounts; // Accounts marked as AddClass (type 2)
|
|
|
|
//void ScaleBotActivity(); // Deprecated function
|
|
static inline uint32 NowSeconds() { return static_cast<uint32>(GameTime::GetGameTime().count()); }
|
|
};
|
|
|
|
#define sRandomPlayerbotMgr RandomPlayerbotMgr::instance()
|
|
|
|
#endif
|