Properly deregister WorldSocket connections in case of reaching socket timeout time.

--HG--
branch : trunk
This commit is contained in:
Machiavelli
2010-04-23 12:56:16 +02:00
parent b142ae155e
commit c4e4486903
4 changed files with 38 additions and 25 deletions

View File

@@ -49,7 +49,7 @@ LookingForGroup_auto_join(false), LookingForGroup_auto_add(false), m_muteTime(mu
_player(NULL), m_Socket(sock),_security(sec), _accountId(id), m_expansion(expansion),
m_sessionDbcLocale(sWorld.GetAvailableDbcLocale(locale)), m_sessionDbLocaleIndex(objmgr.GetIndexForLocale(locale)),
_logoutTime(0), m_inQueue(false), m_playerLoading(false), m_playerLogout(false), m_playerRecentlyLogout(false), m_playerSave(false),
m_latency(0), m_TutorialsChanged(false)
m_latency(0), m_TutorialsChanged(false), m_timeOutTime(0)
{
if (sock)
{
@@ -180,7 +180,7 @@ bool WorldSession::Update(uint32 /*diff*/)
LookupOpcodeName(packet->GetOpcode()),
packet->GetOpcode());
#endif*/
if (packet->GetOpcode() >= NUM_MSG_TYPES)
{
sLog.outError("SESSION: received non-existed opcode %s (0x%.4X)",
@@ -287,6 +287,10 @@ bool WorldSession::Update(uint32 /*diff*/)
if (!m_Socket || (ShouldLogOut(currTime) && !m_playerLoading))
LogoutPlayer(true);
///- If necessary, kick the player from the character select screen
if (IsConnectionIdle())
return false;
if (!m_Socket)
return false; //Will remove this session from the world session map

View File

@@ -29,6 +29,7 @@
#include "SharedDefines.h"
#include "AddonMgr.h"
#include "QueryResult.h"
#include "World.h"
struct ItemPrototype;
struct AuctionEntry;
@@ -283,6 +284,22 @@ class WorldSession
uint32 GetLatency() const { return m_latency; }
void SetLatency(uint32 latency) { m_latency = latency; }
uint32 getDialogStatus(Player *pPlayer, Object* questgiver, uint32 defstatus);
time_t m_timeOutTime;
void UpdateTimeOutTime(bool b)
{
if (b)
m_timeOutTime = time(NULL) + sWorld.getConfig(CONFIG_SOCKET_TIMEOUTTIME) / IN_MILISECONDS;
else
m_timeOutTime = 0;
}
bool IsConnectionIdle() const
{
if (m_timeOutTime && m_timeOutTime <= time(NULL))
return true;
return false;
}
public: // opcodes handlers

View File

@@ -110,8 +110,7 @@ m_OutBufferSize (65536),
m_OutActive (false),
m_Seed (static_cast<uint32> (rand32 ())),
m_OverSpeedPings (0),
m_LastPingTime (ACE_Time_Value::zero),
m_TimeOutTime (0)
m_LastPingTime (ACE_Time_Value::zero)
{
reference_counting_policy ().value (ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
}
@@ -412,10 +411,6 @@ 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;
@@ -665,22 +660,22 @@ 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)
{
/* 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_Session->UpdateTimeOutTime(true);
/* 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_Session->UpdateTimeOutTime(false);
// OK ,give the packet to WorldSession
aptr.release ();
// WARNINIG here we call it with locks held.

View File

@@ -233,9 +233,6 @@ class WorldSocket : protected WorldHandler
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 */