diff --git a/docs/pokerth.asn1 b/docs/pokerth.asn1 index 5454a1bf..857b96b5 100644 --- a/docs/pokerth.asn1 +++ b/docs/pokerth.asn1 @@ -489,7 +489,8 @@ HandStartMessage ::= [APPLICATION 23] SEQUENCE { plainCards [0] PlainCards, encryptedCards [1] EncryptedCards }, - smallBlind INTEGER(1..100000000) + smallBlind INTEGER(1..100000000), + seatStates SEQUENCE SIZE(2..10) OF NetPlayerState } PlayersTurnMessage ::= [APPLICATION 24] SEQUENCE { @@ -523,7 +524,6 @@ PlayersActionDoneMessage ::= [APPLICATION 27] SEQUENCE { playerId NonZeroId, gameState NetGameState, playerAction NetPlayerAction, - playerState NetPlayerState, totalPlayerBet AmountOfMoney, playerMoney AmountOfMoney, highestSet AmountOfMoney, @@ -748,7 +748,8 @@ DialogMessage ::= [APPLICATION 132] SEQUENCE { TimeoutWarningMessage ::= [APPLICATION 133] SEQUENCE { timeoutReason ENUMERATED { timeoutNoDataReceived (0), - timeoutInactiveGame (1) + timeoutInactiveGame (1), + timeoutKickAfterAutofold (2) }, remainingSeconds INTEGER } diff --git a/src/engine/game.cpp b/src/engine/game.cpp index 86158438..a07bfe56 100755 --- a/src/engine/game.cpp +++ b/src/engine/game.cpp @@ -217,6 +217,21 @@ boost::shared_ptr Game::getPlayerByUniqueId(unsigned id) return tmpPlayer; } +boost::shared_ptr Game::getPlayerByNumber(int number) +{ + boost::shared_ptr tmpPlayer; + PlayerListIterator i = getSeatsList()->begin(); + PlayerListIterator end = getSeatsList()->end(); + while (i != end) { + if ((*i)->getMyID() == number) { + tmpPlayer = *i; + break; + } + ++i; + } + return tmpPlayer; +} + boost::shared_ptr Game::getCurrentPlayer() { boost::shared_ptr tmpPlayer = getPlayerByUniqueId(getCurrentHand()->getCurrentBeRo()->getCurrentPlayersTurnId()); diff --git a/src/engine/game.h b/src/engine/game.h index cdc0762b..b03a123f 100755 --- a/src/engine/game.h +++ b/src/engine/game.h @@ -109,6 +109,7 @@ public: } boost::shared_ptr getPlayerByUniqueId(unsigned id); + boost::shared_ptr getPlayerByNumber(int number); boost::shared_ptr getPlayerByName(const std::string &name); boost::shared_ptr getCurrentPlayer(); diff --git a/src/net/clientthread.h b/src/net/clientthread.h index 3d5adaa6..990ca75e 100644 --- a/src/net/clientthread.h +++ b/src/net/clientthread.h @@ -102,6 +102,7 @@ public: ServerStats GetStatData() const; unsigned GetGameId() const; unsigned GetGuiPlayerId() const; + int GetOrigGuiPlayerNum() const; Gsasl *GetAuthContext(); @@ -268,6 +269,7 @@ private: unsigned m_curGameNum; unsigned m_guiPlayerId; mutable boost::mutex m_guiPlayerIdMutex; + int m_origGuiPlayerNum; bool m_sessionEstablished; mutable boost::mutex m_curStatsMutex; diff --git a/src/net/common/clientstate.cpp b/src/net/common/clientstate.cpp index e57b79cc..83388d06 100644 --- a/src/net/common/clientstate.cpp +++ b/src/net/common/clientstate.cpp @@ -1647,6 +1647,20 @@ ClientStateWaitHand::InternalHandlePacket(boost::shared_ptr client cardDataStream >> myCards[0]; cardDataStream >> myCards[1]; } + // Retrieve state for each seat (not based on player id). + NetPlayerState_t **seatStates = netHandStart->seatStates.list.array; + unsigned numPlayers = netHandStart->seatStates.list.count; + // Request player info for players if needed. + if (numPlayers && seatStates && *seatStates) { + for (int i = 0; i < numPlayers; i++) { + NetPlayerState_t *seatState = seatStates[i]; + boost::shared_ptr tmpPlayer = client->GetGame()->getPlayerByNumber((i + client->GetOrigGuiPlayerNum()) % client->GetStartData().numberOfPlayers); + if (!tmpPlayer) + throw ClientException(__FILE__, __LINE__, ERR_NET_UNKNOWN_PLAYER_ID, 0); + tmpPlayer->setIsSessionActive(*seatState == NetPlayerState_playerStateNormal); + } + } + // Basic synchronisation before a new hand is started. client->GetGui().waitForGuiUpdateDone(); // Start new hand. @@ -1785,7 +1799,6 @@ ClientStateRunHand::InternalHandlePacket(boost::shared_ptr client, } tmpPlayer->setMyAction(PlayerAction(netActionDone->playerAction)); - tmpPlayer->setIsSessionActive(netActionDone->playerState == NetPlayerState_playerStateNormal); tmpPlayer->setMySetAbsolute(netActionDone->totalPlayerBet); tmpPlayer->setMyCash(netActionDone->playerMoney); curGame->getCurrentHand()->getCurrentBeRo()->setHighestSet(netActionDone->highestSet); diff --git a/src/net/common/clientthread.cpp b/src/net/common/clientthread.cpp index 1657439e..18c9abd0 100644 --- a/src/net/common/clientthread.cpp +++ b/src/net/common/clientthread.cpp @@ -1018,6 +1018,12 @@ ClientThread::GetGuiPlayerId() const return m_guiPlayerId; } +int +ClientThread::GetOrigGuiPlayerNum() const +{ + return m_origGuiPlayerNum; +} + void ClientThread::SetGuiPlayerId(unsigned guiPlayerId) { @@ -1084,7 +1090,7 @@ ClientThread::MapPlayerDataList() // Retrieve the GUI player. boost::shared_ptr guiPlayer = GetPlayerDataByUniqueId(GetGuiPlayerId()); assert(guiPlayer.get()); - int guiPlayerNum = guiPlayer->GetNumber(); + m_origGuiPlayerNum = guiPlayer->GetNumber(); // Create a copy of the player list so that the GUI player // is player 0. This is mapped because the GUI depends on it. @@ -1096,7 +1102,7 @@ ClientThread::MapPlayerDataList() while (i != end) { boost::shared_ptr tmpData(new PlayerData(*(*i))); - int numberDiff = tmpData->GetNumber() - guiPlayerNum; + int numberDiff = tmpData->GetNumber() - m_origGuiPlayerNum; if (numberDiff >= 0) tmpData->SetNumber(numberDiff); else @@ -1171,7 +1177,6 @@ ClientThread::RemoveDisconnectedPlayers() if (tmpPlayer->isKicked()) { tmpPlayer->setMyCash(0); } - tmpPlayer->setMyActiveStatus(false); } } ++i; diff --git a/src/net/common/servergame.cpp b/src/net/common/servergame.cpp index 18f9a8d6..ccd4f60c 100644 --- a/src/net/common/servergame.cpp +++ b/src/net/common/servergame.cpp @@ -670,6 +670,22 @@ ServerGame::GetAndResetRejoinPlayers() return tmpList; } +void +ServerGame::AddReactivatePlayer(unsigned playerId) +{ + boost::mutex::scoped_lock lock(m_reactivatePlayerListMutex); + m_reactivatePlayerList.push_back(playerId); +} + +PlayerIdList +ServerGame::GetAndResetReactivatePlayers() +{ + boost::mutex::scoped_lock lock(m_reactivatePlayerListMutex); + PlayerIdList tmpList(m_reactivatePlayerList); + m_reactivatePlayerList.clear(); + return tmpList; +} + void ServerGame::AddComputerPlayer(boost::shared_ptr player) { diff --git a/src/net/common/servergamestate.cpp b/src/net/common/servergamestate.cpp index fee241d9..305c832c 100644 --- a/src/net/common/servergamestate.cpp +++ b/src/net/common/servergamestate.cpp @@ -86,7 +86,6 @@ static void SendPlayerAction(ServerGame &server, boost::shared_ptrhighestSet = server.GetGame().getCurrentHand()->getCurrentBeRo()->getHighestSet(); netActionDone->minimumRaise = server.GetGame().getCurrentHand()->getCurrentBeRo()->getMinimumRaise(); netActionDone->playerAction = player->getMyAction(); - netActionDone->playerState = player->isSessionActive() ? NetPlayerState_playerStateNormal : NetPlayerState_playerStateSessionInactive; netActionDone->playerId = player->getMyUniqueID(); netActionDone->playerMoney = player->getMyCash(); netActionDone->totalPlayerBet = player->getMySet(); @@ -357,11 +356,7 @@ AbstractServerGameStateReceiving::ProcessPacket(boost::shared_ptr se } else if (packet->GetMsg()->present == PokerTHMessage_PR_resetTimeoutMessage) { // Reactivate session. if (server->IsRunning()) { - boost::shared_ptr tmpPlayer = server->GetGame().getPlayerByUniqueId(session->GetPlayerData()->GetUniqueId()); - if (tmpPlayer) { - tmpPlayer->markRemoteAction(); - tmpPlayer->setIsSessionActive(true); - } + server->AddReactivatePlayer(session->GetPlayerData()->GetUniqueId()); } } else { // Packet processing in subclass. @@ -626,7 +621,7 @@ ServerGameStateInit::InternalProcessPacket(boost::shared_ptr server, && netStartEvent->startEventType.present == startEventType_PR_startEvent && (server->GetGameData().gameType != GAME_TYPE_RANKING // ranking games need to be full || server->GetGameData().maxNumberOfPlayers == server->GetCurNumberOfPlayers())) { - SendStartEvent(*server, netStartEvent->startEventType.choice.startEvent.fillWithComputerPlayers); + SendStartEvent(*server, netStartEvent->startEventType.choice.startEvent.fillWithComputerPlayers != 0); } else { // kick players who try to start but are not allowed to server->MoveSessionToLobby(session, NTF_NET_REMOVED_START_FAILED); } @@ -952,28 +947,6 @@ ServerGameStateHand::EngineLoop(boost::shared_ptr server) &ServerGameStateHand::TimerComputerAction, this, boost::asio::placeholders::error, server)); } else { - // Check timeout. - int actionTimeout = server->GetGameData().playerActionTimeoutSec; - if (actionTimeout) { - if (curPlayer->getTimeSecSinceLastRemoteAction() >= actionTimeout * SERVER_GAME_AUTOFOLD_TIMEOUT_FACTOR) { - if (curPlayer->isSessionActive()) { - curPlayer->setIsSessionActive(false); - boost::shared_ptr session = server->GetSessionManager().GetSessionByUniquePlayerId(curPlayer->getMyUniqueID()); - if (session) { - boost::shared_ptr packet(new NetPacket(NetPacket::Alloc)); - packet->GetMsg()->present = PokerTHMessage_PR_timeoutWarningMessage; - TimeoutWarningMessage_t *netWarning = &packet->GetMsg()->choice.timeoutWarningMessage; - netWarning->timeoutReason = NETWORK_TIMEOUT_GENERIC; - netWarning->remainingSeconds = actionTimeout * SERVER_GAME_FORCED_TIMEOUT_FACTOR - curPlayer->getTimeSecSinceLastRemoteAction(); - server->GetLobbyThread().GetSender().Send(session, packet); - } - } - if (curPlayer->getTimeSecSinceLastRemoteAction() >= actionTimeout * SERVER_GAME_FORCED_TIMEOUT_FACTOR) { - server->KickPlayer(curPlayer->getMyUniqueID()); - } - } - } - // If the player we are waiting for left, continue without him. if (!server->GetSessionManager().IsPlayerConnected(curPlayer->getMyUniqueID()) || !curPlayer->isSessionActive()) { @@ -1157,6 +1130,10 @@ ServerGameStateHand::StartNewHand(boost::shared_ptr server) { Game &curGame = server->GetGame(); + // Kick inactive players. + ReactivatePlayers(server); + CheckPlayerTimeouts(server); + // Initialize rejoining players. // This has to be done before initialising the new hand, because there are side effects. InitRejoiningPlayers(server); @@ -1218,6 +1195,15 @@ ServerGameStateHand::StartNewHand(boost::shared_ptr server) errorFlag = true; } } + PlayerListIterator player_i = curGame.getSeatsList()->begin(); + PlayerListIterator player_end = curGame.getSeatsList()->end(); + while (player_i != player_end) { + NetPlayerState_t *seatState = (NetPlayerState_t *)calloc(1, sizeof(NetPlayerState_t)); + *seatState = (*player_i)->isSessionActive() ? NetPlayerState_playerStateNormal : NetPlayerState_playerStateSessionInactive; + ASN_SEQUENCE_ADD(&netHandStart->seatStates.list, seatState); + ++player_i; + } + if (!errorFlag) { netHandStart->smallBlind = curGame.getCurrentHand()->getSmallBlind(); server->GetLobbyThread().GetSender().Send(tmpSession, notifyCards); @@ -1243,7 +1229,6 @@ ServerGameStateHand::StartNewHand(boost::shared_ptr server) netSmallBlind->gameState = NetGameState_statePreflopSmallBlind; netSmallBlind->playerId = tmpPlayer->getMyUniqueID(); netSmallBlind->playerAction = tmpPlayer->getMyAction(); - netSmallBlind->playerState = tmpPlayer->isSessionActive() ? NetPlayerState_playerStateNormal : NetPlayerState_playerStateSessionInactive; netSmallBlind->totalPlayerBet = tmpPlayer->getMySet(); netSmallBlind->playerMoney = tmpPlayer->getMyCash(); netSmallBlind->highestSet = server->GetGame().getCurrentHand()->getCurrentBeRo()->getHighestSet(); @@ -1266,7 +1251,6 @@ ServerGameStateHand::StartNewHand(boost::shared_ptr server) netBigBlind->gameState = NetGameState_statePreflopBigBlind; netBigBlind->playerId = tmpPlayer->getMyUniqueID(); netBigBlind->playerAction = tmpPlayer->getMyAction(); - netBigBlind->playerState = tmpPlayer->isSessionActive() ? NetPlayerState_playerStateNormal : NetPlayerState_playerStateSessionInactive; netBigBlind->totalPlayerBet = tmpPlayer->getMySet(); netBigBlind->playerMoney = tmpPlayer->getMyCash(); netBigBlind->highestSet = server->GetGame().getCurrentHand()->getCurrentBeRo()->getHighestSet(); @@ -1278,6 +1262,55 @@ ServerGameStateHand::StartNewHand(boost::shared_ptr server) } } +void +ServerGameStateHand::CheckPlayerTimeouts(boost::shared_ptr server) +{ + // Consider all players, even inactive. + PlayerListIterator i = server->GetGame().getSeatsList()->begin(); + PlayerListIterator end = server->GetGame().getSeatsList()->end(); + + // Send cards to all players. + while (i != end) { + boost::shared_ptr tmpPlayer = *i; + // Check timeout. + int actionTimeout = server->GetGameData().playerActionTimeoutSec; + if (actionTimeout) { + if ((int)tmpPlayer->getTimeSecSinceLastRemoteAction() >= actionTimeout * SERVER_GAME_AUTOFOLD_TIMEOUT_FACTOR) { + if (tmpPlayer->isSessionActive()) { + tmpPlayer->setIsSessionActive(false); + boost::shared_ptr session = server->GetSessionManager().GetSessionByUniquePlayerId(tmpPlayer->getMyUniqueID()); + if (session) { + boost::shared_ptr packet(new NetPacket(NetPacket::Alloc)); + packet->GetMsg()->present = PokerTHMessage_PR_timeoutWarningMessage; + TimeoutWarningMessage_t *netWarning = &packet->GetMsg()->choice.timeoutWarningMessage; + netWarning->timeoutReason = NETWORK_TIMEOUT_GENERIC; + netWarning->remainingSeconds = actionTimeout * SERVER_GAME_FORCED_TIMEOUT_FACTOR - tmpPlayer->getTimeSecSinceLastRemoteAction(); + server->GetLobbyThread().GetSender().Send(session, packet); + } + } + if ((int)tmpPlayer->getTimeSecSinceLastRemoteAction() >= actionTimeout * SERVER_GAME_FORCED_TIMEOUT_FACTOR) { + server->KickPlayer(tmpPlayer->getMyUniqueID()); + } + } + } + ++i; + } +} + +void +ServerGameStateHand::ReactivatePlayers(boost::shared_ptr server) +{ + PlayerIdList reactivateIdList(server->GetAndResetReactivatePlayers()); + PlayerIdList::iterator i = reactivateIdList.begin(); + PlayerIdList::iterator end = reactivateIdList.end(); + while (i != end) { + boost::shared_ptr tmpPlayer(server->GetGame().getPlayerByUniqueId(*i)); + tmpPlayer->markRemoteAction(); + tmpPlayer->setIsSessionActive(true); + ++i; + } +} + void ServerGameStateHand::InitRejoiningPlayers(boost::shared_ptr server) { diff --git a/src/net/servergame.h b/src/net/servergame.h index e89ccbfa..f84ce542 100644 --- a/src/net/servergame.h +++ b/src/net/servergame.h @@ -92,6 +92,9 @@ public: void AddRejoinPlayer(unsigned playerId); PlayerIdList GetAndResetRejoinPlayers(); + void AddReactivatePlayer(unsigned playerId); + PlayerIdList GetAndResetReactivatePlayers(); + // should be protected, but is needed in function. const Game &GetGame() const; Game &GetGame(); @@ -179,6 +182,9 @@ private: PlayerIdList m_rejoinPlayerList; mutable boost::mutex m_rejoinPlayerListMutex; + PlayerIdList m_reactivatePlayerList; + mutable boost::mutex m_reactivatePlayerListMutex; + PlayerIdList m_reportedAvatarList; RankingMap m_rankingMap; diff --git a/src/net/servergamestate.h b/src/net/servergamestate.h index f7e44fd5..cd08c20f 100644 --- a/src/net/servergamestate.h +++ b/src/net/servergamestate.h @@ -165,6 +165,8 @@ protected: void TimerNextGame(const boost::system::error_code &ec, boost::shared_ptr server, unsigned winnerPlayerId); int GetDealCardsDelaySec(ServerGame &server); static void StartNewHand(boost::shared_ptr server); + static void CheckPlayerTimeouts(boost::shared_ptr server); + static void ReactivatePlayers(boost::shared_ptr server); static void InitRejoiningPlayers(boost::shared_ptr server); static void PerformRejoin(boost::shared_ptr server, boost::shared_ptr session); diff --git a/src/third_party/asn1/ErrorMessage.c b/src/third_party/asn1/ErrorMessage.c index b92f0fc2..00b62c66 100644 --- a/src/third_party/asn1/ErrorMessage.c +++ b/src/third_party/asn1/ErrorMessage.c @@ -166,7 +166,7 @@ static ber_tlv_tag_t asn_DEF_ErrorMessage_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) }; static asn_TYPE_tag2member_t asn_MAP_ErrorMessage_tag2el_1[] = { - { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 0, 0, 0 } /* errorReason at 775 */ + { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 0, 0, 0 } /* errorReason at 776 */ }; static asn_SEQUENCE_specifics_t asn_SPC_ErrorMessage_specs_1 = { sizeof(struct ErrorMessage), diff --git a/src/third_party/asn1/HandStartMessage.c b/src/third_party/asn1/HandStartMessage.c index 2351f9b9..10a21302 100644 --- a/src/third_party/asn1/HandStartMessage.c +++ b/src/third_party/asn1/HandStartMessage.c @@ -32,6 +32,32 @@ memb_smallBlind_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, } } +static int +memb_seatStates_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr, + asn_app_constraint_failed_f *ctfailcb, void *app_key) { + size_t size; + + if(!sptr) { + _ASN_CTFAIL(app_key, td, sptr, + "%s: value not given (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } + + /* Determine the number of elements */ + size = _A_CSEQUENCE_FROM_VOID(sptr)->count; + + if((size >= 2 && size <= 10)) { + /* Perform validation of the inner elements */ + return td->check_constraints(td, sptr, ctfailcb, app_key); + } else { + _ASN_CTFAIL(app_key, td, sptr, + "%s: constraint failed (%s:%d)", + td->name, __FILE__, __LINE__); + return -1; + } +} + static asn_TYPE_member_t asn_MBR_yourCards_3[] = { { ATF_NOFLAGS, 0, offsetof(struct yourCards, choice.plainCards), (ASN_TAG_CLASS_CONTEXT | (0 << 2)), @@ -89,6 +115,50 @@ asn_TYPE_descriptor_t asn_DEF_yourCards_3 = { &asn_SPC_yourCards_specs_3 /* Additional specs */ }; +static asn_TYPE_member_t asn_MBR_seatStates_8[] = { + { ATF_POINTER, 0, 0, + (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), + 0, + &asn_DEF_NetPlayerState, + 0, /* Defer constraints checking to the member type */ + 0, /* PER is not compiled, use -gen-PER */ + 0, + "" + }, +}; +static ber_tlv_tag_t asn_DEF_seatStates_tags_8[] = { + (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) +}; +static asn_SET_OF_specifics_t asn_SPC_seatStates_specs_8 = { + sizeof(struct seatStates), + offsetof(struct seatStates, _asn_ctx), + 1, /* XER encoding is XMLValueList */ +}; +static /* Use -fall-defs-global to expose */ +asn_TYPE_descriptor_t asn_DEF_seatStates_8 = { + "seatStates", + "seatStates", + SEQUENCE_OF_free, + SEQUENCE_OF_print, + SEQUENCE_OF_constraint, + SEQUENCE_OF_decode_ber, + SEQUENCE_OF_encode_der, + SEQUENCE_OF_decode_xer, + SEQUENCE_OF_encode_xer, + 0, 0, /* No PER support, use "-gen-PER" to enable */ + 0, /* Use generic outmost tag fetcher */ + asn_DEF_seatStates_tags_8, + sizeof(asn_DEF_seatStates_tags_8) + /sizeof(asn_DEF_seatStates_tags_8[0]), /* 1 */ + asn_DEF_seatStates_tags_8, /* Same as above */ + sizeof(asn_DEF_seatStates_tags_8) + /sizeof(asn_DEF_seatStates_tags_8[0]), /* 1 */ + 0, /* No PER visible constraints */ + asn_MBR_seatStates_8, + 1, /* Single element */ + &asn_SPC_seatStates_specs_8 /* Additional specs */ +}; + static asn_TYPE_member_t asn_MBR_HandStartMessage_1[] = { { ATF_NOFLAGS, 0, offsetof(struct HandStartMessage, gameId), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), @@ -117,6 +187,15 @@ static asn_TYPE_member_t asn_MBR_HandStartMessage_1[] = { 0, "smallBlind" }, + { ATF_NOFLAGS, 0, offsetof(struct HandStartMessage, seatStates), + (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), + 0, + &asn_DEF_seatStates_8, + memb_seatStates_constraint_1, + 0, /* PER is not compiled, use -gen-PER */ + 0, + "seatStates" + }, }; static ber_tlv_tag_t asn_DEF_HandStartMessage_tags_1[] = { (ASN_TAG_CLASS_APPLICATION | (23 << 2)), @@ -125,6 +204,7 @@ static ber_tlv_tag_t asn_DEF_HandStartMessage_tags_1[] = { static asn_TYPE_tag2member_t asn_MAP_HandStartMessage_tag2el_1[] = { { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 1 }, /* gameId at 487 */ { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 0 }, /* smallBlind at 492 */ + { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 3, 0, 0 }, /* seatStates at 494 */ { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 1, 0, 0 }, /* plainCards at 489 */ { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 } /* encryptedCards at 491 */ }; @@ -132,10 +212,10 @@ static asn_SEQUENCE_specifics_t asn_SPC_HandStartMessage_specs_1 = { sizeof(struct HandStartMessage), offsetof(struct HandStartMessage, _asn_ctx), asn_MAP_HandStartMessage_tag2el_1, - 4, /* Count of tags in the map */ + 5, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - 2, /* Start extensions */ - 4 /* Stop extensions */ + 3, /* Start extensions */ + 5 /* Stop extensions */ }; asn_TYPE_descriptor_t asn_DEF_HandStartMessage = { "HandStartMessage", @@ -157,7 +237,7 @@ asn_TYPE_descriptor_t asn_DEF_HandStartMessage = { /sizeof(asn_DEF_HandStartMessage_tags_1[0]), /* 2 */ 0, /* No PER visible constraints */ asn_MBR_HandStartMessage_1, - 3, /* Elements count */ + 4, /* Elements count */ &asn_SPC_HandStartMessage_specs_1 /* Additional specs */ }; diff --git a/src/third_party/asn1/HandStartMessage.h b/src/third_party/asn1/HandStartMessage.h index 119e6d24..1bfaf8bc 100644 --- a/src/third_party/asn1/HandStartMessage.h +++ b/src/third_party/asn1/HandStartMessage.h @@ -17,6 +17,9 @@ #include "PlainCards.h" #include "EncryptedCards.h" #include +#include "NetPlayerState.h" +#include +#include #include #ifdef __cplusplus @@ -51,6 +54,12 @@ extern "C" { asn_struct_ctx_t _asn_ctx; } yourCards; long smallBlind; + struct seatStates { + A_SEQUENCE_OF(NetPlayerState_t) list; + + /* Context for parsing across buffer boundaries */ + asn_struct_ctx_t _asn_ctx; + } seatStates; /* * This type is extensible, * possible extensions are below. diff --git a/src/third_party/asn1/MyActionRequestMessage.c b/src/third_party/asn1/MyActionRequestMessage.c index 318fbe16..bf170da4 100644 --- a/src/third_party/asn1/MyActionRequestMessage.c +++ b/src/third_party/asn1/MyActionRequestMessage.c @@ -59,11 +59,11 @@ static ber_tlv_tag_t asn_DEF_MyActionRequestMessage_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) }; static asn_TYPE_tag2member_t asn_MAP_MyActionRequestMessage_tag2el_1[] = { - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 2 }, /* gameId at 502 */ - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, -1, 1 }, /* handNum at 503 */ - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 4, -2, 0 }, /* myRelativeBet at 507 */ - { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 2, 0, 1 }, /* gameState at 504 */ - { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 3, -1, 0 } /* myAction at 505 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 2 }, /* gameId at 503 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, -1, 1 }, /* handNum at 504 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 4, -2, 0 }, /* myRelativeBet at 508 */ + { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 2, 0, 1 }, /* gameState at 505 */ + { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 3, -1, 0 } /* myAction at 506 */ }; static asn_SEQUENCE_specifics_t asn_SPC_MyActionRequestMessage_specs_1 = { sizeof(struct MyActionRequestMessage), diff --git a/src/third_party/asn1/PlayersActionDoneMessage.c b/src/third_party/asn1/PlayersActionDoneMessage.c index 0f48e9d7..629f402d 100644 --- a/src/third_party/asn1/PlayersActionDoneMessage.c +++ b/src/third_party/asn1/PlayersActionDoneMessage.c @@ -44,15 +44,6 @@ static asn_TYPE_member_t asn_MBR_PlayersActionDoneMessage_1[] = { 0, "playerAction" }, - { ATF_NOFLAGS, 0, offsetof(struct PlayersActionDoneMessage, playerState), - (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), - 0, - &asn_DEF_NetPlayerState, - 0, /* Defer constraints checking to the member type */ - 0, /* PER is not compiled, use -gen-PER */ - 0, - "playerState" - }, { ATF_NOFLAGS, 0, offsetof(struct PlayersActionDoneMessage, totalPlayerBet), (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, @@ -95,24 +86,23 @@ static ber_tlv_tag_t asn_DEF_PlayersActionDoneMessage_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) }; static asn_TYPE_tag2member_t asn_MAP_PlayersActionDoneMessage_tag2el_1[] = { - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 5 }, /* gameId at 522 */ - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, -1, 4 }, /* playerId at 523 */ - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 5, -2, 3 }, /* totalPlayerBet at 527 */ - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 6, -3, 2 }, /* playerMoney at 528 */ - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 7, -4, 1 }, /* highestSet at 529 */ - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 8, -5, 0 }, /* minimumRaise at 531 */ - { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 2, 0, 2 }, /* gameState at 524 */ - { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 3, -1, 1 }, /* playerAction at 525 */ - { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 4, -2, 0 } /* playerState at 526 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 5 }, /* gameId at 523 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, -1, 4 }, /* playerId at 524 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 4, -2, 3 }, /* totalPlayerBet at 527 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 5, -3, 2 }, /* playerMoney at 528 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 6, -4, 1 }, /* highestSet at 529 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 7, -5, 0 }, /* minimumRaise at 531 */ + { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 2, 0, 1 }, /* gameState at 525 */ + { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 3, -1, 0 } /* playerAction at 526 */ }; static asn_SEQUENCE_specifics_t asn_SPC_PlayersActionDoneMessage_specs_1 = { sizeof(struct PlayersActionDoneMessage), offsetof(struct PlayersActionDoneMessage, _asn_ctx), asn_MAP_PlayersActionDoneMessage_tag2el_1, - 9, /* Count of tags in the map */ + 8, /* Count of tags in the map */ 0, 0, 0, /* Optional elements (not needed) */ - 8, /* Start extensions */ - 10 /* Stop extensions */ + 7, /* Start extensions */ + 9 /* Stop extensions */ }; asn_TYPE_descriptor_t asn_DEF_PlayersActionDoneMessage = { "PlayersActionDoneMessage", @@ -134,7 +124,7 @@ asn_TYPE_descriptor_t asn_DEF_PlayersActionDoneMessage = { /sizeof(asn_DEF_PlayersActionDoneMessage_tags_1[0]), /* 2 */ 0, /* No PER visible constraints */ asn_MBR_PlayersActionDoneMessage_1, - 9, /* Elements count */ + 8, /* Elements count */ &asn_SPC_PlayersActionDoneMessage_specs_1 /* Additional specs */ }; diff --git a/src/third_party/asn1/PlayersActionDoneMessage.h b/src/third_party/asn1/PlayersActionDoneMessage.h index 6984a149..bf6f76f6 100644 --- a/src/third_party/asn1/PlayersActionDoneMessage.h +++ b/src/third_party/asn1/PlayersActionDoneMessage.h @@ -15,7 +15,6 @@ #include "NonZeroId.h" #include "NetGameState.h" #include "NetPlayerAction.h" -#include "NetPlayerState.h" #include "AmountOfMoney.h" #include @@ -29,7 +28,6 @@ extern "C" { NonZeroId_t playerId; NetGameState_t gameState; NetPlayerAction_t playerAction; - NetPlayerState_t playerState; AmountOfMoney_t totalPlayerBet; AmountOfMoney_t playerMoney; AmountOfMoney_t highestSet; diff --git a/src/third_party/asn1/PlayersTurnMessage.c b/src/third_party/asn1/PlayersTurnMessage.c index 89a18e89..8a6357aa 100644 --- a/src/third_party/asn1/PlayersTurnMessage.c +++ b/src/third_party/asn1/PlayersTurnMessage.c @@ -41,9 +41,9 @@ static ber_tlv_tag_t asn_DEF_PlayersTurnMessage_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) }; static asn_TYPE_tag2member_t asn_MAP_PlayersTurnMessage_tag2el_1[] = { - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 1 }, /* gameId at 496 */ - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, -1, 0 }, /* playerId at 497 */ - { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 2, 0, 0 } /* gameState at 499 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 1 }, /* gameId at 497 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, -1, 0 }, /* playerId at 498 */ + { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 2, 0, 0 } /* gameState at 500 */ }; static asn_SEQUENCE_specifics_t asn_SPC_PlayersTurnMessage_specs_1 = { sizeof(struct PlayersTurnMessage), diff --git a/src/third_party/asn1/ReportAvatarAckMessage.c b/src/third_party/asn1/ReportAvatarAckMessage.c index 21a07d71..13b7cac7 100644 --- a/src/third_party/asn1/ReportAvatarAckMessage.c +++ b/src/third_party/asn1/ReportAvatarAckMessage.c @@ -151,8 +151,8 @@ static ber_tlv_tag_t asn_DEF_ReportAvatarAckMessage_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) }; static asn_TYPE_tag2member_t asn_MAP_ReportAvatarAckMessage_tag2el_1[] = { - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* reportedPlayerId at 765 */ - { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 1, 0, 0 } /* reportResult at 767 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* reportedPlayerId at 766 */ + { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 1, 0, 0 } /* reportResult at 768 */ }; static asn_SEQUENCE_specifics_t asn_SPC_ReportAvatarAckMessage_specs_1 = { sizeof(struct ReportAvatarAckMessage), diff --git a/src/third_party/asn1/ReportAvatarMessage.c b/src/third_party/asn1/ReportAvatarMessage.c index 3e85ff3e..d3d63e06 100644 --- a/src/third_party/asn1/ReportAvatarMessage.c +++ b/src/third_party/asn1/ReportAvatarMessage.c @@ -32,8 +32,8 @@ static ber_tlv_tag_t asn_DEF_ReportAvatarMessage_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) }; static asn_TYPE_tag2member_t asn_MAP_ReportAvatarMessage_tag2el_1[] = { - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* reportedPlayerId at 760 */ - { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 } /* reportedAvatar at 762 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* reportedPlayerId at 761 */ + { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 } /* reportedAvatar at 763 */ }; static asn_SEQUENCE_specifics_t asn_SPC_ReportAvatarMessage_specs_1 = { sizeof(struct ReportAvatarMessage), diff --git a/src/third_party/asn1/TimeoutWarningMessage.c b/src/third_party/asn1/TimeoutWarningMessage.c index 69111850..29a15830 100644 --- a/src/third_party/asn1/TimeoutWarningMessage.c +++ b/src/third_party/asn1/TimeoutWarningMessage.c @@ -82,16 +82,18 @@ timeoutReason_2_encode_xer(asn_TYPE_descriptor_t *td, void *structure, static asn_INTEGER_enum_map_t asn_MAP_timeoutReason_value2enum_2[] = { { 0, 21, "timeoutNoDataReceived" }, - { 1, 19, "timeoutInactiveGame" } + { 1, 19, "timeoutInactiveGame" }, + { 2, 24, "timeoutKickAfterAutofold" } }; static unsigned int asn_MAP_timeoutReason_enum2value_2[] = { 1, /* timeoutInactiveGame(1) */ + 2, /* timeoutKickAfterAutofold(2) */ 0 /* timeoutNoDataReceived(0) */ }; static asn_INTEGER_specifics_t asn_SPC_timeoutReason_specs_2 = { asn_MAP_timeoutReason_value2enum_2, /* "tag" => N; sorted by tag */ asn_MAP_timeoutReason_enum2value_2, /* N => "tag"; sorted by N */ - 2, /* Number of elements in the maps */ + 3, /* Number of elements in the maps */ 0, /* Enumeration is not extensible */ 1, /* Strict enumeration */ 0, /* Native long size */ @@ -149,7 +151,7 @@ static ber_tlv_tag_t asn_DEF_TimeoutWarningMessage_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) }; static asn_TYPE_tag2member_t asn_MAP_TimeoutWarningMessage_tag2el_1[] = { - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 0 }, /* remainingSeconds at 754 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 0 }, /* remainingSeconds at 755 */ { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 0, 0, 0 } /* timeoutReason at 750 */ }; static asn_SEQUENCE_specifics_t asn_SPC_TimeoutWarningMessage_specs_1 = { diff --git a/src/third_party/asn1/TimeoutWarningMessage.h b/src/third_party/asn1/TimeoutWarningMessage.h index bee21676..376b94c1 100644 --- a/src/third_party/asn1/TimeoutWarningMessage.h +++ b/src/third_party/asn1/TimeoutWarningMessage.h @@ -23,9 +23,10 @@ extern "C" { /* Dependencies */ typedef enum timeoutReason { timeoutReason_timeoutNoDataReceived = 0, - timeoutReason_timeoutInactiveGame = 1 + timeoutReason_timeoutInactiveGame = 1, + timeoutReason_timeoutKickAfterAutofold = 2 } - e_timeoutReason; + e_timeoutReason; /* TimeoutWarningMessage */ typedef struct TimeoutWarningMessage { diff --git a/src/third_party/asn1/YourActionRejectedMessage.c b/src/third_party/asn1/YourActionRejectedMessage.c index 11c8acaf..b5cc04ad 100644 --- a/src/third_party/asn1/YourActionRejectedMessage.c +++ b/src/third_party/asn1/YourActionRejectedMessage.c @@ -178,11 +178,11 @@ static ber_tlv_tag_t asn_DEF_YourActionRejectedMessage_tags_1[] = { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)) }; static asn_TYPE_tag2member_t asn_MAP_YourActionRejectedMessage_tag2el_1[] = { - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 1 }, /* gameId at 510 */ - { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -1, 0 }, /* yourRelativeBet at 513 */ - { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 1, 0, 2 }, /* gameState at 511 */ - { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 2, -1, 1 }, /* yourAction at 512 */ - { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 4, -2, 0 } /* rejectionReason at 515 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 1 }, /* gameId at 511 */ + { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -1, 0 }, /* yourRelativeBet at 514 */ + { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 1, 0, 2 }, /* gameState at 512 */ + { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 2, -1, 1 }, /* yourAction at 513 */ + { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 4, -2, 0 } /* rejectionReason at 516 */ }; static asn_SEQUENCE_specifics_t asn_SPC_YourActionRejectedMessage_specs_1 = { sizeof(struct YourActionRejectedMessage), diff --git a/tests/src/pokerth_protocol/HandStartMessage.java b/tests/src/pokerth_protocol/HandStartMessage.java index f95e660f..45ec1f74 100644 --- a/tests/src/pokerth_protocol/HandStartMessage.java +++ b/tests/src/pokerth_protocol/HandStartMessage.java @@ -122,6 +122,21 @@ import org.bn.types.*; private Integer smallBlind = null; +@ASN1SequenceOf( name = "seatStates", isSetOf = false ) + + @ASN1ValueRangeConstraint ( + + min = 2L, + + max = 10L + + ) + + @ASN1Element ( name = "seatStates", isOptional = false , hasTag = false , hasDefaultValue = false ) + + private java.util.Collection seatStates = null; + + public NonZeroId getGameId () { return this.gameId; @@ -158,6 +173,18 @@ import org.bn.types.*; } + + public java.util.Collection getSeatStates () { + return this.seatStates; + } + + + + public void setSeatStates (java.util.Collection value) { + this.seatStates = value; + } + + public void initWithDefaults() { diff --git a/tests/src/pokerth_protocol/PlayersActionDoneMessage.java b/tests/src/pokerth_protocol/PlayersActionDoneMessage.java index de9c9a88..021ae642 100644 --- a/tests/src/pokerth_protocol/PlayersActionDoneMessage.java +++ b/tests/src/pokerth_protocol/PlayersActionDoneMessage.java @@ -45,11 +45,6 @@ import org.bn.types.*; private NetPlayerAction playerAction = null; - @ASN1Element ( name = "playerState", isOptional = false , hasTag = false , hasDefaultValue = false ) - - private NetPlayerState playerState = null; - - @ASN1Element ( name = "totalPlayerBet", isOptional = false , hasTag = false , hasDefaultValue = false ) private AmountOfMoney totalPlayerBet = null; @@ -119,18 +114,6 @@ import org.bn.types.*; - public NetPlayerState getPlayerState () { - return this.playerState; - } - - - - public void setPlayerState (NetPlayerState value) { - this.playerState = value; - } - - - public AmountOfMoney getTotalPlayerBet () { return this.totalPlayerBet; } diff --git a/tests/src/pokerth_protocol/TimeoutWarningMessage.java b/tests/src/pokerth_protocol/TimeoutWarningMessage.java index 36496ad0..a74a0699 100644 --- a/tests/src/pokerth_protocol/TimeoutWarningMessage.java +++ b/tests/src/pokerth_protocol/TimeoutWarningMessage.java @@ -37,6 +37,8 @@ import org.bn.types.*; timeoutNoDataReceived , @ASN1EnumItem ( name = "timeoutInactiveGame", hasTag = true , tag = 1 ) timeoutInactiveGame , + @ASN1EnumItem ( name = "timeoutKickAfterAutofold", hasTag = true , tag = 2 ) + timeoutKickAfterAutofold , } private EnumType value;