diff --git a/common/say_link.cpp b/common/say_link.cpp index aa4c4e3ac..a10dc4b2d 100644 --- a/common/say_link.cpp +++ b/common/say_link.cpp @@ -26,6 +26,9 @@ #include "../zone/zonedb.h" #include +// static bucket global +std::vector g_cached_saylinks = {}; + bool EQ::saylink::DegenerateLinkBody(SayLinkBody_Struct &say_link_body_struct, const std::string &say_link_body) { memset(&say_link_body_struct, 0, sizeof(say_link_body_struct)); @@ -295,33 +298,9 @@ std::string EQ::SayLinkEngine::GenerateQuestSaylink(std::string saylink_text, bo { uint32 saylink_id = 0; - /** - * Query for an existing phrase and id in the saylink table - */ - std::string query = StringFormat( - "SELECT `id` FROM `saylink` WHERE `phrase` = '%s' LIMIT 1", - EscapeString(saylink_text).c_str()); - - auto results = database.QueryDatabase(query); - - if (results.Success()) { - if (results.RowCount() >= 1) { - for (auto row = results.begin(); row != results.end(); ++row) - saylink_id = static_cast(atoi(row[0])); - } - else { - std::string insert_query = StringFormat( - "INSERT INTO `saylink` (`phrase`) VALUES ('%s')", - EscapeString(saylink_text).c_str()); - - results = database.QueryDatabase(insert_query); - if (!results.Success()) { - LogError("Error in saylink phrase queries {}", results.ErrorMessage().c_str()); - } - else { - saylink_id = results.LastInsertedID(); - } - } + SaylinkRepository::Saylink saylink = GetOrSaveSaylink(saylink_text); + if (saylink.id > 0) { + saylink_id = saylink.id; } /** @@ -485,3 +464,47 @@ std::string EQ::SayLinkEngine::InjectSaylinksIfNotExist(const char *message) return new_message; } + +void EQ::SayLinkEngine::LoadCachedSaylinks() +{ + auto saylinks = SaylinkRepository::GetWhere(database, "phrase not like '%#%'"); + LogSaylink("Loaded [{}] saylinks into cache", saylinks.size()); + g_cached_saylinks = saylinks; +} + +SaylinkRepository::Saylink EQ::SayLinkEngine::GetOrSaveSaylink(std::string saylink_text) +{ + // return cached saylink if exist + if (!g_cached_saylinks.empty()) { + for (auto &s: g_cached_saylinks) { + if (s.phrase == saylink_text) { + return s; + } + } + } + + auto saylinks = SaylinkRepository::GetWhere( + database, + fmt::format("phrase = '{}'", EscapeString(saylink_text)) + ); + + // return if found from the database + if (!saylinks.empty()) { + return saylinks[0]; + } + + // if not found in database - save + if (saylinks.empty()) { + auto new_saylink = SaylinkRepository::NewEntity(); + new_saylink.phrase = saylink_text; + + // persist to database + auto link = SaylinkRepository::InsertOne(database, new_saylink); + if (link.id > 0) { + g_cached_saylinks.emplace_back(link); + return link; + } + } + + return {}; +} diff --git a/common/say_link.h b/common/say_link.h index 982b9ec58..aec8d8879 100644 --- a/common/say_link.h +++ b/common/say_link.h @@ -23,7 +23,7 @@ #include "types.h" #include - +#include "repositories/saylink_repository.h" struct ServerLootItem_Struct; @@ -106,6 +106,7 @@ namespace EQ void Reset(); static std::string InjectSaylinksIfNotExist(const char *message); + static void LoadCachedSaylinks(); private: void generate_body(); void generate_text(); @@ -121,6 +122,7 @@ namespace EQ std::string m_LinkBody; std::string m_LinkText; bool m_Error; + static SaylinkRepository::Saylink GetOrSaveSaylink(std::string saylink_text); }; } /*EQEmu*/ diff --git a/zone/main.cpp b/zone/main.cpp index a152e9945..eab175639 100644 --- a/zone/main.cpp +++ b/zone/main.cpp @@ -392,6 +392,8 @@ int main(int argc, char** argv) { event_scheduler.SetDatabase(&database)->LoadScheduledEvents(); + EQ::SayLinkEngine::LoadCachedSaylinks(); + #ifdef BOTS LogInfo("Loading bot commands"); int botretval = bot_command_init();