Cleaning up the different timeouts and how players can be removed from the game.
This commit is contained in:
@@ -274,7 +274,7 @@ public:
|
||||
virtual void Enter(boost::shared_ptr<ClientThread> client);
|
||||
virtual void Exit(boost::shared_ptr<ClientThread> client);
|
||||
|
||||
virtual void HandlePacket(boost::shared_ptr<ClientThread> /*client*/, boost::shared_ptr<NetPacket> /*tmpPacket*/) {}
|
||||
virtual void HandlePacket(boost::shared_ptr<ClientThread> client, boost::shared_ptr<NetPacket> tmpPacket);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -87,6 +87,8 @@ public:
|
||||
|
||||
void StartAsyncRead();
|
||||
virtual void CloseSession(boost::shared_ptr<SessionData> session);
|
||||
virtual void SessionError(boost::shared_ptr<SessionData> /*session*/, int /*errorCode*/) {}
|
||||
virtual void SessionTimeoutWarning(boost::shared_ptr<SessionData> /*session*/, unsigned /*remainingSec*/) {}
|
||||
virtual void HandlePacket(boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet);
|
||||
|
||||
void SelectServer(unsigned serverId);
|
||||
|
||||
@@ -1010,6 +1010,17 @@ ClientStateWaitEnterLogin::Exit(boost::shared_ptr<ClientThread> client)
|
||||
client->GetStateTimer().cancel();
|
||||
}
|
||||
|
||||
void
|
||||
ClientStateWaitEnterLogin::HandlePacket(boost::shared_ptr<ClientThread> client, boost::shared_ptr<NetPacket> 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<ClientThread> client)
|
||||
{
|
||||
|
||||
@@ -926,7 +926,8 @@ ClientThread::CreateContextSession()
|
||||
GetContext().SetSessionData(boost::shared_ptr<SessionData>(new SessionData(
|
||||
newSock,
|
||||
SESSION_ID_GENERIC,
|
||||
*this)));
|
||||
*this,
|
||||
*m_ioService)));
|
||||
GetContext().SetResolver(boost::shared_ptr<boost::asio::ip::tcp::resolver>(
|
||||
new boost::asio::ip::tcp::resolver(*m_ioService)));
|
||||
validSocket = true;
|
||||
|
||||
@@ -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<boost::asio::ip::tcp::socket>
|
||||
shared_from_this(),
|
||||
socket,
|
||||
boost::asio::placeholders::error));
|
||||
} else if (closeAfterSend) {
|
||||
socket->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,18 @@ SenderHelper::Send(boost::shared_ptr<SessionData> session, const NetPacketList &
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SenderHelper::SetCloseAfterSend(boost::shared_ptr<SessionData> 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<NetPacket> packet)
|
||||
{
|
||||
|
||||
@@ -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<SessionData> session, int reason)
|
||||
ServerGame::RemoveSession(boost::shared_ptr<SessionData> session, int reason)
|
||||
{
|
||||
if (!session)
|
||||
throw ServerException(__FILE__, __LINE__, ERR_NET_INVALID_SESSION, 0);
|
||||
@@ -794,26 +794,19 @@ ServerGame::RemovePlayerData(boost::shared_ptr<PlayerData> player, int reason)
|
||||
GetLobbyThread().NotifyPlayerLeftGame(GetId(), player->GetUniqueId());
|
||||
}
|
||||
|
||||
void
|
||||
ServerGame::ErrorRemoveSession(boost::shared_ptr<SessionData> session)
|
||||
{
|
||||
GetLobbyThread().RemoveSessionFromGame(session);
|
||||
GracefulRemoveSession(session, NTF_NET_INTERNAL);
|
||||
}
|
||||
|
||||
void
|
||||
ServerGame::SessionError(boost::shared_ptr<SessionData> 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<SessionData> 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());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -19,16 +19,15 @@
|
||||
#include <net/sessiondata.h>
|
||||
#include <net/receivebuffer.h>
|
||||
#include <net/sendbuffer.h>
|
||||
#include <net/socket_msg.h>
|
||||
#include <gsasl.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
SessionData::SessionData(boost::shared_ptr<boost::asio::ip::tcp::socket> sock, SessionId id, SessionDataCallback &cb)
|
||||
SessionData::SessionData(boost::shared_ptr<boost::asio::ip::tcp::socket> 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
|
||||
|
||||
@@ -67,6 +67,10 @@ public:
|
||||
sendBufUsed += size;
|
||||
}
|
||||
|
||||
inline void SetCloseAfterSend() {
|
||||
closeAfterSend = true;
|
||||
}
|
||||
|
||||
void HandleWrite(boost::shared_ptr<boost::asio::ip::tcp::socket> socket, const boost::system::error_code &error);
|
||||
void AsyncSendNextPacket(boost::shared_ptr<boost::asio::ip::tcp::socket> socket);
|
||||
|
||||
@@ -81,6 +85,7 @@ private:
|
||||
size_t sendBufUsed;
|
||||
size_t curWriteBufAllocated;
|
||||
size_t curWriteBufUsed;
|
||||
bool closeAfterSend;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,6 +35,8 @@ public:
|
||||
void Send(boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet);
|
||||
void Send(boost::shared_ptr<SessionData> session, const NetPacketList &packetList);
|
||||
|
||||
void SetCloseAfterSend(boost::shared_ptr<SessionData> session);
|
||||
|
||||
protected:
|
||||
void InternalStorePacket(SendBuffer &tmpManager, boost::shared_ptr<NetPacket> packet);
|
||||
|
||||
|
||||
@@ -129,9 +129,8 @@ protected:
|
||||
bool IsComputerPlayerActive(unsigned playerId) const;
|
||||
void ResetComputerPlayerList();
|
||||
|
||||
void GracefulRemoveSession(boost::shared_ptr<SessionData> session, int reason);
|
||||
void RemoveSession(boost::shared_ptr<SessionData> session, int reason);
|
||||
void RemovePlayerData(boost::shared_ptr<PlayerData> player, int reason);
|
||||
void ErrorRemoveSession(boost::shared_ptr<SessionData> session);
|
||||
void SessionError(boost::shared_ptr<SessionData> session, int errorCode);
|
||||
void MoveSessionToLobby(boost::shared_ptr<SessionData> session, int reason);
|
||||
|
||||
|
||||
@@ -62,7 +62,6 @@ public:
|
||||
void AddConnection(boost::shared_ptr<boost::asio::ip::tcp::socket> sock);
|
||||
void ReAddSession(boost::shared_ptr<SessionData> session, int reason, unsigned gameId);
|
||||
void MoveSessionToGame(boost::shared_ptr<ServerGame> game, boost::shared_ptr<SessionData> session, bool autoLeave);
|
||||
void RemoveSessionFromGame(boost::shared_ptr<SessionData> session);
|
||||
void SessionError(boost::shared_ptr<SessionData> session, int errorCode);
|
||||
void ResubscribeLobbyMsg(boost::shared_ptr<SessionData> 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<SessionData> session);
|
||||
|
||||
void InternalCheckSessionTimeouts(boost::shared_ptr<SessionData> session);
|
||||
void SessionTimeoutWarning(boost::shared_ptr<SessionData> session, unsigned remainingSec);
|
||||
|
||||
void CleanupSessionMap();
|
||||
|
||||
void CloseSession(SessionId sessionId);
|
||||
void CloseSession(boost::shared_ptr<SessionData> session);
|
||||
void SendError(boost::shared_ptr<SessionData> s, int errorCode);
|
||||
void SendJoinGameFailed(boost::shared_ptr<SessionData> 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;
|
||||
|
||||
|
||||
+14
-9
@@ -25,7 +25,6 @@ typedef unsigned SessionId;
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <third_party/boost/timers.hpp>
|
||||
#include <string>
|
||||
|
||||
#include <net/socket_helper.h>
|
||||
@@ -48,7 +47,7 @@ class SessionData : public boost::enable_shared_from_this<SessionData>
|
||||
public:
|
||||
enum State { Init, ReceivingAvatar, Established, Game, Closed };
|
||||
|
||||
SessionData(boost::shared_ptr<boost::asio::ip::tcp::socket> sock, SessionId id, SessionDataCallback &cb);
|
||||
SessionData(boost::shared_ptr<boost::asio::ip::tcp::socket> 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<PlayerData> player);
|
||||
boost::shared_ptr<PlayerData> 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<boost::asio::ip::tcp::socket> m_socket;
|
||||
@@ -118,9 +121,11 @@ private:
|
||||
boost::shared_ptr<SendBuffer> 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;
|
||||
|
||||
@@ -32,6 +32,8 @@ public:
|
||||
virtual ~SessionDataCallback();
|
||||
|
||||
virtual void CloseSession(boost::shared_ptr<SessionData> session) = 0;
|
||||
virtual void SessionError(boost::shared_ptr<SessionData> session, int errorCode) = 0;
|
||||
virtual void SessionTimeoutWarning(boost::shared_ptr<SessionData> session, unsigned remainingSec) = 0;
|
||||
virtual void HandlePacket(boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet) = 0;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user