diff options
Diffstat (limited to 'src/server/shared')
76 files changed, 17 insertions, 13809 deletions
diff --git a/src/server/shared/CMakeLists.txt b/src/server/shared/CMakeLists.txt index d68ddf85ff3..1653d605faa 100644 --- a/src/server/shared/CMakeLists.txt +++ b/src/server/shared/CMakeLists.txt @@ -12,25 +12,16 @@ if( USE_COREPCH ) include_directories(${CMAKE_CURRENT_BINARY_DIR}) endif() -file(GLOB_RECURSE sources_Configuration Configuration/*.cpp Configuration/*.h) file(GLOB_RECURSE sources_Cryptography Cryptography/*.cpp Cryptography/*.h) -file(GLOB_RECURSE sources_Database Database/*.cpp Database/*.h) file(GLOB_RECURSE sources_DataStores DataStores/*.cpp DataStores/*.h) file(GLOB_RECURSE sources_Dynamic Dynamic/*.cpp Dynamic/*.h) -file(GLOB_RECURSE sources_Logging Logging/*.cpp Logging/*.h) file(GLOB_RECURSE sources_Networking Networking/*.cpp Networking/*.h) file(GLOB_RECURSE sources_Packets Packets/*.cpp Packets/*.h) -file(GLOB_RECURSE sources_Threading Threading/*.cpp Threading/*.h) -file(GLOB_RECURSE sources_Updater Updater/*.cpp Updater/*.h) -file(GLOB_RECURSE sources_Utilities Utilities/*.cpp Utilities/*.h) - +if( WIN32 ) + file(GLOB_RECURSE sources_Service Service/*.cpp Service/*.h) +endif( WIN32 ) file(GLOB sources_localdir *.cpp *.h) -# Manually set sources for Debugging directory as we don't want to include WheatyExceptionReport in shared project -# It needs to be included both in authserver and worldserver for the static global variable to be properly initialized -# and to handle crash logs on windows -set(sources_Debugging Debugging/Errors.cpp Debugging/Errors.h) - # # Build shared sourcelist # @@ -42,18 +33,13 @@ endif() set(shared_STAT_SRCS ${shared_STAT_SRCS} - ${sources_Configuration} ${sources_Cryptography} - ${sources_Database} ${sources_DataStores} - ${sources_Debugging} ${sources_Dynamic} - ${sources_Logging} ${sources_Networking} ${sources_Packets} - ${sources_Threading} - ${sources_Updater} ${sources_Utilities} + ${sources_Service} ${sources_localdir} ) @@ -65,20 +51,25 @@ include_directories( ${CMAKE_SOURCE_DIR}/dep/utf8cpp ${CMAKE_SOURCE_DIR}/dep/process ${CMAKE_SOURCE_DIR}/src/server + ${CMAKE_SOURCE_DIR}/src/server/database + ${CMAKE_SOURCE_DIR}/src/server/database/Database + ${CMAKE_SOURCE_DIR}/src/server/database/Logging + ${CMAKE_SOURCE_DIR}/src/server/database/Updater ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/Configuration ${CMAKE_CURRENT_SOURCE_DIR}/Cryptography - ${CMAKE_CURRENT_SOURCE_DIR}/Database ${CMAKE_CURRENT_SOURCE_DIR}/DataStores - ${CMAKE_CURRENT_SOURCE_DIR}/Debugging ${CMAKE_CURRENT_SOURCE_DIR}/Dynamic - ${CMAKE_CURRENT_SOURCE_DIR}/Logging ${CMAKE_CURRENT_SOURCE_DIR}/Networking ${CMAKE_CURRENT_SOURCE_DIR}/Packets - ${CMAKE_CURRENT_SOURCE_DIR}/Threading - ${CMAKE_CURRENT_SOURCE_DIR}/Utilities - ${CMAKE_CURRENT_SOURCE_DIR}/Updater - ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object + ${CMAKE_CURRENT_SOURCE_DIR}/Service + ${CMAKE_SOURCE_DIR}/src/common/ + ${CMAKE_SOURCE_DIR}/src/common/Collision + ${CMAKE_SOURCE_DIR}/src/common/Collision/Management + ${CMAKE_SOURCE_DIR}/src/common/Collision/Models + ${CMAKE_SOURCE_DIR}/src/common/Debugging + ${CMAKE_SOURCE_DIR}/src/common/Utilities + ${CMAKE_SOURCE_DIR}/src/common/Configuration + ${CMAKE_SOURCE_DIR}/src/common/Logging ${MYSQL_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${VALGRIND_INCLUDE_DIR} diff --git a/src/server/shared/Common.cpp b/src/server/shared/Common.cpp deleted file mode 100644 index 56e3c4faaf5..00000000000 --- a/src/server/shared/Common.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "Common.h" - -char const* localeNames[TOTAL_LOCALES] = { - "enUS", - "koKR", - "frFR", - "deDE", - "zhCN", - "zhTW", - "esES", - "esMX", - "ruRU" -}; - -LocaleConstant GetLocaleByName(const std::string& name) -{ - for (uint32 i = 0; i < TOTAL_LOCALES; ++i) - if (name==localeNames[i]) - return LocaleConstant(i); - - return LOCALE_enUS; // including enGB case -} - diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h deleted file mode 100644 index 09d64acc795..00000000000 --- a/src/server/shared/Common.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef TRINITYCORE_COMMON_H -#define TRINITYCORE_COMMON_H - -#include "Define.h" - -#include <unordered_map> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <cmath> -#include <errno.h> -#include <signal.h> -#include <assert.h> - -#include <set> -#include <list> -#include <string> -#include <map> -#include <queue> -#include <sstream> -#include <algorithm> -#include <memory> - -#include "Debugging/Errors.h" - -#include "Threading/LockedQueue.h" - -#if PLATFORM == PLATFORM_WINDOWS -# include <ws2tcpip.h> - -# if defined(__INTEL_COMPILER) -# if !defined(BOOST_ASIO_HAS_MOVE) -# define BOOST_ASIO_HAS_MOVE -# endif // !defined(BOOST_ASIO_HAS_MOVE) -# endif // if defined(__INTEL_COMPILER) - -#else -# include <sys/types.h> -# include <sys/ioctl.h> -# include <sys/socket.h> -# include <netinet/in.h> -# include <unistd.h> -# include <netdb.h> -#endif - -#if COMPILER == COMPILER_MICROSOFT - -#include <float.h> - -#define snprintf _snprintf -#define atoll _atoi64 -#define vsnprintf _vsnprintf -#define llabs _abs64 - -#else - -#define stricmp strcasecmp -#define strnicmp strncasecmp - -#endif - -inline float finiteAlways(float f) { return std::isfinite(f) ? f : 0.0f; } - -inline unsigned long atoul(char const* str) { return strtoul(str, nullptr, 10); } -inline unsigned long long atoull(char const* str) { return strtoull(str, nullptr, 10); } - -#define STRINGIZE(a) #a - -enum TimeConstants -{ - MINUTE = 60, - HOUR = MINUTE*60, - DAY = HOUR*24, - WEEK = DAY*7, - MONTH = DAY*30, - YEAR = MONTH*12, - IN_MILLISECONDS = 1000 -}; - -enum AccountTypes -{ - SEC_PLAYER = 0, - SEC_MODERATOR = 1, - SEC_GAMEMASTER = 2, - SEC_ADMINISTRATOR = 3, - SEC_CONSOLE = 4 // must be always last in list, accounts must have less security level always also -}; - -enum LocaleConstant -{ - LOCALE_enUS = 0, - LOCALE_koKR = 1, - LOCALE_frFR = 2, - LOCALE_deDE = 3, - LOCALE_zhCN = 4, - LOCALE_zhTW = 5, - LOCALE_esES = 6, - LOCALE_esMX = 7, - LOCALE_ruRU = 8 -}; - -const uint8 TOTAL_LOCALES = 9; -#define DEFAULT_LOCALE LOCALE_enUS - -#define MAX_LOCALES 8 -#define MAX_ACCOUNT_TUTORIAL_VALUES 8 - -extern char const* localeNames[TOTAL_LOCALES]; - -LocaleConstant GetLocaleByName(const std::string& name); - -typedef std::vector<std::string> StringVector; - -// we always use stdlibc++ std::max/std::min, undefine some not C++ standard defines (Win API and some other platforms) -#ifdef max -#undef max -#endif - -#ifdef min -#undef min -#endif - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -#define MAX_QUERY_LEN 32*1024 - -namespace Trinity -{ - //! std::make_unique implementation (TODO: remove this once C++14 is supported) - template<typename T, typename ...Args> - std::unique_ptr<T> make_unique(Args&& ...args) - { - return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); - } -} - -#endif diff --git a/src/server/shared/CompilerDefs.h b/src/server/shared/CompilerDefs.h deleted file mode 100644 index c7867be517b..00000000000 --- a/src/server/shared/CompilerDefs.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef TRINITY_COMPILERDEFS_H -#define TRINITY_COMPILERDEFS_H - -#define PLATFORM_WINDOWS 0 -#define PLATFORM_UNIX 1 -#define PLATFORM_APPLE 2 -#define PLATFORM_INTEL 3 - -// must be first (win 64 also define _WIN32) -#if defined( _WIN64 ) -# define PLATFORM PLATFORM_WINDOWS -#elif defined( __WIN32__ ) || defined( WIN32 ) || defined( _WIN32 ) -# define PLATFORM PLATFORM_WINDOWS -#elif defined( __APPLE_CC__ ) -# define PLATFORM PLATFORM_APPLE -#elif defined( __INTEL_COMPILER ) -# define PLATFORM PLATFORM_INTEL -#else -# define PLATFORM PLATFORM_UNIX -#endif - -#define COMPILER_MICROSOFT 0 -#define COMPILER_GNU 1 -#define COMPILER_BORLAND 2 -#define COMPILER_INTEL 3 - -#ifdef _MSC_VER -# define COMPILER COMPILER_MICROSOFT -#elif defined( __BORLANDC__ ) -# define COMPILER COMPILER_BORLAND -#elif defined( __INTEL_COMPILER ) -# define COMPILER COMPILER_INTEL -#elif defined( __GNUC__ ) -# define COMPILER COMPILER_GNU -# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#else -# error "FATAL ERROR: Unknown compiler." -#endif - -#endif diff --git a/src/server/shared/Configuration/Config.cpp b/src/server/shared/Configuration/Config.cpp deleted file mode 100644 index ea426a5d33e..00000000000 --- a/src/server/shared/Configuration/Config.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include <algorithm> -#include <mutex> -#include <boost/property_tree/ptree.hpp> -#include <boost/property_tree/ini_parser.hpp> -#include "Config.h" - -using namespace boost::property_tree; - -bool ConfigMgr::LoadInitial(std::string const& file, std::string& error) -{ - std::lock_guard<std::mutex> lock(_configLock); - - _filename = file; - - try - { - ptree fullTree; - ini_parser::read_ini(file, fullTree); - - if (fullTree.empty()) - { - error = "empty file (" + file + ")"; - return false; - } - - // Since we're using only one section per config file, we skip the section and have direct property access - _config = fullTree.begin()->second; - } - catch (ini_parser::ini_parser_error const& e) - { - if (e.line() == 0) - error = e.message() + " (" + e.filename() + ")"; - else - error = e.message() + " (" + e.filename() + ":" + std::to_string(e.line()) + ")"; - return false; - } - - return true; -} - -bool ConfigMgr::Reload(std::string& error) -{ - return LoadInitial(_filename, error); -} - -std::string ConfigMgr::GetStringDefault(std::string const& name, const std::string& def) -{ - std::string value = _config.get<std::string>(ptree::path_type(name, '/'), def); - - value.erase(std::remove(value.begin(), value.end(), '"'), value.end()); - - return value; -} - -bool ConfigMgr::GetBoolDefault(std::string const& name, bool def) -{ - try - { - std::string val = _config.get<std::string>(ptree::path_type(name, '/')); - val.erase(std::remove(val.begin(), val.end(), '"'), val.end()); - return (val == "true" || val == "TRUE" || val == "yes" || val == "YES" || val == "1"); - } - catch (std::exception const& /*ex*/) - { - return def; - } -} - -int ConfigMgr::GetIntDefault(std::string const& name, int def) -{ - return _config.get<int>(ptree::path_type(name, '/'), def); -} - -float ConfigMgr::GetFloatDefault(std::string const& name, float def) -{ - return _config.get<float>(ptree::path_type(name, '/'), def); -} - -std::string const& ConfigMgr::GetFilename() -{ - std::lock_guard<std::mutex> lock(_configLock); - return _filename; -} - -std::list<std::string> ConfigMgr::GetKeysByString(std::string const& name) -{ - std::lock_guard<std::mutex> lock(_configLock); - - std::list<std::string> keys; - - for (const ptree::value_type& child : _config) - if (child.first.compare(0, name.length(), name) == 0) - keys.push_back(child.first); - - return keys; -} diff --git a/src/server/shared/Configuration/Config.h b/src/server/shared/Configuration/Config.h deleted file mode 100644 index 5fb7cef9241..00000000000 --- a/src/server/shared/Configuration/Config.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef CONFIG_H -#define CONFIG_H - -#include <string> -#include <list> -#include <mutex> -#include <boost/property_tree/ptree.hpp> - -class ConfigMgr -{ - ConfigMgr() { } - ~ConfigMgr() { } - -public: - /// Method used only for loading main configuration files (authserver.conf and worldserver.conf) - bool LoadInitial(std::string const& file, std::string& error); - - static ConfigMgr* instance() - { - static ConfigMgr instance; - return &instance; - } - - bool Reload(std::string& error); - - std::string GetStringDefault(std::string const& name, const std::string& def); - bool GetBoolDefault(std::string const& name, bool def); - int GetIntDefault(std::string const& name, int def); - float GetFloatDefault(std::string const& name, float def); - - std::string const& GetFilename(); - std::list<std::string> GetKeysByString(std::string const& name); - -private: - std::string _filename; - boost::property_tree::ptree _config; - std::mutex _configLock; - - ConfigMgr(ConfigMgr const&); - ConfigMgr& operator=(ConfigMgr const&); -}; - -#define sConfigMgr ConfigMgr::instance() - -#endif diff --git a/src/server/shared/Database/AdhocStatement.cpp b/src/server/shared/Database/AdhocStatement.cpp deleted file mode 100644 index 547ff967efe..00000000000 --- a/src/server/shared/Database/AdhocStatement.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "AdhocStatement.h" -#include "MySQLConnection.h" - -/*! Basic, ad-hoc queries. */ -BasicStatementTask::BasicStatementTask(const char* sql, bool async) : -m_result(nullptr) -{ - m_sql = strdup(sql); - m_has_result = async; // If the operation is async, then there's a result - if (async) - m_result = new QueryResultPromise(); -} - -BasicStatementTask::~BasicStatementTask() -{ - free((void*)m_sql); - if (m_has_result && m_result != nullptr) - delete m_result; -} - -bool BasicStatementTask::Execute() -{ - if (m_has_result) - { - ResultSet* result = m_conn->Query(m_sql); - if (!result || !result->GetRowCount() || !result->NextRow()) - { - delete result; - m_result->set_value(QueryResult(NULL)); - return false; - } - - m_result->set_value(QueryResult(result)); - return true; - } - - return m_conn->Execute(m_sql); -} diff --git a/src/server/shared/Database/AdhocStatement.h b/src/server/shared/Database/AdhocStatement.h deleted file mode 100644 index c449e0f6e59..00000000000 --- a/src/server/shared/Database/AdhocStatement.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _ADHOCSTATEMENT_H -#define _ADHOCSTATEMENT_H - -#include <future> -#include "SQLOperation.h" - -typedef std::future<QueryResult> QueryResultFuture; -typedef std::promise<QueryResult> QueryResultPromise; - -/*! Raw, ad-hoc query. */ -class BasicStatementTask : public SQLOperation -{ - public: - BasicStatementTask(const char* sql, bool async = false); - ~BasicStatementTask(); - - bool Execute() override; - QueryResultFuture GetFuture() const { return m_result->get_future(); } - - private: - const char* m_sql; //- Raw query to be executed - bool m_has_result; - QueryResultPromise* m_result; -}; - -#endif diff --git a/src/server/shared/Database/DatabaseEnv.h b/src/server/shared/Database/DatabaseEnv.h deleted file mode 100644 index c3e11c5b98e..00000000000 --- a/src/server/shared/Database/DatabaseEnv.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef DATABASEENV_H -#define DATABASEENV_H - -#include "Common.h" -#include "Errors.h" -#include "Log.h" - -#include "Field.h" -#include "QueryResult.h" - -#include "MySQLThreading.h" -#include "Transaction.h" - -#define _LIKE_ "LIKE" -#define _TABLE_SIM_ "`" -#define _CONCAT3_(A, B, C) "CONCAT( " A ", " B ", " C " )" -#define _OFFSET_ "LIMIT %d, 1" - -#include "Implementation/LoginDatabase.h" -#include "Implementation/CharacterDatabase.h" -#include "Implementation/WorldDatabase.h" - -extern WorldDatabaseWorkerPool WorldDatabase; -extern CharacterDatabaseWorkerPool CharacterDatabase; -extern LoginDatabaseWorkerPool LoginDatabase; - -#endif - diff --git a/src/server/shared/Database/DatabaseLoader.cpp b/src/server/shared/Database/DatabaseLoader.cpp deleted file mode 100644 index a3e2083fff4..00000000000 --- a/src/server/shared/Database/DatabaseLoader.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "DatabaseLoader.h" -#include "DBUpdater.h" -#include "Config.h" - -#include <mysqld_error.h> - -DatabaseLoader::DatabaseLoader(std::string const& logger, uint32 const defaultUpdateMask) - : _logger(logger), _autoSetup(sConfigMgr->GetBoolDefault("Updates.AutoSetup", true)), - _updateFlags(sConfigMgr->GetIntDefault("Updates.EnableDatabases", defaultUpdateMask)) -{ -} - -template <class T> -DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool<T>& pool, std::string const& name) -{ - bool const updatesEnabledForThis = DBUpdater<T>::IsEnabled(_updateFlags); - - _open.push(std::make_pair([this, name, updatesEnabledForThis, &pool]() -> bool - { - std::string const dbString = sConfigMgr->GetStringDefault(name + "DatabaseInfo", ""); - if (dbString.empty()) - { - TC_LOG_ERROR(_logger.c_str(), "Database %s not specified in configuration file!", name.c_str()); - return false; - } - - uint8 const asyncThreads = uint8(sConfigMgr->GetIntDefault(name + "Database.WorkerThreads", 1)); - if (asyncThreads < 1 || asyncThreads > 32) - { - TC_LOG_ERROR(_logger.c_str(), "%s database: invalid number of worker threads specified. " - "Please pick a value between 1 and 32.", name.c_str()); - return false; - } - - uint8 const synchThreads = uint8(sConfigMgr->GetIntDefault(name + "Database.SynchThreads", 1)); - - pool.SetConnectionInfo(dbString, asyncThreads, synchThreads); - if (uint32 error = pool.Open()) - { - // Database does not exist - if ((error == ER_BAD_DB_ERROR) && updatesEnabledForThis && _autoSetup) - { - // Try to create the database and connect again if auto setup is enabled - if (DBUpdater<T>::Create(pool) && (!pool.Open())) - error = 0; - } - - // If the error wasn't handled quit - if (error) - { - TC_LOG_ERROR("sql.driver", "\nDatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile " - "for specific errors. Read wiki at http://collab.kpsn.org/display/tc/TrinityCore+Home", name.c_str()); - - return false; - } - } - return true; - }, - [&pool]() - { - pool.Close(); - })); - - // Populate and update only if updates are enabled for this pool - if (updatesEnabledForThis) - { - _populate.push([this, name, &pool]() -> bool - { - if (!DBUpdater<T>::Populate(pool)) - { - TC_LOG_ERROR(_logger.c_str(), "Could not populate the %s database, see log for details.", name.c_str()); - return false; - } - return true; - }); - - _update.push([this, name, &pool]() -> bool - { - if (!DBUpdater<T>::Update(pool)) - { - TC_LOG_ERROR(_logger.c_str(), "Could not update the %s database, see log for details.", name.c_str()); - return false; - } - return true; - }); - } - - _prepare.push([this, name, &pool]() -> bool - { - if (!pool.PrepareStatements()) - { - TC_LOG_ERROR(_logger.c_str(), "Could not prepare statements of the %s database, see log for details.", name.c_str()); - return false; - } - return true; - }); - - return *this; -} - -bool DatabaseLoader::Load() -{ - if (!_updateFlags) - TC_LOG_INFO("sql.updates", "Automatic database updates are disabled for all databases!"); - - if (!OpenDatabases()) - return false; - - if (!PopulateDatabases()) - return false; - - if (!UpdateDatabases()) - return false; - - if (!PrepareStatements()) - return false; - - return true; -} - -bool DatabaseLoader::OpenDatabases() -{ - while (!_open.empty()) - { - std::pair<Predicate, std::function<void()>> const load = _open.top(); - if (load.first()) - _close.push(load.second); - else - { - // Close all loaded databases - while (!_close.empty()) - { - _close.top()(); - _close.pop(); - } - return false; - } - - _open.pop(); - } - return true; -} - -// Processes the elements of the given stack until a predicate returned false. -bool DatabaseLoader::Process(std::stack<Predicate>& stack) -{ - while (!stack.empty()) - { - if (!stack.top()()) - return false; - - stack.pop(); - } - return true; -} - -bool DatabaseLoader::PopulateDatabases() -{ - return Process(_populate); -} - -bool DatabaseLoader::UpdateDatabases() -{ - return Process(_update); -} - -bool DatabaseLoader::PrepareStatements() -{ - return Process(_prepare); -} - -template -DatabaseLoader& DatabaseLoader::AddDatabase<LoginDatabaseConnection>(DatabaseWorkerPool<LoginDatabaseConnection>& pool, std::string const& name); -template -DatabaseLoader& DatabaseLoader::AddDatabase<WorldDatabaseConnection>(DatabaseWorkerPool<WorldDatabaseConnection>& pool, std::string const& name); -template -DatabaseLoader& DatabaseLoader::AddDatabase<CharacterDatabaseConnection>(DatabaseWorkerPool<CharacterDatabaseConnection>& pool, std::string const& name); diff --git a/src/server/shared/Database/DatabaseLoader.h b/src/server/shared/Database/DatabaseLoader.h deleted file mode 100644 index d35597ba807..00000000000 --- a/src/server/shared/Database/DatabaseLoader.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef DatabaseLoader_h__ -#define DatabaseLoader_h__ - -#include "DatabaseWorkerPool.h" -#include "DatabaseEnv.h" - -#include <stack> -#include <functional> - -// A helper class to initiate all database worker pools, -// handles updating, delays preparing of statements and cleans up on failure. -class DatabaseLoader -{ -public: - DatabaseLoader(std::string const& logger, uint32 const defaultUpdateMask); - - // Register a database to the loader (lazy implemented) - template <class T> - DatabaseLoader& AddDatabase(DatabaseWorkerPool<T>& pool, std::string const& name); - - // Load all databases - bool Load(); - - enum DatabaseTypeFlags - { - DATABASE_NONE = 0, - - DATABASE_LOGIN = 1, - DATABASE_CHARACTER = 2, - DATABASE_WORLD = 4, - - DATABASE_MASK_ALL = DATABASE_LOGIN | DATABASE_CHARACTER | DATABASE_WORLD - }; - -private: - bool OpenDatabases(); - bool PopulateDatabases(); - bool UpdateDatabases(); - bool PrepareStatements(); - - using Predicate = std::function<bool()>; - - static bool Process(std::stack<Predicate>& stack); - - std::string const _logger; - bool const _autoSetup; - uint32 const _updateFlags; - - std::stack<std::pair<Predicate, std::function<void()>>> _open; - std::stack<std::function<void()>> _close; - std::stack<Predicate> _populate, _update, _prepare; -}; - -#endif // DatabaseLoader_h__ diff --git a/src/server/shared/Database/DatabaseWorker.cpp b/src/server/shared/Database/DatabaseWorker.cpp deleted file mode 100644 index 56757ce12a0..00000000000 --- a/src/server/shared/Database/DatabaseWorker.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "DatabaseEnv.h" -#include "DatabaseWorker.h" -#include "SQLOperation.h" -#include "ProducerConsumerQueue.h" - -DatabaseWorker::DatabaseWorker(ProducerConsumerQueue<SQLOperation*>* newQueue, MySQLConnection* connection) -{ - _connection = connection; - _queue = newQueue; - _cancelationToken = false; - _workerThread = std::thread(&DatabaseWorker::WorkerThread, this); -} - -DatabaseWorker::~DatabaseWorker() -{ - _cancelationToken = true; - - _queue->Cancel(); - - _workerThread.join(); -} - -void DatabaseWorker::WorkerThread() -{ - if (!_queue) - return; - - for (;;) - { - SQLOperation* operation = nullptr; - - _queue->WaitAndPop(operation); - - if (_cancelationToken || !operation) - return; - - operation->SetConnection(_connection); - operation->call(); - - delete operation; - } -} diff --git a/src/server/shared/Database/DatabaseWorker.h b/src/server/shared/Database/DatabaseWorker.h deleted file mode 100644 index 0ca476b1e66..00000000000 --- a/src/server/shared/Database/DatabaseWorker.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _WORKERTHREAD_H -#define _WORKERTHREAD_H - -#include <thread> -#include "ProducerConsumerQueue.h" - -class MySQLConnection; -class SQLOperation; - -class DatabaseWorker -{ - public: - DatabaseWorker(ProducerConsumerQueue<SQLOperation*>* newQueue, MySQLConnection* connection); - ~DatabaseWorker(); - - private: - ProducerConsumerQueue<SQLOperation*>* _queue; - MySQLConnection* _connection; - - void WorkerThread(); - std::thread _workerThread; - - std::atomic_bool _cancelationToken; - - DatabaseWorker(DatabaseWorker const& right) = delete; - DatabaseWorker& operator=(DatabaseWorker const& right) = delete; -}; - -#endif diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h deleted file mode 100644 index f5002c6943b..00000000000 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ /dev/null @@ -1,564 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _DATABASEWORKERPOOL_H -#define _DATABASEWORKERPOOL_H - -#include "Common.h" -#include "Callback.h" -#include "MySQLConnection.h" -#include "Transaction.h" -#include "DatabaseWorker.h" -#include "PreparedStatement.h" -#include "Log.h" -#include "QueryResult.h" -#include "QueryHolder.h" -#include "AdhocStatement.h" -#include "StringFormat.h" - -#include <mysqld_error.h> -#include <memory> - -#define MIN_MYSQL_SERVER_VERSION 50100u -#define MIN_MYSQL_CLIENT_VERSION 50100u - -class PingOperation : public SQLOperation -{ - //! Operation for idle delaythreads - bool Execute() override - { - m_conn->Ping(); - return true; - } -}; - -template <class T> -class DatabaseWorkerPool -{ - private: - enum InternalIndex - { - IDX_ASYNC, - IDX_SYNCH, - IDX_SIZE - }; - - public: - /* Activity state */ - DatabaseWorkerPool() : _queue(new ProducerConsumerQueue<SQLOperation*>()), - _async_threads(0), _synch_threads(0) - { - memset(_connectionCount, 0, sizeof(_connectionCount)); - _connections.resize(IDX_SIZE); - - WPFatal(mysql_thread_safe(), "Used MySQL library isn't thread-safe."); - WPFatal(mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION, "TrinityCore does not support MySQL versions below 5.1"); - } - - ~DatabaseWorkerPool() - { - _queue->Cancel(); - } - - void SetConnectionInfo(std::string const& infoString, uint8 const asyncThreads, uint8 const synchThreads) - { - _connectionInfo.reset(new MySQLConnectionInfo(infoString)); - - _async_threads = asyncThreads; - _synch_threads = synchThreads; - } - - uint32 Open() - { - WPFatal(_connectionInfo.get(), "Connection info was not set!"); - - TC_LOG_INFO("sql.driver", "Opening DatabasePool '%s'. Asynchronous connections: %u, synchronous connections: %u.", - GetDatabaseName(), _async_threads, _synch_threads); - - uint32 error = OpenConnections(IDX_ASYNC, _async_threads); - - if (error) - return error; - - error = OpenConnections(IDX_SYNCH, _synch_threads); - - if (!error) - { - TC_LOG_INFO("sql.driver", "DatabasePool '%s' opened successfully. %u total connections running.", GetDatabaseName(), - (_connectionCount[IDX_SYNCH] + _connectionCount[IDX_ASYNC])); - } - - return error; - } - - void Close() - { - TC_LOG_INFO("sql.driver", "Closing down DatabasePool '%s'.", GetDatabaseName()); - - for (uint8 i = 0; i < _connectionCount[IDX_ASYNC]; ++i) - { - T* t = _connections[IDX_ASYNC][i]; - t->Close(); //! Closes the actualy MySQL connection. - } - - TC_LOG_INFO("sql.driver", "Asynchronous connections on DatabasePool '%s' terminated. Proceeding with synchronous connections.", - GetDatabaseName()); - - //! Shut down the synchronous connections - //! There's no need for locking the connection, because DatabaseWorkerPool<>::Close - //! should only be called after any other thread tasks in the core have exited, - //! meaning there can be no concurrent access at this point. - for (uint8 i = 0; i < _connectionCount[IDX_SYNCH]; ++i) - _connections[IDX_SYNCH][i]->Close(); - - TC_LOG_INFO("sql.driver", "All connections on DatabasePool '%s' closed.", GetDatabaseName()); - } - - //! Prepares all prepared statements - bool PrepareStatements() - { - for (uint8 i = 0; i < IDX_SIZE; ++i) - for (uint32 c = 0; c < _connectionCount[i]; ++c) - { - T* t = _connections[i][c]; - t->LockIfReady(); - if (!t->PrepareStatements()) - { - t->Unlock(); - Close(); - return false; - } - else - t->Unlock(); - } - - return true; - } - - inline MySQLConnectionInfo const* GetConnectionInfo() const - { - return _connectionInfo.get(); - } - - /** - Delayed one-way statement methods. - */ - - //! Enqueues a one-way SQL operation in string format that will be executed asynchronously. - //! This method should only be used for queries that are only executed once, e.g during startup. - void Execute(const char* sql) - { - if (Trinity::IsFormatEmptyOrNull(sql)) - return; - - BasicStatementTask* task = new BasicStatementTask(sql); - Enqueue(task); - } - - //! Enqueues a one-way SQL operation in string format -with variable args- that will be executed asynchronously. - //! This method should only be used for queries that are only executed once, e.g during startup. - template<typename Format, typename... Args> - void PExecute(Format&& sql, Args&&... args) - { - if (Trinity::IsFormatEmptyOrNull(sql)) - return; - - Execute(Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str()); - } - - //! Enqueues a one-way SQL operation in prepared statement format that will be executed asynchronously. - //! Statement must be prepared with CONNECTION_ASYNC flag. - void Execute(PreparedStatement* stmt) - { - PreparedStatementTask* task = new PreparedStatementTask(stmt); - Enqueue(task); - } - - /** - Direct synchronous one-way statement methods. - */ - - //! Directly executes a one-way SQL operation in string format, that will block the calling thread until finished. - //! This method should only be used for queries that are only executed once, e.g during startup. - void DirectExecute(const char* sql) - { - if (!sql) - return; - - T* t = GetFreeConnection(); - t->Execute(sql); - t->Unlock(); - } - - //! Directly executes a one-way SQL operation in string format -with variable args-, that will block the calling thread until finished. - //! This method should only be used for queries that are only executed once, e.g during startup. - template<typename Format, typename... Args> - void DirectPExecute(Format&& sql, Args&&... args) - { - if (Trinity::IsFormatEmptyOrNull(sql)) - return; - - DirectExecute(Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str()); - } - - //! Directly executes a one-way SQL operation in prepared statement format, that will block the calling thread until finished. - //! Statement must be prepared with the CONNECTION_SYNCH flag. - void DirectExecute(PreparedStatement* stmt) - { - T* t = GetFreeConnection(); - t->Execute(stmt); - t->Unlock(); - - //! Delete proxy-class. Not needed anymore - delete stmt; - } - - /** - Synchronous query (with resultset) methods. - */ - - //! Directly executes an SQL query in string format that will block the calling thread until finished. - //! Returns reference counted auto pointer, no need for manual memory management in upper level code. - QueryResult Query(const char* sql, T* conn = nullptr) - { - if (!conn) - conn = GetFreeConnection(); - - ResultSet* result = conn->Query(sql); - conn->Unlock(); - if (!result || !result->GetRowCount() || !result->NextRow()) - { - delete result; - return QueryResult(NULL); - } - - return QueryResult(result); - } - - //! Directly executes an SQL query in string format -with variable args- that will block the calling thread until finished. - //! Returns reference counted auto pointer, no need for manual memory management in upper level code. - template<typename Format, typename... Args> - QueryResult PQuery(Format&& sql, T* conn, Args&&... args) - { - if (Trinity::IsFormatEmptyOrNull(sql)) - return QueryResult(nullptr); - - return Query(Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str(), conn); - } - - //! Directly executes an SQL query in string format -with variable args- that will block the calling thread until finished. - //! Returns reference counted auto pointer, no need for manual memory management in upper level code. - template<typename Format, typename... Args> - QueryResult PQuery(Format&& sql, Args&&... args) - { - if (!sql) - return QueryResult(nullptr); - - return Query(Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str()); - } - - //! Directly executes an SQL query in prepared format that will block the calling thread until finished. - //! Returns reference counted auto pointer, no need for manual memory management in upper level code. - //! Statement must be prepared with CONNECTION_SYNCH flag. - PreparedQueryResult Query(PreparedStatement* stmt) - { - T* t = GetFreeConnection(); - PreparedResultSet* ret = t->Query(stmt); - t->Unlock(); - - //! Delete proxy-class. Not needed anymore - delete stmt; - - if (!ret || !ret->GetRowCount()) - { - delete ret; - return PreparedQueryResult(NULL); - } - - return PreparedQueryResult(ret); - } - - /** - Asynchronous query (with resultset) methods. - */ - - //! Enqueues a query in string format that will set the value of the QueryResultFuture return object as soon as the query is executed. - //! The return value is then processed in ProcessQueryCallback methods. - QueryResultFuture AsyncQuery(const char* sql) - { - BasicStatementTask* task = new BasicStatementTask(sql, true); - // Store future result before enqueueing - task might get already processed and deleted before returning from this method - QueryResultFuture result = task->GetFuture(); - Enqueue(task); - return result; - } - - //! Enqueues a query in string format -with variable args- that will set the value of the QueryResultFuture return object as soon as the query is executed. - //! The return value is then processed in ProcessQueryCallback methods. - template<typename Format, typename... Args> - QueryResultFuture AsyncPQuery(Format&& sql, Args&&... args) - { - return AsyncQuery(Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str()); - } - - //! Enqueues a query in prepared format that will set the value of the PreparedQueryResultFuture return object as soon as the query is executed. - //! The return value is then processed in ProcessQueryCallback methods. - //! Statement must be prepared with CONNECTION_ASYNC flag. - PreparedQueryResultFuture AsyncQuery(PreparedStatement* stmt) - { - PreparedStatementTask* task = new PreparedStatementTask(stmt, true); - // Store future result before enqueueing - task might get already processed and deleted before returning from this method - PreparedQueryResultFuture result = task->GetFuture(); - Enqueue(task); - return result; - } - - //! Enqueues a vector of SQL operations (can be both adhoc and prepared) that will set the value of the QueryResultHolderFuture - //! return object as soon as the query is executed. - //! The return value is then processed in ProcessQueryCallback methods. - //! Any prepared statements added to this holder need to be prepared with the CONNECTION_ASYNC flag. - QueryResultHolderFuture DelayQueryHolder(SQLQueryHolder* holder) - { - SQLQueryHolderTask* task = new SQLQueryHolderTask(holder); - // Store future result before enqueueing - task might get already processed and deleted before returning from this method - QueryResultHolderFuture result = task->GetFuture(); - Enqueue(task); - return result; - } - - /** - Transaction context methods. - */ - - //! Begins an automanaged transaction pointer that will automatically rollback if not commited. (Autocommit=0) - SQLTransaction BeginTransaction() - { - return SQLTransaction(new Transaction); - } - - //! Enqueues a collection of one-way SQL operations (can be both adhoc and prepared). The order in which these operations - //! were appended to the transaction will be respected during execution. - void CommitTransaction(SQLTransaction transaction) - { - #ifdef TRINITY_DEBUG - //! Only analyze transaction weaknesses in Debug mode. - //! Ideally we catch the faults in Debug mode and then correct them, - //! so there's no need to waste these CPU cycles in Release mode. - switch (transaction->GetSize()) - { - case 0: - TC_LOG_DEBUG("sql.driver", "Transaction contains 0 queries. Not executing."); - return; - case 1: - TC_LOG_DEBUG("sql.driver", "Warning: Transaction only holds 1 query, consider removing Transaction context in code."); - break; - default: - break; - } - #endif // TRINITY_DEBUG - - Enqueue(new TransactionTask(transaction)); - } - - //! Directly executes a collection of one-way SQL operations (can be both adhoc and prepared). The order in which these operations - //! were appended to the transaction will be respected during execution. - void DirectCommitTransaction(SQLTransaction& transaction) - { - T* con = GetFreeConnection(); - int errorCode = con->ExecuteTransaction(transaction); - if (!errorCode) - { - con->Unlock(); // OK, operation succesful - return; - } - - //! Handle MySQL Errno 1213 without extending deadlock to the core itself - /// @todo More elegant way - if (errorCode == ER_LOCK_DEADLOCK) - { - uint8 loopBreaker = 5; - for (uint8 i = 0; i < loopBreaker; ++i) - { - if (!con->ExecuteTransaction(transaction)) - break; - } - } - - //! Clean up now. - transaction->Cleanup(); - - con->Unlock(); - } - - //! Method used to execute prepared statements in a diverse context. - //! Will be wrapped in a transaction if valid object is present, otherwise executed standalone. - void ExecuteOrAppend(SQLTransaction& trans, PreparedStatement* stmt) - { - if (!trans) - Execute(stmt); - else - trans->Append(stmt); - } - - //! Method used to execute ad-hoc statements in a diverse context. - //! Will be wrapped in a transaction if valid object is present, otherwise executed standalone. - void ExecuteOrAppend(SQLTransaction& trans, const char* sql) - { - if (!trans) - Execute(sql); - else - trans->Append(sql); - } - - /** - Other - */ - - //! Automanaged (internally) pointer to a prepared statement object for usage in upper level code. - //! Pointer is deleted in this->DirectExecute(PreparedStatement*), this->Query(PreparedStatement*) or PreparedStatementTask::~PreparedStatementTask. - //! This object is not tied to the prepared statement on the MySQL context yet until execution. - PreparedStatement* GetPreparedStatement(uint32 index) - { - return new PreparedStatement(index); - } - - //! Apply escape string'ing for current collation. (utf8) - void EscapeString(std::string& str) - { - if (str.empty()) - return; - - char* buf = new char[str.size() * 2 + 1]; - EscapeString(buf, str.c_str(), str.size()); - str = buf; - delete[] buf; - } - - //! Keeps all our MySQL connections alive, prevent the server from disconnecting us. - void KeepAlive() - { - //! Ping synchronous connections - for (uint8 i = 0; i < _connectionCount[IDX_SYNCH]; ++i) - { - T* t = _connections[IDX_SYNCH][i]; - if (t->LockIfReady()) - { - t->Ping(); - t->Unlock(); - } - } - - //! Assuming all worker threads are free, every worker thread will receive 1 ping operation request - //! If one or more worker threads are busy, the ping operations will not be split evenly, but this doesn't matter - //! as the sole purpose is to prevent connections from idling. - for (size_t i = 0; i < _connections[IDX_ASYNC].size(); ++i) - Enqueue(new PingOperation); - } - - private: - uint32 OpenConnections(InternalIndex type, uint8 numConnections) - { - _connections[type].resize(numConnections); - for (uint8 i = 0; i < numConnections; ++i) - { - T* t; - - if (type == IDX_ASYNC) - t = new T(_queue.get(), *_connectionInfo); - else if (type == IDX_SYNCH) - t = new T(*_connectionInfo); - else - ASSERT(false); - - _connections[type][i] = t; - ++_connectionCount[type]; - - uint32 error = t->Open(); - - if (!error) - { - if (mysql_get_server_version(t->GetHandle()) < MIN_MYSQL_SERVER_VERSION) - { - TC_LOG_ERROR("sql.driver", "TrinityCore does not support MySQL versions below 5.1"); - error = 1; - } - } - - // Failed to open a connection or invalid version, abort and cleanup - if (error) - { - while (_connectionCount[type] != 0) - { - t = _connections[type][i--]; - delete t; - --_connectionCount[type]; - } - return error; - } - } - - // Everything is fine - return 0; - } - - unsigned long EscapeString(char *to, const char *from, unsigned long length) - { - if (!to || !from || !length) - return 0; - - return mysql_real_escape_string(_connections[IDX_SYNCH][0]->GetHandle(), to, from, length); - } - - void Enqueue(SQLOperation* op) - { - _queue->Push(op); - } - - //! Gets a free connection in the synchronous connection pool. - //! Caller MUST call t->Unlock() after touching the MySQL context to prevent deadlocks. - T* GetFreeConnection() - { - uint8 i = 0; - size_t num_cons = _connectionCount[IDX_SYNCH]; - T* t = NULL; - //! Block forever until a connection is free - for (;;) - { - t = _connections[IDX_SYNCH][++i % num_cons]; - //! Must be matched with t->Unlock() or you will get deadlocks - if (t->LockIfReady()) - break; - } - - return t; - } - - char const* GetDatabaseName() const - { - return _connectionInfo->database.c_str(); - } - - //! Queue shared by async worker threads. - std::unique_ptr<ProducerConsumerQueue<SQLOperation*>> _queue; - std::vector<std::vector<T*>> _connections; - //! Counter of MySQL connections; - uint32 _connectionCount[IDX_SIZE]; - std::unique_ptr<MySQLConnectionInfo> _connectionInfo; - uint8 _async_threads, _synch_threads; -}; - -#endif diff --git a/src/server/shared/Database/Field.cpp b/src/server/shared/Database/Field.cpp deleted file mode 100644 index 89195b699b7..00000000000 --- a/src/server/shared/Database/Field.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "Field.h" - -Field::Field() -{ - data.value = NULL; - data.type = MYSQL_TYPE_NULL; - data.length = 0; - data.raw = false; -} - -Field::~Field() -{ - CleanUp(); -} - -void Field::SetByteValue(const void* newValue, const size_t newSize, enum_field_types newType, uint32 length) -{ - if (data.value) - CleanUp(); - - // This value stores raw bytes that have to be explicitly cast later - if (newValue) - { - data.value = new char[newSize]; - memcpy(data.value, newValue, newSize); - data.length = length; - } - data.type = newType; - data.raw = true; -} - -void Field::SetStructuredValue(char* newValue, enum_field_types newType) -{ - if (data.value) - CleanUp(); - - // This value stores somewhat structured data that needs function style casting - if (newValue) - { - size_t size = strlen(newValue); - data.value = new char [size+1]; - strcpy((char*)data.value, newValue); - data.length = size; - } - - data.type = newType; - data.raw = false; -} diff --git a/src/server/shared/Database/Field.h b/src/server/shared/Database/Field.h deleted file mode 100644 index 1bbd264482f..00000000000 --- a/src/server/shared/Database/Field.h +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _FIELD_H -#define _FIELD_H - -#include "Common.h" -#include "Log.h" - -#include <mysql.h> - -class Field -{ - friend class ResultSet; - friend class PreparedResultSet; - - public: - - bool GetBool() const // Wrapper, actually gets integer - { - return GetUInt8() == 1 ? true : false; - } - - uint8 GetUInt8() const - { - if (!data.value) - return 0; - - #ifdef TRINITY_DEBUG - if (!IsType(MYSQL_TYPE_TINY)) - { - TC_LOG_WARN("sql.sql", "Warning: GetUInt8() on non-tinyint field. Using type: %s.", FieldTypeToString(data.type)); - return 0; - } - #endif - - if (data.raw) - return *reinterpret_cast<uint8*>(data.value); - return static_cast<uint8>(strtoul((char*)data.value, nullptr, 10)); - } - - int8 GetInt8() const - { - if (!data.value) - return 0; - - #ifdef TRINITY_DEBUG - if (!IsType(MYSQL_TYPE_TINY)) - { - TC_LOG_WARN("sql.sql", "Warning: GetInt8() on non-tinyint field. Using type: %s.", FieldTypeToString(data.type)); - return 0; - } - #endif - - if (data.raw) - return *reinterpret_cast<int8*>(data.value); - return static_cast<int8>(strtol((char*)data.value, NULL, 10)); - } - - uint16 GetUInt16() const - { - if (!data.value) - return 0; - - #ifdef TRINITY_DEBUG - if (!IsType(MYSQL_TYPE_SHORT) && !IsType(MYSQL_TYPE_YEAR)) - { - TC_LOG_WARN("sql.sql", "Warning: GetUInt16() on non-smallint field. Using type: %s.", FieldTypeToString(data.type)); - return 0; - } - #endif - - if (data.raw) - return *reinterpret_cast<uint16*>(data.value); - return static_cast<uint16>(strtoul((char*)data.value, nullptr, 10)); - } - - int16 GetInt16() const - { - if (!data.value) - return 0; - - #ifdef TRINITY_DEBUG - if (!IsType(MYSQL_TYPE_SHORT) && !IsType(MYSQL_TYPE_YEAR)) - { - TC_LOG_WARN("sql.sql", "Warning: GetInt16() on non-smallint field. Using type: %s.", FieldTypeToString(data.type)); - return 0; - } - #endif - - if (data.raw) - return *reinterpret_cast<int16*>(data.value); - return static_cast<int16>(strtol((char*)data.value, NULL, 10)); - } - - uint32 GetUInt32() const - { - if (!data.value) - return 0; - - #ifdef TRINITY_DEBUG - if (!IsType(MYSQL_TYPE_INT24) && !IsType(MYSQL_TYPE_LONG)) - { - TC_LOG_WARN("sql.sql", "Warning: GetUInt32() on non-(medium)int field. Using type: %s.", FieldTypeToString(data.type)); - return 0; - } - #endif - - if (data.raw) - return *reinterpret_cast<uint32*>(data.value); - return static_cast<uint32>(strtoul((char*)data.value, nullptr, 10)); - } - - int32 GetInt32() const - { - if (!data.value) - return 0; - - #ifdef TRINITY_DEBUG - if (!IsType(MYSQL_TYPE_INT24) && !IsType(MYSQL_TYPE_LONG)) - { - TC_LOG_WARN("sql.sql", "Warning: GetInt32() on non-(medium)int field. Using type: %s.", FieldTypeToString(data.type)); - return 0; - } - #endif - - if (data.raw) - return *reinterpret_cast<int32*>(data.value); - return static_cast<int32>(strtol((char*)data.value, NULL, 10)); - } - - uint64 GetUInt64() const - { - if (!data.value) - return 0; - - #ifdef TRINITY_DEBUG - if (!IsType(MYSQL_TYPE_LONGLONG) && !IsType(MYSQL_TYPE_BIT)) - { - TC_LOG_WARN("sql.sql", "Warning: GetUInt64() on non-bigint field. Using type: %s.", FieldTypeToString(data.type)); - return 0; - } - #endif - - if (data.raw) - return *reinterpret_cast<uint64*>(data.value); - return static_cast<uint64>(strtoull((char*)data.value, nullptr, 10)); - } - - int64 GetInt64() const - { - if (!data.value) - return 0; - - #ifdef TRINITY_DEBUG - if (!IsType(MYSQL_TYPE_LONGLONG) && !IsType(MYSQL_TYPE_BIT)) - { - TC_LOG_WARN("sql.sql", "Warning: GetInt64() on non-bigint field. Using type: %s.", FieldTypeToString(data.type)); - return 0; - } - #endif - - if (data.raw) - return *reinterpret_cast<int64*>(data.value); - return static_cast<int64>(strtoll((char*)data.value, NULL, 10)); - } - - float GetFloat() const - { - if (!data.value) - return 0.0f; - - #ifdef TRINITY_DEBUG - if (!IsType(MYSQL_TYPE_FLOAT)) - { - TC_LOG_WARN("sql.sql", "Warning: GetFloat() on non-float field. Using type: %s.", FieldTypeToString(data.type)); - return 0.0f; - } - #endif - - if (data.raw) - return *reinterpret_cast<float*>(data.value); - return static_cast<float>(atof((char*)data.value)); - } - - double GetDouble() const - { - if (!data.value) - return 0.0f; - - #ifdef TRINITY_DEBUG - if (!IsType(MYSQL_TYPE_DOUBLE)) - { - TC_LOG_WARN("sql.sql", "Warning: GetDouble() on non-double field. Using type: %s.", FieldTypeToString(data.type)); - return 0.0f; - } - #endif - - if (data.raw) - return *reinterpret_cast<double*>(data.value); - return static_cast<double>(atof((char*)data.value)); - } - - char const* GetCString() const - { - if (!data.value) - return NULL; - - #ifdef TRINITY_DEBUG - if (IsNumeric()) - { - TC_LOG_WARN("sql.sql", "Error: GetCString() on numeric field. Using type: %s.", FieldTypeToString(data.type)); - return NULL; - } - #endif - return static_cast<char const*>(data.value); - - } - - std::string GetString() const - { - if (!data.value) - return ""; - - if (data.raw) - { - char const* string = GetCString(); - if (!string) - string = ""; - return std::string(string, data.length); - } - return std::string((char*)data.value); - } - - bool IsNull() const - { - return data.value == NULL; - } - - protected: - Field(); - ~Field(); - - #pragma pack(push, 1) - struct - { - uint32 length; // Length (prepared strings only) - void* value; // Actual data in memory - enum_field_types type; // Field type - bool raw; // Raw bytes? (Prepared statement or ad hoc) - } data; - #pragma pack(pop) - - void SetByteValue(void const* newValue, size_t const newSize, enum_field_types newType, uint32 length); - void SetStructuredValue(char* newValue, enum_field_types newType); - - void CleanUp() - { - delete[] ((char*)data.value); - data.value = NULL; - } - - static size_t SizeForType(MYSQL_FIELD* field) - { - switch (field->type) - { - case MYSQL_TYPE_NULL: - return 0; - case MYSQL_TYPE_TINY: - return 1; - case MYSQL_TYPE_YEAR: - case MYSQL_TYPE_SHORT: - return 2; - case MYSQL_TYPE_INT24: - case MYSQL_TYPE_LONG: - case MYSQL_TYPE_FLOAT: - return 4; - case MYSQL_TYPE_DOUBLE: - case MYSQL_TYPE_LONGLONG: - case MYSQL_TYPE_BIT: - return 8; - - case MYSQL_TYPE_TIMESTAMP: - case MYSQL_TYPE_DATE: - case MYSQL_TYPE_TIME: - case MYSQL_TYPE_DATETIME: - return sizeof(MYSQL_TIME); - - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_VAR_STRING: - return field->max_length + 1; - - case MYSQL_TYPE_DECIMAL: - case MYSQL_TYPE_NEWDECIMAL: - return 64; - - case MYSQL_TYPE_GEOMETRY: - /* - Following types are not sent over the wire: - MYSQL_TYPE_ENUM: - MYSQL_TYPE_SET: - */ - default: - TC_LOG_WARN("sql.sql", "SQL::SizeForType(): invalid field type %u", uint32(field->type)); - return 0; - } - } - - bool IsType(enum_field_types type) const - { - return data.type == type; - } - - bool IsNumeric() const - { - return (data.type == MYSQL_TYPE_TINY || - data.type == MYSQL_TYPE_SHORT || - data.type == MYSQL_TYPE_INT24 || - data.type == MYSQL_TYPE_LONG || - data.type == MYSQL_TYPE_FLOAT || - data.type == MYSQL_TYPE_DOUBLE || - data.type == MYSQL_TYPE_LONGLONG ); - } - - private: - #ifdef TRINITY_DEBUG - static char const* FieldTypeToString(enum_field_types type) - { - switch (type) - { - case MYSQL_TYPE_BIT: return "BIT"; - case MYSQL_TYPE_BLOB: return "BLOB"; - case MYSQL_TYPE_DATE: return "DATE"; - case MYSQL_TYPE_DATETIME: return "DATETIME"; - case MYSQL_TYPE_NEWDECIMAL: return "NEWDECIMAL"; - case MYSQL_TYPE_DECIMAL: return "DECIMAL"; - case MYSQL_TYPE_DOUBLE: return "DOUBLE"; - case MYSQL_TYPE_ENUM: return "ENUM"; - case MYSQL_TYPE_FLOAT: return "FLOAT"; - case MYSQL_TYPE_GEOMETRY: return "GEOMETRY"; - case MYSQL_TYPE_INT24: return "INT24"; - case MYSQL_TYPE_LONG: return "LONG"; - case MYSQL_TYPE_LONGLONG: return "LONGLONG"; - case MYSQL_TYPE_LONG_BLOB: return "LONG_BLOB"; - case MYSQL_TYPE_MEDIUM_BLOB: return "MEDIUM_BLOB"; - case MYSQL_TYPE_NEWDATE: return "NEWDATE"; - case MYSQL_TYPE_NULL: return "NULL"; - case MYSQL_TYPE_SET: return "SET"; - case MYSQL_TYPE_SHORT: return "SHORT"; - case MYSQL_TYPE_STRING: return "STRING"; - case MYSQL_TYPE_TIME: return "TIME"; - case MYSQL_TYPE_TIMESTAMP: return "TIMESTAMP"; - case MYSQL_TYPE_TINY: return "TINY"; - case MYSQL_TYPE_TINY_BLOB: return "TINY_BLOB"; - case MYSQL_TYPE_VAR_STRING: return "VAR_STRING"; - case MYSQL_TYPE_YEAR: return "YEAR"; - default: return "-Unknown-"; - } - } - #endif -}; - -#endif - diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp deleted file mode 100644 index 1efdb16804f..00000000000 --- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "CharacterDatabase.h" - -void CharacterDatabaseConnection::DoPrepareStatements() -{ - if (!m_reconnecting) - m_stmts.resize(MAX_CHARACTERDATABASE_STATEMENTS); - - PrepareStatement(CHAR_DEL_QUEST_POOL_SAVE, "DELETE FROM pool_quest_save WHERE pool_id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_QUEST_POOL_SAVE, "INSERT INTO pool_quest_save (pool_id, quest_id) VALUES (?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_NONEXISTENT_GUILD_BANK_ITEM, "DELETE FROM guild_bank_item WHERE guildid = ? AND TabId = ? AND SlotId = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_EXPIRED_BANS, "UPDATE character_banned SET active = 0 WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate <> bandate", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_GUID_BY_NAME, "SELECT guid FROM characters WHERE name = ?", CONNECTION_BOTH); - PrepareStatement(CHAR_SEL_CHECK_NAME, "SELECT 1 FROM characters WHERE name = ?", CONNECTION_BOTH); - PrepareStatement(CHAR_SEL_CHECK_GUID, "SELECT 1 FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_SUM_CHARS, "SELECT COUNT(guid) FROM characters WHERE account = ?", CONNECTION_BOTH); - PrepareStatement(CHAR_SEL_CHAR_CREATE_INFO, "SELECT level, race, class FROM characters WHERE account = ? LIMIT 0, ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHARACTER_BAN, "INSERT INTO character_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, ?, ?, 1)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHARACTER_BAN, "UPDATE character_banned SET active = 0 WHERE guid = ? AND active != 0", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHARACTER_BAN, "DELETE cb FROM character_banned cb INNER JOIN characters c ON c.guid = cb.guid WHERE c.account = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_BANINFO, "SELECT bandate, unbandate-bandate, active, unbandate, banreason, bannedby FROM character_banned WHERE guid = ? ORDER BY bandate ASC", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_GUID_BY_NAME_FILTER, "SELECT guid, name FROM characters WHERE name LIKE CONCAT('%%', ?, '%%')", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_BANINFO_LIST, "SELECT bandate, unbandate, bannedby, banreason FROM character_banned WHERE guid = ? ORDER BY unbandate", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_BANNED_NAME, "SELECT characters.name FROM characters, character_banned WHERE character_banned.guid = ? AND character_banned.guid = characters.guid", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_MAIL_LIST_COUNT, "SELECT COUNT(id) FROM mail WHERE receiver = ? ", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_MAIL_LIST_INFO, "SELECT id, sender, (SELECT name FROM characters WHERE guid = sender) AS sendername, receiver, (SELECT name FROM characters WHERE guid = receiver) AS receivername, " - "subject, deliver_time, expire_time, money, has_items FROM mail WHERE receiver = ? ", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_MAIL_LIST_ITEMS, "SELECT itemEntry,count FROM item_instance WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_ENUM, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.playerBytes, c.playerBytes2, c.level, c.zone, c.map, c.position_x, c.position_y, c.position_z, " - "gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, cb.guid " - "FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? LEFT JOIN guild_member AS gm ON c.guid = gm.guid " - "LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? AND c.deleteInfos_Name IS NULL ORDER BY c.guid", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_ENUM_DECLINED_NAME, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.playerBytes, c.playerBytes2, c.level, c.zone, c.map, " - "c.position_x, c.position_y, c.position_z, gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, " - "cb.guid, cd.genitive FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? " - "LEFT JOIN character_declinedname AS cd ON c.guid = cd.guid LEFT JOIN guild_member AS gm ON c.guid = gm.guid " - "LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? AND c.deleteInfos_Name IS NULL ORDER BY c.guid", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_FREE_NAME, "SELECT guid, name FROM characters WHERE guid = ? AND account = ? AND (at_login & ?) = ? AND NOT EXISTS (SELECT NULL FROM characters WHERE name = ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME, "SELECT guid, race, account FROM characters WHERE name = ?", CONNECTION_BOTH); - PrepareStatement(CHAR_SEL_CHAR_RACE, "SELECT race FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_LEVEL, "SELECT level FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_ZONE, "SELECT zone FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHARACTER_NAME_DATA, "SELECT race, class, gender, level FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_POSITION_XYZ, "SELECT map, position_x, position_y, position_z FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_POSITION, "SELECT position_x, position_y, position_z, orientation, map, taxi_path FROM characters WHERE guid = ?", CONNECTION_SYNCH); - - PrepareStatement(CHAR_DEL_BATTLEGROUND_RANDOM_ALL, "DELETE FROM character_battleground_random", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_BATTLEGROUND_RANDOM, "DELETE FROM character_battleground_random WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_BATTLEGROUND_RANDOM, "INSERT INTO character_battleground_random (guid) VALUES (?)", CONNECTION_ASYNC); - - PrepareStatement(CHAR_SEL_CHARACTER, "SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, " - "position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, " - "resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, " - "arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, " - "health, power1, power2, power3, power4, power5, power6, power7, instance_id, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels " - "FROM characters WHERE guid = ?", CONNECTION_ASYNC); - - PrepareStatement(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_BOTH); - PrepareStatement(CHAR_SEL_CHARACTER_INSTANCE, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_AURAS, "SELECT casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, " - "base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges FROM character_aura WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_SPELL, "SELECT spell, active, disabled FROM character_spell WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS, "SELECT quest, status, explored, timer, mobcount1, mobcount2, mobcount3, mobcount4, " - "itemcount1, itemcount2, itemcount3, itemcount4, playercount FROM character_queststatus WHERE guid = ? AND status <> 0", CONNECTION_ASYNC); - - PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_DAILY, "SELECT quest, time FROM character_queststatus_daily WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_WEEKLY, "SELECT quest FROM character_queststatus_weekly WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_MONTHLY, "SELECT quest FROM character_queststatus_monthly WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_SEASONAL, "SELECT quest, event FROM character_queststatus_seasonal WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_DAILY, "DELETE FROM character_queststatus_daily WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_WEEKLY, "DELETE FROM character_queststatus_weekly WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_MONTHLY, "DELETE FROM character_queststatus_monthly WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_SEASONAL, "DELETE FROM character_queststatus_seasonal WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHARACTER_QUESTSTATUS_DAILY, "INSERT INTO character_queststatus_daily (guid, quest, time) VALUES (?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHARACTER_QUESTSTATUS_WEEKLY, "INSERT INTO character_queststatus_weekly (guid, quest) VALUES (?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHARACTER_QUESTSTATUS_MONTHLY, "INSERT INTO character_queststatus_monthly (guid, quest) VALUES (?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHARACTER_QUESTSTATUS_SEASONAL, "INSERT INTO character_queststatus_seasonal (guid, quest, event) VALUES (?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_DAILY, "DELETE FROM character_queststatus_daily", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_WEEKLY, "DELETE FROM character_queststatus_weekly", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_MONTHLY, "DELETE FROM character_queststatus_monthly", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_SEASONAL_BY_EVENT, "DELETE FROM character_queststatus_seasonal WHERE event = ?", CONNECTION_ASYNC); - - PrepareStatement(CHAR_SEL_CHARACTER_REPUTATION, "SELECT faction, standing, flags FROM character_reputation WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_INVENTORY, "SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, bag, slot, " - "item, itemEntry FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ? ORDER BY bag, slot", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_ACTIONS, "SELECT a.button, a.action, a.type FROM character_action as a, characters as c WHERE a.guid = c.guid AND a.spec = c.activeTalentGroup AND a.guid = ? ORDER BY button", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_MAILCOUNT, "SELECT COUNT(id) FROM mail WHERE receiver = ? AND (checked & 1) = 0 AND deliver_time <= ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_MAILDATE, "SELECT MIN(deliver_time) FROM mail WHERE receiver = ? AND (checked & 1) = 0", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_MAIL_COUNT, "SELECT COUNT(*) FROM mail WHERE receiver = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHARACTER_SOCIALLIST, "SELECT friend, flags, note FROM character_social JOIN characters ON characters.guid = character_social.friend WHERE character_social.guid = ? AND deleteinfos_name IS NULL LIMIT 255", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_HOMEBIND, "SELECT mapId, zoneId, posX, posY, posZ FROM character_homebind WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_SPELLCOOLDOWNS, "SELECT spell, item, time FROM character_spell_cooldown WHERE guid = ? AND time > UNIX_TIMESTAMP()", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_DECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_GUILD_MEMBER, "SELECT guildid, rank FROM guild_member WHERE guid = ?", CONNECTION_BOTH); - PrepareStatement(CHAR_SEL_GUILD_MEMBER_EXTENDED, "SELECT g.guildid, g.name, gr.rname, gr.rid, gm.pnote, gm.offnote " - "FROM guild g JOIN guild_member gm ON g.guildid = gm.guildid " - "JOIN guild_rank gr ON g.guildid = gr.guildid AND gm.rank = gr.rid WHERE gm.guid = ?", CONNECTION_BOTH); - PrepareStatement(CHAR_SEL_CHARACTER_ACHIEVEMENTS, "SELECT achievement, date FROM character_achievement WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_CRITERIAPROGRESS, "SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_EQUIPMENTSETS, "SELECT setguid, setindex, name, iconname, ignore_mask, item0, item1, item2, item3, item4, item5, item6, item7, item8, " - "item9, item10, item11, item12, item13, item14, item15, item16, item17, item18 FROM character_equipmentsets WHERE guid = ? ORDER BY setindex", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_BGDATA, "SELECT instanceId, team, joinX, joinY, joinZ, joinO, joinMapId, taxiStart, taxiEnd, mountSpell FROM character_battleground_data WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_GLYPHS, "SELECT talentGroup, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6 FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_TALENTS, "SELECT spell, talentGroup FROM character_talent WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_SKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_RANDOMBG, "SELECT guid FROM character_battleground_random WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_BANNED, "SELECT guid FROM character_banned WHERE guid = ? AND active = 1", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUSREW, "SELECT quest FROM character_queststatus_rewarded WHERE guid = ? AND active = 1", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES, "SELECT instanceId, releaseTime FROM account_instance_times WHERE accountId = ?", CONNECTION_ASYNC); - - PrepareStatement(CHAR_SEL_CHARACTER_ACTIONS_SPEC, "SELECT button, action, type FROM character_action WHERE guid = ? AND spec = ? ORDER BY button", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_MAILITEMS, "SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, item_guid, itemEntry, owner_guid FROM mail_items mi JOIN item_instance ii ON mi.item_guid = ii.guid WHERE mail_id = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_AUCTION_ITEMS, "SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, itemguid, itemEntry FROM auctionhouse ah JOIN item_instance ii ON ah.itemguid = ii.guid", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_AUCTIONS, "SELECT id, auctioneerguid, itemguid, itemEntry, count, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid", CONNECTION_SYNCH); - PrepareStatement(CHAR_INS_AUCTION, "INSERT INTO auctionhouse (id, auctioneerguid, itemguid, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_AUCTION, "DELETE FROM auctionhouse WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_AUCTION_BID, "UPDATE auctionhouse SET buyguid = ?, lastbid = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_MAIL, "INSERT INTO mail(id, messageType, stationery, mailTemplateId, sender, receiver, subject, body, has_items, expire_time, deliver_time, money, cod, checked) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_MAIL_BY_ID, "DELETE FROM mail WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_MAIL_ITEM, "INSERT INTO mail_items(mail_id, item_guid, receiver) VALUES (?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_MAIL_ITEM, "DELETE FROM mail_items WHERE item_guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_INVALID_MAIL_ITEM, "DELETE FROM mail_items WHERE item_guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_EMPTY_EXPIRED_MAIL, "DELETE FROM mail WHERE expire_time < ? AND has_items = 0 AND body = ''", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_EXPIRED_MAIL, "SELECT id, messageType, sender, receiver, has_items, expire_time, cod, checked, mailTemplateId FROM mail WHERE expire_time < ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_EXPIRED_MAIL_ITEMS, "SELECT item_guid, itemEntry, mail_id FROM mail_items mi INNER JOIN item_instance ii ON ii.guid = mi.item_guid LEFT JOIN mail mm ON mi.mail_id = mm.id WHERE mm.id IS NOT NULL AND mm.expire_time < ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_UPD_MAIL_RETURNED, "UPDATE mail SET sender = ?, receiver = ?, expire_time = ?, deliver_time = ?, cod = 0, checked = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_MAIL_ITEM_RECEIVER, "UPDATE mail_items SET receiver = ? WHERE item_guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_ITEM_OWNER, "UPDATE item_instance SET owner_guid = ? WHERE guid = ?", CONNECTION_ASYNC); - - PrepareStatement(CHAR_SEL_ITEM_REFUNDS, "SELECT player_guid, paidMoney, paidExtendedCost FROM item_refund_instance WHERE item_guid = ? AND player_guid = ? LIMIT 1", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_ITEM_BOP_TRADE, "SELECT allowedPlayers FROM item_soulbound_trade_data WHERE itemGuid = ? LIMIT 1", CONNECTION_SYNCH); - PrepareStatement(CHAR_DEL_ITEM_BOP_TRADE, "DELETE FROM item_soulbound_trade_data WHERE itemGuid = ? LIMIT 1", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_ITEM_BOP_TRADE, "INSERT INTO item_soulbound_trade_data VALUES (?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_REP_INVENTORY_ITEM, "REPLACE INTO character_inventory (guid, bag, slot, item) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_REP_ITEM_INSTANCE, "REPLACE INTO item_instance (itemEntry, owner_guid, creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, guid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_ITEM_INSTANCE, "UPDATE item_instance SET itemEntry = ?, owner_guid = ?, creatorGuid = ?, giftCreatorGuid = ?, count = ?, duration = ?, charges = ?, flags = ?, enchantments = ?, randomPropertyId = ?, durability = ?, playedTime = ?, text = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_ITEM_INSTANCE_ON_LOAD, "UPDATE item_instance SET duration = ?, flags = ?, durability = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_ITEM_INSTANCE, "DELETE FROM item_instance WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_ITEM_INSTANCE_BY_OWNER, "DELETE FROM item_instance WHERE owner_guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_GIFT_OWNER, "UPDATE character_gifts SET guid = ? WHERE item_guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GIFT, "DELETE FROM character_gifts WHERE item_guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_GIFT_BY_ITEM, "SELECT entry, flags FROM character_gifts WHERE item_guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_ACCOUNT_BY_NAME, "SELECT account FROM characters WHERE name = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_ACCOUNT_BY_GUID, "SELECT account FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHARACTER_DATA_BY_GUID, "SELECT account, name, level FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_DEL_ACCOUNT_INSTANCE_LOCK_TIMES, "DELETE FROM account_instance_times WHERE accountId = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_ACCOUNT_INSTANCE_LOCK_TIMES, "INSERT INTO account_instance_times (accountId, instanceId, releaseTime) VALUES (?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_NAME_CLASS, "SELECT name, class FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHARACTER_NAME, "SELECT name FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_MATCH_MAKER_RATING, "SELECT matchMakerRating FROM character_arena_stats WHERE guid = ? AND slot = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHARACTER_COUNT, "SELECT account, COUNT(guid) FROM characters WHERE account = ? GROUP BY account", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_NAME, "UPDATE characters set name = ?, at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_NAME_BY_GUID, "UPDATE characters SET name = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_DECLINED_NAME, "DELETE FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC); - - // Guild handling - // 0: uint32, 1: string, 2: uint32, 3: string, 4: string, 5: uint64, 6-10: uint32, 11: uint64 - PrepareStatement(CHAR_INS_GUILD, "INSERT INTO guild (guildid, name, leaderguid, info, motd, createdate, EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor, BankMoney) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GUILD, "DELETE FROM guild WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32 - // 0: string, 1: uint32 - PrepareStatement(CHAR_UPD_GUILD_NAME, "UPDATE guild SET name = ? WHERE guildid = ?", CONNECTION_ASYNC); - // 0: uint32, 1: uint32, 2: uint8, 4: string, 5: string - PrepareStatement(CHAR_INS_GUILD_MEMBER, "INSERT INTO guild_member (guildid, guid, rank, pnote, offnote) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GUILD_MEMBER, "DELETE FROM guild_member WHERE guid = ?", CONNECTION_ASYNC); // 0: uint32 - PrepareStatement(CHAR_DEL_GUILD_MEMBERS, "DELETE FROM guild_member WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32 - // 0: uint32, 1: uint8, 3: string, 4: uint32, 5: uint32 - PrepareStatement(CHAR_INS_GUILD_RANK, "INSERT INTO guild_rank (guildid, rid, rname, rights, BankMoneyPerDay) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GUILD_RANKS, "DELETE FROM guild_rank WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32 - PrepareStatement(CHAR_DEL_GUILD_LOWEST_RANK, "DELETE FROM guild_rank WHERE guildid = ? AND rid >= ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8 - PrepareStatement(CHAR_INS_GUILD_BANK_TAB, "INSERT INTO guild_bank_tab (guildid, TabId) VALUES (?, ?)", CONNECTION_ASYNC); // 0: uint32, 1: uint8 - PrepareStatement(CHAR_DEL_GUILD_BANK_TAB, "DELETE FROM guild_bank_tab WHERE guildid = ? AND TabId = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8 - PrepareStatement(CHAR_DEL_GUILD_BANK_TABS, "DELETE FROM guild_bank_tab WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32 - // 0: uint32, 1: uint8, 2: uint8, 3: uint32, 4: uint32 - PrepareStatement(CHAR_INS_GUILD_BANK_ITEM, "INSERT INTO guild_bank_item (guildid, TabId, SlotId, item_guid) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GUILD_BANK_ITEM, "DELETE FROM guild_bank_item WHERE guildid = ? AND TabId = ? AND SlotId = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8, 2: uint8 - PrepareStatement(CHAR_DEL_GUILD_BANK_ITEMS, "DELETE FROM guild_bank_item WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32 - // 0: uint32, 1: uint8, 2: uint8, 3: uint8, 4: uint32 - PrepareStatement(CHAR_INS_GUILD_BANK_RIGHT, "INSERT INTO guild_bank_right (guildid, TabId, rid, gbright, SlotPerDay) VALUES (?, ?, ?, ?, ?) " - "ON DUPLICATE KEY UPDATE gbright = VALUES(gbright), SlotPerDay = VALUES(SlotPerDay)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GUILD_BANK_RIGHTS, "DELETE FROM guild_bank_right WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32 - PrepareStatement(CHAR_DEL_GUILD_BANK_RIGHTS_FOR_RANK, "DELETE FROM guild_bank_right WHERE guildid = ? AND rid = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8 - // 0-1: uint32, 2-3: uint8, 4-5: uint32, 6: uint16, 7: uint8, 8: uint64 - PrepareStatement(CHAR_INS_GUILD_BANK_EVENTLOG, "INSERT INTO guild_bank_eventlog (guildid, LogGuid, TabId, EventType, PlayerGuid, ItemOrMoney, ItemStackCount, DestTabId, TimeStamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GUILD_BANK_EVENTLOG, "DELETE FROM guild_bank_eventlog WHERE guildid = ? AND LogGuid = ? AND TabId = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint32, 2: uint8 - PrepareStatement(CHAR_DEL_GUILD_BANK_EVENTLOGS, "DELETE FROM guild_bank_eventlog WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32 - // 0-1: uint32, 2: uint8, 3-4: uint32, 5: uint8, 6: uint64 - PrepareStatement(CHAR_INS_GUILD_EVENTLOG, "INSERT INTO guild_eventlog (guildid, LogGuid, EventType, PlayerGuid1, PlayerGuid2, NewRank, TimeStamp) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GUILD_EVENTLOG, "DELETE FROM guild_eventlog WHERE guildid = ? AND LogGuid = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint32 - PrepareStatement(CHAR_DEL_GUILD_EVENTLOGS, "DELETE FROM guild_eventlog WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32 - PrepareStatement(CHAR_UPD_GUILD_MEMBER_PNOTE, "UPDATE guild_member SET pnote = ? WHERE guid = ?", CONNECTION_ASYNC); // 0: string, 1: uint32 - PrepareStatement(CHAR_UPD_GUILD_MEMBER_OFFNOTE, "UPDATE guild_member SET offnote = ? WHERE guid = ?", CONNECTION_ASYNC); // 0: string, 1: uint32 - PrepareStatement(CHAR_UPD_GUILD_MEMBER_RANK, "UPDATE guild_member SET rank = ? WHERE guid = ?", CONNECTION_ASYNC); // 0: uint8, 1: uint32 - PrepareStatement(CHAR_UPD_GUILD_MOTD, "UPDATE guild SET motd = ? WHERE guildid = ?", CONNECTION_ASYNC); // 0: string, 1: uint32 - PrepareStatement(CHAR_UPD_GUILD_INFO, "UPDATE guild SET info = ? WHERE guildid = ?", CONNECTION_ASYNC); // 0: string, 1: uint32 - PrepareStatement(CHAR_UPD_GUILD_LEADER, "UPDATE guild SET leaderguid = ? WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint32 - PrepareStatement(CHAR_UPD_GUILD_RANK_NAME, "UPDATE guild_rank SET rname = ? WHERE rid = ? AND guildid = ?", CONNECTION_ASYNC); // 0: string, 1: uint8, 2: uint32 - PrepareStatement(CHAR_UPD_GUILD_RANK_RIGHTS, "UPDATE guild_rank SET rights = ? WHERE rid = ? AND guildid = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8, 2: uint32 - // 0-5: uint32 - PrepareStatement(CHAR_UPD_GUILD_EMBLEM_INFO, "UPDATE guild SET EmblemStyle = ?, EmblemColor = ?, BorderStyle = ?, BorderColor = ?, BackgroundColor = ? WHERE guildid = ?", CONNECTION_ASYNC); - // 0: string, 1: string, 2: uint32, 3: uint8 - PrepareStatement(CHAR_UPD_GUILD_BANK_TAB_INFO, "UPDATE guild_bank_tab SET TabName = ?, TabIcon = ? WHERE guildid = ? AND TabId = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_GUILD_BANK_MONEY, "UPDATE guild SET BankMoney = ? WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint64, 1: uint32 - // 0: uint8, 1: uint32, 2: uint8, 3: uint32 - PrepareStatement(CHAR_UPD_GUILD_BANK_EVENTLOG_TAB, "UPDATE guild_bank_eventlog SET TabId = ? WHERE guildid = ? AND TabId = ? AND LogGuid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_GUILD_RANK_BANK_MONEY, "UPDATE guild_rank SET BankMoneyPerDay = ? WHERE rid = ? AND guildid = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8, 2: uint32 - PrepareStatement(CHAR_UPD_GUILD_BANK_TAB_TEXT, "UPDATE guild_bank_tab SET TabText = ? WHERE guildid = ? AND TabId = ?", CONNECTION_ASYNC); // 0: string, 1: uint32, 2: uint8 - - PrepareStatement(CHAR_INS_GUILD_MEMBER_WITHDRAW, - "INSERT INTO guild_member_withdraw (guid, tab0, tab1, tab2, tab3, tab4, tab5, money) VALUES (?, ?, ?, ?, ?, ?, ?, ?) " - "ON DUPLICATE KEY UPDATE tab0 = VALUES (tab0), tab1 = VALUES (tab1), tab2 = VALUES (tab2), tab3 = VALUES (tab3), tab4 = VALUES (tab4), tab5 = VALUES (tab5)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GUILD_MEMBER_WITHDRAW, "TRUNCATE guild_member_withdraw", CONNECTION_ASYNC); - - // 0: uint32, 1: uint32, 2: uint32 - PrepareStatement(CHAR_SEL_CHAR_DATA_FOR_GUILD, "SELECT name, level, class, zone, account FROM characters WHERE guid = ?", CONNECTION_SYNCH); - - // Chat channel handling - PrepareStatement(CHAR_SEL_CHANNEL, "SELECT announce, ownership, password, bannedList FROM channels WHERE name = ? AND team = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_INS_CHANNEL, "INSERT INTO channels(name, team, lastUsed) VALUES (?, ?, UNIX_TIMESTAMP())", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHANNEL, "UPDATE channels SET announce = ?, ownership = ?, password = ?, bannedList = ?, lastUsed = UNIX_TIMESTAMP() WHERE name = ? AND team = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHANNEL_USAGE, "UPDATE channels SET lastUsed = UNIX_TIMESTAMP() WHERE name = ? AND team = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHANNEL_OWNERSHIP, "UPDATE channels SET ownership = ? WHERE name LIKE ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_OLD_CHANNELS, "DELETE FROM channels WHERE ownership = 1 AND lastUsed + ? < UNIX_TIMESTAMP()", CONNECTION_ASYNC); - - // Equipmentsets - PrepareStatement(CHAR_UPD_EQUIP_SET, "UPDATE character_equipmentsets SET name=?, iconname=?, ignore_mask=?, item0=?, item1=?, item2=?, item3=?, " - "item4=?, item5=?, item6=?, item7=?, item8=?, item9=?, item10=?, item11=?, item12=?, item13=?, item14=?, item15=?, item16=?, " - "item17=?, item18=? WHERE guid=? AND setguid=? AND setindex=?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_EQUIP_SET, "INSERT INTO character_equipmentsets (guid, setguid, setindex, name, iconname, ignore_mask, item0, item1, item2, item3, " - "item4, item5, item6, item7, item8, item9, item10, item11, item12, item13, item14, item15, item16, item17, item18) " - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_EQUIP_SET, "DELETE FROM character_equipmentsets WHERE setguid=?", CONNECTION_ASYNC); - - // Auras - PrepareStatement(CHAR_INS_AURA, "INSERT INTO character_aura (guid, casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges) " - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - - // Account data - PrepareStatement(CHAR_SEL_ACCOUNT_DATA, "SELECT type, time, data FROM account_data WHERE accountId = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_REP_ACCOUNT_DATA, "REPLACE INTO account_data (accountId, type, time, data) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_ACCOUNT_DATA, "DELETE FROM account_data WHERE accountId = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_PLAYER_ACCOUNT_DATA, "SELECT type, time, data FROM character_account_data WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_REP_PLAYER_ACCOUNT_DATA, "REPLACE INTO character_account_data(guid, type, time, data) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PLAYER_ACCOUNT_DATA, "DELETE FROM character_account_data WHERE guid = ?", CONNECTION_ASYNC); - - // Tutorials - PrepareStatement(CHAR_SEL_TUTORIALS, "SELECT tut0, tut1, tut2, tut3, tut4, tut5, tut6, tut7 FROM account_tutorial WHERE accountId = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_HAS_TUTORIALS, "SELECT 1 FROM account_tutorial WHERE accountId = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_INS_TUTORIALS, "INSERT INTO account_tutorial(tut0, tut1, tut2, tut3, tut4, tut5, tut6, tut7, accountId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_TUTORIALS, "UPDATE account_tutorial SET tut0 = ?, tut1 = ?, tut2 = ?, tut3 = ?, tut4 = ?, tut5 = ?, tut6 = ?, tut7 = ? WHERE accountId = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_TUTORIALS, "DELETE FROM account_tutorial WHERE accountId = ?", CONNECTION_ASYNC); - - // Instance saves - PrepareStatement(CHAR_INS_INSTANCE_SAVE, "INSERT INTO instance (id, map, resettime, difficulty, completedEncounters, data) VALUES (?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_INSTANCE_DATA, "UPDATE instance SET completedEncounters=?, data=? WHERE id=?", CONNECTION_ASYNC); - - // Game event saves - PrepareStatement(CHAR_DEL_GAME_EVENT_SAVE, "DELETE FROM game_event_save WHERE eventEntry = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_GAME_EVENT_SAVE, "INSERT INTO game_event_save (eventEntry, state, next_start) VALUES (?, ?, ?)", CONNECTION_ASYNC); - - // Game event condition saves - PrepareStatement(CHAR_DEL_ALL_GAME_EVENT_CONDITION_SAVE, "DELETE FROM game_event_condition_save WHERE eventEntry = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GAME_EVENT_CONDITION_SAVE, "DELETE FROM game_event_condition_save WHERE eventEntry = ? AND condition_id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_GAME_EVENT_CONDITION_SAVE, "INSERT INTO game_event_condition_save (eventEntry, condition_id, done) VALUES (?, ?, ?)", CONNECTION_ASYNC); - - // Petitions - PrepareStatement(CHAR_SEL_PETITION, "SELECT ownerguid, name, type FROM petition WHERE petitionguid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_PETITION_SIGNATURE, "SELECT playerguid FROM petition_sign WHERE petitionguid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_DEL_ALL_PETITION_SIGNATURES, "DELETE FROM petition_sign WHERE playerguid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PETITION_SIGNATURE, "DELETE FROM petition_sign WHERE playerguid = ? AND type = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_PETITION_BY_OWNER, "SELECT petitionguid FROM petition WHERE ownerguid = ? AND type = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_PETITION_TYPE, "SELECT type FROM petition WHERE petitionguid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_PETITION_SIGNATURES, "SELECT ownerguid, (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = ?) AS signs, type FROM petition WHERE petitionguid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_PETITION_SIG_BY_ACCOUNT, "SELECT playerguid FROM petition_sign WHERE player_account = ? AND petitionguid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_PETITION_OWNER_BY_GUID, "SELECT ownerguid FROM petition WHERE petitionguid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_PETITION_SIG_BY_GUID, "SELECT ownerguid, petitionguid FROM petition_sign WHERE playerguid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_PETITION_SIG_BY_GUID_TYPE, "SELECT ownerguid, petitionguid FROM petition_sign WHERE playerguid = ? AND type = ?", CONNECTION_SYNCH); - - // Arena teams - PrepareStatement(CHAR_SEL_CHARACTER_ARENAINFO, "SELECT arenaTeamId, weekGames, seasonGames, seasonWins, personalRating FROM arena_team_member WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_ARENA_TEAM, "INSERT INTO arena_team (arenaTeamId, name, captainGuid, type, rating, backgroundColor, emblemStyle, emblemColor, borderStyle, borderColor) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_ARENA_TEAM_MEMBER, "INSERT INTO arena_team_member (arenaTeamId, guid) VALUES (?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_ARENA_TEAM, "DELETE FROM arena_team where arenaTeamId = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_ARENA_TEAM_MEMBERS, "DELETE FROM arena_team_member WHERE arenaTeamId = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_ARENA_TEAM_CAPTAIN, "UPDATE arena_team SET captainGuid = ? WHERE arenaTeamId = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_ARENA_TEAM_MEMBER, "DELETE FROM arena_team_member WHERE arenaTeamId = ? AND guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_ARENA_TEAM_STATS, "UPDATE arena_team SET rating = ?, weekGames = ?, weekWins = ?, seasonGames = ?, seasonWins = ?, rank = ? WHERE arenaTeamId = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_ARENA_TEAM_MEMBER, "UPDATE arena_team_member SET personalRating = ?, weekGames = ?, weekWins = ?, seasonGames = ?, seasonWins = ? WHERE arenaTeamId = ? AND guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHARACTER_ARENA_STATS, "DELETE FROM character_arena_stats WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_REP_CHARACTER_ARENA_STATS, "REPLACE INTO character_arena_stats (guid, slot, matchMakerRating) VALUES (?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_PLAYER_ARENA_TEAMS, "SELECT arena_team_member.arenaTeamId FROM arena_team_member JOIN arena_team ON arena_team_member.arenaTeamId = arena_team.arenaTeamId WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_UPD_ARENA_TEAM_NAME, "UPDATE arena_team SET name = ? WHERE arenaTeamId = ?", CONNECTION_ASYNC); - - // Character battleground data - PrepareStatement(CHAR_INS_PLAYER_BGDATA, "INSERT INTO character_battleground_data (guid, instanceId, team, joinX, joinY, joinZ, joinO, joinMapId, taxiStart, taxiEnd, mountSpell) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PLAYER_BGDATA, "DELETE FROM character_battleground_data WHERE guid = ?", CONNECTION_ASYNC); - - // Character homebind - PrepareStatement(CHAR_INS_PLAYER_HOMEBIND, "INSERT INTO character_homebind (guid, mapId, zoneId, posX, posY, posZ) VALUES (?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_PLAYER_HOMEBIND, "UPDATE character_homebind SET mapId = ?, zoneId = ?, posX = ?, posY = ?, posZ = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PLAYER_HOMEBIND, "DELETE FROM character_homebind WHERE guid = ?", CONNECTION_ASYNC); - - // Corpse - PrepareStatement(CHAR_SEL_CORPSES, "SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, guildId, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0", CONNECTION_SYNCH); - PrepareStatement(CHAR_INS_CORPSE, "INSERT INTO corpse (corpseGuid, guid, posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, guildId, flags, dynFlags, time, corpseType, instanceId, phaseMask) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CORPSE, "DELETE FROM corpse WHERE corpseGuid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PLAYER_CORPSES, "DELETE FROM corpse WHERE guid = ? AND corpseType <> 0", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_OLD_CORPSES, "DELETE FROM corpse WHERE corpseType = 0 OR time < (UNIX_TIMESTAMP(NOW()) - ?)", CONNECTION_ASYNC); - - // Creature respawn - PrepareStatement(CHAR_SEL_CREATURE_RESPAWNS, "SELECT guid, respawnTime FROM creature_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_REP_CREATURE_RESPAWN, "REPLACE INTO creature_respawn (guid, respawnTime, mapId, instanceId) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CREATURE_RESPAWN, "DELETE FROM creature_respawn WHERE guid = ? AND mapId = ? AND instanceId = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE, "DELETE FROM creature_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_MAX_CREATURE_RESPAWNS, "SELECT MAX(respawnTime), instanceId FROM creature_respawn WHERE instanceId > 0 GROUP BY instanceId", CONNECTION_SYNCH); - - // Gameobject respawn - PrepareStatement(CHAR_SEL_GO_RESPAWNS, "SELECT guid, respawnTime FROM gameobject_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_REP_GO_RESPAWN, "REPLACE INTO gameobject_respawn (guid, respawnTime, mapId, instanceId) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GO_RESPAWN, "DELETE FROM gameobject_respawn WHERE guid = ? AND mapId = ? AND instanceId = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GO_RESPAWN_BY_INSTANCE, "DELETE FROM gameobject_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_ASYNC); - - // GM Tickets - PrepareStatement(CHAR_SEL_GM_TICKETS, "SELECT id, playerGuid, name, description, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, needMoreHelp FROM gm_ticket", CONNECTION_SYNCH); - PrepareStatement(CHAR_REP_GM_TICKET, "REPLACE INTO gm_ticket (id, playerGuid, name, description, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, needMoreHelp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GM_TICKET, "DELETE FROM gm_ticket WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PLAYER_GM_TICKETS, "DELETE FROM gm_ticket WHERE playerGuid = ?", CONNECTION_ASYNC); - - // GM Survey/subsurvey/lag report - PrepareStatement(CHAR_INS_GM_SURVEY, "INSERT INTO gm_survey (guid, surveyId, mainSurvey, comment, createTime) VALUES (?, ?, ?, ?, UNIX_TIMESTAMP(NOW()))", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_GM_SUBSURVEY, "INSERT INTO gm_subsurvey (surveyId, questionId, answer, answerComment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_LAG_REPORT, "INSERT INTO lag_reports (guid, lagType, mapId, posX, posY, posZ, latency, createTime) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - - // LFG Data - PrepareStatement(CHAR_INS_LFG_DATA, "INSERT INTO lfg_data (guid, dungeon, state) VALUES (?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_LFG_DATA, "DELETE FROM lfg_data WHERE guid = ?", CONNECTION_ASYNC); - - // Player saving - PrepareStatement(CHAR_INS_CHARACTER, "INSERT INTO characters (guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, " - "map, instance_id, instance_mode_mask, position_x, position_y, position_z, orientation, trans_x, trans_y, trans_z, trans_o, transguid, " - "taximask, cinematic, " - "totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, " - "extra_flags, stable_slots, at_login, zone, " - "death_expire_time, taxi_path, arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, " - "todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, health, power1, power2, power3, " - "power4, power5, power6, power7, latency, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels) VALUES " - "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,playerBytes=?,playerBytes2=?,playerFlags=?," - "map=?,instance_id=?,instance_mode_mask=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?," - "logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?," - "arenaPoints=?,totalHonorPoints=?,todayHonorPoints=?,yesterdayHonorPoints=?,totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?,knownCurrencies=?," - "watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,power6=?,power7=?,latency=?,talentGroupsCount=?,activeTalentGroup=?,exploredZones=?," - "equipmentCache=?,ammoId=?,knownTitles=?,actionBars=?,grantableLevels=?,online=? WHERE guid=?", CONNECTION_ASYNC); - - PrepareStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG, "UPDATE characters SET at_login = at_login | ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_REM_AT_LOGIN_FLAG, "UPDATE characters set at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_ALL_AT_LOGIN_FLAGS, "UPDATE characters SET at_login = at_login | ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_BUG_REPORT, "INSERT INTO bugreport (type, content) VALUES(?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_PETITION_NAME, "UPDATE petition SET name = ? WHERE petitionguid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_PETITION_SIGNATURE, "INSERT INTO petition_sign (ownerguid, petitionguid, playerguid, player_account) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_ACCOUNT_ONLINE, "UPDATE characters SET online = 0 WHERE account = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_GROUP, "INSERT INTO groups (guid, leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8, groupType, difficulty, raidDifficulty, masterLooterGuid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_GROUP_MEMBER, "INSERT INTO group_member (guid, memberGuid, memberFlags, subgroup, roles) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GROUP_MEMBER, "DELETE FROM group_member WHERE memberGuid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GROUP_INSTANCE_PERM_BINDING, "DELETE FROM group_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_GROUP_LEADER, "UPDATE groups SET leaderGuid = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_GROUP_TYPE, "UPDATE groups SET groupType = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_GROUP_MEMBER_SUBGROUP, "UPDATE group_member SET subgroup = ? WHERE memberGuid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_GROUP_MEMBER_FLAG, "UPDATE group_member SET memberFlags = ? WHERE memberGuid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_GROUP_DIFFICULTY, "UPDATE groups SET difficulty = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_GROUP_RAID_DIFFICULTY, "UPDATE groups SET raiddifficulty = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_ALL_GM_TICKETS, "TRUNCATE TABLE gm_ticket", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_INVALID_SPELL_TALENTS, "DELETE FROM character_talent WHERE spell = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_INVALID_SPELL_SPELLS, "DELETE FROM character_spell WHERE spell = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_DELETE_INFO, "UPDATE characters SET deleteInfos_Name = name, deleteInfos_Account = account, deleteDate = UNIX_TIMESTAMP(), name = '', account = 0 WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_RESTORE_DELETE_INFO, "UPDATE characters SET name = ?, account = ?, deleteDate = NULL, deleteInfos_Name = NULL, deleteInfos_Account = NULL WHERE deleteDate IS NOT NULL AND guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_ZONE, "UPDATE characters SET zone = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_LEVEL, "UPDATE characters SET level = ?, xp = 0 WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA, "DELETE FROM character_achievement_progress WHERE criteria = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_INVALID_ACHIEVMENT, "DELETE FROM character_achievement WHERE achievement = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_ADDON, "INSERT INTO addons (name, crc) VALUES (?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_INVALID_PET_SPELL, "DELETE FROM pet_spell WHERE spell = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GROUP_INSTANCE_BY_INSTANCE, "DELETE FROM group_instance WHERE instance = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GROUP_INSTANCE_BY_GUID, "DELETE FROM group_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_REP_GROUP_INSTANCE, "REPLACE INTO group_instance (guid, instance, permanent) VALUES (?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_INSTANCE_RESETTIME, "UPDATE instance SET resettime = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_GLOBAL_INSTANCE_RESETTIME, "UPDATE instance_reset SET resettime = ? WHERE mapid = ? AND difficulty = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_ONLINE, "UPDATE characters SET online = 1 WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN, "UPDATE characters set name = ?, at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_WORLDSTATE, "UPDATE worldstates SET value = ? WHERE entry = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_WORLDSTATE, "INSERT INTO worldstates (entry, value) VALUES (?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID, "DELETE FROM character_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_INSTANCE, "UPDATE character_instance SET instance = ?, permanent = ? WHERE guid = ? AND instance = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_INSTANCE, "INSERT INTO character_instance (guid, instance, permanent) VALUES (?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_GENDER_PLAYERBYTES, "UPDATE characters SET gender = ?, playerBytes = ?, playerBytes2 = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHARACTER_SKILL, "DELETE FROM character_skills WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_ADD_CHARACTER_SOCIAL_FLAGS, "UPDATE character_social SET flags = flags | ? WHERE guid = ? AND friend = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_REM_CHARACTER_SOCIAL_FLAGS, "UPDATE character_social SET flags = flags & ~ ? WHERE guid = ? AND friend = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHARACTER_SOCIAL, "INSERT INTO character_social (guid, friend, flags) VALUES (?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHARACTER_SOCIAL, "DELETE FROM character_social WHERE guid = ? AND friend = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHARACTER_SOCIAL_NOTE, "UPDATE character_social SET note = ? WHERE guid = ? AND friend = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHARACTER_POSITION, "UPDATE characters SET position_x = ?, position_y = ?, position_z = ?, orientation = ?, map = ?, zone = ?, trans_x = 0, trans_y = 0, trans_z = 0, transguid = 0, taxi_path = '' WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_AURA_FROZEN, "SELECT characters.name, character_aura.remainTime FROM characters LEFT JOIN character_aura ON (characters.guid = character_aura.guid) WHERE character_aura.spell = 9454", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHARACTER_ONLINE, "SELECT name, account, map, zone FROM characters WHERE online > 0", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_DEL_INFO_BY_GUID, "SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL AND guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_DEL_INFO_BY_NAME, "SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL AND deleteInfos_Name LIKE CONCAT('%%', ?, '%%')", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_DEL_INFO, "SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHARS_BY_ACCOUNT_ID, "SELECT guid FROM characters WHERE account = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_PINFO, "SELECT totaltime, level, money, account, race, class, map, zone, gender, health, playerFlags FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_PINFO_BANS, "SELECT unbandate, bandate = unbandate, bannedby, banreason FROM character_banned WHERE guid = ? AND active ORDER BY bandate ASC LIMIT 1", CONNECTION_SYNCH); - //0: lowGUID - PrepareStatement(CHAR_SEL_PINFO_MAILS, "SELECT SUM(CASE WHEN (checked & 1) THEN 1 ELSE 0 END) AS 'readmail', COUNT(*) AS 'totalmail' FROM mail WHERE `receiver` = ?", CONNECTION_SYNCH); - //0: lowGUID - PrepareStatement(CHAR_SEL_PINFO_XP, "SELECT a.xp, b.guid FROM characters a LEFT JOIN guild_member b ON a.guid = b.guid WHERE a.guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_HOMEBIND, "SELECT mapId, zoneId, posX, posY, posZ FROM character_homebind WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_GUID_NAME_BY_ACC, "SELECT guid, name FROM characters WHERE account = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_POOL_QUEST_SAVE, "SELECT quest_id FROM pool_quest_save WHERE pool_id = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHARACTER_AT_LOGIN, "SELECT at_login FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_CLASS_LVL_AT_LOGIN, "SELECT class, level, at_login, knownTitles FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_AT_LOGIN_TITLES, "SELECT at_login, knownTitles FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_INSTANCE, "SELECT data, completedEncounters FROM instance WHERE map = ? AND id = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_COD_ITEM_MAIL, "SELECT id, messageType, mailTemplateId, sender, subject, body, money, has_items FROM mail WHERE receiver = ? AND has_items <> 0 AND cod <> 0", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_SOCIAL, "SELECT DISTINCT guid FROM character_social WHERE friend = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_OLD_CHARS, "SELECT guid, deleteInfos_Account FROM characters WHERE deleteDate IS NOT NULL AND deleteDate < ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID, "SELECT arena_team_member.arenateamid FROM arena_team_member JOIN arena_team ON arena_team_member.arenateamid = arena_team.arenateamid WHERE guid = ? AND type = ? LIMIT 1", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_MAIL, "SELECT id, messageType, sender, receiver, subject, body, has_items, expire_time, deliver_time, money, cod, checked, stationery, mailTemplateId FROM mail WHERE receiver = ? ORDER BY id DESC", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_PLAYERBYTES2, "SELECT playerBytes2 FROM characters WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_GUID_BY_NAME, "SELECT guid FROM characters WHERE name = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_DEL_CHAR_AURA_FROZEN, "DELETE FROM character_aura WHERE spell = 9454 AND guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM character_inventory ci INNER JOIN item_instance ii ON ii.guid = ci.item WHERE itemEntry = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_MAIL_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM mail_items mi INNER JOIN item_instance ii ON ii.guid = mi.item_guid WHERE itemEntry = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM,"SELECT COUNT(itemEntry) FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE itemEntry = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_GUILD_BANK_COUNT_ITEM, "SELECT COUNT(itemEntry) FROM guild_bank_item gbi INNER JOIN item_instance ii ON ii.guid = gbi.item_guid WHERE itemEntry = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_INVENTORY_ITEM_BY_ENTRY, "SELECT ci.item, cb.slot AS bag, ci.slot, ci.guid, c.account, c.name FROM characters c " - "INNER JOIN character_inventory ci ON ci.guid = c.guid " - "INNER JOIN item_instance ii ON ii.guid = ci.item " - "LEFT JOIN character_inventory cb ON cb.item = ci.bag WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_MAIL_ITEMS_BY_ENTRY, "SELECT mi.item_guid, m.sender, m.receiver, cs.account, cs.name, cr.account, cr.name " - "FROM mail m INNER JOIN mail_items mi ON mi.mail_id = m.id INNER JOIN item_instance ii ON ii.guid = mi.item_guid " - "INNER JOIN characters cs ON cs.guid = m.sender INNER JOIN characters cr ON cr.guid = m.receiver WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY, "SELECT ah.itemguid, ah.itemowner, c.account, c.name FROM auctionhouse ah INNER JOIN characters c ON c.guid = ah.itemowner INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY, "SELECT gi.item_guid, gi.guildid, g.name FROM guild_bank_item gi INNER JOIN guild g ON g.guildid = gi.guildid INNER JOIN item_instance ii ON ii.guid = gi.item_guid WHERE ii.itemEntry = ? LIMIT ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_DEL_CHAR_ACHIEVEMENT, "DELETE FROM character_achievement WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS, "DELETE FROM character_achievement_progress WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_ACHIEVEMENT, "INSERT INTO character_achievement (guid, achievement, date) VALUES (?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS_BY_CRITERIA, "DELETE FROM character_achievement_progress WHERE guid = ? AND criteria = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS, "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_REPUTATION_BY_FACTION, "DELETE FROM character_reputation WHERE guid = ? AND faction = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_REPUTATION_BY_FACTION, "INSERT INTO character_reputation (guid, faction, standing, flags) VALUES (?, ?, ? , ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_ADD_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = (arenaPoints + ?) WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_ITEM_REFUND_INSTANCE, "DELETE FROM item_refund_instance WHERE item_guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_ITEM_REFUND_INSTANCE, "INSERT INTO item_refund_instance (item_guid, player_guid, paidMoney, paidExtendedCost) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GROUP, "DELETE FROM groups WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GROUP_MEMBER_ALL, "DELETE FROM group_member WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_GIFT, "INSERT INTO character_gifts (guid, item_guid, entry, flags) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_INSTANCE_BY_INSTANCE, "DELETE FROM instance WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE, "DELETE FROM character_instance WHERE instance = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_INSTANCE_BY_MAP_DIFF, "DELETE FROM character_instance USING character_instance LEFT JOIN instance ON character_instance.instance = id WHERE map = ? and difficulty = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GROUP_INSTANCE_BY_MAP_DIFF, "DELETE FROM group_instance USING group_instance LEFT JOIN instance ON group_instance.instance = id WHERE map = ? and difficulty = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_INSTANCE_BY_MAP_DIFF, "DELETE FROM instance WHERE map = ? and difficulty = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_MAIL_ITEM_BY_ID, "DELETE FROM mail_items WHERE mail_id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_PETITION, "INSERT INTO petition (ownerguid, petitionguid, name, type) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PETITION_BY_GUID, "DELETE FROM petition WHERE petitionguid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_GUID, "DELETE FROM petition_sign WHERE petitionguid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_DECLINED_NAME, "DELETE FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_DECLINED_NAME, "INSERT INTO character_declinedname (guid, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_FACTION_OR_RACE, "UPDATE characters SET name = ?, race = ?, at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_SKILL_LANGUAGES, "DELETE FROM character_skills WHERE skill IN (98, 113, 759, 111, 313, 109, 115, 315, 673, 137) AND guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_SKILL_LANGUAGE, "INSERT INTO `character_skills` (guid, skill, value, max) VALUES (?, ?, 300, 300)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_TAXI_PATH, "UPDATE characters SET taxi_path = '' WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_TAXIMASK, "UPDATE characters SET taximask = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS, "DELETE FROM character_queststatus WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_SOCIAL_BY_GUID, "DELETE FROM character_social WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_SOCIAL_BY_FRIEND, "DELETE FROM character_social WHERE friend = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT, "DELETE FROM character_achievement WHERE achievement = ? AND guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_ACHIEVEMENT, "UPDATE character_achievement SET achievement = ? where achievement = ? AND guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE, "UPDATE item_instance ii, character_inventory ci SET ii.itemEntry = ? WHERE ii.itemEntry = ? AND ci.guid = ? AND ci.item = ii.guid", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_SPELL_BY_SPELL, "DELETE FROM character_spell WHERE spell = ? AND guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_SPELL_FACTION_CHANGE, "UPDATE character_spell SET spell = ? where spell = ? AND guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHAR_REP_BY_FACTION, "SELECT standing FROM character_reputation WHERE faction = ? AND guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_DEL_CHAR_REP_BY_FACTION, "DELETE FROM character_reputation WHERE faction = ? AND guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_REP_FACTION_CHANGE, "UPDATE character_reputation SET faction = ?, standing = ? WHERE faction = ? AND guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_TITLES_FACTION_CHANGE, "UPDATE characters SET knownTitles = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_RES_CHAR_TITLES_FACTION_CHANGE, "UPDATE characters SET chosenTitle = 0 WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_SPELL_COOLDOWNS, "DELETE FROM character_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_SPELL_COOLDOWN, "INSERT INTO character_spell_cooldown (guid, spell, item, time) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHARACTER, "DELETE FROM characters WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_ACTION, "DELETE FROM character_action WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_AURA, "DELETE FROM character_aura WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_GIFT, "DELETE FROM character_gifts WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_INSTANCE, "DELETE FROM character_instance WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_INVENTORY, "DELETE FROM character_inventory WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS_REWARDED, "DELETE FROM character_queststatus_rewarded WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_REPUTATION, "DELETE FROM character_reputation WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_SPELL, "DELETE FROM character_spell WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_MAIL, "DELETE FROM mail WHERE receiver = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_MAIL_ITEMS, "DELETE FROM mail_items WHERE receiver = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_ACHIEVEMENTS, "DELETE FROM character_achievement WHERE guid = ? AND achievement NOT BETWEEN '456' AND '467' AND achievement NOT BETWEEN '1400' AND '1427' AND achievement NOT IN(1463, 3117, 3259)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_EQUIPMENTSETS, "DELETE FROM character_equipmentsets WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GUILD_EVENTLOG_BY_PLAYER, "DELETE FROM guild_eventlog WHERE PlayerGuid1 = ? OR PlayerGuid2 = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_GUILD_BANK_EVENTLOG_BY_PLAYER, "DELETE FROM guild_bank_eventlog WHERE PlayerGuid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_GLYPHS, "DELETE FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_TALENT, "DELETE FROM character_talent WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_SKILLS, "DELETE FROM character_skills WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_HONOR_POINTS, "UPDATE characters SET totalHonorPoints = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_MONEY, "UPDATE characters SET money = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_ACTION, "INSERT INTO character_action (guid, spec, button, action, type) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_ACTION, "UPDATE character_action SET action = ?, type = ? WHERE guid = ? AND button = ? AND spec = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_ACTION_BY_BUTTON_SPEC, "DELETE FROM character_action WHERE guid = ? and button = ? and spec = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_INVENTORY_BY_ITEM, "DELETE FROM character_inventory WHERE item = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_INVENTORY_BY_BAG_SLOT, "DELETE FROM character_inventory WHERE bag = ? AND slot = ? AND guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_MAIL, "UPDATE mail SET has_items = ?, expire_time = ?, deliver_time = ?, money = ?, cod = ?, checked = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_REP_CHAR_QUESTSTATUS, "REPLACE INTO character_queststatus (guid, quest, status, explored, timer, mobcount1, mobcount2, mobcount3, mobcount4, itemcount1, itemcount2, itemcount3, itemcount4, playercount) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS_BY_QUEST, "DELETE FROM character_queststatus WHERE guid = ? AND quest = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_QUESTSTATUS_REWARDED, "INSERT IGNORE INTO character_queststatus_rewarded (guid, quest, active) VALUES (?, ?, 1)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST, "DELETE FROM character_queststatus_rewarded WHERE guid = ? AND quest = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE, "UPDATE character_queststatus_rewarded SET quest = ? WHERE quest = ? AND guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE, "UPDATE character_queststatus_rewarded SET active = 1 WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST, "UPDATE character_queststatus_rewarded SET active = 0 WHERE quest = ? AND guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_SKILL_BY_SKILL, "DELETE FROM character_skills WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_SKILLS, "INSERT INTO character_skills (guid, skill, value, max) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_SKILLS, "UPDATE character_skills SET value = ?, max = ? WHERE guid = ? AND skill = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_SPELL, "INSERT INTO character_spell (guid, spell, active, disabled) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_STATS, "DELETE FROM character_stats WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_STATS, "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, maxpower6, maxpower7, strength, agility, stamina, intellect, spirit, " - "armor, resHoly, resFire, resNature, resFrost, resShadow, resArcane, blockPct, dodgePct, parryPct, critPct, rangedCritPct, spellCritPct, attackPower, rangedAttackPower, " - "spellPower, resilience) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PETITION_BY_OWNER, "DELETE FROM petition WHERE ownerguid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER, "DELETE FROM petition_sign WHERE ownerguid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PETITION_BY_OWNER_AND_TYPE, "DELETE FROM petition WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER_AND_TYPE, "DELETE FROM petition_sign WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_GLYPHS, "INSERT INTO character_glyphs VALUES(?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC, "DELETE FROM character_talent WHERE guid = ? AND spell = ? AND talentGroup = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_TALENT, "INSERT INTO character_talent (guid, spell, talentGroup) VALUES (?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, "DELETE FROM character_action WHERE spec<>? AND guid = ?", CONNECTION_ASYNC); - - // Items that hold loot or money - PrepareStatement(CHAR_SEL_ITEMCONTAINER_ITEMS, "SELECT item_id, item_count, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_prop, rnd_suffix FROM item_loot_items WHERE container_id = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_DEL_ITEMCONTAINER_ITEMS, "DELETE FROM item_loot_items WHERE container_id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_ITEMCONTAINER_ITEM, "DELETE FROM item_loot_items WHERE container_id = ? AND item_id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_ITEMCONTAINER_ITEMS, "INSERT INTO item_loot_items (container_id, item_id, item_count, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_prop, rnd_suffix) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_ITEMCONTAINER_MONEY, "SELECT money FROM item_loot_money WHERE container_id = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_DEL_ITEMCONTAINER_MONEY, "DELETE FROM item_loot_money WHERE container_id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_ITEMCONTAINER_MONEY, "INSERT INTO item_loot_money (container_id, money) VALUES (?, ?)", CONNECTION_ASYNC); - - // Calendar - PrepareStatement(CHAR_REP_CALENDAR_EVENT, "REPLACE INTO calendar_events (id, creator, title, description, type, dungeon, eventtime, flags, time2) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CALENDAR_EVENT, "DELETE FROM calendar_events WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_REP_CALENDAR_INVITE, "REPLACE INTO calendar_invites (id, event, invitee, sender, status, statustime, rank, text) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CALENDAR_INVITE, "DELETE FROM calendar_invites WHERE id = ?", CONNECTION_ASYNC); - - // Pet - PrepareStatement(CHAR_SEL_PET_SLOTS, "SELECT owner, slot FROM character_pet WHERE owner = ? AND slot >= ? AND slot <= ? ORDER BY slot", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_PET_SLOTS_DETAIL, "SELECT owner, id, entry, level, name FROM character_pet WHERE owner = ? AND slot >= ? AND slot <= ? ORDER BY slot", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_PET_ENTRY, "SELECT entry FROM character_pet WHERE owner = ? AND id = ? AND slot >= ? AND slot <= ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_PET_SLOT_BY_ID, "SELECT slot, entry FROM character_pet WHERE owner = ? AND id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_PET_SPELL_LIST, "SELECT DISTINCT pet_spell.spell FROM pet_spell, character_pet WHERE character_pet.owner = ? AND character_pet.id = pet_spell.guid AND character_pet.id <> ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_PET, "SELECT id FROM character_pet WHERE owner = ? AND id <> ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_PETS, "SELECT id FROM character_pet WHERE owner = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME_BY_OWNER, "DELETE FROM character_pet_declinedname WHERE owner = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME, "DELETE FROM character_pet_declinedname WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_CHAR_PET_DECLINEDNAME, "INSERT INTO character_pet_declinedname (id, owner, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_PET_AURA, "SELECT casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges FROM pet_aura WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_PET_SPELL, "SELECT spell, active FROM pet_spell WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_PET_SPELL_COOLDOWN, "SELECT spell, time FROM pet_spell_cooldown WHERE guid = ? AND time > UNIX_TIMESTAMP()", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_PET_DECLINED_NAME, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_pet_declinedname WHERE owner = ? AND id = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_DEL_PET_AURAS, "DELETE FROM pet_aura WHERE guid = ?", CONNECTION_BOTH); - PrepareStatement(CHAR_DEL_PET_SPELLS, "DELETE FROM pet_spell WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_PET_SPELL_COOLDOWNS, "DELETE FROM pet_spell_cooldown WHERE guid = ?", CONNECTION_BOTH); - PrepareStatement(CHAR_INS_PET_SPELL_COOLDOWN, "INSERT INTO pet_spell_cooldown (guid, spell, time) VALUES (?, ?, ?)", CONNECTION_BOTH); - PrepareStatement(CHAR_DEL_PET_SPELL_BY_SPELL, "DELETE FROM pet_spell WHERE guid = ? and spell = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_PET_SPELL, "INSERT INTO pet_spell (guid, spell, active) VALUES (?, ?, ?)", CONNECTION_BOTH); - PrepareStatement(CHAR_INS_PET_AURA, "INSERT INTO pet_aura (guid, casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, " - "base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_BOTH); - PrepareStatement(CHAR_SEL_CHAR_PET_BY_ENTRY, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND id = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND entry = ? AND (slot = ? OR slot > ?)", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_PET_BY_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?) ", CONNECTION_SYNCH); - PrepareStatement(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND slot = ?", CONNECTION_SYNCH); - PrepareStatement(CHAR_DEL_CHAR_PET_BY_OWNER, "DELETE FROM character_pet WHERE owner = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_PET_NAME, "UPDATE character_pet SET name = ?, renamed = 1 WHERE owner = ? AND id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID, "UPDATE character_pet SET slot = ? WHERE owner = ? AND slot = ? AND id <> ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_PET_SLOT_BY_SLOT, "UPDATE character_pet SET slot = ? WHERE owner = ? AND slot = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHAR_PET_SLOT_BY_ID, "UPDATE character_pet SET slot = ? WHERE owner = ? AND id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_PET_BY_ID, "DELETE FROM character_pet WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_DEL_CHAR_PET_BY_SLOT, "DELETE FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?)", CONNECTION_ASYNC); - - // PvPstats - PrepareStatement(CHAR_SEL_PVPSTATS_MAXID, "SELECT MAX(id) FROM pvpstats_battlegrounds", CONNECTION_SYNCH); - PrepareStatement(CHAR_INS_PVPSTATS_BATTLEGROUND, "INSERT INTO pvpstats_battlegrounds (id, winner_faction, bracket_id, type, date) VALUES (?, ?, ?, ?, NOW())", CONNECTION_ASYNC); - PrepareStatement(CHAR_INS_PVPSTATS_PLAYER, "INSERT INTO pvpstats_players (battleground_id, character_guid, score_killing_blows, score_deaths, score_honorable_kills, score_bonus_honor, score_damage_done, score_healing_done, attr_1, attr_2, attr_3, attr_4, attr_5) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_PVPSTATS_FACTIONS_OVERALL, "SELECT winner_faction, COUNT(*) AS count FROM pvpstats_battlegrounds WHERE DATEDIFF(NOW(), date) < 7 GROUP BY winner_faction ORDER BY winner_faction ASC", CONNECTION_SYNCH); - - // QuestTracker - PrepareStatement(CHAR_INS_QUEST_TRACK, "INSERT INTO quest_tracker (id, character_guid, quest_accept_time, core_hash, core_revision) VALUES (?, ?, NOW(), ?, ?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_QUEST_TRACK_GM_COMPLETE, "UPDATE quest_tracker SET completed_by_gm = 1 WHERE id = ? AND character_guid = ? ORDER BY quest_accept_time DESC LIMIT 1", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_QUEST_TRACK_COMPLETE_TIME, "UPDATE quest_tracker SET quest_complete_time = NOW() WHERE id = ? AND character_guid = ? ORDER BY quest_accept_time DESC LIMIT 1", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_QUEST_TRACK_ABANDON_TIME, "UPDATE quest_tracker SET quest_abandon_time = NOW() WHERE id = ? AND character_guid = ? ORDER BY quest_accept_time DESC LIMIT 1", CONNECTION_ASYNC); -} diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h deleted file mode 100644 index f88a912e022..00000000000 --- a/src/server/shared/Database/Implementation/CharacterDatabase.h +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _CHARACTERDATABASE_H -#define _CHARACTERDATABASE_H - -#include "DatabaseWorkerPool.h" -#include "MySQLConnection.h" - -class CharacterDatabaseConnection : public MySQLConnection -{ - public: - //- Constructors for sync and async connections - CharacterDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo) { } - CharacterDatabaseConnection(ProducerConsumerQueue<SQLOperation*>* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { } - - //- Loads database type specific prepared statements - void DoPrepareStatements() override; -}; - -typedef DatabaseWorkerPool<CharacterDatabaseConnection> CharacterDatabaseWorkerPool; - -enum CharacterDatabaseStatements -{ - /* Naming standard for defines: - {DB}_{SEL/INS/UPD/DEL/REP}_{Summary of data changed} - When updating more than one field, consider looking at the calling function - name for a suiting suffix. - */ - - CHAR_DEL_QUEST_POOL_SAVE, - CHAR_INS_QUEST_POOL_SAVE, - CHAR_DEL_NONEXISTENT_GUILD_BANK_ITEM, - CHAR_DEL_EXPIRED_BANS, - CHAR_SEL_GUID_BY_NAME, - CHAR_SEL_CHECK_NAME, - CHAR_SEL_CHECK_GUID, - CHAR_SEL_SUM_CHARS, - CHAR_SEL_CHAR_CREATE_INFO, - CHAR_INS_CHARACTER_BAN, - CHAR_UPD_CHARACTER_BAN, - CHAR_DEL_CHARACTER_BAN, - CHAR_SEL_BANINFO, - CHAR_SEL_GUID_BY_NAME_FILTER, - CHAR_SEL_BANINFO_LIST, - CHAR_SEL_BANNED_NAME, - CHAR_SEL_MAIL_LIST_COUNT, - CHAR_SEL_MAIL_LIST_INFO, - CHAR_SEL_MAIL_LIST_ITEMS, - CHAR_SEL_ENUM, - CHAR_SEL_ENUM_DECLINED_NAME, - CHAR_SEL_FREE_NAME, - CHAR_SEL_GUID_RACE_ACC_BY_NAME, - CHAR_SEL_CHAR_RACE, - CHAR_SEL_CHAR_LEVEL, - CHAR_SEL_CHAR_ZONE, - CHAR_SEL_CHARACTER_NAME_DATA, - CHAR_SEL_CHAR_POSITION_XYZ, - CHAR_SEL_CHAR_POSITION, - - CHAR_DEL_BATTLEGROUND_RANDOM_ALL, - CHAR_DEL_BATTLEGROUND_RANDOM, - CHAR_INS_BATTLEGROUND_RANDOM, - - CHAR_SEL_CHARACTER, - CHAR_SEL_GROUP_MEMBER, - CHAR_SEL_CHARACTER_INSTANCE, - CHAR_SEL_CHARACTER_AURAS, - CHAR_SEL_CHARACTER_SPELL, - CHAR_SEL_CHARACTER_QUESTSTATUS, - - CHAR_SEL_CHARACTER_QUESTSTATUS_DAILY, - CHAR_SEL_CHARACTER_QUESTSTATUS_WEEKLY, - CHAR_SEL_CHARACTER_QUESTSTATUS_MONTHLY, - CHAR_SEL_CHARACTER_QUESTSTATUS_SEASONAL, - CHAR_DEL_CHARACTER_QUESTSTATUS_DAILY, - CHAR_DEL_CHARACTER_QUESTSTATUS_WEEKLY, - CHAR_DEL_CHARACTER_QUESTSTATUS_MONTHLY, - CHAR_DEL_CHARACTER_QUESTSTATUS_SEASONAL, - CHAR_INS_CHARACTER_QUESTSTATUS_DAILY, - CHAR_INS_CHARACTER_QUESTSTATUS_WEEKLY, - CHAR_INS_CHARACTER_QUESTSTATUS_MONTHLY, - CHAR_INS_CHARACTER_QUESTSTATUS_SEASONAL, - CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_DAILY, - CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_WEEKLY, - CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_MONTHLY, - CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_SEASONAL_BY_EVENT, - - CHAR_SEL_CHARACTER_REPUTATION, - CHAR_SEL_CHARACTER_INVENTORY, - CHAR_SEL_CHARACTER_ACTIONS, - CHAR_SEL_CHARACTER_ACTIONS_SPEC, - CHAR_SEL_CHARACTER_MAILCOUNT, - CHAR_SEL_CHARACTER_MAILDATE, - CHAR_SEL_MAIL_COUNT, - CHAR_SEL_CHARACTER_SOCIALLIST, - CHAR_SEL_CHARACTER_HOMEBIND, - CHAR_SEL_CHARACTER_SPELLCOOLDOWNS, - CHAR_SEL_CHARACTER_DECLINEDNAMES, - CHAR_SEL_GUILD_MEMBER, - CHAR_SEL_GUILD_MEMBER_EXTENDED, - CHAR_SEL_CHARACTER_ARENAINFO, - CHAR_SEL_CHARACTER_ACHIEVEMENTS, - CHAR_SEL_CHARACTER_CRITERIAPROGRESS, - CHAR_SEL_CHARACTER_EQUIPMENTSETS, - CHAR_SEL_CHARACTER_BGDATA, - CHAR_SEL_CHARACTER_GLYPHS, - CHAR_SEL_CHARACTER_TALENTS, - CHAR_SEL_CHARACTER_SKILLS, - CHAR_SEL_CHARACTER_RANDOMBG, - CHAR_SEL_CHARACTER_BANNED, - CHAR_SEL_CHARACTER_QUESTSTATUSREW, - CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES, - CHAR_SEL_MAILITEMS, - CHAR_SEL_AUCTION_ITEMS, - CHAR_INS_AUCTION, - CHAR_DEL_AUCTION, - CHAR_UPD_AUCTION_BID, - CHAR_SEL_AUCTIONS, - CHAR_INS_MAIL, - CHAR_DEL_MAIL_BY_ID, - CHAR_INS_MAIL_ITEM, - CHAR_DEL_MAIL_ITEM, - CHAR_DEL_INVALID_MAIL_ITEM, - CHAR_DEL_EMPTY_EXPIRED_MAIL, - CHAR_SEL_EXPIRED_MAIL, - CHAR_SEL_EXPIRED_MAIL_ITEMS, - CHAR_UPD_MAIL_RETURNED, - CHAR_UPD_MAIL_ITEM_RECEIVER, - CHAR_UPD_ITEM_OWNER, - CHAR_SEL_ITEM_REFUNDS, - CHAR_SEL_ITEM_BOP_TRADE, - CHAR_DEL_ITEM_BOP_TRADE, - CHAR_INS_ITEM_BOP_TRADE, - CHAR_REP_INVENTORY_ITEM, - CHAR_REP_ITEM_INSTANCE, - CHAR_UPD_ITEM_INSTANCE, - CHAR_UPD_ITEM_INSTANCE_ON_LOAD, - CHAR_DEL_ITEM_INSTANCE, - CHAR_DEL_ITEM_INSTANCE_BY_OWNER, - CHAR_UPD_GIFT_OWNER, - CHAR_DEL_GIFT, - CHAR_SEL_CHARACTER_GIFT_BY_ITEM, - CHAR_SEL_ACCOUNT_BY_NAME, - CHAR_SEL_ACCOUNT_BY_GUID, - CHAR_DEL_ACCOUNT_INSTANCE_LOCK_TIMES, - CHAR_INS_ACCOUNT_INSTANCE_LOCK_TIMES, - CHAR_SEL_CHARACTER_NAME_CLASS, - CHAR_SEL_CHARACTER_NAME, - CHAR_SEL_MATCH_MAKER_RATING, - CHAR_SEL_CHARACTER_COUNT, - CHAR_UPD_NAME, - CHAR_UPD_NAME_BY_GUID, - CHAR_DEL_DECLINED_NAME, - CHAR_SEL_CHARACTER_DATA_BY_GUID, - - CHAR_INS_GUILD, - CHAR_DEL_GUILD, - CHAR_UPD_GUILD_NAME, - CHAR_INS_GUILD_MEMBER, - CHAR_DEL_GUILD_MEMBER, - CHAR_DEL_GUILD_MEMBERS, - CHAR_INS_GUILD_RANK, - CHAR_DEL_GUILD_RANKS, - CHAR_DEL_GUILD_LOWEST_RANK, - CHAR_INS_GUILD_BANK_TAB, - CHAR_DEL_GUILD_BANK_TAB, - CHAR_DEL_GUILD_BANK_TABS, - CHAR_INS_GUILD_BANK_ITEM, - CHAR_DEL_GUILD_BANK_ITEM, - CHAR_DEL_GUILD_BANK_ITEMS, - CHAR_INS_GUILD_BANK_RIGHT, - CHAR_DEL_GUILD_BANK_RIGHTS, - CHAR_DEL_GUILD_BANK_RIGHTS_FOR_RANK, - CHAR_INS_GUILD_BANK_EVENTLOG, - CHAR_DEL_GUILD_BANK_EVENTLOG, - CHAR_DEL_GUILD_BANK_EVENTLOGS, - CHAR_INS_GUILD_EVENTLOG, - CHAR_DEL_GUILD_EVENTLOG, - CHAR_DEL_GUILD_EVENTLOGS, - CHAR_UPD_GUILD_MEMBER_PNOTE, - CHAR_UPD_GUILD_MEMBER_OFFNOTE, - CHAR_UPD_GUILD_MEMBER_RANK, - CHAR_UPD_GUILD_MOTD, - CHAR_UPD_GUILD_INFO, - CHAR_UPD_GUILD_LEADER, - CHAR_UPD_GUILD_RANK_NAME, - CHAR_UPD_GUILD_RANK_RIGHTS, - CHAR_UPD_GUILD_EMBLEM_INFO, - CHAR_UPD_GUILD_BANK_TAB_INFO, - CHAR_UPD_GUILD_BANK_MONEY, - CHAR_UPD_GUILD_BANK_EVENTLOG_TAB, - CHAR_UPD_GUILD_RANK_BANK_MONEY, - CHAR_UPD_GUILD_BANK_TAB_TEXT, - CHAR_INS_GUILD_MEMBER_WITHDRAW, - CHAR_DEL_GUILD_MEMBER_WITHDRAW, - CHAR_SEL_CHAR_DATA_FOR_GUILD, - - CHAR_SEL_CHANNEL, - CHAR_INS_CHANNEL, - CHAR_UPD_CHANNEL, - CHAR_UPD_CHANNEL_USAGE, - CHAR_UPD_CHANNEL_OWNERSHIP, - CHAR_DEL_OLD_CHANNELS, - - CHAR_UPD_EQUIP_SET, - CHAR_INS_EQUIP_SET, - CHAR_DEL_EQUIP_SET, - - CHAR_INS_AURA, - - CHAR_SEL_ACCOUNT_DATA, - CHAR_REP_ACCOUNT_DATA, - CHAR_DEL_ACCOUNT_DATA, - CHAR_SEL_PLAYER_ACCOUNT_DATA, - CHAR_REP_PLAYER_ACCOUNT_DATA, - CHAR_DEL_PLAYER_ACCOUNT_DATA, - - CHAR_SEL_TUTORIALS, - CHAR_SEL_HAS_TUTORIALS, - CHAR_INS_TUTORIALS, - CHAR_UPD_TUTORIALS, - CHAR_DEL_TUTORIALS, - - CHAR_INS_INSTANCE_SAVE, - CHAR_UPD_INSTANCE_DATA, - - CHAR_DEL_GAME_EVENT_SAVE, - CHAR_INS_GAME_EVENT_SAVE, - - CHAR_DEL_ALL_GAME_EVENT_CONDITION_SAVE, - CHAR_DEL_GAME_EVENT_CONDITION_SAVE, - CHAR_INS_GAME_EVENT_CONDITION_SAVE, - - CHAR_INS_ARENA_TEAM, - CHAR_INS_ARENA_TEAM_MEMBER, - CHAR_DEL_ARENA_TEAM, - CHAR_DEL_ARENA_TEAM_MEMBERS, - CHAR_UPD_ARENA_TEAM_CAPTAIN, - CHAR_DEL_ARENA_TEAM_MEMBER, - CHAR_UPD_ARENA_TEAM_STATS, - CHAR_UPD_ARENA_TEAM_MEMBER, - CHAR_DEL_CHARACTER_ARENA_STATS, - CHAR_REP_CHARACTER_ARENA_STATS, - CHAR_SEL_PLAYER_ARENA_TEAMS, - CHAR_UPD_ARENA_TEAM_NAME, - - CHAR_SEL_PETITION, - CHAR_SEL_PETITION_SIGNATURE, - CHAR_DEL_ALL_PETITION_SIGNATURES, - CHAR_DEL_PETITION_SIGNATURE, - CHAR_SEL_PETITION_BY_OWNER, - CHAR_SEL_PETITION_TYPE, - CHAR_SEL_PETITION_SIGNATURES, - CHAR_SEL_PETITION_SIG_BY_ACCOUNT, - CHAR_SEL_PETITION_OWNER_BY_GUID, - CHAR_SEL_PETITION_SIG_BY_GUID, - CHAR_SEL_PETITION_SIG_BY_GUID_TYPE, - - CHAR_INS_PLAYER_BGDATA, - CHAR_DEL_PLAYER_BGDATA, - - CHAR_INS_PLAYER_HOMEBIND, - CHAR_UPD_PLAYER_HOMEBIND, - CHAR_DEL_PLAYER_HOMEBIND, - - CHAR_SEL_CORPSES, - CHAR_INS_CORPSE, - CHAR_DEL_CORPSE, - CHAR_DEL_PLAYER_CORPSES, - CHAR_DEL_OLD_CORPSES, - - CHAR_SEL_CREATURE_RESPAWNS, - CHAR_REP_CREATURE_RESPAWN, - CHAR_DEL_CREATURE_RESPAWN, - CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE, - CHAR_SEL_MAX_CREATURE_RESPAWNS, - - CHAR_SEL_GO_RESPAWNS, - CHAR_REP_GO_RESPAWN, - CHAR_DEL_GO_RESPAWN, - CHAR_DEL_GO_RESPAWN_BY_INSTANCE, - - CHAR_SEL_GM_TICKETS, - CHAR_REP_GM_TICKET, - CHAR_DEL_GM_TICKET, - CHAR_DEL_ALL_GM_TICKETS, - CHAR_DEL_PLAYER_GM_TICKETS, - - CHAR_INS_GM_SURVEY, - CHAR_INS_GM_SUBSURVEY, - CHAR_INS_LAG_REPORT, - - CHAR_INS_CHARACTER, - CHAR_UPD_CHARACTER, - - CHAR_UPD_ADD_AT_LOGIN_FLAG, - CHAR_UPD_REM_AT_LOGIN_FLAG, - CHAR_UPD_ALL_AT_LOGIN_FLAGS, - CHAR_INS_BUG_REPORT, - CHAR_UPD_PETITION_NAME, - CHAR_INS_PETITION_SIGNATURE, - CHAR_UPD_ACCOUNT_ONLINE, - CHAR_INS_GROUP, - CHAR_INS_GROUP_MEMBER, - CHAR_DEL_GROUP_MEMBER, - CHAR_DEL_GROUP_INSTANCE_PERM_BINDING, - CHAR_UPD_GROUP_LEADER, - CHAR_UPD_GROUP_TYPE, - CHAR_UPD_GROUP_MEMBER_SUBGROUP, - CHAR_UPD_GROUP_MEMBER_FLAG, - CHAR_UPD_GROUP_DIFFICULTY, - CHAR_UPD_GROUP_RAID_DIFFICULTY, - CHAR_DEL_INVALID_SPELL_SPELLS, - CHAR_DEL_INVALID_SPELL_TALENTS, - CHAR_UPD_DELETE_INFO, - CHAR_UPD_RESTORE_DELETE_INFO, - CHAR_UPD_ZONE, - CHAR_UPD_LEVEL, - CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA, - CHAR_DEL_INVALID_ACHIEVMENT, - CHAR_INS_ADDON, - CHAR_DEL_INVALID_PET_SPELL, - CHAR_DEL_GROUP_INSTANCE_BY_INSTANCE, - CHAR_DEL_GROUP_INSTANCE_BY_GUID, - CHAR_REP_GROUP_INSTANCE, - CHAR_UPD_INSTANCE_RESETTIME, - CHAR_UPD_GLOBAL_INSTANCE_RESETTIME, - CHAR_UPD_CHAR_ONLINE, - CHAR_UPD_CHAR_NAME_AT_LOGIN, - CHAR_UPD_WORLDSTATE, - CHAR_INS_WORLDSTATE, - CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID, - CHAR_UPD_CHAR_INSTANCE, - CHAR_INS_CHAR_INSTANCE, - CHAR_UPD_GENDER_PLAYERBYTES, - CHAR_DEL_CHARACTER_SKILL, - CHAR_UPD_ADD_CHARACTER_SOCIAL_FLAGS, - CHAR_UPD_REM_CHARACTER_SOCIAL_FLAGS, - CHAR_INS_CHARACTER_SOCIAL, - CHAR_DEL_CHARACTER_SOCIAL, - CHAR_UPD_CHARACTER_SOCIAL_NOTE, - CHAR_UPD_CHARACTER_POSITION, - - CHAR_INS_LFG_DATA, - CHAR_DEL_LFG_DATA, - - CHAR_SEL_CHARACTER_AURA_FROZEN, - CHAR_SEL_CHARACTER_ONLINE, - - CHAR_SEL_CHAR_DEL_INFO_BY_GUID, - CHAR_SEL_CHAR_DEL_INFO_BY_NAME, - CHAR_SEL_CHAR_DEL_INFO, - - CHAR_SEL_CHARS_BY_ACCOUNT_ID, - CHAR_SEL_CHAR_PINFO, - CHAR_SEL_PINFO_XP, - CHAR_SEL_PINFO_MAILS, - CHAR_SEL_PINFO_BANS, - CHAR_SEL_CHAR_HOMEBIND, - CHAR_SEL_CHAR_GUID_NAME_BY_ACC, - CHAR_SEL_POOL_QUEST_SAVE, - CHAR_SEL_CHARACTER_AT_LOGIN, - CHAR_SEL_CHAR_CLASS_LVL_AT_LOGIN, - CHAR_SEL_CHAR_AT_LOGIN_TITLES, - CHAR_SEL_INSTANCE, - CHAR_SEL_CHAR_COD_ITEM_MAIL, - CHAR_SEL_CHAR_SOCIAL, - CHAR_SEL_CHAR_OLD_CHARS, - CHAR_SEL_ARENA_TEAM_ID_BY_PLAYER_GUID, - CHAR_SEL_MAIL, - CHAR_SEL_CHAR_PLAYERBYTES2, - CHAR_SEL_CHAR_GUID_BY_NAME, - CHAR_DEL_CHAR_AURA_FROZEN, - CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM, - CHAR_SEL_MAIL_COUNT_ITEM, - CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM, - CHAR_SEL_GUILD_BANK_COUNT_ITEM, - CHAR_SEL_CHAR_INVENTORY_ITEM_BY_ENTRY, - CHAR_SEL_MAIL_ITEMS_BY_ENTRY, - CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY, - CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY, - CHAR_DEL_CHAR_ACHIEVEMENT, - CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS, - CHAR_INS_CHAR_ACHIEVEMENT, - CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS_BY_CRITERIA, - CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS, - CHAR_DEL_CHAR_REPUTATION_BY_FACTION, - CHAR_INS_CHAR_REPUTATION_BY_FACTION, - CHAR_UPD_ADD_CHAR_ARENA_POINTS, - CHAR_DEL_ITEM_REFUND_INSTANCE, - CHAR_INS_ITEM_REFUND_INSTANCE, - CHAR_DEL_GROUP, - CHAR_DEL_GROUP_MEMBER_ALL, - CHAR_INS_CHAR_GIFT, - CHAR_DEL_INSTANCE_BY_INSTANCE, - CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE, - CHAR_DEL_CHAR_INSTANCE_BY_MAP_DIFF, - CHAR_DEL_GROUP_INSTANCE_BY_MAP_DIFF, - CHAR_DEL_INSTANCE_BY_MAP_DIFF, - CHAR_DEL_MAIL_ITEM_BY_ID, - CHAR_INS_PETITION, - CHAR_DEL_PETITION_BY_GUID, - CHAR_DEL_PETITION_SIGNATURE_BY_GUID, - CHAR_DEL_CHAR_DECLINED_NAME, - CHAR_INS_CHAR_DECLINED_NAME, - CHAR_UPD_FACTION_OR_RACE, - CHAR_DEL_CHAR_SKILL_LANGUAGES, - CHAR_INS_CHAR_SKILL_LANGUAGE, - CHAR_UPD_CHAR_TAXI_PATH, - CHAR_UPD_CHAR_TAXIMASK, - CHAR_DEL_CHAR_QUESTSTATUS, - CHAR_DEL_CHAR_SOCIAL_BY_GUID, - CHAR_DEL_CHAR_SOCIAL_BY_FRIEND, - CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT, - CHAR_UPD_CHAR_ACHIEVEMENT, - CHAR_UPD_CHAR_INVENTORY_FACTION_CHANGE, - CHAR_DEL_CHAR_SPELL_BY_SPELL, - CHAR_UPD_CHAR_SPELL_FACTION_CHANGE, - CHAR_SEL_CHAR_REP_BY_FACTION, - CHAR_DEL_CHAR_REP_BY_FACTION, - CHAR_UPD_CHAR_REP_FACTION_CHANGE, - CHAR_UPD_CHAR_TITLES_FACTION_CHANGE, - CHAR_RES_CHAR_TITLES_FACTION_CHANGE, - CHAR_DEL_CHAR_SPELL_COOLDOWNS, - CHAR_INS_CHAR_SPELL_COOLDOWN, - CHAR_DEL_CHARACTER, - CHAR_DEL_CHAR_ACTION, - CHAR_DEL_CHAR_AURA, - CHAR_DEL_CHAR_GIFT, - CHAR_DEL_CHAR_INSTANCE, - CHAR_DEL_CHAR_INVENTORY, - CHAR_DEL_CHAR_QUESTSTATUS_REWARDED, - CHAR_DEL_CHAR_REPUTATION, - CHAR_DEL_CHAR_SPELL, - CHAR_DEL_MAIL, - CHAR_DEL_MAIL_ITEMS, - CHAR_DEL_CHAR_ACHIEVEMENTS, - CHAR_DEL_CHAR_EQUIPMENTSETS, - CHAR_DEL_GUILD_EVENTLOG_BY_PLAYER, - CHAR_DEL_GUILD_BANK_EVENTLOG_BY_PLAYER, - CHAR_DEL_CHAR_GLYPHS, - CHAR_DEL_CHAR_TALENT, - CHAR_DEL_CHAR_SKILLS, - CHAR_UPD_CHAR_HONOR_POINTS, - CHAR_UPD_CHAR_ARENA_POINTS, - CHAR_UPD_CHAR_MONEY, - CHAR_INS_CHAR_ACTION, - CHAR_UPD_CHAR_ACTION, - CHAR_DEL_CHAR_ACTION_BY_BUTTON_SPEC, - CHAR_DEL_CHAR_INVENTORY_BY_ITEM, - CHAR_DEL_CHAR_INVENTORY_BY_BAG_SLOT, - CHAR_UPD_MAIL, - CHAR_REP_CHAR_QUESTSTATUS, - CHAR_DEL_CHAR_QUESTSTATUS_BY_QUEST, - CHAR_INS_CHAR_QUESTSTATUS_REWARDED, - CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST, - CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_FACTION_CHANGE, - CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE, - CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST, - CHAR_DEL_CHAR_SKILL_BY_SKILL, - CHAR_INS_CHAR_SKILLS, - CHAR_UPD_CHAR_SKILLS, - CHAR_INS_CHAR_SPELL, - CHAR_DEL_CHAR_STATS, - CHAR_INS_CHAR_STATS, - CHAR_DEL_PETITION_BY_OWNER, - CHAR_DEL_PETITION_SIGNATURE_BY_OWNER, - CHAR_DEL_PETITION_BY_OWNER_AND_TYPE, - CHAR_DEL_PETITION_SIGNATURE_BY_OWNER_AND_TYPE, - CHAR_INS_CHAR_GLYPHS, - CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC, - CHAR_INS_CHAR_TALENT, - CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, - - CHAR_REP_CALENDAR_EVENT, - CHAR_DEL_CALENDAR_EVENT, - CHAR_REP_CALENDAR_INVITE, - CHAR_DEL_CALENDAR_INVITE, - - CHAR_SEL_PET_AURA, - CHAR_SEL_PET_SPELL, - CHAR_SEL_PET_SPELL_COOLDOWN, - CHAR_SEL_PET_DECLINED_NAME, - CHAR_DEL_PET_AURAS, - CHAR_DEL_PET_SPELL_COOLDOWNS, - CHAR_INS_PET_SPELL_COOLDOWN, - CHAR_DEL_PET_SPELL_BY_SPELL, - CHAR_INS_PET_SPELL, - CHAR_INS_PET_AURA, - - CHAR_DEL_PET_SPELLS, - CHAR_DEL_CHAR_PET_BY_OWNER, - CHAR_DEL_CHAR_PET_DECLINEDNAME_BY_OWNER, - CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, - CHAR_SEL_PET_SLOTS, - CHAR_SEL_PET_SLOTS_DETAIL, - CHAR_SEL_PET_ENTRY, - CHAR_SEL_PET_SLOT_BY_ID, - CHAR_SEL_PET_SPELL_LIST, - CHAR_SEL_CHAR_PET, - CHAR_SEL_CHAR_PETS, - CHAR_SEL_CHAR_PET_BY_ENTRY, - CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2, - CHAR_SEL_CHAR_PET_BY_SLOT, - CHAR_DEL_CHAR_PET_DECLINEDNAME, - CHAR_INS_CHAR_PET_DECLINEDNAME, - CHAR_UPD_CHAR_PET_NAME, - CHAR_UPD_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID, - CHAR_UPD_CHAR_PET_SLOT_BY_SLOT, - CHAR_UPD_CHAR_PET_SLOT_BY_ID, - CHAR_DEL_CHAR_PET_BY_ID, - CHAR_DEL_CHAR_PET_BY_SLOT, - - CHAR_SEL_ITEMCONTAINER_ITEMS, - CHAR_DEL_ITEMCONTAINER_ITEMS, - CHAR_DEL_ITEMCONTAINER_ITEM, - CHAR_INS_ITEMCONTAINER_ITEMS, - CHAR_SEL_ITEMCONTAINER_MONEY, - CHAR_DEL_ITEMCONTAINER_MONEY, - CHAR_INS_ITEMCONTAINER_MONEY, - - CHAR_SEL_PVPSTATS_MAXID, - CHAR_INS_PVPSTATS_BATTLEGROUND, - CHAR_INS_PVPSTATS_PLAYER, - CHAR_SEL_PVPSTATS_FACTIONS_OVERALL, - - CHAR_INS_QUEST_TRACK, - CHAR_UPD_QUEST_TRACK_GM_COMPLETE, - CHAR_UPD_QUEST_TRACK_COMPLETE_TIME, - CHAR_UPD_QUEST_TRACK_ABANDON_TIME, - - MAX_CHARACTERDATABASE_STATEMENTS -}; - -#endif diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp deleted file mode 100644 index 8f0b5067957..00000000000 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "LoginDatabase.h" - -void LoginDatabaseConnection::DoPrepareStatements() -{ - if (!m_reconnecting) - m_stmts.resize(MAX_LOGINDATABASE_STATEMENTS); - - PrepareStatement(LOGIN_SEL_REALMLIST, "SELECT id, name, address, localAddress, localSubnetMask, port, icon, flag, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE flag <> 3 ORDER BY name", CONNECTION_SYNCH); - PrepareStatement(LOGIN_DEL_EXPIRED_IP_BANS, "DELETE FROM ip_banned WHERE unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_EXPIRED_ACCOUNT_BANS, "UPDATE account_banned SET active = 0 WHERE active = 1 AND unbandate<>bandate AND unbandate<=UNIX_TIMESTAMP()", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_IP_BANNED, "SELECT * FROM ip_banned WHERE ip = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_INS_IP_AUTO_BANNED, "INSERT INTO ip_banned (ip, bandate, unbandate, bannedby, banreason) VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity Auth', 'Failed login autoban')", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_IP_BANNED_ALL, "SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned WHERE (bandate = unbandate OR unbandate > UNIX_TIMESTAMP()) ORDER BY unbandate", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_IP_BANNED_BY_IP, "SELECT ip, bandate, unbandate, bannedby, banreason FROM ip_banned WHERE (bandate = unbandate OR unbandate > UNIX_TIMESTAMP()) AND ip LIKE CONCAT('%%', ?, '%%') ORDER BY unbandate", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_BANNED, "SELECT bandate, unbandate FROM account_banned WHERE id = ? AND active = 1", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_BANNED_ALL, "SELECT account.id, username FROM account, account_banned WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME, "SELECT account.id, username FROM account, account_banned WHERE account.id = account_banned.id AND active = 1 AND username LIKE CONCAT('%%', ?, '%%') GROUP BY account.id", CONNECTION_SYNCH); - PrepareStatement(LOGIN_INS_ACCOUNT_AUTO_BANNED, "INSERT INTO account_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity Auth', 'Failed login autoban', 1)", CONNECTION_ASYNC); - PrepareStatement(LOGIN_DEL_ACCOUNT_BANNED, "DELETE FROM account_banned WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_SESSIONKEY, "SELECT a.sessionkey, a.id, aa.gmlevel FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_UPD_VS, "UPDATE account SET v = ?, s = ? WHERE username = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_LOGONPROOF, "UPDATE account SET sessionkey = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, "SELECT a.sha_pass_hash, a.id, a.locked, a.lock_country, a.last_ip, aa.gmlevel, a.v, a.s, a.token_key FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_LOGON_COUNTRY, "SELECT country FROM ip2nation WHERE ip < ? ORDER BY ip DESC LIMIT 0,1", CONNECTION_SYNCH); - PrepareStatement(LOGIN_UPD_FAILEDLOGINS, "UPDATE account SET failed_logins = failed_logins + 1 WHERE username = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_FAILEDLOGINS, "SELECT id, failed_logins FROM account WHERE username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_NAME, "SELECT id, username FROM account WHERE username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL, "SELECT id, username FROM account WHERE email = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_NUM_CHARS_ON_REALM, "SELECT numchars FROM realmcharacters WHERE realmid = ? AND acctid= ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_BY_IP, "SELECT id, username FROM account WHERE last_ip = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_BY_ID, "SELECT 1 FROM account WHERE id = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_INS_IP_BANNED, "INSERT INTO ip_banned (ip, bandate, unbandate, bannedby, banreason) VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(LOGIN_DEL_IP_NOT_BANNED, "DELETE FROM ip_banned WHERE ip = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_INS_ACCOUNT_BANNED, "INSERT INTO account_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, ?, ?, 1)", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_ACCOUNT_NOT_BANNED, "UPDATE account_banned SET active = 0 WHERE id = ? AND active != 0", CONNECTION_ASYNC); - PrepareStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM, "DELETE FROM realmcharacters WHERE acctid = ? AND realmid = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_DEL_REALM_CHARACTERS, "DELETE FROM realmcharacters WHERE acctid = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_INS_REALM_CHARACTERS, "INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_SUM_REALM_CHARACTERS, "SELECT SUM(numchars) FROM realmcharacters WHERE acctid = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_INS_ACCOUNT, "INSERT INTO account(username, sha_pass_hash, reg_mail, email, joindate) VALUES(?, ?, ?, ?, NOW())", CONNECTION_SYNCH); - PrepareStatement(LOGIN_INS_REALM_CHARACTERS_INIT, "INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist, account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_EXPANSION, "UPDATE account SET expansion = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_ACCOUNT_LOCK, "UPDATE account SET locked = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_ACCOUNT_LOCK_CONTRY, "UPDATE account SET lock_country = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_INS_LOG, "INSERT INTO logs (time, realm, type, level, string) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_USERNAME, "UPDATE account SET v = 0, s = 0, username = ?, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_PASSWORD, "UPDATE account SET v = 0, s = 0, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_EMAIL, "UPDATE account SET email = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_REG_EMAIL, "UPDATE account SET reg_mail = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_MUTE_TIME, "UPDATE account SET mutetime = ? , mutereason = ? , muteby = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_MUTE_TIME_LOGIN, "UPDATE account SET mutetime = ? WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_LAST_IP, "UPDATE account SET last_ip = ? WHERE username = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_LAST_ATTEMPT_IP, "UPDATE account SET last_attempt_ip = ? WHERE username = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_ACCOUNT_ONLINE, "UPDATE account SET online = 1 WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_UPD_UPTIME_PLAYERS, "UPDATE uptime SET uptime = ?, maxplayers = ? WHERE realmid = ? AND starttime = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_DEL_OLD_LOGS, "DELETE FROM logs WHERE (time + ?) < ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_DEL_ACCOUNT_ACCESS, "DELETE FROM account_access WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM, "DELETE FROM account_access WHERE id = ? AND (RealmID = ? OR RealmID = -1)", CONNECTION_ASYNC); - PrepareStatement(LOGIN_INS_ACCOUNT_ACCESS, "INSERT INTO account_access (id,gmlevel,RealmID) VALUES (?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(LOGIN_GET_ACCOUNT_ID_BY_USERNAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_GET_ACCOUNT_ACCESS_GMLEVEL, "SELECT gmlevel FROM account_access WHERE id = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_GET_GMLEVEL_BY_REALMID, "SELECT gmlevel FROM account_access WHERE id = ? AND (RealmID = ? OR RealmID = -1)", CONNECTION_SYNCH); - PrepareStatement(LOGIN_GET_USERNAME_BY_ID, "SELECT username FROM account WHERE id = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_CHECK_PASSWORD, "SELECT 1 FROM account WHERE id = ? AND sha_pass_hash = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_CHECK_PASSWORD_BY_NAME, "SELECT 1 FROM account WHERE username = ? AND sha_pass_hash = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_PINFO, "SELECT a.username, aa.gmlevel, a.email, a.reg_mail, a.last_ip, DATE_FORMAT(a.last_login, '%Y-%m-%d %T'), a.mutetime, a.mutereason, a.muteby, a.failed_logins, a.locked, a.OS FROM account a LEFT JOIN account_access aa ON (a.id = aa.id AND (aa.RealmID = ? OR aa.RealmID = -1)) WHERE a.id = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_PINFO_BANS, "SELECT unbandate, bandate = unbandate, bannedby, banreason FROM account_banned WHERE id = ? AND active ORDER BY bandate ASC LIMIT 1", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_GM_ACCOUNTS, "SELECT a.username, aa.gmlevel FROM account a, account_access aa WHERE a.id=aa.id AND aa.gmlevel >= ? AND (aa.realmid = -1 OR aa.realmid = ?)", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_INFO, "SELECT a.username, a.last_ip, aa.gmlevel, a.expansion FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.id = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_ACCESS_GMLEVEL_TEST, "SELECT 1 FROM account_access WHERE id = ? AND gmlevel > ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_ACCESS, "SELECT a.id, aa.gmlevel, aa.RealmID FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_RECRUITER, "SELECT 1 FROM account WHERE recruiter = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_BANS, "SELECT 1 FROM account_banned WHERE id = ? AND active = 1 UNION SELECT 1 FROM ip_banned WHERE ip = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_ACCOUNT_WHOIS, "SELECT username, email, last_ip FROM account WHERE id = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_LAST_ATTEMPT_IP, "SELECT last_attempt_ip FROM account WHERE id = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_LAST_IP, "SELECT last_ip FROM account WHERE id = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL, "SELECT allowedSecurityLevel from realmlist WHERE id = ?", CONNECTION_SYNCH); - PrepareStatement(LOGIN_DEL_ACCOUNT, "DELETE FROM account WHERE id = ?", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_IP2NATION_COUNTRY, "SELECT c.country FROM ip2nationCountries c, ip2nation i WHERE i.ip < ? AND c.code = i.country ORDER BY i.ip DESC LIMIT 0,1", CONNECTION_SYNCH); - PrepareStatement(LOGIN_SEL_AUTOBROADCAST, "SELECT id, weight, text FROM autobroadcast WHERE realmid = ? OR realmid = -1", CONNECTION_SYNCH); - PrepareStatement(LOGIN_GET_EMAIL_BY_ID, "SELECT email FROM account WHERE id = ?", CONNECTION_SYNCH); - // 0: uint32, 1: uint32, 2: uint8, 3: uint32, 4: string // Complete name: "Login_Insert_AccountLoginDeLete_IP_Logging" - PrepareStatement(LOGIN_INS_ALDL_IP_LOGGING, "INSERT INTO logs_ip_actions (account_id,character_guid,type,ip,systemnote,unixtime,time) VALUES (?, ?, ?, (SELECT last_ip FROM account WHERE id = ?), ?, unix_timestamp(NOW()), NOW())", CONNECTION_ASYNC); - // 0: uint32, 1: uint32, 2: uint8, 3: uint32, 4: string // Complete name: "Login_Insert_FailedAccountLogin_IP_Logging" - PrepareStatement(LOGIN_INS_FACL_IP_LOGGING, "INSERT INTO logs_ip_actions (account_id,character_guid,type,ip,systemnote,unixtime,time) VALUES (?, ?, ?, (SELECT last_attempt_ip FROM account WHERE id = ?), ?, unix_timestamp(NOW()), NOW())", CONNECTION_ASYNC); - // 0: uint32, 1: uint32, 2: uint8, 3: string, 4: string // Complete name: "Login_Insert_CharacterDelete_IP_Logging" - PrepareStatement(LOGIN_INS_CHAR_IP_LOGGING, "INSERT INTO logs_ip_actions (account_id,character_guid,type,ip,systemnote,unixtime,time) VALUES (?, ?, ?, ?, ?, unix_timestamp(NOW()), NOW())", CONNECTION_ASYNC); - // 0: string, 1: string, 2: string // Complete name: "Login_Insert_Failed_Account_Login_due_password_IP_Logging" - PrepareStatement(LOGIN_INS_FALP_IP_LOGGING, "INSERT INTO logs_ip_actions (account_id,character_guid,type,ip,systemnote,unixtime,time) VALUES ((SELECT id FROM account WHERE username = ?), 0, 1, ?, ?, unix_timestamp(NOW()), NOW())", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_ACCOUNT_ACCESS_BY_ID, "SELECT gmlevel, RealmID FROM account_access WHERE id = ? and (RealmID = ? OR RealmID = -1) ORDER BY gmlevel desc", CONNECTION_SYNCH); - - PrepareStatement(LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS, "SELECT permissionId, granted FROM rbac_account_permissions WHERE accountId = ? AND (realmId = ? OR realmId = -1) ORDER BY permissionId, realmId", CONNECTION_SYNCH); - PrepareStatement(LOGIN_INS_RBAC_ACCOUNT_PERMISSION, "INSERT INTO rbac_account_permissions (accountId, permissionId, granted, realmId) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE granted = VALUES(granted)", CONNECTION_ASYNC); - PrepareStatement(LOGIN_DEL_RBAC_ACCOUNT_PERMISSION, "DELETE FROM rbac_account_permissions WHERE accountId = ? AND permissionId = ? AND (realmId = ? OR realmId = -1)", CONNECTION_ASYNC); - PrepareStatement(LOGIN_INS_ACCOUNT_MUTE, "INSERT INTO account_muted VALUES (?, UNIX_TIMESTAMP(), ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(LOGIN_SEL_ACCOUNT_MUTE_INFO, "SELECT mutedate, mutetime, mutereason, mutedby FROM account_muted WHERE guid = ? ORDER BY mutedate ASC", CONNECTION_SYNCH); -} diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h deleted file mode 100644 index 7f6cffa520f..00000000000 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _LOGINDATABASE_H -#define _LOGINDATABASE_H - -#include "DatabaseWorkerPool.h" -#include "MySQLConnection.h" - -class LoginDatabaseConnection : public MySQLConnection -{ - public: - //- Constructors for sync and async connections - LoginDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo) { } - LoginDatabaseConnection(ProducerConsumerQueue<SQLOperation*>* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { } - - //- Loads database type specific prepared statements - void DoPrepareStatements() override; -}; - -typedef DatabaseWorkerPool<LoginDatabaseConnection> LoginDatabaseWorkerPool; - -enum LoginDatabaseStatements -{ - /* Naming standard for defines: - {DB}_{SEL/INS/UPD/DEL/REP}_{Summary of data changed} - When updating more than one field, consider looking at the calling function - name for a suiting suffix. - */ - - LOGIN_SEL_REALMLIST, - LOGIN_DEL_EXPIRED_IP_BANS, - LOGIN_UPD_EXPIRED_ACCOUNT_BANS, - LOGIN_SEL_IP_BANNED, - LOGIN_INS_IP_AUTO_BANNED, - LOGIN_SEL_ACCOUNT_BANNED, - LOGIN_SEL_ACCOUNT_BANNED_ALL, - LOGIN_SEL_ACCOUNT_BANNED_BY_USERNAME, - LOGIN_INS_ACCOUNT_AUTO_BANNED, - LOGIN_DEL_ACCOUNT_BANNED, - LOGIN_SEL_SESSIONKEY, - LOGIN_UPD_VS, - LOGIN_UPD_LOGONPROOF, - LOGIN_SEL_LOGONCHALLENGE, - LOGIN_SEL_LOGON_COUNTRY, - LOGIN_UPD_FAILEDLOGINS, - LOGIN_SEL_FAILEDLOGINS, - LOGIN_SEL_ACCOUNT_ID_BY_NAME, - LOGIN_SEL_ACCOUNT_LIST_BY_NAME, - LOGIN_SEL_ACCOUNT_INFO_BY_NAME, - LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL, - LOGIN_SEL_NUM_CHARS_ON_REALM, - LOGIN_SEL_ACCOUNT_BY_IP, - LOGIN_INS_IP_BANNED, - LOGIN_DEL_IP_NOT_BANNED, - LOGIN_SEL_IP_BANNED_ALL, - LOGIN_SEL_IP_BANNED_BY_IP, - LOGIN_SEL_ACCOUNT_BY_ID, - LOGIN_INS_ACCOUNT_BANNED, - LOGIN_UPD_ACCOUNT_NOT_BANNED, - LOGIN_DEL_REALM_CHARACTERS_BY_REALM, - LOGIN_DEL_REALM_CHARACTERS, - LOGIN_INS_REALM_CHARACTERS, - LOGIN_SEL_SUM_REALM_CHARACTERS, - LOGIN_INS_ACCOUNT, - LOGIN_INS_REALM_CHARACTERS_INIT, - LOGIN_UPD_EXPANSION, - LOGIN_UPD_ACCOUNT_LOCK, - LOGIN_UPD_ACCOUNT_LOCK_CONTRY, - LOGIN_INS_LOG, - LOGIN_UPD_USERNAME, - LOGIN_UPD_PASSWORD, - LOGIN_UPD_EMAIL, - LOGIN_UPD_REG_EMAIL, - LOGIN_UPD_MUTE_TIME, - LOGIN_UPD_MUTE_TIME_LOGIN, - LOGIN_UPD_LAST_IP, - LOGIN_UPD_LAST_ATTEMPT_IP, - LOGIN_UPD_ACCOUNT_ONLINE, - LOGIN_UPD_UPTIME_PLAYERS, - LOGIN_DEL_OLD_LOGS, - LOGIN_DEL_ACCOUNT_ACCESS, - LOGIN_DEL_ACCOUNT_ACCESS_BY_REALM, - LOGIN_INS_ACCOUNT_ACCESS, - LOGIN_GET_ACCOUNT_ID_BY_USERNAME, - LOGIN_GET_ACCOUNT_ACCESS_GMLEVEL, - LOGIN_GET_GMLEVEL_BY_REALMID, - LOGIN_GET_USERNAME_BY_ID, - LOGIN_SEL_CHECK_PASSWORD, - LOGIN_SEL_CHECK_PASSWORD_BY_NAME, - LOGIN_SEL_PINFO, - LOGIN_SEL_PINFO_BANS, - LOGIN_SEL_GM_ACCOUNTS, - LOGIN_SEL_ACCOUNT_INFO, - LOGIN_SEL_ACCOUNT_ACCESS_GMLEVEL_TEST, - LOGIN_SEL_ACCOUNT_ACCESS, - LOGIN_SEL_ACCOUNT_RECRUITER, - LOGIN_SEL_BANS, - LOGIN_SEL_ACCOUNT_WHOIS, - LOGIN_SEL_REALMLIST_SECURITY_LEVEL, - LOGIN_DEL_ACCOUNT, - LOGIN_SEL_IP2NATION_COUNTRY, - LOGIN_SEL_AUTOBROADCAST, - LOGIN_SEL_LAST_ATTEMPT_IP, - LOGIN_SEL_LAST_IP, - LOGIN_GET_EMAIL_BY_ID, - LOGIN_INS_ALDL_IP_LOGGING, - LOGIN_INS_FACL_IP_LOGGING, - LOGIN_INS_CHAR_IP_LOGGING, - LOGIN_INS_FALP_IP_LOGGING, - - LOGIN_SEL_ACCOUNT_ACCESS_BY_ID, - LOGIN_SEL_RBAC_ACCOUNT_PERMISSIONS, - LOGIN_INS_RBAC_ACCOUNT_PERMISSION, - LOGIN_DEL_RBAC_ACCOUNT_PERMISSION, - - LOGIN_INS_ACCOUNT_MUTE, - LOGIN_SEL_ACCOUNT_MUTE_INFO, - MAX_LOGINDATABASE_STATEMENTS -}; - -#endif diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp deleted file mode 100644 index d9aad94293e..00000000000 --- a/src/server/shared/Database/Implementation/WorldDatabase.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "WorldDatabase.h" - -void WorldDatabaseConnection::DoPrepareStatements() -{ - if (!m_reconnecting) - m_stmts.resize(MAX_WORLDDATABASE_STATEMENTS); - - PrepareStatement(WORLD_SEL_QUEST_POOLS, "SELECT entry, pool_entry FROM pool_quest", CONNECTION_SYNCH); - PrepareStatement(WORLD_DEL_CRELINKED_RESPAWN, "DELETE FROM linked_respawn WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_REP_CREATURE_LINKED_RESPAWN, "REPLACE INTO linked_respawn (guid, linkedGuid) VALUES (?, ?)", CONNECTION_ASYNC); - PrepareStatement(WORLD_SEL_CREATURE_TEXT, "SELECT entry, groupid, id, text, type, language, probability, emote, duration, sound, BroadcastTextId, TextRange FROM creature_text", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_SMART_SCRIPTS, "SELECT entryorguid, source_type, id, link, event_type, event_phase_mask, event_chance, event_flags, event_param1, event_param2, event_param3, event_param4, action_type, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, target_type, target_param1, target_param2, target_param3, target_x, target_y, target_z, target_o FROM smart_scripts ORDER BY entryorguid, source_type, id, link", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_SMARTAI_WP, "SELECT entry, pointid, position_x, position_y, position_z FROM waypoints ORDER BY entry, pointid", CONNECTION_SYNCH); - PrepareStatement(WORLD_DEL_GAMEOBJECT, "DELETE FROM gameobject WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_DEL_EVENT_GAMEOBJECT, "DELETE FROM game_event_gameobject WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_INS_GRAVEYARD_ZONE, "INSERT INTO game_graveyard_zone (id, ghost_zone, faction) VALUES (?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(WORLD_DEL_GRAVEYARD_ZONE, "DELETE FROM game_graveyard_zone WHERE id = ? AND ghost_zone = ? AND faction = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_INS_GAME_TELE, "INSERT INTO game_tele (id, position_x, position_y, position_z, orientation, map, name) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(WORLD_DEL_GAME_TELE, "DELETE FROM game_tele WHERE name = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_INS_NPC_VENDOR, "INSERT INTO npc_vendor (entry, item, maxcount, incrtime, extendedcost) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(WORLD_DEL_NPC_VENDOR, "DELETE FROM npc_vendor WHERE entry = ? AND item = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_SEL_NPC_VENDOR_REF, "SELECT item, maxcount, incrtime, ExtendedCost FROM npc_vendor WHERE entry = ? ORDER BY slot ASC", CONNECTION_SYNCH); - PrepareStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE, "UPDATE creature SET MovementType = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_CREATURE_FACTION, "UPDATE creature_template SET faction = ? WHERE entry = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_CREATURE_NPCFLAG, "UPDATE creature_template SET npcflag = ? WHERE entry = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_CREATURE_POSITION, "UPDATE creature SET position_x = ?, position_y = ?, position_z = ?, orientation = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_CREATURE_SPAWN_DISTANCE, "UPDATE creature SET spawndist = ?, MovementType = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_CREATURE_SPAWN_TIME_SECS, "UPDATE creature SET spawntimesecs = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_INS_CREATURE_FORMATION, "INSERT INTO creature_formations (leaderGUID, memberGUID, dist, angle, groupAI) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(WORLD_INS_WAYPOINT_DATA, "INSERT INTO waypoint_data (id, point, position_x, position_y, position_z) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(WORLD_DEL_WAYPOINT_DATA, "DELETE FROM waypoint_data WHERE id = ? AND point = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_WAYPOINT_DATA_POINT, "UPDATE waypoint_data SET point = point - 1 WHERE id = ? AND point > ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_WAYPOINT_DATA_POSITION, "UPDATE waypoint_data SET position_x = ?, position_y = ?, position_z = ? where id = ? AND point = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID, "UPDATE waypoint_data SET wpguid = ? WHERE id = ? and point = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_SEL_WAYPOINT_DATA_MAX_ID, "SELECT MAX(id) FROM waypoint_data", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_WAYPOINT_DATA_MAX_POINT, "SELECT MAX(point) FROM waypoint_data WHERE id = ?", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_WAYPOINT_DATA_BY_ID, "SELECT point, position_x, position_y, position_z, orientation, move_type, delay, action, action_chance FROM waypoint_data WHERE id = ? ORDER BY point", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_WAYPOINT_DATA_POS_BY_ID, "SELECT point, position_x, position_y, position_z FROM waypoint_data WHERE id = ?", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_WAYPOINT_DATA_POS_FIRST_BY_ID, "SELECT position_x, position_y, position_z FROM waypoint_data WHERE point = 1 AND id = ?", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_WAYPOINT_DATA_POS_LAST_BY_ID, "SELECT position_x, position_y, position_z, orientation FROM waypoint_data WHERE id = ? ORDER BY point DESC LIMIT 1", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_WAYPOINT_DATA_BY_WPGUID, "SELECT id, point FROM waypoint_data WHERE wpguid = ?", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_WAYPOINT_DATA_ALL_BY_WPGUID, "SELECT id, point, delay, move_type, action, action_chance FROM waypoint_data WHERE wpguid = ?", CONNECTION_SYNCH); - PrepareStatement(WORLD_UPD_WAYPOINT_DATA_ALL_WPGUID, "UPDATE waypoint_data SET wpguid = 0", CONNECTION_ASYNC); - PrepareStatement(WORLD_SEL_WAYPOINT_DATA_BY_POS, "SELECT id, point FROM waypoint_data WHERE (abs(position_x - ?) <= ?) and (abs(position_y - ?) <= ?) and (abs(position_z - ?) <= ?)", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_WAYPOINT_DATA_WPGUID_BY_ID, "SELECT wpguid FROM waypoint_data WHERE id = ? and wpguid <> 0", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_WAYPOINT_DATA_ACTION, "SELECT DISTINCT action FROM waypoint_data", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPTS_MAX_ID, "SELECT MAX(guid) FROM waypoint_scripts", CONNECTION_SYNCH); - PrepareStatement(WORLD_INS_CREATURE_ADDON, "INSERT INTO creature_addon(guid, path_id) VALUES (?, ?)", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_CREATURE_ADDON_PATH, "UPDATE creature_addon SET path_id = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_DEL_CREATURE_ADDON, "DELETE FROM creature_addon WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_SEL_CREATURE_ADDON_BY_GUID, "SELECT guid FROM creature_addon WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(WORLD_INS_WAYPOINT_SCRIPT, "INSERT INTO waypoint_scripts (guid) VALUES (?)", CONNECTION_ASYNC); - PrepareStatement(WORLD_DEL_WAYPOINT_SCRIPT, "DELETE FROM waypoint_scripts WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_WAYPOINT_SCRIPT_ID, "UPDATE waypoint_scripts SET id = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_WAYPOINT_SCRIPT_X, "UPDATE waypoint_scripts SET x = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_WAYPOINT_SCRIPT_Y, "UPDATE waypoint_scripts SET y = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_WAYPOINT_SCRIPT_Z, "UPDATE waypoint_scripts SET z = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_WAYPOINT_SCRIPT_O, "UPDATE waypoint_scripts SET o = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID, "SELECT id FROM waypoint_scripts WHERE guid = ?", CONNECTION_SYNCH); - PrepareStatement(WORLD_DEL_CREATURE, "DELETE FROM creature WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, permission, help FROM command", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction, npcflag, speed_walk, speed_run, scale, rank, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, HealthModifier, ManaModifier, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME, "SELECT entry FROM item_template WHERE name = ?", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_GAMEOBJECT_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM gameobject WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_CREATURE_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM creature WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_", CONNECTION_SYNCH); - PrepareStatement(WORLD_INS_CREATURE, "INSERT INTO creature (guid, id , map, spawnMask, phaseMask, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint, curhealth, curmana, MovementType, npcflag, unit_flags, dynamicflags) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(WORLD_DEL_GAME_EVENT_CREATURE, "DELETE FROM game_event_creature WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_DEL_GAME_EVENT_MODEL_EQUIP, "DELETE FROM game_event_model_equip WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_INS_GAMEOBJECT, "INSERT INTO gameobject (guid, id, map, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(WORLD_INS_DISABLES, "INSERT INTO disables (entry, sourceType, flags, comment) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC); - PrepareStatement(WORLD_SEL_DISABLES, "SELECT entry FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_SYNCH); - PrepareStatement(WORLD_DEL_DISABLES, "DELETE FROM disables WHERE entry = ? AND sourceType = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_CREATURE_ZONE_AREA_DATA, "UPDATE creature SET zoneId = ?, areaId = ? WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA, "UPDATE gameobject SET zoneId = ?, areaId = ? WHERE guid = ?", CONNECTION_ASYNC); -} diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h deleted file mode 100644 index 36fd6fbb186..00000000000 --- a/src/server/shared/Database/Implementation/WorldDatabase.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _WORLDDATABASE_H -#define _WORLDDATABASE_H - -#include "DatabaseWorkerPool.h" -#include "MySQLConnection.h" - -class WorldDatabaseConnection : public MySQLConnection -{ - public: - //- Constructors for sync and async connections - WorldDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo) { } - WorldDatabaseConnection(ProducerConsumerQueue<SQLOperation*>* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { } - - //- Loads database type specific prepared statements - void DoPrepareStatements() override; -}; - -typedef DatabaseWorkerPool<WorldDatabaseConnection> WorldDatabaseWorkerPool; - -enum WorldDatabaseStatements -{ - /* Naming standard for defines: - {DB}_{SEL/INS/UPD/DEL/REP}_{Summary of data changed} - When updating more than one field, consider looking at the calling function - name for a suiting suffix. - */ - - WORLD_SEL_QUEST_POOLS, - WORLD_DEL_CRELINKED_RESPAWN, - WORLD_REP_CREATURE_LINKED_RESPAWN, - WORLD_SEL_CREATURE_TEXT, - WORLD_SEL_SMART_SCRIPTS, - WORLD_SEL_SMARTAI_WP, - WORLD_DEL_GAMEOBJECT, - WORLD_DEL_EVENT_GAMEOBJECT, - WORLD_INS_GRAVEYARD_ZONE, - WORLD_DEL_GRAVEYARD_ZONE, - WORLD_INS_GAME_TELE, - WORLD_DEL_GAME_TELE, - WORLD_INS_NPC_VENDOR, - WORLD_DEL_NPC_VENDOR, - WORLD_SEL_NPC_VENDOR_REF, - WORLD_UPD_CREATURE_MOVEMENT_TYPE, - WORLD_UPD_CREATURE_FACTION, - WORLD_UPD_CREATURE_NPCFLAG, - WORLD_UPD_CREATURE_POSITION, - WORLD_UPD_CREATURE_SPAWN_DISTANCE, - WORLD_UPD_CREATURE_SPAWN_TIME_SECS, - WORLD_INS_CREATURE_FORMATION, - WORLD_INS_WAYPOINT_DATA, - WORLD_DEL_WAYPOINT_DATA, - WORLD_UPD_WAYPOINT_DATA_POINT, - WORLD_UPD_WAYPOINT_DATA_POSITION, - WORLD_UPD_WAYPOINT_DATA_WPGUID, - WORLD_UPD_WAYPOINT_DATA_ALL_WPGUID, - WORLD_SEL_WAYPOINT_DATA_MAX_ID, - WORLD_SEL_WAYPOINT_DATA_BY_ID, - WORLD_SEL_WAYPOINT_DATA_POS_BY_ID, - WORLD_SEL_WAYPOINT_DATA_POS_FIRST_BY_ID, - WORLD_SEL_WAYPOINT_DATA_POS_LAST_BY_ID, - WORLD_SEL_WAYPOINT_DATA_BY_WPGUID, - WORLD_SEL_WAYPOINT_DATA_ALL_BY_WPGUID, - WORLD_SEL_WAYPOINT_DATA_MAX_POINT, - WORLD_SEL_WAYPOINT_DATA_BY_POS, - WORLD_SEL_WAYPOINT_DATA_WPGUID_BY_ID, - WORLD_SEL_WAYPOINT_DATA_ACTION, - WORLD_SEL_WAYPOINT_SCRIPTS_MAX_ID, - WORLD_UPD_CREATURE_ADDON_PATH, - WORLD_INS_CREATURE_ADDON, - WORLD_DEL_CREATURE_ADDON, - WORLD_SEL_CREATURE_ADDON_BY_GUID, - WORLD_INS_WAYPOINT_SCRIPT, - WORLD_DEL_WAYPOINT_SCRIPT, - WORLD_UPD_WAYPOINT_SCRIPT_ID, - WORLD_UPD_WAYPOINT_SCRIPT_X, - WORLD_UPD_WAYPOINT_SCRIPT_Y, - WORLD_UPD_WAYPOINT_SCRIPT_Z, - WORLD_UPD_WAYPOINT_SCRIPT_O, - WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID, - WORLD_DEL_CREATURE, - WORLD_SEL_COMMANDS, - WORLD_SEL_CREATURE_TEMPLATE, - WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, - WORLD_SEL_ITEM_TEMPLATE_BY_NAME, - WORLD_SEL_CREATURE_BY_ID, - WORLD_SEL_GAMEOBJECT_NEAREST, - WORLD_SEL_CREATURE_NEAREST, - WORLD_SEL_GAMEOBJECT_TARGET, - WORLD_INS_CREATURE, - WORLD_DEL_GAME_EVENT_CREATURE, - WORLD_DEL_GAME_EVENT_MODEL_EQUIP, - WORLD_INS_GAMEOBJECT, - WORLD_SEL_DISABLES, - WORLD_INS_DISABLES, - WORLD_DEL_DISABLES, - WORLD_UPD_CREATURE_ZONE_AREA_DATA, - WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA, - - MAX_WORLDDATABASE_STATEMENTS -}; - -#endif diff --git a/src/server/shared/Database/MySQLConnection.cpp b/src/server/shared/Database/MySQLConnection.cpp deleted file mode 100644 index 10f4a7baa18..00000000000 --- a/src/server/shared/Database/MySQLConnection.cpp +++ /dev/null @@ -1,542 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - - -#include "Common.h" - -#ifdef _WIN32 - #include <winsock2.h> -#endif -#include <mysql.h> -#include <errmsg.h> - -#include "MySQLConnection.h" -#include "QueryResult.h" -#include "SQLOperation.h" -#include "PreparedStatement.h" -#include "DatabaseWorker.h" -#include "Timer.h" -#include "Log.h" -#include "ProducerConsumerQueue.h" - -MySQLConnection::MySQLConnection(MySQLConnectionInfo& connInfo) : -m_reconnecting(false), -m_prepareError(false), -m_queue(NULL), -m_worker(NULL), -m_Mysql(NULL), -m_connectionInfo(connInfo), -m_connectionFlags(CONNECTION_SYNCH) { } - -MySQLConnection::MySQLConnection(ProducerConsumerQueue<SQLOperation*>* queue, MySQLConnectionInfo& connInfo) : -m_reconnecting(false), -m_prepareError(false), -m_queue(queue), -m_Mysql(NULL), -m_connectionInfo(connInfo), -m_connectionFlags(CONNECTION_ASYNC) -{ - m_worker = new DatabaseWorker(m_queue, this); -} - -MySQLConnection::~MySQLConnection() -{ - delete m_worker; - - for (size_t i = 0; i < m_stmts.size(); ++i) - delete m_stmts[i]; - - if (m_Mysql) - mysql_close(m_Mysql); -} - -void MySQLConnection::Close() -{ - /// Only close us if we're not operating - delete this; -} - -uint32 MySQLConnection::Open() -{ - MYSQL *mysqlInit; - mysqlInit = mysql_init(NULL); - if (!mysqlInit) - { - TC_LOG_ERROR("sql.sql", "Could not initialize Mysql connection to database `%s`", m_connectionInfo.database.c_str()); - return CR_UNKNOWN_ERROR; - } - - int port; - char const* unix_socket; - //unsigned int timeout = 10; - - mysql_options(mysqlInit, MYSQL_SET_CHARSET_NAME, "utf8"); - //mysql_options(mysqlInit, MYSQL_OPT_READ_TIMEOUT, (char const*)&timeout); - #ifdef _WIN32 - if (m_connectionInfo.host == ".") // named pipe use option (Windows) - { - unsigned int opt = MYSQL_PROTOCOL_PIPE; - mysql_options(mysqlInit, MYSQL_OPT_PROTOCOL, (char const*)&opt); - port = 0; - unix_socket = 0; - } - else // generic case - { - port = atoi(m_connectionInfo.port_or_socket.c_str()); - unix_socket = 0; - } - #else - if (m_connectionInfo.host == ".") // socket use option (Unix/Linux) - { - unsigned int opt = MYSQL_PROTOCOL_SOCKET; - mysql_options(mysqlInit, MYSQL_OPT_PROTOCOL, (char const*)&opt); - m_connectionInfo.host = "localhost"; - port = 0; - unix_socket = m_connectionInfo.port_or_socket.c_str(); - } - else // generic case - { - port = atoi(m_connectionInfo.port_or_socket.c_str()); - unix_socket = nullptr; - } - #endif - - m_Mysql = mysql_real_connect(mysqlInit, m_connectionInfo.host.c_str(), m_connectionInfo.user.c_str(), - m_connectionInfo.password.c_str(), m_connectionInfo.database.c_str(), port, unix_socket, 0); - - if (m_Mysql) - { - if (!m_reconnecting) - { - TC_LOG_INFO("sql.sql", "MySQL client library: %s", mysql_get_client_info()); - TC_LOG_INFO("sql.sql", "MySQL server ver: %s ", mysql_get_server_info(m_Mysql)); - // MySQL version above 5.1 IS required in both client and server and there is no known issue with different versions above 5.1 - // if (mysql_get_server_version(m_Mysql) != mysql_get_client_version()) - // TC_LOG_INFO("sql.sql", "[WARNING] MySQL client/server version mismatch; may conflict with behaviour of prepared statements."); - } - - TC_LOG_INFO("sql.sql", "Connected to MySQL database at %s", m_connectionInfo.host.c_str()); - mysql_autocommit(m_Mysql, 1); - - // set connection properties to UTF8 to properly handle locales for different - // server configs - core sends data in UTF8, so MySQL must expect UTF8 too - mysql_set_character_set(m_Mysql, "utf8"); - return 0; - } - else - { - TC_LOG_ERROR("sql.sql", "Could not connect to MySQL database at %s: %s", m_connectionInfo.host.c_str(), mysql_error(mysqlInit)); - mysql_close(mysqlInit); - return mysql_errno(mysqlInit); - } -} - -bool MySQLConnection::PrepareStatements() -{ - DoPrepareStatements(); - return !m_prepareError; -} - -bool MySQLConnection::Execute(const char* sql) -{ - if (!m_Mysql) - return false; - - { - uint32 _s = getMSTime(); - - if (mysql_query(m_Mysql, sql)) - { - uint32 lErrno = mysql_errno(m_Mysql); - - TC_LOG_INFO("sql.sql", "SQL: %s", sql); - TC_LOG_ERROR("sql.sql", "[%u] %s", lErrno, mysql_error(m_Mysql)); - - if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection) - return Execute(sql); // Try again - - return false; - } - else - TC_LOG_DEBUG("sql.sql", "[%u ms] SQL: %s", getMSTimeDiff(_s, getMSTime()), sql); - } - - return true; -} - -bool MySQLConnection::Execute(PreparedStatement* stmt) -{ - if (!m_Mysql) - return false; - - uint32 index = stmt->m_index; - { - MySQLPreparedStatement* m_mStmt = GetPreparedStatement(index); - ASSERT(m_mStmt); // Can only be null if preparation failed, server side error or bad query - m_mStmt->m_stmt = stmt; // Cross reference them for debug output - stmt->m_stmt = m_mStmt; /// @todo Cleaner way - - stmt->BindParameters(); - - MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT(); - MYSQL_BIND* msql_BIND = m_mStmt->GetBind(); - - uint32 _s = getMSTime(); - - if (mysql_stmt_bind_param(msql_STMT, msql_BIND)) - { - uint32 lErrno = mysql_errno(m_Mysql); - TC_LOG_ERROR("sql.sql", "SQL(p): %s\n [ERROR]: [%u] %s", m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT)); - - if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection) - return Execute(stmt); // Try again - - m_mStmt->ClearParameters(); - return false; - } - - if (mysql_stmt_execute(msql_STMT)) - { - uint32 lErrno = mysql_errno(m_Mysql); - TC_LOG_ERROR("sql.sql", "SQL(p): %s\n [ERROR]: [%u] %s", m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT)); - - if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection) - return Execute(stmt); // Try again - - m_mStmt->ClearParameters(); - return false; - } - - TC_LOG_DEBUG("sql.sql", "[%u ms] SQL(p): %s", getMSTimeDiff(_s, getMSTime()), m_mStmt->getQueryString(m_queries[index].first).c_str()); - - m_mStmt->ClearParameters(); - return true; - } -} - -bool MySQLConnection::_Query(PreparedStatement* stmt, MYSQL_RES **pResult, uint64* pRowCount, uint32* pFieldCount) -{ - if (!m_Mysql) - return false; - - uint32 index = stmt->m_index; - { - MySQLPreparedStatement* m_mStmt = GetPreparedStatement(index); - ASSERT(m_mStmt); // Can only be null if preparation failed, server side error or bad query - m_mStmt->m_stmt = stmt; // Cross reference them for debug output - stmt->m_stmt = m_mStmt; /// @todo Cleaner way - - stmt->BindParameters(); - - MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT(); - MYSQL_BIND* msql_BIND = m_mStmt->GetBind(); - - uint32 _s = getMSTime(); - - if (mysql_stmt_bind_param(msql_STMT, msql_BIND)) - { - uint32 lErrno = mysql_errno(m_Mysql); - TC_LOG_ERROR("sql.sql", "SQL(p): %s\n [ERROR]: [%u] %s", m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT)); - - if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection) - return _Query(stmt, pResult, pRowCount, pFieldCount); // Try again - - m_mStmt->ClearParameters(); - return false; - } - - if (mysql_stmt_execute(msql_STMT)) - { - uint32 lErrno = mysql_errno(m_Mysql); - TC_LOG_ERROR("sql.sql", "SQL(p): %s\n [ERROR]: [%u] %s", - m_mStmt->getQueryString(m_queries[index].first).c_str(), lErrno, mysql_stmt_error(msql_STMT)); - - if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection) - return _Query(stmt, pResult, pRowCount, pFieldCount); // Try again - - m_mStmt->ClearParameters(); - return false; - } - - TC_LOG_DEBUG("sql.sql", "[%u ms] SQL(p): %s", getMSTimeDiff(_s, getMSTime()), m_mStmt->getQueryString(m_queries[index].first).c_str()); - - m_mStmt->ClearParameters(); - - *pResult = mysql_stmt_result_metadata(msql_STMT); - *pRowCount = mysql_stmt_num_rows(msql_STMT); - *pFieldCount = mysql_stmt_field_count(msql_STMT); - - return true; - - } -} - -ResultSet* MySQLConnection::Query(const char* sql) -{ - if (!sql) - return NULL; - - MYSQL_RES *result = NULL; - MYSQL_FIELD *fields = NULL; - uint64 rowCount = 0; - uint32 fieldCount = 0; - - if (!_Query(sql, &result, &fields, &rowCount, &fieldCount)) - return NULL; - - return new ResultSet(result, fields, rowCount, fieldCount); -} - -bool MySQLConnection::_Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount) -{ - if (!m_Mysql) - return false; - - { - uint32 _s = getMSTime(); - - if (mysql_query(m_Mysql, sql)) - { - uint32 lErrno = mysql_errno(m_Mysql); - TC_LOG_INFO("sql.sql", "SQL: %s", sql); - TC_LOG_ERROR("sql.sql", "[%u] %s", lErrno, mysql_error(m_Mysql)); - - if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection) - return _Query(sql, pResult, pFields, pRowCount, pFieldCount); // We try again - - return false; - } - else - TC_LOG_DEBUG("sql.sql", "[%u ms] SQL: %s", getMSTimeDiff(_s, getMSTime()), sql); - - *pResult = mysql_store_result(m_Mysql); - *pRowCount = mysql_affected_rows(m_Mysql); - *pFieldCount = mysql_field_count(m_Mysql); - } - - if (!*pResult ) - return false; - - if (!*pRowCount) - { - mysql_free_result(*pResult); - return false; - } - - *pFields = mysql_fetch_fields(*pResult); - - return true; -} - -void MySQLConnection::BeginTransaction() -{ - Execute("START TRANSACTION"); -} - -void MySQLConnection::RollbackTransaction() -{ - Execute("ROLLBACK"); -} - -void MySQLConnection::CommitTransaction() -{ - Execute("COMMIT"); -} - -int MySQLConnection::ExecuteTransaction(SQLTransaction& transaction) -{ - std::list<SQLElementData> const& queries = transaction->m_queries; - if (queries.empty()) - return -1; - - BeginTransaction(); - - std::list<SQLElementData>::const_iterator itr; - for (itr = queries.begin(); itr != queries.end(); ++itr) - { - SQLElementData const& data = *itr; - switch (itr->type) - { - case SQL_ELEMENT_PREPARED: - { - PreparedStatement* stmt = data.element.stmt; - ASSERT(stmt); - if (!Execute(stmt)) - { - TC_LOG_WARN("sql.sql", "Transaction aborted. %u queries not executed.", (uint32)queries.size()); - int errorCode = GetLastError(); - RollbackTransaction(); - return errorCode; - } - } - break; - case SQL_ELEMENT_RAW: - { - const char* sql = data.element.query; - ASSERT(sql); - if (!Execute(sql)) - { - TC_LOG_WARN("sql.sql", "Transaction aborted. %u queries not executed.", (uint32)queries.size()); - int errorCode = GetLastError(); - RollbackTransaction(); - return errorCode; - } - } - break; - } - } - - // we might encounter errors during certain queries, and depending on the kind of error - // we might want to restart the transaction. So to prevent data loss, we only clean up when it's all done. - // This is done in calling functions DatabaseWorkerPool<T>::DirectCommitTransaction and TransactionTask::Execute, - // and not while iterating over every element. - - CommitTransaction(); - return 0; -} - -MySQLPreparedStatement* MySQLConnection::GetPreparedStatement(uint32 index) -{ - ASSERT(index < m_stmts.size()); - MySQLPreparedStatement* ret = m_stmts[index]; - if (!ret) - TC_LOG_ERROR("sql.sql", "Could not fetch prepared statement %u on database `%s`, connection type: %s.", - index, m_connectionInfo.database.c_str(), (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous"); - - return ret; -} - -void MySQLConnection::PrepareStatement(uint32 index, const char* sql, ConnectionFlags flags) -{ - m_queries.insert(PreparedStatementMap::value_type(index, std::make_pair(sql, flags))); - - // For reconnection case - if (m_reconnecting) - delete m_stmts[index]; - - // Check if specified query should be prepared on this connection - // i.e. don't prepare async statements on synchronous connections - // to save memory that will not be used. - if (!(m_connectionFlags & flags)) - { - m_stmts[index] = NULL; - return; - } - - MYSQL_STMT* stmt = mysql_stmt_init(m_Mysql); - if (!stmt) - { - TC_LOG_ERROR("sql.sql", "In mysql_stmt_init() id: %u, sql: \"%s\"", index, sql); - TC_LOG_ERROR("sql.sql", "%s", mysql_error(m_Mysql)); - m_prepareError = true; - } - else - { - if (mysql_stmt_prepare(stmt, sql, static_cast<unsigned long>(strlen(sql)))) - { - TC_LOG_ERROR("sql.sql", "In mysql_stmt_prepare() id: %u, sql: \"%s\"", index, sql); - TC_LOG_ERROR("sql.sql", "%s", mysql_stmt_error(stmt)); - mysql_stmt_close(stmt); - m_prepareError = true; - } - else - { - MySQLPreparedStatement* mStmt = new MySQLPreparedStatement(stmt); - m_stmts[index] = mStmt; - } - } -} - -PreparedResultSet* MySQLConnection::Query(PreparedStatement* stmt) -{ - MYSQL_RES *result = NULL; - uint64 rowCount = 0; - uint32 fieldCount = 0; - - if (!_Query(stmt, &result, &rowCount, &fieldCount)) - return NULL; - - if (mysql_more_results(m_Mysql)) - { - mysql_next_result(m_Mysql); - } - return new PreparedResultSet(stmt->m_stmt->GetSTMT(), result, rowCount, fieldCount); -} - -bool MySQLConnection::_HandleMySQLErrno(uint32 errNo) -{ - switch (errNo) - { - case CR_SERVER_GONE_ERROR: - case CR_SERVER_LOST: - case CR_INVALID_CONN_HANDLE: - case CR_SERVER_LOST_EXTENDED: - { - m_reconnecting = true; - uint64 oldThreadId = mysql_thread_id(GetHandle()); - mysql_close(GetHandle()); - - uint32 const lErrno = Open(); - if (!lErrno) - { - // Don't remove 'this' pointer unless you want to skip loading all prepared statements... - if (!this->PrepareStatements()) - { - TC_LOG_ERROR("sql.sql", "Could not re-prepare statements!"); - Close(); - return false; - } - - TC_LOG_INFO("sql.sql", "Connection to the MySQL server is active."); - if (oldThreadId != mysql_thread_id(GetHandle())) - TC_LOG_INFO("sql.sql", "Successfully reconnected to %s @%s:%s (%s).", - m_connectionInfo.database.c_str(), m_connectionInfo.host.c_str(), m_connectionInfo.port_or_socket.c_str(), - (m_connectionFlags & CONNECTION_ASYNC) ? "asynchronous" : "synchronous"); - - m_reconnecting = false; - return true; - } - - // It's possible this attempted reconnect throws 2006 at us. To prevent crazy recursive calls, sleep here. - std::this_thread::sleep_for(std::chrono::seconds(3)); // Sleep 3 seconds - return _HandleMySQLErrno(lErrno); // Call self (recursive) - } - - case ER_LOCK_DEADLOCK: - return false; // Implemented in TransactionTask::Execute and DatabaseWorkerPool<T>::DirectCommitTransaction - // Query related errors - skip query - case ER_WRONG_VALUE_COUNT: - case ER_DUP_ENTRY: - return false; - - // Outdated table or database structure - terminate core - case ER_BAD_FIELD_ERROR: - case ER_NO_SUCH_TABLE: - TC_LOG_ERROR("sql.sql", "Your database structure is not up to date. Please make sure you've executed all queries in the sql/updates folders."); - std::this_thread::sleep_for(std::chrono::seconds(10)); - std::abort(); - return false; - case ER_PARSE_ERROR: - TC_LOG_ERROR("sql.sql", "Error while parsing SQL. Core fix required."); - std::this_thread::sleep_for(std::chrono::seconds(10)); - std::abort(); - return false; - default: - TC_LOG_ERROR("sql.sql", "Unhandled MySQL errno %u. Unexpected behaviour possible.", errNo); - return false; - } -} diff --git a/src/server/shared/Database/MySQLConnection.h b/src/server/shared/Database/MySQLConnection.h deleted file mode 100644 index 78d8d2fb5dd..00000000000 --- a/src/server/shared/Database/MySQLConnection.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "DatabaseWorkerPool.h" -#include "Transaction.h" -#include "Util.h" -#include "ProducerConsumerQueue.h" - -#ifndef _MYSQLCONNECTION_H -#define _MYSQLCONNECTION_H - -class DatabaseWorker; -class PreparedStatement; -class MySQLPreparedStatement; -class PingOperation; - -enum ConnectionFlags -{ - CONNECTION_ASYNC = 0x1, - CONNECTION_SYNCH = 0x2, - CONNECTION_BOTH = CONNECTION_ASYNC | CONNECTION_SYNCH -}; - -struct MySQLConnectionInfo -{ - explicit MySQLConnectionInfo(std::string const& infoString) - { - Tokenizer tokens(infoString, ';'); - - if (tokens.size() != 5) - return; - - uint8 i = 0; - - host.assign(tokens[i++]); - port_or_socket.assign(tokens[i++]); - user.assign(tokens[i++]); - password.assign(tokens[i++]); - database.assign(tokens[i++]); - } - - std::string user; - std::string password; - std::string database; - std::string host; - std::string port_or_socket; -}; - -typedef std::map<uint32 /*index*/, std::pair<std::string /*query*/, ConnectionFlags /*sync/async*/> > PreparedStatementMap; - -class MySQLConnection -{ - template <class T> friend class DatabaseWorkerPool; - friend class PingOperation; - - public: - MySQLConnection(MySQLConnectionInfo& connInfo); //! Constructor for synchronous connections. - MySQLConnection(ProducerConsumerQueue<SQLOperation*>* queue, MySQLConnectionInfo& connInfo); //! Constructor for asynchronous connections. - virtual ~MySQLConnection(); - - virtual uint32 Open(); - void Close(); - - bool PrepareStatements(); - - public: - bool Execute(const char* sql); - bool Execute(PreparedStatement* stmt); - ResultSet* Query(const char* sql); - PreparedResultSet* Query(PreparedStatement* stmt); - bool _Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount); - bool _Query(PreparedStatement* stmt, MYSQL_RES **pResult, uint64* pRowCount, uint32* pFieldCount); - - void BeginTransaction(); - void RollbackTransaction(); - void CommitTransaction(); - int ExecuteTransaction(SQLTransaction& transaction); - - operator bool () const { return m_Mysql != NULL; } - void Ping() { mysql_ping(m_Mysql); } - - uint32 GetLastError() { return mysql_errno(m_Mysql); } - - protected: - bool LockIfReady() - { - /// Tries to acquire lock. If lock is acquired by another thread - /// the calling parent will just try another connection - return m_Mutex.try_lock(); - } - - void Unlock() - { - /// Called by parent databasepool. Will let other threads access this connection - m_Mutex.unlock(); - } - - MYSQL* GetHandle() { return m_Mysql; } - MySQLPreparedStatement* GetPreparedStatement(uint32 index); - void PrepareStatement(uint32 index, const char* sql, ConnectionFlags flags); - - virtual void DoPrepareStatements() = 0; - - protected: - std::vector<MySQLPreparedStatement*> m_stmts; //! PreparedStatements storage - PreparedStatementMap m_queries; //! Query storage - bool m_reconnecting; //! Are we reconnecting? - bool m_prepareError; //! Was there any error while preparing statements? - - private: - bool _HandleMySQLErrno(uint32 errNo); - - private: - ProducerConsumerQueue<SQLOperation*>* m_queue; //! Queue shared with other asynchronous connections. - DatabaseWorker* m_worker; //! Core worker task. - MYSQL * m_Mysql; //! MySQL Handle. - MySQLConnectionInfo& m_connectionInfo; //! Connection info (used for logging) - ConnectionFlags m_connectionFlags; //! Connection flags (for preparing relevant statements) - std::mutex m_Mutex; - - MySQLConnection(MySQLConnection const& right) = delete; - MySQLConnection& operator=(MySQLConnection const& right) = delete; -}; - -#endif diff --git a/src/server/shared/Database/MySQLThreading.h b/src/server/shared/Database/MySQLThreading.h deleted file mode 100644 index 441f30cb6ec..00000000000 --- a/src/server/shared/Database/MySQLThreading.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _MYSQLTHREADING_H -#define _MYSQLTHREADING_H - -#include "Log.h" - -class MySQL -{ - public: - static void Library_Init() - { - mysql_library_init(-1, NULL, NULL); - } - - static void Library_End() - { - mysql_library_end(); - } -}; - -#endif diff --git a/src/server/shared/Database/PreparedStatement.cpp b/src/server/shared/Database/PreparedStatement.cpp deleted file mode 100644 index 1938005c712..00000000000 --- a/src/server/shared/Database/PreparedStatement.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "PreparedStatement.h" -#include "MySQLConnection.h" -#include "Log.h" - -PreparedStatement::PreparedStatement(uint32 index) : -m_stmt(NULL), -m_index(index) { } - -PreparedStatement::~PreparedStatement() { } - -void PreparedStatement::BindParameters() -{ - ASSERT (m_stmt); - - uint8 i = 0; - for (; i < statement_data.size(); i++) - { - switch (statement_data[i].type) - { - case TYPE_BOOL: - m_stmt->setBool(i, statement_data[i].data.boolean); - break; - case TYPE_UI8: - m_stmt->setUInt8(i, statement_data[i].data.ui8); - break; - case TYPE_UI16: - m_stmt->setUInt16(i, statement_data[i].data.ui16); - break; - case TYPE_UI32: - m_stmt->setUInt32(i, statement_data[i].data.ui32); - break; - case TYPE_I8: - m_stmt->setInt8(i, statement_data[i].data.i8); - break; - case TYPE_I16: - m_stmt->setInt16(i, statement_data[i].data.i16); - break; - case TYPE_I32: - m_stmt->setInt32(i, statement_data[i].data.i32); - break; - case TYPE_UI64: - m_stmt->setUInt64(i, statement_data[i].data.ui64); - break; - case TYPE_I64: - m_stmt->setInt64(i, statement_data[i].data.i64); - break; - case TYPE_FLOAT: - m_stmt->setFloat(i, statement_data[i].data.f); - break; - case TYPE_DOUBLE: - m_stmt->setDouble(i, statement_data[i].data.d); - break; - case TYPE_STRING: - m_stmt->setString(i, statement_data[i].str.c_str()); - break; - case TYPE_NULL: - m_stmt->setNull(i); - break; - } - } - #ifdef _DEBUG - if (i < m_stmt->m_paramCount) - TC_LOG_WARN("sql.sql", "[WARNING]: BindParameters() for statement %u did not bind all allocated parameters", m_index); - #endif -} - -//- Bind to buffer -void PreparedStatement::setBool(const uint8 index, const bool value) -{ - if (index >= statement_data.size()) - statement_data.resize(index+1); - - statement_data[index].data.boolean = value; - statement_data[index].type = TYPE_BOOL; -} - -void PreparedStatement::setUInt8(const uint8 index, const uint8 value) -{ - if (index >= statement_data.size()) - statement_data.resize(index+1); - - statement_data[index].data.ui8 = value; - statement_data[index].type = TYPE_UI8; -} - -void PreparedStatement::setUInt16(const uint8 index, const uint16 value) -{ - if (index >= statement_data.size()) - statement_data.resize(index+1); - - statement_data[index].data.ui16 = value; - statement_data[index].type = TYPE_UI16; -} - -void PreparedStatement::setUInt32(const uint8 index, const uint32 value) -{ - if (index >= statement_data.size()) - statement_data.resize(index+1); - - statement_data[index].data.ui32 = value; - statement_data[index].type = TYPE_UI32; -} - -void PreparedStatement::setUInt64(const uint8 index, const uint64 value) -{ - if (index >= statement_data.size()) - statement_data.resize(index+1); - - statement_data[index].data.ui64 = value; - statement_data[index].type = TYPE_UI64; -} - -void PreparedStatement::setInt8(const uint8 index, const int8 value) -{ - if (index >= statement_data.size()) - statement_data.resize(index+1); - - statement_data[index].data.i8 = value; - statement_data[index].type = TYPE_I8; -} - -void PreparedStatement::setInt16(const uint8 index, const int16 value) -{ - if (index >= statement_data.size()) - statement_data.resize(index+1); - - statement_data[index].data.i16 = value; - statement_data[index].type = TYPE_I16; -} - -void PreparedStatement::setInt32(const uint8 index, const int32 value) -{ - if (index >= statement_data.size()) - statement_data.resize(index+1); - - statement_data[index].data.i32 = value; - statement_data[index].type = TYPE_I32; -} - -void PreparedStatement::setInt64(const uint8 index, const int64 value) -{ - if (index >= statement_data.size()) - statement_data.resize(index+1); - - statement_data[index].data.i64 = value; - statement_data[index].type = TYPE_I64; -} - -void PreparedStatement::setFloat(const uint8 index, const float value) -{ - if (index >= statement_data.size()) - statement_data.resize(index+1); - - statement_data[index].data.f = value; - statement_data[index].type = TYPE_FLOAT; -} - -void PreparedStatement::setDouble(const uint8 index, const double value) -{ - if (index >= statement_data.size()) - statement_data.resize(index+1); - - statement_data[index].data.d = value; - statement_data[index].type = TYPE_DOUBLE; -} - -void PreparedStatement::setString(const uint8 index, const std::string& value) -{ - if (index >= statement_data.size()) - statement_data.resize(index+1); - - statement_data[index].str = value; - statement_data[index].type = TYPE_STRING; -} - -void PreparedStatement::setNull(const uint8 index) -{ - if (index >= statement_data.size()) - statement_data.resize(index+1); - - statement_data[index].type = TYPE_NULL; -} - -MySQLPreparedStatement::MySQLPreparedStatement(MYSQL_STMT* stmt) : -m_stmt(NULL), -m_Mstmt(stmt), -m_bind(NULL) -{ - /// Initialize variable parameters - m_paramCount = mysql_stmt_param_count(stmt); - m_paramsSet.assign(m_paramCount, false); - m_bind = new MYSQL_BIND[m_paramCount]; - memset(m_bind, 0, sizeof(MYSQL_BIND)*m_paramCount); - - /// "If set to 1, causes mysql_stmt_store_result() to update the metadata MYSQL_FIELD->max_length value." - my_bool bool_tmp = 1; - mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &bool_tmp); -} - -MySQLPreparedStatement::~MySQLPreparedStatement() -{ - ClearParameters(); - if (m_Mstmt->bind_result_done) - { - delete[] m_Mstmt->bind->length; - delete[] m_Mstmt->bind->is_null; - } - mysql_stmt_close(m_Mstmt); - delete[] m_bind; -} - -void MySQLPreparedStatement::ClearParameters() -{ - for (uint32 i=0; i < m_paramCount; ++i) - { - delete m_bind[i].length; - m_bind[i].length = NULL; - delete[] (char*) m_bind[i].buffer; - m_bind[i].buffer = NULL; - m_paramsSet[i] = false; - } -} - -static bool ParamenterIndexAssertFail(uint32 stmtIndex, uint8 index, uint32 paramCount) -{ - TC_LOG_ERROR("sql.driver", "Attempted to bind parameter %u%s on a PreparedStatement %u (statement has only %u parameters)", uint32(index) + 1, (index == 1 ? "st" : (index == 2 ? "nd" : (index == 3 ? "rd" : "nd"))), stmtIndex, paramCount); - return false; -} - -//- Bind on mysql level -bool MySQLPreparedStatement::CheckValidIndex(uint8 index) -{ - ASSERT(index < m_paramCount || ParamenterIndexAssertFail(m_stmt->m_index, index, m_paramCount)); - - if (m_paramsSet[index]) - TC_LOG_WARN("sql.sql", "[WARNING] Prepared Statement (id: %u) trying to bind value on already bound index (%u).", m_stmt->m_index, index); - return true; -} - -void MySQLPreparedStatement::setBool(const uint8 index, const bool value) -{ - setUInt8(index, value ? 1 : 0); -} - -void MySQLPreparedStatement::setUInt8(const uint8 index, const uint8 value) -{ - CheckValidIndex(index); - m_paramsSet[index] = true; - MYSQL_BIND* param = &m_bind[index]; - setValue(param, MYSQL_TYPE_TINY, &value, sizeof(uint8), true); -} - -void MySQLPreparedStatement::setUInt16(const uint8 index, const uint16 value) -{ - CheckValidIndex(index); - m_paramsSet[index] = true; - MYSQL_BIND* param = &m_bind[index]; - setValue(param, MYSQL_TYPE_SHORT, &value, sizeof(uint16), true); -} - -void MySQLPreparedStatement::setUInt32(const uint8 index, const uint32 value) -{ - CheckValidIndex(index); - m_paramsSet[index] = true; - MYSQL_BIND* param = &m_bind[index]; - setValue(param, MYSQL_TYPE_LONG, &value, sizeof(uint32), true); -} - -void MySQLPreparedStatement::setUInt64(const uint8 index, const uint64 value) -{ - CheckValidIndex(index); - m_paramsSet[index] = true; - MYSQL_BIND* param = &m_bind[index]; - setValue(param, MYSQL_TYPE_LONGLONG, &value, sizeof(uint64), true); -} - -void MySQLPreparedStatement::setInt8(const uint8 index, const int8 value) -{ - CheckValidIndex(index); - m_paramsSet[index] = true; - MYSQL_BIND* param = &m_bind[index]; - setValue(param, MYSQL_TYPE_TINY, &value, sizeof(int8), false); -} - -void MySQLPreparedStatement::setInt16(const uint8 index, const int16 value) -{ - CheckValidIndex(index); - m_paramsSet[index] = true; - MYSQL_BIND* param = &m_bind[index]; - setValue(param, MYSQL_TYPE_SHORT, &value, sizeof(int16), false); -} - -void MySQLPreparedStatement::setInt32(const uint8 index, const int32 value) -{ - CheckValidIndex(index); - m_paramsSet[index] = true; - MYSQL_BIND* param = &m_bind[index]; - setValue(param, MYSQL_TYPE_LONG, &value, sizeof(int32), false); -} - -void MySQLPreparedStatement::setInt64(const uint8 index, const int64 value) -{ - CheckValidIndex(index); - m_paramsSet[index] = true; - MYSQL_BIND* param = &m_bind[index]; - setValue(param, MYSQL_TYPE_LONGLONG, &value, sizeof(int64), false); -} - -void MySQLPreparedStatement::setFloat(const uint8 index, const float value) -{ - CheckValidIndex(index); - m_paramsSet[index] = true; - MYSQL_BIND* param = &m_bind[index]; - setValue(param, MYSQL_TYPE_FLOAT, &value, sizeof(float), (value > 0.0f)); -} - -void MySQLPreparedStatement::setDouble(const uint8 index, const double value) -{ - CheckValidIndex(index); - m_paramsSet[index] = true; - MYSQL_BIND* param = &m_bind[index]; - setValue(param, MYSQL_TYPE_DOUBLE, &value, sizeof(double), (value > 0.0f)); -} - -void MySQLPreparedStatement::setString(const uint8 index, const char* value) -{ - CheckValidIndex(index); - m_paramsSet[index] = true; - MYSQL_BIND* param = &m_bind[index]; - size_t len = strlen(value) + 1; - param->buffer_type = MYSQL_TYPE_VAR_STRING; - delete [] static_cast<char *>(param->buffer); - param->buffer = new char[len]; - param->buffer_length = len; - param->is_null_value = 0; - delete param->length; - param->length = new unsigned long(len-1); - - memcpy(param->buffer, value, len); -} - -void MySQLPreparedStatement::setNull(const uint8 index) -{ - CheckValidIndex(index); - m_paramsSet[index] = true; - MYSQL_BIND* param = &m_bind[index]; - param->buffer_type = MYSQL_TYPE_NULL; - delete [] static_cast<char *>(param->buffer); - param->buffer = NULL; - param->buffer_length = 0; - param->is_null_value = 1; - delete param->length; - param->length = NULL; -} - -void MySQLPreparedStatement::setValue(MYSQL_BIND* param, enum_field_types type, const void* value, uint32 len, bool isUnsigned) -{ - param->buffer_type = type; - delete [] static_cast<char *>(param->buffer); - param->buffer = new char[len]; - param->buffer_length = 0; - param->is_null_value = 0; - param->length = NULL; // Only != NULL for strings - param->is_unsigned = isUnsigned; - - memcpy(param->buffer, value, len); -} - -std::string MySQLPreparedStatement::getQueryString(std::string const& sqlPattern) const -{ - std::string queryString = sqlPattern; - - size_t pos = 0; - for (uint32 i = 0; i < m_stmt->statement_data.size(); i++) - { - pos = queryString.find('?', pos); - std::stringstream ss; - - switch (m_stmt->statement_data[i].type) - { - case TYPE_BOOL: - ss << uint16(m_stmt->statement_data[i].data.boolean); - break; - case TYPE_UI8: - ss << uint16(m_stmt->statement_data[i].data.ui8); // stringstream will append a character with that code instead of numeric representation - break; - case TYPE_UI16: - ss << m_stmt->statement_data[i].data.ui16; - break; - case TYPE_UI32: - ss << m_stmt->statement_data[i].data.ui32; - break; - case TYPE_I8: - ss << int16(m_stmt->statement_data[i].data.i8); // stringstream will append a character with that code instead of numeric representation - break; - case TYPE_I16: - ss << m_stmt->statement_data[i].data.i16; - break; - case TYPE_I32: - ss << m_stmt->statement_data[i].data.i32; - break; - case TYPE_UI64: - ss << m_stmt->statement_data[i].data.ui64; - break; - case TYPE_I64: - ss << m_stmt->statement_data[i].data.i64; - break; - case TYPE_FLOAT: - ss << m_stmt->statement_data[i].data.f; - break; - case TYPE_DOUBLE: - ss << m_stmt->statement_data[i].data.d; - break; - case TYPE_STRING: - ss << '\'' << m_stmt->statement_data[i].str << '\''; - break; - case TYPE_NULL: - ss << "NULL"; - break; - } - - std::string replaceStr = ss.str(); - queryString.replace(pos, 1, replaceStr); - pos += replaceStr.length(); - } - - return queryString; -} - -//- Execution -PreparedStatementTask::PreparedStatementTask(PreparedStatement* stmt, bool async) : -m_stmt(stmt), m_result(nullptr) -{ - m_has_result = async; // If it's async, then there's a result - if (async) - m_result = new PreparedQueryResultPromise(); -} - -PreparedStatementTask::~PreparedStatementTask() -{ - delete m_stmt; - if (m_has_result && m_result != nullptr) - delete m_result; -} - -bool PreparedStatementTask::Execute() -{ - if (m_has_result) - { - PreparedResultSet* result = m_conn->Query(m_stmt); - if (!result || !result->GetRowCount()) - { - delete result; - m_result->set_value(PreparedQueryResult(NULL)); - return false; - } - m_result->set_value(PreparedQueryResult(result)); - return true; - } - - return m_conn->Execute(m_stmt); -} diff --git a/src/server/shared/Database/PreparedStatement.h b/src/server/shared/Database/PreparedStatement.h deleted file mode 100644 index 2b8ce8aac2d..00000000000 --- a/src/server/shared/Database/PreparedStatement.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _PREPAREDSTATEMENT_H -#define _PREPAREDSTATEMENT_H - -#include <future> -#include "SQLOperation.h" - -#ifdef __APPLE__ -#undef TYPE_BOOL -#endif - -//- Union for data buffer (upper-level bind -> queue -> lower-level bind) -union PreparedStatementDataUnion -{ - bool boolean; - uint8 ui8; - int8 i8; - uint16 ui16; - int16 i16; - uint32 ui32; - int32 i32; - uint64 ui64; - int64 i64; - float f; - double d; -}; - -//- This enum helps us differ data held in above union -enum PreparedStatementValueType -{ - TYPE_BOOL, - TYPE_UI8, - TYPE_UI16, - TYPE_UI32, - TYPE_UI64, - TYPE_I8, - TYPE_I16, - TYPE_I32, - TYPE_I64, - TYPE_FLOAT, - TYPE_DOUBLE, - TYPE_STRING, - TYPE_NULL -}; - -struct PreparedStatementData -{ - PreparedStatementDataUnion data; - PreparedStatementValueType type; - std::string str; -}; - -//- Forward declare -class MySQLPreparedStatement; - -//- Upper-level class that is used in code -class PreparedStatement -{ - friend class PreparedStatementTask; - friend class MySQLPreparedStatement; - friend class MySQLConnection; - - public: - explicit PreparedStatement(uint32 index); - ~PreparedStatement(); - - void setBool(const uint8 index, const bool value); - void setUInt8(const uint8 index, const uint8 value); - void setUInt16(const uint8 index, const uint16 value); - void setUInt32(const uint8 index, const uint32 value); - void setUInt64(const uint8 index, const uint64 value); - void setInt8(const uint8 index, const int8 value); - void setInt16(const uint8 index, const int16 value); - void setInt32(const uint8 index, const int32 value); - void setInt64(const uint8 index, const int64 value); - void setFloat(const uint8 index, const float value); - void setDouble(const uint8 index, const double value); - void setString(const uint8 index, const std::string& value); - void setNull(const uint8 index); - - protected: - void BindParameters(); - - protected: - MySQLPreparedStatement* m_stmt; - uint32 m_index; - std::vector<PreparedStatementData> statement_data; //- Buffer of parameters, not tied to MySQL in any way yet - - PreparedStatement(PreparedStatement const& right) = delete; - PreparedStatement& operator=(PreparedStatement const& right) = delete; -}; - -//- Class of which the instances are unique per MySQLConnection -//- access to these class objects is only done when a prepared statement task -//- is executed. -class MySQLPreparedStatement -{ - friend class MySQLConnection; - friend class PreparedStatement; - - public: - MySQLPreparedStatement(MYSQL_STMT* stmt); - ~MySQLPreparedStatement(); - - void setBool(const uint8 index, const bool value); - void setUInt8(const uint8 index, const uint8 value); - void setUInt16(const uint8 index, const uint16 value); - void setUInt32(const uint8 index, const uint32 value); - void setUInt64(const uint8 index, const uint64 value); - void setInt8(const uint8 index, const int8 value); - void setInt16(const uint8 index, const int16 value); - void setInt32(const uint8 index, const int32 value); - void setInt64(const uint8 index, const int64 value); - void setFloat(const uint8 index, const float value); - void setDouble(const uint8 index, const double value); - void setString(const uint8 index, const char* value); - void setNull(const uint8 index); - - protected: - MYSQL_STMT* GetSTMT() { return m_Mstmt; } - MYSQL_BIND* GetBind() { return m_bind; } - PreparedStatement* m_stmt; - void ClearParameters(); - bool CheckValidIndex(uint8 index); - std::string getQueryString(std::string const& sqlPattern) const; - - private: - void setValue(MYSQL_BIND* param, enum_field_types type, const void* value, uint32 len, bool isUnsigned); - - private: - MYSQL_STMT* m_Mstmt; - uint32 m_paramCount; - std::vector<bool> m_paramsSet; - MYSQL_BIND* m_bind; - - MySQLPreparedStatement(MySQLPreparedStatement const& right) = delete; - MySQLPreparedStatement& operator=(MySQLPreparedStatement const& right) = delete; -}; - -typedef std::future<PreparedQueryResult> PreparedQueryResultFuture; -typedef std::promise<PreparedQueryResult> PreparedQueryResultPromise; - -//- Lower-level class, enqueuable operation -class PreparedStatementTask : public SQLOperation -{ - public: - PreparedStatementTask(PreparedStatement* stmt, bool async = false); - ~PreparedStatementTask(); - - bool Execute() override; - PreparedQueryResultFuture GetFuture() { return m_result->get_future(); } - - protected: - PreparedStatement* m_stmt; - bool m_has_result; - PreparedQueryResultPromise* m_result; -}; -#endif diff --git a/src/server/shared/Database/QueryHolder.cpp b/src/server/shared/Database/QueryHolder.cpp deleted file mode 100644 index 2fdb3825526..00000000000 --- a/src/server/shared/Database/QueryHolder.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "MySQLConnection.h" -#include "QueryHolder.h" -#include "PreparedStatement.h" -#include "Log.h" - -bool SQLQueryHolder::SetQuery(size_t index, const char *sql) -{ - if (m_queries.size() <= index) - { - TC_LOG_ERROR("sql.sql", "Query index (%u) out of range (size: %u) for query: %s", uint32(index), (uint32)m_queries.size(), sql); - return false; - } - - /// not executed yet, just stored (it's not called a holder for nothing) - SQLElementData element; - element.type = SQL_ELEMENT_RAW; - element.element.query = strdup(sql); - - SQLResultSetUnion result; - result.qresult = NULL; - - m_queries[index] = SQLResultPair(element, result); - return true; -} - -bool SQLQueryHolder::SetPreparedQuery(size_t index, PreparedStatement* stmt) -{ - if (m_queries.size() <= index) - { - TC_LOG_ERROR("sql.sql", "Query index (%u) out of range (size: %u) for prepared statement", uint32(index), (uint32)m_queries.size()); - return false; - } - - /// not executed yet, just stored (it's not called a holder for nothing) - SQLElementData element; - element.type = SQL_ELEMENT_PREPARED; - element.element.stmt = stmt; - - SQLResultSetUnion result; - result.presult = NULL; - - m_queries[index] = SQLResultPair(element, result); - return true; -} - -QueryResult SQLQueryHolder::GetResult(size_t index) -{ - // Don't call to this function if the index is of an ad-hoc statement - if (index < m_queries.size()) - { - ResultSet* result = m_queries[index].second.qresult; - if (!result || !result->GetRowCount() || !result->NextRow()) - return QueryResult(NULL); - - return QueryResult(result); - } - else - return QueryResult(NULL); -} - -PreparedQueryResult SQLQueryHolder::GetPreparedResult(size_t index) -{ - // Don't call to this function if the index is of a prepared statement - if (index < m_queries.size()) - { - PreparedResultSet* result = m_queries[index].second.presult; - if (!result || !result->GetRowCount()) - return PreparedQueryResult(NULL); - - return PreparedQueryResult(result); - } - else - return PreparedQueryResult(NULL); -} - -void SQLQueryHolder::SetResult(size_t index, ResultSet* result) -{ - if (result && !result->GetRowCount()) - { - delete result; - result = NULL; - } - - /// store the result in the holder - if (index < m_queries.size()) - m_queries[index].second.qresult = result; -} - -void SQLQueryHolder::SetPreparedResult(size_t index, PreparedResultSet* result) -{ - if (result && !result->GetRowCount()) - { - delete result; - result = NULL; - } - - /// store the result in the holder - if (index < m_queries.size()) - m_queries[index].second.presult = result; -} - -SQLQueryHolder::~SQLQueryHolder() -{ - for (size_t i = 0; i < m_queries.size(); i++) - { - /// if the result was never used, free the resources - /// results used already (getresult called) are expected to be deleted - if (SQLElementData* data = &m_queries[i].first) - { - switch (data->type) - { - case SQL_ELEMENT_RAW: - free((void*)(const_cast<char*>(data->element.query))); - break; - case SQL_ELEMENT_PREPARED: - delete data->element.stmt; - break; - } - } - } -} - -void SQLQueryHolder::SetSize(size_t size) -{ - /// to optimize push_back, reserve the number of queries about to be executed - m_queries.resize(size); -} - -SQLQueryHolderTask::~SQLQueryHolderTask() -{ - if (!m_executed) - delete m_holder; -} - -bool SQLQueryHolderTask::Execute() -{ - m_executed = true; - - if (!m_holder) - return false; - - /// we can do this, we are friends - std::vector<SQLQueryHolder::SQLResultPair> &queries = m_holder->m_queries; - - for (size_t i = 0; i < queries.size(); i++) - { - /// execute all queries in the holder and pass the results - if (SQLElementData* data = &queries[i].first) - { - switch (data->type) - { - case SQL_ELEMENT_RAW: - { - char const* sql = data->element.query; - if (sql) - m_holder->SetResult(i, m_conn->Query(sql)); - break; - } - case SQL_ELEMENT_PREPARED: - { - PreparedStatement* stmt = data->element.stmt; - if (stmt) - m_holder->SetPreparedResult(i, m_conn->Query(stmt)); - break; - } - } - } - } - - m_result.set_value(m_holder); - return true; -} diff --git a/src/server/shared/Database/QueryHolder.h b/src/server/shared/Database/QueryHolder.h deleted file mode 100644 index b64da948a16..00000000000 --- a/src/server/shared/Database/QueryHolder.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _QUERYHOLDER_H -#define _QUERYHOLDER_H - -#include <future> - -class SQLQueryHolder -{ - friend class SQLQueryHolderTask; - private: - typedef std::pair<SQLElementData, SQLResultSetUnion> SQLResultPair; - std::vector<SQLResultPair> m_queries; - public: - SQLQueryHolder() { } - ~SQLQueryHolder(); - bool SetQuery(size_t index, const char* sql); - template<typename Format, typename... Args> - bool SetPQuery(size_t index, Format&& sql, Args&&... args) - { - return SetQuery(index, Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str()); - } - bool SetPreparedQuery(size_t index, PreparedStatement* stmt); - void SetSize(size_t size); - QueryResult GetResult(size_t index); - PreparedQueryResult GetPreparedResult(size_t index); - void SetResult(size_t index, ResultSet* result); - void SetPreparedResult(size_t index, PreparedResultSet* result); -}; - -typedef std::future<SQLQueryHolder*> QueryResultHolderFuture; -typedef std::promise<SQLQueryHolder*> QueryResultHolderPromise; - -class SQLQueryHolderTask : public SQLOperation -{ - private: - SQLQueryHolder* m_holder; - QueryResultHolderPromise m_result; - bool m_executed; - - public: - SQLQueryHolderTask(SQLQueryHolder* holder) - : m_holder(holder), m_executed(false) { } - - ~SQLQueryHolderTask(); - - bool Execute() override; - QueryResultHolderFuture GetFuture() { return m_result.get_future(); } -}; - -#endif diff --git a/src/server/shared/Database/QueryResult.cpp b/src/server/shared/Database/QueryResult.cpp deleted file mode 100644 index 02352f221a0..00000000000 --- a/src/server/shared/Database/QueryResult.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "DatabaseEnv.h" -#include "Log.h" - -ResultSet::ResultSet(MYSQL_RES *result, MYSQL_FIELD *fields, uint64 rowCount, uint32 fieldCount) : -_rowCount(rowCount), -_fieldCount(fieldCount), -_result(result), -_fields(fields) -{ - _currentRow = new Field[_fieldCount]; - ASSERT(_currentRow); -} - -PreparedResultSet::PreparedResultSet(MYSQL_STMT* stmt, MYSQL_RES *result, uint64 rowCount, uint32 fieldCount) : -m_rowCount(rowCount), -m_rowPosition(0), -m_fieldCount(fieldCount), -m_rBind(NULL), -m_stmt(stmt), -m_res(result), -m_isNull(NULL), -m_length(NULL) -{ - if (!m_res) - return; - - if (m_stmt->bind_result_done) - { - delete[] m_stmt->bind->length; - delete[] m_stmt->bind->is_null; - } - - m_rBind = new MYSQL_BIND[m_fieldCount]; - m_isNull = new my_bool[m_fieldCount]; - m_length = new unsigned long[m_fieldCount]; - - memset(m_isNull, 0, sizeof(my_bool) * m_fieldCount); - memset(m_rBind, 0, sizeof(MYSQL_BIND) * m_fieldCount); - memset(m_length, 0, sizeof(unsigned long) * m_fieldCount); - - //- This is where we store the (entire) resultset - if (mysql_stmt_store_result(m_stmt)) - { - TC_LOG_WARN("sql.sql", "%s:mysql_stmt_store_result, cannot bind result from MySQL server. Error: %s", __FUNCTION__, mysql_stmt_error(m_stmt)); - delete[] m_rBind; - delete[] m_isNull; - delete[] m_length; - return; - } - - //- This is where we prepare the buffer based on metadata - uint32 i = 0; - MYSQL_FIELD* field = mysql_fetch_field(m_res); - while (field) - { - size_t size = Field::SizeForType(field); - - m_rBind[i].buffer_type = field->type; - m_rBind[i].buffer = malloc(size); - memset(m_rBind[i].buffer, 0, size); - m_rBind[i].buffer_length = size; - m_rBind[i].length = &m_length[i]; - m_rBind[i].is_null = &m_isNull[i]; - m_rBind[i].error = NULL; - m_rBind[i].is_unsigned = field->flags & UNSIGNED_FLAG; - - ++i; - field = mysql_fetch_field(m_res); - } - - //- This is where we bind the bind the buffer to the statement - if (mysql_stmt_bind_result(m_stmt, m_rBind)) - { - TC_LOG_WARN("sql.sql", "%s:mysql_stmt_bind_result, cannot bind result from MySQL server. Error: %s", __FUNCTION__, mysql_stmt_error(m_stmt)); - delete[] m_rBind; - delete[] m_isNull; - delete[] m_length; - return; - } - - m_rowCount = mysql_stmt_num_rows(m_stmt); - - m_rows.resize(uint32(m_rowCount)); - while (_NextRow()) - { - m_rows[uint32(m_rowPosition)] = new Field[m_fieldCount]; - for (uint64 fIndex = 0; fIndex < m_fieldCount; ++fIndex) - { - if (!*m_rBind[fIndex].is_null) - m_rows[uint32(m_rowPosition)][fIndex].SetByteValue(m_rBind[fIndex].buffer, - m_rBind[fIndex].buffer_length, - m_rBind[fIndex].buffer_type, - *m_rBind[fIndex].length); - else - switch (m_rBind[fIndex].buffer_type) - { - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_VAR_STRING: - m_rows[uint32(m_rowPosition)][fIndex].SetByteValue("", - m_rBind[fIndex].buffer_length, - m_rBind[fIndex].buffer_type, - *m_rBind[fIndex].length); - break; - default: - m_rows[uint32(m_rowPosition)][fIndex].SetByteValue(nullptr, - m_rBind[fIndex].buffer_length, - m_rBind[fIndex].buffer_type, - *m_rBind[fIndex].length); - } - } - m_rowPosition++; - } - m_rowPosition = 0; - - /// All data is buffered, let go of mysql c api structures - CleanUp(); -} - -ResultSet::~ResultSet() -{ - CleanUp(); -} - -PreparedResultSet::~PreparedResultSet() -{ - for (uint32 i = 0; i < uint32(m_rowCount); ++i) - delete[] m_rows[i]; -} - -bool ResultSet::NextRow() -{ - MYSQL_ROW row; - - if (!_result) - return false; - - row = mysql_fetch_row(_result); - if (!row) - { - CleanUp(); - return false; - } - - for (uint32 i = 0; i < _fieldCount; i++) - _currentRow[i].SetStructuredValue(row[i], _fields[i].type); - - return true; -} - -bool PreparedResultSet::NextRow() -{ - /// Only updates the m_rowPosition so upper level code knows in which element - /// of the rows vector to look - if (++m_rowPosition >= m_rowCount) - return false; - - return true; -} - -bool PreparedResultSet::_NextRow() -{ - /// Only called in low-level code, namely the constructor - /// Will iterate over every row of data and buffer it - if (m_rowPosition >= m_rowCount) - return false; - - int retval = mysql_stmt_fetch(m_stmt); - return retval == 0 || retval == MYSQL_DATA_TRUNCATED; -} - -void ResultSet::CleanUp() -{ - if (_currentRow) - { - delete [] _currentRow; - _currentRow = NULL; - } - - if (_result) - { - mysql_free_result(_result); - _result = NULL; - } -} - -void PreparedResultSet::CleanUp() -{ - /// More of the in our code allocated sources are deallocated by the poorly documented mysql c api - if (m_res) - mysql_free_result(m_res); - - FreeBindBuffer(); - mysql_stmt_free_result(m_stmt); - - delete[] m_rBind; -} - -void PreparedResultSet::FreeBindBuffer() -{ - for (uint32 i = 0; i < m_fieldCount; ++i) - free (m_rBind[i].buffer); -} diff --git a/src/server/shared/Database/QueryResult.h b/src/server/shared/Database/QueryResult.h deleted file mode 100644 index a61fb6331c1..00000000000 --- a/src/server/shared/Database/QueryResult.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef QUERYRESULT_H -#define QUERYRESULT_H - -#include <memory> -#include "Field.h" - -#ifdef _WIN32 - #include <winsock2.h> -#endif -#include <mysql.h> - -class ResultSet -{ - public: - ResultSet(MYSQL_RES* result, MYSQL_FIELD* fields, uint64 rowCount, uint32 fieldCount); - ~ResultSet(); - - bool NextRow(); - uint64 GetRowCount() const { return _rowCount; } - uint32 GetFieldCount() const { return _fieldCount; } - - Field* Fetch() const { return _currentRow; } - const Field & operator [] (uint32 index) const - { - ASSERT(index < _fieldCount); - return _currentRow[index]; - } - - protected: - uint64 _rowCount; - Field* _currentRow; - uint32 _fieldCount; - - private: - void CleanUp(); - MYSQL_RES* _result; - MYSQL_FIELD* _fields; - - ResultSet(ResultSet const& right) = delete; - ResultSet& operator=(ResultSet const& right) = delete; -}; - -typedef std::shared_ptr<ResultSet> QueryResult; - -class PreparedResultSet -{ - public: - PreparedResultSet(MYSQL_STMT* stmt, MYSQL_RES* result, uint64 rowCount, uint32 fieldCount); - ~PreparedResultSet(); - - bool NextRow(); - uint64 GetRowCount() const { return m_rowCount; } - uint32 GetFieldCount() const { return m_fieldCount; } - - Field* Fetch() const - { - ASSERT(m_rowPosition < m_rowCount); - return m_rows[uint32(m_rowPosition)]; - } - - const Field & operator [] (uint32 index) const - { - ASSERT(m_rowPosition < m_rowCount); - ASSERT(index < m_fieldCount); - return m_rows[uint32(m_rowPosition)][index]; - } - - protected: - std::vector<Field*> m_rows; - uint64 m_rowCount; - uint64 m_rowPosition; - uint32 m_fieldCount; - - private: - MYSQL_BIND* m_rBind; - MYSQL_STMT* m_stmt; - MYSQL_RES* m_res; - - my_bool* m_isNull; - unsigned long* m_length; - - void FreeBindBuffer(); - void CleanUp(); - bool _NextRow(); - - PreparedResultSet(PreparedResultSet const& right) = delete; - PreparedResultSet& operator=(PreparedResultSet const& right) = delete; -}; - -typedef std::shared_ptr<PreparedResultSet> PreparedQueryResult; - -#endif - diff --git a/src/server/shared/Database/SQLOperation.h b/src/server/shared/Database/SQLOperation.h deleted file mode 100644 index c5667288ec0..00000000000 --- a/src/server/shared/Database/SQLOperation.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _SQLOPERATION_H -#define _SQLOPERATION_H - -#include "QueryResult.h" - -//- Forward declare (don't include header to prevent circular includes) -class PreparedStatement; - -//- Union that holds element data -union SQLElementUnion -{ - PreparedStatement* stmt; - const char* query; -}; - -//- Type specifier of our element data -enum SQLElementDataType -{ - SQL_ELEMENT_RAW, - SQL_ELEMENT_PREPARED -}; - -//- The element -struct SQLElementData -{ - SQLElementUnion element; - SQLElementDataType type; -}; - -//- For ambigious resultsets -union SQLResultSetUnion -{ - PreparedResultSet* presult; - ResultSet* qresult; -}; - -class MySQLConnection; - -class SQLOperation -{ - public: - SQLOperation(): m_conn(NULL) { } - virtual ~SQLOperation() { } - - virtual int call() - { - Execute(); - return 0; - } - virtual bool Execute() = 0; - virtual void SetConnection(MySQLConnection* con) { m_conn = con; } - - MySQLConnection* m_conn; - - private: - SQLOperation(SQLOperation const& right) = delete; - SQLOperation& operator=(SQLOperation const& right) = delete; -}; - -#endif diff --git a/src/server/shared/Database/Transaction.cpp b/src/server/shared/Database/Transaction.cpp deleted file mode 100644 index f657411f716..00000000000 --- a/src/server/shared/Database/Transaction.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "DatabaseEnv.h" -#include "Transaction.h" -#include <mysqld_error.h> - -std::mutex TransactionTask::_deadlockLock; - -//- Append a raw ad-hoc query to the transaction -void Transaction::Append(const char* sql) -{ - SQLElementData data; - data.type = SQL_ELEMENT_RAW; - data.element.query = strdup(sql); - m_queries.push_back(data); -} - -//- Append a prepared statement to the transaction -void Transaction::Append(PreparedStatement* stmt) -{ - SQLElementData data; - data.type = SQL_ELEMENT_PREPARED; - data.element.stmt = stmt; - m_queries.push_back(data); -} - -void Transaction::Cleanup() -{ - // This might be called by explicit calls to Cleanup or by the auto-destructor - if (_cleanedUp) - return; - - while (!m_queries.empty()) - { - SQLElementData const &data = m_queries.front(); - switch (data.type) - { - case SQL_ELEMENT_PREPARED: - delete data.element.stmt; - break; - case SQL_ELEMENT_RAW: - free((void*)(data.element.query)); - break; - } - - m_queries.pop_front(); - } - - _cleanedUp = true; -} - -bool TransactionTask::Execute() -{ - int errorCode = m_conn->ExecuteTransaction(m_trans); - if (!errorCode) - return true; - - if (errorCode == ER_LOCK_DEADLOCK) - { - // Make sure only 1 async thread retries a transaction so they don't keep dead-locking each other - std::lock_guard<std::mutex> lock(_deadlockLock); - uint8 loopBreaker = 5; // Handle MySQL Errno 1213 without extending deadlock to the core itself - for (uint8 i = 0; i < loopBreaker; ++i) - if (!m_conn->ExecuteTransaction(m_trans)) - return true; - } - - // Clean up now. - m_trans->Cleanup(); - - return false; -} diff --git a/src/server/shared/Database/Transaction.h b/src/server/shared/Database/Transaction.h deleted file mode 100644 index 4fbbe1ed45b..00000000000 --- a/src/server/shared/Database/Transaction.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _TRANSACTION_H -#define _TRANSACTION_H - -#include "SQLOperation.h" -#include "StringFormat.h" - -//- Forward declare (don't include header to prevent circular includes) -class PreparedStatement; - -/*! Transactions, high level class. */ -class Transaction -{ - friend class TransactionTask; - friend class MySQLConnection; - - template <typename T> - friend class DatabaseWorkerPool; - - public: - Transaction() : _cleanedUp(false) { } - ~Transaction() { Cleanup(); } - - void Append(PreparedStatement* statement); - void Append(const char* sql); - template<typename Format, typename... Args> - void PAppend(Format&& sql, Args&&... args) - { - Append(Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str()); - } - - size_t GetSize() const { return m_queries.size(); } - - protected: - void Cleanup(); - std::list<SQLElementData> m_queries; - - private: - bool _cleanedUp; - -}; -typedef std::shared_ptr<Transaction> SQLTransaction; - -/*! Low level class*/ -class TransactionTask : public SQLOperation -{ - template <class T> friend class DatabaseWorkerPool; - friend class DatabaseWorker; - - public: - TransactionTask(SQLTransaction trans) : m_trans(trans) { } - ~TransactionTask() { } - - protected: - bool Execute() override; - - SQLTransaction m_trans; - static std::mutex _deadlockLock; -}; - -#endif diff --git a/src/server/shared/Debugging/Errors.cpp b/src/server/shared/Debugging/Errors.cpp deleted file mode 100644 index cebd9d4cf2f..00000000000 --- a/src/server/shared/Debugging/Errors.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "Errors.h" - -#include <cstdio> -#include <cstdlib> -#include <thread> -#include <cstdarg> - -namespace Trinity { - -void Assert(char const* file, int line, char const* function, char const* message) -{ - fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n", - file, line, function, message); - *((volatile int*)NULL) = 0; - exit(1); -} - -void Assert(char const* file, int line, char const* function, char const* message, char const* format, ...) -{ - va_list args; - va_start(args, format); - - fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s ", file, line, function, message); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - fflush(stderr); - - va_end(args); - *((volatile int*)NULL) = 0; - exit(1); -} - -void Fatal(char const* file, int line, char const* function, char const* message) -{ - fprintf(stderr, "\n%s:%i in %s FATAL ERROR:\n %s\n", - file, line, function, message); - - std::this_thread::sleep_for(std::chrono::seconds(10)); - *((volatile int*)NULL) = 0; - exit(1); -} - -void Error(char const* file, int line, char const* function, char const* message) -{ - fprintf(stderr, "\n%s:%i in %s ERROR:\n %s\n", - file, line, function, message); - *((volatile int*)NULL) = 0; - exit(1); -} - -void Warning(char const* file, int line, char const* function, char const* message) -{ - fprintf(stderr, "\n%s:%i in %s WARNING:\n %s\n", - file, line, function, message); -} - -} // namespace Trinity diff --git a/src/server/shared/Debugging/Errors.h b/src/server/shared/Debugging/Errors.h deleted file mode 100644 index 4d4624b63dd..00000000000 --- a/src/server/shared/Debugging/Errors.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef TRINITYCORE_ERRORS_H -#define TRINITYCORE_ERRORS_H - -#include "Define.h" - -namespace Trinity -{ - DECLSPEC_NORETURN void Assert(char const* file, int line, char const* function, char const* message) ATTR_NORETURN; - DECLSPEC_NORETURN void Assert(char const* file, int line, char const* function, char const* message, char const* format, ...) ATTR_NORETURN ATTR_PRINTF(5, 6); - - DECLSPEC_NORETURN void Fatal(char const* file, int line, char const* function, char const* message) ATTR_NORETURN; - - DECLSPEC_NORETURN void Error(char const* file, int line, char const* function, char const* message) ATTR_NORETURN; - - void Warning(char const* file, int line, char const* function, char const* message); - -} // namespace Trinity - -#if COMPILER == COMPILER_MICROSOFT -#define ASSERT_BEGIN __pragma(warning(push)) __pragma(warning(disable: 4127)) -#define ASSERT_END __pragma(warning(pop)) -#else -#define ASSERT_BEGIN -#define ASSERT_END -#endif - -#define WPAssert(cond, ...) ASSERT_BEGIN do { if (!(cond)) Trinity::Assert(__FILE__, __LINE__, __FUNCTION__, #cond, ##__VA_ARGS__); } while(0) ASSERT_END -#define WPFatal(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Fatal(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END -#define WPError(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Error(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END -#define WPWarning(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Warning(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END - -#define ASSERT WPAssert - -template <typename T> inline T* ASSERT_NOTNULL(T* pointer) -{ - ASSERT(pointer); - return pointer; -} - -#endif diff --git a/src/server/shared/Debugging/WheatyExceptionReport.cpp b/src/server/shared/Debugging/WheatyExceptionReport.cpp deleted file mode 100644 index 70aa23a8eed..00000000000 --- a/src/server/shared/Debugging/WheatyExceptionReport.cpp +++ /dev/null @@ -1,1423 +0,0 @@ -//========================================== -// Matt Pietrek -// MSDN Magazine, 2002 -// FILE: WheatyExceptionReport.CPP -//========================================== -#include "CompilerDefs.h" - -#if PLATFORM == PLATFORM_WINDOWS && !defined(__MINGW32__) -#define WIN32_LEAN_AND_MEAN -#pragma warning(disable:4996) -#pragma warning(disable:4312) -#pragma warning(disable:4311) -#include <windows.h> -#include <tlhelp32.h> -#include <stdio.h> -#include <tchar.h> -#define _NO_CVCONST_H -#include <dbghelp.h> - -#include "WheatyExceptionReport.h" - -#include "Common.h" -#include "Revision.h" - -#define CrashFolder _T("Crashes") -#pragma comment(linker, "/DEFAULTLIB:dbghelp.lib") - -inline LPTSTR ErrorMessage(DWORD dw) -{ - LPVOID lpMsgBuf; - DWORD formatResult = FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - dw, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, NULL); - if (formatResult != 0) - return (LPTSTR)lpMsgBuf; - else - { - LPTSTR msgBuf = (LPTSTR)LocalAlloc(LPTR, 30); - sprintf(msgBuf, "Unknown error: %u", dw); - return msgBuf; - } - -} - -//============================== Global Variables ============================= - -// -// Declare the static variables of the WheatyExceptionReport class -// -TCHAR WheatyExceptionReport::m_szLogFileName[MAX_PATH]; -TCHAR WheatyExceptionReport::m_szDumpFileName[MAX_PATH]; -LPTOP_LEVEL_EXCEPTION_FILTER WheatyExceptionReport::m_previousFilter; -HANDLE WheatyExceptionReport::m_hReportFile; -HANDLE WheatyExceptionReport::m_hDumpFile; -HANDLE WheatyExceptionReport::m_hProcess; -SymbolPairs WheatyExceptionReport::symbols; -std::stack<SymbolDetail> WheatyExceptionReport::symbolDetails; -bool WheatyExceptionReport::stackOverflowException; -bool WheatyExceptionReport::alreadyCrashed; -std::mutex WheatyExceptionReport::alreadyCrashedLock; - -// Declare global instance of class -WheatyExceptionReport g_WheatyExceptionReport; - -//============================== Class Methods ============================= - -WheatyExceptionReport::WheatyExceptionReport() // Constructor -{ - // Install the unhandled exception filter function - m_previousFilter = SetUnhandledExceptionFilter(WheatyUnhandledExceptionFilter); - m_hProcess = GetCurrentProcess(); - stackOverflowException = false; - alreadyCrashed = false; - if (!IsDebuggerPresent()) - { - _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); - _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); - } -} - -//============ -// Destructor -//============ -WheatyExceptionReport::~WheatyExceptionReport() -{ - if (m_previousFilter) - SetUnhandledExceptionFilter(m_previousFilter); - ClearSymbols(); -} - -//=========================================================== -// Entry point where control comes on an unhandled exception -//=========================================================== -LONG WINAPI WheatyExceptionReport::WheatyUnhandledExceptionFilter( -PEXCEPTION_POINTERS pExceptionInfo) -{ - std::unique_lock<std::mutex> guard(alreadyCrashedLock); - // Handle only 1 exception in the whole process lifetime - if (alreadyCrashed) - return EXCEPTION_EXECUTE_HANDLER; - - alreadyCrashed = true; - - if (pExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_STACK_OVERFLOW) - stackOverflowException = true; - - TCHAR module_folder_name[MAX_PATH]; - GetModuleFileName(0, module_folder_name, MAX_PATH); - TCHAR* pos = _tcsrchr(module_folder_name, '\\'); - if (!pos) - return 0; - pos[0] = '\0'; - ++pos; - - TCHAR crash_folder_path[MAX_PATH]; - sprintf(crash_folder_path, "%s\\%s", module_folder_name, CrashFolder); - if (!CreateDirectory(crash_folder_path, NULL)) - { - if (GetLastError() != ERROR_ALREADY_EXISTS) - return 0; - } - - SYSTEMTIME systime; - GetLocalTime(&systime); - sprintf(m_szDumpFileName, "%s\\%s_%s_[%u-%u_%u-%u-%u].dmp", - crash_folder_path, Revision::GetHash(), pos, systime.wDay, systime.wMonth, systime.wHour, systime.wMinute, systime.wSecond); - - sprintf(m_szLogFileName, "%s\\%s_%s_[%u-%u_%u-%u-%u].txt", - crash_folder_path, Revision::GetHash(), pos, systime.wDay, systime.wMonth, systime.wHour, systime.wMinute, systime.wSecond); - - m_hDumpFile = CreateFile(m_szDumpFileName, - GENERIC_WRITE, - 0, - 0, - OPEN_ALWAYS, - FILE_FLAG_WRITE_THROUGH, - 0); - - m_hReportFile = CreateFile(m_szLogFileName, - GENERIC_WRITE, - 0, - 0, - OPEN_ALWAYS, - FILE_FLAG_WRITE_THROUGH, - 0); - - if (m_hDumpFile) - { - MINIDUMP_EXCEPTION_INFORMATION info; - info.ClientPointers = FALSE; - info.ExceptionPointers = pExceptionInfo; - info.ThreadId = GetCurrentThreadId(); - - MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), - m_hDumpFile, MiniDumpWithIndirectlyReferencedMemory, &info, 0, 0); - - CloseHandle(m_hDumpFile); - } - - if (m_hReportFile) - { - SetFilePointer(m_hReportFile, 0, 0, FILE_END); - - GenerateExceptionReport(pExceptionInfo); - - CloseHandle(m_hReportFile); - m_hReportFile = 0; - } - - if (m_previousFilter) - return m_previousFilter(pExceptionInfo); - else - return EXCEPTION_EXECUTE_HANDLER/*EXCEPTION_CONTINUE_SEARCH*/; -} - -BOOL WheatyExceptionReport::_GetProcessorName(TCHAR* sProcessorName, DWORD maxcount) -{ - if (!sProcessorName) - return FALSE; - - HKEY hKey; - LONG lRet; - lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), - 0, KEY_QUERY_VALUE, &hKey); - if (lRet != ERROR_SUCCESS) - return FALSE; - TCHAR szTmp[2048]; - DWORD cntBytes = sizeof(szTmp); - lRet = ::RegQueryValueEx(hKey, _T("ProcessorNameString"), NULL, NULL, - (LPBYTE)szTmp, &cntBytes); - if (lRet != ERROR_SUCCESS) - return FALSE; - ::RegCloseKey(hKey); - sProcessorName[0] = '\0'; - // Skip spaces - TCHAR* psz = szTmp; - while (iswspace(*psz)) - ++psz; - _tcsncpy(sProcessorName, psz, maxcount); - return TRUE; -} - -BOOL WheatyExceptionReport::_GetWindowsVersion(TCHAR* szVersion, DWORD cntMax) -{ - // Try calling GetVersionEx using the OSVERSIONINFOEX structure. - // If that fails, try using the OSVERSIONINFO structure. - OSVERSIONINFOEX osvi = { 0 }; - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - BOOL bOsVersionInfoEx; - bOsVersionInfoEx = ::GetVersionEx((LPOSVERSIONINFO)(&osvi)); - if (!bOsVersionInfoEx) - { - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (!::GetVersionEx((OSVERSIONINFO*)&osvi)) - return FALSE; - } - *szVersion = _T('\0'); - TCHAR wszTmp[128]; - switch (osvi.dwPlatformId) - { - // Windows NT product family. - case VER_PLATFORM_WIN32_NT: - { - #if WINVER < 0x0500 - BYTE suiteMask = osvi.wReserved[0]; - BYTE productType = osvi.wReserved[1]; - #else - WORD suiteMask = osvi.wSuiteMask; - BYTE productType = osvi.wProductType; - #endif // WINVER < 0x0500 - - // Test for the specific product family. - if (osvi.dwMajorVersion == 6) - { - if (productType == VER_NT_WORKSTATION) - { - if (osvi.dwMinorVersion == 2) - _tcsncat(szVersion, _T("Windows 8 "), cntMax); - else if (osvi.dwMinorVersion == 1) - _tcsncat(szVersion, _T("Windows 7 "), cntMax); - else - _tcsncat(szVersion, _T("Windows Vista "), cntMax); - } - else if (osvi.dwMinorVersion == 2) - _tcsncat(szVersion, _T("Windows Server 2012 "), cntMax); - else if (osvi.dwMinorVersion == 1) - _tcsncat(szVersion, _T("Windows Server 2008 R2 "), cntMax); - else - _tcsncat(szVersion, _T("Windows Server 2008 "), cntMax); - } - else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) - _tcsncat(szVersion, _T("Microsoft Windows Server 2003 "), cntMax); - else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) - _tcsncat(szVersion, _T("Microsoft Windows XP "), cntMax); - else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) - _tcsncat(szVersion, _T("Microsoft Windows 2000 "), cntMax); - else if (osvi.dwMajorVersion <= 4) - _tcsncat(szVersion, _T("Microsoft Windows NT "), cntMax); - - // Test for specific product on Windows NT 4.0 SP6 and later. - if (bOsVersionInfoEx) - { - // Test for the workstation type. - if (productType == VER_NT_WORKSTATION) - { - if (osvi.dwMajorVersion == 4) - _tcsncat(szVersion, _T("Workstation 4.0 "), cntMax); - else if (suiteMask & VER_SUITE_PERSONAL) - _tcsncat(szVersion, _T("Home Edition "), cntMax); - else if (suiteMask & VER_SUITE_EMBEDDEDNT) - _tcsncat(szVersion, _T("Embedded "), cntMax); - else - _tcsncat(szVersion, _T("Professional "), cntMax); - } - // Test for the server type. - else if (productType == VER_NT_SERVER) - { - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) - { - if (suiteMask & VER_SUITE_DATACENTER) - _tcsncat(szVersion, _T("Datacenter Edition "), cntMax); - else if (suiteMask & VER_SUITE_ENTERPRISE) - _tcsncat(szVersion, _T("Enterprise Edition "), cntMax); - else if (suiteMask == VER_SUITE_BLADE) - _tcsncat(szVersion, _T("Web Edition "), cntMax); - else - _tcsncat(szVersion, _T("Standard Edition "), cntMax); - } - else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) - { - if (suiteMask & VER_SUITE_DATACENTER) - _tcsncat(szVersion, _T("Datacenter Server "), cntMax); - else if (suiteMask & VER_SUITE_ENTERPRISE) - _tcsncat(szVersion, _T("Advanced Server "), cntMax); - else - _tcsncat(szVersion, _T("Server "), cntMax); - } - else // Windows NT 4.0 - { - if (suiteMask & VER_SUITE_ENTERPRISE) - _tcsncat(szVersion, _T("Server 4.0, Enterprise Edition "), cntMax); - else - _tcsncat(szVersion, _T("Server 4.0 "), cntMax); - } - } - } - - // Display service pack (if any) and build number. - if (osvi.dwMajorVersion == 4 && _tcsicmp(osvi.szCSDVersion, _T("Service Pack 6")) == 0) - { - HKEY hKey; - LONG lRet; - - // Test for SP6 versus SP6a. - lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009"), 0, KEY_QUERY_VALUE, &hKey); - if (lRet == ERROR_SUCCESS) - { - _stprintf(wszTmp, _T("Service Pack 6a (Version %d.%d, Build %d)"), - osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF); - _tcsncat(szVersion, wszTmp, cntMax); - } - else // Windows NT 4.0 prior to SP6a - { - _stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"), - osvi.szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF); - _tcsncat(szVersion, wszTmp, cntMax); - } - ::RegCloseKey(hKey); - } - else // Windows NT 3.51 and earlier or Windows 2000 and later - { - if (!_tcslen(osvi.szCSDVersion)) - _stprintf(wszTmp, _T("(Version %d.%d, Build %d)"), - osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF); - else - _stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"), - osvi.szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF); - _tcsncat(szVersion, wszTmp, cntMax); - } - break; - } - default: - _stprintf(wszTmp, _T("%s (Version %d.%d, Build %d)"), - osvi.szCSDVersion, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber & 0xFFFF); - _tcsncat(szVersion, wszTmp, cntMax); - break; - } - - return TRUE; -} - -void WheatyExceptionReport::PrintSystemInfo() -{ - SYSTEM_INFO SystemInfo; - ::GetSystemInfo(&SystemInfo); - - MEMORYSTATUS MemoryStatus; - MemoryStatus.dwLength = sizeof (MEMORYSTATUS); - ::GlobalMemoryStatus(&MemoryStatus); - TCHAR sString[1024]; - _tprintf(_T("//=====================================================\r\n")); - if (_GetProcessorName(sString, countof(sString))) - _tprintf(_T("*** Hardware ***\r\nProcessor: %s\r\nNumber Of Processors: %d\r\nPhysical Memory: %d KB (Available: %d KB)\r\nCommit Charge Limit: %d KB\r\n"), - sString, SystemInfo.dwNumberOfProcessors, MemoryStatus.dwTotalPhys/0x400, MemoryStatus.dwAvailPhys/0x400, MemoryStatus.dwTotalPageFile/0x400); - else - _tprintf(_T("*** Hardware ***\r\nProcessor: <unknown>\r\nNumber Of Processors: %d\r\nPhysical Memory: %d KB (Available: %d KB)\r\nCommit Charge Limit: %d KB\r\n"), - SystemInfo.dwNumberOfProcessors, MemoryStatus.dwTotalPhys/0x400, MemoryStatus.dwAvailPhys/0x400, MemoryStatus.dwTotalPageFile/0x400); - - if (_GetWindowsVersion(sString, countof(sString))) - _tprintf(_T("\r\n*** Operation System ***\r\n%s\r\n"), sString); - else - _tprintf(_T("\r\n*** Operation System:\r\n<unknown>\r\n")); -} - -//=========================================================================== -void WheatyExceptionReport::printTracesForAllThreads(bool bWriteVariables) -{ - THREADENTRY32 te32; - - DWORD dwOwnerPID = GetCurrentProcessId(); - m_hProcess = GetCurrentProcess(); - // Take a snapshot of all running threads - HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); - if (hThreadSnap == INVALID_HANDLE_VALUE) - return; - - // Fill in the size of the structure before using it. - te32.dwSize = sizeof(THREADENTRY32); - - // Retrieve information about the first thread, - // and exit if unsuccessful - if (!Thread32First(hThreadSnap, &te32)) - { - CloseHandle(hThreadSnap); // Must clean up the - // snapshot object! - return; - } - - // Now walk the thread list of the system, - // and display information about each thread - // associated with the specified process - do - { - if (te32.th32OwnerProcessID == dwOwnerPID) - { - CONTEXT context; - context.ContextFlags = 0xffffffff; - HANDLE threadHandle = OpenThread(THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, false, te32.th32ThreadID); - if (threadHandle) - { - if (GetThreadContext(threadHandle, &context)) - WriteStackDetails(&context, bWriteVariables, threadHandle); - CloseHandle(threadHandle); - } - } - } while (Thread32Next(hThreadSnap, &te32)); - -// Don't forget to clean up the snapshot object. - CloseHandle(hThreadSnap); -} - -//=========================================================================== -// Open the report file, and write the desired information to it. Called by -// WheatyUnhandledExceptionFilter -//=========================================================================== -void WheatyExceptionReport::GenerateExceptionReport( -PEXCEPTION_POINTERS pExceptionInfo) -{ - __try - { - SYSTEMTIME systime; - GetLocalTime(&systime); - - // Start out with a banner - _tprintf(_T("Revision: %s\r\n"), Revision::GetFullVersion()); - _tprintf(_T("Date %u:%u:%u. Time %u:%u \r\n"), systime.wDay, systime.wMonth, systime.wYear, systime.wHour, systime.wMinute); - PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord; - - PrintSystemInfo(); - // First print information about the type of fault - _tprintf(_T("\r\n//=====================================================\r\n")); - _tprintf(_T("Exception code: %08X %s\r\n"), - pExceptionRecord->ExceptionCode, - GetExceptionString(pExceptionRecord->ExceptionCode)); - - // Now print information about where the fault occured - TCHAR szFaultingModule[MAX_PATH]; - DWORD section; - DWORD_PTR offset; - GetLogicalAddress(pExceptionRecord->ExceptionAddress, - szFaultingModule, - sizeof(szFaultingModule), - section, offset); - -#ifdef _M_IX86 - _tprintf(_T("Fault address: %08X %02X:%08X %s\r\n"), - pExceptionRecord->ExceptionAddress, - section, offset, szFaultingModule); -#endif -#ifdef _M_X64 - _tprintf(_T("Fault address: %016I64X %02X:%016I64X %s\r\n"), - pExceptionRecord->ExceptionAddress, - section, offset, szFaultingModule); -#endif - - PCONTEXT pCtx = pExceptionInfo->ContextRecord; - - // Show the registers -#ifdef _M_IX86 // X86 Only! - _tprintf(_T("\r\nRegisters:\r\n")); - - _tprintf(_T("EAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n") - , pCtx->Eax, pCtx->Ebx, pCtx->Ecx, pCtx->Edx, - pCtx->Esi, pCtx->Edi); - - _tprintf(_T("CS:EIP:%04X:%08X\r\n"), pCtx->SegCs, pCtx->Eip); - _tprintf(_T("SS:ESP:%04X:%08X EBP:%08X\r\n"), - pCtx->SegSs, pCtx->Esp, pCtx->Ebp); - _tprintf(_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"), - pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs); - _tprintf(_T("Flags:%08X\r\n"), pCtx->EFlags); -#endif - -#ifdef _M_X64 - _tprintf(_T("\r\nRegisters:\r\n")); - _tprintf(_T("RAX:%016I64X\r\nRBX:%016I64X\r\nRCX:%016I64X\r\nRDX:%016I64X\r\nRSI:%016I64X\r\nRDI:%016I64X\r\n") - _T("R8: %016I64X\r\nR9: %016I64X\r\nR10:%016I64X\r\nR11:%016I64X\r\nR12:%016I64X\r\nR13:%016I64X\r\nR14:%016I64X\r\nR15:%016I64X\r\n") - , pCtx->Rax, pCtx->Rbx, pCtx->Rcx, pCtx->Rdx, - pCtx->Rsi, pCtx->Rdi, pCtx->R9, pCtx->R10, pCtx->R11, pCtx->R12, pCtx->R13, pCtx->R14, pCtx->R15); - _tprintf(_T("CS:RIP:%04X:%016I64X\r\n"), pCtx->SegCs, pCtx->Rip); - _tprintf(_T("SS:RSP:%04X:%016X RBP:%08X\r\n"), - pCtx->SegSs, pCtx->Rsp, pCtx->Rbp); - _tprintf(_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"), - pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs); - _tprintf(_T("Flags:%08X\r\n"), pCtx->EFlags); -#endif - - SymSetOptions(SYMOPT_DEFERRED_LOADS); - - // Initialize DbgHelp - if (!SymInitialize(GetCurrentProcess(), 0, TRUE)) - { - _tprintf(_T("\n\rCRITICAL ERROR.\n\r Couldn't initialize the symbol handler for process.\n\rError [%s].\n\r\n\r"), - ErrorMessage(GetLastError())); - } - - CONTEXT trashableContext = *pCtx; - - WriteStackDetails(&trashableContext, false, NULL); - printTracesForAllThreads(false); - - // #ifdef _M_IX86 // X86 Only! - - _tprintf(_T("========================\r\n")); - _tprintf(_T("Local Variables And Parameters\r\n")); - - trashableContext = *pCtx; - WriteStackDetails(&trashableContext, true, NULL); - printTracesForAllThreads(true); - - /*_tprintf(_T("========================\r\n")); - _tprintf(_T("Global Variables\r\n")); - - SymEnumSymbols(GetCurrentProcess(), - (UINT_PTR)GetModuleHandle(szFaultingModule), - 0, EnumerateSymbolsCallback, 0);*/ - // #endif // X86 Only! - - SymCleanup(GetCurrentProcess()); - - _tprintf(_T("\r\n")); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - _tprintf(_T("Error writing the crash log\r\n")); - } -} - -//====================================================================== -// Given an exception code, returns a pointer to a static string with a -// description of the exception -//====================================================================== -LPTSTR WheatyExceptionReport::GetExceptionString(DWORD dwCode) -{ - #define EXCEPTION(x) case EXCEPTION_##x: return _T(#x); - - switch (dwCode) - { - EXCEPTION(ACCESS_VIOLATION) - EXCEPTION(DATATYPE_MISALIGNMENT) - EXCEPTION(BREAKPOINT) - EXCEPTION(SINGLE_STEP) - EXCEPTION(ARRAY_BOUNDS_EXCEEDED) - EXCEPTION(FLT_DENORMAL_OPERAND) - EXCEPTION(FLT_DIVIDE_BY_ZERO) - EXCEPTION(FLT_INEXACT_RESULT) - EXCEPTION(FLT_INVALID_OPERATION) - EXCEPTION(FLT_OVERFLOW) - EXCEPTION(FLT_STACK_CHECK) - EXCEPTION(FLT_UNDERFLOW) - EXCEPTION(INT_DIVIDE_BY_ZERO) - EXCEPTION(INT_OVERFLOW) - EXCEPTION(PRIV_INSTRUCTION) - EXCEPTION(IN_PAGE_ERROR) - EXCEPTION(ILLEGAL_INSTRUCTION) - EXCEPTION(NONCONTINUABLE_EXCEPTION) - EXCEPTION(STACK_OVERFLOW) - EXCEPTION(INVALID_DISPOSITION) - EXCEPTION(GUARD_PAGE) - EXCEPTION(INVALID_HANDLE) - } - - // If not one of the "known" exceptions, try to get the string - // from NTDLL.DLL's message table. - - static TCHAR szBuffer[512] = { 0 }; - - FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, - GetModuleHandle(_T("NTDLL.DLL")), - dwCode, 0, szBuffer, sizeof(szBuffer), 0); - - return szBuffer; -} - -//============================================================================= -// Given a linear address, locates the module, section, and offset containing -// that address. -// -// Note: the szModule paramater buffer is an output buffer of length specified -// by the len parameter (in characters!) -//============================================================================= -BOOL WheatyExceptionReport::GetLogicalAddress( -PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD_PTR& offset) -{ - MEMORY_BASIC_INFORMATION mbi; - - if (!VirtualQuery(addr, &mbi, sizeof(mbi))) - return FALSE; - - DWORD_PTR hMod = (DWORD_PTR)mbi.AllocationBase; - - if (!hMod) - return FALSE; - - if (!GetModuleFileName((HMODULE)hMod, szModule, len)) - return FALSE; - - // Point to the DOS header in memory - PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod; - - // From the DOS header, find the NT (PE) header - PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + DWORD_PTR(pDosHdr->e_lfanew)); - - PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHdr); - - DWORD_PTR rva = (DWORD_PTR)addr - hMod; // RVA is offset from module load address - - // Iterate through the section table, looking for the one that encompasses - // the linear address. - for (unsigned i = 0; - i < pNtHdr->FileHeader.NumberOfSections; - i++, pSection++) - { - DWORD_PTR sectionStart = pSection->VirtualAddress; - DWORD_PTR sectionEnd = sectionStart - + DWORD_PTR(std::max(pSection->SizeOfRawData, pSection->Misc.VirtualSize)); - - // Is the address in this section??? - if ((rva >= sectionStart) && (rva <= sectionEnd)) - { - // Yes, address is in the section. Calculate section and offset, - // and store in the "section" & "offset" params, which were - // passed by reference. - section = i+1; - offset = rva - sectionStart; - return TRUE; - } - } - - return FALSE; // Should never get here! -} - -// It contains SYMBOL_INFO structure plus additional -// space for the name of the symbol -struct CSymbolInfoPackage : public SYMBOL_INFO_PACKAGE -{ - CSymbolInfoPackage() - { - si.SizeOfStruct = sizeof(SYMBOL_INFO); - si.MaxNameLen = sizeof(name); - } -}; - -//============================================================ -// Walks the stack, and writes the results to the report file -//============================================================ -void WheatyExceptionReport::WriteStackDetails( -PCONTEXT pContext, -bool bWriteVariables, HANDLE pThreadHandle) // true if local/params should be output -{ - _tprintf(_T("\r\nCall stack:\r\n")); - - _tprintf(_T("Address Frame Function SourceFile\r\n")); - - DWORD dwMachineType = 0; - // Could use SymSetOptions here to add the SYMOPT_DEFERRED_LOADS flag - - STACKFRAME64 sf; - memset(&sf, 0, sizeof(sf)); - - #ifdef _M_IX86 - // Initialize the STACKFRAME structure for the first call. This is only - // necessary for Intel CPUs, and isn't mentioned in the documentation. - sf.AddrPC.Offset = pContext->Eip; - sf.AddrPC.Mode = AddrModeFlat; - sf.AddrStack.Offset = pContext->Esp; - sf.AddrStack.Mode = AddrModeFlat; - sf.AddrFrame.Offset = pContext->Ebp; - sf.AddrFrame.Mode = AddrModeFlat; - - dwMachineType = IMAGE_FILE_MACHINE_I386; - #endif - -#ifdef _M_X64 - sf.AddrPC.Offset = pContext->Rip; - sf.AddrPC.Mode = AddrModeFlat; - sf.AddrStack.Offset = pContext->Rsp; - sf.AddrStack.Mode = AddrModeFlat; - sf.AddrFrame.Offset = pContext->Rbp; - sf.AddrFrame.Mode = AddrModeFlat; - dwMachineType = IMAGE_FILE_MACHINE_AMD64; -#endif - - for (;;) - { - // Get the next stack frame - if (! StackWalk64(dwMachineType, - m_hProcess, - pThreadHandle != NULL ? pThreadHandle : GetCurrentThread(), - &sf, - pContext, - 0, - SymFunctionTableAccess64, - SymGetModuleBase64, - 0)) - break; - if (0 == sf.AddrFrame.Offset) // Basic sanity check to make sure - break; // the frame is OK. Bail if not. -#ifdef _M_IX86 - _tprintf(_T("%08X %08X "), sf.AddrPC.Offset, sf.AddrFrame.Offset); -#endif -#ifdef _M_X64 - _tprintf(_T("%016I64X %016I64X "), sf.AddrPC.Offset, sf.AddrFrame.Offset); -#endif - - DWORD64 symDisplacement = 0; // Displacement of the input address, - // relative to the start of the symbol - - // Get the name of the function for this stack frame entry - CSymbolInfoPackage sip; - if (SymFromAddr( - m_hProcess, // Process handle of the current process - sf.AddrPC.Offset, // Symbol address - &symDisplacement, // Address of the variable that will receive the displacement - &sip.si)) // Address of the SYMBOL_INFO structure (inside "sip" object) - { - _tprintf(_T("%hs+%I64X"), sip.si.Name, symDisplacement); - - } - else // No symbol found. Print out the logical address instead. - { - TCHAR szModule[MAX_PATH] = _T(""); - DWORD section = 0; - DWORD_PTR offset = 0; - - GetLogicalAddress((PVOID)sf.AddrPC.Offset, - szModule, sizeof(szModule), section, offset); -#ifdef _M_IX86 - _tprintf(_T("%04X:%08X %s"), section, offset, szModule); -#endif -#ifdef _M_X64 - _tprintf(_T("%04X:%016I64X %s"), section, offset, szModule); -#endif - } - - // Get the source line for this stack frame entry - IMAGEHLP_LINE64 lineInfo = { sizeof(IMAGEHLP_LINE64) }; - DWORD dwLineDisplacement; - if (SymGetLineFromAddr64(m_hProcess, sf.AddrPC.Offset, - &dwLineDisplacement, &lineInfo)) - { - _tprintf(_T(" %s line %u"), lineInfo.FileName, lineInfo.LineNumber); - } - - _tprintf(_T("\r\n")); - - // Write out the variables, if desired - if (bWriteVariables) - { - // Use SymSetContext to get just the locals/params for this frame - IMAGEHLP_STACK_FRAME imagehlpStackFrame; - imagehlpStackFrame.InstructionOffset = sf.AddrPC.Offset; - SymSetContext(m_hProcess, &imagehlpStackFrame, 0); - - // Enumerate the locals/parameters - SymEnumSymbols(m_hProcess, 0, 0, EnumerateSymbolsCallback, &sf); - - _tprintf(_T("\r\n")); - } - } - -} - -////////////////////////////////////////////////////////////////////////////// -// The function invoked by SymEnumSymbols -////////////////////////////////////////////////////////////////////////////// - -BOOL CALLBACK -WheatyExceptionReport::EnumerateSymbolsCallback( -PSYMBOL_INFO pSymInfo, -ULONG /*SymbolSize*/, -PVOID UserContext) -{ - - char szBuffer[WER_LARGE_BUFFER_SIZE]; - memset(szBuffer, 0, sizeof(szBuffer)); - - __try - { - ClearSymbols(); - if (FormatSymbolValue(pSymInfo, (STACKFRAME64*)UserContext, - szBuffer, sizeof(szBuffer))) - _tprintf(_T("%s"), szBuffer); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - _tprintf(_T("punting on symbol %s, partial output:\r\n"), pSymInfo->Name); - if (szBuffer[0] != '\0') - _tprintf(_T("%s"), szBuffer); - } - - return TRUE; -} - -////////////////////////////////////////////////////////////////////////////// -// Given a SYMBOL_INFO representing a particular variable, displays its -// contents. If it's a user defined type, display the members and their -// values. -////////////////////////////////////////////////////////////////////////////// -bool WheatyExceptionReport::FormatSymbolValue( -PSYMBOL_INFO pSym, -STACKFRAME64 * sf, -char * pszBuffer, -unsigned /*cbBuffer*/) -{ - char * pszCurrBuffer = pszBuffer; - - // If it's a function, don't do anything. - if (pSym->Tag == SymTagFunction) // SymTagFunction from CVCONST.H from the DIA SDK - return false; - - DWORD_PTR pVariable = 0; // Will point to the variable's data in memory - - if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_REGRELATIVE) - { - // if (pSym->Register == 8) // EBP is the value 8 (in DBGHELP 5.1) - { // This may change!!! -#ifdef _M_IX86 - pVariable = sf->AddrFrame.Offset; -#elif _M_X64 - pVariable = sf->AddrStack.Offset; -#endif - pVariable += (DWORD_PTR)pSym->Address; - } - // else - // return false; - } - else if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_REGISTER) - return false; // Don't try to report register variable - else - { - pVariable = (DWORD_PTR)pSym->Address; // It must be a global variable - } - - pszCurrBuffer = PushSymbolDetail(pszCurrBuffer); - - // Indicate if the variable is a local or parameter - if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_PARAMETER) - symbolDetails.top().Prefix = "Parameter "; - else if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_LOCAL) - symbolDetails.top().Prefix = "Local "; - - // Determine if the variable is a user defined type (UDT). IF so, bHandled - // will return true. - bool bHandled; - pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, pSym->ModBase, pSym->TypeIndex, - 0, pVariable, bHandled, pSym->Name, "", false, true); - - if (!bHandled) - { - // The symbol wasn't a UDT, so do basic, stupid formatting of the - // variable. Based on the size, we're assuming it's a char, WORD, or - // DWORD. - BasicType basicType = GetBasicType(pSym->TypeIndex, pSym->ModBase); - if (symbolDetails.top().Type.empty()) - symbolDetails.top().Type = rgBaseType[basicType]; - - // Emit the variable name - if (pSym->Name[0] != '\0') - symbolDetails.top().Name = pSym->Name; - - char buffer[50]; - FormatOutputValue(buffer, basicType, pSym->Size, (PVOID)pVariable, sizeof(buffer)); - symbolDetails.top().Value = buffer; - } - - pszCurrBuffer = PopSymbolDetail(pszCurrBuffer); - return true; -} - -////////////////////////////////////////////////////////////////////////////// -// If it's a user defined type (UDT), recurse through its members until we're -// at fundamental types. When he hit fundamental types, return -// bHandled = false, so that FormatSymbolValue() will format them. -////////////////////////////////////////////////////////////////////////////// -char * WheatyExceptionReport::DumpTypeIndex( -char * pszCurrBuffer, -DWORD64 modBase, -DWORD dwTypeIndex, -unsigned nestingLevel, -DWORD_PTR offset, -bool & bHandled, -const char* Name, -char* /*suffix*/, -bool newSymbol, -bool logChildren) -{ - bHandled = false; - - if (newSymbol) - pszCurrBuffer = PushSymbolDetail(pszCurrBuffer); - - DWORD typeTag; - if (!SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_SYMTAG, &typeTag)) - return pszCurrBuffer; - - // Get the name of the symbol. This will either be a Type name (if a UDT), - // or the structure member name. - WCHAR * pwszTypeName; - if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_SYMNAME, - &pwszTypeName)) - { - // handle special cases - if (wcscmp(pwszTypeName, L"std::basic_string<char,std::char_traits<char>,std::allocator<char> >") == 0) - { - LocalFree(pwszTypeName); - symbolDetails.top().Type = "std::string"; - char buffer[50]; - FormatOutputValue(buffer, btStdString, 0, (PVOID)offset, sizeof(buffer)); - symbolDetails.top().Value = buffer; - if (Name != NULL && Name[0] != '\0') - symbolDetails.top().Name = Name; - bHandled = true; - return pszCurrBuffer; - } - - char buffer[200]; - wcstombs(buffer, pwszTypeName, sizeof(buffer)); - buffer[199] = '\0'; - if (Name != NULL && Name[0] != '\0') - { - symbolDetails.top().Type = buffer; - symbolDetails.top().Name = Name; - } - else if (buffer[0] != '\0') - symbolDetails.top().Name = buffer; - - LocalFree(pwszTypeName); - } - else if (Name != NULL && Name[0] != '\0') - symbolDetails.top().Name = Name; - - if (!StoreSymbol(dwTypeIndex, offset)) - { - // Skip printing address and base class if it has been printed already - if (typeTag == SymTagBaseClass) - bHandled = true; - return pszCurrBuffer; - } - - DWORD innerTypeID; - switch (typeTag) - { - case SymTagPointerType: - if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &innerTypeID)) - { - if (Name != NULL && Name[0] != '\0') - symbolDetails.top().Name = Name; - - BOOL isReference; - SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_IS_REFERENCE, &isReference); - - char addressStr[40]; - memset(addressStr, 0, sizeof(addressStr)); - - if (isReference) - symbolDetails.top().Suffix += "&"; - else - symbolDetails.top().Suffix += "*"; - - // Try to dereference the pointer in a try/except block since it might be invalid - DWORD_PTR address = DereferenceUnsafePointer(offset); - - char buffer[50]; - FormatOutputValue(buffer, btVoid, sizeof(PVOID), (PVOID)offset, sizeof(buffer)); - symbolDetails.top().Value = buffer; - - if (nestingLevel >= WER_MAX_NESTING_LEVEL) - logChildren = false; - - // no need to log any children since the address is invalid anyway - if (address == NULL || address == DWORD_PTR(-1)) - logChildren = false; - - pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1, - address, bHandled, Name, addressStr, false, logChildren); - - if (!bHandled) - { - BasicType basicType = GetBasicType(dwTypeIndex, modBase); - if (symbolDetails.top().Type.empty()) - symbolDetails.top().Type = rgBaseType[basicType]; - - if (address == NULL) - symbolDetails.top().Value = "NULL"; - else if (address == DWORD_PTR(-1)) - symbolDetails.top().Value = "<Unable to read memory>"; - else - { - // Get the size of the child member - ULONG64 length; - SymGetTypeInfo(m_hProcess, modBase, innerTypeID, TI_GET_LENGTH, &length); - char buffer2[50]; - FormatOutputValue(buffer2, basicType, length, (PVOID)address, sizeof(buffer)); - symbolDetails.top().Value = buffer2; - } - bHandled = true; - return pszCurrBuffer; - } - else if (address == NULL) - symbolDetails.top().Value = "NULL"; - else if (address == DWORD_PTR(-1)) - { - symbolDetails.top().Value = "<Unable to read memory>"; - bHandled = true; - return pszCurrBuffer; - } - } - break; - case SymTagData: - if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &innerTypeID)) - { - DWORD innerTypeTag; - if (!SymGetTypeInfo(m_hProcess, modBase, innerTypeID, TI_GET_SYMTAG, &innerTypeTag)) - break; - - switch (innerTypeTag) - { - case SymTagUDT: - if (nestingLevel >= WER_MAX_NESTING_LEVEL) - logChildren = false; - pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1, - offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren); - break; - case SymTagPointerType: - if (Name != NULL && Name[0] != '\0') - symbolDetails.top().Name = Name; - pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1, - offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren); - break; - case SymTagArrayType: - pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1, - offset, bHandled, symbolDetails.top().Name.c_str(), "", false, logChildren); - break; - default: - break; - } - } - break; - case SymTagArrayType: - if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_TYPEID, &innerTypeID)) - { - symbolDetails.top().HasChildren = true; - - BasicType basicType = btNoType; - pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, innerTypeID, nestingLevel + 1, - offset, bHandled, Name, "", false, false); - - // Set Value back to an empty string since the Array object itself has no value, only its elements have - symbolDetails.top().Value.clear(); - - DWORD elementsCount; - if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_COUNT, &elementsCount)) - symbolDetails.top().Suffix += "[" + std::to_string(elementsCount) + "]"; - else - symbolDetails.top().Suffix += "[<unknown count>]"; - - if (!bHandled) - { - basicType = GetBasicType(dwTypeIndex, modBase); - if (symbolDetails.top().Type.empty()) - symbolDetails.top().Type = rgBaseType[basicType]; - bHandled = true; - } - - // Get the size of the child member - ULONG64 length; - SymGetTypeInfo(m_hProcess, modBase, innerTypeID, TI_GET_LENGTH, &length); - - char buffer[50]; - switch (basicType) - { - case btChar: - case btStdString: - FormatOutputValue(buffer, basicType, length, (PVOID)offset, sizeof(buffer), elementsCount); - symbolDetails.top().Value = buffer; - break; - default: - for (DWORD index = 0; index < elementsCount && index < WER_MAX_ARRAY_ELEMENTS_COUNT; index++) - { - pszCurrBuffer = PushSymbolDetail(pszCurrBuffer); - symbolDetails.top().Suffix += "[" + std::to_string(index) + "]"; - FormatOutputValue(buffer, basicType, length, (PVOID)(offset + length * index), sizeof(buffer)); - symbolDetails.top().Value = buffer; - pszCurrBuffer = PopSymbolDetail(pszCurrBuffer); - } - break; - } - - return pszCurrBuffer; - } - break; - case SymTagBaseType: - break; - case SymTagEnum: - return pszCurrBuffer; - default: - break; - } - - // Determine how many children this type has. - DWORD dwChildrenCount = 0; - SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_CHILDRENCOUNT, &dwChildrenCount); - - if (!dwChildrenCount) // If no children, we're done - return pszCurrBuffer; - - // Prepare to get an array of "TypeIds", representing each of the children. - // SymGetTypeInfo(TI_FINDCHILDREN) expects more memory than just a - // TI_FINDCHILDREN_PARAMS struct has. Use derivation to accomplish this. - struct FINDCHILDREN : TI_FINDCHILDREN_PARAMS - { - ULONG MoreChildIds[1024*2]; - FINDCHILDREN(){Count = sizeof(MoreChildIds) / sizeof(MoreChildIds[0]);} - } children; - - children.Count = dwChildrenCount; - children.Start= 0; - - // Get the array of TypeIds, one for each child type - if (!SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_FINDCHILDREN, - &children)) - { - return pszCurrBuffer; - } - - // Iterate through each of the children - for (unsigned i = 0; i < dwChildrenCount; i++) - { - DWORD symTag; - SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i], TI_GET_SYMTAG, &symTag); - - if (symTag == SymTagFunction || - symTag == SymTagEnum || - symTag == SymTagTypedef || - symTag == SymTagVTable) - continue; - - // Ignore static fields - DWORD dataKind; - SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i], TI_GET_DATAKIND, &dataKind); - if (dataKind == DataIsStaticLocal || - dataKind == DataIsGlobal || - dataKind == DataIsStaticMember) - continue; - - - symbolDetails.top().HasChildren = true; - if (!logChildren) - { - bHandled = false; - return pszCurrBuffer; - } - - // Recurse for each of the child types - bool bHandled2; - BasicType basicType = GetBasicType(children.ChildId[i], modBase); - - // Get the offset of the child member, relative to its parent - DWORD dwMemberOffset; - SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i], - TI_GET_OFFSET, &dwMemberOffset); - - // Calculate the address of the member - DWORD_PTR dwFinalOffset = offset + dwMemberOffset; - - pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase, - children.ChildId[i], nestingLevel+1, - dwFinalOffset, bHandled2, ""/*Name */, "", true, true); - - // If the child wasn't a UDT, format it appropriately - if (!bHandled2) - { - if (symbolDetails.top().Type.empty()) - symbolDetails.top().Type = rgBaseType[basicType]; - - // Get the real "TypeId" of the child. We need this for the - // SymGetTypeInfo(TI_GET_TYPEID) call below. - DWORD typeId; - SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i], - TI_GET_TYPEID, &typeId); - - // Get the size of the child member - ULONG64 length; - SymGetTypeInfo(m_hProcess, modBase, typeId, TI_GET_LENGTH, &length); - - char buffer[50]; - FormatOutputValue(buffer, basicType, length, (PVOID)dwFinalOffset, sizeof(buffer)); - symbolDetails.top().Value = buffer; - } - - pszCurrBuffer = PopSymbolDetail(pszCurrBuffer); - } - - bHandled = true; - return pszCurrBuffer; -} - -void WheatyExceptionReport::FormatOutputValue(char * pszCurrBuffer, -BasicType basicType, -DWORD64 length, -PVOID pAddress, -size_t bufferSize, -size_t countOverride) -{ - __try - { - switch (basicType) - { - case btChar: - { - // Special case handling for char[] type - if (countOverride != 0) - length = countOverride; - else - length = strlen((char*)pAddress); - if (length > bufferSize - 6) - pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s...\"", (DWORD)(bufferSize - 6), (char*)pAddress); - else - pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s\"", (DWORD)length, (char*)pAddress); - break; - } - case btStdString: - { - std::string* value = static_cast<std::string*>(pAddress); - if (value->length() > bufferSize - 6) - pszCurrBuffer += sprintf(pszCurrBuffer, "\"%.*s...\"", (DWORD)(bufferSize - 6), value->c_str()); - else - pszCurrBuffer += sprintf(pszCurrBuffer, "\"%s\"", value->c_str()); - break; - } - default: - // Format appropriately (assuming it's a 1, 2, or 4 bytes (!!!) - if (length == 1) - pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X", *(PBYTE)pAddress); - else if (length == 2) - pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X", *(PWORD)pAddress); - else if (length == 4) - { - if (basicType == btFloat) - pszCurrBuffer += sprintf(pszCurrBuffer, "%f", *(PFLOAT)pAddress); - else - pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X", *(PDWORD)pAddress); - } - else if (length == 8) - { - if (basicType == btFloat) - { - pszCurrBuffer += sprintf(pszCurrBuffer, "%f", - *(double *)pAddress); - } - else - pszCurrBuffer += sprintf(pszCurrBuffer, "0x%I64X", - *(DWORD64*)pAddress); - } - else - { - #if _WIN64 - pszCurrBuffer += sprintf(pszCurrBuffer, "0x%I64X", (DWORD64)pAddress); - #else - pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X", (DWORD)pAddress); - #endif - } - break; - } - } - __except (EXCEPTION_EXECUTE_HANDLER) - { -#if _WIN64 - pszCurrBuffer += sprintf(pszCurrBuffer, "0x%I64X <Unable to read memory>", (DWORD64)pAddress); -#else - pszCurrBuffer += sprintf(pszCurrBuffer, "0x%X <Unable to read memory>", (DWORD)pAddress); -#endif - } -} - -BasicType -WheatyExceptionReport::GetBasicType(DWORD typeIndex, DWORD64 modBase) -{ - BasicType basicType; - if (SymGetTypeInfo(m_hProcess, modBase, typeIndex, - TI_GET_BASETYPE, &basicType)) - { - return basicType; - } - - // Get the real "TypeId" of the child. We need this for the - // SymGetTypeInfo(TI_GET_TYPEID) call below. - DWORD typeId; - if (SymGetTypeInfo(m_hProcess, modBase, typeIndex, TI_GET_TYPEID, &typeId)) - { - if (SymGetTypeInfo(m_hProcess, modBase, typeId, TI_GET_BASETYPE, - &basicType)) - { - return basicType; - } - } - - return btNoType; -} - -DWORD_PTR WheatyExceptionReport::DereferenceUnsafePointer(DWORD_PTR address) -{ - __try - { - return *(PDWORD_PTR)address; - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - return DWORD_PTR(-1); - } -} - -//============================================================================ -// Helper function that writes to the report file, and allows the user to use -// printf style formating -//============================================================================ -int __cdecl WheatyExceptionReport::_tprintf(const TCHAR * format, ...) -{ - int retValue; - va_list argptr; - va_start(argptr, format); - if (stackOverflowException) - { - retValue = heapprintf(format, argptr); - va_end(argptr); - } - else - { - retValue = stackprintf(format, argptr); - va_end(argptr); - } - - return retValue; -} - -int __cdecl WheatyExceptionReport::stackprintf(const TCHAR * format, va_list argptr) -{ - int retValue; - DWORD cbWritten; - - TCHAR szBuff[WER_LARGE_BUFFER_SIZE]; - retValue = vsprintf(szBuff, format, argptr); - WriteFile(m_hReportFile, szBuff, retValue * sizeof(TCHAR), &cbWritten, 0); - - return retValue; -} - -int __cdecl WheatyExceptionReport::heapprintf(const TCHAR * format, va_list argptr) -{ - int retValue; - DWORD cbWritten; - TCHAR* szBuff = (TCHAR*)malloc(sizeof(TCHAR) * WER_LARGE_BUFFER_SIZE); - retValue = vsprintf(szBuff, format, argptr); - WriteFile(m_hReportFile, szBuff, retValue * sizeof(TCHAR), &cbWritten, 0); - free(szBuff); - - return retValue; -} - -bool WheatyExceptionReport::StoreSymbol(DWORD type, DWORD_PTR offset) -{ - return symbols.insert(SymbolPair(type, offset)).second; -} - -void WheatyExceptionReport::ClearSymbols() -{ - symbols.clear(); - while (!symbolDetails.empty()) - symbolDetails.pop(); -} - -char* WheatyExceptionReport::PushSymbolDetail(char* pszCurrBuffer) -{ - // Log current symbol and then add another to the stack to keep the hierarchy format - pszCurrBuffer = PrintSymbolDetail(pszCurrBuffer); - symbolDetails.emplace(); - return pszCurrBuffer; -} - -char* WheatyExceptionReport::PopSymbolDetail(char* pszCurrBuffer) -{ - pszCurrBuffer = PrintSymbolDetail(pszCurrBuffer); - symbolDetails.pop(); - return pszCurrBuffer; -} - -char* WheatyExceptionReport::PrintSymbolDetail(char* pszCurrBuffer) -{ - if (symbolDetails.empty()) - return pszCurrBuffer; - - // Don't log anything if has been logged already or if it's empty - if (symbolDetails.top().Logged || symbolDetails.top().empty()) - return pszCurrBuffer; - - // Add appropriate indentation level (since this routine is recursive) - for (size_t i = 0; i < symbolDetails.size(); i++) - pszCurrBuffer += sprintf(pszCurrBuffer, "\t"); - - pszCurrBuffer += sprintf(pszCurrBuffer, "%s\r\n", symbolDetails.top().ToString().c_str()); - - return pszCurrBuffer; -} - -#endif // _WIN32 diff --git a/src/server/shared/Debugging/WheatyExceptionReport.h b/src/server/shared/Debugging/WheatyExceptionReport.h deleted file mode 100644 index 8c2479d5232..00000000000 --- a/src/server/shared/Debugging/WheatyExceptionReport.h +++ /dev/null @@ -1,210 +0,0 @@ -#ifndef _WHEATYEXCEPTIONREPORT_ -#define _WHEATYEXCEPTIONREPORT_ - -#if PLATFORM == PLATFORM_WINDOWS && !defined(__MINGW32__) - -#include <dbghelp.h> -#include <set> -#include <stdlib.h> -#include <stack> -#include <mutex> -#define countof _countof - -#define WER_MAX_ARRAY_ELEMENTS_COUNT 10 -#define WER_MAX_NESTING_LEVEL 5 -#define WER_LARGE_BUFFER_SIZE 1024 * 128 - -enum BasicType // Stolen from CVCONST.H in the DIA 2.0 SDK -{ - btNoType = 0, - btVoid = 1, - btChar = 2, - btWChar = 3, - btInt = 6, - btUInt = 7, - btFloat = 8, - btBCD = 9, - btBool = 10, - btLong = 13, - btULong = 14, - btCurrency = 25, - btDate = 26, - btVariant = 27, - btComplex = 28, - btBit = 29, - btBSTR = 30, - btHresult = 31, - - // Custom types - btStdString = 101 -}; - -enum DataKind // Stolen from CVCONST.H in the DIA 2.0 SDK -{ - DataIsUnknown, - DataIsLocal, - DataIsStaticLocal, - DataIsParam, - DataIsObjectPtr, - DataIsFileStatic, - DataIsGlobal, - DataIsMember, - DataIsStaticMember, - DataIsConstant -}; - -const char* const rgBaseType[] = -{ - "<user defined>", // btNoType = 0, - "void", // btVoid = 1, - "char",//char* // btChar = 2, - "wchar_t*", // btWChar = 3, - "signed char", - "unsigned char", - "int", // btInt = 6, - "unsigned int", // btUInt = 7, - "float", // btFloat = 8, - "<BCD>", // btBCD = 9, - "bool", // btBool = 10, - "short", - "unsigned short", - "long", // btLong = 13, - "unsigned long", // btULong = 14, - "int8", - "int16", - "int32", - "int64", - "int128", - "uint8", - "uint16", - "uint32", - "uint64", - "uint128", - "<currency>", // btCurrency = 25, - "<date>", // btDate = 26, - "VARIANT", // btVariant = 27, - "<complex>", // btComplex = 28, - "<bit>", // btBit = 29, - "BSTR", // btBSTR = 30, - "HRESULT" // btHresult = 31 -}; - -struct SymbolPair -{ - SymbolPair(DWORD type, DWORD_PTR offset) - { - _type = type; - _offset = offset; - } - - bool operator<(const SymbolPair& other) const - { - return _offset < other._offset || - (_offset == other._offset && _type < other._type); - } - - DWORD _type; - DWORD_PTR _offset; -}; -typedef std::set<SymbolPair> SymbolPairs; - -struct SymbolDetail -{ - SymbolDetail() : Prefix(), Type(), Suffix(), Name(), Value(), Logged(false), HasChildren(false) {} - - std::string ToString() - { - Logged = true; - std::string formatted = Prefix + Type + Suffix; - if (!Name.empty()) - { - if (!formatted.empty()) - formatted += " "; - formatted += Name; - } - if (!Value.empty()) - formatted += " = " + Value; - return formatted; - } - - bool empty() const - { - return Value.empty() && !HasChildren; - } - - std::string Prefix; - std::string Type; - std::string Suffix; - std::string Name; - std::string Value; - bool Logged; - bool HasChildren; -}; - -class WheatyExceptionReport -{ - public: - - WheatyExceptionReport(); - ~WheatyExceptionReport(); - - // entry point where control comes on an unhandled exception - static LONG WINAPI WheatyUnhandledExceptionFilter( - PEXCEPTION_POINTERS pExceptionInfo); - - static void printTracesForAllThreads(bool); - private: - // where report info is extracted and generated - static void GenerateExceptionReport(PEXCEPTION_POINTERS pExceptionInfo); - static void PrintSystemInfo(); - static BOOL _GetWindowsVersion(TCHAR* szVersion, DWORD cntMax); - static BOOL _GetProcessorName(TCHAR* sProcessorName, DWORD maxcount); - - // Helper functions - static LPTSTR GetExceptionString(DWORD dwCode); - static BOOL GetLogicalAddress(PVOID addr, PTSTR szModule, DWORD len, - DWORD& section, DWORD_PTR& offset); - - static void WriteStackDetails(PCONTEXT pContext, bool bWriteVariables, HANDLE pThreadHandle); - - static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO, ULONG, PVOID); - - static bool FormatSymbolValue(PSYMBOL_INFO, STACKFRAME64 *, char * pszBuffer, unsigned cbBuffer); - - static char * DumpTypeIndex(char *, DWORD64, DWORD, unsigned, DWORD_PTR, bool &, const char*, char*, bool, bool); - - static void FormatOutputValue(char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress, size_t bufferSize, size_t countOverride = 0); - - static BasicType GetBasicType(DWORD typeIndex, DWORD64 modBase); - static DWORD_PTR DereferenceUnsafePointer(DWORD_PTR address); - - static int __cdecl _tprintf(const TCHAR * format, ...); - static int __cdecl stackprintf(const TCHAR * format, va_list argptr); - static int __cdecl heapprintf(const TCHAR * format, va_list argptr); - - static bool StoreSymbol(DWORD type , DWORD_PTR offset); - static void ClearSymbols(); - - // Variables used by the class - static TCHAR m_szLogFileName[MAX_PATH]; - static TCHAR m_szDumpFileName[MAX_PATH]; - static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter; - static HANDLE m_hReportFile; - static HANDLE m_hDumpFile; - static HANDLE m_hProcess; - static SymbolPairs symbols; - static std::stack<SymbolDetail> symbolDetails; - static bool stackOverflowException; - static bool alreadyCrashed; - static std::mutex alreadyCrashedLock; - - static char* PushSymbolDetail(char* pszCurrBuffer); - static char* PopSymbolDetail(char* pszCurrBuffer); - static char* PrintSymbolDetail(char* pszCurrBuffer); - -}; - -extern WheatyExceptionReport g_WheatyExceptionReport; // global instance of class -#endif // _WIN32 -#endif // _WHEATYEXCEPTIONREPORT_ - diff --git a/src/server/shared/Define.h b/src/server/shared/Define.h deleted file mode 100644 index 97e07cef8b3..00000000000 --- a/src/server/shared/Define.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef TRINITY_DEFINE_H -#define TRINITY_DEFINE_H - -#include "CompilerDefs.h" - -#if COMPILER == COMPILER_GNU -# if !defined(__STDC_FORMAT_MACROS) -# define __STDC_FORMAT_MACROS -# endif -# if !defined(__STDC_CONSTANT_MACROS) -# define __STDC_CONSTANT_MACROS -# endif -# if !defined(_GLIBCXX_USE_NANOSLEEP) -# define _GLIBCXX_USE_NANOSLEEP -# endif -# if defined(HELGRIND) -# include <valgrind/helgrind.h> -# define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) ANNOTATE_HAPPENS_BEFORE(A) -# define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) ANNOTATE_HAPPENS_AFTER(A) -# endif -#endif - -#include <cstddef> -#include <cinttypes> -#include <climits> - -#define TRINITY_LITTLEENDIAN 0 -#define TRINITY_BIGENDIAN 1 - -#if !defined(TRINITY_ENDIAN) -# if defined (BOOST_BIG_ENDIAN) -# define TRINITY_ENDIAN TRINITY_BIGENDIAN -# else -# define TRINITY_ENDIAN TRINITY_LITTLEENDIAN -# endif -#endif - -#if PLATFORM == PLATFORM_WINDOWS -# define TRINITY_PATH_MAX MAX_PATH -# define _USE_MATH_DEFINES -# ifndef DECLSPEC_NORETURN -# define DECLSPEC_NORETURN __declspec(noreturn) -# endif //DECLSPEC_NORETURN -# ifndef DECLSPEC_DEPRECATED -# define DECLSPEC_DEPRECATED __declspec(deprecated) -# endif //DECLSPEC_DEPRECATED -#else //PLATFORM != PLATFORM_WINDOWS -# define TRINITY_PATH_MAX PATH_MAX -# define DECLSPEC_NORETURN -# define DECLSPEC_DEPRECATED -#endif //PLATFORM - -#if !defined(COREDEBUG) -# define TRINITY_INLINE inline -#else //COREDEBUG -# if !defined(TRINITY_DEBUG) -# define TRINITY_DEBUG -# endif //TRINITY_DEBUG -# define TRINITY_INLINE -#endif //!COREDEBUG - -#if COMPILER == COMPILER_GNU -# define ATTR_NORETURN __attribute__((__noreturn__)) -# define ATTR_PRINTF(F, V) __attribute__ ((__format__ (__printf__, F, V))) -# define ATTR_DEPRECATED __attribute__((__deprecated__)) -#else //COMPILER != COMPILER_GNU -# define ATTR_NORETURN -# define ATTR_PRINTF(F, V) -# define ATTR_DEPRECATED -#endif //COMPILER == COMPILER_GNU - -#define UI64FMTD "%" PRIu64 -#define UI64LIT(N) UINT64_C(N) - -#define SI64FMTD "%" PRId64 -#define SI64LIT(N) INT64_C(N) - -#define SZFMTD "%" PRIuPTR - -typedef int64_t int64; -typedef int32_t int32; -typedef int16_t int16; -typedef int8_t int8; -typedef uint64_t uint64; -typedef uint32_t uint32; -typedef uint16_t uint16; -typedef uint8_t uint8; - -#endif //TRINITY_DEFINE_H diff --git a/src/server/shared/Logging/Appender.cpp b/src/server/shared/Logging/Appender.cpp deleted file mode 100644 index d19ef8cf96f..00000000000 --- a/src/server/shared/Logging/Appender.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "Appender.h" -#include "Common.h" -#include "Util.h" -#include "StringFormat.h" - -#include <utility> -#include <sstream> - -std::string LogMessage::getTimeStr(time_t time) -{ - tm aTm; - localtime_r(&time, &aTm); - char buf[20]; - snprintf(buf, 20, "%04d-%02d-%02d_%02d:%02d:%02d", aTm.tm_year+1900, aTm.tm_mon+1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec); - return std::string(buf); -} - -std::string LogMessage::getTimeStr() -{ - return getTimeStr(mtime); -} - -Appender::Appender(uint8 _id, std::string const& _name, LogLevel _level /* = LOG_LEVEL_DISABLED */, AppenderFlags _flags /* = APPENDER_FLAGS_NONE */): -id(_id), name(_name), level(_level), flags(_flags) { } - -Appender::~Appender() { } - -uint8 Appender::getId() const -{ - return id; -} - -std::string const& Appender::getName() const -{ - return name; -} - -LogLevel Appender::getLogLevel() const -{ - return level; -} - -AppenderFlags Appender::getFlags() const -{ - return flags; -} - -void Appender::setLogLevel(LogLevel _level) -{ - level = _level; -} - -void Appender::write(LogMessage* message) -{ - if (!level || level > message->level) - return; - - std::ostringstream ss; - - if (flags & APPENDER_FLAGS_PREFIX_TIMESTAMP) - ss << message->getTimeStr() << ' '; - - if (flags & APPENDER_FLAGS_PREFIX_LOGLEVEL) - ss << Trinity::StringFormat("%-5s ", Appender::getLogLevelString(message->level)); - - if (flags & APPENDER_FLAGS_PREFIX_LOGFILTERTYPE) - ss << '[' << message->type << "] "; - - message->prefix = ss.str(); - _write(message); -} - -const char* Appender::getLogLevelString(LogLevel level) -{ - switch (level) - { - case LOG_LEVEL_FATAL: - return "FATAL"; - case LOG_LEVEL_ERROR: - return "ERROR"; - case LOG_LEVEL_WARN: - return "WARN"; - case LOG_LEVEL_INFO: - return "INFO"; - case LOG_LEVEL_DEBUG: - return "DEBUG"; - case LOG_LEVEL_TRACE: - return "TRACE"; - default: - return "DISABLED"; - } -} diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h deleted file mode 100644 index 7c5aa41924d..00000000000 --- a/src/server/shared/Logging/Appender.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef APPENDER_H -#define APPENDER_H - -#include <unordered_map> -#include <stdexcept> -#include <string> -#include <time.h> -#include <type_traits> -#include <vector> -#include <utility> -#include "Define.h" - -// Values assigned have their equivalent in enum ACE_Log_Priority -enum LogLevel -{ - LOG_LEVEL_DISABLED = 0, - LOG_LEVEL_TRACE = 1, - LOG_LEVEL_DEBUG = 2, - LOG_LEVEL_INFO = 3, - LOG_LEVEL_WARN = 4, - LOG_LEVEL_ERROR = 5, - LOG_LEVEL_FATAL = 6 -}; - -const uint8 MaxLogLevels = 6; - -enum AppenderType -{ - APPENDER_NONE, - APPENDER_CONSOLE, - APPENDER_FILE, - APPENDER_DB -}; - -enum AppenderFlags -{ - APPENDER_FLAGS_NONE = 0x00, - APPENDER_FLAGS_PREFIX_TIMESTAMP = 0x01, - APPENDER_FLAGS_PREFIX_LOGLEVEL = 0x02, - APPENDER_FLAGS_PREFIX_LOGFILTERTYPE = 0x04, - APPENDER_FLAGS_USE_TIMESTAMP = 0x08, // only used by FileAppender - APPENDER_FLAGS_MAKE_FILE_BACKUP = 0x10 // only used by FileAppender -}; - -struct LogMessage -{ - LogMessage(LogLevel _level, std::string const& _type, std::string&& _text) - : level(_level), type(_type), text(std::forward<std::string>(_text)), mtime(time(NULL)) - { } - - LogMessage(LogMessage const& /*other*/) = delete; - LogMessage& operator=(LogMessage const& /*other*/) = delete; - - static std::string getTimeStr(time_t time); - std::string getTimeStr(); - - LogLevel const level; - std::string const type; - std::string const text; - std::string prefix; - std::string param1; - time_t mtime; - - ///@ Returns size of the log message content in bytes - uint32 Size() const - { - return static_cast<uint32>(prefix.size() + text.size()); - } -}; - -class Appender -{ - public: - Appender(uint8 _id, std::string const& name, LogLevel level = LOG_LEVEL_DISABLED, AppenderFlags flags = APPENDER_FLAGS_NONE); - virtual ~Appender(); - - uint8 getId() const; - std::string const& getName() const; - virtual AppenderType getType() const = 0; - LogLevel getLogLevel() const; - AppenderFlags getFlags() const; - - void setLogLevel(LogLevel); - void write(LogMessage* message); - static const char* getLogLevelString(LogLevel level); - virtual void setRealmId(uint32 /*realmId*/) { } - - private: - virtual void _write(LogMessage const* /*message*/) = 0; - - uint8 id; - std::string name; - LogLevel level; - AppenderFlags flags; -}; - -typedef std::unordered_map<uint8, Appender*> AppenderMap; - -typedef std::vector<char const*> ExtraAppenderArgs; -typedef Appender*(*AppenderCreatorFn)(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs); -typedef std::unordered_map<uint8, AppenderCreatorFn> AppenderCreatorMap; - -template<class AppenderImpl> -Appender* CreateAppender(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs) -{ - return new AppenderImpl(id, name, level, flags, std::forward<ExtraAppenderArgs>(extraArgs)); -} - -class InvalidAppenderArgsException : public std::length_error -{ -public: - using std::length_error::length_error; - - explicit InvalidAppenderArgsException(std::string const& message) : length_error(message) { } -}; - -#endif diff --git a/src/server/shared/Logging/AppenderConsole.cpp b/src/server/shared/Logging/AppenderConsole.cpp deleted file mode 100644 index 531df266aa1..00000000000 --- a/src/server/shared/Logging/AppenderConsole.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include <sstream> - -#include "AppenderConsole.h" -#include "Config.h" -#include "Util.h" - -#if PLATFORM == PLATFORM_WINDOWS - #include <Windows.h> -#endif - -AppenderConsole::AppenderConsole(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs) - : Appender(id, name, level, flags), _colored(false) -{ - for (uint8 i = 0; i < MaxLogLevels; ++i) - _colors[i] = ColorTypes(MaxColors); - - if (!extraArgs.empty()) - InitColors(extraArgs[0]); -} - -void AppenderConsole::InitColors(std::string const& str) -{ - if (str.empty()) - { - _colored = false; - return; - } - - int color[MaxLogLevels]; - - std::istringstream ss(str); - - for (uint8 i = 0; i < MaxLogLevels; ++i) - { - ss >> color[i]; - - if (!ss) - return; - - if (color[i] < 0 || color[i] >= MaxColors) - return; - } - - for (uint8 i = 0; i < MaxLogLevels; ++i) - _colors[i] = ColorTypes(color[i]); - - _colored = true; -} - -void AppenderConsole::SetColor(bool stdout_stream, ColorTypes color) -{ -#if PLATFORM == PLATFORM_WINDOWS - static WORD WinColorFG[MaxColors] = - { - 0, // BLACK - FOREGROUND_RED, // RED - FOREGROUND_GREEN, // GREEN - FOREGROUND_RED | FOREGROUND_GREEN, // BROWN - FOREGROUND_BLUE, // BLUE - FOREGROUND_RED | FOREGROUND_BLUE, // MAGENTA - FOREGROUND_GREEN | FOREGROUND_BLUE, // CYAN - FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // WHITE - // YELLOW - FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY, - // RED_BOLD - FOREGROUND_RED | FOREGROUND_INTENSITY, - // GREEN_BOLD - FOREGROUND_GREEN | FOREGROUND_INTENSITY, - FOREGROUND_BLUE | FOREGROUND_INTENSITY, // BLUE_BOLD - // MAGENTA_BOLD - FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY, - // CYAN_BOLD - FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY, - // WHITE_BOLD - FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY - }; - - HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE); - SetConsoleTextAttribute(hConsole, WinColorFG[color]); -#else - enum ANSITextAttr - { - TA_NORMAL = 0, - TA_BOLD = 1, - TA_BLINK = 5, - TA_REVERSE = 7 - }; - - enum ANSIFgTextAttr - { - FG_BLACK = 30, - FG_RED, - FG_GREEN, - FG_BROWN, - FG_BLUE, - FG_MAGENTA, - FG_CYAN, - FG_WHITE, - FG_YELLOW - }; - - enum ANSIBgTextAttr - { - BG_BLACK = 40, - BG_RED, - BG_GREEN, - BG_BROWN, - BG_BLUE, - BG_MAGENTA, - BG_CYAN, - BG_WHITE - }; - - static uint8 UnixColorFG[MaxColors] = - { - FG_BLACK, // BLACK - FG_RED, // RED - FG_GREEN, // GREEN - FG_BROWN, // BROWN - FG_BLUE, // BLUE - FG_MAGENTA, // MAGENTA - FG_CYAN, // CYAN - FG_WHITE, // WHITE - FG_YELLOW, // YELLOW - FG_RED, // LRED - FG_GREEN, // LGREEN - FG_BLUE, // LBLUE - FG_MAGENTA, // LMAGENTA - FG_CYAN, // LCYAN - FG_WHITE // LWHITE - }; - - fprintf((stdout_stream? stdout : stderr), "\x1b[%d%sm", UnixColorFG[color], (color >= YELLOW && color < MaxColors ? ";1" : "")); - #endif -} - -void AppenderConsole::ResetColor(bool stdout_stream) -{ - #if PLATFORM == PLATFORM_WINDOWS - HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE); - SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); - #else - fprintf((stdout_stream ? stdout : stderr), "\x1b[0m"); - #endif -} - -void AppenderConsole::_write(LogMessage const* message) -{ - bool stdout_stream = !(message->level == LOG_LEVEL_ERROR || message->level == LOG_LEVEL_FATAL); - - if (_colored) - { - uint8 index; - switch (message->level) - { - case LOG_LEVEL_TRACE: - index = 5; - break; - case LOG_LEVEL_DEBUG: - index = 4; - break; - case LOG_LEVEL_INFO: - index = 3; - break; - case LOG_LEVEL_WARN: - index = 2; - break; - case LOG_LEVEL_FATAL: - index = 0; - break; - case LOG_LEVEL_ERROR: // No break on purpose - default: - index = 1; - break; - } - - SetColor(stdout_stream, _colors[index]); - utf8printf(stdout_stream ? stdout : stderr, "%s%s\n", message->prefix.c_str(), message->text.c_str()); - ResetColor(stdout_stream); - } - else - utf8printf(stdout_stream ? stdout : stderr, "%s%s\n", message->prefix.c_str(), message->text.c_str()); -} diff --git a/src/server/shared/Logging/AppenderConsole.h b/src/server/shared/Logging/AppenderConsole.h deleted file mode 100644 index 6b30505c6bd..00000000000 --- a/src/server/shared/Logging/AppenderConsole.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef APPENDERCONSOLE_H -#define APPENDERCONSOLE_H - -#include <string> -#include "Appender.h" - -enum ColorTypes -{ - BLACK, - RED, - GREEN, - BROWN, - BLUE, - MAGENTA, - CYAN, - GREY, - YELLOW, - LRED, - LGREEN, - LBLUE, - LMAGENTA, - LCYAN, - WHITE -}; - -const uint8 MaxColors = uint8(WHITE) + 1; - -class AppenderConsole : public Appender -{ - public: - typedef std::integral_constant<AppenderType, APPENDER_CONSOLE>::type TypeIndex; - - AppenderConsole(uint8 _id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs); - void InitColors(const std::string& init_str); - AppenderType getType() const override { return TypeIndex::value; } - - private: - void SetColor(bool stdout_stream, ColorTypes color); - void ResetColor(bool stdout_stream); - void _write(LogMessage const* message) override; - bool _colored; - ColorTypes _colors[MaxLogLevels]; -}; - -#endif diff --git a/src/server/shared/Logging/AppenderDB.cpp b/src/server/shared/Logging/AppenderDB.cpp deleted file mode 100644 index 9e6ab1a057c..00000000000 --- a/src/server/shared/Logging/AppenderDB.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "AppenderDB.h" -#include "Database/DatabaseEnv.h" - -AppenderDB::AppenderDB(uint8 id, std::string const& name, LogLevel level, AppenderFlags /*flags*/, ExtraAppenderArgs /*extraArgs*/) - : Appender(id, name, level), realmId(0), enabled(false) { } - -AppenderDB::~AppenderDB() { } - -void AppenderDB::_write(LogMessage const* message) -{ - // Avoid infinite loop, PExecute triggers Logging with "sql.sql" type - if (!enabled || (message->type.find("sql") != std::string::npos)) - return; - - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_LOG); - stmt->setUInt64(0, message->mtime); - stmt->setUInt32(1, realmId); - stmt->setString(2, message->type); - stmt->setUInt8(3, uint8(message->level)); - stmt->setString(4, message->text); - LoginDatabase.Execute(stmt); -} - -void AppenderDB::setRealmId(uint32 _realmId) -{ - enabled = true; - realmId = _realmId; -} diff --git a/src/server/shared/Logging/AppenderDB.h b/src/server/shared/Logging/AppenderDB.h deleted file mode 100644 index 50607fd8136..00000000000 --- a/src/server/shared/Logging/AppenderDB.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef APPENDERDB_H -#define APPENDERDB_H - -#include "Appender.h" - -class AppenderDB: public Appender -{ - public: - typedef std::integral_constant<AppenderType, APPENDER_DB>::type TypeIndex; - - AppenderDB(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs); - ~AppenderDB(); - - void setRealmId(uint32 realmId) override; - AppenderType getType() const override { return TypeIndex::value; } - - private: - uint32 realmId; - bool enabled; - void _write(LogMessage const* message) override; -}; - -#endif diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp deleted file mode 100644 index d33818626fe..00000000000 --- a/src/server/shared/Logging/AppenderFile.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "AppenderFile.h" -#include "Common.h" -#include "StringFormat.h" -#include "Log.h" - -#if PLATFORM == PLATFORM_WINDOWS -# include <Windows.h> -#endif - -AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs) : - Appender(id, name, level, flags), - logfile(NULL), - _logDir(sLog->GetLogsDir()), - _fileSize(0) -{ - if (extraArgs.empty()) - throw InvalidAppenderArgsException(Trinity::StringFormat("Log::CreateAppenderFromConfig: Missing file name for appender %s\n", name.c_str())); - - _fileName = extraArgs[0]; - - char const* mode = "a"; - if (extraArgs.size() > 1) - mode = extraArgs[1]; - - if (flags & APPENDER_FLAGS_USE_TIMESTAMP) - { - size_t dot_pos = _fileName.find_last_of("."); - if (dot_pos != std::string::npos) - _fileName.insert(dot_pos, sLog->GetLogsTimestamp()); - else - _fileName += sLog->GetLogsTimestamp(); - } - - if (extraArgs.size() > 2) - _maxFileSize = atoi(extraArgs[2]); - - _dynamicName = std::string::npos != _fileName.find("%s"); - _backup = (flags & APPENDER_FLAGS_MAKE_FILE_BACKUP) != 0; - - if (!_dynamicName) - logfile = OpenFile(_fileName, mode, !strcmp(mode, "w") && _backup); -} - -AppenderFile::~AppenderFile() -{ - CloseFile(); -} - -void AppenderFile::_write(LogMessage const* message) -{ - bool exceedMaxSize = _maxFileSize > 0 && (_fileSize.load() + message->Size()) > _maxFileSize; - - if (_dynamicName) - { - char namebuf[TRINITY_PATH_MAX]; - snprintf(namebuf, TRINITY_PATH_MAX, _fileName.c_str(), message->param1.c_str()); - // always use "a" with dynamic name otherwise it could delete the log we wrote in last _write() call - FILE* file = OpenFile(namebuf, "a", _backup || exceedMaxSize); - if (!file) - return; - fprintf(file, "%s%s\n", message->prefix.c_str(), message->text.c_str()); - fflush(file); - _fileSize += uint64(message->Size()); - fclose(file); - return; - } - else if (exceedMaxSize) - logfile = OpenFile(_fileName, "w", true); - - if (!logfile) - return; - - fprintf(logfile, "%s%s\n", message->prefix.c_str(), message->text.c_str()); - fflush(logfile); - _fileSize += uint64(message->Size()); -} - -FILE* AppenderFile::OpenFile(std::string const& filename, std::string const& mode, bool backup) -{ - std::string fullName(_logDir + filename); - if (backup) - { - CloseFile(); - std::string newName(fullName); - newName.push_back('.'); - newName.append(LogMessage::getTimeStr(time(NULL))); - std::replace(newName.begin(), newName.end(), ':', '-'); - rename(fullName.c_str(), newName.c_str()); // no error handling... if we couldn't make a backup, just ignore - } - - if (FILE* ret = fopen(fullName.c_str(), mode.c_str())) - { - _fileSize = ftell(ret); - return ret; - } - - return NULL; -} - -void AppenderFile::CloseFile() -{ - if (logfile) - { - fclose(logfile); - logfile = NULL; - } -} diff --git a/src/server/shared/Logging/AppenderFile.h b/src/server/shared/Logging/AppenderFile.h deleted file mode 100644 index c2781eb1ee9..00000000000 --- a/src/server/shared/Logging/AppenderFile.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef APPENDERFILE_H -#define APPENDERFILE_H - -#include <atomic> -#include "Appender.h" - -class AppenderFile : public Appender -{ - public: - typedef std::integral_constant<AppenderType, APPENDER_FILE>::type TypeIndex; - - AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs); - ~AppenderFile(); - FILE* OpenFile(std::string const& name, std::string const& mode, bool backup); - AppenderType getType() const override { return TypeIndex::value; } - - private: - void CloseFile(); - void _write(LogMessage const* message) override; - FILE* logfile; - std::string _fileName; - std::string _logDir; - bool _dynamicName; - bool _backup; - uint64 _maxFileSize; - std::atomic<uint64> _fileSize; -}; - -#endif diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp deleted file mode 100644 index 5075815ad54..00000000000 --- a/src/server/shared/Logging/Log.cpp +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "Log.h" -#include "Common.h" -#include "Config.h" -#include "Util.h" -#include "AppenderConsole.h" -#include "AppenderFile.h" -#include "AppenderDB.h" -#include "LogOperation.h" - -#include <cstdio> -#include <sstream> - -Log::Log() : _ioService(nullptr), _strand(nullptr) -{ - m_logsTimestamp = "_" + GetTimestampStr(); - RegisterAppender<AppenderConsole>(); - RegisterAppender<AppenderFile>(); -} - -Log::~Log() -{ - delete _strand; - Close(); -} - -uint8 Log::NextAppenderId() -{ - return AppenderId++; -} - -int32 GetConfigIntDefault(std::string base, const char* name, int32 value) -{ - base.append(name); - return sConfigMgr->GetIntDefault(base.c_str(), value); -} - -std::string GetConfigStringDefault(std::string base, const char* name, const char* value) -{ - base.append(name); - return sConfigMgr->GetStringDefault(base.c_str(), value); -} - -Appender* Log::GetAppenderByName(std::string const& name) -{ - AppenderMap::iterator it = appenders.begin(); - while (it != appenders.end() && it->second && it->second->getName() != name) - ++it; - - return it == appenders.end() ? NULL : it->second; -} - -void Log::CreateAppenderFromConfig(std::string const& appenderName) -{ - if (appenderName.empty()) - return; - - // Format=type, level, flags, optional1, optional2 - // if type = File. optional1 = file and option2 = mode - // if type = Console. optional1 = Color - std::string options = sConfigMgr->GetStringDefault(appenderName.c_str(), ""); - - Tokenizer tokens(options, ','); - Tokenizer::const_iterator iter = tokens.begin(); - - size_t size = tokens.size(); - std::string name = appenderName.substr(9); - - if (size < 2) - { - fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong configuration for appender %s. Config line: %s\n", name.c_str(), options.c_str()); - return; - } - - AppenderFlags flags = APPENDER_FLAGS_NONE; - AppenderType type = AppenderType(atoi(*iter++)); - LogLevel level = LogLevel(atoi(*iter++)); - - if (level > LOG_LEVEL_FATAL) - { - fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong Log Level %d for appender %s\n", level, name.c_str()); - return; - } - - if (size > 2) - flags = AppenderFlags(atoi(*iter++)); - - auto factoryFunction = appenderFactory.find(type); - if (factoryFunction == appenderFactory.end()) - { - fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type %d for appender %s\n", type, name.c_str()); - return; - } - - try - { - Appender* appender = factoryFunction->second(NextAppenderId(), name, level, flags, ExtraAppenderArgs(iter, tokens.end())); - appenders[appender->getId()] = appender; - } - catch (InvalidAppenderArgsException const& iaae) - { - fprintf(stderr, "%s", iaae.what()); - } -} - -void Log::CreateLoggerFromConfig(std::string const& appenderName) -{ - if (appenderName.empty()) - return; - - LogLevel level = LOG_LEVEL_DISABLED; - uint8 type = uint8(-1); - - std::string options = sConfigMgr->GetStringDefault(appenderName.c_str(), ""); - std::string name = appenderName.substr(7); - - if (options.empty()) - { - fprintf(stderr, "Log::CreateLoggerFromConfig: Missing config option Logger.%s\n", name.c_str()); - return; - } - - Tokenizer tokens(options, ','); - Tokenizer::const_iterator iter = tokens.begin(); - - if (tokens.size() != 2) - { - fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong config option Logger.%s=%s\n", name.c_str(), options.c_str()); - return; - } - - Logger& logger = loggers[name]; - if (!logger.getName().empty()) - { - fprintf(stderr, "Error while configuring Logger %s. Already defined\n", name.c_str()); - return; - } - - level = LogLevel(atoi(*iter++)); - if (level > LOG_LEVEL_FATAL) - { - fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong Log Level %u for logger %s\n", type, name.c_str()); - return; - } - - if (level < lowestLogLevel) - lowestLogLevel = level; - - logger.Create(name, level); - //fprintf(stdout, "Log::CreateLoggerFromConfig: Created Logger %s, Level %u\n", name.c_str(), level); - - std::istringstream ss(*iter); - std::string str; - - ss >> str; - while (ss) - { - if (Appender* appender = GetAppenderByName(str)) - { - logger.addAppender(appender->getId(), appender); - //fprintf(stdout, "Log::CreateLoggerFromConfig: Added Appender %s to Logger %s\n", appender->getName().c_str(), name.c_str()); - } - else - fprintf(stderr, "Error while configuring Appender %s in Logger %s. Appender does not exist", str.c_str(), name.c_str()); - ss >> str; - } -} - -void Log::ReadAppendersFromConfig() -{ - std::list<std::string> keys = sConfigMgr->GetKeysByString("Appender."); - - while (!keys.empty()) - { - CreateAppenderFromConfig(keys.front()); - keys.pop_front(); - } -} - -void Log::ReadLoggersFromConfig() -{ - std::list<std::string> keys = sConfigMgr->GetKeysByString("Logger."); - - while (!keys.empty()) - { - CreateLoggerFromConfig(keys.front()); - keys.pop_front(); - } - - // Bad config configuration, creating default config - if (loggers.find(LOGGER_ROOT) == loggers.end()) - { - fprintf(stderr, "Wrong Loggers configuration. Review your Logger config section.\n" - "Creating default loggers [root (Error), server (Info)] to console\n"); - - Close(); // Clean any Logger or Appender created - - AppenderConsole* appender = new AppenderConsole(NextAppenderId(), "Console", LOG_LEVEL_DEBUG, APPENDER_FLAGS_NONE, ExtraAppenderArgs()); - appenders[appender->getId()] = appender; - - Logger& logger = loggers[LOGGER_ROOT]; - logger.Create(LOGGER_ROOT, LOG_LEVEL_ERROR); - logger.addAppender(appender->getId(), appender); - - logger = loggers["server"]; - logger.Create("server", LOG_LEVEL_ERROR); - logger.addAppender(appender->getId(), appender); - } -} - -void Log::write(std::unique_ptr<LogMessage>&& msg) const -{ - Logger const* logger = GetLoggerByType(msg->type); - - if (_ioService) - { - auto logOperation = std::shared_ptr<LogOperation>(new LogOperation(logger, std::move(msg))); - - _ioService->post(_strand->wrap([logOperation](){ logOperation->call(); })); - } - else - logger->write(msg.get()); -} - -std::string Log::GetTimestampStr() -{ - time_t tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - - std::tm aTm; - localtime_r(&tt, &aTm); - - // YYYY year - // MM month (2 digits 01-12) - // DD day (2 digits 01-31) - // HH hour (2 digits 00-23) - // MM minutes (2 digits 00-59) - // SS seconds (2 digits 00-59) - return Trinity::StringFormat("%04d-%02d-%02d_%02d-%02d-%02d", - aTm.tm_year + 1900, aTm.tm_mon + 1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec); -} - -bool Log::SetLogLevel(std::string const& name, const char* newLevelc, bool isLogger /* = true */) -{ - LogLevel newLevel = LogLevel(atoi(newLevelc)); - if (newLevel < 0) - return false; - - if (isLogger) - { - LoggerMap::iterator it = loggers.begin(); - while (it != loggers.end() && it->second.getName() != name) - ++it; - - if (it == loggers.end()) - return false; - - it->second.setLogLevel(newLevel); - - if (newLevel != LOG_LEVEL_DISABLED && newLevel < lowestLogLevel) - lowestLogLevel = newLevel; - } - else - { - Appender* appender = GetAppenderByName(name); - if (!appender) - return false; - - appender->setLogLevel(newLevel); - } - - return true; -} - -void Log::outCharDump(char const* str, uint32 accountId, uint64 guid, char const* name) -{ - if (!str || !ShouldLog("entities.player.dump", LOG_LEVEL_INFO)) - return; - - std::ostringstream ss; - ss << "== START DUMP == (account: " << accountId << " guid: " << guid << " name: " << name - << ")\n" << str << "\n== END DUMP ==\n"; - - std::unique_ptr<LogMessage> msg(new LogMessage(LOG_LEVEL_INFO, "entities.player.dump", ss.str())); - std::ostringstream param; - param << guid << '_' << name; - - msg->param1 = param.str(); - - write(std::move(msg)); -} - -void Log::SetRealmId(uint32 id) -{ - for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it) - it->second->setRealmId(id); -} - -void Log::Close() -{ - loggers.clear(); - for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it) - delete it->second; - - appenders.clear(); -} - -void Log::Initialize(boost::asio::io_service* ioService) -{ - if (ioService) - { - _ioService = ioService; - _strand = new boost::asio::strand(*ioService); - } - - LoadFromConfig(); -} - -void Log::LoadFromConfig() -{ - Close(); - - lowestLogLevel = LOG_LEVEL_FATAL; - AppenderId = 0; - m_logsDir = sConfigMgr->GetStringDefault("LogsDir", ""); - if (!m_logsDir.empty()) - if ((m_logsDir.at(m_logsDir.length() - 1) != '/') && (m_logsDir.at(m_logsDir.length() - 1) != '\\')) - m_logsDir.push_back('/'); - - ReadAppendersFromConfig(); - ReadLoggersFromConfig(); -} diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h deleted file mode 100644 index a15bb4ad485..00000000000 --- a/src/server/shared/Logging/Log.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef TRINITYCORE_LOG_H -#define TRINITYCORE_LOG_H - -#include "Define.h" -#include "Appender.h" -#include "Logger.h" -#include "StringFormat.h" -#include "Common.h" -#include <boost/asio/io_service.hpp> -#include <boost/asio/strand.hpp> - -#include <stdarg.h> -#include <unordered_map> -#include <string> -#include <memory> - -#define LOGGER_ROOT "root" - -class Log -{ - typedef std::unordered_map<std::string, Logger> LoggerMap; - - private: - Log(); - ~Log(); - - public: - - static Log* instance() - { - static Log instance; - return &instance; - } - - void Initialize(boost::asio::io_service* ioService); - void LoadFromConfig(); - void Close(); - bool ShouldLog(std::string const& type, LogLevel level) const; - bool SetLogLevel(std::string const& name, char const* level, bool isLogger = true); - - template<typename Format, typename... Args> - inline void outMessage(std::string const& filter, LogLevel const level, Format&& fmt, Args&&... args) - { - write(Trinity::make_unique<LogMessage>(level, filter, - Trinity::StringFormat(std::forward<Format>(fmt), std::forward<Args>(args)...))); - } - - template<typename Format, typename... Args> - void outCommand(uint32 account, Format&& fmt, Args&&... args) - { - if (!ShouldLog("commands.gm", LOG_LEVEL_INFO)) - return; - - std::unique_ptr<LogMessage> msg = - Trinity::make_unique<LogMessage>(LOG_LEVEL_INFO, "commands.gm", - Trinity::StringFormat(std::forward<Format>(fmt), std::forward<Args>(args)...)); - - msg->param1 = std::to_string(account); - - write(std::move(msg)); - } - - void outCharDump(char const* str, uint32 account_id, uint64 guid, char const* name); - - void SetRealmId(uint32 id); - - template<class AppenderImpl> - void RegisterAppender() - { - using Index = typename AppenderImpl::TypeIndex; - auto itr = appenderFactory.find(Index::value); - ASSERT(itr == appenderFactory.end()); - appenderFactory[Index::value] = &CreateAppender<AppenderImpl>; - } - - std::string const& GetLogsDir() const { return m_logsDir; } - std::string const& GetLogsTimestamp() const { return m_logsTimestamp; } - - private: - static std::string GetTimestampStr(); - void write(std::unique_ptr<LogMessage>&& msg) const; - - Logger const* GetLoggerByType(std::string const& type) const; - Appender* GetAppenderByName(std::string const& name); - uint8 NextAppenderId(); - void CreateAppenderFromConfig(std::string const& name); - void CreateLoggerFromConfig(std::string const& name); - void ReadAppendersFromConfig(); - void ReadLoggersFromConfig(); - - AppenderCreatorMap appenderFactory; - AppenderMap appenders; - LoggerMap loggers; - uint8 AppenderId; - LogLevel lowestLogLevel; - - std::string m_logsDir; - std::string m_logsTimestamp; - - boost::asio::io_service* _ioService; - boost::asio::strand* _strand; -}; - -inline Logger const* Log::GetLoggerByType(std::string const& type) const -{ - LoggerMap::const_iterator it = loggers.find(type); - if (it != loggers.end()) - return &(it->second); - - if (type == LOGGER_ROOT) - return NULL; - - std::string parentLogger = LOGGER_ROOT; - size_t found = type.find_last_of("."); - if (found != std::string::npos) - parentLogger = type.substr(0,found); - - return GetLoggerByType(parentLogger); -} - -inline bool Log::ShouldLog(std::string const& type, LogLevel level) const -{ - // TODO: Use cache to store "Type.sub1.sub2": "Type" equivalence, should - // Speed up in cases where requesting "Type.sub1.sub2" but only configured - // Logger "Type" - - // Don't even look for a logger if the LogLevel is lower than lowest log levels across all loggers - if (level < lowestLogLevel) - return false; - - Logger const* logger = GetLoggerByType(type); - if (!logger) - return false; - - LogLevel logLevel = logger->getLogLevel(); - return logLevel != LOG_LEVEL_DISABLED && logLevel <= level; -} - -#define sLog Log::instance() - -#define LOG_EXCEPTION_FREE(filterType__, level__, ...) \ - { \ - try \ - { \ - sLog->outMessage(filterType__, level__, __VA_ARGS__); \ - } \ - catch (std::exception& e) \ - { \ - sLog->outMessage("server", LOG_LEVEL_ERROR, "Wrong format occurred (%s) at %s:%u.", \ - e.what(), __FILE__, __LINE__); \ - } \ - } - -#if PLATFORM != PLATFORM_WINDOWS -void check_args(const char*, ...) ATTR_PRINTF(1, 2); -void check_args(std::string const&, ...); - -// This will catch format errors on build time -#define TC_LOG_MESSAGE_BODY(filterType__, level__, ...) \ - do { \ - if (sLog->ShouldLog(filterType__, level__)) \ - { \ - if (false) \ - check_args(__VA_ARGS__); \ - \ - LOG_EXCEPTION_FREE(filterType__, level__, __VA_ARGS__); \ - } \ - } while (0) -#else -#define TC_LOG_MESSAGE_BODY(filterType__, level__, ...) \ - __pragma(warning(push)) \ - __pragma(warning(disable:4127)) \ - do { \ - if (sLog->ShouldLog(filterType__, level__)) \ - LOG_EXCEPTION_FREE(filterType__, level__, __VA_ARGS__); \ - } while (0) \ - __pragma(warning(pop)) -#endif - -#define TC_LOG_TRACE(filterType__, ...) \ - TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_TRACE, __VA_ARGS__) - -#define TC_LOG_DEBUG(filterType__, ...) \ - TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_DEBUG, __VA_ARGS__) - -#define TC_LOG_INFO(filterType__, ...) \ - TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_INFO, __VA_ARGS__) - -#define TC_LOG_WARN(filterType__, ...) \ - TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_WARN, __VA_ARGS__) - -#define TC_LOG_ERROR(filterType__, ...) \ - TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_ERROR, __VA_ARGS__) - -#define TC_LOG_FATAL(filterType__, ...) \ - TC_LOG_MESSAGE_BODY(filterType__, LOG_LEVEL_FATAL, __VA_ARGS__) - -#endif diff --git a/src/server/shared/Logging/LogOperation.cpp b/src/server/shared/Logging/LogOperation.cpp deleted file mode 100644 index bcd923c705e..00000000000 --- a/src/server/shared/Logging/LogOperation.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "LogOperation.h" -#include "Logger.h" - -int LogOperation::call() -{ - logger->write(msg.get()); - return 0; -} diff --git a/src/server/shared/Logging/LogOperation.h b/src/server/shared/Logging/LogOperation.h deleted file mode 100644 index ffdd35c3c09..00000000000 --- a/src/server/shared/Logging/LogOperation.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef LOGOPERATION_H -#define LOGOPERATION_H - -#include <memory> - -class Logger; -struct LogMessage; - -class LogOperation -{ - public: - LogOperation(Logger const* _logger, std::unique_ptr<LogMessage>&& _msg) - : logger(_logger), msg(std::forward<std::unique_ptr<LogMessage>>(_msg)) - { } - - ~LogOperation() { } - - int call(); - - protected: - Logger const* logger; - std::unique_ptr<LogMessage> msg; -}; - -#endif diff --git a/src/server/shared/Logging/Logger.cpp b/src/server/shared/Logging/Logger.cpp deleted file mode 100644 index 3b02eb47575..00000000000 --- a/src/server/shared/Logging/Logger.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "Logger.h" - -Logger::Logger(): name(""), level(LOG_LEVEL_DISABLED) { } - -void Logger::Create(std::string const& _name, LogLevel _level) -{ - name = _name; - level = _level; -} - -std::string const& Logger::getName() const -{ - return name; -} - -LogLevel Logger::getLogLevel() const -{ - return level; -} - -void Logger::addAppender(uint8 id, Appender* appender) -{ - appenders[id] = appender; -} - -void Logger::delAppender(uint8 id) -{ - appenders.erase(id); -} - -void Logger::setLogLevel(LogLevel _level) -{ - level = _level; -} - -void Logger::write(LogMessage* message) const -{ - if (!level || level > message->level || message->text.empty()) - { - //fprintf(stderr, "Logger::write: Logger %s, Level %u. Msg %s Level %u WRONG LEVEL MASK OR EMPTY MSG\n", getName().c_str(), getLogLevel(), message.text.c_str(), message.level); - return; - } - - for (AppenderMap::const_iterator it = appenders.begin(); it != appenders.end(); ++it) - if (it->second) - it->second->write(message); -} diff --git a/src/server/shared/Logging/Logger.h b/src/server/shared/Logging/Logger.h deleted file mode 100644 index 1aee75c5d72..00000000000 --- a/src/server/shared/Logging/Logger.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef LOGGER_H -#define LOGGER_H - -#include "Appender.h" - -class Logger -{ - public: - Logger(); - - void Create(std::string const& name, LogLevel level); - void addAppender(uint8 type, Appender *); - void delAppender(uint8 type); - - std::string const& getName() const; - LogLevel getLogLevel() const; - void setLogLevel(LogLevel level); - void write(LogMessage* message) const; - - private: - std::string name; - LogLevel level; - AppenderMap appenders; -}; - -#endif diff --git a/src/server/shared/PrecompiledHeaders/sharedPCH.h b/src/server/shared/PrecompiledHeaders/sharedPCH.h index f4c18f89ec1..c09b24e6fd9 100644 --- a/src/server/shared/PrecompiledHeaders/sharedPCH.h +++ b/src/server/shared/PrecompiledHeaders/sharedPCH.h @@ -1,11 +1,4 @@ //add here most rarely modified headers to speed up debug build compilation -#include "Common.h" -#include "Log.h" -#include "DatabaseWorker.h" -#include "SQLOperation.h" -#include "Errors.h" #include "TypeList.h" -#include "TaskScheduler.h" -#include "EventMap.h" #include "Revision.h" diff --git a/src/server/shared/Utilities/ServiceWin32.cpp b/src/server/shared/Service/ServiceWin32.cpp index 3e5e416b1a3..3e5e416b1a3 100644 --- a/src/server/shared/Utilities/ServiceWin32.cpp +++ b/src/server/shared/Service/ServiceWin32.cpp diff --git a/src/server/shared/Utilities/ServiceWin32.h b/src/server/shared/Service/ServiceWin32.h index 9d9c732cd20..9d9c732cd20 100644 --- a/src/server/shared/Utilities/ServiceWin32.h +++ b/src/server/shared/Service/ServiceWin32.h diff --git a/src/server/shared/Threading/Callback.h b/src/server/shared/Threading/Callback.h deleted file mode 100644 index 1f4ffc97cfc..00000000000 --- a/src/server/shared/Threading/Callback.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _CALLBACK_H -#define _CALLBACK_H - -#include <future> -#include "QueryResult.h" - -typedef std::future<QueryResult> QueryResultFuture; -typedef std::promise<QueryResult> QueryResultPromise; -typedef std::future<PreparedQueryResult> PreparedQueryResultFuture; -typedef std::promise<PreparedQueryResult> PreparedQueryResultPromise; - -#define CALLBACK_STAGE_INVALID uint8(-1) - -template <typename Result, typename ParamType, bool chain = false> -class QueryCallback -{ - public: - QueryCallback() : _param(), _stage(chain ? 0 : CALLBACK_STAGE_INVALID) { } - - //! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery - void SetFutureResult(std::future<Result> value) - { - _result = std::move(value); - } - - std::future<Result>& GetFutureResult() - { - return _result; - } - - int IsReady() - { - return _result.valid() && _result.wait_for(std::chrono::seconds(0)) == std::future_status::ready; - } - - void GetResult(Result& res) - { - res = _result.get(); - } - - void FreeResult() - { - // Nothing to do here, the constructor of std::future will take care of the cleanup - } - - void SetParam(ParamType value) - { - _param = value; - } - - ParamType GetParam() - { - return _param; - } - - //! Resets the stage of the callback chain - void ResetStage() - { - if (!chain) - return; - - _stage = 0; - } - - //! Advances the callback chain to the next stage, so upper level code can act on its results accordingly - void NextStage() - { - if (!chain) - return; - - ++_stage; - } - - //! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid) - uint8 GetStage() - { - return _stage; - } - - //! Resets all underlying variables (param, result and stage) - void Reset() - { - SetParam(ParamType()); - FreeResult(); - ResetStage(); - } - - private: - std::future<Result> _result; - ParamType _param; - uint8 _stage; - - QueryCallback(QueryCallback const& right) = delete; - QueryCallback& operator=(QueryCallback const& right) = delete; -}; - -template <typename Result, typename ParamType1, typename ParamType2, bool chain = false> -class QueryCallback_2 -{ - public: - QueryCallback_2() : _stage(chain ? 0 : CALLBACK_STAGE_INVALID) { } - - //! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery - void SetFutureResult(std::future<Result> value) - { - _result = std::move(value); - } - - std::future<Result>& GetFutureResult() - { - return _result; - } - - int IsReady() - { - return _result.valid() && _result.wait_for(std::chrono::seconds(0)) == std::future_status::ready; - } - - void GetResult(Result& res) - { - res = _result.get(); - } - - void FreeResult() - { - // Nothing to do here, the constructor of std::future will take care of the cleanup - } - - void SetFirstParam(ParamType1 value) - { - _param_1 = value; - } - - void SetSecondParam(ParamType2 value) - { - _param_2 = value; - } - - ParamType1 GetFirstParam() - { - return _param_1; - } - - ParamType2 GetSecondParam() - { - return _param_2; - } - - //! Resets the stage of the callback chain - void ResetStage() - { - if (!chain) - return; - - _stage = 0; - } - - //! Advances the callback chain to the next stage, so upper level code can act on its results accordingly - void NextStage() - { - if (!chain) - return; - - ++_stage; - } - - //! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid) - uint8 GetStage() - { - return _stage; - } - - //! Resets all underlying variables (param, result and stage) - void Reset() - { - SetFirstParam(NULL); - SetSecondParam(NULL); - FreeResult(); - ResetStage(); - } - - private: - std::future<Result> _result; - ParamType1 _param_1; - ParamType2 _param_2; - uint8 _stage; - - QueryCallback_2(QueryCallback_2 const& right) = delete; - QueryCallback_2& operator=(QueryCallback_2 const& right) = delete; -}; - -#endif diff --git a/src/server/shared/Threading/LockedQueue.h b/src/server/shared/Threading/LockedQueue.h deleted file mode 100644 index 3abb0f4b8bc..00000000000 --- a/src/server/shared/Threading/LockedQueue.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef LOCKEDQUEUE_H -#define LOCKEDQUEUE_H - -#include <deque> -#include <mutex> - -template <class T, typename StorageType = std::deque<T> > -class LockedQueue -{ - //! Lock access to the queue. - std::mutex _lock; - - //! Storage backing the queue. - StorageType _queue; - - //! Cancellation flag. - volatile bool _canceled; - -public: - - //! Create a LockedQueue. - LockedQueue() - : _canceled(false) - { - } - - //! Destroy a LockedQueue. - virtual ~LockedQueue() - { - } - - //! Adds an item to the queue. - void add(const T& item) - { - lock(); - - _queue.push_back(item); - - unlock(); - } - - //! Gets the next result in the queue, if any. - bool next(T& result) - { - std::lock_guard<std::mutex> lock(_lock); - - if (_queue.empty()) - return false; - - result = _queue.front(); - _queue.pop_front(); - - return true; - } - - template<class Checker> - bool next(T& result, Checker& check) - { - std::lock_guard<std::mutex> lock(_lock); - - if (_queue.empty()) - return false; - - result = _queue.front(); - if (!check.Process(result)) - return false; - - _queue.pop_front(); - return true; - } - - //! Peeks at the top of the queue. Check if the queue is empty before calling! Remember to unlock after use if autoUnlock == false. - T& peek(bool autoUnlock = false) - { - lock(); - - T& result = _queue.front(); - - if (autoUnlock) - unlock(); - - return result; - } - - //! Cancels the queue. - void cancel() - { - std::lock_guard<std::mutex> lock(_lock); - - _canceled = true; - } - - //! Checks if the queue is cancelled. - bool cancelled() - { - std::lock_guard<std::mutex> lock(_lock); - return _canceled; - } - - //! Locks the queue for access. - void lock() - { - this->_lock.lock(); - } - - //! Unlocks the queue. - void unlock() - { - this->_lock.unlock(); - } - - ///! Calls pop_front of the queue - void pop_front() - { - std::lock_guard<std::mutex> lock(_lock); - _queue.pop_front(); - } - - ///! Checks if we're empty or not with locks held - bool empty() - { - std::lock_guard<std::mutex> lock(_lock); - return _queue.empty(); - } -}; -#endif diff --git a/src/server/shared/Threading/ProcessPriority.h b/src/server/shared/Threading/ProcessPriority.h deleted file mode 100644 index 2a8501a0249..00000000000 --- a/src/server/shared/Threading/ProcessPriority.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> -* -* 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; either version 2 of the License, or (at your -* option) any later version. -* -* This program is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _PROCESSPRIO_H -#define _PROCESSPRIO_H - -#include "Configuration/Config.h" - -#ifdef __linux__ -#include <sched.h> -#include <sys/resource.h> -#define PROCESS_HIGH_PRIORITY -15 // [-20, 19], default is 0 -#endif - -void SetProcessPriority(const std::string& logChannel) -{ -// Suppresses Mac OS X Warning since logChannel isn't used. -#if PLATFORM_APPLE - (void)logChannel; -#endif - -#if defined(_WIN32) || defined(__linux__) - - ///- Handle affinity for multiple processors and process priority - uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0); - bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false); - -#ifdef _WIN32 // Windows - - HANDLE hProcess = GetCurrentProcess(); - if (affinity > 0) - { - ULONG_PTR appAff; - ULONG_PTR sysAff; - - if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) - { - // remove non accessible processors - ULONG_PTR currentAffinity = affinity & appAff; - - if (!currentAffinity) - TC_LOG_ERROR(logChannel, "Processors marked in UseProcessors bitmask (hex) %x are not accessible. Accessible processors bitmask (hex): %x", affinity, appAff); - else if (SetProcessAffinityMask(hProcess, currentAffinity)) - TC_LOG_INFO(logChannel, "Using processors (bitmask, hex): %x", currentAffinity); - else - TC_LOG_ERROR(logChannel, "Can't set used processors (hex): %x", currentAffinity); - } - } - - if (highPriority) - { - if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) - TC_LOG_INFO(logChannel, "Process priority class set to HIGH"); - else - TC_LOG_ERROR(logChannel, "Can't set process priority class."); - } - -#else // Linux - - if (affinity > 0) - { - cpu_set_t mask; - CPU_ZERO(&mask); - - for (unsigned int i = 0; i < sizeof(affinity) * 8; ++i) - if (affinity & (1 << i)) - CPU_SET(i, &mask); - - if (sched_setaffinity(0, sizeof(mask), &mask)) - TC_LOG_ERROR(logChannel, "Can't set used processors (hex): %x, error: %s", affinity, strerror(errno)); - else - { - CPU_ZERO(&mask); - sched_getaffinity(0, sizeof(mask), &mask); - TC_LOG_INFO(logChannel, "Using processors (bitmask, hex): %lx", *(__cpu_mask*)(&mask)); - } - } - - if (highPriority) - { - if (setpriority(PRIO_PROCESS, 0, PROCESS_HIGH_PRIORITY)) - TC_LOG_ERROR(logChannel, "Can't set process priority class, error: %s", strerror(errno)); - else - TC_LOG_INFO(logChannel, "Process priority class set to %i", getpriority(PRIO_PROCESS, 0)); - } - -#endif -#endif -} - -#endif diff --git a/src/server/shared/Threading/ProducerConsumerQueue.h b/src/server/shared/Threading/ProducerConsumerQueue.h deleted file mode 100644 index 96546960393..00000000000 --- a/src/server/shared/Threading/ProducerConsumerQueue.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -* Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> -* -* 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; either version 2 of the License, or (at your -* option) any later version. -* -* This program is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _PCQ_H -#define _PCQ_H - -#include <condition_variable> -#include <mutex> -#include <queue> -#include <atomic> -#include <type_traits> - -template <typename T> -class ProducerConsumerQueue -{ -private: - std::mutex _queueLock; - std::queue<T> _queue; - std::condition_variable _condition; - std::atomic<bool> _shutdown; - -public: - - ProducerConsumerQueue<T>() : _shutdown(false) { } - - void Push(const T& value) - { - std::lock_guard<std::mutex> lock(_queueLock); - _queue.push(std::move(value)); - - _condition.notify_one(); - } - - bool Empty() - { - std::lock_guard<std::mutex> lock(_queueLock); - - return _queue.empty(); - } - - bool Pop(T& value) - { - std::lock_guard<std::mutex> lock(_queueLock); - - if (_queue.empty() || _shutdown) - return false; - - value = _queue.front(); - - _queue.pop(); - - return true; - } - - void WaitAndPop(T& value) - { - std::unique_lock<std::mutex> lock(_queueLock); - - // we could be using .wait(lock, predicate) overload here but it is broken - // https://connect.microsoft.com/VisualStudio/feedback/details/1098841 - while (_queue.empty() && !_shutdown) - _condition.wait(lock); - - if (_queue.empty() || _shutdown) - return; - - value = _queue.front(); - - _queue.pop(); - } - - void Cancel() - { - std::unique_lock<std::mutex> lock(_queueLock); - - while (!_queue.empty()) - { - T& value = _queue.front(); - - DeleteQueuedObject(value); - - _queue.pop(); - } - - _shutdown = true; - - _condition.notify_all(); - } - -private: - template<typename E = T> - typename std::enable_if<std::is_pointer<E>::value>::type DeleteQueuedObject(E& obj) { delete obj; } - - template<typename E = T> - typename std::enable_if<!std::is_pointer<E>::value>::type DeleteQueuedObject(E const& /*packet*/) { } -}; - -#endif diff --git a/src/server/shared/Updater/DBUpdater.cpp b/src/server/shared/Updater/DBUpdater.cpp deleted file mode 100644 index c69d19b11d6..00000000000 --- a/src/server/shared/Updater/DBUpdater.cpp +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "DBUpdater.h" -#include "Log.h" -#include "Revision.h" -#include "UpdateFetcher.h" -#include "DatabaseLoader.h" -#include "Config.h" - -#include <fstream> -#include <iostream> -#include <unordered_map> -#include <boost/process.hpp> -#include <boost/iostreams/device/file_descriptor.hpp> -#include <boost/system/system_error.hpp> - -using namespace boost::process; -using namespace boost::process::initializers; -using namespace boost::iostreams; - -template<class T> -std::string DBUpdater<T>::GetSourceDirectory() -{ - std::string const entry = sConfigMgr->GetStringDefault("Updates.SourcePath", ""); - if (!entry.empty()) - return entry; - else - return Revision::GetSourceDirectory(); -} - -template<class T> -std::string DBUpdater<T>::GetMySqlCli() -{ - std::string const entry = sConfigMgr->GetStringDefault("Updates.MySqlCLIPath", ""); - if (!entry.empty()) - return entry; - else - return Revision::GetMySQLExecutable(); -} - -// Auth Database -template<> -std::string DBUpdater<LoginDatabaseConnection>::GetConfigEntry() -{ - return "Updates.Auth"; -} - -template<> -std::string DBUpdater<LoginDatabaseConnection>::GetTableName() -{ - return "Auth"; -} - -template<> -std::string DBUpdater<LoginDatabaseConnection>::GetBaseFile() -{ - return DBUpdater<LoginDatabaseConnection>::GetSourceDirectory() + "/sql/base/auth_database.sql"; -} - -template<> -bool DBUpdater<LoginDatabaseConnection>::IsEnabled(uint32 const updateMask) -{ - // This way silences warnings under msvc - return (updateMask & DatabaseLoader::DATABASE_LOGIN) ? true : false; -} - -// World Database -template<> -std::string DBUpdater<WorldDatabaseConnection>::GetConfigEntry() -{ - return "Updates.World"; -} - -template<> -std::string DBUpdater<WorldDatabaseConnection>::GetTableName() -{ - return "World"; -} - -template<> -std::string DBUpdater<WorldDatabaseConnection>::GetBaseFile() -{ - return Revision::GetFullDatabase(); -} - -template<> -bool DBUpdater<WorldDatabaseConnection>::IsEnabled(uint32 const updateMask) -{ - // This way silences warnings under msvc - return (updateMask & DatabaseLoader::DATABASE_WORLD) ? true : false; -} - -template<> -BaseLocation DBUpdater<WorldDatabaseConnection>::GetBaseLocationType() -{ - return LOCATION_DOWNLOAD; -} - -// Character Database -template<> -std::string DBUpdater<CharacterDatabaseConnection>::GetConfigEntry() -{ - return "Updates.Character"; -} - -template<> -std::string DBUpdater<CharacterDatabaseConnection>::GetTableName() -{ - return "Character"; -} - -template<> -std::string DBUpdater<CharacterDatabaseConnection>::GetBaseFile() -{ - return DBUpdater<CharacterDatabaseConnection>::GetSourceDirectory() + "/sql/base/characters_database.sql"; -} - -template<> -bool DBUpdater<CharacterDatabaseConnection>::IsEnabled(uint32 const updateMask) -{ - // This way silences warnings under msvc - return (updateMask & DatabaseLoader::DATABASE_CHARACTER) ? true : false; -} - -// All -template<class T> -BaseLocation DBUpdater<T>::GetBaseLocationType() -{ - return LOCATION_REPOSITORY; -} - -template<class T> -bool DBUpdater<T>::CheckExecutable() -{ - DBUpdater<T>::Path const exe(DBUpdater<T>::GetMySqlCli()); - if (!exists(exe)) - { - // Check for mysql in path - std::vector<std::string> args = {"--version"}; - uint32 ret; - try - { - child c = execute(run_exe("mysql"), set_args(args), throw_on_error(), close_stdout()); - ret = wait_for_exit(c); - } - catch (boost::system::system_error&) - { - ret = EXIT_FAILURE; - } - - if (ret == EXIT_FAILURE) - { - TC_LOG_FATAL("sql.updates", "Didn't find executeable mysql binary at \'%s\', correct the path in the *.conf (\"Updates.MySqlCLIPath\").", - absolute(exe).generic_string().c_str()); - - return false; - } - } - return true; -} - -template<class T> -bool DBUpdater<T>::Create(DatabaseWorkerPool<T>& pool) -{ - TC_LOG_INFO("sql.updates", "Database \"%s\" does not exist, do you want to create it? [yes (default) / no]: ", - pool.GetConnectionInfo()->database.c_str()); - - std::string answer; - std::getline(std::cin, answer); - if (!answer.empty() && !(answer.substr(0, 1) == "y")) - return false; - - TC_LOG_INFO("sql.updates", "Creating database \"%s\"...", pool.GetConnectionInfo()->database.c_str()); - - // Path of temp file - static Path const temp("create_table.sql"); - - // Create temporary query to use external mysql cli - std::ofstream file(temp.generic_string()); - if (!file.is_open()) - { - TC_LOG_FATAL("sql.updates", "Failed to create temporary query file \"%s\"!", temp.generic_string().c_str()); - return false; - } - - file << "CREATE DATABASE `" << pool.GetConnectionInfo()->database << "` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci\n\n"; - - file.close(); - - try - { - DBUpdater<T>::ApplyFile(pool, pool.GetConnectionInfo()->host, pool.GetConnectionInfo()->user, pool.GetConnectionInfo()->password, - pool.GetConnectionInfo()->port_or_socket, "", temp); - } - catch (UpdateException&) - { - TC_LOG_FATAL("sql.updates", "Failed to create database %s! Has the user `CREATE` priviliges?", pool.GetConnectionInfo()->database.c_str()); - boost::filesystem::remove(temp); - return false; - } - - TC_LOG_INFO("sql.updates", "Done."); - boost::filesystem::remove(temp); - return true; -} - -template<class T> -bool DBUpdater<T>::Update(DatabaseWorkerPool<T>& pool) -{ - if (!DBUpdater<T>::CheckExecutable()) - return false; - - TC_LOG_INFO("sql.updates", "Updating %s database...", DBUpdater<T>::GetTableName().c_str()); - - Path const sourceDirectory(GetSourceDirectory()); - - if (!is_directory(sourceDirectory)) - { - TC_LOG_ERROR("sql.updates", "DBUpdater: Given source directory %s does not exist, skipped!", sourceDirectory.generic_string().c_str()); - return false; - } - - UpdateFetcher updateFetcher(sourceDirectory, [&](std::string const& query) { DBUpdater<T>::Apply(pool, query); }, - [&](Path const& file) { DBUpdater<T>::ApplyFile(pool, file); }, - [&](std::string const& query) -> QueryResult { return DBUpdater<T>::Retrieve(pool, query); }); - - UpdateResult result; - try - { - result = updateFetcher.Update( - sConfigMgr->GetBoolDefault("Updates.Redundancy", true), - sConfigMgr->GetBoolDefault("Updates.AllowRehash", true), - sConfigMgr->GetBoolDefault("Updates.ArchivedRedundancy", false), - sConfigMgr->GetIntDefault("Updates.CleanDeadRefMaxCount", 3)); - } - catch (UpdateException&) - { - return false; - } - - std::string const info = Trinity::StringFormat("Containing " SZFMTD " new and " SZFMTD " archived updates.", - result.recent, result.archived); - - if (!result.updated) - TC_LOG_INFO("sql.updates", ">> %s database is up-to-date! %s", DBUpdater<T>::GetTableName().c_str(), info.c_str()); - else - TC_LOG_INFO("sql.updates", ">> Applied " SZFMTD " %s. %s", result.updated, result.updated == 1 ? "query" : "queries", info.c_str()); - - return true; -} - -template<class T> -bool DBUpdater<T>::Populate(DatabaseWorkerPool<T>& pool) -{ - { - QueryResult const result = Retrieve(pool, "SHOW TABLES"); - if (result && (result->GetRowCount() > 0)) - return true; - } - - if (!DBUpdater<T>::CheckExecutable()) - return false; - - TC_LOG_INFO("sql.updates", "Database %s is empty, auto populating it...", DBUpdater<T>::GetTableName().c_str()); - - std::string const p = DBUpdater<T>::GetBaseFile(); - if (p.empty()) - { - TC_LOG_INFO("sql.updates", ">> No base file provided, skipped!"); - return true; - } - - Path const base(p); - if (!exists(base)) - { - switch (DBUpdater<T>::GetBaseLocationType()) - { - case LOCATION_REPOSITORY: - { - TC_LOG_ERROR("sql.updates", ">> Base file \"%s\" is missing, try to clone the source again.", - base.generic_string().c_str()); - - break; - } - case LOCATION_DOWNLOAD: - { - TC_LOG_ERROR("sql.updates", ">> File \"%s\" is missing, download it from \"http://www.trinitycore.org/f/files/category/1-database/\"" \ - " and place it in your server directory.", base.filename().generic_string().c_str()); - break; - } - } - return false; - } - - // Update database - TC_LOG_INFO("sql.updates", ">> Applying \'%s\'...", base.generic_string().c_str()); - try - { - ApplyFile(pool, base); - } - catch (UpdateException&) - { - return false; - } - - TC_LOG_INFO("sql.updates", ">> Done!"); - return true; -} - -template<class T> -QueryResult DBUpdater<T>::Retrieve(DatabaseWorkerPool<T>& pool, std::string const& query) -{ - return pool.PQuery(query.c_str()); -} - -template<class T> -void DBUpdater<T>::Apply(DatabaseWorkerPool<T>& pool, std::string const& query) -{ - pool.DirectExecute(query.c_str()); -} - -template<class T> -void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, Path const& path) -{ - DBUpdater<T>::ApplyFile(pool, pool.GetConnectionInfo()->host, pool.GetConnectionInfo()->user, pool.GetConnectionInfo()->password, - pool.GetConnectionInfo()->port_or_socket, pool.GetConnectionInfo()->database, path); -} - -template<class T> -void DBUpdater<T>::ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& host, std::string const& user, - std::string const& password, std::string const& port_or_socket, std::string const& database, Path const& path) -{ - std::vector<std::string> args; - args.reserve(7); - - // CLI Client connection info - args.push_back("-h" + host); - args.push_back("-u" + user); - - if (!password.empty()) - args.push_back("-p" + password); - - // Check if we want to connect through ip or socket (Unix only) -#ifdef _WIN32 - - args.push_back("-P" + port_or_socket); - -#else - - if (!std::isdigit(port_or_socket[0])) - { - // We can't check here if host == "." because is named localhost if socket option is enabled - args.push_back("-P0"); - args.push_back("--protocol=SOCKET"); - args.push_back("-S" + port_or_socket); - } - else - // generic case - args.push_back("-P" + port_or_socket); - -#endif - - // Set the default charset to utf8 - args.push_back("--default-character-set=utf8"); - - // Set max allowed packet to 1 GB - args.push_back("--max-allowed-packet=1GB"); - - // Database - if (!database.empty()) - args.push_back(database); - - // ToDo: use the existing query in memory as virtual file if possible - file_descriptor_source source(path); - - uint32 ret; - try - { - child c = execute(run_exe(DBUpdater<T>::GetMySqlCli().empty() ? "mysql" : - boost::filesystem::absolute(DBUpdater<T>::GetMySqlCli()).generic_string()), - set_args(args), bind_stdin(source), throw_on_error()); - - ret = wait_for_exit(c); - } - catch (boost::system::system_error&) - { - ret = EXIT_FAILURE; - } - - source.close(); - - if (ret != EXIT_SUCCESS) - { - TC_LOG_FATAL("sql.updates", "Applying of file \'%s\' to database \'%s\' failed!" \ - " If you are an user pull the latest revision from the repository. If you are a developer fix your sql query.", - path.generic_string().c_str(), pool.GetConnectionInfo()->database.c_str()); - - throw UpdateException("update failed"); - } -} - -template class DBUpdater<LoginDatabaseConnection>; -template class DBUpdater<WorldDatabaseConnection>; -template class DBUpdater<CharacterDatabaseConnection>; diff --git a/src/server/shared/Updater/DBUpdater.h b/src/server/shared/Updater/DBUpdater.h deleted file mode 100644 index a2b12bed235..00000000000 --- a/src/server/shared/Updater/DBUpdater.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef DBUpdater_h__ -#define DBUpdater_h__ - -#include "DatabaseEnv.h" - -#include <string> -#include <boost/filesystem.hpp> - -class UpdateException : public std::exception -{ -public: - UpdateException(std::string const& msg) : _msg(msg) { } - ~UpdateException() throw() { } - - char const* what() const throw() override { return _msg.c_str(); } - -private: - std::string const _msg; -}; - -enum BaseLocation -{ - LOCATION_REPOSITORY, - LOCATION_DOWNLOAD -}; - -struct UpdateResult -{ - UpdateResult() - : updated(0), recent(0), archived(0) { } - - UpdateResult(size_t const updated_, size_t const recent_, size_t const archived_) - : updated(updated_), recent(recent_), archived(archived_) { } - - size_t updated; - size_t recent; - size_t archived; -}; - -template <class T> -class DBUpdater -{ -public: - using Path = boost::filesystem::path; - - static std::string GetSourceDirectory(); - - static inline std::string GetConfigEntry(); - - static inline std::string GetTableName(); - - static std::string GetBaseFile(); - - static bool IsEnabled(uint32 const updateMask); - - static BaseLocation GetBaseLocationType(); - - static bool Create(DatabaseWorkerPool<T>& pool); - - static bool Update(DatabaseWorkerPool<T>& pool); - - static bool Populate(DatabaseWorkerPool<T>& pool); - -private: - static std::string GetMySqlCli(); - static bool CheckExecutable(); - - static QueryResult Retrieve(DatabaseWorkerPool<T>& pool, std::string const& query); - static void Apply(DatabaseWorkerPool<T>& pool, std::string const& query); - static void ApplyFile(DatabaseWorkerPool<T>& pool, Path const& path); - static void ApplyFile(DatabaseWorkerPool<T>& pool, std::string const& host, std::string const& user, - std::string const& password, std::string const& port_or_socket, std::string const& database, Path const& path); -}; - -#endif // DBUpdater_h__ diff --git a/src/server/shared/Updater/UpdateFetcher.cpp b/src/server/shared/Updater/UpdateFetcher.cpp deleted file mode 100644 index ec023928b99..00000000000 --- a/src/server/shared/Updater/UpdateFetcher.cpp +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "UpdateFetcher.h" -#include "Log.h" -#include "Util.h" - -#include <fstream> -#include <chrono> -#include <vector> -#include <sstream> -#include <exception> -#include <unordered_map> -#include <openssl/sha.h> - -using namespace boost::filesystem; - -UpdateFetcher::UpdateFetcher(Path const& sourceDirectory, - std::function<void(std::string const&)> const& apply, - std::function<void(Path const& path)> const& applyFile, - std::function<QueryResult(std::string const&)> const& retrieve) : - _sourceDirectory(sourceDirectory), _apply(apply), _applyFile(applyFile), - _retrieve(retrieve) -{ -} - -UpdateFetcher::LocaleFileStorage UpdateFetcher::GetFileList() const -{ - LocaleFileStorage files; - DirectoryStorage directories = ReceiveIncludedDirectories(); - for (auto const& entry : directories) - FillFileListRecursively(entry.path, files, entry.state, 1); - - return files; -} - -void UpdateFetcher::FillFileListRecursively(Path const& path, LocaleFileStorage& storage, State const state, uint32 const depth) const -{ - static uint32 const MAX_DEPTH = 10; - static directory_iterator const end; - - for (directory_iterator itr(path); itr != end; ++itr) - { - if (is_directory(itr->path())) - { - if (depth < MAX_DEPTH) - FillFileListRecursively(itr->path(), storage, state, depth + 1); - } - else if (itr->path().extension() == ".sql") - { - TC_LOG_TRACE("sql.updates", "Added locale file \"%s\".", itr->path().filename().generic_string().c_str()); - - LocaleFileEntry const entry = { itr->path(), state }; - - // Check for doubled filenames - // Since elements are only compared through their filenames this is ok - if (storage.find(entry) != storage.end()) - { - TC_LOG_FATAL("sql.updates", "Duplicated filename occurred \"%s\", since updates are ordered " \ - "through its filename every name needs to be unique!", itr->path().generic_string().c_str()); - - throw UpdateException("Updating failed, see the log for details."); - } - - storage.insert(entry); - } - } -} - -UpdateFetcher::DirectoryStorage UpdateFetcher::ReceiveIncludedDirectories() const -{ - DirectoryStorage directories; - - QueryResult const result = _retrieve("SELECT `path`, `state` FROM `updates_include`"); - if (!result) - return directories; - - do - { - Field* fields = result->Fetch(); - - std::string path = fields[0].GetString(); - if (path.substr(0, 1) == "$") - path = _sourceDirectory.generic_string() + path.substr(1); - - Path const p(path); - - if (!is_directory(p)) - { - TC_LOG_WARN("sql.updates", "DBUpdater: Given update include directory \"%s\" isn't existing, skipped!", p.generic_string().c_str()); - continue; - } - - DirectoryEntry const entry = { p, AppliedFileEntry::StateConvert(fields[1].GetString()) }; - directories.push_back(entry); - - TC_LOG_TRACE("sql.updates", "Added applied file \"%s\" from remote.", p.filename().generic_string().c_str()); - - } while (result->NextRow()); - - return directories; -} - -UpdateFetcher::AppliedFileStorage UpdateFetcher::ReceiveAppliedFiles() const -{ - AppliedFileStorage map; - - QueryResult result = _retrieve("SELECT `name`, `hash`, `state`, UNIX_TIMESTAMP(`timestamp`) FROM `updates` ORDER BY `name` ASC"); - if (!result) - return map; - - do - { - Field* fields = result->Fetch(); - - AppliedFileEntry const entry = { fields[0].GetString(), fields[1].GetString(), - AppliedFileEntry::StateConvert(fields[2].GetString()), fields[3].GetUInt64() }; - - map.insert(std::make_pair(entry.name, entry)); - } - while (result->NextRow()); - - return map; -} - -UpdateFetcher::SQLUpdate UpdateFetcher::ReadSQLUpdate(boost::filesystem::path const& file) const -{ - std::ifstream in(file.c_str()); - WPFatal(in.is_open(), "Could not read an update file."); - - auto const start_pos = in.tellg(); - in.ignore(std::numeric_limits<std::streamsize>::max()); - auto const char_count = in.gcount(); - in.seekg(start_pos); - - SQLUpdate const update(new std::string(char_count, char{})); - - in.read(&(*update)[0], update->size()); - in.close(); - return update; -} - -UpdateResult UpdateFetcher::Update(bool const redundancyChecks, bool const allowRehash, bool const archivedRedundancy, int32 const cleanDeadReferencesMaxCount) const -{ - LocaleFileStorage const available = GetFileList(); - AppliedFileStorage applied = ReceiveAppliedFiles(); - - size_t countRecentUpdates = 0; - size_t countArchivedUpdates = 0; - - // Count updates - for (auto const& entry : applied) - if (entry.second.state == RELEASED) - ++countRecentUpdates; - else - ++countArchivedUpdates; - - // Fill hash to name cache - HashToFileNameStorage hashToName; - for (auto entry : applied) - hashToName.insert(std::make_pair(entry.second.hash, entry.first)); - - size_t importedUpdates = 0; - - for (auto const& availableQuery : available) - { - TC_LOG_DEBUG("sql.updates", "Checking update \"%s\"...", availableQuery.first.filename().generic_string().c_str()); - - AppliedFileStorage::const_iterator iter = applied.find(availableQuery.first.filename().string()); - if (iter != applied.end()) - { - // If redundancy is disabled skip it since the update is already applied. - if (!redundancyChecks) - { - TC_LOG_DEBUG("sql.updates", ">> Update is already applied, skipping redundancy checks."); - applied.erase(iter); - continue; - } - - // If the update is in an archived directory and is marked as archived in our database skip redundancy checks (archived updates never change). - if (!archivedRedundancy && (iter->second.state == ARCHIVED) && (availableQuery.second == ARCHIVED)) - { - TC_LOG_DEBUG("sql.updates", ">> Update is archived and marked as archived in database, skipping redundancy checks."); - applied.erase(iter); - continue; - } - } - - // Read update from file - SQLUpdate const update = ReadSQLUpdate(availableQuery.first); - - // Calculate hash - std::string const hash = CalculateHash(update); - - UpdateMode mode = MODE_APPLY; - - // Update is not in our applied list - if (iter == applied.end()) - { - // Catch renames (different filename but same hash) - HashToFileNameStorage::const_iterator const hashIter = hashToName.find(hash); - if (hashIter != hashToName.end()) - { - // Check if the original file was removed if not we've got a problem. - LocaleFileStorage::const_iterator localeIter; - // Push localeIter forward - for (localeIter = available.begin(); (localeIter != available.end()) && - (localeIter->first.filename().string() != hashIter->second); ++localeIter); - - // Conflict! - if (localeIter != available.end()) - { - TC_LOG_WARN("sql.updates", ">> Seems like update \"%s\" \'%s\' was renamed, but the old file is still there! " \ - "Trade it as a new file! (Probably its an unmodified copy of file \"%s\")", - availableQuery.first.filename().string().c_str(), hash.substr(0, 7).c_str(), - localeIter->first.filename().string().c_str()); - } - // Its save to trade the file as renamed here - else - { - TC_LOG_INFO("sql.updates", ">> Renaming update \"%s\" to \"%s\" \'%s\'.", - hashIter->second.c_str(), availableQuery.first.filename().string().c_str(), hash.substr(0, 7).c_str()); - - RenameEntry(hashIter->second, availableQuery.first.filename().string()); - applied.erase(hashIter->second); - continue; - } - } - // Apply the update if it was never seen before. - else - { - TC_LOG_INFO("sql.updates", ">> Applying update \"%s\" \'%s\'...", - availableQuery.first.filename().string().c_str(), hash.substr(0, 7).c_str()); - } - } - // Rehash the update entry if it is contained in our database but with an empty hash. - else if (allowRehash && iter->second.hash.empty()) - { - mode = MODE_REHASH; - - TC_LOG_INFO("sql.updates", ">> Re-hashing update \"%s\" \'%s\'...", availableQuery.first.filename().string().c_str(), - hash.substr(0, 7).c_str()); - } - else - { - // If the hash of the files differs from the one stored in our database reapply the update (because it was changed). - if (iter->second.hash != hash) - { - TC_LOG_INFO("sql.updates", ">> Reapplying update \"%s\" \'%s\' -> \'%s\' (it changed)...", availableQuery.first.filename().string().c_str(), - iter->second.hash.substr(0, 7).c_str(), hash.substr(0, 7).c_str()); - } - else - { - // If the file wasn't changed and just moved update its state if necessary. - if (iter->second.state != availableQuery.second) - { - TC_LOG_DEBUG("sql.updates", ">> Updating state of \"%s\" to \'%s\'...", - availableQuery.first.filename().string().c_str(), AppliedFileEntry::StateConvert(availableQuery.second).c_str()); - - UpdateState(availableQuery.first.filename().string(), availableQuery.second); - } - - TC_LOG_DEBUG("sql.updates", ">> Update is already applied and is matching hash \'%s\'.", hash.substr(0, 7).c_str()); - - applied.erase(iter); - continue; - } - } - - uint32 speed = 0; - AppliedFileEntry const file = { availableQuery.first.filename().string(), hash, availableQuery.second, 0 }; - - switch (mode) - { - case MODE_APPLY: - speed = Apply(availableQuery.first); - /*no break*/ - case MODE_REHASH: - UpdateEntry(file, speed); - break; - } - - if (iter != applied.end()) - applied.erase(iter); - - if (mode == MODE_APPLY) - ++importedUpdates; - } - - // Cleanup up orphaned entries if enabled - if (!applied.empty()) - { - bool const doCleanup = (cleanDeadReferencesMaxCount < 0) || (applied.size() <= static_cast<size_t>(cleanDeadReferencesMaxCount)); - - for (auto const& entry : applied) - { - TC_LOG_WARN("sql.updates", ">> File \'%s\' was applied to the database but is missing in" \ - " your update directory now!", entry.first.c_str()); - - if (doCleanup) - TC_LOG_INFO("sql.updates", "Deleting orphaned entry \'%s\'...", entry.first.c_str()); - } - - if (doCleanup) - CleanUp(applied); - else - { - TC_LOG_ERROR("sql.updates", "Cleanup is disabled! There are " SZFMTD " dirty files that were applied to your database " \ - "but are now missing in your source directory!", applied.size()); - } - } - - return UpdateResult(importedUpdates, countRecentUpdates, countArchivedUpdates); -} - -std::string UpdateFetcher::CalculateHash(SQLUpdate const& query) const -{ - // Calculate a Sha1 hash based on query content. - unsigned char digest[SHA_DIGEST_LENGTH]; - SHA1((unsigned char*)query->c_str(), query->length(), (unsigned char*)&digest); - - return ByteArrayToHexStr(digest, SHA_DIGEST_LENGTH); -} - -uint32 UpdateFetcher::Apply(Path const& path) const -{ - using Time = std::chrono::high_resolution_clock; - - // Benchmark query speed - auto const begin = Time::now(); - - // Update database - _applyFile(path); - - // Return time the query took to apply - return std::chrono::duration_cast<std::chrono::milliseconds>(Time::now() - begin).count(); -} - -void UpdateFetcher::UpdateEntry(AppliedFileEntry const& entry, uint32 const speed) const -{ - std::string const update = "REPLACE INTO `updates` (`name`, `hash`, `state`, `speed`) VALUES (\"" + - entry.name + "\", \"" + entry.hash + "\", \'" + entry.GetStateAsString() + "\', " + std::to_string(speed) + ")"; - - // Update database - _apply(update); -} - -void UpdateFetcher::RenameEntry(std::string const& from, std::string const& to) const -{ - // Delete target if it exists - { - std::string const update = "DELETE FROM `updates` WHERE `name`=\"" + to + "\""; - - // Update database - _apply(update); - } - - // Rename - { - std::string const update = "UPDATE `updates` SET `name`=\"" + to + "\" WHERE `name`=\"" + from + "\""; - - // Update database - _apply(update); - } -} - -void UpdateFetcher::CleanUp(AppliedFileStorage const& storage) const -{ - if (storage.empty()) - return; - - std::stringstream update; - size_t remaining = storage.size(); - - update << "DELETE FROM `updates` WHERE `name` IN("; - - for (auto const& entry : storage) - { - update << "\"" << entry.first << "\""; - if ((--remaining) > 0) - update << ", "; - } - - update << ")"; - - // Update database - _apply(update.str()); -} - -void UpdateFetcher::UpdateState(std::string const& name, State const state) const -{ - std::string const update = "UPDATE `updates` SET `state`=\'" + AppliedFileEntry::StateConvert(state) + "\' WHERE `name`=\"" + name + "\""; - - // Update database - _apply(update); -} diff --git a/src/server/shared/Updater/UpdateFetcher.h b/src/server/shared/Updater/UpdateFetcher.h deleted file mode 100644 index 4ff8c93bc76..00000000000 --- a/src/server/shared/Updater/UpdateFetcher.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef UpdateFetcher_h__ -#define UpdateFetcher_h__ - -#include <DBUpdater.h> - -#include <functional> -#include <string> -#include <memory> -#include <vector> - -class UpdateFetcher -{ - typedef boost::filesystem::path Path; - -public: - UpdateFetcher(Path const& updateDirectory, - std::function<void(std::string const&)> const& apply, - std::function<void(Path const& path)> const& applyFile, - std::function<QueryResult(std::string const&)> const& retrieve); - - UpdateResult Update(bool const redundancyChecks, bool const allowRehash, - bool const archivedRedundancy, int32 const cleanDeadReferencesMaxCount) const; - -private: - enum UpdateMode - { - MODE_APPLY, - MODE_REHASH - }; - - enum State - { - RELEASED, - ARCHIVED - }; - - struct AppliedFileEntry - { - AppliedFileEntry(std::string const& name_, std::string const& hash_, State state_, uint64 timestamp_) - : name(name_), hash(hash_), state(state_), timestamp(timestamp_) { } - - std::string const name; - - std::string const hash; - - State const state; - - uint64 const timestamp; - - static inline State StateConvert(std::string const& state) - { - return (state == "RELEASED") ? RELEASED : ARCHIVED; - } - - static inline std::string StateConvert(State const state) - { - return (state == RELEASED) ? "RELEASED" : "ARCHIVED"; - } - - std::string GetStateAsString() const - { - return StateConvert(state); - } - }; - - struct DirectoryEntry - { - DirectoryEntry(Path const& path_, State state_) : path(path_), state(state_) { } - - Path const path; - - State const state; - }; - - typedef std::pair<Path, State> LocaleFileEntry; - - struct PathCompare - { - inline bool operator() (LocaleFileEntry const& left, LocaleFileEntry const& right) const - { - return left.first.filename().string() < right.first.filename().string(); - } - }; - - typedef std::set<LocaleFileEntry, PathCompare> LocaleFileStorage; - typedef std::unordered_map<std::string, std::string> HashToFileNameStorage; - typedef std::unordered_map<std::string, AppliedFileEntry> AppliedFileStorage; - typedef std::vector<UpdateFetcher::DirectoryEntry> DirectoryStorage; - typedef std::shared_ptr<std::string> SQLUpdate; - - LocaleFileStorage GetFileList() const; - void FillFileListRecursively(Path const& path, LocaleFileStorage& storage, State const state, uint32 const depth) const; - - DirectoryStorage ReceiveIncludedDirectories() const; - AppliedFileStorage ReceiveAppliedFiles() const; - - SQLUpdate ReadSQLUpdate(Path const& file) const; - std::string CalculateHash(SQLUpdate const& query) const; - - uint32 Apply(Path const& path) const; - - void UpdateEntry(AppliedFileEntry const& entry, uint32 const speed = 0) const; - void RenameEntry(std::string const& from, std::string const& to) const; - void CleanUp(AppliedFileStorage const& storage) const; - - void UpdateState(std::string const& name, State const state) const; - - Path const _sourceDirectory; - - std::function<void(std::string const&)> const _apply; - std::function<void(Path const& path)> const _applyFile; - std::function<QueryResult(std::string const&)> const _retrieve; -}; - -#endif // UpdateFetcher_h__ diff --git a/src/server/shared/Utilities/ByteConverter.h b/src/server/shared/Utilities/ByteConverter.h deleted file mode 100644 index a077de3eb0b..00000000000 --- a/src/server/shared/Utilities/ByteConverter.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef TRINITY_BYTECONVERTER_H -#define TRINITY_BYTECONVERTER_H - -/** ByteConverter reverse your byte order. This is use - for cross platform where they have different endians. - */ - -#include "Define.h" -#include <algorithm> - -namespace ByteConverter -{ - template<size_t T> - inline void convert(char *val) - { - std::swap(*val, *(val + T - 1)); - convert<T - 2>(val + 1); - } - - template<> inline void convert<0>(char *) { } - template<> inline void convert<1>(char *) { } // ignore central byte - - template<typename T> inline void apply(T *val) - { - convert<sizeof(T)>((char *)(val)); - } -} - -#if TRINITY_ENDIAN == TRINITY_BIGENDIAN -template<typename T> inline void EndianConvert(T& val) { ByteConverter::apply<T>(&val); } -template<typename T> inline void EndianConvertReverse(T&) { } -template<typename T> inline void EndianConvertPtr(void* val) { ByteConverter::apply<T>(val); } -template<typename T> inline void EndianConvertPtrReverse(void*) { } -#else -template<typename T> inline void EndianConvert(T&) { } -template<typename T> inline void EndianConvertReverse(T& val) { ByteConverter::apply<T>(&val); } -template<typename T> inline void EndianConvertPtr(void*) { } -template<typename T> inline void EndianConvertPtrReverse(void* val) { ByteConverter::apply<T>(val); } -#endif - -template<typename T> void EndianConvert(T*); // will generate link error -template<typename T> void EndianConvertReverse(T*); // will generate link error - -inline void EndianConvert(uint8&) { } -inline void EndianConvert( int8&) { } -inline void EndianConvertReverse(uint8&) { } -inline void EndianConvertReverse( int8&) { } - -#endif - diff --git a/src/server/shared/Utilities/Duration.h b/src/server/shared/Utilities/Duration.h deleted file mode 100644 index 58a08e5842f..00000000000 --- a/src/server/shared/Utilities/Duration.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _DURATION_H_ -#define _DURATION_H_ - -#include <chrono> - -/// Milliseconds shorthand typedef. -typedef std::chrono::milliseconds Milliseconds; - -/// Seconds shorthand typedef. -typedef std::chrono::seconds Seconds; - -/// Minutes shorthand typedef. -typedef std::chrono::minutes Minutes; - -/// Hours shorthand typedef. -typedef std::chrono::hours Hours; - -/// Makes std::chrono_literals globally available. -// ToDo: Enable this when TC supports C++14. -// using namespace std::chrono_literals; - -#endif // _DURATION_H_ diff --git a/src/server/shared/Utilities/EventMap.cpp b/src/server/shared/Utilities/EventMap.cpp deleted file mode 100644 index 8c3f60afe82..00000000000 --- a/src/server/shared/Utilities/EventMap.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "EventMap.h" - -void EventMap::Reset() -{ - _eventMap.clear(); - _time = 0; - _phase = 0; -} - -void EventMap::SetPhase(uint8 phase) -{ - if (!phase) - _phase = 0; - else if (phase <= 8) - _phase = uint8(1 << (phase - 1)); -} - -void EventMap::ScheduleEvent(uint32 eventId, uint32 time, uint32 group /*= 0*/, uint8 phase /*= 0*/) -{ - if (group && group <= 8) - eventId |= (1 << (group + 15)); - - if (phase && phase <= 8) - eventId |= (1 << (phase + 23)); - - _eventMap.insert(EventStore::value_type(_time + time, eventId)); -} - -uint32 EventMap::ExecuteEvent() -{ - while (!Empty()) - { - EventStore::iterator itr = _eventMap.begin(); - - if (itr->first > _time) - return 0; - else if (_phase && (itr->second & 0xFF000000) && !((itr->second >> 24) & _phase)) - _eventMap.erase(itr); - else - { - uint32 eventId = (itr->second & 0x0000FFFF); - _lastEvent = itr->second; // include phase/group - _eventMap.erase(itr); - return eventId; - } - } - - return 0; -} - -void EventMap::DelayEvents(uint32 delay, uint32 group) -{ - if (!group || group > 8 || Empty()) - return; - - EventStore delayed; - - for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) - { - if (itr->second & (1 << (group + 15))) - { - delayed.insert(EventStore::value_type(itr->first + delay, itr->second)); - _eventMap.erase(itr++); - } - else - ++itr; - } - - _eventMap.insert(delayed.begin(), delayed.end()); -} - -void EventMap::CancelEvent(uint32 eventId) -{ - if (Empty()) - return; - - for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) - { - if (eventId == (itr->second & 0x0000FFFF)) - _eventMap.erase(itr++); - else - ++itr; - } -} - -void EventMap::CancelEventGroup(uint32 group) -{ - if (!group || group > 8 || Empty()) - return; - - for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();) - { - if (itr->second & (1 << (group + 15))) - _eventMap.erase(itr++); - else - ++itr; - } -} - -uint32 EventMap::GetNextEventTime(uint32 eventId) const -{ - if (Empty()) - return 0; - - for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr) - if (eventId == (itr->second & 0x0000FFFF)) - return itr->first; - - return 0; -} - -uint32 EventMap::GetTimeUntilEvent(uint32 eventId) const -{ - for (EventStore::const_iterator itr = _eventMap.begin(); itr != _eventMap.end(); ++itr) - if (eventId == (itr->second & 0x0000FFFF)) - return itr->first - _time; - - return std::numeric_limits<uint32>::max(); -} diff --git a/src/server/shared/Utilities/EventMap.h b/src/server/shared/Utilities/EventMap.h deleted file mode 100644 index 021dffc4940..00000000000 --- a/src/server/shared/Utilities/EventMap.h +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _EVENT_MAP_H_ -#define _EVENT_MAP_H_ - -#include "Common.h" -#include "Duration.h" -#include "Util.h" - -class EventMap -{ - /** - * Internal storage type. - * Key: Time as uint32 when the event should occur. - * Value: The event data as uint32. - * - * Structure of event data: - * - Bit 0 - 15: Event Id. - * - Bit 16 - 23: Group - * - Bit 24 - 31: Phase - * - Pattern: 0xPPGGEEEE - */ - typedef std::multimap<uint32, uint32> EventStore; - -public: - EventMap() : _time(0), _phase(0), _lastEvent(0) { } - - /** - * @name Reset - * @brief Removes all scheduled events and resets time and phase. - */ - void Reset(); - - /** - * @name Update - * @brief Updates the timer of the event map. - * @param time Value in ms to be added to time. - */ - void Update(uint32 time) - { - _time += time; - } - - /** - * @name GetTimer - * @return Current timer in ms value. - */ - uint32 GetTimer() const - { - return _time; - } - - /** - * @name GetPhaseMask - * @return Active phases as mask. - */ - uint8 GetPhaseMask() const - { - return _phase; - } - - /** - * @name Empty - * @return True, if there are no events scheduled. - */ - bool Empty() const - { - return _eventMap.empty(); - } - - /** - * @name SetPhase - * @brief Sets the phase of the map (absolute). - * @param phase Phase which should be set. Values: 1 - 8. 0 resets phase. - */ - void SetPhase(uint8 phase); - - /** - * @name AddPhase - * @brief Activates the given phase (bitwise). - * @param phase Phase which should be activated. Values: 1 - 8 - */ - void AddPhase(uint8 phase) - { - if (phase && phase <= 8) - _phase |= uint8(1 << (phase - 1)); - } - - /** - * @name RemovePhase - * @brief Deactivates the given phase (bitwise). - * @param phase Phase which should be deactivated. Values: 1 - 8. - */ - void RemovePhase(uint8 phase) - { - if (phase && phase <= 8) - _phase &= uint8(~(1 << (phase - 1))); - } - - /** - * @name ScheduleEvent - * @brief Creates new event entry in map. - * @param eventId The id of the new event. - * @param time The time in milliseconds as std::chrono::duration until the event occurs. - * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group. - * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases. - */ - void ScheduleEvent(uint32 eventId, Milliseconds const& time, uint32 group = 0, uint8 phase = 0) - { - ScheduleEvent(eventId, time.count(), group, phase); - } - - /** - * @name ScheduleEvent - * @brief Creates new event entry in map. - * @param eventId The id of the new event. - * @param time The time in milliseconds until the event occurs. - * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group. - * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases. - */ - void ScheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0); - - /** - * @name RescheduleEvent - * @brief Cancels the given event and reschedules it. - * @param eventId The id of the event. - * @param time The time in milliseconds as std::chrono::duration until the event occurs. - * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group. - * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases. - */ - void RescheduleEvent(uint32 eventId, Milliseconds const& time, uint32 group = 0, uint8 phase = 0) - { - RescheduleEvent(eventId, time.count(), group, phase); - } - - /** - * @name RescheduleEvent - * @brief Cancels the given event and reschedules it. - * @param eventId The id of the event. - * @param time The time in milliseconds until the event occurs. - * @param group The group which the event is associated to. Has to be between 1 and 8. 0 means it has no group. - * @param phase The phase in which the event can occur. Has to be between 1 and 8. 0 means it can occur in all phases. - */ - void RescheduleEvent(uint32 eventId, uint32 time, uint32 group = 0, uint8 phase = 0) - { - CancelEvent(eventId); - ScheduleEvent(eventId, time, group, phase); - } - - /** - * @name RepeatEvent - * @brief Repeats the mostly recently executed event. - * @param time Time until in milliseconds as std::chrono::duration the event occurs. - */ - void Repeat(Milliseconds const& time) - { - Repeat(time.count()); - } - - /** - * @name RepeatEvent - * @brief Repeats the mostly recently executed event. - * @param time Time until the event occurs. - */ - void Repeat(uint32 time) - { - _eventMap.insert(EventStore::value_type(_time + time, _lastEvent)); - } - - /** - * @name RepeatEvent - * @brief Repeats the mostly recently executed event. - * @param minTime Minimum time as std::chrono::duration until the event occurs. - * @param maxTime Maximum time as std::chrono::duration until the event occurs. - */ - void Repeat(Milliseconds const& minTime, Milliseconds const& maxTime) - { - Repeat(minTime.count(), maxTime.count()); - } - - /** - * @name RepeatEvent - * @brief Repeats the mostly recently executed event, Equivalent to Repeat(urand(minTime, maxTime). - * @param minTime Minimum time until the event occurs. - * @param maxTime Maximum time until the event occurs. - */ - void Repeat(uint32 minTime, uint32 maxTime) - { - Repeat(urand(minTime, maxTime)); - } - - /** - * @name ExecuteEvent - * @brief Returns the next event to execute and removes it from map. - * @return Id of the event to execute. - */ - uint32 ExecuteEvent(); - - /** - * @name DelayEvents - * @brief Delays all events in the map. If delay is greater than or equal internal timer, delay will be 0. - * @param delay Amount of delay in ms as std::chrono::duration. - */ - void DelayEvents(Milliseconds const& delay) - { - DelayEvents(delay.count()); - } - - /** - * @name DelayEvents - * @brief Delays all events in the map. If delay is greater than or equal internal timer, delay will be 0. - * @param delay Amount of delay. - */ - void DelayEvents(uint32 delay) - { - _time = delay < _time ? _time - delay : 0; - } - - /** - * @name DelayEvents - * @brief Delay all events of the same group. - * @param delay Amount of delay in ms as std::chrono::duration. - * @param group Group of the events. - */ - void DelayEvents(Milliseconds const& delay, uint32 group) - { - DelayEvents(delay.count(), group); - } - - /** - * @name DelayEvents - * @brief Delay all events of the same group. - * @param delay Amount of delay. - * @param group Group of the events. - */ - void DelayEvents(uint32 delay, uint32 group); - - /** - * @name CancelEvent - * @brief Cancels all events of the specified id. - * @param eventId Event id to cancel. - */ - void CancelEvent(uint32 eventId); - - /** - * @name CancelEventGroup - * @brief Cancel events belonging to specified group. - * @param group Group to cancel. - */ - void CancelEventGroup(uint32 group); - - /** - * @name GetNextEventTime - * @brief Returns closest occurence of specified event. - * @param eventId Wanted event id. - * @return Time of found event. - */ - uint32 GetNextEventTime(uint32 eventId) const; - - /** - * @name GetNextEventTime - * @return Time of next event. - */ - uint32 GetNextEventTime() const - { - return Empty() ? 0 : _eventMap.begin()->first; - } - - /** - * @name IsInPhase - * @brief Returns whether event map is in specified phase or not. - * @param phase Wanted phase. - * @return True, if phase of event map contains specified phase. - */ - bool IsInPhase(uint8 phase) const - { - return phase <= 8 && (!phase || _phase & (1 << (phase - 1))); - } - - /** - * @name GetTimeUntilEvent - * @brief Returns time in milliseconds until next event. - * @param eventId of the event. - * @return Time of next event. - */ - uint32 GetTimeUntilEvent(uint32 eventId) const; - -private: - /** - * @name _time - * @brief Internal timer. - * - * This does not represent the real date/time value. - * It's more like a stopwatch: It can run, it can be stopped, - * it can be resetted and so on. Events occur when this timer - * has reached their time value. Its value is changed in the - * Update method. - */ - uint32 _time; - - /** - * @name _phase - * @brief Phase mask of the event map. - * - * Contains the phases the event map is in. Multiple - * phases from 1 to 8 can be set with SetPhase or - * AddPhase. RemovePhase deactives a phase. - */ - uint8 _phase; - - /** - * @name _eventMap - * @brief Internal event storage map. Contains the scheduled events. - * - * See typedef at the beginning of the class for more - * details. - */ - EventStore _eventMap; - - /** - * @name _lastEvent - * @brief Stores information on the most recently executed event - */ - uint32 _lastEvent; -}; - -#endif // _EVENT_MAP_H_ diff --git a/src/server/shared/Utilities/EventProcessor.cpp b/src/server/shared/Utilities/EventProcessor.cpp deleted file mode 100644 index 34695665443..00000000000 --- a/src/server/shared/Utilities/EventProcessor.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "EventProcessor.h" - -EventProcessor::EventProcessor() -{ - m_time = 0; - m_aborting = false; -} - -EventProcessor::~EventProcessor() -{ - KillAllEvents(true); -} - -void EventProcessor::Update(uint32 p_time) -{ - // update time - m_time += p_time; - - // main event loop - EventList::iterator i; - while (((i = m_events.begin()) != m_events.end()) && i->first <= m_time) - { - // get and remove event from queue - BasicEvent* Event = i->second; - m_events.erase(i); - - if (!Event->to_Abort) - { - if (Event->Execute(m_time, p_time)) - { - // completely destroy event if it is not re-added - delete Event; - } - } - else - { - Event->Abort(m_time); - delete Event; - } - } -} - -void EventProcessor::KillAllEvents(bool force) -{ - // prevent event insertions - m_aborting = true; - - // first, abort all existing events - for (EventList::iterator i = m_events.begin(); i != m_events.end();) - { - EventList::iterator i_old = i; - ++i; - - i_old->second->to_Abort = true; - i_old->second->Abort(m_time); - if (force || i_old->second->IsDeletable()) - { - delete i_old->second; - - if (!force) // need per-element cleanup - m_events.erase (i_old); - } - } - - // fast clear event list (in force case) - if (force) - m_events.clear(); -} - -void EventProcessor::AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime) -{ - if (set_addtime) Event->m_addTime = m_time; - Event->m_execTime = e_time; - m_events.insert(std::pair<uint64, BasicEvent*>(e_time, Event)); -} - -uint64 EventProcessor::CalculateTime(uint64 t_offset) const -{ - return(m_time + t_offset); -} - diff --git a/src/server/shared/Utilities/EventProcessor.h b/src/server/shared/Utilities/EventProcessor.h deleted file mode 100644 index 3d54bd6f9f2..00000000000 --- a/src/server/shared/Utilities/EventProcessor.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef __EVENTPROCESSOR_H -#define __EVENTPROCESSOR_H - -#include "Define.h" - -#include <map> - -// Note. All times are in milliseconds here. - -class BasicEvent -{ - public: - BasicEvent() - { - to_Abort = false; - m_addTime = 0; - m_execTime = 0; - } - virtual ~BasicEvent() { } // override destructor to perform some actions on event removal - - // this method executes when the event is triggered - // return false if event does not want to be deleted - // e_time is execution time, p_time is update interval - virtual bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) { return true; } - - virtual bool IsDeletable() const { return true; } // this event can be safely deleted - - virtual void Abort(uint64 /*e_time*/) { } // this method executes when the event is aborted - - bool to_Abort; // set by externals when the event is aborted, aborted events don't execute - // and get Abort call when deleted - - // these can be used for time offset control - uint64 m_addTime; // time when the event was added to queue, filled by event handler - uint64 m_execTime; // planned time of next execution, filled by event handler -}; - -typedef std::multimap<uint64, BasicEvent*> EventList; - -class EventProcessor -{ - public: - EventProcessor(); - ~EventProcessor(); - - void Update(uint32 p_time); - void KillAllEvents(bool force); - void AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime = true); - uint64 CalculateTime(uint64 t_offset) const; - protected: - uint64 m_time; - EventList m_events; - bool m_aborting; -}; -#endif diff --git a/src/server/shared/Utilities/StringFormat.h b/src/server/shared/Utilities/StringFormat.h deleted file mode 100644 index 67e0100e7c8..00000000000 --- a/src/server/shared/Utilities/StringFormat.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef TRINITYCORE_STRING_FORMAT_H -#define TRINITYCORE_STRING_FORMAT_H - -#include "format.h" - -namespace Trinity -{ - /// Default TC string format function. - template<typename Format, typename... Args> - inline std::string StringFormat(Format&& fmt, Args&&... args) - { - return fmt::sprintf(std::forward<Format>(fmt), std::forward<Args>(args)...); - } - - /// Returns true if the given char pointer is null. - inline bool IsFormatEmptyOrNull(const char* fmt) - { - return fmt == nullptr; - } - - /// Returns true if the given std::string is empty. - inline bool IsFormatEmptyOrNull(std::string const& fmt) - { - return fmt.empty(); - } -} - -#endif diff --git a/src/server/shared/Utilities/TaskScheduler.cpp b/src/server/shared/Utilities/TaskScheduler.cpp deleted file mode 100644 index 801cc96cf77..00000000000 --- a/src/server/shared/Utilities/TaskScheduler.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "TaskScheduler.h" - -TaskScheduler& TaskScheduler::ClearValidator() -{ - _predicate = EmptyValidator; - return *this; -} - -TaskScheduler& TaskScheduler::Update(success_t const& callback) -{ - _now = clock_t::now(); - Dispatch(callback); - return *this; -} - -TaskScheduler& TaskScheduler::Update(size_t const milliseconds, success_t const& callback) -{ - return Update(std::chrono::milliseconds(milliseconds), callback); -} - -TaskScheduler& TaskScheduler::Async(std::function<void()> const& callable) -{ - _asyncHolder.push(callable); - return *this; -} - -TaskScheduler& TaskScheduler::CancelAll() -{ - /// Clear the task holder - _task_holder.Clear(); - _asyncHolder = AsyncHolder(); - return *this; -} - -TaskScheduler& TaskScheduler::CancelGroup(group_t const group) -{ - _task_holder.RemoveIf([group](TaskContainer const& task) -> bool - { - return task->IsInGroup(group); - }); - return *this; -} - -TaskScheduler& TaskScheduler::CancelGroupsOf(std::vector<group_t> const& groups) -{ - std::for_each(groups.begin(), groups.end(), - std::bind(&TaskScheduler::CancelGroup, this, std::placeholders::_1)); - - return *this; -} - -TaskScheduler& TaskScheduler::InsertTask(TaskContainer task) -{ - _task_holder.Push(std::move(task)); - return *this; -} - -void TaskScheduler::Dispatch(success_t const& callback) -{ - // If the validation failed abort the dispatching here. - if (!_predicate()) - return; - - // Process all asyncs - while (!_asyncHolder.empty()) - { - _asyncHolder.front()(); - _asyncHolder.pop(); - - // If the validation failed abort the dispatching here. - if (!_predicate()) - return; - } - - while (!_task_holder.IsEmpty()) - { - if (_task_holder.First()->_end > _now) - break; - - // Perfect forward the context to the handler - // Use weak references to catch destruction before callbacks. - TaskContext context(_task_holder.Pop(), std::weak_ptr<TaskScheduler>(self_reference)); - - // Invoke the context - context.Invoke(); - - // If the validation failed abort the dispatching here. - if (!_predicate()) - return; - } - - // On finish call the final callback - callback(); -} - -void TaskScheduler::TaskQueue::Push(TaskContainer&& task) -{ - container.insert(task); -} - -auto TaskScheduler::TaskQueue::Pop() -> TaskContainer -{ - TaskContainer result = *container.begin(); - container.erase(container.begin()); - return result; -} - -auto TaskScheduler::TaskQueue::First() const -> TaskContainer const& -{ - return *container.begin(); -} - -void TaskScheduler::TaskQueue::Clear() -{ - container.clear(); -} - -void TaskScheduler::TaskQueue::RemoveIf(std::function<bool(TaskContainer const&)> const& filter) -{ - for (auto itr = container.begin(); itr != container.end();) - if (filter(*itr)) - itr = container.erase(itr); - else - ++itr; -} - -void TaskScheduler::TaskQueue::ModifyIf(std::function<bool(TaskContainer const&)> const& filter) -{ - std::vector<TaskContainer> cache; - for (auto itr = container.begin(); itr != container.end();) - if (filter(*itr)) - { - cache.push_back(*itr); - itr = container.erase(itr); - } - else - ++itr; - - container.insert(cache.begin(), cache.end()); -} - -bool TaskScheduler::TaskQueue::IsEmpty() const -{ - return container.empty(); -} - -TaskContext& TaskContext::Dispatch(std::function<TaskScheduler&(TaskScheduler&)> const& apply) -{ - if (auto const owner = _owner.lock()) - apply(*owner); - - return *this; -} - -bool TaskContext::IsExpired() const -{ - return _owner.expired(); -} - -bool TaskContext::IsInGroup(TaskScheduler::group_t const group) const -{ - return _task->IsInGroup(group); -} - -TaskContext& TaskContext::SetGroup(TaskScheduler::group_t const group) -{ - _task->_group = group; - return *this; -} - -TaskContext& TaskContext::ClearGroup() -{ - _task->_group = boost::none; - return *this; -} - -TaskScheduler::repeated_t TaskContext::GetRepeatCounter() const -{ - return _task->_repeated; -} - -TaskContext& TaskContext::Async(std::function<void()> const& callable) -{ - return Dispatch(std::bind(&TaskScheduler::Async, std::placeholders::_1, callable)); -} - -TaskContext& TaskContext::CancelAll() -{ - return Dispatch(std::mem_fn(&TaskScheduler::CancelAll)); -} - -TaskContext& TaskContext::CancelGroup(TaskScheduler::group_t const group) -{ - return Dispatch(std::bind(&TaskScheduler::CancelGroup, std::placeholders::_1, group)); -} - -TaskContext& TaskContext::CancelGroupsOf(std::vector<TaskScheduler::group_t> const& groups) -{ - return Dispatch(std::bind(&TaskScheduler::CancelGroupsOf, std::placeholders::_1, std::cref(groups))); -} - -void TaskContext::AssertOnConsumed() const -{ - // This was adapted to TC to prevent static analysis tools from complaining. - // If you encounter this assertion check if you repeat a TaskContext more then 1 time! - ASSERT(!(*_consumed) && "Bad task logic, task context was consumed already!"); -} - -void TaskContext::Invoke() -{ - _task->_task(*this); -} diff --git a/src/server/shared/Utilities/TaskScheduler.h b/src/server/shared/Utilities/TaskScheduler.h deleted file mode 100644 index f1fe7ea0a21..00000000000 --- a/src/server/shared/Utilities/TaskScheduler.h +++ /dev/null @@ -1,650 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _TASK_SCHEDULER_H_ -#define _TASK_SCHEDULER_H_ - -#include <algorithm> -#include <chrono> -#include <vector> -#include <queue> -#include <memory> -#include <utility> -#include <set> - -#include <boost/optional.hpp> - -#include "Util.h" -#include "Duration.h" - -class TaskContext; - -/// The TaskScheduler class provides the ability to schedule std::function's in the near future. -/// Use TaskScheduler::Update to update the scheduler. -/// Popular methods are: -/// * Schedule (Schedules a std::function which will be executed in the near future). -/// * Schedules an asynchronous function which will be executed at the next update tick. -/// * Cancel, Delay & Reschedule (Methods to manipulate already scheduled tasks). -/// Tasks are organized in groups (uint), multiple tasks can have the same group id, -/// you can provide a group or not, but keep in mind that you can only manipulate specific tasks through its group id! -/// Tasks callbacks use the function signature void(TaskContext) where TaskContext provides -/// access to the function schedule plan which makes it possible to repeat the task -/// with the same duration or a new one. -/// It also provides access to the repeat counter which is useful for task that repeat itself often -/// but behave different every time (spoken event dialogs for example). -class TaskScheduler -{ - friend class TaskContext; - - // Time definitions (use steady clock) - typedef std::chrono::steady_clock clock_t; - typedef clock_t::time_point timepoint_t; - typedef clock_t::duration duration_t; - - // Task group type - typedef uint32 group_t; - // Task repeated type - typedef uint32 repeated_t; - // Task handle type - typedef std::function<void(TaskContext)> task_handler_t; - // Predicate type - typedef std::function<bool()> predicate_t; - // Success handle type - typedef std::function<void()> success_t; - - class Task - { - friend class TaskContext; - friend class TaskScheduler; - - timepoint_t _end; - duration_t _duration; - boost::optional<group_t> _group; - repeated_t _repeated; - task_handler_t _task; - - public: - // All Argument construct - Task(timepoint_t const& end, duration_t const& duration, boost::optional<group_t> const& group, - repeated_t const repeated, task_handler_t const& task) - : _end(end), _duration(duration), _group(group), _repeated(repeated), _task(task) { } - - // Minimal Argument construct - Task(timepoint_t const& end, duration_t const& duration, task_handler_t const& task) - : _end(end), _duration(duration), _group(boost::none), _repeated(0), _task(task) { } - - // Copy construct - Task(Task const&) = delete; - // Move construct - Task(Task&&) = delete; - // Copy Assign - Task& operator= (Task const&) = default; - // Move Assign - Task& operator= (Task&& right) = delete; - - // Order tasks by its end - inline bool operator< (Task const& other) const - { - return _end < other._end; - } - - inline bool operator> (Task const& other) const - { - return _end > other._end; - } - - // Compare tasks with its end - inline bool operator== (Task const& other) - { - return _end == other._end; - } - - // Returns true if the task is in the given group - inline bool IsInGroup(group_t const group) const - { - return _group == group; - } - }; - - typedef std::shared_ptr<Task> TaskContainer; - - /// Container which provides Task order, insert and reschedule operations. - struct Compare - { - bool operator() (TaskContainer const& left, TaskContainer const& right) - { - return (*left.get()) < (*right.get()); - }; - }; - - class TaskQueue - { - std::multiset<TaskContainer, Compare> container; - - public: - // Pushes the task in the container - void Push(TaskContainer&& task); - - /// Pops the task out of the container - TaskContainer Pop(); - - TaskContainer const& First() const; - - void Clear(); - - void RemoveIf(std::function<bool(TaskContainer const&)> const& filter); - - void ModifyIf(std::function<bool(TaskContainer const&)> const& filter); - - bool IsEmpty() const; - }; - - /// Contains a self reference to track if this object was deleted or not. - std::shared_ptr<TaskScheduler> self_reference; - - /// The current time point (now) - timepoint_t _now; - - /// The Task Queue which contains all task objects. - TaskQueue _task_holder; - - typedef std::queue<std::function<void()>> AsyncHolder; - - /// Contains all asynchronous tasks which will be invoked at - /// the next update tick. - AsyncHolder _asyncHolder; - - predicate_t _predicate; - - static bool EmptyValidator() - { - return true; - } - - static void EmptyCallback() - { - } - -public: - TaskScheduler() - : self_reference(this, [](TaskScheduler const*) { }), _now(clock_t::now()), _predicate(EmptyValidator) { } - - template<typename P> - TaskScheduler(P&& predicate) - : self_reference(this, [](TaskScheduler const*) { }), _now(clock_t::now()), _predicate(std::forward<P>(predicate)) { } - - TaskScheduler(TaskScheduler const&) = delete; - TaskScheduler(TaskScheduler&&) = delete; - TaskScheduler& operator= (TaskScheduler const&) = delete; - TaskScheduler& operator= (TaskScheduler&&) = delete; - - /// Sets a validator which is asked if tasks are allowed to be executed. - template<typename P> - TaskScheduler& SetValidator(P&& predicate) - { - _predicate = std::forward<P>(predicate); - return *this; - } - - /// Clears the validator which is asked if tasks are allowed to be executed. - TaskScheduler& ClearValidator(); - - /// Update the scheduler to the current time. - /// Calls the optional callback on successfully finish. - TaskScheduler& Update(success_t const& callback = EmptyCallback); - - /// Update the scheduler with a difftime in ms. - /// Calls the optional callback on successfully finish. - TaskScheduler& Update(size_t const milliseconds, success_t const& callback = EmptyCallback); - - /// Update the scheduler with a difftime. - /// Calls the optional callback on successfully finish. - template<class _Rep, class _Period> - TaskScheduler& Update(std::chrono::duration<_Rep, _Period> const& difftime, - success_t const& callback = EmptyCallback) - { - _now += difftime; - Dispatch(callback); - return *this; - } - - /// Schedule an callable function that is executed at the next update tick. - /// Its safe to modify the TaskScheduler from within the callable. - TaskScheduler& Async(std::function<void()> const& callable); - - /// Schedule an event with a fixed rate. - /// Never call this from within a task context! Use TaskContext::Schedule instead! - template<class _Rep, class _Period> - TaskScheduler& Schedule(std::chrono::duration<_Rep, _Period> const& time, - task_handler_t const& task) - { - return ScheduleAt(_now, time, task); - } - - /// Schedule an event with a fixed rate. - /// Never call this from within a task context! Use TaskContext::Schedule instead! - template<class _Rep, class _Period> - TaskScheduler& Schedule(std::chrono::duration<_Rep, _Period> const& time, - group_t const group, task_handler_t const& task) - { - return ScheduleAt(_now, time, group, task); - } - - /// Schedule an event with a randomized rate between min and max rate. - /// Never call this from within a task context! Use TaskContext::Schedule instead! - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> - TaskScheduler& Schedule(std::chrono::duration<_RepLeft, _PeriodLeft> const& min, - std::chrono::duration<_RepRight, _PeriodRight> const& max, task_handler_t const& task) - { - return Schedule(RandomDurationBetween(min, max), task); - } - - /// Schedule an event with a fixed rate. - /// Never call this from within a task context! Use TaskContext::Schedule instead! - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> - TaskScheduler& Schedule(std::chrono::duration<_RepLeft, _PeriodLeft> const& min, - std::chrono::duration<_RepRight, _PeriodRight> const& max, group_t const group, - task_handler_t const& task) - { - return Schedule(RandomDurationBetween(min, max), group, task); - } - - /// Cancels all tasks. - /// Never call this from within a task context! Use TaskContext::CancelAll instead! - TaskScheduler& CancelAll(); - - /// Cancel all tasks of a single group. - /// Never call this from within a task context! Use TaskContext::CancelGroup instead! - TaskScheduler& CancelGroup(group_t const group); - - /// Cancels all groups in the given std::vector. - /// Hint: Use std::initializer_list for this: "{1, 2, 3, 4}" - TaskScheduler& CancelGroupsOf(std::vector<group_t> const& groups); - - /// Delays all tasks with the given duration. - template<class _Rep, class _Period> - TaskScheduler& DelayAll(std::chrono::duration<_Rep, _Period> const& duration) - { - _task_holder.ModifyIf([&duration](TaskContainer const& task) -> bool - { - task->_end += duration; - return true; - }); - return *this; - } - - /// Delays all tasks with a random duration between min and max. - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> - TaskScheduler& DelayAll(std::chrono::duration<_RepLeft, _PeriodLeft> const& min, - std::chrono::duration<_RepRight, _PeriodRight> const& max) - { - return DelayAll(RandomDurationBetween(min, max)); - } - - /// Delays all tasks of a group with the given duration. - template<class _Rep, class _Period> - TaskScheduler& DelayGroup(group_t const group, std::chrono::duration<_Rep, _Period> const& duration) - { - _task_holder.ModifyIf([&duration, group](TaskContainer const& task) -> bool - { - if (task->IsInGroup(group)) - { - task->_end += duration; - return true; - } - else - return false; - }); - return *this; - } - - /// Delays all tasks of a group with a random duration between min and max. - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> - TaskScheduler& DelayGroup(group_t const group, - std::chrono::duration<_RepLeft, _PeriodLeft> const& min, - std::chrono::duration<_RepRight, _PeriodRight> const& max) - { - return DelayGroup(group, RandomDurationBetween(min, max)); - } - - /// Reschedule all tasks with a given duration. - template<class _Rep, class _Period> - TaskScheduler& RescheduleAll(std::chrono::duration<_Rep, _Period> const& duration) - { - auto const end = _now + duration; - _task_holder.ModifyIf([end](TaskContainer const& task) -> bool - { - task->_end = end; - return true; - }); - return *this; - } - - /// Reschedule all tasks with a random duration between min and max. - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> - TaskScheduler& RescheduleAll(std::chrono::duration<_RepLeft, _PeriodLeft> const& min, - std::chrono::duration<_RepRight, _PeriodRight> const& max) - { - return RescheduleAll(RandomDurationBetween(min, max)); - } - - /// Reschedule all tasks of a group with the given duration. - template<class _Rep, class _Period> - TaskScheduler& RescheduleGroup(group_t const group, std::chrono::duration<_Rep, _Period> const& duration) - { - auto const end = _now + duration; - _task_holder.ModifyIf([end, group](TaskContainer const& task) -> bool - { - if (task->IsInGroup(group)) - { - task->_end = end; - return true; - } - else - return false; - }); - return *this; - } - - /// Reschedule all tasks of a group with a random duration between min and max. - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> - TaskScheduler& RescheduleGroup(group_t const group, - std::chrono::duration<_RepLeft, _PeriodLeft> const& min, - std::chrono::duration<_RepRight, _PeriodRight> const& max) - { - return RescheduleGroup(group, RandomDurationBetween(min, max)); - } - -private: - /// Insert a new task to the enqueued tasks. - TaskScheduler& InsertTask(TaskContainer task); - - template<class _Rep, class _Period> - TaskScheduler& ScheduleAt(timepoint_t const& end, - std::chrono::duration<_Rep, _Period> const& time, task_handler_t const& task) - { - return InsertTask(TaskContainer(new Task(end + time, time, task))); - } - - /// Schedule an event with a fixed rate. - /// Never call this from within a task context! Use TaskContext::schedule instead! - template<class _Rep, class _Period> - TaskScheduler& ScheduleAt(timepoint_t const& end, - std::chrono::duration<_Rep, _Period> const& time, - group_t const group, task_handler_t const& task) - { - static repeated_t const DEFAULT_REPEATED = 0; - return InsertTask(TaskContainer(new Task(end + time, time, group, DEFAULT_REPEATED, task))); - } - - // Returns a random duration between min and max - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> - static std::chrono::milliseconds - RandomDurationBetween(std::chrono::duration<_RepLeft, _PeriodLeft> const& min, - std::chrono::duration<_RepRight, _PeriodRight> const& max) - { - auto const milli_min = std::chrono::duration_cast<std::chrono::milliseconds>(min); - auto const milli_max = std::chrono::duration_cast<std::chrono::milliseconds>(max); - - // TC specific: use SFMT URandom - return std::chrono::milliseconds(urand(milli_min.count(), milli_max.count())); - } - - /// Dispatch remaining tasks - void Dispatch(success_t const& callback); -}; - -class TaskContext -{ - friend class TaskScheduler; - - /// Associated task - TaskScheduler::TaskContainer _task; - - /// Owner - std::weak_ptr<TaskScheduler> _owner; - - /// Marks the task as consumed - std::shared_ptr<bool> _consumed; - - /// Dispatches an action safe on the TaskScheduler - TaskContext& Dispatch(std::function<TaskScheduler&(TaskScheduler&)> const& apply); - -public: - // Empty constructor - TaskContext() - : _task(), _owner(), _consumed(std::make_shared<bool>(true)) { } - - // Construct from task and owner - explicit TaskContext(TaskScheduler::TaskContainer&& task, std::weak_ptr<TaskScheduler>&& owner) - : _task(task), _owner(owner), _consumed(std::make_shared<bool>(false)) { } - - // Copy construct - TaskContext(TaskContext const& right) - : _task(right._task), _owner(right._owner), _consumed(right._consumed) { } - - // Move construct - TaskContext(TaskContext&& right) - : _task(std::move(right._task)), _owner(std::move(right._owner)), _consumed(std::move(right._consumed)) { } - - // Copy assign - TaskContext& operator= (TaskContext const& right) - { - _task = right._task; - _owner = right._owner; - _consumed = right._consumed; - return *this; - } - - // Move assign - TaskContext& operator= (TaskContext&& right) - { - _task = std::move(right._task); - _owner = std::move(right._owner); - _consumed = std::move(right._consumed); - return *this; - } - - /// Returns true if the owner was deallocated and this context has expired. - bool IsExpired() const; - - /// Returns true if the event is in the given group - bool IsInGroup(TaskScheduler::group_t const group) const; - - /// Sets the event in the given group - TaskContext& SetGroup(TaskScheduler::group_t const group); - - /// Removes the group from the event - TaskContext& ClearGroup(); - - /// Returns the repeat counter which increases every time the task is repeated. - TaskScheduler::repeated_t GetRepeatCounter() const; - - /// Repeats the event and sets a new duration. - /// std::chrono::seconds(5) for example. - /// This will consume the task context, its not possible to repeat the task again - /// from the same task context! - template<class _Rep, class _Period> - TaskContext& Repeat(std::chrono::duration<_Rep, _Period> const& duration) - { - AssertOnConsumed(); - - // Set new duration, in-context timing and increment repeat counter - _task->_duration = duration; - _task->_end += duration; - _task->_repeated += 1; - (*_consumed) = true; - return Dispatch(std::bind(&TaskScheduler::InsertTask, std::placeholders::_1, _task)); - } - - /// Repeats the event with the same duration. - /// This will consume the task context, its not possible to repeat the task again - /// from the same task context! - TaskContext& Repeat() - { - return Repeat(_task->_duration); - } - - /// Repeats the event and set a new duration that is randomized between min and max. - /// std::chrono::seconds(5) for example. - /// This will consume the task context, its not possible to repeat the task again - /// from the same task context! - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> - TaskContext& Repeat(std::chrono::duration<_RepLeft, _PeriodLeft> const& min, - std::chrono::duration<_RepRight, _PeriodRight> const& max) - { - return Repeat(TaskScheduler::RandomDurationBetween(min, max)); - } - - /// Schedule a callable function that is executed at the next update tick from within the context. - /// Its safe to modify the TaskScheduler from within the callable. - TaskContext& Async(std::function<void()> const& callable); - - /// Schedule an event with a fixed rate from within the context. - /// Its possible that the new event is executed immediately! - /// Use TaskScheduler::Async to create a task - /// which will be called at the next update tick. - template<class _Rep, class _Period> - TaskContext& Schedule(std::chrono::duration<_Rep, _Period> const& time, - TaskScheduler::task_handler_t const& task) - { - auto const end = _task->_end; - return Dispatch([end, time, task](TaskScheduler& scheduler) -> TaskScheduler& - { - return scheduler.ScheduleAt<_Rep, _Period>(end, time, task); - }); - } - - /// Schedule an event with a fixed rate from within the context. - /// Its possible that the new event is executed immediately! - /// Use TaskScheduler::Async to create a task - /// which will be called at the next update tick. - template<class _Rep, class _Period> - TaskContext& Schedule(std::chrono::duration<_Rep, _Period> const& time, - TaskScheduler::group_t const group, TaskScheduler::task_handler_t const& task) - { - auto const end = _task->_end; - return Dispatch([end, time, group, task](TaskScheduler& scheduler) -> TaskScheduler& - { - return scheduler.ScheduleAt<_Rep, _Period>(end, time, group, task); - }); - } - - /// Schedule an event with a randomized rate between min and max rate from within the context. - /// Its possible that the new event is executed immediately! - /// Use TaskScheduler::Async to create a task - /// which will be called at the next update tick. - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> - TaskContext& Schedule(std::chrono::duration<_RepLeft, _PeriodLeft> const& min, - std::chrono::duration<_RepRight, _PeriodRight> const& max, TaskScheduler::task_handler_t const& task) - { - return Schedule(TaskScheduler::RandomDurationBetween(min, max), task); - } - - /// Schedule an event with a randomized rate between min and max rate from within the context. - /// Its possible that the new event is executed immediately! - /// Use TaskScheduler::Async to create a task - /// which will be called at the next update tick. - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> - TaskContext& Schedule(std::chrono::duration<_RepLeft, _PeriodLeft> const& min, - std::chrono::duration<_RepRight, _PeriodRight> const& max, TaskScheduler::group_t const group, - TaskScheduler::task_handler_t const& task) - { - return Schedule(TaskScheduler::RandomDurationBetween(min, max), group, task); - } - - /// Cancels all tasks from within the context. - TaskContext& CancelAll(); - - /// Cancel all tasks of a single group from within the context. - TaskContext& CancelGroup(TaskScheduler::group_t const group); - - /// Cancels all groups in the given std::vector from within the context. - /// Hint: Use std::initializer_list for this: "{1, 2, 3, 4}" - TaskContext& CancelGroupsOf(std::vector<TaskScheduler::group_t> const& groups); - - /// Delays all tasks with the given duration from within the context. - template<class _Rep, class _Period> - TaskContext& DelayAll(std::chrono::duration<_Rep, _Period> const& duration) - { - return Dispatch(std::bind(&TaskScheduler::DelayAll<_Rep, _Period>, std::placeholders::_1, duration)); - } - - /// Delays all tasks with a random duration between min and max from within the context. - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> - TaskContext& DelayAll(std::chrono::duration<_RepLeft, _PeriodLeft> const& min, - std::chrono::duration<_RepRight, _PeriodRight> const& max) - { - return DelayAll(TaskScheduler::RandomDurationBetween(min, max)); - } - - /// Delays all tasks of a group with the given duration from within the context. - template<class _Rep, class _Period> - TaskContext& DelayGroup(TaskScheduler::group_t const group, std::chrono::duration<_Rep, _Period> const& duration) - { - return Dispatch(std::bind(&TaskScheduler::DelayGroup<_Rep, _Period>, std::placeholders::_1, group, duration)); - } - - /// Delays all tasks of a group with a random duration between min and max from within the context. - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> - TaskContext& DelayGroup(TaskScheduler::group_t const group, - std::chrono::duration<_RepLeft, _PeriodLeft> const& min, - std::chrono::duration<_RepRight, _PeriodRight> const& max) - { - return DelayGroup(group, TaskScheduler::RandomDurationBetween(min, max)); - } - - /// Reschedule all tasks with the given duration. - template<class _Rep, class _Period> - TaskContext& RescheduleAll(std::chrono::duration<_Rep, _Period> const& duration) - { - return Dispatch(std::bind(&TaskScheduler::RescheduleAll, std::placeholders::_1, duration)); - } - - /// Reschedule all tasks with a random duration between min and max. - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> - TaskContext& RescheduleAll(std::chrono::duration<_RepLeft, _PeriodLeft> const& min, - std::chrono::duration<_RepRight, _PeriodRight> const& max) - { - return RescheduleAll(TaskScheduler::RandomDurationBetween(min, max)); - } - - /// Reschedule all tasks of a group with the given duration. - template<class _Rep, class _Period> - TaskContext& RescheduleGroup(TaskScheduler::group_t const group, std::chrono::duration<_Rep, _Period> const& duration) - { - return Dispatch(std::bind(&TaskScheduler::RescheduleGroup<_Rep, _Period>, std::placeholders::_1, group, duration)); - } - - /// Reschedule all tasks of a group with a random duration between min and max. - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> - TaskContext& RescheduleGroup(TaskScheduler::group_t const group, - std::chrono::duration<_RepLeft, _PeriodLeft> const& min, - std::chrono::duration<_RepRight, _PeriodRight> const& max) - { - return RescheduleGroup(group, TaskScheduler::RandomDurationBetween(min, max)); - } - -private: - /// Asserts if the task was consumed already. - void AssertOnConsumed() const; - - /// Invokes the associated hook of the task. - void Invoke(); -}; - -#endif /// _TASK_SCHEDULER_H_ diff --git a/src/server/shared/Utilities/Timer.h b/src/server/shared/Utilities/Timer.h deleted file mode 100644 index c54903d7be2..00000000000 --- a/src/server/shared/Utilities/Timer.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef TRINITY_TIMER_H -#define TRINITY_TIMER_H - -#include <chrono> - -inline uint32 getMSTime() -{ - using namespace std::chrono; - - static const system_clock::time_point ApplicationStartTime = system_clock::now(); - - return uint32(duration_cast<milliseconds>(system_clock::now() - ApplicationStartTime).count()); -} - -inline uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime) -{ - // getMSTime() have limited data range and this is case when it overflow in this tick - if (oldMSTime > newMSTime) - return (0xFFFFFFFF - oldMSTime) + newMSTime; - else - return newMSTime - oldMSTime; -} - -inline uint32 GetMSTimeDiffToNow(uint32 oldMSTime) -{ - return getMSTimeDiff(oldMSTime, getMSTime()); -} - -struct IntervalTimer -{ -public: - - IntervalTimer() - : _interval(0), _current(0) - { - } - - void Update(time_t diff) - { - _current += diff; - if (_current < 0) - _current = 0; - } - - bool Passed() - { - return _current >= _interval; - } - - void Reset() - { - if (_current >= _interval) - _current %= _interval; - } - - void SetCurrent(time_t current) - { - _current = current; - } - - void SetInterval(time_t interval) - { - _interval = interval; - } - - time_t GetInterval() const - { - return _interval; - } - - time_t GetCurrent() const - { - return _current; - } - -private: - - time_t _interval; - time_t _current; -}; - -struct TimeTracker -{ -public: - - TimeTracker(time_t expiry) - : i_expiryTime(expiry) - { - } - - void Update(time_t diff) - { - i_expiryTime -= diff; - } - - bool Passed() const - { - return i_expiryTime <= 0; - } - - void Reset(time_t interval) - { - i_expiryTime = interval; - } - - time_t GetExpiry() const - { - return i_expiryTime; - } - -private: - - time_t i_expiryTime; -}; - -struct TimeTrackerSmall -{ -public: - - TimeTrackerSmall(uint32 expiry = 0) - : i_expiryTime(expiry) - { - } - - void Update(int32 diff) - { - i_expiryTime -= diff; - } - - bool Passed() const - { - return i_expiryTime <= 0; - } - - void Reset(uint32 interval) - { - i_expiryTime = interval; - } - - int32 GetExpiry() const - { - return i_expiryTime; - } - -private: - - int32 i_expiryTime; -}; - -struct PeriodicTimer -{ -public: - - PeriodicTimer(int32 period, int32 start_time) - : i_period(period), i_expireTime(start_time) - { - } - - bool Update(const uint32 diff) - { - if ((i_expireTime -= diff) > 0) - return false; - - i_expireTime += i_period > int32(diff) ? i_period : diff; - return true; - } - - void SetPeriodic(int32 period, int32 start_time) - { - i_expireTime = start_time; - i_period = period; - } - - // Tracker interface - void TUpdate(int32 diff) { i_expireTime -= diff; } - bool TPassed() const { return i_expireTime <= 0; } - void TReset(int32 diff, int32 period) { i_expireTime += period > diff ? period : diff; } - -private: - - int32 i_period; - int32 i_expireTime; -}; - -#endif diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp deleted file mode 100644 index 33c273fb05f..00000000000 --- a/src/server/shared/Utilities/Util.cpp +++ /dev/null @@ -1,562 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#include "Util.h" -#include "Common.h" -#include "CompilerDefs.h" -#include "utf8.h" -#include "SFMT.h" -#include "Errors.h" // for ASSERT -#include <stdarg.h> -#include <boost/thread/tss.hpp> - -#if COMPILER == COMPILER_GNU - #include <sys/socket.h> - #include <netinet/in.h> - #include <arpa/inet.h> -#endif - -static boost::thread_specific_ptr<SFMTRand> sfmtRand; - -static SFMTRand* GetRng() -{ - SFMTRand* rand = sfmtRand.get(); - - if (!rand) - { - rand = new SFMTRand(); - sfmtRand.reset(rand); - } - - return rand; -} - -int32 irand(int32 min, int32 max) -{ - ASSERT(max >= min); - return int32(GetRng()->IRandom(min, max)); -} - -uint32 urand(uint32 min, uint32 max) -{ - ASSERT(max >= min); - return GetRng()->URandom(min, max); -} - -float frand(float min, float max) -{ - ASSERT(max >= min); - return float(GetRng()->Random() * (max - min) + min); -} - -uint32 rand32() -{ - return GetRng()->BRandom(); -} - -double rand_norm() -{ - return GetRng()->Random(); -} - -double rand_chance() -{ - return GetRng()->Random() * 100.0; -} - -Tokenizer::Tokenizer(const std::string &src, const char sep, uint32 vectorReserve) -{ - m_str = new char[src.length() + 1]; - memcpy(m_str, src.c_str(), src.length() + 1); - - if (vectorReserve) - m_storage.reserve(vectorReserve); - - char* posold = m_str; - char* posnew = m_str; - - for (;;) - { - if (*posnew == sep) - { - m_storage.push_back(posold); - posold = posnew + 1; - - *posnew = '\0'; - } - else if (*posnew == '\0') - { - // Hack like, but the old code accepted these kind of broken strings, - // so changing it would break other things - if (posold != posnew) - m_storage.push_back(posold); - - break; - } - - ++posnew; - } -} - -void stripLineInvisibleChars(std::string &str) -{ - static std::string const invChars = " \t\7\n"; - - size_t wpos = 0; - - bool space = false; - for (size_t pos = 0; pos < str.size(); ++pos) - { - if (invChars.find(str[pos])!=std::string::npos) - { - if (!space) - { - str[wpos++] = ' '; - space = true; - } - } - else - { - if (wpos!=pos) - str[wpos++] = str[pos]; - else - ++wpos; - space = false; - } - } - - if (wpos < str.size()) - str.erase(wpos, str.size()); - if (str.find("|TInterface")!=std::string::npos) - str.clear(); - -} - -#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) -struct tm* localtime_r(const time_t* time, struct tm *result) -{ - localtime_s(result, time); - return result; -} -#endif - -std::string secsToTimeString(uint64 timeInSecs, bool shortText, bool hoursOnly) -{ - uint64 secs = timeInSecs % MINUTE; - uint64 minutes = timeInSecs % HOUR / MINUTE; - uint64 hours = timeInSecs % DAY / HOUR; - uint64 days = timeInSecs / DAY; - - std::ostringstream ss; - if (days) - ss << days << (shortText ? "d" : " Day(s) "); - if (hours || hoursOnly) - ss << hours << (shortText ? "h" : " Hour(s) "); - if (!hoursOnly) - { - if (minutes) - ss << minutes << (shortText ? "m" : " Minute(s) "); - if (secs || (!days && !hours && !minutes) ) - ss << secs << (shortText ? "s" : " Second(s)."); - } - - return ss.str(); -} - -int32 MoneyStringToMoney(const std::string& moneyString) -{ - int32 money = 0; - - if (!(std::count(moneyString.begin(), moneyString.end(), 'g') == 1 || - std::count(moneyString.begin(), moneyString.end(), 's') == 1 || - std::count(moneyString.begin(), moneyString.end(), 'c') == 1)) - return 0; // Bad format - - Tokenizer tokens(moneyString, ' '); - for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr) - { - std::string tokenString(*itr); - size_t gCount = std::count(tokenString.begin(), tokenString.end(), 'g'); - size_t sCount = std::count(tokenString.begin(), tokenString.end(), 's'); - size_t cCount = std::count(tokenString.begin(), tokenString.end(), 'c'); - if (gCount + sCount + cCount != 1) - return 0; - - uint32 amount = atoi(*itr); - if (gCount == 1) - money += amount * 100 * 100; - else if (sCount == 1) - money += amount * 100; - else if (cCount == 1) - money += amount; - } - - return money; -} - -uint32 TimeStringToSecs(const std::string& timestring) -{ - uint32 secs = 0; - uint32 buffer = 0; - uint32 multiplier = 0; - - for (std::string::const_iterator itr = timestring.begin(); itr != timestring.end(); ++itr) - { - if (isdigit(*itr)) - { - buffer*=10; - buffer+= (*itr)-'0'; - } - else - { - switch (*itr) - { - case 'd': multiplier = DAY; break; - case 'h': multiplier = HOUR; break; - case 'm': multiplier = MINUTE; break; - case 's': multiplier = 1; break; - default : return 0; //bad format - } - buffer*=multiplier; - secs+=buffer; - buffer=0; - } - } - - return secs; -} - -std::string TimeToTimestampStr(time_t t) -{ - tm aTm; - localtime_r(&t, &aTm); - // YYYY year - // MM month (2 digits 01-12) - // DD day (2 digits 01-31) - // HH hour (2 digits 00-23) - // MM minutes (2 digits 00-59) - // SS seconds (2 digits 00-59) - char buf[20]; - snprintf(buf, 20, "%04d-%02d-%02d_%02d-%02d-%02d", aTm.tm_year+1900, aTm.tm_mon+1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec); - return std::string(buf); -} - -/// Check if the string is a valid ip address representation -bool IsIPAddress(char const* ipaddress) -{ - if (!ipaddress) - return false; - - // Let the big boys do it. - // Drawback: all valid ip address formats are recognized e.g.: 12.23, 121234, 0xABCD) - return inet_addr(ipaddress) != INADDR_NONE; -} - -/// create PID file -uint32 CreatePIDFile(const std::string& filename) -{ - FILE* pid_file = fopen (filename.c_str(), "w" ); - if (pid_file == NULL) - return 0; - -#ifdef _WIN32 - DWORD pid = GetCurrentProcessId(); -#else - pid_t pid = getpid(); -#endif - - fprintf(pid_file, "%u", pid ); - fclose(pid_file); - - return (uint32)pid; -} - -size_t utf8length(std::string& utf8str) -{ - try - { - return utf8::distance(utf8str.c_str(), utf8str.c_str()+utf8str.size()); - } - catch(std::exception) - { - utf8str.clear(); - return 0; - } -} - -void utf8truncate(std::string& utf8str, size_t len) -{ - try - { - size_t wlen = utf8::distance(utf8str.c_str(), utf8str.c_str()+utf8str.size()); - if (wlen <= len) - return; - - std::wstring wstr; - wstr.resize(wlen); - utf8::utf8to16(utf8str.c_str(), utf8str.c_str()+utf8str.size(), &wstr[0]); - wstr.resize(len); - char* oend = utf8::utf16to8(wstr.c_str(), wstr.c_str()+wstr.size(), &utf8str[0]); - utf8str.resize(oend-(&utf8str[0])); // remove unused tail - } - catch(std::exception) - { - utf8str.clear(); - } -} - -bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize) -{ - try - { - size_t len = utf8::distance(utf8str, utf8str+csize); - if (len > wsize) - { - if (wsize > 0) - wstr[0] = L'\0'; - wsize = 0; - return false; - } - - wsize = len; - utf8::utf8to16(utf8str, utf8str+csize, wstr); - wstr[len] = L'\0'; - } - catch(std::exception) - { - if (wsize > 0) - wstr[0] = L'\0'; - wsize = 0; - return false; - } - - return true; -} - -bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr) -{ - try - { - if (size_t len = utf8::distance(utf8str.c_str(), utf8str.c_str()+utf8str.size())) - { - wstr.resize(len); - utf8::utf8to16(utf8str.c_str(), utf8str.c_str()+utf8str.size(), &wstr[0]); - } - } - catch(std::exception) - { - wstr.clear(); - return false; - } - - return true; -} - -bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str) -{ - try - { - std::string utf8str2; - utf8str2.resize(size*4); // allocate for most long case - - if (size) - { - char* oend = utf8::utf16to8(wstr, wstr+size, &utf8str2[0]); - utf8str2.resize(oend-(&utf8str2[0])); // remove unused tail - } - utf8str = utf8str2; - } - catch(std::exception) - { - utf8str.clear(); - return false; - } - - return true; -} - -bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str) -{ - try - { - std::string utf8str2; - utf8str2.resize(wstr.size()*4); // allocate for most long case - - if (wstr.size()) - { - char* oend = utf8::utf16to8(wstr.c_str(), wstr.c_str()+wstr.size(), &utf8str2[0]); - utf8str2.resize(oend-(&utf8str2[0])); // remove unused tail - } - utf8str = utf8str2; - } - catch(std::exception) - { - utf8str.clear(); - return false; - } - - return true; -} - -typedef wchar_t const* const* wstrlist; - -std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension) -{ - // supported only Cyrillic cases - if (wname.size() < 1 || !isCyrillicCharacter(wname[0]) || declension > 5) - return wname; - - // Important: end length must be <= MAX_INTERNAL_PLAYER_NAME-MAX_PLAYER_NAME (3 currently) - - static wchar_t const a_End[] = { wchar_t(1), wchar_t(0x0430), wchar_t(0x0000)}; - static wchar_t const o_End[] = { wchar_t(1), wchar_t(0x043E), wchar_t(0x0000)}; - static wchar_t const ya_End[] = { wchar_t(1), wchar_t(0x044F), wchar_t(0x0000)}; - static wchar_t const ie_End[] = { wchar_t(1), wchar_t(0x0435), wchar_t(0x0000)}; - static wchar_t const i_End[] = { wchar_t(1), wchar_t(0x0438), wchar_t(0x0000)}; - static wchar_t const yeru_End[] = { wchar_t(1), wchar_t(0x044B), wchar_t(0x0000)}; - static wchar_t const u_End[] = { wchar_t(1), wchar_t(0x0443), wchar_t(0x0000)}; - static wchar_t const yu_End[] = { wchar_t(1), wchar_t(0x044E), wchar_t(0x0000)}; - static wchar_t const oj_End[] = { wchar_t(2), wchar_t(0x043E), wchar_t(0x0439), wchar_t(0x0000)}; - static wchar_t const ie_j_End[] = { wchar_t(2), wchar_t(0x0435), wchar_t(0x0439), wchar_t(0x0000)}; - static wchar_t const io_j_End[] = { wchar_t(2), wchar_t(0x0451), wchar_t(0x0439), wchar_t(0x0000)}; - static wchar_t const o_m_End[] = { wchar_t(2), wchar_t(0x043E), wchar_t(0x043C), wchar_t(0x0000)}; - static wchar_t const io_m_End[] = { wchar_t(2), wchar_t(0x0451), wchar_t(0x043C), wchar_t(0x0000)}; - static wchar_t const ie_m_End[] = { wchar_t(2), wchar_t(0x0435), wchar_t(0x043C), wchar_t(0x0000)}; - static wchar_t const soft_End[] = { wchar_t(1), wchar_t(0x044C), wchar_t(0x0000)}; - static wchar_t const j_End[] = { wchar_t(1), wchar_t(0x0439), wchar_t(0x0000)}; - - static wchar_t const* const dropEnds[6][8] = { - { &a_End[1], &o_End[1], &ya_End[1], &ie_End[1], &soft_End[1], &j_End[1], NULL, NULL }, - { &a_End[1], &ya_End[1], &yeru_End[1], &i_End[1], NULL, NULL, NULL, NULL }, - { &ie_End[1], &u_End[1], &yu_End[1], &i_End[1], NULL, NULL, NULL, NULL }, - { &u_End[1], &yu_End[1], &o_End[1], &ie_End[1], &soft_End[1], &ya_End[1], &a_End[1], NULL }, - { &oj_End[1], &io_j_End[1], &ie_j_End[1], &o_m_End[1], &io_m_End[1], &ie_m_End[1], &yu_End[1], NULL }, - { &ie_End[1], &i_End[1], NULL, NULL, NULL, NULL, NULL, NULL } - }; - - for (wchar_t const* const* itr = &dropEnds[declension][0]; *itr; ++itr) - { - size_t len = size_t((*itr)[-1]); // get length from string size field - - if (wname.substr(wname.size()-len, len)==*itr) - return wname.substr(0, wname.size()-len); - } - - return wname; -} - -bool utf8ToConsole(const std::string& utf8str, std::string& conStr) -{ -#if PLATFORM == PLATFORM_WINDOWS - std::wstring wstr; - if (!Utf8toWStr(utf8str, wstr)) - return false; - - conStr.resize(wstr.size()); - CharToOemBuffW(&wstr[0], &conStr[0], wstr.size()); -#else - // not implemented yet - conStr = utf8str; -#endif - - return true; -} - -bool consoleToUtf8(const std::string& conStr, std::string& utf8str) -{ -#if PLATFORM == PLATFORM_WINDOWS - std::wstring wstr; - wstr.resize(conStr.size()); - OemToCharBuffW(&conStr[0], &wstr[0], conStr.size()); - - return WStrToUtf8(wstr, utf8str); -#else - // not implemented yet - utf8str = conStr; - return true; -#endif -} - -bool Utf8FitTo(const std::string& str, std::wstring const& search) -{ - std::wstring temp; - - if (!Utf8toWStr(str, temp)) - return false; - - // converting to lower case - wstrToLower( temp ); - - if (temp.find(search) == std::wstring::npos) - return false; - - return true; -} - -void utf8printf(FILE* out, const char *str, ...) -{ - va_list ap; - va_start(ap, str); - vutf8printf(out, str, &ap); - va_end(ap); -} - -void vutf8printf(FILE* out, const char *str, va_list* ap) -{ -#if PLATFORM == PLATFORM_WINDOWS - char temp_buf[32*1024]; - wchar_t wtemp_buf[32*1024]; - - size_t temp_len = vsnprintf(temp_buf, 32*1024, str, *ap); - //vsnprintf returns -1 if the buffer is too small - if (temp_len == size_t(-1)) - temp_len = 32*1024-1; - - size_t wtemp_len = 32*1024-1; - Utf8toWStr(temp_buf, temp_len, wtemp_buf, wtemp_len); - - CharToOemBuffW(&wtemp_buf[0], &temp_buf[0], wtemp_len+1); - fprintf(out, "%s", temp_buf); -#else - vfprintf(out, str, *ap); -#endif -} - -std::string ByteArrayToHexStr(uint8 const* bytes, uint32 arrayLen, bool reverse /* = false */) -{ - int32 init = 0; - int32 end = arrayLen; - int8 op = 1; - - if (reverse) - { - init = arrayLen - 1; - end = -1; - op = -1; - } - - std::ostringstream ss; - for (int32 i = init; i != end; i += op) - { - char buffer[4]; - sprintf(buffer, "%02X", bytes[i]); - ss << buffer; - } - - return ss.str(); -} diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h deleted file mode 100644 index 3da1c800410..00000000000 --- a/src/server/shared/Utilities/Util.h +++ /dev/null @@ -1,545 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * 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; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _UTIL_H -#define _UTIL_H - -#include "Define.h" -#include "Errors.h" - -#include <algorithm> -#include <string> -#include <vector> -#include <list> -#include <map> - -// Searcher for map of structs -template<typename T, class S> struct Finder -{ - T val_; - T S::* idMember_; - - Finder(T val, T S::* idMember) : val_(val), idMember_(idMember) {} - bool operator()(const std::pair<int, S> &obj) { return obj.second.*idMember_ == val_; } -}; - -class Tokenizer -{ -public: - typedef std::vector<char const*> StorageType; - - typedef StorageType::size_type size_type; - - typedef StorageType::const_iterator const_iterator; - typedef StorageType::reference reference; - typedef StorageType::const_reference const_reference; - -public: - Tokenizer(const std::string &src, char const sep, uint32 vectorReserve = 0); - ~Tokenizer() { delete[] m_str; } - - const_iterator begin() const { return m_storage.begin(); } - const_iterator end() const { return m_storage.end(); } - - size_type size() const { return m_storage.size(); } - - reference operator [] (size_type i) { return m_storage[i]; } - const_reference operator [] (size_type i) const { return m_storage[i]; } - -private: - char* m_str; - StorageType m_storage; -}; - -void stripLineInvisibleChars(std::string &src); - -int32 MoneyStringToMoney(const std::string& moneyString); - -struct tm* localtime_r(const time_t* time, struct tm *result); - -std::string secsToTimeString(uint64 timeInSecs, bool shortText = false, bool hoursOnly = false); -uint32 TimeStringToSecs(const std::string& timestring); -std::string TimeToTimestampStr(time_t t); - -/* Return a random number in the range min..max. */ -int32 irand(int32 min, int32 max); - -/* Return a random number in the range min..max (inclusive). */ -uint32 urand(uint32 min, uint32 max); - -/* Return a random number in the range 0 .. UINT32_MAX. */ -uint32 rand32(); - -/* Return a random number in the range min..max */ -float frand(float min, float max); - -/* Return a random double from 0.0 to 1.0 (exclusive). */ -double rand_norm(); - -/* Return a random double from 0.0 to 100.0 (exclusive). */ -double rand_chance(); - -/* Return true if a random roll fits in the specified chance (range 0-100). */ -inline bool roll_chance_f(float chance) -{ - return chance > rand_chance(); -} - -/* Return true if a random roll fits in the specified chance (range 0-100). */ -inline bool roll_chance_i(int chance) -{ - return chance > irand(0, 99); -} - -inline void ApplyPercentModFloatVar(float& var, float val, bool apply) -{ - if (val == -100.0f) // prevent set var to zero - val = -99.99f; - var *= (apply ? (100.0f + val) / 100.0f : 100.0f / (100.0f + val)); -} - -// Percentage calculation -template <class T, class U> -inline T CalculatePct(T base, U pct) -{ - return T(base * static_cast<float>(pct) / 100.0f); -} - -template <class T, class U> -inline T AddPct(T &base, U pct) -{ - return base += CalculatePct(base, pct); -} - -template <class T, class U> -inline T ApplyPct(T &base, U pct) -{ - return base = CalculatePct(base, pct); -} - -template <class T> -inline T RoundToInterval(T& num, T floor, T ceil) -{ - return num = std::min(std::max(num, floor), ceil); -} - -// UTF8 handling -bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr); -// in wsize==max size of buffer, out wsize==real string size -bool Utf8toWStr(char const* utf8str, size_t csize, wchar_t* wstr, size_t& wsize); -inline bool Utf8toWStr(const std::string& utf8str, wchar_t* wstr, size_t& wsize) -{ - return Utf8toWStr(utf8str.c_str(), utf8str.size(), wstr, wsize); -} - -bool WStrToUtf8(std::wstring const& wstr, std::string& utf8str); -// size==real string size -bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str); - -size_t utf8length(std::string& utf8str); // set string to "" if invalid utf8 sequence -void utf8truncate(std::string& utf8str, size_t len); - -inline bool isBasicLatinCharacter(wchar_t wchar) -{ - if (wchar >= L'a' && wchar <= L'z') // LATIN SMALL LETTER A - LATIN SMALL LETTER Z - return true; - if (wchar >= L'A' && wchar <= L'Z') // LATIN CAPITAL LETTER A - LATIN CAPITAL LETTER Z - return true; - return false; -} - -inline bool isExtendedLatinCharacter(wchar_t wchar) -{ - if (isBasicLatinCharacter(wchar)) - return true; - if (wchar >= 0x00C0 && wchar <= 0x00D6) // LATIN CAPITAL LETTER A WITH GRAVE - LATIN CAPITAL LETTER O WITH DIAERESIS - return true; - if (wchar >= 0x00D8 && wchar <= 0x00DE) // LATIN CAPITAL LETTER O WITH STROKE - LATIN CAPITAL LETTER THORN - return true; - if (wchar == 0x00DF) // LATIN SMALL LETTER SHARP S - return true; - if (wchar >= 0x00E0 && wchar <= 0x00F6) // LATIN SMALL LETTER A WITH GRAVE - LATIN SMALL LETTER O WITH DIAERESIS - return true; - if (wchar >= 0x00F8 && wchar <= 0x00FE) // LATIN SMALL LETTER O WITH STROKE - LATIN SMALL LETTER THORN - return true; - if (wchar >= 0x0100 && wchar <= 0x012F) // LATIN CAPITAL LETTER A WITH MACRON - LATIN SMALL LETTER I WITH OGONEK - return true; - if (wchar == 0x1E9E) // LATIN CAPITAL LETTER SHARP S - return true; - return false; -} - -inline bool isCyrillicCharacter(wchar_t wchar) -{ - if (wchar >= 0x0410 && wchar <= 0x044F) // CYRILLIC CAPITAL LETTER A - CYRILLIC SMALL LETTER YA - return true; - if (wchar == 0x0401 || wchar == 0x0451) // CYRILLIC CAPITAL LETTER IO, CYRILLIC SMALL LETTER IO - return true; - return false; -} - -inline bool isEastAsianCharacter(wchar_t wchar) -{ - if (wchar >= 0x1100 && wchar <= 0x11F9) // Hangul Jamo - return true; - if (wchar >= 0x3041 && wchar <= 0x30FF) // Hiragana + Katakana - return true; - if (wchar >= 0x3131 && wchar <= 0x318E) // Hangul Compatibility Jamo - return true; - if (wchar >= 0x31F0 && wchar <= 0x31FF) // Katakana Phonetic Ext. - return true; - if (wchar >= 0x3400 && wchar <= 0x4DB5) // CJK Ideographs Ext. A - return true; - if (wchar >= 0x4E00 && wchar <= 0x9FC3) // Unified CJK Ideographs - return true; - if (wchar >= 0xAC00 && wchar <= 0xD7A3) // Hangul Syllables - return true; - if (wchar >= 0xFF01 && wchar <= 0xFFEE) // Halfwidth forms - return true; - return false; -} - -inline bool isNumeric(wchar_t wchar) -{ - return (wchar >= L'0' && wchar <=L'9'); -} - -inline bool isNumeric(char c) -{ - return (c >= '0' && c <='9'); -} - -inline bool isNumeric(char const* str) -{ - for (char const* c = str; *c; ++c) - if (!isNumeric(*c)) - return false; - - return true; -} - -inline bool isNumericOrSpace(wchar_t wchar) -{ - return isNumeric(wchar) || wchar == L' '; -} - -inline bool isBasicLatinString(const std::wstring &wstr, bool numericOrSpace) -{ - for (size_t i = 0; i < wstr.size(); ++i) - if (!isBasicLatinCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i]))) - return false; - return true; -} - -inline bool isExtendedLatinString(const std::wstring &wstr, bool numericOrSpace) -{ - for (size_t i = 0; i < wstr.size(); ++i) - if (!isExtendedLatinCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i]))) - return false; - return true; -} - -inline bool isCyrillicString(const std::wstring &wstr, bool numericOrSpace) -{ - for (size_t i = 0; i < wstr.size(); ++i) - if (!isCyrillicCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i]))) - return false; - return true; -} - -inline bool isEastAsianString(const std::wstring &wstr, bool numericOrSpace) -{ - for (size_t i = 0; i < wstr.size(); ++i) - if (!isEastAsianCharacter(wstr[i]) && (!numericOrSpace || !isNumericOrSpace(wstr[i]))) - return false; - return true; -} - -inline wchar_t wcharToUpper(wchar_t wchar) -{ - if (wchar >= L'a' && wchar <= L'z') // LATIN SMALL LETTER A - LATIN SMALL LETTER Z - return wchar_t(uint16(wchar)-0x0020); - if (wchar == 0x00DF) // LATIN SMALL LETTER SHARP S - return wchar_t(0x1E9E); - if (wchar >= 0x00E0 && wchar <= 0x00F6) // LATIN SMALL LETTER A WITH GRAVE - LATIN SMALL LETTER O WITH DIAERESIS - return wchar_t(uint16(wchar)-0x0020); - if (wchar >= 0x00F8 && wchar <= 0x00FE) // LATIN SMALL LETTER O WITH STROKE - LATIN SMALL LETTER THORN - return wchar_t(uint16(wchar)-0x0020); - if (wchar >= 0x0101 && wchar <= 0x012F) // LATIN SMALL LETTER A WITH MACRON - LATIN SMALL LETTER I WITH OGONEK (only %2=1) - { - if (wchar % 2 == 1) - return wchar_t(uint16(wchar)-0x0001); - } - if (wchar >= 0x0430 && wchar <= 0x044F) // CYRILLIC SMALL LETTER A - CYRILLIC SMALL LETTER YA - return wchar_t(uint16(wchar)-0x0020); - if (wchar == 0x0451) // CYRILLIC SMALL LETTER IO - return wchar_t(0x0401); - - return wchar; -} - -inline wchar_t wcharToUpperOnlyLatin(wchar_t wchar) -{ - return isBasicLatinCharacter(wchar) ? wcharToUpper(wchar) : wchar; -} - -inline wchar_t wcharToLower(wchar_t wchar) -{ - if (wchar >= L'A' && wchar <= L'Z') // LATIN CAPITAL LETTER A - LATIN CAPITAL LETTER Z - return wchar_t(uint16(wchar)+0x0020); - if (wchar >= 0x00C0 && wchar <= 0x00D6) // LATIN CAPITAL LETTER A WITH GRAVE - LATIN CAPITAL LETTER O WITH DIAERESIS - return wchar_t(uint16(wchar)+0x0020); - if (wchar >= 0x00D8 && wchar <= 0x00DE) // LATIN CAPITAL LETTER O WITH STROKE - LATIN CAPITAL LETTER THORN - return wchar_t(uint16(wchar)+0x0020); - if (wchar >= 0x0100 && wchar <= 0x012E) // LATIN CAPITAL LETTER A WITH MACRON - LATIN CAPITAL LETTER I WITH OGONEK (only %2=0) - { - if (wchar % 2 == 0) - return wchar_t(uint16(wchar)+0x0001); - } - if (wchar == 0x1E9E) // LATIN CAPITAL LETTER SHARP S - return wchar_t(0x00DF); - if (wchar == 0x0401) // CYRILLIC CAPITAL LETTER IO - return wchar_t(0x0451); - if (wchar >= 0x0410 && wchar <= 0x042F) // CYRILLIC CAPITAL LETTER A - CYRILLIC CAPITAL LETTER YA - return wchar_t(uint16(wchar)+0x0020); - - return wchar; -} - -inline void wstrToUpper(std::wstring& str) -{ - std::transform( str.begin(), str.end(), str.begin(), wcharToUpper ); -} - -inline void wstrToLower(std::wstring& str) -{ - std::transform( str.begin(), str.end(), str.begin(), wcharToLower ); -} - -std::wstring GetMainPartOfName(std::wstring const& wname, uint32 declension); - -bool utf8ToConsole(const std::string& utf8str, std::string& conStr); -bool consoleToUtf8(const std::string& conStr, std::string& utf8str); -bool Utf8FitTo(const std::string& str, std::wstring const& search); -void utf8printf(FILE* out, const char *str, ...); -void vutf8printf(FILE* out, const char *str, va_list* ap); - -bool IsIPAddress(char const* ipaddress); - -uint32 CreatePIDFile(const std::string& filename); - -std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false); - -// simple class for not-modifyable list -template <typename T> -class HookList -{ - typedef typename std::list<T>::iterator ListIterator; - private: - typename std::list<T> m_list; - public: - HookList<T> & operator+=(T t) - { - m_list.push_back(t); - return *this; - } - HookList<T> & operator-=(T t) - { - m_list.remove(t); - return *this; - } - size_t size() - { - return m_list.size(); - } - ListIterator begin() - { - return m_list.begin(); - } - ListIterator end() - { - return m_list.end(); - } -}; - -class flag96 -{ -private: - uint32 part[3]; - -public: - flag96(uint32 p1 = 0, uint32 p2 = 0, uint32 p3 = 0) - { - part[0] = p1; - part[1] = p2; - part[2] = p3; - } - - inline bool IsEqual(uint32 p1 = 0, uint32 p2 = 0, uint32 p3 = 0) const - { - return (part[0] == p1 && part[1] == p2 && part[2] == p3); - } - - inline bool HasFlag(uint32 p1 = 0, uint32 p2 = 0, uint32 p3 = 0) const - { - return (part[0] & p1 || part[1] & p2 || part[2] & p3); - } - - inline void Set(uint32 p1 = 0, uint32 p2 = 0, uint32 p3 = 0) - { - part[0] = p1; - part[1] = p2; - part[2] = p3; - } - - inline bool operator <(const flag96 &right) const - { - for (uint8 i = 3; i > 0; --i) - { - if (part[i - 1] < right.part[i - 1]) - return true; - else if (part[i - 1] > right.part[i - 1]) - return false; - } - return false; - } - - inline bool operator ==(const flag96 &right) const - { - return - ( - part[0] == right.part[0] && - part[1] == right.part[1] && - part[2] == right.part[2] - ); - } - - inline bool operator !=(const flag96 &right) const - { - return !this->operator ==(right); - } - - inline flag96 & operator =(const flag96 &right) - { - part[0] = right.part[0]; - part[1] = right.part[1]; - part[2] = right.part[2]; - return *this; - } - - inline flag96 operator &(const flag96 &right) const - { - return flag96(part[0] & right.part[0], part[1] & right.part[1], - part[2] & right.part[2]); - } - - inline flag96 & operator &=(const flag96 &right) - { - part[0] &= right.part[0]; - part[1] &= right.part[1]; - part[2] &= right.part[2]; - return *this; - } - - inline flag96 operator |(const flag96 &right) const - { - return flag96(part[0] | right.part[0], part[1] | right.part[1], - part[2] | right.part[2]); - } - - inline flag96 & operator |=(const flag96 &right) - { - part[0] |= right.part[0]; - part[1] |= right.part[1]; - part[2] |= right.part[2]; - return *this; - } - - inline flag96 operator ~() const - { - return flag96(~part[0], ~part[1], ~part[2]); - } - - inline flag96 operator ^(const flag96 &right) const - { - return flag96(part[0] ^ right.part[0], part[1] ^ right.part[1], - part[2] ^ right.part[2]); - } - - inline flag96 & operator ^=(const flag96 &right) - { - part[0] ^= right.part[0]; - part[1] ^= right.part[1]; - part[2] ^= right.part[2]; - return *this; - } - - inline operator bool() const - { - return (part[0] != 0 || part[1] != 0 || part[2] != 0); - } - - inline bool operator !() const - { - return !this->operator bool(); - } - - inline uint32 & operator [](uint8 el) - { - return part[el]; - } - - inline const uint32 & operator [](uint8 el) const - { - return part[el]; - } -}; - -enum ComparisionType -{ - COMP_TYPE_EQ = 0, - COMP_TYPE_HIGH, - COMP_TYPE_LOW, - COMP_TYPE_HIGH_EQ, - COMP_TYPE_LOW_EQ, - COMP_TYPE_MAX -}; - -template <class T> -bool CompareValues(ComparisionType type, T val1, T val2) -{ - switch (type) - { - case COMP_TYPE_EQ: - return val1 == val2; - case COMP_TYPE_HIGH: - return val1 > val2; - case COMP_TYPE_LOW: - return val1 < val2; - case COMP_TYPE_HIGH_EQ: - return val1 >= val2; - case COMP_TYPE_LOW_EQ: - return val1 <= val2; - default: - // incorrect parameter - ASSERT(false); - return false; - } -} - -#endif |