diff --git a/src/engine/local_engine/localplayer.cpp b/src/engine/local_engine/localplayer.cpp index fae3e8c7..a7b8134b 100755 --- a/src/engine/local_engine/localplayer.cpp +++ b/src/engine/local_engine/localplayer.cpp @@ -5123,3 +5123,13 @@ bool LocalPlayer::checkIfINeedToShowCards() return false; } + +void LocalPlayer::markRemoteAction() +{ + m_lastRemoteActionTimer.restart(); +} + +unsigned LocalPlayer::getTimeSecSinceLastRemoteAction() const +{ + return m_lastRemoteActionTimer.elapsed().total_seconds(); +} diff --git a/src/engine/local_engine/localplayer.h b/src/engine/local_engine/localplayer.h index 94512fb3..af548d6b 100755 --- a/src/engine/local_engine/localplayer.h +++ b/src/engine/local_engine/localplayer.h @@ -285,12 +285,11 @@ public: void setIsKicked(bool kicked); bool isKicked() const; - unsigned getActionTimeoutCounter() const; - void incrementActionTimeoutCounter(); - void resetActionTimeoutCounter(); - bool checkIfINeedToShowCards(); + void markRemoteAction(); + unsigned getTimeSecSinceLastRemoteAction() const; + private: ConfigFile *myConfig; @@ -336,6 +335,7 @@ private: unsigned m_actionTimeoutCounter; bool m_isSessionActive; bool m_isKicked; + boost::timers::portable::microsec_timer m_lastRemoteActionTimer; }; #endif diff --git a/src/engine/network_engine/clientplayer.h b/src/engine/network_engine/clientplayer.h index 2789391b..8579bd3d 100644 --- a/src/engine/network_engine/clientplayer.h +++ b/src/engine/network_engine/clientplayer.h @@ -140,6 +140,9 @@ public: bool checkIfINeedToShowCards(); + void markRemoteAction() {} + unsigned getTimeSecSinceLastRemoteAction() const {return 0;} + private: mutable boost::recursive_mutex m_syncMutex; diff --git a/src/engine/playerinterface.h b/src/engine/playerinterface.h index a7d818a9..a6d0fa9a 100644 --- a/src/engine/playerinterface.h +++ b/src/engine/playerinterface.h @@ -124,6 +124,9 @@ public: virtual bool isKicked() const=0; virtual bool checkIfINeedToShowCards() =0; + + virtual void markRemoteAction() =0; + virtual unsigned getTimeSecSinceLastRemoteAction() const =0; }; #endif diff --git a/src/net/common/servergame.cpp b/src/net/common/servergame.cpp index 30966caa..18f9a8d6 100644 --- a/src/net/common/servergame.cpp +++ b/src/net/common/servergame.cpp @@ -220,7 +220,7 @@ ServerGame::TimerVoteKick(const boost::system::error_code &ec) // Perform kick. if (doKick) - InternalKickPlayer(m_voteKickData->kickPlayerId); + KickPlayer(m_voteKickData->kickPlayerId); // This petition has ended. m_voteKickData.reset(); } @@ -398,7 +398,7 @@ ServerGame::InternalEndGame() } void -ServerGame::InternalKickPlayer(unsigned playerId) +ServerGame::KickPlayer(unsigned playerId) { MarkPlayerAsKicked(playerId); diff --git a/src/net/common/servergamestate.cpp b/src/net/common/servergamestate.cpp index da770b17..e1e2f91e 100644 --- a/src/net/common/servergamestate.cpp +++ b/src/net/common/servergamestate.cpp @@ -65,6 +65,8 @@ using namespace std; #define SERVER_AUTOSTART_GAME_DELAY_SEC 6 #define SERVER_GAME_ADMIN_WARNING_REMAINING_SEC 60 #define SERVER_GAME_ADMIN_TIMEOUT_SEC 300 // 5 min, MUST be > SERVER_GAME_ADMIN_WARNING_REMAINING_SEC +#define SERVER_GAME_AUTOFOLD_TIMEOUT_SEC 60 +#define SERVER_GAME_FORCED_TIMEOUT_SEC 120 #define SERVER_VOTE_KICK_TIMEOUT_SEC 30 #define SERVER_LOOP_DELAY_MSEC 50 @@ -179,8 +181,15 @@ static void PerformPlayerAction(ServerGame &server, boost::shared_ptrgetBoard()->collectSets(); } - SendPlayerAction(server, player); + + // Check timeout. + if (player->getTimeSecSinceLastRemoteAction() >= SERVER_GAME_AUTOFOLD_TIMEOUT_SEC) { + player->setIsSessionActive(false); + if (player->getTimeSecSinceLastRemoteAction() >= SERVER_GAME_FORCED_TIMEOUT_SEC) { + server.KickPlayer(player->getMyUniqueID()); + } + } } static void @@ -224,12 +233,6 @@ AbstractServerGameStateReceiving::ProcessPacket(boost::shared_ptr se { if (packet->IsClientActivity()) { session->ResetActivityTimer(); - if (server->IsRunning()) { - boost::shared_ptr tmpPlayer(server->GetGame().getPlayerByUniqueId(session->GetPlayerData()->GetUniqueId())); - if (tmpPlayer) { - tmpPlayer->setIsSessionActive(true); - } - } } if (packet->GetMsg()->present == PokerTHMessage_PR_playerInfoRequestMessage) { // Delegate to Lobby. @@ -245,7 +248,7 @@ AbstractServerGameStateReceiving::ProcessPacket(boost::shared_ptr se KickPlayerRequestMessage_t *netKickRequest = &packet->GetMsg()->choice.kickPlayerRequestMessage; if (session->GetPlayerData()->IsGameAdmin() && !server->IsRunning() && netKickRequest->gameId == server->GetId() && server->GetGameData().gameType != GAME_TYPE_RANKING) { - server->InternalKickPlayer(netKickRequest->playerId); + server->KickPlayer(netKickRequest->playerId); } } else if (packet->GetMsg()->present == PokerTHMessage_PR_askKickPlayerMessage) { if (server->GetGameData().gameType != GAME_TYPE_RANKING) { @@ -946,18 +949,20 @@ ServerGameStateHand::EngineLoop(boost::shared_ptr server) boost::bind( &ServerGameStateHand::TimerComputerAction, this, boost::asio::placeholders::error, server)); } - // If the player we are waiting for left, continue without him. - else if (!server->GetSessionManager().IsPlayerConnected(curPlayer->getMyUniqueID()) - || !curPlayer->isSessionActive()) { - PerformPlayerAction(*server, curPlayer, PLAYER_ACTION_FOLD, 0); + else { + // If the player we are waiting for left, continue without him. + if (!server->GetSessionManager().IsPlayerConnected(curPlayer->getMyUniqueID()) + || !curPlayer->isSessionActive()) { + PerformPlayerAction(*server, curPlayer, PLAYER_ACTION_FOLD, 0); - server->GetStateTimer1().expires_from_now( - boost::posix_time::milliseconds(SERVER_LOOP_DELAY_MSEC)); - server->GetStateTimer1().async_wait( - boost::bind( - &ServerGameStateHand::TimerLoop, this, boost::asio::placeholders::error, server)); - } else { - server->SetState(ServerGameStateWaitPlayerAction::Instance()); + server->GetStateTimer1().expires_from_now( + boost::posix_time::milliseconds(SERVER_LOOP_DELAY_MSEC)); + server->GetStateTimer1().async_wait( + boost::bind( + &ServerGameStateHand::TimerLoop, this, boost::asio::placeholders::error, server)); + } else { + server->SetState(ServerGameStateWaitPlayerAction::Instance()); + } } } else { // hand is over // Engine will find out who won. @@ -1401,6 +1406,8 @@ ServerGameStateWaitPlayerAction::InternalProcessPacket(boost::shared_ptrsetIsSessionActive(true); + tmpPlayer->markRemoteAction(); PerformPlayerAction(*server, tmpPlayer, static_cast(netMyAction->myAction), netMyAction->myRelativeBet); server->SetState(ServerGameStateHand::Instance()); } else { diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index 28788686..a9206e38 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -65,7 +65,7 @@ #define SERVER_INIT_SESSION_TIMEOUT_SEC 60 #define SERVER_TIMEOUT_WARNING_REMAINING_SEC 60 -#define SERVER_SESSION_ACTIVITY_TIMEOUT_SEC 180/*1800*/ // 30 min, MUST be > SERVER_TIMEOUT_WARNING_REMAINING_SEC +#define SERVER_SESSION_ACTIVITY_TIMEOUT_SEC 1800 // 30 min, MUST be > SERVER_TIMEOUT_WARNING_REMAINING_SEC #define SERVER_SESSION_FORCED_TIMEOUT_SEC 86400 // 1 day, should be quite large. #define SERVER_ADDRESS_LOCALHOST_STR_V4 "127.0.0.1" diff --git a/src/net/servergame.h b/src/net/servergame.h index d5f97d37..e89ccbfa 100644 --- a/src/net/servergame.h +++ b/src/net/servergame.h @@ -96,6 +96,8 @@ public: const Game &GetGame() const; Game &GetGame(); + void KickPlayer(unsigned playerId); + protected: struct RankingData { @@ -117,7 +119,6 @@ protected: void RemoveAutoLeavePlayers(); void InternalEndGame(); - void InternalKickPlayer(unsigned playerId); void InternalAskVoteKick(boost::shared_ptr byWhom, unsigned playerIdWho, unsigned timeoutSec); void InternalDenyAskVoteKick(boost::shared_ptr byWhom, unsigned playerIdWho, DenyKickPlayerReason reason); void InternalVoteKick(boost::shared_ptr byWhom, unsigned petitionId, KickVote vote);