Skip to content

Commit

Permalink
perf: optimized account players badge loading (opentibiabr#2977)
Browse files Browse the repository at this point in the history
This change optimizes the player information retrieval process by
selecting only the pertinent details of each character instead of
loading all player objects for an account. This prevents unnecessary
memory allocation and reduces server load, especially in scenarios where
accounts have multiple characters.
  • Loading branch information
dudantas authored and vasconcellosdevictor committed Oct 24, 2024
1 parent a8333d1 commit 8d083b2
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 2 deletions.
36 changes: 34 additions & 2 deletions src/creatures/players/cyclopedia/player_badge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "game/game.hpp"
#include "kv/kv.hpp"

#include "enums/account_errors.hpp"

PlayerBadge::PlayerBadge(Player &player) :
m_player(player) { }

Expand Down Expand Up @@ -113,8 +115,38 @@ bool PlayerBadge::loyalty(uint8_t amount) {
return m_player.getLoyaltyPoints() >= amount;
}

std::vector<std::shared_ptr<Player>> PlayerBadge::getPlayersInfoByAccount(std::shared_ptr<Account> acc) const {
auto [accountPlayers, error] = acc->getAccountPlayers();
if (error != enumToValue(AccountErrors_t::Ok) || accountPlayers.empty()) {
return {};
}

std::string namesList;
for (const auto &[name, _] : accountPlayers) {
if (!namesList.empty()) {
namesList += ", ";
}
namesList += fmt::format("'{}'", name);
}

auto query = fmt::format("SELECT name, level, vocation FROM players WHERE name IN ({})", namesList);
std::vector<std::shared_ptr<Player>> players;
DBResult_ptr result = g_database().storeQuery(query);
if (result) {
do {
auto player = std::make_shared<Player>(nullptr);
player->setName(result->getString("name"));
player->setLevel(result->getNumber<uint32_t>("level"));
player->setVocation(result->getNumber<uint16_t>("vocation"));
players.push_back(player);
} while (result->next());
}

return players;
}

bool PlayerBadge::accountAllLevel(uint8_t amount) {
auto players = g_game().getPlayersByAccount(m_player.getAccount(), true);
auto players = getPlayersInfoByAccount(m_player.getAccount());
uint16_t total = std::accumulate(players.begin(), players.end(), 0, [](uint16_t sum, const std::shared_ptr<Player> &player) {
return sum + player->getLevel();
});
Expand All @@ -126,7 +158,7 @@ bool PlayerBadge::accountAllVocations(uint8_t amount) {
auto paladin = false;
auto druid = false;
auto sorcerer = false;
for (const auto &player : g_game().getPlayersByAccount(m_player.getAccount(), true)) {
for (const auto &player : getPlayersInfoByAccount(m_player.getAccount())) {
if (player->getLevel() >= amount) {
auto vocationEnum = player->getPlayerVocationEnum();
if (vocationEnum == Vocation_t::VOCATION_KNIGHT_CIP) {
Expand Down
2 changes: 2 additions & 0 deletions src/creatures/players/cyclopedia/player_badge.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

class Player;
class KV;
class Account;

struct Badge {
uint8_t m_id = 0;
Expand Down Expand Up @@ -52,6 +53,7 @@ class PlayerBadge {
// Badge Calculate Functions
bool accountAge(uint8_t amount);
bool loyalty(uint8_t amount);
std::vector<std::shared_ptr<Player>> getPlayersInfoByAccount(std::shared_ptr<Account> acc) const;
bool accountAllLevel(uint8_t amount);
bool accountAllVocations(uint8_t amount);
[[nodiscard]] bool tournamentParticipation(uint8_t skill);
Expand Down
3 changes: 3 additions & 0 deletions src/creatures/players/player.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,9 @@ class Player final : public Creature, public Cylinder, public Bankable {
uint32_t getLevel() const {
return level;
}
void setLevel(uint32_t newLevel) {
level = newLevel;
}
uint8_t getLevelPercent() const {
return levelPercent;
}
Expand Down

0 comments on commit 8d083b2

Please sign in to comment.