mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 07:37:01 +00:00
[Sync] Project Sync plus Revision changes
The main revision system changes are based on FoeReapers work in:
b37de3b83e
This commit is contained in:
parent
f5e2d53ccc
commit
bf4b6fafc5
39 changed files with 684 additions and 416 deletions
|
|
@ -169,6 +169,7 @@ typedef uint32 DWORD;
|
||||||
#define CONCAT1(x, y) x##y
|
#define CONCAT1(x, y) x##y
|
||||||
#define STATIC_ASSERT_WORKAROUND(expr, msg) typedef char CONCAT(static_assert_failed_at_line_, __LINE__) [(expr) ? 1 : -1]
|
#define STATIC_ASSERT_WORKAROUND(expr, msg) typedef char CONCAT(static_assert_failed_at_line_, __LINE__) [(expr) ? 1 : -1]
|
||||||
|
|
||||||
|
#ifndef COMPILER_HAS_CPP11_SUPPORT
|
||||||
#if COMPILER == COMPILER_GNU
|
#if COMPILER == COMPILER_GNU
|
||||||
# if !defined(__GXX_EXPERIMENTAL_CXX0X__) || (__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 7)
|
# if !defined(__GXX_EXPERIMENTAL_CXX0X__) || (__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 7)
|
||||||
# define override
|
# define override
|
||||||
|
|
@ -184,6 +185,7 @@ typedef uint32 DWORD;
|
||||||
# define static_assert(a, b) STATIC_ASSERT_WORKAROUND(a, b)
|
# define static_assert(a, b) STATIC_ASSERT_WORKAROUND(a, b)
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ namespace MaNGOS
|
||||||
* @brief OperatorNew policy creates an object on the heap using new.
|
* @brief OperatorNew policy creates an object on the heap using new.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class OperatorNew
|
class OperatorNew
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -65,7 +65,7 @@ namespace MaNGOS
|
||||||
* @brief LocalStaticCreation policy creates an object on the stack the first time call Create.
|
* @brief LocalStaticCreation policy creates an object on the stack the first time call Create.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class LocalStaticCreation
|
class LocalStaticCreation
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
|
|
@ -123,7 +123,7 @@ namespace MaNGOS
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class CreateUsingMalloc
|
class CreateUsingMalloc
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -159,7 +159,7 @@ namespace MaNGOS
|
||||||
* @brief CreateOnCallBack creates the object base on the call back.
|
* @brief CreateOnCallBack creates the object base on the call back.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class CreateOnCallBack
|
class CreateOnCallBack
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ namespace MaNGOS
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ObjectLifeTime
|
class ObjectLifeTime
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ namespace MaNGOS
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Singleton
|
class Singleton
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -147,15 +147,15 @@ namespace MaNGOS
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INSTANTIATE_SINGLETON_1(TYPE) \
|
#define INSTANTIATE_SINGLETON_1(TYPE) \
|
||||||
template class MaNGOS::Singleton<TYPE, MaNGOS::SingleThreaded<TYPE>, MaNGOS::OperatorNew<TYPE>, MaNGOS::ObjectLifeTime<TYPE> >;
|
template class MaNGOS::Singleton<TYPE, MaNGOS::SingleThreaded<TYPE>, MaNGOS::OperatorNew<TYPE>, MaNGOS::ObjectLifeTime<TYPE> >;
|
||||||
|
|
||||||
#define INSTANTIATE_SINGLETON_2(TYPE, THREADINGMODEL) \
|
#define INSTANTIATE_SINGLETON_2(TYPE, THREADINGMODEL) \
|
||||||
template class MaNGOS::Singleton<TYPE, THREADINGMODEL, MaNGOS::OperatorNew<TYPE>, MaNGOS::ObjectLifeTime<TYPE> >;
|
template class MaNGOS::Singleton<TYPE, THREADINGMODEL, MaNGOS::OperatorNew<TYPE>, MaNGOS::ObjectLifeTime<TYPE> >;
|
||||||
|
|
||||||
#define INSTANTIATE_SINGLETON_3(TYPE, THREADINGMODEL, CREATIONPOLICY ) \
|
#define INSTANTIATE_SINGLETON_3(TYPE, THREADINGMODEL, CREATIONPOLICY ) \
|
||||||
template class MaNGOS::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, MaNGOS::ObjectLifeTime<TYPE> >;
|
template class MaNGOS::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, MaNGOS::ObjectLifeTime<TYPE> >;
|
||||||
|
|
||||||
#define INSTANTIATE_SINGLETON_4(TYPE, THREADINGMODEL, CREATIONPOLICY, OBJECTLIFETIME) \
|
#define INSTANTIATE_SINGLETON_4(TYPE, THREADINGMODEL, CREATIONPOLICY, OBJECTLIFETIME) \
|
||||||
template class MaNGOS::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, OBJECTLIFETIME >;
|
template class MaNGOS::Singleton<TYPE, THREADINGMODEL, CREATIONPOLICY, OBJECTLIFETIME >;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ namespace MaNGOS
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class GeneralLock
|
class GeneralLock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -86,7 +86,7 @@ namespace MaNGOS
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class SingleThreaded
|
class SingleThreaded
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -128,7 +128,7 @@ namespace MaNGOS
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ObjectLevelLockable
|
class ObjectLevelLockable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -193,7 +193,7 @@ namespace MaNGOS
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ClassLevelLockable
|
class ClassLevelLockable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -265,6 +265,6 @@ namespace MaNGOS
|
||||||
template<class T, class MUTEX> MUTEX MaNGOS::ClassLevelLockable<T, MUTEX>::si_mtx; /**< TODO */
|
template<class T, class MUTEX> MUTEX MaNGOS::ClassLevelLockable<T, MUTEX>::si_mtx; /**< TODO */
|
||||||
|
|
||||||
#define INSTANTIATE_CLASS_MUTEX(CTYPE, MUTEX) \
|
#define INSTANTIATE_CLASS_MUTEX(CTYPE, MUTEX) \
|
||||||
template class MaNGOS::ClassLevelLockable<CTYPE, MUTEX>
|
template class MaNGOS::ClassLevelLockable<CTYPE, MUTEX>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,18 @@
|
||||||
#include "Platform/CompilerDefs.h"
|
#include "Platform/CompilerDefs.h"
|
||||||
#include "Platform/Define.h"
|
#include "Platform/Define.h"
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <AvailabilityMacros.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if COMPILER == COMPILER_CLANG
|
#if COMPILER == COMPILER_CLANG
|
||||||
# include <tr1/unordered_map>
|
# if defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_9) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9
|
||||||
# include <tr1/unordered_set>
|
# include <unordered_map>
|
||||||
|
# include <unordered_set>
|
||||||
|
# else
|
||||||
|
# include <tr1/unordered_map>
|
||||||
|
# include <tr1/unordered_set>
|
||||||
|
# endif
|
||||||
#elif COMPILER == COMPILER_INTEL
|
#elif COMPILER == COMPILER_INTEL
|
||||||
# include <ext/hash_map>
|
# include <ext/hash_map>
|
||||||
# include <ext/hash_set>
|
# include <ext/hash_set>
|
||||||
|
|
@ -97,20 +106,40 @@ HASH_NAMESPACE_END
|
||||||
using std::hash_map;
|
using std::hash_map;
|
||||||
using std::hash_set;
|
using std::hash_set;
|
||||||
#elif COMPILER == COMPILER_CLANG && defined(__FreeBSD__)
|
#elif COMPILER == COMPILER_CLANG && defined(__FreeBSD__)
|
||||||
|
# include <osreldate.h>
|
||||||
# define UNORDERED_MAP std::unordered_map
|
# define UNORDERED_MAP std::unordered_map
|
||||||
# define UNORDERED_SET std::unordered_set
|
# define UNORDERED_SET std::unordered_set
|
||||||
# define HASH_NAMESPACE_START namespace std { namespace __1 {
|
# if __FreeBSD_version >= 1001000
|
||||||
# define HASH_NAMESPACE_END } }
|
# define HASH_NAMESPACE_START namespace std {
|
||||||
|
# define HASH_NAMESPACE_END }
|
||||||
|
# else
|
||||||
|
# define HASH_NAMESPACE_START namespace std { namespace __1 {
|
||||||
|
# define HASH_NAMESPACE_END } }
|
||||||
|
# endif
|
||||||
#elif COMPILER == COMPILER_CLANG
|
#elif COMPILER == COMPILER_CLANG
|
||||||
# define UNORDERED_MAP std::tr1::unordered_map
|
# if defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_9) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9
|
||||||
# define UNORDERED_SET std::tr1::unordered_set
|
# define UNORDERED_MAP std::unordered_map
|
||||||
# define HASH_NAMESPACE_START namespace std { namespace tr1 {
|
# define UNORDERED_SET std::unordered_set
|
||||||
# define HASH_NAMESPACE_END } }
|
# define HASH_NAMESPACE_START namespace std {
|
||||||
|
# define HASH_NAMESPACE_END }
|
||||||
|
# else
|
||||||
|
# define UNORDERED_MAP std::tr1::unordered_map
|
||||||
|
# define UNORDERED_SET std::tr1::unordered_set
|
||||||
|
# define HASH_NAMESPACE_START namespace std { namespace tr1 {
|
||||||
|
# define HASH_NAMESPACE_END } }
|
||||||
|
# endif
|
||||||
#elif COMPILER == COMPILER_GNU && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 3)
|
#elif COMPILER == COMPILER_GNU && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 3)
|
||||||
# define UNORDERED_MAP std::tr1::unordered_map
|
# if defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_9) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9
|
||||||
# define UNORDERED_SET std::tr1::unordered_set
|
# define UNORDERED_MAP std::unordered_map
|
||||||
# define HASH_NAMESPACE_START namespace std { namespace tr1 {
|
# define UNORDERED_SET std::unordered_set
|
||||||
# define HASH_NAMESPACE_END } }
|
# define HASH_NAMESPACE_START namespace std {
|
||||||
|
# define HASH_NAMESPACE_END }
|
||||||
|
# else
|
||||||
|
# define UNORDERED_MAP std::tr1::unordered_map
|
||||||
|
# define UNORDERED_SET std::tr1::unordered_set
|
||||||
|
# define HASH_NAMESPACE_START namespace std { namespace tr1 {
|
||||||
|
# define HASH_NAMESPACE_END } }
|
||||||
|
# endif
|
||||||
#elif COMPILER == COMPILER_GNU && __GNUC__ >= 3 && (__GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ < 3)
|
#elif COMPILER == COMPILER_GNU && __GNUC__ >= 3 && (__GNUC__ < 4 || __GNUC__ == 4 && __GNUC_MINOR__ < 3)
|
||||||
# define UNORDERED_MAP __gnu_cxx::hash_map
|
# define UNORDERED_MAP __gnu_cxx::hash_map
|
||||||
# define UNORDERED_SET __gnu_cxx::hash_set
|
# define UNORDERED_SET __gnu_cxx::hash_set
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ bool ChatHandler::HandleHelpCommand(char* args)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!ShowHelpForCommand(getCommandTable(), args))
|
if (!ShowHelpForCommand(getCommandTable(), args))
|
||||||
SendSysMessage(LANG_NO_CMD);
|
{ SendSysMessage(LANG_NO_CMD); }
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -62,7 +62,7 @@ bool ChatHandler::HandleAccountCommand(char* args)
|
||||||
{
|
{
|
||||||
// let show subcommands at unexpected data in args
|
// let show subcommands at unexpected data in args
|
||||||
if (*args)
|
if (*args)
|
||||||
return false;
|
{ return false; }
|
||||||
|
|
||||||
AccountTypes gmlevel = GetAccessLevel();
|
AccountTypes gmlevel = GetAccessLevel();
|
||||||
PSendSysMessage(LANG_ACCOUNT_LEVEL, uint32(gmlevel));
|
PSendSysMessage(LANG_ACCOUNT_LEVEL, uint32(gmlevel));
|
||||||
|
|
@ -108,15 +108,14 @@ bool ChatHandler::HandleServerInfoCommand(char* /*args*/)
|
||||||
{
|
{
|
||||||
char const* ver = sScriptMgr.GetScriptLibraryVersion();
|
char const* ver = sScriptMgr.GetScriptLibraryVersion();
|
||||||
if (ver && *ver)
|
if (ver && *ver)
|
||||||
PSendSysMessage(LANG_USING_SCRIPT_LIB, ver);
|
{ PSendSysMessage(LANG_USING_SCRIPT_LIB, ver); }
|
||||||
else
|
else
|
||||||
SendSysMessage(LANG_USING_SCRIPT_LIB_UNKNOWN);
|
{ SendSysMessage(LANG_USING_SCRIPT_LIB_UNKNOWN); }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SendSysMessage(LANG_USING_SCRIPT_LIB_NONE);
|
{ SendSysMessage(LANG_USING_SCRIPT_LIB_NONE); }
|
||||||
|
|
||||||
PSendSysMessage(LANG_USING_WORLD_DB, sWorld.GetDBVersion());
|
PSendSysMessage(LANG_USING_WORLD_DB, sWorld.GetDBVersion());
|
||||||
PSendSysMessage(LANG_USING_EVENT_AI, sWorld.GetCreatureEventAIVersion());
|
|
||||||
PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum);
|
PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum);
|
||||||
PSendSysMessage(LANG_UPTIME, str.c_str());
|
PSendSysMessage(LANG_UPTIME, str.c_str());
|
||||||
|
|
||||||
|
|
@ -125,23 +124,25 @@ bool ChatHandler::HandleServerInfoCommand(char* /*args*/)
|
||||||
|
|
||||||
bool ChatHandler::HandleDismountCommand(char* /*args*/)
|
bool ChatHandler::HandleDismountCommand(char* /*args*/)
|
||||||
{
|
{
|
||||||
|
Player* player = m_session->GetPlayer();
|
||||||
|
|
||||||
// If player is not mounted, so go out :)
|
// If player is not mounted, so go out :)
|
||||||
if (!m_session->GetPlayer()->IsMounted())
|
if (!player->IsMounted())
|
||||||
{
|
{
|
||||||
SendSysMessage(LANG_CHAR_NON_MOUNTED);
|
SendSysMessage(LANG_CHAR_NON_MOUNTED);
|
||||||
SetSentErrorMessage(true);
|
SetSentErrorMessage(true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_session->GetPlayer()->IsTaxiFlying())
|
if (player->IsTaxiFlying())
|
||||||
{
|
{
|
||||||
SendSysMessage(LANG_YOU_IN_FLIGHT);
|
SendSysMessage(LANG_YOU_IN_FLIGHT);
|
||||||
SetSentErrorMessage(true);
|
SetSentErrorMessage(true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_session->GetPlayer()->Unmount();
|
player->Unmount();
|
||||||
m_session->GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
|
player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,7 +161,7 @@ bool ChatHandler::HandleSaveCommand(char* /*args*/)
|
||||||
// save or plan save after 20 sec (logout delay) if current next save time more this value and _not_ output any messages to prevent cheat planning
|
// save or plan save after 20 sec (logout delay) if current next save time more this value and _not_ output any messages to prevent cheat planning
|
||||||
uint32 save_interval = sWorld.getConfig(CONFIG_UINT32_INTERVAL_SAVE);
|
uint32 save_interval = sWorld.getConfig(CONFIG_UINT32_INTERVAL_SAVE);
|
||||||
if (save_interval == 0 || (save_interval > 20 * IN_MILLISECONDS && player->GetSaveTimer() <= save_interval - 20 * IN_MILLISECONDS))
|
if (save_interval == 0 || (save_interval > 20 * IN_MILLISECONDS && player->GetSaveTimer() <= save_interval - 20 * IN_MILLISECONDS))
|
||||||
player->SaveToDB();
|
{ player->SaveToDB(); }
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -176,8 +177,8 @@ bool ChatHandler::HandleGMListIngameCommand(char* /*args*/)
|
||||||
{
|
{
|
||||||
AccountTypes itr_sec = itr->second->GetSession()->GetSecurity();
|
AccountTypes itr_sec = itr->second->GetSession()->GetSecurity();
|
||||||
if ((itr->second->isGameMaster() || (itr_sec > SEC_PLAYER && itr_sec <= (AccountTypes)sWorld.getConfig(CONFIG_UINT32_GM_LEVEL_IN_GM_LIST))) &&
|
if ((itr->second->isGameMaster() || (itr_sec > SEC_PLAYER && itr_sec <= (AccountTypes)sWorld.getConfig(CONFIG_UINT32_GM_LEVEL_IN_GM_LIST))) &&
|
||||||
(!m_session || itr->second->IsVisibleGloballyFor(m_session->GetPlayer())))
|
(!m_session || itr->second->IsVisibleGloballyFor(m_session->GetPlayer())))
|
||||||
names.push_back(std::make_pair<std::string, bool>(GetNameLink(itr->second), itr->second->isAcceptWhispers()));
|
{ names.push_back(std::make_pair<std::string, bool>(GetNameLink(itr->second), itr->second->isAcceptWhispers())); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -188,10 +189,10 @@ bool ChatHandler::HandleGMListIngameCommand(char* /*args*/)
|
||||||
char const* accepts = GetMangosString(LANG_GM_ACCEPTS_WHISPER);
|
char const* accepts = GetMangosString(LANG_GM_ACCEPTS_WHISPER);
|
||||||
char const* not_accept = GetMangosString(LANG_GM_NO_WHISPER);
|
char const* not_accept = GetMangosString(LANG_GM_NO_WHISPER);
|
||||||
for (std::list<std::pair< std::string, bool> >::const_iterator iter = names.begin(); iter != names.end(); ++iter)
|
for (std::list<std::pair< std::string, bool> >::const_iterator iter = names.begin(); iter != names.end(); ++iter)
|
||||||
PSendSysMessage("%s - %s", iter->first.c_str(), iter->second ? accepts : not_accept);
|
{ PSendSysMessage("%s - %s", iter->first.c_str(), iter->second ? accepts : not_accept); }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SendSysMessage(LANG_GMS_NOT_LOGGED);
|
{ SendSysMessage(LANG_GMS_NOT_LOGGED); }
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -212,7 +213,7 @@ bool ChatHandler::HandleAccountPasswordCommand(char* args)
|
||||||
char* new_pass_c = ExtractQuotedOrLiteralArg(&args);
|
char* new_pass_c = ExtractQuotedOrLiteralArg(&args);
|
||||||
|
|
||||||
if (!old_pass || !new_pass || !new_pass_c)
|
if (!old_pass || !new_pass || !new_pass_c)
|
||||||
return false;
|
{ return false; }
|
||||||
|
|
||||||
std::string password_old = old_pass;
|
std::string password_old = old_pass;
|
||||||
std::string password_new = new_pass;
|
std::string password_new = new_pass;
|
||||||
|
|
|
||||||
|
|
@ -230,7 +230,7 @@ std::string Warden::Penalty(WardenCheck* check /*= NULL*/)
|
||||||
banReason << "Warden Anticheat Violation";
|
banReason << "Warden Anticheat Violation";
|
||||||
// Check can be NULL, for example if the client sent a wrong signature in the warden packet (CHECKSUM FAIL)
|
// Check can be NULL, for example if the client sent a wrong signature in the warden packet (CHECKSUM FAIL)
|
||||||
if (check)
|
if (check)
|
||||||
banReason << ": " << check->Comment << " (CheckId: " << check->CheckId << ")";
|
banReason << ": " << (check->Comment.empty() ? std::string("Undocumented Check") : check->Comment) << " (CheckId: " << check->CheckId << ")";
|
||||||
|
|
||||||
sWorld.BanAccount(BAN_ACCOUNT, accountName, sWorld.getConfig(CONFIG_UINT32_WARDEN_CLIENT_BAN_DURATION), banReason.str(), "Warden");
|
sWorld.BanAccount(BAN_ACCOUNT, accountName, sWorld.getConfig(CONFIG_UINT32_WARDEN_CLIENT_BAN_DURATION), banReason.str(), "Warden");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,9 @@
|
||||||
#include "WardenCheckMgr.h"
|
#include "WardenCheckMgr.h"
|
||||||
#include "Database/DatabaseEnv.h"
|
#include "Database/DatabaseEnv.h"
|
||||||
|
|
||||||
|
// the default client version with info in warden_checks; for other version checks, see warden_build_specific
|
||||||
|
#define DEFAULT_CLIENT_BUILD 5875
|
||||||
|
|
||||||
enum WardenOpcodes
|
enum WardenOpcodes
|
||||||
{
|
{
|
||||||
// Client->Server
|
// Client->Server
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ void WardenCheckMgr::LoadWardenChecks()
|
||||||
|
|
||||||
CheckStore.resize(maxCheckId + 1);
|
CheckStore.resize(maxCheckId + 1);
|
||||||
|
|
||||||
|
delete result;
|
||||||
// 0 1 2 3 4 5 6 7
|
// 0 1 2 3 4 5 6 7
|
||||||
result = WorldDatabase.Query("SELECT id, type, data, result, address, length, str, comment FROM warden_checks ORDER BY id ASC");
|
result = WorldDatabase.Query("SELECT id, type, data, result, address, length, str, comment FROM warden_checks ORDER BY id ASC");
|
||||||
|
|
||||||
|
|
@ -147,7 +148,7 @@ void WardenCheckMgr::LoadWardenChecks()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comment.empty())
|
if (comment.empty())
|
||||||
wardenCheck->Comment = "Undocumented Check";
|
wardenCheck->Comment = "";
|
||||||
else
|
else
|
||||||
wardenCheck->Comment = comment;
|
wardenCheck->Comment = comment;
|
||||||
|
|
||||||
|
|
@ -155,6 +156,81 @@ void WardenCheckMgr::LoadWardenChecks()
|
||||||
} while (result->NextRow());
|
} while (result->NextRow());
|
||||||
|
|
||||||
sLog.outWarden(">> Loaded %u warden checks.", count);
|
sLog.outWarden(">> Loaded %u warden checks.", count);
|
||||||
|
|
||||||
|
delete result;
|
||||||
|
// 0 1 2 3 4 5 6
|
||||||
|
result = WorldDatabase.Query("SELECT id, build, data, result, address, length, str FROM warden_build_specific ORDER BY id ASC");
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
sLog.outString("[Warden]: >> Loaded 0 warden client build-specific data.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
fields = result->Fetch();
|
||||||
|
|
||||||
|
uint16 id = fields[0].GetUInt16();
|
||||||
|
if (id >= CheckStore.size())
|
||||||
|
{
|
||||||
|
sLog.outWarden("ERROR: Build-specific, check is missing in warden_checks, skipping id %u.", id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 build = fields[1].GetUInt16();
|
||||||
|
if (build == DEFAULT_CLIENT_BUILD)
|
||||||
|
{
|
||||||
|
sLog.outWarden("ERROR: Build-specific table may not contain checks for default %u build, skipping id %u.", DEFAULT_CLIENT_BUILD, id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//std::string data = fields[2].GetString(); //unused for now
|
||||||
|
std::string checkResult = fields[3].GetString();
|
||||||
|
uint32 address = fields[4].GetUInt32();
|
||||||
|
uint8 length = fields[5].GetUInt8();
|
||||||
|
std::string str = fields[6].GetString();
|
||||||
|
|
||||||
|
WardenCheck* wardenCheck = new WardenCheck();
|
||||||
|
wardenCheck->CheckId = id;
|
||||||
|
wardenCheck->Type = CheckStore[id]->Type;
|
||||||
|
|
||||||
|
WardenCheckResult* wr = new WardenCheckResult();
|
||||||
|
switch (wardenCheck->Type)
|
||||||
|
{
|
||||||
|
case MEM_CHECK:
|
||||||
|
wardenCheck->Address = address;
|
||||||
|
wardenCheck->Length = length;
|
||||||
|
wardenCheck->Str = str;
|
||||||
|
wr->Result.SetHexStr(checkResult.c_str());
|
||||||
|
{
|
||||||
|
int len = checkResult.size() / 2;
|
||||||
|
if (wr->Result.GetNumBytes() < len)
|
||||||
|
{
|
||||||
|
uint8 *temp = new uint8[len];
|
||||||
|
memset(temp, 0, len);
|
||||||
|
memcpy(temp, wr->Result.AsByteArray(), wr->Result.GetNumBytes());
|
||||||
|
std::reverse(temp, temp + len);
|
||||||
|
wr->Result.SetBinary((uint8*)temp, len);
|
||||||
|
delete[] temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sLog.outWarden("The check type %u is considered as build-independent, skipping id %u.", wardenCheck->Type, id);
|
||||||
|
delete wr;
|
||||||
|
delete wardenCheck;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
MCheckStore[ComposeMultiCheckKey(build, id)] = wardenCheck;
|
||||||
|
MCheckResultStore[ComposeMultiCheckKey(build, id)] = wr;
|
||||||
|
++count;
|
||||||
|
|
||||||
|
} while (result->NextRow());
|
||||||
|
|
||||||
|
sLog.outString(">> Loaded %u warden client build-specific check overrides.", count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WardenCheckMgr::LoadWardenOverrides()
|
void WardenCheckMgr::LoadWardenOverrides()
|
||||||
|
|
@ -203,18 +279,34 @@ void WardenCheckMgr::LoadWardenOverrides()
|
||||||
sLog.outWarden(">> Loaded %u warden action overrides.", count);
|
sLog.outWarden(">> Loaded %u warden action overrides.", count);
|
||||||
}
|
}
|
||||||
|
|
||||||
WardenCheck* WardenCheckMgr::GetWardenDataById(uint16 Id)
|
WardenCheck* WardenCheckMgr::GetWardenDataById(uint16 build, uint16 Id)
|
||||||
{
|
{
|
||||||
if (Id < CheckStore.size())
|
if (Id < CheckStore.size())
|
||||||
|
{
|
||||||
|
if (build != DEFAULT_CLIENT_BUILD)
|
||||||
|
{
|
||||||
|
MultiCheckContainer::const_iterator it = MCheckStore.find(ComposeMultiCheckKey(build, Id));
|
||||||
|
if (it != MCheckStore.end())
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
return CheckStore[Id];
|
return CheckStore[Id];
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
WardenCheckResult* WardenCheckMgr::GetWardenResultById(uint16 Id)
|
WardenCheckResult* WardenCheckMgr::GetWardenResultById(uint16 build, uint16 Id)
|
||||||
{
|
{
|
||||||
|
if (build != DEFAULT_CLIENT_BUILD)
|
||||||
|
{
|
||||||
|
MultiResultContainer::const_iterator it = MCheckResultStore.find(ComposeMultiCheckKey(build, Id));
|
||||||
|
if (it != MCheckResultStore.end())
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
CheckResultContainer::const_iterator itr = CheckResultStore.find(Id);
|
CheckResultContainer::const_iterator itr = CheckResultStore.find(Id);
|
||||||
if (itr != CheckResultStore.end())
|
if (itr != CheckResultStore.end())
|
||||||
return itr->second;
|
return itr->second;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,12 +66,8 @@ class WardenCheckMgr
|
||||||
return &instance;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have a linear key without any gaps, so we use vector for fast access
|
WardenCheck* GetWardenDataById(uint16 build, uint16 Id);
|
||||||
typedef std::vector<WardenCheck*> CheckContainer;
|
WardenCheckResult* GetWardenResultById(uint16 build, uint16 Id);
|
||||||
typedef std::map<uint32, WardenCheckResult*> CheckResultContainer;
|
|
||||||
|
|
||||||
WardenCheck* GetWardenDataById(uint16 Id);
|
|
||||||
WardenCheckResult* GetWardenResultById(uint16 Id);
|
|
||||||
|
|
||||||
std::vector<uint16> MemChecksIdPool;
|
std::vector<uint16> MemChecksIdPool;
|
||||||
std::vector<uint16> OtherChecksIdPool;
|
std::vector<uint16> OtherChecksIdPool;
|
||||||
|
|
@ -82,8 +78,21 @@ class WardenCheckMgr
|
||||||
ACE_RW_Mutex _checkStoreLock;
|
ACE_RW_Mutex _checkStoreLock;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
uint32 inline ComposeMultiCheckKey(uint16 clientBuild, uint16 checkID) { return (uint32(checkID) << 16) | clientBuild; }
|
||||||
|
|
||||||
|
// We have a linear key without any gaps, so we use vector for fast access
|
||||||
|
typedef std::vector<WardenCheck*> CheckContainer;
|
||||||
|
typedef std::map<uint32, WardenCheckResult*> CheckResultContainer;
|
||||||
|
|
||||||
CheckContainer CheckStore;
|
CheckContainer CheckStore;
|
||||||
CheckResultContainer CheckResultStore;
|
CheckResultContainer CheckResultStore;
|
||||||
|
|
||||||
|
// here we have just few checks, vector is not appropriate; key is from ComposeMultiCheckKey
|
||||||
|
typedef std::map<uint32 /*MultiCheckKey*/, WardenCheck*> MultiCheckContainer;
|
||||||
|
typedef std::map<uint32 /*MultiCheckKey*/, WardenCheckResult*> MultiResultContainer;
|
||||||
|
|
||||||
|
MultiCheckContainer MCheckStore;
|
||||||
|
MultiResultContainer MCheckResultStore;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define sWardenCheckMgr WardenCheckMgr::instance()
|
#define sWardenCheckMgr WardenCheckMgr::instance()
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ void WardenMac::Init(WorldSession* pClient, BigNumber* K)
|
||||||
|
|
||||||
_inputCrypto.Init(_inputKey);
|
_inputCrypto.Init(_inputKey);
|
||||||
_outputCrypto.Init(_outputKey);
|
_outputCrypto.Init(_outputKey);
|
||||||
sLog.outWarden("Server side warden for client %u initializing...", pClient->GetAccountId());
|
sLog.outWarden("Server side Mac warden for client %u (build %u) initializing...", pClient->GetAccountId(), _session->GetClientBuild());
|
||||||
sLog.outWarden("C->S Key: %s", ByteArrayToHexStr(_inputKey, 16).c_str());
|
sLog.outWarden("C->S Key: %s", ByteArrayToHexStr(_inputKey, 16).c_str());
|
||||||
sLog.outWarden("S->C Key: %s", ByteArrayToHexStr(_outputKey, 16).c_str());
|
sLog.outWarden("S->C Key: %s", ByteArrayToHexStr(_outputKey, 16).c_str());
|
||||||
sLog.outWarden(" Seed: %s", ByteArrayToHexStr(_seed, 16).c_str());
|
sLog.outWarden(" Seed: %s", ByteArrayToHexStr(_seed, 16).c_str());
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ void WardenWin::Init(WorldSession* session, BigNumber* k)
|
||||||
|
|
||||||
_inputCrypto.Init(_inputKey);
|
_inputCrypto.Init(_inputKey);
|
||||||
_outputCrypto.Init(_outputKey);
|
_outputCrypto.Init(_outputKey);
|
||||||
sLog.outWarden("Server side warden for client %u initializing...", session->GetAccountId());
|
sLog.outWarden("Server side warden for client %u (build %u) initializing...", session->GetAccountId(), _session->GetClientBuild());
|
||||||
sLog.outWarden("C->S Key: %s", ByteArrayToHexStr(_inputKey, 16).c_str());
|
sLog.outWarden("C->S Key: %s", ByteArrayToHexStr(_inputKey, 16).c_str());
|
||||||
sLog.outWarden("S->C Key: %s", ByteArrayToHexStr(_outputKey, 16).c_str());
|
sLog.outWarden("S->C Key: %s", ByteArrayToHexStr(_outputKey, 16).c_str());
|
||||||
sLog.outWarden(" Seed: %s", ByteArrayToHexStr(_seed, 16).c_str());
|
sLog.outWarden(" Seed: %s", ByteArrayToHexStr(_seed, 16).c_str());
|
||||||
|
|
@ -210,7 +210,7 @@ void WardenWin::RequestData()
|
||||||
// Add the id to the list sent in this cycle
|
// Add the id to the list sent in this cycle
|
||||||
_currentChecks.push_back(id);
|
_currentChecks.push_back(id);
|
||||||
|
|
||||||
wd = sWardenCheckMgr->GetWardenDataById(id);
|
wd = sWardenCheckMgr->GetWardenDataById(_session->GetClientBuild(), id);
|
||||||
|
|
||||||
switch (wd->Type)
|
switch (wd->Type)
|
||||||
{
|
{
|
||||||
|
|
@ -235,7 +235,7 @@ void WardenWin::RequestData()
|
||||||
|
|
||||||
for (std::list<uint16>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
|
for (std::list<uint16>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
|
||||||
{
|
{
|
||||||
wd = sWardenCheckMgr->GetWardenDataById(*itr);
|
wd = sWardenCheckMgr->GetWardenDataById(_session->GetClientBuild(), *itr);
|
||||||
|
|
||||||
type = wd->Type;
|
type = wd->Type;
|
||||||
buff << uint8(type ^ xorByte);
|
buff << uint8(type ^ xorByte);
|
||||||
|
|
@ -360,8 +360,8 @@ void WardenWin::HandleData(ByteBuffer &buff)
|
||||||
|
|
||||||
for (std::list<uint16>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
|
for (std::list<uint16>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
|
||||||
{
|
{
|
||||||
rd = sWardenCheckMgr->GetWardenDataById(*itr);
|
rd = sWardenCheckMgr->GetWardenDataById(_session->GetClientBuild(), *itr);
|
||||||
rs = sWardenCheckMgr->GetWardenResultById(*itr);
|
rs = sWardenCheckMgr->GetWardenResultById(_session->GetClientBuild(), *itr);
|
||||||
|
|
||||||
type = rd->Type;
|
type = rd->Type;
|
||||||
switch (type)
|
switch (type)
|
||||||
|
|
@ -475,7 +475,7 @@ void WardenWin::HandleData(ByteBuffer &buff)
|
||||||
|
|
||||||
if (checkFailed > 0)
|
if (checkFailed > 0)
|
||||||
{
|
{
|
||||||
WardenCheck* check = sWardenCheckMgr->GetWardenDataById(checkFailed); //note it IS NOT NULL here
|
WardenCheck* check = sWardenCheckMgr->GetWardenDataById(_session->GetClientBuild(), checkFailed); //note it IS NOT NULL here
|
||||||
sLog.outWarden("%s failed Warden check %u. Action: %s", _session->GetPlayerName(), checkFailed, Penalty(check).c_str());
|
sLog.outWarden("%s failed Warden check %u. Action: %s", _session->GetPlayerName(), checkFailed, Penalty(check).c_str());
|
||||||
LogPositiveToDB(check);
|
LogPositiveToDB(check);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ struct WardenInitModuleRequest
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class WorldSession;
|
class WorldSession;
|
||||||
class Warden;
|
//class Warden;
|
||||||
|
|
||||||
class WardenWin : public Warden
|
class WardenWin : public Warden
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,9 @@
|
||||||
// Warden
|
// Warden
|
||||||
#include "WardenCheckMgr.h"
|
#include "WardenCheckMgr.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
INSTANTIATE_SINGLETON_1(World);
|
INSTANTIATE_SINGLETON_1(World);
|
||||||
|
|
||||||
extern void LoadGameObjectModelList();
|
extern void LoadGameObjectModelList();
|
||||||
|
|
@ -122,16 +125,16 @@ World::World()
|
||||||
m_availableDbcLocaleMask = 0;
|
m_availableDbcLocaleMask = 0;
|
||||||
|
|
||||||
for (int i = 0; i < CONFIG_UINT32_VALUE_COUNT; ++i)
|
for (int i = 0; i < CONFIG_UINT32_VALUE_COUNT; ++i)
|
||||||
m_configUint32Values[i] = 0;
|
{ m_configUint32Values[i] = 0; }
|
||||||
|
|
||||||
for (int i = 0; i < CONFIG_INT32_VALUE_COUNT; ++i)
|
for (int i = 0; i < CONFIG_INT32_VALUE_COUNT; ++i)
|
||||||
m_configInt32Values[i] = 0;
|
{ m_configInt32Values[i] = 0; }
|
||||||
|
|
||||||
for (int i = 0; i < CONFIG_FLOAT_VALUE_COUNT; ++i)
|
for (int i = 0; i < CONFIG_FLOAT_VALUE_COUNT; ++i)
|
||||||
m_configFloatValues[i] = 0.0f;
|
{ m_configFloatValues[i] = 0.0f; }
|
||||||
|
|
||||||
for (int i = 0; i < CONFIG_BOOL_VALUE_COUNT; ++i)
|
for (int i = 0; i < CONFIG_BOOL_VALUE_COUNT; ++i)
|
||||||
m_configBoolValues[i] = false;
|
{ m_configBoolValues[i] = false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// World destructor
|
/// World destructor
|
||||||
|
|
@ -153,7 +156,7 @@ World::~World()
|
||||||
|
|
||||||
CliCommandHolder* command = NULL;
|
CliCommandHolder* command = NULL;
|
||||||
while (cliCmdQueue.next(command))
|
while (cliCmdQueue.next(command))
|
||||||
delete command;
|
{ delete command; }
|
||||||
|
|
||||||
VMAP::VMapFactory::clear();
|
VMAP::VMapFactory::clear();
|
||||||
MMAP::MMapFactory::clear();
|
MMAP::MMapFactory::clear();
|
||||||
|
|
@ -167,6 +170,9 @@ void World::CleanupsBeforeStop()
|
||||||
KickAll(); // save and kick all players
|
KickAll(); // save and kick all players
|
||||||
UpdateSessions(1); // real players unload required UpdateSessions call
|
UpdateSessions(1); // real players unload required UpdateSessions call
|
||||||
sBattleGroundMgr.DeleteAllBattleGrounds(); // unload battleground templates before different singletons destroyed
|
sBattleGroundMgr.DeleteAllBattleGrounds(); // unload battleground templates before different singletons destroyed
|
||||||
|
#ifdef ENABLE_ELUNA
|
||||||
|
Eluna::Uninitialize();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find a player in a specified zone
|
/// Find a player in a specified zone
|
||||||
|
|
@ -196,9 +202,9 @@ WorldSession* World::FindSession(uint32 id) const
|
||||||
SessionMap::const_iterator itr = m_sessions.find(id);
|
SessionMap::const_iterator itr = m_sessions.find(id);
|
||||||
|
|
||||||
if (itr != m_sessions.end())
|
if (itr != m_sessions.end())
|
||||||
return itr->second; // also can return NULL for kicked session
|
{ return itr->second; } // also can return NULL for kicked session
|
||||||
else
|
else
|
||||||
return NULL;
|
{ return NULL; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove a given session
|
/// Remove a given session
|
||||||
|
|
@ -210,7 +216,7 @@ bool World::RemoveSession(uint32 id)
|
||||||
if (itr != m_sessions.end() && itr->second)
|
if (itr != m_sessions.end() && itr->second)
|
||||||
{
|
{
|
||||||
if (itr->second->PlayerLoading())
|
if (itr->second->PlayerLoading())
|
||||||
return false;
|
{ return false; }
|
||||||
itr->second->KickPlayer();
|
itr->second->KickPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -250,7 +256,7 @@ World::AddSession_(WorldSession* s)
|
||||||
{
|
{
|
||||||
// prevent decrease sessions count if session queued
|
// prevent decrease sessions count if session queued
|
||||||
if (RemoveQueuedSession(old->second))
|
if (RemoveQueuedSession(old->second))
|
||||||
decrease_session = false;
|
{ decrease_session = false; }
|
||||||
// not remove replaced session form queue if listed
|
// not remove replaced session form queue if listed
|
||||||
delete old->second;
|
delete old->second;
|
||||||
}
|
}
|
||||||
|
|
@ -265,7 +271,7 @@ World::AddSession_(WorldSession* s)
|
||||||
// so we don't count the user trying to
|
// so we don't count the user trying to
|
||||||
// login as a session and queue the socket that we are using
|
// login as a session and queue the socket that we are using
|
||||||
if (decrease_session)
|
if (decrease_session)
|
||||||
--Sessions;
|
{ --Sessions; }
|
||||||
|
|
||||||
if (pLimit > 0 && Sessions >= pLimit && s->GetSecurity() == SEC_PLAYER)
|
if (pLimit > 0 && Sessions >= pLimit && s->GetSecurity() == SEC_PLAYER)
|
||||||
{
|
{
|
||||||
|
|
@ -322,7 +328,7 @@ int32 World::GetQueuedSessionPos(WorldSession* sess)
|
||||||
|
|
||||||
for (Queue::const_iterator iter = m_QueuedSessions.begin(); iter != m_QueuedSessions.end(); ++iter, ++position)
|
for (Queue::const_iterator iter = m_QueuedSessions.begin(); iter != m_QueuedSessions.end(); ++iter, ++position)
|
||||||
if ((*iter) == sess)
|
if ((*iter) == sess)
|
||||||
return position;
|
{ return position; }
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -378,7 +384,7 @@ bool World::RemoveQueuedSession(WorldSession* sess)
|
||||||
|
|
||||||
// if session not queued then we need decrease sessions count
|
// if session not queued then we need decrease sessions count
|
||||||
if (!found && sessions)
|
if (!found && sessions)
|
||||||
--sessions;
|
{ --sessions; }
|
||||||
|
|
||||||
// accept first in queue
|
// accept first in queue
|
||||||
if ((!m_playerLimit || (int32)sessions < m_playerLimit) && !m_QueuedSessions.empty())
|
if ((!m_playerLimit || (int32)sessions < m_playerLimit) && !m_QueuedSessions.empty())
|
||||||
|
|
@ -405,7 +411,7 @@ bool World::RemoveQueuedSession(WorldSession* sess)
|
||||||
// update position from iter to end()
|
// update position from iter to end()
|
||||||
// iter point to first not updated socket, position store new position
|
// iter point to first not updated socket, position store new position
|
||||||
for (; iter != m_QueuedSessions.end(); ++iter, ++position)
|
for (; iter != m_QueuedSessions.end(); ++iter, ++position)
|
||||||
(*iter)->SendAuthWaitQue(position);
|
{ (*iter)->SendAuthWaitQue(position); }
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
@ -580,22 +586,22 @@ void World::LoadConfigSettings(bool reload)
|
||||||
|
|
||||||
setConfigMin(CONFIG_UINT32_INTERVAL_GRIDCLEAN, "GridCleanUpDelay", 5 * MINUTE * IN_MILLISECONDS, MIN_GRID_DELAY);
|
setConfigMin(CONFIG_UINT32_INTERVAL_GRIDCLEAN, "GridCleanUpDelay", 5 * MINUTE * IN_MILLISECONDS, MIN_GRID_DELAY);
|
||||||
if (reload)
|
if (reload)
|
||||||
sMapMgr.SetGridCleanUpDelay(getConfig(CONFIG_UINT32_INTERVAL_GRIDCLEAN));
|
{ sMapMgr.SetGridCleanUpDelay(getConfig(CONFIG_UINT32_INTERVAL_GRIDCLEAN)); }
|
||||||
|
|
||||||
setConfigMin(CONFIG_UINT32_INTERVAL_MAPUPDATE, "MapUpdateInterval", 100, MIN_MAP_UPDATE_DELAY);
|
setConfigMin(CONFIG_UINT32_INTERVAL_MAPUPDATE, "MapUpdateInterval", 100, MIN_MAP_UPDATE_DELAY);
|
||||||
if (reload)
|
if (reload)
|
||||||
sMapMgr.SetMapUpdateInterval(getConfig(CONFIG_UINT32_INTERVAL_MAPUPDATE));
|
{ sMapMgr.SetMapUpdateInterval(getConfig(CONFIG_UINT32_INTERVAL_MAPUPDATE)); }
|
||||||
|
|
||||||
setConfig(CONFIG_UINT32_INTERVAL_CHANGEWEATHER, "ChangeWeatherInterval", 10 * MINUTE * IN_MILLISECONDS);
|
setConfig(CONFIG_UINT32_INTERVAL_CHANGEWEATHER, "ChangeWeatherInterval", 10 * MINUTE * IN_MILLISECONDS);
|
||||||
|
|
||||||
if (configNoReload(reload, CONFIG_UINT32_PORT_WORLD, "WorldServerPort", DEFAULT_WORLDSERVER_PORT))
|
if (configNoReload(reload, CONFIG_UINT32_PORT_WORLD, "WorldServerPort", DEFAULT_WORLDSERVER_PORT))
|
||||||
setConfig(CONFIG_UINT32_PORT_WORLD, "WorldServerPort", DEFAULT_WORLDSERVER_PORT);
|
{ setConfig(CONFIG_UINT32_PORT_WORLD, "WorldServerPort", DEFAULT_WORLDSERVER_PORT); }
|
||||||
|
|
||||||
if (configNoReload(reload, CONFIG_UINT32_GAME_TYPE, "GameType", 0))
|
if (configNoReload(reload, CONFIG_UINT32_GAME_TYPE, "GameType", 0))
|
||||||
setConfig(CONFIG_UINT32_GAME_TYPE, "GameType", 0);
|
{ setConfig(CONFIG_UINT32_GAME_TYPE, "GameType", 0); }
|
||||||
|
|
||||||
if (configNoReload(reload, CONFIG_UINT32_REALM_ZONE, "RealmZone", REALM_ZONE_DEVELOPMENT))
|
if (configNoReload(reload, CONFIG_UINT32_REALM_ZONE, "RealmZone", REALM_ZONE_DEVELOPMENT))
|
||||||
setConfig(CONFIG_UINT32_REALM_ZONE, "RealmZone", REALM_ZONE_DEVELOPMENT);
|
{ setConfig(CONFIG_UINT32_REALM_ZONE, "RealmZone", REALM_ZONE_DEVELOPMENT); }
|
||||||
|
|
||||||
setConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_ACCOUNTS, "AllowTwoSide.Accounts", true);
|
setConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_ACCOUNTS, "AllowTwoSide.Accounts", true);
|
||||||
setConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_CHAT, "AllowTwoSide.Interaction.Chat", false);
|
setConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_INTERACTION_CHAT, "AllowTwoSide.Interaction.Chat", false);
|
||||||
|
|
@ -630,7 +636,7 @@ void World::LoadConfigSettings(bool reload)
|
||||||
setConfigMinMax(CONFIG_UINT32_SKIP_CINEMATICS, "SkipCinematics", 0, 0, 2);
|
setConfigMinMax(CONFIG_UINT32_SKIP_CINEMATICS, "SkipCinematics", 0, 0, 2);
|
||||||
|
|
||||||
if (configNoReload(reload, CONFIG_UINT32_MAX_PLAYER_LEVEL, "MaxPlayerLevel", DEFAULT_MAX_LEVEL))
|
if (configNoReload(reload, CONFIG_UINT32_MAX_PLAYER_LEVEL, "MaxPlayerLevel", DEFAULT_MAX_LEVEL))
|
||||||
setConfigMinMax(CONFIG_UINT32_MAX_PLAYER_LEVEL, "MaxPlayerLevel", DEFAULT_MAX_LEVEL, 1, DEFAULT_MAX_LEVEL);
|
{ setConfigMinMax(CONFIG_UINT32_MAX_PLAYER_LEVEL, "MaxPlayerLevel", DEFAULT_MAX_LEVEL, 1, DEFAULT_MAX_LEVEL); }
|
||||||
|
|
||||||
setConfigMinMax(CONFIG_UINT32_START_PLAYER_LEVEL, "StartPlayerLevel", 1, 1, getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL));
|
setConfigMinMax(CONFIG_UINT32_START_PLAYER_LEVEL, "StartPlayerLevel", 1, 1, getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL));
|
||||||
setConfigMinMax(CONFIG_UINT32_START_HEROIC_PLAYER_LEVEL, "StartHeroicPlayerLevel", 55, 1, getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL));
|
setConfigMinMax(CONFIG_UINT32_START_HEROIC_PLAYER_LEVEL, "StartHeroicPlayerLevel", 55, 1, getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL));
|
||||||
|
|
@ -904,9 +910,9 @@ void World::LoadConfigSettings(bool reload)
|
||||||
setConfig(CONFIG_UINT32_CHARDELETE_KEEP_DAYS, "CharDelete.KeepDays", 30);
|
setConfig(CONFIG_UINT32_CHARDELETE_KEEP_DAYS, "CharDelete.KeepDays", 30);
|
||||||
|
|
||||||
if (configNoReload(reload, CONFIG_UINT32_GUID_RESERVE_SIZE_CREATURE, "GuidReserveSize.Creature", 100))
|
if (configNoReload(reload, CONFIG_UINT32_GUID_RESERVE_SIZE_CREATURE, "GuidReserveSize.Creature", 100))
|
||||||
setConfig(CONFIG_UINT32_GUID_RESERVE_SIZE_CREATURE, "GuidReserveSize.Creature", 100);
|
{ setConfig(CONFIG_UINT32_GUID_RESERVE_SIZE_CREATURE, "GuidReserveSize.Creature", 100); }
|
||||||
if (configNoReload(reload, CONFIG_UINT32_GUID_RESERVE_SIZE_GAMEOBJECT, "GuidReserveSize.GameObject", 100))
|
if (configNoReload(reload, CONFIG_UINT32_GUID_RESERVE_SIZE_GAMEOBJECT, "GuidReserveSize.GameObject", 100))
|
||||||
setConfig(CONFIG_UINT32_GUID_RESERVE_SIZE_GAMEOBJECT, "GuidReserveSize.GameObject", 100);
|
{ setConfig(CONFIG_UINT32_GUID_RESERVE_SIZE_GAMEOBJECT, "GuidReserveSize.GameObject", 100); }
|
||||||
|
|
||||||
setConfig(CONFIG_UINT32_MIN_LEVEL_FOR_RAID, "Raid.MinLevel", 10);
|
setConfig(CONFIG_UINT32_MIN_LEVEL_FOR_RAID, "Raid.MinLevel", 10);
|
||||||
|
|
||||||
|
|
@ -915,15 +921,15 @@ void World::LoadConfigSettings(bool reload)
|
||||||
|
|
||||||
// for empty string use current dir as for absent case
|
// for empty string use current dir as for absent case
|
||||||
if (dataPath.empty())
|
if (dataPath.empty())
|
||||||
dataPath = "./";
|
{ dataPath = "./"; }
|
||||||
// normalize dir path to path/ or path\ form
|
// normalize dir path to path/ or path\ form
|
||||||
else if (dataPath.at(dataPath.length() - 1) != '/' && dataPath.at(dataPath.length() - 1) != '\\')
|
else if (dataPath.at(dataPath.length() - 1) != '/' && dataPath.at(dataPath.length() - 1) != '\\')
|
||||||
dataPath.append("/");
|
{ dataPath.append("/"); }
|
||||||
|
|
||||||
if (reload)
|
if (reload)
|
||||||
{
|
{
|
||||||
if (dataPath != m_dataPath)
|
if (dataPath != m_dataPath)
|
||||||
sLog.outError("DataDir option can't be changed at mangosd.conf reload, using current value (%s).", m_dataPath.c_str());
|
{ sLog.outError("DataDir option can't be changed at mangosd.conf reload, using current value (%s).", m_dataPath.c_str()); }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -937,7 +943,7 @@ void World::LoadConfigSettings(bool reload)
|
||||||
std::string ignoreSpellIds = sConfig.GetStringDefault("vmap.ignoreSpellIds", "");
|
std::string ignoreSpellIds = sConfig.GetStringDefault("vmap.ignoreSpellIds", "");
|
||||||
|
|
||||||
if (!enableHeight)
|
if (!enableHeight)
|
||||||
sLog.outError("VMAP height use disabled! Creatures movements and other things will be in broken state.");
|
{ sLog.outError("VMAP height use disabled! Creatures movements and other things will be in broken state."); }
|
||||||
|
|
||||||
VMAP::VMapFactory::createOrGetVMapManager()->setEnableLineOfSightCalc(enableLOS);
|
VMAP::VMapFactory::createOrGetVMapManager()->setEnableLineOfSightCalc(enableLOS);
|
||||||
VMAP::VMapFactory::createOrGetVMapManager()->setEnableHeightCalc(enableHeight);
|
VMAP::VMapFactory::createOrGetVMapManager()->setEnableHeightCalc(enableHeight);
|
||||||
|
|
@ -950,6 +956,13 @@ void World::LoadConfigSettings(bool reload)
|
||||||
std::string ignoreMapIds = sConfig.GetStringDefault("mmap.ignoreMapIds", "");
|
std::string ignoreMapIds = sConfig.GetStringDefault("mmap.ignoreMapIds", "");
|
||||||
MMAP::MMapFactory::preventPathfindingOnMaps(ignoreMapIds.c_str());
|
MMAP::MMapFactory::preventPathfindingOnMaps(ignoreMapIds.c_str());
|
||||||
sLog.outString("WORLD: mmap pathfinding %sabled", getConfig(CONFIG_BOOL_MMAP_ENABLED) ? "en" : "dis");
|
sLog.outString("WORLD: mmap pathfinding %sabled", getConfig(CONFIG_BOOL_MMAP_ENABLED) ? "en" : "dis");
|
||||||
|
|
||||||
|
setConfig(CONFIG_BOOL_ELUNA_ENABLED, "Eluna.Enabled", true);
|
||||||
|
|
||||||
|
#ifdef ENABLE_ELUNA
|
||||||
|
if (reload)
|
||||||
|
sEluna->OnConfigLoad(reload);
|
||||||
|
#endif /* ENABLE_ELUNA */
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize the World
|
/// Initialize the World
|
||||||
|
|
@ -2012,7 +2025,7 @@ void World::ShutdownMsg(bool show /*= false*/, Player* player /*= NULL*/)
|
||||||
{
|
{
|
||||||
// not show messages for idle shutdown mode
|
// not show messages for idle shutdown mode
|
||||||
if (m_ShutdownMask & SHUTDOWN_MASK_IDLE)
|
if (m_ShutdownMask & SHUTDOWN_MASK_IDLE)
|
||||||
return;
|
{ return; }
|
||||||
|
|
||||||
///- Display a message every 12 hours, 1 hour, 5 minutes, 1 minute and 15 seconds
|
///- Display a message every 12 hours, 1 hour, 5 minutes, 1 minute and 15 seconds
|
||||||
if (show ||
|
if (show ||
|
||||||
|
|
@ -2036,7 +2049,7 @@ void World::ShutdownCancel()
|
||||||
{
|
{
|
||||||
// nothing cancel or too later
|
// nothing cancel or too later
|
||||||
if (!m_ShutdownTimer || m_stopEvent)
|
if (!m_ShutdownTimer || m_stopEvent)
|
||||||
return;
|
{ return; }
|
||||||
|
|
||||||
ServerMessageType msgid = (m_ShutdownMask & SHUTDOWN_MASK_RESTART) ? SERVER_MSG_RESTART_CANCELLED : SERVER_MSG_SHUTDOWN_CANCELLED;
|
ServerMessageType msgid = (m_ShutdownMask & SHUTDOWN_MASK_RESTART) ? SERVER_MSG_RESTART_CANCELLED : SERVER_MSG_SHUTDOWN_CANCELLED;
|
||||||
|
|
||||||
|
|
@ -2046,6 +2059,11 @@ void World::ShutdownCancel()
|
||||||
SendServerMessage(msgid);
|
SendServerMessage(msgid);
|
||||||
|
|
||||||
DEBUG_LOG("Server %s cancelled.", (m_ShutdownMask & SHUTDOWN_MASK_RESTART ? "restart" : "shutdown"));
|
DEBUG_LOG("Server %s cancelled.", (m_ShutdownMask & SHUTDOWN_MASK_RESTART ? "restart" : "shutdown"));
|
||||||
|
|
||||||
|
///- Used by Eluna
|
||||||
|
#ifdef ENABLE_ELUNA
|
||||||
|
sEluna->OnShutdownCancel();
|
||||||
|
#endif /* ENABLE_ELUNA */
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::UpdateSessions(uint32 diff)
|
void World::UpdateSessions(uint32 diff)
|
||||||
|
|
@ -2053,7 +2071,7 @@ void World::UpdateSessions(uint32 diff)
|
||||||
///- Add new sessions
|
///- Add new sessions
|
||||||
WorldSession* sess;
|
WorldSession* sess;
|
||||||
while (addSessQueue.next(sess))
|
while (addSessQueue.next(sess))
|
||||||
AddSession_(sess);
|
{ AddSession_(sess); }
|
||||||
|
|
||||||
///- Then send an update signal to remaining ones
|
///- Then send an update signal to remaining ones
|
||||||
for (SessionMap::iterator itr = m_sessions.begin(), next; itr != m_sessions.end(); itr = next)
|
for (SessionMap::iterator itr = m_sessions.begin(), next; itr != m_sessions.end(); itr = next)
|
||||||
|
|
@ -2088,7 +2106,7 @@ void World::ProcessCliCommands()
|
||||||
handler.ParseCommands(command->m_command);
|
handler.ParseCommands(command->m_command);
|
||||||
|
|
||||||
if (command->m_commandFinished)
|
if (command->m_commandFinished)
|
||||||
command->m_commandFinished(callbackArg, !handler.HasSentErrorMessage());
|
{ command->m_commandFinished(callbackArg, !handler.HasSentErrorMessage()); }
|
||||||
|
|
||||||
delete command;
|
delete command;
|
||||||
}
|
}
|
||||||
|
|
@ -2400,24 +2418,27 @@ void World::UpdateMaxSessionCounters()
|
||||||
|
|
||||||
void World::LoadDBVersion()
|
void World::LoadDBVersion()
|
||||||
{
|
{
|
||||||
QueryResult* result = WorldDatabase.Query("SELECT version, creature_ai_version, cache_id FROM db_version LIMIT 1");
|
QueryResult* result = WorldDatabase.Query("SELECT version, structure, content FROM db_version ORDER BY version DESC, structure DESC, content DESC LIMIT 1");
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
Field* fields = result->Fetch();
|
Field* fields = result->Fetch();
|
||||||
|
|
||||||
m_DBVersion = fields[0].GetCppString();
|
uint32 version = fields[0].GetUInt32();
|
||||||
m_CreatureEventAIVersion = fields[1].GetCppString();
|
uint32 structure = fields[1].GetUInt32();
|
||||||
|
uint32 content = fields[2].GetUInt32();
|
||||||
|
|
||||||
// will be overwrite by config values if different and non-0
|
// will be overwrite by config values if different and non-0
|
||||||
setConfig(CONFIG_UINT32_CLIENTCACHE_VERSION, fields[2].GetUInt32());
|
setConfig(CONFIG_UINT32_CLIENTCACHE_VERSION, fields[2].GetUInt32());
|
||||||
delete result;
|
delete result;
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Version: " << version << ", Structure: " << structure << ", Content: " << content;
|
||||||
|
|
||||||
|
m_DBVersion = ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_DBVersion.empty())
|
if (m_DBVersion.empty())
|
||||||
m_DBVersion = "Unknown world database.";
|
{ m_DBVersion = "Unknown world database."; }
|
||||||
|
|
||||||
if (m_CreatureEventAIVersion.empty())
|
|
||||||
m_CreatureEventAIVersion = "Unknown creature EventAI.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::setConfig(eConfigUInt64Values index, char const* fieldname, uint64 defvalue)
|
void World::setConfig(eConfigUInt64Values index, char const* fieldname, uint64 defvalue)
|
||||||
|
|
@ -2598,11 +2619,11 @@ void World::setConfigMinMax(eConfigFloatValues index, char const* fieldname, flo
|
||||||
bool World::configNoReload(bool reload, eConfigUInt32Values index, char const* fieldname, uint32 defvalue)
|
bool World::configNoReload(bool reload, eConfigUInt32Values index, char const* fieldname, uint32 defvalue)
|
||||||
{
|
{
|
||||||
if (!reload)
|
if (!reload)
|
||||||
return true;
|
{ return true; }
|
||||||
|
|
||||||
uint32 val = sConfig.GetIntDefault(fieldname, defvalue);
|
uint32 val = sConfig.GetIntDefault(fieldname, defvalue);
|
||||||
if (val != getConfig(index))
|
if (val != getConfig(index))
|
||||||
sLog.outError("%s option can't be changed at mangosd.conf reload, using current value (%u).", fieldname, getConfig(index));
|
{ sLog.outError("%s option can't be changed at mangosd.conf reload, using current value (%u).", fieldname, getConfig(index)); }
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2610,11 +2631,11 @@ bool World::configNoReload(bool reload, eConfigUInt32Values index, char const* f
|
||||||
bool World::configNoReload(bool reload, eConfigInt32Values index, char const* fieldname, int32 defvalue)
|
bool World::configNoReload(bool reload, eConfigInt32Values index, char const* fieldname, int32 defvalue)
|
||||||
{
|
{
|
||||||
if (!reload)
|
if (!reload)
|
||||||
return true;
|
{ return true; }
|
||||||
|
|
||||||
int32 val = sConfig.GetIntDefault(fieldname, defvalue);
|
int32 val = sConfig.GetIntDefault(fieldname, defvalue);
|
||||||
if (val != getConfig(index))
|
if (val != getConfig(index))
|
||||||
sLog.outError("%s option can't be changed at mangosd.conf reload, using current value (%i).", fieldname, getConfig(index));
|
{ sLog.outError("%s option can't be changed at mangosd.conf reload, using current value (%i).", fieldname, getConfig(index)); }
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2622,11 +2643,11 @@ bool World::configNoReload(bool reload, eConfigInt32Values index, char const* fi
|
||||||
bool World::configNoReload(bool reload, eConfigFloatValues index, char const* fieldname, float defvalue)
|
bool World::configNoReload(bool reload, eConfigFloatValues index, char const* fieldname, float defvalue)
|
||||||
{
|
{
|
||||||
if (!reload)
|
if (!reload)
|
||||||
return true;
|
{ return true; }
|
||||||
|
|
||||||
float val = sConfig.GetFloatDefault(fieldname, defvalue);
|
float val = sConfig.GetFloatDefault(fieldname, defvalue);
|
||||||
if (val != getConfig(index))
|
if (val != getConfig(index))
|
||||||
sLog.outError("%s option can't be changed at mangosd.conf reload, using current value (%f).", fieldname, getConfig(index));
|
{ sLog.outError("%s option can't be changed at mangosd.conf reload, using current value (%f).", fieldname, getConfig(index)); }
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2634,11 +2655,11 @@ bool World::configNoReload(bool reload, eConfigFloatValues index, char const* fi
|
||||||
bool World::configNoReload(bool reload, eConfigBoolValues index, char const* fieldname, bool defvalue)
|
bool World::configNoReload(bool reload, eConfigBoolValues index, char const* fieldname, bool defvalue)
|
||||||
{
|
{
|
||||||
if (!reload)
|
if (!reload)
|
||||||
return true;
|
{ return true; }
|
||||||
|
|
||||||
bool val = sConfig.GetBoolDefault(fieldname, defvalue);
|
bool val = sConfig.GetBoolDefault(fieldname, defvalue);
|
||||||
if (val != getConfig(index))
|
if (val != getConfig(index))
|
||||||
sLog.outError("%s option can't be changed at mangosd.conf reload, using current value (%s).", fieldname, getConfig(index) ? "'true'" : "'false'");
|
{ sLog.outError("%s option can't be changed at mangosd.conf reload, using current value (%s).", fieldname, getConfig(index) ? "'true'" : "'false'"); }
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
class Object;
|
class Object;
|
||||||
|
class ObjectGuid;
|
||||||
class WorldPacket;
|
class WorldPacket;
|
||||||
class WorldSession;
|
class WorldSession;
|
||||||
class Player;
|
class Player;
|
||||||
|
|
@ -379,6 +380,7 @@ enum eConfigBoolValues
|
||||||
CONFIG_BOOL_VMAP_INDOOR_CHECK,
|
CONFIG_BOOL_VMAP_INDOOR_CHECK,
|
||||||
CONFIG_BOOL_PET_UNSUMMON_AT_MOUNT,
|
CONFIG_BOOL_PET_UNSUMMON_AT_MOUNT,
|
||||||
CONFIG_BOOL_MMAP_ENABLED,
|
CONFIG_BOOL_MMAP_ENABLED,
|
||||||
|
CONFIG_BOOL_ELUNA_ENABLED,
|
||||||
CONFIG_BOOL_PLAYER_COMMANDS,
|
CONFIG_BOOL_PLAYER_COMMANDS,
|
||||||
CONFIG_BOOL_GUILD_LEVELING_ENABLED,
|
CONFIG_BOOL_GUILD_LEVELING_ENABLED,
|
||||||
// Warden
|
// Warden
|
||||||
|
|
@ -641,7 +643,6 @@ class World
|
||||||
// used World DB version
|
// used World DB version
|
||||||
void LoadDBVersion();
|
void LoadDBVersion();
|
||||||
char const* GetDBVersion() { return m_DBVersion.c_str(); }
|
char const* GetDBVersion() { return m_DBVersion.c_str(); }
|
||||||
char const* GetCreatureEventAIVersion() { return m_CreatureEventAIVersion.c_str(); }
|
|
||||||
|
|
||||||
void UpdatePhaseDefinitions();
|
void UpdatePhaseDefinitions();
|
||||||
|
|
||||||
|
|
@ -748,7 +749,6 @@ class World
|
||||||
|
|
||||||
// used versions
|
// used versions
|
||||||
std::string m_DBVersion;
|
std::string m_DBVersion;
|
||||||
std::string m_CreatureEventAIVersion;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern uint32 realmID;
|
extern uint32 realmID;
|
||||||
|
|
|
||||||
|
|
@ -168,12 +168,12 @@ if(WIN32)
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
add_custom_command(TARGET ${EXECUTABLE_NAME}
|
add_custom_command(TARGET ${EXECUTABLE_NAME}
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy "${MYSQL_INCLUDE_DIR}/../lib/libmysql.dll" "${CMAKE_BINARY_DIR}/bin/$(Configuration)/"
|
COMMAND ${CMAKE_COMMAND} -E copy "${MYSQL_LIBRARY}" "${CMAKE_BINARY_DIR}/bin/$(Configuration)/"
|
||||||
)
|
)
|
||||||
elseif(XCODE)
|
elseif(XCODE)
|
||||||
add_custom_command(TARGET ${EXECUTABLE_NAME}
|
add_custom_command(TARGET ${EXECUTABLE_NAME}
|
||||||
POST_BUILD
|
POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy "${MYSQL_INCLUDE_DIR}/../lib/libmysql.dll" "${CMAKE_BINARY_DIR}/bin/"
|
COMMAND ${CMAKE_COMMAND} -E copy "${MYSQL_LIBRARY}" "${CMAKE_BINARY_DIR}/bin/"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -580,7 +580,7 @@ bool ChatHandler::HandleServerLogLevelCommand(char* args)
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
#ifdef linux
|
#if (PLATFORM == PLATFORM_APPLE) || (PLATFORM == PLATFORM_UNIX)
|
||||||
// Non-blocking keypress detector, when return pressed, return 1, else always return 0
|
// Non-blocking keypress detector, when return pressed, return 1, else always return 0
|
||||||
int kb_hit_return()
|
int kb_hit_return()
|
||||||
{
|
{
|
||||||
|
|
@ -617,7 +617,7 @@ void CliRunnable::run()
|
||||||
while (!World::IsStopped())
|
while (!World::IsStopped())
|
||||||
{
|
{
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
#ifdef linux
|
#if (PLATFORM == PLATFORM_APPLE) || (PLATFORM == PLATFORM_UNIX)
|
||||||
while (!kb_hit_return() && !World::IsStopped())
|
while (!kb_hit_return() && !World::IsStopped())
|
||||||
// With this, we limit CLI to 10commands/second
|
// With this, we limit CLI to 10commands/second
|
||||||
{ usleep(100); }
|
{ usleep(100); }
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@
|
||||||
char serviceName[] = "mangosd";
|
char serviceName[] = "mangosd";
|
||||||
char serviceLongName[] = "MaNGOS world service";
|
char serviceLongName[] = "MaNGOS world service";
|
||||||
char serviceDescription[] = "Massive Network Game Object Server";
|
char serviceDescription[] = "Massive Network Game Object Server";
|
||||||
|
const char RAW_VMAP_MAGIC[] = "VMAPc06"; /**< used in extracted vmap files with raw data */
|
||||||
/*
|
/*
|
||||||
* -1 - not in service mode
|
* -1 - not in service mode
|
||||||
* 0 - stopped
|
* 0 - stopped
|
||||||
|
|
|
||||||
|
|
@ -465,7 +465,8 @@ bool Master::_StartDB()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!WorldDatabase.CheckRequiredField("db_version", REVISION_DB_MANGOS))
|
///- Check the World database version
|
||||||
|
if(!WorldDatabase.CheckDatabaseVersion(DATABASE_WORLD))
|
||||||
{
|
{
|
||||||
///- Wait for already started DB delay threads to end
|
///- Wait for already started DB delay threads to end
|
||||||
WorldDatabase.HaltDelayThread();
|
WorldDatabase.HaltDelayThread();
|
||||||
|
|
@ -494,7 +495,8 @@ bool Master::_StartDB()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CharacterDatabase.CheckRequiredField("character_db_version", REVISION_DB_CHARACTERS))
|
///- Check the Character database version
|
||||||
|
if (!CharacterDatabase.CheckDatabaseVersion(DATABASE_CHARACTER))
|
||||||
{
|
{
|
||||||
///- Wait for already started DB delay threads to end
|
///- Wait for already started DB delay threads to end
|
||||||
WorldDatabase.HaltDelayThread();
|
WorldDatabase.HaltDelayThread();
|
||||||
|
|
@ -527,7 +529,8 @@ bool Master::_StartDB()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!LoginDatabase.CheckRequiredField("realmd_db_version", REVISION_DB_REALMD))
|
///- Check the Realm database version
|
||||||
|
if (!LoginDatabase.CheckDatabaseVersion(DATABASE_REALMD))
|
||||||
{
|
{
|
||||||
///- Wait for already started DB delay threads to end
|
///- Wait for already started DB delay threads to end
|
||||||
WorldDatabase.HaltDelayThread();
|
WorldDatabase.HaltDelayThread();
|
||||||
|
|
@ -560,7 +563,6 @@ bool Master::_StartDB()
|
||||||
sWorld.LoadDBVersion();
|
sWorld.LoadDBVersion();
|
||||||
|
|
||||||
sLog.outString("Using World DB: %s", sWorld.GetDBVersion());
|
sLog.outString("Using World DB: %s", sWorld.GetDBVersion());
|
||||||
sLog.outString("Using creature EventAI: %s", sWorld.GetCreatureEventAIVersion());
|
|
||||||
sLog.outString();
|
sLog.outString();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@
|
||||||
/// @{
|
/// @{
|
||||||
/// \file
|
/// \file
|
||||||
|
|
||||||
#ifndef _RASOCKET_H
|
#ifndef MANGOS_H_RASOCKET
|
||||||
#define _RASOCKET_H
|
#define MANGOS_H_RASOCKET
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include <ace/Synch_Traits.h>
|
#include <ace/Synch_Traits.h>
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ void WorldRunnable::run()
|
||||||
uint32 realCurrTime = 0;
|
uint32 realCurrTime = 0;
|
||||||
uint32 realPrevTime = WorldTimer::tick();
|
uint32 realPrevTime = WorldTimer::tick();
|
||||||
|
|
||||||
uint32 prevSleepTime = 0; // used for balanced full tick time length near WORLD_SLEEP_CONST
|
uint32 prevSleepTime = 0; // used for balanced full tick time length near WORLD_SLEEP_CONST
|
||||||
|
|
||||||
///- While we have not World::m_stopEvent, update the world
|
///- While we have not World::m_stopEvent, update the world
|
||||||
while (!World::IsStopped())
|
while (!World::IsStopped())
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
[MangosdConf]
|
[MangosdConf]
|
||||||
ConfVersion=2013122901
|
ConfVersion=2016031901
|
||||||
|
|
||||||
###################################################################################################################
|
################################################################################
|
||||||
# CONNECTIONS AND DIRECTORIES
|
# CONNECTIONS AND DIRECTORIES
|
||||||
#
|
#
|
||||||
# RealmID
|
# RealmID
|
||||||
|
|
@ -26,7 +26,6 @@ ConfVersion=2013122901
|
||||||
# LoginDatabaseInfo
|
# LoginDatabaseInfo
|
||||||
# WorldDatabaseInfo
|
# WorldDatabaseInfo
|
||||||
# CharacterDatabaseInfo
|
# CharacterDatabaseInfo
|
||||||
# ScriptDev2DatabaseInfo
|
|
||||||
# Database connection settings for the world server.
|
# Database connection settings for the world server.
|
||||||
# Default:
|
# Default:
|
||||||
# ---MYSQL---
|
# ---MYSQL---
|
||||||
|
|
@ -41,7 +40,6 @@ ConfVersion=2013122901
|
||||||
# LoginDatabaseConnections
|
# LoginDatabaseConnections
|
||||||
# WorldDatabaseConnections
|
# WorldDatabaseConnections
|
||||||
# CharacterDatabaseConnections
|
# CharacterDatabaseConnections
|
||||||
# ScriptDev2DatabaseConnections
|
|
||||||
# Amount of connections to database which will be used for SELECT queries. Maximum 16 connections per database.
|
# Amount of connections to database which will be used for SELECT queries. Maximum 16 connections per database.
|
||||||
# Please, note, for data consistency only one connection for each database is used for transactions and async SELECTs.
|
# Please, note, for data consistency only one connection for each database is used for transactions and async SELECTs.
|
||||||
# So formula to find out how many connections will be established:
|
# So formula to find out how many connections will be established:
|
||||||
|
|
@ -68,12 +66,10 @@ LogsDir = ""
|
||||||
LoginDatabaseInfo = "127.0.0.1;3306;mangos;mangos;realmd"
|
LoginDatabaseInfo = "127.0.0.1;3306;mangos;mangos;realmd"
|
||||||
WorldDatabaseInfo = "127.0.0.1;3306;mangos;mangos;mangos"
|
WorldDatabaseInfo = "127.0.0.1;3306;mangos;mangos;mangos"
|
||||||
CharacterDatabaseInfo = "127.0.0.1;3306;mangos;mangos;characters"
|
CharacterDatabaseInfo = "127.0.0.1;3306;mangos;mangos;characters"
|
||||||
ScriptDev2DatabaseInfo = "127.0.0.1;3306;mangos;mangos;mangos"
|
|
||||||
LoginDatabaseConnections = 1
|
LoginDatabaseConnections = 1
|
||||||
WorldDatabaseConnections = 1
|
WorldDatabaseConnections = 1
|
||||||
CharacterDatabaseConnections = 1
|
CharacterDatabaseConnections = 1
|
||||||
ScriptDev2DatabaseConnections= 1
|
MaxPingTime = 5
|
||||||
MaxPingTime = 30
|
|
||||||
WorldServerPort = 8085
|
WorldServerPort = 8085
|
||||||
BindIP = "0.0.0.0"
|
BindIP = "0.0.0.0"
|
||||||
|
|
||||||
|
|
@ -310,6 +306,10 @@ CleanCharacterDB = 1
|
||||||
# Log file of DB errors detected at server run
|
# Log file of DB errors detected at server run
|
||||||
# Default: "DBErrors.log"
|
# Default: "DBErrors.log"
|
||||||
#
|
#
|
||||||
|
# ElunaErrorLogFile
|
||||||
|
# Log file of Eluna errors detected at server run
|
||||||
|
# Default: "ElunaErrors.log"
|
||||||
|
#
|
||||||
# EventAIErrorLogFile
|
# EventAIErrorLogFile
|
||||||
# Log file of EventAI errors detected at server run
|
# Log file of EventAI errors detected at server run
|
||||||
# Default: "EventAIErrors.log"
|
# Default: "EventAIErrors.log"
|
||||||
|
|
@ -352,6 +352,11 @@ CleanCharacterDB = 1
|
||||||
# Default: "Ra.log"
|
# Default: "Ra.log"
|
||||||
# "" - Empty name for disable
|
# "" - Empty name for disable
|
||||||
#
|
#
|
||||||
|
# WardenLogFile
|
||||||
|
# Log file for warden-related output
|
||||||
|
# Default: "" - no log file created
|
||||||
|
# "warden.log" - recommended name to create a log file
|
||||||
|
#
|
||||||
# LogColors
|
# LogColors
|
||||||
# Color for messages (format "normal_color details_color debug_color error_color")
|
# Color for messages (format "normal_color details_color debug_color error_color")
|
||||||
# Colors: 0 - BLACK, 1 - RED, 2 - GREEN, 3 - BROWN, 4 - BLUE, 5 - MAGENTA, 6 - CYAN, 7 - GREY,
|
# Colors: 0 - BLACK, 1 - RED, 2 - GREEN, 3 - BROWN, 4 - BLUE, 5 - MAGENTA, 6 - CYAN, 7 - GREY,
|
||||||
|
|
@ -389,6 +394,7 @@ LogFilter_Calendar = 1
|
||||||
WorldLogFile = "world-packets.log"
|
WorldLogFile = "world-packets.log"
|
||||||
WorldLogTimestamp = 0
|
WorldLogTimestamp = 0
|
||||||
DBErrorLogFile = "world-database.log"
|
DBErrorLogFile = "world-database.log"
|
||||||
|
ElunaErrorLogFile = "ElunaErrors.log"
|
||||||
EventAIErrorLogFile = "world-eventai.log"
|
EventAIErrorLogFile = "world-eventai.log"
|
||||||
CharLogFile = "world-characters.log"
|
CharLogFile = "world-characters.log"
|
||||||
CharLogTimestamp = 0
|
CharLogTimestamp = 0
|
||||||
|
|
@ -397,6 +403,8 @@ GmLogFile = "world-gamemaster.log"
|
||||||
GmLogTimestamp = 0
|
GmLogTimestamp = 0
|
||||||
GmLogPerAccount = 0
|
GmLogPerAccount = 0
|
||||||
RaLogFile = "world-remote-access.log"
|
RaLogFile = "world-remote-access.log"
|
||||||
|
WardenLogFile = "warden.log"
|
||||||
|
WardenLogTimestamp = 0
|
||||||
LogColors = "13 7 11 9"
|
LogColors = "13 7 11 9"
|
||||||
SD2ErrorLogFile = "scriptdev2-errors.log"
|
SD2ErrorLogFile = "scriptdev2-errors.log"
|
||||||
|
|
||||||
|
|
@ -735,7 +743,7 @@ SD2ErrorLogFile = "scriptdev2-errors.log"
|
||||||
# 1 - recheck offhand slot weapon at talent reset also
|
# 1 - recheck offhand slot weapon at talent reset also
|
||||||
#
|
#
|
||||||
# PetUnsummonAtMount
|
# PetUnsummonAtMount
|
||||||
# Persmanent pet will unsummoned at player mount
|
# Permanent pet will unsummoned at player mount
|
||||||
# 0 - unsummon only for flying mounts
|
# 0 - unsummon only for flying mounts
|
||||||
# Default: 1 - unsummon for any mount
|
# Default: 1 - unsummon for any mount
|
||||||
#
|
#
|
||||||
|
|
@ -776,11 +784,11 @@ SD2ErrorLogFile = "scriptdev2-errors.log"
|
||||||
# You can bypass this setting by typing "/script SetAllowLowLevelRaid(true/false)" command in chat
|
# You can bypass this setting by typing "/script SetAllowLowLevelRaid(true/false)" command in chat
|
||||||
# Default: 10
|
# Default: 10
|
||||||
#
|
#
|
||||||
###################################################################################################################
|
################################################################################
|
||||||
|
|
||||||
GameType = 1
|
GameType = 1
|
||||||
RealmZone = 1
|
RealmZone = 1
|
||||||
Expansion = 3
|
Expansion = 3
|
||||||
DBC.Locale = 255
|
DBC.Locale = 255
|
||||||
DeclinedNames = 0
|
DeclinedNames = 0
|
||||||
StrictPlayerNames = 0
|
StrictPlayerNames = 0
|
||||||
|
|
@ -792,15 +800,15 @@ MinPetName = 2
|
||||||
CharactersCreatingDisabled = 0
|
CharactersCreatingDisabled = 0
|
||||||
CharactersPerAccount = 50
|
CharactersPerAccount = 50
|
||||||
CharactersPerRealm = 10
|
CharactersPerRealm = 10
|
||||||
HeroicCharactersPerRealm = 1
|
HeroicCharactersPerRealm = 1
|
||||||
MinLevelForHeroicCharacterCreating = 55
|
MinLevelForHeroicCharacterCreating = 55
|
||||||
SkipCinematics = 0
|
SkipCinematics = 0
|
||||||
MaxPlayerLevel = 85
|
MaxPlayerLevel = 85
|
||||||
StartPlayerLevel = 1
|
StartPlayerLevel = 1
|
||||||
StartHeroicPlayerLevel = 55
|
StartHeroicPlayerLevel = 55
|
||||||
StartPlayerMoney = 0
|
StartPlayerMoney = 0
|
||||||
InstantLogout = 1
|
InstantLogout = 1
|
||||||
DisableWaterBreath = 4
|
DisableWaterBreath = 4
|
||||||
AllFlightPaths = 0
|
AllFlightPaths = 0
|
||||||
ActivateWeather = 1
|
ActivateWeather = 1
|
||||||
CastUnstuck = 1
|
CastUnstuck = 1
|
||||||
|
|
@ -831,15 +839,15 @@ MaxPrimaryTradeSkill = 2
|
||||||
TradeSkill.GMIgnore.MaxPrimarySkillsCount = 4
|
TradeSkill.GMIgnore.MaxPrimarySkillsCount = 4
|
||||||
TradeSkill.GMIgnore.Level = 4
|
TradeSkill.GMIgnore.Level = 4
|
||||||
TradeSkill.GMIgnore.Skill = 4
|
TradeSkill.GMIgnore.Skill = 4
|
||||||
MinPetitionSigns = 4
|
MinPetitionSigns = 4
|
||||||
MaxGroupXPDistance = 74
|
MaxGroupXPDistance = 74
|
||||||
MailDeliveryDelay = 3600
|
MailDeliveryDelay = 3600
|
||||||
MassMailer.SendPerTick = 10
|
MassMailer.SendPerTick = 10
|
||||||
SkillChance.Prospecting = 0
|
SkillChance.Prospecting = 0
|
||||||
SkillChance.Milling = 0
|
SkillChance.Milling = 0
|
||||||
OffhandCheckAtTalentsReset = 0
|
OffhandCheckAtTalentsReset = 0
|
||||||
PetUnsummonAtMount = 1
|
PetUnsummonAtMount = 1
|
||||||
ClientCacheVersion = 0
|
ClientCacheVersion = 0
|
||||||
Event.Announce = 0
|
Event.Announce = 0
|
||||||
BeepAtStart = 1
|
BeepAtStart = 1
|
||||||
ShowProgressBars = 1
|
ShowProgressBars = 1
|
||||||
|
|
@ -1010,22 +1018,23 @@ Corpse.Decay.RARE = 900
|
||||||
Corpse.Decay.ELITE = 600
|
Corpse.Decay.ELITE = 600
|
||||||
Corpse.Decay.RAREELITE = 1200
|
Corpse.Decay.RAREELITE = 1200
|
||||||
Corpse.Decay.WORLDBOSS = 3600
|
Corpse.Decay.WORLDBOSS = 3600
|
||||||
Rate.Corpse.Decay.Looted = 0.0
|
Rate.Corpse.Decay.Looted = 0.0
|
||||||
Rate.Creature.Normal.Damage = 1
|
|
||||||
Rate.Creature.Elite.Elite.Damage = 1
|
Rate.Creature.Elite.Elite.Damage = 1
|
||||||
Rate.Creature.Elite.RAREELITE.Damage = 1
|
Rate.Creature.Elite.Elite.HP = 1
|
||||||
Rate.Creature.Elite.WORLDBOSS.Damage = 1
|
Rate.Creature.Elite.Elite.SpellDamage = 1
|
||||||
Rate.Creature.Elite.RARE.Damage = 1
|
Rate.Creature.Elite.RARE.Damage = 1
|
||||||
Rate.Creature.Normal.SpellDamage = 1
|
Rate.Creature.Elite.RARE.HP = 1
|
||||||
Rate.Creature.Elite.Elite.SpellDamage = 1
|
Rate.Creature.Elite.RARE.SpellDamage = 1
|
||||||
|
Rate.Creature.Elite.RAREELITE.Damage = 1
|
||||||
|
Rate.Creature.Elite.RAREELITE.HP = 1
|
||||||
Rate.Creature.Elite.RAREELITE.SpellDamage = 1
|
Rate.Creature.Elite.RAREELITE.SpellDamage = 1
|
||||||
|
Rate.Creature.Elite.WORLDBOSS.Damage = 1
|
||||||
|
Rate.Creature.Elite.WORLDBOSS.HP = 1
|
||||||
Rate.Creature.Elite.WORLDBOSS.SpellDamage = 1
|
Rate.Creature.Elite.WORLDBOSS.SpellDamage = 1
|
||||||
Rate.Creature.Elite.RARE.SpellDamage = 1
|
Rate.Creature.Normal.Damage = 1
|
||||||
Rate.Creature.Normal.HP = 1
|
Rate.Creature.Normal.HP = 1
|
||||||
Rate.Creature.Elite.Elite.HP = 1
|
Rate.Creature.Normal.SpellDamage = 1
|
||||||
Rate.Creature.Elite.RAREELITE.HP = 1
|
|
||||||
Rate.Creature.Elite.WORLDBOSS.HP = 1
|
|
||||||
Rate.Creature.Elite.RARE.HP = 1
|
|
||||||
ListenRange.Say = 40
|
ListenRange.Say = 40
|
||||||
ListenRange.TextEmote = 40
|
ListenRange.TextEmote = 40
|
||||||
ListenRange.Yell = 300
|
ListenRange.Yell = 300
|
||||||
|
|
@ -1163,16 +1172,16 @@ Channel.SilentlyGMJoin = 0
|
||||||
#
|
#
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
GM.LoginState = 2
|
GM.LoginState = 2
|
||||||
GM.Visible = 2
|
GM.Visible = 2
|
||||||
GM.AcceptTickets = 2
|
GM.AcceptTickets = 2
|
||||||
GM.Chat = 2
|
GM.Chat = 2
|
||||||
GM.WhisperingTo = 2
|
GM.WhisperingTo = 2
|
||||||
GM.InGMList.Level = 3
|
GM.InGMList.Level = 3
|
||||||
GM.InWhoList.Level = 3
|
GM.InWhoList.Level = 3
|
||||||
GM.LogTrade = 1
|
GM.LogTrade = 1
|
||||||
GM.StartLevel = 1
|
GM.StartLevel = 1
|
||||||
GM.LowerSecurity = 0
|
GM.LowerSecurity = 0
|
||||||
GM.AllowAchievementGain = 1
|
GM.AllowAchievementGain = 1
|
||||||
GM.InvisibleAura = 37800
|
GM.InvisibleAura = 37800
|
||||||
|
|
||||||
|
|
@ -1393,8 +1402,8 @@ Rate.Health = 1
|
||||||
Rate.Mana = 1
|
Rate.Mana = 1
|
||||||
Rate.Rage.Income = 1
|
Rate.Rage.Income = 1
|
||||||
Rate.Rage.Loss = 1
|
Rate.Rage.Loss = 1
|
||||||
Rate.RunicPower.Income = 1
|
Rate.RunicPower.Income = 1
|
||||||
Rate.RunicPower.Loss = 1
|
Rate.RunicPower.Loss = 1
|
||||||
Rate.Focus = 1
|
Rate.Focus = 1
|
||||||
Rate.Energy = 1
|
Rate.Energy = 1
|
||||||
Rate.Skill.Discovery = 1
|
Rate.Skill.Discovery = 1
|
||||||
|
|
@ -1407,8 +1416,8 @@ Rate.Drop.Item.Legendary = 1
|
||||||
Rate.Drop.Item.Artifact = 1
|
Rate.Drop.Item.Artifact = 1
|
||||||
Rate.Drop.Item.Referenced = 1
|
Rate.Drop.Item.Referenced = 1
|
||||||
Rate.Drop.Money = 1
|
Rate.Drop.Money = 1
|
||||||
Rate.Drop.Currency = 1
|
Rate.Drop.Currency = 1
|
||||||
Rate.Drop.Currency.Amount = 1
|
Rate.Drop.Currency.Amount = 1
|
||||||
Rate.XP.Kill = 1
|
Rate.XP.Kill = 1
|
||||||
Rate.XP.Quest = 1
|
Rate.XP.Quest = 1
|
||||||
Rate.XP.Explore = 1
|
Rate.XP.Explore = 1
|
||||||
|
|
@ -1419,13 +1428,13 @@ Rate.Damage.Fall = 1
|
||||||
Rate.Auction.Time = 1
|
Rate.Auction.Time = 1
|
||||||
Rate.Auction.Deposit = 1
|
Rate.Auction.Deposit = 1
|
||||||
Rate.Auction.Cut = 1
|
Rate.Auction.Cut = 1
|
||||||
Auction.Deposit.Min = 100
|
Auction.Deposit.Min = 100
|
||||||
Rate.Honor = 1
|
Rate.Honor = 1
|
||||||
Rate.Mining.Amount = 1
|
Rate.Mining.Amount = 1
|
||||||
Rate.Mining.Next = 1
|
Rate.Mining.Next = 1
|
||||||
Rate.Talent = 1
|
Rate.Talent = 1
|
||||||
Rate.Reputation.Gain = 1
|
Rate.Reputation.Gain = 1
|
||||||
Rate.Reputation.LowLevel.Kill = 1
|
Rate.Reputation.LowLevel.Kill = 1
|
||||||
Rate.Reputation.LowLevel.Quest = 1
|
Rate.Reputation.LowLevel.Quest = 1
|
||||||
Rate.InstanceResetTime = 1
|
Rate.InstanceResetTime = 1
|
||||||
|
|
||||||
|
|
@ -1439,9 +1448,9 @@ SkillChance.Grey = 0
|
||||||
SkillChance.MiningSteps = 0
|
SkillChance.MiningSteps = 0
|
||||||
SkillChance.SkinningSteps = 0
|
SkillChance.SkinningSteps = 0
|
||||||
|
|
||||||
SkillFail.Loot.Fishing = 1
|
SkillFail.Loot.Fishing = 1
|
||||||
SkillFail.Gain.Fishing = 1
|
SkillFail.Gain.Fishing = 1
|
||||||
SkillFail.Possible.FishingPool = 0
|
SkillFail.Possible.FishingPool = 0
|
||||||
|
|
||||||
DurabilityLossChance.Damage = 0.5
|
DurabilityLossChance.Damage = 0.5
|
||||||
DurabilityLossChance.Absorb = 0.5
|
DurabilityLossChance.Absorb = 0.5
|
||||||
|
|
@ -1737,3 +1746,28 @@ Currency.ResetWeekDay = 3
|
||||||
Currency.ResetHour = 6
|
Currency.ResetHour = 6
|
||||||
Currency.ConquestPointsDefaultWeekCap = 135000
|
Currency.ConquestPointsDefaultWeekCap = 135000
|
||||||
Currency.ConquestPointsArenaReward = 12000
|
Currency.ConquestPointsArenaReward = 12000
|
||||||
|
|
||||||
|
###################################################################################################################
|
||||||
|
# ELUNA SETTINGS
|
||||||
|
#
|
||||||
|
# Eluna.Enabled
|
||||||
|
# Enable Eluna LuaEngine
|
||||||
|
# Default: 1 (Enabled)
|
||||||
|
# 0 (Disabled)
|
||||||
|
#
|
||||||
|
# Eluna.TraceBack
|
||||||
|
# Description: Sets whether to use debug.traceback function on a lua error or not.
|
||||||
|
# Notice that you can redefine the function.
|
||||||
|
# Default: false - (use default error output)
|
||||||
|
# true - (use debug.traceback function)
|
||||||
|
#
|
||||||
|
# Eluna.ScriptPath
|
||||||
|
# Description: Sets the location of the script folder to load scripts from
|
||||||
|
# The path can be relative or absolute.
|
||||||
|
# Default: "lua_scripts"
|
||||||
|
#
|
||||||
|
###################################################################################################################
|
||||||
|
|
||||||
|
Eluna.Enabled = 1
|
||||||
|
Eluna.TraceBack = false
|
||||||
|
Eluna.ScriptPath = "lua_scripts"
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 9c9e7ae7919e1cd5ce1f454520b9adf3316e2137
|
Subproject commit 15df5d42ae03cabe9cebfbd7534df8af4f739ecb
|
||||||
|
|
@ -149,7 +149,16 @@ typedef off_t ACE_OFF_T;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UI64FMTD ACE_UINT64_FORMAT_SPECIFIER
|
#if defined(__APPLE__)
|
||||||
|
# ifdef I64FMT
|
||||||
|
# undef I64FMT
|
||||||
|
# endif
|
||||||
|
# define I64FMT "%016llX"
|
||||||
|
# define UI64FMTD "%llu"
|
||||||
|
#else
|
||||||
|
# define UI64FMTD ACE_UINT64_FORMAT_SPECIFIER
|
||||||
|
#endif
|
||||||
|
|
||||||
#define UI64LIT(N) ACE_UINT64_LITERAL(N)
|
#define UI64LIT(N) ACE_UINT64_LITERAL(N)
|
||||||
|
|
||||||
#define SI64FMTD ACE_INT64_FORMAT_SPECIFIER
|
#define SI64FMTD ACE_INT64_FORMAT_SPECIFIER
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,6 @@ bool DBCFileLoader::Load(const char* filename, const char* fmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
EndianConvert(header);
|
EndianConvert(header);
|
||||||
|
|
||||||
if (header != 0x43424457) //'WDBC'
|
if (header != 0x43424457) //'WDBC'
|
||||||
{
|
{
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
@ -366,11 +365,9 @@ char* DBCFileLoader::AutoProduceStrings(const char* format, char* dataTable, Loc
|
||||||
break;
|
break;
|
||||||
case DBC_FF_STRING:
|
case DBC_FF_STRING:
|
||||||
{
|
{
|
||||||
char** holder = *((char***)(&dataTable[offset]));
|
|
||||||
char** slot = &holder[loc];
|
|
||||||
|
|
||||||
// fill only not filled entries
|
// fill only not filled entries
|
||||||
if (*slot == nullStr)
|
char** slot = (char**)(&dataTable[offset]);
|
||||||
|
if (!*slot || !** slot)
|
||||||
{
|
{
|
||||||
const char* st = getRecord(y).getString(x);
|
const char* st = getRecord(y).getString(x);
|
||||||
*slot = stringPool + (st - (const char*)stringTable);
|
*slot = stringPool + (st - (const char*)stringTable);
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
#include "DatabaseEnv.h"
|
#include "DatabaseEnv.h"
|
||||||
#include "Config/Config.h"
|
#include "Config/Config.h"
|
||||||
#include "Database/SqlOperations.h"
|
#include "Database/SqlOperations.h"
|
||||||
|
#include "revision.h"
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
@ -34,6 +35,21 @@
|
||||||
#define MIN_CONNECTION_POOL_SIZE 1
|
#define MIN_CONNECTION_POOL_SIZE 1
|
||||||
#define MAX_CONNECTION_POOL_SIZE 16
|
#define MAX_CONNECTION_POOL_SIZE 16
|
||||||
|
|
||||||
|
struct DBVersion
|
||||||
|
{
|
||||||
|
std::string dbname;
|
||||||
|
uint32 expected_version;
|
||||||
|
uint32 expected_structure;
|
||||||
|
uint32 expected_content;
|
||||||
|
std::string description;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DBVersion databaseVersions[COUNT_DATABASES] = {
|
||||||
|
{ "World", WORLD_DB_VERSION_NR, WORLD_DB_STRUCTURE_NR, WORLD_DB_CONTENT_NR, WORLD_DB_UPDATE_DESCRIPTION }, // DATABASE_WORLD
|
||||||
|
{ "Realmd", REALMD_DB_VERSION_NR, REALMD_DB_STRUCTURE_NR, REALMD_DB_CONTENT_NR, REALMD_DB_UPDATE_DESCRIPTION }, // DATABASE_REALMD
|
||||||
|
{ "Character", CHAR_DB_VERSION_NR, CHAR_DB_STRUCTURE_NR, CHAR_DB_CONTENT_NR, CHAR_DB_UPDATE_DESCRIPTION }, // DATABASE_CHARACTER
|
||||||
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
SqlPreparedStatement* SqlConnection::CreateStatement(const std::string& fmt)
|
SqlPreparedStatement* SqlConnection::CreateStatement(const std::string& fmt)
|
||||||
{
|
{
|
||||||
|
|
@ -178,6 +194,7 @@ void Database::InitDelayThread()
|
||||||
|
|
||||||
// New delay thread for delay execute
|
// New delay thread for delay execute
|
||||||
m_threadBody = CreateDelayThread(); // will deleted at m_delayThread delete
|
m_threadBody = CreateDelayThread(); // will deleted at m_delayThread delete
|
||||||
|
m_TransStorage = new ACE_TSS<Database::TransHelper>();
|
||||||
m_delayThread = new ACE_Based::Thread(m_threadBody);
|
m_delayThread = new ACE_Based::Thread(m_threadBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -187,9 +204,11 @@ void Database::HaltDelayThread()
|
||||||
|
|
||||||
m_threadBody->Stop(); // Stop event
|
m_threadBody->Stop(); // Stop event
|
||||||
m_delayThread->wait(); // Wait for flush to DB
|
m_delayThread->wait(); // Wait for flush to DB
|
||||||
|
delete m_TransStorage;
|
||||||
delete m_delayThread; // This also deletes m_threadBody
|
delete m_delayThread; // This also deletes m_threadBody
|
||||||
m_delayThread = NULL;
|
m_delayThread = NULL;
|
||||||
m_threadBody = NULL;
|
m_threadBody = NULL;
|
||||||
|
m_TransStorage=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::ThreadStart()
|
void Database::ThreadStart()
|
||||||
|
|
@ -333,7 +352,7 @@ bool Database::Execute(const char* sql)
|
||||||
if (!m_pAsyncConn)
|
if (!m_pAsyncConn)
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
SqlTransaction* pTrans = m_TransStorage->get();
|
SqlTransaction* pTrans = (*m_TransStorage)->get();
|
||||||
if (pTrans)
|
if (pTrans)
|
||||||
{
|
{
|
||||||
// add SQL request to trans queue
|
// add SQL request to trans queue
|
||||||
|
|
@ -399,7 +418,7 @@ bool Database::BeginTransaction()
|
||||||
|
|
||||||
// initiate transaction on current thread
|
// initiate transaction on current thread
|
||||||
// currently we do not support queued transactions
|
// currently we do not support queued transactions
|
||||||
m_TransStorage->init();
|
(*m_TransStorage)->init();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -409,7 +428,7 @@ bool Database::CommitTransaction()
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
// check if we have pending transaction
|
// check if we have pending transaction
|
||||||
if (!m_TransStorage->get())
|
if (!(*m_TransStorage)->get())
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
// if async execution is not available
|
// if async execution is not available
|
||||||
|
|
@ -417,7 +436,7 @@ bool Database::CommitTransaction()
|
||||||
{ return CommitTransactionDirect(); }
|
{ return CommitTransactionDirect(); }
|
||||||
|
|
||||||
// add SqlTransaction to the async queue
|
// add SqlTransaction to the async queue
|
||||||
m_threadBody->Delay(m_TransStorage->detach());
|
m_threadBody->Delay((*m_TransStorage)->detach());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -427,11 +446,11 @@ bool Database::CommitTransactionDirect()
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
// check if we have pending transaction
|
// check if we have pending transaction
|
||||||
if (!m_TransStorage->get())
|
if (!(*m_TransStorage)->get())
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
// directly execute SqlTransaction
|
// directly execute SqlTransaction
|
||||||
SqlTransaction* pTrans = m_TransStorage->detach();
|
SqlTransaction* pTrans = (*m_TransStorage)->detach();
|
||||||
pTrans->Execute(m_pAsyncConn);
|
pTrans->Execute(m_pAsyncConn);
|
||||||
delete pTrans;
|
delete pTrans;
|
||||||
|
|
||||||
|
|
@ -443,101 +462,93 @@ bool Database::RollbackTransaction()
|
||||||
if (!m_pAsyncConn)
|
if (!m_pAsyncConn)
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
if (!m_TransStorage->get())
|
if (!(*m_TransStorage)->get())
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
// remove scheduled transaction
|
// remove scheduled transaction
|
||||||
m_TransStorage->reset();
|
(*m_TransStorage)->reset();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::CheckRequiredField(char const* table_name, char const* required_name)
|
bool Database::CheckDatabaseVersion(DatabaseTypes database)
|
||||||
{
|
{
|
||||||
// check required field
|
const DBVersion& dbversion = databaseVersions[database];
|
||||||
QueryResult* result = PQuery("SELECT %s FROM %s LIMIT 1", required_name, table_name);
|
|
||||||
if (result)
|
// Fetch the database version table information
|
||||||
|
QueryResult* result = Query("SELECT version, structure, content, description FROM db_version ORDER BY version DESC, structure DESC, content DESC LIMIT 1");
|
||||||
|
|
||||||
|
// db_version table does not exist or is empty
|
||||||
|
if (!result)
|
||||||
{
|
{
|
||||||
delete result;
|
sLog.outErrorDb("The table `db_version` in your [%s] database is missing or corrupt.", dbversion.dbname.c_str());
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check fail, prepare readabale error message
|
|
||||||
|
|
||||||
// search current required_* field in DB
|
|
||||||
const char* db_name;
|
|
||||||
if (!strcmp(table_name, "db_version"))
|
|
||||||
{ db_name = "WORLD"; }
|
|
||||||
else if (!strcmp(table_name, "character_db_version"))
|
|
||||||
{ db_name = "CHARACTER"; }
|
|
||||||
else if (!strcmp(table_name, "realmd_db_version"))
|
|
||||||
{ db_name = "REALMD"; }
|
|
||||||
else
|
|
||||||
{ db_name = "UNKNOWN"; }
|
|
||||||
|
|
||||||
char const* req_sql_update_name = required_name + strlen("required_");
|
|
||||||
|
|
||||||
QueryNamedResult* result2 = PQueryNamed("SELECT * FROM %s LIMIT 1", table_name);
|
|
||||||
if (result2)
|
|
||||||
{
|
|
||||||
QueryFieldNames const& namesMap = result2->GetFieldNames();
|
|
||||||
std::string reqName;
|
|
||||||
for (QueryFieldNames::const_iterator itr = namesMap.begin(); itr != namesMap.end(); ++itr)
|
|
||||||
{
|
|
||||||
if (itr->substr(0, 9) == "required_")
|
|
||||||
{
|
|
||||||
reqName = *itr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete result2;
|
|
||||||
|
|
||||||
std::string cur_sql_update_name = reqName.substr(strlen("required_"), reqName.npos);
|
|
||||||
|
|
||||||
if (!reqName.empty())
|
|
||||||
{
|
|
||||||
sLog.outErrorDb("The table `%s` in your [%s] database indicates that this database is out of date!", table_name, db_name);
|
|
||||||
sLog.outErrorDb();
|
|
||||||
sLog.outErrorDb(" [A] You have: --> `%s.sql`", cur_sql_update_name.c_str());
|
|
||||||
sLog.outErrorDb();
|
|
||||||
sLog.outErrorDb(" [B] You need: --> `%s.sql`", req_sql_update_name);
|
|
||||||
sLog.outErrorDb();
|
|
||||||
sLog.outErrorDb("You must apply all updates after [A] to [B] to use mangos with this database.");
|
|
||||||
sLog.outErrorDb("These updates are included in the sql/updates folder.");
|
|
||||||
sLog.outErrorDb("Please read the included [README] in sql/updates for instructions on updating.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sLog.outErrorDb("The table `%s` in your [%s] database is missing its version info.", table_name, db_name);
|
|
||||||
sLog.outErrorDb("MaNGOS can not find the version info needed to check that the db is up to date.");
|
|
||||||
sLog.outErrorDb();
|
|
||||||
sLog.outErrorDb("This revision of MaNGOS requires a database updated to:");
|
|
||||||
sLog.outErrorDb("`%s.sql`", req_sql_update_name);
|
|
||||||
sLog.outErrorDb();
|
|
||||||
|
|
||||||
if (!strcmp(db_name, "WORLD"))
|
|
||||||
{ sLog.outErrorDb("Post this error to your database provider forum or find a solution there."); }
|
|
||||||
else
|
|
||||||
{ sLog.outErrorDb("Reinstall your [%s] database with the included sql file in the sql folder.", db_name); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sLog.outErrorDb("The table `%s` in your [%s] database is missing or corrupt.", table_name, db_name);
|
|
||||||
sLog.outErrorDb("MaNGOS can not find the version info needed to check that the db is up to date.");
|
|
||||||
sLog.outErrorDb();
|
sLog.outErrorDb();
|
||||||
sLog.outErrorDb("This revision of mangos requires a database updated to:");
|
sLog.outErrorDb(" [A] You have database Version: MaNGOS can not verify your database version or its existence!");
|
||||||
sLog.outErrorDb("`%s.sql`", req_sql_update_name);
|
|
||||||
sLog.outErrorDb();
|
sLog.outErrorDb();
|
||||||
|
sLog.outErrorDb(" [B] You need database Version: %u", dbversion.expected_version);
|
||||||
if (!strcmp(db_name, "WORLD"))
|
sLog.outErrorDb(" Structure: %u", dbversion.expected_structure);
|
||||||
{ sLog.outErrorDb("Post this error to your database provider forum or find a solution there."); }
|
sLog.outErrorDb(" Content: %u", dbversion.expected_content);
|
||||||
else
|
sLog.outErrorDb(" Description: %s", dbversion.description.c_str());
|
||||||
{ sLog.outErrorDb("Reinstall your [%s] database with the included sql file in the sql folder.", db_name); }
|
sLog.outErrorDb();
|
||||||
|
sLog.outErrorDb("Please verify your database location or your database integrity.");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
Field* fields = result->Fetch();
|
||||||
|
uint32 version = fields[0].GetUInt32();
|
||||||
|
uint32 structure = fields[1].GetUInt32();
|
||||||
|
uint32 content = fields[2].GetUInt32();
|
||||||
|
std::string description = fields[3].GetCppString();
|
||||||
|
|
||||||
|
delete result;
|
||||||
|
|
||||||
|
// Structure does not match the required version
|
||||||
|
if (version != dbversion.expected_version || structure != dbversion.expected_structure)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("The table `db_version` indicates that your [%s] database does not match the expected structure!", dbversion.dbname.c_str());
|
||||||
|
sLog.outErrorDb();
|
||||||
|
sLog.outErrorDb(" [A] You have database Version: %u", version);
|
||||||
|
sLog.outErrorDb(" Structure: %u", structure);
|
||||||
|
sLog.outErrorDb(" Content: %u", content);
|
||||||
|
sLog.outErrorDb(" Description: %s", description.c_str());
|
||||||
|
sLog.outErrorDb();
|
||||||
|
sLog.outErrorDb(" [B] You need database Version: %u", dbversion.expected_version);
|
||||||
|
sLog.outErrorDb(" Structure: %u", dbversion.expected_structure);
|
||||||
|
sLog.outErrorDb(" Content: %u", dbversion.expected_content);
|
||||||
|
sLog.outErrorDb(" Description: %s", dbversion.description.c_str());
|
||||||
|
sLog.outErrorDb();
|
||||||
|
sLog.outErrorDb("You must apply all updates after [A] to [B] to use MaNGOS with this database.");
|
||||||
|
sLog.outErrorDb("These updates are included in the database/%s/Updates folder.", dbversion.dbname.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DB is not up to date, but structure is correct. Send warning but start core
|
||||||
|
if (content > dbversion.expected_content)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("You have not updated the core for few DB [%s] updates!", dbversion.dbname.c_str());
|
||||||
|
sLog.outErrorDb("Current DB content is %u, core expects %u", content, dbversion.expected_content);
|
||||||
|
sLog.outErrorDb("This is ok for now but should not last long.");
|
||||||
|
}
|
||||||
|
else if (content != dbversion.expected_content)
|
||||||
|
{
|
||||||
|
sLog.outErrorDb("The table `db_version` indicates that your [%s] database does not match the expected version!", dbversion.dbname.c_str());
|
||||||
|
sLog.outErrorDb();
|
||||||
|
sLog.outErrorDb(" [A] You have database Version: %u", version);
|
||||||
|
sLog.outErrorDb(" Structure: %u", structure);
|
||||||
|
sLog.outErrorDb(" Content: %u", content);
|
||||||
|
sLog.outErrorDb(" Description: %s", description.c_str());
|
||||||
|
sLog.outErrorDb();
|
||||||
|
sLog.outErrorDb(" [B] You need database Version: %u", dbversion.expected_version);
|
||||||
|
sLog.outErrorDb(" Structure: %u", dbversion.expected_structure);
|
||||||
|
sLog.outErrorDb(" Content: %u", dbversion.expected_content);
|
||||||
|
sLog.outErrorDb(" Description: %s", dbversion.description.c_str());
|
||||||
|
sLog.outErrorDb();
|
||||||
|
sLog.outErrorDb("You are missing content updates or you have content updates beyond the expected core version.");
|
||||||
|
sLog.outErrorDb("It is recommended to run ALL database updates up to the required core version.");
|
||||||
|
sLog.outErrorDb("These updates are included in the database/%s/Updates folder.", dbversion.dbname.c_str());
|
||||||
|
};
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::ExecuteStmt(const SqlStatementID& id, SqlStmtParameters* params)
|
bool Database::ExecuteStmt(const SqlStatementID& id, SqlStmtParameters* params)
|
||||||
|
|
@ -545,7 +556,7 @@ bool Database::ExecuteStmt(const SqlStatementID& id, SqlStmtParameters* params)
|
||||||
if (!m_pAsyncConn)
|
if (!m_pAsyncConn)
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
SqlTransaction* pTrans = m_TransStorage->get();
|
SqlTransaction* pTrans = (*m_TransStorage)->get();
|
||||||
if (pTrans)
|
if (pTrans)
|
||||||
{
|
{
|
||||||
// add SQL request to trans queue
|
// add SQL request to trans queue
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,14 @@ class Database;
|
||||||
|
|
||||||
#define MAX_QUERY_LEN (32*1024)
|
#define MAX_QUERY_LEN (32*1024)
|
||||||
|
|
||||||
|
enum DatabaseTypes
|
||||||
|
{
|
||||||
|
DATABASE_WORLD,
|
||||||
|
DATABASE_REALMD,
|
||||||
|
DATABASE_CHARACTER,
|
||||||
|
COUNT_DATABASES,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
|
|
@ -613,13 +621,12 @@ class Database
|
||||||
void ProcessResultQueue();
|
void ProcessResultQueue();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief Function to check that the database version matches expected core version
|
||||||
*
|
*
|
||||||
* @param table_name
|
* @param DatabaseTypes
|
||||||
* @param required_name
|
* @return bool
|
||||||
* @return bool
|
*/
|
||||||
*/
|
bool CheckDatabaseVersion(DatabaseTypes database);
|
||||||
bool CheckRequiredField(char const* table_name, char const* required_name);
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
|
|
@ -651,7 +658,7 @@ class Database
|
||||||
Database() :
|
Database() :
|
||||||
m_nQueryConnPoolSize(1), m_pAsyncConn(NULL), m_pResultQueue(NULL),
|
m_nQueryConnPoolSize(1), m_pAsyncConn(NULL), m_pResultQueue(NULL),
|
||||||
m_threadBody(NULL), m_delayThread(NULL), m_bAllowAsyncTransactions(false),
|
m_threadBody(NULL), m_delayThread(NULL), m_bAllowAsyncTransactions(false),
|
||||||
m_iStmtIndex(-1), m_logSQL(false), m_pingIntervallms(0)
|
m_iStmtIndex(-1), m_logSQL(false), m_pingIntervallms(0), m_TransStorage(NULL)
|
||||||
{
|
{
|
||||||
m_nQueryCounter = -1;
|
m_nQueryCounter = -1;
|
||||||
}
|
}
|
||||||
|
|
@ -679,7 +686,7 @@ class Database
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class TransHelper
|
class TransHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
|
@ -730,7 +737,7 @@ class Database
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef ACE_TSS<Database::TransHelper> DBTransHelperTSS;
|
typedef ACE_TSS<Database::TransHelper> DBTransHelperTSS;
|
||||||
Database::DBTransHelperTSS m_TransStorage; /**< TODO */
|
Database::DBTransHelperTSS *m_TransStorage; /**< TODO */
|
||||||
|
|
||||||
///< DB connections
|
///< DB connections
|
||||||
/**
|
/**
|
||||||
|
|
@ -781,7 +788,7 @@ class Database
|
||||||
|
|
||||||
SqlResultQueue* m_pResultQueue; /**< Transaction queues from diff. threads */
|
SqlResultQueue* m_pResultQueue; /**< Transaction queues from diff. threads */
|
||||||
SqlDelayThread* m_threadBody; /**< Pointer to delay sql executer (owned by m_delayThread) */
|
SqlDelayThread* m_threadBody; /**< Pointer to delay sql executer (owned by m_delayThread) */
|
||||||
ACE_Based::Thread* m_delayThread; /**< Pointer to executer thread */
|
ACE_Based::Thread* m_delayThread; /**< Pointer to executer thread */
|
||||||
|
|
||||||
bool m_bAllowAsyncTransactions; /**< flag which specifies if async transactions are enabled */
|
bool m_bAllowAsyncTransactions; /**< flag which specifies if async transactions are enabled */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ class Field
|
||||||
*
|
*
|
||||||
* @return int8
|
* @return int8
|
||||||
*/
|
*/
|
||||||
int8 GetInt8() const { return mValue ? static_cast<int8>(atol(mValue)) : int8(0); }
|
int8 GetInt8() const { return mValue ? static_cast<int8>(atol(mValue)) : int8(0); }
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
|
|
@ -154,29 +154,29 @@ class Field
|
||||||
{
|
{
|
||||||
uint64 value = 0;
|
uint64 value = 0;
|
||||||
if (!mValue || sscanf(mValue, UI64FMTD, &value) == -1)
|
if (!mValue || sscanf(mValue, UI64FMTD, &value) == -1)
|
||||||
return 0;
|
{ return 0; }
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
* @return int64
|
* @return int64
|
||||||
*/
|
*/
|
||||||
uint64 GetInt64() const
|
uint64 GetInt64() const
|
||||||
{
|
{
|
||||||
int64 value = 0;
|
int64 value = 0;
|
||||||
if (!mValue || sscanf(mValue, SI64FMTD, &value) == -1)
|
if (!mValue || sscanf(mValue, SI64FMTD, &value) == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
* @param type
|
* @param type
|
||||||
*/
|
*/
|
||||||
void SetType(enum DataTypes type) { mType = type; }
|
void SetType(enum DataTypes type) { mType = type; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ void SQLStorage::prepareToLoad(uint32 maxRecordId, uint32 recordCount, uint32 re
|
||||||
|
|
||||||
// Set index array
|
// Set index array
|
||||||
m_Index = new char*[maxRecordId];
|
m_Index = new char*[maxRecordId];
|
||||||
memset(m_Index, NULL, maxRecordId * sizeof(char*));
|
memset(m_Index, 0, maxRecordId * sizeof(char*));
|
||||||
|
|
||||||
SQLStorageBase::prepareToLoad(maxRecordId, recordCount, recordSize);
|
SQLStorageBase::prepareToLoad(maxRecordId, recordCount, recordSize);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
// Format is YYYYMMDDRR where RR is the change in the conf file
|
// Format is YYYYMMDDRR where RR is the change in the conf file
|
||||||
// for that day.
|
// for that day.
|
||||||
#ifndef MANGOSD_CONFIG_VERSION
|
#ifndef MANGOSD_CONFIG_VERSION
|
||||||
# define MANGOSD_CONFIG_VERSION 2015010201
|
# define MANGOSD_CONFIG_VERSION 2016031901
|
||||||
#endif
|
#endif
|
||||||
#ifndef REALMD_CONFIG_VERSION
|
#ifndef REALMD_CONFIG_VERSION
|
||||||
# define REALMD_CONFIG_VERSION 2010062001
|
# define REALMD_CONFIG_VERSION 2010062001
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ Thread::~Thread()
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize Thread's class static member
|
// initialize Thread's class static member
|
||||||
Thread::ThreadStorage Thread::m_ThreadStorage;
|
Thread::ThreadStorage *Thread::m_ThreadStorage = NULL;
|
||||||
ThreadPriority Thread::m_TpEnum;
|
ThreadPriority Thread::m_TpEnum;
|
||||||
|
|
||||||
bool Thread::start()
|
bool Thread::start()
|
||||||
|
|
@ -142,6 +142,8 @@ bool Thread::start()
|
||||||
// incRef before spawing the thread, otherwise Thread::ThreadTask() might call decRef and delete m_task
|
// incRef before spawing the thread, otherwise Thread::ThreadTask() might call decRef and delete m_task
|
||||||
m_task->incReference();
|
m_task->incReference();
|
||||||
|
|
||||||
|
m_ThreadStorage = new ACE_TSS<Thread>();
|
||||||
|
|
||||||
bool res = (ACE_Thread::spawn(&Thread::ThreadTask, (void*)m_task, THREADFLAG, &m_iThreadId, &m_hThreadHandle) == 0);
|
bool res = (ACE_Thread::spawn(&Thread::ThreadTask, (void*)m_task, THREADFLAG, &m_iThreadId, &m_hThreadHandle) == 0);
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
|
|
@ -160,6 +162,8 @@ bool Thread::wait()
|
||||||
|
|
||||||
m_iThreadId = 0;
|
m_iThreadId = 0;
|
||||||
m_hThreadHandle = 0;
|
m_hThreadHandle = 0;
|
||||||
|
delete m_ThreadStorage;
|
||||||
|
m_ThreadStorage = NULL;
|
||||||
|
|
||||||
return (_res == 0);
|
return (_res == 0);
|
||||||
}
|
}
|
||||||
|
|
@ -174,6 +178,8 @@ void Thread::destroy()
|
||||||
|
|
||||||
m_iThreadId = 0;
|
m_iThreadId = 0;
|
||||||
m_hThreadHandle = 0;
|
m_hThreadHandle = 0;
|
||||||
|
delete m_ThreadStorage;
|
||||||
|
m_ThreadStorage = NULL;
|
||||||
|
|
||||||
// reference set at ACE_Thread::spawn
|
// reference set at ACE_Thread::spawn
|
||||||
m_task->decReference();
|
m_task->decReference();
|
||||||
|
|
@ -217,14 +223,14 @@ ACE_hthread_t Thread::currentHandle()
|
||||||
|
|
||||||
Thread* Thread::current()
|
Thread* Thread::current()
|
||||||
{
|
{
|
||||||
Thread* _thread = m_ThreadStorage.ts_object();
|
Thread* _thread = (*m_ThreadStorage).ts_object();
|
||||||
if (!_thread)
|
if (!_thread)
|
||||||
{
|
{
|
||||||
_thread = new Thread();
|
_thread = new Thread();
|
||||||
_thread->m_iThreadId = Thread::currentId();
|
_thread->m_iThreadId = Thread::currentId();
|
||||||
_thread->m_hThreadHandle = Thread::currentHandle();
|
_thread->m_hThreadHandle = Thread::currentHandle();
|
||||||
|
|
||||||
Thread* _oldValue = m_ThreadStorage.ts_object(_thread);
|
Thread* _oldValue = (*m_ThreadStorage).ts_object(_thread);
|
||||||
delete _oldValue;
|
delete _oldValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -226,7 +226,7 @@ namespace ACE_Based
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef ACE_TSS<Thread> ThreadStorage;
|
typedef ACE_TSS<Thread> ThreadStorage;
|
||||||
static ThreadStorage m_ThreadStorage; /**< global object - container for Thread class representation of every thread */
|
static ThreadStorage *m_ThreadStorage; /**< global object - container for Thread class representation of every thread */
|
||||||
static ThreadPriority m_TpEnum; /**< use this object to determine current OS thread priority values mapped to enum Priority{} */
|
static ThreadPriority m_TpEnum; /**< use this object to determine current OS thread priority values mapped to enum Priority{} */
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,5 +79,5 @@ void BitStream::Print()
|
||||||
for (uint32 i = 0; i < GetLength(); ++i)
|
for (uint32 i = 0; i < GetLength(); ++i)
|
||||||
ss << uint32(GetBit(i)) << " ";
|
ss << uint32(GetBit(i)) << " ";
|
||||||
|
|
||||||
sLog.outDebug(ss.str().c_str());
|
sLog.outDebug("%s", ss.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ class BarGoLink
|
||||||
*/
|
*/
|
||||||
explicit BarGoLink(int row_count);
|
explicit BarGoLink(int row_count);
|
||||||
explicit BarGoLink(uint32 row_count); // row_count < ACE_INT32_MAX
|
explicit BarGoLink(uint32 row_count); // row_count < ACE_INT32_MAX
|
||||||
explicit BarGoLink(uint64 row_count); // row_count < ACE_INT32_MAX
|
explicit BarGoLink(uint64 row_count); // row_count < ACE_INT64_MAX
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
* MaNGOS is a full featured server for World of Warcraft, supporting
|
* MaNGOS is a full featured server for World of Warcraft, supporting
|
||||||
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
|
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005-2016 MaNGOS project <https://getmangos.eu>
|
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -422,17 +422,6 @@ bool Utf8toWStr(const std::string& utf8str, std::wstring& wstr)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Utf8ToUpperOnlyLatin(std::string &utf8String)
|
|
||||||
{
|
|
||||||
std::wstring wstr;
|
|
||||||
if (!Utf8toWStr(utf8String, wstr))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::transform(wstr.begin(), wstr.end(), wstr.begin(), wcharToUpperOnlyLatin);
|
|
||||||
|
|
||||||
return WStrToUtf8(wstr, utf8String);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str)
|
bool WStrToUtf8(wchar_t* wstr, size_t size, std::string& utf8str)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
* MaNGOS is a full featured server for World of Warcraft, supporting
|
* MaNGOS is a full featured server for World of Warcraft, supporting
|
||||||
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
|
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005-2016 MaNGOS project <https://getmangos.eu>
|
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -282,13 +282,7 @@ inline bool Utf8toWStr(const std::string& utf8str, wchar_t* wstr, size_t& wsize)
|
||||||
{
|
{
|
||||||
return Utf8toWStr(utf8str.c_str(), utf8str.size(), wstr, wsize);
|
return Utf8toWStr(utf8str.c_str(), utf8str.size(), wstr, wsize);
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* @brief
|
|
||||||
*
|
|
||||||
* @param utf8String
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
bool Utf8ToUpperOnlyLatin(std::string &utf8String);
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,20 @@
|
||||||
|
|
||||||
#ifndef MANGOS_H_REVISION
|
#ifndef MANGOS_H_REVISION
|
||||||
#define MANGOS_H_REVISION
|
#define MANGOS_H_REVISION
|
||||||
#define REVISION_NR "12778"
|
#define REVISION_NR "21000"
|
||||||
#define REVISION_DB_CHARACTERS "required_12712_01_characters_characters"
|
|
||||||
#define REVISION_DB_MANGOS "required_12752_01_mangos_reputation_spillover_template"
|
#define REALMD_DB_VERSION_NR 21
|
||||||
#define REVISION_DB_REALMD "required_20150722_01_realmcharacters_remove_constraint"
|
#define REALMD_DB_STRUCTURE_NR 1
|
||||||
|
#define REALMD_DB_CONTENT_NR 2
|
||||||
|
#define REALMD_DB_UPDATE_DESCRIPTION "dbdocs update"
|
||||||
|
|
||||||
|
#define CHAR_DB_VERSION_NR 21
|
||||||
|
#define CHAR_DB_STRUCTURE_NR 2
|
||||||
|
#define CHAR_DB_CONTENT_NR 1
|
||||||
|
#define CHAR_DB_UPDATE_DESCRIPTION "match_client_limits"
|
||||||
|
|
||||||
|
#define WORLD_DB_VERSION_NR 21
|
||||||
|
#define WORLD_DB_STRUCTURE_NR 1
|
||||||
|
#define WORLD_DB_CONTENT_NR 0
|
||||||
|
#define WORLD_DB_UPDATE_DESCRIPTION "revision_refactor"
|
||||||
#endif // __REVISION_H__
|
#endif // __REVISION_H__
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
* MaNGOS is a full featured server for World of Warcraft, supporting
|
* MaNGOS is a full featured server for World of Warcraft, supporting
|
||||||
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
|
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005-2015 MaNGOS project <http://getmangos.eu>
|
* Copyright (C) 2005-2016 MaNGOS project <https://getmangos.eu>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -63,90 +63,146 @@ void extractDataFromSvn(FILE* EntriesFile, bool url, RawData& data)
|
||||||
{ strcpy(data.rev_str, num_str); }
|
{ strcpy(data.rev_str, num_str); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void extractDataFromGit(FILE* EntriesFile, std::string path, bool url, RawData& data)
|
bool extractDataFromSvn(std::string filename, bool url, RawData& data)
|
||||||
{
|
{
|
||||||
char buf[200];
|
FILE* entriesFile = fopen(filename.c_str(), "r");
|
||||||
|
if (!entriesFile)
|
||||||
|
{ return false; }
|
||||||
|
|
||||||
char hash_str[200];
|
extractDataFromSvn(entriesFile, url, data);
|
||||||
char branch_str[200];
|
fclose(entriesFile);
|
||||||
char url_str[200];
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool found = false;
|
bool extractDataFromGit(std::string filename, std::string path, bool url, RawData& data)
|
||||||
while (fgets(buf, 200, EntriesFile))
|
{
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
if (FILE* entriesFile = fopen(filename.c_str(), "r"))
|
||||||
{
|
{
|
||||||
if (sscanf(buf, "%s\t\tbranch %s of %s", hash_str, branch_str, url_str) == 3)
|
char hash_str[200];
|
||||||
{
|
char branch_str[200];
|
||||||
found = true;
|
char url_str[200];
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found)
|
bool found = false;
|
||||||
{
|
while (fgets(buf, 200, entriesFile))
|
||||||
strcpy(data.rev_str, "*");
|
|
||||||
strcpy(data.date_str, "*");
|
|
||||||
strcpy(data.time_str, "*");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url)
|
|
||||||
{
|
|
||||||
char* host_str = NULL;
|
|
||||||
char* acc_str = NULL;
|
|
||||||
char* repo_str = NULL;
|
|
||||||
|
|
||||||
// parse URL like git@github.com:mangosthree/server
|
|
||||||
char url_buf[200];
|
|
||||||
int res = sscanf(url_str, "git@%s", url_buf);
|
|
||||||
if (res)
|
|
||||||
{
|
{
|
||||||
host_str = strtok(url_buf, ":");
|
if (sscanf(buf, "%s\t\tbranch %s of %s", hash_str, branch_str, url_str) == 3)
|
||||||
acc_str = strtok(NULL, "/");
|
|
||||||
repo_str = strtok(NULL, " ");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
res = sscanf(url_str, "git://%s", url_buf);
|
|
||||||
if (res)
|
|
||||||
{
|
{
|
||||||
host_str = strtok(url_buf, "/");
|
found = true;
|
||||||
acc_str = strtok(NULL, "/");
|
break;
|
||||||
repo_str = strtok(NULL, ".");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// can generate nice link
|
fclose(entriesFile);
|
||||||
if (res)
|
|
||||||
{ sprintf(data.rev_str, "http://%s/%s/%s/commit/%s", host_str, acc_str, repo_str, hash_str); }
|
if (!found)
|
||||||
// unknonw URL format, use as-is
|
{
|
||||||
|
strcpy(data.rev_str, "*");
|
||||||
|
strcpy(data.date_str, "*");
|
||||||
|
strcpy(data.time_str, "*");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url)
|
||||||
|
{
|
||||||
|
char* host_str = NULL;
|
||||||
|
char* acc_str = NULL;
|
||||||
|
char* repo_str = NULL;
|
||||||
|
|
||||||
|
// parse URL like git@github.com:mangosthree/server
|
||||||
|
char url_buf[200];
|
||||||
|
int res = sscanf(url_str, "git@%s", url_buf);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
host_str = strtok(url_buf, ":");
|
||||||
|
acc_str = strtok(NULL, "/");
|
||||||
|
repo_str = strtok(NULL, " ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res = sscanf(url_str, "git://%s", url_buf);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
host_str = strtok(url_buf, "/");
|
||||||
|
acc_str = strtok(NULL, "/");
|
||||||
|
repo_str = strtok(NULL, ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// can generate nice link
|
||||||
|
if (res)
|
||||||
|
{ sprintf(data.rev_str, "http://%s/%s/%s/commit/%s", host_str, acc_str, repo_str, hash_str); }
|
||||||
|
// unknonw URL format, use as-is
|
||||||
|
else
|
||||||
|
{ sprintf(data.rev_str, "%s at %s", hash_str, url_str); }
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{ sprintf(data.rev_str, "%s at %s", hash_str, url_str); }
|
{ strcpy(data.rev_str, hash_str); }
|
||||||
|
}
|
||||||
|
else if (entriesFile = fopen((path + ".git/HEAD").c_str(), "r"))
|
||||||
|
{
|
||||||
|
if (!fgets(buf, sizeof(buf), entriesFile))
|
||||||
|
{
|
||||||
|
fclose(entriesFile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char refBuff[200];
|
||||||
|
if (!sscanf(buf, "ref: %s", refBuff))
|
||||||
|
{
|
||||||
|
fclose(entriesFile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(entriesFile);
|
||||||
|
|
||||||
|
if (FILE *refFile = fopen((path + ".git/" + refBuff).c_str(), "r"))
|
||||||
|
{
|
||||||
|
char hash[41];
|
||||||
|
|
||||||
|
if (!fgets(hash, sizeof(hash), refFile))
|
||||||
|
{
|
||||||
|
fclose(refFile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(data.rev_str, hash);
|
||||||
|
|
||||||
|
fclose(refFile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ return false; }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ strcpy(data.rev_str, hash_str); }
|
return false;
|
||||||
|
|
||||||
time_t rev_time = 0;
|
time_t rev_time = 0;
|
||||||
// extracting date/time
|
// extracting date/time
|
||||||
FILE* LogFile = fopen((path + ".git/logs/HEAD").c_str(), "r");
|
if (FILE* logFile = fopen((path + ".git/logs/HEAD").c_str(), "r"))
|
||||||
if (LogFile)
|
|
||||||
{
|
{
|
||||||
while (fgets(buf, 200, LogFile))
|
while (fgets(buf, sizeof(buf), logFile))
|
||||||
{
|
{
|
||||||
char buf2[200];
|
char *hash = strchr(buf, ' ') + 1;
|
||||||
char new_hash[200];
|
char *time = strchr(hash, ' ');
|
||||||
int unix_time = 0;
|
*(time++) = '\0';
|
||||||
int res2 = sscanf(buf, "%s %s %s %s %i", buf2, new_hash, buf2, buf2, &unix_time);
|
|
||||||
if (res2 != 5)
|
|
||||||
{ continue; }
|
|
||||||
|
|
||||||
if (strcmp(hash_str, new_hash))
|
if (!strcmp(data.rev_str, hash))
|
||||||
{ continue; }
|
{
|
||||||
|
char *tab = strchr(time, '\t');
|
||||||
|
*tab = '\0';
|
||||||
|
|
||||||
rev_time = unix_time;
|
tab = strrchr(time, ' ');
|
||||||
break;
|
*tab = '\0';
|
||||||
|
|
||||||
|
time = strrchr(time, ' ') + 1;
|
||||||
|
rev_time = atoi(time);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(LogFile);
|
fclose(logFile);
|
||||||
|
|
||||||
if (rev_time)
|
if (rev_time)
|
||||||
{
|
{
|
||||||
|
|
@ -171,31 +227,11 @@ void extractDataFromGit(FILE* EntriesFile, std::string path, bool url, RawData&
|
||||||
strcpy(data.date_str, "*");
|
strcpy(data.date_str, "*");
|
||||||
strcpy(data.time_str, "*");
|
strcpy(data.time_str, "*");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool extractDataFromSvn(std::string filename, bool url, RawData& data)
|
|
||||||
{
|
|
||||||
FILE* EntriesFile = fopen(filename.c_str(), "r");
|
|
||||||
if (!EntriesFile)
|
|
||||||
{ return false; }
|
|
||||||
|
|
||||||
extractDataFromSvn(EntriesFile, url, data);
|
|
||||||
fclose(EntriesFile);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool extractDataFromGit(std::string filename, std::string path, bool url, RawData& data)
|
std::string generateHeader(char const* rev_str, char const* date_str, char const* time_str, char const *ver_str)
|
||||||
{
|
|
||||||
FILE* EntriesFile = fopen(filename.c_str(), "r");
|
|
||||||
if (!EntriesFile)
|
|
||||||
{ return false; }
|
|
||||||
|
|
||||||
extractDataFromGit(EntriesFile, path, url, data);
|
|
||||||
fclose(EntriesFile);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string generateHeader(char const* rev_str, char const* date_str, char const* time_str)
|
|
||||||
{
|
{
|
||||||
std::ostringstream newData;
|
std::ostringstream newData;
|
||||||
newData << "#ifndef __REVISION_H__" << std::endl;
|
newData << "#ifndef __REVISION_H__" << std::endl;
|
||||||
|
|
@ -203,6 +239,7 @@ std::string generateHeader(char const* rev_str, char const* date_str, char const
|
||||||
newData << " #define REVISION_ID \"" << rev_str << "\"" << std::endl;
|
newData << " #define REVISION_ID \"" << rev_str << "\"" << std::endl;
|
||||||
newData << " #define REVISION_DATE \"" << date_str << "\"" << std::endl;
|
newData << " #define REVISION_DATE \"" << date_str << "\"" << std::endl;
|
||||||
newData << " #define REVISION_TIME \"" << time_str << "\"" << std::endl;
|
newData << " #define REVISION_TIME \"" << time_str << "\"" << std::endl;
|
||||||
|
newData << " #define VERSION \"" << ver_str << "\"" << std::endl;
|
||||||
newData << "#endif // __REVISION_H__" << std::endl;
|
newData << "#endif // __REVISION_H__" << std::endl;
|
||||||
return newData.str();
|
return newData.str();
|
||||||
}
|
}
|
||||||
|
|
@ -218,7 +255,7 @@ int main(int argc, char** argv)
|
||||||
// -g use git prefered (default)
|
// -g use git prefered (default)
|
||||||
// -s use svn prefered
|
// -s use svn prefered
|
||||||
// -r use only revision (without repo URL) (default)
|
// -r use only revision (without repo URL) (default)
|
||||||
// -u include repositire URL as commit URL or "rev at URL"
|
// -u include repository URL as commit URL or "rev at URL"
|
||||||
// -o <file> write header to specified target file
|
// -o <file> write header to specified target file
|
||||||
for (int k = 1; k <= argc; ++k)
|
for (int k = 1; k <= argc; ++k)
|
||||||
{
|
{
|
||||||
|
|
@ -260,6 +297,18 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// new data extraction
|
/// new data extraction
|
||||||
|
char version[200];
|
||||||
|
if (FILE *versionFile = fopen((path + "/version.txt").c_str(), "r"))
|
||||||
|
{
|
||||||
|
if (!fgets(version, sizeof(version), versionFile))
|
||||||
|
{
|
||||||
|
fclose(versionFile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(versionFile);
|
||||||
|
}
|
||||||
|
|
||||||
std::string newData;
|
std::string newData;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -289,34 +338,34 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
{ newData = generateHeader(data.rev_str, data.date_str, data.time_str); }
|
{ newData = generateHeader(data.rev_str, data.date_str, data.time_str, version); }
|
||||||
else
|
else
|
||||||
{ newData = generateHeader("*", "*", "*"); }
|
{ newData = generateHeader("*", "*", "*", "0.0"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get existed header data for compare
|
/// get existed header data for compare
|
||||||
std::string oldData;
|
std::string oldData;
|
||||||
|
|
||||||
if (FILE* HeaderFile = fopen(outfile.c_str(), "rb"))
|
if (FILE* headerFile = fopen(outfile.c_str(), "rb"))
|
||||||
{
|
{
|
||||||
while (!feof(HeaderFile))
|
while (!feof(headerFile))
|
||||||
{
|
{
|
||||||
int c = fgetc(HeaderFile);
|
int c = fgetc(headerFile);
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
{ break; }
|
{ break; }
|
||||||
oldData += (char)c;
|
oldData += (char)c;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(HeaderFile);
|
fclose(headerFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// update header only if different data
|
/// update header only if different data
|
||||||
if (newData != oldData)
|
if (newData != oldData)
|
||||||
{
|
{
|
||||||
if (FILE* OutputFile = fopen(outfile.c_str(), "wb"))
|
if (FILE* outputFile = fopen(outfile.c_str(), "w"))
|
||||||
{
|
{
|
||||||
fprintf(OutputFile, "%s", newData.c_str());
|
fprintf(outputFile, "%s", newData.c_str());
|
||||||
fclose(OutputFile);
|
fclose(outputFile);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ return 1; }
|
{ return 1; }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue