exp modifiers, pets, timers

This commit is contained in:
Chris Miles 2025-05-17 15:43:31 -05:00
parent 36fc7b6e7f
commit 2c1cb55f14
6 changed files with 102 additions and 109 deletions

View File

@ -22,6 +22,7 @@
#include "ptimer.h" #include "ptimer.h"
#include "database.h" #include "database.h"
#include "strings.h" #include "strings.h"
#include "repositories/timers_repository.h"
#ifdef _WINDOWS #ifdef _WINDOWS
#include <winsock2.h> #include <winsock2.h>
@ -149,27 +150,6 @@ bool PersistentTimer::Load(Database *db) {
return true; return true;
} }
bool PersistentTimer::Store(Database *db) {
if(Expired(db, false)) //dont need to store expired timers.
return true;
std::string query = StringFormat("REPLACE INTO timers "
" (char_id, type, start, duration, enable) "
" VALUES (%lu, %u, %lu, %lu, %d)",
(unsigned long)_char_id, _type, (unsigned long)start_time,
(unsigned long)timer_time, enabled ? 1: 0);
#ifdef DEBUG_PTIMERS
printf("Storing timer: char %lu of type %u: '%s'\n", (unsigned long)_char_id, _type, query.c_str());
#endif
auto results = db->QueryDatabase(query);
if (!results.Success()) {
return false;
}
return true;
}
bool PersistentTimer::Clear(Database *db) { bool PersistentTimer::Clear(Database *db) {
std::string query = StringFormat("DELETE FROM timers " std::string query = StringFormat("DELETE FROM timers "
@ -304,27 +284,34 @@ bool PTimerList::Load(Database *db) {
return true; return true;
} }
bool PTimerList::Store(Database *db) { bool PTimerList::Store(Database *db)
#ifdef DEBUG_PTIMERS {
printf("Storing all timers for char %lu\n", (unsigned long)_char_id); auto e = TimersRepository::NewEntity();
#endif std::vector<TimersRepository::Timers> entries;
std::map<pTimerType, PersistentTimer *>::iterator s; for (auto &[type, timer] : _list) {
s = _list.begin(); if (!timer) {
bool res = true; continue;
while(s != _list.end()) {
if(s->second != nullptr) {
#ifdef DEBUG_PTIMERS
printf("Storing timer %u for char %lu\n", s->first, (unsigned long)_char_id);
#endif
if(!s->second->Store(db))
res = false;
} }
++s;
e.char_id = _char_id;
e.type = type;
e.start = timer->GetStartTime();
e.duration = timer->GetTimerTime();
e.enable = timer->Enabled() ? 1 : 0;
entries.emplace_back(e);
} }
return(res);
if (!entries.empty()) {
Expired(db, false);
TimersRepository::ReplaceMany(*db, entries);
} }
return true;
}
bool PTimerList::Clear(Database *db) { bool PTimerList::Clear(Database *db) {
_list.clear(); _list.clear();

View File

@ -91,7 +91,6 @@ public:
inline bool Enabled() { return enabled; } inline bool Enabled() { return enabled; }
bool Load(Database *db); bool Load(Database *db);
bool Store(Database *db);
bool Clear(Database *db); bool Clear(Database *db);
protected: protected:

View File

@ -115,8 +115,8 @@ public:
uint8_t lfg; uint8_t lfg;
std::string mailkey; std::string mailkey;
uint8_t xtargets; uint8_t xtargets;
uint8_t ingame;
uint32_t first_login; uint32_t first_login;
uint8_t ingame;
uint32_t e_aa_effects; uint32_t e_aa_effects;
uint32_t e_percent_to_aa; uint32_t e_percent_to_aa;
uint32_t e_expended_aa_spent; uint32_t e_expended_aa_spent;
@ -231,8 +231,8 @@ public:
"lfg", "lfg",
"mailkey", "mailkey",
"xtargets", "xtargets",
"ingame",
"first_login", "first_login",
"ingame",
"e_aa_effects", "e_aa_effects",
"e_percent_to_aa", "e_percent_to_aa",
"e_expended_aa_spent", "e_expended_aa_spent",
@ -343,8 +343,8 @@ public:
"lfg", "lfg",
"mailkey", "mailkey",
"xtargets", "xtargets",
"ingame",
"first_login", "first_login",
"ingame",
"e_aa_effects", "e_aa_effects",
"e_percent_to_aa", "e_percent_to_aa",
"e_expended_aa_spent", "e_expended_aa_spent",
@ -489,8 +489,8 @@ public:
e.lfg = 0; e.lfg = 0;
e.mailkey = ""; e.mailkey = "";
e.xtargets = 5; e.xtargets = 5;
e.ingame = 0;
e.first_login = 0; e.first_login = 0;
e.ingame = 0;
e.e_aa_effects = 0; e.e_aa_effects = 0;
e.e_percent_to_aa = 0; e.e_percent_to_aa = 0;
e.e_expended_aa_spent = 0; e.e_expended_aa_spent = 0;
@ -631,8 +631,8 @@ public:
e.lfg = row[93] ? static_cast<uint8_t>(strtoul(row[93], nullptr, 10)) : 0; e.lfg = row[93] ? static_cast<uint8_t>(strtoul(row[93], nullptr, 10)) : 0;
e.mailkey = row[94] ? row[94] : ""; e.mailkey = row[94] ? row[94] : "";
e.xtargets = row[95] ? static_cast<uint8_t>(strtoul(row[95], nullptr, 10)) : 5; e.xtargets = row[95] ? static_cast<uint8_t>(strtoul(row[95], nullptr, 10)) : 5;
e.ingame = row[96] ? static_cast<uint8_t>(strtoul(row[96], nullptr, 10)) : 0; e.first_login = row[96] ? static_cast<uint32_t>(strtoul(row[96], nullptr, 10)) : 0;
e.first_login = row[97] ? static_cast<uint32_t>(strtoul(row[97], nullptr, 10)) : 0; e.ingame = row[97] ? static_cast<uint8_t>(strtoul(row[97], nullptr, 10)) : 0;
e.e_aa_effects = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0; e.e_aa_effects = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0;
e.e_percent_to_aa = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0; e.e_percent_to_aa = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0;
e.e_expended_aa_spent = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0; e.e_expended_aa_spent = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0;
@ -769,8 +769,8 @@ public:
v.push_back(columns[93] + " = " + std::to_string(e.lfg)); v.push_back(columns[93] + " = " + std::to_string(e.lfg));
v.push_back(columns[94] + " = '" + Strings::Escape(e.mailkey) + "'"); v.push_back(columns[94] + " = '" + Strings::Escape(e.mailkey) + "'");
v.push_back(columns[95] + " = " + std::to_string(e.xtargets)); v.push_back(columns[95] + " = " + std::to_string(e.xtargets));
v.push_back(columns[96] + " = " + std::to_string(e.ingame)); v.push_back(columns[96] + " = " + std::to_string(e.first_login));
v.push_back(columns[97] + " = " + std::to_string(e.first_login)); v.push_back(columns[97] + " = " + std::to_string(e.ingame));
v.push_back(columns[98] + " = " + std::to_string(e.e_aa_effects)); v.push_back(columns[98] + " = " + std::to_string(e.e_aa_effects));
v.push_back(columns[99] + " = " + std::to_string(e.e_percent_to_aa)); v.push_back(columns[99] + " = " + std::to_string(e.e_percent_to_aa));
v.push_back(columns[100] + " = " + std::to_string(e.e_expended_aa_spent)); v.push_back(columns[100] + " = " + std::to_string(e.e_expended_aa_spent));
@ -896,8 +896,8 @@ public:
v.push_back(std::to_string(e.lfg)); v.push_back(std::to_string(e.lfg));
v.push_back("'" + Strings::Escape(e.mailkey) + "'"); v.push_back("'" + Strings::Escape(e.mailkey) + "'");
v.push_back(std::to_string(e.xtargets)); v.push_back(std::to_string(e.xtargets));
v.push_back(std::to_string(e.ingame));
v.push_back(std::to_string(e.first_login)); v.push_back(std::to_string(e.first_login));
v.push_back(std::to_string(e.ingame));
v.push_back(std::to_string(e.e_aa_effects)); v.push_back(std::to_string(e.e_aa_effects));
v.push_back(std::to_string(e.e_percent_to_aa)); v.push_back(std::to_string(e.e_percent_to_aa));
v.push_back(std::to_string(e.e_expended_aa_spent)); v.push_back(std::to_string(e.e_expended_aa_spent));
@ -1031,8 +1031,8 @@ public:
v.push_back(std::to_string(e.lfg)); v.push_back(std::to_string(e.lfg));
v.push_back("'" + Strings::Escape(e.mailkey) + "'"); v.push_back("'" + Strings::Escape(e.mailkey) + "'");
v.push_back(std::to_string(e.xtargets)); v.push_back(std::to_string(e.xtargets));
v.push_back(std::to_string(e.ingame));
v.push_back(std::to_string(e.first_login)); v.push_back(std::to_string(e.first_login));
v.push_back(std::to_string(e.ingame));
v.push_back(std::to_string(e.e_aa_effects)); v.push_back(std::to_string(e.e_aa_effects));
v.push_back(std::to_string(e.e_percent_to_aa)); v.push_back(std::to_string(e.e_percent_to_aa));
v.push_back(std::to_string(e.e_expended_aa_spent)); v.push_back(std::to_string(e.e_expended_aa_spent));
@ -1170,8 +1170,8 @@ public:
e.lfg = row[93] ? static_cast<uint8_t>(strtoul(row[93], nullptr, 10)) : 0; e.lfg = row[93] ? static_cast<uint8_t>(strtoul(row[93], nullptr, 10)) : 0;
e.mailkey = row[94] ? row[94] : ""; e.mailkey = row[94] ? row[94] : "";
e.xtargets = row[95] ? static_cast<uint8_t>(strtoul(row[95], nullptr, 10)) : 5; e.xtargets = row[95] ? static_cast<uint8_t>(strtoul(row[95], nullptr, 10)) : 5;
e.ingame = row[96] ? static_cast<uint8_t>(strtoul(row[96], nullptr, 10)) : 0; e.first_login = row[96] ? static_cast<uint32_t>(strtoul(row[96], nullptr, 10)) : 0;
e.first_login = row[97] ? static_cast<uint32_t>(strtoul(row[97], nullptr, 10)) : 0; e.ingame = row[97] ? static_cast<uint8_t>(strtoul(row[97], nullptr, 10)) : 0;
e.e_aa_effects = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0; e.e_aa_effects = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0;
e.e_percent_to_aa = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0; e.e_percent_to_aa = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0;
e.e_expended_aa_spent = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0; e.e_expended_aa_spent = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0;
@ -1300,8 +1300,8 @@ public:
e.lfg = row[93] ? static_cast<uint8_t>(strtoul(row[93], nullptr, 10)) : 0; e.lfg = row[93] ? static_cast<uint8_t>(strtoul(row[93], nullptr, 10)) : 0;
e.mailkey = row[94] ? row[94] : ""; e.mailkey = row[94] ? row[94] : "";
e.xtargets = row[95] ? static_cast<uint8_t>(strtoul(row[95], nullptr, 10)) : 5; e.xtargets = row[95] ? static_cast<uint8_t>(strtoul(row[95], nullptr, 10)) : 5;
e.ingame = row[96] ? static_cast<uint8_t>(strtoul(row[96], nullptr, 10)) : 0; e.first_login = row[96] ? static_cast<uint32_t>(strtoul(row[96], nullptr, 10)) : 0;
e.first_login = row[97] ? static_cast<uint32_t>(strtoul(row[97], nullptr, 10)) : 0; e.ingame = row[97] ? static_cast<uint8_t>(strtoul(row[97], nullptr, 10)) : 0;
e.e_aa_effects = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0; e.e_aa_effects = row[98] ? static_cast<uint32_t>(strtoul(row[98], nullptr, 10)) : 0;
e.e_percent_to_aa = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0; e.e_percent_to_aa = row[99] ? static_cast<uint32_t>(strtoul(row[99], nullptr, 10)) : 0;
e.e_expended_aa_spent = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0; e.e_expended_aa_spent = row[100] ? static_cast<uint32_t>(strtoul(row[100], nullptr, 10)) : 0;
@ -1480,8 +1480,8 @@ public:
v.push_back(std::to_string(e.lfg)); v.push_back(std::to_string(e.lfg));
v.push_back("'" + Strings::Escape(e.mailkey) + "'"); v.push_back("'" + Strings::Escape(e.mailkey) + "'");
v.push_back(std::to_string(e.xtargets)); v.push_back(std::to_string(e.xtargets));
v.push_back(std::to_string(e.ingame));
v.push_back(std::to_string(e.first_login)); v.push_back(std::to_string(e.first_login));
v.push_back(std::to_string(e.ingame));
v.push_back(std::to_string(e.e_aa_effects)); v.push_back(std::to_string(e.e_aa_effects));
v.push_back(std::to_string(e.e_percent_to_aa)); v.push_back(std::to_string(e.e_percent_to_aa));
v.push_back(std::to_string(e.e_expended_aa_spent)); v.push_back(std::to_string(e.e_expended_aa_spent));
@ -1608,8 +1608,8 @@ public:
v.push_back(std::to_string(e.lfg)); v.push_back(std::to_string(e.lfg));
v.push_back("'" + Strings::Escape(e.mailkey) + "'"); v.push_back("'" + Strings::Escape(e.mailkey) + "'");
v.push_back(std::to_string(e.xtargets)); v.push_back(std::to_string(e.xtargets));
v.push_back(std::to_string(e.ingame));
v.push_back(std::to_string(e.first_login)); v.push_back(std::to_string(e.first_login));
v.push_back(std::to_string(e.ingame));
v.push_back(std::to_string(e.e_aa_effects)); v.push_back(std::to_string(e.e_aa_effects));
v.push_back(std::to_string(e.e_percent_to_aa)); v.push_back(std::to_string(e.e_percent_to_aa));
v.push_back(std::to_string(e.e_expended_aa_spent)); v.push_back(std::to_string(e.e_expended_aa_spent));

View File

@ -11478,9 +11478,8 @@ void Client::SaveSpells()
} }
} }
CharacterSpellsRepository::DeleteWhere(database, fmt::format("id = {}", CharacterID()));
if (!character_spells.empty()) { if (!character_spells.empty()) {
CharacterSpellsRepository::DeleteWhere(database, fmt::format("id = {}", CharacterID()));
CharacterSpellsRepository::InsertMany(database, character_spells); CharacterSpellsRepository::InsertMany(database, character_spells);
} }
} }

View File

@ -827,6 +827,8 @@ void Client::CompleteConnect()
parse->EventPlayer(EVENT_CONNECT, this, export_string, 0); parse->EventPlayer(EVENT_CONNECT, this, export_string, 0);
} }
RecordStats();
if (is_first_login) { if (is_first_login) {
e.first_login = time(nullptr); e.first_login = time(nullptr);
TraderRepository::DeleteWhere(database, fmt::format("`char_id` = '{}'", CharacterID())); TraderRepository::DeleteWhere(database, fmt::format("`char_id` = '{}'", CharacterID()));
@ -1002,7 +1004,6 @@ void Client::CompleteConnect()
safe_delete(p); safe_delete(p);
} }
RecordStats();
AutoGrantAAPoints(); AutoGrantAAPoints();
// set initial position for mob tracking // set initial position for mob tracking
@ -1366,22 +1367,22 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
// set to full support in case they're a gm with items in disabled expansion slots...but, have their gm flag off... // set to full support in case they're a gm with items in disabled expansion slots...but, have their gm flag off...
// item loss will occur when they use the 'empty' slots, if this is not done // item loss will occur when they use the 'empty' slots, if this is not done
m_inv.SetGMInventory(true); m_inv.SetGMInventory(true);
loaditems = database.GetInventory(this); /* Load Character Inventory */ loaditems = database.GetInventory(this);
database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */ database.LoadCharacterData(cid, &m_pp, &m_epp);
database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */ database.LoadCharacterBandolier(cid, &m_pp);
database.LoadCharacterMaterialColor(cid, &m_pp); /* Load Character Material */ database.LoadCharacterBindPoint(cid, &m_pp);
database.LoadCharacterPotionBelt(cid, &m_pp); /* Load Character Potion Belt */ database.LoadCharacterMaterialColor(cid, &m_pp);
database.LoadCharacterCurrency(cid, &m_pp); /* Load Character Currency into PP */ database.LoadCharacterPotionBelt(cid, &m_pp);
database.LoadCharacterData(cid, &m_pp, &m_epp); /* Load Character Data from DB into PP as well as E_PP */ database.LoadCharacterCurrency(cid, &m_pp);
database.LoadCharacterSkills(cid, &m_pp); /* Load Character Skills */ database.LoadCharacterSkills(cid, &m_pp);
database.LoadCharacterInspectMessage(cid, &m_inspect_message); /* Load Character Inspect Message */ database.LoadCharacterInspectMessage(cid, &m_inspect_message);
database.LoadCharacterSpellBook(cid, &m_pp); /* Load Character Spell Book */ database.LoadCharacterSpellBook(cid, &m_pp);
database.LoadCharacterMemmedSpells(cid, &m_pp); /* Load Character Memorized Spells */ database.LoadCharacterMemmedSpells(cid, &m_pp);
database.LoadCharacterLanguages(cid, &m_pp); /* Load Character Languages */ database.LoadCharacterLanguages(cid, &m_pp);
database.LoadCharacterLeadershipAbilities(cid, &m_pp); /* Load Character Leadership AA's */ database.LoadCharacterLeadershipAbilities(cid, &m_pp);
database.LoadCharacterTribute(this); /* Load CharacterTribute */ database.LoadCharacterTribute(this);
database.LoadCharacterEXPModifier(this); /* Load Character EXP Modifier */ database.LoadCharacterEXPModifier(this);
database.LoadCharacterTitleSets(this); /* Load Character Title Sets */ database.LoadCharacterTitleSets(this);
// this pattern is strange // this pattern is strange
// this is remnants of the old way of doing things // this is remnants of the old way of doing things

View File

@ -642,8 +642,8 @@ bool ZoneDatabase::LoadCharacterLanguages(uint32 character_id, PlayerProfile_Str
return false; return false;
} }
for (int i = 0; i < MAX_PP_LANGUAGE; ++i) { // Initialize Languages for (unsigned char & language : pp->languages) { // Initialize Languages
pp->languages[i] = 0; language = 0;
} }
for (const auto& e : l) { for (const auto& e : l) {
@ -689,8 +689,8 @@ bool ZoneDatabase::LoadCharacterDisciplines(Client* c)
return false; return false;
} }
for (int slot_id = 0; slot_id < MAX_PP_DISCIPLINES; slot_id++) { for (unsigned int & value : c->GetPP().disciplines.values) {
c->GetPP().disciplines.values[slot_id] = 0; value = 0;
} }
for (const auto& e : l) { for (const auto& e : l) {
@ -2879,14 +2879,6 @@ void ZoneDatabase::UpdateAltCurrencyValue(uint32 char_id, uint32 currency_id, ui
void ZoneDatabase::SaveBuffs(Client *client) void ZoneDatabase::SaveBuffs(Client *client)
{ {
CharacterBuffsRepository::DeleteWhere(
database,
fmt::format(
"`character_id` = {}",
client->CharacterID()
)
);
auto buffs = client->GetBuffs(); auto buffs = client->GetBuffs();
const int max_buff_slots = client->GetMaxBuffSlots(); const int max_buff_slots = client->GetMaxBuffSlots();
@ -2904,6 +2896,16 @@ void ZoneDatabase::SaveBuffs(Client *client)
character_buff_count++; character_buff_count++;
} }
if (character_buff_count) {
CharacterBuffsRepository::DeleteWhere(
database,
fmt::format(
"`character_id` = {}",
client->CharacterID()
)
);
}
v.reserve(character_buff_count); v.reserve(character_buff_count);
for (int slot_id = 0; slot_id < max_buff_slots; slot_id++) { for (int slot_id = 0; slot_id < max_buff_slots; slot_id++) {
@ -3170,6 +3172,7 @@ void ZoneDatabase::SavePetInfo(Client *client)
} }
} }
if (!pet_infos.empty()) {
CharacterPetInfoRepository::DeleteWhere( CharacterPetInfoRepository::DeleteWhere(
database, database,
fmt::format( fmt::format(
@ -3178,10 +3181,10 @@ void ZoneDatabase::SavePetInfo(Client *client)
) )
); );
if (!pet_infos.empty()) {
CharacterPetInfoRepository::InsertMany(database, pet_infos); CharacterPetInfoRepository::InsertMany(database, pet_infos);
} }
if (!pet_buffs.empty()) {
CharacterPetBuffsRepository::DeleteWhere( CharacterPetBuffsRepository::DeleteWhere(
database, database,
fmt::format( fmt::format(
@ -3190,10 +3193,10 @@ void ZoneDatabase::SavePetInfo(Client *client)
) )
); );
if (!pet_buffs.empty()) {
CharacterPetBuffsRepository::InsertMany(database, pet_buffs); CharacterPetBuffsRepository::InsertMany(database, pet_buffs);
} }
if (!inventory.empty()) {
CharacterPetInventoryRepository::DeleteWhere( CharacterPetInventoryRepository::DeleteWhere(
database, database,
fmt::format( fmt::format(
@ -3202,7 +3205,6 @@ void ZoneDatabase::SavePetInfo(Client *client)
) )
); );
if (!inventory.empty()) {
CharacterPetInventoryRepository::InsertMany(database, inventory); CharacterPetInventoryRepository::InsertMany(database, inventory);
} }
} }
@ -4261,6 +4263,11 @@ void ZoneDatabase::SaveCharacterEXPModifier(Client* c)
EXPModifier m = zone->exp_modifiers[c->CharacterID()]; EXPModifier m = zone->exp_modifiers[c->CharacterID()];
// if both modifiers are 0, we don't need to save
if (m.aa_modifier == 0 && m.exp_modifier == 0) {
return;
}
CharacterExpModifiersRepository::ReplaceOne( CharacterExpModifiersRepository::ReplaceOne(
*this, *this,
CharacterExpModifiersRepository::CharacterExpModifiers{ CharacterExpModifiersRepository::CharacterExpModifiers{