Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
elsongabriel committed May 22, 2024
1 parent abf46ee commit e8c3582
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 65 deletions.
73 changes: 53 additions & 20 deletions src/creatures/players/cyclopedia/player_cyclopedia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,18 @@ PlayerCyclopedia::PlayerCyclopedia(Player &player) :
m_player(player) { }

void PlayerCyclopedia::loadSummaryData() {

loadSummary();
loadRecentKills();
loadDeathHistory();
}

void PlayerCyclopedia::loadSummary() {
}

void PlayerCyclopedia::loadRecentKills() {
Benchmark bm_check;

Database &db = Database::getInstance();
Database &db = g_database();
const std::string &escapedName = db.escapeString(m_player.getName());
DBResult_ptr result = db.storeQuery(fmt::format("SELECT `d`.`time`, `d`.`killed_by`, `d`.`mostdamage_by`, `d`.`unjustified`, `d`.`mostdamage_unjustified`, `p`.`name` FROM `player_deaths` AS `d` INNER JOIN `players` AS `p` ON `d`.`player_id` = `p`.`id` WHERE ((`d`.`killed_by` = {} AND `d`.`is_player` = 1) OR (`d`.`mostdamage_by` = {} AND `d`.`mostdamage_is_player` = 1))", escapedName, escapedName));
if (result) {
Expand All @@ -47,9 +50,7 @@ void PlayerCyclopedia::loadRecentKills() {
}
}

std::ostringstream description;
description << "Killed " << name << '.';
insertPvpKillOnHistory(std::move(description.str()), result->getNumber<uint32_t>("time"), status);
insertPvpKillOnHistory(fmt::format("Killed {}.", name), result->getNumber<uint32_t>("time"), status);
} while (result->next());
}

Expand All @@ -59,8 +60,7 @@ void PlayerCyclopedia::loadRecentKills() {
void PlayerCyclopedia::loadDeathHistory() {
Benchmark bm_check;

Database &db = Database::getInstance();
DBResult_ptr result = db.storeQuery(fmt::format("SELECT `time`, `level`, `killed_by`, `mostdamage_by` FROM `player_deaths` WHERE `player_id` = {} ORDER BY `time` DESC", m_player.getGUID()));
DBResult_ptr result = g_database().storeQuery(fmt::format("SELECT `time`, `level`, `killed_by`, `mostdamage_by` FROM `player_deaths` WHERE `player_id` = {} ORDER BY `time` DESC", m_player.getGUID()));
if (result) {
do {
std::string cause1 = result->getString("killed_by");
Expand All @@ -86,6 +86,20 @@ void PlayerCyclopedia::loadDeathHistory() {
g_logger().debug("Checking and updating death history of player {} took {} milliseconds.", m_player.getName(), bm_check.duration());
}

void PlayerCyclopedia::updateStoreSummary(uint8_t type, uint16_t count, uint8_t itemType, uint8_t offerId, uint8_t blessId) {
updateAmount(type, count);
}

uint16_t PlayerCyclopedia::getAmount(uint8_t type) {
auto kv = m_player.kv()->scoped("summary")->scoped(g_game().getSummaryKeyByType(type))->get("amount");
return static_cast<uint16_t>(kv ? kv->getNumber() : 0);
}

void PlayerCyclopedia::updateAmount(uint8_t type, uint16_t toAddPoints) {
auto oldPoints = getAmount(type);
m_player.kv()->scoped("summary")->scoped(g_game().getSummaryKeyByType(type))->set("amount", oldPoints + toAddPoints);
}

std::vector<RecentDeathEntry> PlayerCyclopedia::getDeathHistory() const {
return m_deathHistory;
}
Expand All @@ -102,18 +116,37 @@ void PlayerCyclopedia::insertPvpKillOnHistory(std::string cause, uint32_t timest
m_pvpKillsHistory.emplace_back(std::move(cause), timestamp, status);
}

void PlayerCyclopedia::updateStoreSummary(uint8_t type, uint16_t count, uint8_t itemType, uint8_t offerId, uint8_t blessId) {
std::map<Blessings_t, uint16_t> PlayerCyclopedia::getBlessings() const {
}
void insertBlessings(uint8_t bless, uint32_t timestamp) {
}

// const std::shared_ptr<KV> &PlayerTitle::getSummary(std::string &key) {
// return m_player.kv()->scoped("titles")->scoped("summary")->get(key);
// }
//
// uint16_t PlayerAchievement::getPoints() const {
// return m_player.kv()->scoped("achievements")->get("points")->getNumber();
// }
//
// void PlayerAchievement::addPoints(uint16_t toAddPoints) {
// auto oldPoints = getPoints();
// m_player.kv()->scoped("achievements")->set("points", oldPoints + toAddPoints);
// }
std::vector<uint8_t> PlayerCyclopedia::getHirelingJobs() const {
}
void insertHirelingJobs(uint8_t job, uint32_t timestamp) {
}

std::vector<uint16_t> PlayerCyclopedia::getHirelingOutfits() const {
}
void insertHirelingOutfits(uint8_t outfit, uint32_t timestamp) {
}

std::map<uint32_t, uint16_t> PlayerCyclopedia::getHouseItems() const {
auto type = static_cast<uint8_t>(Summary_t::HOUSE_ITEMS);
auto kvItem = m_player.kv()->scoped("summary")->scoped(g_game().getSummaryKeyByType(type));

std::map<uint32_t, uint16_t> items = {};
for (const auto &itemId : kvItem->keys()) {
auto kv = kvItem->scoped(itemId)->get("amount");
auto amount = static_cast<uint16_t>(kv ? kv->getNumber() : 0);
items[std::stoull(itemId)] += amount;
}

return items;
}

void PlayerCyclopedia::insertHouseItems(uint32_t itemId, uint16_t amount) {
auto type = static_cast<uint8_t>(Summary_t::HOUSE_ITEMS);
auto oldAmount = static_cast<uint16_t>(m_houseItems[itemId]);
m_player.kv()->scoped("summary")->scoped(g_game().getSummaryKeyByType(type))->scoped(fmt::format("{}", itemId))->set("amount", oldAmount + amount);
}
68 changes: 32 additions & 36 deletions src/creatures/players/cyclopedia/player_cyclopedia.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,68 +9,64 @@

#pragma once

#include <creatures/creatures_definitions.hpp>
#include <utils/utils_definitions.hpp>
#include <enums/player_cyclopedia.hpp>

class Player;
class KV;

struct Summary {
uint16_t m_storeXpBoosts = 0;
uint16_t m_dailyRewardCollections = 0;
uint16_t m_xpBoosts = 0;
uint16_t m_preyWildcards = 0;
uint16_t m_instantRewards = 0;
uint16_t m_charmsExpansions = 0;
uint16_t m_hirelings = 0;
uint16_t m_preyCards = 0;
uint16_t m_charms = 0;
uint16_t m_goshnar = 0;
uint16_t m_drome = 0;
uint16_t m_loginStreak = 0;
uint16_t m_taskHuntingPoints = 0;
uint16_t m_mapAreaDiscoveredPercentage = 0;

std::vector<uint16_t> m_hirelingOutfits;
std::vector<uint8_t> m_hirelingJobs;
std::map<Blessings_t, uint16_t> m_blessings;

Summary(uint16_t mStoreXpBoosts, uint16_t mDailyRewardCollections, uint16_t mHirelings, uint16_t mPreyCards, uint16_t mCharms, uint16_t mGoshnar, uint16_t mDrome, uint16_t mLoginStreak, uint16_t mTaskHuntingPoints, uint16_t mMapAreaDiscoveredPercentage, const std::vector<uint16_t> &mHirelingOutfits, const std::vector<uint8_t> &mHirelingJobs, const std::map<Blessings_t, uint16_t> &mBlessings) :
m_storeXpBoosts(mStoreXpBoosts), m_dailyRewardCollections(mDailyRewardCollections), m_hirelings(mHirelings), m_preyCards(mPreyCards), m_charms(mCharms), m_goshnar(mGoshnar), m_drome(mDrome), m_loginStreak(mLoginStreak), m_taskHuntingPoints(mTaskHuntingPoints), m_mapAreaDiscoveredPercentage(mMapAreaDiscoveredPercentage), m_hirelingOutfits(mHirelingOutfits), m_hirelingJobs(mHirelingJobs), m_blessings(mBlessings) { }
Summary(uint16_t mXpBoosts, uint16_t mPreyWildcards, uint16_t mInstantRewards, uint16_t mCharmsExpansions, uint16_t mHirelings) :
m_xpBoosts(mXpBoosts), m_preyWildcards(mPreyWildcards), m_instantRewards(mInstantRewards), m_charmsExpansions(mCharmsExpansions), m_hirelings(mHirelings) { }
};

class PlayerCyclopedia {
public:
explicit PlayerCyclopedia(Player &player);

Summary getSummary() {
return Summary(m_storeXpBoosts, m_dailyRewardCollections, m_hirelings, m_preyCards, m_charms, m_goshnar, m_drome, m_loginStreak, m_taskHuntingPoints, m_mapAreaDiscoveredPercentage, m_hirelingOutfits, m_hirelingJobs, m_blessings);
}
void loadSummaryData();
void loadSummary();
void loadRecentKills();
void loadDeathHistory();

void updateStoreSummary(uint8_t type, uint16_t count = 1, uint8_t itemType = 0, uint8_t offerId = 0, uint8_t blessId = 0);
uint16_t getAmount(uint8_t type);
void updateAmount(uint8_t type, uint16_t toAddPoints);

[[nodiscard]] std::vector<RecentDeathEntry> getDeathHistory() const;
void insertDeathOnHistory(std::string cause, uint32_t timestamp);

[[nodiscard]] std::vector<RecentPvPKillEntry> getPvpKillsHistory() const;
void insertPvpKillOnHistory(std::string cause, uint32_t timestamp, uint8_t status);

void updateStoreSummary(uint8_t type, uint16_t count = 1, uint8_t itemType = 0, uint8_t offerId = 0, uint8_t blessId = 0);
const Summary &getSummary() {
return Summary(getAmount(Summary_t::BOOSTS), getAmount(Summary_t::PREY_WILDCARDS), getAmount(Summary_t::INSTANT_REWARDS), getAmount(Summary_t::CHARM_EXPANSIONS), getAmount(Summary_t::HIRELINGS));
}
[[nodiscard]] std::map<Blessings_t, uint16_t> getBlessings() const;
void insertBlessings(uint8_t bless, uint32_t timestamp);

private:
uint16_t m_storeXpBoosts = 0;
uint16_t m_dailyRewardCollections = 0;
uint16_t m_hirelings = 0;
uint16_t m_preyCards = 0;
uint16_t m_charms = 0;
uint16_t m_goshnar = 0;
uint16_t m_drome = 0;
uint16_t m_loginStreak = 0;
uint16_t m_taskHuntingPoints = 0;
uint16_t m_mapAreaDiscoveredPercentage = 0;
[[nodiscard]] std::vector<uint8_t> getHirelingJobs() const;
void insertHirelingJobs(uint8_t job, uint32_t timestamp);

std::vector<uint16_t> m_hirelingOutfits;
std::vector<uint8_t> m_hirelingJobs;
std::map<Blessings_t, uint16_t> m_blessings;
[[nodiscard]] std::vector<uint16_t> getHirelingOutfits() const;
void insertHirelingOutfits(uint8_t outfit, uint32_t timestamp);

// StashItemList houseItems;
// std::map<uint8_t, std::vector<uint16_t>> m_accountLevelSummary;
[[nodiscard]] std::map<uint32_t, uint16_t> getHouseItems() const;
void insertHouseItems(uint32_t itemId, uint16_t amount);

private:
std::vector<RecentDeathEntry> m_deathHistory;
std::vector<RecentPvPKillEntry> m_pvpKillsHistory;

std::map<Blessings_t, uint16_t> m_blessings;
std::vector<uint8_t> m_hirelingJobs;
std::vector<uint16_t> m_hirelingOutfits;
std::map<uint32_t, uint16_t> m_houseItems;
Player &m_player;
};
12 changes: 12 additions & 0 deletions src/enums/player_cyclopedia.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,15 @@ enum CyclopediaTitle_t : uint8_t {
MAP,
OTHERS,
};

enum Summary_t : uint8_t {
BOOSTS = 1,
PREY_SLOTS,
PREY_WILDCARDS,
INSTANT_REWARDS,
CHARM_EXPANSIONS,
HIRELINGS,
HIRELING_JOBS,
HIRELING_OUTFITS,
HOUSE_ITEMS,
};
12 changes: 12 additions & 0 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,18 @@ Game::Game() {
HighscoreCategory("Fishing", static_cast<uint8_t>(HighscoreCategories_t::FISHING)),
HighscoreCategory("Magic Level", static_cast<uint8_t>(HighscoreCategories_t::MAGIC_LEVEL))
};

m_summaryCategories = {
{ static_cast<uint8_t>(Summary_t::BOOSTS), "xp-boosts" },
{ static_cast<uint8_t>(Summary_t::PREY_SLOTS), "prey-slots" },
{ static_cast<uint8_t>(Summary_t::PREY_WILDCARDS), "prey-wildcards" },
{ static_cast<uint8_t>(Summary_t::INSTANT_REWARDS), "instant-rewards" },
{ static_cast<uint8_t>(Summary_t::CHARM_EXPANSIONS), "charm-expansions" },
{ static_cast<uint8_t>(Summary_t::HIRELINGS), "hirelings" },
{ static_cast<uint8_t>(Summary_t::HIRELING_JOBS), "hirelings-jobs" },
{ static_cast<uint8_t>(Summary_t::HIRELING_OUTFITS), "hireling-outfits" },
{ static_cast<uint8_t>(Summary_t::HOUSE_ITEMS), "house-items" },
};
}

Game::~Game() = default;
Expand Down
6 changes: 6 additions & 0 deletions src/game/game.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,10 @@ class Game {
Title getTitleById(uint8_t id);
Title getTitleByName(const std::string &name);

const std::string &getSummaryKeyByType(uint8_t type) {
return m_summaryCategories[type];
}

private:
std::map<uint16_t, Achievement> m_achievements;
std::map<std::string, uint16_t> m_achievementsNameToId;
Expand All @@ -742,6 +746,8 @@ class Game {
std::vector<HighscoreCategory> m_highscoreCategories;
std::unordered_map<uint8_t, std::string> m_highscoreCategoriesNames;

std::unordered_map<uint8_t, std::string> m_summaryCategories;

std::map<uint32_t, int32_t> forgeMonsterEventIds;
std::unordered_set<uint32_t> fiendishMonsters;
std::unordered_set<uint32_t> influencedMonsters;
Expand Down
50 changes: 41 additions & 9 deletions src/server/network/protocol/protocolgame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3941,19 +3941,51 @@ void ProtocolGame::sendCyclopediaCharacterStoreSummary() {

// getBlessingsObtained
auto blessings = player->getBlessingNames();
msg.addByte(static_cast<uint8_t>(blessings.size())); // getBlessingsObtained
msg.addByte(static_cast<uint8_t>(blessings.size()));
for (const auto &it : blessings) {
msg.addString(it.second, "ProtocolGame::sendCyclopediaCharacterStoreSummary - blessing.name");
msg.addByte(static_cast<uint8_t>((cyclopediaSummary.m_blessings)[it.first]));
msg.addByte(static_cast<uint8_t>((player->cyclopedia()->getBlessings())[it.first]));
}
msg.addByte(0x00); // getTaskHuntingSlotById
msg.addByte(0x00); // getPreyCardsObtained
msg.addByte(0x00); // getRewardCollectionObtained

uint8_t preySlotsUnlocked = 0;
// Prey third slot unlocked
if (const auto &slotP = player->getPreySlotById(PreySlot_Three);
slotP && slotP->state != PreyDataState_Locked) {
preySlotsUnlocked++;
}
// Task hunting third slot unlocked
if (const auto &slotH = player->getTaskHuntingSlotById(PreySlot_Three);
slotH && slotH->state != PreyTaskDataState_Locked) {
preySlotsUnlocked++;
}
msg.addByte(preySlotsUnlocked); // getPreySlotById + getTaskHuntingSlotById

msg.addByte(cyclopediaSummary.m_preyWildcards); // getPreyCardsObtained
msg.addByte(cyclopediaSummary.m_instantRewards); // getRewardCollectionObtained
msg.addByte(player->hasCharmExpansion() ? 0x01 : 0x00);
msg.addByte(0x00); // getHirelingsObtained
msg.addByte(0x00); // getHirelinsJobsObtained
msg.addByte(0x00); // getHirelinsOutfitsObtained
msg.add<uint16_t>(0); // getHouseItemsObtained
msg.addByte(cyclopediaSummary.m_hirelings); // getHirelingsObtained

auto jobs = player->cyclopedia()->getHirelingJobs();
msg.addByte(jobs.size());
for (const auto job_it : jobs) {
msg.addByte(job_it);
}

auto outfits = player->cyclopedia()->getHirelingOutfits();
msg.addByte(outfits.size());
for (const auto outfit_it : outfits) {
msg.addByte(outfit_it);
}

auto houseItems = player->cyclopedia()->getHouseItems();
msg.add<uint16_t>(houseItems.size());
for (const auto &hItem_it : houseItems) {
const ItemType &it = Item::items[hItem_it.first];
msg.add<uint16_t>(hItem_it.first); // Item ID
msg.addString(it.name, "ProtocolGame::sendCyclopediaCharacterStoreSummary - houseItem.name");
msg.addByte(hItem_it.second);
}

writeToOutputBuffer(msg);
}

Expand Down

0 comments on commit e8c3582

Please sign in to comment.