diff --git a/src/Util/PerfMonitor.cpp b/src/Bot/Handler/Command/PerfMonitor.cpp similarity index 100% rename from src/Util/PerfMonitor.cpp rename to src/Bot/Handler/Command/PerfMonitor.cpp diff --git a/src/Util/PerfMonitor.h b/src/Bot/Handler/Command/PerfMonitor.h similarity index 100% rename from src/Util/PerfMonitor.h rename to src/Bot/Handler/Command/PerfMonitor.h diff --git a/src/Util/Helpers.cpp b/src/Util/Helpers.cpp index 84d34c12..fab0b483 100644 --- a/src/Util/Helpers.cpp +++ b/src/Util/Helpers.cpp @@ -5,6 +5,17 @@ #include "Helpers.h" +#include +#include +#include +#include +#include +#include +#include + +/** + * Case-insensitive substring search. + */ char* strstri(char const* haystack, char const* needle) { if (!*needle) @@ -16,7 +27,9 @@ char* strstri(char const* haystack, char const* needle) { if (tolower(*haystack) == tolower(*needle)) { - char const *h = haystack, *n = needle; + char const* h = haystack; + char const* n = needle; + for (; *h && *n; ++h, ++n) { if (tolower(*h) != tolower(*n)) @@ -35,16 +48,67 @@ char* strstri(char const* haystack, char const* needle) return 0; } +/** + * Trim whitespace from the left side of a string (in place). + */ std::string& ltrim(std::string& s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int c) { return !std::isspace(c); })); return s; } +/** + * Trim whitespace from the right side of a string (in place). + */ std::string& rtrim(std::string& s) { s.erase(std::find_if(s.rbegin(), s.rend(), [](int c) { return !std::isspace(c); }).base(), s.end()); return s; } +/** + * Trim whitespace from both ends of a string (in place). + */ std::string& trim(std::string& s) { return ltrim(rtrim(s)); } + +/** + * Split a string using a C-string delimiter. + */ +void split(std::vector& dest, std::string const str, char const* delim) +{ + char* pTempStr = strdup(str.c_str()); + char* pWord = strtok(pTempStr, delim); + + while (pWord != nullptr) + { + dest.push_back(pWord); + pWord = strtok(nullptr, delim); + } + + free(pTempStr); +} + +/** + * Split a string using a single character delimiter. + */ +std::vector& split(std::string const s, char delim, std::vector& elems) +{ + std::stringstream ss(s); + std::string item; + + while (getline(ss, item, delim)) + { + elems.push_back(item); + } + + return elems; +} + +/** + * Split a string using a single character delimiter. + */ +std::vector split(std::string const s, char delim) +{ + std::vector elems; + return split(s, delim, elems); +} diff --git a/src/Util/Helpers.h b/src/Util/Helpers.h index 6a648ad1..90d5b642 100644 --- a/src/Util/Helpers.h +++ b/src/Util/Helpers.h @@ -6,50 +6,68 @@ #ifndef _PLAYERBOT_HELPERS_H #define _PLAYERBOT_HELPERS_H -#include -#include - -#include -#include -#include -#include -#include -#include +#include #include -#include "Common.h" +/** + * Case-insensitive substring search. + * + * @param haystack The string to search in + * @param needle The substring to search for + * @return Pointer to the first matching position in haystack, or nullptr if not found. + */ +char* strstri(char const* haystack, char const* needle); -void split(std::vector& dest, std::string const str, char const* delim) -{ - char* pTempStr = strdup(str.c_str()); - char* pWord = strtok(pTempStr, delim); +/** + * Trim whitespace from the left side of a string (in place). + * + * @param s The string to trim + * @return Reference to the modified string + */ +std::string& ltrim(std::string& s); - while (pWord != nullptr) - { - dest.push_back(pWord); - pWord = strtok(nullptr, delim); - } +/** + * Trim whitespace from the right side of a string (in place). + * + * @param s The string to trim + * @return Reference to the modified string + */ +std::string& rtrim(std::string& s); - free(pTempStr); -} +/** + * Trim whitespace from both ends of a string (in place). + * + * @param s The string to trim + * @return Reference to the modified string + */ +std::string& trim(std::string& s); -std::vector& split(std::string const s, char delim, std::vector& elems) -{ - std::stringstream ss(s); - std::string item; +/** + * Split a string using a C-string delimiter. + * + * @param dest Vector to store split tokens + * @param str String to split + * @param delim C-string delimiter + */ +void split(std::vector& dest, std::string const str, char const* delim); - while (getline(ss, item, delim)) - { - elems.push_back(item); - } +/** + * Split a string using a single character delimiter. + * + * @param s String to split + * @param delim Delimiter character + * @param elems Vector to store split tokens + * @return Reference to the vector containing tokens + */ +std::vector& split(std::string const s, char delim, std::vector& elems); - return elems; -} - -std::vector split(std::string const s, char delim) -{ - std::vector elems; - return split(s, delim, elems); -} +/** + * Split a string using a single character delimiter. + * + * @param s String to split + * @param delim Delimiter character + * @return Vector containing split tokens + */ +std::vector split(std::string const s, char delim); #endif diff --git a/src/Util/LazyCalculatedValue.h b/src/Util/LazyCalculatedValue.h index 84497b8a..bef54e2d 100644 --- a/src/Util/LazyCalculatedValue.h +++ b/src/Util/LazyCalculatedValue.h @@ -6,16 +6,45 @@ #ifndef _PLAYERBOT_LAZYCALCULATEDVALUE_H #define _PLAYERBOT_LAZYCALCULATEDVALUE_H +/** + * @brief Lazy calculation helper. + * + * Stores a function pointer (calculator) and its owner instance, and + * calculates the value only when it is requested for the first time. + * The result is cached until Reset() is called. + * + * @tparam TValue Type of the calculated value. + * @tparam TOwner Type of the owner class containing the calculator function. + */ template class LazyCalculatedValue { public: + /** + * @brief Type of the calculator function. + * + * This is a pointer to a member function of TOwner returning TValue. + */ typedef TValue (TOwner::*Calculator)(); public: + /** + * @brief Constructor. + * + * @param owner Pointer to the owner object. + * @param calculator Pointer to the member function used to calculate the value. + */ LazyCalculatedValue(TOwner* owner, Calculator calculator) : calculator(calculator), owner(owner) { Reset(); } public: + /** + * @brief Get the cached value or calculate it if needed. + * + * If the value has not been calculated yet, it calls the calculator + * on the owner and caches the result. + * + * @return TValue The calculated or cached value. + */ TValue GetValue() { if (!calculated) @@ -27,13 +56,19 @@ public: return value; } + /** + * @brief Reset the cached state. + * + * After calling Reset(), the next call to GetValue() will recalculate + * the value again. + */ void Reset() { calculated = false; } protected: - Calculator calculator; - TOwner* owner; - bool calculated; - TValue value; + Calculator calculator; ///< Pointer to calculator member function + TOwner* owner; ///< Owner instance + bool calculated; ///< Whether value has already been calculated + TValue value; ///< Cached value }; #endif diff --git a/src/Util/ServerFacade.cpp b/src/Util/ServerFacade.cpp index dda19aeb..d69944c0 100644 --- a/src/Util/ServerFacade.cpp +++ b/src/Util/ServerFacade.cpp @@ -45,11 +45,13 @@ void ServerFacade::SetFacingTo(Player* bot, WorldObject* wo, bool force) return; float angle = bot->GetAngle(wo); + // if (!force && bot->isMoving()) // bot->SetFacingTo(bot->GetAngle(wo)); // else // { bot->SetOrientation(angle); + if (!bot->IsRooted()) bot->SendMovementFlagUpdate(); // } @@ -64,16 +66,14 @@ Unit* ServerFacade::GetChaseTarget(Unit* target) { return static_cast const*>(movementGen)->GetTarget(); } - else - { - return static_cast const*>(movementGen)->GetTarget(); - } + + return static_cast const*>(movementGen)->GetTarget(); } return nullptr; } -void ServerFacade::SendPacket(Player *player, WorldPacket *packet) +void ServerFacade::SendPacket(Player* player, WorldPacket* packet) { - return player->GetSession()->SendPacket(packet); + player->GetSession()->SendPacket(packet); } diff --git a/src/Util/ServerFacade.h b/src/Util/ServerFacade.h index 0ea93f07..6668fa95 100644 --- a/src/Util/ServerFacade.h +++ b/src/Util/ServerFacade.h @@ -13,11 +13,24 @@ class Unit; class WorldObject; class WorldPacket; +/** + * @brief Provides a simplified interface to server engine operations. + * + * ServerFacade acts as a wrapper around common server functions used by + * the Playerbot system. It centralizes utility methods for distance + * calculations, facing, chase target retrieval, and packet sending. + */ class ServerFacade { public: - ServerFacade(){}; - virtual ~ServerFacade(){}; + ServerFacade() {} + virtual ~ServerFacade() {} + + /** + * @brief Get singleton instance. + * + * @return ServerFacade* Pointer to the singleton instance. + */ static ServerFacade* instance() { static ServerFacade instance; @@ -25,19 +38,92 @@ public: } public: + /** + * @brief Get 2D distance between a unit and a world object. + * + * The result is rounded to one decimal place. + * + * @param unit Source unit. + * @param wo Target world object. + * @return float Distance in yards. + */ float GetDistance2d(Unit* unit, WorldObject* wo); + + /** + * @brief Get 2D distance between a unit and coordinates. + * + * The result is rounded to one decimal place. + * + * @param unit Source unit. + * @param x Target X coordinate. + * @param y Target Y coordinate. + * @return float Distance in yards. + */ float GetDistance2d(Unit* unit, float x, float y); + + /** + * @brief Compare two distances. + * + * @param dist1 First distance. + * @param dist2 Second distance. + * @return true if dist1 < dist2. + */ bool IsDistanceLessThan(float dist1, float dist2); + + /** + * @brief Compare two distances. + * + * @param dist1 First distance. + * @param dist2 Second distance. + * @return true if dist1 > dist2. + */ bool IsDistanceGreaterThan(float dist1, float dist2); + + /** + * @brief Compare two distances. + * + * @param dist1 First distance. + * @param dist2 Second distance. + * @return true if dist1 >= dist2. + */ bool IsDistanceGreaterOrEqualThan(float dist1, float dist2); + + /** + * @brief Compare two distances. + * + * @param dist1 First distance. + * @param dist2 Second distance. + * @return true if dist1 <= dist2. + */ bool IsDistanceLessOrEqualThan(float dist1, float dist2); + /** + * @brief Set bot facing towards a world object. + * + * @param bot Player bot to rotate. + * @param wo Target world object. + * @param force If true, force facing even while moving. + */ void SetFacingTo(Player* bot, WorldObject* wo, bool force = false); + + /** + * @brief Get the current chase target of a unit. + * + * @param target Unit that is chasing. + * @return Unit* The chase target, or nullptr if not chasing. + */ Unit* GetChaseTarget(Unit* target); - void SendPacket(Player *player, WorldPacket* packet); + /** + * @brief Send a raw packet to a player. + * + * @param player Player to receive the packet. + * @param packet Packet to send. + */ + void SendPacket(Player* player, WorldPacket* packet); }; +/** Global singleton accessor. */ #define sServerFacade ServerFacade::instance() #endif