From eca4eed99645ebf772e7e64b7ef0f15cc3931385 Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Wed, 6 Jul 2022 22:01:47 -0500 Subject: [PATCH] [Logging] Table Injection - Member Variable Cleanup (#2281) * Logsys member variable cleanup, table injection * Private member adjustments, OOB checks * continue --- common/discord_manager.cpp | 7 +- common/eqemu_logsys.cpp | 130 ++++++++++++++++++++++++++----------- common/eqemu_logsys.h | 25 ++++--- zone/gm_commands/logs.cpp | 4 +- zone/zone.cpp | 4 +- 5 files changed, 115 insertions(+), 55 deletions(-) diff --git a/common/discord_manager.cpp b/common/discord_manager.cpp index b2d8a9590..d889b7e9b 100644 --- a/common/discord_manager.cpp +++ b/common/discord_manager.cpp @@ -22,7 +22,12 @@ void DiscordManager::ProcessMessageQueue() for (auto &q: webhook_message_queue) { LogDiscord("Processing [{}] messages in queue for webhook ID [{}]...", q.second.size(), q.first); - auto webhook = LogSys.discord_webhooks[q.first]; + if (q.first >= MAX_DISCORD_WEBHOOK_ID) { + LogDiscord("Out of bounds webhook ID [{}] max [{}]", q.first, MAX_DISCORD_WEBHOOK_ID); + continue; + } + + auto webhook = LogSys.GetDiscordWebhooks()[q.first]; std::string message; for (auto &m: q.second) { diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index 5bf508ec5..453b9566e 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -91,8 +91,8 @@ namespace Console { */ EQEmuLogSys::EQEmuLogSys() { - on_log_gmsay_hook = [](uint16 log_type, const std::string &) {}; - on_log_console_hook = [](uint16 log_type, const std::string &) {}; + m_on_log_gmsay_hook = [](uint16 log_type, const std::string &) {}; + m_on_log_console_hook = [](uint16 log_type, const std::string &) {}; } /** @@ -105,7 +105,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults() /** * Get Executable platform currently running this code (Zone/World/etc) */ - log_platform = GetExecutablePlatformInt(); + m_log_platform = GetExecutablePlatformInt(); for (int log_category_id = Logs::AA; log_category_id != Logs::MaxCategoryID; log_category_id++) { log_settings[log_category_id].log_to_console = 0; @@ -115,7 +115,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults() log_settings[log_category_id].is_category_enabled = 0; } - file_logs_enabled = false; + m_file_logs_enabled = false; /** * Set Defaults @@ -169,26 +169,26 @@ EQEmuLogSys *EQEmuLogSys::LoadLogSettingsDefaults() /** * Declare process file names for log writing= */ - if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld) { - platform_file_name = "world"; + if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformWorld) { + m_platform_file_name = "world"; } - else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformQueryServ) { - platform_file_name = "query_server"; + else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformQueryServ) { + m_platform_file_name = "query_server"; } - else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) { - platform_file_name = "zone"; + else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone) { + m_platform_file_name = "zone"; } - else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformUCS) { - platform_file_name = "ucs"; + else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformUCS) { + m_platform_file_name = "ucs"; } - else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin) { - platform_file_name = "login"; + else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformLogin) { + m_platform_file_name = "login"; } - else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLaunch) { - platform_file_name = "launcher"; + else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformLaunch) { + m_platform_file_name = "launcher"; } - else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformHC) { - platform_file_name = "hc"; + else if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformHC) { + m_platform_file_name = "hc"; } return this; @@ -243,7 +243,7 @@ void EQEmuLogSys::ProcessLogWrite( std::ofstream crash_log; EQEmuLogSys::MakeDirectory("logs/crashes"); crash_log.open( - StringFormat("logs/crashes/crash_%s_%i.log", platform_file_name.c_str(), getpid()), + StringFormat("logs/crashes/crash_%s_%i.log", m_platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out ); crash_log << time_stamp << " " << message << "\n"; @@ -366,7 +366,7 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 log_category, const std::string & std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl; #endif - on_log_console_hook(log_category, message); + m_on_log_console_hook(log_category, message); } /** @@ -430,9 +430,9 @@ void EQEmuLogSys::Out( bool log_to_gmsay = log_settings[log_category].log_to_gmsay > 0 && log_settings[log_category].log_to_gmsay >= debug_level && log_category != Logs::LogCategory::Netcode && - (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone || - EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld); - bool log_to_discord = EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone && + (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone || + EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformWorld); + bool log_to_discord = EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone && log_settings[log_category].log_to_discord > 0 && log_settings[log_category].log_to_discord >= debug_level && log_settings[log_category].discord_webhook_id > 0 && @@ -460,13 +460,13 @@ void EQEmuLogSys::Out( EQEmuLogSys::ProcessConsoleMessage(log_category, output_debug_message); } if (log_to_gmsay) { - on_log_gmsay_hook(log_category, message); + m_on_log_gmsay_hook(log_category, message); } if (log_to_file) { EQEmuLogSys::ProcessLogWrite(log_category, output_debug_message); } - if (log_to_discord && on_log_discord_hook) { - on_log_discord_hook(log_category, log_settings[log_category].discord_webhook_id, output_message); + if (log_to_discord && m_on_log_discord_hook) { + m_on_log_discord_hook(log_category, log_settings[log_category].discord_webhook_id, output_message); } } @@ -518,23 +518,23 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name) /** * When loading settings, we must have been given a reason in category based logging to output to a file in order to even create or open one... */ - if (!file_logs_enabled) { + if (!m_file_logs_enabled) { return; } /** * Zone */ - if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) { + if (EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone) { if (!log_name.empty()) { - platform_file_name = log_name; + m_platform_file_name = log_name; } - if (platform_file_name.empty()) { + if (m_platform_file_name.empty()) { return; } - LogInfo("Starting File Log [logs/{}_{}.log]", platform_file_name.c_str(), getpid()); + LogInfo("Starting File Log [logs/{}_{}.log]", m_platform_file_name.c_str(), getpid()); /** * Make directory if not exists @@ -545,7 +545,7 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name) * Open file pointer */ process_log.open( - StringFormat("logs/zone/%s_%i.log", platform_file_name.c_str(), getpid()), + StringFormat("logs/zone/%s_%i.log", m_platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out ); } @@ -554,17 +554,17 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name) /** * All other processes */ - if (platform_file_name.empty()) { + if (m_platform_file_name.empty()) { return; } - LogInfo("Starting File Log [logs/{}_{}.log]", platform_file_name.c_str(), getpid()); + LogInfo("Starting File Log [logs/{}_{}.log]", m_platform_file_name.c_str(), getpid()); /** * Open file pointer */ process_log.open( - StringFormat("logs/%s_%i.log", platform_file_name.c_str(), getpid()), + StringFormat("logs/%s_%i.log", m_platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out ); } @@ -594,6 +594,8 @@ void EQEmuLogSys::EnableConsoleLogging() EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings() { + InjectTablesIfNotExist(); + auto categories = LogsysCategoriesRepository::GetWhere( *m_database, "TRUE ORDER BY log_category_id" @@ -632,7 +634,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings() // If we go through this whole loop and nothing is set to any debug level, there // is no point to create a file or keep anything open if (log_settings[c.log_category_id].log_to_file > 0) { - LogSys.file_logs_enabled = true; + LogSys.m_file_logs_enabled = true; } db_categories.emplace_back(c.log_category_id); @@ -660,10 +662,10 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings() LogInfo("Loaded [{}] log categories", categories.size()); - auto webhooks = DiscordWebhooksRepository::All(*m_database); + auto webhooks = DiscordWebhooksRepository::GetWhere(*m_database, fmt::format("id < {}", MAX_DISCORD_WEBHOOK_ID)); if (!webhooks.empty()) { for (auto &w: webhooks) { - discord_webhooks[w.id] = {w.id, w.webhook_name, w.webhook_url}; + m_discord_webhooks[w.id] = {w.id, w.webhook_name, w.webhook_url}; } LogInfo("Loaded [{}] Discord webhooks", webhooks.size()); } @@ -678,3 +680,55 @@ EQEmuLogSys *EQEmuLogSys::SetDatabase(Database *db) return this; } +void EQEmuLogSys::InjectTablesIfNotExist() +{ + // do not run injections for zone as its unnecessary hits every time a zone boots + // other processes less frequently ran can pick up injection + if (m_log_platform == EQEmuExePlatform::ExePlatformZone) { + return; + } + + // inject discord_webhooks + if (!m_database->DoesTableExist("discord_webhooks")) { + LogInfo("Creating table [discord_webhooks]"); + m_database->QueryDatabase( + SQL( + CREATE TABLE discord_webhooks + ( + id INT auto_increment primary key NULL, + webhook_name varchar(100) NULL, + webhook_url varchar(255) NULL, + created_at DATETIME NULL, + deleted_at DATETIME NULL + ) ENGINE=InnoDB + DEFAULT CHARSET=utf8mb4 + COLLATE=utf8mb4_general_ci; + ) + ); + } + + // inject logsys_categories + if (!m_database->DoesTableExist("logsys_categories")) { + LogInfo("Creating table [logsys_categories]"); + m_database->QueryDatabase( + SQL( + CREATE TABLE `logsys_categories` ( + `log_category_id` int(11) NOT NULL, + `log_category_description` varchar(150) DEFAULT NULL, + `log_to_console` smallint(11) DEFAULT 0, + `log_to_file` smallint(11) DEFAULT 0, + `log_to_gmsay` smallint(11) DEFAULT 0, + `log_to_discord` smallint(11) DEFAULT 0, + `discord_webhook_id` int(11) DEFAULT 0, + PRIMARY KEY (`log_category_id`) + ) ENGINE=InnoDB DEFAULT CHARSET=latin1 + ) + ); + } +} + +const EQEmuLogSys::DiscordWebhooks *EQEmuLogSys::GetDiscordWebhooks() const +{ + return m_discord_webhooks; +} + diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index 098851e23..63e7d1a12 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -317,26 +317,20 @@ public: std::string webhook_url; }; - DiscordWebhooks discord_webhooks[MAX_DISCORD_WEBHOOK_ID]{}; - - bool file_logs_enabled = false; - - int log_platform = 0; - std::string platform_file_name; - + const DiscordWebhooks *GetDiscordWebhooks() const; // gmsay uint16 GetGMSayColorFromCategory(uint16 log_category); EQEmuLogSys *SetGMSayHandler(std::function f) { - on_log_gmsay_hook = f; + m_on_log_gmsay_hook = f; return this; } EQEmuLogSys *SetDiscordHandler(std::function f) { - on_log_discord_hook = f; + m_on_log_discord_hook = f; return this; } @@ -346,7 +340,7 @@ public: uint16 log_type, const std::string & )> f - ) { on_log_console_hook = f; } + ) { m_on_log_console_hook = f; } void SilenceConsoleLogging(); void EnableConsoleLogging(); @@ -357,9 +351,13 @@ private: // reference to database Database *m_database; - std::function on_log_gmsay_hook; - std::function on_log_discord_hook; - std::function on_log_console_hook; + std::function m_on_log_gmsay_hook; + std::function m_on_log_discord_hook; + std::function m_on_log_console_hook; + DiscordWebhooks m_discord_webhooks[MAX_DISCORD_WEBHOOK_ID]{}; + bool m_file_logs_enabled = false; + int m_log_platform = 0; + std::string m_platform_file_name; std::string FormatOutMessageString(uint16 log_category, const std::string &in_message); std::string GetLinuxConsoleColorFromCategory(uint16 log_category); @@ -368,6 +366,7 @@ private: void ProcessConsoleMessage(uint16 log_category, const std::string &message); void ProcessLogWrite(uint16 log_category, const std::string &message); bool IsRfc5424LogCategory(uint16 log_category); + void InjectTablesIfNotExist(); }; extern EQEmuLogSys LogSys; diff --git a/zone/gm_commands/logs.cpp b/zone/gm_commands/logs.cpp index 2460ab62d..a7a53f203 100755 --- a/zone/gm_commands/logs.cpp +++ b/zone/gm_commands/logs.cpp @@ -25,7 +25,7 @@ void command_logs(Client *c, const Seperator *sep) ); return; } - + bool is_list = !strcasecmp(sep->arg[1], "list"); bool is_reload = !strcasecmp(sep->arg[1], "reload"); bool is_set = !strcasecmp(sep->arg[1], "set"); @@ -73,7 +73,7 @@ void command_logs(Client *c, const Seperator *sep) max_category_id = (Logs::LogCategory::MaxCategoryID - 1); break; } - + popup_text += fmt::format( "{}{}{}{}{}", index, diff --git a/zone/zone.cpp b/zone/zone.cpp index 35376caf6..7d1b5fb92 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -2799,7 +2799,9 @@ void Zone::SendDiscordMessage(int webhook_id, const std::string& message) void Zone::SendDiscordMessage(const std::string& webhook_name, const std::string &message) { bool not_found = true; - for (auto & w : LogSys.discord_webhooks) { + + for (int i= 0; i < MAX_DISCORD_WEBHOOK_ID; i++) { + auto &w = LogSys.GetDiscordWebhooks()[i]; if (w.webhook_name == webhook_name) { SendDiscordMessage(w.id, message + "\n"); not_found = false;