Fix Autokick timer. Will work again properly for people on the char selection screen. In addition, it now also catches non-terminated, lingering sessions.

--HG--
branch : trunk
This commit is contained in:
Machiavelli
2010-05-16 03:42:05 +02:00
parent a99c6bd5a9
commit 6ee54548f3
3 changed files with 27 additions and 28 deletions
+14 -9
View File
@@ -55,6 +55,7 @@ m_latency(0), m_TutorialsChanged(false), m_timeOutTime(0)
{
m_Address = sock->GetRemoteAddress ();
sock->AddReference ();
ResetTimeOutTime();
LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = %u;", GetAccountId());
}
}
@@ -168,8 +169,16 @@ void WorldSession::LogUnprocessedTail(WorldPacket *packet)
}
/// Update the WorldSession (triggered by World update)
bool WorldSession::Update(uint32 /*diff*/)
bool WorldSession::Update(uint32 diff)
{
/// Update Timeout timer.
UpdateTimeOutTime(diff);
///- Before we process anything:
/// If necessary, kick the player from the character select screen
if (IsConnectionIdle())
m_Socket->CloseSocket();
///- Retrieve packets from the receive queue and call the appropriate handlers
/// not proccess packets if socket already closed
WorldPacket* packet;
@@ -275,9 +284,10 @@ bool WorldSession::Update(uint32 /*diff*/)
delete packet;
}
///- If necessary, kick the player from the character select screen
if (IsConnectionIdle())
m_Socket->CloseSocket();
time_t currTime = time(NULL);
///- If necessary, log the player out
if (ShouldLogOut(currTime) && !m_playerLoading)
LogoutPlayer(true);
///- Cleanup socket pointer if need
if (m_Socket && m_Socket->IsClosed())
@@ -286,11 +296,6 @@ bool WorldSession::Update(uint32 /*diff*/)
m_Socket = NULL;
}
///- If necessary, log the player out
time_t currTime = time(NULL);
if (!m_Socket || (ShouldLogOut(currTime) && !m_playerLoading))
LogoutPlayer(true);
if (!m_Socket)
return false; //Will remove this session from the world session map
+9 -5
View File
@@ -287,16 +287,20 @@ class WorldSession
uint32 getDialogStatus(Player *pPlayer, Object* questgiver, uint32 defstatus);
time_t m_timeOutTime;
void UpdateTimeOutTime(bool b)
void UpdateTimeOutTime(uint32 diff)
{
if (b)
m_timeOutTime = time(NULL) + sWorld.getConfig(CONFIG_SOCKET_TIMEOUTTIME) / IN_MILISECONDS;
else
if (diff > m_timeOutTime)
m_timeOutTime = 0;
else
m_timeOutTime -= diff;
}
void ResetTimeOutTime()
{
m_timeOutTime = sWorld.getConfig(CONFIG_SOCKET_TIMEOUTTIME);
}
bool IsConnectionIdle() const
{
if (m_timeOutTime && m_timeOutTime <= time(NULL))
if (m_timeOutTime <= 0)
return true;
return false;
}
+3 -13
View File
@@ -729,19 +729,9 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
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 WorldSession::Update.
*/
if (opcode == CMSG_CHAR_ENUM)
m_Session->UpdateTimeOutTime(true);
/* If we're sending any other 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
m_Session->UpdateTimeOutTime(false);
// 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();
// OK ,give the packet to WorldSession
aptr.release();