Cleaning up the different timeouts and how players can be removed from the game.

This commit is contained in:
lotodore
2011-12-11 14:54:17 +00:00
parent 110a9536f4
commit aad9e271db
16 changed files with 175 additions and 167 deletions
+32 -105
View File
@@ -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<SessionData> session) {
m_server.CloseSession(session->GetId());
m_server.CloseSession(session);
}
virtual void SessionError(boost::shared_ptr<SessionData> session, int errorCode) {
m_server.SessionError(session, errorCode);
}
virtual void SessionTimeoutWarning(boost::shared_ptr<SessionData> session, unsigned remainingSec) {
m_server.SessionTimeoutWarning(session, remainingSec);
}
virtual void HandlePacket(boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> 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<tcp::socket> sock)
{
// Create a new session.
boost::shared_ptr<SessionData> sessionData(new SessionData(sock, m_curSessionId++, *m_internalServerCallback));
boost::shared_ptr<SessionData> 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<ServerGame> game, boost::
game->SetPlayerAutoLeaveOnFinish(session->GetPlayerData()->GetUniqueId());
}
void
ServerLobbyThread::RemoveSessionFromGame(boost::shared_ptr<SessionData> session)
{
// Just remove the session. Only for fatal errors.
CloseSession(session);
}
void
ServerLobbyThread::CloseSession(SessionId sessionId)
{
boost::shared_ptr<SessionData> session = m_sessionManager.GetSessionById(sessionId);
if (!session)
session = m_gameSessionManager.GetSessionById(sessionId);
if (session) {
boost::shared_ptr<ServerGame> tmpGame = session->GetGame();
if (tmpGame) {
tmpGame->ErrorRemoveSession(session);
} else {
CloseSession(session);
}
}
}
void
ServerLobbyThread::CloseSession(boost::shared_ptr<SessionData> session)
{
if (session && session->GetState() != SessionData::Closed) { // Make this call reentrant.
LOG_VERBOSE("Closing session #" << session->GetId() << ".");
session->SetState(SessionData::Closed);
boost::shared_ptr<ServerGame> 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<SessionData> session)
// Update stats (if needed).
UpdateStatisticsNumberOfPlayers();
session->SetGame(boost::shared_ptr<ServerGame>());
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<SessionData> session)
}
void
ServerLobbyThread::InternalCheckSessionTimeouts(boost::shared_ptr<SessionData> session)
ServerLobbyThread::SessionTimeoutWarning(boost::shared_ptr<SessionData> 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<NetPacket> 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<NetPacket> 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