From 5a363ee0e1556b58ad1d16ce2b78ae5f92e065ea Mon Sep 17 00:00:00 2001 From: leak Date: Sat, 17 May 2014 20:27:39 +0200 Subject: Replace authserver ACE related code with Boost/C++11 --- src/server/worldserver/Master.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/server/worldserver/Master.cpp') diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index c5424374f5a..a5230b908ef 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -40,7 +40,6 @@ #include "TCSoap.h" #include "Timer.h" #include "Util.h" -#include "AuthSocket.h" #include "RealmList.h" #include "BigNumber.h" -- cgit v1.2.3 From 33dc72a812ad5fb6e17a26b14d6d7f9aaf5d34b5 Mon Sep 17 00:00:00 2001 From: leak Date: Sat, 21 Jun 2014 19:39:16 +0200 Subject: Replaced Threading and SFMT access related code with std::thread and boost TSS Note: The remote access thread is currently broken due to unknown ACE fail (will be replaced at some point anyways..) --- dep/SFMT/SFMT.h | 87 ++++---- src/server/shared/Common.h | 3 - src/server/shared/Database/MySQLThreading.h | 27 +-- src/server/shared/Threading/Threading.cpp | 235 --------------------- src/server/shared/Threading/Threading.h | 108 ---------- src/server/shared/Utilities/Util.cpp | 37 ++-- src/server/shared/Utilities/Util.h | 3 - src/server/worldserver/CommandLine/CliRunnable.cpp | 2 +- src/server/worldserver/CommandLine/CliRunnable.h | 7 +- src/server/worldserver/Master.cpp | 104 ++++----- src/server/worldserver/RemoteAccess/RARunnable.cpp | 28 ++- src/server/worldserver/RemoteAccess/RARunnable.h | 16 +- src/server/worldserver/TCSoap/TCSoap.cpp | 10 +- src/server/worldserver/TCSoap/TCSoap.h | 22 +- .../worldserver/WorldThread/WorldRunnable.cpp | 7 +- src/server/worldserver/WorldThread/WorldRunnable.h | 7 +- 16 files changed, 138 insertions(+), 565 deletions(-) delete mode 100644 src/server/shared/Threading/Threading.cpp delete mode 100644 src/server/shared/Threading/Threading.h (limited to 'src/server/worldserver/Master.cpp') diff --git a/dep/SFMT/SFMT.h b/dep/SFMT/SFMT.h index 4004ae1db6e..3d15d651e5b 100644 --- a/dep/SFMT/SFMT.h +++ b/dep/SFMT/SFMT.h @@ -150,9 +150,13 @@ __m128i const &c, __m128i const &d, __m128i const &mask) { return z2; } +namespace boost { + template class thread_specific_ptr; +} + // Class for SFMT generator class SFMTRand { // Encapsulate random number generator - friend class ACE_TSS; + friend class boost::thread_specific_ptr; public: SFMTRand() @@ -243,6 +247,47 @@ public: y = ((uint32_t*)state)[ix++]; return y; } + + void* operator new(size_t size, std::nothrow_t const&) + { + return _mm_malloc(size, 16); + } + + void operator delete(void* ptr, std::nothrow_t const&) + { + _mm_free(ptr); + } + + void* operator new(size_t size) + { + return _mm_malloc(size, 16); + } + + void operator delete(void* ptr) + { + _mm_free(ptr); + } + + void* operator new[](size_t size, std::nothrow_t const&) + { + return _mm_malloc(size, 16); + } + + void operator delete[](void* ptr, std::nothrow_t const&) + { + _mm_free(ptr); + } + + void* operator new[](size_t size) + { + return _mm_malloc(size, 16); + } + + void operator delete[](void* ptr) + { + _mm_free(ptr); + } + private: void Init2() // Various initializations and period certification { @@ -307,46 +352,6 @@ private: ix = 0; } - void* operator new(size_t size, std::nothrow_t const&) - { - return _mm_malloc(size, 16); - } - - void operator delete(void* ptr, std::nothrow_t const&) - { - _mm_free(ptr); - } - - void* operator new(size_t size) - { - return _mm_malloc(size, 16); - } - - void operator delete(void* ptr) - { - _mm_free(ptr); - } - - void* operator new[](size_t size, std::nothrow_t const&) - { - return _mm_malloc(size, 16); - } - - void operator delete[](void* ptr, std::nothrow_t const&) - { - _mm_free(ptr); - } - - void* operator new[](size_t size) - { - return _mm_malloc(size, 16); - } - - void operator delete[](void* ptr) - { - _mm_free(ptr); - } - __m128i mask; // AND mask __m128i state[SFMT_N]; // State vector for SFMT generator uint32_t ix; // Index into state array diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h index f6152fafc8e..8cab769ec8a 100644 --- a/src/server/shared/Common.h +++ b/src/server/shared/Common.h @@ -82,7 +82,6 @@ #include "Debugging/Errors.h" #include "Threading/LockedQueue.h" -#include "Threading/Threading.h" #if PLATFORM == PLATFORM_WINDOWS # include @@ -114,8 +113,6 @@ inline float finiteAlways(float f) { return finite(f) ? f : 0.0f; } -#define atol(a) strtoul( a, NULL, 10) - #define STRINGIZE(a) #a enum TimeConstants diff --git a/src/server/shared/Database/MySQLThreading.h b/src/server/shared/Database/MySQLThreading.h index 0f6af8ace20..da234138879 100644 --- a/src/server/shared/Database/MySQLThreading.h +++ b/src/server/shared/Database/MySQLThreading.h @@ -23,31 +23,6 @@ class MySQL { public: - /*! Create a thread on the MySQL server to mirrior the calling thread, - initializes thread-specific variables and allows thread-specific - operations without concurrence from other threads. - This should only be called if multiple core threads are running - on the same MySQL connection. Seperate MySQL connections implicitly - create a mirror thread. - */ - static void Thread_Init() - { - mysql_thread_init(); - TC_LOG_WARN("sql.sql", "Core thread with ID [" UI64FMTD "] initializing MySQL thread.", - (uint64)ACE_Based::Thread::currentId()); - } - - /*! Shuts down MySQL thread and frees resources, should only be called - when we terminate. MySQL threads and connections are not configurable - during runtime. - */ - static void Thread_End() - { - mysql_thread_end(); - TC_LOG_WARN("sql.sql", "Core thread with ID [" UI64FMTD "] shutting down MySQL thread.", - (uint64)ACE_Based::Thread::currentId()); - } - static void Library_Init() { mysql_library_init(-1, NULL, NULL); @@ -59,4 +34,4 @@ class MySQL } }; -#endif \ No newline at end of file +#endif diff --git a/src/server/shared/Threading/Threading.cpp b/src/server/shared/Threading/Threading.cpp deleted file mode 100644 index f67a985943a..00000000000 --- a/src/server/shared/Threading/Threading.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * Copyright (C) 2005-2008 MaNGOS - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Threading.h" -#include "Errors.h" -#include -#include -#include - -using namespace ACE_Based; - -ThreadPriority::ThreadPriority() -{ - for (int i = Idle; i < MAXPRIORITYNUM; ++i) - m_priority[i] = ACE_THR_PRI_OTHER_DEF; - - m_priority[Idle] = ACE_Sched_Params::priority_min(ACE_SCHED_OTHER); - m_priority[Realtime] = ACE_Sched_Params::priority_max(ACE_SCHED_OTHER); - - std::vector _tmp; - - ACE_Sched_Params::Policy _policy = ACE_SCHED_OTHER; - ACE_Sched_Priority_Iterator pr_iter(_policy); - - while (pr_iter.more()) - { - _tmp.push_back(pr_iter.priority()); - pr_iter.next(); - } - - ASSERT (!_tmp.empty()); - - if (_tmp.size() >= MAXPRIORITYNUM) - { - const size_t max_pos = _tmp.size(); - size_t min_pos = 1; - size_t norm_pos = 0; - for (size_t i = 0; i < max_pos; ++i) - { - if (_tmp[i] == ACE_THR_PRI_OTHER_DEF) - { - norm_pos = i + 1; - break; - } - } - - // since we have only 7(seven) values in enum Priority - // and 3 we know already (Idle, Normal, Realtime) so - // we need to split each list [Idle...Normal] and [Normal...Realtime] - // into pieces - const size_t _divider = 4; - size_t _div = (norm_pos - min_pos) / _divider; - if (_div == 0) - _div = 1; - - min_pos = (norm_pos - 1); - - m_priority[Low] = _tmp[min_pos -= _div]; - m_priority[Lowest] = _tmp[min_pos -= _div ]; - - _div = (max_pos - norm_pos) / _divider; - if (_div == 0) - _div = 1; - - min_pos = norm_pos - 1; - - m_priority[High] = _tmp[min_pos += _div]; - m_priority[Highest] = _tmp[min_pos += _div]; - } -} - -int ThreadPriority::getPriority(Priority p) const -{ - if (p < Idle) - p = Idle; - - if (p > Realtime) - p = Realtime; - - return m_priority[p]; -} - -#define THREADFLAG (THR_NEW_LWP | THR_SCHED_DEFAULT| THR_JOINABLE) - -Thread::Thread(): m_iThreadId(0), m_hThreadHandle(0), m_task(0) -{ - -} - -Thread::Thread(Runnable* instance): m_iThreadId(0), m_hThreadHandle(0), m_task(instance) -{ - // register reference to m_task to prevent it deeltion until destructor - if (m_task) - m_task->incReference(); - - bool _start = start(); - ASSERT (_start); -} - -Thread::~Thread() -{ - //Wait(); - - // deleted runnable object (if no other references) - if (m_task) - m_task->decReference(); -} - -//initialize Thread's class static member -Thread::ThreadStorage Thread::m_ThreadStorage; -ThreadPriority Thread::m_TpEnum; - -bool Thread::start() -{ - if (m_task == 0 || m_iThreadId != 0) - return false; - - // incRef before spawing the thread, otherwise Thread::ThreadTask() might call decRef and delete m_task - m_task->incReference(); - - bool res = (ACE_Thread::spawn(&Thread::ThreadTask, (void*)m_task, THREADFLAG, &m_iThreadId, &m_hThreadHandle) == 0); - - if (!res) - m_task->decReference(); - - return res; -} - -bool Thread::wait() -{ - if (!m_hThreadHandle || !m_task) - return false; - - ACE_THR_FUNC_RETURN _value = ACE_THR_FUNC_RETURN(-1); - int _res = ACE_Thread::join(m_hThreadHandle, &_value); - - m_iThreadId = 0; - m_hThreadHandle = 0; - - return (_res == 0); -} - -void Thread::destroy() -{ - if (!m_iThreadId || !m_task) - return; - - if (ACE_Thread::kill(m_iThreadId, -1) != 0) - return; - - m_iThreadId = 0; - m_hThreadHandle = 0; - - // reference set at ACE_Thread::spawn - m_task->decReference(); -} - -void Thread::suspend() -{ - ACE_Thread::suspend(m_hThreadHandle); -} - -void Thread::resume() -{ - ACE_Thread::resume(m_hThreadHandle); -} - -ACE_THR_FUNC_RETURN Thread::ThreadTask(void * param) -{ - Runnable* _task = (Runnable*)param; - _task->run(); - - // task execution complete, free referecne added at - _task->decReference(); - - return (ACE_THR_FUNC_RETURN)0; -} - -ACE_thread_t Thread::currentId() -{ - return ACE_Thread::self(); -} - -ACE_hthread_t Thread::currentHandle() -{ - ACE_hthread_t _handle; - ACE_Thread::self(_handle); - - return _handle; -} - -Thread * Thread::current() -{ - Thread * _thread = m_ThreadStorage.ts_object(); - if (!_thread) - { - _thread = new Thread(); - _thread->m_iThreadId = Thread::currentId(); - _thread->m_hThreadHandle = Thread::currentHandle(); - - Thread * _oldValue = m_ThreadStorage.ts_object(_thread); - if (_oldValue) - delete _oldValue; - } - - return _thread; -} - -void Thread::setPriority(Priority type) -{ - int _priority = m_TpEnum.getPriority(type); - int _ok = ACE_Thread::setprio(m_hThreadHandle, _priority); - //remove this ASSERT in case you don't want to know is thread priority change was successful or not - ASSERT (_ok == 0); -} - -void Thread::Sleep(unsigned long msecs) -{ - ACE_OS::sleep(ACE_Time_Value(0, 1000 * msecs)); -} diff --git a/src/server/shared/Threading/Threading.h b/src/server/shared/Threading/Threading.h deleted file mode 100644 index 9d416109e9f..00000000000 --- a/src/server/shared/Threading/Threading.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * Copyright (C) 2005-2008 MaNGOS - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef THREADING_H -#define THREADING_H - -#include -#include -#include -#include - -namespace ACE_Based -{ - - class Runnable - { - public: - virtual ~Runnable() { } - virtual void run() = 0; - - void incReference() { ++m_refs; } - void decReference() - { - if (!--m_refs) - delete this; - } - private: - ACE_Atomic_Op m_refs; - }; - - enum Priority - { - Idle, - Lowest, - Low, - Normal, - High, - Highest, - Realtime - }; - -#define MAXPRIORITYNUM (Realtime + 1) - - class ThreadPriority - { - public: - ThreadPriority(); - int getPriority(Priority p) const; - - private: - int m_priority[MAXPRIORITYNUM]; - }; - - class Thread - { - public: - Thread(); - explicit Thread(Runnable* instance); - ~Thread(); - - bool start(); - bool wait(); - void destroy(); - - void suspend(); - void resume(); - - void setPriority(Priority type); - - static void Sleep(unsigned long msecs); - static ACE_thread_t currentId(); - static ACE_hthread_t currentHandle(); - static Thread * current(); - - private: - Thread(const Thread&); - Thread& operator=(const Thread&); - - static ACE_THR_FUNC_RETURN ThreadTask(void * param); - - ACE_thread_t m_iThreadId; - ACE_hthread_t m_hThreadHandle; - Runnable* m_task; - - typedef ACE_TSS ThreadStorage; - //global object - container for Thread class representation of every thread - static ThreadStorage m_ThreadStorage; - //use this object to determine current OS thread priority values mapped to enum Priority{ } - static ThreadPriority m_TpEnum; - }; - -} -#endif diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp index fc01442adb3..c766cc3ca91 100644 --- a/src/server/shared/Utilities/Util.cpp +++ b/src/server/shared/Utilities/Util.cpp @@ -21,42 +21,54 @@ #include "utf8.h" #include "SFMT.h" #include "Errors.h" // for ASSERT -#include +#include -typedef ACE_TSS SFMTRandTSS; -static SFMTRandTSS sfmtRand; +static boost::thread_specific_ptr sfmtRand; + +static SFMTRand* GetRng() +{ + SFMTRand* rand = sfmtRand.get(); + + if (!rand) + { + rand = new SFMTRand(); + sfmtRand.reset(rand); + } + + return rand; +} int32 irand(int32 min, int32 max) { ASSERT(max >= min); - return int32(sfmtRand->IRandom(min, max)); + return int32(GetRng()->IRandom(min, max)); } uint32 urand(uint32 min, uint32 max) { ASSERT(max >= min); - return sfmtRand->URandom(min, max); + return GetRng()->URandom(min, max); } float frand(float min, float max) { ASSERT(max >= min); - return float(sfmtRand->Random() * (max - min) + min); + return float(GetRng()->Random() * (max - min) + min); } int32 rand32() { - return int32(sfmtRand->BRandom()); + return int32(GetRng()->BRandom()); } double rand_norm(void) { - return sfmtRand->Random(); + return GetRng()->Random(); } double rand_chance(void) { - return sfmtRand->Random() * 100.0; + return GetRng()->Random() * 100.0; } Tokenizer::Tokenizer(const std::string &src, const char sep, uint32 vectorReserve) @@ -250,13 +262,6 @@ bool IsIPAddress(char const* ipaddress) return inet_addr(ipaddress) != INADDR_NONE; } -std::string GetAddressString(ACE_INET_Addr const& addr) -{ - char buf[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16]; - addr.addr_to_string(buf, ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 16); - return buf; -} - bool IsIPAddrInNetwork(ACE_INET_Addr const& net, ACE_INET_Addr const& addr, ACE_INET_Addr const& subnetMask) { uint32 mask = subnetMask.get_ip_address(); diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h index fb40b921bc2..af28afd66ff 100644 --- a/src/server/shared/Utilities/Util.h +++ b/src/server/shared/Utilities/Util.h @@ -351,9 +351,6 @@ bool IsIPAddress(char const* ipaddress); /// Checks if address belongs to the a network with specified submask bool IsIPAddrInNetwork(ACE_INET_Addr const& net, ACE_INET_Addr const& addr, ACE_INET_Addr const& subnetMask); -/// Transforms ACE_INET_Addr address into string format "dotted_ip:port" -std::string GetAddressString(ACE_INET_Addr const& addr); - uint32 CreatePIDFile(const std::string& filename); std::string ByteArrayToHexStr(uint8 const* bytes, uint32 length, bool reverse = false); diff --git a/src/server/worldserver/CommandLine/CliRunnable.cpp b/src/server/worldserver/CommandLine/CliRunnable.cpp index ac46b218305..295e63c696b 100644 --- a/src/server/worldserver/CommandLine/CliRunnable.cpp +++ b/src/server/worldserver/CommandLine/CliRunnable.cpp @@ -131,7 +131,7 @@ int kb_hit_return() #endif /// %Thread start -void CliRunnable::run() +void CliThread() { ///- Display the list of available CLI functions then beep //TC_LOG_INFO("server.worldserver", ""); diff --git a/src/server/worldserver/CommandLine/CliRunnable.h b/src/server/worldserver/CommandLine/CliRunnable.h index 5510173973e..7ed3a44995f 100644 --- a/src/server/worldserver/CommandLine/CliRunnable.h +++ b/src/server/worldserver/CommandLine/CliRunnable.h @@ -23,12 +23,7 @@ #ifndef __CLIRUNNABLE_H #define __CLIRUNNABLE_H -/// Command Line Interface handling thread -class CliRunnable : public ACE_Based::Runnable -{ - public: - void run() override; -}; +void CliThread(); #endif diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index a5230b908ef..82c547cad40 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -20,6 +20,8 @@ \ingroup Trinityd */ +#include + #include #include "Common.h" @@ -78,51 +80,35 @@ class WorldServerSignalHandler : public Trinity::SignalHandler } }; -class FreezeDetectorRunnable : public ACE_Based::Runnable +void FreezeDetectorThread(uint32 delayTime) { -private: - uint32 _loops; - uint32 _lastChange; - uint32 _delaytime; -public: - FreezeDetectorRunnable() - { - _loops = 0; - _lastChange = 0; - _delaytime = 0; - } + if (!delayTime) + return; - void SetDelayTime(uint32 t) { _delaytime = t; } + TC_LOG_INFO("server.worldserver", "Starting up anti-freeze thread (%u seconds max stuck time)...", delayTime / 1000); + uint32 loops = 0; + uint32 lastChange = 0; - void run() override + while (!World::IsStopped()) { - if (!_delaytime) - return; - - TC_LOG_INFO("server.worldserver", "Starting up anti-freeze thread (%u seconds max stuck time)...", _delaytime/1000); - _loops = 0; - _lastChange = 0; - while (!World::IsStopped()) + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + uint32 curtime = getMSTime(); + // normal work + uint32 worldLoopCounter = World::m_worldLoopCounter.value(); + if (loops != worldLoopCounter) { - ACE_Based::Thread::Sleep(1000); - uint32 curtime = getMSTime(); - // normal work - uint32 worldLoopCounter = World::m_worldLoopCounter.value(); - if (_loops != worldLoopCounter) - { - _lastChange = curtime; - _loops = worldLoopCounter; - } - // possible freeze - else if (getMSTimeDiff(_lastChange, curtime) > _delaytime) - { - TC_LOG_ERROR("server.worldserver", "World Thread hangs, kicking out server!"); - ASSERT(false); - } + lastChange = curtime; + loops = worldLoopCounter; + } + // possible freeze + else if (getMSTimeDiff(lastChange, curtime) > delayTime) + { + TC_LOG_ERROR("server.worldserver", "World Thread hangs, kicking out server!"); + ASSERT(false); } - TC_LOG_INFO("server.worldserver", "Anti-freeze thread exiting without problems."); } -}; + TC_LOG_INFO("server.worldserver", "Anti-freeze thread exiting without problems."); +} /// Main function int Master::Run() @@ -182,10 +168,10 @@ int Master::Run() #endif ///- Launch WorldRunnable thread - ACE_Based::Thread worldThread(new WorldRunnable); - worldThread.setPriority(ACE_Based::Highest); - ACE_Based::Thread* cliThread = NULL; + std::thread worldThread(WorldThread); + + std::thread* cliThread = NULL; #ifdef _WIN32 if (sConfigMgr->GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/) @@ -194,10 +180,10 @@ int Master::Run() #endif { ///- Launch CliRunnable thread - cliThread = new ACE_Based::Thread(new CliRunnable); + cliThread = new std::thread(CliThread); } - ACE_Based::Thread rarThread(new RARunnable); + std::thread rarThread(RemoteAccessThread); #if defined(_WIN32) || defined(__linux__) @@ -268,22 +254,19 @@ int Master::Run() #endif //Start soap serving thread - ACE_Based::Thread* soapThread = NULL; + std::thread* soapThread = nullptr; if (sConfigMgr->GetBoolDefault("SOAP.Enabled", false)) { - TCSoapRunnable* runnable = new TCSoapRunnable(); - runnable->SetListenArguments(sConfigMgr->GetStringDefault("SOAP.IP", "127.0.0.1"), uint16(sConfigMgr->GetIntDefault("SOAP.Port", 7878))); - soapThread = new ACE_Based::Thread(runnable); + soapThread = new std::thread(TCSoapThread, sConfigMgr->GetStringDefault("SOAP.IP", "127.0.0.1"), uint16(sConfigMgr->GetIntDefault("SOAP.Port", 7878))); } + std::thread* freezeDetectorThread = nullptr; + ///- Start up freeze catcher thread if (uint32 freezeDelay = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0)) { - FreezeDetectorRunnable* fdr = new FreezeDetectorRunnable(); - fdr->SetDelayTime(freezeDelay * 1000); - ACE_Based::Thread freezeThread(fdr); - freezeThread.setPriority(ACE_Based::Highest); + freezeDetectorThread = new std::thread(FreezeDetectorThread, freezeDelay); } ///- Launch the world listener socket @@ -304,13 +287,12 @@ int Master::Run() // when the main thread closes the singletons get unloaded // since worldrunnable uses them, it will crash if unloaded after master - worldThread.wait(); - rarThread.wait(); + worldThread.join(); + //rarThread.join(); - if (soapThread) + if (soapThread != nullptr) { - soapThread->wait(); - soapThread->destroy(); + soapThread->join(); delete soapThread; } @@ -324,7 +306,7 @@ int Master::Run() TC_LOG_INFO("server.worldserver", "Halting process..."); - if (cliThread) + if (cliThread != nullptr) { #ifdef _WIN32 @@ -363,17 +345,15 @@ int Master::Run() DWORD numb; WriteConsoleInput(hStdIn, b, 4, &numb); - cliThread->wait(); - - #else - - cliThread->destroy(); + cliThread->join(); #endif delete cliThread; } + delete freezeDetectorThread; + // for some unknown reason, unloading scripts here and not in worldrunnable // fixes a memory leak related to detaching threads from the module //UnloadScriptingModule(); diff --git a/src/server/worldserver/RemoteAccess/RARunnable.cpp b/src/server/worldserver/RemoteAccess/RARunnable.cpp index 44b07163294..4efeb07ef25 100644 --- a/src/server/worldserver/RemoteAccess/RARunnable.cpp +++ b/src/server/worldserver/RemoteAccess/RARunnable.cpp @@ -33,29 +33,22 @@ #include "RASocket.h" -RARunnable::RARunnable() + +void RemoteAccessThread() { - ACE_Reactor_Impl* imp; + ACE_Reactor_Impl* imp = nullptr; #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) imp = new ACE_Dev_Poll_Reactor(); - imp->max_notify_iterations (128); - imp->restart (1); + imp->max_notify_iterations(128); + imp->restart(1); #else imp = new ACE_TP_Reactor(); - imp->max_notify_iterations (128); + imp->max_notify_iterations(128); #endif - m_Reactor = new ACE_Reactor (imp, 1); -} + ACE_Reactor* reactor = new ACE_Reactor(imp, 1); -RARunnable::~RARunnable() -{ - delete m_Reactor; -} - -void RARunnable::run() -{ if (!sConfigMgr->GetBoolDefault("Ra.Enable", false)) return; @@ -65,7 +58,7 @@ void RARunnable::run() std::string stringIp = sConfigMgr->GetStringDefault("Ra.IP", "0.0.0.0"); ACE_INET_Addr listenAddress(raPort, stringIp.c_str()); - if (acceptor.open(listenAddress, m_Reactor) == -1) + if (acceptor.open(listenAddress, reactor) == -1) { TC_LOG_ERROR("server.worldserver", "Trinity RA can not bind to port %d on %s", raPort, stringIp.c_str()); return; @@ -76,9 +69,12 @@ void RARunnable::run() while (!World::IsStopped()) { ACE_Time_Value interval(0, 100000); - if (m_Reactor->run_reactor_event_loop(interval) == -1) + if (reactor->run_reactor_event_loop(interval) == -1) break; } + delete imp; + delete reactor; + TC_LOG_DEBUG("server.worldserver", "Trinity RA thread exiting"); } diff --git a/src/server/worldserver/RemoteAccess/RARunnable.h b/src/server/worldserver/RemoteAccess/RARunnable.h index 540ac762f30..a65df077f97 100644 --- a/src/server/worldserver/RemoteAccess/RARunnable.h +++ b/src/server/worldserver/RemoteAccess/RARunnable.h @@ -22,21 +22,7 @@ #ifndef _TRINITY_RARUNNABLE_H_ #define _TRINITY_RARUNNABLE_H_ -#include "Common.h" - -#include - -class RARunnable : public ACE_Based::Runnable -{ -public: - RARunnable(); - virtual ~RARunnable(); - void run() override; - -private: - ACE_Reactor* m_Reactor; - -}; +void RemoteAccessThread(); #endif /* _TRINITY_RARUNNABLE_H_ */ diff --git a/src/server/worldserver/TCSoap/TCSoap.cpp b/src/server/worldserver/TCSoap/TCSoap.cpp index 1549019352d..3d242859ff2 100644 --- a/src/server/worldserver/TCSoap/TCSoap.cpp +++ b/src/server/worldserver/TCSoap/TCSoap.cpp @@ -22,7 +22,7 @@ #include "AccountMgr.h" #include "Log.h" -void TCSoapRunnable::run() +void TCSoapThread(const std::string& host, uint16 port) { struct soap soap; soap_init(&soap); @@ -33,13 +33,13 @@ void TCSoapRunnable::run() soap.accept_timeout = 3; soap.recv_timeout = 5; soap.send_timeout = 5; - if (!soap_valid_socket(soap_bind(&soap, _host.c_str(), _port, 100))) + if (!soap_valid_socket(soap_bind(&soap, host.c_str(), port, 100))) { - TC_LOG_ERROR("network.soap", "Couldn't bind to %s:%d", _host.c_str(), _port); + TC_LOG_ERROR("network.soap", "Couldn't bind to %s:%d", host.c_str(), port); exit(-1); } - TC_LOG_INFO("network.soap", "Bound to http://%s:%d", _host.c_str(), _port); + TC_LOG_INFO("network.soap", "Bound to http://%s:%d", host.c_str(), port); while (!World::IsStopped()) { @@ -57,7 +57,7 @@ void TCSoapRunnable::run() soap_done(&soap); } -void TCSoapRunnable::process_message(ACE_Message_Block* mb) +void process_message(ACE_Message_Block* mb) { ACE_TRACE (ACE_TEXT ("SOAPWorkingThread::process_message")); diff --git a/src/server/worldserver/TCSoap/TCSoap.h b/src/server/worldserver/TCSoap/TCSoap.h index 427d37ef0cc..937ceac6425 100644 --- a/src/server/worldserver/TCSoap/TCSoap.h +++ b/src/server/worldserver/TCSoap/TCSoap.h @@ -22,27 +22,9 @@ #include #include -#include -class TCSoapRunnable : public ACE_Based::Runnable -{ - public: - TCSoapRunnable() : _port(0) { } - - void run() override; - - void SetListenArguments(const std::string& host, uint16 port) - { - _host = host; - _port = port; - } - - private: - void process_message(ACE_Message_Block* mb); - - std::string _host; - uint16 _port; -}; +void process_message(ACE_Message_Block* mb); +void TCSoapThread(const std::string& host, uint16 port); class SOAPCommand { diff --git a/src/server/worldserver/WorldThread/WorldRunnable.cpp b/src/server/worldserver/WorldThread/WorldRunnable.cpp index 476007f6ea0..7722492b5a8 100644 --- a/src/server/worldserver/WorldThread/WorldRunnable.cpp +++ b/src/server/worldserver/WorldThread/WorldRunnable.cpp @@ -20,6 +20,8 @@ \ingroup Trinityd */ +#include + #include "Common.h" #include "ObjectAccessor.h" #include "World.h" @@ -40,7 +42,7 @@ extern int m_ServiceStatus; #endif /// Heartbeat for the World -void WorldRunnable::run() +void WorldThread() { uint32 realCurrTime = 0; uint32 realPrevTime = getMSTime(); @@ -67,7 +69,8 @@ void WorldRunnable::run() if (diff <= WORLD_SLEEP_CONST+prevSleepTime) { prevSleepTime = WORLD_SLEEP_CONST+prevSleepTime-diff; - ACE_Based::Thread::Sleep(prevSleepTime); + + std::this_thread::sleep_for(std::chrono::milliseconds(prevSleepTime)); } else prevSleepTime = 0; diff --git a/src/server/worldserver/WorldThread/WorldRunnable.h b/src/server/worldserver/WorldThread/WorldRunnable.h index dfc74dd1e3a..915bd5b580a 100644 --- a/src/server/worldserver/WorldThread/WorldRunnable.h +++ b/src/server/worldserver/WorldThread/WorldRunnable.h @@ -23,12 +23,7 @@ #ifndef __WORLDRUNNABLE_H #define __WORLDRUNNABLE_H -/// Heartbeat thread for the World -class WorldRunnable : public ACE_Based::Runnable -{ - public: - void run() override; -}; +void WorldThread(); #endif -- cgit v1.2.3 From 0df19b9087b1336dd60a98256b016def9b058b1e Mon Sep 17 00:00:00 2001 From: leak Date: Sat, 21 Jun 2014 20:19:55 +0200 Subject: Replaced ACE_Auto_Array_Ptr --- src/server/shared/Cryptography/BigNumber.cpp | 8 +++----- src/server/shared/Cryptography/BigNumber.h | 5 +++-- src/server/worldserver/Master.cpp | 3 ++- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/server/worldserver/Master.cpp') diff --git a/src/server/shared/Cryptography/BigNumber.cpp b/src/server/shared/Cryptography/BigNumber.cpp index 1f3fc96e28d..ed355b5f63c 100644 --- a/src/server/shared/Cryptography/BigNumber.cpp +++ b/src/server/shared/Cryptography/BigNumber.cpp @@ -16,13 +16,11 @@ * with this program. If not, see . */ -#include - #include "Cryptography/BigNumber.h" #include #include #include -#include +#include BigNumber::BigNumber() : _bn(BN_new()) @@ -170,7 +168,7 @@ bool BigNumber::isZero() const return BN_is_zero(_bn); } -ACE_Auto_Array_Ptr BigNumber::AsByteArray(int32 minSize, bool littleEndian) +std::unique_ptr BigNumber::AsByteArray(int32 minSize, bool littleEndian) { int length = (minSize >= GetNumBytes()) ? minSize : GetNumBytes(); @@ -186,7 +184,7 @@ ACE_Auto_Array_Ptr BigNumber::AsByteArray(int32 minSize, bool littleEndia if (littleEndian) std::reverse(array, array + length); - ACE_Auto_Array_Ptr ret(array); + std::unique_ptr ret(array); return ret; } diff --git a/src/server/shared/Cryptography/BigNumber.h b/src/server/shared/Cryptography/BigNumber.h index dc553babec9..d0a09dca6c4 100644 --- a/src/server/shared/Cryptography/BigNumber.h +++ b/src/server/shared/Cryptography/BigNumber.h @@ -19,8 +19,9 @@ #ifndef _AUTH_BIGNUMBER_H #define _AUTH_BIGNUMBER_H +#include #include "Define.h" -#include + struct bignum_st; @@ -87,7 +88,7 @@ class BigNumber uint32 AsDword(); - ACE_Auto_Array_Ptr AsByteArray(int32 minSize = 0, bool littleEndian = true); + std::unique_ptr AsByteArray(int32 minSize = 0, bool littleEndian = true); char * AsHexStr() const; char * AsDecStr() const; diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index 82c547cad40..32ca89f3c45 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -183,7 +183,8 @@ int Master::Run() cliThread = new std::thread(CliThread); } - std::thread rarThread(RemoteAccessThread); + // TODO C++11/Boost + // std::thread rarThread(RemoteAccessThread); #if defined(_WIN32) || defined(__linux__) -- cgit v1.2.3 From bfcbde1c97971211d2ecdf5c5f8033eb138658d1 Mon Sep 17 00:00:00 2001 From: leak Date: Sun, 22 Jun 2014 16:29:49 +0200 Subject: Various cleanups and fixes due to feedback --- src/server/shared/Configuration/Config.cpp | 10 +++++----- src/server/shared/Cryptography/BigNumber.cpp | 4 ++-- src/server/shared/Cryptography/BigNumber.h | 2 +- src/server/shared/Utilities/Util.cpp | 7 ++----- src/server/worldserver/Master.cpp | 2 +- 5 files changed, 11 insertions(+), 14 deletions(-) (limited to 'src/server/worldserver/Master.cpp') diff --git a/src/server/shared/Configuration/Config.cpp b/src/server/shared/Configuration/Config.cpp index 95336457428..9e0e57eb198 100644 --- a/src/server/shared/Configuration/Config.cpp +++ b/src/server/shared/Configuration/Config.cpp @@ -35,13 +35,13 @@ bool ConfigMgr::LoadInitial(char const* file) try { - ptree temp; - boost::property_tree::ini_parser::read_ini(file, temp); + ptree fullTree; + boost::property_tree::ini_parser::read_ini(file, fullTree); - - for (auto bla : temp) + // Since we're using only one section per config file, we skip the section and have direct property access + for (auto section : fullTree) { - _config = bla.second; + _config = section.second; break; } } diff --git a/src/server/shared/Cryptography/BigNumber.cpp b/src/server/shared/Cryptography/BigNumber.cpp index ed355b5f63c..c5e0635c5ec 100644 --- a/src/server/shared/Cryptography/BigNumber.cpp +++ b/src/server/shared/Cryptography/BigNumber.cpp @@ -168,7 +168,7 @@ bool BigNumber::isZero() const return BN_is_zero(_bn); } -std::unique_ptr BigNumber::AsByteArray(int32 minSize, bool littleEndian) +std::unique_ptr BigNumber::AsByteArray(int32 minSize, bool littleEndian) { int length = (minSize >= GetNumBytes()) ? minSize : GetNumBytes(); @@ -184,7 +184,7 @@ std::unique_ptr BigNumber::AsByteArray(int32 minSize, bool littleEndian) if (littleEndian) std::reverse(array, array + length); - std::unique_ptr ret(array); + std::unique_ptr ret(array); return ret; } diff --git a/src/server/shared/Cryptography/BigNumber.h b/src/server/shared/Cryptography/BigNumber.h index d0a09dca6c4..848b3da3e2d 100644 --- a/src/server/shared/Cryptography/BigNumber.h +++ b/src/server/shared/Cryptography/BigNumber.h @@ -88,7 +88,7 @@ class BigNumber uint32 AsDword(); - std::unique_ptr AsByteArray(int32 minSize = 0, bool littleEndian = true); + std::unique_ptr AsByteArray(int32 minSize = 0, bool littleEndian = true); char * AsHexStr() const; char * AsDecStr() const; diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp index f80730af05d..1290a7dbae4 100644 --- a/src/server/shared/Utilities/Util.cpp +++ b/src/server/shared/Utilities/Util.cpp @@ -139,16 +139,13 @@ void stripLineInvisibleChars(std::string &str) } +#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) struct tm* localtime_r(const time_t* time, struct tm *result) { -#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) localtime_s(result, time); return result; -#else - return localtime_r(&time, &result); // POSIX -#endif } - +#endif std::string secsToTimeString(uint64 timeInSecs, bool shortText, bool hoursOnly) { diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index 32ca89f3c45..765ab0f09a6 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -171,7 +171,7 @@ int Master::Run() std::thread worldThread(WorldThread); - std::thread* cliThread = NULL; + std::thread* cliThread = nullptr; #ifdef _WIN32 if (sConfigMgr->GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/) -- cgit v1.2.3 From 029bad6698df6ac9556fe308342e616f4a7a8cc7 Mon Sep 17 00:00:00 2001 From: leak Date: Tue, 1 Jul 2014 00:54:09 +0200 Subject: Replaced all remaining ACE based Singletons Replaced ACE base AutoPtr class with shared_ptr Note: worldserver currently broken due to MapUpdater threading failure (ACE ofc, what else could it be) --- src/server/authserver/Main.cpp | 1 - src/server/collision/Management/VMapManager2.cpp | 2 - src/server/game/AI/SmartScripts/SmartScriptMgr.h | 28 +++++++---- src/server/game/Accounts/AccountMgr.h | 11 +++-- src/server/game/Achievements/AchievementMgr.h | 10 ++-- src/server/game/AuctionHouse/AuctionHouseMgr.h | 11 +++-- src/server/game/Battlefield/BattlefieldMgr.h | 17 ++++--- src/server/game/Battlegrounds/ArenaTeam.h | 1 - src/server/game/Battlegrounds/ArenaTeamMgr.h | 10 +++- src/server/game/Battlegrounds/BattlegroundMgr.h | 11 +++-- src/server/game/Calendar/CalendarMgr.h | 11 +++-- src/server/game/Chat/Channels/ChannelMgr.cpp | 6 +-- src/server/game/Chat/Channels/ChannelMgr.h | 14 ++++-- src/server/game/Conditions/ConditionMgr.h | 12 +++-- src/server/game/DataStores/DBCStructure.h | 10 ++-- src/server/game/DungeonFinding/LFGMgr.h | 11 +++-- src/server/game/Entities/Creature/CreatureGroups.h | 13 +++-- src/server/game/Entities/Item/Item.cpp | 4 +- src/server/game/Entities/Player/Player.cpp | 6 +-- src/server/game/Entities/Player/SocialMgr.h | 11 +++-- src/server/game/Events/GameEventMgr.h | 11 +++-- src/server/game/Globals/ObjectMgr.h | 10 ++-- src/server/game/Groups/GroupMgr.h | 9 +++- src/server/game/Guilds/GuildMgr.h | 10 ++-- src/server/game/Handlers/AddonHandler.cpp | 4 -- src/server/game/Handlers/AddonHandler.h | 19 ++++---- src/server/game/Maps/MapManager.h | 14 +++--- src/server/game/Maps/TransportMgr.h | 10 ++-- src/server/game/Movement/MovementGenerator.h | 1 - .../game/Movement/Waypoints/WaypointManager.h | 13 ++--- src/server/game/OutdoorPvP/OutdoorPvPMgr.h | 11 +++-- src/server/game/Pools/PoolMgr.h | 11 +++-- src/server/game/Scripting/ScriptMgr.h | 10 ++-- src/server/game/Scripting/ScriptSystem.h | 11 +++-- src/server/game/Server/Protocol/PacketLog.h | 11 +++-- src/server/game/Server/WorldSession.cpp | 2 +- src/server/game/Server/WorldSocketMgr.h | 12 +++-- src/server/game/Spells/SpellMgr.h | 12 +++-- src/server/game/Texts/CreatureTextMgr.h | 14 ++++-- src/server/game/Tickets/TicketMgr.h | 11 +++-- src/server/game/Warden/WardenCheckMgr.h | 14 ++++-- src/server/game/Weather/WeatherMgr.cpp | 2 +- src/server/game/World/World.cpp | 4 +- src/server/game/World/World.h | 17 ++++--- src/server/shared/Cryptography/ARC4.h | 2 +- src/server/shared/Cryptography/BigNumber.h | 1 - src/server/shared/Database/DatabaseWorkerPool.h | 10 +--- src/server/shared/Database/MySQLConnection.h | 8 ++-- src/server/shared/Database/QueryResult.h | 8 ++-- src/server/shared/Database/Transaction.h | 2 +- src/server/shared/Debugging/Errors.cpp | 11 ++--- src/server/shared/Logging/Appender.h | 4 +- src/server/shared/Logging/AppenderConsole.h | 2 +- src/server/shared/Logging/AppenderFile.h | 2 +- src/server/shared/Threading/Callback.h | 6 +-- src/server/shared/Threading/DelayExecutor.cpp | 18 ++++++- src/server/shared/Threading/DelayExecutor.h | 2 - src/server/worldserver/Master.cpp | 55 ++++++++-------------- src/server/worldserver/Master.h | 8 +++- .../worldserver/WorldThread/WorldRunnable.cpp | 4 +- src/server/worldserver/WorldThread/WorldRunnable.h | 4 +- 61 files changed, 347 insertions(+), 243 deletions(-) (limited to 'src/server/worldserver/Master.cpp') diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index 3901480c70d..ad04a52c7db 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -178,7 +178,6 @@ int main(int argc, char** argv) SetProcessPriority(); - _dbPingInterval = sConfigMgr->GetIntDefault("MaxPingTime", 30); _dbPingTimer.expires_from_now(boost::posix_time::seconds(_dbPingInterval)); diff --git a/src/server/collision/Management/VMapManager2.cpp b/src/server/collision/Management/VMapManager2.cpp index 2aa3b6ab40d..00381cb1205 100644 --- a/src/server/collision/Management/VMapManager2.cpp +++ b/src/server/collision/Management/VMapManager2.cpp @@ -26,8 +26,6 @@ #include "ModelInstance.h" #include "WorldModel.h" #include -#include -#include #include "DisableMgr.h" #include "DBCStores.h" #include "Log.h" diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 3d14b8f69e9..0380ec8bae9 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1396,11 +1396,17 @@ typedef std::unordered_map ObjectListMap; class SmartWaypointMgr { - friend class ACE_Singleton; - SmartWaypointMgr() { } - public: + private: + SmartWaypointMgr() { } ~SmartWaypointMgr(); + public: + static SmartWaypointMgr* instance() + { + static SmartWaypointMgr* instance = new SmartWaypointMgr(); + return instance; + } + void LoadFromDB(); WPPath* GetPath(uint32 id) @@ -1426,11 +1432,17 @@ typedef std::pair; - SmartAIMgr() { } - public: + private: + SmartAIMgr() { } ~SmartAIMgr() { } + public: + static SmartAIMgr* instance() + { + static SmartAIMgr* instance = new SmartAIMgr(); + return instance; + } + void LoadSmartAIFromDB(); SmartAIEventList GetScript(int32 entry, SmartScriptType type) @@ -1598,6 +1610,6 @@ class SmartAIMgr CacheSpellContainer KillCreditSpellStore; }; -#define sSmartScriptMgr ACE_Singleton::instance() -#define sSmartWaypointMgr ACE_Singleton::instance() +#define sSmartScriptMgr SmartAIMgr::instance() +#define sSmartWaypointMgr SmartWaypointMgr::instance() #endif diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index b3012ace177..2f3137ae3cd 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -20,7 +20,6 @@ #define _ACCMGR_H #include "RBAC.h" -#include enum AccountOpResult { @@ -51,13 +50,17 @@ typedef std::map RBACDefaultPermissionsCon class AccountMgr { - friend class ACE_Singleton; - private: AccountMgr(); ~AccountMgr(); public: + static AccountMgr* instance() + { + static AccountMgr* instance = new AccountMgr(); + return instance; + } + AccountOpResult CreateAccount(std::string username, std::string password, std::string email); static AccountOpResult DeleteAccount(uint32 accountId); static AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword); @@ -95,5 +98,5 @@ class AccountMgr rbac::RBACDefaultPermissionsContainer _defaultPermissions; }; -#define sAccountMgr ACE_Singleton::instance() +#define sAccountMgr AccountMgr::instance() #endif diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index c3a1481bb2e..7128b8d6318 100644 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -23,7 +23,6 @@ #include #include "Common.h" -#include #include "DatabaseEnv.h" #include "DBCEnums.h" #include "DBCStores.h" @@ -305,11 +304,16 @@ class AchievementMgr class AchievementGlobalMgr { - friend class ACE_Singleton; AchievementGlobalMgr() { } ~AchievementGlobalMgr() { } public: + static AchievementGlobalMgr* instance() + { + static AchievementGlobalMgr* instance = new AchievementGlobalMgr(); + return instance; + } + AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type) const { return m_AchievementCriteriasByType[type]; @@ -389,6 +393,6 @@ class AchievementGlobalMgr AchievementRewardLocales m_achievementRewardLocales; }; -#define sAchievementMgr ACE_Singleton::instance() +#define sAchievementMgr AchievementGlobalMgr::instance() #endif diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h index f45fc4100de..0f42a5833a2 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.h +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h @@ -19,8 +19,6 @@ #ifndef _AUCTION_HOUSE_MGR_H #define _AUCTION_HOUSE_MGR_H -#include - #include "Common.h" #include "DatabaseEnv.h" #include "DBCStructure.h" @@ -137,13 +135,16 @@ class AuctionHouseObject class AuctionHouseMgr { - friend class ACE_Singleton; - private: AuctionHouseMgr(); ~AuctionHouseMgr(); public: + static AuctionHouseMgr* instance() + { + static AuctionHouseMgr* instance = new AuctionHouseMgr(); + return instance; + } typedef std::unordered_map ItemMap; @@ -193,6 +194,6 @@ class AuctionHouseMgr ItemMap mAitems; }; -#define sAuctionMgr ACE_Singleton::instance() +#define sAuctionMgr AuctionHouseMgr::instance() #endif diff --git a/src/server/game/Battlefield/BattlefieldMgr.h b/src/server/game/Battlefield/BattlefieldMgr.h index bb8a076d5d0..9b51fd7710e 100644 --- a/src/server/game/Battlefield/BattlefieldMgr.h +++ b/src/server/game/Battlefield/BattlefieldMgr.h @@ -19,7 +19,6 @@ #define BATTLEFIELD_MGR_H_ #include "Battlefield.h" -#include class Player; class ZoneScript; @@ -28,11 +27,12 @@ class ZoneScript; class BattlefieldMgr { public: - // ctor - BattlefieldMgr(); - // dtor - ~BattlefieldMgr(); - + static BattlefieldMgr* instance() + { + static BattlefieldMgr* instance = new BattlefieldMgr(); + return instance; + } + // create battlefield events void InitBattlefield(); @@ -52,6 +52,9 @@ class BattlefieldMgr void Update(uint32 diff); private: + BattlefieldMgr(); + ~BattlefieldMgr(); + typedef std::vector BattlefieldSet; typedef std::map BattlefieldMap; // contains all initiated battlefield events @@ -64,6 +67,6 @@ class BattlefieldMgr uint32 _updateTimer; }; -#define sBattlefieldMgr ACE_Singleton::instance() +#define sBattlefieldMgr BattlefieldMgr::instance() #endif // BATTLEFIELD_MGR_H_ diff --git a/src/server/game/Battlegrounds/ArenaTeam.h b/src/server/game/Battlegrounds/ArenaTeam.h index cd9e2be4318..85372c35daa 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.h +++ b/src/server/game/Battlegrounds/ArenaTeam.h @@ -20,7 +20,6 @@ #define TRINITYCORE_ARENATEAM_H #include "QueryResult.h" -#include #include #include diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.h b/src/server/game/Battlegrounds/ArenaTeamMgr.h index 946824fb656..9a4c1184133 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.h +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.h @@ -22,11 +22,17 @@ class ArenaTeamMgr { - friend class ACE_Singleton; +private: ArenaTeamMgr(); ~ArenaTeamMgr(); public: + static ArenaTeamMgr* instance() + { + static ArenaTeamMgr* instance = new ArenaTeamMgr(); + return instance; + } + typedef std::unordered_map ArenaTeamContainer; ArenaTeam* GetArenaTeamById(uint32 arenaTeamId) const; @@ -50,6 +56,6 @@ protected: ArenaTeamContainer ArenaTeamStore; }; -#define sArenaTeamMgr ACE_Singleton::instance() +#define sArenaTeamMgr ArenaTeamMgr::instance() #endif diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h index 786e664c3f3..046e2588ad3 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.h +++ b/src/server/game/Battlegrounds/BattlegroundMgr.h @@ -23,7 +23,6 @@ #include "DBCEnums.h" #include "Battleground.h" #include "BattlegroundQueue.h" -#include typedef std::map BattlegroundContainer; typedef std::set BattlegroundClientIdsContainer; @@ -64,13 +63,17 @@ struct BattlegroundData class BattlegroundMgr { - friend class ACE_Singleton; - private: BattlegroundMgr(); ~BattlegroundMgr(); public: + static BattlegroundMgr* instance() + { + static BattlegroundMgr* instance = new BattlegroundMgr(); + return instance; + } + void Update(uint32 diff); /* Packet Building */ @@ -158,5 +161,5 @@ class BattlegroundMgr BattleMastersMap mBattleMastersMap; }; -#define sBattlegroundMgr ACE_Singleton::instance() +#define sBattlegroundMgr BattlegroundMgr::instance() #endif diff --git a/src/server/game/Calendar/CalendarMgr.h b/src/server/game/Calendar/CalendarMgr.h index 8f44b013e5c..9c7882fe4b7 100644 --- a/src/server/game/Calendar/CalendarMgr.h +++ b/src/server/game/Calendar/CalendarMgr.h @@ -18,7 +18,6 @@ #ifndef TRINITY_CALENDARMGR_H #define TRINITY_CALENDARMGR_H -#include #include "Common.h" #include "DatabaseEnv.h" #include "WorldPacket.h" @@ -268,8 +267,6 @@ typedef std::map CalendarEventInvite class CalendarMgr { - friend class ACE_Singleton; - private: CalendarMgr(); ~CalendarMgr(); @@ -283,6 +280,12 @@ class CalendarMgr uint64 _maxInviteId; public: + static CalendarMgr* instance() + { + static CalendarMgr* instance = new CalendarMgr(); + return instance; + } + void LoadFromDB(); CalendarEvent* GetEvent(uint64 eventId) const; @@ -329,6 +332,6 @@ class CalendarMgr void SendPacketToAllEventRelatives(WorldPacket packet, CalendarEvent const& calendarEvent); }; -#define sCalendarMgr ACE_Singleton::instance() +#define sCalendarMgr CalendarMgr::instance() #endif diff --git a/src/server/game/Chat/Channels/ChannelMgr.cpp b/src/server/game/Chat/Channels/ChannelMgr.cpp index 0975a690889..00824ae2056 100644 --- a/src/server/game/Chat/Channels/ChannelMgr.cpp +++ b/src/server/game/Chat/Channels/ChannelMgr.cpp @@ -29,13 +29,13 @@ ChannelMgr::~ChannelMgr() ChannelMgr* ChannelMgr::forTeam(uint32 team) { if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)) - return ACE_Singleton::instance(); // cross-faction + return AllianceChannelMgr::instance(); // cross-faction if (team == ALLIANCE) - return ACE_Singleton::instance(); + return AllianceChannelMgr::instance(); if (team == HORDE) - return ACE_Singleton::instance(); + return HordeChannelMgr::instance(); return NULL; } diff --git a/src/server/game/Chat/Channels/ChannelMgr.h b/src/server/game/Chat/Channels/ChannelMgr.h index 603eb52f589..0fd5cdbfe24 100644 --- a/src/server/game/Chat/Channels/ChannelMgr.h +++ b/src/server/game/Chat/Channels/ChannelMgr.h @@ -20,7 +20,6 @@ #include "Common.h" #include "Channel.h" -#include #include #include @@ -31,12 +30,17 @@ class ChannelMgr { typedef std::map ChannelMap; - public: - ChannelMgr() : team(0) - { } - + protected: + ChannelMgr() : team(0) { } ~ChannelMgr(); + public: + static ChannelMgr* instance() + { + static ChannelMgr* instance = new ChannelMgr(); + return instance; + } + static ChannelMgr * forTeam(uint32 team); void setTeam(uint32 newTeam) { team = newTeam; } diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 876b922d243..a78434776e0 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -21,7 +21,6 @@ #include "Define.h" #include "Errors.h" -#include #include #include @@ -223,13 +222,18 @@ typedef std::map ConditionReferenceContainer;//only used class ConditionMgr { - friend class ACE_Singleton; - private: ConditionMgr(); ~ConditionMgr(); public: + + static ConditionMgr* instance() + { + static ConditionMgr* instance = new ConditionMgr(); + return instance; + } + void LoadConditions(bool isReload = false); bool isConditionTypeValid(Condition* cond); ConditionList GetConditionReferences(uint32 refId); @@ -265,6 +269,6 @@ class ConditionMgr SmartEventConditionContainer SmartEventConditionStore; }; -#define sConditionMgr ACE_Singleton::instance() +#define sConditionMgr ConditionMgr::instance() #endif diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 5d6c8c7aa89..ec9d2dafbd2 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -535,7 +535,7 @@ struct AreaTableEntry { if (mapid == 609) return true; - return (flags & AREA_FLAG_SANCTUARY); + return (flags & AREA_FLAG_SANCTUARY) != 0; } }; @@ -1367,7 +1367,7 @@ struct MapEntry return MapID == 0 || MapID == 1 || MapID == 530 || MapID == 571; } - bool IsDynamicDifficultyMap() const { return Flags & MAP_FLAG_DYNAMIC_DIFFICULTY; } + bool IsDynamicDifficultyMap() const { return (Flags & MAP_FLAG_DYNAMIC_DIFFICULTY) != 0; } }; struct MapDifficultyEntry @@ -2047,12 +2047,12 @@ struct VehicleSeatEntry uint32 m_flagsB; // 45 // 46-57 added in 3.1, floats mostly - bool CanEnterOrExit() const { return m_flags & VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT; } - bool CanSwitchFromSeat() const { return m_flags & VEHICLE_SEAT_FLAG_CAN_SWITCH; } + bool CanEnterOrExit() const { return (m_flags & VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT) != 0; } + bool CanSwitchFromSeat() const { return (m_flags & VEHICLE_SEAT_FLAG_CAN_SWITCH) != 0; } bool IsUsableByOverride() const { return (m_flags & (VEHICLE_SEAT_FLAG_UNCONTROLLED | VEHICLE_SEAT_FLAG_UNK18) || (m_flagsB & (VEHICLE_SEAT_FLAG_B_USABLE_FORCED | VEHICLE_SEAT_FLAG_B_USABLE_FORCED_2 | VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3 | VEHICLE_SEAT_FLAG_B_USABLE_FORCED_4))); } - bool IsEjectable() const { return m_flagsB & VEHICLE_SEAT_FLAG_B_EJECTABLE; } + bool IsEjectable() const { return (m_flagsB & VEHICLE_SEAT_FLAG_B_EJECTABLE) != 0; } }; struct WMOAreaTableEntry diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 2c31fe37d4d..03ac5254057 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -18,7 +18,6 @@ #ifndef _LFGMGR_H #define _LFGMGR_H -#include #include "DBCStructure.h" #include "Field.h" #include "LFG.h" @@ -292,13 +291,17 @@ struct LFGDungeonData class LFGMgr { - friend class ACE_Singleton; - private: LFGMgr(); ~LFGMgr(); public: + static LFGMgr* instance() + { + static LFGMgr* instance = new LFGMgr(); + return instance; + } + // Functions used outside lfg namespace void Update(uint32 diff); @@ -466,5 +469,5 @@ class LFGMgr } // namespace lfg -#define sLFGMgr ACE_Singleton::instance() +#define sLFGMgr lfg::LFGMgr::instance() #endif diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h index b790853f5e1..29832e4ff76 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.h +++ b/src/server/game/Entities/Creature/CreatureGroups.h @@ -40,10 +40,17 @@ typedef std::unordered_map CreatureGro class FormationMgr { - friend class ACE_Singleton; - public: + private: FormationMgr() { } ~FormationMgr(); + + public: + static FormationMgr* instance() + { + static FormationMgr* instance = new FormationMgr(); + return instance; + } + void AddCreatureToGroup(uint32 group_id, Creature* creature); void RemoveCreatureFromGroup(CreatureGroup* group, Creature* creature); void LoadCreatureFormations(); @@ -78,6 +85,6 @@ class CreatureGroup void MemberAttackStart(Creature* member, Unit* target); }; -#define sFormationMgr ACE_Singleton::instance() +#define sFormationMgr FormationMgr::instance() #endif diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 4573b85c7f3..e041e063080 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -310,7 +310,7 @@ void Item::UpdateDuration(Player* owner, uint32 diff) void Item::SaveToDB(SQLTransaction& trans) { - bool isInTransaction = !(trans.null()); + bool isInTransaction = !trans; if (!isInTransaction) trans = CharacterDatabase.BeginTransaction(); @@ -1129,7 +1129,7 @@ void Item::SaveRefundDataToDB() void Item::DeleteRefundDataFromDB(SQLTransaction* trans) { - if (trans && !trans->null()) + if (trans) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_REFUND_INSTANCE); stmt->setUInt32(0, GetGUIDLow()); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 9733c0f2b52..f2823cc1435 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7326,7 +7326,7 @@ void Player::ModifyHonorPoints(int32 value, SQLTransaction* trans /*=NULL*/) newValue = 0; SetHonorPoints(uint32(newValue)); - if (trans && !trans->null()) + if (trans && !trans) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_HONOR_POINTS); stmt->setUInt32(0, newValue); @@ -7342,7 +7342,7 @@ void Player::ModifyArenaPoints(int32 value, SQLTransaction* trans /*=NULL*/) newValue = 0; SetArenaPoints(uint32(newValue)); - if (trans && !trans->null()) + if (trans && !trans) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ARENA_POINTS); stmt->setUInt32(0, newValue); @@ -19769,7 +19769,7 @@ void Player::_SaveMail(SQLTransaction& trans) void Player::_SaveQuestStatus(SQLTransaction& trans) { - bool isTransaction = !trans.null(); + bool isTransaction = !trans; if (!isTransaction) trans = CharacterDatabase.BeginTransaction(); diff --git a/src/server/game/Entities/Player/SocialMgr.h b/src/server/game/Entities/Player/SocialMgr.h index 910c9164738..68c25fbf648 100644 --- a/src/server/game/Entities/Player/SocialMgr.h +++ b/src/server/game/Entities/Player/SocialMgr.h @@ -19,7 +19,6 @@ #ifndef __TRINITY_SOCIALMGR_H #define __TRINITY_SOCIALMGR_H -#include #include "DatabaseEnv.h" #include "Common.h" @@ -123,13 +122,17 @@ class PlayerSocial class SocialMgr { - friend class ACE_Singleton; - private: SocialMgr(); ~SocialMgr(); public: + static SocialMgr* instance() + { + static SocialMgr* instance = new SocialMgr(); + return instance; + } + // Misc void RemovePlayerSocial(uint32 guid) { m_socialMap.erase(guid); } @@ -144,5 +147,5 @@ class SocialMgr SocialMap m_socialMap; }; -#define sSocialMgr ACE_Singleton::instance() +#define sSocialMgr SocialMgr::instance() #endif diff --git a/src/server/game/Events/GameEventMgr.h b/src/server/game/Events/GameEventMgr.h index df062c6f660..94beb9912d5 100644 --- a/src/server/game/Events/GameEventMgr.h +++ b/src/server/game/Events/GameEventMgr.h @@ -22,7 +22,6 @@ #include "Common.h" #include "SharedDefines.h" #include "Define.h" -#include #define max_ge_check_delay DAY // 1 day in seconds @@ -95,13 +94,17 @@ class Quest; class GameEventMgr { - friend class ACE_Singleton; - private: GameEventMgr(); ~GameEventMgr() { }; public: + static GameEventMgr* instance() + { + static GameEventMgr* instance = new GameEventMgr(); + return instance; + } + typedef std::set ActiveEvents; typedef std::vector GameEventDataMap; ActiveEvents const& GetActiveEventList() const { return m_ActiveEvents; } @@ -180,7 +183,7 @@ class GameEventMgr GameEventGuidMap mGameEventGameobjectGuids; }; -#define sGameEventMgr ACE_Singleton::instance() +#define sGameEventMgr GameEventMgr::instance() bool IsHolidayActive(HolidayIds id); bool IsEventActive(uint16 event_id); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index ba5940d7e12..20941901731 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -35,7 +35,6 @@ #include "Map.h" #include "ObjectAccessor.h" #include "ObjectDefines.h" -#include #include "VehicleDefines.h" #include #include @@ -687,13 +686,18 @@ class PlayerDumpReader; class ObjectMgr { friend class PlayerDumpReader; - friend class ACE_Singleton; private: ObjectMgr(); ~ObjectMgr(); public: + static ObjectMgr* instance() + { + static ObjectMgr* instance = new ObjectMgr(); + return instance; + } + typedef std::unordered_map ItemMap; typedef std::unordered_map QuestMap; @@ -1442,6 +1446,6 @@ class ObjectMgr std::set _transportMaps; // Helper container storing map ids that are for transports only, loaded from gameobject_template }; -#define sObjectMgr ACE_Singleton::instance() +#define sObjectMgr ObjectMgr::instance() #endif diff --git a/src/server/game/Groups/GroupMgr.h b/src/server/game/Groups/GroupMgr.h index a805b7514da..4bf440c881e 100644 --- a/src/server/game/Groups/GroupMgr.h +++ b/src/server/game/Groups/GroupMgr.h @@ -22,12 +22,17 @@ class GroupMgr { - friend class ACE_Singleton; private: GroupMgr(); ~GroupMgr(); public: + static GroupMgr* instance() + { + static GroupMgr* instance = new GroupMgr(); + return instance; + } + typedef std::map GroupContainer; typedef std::vector GroupDbContainer; @@ -53,6 +58,6 @@ protected: GroupDbContainer GroupDbStore; }; -#define sGroupMgr ACE_Singleton::instance() +#define sGroupMgr GroupMgr::instance() #endif diff --git a/src/server/game/Guilds/GuildMgr.h b/src/server/game/Guilds/GuildMgr.h index e8e6acb1bf0..032a8864e3e 100644 --- a/src/server/game/Guilds/GuildMgr.h +++ b/src/server/game/Guilds/GuildMgr.h @@ -22,13 +22,17 @@ class GuildMgr { - friend class ACE_Singleton; - private: GuildMgr(); ~GuildMgr(); public: + static GuildMgr* instance() + { + static GuildMgr* instance = new GuildMgr(); + return instance; + } + Guild* GetGuildByLeader(uint64 guid) const; Guild* GetGuildById(uint32 guildId) const; Guild* GetGuildByName(std::string const& guildName) const; @@ -48,6 +52,6 @@ protected: GuildContainer GuildStore; }; -#define sGuildMgr ACE_Singleton::instance() +#define sGuildMgr GuildMgr::instance() #endif diff --git a/src/server/game/Handlers/AddonHandler.cpp b/src/server/game/Handlers/AddonHandler.cpp index 806cbd1c7fc..8a00ddc22f4 100644 --- a/src/server/game/Handlers/AddonHandler.cpp +++ b/src/server/game/Handlers/AddonHandler.cpp @@ -22,10 +22,6 @@ #include "Opcodes.h" #include "Log.h" -AddonHandler::AddonHandler() { } - -AddonHandler::~AddonHandler() { } - bool AddonHandler::BuildAddonPacket(WorldPacket* source, WorldPacket* target) { ByteBuffer AddOnPacked; diff --git a/src/server/game/Handlers/AddonHandler.h b/src/server/game/Handlers/AddonHandler.h index 97a541753d0..31bbfa01900 100644 --- a/src/server/game/Handlers/AddonHandler.h +++ b/src/server/game/Handlers/AddonHandler.h @@ -21,20 +21,23 @@ #include "Common.h" #include "Config.h" -#include #include "WorldPacket.h" class AddonHandler { - /* Construction */ - friend class ACE_Singleton; - AddonHandler(); - public: - ~AddonHandler(); - //build addon packet + static AddonHandler* instance() + { + static AddonHandler* instance = new AddonHandler(); + return instance; + } + bool BuildAddonPacket(WorldPacket* Source, WorldPacket* Target); + + private: + AddonHandler() { } + ~AddonHandler() { } }; -#define sAddOnHandler ACE_Singleton::instance() +#define sAddOnHandler AddonHandler::instance() #endif diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h index 91becb88dfe..990d5e80c1a 100644 --- a/src/server/game/Maps/MapManager.h +++ b/src/server/game/Maps/MapManager.h @@ -24,18 +24,18 @@ #include "GridStates.h" #include "MapUpdater.h" -#include -#include - - class Transport; struct TransportCreatureProto; class MapManager { - friend class ACE_Singleton; - public: + static MapManager* instance() + { + static MapManager* instance = new MapManager(); + return instance; + } + Map* CreateBaseMap(uint32 mapId); Map* FindBaseNonInstanceMap(uint32 mapId) const; Map* CreateMap(uint32 mapId, Player* player); @@ -150,5 +150,5 @@ class MapManager uint32 _nextInstanceId; MapUpdater m_updater; }; -#define sMapMgr ACE_Singleton::instance() +#define sMapMgr MapManager::instance() #endif diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h index 5da856b185c..6ebc6316710 100644 --- a/src/server/game/Maps/TransportMgr.h +++ b/src/server/game/Maps/TransportMgr.h @@ -18,7 +18,6 @@ #ifndef TRANSPORTMGR_H #define TRANSPORTMGR_H -#include #include #include "Spline.h" #include "DBCStores.h" @@ -96,10 +95,15 @@ typedef std::map TransportAnimationContainer; class TransportMgr { - friend class ACE_Singleton; friend void LoadDBCStores(std::string const&); public: + static TransportMgr* instance() + { + static TransportMgr* instance = new TransportMgr(); + return instance; + } + void Unload(); void LoadTransportTemplates(); @@ -155,6 +159,6 @@ class TransportMgr TransportAnimationContainer _transportAnimations; }; -#define sTransportMgr ACE_Singleton::instance() +#define sTransportMgr TransportMgr::instance() #endif // TRANSPORTMGR_H diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h index 5c74bef8d8c..12116b5505d 100755 --- a/src/server/game/Movement/MovementGenerator.h +++ b/src/server/game/Movement/MovementGenerator.h @@ -20,7 +20,6 @@ #define TRINITY_MOVEMENTGENERATOR_H #include "Define.h" -#include #include "ObjectRegistry.h" #include "FactoryHolder.h" #include "Common.h" diff --git a/src/server/game/Movement/Waypoints/WaypointManager.h b/src/server/game/Movement/Waypoints/WaypointManager.h index bafc6322e71..b12396293aa 100644 --- a/src/server/game/Movement/Waypoints/WaypointManager.h +++ b/src/server/game/Movement/Waypoints/WaypointManager.h @@ -19,8 +19,6 @@ #ifndef TRINITY_WAYPOINTMANAGER_H #define TRINITY_WAYPOINTMANAGER_H -#include -#include #include struct WaypointData @@ -38,9 +36,13 @@ typedef std::unordered_map WaypointPathContainer; class WaypointMgr { - friend class ACE_Singleton; - public: + static WaypointMgr* instance() + { + static WaypointMgr* instance = new WaypointMgr(); + return instance; + } + // Attempts to reload a single path from database void ReloadPath(uint32 id); @@ -58,13 +60,12 @@ class WaypointMgr } private: - // Only allow instantiation from ACE_Singleton WaypointMgr(); ~WaypointMgr(); WaypointPathContainer _waypointStore; }; -#define sWaypointMgr ACE_Singleton::instance() +#define sWaypointMgr WaypointMgr::instance() #endif diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h index 54ea2f3ba1d..ab1908e273d 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h +++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h @@ -21,7 +21,6 @@ #define OUTDOORPVP_OBJECTIVE_UPDATE_INTERVAL 1000 #include "OutdoorPvP.h" -#include class Player; class GameObject; @@ -38,13 +37,17 @@ struct OutdoorPvPData // class to handle player enter / leave / areatrigger / GO use events class OutdoorPvPMgr { - friend class ACE_Singleton; - private: OutdoorPvPMgr(); ~OutdoorPvPMgr() { }; public: + static OutdoorPvPMgr* instance() + { + static OutdoorPvPMgr* instance = new OutdoorPvPMgr(); + return instance; + } + // create outdoor pvp events void InitOutdoorPvP(); @@ -101,6 +104,6 @@ class OutdoorPvPMgr uint32 m_UpdateTimer; }; -#define sOutdoorPvPMgr ACE_Singleton::instance() +#define sOutdoorPvPMgr OutdoorPvPMgr::instance() #endif /*OUTDOOR_PVP_MGR_H_*/ diff --git a/src/server/game/Pools/PoolMgr.h b/src/server/game/Pools/PoolMgr.h index 2bc404b3a36..0a3f52b55f6 100644 --- a/src/server/game/Pools/PoolMgr.h +++ b/src/server/game/Pools/PoolMgr.h @@ -20,7 +20,6 @@ #define TRINITY_POOLHANDLER_H #include "Define.h" -#include #include "Creature.h" #include "GameObject.h" #include "QuestDef.h" @@ -104,13 +103,17 @@ typedef std::pair class PoolMgr { - friend class ACE_Singleton; - private: PoolMgr(); ~PoolMgr() { }; public: + static PoolMgr* instance() + { + static PoolMgr* instance = new PoolMgr(); + return instance; + } + void LoadFromDB(); void LoadQuestPools(); void SaveQuestsToDB(); @@ -164,7 +167,7 @@ class PoolMgr ActivePoolData mSpawnedData; }; -#define sPoolMgr ACE_Singleton::instance() +#define sPoolMgr PoolMgr::instance() // Method that tell if the creature is part of a pool and return the pool id if yes template<> diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index ee95759c72e..4f6027bedec 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -20,7 +20,6 @@ #define SC_SCRIPTMGR_H #include "Common.h" -#include #include #include "DBCStores.h" @@ -869,20 +868,23 @@ class GroupScript : public ScriptObject }; // Placed here due to ScriptRegistry::AddScript dependency. -#define sScriptMgr ACE_Singleton::instance() +#define sScriptMgr ScriptMgr::instance() // Manages registration, loading, and execution of scripts. class ScriptMgr { - friend class ACE_Singleton; friend class ScriptObject; private: - ScriptMgr(); virtual ~ScriptMgr(); public: /* Initialization */ + static ScriptMgr* instance() + { + static ScriptMgr* instance = new ScriptMgr(); + return instance; + } void Initialize(); void LoadDatabase(); diff --git a/src/server/game/Scripting/ScriptSystem.h b/src/server/game/Scripting/ScriptSystem.h index 11120f3031b..636343838c1 100644 --- a/src/server/game/Scripting/ScriptSystem.h +++ b/src/server/game/Scripting/ScriptSystem.h @@ -6,7 +6,6 @@ #define SC_SYSTEM_H #include "ScriptMgr.h" -#include #define TEXT_SOURCE_RANGE -1000000 //the amount of entries each text source has available @@ -48,11 +47,17 @@ typedef std::vector ScriptPointVector; class SystemMgr { - friend class ACE_Singleton; + private: SystemMgr() { } ~SystemMgr() { } public: + static SystemMgr* instance() + { + static SystemMgr* instance = new SystemMgr(); + return instance; + } + typedef std::unordered_map PointMoveMap; //Database @@ -75,6 +80,6 @@ class SystemMgr static ScriptPointVector const _empty; }; -#define sScriptSystemMgr ACE_Singleton::instance() +#define sScriptSystemMgr SystemMgr::instance() #endif diff --git a/src/server/game/Server/Protocol/PacketLog.h b/src/server/game/Server/Protocol/PacketLog.h index 9c60655e627..71d87bf45ae 100644 --- a/src/server/game/Server/Protocol/PacketLog.h +++ b/src/server/game/Server/Protocol/PacketLog.h @@ -19,7 +19,6 @@ #define TRINITY_PACKETLOG_H #include "Common.h" -#include enum Direction { @@ -31,13 +30,17 @@ class WorldPacket; class PacketLog { - friend class ACE_Singleton; - private: PacketLog(); ~PacketLog(); public: + static PacketLog* instance() + { + static PacketLog* instance = new PacketLog(); + return instance; + } + void Initialize(); bool CanLogPacket() const { return (_file != NULL); } void LogPacket(WorldPacket const& packet, Direction direction); @@ -46,5 +49,5 @@ class PacketLog FILE* _file; }; -#define sPacketLog ACE_Singleton::instance() +#define sPacketLog PacketLog::instance() #endif diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 0c391993c0b..7fbc398a4da 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -780,7 +780,7 @@ void WorldSession::SaveTutorialsData(SQLTransaction &trans) PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_HAS_TUTORIALS); stmt->setUInt32(0, GetAccountId()); - bool hasTutorials = !CharacterDatabase.Query(stmt).null(); + bool hasTutorials = !CharacterDatabase.Query(stmt); // Modify data in DB stmt = CharacterDatabase.GetPreparedStatement(hasTutorials ? CHAR_UPD_TUTORIALS : CHAR_INS_TUTORIALS); for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i) diff --git a/src/server/game/Server/WorldSocketMgr.h b/src/server/game/Server/WorldSocketMgr.h index fb8ddb42b9e..2c91a164ff9 100644 --- a/src/server/game/Server/WorldSocketMgr.h +++ b/src/server/game/Server/WorldSocketMgr.h @@ -26,7 +26,6 @@ #define __WORLDSOCKETMGR_H #include -#include #include class WorldSocket; @@ -36,9 +35,14 @@ class ACE_Event_Handler; /// Manages all sockets connected to peers and network threads class WorldSocketMgr { -public: friend class WorldSocket; - friend class ACE_Singleton; + +public: + static WorldSocketMgr* instance() + { + static WorldSocketMgr* instance = new WorldSocketMgr(); + return instance; + } /// Start network, listen at address:port . int StartNetwork(ACE_UINT16 port, const char* address); @@ -68,7 +72,7 @@ private: class WorldSocketAcceptor* m_Acceptor; }; -#define sWorldSocketMgr ACE_Singleton::instance() +#define sWorldSocketMgr WorldSocketMgr::instance() #endif /// @} diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 757bd813613..53b4cef73e8 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -21,8 +21,6 @@ // For static or at-server-startup loaded spell data -#include - #include "Define.h" #include "DBCStructure.h" #include "SharedDefines.h" @@ -603,7 +601,6 @@ bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group); class SpellMgr { - friend class ACE_Singleton; // Constructors private: SpellMgr(); @@ -611,6 +608,13 @@ class SpellMgr // Accessors (const or static functions) public: + static SpellMgr* instance() + { + static SpellMgr* instance = new SpellMgr(); + + return instance; + } + // Spell correctness for client using static bool IsSpellValid(SpellInfo const* spellInfo, Player* player = NULL, bool msg = true); @@ -766,6 +770,6 @@ class SpellMgr SpellInfoMap mSpellInfoMap; }; -#define sSpellMgr ACE_Singleton::instance() +#define sSpellMgr SpellMgr::instance() #endif diff --git a/src/server/game/Texts/CreatureTextMgr.h b/src/server/game/Texts/CreatureTextMgr.h index ab5b9f59032..f8c499f7ce6 100644 --- a/src/server/game/Texts/CreatureTextMgr.h +++ b/src/server/game/Texts/CreatureTextMgr.h @@ -82,11 +82,17 @@ typedef std::unordered_map CreatureTextRepeatMa class CreatureTextMgr { - friend class ACE_Singleton; - CreatureTextMgr() { }; + private: + CreatureTextMgr() { }; + ~CreatureTextMgr() { }; public: - ~CreatureTextMgr() { }; + static CreatureTextMgr* instance() + { + static CreatureTextMgr* instance = new CreatureTextMgr(); + return instance; + } + void LoadCreatureTexts(); void LoadCreatureTextLocales(); CreatureTextMap const& GetTextMap() const { return mTextMap; } @@ -113,7 +119,7 @@ class CreatureTextMgr LocaleCreatureTextMap mLocaleTextMap; }; -#define sCreatureTextMgr ACE_Singleton::instance() +#define sCreatureTextMgr CreatureTextMgr::instance() template class CreatureTextLocalizer diff --git a/src/server/game/Tickets/TicketMgr.h b/src/server/game/Tickets/TicketMgr.h index 5bfe78abbba..5f85ee307ed 100644 --- a/src/server/game/Tickets/TicketMgr.h +++ b/src/server/game/Tickets/TicketMgr.h @@ -19,7 +19,6 @@ #define _TICKETMGR_H #include -#include #include "ObjectMgr.h" @@ -174,13 +173,17 @@ typedef std::map GmTicketList; class TicketMgr { - friend class ACE_Singleton; - private: TicketMgr(); ~TicketMgr(); public: + static TicketMgr* instance() + { + static TicketMgr* instance = new TicketMgr(); + return instance; + } + void LoadTickets(); void LoadSurveys(); @@ -246,6 +249,6 @@ protected: uint64 _lastChange; }; -#define sTicketMgr ACE_Singleton::instance() +#define sTicketMgr TicketMgr::instance() #endif // _TICKETMGR_H diff --git a/src/server/game/Warden/WardenCheckMgr.h b/src/server/game/Warden/WardenCheckMgr.h index 8f2fa37400d..1108c9a6521 100644 --- a/src/server/game/Warden/WardenCheckMgr.h +++ b/src/server/game/Warden/WardenCheckMgr.h @@ -48,11 +48,17 @@ struct WardenCheckResult class WardenCheckMgr { - friend class ACE_Singleton; - WardenCheckMgr(); - ~WardenCheckMgr(); + private: + WardenCheckMgr(); + ~WardenCheckMgr(); public: + static WardenCheckMgr* instance() + { + static WardenCheckMgr* instance = new WardenCheckMgr(); + return instance; + } + // We have a linear key without any gaps, so we use vector for fast access typedef std::vector CheckContainer; typedef std::map CheckResultContainer; @@ -73,6 +79,6 @@ class WardenCheckMgr CheckResultContainer CheckResultStore; }; -#define sWardenCheckMgr ACE_Singleton::instance() +#define sWardenCheckMgr WardenCheckMgr::instance() #endif diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp index 5cf5cde75fd..5274dcd358d 100644 --- a/src/server/game/Weather/WeatherMgr.cpp +++ b/src/server/game/Weather/WeatherMgr.cpp @@ -34,7 +34,7 @@ namespace WeatherMgr namespace { - typedef std::unordered_map > WeatherMap; + typedef std::unordered_map > WeatherMap; typedef std::unordered_map WeatherZoneMap; WeatherMap m_weathers; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 234a366b08e..4a46412dff7 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -668,7 +668,7 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP] = sConfigMgr->GetBoolDefault("AllowTwoSide.Interaction.Group", false); m_bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD] = sConfigMgr->GetBoolDefault("AllowTwoSide.Interaction.Guild", false); m_bool_configs[CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION] = sConfigMgr->GetBoolDefault("AllowTwoSide.Interaction.Auction", false); - m_bool_configs[CONFIG_ALLOW_TWO_SIDE_TRADE] = sConfigMgr->GetBoolDefault("AllowTwoSide.trade", false); + m_bool_configs[CONFIG_ALLOW_TWO_SIDE_TRADE] = sConfigMgr->GetBoolDefault("AllowTwoSide.Trade", false); m_int_configs[CONFIG_STRICT_PLAYER_NAMES] = sConfigMgr->GetIntDefault ("StrictPlayerNames", 0); m_int_configs[CONFIG_STRICT_CHARTER_NAMES] = sConfigMgr->GetIntDefault ("StrictCharterNames", 0); m_int_configs[CONFIG_STRICT_PET_NAMES] = sConfigMgr->GetIntDefault ("StrictPetNames", 0); @@ -1255,8 +1255,6 @@ void World::LoadConfigSettings(bool reload) m_bool_configs[CONFIG_IP_BASED_ACTION_LOGGING] = sConfigMgr->GetBoolDefault("Allow.IP.Based.Action.Logging", false); - m_bool_configs[CONFIG_IP_BASED_LOGIN_LOGGING] = sConfigMgr->GetBoolDefault("Wrong.Password.Login.Logging", false); - // call ScriptMgr if we're reloading the configuration if (reload) sScriptMgr->OnConfigLoad(reload); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 4096dd7399a..f9528c793f7 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -25,9 +25,7 @@ #include "Common.h" #include "Timer.h" -#include #include -#include #include "SharedDefines.h" #include "QueryResult.h" #include "Callback.h" @@ -156,7 +154,6 @@ enum WorldBoolConfigs CONFIG_STATS_LIMITS_ENABLE, CONFIG_INSTANCES_RESET_ANNOUNCE, CONFIG_IP_BASED_ACTION_LOGGING, - CONFIG_IP_BASED_LOGIN_LOGGING, BOOL_CONFIG_VALUE_COUNT }; @@ -520,10 +517,13 @@ struct CharacterNameData class World { public: - static ACE_Atomic_Op m_worldLoopCounter; + static World* instance() + { + static World* instance = new World(); + return instance; + } - World(); - ~World(); + static ACE_Atomic_Op m_worldLoopCounter; WorldSession* FindSession(uint32 id) const; void AddSession(WorldSession* s); @@ -758,6 +758,9 @@ class World void ResetRandomBG(); void ResetGuildCap(); private: + World(); + ~World(); + static ACE_Atomic_Op m_stopEvent; static uint8 m_ExitCode; uint32 m_ShutdownTimer; @@ -845,6 +848,6 @@ class World extern uint32 realmID; -#define sWorld ACE_Singleton::instance() +#define sWorld World::instance() #endif /// @} diff --git a/src/server/shared/Cryptography/ARC4.h b/src/server/shared/Cryptography/ARC4.h index 5304b0730a6..11d3d4ba87b 100644 --- a/src/server/shared/Cryptography/ARC4.h +++ b/src/server/shared/Cryptography/ARC4.h @@ -19,8 +19,8 @@ #ifndef _AUTH_SARC4_H #define _AUTH_SARC4_H -#include "Define.h" #include +#include "Define.h" class ARC4 { diff --git a/src/server/shared/Cryptography/BigNumber.h b/src/server/shared/Cryptography/BigNumber.h index 848b3da3e2d..684a25e8801 100644 --- a/src/server/shared/Cryptography/BigNumber.h +++ b/src/server/shared/Cryptography/BigNumber.h @@ -22,7 +22,6 @@ #include #include "Define.h" - struct bignum_st; class BigNumber diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index e56dcc329cd..4b9e887f341 100644 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -18,8 +18,6 @@ #ifndef _DATABASEWORKERPOOL_H #define _DATABASEWORKERPOOL_H -#include - #include "Common.h" #include "Callback.h" #include "MySQLConnection.h" @@ -51,7 +49,6 @@ class DatabaseWorkerPool /* Activity state */ DatabaseWorkerPool() : _connectionInfo(NULL) { - _messageQueue = new ACE_Message_Queue(8 * 1024 * 1024, 8 * 1024 * 1024); _queue = new ProducerConsumerQueue(); memset(_connectionCount, 0, sizeof(_connectionCount)); _connections.resize(IDX_SIZE); @@ -125,9 +122,7 @@ class DatabaseWorkerPool for (uint8 i = 0; i < _connectionCount[IDX_SYNCH]; ++i) _connections[IDX_SYNCH][i]->Close(); - //! Deletes the ACE_Activation_Queue object and its underlying ACE_Message_Queue delete _queue; - delete _messageQueue; TC_LOG_INFO("sql.driver", "All connections on DatabasePool '%s' closed.", GetDatabaseName()); @@ -410,7 +405,7 @@ class DatabaseWorkerPool //! Will be wrapped in a transaction if valid object is present, otherwise executed standalone. void ExecuteOrAppend(SQLTransaction& trans, PreparedStatement* stmt) { - if (trans.null()) + if (!trans) Execute(stmt); else trans->Append(stmt); @@ -420,7 +415,7 @@ class DatabaseWorkerPool //! Will be wrapped in a transaction if valid object is present, otherwise executed standalone. void ExecuteOrAppend(SQLTransaction& trans, const char* sql) { - if (trans.null()) + if (!trans) Execute(sql); else trans->Append(sql); @@ -517,7 +512,6 @@ class DatabaseWorkerPool IDX_SIZE }; - ACE_Message_Queue* _messageQueue; //! Message Queue used by ACE_Activation_Queue ProducerConsumerQueue* _queue; //! Queue shared by async worker threads. std::vector< std::vector > _connections; uint32 _connectionCount[2]; //! Counter of MySQL connections; diff --git a/src/server/shared/Database/MySQLConnection.h b/src/server/shared/Database/MySQLConnection.h index 3b7efeb5846..61b3b37cbc2 100644 --- a/src/server/shared/Database/MySQLConnection.h +++ b/src/server/shared/Database/MySQLConnection.h @@ -15,8 +15,6 @@ * with this program. If not, see . */ -#include - #include "DatabaseWorkerPool.h" #include "Transaction.h" #include "Util.h" @@ -100,13 +98,13 @@ class MySQLConnection { /// Tries to acquire lock. If lock is acquired by another thread /// the calling parent will just try another connection - return m_Mutex.tryacquire() != -1; + return m_Mutex.try_lock(); } void Unlock() { /// Called by parent databasepool. Will let other threads access this connection - m_Mutex.release(); + m_Mutex.unlock(); } MYSQL* GetHandle() { return m_Mysql; } @@ -131,7 +129,7 @@ class MySQLConnection MYSQL * m_Mysql; //! MySQL Handle. MySQLConnectionInfo& m_connectionInfo; //! Connection info (used for logging) ConnectionFlags m_connectionFlags; //! Connection flags (for preparing relevant statements) - ACE_Thread_Mutex m_Mutex; + std::mutex m_Mutex; MySQLConnection(MySQLConnection const& right) = delete; MySQLConnection& operator=(MySQLConnection const& right) = delete; diff --git a/src/server/shared/Database/QueryResult.h b/src/server/shared/Database/QueryResult.h index 4795fef4a4c..e8c277c03cf 100644 --- a/src/server/shared/Database/QueryResult.h +++ b/src/server/shared/Database/QueryResult.h @@ -19,9 +19,7 @@ #ifndef QUERYRESULT_H #define QUERYRESULT_H -#include "AutoPtr.h" -#include - +#include #include "Field.h" #ifdef _WIN32 @@ -60,7 +58,7 @@ class ResultSet ResultSet& operator=(ResultSet const& right) = delete; }; -typedef Trinity::AutoPtr QueryResult; +typedef std::shared_ptr QueryResult; class PreparedResultSet { @@ -107,7 +105,7 @@ class PreparedResultSet PreparedResultSet& operator=(PreparedResultSet const& right) = delete; }; -typedef Trinity::AutoPtr PreparedQueryResult; +typedef std::shared_ptr PreparedQueryResult; #endif diff --git a/src/server/shared/Database/Transaction.h b/src/server/shared/Database/Transaction.h index cb28f0ad876..c7cbbbbe712 100644 --- a/src/server/shared/Database/Transaction.h +++ b/src/server/shared/Database/Transaction.h @@ -50,7 +50,7 @@ class Transaction bool _cleanedUp; }; -typedef Trinity::AutoPtr SQLTransaction; +typedef std::shared_ptr SQLTransaction; /*! Low level class*/ class TransactionTask : public SQLOperation diff --git a/src/server/shared/Debugging/Errors.cpp b/src/server/shared/Debugging/Errors.cpp index d656dc3fb4a..62e97d56d42 100644 --- a/src/server/shared/Debugging/Errors.cpp +++ b/src/server/shared/Debugging/Errors.cpp @@ -18,17 +18,15 @@ #include "Errors.h" -#include -#include #include +#include namespace Trinity { void Assert(char const* file, int line, char const* function, char const* message) { - ACE_Stack_Trace st; - fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n", - file, line, function, message, st.c_str()); + fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n", + file, line, function, message); *((volatile int*)NULL) = 0; exit(1); } @@ -37,7 +35,8 @@ void Fatal(char const* file, int line, char const* function, char const* message { fprintf(stderr, "\n%s:%i in %s FATAL ERROR:\n %s\n", file, line, function, message); - ACE_OS::sleep(10); + + std::this_thread::sleep_for(std::chrono::seconds(10)); *((volatile int*)NULL) = 0; exit(1); } diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h index 84d0dc14eca..67213d0ddd0 100644 --- a/src/server/shared/Logging/Appender.h +++ b/src/server/shared/Logging/Appender.h @@ -18,10 +18,10 @@ #ifndef APPENDER_H #define APPENDER_H -#include "Define.h" -#include #include #include +#include +#include "Define.h" // Values assigned have their equivalent in enum ACE_Log_Priority enum LogLevel diff --git a/src/server/shared/Logging/AppenderConsole.h b/src/server/shared/Logging/AppenderConsole.h index 1aaa74e96ec..b8f15b4fa0f 100644 --- a/src/server/shared/Logging/AppenderConsole.h +++ b/src/server/shared/Logging/AppenderConsole.h @@ -18,8 +18,8 @@ #ifndef APPENDERCONSOLE_H #define APPENDERCONSOLE_H -#include "Appender.h" #include +#include "Appender.h" enum ColorTypes { diff --git a/src/server/shared/Logging/AppenderFile.h b/src/server/shared/Logging/AppenderFile.h index 592742c2184..a600c92d152 100644 --- a/src/server/shared/Logging/AppenderFile.h +++ b/src/server/shared/Logging/AppenderFile.h @@ -18,8 +18,8 @@ #ifndef APPENDERFILE_H #define APPENDERFILE_H -#include "Appender.h" #include +#include "Appender.h" class AppenderFile: public Appender { diff --git a/src/server/shared/Threading/Callback.h b/src/server/shared/Threading/Callback.h index a6aa11b3958..5d9dc9a760d 100644 --- a/src/server/shared/Threading/Callback.h +++ b/src/server/shared/Threading/Callback.h @@ -26,10 +26,6 @@ typedef std::promise QueryResultPromise; typedef std::future PreparedQueryResultFuture; typedef std::promise PreparedQueryResultPromise; -/*! A simple template using ACE_Future to manage callbacks from the thread and object that - issued the request. is variable type of parameter that is used as parameter - for the callback function. -*/ #define CALLBACK_STAGE_INVALID uint8(-1) template @@ -210,4 +206,4 @@ class QueryCallback_2 QueryCallback_2& operator=(QueryCallback_2 const& right) = delete; }; -#endif \ No newline at end of file +#endif diff --git a/src/server/shared/Threading/DelayExecutor.cpp b/src/server/shared/Threading/DelayExecutor.cpp index 0db45a8ff8f..ef3c028fd97 100644 --- a/src/server/shared/Threading/DelayExecutor.cpp +++ b/src/server/shared/Threading/DelayExecutor.cpp @@ -1,4 +1,20 @@ -#include +/* +* Copyright (C) 2008-2014 TrinityCore +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along +* with this program. If not, see . +*/ + #include #include diff --git a/src/server/shared/Threading/DelayExecutor.h b/src/server/shared/Threading/DelayExecutor.h index 5eaaacdb98b..2a3721263fc 100644 --- a/src/server/shared/Threading/DelayExecutor.h +++ b/src/server/shared/Threading/DelayExecutor.h @@ -8,7 +8,6 @@ class DelayExecutor : protected ACE_Task_Base { public: - DelayExecutor(); virtual ~DelayExecutor(); @@ -25,7 +24,6 @@ class DelayExecutor : protected ACE_Task_Base virtual int svc(); private: - ACE_Activation_Queue queue_; ACE_Method_Request* pre_svc_hook_; ACE_Method_Request* post_svc_hook_; diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index 2a8fcdd431a..41060e37b38 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -22,8 +22,6 @@ #include -#include - #include "Common.h" #include "SystemConfig.h" #include "SignalHandler.h" @@ -46,6 +44,7 @@ #include "BigNumber.h" #include "OpenSSLCrypto.h" +#include #ifdef _WIN32 #include "ServiceWin32.h" @@ -58,27 +57,22 @@ extern int m_ServiceStatus; #define PROCESS_HIGH_PRIORITY -15 // [-20, 19], default is 0 #endif -/// Handle worldservers's termination signals -class WorldServerSignalHandler : public Trinity::SignalHandler +boost::asio::io_service _ioService; + +void SignalHandler(const boost::system::error_code& error, int signalNumber) { - public: - virtual void HandleSignal(int sigNum) + if (!error) + { + switch (signalNumber) { - switch (sigNum) - { - case SIGINT: - World::StopNow(RESTART_EXIT_CODE); - break; - case SIGTERM: -#ifdef _WIN32 - case SIGBREAK: - if (m_ServiceStatus != 1) -#endif - World::StopNow(SHUTDOWN_EXIT_CODE); - break; - } + case SIGINT: + case SIGTERM: + _ioService.stop(); + break; } -}; + } +} + void FreezeDetectorThread(uint32 delayTime) { @@ -153,23 +147,12 @@ int Master::Run() ///- Initialize the World sWorld->SetInitialWorldSettings(); - ///- Initialize the signal handlers - WorldServerSignalHandler signalINT, signalTERM; - #ifdef _WIN32 - WorldServerSignalHandler signalBREAK; - #endif /* _WIN32 */ - - ///- Register worldserver's signal handlers - ACE_Sig_Handler handle; - handle.register_handler(SIGINT, &signalINT); - handle.register_handler(SIGTERM, &signalTERM); -#ifdef _WIN32 - handle.register_handler(SIGBREAK, &signalBREAK); -#endif + // Set signal handlers + boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM); + signals.async_wait(SignalHandler); ///- Launch WorldRunnable thread - - std::thread worldThread(WorldThread); + std::thread worldThread(WorldThread, std::ref(_ioService)); std::thread* cliThread = nullptr; @@ -286,6 +269,8 @@ int Master::Run() TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon) ready...", _FULLVERSION); + _ioService.run(); + // when the main thread closes the singletons get unloaded // since worldrunnable uses them, it will crash if unloaded after master worldThread.join(); diff --git a/src/server/worldserver/Master.h b/src/server/worldserver/Master.h index 9ee94a44acb..d2a51b85f4b 100644 --- a/src/server/worldserver/Master.h +++ b/src/server/worldserver/Master.h @@ -29,6 +29,12 @@ class Master { public: + static Master* instance() + { + static Master* instance = new Master(); + return instance; + } + int Run(); private: @@ -38,7 +44,7 @@ class Master void ClearOnlineAccounts(); }; -#define sMaster ACE_Singleton::instance() +#define sMaster Master::instance() #endif diff --git a/src/server/worldserver/WorldThread/WorldRunnable.cpp b/src/server/worldserver/WorldThread/WorldRunnable.cpp index 7722492b5a8..85c3e7a74b9 100644 --- a/src/server/worldserver/WorldThread/WorldRunnable.cpp +++ b/src/server/worldserver/WorldThread/WorldRunnable.cpp @@ -42,7 +42,7 @@ extern int m_ServiceStatus; #endif /// Heartbeat for the World -void WorldThread() +void WorldThread(boost::asio::io_service& ioService) { uint32 realCurrTime = 0; uint32 realPrevTime = getMSTime(); @@ -84,6 +84,8 @@ void WorldThread() #endif } + ioService.stop(); + sScriptMgr->OnShutdown(); sWorld->KickAll(); // save and kick all players diff --git a/src/server/worldserver/WorldThread/WorldRunnable.h b/src/server/worldserver/WorldThread/WorldRunnable.h index 915bd5b580a..3e2c07b8842 100644 --- a/src/server/worldserver/WorldThread/WorldRunnable.h +++ b/src/server/worldserver/WorldThread/WorldRunnable.h @@ -23,7 +23,9 @@ #ifndef __WORLDRUNNABLE_H #define __WORLDRUNNABLE_H -void WorldThread(); +#include + +void WorldThread(boost::asio::io_service& ioService); #endif -- cgit v1.2.3 From 25e633aa34ef227841b4092270d862b0864dc372 Mon Sep 17 00:00:00 2001 From: leak Date: Wed, 2 Jul 2014 00:41:30 +0200 Subject: Replaced ACE_Method_Request based DelayExecutor by PCQ impl Untested due to worldserver still breaking because of ACE threading fails --- src/server/game/Maps/MapManager.cpp | 4 +- src/server/game/Maps/MapUpdater.cpp | 71 ++++++++------- src/server/game/Maps/MapUpdater.h | 21 +++-- src/server/game/Weather/WeatherMgr.cpp | 1 - src/server/shared/AutoPtr.h | 53 ----------- src/server/shared/Threading/DelayExecutor.cpp | 126 -------------------------- src/server/shared/Threading/DelayExecutor.h | 35 ------- src/server/worldserver/Master.cpp | 1 - 8 files changed, 54 insertions(+), 258 deletions(-) delete mode 100644 src/server/shared/AutoPtr.h delete mode 100644 src/server/shared/Threading/DelayExecutor.cpp delete mode 100644 src/server/shared/Threading/DelayExecutor.h (limited to 'src/server/worldserver/Master.cpp') diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index 2b8dbde8280..1de13d137c4 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -52,8 +52,8 @@ void MapManager::Initialize() int num_threads(sWorld->getIntConfig(CONFIG_NUMTHREADS)); // Start mtmaps if needed. - if (num_threads > 0 && m_updater.activate(num_threads) == -1) - abort(); + if (num_threads > 0) + m_updater.activate(num_threads); } void MapManager::InitializeVisibilityDistanceInfo() diff --git a/src/server/game/Maps/MapUpdater.cpp b/src/server/game/Maps/MapUpdater.cpp index 2a6b810fcef..4ab95d87d48 100644 --- a/src/server/game/Maps/MapUpdater.cpp +++ b/src/server/game/Maps/MapUpdater.cpp @@ -18,57 +18,61 @@ #include #include -#include #include "MapUpdater.h" -#include "DelayExecutor.h" #include "Map.h" -#include "DatabaseEnv.h" -class MapUpdateRequest : public ACE_Method_Request +class MapUpdateRequest { private: Map& m_map; MapUpdater& m_updater; - ACE_UINT32 m_diff; + uint32 m_diff; public: - MapUpdateRequest(Map& m, MapUpdater& u, ACE_UINT32 d) + MapUpdateRequest(Map& m, MapUpdater& u, uint32 d) : m_map(m), m_updater(u), m_diff(d) { } - virtual int call() + void call() { m_map.Update (m_diff); m_updater.update_finished(); - return 0; } }; -MapUpdater::MapUpdater(): m_executor(), pending_requests(0) { } +MapUpdater::MapUpdater(): pending_requests(0) { } MapUpdater::~MapUpdater() { deactivate(); } -int MapUpdater::activate(size_t num_threads) +void MapUpdater::activate(size_t num_threads) { - return m_executor.start((int)num_threads); + for (size_t i = 0; i < num_threads; ++i) + { + _workerThreads.push_back(std::thread(&MapUpdater::WorkerThread, this)); + } } -int MapUpdater::deactivate() +void MapUpdater::deactivate() { wait(); - return m_executor.deactivate(); + _queue.Cancel(); + + for (auto& thread : _workerThreads) + { + thread.join(); + } } -int MapUpdater::wait() +void MapUpdater::wait() { std::unique_lock lock(_lock); @@ -76,43 +80,44 @@ int MapUpdater::wait() _condition.wait(lock); lock.unlock(); - - return 0; } -int MapUpdater::schedule_update(Map& map, ACE_UINT32 diff) +void MapUpdater::schedule_update(Map& map, uint32 diff) { std::lock_guard lock(_lock); ++pending_requests; - if (m_executor.execute(new MapUpdateRequest(map, *this, diff)) == -1) - { - ACE_DEBUG((LM_ERROR, ACE_TEXT("(%t) \n"), ACE_TEXT("Failed to schedule Map Update"))); - - --pending_requests; - return -1; - } - - return 0; + _queue.Push(new MapUpdateRequest(map, *this, diff)); } bool MapUpdater::activated() { - return m_executor.activated(); + return _workerThreads.size() > 0; } void MapUpdater::update_finished() { std::lock_guard lock(_lock); - if (pending_requests == 0) - { - ACE_ERROR((LM_ERROR, ACE_TEXT("(%t)\n"), ACE_TEXT("MapUpdater::update_finished BUG, report to devs"))); - return; - } - --pending_requests; _condition.notify_all(); } + +void MapUpdater::WorkerThread() +{ + while (1) + { + MapUpdateRequest* request = nullptr; + + _queue.WaitAndPop(request); + + if (_cancelationToken) + return; + + request->call(); + + delete request; + } +} diff --git a/src/server/game/Maps/MapUpdater.h b/src/server/game/Maps/MapUpdater.h index 8461b53e992..ff1d85a23e9 100644 --- a/src/server/game/Maps/MapUpdater.h +++ b/src/server/game/Maps/MapUpdater.h @@ -19,10 +19,11 @@ #ifndef _MAP_UPDATER_H_INCLUDED #define _MAP_UPDATER_H_INCLUDED +#include "Define.h" #include +#include #include - -#include "DelayExecutor.h" +#include "ProducerConsumerQueue.h" class Map; @@ -35,24 +36,30 @@ class MapUpdater friend class MapUpdateRequest; - int schedule_update(Map& map, ACE_UINT32 diff); + void schedule_update(Map& map, uint32 diff); - int wait(); + void wait(); - int activate(size_t num_threads); + void activate(size_t num_threads); - int deactivate(); + void deactivate(); bool activated(); private: - DelayExecutor m_executor; + ProducerConsumerQueue _queue; + + std::vector _workerThreads; + std::atomic_bool _cancelationToken; + std::mutex _lock; std::condition_variable _condition; size_t pending_requests; void update_finished(); + + void WorkerThread(); }; #endif //_MAP_UPDATER_H_INCLUDED diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp index 5274dcd358d..938c91b0228 100644 --- a/src/server/game/Weather/WeatherMgr.cpp +++ b/src/server/game/Weather/WeatherMgr.cpp @@ -24,7 +24,6 @@ #include "Weather.h" #include "Log.h" #include "ObjectMgr.h" -#include "AutoPtr.h" #include "Player.h" #include "WorldPacket.h" #include "WorldSession.h" diff --git a/src/server/shared/AutoPtr.h b/src/server/shared/AutoPtr.h deleted file mode 100644 index 96ecbfc79fe..00000000000 --- a/src/server/shared/AutoPtr.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#ifndef _TRINITY_AUTO_PTR_H -#define _TRINITY_AUTO_PTR_H - -#include - -namespace Trinity -{ - -template -class AutoPtr : public ACE_Strong_Bound_Ptr -{ - typedef ACE_Strong_Bound_Ptr Base; - -public: - AutoPtr() - : Base() - { } - - AutoPtr(Pointer* x) - : Base(x) - { } - - operator bool() const - { - return !Base::null(); - } - - bool operator !() const - { - return Base::null(); - } -}; - -} // namespace Trinity - -#endif diff --git a/src/server/shared/Threading/DelayExecutor.cpp b/src/server/shared/Threading/DelayExecutor.cpp deleted file mode 100644 index ef3c028fd97..00000000000 --- a/src/server/shared/Threading/DelayExecutor.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* -* Copyright (C) 2008-2014 TrinityCore -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the -* Free Software Foundation; either version 2 of the License, or (at your -* option) any later version. -* -* This program is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* You should have received a copy of the GNU General Public License along -* with this program. If not, see . -*/ - -#include -#include - -#include "DelayExecutor.h" - -DelayExecutor* DelayExecutor::instance() -{ - static DelayExecutor* instance = new DelayExecutor(); - return instance; -} - -DelayExecutor::DelayExecutor() - : pre_svc_hook_(0), post_svc_hook_(0), activated_(false) { } - -DelayExecutor::~DelayExecutor() -{ - if (pre_svc_hook_) - delete pre_svc_hook_; - - if (post_svc_hook_) - delete post_svc_hook_; - - deactivate(); -} - -int DelayExecutor::deactivate() -{ - if (!activated()) - return -1; - - activated(false); - queue_.queue()->deactivate(); - wait(); - - return 0; -} - -int DelayExecutor::svc() -{ - if (pre_svc_hook_) - pre_svc_hook_->call(); - - for (;;) - { - ACE_Method_Request* rq = queue_.dequeue(); - - if (!rq) - break; - - rq->call(); - delete rq; - } - - if (post_svc_hook_) - post_svc_hook_->call(); - - return 0; -} - -int DelayExecutor::start(int num_threads, ACE_Method_Request* pre_svc_hook, ACE_Method_Request* post_svc_hook) -{ - if (activated()) - return -1; - - if (num_threads < 1) - return -1; - - if (pre_svc_hook_) - delete pre_svc_hook_; - - if (post_svc_hook_) - delete post_svc_hook_; - - pre_svc_hook_ = pre_svc_hook; - post_svc_hook_ = post_svc_hook; - - queue_.queue()->activate(); - - if (ACE_Task_Base::activate(THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED, num_threads) == -1) - return -1; - - activated(true); - - return true; -} - -int DelayExecutor::execute(ACE_Method_Request* new_req) -{ - if (new_req == NULL) - return -1; - - if (queue_.enqueue(new_req, (ACE_Time_Value*)&ACE_Time_Value::zero) == -1) - { - delete new_req; - ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("(%t) %p\n"), ACE_TEXT("DelayExecutor::execute enqueue")), -1); - } - - return 0; -} - -bool DelayExecutor::activated() -{ - return activated_; -} - -void DelayExecutor::activated(bool s) -{ - activated_ = s; -} diff --git a/src/server/shared/Threading/DelayExecutor.h b/src/server/shared/Threading/DelayExecutor.h deleted file mode 100644 index 2a3721263fc..00000000000 --- a/src/server/shared/Threading/DelayExecutor.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _M_DELAY_EXECUTOR_H -#define _M_DELAY_EXECUTOR_H - -#include -#include -#include - -class DelayExecutor : protected ACE_Task_Base -{ - public: - DelayExecutor(); - virtual ~DelayExecutor(); - - static DelayExecutor* instance(); - - int execute(ACE_Method_Request* new_req); - - int start(int num_threads = 1, ACE_Method_Request* pre_svc_hook = NULL, ACE_Method_Request* post_svc_hook = NULL); - - int deactivate(); - - bool activated(); - - virtual int svc(); - - private: - ACE_Activation_Queue queue_; - ACE_Method_Request* pre_svc_hook_; - ACE_Method_Request* post_svc_hook_; - bool activated_; - - void activated(bool s); -}; - -#endif // _M_DELAY_EXECUTOR_H diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index 41060e37b38..ecc3e31a349 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -24,7 +24,6 @@ #include "Common.h" #include "SystemConfig.h" -#include "SignalHandler.h" #include "World.h" #include "WorldRunnable.h" #include "WorldSocket.h" -- cgit v1.2.3 From 433f0b25caa267054df679551806a317c2f215df Mon Sep 17 00:00:00 2001 From: leak Date: Wed, 2 Jul 2014 02:21:36 +0200 Subject: Forgotten change --- src/server/worldserver/Master.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server/worldserver/Master.cpp') diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index ecc3e31a349..920dc766900 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -87,7 +87,7 @@ void FreezeDetectorThread(uint32 delayTime) std::this_thread::sleep_for(std::chrono::milliseconds(1000)); uint32 curtime = getMSTime(); // normal work - uint32 worldLoopCounter = World::m_worldLoopCounter.value(); + uint32 worldLoopCounter = World::m_worldLoopCounter; if (loops != worldLoopCounter) { lastChange = curtime; -- cgit v1.2.3 From 310f5e68467ee61b66796fdd88c7c9691d4bd2a0 Mon Sep 17 00:00:00 2001 From: leak Date: Wed, 2 Jul 2014 17:38:44 +0200 Subject: Some ground work for ASIO based RemoteAccess handling --- src/server/authserver/Server/AuthServer.cpp | 3 -- src/server/shared/CMakeLists.txt | 3 ++ src/server/shared/Networking/AsyncAcceptor.h | 54 +++++++++++++++++++++ src/server/worldserver/CMakeLists.txt | 1 + src/server/worldserver/Main.cpp | 3 +- src/server/worldserver/Master.cpp | 21 +++++--- src/server/worldserver/Master.h | 2 + src/server/worldserver/RemoteAccess/RARunnable.cpp | 2 +- src/server/worldserver/RemoteAccess/RASession.cpp | 52 ++++++++++++++++++++ src/server/worldserver/RemoteAccess/RASession.h | 56 ++++++++++++++++++++++ 10 files changed, 184 insertions(+), 13 deletions(-) create mode 100644 src/server/shared/Networking/AsyncAcceptor.h create mode 100644 src/server/worldserver/RemoteAccess/RASession.cpp create mode 100644 src/server/worldserver/RemoteAccess/RASession.h (limited to 'src/server/worldserver/Master.cpp') diff --git a/src/server/authserver/Server/AuthServer.cpp b/src/server/authserver/Server/AuthServer.cpp index 5c3ef247254..c5a0cff186f 100644 --- a/src/server/authserver/Server/AuthServer.cpp +++ b/src/server/authserver/Server/AuthServer.cpp @@ -35,6 +35,3 @@ void AuthServer::AsyncAccept() AsyncAccept(); }); } - - - diff --git a/src/server/shared/CMakeLists.txt b/src/server/shared/CMakeLists.txt index 63aecab0fb7..a61248f01ea 100644 --- a/src/server/shared/CMakeLists.txt +++ b/src/server/shared/CMakeLists.txt @@ -18,6 +18,7 @@ file(GLOB_RECURSE sources_Database Database/*.cpp Database/*.h) file(GLOB_RECURSE sources_DataStores DataStores/*.cpp DataStores/*.h) file(GLOB_RECURSE sources_Dynamic Dynamic/*.cpp Dynamic/*.h) file(GLOB_RECURSE sources_Logging Logging/*.cpp Logging/*.h) +file(GLOB_RECURSE sources_Networking Networking/*.cpp Networking/*.h) file(GLOB_RECURSE sources_Packets Packets/*.cpp Packets/*.h) file(GLOB_RECURSE sources_Threading Threading/*.cpp Threading/*.h) file(GLOB_RECURSE sources_Utilities Utilities/*.cpp Utilities/*.h) @@ -47,6 +48,7 @@ set(shared_STAT_SRCS ${sources_Debugging} ${sources_Dynamic} ${sources_Logging} + ${sources_Networking} ${sources_Packets} ${sources_Threading} ${sources_Utilities} @@ -68,6 +70,7 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/Debugging ${CMAKE_CURRENT_SOURCE_DIR}/Dynamic ${CMAKE_CURRENT_SOURCE_DIR}/Logging + ${CMAKE_CURRENT_SOURCE_DIR}/Networking ${CMAKE_CURRENT_SOURCE_DIR}/Packets ${CMAKE_CURRENT_SOURCE_DIR}/Threading ${CMAKE_CURRENT_SOURCE_DIR}/Utilities diff --git a/src/server/shared/Networking/AsyncAcceptor.h b/src/server/shared/Networking/AsyncAcceptor.h new file mode 100644 index 00000000000..c54471fd01a --- /dev/null +++ b/src/server/shared/Networking/AsyncAcceptor.h @@ -0,0 +1,54 @@ +/* +* Copyright (C) 2008-2014 TrinityCore +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along +* with this program. If not, see . +*/ + +#ifndef __ASYNCACCEPT_H_ +#define __ASYNCACCEPT_H_ + +#include + +using boost::asio::ip::tcp; + +template +class AsyncAcceptor +{ +public: + AsyncAcceptor(boost::asio::io_service& ioService, std::string bindIp, int port) : + _socket(ioService), + _acceptor(ioService, tcp::endpoint(boost::asio::ip::address::from_string(bindIp), port)) + { + AsyncAccept(); + }; + +private: + void AsyncAcceptor::AsyncAccept() + { + _acceptor.async_accept(_socket, [this](boost::system::error_code error) + { + if (!error) + { + std::make_shared(std::move(_socket))->Start(); + } + + AsyncAccept(); + }); + } + + tcp::acceptor _acceptor; + tcp::socket _socket; +}; + +#endif /* __ASYNCACCEPT_H_ */ diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt index c006e6c925c..9d2e859a7de 100644 --- a/src/server/worldserver/CMakeLists.txt +++ b/src/server/worldserver/CMakeLists.txt @@ -62,6 +62,7 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic ${CMAKE_SOURCE_DIR}/src/server/shared/Logging + ${CMAKE_SOURCE_DIR}/src/server/shared/Networking ${CMAKE_SOURCE_DIR}/src/server/shared/Packets ${CMAKE_SOURCE_DIR}/src/server/shared/Threading ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index 75d9ca5145d..bcc058c7fb3 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -22,7 +22,6 @@ #include #include -#include #include "Common.h" #include "Database/DatabaseEnv.h" @@ -135,7 +134,7 @@ extern int main(int argc, char** argv) TC_LOG_INFO("server.worldserver", "Using configuration file %s.", cfg_file); TC_LOG_INFO("server.worldserver", "Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); - TC_LOG_INFO("server.worldserver", "Using ACE version: %s", ACE_VERSION); + TC_LOG_INFO("server.worldserver", "Using Boost version: %s", BOOST_LIB_VERSION); ///- and run the 'Master' /// @todo Why do we need this 'Master'? Can't all of this be in the Main as for Realmd? diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index 920dc766900..5318652ad88 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -22,7 +22,8 @@ #include -#include "Common.h" +#include "Master.h" + #include "SystemConfig.h" #include "World.h" #include "WorldRunnable.h" @@ -31,19 +32,17 @@ #include "Configuration/Config.h" #include "Database/DatabaseEnv.h" #include "Database/DatabaseWorkerPool.h" - #include "CliRunnable.h" #include "Log.h" -#include "Master.h" #include "RARunnable.h" #include "TCSoap.h" #include "Timer.h" #include "Util.h" #include "RealmList.h" - #include "BigNumber.h" #include "OpenSSLCrypto.h" -#include +#include "AsyncAcceptor.h" +#include "RASession.h" #ifdef _WIN32 #include "ServiceWin32.h" @@ -165,8 +164,8 @@ int Master::Run() cliThread = new std::thread(CliThread); } - // TODO C++11/Boost - // std::thread rarThread(RemoteAccessThread); + if (sConfigMgr->GetBoolDefault("Ra.Enable", false)) + StartRaSocketAcceptor(_ioService); #if defined(_WIN32) || defined(__linux__) @@ -470,3 +469,11 @@ void Master::ClearOnlineAccounts() // Battleground instance ids reset at server restart CharacterDatabase.DirectExecute("UPDATE character_battleground_data SET instanceId = 0"); } + +void Master::StartRaSocketAcceptor(boost::asio::io_service& ioService) +{ + uint16 raPort = uint16(sConfigMgr->GetIntDefault("Ra.Port", 3443)); + std::string raListener = sConfigMgr->GetStringDefault("Ra.IP", "0.0.0.0"); + + AsyncAcceptor raAcceptor(ioService, raListener, raPort); +} diff --git a/src/server/worldserver/Master.h b/src/server/worldserver/Master.h index d2a51b85f4b..3567d5ea933 100644 --- a/src/server/worldserver/Master.h +++ b/src/server/worldserver/Master.h @@ -23,6 +23,7 @@ #ifndef _MASTER_H #define _MASTER_H +#include #include "Common.h" /// Start the server @@ -42,6 +43,7 @@ class Master void _StopDB(); void ClearOnlineAccounts(); + void StartRaSocketAcceptor(boost::asio::io_service& ioService); }; #define sMaster Master::instance() diff --git a/src/server/worldserver/RemoteAccess/RARunnable.cpp b/src/server/worldserver/RemoteAccess/RARunnable.cpp index 4efeb07ef25..b3461af5a87 100644 --- a/src/server/worldserver/RemoteAccess/RARunnable.cpp +++ b/src/server/worldserver/RemoteAccess/RARunnable.cpp @@ -22,7 +22,7 @@ #include "Common.h" #include "Config.h" #include "Log.h" -#include "RARunnable.h" +#include "RARunnable.h", #include "World.h" #include diff --git a/src/server/worldserver/RemoteAccess/RASession.cpp b/src/server/worldserver/RemoteAccess/RASession.cpp new file mode 100644 index 00000000000..1438557e924 --- /dev/null +++ b/src/server/worldserver/RemoteAccess/RASession.cpp @@ -0,0 +1,52 @@ +/* +* Copyright (C) 2008-2014 TrinityCore +* Copyright (C) 2005-2009 MaNGOS +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along +* with this program. If not, see . +*/ + +#include +#include +#include + +using boost::asio::ip::tcp; + +void RASession::AsyncRead() +{ + auto self(shared_from_this()); + + _socket.async_read_some(boost::asio::buffer(_readBuffer, 1), [this, self](boost::system::error_code error, size_t transferedBytes) + { + if (!error && transferedBytes == 1) + { + // let the magic happen + } + else + { + _socket.close(); + } + }); +} + +void RASession::AsyncWrite(std::size_t length) +{ + boost::asio::async_write(_socket, boost::asio::buffer(_writeBuffer, length), [this](boost::system::error_code error, std::size_t /*length*/) + { + if (error) + { + _socket.close(); + } + }); +} + diff --git a/src/server/worldserver/RemoteAccess/RASession.h b/src/server/worldserver/RemoteAccess/RASession.h new file mode 100644 index 00000000000..ed2a83a4f2c --- /dev/null +++ b/src/server/worldserver/RemoteAccess/RASession.h @@ -0,0 +1,56 @@ +/* +* Copyright (C) 2008-2014 TrinityCore +* Copyright (C) 2005-2009 MaNGOS +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along +* with this program. If not, see . +*/ + +#ifndef __RASESSION_H__ +#define __RASESSION_H__ + +#include +#include +#include "Common.h" + +using boost::asio::ip::tcp; + +const size_t bufferSize = 4096; + +#define BUFFER_SIZE 4096 + +class RASession : public std::enable_shared_from_this +{ +public: + RASession(tcp::socket socket) : _socket(std::move(socket)) + { + } + + void Start() + { + AsyncRead(); + } + + const std::string GetRemoteIpAddress() const { return _socket.remote_endpoint().address().to_string(); }; + unsigned short GetRemotePort() const { return _socket.remote_endpoint().port(); } + +private: + void AsyncRead(); + void AsyncWrite(size_t length); + + tcp::socket _socket; + char _readBuffer[BUFFER_SIZE]; + char _writeBuffer[BUFFER_SIZE]; +}; + +#endif -- cgit v1.2.3 From 8df9e98ba5d7e230009f640a95289639ede8b0c1 Mon Sep 17 00:00:00 2001 From: leak Date: Wed, 2 Jul 2014 18:21:18 +0200 Subject: Remove unused RARunnable files --- src/server/worldserver/Master.cpp | 1 - src/server/worldserver/RemoteAccess/RARunnable.cpp | 80 ---------------------- src/server/worldserver/RemoteAccess/RARunnable.h | 29 -------- 3 files changed, 110 deletions(-) delete mode 100644 src/server/worldserver/RemoteAccess/RARunnable.cpp delete mode 100644 src/server/worldserver/RemoteAccess/RARunnable.h (limited to 'src/server/worldserver/Master.cpp') diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index 5318652ad88..4669168042c 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -34,7 +34,6 @@ #include "Database/DatabaseWorkerPool.h" #include "CliRunnable.h" #include "Log.h" -#include "RARunnable.h" #include "TCSoap.h" #include "Timer.h" #include "Util.h" diff --git a/src/server/worldserver/RemoteAccess/RARunnable.cpp b/src/server/worldserver/RemoteAccess/RARunnable.cpp deleted file mode 100644 index b3461af5a87..00000000000 --- a/src/server/worldserver/RemoteAccess/RARunnable.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -/** \file - \ingroup Trinityd - */ - -#include "Common.h" -#include "Config.h" -#include "Log.h" -#include "RARunnable.h", -#include "World.h" - -#include -#include -#include -#include -#include - -#include "RASocket.h" - - -void RemoteAccessThread() -{ - ACE_Reactor_Impl* imp = nullptr; - -#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) - imp = new ACE_Dev_Poll_Reactor(); - imp->max_notify_iterations(128); - imp->restart(1); -#else - imp = new ACE_TP_Reactor(); - imp->max_notify_iterations(128); -#endif - - ACE_Reactor* reactor = new ACE_Reactor(imp, 1); - - if (!sConfigMgr->GetBoolDefault("Ra.Enable", false)) - return; - - ACE_Acceptor acceptor; - - uint16 raPort = uint16(sConfigMgr->GetIntDefault("Ra.Port", 3443)); - std::string stringIp = sConfigMgr->GetStringDefault("Ra.IP", "0.0.0.0"); - ACE_INET_Addr listenAddress(raPort, stringIp.c_str()); - - if (acceptor.open(listenAddress, reactor) == -1) - { - TC_LOG_ERROR("server.worldserver", "Trinity RA can not bind to port %d on %s", raPort, stringIp.c_str()); - return; - } - - TC_LOG_INFO("server.worldserver", "Starting Trinity RA on port %d on %s", raPort, stringIp.c_str()); - - while (!World::IsStopped()) - { - ACE_Time_Value interval(0, 100000); - if (reactor->run_reactor_event_loop(interval) == -1) - break; - } - - delete imp; - delete reactor; - - TC_LOG_DEBUG("server.worldserver", "Trinity RA thread exiting"); -} diff --git a/src/server/worldserver/RemoteAccess/RARunnable.h b/src/server/worldserver/RemoteAccess/RARunnable.h deleted file mode 100644 index a65df077f97..00000000000 --- a/src/server/worldserver/RemoteAccess/RARunnable.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -/// \addtogroup Trinityd -/// @{ -/// \file - -#ifndef _TRINITY_RARUNNABLE_H_ -#define _TRINITY_RARUNNABLE_H_ - -void RemoteAccessThread(); - -#endif /* _TRINITY_RARUNNABLE_H_ */ - -/// @} -- cgit v1.2.3 From b516926da83a56b1318c4d94b4d4f3bac5510cce Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 2 Jul 2014 18:58:48 -0500 Subject: Enabled RA and removed all ACE from it --- src/server/worldserver/Master.cpp | 15 +- src/server/worldserver/Master.h | 6 +- src/server/worldserver/RemoteAccess/RASession.cpp | 204 ++++++++++- src/server/worldserver/RemoteAccess/RASession.h | 23 +- src/server/worldserver/RemoteAccess/RASocket.cpp | 425 ---------------------- src/server/worldserver/RemoteAccess/RASocket.h | 64 ---- 6 files changed, 214 insertions(+), 523 deletions(-) delete mode 100644 src/server/worldserver/RemoteAccess/RASocket.cpp delete mode 100644 src/server/worldserver/RemoteAccess/RASocket.h (limited to 'src/server/worldserver/Master.cpp') diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index 4669168042c..c529e6b6478 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -41,7 +41,6 @@ #include "BigNumber.h" #include "OpenSSLCrypto.h" #include "AsyncAcceptor.h" -#include "RASession.h" #ifdef _WIN32 #include "ServiceWin32.h" @@ -163,8 +162,10 @@ int Master::Run() cliThread = new std::thread(CliThread); } + AsyncAcceptor* raAcceptor = nullptr; + if (sConfigMgr->GetBoolDefault("Ra.Enable", false)) - StartRaSocketAcceptor(_ioService); + raAcceptor = StartRaSocketAcceptor(_ioService); #if defined(_WIN32) || defined(__linux__) @@ -246,9 +247,7 @@ int Master::Run() ///- Start up freeze catcher thread if (uint32 freezeDelay = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0)) - { freezeDetectorThread = new std::thread(FreezeDetectorThread, freezeDelay); - } ///- Launch the world listener socket uint16 worldPort = uint16(sWorld->getIntConfig(CONFIG_PORT_WORLD)); @@ -271,7 +270,6 @@ int Master::Run() // when the main thread closes the singletons get unloaded // since worldrunnable uses them, it will crash if unloaded after master worldThread.join(); - //rarThread.join(); if (soapThread != nullptr) { @@ -279,6 +277,9 @@ int Master::Run() delete soapThread; } + if (raAcceptor != nullptr) + delete raAcceptor; + // set server offline LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID); @@ -469,10 +470,10 @@ void Master::ClearOnlineAccounts() CharacterDatabase.DirectExecute("UPDATE character_battleground_data SET instanceId = 0"); } -void Master::StartRaSocketAcceptor(boost::asio::io_service& ioService) +AsyncAcceptor* Master::StartRaSocketAcceptor(boost::asio::io_service& ioService) { uint16 raPort = uint16(sConfigMgr->GetIntDefault("Ra.Port", 3443)); std::string raListener = sConfigMgr->GetStringDefault("Ra.IP", "0.0.0.0"); - AsyncAcceptor raAcceptor(ioService, raListener, raPort); + return new AsyncAcceptor(ioService, raListener, raPort); } diff --git a/src/server/worldserver/Master.h b/src/server/worldserver/Master.h index 0c6836f25b8..86059e6417a 100644 --- a/src/server/worldserver/Master.h +++ b/src/server/worldserver/Master.h @@ -25,6 +25,10 @@ #include #include "Common.h" +#include "RASession.h" + +template +class AsyncAcceptor; /// Start the server class Master @@ -43,7 +47,7 @@ class Master void _StopDB(); void ClearOnlineAccounts(); - void StartRaSocketAcceptor(boost::asio::io_service& ioService); + AsyncAcceptor* StartRaSocketAcceptor(boost::asio::io_service& ioService); }; #define sMaster Master::instance() diff --git a/src/server/worldserver/RemoteAccess/RASession.cpp b/src/server/worldserver/RemoteAccess/RASession.cpp index 359b18f1039..536ce22839b 100644 --- a/src/server/worldserver/RemoteAccess/RASession.cpp +++ b/src/server/worldserver/RemoteAccess/RASession.cpp @@ -18,35 +18,201 @@ #include #include +#include +#include #include "RASession.h" +#include "AccountMgr.h" using boost::asio::ip::tcp; -void RASession::AsyncRead() +void RASession::Start() { - auto self(shared_from_this()); + boost::asio::socket_base::bytes_readable command(true); + _socket.io_control(command); + std::size_t bytes_readable = command.get(); - _socket.async_read_some(boost::asio::buffer(_readBuffer, 1), [this, self](boost::system::error_code error, size_t transferedBytes) + // Check if there are bytes available, if they are, then the client is requesting the negotiation + if (bytes_readable > 0) { - if (!error && transferedBytes == 1) - { - // let the magic happen - } - else - { - _socket.close(); - } - }); + // Handle subnegotiation + boost::array buf; + std::size_t length = _socket.read_some(boost::asio::buffer(buf)); + + // Send the end-of-negotiation packet + uint8 const reply[2] = { 0xFF, 0xF0 }; + _socket.write_some(boost::asio::buffer(reply)); + } + + Send("Authentication Required\r\n"); + Send("Username: "); + + std::string username = ReadString(); + + if (username.empty()) + return; + + TC_LOG_INFO("commands.ra", "Accepting RA connection from user %s (IP: %s)", username.c_str(), GetRemoteIpAddress().c_str()); + + Send("Password: "); + + std::string password = ReadString(); + if (password.empty()) + return; + + if (!CheckAccessLevel(username) || !CheckPassword(username, password)) + { + Send("Authentication failed\r\n"); + _socket.close(); + return; + } + + TC_LOG_INFO("commands.ra", "User %s (IP: %s) authenticated correctly to RA", username.c_str(), GetRemoteIpAddress().c_str()); + + // Authentication successful, send the motd + Send(std::string(std::string(sWorld->GetMotd()) + "\r\n").c_str()); + + // Read commands + while (true) + { + Send("TC>"); + std::string command = ReadString(); + + if (ProcessCommand(command)) + break; + } + + _socket.close(); +} + +int RASession::Send(const char* data) +{ + std::ostream os(&_writeBuffer); + os << data; + size_t written = _socket.send(_writeBuffer.data()); + _writeBuffer.consume(written); + return written; +} + +std::string RASession::ReadString() +{ + boost::system::error_code error; + size_t read = boost::asio::read_until(_socket, _readBuffer, "\r\n", error); + if (!read) + { + _socket.close(); + return ""; + } + + std::string line; + std::istream is(&_readBuffer); + std::getline(is, line); + + if (*line.rbegin() == '\r') + line.erase(line.length() - 1); + + return line; +} + +bool RASession::CheckAccessLevel(const std::string& user) +{ + std::string safeUser = user; + + AccountMgr::normalizeString(safeUser); + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ACCESS); + stmt->setString(0, safeUser); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (!result) + { + TC_LOG_INFO("commands.ra", "User %s does not exist in database", user.c_str()); + return false; + } + + Field* fields = result->Fetch(); + + if (fields[1].GetUInt8() < sConfigMgr->GetIntDefault("RA.MinLevel", 3)) + { + TC_LOG_INFO("commands.ra", "User %s has no privilege to login", user.c_str()); + return false; + } + else if (fields[2].GetInt32() != -1) + { + TC_LOG_INFO("commands.ra", "User %s has to be assigned on all realms (with RealmID = '-1')", user.c_str()); + return false; + } + + return true; } -void RASession::AsyncWrite(std::size_t length) +bool RASession::CheckPassword(const std::string& user, const std::string& pass) { - boost::asio::async_write(_socket, boost::asio::buffer(_writeBuffer, length), [this](boost::system::error_code error, std::size_t /*length*/) + std::string safe_user = user; + std::transform(safe_user.begin(), safe_user.end(), safe_user.begin(), ::toupper); + AccountMgr::normalizeString(safe_user); + + std::string safe_pass = pass; + AccountMgr::normalizeString(safe_pass); + std::transform(safe_pass.begin(), safe_pass.end(), safe_pass.begin(), ::toupper); + + std::string hash = AccountMgr::CalculateShaPassHash(safe_user, safe_pass); + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_CHECK_PASSWORD_BY_NAME); + + stmt->setString(0, safe_user); + stmt->setString(1, hash); + + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (!result) { - if (error) - { - _socket.close(); - } - }); + TC_LOG_INFO("commands.ra", "Wrong password for user: %s", user.c_str()); + return false; + } + + return true; } +bool RASession::ProcessCommand(std::string& command) +{ + if (command.length() == 0) + return true; + + TC_LOG_INFO("commands.ra", "Received command: %s", command.c_str()); + + // handle quit, exit and logout commands to terminate connection + if (command == "quit" || command == "exit" || command == "logout") + { + Send("Bye\r\n"); + return true; + } + + // Obtain a new promise per command + if (_commandExecuting != nullptr) + delete _commandExecuting; + + _commandExecuting = new std::promise(); + + CliCommandHolder* cmd = new CliCommandHolder(this, command.c_str(), &RASession::CommandPrint, &RASession::CommandFinished); + sWorld->QueueCliCommand(cmd); + + // Wait for the command to finish + _commandExecuting->get_future().wait(); + + return false; +} + +void RASession::CommandPrint(void* callbackArg, const char* text) +{ + if (!text || !*text) + return; + + RASession* session = static_cast(callbackArg); + session->Send(text); +} + +void RASession::CommandFinished(void* callbackArg, bool success) +{ + RASession* session = static_cast(callbackArg); + session->_commandExecuting->set_value(); +} diff --git a/src/server/worldserver/RemoteAccess/RASession.h b/src/server/worldserver/RemoteAccess/RASession.h index a467c387858..f3ef2a6a86a 100644 --- a/src/server/worldserver/RemoteAccess/RASession.h +++ b/src/server/worldserver/RemoteAccess/RASession.h @@ -21,8 +21,11 @@ #include #include +#include #include "Common.h" +#include + using boost::asio::ip::tcp; const size_t bufferSize = 4096; @@ -32,25 +35,31 @@ const size_t bufferSize = 4096; class RASession : public std::enable_shared_from_this { public: - RASession(tcp::socket socket) : _socket(std::move(socket)) + RASession(tcp::socket socket) : _socket(std::move(socket)), _commandExecuting(nullptr) { } - void Start() - { - AsyncRead(); - } + void Start(); const std::string GetRemoteIpAddress() const { return _socket.remote_endpoint().address().to_string(); }; unsigned short GetRemotePort() const { return _socket.remote_endpoint().port(); } private: + int Send(const char* data); void AsyncRead(); void AsyncWrite(size_t length); + std::string ReadString(); + bool CheckAccessLevel(const std::string& user); + bool CheckPassword(const std::string& user, const std::string& pass); + bool ProcessCommand(std::string& command); + + static void CommandPrint(void* callbackArg, const char* text); + static void CommandFinished(void* callbackArg, bool success); tcp::socket _socket; - char _readBuffer[BUFFER_SIZE]; - char _writeBuffer[BUFFER_SIZE]; + boost::asio::streambuf _readBuffer; + boost::asio::streambuf _writeBuffer; + std::promise* _commandExecuting; }; #endif diff --git a/src/server/worldserver/RemoteAccess/RASocket.cpp b/src/server/worldserver/RemoteAccess/RASocket.cpp deleted file mode 100644 index 698d3c949cd..00000000000 --- a/src/server/worldserver/RemoteAccess/RASocket.cpp +++ /dev/null @@ -1,425 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -/** \file - \ingroup Trinityd -*/ - -#include "Common.h" -#include "Configuration/Config.h" -#include "Database/DatabaseEnv.h" -#include "AccountMgr.h" -#include "Log.h" -#include "RASocket.h" -#include "Util.h" -#include "World.h" -#include "SHA1.h" -#include "ace/OS_NS_unistd.h" - -RASocket::RASocket() -{ - _minLevel = uint8(sConfigMgr->GetIntDefault("RA.MinLevel", 3)); - _commandExecuting = false; -} - -int RASocket::open(void *) -{ - ACE_INET_Addr remoteAddress; - - if (peer().get_remote_addr(remoteAddress) == -1) - { - TC_LOG_ERROR("server.worldserver", "RASocket::open: peer().get_remote_addr error is %s", ACE_OS::strerror(errno)); - return -1; - } - - TC_LOG_INFO("commands.ra", "Incoming connection from %s", remoteAddress.get_host_addr()); - - return activate(); -} - -int RASocket::handle_close(ACE_HANDLE /*handle*/, ACE_Reactor_Mask /*mask*/) -{ - TC_LOG_INFO("commands.ra", "Closing connection"); - peer().close_reader(); - wait(); - // While the above wait() will wait for the ::svc() to finish, it will not wait for the async event - // RASocket::commandfinished to be completed. Calling destroy() before the latter function ends - // will lead to using a freed pointer -> crash. - while (_commandExecuting.value()) - ACE_OS::sleep(1); - - destroy(); - return 0; -} - -int RASocket::send(const std::string& line) -{ -#ifdef MSG_NOSIGNAL - ssize_t n = peer().send(line.c_str(), line.length(), MSG_NOSIGNAL); -#else - ssize_t n = peer().send(line.c_str(), line.length()); -#endif // MSG_NOSIGNAL - - return n == ssize_t(line.length()) ? 0 : -1; -} - -int RASocket::recv_line(ACE_Message_Block& buffer) -{ - char byte; - for (;;) - { - ssize_t n = peer().recv(&byte, sizeof(byte)); - - if (n < 0) - return -1; - - if (n == 0) - { - // EOF, connection was closed - errno = ECONNRESET; - return -1; - } - - ACE_ASSERT(n == sizeof(byte)); - - if (byte == '\n') - break; - else if (byte == '\r') /* Ignore CR */ - continue; - else if (buffer.copy(&byte, sizeof(byte)) == -1) - return -1; - } - - const char nullTerm = '\0'; - if (buffer.copy(&nullTerm, sizeof(nullTerm)) == -1) - return -1; - - return 0; -} - -int RASocket::recv_line(std::string& out_line) -{ - char buf[4096]; - - ACE_Data_Block db(sizeof (buf), - ACE_Message_Block::MB_DATA, - buf, - 0, - 0, - ACE_Message_Block::DONT_DELETE, - 0); - - ACE_Message_Block message_block(&db, - ACE_Message_Block::DONT_DELETE, - 0); - - if (recv_line(message_block) == -1) - { - TC_LOG_DEBUG("commands.ra", "Recv error %s", ACE_OS::strerror(errno)); - return -1; - } - - out_line = message_block.rd_ptr(); - - return 0; -} - -int RASocket::process_command(const std::string& command) -{ - if (command.length() == 0) - return 0; - - TC_LOG_INFO("commands.ra", "Received command: %s", command.c_str()); - - // handle quit, exit and logout commands to terminate connection - if (command == "quit" || command == "exit" || command == "logout") { - (void) send("Bye\r\n"); - return -1; - } - - _commandExecuting = true; - CliCommandHolder* cmd = new CliCommandHolder(this, command.c_str(), &RASocket::zprint, &RASocket::commandFinished); - sWorld->QueueCliCommand(cmd); - - // wait for result - ACE_Message_Block* mb; - for (;;) - { - if (getq(mb) == -1) - return -1; - - if (mb->msg_type() == ACE_Message_Block::MB_BREAK) - { - mb->release(); - break; - } - - if (send(std::string(mb->rd_ptr(), mb->length())) == -1) - { - mb->release(); - return -1; - } - - mb->release(); - } - - return 0; -} - -int RASocket::check_access_level(const std::string& user) -{ - std::string safeUser = user; - - AccountMgr::normalizeString(safeUser); - - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_ACCESS); - stmt->setString(0, safeUser); - PreparedQueryResult result = LoginDatabase.Query(stmt); - - if (!result) - { - TC_LOG_INFO("commands.ra", "User %s does not exist in database", user.c_str()); - return -1; - } - - Field* fields = result->Fetch(); - - if (fields[1].GetUInt8() < _minLevel) - { - TC_LOG_INFO("commands.ra", "User %s has no privilege to login", user.c_str()); - return -1; - } - else if (fields[2].GetInt32() != -1) - { - TC_LOG_INFO("commands.ra", "User %s has to be assigned on all realms (with RealmID = '-1')", user.c_str()); - return -1; - } - - return 0; -} - -int RASocket::check_password(const std::string& user, const std::string& pass) -{ - std::string safe_user = user; - AccountMgr::normalizeString(safe_user); - - std::string safe_pass = pass; - AccountMgr::normalizeString(safe_pass); - - std::string hash = AccountMgr::CalculateShaPassHash(safe_user, safe_pass); - - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_CHECK_PASSWORD_BY_NAME); - - stmt->setString(0, safe_user); - stmt->setString(1, hash); - - PreparedQueryResult result = LoginDatabase.Query(stmt); - - if (!result) - { - TC_LOG_INFO("commands.ra", "Wrong password for user: %s", user.c_str()); - return -1; - } - - return 0; -} - -int RASocket::authenticate() -{ - if (send(std::string("Username: ")) == -1) - return -1; - - std::string user; - if (recv_line(user) == -1) - return -1; - - if (send(std::string("Password: ")) == -1) - return -1; - - std::string pass; - if (recv_line(pass) == -1) - return -1; - - TC_LOG_INFO("commands.ra", "Login attempt for user: %s", user.c_str()); - - if (check_access_level(user) == -1) - return -1; - - if (check_password(user, pass) == -1) - return -1; - - TC_LOG_INFO("commands.ra", "User login: %s", user.c_str()); - - return 0; -} - - -int RASocket::subnegotiate() -{ - char buf[1024]; - - ACE_Data_Block db(sizeof (buf), - ACE_Message_Block::MB_DATA, - buf, - 0, - 0, - ACE_Message_Block::DONT_DELETE, - 0); - - ACE_Message_Block message_block(&db, - ACE_Message_Block::DONT_DELETE, - 0); - - const size_t recv_size = message_block.space(); - - // Wait a maximum of 1000ms for negotiation packet - not all telnet clients may send it - ACE_Time_Value waitTime = ACE_Time_Value(1); - const ssize_t n = peer().recv(message_block.wr_ptr(), - recv_size, &waitTime); - - if (n <= 0) - return int(n); - - if (n >= 1024) - { - TC_LOG_DEBUG("commands.ra", "RASocket::subnegotiate: allocated buffer 1024 bytes was too small for negotiation packet, size: %u", uint32(n)); - return -1; - } - - buf[n] = '\0'; - - #ifdef _DEBUG - for (uint8 i = 0; i < n; ) - { - uint8 iac = buf[i]; - if (iac == 0xFF) // "Interpret as Command" (IAC) - { - uint8 command = buf[++i]; - std::stringstream ss; - switch (command) - { - case 0xFB: // WILL - ss << "WILL "; - break; - case 0xFC: // WON'T - ss << "WON'T "; - break; - case 0xFD: // DO - ss << "DO "; - break; - case 0xFE: // DON'T - ss << "DON'T "; - break; - default: - return -1; // not allowed - } - - uint8 param = buf[++i]; - ss << uint32(param); - TC_LOG_DEBUG("commands.ra", ss.str().c_str()); - } - ++i; - } - #endif - - //! Just send back end of subnegotiation packet - uint8 const reply[2] = {0xFF, 0xF0}; - -#ifdef MSG_NOSIGNAL - return int(peer().send(reply, 2, MSG_NOSIGNAL)); -#else - return int(peer().send(reply, 2)); -#endif // MSG_NOSIGNAL -} - -int RASocket::svc(void) -{ - //! Subnegotiation may differ per client - do not react on it - subnegotiate(); - - if (send("Authentication required\r\n") == -1) - return -1; - - if (authenticate() == -1) - { - (void) send("Authentication failed\r\n"); - return -1; - } - - // send motd - if (send(std::string(sWorld->GetMotd()) + "\r\n") == -1) - return -1; - - for (;;) - { - // show prompt - if (send("TC> ") == -1) - return -1; - - std::string line; - - if (recv_line(line) == -1) - return -1; - - if (process_command(line) == -1) - return -1; - } - - return 0; -} - -void RASocket::zprint(void* callbackArg, const char * szText) -{ - if (!szText || !callbackArg) - return; - - RASocket* socket = static_cast(callbackArg); - size_t sz = strlen(szText); - - ACE_Message_Block* mb = new ACE_Message_Block(sz); - mb->copy(szText, sz); - - ACE_Time_Value tv = ACE_Time_Value::zero; - if (socket->putq(mb, &tv) == -1) - { - TC_LOG_DEBUG("commands.ra", "Failed to enqueue message, queue is full or closed. Error is %s", ACE_OS::strerror(errno)); - mb->release(); - } -} - -void RASocket::commandFinished(void* callbackArg, bool /*success*/) -{ - if (!callbackArg) - return; - - RASocket* socket = static_cast(callbackArg); - - ACE_Message_Block* mb = new ACE_Message_Block(); - - mb->msg_type(ACE_Message_Block::MB_BREAK); - - // the message is 0 size control message to tell that command output is finished - // hence we don't put timeout, because it shouldn't increase queue size and shouldn't block - if (socket->putq(mb->duplicate()) == -1) - // getting here is bad, command can't be marked as complete - TC_LOG_DEBUG("commands.ra", "Failed to enqueue command end message. Error is %s", ACE_OS::strerror(errno)); - - mb->release(); - - socket->_commandExecuting = false; -} diff --git a/src/server/worldserver/RemoteAccess/RASocket.h b/src/server/worldserver/RemoteAccess/RASocket.h deleted file mode 100644 index 2cbb14b3578..00000000000 --- a/src/server/worldserver/RemoteAccess/RASocket.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -/// \addtogroup Trinityd -/// @{ -/// \file - -#ifndef _RASOCKET_H -#define _RASOCKET_H - -#include "Common.h" - -#include -#include -#include -#include - -/// Remote Administration socket -class RASocket : public ACE_Svc_Handler -{ - public: - RASocket(); - virtual ~RASocket() { } - - virtual int svc() override; - virtual int open(void* = 0) override; - virtual int handle_close(ACE_HANDLE = ACE_INVALID_HANDLE, ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK) override; - - private: - int recv_line(std::string& outLine); - int recv_line(ACE_Message_Block& buffer); - int process_command(const std::string& command); - int authenticate(); - int subnegotiate(); ///< Used by telnet protocol RFC 854 / 855 - int check_access_level(const std::string& user); - int check_password(const std::string& user, const std::string& pass); - int send(const std::string& line); - - static void zprint(void* callbackArg, const char* szText); - static void commandFinished(void* callbackArg, bool success); - - private: - uint8 _minLevel; ///< Minimum security level required to connect - ACE_Atomic_Op _commandExecuting; -}; - -#endif - -/// @} -- cgit v1.2.3 From 021e18d152b68b9d2a0c5887bab7eb7b61ecd2ca Mon Sep 17 00:00:00 2001 From: leak Date: Fri, 4 Jul 2014 15:22:06 +0200 Subject: Refactored both world and auth main - Master/Worldrunable removed - World Update loop now running on main (which was doing nothing before) - Processpriority moved to shared - Added a preliminary thread pool for boost::asio::io_service --- src/server/authserver/Main.cpp | 160 ++----- src/server/shared/Threading/ProcessPriority.h | 100 +++++ src/server/worldserver/CMakeLists.txt | 3 - src/server/worldserver/Main.cpp | 487 +++++++++++++++++++-- src/server/worldserver/Master.cpp | 479 -------------------- src/server/worldserver/Master.h | 57 --- .../worldserver/WorldThread/WorldRunnable.cpp | 103 ----- src/server/worldserver/WorldThread/WorldRunnable.h | 32 -- src/server/worldserver/worldserver.conf.dist | 23 +- 9 files changed, 616 insertions(+), 828 deletions(-) create mode 100644 src/server/shared/Threading/ProcessPriority.h delete mode 100644 src/server/worldserver/Master.cpp delete mode 100644 src/server/worldserver/Master.h delete mode 100644 src/server/worldserver/WorldThread/WorldRunnable.cpp delete mode 100644 src/server/worldserver/WorldThread/WorldRunnable.h (limited to 'src/server/worldserver/Master.cpp') diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index 4e39ae0aca1..c7f71edbd0c 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -24,28 +24,24 @@ * authentication server */ -#include -#include -#include #include #include +#include +#include +#include +#include "AsyncAcceptor.h" +#include "AuthSession.h" #include "Common.h" -#include "Database/DatabaseEnv.h" #include "Configuration/Config.h" +#include "Database/DatabaseEnv.h" #include "Log.h" +#include "ProcessPriority.h" +#include "RealmList.h" #include "SystemConfig.h" #include "Util.h" -#include "RealmList.h" -#include "AsyncAcceptor.h" -#include "AuthSession.h" - -#ifdef __linux__ -#include -#include -#define PROCESS_HIGH_PRIORITY -15 // [-20, 19], default is 0 -#endif +using boost::asio::ip::tcp; #ifndef _TRINITY_REALM_CONFIG # define _TRINITY_REALM_CONFIG "authserver.conf" @@ -53,51 +49,15 @@ bool StartDB(); void StopDB(); -void SetProcessPriority(); +void SignalHandler(const boost::system::error_code& error, int signalNumber); +void KeepDatabaseAliveHandler(const boost::system::error_code& error); +void usage(const char* prog); boost::asio::io_service _ioService; boost::asio::deadline_timer _dbPingTimer(_ioService); uint32 _dbPingInterval; +LoginDatabaseWorkerPool LoginDatabase; -LoginDatabaseWorkerPool LoginDatabase; // Accessor to the authserver database - -using boost::asio::ip::tcp; - - -void SignalHandler(const boost::system::error_code& error, int signalNumber) -{ - if (!error) - { - switch (signalNumber) - { - case SIGINT: - case SIGTERM: - _ioService.stop(); - break; - } - } -} - -void KeepDatabaseAliveHandler(const boost::system::error_code& error) -{ - if (!error) - { - TC_LOG_INFO("server.authserver", "Ping MySQL to keep connection alive"); - LoginDatabase.KeepAlive(); - - _dbPingTimer.expires_from_now(boost::posix_time::minutes(_dbPingInterval)); - } -} - -/// Print out the usage string for this program on the console. -void usage(const char* prog) -{ - TC_LOG_INFO("server.authserver", "Usage: \n %s []\n" - " -c config_file use config_file as configuration file\n\r", - prog); -} - -/// Launch the auth server int main(int argc, char** argv) { // Command line parsing to get the configuration file name @@ -129,7 +89,6 @@ int main(int argc, char** argv) TC_LOG_INFO("server.authserver", "%s (authserver)", _FULLVERSION); TC_LOG_INFO("server.authserver", " to stop.\n"); TC_LOG_INFO("server.authserver", "Using configuration file %s.", configFile); - TC_LOG_INFO("server.authserver", "%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); // authserver PID file creation @@ -158,31 +117,30 @@ int main(int argc, char** argv) return 1; } - // Launch the listening network socket - + // Start the listening port (acceptor) for auth connections int32 port = sConfigMgr->GetIntDefault("RealmServerPort", 3724); if (port < 0 || port > 0xFFFF) { TC_LOG_ERROR("server.authserver", "Specified port out of allowed range (1-65535)"); return 1; } - + std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0"); - AsyncAcceptor authServer(_ioService, bindIp, port); // Set signal handlers boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM); signals.async_wait(SignalHandler); - SetProcessPriority(); + // Set process priority according to configuration settings + SetProcessPriority("server.authserver"); + // Enabled a timed callback for handling the database keep alive ping _dbPingInterval = sConfigMgr->GetIntDefault("MaxPingTime", 30); - _dbPingTimer.expires_from_now(boost::posix_time::seconds(_dbPingInterval)); _dbPingTimer.async_wait(KeepDatabaseAliveHandler); - // Start the io service + // Start the io service worker loop _ioService.run(); // Close the Database Pool and library @@ -238,73 +196,35 @@ void StopDB() MySQL::Library_End(); } -void SetProcessPriority() +void SignalHandler(const boost::system::error_code& error, int signalNumber) { -#if defined(_WIN32) || defined(__linux__) - - ///- Handle affinity for multiple processors and process priority - uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0); - bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false); - -#ifdef _WIN32 // Windows - - HANDLE hProcess = GetCurrentProcess(); - if (affinity > 0) + if (!error) { - ULONG_PTR appAff; - ULONG_PTR sysAff; - - if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) + switch (signalNumber) { - // remove non accessible processors - ULONG_PTR currentAffinity = affinity & appAff; - - if (!currentAffinity) - TC_LOG_ERROR("server.authserver", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the authserver. Accessible processors bitmask (hex): %x", affinity, appAff); - else if (SetProcessAffinityMask(hProcess, currentAffinity)) - TC_LOG_INFO("server.authserver", "Using processors (bitmask, hex): %x", currentAffinity); - else - TC_LOG_ERROR("server.authserver", "Can't set used processors (hex): %x", currentAffinity); + case SIGINT: + case SIGTERM: + _ioService.stop(); + break; } } +} - if (highPriority) - { - if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) - TC_LOG_INFO("server.authserver", "authserver process priority class set to HIGH"); - else - TC_LOG_ERROR("server.authserver", "Can't set authserver process priority class."); - } - -#else // Linux - - if (affinity > 0) +void KeepDatabaseAliveHandler(const boost::system::error_code& error) +{ + if (!error) { - cpu_set_t mask; - CPU_ZERO(&mask); - - for (unsigned int i = 0; i < sizeof(affinity) * 8; ++i) - if (affinity & (1 << i)) - CPU_SET(i, &mask); - - if (sched_setaffinity(0, sizeof(mask), &mask)) - TC_LOG_ERROR("server.authserver", "Can't set used processors (hex): %x, error: %s", affinity, strerror(errno)); - else - { - CPU_ZERO(&mask); - sched_getaffinity(0, sizeof(mask), &mask); - TC_LOG_INFO("server.authserver", "Using processors (bitmask, hex): %lx", *(__cpu_mask*)(&mask)); - } - } + TC_LOG_INFO("server.authserver", "Ping MySQL to keep connection alive"); + LoginDatabase.KeepAlive(); - if (highPriority) - { - if (setpriority(PRIO_PROCESS, 0, PROCESS_HIGH_PRIORITY)) - TC_LOG_ERROR("server.authserver", "Can't set authserver process priority class, error: %s", strerror(errno)); - else - TC_LOG_INFO("server.authserver", "authserver process priority class set to %i", getpriority(PRIO_PROCESS, 0)); + _dbPingTimer.expires_from_now(boost::posix_time::minutes(_dbPingInterval)); } +} -#endif -#endif +/// Print out the usage string for this program on the console. +void usage(const char* prog) +{ + TC_LOG_INFO("server.authserver", "Usage: \n %s []\n" + " -c config_file use config_file as configuration file\n\r", + prog); } diff --git a/src/server/shared/Threading/ProcessPriority.h b/src/server/shared/Threading/ProcessPriority.h new file mode 100644 index 00000000000..cd116ccbbc8 --- /dev/null +++ b/src/server/shared/Threading/ProcessPriority.h @@ -0,0 +1,100 @@ +/* +* Copyright (C) 2008-2014 TrinityCore +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along +* with this program. If not, see . +*/ + +#ifndef _PROCESSPRIO_H +#define _PROCESSPRIO_H + +#include "Configuration/Config.h" + +#ifdef __linux__ +#include +#include +#define PROCESS_HIGH_PRIORITY -15 // [-20, 19], default is 0 +#endif + +void SetProcessPriority(const std::string logChannel) +{ +#if defined(_WIN32) || defined(__linux__) + + ///- Handle affinity for multiple processors and process priority + uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0); + bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false); + +#ifdef _WIN32 // Windows + + HANDLE hProcess = GetCurrentProcess(); + if (affinity > 0) + { + ULONG_PTR appAff; + ULONG_PTR sysAff; + + if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) + { + // remove non accessible processors + ULONG_PTR currentAffinity = affinity & appAff; + + if (!currentAffinity) + TC_LOG_ERROR(logChannel, "Processors marked in UseProcessors bitmask (hex) %x are not accessible. Accessible processors bitmask (hex): %x", affinity, appAff); + else if (SetProcessAffinityMask(hProcess, currentAffinity)) + TC_LOG_INFO(logChannel, "Using processors (bitmask, hex): %x", currentAffinity); + else + TC_LOG_ERROR(logChannel, "Can't set used processors (hex): %x", currentAffinity); + } + } + + if (highPriority) + { + if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) + TC_LOG_INFO(logChannel, "Process priority class set to HIGH"); + else + TC_LOG_ERROR(logChannel, "Can't set process priority class."); + } + +#else // Linux + + if (affinity > 0) + { + cpu_set_t mask; + CPU_ZERO(&mask); + + for (unsigned int i = 0; i < sizeof(affinity) * 8; ++i) + if (affinity & (1 << i)) + CPU_SET(i, &mask); + + if (sched_setaffinity(0, sizeof(mask), &mask)) + TC_LOG_ERROR(logChannel, "Can't set used processors (hex): %x, error: %s", affinity, strerror(errno)); + else + { + CPU_ZERO(&mask); + sched_getaffinity(0, sizeof(mask), &mask); + TC_LOG_INFO(logChannel, "Using processors (bitmask, hex): %lx", *(__cpu_mask*)(&mask)); + } + } + + if (highPriority) + { + if (setpriority(PRIO_PROCESS, 0, PROCESS_HIGH_PRIORITY)) + TC_LOG_ERROR(logChannel, "Can't set process priority class, error: %s", strerror(errno)); + else + TC_LOG_INFO(logChannel, "Process priority class set to %i", getpriority(PRIO_PROCESS, 0)); + } + +#endif +#endif +} + +#endif diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt index 9d2e859a7de..b7a158ab3ce 100644 --- a/src/server/worldserver/CMakeLists.txt +++ b/src/server/worldserver/CMakeLists.txt @@ -11,7 +11,6 @@ file(GLOB_RECURSE sources_CommandLine CommandLine/*.cpp CommandLine/*.h) file(GLOB_RECURSE sources_RemoteAccess RemoteAccess/*.cpp RemoteAccess/*.h) file(GLOB_RECURSE sources_TCSoap TCSoap/*.cpp TCSoap/*.h) -file(GLOB_RECURSE sources_WorldThread WorldThread/*.cpp WorldThread/*.h) file(GLOB sources_localdir *.cpp *.h) if (USE_COREPCH) @@ -24,7 +23,6 @@ set(worldserver_SRCS ${sources_CommandLine} ${sources_RemoteAccess} ${sources_TCSoap} - ${sources_WorldThread} ${sources_localdir} ) @@ -138,7 +136,6 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/CommandLine ${CMAKE_CURRENT_SOURCE_DIR}/RemoteAccess ${CMAKE_CURRENT_SOURCE_DIR}/TCSoap - ${CMAKE_CURRENT_SOURCE_DIR}/WorldThread ${ACE_INCLUDE_DIR} ${MYSQL_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp index bcc058c7fb3..0fc2c1a7221 100644 --- a/src/server/worldserver/Main.cpp +++ b/src/server/worldserver/Main.cpp @@ -22,17 +22,30 @@ #include #include +#include #include "Common.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" +#include "AsyncAcceptor.h" +#include "RASession.h" #include "Configuration/Config.h" +#include "OpenSSLCrypto.h" +#include "ProcessPriority.h" +#include "BigNumber.h" +#include "RealmList.h" +#include "World.h" +#include "MapManager.h" +#include "ObjectAccessor.h" +#include "ScriptMgr.h" +#include "WorldSocketMgr.h" +#include "OutdoorPvP/OutdoorPvPMgr.h" +#include "BattlegroundMgr.h" +#include "TCSoap.h" +#include "CliRunnable.h" +#include "SystemConfig.h" -#include "Log.h" -#include "Master.h" - -#ifndef _TRINITY_CORE_CONFIG -# define _TRINITY_CORE_CONFIG "worldserver.conf" -#endif +#define TRINITY_CORE_CONFIG "worldserver.conf" +#define WORLD_SLEEP_CONST 50 #ifdef _WIN32 #include "ServiceWin32.h" @@ -48,31 +61,26 @@ char serviceDescription[] = "TrinityCore World of Warcraft emulator world servic int m_ServiceStatus = -1; #endif +boost::asio::io_service _ioService; WorldDatabaseWorkerPool WorldDatabase; ///< Accessor to the world database CharacterDatabaseWorkerPool CharacterDatabase; ///< Accessor to the character database LoginDatabaseWorkerPool LoginDatabase; ///< Accessor to the realm/login database - uint32 realmID; ///< Id of the realm -/// Print out the usage string for this program on the console. -void usage(const char* prog) -{ - printf("Usage:\n"); - printf(" %s []\n", prog); - printf(" -c config_file use config_file as configuration file\n"); -#ifdef _WIN32 - printf(" Running as service functions:\n"); - printf(" --service run as service\n"); - printf(" -s install install service\n"); - printf(" -s uninstall uninstall service\n"); -#endif -} +void usage(const char* prog); +void SignalHandler(const boost::system::error_code& error, int signalNumber); +void FreezeDetectorThread(uint32 delayTime); +AsyncAcceptor* StartRaSocketAcceptor(boost::asio::io_service& ioService); +bool StartDB(); +void StopDB(); +void WorldUpdateLoop(); +void ClearOnlineAccounts(); /// Launch the Trinity server extern int main(int argc, char** argv) { ///- Command line parsing to get the configuration file name - char const* cfg_file = _TRINITY_CORE_CONFIG; + char const* cfg_file = TRINITY_CORE_CONFIG; int c = 1; while (c < argc) { @@ -131,21 +139,442 @@ extern int main(int argc, char** argv) return 1; } + TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon)", _FULLVERSION); + TC_LOG_INFO("server.worldserver", " to stop.\n"); + TC_LOG_INFO("server.worldserver", " ______ __"); + TC_LOG_INFO("server.worldserver", "/\\__ _\\ __ __/\\ \\__"); + TC_LOG_INFO("server.worldserver", "\\/_/\\ \\/ _ __ /\\_\\ ___ /\\_\\ \\, _\\ __ __"); + TC_LOG_INFO("server.worldserver", " \\ \\ \\/\\`'__\\/\\ \\ /' _ `\\/\\ \\ \\ \\/ /\\ \\/\\ \\"); + TC_LOG_INFO("server.worldserver", " \\ \\ \\ \\ \\/ \\ \\ \\/\\ \\/\\ \\ \\ \\ \\ \\_\\ \\ \\_\\ \\"); + TC_LOG_INFO("server.worldserver", " \\ \\_\\ \\_\\ \\ \\_\\ \\_\\ \\_\\ \\_\\ \\__\\\\/`____ \\"); + TC_LOG_INFO("server.worldserver", " \\/_/\\/_/ \\/_/\\/_/\\/_/\\/_/\\/__/ `/___/> \\"); + TC_LOG_INFO("server.worldserver", " C O R E /\\___/"); + TC_LOG_INFO("server.worldserver", "http://TrinityCore.org \\/__/\n"); TC_LOG_INFO("server.worldserver", "Using configuration file %s.", cfg_file); - TC_LOG_INFO("server.worldserver", "Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); - TC_LOG_INFO("server.worldserver", "Using Boost version: %s", BOOST_LIB_VERSION); + TC_LOG_INFO("server.worldserver", "Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); + + OpenSSLCrypto::threadsSetup(); + BigNumber seed1; + seed1.SetRand(16 * 8); + + /// worldserver PID file creation + std::string pidFile = sConfigMgr->GetStringDefault("PidFile", ""); + if (!pidFile.empty()) + { + if (uint32 pid = CreatePIDFile(pidFile)) + TC_LOG_INFO("server.worldserver", "Daemon PID: %u\n", pid); + else + { + TC_LOG_ERROR("server.worldserver", "Cannot create PID file %s.\n", pidFile.c_str()); + return 1; + } + } + + // Set signal handlers (this must be done before starting io_service threads, because otherwise they would unblock and exit) + boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM); + signals.async_wait(SignalHandler); + + // Start the Boost based thread pool + int numThreads = sConfigMgr->GetIntDefault("ThreadPool", 1); + std::vector threadPool; + + if (numThreads < 1) + numThreads = 1; + + for (int i = 0; i < numThreads; ++i) + threadPool.push_back(std::thread(boost::bind(&boost::asio::io_service::run, &_ioService))); + + // Set process priority according to configuration settings + SetProcessPriority("server.worldserver"); + + // Start the databases + if (!StartDB()) + return 1; + + // Set server offline (not connectable) + LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID); + + // Initialize the World + sWorld->SetInitialWorldSettings(); + + // Launch CliRunnable thread + std::thread* cliThread = nullptr; +#ifdef _WIN32 + if (sConfigMgr->GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/) +#else + if (sConfigMgr->GetBoolDefault("Console.Enable", true)) +#endif + { + cliThread = new std::thread(CliThread); + } + + // Start the Remote Access port (acceptor) if enabled + AsyncAcceptor* raAcceptor = nullptr; + if (sConfigMgr->GetBoolDefault("Ra.Enable", false)) + raAcceptor = StartRaSocketAcceptor(_ioService); + + // Start soap serving thread if enabled + std::thread* soapThread = nullptr; + if (sConfigMgr->GetBoolDefault("SOAP.Enabled", false)) + { + soapThread = new std::thread(TCSoapThread, sConfigMgr->GetStringDefault("SOAP.IP", "127.0.0.1"), uint16(sConfigMgr->GetIntDefault("SOAP.Port", 7878))); + } + + // Start up freeze catcher thread + std::thread* freezeDetectorThread = nullptr; + if (uint32 freezeDelay = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0)) + freezeDetectorThread = new std::thread(FreezeDetectorThread, freezeDelay); + + // Launch the worldserver listener socket + uint16 worldPort = uint16(sWorld->getIntConfig(CONFIG_PORT_WORLD)); + std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0"); + + if (sWorldSocketMgr->StartNetwork(worldPort, bindIp.c_str()) == -1) + { + TC_LOG_ERROR("server.worldserver", "Failed to start network"); + return ERROR_EXIT_CODE; + } - ///- and run the 'Master' - /// @todo Why do we need this 'Master'? Can't all of this be in the Main as for Realmd? - int ret = sMaster->Run(); + // Set server online (allow connecting now) + LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID); + + TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon) ready...", _FULLVERSION); + + sScriptMgr->OnStartup(); + + WorldUpdateLoop(); + + // Shutdown starts here + + _ioService.stop(); + + for (auto& thread : threadPool) + { + thread.join(); + } + + sScriptMgr->OnShutdown(); + + sWorld->KickAll(); // save and kick all players + sWorld->UpdateSessions(1); // real players unload required UpdateSessions call + + // unload battleground templates before different singletons destroyed + sBattlegroundMgr->DeleteAllBattlegrounds(); + + sWorldSocketMgr->StopNetwork(); + + sMapMgr->UnloadAll(); // unload all grids (including locked in memory) + sObjectAccessor->UnloadAll(); // unload 'i_player2corpse' storage and remove from world + sScriptMgr->Unload(); + sOutdoorPvPMgr->Die(); + + // set server offline + LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID); + + // Clean up threads if any + if (soapThread != nullptr) + { + soapThread->join(); + delete soapThread; + } + + if (raAcceptor != nullptr) + delete raAcceptor; + + ///- Clean database before leaving + ClearOnlineAccounts(); + + StopDB(); + + TC_LOG_INFO("server.worldserver", "Halting process..."); + + if (cliThread != nullptr) + { +#ifdef _WIN32 + + // this only way to terminate CLI thread exist at Win32 (alt. way exist only in Windows Vista API) + //_exit(1); + // send keyboard input to safely unblock the CLI thread + INPUT_RECORD b[4]; + HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); + b[0].EventType = KEY_EVENT; + b[0].Event.KeyEvent.bKeyDown = TRUE; + b[0].Event.KeyEvent.uChar.AsciiChar = 'X'; + b[0].Event.KeyEvent.wVirtualKeyCode = 'X'; + b[0].Event.KeyEvent.wRepeatCount = 1; + + b[1].EventType = KEY_EVENT; + b[1].Event.KeyEvent.bKeyDown = FALSE; + b[1].Event.KeyEvent.uChar.AsciiChar = 'X'; + b[1].Event.KeyEvent.wVirtualKeyCode = 'X'; + b[1].Event.KeyEvent.wRepeatCount = 1; + + b[2].EventType = KEY_EVENT; + b[2].Event.KeyEvent.bKeyDown = TRUE; + b[2].Event.KeyEvent.dwControlKeyState = 0; + b[2].Event.KeyEvent.uChar.AsciiChar = '\r'; + b[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; + b[2].Event.KeyEvent.wRepeatCount = 1; + b[2].Event.KeyEvent.wVirtualScanCode = 0x1c; + + b[3].EventType = KEY_EVENT; + b[3].Event.KeyEvent.bKeyDown = FALSE; + b[3].Event.KeyEvent.dwControlKeyState = 0; + b[3].Event.KeyEvent.uChar.AsciiChar = '\r'; + b[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; + b[3].Event.KeyEvent.wVirtualScanCode = 0x1c; + b[3].Event.KeyEvent.wRepeatCount = 1; + DWORD numb; + WriteConsoleInput(hStdIn, b, 4, &numb); + + cliThread->join(); + +#endif + + delete cliThread; + } + + delete freezeDetectorThread; + + OpenSSLCrypto::threadsCleanup(); - // at sMaster return function exist with codes // 0 - normal shutdown // 1 - shutdown at error // 2 - restart command used, this code can be used by restarter for restart Trinityd - return ret; + return World::GetExitCode(); +} + + +void WorldUpdateLoop() +{ + uint32 realCurrTime = 0; + uint32 realPrevTime = getMSTime(); + + 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 (!World::IsStopped()) + { + ++World::m_worldLoopCounter; + realCurrTime = getMSTime(); + + uint32 diff = getMSTimeDiff(realPrevTime, realCurrTime); + + sWorld->Update(diff); + realPrevTime = realCurrTime; + + // diff (D0) include time of previous sleep (d0) + tick time (t0) + // we want that next d1 + t1 == WORLD_SLEEP_CONST + // we can't know next t1 and then can use (t0 + d1) == WORLD_SLEEP_CONST requirement + // d1 = WORLD_SLEEP_CONST - t0 = WORLD_SLEEP_CONST - (D0 - d0) = WORLD_SLEEP_CONST + d0 - D0 + if (diff <= WORLD_SLEEP_CONST + prevSleepTime) + { + prevSleepTime = WORLD_SLEEP_CONST + prevSleepTime - diff; + + std::this_thread::sleep_for(std::chrono::milliseconds(prevSleepTime)); + } + else + prevSleepTime = 0; + +#ifdef _WIN32 + if (m_ServiceStatus == 0) + World::StopNow(SHUTDOWN_EXIT_CODE); + + while (m_ServiceStatus == 2) + Sleep(1000); +#endif + } +} + +/// Print out the usage string for this program on the console. +void usage(const char* prog) +{ + printf("Usage:\n"); + printf(" %s []\n", prog); + printf(" -c config_file use config_file as configuration file\n"); +#ifdef _WIN32 + printf(" Running as service functions:\n"); + printf(" --service run as service\n"); + printf(" -s install install service\n"); + printf(" -s uninstall uninstall service\n"); +#endif +} + +void SignalHandler(const boost::system::error_code& error, int signalNumber) +{ + if (!error) + { + switch (signalNumber) + { + case SIGINT: + case SIGTERM: + World::StopNow(SHUTDOWN_EXIT_CODE); + break; + } + } +} + +void FreezeDetectorThread(uint32 delayTime) +{ + if (!delayTime) + return; + + TC_LOG_INFO("server.worldserver", "Starting up anti-freeze thread (%u seconds max stuck time)...", delayTime / 1000); + uint32 loops = 0; + uint32 lastChange = 0; + + while (!World::IsStopped()) + { + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + uint32 curtime = getMSTime(); + // normal work + uint32 worldLoopCounter = World::m_worldLoopCounter; + if (loops != worldLoopCounter) + { + lastChange = curtime; + loops = worldLoopCounter; + } + // possible freeze + else if (getMSTimeDiff(lastChange, curtime) > delayTime) + { + TC_LOG_ERROR("server.worldserver", "World Thread hangs, kicking out server!"); + ASSERT(false); + } + } + TC_LOG_INFO("server.worldserver", "Anti-freeze thread exiting without problems."); +} + +AsyncAcceptor* StartRaSocketAcceptor(boost::asio::io_service& ioService) +{ + uint16 raPort = uint16(sConfigMgr->GetIntDefault("Ra.Port", 3443)); + std::string raListener = sConfigMgr->GetStringDefault("Ra.IP", "0.0.0.0"); + + return new AsyncAcceptor(ioService, raListener, raPort); +} + +/// Initialize connection to the databases +bool StartDB() +{ + MySQL::Library_Init(); + + std::string dbString; + uint8 asyncThreads, synchThreads; + + dbString = sConfigMgr->GetStringDefault("WorldDatabaseInfo", ""); + if (dbString.empty()) + { + TC_LOG_ERROR("server.worldserver", "World database not specified in configuration file"); + return false; + } + + asyncThreads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.WorkerThreads", 1)); + if (asyncThreads < 1 || asyncThreads > 32) + { + TC_LOG_ERROR("server.worldserver", "World database: invalid number of worker threads specified. " + "Please pick a value between 1 and 32."); + return false; + } + + synchThreads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.SynchThreads", 1)); + ///- Initialize the world database + if (!WorldDatabase.Open(dbString, asyncThreads, synchThreads)) + { + TC_LOG_ERROR("server.worldserver", "Cannot connect to world database %s", dbString.c_str()); + return false; + } + + ///- Get character database info from configuration file + dbString = sConfigMgr->GetStringDefault("CharacterDatabaseInfo", ""); + if (dbString.empty()) + { + TC_LOG_ERROR("server.worldserver", "Character database not specified in configuration file"); + return false; + } + + asyncThreads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.WorkerThreads", 1)); + if (asyncThreads < 1 || asyncThreads > 32) + { + TC_LOG_ERROR("server.worldserver", "Character database: invalid number of worker threads specified. " + "Please pick a value between 1 and 32."); + return false; + } + + synchThreads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.SynchThreads", 2)); + + ///- Initialize the Character database + if (!CharacterDatabase.Open(dbString, asyncThreads, synchThreads)) + { + TC_LOG_ERROR("server.worldserver", "Cannot connect to Character database %s", dbString.c_str()); + return false; + } + + ///- Get login database info from configuration file + dbString = sConfigMgr->GetStringDefault("LoginDatabaseInfo", ""); + if (dbString.empty()) + { + TC_LOG_ERROR("server.worldserver", "Login database not specified in configuration file"); + return false; + } + + asyncThreads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.WorkerThreads", 1)); + if (asyncThreads < 1 || asyncThreads > 32) + { + TC_LOG_ERROR("server.worldserver", "Login database: invalid number of worker threads specified. " + "Please pick a value between 1 and 32."); + return false; + } + + synchThreads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.SynchThreads", 1)); + ///- Initialise the login database + if (!LoginDatabase.Open(dbString, asyncThreads, synchThreads)) + { + TC_LOG_ERROR("server.worldserver", "Cannot connect to login database %s", dbString.c_str()); + return false; + } + + ///- Get the realm Id from the configuration file + realmID = sConfigMgr->GetIntDefault("RealmID", 0); + if (!realmID) + { + TC_LOG_ERROR("server.worldserver", "Realm ID not defined in configuration file"); + return false; + } + TC_LOG_INFO("server.worldserver", "Realm running as realm ID %d", realmID); + + ///- Clean the database before starting + ClearOnlineAccounts(); + + ///- Insert version info into DB + WorldDatabase.PExecute("UPDATE version SET core_version = '%s', core_revision = '%s'", _FULLVERSION, _HASH); // One-time query + + sWorld->LoadDBVersion(); + + TC_LOG_INFO("server.worldserver", "Using World DB: %s", sWorld->GetDBVersion()); + return true; +} + +void StopDB() +{ + CharacterDatabase.Close(); + WorldDatabase.Close(); + LoginDatabase.Close(); + + MySQL::Library_End(); +} + +/// Clear 'online' status for all accounts with characters in this realm +void ClearOnlineAccounts() +{ + // Reset online status for all accounts with characters on the current realm + LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = %d)", realmID); + + // Reset online status for all characters + CharacterDatabase.DirectExecute("UPDATE characters SET online = 0 WHERE online <> 0"); + + // Battleground instance ids reset at server restart + CharacterDatabase.DirectExecute("UPDATE character_battleground_data SET instanceId = 0"); } /// @} diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp deleted file mode 100644 index c529e6b6478..00000000000 --- a/src/server/worldserver/Master.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -/** \file - \ingroup Trinityd -*/ - -#include - -#include "Master.h" - -#include "SystemConfig.h" -#include "World.h" -#include "WorldRunnable.h" -#include "WorldSocket.h" -#include "WorldSocketMgr.h" -#include "Configuration/Config.h" -#include "Database/DatabaseEnv.h" -#include "Database/DatabaseWorkerPool.h" -#include "CliRunnable.h" -#include "Log.h" -#include "TCSoap.h" -#include "Timer.h" -#include "Util.h" -#include "RealmList.h" -#include "BigNumber.h" -#include "OpenSSLCrypto.h" -#include "AsyncAcceptor.h" - -#ifdef _WIN32 -#include "ServiceWin32.h" -extern int m_ServiceStatus; -#endif - -#ifdef __linux__ -#include -#include -#define PROCESS_HIGH_PRIORITY -15 // [-20, 19], default is 0 -#endif - -boost::asio::io_service _ioService; - -void SignalHandler(const boost::system::error_code& error, int signalNumber) -{ - if (!error) - { - switch (signalNumber) - { - case SIGINT: - case SIGTERM: - _ioService.stop(); - break; - } - } -} - - -void FreezeDetectorThread(uint32 delayTime) -{ - if (!delayTime) - return; - - TC_LOG_INFO("server.worldserver", "Starting up anti-freeze thread (%u seconds max stuck time)...", delayTime / 1000); - uint32 loops = 0; - uint32 lastChange = 0; - - while (!World::IsStopped()) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - uint32 curtime = getMSTime(); - // normal work - uint32 worldLoopCounter = World::m_worldLoopCounter; - if (loops != worldLoopCounter) - { - lastChange = curtime; - loops = worldLoopCounter; - } - // possible freeze - else if (getMSTimeDiff(lastChange, curtime) > delayTime) - { - TC_LOG_ERROR("server.worldserver", "World Thread hangs, kicking out server!"); - ASSERT(false); - } - } - TC_LOG_INFO("server.worldserver", "Anti-freeze thread exiting without problems."); -} - -/// Main function -int Master::Run() -{ - OpenSSLCrypto::threadsSetup(); - BigNumber seed1; - seed1.SetRand(16 * 8); - - TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon)", _FULLVERSION); - TC_LOG_INFO("server.worldserver", " to stop.\n"); - - TC_LOG_INFO("server.worldserver", " ______ __"); - TC_LOG_INFO("server.worldserver", "/\\__ _\\ __ __/\\ \\__"); - TC_LOG_INFO("server.worldserver", "\\/_/\\ \\/ _ __ /\\_\\ ___ /\\_\\ \\, _\\ __ __"); - TC_LOG_INFO("server.worldserver", " \\ \\ \\/\\`'__\\/\\ \\ /' _ `\\/\\ \\ \\ \\/ /\\ \\/\\ \\"); - TC_LOG_INFO("server.worldserver", " \\ \\ \\ \\ \\/ \\ \\ \\/\\ \\/\\ \\ \\ \\ \\ \\_\\ \\ \\_\\ \\"); - TC_LOG_INFO("server.worldserver", " \\ \\_\\ \\_\\ \\ \\_\\ \\_\\ \\_\\ \\_\\ \\__\\\\/`____ \\"); - TC_LOG_INFO("server.worldserver", " \\/_/\\/_/ \\/_/\\/_/\\/_/\\/_/\\/__/ `/___/> \\"); - TC_LOG_INFO("server.worldserver", " C O R E /\\___/"); - TC_LOG_INFO("server.worldserver", "http://TrinityCore.org \\/__/\n"); - - /// worldserver PID file creation - std::string pidFile = sConfigMgr->GetStringDefault("PidFile", ""); - if (!pidFile.empty()) - { - if (uint32 pid = CreatePIDFile(pidFile)) - TC_LOG_INFO("server.worldserver", "Daemon PID: %u\n", pid); - else - { - TC_LOG_ERROR("server.worldserver", "Cannot create PID file %s.\n", pidFile.c_str()); - return 1; - } - } - - ///- Start the databases - if (!_StartDB()) - return 1; - - // set server offline (not connectable) - LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID); - - ///- Initialize the World - sWorld->SetInitialWorldSettings(); - - // Set signal handlers - boost::asio::signal_set signals(_ioService, SIGINT, SIGTERM); - signals.async_wait(SignalHandler); - - ///- Launch WorldRunnable thread - std::thread worldThread(WorldThread, std::ref(_ioService)); - - std::thread* cliThread = nullptr; - -#ifdef _WIN32 - if (sConfigMgr->GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/) -#else - if (sConfigMgr->GetBoolDefault("Console.Enable", true)) -#endif - { - ///- Launch CliRunnable thread - cliThread = new std::thread(CliThread); - } - - AsyncAcceptor* raAcceptor = nullptr; - - if (sConfigMgr->GetBoolDefault("Ra.Enable", false)) - raAcceptor = StartRaSocketAcceptor(_ioService); - -#if defined(_WIN32) || defined(__linux__) - - ///- Handle affinity for multiple processors and process priority - uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0); - bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false); - -#ifdef _WIN32 // Windows - - HANDLE hProcess = GetCurrentProcess(); - - if (affinity > 0) - { - ULONG_PTR appAff; - ULONG_PTR sysAff; - - if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) - { - ULONG_PTR currentAffinity = affinity & appAff; // remove non accessible processors - - if (!currentAffinity) - TC_LOG_ERROR("server.worldserver", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the worldserver. Accessible processors bitmask (hex): %x", affinity, appAff); - else if (SetProcessAffinityMask(hProcess, currentAffinity)) - TC_LOG_INFO("server.worldserver", "Using processors (bitmask, hex): %x", currentAffinity); - else - TC_LOG_ERROR("server.worldserver", "Can't set used processors (hex): %x", currentAffinity); - } - } - - if (highPriority) - { - if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) - TC_LOG_INFO("server.worldserver", "worldserver process priority class set to HIGH"); - else - TC_LOG_ERROR("server.worldserver", "Can't set worldserver process priority class."); - } - -#else // Linux - - if (affinity > 0) - { - cpu_set_t mask; - CPU_ZERO(&mask); - - for (unsigned int i = 0; i < sizeof(affinity) * 8; ++i) - if (affinity & (1 << i)) - CPU_SET(i, &mask); - - if (sched_setaffinity(0, sizeof(mask), &mask)) - TC_LOG_ERROR("server.worldserver", "Can't set used processors (hex): %x, error: %s", affinity, strerror(errno)); - else - { - CPU_ZERO(&mask); - sched_getaffinity(0, sizeof(mask), &mask); - TC_LOG_INFO("server.worldserver", "Using processors (bitmask, hex): %lx", *(__cpu_mask*)(&mask)); - } - } - - if (highPriority) - { - if (setpriority(PRIO_PROCESS, 0, PROCESS_HIGH_PRIORITY)) - TC_LOG_ERROR("server.worldserver", "Can't set worldserver process priority class, error: %s", strerror(errno)); - else - TC_LOG_INFO("server.worldserver", "worldserver process priority class set to %i", getpriority(PRIO_PROCESS, 0)); - } - -#endif -#endif - - //Start soap serving thread - std::thread* soapThread = nullptr; - - if (sConfigMgr->GetBoolDefault("SOAP.Enabled", false)) - { - soapThread = new std::thread(TCSoapThread, sConfigMgr->GetStringDefault("SOAP.IP", "127.0.0.1"), uint16(sConfigMgr->GetIntDefault("SOAP.Port", 7878))); - } - - std::thread* freezeDetectorThread = nullptr; - - ///- Start up freeze catcher thread - if (uint32 freezeDelay = sConfigMgr->GetIntDefault("MaxCoreStuckTime", 0)) - freezeDetectorThread = new std::thread(FreezeDetectorThread, freezeDelay); - - ///- Launch the world listener socket - uint16 worldPort = uint16(sWorld->getIntConfig(CONFIG_PORT_WORLD)); - std::string bindIp = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0"); - - if (sWorldSocketMgr->StartNetwork(worldPort, bindIp.c_str()) == -1) - { - TC_LOG_ERROR("server.worldserver", "Failed to start network"); - World::StopNow(ERROR_EXIT_CODE); - // go down and shutdown the server - } - - // set server online (allow connecting now) - LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID); - - TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon) ready...", _FULLVERSION); - - _ioService.run(); - - // when the main thread closes the singletons get unloaded - // since worldrunnable uses them, it will crash if unloaded after master - worldThread.join(); - - if (soapThread != nullptr) - { - soapThread->join(); - delete soapThread; - } - - if (raAcceptor != nullptr) - delete raAcceptor; - - // set server offline - LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID); - - ///- Clean database before leaving - ClearOnlineAccounts(); - - _StopDB(); - - TC_LOG_INFO("server.worldserver", "Halting process..."); - - if (cliThread != nullptr) - { - #ifdef _WIN32 - - // this only way to terminate CLI thread exist at Win32 (alt. way exist only in Windows Vista API) - //_exit(1); - // send keyboard input to safely unblock the CLI thread - INPUT_RECORD b[4]; - HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); - b[0].EventType = KEY_EVENT; - b[0].Event.KeyEvent.bKeyDown = TRUE; - b[0].Event.KeyEvent.uChar.AsciiChar = 'X'; - b[0].Event.KeyEvent.wVirtualKeyCode = 'X'; - b[0].Event.KeyEvent.wRepeatCount = 1; - - b[1].EventType = KEY_EVENT; - b[1].Event.KeyEvent.bKeyDown = FALSE; - b[1].Event.KeyEvent.uChar.AsciiChar = 'X'; - b[1].Event.KeyEvent.wVirtualKeyCode = 'X'; - b[1].Event.KeyEvent.wRepeatCount = 1; - - b[2].EventType = KEY_EVENT; - b[2].Event.KeyEvent.bKeyDown = TRUE; - b[2].Event.KeyEvent.dwControlKeyState = 0; - b[2].Event.KeyEvent.uChar.AsciiChar = '\r'; - b[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; - b[2].Event.KeyEvent.wRepeatCount = 1; - b[2].Event.KeyEvent.wVirtualScanCode = 0x1c; - - b[3].EventType = KEY_EVENT; - b[3].Event.KeyEvent.bKeyDown = FALSE; - b[3].Event.KeyEvent.dwControlKeyState = 0; - b[3].Event.KeyEvent.uChar.AsciiChar = '\r'; - b[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; - b[3].Event.KeyEvent.wVirtualScanCode = 0x1c; - b[3].Event.KeyEvent.wRepeatCount = 1; - DWORD numb; - WriteConsoleInput(hStdIn, b, 4, &numb); - - cliThread->join(); - - #endif - - delete cliThread; - } - - delete freezeDetectorThread; - - // for some unknown reason, unloading scripts here and not in worldrunnable - // fixes a memory leak related to detaching threads from the module - //UnloadScriptingModule(); - - OpenSSLCrypto::threadsCleanup(); - // Exit the process with specified return value - return World::GetExitCode(); -} - -/// Initialize connection to the databases -bool Master::_StartDB() -{ - MySQL::Library_Init(); - - std::string dbString; - uint8 asyncThreads, synchThreads; - - dbString = sConfigMgr->GetStringDefault("WorldDatabaseInfo", ""); - if (dbString.empty()) - { - TC_LOG_ERROR("server.worldserver", "World database not specified in configuration file"); - return false; - } - - asyncThreads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.WorkerThreads", 1)); - if (asyncThreads < 1 || asyncThreads > 32) - { - TC_LOG_ERROR("server.worldserver", "World database: invalid number of worker threads specified. " - "Please pick a value between 1 and 32."); - return false; - } - - synchThreads = uint8(sConfigMgr->GetIntDefault("WorldDatabase.SynchThreads", 1)); - ///- Initialize the world database - if (!WorldDatabase.Open(dbString, asyncThreads, synchThreads)) - { - TC_LOG_ERROR("server.worldserver", "Cannot connect to world database %s", dbString.c_str()); - return false; - } - - ///- Get character database info from configuration file - dbString = sConfigMgr->GetStringDefault("CharacterDatabaseInfo", ""); - if (dbString.empty()) - { - TC_LOG_ERROR("server.worldserver", "Character database not specified in configuration file"); - return false; - } - - asyncThreads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.WorkerThreads", 1)); - if (asyncThreads < 1 || asyncThreads > 32) - { - TC_LOG_ERROR("server.worldserver", "Character database: invalid number of worker threads specified. " - "Please pick a value between 1 and 32."); - return false; - } - - synchThreads = uint8(sConfigMgr->GetIntDefault("CharacterDatabase.SynchThreads", 2)); - - ///- Initialize the Character database - if (!CharacterDatabase.Open(dbString, asyncThreads, synchThreads)) - { - TC_LOG_ERROR("server.worldserver", "Cannot connect to Character database %s", dbString.c_str()); - return false; - } - - ///- Get login database info from configuration file - dbString = sConfigMgr->GetStringDefault("LoginDatabaseInfo", ""); - if (dbString.empty()) - { - TC_LOG_ERROR("server.worldserver", "Login database not specified in configuration file"); - return false; - } - - asyncThreads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.WorkerThreads", 1)); - if (asyncThreads < 1 || asyncThreads > 32) - { - TC_LOG_ERROR("server.worldserver", "Login database: invalid number of worker threads specified. " - "Please pick a value between 1 and 32."); - return false; - } - - synchThreads = uint8(sConfigMgr->GetIntDefault("LoginDatabase.SynchThreads", 1)); - ///- Initialise the login database - if (!LoginDatabase.Open(dbString, asyncThreads, synchThreads)) - { - TC_LOG_ERROR("server.worldserver", "Cannot connect to login database %s", dbString.c_str()); - return false; - } - - ///- Get the realm Id from the configuration file - realmID = sConfigMgr->GetIntDefault("RealmID", 0); - if (!realmID) - { - TC_LOG_ERROR("server.worldserver", "Realm ID not defined in configuration file"); - return false; - } - TC_LOG_INFO("server.worldserver", "Realm running as realm ID %d", realmID); - - ///- Clean the database before starting - ClearOnlineAccounts(); - - ///- Insert version info into DB - WorldDatabase.PExecute("UPDATE version SET core_version = '%s', core_revision = '%s'", _FULLVERSION, _HASH); // One-time query - - sWorld->LoadDBVersion(); - - TC_LOG_INFO("server.worldserver", "Using World DB: %s", sWorld->GetDBVersion()); - return true; -} - -void Master::_StopDB() -{ - CharacterDatabase.Close(); - WorldDatabase.Close(); - LoginDatabase.Close(); - - MySQL::Library_End(); -} - -/// Clear 'online' status for all accounts with characters in this realm -void Master::ClearOnlineAccounts() -{ - // Reset online status for all accounts with characters on the current realm - LoginDatabase.DirectPExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = %d)", realmID); - - // Reset online status for all characters - CharacterDatabase.DirectExecute("UPDATE characters SET online = 0 WHERE online <> 0"); - - // Battleground instance ids reset at server restart - CharacterDatabase.DirectExecute("UPDATE character_battleground_data SET instanceId = 0"); -} - -AsyncAcceptor* Master::StartRaSocketAcceptor(boost::asio::io_service& ioService) -{ - uint16 raPort = uint16(sConfigMgr->GetIntDefault("Ra.Port", 3443)); - std::string raListener = sConfigMgr->GetStringDefault("Ra.IP", "0.0.0.0"); - - return new AsyncAcceptor(ioService, raListener, raPort); -} diff --git a/src/server/worldserver/Master.h b/src/server/worldserver/Master.h deleted file mode 100644 index 86059e6417a..00000000000 --- a/src/server/worldserver/Master.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -/// \addtogroup Trinityd -/// @{ -/// \file - -#ifndef _MASTER_H -#define _MASTER_H - -#include -#include "Common.h" -#include "RASession.h" - -template -class AsyncAcceptor; - -/// Start the server -class Master -{ - public: - static Master* instance() - { - static Master* instance = new Master(); - return instance; - } - - int Run(); - - private: - bool _StartDB(); - void _StopDB(); - - void ClearOnlineAccounts(); - AsyncAcceptor* StartRaSocketAcceptor(boost::asio::io_service& ioService); -}; - -#define sMaster Master::instance() - -#endif - -/// @} diff --git a/src/server/worldserver/WorldThread/WorldRunnable.cpp b/src/server/worldserver/WorldThread/WorldRunnable.cpp deleted file mode 100644 index 85c3e7a74b9..00000000000 --- a/src/server/worldserver/WorldThread/WorldRunnable.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -/** \file - \ingroup Trinityd -*/ - -#include - -#include "Common.h" -#include "ObjectAccessor.h" -#include "World.h" -#include "WorldSocketMgr.h" -#include "Database/DatabaseEnv.h" -#include "ScriptMgr.h" -#include "BattlegroundMgr.h" -#include "MapManager.h" -#include "Timer.h" -#include "WorldRunnable.h" -#include "OutdoorPvPMgr.h" - -#define WORLD_SLEEP_CONST 50 - -#ifdef _WIN32 -#include "ServiceWin32.h" -extern int m_ServiceStatus; -#endif - -/// Heartbeat for the World -void WorldThread(boost::asio::io_service& ioService) -{ - uint32 realCurrTime = 0; - uint32 realPrevTime = getMSTime(); - - uint32 prevSleepTime = 0; // used for balanced full tick time length near WORLD_SLEEP_CONST - - sScriptMgr->OnStartup(); - - ///- While we have not World::m_stopEvent, update the world - while (!World::IsStopped()) - { - ++World::m_worldLoopCounter; - realCurrTime = getMSTime(); - - uint32 diff = getMSTimeDiff(realPrevTime, realCurrTime); - - sWorld->Update( diff ); - realPrevTime = realCurrTime; - - // diff (D0) include time of previous sleep (d0) + tick time (t0) - // we want that next d1 + t1 == WORLD_SLEEP_CONST - // we can't know next t1 and then can use (t0 + d1) == WORLD_SLEEP_CONST requirement - // d1 = WORLD_SLEEP_CONST - t0 = WORLD_SLEEP_CONST - (D0 - d0) = WORLD_SLEEP_CONST + d0 - D0 - if (diff <= WORLD_SLEEP_CONST+prevSleepTime) - { - prevSleepTime = WORLD_SLEEP_CONST+prevSleepTime-diff; - - std::this_thread::sleep_for(std::chrono::milliseconds(prevSleepTime)); - } - else - prevSleepTime = 0; - - #ifdef _WIN32 - if (m_ServiceStatus == 0) - World::StopNow(SHUTDOWN_EXIT_CODE); - - while (m_ServiceStatus == 2) - Sleep(1000); - #endif - } - - ioService.stop(); - - sScriptMgr->OnShutdown(); - - sWorld->KickAll(); // save and kick all players - sWorld->UpdateSessions( 1 ); // real players unload required UpdateSessions call - - // unload battleground templates before different singletons destroyed - sBattlegroundMgr->DeleteAllBattlegrounds(); - - sWorldSocketMgr->StopNetwork(); - - sMapMgr->UnloadAll(); // unload all grids (including locked in memory) - sObjectAccessor->UnloadAll(); // unload 'i_player2corpse' storage and remove from world - sScriptMgr->Unload(); - sOutdoorPvPMgr->Die(); -} diff --git a/src/server/worldserver/WorldThread/WorldRunnable.h b/src/server/worldserver/WorldThread/WorldRunnable.h deleted file mode 100644 index c6d00d269e7..00000000000 --- a/src/server/worldserver/WorldThread/WorldRunnable.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -/// \addtogroup Trinityd -/// @{ -/// \file - -#ifndef __WORLDRUNNABLE_H -#define __WORLDRUNNABLE_H - -#include - -void WorldThread(boost::asio::io_service& ioService); - -#endif - -/// @} diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 90f330bac42..c4e3ad832a7 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -143,6 +143,14 @@ WorldServerPort = 8085 BindIP = "0.0.0.0" +# +# ThreadPool +# Description: Number of threads to be used for the global thread pool +# The thread pool is currently used for the signal handler and remote access +# Default: 1 + +ThreadPool = 1 + # ################################################################################################### @@ -161,7 +169,8 @@ UseProcessors = 0 # # ProcessPriority # Description: Process priority setting for Windows and Linux based systems. -# Details: On Linux, a nice value of -15 is used. (requires superuser). On Windows, process is set to HIGH class. +# Details: On Linux, a nice value of -15 is used. (requires superuser). +# On Windows, process is set to HIGH class. # Default: 0 - (Normal) # 1 - (High) @@ -1069,7 +1078,8 @@ Account.PasswordChangeSecurity = 0 # # BirthdayTime -# Description: Set to date of project's birth in UNIX time. By default the date when TrinityCore was started (Thu Oct 2, 2008) +# Description: Set to date of project's birth in UNIX time. By default the date when +# TrinityCore was started (Thu Oct 2, 2008) # Default: 1222964635 # # @@ -2627,8 +2637,10 @@ UI.ShowQuestLevelsInDialogs = 0 # 1 - Prefix Timestamp to the text # 2 - Prefix Log Level to the text # 4 - Prefix Log Filter type to the text -# 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS (Only used with Type = 2) -# 16 - Make a backup of existing file before overwrite (Only used with Mode = w) +# 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS +# (Only used with Type = 2) +# 16 - Make a backup of existing file before overwrite +# (Only used with Mode = w) # # Colors (read as optional1 if Type = Console) # Format: "fatal error warn info debug trace" @@ -2744,7 +2756,8 @@ Log.Async.Enable = 0 # # Allow.IP.Based.Action.Logging -# Description: Logs actions, e.g. account login and logout to name a few, based on IP of current session. +# Description: Logs actions, e.g. account login and logout to name a few, based on IP of +# current session. # Default: 0 - (Disabled) # 1 - (Enabled) -- cgit v1.2.3