From aad9e271dbea06dc471765b9c986f711fbcc4b2c Mon Sep 17 00:00:00 2001 From: lotodore Date: Sun, 11 Dec 2011 14:54:17 +0000 Subject: [PATCH] Cleaning up the different timeouts and how players can be removed from the game. --- src/net/clientstate.h | 2 +- src/net/clientthread.h | 2 + src/net/common/clientstate.cpp | 11 +++ src/net/common/clientthread.cpp | 3 +- src/net/common/sendbuffer.cpp | 4 +- src/net/common/senderhelper.cpp | 12 +++ src/net/common/servergame.cpp | 15 +-- src/net/common/serverlobbythread.cpp | 137 +++++++-------------------- src/net/common/sessiondata.cpp | 104 ++++++++++++++------ src/net/sendbuffer.h | 5 + src/net/senderhelper.h | 2 + src/net/servergame.h | 3 +- src/net/serverlobbythread.h | 7 +- src/net/sessiondata.h | 23 +++-- src/net/sessiondatacallback.h | 2 + src/session.cpp | 10 +- 16 files changed, 175 insertions(+), 167 deletions(-) diff --git a/src/net/clientstate.h b/src/net/clientstate.h index df52daef..1f1ee81b 100644 --- a/src/net/clientstate.h +++ b/src/net/clientstate.h @@ -274,7 +274,7 @@ public: virtual void Enter(boost::shared_ptr client); virtual void Exit(boost::shared_ptr client); - virtual void HandlePacket(boost::shared_ptr /*client*/, boost::shared_ptr /*tmpPacket*/) {} + virtual void HandlePacket(boost::shared_ptr client, boost::shared_ptr tmpPacket); protected: diff --git a/src/net/clientthread.h b/src/net/clientthread.h index db9365b5..3d5adaa6 100644 --- a/src/net/clientthread.h +++ b/src/net/clientthread.h @@ -87,6 +87,8 @@ public: void StartAsyncRead(); virtual void CloseSession(boost::shared_ptr session); + virtual void SessionError(boost::shared_ptr /*session*/, int /*errorCode*/) {} + virtual void SessionTimeoutWarning(boost::shared_ptr /*session*/, unsigned /*remainingSec*/) {} virtual void HandlePacket(boost::shared_ptr session, boost::shared_ptr packet); void SelectServer(unsigned serverId); diff --git a/src/net/common/clientstate.cpp b/src/net/common/clientstate.cpp index 5d1b93d8..40fe0aa7 100644 --- a/src/net/common/clientstate.cpp +++ b/src/net/common/clientstate.cpp @@ -1010,6 +1010,17 @@ ClientStateWaitEnterLogin::Exit(boost::shared_ptr client) client->GetStateTimer().cancel(); } +void +ClientStateWaitEnterLogin::HandlePacket(boost::shared_ptr client, boost::shared_ptr tmpPacket) +{ + if (tmpPacket->GetMsg()->present == PokerTHMessage_PR_errorMessage) { + // Server reported an error. + ErrorMessage_t *netError = &tmpPacket->GetMsg()->choice.errorMessage; + // Show the error. + throw ClientException(__FILE__, __LINE__, NetPacket::NetErrorToGameError(netError->errorReason), 0); + } +} + void ClientStateWaitEnterLogin::TimerLoop(const boost::system::error_code& ec, boost::shared_ptr client) { diff --git a/src/net/common/clientthread.cpp b/src/net/common/clientthread.cpp index c00e2259..1657439e 100644 --- a/src/net/common/clientthread.cpp +++ b/src/net/common/clientthread.cpp @@ -926,7 +926,8 @@ ClientThread::CreateContextSession() GetContext().SetSessionData(boost::shared_ptr(new SessionData( newSock, SESSION_ID_GENERIC, - *this))); + *this, + *m_ioService))); GetContext().SetResolver(boost::shared_ptr( new boost::asio::ip::tcp::resolver(*m_ioService))); validSocket = true; diff --git a/src/net/common/sendbuffer.cpp b/src/net/common/sendbuffer.cpp index 73167c4e..38284dbf 100644 --- a/src/net/common/sendbuffer.cpp +++ b/src/net/common/sendbuffer.cpp @@ -27,7 +27,7 @@ using namespace std; SendBuffer::SendBuffer() : sendBuf(NULL), curWriteBuf(NULL), sendBufAllocated(0), sendBufUsed(0), - curWriteBufAllocated(0), curWriteBufUsed(0) + curWriteBufAllocated(0), curWriteBufUsed(0), closeAfterSend(false) { } @@ -65,6 +65,8 @@ SendBuffer::AsyncSendNextPacket(boost::shared_ptr shared_from_this(), socket, boost::asio::placeholders::error)); + } else if (closeAfterSend) { + socket->close(); } } } diff --git a/src/net/common/senderhelper.cpp b/src/net/common/senderhelper.cpp index 356af6aa..fd1df9a0 100644 --- a/src/net/common/senderhelper.cpp +++ b/src/net/common/senderhelper.cpp @@ -68,6 +68,18 @@ SenderHelper::Send(boost::shared_ptr session, const NetPacketList & } } +void +SenderHelper::SetCloseAfterSend(boost::shared_ptr session) +{ + SendBuffer &tmpBuffer = session->GetSendBuffer(); + // Add packet to specific queue. + boost::mutex::scoped_lock lock(tmpBuffer.dataMutex); + // Mark that the socket should be closed after the send operation. + tmpBuffer.SetCloseAfterSend(); + // Activate async send, if needed. + tmpBuffer.AsyncSendNextPacket(session->GetAsioSocket()); +} + void SenderHelper::InternalStorePacket(SendBuffer &tmpBuffer, boost::shared_ptr packet) { diff --git a/src/net/common/servergame.cpp b/src/net/common/servergame.cpp index 7f724d8d..611d8c7e 100644 --- a/src/net/common/servergame.cpp +++ b/src/net/common/servergame.cpp @@ -135,7 +135,7 @@ void ServerGame::RemoveAllSessions() { // Clean up ALL sessions which are left. - GetSessionManager().ForEach(boost::bind(&ServerLobbyThread::RemoveSessionFromGame, boost::ref(*m_lobbyThread), _1)); + GetSessionManager().ForEach(&SessionData::Close); GetSessionManager().Clear(); SetState(ServerGameStateFinal::Instance()); } @@ -726,7 +726,7 @@ ServerGame::ResetComputerPlayerList() } void -ServerGame::GracefulRemoveSession(boost::shared_ptr session, int reason) +ServerGame::RemoveSession(boost::shared_ptr session, int reason) { if (!session) throw ServerException(__FILE__, __LINE__, ERR_NET_INVALID_SESSION, 0); @@ -794,26 +794,19 @@ ServerGame::RemovePlayerData(boost::shared_ptr player, int reason) GetLobbyThread().NotifyPlayerLeftGame(GetId(), player->GetUniqueId()); } -void -ServerGame::ErrorRemoveSession(boost::shared_ptr session) -{ - GetLobbyThread().RemoveSessionFromGame(session); - GracefulRemoveSession(session, NTF_NET_INTERNAL); -} - void ServerGame::SessionError(boost::shared_ptr session, int errorCode) { if (!session) throw ServerException(__FILE__, __LINE__, ERR_NET_INVALID_SESSION, 0); - ErrorRemoveSession(session); + RemoveSession(session, NTF_NET_INTERNAL); GetLobbyThread().SessionError(session, errorCode); } void ServerGame::MoveSessionToLobby(boost::shared_ptr session, int reason) { - GracefulRemoveSession(session, reason); + RemoveSession(session, reason); // Reset ready flag - just in case it is set, player may leave at any time. session->ResetReadyFlag(); GetLobbyThread().ReAddSession(session, reason, GetId()); diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index 2a80f650..2c9f02a5 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -54,7 +54,6 @@ #define SERVER_MAX_NUM_LOBBY_SESSIONS 512 // Maximum number of idle users in lobby. #define SERVER_MAX_NUM_TOTAL_SESSIONS 2000 // Total maximum of sessions, fitting a 2048 handle limit -#define SERVER_CACHE_CLEANUP_INTERVAL_SEC 86400 // 1 day #define SERVER_SAVE_STATISTICS_INTERVAL_SEC 60 #define SERVER_CHECK_SESSION_TIMEOUTS_INTERVAL_MSEC 500 #define SERVER_REMOVE_GAME_INTERVAL_MSEC 500 @@ -92,7 +91,15 @@ public: virtual ~InternalServerCallback() {} virtual void CloseSession(boost::shared_ptr session) { - m_server.CloseSession(session->GetId()); + m_server.CloseSession(session); + } + + virtual void SessionError(boost::shared_ptr session, int errorCode) { + m_server.SessionError(session, errorCode); + } + + virtual void SessionTimeoutWarning(boost::shared_ptr session, unsigned remainingSec) { + m_server.SessionTimeoutWarning(session, remainingSec); } virtual void HandlePacket(boost::shared_ptr session, boost::shared_ptr packet) { @@ -178,7 +185,6 @@ ServerLobbyThread::ServerLobbyThread(GuiInterface &gui, ServerMode mode, ServerI : m_ioService(ioService), m_authContext(NULL), m_gui(gui), m_ircBotCb(ircBotCb), m_avatarManager(avatarManager), m_mode(mode), m_serverConfig(serverConfig), m_curGameId(0), m_curUniquePlayerId(0), m_curSessionId(INVALID_SESSION + 1), m_statDataChanged(false), m_removeGameTimer(*ioService), m_removePlayerTimer(*ioService), - m_sessionTimeoutTimer(*ioService), m_avatarCleanupTimer(*ioService), m_saveStatisticsTimer(*ioService), m_loginLockTimer(*ioService), m_startTime(boost::posix_time::second_clock::local_time()) { @@ -228,11 +234,15 @@ void ServerLobbyThread::AddConnection(boost::shared_ptr sock) { // Create a new session. - boost::shared_ptr sessionData(new SessionData(sock, m_curSessionId++, *m_internalServerCallback)); + boost::shared_ptr sessionData(new SessionData(sock, m_curSessionId++, *m_internalServerCallback, GetIOService())); m_sessionManager.AddSession(sessionData); LOG_VERBOSE("Accepted connection - session #" << sessionData->GetId() << "."); + sessionData->StartTimerInitTimeout(SERVER_INIT_SESSION_TIMEOUT_SEC); + sessionData->StartTimerGlobalTimeout(SERVER_SESSION_FORCED_TIMEOUT_SEC); + sessionData->StartTimerActivityTimeout(SERVER_SESSION_ACTIVITY_TIMEOUT_SEC, SERVER_TIMEOUT_WARNING_REMAINING_SEC); + bool hasClientIp = false; unsigned numLobbySessions = m_sessionManager.GetRawSessionCount(); unsigned numGameSessions = m_gameSessionManager.GetRawSessionCount(); @@ -340,36 +350,19 @@ ServerLobbyThread::MoveSessionToGame(boost::shared_ptr game, boost:: game->SetPlayerAutoLeaveOnFinish(session->GetPlayerData()->GetUniqueId()); } -void -ServerLobbyThread::RemoveSessionFromGame(boost::shared_ptr session) -{ - // Just remove the session. Only for fatal errors. - CloseSession(session); -} - -void -ServerLobbyThread::CloseSession(SessionId sessionId) -{ - boost::shared_ptr session = m_sessionManager.GetSessionById(sessionId); - if (!session) - session = m_gameSessionManager.GetSessionById(sessionId); - if (session) { - boost::shared_ptr tmpGame = session->GetGame(); - if (tmpGame) { - tmpGame->ErrorRemoveSession(session); - } else { - CloseSession(session); - } - } -} - void ServerLobbyThread::CloseSession(boost::shared_ptr session) { if (session && session->GetState() != SessionData::Closed) { // Make this call reentrant. LOG_VERBOSE("Closing session #" << session->GetId() << "."); + session->SetState(SessionData::Closed); + boost::shared_ptr tmpGame = session->GetGame(); + if (tmpGame) { + tmpGame->RemoveSession(session, NTF_NET_INTERNAL); + } + m_sessionManager.RemoveSession(session->GetId()); m_gameSessionManager.RemoveSession(session->GetId()); @@ -378,6 +371,11 @@ ServerLobbyThread::CloseSession(boost::shared_ptr session) // Update stats (if needed). UpdateStatisticsNumberOfPlayers(); session->SetGame(boost::shared_ptr()); + session->GetAsioSocket()->shutdown(boost::asio::ip::tcp::socket::shutdown_receive); + // Close this session after send. + GetSender().SetCloseAfterSend(session); + // Cancel all timers of the session. + session->CancelTimers(); } } @@ -773,18 +771,6 @@ ServerLobbyThread::RegisterTimers() m_removePlayerTimer.async_wait( boost::bind( &ServerLobbyThread::TimerRemovePlayer, shared_from_this(), boost::asio::placeholders::error)); - // Check the timeout of sessions which have not been initialised. - m_sessionTimeoutTimer.expires_from_now( - boost::posix_time::milliseconds(SERVER_CHECK_SESSION_TIMEOUTS_INTERVAL_MSEC)); - m_sessionTimeoutTimer.async_wait( - boost::bind( - &ServerLobbyThread::TimerCheckSessionTimeouts, shared_from_this(), boost::asio::placeholders::error)); - // Cleanup the avatar cache. Note: Only works if there are no users on the server. - m_avatarCleanupTimer.expires_from_now( - boost::posix_time::seconds(SERVER_CACHE_CLEANUP_INTERVAL_SEC)); - m_avatarCleanupTimer.async_wait( - boost::bind( - &ServerLobbyThread::TimerCleanupAvatarCache, shared_from_this(), boost::asio::placeholders::error)); // Update the statistics file. m_saveStatisticsTimer.expires_from_now( boost::posix_time::seconds(SERVER_SAVE_STATISTICS_INTERVAL_SEC)); @@ -804,8 +790,6 @@ ServerLobbyThread::CancelTimers() { m_removeGameTimer.cancel(); m_removePlayerTimer.cancel(); - m_sessionTimeoutTimer.cancel(); - m_avatarCleanupTimer.cancel(); m_saveStatisticsTimer.cancel(); m_loginLockTimer.cancel(); } @@ -1709,40 +1693,6 @@ ServerLobbyThread::TimerUpdateClientLoginLock(const boost::system::error_code &e } } -void -ServerLobbyThread::TimerCheckSessionTimeouts(const boost::system::error_code &ec) -{ - if (!ec) { - m_sessionManager.ForEach(boost::bind(&ServerLobbyThread::InternalCheckSessionTimeouts, boost::ref(*this), _1)); - m_gameSessionManager.ForEach(boost::bind(&ServerLobbyThread::InternalCheckSessionTimeouts, boost::ref(*this), _1)); - // Restart timer - m_sessionTimeoutTimer.expires_from_now( - boost::posix_time::milliseconds(SERVER_CHECK_SESSION_TIMEOUTS_INTERVAL_MSEC)); - m_sessionTimeoutTimer.async_wait( - boost::bind( - &ServerLobbyThread::TimerCheckSessionTimeouts, shared_from_this(), boost::asio::placeholders::error)); - } -} - -void -ServerLobbyThread::TimerCleanupAvatarCache(const boost::system::error_code &ec) -{ - if (!ec) { - // Only act if there are no sessions. - if (!m_sessionManager.HasSessions() && !m_gameSessionManager.HasSessions()) { - LOG_VERBOSE("Cleaning up avatar cache."); - - m_avatarManager.RemoveOldAvatarCacheEntries(); - } - // Restart timer - m_avatarCleanupTimer.expires_from_now( - boost::posix_time::seconds(SERVER_CACHE_CLEANUP_INTERVAL_SEC)); - m_avatarCleanupTimer.async_wait( - boost::bind( - &ServerLobbyThread::TimerCleanupAvatarCache, shared_from_this(), boost::asio::placeholders::error)); - } -} - bool ServerLobbyThread::IsGameNameInUse(const std::string &gameName) const { @@ -1877,37 +1827,14 @@ ServerLobbyThread::HandleReAddedSession(boost::shared_ptr session) } void -ServerLobbyThread::InternalCheckSessionTimeouts(boost::shared_ptr session) +ServerLobbyThread::SessionTimeoutWarning(boost::shared_ptr session, unsigned remainingSec) { - bool closeSession = false; - if (session) { - if (session->GetState() == SessionData::Init && session->GetAutoDisconnectTimerElapsedSec() >= SERVER_INIT_SESSION_TIMEOUT_SEC) { - LOG_VERBOSE("Session init timeout, removing session #" << session->GetId() << "."); - closeSession = true; - } else if (session->GetActivityTimerElapsedSec() >= SERVER_SESSION_ACTIVITY_TIMEOUT_SEC - SERVER_TIMEOUT_WARNING_REMAINING_SEC - && !session->HasActivityNoticeBeenSent()) { - session->MarkActivityNotice(); - - boost::shared_ptr packet(new NetPacket(NetPacket::Alloc)); - packet->GetMsg()->present = PokerTHMessage_PR_timeoutWarningMessage; - TimeoutWarningMessage_t *netWarning = &packet->GetMsg()->choice.timeoutWarningMessage; - netWarning->timeoutReason = timeoutReason_timeoutNoDataReceived; - netWarning->remainingSeconds = SERVER_TIMEOUT_WARNING_REMAINING_SEC; - GetSender().Send(session, packet); - } else if (session->GetActivityTimerElapsedSec() >= SERVER_SESSION_ACTIVITY_TIMEOUT_SEC) { - LOG_VERBOSE("Activity timeout, removing session #" << session->GetId() << "."); - closeSession = true; - } else if (session->GetAutoDisconnectTimerElapsedSec() >= SERVER_SESSION_FORCED_TIMEOUT_SEC) { - LOG_VERBOSE("Auto disconnect timeout, removing session #" << session->GetId() << "."); - closeSession = true; - } - } - if (closeSession) { - if (session->GetPlayerData()) - RemovePlayer(session->GetPlayerData()->GetUniqueId(), ERR_NET_SESSION_TIMED_OUT); - else - m_sessionManager.RemoveSession(session->GetId()); - } + boost::shared_ptr packet(new NetPacket(NetPacket::Alloc)); + packet->GetMsg()->present = PokerTHMessage_PR_timeoutWarningMessage; + TimeoutWarningMessage_t *netWarning = &packet->GetMsg()->choice.timeoutWarningMessage; + netWarning->timeoutReason = timeoutReason_timeoutNoDataReceived; + netWarning->remainingSeconds = remainingSec; + GetSender().Send(session, packet); } void diff --git a/src/net/common/sessiondata.cpp b/src/net/common/sessiondata.cpp index a899b0a4..7b7c8850 100644 --- a/src/net/common/sessiondata.cpp +++ b/src/net/common/sessiondata.cpp @@ -19,16 +19,15 @@ #include #include #include +#include #include using namespace std; -SessionData::SessionData(boost::shared_ptr sock, SessionId id, SessionDataCallback &cb) +SessionData::SessionData(boost::shared_ptr sock, SessionId id, SessionDataCallback &cb, boost::asio::io_service &ioService) : m_socket(sock), m_id(id), m_state(SessionData::Init), m_readyFlag(false), m_wantsLobbyMsg(true), - m_activityTimer(boost::posix_time::time_duration(0, 0, 0), boost::timers::portable::microsec_timer::auto_start), - m_activityTimeoutNoticeSent(false), - m_autoDisconnectTimer(boost::posix_time::time_duration(0, 0, 0), boost::timers::portable::microsec_timer::auto_start), - m_callback(cb), m_authSession(NULL), m_curAuthStep(0) + m_activityTimeoutSec(0), m_activityWarningRemainingSec(0), m_initTimeoutTimer(ioService), m_globalTimeoutTimer(ioService), + m_activityTimeoutTimer(ioService), m_callback(cb), m_authSession(NULL), m_curAuthStep(0) { m_receiveBuffer.reset(new ReceiveBuffer); m_sendBuffer.reset(new SendBuffer); @@ -178,6 +177,38 @@ SessionData::InternalClearAuthSession() } } +void +SessionData::TimerInitTimeout(const boost::system::error_code &ec) +{ + if (!ec) { + if (GetState() == SessionData::Init) { + m_callback.SessionError(shared_from_this(), ERR_NET_SESSION_TIMED_OUT); + } + } +} + +void +SessionData::TimerSessionTimeout(const boost::system::error_code &ec) +{ + if (!ec) { + m_callback.SessionError(shared_from_this(), ERR_NET_SESSION_TIMED_OUT); + } +} + +void +SessionData::TimerActivityWarning(const boost::system::error_code &ec) +{ + if (!ec) { + m_callback.SessionTimeoutWarning(shared_from_this(), m_activityWarningRemainingSec); + + m_activityTimeoutTimer.expires_from_now( + boost::posix_time::seconds(m_activityWarningRemainingSec)); + m_activityTimeoutTimer.async_wait( + boost::bind( + &SessionData::TimerSessionTimeout, shared_from_this(), boost::asio::placeholders::error)); + } +} + void SessionData::SetReadyFlag() { @@ -238,37 +269,56 @@ void SessionData::ResetActivityTimer() { boost::mutex::scoped_lock lock(m_dataMutex); - m_activityTimeoutNoticeSent = false; - m_activityTimer.reset(); - m_activityTimer.start(); -} - -unsigned -SessionData::GetActivityTimerElapsedSec() const -{ - boost::mutex::scoped_lock lock(m_dataMutex); - return m_activityTimer.elapsed().total_seconds(); -} - -bool -SessionData::HasActivityNoticeBeenSent() const -{ - boost::mutex::scoped_lock lock(m_dataMutex); - return m_activityTimeoutNoticeSent; + m_activityTimeoutTimer.expires_from_now( + boost::posix_time::seconds(m_activityTimeoutSec - m_activityWarningRemainingSec)); + m_activityTimeoutTimer.async_wait( + boost::bind( + &SessionData::TimerActivityWarning, shared_from_this(), boost::asio::placeholders::error)); } void -SessionData::MarkActivityNotice() +SessionData::StartTimerInitTimeout(unsigned timeoutSec) { boost::mutex::scoped_lock lock(m_dataMutex); - m_activityTimeoutNoticeSent = true; + m_initTimeoutTimer.expires_from_now( + boost::posix_time::seconds(timeoutSec)); + m_initTimeoutTimer.async_wait( + boost::bind( + &SessionData::TimerInitTimeout, shared_from_this(), boost::asio::placeholders::error)); } -unsigned -SessionData::GetAutoDisconnectTimerElapsedSec() const +void +SessionData::StartTimerGlobalTimeout(unsigned timeoutSec) { boost::mutex::scoped_lock lock(m_dataMutex); - return m_autoDisconnectTimer.elapsed().total_seconds(); + m_globalTimeoutTimer.expires_from_now( + boost::posix_time::seconds(timeoutSec)); + m_globalTimeoutTimer.async_wait( + boost::bind( + &SessionData::TimerSessionTimeout, shared_from_this(), boost::asio::placeholders::error)); +} + +void +SessionData::StartTimerActivityTimeout(unsigned timeoutSec, unsigned warningRemainingSec) +{ + boost::mutex::scoped_lock lock(m_dataMutex); + m_activityTimeoutSec = timeoutSec; + m_activityWarningRemainingSec = warningRemainingSec; + + m_activityTimeoutTimer.expires_from_now( + boost::posix_time::seconds(timeoutSec - warningRemainingSec)); + m_activityTimeoutTimer.async_wait( + boost::bind( + &SessionData::TimerActivityWarning, shared_from_this(), boost::asio::placeholders::error)); +} + +void +SessionData::CancelTimers() +{ + boost::mutex::scoped_lock lock(m_dataMutex); + m_initTimeoutTimer.cancel(); + m_globalTimeoutTimer.cancel(); + m_activityTimeoutTimer.cancel(); } void diff --git a/src/net/sendbuffer.h b/src/net/sendbuffer.h index 62c7e30d..253d6002 100644 --- a/src/net/sendbuffer.h +++ b/src/net/sendbuffer.h @@ -67,6 +67,10 @@ public: sendBufUsed += size; } + inline void SetCloseAfterSend() { + closeAfterSend = true; + } + void HandleWrite(boost::shared_ptr socket, const boost::system::error_code &error); void AsyncSendNextPacket(boost::shared_ptr socket); @@ -81,6 +85,7 @@ private: size_t sendBufUsed; size_t curWriteBufAllocated; size_t curWriteBufUsed; + bool closeAfterSend; }; #endif diff --git a/src/net/senderhelper.h b/src/net/senderhelper.h index 8d2d91be..4fe425ed 100644 --- a/src/net/senderhelper.h +++ b/src/net/senderhelper.h @@ -35,6 +35,8 @@ public: void Send(boost::shared_ptr session, boost::shared_ptr packet); void Send(boost::shared_ptr session, const NetPacketList &packetList); + void SetCloseAfterSend(boost::shared_ptr session); + protected: void InternalStorePacket(SendBuffer &tmpManager, boost::shared_ptr packet); diff --git a/src/net/servergame.h b/src/net/servergame.h index 97628044..49075f04 100644 --- a/src/net/servergame.h +++ b/src/net/servergame.h @@ -129,9 +129,8 @@ protected: bool IsComputerPlayerActive(unsigned playerId) const; void ResetComputerPlayerList(); - void GracefulRemoveSession(boost::shared_ptr session, int reason); + void RemoveSession(boost::shared_ptr session, int reason); void RemovePlayerData(boost::shared_ptr player, int reason); - void ErrorRemoveSession(boost::shared_ptr session); void SessionError(boost::shared_ptr session, int errorCode); void MoveSessionToLobby(boost::shared_ptr session, int reason); diff --git a/src/net/serverlobbythread.h b/src/net/serverlobbythread.h index 468984b0..39739947 100644 --- a/src/net/serverlobbythread.h +++ b/src/net/serverlobbythread.h @@ -62,7 +62,6 @@ public: void AddConnection(boost::shared_ptr sock); void ReAddSession(boost::shared_ptr session, int reason, unsigned gameId); void MoveSessionToGame(boost::shared_ptr game, boost::shared_ptr session, bool autoLeave); - void RemoveSessionFromGame(boost::shared_ptr session); void SessionError(boost::shared_ptr session, int errorCode); void ResubscribeLobbyMsg(boost::shared_ptr session); void NotifyPlayerJoinedLobby(unsigned playerId); @@ -159,7 +158,6 @@ protected: void TimerRemoveGame(const boost::system::error_code &ec); void TimerRemovePlayer(const boost::system::error_code &ec); void TimerUpdateClientLoginLock(const boost::system::error_code &ec); - void TimerCheckSessionTimeouts(const boost::system::error_code &ec); void TimerCleanupAvatarCache(const boost::system::error_code &ec); bool IsGameNameInUse(const std::string &gameName) const; @@ -171,11 +169,10 @@ protected: void HandleReAddedSession(boost::shared_ptr session); - void InternalCheckSessionTimeouts(boost::shared_ptr session); + void SessionTimeoutWarning(boost::shared_ptr session, unsigned remainingSec); void CleanupSessionMap(); - void CloseSession(SessionId sessionId); void CloseSession(boost::shared_ptr session); void SendError(boost::shared_ptr s, int errorCode); void SendJoinGameFailed(boost::shared_ptr s, unsigned gameId, int reason); @@ -251,8 +248,6 @@ private: boost::asio::deadline_timer m_removeGameTimer; boost::asio::deadline_timer m_removePlayerTimer; - boost::asio::deadline_timer m_sessionTimeoutTimer; - boost::asio::deadline_timer m_avatarCleanupTimer; boost::asio::deadline_timer m_saveStatisticsTimer; boost::asio::deadline_timer m_loginLockTimer; diff --git a/src/net/sessiondata.h b/src/net/sessiondata.h index e3f0dd34..006bf6f1 100644 --- a/src/net/sessiondata.h +++ b/src/net/sessiondata.h @@ -25,7 +25,6 @@ typedef unsigned SessionId; #include #include #include -#include #include #include @@ -48,7 +47,7 @@ class SessionData : public boost::enable_shared_from_this public: enum State { Init, ReceivingAvatar, Established, Game, Closed }; - SessionData(boost::shared_ptr sock, SessionId id, SessionDataCallback &cb); + SessionData(boost::shared_ptr sock, SessionId id, SessionDataCallback &cb, boost::asio::io_service &ioService); ~SessionData(); SessionId GetId() const; @@ -95,10 +94,11 @@ public: } void ResetActivityTimer(); - unsigned GetActivityTimerElapsedSec() const; - bool HasActivityNoticeBeenSent() const; - void MarkActivityNotice(); - unsigned GetAutoDisconnectTimerElapsedSec() const; + + void StartTimerInitTimeout(unsigned timeoutSec); + void StartTimerGlobalTimeout(unsigned timeoutSec); + void StartTimerActivityTimeout(unsigned timeoutSec, unsigned warningRemainingSec); + void CancelTimers(); void SetPlayerData(boost::shared_ptr player); boost::shared_ptr GetPlayerData(); @@ -107,6 +107,9 @@ protected: SessionData(const SessionData &other); SessionData &operator=(const SessionData &other); void InternalClearAuthSession(); + void TimerInitTimeout(const boost::system::error_code &ec); + void TimerSessionTimeout(const boost::system::error_code &ec); + void TimerActivityWarning(const boost::system::error_code &ec); private: boost::shared_ptr m_socket; @@ -118,9 +121,11 @@ private: boost::shared_ptr m_sendBuffer; bool m_readyFlag; bool m_wantsLobbyMsg; - boost::timers::portable::microsec_timer m_activityTimer; - bool m_activityTimeoutNoticeSent; - boost::timers::portable::microsec_timer m_autoDisconnectTimer; + unsigned m_activityTimeoutSec; + unsigned m_activityWarningRemainingSec; + boost::asio::deadline_timer m_initTimeoutTimer; + boost::asio::deadline_timer m_globalTimeoutTimer; + boost::asio::deadline_timer m_activityTimeoutTimer; SessionDataCallback &m_callback; Gsasl_session *m_authSession; int m_curAuthStep; diff --git a/src/net/sessiondatacallback.h b/src/net/sessiondatacallback.h index e5e3993d..f921c237 100644 --- a/src/net/sessiondatacallback.h +++ b/src/net/sessiondatacallback.h @@ -32,6 +32,8 @@ public: virtual ~SessionDataCallback(); virtual void CloseSession(boost::shared_ptr session) = 0; + virtual void SessionError(boost::shared_ptr session, int errorCode) = 0; + virtual void SessionTimeoutWarning(boost::shared_ptr session, unsigned remainingSec) = 0; virtual void HandlePacket(boost::shared_ptr session, boost::shared_ptr packet) = 0; }; diff --git a/src/session.cpp b/src/session.cpp index aa7f82f1..4bc9f4d2 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -69,7 +69,9 @@ bool Session::init() myQtToolsInterface->stringFromUtf8(myConfig->readConfigString("AppDataDir")), myQtToolsInterface->stringFromUtf8(myConfig->readConfigString("CacheDir"))); addOwnAvatar(myQtToolsInterface->stringFromUtf8(myConfig->readConfigString("MyAvatar"))); +#ifndef POKERTH_OFFICIAL_SERVER myAvatarManager->RemoveOldAvatarCacheEntries(); +#endif return retVal; } @@ -174,11 +176,11 @@ void Session::startInternetClient() myNetClient->Init( myConfig->readConfigString("InternetServerAddress"), -// myConfig->readConfigString("InternetServerListAddress"), - "pokerth.net/serverlist_testing.xml.z", + myConfig->readConfigString("InternetServerListAddress"), +// "pokerth.net/serverlist_testing.xml.z", myConfig->readConfigString("ServerPassword"), -// myConfig->readConfigInt("InternetServerConfigMode") == 0, - true, + myConfig->readConfigInt("InternetServerConfigMode") == 0, +// true, myConfig->readConfigInt("InternetServerPort"), myConfig->readConfigInt("InternetServerUseIpv6") == 1, myConfig->readConfigInt("InternetServerUseSctp") == 1,