diff options
Diffstat (limited to 'src/server/shared')
| -rw-r--r-- | src/server/shared/CMakeLists.txt | 90 | ||||
| -rw-r--r-- | src/server/shared/DataStores/DBCFileLoader.h | 2 | ||||
| -rw-r--r-- | src/server/shared/Networking/AsyncAcceptor.h | 41 | ||||
| -rw-r--r-- | src/server/shared/Networking/MessageBuffer.h | 138 | ||||
| -rw-r--r-- | src/server/shared/Networking/NetworkThread.h | 84 | ||||
| -rw-r--r-- | src/server/shared/Networking/Socket.h | 103 | ||||
| -rw-r--r-- | src/server/shared/Networking/SocketMgr.h | 49 | ||||
| -rw-r--r-- | src/server/shared/Packets/ByteBuffer.h | 29 | ||||
| -rw-r--r-- | src/server/shared/Realm/Realm.cpp | 53 | ||||
| -rw-r--r-- | src/server/shared/Realm/Realm.h | 87 | ||||
| -rw-r--r-- | src/server/shared/Realm/RealmList.cpp | 185 | ||||
| -rw-r--r-- | src/server/shared/Realm/RealmList.h | 61 | ||||
| -rw-r--r-- | src/server/shared/Service/ServiceWin32.cpp | 264 | ||||
| -rw-r--r-- | src/server/shared/Service/ServiceWin32.h | 29 |
14 files changed, 583 insertions, 632 deletions
diff --git a/src/server/shared/CMakeLists.txt b/src/server/shared/CMakeLists.txt index b6e5c8b1c6f..e99a81a084b 100644 --- a/src/server/shared/CMakeLists.txt +++ b/src/server/shared/CMakeLists.txt @@ -8,62 +8,60 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -if( USE_COREPCH ) - include_directories(${CMAKE_CURRENT_BINARY_DIR}) -endif() - -file(GLOB_RECURSE sources_DataStores DataStores/*.cpp DataStores/*.h) -file(GLOB_RECURSE sources_Dynamic Dynamic/*.cpp Dynamic/*.h) -file(GLOB_RECURSE sources_Networking Networking/*.cpp Networking/*.h) -file(GLOB_RECURSE sources_Packets Packets/*.cpp Packets/*.h) -if( WIN32 ) - file(GLOB_RECURSE sources_Service Service/*.cpp Service/*.h) -endif( WIN32 ) -file(GLOB sources_localdir *.cpp *.h) - -# -# Build shared sourcelist -# +CollectSourceFiles( + ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE_SOURCES + # Exclude + ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders) if (USE_COREPCH) - set(shared_STAT_PCH_HDR PrecompiledHeaders/sharedPCH.h) - set(shared_STAT_PCH_SRC PrecompiledHeaders/sharedPCH.cpp) + set(PRIVATE_PCH_HEADER PrecompiledHeaders/sharedPCH.h) + set(PRIVATE_PCH_SOURCE PrecompiledHeaders/sharedPCH.cpp) endif() -set(shared_STAT_SRCS - ${shared_STAT_SRCS} - ${sources_DataStores} - ${sources_Dynamic} - ${sources_Networking} - ${sources_Packets} - ${sources_Utilities} - ${sources_Service} - ${sources_localdir} -) +GroupSources(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR}/Dynamic - ${CMAKE_CURRENT_SOURCE_DIR}/Networking - ${CMAKE_SOURCE_DIR}/dep/cppformat - ${CMAKE_SOURCE_DIR}/src/common/ - ${CMAKE_SOURCE_DIR}/src/common/Debugging - ${CMAKE_SOURCE_DIR}/src/common/Logging - ${CMAKE_SOURCE_DIR}/src/common/Utilities - ${MYSQL_INCLUDE_DIR} - ${OPENSSL_INCLUDE_DIR} - ${VALGRIND_INCLUDE_DIR} +add_definitions(-DTRINITY_API_EXPORT_SHARED) + +add_library(shared + ${PRIVATE_PCH_SOURCE} + ${PRIVATE_SOURCES} ) -GroupSources(${CMAKE_CURRENT_SOURCE_DIR}) +CollectIncludeDirectories( + ${CMAKE_CURRENT_SOURCE_DIR} + PUBLIC_INCLUDES + # Exclude + ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders) -add_library(shared STATIC - ${shared_STAT_SRCS} - ${shared_STAT_PCH_SRC} -) +target_include_directories(shared + PUBLIC + ${PUBLIC_INCLUDES} + PRIVATE + ${CMAKE_CURRENT_BINARY_DIR}) -add_dependencies(shared revision_data.h) +target_link_libraries(shared + PUBLIC + database) + +set_target_properties(shared + PROPERTIES + FOLDER + "server") + +if( BUILD_SHARED_LIBS ) + if( UNIX ) + install(TARGETS shared + LIBRARY + DESTINATION lib) + elseif( WIN32 ) + install(TARGETS shared + RUNTIME + DESTINATION "${CMAKE_INSTALL_PREFIX}") + endif() +endif() # Generate precompiled header if (USE_COREPCH) - add_cxx_pch(shared ${shared_STAT_PCH_HDR} ${shared_STAT_PCH_SRC}) + add_cxx_pch(shared ${PRIVATE_PCH_HEADER} ${PRIVATE_PCH_SOURCE}) endif () diff --git a/src/server/shared/DataStores/DBCFileLoader.h b/src/server/shared/DataStores/DBCFileLoader.h index 00b1ee54a4a..abe18d1425e 100644 --- a/src/server/shared/DataStores/DBCFileLoader.h +++ b/src/server/shared/DataStores/DBCFileLoader.h @@ -37,7 +37,7 @@ enum DbcFieldFormat FT_SQL_ABSENT='a' //Used in sql format to mark column absent in sql dbc }; -class DBCFileLoader +class TC_SHARED_API DBCFileLoader { public: DBCFileLoader(); diff --git a/src/server/shared/Networking/AsyncAcceptor.h b/src/server/shared/Networking/AsyncAcceptor.h index 260e1c8ea11..f68da230553 100644 --- a/src/server/shared/Networking/AsyncAcceptor.h +++ b/src/server/shared/Networking/AsyncAcceptor.h @@ -20,34 +20,40 @@ #include "Log.h" #include <boost/asio.hpp> +#include <functional> +#include <atomic> using boost::asio::ip::tcp; class AsyncAcceptor { public: - typedef void(*ManagerAcceptHandler)(tcp::socket&& newSocket); + typedef void(*AcceptCallback)(tcp::socket&& newSocket, uint32 threadIndex); AsyncAcceptor(boost::asio::io_service& ioService, std::string const& bindIp, uint16 port) : _acceptor(ioService, tcp::endpoint(boost::asio::ip::address::from_string(bindIp), port)), - _socket(ioService) + _socket(ioService), _closed(false), _socketFactory(std::bind(&AsyncAcceptor::DefeaultSocketFactory, this)) { } - template <class T> + template<class T> void AsyncAccept(); - void AsyncAcceptManaged(ManagerAcceptHandler mgrHandler) + template<AcceptCallback acceptCallback> + void AsyncAcceptWithCallback() { - _acceptor.async_accept(_socket, [this, mgrHandler](boost::system::error_code error) + tcp::socket* socket; + uint32 threadIndex; + std::tie(socket, threadIndex) = _socketFactory(); + _acceptor.async_accept(*socket, [this, socket, threadIndex](boost::system::error_code error) { if (!error) { try { - _socket.non_blocking(true); + socket->non_blocking(true); - mgrHandler(std::move(_socket)); + acceptCallback(std::move(*socket), threadIndex); } catch (boost::system::system_error const& err) { @@ -55,13 +61,29 @@ public: } } - AsyncAcceptManaged(mgrHandler); + if (!_closed) + this->AsyncAcceptWithCallback<acceptCallback>(); }); } + void Close() + { + if (_closed.exchange(true)) + return; + + boost::system::error_code err; + _acceptor.close(err); + } + + void SetSocketFactory(std::function<std::pair<tcp::socket*, uint32>()> func) { _socketFactory = func; } + private: + std::pair<tcp::socket*, uint32> DefeaultSocketFactory() { return std::make_pair(&_socket, 0); } + tcp::acceptor _acceptor; tcp::socket _socket; + std::atomic<bool> _closed; + std::function<std::pair<tcp::socket*, uint32>()> _socketFactory; }; template<class T> @@ -83,7 +105,8 @@ void AsyncAcceptor::AsyncAccept() } // lets slap some more this-> on this so we can fix this bug with gcc 4.7.2 throwing internals in yo face - this->AsyncAccept<T>(); + if (!_closed) + this->AsyncAccept<T>(); }); } diff --git a/src/server/shared/Networking/MessageBuffer.h b/src/server/shared/Networking/MessageBuffer.h deleted file mode 100644 index 189a56f18b6..00000000000 --- a/src/server/shared/Networking/MessageBuffer.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the -* Free Software Foundation; either version 2 of the License, or (at your -* option) any later version. -* -* This program is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -* more details. -* -* You should have received a copy of the GNU General Public License along -* with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef __MESSAGEBUFFER_H_ -#define __MESSAGEBUFFER_H_ - -#include "Define.h" -#include <vector> - -class MessageBuffer -{ - typedef std::vector<uint8>::size_type size_type; - -public: - MessageBuffer() : _wpos(0), _rpos(0), _storage() - { - _storage.resize(4096); - } - - explicit MessageBuffer(std::size_t initialSize) : _wpos(0), _rpos(0), _storage() - { - _storage.resize(initialSize); - } - - MessageBuffer(MessageBuffer const& right) : _wpos(right._wpos), _rpos(right._rpos), _storage(right._storage) - { - } - - MessageBuffer(MessageBuffer&& right) : _wpos(right._wpos), _rpos(right._rpos), _storage(right.Move()) { } - - void Reset() - { - _wpos = 0; - _rpos = 0; - } - - void Resize(size_type bytes) - { - _storage.resize(bytes); - } - - uint8* GetBasePointer() { return _storage.data(); } - - uint8* GetReadPointer() { return GetBasePointer() + _rpos; } - - uint8* GetWritePointer() { return GetBasePointer() + _wpos; } - - void ReadCompleted(size_type bytes) { _rpos += bytes; } - - void WriteCompleted(size_type bytes) { _wpos += bytes; } - - size_type GetActiveSize() const { return _wpos - _rpos; } - - size_type GetRemainingSpace() const { return _storage.size() - _wpos; } - - size_type GetBufferSize() const { return _storage.size(); } - - // Discards inactive data - void Normalize() - { - if (_rpos) - { - if (_rpos != _wpos) - memmove(GetBasePointer(), GetReadPointer(), GetActiveSize()); - _wpos -= _rpos; - _rpos = 0; - } - } - - // Ensures there's "some" free space, make sure to call Normalize() before this - void EnsureFreeSpace() - { - // resize buffer if it's already full - if (GetRemainingSpace() == 0) - _storage.resize(_storage.size() * 3 / 2); - } - - void Write(void const* data, std::size_t size) - { - if (size) - { - memcpy(GetWritePointer(), data, size); - WriteCompleted(size); - } - } - - std::vector<uint8>&& Move() - { - _wpos = 0; - _rpos = 0; - return std::move(_storage); - } - - MessageBuffer& operator=(MessageBuffer& right) - { - if (this != &right) - { - _wpos = right._wpos; - _rpos = right._rpos; - _storage = right._storage; - } - - return *this; - } - - MessageBuffer& operator=(MessageBuffer&& right) - { - if (this != &right) - { - _wpos = right._wpos; - _rpos = right._rpos; - _storage = right.Move(); - } - - return *this; - } - -private: - size_type _wpos; - size_type _rpos; - std::vector<uint8> _storage; -}; - -#endif /* __MESSAGEBUFFER_H_ */ diff --git a/src/server/shared/Networking/NetworkThread.h b/src/server/shared/Networking/NetworkThread.h index ac216838bce..be0e9f10176 100644 --- a/src/server/shared/Networking/NetworkThread.h +++ b/src/server/shared/Networking/NetworkThread.h @@ -22,6 +22,8 @@ #include "Errors.h" #include "Log.h" #include "Timer.h" +#include <boost/asio/ip/tcp.hpp> +#include <boost/asio/deadline_timer.hpp> #include <atomic> #include <chrono> #include <memory> @@ -29,11 +31,14 @@ #include <set> #include <thread> +using boost::asio::ip::tcp; + template<class SocketType> class NetworkThread { public: - NetworkThread() : _connections(0), _stopped(false), _thread(nullptr) + NetworkThread() : _connections(0), _stopped(false), _thread(nullptr), + _acceptSocket(_io_service), _updateTimer(_io_service) { } @@ -50,6 +55,7 @@ public: void Stop() { _stopped = true; + _io_service.stop(); } bool Start() @@ -80,10 +86,12 @@ public: std::lock_guard<std::mutex> lock(_newSocketsLock); ++_connections; - _newSockets.insert(sock); + _newSockets.push_back(sock); SocketAdded(sock); } + tcp::socket* GetSocketForAccept() { return &_acceptSocket; } + protected: virtual void SocketAdded(std::shared_ptr<SocketType> /*sock*/) { } virtual void SocketRemoved(std::shared_ptr<SocketType> /*sock*/) { } @@ -95,16 +103,15 @@ protected: if (_newSockets.empty()) return; - for (typename SocketSet::const_iterator i = _newSockets.begin(); i != _newSockets.end(); ++i) + for (std::shared_ptr<SocketType> sock : _newSockets) { - if (!(*i)->IsOpen()) + if (!sock->IsOpen()) { - SocketRemoved(*i); - + SocketRemoved(sock); --_connections; } else - _Sockets.insert(*i); + _sockets.push_back(sock); } _newSockets.clear(); @@ -114,53 +121,58 @@ protected: { TC_LOG_DEBUG("misc", "Network Thread Starting"); - typename SocketSet::iterator i, t; + _updateTimer.expires_from_now(boost::posix_time::milliseconds(10)); + _updateTimer.async_wait(std::bind(&NetworkThread<SocketType>::Update, this)); + _io_service.run(); - uint32 sleepTime = 10; - uint32 tickStart = 0, diff = 0; - while (!_stopped) - { - std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime)); + TC_LOG_DEBUG("misc", "Network Thread exits"); + _newSockets.clear(); + _sockets.clear(); + } + + void Update() + { + if (_stopped) + return; - tickStart = getMSTime(); + _updateTimer.expires_from_now(boost::posix_time::milliseconds(10)); + _updateTimer.async_wait(std::bind(&NetworkThread<SocketType>::Update, this)); - AddNewSockets(); + AddNewSockets(); - for (i = _Sockets.begin(); i != _Sockets.end();) + _sockets.erase(std::remove_if(_sockets.begin(), _sockets.end(), [this](std::shared_ptr<SocketType> sock) + { + if (!sock->Update()) { - if (!(*i)->Update()) - { - if ((*i)->IsOpen()) - (*i)->CloseSocket(); - - SocketRemoved(*i); - - --_connections; - _Sockets.erase(i++); - } - else - ++i; - } + if (sock->IsOpen()) + sock->CloseSocket(); - diff = GetMSTimeDiffToNow(tickStart); - sleepTime = diff > 10 ? 0 : 10 - diff; - } + this->SocketRemoved(sock); - TC_LOG_DEBUG("misc", "Network Thread exits"); + --this->_connections; + return true; + } + + return false; + }), _sockets.end()); } private: - typedef std::set<std::shared_ptr<SocketType> > SocketSet; + typedef std::vector<std::shared_ptr<SocketType>> SocketContainer; std::atomic<int32> _connections; std::atomic<bool> _stopped; std::thread* _thread; - SocketSet _Sockets; + SocketContainer _sockets; std::mutex _newSocketsLock; - SocketSet _newSockets; + SocketContainer _newSockets; + + boost::asio::io_service _io_service; + tcp::socket _acceptSocket; + boost::asio::deadline_timer _updateTimer; }; #endif // NetworkThread_h__ diff --git a/src/server/shared/Networking/Socket.h b/src/server/shared/Networking/Socket.h index a2f57b5029e..0674ede57d8 100644 --- a/src/server/shared/Networking/Socket.h +++ b/src/server/shared/Networking/Socket.h @@ -21,15 +21,11 @@ #include "MessageBuffer.h" #include "Log.h" #include <atomic> -#include <vector> -#include <mutex> #include <queue> #include <memory> #include <functional> #include <type_traits> #include <boost/asio/ip/tcp.hpp> -#include <boost/asio/write.hpp> -#include <boost/asio/read.hpp> using boost::asio::ip::tcp; @@ -59,18 +55,14 @@ public: virtual bool Update() { - if (!IsOpen()) + if (_closed) return false; #ifndef TC_SOCKET_USE_IOCP - std::unique_lock<std::mutex> guard(_writeLock); - if (!guard) - return true; - - if (_isWritingAsync || (!_writeBuffer.GetActiveSize() && _writeQueue.empty())) + if (_isWritingAsync || (_writeQueue.empty() && !_closing)) return true; - for (; WriteHandler(guard);) + for (; HandleQueue();) ; #endif @@ -98,14 +90,23 @@ public: std::bind(&Socket<T>::ReadHandlerInternal, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2)); } - void QueuePacket(MessageBuffer&& buffer, std::unique_lock<std::mutex>& guard) + void AsyncReadWithCallback(void (T::*callback)(boost::system::error_code, std::size_t)) + { + if (!IsOpen()) + return; + + _readBuffer.Normalize(); + _readBuffer.EnsureFreeSpace(); + _socket.async_read_some(boost::asio::buffer(_readBuffer.GetWritePointer(), _readBuffer.GetRemainingSpace()), + std::bind(callback, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2)); + } + + void QueuePacket(MessageBuffer&& buffer) { _writeQueue.push(std::move(buffer)); #ifdef TC_SOCKET_USE_IOCP - AsyncProcessQueue(guard); -#else - (void)guard; + AsyncProcessQueue(); #endif } @@ -135,7 +136,7 @@ protected: virtual void ReadHandler() = 0; - bool AsyncProcessQueue(std::unique_lock<std::mutex>&) + bool AsyncProcessQueue() { if (_isWritingAsync) return false; @@ -154,13 +155,14 @@ protected: return false; } - std::mutex _writeLock; - std::queue<MessageBuffer> _writeQueue; -#ifndef TC_SOCKET_USE_IOCP - MessageBuffer _writeBuffer; -#endif - - boost::asio::io_service& io_service() { return _socket.get_io_service(); } + void SetNoDelay(bool enable) + { + boost::system::error_code err; + _socket.set_option(tcp::no_delay(enable), err); + if (err) + TC_LOG_DEBUG("network", "Socket::SetNoDelay: failed to set_option(boost::asio::ip::tcp::no_delay) for %s - %d (%s)", + GetRemoteIpAddress().to_string().c_str(), err.value(), err.message().c_str()); + } private: void ReadHandlerInternal(boost::system::error_code error, size_t transferredBytes) @@ -181,15 +183,13 @@ private: { if (!error) { - std::unique_lock<std::mutex> deleteGuard(_writeLock); - _isWritingAsync = false; _writeQueue.front().ReadCompleted(transferedBytes); if (!_writeQueue.front().GetActiveSize()) _writeQueue.pop(); if (!_writeQueue.empty()) - AsyncProcessQueue(deleteGuard); + AsyncProcessQueue(); else if (_closing) CloseSocket(); } @@ -201,47 +201,11 @@ private: void WriteHandlerWrapper(boost::system::error_code /*error*/, std::size_t /*transferedBytes*/) { - std::unique_lock<std::mutex> guard(_writeLock); _isWritingAsync = false; - WriteHandler(guard); + HandleQueue(); } - bool WriteHandler(std::unique_lock<std::mutex>& guard) - { - if (!IsOpen()) - return false; - - std::size_t bytesToSend = _writeBuffer.GetActiveSize(); - - if (bytesToSend == 0) - return HandleQueue(guard); - - boost::system::error_code error; - std::size_t bytesWritten = _socket.write_some(boost::asio::buffer(_writeBuffer.GetReadPointer(), bytesToSend), error); - - if (error) - { - if (error == boost::asio::error::would_block || error == boost::asio::error::try_again) - return AsyncProcessQueue(guard); - - return false; - } - else if (bytesWritten == 0) - return false; - else if (bytesWritten < bytesToSend) - { - _writeBuffer.ReadCompleted(bytesWritten); - _writeBuffer.Normalize(); - return AsyncProcessQueue(guard); - } - - // now bytesWritten == bytesToSend - _writeBuffer.Reset(); - - return HandleQueue(guard); - } - - bool HandleQueue(std::unique_lock<std::mutex>& guard) + bool HandleQueue() { if (_writeQueue.empty()) return false; @@ -256,23 +220,29 @@ private: if (error) { if (error == boost::asio::error::would_block || error == boost::asio::error::try_again) - return AsyncProcessQueue(guard); + return AsyncProcessQueue(); _writeQueue.pop(); + if (_closing && _writeQueue.empty()) + CloseSocket(); return false; } else if (bytesSent == 0) { _writeQueue.pop(); + if (_closing && _writeQueue.empty()) + CloseSocket(); return false; } else if (bytesSent < bytesToSend) // now n > 0 { queuedMessage.ReadCompleted(bytesSent); - return AsyncProcessQueue(guard); + return AsyncProcessQueue(); } _writeQueue.pop(); + if (_closing && _writeQueue.empty()) + CloseSocket(); return !_writeQueue.empty(); } @@ -284,6 +254,7 @@ private: uint16 _remotePort; MessageBuffer _readBuffer; + std::queue<MessageBuffer> _writeQueue; std::atomic<bool> _closed; std::atomic<bool> _closing; diff --git a/src/server/shared/Networking/SocketMgr.h b/src/server/shared/Networking/SocketMgr.h index ce5bc2d8fc2..e479cd2450d 100644 --- a/src/server/shared/Networking/SocketMgr.h +++ b/src/server/shared/Networking/SocketMgr.h @@ -19,7 +19,6 @@ #define SocketMgr_h__ #include "AsyncAcceptor.h" -#include "Config.h" #include "Errors.h" #include "NetworkThread.h" #include <boost/asio/ip/tcp.hpp> @@ -33,18 +32,12 @@ class SocketMgr public: virtual ~SocketMgr() { - delete[] _threads; + ASSERT(!_threads && !_acceptor && !_threadCount, "StopNetwork must be called prior to SocketMgr destruction"); } - virtual bool StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port) + virtual bool StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port, int threadCount) { - _threadCount = sConfigMgr->GetIntDefault("Network.Threads", 1); - - if (_threadCount <= 0) - { - TC_LOG_ERROR("misc", "Network.Threads is wrong in your config file"); - return false; - } + ASSERT(threadCount > 0); try { @@ -56,6 +49,7 @@ public: return false; } + _threadCount = threadCount; _threads = CreateThreads(); ASSERT(_threads); @@ -68,11 +62,19 @@ public: virtual void StopNetwork() { + _acceptor->Close(); + if (_threadCount != 0) for (int32 i = 0; i < _threadCount; ++i) _threads[i].Stop(); Wait(); + + delete _acceptor; + _acceptor = nullptr; + delete[] _threads; + _threads = nullptr; + _threadCount = 0; } void Wait() @@ -82,20 +84,14 @@ public: _threads[i].Wait(); } - virtual void OnSocketOpen(tcp::socket&& sock) + virtual void OnSocketOpen(tcp::socket&& sock, uint32 threadIndex) { - size_t min = 0; - - for (int32 i = 1; i < _threadCount; ++i) - if (_threads[i].GetConnectionCount() < _threads[min].GetConnectionCount()) - min = i; - try { std::shared_ptr<SocketType> newSocket = std::make_shared<SocketType>(std::move(sock)); newSocket->Start(); - _threads[min].AddSocket(newSocket); + _threads[threadIndex].AddSocket(newSocket); } catch (boost::system::system_error const& err) { @@ -105,6 +101,23 @@ public: int32 GetNetworkThreadCount() const { return _threadCount; } + uint32 SelectThreadWithMinConnections() const + { + uint32 min = 0; + + for (int32 i = 1; i < _threadCount; ++i) + if (_threads[i].GetConnectionCount() < _threads[min].GetConnectionCount()) + min = i; + + return min; + } + + std::pair<tcp::socket*, uint32> GetSocketForAccept() + { + uint32 threadIndex = SelectThreadWithMinConnections(); + return std::make_pair(_threads[threadIndex].GetSocketForAccept(), threadIndex); + } + protected: SocketMgr() : _acceptor(nullptr), _threads(nullptr), _threadCount(1) { diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index 5ebe5258a44..d24a91ed458 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -23,22 +23,12 @@ #include "Errors.h" #include "ByteConverter.h" #include "Util.h" - -#include <exception> -#include <list> -#include <map> -#include <string> -#include <vector> #include <cstring> -#include <time.h> -#include <cmath> -#include <type_traits> -#include <boost/asio/buffer.hpp> class MessageBuffer; // Root of ByteBuffer exception hierarchy -class ByteBufferException : public std::exception +class TC_SHARED_API ByteBufferException : public std::exception { public: ~ByteBufferException() throw() { } @@ -52,7 +42,7 @@ private: std::string msg_; }; -class ByteBufferPositionException : public ByteBufferException +class TC_SHARED_API ByteBufferPositionException : public ByteBufferException { public: ByteBufferPositionException(bool add, size_t pos, size_t size, size_t valueSize); @@ -60,7 +50,7 @@ public: ~ByteBufferPositionException() throw() { } }; -class ByteBufferSourceException : public ByteBufferException +class TC_SHARED_API ByteBufferSourceException : public ByteBufferException { public: ByteBufferSourceException(size_t pos, size_t size, size_t valueSize); @@ -68,7 +58,7 @@ public: ~ByteBufferSourceException() throw() { } }; -class ByteBuffer +class TC_SHARED_API ByteBuffer { public: const static size_t DEFAULT_SIZE = 0x1000; @@ -628,15 +618,4 @@ inline void ByteBuffer::read_skip<std::string>() read_skip<char*>(); } -namespace boost -{ - namespace asio - { - inline const_buffers_1 buffer(ByteBuffer const& packet) - { - return buffer(packet.contents(), packet.size()); - } - } -} - #endif diff --git a/src/server/shared/Realm/Realm.cpp b/src/server/shared/Realm/Realm.cpp new file mode 100644 index 00000000000..11c52f281a9 --- /dev/null +++ b/src/server/shared/Realm/Realm.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "Realm.h" + +ip::tcp::endpoint Realm::GetAddressForClient(ip::address const& clientAddr) const +{ + ip::address realmIp; + + // Attempt to send best address for client + if (clientAddr.is_loopback()) + { + // Try guessing if realm is also connected locally + if (LocalAddress.is_loopback() || ExternalAddress.is_loopback()) + realmIp = clientAddr; + else + { + // Assume that user connecting from the machine that bnetserver is located on + // has all realms available in his local network + realmIp = LocalAddress; + } + } + else + { + if (clientAddr.is_v4() && + (clientAddr.to_v4().to_ulong() & LocalSubnetMask.to_v4().to_ulong()) == + (LocalAddress.to_v4().to_ulong() & LocalSubnetMask.to_v4().to_ulong())) + { + realmIp = LocalAddress; + } + else + realmIp = ExternalAddress; + } + + ip::tcp::endpoint endpoint(realmIp, Port); + + // Return external IP + return endpoint; +} diff --git a/src/server/shared/Realm/Realm.h b/src/server/shared/Realm/Realm.h new file mode 100644 index 00000000000..241ccd2bca8 --- /dev/null +++ b/src/server/shared/Realm/Realm.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef Realm_h__ +#define Realm_h__ + +#include "Common.h" +#include <boost/asio/ip/address.hpp> +#include <boost/asio/ip/tcp.hpp> + +using namespace boost::asio; + +enum RealmFlags +{ + REALM_FLAG_NONE = 0x00, + REALM_FLAG_VERSION_MISMATCH = 0x01, + REALM_FLAG_OFFLINE = 0x02, + REALM_FLAG_SPECIFYBUILD = 0x04, + REALM_FLAG_UNK1 = 0x08, + REALM_FLAG_UNK2 = 0x10, + REALM_FLAG_RECOMMENDED = 0x20, + REALM_FLAG_NEW = 0x40, + REALM_FLAG_FULL = 0x80 +}; + +struct TC_SHARED_API RealmHandle +{ + RealmHandle() : Realm(0) { } + RealmHandle(uint32 index) : Realm(index) { } + + uint32 Realm; // primary key in `realmlist` table + + bool operator<(RealmHandle const& r) const + { + return Realm < r.Realm; + } +}; + +/// Type of server, this is values from second column of Cfg_Configs.dbc +enum RealmType +{ + REALM_TYPE_NORMAL = 0, + REALM_TYPE_PVP = 1, + REALM_TYPE_NORMAL2 = 4, + REALM_TYPE_RP = 6, + REALM_TYPE_RPPVP = 8, + + MAX_CLIENT_REALM_TYPE = 14, + + REALM_TYPE_FFA_PVP = 16 // custom, free for all pvp mode like arena PvP in all zones except rest activated places and sanctuaries + // replaced by REALM_PVP in realm list +}; + +// Storage object for a realm +struct TC_SHARED_API Realm +{ + RealmHandle Id; + uint32 Build; + ip::address ExternalAddress; + ip::address LocalAddress; + ip::address LocalSubnetMask; + uint16 Port; + std::string Name; + uint8 Type; + RealmFlags Flags; + uint8 Timezone; + AccountTypes AllowedSecurityLevel; + float PopulationLevel; + + ip::tcp::endpoint GetAddressForClient(ip::address const& clientAddr) const; +}; + +#endif // Realm_h__ diff --git a/src/server/shared/Realm/RealmList.cpp b/src/server/shared/Realm/RealmList.cpp new file mode 100644 index 00000000000..e941800cd76 --- /dev/null +++ b/src/server/shared/Realm/RealmList.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "RealmList.h" +#include "Database/DatabaseEnv.h" +#include "Util.h" + +RealmList::RealmList() : _updateInterval(0), _updateTimer(nullptr), _resolver(nullptr) +{ +} + +RealmList::~RealmList() +{ + delete _updateTimer; +} + +RealmList* RealmList::Instance() +{ + static RealmList instance; + return &instance; +} + +// Load the realm list from the database +void RealmList::Initialize(boost::asio::io_service& ioService, uint32 updateInterval) +{ + _updateInterval = updateInterval; + _updateTimer = new boost::asio::deadline_timer(ioService); + _resolver = new boost::asio::ip::tcp::resolver(ioService); + + // Get the content of the realmlist table in the database + UpdateRealms(boost::system::error_code()); +} + +void RealmList::Close() +{ + _updateTimer->cancel(); +} + +void RealmList::UpdateRealm(RealmHandle const& id, uint32 build, const std::string& name, ip::address const& address, ip::address const& localAddr, + ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, + float population) +{ + // Create new if not exist or update existed + Realm& realm = _realms[id]; + + realm.Id = id; + realm.Build = build; + realm.Name = name; + realm.Type = icon; + realm.Flags = flag; + realm.Timezone = timezone; + realm.AllowedSecurityLevel = allowedSecurityLevel; + realm.PopulationLevel = population; + realm.ExternalAddress = address; + realm.LocalAddress = localAddr; + realm.LocalSubnetMask = localSubmask; + realm.Port = port; +} + +void RealmList::UpdateRealms(boost::system::error_code const& error) +{ + if (error) + return; + + TC_LOG_DEBUG("server.authserver", "Updating Realm List..."); + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + std::map<RealmHandle, std::string> existingRealms; + for (auto const& p : _realms) + existingRealms[p.first] = p.second.Name; + + _realms.clear(); + + // Circle through results and add them to the realm map + if (result) + { + do + { + try + { + boost::asio::ip::tcp::resolver::iterator end; + + Field* fields = result->Fetch(); + uint32 realmId = fields[0].GetUInt32(); + std::string name = fields[1].GetString(); + boost::asio::ip::tcp::resolver::query externalAddressQuery(ip::tcp::v4(), fields[2].GetString(), ""); + + boost::system::error_code ec; + boost::asio::ip::tcp::resolver::iterator endPoint = _resolver->resolve(externalAddressQuery, ec); + if (endPoint == end || ec) + { + TC_LOG_ERROR("server.authserver", "Could not resolve address %s for realm \"%s\" id %u", fields[2].GetString().c_str(), name.c_str(), realmId); + continue; + } + + ip::address externalAddress = (*endPoint).endpoint().address(); + + boost::asio::ip::tcp::resolver::query localAddressQuery(ip::tcp::v4(), fields[3].GetString(), ""); + endPoint = _resolver->resolve(localAddressQuery, ec); + if (endPoint == end || ec) + { + TC_LOG_ERROR("server.authserver", "Could not resolve localAddress %s for realm \"%s\" id %u", fields[3].GetString().c_str(), name.c_str(), realmId); + continue; + } + + ip::address localAddress = (*endPoint).endpoint().address(); + + boost::asio::ip::tcp::resolver::query localSubmaskQuery(ip::tcp::v4(), fields[4].GetString(), ""); + endPoint = _resolver->resolve(localSubmaskQuery, ec); + if (endPoint == end || ec) + { + TC_LOG_ERROR("server.authserver", "Could not resolve localSubnetMask %s for realm \"%s\" id %u", fields[4].GetString().c_str(), name.c_str(), realmId); + continue; + } + + ip::address localSubmask = (*endPoint).endpoint().address(); + + uint16 port = fields[5].GetUInt16(); + uint8 icon = fields[6].GetUInt8(); + if (icon == REALM_TYPE_FFA_PVP) + icon = REALM_TYPE_PVP; + if (icon >= MAX_CLIENT_REALM_TYPE) + icon = REALM_TYPE_NORMAL; + RealmFlags flag = RealmFlags(fields[7].GetUInt8()); + uint8 timezone = fields[8].GetUInt8(); + uint8 allowedSecurityLevel = fields[9].GetUInt8(); + float pop = fields[10].GetFloat(); + uint32 build = fields[11].GetUInt32(); + + RealmHandle id{ realmId }; + + UpdateRealm(id, build, name, externalAddress, localAddress, localSubmask, port, icon, flag, + timezone, (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), pop); + + if (!existingRealms.count(id)) + TC_LOG_INFO("server.authserver", "Added realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port); + else + TC_LOG_DEBUG("server.authserver", "Updating realm \"%s\" at %s:%u.", name.c_str(), externalAddress.to_string().c_str(), port); + + existingRealms.erase(id); + } + catch (std::exception& ex) + { + TC_LOG_ERROR("server.authserver", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what()); + ABORT(); + } + } + while (result->NextRow()); + } + + for (auto itr = existingRealms.begin(); itr != existingRealms.end(); ++itr) + TC_LOG_INFO("server.authserver", "Removed realm \"%s\".", itr->second.c_str()); + + if (_updateInterval) + { + _updateTimer->expires_from_now(boost::posix_time::seconds(_updateInterval)); + _updateTimer->async_wait(std::bind(&RealmList::UpdateRealms, this, std::placeholders::_1)); + } +} + +Realm const* RealmList::GetRealm(RealmHandle const& id) const +{ + auto itr = _realms.find(id); + if (itr != _realms.end()) + return &itr->second; + + return NULL; +} diff --git a/src/server/shared/Realm/RealmList.h b/src/server/shared/Realm/RealmList.h new file mode 100644 index 00000000000..3b81337e762 --- /dev/null +++ b/src/server/shared/Realm/RealmList.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _REALMLIST_H +#define _REALMLIST_H + +#include "Common.h" +#include "Realm/Realm.h" +#include <boost/asio/ip/address.hpp> +#include <boost/asio/ip/tcp.hpp> +#include <boost/asio/io_service.hpp> +#include <boost/asio/deadline_timer.hpp> + +using namespace boost::asio; + +/// Storage object for the list of realms on the server +class TC_SHARED_API RealmList +{ +public: + typedef std::map<RealmHandle, Realm> RealmMap; + + static RealmList* Instance(); + + ~RealmList(); + + void Initialize(boost::asio::io_service& ioService, uint32 updateInterval); + void Close(); + + RealmMap const& GetRealms() const { return _realms; } + Realm const* GetRealm(RealmHandle const& id) const; + +private: + RealmList(); + + void UpdateRealms(boost::system::error_code const& error); + void UpdateRealm(RealmHandle const& id, uint32 build, const std::string& name, ip::address const& address, ip::address const& localAddr, + ip::address const& localSubmask, uint16 port, uint8 icon, RealmFlags flag, uint8 timezone, AccountTypes allowedSecurityLevel, float population); + + RealmMap _realms; + uint32 _updateInterval; + boost::asio::deadline_timer* _updateTimer; + boost::asio::ip::tcp::resolver* _resolver; +}; + +#define sRealmList RealmList::Instance() +#endif diff --git a/src/server/shared/Service/ServiceWin32.cpp b/src/server/shared/Service/ServiceWin32.cpp deleted file mode 100644 index b6a1682993b..00000000000 --- a/src/server/shared/Service/ServiceWin32.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifdef _WIN32 - -#include "Common.h" -#include "Log.h" -#include <cstring> -#include <windows.h> -#include <winsvc.h> - -#if !defined(WINADVAPI) -#if !defined(_ADVAPI32_) -#define WINADVAPI DECLSPEC_IMPORT -#else -#define WINADVAPI -#endif -#endif - -extern int main(int argc, char ** argv); -extern char serviceLongName[]; -extern char serviceName[]; -extern char serviceDescription[]; - -extern int m_ServiceStatus; - -SERVICE_STATUS serviceStatus; - -SERVICE_STATUS_HANDLE serviceStatusHandle = 0; - -typedef WINADVAPI BOOL (WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID); - -bool WinServiceInstall() -{ - SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE); - - if (serviceControlManager) - { - char path[_MAX_PATH + 10]; - if (GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0) - { - SC_HANDLE service; - std::strcat(path, " --service run"); - service = CreateService(serviceControlManager, - serviceName, // name of service - serviceLongName, // service name to display - SERVICE_ALL_ACCESS, // desired access - // service type - SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, - SERVICE_AUTO_START, // start type - SERVICE_ERROR_IGNORE, // error control type - path, // service's binary - 0, // no load ordering group - 0, // no tag identifier - 0, // no dependencies - 0, // LocalSystem account - 0); // no password - if (service) - { - HMODULE advapi32 = GetModuleHandle("ADVAPI32.DLL"); - if (!advapi32) - { - CloseServiceHandle(service); - CloseServiceHandle(serviceControlManager); - return false; - } - - CSD_T ChangeService_Config2 = (CSD_T) GetProcAddress(advapi32, "ChangeServiceConfig2A"); - if (!ChangeService_Config2) - { - CloseServiceHandle(service); - CloseServiceHandle(serviceControlManager); - return false; - } - - SERVICE_DESCRIPTION sdBuf; - sdBuf.lpDescription = serviceDescription; - ChangeService_Config2( - service, // handle to service - SERVICE_CONFIG_DESCRIPTION, // change: description - &sdBuf); // new data - - SC_ACTION _action[1]; - _action[0].Type = SC_ACTION_RESTART; - _action[0].Delay = 10000; - SERVICE_FAILURE_ACTIONS sfa; - ZeroMemory(&sfa, sizeof(SERVICE_FAILURE_ACTIONS)); - sfa.lpsaActions = _action; - sfa.cActions = 1; - sfa.dwResetPeriod =INFINITE; - ChangeService_Config2( - service, // handle to service - SERVICE_CONFIG_FAILURE_ACTIONS, // information level - &sfa); // new data - - CloseServiceHandle(service); - - } - } - CloseServiceHandle(serviceControlManager); - } - - printf("Service installed\n"); - return true; -} - -bool WinServiceUninstall() -{ - SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT); - - if (serviceControlManager) - { - SC_HANDLE service = OpenService(serviceControlManager, - serviceName, SERVICE_QUERY_STATUS | DELETE); - if (service) - { - SERVICE_STATUS serviceStatus2; - if (QueryServiceStatus(service, &serviceStatus2)) - { - if (serviceStatus2.dwCurrentState == SERVICE_STOPPED) - DeleteService(service); - } - CloseServiceHandle(service); - } - - CloseServiceHandle(serviceControlManager); - } - - printf("Service uninstalled\n"); - return true; -} - -void WINAPI ServiceControlHandler(DWORD controlCode) -{ - switch (controlCode) - { - case SERVICE_CONTROL_INTERROGATE: - break; - - case SERVICE_CONTROL_SHUTDOWN: - case SERVICE_CONTROL_STOP: - serviceStatus.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus(serviceStatusHandle, &serviceStatus); - - m_ServiceStatus = 0; - return; - - case SERVICE_CONTROL_PAUSE: - m_ServiceStatus = 2; - serviceStatus.dwCurrentState = SERVICE_PAUSED; - SetServiceStatus(serviceStatusHandle, &serviceStatus); - break; - - case SERVICE_CONTROL_CONTINUE: - serviceStatus.dwCurrentState = SERVICE_RUNNING; - SetServiceStatus(serviceStatusHandle, &serviceStatus); - m_ServiceStatus = 1; - break; - - default: - if ( controlCode >= 128 && controlCode <= 255 ) - // user defined control code - break; - else - // unrecognized control code - break; - } - - SetServiceStatus(serviceStatusHandle, &serviceStatus); -} - -void WINAPI ServiceMain(DWORD argc, char *argv[]) -{ - // initialise service status - serviceStatus.dwServiceType = SERVICE_WIN32; - serviceStatus.dwCurrentState = SERVICE_START_PENDING; - serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; - serviceStatus.dwWin32ExitCode = NO_ERROR; - serviceStatus.dwServiceSpecificExitCode = NO_ERROR; - serviceStatus.dwCheckPoint = 0; - serviceStatus.dwWaitHint = 0; - - serviceStatusHandle = RegisterServiceCtrlHandler(serviceName, ServiceControlHandler); - - if ( serviceStatusHandle ) - { - char path[_MAX_PATH + 1]; - unsigned int i, last_slash = 0; - - GetModuleFileName(0, path, sizeof(path)/sizeof(path[0])); - - size_t pathLen = std::strlen(path); - for (i = 0; i < pathLen; i++) - { - if (path[i] == '\\') last_slash = i; - } - - path[last_slash] = 0; - - // service is starting - serviceStatus.dwCurrentState = SERVICE_START_PENDING; - SetServiceStatus(serviceStatusHandle, &serviceStatus); - - // do initialisation here - SetCurrentDirectory(path); - - // running - serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); - serviceStatus.dwCurrentState = SERVICE_RUNNING; - SetServiceStatus( serviceStatusHandle, &serviceStatus ); - - //////////////////////// - // service main cycle // - //////////////////////// - - m_ServiceStatus = 1; - argc = 1; - main(argc, argv); - - // service was stopped - serviceStatus.dwCurrentState = SERVICE_STOP_PENDING; - SetServiceStatus(serviceStatusHandle, &serviceStatus); - - // do cleanup here - - // service is now stopped - serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); - serviceStatus.dwCurrentState = SERVICE_STOPPED; - SetServiceStatus(serviceStatusHandle, &serviceStatus); - } -} - -bool WinServiceRun() -{ - SERVICE_TABLE_ENTRY serviceTable[] = - { - { serviceName, ServiceMain }, - { 0, 0 } - }; - - if (!StartServiceCtrlDispatcher(serviceTable)) - { - TC_LOG_ERROR("server.worldserver", "StartService Failed. Error [%u]", uint32(::GetLastError())); - return false; - } - return true; -} -#endif - diff --git a/src/server/shared/Service/ServiceWin32.h b/src/server/shared/Service/ServiceWin32.h deleted file mode 100644 index 3d67bfe5445..00000000000 --- a/src/server/shared/Service/ServiceWin32.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifdef _WIN32 -#ifndef _WIN32_SERVICE_ -#define _WIN32_SERVICE_ - -bool WinServiceInstall(); -bool WinServiceUninstall(); -bool WinServiceRun(); - -#endif // _WIN32_SERVICE_ -#endif // _WIN32 - |
