diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 9c2a9fe65..d8dee346c 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -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(); } diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 3f8ca17a3..82d0d5800 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -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 { diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 59bcee696..d812c6eb1 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -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(); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 7e27feedf..1bf76bc3c 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -375,7 +375,7 @@ bool World::RemoveQueuedPlayer(WorldSession* sess) if (*iter == sess) { sess->SetInQueue(false); - sess->ResetTimeOutTime(); + sess->ResetTimeOutTime(false); iter = m_QueuedPlayer.erase(iter); found = true; break; @@ -394,7 +394,7 @@ bool World::RemoveQueuedPlayer(WorldSession* sess) { WorldSession* pop_sess = m_QueuedPlayer.front(); pop_sess->SetInQueue(false); - pop_sess->ResetTimeOutTime(); + pop_sess->ResetTimeOutTime(false); pop_sess->SendAuthWaitQue(0); pop_sess->SendAddonsInfo(); @@ -690,6 +690,7 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_PORT_WORLD] = sConfigMgr->GetIntDefault("WorldServerPort", 8085); m_int_configs[CONFIG_SOCKET_TIMEOUTTIME] = sConfigMgr->GetIntDefault("SocketTimeOutTime", 900000); + m_int_configs[CONFIG_SOCKET_TIMEOUTTIME_ACTIVE] = sConfigMgr->GetIntDefault("SocketTimeOutTimeActive", 60000); m_int_configs[CONFIG_SESSION_ADD_DELAY] = sConfigMgr->GetIntDefault("SessionAddDelay", 10000); m_float_configs[CONFIG_GROUP_XP_DISTANCE] = sConfigMgr->GetFloatDefault("MaxGroupXPDistance", 74.0f); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index b70c67f46..d0b2fb3de 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -330,6 +330,7 @@ enum WorldIntConfigs CONFIG_WARDEN_NUM_MEM_CHECKS, CONFIG_WARDEN_NUM_OTHER_CHECKS, CONFIG_BIRTHDAY_TIME, + CONFIG_SOCKET_TIMEOUTTIME_ACTIVE, INT_CONFIG_VALUE_COUNT }; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 481ded8c4..7bbfbc9aa 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -220,6 +220,15 @@ GridUnload = 1 SocketTimeOutTime = 900000 +# +# SocketTimeOutTimeActive +# Description: Time (in milliseconds) after which an idle connection is dropped while +# logged into the world. +# The client sends keepalive packets every 30 seconds. Values <= 30s are not recommended. +# Default: 60000 - (1 minute) + +SocketTimeOutTimeActive = 60000 + # # SessionAddDelay # Description: Time (in microseconds) that a network thread will sleep after authentication