mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-14 17:49:10 +00:00
Big re-organization of repository [W.I.P]
This commit is contained in:
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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_AUTO_PTR_H
|
||||
#define _TRINITY_AUTO_PTR_H
|
||||
|
||||
#include <ace/Bound_Ptr.h>
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
|
||||
template <class Pointer, class Lock>
|
||||
class AutoPtr : public ACE_Strong_Bound_Ptr<Pointer, Lock>
|
||||
{
|
||||
typedef ACE_Strong_Bound_Ptr<Pointer, Lock> Base;
|
||||
|
||||
public:
|
||||
AutoPtr()
|
||||
: Base()
|
||||
{ }
|
||||
|
||||
AutoPtr(Pointer* x)
|
||||
: Base(x)
|
||||
{ }
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return !Base::null();
|
||||
}
|
||||
|
||||
bool operator !() const
|
||||
{
|
||||
return Base::null();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Trinity
|
||||
|
||||
#endif
|
||||
@@ -1,93 +0,0 @@
|
||||
# Copyright (C)
|
||||
#
|
||||
# This file is free software; as a special exception the author gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
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_Packets Packets/*.cpp Packets/*.h)
|
||||
file(GLOB_RECURSE sources_Threading Threading/*.cpp Threading/*.h)
|
||||
file(GLOB_RECURSE sources_Utilities Utilities/*.cpp Utilities/*.h)
|
||||
|
||||
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
|
||||
#
|
||||
|
||||
if (USE_COREPCH)
|
||||
set(shared_STAT_PCH_HDR PrecompiledHeaders/sharedPCH.h)
|
||||
set(shared_STAT_PCH_SRC PrecompiledHeaders/sharedPCH.cpp)
|
||||
endif()
|
||||
|
||||
set(shared_STAT_SRCS
|
||||
${shared_STAT_SRCS}
|
||||
${sources_Configuration}
|
||||
${sources_Cryptography}
|
||||
${sources_Database}
|
||||
${sources_DataStores}
|
||||
${sources_Debugging}
|
||||
${sources_Dynamic}
|
||||
${sources_Logging}
|
||||
${sources_Packets}
|
||||
${sources_Threading}
|
||||
${sources_Utilities}
|
||||
${sources_localdir}
|
||||
Debugging/Errors.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}/modules/dep/recastnavigation/Detour
|
||||
${CMAKE_SOURCE_DIR}/modules/dep/SFMT
|
||||
${CMAKE_SOURCE_DIR}/modules/dep/sockets/include
|
||||
${CMAKE_SOURCE_DIR}/modules/dep/utf8cpp
|
||||
${CMAKE_SOURCE_DIR}/src/server
|
||||
${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}/Packets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Threading
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Utilities
|
||||
${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object
|
||||
${ACE_INCLUDE_DIR}
|
||||
${MYSQL_INCLUDE_DIR}
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
add_library(shared STATIC
|
||||
${shared_STAT_SRCS}
|
||||
${shared_STAT_PCH_SRC}
|
||||
)
|
||||
|
||||
target_link_libraries(shared
|
||||
${ACE_LIBRARY}
|
||||
)
|
||||
|
||||
# Generate precompiled header
|
||||
if (USE_COREPCH)
|
||||
add_cxx_pch(shared ${shared_STAT_PCH_HDR} ${shared_STAT_PCH_SRC})
|
||||
endif ()
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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
|
||||
}
|
||||
|
||||
void CleanStringForMysqlQuery(std::string& str)
|
||||
{
|
||||
std::string::size_type n = 0;
|
||||
while ((n=str.find('\\')) != str.npos) str.erase(n,1);
|
||||
while ((n=str.find('"')) != str.npos) str.erase(n,1);
|
||||
while ((n=str.find('\'')) != str.npos) str.erase(n,1);
|
||||
}
|
||||
|
||||
@@ -1,226 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 AZEROTHCORE_COMMON_H
|
||||
#define AZEROTHCORE_COMMON_H
|
||||
|
||||
// config.h needs to be included 1st
|
||||
/// @todo this thingy looks like hack, but its not, need to
|
||||
// make separate header however, because It makes mess here.
|
||||
#ifdef HAVE_CONFIG_H
|
||||
// Remove Some things that we will define
|
||||
// This is in case including another config.h
|
||||
// before trinity config.h
|
||||
#ifdef PACKAGE
|
||||
#undef PACKAGE
|
||||
#endif //PACKAGE
|
||||
#ifdef PACKAGE_BUGREPORT
|
||||
#undef PACKAGE_BUGREPORT
|
||||
#endif //PACKAGE_BUGREPORT
|
||||
#ifdef PACKAGE_NAME
|
||||
#undef PACKAGE_NAME
|
||||
#endif //PACKAGE_NAME
|
||||
#ifdef PACKAGE_STRING
|
||||
#undef PACKAGE_STRING
|
||||
#endif //PACKAGE_STRING
|
||||
#ifdef PACKAGE_TARNAME
|
||||
#undef PACKAGE_TARNAME
|
||||
#endif //PACKAGE_TARNAME
|
||||
#ifdef PACKAGE_VERSION
|
||||
#undef PACKAGE_VERSION
|
||||
#endif //PACKAGE_VERSION
|
||||
#ifdef VERSION
|
||||
#undef VERSION
|
||||
#endif //VERSION
|
||||
|
||||
# include "Config.h"
|
||||
|
||||
#undef PACKAGE
|
||||
#undef PACKAGE_BUGREPORT
|
||||
#undef PACKAGE_NAME
|
||||
#undef PACKAGE_STRING
|
||||
#undef PACKAGE_TARNAME
|
||||
#undef PACKAGE_VERSION
|
||||
#undef VERSION
|
||||
#endif //HAVE_CONFIG_H
|
||||
|
||||
#include "Define.h"
|
||||
|
||||
#include "Dynamic/UnorderedMap.h"
|
||||
#include "Dynamic/UnorderedSet.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
#define STRCASECMP stricmp
|
||||
#else
|
||||
#define STRCASECMP strcasecmp
|
||||
#endif
|
||||
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "Threading/LockedQueue.h"
|
||||
#include "Threading/Threading.h"
|
||||
|
||||
#include <ace/Basic_Types.h>
|
||||
#include <ace/Guard_T.h>
|
||||
#include <ace/RW_Thread_Mutex.h>
|
||||
#include <ace/Thread_Mutex.h>
|
||||
#include <ace/OS_NS_time.h>
|
||||
#include <ace/Stack_Trace.h>
|
||||
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
# include <ace/config-all.h>
|
||||
// XP winver - needed to compile with standard leak check in MemoryLeaks.h
|
||||
// uncomment later if needed
|
||||
//#define _WIN32_WINNT 0x0501
|
||||
# include <ws2tcpip.h>
|
||||
//#undef WIN32_WINNT
|
||||
#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 I32FMT "%08I32X"
|
||||
#define I64FMT "%016I64X"
|
||||
#define snprintf _snprintf
|
||||
#define atoll _atoi64
|
||||
#define vsnprintf _vsnprintf
|
||||
#define finite(X) _finite(X)
|
||||
#define llabs _abs64
|
||||
|
||||
#else
|
||||
|
||||
#define stricmp strcasecmp
|
||||
#define strnicmp strncasecmp
|
||||
#define I32FMT "%08X"
|
||||
#define I64FMT "%016llX"
|
||||
|
||||
#endif
|
||||
|
||||
inline float finiteAlways(float f) { return finite(f) ? f : 0.0f; }
|
||||
|
||||
#if COMPILER == COMPILER_MICROSOFT
|
||||
inline bool myisfinite(float f) { return _finite(f) && !_isnan(f); }
|
||||
#else
|
||||
inline bool myisfinite(float f) { return finite(f) && !std::isnan(f); }
|
||||
#endif
|
||||
|
||||
#define atol(a) strtoul( a, NULL, 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);
|
||||
void CleanStringForMysqlQuery(std::string& str);
|
||||
|
||||
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.14159265358979323846f
|
||||
#endif
|
||||
|
||||
#define MAX_QUERY_LEN 32*1024
|
||||
|
||||
#define TRINITY_GUARD(MUTEX, LOCK) \
|
||||
ACE_Guard< MUTEX > TRINITY_GUARD_OBJECT (LOCK); \
|
||||
if (TRINITY_GUARD_OBJECT.locked() == 0) ASSERT(false);
|
||||
|
||||
//! For proper implementation of multiple-read, single-write pattern, use
|
||||
//! ACE_RW_Mutex as underlying @MUTEX
|
||||
# define TRINITY_WRITE_GUARD(MUTEX, LOCK) \
|
||||
ACE_Write_Guard< MUTEX > TRINITY_GUARD_OBJECT (LOCK); \
|
||||
if (TRINITY_GUARD_OBJECT.locked() == 0) ASSERT(false);
|
||||
|
||||
//! For proper implementation of multiple-read, single-write pattern, use
|
||||
//! ACE_RW_Mutex as underlying @MUTEX
|
||||
# define TRINITY_READ_GUARD(MUTEX, LOCK) \
|
||||
ACE_Read_Guard< MUTEX > TRINITY_GUARD_OBJECT (LOCK); \
|
||||
if (TRINITY_GUARD_OBJECT.locked() == 0) ASSERT(false);
|
||||
|
||||
#endif
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus == 201103L
|
||||
# define COMPILER_HAS_CPP11_SUPPORT 1
|
||||
#elif _MSC_VER >= 1700
|
||||
# define COMPILER_HAS_CPP11_SUPPORT 1
|
||||
#else
|
||||
# define COMPILER_HAS_CPP11_SUPPORT 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "Config.h"
|
||||
#include "Errors.h"
|
||||
|
||||
// Defined here as it must not be exposed to end-users.
|
||||
bool ConfigMgr::GetValueHelper(const char* name, ACE_TString &result)
|
||||
{
|
||||
GuardType guard(_configLock);
|
||||
|
||||
if (_config.get() == 0)
|
||||
return false;
|
||||
|
||||
ACE_TString section_name;
|
||||
ACE_Configuration_Section_Key section_key;
|
||||
const ACE_Configuration_Section_Key &root_key = _config->root_section();
|
||||
|
||||
int i = 0;
|
||||
while (_config->enumerate_sections(root_key, i, section_name) == 0)
|
||||
{
|
||||
_config->open_section(root_key, section_name.c_str(), 0, section_key);
|
||||
if (_config->get_string_value(section_key, name, result) == 0)
|
||||
return true;
|
||||
++i;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConfigMgr::LoadInitial(char const* file)
|
||||
{
|
||||
ASSERT(file);
|
||||
|
||||
GuardType guard(_configLock);
|
||||
|
||||
_config.reset(new ACE_Configuration_Heap());
|
||||
if (_config->open() == 0)
|
||||
if (LoadData(file))
|
||||
return true;
|
||||
|
||||
_config.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConfigMgr::LoadMore(char const* file)
|
||||
{
|
||||
ASSERT(file);
|
||||
ASSERT(_config);
|
||||
|
||||
GuardType guard(_configLock);
|
||||
|
||||
return LoadData(file);
|
||||
}
|
||||
|
||||
bool ConfigMgr::Reload()
|
||||
{
|
||||
for(std::vector<std::string>::iterator it = _confFiles.begin(); it != _confFiles.end(); ++it) {
|
||||
if (it==_confFiles.begin()) {
|
||||
if (!LoadInitial((*it).c_str()))
|
||||
return false;
|
||||
} else {
|
||||
if (!LoadMore((*it).c_str()))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConfigMgr::LoadData(char const* file)
|
||||
{
|
||||
if(std::find(_confFiles.begin(), _confFiles.end(), file) == _confFiles.end()) {
|
||||
_confFiles.push_back(file);
|
||||
}
|
||||
|
||||
ACE_Ini_ImpExp config_importer(*_config.get());
|
||||
if (config_importer.import_config(file) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string ConfigMgr::GetStringDefault(const char* name, const std::string &def)
|
||||
{
|
||||
ACE_TString val;
|
||||
return GetValueHelper(name, val) ? val.c_str() : def;
|
||||
}
|
||||
|
||||
bool ConfigMgr::GetBoolDefault(const char* name, bool def)
|
||||
{
|
||||
ACE_TString val;
|
||||
|
||||
if (!GetValueHelper(name, val))
|
||||
return def;
|
||||
|
||||
return (val == "true" || val == "TRUE" || val == "yes" || val == "YES" ||
|
||||
val == "1");
|
||||
}
|
||||
|
||||
int ConfigMgr::GetIntDefault(const char* name, int def)
|
||||
{
|
||||
ACE_TString val;
|
||||
return GetValueHelper(name, val) ? atoi(val.c_str()) : def;
|
||||
}
|
||||
|
||||
float ConfigMgr::GetFloatDefault(const char* name, float def)
|
||||
{
|
||||
ACE_TString val;
|
||||
return GetValueHelper(name, val) ? (float)atof(val.c_str()) : def;
|
||||
}
|
||||
|
||||
std::list<std::string> ConfigMgr::GetKeysByString(std::string const& name)
|
||||
{
|
||||
GuardType guard(_configLock);
|
||||
|
||||
std::list<std::string> keys;
|
||||
if (_config.get() == 0)
|
||||
return keys;
|
||||
|
||||
ACE_TString section_name;
|
||||
ACE_Configuration_Section_Key section_key;
|
||||
const ACE_Configuration_Section_Key &root_key = _config->root_section();
|
||||
|
||||
int i = 0;
|
||||
while (_config->enumerate_sections(root_key, i++, section_name) == 0)
|
||||
{
|
||||
_config->open_section(root_key, section_name.c_str(), 0, section_key);
|
||||
|
||||
ACE_TString key_name;
|
||||
ACE_Configuration::VALUETYPE type;
|
||||
int j = 0;
|
||||
while (_config->enumerate_values(section_key, j++, key_name, type) == 0)
|
||||
{
|
||||
std::string temp = key_name.c_str();
|
||||
|
||||
if (!temp.find(name))
|
||||
keys.push_back(temp);
|
||||
}
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 <vector>
|
||||
#include <ace/Singleton.h>
|
||||
#include <ace/Configuration_Import_Export.h>
|
||||
#include <ace/Thread_Mutex.h>
|
||||
#include <AutoPtr.h>
|
||||
|
||||
typedef Trinity::AutoPtr<ACE_Configuration_Heap, ACE_Null_Mutex> Config;
|
||||
|
||||
class ConfigMgr
|
||||
{
|
||||
friend class ACE_Singleton<ConfigMgr, ACE_Null_Mutex>;
|
||||
friend class ConfigLoader;
|
||||
|
||||
ConfigMgr() { }
|
||||
~ConfigMgr() { }
|
||||
|
||||
public:
|
||||
/// Method used only for loading main configuration files (authserver.conf and worldserver.conf)
|
||||
bool LoadInitial(char const* file);
|
||||
|
||||
/**
|
||||
* This method loads additional configuration files
|
||||
* It is recommended to use this method in WorldScript::OnConfigLoad hooks
|
||||
*
|
||||
* @return true if loading was successful
|
||||
*/
|
||||
bool LoadMore(char const* file);
|
||||
|
||||
bool Reload();
|
||||
|
||||
std::string GetStringDefault(const char* name, const std::string& def);
|
||||
bool GetBoolDefault(const char* name, bool def);
|
||||
int GetIntDefault(const char* name, int def);
|
||||
float GetFloatDefault(const char* name, float def);
|
||||
|
||||
std::list<std::string> GetKeysByString(std::string const& name);
|
||||
|
||||
private:
|
||||
bool GetValueHelper(const char* name, ACE_TString &result);
|
||||
bool LoadData(char const* file);
|
||||
|
||||
typedef ACE_Thread_Mutex LockType;
|
||||
typedef ACE_Guard<LockType> GuardType;
|
||||
|
||||
std::vector<std::string> _confFiles;
|
||||
Config _config;
|
||||
LockType _configLock;
|
||||
|
||||
ConfigMgr(ConfigMgr const&);
|
||||
ConfigMgr& operator=(ConfigMgr const&);
|
||||
};
|
||||
|
||||
#define sConfigMgr ACE_Singleton<ConfigMgr, ACE_Null_Mutex>::instance()
|
||||
|
||||
#endif
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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_CONTAINERS_H
|
||||
#define TRINITY_CONTAINERS_H
|
||||
|
||||
#include "Define.h"
|
||||
#include <list>
|
||||
|
||||
//! Because circular includes are bad
|
||||
extern uint32 urand(uint32 min, uint32 max);
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
namespace Containers
|
||||
{
|
||||
template<class T>
|
||||
void RandomResizeList(std::list<T> &list, uint32 size)
|
||||
{
|
||||
size_t list_size = list.size();
|
||||
|
||||
while (list_size > size)
|
||||
{
|
||||
typename std::list<T>::iterator itr = list.begin();
|
||||
std::advance(itr, urand(0, list_size - 1));
|
||||
list.erase(itr);
|
||||
--list_size;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class Predicate>
|
||||
void RandomResizeList(std::list<T> &list, Predicate& predicate, uint32 size)
|
||||
{
|
||||
//! First use predicate filter
|
||||
std::list<T> listCopy;
|
||||
for (typename std::list<T>::iterator itr = list.begin(); itr != list.end(); ++itr)
|
||||
if (predicate(*itr))
|
||||
listCopy.push_back(*itr);
|
||||
|
||||
if (size)
|
||||
RandomResizeList(listCopy, size);
|
||||
|
||||
list = listCopy;
|
||||
}
|
||||
|
||||
/* Select a random element from a container. Note: make sure you explicitly empty check the container */
|
||||
template <class C> typename C::value_type const& SelectRandomContainerElement(C const& container)
|
||||
{
|
||||
typename C::const_iterator it = container.begin();
|
||||
std::advance(it, urand(0, container.size() - 1));
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
//! namespace Containers
|
||||
}
|
||||
//! namespace Trinity
|
||||
|
||||
#endif //! #ifdef TRINITY_CONTAINERS_H
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "ARC4.h"
|
||||
#include <openssl/sha.h>
|
||||
|
||||
ARC4::ARC4(uint8 len) : m_ctx()
|
||||
{
|
||||
EVP_CIPHER_CTX_init(&m_ctx);
|
||||
EVP_EncryptInit_ex(&m_ctx, EVP_rc4(), NULL, NULL, NULL);
|
||||
EVP_CIPHER_CTX_set_key_length(&m_ctx, len);
|
||||
}
|
||||
|
||||
ARC4::ARC4(uint8 *seed, uint8 len) : m_ctx()
|
||||
{
|
||||
EVP_CIPHER_CTX_init(&m_ctx);
|
||||
EVP_EncryptInit_ex(&m_ctx, EVP_rc4(), NULL, NULL, NULL);
|
||||
EVP_CIPHER_CTX_set_key_length(&m_ctx, len);
|
||||
EVP_EncryptInit_ex(&m_ctx, NULL, NULL, seed, NULL);
|
||||
}
|
||||
|
||||
ARC4::~ARC4()
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup(&m_ctx);
|
||||
}
|
||||
|
||||
void ARC4::Init(uint8 *seed)
|
||||
{
|
||||
EVP_EncryptInit_ex(&m_ctx, NULL, NULL, seed, NULL);
|
||||
}
|
||||
|
||||
void ARC4::UpdateData(int len, uint8 *data)
|
||||
{
|
||||
int outlen = 0;
|
||||
EVP_EncryptUpdate(&m_ctx, data, &outlen, data, len);
|
||||
EVP_EncryptFinal_ex(&m_ctx, data, &outlen);
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 _AUTH_SARC4_H
|
||||
#define _AUTH_SARC4_H
|
||||
|
||||
#include "Define.h"
|
||||
#include <openssl/evp.h>
|
||||
|
||||
class ARC4
|
||||
{
|
||||
public:
|
||||
ARC4(uint8 len);
|
||||
ARC4(uint8 *seed, uint8 len);
|
||||
~ARC4();
|
||||
void Init(uint8 *seed);
|
||||
void UpdateData(int len, uint8 *data);
|
||||
private:
|
||||
EVP_CIPHER_CTX m_ctx;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "AuthCrypt.h"
|
||||
#include "Cryptography/HMACSHA1.h"
|
||||
#include "Cryptography/BigNumber.h"
|
||||
|
||||
AuthCrypt::AuthCrypt() :
|
||||
_clientDecrypt(SHA_DIGEST_LENGTH), _serverEncrypt(SHA_DIGEST_LENGTH),
|
||||
_initialized(false)
|
||||
{ }
|
||||
|
||||
void AuthCrypt::Init(BigNumber* K)
|
||||
{
|
||||
uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0xCC, 0x98, 0xAE, 0x04, 0xE8, 0x97, 0xEA, 0xCA, 0x12, 0xDD, 0xC0, 0x93, 0x42, 0x91, 0x53, 0x57 };
|
||||
HmacHash serverEncryptHmac(SEED_KEY_SIZE, (uint8*)ServerEncryptionKey);
|
||||
uint8 *encryptHash = serverEncryptHmac.ComputeHash(K);
|
||||
|
||||
uint8 ServerDecryptionKey[SEED_KEY_SIZE] = { 0xC2, 0xB3, 0x72, 0x3C, 0xC6, 0xAE, 0xD9, 0xB5, 0x34, 0x3C, 0x53, 0xEE, 0x2F, 0x43, 0x67, 0xCE };
|
||||
HmacHash clientDecryptHmac(SEED_KEY_SIZE, (uint8*)ServerDecryptionKey);
|
||||
uint8 *decryptHash = clientDecryptHmac.ComputeHash(K);
|
||||
|
||||
//ARC4 _serverDecrypt(encryptHash);
|
||||
_clientDecrypt.Init(decryptHash);
|
||||
_serverEncrypt.Init(encryptHash);
|
||||
//ARC4 _clientEncrypt(decryptHash);
|
||||
|
||||
// Drop first 1024 bytes, as WoW uses ARC4-drop1024.
|
||||
uint8 syncBuf[1024];
|
||||
memset(syncBuf, 0, 1024);
|
||||
|
||||
_serverEncrypt.UpdateData(1024, syncBuf);
|
||||
//_clientEncrypt.UpdateData(1024, syncBuf);
|
||||
|
||||
memset(syncBuf, 0, 1024);
|
||||
|
||||
//_serverDecrypt.UpdateData(1024, syncBuf);
|
||||
_clientDecrypt.UpdateData(1024, syncBuf);
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
void AuthCrypt::DecryptRecv(uint8 *data, size_t len)
|
||||
{
|
||||
if (!_initialized)
|
||||
return;
|
||||
|
||||
_clientDecrypt.UpdateData(len, data);
|
||||
}
|
||||
|
||||
void AuthCrypt::EncryptSend(uint8 *data, size_t len)
|
||||
{
|
||||
if (!_initialized)
|
||||
return;
|
||||
|
||||
_serverEncrypt.UpdateData(len, data);
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 _AUTHCRYPT_H
|
||||
#define _AUTHCRYPT_H
|
||||
|
||||
#include "Cryptography/ARC4.h"
|
||||
|
||||
class BigNumber;
|
||||
|
||||
class AuthCrypt
|
||||
{
|
||||
public:
|
||||
AuthCrypt();
|
||||
|
||||
void Init(BigNumber* K);
|
||||
void DecryptRecv(uint8 *, size_t);
|
||||
void EncryptSend(uint8 *, size_t);
|
||||
|
||||
bool IsInitialized() const { return _initialized; }
|
||||
|
||||
private:
|
||||
ARC4 _clientDecrypt;
|
||||
ARC4 _serverEncrypt;
|
||||
bool _initialized;
|
||||
};
|
||||
#endif
|
||||
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 <ace/Guard_T.h>
|
||||
|
||||
#include "Cryptography/BigNumber.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <algorithm>
|
||||
#include <ace/Auto_Ptr.h>
|
||||
|
||||
BigNumber::BigNumber()
|
||||
: _bn(BN_new())
|
||||
{ }
|
||||
|
||||
BigNumber::BigNumber(BigNumber const& bn)
|
||||
: _bn(BN_dup(bn._bn))
|
||||
{ }
|
||||
|
||||
BigNumber::BigNumber(uint32 val)
|
||||
: _bn(BN_new())
|
||||
{
|
||||
BN_set_word(_bn, val);
|
||||
}
|
||||
|
||||
BigNumber::~BigNumber()
|
||||
{
|
||||
BN_free(_bn);
|
||||
}
|
||||
|
||||
void BigNumber::SetDword(uint32 val)
|
||||
{
|
||||
BN_set_word(_bn, val);
|
||||
}
|
||||
|
||||
void BigNumber::SetQword(uint64 val)
|
||||
{
|
||||
BN_set_word(_bn, (uint32)(val >> 32));
|
||||
BN_lshift(_bn, _bn, 32);
|
||||
BN_add_word(_bn, (uint32)(val & 0xFFFFFFFF));
|
||||
}
|
||||
|
||||
void BigNumber::SetBinary(uint8 const* bytes, int32 len)
|
||||
{
|
||||
uint8* array = new uint8[len];
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
array[i] = bytes[len - 1 - i];
|
||||
|
||||
BN_bin2bn(array, len, _bn);
|
||||
|
||||
delete[] array;
|
||||
}
|
||||
|
||||
void BigNumber::SetHexStr(char const* str)
|
||||
{
|
||||
BN_hex2bn(&_bn, str);
|
||||
}
|
||||
|
||||
void BigNumber::SetRand(int32 numbits)
|
||||
{
|
||||
BN_rand(_bn, numbits, 0, 1);
|
||||
}
|
||||
|
||||
BigNumber& BigNumber::operator=(BigNumber const& bn)
|
||||
{
|
||||
if (this == &bn)
|
||||
return *this;
|
||||
|
||||
BN_copy(_bn, bn._bn);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigNumber BigNumber::operator+=(BigNumber const& bn)
|
||||
{
|
||||
BN_add(_bn, _bn, bn._bn);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigNumber BigNumber::operator-=(BigNumber const& bn)
|
||||
{
|
||||
BN_sub(_bn, _bn, bn._bn);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigNumber BigNumber::operator*=(BigNumber const& bn)
|
||||
{
|
||||
BN_CTX *bnctx;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_mul(_bn, _bn, bn._bn, bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigNumber BigNumber::operator/=(BigNumber const& bn)
|
||||
{
|
||||
BN_CTX *bnctx;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_div(_bn, NULL, _bn, bn._bn, bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigNumber BigNumber::operator%=(BigNumber const& bn)
|
||||
{
|
||||
BN_CTX *bnctx;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_mod(_bn, _bn, bn._bn, bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigNumber BigNumber::Exp(BigNumber const& bn)
|
||||
{
|
||||
BigNumber ret;
|
||||
BN_CTX *bnctx;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_exp(ret._bn, _bn, bn._bn, bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BigNumber BigNumber::ModExp(BigNumber const& bn1, BigNumber const& bn2)
|
||||
{
|
||||
BigNumber ret;
|
||||
BN_CTX *bnctx;
|
||||
|
||||
bnctx = BN_CTX_new();
|
||||
BN_mod_exp(ret._bn, _bn, bn1._bn, bn2._bn, bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32 BigNumber::GetNumBytes(void)
|
||||
{
|
||||
return BN_num_bytes(_bn);
|
||||
}
|
||||
|
||||
uint32 BigNumber::AsDword()
|
||||
{
|
||||
return (uint32)BN_get_word(_bn);
|
||||
}
|
||||
|
||||
bool BigNumber::isZero() const
|
||||
{
|
||||
return BN_is_zero(_bn);
|
||||
}
|
||||
|
||||
ACE_Auto_Array_Ptr<uint8> BigNumber::AsByteArray(int32 minSize, bool littleEndian)
|
||||
{
|
||||
int length = (minSize >= GetNumBytes()) ? minSize : GetNumBytes();
|
||||
|
||||
uint8* array = new uint8[length];
|
||||
|
||||
// If we need more bytes than length of BigNumber set the rest to 0
|
||||
if (length > GetNumBytes())
|
||||
memset((void*)array, 0, length);
|
||||
|
||||
BN_bn2bin(_bn, (unsigned char *)array);
|
||||
|
||||
// openssl's BN stores data internally in big endian format, reverse if little endian desired
|
||||
if (littleEndian)
|
||||
std::reverse(array, array + length);
|
||||
|
||||
ACE_Auto_Array_Ptr<uint8> ret(array);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char * BigNumber::AsHexStr() const
|
||||
{
|
||||
return BN_bn2hex(_bn);
|
||||
}
|
||||
|
||||
char * BigNumber::AsDecStr() const
|
||||
{
|
||||
return BN_bn2dec(_bn);
|
||||
}
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 _AUTH_BIGNUMBER_H
|
||||
#define _AUTH_BIGNUMBER_H
|
||||
|
||||
#include "Define.h"
|
||||
#include <ace/Auto_Ptr.h>
|
||||
|
||||
struct bignum_st;
|
||||
|
||||
class BigNumber
|
||||
{
|
||||
public:
|
||||
BigNumber();
|
||||
BigNumber(BigNumber const& bn);
|
||||
BigNumber(uint32);
|
||||
~BigNumber();
|
||||
|
||||
void SetDword(uint32);
|
||||
void SetQword(uint64);
|
||||
void SetBinary(uint8 const* bytes, int32 len);
|
||||
void SetHexStr(char const* str);
|
||||
|
||||
void SetRand(int32 numbits);
|
||||
|
||||
BigNumber& operator=(BigNumber const& bn);
|
||||
|
||||
BigNumber operator+=(BigNumber const& bn);
|
||||
BigNumber operator+(BigNumber const& bn)
|
||||
{
|
||||
BigNumber t(*this);
|
||||
return t += bn;
|
||||
}
|
||||
|
||||
BigNumber operator-=(BigNumber const& bn);
|
||||
BigNumber operator-(BigNumber const& bn)
|
||||
{
|
||||
BigNumber t(*this);
|
||||
return t -= bn;
|
||||
}
|
||||
|
||||
BigNumber operator*=(BigNumber const& bn);
|
||||
BigNumber operator*(BigNumber const& bn)
|
||||
{
|
||||
BigNumber t(*this);
|
||||
return t *= bn;
|
||||
}
|
||||
|
||||
BigNumber operator/=(BigNumber const& bn);
|
||||
BigNumber operator/(BigNumber const& bn)
|
||||
{
|
||||
BigNumber t(*this);
|
||||
return t /= bn;
|
||||
}
|
||||
|
||||
BigNumber operator%=(BigNumber const& bn);
|
||||
BigNumber operator%(BigNumber const& bn)
|
||||
{
|
||||
BigNumber t(*this);
|
||||
return t %= bn;
|
||||
}
|
||||
|
||||
bool isZero() const;
|
||||
|
||||
BigNumber ModExp(BigNumber const& bn1, BigNumber const& bn2);
|
||||
BigNumber Exp(BigNumber const&);
|
||||
|
||||
int32 GetNumBytes(void);
|
||||
|
||||
struct bignum_st *BN() { return _bn; }
|
||||
|
||||
uint32 AsDword();
|
||||
|
||||
ACE_Auto_Array_Ptr<uint8> AsByteArray(int32 minSize = 0, bool littleEndian = true);
|
||||
|
||||
char * AsHexStr() const;
|
||||
char * AsDecStr() const;
|
||||
|
||||
private:
|
||||
struct bignum_st *_bn;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "HMACSHA1.h"
|
||||
#include "BigNumber.h"
|
||||
#include "Common.h"
|
||||
|
||||
HmacHash::HmacHash(uint32 len, uint8 *seed)
|
||||
{
|
||||
HMAC_CTX_init(&m_ctx);
|
||||
HMAC_Init_ex(&m_ctx, seed, len, EVP_sha1(), NULL);
|
||||
memset(m_digest, 0, sizeof(m_digest));
|
||||
}
|
||||
|
||||
HmacHash::~HmacHash()
|
||||
{
|
||||
HMAC_CTX_cleanup(&m_ctx);
|
||||
}
|
||||
|
||||
void HmacHash::UpdateData(const std::string &str)
|
||||
{
|
||||
HMAC_Update(&m_ctx, (uint8 const*)str.c_str(), str.length());
|
||||
}
|
||||
|
||||
void HmacHash::UpdateData(const uint8* data, size_t len)
|
||||
{
|
||||
HMAC_Update(&m_ctx, data, len);
|
||||
}
|
||||
|
||||
void HmacHash::Finalize()
|
||||
{
|
||||
uint32 length = 0;
|
||||
HMAC_Final(&m_ctx, (uint8*)m_digest, &length);
|
||||
ASSERT(length == SHA_DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
uint8 *HmacHash::ComputeHash(BigNumber* bn)
|
||||
{
|
||||
HMAC_Update(&m_ctx, bn->AsByteArray().get(), bn->GetNumBytes());
|
||||
Finalize();
|
||||
return (uint8*)m_digest;
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 _AUTH_HMAC_H
|
||||
#define _AUTH_HMAC_H
|
||||
|
||||
#include "Define.h"
|
||||
#include <string>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
class BigNumber;
|
||||
|
||||
#define SEED_KEY_SIZE 16
|
||||
|
||||
class HmacHash
|
||||
{
|
||||
public:
|
||||
HmacHash(uint32 len, uint8 *seed);
|
||||
~HmacHash();
|
||||
void UpdateData(const std::string &str);
|
||||
void UpdateData(const uint8* data, size_t len);
|
||||
void Finalize();
|
||||
uint8 *ComputeHash(BigNumber* bn);
|
||||
uint8 *GetDigest() { return (uint8*)m_digest; }
|
||||
int GetLength() const { return SHA_DIGEST_LENGTH; }
|
||||
private:
|
||||
HMAC_CTX m_ctx;
|
||||
uint8 m_digest[SHA_DIGEST_LENGTH];
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 <OpenSSLCrypto.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <ace/Thread_Mutex.h>
|
||||
#include <vector>
|
||||
#include <ace/Thread.h>
|
||||
|
||||
std::vector<ACE_Thread_Mutex*> cryptoLocks;
|
||||
|
||||
static void lockingCallback(int mode, int type, const char* /*file*/, int /*line*/)
|
||||
{
|
||||
if (mode & CRYPTO_LOCK)
|
||||
cryptoLocks[type]->acquire();
|
||||
else
|
||||
cryptoLocks[type]->release();
|
||||
}
|
||||
|
||||
static void threadIdCallback(CRYPTO_THREADID * id)
|
||||
{
|
||||
/// ACE_thread_t turns out to be a struct under Mac OS.
|
||||
#ifndef __APPLE__
|
||||
CRYPTO_THREADID_set_numeric(id, ACE_Thread::self());
|
||||
#else
|
||||
CRYPTO_THREADID_set_pointer(id, ACE_Thread::self());
|
||||
#endif
|
||||
}
|
||||
|
||||
void OpenSSLCrypto::threadsSetup()
|
||||
{
|
||||
cryptoLocks.resize(CRYPTO_num_locks());
|
||||
for(int i = 0 ; i < CRYPTO_num_locks(); ++i)
|
||||
{
|
||||
cryptoLocks[i] = new ACE_Thread_Mutex();
|
||||
}
|
||||
CRYPTO_THREADID_set_callback(threadIdCallback);
|
||||
CRYPTO_set_locking_callback(lockingCallback);
|
||||
}
|
||||
|
||||
void OpenSSLCrypto::threadsCleanup()
|
||||
{
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
CRYPTO_THREADID_set_callback(NULL);
|
||||
for(int i = 0 ; i < CRYPTO_num_locks(); ++i)
|
||||
{
|
||||
delete cryptoLocks[i];
|
||||
}
|
||||
cryptoLocks.resize(0);
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 OPENSSL_CRYPTO_H
|
||||
#define OPENSSL_CRYPTO_H
|
||||
|
||||
/**
|
||||
* A group of functions which setup openssl crypto module to work properly in multithreaded enviroment
|
||||
* If not setup properly - it will crash
|
||||
*/
|
||||
namespace OpenSSLCrypto
|
||||
{
|
||||
/// Needs to be called before threads using openssl are spawned
|
||||
void threadsSetup();
|
||||
/// Needs to be called after threads using openssl are despawned
|
||||
void threadsCleanup();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "SHA1.h"
|
||||
#include "BigNumber.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
SHA1Hash::SHA1Hash()
|
||||
{
|
||||
SHA1_Init(&mC);
|
||||
memset(mDigest, 0, SHA_DIGEST_LENGTH * sizeof(uint8));
|
||||
}
|
||||
|
||||
SHA1Hash::~SHA1Hash()
|
||||
{
|
||||
SHA1_Init(&mC);
|
||||
}
|
||||
|
||||
void SHA1Hash::UpdateData(const uint8 *dta, int len)
|
||||
{
|
||||
SHA1_Update(&mC, dta, len);
|
||||
}
|
||||
|
||||
void SHA1Hash::UpdateData(const std::string &str)
|
||||
{
|
||||
UpdateData((uint8 const*)str.c_str(), str.length());
|
||||
}
|
||||
|
||||
void SHA1Hash::UpdateBigNumbers(BigNumber* bn0, ...)
|
||||
{
|
||||
va_list v;
|
||||
BigNumber* bn;
|
||||
|
||||
va_start(v, bn0);
|
||||
bn = bn0;
|
||||
while (bn)
|
||||
{
|
||||
UpdateData(bn->AsByteArray().get(), bn->GetNumBytes());
|
||||
bn = va_arg(v, BigNumber*);
|
||||
}
|
||||
va_end(v);
|
||||
}
|
||||
|
||||
void SHA1Hash::Initialize()
|
||||
{
|
||||
SHA1_Init(&mC);
|
||||
}
|
||||
|
||||
void SHA1Hash::Finalize(void)
|
||||
{
|
||||
SHA1_Final(mDigest, &mC);
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 _AUTH_SHA1_H
|
||||
#define _AUTH_SHA1_H
|
||||
|
||||
#include "Define.h"
|
||||
#include <string>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
class BigNumber;
|
||||
|
||||
class SHA1Hash
|
||||
{
|
||||
public:
|
||||
SHA1Hash();
|
||||
~SHA1Hash();
|
||||
|
||||
void UpdateBigNumbers(BigNumber* bn0, ...);
|
||||
|
||||
void UpdateData(const uint8 *dta, int len);
|
||||
void UpdateData(const std::string &str);
|
||||
|
||||
void Initialize();
|
||||
void Finalize();
|
||||
|
||||
uint8 *GetDigest(void) { return mDigest; };
|
||||
int GetLength(void) const { return SHA_DIGEST_LENGTH; };
|
||||
|
||||
private:
|
||||
SHA_CTX mC;
|
||||
uint8 mDigest[SHA_DIGEST_LENGTH];
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "SHA1.h"
|
||||
|
||||
#ifndef _WARDEN_KEY_GENERATION_H
|
||||
#define _WARDEN_KEY_GENERATION_H
|
||||
|
||||
class SHA1Randx
|
||||
{
|
||||
public:
|
||||
SHA1Randx(uint8* buff, uint32 size)
|
||||
{
|
||||
uint32 taken = size/2;
|
||||
|
||||
sh.Initialize();
|
||||
sh.UpdateData(buff, taken);
|
||||
sh.Finalize();
|
||||
|
||||
memcpy(o1, sh.GetDigest(), 20);
|
||||
|
||||
sh.Initialize();
|
||||
sh.UpdateData(buff + taken, size - taken);
|
||||
sh.Finalize();
|
||||
|
||||
memcpy(o2, sh.GetDigest(), 20);
|
||||
|
||||
memset(o0, 0x00, 20);
|
||||
|
||||
FillUp();
|
||||
}
|
||||
|
||||
void Generate(uint8* buf, uint32 sz)
|
||||
{
|
||||
for (uint32 i = 0; i < sz; ++i)
|
||||
{
|
||||
if (taken == 20)
|
||||
FillUp();
|
||||
|
||||
buf[i] = o0[taken];
|
||||
taken++;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void FillUp()
|
||||
{
|
||||
sh.Initialize();
|
||||
sh.UpdateData(o1, 20);
|
||||
sh.UpdateData(o0, 20);
|
||||
sh.UpdateData(o2, 20);
|
||||
sh.Finalize();
|
||||
|
||||
memcpy(o0, sh.GetDigest(), 20);
|
||||
|
||||
taken = 0;
|
||||
}
|
||||
|
||||
SHA1Hash sh;
|
||||
uint32 taken;
|
||||
uint8 o0[20], o1[20], o2[20];
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,324 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "DBCFileLoader.h"
|
||||
#include "Errors.h"
|
||||
|
||||
DBCFileLoader::DBCFileLoader() : recordSize(0), recordCount(0), fieldCount(0), stringSize(0), fieldsOffset(NULL), data(NULL), stringTable(NULL) { }
|
||||
|
||||
bool DBCFileLoader::Load(const char* filename, const char* fmt)
|
||||
{
|
||||
uint32 header;
|
||||
if (data)
|
||||
{
|
||||
delete [] data;
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
FILE* f = fopen(filename, "rb");
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
if (fread(&header, 4, 1, f) != 1) // Number of records
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
EndianConvert(header);
|
||||
|
||||
if (header != 0x43424457) //'WDBC'
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fread(&recordCount, 4, 1, f) != 1) // Number of records
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
EndianConvert(recordCount);
|
||||
|
||||
if (fread(&fieldCount, 4, 1, f) != 1) // Number of fields
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
EndianConvert(fieldCount);
|
||||
|
||||
if (fread(&recordSize, 4, 1, f) != 1) // Size of a record
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
EndianConvert(recordSize);
|
||||
|
||||
if (fread(&stringSize, 4, 1, f) != 1) // String size
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
EndianConvert(stringSize);
|
||||
|
||||
fieldsOffset = new uint32[fieldCount];
|
||||
fieldsOffset[0] = 0;
|
||||
for (uint32 i = 1; i < fieldCount; ++i)
|
||||
{
|
||||
fieldsOffset[i] = fieldsOffset[i - 1];
|
||||
if (fmt[i - 1] == 'b' || fmt[i - 1] == 'X') // byte fields
|
||||
fieldsOffset[i] += sizeof(uint8);
|
||||
else // 4 byte fields (int32/float/strings)
|
||||
fieldsOffset[i] += sizeof(uint32);
|
||||
}
|
||||
|
||||
data = new unsigned char[recordSize * recordCount + stringSize];
|
||||
stringTable = data + recordSize*recordCount;
|
||||
|
||||
if (fread(data, recordSize * recordCount + stringSize, 1, f) != 1)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DBCFileLoader::~DBCFileLoader()
|
||||
{
|
||||
if (data)
|
||||
delete [] data;
|
||||
|
||||
if (fieldsOffset)
|
||||
delete [] fieldsOffset;
|
||||
}
|
||||
|
||||
DBCFileLoader::Record DBCFileLoader::getRecord(size_t id)
|
||||
{
|
||||
assert(data);
|
||||
return Record(*this, data + id * recordSize);
|
||||
}
|
||||
|
||||
uint32 DBCFileLoader::GetFormatRecordSize(const char* format, int32* index_pos)
|
||||
{
|
||||
uint32 recordsize = 0;
|
||||
int32 i = -1;
|
||||
for (uint32 x = 0; format[x]; ++x)
|
||||
{
|
||||
switch (format[x])
|
||||
{
|
||||
case FT_FLOAT:
|
||||
recordsize += sizeof(float);
|
||||
break;
|
||||
case FT_INT:
|
||||
recordsize += sizeof(uint32);
|
||||
break;
|
||||
case FT_STRING:
|
||||
recordsize += sizeof(char*);
|
||||
break;
|
||||
case FT_SORT:
|
||||
i = x;
|
||||
break;
|
||||
case FT_IND:
|
||||
i = x;
|
||||
recordsize += sizeof(uint32);
|
||||
break;
|
||||
case FT_BYTE:
|
||||
recordsize += sizeof(uint8);
|
||||
break;
|
||||
case FT_NA:
|
||||
case FT_NA_BYTE:
|
||||
break;
|
||||
case FT_LOGIC:
|
||||
ASSERT(false && "Attempted to load DBC files that do not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
|
||||
break;
|
||||
default:
|
||||
ASSERT(false && "Unknown field format character in DBCfmt.h");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index_pos)
|
||||
*index_pos = i;
|
||||
|
||||
return recordsize;
|
||||
}
|
||||
|
||||
char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char**& indexTable, uint32 sqlRecordCount, uint32 sqlHighestIndex, char*& sqlDataTable)
|
||||
{
|
||||
/*
|
||||
format STRING, NA, FLOAT, NA, INT <=>
|
||||
struct{
|
||||
char* field0,
|
||||
float field1,
|
||||
int field2
|
||||
}entry;
|
||||
|
||||
this func will generate entry[rows] data;
|
||||
*/
|
||||
|
||||
typedef char* ptr;
|
||||
if (strlen(format) != fieldCount)
|
||||
return NULL;
|
||||
|
||||
//get struct size and index pos
|
||||
int32 i;
|
||||
uint32 recordsize = GetFormatRecordSize(format, &i);
|
||||
|
||||
if (i >= 0)
|
||||
{
|
||||
uint32 maxi = 0;
|
||||
//find max index
|
||||
for (uint32 y = 0; y < recordCount; ++y)
|
||||
{
|
||||
uint32 ind = getRecord(y).getUInt(i);
|
||||
if (ind > maxi)
|
||||
maxi = ind;
|
||||
}
|
||||
|
||||
// If higher index avalible from sql - use it instead of dbcs
|
||||
if (sqlHighestIndex > maxi)
|
||||
maxi = sqlHighestIndex;
|
||||
|
||||
++maxi;
|
||||
records = maxi;
|
||||
indexTable = new ptr[maxi];
|
||||
memset(indexTable, 0, maxi * sizeof(ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
records = recordCount + sqlRecordCount;
|
||||
indexTable = new ptr[recordCount + sqlRecordCount];
|
||||
}
|
||||
|
||||
char* dataTable = new char[(recordCount + sqlRecordCount) * recordsize];
|
||||
|
||||
uint32 offset = 0;
|
||||
|
||||
for (uint32 y = 0; y < recordCount; ++y)
|
||||
{
|
||||
if (i >= 0)
|
||||
indexTable[getRecord(y).getUInt(i)] = &dataTable[offset];
|
||||
else
|
||||
indexTable[y] = &dataTable[offset];
|
||||
|
||||
for (uint32 x=0; x < fieldCount; ++x)
|
||||
{
|
||||
switch (format[x])
|
||||
{
|
||||
case FT_FLOAT:
|
||||
*((float*)(&dataTable[offset])) = getRecord(y).getFloat(x);
|
||||
offset += sizeof(float);
|
||||
break;
|
||||
case FT_IND:
|
||||
case FT_INT:
|
||||
*((uint32*)(&dataTable[offset])) = getRecord(y).getUInt(x);
|
||||
offset += sizeof(uint32);
|
||||
break;
|
||||
case FT_BYTE:
|
||||
*((uint8*)(&dataTable[offset])) = getRecord(y).getUInt8(x);
|
||||
offset += sizeof(uint8);
|
||||
break;
|
||||
case FT_STRING:
|
||||
*((char**)(&dataTable[offset])) = NULL; // will replace non-empty or "" strings in AutoProduceStrings
|
||||
offset += sizeof(char*);
|
||||
break;
|
||||
case FT_LOGIC:
|
||||
ASSERT(false && "Attempted to load DBC files that do not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
|
||||
break;
|
||||
case FT_NA:
|
||||
case FT_NA_BYTE:
|
||||
case FT_SORT:
|
||||
break;
|
||||
default:
|
||||
ASSERT(false && "Unknown field format character in DBCfmt.h");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sqlDataTable = dataTable + offset;
|
||||
|
||||
return dataTable;
|
||||
}
|
||||
|
||||
char* DBCFileLoader::AutoProduceStrings(const char* format, char* dataTable)
|
||||
{
|
||||
if (strlen(format) != fieldCount)
|
||||
return NULL;
|
||||
|
||||
char* stringPool = new char[stringSize];
|
||||
memcpy(stringPool, stringTable, stringSize);
|
||||
|
||||
uint32 offset = 0;
|
||||
|
||||
for (uint32 y = 0; y < recordCount; ++y)
|
||||
{
|
||||
for (uint32 x = 0; x < fieldCount; ++x)
|
||||
{
|
||||
switch (format[x])
|
||||
{
|
||||
case FT_FLOAT:
|
||||
offset += sizeof(float);
|
||||
break;
|
||||
case FT_IND:
|
||||
case FT_INT:
|
||||
offset += sizeof(uint32);
|
||||
break;
|
||||
case FT_BYTE:
|
||||
offset += sizeof(uint8);
|
||||
break;
|
||||
case FT_STRING:
|
||||
{
|
||||
// fill only not filled entries
|
||||
char** slot = (char**)(&dataTable[offset]);
|
||||
if (!*slot || !**slot)
|
||||
{
|
||||
const char * st = getRecord(y).getString(x);
|
||||
*slot=stringPool+(st-(const char*)stringTable);
|
||||
}
|
||||
offset += sizeof(char*);
|
||||
break;
|
||||
}
|
||||
case FT_LOGIC:
|
||||
ASSERT(false && "Attempted to load DBC files that does not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
|
||||
break;
|
||||
case FT_NA:
|
||||
case FT_NA_BYTE:
|
||||
case FT_SORT:
|
||||
break;
|
||||
default:
|
||||
ASSERT(false && "Unknown field format character in DBCfmt.h");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return stringPool;
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 DBC_FILE_LOADER_H
|
||||
#define DBC_FILE_LOADER_H
|
||||
#include "Define.h"
|
||||
#include "Utilities/ByteConverter.h"
|
||||
#include <cassert>
|
||||
|
||||
enum DbcFieldFormat
|
||||
{
|
||||
FT_NA='x', //not used or unknown, 4 byte size
|
||||
FT_NA_BYTE='X', //not used or unknown, byte
|
||||
FT_STRING='s', //char*
|
||||
FT_FLOAT='f', //float
|
||||
FT_INT='i', //uint32
|
||||
FT_BYTE='b', //uint8
|
||||
FT_SORT='d', //sorted by this field, field is not included
|
||||
FT_IND='n', //the same, but parsed to data
|
||||
FT_LOGIC='l', //Logical (boolean)
|
||||
FT_SQL_PRESENT='p', //Used in sql format to mark column present in sql dbc
|
||||
FT_SQL_ABSENT='a' //Used in sql format to mark column absent in sql dbc
|
||||
};
|
||||
|
||||
class DBCFileLoader
|
||||
{
|
||||
public:
|
||||
DBCFileLoader();
|
||||
~DBCFileLoader();
|
||||
|
||||
bool Load(const char *filename, const char *fmt);
|
||||
|
||||
class Record
|
||||
{
|
||||
public:
|
||||
float getFloat(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
float val = *reinterpret_cast<float*>(offset+file.GetOffset(field));
|
||||
EndianConvert(val);
|
||||
return val;
|
||||
}
|
||||
uint32 getUInt(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
uint32 val = *reinterpret_cast<uint32*>(offset+file.GetOffset(field));
|
||||
EndianConvert(val);
|
||||
return val;
|
||||
}
|
||||
uint8 getUInt8(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
return *reinterpret_cast<uint8*>(offset+file.GetOffset(field));
|
||||
}
|
||||
|
||||
const char *getString(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
size_t stringOffset = getUInt(field);
|
||||
assert(stringOffset < file.stringSize);
|
||||
return reinterpret_cast<char*>(file.stringTable + stringOffset);
|
||||
}
|
||||
|
||||
private:
|
||||
Record(DBCFileLoader &file_, unsigned char *offset_): offset(offset_), file(file_) { }
|
||||
unsigned char *offset;
|
||||
DBCFileLoader &file;
|
||||
|
||||
friend class DBCFileLoader;
|
||||
|
||||
};
|
||||
|
||||
// Get record by id
|
||||
Record getRecord(size_t id);
|
||||
/// Get begin iterator over records
|
||||
|
||||
uint32 GetNumRows() const { return recordCount; }
|
||||
uint32 GetRowSize() const { return recordSize; }
|
||||
uint32 GetCols() const { return fieldCount; }
|
||||
uint32 GetOffset(size_t id) const { return (fieldsOffset != NULL && id < fieldCount) ? fieldsOffset[id] : 0; }
|
||||
bool IsLoaded() const { return data != NULL; }
|
||||
char* AutoProduceData(const char* fmt, uint32& count, char**& indexTable, uint32 sqlRecordCount, uint32 sqlHighestIndex, char *& sqlDataTable);
|
||||
char* AutoProduceStrings(const char* fmt, char* dataTable);
|
||||
static uint32 GetFormatRecordSize(const char * format, int32 * index_pos = NULL);
|
||||
private:
|
||||
|
||||
uint32 recordSize;
|
||||
uint32 recordCount;
|
||||
uint32 fieldCount;
|
||||
uint32 stringSize;
|
||||
uint32 *fieldsOffset;
|
||||
unsigned char *data;
|
||||
unsigned char *stringTable;
|
||||
};
|
||||
#endif
|
||||
@@ -1,296 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 DBCSTORE_H
|
||||
#define DBCSTORE_H
|
||||
|
||||
#include "DBCFileLoader.h"
|
||||
#include "Logging/Log.h"
|
||||
#include "Field.h"
|
||||
#include "DatabaseWorkerPool.h"
|
||||
#include "Implementation/WorldDatabase.h"
|
||||
#include "DatabaseEnv.h"
|
||||
|
||||
struct SqlDbc
|
||||
{
|
||||
std::string const* formatString;
|
||||
std::string const* indexName;
|
||||
std::string sqlTableName;
|
||||
int32 indexPos;
|
||||
int32 sqlIndexPos;
|
||||
SqlDbc(std::string const* _filename, std::string const* _format, std::string const* _idname, char const* fmt)
|
||||
: formatString(_format), indexName (_idname), sqlIndexPos(0)
|
||||
{
|
||||
// Convert dbc file name to sql table name
|
||||
sqlTableName = *_filename;
|
||||
for (uint32 i = 0; i< sqlTableName.size(); ++i)
|
||||
{
|
||||
if (isalpha(sqlTableName[i]))
|
||||
sqlTableName[i] = char(tolower(sqlTableName[i]));
|
||||
else if (sqlTableName[i] == '.')
|
||||
sqlTableName[i] = '_';
|
||||
}
|
||||
|
||||
// Get sql index position
|
||||
DBCFileLoader::GetFormatRecordSize(fmt, &indexPos);
|
||||
if (indexPos >= 0)
|
||||
{
|
||||
uint32 uindexPos = uint32(indexPos);
|
||||
for (uint32 x = 0; x < formatString->size(); ++x)
|
||||
{
|
||||
// Count only fields present in sql
|
||||
if ((*formatString)[x] == FT_SQL_PRESENT)
|
||||
{
|
||||
if (x == uindexPos)
|
||||
break;
|
||||
++sqlIndexPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class DBCStorage
|
||||
{
|
||||
typedef std::list<char*> StringPoolList;
|
||||
public:
|
||||
explicit DBCStorage(char const* f)
|
||||
: fmt(f), nCount(0), fieldCount(0), dataTable(NULL)
|
||||
{
|
||||
indexTable.asT = NULL;
|
||||
}
|
||||
|
||||
~DBCStorage() { Clear(); }
|
||||
|
||||
T const* LookupEntry(uint32 id) const
|
||||
{
|
||||
return (id >= nCount) ? NULL : indexTable.asT[id];
|
||||
}
|
||||
|
||||
uint32 GetNumRows() const { return nCount; }
|
||||
char const* GetFormat() const { return fmt; }
|
||||
uint32 GetFieldCount() const { return fieldCount; }
|
||||
|
||||
bool Load(char const* fn, SqlDbc* sql)
|
||||
{
|
||||
DBCFileLoader dbc;
|
||||
// Check if load was sucessful, only then continue
|
||||
if (!dbc.Load(fn, fmt))
|
||||
return false;
|
||||
|
||||
uint32 sqlRecordCount = 0;
|
||||
uint32 sqlHighestIndex = 0;
|
||||
Field* fields = NULL;
|
||||
QueryResult result = QueryResult(NULL);
|
||||
// Load data from sql
|
||||
if (sql)
|
||||
{
|
||||
std::string query = "SELECT * FROM " + sql->sqlTableName;
|
||||
if (sql->indexPos >= 0)
|
||||
query +=" ORDER BY " + *sql->indexName + " DESC";
|
||||
query += ';';
|
||||
|
||||
|
||||
result = WorldDatabase.Query(query.c_str());
|
||||
if (result)
|
||||
{
|
||||
sqlRecordCount = uint32(result->GetRowCount());
|
||||
if (sql->indexPos >= 0)
|
||||
{
|
||||
fields = result->Fetch();
|
||||
sqlHighestIndex = fields[sql->sqlIndexPos].GetUInt32();
|
||||
}
|
||||
|
||||
// Check if sql index pos is valid
|
||||
if (int32(result->GetFieldCount() - 1) < sql->sqlIndexPos)
|
||||
{
|
||||
sLog->outError("Invalid index pos for dbc:'%s'", sql->sqlTableName.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char* sqlDataTable = NULL;
|
||||
fieldCount = dbc.GetCols();
|
||||
|
||||
dataTable = reinterpret_cast<T*>(dbc.AutoProduceData(fmt, nCount, indexTable.asChar,
|
||||
sqlRecordCount, sqlHighestIndex, sqlDataTable));
|
||||
|
||||
stringPoolList.push_back(dbc.AutoProduceStrings(fmt, reinterpret_cast<char*>(dataTable)));
|
||||
|
||||
// Insert sql data into arrays
|
||||
if (result)
|
||||
{
|
||||
if (indexTable.asT)
|
||||
{
|
||||
uint32 offset = 0;
|
||||
uint32 rowIndex = dbc.GetNumRows();
|
||||
do
|
||||
{
|
||||
if (!fields)
|
||||
fields = result->Fetch();
|
||||
|
||||
if (sql->indexPos >= 0)
|
||||
{
|
||||
uint32 id = fields[sql->sqlIndexPos].GetUInt32();
|
||||
if (indexTable.asT[id])
|
||||
{
|
||||
sLog->outError("Index %d already exists in dbc:'%s'", id, sql->sqlTableName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
indexTable.asT[id] = reinterpret_cast<T*>(&sqlDataTable[offset]);
|
||||
}
|
||||
else
|
||||
indexTable.asT[rowIndex]= reinterpret_cast<T*>(&sqlDataTable[offset]);
|
||||
|
||||
uint32 columnNumber = 0;
|
||||
uint32 sqlColumnNumber = 0;
|
||||
|
||||
for (; columnNumber < sql->formatString->size(); ++columnNumber)
|
||||
{
|
||||
if ((*sql->formatString)[columnNumber] == FT_SQL_ABSENT)
|
||||
{
|
||||
switch (fmt[columnNumber])
|
||||
{
|
||||
case FT_FLOAT:
|
||||
*reinterpret_cast<float*>(&sqlDataTable[offset]) = 0.0f;
|
||||
offset += 4;
|
||||
break;
|
||||
case FT_IND:
|
||||
case FT_INT:
|
||||
*reinterpret_cast<uint32*>(&sqlDataTable[offset]) = uint32(0);
|
||||
offset += 4;
|
||||
break;
|
||||
case FT_BYTE:
|
||||
*reinterpret_cast<uint8*>(&sqlDataTable[offset]) = uint8(0);
|
||||
offset += 1;
|
||||
break;
|
||||
case FT_STRING:
|
||||
// Beginning of the pool - empty string
|
||||
*reinterpret_cast<char**>(&sqlDataTable[offset]) = stringPoolList.back();
|
||||
offset += sizeof(char*);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((*sql->formatString)[columnNumber] == FT_SQL_PRESENT)
|
||||
{
|
||||
bool validSqlColumn = true;
|
||||
switch (fmt[columnNumber])
|
||||
{
|
||||
case FT_FLOAT:
|
||||
*reinterpret_cast<float*>(&sqlDataTable[offset]) = fields[sqlColumnNumber].GetFloat();
|
||||
offset += 4;
|
||||
break;
|
||||
case FT_IND:
|
||||
case FT_INT:
|
||||
*reinterpret_cast<uint32*>(&sqlDataTable[offset]) = fields[sqlColumnNumber].GetUInt32();
|
||||
offset += 4;
|
||||
break;
|
||||
case FT_BYTE:
|
||||
*reinterpret_cast<uint8*>(&sqlDataTable[offset]) = fields[sqlColumnNumber].GetUInt8();
|
||||
offset += 1;
|
||||
break;
|
||||
case FT_STRING:
|
||||
sLog->outError("Unsupported data type in table '%s' at char %d", sql->sqlTableName.c_str(), columnNumber);
|
||||
return false;
|
||||
case FT_SORT:
|
||||
break;
|
||||
default:
|
||||
validSqlColumn = false;
|
||||
break;
|
||||
}
|
||||
if (validSqlColumn && (columnNumber != (sql->formatString->size()-1)))
|
||||
sqlColumnNumber++;
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog->outError("Incorrect sql format string '%s' at char %d", sql->sqlTableName.c_str(), columnNumber);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (sqlColumnNumber != (result->GetFieldCount() - 1))
|
||||
{
|
||||
sLog->outError("SQL and DBC format strings are not matching for table: '%s'", sql->sqlTableName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
fields = NULL;
|
||||
++rowIndex;
|
||||
} while (result->NextRow());
|
||||
}
|
||||
}
|
||||
|
||||
// error in dbc file at loading if NULL
|
||||
return indexTable.asT != NULL;
|
||||
}
|
||||
|
||||
bool LoadStringsFrom(char const* fn)
|
||||
{
|
||||
// DBC must be already loaded using Load
|
||||
if (!indexTable.asT)
|
||||
return false;
|
||||
|
||||
DBCFileLoader dbc;
|
||||
// Check if load was successful, only then continue
|
||||
if (!dbc.Load(fn, fmt))
|
||||
return false;
|
||||
|
||||
stringPoolList.push_back(dbc.AutoProduceStrings(fmt, reinterpret_cast<char*>(dataTable)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
if (!indexTable.asT)
|
||||
return;
|
||||
|
||||
delete[] reinterpret_cast<char*>(indexTable.asT);
|
||||
indexTable.asT = NULL;
|
||||
delete[] reinterpret_cast<char*>(dataTable);
|
||||
dataTable = NULL;
|
||||
|
||||
while (!stringPoolList.empty())
|
||||
{
|
||||
delete[] stringPoolList.front();
|
||||
stringPoolList.pop_front();
|
||||
}
|
||||
|
||||
nCount = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
char const* fmt;
|
||||
uint32 nCount;
|
||||
uint32 fieldCount;
|
||||
|
||||
union
|
||||
{
|
||||
T** asT;
|
||||
char** asChar;
|
||||
}
|
||||
indexTable;
|
||||
|
||||
T* dataTable;
|
||||
StringPoolList stringPoolList;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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) :
|
||||
m_has_result(false)
|
||||
{
|
||||
m_sql = strdup(sql);
|
||||
}
|
||||
|
||||
BasicStatementTask::BasicStatementTask(const char* sql, QueryResultFuture result) :
|
||||
m_has_result(true),
|
||||
m_result(result)
|
||||
{
|
||||
m_sql = strdup(sql);
|
||||
}
|
||||
|
||||
BasicStatementTask::~BasicStatementTask()
|
||||
{
|
||||
free((void*)m_sql);
|
||||
}
|
||||
|
||||
bool BasicStatementTask::Execute()
|
||||
{
|
||||
if (m_has_result)
|
||||
{
|
||||
ResultSet* result = m_conn->Query(m_sql);
|
||||
if (!result || !result->GetRowCount())
|
||||
{
|
||||
delete result;
|
||||
m_result.set(QueryResult(NULL));
|
||||
return false;
|
||||
}
|
||||
result->NextRow();
|
||||
m_result.set(QueryResult(result));
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_conn->Execute(m_sql);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 <ace/Future.h>
|
||||
#include "SQLOperation.h"
|
||||
|
||||
typedef ACE_Future<QueryResult> QueryResultFuture;
|
||||
/*! Raw, ad-hoc query. */
|
||||
class BasicStatementTask : public SQLOperation
|
||||
{
|
||||
public:
|
||||
BasicStatementTask(const char* sql);
|
||||
BasicStatementTask(const char* sql, QueryResultFuture result);
|
||||
~BasicStatementTask();
|
||||
|
||||
bool Execute();
|
||||
|
||||
private:
|
||||
const char* m_sql; //- Raw query to be executed
|
||||
bool m_has_result;
|
||||
QueryResultFuture m_result;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "MySQLConnection.h"
|
||||
#include "MySQLThreading.h"
|
||||
|
||||
DatabaseWorker::DatabaseWorker(ACE_Activation_Queue* new_queue, MySQLConnection* con) :
|
||||
m_queue(new_queue),
|
||||
m_conn(con)
|
||||
{
|
||||
/// Assign thread to task
|
||||
activate();
|
||||
}
|
||||
|
||||
int DatabaseWorker::svc()
|
||||
{
|
||||
if (!m_queue)
|
||||
return -1;
|
||||
|
||||
SQLOperation *request = NULL;
|
||||
while (1)
|
||||
{
|
||||
request = (SQLOperation*)(m_queue->dequeue());
|
||||
if (!request)
|
||||
break;
|
||||
|
||||
request->SetConnection(m_conn);
|
||||
request->call();
|
||||
|
||||
delete request;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 <ace/Task.h>
|
||||
#include <ace/Activation_Queue.h>
|
||||
|
||||
class MySQLConnection;
|
||||
|
||||
class DatabaseWorker : protected ACE_Task_Base
|
||||
{
|
||||
public:
|
||||
DatabaseWorker(ACE_Activation_Queue* new_queue, MySQLConnection* con);
|
||||
|
||||
///- Inherited from ACE_Task_Base
|
||||
int svc();
|
||||
int wait() { return ACE_Task_Base::wait(); }
|
||||
|
||||
private:
|
||||
DatabaseWorker() : ACE_Task_Base() { }
|
||||
ACE_Activation_Queue* m_queue;
|
||||
MySQLConnection* m_conn;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,531 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 <ace/Thread_Mutex.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"
|
||||
|
||||
#define MIN_MYSQL_SERVER_VERSION 50100u
|
||||
#define MIN_MYSQL_CLIENT_VERSION 50100u
|
||||
|
||||
class PingOperation : public SQLOperation
|
||||
{
|
||||
//! Operation for idle delaythreads
|
||||
bool Execute()
|
||||
{
|
||||
m_conn->Ping();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class DatabaseWorkerPool
|
||||
{
|
||||
public:
|
||||
/* Activity state */
|
||||
DatabaseWorkerPool() :
|
||||
_mqueue(new ACE_Message_Queue<ACE_SYNCH>(2*1024*1024, 2*1024*1024)),
|
||||
_queue(new ACE_Activation_Queue(_mqueue))
|
||||
{
|
||||
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, "AzerothCore does not support MySQL versions below 5.1");
|
||||
}
|
||||
|
||||
~DatabaseWorkerPool()
|
||||
{
|
||||
}
|
||||
|
||||
bool Open(const std::string& infoString, uint8 async_threads, uint8 synch_threads)
|
||||
{
|
||||
bool res = true;
|
||||
_connectionInfo = MySQLConnectionInfo(infoString);
|
||||
|
||||
sLog->outSQLDriver("Opening DatabasePool '%s'. Asynchronous connections: %u, synchronous connections: %u.",
|
||||
GetDatabaseName(), async_threads, synch_threads);
|
||||
|
||||
//! Open asynchronous connections (delayed operations)
|
||||
_connections[IDX_ASYNC].resize(async_threads);
|
||||
for (uint8 i = 0; i < async_threads; ++i)
|
||||
{
|
||||
T* t = new T(_queue, _connectionInfo);
|
||||
res &= t->Open();
|
||||
if (res) // only check mysql version if connection is valid
|
||||
WPFatal(mysql_get_server_version(t->GetHandle()) >= MIN_MYSQL_SERVER_VERSION, "AzerothCore does not support MySQL versions below 5.1");
|
||||
_connections[IDX_ASYNC][i] = t;
|
||||
++_connectionCount[IDX_ASYNC];
|
||||
}
|
||||
|
||||
//! Open synchronous connections (direct, blocking operations)
|
||||
_connections[IDX_SYNCH].resize(synch_threads);
|
||||
for (uint8 i = 0; i < synch_threads; ++i)
|
||||
{
|
||||
T* t = new T(_connectionInfo);
|
||||
res &= t->Open();
|
||||
_connections[IDX_SYNCH][i] = t;
|
||||
++_connectionCount[IDX_SYNCH];
|
||||
}
|
||||
|
||||
if (res)
|
||||
sLog->outSQLDriver("DatabasePool '%s' opened successfully. %u total connections running.", GetDatabaseName(),
|
||||
(_connectionCount[IDX_SYNCH] + _connectionCount[IDX_ASYNC]));
|
||||
else
|
||||
sLog->outError("DatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile "
|
||||
"for specific errors.", GetDatabaseName());
|
||||
return res;
|
||||
}
|
||||
|
||||
void Close()
|
||||
{
|
||||
sLog->outSQLDriver("Closing down DatabasePool '%s'.", GetDatabaseName());
|
||||
|
||||
//! Shuts down delaythreads for this connection pool by underlying deactivate().
|
||||
//! The next dequeue attempt in the worker thread tasks will result in an error,
|
||||
//! ultimately ending the worker thread task.
|
||||
_queue->queue()->close();
|
||||
|
||||
for (uint8 i = 0; i < _connectionCount[IDX_ASYNC]; ++i)
|
||||
{
|
||||
T* t = _connections[IDX_ASYNC][i];
|
||||
DatabaseWorker* worker = t->m_worker;
|
||||
worker->wait(); //! Block until no more threads are running this task.
|
||||
delete worker;
|
||||
t->Close(); //! Closes the actualy MySQL connection.
|
||||
}
|
||||
|
||||
sLog->outSQLDriver("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();
|
||||
|
||||
//! Deletes the ACE_Activation_Queue object and its underlying ACE_Message_Queue
|
||||
delete _queue;
|
||||
delete _mqueue;
|
||||
|
||||
sLog->outSQLDriver("All connections on DatabasePool '%s' closed.", GetDatabaseName());
|
||||
}
|
||||
|
||||
/**
|
||||
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 (!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.
|
||||
void PExecute(const char* sql, ...)
|
||||
{
|
||||
if (!sql)
|
||||
return;
|
||||
|
||||
va_list ap;
|
||||
char szQuery[MAX_QUERY_LEN];
|
||||
va_start(ap, sql);
|
||||
vsnprintf(szQuery, MAX_QUERY_LEN, sql, ap);
|
||||
va_end(ap);
|
||||
|
||||
Execute(szQuery);
|
||||
}
|
||||
|
||||
//! 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.
|
||||
void DirectPExecute(const char* sql, ...)
|
||||
{
|
||||
if (!sql)
|
||||
return;
|
||||
|
||||
va_list ap;
|
||||
char szQuery[MAX_QUERY_LEN];
|
||||
va_start(ap, sql);
|
||||
vsnprintf(szQuery, MAX_QUERY_LEN, sql, ap);
|
||||
va_end(ap);
|
||||
|
||||
return DirectExecute(szQuery);
|
||||
}
|
||||
|
||||
//! 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 = NULL)
|
||||
{
|
||||
if (!conn)
|
||||
conn = GetFreeConnection();
|
||||
|
||||
ResultSet* result = conn->Query(sql);
|
||||
conn->Unlock();
|
||||
if (!result || !result->GetRowCount())
|
||||
{
|
||||
delete result;
|
||||
return QueryResult(NULL);
|
||||
}
|
||||
|
||||
result->NextRow();
|
||||
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.
|
||||
QueryResult PQuery(const char* sql, T* conn, ...)
|
||||
{
|
||||
if (!sql)
|
||||
return QueryResult(NULL);
|
||||
|
||||
va_list ap;
|
||||
char szQuery[MAX_QUERY_LEN];
|
||||
va_start(ap, conn);
|
||||
vsnprintf(szQuery, MAX_QUERY_LEN, sql, ap);
|
||||
va_end(ap);
|
||||
|
||||
return Query(szQuery, 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.
|
||||
QueryResult PQuery(const char* sql, ...)
|
||||
{
|
||||
if (!sql)
|
||||
return QueryResult(NULL);
|
||||
|
||||
va_list ap;
|
||||
char szQuery[MAX_QUERY_LEN];
|
||||
va_start(ap, sql);
|
||||
vsnprintf(szQuery, MAX_QUERY_LEN, sql, ap);
|
||||
va_end(ap);
|
||||
|
||||
return Query(szQuery);
|
||||
}
|
||||
|
||||
//! 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)
|
||||
{
|
||||
QueryResultFuture res;
|
||||
BasicStatementTask* task = new BasicStatementTask(sql, res);
|
||||
Enqueue(task);
|
||||
return res; //! Actual return value has no use yet
|
||||
}
|
||||
|
||||
//! 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.
|
||||
QueryResultFuture AsyncPQuery(const char* sql, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char szQuery[MAX_QUERY_LEN];
|
||||
va_start(ap, sql);
|
||||
vsnprintf(szQuery, MAX_QUERY_LEN, sql, ap);
|
||||
va_end(ap);
|
||||
|
||||
return AsyncQuery(szQuery);
|
||||
}
|
||||
|
||||
//! 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)
|
||||
{
|
||||
PreparedQueryResultFuture res;
|
||||
PreparedStatementTask* task = new PreparedStatementTask(stmt, res);
|
||||
Enqueue(task);
|
||||
return res;
|
||||
}
|
||||
|
||||
//! 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)
|
||||
{
|
||||
QueryResultHolderFuture res;
|
||||
SQLQueryHolderTask* task = new SQLQueryHolderTask(holder, res);
|
||||
Enqueue(task);
|
||||
return res; //! Fool compiler, has no use yet
|
||||
}
|
||||
|
||||
/**
|
||||
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:
|
||||
sLog->outSQLDriver("Transaction contains 0 queries. Not executing.");
|
||||
return;
|
||||
case 1:
|
||||
sLog->outSQLDriver("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();
|
||||
if (con->ExecuteTransaction(transaction))
|
||||
{
|
||||
con->Unlock(); // OK, operation succesful
|
||||
return;
|
||||
}
|
||||
|
||||
//! Handle MySQL Errno 1213 without extending deadlock to the core itself
|
||||
//! TODO: More elegant way
|
||||
if (con->GetLastError() == 1213)
|
||||
{
|
||||
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.null())
|
||||
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.null())
|
||||
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:
|
||||
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->enqueue(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();
|
||||
}
|
||||
|
||||
private:
|
||||
enum _internalIndex
|
||||
{
|
||||
IDX_ASYNC,
|
||||
IDX_SYNCH,
|
||||
IDX_SIZE
|
||||
};
|
||||
|
||||
ACE_Message_Queue<ACE_SYNCH>* _mqueue;
|
||||
ACE_Activation_Queue* _queue; //! Queue shared by async worker threads.
|
||||
std::vector< std::vector<T*> > _connections;
|
||||
uint32 _connectionCount[2]; //! Counter of MySQL connections;
|
||||
MySQLConnectionInfo _connectionInfo;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
@@ -1,390 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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))
|
||||
{
|
||||
sLog->outSQLDriver("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>(atol((char*)data.value));
|
||||
}
|
||||
|
||||
int8 GetInt8() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0;
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
if (!IsType(MYSQL_TYPE_TINY))
|
||||
{
|
||||
sLog->outSQLDriver("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>(atol((char*)data.value));
|
||||
}
|
||||
|
||||
uint16 GetUInt16() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0;
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
if (!IsType(MYSQL_TYPE_SHORT) && !IsType(MYSQL_TYPE_YEAR))
|
||||
{
|
||||
sLog->outSQLDriver("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>(atol((char*)data.value));
|
||||
}
|
||||
|
||||
int16 GetInt16() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0;
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
if (!IsType(MYSQL_TYPE_SHORT) && !IsType(MYSQL_TYPE_YEAR))
|
||||
{
|
||||
sLog->outSQLDriver("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>(atol((char*)data.value));
|
||||
}
|
||||
|
||||
uint32 GetUInt32() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0;
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
if (!IsType(MYSQL_TYPE_INT24) && !IsType(MYSQL_TYPE_LONG))
|
||||
{
|
||||
sLog->outSQLDriver("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>(atol((char*)data.value));
|
||||
}
|
||||
|
||||
int32 GetInt32() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0;
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
if (!IsType(MYSQL_TYPE_INT24) && !IsType(MYSQL_TYPE_LONG))
|
||||
{
|
||||
sLog->outSQLDriver("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>(atol((char*)data.value));
|
||||
}
|
||||
|
||||
uint64 GetUInt64() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0;
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
if (!IsType(MYSQL_TYPE_LONGLONG) && !IsType(MYSQL_TYPE_BIT))
|
||||
{
|
||||
sLog->outSQLDriver("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>(atol((char*)data.value));
|
||||
}
|
||||
|
||||
int64 GetInt64() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0;
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
if (!IsType(MYSQL_TYPE_LONGLONG) && !IsType(MYSQL_TYPE_BIT))
|
||||
{
|
||||
sLog->outSQLDriver("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>(strtol((char*)data.value, NULL, 10));
|
||||
}
|
||||
|
||||
float GetFloat() const
|
||||
{
|
||||
if (!data.value)
|
||||
return 0.0f;
|
||||
|
||||
#ifdef TRINITY_DEBUG
|
||||
if (!IsType(MYSQL_TYPE_FLOAT))
|
||||
{
|
||||
sLog->outSQLDriver("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))
|
||||
{
|
||||
sLog->outSQLDriver("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())
|
||||
{
|
||||
sLog->outSQLDriver("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();
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma pack(1)
|
||||
#else
|
||||
#pragma pack(push, 1)
|
||||
#endif
|
||||
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;
|
||||
#if defined(__GNUC__)
|
||||
#pragma pack()
|
||||
#else
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
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:
|
||||
sLog->outSQLDriver("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
|
||||
|
||||
@@ -1,567 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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_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 FROM_UNIXTIME(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_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, c.extra_flags "
|
||||
"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, c.extra_flags, 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_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_QUEST_STATUS_DAILY, "DELETE FROM character_queststatus_daily", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_QUEST_STATUS_WEEKLY, "DELETE FROM character_queststatus_weekly", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_QUEST_STATUS_MONTHLY, "DELETE FROM character_queststatus_monthly", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_QUEST_STATUS_SEASONAL, "DELETE FROM character_queststatus_seasonal WHERE event = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_QUEST_STATUS_DAILY_CHAR, "DELETE FROM character_queststatus_daily WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_QUEST_STATUS_WEEKLY_CHAR, "DELETE FROM character_queststatus_weekly WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_QUEST_STATUS_MONTHLY_CHAR, "DELETE FROM character_queststatus_monthly WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_QUEST_STATUS_SEASONAL_CHAR, "DELETE FROM character_queststatus_seasonal WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_BATTLEGROUND_RANDOM, "DELETE FROM character_battleground_random", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_BATTLEGROUND_RANDOM, "INSERT INTO character_battleground_random (guid) VALUES (?)", CONNECTION_ASYNC);
|
||||
|
||||
// Start LoginQueryHolder content
|
||||
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, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels "
|
||||
"FROM characters WHERE guid = ?", CONNECTION_ASYNC);
|
||||
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_AURAS, "SELECT caster_guid, spell, effect_mask, recalculate_mask, 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, specMask 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_DAILYQUESTSTATUS, "SELECT quest, time FROM character_queststatus_daily WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_WEEKLYQUESTSTATUS, "SELECT quest FROM character_queststatus_weekly WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_MONTHLYQUESTSTATUS, "SELECT quest FROM character_queststatus_monthly WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_SEASONALQUESTSTATUS, "SELECT quest, event FROM character_queststatus_seasonal WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHARACTER_DAILYQUESTSTATUS, "INSERT INTO character_queststatus_daily (guid, quest, time) VALUES (?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHARACTER_WEEKLYQUESTSTATUS, "INSERT INTO character_queststatus_weekly (guid, quest) VALUES (?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHARACTER_MONTHLYQUESTSTATUS, "INSERT INTO character_queststatus_monthly (guid, quest) VALUES (?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHARACTER_SEASONALQUESTSTATUS, "INSERT INTO character_queststatus_seasonal (guid, quest, event) VALUES (?, ?, ?)", 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.activespec 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_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, needSend FROM character_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_DECLINEDNAMES, "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC);
|
||||
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_ENTRY_POINT, "SELECT joinX, joinY, joinZ, joinO, joinMapId, taxiPath, mountSpell FROM character_entry_point WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_GLYPHS, "SELECT spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6 FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_TALENTS, "SELECT spell, specMask 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_BREW_OF_THE_MONTH, "SELECT lastEventId FROM character_brew_of_the_month WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_REP_BREW_OF_THE_MONTH, "REPLACE INTO character_brew_of_the_month (guid, lastEventId) VALUES (?, ?)", CONNECTION_ASYNC);
|
||||
// End LoginQueryHolder content
|
||||
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_ACTIONS_SPEC, "SELECT button, action, type FROM character_action WHERE guid = ? AND spec = ? ORDER BY button", CONNECTION_ASYNC);
|
||||
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_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_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_ACCOUNT_BY_NAME, "SELECT account FROM characters WHERE name = ?", 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_MATCH_MAKER_RATING, "SELECT matchMakerRating, maxMMR 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_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: 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_INS_CHANNEL, "INSERT INTO channels(channelId, name, team, announce, lastUsed) VALUES (?, ?, ?, ?, UNIX_TIMESTAMP())", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_CHANNEL, "UPDATE channels SET announce = ?, password = ?, lastUsed = UNIX_TIMESTAMP() WHERE channelId = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_CHANNEL_USAGE, "UPDATE channels SET lastUsed = UNIX_TIMESTAMP() WHERE channelId = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_OLD_CHANNELS, "DELETE FROM channels WHERE lastUsed + ? < UNIX_TIMESTAMP()", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_OLD_CHANNELS_BANS, "DELETE cb.* FROM channels_bans cb LEFT JOIN channels cn ON cb.channelId=cn.channelId WHERE cn.channelId IS NULL OR cb.banTime <= UNIX_TIMESTAMP()", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHANNEL_BAN, "REPLACE INTO channels_bans VALUES (?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_CHANNEL_BAN, "DELETE FROM channels_bans WHERE channelId = ? AND playerGUID = ?", 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, caster_guid, item_guid, spell, effect_mask, recalculate_mask, 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_SAVE_DATA, "UPDATE instance SET data=? WHERE id=?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_INSTANCE_SAVE_ENCOUNTERMASK, "UPDATE instance SET completedEncounters=? 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_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);
|
||||
|
||||
// Arena teams
|
||||
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_REP_CHARACTER_ARENA_STATS, "REPLACE INTO character_arena_stats (guid, slot, matchMakerRating, maxMMR) 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);
|
||||
|
||||
// Character battleground data
|
||||
PrepareStatement(CHAR_INS_PLAYER_ENTRY_POINT, "INSERT INTO character_entry_point (guid, joinX, joinY, joinZ, joinO, joinMapId, taxiPath, mountSpell) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_PLAYER_ENTRY_POINT, "DELETE FROM character_entry_point 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);
|
||||
|
||||
// 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, type, playerGuid, name, description, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, needMoreHelp, resolvedBy FROM gm_ticket", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_REP_GM_TICKET, "REPLACE INTO gm_ticket (id, type, playerGuid, name, description, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, needMoreHelp, resolvedBy) 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);
|
||||
PrepareStatement(CHAR_UPD_PLAYER_GM_TICKETS_ON_CHAR_DELETION, "UPDATE gm_ticket SET type = 2 WHERE playerGuid = ?", CONNECTION_ASYNC);
|
||||
|
||||
// GM Survey/subsurvey/lag report
|
||||
PrepareStatement(CHAR_INS_GM_SURVEY, "INSERT INTO gm_surveys (guid, surveyId, mainSurvey, overallComment, createTime) VALUES (?, ?, ?, ?, UNIX_TIMESTAMP(NOW()))", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_GM_SUBSURVEY, "INSERT INTO gm_subsurveys (surveyId, subsurveyId, rank, comment) 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_REP_LFG_DATA, "REPLACE 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, speccount, activespec, 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=?,speccount=?,activespec=?,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_REP_GROUP_MEMBER, "REPLACE INTO group_member (guid, memberGuid, memberFlags, subgroup, roles) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_GROUP_MEMBER, "DELETE FROM group_member WHERE memberGuid = ? AND guid = ?", 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_UDP_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_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, "DELETE FROM character_instance WHERE instance = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_NOT_EXTENDED, "DELETE FROM character_instance WHERE instance = ? AND extended = 0", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_CHAR_INSTANCE_SET_NOT_EXTENDED, "UPDATE character_instance SET extended = 0 WHERE instance = ?", 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 = ?, extended = 0 WHERE guid = ? AND instance = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_CHAR_INSTANCE_EXTENDED, "UPDATE character_instance SET extended = ? WHERE guid = ? AND instance = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHAR_INSTANCE, "INSERT INTO character_instance (guid, instance, permanent, extended) VALUES (?, ?, ?, 0)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_ARENA_LOG_FIGHT, "INSERT INTO log_arena_fights VALUES (?, NOW(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_ARENA_LOG_MEMBERSTATS, "INSERT INTO log_arena_memberstats 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, "REPLACE 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 FROM characters LEFT JOIN character_aura ON (characters.guid = character_aura.guid) WHERE character_aura.spell = 9454", CONNECTION_ASYNC);
|
||||
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 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);
|
||||
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_MONEY, "SELECT at_login, knownTitles, money FROM characters WHERE guid = ?", 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_MAIL_ASYNCH, "SELECT ii.creatorGuid, ii.giftCreatorGuid, ii.count, ii.duration, ii.charges, ii.flags, ii.enchantments, ii.randomPropertyId, ii.durability, ii.playedTime, ii.text, mi.item_guid, ii.itemEntry, ii.owner_guid, mail.id, mail.messageType, mail.sender, mail.receiver, mail.subject, mail.body, mail.has_items, mail.expire_time, mail.deliver_time, mail.money, mail.cod, mail.checked, mail.stationery, mail.mailTemplateId FROM mail LEFT JOIN (mail_items mi JOIN item_instance ii) ON (mi.mail_id = mail.id AND mi.item_guid = ii.guid) WHERE mail.receiver = ? ORDER BY mail.id DESC", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHAR_PLAYERBYTES2, "SELECT playerBytes2 FROM characters WHERE guid = ?", 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_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_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 guid = ? AND spell = ?", 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_COOLDOWN, "DELETE FROM character_spell_cooldown WHERE guid = ?", 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_UDP_CHAR_HONOR_POINTS, "UPDATE characters SET totalHonorPoints = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UDP_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UDP_CHAR_MONEY, "UPDATE characters SET money = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_CHAR_REMOVE_GHOST, "UPDATE characters SET playerFlags = (playerFlags & (~16)) 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_UDP_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, specMask) 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, "DELETE FROM character_talent WHERE guid = ? and spell = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHAR_TALENT, "INSERT INTO character_talent (guid, spell, specMask) 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 containerGUID, itemid, count, randomPropertyId, randomSuffix FROM item_loot_storage", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_DEL_ITEMCONTAINER_SINGLE_ITEM, "DELETE FROM item_loot_storage WHERE containerGUID = ? AND itemid = ? AND count = ? LIMIT 1", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_ITEMCONTAINER_SINGLE_ITEM, "INSERT INTO item_loot_storage (containerGUID, itemid, count, randomPropertyId, randomSuffix) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_ITEMCONTAINER_CONTAINER, "DELETE FROM item_loot_storage WHERE containerGUID = ?", 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_ADD_CHAR_PET_DECLINEDNAME, "INSERT INTO character_pet_declinedname (id, owner, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_PET_AURA, "SELECT caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges FROM pet_aura WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_PET_SPELL, "SELECT spell, active FROM pet_spell WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_PET_SPELL_COOLDOWN, "SELECT spell, time FROM pet_spell_cooldown WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_PET_AURAS, "DELETE FROM pet_aura WHERE guid = ?", CONNECTION_ASYNC);
|
||||
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_ASYNC);
|
||||
PrepareStatement(CHAR_INS_PET_SPELL_COOLDOWN, "INSERT INTO pet_spell_cooldown (guid, spell, time) VALUES (?, ?, ?)", CONNECTION_ASYNC);
|
||||
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_ASYNC);
|
||||
PrepareStatement(CHAR_INS_PET_AURA, "INSERT INTO pet_aura (guid, caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, "
|
||||
"base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
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_ASYNC);
|
||||
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_ASYNC);
|
||||
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_ASYNC);
|
||||
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_ASYNC);
|
||||
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_UDP_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID, "UPDATE character_pet SET slot = ? WHERE owner = ? AND slot = ? AND id <> ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UDP_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);
|
||||
PrepareStatement(CHAR_REP_CHAR_PET, "REPLACE INTO character_pet (id, entry, owner, modelid, CreatedBySpell, PetType, level, exp, Reactstate, name, renamed, slot, curhealth, curmana, curhappiness, savetime, abdata) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", 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, winner, 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);
|
||||
|
||||
// Deserter tracker
|
||||
PrepareStatement(CHAR_INS_DESERTER_TRACK, "INSERT INTO battleground_deserters (guid, type, datetime) VALUES (?, ?, NOW())", CONNECTION_ASYNC);
|
||||
}
|
||||
@@ -1,507 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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(ACE_Activation_Queue* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) {}
|
||||
|
||||
//- Loads database type specific prepared statements
|
||||
void DoPrepareStatements();
|
||||
};
|
||||
|
||||
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_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_ENUM,
|
||||
CHAR_SEL_ENUM_DECLINED_NAME,
|
||||
CHAR_SEL_FREE_NAME,
|
||||
CHAR_SEL_CHAR_ZONE,
|
||||
CHAR_SEL_CHARACTER_NAME_DATA,
|
||||
CHAR_SEL_CHAR_POSITION_XYZ,
|
||||
CHAR_SEL_CHAR_POSITION,
|
||||
CHAR_DEL_QUEST_STATUS_DAILY,
|
||||
CHAR_DEL_QUEST_STATUS_WEEKLY,
|
||||
CHAR_DEL_QUEST_STATUS_MONTHLY,
|
||||
CHAR_DEL_QUEST_STATUS_SEASONAL,
|
||||
CHAR_DEL_QUEST_STATUS_DAILY_CHAR,
|
||||
CHAR_DEL_QUEST_STATUS_WEEKLY_CHAR,
|
||||
CHAR_DEL_QUEST_STATUS_MONTHLY_CHAR,
|
||||
CHAR_DEL_QUEST_STATUS_SEASONAL_CHAR,
|
||||
CHAR_DEL_BATTLEGROUND_RANDOM,
|
||||
CHAR_INS_BATTLEGROUND_RANDOM,
|
||||
|
||||
CHAR_SEL_CHARACTER,
|
||||
CHAR_SEL_CHARACTER_AURAS,
|
||||
CHAR_SEL_CHARACTER_SPELL,
|
||||
CHAR_SEL_CHARACTER_QUESTSTATUS,
|
||||
CHAR_SEL_CHARACTER_DAILYQUESTSTATUS,
|
||||
CHAR_SEL_CHARACTER_WEEKLYQUESTSTATUS,
|
||||
CHAR_SEL_CHARACTER_MONTHLYQUESTSTATUS,
|
||||
CHAR_SEL_CHARACTER_SEASONALQUESTSTATUS,
|
||||
CHAR_INS_CHARACTER_DAILYQUESTSTATUS,
|
||||
CHAR_INS_CHARACTER_WEEKLYQUESTSTATUS,
|
||||
CHAR_INS_CHARACTER_MONTHLYQUESTSTATUS,
|
||||
CHAR_INS_CHARACTER_SEASONALQUESTSTATUS,
|
||||
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_CHARACTER_SOCIALLIST,
|
||||
CHAR_SEL_CHARACTER_HOMEBIND,
|
||||
CHAR_SEL_CHARACTER_SPELLCOOLDOWNS,
|
||||
CHAR_SEL_CHARACTER_DECLINEDNAMES,
|
||||
CHAR_SEL_CHARACTER_ACHIEVEMENTS,
|
||||
CHAR_SEL_CHARACTER_CRITERIAPROGRESS,
|
||||
CHAR_SEL_CHARACTER_EQUIPMENTSETS,
|
||||
CHAR_SEL_CHARACTER_ENTRY_POINT,
|
||||
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_BREW_OF_THE_MONTH,
|
||||
CHAR_REP_BREW_OF_THE_MONTH,
|
||||
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_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_DEL_ACCOUNT_INSTANCE_LOCK_TIMES,
|
||||
CHAR_INS_ACCOUNT_INSTANCE_LOCK_TIMES,
|
||||
CHAR_SEL_MATCH_MAKER_RATING,
|
||||
CHAR_SEL_CHARACTER_COUNT,
|
||||
CHAR_UPD_NAME,
|
||||
CHAR_DEL_DECLINED_NAME,
|
||||
|
||||
CHAR_INS_GUILD,
|
||||
CHAR_DEL_GUILD,
|
||||
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_INS_CHANNEL,
|
||||
CHAR_UPD_CHANNEL,
|
||||
CHAR_UPD_CHANNEL_USAGE,
|
||||
CHAR_DEL_OLD_CHANNELS,
|
||||
CHAR_DEL_OLD_CHANNELS_BANS,
|
||||
CHAR_INS_CHANNEL_BAN,
|
||||
CHAR_DEL_CHANNEL_BAN,
|
||||
|
||||
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_SAVE_DATA,
|
||||
CHAR_UPD_INSTANCE_SAVE_ENCOUNTERMASK,
|
||||
|
||||
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_REP_CHARACTER_ARENA_STATS,
|
||||
CHAR_SEL_PLAYER_ARENA_TEAMS,
|
||||
|
||||
CHAR_DEL_ALL_PETITION_SIGNATURES,
|
||||
CHAR_DEL_PETITION_SIGNATURE,
|
||||
|
||||
CHAR_INS_PLAYER_ENTRY_POINT,
|
||||
CHAR_DEL_PLAYER_ENTRY_POINT,
|
||||
|
||||
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_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_UPD_PLAYER_GM_TICKETS_ON_CHAR_DELETION,
|
||||
|
||||
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_REP_GROUP_MEMBER,
|
||||
CHAR_DEL_GROUP_MEMBER,
|
||||
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_UDP_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_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,
|
||||
CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_NOT_EXTENDED,
|
||||
CHAR_UPD_CHAR_INSTANCE_SET_NOT_EXTENDED,
|
||||
CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID,
|
||||
CHAR_UPD_CHAR_INSTANCE,
|
||||
CHAR_UPD_CHAR_INSTANCE_EXTENDED,
|
||||
CHAR_INS_CHAR_INSTANCE,
|
||||
CHAR_INS_ARENA_LOG_FIGHT,
|
||||
CHAR_INS_ARENA_LOG_MEMBERSTATS,
|
||||
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_REP_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_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_MONEY,
|
||||
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_MAIL_ASYNCH,
|
||||
CHAR_SEL_CHAR_PLAYERBYTES2,
|
||||
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_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_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_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_UDP_CHAR_HONOR_POINTS,
|
||||
CHAR_UDP_CHAR_ARENA_POINTS,
|
||||
CHAR_UDP_CHAR_MONEY,
|
||||
CHAR_UPD_CHAR_REMOVE_GHOST, // pussywizard
|
||||
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_UDP_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,
|
||||
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_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_ADD_CHAR_PET_DECLINEDNAME,
|
||||
CHAR_UPD_CHAR_PET_NAME,
|
||||
CHAR_UDP_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID,
|
||||
CHAR_UDP_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_REP_CHAR_PET,
|
||||
|
||||
CHAR_SEL_ITEMCONTAINER_ITEMS,
|
||||
CHAR_DEL_ITEMCONTAINER_SINGLE_ITEM,
|
||||
CHAR_INS_ITEMCONTAINER_SINGLE_ITEM,
|
||||
CHAR_DEL_ITEMCONTAINER_CONTAINER,
|
||||
|
||||
CHAR_SEL_PVPSTATS_MAXID,
|
||||
CHAR_INS_PVPSTATS_BATTLEGROUND,
|
||||
CHAR_INS_PVPSTATS_PLAYER,
|
||||
CHAR_SEL_PVPSTATS_FACTIONS_OVERALL,
|
||||
|
||||
CHAR_INS_DESERTER_TRACK,
|
||||
|
||||
MAX_CHARACTERDATABASE_STATEMENTS
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 realmd', '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 realmd', '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.last_ip, aa.gmlevel, a.v, a.s FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = ?", 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, joindate) VALUES(?, ?, NOW())", CONNECTION_ASYNC);
|
||||
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_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_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_ACCOUNT_ONLINE, "UPDATE account SET online = online | (1<<(?-1)) WHERE id = ?", 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.last_ip, DATE_FORMAT(a.last_login, '%Y-%m-%d %T'), a.mutetime, a.mutereason, a.muteby 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_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_AUTOBROADCAST, "SELECT id, weight, text FROM autobroadcast WHERE realmid = ? OR realmid = -1", CONNECTION_SYNCH);
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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(ACE_Activation_Queue* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { }
|
||||
|
||||
//- Loads database type specific prepared statements
|
||||
void DoPrepareStatements();
|
||||
};
|
||||
|
||||
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_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_USERNAME,
|
||||
LOGIN_UPD_PASSWORD,
|
||||
LOGIN_UPD_MUTE_TIME,
|
||||
LOGIN_UPD_MUTE_TIME_LOGIN,
|
||||
LOGIN_UPD_LAST_IP,
|
||||
LOGIN_UPD_ACCOUNT_ONLINE,
|
||||
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_AUTOBROADCAST,
|
||||
|
||||
MAX_LOGINDATABASE_STATEMENTS
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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, 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, security, help FROM command", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT 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, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, 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, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, 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);
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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(ACE_Activation_Queue* q, MySQLConnectionInfo& connInfo) : MySQLConnection(q, connInfo) { }
|
||||
|
||||
//- Loads database type specific prepared statements
|
||||
void DoPrepareStatements();
|
||||
};
|
||||
|
||||
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,
|
||||
|
||||
MAX_WORLDDATABASE_STATEMENTS
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,546 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 <mysqld_error.h>
|
||||
#include <errmsg.h>
|
||||
|
||||
#include "MySQLConnection.h"
|
||||
#include "MySQLThreading.h"
|
||||
#include "QueryResult.h"
|
||||
#include "SQLOperation.h"
|
||||
#include "PreparedStatement.h"
|
||||
#include "DatabaseWorker.h"
|
||||
#include "Timer.h"
|
||||
#include "Log.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(ACE_Activation_Queue* 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()
|
||||
{
|
||||
ASSERT (m_Mysql); /// MySQL context must be present at this point
|
||||
|
||||
for (size_t i = 0; i < m_stmts.size(); ++i)
|
||||
delete m_stmts[i];
|
||||
|
||||
mysql_close(m_Mysql);
|
||||
}
|
||||
|
||||
void MySQLConnection::Close()
|
||||
{
|
||||
/// Only close us if we're not operating
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool MySQLConnection::Open()
|
||||
{
|
||||
MYSQL *mysqlInit;
|
||||
mysqlInit = mysql_init(NULL);
|
||||
if (!mysqlInit)
|
||||
{
|
||||
sLog->outError("Could not initialize Mysql connection to database `%s`", m_connectionInfo.database.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
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 = 0;
|
||||
}
|
||||
#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)
|
||||
{
|
||||
sLog->outSQLDriver("MySQL client library: %s", mysql_get_client_info());
|
||||
sLog->outSQLDriver("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())
|
||||
// sLog->outInfo(LOG_FILTER_SQL, "[WARNING] MySQL client/server version mismatch; may conflict with behaviour of prepared statements.");
|
||||
}
|
||||
|
||||
;//sLog->outDetail("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 PrepareStatements();
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog->outError("Could not connect to MySQL database at %s: %s\n", m_connectionInfo.host.c_str(), mysql_error(mysqlInit));
|
||||
mysql_close(mysqlInit);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool MySQLConnection::PrepareStatements()
|
||||
{
|
||||
DoPrepareStatements();
|
||||
return !m_prepareError;
|
||||
}
|
||||
|
||||
bool MySQLConnection::Execute(const char* sql)
|
||||
{
|
||||
if (!m_Mysql)
|
||||
return false;
|
||||
|
||||
{
|
||||
uint32 _s = 0;
|
||||
if (sLog->GetSQLDriverQueryLogging())
|
||||
_s = getMSTime();
|
||||
|
||||
if (mysql_query(m_Mysql, sql))
|
||||
{
|
||||
uint32 lErrno = mysql_errno(m_Mysql);
|
||||
|
||||
sLog->outSQLDriver("SQL: %s", sql);
|
||||
sLog->outSQLDriver("ERROR: [%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 if (sLog->GetSQLDriverQueryLogging())
|
||||
{
|
||||
sLog->outSQLDriver("[%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 = 0;
|
||||
if (sLog->GetSQLDriverQueryLogging())
|
||||
_s = getMSTime();
|
||||
|
||||
if (mysql_stmt_bind_param(msql_STMT, msql_BIND))
|
||||
{
|
||||
uint32 lErrno = mysql_errno(m_Mysql);
|
||||
sLog->outSQLDriver("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);
|
||||
sLog->outSQLDriver("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 (sLog->GetSQLDriverQueryLogging())
|
||||
sLog->outSQLDriver("[%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 = 0;
|
||||
if (sLog->GetSQLDriverQueryLogging())
|
||||
_s = getMSTime();
|
||||
|
||||
if (mysql_stmt_bind_param(msql_STMT, msql_BIND))
|
||||
{
|
||||
uint32 lErrno = mysql_errno(m_Mysql);
|
||||
sLog->outSQLDriver("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);
|
||||
sLog->outSQLDriver("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 (sLog->GetSQLDriverQueryLogging())
|
||||
sLog->outSQLDriver("[%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 = 0;
|
||||
if (sLog->GetSQLDriverQueryLogging())
|
||||
_s = getMSTime();
|
||||
|
||||
if (mysql_query(m_Mysql, sql))
|
||||
{
|
||||
uint32 lErrno = mysql_errno(m_Mysql);
|
||||
sLog->outSQLDriver("SQL: %s", sql);
|
||||
sLog->outSQLDriver("ERROR: [%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 if (sLog->GetSQLDriverQueryLogging())
|
||||
{
|
||||
sLog->outSQLDriver("[%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");
|
||||
}
|
||||
|
||||
bool MySQLConnection::ExecuteTransaction(SQLTransaction& transaction)
|
||||
{
|
||||
std::list<SQLElementData> const& queries = transaction->m_queries;
|
||||
if (queries.empty())
|
||||
return false;
|
||||
|
||||
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))
|
||||
{
|
||||
sLog->outSQLDriver("[Warning] Transaction aborted. %u queries not executed.", (uint32)queries.size());
|
||||
RollbackTransaction();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SQL_ELEMENT_RAW:
|
||||
{
|
||||
const char* sql = data.element.query;
|
||||
ASSERT(sql);
|
||||
if (!Execute(sql))
|
||||
{
|
||||
sLog->outSQLDriver("[Warning] Transaction aborted. %u queries not executed.", (uint32)queries.size());
|
||||
RollbackTransaction();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
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 true;
|
||||
}
|
||||
|
||||
MySQLPreparedStatement* MySQLConnection::GetPreparedStatement(uint32 index)
|
||||
{
|
||||
ASSERT(index < m_stmts.size());
|
||||
MySQLPreparedStatement* ret = m_stmts[index];
|
||||
if (!ret)
|
||||
sLog->outSQLDriver("ERROR: 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)
|
||||
{
|
||||
sLog->outSQLDriver("[ERROR]: In mysql_stmt_init() id: %u, sql: \"%s\"", index, sql);
|
||||
sLog->outSQLDriver("[ERROR]: %s", mysql_error(m_Mysql));
|
||||
m_prepareError = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mysql_stmt_prepare(stmt, sql, static_cast<unsigned long>(strlen(sql))))
|
||||
{
|
||||
sLog->outSQLDriver("[ERROR]: In mysql_stmt_prepare() id: %u, sql: \"%s\"", index, sql);
|
||||
sLog->outSQLDriver("[ERROR]: %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());
|
||||
if (this->Open()) // Don't remove 'this' pointer unless you want to skip loading all prepared statements....
|
||||
{
|
||||
sLog->outSQLDriver("Connection to the MySQL server is active.");
|
||||
if (oldThreadId != mysql_thread_id(GetHandle()))
|
||||
sLog->outSQLDriver("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;
|
||||
}
|
||||
|
||||
uint32 lErrno = mysql_errno(GetHandle()); // It's possible this attempted reconnect throws 2006 at us. To prevent crazy recursive calls, sleep here.
|
||||
ACE_OS::sleep(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:
|
||||
sLog->outError("Your database structure is not up to date. Please make sure you've executed all queries in the sql/updates folders.");
|
||||
ACE_OS::sleep(10);
|
||||
std::abort();
|
||||
return false;
|
||||
case ER_PARSE_ERROR:
|
||||
sLog->outError("Error while parsing SQL. Core fix required.");
|
||||
ACE_OS::sleep(10);
|
||||
std::abort();
|
||||
return false;
|
||||
default:
|
||||
sLog->outError("Unhandled MySQL errno %u. Unexpected behaviour possible.", errNo);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 <ace/Activation_Queue.h>
|
||||
|
||||
#include "DatabaseWorkerPool.h"
|
||||
#include "Transaction.h"
|
||||
#include "Util.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
|
||||
{
|
||||
MySQLConnectionInfo() { }
|
||||
MySQLConnectionInfo(const std::string& 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(ACE_Activation_Queue* queue, MySQLConnectionInfo& connInfo); //! Constructor for asynchronous connections.
|
||||
virtual ~MySQLConnection();
|
||||
|
||||
virtual bool Open();
|
||||
void Close();
|
||||
|
||||
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();
|
||||
bool 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.tryacquire() != -1;
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
/// Called by parent databasepool. Will let other threads access this connection
|
||||
m_Mutex.release();
|
||||
}
|
||||
|
||||
MYSQL* GetHandle() { return m_Mysql; }
|
||||
MySQLPreparedStatement* GetPreparedStatement(uint32 index);
|
||||
void PrepareStatement(uint32 index, const char* sql, ConnectionFlags flags);
|
||||
|
||||
bool PrepareStatements();
|
||||
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:
|
||||
ACE_Activation_Queue* 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)
|
||||
ACE_Thread_Mutex m_Mutex;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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:
|
||||
/*! Create a thread on the MySQL server to mirrior the calling thread,
|
||||
initializes thread-specific variables and allows thread-specific
|
||||
operations without concurrence from other threads.
|
||||
This should only be called if multiple core threads are running
|
||||
on the same MySQL connection. Seperate MySQL connections implicitly
|
||||
create a mirror thread.
|
||||
*/
|
||||
static void Thread_Init()
|
||||
{
|
||||
mysql_thread_init();
|
||||
sLog->outSQLDriver("Core thread with ID [" UI64FMTD "] initializing MySQL thread.",
|
||||
(uint64)ACE_Based::Thread::currentId());
|
||||
}
|
||||
|
||||
/*! Shuts down MySQL thread and frees resources, should only be called
|
||||
when we terminate. MySQL threads and connections are not configurable
|
||||
during runtime.
|
||||
*/
|
||||
static void Thread_End()
|
||||
{
|
||||
mysql_thread_end();
|
||||
sLog->outSQLDriver("Core thread with ID [" UI64FMTD "] shutting down MySQL thread.",
|
||||
(uint64)ACE_Based::Thread::currentId());
|
||||
}
|
||||
|
||||
static void Library_Init()
|
||||
{
|
||||
mysql_library_init(-1, NULL, NULL);
|
||||
}
|
||||
|
||||
static void Library_End()
|
||||
{
|
||||
mysql_library_end();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,487 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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)
|
||||
sLog->outSQLDriver("[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)
|
||||
{
|
||||
sLog->outError("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])
|
||||
sLog->outSQLDriver("[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) :
|
||||
m_stmt(stmt),
|
||||
m_has_result(false)
|
||||
{
|
||||
}
|
||||
|
||||
PreparedStatementTask::PreparedStatementTask(PreparedStatement* stmt, PreparedQueryResultFuture result) :
|
||||
m_stmt(stmt),
|
||||
m_has_result(true),
|
||||
m_result(result)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PreparedStatementTask::~PreparedStatementTask()
|
||||
{
|
||||
delete m_stmt;
|
||||
}
|
||||
|
||||
bool PreparedStatementTask::Execute()
|
||||
{
|
||||
if (m_has_result)
|
||||
{
|
||||
PreparedResultSet* result = m_conn->Query(m_stmt);
|
||||
if (!result || !result->GetRowCount())
|
||||
{
|
||||
delete result;
|
||||
m_result.set(PreparedQueryResult(NULL));
|
||||
return false;
|
||||
}
|
||||
m_result.set(PreparedQueryResult(result));
|
||||
return true;
|
||||
}
|
||||
|
||||
return m_conn->Execute(m_stmt);
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "SQLOperation.h"
|
||||
#include <ace/Future.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
|
||||
};
|
||||
|
||||
//- 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;
|
||||
};
|
||||
|
||||
typedef ACE_Future<PreparedQueryResult> PreparedQueryResultFuture;
|
||||
|
||||
//- Lower-level class, enqueuable operation
|
||||
class PreparedStatementTask : public SQLOperation
|
||||
{
|
||||
public:
|
||||
PreparedStatementTask(PreparedStatement* stmt);
|
||||
PreparedStatementTask(PreparedStatement* stmt, PreparedQueryResultFuture result);
|
||||
~PreparedStatementTask();
|
||||
|
||||
bool Execute();
|
||||
|
||||
protected:
|
||||
PreparedStatement* m_stmt;
|
||||
bool m_has_result;
|
||||
PreparedQueryResultFuture m_result;
|
||||
};
|
||||
#endif
|
||||
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
sLog->outError("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::SetPQuery(size_t index, const char *format, ...)
|
||||
{
|
||||
if (!format)
|
||||
{
|
||||
sLog->outError("Query (index: %u) is empty.", uint32(index));
|
||||
return false;
|
||||
}
|
||||
|
||||
va_list ap;
|
||||
char szQuery [MAX_QUERY_LEN];
|
||||
va_start(ap, format);
|
||||
int res = vsnprintf(szQuery, MAX_QUERY_LEN, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (res == -1)
|
||||
{
|
||||
sLog->outError("SQL Query truncated (and not execute) for format: %s", format);
|
||||
return false;
|
||||
}
|
||||
|
||||
return SetQuery(index, szQuery);
|
||||
}
|
||||
|
||||
bool SQLQueryHolder::SetPreparedQuery(size_t index, PreparedStatement* stmt)
|
||||
{
|
||||
if (m_queries.size() <= index)
|
||||
{
|
||||
sLog->outError("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())
|
||||
return QueryResult(NULL);
|
||||
|
||||
result->NextRow();
|
||||
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);
|
||||
}
|
||||
|
||||
bool SQLQueryHolderTask::Execute()
|
||||
{
|
||||
//the result can't be ready as we are processing it right now
|
||||
ASSERT(!m_result.ready());
|
||||
|
||||
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(m_holder);
|
||||
return true;
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 <ace/Future.h>
|
||||
|
||||
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);
|
||||
bool SetPQuery(size_t index, const char *format, ...) ATTR_PRINTF(3, 4);
|
||||
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 ACE_Future<SQLQueryHolder*> QueryResultHolderFuture;
|
||||
|
||||
class SQLQueryHolderTask : public SQLOperation
|
||||
{
|
||||
private:
|
||||
SQLQueryHolder * m_holder;
|
||||
QueryResultHolderFuture m_result;
|
||||
|
||||
public:
|
||||
SQLQueryHolderTask(SQLQueryHolder *holder, QueryResultHolderFuture res)
|
||||
: m_holder(holder), m_result(res){ };
|
||||
bool Execute();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,231 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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))
|
||||
{
|
||||
sLog->outSQLDriver("%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))
|
||||
{
|
||||
sLog->outSQLDriver("%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( 0,
|
||||
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 );
|
||||
|
||||
if (!retval || retval == MYSQL_DATA_TRUNCATED)
|
||||
retval = true;
|
||||
|
||||
if (retval == MYSQL_NO_DATA)
|
||||
retval = false;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "AutoPtr.h"
|
||||
#include <ace/Thread_Mutex.h>
|
||||
|
||||
#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;
|
||||
};
|
||||
|
||||
typedef Trinity::AutoPtr<ResultSet, ACE_Thread_Mutex> 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();
|
||||
|
||||
};
|
||||
|
||||
typedef Trinity::AutoPtr<PreparedResultSet, ACE_Thread_Mutex> PreparedQueryResult;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 <ace/Method_Request.h>
|
||||
#include <ace/Activation_Queue.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 ACE_Method_Request
|
||||
{
|
||||
public:
|
||||
SQLOperation(): m_conn(NULL) { }
|
||||
virtual int call()
|
||||
{
|
||||
Execute();
|
||||
return 0;
|
||||
}
|
||||
virtual bool Execute() = 0;
|
||||
virtual void SetConnection(MySQLConnection* con) { m_conn = con; }
|
||||
|
||||
MySQLConnection* m_conn;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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"
|
||||
|
||||
//- 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);
|
||||
}
|
||||
|
||||
void Transaction::PAppend(const char* sql, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char szQuery [MAX_QUERY_LEN];
|
||||
va_start(ap, sql);
|
||||
vsnprintf(szQuery, MAX_QUERY_LEN, sql, ap);
|
||||
va_end(ap);
|
||||
|
||||
Append(szQuery);
|
||||
}
|
||||
|
||||
//- 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()
|
||||
{
|
||||
if (m_conn->ExecuteTransaction(m_trans))
|
||||
return true;
|
||||
|
||||
if (m_conn->GetLastError() == 1213)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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"
|
||||
|
||||
//- 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);
|
||||
void PAppend(const char* sql, ...);
|
||||
|
||||
size_t GetSize() const { return m_queries.size(); }
|
||||
|
||||
protected:
|
||||
void Cleanup();
|
||||
std::list<SQLElementData> m_queries;
|
||||
|
||||
private:
|
||||
bool _cleanedUp;
|
||||
|
||||
};
|
||||
typedef Trinity::AutoPtr<Transaction, ACE_Thread_Mutex> 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();
|
||||
|
||||
SQLTransaction m_trans;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 <ace/Stack_Trace.h>
|
||||
#include <ace/OS_NS_unistd.h>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace Trinity {
|
||||
|
||||
void Assert(char const* file, int line, char const* function, char const* message)
|
||||
{
|
||||
ACE_Stack_Trace st;
|
||||
fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n",
|
||||
file, line, function, message, st.c_str());
|
||||
*((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);
|
||||
ACE_OS::sleep(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
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 AZEROTHCORE_ERRORS_H
|
||||
#define AZEROTHCORE_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 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
|
||||
|
||||
#define WPAssert(cond) do { if (!(cond)) Trinity::Assert(__FILE__, __LINE__, __FUNCTION__, #cond); } while (0)
|
||||
#define WPFatal(cond, msg) do { if (!(cond)) Trinity::Fatal(__FILE__, __LINE__, __FUNCTION__, (msg)); } while (0)
|
||||
#define WPError(cond, msg) do { if (!(cond)) Trinity::Error(__FILE__, __LINE__, __FUNCTION__, (msg)); } while (0)
|
||||
#define WPWarning(cond, msg) do { if (!(cond)) Trinity::Warning(__FILE__, __LINE__, __FUNCTION__, (msg)); } while (0)
|
||||
|
||||
#define ASSERT WPAssert
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,149 +0,0 @@
|
||||
#ifndef _WHEATYEXCEPTIONREPORT_
|
||||
#define _WHEATYEXCEPTIONREPORT_
|
||||
|
||||
#if PLATFORM == PLATFORM_WINDOWS && !defined(__MINGW32__)
|
||||
|
||||
#include <dbghelp.h>
|
||||
#include <set>
|
||||
#if _MSC_VER < 1400
|
||||
# define countof(array) (sizeof(array) / sizeof(array[0]))
|
||||
#else
|
||||
# include <stdlib.h>
|
||||
# define countof _countof
|
||||
#endif // _MSC_VER < 1400
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
const char* const rgBaseType[] =
|
||||
{
|
||||
" <user defined> ", // btNoType = 0,
|
||||
" void ", // btVoid = 1,
|
||||
" 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 ",
|
||||
" unsigned __int8 ",
|
||||
" unsigned __int16 ",
|
||||
" unsigned __int32 ",
|
||||
" unsigned __int64 ",
|
||||
" unsigned __int128 ",
|
||||
" <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;
|
||||
|
||||
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 &, char*, char*);
|
||||
|
||||
static char * FormatOutputValue(char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress);
|
||||
|
||||
static BasicType GetBasicType(DWORD typeIndex, DWORD64 modBase);
|
||||
|
||||
static int __cdecl _tprintf(const TCHAR * format, ...);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
extern WheatyExceptionReport g_WheatyExceptionReport; // global instance of class
|
||||
#endif // _WIN32
|
||||
#endif // _WHEATYEXCEPTIONREPORT_
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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"
|
||||
|
||||
#include <ace/Basic_Types.h>
|
||||
#include <ace/ACE_export.h>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
|
||||
#define OS_WIN
|
||||
#endif
|
||||
|
||||
#define TRINITY_LITTLEENDIAN 0
|
||||
#define TRINITY_BIGENDIAN 1
|
||||
|
||||
#if !defined(TRINITY_ENDIAN)
|
||||
# if defined (ACE_BIG_ENDIAN)
|
||||
# define TRINITY_ENDIAN TRINITY_BIGENDIAN
|
||||
# else //ACE_BYTE_ORDER != ACE_BIG_ENDIAN
|
||||
# define TRINITY_ENDIAN TRINITY_LITTLEENDIAN
|
||||
# endif //ACE_BYTE_ORDER
|
||||
#endif //TRINITY_ENDIAN
|
||||
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
# define TRINITY_PATH_MAX MAX_PATH
|
||||
# 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 ACE_UINT64_FORMAT_SPECIFIER
|
||||
#define UI64LIT(N) ACE_UINT64_LITERAL(N)
|
||||
|
||||
#define SI64FMTD ACE_INT64_FORMAT_SPECIFIER
|
||||
#define SI64LIT(N) ACE_INT64_LITERAL(N)
|
||||
|
||||
#define SIZEFMTD ACE_SIZE_T_FORMAT_SPECIFIER
|
||||
|
||||
typedef ACE_INT64 int64;
|
||||
typedef ACE_INT32 int32;
|
||||
typedef ACE_INT16 int16;
|
||||
typedef ACE_INT8 int8;
|
||||
typedef ACE_UINT64 uint64;
|
||||
typedef ACE_UINT32 uint32;
|
||||
typedef ACE_UINT16 uint16;
|
||||
typedef ACE_UINT8 uint8;
|
||||
|
||||
#endif //TRINITY_DEFINE_H
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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_FACTORY_HOLDER
|
||||
#define TRINITY_FACTORY_HOLDER
|
||||
|
||||
#include "Define.h"
|
||||
#include "Dynamic/TypeList.h"
|
||||
#include "ObjectRegistry.h"
|
||||
|
||||
/** FactoryHolder holds a factory object of a specific type
|
||||
*/
|
||||
template<class T, class Key = std::string>
|
||||
class FactoryHolder
|
||||
{
|
||||
public:
|
||||
typedef ObjectRegistry<FactoryHolder<T, Key >, Key > FactoryHolderRegistry;
|
||||
friend class ACE_Singleton<FactoryHolderRegistry, ACE_Null_Mutex>;
|
||||
typedef ACE_Singleton<FactoryHolderRegistry, ACE_Null_Mutex> FactoryHolderRepository;
|
||||
|
||||
FactoryHolder(Key k) : i_key(k) { }
|
||||
virtual ~FactoryHolder() { }
|
||||
inline Key key() const { return i_key; }
|
||||
|
||||
void RegisterSelf(void) { FactoryHolderRepository::instance()->InsertItem(this, i_key); }
|
||||
void DeregisterSelf(void) { FactoryHolderRepository::instance()->RemoveItem(this, false); }
|
||||
|
||||
/// Abstract Factory create method
|
||||
virtual T* Create(void *data = NULL) const = 0;
|
||||
private:
|
||||
Key i_key;
|
||||
};
|
||||
|
||||
/** Permissible is a classic way of letting the object decide
|
||||
* whether how good they handle things. This is not retricted
|
||||
* to factory selectors.
|
||||
*/
|
||||
template<class T>
|
||||
class Permissible
|
||||
{
|
||||
public:
|
||||
virtual ~Permissible() { }
|
||||
virtual int Permit(const T *) const = 0;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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_HASH_NAMESPACE_H
|
||||
#define TRINITY_HASH_NAMESPACE_H
|
||||
|
||||
#include "Define.h"
|
||||
|
||||
#if COMPILER_HAS_CPP11_SUPPORT
|
||||
# define HASH_NAMESPACE_START namespace std {
|
||||
# define HASH_NAMESPACE_END }
|
||||
#elif defined(_STLPORT_VERSION)
|
||||
# define HASH_NAMESPACE_START namespace std {
|
||||
# define HASH_NAMESPACE_END }
|
||||
#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1600 // VS100
|
||||
# define HASH_NAMESPACE_START namespace std {
|
||||
# define HASH_NAMESPACE_END }
|
||||
#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1500 && _HAS_TR1
|
||||
# define HASH_NAMESPACE_START namespace std { namespace tr1 {
|
||||
# define HASH_NAMESPACE_END } }
|
||||
#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1300
|
||||
# define HASH_NAMESPACE_START namespace stdext {
|
||||
# define HASH_NAMESPACE_END }
|
||||
|
||||
#if !_HAS_TRADITIONAL_STL
|
||||
#ifndef HASH_NAMESPACE
|
||||
#define HASH_NAMESPACE
|
||||
#else
|
||||
|
||||
// can be not used by some platforms, so provide fake forward
|
||||
HASH_NAMESPACE_START
|
||||
|
||||
template<class K>
|
||||
class hash
|
||||
{
|
||||
public:
|
||||
size_t operator() (K const&);
|
||||
};
|
||||
|
||||
HASH_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif COMPILER == COMPILER_INTEL
|
||||
# define HASH_NAMESPACE_START namespace std {
|
||||
# define HASH_NAMESPACE_END }
|
||||
#elif COMPILER == COMPILER_GNU && defined(__clang__) && defined(_LIBCPP_VERSION)
|
||||
# define HASH_NAMESPACE_START namespace std {
|
||||
# define HASH_NAMESPACE_END }
|
||||
#elif COMPILER == COMPILER_GNU && GCC_VERSION > 40200
|
||||
# define HASH_NAMESPACE_START namespace std { namespace tr1 {
|
||||
# define HASH_NAMESPACE_END } }
|
||||
#elif COMPILER == COMPILER_GNU && GCC_VERSION >= 30000
|
||||
# define HASH_NAMESPACE_START namespace __gnu_cxx {
|
||||
# define HASH_NAMESPACE_END }
|
||||
|
||||
#include <ext/hash_fun.h>
|
||||
#include <string>
|
||||
|
||||
HASH_NAMESPACE_START
|
||||
|
||||
template<>
|
||||
class hash<unsigned long long>
|
||||
{
|
||||
public:
|
||||
size_t operator()(const unsigned long long &__x) const { return (size_t)__x; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class hash<T *>
|
||||
{
|
||||
public:
|
||||
size_t operator()(T * const &__x) const { return (size_t)__x; }
|
||||
};
|
||||
|
||||
template<> struct hash<std::string>
|
||||
{
|
||||
size_t operator()(const std::string &__x) const
|
||||
{
|
||||
return hash<char const*>()(__x.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
HASH_NAMESPACE_END
|
||||
|
||||
#else
|
||||
# define HASH_NAMESPACE_START namespace std {
|
||||
# define HASH_NAMESPACE_END }
|
||||
#endif
|
||||
|
||||
#if COMPILER != COMPILER_MICROSOFT
|
||||
|
||||
// Visual Studio use non standard hash calculation function, so provide fake forward for other
|
||||
HASH_NAMESPACE_START
|
||||
|
||||
template<class K>
|
||||
size_t hash_value(K const&);
|
||||
|
||||
HASH_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,245 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 _LINKEDLIST
|
||||
#define _LINKEDLIST
|
||||
|
||||
#include "Define.h"
|
||||
#include <iterator>
|
||||
|
||||
//============================================
|
||||
class LinkedListHead;
|
||||
|
||||
class LinkedListElement
|
||||
{
|
||||
private:
|
||||
friend class LinkedListHead;
|
||||
|
||||
LinkedListElement* iNext;
|
||||
LinkedListElement* iPrev;
|
||||
public:
|
||||
LinkedListElement(): iNext(NULL), iPrev(NULL) { }
|
||||
~LinkedListElement() { delink(); }
|
||||
|
||||
bool hasNext() const { return(iNext && iNext->iNext != NULL); }
|
||||
bool hasPrev() const { return(iPrev && iPrev->iPrev != NULL); }
|
||||
bool isInList() const { return(iNext != NULL && iPrev != NULL); }
|
||||
|
||||
LinkedListElement * next() { return hasNext() ? iNext : NULL; }
|
||||
LinkedListElement const* next() const { return hasNext() ? iNext : NULL; }
|
||||
LinkedListElement * prev() { return hasPrev() ? iPrev : NULL; }
|
||||
LinkedListElement const* prev() const { return hasPrev() ? iPrev : NULL; }
|
||||
|
||||
LinkedListElement * nocheck_next() { return iNext; }
|
||||
LinkedListElement const* nocheck_next() const { return iNext; }
|
||||
LinkedListElement * nocheck_prev() { return iPrev; }
|
||||
LinkedListElement const* nocheck_prev() const { return iPrev; }
|
||||
|
||||
void delink()
|
||||
{
|
||||
if (isInList())
|
||||
{
|
||||
iNext->iPrev = iPrev; iPrev->iNext = iNext; iNext = NULL; iPrev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void insertBefore(LinkedListElement* pElem)
|
||||
{
|
||||
pElem->iNext = this;
|
||||
pElem->iPrev = iPrev;
|
||||
iPrev->iNext = pElem;
|
||||
iPrev = pElem;
|
||||
}
|
||||
|
||||
void insertAfter(LinkedListElement* pElem)
|
||||
{
|
||||
pElem->iPrev = this;
|
||||
pElem->iNext = iNext;
|
||||
iNext->iPrev = pElem;
|
||||
iNext = pElem;
|
||||
}
|
||||
};
|
||||
|
||||
//============================================
|
||||
|
||||
class LinkedListHead
|
||||
{
|
||||
private:
|
||||
LinkedListElement iFirst;
|
||||
LinkedListElement iLast;
|
||||
uint32 iSize;
|
||||
public:
|
||||
LinkedListHead(): iSize(0)
|
||||
{
|
||||
// create empty list
|
||||
|
||||
iFirst.iNext = &iLast;
|
||||
iLast.iPrev = &iFirst;
|
||||
}
|
||||
|
||||
bool isEmpty() const { return(!iFirst.iNext->isInList()); }
|
||||
|
||||
LinkedListElement * getFirst() { return(isEmpty() ? NULL : iFirst.iNext); }
|
||||
LinkedListElement const* getFirst() const { return(isEmpty() ? NULL : iFirst.iNext); }
|
||||
|
||||
LinkedListElement * getLast() { return(isEmpty() ? NULL : iLast.iPrev); }
|
||||
LinkedListElement const* getLast() const { return(isEmpty() ? NULL : iLast.iPrev); }
|
||||
|
||||
void insertFirst(LinkedListElement* pElem)
|
||||
{
|
||||
iFirst.insertAfter(pElem);
|
||||
}
|
||||
|
||||
void insertLast(LinkedListElement* pElem)
|
||||
{
|
||||
iLast.insertBefore(pElem);
|
||||
}
|
||||
|
||||
uint32 getSize() const
|
||||
{
|
||||
if (!iSize)
|
||||
{
|
||||
uint32 result = 0;
|
||||
LinkedListElement const* e = getFirst();
|
||||
while (e)
|
||||
{
|
||||
++result;
|
||||
e = e->next();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else
|
||||
return iSize;
|
||||
}
|
||||
|
||||
void incSize() { ++iSize; }
|
||||
void decSize() { --iSize; }
|
||||
|
||||
template<class _Ty>
|
||||
class Iterator
|
||||
{
|
||||
public:
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef _Ty value_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef ptrdiff_t distance_type;
|
||||
typedef _Ty* pointer;
|
||||
typedef _Ty const* const_pointer;
|
||||
typedef _Ty& reference;
|
||||
typedef _Ty const & const_reference;
|
||||
|
||||
Iterator() : _Ptr(0)
|
||||
{ // construct with null node pointer
|
||||
}
|
||||
|
||||
Iterator(pointer _Pnode) : _Ptr(_Pnode)
|
||||
{ // construct with node pointer _Pnode
|
||||
}
|
||||
|
||||
Iterator& operator=(Iterator const &_Right)
|
||||
{
|
||||
_Ptr = _Right._Ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator& operator=(const_pointer const &_Right)
|
||||
{
|
||||
_Ptr = pointer(_Right);
|
||||
return *this;
|
||||
}
|
||||
|
||||
reference operator*()
|
||||
{ // return designated value
|
||||
return *_Ptr;
|
||||
}
|
||||
|
||||
pointer operator->()
|
||||
{ // return pointer to class object
|
||||
return _Ptr;
|
||||
}
|
||||
|
||||
Iterator& operator++()
|
||||
{ // preincrement
|
||||
_Ptr = _Ptr->next();
|
||||
return (*this);
|
||||
}
|
||||
|
||||
Iterator operator++(int)
|
||||
{ // postincrement
|
||||
iterator _Tmp = *this;
|
||||
++*this;
|
||||
return (_Tmp);
|
||||
}
|
||||
|
||||
Iterator& operator--()
|
||||
{ // predecrement
|
||||
_Ptr = _Ptr->prev();
|
||||
return (*this);
|
||||
}
|
||||
|
||||
Iterator operator--(int)
|
||||
{ // postdecrement
|
||||
iterator _Tmp = *this;
|
||||
--*this;
|
||||
return (_Tmp);
|
||||
}
|
||||
|
||||
bool operator==(Iterator const &_Right) const
|
||||
{ // test for iterator equality
|
||||
return (_Ptr == _Right._Ptr);
|
||||
}
|
||||
|
||||
bool operator!=(Iterator const &_Right) const
|
||||
{ // test for iterator inequality
|
||||
return (!(*this == _Right));
|
||||
}
|
||||
|
||||
bool operator==(pointer const &_Right) const
|
||||
{ // test for pointer equality
|
||||
return (_Ptr != _Right);
|
||||
}
|
||||
|
||||
bool operator!=(pointer const &_Right) const
|
||||
{ // test for pointer equality
|
||||
return (!(*this == _Right));
|
||||
}
|
||||
|
||||
bool operator==(const_reference _Right) const
|
||||
{ // test for reference equality
|
||||
return (_Ptr == &_Right);
|
||||
}
|
||||
|
||||
bool operator!=(const_reference _Right) const
|
||||
{ // test for reference equality
|
||||
return (_Ptr != &_Right);
|
||||
}
|
||||
|
||||
pointer _Mynode()
|
||||
{ // return node pointer
|
||||
return (_Ptr);
|
||||
}
|
||||
|
||||
protected:
|
||||
pointer _Ptr; // pointer to node
|
||||
};
|
||||
|
||||
typedef Iterator<LinkedListElement> iterator;
|
||||
};
|
||||
|
||||
//============================================
|
||||
#endif
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 _REFMANAGER_H
|
||||
#define _REFMANAGER_H
|
||||
//=====================================================
|
||||
|
||||
#include "Dynamic/LinkedList.h"
|
||||
#include "Dynamic/LinkedReference/Reference.h"
|
||||
|
||||
template <class TO, class FROM> class RefManager : public LinkedListHead
|
||||
{
|
||||
public:
|
||||
typedef LinkedListHead::Iterator< Reference<TO, FROM> > iterator;
|
||||
RefManager() { }
|
||||
virtual ~RefManager() { clearReferences(); }
|
||||
|
||||
Reference<TO, FROM>* getFirst() { return ((Reference<TO, FROM>*) LinkedListHead::getFirst()); }
|
||||
Reference<TO, FROM> const* getFirst() const { return ((Reference<TO, FROM> const*) LinkedListHead::getFirst()); }
|
||||
Reference<TO, FROM>* getLast() { return ((Reference<TO, FROM>*) LinkedListHead::getLast()); }
|
||||
Reference<TO, FROM> const* getLast() const { return ((Reference<TO, FROM> const*) LinkedListHead::getLast()); }
|
||||
|
||||
iterator begin() { return iterator(getFirst()); }
|
||||
iterator end() { return iterator(NULL); }
|
||||
iterator rbegin() { return iterator(getLast()); }
|
||||
iterator rend() { return iterator(NULL); }
|
||||
|
||||
void clearReferences()
|
||||
{
|
||||
LinkedListElement* ref;
|
||||
while ((ref = getFirst()) != NULL)
|
||||
{
|
||||
((Reference<TO, FROM>*) ref)->invalidate();
|
||||
ref->delink(); // the delink might be already done by invalidate(), but doing it here again does not hurt and insures an empty list
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//=====================================================
|
||||
#endif
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 _REFERENCE_H
|
||||
#define _REFERENCE_H
|
||||
|
||||
#include "Dynamic/LinkedList.h"
|
||||
#include "Errors.h" // for ASSERT
|
||||
|
||||
//=====================================================
|
||||
|
||||
template <class TO, class FROM> class Reference : public LinkedListElement
|
||||
{
|
||||
private:
|
||||
TO* iRefTo;
|
||||
FROM* iRefFrom;
|
||||
protected:
|
||||
// Tell our refTo (target) object that we have a link
|
||||
virtual void targetObjectBuildLink() = 0;
|
||||
|
||||
// Tell our refTo (taget) object, that the link is cut
|
||||
virtual void targetObjectDestroyLink() = 0;
|
||||
|
||||
// Tell our refFrom (source) object, that the link is cut (Target destroyed)
|
||||
virtual void sourceObjectDestroyLink() = 0;
|
||||
public:
|
||||
Reference() { iRefTo = NULL; iRefFrom = NULL; }
|
||||
virtual ~Reference() { }
|
||||
|
||||
// Create new link
|
||||
void link(TO* toObj, FROM* fromObj)
|
||||
{
|
||||
ASSERT(fromObj); // fromObj MUST not be NULL
|
||||
if (isValid())
|
||||
unlink();
|
||||
if (toObj != NULL)
|
||||
{
|
||||
iRefTo = toObj;
|
||||
iRefFrom = fromObj;
|
||||
targetObjectBuildLink();
|
||||
}
|
||||
}
|
||||
|
||||
// We don't need the reference anymore. Call comes from the refFrom object
|
||||
// Tell our refTo object, that the link is cut
|
||||
void unlink()
|
||||
{
|
||||
targetObjectDestroyLink();
|
||||
delink();
|
||||
iRefTo = NULL;
|
||||
iRefFrom = NULL;
|
||||
}
|
||||
|
||||
// Link is invalid due to destruction of referenced target object. Call comes from the refTo object
|
||||
// Tell our refFrom object, that the link is cut
|
||||
void invalidate() // the iRefFrom MUST remain!!
|
||||
{
|
||||
sourceObjectDestroyLink();
|
||||
delink();
|
||||
iRefTo = NULL;
|
||||
}
|
||||
|
||||
bool isValid() const // Only check the iRefTo
|
||||
{
|
||||
return iRefTo != NULL;
|
||||
}
|
||||
|
||||
Reference<TO, FROM> * next() { return((Reference<TO, FROM> *) LinkedListElement::next()); }
|
||||
Reference<TO, FROM> const* next() const { return((Reference<TO, FROM> const*) LinkedListElement::next()); }
|
||||
Reference<TO, FROM> * prev() { return((Reference<TO, FROM> *) LinkedListElement::prev()); }
|
||||
Reference<TO, FROM> const* prev() const { return((Reference<TO, FROM> const*) LinkedListElement::prev()); }
|
||||
|
||||
Reference<TO, FROM> * nocheck_next() { return((Reference<TO, FROM> *) LinkedListElement::nocheck_next()); }
|
||||
Reference<TO, FROM> const* nocheck_next() const { return((Reference<TO, FROM> const*) LinkedListElement::nocheck_next()); }
|
||||
Reference<TO, FROM> * nocheck_prev() { return((Reference<TO, FROM> *) LinkedListElement::nocheck_prev()); }
|
||||
Reference<TO, FROM> const* nocheck_prev() const { return((Reference<TO, FROM> const*) LinkedListElement::nocheck_prev()); }
|
||||
|
||||
TO* operator ->() const { return iRefTo; }
|
||||
TO* getTarget() const { return iRefTo; }
|
||||
|
||||
FROM* GetSource() const { return iRefFrom; }
|
||||
};
|
||||
|
||||
//=====================================================
|
||||
#endif
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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_OBJECTREGISTRY_H
|
||||
#define TRINITY_OBJECTREGISTRY_H
|
||||
|
||||
#include "Define.h"
|
||||
#include "Dynamic/UnorderedMap.h"
|
||||
#include <ace/Singleton.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
/** ObjectRegistry holds all registry item of the same type
|
||||
*/
|
||||
template<class T, class Key = std::string>
|
||||
class ObjectRegistry
|
||||
{
|
||||
public:
|
||||
typedef std::map<Key, T *> RegistryMapType;
|
||||
|
||||
/// Returns a registry item
|
||||
const T* GetRegistryItem(Key key) const
|
||||
{
|
||||
typename RegistryMapType::const_iterator iter = i_registeredObjects.find(key);
|
||||
return( iter == i_registeredObjects.end() ? NULL : iter->second );
|
||||
}
|
||||
|
||||
/// Inserts a registry item
|
||||
bool InsertItem(T *obj, Key key, bool override = false)
|
||||
{
|
||||
typename RegistryMapType::iterator iter = i_registeredObjects.find(key);
|
||||
if ( iter != i_registeredObjects.end() )
|
||||
{
|
||||
if ( !override )
|
||||
return false;
|
||||
delete iter->second;
|
||||
i_registeredObjects.erase(iter);
|
||||
}
|
||||
|
||||
i_registeredObjects[key] = obj;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Removes a registry item
|
||||
void RemoveItem(Key key, bool delete_object = true)
|
||||
{
|
||||
typename RegistryMapType::iterator iter = i_registeredObjects.find(key);
|
||||
if ( iter != i_registeredObjects.end() )
|
||||
{
|
||||
if ( delete_object )
|
||||
delete iter->second;
|
||||
i_registeredObjects.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if registry contains an item
|
||||
bool HasItem(Key key) const
|
||||
{
|
||||
return (i_registeredObjects.find(key) != i_registeredObjects.end());
|
||||
}
|
||||
|
||||
/// Inefficiently return a vector of registered items
|
||||
unsigned int GetRegisteredItems(std::vector<Key> &l) const
|
||||
{
|
||||
unsigned int sz = l.size();
|
||||
l.resize(sz + i_registeredObjects.size());
|
||||
for (typename RegistryMapType::const_iterator iter = i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter)
|
||||
l[sz++] = iter->first;
|
||||
return i_registeredObjects.size();
|
||||
}
|
||||
|
||||
/// Return the map of registered items
|
||||
RegistryMapType const &GetRegisteredItems() const
|
||||
{
|
||||
return i_registeredObjects;
|
||||
}
|
||||
|
||||
ObjectRegistry() { }
|
||||
~ObjectRegistry()
|
||||
{
|
||||
for (typename RegistryMapType::iterator iter=i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter)
|
||||
delete iter->second;
|
||||
i_registeredObjects.clear();
|
||||
}
|
||||
private:
|
||||
RegistryMapType i_registeredObjects;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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_TYPECONTAINER_H
|
||||
#define TRINITY_TYPECONTAINER_H
|
||||
|
||||
/*
|
||||
* Here, you'll find a series of containers that allow you to hold multiple
|
||||
* types of object at the same time.
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "Define.h"
|
||||
#include "Dynamic/TypeList.h"
|
||||
#include "GridRefManager.h"
|
||||
|
||||
/*
|
||||
* @class ContainerMapList is a mulit-type container for map elements
|
||||
* By itself its meaningless but collaborate along with TypeContainers,
|
||||
* it become the most powerfully container in the whole system.
|
||||
*/
|
||||
template<class OBJECT> struct ContainerMapList
|
||||
{
|
||||
//std::map<OBJECT_HANDLE, OBJECT *> _element;
|
||||
GridRefManager<OBJECT> _element;
|
||||
};
|
||||
|
||||
template<> struct ContainerMapList<TypeNull> /* nothing is in type null */
|
||||
{
|
||||
};
|
||||
template<class H, class T> struct ContainerMapList<TypeList<H, T> >
|
||||
{
|
||||
ContainerMapList<H> _elements;
|
||||
ContainerMapList<T> _TailElements;
|
||||
};
|
||||
|
||||
/*
|
||||
* @class ContaierArrayList is a multi-type container for
|
||||
* array of elements.
|
||||
*/
|
||||
template<class OBJECT> struct ContainerArrayList
|
||||
{
|
||||
std::vector<OBJECT> _element;
|
||||
};
|
||||
|
||||
// termination condition
|
||||
template<> struct ContainerArrayList<TypeNull> { };
|
||||
// recursion
|
||||
template<class H, class T> struct ContainerArrayList<TypeList<H, T> >
|
||||
{
|
||||
ContainerArrayList<H> _elements;
|
||||
ContainerArrayList<T> _TailElements;
|
||||
};
|
||||
|
||||
/*
|
||||
* @class ContainerList is a simple list of different types of elements
|
||||
*
|
||||
*/
|
||||
template<class OBJECT> struct ContainerList
|
||||
{
|
||||
OBJECT _element;
|
||||
};
|
||||
|
||||
/* TypeNull is underfined */
|
||||
template<> struct ContainerList<TypeNull> { };
|
||||
template<class H, class T> struct ContainerList<TypeList<H, T> >
|
||||
{
|
||||
ContainerList<H> _elements;
|
||||
ContainerMapList<T> _TailElements;
|
||||
};
|
||||
|
||||
#include "TypeContainerFunctions.h"
|
||||
|
||||
/*
|
||||
* @class TypeMapContainer contains a fixed number of types and is
|
||||
* determined at compile time. This is probably the most complicated
|
||||
* class and do its simplest thing, that is, holds objects
|
||||
* of different types.
|
||||
*/
|
||||
|
||||
template<class OBJECT_TYPES>
|
||||
class TypeMapContainer
|
||||
{
|
||||
public:
|
||||
template<class SPECIFIC_TYPE> size_t Count() const { return Trinity::Count(i_elements, (SPECIFIC_TYPE*)NULL); }
|
||||
|
||||
/// inserts a specific object into the container
|
||||
template<class SPECIFIC_TYPE> bool insert(SPECIFIC_TYPE *obj)
|
||||
{
|
||||
SPECIFIC_TYPE* t = Trinity::Insert(i_elements, obj);
|
||||
return (t != NULL);
|
||||
}
|
||||
|
||||
/// Removes the object from the container, and returns the removed object
|
||||
//template<class SPECIFIC_TYPE> bool remove(SPECIFIC_TYPE* obj)
|
||||
//{
|
||||
// SPECIFIC_TYPE* t = Trinity::Remove(i_elements, obj);
|
||||
// return (t != NULL);
|
||||
//}
|
||||
|
||||
ContainerMapList<OBJECT_TYPES> & GetElements(void) { return i_elements; }
|
||||
const ContainerMapList<OBJECT_TYPES> & GetElements(void) const { return i_elements;}
|
||||
|
||||
private:
|
||||
ContainerMapList<OBJECT_TYPES> i_elements;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 TYPECONTAINER_FUNCTIONS_H
|
||||
#define TYPECONTAINER_FUNCTIONS_H
|
||||
|
||||
/*
|
||||
* Here you'll find a list of helper functions to make
|
||||
* the TypeContainer usefull. Without it, its hard
|
||||
* to access or mutate the container.
|
||||
*/
|
||||
|
||||
#include "Define.h"
|
||||
#include "Dynamic/TypeList.h"
|
||||
#include <map>
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
/* ContainerMapList Helpers */
|
||||
// count functions
|
||||
template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<SPECIFIC_TYPE> &elements, SPECIFIC_TYPE* /*fake*/)
|
||||
{
|
||||
return elements._element.getSize();
|
||||
}
|
||||
|
||||
template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE* /*fake*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE* /*fake*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<TypeList<SPECIFIC_TYPE, T> >&elements, SPECIFIC_TYPE* fake)
|
||||
{
|
||||
return Count(elements._elements, fake);
|
||||
}
|
||||
|
||||
template<class SPECIFIC_TYPE, class H, class T> size_t Count(const ContainerMapList<TypeList<H, T> >&elements, SPECIFIC_TYPE* fake)
|
||||
{
|
||||
return Count(elements._TailElements, fake);
|
||||
}
|
||||
|
||||
// non-const insert functions
|
||||
template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Insert(ContainerMapList<SPECIFIC_TYPE> &elements, SPECIFIC_TYPE *obj)
|
||||
{
|
||||
//elements._element[hdl] = obj;
|
||||
obj->AddToGrid(elements._element);
|
||||
return obj;
|
||||
}
|
||||
|
||||
template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Insert(ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// this is a missed
|
||||
template<class SPECIFIC_TYPE, class T> SPECIFIC_TYPE* Insert(ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
|
||||
{
|
||||
return NULL; // a missed
|
||||
}
|
||||
|
||||
// Recursion
|
||||
template<class SPECIFIC_TYPE, class H, class T> SPECIFIC_TYPE* Insert(ContainerMapList<TypeList<H, T> >&elements, SPECIFIC_TYPE *obj)
|
||||
{
|
||||
SPECIFIC_TYPE* t= Insert(elements._elements, obj);
|
||||
return (t != NULL ? t : Insert(elements._TailElements, obj));
|
||||
}
|
||||
|
||||
//// non-const remove method
|
||||
//template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Remove(ContainerMapList<SPECIFIC_TYPE> & /*elements*/, SPECIFIC_TYPE *obj)
|
||||
//{
|
||||
// obj->GetGridRef().unlink();
|
||||
// return obj;
|
||||
//}
|
||||
|
||||
//template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Remove(ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
|
||||
//{
|
||||
// return NULL;
|
||||
//}
|
||||
|
||||
//// this is a missed
|
||||
//template<class SPECIFIC_TYPE, class T> SPECIFIC_TYPE* Remove(ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE * /*obj*/)
|
||||
//{
|
||||
// return NULL; // a missed
|
||||
//}
|
||||
|
||||
//template<class SPECIFIC_TYPE, class T, class H> SPECIFIC_TYPE* Remove(ContainerMapList<TypeList<H, T> > &elements, SPECIFIC_TYPE *obj)
|
||||
//{
|
||||
// // The head element is bad
|
||||
// SPECIFIC_TYPE* t = Remove(elements._elements, obj);
|
||||
// return ( t != NULL ? t : Remove(elements._TailElements, obj) );
|
||||
//}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 TYPECONTAINER_FUNCTIONS_PTR_H
|
||||
#define TYPECONTAINER_FUNCTIONS_PTR_H
|
||||
|
||||
/*
|
||||
* Here you'll find a list of helper functions to make
|
||||
* the TypeContainer usefull. Without it, its hard
|
||||
* to access or mutate the container.
|
||||
*/
|
||||
|
||||
#include "Platform/Define.h"
|
||||
#include "Utilities/TypeList.h"
|
||||
#include <map>
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
/* ContainerMapList Helpers */
|
||||
// count functions
|
||||
// template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<SPECIFIC_TYPE> &elements, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
|
||||
// {
|
||||
// return elements._element.size();
|
||||
// };
|
||||
//
|
||||
// template<class SPECIFIC_TYPE> size_t Count(const ContainerMapList<TypeNull> &elements, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
|
||||
// {
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<T> &elements, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
|
||||
// {
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// template<class SPECIFIC_TYPE, class T> size_t Count(const ContainerMapList<TypeList<SPECIFIC_TYPE, T> >&elements, SPECIFIC_TYPE* fake)
|
||||
// {
|
||||
// return Count(elements._elements, fake);
|
||||
// }
|
||||
//
|
||||
// template<class SPECIFIC_TYPE, class H, class T> size_t Count(const ContainerMapList<TypeList<H, T> >&elements, SPECIFIC_TYPE* fake)
|
||||
// {
|
||||
// return Count(elements._TailElements, fake);
|
||||
// }
|
||||
|
||||
// non-const find functions
|
||||
template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<SPECIFIC_TYPE> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
|
||||
{
|
||||
typename std::map<OBJECT_HANDLE, CountedPtr<SPECIFIC_TYPE> >::iterator iter = elements._element.find(hdl);
|
||||
return (iter == elements._element.end() ? NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL) : iter->second);
|
||||
};
|
||||
|
||||
template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<TypeNull> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
|
||||
{
|
||||
return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);// terminate recursion
|
||||
}
|
||||
|
||||
template<class SPECIFIC_TYPE, class T> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<T> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
|
||||
{
|
||||
return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);// this is a missed
|
||||
}
|
||||
|
||||
template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Find(ContainerMapList<TypeList<H, T> >&elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* fake)
|
||||
{
|
||||
CountedPtr<SPECIFIC_TYPE> &t = Find(elements._elements, hdl, fake);
|
||||
return (!t ? Find(elements._TailElements, hdl, fake) : t);
|
||||
}
|
||||
|
||||
// const find functions
|
||||
template<class SPECIFIC_TYPE> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<SPECIFIC_TYPE> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
|
||||
{
|
||||
typename CountedPtr<SPECIFIC_TYPE>::iterator iter = elements._element.find(hdl);
|
||||
return (iter == elements._element.end() ? NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL) : iter->second);
|
||||
};
|
||||
|
||||
template<class SPECIFIC_TYPE> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<TypeNull> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
|
||||
{
|
||||
return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);
|
||||
}
|
||||
|
||||
template<class SPECIFIC_TYPE, class T> const CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<T> &elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* /*fake*/)
|
||||
{
|
||||
return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);
|
||||
}
|
||||
|
||||
template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Find(const ContainerMapList<TypeList<H, T> >&elements, OBJECT_HANDLE hdl, CountedPtr<SPECIFIC_TYPE>* fake)
|
||||
{
|
||||
CountedPtr<SPECIFIC_TYPE> &t = Find(elements._elements, hdl, fake);
|
||||
if (!t)
|
||||
t = Find(elements._TailElement, hdl, fake);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
// non-const insert functions
|
||||
template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<SPECIFIC_TYPE> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
|
||||
{
|
||||
elements._element[hdl] = obj;
|
||||
return obj;
|
||||
};
|
||||
|
||||
template<class SPECIFIC_TYPE> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<TypeNull> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
|
||||
{
|
||||
return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);
|
||||
}
|
||||
|
||||
// this is a missed
|
||||
template<class SPECIFIC_TYPE, class T> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<T> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
|
||||
{
|
||||
return NullPtr<SPECIFIC_TYPE>((SPECIFIC_TYPE*)NULL);// a missed
|
||||
}
|
||||
|
||||
// Recursion
|
||||
template<class SPECIFIC_TYPE, class H, class T> CountedPtr<SPECIFIC_TYPE>& Insert(ContainerMapList<TypeList<H, T> >&elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
|
||||
{
|
||||
CountedPtr<SPECIFIC_TYPE> &t= Insert(elements._elements, obj, hdl);
|
||||
return (!t ? Insert(elements._TailElements, obj, hdl) : t);
|
||||
}
|
||||
|
||||
// non-const remove method
|
||||
template<class SPECIFIC_TYPE> bool Remove(ContainerMapList<SPECIFIC_TYPE> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
|
||||
{
|
||||
typename std::map<OBJECT_HANDLE, CountedPtr<SPECIFIC_TYPE> >::iterator iter = elements._element.find(hdl);
|
||||
if ( iter != elements._element.end() )
|
||||
{
|
||||
elements._element.erase(iter);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // found... terminate the search
|
||||
}
|
||||
|
||||
template<class SPECIFIC_TYPE> bool Remove(ContainerMapList<TypeNull> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// this is a missed
|
||||
template<class SPECIFIC_TYPE, class T> bool Remove(ContainerMapList<T> &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class SPECIFIC_TYPE, class T, class H> bool Remove(ContainerMapList<TypeList<H, T> > &elements, CountedPtr<SPECIFIC_TYPE> &obj, OBJECT_HANDLE hdl)
|
||||
{
|
||||
// The head element is bad
|
||||
bool t = Remove(elements._elements, obj, hdl);
|
||||
return ( !t ? Remove(elements._TailElements, obj, hdl) : t );
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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_TYPECONTAINERVISITOR_H
|
||||
#define TRINITY_TYPECONTAINERVISITOR_H
|
||||
|
||||
/*
|
||||
* @class TypeContainerVisitor is implemented as a visitor pattern. It is
|
||||
* a visitor to the TypeContainerList or TypeContainerMapList. The visitor has
|
||||
* to overload its types as a visit method is called.
|
||||
*/
|
||||
|
||||
#include "Define.h"
|
||||
#include "Dynamic/TypeContainer.h"
|
||||
|
||||
// forward declaration
|
||||
template<class T, class Y> class TypeContainerVisitor;
|
||||
|
||||
// visitor helper
|
||||
template<class VISITOR, class TYPE_CONTAINER> void VisitorHelper(VISITOR &v, TYPE_CONTAINER &c)
|
||||
{
|
||||
v.Visit(c);
|
||||
}
|
||||
|
||||
// terminate condition for container list
|
||||
template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerList<TypeNull> &/*c*/) { }
|
||||
|
||||
template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerList<T> &c)
|
||||
{
|
||||
v.Visit(c._element);
|
||||
}
|
||||
|
||||
// recursion for container list
|
||||
template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerList<TypeList<H, T> > &c)
|
||||
{
|
||||
VisitorHelper(v, c._elements);
|
||||
VisitorHelper(v, c._TailElements);
|
||||
}
|
||||
|
||||
// terminate condition container map list
|
||||
template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerMapList<TypeNull> &/*c*/) { }
|
||||
|
||||
template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerMapList<T> &c)
|
||||
{
|
||||
v.Visit(c._element);
|
||||
}
|
||||
|
||||
// recursion container map list
|
||||
template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerMapList<TypeList<H, T> > &c)
|
||||
{
|
||||
VisitorHelper(v, c._elements);
|
||||
VisitorHelper(v, c._TailElements);
|
||||
}
|
||||
|
||||
// array list
|
||||
template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerArrayList<T> &c)
|
||||
{
|
||||
v.Visit(c._element);
|
||||
}
|
||||
|
||||
template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerArrayList<TypeNull> &/*c*/) { }
|
||||
|
||||
// recursion
|
||||
template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerArrayList<TypeList<H, T> > &c)
|
||||
{
|
||||
VisitorHelper(v, c._elements);
|
||||
VisitorHelper(v, c._TailElements);
|
||||
}
|
||||
|
||||
// for TypeMapContainer
|
||||
template<class VISITOR, class OBJECT_TYPES> void VisitorHelper(VISITOR &v, TypeMapContainer<OBJECT_TYPES> &c)
|
||||
{
|
||||
VisitorHelper(v, c.GetElements());
|
||||
}
|
||||
|
||||
template<class VISITOR, class TYPE_CONTAINER>
|
||||
class TypeContainerVisitor
|
||||
{
|
||||
public:
|
||||
TypeContainerVisitor(VISITOR &v) : i_visitor(v) { }
|
||||
|
||||
void Visit(TYPE_CONTAINER &c)
|
||||
{
|
||||
VisitorHelper(i_visitor, c);
|
||||
}
|
||||
|
||||
void Visit(const TYPE_CONTAINER &c) const
|
||||
{
|
||||
VisitorHelper(i_visitor, c);
|
||||
}
|
||||
|
||||
private:
|
||||
VISITOR &i_visitor;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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_TYPELIST_H
|
||||
#define TRINITY_TYPELIST_H
|
||||
|
||||
/*
|
||||
@struct TypeList
|
||||
TypeList is the most simple but yet the most powerfull class of all. It holds
|
||||
at compile time the different type of objects in a linked list.
|
||||
*/
|
||||
|
||||
class TypeNull;
|
||||
|
||||
template<typename HEAD, typename TAIL>
|
||||
struct TypeList
|
||||
{
|
||||
typedef HEAD Head;
|
||||
typedef TAIL Tail;
|
||||
};
|
||||
|
||||
// enough for now.. can be expand at any point in time as needed
|
||||
#define TYPELIST_1(T1) TypeList<T1, TypeNull>
|
||||
#define TYPELIST_2(T1, T2) TypeList<T1, TYPELIST_1(T2) >
|
||||
#define TYPELIST_3(T1, T2, T3) TypeList<T1, TYPELIST_2(T2, T3) >
|
||||
#define TYPELIST_4(T1, T2, T3, T4) TypeList<T1, TYPELIST_3(T2, T3, T4) >
|
||||
#define TYPELIST_5(T1, T2, T3, T4, T5) TypeList<T1, TYPELIST_4(T2, T3, T4, T5) >
|
||||
#endif
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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_UNORDERED_MAP_H
|
||||
#define TRINITY_UNORDERED_MAP_H
|
||||
|
||||
#include "HashNamespace.h"
|
||||
|
||||
#if COMPILER_HAS_CPP11_SUPPORT
|
||||
# include <unordered_map>
|
||||
#elif COMPILER == COMPILER_INTEL
|
||||
# include <ext/hash_map>
|
||||
#elif COMPILER == COMPILER_GNU && defined(__clang__) && defined(_LIBCPP_VERSION)
|
||||
# include <unordered_map>
|
||||
#elif COMPILER == COMPILER_GNU && GCC_VERSION > 40200
|
||||
# include <tr1/unordered_map>
|
||||
#elif COMPILER == COMPILER_GNU && GCC_VERSION >= 30000
|
||||
# include <ext/hash_map>
|
||||
#elif COMPILER == COMPILER_MICROSOFT && ((_MSC_VER >= 1500 && _HAS_TR1) || _MSC_VER >= 1700) // VC9.0 SP1 and later
|
||||
# include <unordered_map>
|
||||
#else
|
||||
# include <hash_map>
|
||||
#endif
|
||||
|
||||
#ifdef _STLPORT_VERSION
|
||||
# define UNORDERED_MAP std::hash_map
|
||||
# define UNORDERED_MULTIMAP std::hash_multimap
|
||||
#elif COMPILER_HAS_CPP11_SUPPORT
|
||||
# define UNORDERED_MAP std::unordered_map
|
||||
# define UNORDERED_MULTIMAP std::unordered_multimap
|
||||
#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1600 // VS100
|
||||
# define UNORDERED_MAP std::tr1::unordered_map
|
||||
# define UNORDERED_MULTIMAP std::tr1::unordered_multimap
|
||||
#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1500 && _HAS_TR1
|
||||
# define UNORDERED_MAP std::tr1::unordered_map
|
||||
# define UNORDERED_MULTIMAP std::tr1::unordered_multimap
|
||||
#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1300
|
||||
# define UNORDERED_MAP stdext::hash_map
|
||||
# define UNORDERED_MULTIMAP stdext::hash_multimap
|
||||
#elif COMPILER == COMPILER_INTEL
|
||||
# define UNORDERED_MAP std::hash_map
|
||||
# define UNORDERED_MULTIMAP std::hash_multimap
|
||||
#elif COMPILER == COMPILER_GNU && defined(__clang__) && defined(_LIBCPP_VERSION)
|
||||
# define UNORDERED_MAP std::unordered_map
|
||||
# define UNORDERED_MULTIMAP std::unordered_multimap
|
||||
#elif COMPILER == COMPILER_GNU && GCC_VERSION > 40200
|
||||
# define UNORDERED_MAP std::tr1::unordered_map
|
||||
# define UNORDERED_MULTIMAP std::tr1::unordered_multimap
|
||||
#elif COMPILER == COMPILER_GNU && GCC_VERSION >= 30000
|
||||
# define UNORDERED_MAP __gnu_cxx::hash_map
|
||||
# define UNORDERED_MULTIMAP __gnu_cxx::hash_multimap
|
||||
#else
|
||||
# define UNORDERED_MAP std::hash_map
|
||||
# define UNORDERED_MULTIMAP std::hash_multimap
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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_UNORDERED_SET_H
|
||||
#define TRINITY_UNORDERED_SET_H
|
||||
|
||||
#include "HashNamespace.h"
|
||||
|
||||
#if COMPILER_HAS_CPP11_SUPPORT
|
||||
# include <unordered_set>
|
||||
#elif COMPILER == COMPILER_INTEL
|
||||
# include <ext/hash_set>
|
||||
#elif COMPILER == COMPILER_GNU && defined(__clang__) && defined(_LIBCPP_VERSION)
|
||||
# include <unordered_set>
|
||||
#elif COMPILER == COMPILER_GNU && GCC_VERSION > 40200
|
||||
# include <tr1/unordered_set>
|
||||
#elif COMPILER == COMPILER_GNU && GCC_VERSION >= 30000
|
||||
# include <ext/hash_set>
|
||||
#elif COMPILER == COMPILER_MICROSOFT && ((_MSC_VER >= 1500 && _HAS_TR1) || _MSC_VER >= 1700) // VC9.0 SP1 and later
|
||||
# include <unordered_set>
|
||||
#else
|
||||
# include <hash_set>
|
||||
#endif
|
||||
|
||||
#ifdef _STLPORT_VERSION
|
||||
# define UNORDERED_SET std::hash_set
|
||||
using std::hash_set;
|
||||
#elif COMPILER_HAS_CPP11_SUPPORT
|
||||
# define UNORDERED_SET std::unordered_set
|
||||
#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1600 // VS100
|
||||
# define UNORDERED_SET std::tr1::unordered_set
|
||||
#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1500 && _HAS_TR1
|
||||
# define UNORDERED_SET std::tr1::unordered_set
|
||||
#elif COMPILER == COMPILER_MICROSOFT && _MSC_VER >= 1300
|
||||
# define UNORDERED_SET stdext::hash_set
|
||||
using stdext::hash_set;
|
||||
#elif COMPILER == COMPILER_INTEL
|
||||
# define UNORDERED_SET std::hash_set
|
||||
using std::hash_set;
|
||||
#elif COMPILER == COMPILER_GNU && defined(__clang__) && defined(_LIBCPP_VERSION)
|
||||
# define UNORDERED_SET std::unordered_set
|
||||
#elif COMPILER == COMPILER_GNU && GCC_VERSION > 40200
|
||||
# define UNORDERED_SET std::tr1::unordered_set
|
||||
#elif COMPILER == COMPILER_GNU && GCC_VERSION >= 30000
|
||||
# define UNORDERED_SET __gnu_cxx::hash_set
|
||||
#else
|
||||
# define UNORDERED_SET std::hash_set
|
||||
using std::hash_set;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,987 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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"
|
||||
#include "Log.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Configuration/Config.h"
|
||||
#include "Util.h"
|
||||
#include "SHA1.h"
|
||||
|
||||
#include "Implementation/LoginDatabase.h" // For logging
|
||||
extern LoginDatabaseWorkerPool LoginDatabase;
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <ace/Stack_Trace.h>
|
||||
|
||||
Log::Log() :
|
||||
raLogfile(NULL), logfile(NULL), gmLogfile(NULL), charLogfile(NULL),
|
||||
dberLogfile(NULL), sqlLogFile(NULL), sqlDevLogFile(NULL), miscLogFile(NULL),
|
||||
m_gmlog_per_account(false), m_enableLogDB(false), m_colored(false)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
Log::~Log()
|
||||
{
|
||||
if (logfile != NULL)
|
||||
fclose(logfile);
|
||||
logfile = NULL;
|
||||
|
||||
if (gmLogfile != NULL)
|
||||
fclose(gmLogfile);
|
||||
gmLogfile = NULL;
|
||||
|
||||
if (charLogfile != NULL)
|
||||
fclose(charLogfile);
|
||||
charLogfile = NULL;
|
||||
|
||||
if (dberLogfile != NULL)
|
||||
fclose(dberLogfile);
|
||||
dberLogfile = NULL;
|
||||
|
||||
if (raLogfile != NULL)
|
||||
fclose(raLogfile);
|
||||
raLogfile = NULL;
|
||||
|
||||
if (sqlLogFile != NULL)
|
||||
fclose(sqlLogFile);
|
||||
sqlLogFile = NULL;
|
||||
|
||||
if (sqlDevLogFile != NULL)
|
||||
fclose(sqlDevLogFile);
|
||||
sqlDevLogFile = NULL;
|
||||
|
||||
if (miscLogFile != NULL)
|
||||
fclose(miscLogFile);
|
||||
miscLogFile = NULL;
|
||||
}
|
||||
|
||||
void Log::SetLogLevel(char *Level)
|
||||
{
|
||||
int32 NewLevel = atoi((char*)Level);
|
||||
if (NewLevel < 0)
|
||||
NewLevel = 0;
|
||||
m_logLevel = NewLevel;
|
||||
|
||||
outString("LogLevel is %u", m_logLevel);
|
||||
}
|
||||
|
||||
void Log::SetLogFileLevel(char *Level)
|
||||
{
|
||||
int32 NewLevel = atoi((char*)Level);
|
||||
if (NewLevel < 0)
|
||||
NewLevel = 0;
|
||||
m_logFileLevel = NewLevel;
|
||||
|
||||
outString("LogFileLevel is %u", m_logFileLevel);
|
||||
}
|
||||
|
||||
void Log::Initialize()
|
||||
{
|
||||
/// Check whether we'll log GM commands/RA events/character outputs/chat stuffs
|
||||
m_dbChar = sConfigMgr->GetBoolDefault("LogDB.Char", false);
|
||||
m_dbRA = sConfigMgr->GetBoolDefault("LogDB.RA", false);
|
||||
m_dbGM = sConfigMgr->GetBoolDefault("LogDB.GM", false);
|
||||
|
||||
/// Realm must be 0 by default
|
||||
SetRealmID(0);
|
||||
|
||||
/// Common log files data
|
||||
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('/');
|
||||
|
||||
m_logsTimestamp = "_" + GetTimestampStr();
|
||||
|
||||
/// Open specific log files
|
||||
logfile = openLogFile("LogFile", "LogTimestamp", "w");
|
||||
InitColors(sConfigMgr->GetStringDefault("LogColors", ""));
|
||||
|
||||
m_gmlog_per_account = sConfigMgr->GetBoolDefault("GmLogPerAccount", false);
|
||||
if (!m_gmlog_per_account)
|
||||
gmLogfile = openLogFile("GMLogFile", "GmLogTimestamp", "a");
|
||||
else
|
||||
{
|
||||
// GM log settings for per account case
|
||||
m_gmlog_filename_format = sConfigMgr->GetStringDefault("GMLogFile", "");
|
||||
if (!m_gmlog_filename_format.empty())
|
||||
{
|
||||
bool m_gmlog_timestamp = sConfigMgr->GetBoolDefault("GmLogTimestamp", false);
|
||||
|
||||
size_t dot_pos = m_gmlog_filename_format.find_last_of('.');
|
||||
if (dot_pos!=m_gmlog_filename_format.npos)
|
||||
{
|
||||
if (m_gmlog_timestamp)
|
||||
m_gmlog_filename_format.insert(dot_pos, m_logsTimestamp);
|
||||
|
||||
m_gmlog_filename_format.insert(dot_pos, "_#%u");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gmlog_filename_format += "_#%u";
|
||||
|
||||
if (m_gmlog_timestamp)
|
||||
m_gmlog_filename_format += m_logsTimestamp;
|
||||
}
|
||||
|
||||
m_gmlog_filename_format = m_logsDir + m_gmlog_filename_format;
|
||||
}
|
||||
}
|
||||
|
||||
charLogfile = openLogFile("CharLogFile", "CharLogTimestamp", "a");
|
||||
dberLogfile = openLogFile("DBErrorLogFile", NULL, "a");
|
||||
raLogfile = openLogFile("RaLogFile", NULL, "a");
|
||||
sqlLogFile = openLogFile("SQLDriverLogFile", NULL, "a");
|
||||
sqlDevLogFile = openLogFile("SQLDeveloperLogFile", NULL, "a");
|
||||
miscLogFile = fopen((m_logsDir+"Misc.log").c_str(), "a");
|
||||
|
||||
// Main log file settings
|
||||
m_logLevel = sConfigMgr->GetIntDefault("LogLevel", LOGL_NORMAL);
|
||||
m_logFileLevel = sConfigMgr->GetIntDefault("LogFileLevel", LOGL_NORMAL);
|
||||
m_dbLogLevel = sConfigMgr->GetIntDefault("DBLogLevel", LOGL_NORMAL);
|
||||
m_sqlDriverQueryLogging = sConfigMgr->GetBoolDefault("SQLDriverQueryLogging", false);
|
||||
|
||||
m_DebugLogMask = DebugLogFilters(sConfigMgr->GetIntDefault("DebugLogMask", LOG_FILTER_NONE));
|
||||
|
||||
// Char log settings
|
||||
m_charLog_Dump = sConfigMgr->GetBoolDefault("CharLogDump", false);
|
||||
m_charLog_Dump_Separate = sConfigMgr->GetBoolDefault("CharLogDump.Separate", false);
|
||||
if (m_charLog_Dump_Separate)
|
||||
{
|
||||
m_dumpsDir = sConfigMgr->GetStringDefault("CharLogDump.SeparateDir", "");
|
||||
if (!m_dumpsDir.empty())
|
||||
if ((m_dumpsDir.at(m_dumpsDir.length() - 1) != '/') && (m_dumpsDir.at(m_dumpsDir.length() - 1) != '\\'))
|
||||
m_dumpsDir.push_back('/');
|
||||
}
|
||||
}
|
||||
|
||||
void Log::ReloadConfig()
|
||||
{
|
||||
m_logLevel = sConfigMgr->GetIntDefault("LogLevel", LOGL_NORMAL);
|
||||
m_logFileLevel = sConfigMgr->GetIntDefault("LogFileLevel", LOGL_NORMAL);
|
||||
m_dbLogLevel = sConfigMgr->GetIntDefault("DBLogLevel", LOGL_NORMAL);
|
||||
|
||||
m_DebugLogMask = DebugLogFilters(sConfigMgr->GetIntDefault("DebugLogMask", LOG_FILTER_NONE));
|
||||
}
|
||||
|
||||
FILE* Log::openLogFile(char const* configFileName, char const* configTimeStampFlag, char const* mode)
|
||||
{
|
||||
std::string logfn=sConfigMgr->GetStringDefault(configFileName, "");
|
||||
if (logfn.empty())
|
||||
return NULL;
|
||||
|
||||
if (configTimeStampFlag && sConfigMgr->GetBoolDefault(configTimeStampFlag, false))
|
||||
{
|
||||
size_t dot_pos = logfn.find_last_of(".");
|
||||
if (dot_pos!=logfn.npos)
|
||||
logfn.insert(dot_pos, m_logsTimestamp);
|
||||
else
|
||||
logfn += m_logsTimestamp;
|
||||
}
|
||||
|
||||
return fopen((m_logsDir+logfn).c_str(), mode);
|
||||
}
|
||||
|
||||
FILE* Log::openGmlogPerAccount(uint32 account)
|
||||
{
|
||||
if (m_gmlog_filename_format.empty())
|
||||
return NULL;
|
||||
|
||||
char namebuf[TRINITY_PATH_MAX];
|
||||
snprintf(namebuf, TRINITY_PATH_MAX, m_gmlog_filename_format.c_str(), account);
|
||||
return fopen(namebuf, "a");
|
||||
}
|
||||
|
||||
void Log::outTimestamp(FILE* file)
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
tm* aTm = localtime(&t);
|
||||
// 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)
|
||||
fprintf(file, "%-4d-%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);
|
||||
}
|
||||
|
||||
void Log::InitColors(const std::string& str)
|
||||
{
|
||||
if (str.empty())
|
||||
{
|
||||
m_colored = false;
|
||||
return;
|
||||
}
|
||||
|
||||
int color[4];
|
||||
|
||||
std::istringstream ss(str);
|
||||
|
||||
for (uint8 i = 0; i < LogLevels; ++i)
|
||||
{
|
||||
ss >> color[i];
|
||||
|
||||
if (!ss)
|
||||
return;
|
||||
|
||||
if (color[i] < 0 || color[i] >= Colors)
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint8 i = 0; i < LogLevels; ++i)
|
||||
m_colors[i] = ColorTypes(color[i]);
|
||||
|
||||
m_colored = true;
|
||||
}
|
||||
|
||||
void Log::SetColor(bool stdout_stream, ColorTypes color)
|
||||
{
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
static WORD WinColorFG[Colors] =
|
||||
{
|
||||
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[Colors] =
|
||||
{
|
||||
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 < Colors ? ";1" : ""));
|
||||
#endif
|
||||
}
|
||||
|
||||
void Log::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
|
||||
}
|
||||
|
||||
std::string Log::GetTimestampStr()
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
tm aTm;
|
||||
ACE_OS::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);
|
||||
}
|
||||
|
||||
void Log::outDB(LogTypes type, const char * str)
|
||||
{
|
||||
if (!str || type >= MAX_LOG_TYPES)
|
||||
return;
|
||||
|
||||
std::string logStr(str);
|
||||
if (logStr.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
void Log::outString(const char * str, ...)
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
/*if (m_enableLogDB)
|
||||
{
|
||||
va_list ap2;
|
||||
va_start(ap2, str);
|
||||
char nnew_str[MAX_QUERY_LEN];
|
||||
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
|
||||
outDB(LOG_TYPE_STRING, nnew_str);
|
||||
va_end(ap2);
|
||||
}*/
|
||||
|
||||
if (m_colored)
|
||||
SetColor(true, m_colors[LOGL_NORMAL]);
|
||||
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, str);
|
||||
vutf8printf(stdout, str, &ap);
|
||||
va_end(ap);
|
||||
|
||||
if (m_colored)
|
||||
ResetColor(true);
|
||||
|
||||
printf("\n");
|
||||
if (logfile)
|
||||
{
|
||||
outTimestamp(logfile);
|
||||
va_start(ap, str);
|
||||
vfprintf(logfile, str, ap);
|
||||
fprintf(logfile, "\n");
|
||||
va_end(ap);
|
||||
|
||||
fflush(logfile);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void Log::outString()
|
||||
{
|
||||
printf("\n");
|
||||
if (logfile)
|
||||
{
|
||||
outTimestamp(logfile);
|
||||
fprintf(logfile, "\n");
|
||||
fflush(logfile);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void Log::outCrash(const char * err, ...)
|
||||
{
|
||||
if (!err)
|
||||
return;
|
||||
|
||||
if (m_enableLogDB)
|
||||
{
|
||||
va_list ap2;
|
||||
va_start(ap2, err);
|
||||
char nnew_str[MAX_QUERY_LEN];
|
||||
vsnprintf(nnew_str, MAX_QUERY_LEN, err, ap2);
|
||||
outDB(LOG_TYPE_CRASH, nnew_str);
|
||||
va_end(ap2);
|
||||
}
|
||||
|
||||
if (m_colored)
|
||||
SetColor(false, LRED);
|
||||
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, err);
|
||||
vutf8printf(stderr, err, &ap);
|
||||
va_end(ap);
|
||||
|
||||
if (m_colored)
|
||||
ResetColor(false);
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
if (logfile)
|
||||
{
|
||||
outTimestamp(logfile);
|
||||
fprintf(logfile, "CRASH ALERT: ");
|
||||
|
||||
va_start(ap, err);
|
||||
vfprintf(logfile, err, ap);
|
||||
va_end(ap);
|
||||
|
||||
fprintf(logfile, "\n");
|
||||
fflush(logfile);
|
||||
}
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
void Log::outError(const char * err, ...)
|
||||
{
|
||||
if (!err)
|
||||
return;
|
||||
|
||||
if (m_enableLogDB)
|
||||
{
|
||||
va_list ap2;
|
||||
va_start(ap2, err);
|
||||
char nnew_str[MAX_QUERY_LEN];
|
||||
vsnprintf(nnew_str, MAX_QUERY_LEN, err, ap2);
|
||||
outDB(LOG_TYPE_ERROR, nnew_str);
|
||||
va_end(ap2);
|
||||
}
|
||||
|
||||
if (m_colored)
|
||||
SetColor(false, LRED);
|
||||
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, err);
|
||||
vutf8printf(stderr, err, &ap);
|
||||
va_end(ap);
|
||||
|
||||
if (m_colored)
|
||||
ResetColor(false);
|
||||
|
||||
fprintf( stderr, "\n");
|
||||
if (logfile)
|
||||
{
|
||||
outTimestamp(logfile);
|
||||
fprintf(logfile, "ERROR: ");
|
||||
|
||||
va_start(ap, err);
|
||||
vfprintf(logfile, err, ap);
|
||||
va_end(ap);
|
||||
|
||||
fprintf(logfile, "\n");
|
||||
fflush(logfile);
|
||||
}
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
void Log::outSQLDriver(const char* str, ...)
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
vutf8printf(stdout, str, &ap);
|
||||
va_end(ap);
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (sqlLogFile)
|
||||
{
|
||||
outTimestamp(sqlLogFile);
|
||||
|
||||
va_list apSQL;
|
||||
va_start(apSQL, str);
|
||||
vfprintf(sqlLogFile, str, apSQL);
|
||||
va_end(apSQL);
|
||||
|
||||
fprintf(sqlLogFile, "\n");
|
||||
fflush(sqlLogFile);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void Log::outErrorDb(const char * err, ...)
|
||||
{
|
||||
if (!err)
|
||||
return;
|
||||
|
||||
if (m_colored)
|
||||
SetColor(false, LRED);
|
||||
|
||||
if (m_enableLogDB)
|
||||
{
|
||||
va_list ap2;
|
||||
va_start(ap2, err);
|
||||
char nnew_str[MAX_QUERY_LEN];
|
||||
vsnprintf(nnew_str, MAX_QUERY_LEN, err, ap2);
|
||||
outDB(LOG_TYPE_ERROR, nnew_str);
|
||||
va_end(ap2);
|
||||
}
|
||||
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, err);
|
||||
vutf8printf(stderr, err, &ap);
|
||||
va_end(ap);
|
||||
|
||||
if (m_colored)
|
||||
ResetColor(false);
|
||||
|
||||
fprintf( stderr, "\n" );
|
||||
|
||||
if (logfile)
|
||||
{
|
||||
outTimestamp(logfile);
|
||||
fprintf(logfile, "ERROR: " );
|
||||
|
||||
va_start(ap, err);
|
||||
vfprintf(logfile, err, ap);
|
||||
va_end(ap);
|
||||
|
||||
fprintf(logfile, "\n" );
|
||||
fflush(logfile);
|
||||
}
|
||||
|
||||
if (dberLogfile)
|
||||
{
|
||||
outTimestamp(dberLogfile);
|
||||
va_start(ap, err);
|
||||
vfprintf(dberLogfile, err, ap);
|
||||
va_end(ap);
|
||||
|
||||
fprintf(dberLogfile, "\n" );
|
||||
fflush(dberLogfile);
|
||||
}
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
void Log::outBasic(const char * str, ...)
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
if (m_enableLogDB && m_dbLogLevel > LOGL_NORMAL)
|
||||
{
|
||||
va_list ap2;
|
||||
va_start(ap2, str);
|
||||
char nnew_str[MAX_QUERY_LEN];
|
||||
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
|
||||
outDB(LOG_TYPE_BASIC, nnew_str);
|
||||
va_end(ap2);
|
||||
}
|
||||
|
||||
if (m_logLevel > LOGL_NORMAL)
|
||||
{
|
||||
if (m_colored)
|
||||
SetColor(true, m_colors[LOGL_BASIC]);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
vutf8printf(stdout, str, &ap);
|
||||
va_end(ap);
|
||||
|
||||
if (m_colored)
|
||||
ResetColor(true);
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (logfile)
|
||||
{
|
||||
outTimestamp(logfile);
|
||||
va_list ap2;
|
||||
va_start(ap2, str);
|
||||
vfprintf(logfile, str, ap2);
|
||||
fprintf(logfile, "\n" );
|
||||
va_end(ap2);
|
||||
fflush(logfile);
|
||||
}
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void Log::outDetail(const char * str, ...)
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
if (m_enableLogDB && m_dbLogLevel > LOGL_BASIC)
|
||||
{
|
||||
va_list ap2;
|
||||
va_start(ap2, str);
|
||||
char nnew_str[MAX_QUERY_LEN];
|
||||
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
|
||||
outDB(LOG_TYPE_DETAIL, nnew_str);
|
||||
va_end(ap2);
|
||||
}
|
||||
|
||||
if (m_logLevel > LOGL_BASIC)
|
||||
{
|
||||
if (m_colored)
|
||||
SetColor(true, m_colors[LOGL_DETAIL]);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
vutf8printf(stdout, str, &ap);
|
||||
va_end(ap);
|
||||
|
||||
if (m_colored)
|
||||
ResetColor(true);
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (logfile)
|
||||
{
|
||||
outTimestamp(logfile);
|
||||
va_list ap2;
|
||||
va_start(ap2, str);
|
||||
vfprintf(logfile, str, ap2);
|
||||
va_end(ap2);
|
||||
|
||||
fprintf(logfile, "\n");
|
||||
fflush(logfile);
|
||||
}
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void Log::outSQLDev(const char* str, ...)
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
vutf8printf(stdout, str, &ap);
|
||||
va_end(ap);
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (sqlDevLogFile)
|
||||
{
|
||||
va_list ap2;
|
||||
va_start(ap2, str);
|
||||
vfprintf(sqlDevLogFile, str, ap2);
|
||||
va_end(ap2);
|
||||
|
||||
fprintf(sqlDevLogFile, "\n");
|
||||
fflush(sqlDevLogFile);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void Log::outDebug(DebugLogFilters f, const char * str, ...)
|
||||
{
|
||||
if (!(m_DebugLogMask & f))
|
||||
return;
|
||||
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
if (m_enableLogDB && m_dbLogLevel > LOGL_DETAIL)
|
||||
{
|
||||
va_list ap2;
|
||||
va_start(ap2, str);
|
||||
char nnew_str[MAX_QUERY_LEN];
|
||||
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
|
||||
outDB(LOG_TYPE_DEBUG, nnew_str);
|
||||
va_end(ap2);
|
||||
}
|
||||
|
||||
if ( m_logLevel > LOGL_DETAIL )
|
||||
{
|
||||
if (m_colored)
|
||||
SetColor(true, m_colors[LOGL_DEBUG]);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
vutf8printf(stdout, str, &ap);
|
||||
va_end(ap);
|
||||
|
||||
if (m_colored)
|
||||
ResetColor(true);
|
||||
|
||||
printf( "\n" );
|
||||
|
||||
if (logfile)
|
||||
{
|
||||
outTimestamp(logfile);
|
||||
va_list ap2;
|
||||
va_start(ap2, str);
|
||||
vfprintf(logfile, str, ap2);
|
||||
va_end(ap2);
|
||||
|
||||
fprintf(logfile, "\n" );
|
||||
fflush(logfile);
|
||||
}
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void Log::outStaticDebug(const char * str, ...)
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
if (m_enableLogDB && m_dbLogLevel > LOGL_DETAIL)
|
||||
{
|
||||
va_list ap2;
|
||||
va_start(ap2, str);
|
||||
char nnew_str[MAX_QUERY_LEN];
|
||||
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
|
||||
outDB(LOG_TYPE_DEBUG, nnew_str);
|
||||
va_end(ap2);
|
||||
}
|
||||
|
||||
if ( m_logLevel > LOGL_DETAIL )
|
||||
{
|
||||
if (m_colored)
|
||||
SetColor(true, m_colors[LOGL_DEBUG]);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
vutf8printf(stdout, str, &ap);
|
||||
va_end(ap);
|
||||
|
||||
if (m_colored)
|
||||
ResetColor(true);
|
||||
|
||||
printf( "\n" );
|
||||
|
||||
if (logfile)
|
||||
{
|
||||
outTimestamp(logfile);
|
||||
va_list ap2;
|
||||
va_start(ap2, str);
|
||||
vfprintf(logfile, str, ap2);
|
||||
va_end(ap2);
|
||||
|
||||
fprintf(logfile, "\n" );
|
||||
fflush(logfile);
|
||||
}
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void Log::outStringInLine(const char * str, ...)
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, str);
|
||||
vutf8printf(stdout, str, &ap);
|
||||
va_end(ap);
|
||||
|
||||
if (logfile)
|
||||
{
|
||||
va_start(ap, str);
|
||||
vfprintf(logfile, str, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
|
||||
void Log::outCommand(uint32 account, const char * str, ...)
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
// TODO: support accountid
|
||||
if (m_enableLogDB && m_dbGM)
|
||||
{
|
||||
va_list ap2;
|
||||
va_start(ap2, str);
|
||||
char nnew_str[MAX_QUERY_LEN];
|
||||
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
|
||||
outDB(LOG_TYPE_GM, nnew_str);
|
||||
va_end(ap2);
|
||||
}
|
||||
|
||||
if (m_logLevel > LOGL_NORMAL)
|
||||
{
|
||||
if (m_colored)
|
||||
SetColor(true, m_colors[LOGL_BASIC]);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
vutf8printf(stdout, str, &ap);
|
||||
va_end(ap);
|
||||
|
||||
if (m_colored)
|
||||
ResetColor(true);
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (logfile)
|
||||
{
|
||||
outTimestamp(logfile);
|
||||
va_list ap2;
|
||||
va_start(ap2, str);
|
||||
vfprintf(logfile, str, ap2);
|
||||
fprintf(logfile, "\n" );
|
||||
va_end(ap2);
|
||||
fflush(logfile);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_gmlog_per_account)
|
||||
{
|
||||
if (FILE* per_file = openGmlogPerAccount (account))
|
||||
{
|
||||
outTimestamp(per_file);
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
vfprintf(per_file, str, ap);
|
||||
fprintf(per_file, "\n" );
|
||||
va_end(ap);
|
||||
fclose(per_file);
|
||||
}
|
||||
}
|
||||
else if (gmLogfile)
|
||||
{
|
||||
outTimestamp(gmLogfile);
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
vfprintf(gmLogfile, str, ap);
|
||||
fprintf(gmLogfile, "\n" );
|
||||
va_end(ap);
|
||||
fflush(gmLogfile);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void Log::outChar(const char * str, ...)
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
if (m_enableLogDB && m_dbChar)
|
||||
{
|
||||
va_list ap2;
|
||||
va_start(ap2, str);
|
||||
char nnew_str[MAX_QUERY_LEN];
|
||||
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
|
||||
outDB(LOG_TYPE_CHAR, nnew_str);
|
||||
va_end(ap2);
|
||||
}
|
||||
|
||||
if (charLogfile)
|
||||
{
|
||||
outTimestamp(charLogfile);
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
vfprintf(charLogfile, str, ap);
|
||||
fprintf(charLogfile, "\n" );
|
||||
va_end(ap);
|
||||
fflush(charLogfile);
|
||||
}
|
||||
}
|
||||
|
||||
void Log::outCharDump(const char * str, uint32 account_id, uint32 guid, const char * name)
|
||||
{
|
||||
FILE* file = NULL;
|
||||
if (m_charLog_Dump_Separate)
|
||||
{
|
||||
char fileName[29]; // Max length: name(12) + guid(11) + _.log (5) + \0
|
||||
snprintf(fileName, 29, "%d_%s.log", guid, name);
|
||||
std::string sFileName(m_dumpsDir);
|
||||
sFileName.append(fileName);
|
||||
file = fopen((m_logsDir + sFileName).c_str(), "w");
|
||||
}
|
||||
else
|
||||
file = charLogfile;
|
||||
if (file)
|
||||
{
|
||||
fprintf(file, "== START DUMP == (account: %u guid: %u name: %s )\n%s\n== END DUMP ==\n",
|
||||
account_id, guid, name, str);
|
||||
fflush(file);
|
||||
if (m_charLog_Dump_Separate)
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
void Log::outRemote(const char * str, ...)
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
if (m_enableLogDB && m_dbRA)
|
||||
{
|
||||
va_list ap2;
|
||||
va_start(ap2, str);
|
||||
char nnew_str[MAX_QUERY_LEN];
|
||||
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
|
||||
outDB(LOG_TYPE_RA, nnew_str);
|
||||
va_end(ap2);
|
||||
}
|
||||
|
||||
if (raLogfile)
|
||||
{
|
||||
outTimestamp(raLogfile);
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
vfprintf(raLogfile, str, ap);
|
||||
fprintf(raLogfile, "\n" );
|
||||
va_end(ap);
|
||||
fflush(raLogfile);
|
||||
}
|
||||
}
|
||||
|
||||
void Log::outMisc(const char * str, ...)
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
if (m_enableLogDB)
|
||||
{
|
||||
va_list ap2;
|
||||
va_start(ap2, str);
|
||||
char nnew_str[MAX_QUERY_LEN];
|
||||
vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
|
||||
outDB(LOG_TYPE_PERF, nnew_str);
|
||||
va_end(ap2);
|
||||
}
|
||||
|
||||
if (miscLogFile)
|
||||
{
|
||||
outTimestamp(miscLogFile);
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
vfprintf(miscLogFile, str, ap);
|
||||
fprintf(miscLogFile, "\n" );
|
||||
fflush(miscLogFile);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
@@ -1,207 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 AZEROTHCORE_LOG_H
|
||||
#define AZEROTHCORE_LOG_H
|
||||
|
||||
#include "Common.h"
|
||||
#include <ace/Task.h>
|
||||
#include <ace/Singleton.h>
|
||||
|
||||
class WorldPacket;
|
||||
|
||||
enum DebugLogFilters
|
||||
{
|
||||
LOG_FILTER_NONE = 0x00000000,
|
||||
LOG_FILTER_UNITS = 0x00000001, // Anything related to units that doesn't fit in other categories. ie. creature formations
|
||||
LOG_FILTER_PETS = 0x00000002,
|
||||
LOG_FILTER_VEHICLES = 0x00000004,
|
||||
LOG_FILTER_TSCR = 0x00000008, // C++ AI, instance scripts, etc.
|
||||
LOG_FILTER_DATABASE_AI = 0x00000010, // SmartAI, EventAI, CreatureAI
|
||||
LOG_FILTER_MAPSCRIPTS = 0x00000020,
|
||||
LOG_FILTER_NETWORKIO = 0x00000040, // Anything packet/netcode related
|
||||
LOG_FILTER_SPELLS_AURAS = 0x00000080,
|
||||
LOG_FILTER_ACHIEVEMENTSYS = 0x00000100,
|
||||
LOG_FILTER_CONDITIONSYS = 0x00000200,
|
||||
LOG_FILTER_POOLSYS = 0x00000400,
|
||||
LOG_FILTER_AUCTIONHOUSE = 0x00000800,
|
||||
LOG_FILTER_BATTLEGROUND = 0x00001000, // Anything related to arena's and battlegrounds
|
||||
LOG_FILTER_OUTDOORPVP = 0x00002000,
|
||||
LOG_FILTER_CHATSYS = 0x00004000,
|
||||
LOG_FILTER_LFG = 0x00008000,
|
||||
LOG_FILTER_MAPS = 0x00010000, // Maps, instances, grids, cells, visibility
|
||||
LOG_FILTER_PLAYER_LOADING = 0x00020000, // Debug output from Player::_Load functions
|
||||
LOG_FILTER_PLAYER_ITEMS = 0x00040000, // Anything item related
|
||||
LOG_FILTER_PLAYER_SKILLS = 0x00080000, // Skills related
|
||||
LOG_FILTER_LOOT = 0x00100000, // Loot related
|
||||
LOG_FILTER_GUILD = 0x00200000, // Guild related
|
||||
LOG_FILTER_TRANSPORTS = 0x00400000, // Transport related
|
||||
LOG_FILTER_WARDEN = 0x00800000, // Warden related
|
||||
LOG_FILTER_BATTLEFIELD = 0x01000000, // Battlefield related
|
||||
};
|
||||
|
||||
enum LogTypes
|
||||
{
|
||||
LOG_TYPE_STRING = 0,
|
||||
LOG_TYPE_ERROR = 1,
|
||||
LOG_TYPE_BASIC = 2,
|
||||
LOG_TYPE_DETAIL = 3,
|
||||
LOG_TYPE_DEBUG = 4,
|
||||
LOG_TYPE_CHAR = 5,
|
||||
LOG_TYPE_WORLD = 6,
|
||||
LOG_TYPE_RA = 7,
|
||||
LOG_TYPE_GM = 8,
|
||||
LOG_TYPE_CRASH = 9,
|
||||
LOG_TYPE_CHAT = 10,
|
||||
LOG_TYPE_PERF = 11,
|
||||
LOG_TYPE_MULTITH= 12,
|
||||
MAX_LOG_TYPES
|
||||
};
|
||||
|
||||
enum LogLevel
|
||||
{
|
||||
LOGL_NORMAL = 0,
|
||||
LOGL_BASIC,
|
||||
LOGL_DETAIL,
|
||||
LOGL_DEBUG
|
||||
};
|
||||
|
||||
const int LogLevels = int(LOGL_DEBUG)+1;
|
||||
|
||||
enum ColorTypes
|
||||
{
|
||||
BLACK,
|
||||
RED,
|
||||
GREEN,
|
||||
BROWN,
|
||||
BLUE,
|
||||
MAGENTA,
|
||||
CYAN,
|
||||
GREY,
|
||||
YELLOW,
|
||||
LRED,
|
||||
LGREEN,
|
||||
LBLUE,
|
||||
LMAGENTA,
|
||||
LCYAN,
|
||||
WHITE
|
||||
};
|
||||
|
||||
const int Colors = int(WHITE)+1;
|
||||
|
||||
class Log
|
||||
{
|
||||
friend class ACE_Singleton<Log, ACE_Thread_Mutex>;
|
||||
|
||||
private:
|
||||
Log();
|
||||
~Log();
|
||||
|
||||
public:
|
||||
void Initialize();
|
||||
|
||||
void ReloadConfig();
|
||||
|
||||
void InitColors(const std::string& init_str);
|
||||
void SetColor(bool stdout_stream, ColorTypes color);
|
||||
void ResetColor(bool stdout_stream);
|
||||
|
||||
void outDB(LogTypes type, const char * str);
|
||||
void outString(const char * str, ...) ATTR_PRINTF(2, 3);
|
||||
void outString();
|
||||
void outStringInLine(const char * str, ...) ATTR_PRINTF(2, 3);
|
||||
void outError(const char * err, ...) ATTR_PRINTF(2, 3);
|
||||
void outCrash(const char * err, ...) ATTR_PRINTF(2, 3);
|
||||
void outBasic(const char * str, ...) ATTR_PRINTF(2, 3);
|
||||
void outDetail(const char * str, ...) ATTR_PRINTF(2, 3);
|
||||
void outSQLDev(const char * str, ...) ATTR_PRINTF(2, 3);
|
||||
void outDebug(DebugLogFilters f, const char* str, ...) ATTR_PRINTF(3, 4);
|
||||
void outStaticDebug(const char * str, ...) ATTR_PRINTF(2, 3);
|
||||
void outErrorDb(const char * str, ...) ATTR_PRINTF(2, 3);
|
||||
void outChar(const char * str, ...) ATTR_PRINTF(2, 3);
|
||||
void outCommand(uint32 account, const char * str, ...) ATTR_PRINTF(3, 4);
|
||||
void outRemote(const char * str, ...) ATTR_PRINTF(2, 3);
|
||||
void outSQLDriver(const char* str, ...) ATTR_PRINTF(2, 3);
|
||||
void outMisc(const char * str, ...) ATTR_PRINTF(2, 3); // pussywizard
|
||||
void outCharDump(const char * str, uint32 account_id, uint32 guid, const char * name);
|
||||
|
||||
static void outTimestamp(FILE* file);
|
||||
static std::string GetTimestampStr();
|
||||
|
||||
void SetLogLevel(char * Level);
|
||||
void SetLogFileLevel(char * Level);
|
||||
void SetSQLDriverQueryLogging(bool newStatus) { m_sqlDriverQueryLogging = newStatus; }
|
||||
void SetRealmID(uint32 id) { realm = id; }
|
||||
|
||||
bool IsOutDebug() const { return m_logLevel > 2 || (m_logFileLevel > 2 && logfile); }
|
||||
bool IsOutCharDump() const { return m_charLog_Dump; }
|
||||
|
||||
bool GetLogDB() const { return m_enableLogDB; }
|
||||
void SetLogDB(bool enable) { m_enableLogDB = enable; }
|
||||
bool GetSQLDriverQueryLogging() const { return m_sqlDriverQueryLogging; }
|
||||
private:
|
||||
FILE* openLogFile(char const* configFileName, char const* configTimeStampFlag, char const* mode);
|
||||
FILE* openGmlogPerAccount(uint32 account);
|
||||
|
||||
FILE* raLogfile;
|
||||
FILE* logfile;
|
||||
FILE* gmLogfile;
|
||||
FILE* charLogfile;
|
||||
FILE* dberLogfile;
|
||||
FILE* sqlLogFile;
|
||||
FILE* sqlDevLogFile;
|
||||
FILE* miscLogFile;
|
||||
|
||||
// cache values for after initilization use (like gm log per account case)
|
||||
std::string m_logsDir;
|
||||
std::string m_logsTimestamp;
|
||||
|
||||
// gm log control
|
||||
bool m_gmlog_per_account;
|
||||
std::string m_gmlog_filename_format;
|
||||
|
||||
bool m_enableLogDB;
|
||||
uint32 realm;
|
||||
|
||||
// log coloring
|
||||
bool m_colored;
|
||||
ColorTypes m_colors[4];
|
||||
|
||||
// log levels:
|
||||
// false: errors only, true: full query logging
|
||||
bool m_sqlDriverQueryLogging;
|
||||
|
||||
// log levels:
|
||||
// 0 minimum/string, 1 basic/error, 2 detail, 3 full/debug
|
||||
uint8 m_dbLogLevel;
|
||||
uint8 m_logLevel;
|
||||
uint8 m_logFileLevel;
|
||||
bool m_dbChar;
|
||||
bool m_dbRA;
|
||||
bool m_dbGM;
|
||||
bool m_charLog_Dump;
|
||||
bool m_charLog_Dump_Separate;
|
||||
std::string m_dumpsDir;
|
||||
|
||||
DebugLogFilters m_DebugLogMask;
|
||||
};
|
||||
|
||||
#define sLog ACE_Singleton<Log, ACE_Thread_Mutex>::instance()
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "ByteBuffer.h"
|
||||
#include "Common.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <ace/Stack_Trace.h>
|
||||
#include <sstream>
|
||||
|
||||
ByteBufferPositionException::ByteBufferPositionException(bool add, size_t pos,
|
||||
size_t size, size_t valueSize)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
|
||||
ss << "Attempted to " << (add ? "put" : "get") << " value with size: "
|
||||
<< valueSize << " in ByteBuffer (pos: " << pos << " size: " << size
|
||||
<< ")";
|
||||
|
||||
message().assign(ss.str());
|
||||
}
|
||||
|
||||
ByteBufferSourceException::ByteBufferSourceException(size_t pos, size_t size,
|
||||
size_t valueSize)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
|
||||
ss << "Attempted to put a "
|
||||
<< (valueSize > 0 ? "NULL-pointer" : "zero-sized value")
|
||||
<< " in ByteBuffer (pos: " << pos << " size: " << size << ")";
|
||||
|
||||
message().assign(ss.str());
|
||||
}
|
||||
|
||||
void ByteBuffer::hexlike(bool outString) const
|
||||
{
|
||||
if (!outString)
|
||||
return;
|
||||
|
||||
uint32 j = 1, k = 1;
|
||||
|
||||
std::ostringstream o;
|
||||
o << "STORAGE_SIZE: " << size() << "\nCONTENTS:\n";
|
||||
|
||||
for (uint32 i = 0; i < size(); ++i)
|
||||
{
|
||||
char buf[3];
|
||||
snprintf(buf, 3, "%02X", read<uint8>(i));
|
||||
if ((i == (j * 8)) && ((i != (k * 16))))
|
||||
{
|
||||
o << "| ";
|
||||
++j;
|
||||
}
|
||||
else if (i == (k * 16))
|
||||
{
|
||||
o << "\n";
|
||||
++k;
|
||||
++j;
|
||||
}
|
||||
|
||||
o << buf << " ";
|
||||
}
|
||||
o << " ";
|
||||
|
||||
sLog->outString("%s", o.str().c_str());
|
||||
}
|
||||
@@ -1,631 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 _BYTEBUFFER_H
|
||||
#define _BYTEBUFFER_H
|
||||
|
||||
#include "Define.h"
|
||||
#include "Errors.h"
|
||||
#include "ByteConverter.h"
|
||||
|
||||
#include <ace/OS_NS_time.h>
|
||||
#include <exception>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <time.h>
|
||||
|
||||
// Root of ByteBuffer exception hierarchy
|
||||
class ByteBufferException : public std::exception
|
||||
{
|
||||
public:
|
||||
~ByteBufferException() throw() { }
|
||||
|
||||
char const* what() const throw() { return msg_.c_str(); }
|
||||
|
||||
protected:
|
||||
std::string & message() throw() { return msg_; }
|
||||
|
||||
private:
|
||||
std::string msg_;
|
||||
};
|
||||
|
||||
class ByteBufferPositionException : public ByteBufferException
|
||||
{
|
||||
public:
|
||||
ByteBufferPositionException(bool add, size_t pos, size_t size, size_t valueSize);
|
||||
|
||||
~ByteBufferPositionException() throw() { }
|
||||
};
|
||||
|
||||
class ByteBufferSourceException : public ByteBufferException
|
||||
{
|
||||
public:
|
||||
ByteBufferSourceException(size_t pos, size_t size, size_t valueSize);
|
||||
|
||||
~ByteBufferSourceException() throw() { }
|
||||
};
|
||||
|
||||
class ByteBuffer
|
||||
{
|
||||
public:
|
||||
const static size_t DEFAULT_SIZE = 0x1000;
|
||||
|
||||
// constructor
|
||||
ByteBuffer() : _rpos(0), _wpos(0)
|
||||
{
|
||||
_storage.reserve(DEFAULT_SIZE);
|
||||
}
|
||||
|
||||
ByteBuffer(size_t reserve) : _rpos(0), _wpos(0)
|
||||
{
|
||||
_storage.reserve(reserve);
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
ByteBuffer(const ByteBuffer &buf) : _rpos(buf._rpos), _wpos(buf._wpos),
|
||||
_storage(buf._storage)
|
||||
{
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
_storage.clear();
|
||||
_rpos = _wpos = 0;
|
||||
}
|
||||
|
||||
template <typename T> void append(T value)
|
||||
{
|
||||
EndianConvert(value);
|
||||
append((uint8 *)&value, sizeof(value));
|
||||
}
|
||||
|
||||
template <typename T> void put(size_t pos, T value)
|
||||
{
|
||||
EndianConvert(value);
|
||||
put(pos, (uint8 *)&value, sizeof(value));
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(uint8 value)
|
||||
{
|
||||
append<uint8>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(uint16 value)
|
||||
{
|
||||
append<uint16>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(uint32 value)
|
||||
{
|
||||
append<uint32>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(uint64 value)
|
||||
{
|
||||
append<uint64>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// signed as in 2e complement
|
||||
ByteBuffer &operator<<(int8 value)
|
||||
{
|
||||
append<int8>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(int16 value)
|
||||
{
|
||||
append<int16>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(int32 value)
|
||||
{
|
||||
append<int32>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(int64 value)
|
||||
{
|
||||
append<int64>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// floating points
|
||||
ByteBuffer &operator<<(float value)
|
||||
{
|
||||
append<float>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(double value)
|
||||
{
|
||||
append<double>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(const std::string &value)
|
||||
{
|
||||
if (size_t len = value.length())
|
||||
append((uint8 const*)value.c_str(), len);
|
||||
append((uint8)0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator<<(const char *str)
|
||||
{
|
||||
if (size_t len = (str ? strlen(str) : 0))
|
||||
append((uint8 const*)str, len);
|
||||
append((uint8)0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(bool &value)
|
||||
{
|
||||
value = read<char>() > 0 ? true : false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(uint8 &value)
|
||||
{
|
||||
value = read<uint8>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(uint16 &value)
|
||||
{
|
||||
value = read<uint16>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(uint32 &value)
|
||||
{
|
||||
value = read<uint32>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(uint64 &value)
|
||||
{
|
||||
value = read<uint64>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
//signed as in 2e complement
|
||||
ByteBuffer &operator>>(int8 &value)
|
||||
{
|
||||
value = read<int8>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(int16 &value)
|
||||
{
|
||||
value = read<int16>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(int32 &value)
|
||||
{
|
||||
value = read<int32>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(int64 &value)
|
||||
{
|
||||
value = read<int64>();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(float &value)
|
||||
{
|
||||
value = read<float>();
|
||||
if (!myisfinite(value))
|
||||
{
|
||||
value = 0.0f;
|
||||
//throw ByteBufferException();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(double &value)
|
||||
{
|
||||
value = read<double>();
|
||||
if (!myisfinite(value))
|
||||
{
|
||||
value = 0.0f;
|
||||
//throw ByteBufferException();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteBuffer &operator>>(std::string& value)
|
||||
{
|
||||
value.clear();
|
||||
while (rpos() < size()) // prevent crash at wrong string format in packet
|
||||
{
|
||||
char c = read<char>();
|
||||
if (c == 0)
|
||||
break;
|
||||
value += c;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint8& operator[](size_t const pos)
|
||||
{
|
||||
if (pos >= size())
|
||||
throw ByteBufferPositionException(false, pos, 1, size());
|
||||
return _storage[pos];
|
||||
}
|
||||
|
||||
uint8 const& operator[](size_t const pos) const
|
||||
{
|
||||
if (pos >= size())
|
||||
throw ByteBufferPositionException(false, pos, 1, size());
|
||||
return _storage[pos];
|
||||
}
|
||||
|
||||
size_t rpos() const { return _rpos; }
|
||||
|
||||
size_t rpos(size_t rpos_)
|
||||
{
|
||||
_rpos = rpos_;
|
||||
return _rpos;
|
||||
}
|
||||
|
||||
void rfinish()
|
||||
{
|
||||
_rpos = wpos();
|
||||
}
|
||||
|
||||
size_t wpos() const { return _wpos; }
|
||||
|
||||
size_t wpos(size_t wpos_)
|
||||
{
|
||||
_wpos = wpos_;
|
||||
return _wpos;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void read_skip() { read_skip(sizeof(T)); }
|
||||
|
||||
void read_skip(size_t skip)
|
||||
{
|
||||
if (_rpos + skip > size())
|
||||
throw ByteBufferPositionException(false, _rpos, skip, size());
|
||||
_rpos += skip;
|
||||
}
|
||||
|
||||
template <typename T> T read()
|
||||
{
|
||||
T r = read<T>(_rpos);
|
||||
_rpos += sizeof(T);
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename T> T read(size_t pos) const
|
||||
{
|
||||
if (pos + sizeof(T) > size())
|
||||
throw ByteBufferPositionException(false, pos, sizeof(T), size());
|
||||
T val = *((T const*)&_storage[pos]);
|
||||
EndianConvert(val);
|
||||
return val;
|
||||
}
|
||||
|
||||
void read(uint8 *dest, size_t len)
|
||||
{
|
||||
if (_rpos + len > size())
|
||||
throw ByteBufferPositionException(false, _rpos, len, size());
|
||||
std::memcpy(dest, &_storage[_rpos], len);
|
||||
_rpos += len;
|
||||
}
|
||||
|
||||
void readPackGUID(uint64& guid)
|
||||
{
|
||||
if (rpos() + 1 > size())
|
||||
throw ByteBufferPositionException(false, _rpos, 1, size());
|
||||
|
||||
guid = 0;
|
||||
|
||||
uint8 guidmark = 0;
|
||||
(*this) >> guidmark;
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
if (guidmark & (uint8(1) << i))
|
||||
{
|
||||
if (rpos() + 1 > size())
|
||||
throw ByteBufferPositionException(false, _rpos, 1, size());
|
||||
|
||||
uint8 bit;
|
||||
(*this) >> bit;
|
||||
guid |= (uint64(bit) << (i * 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 ReadPackedTime()
|
||||
{
|
||||
uint32 packedDate = read<uint32>();
|
||||
tm lt = tm();
|
||||
|
||||
lt.tm_min = packedDate & 0x3F;
|
||||
lt.tm_hour = (packedDate >> 6) & 0x1F;
|
||||
//lt.tm_wday = (packedDate >> 11) & 7;
|
||||
lt.tm_mday = ((packedDate >> 14) & 0x3F) + 1;
|
||||
lt.tm_mon = (packedDate >> 20) & 0xF;
|
||||
lt.tm_year = ((packedDate >> 24) & 0x1F) + 100;
|
||||
|
||||
#ifdef OS_WIN
|
||||
return uint32(mktime(<) + _timezone);
|
||||
#else
|
||||
return uint32(mktime(<) + timezone);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
ByteBuffer& ReadPackedTime(uint32& time)
|
||||
{
|
||||
time = ReadPackedTime();
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint8 * contents()
|
||||
{
|
||||
if (_storage.empty())
|
||||
throw ByteBufferException();
|
||||
return &_storage[0];
|
||||
}
|
||||
|
||||
const uint8 *contents() const
|
||||
{
|
||||
if (_storage.empty())
|
||||
throw ByteBufferException();
|
||||
return &_storage[0];
|
||||
}
|
||||
|
||||
size_t size() const { return _storage.size(); }
|
||||
bool empty() const { return _storage.empty(); }
|
||||
|
||||
void resize(size_t newsize)
|
||||
{
|
||||
_storage.resize(newsize, 0);
|
||||
_rpos = 0;
|
||||
_wpos = size();
|
||||
}
|
||||
|
||||
void reserve(size_t ressize)
|
||||
{
|
||||
if (ressize > size())
|
||||
_storage.reserve(ressize);
|
||||
}
|
||||
|
||||
void append(const char *src, size_t cnt)
|
||||
{
|
||||
return append((const uint8 *)src, cnt);
|
||||
}
|
||||
|
||||
template<class T> void append(const T *src, size_t cnt)
|
||||
{
|
||||
return append((const uint8 *)src, cnt * sizeof(T));
|
||||
}
|
||||
|
||||
void append(const uint8 *src, size_t cnt)
|
||||
{
|
||||
if (!cnt)
|
||||
throw ByteBufferSourceException(_wpos, size(), cnt);
|
||||
|
||||
if (!src)
|
||||
throw ByteBufferSourceException(_wpos, size(), cnt);
|
||||
|
||||
ASSERT(size() < 10000000);
|
||||
|
||||
size_t newsize = _wpos + cnt;
|
||||
|
||||
if (_storage.capacity() < newsize) // pussywizard
|
||||
{
|
||||
if (newsize < 100)
|
||||
_storage.reserve(300);
|
||||
else if (newsize < 750)
|
||||
_storage.reserve(2500);
|
||||
else if (newsize < 6000)
|
||||
_storage.reserve(10000);
|
||||
else
|
||||
_storage.reserve(400000);
|
||||
}
|
||||
|
||||
if (_storage.size() < newsize)
|
||||
_storage.resize(newsize);
|
||||
|
||||
memcpy(&_storage[_wpos], src, cnt);
|
||||
_wpos = newsize;
|
||||
}
|
||||
|
||||
void append(const ByteBuffer& buffer)
|
||||
{
|
||||
if (buffer.wpos())
|
||||
append(buffer.contents(), buffer.wpos());
|
||||
}
|
||||
|
||||
// can be used in SMSG_MONSTER_MOVE opcode
|
||||
void appendPackXYZ(float x, float y, float z)
|
||||
{
|
||||
uint32 packed = 0;
|
||||
packed |= ((int)(x / 0.25f) & 0x7FF);
|
||||
packed |= ((int)(y / 0.25f) & 0x7FF) << 11;
|
||||
packed |= ((int)(z / 0.25f) & 0x3FF) << 22;
|
||||
*this << packed;
|
||||
}
|
||||
|
||||
void appendPackGUID(uint64 guid)
|
||||
{
|
||||
uint8 packGUID[8+1];
|
||||
packGUID[0] = 0;
|
||||
size_t size = 1;
|
||||
for (uint8 i = 0;guid != 0;++i)
|
||||
{
|
||||
if (guid & 0xFF)
|
||||
{
|
||||
packGUID[0] |= uint8(1 << i);
|
||||
packGUID[size] = uint8(guid & 0xFF);
|
||||
++size;
|
||||
}
|
||||
|
||||
guid >>= 8;
|
||||
}
|
||||
append(packGUID, size);
|
||||
}
|
||||
|
||||
void AppendPackedTime(time_t time)
|
||||
{
|
||||
tm lt;
|
||||
ACE_OS::localtime_r(&time, <);
|
||||
append<uint32>((lt.tm_year - 100) << 24 | lt.tm_mon << 20 | (lt.tm_mday - 1) << 14 | lt.tm_wday << 11 | lt.tm_hour << 6 | lt.tm_min);
|
||||
}
|
||||
|
||||
void put(size_t pos, const uint8 *src, size_t cnt)
|
||||
{
|
||||
if (pos + cnt > size())
|
||||
throw ByteBufferPositionException(true, pos, cnt, size());
|
||||
|
||||
if (!src)
|
||||
throw ByteBufferSourceException(_wpos, size(), cnt);
|
||||
|
||||
std::memcpy(&_storage[pos], src, cnt);
|
||||
}
|
||||
|
||||
void hexlike(bool outString = false) const;
|
||||
|
||||
protected:
|
||||
size_t _rpos, _wpos;
|
||||
std::vector<uint8> _storage;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline ByteBuffer &operator<<(ByteBuffer &b, std::vector<T> v)
|
||||
{
|
||||
b << (uint32)v.size();
|
||||
for (typename std::vector<T>::iterator i = v.begin(); i != v.end(); ++i)
|
||||
{
|
||||
b << *i;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline ByteBuffer &operator>>(ByteBuffer &b, std::vector<T> &v)
|
||||
{
|
||||
uint32 vsize;
|
||||
b >> vsize;
|
||||
v.clear();
|
||||
while (vsize--)
|
||||
{
|
||||
T t;
|
||||
b >> t;
|
||||
v.push_back(t);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline ByteBuffer &operator<<(ByteBuffer &b, std::list<T> v)
|
||||
{
|
||||
b << (uint32)v.size();
|
||||
for (typename std::list<T>::iterator i = v.begin(); i != v.end(); ++i)
|
||||
{
|
||||
b << *i;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline ByteBuffer &operator>>(ByteBuffer &b, std::list<T> &v)
|
||||
{
|
||||
uint32 vsize;
|
||||
b >> vsize;
|
||||
v.clear();
|
||||
while (vsize--)
|
||||
{
|
||||
T t;
|
||||
b >> t;
|
||||
v.push_back(t);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
inline ByteBuffer &operator<<(ByteBuffer &b, std::map<K, V> &m)
|
||||
{
|
||||
b << (uint32)m.size();
|
||||
for (typename std::map<K, V>::iterator i = m.begin(); i != m.end(); ++i)
|
||||
{
|
||||
b << i->first << i->second;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
inline ByteBuffer &operator>>(ByteBuffer &b, std::map<K, V> &m)
|
||||
{
|
||||
uint32 msize;
|
||||
b >> msize;
|
||||
m.clear();
|
||||
while (msize--)
|
||||
{
|
||||
K k;
|
||||
V v;
|
||||
b >> k >> v;
|
||||
m.insert(make_pair(k, v));
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/// @todo Make a ByteBuffer.cpp and move all this inlining to it.
|
||||
template<> inline std::string ByteBuffer::read<std::string>()
|
||||
{
|
||||
std::string tmp;
|
||||
*this >> tmp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void ByteBuffer::read_skip<char*>()
|
||||
{
|
||||
std::string temp;
|
||||
*this >> temp;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void ByteBuffer::read_skip<char const*>()
|
||||
{
|
||||
read_skip<char*>();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void ByteBuffer::read_skip<std::string>()
|
||||
{
|
||||
read_skip<char*>();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 AZEROTHCORE_WORLDPACKET_H
|
||||
#define AZEROTHCORE_WORLDPACKET_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "ByteBuffer.h"
|
||||
|
||||
class WorldPacket : public ByteBuffer
|
||||
{
|
||||
public:
|
||||
// just container for later use
|
||||
WorldPacket() : ByteBuffer(0), m_opcode(0)
|
||||
{
|
||||
}
|
||||
explicit WorldPacket(uint16 opcode, size_t res=200) : ByteBuffer(res), m_opcode(opcode) { }
|
||||
// copy constructor
|
||||
WorldPacket(const WorldPacket &packet) : ByteBuffer(packet), m_opcode(packet.m_opcode)
|
||||
{
|
||||
}
|
||||
|
||||
void Initialize(uint16 opcode, size_t newres=200)
|
||||
{
|
||||
clear();
|
||||
_storage.reserve(newres);
|
||||
m_opcode = opcode;
|
||||
}
|
||||
|
||||
uint16 GetOpcode() const { return m_opcode; }
|
||||
void SetOpcode(uint16 opcode) { m_opcode = opcode; }
|
||||
|
||||
protected:
|
||||
uint16 m_opcode;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#include "sharedPCH.h"
|
||||
@@ -1,8 +0,0 @@
|
||||
//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"
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
// THIS FILE IS DEPRECATED
|
||||
|
||||
#ifndef TRINITY_SYSTEMCONFIG_H
|
||||
#define TRINITY_SYSTEMCONFIG_H
|
||||
|
||||
#include "Define.h"
|
||||
#include "revision.h"
|
||||
|
||||
#define _PACKAGENAME "AzerothCore"
|
||||
|
||||
#if TRINITY_ENDIAN == TRINITY_BIGENDIAN
|
||||
# define _ENDIAN_STRING "big-endian"
|
||||
#else
|
||||
# define _ENDIAN_STRING "little-endian"
|
||||
#endif
|
||||
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
# ifdef _WIN64
|
||||
# define _FULLVERSION _PACKAGENAME " rev. " VER_PRODUCTVERSION_STR " (Win64, " _BUILD_DIRECTIVE ")"
|
||||
# else
|
||||
# define _FULLVERSION _PACKAGENAME " rev. " VER_PRODUCTVERSION_STR " (Win32, " _BUILD_DIRECTIVE ")"
|
||||
# endif
|
||||
#else
|
||||
# define _FULLVERSION _PACKAGENAME " rev. " VER_PRODUCTVERSION_STR " (Unix, " _BUILD_DIRECTIVE ")"
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,310 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 <ace/Future.h>
|
||||
#include <ace/Future_Set.h>
|
||||
#include "QueryResult.h"
|
||||
|
||||
typedef ACE_Future<QueryResult> QueryResultFuture;
|
||||
typedef ACE_Future<PreparedQueryResult> PreparedQueryResultFuture;
|
||||
|
||||
/*! A simple template using ACE_Future to manage callbacks from the thread and object that
|
||||
issued the request. <ParamType> is variable type of parameter that is used as parameter
|
||||
for the callback function.
|
||||
*/
|
||||
#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(ACE_Future<Result> value)
|
||||
{
|
||||
_result = value;
|
||||
}
|
||||
|
||||
ACE_Future<Result> GetFutureResult()
|
||||
{
|
||||
return _result;
|
||||
}
|
||||
|
||||
int IsReady()
|
||||
{
|
||||
return _result.ready();
|
||||
}
|
||||
|
||||
void GetResult(Result& res)
|
||||
{
|
||||
_result.get(res);
|
||||
}
|
||||
|
||||
void FreeResult()
|
||||
{
|
||||
_result.cancel();
|
||||
}
|
||||
|
||||
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(NULL);
|
||||
FreeResult();
|
||||
ResetStage();
|
||||
}
|
||||
|
||||
private:
|
||||
ACE_Future<Result> _result;
|
||||
ParamType _param;
|
||||
uint8 _stage;
|
||||
};
|
||||
|
||||
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(ACE_Future<Result> value)
|
||||
{
|
||||
_result = value;
|
||||
}
|
||||
|
||||
ACE_Future<Result> GetFutureResult()
|
||||
{
|
||||
return _result;
|
||||
}
|
||||
|
||||
int IsReady()
|
||||
{
|
||||
return _result.ready();
|
||||
}
|
||||
|
||||
void GetResult(Result& res)
|
||||
{
|
||||
_result.get(res);
|
||||
}
|
||||
|
||||
void FreeResult()
|
||||
{
|
||||
_result.cancel();
|
||||
}
|
||||
|
||||
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(0);
|
||||
SetSecondParam(NULL);
|
||||
FreeResult();
|
||||
ResetStage();
|
||||
}
|
||||
|
||||
private:
|
||||
ACE_Future<Result> _result;
|
||||
ParamType1 _param_1;
|
||||
ParamType2 _param_2;
|
||||
uint8 _stage;
|
||||
};
|
||||
|
||||
template <typename Result, typename ParamType1, typename ParamType2, typename ParamType3, bool chain = false>
|
||||
class QueryCallback_3
|
||||
{
|
||||
public:
|
||||
QueryCallback_3() : _stage(chain ? 0 : CALLBACK_STAGE_INVALID) {}
|
||||
|
||||
//! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
|
||||
void SetFutureResult(ACE_Future<Result> value)
|
||||
{
|
||||
_result = value;
|
||||
}
|
||||
|
||||
ACE_Future<Result> GetFutureResult()
|
||||
{
|
||||
return _result;
|
||||
}
|
||||
|
||||
int IsReady()
|
||||
{
|
||||
return _result.ready();
|
||||
}
|
||||
|
||||
void GetResult(Result& res)
|
||||
{
|
||||
_result.get(res);
|
||||
}
|
||||
|
||||
void FreeResult()
|
||||
{
|
||||
_result.cancel();
|
||||
}
|
||||
|
||||
void SetFirstParam(ParamType1 value)
|
||||
{
|
||||
_param_1 = value;
|
||||
}
|
||||
|
||||
void SetSecondParam(ParamType2 value)
|
||||
{
|
||||
_param_2 = value;
|
||||
}
|
||||
|
||||
void SetThirdParam(ParamType3 value)
|
||||
{
|
||||
_param_3 = value;
|
||||
}
|
||||
|
||||
ParamType1 GetFirstParam()
|
||||
{
|
||||
return _param_1;
|
||||
}
|
||||
|
||||
ParamType2 GetSecondParam()
|
||||
{
|
||||
return _param_2;
|
||||
}
|
||||
|
||||
ParamType3 GetThirdParam()
|
||||
{
|
||||
return _param_3;
|
||||
}
|
||||
|
||||
//! 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);
|
||||
SetThirdParam(NULL);
|
||||
FreeResult();
|
||||
ResetStage();
|
||||
}
|
||||
|
||||
private:
|
||||
ACE_Future<Result> _result;
|
||||
ParamType1 _param_1;
|
||||
ParamType2 _param_2;
|
||||
ParamType3 _param_3;
|
||||
uint8 _stage;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,122 +0,0 @@
|
||||
#include <ace/Singleton.h>
|
||||
#include <ace/Thread_Mutex.h>
|
||||
#include <ace/Log_Msg.h>
|
||||
#include "Threading.h"
|
||||
|
||||
#include "DelayExecutor.h"
|
||||
|
||||
DelayExecutor* DelayExecutor::instance()
|
||||
{
|
||||
return ACE_Singleton<DelayExecutor, ACE_Thread_Mutex>::instance();
|
||||
}
|
||||
|
||||
DelayExecutor::DelayExecutor()
|
||||
: pre_svc_hook_(0), post_svc_hook_(0), activated_(false), mqueue_(1*1024*1024, 1*1024*1024), queue_(&mqueue_)
|
||||
{
|
||||
}
|
||||
|
||||
DelayExecutor::~DelayExecutor()
|
||||
{
|
||||
if (pre_svc_hook_)
|
||||
delete pre_svc_hook_;
|
||||
|
||||
if (post_svc_hook_)
|
||||
delete post_svc_hook_;
|
||||
|
||||
deactivate();
|
||||
}
|
||||
|
||||
int DelayExecutor::deactivate()
|
||||
{
|
||||
if (!activated())
|
||||
return -1;
|
||||
|
||||
activated(false);
|
||||
queue_.queue()->deactivate();
|
||||
wait();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DelayExecutor::svc()
|
||||
{
|
||||
if (pre_svc_hook_)
|
||||
pre_svc_hook_->call();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ACE_Method_Request* rq = queue_.dequeue();
|
||||
|
||||
if (!rq)
|
||||
break;
|
||||
|
||||
rq->call();
|
||||
delete rq;
|
||||
}
|
||||
|
||||
if (post_svc_hook_)
|
||||
post_svc_hook_->call();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DelayExecutor::start(int num_threads, ACE_Method_Request* pre_svc_hook, ACE_Method_Request* post_svc_hook)
|
||||
{
|
||||
if (activated())
|
||||
return -1;
|
||||
|
||||
if (num_threads < 1)
|
||||
return -1;
|
||||
|
||||
if (pre_svc_hook_)
|
||||
delete pre_svc_hook_;
|
||||
|
||||
if (post_svc_hook_)
|
||||
delete post_svc_hook_;
|
||||
|
||||
pre_svc_hook_ = pre_svc_hook;
|
||||
post_svc_hook_ = post_svc_hook;
|
||||
|
||||
queue_.queue()->activate();
|
||||
|
||||
// pussywizard:
|
||||
ACE_Based::ThreadPriority tp;
|
||||
int _priority = tp.getPriority(ACE_Based::Highest);
|
||||
if (ACE_Task_Base::activate(THR_NEW_LWP | THR_JOINABLE, num_threads, 0, _priority) == -1)
|
||||
return -1;
|
||||
|
||||
//if (ACE_Task_Base::activate(THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED, num_threads) == -1)
|
||||
// return -1;
|
||||
|
||||
activated(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int DelayExecutor::execute(ACE_Method_Request* new_req)
|
||||
{
|
||||
if (new_req == NULL)
|
||||
return -1;
|
||||
|
||||
// pussywizard: NULL as param for enqueue - wait until the action is possible!
|
||||
// new tasks are added to the queue during map update (schedule_update in MapInstanced::Update)
|
||||
// the queue can be momentarily blocked by map threads constantly waiting for tasks (for (;;) { queue_.dequeue();... } in DelayExecutor::svc())
|
||||
// so just wait a moment, don't drop the task xDddd
|
||||
if (queue_.enqueue(new_req, /*(ACE_Time_Value*)&ACE_Time_Value::zero*/ NULL) == -1)
|
||||
{
|
||||
delete new_req;
|
||||
ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%t) %p\n"), ACE_TEXT("DelayExecutor::execute enqueue")), -1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool DelayExecutor::activated()
|
||||
{
|
||||
return activated_;
|
||||
}
|
||||
|
||||
void DelayExecutor::activated(bool s)
|
||||
{
|
||||
activated_ = s;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
#ifndef _M_DELAY_EXECUTOR_H
|
||||
#define _M_DELAY_EXECUTOR_H
|
||||
|
||||
#include <ace/Task.h>
|
||||
#include <ace/Activation_Queue.h>
|
||||
#include <ace/Method_Request.h>
|
||||
|
||||
class DelayExecutor : protected ACE_Task_Base
|
||||
{
|
||||
public:
|
||||
|
||||
DelayExecutor();
|
||||
virtual ~DelayExecutor();
|
||||
|
||||
static DelayExecutor* instance();
|
||||
|
||||
int execute(ACE_Method_Request* new_req);
|
||||
|
||||
int start(int num_threads = 1, ACE_Method_Request* pre_svc_hook = NULL, ACE_Method_Request* post_svc_hook = NULL);
|
||||
|
||||
int deactivate();
|
||||
|
||||
bool activated();
|
||||
|
||||
virtual int svc();
|
||||
|
||||
private:
|
||||
|
||||
ACE_Message_Queue<ACE_SYNCH> mqueue_;
|
||||
ACE_Activation_Queue queue_;
|
||||
ACE_Method_Request* pre_svc_hook_;
|
||||
ACE_Method_Request* post_svc_hook_;
|
||||
bool activated_;
|
||||
|
||||
void activated(bool s);
|
||||
};
|
||||
|
||||
#endif // _M_DELAY_EXECUTOR_H
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 <ace/Guard_T.h>
|
||||
#include <ace/Thread_Mutex.h>
|
||||
#include <deque>
|
||||
#include <assert.h>
|
||||
#include "Debugging/Errors.h"
|
||||
|
||||
namespace ACE_Based
|
||||
{
|
||||
template <class T, class LockType, typename StorageType=std::deque<T> >
|
||||
class LockedQueue
|
||||
{
|
||||
//! Lock access to the queue.
|
||||
LockType _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();
|
||||
|
||||
//ASSERT(!this->_canceled);
|
||||
// throw Cancellation_Exception();
|
||||
|
||||
_queue.push_back(item);
|
||||
|
||||
unlock();
|
||||
}
|
||||
|
||||
//! Gets the next result in the queue, if any.
|
||||
bool next(T& result)
|
||||
{
|
||||
// ACE_Guard<LockType> g(this->_lock);
|
||||
ACE_GUARD_RETURN (LockType, g, this->_lock, false);
|
||||
|
||||
if (_queue.empty())
|
||||
return false;
|
||||
|
||||
//ASSERT (!_queue.empty() || !this->_canceled);
|
||||
// throw Cancellation_Exception();
|
||||
result = _queue.front();
|
||||
_queue.pop_front();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class Checker>
|
||||
bool next(T& result, Checker& check)
|
||||
{
|
||||
ACE_Guard<LockType> g(this->_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()
|
||||
{
|
||||
lock();
|
||||
|
||||
_canceled = true;
|
||||
|
||||
unlock();
|
||||
}
|
||||
|
||||
//! Checks if the queue is cancelled.
|
||||
bool cancelled()
|
||||
{
|
||||
ACE_Guard<LockType> g(this->_lock);
|
||||
return _canceled;
|
||||
}
|
||||
|
||||
//! Locks the queue for access.
|
||||
void lock()
|
||||
{
|
||||
this->_lock.acquire();
|
||||
}
|
||||
|
||||
//! Unlocks the queue.
|
||||
void unlock()
|
||||
{
|
||||
this->_lock.release();
|
||||
}
|
||||
|
||||
///! Calls pop_front of the queue
|
||||
void pop_front()
|
||||
{
|
||||
ACE_GUARD (LockType, g, this->_lock);
|
||||
_queue.pop_front();
|
||||
}
|
||||
|
||||
///! Checks if we're empty or not with locks held
|
||||
bool empty()
|
||||
{
|
||||
ACE_GUARD_RETURN (LockType, g, this->_lock, false);
|
||||
return _queue.empty();
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -1,235 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "Threading.h"
|
||||
#include "Errors.h"
|
||||
#include <ace/OS_NS_unistd.h>
|
||||
#include <ace/Sched_Params.h>
|
||||
#include <vector>
|
||||
|
||||
using namespace ACE_Based;
|
||||
|
||||
ThreadPriority::ThreadPriority()
|
||||
{
|
||||
for (int i = Idle; i < MAXPRIORITYNUM; ++i)
|
||||
m_priority[i] = ACE_THR_PRI_OTHER_DEF;
|
||||
|
||||
m_priority[Idle] = ACE_Sched_Params::priority_min(ACE_SCHED_OTHER);
|
||||
m_priority[Realtime] = ACE_Sched_Params::priority_max(ACE_SCHED_OTHER);
|
||||
|
||||
std::vector<int> _tmp;
|
||||
|
||||
ACE_Sched_Params::Policy _policy = ACE_SCHED_OTHER;
|
||||
ACE_Sched_Priority_Iterator pr_iter(_policy);
|
||||
|
||||
while (pr_iter.more())
|
||||
{
|
||||
_tmp.push_back(pr_iter.priority());
|
||||
pr_iter.next();
|
||||
}
|
||||
|
||||
ASSERT (!_tmp.empty());
|
||||
|
||||
if (_tmp.size() >= MAXPRIORITYNUM)
|
||||
{
|
||||
const size_t max_pos = _tmp.size();
|
||||
size_t min_pos = 1;
|
||||
size_t norm_pos = 0;
|
||||
for (size_t i = 0; i < max_pos; ++i)
|
||||
{
|
||||
if (_tmp[i] == ACE_THR_PRI_OTHER_DEF)
|
||||
{
|
||||
norm_pos = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// since we have only 7(seven) values in enum Priority
|
||||
// and 3 we know already (Idle, Normal, Realtime) so
|
||||
// we need to split each list [Idle...Normal] and [Normal...Realtime]
|
||||
// into pieces
|
||||
const size_t _divider = 4;
|
||||
size_t _div = (norm_pos - min_pos) / _divider;
|
||||
if (_div == 0)
|
||||
_div = 1;
|
||||
|
||||
min_pos = (norm_pos - 1);
|
||||
|
||||
m_priority[Low] = _tmp[min_pos -= _div];
|
||||
m_priority[Lowest] = _tmp[min_pos -= _div ];
|
||||
|
||||
_div = (max_pos - norm_pos) / _divider;
|
||||
if (_div == 0)
|
||||
_div = 1;
|
||||
|
||||
min_pos = norm_pos - 1;
|
||||
|
||||
m_priority[High] = _tmp[min_pos += _div];
|
||||
m_priority[Highest] = _tmp[min_pos += _div];
|
||||
}
|
||||
}
|
||||
|
||||
int ThreadPriority::getPriority(Priority p) const
|
||||
{
|
||||
if (p < Idle)
|
||||
p = Idle;
|
||||
|
||||
if (p > Realtime)
|
||||
p = Realtime;
|
||||
|
||||
return m_priority[p];
|
||||
}
|
||||
|
||||
#define THREADFLAG (THR_NEW_LWP | THR_SCHED_DEFAULT| THR_JOINABLE)
|
||||
|
||||
Thread::Thread(): m_iThreadId(0), m_hThreadHandle(0), m_task(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Thread::Thread(Runnable* instance): m_iThreadId(0), m_hThreadHandle(0), m_task(instance)
|
||||
{
|
||||
// register reference to m_task to prevent it deeltion until destructor
|
||||
if (m_task)
|
||||
m_task->incReference();
|
||||
|
||||
bool _start = start();
|
||||
ASSERT (_start);
|
||||
}
|
||||
|
||||
Thread::~Thread()
|
||||
{
|
||||
//Wait();
|
||||
|
||||
// deleted runnable object (if no other references)
|
||||
if (m_task)
|
||||
m_task->decReference();
|
||||
}
|
||||
|
||||
//initialize Thread's class static member
|
||||
Thread::ThreadStorage Thread::m_ThreadStorage;
|
||||
ThreadPriority Thread::m_TpEnum;
|
||||
|
||||
bool Thread::start()
|
||||
{
|
||||
if (m_task == 0 || m_iThreadId != 0)
|
||||
return false;
|
||||
|
||||
// incRef before spawing the thread, otherwise Thread::ThreadTask() might call decRef and delete m_task
|
||||
m_task->incReference();
|
||||
|
||||
bool res = (ACE_Thread::spawn(&Thread::ThreadTask, (void*)m_task, THREADFLAG, &m_iThreadId, &m_hThreadHandle) == 0);
|
||||
|
||||
if (!res)
|
||||
m_task->decReference();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool Thread::wait()
|
||||
{
|
||||
if (!m_hThreadHandle || !m_task)
|
||||
return false;
|
||||
|
||||
ACE_THR_FUNC_RETURN _value = ACE_THR_FUNC_RETURN(-1);
|
||||
int _res = ACE_Thread::join(m_hThreadHandle, &_value);
|
||||
|
||||
m_iThreadId = 0;
|
||||
m_hThreadHandle = 0;
|
||||
|
||||
return (_res == 0);
|
||||
}
|
||||
|
||||
void Thread::destroy()
|
||||
{
|
||||
if (!m_iThreadId || !m_task)
|
||||
return;
|
||||
|
||||
if (ACE_Thread::kill(m_iThreadId, -1) != 0)
|
||||
return;
|
||||
|
||||
m_iThreadId = 0;
|
||||
m_hThreadHandle = 0;
|
||||
|
||||
// reference set at ACE_Thread::spawn
|
||||
m_task->decReference();
|
||||
}
|
||||
|
||||
void Thread::suspend()
|
||||
{
|
||||
ACE_Thread::suspend(m_hThreadHandle);
|
||||
}
|
||||
|
||||
void Thread::resume()
|
||||
{
|
||||
ACE_Thread::resume(m_hThreadHandle);
|
||||
}
|
||||
|
||||
ACE_THR_FUNC_RETURN Thread::ThreadTask(void * param)
|
||||
{
|
||||
Runnable* _task = (Runnable*)param;
|
||||
_task->run();
|
||||
|
||||
// task execution complete, free referecne added at
|
||||
_task->decReference();
|
||||
|
||||
return (ACE_THR_FUNC_RETURN)0;
|
||||
}
|
||||
|
||||
ACE_thread_t Thread::currentId()
|
||||
{
|
||||
return ACE_Thread::self();
|
||||
}
|
||||
|
||||
ACE_hthread_t Thread::currentHandle()
|
||||
{
|
||||
ACE_hthread_t _handle;
|
||||
ACE_Thread::self(_handle);
|
||||
|
||||
return _handle;
|
||||
}
|
||||
|
||||
Thread * Thread::current()
|
||||
{
|
||||
Thread * _thread = m_ThreadStorage.ts_object();
|
||||
if (!_thread)
|
||||
{
|
||||
_thread = new Thread();
|
||||
_thread->m_iThreadId = Thread::currentId();
|
||||
_thread->m_hThreadHandle = Thread::currentHandle();
|
||||
|
||||
Thread * _oldValue = m_ThreadStorage.ts_object(_thread);
|
||||
if (_oldValue)
|
||||
delete _oldValue;
|
||||
}
|
||||
|
||||
return _thread;
|
||||
}
|
||||
|
||||
void Thread::setPriority(Priority type)
|
||||
{
|
||||
int _priority = m_TpEnum.getPriority(type);
|
||||
int _ok = ACE_Thread::setprio(m_hThreadHandle, _priority);
|
||||
//remove this ASSERT in case you don't want to know is thread priority change was successful or not
|
||||
ASSERT (_ok == 0);
|
||||
}
|
||||
|
||||
void Thread::Sleep(unsigned long msecs)
|
||||
{
|
||||
ACE_OS::sleep(ACE_Time_Value(0, 1000 * msecs));
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 THREADING_H
|
||||
#define THREADING_H
|
||||
|
||||
#include "Common.h"
|
||||
#include <ace/ACE.h>
|
||||
#include <ace/Thread.h>
|
||||
#include <ace/TSS_T.h>
|
||||
#include <ace/Atomic_Op.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace ACE_Based
|
||||
{
|
||||
|
||||
class Runnable
|
||||
{
|
||||
public:
|
||||
virtual ~Runnable() { }
|
||||
virtual void run() = 0;
|
||||
|
||||
void incReference() { ++m_refs; }
|
||||
void decReference()
|
||||
{
|
||||
if (!--m_refs)
|
||||
delete this;
|
||||
}
|
||||
private:
|
||||
ACE_Atomic_Op<ACE_Thread_Mutex, long> m_refs;
|
||||
};
|
||||
|
||||
enum Priority
|
||||
{
|
||||
Idle,
|
||||
Lowest,
|
||||
Low,
|
||||
Normal,
|
||||
High,
|
||||
Highest,
|
||||
Realtime
|
||||
};
|
||||
|
||||
#define MAXPRIORITYNUM (Realtime + 1)
|
||||
|
||||
class ThreadPriority
|
||||
{
|
||||
public:
|
||||
ThreadPriority();
|
||||
int getPriority(Priority p) const;
|
||||
|
||||
private:
|
||||
int m_priority[MAXPRIORITYNUM];
|
||||
};
|
||||
|
||||
class Thread
|
||||
{
|
||||
public:
|
||||
Thread();
|
||||
explicit Thread(Runnable* instance);
|
||||
~Thread();
|
||||
|
||||
bool start();
|
||||
bool wait();
|
||||
void destroy();
|
||||
|
||||
void suspend();
|
||||
void resume();
|
||||
|
||||
void setPriority(Priority type);
|
||||
|
||||
static void Sleep(unsigned long msecs);
|
||||
static ACE_thread_t currentId();
|
||||
static ACE_hthread_t currentHandle();
|
||||
static Thread * current();
|
||||
|
||||
private:
|
||||
Thread(const Thread&);
|
||||
Thread& operator=(const Thread&);
|
||||
|
||||
static ACE_THR_FUNC_RETURN ThreadTask(void * param);
|
||||
|
||||
ACE_thread_t m_iThreadId;
|
||||
ACE_hthread_t m_hThreadHandle;
|
||||
Runnable* m_task;
|
||||
|
||||
typedef ACE_TSS<Thread> ThreadStorage;
|
||||
//global object - container for Thread class representation of every thread
|
||||
static ThreadStorage m_ThreadStorage;
|
||||
//use this object to determine current OS thread priority values mapped to enum Priority{ }
|
||||
static ThreadPriority m_TpEnum;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
|
||||
uint64 EventProcessor::CalculateQueueTime(uint64 delay) const
|
||||
{
|
||||
return CalculateTime(delay - (m_time % delay));
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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;
|
||||
|
||||
// Xinef: calculates next queue tick time
|
||||
uint64 CalculateQueueTime(uint64 delay) const;
|
||||
|
||||
protected:
|
||||
uint64 m_time;
|
||||
EventList m_events;
|
||||
bool m_aborting;
|
||||
};
|
||||
#endif
|
||||
@@ -1,264 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "Common.h"
|
||||
#include "Log.h"
|
||||
#include <cstring>
|
||||
#include <windows.h>
|
||||
#include <winsvc.h>
|
||||
|
||||
// stupid ACE define
|
||||
#ifdef main
|
||||
#undef main
|
||||
#endif //main
|
||||
|
||||
#if !defined(WINADVAPI)
|
||||
#if !defined(_ADVAPI32_)
|
||||
#define WINADVAPI DECLSPEC_IMPORT
|
||||
#else
|
||||
#define WINADVAPI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern int main(int argc, char ** argv);
|
||||
extern char serviceLongName[];
|
||||
extern char serviceName[];
|
||||
extern char serviceDescription[];
|
||||
|
||||
extern int m_ServiceStatus;
|
||||
|
||||
SERVICE_STATUS serviceStatus;
|
||||
|
||||
SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
|
||||
|
||||
typedef WINADVAPI BOOL (WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID);
|
||||
|
||||
bool WinServiceInstall()
|
||||
{
|
||||
SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
|
||||
|
||||
if (serviceControlManager)
|
||||
{
|
||||
char path[_MAX_PATH + 10];
|
||||
if (GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0)
|
||||
{
|
||||
SC_HANDLE service;
|
||||
std::strcat(path, " --service");
|
||||
service = CreateService(serviceControlManager,
|
||||
serviceName, // name of service
|
||||
serviceLongName, // service name to display
|
||||
SERVICE_ALL_ACCESS, // desired access
|
||||
// service type
|
||||
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
|
||||
SERVICE_AUTO_START, // start type
|
||||
SERVICE_ERROR_IGNORE, // error control type
|
||||
path, // service's binary
|
||||
0, // no load ordering group
|
||||
0, // no tag identifier
|
||||
0, // no dependencies
|
||||
0, // LocalSystem account
|
||||
0); // no password
|
||||
if (service)
|
||||
{
|
||||
HMODULE advapi32 = GetModuleHandle("ADVAPI32.DLL");
|
||||
if (!advapi32)
|
||||
{
|
||||
CloseServiceHandle(service);
|
||||
CloseServiceHandle(serviceControlManager);
|
||||
return false;
|
||||
}
|
||||
|
||||
CSD_T ChangeService_Config2 = (CSD_T) GetProcAddress(advapi32, "ChangeServiceConfig2A");
|
||||
if (!ChangeService_Config2)
|
||||
{
|
||||
CloseServiceHandle(service);
|
||||
CloseServiceHandle(serviceControlManager);
|
||||
return false;
|
||||
}
|
||||
|
||||
SERVICE_DESCRIPTION sdBuf;
|
||||
sdBuf.lpDescription = serviceDescription;
|
||||
ChangeService_Config2(
|
||||
service, // handle to service
|
||||
SERVICE_CONFIG_DESCRIPTION, // change: description
|
||||
&sdBuf); // new data
|
||||
|
||||
SC_ACTION _action[1];
|
||||
_action[0].Type = SC_ACTION_RESTART;
|
||||
_action[0].Delay = 10000;
|
||||
SERVICE_FAILURE_ACTIONS sfa;
|
||||
ZeroMemory(&sfa, sizeof(SERVICE_FAILURE_ACTIONS));
|
||||
sfa.lpsaActions = _action;
|
||||
sfa.cActions = 1;
|
||||
sfa.dwResetPeriod =INFINITE;
|
||||
ChangeService_Config2(
|
||||
service, // handle to service
|
||||
SERVICE_CONFIG_FAILURE_ACTIONS, // information level
|
||||
&sfa); // new data
|
||||
|
||||
CloseServiceHandle(service);
|
||||
|
||||
}
|
||||
}
|
||||
CloseServiceHandle(serviceControlManager);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinServiceUninstall()
|
||||
{
|
||||
SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
|
||||
|
||||
if (serviceControlManager)
|
||||
{
|
||||
SC_HANDLE service = OpenService(serviceControlManager,
|
||||
serviceName, SERVICE_QUERY_STATUS | DELETE);
|
||||
if (service)
|
||||
{
|
||||
SERVICE_STATUS serviceStatus2;
|
||||
if (QueryServiceStatus(service, &serviceStatus2))
|
||||
{
|
||||
if (serviceStatus2.dwCurrentState == SERVICE_STOPPED)
|
||||
DeleteService(service);
|
||||
}
|
||||
CloseServiceHandle(service);
|
||||
}
|
||||
|
||||
CloseServiceHandle(serviceControlManager);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void WINAPI ServiceControlHandler(DWORD controlCode)
|
||||
{
|
||||
switch (controlCode)
|
||||
{
|
||||
case SERVICE_CONTROL_INTERROGATE:
|
||||
break;
|
||||
|
||||
case SERVICE_CONTROL_SHUTDOWN:
|
||||
case SERVICE_CONTROL_STOP:
|
||||
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
|
||||
m_ServiceStatus = 0;
|
||||
return;
|
||||
|
||||
case SERVICE_CONTROL_PAUSE:
|
||||
m_ServiceStatus = 2;
|
||||
serviceStatus.dwCurrentState = SERVICE_PAUSED;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
break;
|
||||
|
||||
case SERVICE_CONTROL_CONTINUE:
|
||||
serviceStatus.dwCurrentState = SERVICE_RUNNING;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
m_ServiceStatus = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( controlCode >= 128 && controlCode <= 255 )
|
||||
// user defined control code
|
||||
break;
|
||||
else
|
||||
// unrecognized control code
|
||||
break;
|
||||
}
|
||||
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
}
|
||||
|
||||
void WINAPI ServiceMain(DWORD argc, char *argv[])
|
||||
{
|
||||
// initialise service status
|
||||
serviceStatus.dwServiceType = SERVICE_WIN32;
|
||||
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
|
||||
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
|
||||
serviceStatus.dwWin32ExitCode = NO_ERROR;
|
||||
serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
|
||||
serviceStatus.dwCheckPoint = 0;
|
||||
serviceStatus.dwWaitHint = 0;
|
||||
|
||||
serviceStatusHandle = RegisterServiceCtrlHandler(serviceName, ServiceControlHandler);
|
||||
|
||||
if ( serviceStatusHandle )
|
||||
{
|
||||
char path[_MAX_PATH + 1];
|
||||
unsigned int i, last_slash = 0;
|
||||
|
||||
GetModuleFileName(0, path, sizeof(path)/sizeof(path[0]));
|
||||
|
||||
for (i = 0; i < std::strlen(path); i++)
|
||||
{
|
||||
if (path[i] == '\\') last_slash = i;
|
||||
}
|
||||
|
||||
path[last_slash] = 0;
|
||||
|
||||
// service is starting
|
||||
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
|
||||
// do initialisation here
|
||||
SetCurrentDirectory(path);
|
||||
|
||||
// running
|
||||
serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
|
||||
serviceStatus.dwCurrentState = SERVICE_RUNNING;
|
||||
SetServiceStatus( serviceStatusHandle, &serviceStatus );
|
||||
|
||||
////////////////////////
|
||||
// service main cycle //
|
||||
////////////////////////
|
||||
|
||||
m_ServiceStatus = 1;
|
||||
argc = 1;
|
||||
main(argc, argv);
|
||||
|
||||
// service was stopped
|
||||
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
|
||||
// do cleanup here
|
||||
|
||||
// service is now stopped
|
||||
serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
|
||||
serviceStatus.dwCurrentState = SERVICE_STOPPED;
|
||||
SetServiceStatus(serviceStatusHandle, &serviceStatus);
|
||||
}
|
||||
}
|
||||
|
||||
bool WinServiceRun()
|
||||
{
|
||||
SERVICE_TABLE_ENTRY serviceTable[] =
|
||||
{
|
||||
{ serviceName, ServiceMain },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
if (!StartServiceCtrlDispatcher(serviceTable))
|
||||
{
|
||||
sLog->outError("StartService Failed. Error [%u]", ::GetLastError());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef _WIN32_SERVICE_
|
||||
#define _WIN32_SERVICE_
|
||||
|
||||
bool WinServiceInstall();
|
||||
bool WinServiceUninstall();
|
||||
bool WinServiceRun();
|
||||
|
||||
#endif // _WIN32_SERVICE_
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 __SIGNAL_HANDLER_H__
|
||||
#define __SIGNAL_HANDLER_H__
|
||||
|
||||
#include <ace/Event_Handler.h>
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
|
||||
/// Handle termination signals
|
||||
class SignalHandler : public ACE_Event_Handler
|
||||
{
|
||||
public:
|
||||
int handle_signal(int SigNum, siginfo_t* = NULL, ucontext_t* = NULL)
|
||||
{
|
||||
HandleSignal(SigNum);
|
||||
return 0;
|
||||
}
|
||||
virtual void HandleSignal(int /*SigNum*/) { };
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* __SIGNAL_HANDLER_H__ */
|
||||
@@ -1,201 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "ace/OS_NS_sys_time.h"
|
||||
#include "Common.h"
|
||||
|
||||
inline uint32 getMSTime()
|
||||
{
|
||||
static const ACE_Time_Value ApplicationStartTime = ACE_OS::gettimeofday();
|
||||
return (ACE_OS::gettimeofday() - ApplicationStartTime).msec();
|
||||
}
|
||||
|
||||
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
|
||||
@@ -1,551 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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 "utf8.h"
|
||||
#include "SFMT.h"
|
||||
#include "Errors.h" // for ASSERT
|
||||
#include <ace/TSS_T.h>
|
||||
|
||||
typedef ACE_TSS<SFMTRand> SFMTRandTSS;
|
||||
static SFMTRandTSS sfmtRand;
|
||||
|
||||
int32 irand(int32 min, int32 max)
|
||||
{
|
||||
ASSERT(max >= min);
|
||||
return int32(sfmtRand->IRandom(min, max));
|
||||
}
|
||||
|
||||
uint32 urand(uint32 min, uint32 max)
|
||||
{
|
||||
ASSERT(max >= min);
|
||||
return sfmtRand->URandom(min, max);
|
||||
}
|
||||
|
||||
float frand(float min, float max)
|
||||
{
|
||||
ASSERT(max >= min);
|
||||
return float(sfmtRand->Random() * (max - min) + min);
|
||||
}
|
||||
|
||||
uint32 rand32()
|
||||
{
|
||||
return int32(sfmtRand->BRandom());
|
||||
}
|
||||
|
||||
double rand_norm()
|
||||
{
|
||||
return sfmtRand->Random();
|
||||
}
|
||||
|
||||
double rand_chance()
|
||||
{
|
||||
return sfmtRand->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();
|
||||
|
||||
}
|
||||
|
||||
std::string secsToTimeString(uint64 timeInSecs, bool shortText)
|
||||
{
|
||||
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)
|
||||
ss << hours << (shortText ? "h" : " hour(s) ");
|
||||
if (minutes)
|
||||
ss << minutes << (shortText ? "m" : " minute(s) ");
|
||||
if (secs || (!days && !hours && !minutes) )
|
||||
ss << secs << (shortText ? "s" : " second(s) ");
|
||||
|
||||
std::string str = ss.str();
|
||||
|
||||
if (!shortText && !str.empty() && str[str.size()-1] == ' ')
|
||||
str.resize(str.size()-1);
|
||||
|
||||
return 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;
|
||||
ACE_OS::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;
|
||||
}
|
||||
|
||||
std::string GetAddressString(ACE_INET_Addr const& addr)
|
||||
{
|
||||
char buf[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16];
|
||||
addr.addr_to_string(buf, ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16);
|
||||
return buf;
|
||||
}
|
||||
|
||||
bool IsIPAddrInNetwork(ACE_INET_Addr const& net, ACE_INET_Addr const& addr, ACE_INET_Addr const& subnetMask)
|
||||
{
|
||||
uint32 mask = subnetMask.get_ip_address();
|
||||
if ((net.get_ip_address() & mask) == (addr.get_ip_address() & mask))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 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 = "";
|
||||
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 = "";
|
||||
}
|
||||
}
|
||||
|
||||
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 = L"";
|
||||
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 = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WStrToUtf8(std::wstring 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 = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef wchar_t const* const* wstrlist;
|
||||
|
||||
std::wstring GetMainPartOfName(std::wstring 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 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();
|
||||
}
|
||||
@@ -1,905 +0,0 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
* Copyright (C)
|
||||
*
|
||||
* 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>
|
||||
#include <ace/INET_Addr.h>
|
||||
|
||||
// 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);
|
||||
|
||||
std::string secsToTimeString(uint64 timeInSecs, bool shortText = 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(int32 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 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 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 search);
|
||||
void utf8printf(FILE* out, const char *str, ...);
|
||||
void vutf8printf(FILE* out, const char *str, va_list* ap);
|
||||
|
||||
bool IsIPAddress(char const* ipaddress);
|
||||
|
||||
/// Checks if address belongs to the a network with specified submask
|
||||
bool IsIPAddrInNetwork(ACE_INET_Addr const& net, ACE_INET_Addr const& addr, ACE_INET_Addr const& subnetMask);
|
||||
|
||||
/// Transforms ACE_INET_Addr address into string format "dotted_ip:port"
|
||||
std::string GetAddressString(ACE_INET_Addr const& addr);
|
||||
|
||||
uint32 CreatePIDFile(const std::string& filename);
|
||||
|
||||
std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false);
|
||||
#endif
|
||||
|
||||
//handler for operations on large flags
|
||||
#ifndef _FLAG96
|
||||
#define _FLAG96
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
flag96(uint64 p1, uint32 p2)
|
||||
{
|
||||
part[0] = (uint32)(p1 & UI64LIT(0x00000000FFFFFFFF));
|
||||
part[1] = (uint32)((p1 >> 32) & UI64LIT(0x00000000FFFFFFFF));
|
||||
part[2] = p2;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
class EventMap
|
||||
{
|
||||
typedef std::multimap<uint32, uint32> EventStore;
|
||||
|
||||
public:
|
||||
EventMap() : _time(0), _phase(0) { }
|
||||
|
||||
/**
|
||||
* @name Reset
|
||||
* @brief Removes all scheduled events and resets time and phase.
|
||||
*/
|
||||
void Reset()
|
||||
{
|
||||
_eventMap.clear();
|
||||
_time = 0;
|
||||
_phase = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Update
|
||||
* @brief Updates the timer of the event map.
|
||||
* @param time Value to be added to time.
|
||||
*/
|
||||
void Update(uint32 time)
|
||||
{
|
||||
_time += time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name GetTimer
|
||||
* @return Current timer value.
|
||||
*/
|
||||
uint32 GetTimer() const
|
||||
{
|
||||
return _time;
|
||||
}
|
||||
|
||||
void SetTimer(uint32 time)
|
||||
{
|
||||
_time = 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)
|
||||
{
|
||||
if (!phase)
|
||||
_phase = 0;
|
||||
else if (phase <= 8)
|
||||
_phase = (1 << (phase - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 |= (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 &= ~(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 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, uint32 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));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 groupId = 0, uint32 phase = 0)
|
||||
{
|
||||
CancelEvent(eventId);
|
||||
ScheduleEvent(eventId, time, groupId, 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 RepeatEvent(uint32 time)
|
||||
{
|
||||
if (Empty())
|
||||
return;
|
||||
|
||||
uint32 eventId = _eventMap.begin()->second;
|
||||
_eventMap.erase(_eventMap.begin());
|
||||
ScheduleEvent(eventId, time);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name PopEvent
|
||||
* @brief Remove the first event in the map.
|
||||
*/
|
||||
void PopEvent()
|
||||
{
|
||||
if (!Empty())
|
||||
_eventMap.erase(_eventMap.begin());
|
||||
}
|
||||
|
||||
/**
|
||||
* @name ExecuteEvent
|
||||
* @brief Returns the next event to execute and removes it from map.
|
||||
* @return Id of the event to execute.
|
||||
*/
|
||||
uint32 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);
|
||||
_eventMap.erase(itr);
|
||||
return eventId;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name GetEvent
|
||||
* @brief Returns the next event to execute.
|
||||
* @return Id of the event to execute.
|
||||
*/
|
||||
uint32 GetEvent()
|
||||
{
|
||||
while (!Empty())
|
||||
{
|
||||
EventStore::iterator itr = _eventMap.begin();
|
||||
|
||||
if (itr->first > _time)
|
||||
return 0;
|
||||
else if (_phase && (itr->second & 0xFF000000) && !(itr->second & (_phase << 24)))
|
||||
_eventMap.erase(itr);
|
||||
else
|
||||
return (itr->second & 0x0000FFFF);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
void DelayEventsToMax(uint32 delay, uint32 group)
|
||||
{
|
||||
for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
|
||||
{
|
||||
if (itr->first < _time+delay && (group == 0 || ((1 << (group + 15)) & itr->second)))
|
||||
{
|
||||
ScheduleEvent(itr->second, delay);
|
||||
_eventMap.erase(itr);
|
||||
itr = _eventMap.begin();
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
if (group > 8 || Empty())
|
||||
return;
|
||||
|
||||
EventStore delayed;
|
||||
|
||||
for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
|
||||
{
|
||||
if (!group || (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());
|
||||
}
|
||||
|
||||
/**
|
||||
* @name CancelEvent
|
||||
* @brief Cancels all events of the specified id.
|
||||
* @param eventId Event id to cancel.
|
||||
*/
|
||||
void 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name CancelEventGroup
|
||||
* @brief Cancel events belonging to specified group.
|
||||
* @param group Group to cancel.
|
||||
*/
|
||||
void CancelEventGroup(uint32 group)
|
||||
{
|
||||
if (!group || group > 8 || Empty())
|
||||
return;
|
||||
|
||||
uint32 groupMask = (1 << (group + 15));
|
||||
for (EventStore::iterator itr = _eventMap.begin(); itr != _eventMap.end();)
|
||||
{
|
||||
if (itr->second & groupMask)
|
||||
{
|
||||
_eventMap.erase(itr);
|
||||
itr = _eventMap.begin();
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @name GetNextEventTime
|
||||
* @brief Returns closest occurence of specified event.
|
||||
* @param eventId Wanted event id.
|
||||
* @return Time of found event.
|
||||
*/
|
||||
uint32 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name GetNextEventTime
|
||||
* @return Time of next event.
|
||||
*/
|
||||
uint32 GetNextEventTime() const
|
||||
{
|
||||
return Empty() ? 0 : _eventMap.begin()->first;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name IsInPhase
|
||||
* @brief Returns wether 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)
|
||||
{
|
||||
return phase <= 8 && (!phase || _phase & (1 << (phase - 1)));
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _time;
|
||||
uint32 _phase;
|
||||
|
||||
EventStore _eventMap;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user