diff --git a/common/repositories/character_data_repository.h b/common/repositories/character_data_repository.h index 74f884cf3..d95ac2fda 100644 --- a/common/repositories/character_data_repository.h +++ b/common/repositories/character_data_repository.h @@ -167,6 +167,30 @@ public: return zone_player_counts; } + + static std::vector GetCharacterIDsByAccountID( + Database& db, + uint32_t account_id + ) + { + std::vector character_ids; + + auto query = fmt::format( + "SELECT id FROM character_data WHERE account_id = {} AND deleted_at IS NULL", + account_id + ); + + auto results = db.QueryDatabase(query); + if (results.Success()) { + for (auto row : results) { + if (row[0]) { + character_ids.push_back(static_cast(std::stoul(row[0]))); + } + } + } + + return character_ids; + } }; #endif //EQEMU_CHARACTER_DATA_REPOSITORY_H diff --git a/world/client.cpp b/world/client.cpp index 243d9f203..bb3f76cd5 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -36,6 +36,7 @@ #include "../common/shareddb.h" #include "../common/opcodemgr.h" #include "../common/data_verification.h" +#include "../common/data_bucket.h" #include "client.h" #include "worlddb.h" @@ -135,6 +136,8 @@ Client::Client(EQStreamInterface* ieqs) } Client::~Client() { + ClearDataBucketsCache(); + if (RunLoops && cle && zone_id == 0) cle->SetOnline(CLE_Status::Offline); @@ -477,6 +480,8 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) LogClientLogin("Checking authentication id [{}]", id); if ((cle = client_list.CheckAuth(id, password))) { + LoadDataBucketsCache(); + LogClientLogin("Checking authentication id [{}] passed", id); if (!is_player_zoning) { // Track who is in and who is out of the game @@ -2518,3 +2523,19 @@ void Client::SendUnsupportedClientPacket(const std::string& message) QueuePacket(&packet); } + +void Client::LoadDataBucketsCache() +{ + DataBucket::BulkLoadEntitiesToCache(DataBucketLoadType::Account, {GetAccountID()}); + const auto ids = CharacterDataRepository::GetCharacterIDsByAccountID(database, GetAccountID()); + DataBucket::BulkLoadEntitiesToCache(DataBucketLoadType::Client, ids); +} + +void Client::ClearDataBucketsCache() +{ + DataBucket::DeleteFromCache(GetAccountID(), DataBucketLoadType::Account); + auto ids = CharacterDataRepository::GetCharacterIDsByAccountID(database, GetAccountID()); + for (const auto& id : ids) { + DataBucket::DeleteFromCache(id, DataBucketLoadType::Client); + } +} diff --git a/world/client.h b/world/client.h index e88f8a94e..5890cfcf0 100644 --- a/world/client.h +++ b/world/client.h @@ -121,6 +121,9 @@ private: bool CanTradeFVNoDropItem(); void RecordPossibleHack(const std::string& message); void SendUnsupportedClientPacket(const std::string& message); + + void LoadDataBucketsCache(); + void ClearDataBucketsCache(); }; bool CheckCharCreateInfoSoF(CharCreate_Struct *cc);