From 88debae6600d9ccd480fa31008551385f473b748 Mon Sep 17 00:00:00 2001 From: Matt Hogan Date: Fri, 19 Oct 2018 19:37:25 -0400 Subject: [PATCH 1/9] Added get_data_expires function to both Perl and Lua to retrieve DataBucket expire time --- zone/data_bucket.cpp | 25 +++++++++++++++++++++++++ zone/data_bucket.h | 1 + zone/embparser_api.cpp | 15 +++++++++++++++ zone/lua_general.cpp | 4 ++++ 4 files changed, 45 insertions(+) diff --git a/zone/data_bucket.cpp b/zone/data_bucket.cpp index d1bdcd83c..15a6e7720 100644 --- a/zone/data_bucket.cpp +++ b/zone/data_bucket.cpp @@ -76,6 +76,31 @@ std::string DataBucket::GetData(std::string bucket_key) { return std::string(row[0]); } +/** + * Retrieves data expires time via bucket_name as key + * @param bucket_key + * @return + */ +std::string DataBucket::GetDataExpires(std::string bucket_key) { + std::string query = StringFormat( + "SELECT `expires` from `data_buckets` WHERE `key` = '%s' AND (`expires` > %lld OR `expires` = 0) LIMIT 1", + bucket_key.c_str(), + (long long) std::time(nullptr) + ); + + auto results = database.QueryDatabase(query); + if (!results.Success()) { + return std::string(); + } + + if (results.RowCount() != 1) + return std::string(); + + auto row = results.begin(); + + return std::string(row[0]); +} + /** * Checks for bucket existence by bucket_name key * @param bucket_key diff --git a/zone/data_bucket.h b/zone/data_bucket.h index 87d3ab0b3..88a344637 100644 --- a/zone/data_bucket.h +++ b/zone/data_bucket.h @@ -14,6 +14,7 @@ public: static void SetData(std::string bucket_key, std::string bucket_value, std::string expires_time = ""); static bool DeleteData(std::string bucket_key); static std::string GetData(std::string bucket_key); + static std::string GetDataExpires(std::string bucket_key); private: static uint64 DoesBucketExist(std::string bucket_key); static uint32 ParseStringTimeToInt(std::string time_string); diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index 1a251b8ec..633bcda53 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -3596,6 +3596,21 @@ XS(XS__get_data) { XSRETURN(1); } +XS(XS__get_data_expires); +XS(XS__get_data_expires) { + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: quest::get_data_expires(string bucket_key)"); + + dXSTARG; + std::string key = (std::string) SvPV_nolen(ST(0)); + + sv_setpv(TARG, DataBucket::GetDataExpires(key).c_str()); + XSprePUSH; + PUSHTARG; + XSRETURN(1); +} + XS(XS__set_data); XS(XS__set_data) { dXSARGS; diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 65fe2c575..955b69d5e 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -822,6 +822,10 @@ std::string lua_get_data(std::string bucket_key) { return DataBucket::GetData(bucket_key); } +std::string lua_get_data_expires(std::string bucket_key) { + return DataBucket::GetDataExpires(bucket_key); +} + void lua_set_data(std::string bucket_key, std::string bucket_value) { DataBucket::SetData(bucket_key, bucket_value); } From 55197cf830f8ca926ab284656f2c2487505f313e Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 20 Oct 2018 21:07:45 -0500 Subject: [PATCH 2/9] Add fix for data buckets deletion --- zone/data_bucket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/data_bucket.cpp b/zone/data_bucket.cpp index d1bdcd83c..67c1e04c4 100644 --- a/zone/data_bucket.cpp +++ b/zone/data_bucket.cpp @@ -107,7 +107,7 @@ uint64 DataBucket::DoesBucketExist(std::string bucket_key) { */ bool DataBucket::DeleteData(std::string bucket_key) { std::string query = StringFormat( - "DELETE FROM `data_buckets` WHERE `key` = '%s' AND (`expires` > %lld OR `expires` = 0)", + "DELETE FROM `data_buckets` WHERE `key` = '%s'", EscapeString(bucket_key).c_str() ); From 0830ea865069039a7ff802ae8e160b84d1be0841 Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Sat, 20 Oct 2018 22:54:38 -0400 Subject: [PATCH 3/9] Zone header was getting ignored by RoF2 client. --- zone/client_packet.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index c6fd66894..ceb242890 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1115,7 +1115,12 @@ void Client::Handle_Connect_OP_ReqNewZone(const EQApplicationPacket *app) memcpy(outapp->pBuffer, &zone->newzone_data, sizeof(NewZone_Struct)); strcpy(nz->char_name, m_pp.name); - FastQueuePacket(&outapp); + // This was using FastQueuePacket and the packet was never getting sent... + // Not sure if this was timing.... but the NewZone was never logged until + // I changed it. + outapp->priority = 6; + QueuePacket(outapp); + safe_delete(outapp); return; } @@ -1741,11 +1746,6 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) /* Task Packets */ LoadClientTaskState(); - if (ClientVersion() >= EQEmu::versions::ClientVersion::RoF) { - outapp = new EQApplicationPacket(OP_ReqNewZone, 0); - Handle_Connect_OP_ReqNewZone(outapp); - safe_delete(outapp); - } if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater) { outapp = new EQApplicationPacket(OP_XTargetResponse, 8); @@ -1771,6 +1771,10 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) QueuePacket(outapp); safe_delete(outapp); + if (ClientVersion() >= EQEmu::versions::ClientVersion::RoF) { + Handle_Connect_OP_ReqNewZone(nullptr); + } + SetAttackTimer(); conn_state = ZoneInfoSent; zoneinpacket_timer.Start(); From ab8075d629e5b51a42b8b39411ca7819f93fc2e7 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 20 Oct 2018 22:29:59 -0500 Subject: [PATCH 4/9] Cleanup eqemu_logsys code and automatically inject new logging categories into the database if they do not exist --- .gitignore | 3 +- common/database.cpp | 102 +++++++--- common/eqemu_logsys.cpp | 421 +++++++++++++++++++++++++++------------- common/eqemu_logsys.h | 382 ++++++++++++++++++++---------------- 4 files changed, 569 insertions(+), 339 deletions(-) diff --git a/.gitignore b/.gitignore index 5698779e8..a5e41a779 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,5 @@ log/ logs/ vcpkg/ -.idea/* \ No newline at end of file +.idea/* +*cbp \ No newline at end of file diff --git a/common/database.cpp b/common/database.cpp index 2ec4675b3..a9496b6e3 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -2063,51 +2063,91 @@ uint32 Database::GetGuildIDByCharID(uint32 character_id) return atoi(row[0]); } -void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) -{ +void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) { // log_settings previously initialized to '0' by EQEmuLogSys::LoadLogSettingsDefaults() - - std::string query = - "SELECT " - "log_category_id, " - "log_category_description, " - "log_to_console, " - "log_to_file, " - "log_to_gmsay " - "FROM " - "logsys_categories " - "ORDER BY log_category_id"; + + std::string query = + "SELECT " + "log_category_id, " + "log_category_description, " + "log_to_console, " + "log_to_file, " + "log_to_gmsay " + "FROM " + "logsys_categories " + "ORDER BY log_category_id"; + auto results = QueryDatabase(query); - int log_category = 0; + int log_category_id = 0; LogSys.file_logs_enabled = false; + int categories_in_database[1000] = {}; + for (auto row = results.begin(); row != results.end(); ++row) { - log_category = atoi(row[0]); - if (log_category <= Logs::None || log_category >= Logs::MaxCategoryID) + log_category_id = atoi(row[0]); + if (log_category_id <= Logs::None || log_category_id >= Logs::MaxCategoryID) { continue; + } - log_settings[log_category].log_to_console = atoi(row[2]); - log_settings[log_category].log_to_file = atoi(row[3]); - log_settings[log_category].log_to_gmsay = atoi(row[4]); + log_settings[log_category_id].log_to_console = atoi(row[2]); + log_settings[log_category_id].log_to_file = atoi(row[3]); + log_settings[log_category_id].log_to_gmsay = atoi(row[4]); - /* Determine if any output method is enabled for the category - and set it to 1 so it can used to check if category is enabled */ - const bool log_to_console = log_settings[log_category].log_to_console > 0; - const bool log_to_file = log_settings[log_category].log_to_file > 0; - const bool log_to_gmsay = log_settings[log_category].log_to_gmsay > 0; + /** + * Determine if any output method is enabled for the category + * and set it to 1 so it can used to check if category is enabled + */ + const bool log_to_console = log_settings[log_category_id].log_to_console > 0; + const bool log_to_file = log_settings[log_category_id].log_to_file > 0; + const bool log_to_gmsay = log_settings[log_category_id].log_to_gmsay > 0; const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay; - if (is_category_enabled) - log_settings[log_category].is_category_enabled = 1; + if (is_category_enabled) { + log_settings[log_category_id].is_category_enabled = 1; + } - /* - This determines whether or not the process needs to actually file log anything. - 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[log_category].log_to_file > 0){ + /** + * This determines whether or not the process needs to actually file log anything. + * 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[log_category_id].log_to_file > 0) { LogSys.file_logs_enabled = true; } + + categories_in_database[log_category_id] = 1; + } + + /** + * Auto inject categories that don't exist in the database... + */ + for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) { + if (!categories_in_database[log_index]) { + + Log(Logs::General, + Logs::Status, + "New Log Category '%s' doesn't exist... Automatically adding to `logsys_categories` table...", + Logs::LogCategoryName[log_index] + ); + + std::string inject_query = StringFormat( + "INSERT INTO logsys_categories " + "(log_category_id, " + "log_category_description, " + "log_to_console, " + "log_to_file, " + "log_to_gmsay) " + "VALUES " + "(%i, '%s', %i, %i, %i)", + log_index, + EscapeString(Logs::LogCategoryName[log_index]).c_str(), + log_settings[log_category_id].log_to_console, + log_settings[log_category_id].log_to_file, + log_settings[log_category_id].log_to_gmsay + ); + + QueryDatabase(inject_query); + } } } diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index a14a27a1b..f4d36e5d5 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -1,22 +1,23 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2018 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * */ - #include "eqemu_logsys.h" #include "platform.h" #include "string_util.h" @@ -33,106 +34,144 @@ std::ofstream process_log; #ifdef _WINDOWS - #include - #include - #include - #include - #include - #include +#include +#include +#include +#include +#include +#include #else - #include - #include + +#include +#include + #endif -/* Linux ANSI console color defines */ +/** + * Linux ANSI console color defines + */ #define LC_RESET "\033[0m" -#define LC_BLACK "\033[30m" /* Black */ -#define LC_RED "\033[31m" /* Red */ -#define LC_GREEN "\033[32m" /* Green */ -#define LC_YELLOW "\033[33m" /* Yellow */ -#define LC_BLUE "\033[34m" /* Blue */ -#define LC_MAGENTA "\033[35m" /* Magenta */ -#define LC_CYAN "\033[36m" /* Cyan */ -#define LC_WHITE "\033[37m" /* White */ +#define LC_BLACK "\033[30m" /* Black */ +#define LC_RED "\033[31m" /* Red */ +#define LC_GREEN "\033[32m" /* Green */ +#define LC_YELLOW "\033[33m" /* Yellow */ +#define LC_BLUE "\033[34m" /* Blue */ +#define LC_MAGENTA "\033[35m" /* Magenta */ +#define LC_CYAN "\033[36m" /* Cyan */ +#define LC_WHITE "\033[37m" /* White */ namespace Console { enum Color { - Black = 0, - Blue = 1, - Green = 2, - Cyan = 3, - Red = 4, - Magenta = 5, - Brown = 6, - LightGray = 7, - DarkGray = 8, - LightBlue = 9, - LightGreen = 10, - LightCyan = 11, - LightRed = 12, + Black = 0, + Blue = 1, + Green = 2, + Cyan = 3, + Red = 4, + Magenta = 5, + Brown = 6, + LightGray = 7, + DarkGray = 8, + LightBlue = 9, + LightGreen = 10, + LightCyan = 11, + LightRed = 12, LightMagenta = 13, - Yellow = 14, - White = 15 + Yellow = 14, + White = 15 }; } +enum GameChatColor { + yellow = 15, + red = 13, + light_green = 14, + light_cyan = 258, + light_purple = 5 +}; + +/** + * EQEmuLogSys Constructor + */ EQEmuLogSys::EQEmuLogSys() { - on_log_gmsay_hook = [](uint16 log_type, const std::string&) {}; + on_log_gmsay_hook = [](uint16 log_type, const std::string &) {}; bool file_logs_enabled = false; - int log_platform = 0; + int log_platform = 0; } +/** + * EQEmuLogSys Deconstructor + */ EQEmuLogSys::~EQEmuLogSys() { } void EQEmuLogSys::LoadLogSettingsDefaults() { - /* Get Executable platform currently running this code (Zone/World/etc) */ + /** + * Get Executable platform currently running this code (Zone/World/etc) + */ log_platform = GetExecutablePlatformInt(); - /* Zero out Array */ + /** + * Zero out Array + */ memset(log_settings, 0, sizeof(LogSettings) * Logs::LogCategory::MaxCategoryID); - /* Set Defaults */ - log_settings[Logs::World_Server].log_to_console = Logs::General; - log_settings[Logs::Zone_Server].log_to_console = Logs::General; - log_settings[Logs::QS_Server].log_to_console = Logs::General; - log_settings[Logs::UCS_Server].log_to_console = Logs::General; - log_settings[Logs::Crash].log_to_console = Logs::General; - log_settings[Logs::MySQLError].log_to_console = Logs::General; - log_settings[Logs::Login_Server].log_to_console = Logs::General; + /** + * Set Defaults + */ + log_settings[Logs::World_Server].log_to_console = Logs::General; + log_settings[Logs::Zone_Server].log_to_console = Logs::General; + log_settings[Logs::QS_Server].log_to_console = Logs::General; + log_settings[Logs::UCS_Server].log_to_console = Logs::General; + log_settings[Logs::Crash].log_to_console = Logs::General; + log_settings[Logs::MySQLError].log_to_console = Logs::General; + log_settings[Logs::Login_Server].log_to_console = Logs::General; log_settings[Logs::Headless_Client].log_to_console = Logs::General; - /* Set Category enabled status on defaults */ + /** + * Set Category enabled status on defaults + */ log_settings[Logs::World_Server].is_category_enabled = 1; - log_settings[Logs::Zone_Server].is_category_enabled = 1; - log_settings[Logs::QS_Server].is_category_enabled = 1; - log_settings[Logs::UCS_Server].is_category_enabled = 1; - log_settings[Logs::Crash].is_category_enabled = 1; - log_settings[Logs::MySQLError].is_category_enabled = 1; + log_settings[Logs::Zone_Server].is_category_enabled = 1; + log_settings[Logs::QS_Server].is_category_enabled = 1; + log_settings[Logs::UCS_Server].is_category_enabled = 1; + log_settings[Logs::Crash].is_category_enabled = 1; + log_settings[Logs::MySQLError].is_category_enabled = 1; log_settings[Logs::Login_Server].is_category_enabled = 1; - /* Declare process file names for log writing - If there is no process_file_name declared, no log file will be written, simply - */ - if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld) + /** + * Declare process file names for log writing= + */ + if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld) { platform_file_name = "world"; - else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformQueryServ) + } + else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformQueryServ) { platform_file_name = "query_server"; - else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) + } + else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) { platform_file_name = "zone"; - else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformUCS) + } + else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformUCS) { platform_file_name = "ucs"; - else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin) + } + else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin) { platform_file_name = "login"; - else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLaunch) + } + else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLaunch) { platform_file_name = "launcher"; - else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformHC) + } + else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformHC) { platform_file_name = "hc"; + } } +/** + * @param log_category + * @param in_message + * @return + */ std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::string &in_message) { std::string ret; @@ -144,17 +183,33 @@ std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std:: return ret; } +/** + * @param debug_level + * @param log_category + * @param message + */ void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message) { - /* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash */ - if (log_category == Logs::LogCategory::Netcode) + /** + * Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash + */ + if (log_category == Logs::LogCategory::Netcode) { return; + } - /* Check to see if the process that actually ran this is zone */ - if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) + /** + * Check to see if the process that actually ran this is zone + */ + if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) { on_log_gmsay_hook(log_category, message); + } } +/** + * @param debug_level + * @param log_category + * @param message + */ void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message) { if (log_category == Logs::Crash) { @@ -162,7 +217,10 @@ void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const EQEmuLogSys::SetCurrentTimeStamp(time_stamp); std::ofstream crash_log; EQEmuLogSys::MakeDirectory("logs/crashes"); - crash_log.open(StringFormat("logs/crashes/crash_%s_%i.log", platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out); + crash_log.open( + StringFormat("logs/crashes/crash_%s_%i.log", platform_file_name.c_str(), getpid()), + std::ios_base::app | std::ios_base::out + ); crash_log << time_stamp << " " << message << "\n"; crash_log.close(); } @@ -170,11 +228,17 @@ void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const char time_stamp[80]; EQEmuLogSys::SetCurrentTimeStamp(time_stamp); - if (process_log) + if (process_log) { process_log << time_stamp << " " << message << std::endl; + } } -uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category) { +/** + * @param log_category + * @return + */ +uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category) +{ switch (log_category) { case Logs::Status: case Logs::Normal: @@ -197,7 +261,12 @@ uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category) { } } -std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category) { +/** + * @param log_category + * @return + */ +std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category) +{ switch (log_category) { case Logs::Status: case Logs::Normal: @@ -220,52 +289,68 @@ std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category) { } } -uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category) { +/** + * @param log_category + * @return + */ +uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category) +{ switch (log_category) { case Logs::Status: case Logs::Normal: - return 15; /* Yellow */ + return GameChatColor::yellow; case Logs::MySQLError: case Logs::Error: - return 13; /* Red */ + return GameChatColor::red; case Logs::MySQLQuery: case Logs::Debug: - return 14; /* Light Green */ + return GameChatColor::light_green; case Logs::Quests: - return 258; /* Light Cyan */ + return GameChatColor::light_cyan; case Logs::Commands: case Logs::Mercenaries: - return 5; /* Light Purple */ + return GameChatColor::light_purple; case Logs::Crash: - return 13; /* Red */ + return GameChatColor::red; default: - return 15; /* Yellow */ + return GameChatColor::yellow; } } +/** + * @param debug_level + * @param log_category + * @param message + */ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message) { - - #ifdef _WINDOWS - HANDLE console_handle; - console_handle = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_FONT_INFOEX info = { 0 }; - info.cbSize = sizeof(info); - info.dwFontSize.Y = 12; // leave X as zero - info.FontWeight = FW_NORMAL; - wcscpy(info.FaceName, L"Lucida Console"); - SetCurrentConsoleFontEx(console_handle, NULL, &info); - SetConsoleTextAttribute(console_handle, EQEmuLogSys::GetWindowsConsoleColorFromCategory(log_category)); - std::cout << message << "\n"; - SetConsoleTextAttribute(console_handle, Console::Color::White); - #else - std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl; - #endif +#ifdef _WINDOWS + HANDLE console_handle; + console_handle = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_FONT_INFOEX info = { 0 }; + info.cbSize = sizeof(info); + info.dwFontSize.Y = 12; // leave X as zero + info.FontWeight = FW_NORMAL; + wcscpy(info.FaceName, L"Lucida Console"); + SetCurrentConsoleFontEx(console_handle, NULL, &info); + SetConsoleTextAttribute(console_handle, EQEmuLogSys::GetWindowsConsoleColorFromCategory(log_category)); + std::cout << message << "\n"; + SetConsoleTextAttribute(console_handle, Console::Color::White); +#else + std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl; +#endif } +/** + * Core logging function + * + * @param debug_level + * @param log_category + * @param message + * @param ... + */ void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...) { - bool log_to_console = true; if (log_settings[log_category].log_to_console < debug_level) { log_to_console = false; @@ -282,8 +367,9 @@ void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::st } const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay; - if (nothing_to_log) + if (nothing_to_log) { return; + } va_list args; va_start(args, message); @@ -292,20 +378,32 @@ void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::st std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, output_message); - if (log_to_console) EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message); - if (log_to_gmsay) EQEmuLogSys::ProcessGMSay(debug_level, log_category, output_debug_message); - if (log_to_file) EQEmuLogSys::ProcessLogWrite(debug_level, log_category, output_debug_message); + if (log_to_console) { + EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message); + } + if (log_to_gmsay) { + EQEmuLogSys::ProcessGMSay(debug_level, log_category, output_debug_message); + } + if (log_to_file) { + EQEmuLogSys::ProcessLogWrite(debug_level, log_category, output_debug_message); + } } -void EQEmuLogSys::SetCurrentTimeStamp(char* time_stamp) +/** + * @param time_stamp + */ +void EQEmuLogSys::SetCurrentTimeStamp(char *time_stamp) { - time_t raw_time; - struct tm * time_info; + time_t raw_time; + struct tm *time_info; time(&raw_time); time_info = localtime(&raw_time); strftime(time_stamp, 80, "[%m-%d-%Y :: %H:%M:%S]", time_info); } +/** + * @param directory_name + */ void EQEmuLogSys::MakeDirectory(const std::string &directory_name) { #ifdef _WINDOWS @@ -315,8 +413,9 @@ void EQEmuLogSys::MakeDirectory(const std::string &directory_name) _mkdir(directory_name.c_str()); #else struct stat st; - if (stat(directory_name.c_str(), &st) == 0) // exists + if (stat(directory_name.c_str(), &st) == 0) { // exists return; + } mkdir(directory_name.c_str(), 0755); #endif } @@ -328,29 +427,75 @@ void EQEmuLogSys::CloseFileLogs() } } +/** + * @param log_name + */ void EQEmuLogSys::StartFileLogs(const std::string &log_name) { EQEmuLogSys::CloseFileLogs(); - /* 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 == false) + /** + * 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) { return; - - if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) { - if (!log_name.empty()) - platform_file_name = log_name; - - if (platform_file_name.empty()) - return; - - EQEmuLogSys::Out(Logs::General, Logs::Status, "Starting File Log 'logs/%s_%i.log'", platform_file_name.c_str(), getpid()); - EQEmuLogSys::MakeDirectory("logs/zone"); - process_log.open(StringFormat("logs/zone/%s_%i.log", platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out); - } else { - if (platform_file_name.empty()) - return; - - EQEmuLogSys::Out(Logs::General, Logs::Status, "Starting File Log 'logs/%s_%i.log'", platform_file_name.c_str(), getpid()); - process_log.open(StringFormat("logs/%s_%i.log", platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out); } -} + + /** + * Zone + */ + if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) { + if (!log_name.empty()) { + platform_file_name = log_name; + } + + if (platform_file_name.empty()) { + return; + } + + EQEmuLogSys::Out( + Logs::General, + Logs::Status, + "Starting File Log 'logs/%s_%i.log'", + platform_file_name.c_str(), + getpid()); + + /** + * Make directory if not exists + */ + EQEmuLogSys::MakeDirectory("logs/zone"); + + /** + * Open file pointer + */ + process_log.open( + StringFormat("logs/zone/%s_%i.log", platform_file_name.c_str(), getpid()), + std::ios_base::app | std::ios_base::out + ); + } + else { + + /** + * All other processes + */ + + if (platform_file_name.empty()) { + return; + } + + EQEmuLogSys::Out( + Logs::General, + Logs::Status, + "Starting File Log 'logs/%s_%i.log'", + platform_file_name.c_str(), + getpid()); + + /** + * Open file pointer + */ + process_log.open( + StringFormat("logs/%s_%i.log", platform_file_name.c_str(), getpid()), + std::ios_base::app | std::ios_base::out + ); + } +} \ No newline at end of file diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index b0afa72f2..be646432a 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -1,20 +1,21 @@ - -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2018 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * */ #ifndef EQEMU_LOGSYS_H @@ -34,130 +35,134 @@ namespace Logs { Detail /* 3 - Use this for extreme detail in logging, usually in extreme debugging in the stack or interprocess communication */ }; - /* - If you add to this, make sure you update LogCategoryName - NOTE: Only add to the bottom of the enum because that is the type ID assignment - */ + /** + * If you add to this, make sure you update LogCategoryName + * + * NOTE: Only add to the bottom of the enum because that is the type ID assignment + */ + enum LogCategory { + None = 0, + AA, + AI, + Aggro, + Attack, + Client_Server_Packet, + Combat, + Commands, + Crash, + Debug, + Doors, + Error, + Guilds, + Inventory, + Launcher, + Netcode, + Normal, + Object, + Pathing, + QS_Server, + Quests, + Rules, + Skills, + Spawns, + Spells, + Status, + TCP_Connection, + Tasks, + Tradeskills, + Trading, + Tribute, + UCS_Server, + WebInterface_Server, + World_Server, + Zone_Server, + MySQLError, + MySQLQuery, + Mercenaries, + QuestDebug, + Server_Client_Packet, + Client_Server_Packet_Unhandled, + Server_Client_Packet_With_Dump, + Client_Server_Packet_With_Dump, + Login_Server, + Client_Login, + Headless_Client, + HP_Update, + FixZ, + Food, + Traps, + NPCRoamBox, + NPCScaling, + MaxCategoryID /* Don't Remove this */ + }; -enum LogCategory { - None = 0, - AA, - AI, - Aggro, - Attack, - Client_Server_Packet, - Combat, - Commands, - Crash, - Debug, - Doors, - Error, - Guilds, - Inventory, - Launcher, - Netcode, - Normal, - Object, - Pathing, - QS_Server, - Quests, - Rules, - Skills, - Spawns, - Spells, - Status, - TCP_Connection, - Tasks, - Tradeskills, - Trading, - Tribute, - UCS_Server, - WebInterface_Server, - World_Server, - Zone_Server, - MySQLError, - MySQLQuery, - Mercenaries, - QuestDebug, - Server_Client_Packet, - Client_Server_Packet_Unhandled, - Server_Client_Packet_With_Dump, - Client_Server_Packet_With_Dump, - Login_Server, - Client_Login, - Headless_Client, - HP_Update, - FixZ, - Food, - Traps, - NPCRoamBox, - MaxCategoryID /* Don't Remove this*/ -}; - -/* If you add to this, make sure you update LogCategory */ -static const char* LogCategoryName[LogCategory::MaxCategoryID] = { - "", - "AA", - "AI", - "Aggro", - "Attack", - "Packet :: Client -> Server", - "Combat", - "Commands", - "Crash", - "Debug", - "Doors", - "Error", - "Guilds", - "Inventory", - "Launcher", - "Netcode", - "Normal", - "Object", - "Pathing", - "QS Server", - "Quests", - "Rules", - "Skills", - "Spawns", - "Spells", - "Status", - "TCP Connection", - "Tasks", - "Tradeskills", - "Trading", - "Tribute", - "UCS Server", - "WebInterface Server", - "World Server", - "Zone Server", - "MySQL Error", - "MySQL Query", - "Mercenaries", - "Quest Debug", - "Packet :: Server -> Client", - "Packet :: Client -> Server Unhandled", - "Packet :: Server -> Client (Dump)", - "Packet :: Client -> Server (Dump)", - "Login Server", - "Client Login", - "Headless Client", - "HP Update", - "FixZ", - "Food", - "Traps", - "NPC Roam Box" -}; + /** + * If you add to this, make sure you update LogCategory + */ + static const char* LogCategoryName[LogCategory::MaxCategoryID] = { + "", + "AA", + "AI", + "Aggro", + "Attack", + "Packet :: Client -> Server", + "Combat", + "Commands", + "Crash", + "Debug", + "Doors", + "Error", + "Guilds", + "Inventory", + "Launcher", + "Netcode", + "Normal", + "Object", + "Pathing", + "QS Server", + "Quests", + "Rules", + "Skills", + "Spawns", + "Spells", + "Status", + "TCP Connection", + "Tasks", + "Tradeskills", + "Trading", + "Tribute", + "UCS Server", + "WebInterface Server", + "World Server", + "Zone Server", + "MySQL Error", + "MySQL Query", + "Mercenaries", + "Quest Debug", + "Packet :: Server -> Client", + "Packet :: Client -> Server Unhandled", + "Packet :: Server -> Client (Dump)", + "Packet :: Client -> Server (Dump)", + "Login Server", + "Client Login", + "Headless Client", + "HP Update", + "FixZ", + "Food", + "Traps", + "NPC Roam Box", + "NPC Scaling" + }; } #define Log(debug_level, log_category, message, ...) do {\ - if (LogSys.log_settings[log_category].is_category_enabled == 1)\ - LogSys.Out(debug_level, log_category, message, ##__VA_ARGS__);\ + if (LogSys.log_settings[log_category].is_category_enabled == 1)\ + LogSys.Out(debug_level, log_category, message, ##__VA_ARGS__);\ } while (0) #define LogF(debug_level, log_category, message, ...) do {\ - if (LogSys.log_settings[log_category].is_category_enabled == 1)\ - LogSys.OutF(debug_level, log_category, message, ##__VA_ARGS__);\ + if (LogSys.log_settings[log_category].is_category_enabled == 1)\ + LogSys.OutF(debug_level, log_category, message, ##__VA_ARGS__);\ } while (0) class EQEmuLogSys { @@ -165,21 +170,30 @@ public: EQEmuLogSys(); ~EQEmuLogSys(); - void CloseFileLogs(); /* Close File Logs wherever necessary, either at zone shutdown or entire process shutdown for everything else. This should be handled on deconstructor but to be safe we use it anyways. */ - void LoadLogSettingsDefaults(); /* Initializes log_settings and sets some defaults if DB is not present */ - void MakeDirectory(const std::string &directory_name); /* Platform independent way of performing a MakeDirectory based on name */ - /* - The one and only Logging function that uses a debug level as a parameter, as well as a log_category - log_category - defined in Logs::LogCategory::[] - log_category name resolution works by passing the enum int ID to Logs::LogCategoryName[category_id] + /** + * Close File Logs wherever necessary, either at zone shutdown or entire process shutdown for everything else. + * This should be handled on deconstructor but to be safe we use it anyways. + */ + void CloseFileLogs(); + void LoadLogSettingsDefaults(); + void MakeDirectory(const std::string &directory_name); - Example: EQEmuLogSys::Out(Logs::General, Logs::Guilds, "This guild has no leader present"); - - This would pipe the same category and debug level to all output formats, but the internal memory reference of log_settings would - be checked against to see if that piped output is set to actually process it for the category and debug level + /** + * The one and only Logging function that uses a debug level as a parameter, as well as a log_category + * log_category - defined in Logs::LogCategory::[] + * log_category name resolution works by passing the enum int ID to Logs::LogCategoryName[category_id] + * + * Example: EQEmuLogSys::Out(Logs::General, Logs::Guilds, "This guild has no leader present"); + * - This would pipe the same category and debug level to all output formats, but the internal memory reference of log_settings would + * be checked against to see if that piped output is set to actually process it for the category and debug level */ void Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...); - void SetCurrentTimeStamp(char* time_stamp); /* Used in file logs to prepend a timestamp entry for logs */ - void StartFileLogs(const std::string &log_name = ""); /* Used to declare the processes file log and to keep it open for later use */ + + /** + * Used in file logs to prepend a timestamp entry for logs + */ + void SetCurrentTimeStamp(char* time_stamp); + void StartFileLogs(const std::string &log_name = ""); template void OutF(Logs::DebugLevel debug_level, uint16 log_category, const char *fmt, const Args&... args) @@ -188,16 +202,16 @@ public: Out(debug_level, log_category, log_str); } - /* - LogSettings Struct - - This struct is the master reference for all settings for each category, and for each output - - log_to_file[category_id] = [1-3] - Sets debug level for category to output to file - log_to_console[category_id] = [1-3] - Sets debug level for category to output to console - log_to_gmsay[category_id] = [1-3] - Sets debug level for category to output to gmsay + /** + * LogSettings Struct + * + * This struct is the master reference for all settings for each category, and for each output + * + * log_to_file[category_id] = [1-3] - Sets debug level for category to output to file + * log_to_console[category_id] = [1-3] - Sets debug level for category to output to console + * log_to_gmsay[category_id] = [1-3] - Sets debug level for category to output to gmsay + * */ - struct LogSettings { uint8 log_to_file; uint8 log_to_console; @@ -205,32 +219,62 @@ public: uint8 is_category_enabled; /* When any log output in a category > 0, set this to 1 as (Enabled) */ }; - /* Internally used memory reference for all log settings per category. - These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults. - Database loaded via Database::LoadLogSettings(log_settings) + /** + * Internally used memory reference for all log settings per category + * These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults + * Database loaded via Database::LoadLogSettings(log_settings) */ LogSettings log_settings[Logs::LogCategory::MaxCategoryID]; - bool file_logs_enabled; /* Set when log settings are loaded to determine if keeping a file open is necessary */ + bool file_logs_enabled; - int log_platform; /* Sets Executable platform (Zone/World/UCS) etc. */ + /** + * Sets Executable platform (Zone/World/UCS) etc. + */ + int log_platform; - std::string platform_file_name; /* File name used in writing logs */ + /** + * File name used in writing logs + */ + std::string platform_file_name; - uint16 GetGMSayColorFromCategory(uint16 log_category); /* GMSay Client Message colors mapped by category */ + /** + * GMSay Client Message colors mapped by category + * + * @param log_category + * @return + */ + uint16 GetGMSayColorFromCategory(uint16 log_category); void OnLogHookCallBackZone(std::function f) { on_log_gmsay_hook = f; } private: - std::function on_log_gmsay_hook; /* Callback pointer to zone process for hooking logs to zone using GMSay */ - std::string FormatOutMessageString(uint16 log_category, const std::string &in_message); /* Formats log messages like '[Category] This is a log message' */ - std::string GetLinuxConsoleColorFromCategory(uint16 log_category); /* Linux console color messages mapped by category */ - uint16 GetWindowsConsoleColorFromCategory(uint16 log_category); /* Windows console color messages mapped by category */ + /** + * Callback pointer to zone process for hooking logs to zone using GMSay + */ + std::function on_log_gmsay_hook; - void ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message); /* ProcessConsoleMessage called via Log */ - void ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message); /* ProcessGMSay called via Log */ - void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message); /* ProcessLogWrite called via Log */ + /** + * Formats log messages like '[Category] This is a log message' + */ + std::string FormatOutMessageString(uint16 log_category, const std::string &in_message); + + /** + * Linux console color messages mapped by category + * @param log_category + * @return + */ + std::string GetLinuxConsoleColorFromCategory(uint16 log_category); + + /** + * Windows console color messages mapped by category + */ + uint16 GetWindowsConsoleColorFromCategory(uint16 log_category); + + void ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message); + void ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message); + void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message); }; extern EQEmuLogSys LogSys; From 84643ce9a15d4bafde69dd29e48d5a497cad3838 Mon Sep 17 00:00:00 2001 From: Uleat Date: Mon, 22 Oct 2018 22:27:05 -0400 Subject: [PATCH 5/9] Inventory update work-around [ci skip] --- utils/sql/db_update_manifest.txt | 4 +- .../required/2018_08_13_inventory_update.sql | 63 +++++++++++++++++++ .../2018_08_13_inventory_version_update.sql | 60 ------------------ 3 files changed, 65 insertions(+), 62 deletions(-) diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index dae319641..587839291 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -381,8 +381,8 @@ 9125|2018_07_20_task_emote.sql|SHOW COLUMNS FROM `tasks` LIKE 'completion_emote'|empty| 9126|2018_09_07_FastRegen.sql|SHOW COLUMNS FROM `zone` LIKE 'fast_regen_hp'|empty| 9127|2018_09_07_NPCMaxAggroDist.sql|SHOW COLUMNS FROM `zone` LIKE 'npc_max_aggro_dist'|empty| -9128|2018_08_13_inventory_version_update.sql|SHOW TABLES LIKE 'inventory_versions'|empty| -9129|2018_08_13_inventory_update.sql|SELECT * FROM `inventory_versions` WHERE `version` = 2 and `step` = 0|not_empty| +9128|2018_08_13_inventory_version_update.sql|SHOW TABLES LIKE 'inventory_version'|not_empty| +9129|2018_08_13_inventory_update.sql|SHOW TABLES LIKE 'inventory_versions'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/required/2018_08_13_inventory_update.sql b/utils/sql/git/required/2018_08_13_inventory_update.sql index e02bc3ae0..4aeee6806 100644 --- a/utils/sql/git/required/2018_08_13_inventory_update.sql +++ b/utils/sql/git/required/2018_08_13_inventory_update.sql @@ -1,3 +1,66 @@ +DROP TABLE IF EXISTS `inventory_versions`; +DROP TABLE IF EXISTS `inventory_snapshots`; + + +CREATE TABLE `inventory_versions` ( + `version` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `step` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `bot_step` INT(11) UNSIGNED NOT NULL DEFAULT '0' +) +COLLATE='latin1_swedish_ci' +ENGINE=MyISAM; + +INSERT INTO `inventory_versions` VALUES (2, 0, 0); + + +CREATE TABLE `inventory_snapshots` ( + `time_index` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `charid` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `slotid` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `itemid` INT(11) UNSIGNED NULL DEFAULT '0', + `charges` SMALLINT(3) UNSIGNED NULL DEFAULT '0', + `color` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `augslot1` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `augslot2` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `augslot3` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `augslot4` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `augslot5` MEDIUMINT(7) UNSIGNED NULL DEFAULT '0', + `augslot6` MEDIUMINT(7) NOT NULL DEFAULT '0', + `instnodrop` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0', + `custom_data` TEXT NULL, + `ornamenticon` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `ornamentidfile` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `ornament_hero_model` INT(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`time_index`, `charid`, `slotid`) +) +COLLATE='latin1_swedish_ci' +ENGINE=InnoDB; + + +CREATE TABLE `inventory_snapshots_v1_bak` ( + `time_index` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `charid` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `slotid` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `itemid` INT(11) UNSIGNED NULL DEFAULT '0', + `charges` SMALLINT(3) UNSIGNED NULL DEFAULT '0', + `color` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `augslot1` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `augslot2` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `augslot3` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `augslot4` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', + `augslot5` MEDIUMINT(7) UNSIGNED NULL DEFAULT '0', + `augslot6` MEDIUMINT(7) NOT NULL DEFAULT '0', + `instnodrop` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0', + `custom_data` TEXT NULL, + `ornamenticon` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `ornamentidfile` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `ornament_hero_model` INT(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`time_index`, `charid`, `slotid`) +) +COLLATE='latin1_swedish_ci' +ENGINE=InnoDB; + + -- create inventory v1 backup SELECT @pre_timestamp := UNIX_TIMESTAMP(NOW()); INSERT INTO `inventory_snapshots_v1_bak` diff --git a/utils/sql/git/required/2018_08_13_inventory_version_update.sql b/utils/sql/git/required/2018_08_13_inventory_version_update.sql index f8fc33162..942544544 100644 --- a/utils/sql/git/required/2018_08_13_inventory_version_update.sql +++ b/utils/sql/git/required/2018_08_13_inventory_version_update.sql @@ -1,61 +1 @@ DROP TABLE IF EXISTS `inventory_version`; -DROP TABLE IF EXISTS `inventory_snapshots`; - - -CREATE TABLE `inventory_versions` ( - `version` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `step` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `bot_step` INT(11) UNSIGNED NOT NULL DEFAULT '0' -) -COLLATE='latin1_swedish_ci' -ENGINE=MyISAM; - -INSERT INTO `inventory_versions` VALUES (2, 0, 0); - - -CREATE TABLE `inventory_snapshots` ( - `time_index` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `charid` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `slotid` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', - `itemid` INT(11) UNSIGNED NULL DEFAULT '0', - `charges` SMALLINT(3) UNSIGNED NULL DEFAULT '0', - `color` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `augslot1` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', - `augslot2` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', - `augslot3` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', - `augslot4` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', - `augslot5` MEDIUMINT(7) UNSIGNED NULL DEFAULT '0', - `augslot6` MEDIUMINT(7) NOT NULL DEFAULT '0', - `instnodrop` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0', - `custom_data` TEXT NULL, - `ornamenticon` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `ornamentidfile` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `ornament_hero_model` INT(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`time_index`, `charid`, `slotid`) -) -COLLATE='latin1_swedish_ci' -ENGINE=InnoDB; - - -CREATE TABLE `inventory_snapshots_v1_bak` ( - `time_index` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `charid` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `slotid` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', - `itemid` INT(11) UNSIGNED NULL DEFAULT '0', - `charges` SMALLINT(3) UNSIGNED NULL DEFAULT '0', - `color` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `augslot1` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', - `augslot2` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', - `augslot3` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', - `augslot4` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0', - `augslot5` MEDIUMINT(7) UNSIGNED NULL DEFAULT '0', - `augslot6` MEDIUMINT(7) NOT NULL DEFAULT '0', - `instnodrop` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0', - `custom_data` TEXT NULL, - `ornamenticon` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `ornamentidfile` INT(11) UNSIGNED NOT NULL DEFAULT '0', - `ornament_hero_model` INT(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`time_index`, `charid`, `slotid`) -) -COLLATE='latin1_swedish_ci' -ENGINE=InnoDB; From dbb368865c840542ba4d6099ea3d412e58fbcb14 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 3 Nov 2018 17:44:19 -0400 Subject: [PATCH 6/9] Add some Follow stuff to lua You can also disallow following code from allowing the NPC to run if they're far enough away --- zone/lua_npc.cpp | 18 ++++++++++++++++++ zone/lua_npc.h | 3 +++ zone/mob.cpp | 3 ++- zone/mob.h | 9 ++++++--- zone/mob_ai.cpp | 3 ++- 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/zone/lua_npc.cpp b/zone/lua_npc.cpp index a16d78361..9079049b7 100644 --- a/zone/lua_npc.cpp +++ b/zone/lua_npc.cpp @@ -333,6 +333,21 @@ void Lua_NPC::AI_SetRoambox(float dist, float max_x, float min_x, float max_y, f self->AI_SetRoambox(dist, max_x, min_x, max_y, min_y, delay, mindelay); } +void Lua_NPC::SetFollowID(int id) { + Lua_Safe_Call_Void(); + self->SetFollowID(id); +} + +void Lua_NPC::SetFollowDistance(int dist) { + Lua_Safe_Call_Void(); + self->SetFollowDistance(dist); +} + +void Lua_NPC::SetFollowCanRun(bool v) { + Lua_Safe_Call_Void(); + self->SetFollowCanRun(v); +} + int Lua_NPC::GetNPCSpellsID() { Lua_Safe_Call_Int(); return self->GetNPCSpellsID(); @@ -572,6 +587,9 @@ luabind::scope lua_register_npc() { .def("IsGuarding", (bool(Lua_NPC::*)(void))&Lua_NPC::IsGuarding) .def("AI_SetRoambox", (void(Lua_NPC::*)(float,float,float,float,float))&Lua_NPC::AI_SetRoambox) .def("AI_SetRoambox", (void(Lua_NPC::*)(float,float,float,float,float,uint32,uint32))&Lua_NPC::AI_SetRoambox) + .def("SetFollowID", (void(Lua_NPC::*)(int))&Lua_NPC::SetFollowID) + .def("SetFollowDistance", (void(Lua_NPC::*)(int))&Lua_NPC::SetFollowDistance) + .def("SetFollowCanRun", (void(Lua_NPC::*)(bool))&Lua_NPC::SetFollowCanRun) .def("GetNPCSpellsID", (int(Lua_NPC::*)(void))&Lua_NPC::GetNPCSpellsID) .def("GetSpawnPointID", (int(Lua_NPC::*)(void))&Lua_NPC::GetSpawnPointID) .def("GetSpawnPointX", (float(Lua_NPC::*)(void))&Lua_NPC::GetSpawnPointX) diff --git a/zone/lua_npc.h b/zone/lua_npc.h index 972adee90..a0097eb90 100644 --- a/zone/lua_npc.h +++ b/zone/lua_npc.h @@ -92,6 +92,9 @@ public: bool IsGuarding(); void AI_SetRoambox(float dist, float max_x, float min_x, float max_y, float min_y); void AI_SetRoambox(float dist, float max_x, float min_x, float max_y, float min_y, uint32 delay, uint32 mindelay); + void SetFollowID(int id); + void SetFollowDistance(int dist); + void SetFollowCanRun(bool v); int GetNPCSpellsID(); int GetSpawnPointID(); float GetSpawnPointX(); diff --git a/zone/mob.cpp b/zone/mob.cpp index 45a41df6e..e4c7b5f26 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -383,8 +383,9 @@ Mob::Mob(const char* in_name, m_CurrentWayPoint = glm::vec4(); cur_wp_pause = 0; patrol = 0; - follow = 0; + follow_id = 0; follow_dist = 100; // Default Distance for Follow + follow_run = true; // We can run if distance great enough no_target_hotkey = false; flee_mode = false; currently_fleeing = false; diff --git a/zone/mob.h b/zone/mob.h index 30464822c..59b4a5079 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -695,10 +695,12 @@ public: virtual bool IsAttackAllowed(Mob *target, bool isSpellAttack = false); bool IsTargeted() const { return (targeted > 0); } inline void IsTargeted(int in_tar) { targeted += in_tar; if(targeted < 0) targeted = 0;} - void SetFollowID(uint32 id) { follow = id; } + void SetFollowID(uint32 id) { follow_id = id; } void SetFollowDistance(uint32 dist) { follow_dist = dist; } - uint32 GetFollowID() const { return follow; } + void SetFollowCanRun(bool v) { follow_run = v; } + uint32 GetFollowID() const { return follow_id; } uint32 GetFollowDistance() const { return follow_dist; } + bool GetFollowCanRun() const { return follow_run; } inline bool IsRareSpawn() const { return rare_spawn; } inline void SetRareSpawn(bool in) { rare_spawn = in; } @@ -1235,8 +1237,9 @@ protected: uint16 ownerid; PetType typeofpet; int16 petpower; - uint32 follow; + uint32 follow_id; uint32 follow_dist; + bool follow_run; bool no_target_hotkey; bool rare_spawn; diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index e4066e2cc..bab3b78d2 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -1647,7 +1647,8 @@ void Mob::AI_Process() { if (distance >= follow_distance) { int speed = GetWalkspeed(); - if (distance >= follow_distance + 150) { + // maybe we want the NPC to only walk doing follow logic + if (GetFollowCanRun() && distance >= follow_distance + 150) { speed = GetRunspeed(); } From 467e2d3114fe010712efa2bfbdd6fd7fe1f84961 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 3 Nov 2018 18:10:36 -0400 Subject: [PATCH 7/9] Add follow getters to lua just in case --- zone/lua_npc.cpp | 19 +++++++++++++++++++ zone/lua_npc.h | 3 +++ 2 files changed, 22 insertions(+) diff --git a/zone/lua_npc.cpp b/zone/lua_npc.cpp index 9079049b7..02e9b9795 100644 --- a/zone/lua_npc.cpp +++ b/zone/lua_npc.cpp @@ -348,6 +348,21 @@ void Lua_NPC::SetFollowCanRun(bool v) { self->SetFollowCanRun(v); } +int Lua_NPC::GetFollowID() { + Lua_Safe_Call_Int(); + return self->GetFollowID(); +} + +int Lua_NPC::GetFollowDistance() { + Lua_Safe_Call_Int(); + return self->GetFollowDistance(); +} + +bool Lua_NPC::GetFollowCanRun() { + Lua_Safe_Call_Bool(); + return self->GetFollowCanRun(); +} + int Lua_NPC::GetNPCSpellsID() { Lua_Safe_Call_Int(); return self->GetNPCSpellsID(); @@ -590,6 +605,10 @@ luabind::scope lua_register_npc() { .def("SetFollowID", (void(Lua_NPC::*)(int))&Lua_NPC::SetFollowID) .def("SetFollowDistance", (void(Lua_NPC::*)(int))&Lua_NPC::SetFollowDistance) .def("SetFollowCanRun", (void(Lua_NPC::*)(bool))&Lua_NPC::SetFollowCanRun) + .def("GetFollowID", (int(Lua_NPC::*)(void))&Lua_NPC::GetFollowID) + .def("GetFollowDistance", (int(Lua_NPC::*)(void))&Lua_NPC::GetFollowDistance) + .def("GetFollowCanRun", (bool(Lua_NPC::*)(void))&Lua_NPC::GetFollowCanRun) + .def("GetNPCSpellsID", (int(Lua_NPC::*)(void))&Lua_NPC::GetNPCSpellsID) .def("GetNPCSpellsID", (int(Lua_NPC::*)(void))&Lua_NPC::GetNPCSpellsID) .def("GetSpawnPointID", (int(Lua_NPC::*)(void))&Lua_NPC::GetSpawnPointID) .def("GetSpawnPointX", (float(Lua_NPC::*)(void))&Lua_NPC::GetSpawnPointX) diff --git a/zone/lua_npc.h b/zone/lua_npc.h index a0097eb90..4b567eb1b 100644 --- a/zone/lua_npc.h +++ b/zone/lua_npc.h @@ -95,6 +95,9 @@ public: void SetFollowID(int id); void SetFollowDistance(int dist); void SetFollowCanRun(bool v); + int GetFollowID(); + int GetFollowDistance(); + bool GetFollowCanRun(); int GetNPCSpellsID(); int GetSpawnPointID(); float GetSpawnPointX(); From cc920e60d9b0a39c6bc5be559a81aab3666ee30f Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sat, 3 Nov 2018 18:14:54 -0400 Subject: [PATCH 8/9] Reset all follow variables when follow target is gone --- zone/mob_ai.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index bab3b78d2..05e53c7e8 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -1635,6 +1635,8 @@ void Mob::AI_Process() { Mob *follow = entity_list.GetMob(static_cast(GetFollowID())); if (!follow) { SetFollowID(0); + SetFollowDistance(100); + SetFollowCanRun(true); } else { From 4e0d85534e5bee80caa5ea778b657fa99a6b353b Mon Sep 17 00:00:00 2001 From: Akkadius Date: Mon, 5 Nov 2018 00:43:52 -0600 Subject: [PATCH 9/9] Fix issue where new log category settings were getting injected into the database with all settings turned on --- common/database.cpp | 7 +++---- common/eqemu_logsys.cpp | 9 +++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index a9496b6e3..8ff79a44c 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -2080,7 +2080,6 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) { auto results = QueryDatabase(query); int log_category_id = 0; - LogSys.file_logs_enabled = false; int categories_in_database[1000] = {}; @@ -2090,9 +2089,9 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) { continue; } - log_settings[log_category_id].log_to_console = atoi(row[2]); - log_settings[log_category_id].log_to_file = atoi(row[3]); - log_settings[log_category_id].log_to_gmsay = atoi(row[4]); + log_settings[log_category_id].log_to_console = static_cast(atoi(row[2])); + log_settings[log_category_id].log_to_file = static_cast(atoi(row[3])); + log_settings[log_category_id].log_to_gmsay = static_cast(atoi(row[4])); /** * Determine if any output method is enabled for the category diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index f4d36e5d5..9e99e6cbe 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -113,6 +113,15 @@ void EQEmuLogSys::LoadLogSettingsDefaults() */ 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; + log_settings[log_category_id].log_to_file = 0; + log_settings[log_category_id].log_to_gmsay = 0; + log_settings[log_category_id].is_category_enabled = 0; + } + + file_logs_enabled = false; + /** * Zero out Array */