diff options
author | Machiavelli <none@none> | 2010-02-12 19:59:44 +0100 |
---|---|---|
committer | Machiavelli <none@none> | 2010-02-12 19:59:44 +0100 |
commit | ce2d71e1d9cebbcba4a89323a4f745ae280ffa27 (patch) | |
tree | 711387990d8373f273a99f05b5b07e0c8bfc9192 | |
parent | ab146caaa86e5d0f89bdbcf967f3d620b5aa3c25 (diff) |
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
-rw-r--r-- | src/game/World.cpp | 1 | ||||
-rw-r--r-- | src/game/World.h | 1 | ||||
-rw-r--r-- | src/game/WorldSocket.cpp | 21 | ||||
-rw-r--r-- | src/game/WorldSocket.h | 4 | ||||
-rw-r--r-- | src/trinitycore/trinitycore.conf.dist | 6 |
5 files changed, 32 insertions, 1 deletions
diff --git a/src/game/World.cpp b/src/game/World.cpp index 9b92a4f56fa..f413fc7dfd1 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -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); diff --git a/src/game/World.h b/src/game/World.h index e18d1803a3d..b8d9b217562 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -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, diff --git a/src/game/WorldSocket.cpp b/src/game/WorldSocket.cpp index af6ddd4f0e5..b0e524718e4 100644 --- a/src/game/WorldSocket.cpp +++ b/src/game/WorldSocket.cpp @@ -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 diff --git a/src/game/WorldSocket.h b/src/game/WorldSocket.h index 0d2917869b9..a10a5e47f40 100644 --- a/src/game/WorldSocket.h +++ b/src/game/WorldSocket.h @@ -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 */ diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist index 6fe239f554c..e8bfddbd39f 100644 --- a/src/trinitycore/trinitycore.conf.dist +++ b/src/trinitycore/trinitycore.conf.dist @@ -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 |