summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKitzunu <24550914+Kitzunu@users.noreply.github.com>2021-05-30 21:12:01 +0200
committerGitHub <noreply@github.com>2021-05-30 21:12:01 +0200
commitae665f7ec32c5da3877b4acb0d0dd2534e9cdd06 (patch)
tree4354987c0cf316e701cedbd83e805d1c773c3dd6
parente93159b408f2ce2162b98c9a631fa7b932a97593 (diff)
feat(Core/Command): server debug (#6007)
* initial work * fix query * load * clean up * remove from startup * ACE * remove static * Update MySQLThreading.cpp * not used * Update MySQLThreading.cpp * unit testing * Update WorldMock.h * show Boost ver * Update WorldMock.h * include * Now we have boost::filesystem woo * fix build * fix typo
-rw-r--r--data/sql/updates/pending_db_world/rev_1621718778456057300.sql5
-rw-r--r--src/cmake/revision.h.in.cmake2
-rw-r--r--src/common/GitRevision.cpp18
-rw-r--r--src/common/GitRevision.h2
-rw-r--r--src/server/database/Database/MySQLThreading.cpp23
-rw-r--r--src/server/database/Database/MySQLThreading.h38
-rw-r--r--src/server/game/World/IWorld.h4
-rw-r--r--src/server/game/World/World.cpp39
-rw-r--r--src/server/game/World/World.h7
-rw-r--r--src/server/scripts/Commands/cs_server.cpp117
-rw-r--r--src/server/worldserver/Master.cpp1
-rw-r--r--src/test/mocks/WorldMock.h4
12 files changed, 226 insertions, 34 deletions
diff --git a/data/sql/updates/pending_db_world/rev_1621718778456057300.sql b/data/sql/updates/pending_db_world/rev_1621718778456057300.sql
new file mode 100644
index 0000000000..0e10c13ba8
--- /dev/null
+++ b/data/sql/updates/pending_db_world/rev_1621718778456057300.sql
@@ -0,0 +1,5 @@
+INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1621718778456057300');
+
+DELETE FROM `command` WHERE `name` = 'server debug';
+INSERT INTO `command` (`name`, `security`, `help`) VALUES
+('server debug', 3, 'Syntax: .server debug\r\nShows detailed information about the server setup, useful when reporting a bug.');
diff --git a/src/cmake/revision.h.in.cmake b/src/cmake/revision.h.in.cmake
index 9888ddd90b..0b977bc68f 100644
--- a/src/cmake/revision.h.in.cmake
+++ b/src/cmake/revision.h.in.cmake
@@ -4,6 +4,8 @@
#define _HASH "@rev_hash@"
#define _DATE "@rev_date@"
#define _BRANCH "@rev_branch@"
+ #define _CMAKE_VERSION R"(@CMAKE_VERSION@)"
+ #define _CMAKE_HOST_SYSTEM R"(@CMAKE_HOST_SYSTEM_NAME@ @CMAKE_HOST_SYSTEM_VERSION@)"
#define VER_COMPANYNAME_STR "AzerothCore"
#define VER_LEGALCOPYRIGHT_STR "AzerothCore"
#define VER_FILEVERSION 0,0,0
diff --git a/src/common/GitRevision.cpp b/src/common/GitRevision.cpp
index bf7fd4a428..a8a53665f7 100644
--- a/src/common/GitRevision.cpp
+++ b/src/common/GitRevision.cpp
@@ -21,6 +21,16 @@ char const* GitRevision::GetBranch()
return _BRANCH;
}
+char const* GitRevision::GetCMakeVersion()
+{
+ return _CMAKE_VERSION;
+}
+
+char const* GitRevision::GetHostOSVersion()
+{
+ return _CMAKE_HOST_SYSTEM;
+}
+
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
# ifdef _WIN64
# define AZEROTH_PLATFORM_STR "Win64"
@@ -31,9 +41,15 @@ char const* GitRevision::GetBranch()
# define AZEROTH_PLATFORM_STR "Unix"
#endif
+#ifndef ACORE_API_USE_DYNAMIC_LINKING
+# define ACORE_LINKAGE_TYPE_STR "Static"
+#else
+# define ACORE_LINKAGE_TYPE_STR "Dynamic"
+#endif
+
char const* GitRevision::GetFullVersion()
{
- return VER_COMPANYNAME_STR " rev. " VER_PRODUCTVERSION_STR " (" AZEROTH_PLATFORM_STR ", " _BUILD_DIRECTIVE ")";
+ return VER_COMPANYNAME_STR " rev. " VER_PRODUCTVERSION_STR " (" AZEROTH_PLATFORM_STR ", " _BUILD_DIRECTIVE ", " ACORE_LINKAGE_TYPE_STR ")";
}
char const* GitRevision::GetCompanyNameStr()
diff --git a/src/common/GitRevision.h b/src/common/GitRevision.h
index 762c3512da..f46520b057 100644
--- a/src/common/GitRevision.h
+++ b/src/common/GitRevision.h
@@ -13,6 +13,8 @@ namespace GitRevision
char const* GetHash();
char const* GetDate();
char const* GetBranch();
+ char const* GetCMakeVersion();
+ char const* GetHostOSVersion();
char const* GetFullVersion();
char const* GetCompanyNameStr();
char const* GetLegalCopyrightStr();
diff --git a/src/server/database/Database/MySQLThreading.cpp b/src/server/database/Database/MySQLThreading.cpp
new file mode 100644
index 0000000000..5d70ee4f8d
--- /dev/null
+++ b/src/server/database/Database/MySQLThreading.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2016+ AzerothCore <www.azerothcore.org>
+ * Copyright (C) 2008-2021 TrinityCore <http://www.trinitycore.org/>
+ */
+
+#include "MySQLThreading.h"
+#include "Log.h"
+#include <mysql.h>
+
+void MySQL::Library_Init()
+{
+ mysql_library_init(-1, nullptr, nullptr);
+}
+
+void MySQL::Library_End()
+{
+ mysql_library_end();
+}
+
+uint32 MySQL::GetLibraryVersion()
+{
+ return MYSQL_VERSION_ID;
+}
diff --git a/src/server/database/Database/MySQLThreading.h b/src/server/database/Database/MySQLThreading.h
index 29f1a07405..8a26ba375b 100644
--- a/src/server/database/Database/MySQLThreading.h
+++ b/src/server/database/Database/MySQLThreading.h
@@ -9,39 +9,11 @@
#include "Log.h"
-class MySQL
+namespace MySQL
{
-public:
- /*! Create a thread on the MySQL server to mirrior the calling thread,
- initializes thread-specific variables and allows thread-specific
- operations without concurrence from other threads.
- This should only be called if multiple core threads are running
- on the same MySQL connection. Seperate MySQL connections implicitly
- create a mirror thread.
- */
- static void Thread_Init()
- {
- mysql_thread_init();
- }
-
- /*! Shuts down MySQL thread and frees resources, should only be called
- when we terminate. MySQL threads and connections are not configurable
- during runtime.
- */
- static void Thread_End()
- {
- mysql_thread_end();
- }
-
- static void Library_Init()
- {
- mysql_library_init(-1, nullptr, nullptr);
- }
-
- static void Library_End()
- {
- mysql_library_end();
- }
-};
+ void Library_Init();
+ void Library_End();
+ uint32 GetLibraryVersion();
+}
#endif
diff --git a/src/server/game/World/IWorld.h b/src/server/game/World/IWorld.h
index 383d17e9e0..5f40a9f524 100644
--- a/src/server/game/World/IWorld.h
+++ b/src/server/game/World/IWorld.h
@@ -581,7 +581,11 @@ public:
virtual void UpdateRealmCharCount(uint32 accid) = 0;
virtual LocaleConstant GetAvailableDbcLocale(LocaleConstant locale) const = 0;
virtual void LoadDBVersion() = 0;
+ virtual void LoadDBRevision() = 0;
virtual char const* GetDBVersion() const = 0;
+ virtual char const* GetWorldDBRevision() const = 0;
+ virtual char const* GetCharacterDBRevision() const = 0;
+ virtual char const* GetAuthDBRevision() const = 0;
virtual void LoadAutobroadcasts() = 0;
virtual void UpdateAreaDependentAuras() = 0;
virtual uint32 GetCleaningFlags() const = 0;
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 20186e06f2..69392bc299 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -3109,6 +3109,45 @@ void World::LoadDBVersion()
m_DBVersion = "Unknown world database.";
}
+void World::LoadDBRevision()
+{
+ QueryResult resultWorld = WorldDatabase.Query("SELECT date FROM version_db_world ORDER BY date DESC LIMIT 1");
+ QueryResult resultCharacter = CharacterDatabase.Query("SELECT date FROM version_db_characters ORDER BY date DESC LIMIT 1");
+ QueryResult resultAuth = LoginDatabase.Query("SELECT date FROM version_db_auth ORDER BY date DESC LIMIT 1");
+
+ if (resultWorld)
+ {
+ Field* fields = resultWorld->Fetch();
+
+ m_WorldDBRevision = fields[0].GetString();
+ }
+ if (resultCharacter)
+ {
+ Field* fields = resultCharacter->Fetch();
+
+ m_CharacterDBRevision = fields[0].GetString();
+ }
+ if (resultAuth)
+ {
+ Field* fields = resultAuth->Fetch();
+
+ m_AuthDBRevision = fields[0].GetString();
+ }
+
+ if (m_WorldDBRevision.empty())
+ {
+ m_WorldDBRevision = "Unkown World Database Revision";
+ }
+ if (m_CharacterDBRevision.empty())
+ {
+ m_CharacterDBRevision = "Unkown Character Database Revision";
+ }
+ if (m_AuthDBRevision.empty())
+ {
+ m_AuthDBRevision = "Unkown Auth Database Revision";
+ }
+}
+
void World::UpdateAreaDependentAuras()
{
SessionMap::const_iterator itr;
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index b2005d2073..edbfd8dfde 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -370,7 +370,11 @@ public:
// used World DB version
void LoadDBVersion();
+ void LoadDBRevision();
char const* GetDBVersion() const { return m_DBVersion.c_str(); }
+ char const* GetWorldDBRevision() const { return m_WorldDBRevision.c_str(); }
+ char const* GetCharacterDBRevision() const { return m_CharacterDBRevision.c_str(); }
+ char const* GetAuthDBRevision() const { return m_AuthDBRevision.c_str(); }
void LoadAutobroadcasts();
@@ -478,6 +482,9 @@ private:
// used versions
std::string m_DBVersion;
+ std::string m_WorldDBRevision;
+ std::string m_CharacterDBRevision;
+ std::string m_AuthDBRevision;
typedef std::map<uint8, std::string> AutobroadcastsMap;
AutobroadcastsMap m_Autobroadcasts;
diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp
index 068988f754..d02b7b6605 100644
--- a/src/server/scripts/Commands/cs_server.cpp
+++ b/src/server/scripts/Commands/cs_server.cpp
@@ -15,12 +15,20 @@ EndScriptData */
#include "Chat.h"
#include "Config.h"
#include "GitRevision.h"
+#include "VMapManager2.h"
+#include "VMapFactory.h"
#include "Language.h"
#include "ObjectAccessor.h"
#include "Player.h"
+#include "Realm.h"
#include "ScriptMgr.h"
#include "ServerMotd.h"
#include "StringConvert.h"
+#include <boost/filesystem/operations.hpp>
+#include <boost/version.hpp>
+#include <openssl/crypto.h>
+#include <openssl/opensslv.h>
+#include <numeric>
class server_commandscript : public CommandScript
{
@@ -64,6 +72,7 @@ public:
static std::vector<ChatCommand> serverCommandTable =
{
{ "corpses", SEC_GAMEMASTER, true, &HandleServerCorpsesCommand, "" },
+ { "debug", SEC_ADMINISTRATOR, true, &HandleServerDebugCommand, "" },
{ "exit", SEC_CONSOLE, true, &HandleServerExitCommand, "" },
{ "idlerestart", SEC_CONSOLE, true, nullptr, "", serverIdleRestartCommandTable },
{ "idleshutdown", SEC_CONSOLE, true, nullptr, "", serverIdleShutdownCommandTable },
@@ -89,6 +98,114 @@ public:
return true;
}
+ static bool HandleServerDebugCommand(ChatHandler* handler, char const* /*args*/)
+ {
+ uint16 worldPort = uint16(sWorld->getIntConfig(CONFIG_PORT_WORLD));
+ std::string dbPortOutput;
+
+ {
+ uint16 dbPort = 0;
+ if (QueryResult res = LoginDatabase.PQuery("SELECT port FROM realmlist WHERE id = %u", realm.Id.Realm))
+ dbPort = (*res)[0].GetUInt16();
+
+ if (dbPort)
+ dbPortOutput = acore::StringFormat("Realmlist (Realm Id: %u) configured in port %" PRIu16, realm.Id.Realm, dbPort);
+ else
+ dbPortOutput = acore::StringFormat("Realm Id: %u not found in `realmlist` table. Please check your setup", realm.Id.Realm);
+ }
+
+ handler->PSendSysMessage("%s", GitRevision::GetFullVersion());
+ handler->PSendSysMessage("Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
+ handler->PSendSysMessage("Using ACE version: %s", ACE_VERSION);
+ handler->PSendSysMessage("Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100);
+ handler->PSendSysMessage("Using MySQL version: %u", MySQL::GetLibraryVersion());
+ handler->PSendSysMessage("Using CMake version: %s", GitRevision::GetCMakeVersion());
+
+ handler->PSendSysMessage("Compiled on: %s", GitRevision::GetHostOSVersion());
+
+ handler->PSendSysMessage("Worldserver listening connections on port %" PRIu16, worldPort);
+ handler->PSendSysMessage("%s", dbPortOutput.c_str());
+
+ bool vmapIndoorCheck = sWorld->getBoolConfig(CONFIG_VMAP_INDOOR_CHECK);
+ bool vmapLOSCheck = VMAP::VMapFactory::createOrGetVMapManager()->isLineOfSightCalcEnabled();
+ bool vmapHeightCheck = VMAP::VMapFactory::createOrGetVMapManager()->isHeightCalcEnabled();
+
+ bool mmapEnabled = sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS);
+
+ std::string dataDir = sWorld->GetDataPath();
+ std::vector<std::string> subDirs;
+ subDirs.emplace_back("maps");
+ if (vmapIndoorCheck || vmapLOSCheck || vmapHeightCheck)
+ {
+ handler->PSendSysMessage("VMAPs status: Enabled. LineOfSight: %i, getHeight: %i, indoorCheck: %i", vmapLOSCheck, vmapHeightCheck, vmapIndoorCheck);
+ subDirs.emplace_back("vmaps");
+ }
+ else
+ handler->SendSysMessage("VMAPs status: Disabled");
+
+ if (mmapEnabled)
+ {
+ handler->SendSysMessage("MMAPs status: Enabled");
+ subDirs.emplace_back("mmaps");
+ }
+ else
+ handler->SendSysMessage("MMAPs status: Disabled");
+
+ for (std::string const& subDir : subDirs)
+ {
+ boost::filesystem::path mapPath(dataDir);
+ mapPath /= subDir;
+
+ if (!boost::filesystem::exists(mapPath))
+ {
+ handler->PSendSysMessage("%s directory doesn't exist!. Using path: %s", subDir.c_str(), mapPath.generic_string().c_str());
+ continue;
+ }
+
+ auto end = boost::filesystem::directory_iterator();
+ std::size_t folderSize = std::accumulate(boost::filesystem::directory_iterator(mapPath), end, std::size_t(0), [](std::size_t val, boost::filesystem::path const& mapFile)
+ {
+ if (boost::filesystem::is_regular_file(mapFile))
+ val += boost::filesystem::file_size(mapFile);
+ return val;
+ });
+
+ handler->PSendSysMessage("%s directory located in %s. Total size: " SZFMTD " bytes", subDir.c_str(), mapPath.generic_string().c_str(), folderSize);
+ }
+
+ LocaleConstant defaultLocale = sWorld->GetDefaultDbcLocale();
+ uint32 availableLocalesMask = (1 << defaultLocale);
+
+ for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
+ {
+ LocaleConstant locale = static_cast<LocaleConstant>(i);
+ if (locale == defaultLocale)
+ continue;
+
+ if (sWorld->GetAvailableDbcLocale(locale) != defaultLocale)
+ availableLocalesMask |= (1 << locale);
+ }
+
+ std::string availableLocales;
+ for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
+ {
+ if (!(availableLocalesMask & (1 << i)))
+ continue;
+
+ availableLocales += localeNames[i];
+ if (i != TOTAL_LOCALES - 1)
+ availableLocales += " ";
+ }
+
+ handler->PSendSysMessage("Using %s DBC Locale as default. All available DBC locales: %s", localeNames[defaultLocale], availableLocales.c_str());
+
+ handler->PSendSysMessage("Using World DB: %s", sWorld->GetDBVersion());
+ handler->PSendSysMessage("Using World DB Revision: %s", sWorld->GetWorldDBRevision());
+ handler->PSendSysMessage("Using Character DB Revision: %s", sWorld->GetCharacterDBRevision());
+ handler->PSendSysMessage("Using Auth DB Revision: %s", sWorld->GetAuthDBRevision());
+ return true;
+ }
+
static bool HandleServerInfoCommand(ChatHandler* handler, char const* /*args*/)
{
std::string realmName = sWorld->GetRealmName();
diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp
index dce780f814..fd2a7e2e33 100644
--- a/src/server/worldserver/Master.cpp
+++ b/src/server/worldserver/Master.cpp
@@ -406,6 +406,7 @@ bool Master::_StartDB()
WorldDatabase.PExecute("UPDATE version SET core_version = '%s', core_revision = '%s'", GitRevision::GetFullVersion(), GitRevision::GetHash()); // One-time query
sWorld->LoadDBVersion();
+ sWorld->LoadDBRevision();
LOG_INFO("server", "Using World DB: %s", sWorld->GetDBVersion());
return true;
diff --git a/src/test/mocks/WorldMock.h b/src/test/mocks/WorldMock.h
index f58be22e22..15c2c8cd1b 100644
--- a/src/test/mocks/WorldMock.h
+++ b/src/test/mocks/WorldMock.h
@@ -112,7 +112,11 @@ public:
MOCK_METHOD(void, UpdateRealmCharCount, (uint32 accid), ());
MOCK_METHOD(LocaleConstant, GetAvailableDbcLocale, (LocaleConstant locale), (const));
MOCK_METHOD(void, LoadDBVersion, ());
+ MOCK_METHOD(void, LoadDBRevision, ());
MOCK_METHOD(char const *, GetDBVersion, (), (const));
+ MOCK_METHOD(char const *, GetWorldDBRevision, (), (const));
+ MOCK_METHOD(char const *, GetCharacterDBRevision, (), (const));
+ MOCK_METHOD(char const *, GetAuthDBRevision, (), (const));
MOCK_METHOD(void, LoadAutobroadcasts, ());
MOCK_METHOD(void, UpdateAreaDependentAuras, ());
MOCK_METHOD(uint32, GetCleaningFlags, (), (const));