mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 01:08:35 +00:00
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
This commit is contained in:
@@ -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.');
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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();
|
||||
|
||||
23
src/server/database/Database/MySQLThreading.cpp
Normal file
23
src/server/database/Database/MySQLThreading.cpp
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user