From 63fb9bc28746881ef0ab3536b5e5376a325b9bf2 Mon Sep 17 00:00:00 2001 From: Albert Medela Date: Sun, 7 Jun 2020 01:47:11 +0200 Subject: [PATCH] corrections and starting reentry development --- pokerth.proto | 1 + src/engine/game.cpp | 17 ++++ src/engine/game.h | 2 + src/net/common/servergame.cpp | 76 +++++++++++++++- src/net/common/servergamestate.cpp | 135 +++++++++++++++++++++++++---- src/net/servergame.h | 7 ++ src/net/servergamestate.h | 2 + 7 files changed, 220 insertions(+), 20 deletions(-) diff --git a/pokerth.proto b/pokerth.proto index 1b0e43cc..2fda5a68 100644 --- a/pokerth.proto +++ b/pokerth.proto @@ -424,6 +424,7 @@ message StartEventMessage { enum StartEventType { startEvent = 0; rejoinEvent = 1; + reentryEvent = 2; } required StartEventType startEventType = 2; optional bool fillWithComputerPlayers = 3; diff --git a/src/engine/game.cpp b/src/engine/game.cpp index 344593ec..0e9d6c06 100755 --- a/src/engine/game.cpp +++ b/src/engine/game.cpp @@ -324,3 +324,20 @@ void Game::raiseBlinds() currentSmallBlind = min(currentSmallBlind,startQuantityPlayers*startCash/2); } } + +boost::shared_ptr +Game::addNewPlayer(boost::shared_ptr player) +{ + + // TODO (albmed): We must think how: + // also add to seatList (or replace a free slot if 10 players tops) + + int i = 0; // ERROR. Thik about approppiate value (probably this should be set after a seat is found) + + boost::shared_ptr tmpPlayer = myFactory->createPlayer(i, player->GetUniqueId(), player->GetType(), player->GetName(), player->GetAvatarFile(), player->GetStartCash(), startQuantityPlayers > i, PLAYER_TYPE_HUMAN, 0); + tmpPlayer->setIsSessionActive(true); // ??? Really ??? + tmpPlayer->setMyGuid(player->GetGuid()); + + + return tmpPlayer; +} diff --git a/src/engine/game.h b/src/engine/game.h index 210c90d4..344fc8e3 100755 --- a/src/engine/game.h +++ b/src/engine/game.h @@ -142,6 +142,8 @@ public: boost::shared_ptr getPlayerByName(const std::string &name); boost::shared_ptr getCurrentPlayer(); + boost::shared_ptr addNewPlayer(boost::shared_ptr player); + void raiseBlinds(); private: diff --git a/src/net/common/servergame.cpp b/src/net/common/servergame.cpp index b7b140d6..314297b6 100644 --- a/src/net/common/servergame.cpp +++ b/src/net/common/servergame.cpp @@ -76,10 +76,18 @@ ServerGame::ServerGame(boost::shared_ptr lobbyThread, u_int32 { LOG_VERBOSE("Game object " << GetId() << " created."); + // TODO (albmed): Next is wrong!! + // If game is restarted without being created, m_isLateRegAllowed probably will be always false because its timer would already be cancelled in previous game and object is not created again. + // So, constructor is not called again. + // m_isLateRegAllowed should probably be set on Init() function or in ServerGameStateInit::Enter. To be checked!! + + // set late reg allowed if ((m_gameData.gameType == GAME_TYPE_NORMAL || m_gameData.gameType == GAME_TYPE_REGISTERED_ONLY) && (m_gameData.allowLateReg || m_gameData.allowReentries) && m_gameData.maxTimeLateReg > 0) m_isLateRegAllowed = true; + + LOG_MSG("m_isLateRegAllowed: " << std::boolalpha << m_isLateRegAllowed); } ServerGame::~ServerGame() @@ -787,6 +795,13 @@ ServerGame::AddRejoinPlayer(unsigned playerId) m_rejoinPlayerList.push_back(playerId); } +void +ServerGame::AddReentryPlayer(unsigned playerId) +{ + boost::mutex::scoped_lock lock(m_reentryPlayerListMutex); + m_reentryPlayerList.push_back(playerId); +} + PlayerIdList ServerGame::GetAndResetRejoinPlayers() { @@ -796,6 +811,22 @@ ServerGame::GetAndResetRejoinPlayers() return tmpList; } +unsigned +ServerGame::GetNumberPlayersReentry() +{ + boost::mutex::scoped_lock lock(m_rejoinPlayerListMutex); + return static_cast(m_rejoinPlayerList.size()); +} + +PlayerIdList +ServerGame::GetAndResetReentryPlayers() +{ + boost::mutex::scoped_lock lock(m_reentryPlayerListMutex); + PlayerIdList tmpList(m_reentryPlayerList); + m_reentryPlayerList.clear(); + return tmpList; +} + void ServerGame::AddReactivatePlayer(unsigned playerId) { @@ -1258,6 +1289,18 @@ ServerGame::setEntries(const PlayerDataList &playerDataList) { m_numEntriesPlayer[tmpPlayer->GetName()] = 0; ++i; } + + { + LOG_MSG("Printting set entries:"); + + NumJoinsPerPlayerMap::const_iterator i = m_numEntriesPlayer.begin(); + NumJoinsPerPlayerMap::const_iterator end = m_numEntriesPlayer.end(); + + while (i != end) { + LOG_MSG("\t{player, entries}: {" << (*i).first << ", " << (*i).second << "}"); + ++i; + } + } } bool @@ -1266,7 +1309,8 @@ ServerGame::admitReentries(boost::shared_ptr player) { // FIXME: may bool retVal = false; const GameData &tmpGameData = GetGameData(); - if (!m_isLateRegAllowed) return retVal; + // uncomment to remove logs + /*if (!m_isLateRegAllowed) return retVal; NumJoinsPerPlayerMap::iterator pos = m_numEntriesPlayer.find(player->GetName()); if (pos != m_numEntriesPlayer.end()) { // is reentry if (!tmpGameData.allowReentries || pos->second++ >= tmpGameData.numReentries ) return retVal; // number of entries exceeded @@ -1274,7 +1318,35 @@ ServerGame::admitReentries(boost::shared_ptr player) { // FIXME: may else { // is late reg if (!tmpGameData.allowLateReg) return false; // does not allow late reg m_numEntriesPlayer[player->GetName()] = 0; // add player as new entry. Perhaps this should be set otherplace + }*/ + + // comment or delete to remove logs -- begin + if (!m_isLateRegAllowed) { + LOG_MSG("Late reg was not allowed or is no longer available"); + return retVal; } + NumJoinsPerPlayerMap::iterator pos = m_numEntriesPlayer.find(player->GetName()); + if (pos != m_numEntriesPlayer.end()) { // is reentry + LOG_MSG("Player " << player->GetName() << " is trying to re-entry. Previous entries: " << pos->second); + if (!tmpGameData.allowReentries || pos->second++ >= tmpGameData.numReentries ) { + LOG_MSG("Number of reentries exceeded"); + return retVal; // number of entries exceeded + } + else { + LOG_MSG("Allowed to re-entry"); + } + } + else { // is late reg + LOG_MSG("Player " << player->GetName() << " is trying a late reg"); + if (!tmpGameData.allowLateReg) { + LOG_MSG("Game does not allow late reg"); + return false; // does not allow late reg + } + m_numEntriesPlayer[player->GetName()] = 0; // add player as new entry. Perhaps this should be set otherplace + } + + LOG_MSG("Late reg allowed!! "); + // comment or delete to remove logs -- end return true; } @@ -1282,6 +1354,8 @@ ServerGame::admitReentries(boost::shared_ptr player) { // FIXME: may void ServerGame::CancelLateReg() { m_isLateRegAllowed = false; + + LOG_MSG("Called CancelLateReg"); } bool diff --git a/src/net/common/servergamestate.cpp b/src/net/common/servergamestate.cpp index 8b351a0b..30823013 100644 --- a/src/net/common/servergamestate.cpp +++ b/src/net/common/servergamestate.cpp @@ -92,6 +92,8 @@ using namespace boost::chrono; #define GAME_MAX_NUM_JOINS_PER_PLAYER 6 +//#define TESTS_LATE_REG // (albmed) To develop set this define, to compile comment until reentry is implemented + // Helper functions static void SendPlayerAction(ServerGame &server, boost::shared_ptr player) @@ -227,6 +229,35 @@ SetPlayerResult(PlayerResult &playerResult, boost::shared_ptr t playerResult.set_playermoney(tmpPlayer->getMyCash()); } +static int +GetRandomFreeSeat(PlayerList playerList) { + + // seek for a free seat + PlayerListConstIterator player_i = playerList->begin(); + PlayerListConstIterator player_end = playerList->end(); + + std::vector v(10, 0); + while (player_i != player_end) { + v[(*player_i)->getMyID()] = 1; // mark seats with player + ++player_i; + } + + // random seats + random_shuffle(v.begin(), v.end()); + + int seat = -1; + // seeks first free seat + for (int i = 0; i < v.size(); i++) { + if (v[i] == 0) { + seat = i; + beak; + } + } + + return seat; +} + + //----------------------------------------------------------------------------- ServerGameState::~ServerGameState() @@ -828,7 +859,7 @@ ServerGameStateStartGame::TimerTimeout(const boost::system::error_code &ec, boos void ServerGameStateStartGame::TimerAllowLateRegTimeout(const boost::system::error_code &ec, boost::shared_ptr server) { - if (!ec) { // ( && &server->GetState() != &ServerGameStateFinal::s_state ) I don't know how to check if state is not final + if (!ec && &server->GetState() != &ServerGameStateFinal::Instance()) { server->CancelLateReg(); } } @@ -869,11 +900,11 @@ ServerGameStateStartGame::DoStart(boost::shared_ptr server) while (player_i != player_end) { boost::shared_ptr tmpPlayer = (*player_i); - LOG_MSG("\t\t {UID, name, GUID, seat}" << + LOG_MSG("\t\t {UID, name, GUID, seat}: -> {" << tmpPlayer->GetUniqueId() << ", " << tmpPlayer->GetName() << ", " << tmpPlayer->GetGuid() << ", " << - tmpPlayer->GetNumber() + tmpPlayer->GetNumber() << "}" ); ++player_i; } @@ -882,6 +913,8 @@ ServerGameStateStartGame::DoStart(boost::shared_ptr server) server->SendToAllPlayers(packet, SessionData::Game | SessionData::Spectating); + LOG_MSG("Starting timer for LateReg"); + // set late reg timer (if allowed) if (server->IsLateReg()) { server->GetAllowEntryTimer().expires_from_now( @@ -929,17 +962,42 @@ AbstractServerGameStateRunning::HandleNewPlayer(boost::shared_ptr se else if (session && session->GetPlayerData() && server->admitReentries(session->GetPlayerData())) { const GameData tmpGameData = server->GetGameData(); - if (server->GetCurNumberOfPlayers() < tmpGameData.maxNumberOfPlayers) { // there is a seat available - AcceptNewSession(server, session, false); // player wants to join + if (server->GetCurNumberOfPlayers() + server->GetNumberPlayersReentry() < tmpGameData.maxNumberOfPlayers) { // there is a seat available - // TODO: - // - locate seat + + + +#ifndef TESTS_LATE_REG + server->MoveSessionToLobby(session, NTF_NET_REMOVED_GAME_FULL); +#else + // Uncomment next line when implemented + AcceptNewSession(server, session, false); // player wants to join + server->AddReentryPlayer(session->GetPlayerData()->GetUniqueId()); // add to list of players to reentry + + LOG_MSG("Late reg is allowed and there is a seat available... unfortunatelly not implemented, yet ;)"); + + // Send start event right away. + boost::shared_ptr packet(new NetPacket); + packet->GetMsg()->set_messagetype(PokerTHMessage::Type_StartEventMessage); + StartEventMessage *netStartEvent = packet->GetMsg()->mutable_starteventmessage(); + netStartEvent->set_starteventtype(StartEventMessage::reentryEvent); // <-- set reentry event!! TODO (albmed): Fist we have to check proto NET versions. Both NET_VERSION_MAJOR & NET_VERSION_MINOR + netStartEvent->set_gameid(server->GetId()); + + // Wait for rejoining player to confirm start of game. + server->GetLobbyThread().GetSender().Send(session, packet); + + + // TODO (albmed): + // - locate seat ---> this should be done in ServerGameStateHand::StartNewHand // - notify players and users // - move session to server // - set cash // - wait for button to pass (if necessary) // - let player play + + +#endif } else { server->MoveSessionToLobby(session, NTF_NET_REMOVED_GAME_FULL); @@ -1323,11 +1381,11 @@ ServerGameStateHand::StartNewHand(boost::shared_ptr server) while (i != end) { boost::shared_ptr tmpPlayer = (*i); - LOG_MSG("\t\t {ID, name, GUID; UID} => " << + LOG_MSG("\t\t {ID, name, UID} -> {" << tmpPlayer->getMyID() << ", " << tmpPlayer->getMyName() << ", " << - tmpPlayer->getMyUniqueID() << ", " << - tmpPlayer->getMyGuid()); + tmpPlayer->getMyUniqueID() << "}" + ); ++i; } @@ -1338,11 +1396,11 @@ ServerGameStateHand::StartNewHand(boost::shared_ptr server) while (i != end) { boost::shared_ptr tmpPlayer = (*i); - LOG_MSG("\t\t {ID, name, GUID; UID} => " << + LOG_MSG("\t\t {ID, name, UID} -> {" << tmpPlayer->getMyID() << ", " << tmpPlayer->getMyName() << ", " << - tmpPlayer->getMyUniqueID() << ", " << - tmpPlayer->getMyGuid()); + tmpPlayer->getMyUniqueID() << "}" + ); ++i; } @@ -1353,11 +1411,11 @@ ServerGameStateHand::StartNewHand(boost::shared_ptr server) while (i != end) { boost::shared_ptr tmpPlayer = (*i); - LOG_MSG("\t\t {ID, name, GUID; UID} => " << + LOG_MSG("\t\t {ID, name, UID} -> {" << tmpPlayer->getMyID() << ", " << tmpPlayer->getMyName() << ", " << - tmpPlayer->getMyUniqueID() << ", " << - tmpPlayer->getMyGuid()); + tmpPlayer->getMyUniqueID() << "}" + ); ++i; } @@ -1370,11 +1428,11 @@ ServerGameStateHand::StartNewHand(boost::shared_ptr server) while (player_i != player_end) { boost::shared_ptr tmpPlayer = (*player_i); - LOG_MSG("PlayerData: {playerId, name, GUID, number} -> {" << + LOG_MSG("\t\tPlayerData: {playerId, name, number} -> {" << tmpPlayer->GetUniqueId() << "," << tmpPlayer->GetName() << "," << - tmpPlayer->GetGuid() << "," << - tmpPlayer->GetNumber() + //tmpPlayer->GetGuid() << "," << + tmpPlayer->GetNumber() << "}" ); ++player_i; @@ -1550,6 +1608,21 @@ ServerGameStateHand::InitRejoiningPlayers(boost::shared_ptr server) } } +void +ServerGameStateHand::InitReetryPlayers(boost::shared_ptr server) +{ + PlayerIdList reentryIdList(server->GetAndResetReentryPlayers()); + PlayerIdList::iterator i = reentryIdList.begin(); + PlayerIdList::iterator end = reentryIdList.end(); + while (i != end) { + boost::shared_ptr session(server->GetSessionManager().GetSessionByUniquePlayerId(*i)); + if (session && session->GetPlayerData()) { + PerformReentry(server, session); + } + ++i; + } +} + void ServerGameStateHand::InitNewSpectators(boost::shared_ptr server) { @@ -1596,6 +1669,30 @@ ServerGameStateHand::PerformRejoin(boost::shared_ptr server, boost:: } } +void +ServerGameStateHand::PerformReentry(boost::shared_ptr server, boost::shared_ptr session) +{ + Game &curGame = server->GetGame(); + + // TODO (albmed): + // Create player interface + if (session) { + // check if player already played this game + boost::shared_ptr tmpPlayer = curGame.getPlayerByName(session->GetPlayerData()->GetName()); + if (!tmpPlayer) { + tmpPlayer = curGame.addNewPlayer(session->GetPlayerData()); // TODO (albmed): Create addNewPlayer method + } + + int seat = getRandomFreeSeat(curGame.getActivePlayerList()); + if (seat >= 0) { // ok + // seat found.... + } + else throw ServerException(__FILE__, __LINE__, ERR_NET_INTERNAL_GAME_ERROR, 0); + } + + +} + void ServerGameStateHand::SendGameData(boost::shared_ptr server, boost::shared_ptr session) { diff --git a/src/net/servergame.h b/src/net/servergame.h index 52ae1f1e..7d916310 100644 --- a/src/net/servergame.h +++ b/src/net/servergame.h @@ -111,6 +111,10 @@ public: void AddRejoinPlayer(unsigned playerId); PlayerIdList GetAndResetRejoinPlayers(); + void AddReentryPlayer(unsigned playerId); + PlayerIdList GetAndResetReentryPlayers(); + int GetNumberPlayersReentry(); + void AddReactivatePlayer(unsigned playerId); PlayerIdList GetAndResetReactivatePlayers(); @@ -221,6 +225,9 @@ private: PlayerIdList m_rejoinPlayerList; mutable boost::mutex m_rejoinPlayerListMutex; + PlayerIdList m_reentryPlayerList; + mutable boost::mutex m_reentryPlayerListMutex; + PlayerIdList m_reactivatePlayerList; mutable boost::mutex m_reactivatePlayerListMutex; diff --git a/src/net/servergamestate.h b/src/net/servergamestate.h index a091d6d1..e7db339d 100644 --- a/src/net/servergamestate.h +++ b/src/net/servergamestate.h @@ -192,8 +192,10 @@ protected: static void CheckPlayerTimeouts(boost::shared_ptr server); static void ReactivatePlayers(boost::shared_ptr server); static void InitRejoiningPlayers(boost::shared_ptr server); + static void InitReetryPlayers(boost::shared_ptr server); static void InitNewSpectators(boost::shared_ptr server); static void PerformRejoin(boost::shared_ptr server, boost::shared_ptr session); + static void PerformReentry(boost::shared_ptr server, boost::shared_ptr session); static void SendGameData(boost::shared_ptr server, boost::shared_ptr session); private: