diff --git a/common/ptimer.cpp b/common/ptimer.cpp index d5f6ca162..7b7146232 100644 --- a/common/ptimer.cpp +++ b/common/ptimer.cpp @@ -22,6 +22,7 @@ #include "ptimer.h" #include "database.h" #include "strings.h" +#include "repositories/timers_repository.h" #ifdef _WINDOWS #include @@ -149,27 +150,6 @@ bool PersistentTimer::Load(Database *db) { 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) { std::string query = StringFormat("DELETE FROM timers " @@ -304,27 +284,34 @@ bool PTimerList::Load(Database *db) { return true; } -bool PTimerList::Store(Database *db) { -#ifdef DEBUG_PTIMERS - printf("Storing all timers for char %lu\n", (unsigned long)_char_id); -#endif +bool PTimerList::Store(Database *db) +{ + auto e = TimersRepository::NewEntity(); + std::vector entries; - std::map::iterator s; - s = _list.begin(); - bool res = true; - 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; + for (auto &[type, timer] : _list) { + if (!timer) { + continue; } - ++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) { _list.clear(); diff --git a/common/ptimer.h b/common/ptimer.h index ad5e5a8c8..b90848c27 100644 --- a/common/ptimer.h +++ b/common/ptimer.h @@ -91,7 +91,6 @@ public: inline bool Enabled() { return enabled; } bool Load(Database *db); - bool Store(Database *db); bool Clear(Database *db); protected: diff --git a/common/repositories/base/base_character_data_repository.h b/common/repositories/base/base_character_data_repository.h index 85374f7fc..dabdde51d 100644 --- a/common/repositories/base/base_character_data_repository.h +++ b/common/repositories/base/base_character_data_repository.h @@ -115,8 +115,8 @@ public: uint8_t lfg; std::string mailkey; uint8_t xtargets; - uint8_t ingame; uint32_t first_login; + uint8_t ingame; uint32_t e_aa_effects; uint32_t e_percent_to_aa; uint32_t e_expended_aa_spent; @@ -231,8 +231,8 @@ public: "lfg", "mailkey", "xtargets", - "ingame", "first_login", + "ingame", "e_aa_effects", "e_percent_to_aa", "e_expended_aa_spent", @@ -343,8 +343,8 @@ public: "lfg", "mailkey", "xtargets", - "ingame", "first_login", + "ingame", "e_aa_effects", "e_percent_to_aa", "e_expended_aa_spent", @@ -489,8 +489,8 @@ public: e.lfg = 0; e.mailkey = ""; e.xtargets = 5; - e.ingame = 0; e.first_login = 0; + e.ingame = 0; e.e_aa_effects = 0; e.e_percent_to_aa = 0; e.e_expended_aa_spent = 0; @@ -631,8 +631,8 @@ public: e.lfg = row[93] ? static_cast(strtoul(row[93], nullptr, 10)) : 0; e.mailkey = row[94] ? row[94] : ""; e.xtargets = row[95] ? static_cast(strtoul(row[95], nullptr, 10)) : 5; - e.ingame = row[96] ? static_cast(strtoul(row[96], nullptr, 10)) : 0; - e.first_login = row[97] ? static_cast(strtoul(row[97], nullptr, 10)) : 0; + e.first_login = row[96] ? static_cast(strtoul(row[96], nullptr, 10)) : 0; + e.ingame = row[97] ? static_cast(strtoul(row[97], nullptr, 10)) : 0; e.e_aa_effects = row[98] ? static_cast(strtoul(row[98], nullptr, 10)) : 0; e.e_percent_to_aa = row[99] ? static_cast(strtoul(row[99], nullptr, 10)) : 0; e.e_expended_aa_spent = row[100] ? static_cast(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[94] + " = '" + Strings::Escape(e.mailkey) + "'"); v.push_back(columns[95] + " = " + std::to_string(e.xtargets)); - v.push_back(columns[96] + " = " + std::to_string(e.ingame)); - v.push_back(columns[97] + " = " + std::to_string(e.first_login)); + v.push_back(columns[96] + " = " + 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[99] + " = " + std::to_string(e.e_percent_to_aa)); 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("'" + Strings::Escape(e.mailkey) + "'"); 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.ingame)); 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_expended_aa_spent)); @@ -1031,8 +1031,8 @@ public: v.push_back(std::to_string(e.lfg)); v.push_back("'" + Strings::Escape(e.mailkey) + "'"); 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.ingame)); 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_expended_aa_spent)); @@ -1170,8 +1170,8 @@ public: e.lfg = row[93] ? static_cast(strtoul(row[93], nullptr, 10)) : 0; e.mailkey = row[94] ? row[94] : ""; e.xtargets = row[95] ? static_cast(strtoul(row[95], nullptr, 10)) : 5; - e.ingame = row[96] ? static_cast(strtoul(row[96], nullptr, 10)) : 0; - e.first_login = row[97] ? static_cast(strtoul(row[97], nullptr, 10)) : 0; + e.first_login = row[96] ? static_cast(strtoul(row[96], nullptr, 10)) : 0; + e.ingame = row[97] ? static_cast(strtoul(row[97], nullptr, 10)) : 0; e.e_aa_effects = row[98] ? static_cast(strtoul(row[98], nullptr, 10)) : 0; e.e_percent_to_aa = row[99] ? static_cast(strtoul(row[99], nullptr, 10)) : 0; e.e_expended_aa_spent = row[100] ? static_cast(strtoul(row[100], nullptr, 10)) : 0; @@ -1300,8 +1300,8 @@ public: e.lfg = row[93] ? static_cast(strtoul(row[93], nullptr, 10)) : 0; e.mailkey = row[94] ? row[94] : ""; e.xtargets = row[95] ? static_cast(strtoul(row[95], nullptr, 10)) : 5; - e.ingame = row[96] ? static_cast(strtoul(row[96], nullptr, 10)) : 0; - e.first_login = row[97] ? static_cast(strtoul(row[97], nullptr, 10)) : 0; + e.first_login = row[96] ? static_cast(strtoul(row[96], nullptr, 10)) : 0; + e.ingame = row[97] ? static_cast(strtoul(row[97], nullptr, 10)) : 0; e.e_aa_effects = row[98] ? static_cast(strtoul(row[98], nullptr, 10)) : 0; e.e_percent_to_aa = row[99] ? static_cast(strtoul(row[99], nullptr, 10)) : 0; e.e_expended_aa_spent = row[100] ? static_cast(strtoul(row[100], nullptr, 10)) : 0; @@ -1480,8 +1480,8 @@ public: v.push_back(std::to_string(e.lfg)); v.push_back("'" + Strings::Escape(e.mailkey) + "'"); 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.ingame)); 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_expended_aa_spent)); @@ -1608,8 +1608,8 @@ public: v.push_back(std::to_string(e.lfg)); v.push_back("'" + Strings::Escape(e.mailkey) + "'"); 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.ingame)); 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_expended_aa_spent)); diff --git a/zone/client.cpp b/zone/client.cpp index 94c976788..8768c14a7 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -11478,9 +11478,8 @@ void Client::SaveSpells() } } - CharacterSpellsRepository::DeleteWhere(database, fmt::format("id = {}", CharacterID())); - if (!character_spells.empty()) { + CharacterSpellsRepository::DeleteWhere(database, fmt::format("id = {}", CharacterID())); CharacterSpellsRepository::InsertMany(database, character_spells); } } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 3416acef8..f4e3c62c0 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -827,6 +827,8 @@ void Client::CompleteConnect() parse->EventPlayer(EVENT_CONNECT, this, export_string, 0); } + RecordStats(); + if (is_first_login) { e.first_login = time(nullptr); TraderRepository::DeleteWhere(database, fmt::format("`char_id` = '{}'", CharacterID())); @@ -1002,7 +1004,6 @@ void Client::CompleteConnect() safe_delete(p); } - RecordStats(); AutoGrantAAPoints(); // 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... // item loss will occur when they use the 'empty' slots, if this is not done m_inv.SetGMInventory(true); - loaditems = database.GetInventory(this); /* Load Character Inventory */ - database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */ - database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */ - database.LoadCharacterMaterialColor(cid, &m_pp); /* Load Character Material */ - database.LoadCharacterPotionBelt(cid, &m_pp); /* Load Character Potion Belt */ - database.LoadCharacterCurrency(cid, &m_pp); /* Load Character Currency into PP */ - database.LoadCharacterData(cid, &m_pp, &m_epp); /* Load Character Data from DB into PP as well as E_PP */ - database.LoadCharacterSkills(cid, &m_pp); /* Load Character Skills */ - database.LoadCharacterInspectMessage(cid, &m_inspect_message); /* Load Character Inspect Message */ - database.LoadCharacterSpellBook(cid, &m_pp); /* Load Character Spell Book */ - database.LoadCharacterMemmedSpells(cid, &m_pp); /* Load Character Memorized Spells */ - database.LoadCharacterLanguages(cid, &m_pp); /* Load Character Languages */ - database.LoadCharacterLeadershipAbilities(cid, &m_pp); /* Load Character Leadership AA's */ - database.LoadCharacterTribute(this); /* Load CharacterTribute */ - database.LoadCharacterEXPModifier(this); /* Load Character EXP Modifier */ - database.LoadCharacterTitleSets(this); /* Load Character Title Sets */ + loaditems = database.GetInventory(this); + database.LoadCharacterData(cid, &m_pp, &m_epp); + database.LoadCharacterBandolier(cid, &m_pp); + database.LoadCharacterBindPoint(cid, &m_pp); + database.LoadCharacterMaterialColor(cid, &m_pp); + database.LoadCharacterPotionBelt(cid, &m_pp); + database.LoadCharacterCurrency(cid, &m_pp); + database.LoadCharacterSkills(cid, &m_pp); + database.LoadCharacterInspectMessage(cid, &m_inspect_message); + database.LoadCharacterSpellBook(cid, &m_pp); + database.LoadCharacterMemmedSpells(cid, &m_pp); + database.LoadCharacterLanguages(cid, &m_pp); + database.LoadCharacterLeadershipAbilities(cid, &m_pp); + database.LoadCharacterTribute(this); + database.LoadCharacterEXPModifier(this); + database.LoadCharacterTitleSets(this); // this pattern is strange // this is remnants of the old way of doing things diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 9de9b2096..8ee918577 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -642,8 +642,8 @@ bool ZoneDatabase::LoadCharacterLanguages(uint32 character_id, PlayerProfile_Str return false; } - for (int i = 0; i < MAX_PP_LANGUAGE; ++i) { // Initialize Languages - pp->languages[i] = 0; + for (unsigned char & language : pp->languages) { // Initialize Languages + language = 0; } for (const auto& e : l) { @@ -689,8 +689,8 @@ bool ZoneDatabase::LoadCharacterDisciplines(Client* c) return false; } - for (int slot_id = 0; slot_id < MAX_PP_DISCIPLINES; slot_id++) { - c->GetPP().disciplines.values[slot_id] = 0; + for (unsigned int & value : c->GetPP().disciplines.values) { + value = 0; } for (const auto& e : l) { @@ -2879,14 +2879,6 @@ void ZoneDatabase::UpdateAltCurrencyValue(uint32 char_id, uint32 currency_id, ui void ZoneDatabase::SaveBuffs(Client *client) { - CharacterBuffsRepository::DeleteWhere( - database, - fmt::format( - "`character_id` = {}", - client->CharacterID() - ) - ); - auto buffs = client->GetBuffs(); const int max_buff_slots = client->GetMaxBuffSlots(); @@ -2904,6 +2896,16 @@ void ZoneDatabase::SaveBuffs(Client *client) character_buff_count++; } + if (character_buff_count) { + CharacterBuffsRepository::DeleteWhere( + database, + fmt::format( + "`character_id` = {}", + client->CharacterID() + ) + ); + } + v.reserve(character_buff_count); for (int slot_id = 0; slot_id < max_buff_slots; slot_id++) { @@ -3170,39 +3172,39 @@ void ZoneDatabase::SavePetInfo(Client *client) } } - CharacterPetInfoRepository::DeleteWhere( - database, - fmt::format( - "`char_id` = {}", - client->CharacterID() - ) - ); - if (!pet_infos.empty()) { + CharacterPetInfoRepository::DeleteWhere( + database, + fmt::format( + "`char_id` = {}", + client->CharacterID() + ) + ); + CharacterPetInfoRepository::InsertMany(database, pet_infos); } - CharacterPetBuffsRepository::DeleteWhere( - database, - fmt::format( - "`char_id` = {}", - client->CharacterID() - ) - ); - if (!pet_buffs.empty()) { + CharacterPetBuffsRepository::DeleteWhere( + database, + fmt::format( + "`char_id` = {}", + client->CharacterID() + ) + ); + CharacterPetBuffsRepository::InsertMany(database, pet_buffs); } - CharacterPetInventoryRepository::DeleteWhere( - database, - fmt::format( - "`char_id` = {}", - client->CharacterID() - ) - ); - if (!inventory.empty()) { + CharacterPetInventoryRepository::DeleteWhere( + database, + fmt::format( + "`char_id` = {}", + client->CharacterID() + ) + ); + CharacterPetInventoryRepository::InsertMany(database, inventory); } } @@ -4261,6 +4263,11 @@ void ZoneDatabase::SaveCharacterEXPModifier(Client* c) 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( *this, CharacterExpModifiersRepository::CharacterExpModifiers{