From 1886d9100941da109ef9e7f603df39bf2f383ee5 Mon Sep 17 00:00:00 2001 From: lotodore Date: Fri, 22 Oct 2010 19:42:48 +0000 Subject: [PATCH] Randomize player list before starting the game. --- src/net/common/servergame.cpp | 103 ++++++++++++++++------------- src/net/common/servergamestate.cpp | 6 +- src/net/servergame.h | 4 +- 3 files changed, 61 insertions(+), 52 deletions(-) diff --git a/src/net/common/servergame.cpp b/src/net/common/servergame.cpp index d1b1e373..b70bb5ea 100644 --- a/src/net/common/servergame.cpp +++ b/src/net/common/servergame.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -231,56 +232,67 @@ ServerGame::TimerVoteKick(const boost::system::error_code &ec) } } -void +PlayerDataList ServerGame::InternalStartGame() { - // Set DB Backend. - if (GetGameData().gameType == GAME_TYPE_RANKING) - m_database = GetLobbyThread().GetDatabase(); - else - m_database.reset(new ServerDBNoAction); - - // Set order of players. - AssignPlayerNumbers(); - // Initialize the game. - GuiInterface &gui = GetGui(); - PlayerDataList playerData = GetFullPlayerDataList(); + PlayerDataList playerData(GetFullPlayerDataList()); - // Create EngineFactory - boost::shared_ptr factory(new LocalEngineFactory(m_playerConfig)); // LocalEngine erstellen - - // Set start data. - StartData startData; - startData.numberOfPlayers = playerData.size(); - - int tmpDealerPos = 0; - Tools::getRandNumber(0, startData.numberOfPlayers-1, 1, &tmpDealerPos, 0); - // The Player Id is not continuous. Therefore, the start dealer position - // needs to be converted to a player Id, and cannot be directly generated - // as player Id. - PlayerDataList::const_iterator player_i = playerData.begin(); - PlayerDataList::const_iterator player_end = playerData.end(); - - int tmpPos = 0; - while (player_i != player_end) + if (playerData.size() >= 2) { - startData.startDealerPlayerId = static_cast((*player_i)->GetUniqueId()); - if (tmpPos == tmpDealerPos) - break; - ++tmpPos; - ++player_i; + // Set DB Backend. + if (GetGameData().gameType == GAME_TYPE_RANKING) + m_database = GetLobbyThread().GetDatabase(); + else + m_database.reset(new ServerDBNoAction); + + // Randomize player list. + // Note: This does not use a cryptographically strong + // random number generator. + vector > tmpData(playerData.begin(), playerData.end()); + random_shuffle(tmpData.begin(), tmpData.end()); + copy(tmpData.begin(), tmpData.end(), playerData.begin()); + + // Set order of players. + AssignPlayerNumbers(playerData); + + // Create EngineFactory + boost::shared_ptr factory(new LocalEngineFactory(m_playerConfig)); // LocalEngine erstellen + + // Set start data. + StartData startData; + startData.numberOfPlayers = playerData.size(); + + int tmpDealerPos = 0; + Tools::getRandNumber(0, startData.numberOfPlayers-1, 1, &tmpDealerPos, 0); + // The Player Id is not continuous. Therefore, the start dealer position + // needs to be converted to a player Id, and cannot be directly generated + // as player Id. + PlayerDataList::const_iterator player_i = playerData.begin(); + PlayerDataList::const_iterator player_end = playerData.end(); + + int tmpPos = 0; + while (player_i != player_end) + { + startData.startDealerPlayerId = static_cast((*player_i)->GetUniqueId()); + if (tmpPos == tmpDealerPos) + break; + ++tmpPos; + ++player_i; + } + if (player_i == player_end) + throw ServerException(__FILE__, __LINE__, ERR_NET_DEALER_NOT_FOUND, 0); + + SetStartData(startData); + + GuiInterface &gui = GetGui(); + m_game.reset(new Game(&gui, factory, playerData, GetGameData(), GetStartData(), GetNextGameNum())); + + GetLobbyThread().NotifyStartingGame(GetId()); + GetDatabase().AsyncCreateGame(GetId(), GetName()); + InitRankingMap(playerData); } - if (player_i == player_end) - throw ServerException(__FILE__, __LINE__, ERR_NET_DEALER_NOT_FOUND, 0); - - SetStartData(startData); - - m_game.reset(new Game(&gui, factory, playerData, GetGameData(), GetStartData(), GetNextGameNum())); - - GetLobbyThread().NotifyStartingGame(GetId()); - GetDatabase().AsyncCreateGame(GetId(), GetName()); - InitRankingMap(playerData); + return playerData; } void @@ -829,11 +841,10 @@ ServerGame::GetCurNumberOfPlayers() const } void -ServerGame::AssignPlayerNumbers() +ServerGame::AssignPlayerNumbers(PlayerDataList &playerList) { int playerNumber = 0; - PlayerDataList playerList = GetFullPlayerDataList(); PlayerDataList::iterator player_i = playerList.begin(); PlayerDataList::iterator player_end = playerList.end(); diff --git a/src/net/common/servergamestate.cpp b/src/net/common/servergamestate.cpp index b11716c3..4017faf4 100644 --- a/src/net/common/servergamestate.cpp +++ b/src/net/common/servergamestate.cpp @@ -687,21 +687,19 @@ ServerGameStateStartGame::TimerTimeout(const boost::system::error_code &ec, boos void ServerGameStateStartGame::DoStart(boost::shared_ptr server) { - PlayerDataList tmpPlayerList = server->GetFullPlayerDataList(); + PlayerDataList tmpPlayerList(server->InternalStartGame()); if (tmpPlayerList.size() <= 1) { if (!tmpPlayerList.empty()) { boost::shared_ptr tmpPlayer(tmpPlayerList.front()); SessionWrapper tmpSession = server->GetSessionManager().GetSessionByUniquePlayerId(tmpPlayer->GetUniqueId()); - if (tmpSession.sessionData.get()) + if (tmpSession.sessionData) server->MoveSessionToLobby(tmpSession, NTF_NET_REMOVED_START_FAILED); } } else { - server->InternalStartGame(); - boost::shared_ptr packet(new NetPacket(NetPacket::Alloc)); packet->GetMsg()->present = PokerTHMessage_PR_gameStartMessage; GameStartMessage_t *netGameStart = &packet->GetMsg()->choice.gameStartMessage; diff --git a/src/net/servergame.h b/src/net/servergame.h index 4e21c043..eff6e23e 100644 --- a/src/net/servergame.h +++ b/src/net/servergame.h @@ -107,7 +107,7 @@ protected: void TimerVoteKick(const boost::system::error_code &ec); - void InternalStartGame(); + PlayerDataList InternalStartGame(); void InitRankingMap(const PlayerDataList &playerDataList); void UpdateRankingMap(); void SetPlayerPlace(unsigned playerId, int place); @@ -134,7 +134,7 @@ protected: void RemoveDisconnectedPlayers(); size_t GetCurNumberOfPlayers() const; - void AssignPlayerNumbers(); + void AssignPlayerNumbers(PlayerDataList &playerList); bool IsValidPlayer(unsigned playerId) const; ServerLobbyThread &GetLobbyThread();