mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-21 20:56:23 +00:00
Core/Session: proper client timeout detection (#1232)
* Core/Session: proper client timeout detection - Properly detect client timeout when logged into a character after a configurable time (default 60s) has passed without the client sending any packets. - Fixes issues with crashed clients leaving characters in the world for a very long time (default 15 minutes), as well as edge case exploits involving intentionally pausing client execution for some amount of time.
This commit is contained in:
@@ -125,7 +125,7 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8
|
||||
{
|
||||
m_Address = sock->GetRemoteAddress();
|
||||
sock->AddReference();
|
||||
ResetTimeOutTime();
|
||||
ResetTimeOutTime(false);
|
||||
LoginDatabase.PExecute("UPDATE account SET online = online | (1<<(%u-1)) WHERE id = %u;", realmID, GetAccountId());
|
||||
}
|
||||
|
||||
@@ -251,6 +251,9 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
||||
if (updater.ProcessLogout())
|
||||
{
|
||||
UpdateTimeOutTime(diff);
|
||||
|
||||
/// If necessary, kick the player because the client didn't send anything for too long
|
||||
/// (or they've been idling in character select)
|
||||
if (IsConnectionIdle())
|
||||
m_Socket->CloseSocket();
|
||||
}
|
||||
|
||||
@@ -355,9 +355,12 @@ class WorldSession
|
||||
else
|
||||
m_timeOutTime -= diff;
|
||||
}
|
||||
void ResetTimeOutTime()
|
||||
void ResetTimeOutTime(bool onlyActive)
|
||||
{
|
||||
m_timeOutTime = sWorld->getIntConfig(CONFIG_SOCKET_TIMEOUTTIME);
|
||||
if (GetPlayer())
|
||||
m_timeOutTime = int32(sWorld->getIntConfig(CONFIG_SOCKET_TIMEOUTTIME_ACTIVE));
|
||||
else if (!onlyActive)
|
||||
m_timeOutTime = int32(sWorld->getIntConfig(CONFIG_SOCKET_TIMEOUTTIME));
|
||||
}
|
||||
bool IsConnectionIdle() const
|
||||
{
|
||||
|
||||
@@ -681,8 +681,10 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
|
||||
return -1;
|
||||
}
|
||||
return HandleAuthSession (*new_pct);
|
||||
case CMSG_KEEP_ALIVE:
|
||||
return 0;
|
||||
case CMSG_KEEP_ALIVE:
|
||||
if (m_Session)
|
||||
m_Session->ResetTimeOutTime(true);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);
|
||||
@@ -691,7 +693,7 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
|
||||
{
|
||||
// Our Idle timer will reset on any non PING opcodes.
|
||||
// Catches people idling on the login screen and any lingering ingame connections.
|
||||
m_Session->ResetTimeOutTime();
|
||||
m_Session->ResetTimeOutTime(false);
|
||||
|
||||
// OK, give the packet to WorldSession
|
||||
aptr.release();
|
||||
|
||||
Reference in New Issue
Block a user