Add config option that determines the maximum allowed time between the last received CMSG_CHAR_ENUM and another incoming packet, and will disconnect the peer if this time limit is exceeded.

In other words, a time limit in which idlers can stay logged in on the character selection screen before they are disconnected.
Fixes issue #335

--HG--
branch : trunk
This commit is contained in:
Machiavelli
2010-02-12 19:59:44 +01:00
parent ab146caaa8
commit ce2d71e1d9
5 changed files with 32 additions and 1 deletions

View File

@@ -648,6 +648,7 @@ void World::LoadConfigSettings(bool reload)
else
m_configs[CONFIG_SOCKET_SELECTTIME] = sConfig.GetIntDefault("SocketSelectTime", DEFAULT_SOCKET_SELECT_TIME);
m_configs[CONFIG_SOCKET_TIMEOUTTIME] = sConfig.GetIntDefault("SocketTimeOutTime", 900000);
m_configs[CONFIG_GROUP_XP_DISTANCE] = sConfig.GetIntDefault("MaxGroupXPDistance", 74);
/// \todo Add MonsterSight and GuarderSight (with meaning) in Trinityd.conf or put them as define
m_configs[CONFIG_SIGHT_MONSTER] = sConfig.GetIntDefault("MonsterSight", 50);

View File

@@ -106,6 +106,7 @@ enum WorldConfigs
CONFIG_INTERVAL_DISCONNECT_TOLERANCE,
CONFIG_PORT_WORLD,
CONFIG_SOCKET_SELECTTIME,
CONFIG_SOCKET_TIMEOUTTIME,
CONFIG_GROUP_XP_DISTANCE,
CONFIG_SIGHT_MONSTER,
CONFIG_SIGHT_GUARDER,

View File

@@ -110,7 +110,8 @@ m_OutBufferSize (65536),
m_OutActive (false),
m_Seed (static_cast<uint32> (rand32 ())),
m_OverSpeedPings (0),
m_LastPingTime (ACE_Time_Value::zero)
m_LastPingTime (ACE_Time_Value::zero),
m_TimeOutTime (0)
{
reference_counting_policy ().value (ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
}
@@ -407,6 +408,10 @@ int WorldSocket::Update (void)
if (closing_)
return -1;
if (m_TimeOutTime &&
time(NULL) >= m_TimeOutTime)
return -1;
if (m_OutActive || m_OutBuffer->length () == 0)
return 0;
@@ -656,6 +661,20 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
{
ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);
/* The m_TimeOutTime measure is put in to be able to automatically disconnect connections
that are sitting idle on the character select screen. After a period of being AFK in the realm,
the client will be automatically sent back to the character selection screen. In order to pick up
the idle connections and prevent they are sitting there, taking up slots for the realm, we'll check if the packet
that was sent is CMSG_CHAR_ENUM and initiate the timeout timer that will be checked on WorldSocket::Update.
*/
if (opcode == CMSG_CHAR_ENUM)
m_TimeOutTime = time(NULL) + sWorld.getConfig(CONFIG_SOCKET_TIMEOUTTIME) / IN_MILISECONDS;
/* If the packet is CMSG_PLAYER_LOGIN opcode, it means our connection is not idle, we're logging into the world.
Until we receive our next CMSG_CHAR_ENUM packet, we can disregard the timeout timer.
*/
else if (opcode == CMSG_PLAYER_LOGIN)
m_TimeOutTime = 0;
if (m_Session != NULL)
{
// OK ,give the packet to WorldSession

View File

@@ -232,6 +232,10 @@ class WorldSocket : protected WorldHandler
bool m_OutActive;
uint32 m_Seed;
/// The defined time where the socket will be forced to close. This is
/// to detect and close idle connections.
time_t m_TimeOutTime;
};
#endif /* _WORLDSOCKET_H */

View File

@@ -124,6 +124,11 @@ EAIErrorLevel = 2
# Socket select time (in milliseconds)
# Default: 10000 (10 secs)
#
# SocketTimeOutTime
# Time in milliseconds afer which a connection sitting idle on the character
# selection screen is disconnected.
# Default: 900000 (15 minutes)
#
# GridCleanUpDelay
# Grid clean up delay (in milliseconds)
# Default: 300000 (5 min)
@@ -217,6 +222,7 @@ SaveRespawnTimeImmediately = 1
MaxOverspeedPings = 2
GridUnload = 1
SocketSelectTime = 10000
SocketTimeOutTime = 900000
GridCleanUpDelay = 300000
MapUpdateInterval = 100
ChangeWeatherInterval = 600000