rendered paste bodyIndex: src/mangosd/Master.cpp
===================================================================
--- src/mangosd/Master.cpp (revision 5031)
+++ src/mangosd/Master.cpp (working copy)
@@ -21,8 +21,7 @@
*/
#include "Master.h"
-#include "Network/SocketHandler.h"
-#include "Network/ListenSocket.h"
+#include "Network/Network.h"
#include "WorldSocket.h"
#include "WorldSocketMgr.h"
#include "WorldRunnable.h"
@@ -39,29 +38,21 @@
#include "ScriptCalls.h"
#include "Util.h"
-#include "Network/TcpSocket.h"
-#include "Network/Utility.h"
-#include "Network/Parse.h"
-#include "Network/Socket.h"
+#ifdef WIN32
+#include <crtdbg.h>
+#endif
+
#ifdef WIN32
#include "ServiceWin32.h"
extern int m_ServiceStatus;
#endif
/// \todo Warning disabling not useful under VC++2005. Can somebody say on which compiler it is useful?
-#pragma warning(disable:4305)
+//#pragma warning(disable:4305)
INSTANTIATE_SINGLETON_1( Master );
-Master::Master()
-{
-}
-
-Master::~Master()
-{
-}
-
/// Main function
void Master::Run()
{
@@ -93,6 +84,23 @@
sLog.outString( "Daemon PID: %u\n", pid );
}
+#ifdef USE_LEVENT
+ //show version of libevent at start
+ sLog.outBasic("Using %s version of LibEvent",event_get_version());
+ bool isvalid_vlibevent=false;
+ const char* accepted_vlibevent[]=REQ_LEVENT_VER;
+ for(int i=0;accepted_vlibevent[i];i++)
+ if(!strcmp(event_get_version(),accepted_vlibevent[i]))
+ {
+ isvalid_vlibevent=true;
+ break;
+ }
+ if(!isvalid_vlibevent)
+ {
+ sLog.outError("Version of libevent is wrong, shutdown now");
+ return;
+ }
+#endif//USE_LEVENT
///- Start the databases
if (!_StartDB())
@@ -101,21 +109,6 @@
///- Initialize the World
sWorld.SetInitialWorldSettings();
- ///- Launch the world listener socket
- port_t wsport = sWorld.getConfig(CONFIG_PORT_WORLD);
-
- SocketHandler h;
-
- ListenSocket<WorldSocket> worldListenSocket(h);
- if (worldListenSocket.Bind(wsport))
- {
- clearOnlineAccounts();
- sLog.outError("MaNGOS cannot bind to port %d", wsport);
- return;
- }
-
- h.Add(&worldListenSocket);
-
///- Catch termination signals
_HookSignals();
@@ -137,22 +130,17 @@
}
///- Launch the RA listener socket
- ListenSocket<RASocket> RAListenSocket(h);
+ ListenSocket<RASocket>* pRAListenSocket = NULL;
if (sConfig.GetBoolDefault("Ra.Enable", false))
{
- port_t raport = sConfig.GetIntDefault( "Ra.Port", 3443 );
+ uint32 raport = sConfig.GetIntDefault( "Ra.Port", 3443 );
std::string stringip = sConfig.GetStringDefault( "Ra.IP", "0.0.0.0" );
- ipaddr_t raip;
- if(!Utility::u2ip(stringip, raip))
- sLog.outError( "MaNGOS RA can not bind to ip %s", stringip.c_str());
- else if (RAListenSocket.Bind(raip, raport))
- sLog.outError( "MaNGOS RA can not bind to port %d on %s", raport, stringip.c_str());
+ pRAListenSocket = new ListenSocket<RASocket>(stringip.c_str(), raport);
+ if (!pRAListenSocket->IsListernPortOpened())
+ sLog.outString("Remote access lister on port %d on %s - FAILED", raport, stringip.c_str());
else
- {
- h.Add(&RAListenSocket);
-
- sLog.outString("Starting Remote access listner on port %d on %s", raport, stringip.c_str());
- }
+ {
+ sLog.outString("Starting Remote access lister on port %d on %s", raport, stringip.c_str());
}
///- Handle affinity for multiple processors and process priority on Windows
@@ -199,42 +187,45 @@
}
#endif
- uint32 realCurrTime, realPrevTime;
- realCurrTime = realPrevTime = getMSTime();
+ // sSocketManager.SetupIOWorkers();
+ ///- Launch the world listener socket
- uint32 socketSelecttime = sWorld.getConfig(CONFIG_SOCKET_SELECTTIME);
+ uint32 wsport = sWorld.getConfig(CONFIG_PORT_WORLD);
+ ListenSocket<WorldSocket> worldListenSocket("0.0.0.0", wsport);
+ bool bListenPortOpened = worldListenSocket.IsListernPortOpened();
// maximum counter for next ping
- uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / socketSelecttime));
- uint32 loopCounter = 0;
+ uint32 PingInterval = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * MINUTE * 1000);
+ uint32 RestToPing = PingInterval;
+ uint32 time_to_sleep = 100;
///- Wait for termination signal
- while (!World::m_stopEvent)
+ while (!World::m_stopEvent && bListenPortOpened)
{
#ifdef WIN32
if (m_ServiceStatus == 0) World::m_stopEvent = true;
while (m_ServiceStatus == 2) Sleep(1000);
#endif
- if (realPrevTime > realCurrTime)
- realPrevTime = 0;
+ Sleep(time_to_sleep);
+ if (RestToPing - time_to_sleep < 0)
+ RestToPing = 0;
+ else
+ RestToPing -= time_to_sleep;
+ if (RestToPing)
+ continue;
- realCurrTime = getMSTime();
- sWorldSocketMgr.Update( realCurrTime - realPrevTime );
- realPrevTime = realCurrTime;
-
- h.Select(0, socketSelecttime);
-
- // ping if need
- if( (++loopCounter) == numLoops )
- {
- loopCounter = 0;
+ RestToPing = PingInterval;
sLog.outDetail("Ping MySQL to keep connection alive");
delete WorldDatabase.Query("SELECT 1 FROM `command` LIMIT 1");
delete loginDatabase.Query("SELECT 1 FROM `realmlist` LIMIT 1");
delete CharacterDatabase.Query("SELECT 1 FROM `bugreport` LIMIT 1");
}
- }
+ worldListenSocket.StopListening();
+ sSocketManager.DisconnectAll();
+ sSocketManager.StopIOWorkers();
+ sAuthSocketManagerCleaner.Stop();
+
// set server offline
loginDatabase.PExecute("UPDATE `realmlist` SET `color` = 2 WHERE `id` = '%d'",realmID);
Index: src/mangosd/RASocket.cpp
===================================================================
--- src/mangosd/RASocket.cpp (revision 5031)
+++ src/mangosd/RASocket.cpp (working copy)
@@ -27,23 +27,19 @@
#include "World.h"
#include "Config/ConfigEnv.h"
+uint32 iSession=0; ///< Session number (incremented each time a new connection is made)
+unsigned int iUsers=0; ///< Number of active administrators
+typedef int(* pPrintf)(const char*,...);
/// \todo Make this thread safe if in the future 2 admins should be able to log at the same time.
-SOCKET r;
-
+SOCKET r=NULL;
#define dropclient {Sendf("I'm busy right now, come back later."); \
- SetCloseAndDelete(); \
+ Disconnect(); \
return; \
}
-
-uint32 iSession=0; ///< Session number (incremented each time a new connection is made)
-unsigned int iUsers=0; ///< Number of active administrators
-
-typedef int(* pPrintf)(const char*,...);
-
void ParseCommand(pPrintf zprintf, char*command);
/// RASocket constructor
-RASocket::RASocket(ISocketHandler &h): TcpSocket(h)
+RASocket::RASocket(SOCKET s): Socket(s)
{
///- Increment the session number
@@ -72,7 +68,7 @@
}
/// Accept an incoming connection
-void RASocket::OnAccept()
+void RASocket::OnConnect()
{
std::string ss=GetRemoteAddress();
sLog.outRALog("Incoming connection from %s.\n",ss.c_str());
@@ -87,14 +83,11 @@
/// Read data from the network
void RASocket::OnRead()
{
- ///- Read data and check input length
- TcpSocket::OnRead();
-
- unsigned int sz=ibuf.GetLength();
+ unsigned int sz = ReadBuffer()->get_data_size();
if(iInputLength+sz>=RA_BUFF_SIZE)
{
sLog.outRALog("Input buffer overflow, possible DOS attack.\n");
- SetCloseAndDelete();
+ Disconnect();
return;
}
@@ -103,7 +96,7 @@
dropclient
char *inp = new char [sz+1];
- ibuf.Read(inp,sz);
+ ReadBuffer()->extract((uint8*)inp, sz);
/// \todo Can somebody explain this 'Linux bugfix'?
if(stage==NONE)
@@ -153,7 +146,8 @@
{
Sendf("-No such user.\r\n");
sLog.outRALog("User %s does not exist.\n",szLogin.c_str());
- if(bSecure)SetCloseAndDelete();
+ if(bSecure)
+ Disconnect();
}
else
{
@@ -166,7 +160,7 @@
{
Sendf("-Not enough privileges.\r\n");
sLog.outRALog("User %s has no privilege.\n",szLogin.c_str());
- if(bSecure)SetCloseAndDelete();
+ if(bSecure)Disconnect();
} else
{
stage=LG;
@@ -201,7 +195,7 @@
///- Else deny access
Sendf("-Wrong pass.\r\n");
sLog.outRALog("User %s has failed to log in.\n",szLogin.c_str());
- if(bSecure)SetCloseAndDelete();
+ if(bSecure)Disconnect();
}
}
break;
@@ -227,13 +221,11 @@
if( !szText ) return 0;
va_list ap;
va_start(ap, szText);
- /// \todo Remove buffer length here. Can be >1024 (e.g. list of users)
- char *megabuffer=new char[1024];
- unsigned int sz=vsnprintf(megabuffer,1024,szText,ap);
+ char *megabuffer=new char[sizeof(szText)];
+ unsigned int sz=vsnprintf(megabuffer,sizeof(szText),szText,ap);
#ifdef RA_CRYPT
Encrypt(megabuffer,sz);
#endif
-
send(r,megabuffer,sz,0);
delete [] megabuffer;
va_end(ap);
Index: src/realmd/AuthSocket.cpp
===================================================================
--- src/realmd/AuthSocket.cpp (revision 5031)
+++ src/realmd/AuthSocket.cpp (working copy)
@@ -212,7 +212,7 @@
Patcher PatchesCache;
/// Constructor - set the N and g values for SRP6
-AuthSocket::AuthSocket(ISocketHandler &h) : TcpSocket(h)
+AuthSocket::AuthSocket(SOCKET h) : Socket(h)
{
N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7");
g.SetDword(7);
@@ -229,35 +229,30 @@
fclose(pPatch);
}
+void AuthSocket::OnDisconnect()
+{
+ sAuthSocketManagerCleaner.Add(this);//will be removed after 200 ms
+}
+
/// Accept the connection and set the s random value for SRP6
-void AuthSocket::OnAccept()
+void AuthSocket::OnConnect()
{
- sLog.outBasic("Accepting connection from '%s:%d'",
- GetRemoteAddress().c_str(), GetRemotePort());
-
- s.SetRand(s_BYTE_SIZE * 8);
+ sLog.outBasic("Accepting connection from '%s'", GetRemoteAddress().c_str());
+ s.SetRand(s_BYTE_SIZE * 8);
}
/// Read the packet from the client
void AuthSocket::OnRead()
{
///- Read the packet
- TcpSocket::OnRead();
uint8 _cmd;
while (1)
{
- if (!ibuf.GetLength())
+ if (!ReadBuffer()->get_data_size())
return;
///- Get the command out of it
- ibuf.SoftRead((char *)&_cmd, 1); // UQ1: No longer exists in new net code ???
- //ibuf.Read((char *)&_cmd, 1);
- /*char *command = (char *)malloc(1);
-
- ibuf.Read(command, 1);
-
- _cmd = (uint8)command;*/
- // assert(0);
+ ReadBuffer()->peek((uint8*)&_cmd, 1); // UQ1: No longer exists in new net code ???
size_t i;
///- Circle through known commands and call the correct command handler
@@ -267,11 +262,11 @@
(table[i].status == STATUS_CONNECTED ||
(_authed && table[i].status == STATUS_AUTHED)))
{
- DEBUG_LOG("[Auth] got data for cmd %u ibuf length %u", (uint32)_cmd, ibuf.GetLength());
+ DEBUG_LOG("[Auth] got data for cmd %u ibuf length %u", (uint32)_cmd, ReadBuffer()->get_data_size());
if (!(*this.*table[i].handler)())
{
- DEBUG_LOG("Command handler failed for cmd %u ibuf length %u", (uint32)_cmd, ibuf.GetLength());
+ DEBUG_LOG("Command handler failed for cmd %u ibuf length %u", (uint32)_cmd, ReadBuffer()->get_data_size());
return;
}
break;
@@ -321,19 +316,22 @@
bool AuthSocket::_HandleLogonChallenge()
{
DEBUG_LOG("Entering _HandleLogonChallenge");
- if (ibuf.GetLength() < sizeof(sAuthLogonChallenge_C))
+ if (ReadBuffer()->get_data_size() < sizeof(sAuthLogonChallenge_C))
return false;
///- Read the first 4 bytes (header) to get the length of the remaining of the packet
std::vector<uint8> buf;
buf.resize(4);
- ibuf.Read((char *)&buf[0], 4);
+ LockReading();
+ ReadBuffer()->extract((uint8* )&buf[0], 4);
+ UnlockReading();
+
uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size;
DEBUG_LOG("[AuthChallenge] got header, body is %#04x bytes", remaining);
- if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (ibuf.GetLength() < remaining))
- return false;
+ if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (ReadBuffer()->get_data_size() < remaining))
+ return false;
//No big fear of memory outage (size is int16, i.e. < 65536)
buf.resize(remaining + buf.size() + 1);
@@ -341,7 +339,9 @@
sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0];
///- Read the remaining of the packet
- ibuf.Read((char *)&buf[4], remaining);
+ LockReading();
+ ReadBuffer()->extract((uint8*)&buf[4], remaining);
+ UnlockReading();
DEBUG_LOG("[AuthChallenge] got full packet, %#04x bytes", ch->size);
DEBUG_LOG("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I);
@@ -522,19 +522,19 @@
///- Send a packet to the client with the file length and MD5 hash
uint8 data[2]={AUTH_LOGON_PROOF,REALM_AUTH_UPDATE_CLIENT};
- SendBuf((const char*)data,sizeof(data));
+ Send((const uint8*)data,sizeof(data));
memcpy(&xferh,"0\x05Patch",7);
xferh.cmd=XFER_INITIATE;
fseek(pPatch,0,SEEK_END);
xferh.file_size=ftell(pPatch);
- SendBuf((const char*)&xferh,sizeof(xferh));
+ Send((const uint8*)&xferh,sizeof(xferh));
return true;
}
}
/// </ul>
- SendBuf((char const*)pkt.contents(), pkt.size());
+ Send((uint8*)pkt.contents(), pkt.size());
return true;
}
@@ -543,11 +543,13 @@
{
DEBUG_LOG("Entering _HandleLogonProof");
///- Read the packet
- if (ibuf.GetLength() < sizeof(sAuthLogonProof_C))
+ if (ReadBuffer()->get_data_size() < sizeof(sAuthLogonProof_C))
return false;
sAuthLogonProof_C lp;
- ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C));
+ LockReading();
+ ReadBuffer()->extract((uint8*)&lp, sizeof(sAuthLogonProof_C));
+ UnlockReading();
///- Continue the SRP6 calculation based on data received from the client
BigNumber A;
@@ -639,7 +641,7 @@
proof.unk2 = 0;
proof.unk3 = 0;
- SendBuf((char *)&proof, sizeof(proof));
+ Send((uint8*)&proof, sizeof(proof));
///- Set _authed to true!
_authed = true;
@@ -647,7 +649,7 @@
else
{
char data[4]={AUTH_LOGON_PROOF,REALM_AUTH_NO_MATCH,3,0};
- SendBuf(data,sizeof(data));
+ Send((uint8*)data,sizeof(data));
}
return true;
}
@@ -656,11 +658,14 @@
bool AuthSocket::_HandleRealmList()
{
DEBUG_LOG("Entering _HandleRealmList");
- if (ibuf.GetLength() < 5)
+ if (ReadBuffer()->get_data_size() < 5)
return false;
- ibuf.Remove(5);
+ LockReading();
+ ReadBuffer()->remove(5);
+ UnlockReading();
+
///- Get the user id (else close the connection)
// No SQL injection (escaped user name)
@@ -668,7 +673,7 @@
if(!result)
{
sLog.outError("[ERROR] user %s tried to login and we cannot find him in the database.",_login.c_str());
- SetCloseAndDelete();
+ Disconnect();
return false;
}
@@ -719,7 +724,7 @@
hdr << (uint16)pkt.size();
hdr.append(pkt);
- SendBuf((char const*)hdr.contents(), hdr.size());
+ Send(hdr.contents(), hdr.size());
// Set check field before possable relogin to realm
_SetVSFields(rI);
@@ -731,7 +736,7 @@
{
DEBUG_LOG("Entering _HandleXferResume");
///- Check packet length
- if (ibuf.GetLength()<9)
+ if (ReadBuffer()->get_data_size() < 9)
{
sLog.outError("Error while resuming patch transfer (wrong packet)");
return false;
@@ -739,8 +744,10 @@
///- Launch a PatcherRunnable thread starting at given patch file offset
uint64 start;
- ibuf.Remove(1);
- ibuf.Read((char*)&start,sizeof(start));
+ LockReading();
+ ReadBuffer()->remove(1);
+ ReadBuffer()->extract((uint8*)&start, sizeof(start));
+ UnlockReading();
fseek(pPatch,start,0);
ZThread::Thread u(new PatcherRunnable(this));
@@ -753,10 +760,14 @@
DEBUG_LOG("Entering _HandleXferCancel");
///- Close and delete the socket
- ibuf.Remove(1); //clear input buffer
+ LockReading();
+ ReadBuffer()->remove(1);
+ UnlockReading();
+ //clear input buffer
//ZThread::Thread::sleep(15);
- SetCloseAndDelete();
+ /// \todo What is the difference between SetCloseAndDelete() and the this->Close() higher?
+ Disconnect();
return true;
}
@@ -766,7 +777,10 @@
{
DEBUG_LOG("Entering _HandleXferAccept");
///- Launch a PatcherRunnable thread, starting at the begining of the patch file
- ibuf.Remove(1); //clear input buffer
+ LockReading();
+ ReadBuffer()->remove(1);
+ UnlockReading();
+ //clear input buffer
fseek(pPatch,0,0);
ZThread::Thread u(new PatcherRunnable(this));
@@ -777,7 +791,7 @@
/// Check if there is lag on the connection to the client
bool AuthSocket::IsLag()
{
- return (TCP_BUFSIZE_READ-obuf.GetLength()< 2*ChunkSize);
+ return (SENDBUF_SIZE - WriteBuffer()->get_data_size() < 2 * ChunkSize);
}
PatcherRunnable::PatcherRunnable(class AuthSocket * as)
@@ -791,16 +805,16 @@
XFER_DATA_STRUCT xfdata;
xfdata.opcode = XFER_DATA;
- while(!feof(mySocket->pPatch) && mySocket->Ready())
+ while(!feof(mySocket->pPatch) && mySocket->IsConnected())
{
///- Wait until output buffer is reasonably empty
- while(mySocket->Ready() && mySocket->IsLag())
+ while(mySocket->IsConnected() && mySocket->IsLag())
{
ZThread::Thread::sleep(1);
}
///- And send content of the patch file to the client
xfdata.data_size=fread(&xfdata.data,1,ChunkSize,mySocket->pPatch);
- mySocket->SendBuf((const char*)&xfdata,xfdata.data_size +(sizeof(XFER_DATA_STRUCT)-ChunkSize));
+mySocket->Send((const uint8*)&xfdata, xfdata.data_size +(sizeof(XFER_DATA_STRUCT)-ChunkSize));
}
}
Index: src/realmd/AuthSocket.h
===================================================================
--- src/realmd/AuthSocket.h (revision 5031)
+++ src/realmd/AuthSocket.h (working copy)
@@ -25,23 +25,19 @@
#include "Common.h"
#include "Auth/BigNumber.h"
-#include "Network/TcpSocket.h"
-#include "Network/SocketHandler.h"
-#include "Network/ListenSocket.h"
-#include "Network/Utility.h"
-#include "Network/Parse.h"
-#include "Network/Socket.h"
+#include "Network/Network.h"
/// Handle login commands
-class AuthSocket: public TcpSocket
+class AuthSocket: public Socket
{
public:
const static int s_BYTE_SIZE = 32;
- AuthSocket(ISocketHandler& h);
+ AuthSocket(SOCKET h);
~AuthSocket();
- void OnAccept();
+ void OnConnect();
+ void OnDisconnect();
void OnRead();
bool _HandleLogonChallenge();
Index: src/realmd/Main.cpp
===================================================================
--- src/realmd/Main.cpp (revision 5031)
+++ src/realmd/Main.cpp (working copy)
@@ -26,7 +26,7 @@
#include "Config/ConfigEnv.h"
#include "Log.h"
-#include "Network/ListenSocket.h"
+#include "Network/Network.h"
#include "AuthSocket.h"
#include "SystemConfig.h"
#include "Util.h"
@@ -154,7 +154,23 @@
sLog.outString( "MaNGOS realm daemon %s", _FULLVERSION );
sLog.outString( "<Ctrl-C> to stop.\n" );
-
+#ifdef USE_LEVENT
+ //show version of libevent at start
+ sLog.outBasic("Using %s version of LibEvent",event_get_version());
+ bool isvalid_vlibevent=false;
+ const char* accepted_vlibevent[]=REQ_LEVENT_VER;
+ for(int i=0;accepted_vlibevent[i];i++)
+ if(!strcmp(event_get_version(),accepted_vlibevent[i]))
+ {
+ isvalid_vlibevent=true;
+ break;
+ }
+ if(!isvalid_vlibevent)
+ {
+ sLog.outError("Version of libevent is wrong, shutdown now");
+ return 1;
+ }
+#endif//USE_LEVENT
/// realmd PID file creation
std::string pidfile = sConfig.GetStringDefault("PidFile", "");
if(!pidfile.empty())
@@ -182,19 +198,6 @@
return 1;
}
- ///- Launch the listening network socket
- port_t rmport = sConfig.GetIntDefault( "RealmServerPort", DEFAULT_REALMSERVER_PORT );
-
- SocketHandler h;
- ListenSocket<AuthSocket> authListenSocket(h);
- if ( authListenSocket.Bind(rmport))
- {
- sLog.outError( "MaNGOS realmd can not bind to port %d", rmport );
- return 1;
- }
-
- h.Add(&authListenSocket);
-
///- Catch termination signals
HookSignals();
@@ -242,18 +245,27 @@
#endif
// maximum counter for next ping
- uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000));
- uint32 loopCounter = 0;
+ uint32 PingInterval = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * MINUTE * 1000);
+ uint32 RestToPing = PingInterval;
+ uint32 time_to_sleep = 100;
+ ///- Launch the listening network socket
+ uint32 rmport = sConfig.GetIntDefault( "RealmServerPort", DEFAULT_REALMSERVER_PORT );
///- Wait for termination signal
- while (!stopEvent)
+ ListenSocket<AuthSocket> authListenSocket("0.0.0.0", rmport);
+ ///- Wait for termination signal or listen socket closing
+ while (!stopEvent && authListenSocket.IsListernPortOpened())
{
+ Sleep(time_to_sleep);
+ if (RestToPing - time_to_sleep < 0)
+ RestToPing = 0;
+ else
+ RestToPing -= time_to_sleep;
+ if (RestToPing)
+ continue;
- h.Select(0, 100000);
-
- if( (++loopCounter) == numLoops )
- {
- loopCounter = 0;
+ // ping if need
+ RestToPing = PingInterval;
sLog.outDetail("Ping MySQL to keep connection alive");
delete dbRealmServer.Query("SELECT 1 FROM `realmlist` LIMIT 1");
}
@@ -261,7 +273,10 @@
if (m_ServiceStatus == 0) stopEvent = true;
while (m_ServiceStatus == 2) Sleep(1000);
#endif
- }
+ authListenSocket.StopListening();
+ sSocketManager.DisconnectAll();
+ sSocketManager.StopIOWorkers();
+ sAuthSocketManagerCleaner.Stop();
///- Wait for the delay thread to exit
dbRealmServer.HaltDelayThread();