2011-07-02 14:38:06 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
|
* PokerTH - The open source texas holdem engine *
|
2012-09-18 15:57:58 +02:00
|
|
|
* Copyright (C) 2006-2012 Felix Hammer, Florian Thauer, Lothar May *
|
2011-07-02 14:38:06 +00:00
|
|
|
* *
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify *
|
|
|
|
|
* it under the terms of the GNU Affero General Public License as *
|
|
|
|
|
* published by the Free Software Foundation, either version 3 of the *
|
|
|
|
|
* License, or (at your option) any later version. *
|
|
|
|
|
* *
|
|
|
|
|
* This program is distributed in the hope that it will be useful, *
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
|
* GNU Affero General Public License for more details. *
|
|
|
|
|
* *
|
|
|
|
|
* You should have received a copy of the GNU Affero General Public License *
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
2012-12-25 15:06:23 +01:00
|
|
|
* *
|
|
|
|
|
* *
|
|
|
|
|
* Additional permission under GNU AGPL version 3 section 7 *
|
|
|
|
|
* *
|
|
|
|
|
* If you modify this program, or any covered work, by linking or *
|
|
|
|
|
* combining it with the OpenSSL project's OpenSSL library (or a *
|
|
|
|
|
* modified version of that library), containing parts covered by the *
|
|
|
|
|
* terms of the OpenSSL or SSLeay licenses, the authors of PokerTH *
|
|
|
|
|
* (Felix Hammer, Florian Thauer, Lothar May) grant you additional *
|
|
|
|
|
* permission to convey the resulting work. *
|
|
|
|
|
* Corresponding Source for a non-source form of such a combination *
|
|
|
|
|
* shall include the source code for the parts of OpenSSL used as well *
|
|
|
|
|
* as that of the covered work. *
|
2011-07-02 14:38:06 +00:00
|
|
|
*****************************************************************************/
|
2007-10-18 17:40:12 +00:00
|
|
|
|
|
|
|
|
#include <net/servergamestate.h>
|
2009-05-31 19:45:20 +00:00
|
|
|
#include <net/servergame.h>
|
2007-10-18 17:40:12 +00:00
|
|
|
#include <net/serverlobbythread.h>
|
2009-05-10 22:21:20 +00:00
|
|
|
#include <net/senderhelper.h>
|
2007-10-18 17:40:12 +00:00
|
|
|
#include <net/netpacket.h>
|
|
|
|
|
#include <net/socket_msg.h>
|
2007-10-18 20:36:49 +00:00
|
|
|
#include <net/serverexception.h>
|
2010-08-01 19:23:08 +00:00
|
|
|
#include <net/net_helper.h>
|
2011-01-30 18:28:44 +00:00
|
|
|
#include <net/chatcleanermanager.h>
|
2010-07-19 19:29:49 +00:00
|
|
|
#include <db/serverdbinterface.h>
|
2009-07-12 21:12:55 +00:00
|
|
|
#include <core/loghelper.h>
|
2011-01-04 12:03:40 +00:00
|
|
|
#include <core/avatarmanager.h>
|
2007-10-18 17:40:12 +00:00
|
|
|
#include <gamedata.h>
|
|
|
|
|
#include <game.h>
|
|
|
|
|
#include <playerinterface.h>
|
|
|
|
|
#include <handinterface.h>
|
|
|
|
|
|
|
|
|
|
#include <boost/bind.hpp>
|
|
|
|
|
|
|
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
2014-03-29 16:13:53 +01:00
|
|
|
#ifdef BOOST_ASIO_HAS_STD_CHRONO
|
|
|
|
|
using namespace std::chrono;
|
|
|
|
|
#else
|
|
|
|
|
using namespace boost::chrono;
|
|
|
|
|
#endif
|
|
|
|
|
|
2008-12-06 00:18:36 +00:00
|
|
|
#define SERVER_START_GAME_TIMEOUT_SEC 10
|
2010-09-04 20:08:40 +00:00
|
|
|
#define SERVER_AUTOSTART_GAME_DELAY_SEC 6
|
2008-03-06 20:44:37 +00:00
|
|
|
#define SERVER_GAME_ADMIN_WARNING_REMAINING_SEC 60
|
2008-03-09 23:32:45 +00:00
|
|
|
#define SERVER_GAME_ADMIN_TIMEOUT_SEC 300 // 5 min, MUST be > SERVER_GAME_ADMIN_WARNING_REMAINING_SEC
|
2012-02-04 21:46:54 +00:00
|
|
|
#define SERVER_GAME_AUTOFOLD_TIMEOUT_FACTOR 30
|
2011-12-17 23:34:34 +00:00
|
|
|
#define SERVER_GAME_FORCED_TIMEOUT_FACTOR 60
|
2008-11-16 22:57:11 +00:00
|
|
|
#define SERVER_VOTE_KICK_TIMEOUT_SEC 30
|
2009-06-13 10:52:12 +00:00
|
|
|
#define SERVER_LOOP_DELAY_MSEC 50
|
2013-09-30 23:36:32 +02:00
|
|
|
#define SERVER_MAX_NUM_SPECTATORS_PER_GAME 100
|
2008-03-06 20:44:37 +00:00
|
|
|
|
2007-10-18 17:40:12 +00:00
|
|
|
// Helper functions
|
|
|
|
|
|
2009-05-31 20:14:46 +00:00
|
|
|
static void SendPlayerAction(ServerGame &server, boost::shared_ptr<PlayerInterface> player)
|
2007-10-18 17:40:12 +00:00
|
|
|
{
|
2007-11-10 22:18:31 +00:00
|
|
|
if (!player.get())
|
|
|
|
|
throw ServerException(__FILE__, __LINE__, ERR_NET_NO_CURRENT_PLAYER, 0);
|
2009-08-02 15:11:40 +00:00
|
|
|
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_PlayersActionDoneMessage);
|
|
|
|
|
PlayersActionDoneMessage *netActionDone = packet->GetMsg()->mutable_playersactiondonemessage();
|
2009-08-02 15:11:40 +00:00
|
|
|
|
2012-09-18 15:57:58 +02:00
|
|
|
netActionDone->set_gameid(server.GetId());
|
|
|
|
|
netActionDone->set_gamestate(static_cast<NetGameState>(server.GetCurRound()));
|
|
|
|
|
netActionDone->set_highestset(server.GetGame().getCurrentHand()->getCurrentBeRo()->getHighestSet());
|
|
|
|
|
netActionDone->set_minimumraise(server.GetGame().getCurrentHand()->getCurrentBeRo()->getMinimumRaise());
|
|
|
|
|
netActionDone->set_playeraction(static_cast<NetPlayerAction>(player->getMyAction()));
|
|
|
|
|
netActionDone->set_playerid(player->getMyUniqueID());
|
|
|
|
|
netActionDone->set_playermoney(player->getMyCash());
|
|
|
|
|
netActionDone->set_totalplayerbet(player->getMySet());
|
2013-06-29 16:23:10 +02:00
|
|
|
server.SendToAllPlayers(packet, SessionData::Game | SessionData::Spectating);
|
2007-10-18 17:40:12 +00:00
|
|
|
}
|
|
|
|
|
|
2009-05-31 20:14:46 +00:00
|
|
|
static void SendNewRoundCards(ServerGame &server, Game &curGame, int state)
|
2007-10-18 17:40:12 +00:00
|
|
|
{
|
2009-08-02 15:11:40 +00:00
|
|
|
int cards[5];
|
|
|
|
|
curGame.getCurrentHand()->getBoard()->getMyCards(cards);
|
2007-10-18 17:40:12 +00:00
|
|
|
switch(state) {
|
2011-02-11 20:02:08 +00:00
|
|
|
case GAME_STATE_PREFLOP: {
|
|
|
|
|
// nothing to do
|
|
|
|
|
} break;
|
|
|
|
|
case GAME_STATE_FLOP: {
|
|
|
|
|
// deal flop cards
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_DealFlopCardsMessage);
|
|
|
|
|
DealFlopCardsMessage *netDealFlop = packet->GetMsg()->mutable_dealflopcardsmessage();
|
|
|
|
|
netDealFlop->set_gameid(server.GetId());
|
|
|
|
|
netDealFlop->set_flopcard1(cards[0]);
|
|
|
|
|
netDealFlop->set_flopcard2(cards[1]);
|
|
|
|
|
netDealFlop->set_flopcard3(cards[2]);
|
2013-06-29 16:23:10 +02:00
|
|
|
server.SendToAllPlayers(packet, SessionData::Game | SessionData::Spectating);
|
2011-02-11 20:02:08 +00:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case GAME_STATE_TURN: {
|
|
|
|
|
// deal turn card
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_DealTurnCardMessage);
|
|
|
|
|
DealTurnCardMessage *netDealTurn = packet->GetMsg()->mutable_dealturncardmessage();
|
|
|
|
|
netDealTurn->set_gameid(server.GetId());
|
|
|
|
|
netDealTurn->set_turncard(cards[3]);
|
2013-06-29 16:23:10 +02:00
|
|
|
server.SendToAllPlayers(packet, SessionData::Game | SessionData::Spectating);
|
2011-02-11 20:02:08 +00:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case GAME_STATE_RIVER: {
|
|
|
|
|
// deal river card
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_DealRiverCardMessage);
|
|
|
|
|
DealRiverCardMessage *netDealRiver = packet->GetMsg()->mutable_dealrivercardmessage();
|
|
|
|
|
netDealRiver->set_gameid(server.GetId());
|
|
|
|
|
netDealRiver->set_rivercard(cards[4]);
|
2013-06-29 16:23:10 +02:00
|
|
|
server.SendToAllPlayers(packet, SessionData::Game | SessionData::Spectating);
|
2011-02-11 20:02:08 +00:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default: {
|
|
|
|
|
//
|
|
|
|
|
}
|
2007-10-18 17:40:12 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-31 20:14:46 +00:00
|
|
|
static void PerformPlayerAction(ServerGame &server, boost::shared_ptr<PlayerInterface> player, PlayerAction action, int bet)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
|
|
|
|
Game &curGame = server.GetGame();
|
|
|
|
|
if (!player.get())
|
|
|
|
|
throw ServerException(__FILE__, __LINE__, ERR_NET_NO_CURRENT_PLAYER, 0);
|
|
|
|
|
player->setMyAction(action);
|
|
|
|
|
// Only change the player bet if action is not fold/check
|
2011-02-11 20:02:08 +00:00
|
|
|
if (action != PLAYER_ACTION_FOLD && action != PLAYER_ACTION_CHECK) {
|
2007-10-18 17:40:12 +00:00
|
|
|
|
2009-05-30 22:20:40 +00:00
|
|
|
player->setMySet(bet);
|
|
|
|
|
|
2010-09-05 00:15:25 +00:00
|
|
|
// update minimumRaise and lastActionPlayer
|
2009-05-30 22:20:40 +00:00
|
|
|
switch(action) {
|
2011-02-11 20:02:08 +00:00
|
|
|
case PLAYER_ACTION_BET: {
|
|
|
|
|
curGame.getCurrentHand()->getCurrentBeRo()->setMinimumRaise(bet);
|
2011-10-26 22:29:47 +00:00
|
|
|
curGame.getCurrentHand()->setLastActionPlayerID(player->getMyUniqueID());
|
2011-02-11 20:02:08 +00:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PLAYER_ACTION_RAISE: {
|
|
|
|
|
curGame.getCurrentHand()->getCurrentBeRo()->setMinimumRaise(player->getMySet() - curGame.getCurrentHand()->getCurrentBeRo()->getHighestSet());
|
2011-10-26 22:29:47 +00:00
|
|
|
curGame.getCurrentHand()->setLastActionPlayerID(player->getMyUniqueID());
|
2011-02-11 20:02:08 +00:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PLAYER_ACTION_ALLIN: {
|
|
|
|
|
if(player->getMySet() - curGame.getCurrentHand()->getCurrentBeRo()->getHighestSet() > curGame.getCurrentHand()->getCurrentBeRo()->getMinimumRaise()) {
|
2009-05-30 22:20:40 +00:00
|
|
|
curGame.getCurrentHand()->getCurrentBeRo()->setMinimumRaise(player->getMySet() - curGame.getCurrentHand()->getCurrentBeRo()->getHighestSet());
|
|
|
|
|
}
|
2011-02-11 20:02:08 +00:00
|
|
|
if(player->getMySet() - curGame.getCurrentHand()->getCurrentBeRo()->getHighestSet() > 0) {
|
2011-10-26 22:29:47 +00:00
|
|
|
curGame.getCurrentHand()->setLastActionPlayerID(player->getMyUniqueID());
|
2011-02-11 20:02:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default: {
|
|
|
|
|
}
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// update highestSet
|
|
|
|
|
if (player->getMySet() > curGame.getCurrentHand()->getCurrentBeRo()->getHighestSet())
|
|
|
|
|
curGame.getCurrentHand()->getCurrentBeRo()->setHighestSet(player->getMySet());
|
|
|
|
|
// Update total sets.
|
|
|
|
|
curGame.getCurrentHand()->getBoard()->collectSets();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SendPlayerAction(server, player);
|
2007-10-18 17:40:12 +00:00
|
|
|
}
|
|
|
|
|
|
2010-07-17 21:11:12 +00:00
|
|
|
static void
|
2012-09-18 15:57:58 +02:00
|
|
|
SetPlayerResult(PlayerResult &playerResult, boost::shared_ptr<PlayerInterface> tmpPlayer, GameState roundBeforePostRiver)
|
2010-07-17 21:11:12 +00:00
|
|
|
{
|
2012-09-18 15:57:58 +02:00
|
|
|
playerResult.set_playerid(tmpPlayer->getMyUniqueID());
|
2010-07-17 21:11:12 +00:00
|
|
|
int tmpCards[2];
|
|
|
|
|
int bestHandPos[5];
|
2014-05-26 12:41:21 +02:00
|
|
|
tmpPlayer->getMyHoleCards(tmpCards);
|
2012-09-18 15:57:58 +02:00
|
|
|
playerResult.set_resultcard1(tmpCards[0]);
|
|
|
|
|
playerResult.set_resultcard2(tmpCards[1]);
|
2010-07-17 21:11:12 +00:00
|
|
|
tmpPlayer->getMyBestHandPosition(bestHandPos);
|
2011-02-11 20:02:08 +00:00
|
|
|
for (int num = 0; num < 5; num++) {
|
2012-09-18 15:57:58 +02:00
|
|
|
playerResult.add_besthandposition(bestHandPos[num]);
|
2010-07-17 21:11:12 +00:00
|
|
|
}
|
|
|
|
|
|
2011-11-13 16:28:04 +00:00
|
|
|
if (roundBeforePostRiver == GAME_STATE_RIVER) {
|
2012-09-18 15:57:58 +02:00
|
|
|
playerResult.set_cardsvalue(tmpPlayer->getMyCardsValueInt());
|
2011-11-13 16:28:04 +00:00
|
|
|
}
|
2012-09-18 15:57:58 +02:00
|
|
|
playerResult.set_moneywon(tmpPlayer->getLastMoneyWon());
|
|
|
|
|
playerResult.set_playermoney(tmpPlayer->getMyCash());
|
2010-07-17 21:11:12 +00:00
|
|
|
}
|
|
|
|
|
|
2007-10-18 17:40:12 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
2009-05-30 22:20:40 +00:00
|
|
|
ServerGameState::~ServerGameState()
|
2007-10-18 17:40:12 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-30 22:20:40 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
AbstractServerGameStateReceiving::~AbstractServerGameStateReceiving()
|
2007-10-18 17:40:12 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-20 18:41:03 +00:00
|
|
|
void
|
2011-03-10 20:55:46 +00:00
|
|
|
AbstractServerGameStateReceiving::ProcessPacket(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
2011-12-11 19:37:51 +00:00
|
|
|
if (packet->IsClientActivity()) {
|
2011-03-10 20:55:46 +00:00
|
|
|
session->ResetActivityTimer();
|
2011-12-11 19:37:51 +00:00
|
|
|
}
|
2012-09-18 15:57:58 +02:00
|
|
|
if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_PlayerInfoRequestMessage) {
|
2009-05-30 22:20:40 +00:00
|
|
|
// Delegate to Lobby.
|
2012-09-18 15:57:58 +02:00
|
|
|
server->GetLobbyThread().HandleGameRetrievePlayerInfo(session, packet->GetMsg()->playerinforequestmessage());
|
|
|
|
|
} else if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_AvatarRequestMessage) {
|
2009-05-30 22:20:40 +00:00
|
|
|
// Delegate to Lobby.
|
2012-09-18 15:57:58 +02:00
|
|
|
server->GetLobbyThread().HandleGameRetrieveAvatar(session, packet->GetMsg()->avatarrequestmessage());
|
|
|
|
|
} else if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_LeaveGameRequestMessage) {
|
2009-06-12 15:48:34 +00:00
|
|
|
server->MoveSessionToLobby(session, NTF_NET_REMOVED_ON_REQUEST);
|
2012-09-18 15:57:58 +02:00
|
|
|
} else if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_KickPlayerRequestMessage) {
|
2009-05-30 22:20:40 +00:00
|
|
|
// Only admins are allowed to kick, and only in the lobby.
|
|
|
|
|
// After leaving the lobby, a vote needs to be initiated to kick.
|
2012-09-18 15:57:58 +02:00
|
|
|
const KickPlayerRequestMessage &netKickRequest = packet->GetMsg()->kickplayerrequestmessage();
|
2011-03-10 20:55:46 +00:00
|
|
|
if (session->GetPlayerData()->IsGameAdmin() && !server->IsRunning()
|
2012-09-18 15:57:58 +02:00
|
|
|
&& netKickRequest.gameid() == server->GetId() && server->GetGameData().gameType != GAME_TYPE_RANKING) {
|
|
|
|
|
server->KickPlayer(netKickRequest.playerid());
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
2012-09-18 15:57:58 +02:00
|
|
|
} else if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_AskKickPlayerMessage) {
|
2011-03-10 20:55:46 +00:00
|
|
|
if (server->GetGameData().gameType != GAME_TYPE_RANKING) {
|
2012-09-18 15:57:58 +02:00
|
|
|
const AskKickPlayerMessage &netAskKick = packet->GetMsg()->askkickplayermessage();
|
|
|
|
|
server->InternalAskVoteKick(session, netAskKick.playerid(), SERVER_VOTE_KICK_TIMEOUT_SEC);
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
2012-09-18 15:57:58 +02:00
|
|
|
} else if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_VoteKickRequestMessage) {
|
|
|
|
|
const VoteKickRequestMessage &netVoteKick = packet->GetMsg()->votekickrequestmessage();
|
|
|
|
|
server->InternalVoteKick(session, netVoteKick.petitionid(), netVoteKick.votekick() ? KICK_VOTE_IN_FAVOUR : KICK_VOTE_AGAINST);
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
// Chat text is always allowed.
|
2012-09-18 15:57:58 +02:00
|
|
|
else if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_ChatRequestMessage) {
|
2011-02-18 13:39:22 +00:00
|
|
|
bool chatSent = false;
|
2012-09-18 15:57:58 +02:00
|
|
|
const ChatRequestMessage &netChatRequest = packet->GetMsg()->chatrequestmessage();
|
2010-03-28 12:54:11 +00:00
|
|
|
// Only forward if this player is known and not a guest.
|
2011-03-10 20:55:46 +00:00
|
|
|
if (session->GetPlayerData()->GetRights() != PLAYER_RIGHTS_GUEST) {
|
2009-05-30 22:20:40 +00:00
|
|
|
// Forward chat text to all players.
|
|
|
|
|
// TODO: Some limitation needed.
|
2012-09-18 15:57:58 +02:00
|
|
|
if (!netChatRequest.has_targetgameid()) {
|
2011-02-18 13:39:22 +00:00
|
|
|
if (!server->IsRunning()) {
|
2012-09-18 15:57:58 +02:00
|
|
|
server->GetLobbyThread().HandleChatRequest(session, netChatRequest);
|
2011-02-18 13:39:22 +00:00
|
|
|
chatSent = true;
|
|
|
|
|
}
|
2012-09-18 15:57:58 +02:00
|
|
|
} else {
|
2012-01-08 13:02:29 +00:00
|
|
|
boost::shared_ptr<PlayerInterface> tmpPlayer (server->GetPlayerInterfaceFromGame(session->GetPlayerData()->GetUniqueId()));
|
2012-01-08 17:10:21 +00:00
|
|
|
// If we did not find the player, then the game did not start yet. Allow chat for now.
|
|
|
|
|
// Otherwise, check whether the player is muted.
|
|
|
|
|
if (!tmpPlayer || !tmpPlayer->isMuted()) {
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_ChatMessage);
|
|
|
|
|
ChatMessage *netChat = packet->GetMsg()->mutable_chatmessage();
|
|
|
|
|
netChat->set_gameid(server->GetId());
|
|
|
|
|
netChat->set_playerid(session->GetPlayerData()->GetUniqueId());
|
|
|
|
|
netChat->set_chattype(ChatMessage::chatTypeGame);
|
|
|
|
|
netChat->set_chattext(netChatRequest.chattext());
|
2013-09-01 18:09:15 +02:00
|
|
|
server->SendToAllPlayers(packet, SessionData::Game | SessionData::Spectating | SessionData::SpectatorWaiting);
|
2012-01-08 13:02:29 +00:00
|
|
|
chatSent = true;
|
2011-01-30 18:28:44 +00:00
|
|
|
|
2012-01-08 16:56:51 +00:00
|
|
|
// Send the message to the chat cleaner bot for ranking games.
|
|
|
|
|
//if (server->GetGameData().gameType == GAME_TYPE_RANKING)
|
|
|
|
|
//{
|
|
|
|
|
server->GetLobbyThread().GetChatCleaner().HandleGameChatText(
|
|
|
|
|
server->GetId(),
|
|
|
|
|
session->GetPlayerData()->GetUniqueId(),
|
|
|
|
|
session->GetPlayerData()->GetName(),
|
2012-09-18 15:57:58 +02:00
|
|
|
netChatRequest.chattext());
|
2012-01-08 16:56:51 +00:00
|
|
|
//}
|
|
|
|
|
}
|
2009-08-15 14:51:21 +00:00
|
|
|
}
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
2011-02-18 13:39:22 +00:00
|
|
|
// Reject chat otherwise.
|
|
|
|
|
if (!chatSent) {
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_ChatRejectMessage);
|
|
|
|
|
ChatRejectMessage *netReject = packet->GetMsg()->mutable_chatrejectmessage();
|
|
|
|
|
netReject->set_chattext(netChatRequest.chattext());
|
2011-03-10 20:55:46 +00:00
|
|
|
server->GetLobbyThread().GetSender().Send(session, packet);
|
2011-02-18 13:39:22 +00:00
|
|
|
}
|
2012-09-18 15:57:58 +02:00
|
|
|
} else if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_SubscriptionRequestMessage) {
|
|
|
|
|
const SubscriptionRequestMessage &netSubscription = packet->GetMsg()->subscriptionrequestmessage();
|
|
|
|
|
if (netSubscription.subscriptionaction() == SubscriptionRequestMessage::resubscribeGameList) {
|
2011-03-10 20:55:46 +00:00
|
|
|
if (!session->WantsLobbyMsg())
|
2009-08-02 15:11:40 +00:00
|
|
|
server->GetLobbyThread().ResubscribeLobbyMsg(session);
|
2011-02-11 20:02:08 +00:00
|
|
|
} else
|
2011-03-10 20:55:46 +00:00
|
|
|
session->ResetWantsLobbyMsg();
|
2012-09-18 15:57:58 +02:00
|
|
|
} else if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_ReportAvatarMessage) {
|
|
|
|
|
const ReportAvatarMessage &netReport = packet->GetMsg()->reportavatarmessage();
|
|
|
|
|
boost::shared_ptr<PlayerData> tmpPlayer = server->GetPlayerDataByUniqueId(netReport.reportedplayerid());
|
2010-12-24 16:46:49 +00:00
|
|
|
MD5Buf tmpMD5;
|
2012-09-18 15:57:58 +02:00
|
|
|
memcpy(tmpMD5.GetData(), netReport.reportedavatarhash().data(), MD5_DATA_SIZE);
|
2011-02-11 20:02:08 +00:00
|
|
|
if (tmpPlayer && tmpPlayer->GetDBId() && !tmpMD5.IsZero() && tmpPlayer->GetAvatarMD5() == tmpMD5) {
|
|
|
|
|
if (!server->IsAvatarReported(tmpPlayer->GetUniqueId())) {
|
2010-12-25 21:54:26 +00:00
|
|
|
// Temporarily note that this avatar was reported.
|
|
|
|
|
// This prevents spamming of the avatar report.
|
|
|
|
|
server->AddReportedAvatar(tmpPlayer->GetUniqueId());
|
2011-03-10 20:55:46 +00:00
|
|
|
DB_id myDBid = session->GetPlayerData()->GetDBId();
|
2010-12-25 21:54:26 +00:00
|
|
|
// Do not use the "game" database object, but the global one.
|
|
|
|
|
// The entry should be created even if we are not running a
|
|
|
|
|
// ranking game.
|
2011-01-04 12:03:40 +00:00
|
|
|
|
|
|
|
|
string tmpAvatarType;
|
|
|
|
|
tmpAvatarType = AvatarManager::GetAvatarFileExtension(AvatarManager::GetAvatarFileType(tmpPlayer->GetAvatarFile()));
|
|
|
|
|
if (!tmpAvatarType.empty())
|
|
|
|
|
tmpAvatarType.erase(0, 1); // Only store extension without the "."
|
|
|
|
|
|
2010-12-25 21:54:26 +00:00
|
|
|
server->GetLobbyThread().GetDatabase()->AsyncReportAvatar(
|
2011-03-10 20:55:46 +00:00
|
|
|
session->GetPlayerData()->GetUniqueId(),
|
2011-02-11 20:02:08 +00:00
|
|
|
tmpPlayer->GetUniqueId(),
|
|
|
|
|
tmpPlayer->GetDBId(),
|
|
|
|
|
tmpPlayer->GetAvatarMD5().ToString(),
|
|
|
|
|
tmpAvatarType,
|
|
|
|
|
myDBid != 0 ? &myDBid : NULL
|
2010-12-25 21:54:26 +00:00
|
|
|
);
|
2011-02-11 20:02:08 +00:00
|
|
|
} else {
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_ReportAvatarAckMessage);
|
|
|
|
|
ReportAvatarAckMessage *netReportAck = packet->GetMsg()->mutable_reportavatarackmessage();
|
|
|
|
|
netReportAck->set_reportedplayerid(netReport.reportedplayerid());
|
|
|
|
|
netReportAck->set_reportavatarresult(ReportAvatarAckMessage::avatarReportDuplicate);
|
2011-03-10 20:55:46 +00:00
|
|
|
server->GetLobbyThread().GetSender().Send(session, packet);
|
2010-12-25 21:54:26 +00:00
|
|
|
}
|
2011-02-11 20:02:08 +00:00
|
|
|
} else {
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_ReportAvatarAckMessage);
|
|
|
|
|
ReportAvatarAckMessage *netReportAck = packet->GetMsg()->mutable_reportavatarackmessage();
|
|
|
|
|
netReportAck->set_reportedplayerid(netReport.reportedplayerid());
|
|
|
|
|
netReportAck->set_reportavatarresult(ReportAvatarAckMessage::avatarReportInvalid);
|
2011-03-10 20:55:46 +00:00
|
|
|
server->GetLobbyThread().GetSender().Send(session, packet);
|
2010-12-24 16:46:49 +00:00
|
|
|
}
|
2012-09-18 15:57:58 +02:00
|
|
|
} else if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_ReportGameMessage) {
|
2012-04-08 14:36:14 +00:00
|
|
|
// Delegate to Lobby.
|
2012-09-18 15:57:58 +02:00
|
|
|
server->GetLobbyThread().HandleGameReportGame(session, packet->GetMsg()->reportgamemessage());
|
|
|
|
|
} else if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_JoinExistingGameMessage) {
|
2012-06-08 22:07:55 +02:00
|
|
|
// Ignore join game requests in this state (may be multiple clicks from the lobby).
|
2011-02-11 20:02:08 +00:00
|
|
|
} else {
|
2009-05-30 22:20:40 +00:00
|
|
|
// Packet processing in subclass.
|
2009-06-20 18:41:03 +00:00
|
|
|
InternalProcessPacket(server, session, packet);
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-11 20:38:18 +00:00
|
|
|
boost::shared_ptr<NetPacket>
|
|
|
|
|
AbstractServerGameStateReceiving::CreateNetPacketPlayerJoined(unsigned gameId, const PlayerData &playerData)
|
|
|
|
|
{
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_GamePlayerJoinedMessage);
|
|
|
|
|
GamePlayerJoinedMessage *netGamePlayer = packet->GetMsg()->mutable_gameplayerjoinedmessage();
|
|
|
|
|
netGamePlayer->set_gameid(gameId);
|
|
|
|
|
netGamePlayer->set_playerid(playerData.GetUniqueId());
|
|
|
|
|
netGamePlayer->set_isgameadmin(playerData.IsGameAdmin());
|
2011-09-11 20:38:18 +00:00
|
|
|
return packet;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-23 09:13:04 +00:00
|
|
|
boost::shared_ptr<NetPacket>
|
2013-06-16 10:43:13 +02:00
|
|
|
AbstractServerGameStateReceiving::CreateNetPacketSpectatorJoined(unsigned gameId, const PlayerData &playerData)
|
|
|
|
|
{
|
|
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_GameSpectatorJoinedMessage);
|
|
|
|
|
GameSpectatorJoinedMessage *netGameSpectator = packet->GetMsg()->mutable_gamespectatorjoinedmessage();
|
|
|
|
|
netGameSpectator->set_gameid(gameId);
|
|
|
|
|
netGameSpectator->set_playerid(playerData.GetUniqueId());
|
|
|
|
|
return packet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boost::shared_ptr<NetPacket>
|
|
|
|
|
AbstractServerGameStateReceiving::CreateNetPacketJoinGameAck(const ServerGame &server, const PlayerData &playerData, bool spectateOnly)
|
2011-10-23 09:13:04 +00:00
|
|
|
{
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_JoinGameAckMessage);
|
|
|
|
|
JoinGameAckMessage *netJoinReply = packet->GetMsg()->mutable_joingameackmessage();
|
|
|
|
|
netJoinReply->set_gameid(server.GetId());
|
|
|
|
|
netJoinReply->set_areyougameadmin(playerData.IsGameAdmin());
|
2013-06-16 10:43:13 +02:00
|
|
|
netJoinReply->set_spectateonly(spectateOnly);
|
2011-10-23 09:13:04 +00:00
|
|
|
|
2012-09-18 15:57:58 +02:00
|
|
|
NetGameInfo *gameInfo = netJoinReply->mutable_gameinfo();
|
|
|
|
|
NetPacket::SetGameData(server.GetGameData(), *gameInfo);
|
|
|
|
|
gameInfo->set_gamename(server.GetName());
|
2011-10-23 09:13:04 +00:00
|
|
|
return packet;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-29 16:23:10 +02:00
|
|
|
boost::shared_ptr<NetPacket>
|
|
|
|
|
AbstractServerGameStateReceiving::CreateNetPacketHandStart(const ServerGame &server)
|
|
|
|
|
{
|
|
|
|
|
const Game &curGame = server.GetGame();
|
|
|
|
|
|
|
|
|
|
boost::shared_ptr<NetPacket> notifyCards(new NetPacket);
|
|
|
|
|
notifyCards->GetMsg()->set_messagetype(PokerTHMessage::Type_HandStartMessage);
|
|
|
|
|
HandStartMessage *netHandStart = notifyCards->GetMsg()->mutable_handstartmessage();
|
|
|
|
|
netHandStart->set_gameid(server.GetId());
|
|
|
|
|
|
|
|
|
|
PlayerListIterator player_i = curGame.getSeatsList()->begin();
|
|
|
|
|
PlayerListIterator player_end = curGame.getSeatsList()->end();
|
|
|
|
|
int playerCounter = 0;
|
|
|
|
|
while (player_i != player_end && playerCounter < server.GetStartData().numberOfPlayers) {
|
|
|
|
|
NetPlayerState seatState;
|
|
|
|
|
if (!(*player_i)->getMyActiveStatus()) {
|
|
|
|
|
seatState = netPlayerStateNoMoney;
|
|
|
|
|
} else if (!(*player_i)->isSessionActive()) {
|
|
|
|
|
seatState = netPlayerStateSessionInactive;
|
|
|
|
|
} else {
|
|
|
|
|
seatState = netPlayerStateNormal;
|
|
|
|
|
}
|
|
|
|
|
netHandStart->add_seatstates(seatState);
|
|
|
|
|
++player_i;
|
|
|
|
|
++playerCounter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
netHandStart->set_smallblind(curGame.getCurrentHand()->getSmallBlind());
|
2013-09-24 23:40:10 +02:00
|
|
|
netHandStart->set_dealerplayerid(curGame.getCurrentHand()->getDealerPosition());
|
2013-06-29 16:23:10 +02:00
|
|
|
return notifyCards;
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-23 09:13:04 +00:00
|
|
|
void
|
2013-06-16 10:43:13 +02:00
|
|
|
AbstractServerGameStateReceiving::AcceptNewSession(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session, bool spectateOnly)
|
2011-10-23 09:13:04 +00:00
|
|
|
{
|
|
|
|
|
// Set game admin, if applicable.
|
|
|
|
|
session->GetPlayerData()->SetGameAdmin(session->GetPlayerData()->GetUniqueId() == server->GetAdminPlayerId());
|
|
|
|
|
|
|
|
|
|
// Send ack to client.
|
2013-06-16 10:43:13 +02:00
|
|
|
server->GetLobbyThread().GetSender().Send(session, CreateNetPacketJoinGameAck(*server, *session->GetPlayerData(), spectateOnly));
|
2011-10-23 09:13:04 +00:00
|
|
|
|
|
|
|
|
// Send notifications for connected players to client.
|
|
|
|
|
PlayerDataList tmpPlayerList(server->GetFullPlayerDataList());
|
|
|
|
|
PlayerDataList::iterator player_i = tmpPlayerList.begin();
|
|
|
|
|
PlayerDataList::iterator player_end = tmpPlayerList.end();
|
|
|
|
|
while (player_i != player_end) {
|
|
|
|
|
server->GetLobbyThread().GetSender().Send(session, CreateNetPacketPlayerJoined(server->GetId(), *(*player_i)));
|
|
|
|
|
++player_i;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-28 18:58:43 +02:00
|
|
|
// Send notifications for connected spectators to client.
|
|
|
|
|
PlayerDataList tmpSpectatorList(server->GetSessionManager().GetSpectatorDataList());
|
|
|
|
|
PlayerDataList::iterator spectator_i = tmpSpectatorList.begin();
|
|
|
|
|
PlayerDataList::iterator spectator_end = tmpSpectatorList.end();
|
|
|
|
|
while (spectator_i != spectator_end) {
|
|
|
|
|
server->GetLobbyThread().GetSender().Send(session, CreateNetPacketSpectatorJoined(server->GetId(), *(*spectator_i)));
|
|
|
|
|
++spectator_i;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-16 10:43:13 +02:00
|
|
|
// Send "Player Joined"/"Spectator Joined" to other fully connected clients.
|
|
|
|
|
if (spectateOnly) {
|
2013-09-01 18:09:15 +02:00
|
|
|
server->SendToAllPlayers(CreateNetPacketSpectatorJoined(server->GetId(), *session->GetPlayerData()), SessionData::Game | SessionData::Spectating | SessionData::SpectatorWaiting);
|
2013-06-16 10:43:13 +02:00
|
|
|
} else {
|
2013-09-01 18:09:15 +02:00
|
|
|
server->SendToAllPlayers(CreateNetPacketPlayerJoined(server->GetId(), *session->GetPlayerData()), SessionData::Game | SessionData::Spectating | SessionData::SpectatorWaiting);
|
2013-06-16 10:43:13 +02:00
|
|
|
}
|
2011-10-23 09:13:04 +00:00
|
|
|
|
|
|
|
|
// Accept session.
|
|
|
|
|
server->GetSessionManager().AddSession(session);
|
|
|
|
|
|
|
|
|
|
// Notify lobby.
|
2013-06-16 10:43:13 +02:00
|
|
|
if (spectateOnly) {
|
|
|
|
|
server->GetLobbyThread().NotifySpectatorJoinedGame(server->GetId(), session->GetPlayerData()->GetUniqueId());
|
|
|
|
|
} else {
|
|
|
|
|
server->GetLobbyThread().NotifyPlayerJoinedGame(server->GetId(), session->GetPlayerData()->GetUniqueId());
|
|
|
|
|
}
|
2011-10-23 09:13:04 +00:00
|
|
|
}
|
|
|
|
|
|
2009-05-30 22:20:40 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
2009-05-31 13:17:02 +00:00
|
|
|
ServerGameStateInit ServerGameStateInit::s_state;
|
|
|
|
|
|
|
|
|
|
ServerGameStateInit &
|
|
|
|
|
ServerGameStateInit::Instance()
|
|
|
|
|
{
|
|
|
|
|
return s_state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ServerGameStateInit::ServerGameStateInit()
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ServerGameStateInit::~ServerGameStateInit()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateInit::Enter(boost::shared_ptr<ServerGame> server)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
2009-05-31 13:17:02 +00:00
|
|
|
RegisterAdminTimer(server);
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateInit::Exit(boost::shared_ptr<ServerGame> server)
|
2009-05-31 13:17:02 +00:00
|
|
|
{
|
|
|
|
|
UnregisterAdminTimer(server);
|
2010-09-04 20:08:40 +00:00
|
|
|
UnregisterAutoStartTimer(server);
|
2009-05-31 13:17:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateInit::NotifyGameAdminChanged(boost::shared_ptr<ServerGame> server)
|
2009-05-31 13:17:02 +00:00
|
|
|
{
|
|
|
|
|
UnregisterAdminTimer(server);
|
|
|
|
|
RegisterAdminTimer(server);
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-04 20:08:40 +00:00
|
|
|
void
|
|
|
|
|
ServerGameStateInit::NotifySessionRemoved(boost::shared_ptr<ServerGame> server)
|
|
|
|
|
{
|
|
|
|
|
UnregisterAutoStartTimer(server);
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-31 13:17:02 +00:00
|
|
|
void
|
2013-06-16 10:43:13 +02:00
|
|
|
ServerGameStateInit::HandleNewPlayer(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
2011-03-10 20:55:46 +00:00
|
|
|
if (session && session->GetPlayerData()) {
|
2010-03-30 17:10:37 +00:00
|
|
|
const GameData &tmpGameData = server->GetGameData();
|
2009-05-30 22:20:40 +00:00
|
|
|
// Check the number of players.
|
2011-04-10 10:04:42 +00:00
|
|
|
if (server->GetCurNumberOfPlayers() >= tmpGameData.maxNumberOfPlayers) {
|
2009-06-12 15:48:34 +00:00
|
|
|
server->MoveSessionToLobby(session, NTF_NET_REMOVED_GAME_FULL);
|
2011-02-11 20:02:08 +00:00
|
|
|
} else {
|
2009-05-30 22:20:40 +00:00
|
|
|
|
2013-06-16 10:43:13 +02:00
|
|
|
AcceptNewSession(server, session, false);
|
2010-04-17 12:50:38 +00:00
|
|
|
|
2011-04-10 10:04:42 +00:00
|
|
|
if (server->GetCurNumberOfPlayers() == tmpGameData.maxNumberOfPlayers) {
|
2010-04-17 12:50:38 +00:00
|
|
|
// Automatically start the game if it is full.
|
2010-09-04 20:08:40 +00:00
|
|
|
RegisterAutoStartTimer(server);
|
2010-04-17 12:50:38 +00:00
|
|
|
}
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-16 10:43:13 +02:00
|
|
|
void
|
|
|
|
|
ServerGameStateInit::HandleNewSpectator(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
|
|
|
|
|
{
|
2013-06-29 16:23:10 +02:00
|
|
|
if (session && session->GetPlayerData()) {
|
2013-09-30 23:36:32 +02:00
|
|
|
if (server->GetSpectatorIdList().size() >= SERVER_MAX_NUM_SPECTATORS_PER_GAME) {
|
|
|
|
|
server->MoveSessionToLobby(session, NTF_NET_REMOVED_GAME_FULL);
|
|
|
|
|
} else {
|
|
|
|
|
AcceptNewSession(server, session, true);
|
|
|
|
|
}
|
2013-06-29 16:23:10 +02:00
|
|
|
}
|
2013-06-16 10:43:13 +02:00
|
|
|
}
|
|
|
|
|
|
2009-05-30 22:20:40 +00:00
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateInit::RegisterAdminTimer(boost::shared_ptr<ServerGame> server)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
2012-01-07 20:16:57 +00:00
|
|
|
// No admin timeout in LAN or ranking games.
|
2014-07-11 18:15:40 +02:00
|
|
|
if (server->GetLobbyThread().GetServerMode() != SERVER_MODE_LAN && server->GetLobbyThread().GetServerMode() != SERVER_MODE_LAN_LOCAL && server->GetGameData().gameType != GAME_TYPE_RANKING) {
|
2010-09-04 23:00:39 +00:00
|
|
|
server->GetStateTimer1().expires_from_now(
|
2014-03-29 16:13:53 +01:00
|
|
|
seconds(SERVER_GAME_ADMIN_TIMEOUT_SEC - SERVER_GAME_ADMIN_WARNING_REMAINING_SEC));
|
2010-09-04 23:00:39 +00:00
|
|
|
server->GetStateTimer1().async_wait(
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerGameStateInit::TimerAdminWarning, this, boost::asio::placeholders::error, server));
|
|
|
|
|
}
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateInit::UnregisterAdminTimer(boost::shared_ptr<ServerGame> server)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().cancel();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerGameStateInit::RegisterAutoStartTimer(boost::shared_ptr<ServerGame> server)
|
|
|
|
|
{
|
2010-09-04 23:00:39 +00:00
|
|
|
// No autostart in LAN games.
|
2014-07-11 18:15:40 +02:00
|
|
|
if (server->GetLobbyThread().GetServerMode() != SERVER_MODE_LAN && server->GetLobbyThread().GetServerMode() != SERVER_MODE_LAN_LOCAL) {
|
2010-09-04 23:00:39 +00:00
|
|
|
server->GetStateTimer2().expires_from_now(
|
2014-03-29 16:13:53 +01:00
|
|
|
seconds(SERVER_AUTOSTART_GAME_DELAY_SEC));
|
2010-09-04 23:00:39 +00:00
|
|
|
server->GetStateTimer2().async_wait(
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerGameStateInit::TimerAutoStart, this, boost::asio::placeholders::error, server));
|
|
|
|
|
}
|
2010-09-04 20:08:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerGameStateInit::UnregisterAutoStartTimer(boost::shared_ptr<ServerGame> server)
|
|
|
|
|
{
|
|
|
|
|
server->GetStateTimer2().cancel();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerGameStateInit::TimerAutoStart(const boost::system::error_code &ec, boost::shared_ptr<ServerGame> server)
|
|
|
|
|
{
|
2011-02-11 20:02:08 +00:00
|
|
|
if (!ec && &server->GetState() == this) {
|
2010-09-04 20:08:40 +00:00
|
|
|
SendStartEvent(*server, false);
|
|
|
|
|
}
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateInit::TimerAdminWarning(const boost::system::error_code &ec, boost::shared_ptr<ServerGame> server)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
2011-02-11 20:02:08 +00:00
|
|
|
if (!ec && &server->GetState() == this) {
|
2009-06-12 15:48:34 +00:00
|
|
|
// Find game admin.
|
2011-03-10 20:55:46 +00:00
|
|
|
boost::shared_ptr<SessionData> session = server->GetSessionManager().GetSessionByUniquePlayerId(server->GetAdminPlayerId());
|
|
|
|
|
if (session) {
|
2009-06-12 15:48:34 +00:00
|
|
|
// Send him a warning.
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_TimeoutWarningMessage);
|
|
|
|
|
TimeoutWarningMessage *netWarning = packet->GetMsg()->mutable_timeoutwarningmessage();
|
|
|
|
|
netWarning->set_timeoutreason(TimeoutWarningMessage::timeoutInactiveGame);
|
|
|
|
|
netWarning->set_remainingseconds(SERVER_GAME_ADMIN_WARNING_REMAINING_SEC);
|
2011-03-10 20:55:46 +00:00
|
|
|
server->GetLobbyThread().GetSender().Send(session, packet);
|
2009-06-12 15:48:34 +00:00
|
|
|
}
|
|
|
|
|
// Start timeout timer.
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().expires_from_now(
|
2014-03-29 16:13:53 +01:00
|
|
|
seconds(SERVER_GAME_ADMIN_WARNING_REMAINING_SEC));
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().async_wait(
|
2009-06-12 15:48:34 +00:00
|
|
|
boost::bind(
|
|
|
|
|
&ServerGameStateInit::TimerAdminTimeout, this, boost::asio::placeholders::error, server));
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateInit::TimerAdminTimeout(const boost::system::error_code &ec, boost::shared_ptr<ServerGame> server)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
2011-02-11 20:02:08 +00:00
|
|
|
if (!ec && &server->GetState() == this) {
|
2009-06-12 15:48:34 +00:00
|
|
|
// Find game admin.
|
2011-03-10 20:55:46 +00:00
|
|
|
boost::shared_ptr<SessionData> session = server->GetSessionManager().GetSessionByUniquePlayerId(server->GetAdminPlayerId());
|
|
|
|
|
if (session) {
|
2009-06-12 15:48:34 +00:00
|
|
|
// Remove him from the game.
|
|
|
|
|
server->MoveSessionToLobby(session, NTF_NET_REMOVED_TIMEOUT);
|
|
|
|
|
}
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-04-17 12:50:38 +00:00
|
|
|
void
|
|
|
|
|
ServerGameStateInit::SendStartEvent(ServerGame &server, bool fillWithComputerPlayers)
|
|
|
|
|
{
|
2011-02-11 20:02:08 +00:00
|
|
|
if (fillWithComputerPlayers) {
|
2010-04-17 12:50:38 +00:00
|
|
|
int remainingSlots = server.GetGameData().maxNumberOfPlayers - server.GetCurNumberOfPlayers();
|
2011-02-11 20:02:08 +00:00
|
|
|
for (int i = 1; i <= remainingSlots; i++) {
|
2010-04-17 12:50:38 +00:00
|
|
|
boost::shared_ptr<PlayerData> tmpPlayerData(
|
|
|
|
|
new PlayerData(server.GetLobbyThread().GetNextUniquePlayerId(), 0, PLAYER_TYPE_COMPUTER, PLAYER_RIGHTS_NORMAL, false));
|
|
|
|
|
|
|
|
|
|
ostringstream name;
|
|
|
|
|
name << SERVER_COMPUTER_PLAYER_NAME << i;
|
|
|
|
|
tmpPlayerData->SetName(name.str());
|
|
|
|
|
server.AddComputerPlayer(tmpPlayerData);
|
|
|
|
|
|
|
|
|
|
// Send "Player Joined" to other fully connected clients.
|
2013-09-01 18:09:15 +02:00
|
|
|
server.SendToAllPlayers(CreateNetPacketPlayerJoined(server.GetId(), *tmpPlayerData), SessionData::Game | SessionData::Spectating | SessionData::SpectatorWaiting);
|
2010-04-17 12:50:38 +00:00
|
|
|
|
|
|
|
|
// Notify lobby.
|
|
|
|
|
server.GetLobbyThread().NotifyPlayerJoinedGame(server.GetId(), tmpPlayerData->GetUniqueId());
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_StartEventMessage);
|
|
|
|
|
StartEventMessage *netStartEvent = packet->GetMsg()->mutable_starteventmessage();
|
|
|
|
|
netStartEvent->set_starteventtype(StartEventMessage::startEvent);
|
|
|
|
|
netStartEvent->set_gameid(server.GetId());
|
|
|
|
|
netStartEvent->set_fillwithcomputerplayers(fillWithComputerPlayers);
|
2010-04-17 12:50:38 +00:00
|
|
|
|
|
|
|
|
// Wait for all players to confirm start of game.
|
|
|
|
|
server.SendToAllPlayers(packet, SessionData::Game);
|
2010-11-13 12:37:28 +00:00
|
|
|
// Notify lobby that this game is running.
|
|
|
|
|
server.GetLobbyThread().NotifyStartingGame(server.GetId());
|
2010-04-17 12:50:38 +00:00
|
|
|
|
|
|
|
|
server.SetState(ServerGameStateStartGame::Instance());
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-20 18:41:03 +00:00
|
|
|
void
|
2011-03-10 20:55:46 +00:00
|
|
|
ServerGameStateInit::InternalProcessPacket(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet)
|
2007-10-18 17:40:12 +00:00
|
|
|
{
|
2012-09-18 15:57:58 +02:00
|
|
|
if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_StartEventMessage) {
|
|
|
|
|
const StartEventMessage &netStartEvent = packet->GetMsg()->starteventmessage();
|
2009-05-30 22:20:40 +00:00
|
|
|
// Only admins are allowed to start the game.
|
2011-03-10 20:55:46 +00:00
|
|
|
if (session->GetPlayerData()->IsGameAdmin()
|
2012-09-18 15:57:58 +02:00
|
|
|
&& netStartEvent.gameid() == server->GetId()
|
|
|
|
|
&& netStartEvent.starteventtype() == StartEventMessage::startEvent
|
2011-02-11 20:02:08 +00:00
|
|
|
&& (server->GetGameData().gameType != GAME_TYPE_RANKING // ranking games need to be full
|
2011-04-10 10:04:42 +00:00
|
|
|
|| server->GetGameData().maxNumberOfPlayers == server->GetCurNumberOfPlayers())) {
|
2012-09-18 15:57:58 +02:00
|
|
|
SendStartEvent(*server, netStartEvent.fillwithcomputerplayers());
|
2011-02-11 20:02:08 +00:00
|
|
|
} else { // kick players who try to start but are not allowed to
|
2010-11-14 01:13:23 +00:00
|
|
|
server->MoveSessionToLobby(session, NTF_NET_REMOVED_START_FAILED);
|
|
|
|
|
}
|
2012-09-18 15:57:58 +02:00
|
|
|
} else if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_InvitePlayerToGameMessage) {
|
|
|
|
|
const InvitePlayerToGameMessage &netInvite = packet->GetMsg()->inviteplayertogamemessage();
|
2010-03-30 12:07:48 +00:00
|
|
|
|
2010-03-30 18:03:08 +00:00
|
|
|
// Only invite players which are not already within the group.
|
2012-09-18 15:57:58 +02:00
|
|
|
if (netInvite.gameid() == server->GetId() && !server->IsPlayerConnected(netInvite.playerid())) {
|
|
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_InviteNotifyMessage);
|
|
|
|
|
InviteNotifyMessage *netInvNotif = packet->GetMsg()->mutable_invitenotifymessage();
|
|
|
|
|
netInvNotif->set_gameid(netInvite.gameid());
|
|
|
|
|
netInvNotif->set_playeridbywhom(session->GetPlayerData()->GetUniqueId());
|
|
|
|
|
netInvNotif->set_playeridwho(netInvite.playerid());
|
2010-03-30 12:07:48 +00:00
|
|
|
|
2012-09-18 15:57:58 +02:00
|
|
|
bool requestSent = server->GetLobbyThread().SendToLobbyPlayer(netInvite.playerid(), packet);
|
2010-03-30 12:07:48 +00:00
|
|
|
server->SendToAllPlayers(packet, SessionData::Game);
|
2011-02-11 20:02:08 +00:00
|
|
|
if (requestSent) {
|
2010-03-30 17:10:37 +00:00
|
|
|
// This player has been invited.
|
2012-09-18 15:57:58 +02:00
|
|
|
server->AddPlayerInvitation(netInvite.playerid());
|
2011-02-11 20:02:08 +00:00
|
|
|
} else {
|
2010-03-30 13:02:43 +00:00
|
|
|
// Player is not in lobby - send reject message.
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> p2(new NetPacket);
|
|
|
|
|
p2->GetMsg()->set_messagetype(PokerTHMessage::Type_RejectInvNotifyMessage);
|
|
|
|
|
RejectInvNotifyMessage *netRejNotif = p2->GetMsg()->mutable_rejectinvnotifymessage();
|
|
|
|
|
netRejNotif->set_gameid(netInvite.gameid());
|
|
|
|
|
netRejNotif->set_playerid(netInvite.playerid());
|
|
|
|
|
netRejNotif->set_playerrejectreason(RejectGameInvitationMessage::rejectReasonBusy);
|
2010-03-30 13:02:43 +00:00
|
|
|
|
|
|
|
|
server->SendToAllPlayers(p2, SessionData::Game);
|
|
|
|
|
}
|
2010-03-30 12:07:48 +00:00
|
|
|
}
|
2012-09-18 15:57:58 +02:00
|
|
|
} else if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_ResetTimeoutMessage) {
|
2011-03-10 20:55:46 +00:00
|
|
|
if (session->GetPlayerData()->IsGameAdmin()) {
|
2009-05-31 13:17:02 +00:00
|
|
|
RegisterAdminTimer(server);
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
2013-02-25 23:02:20 +01:00
|
|
|
} else if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_AdminRemoveGameMessage) {
|
|
|
|
|
server->GetLobbyThread().HandleAdminRemoveGame(session, packet->GetMsg()->adminremovegamemessage());
|
|
|
|
|
} else if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_AdminBanPlayerMessage) {
|
|
|
|
|
server->GetLobbyThread().HandleAdminBanPlayer(session, packet->GetMsg()->adminbanplayermessage());
|
2011-02-11 20:02:08 +00:00
|
|
|
} else {
|
2009-06-12 15:48:34 +00:00
|
|
|
server->SessionError(session, ERR_SOCK_INVALID_PACKET);
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
2009-05-31 13:17:02 +00:00
|
|
|
ServerGameStateStartGame ServerGameStateStartGame::s_state;
|
|
|
|
|
|
|
|
|
|
ServerGameStateStartGame &
|
|
|
|
|
ServerGameStateStartGame::Instance()
|
|
|
|
|
{
|
|
|
|
|
return s_state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ServerGameStateStartGame::ServerGameStateStartGame()
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ServerGameStateStartGame::~ServerGameStateStartGame()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateStartGame::Enter(boost::shared_ptr<ServerGame> server)
|
2009-05-31 13:17:02 +00:00
|
|
|
{
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().expires_from_now(
|
2014-03-29 16:13:53 +01:00
|
|
|
seconds(SERVER_START_GAME_TIMEOUT_SEC));
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().async_wait(
|
2009-06-12 15:48:34 +00:00
|
|
|
boost::bind(
|
|
|
|
|
&ServerGameStateStartGame::TimerTimeout, this, boost::asio::placeholders::error, server));
|
2009-05-31 13:17:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateStartGame::Exit(boost::shared_ptr<ServerGame> server)
|
2009-05-31 13:17:02 +00:00
|
|
|
{
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().cancel();
|
2009-05-31 13:17:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2013-06-16 10:43:13 +02:00
|
|
|
ServerGameStateStartGame::HandleNewPlayer(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
|
|
|
|
// Do not accept new sessions in this state.
|
2009-06-12 15:48:34 +00:00
|
|
|
server->MoveSessionToLobby(session, NTF_NET_REMOVED_ALREADY_RUNNING);
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
|
2013-06-16 10:43:13 +02:00
|
|
|
void
|
|
|
|
|
ServerGameStateStartGame::HandleNewSpectator(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
|
|
|
|
|
{
|
2013-06-29 16:23:10 +02:00
|
|
|
if (session && session->GetPlayerData()) {
|
2013-08-10 16:53:36 +02:00
|
|
|
AcceptNewSession(server, session, true);
|
2013-06-29 16:23:10 +02:00
|
|
|
}
|
2013-06-16 10:43:13 +02:00
|
|
|
}
|
|
|
|
|
|
2009-06-20 18:41:03 +00:00
|
|
|
void
|
2011-03-10 20:55:46 +00:00
|
|
|
ServerGameStateStartGame::InternalProcessPacket(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
2012-09-18 15:57:58 +02:00
|
|
|
if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_StartEventAckMessage) {
|
2011-03-10 20:55:46 +00:00
|
|
|
session->SetReadyFlag();
|
2013-06-29 23:44:00 +02:00
|
|
|
if (server->GetSessionManager().CountReadySessions() == server->GetSessionManager().GetSessionCountWithState(SessionData::Game)) {
|
2009-05-30 22:20:40 +00:00
|
|
|
// Everyone is ready.
|
2009-06-12 15:48:34 +00:00
|
|
|
server->GetSessionManager().ResetAllReadyFlags();
|
2009-05-31 13:17:02 +00:00
|
|
|
DoStart(server);
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateStartGame::TimerTimeout(const boost::system::error_code &ec, boost::shared_ptr<ServerGame> server)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
2011-02-11 20:02:08 +00:00
|
|
|
if (!ec && &server->GetState() == this) {
|
2009-06-12 15:48:34 +00:00
|
|
|
// On timeout: start anyway.
|
|
|
|
|
server->GetSessionManager().ResetAllReadyFlags();
|
|
|
|
|
// TODO report successful start! -> new callback?!
|
|
|
|
|
//retVal = MSG_SOCK_INIT_DONE;
|
|
|
|
|
DoStart(server);
|
|
|
|
|
}
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateStartGame::DoStart(boost::shared_ptr<ServerGame> server)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
2010-10-22 19:42:48 +00:00
|
|
|
PlayerDataList tmpPlayerList(server->InternalStartGame());
|
2011-02-11 20:02:08 +00:00
|
|
|
if (tmpPlayerList.size() <= 1) {
|
|
|
|
|
if (!tmpPlayerList.empty()) {
|
2009-05-30 22:20:40 +00:00
|
|
|
boost::shared_ptr<PlayerData> tmpPlayer(tmpPlayerList.front());
|
2011-03-10 20:55:46 +00:00
|
|
|
boost::shared_ptr<SessionData> tmpSession = server->GetSessionManager().GetSessionByUniquePlayerId(tmpPlayer->GetUniqueId());
|
|
|
|
|
if (tmpSession)
|
2009-06-12 15:48:34 +00:00
|
|
|
server->MoveSessionToLobby(tmpSession, NTF_NET_REMOVED_START_FAILED);
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
2011-02-11 20:02:08 +00:00
|
|
|
} else {
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_GameStartInitialMessage);
|
|
|
|
|
GameStartInitialMessage *netGameStart = packet->GetMsg()->mutable_gamestartinitialmessage();
|
|
|
|
|
netGameStart->set_gameid(server->GetId());
|
|
|
|
|
netGameStart->set_startdealerplayerid(server->GetStartData().startDealerPlayerId);
|
2009-05-30 22:20:40 +00:00
|
|
|
|
|
|
|
|
// Send player order to clients.
|
|
|
|
|
// Assume player list is sorted by number.
|
|
|
|
|
PlayerDataList::iterator player_i = tmpPlayerList.begin();
|
|
|
|
|
PlayerDataList::iterator player_end = tmpPlayerList.end();
|
2011-02-11 20:02:08 +00:00
|
|
|
while (player_i != player_end) {
|
2012-09-18 15:57:58 +02:00
|
|
|
netGameStart->add_playerseats((*player_i)->GetUniqueId());
|
2009-05-30 22:20:40 +00:00
|
|
|
++player_i;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-29 16:23:10 +02:00
|
|
|
server->SendToAllPlayers(packet, SessionData::Game | SessionData::Spectating);
|
2009-05-30 22:20:40 +00:00
|
|
|
|
|
|
|
|
// Start the first hand.
|
2009-06-07 08:51:43 +00:00
|
|
|
ServerGameStateHand::StartNewHand(server);
|
2009-06-12 15:48:34 +00:00
|
|
|
server->SetState(ServerGameStateHand::Instance());
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
2011-09-11 17:41:56 +00:00
|
|
|
AbstractServerGameStateRunning::~AbstractServerGameStateRunning()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2013-06-16 10:43:13 +02:00
|
|
|
AbstractServerGameStateRunning::HandleNewPlayer(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
|
2011-09-11 17:41:56 +00:00
|
|
|
{
|
2011-09-11 20:38:18 +00:00
|
|
|
|
|
|
|
|
// Verify that the user is allowed to rejoin.
|
2011-10-23 09:13:04 +00:00
|
|
|
if (session && session->GetPlayerData()) {
|
|
|
|
|
boost::shared_ptr<PlayerInterface> tmpPlayer = server->GetPlayerInterfaceFromGame(session->GetPlayerData()->GetName());
|
|
|
|
|
if (tmpPlayer && tmpPlayer->getMyGuid() == session->GetPlayerData()->GetOldGuid()) {
|
|
|
|
|
// The player wants to rejoin.
|
2013-06-16 10:43:13 +02:00
|
|
|
AcceptNewSession(server, session, false);
|
2011-10-23 09:13:04 +00:00
|
|
|
// Remember: We need to initiate a rejoin when starting the next hand.
|
|
|
|
|
server->AddRejoinPlayer(session->GetPlayerData()->GetUniqueId());
|
2011-09-11 20:38:18 +00:00
|
|
|
|
2011-10-23 09:13:04 +00:00
|
|
|
// Send start event right away.
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_StartEventMessage);
|
|
|
|
|
StartEventMessage *netStartEvent = packet->GetMsg()->mutable_starteventmessage();
|
|
|
|
|
netStartEvent->set_starteventtype(StartEventMessage::rejoinEvent);
|
|
|
|
|
netStartEvent->set_gameid(server->GetId());
|
2011-09-11 20:38:18 +00:00
|
|
|
|
|
|
|
|
// Wait for rejoining player to confirm start of game.
|
|
|
|
|
server->GetLobbyThread().GetSender().Send(session, packet);
|
2011-10-23 09:13:04 +00:00
|
|
|
} else {
|
|
|
|
|
// Do not accept "new" sessions in this state, only rejoin is allowed.
|
|
|
|
|
server->MoveSessionToLobby(session, NTF_NET_REMOVED_ALREADY_RUNNING);
|
2011-09-11 20:38:18 +00:00
|
|
|
}
|
|
|
|
|
}
|
2011-09-11 17:41:56 +00:00
|
|
|
}
|
|
|
|
|
|
2013-06-16 10:43:13 +02:00
|
|
|
void
|
|
|
|
|
AbstractServerGameStateRunning::HandleNewSpectator(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
|
|
|
|
|
{
|
2013-06-29 16:23:10 +02:00
|
|
|
if (session && session->GetPlayerData()) {
|
2013-08-10 16:53:36 +02:00
|
|
|
AcceptNewSession(server, session, true);
|
2013-08-11 13:25:26 +02:00
|
|
|
session->SetState(SessionData::SpectatorWaiting);
|
2013-06-29 16:23:10 +02:00
|
|
|
server->AddNewSpectator(session->GetPlayerData()->GetUniqueId());
|
|
|
|
|
}
|
2013-06-16 10:43:13 +02:00
|
|
|
}
|
|
|
|
|
|
2011-12-27 10:11:15 +00:00
|
|
|
void
|
|
|
|
|
AbstractServerGameStateRunning::InternalProcessPacket(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet)
|
|
|
|
|
{
|
2012-09-18 15:57:58 +02:00
|
|
|
if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_ResetTimeoutMessage) {
|
2011-12-27 10:11:15 +00:00
|
|
|
// Reactivate session.
|
|
|
|
|
server->AddReactivatePlayer(session->GetPlayerData()->GetUniqueId());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-11 17:41:56 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
2009-05-31 13:17:02 +00:00
|
|
|
ServerGameStateHand ServerGameStateHand::s_state;
|
|
|
|
|
|
|
|
|
|
ServerGameStateHand &
|
|
|
|
|
ServerGameStateHand::Instance()
|
|
|
|
|
{
|
|
|
|
|
return s_state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ServerGameStateHand::ServerGameStateHand()
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ServerGameStateHand::~ServerGameStateHand()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateHand::Enter(boost::shared_ptr<ServerGame> server)
|
2009-05-31 13:17:02 +00:00
|
|
|
{
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().expires_from_now(
|
2014-03-29 16:13:53 +01:00
|
|
|
milliseconds(SERVER_LOOP_DELAY_MSEC));
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().async_wait(
|
2009-06-12 15:48:34 +00:00
|
|
|
boost::bind(
|
|
|
|
|
&ServerGameStateHand::TimerLoop, this, boost::asio::placeholders::error, server));
|
2009-05-31 13:17:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateHand::Exit(boost::shared_ptr<ServerGame> server)
|
2009-05-31 13:17:02 +00:00
|
|
|
{
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().cancel();
|
2009-05-31 13:17:02 +00:00
|
|
|
}
|
|
|
|
|
|
2009-06-20 18:41:03 +00:00
|
|
|
void
|
2011-12-27 10:11:15 +00:00
|
|
|
ServerGameStateHand::InternalProcessPacket(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
2011-12-27 10:11:15 +00:00
|
|
|
AbstractServerGameStateRunning::InternalProcessPacket(server, session, packet);
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateHand::TimerLoop(const boost::system::error_code &ec, boost::shared_ptr<ServerGame> server)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
2011-02-11 20:02:08 +00:00
|
|
|
if (!ec && &server->GetState() == this) {
|
|
|
|
|
try {
|
2009-06-19 20:48:57 +00:00
|
|
|
EngineLoop(server);
|
2011-02-11 20:02:08 +00:00
|
|
|
} catch (const PokerTHException &e) {
|
2009-07-12 21:12:55 +00:00
|
|
|
LOG_ERROR("Game " << server->GetId() << " - Engine exception: " << e.what());
|
2009-06-19 20:48:57 +00:00
|
|
|
server->RemoveAllSessions(); // Close this game on error.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-10-18 17:40:12 +00:00
|
|
|
|
2009-06-19 20:48:57 +00:00
|
|
|
void
|
|
|
|
|
ServerGameStateHand::EngineLoop(boost::shared_ptr<ServerGame> server)
|
|
|
|
|
{
|
|
|
|
|
Game &curGame = server->GetGame();
|
2007-10-18 17:40:12 +00:00
|
|
|
|
2009-06-19 20:48:57 +00:00
|
|
|
// Main game loop.
|
|
|
|
|
int curRound = curGame.getCurrentHand()->getCurrentRound();
|
|
|
|
|
curGame.getCurrentHand()->switchRounds();
|
|
|
|
|
if (!curGame.getCurrentHand()->getAllInCondition())
|
|
|
|
|
curGame.getCurrentHand()->getCurrentBeRo()->run();
|
|
|
|
|
int newRound = curGame.getCurrentHand()->getCurrentRound();
|
|
|
|
|
|
|
|
|
|
// If round changes, deal cards if needed.
|
2011-02-11 20:02:08 +00:00
|
|
|
if (newRound != curRound && newRound != GAME_STATE_POST_RIVER) {
|
2009-06-19 20:48:57 +00:00
|
|
|
if (newRound <= curRound)
|
|
|
|
|
throw ServerException(__FILE__, __LINE__, ERR_NET_INVALID_GAME_ROUND, 0);
|
|
|
|
|
|
|
|
|
|
// Retrieve non-fold players. If only one player is left, no cards are shown.
|
|
|
|
|
list<boost::shared_ptr<PlayerInterface> > nonFoldPlayers = *curGame.getActivePlayerList();
|
|
|
|
|
nonFoldPlayers.remove_if(boost::bind(&PlayerInterface::getMyAction, _1) == PLAYER_ACTION_FOLD);
|
|
|
|
|
|
|
|
|
|
if (curGame.getCurrentHand()->getAllInCondition()
|
2011-02-11 20:02:08 +00:00
|
|
|
&& !curGame.getCurrentHand()->getCardsShown()
|
|
|
|
|
&& nonFoldPlayers.size() > 1) {
|
2009-06-19 20:48:57 +00:00
|
|
|
// Send cards of all active players to all players (all in).
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> allIn(new NetPacket);
|
|
|
|
|
allIn->GetMsg()->set_messagetype(PokerTHMessage::Type_AllInShowCardsMessage);
|
|
|
|
|
AllInShowCardsMessage *netAllInShow = allIn->GetMsg()->mutable_allinshowcardsmessage();
|
|
|
|
|
netAllInShow->set_gameid(server->GetId());
|
2009-06-19 20:48:57 +00:00
|
|
|
|
|
|
|
|
PlayerListConstIterator i = nonFoldPlayers.begin();
|
|
|
|
|
PlayerListConstIterator end = nonFoldPlayers.end();
|
|
|
|
|
|
2011-02-11 20:02:08 +00:00
|
|
|
while (i != end) {
|
2012-09-18 15:57:58 +02:00
|
|
|
AllInShowCardsMessage::PlayerAllIn *playerAllIn = netAllInShow->add_playersallin();
|
|
|
|
|
playerAllIn->set_playerid((*i)->getMyUniqueID());
|
2009-06-19 20:48:57 +00:00
|
|
|
int tmpCards[2];
|
2014-05-26 12:41:21 +02:00
|
|
|
(*i)->getMyHoleCards(tmpCards);
|
2012-09-18 15:57:58 +02:00
|
|
|
playerAllIn->set_allincard1(tmpCards[0]);
|
|
|
|
|
playerAllIn->set_allincard2(tmpCards[1]);
|
2009-06-19 20:48:57 +00:00
|
|
|
++i;
|
|
|
|
|
}
|
2013-06-29 16:23:10 +02:00
|
|
|
server->SendToAllPlayers(allIn, SessionData::Game | SessionData::Spectating);
|
2009-06-19 20:48:57 +00:00
|
|
|
curGame.getCurrentHand()->setCardsShown(true);
|
2007-10-18 17:40:12 +00:00
|
|
|
|
2014-07-27 18:09:19 +02:00
|
|
|
server->GetStateTimer1().expires_from_now(
|
|
|
|
|
seconds(server->GetServerDelayTime().getShowCardsDelay()));
|
|
|
|
|
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().async_wait(
|
2009-06-19 20:48:57 +00:00
|
|
|
boost::bind(
|
2009-06-20 07:59:33 +00:00
|
|
|
&ServerGameStateHand::TimerShowCards, this, boost::asio::placeholders::error, server));
|
2011-02-11 20:02:08 +00:00
|
|
|
} else {
|
2009-06-19 20:48:57 +00:00
|
|
|
SendNewRoundCards(*server, curGame, newRound);
|
2007-10-18 17:40:12 +00:00
|
|
|
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().expires_from_now(
|
2014-03-29 16:13:53 +01:00
|
|
|
seconds(GetDealCardsDelaySec(*server)));
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().async_wait(
|
2009-06-19 20:48:57 +00:00
|
|
|
boost::bind(
|
|
|
|
|
&ServerGameStateHand::TimerLoop, this, boost::asio::placeholders::error, server));
|
|
|
|
|
}
|
2011-02-11 20:02:08 +00:00
|
|
|
} else {
|
|
|
|
|
if (newRound != GAME_STATE_POST_RIVER) { // continue hand
|
2009-06-19 20:48:57 +00:00
|
|
|
if (curGame.getCurrentHand()->getAllInCondition())
|
|
|
|
|
throw ServerException(__FILE__, __LINE__, ERR_NET_INTERNAL_GAME_ERROR, 0);
|
|
|
|
|
|
|
|
|
|
// Retrieve current player.
|
|
|
|
|
boost::shared_ptr<PlayerInterface> curPlayer = curGame.getCurrentPlayer();
|
|
|
|
|
if (!curPlayer.get())
|
|
|
|
|
throw ServerException(__FILE__, __LINE__, ERR_NET_NO_CURRENT_PLAYER, 0);
|
|
|
|
|
if (!curPlayer->getMyActiveStatus())
|
|
|
|
|
throw ServerException(__FILE__, __LINE__, ERR_NET_PLAYER_NOT_ACTIVE, 0);
|
|
|
|
|
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> notification(new NetPacket);
|
|
|
|
|
notification->GetMsg()->set_messagetype(PokerTHMessage::Type_PlayersTurnMessage);
|
|
|
|
|
PlayersTurnMessage *netPlayersTurn = notification->GetMsg()->mutable_playersturnmessage();
|
|
|
|
|
netPlayersTurn->set_gameid(server->GetId());
|
|
|
|
|
netPlayersTurn->set_gamestate(static_cast<NetGameState>(curGame.getCurrentHand()->getCurrentRound()));
|
|
|
|
|
netPlayersTurn->set_playerid(curPlayer->getMyUniqueID());
|
2013-06-29 16:23:10 +02:00
|
|
|
server->SendToAllPlayers(notification, SessionData::Game | SessionData::Spectating);
|
2009-06-19 20:48:57 +00:00
|
|
|
|
|
|
|
|
// If the player is computer controlled, let the engine act.
|
2011-02-11 20:02:08 +00:00
|
|
|
if (curPlayer->getMyType() == PLAYER_TYPE_COMPUTER) {
|
2014-07-27 18:09:19 +02:00
|
|
|
server->GetStateTimer1().expires_from_now(
|
|
|
|
|
seconds(server->GetServerDelayTime().getComputerActionDelay()));
|
|
|
|
|
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().async_wait(
|
2009-06-19 20:48:57 +00:00
|
|
|
boost::bind(
|
|
|
|
|
&ServerGameStateHand::TimerComputerAction, this, boost::asio::placeholders::error, server));
|
2012-01-05 20:54:27 +00:00
|
|
|
} else {
|
2011-12-16 22:39:24 +00:00
|
|
|
// If the player we are waiting for left, continue without him.
|
|
|
|
|
if (!server->GetSessionManager().IsPlayerConnected(curPlayer->getMyUniqueID())
|
2012-01-05 20:54:27 +00:00
|
|
|
|| !curPlayer->isSessionActive()) {
|
2011-12-16 22:39:24 +00:00
|
|
|
PerformPlayerAction(*server, curPlayer, PLAYER_ACTION_FOLD, 0);
|
2007-10-18 17:40:12 +00:00
|
|
|
|
2011-12-16 22:39:24 +00:00
|
|
|
server->GetStateTimer1().expires_from_now(
|
2014-03-29 16:13:53 +01:00
|
|
|
milliseconds(SERVER_LOOP_DELAY_MSEC));
|
2011-12-16 22:39:24 +00:00
|
|
|
server->GetStateTimer1().async_wait(
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerGameStateHand::TimerLoop, this, boost::asio::placeholders::error, server));
|
|
|
|
|
} else {
|
|
|
|
|
server->SetState(ServerGameStateWaitPlayerAction::Instance());
|
|
|
|
|
}
|
2009-06-12 15:48:34 +00:00
|
|
|
}
|
2011-02-11 20:02:08 +00:00
|
|
|
} else { // hand is over
|
2009-06-19 20:48:57 +00:00
|
|
|
// Engine will find out who won.
|
|
|
|
|
curGame.getCurrentHand()->getCurrentBeRo()->postRiverRun();
|
|
|
|
|
|
|
|
|
|
// Retrieve non-fold players. If only one player is left, no cards are shown.
|
|
|
|
|
list<boost::shared_ptr<PlayerInterface> > nonFoldPlayers = *curGame.getActivePlayerList();
|
|
|
|
|
nonFoldPlayers.remove_if(boost::bind(&PlayerInterface::getMyAction, _1) == PLAYER_ACTION_FOLD);
|
|
|
|
|
|
2011-02-11 20:02:08 +00:00
|
|
|
if (nonFoldPlayers.size() == 1) {
|
2009-06-19 20:48:57 +00:00
|
|
|
// End of Hand, but keep cards hidden.
|
|
|
|
|
boost::shared_ptr<PlayerInterface> player = nonFoldPlayers.front();
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> endHand(new NetPacket);
|
|
|
|
|
endHand->GetMsg()->set_messagetype(PokerTHMessage::Type_EndOfHandHideCardsMessage);
|
|
|
|
|
EndOfHandHideCardsMessage *netEndHand = endHand->GetMsg()->mutable_endofhandhidecardsmessage();
|
|
|
|
|
netEndHand->set_gameid(server->GetId());
|
|
|
|
|
netEndHand->set_playerid(player->getMyUniqueID());
|
|
|
|
|
netEndHand->set_moneywon(player->getLastMoneyWon());
|
|
|
|
|
netEndHand->set_playermoney(player->getMyCash());
|
2013-06-29 16:23:10 +02:00
|
|
|
server->SendToAllPlayers(endHand, SessionData::Game | SessionData::Spectating);
|
2011-02-11 20:02:08 +00:00
|
|
|
} else {
|
2010-07-23 15:55:52 +00:00
|
|
|
// End of Hand - show cards.
|
|
|
|
|
const PlayerIdList showList(curGame.getCurrentHand()->getBoard()->getPlayerNeedToShowCards());
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> endHand(new NetPacket);
|
|
|
|
|
endHand->GetMsg()->set_messagetype(PokerTHMessage::Type_EndOfHandShowCardsMessage);
|
|
|
|
|
EndOfHandShowCardsMessage *netEndHand = endHand->GetMsg()->mutable_endofhandshowcardsmessage();
|
|
|
|
|
netEndHand->set_gameid(server->GetId());
|
2009-06-12 15:48:34 +00:00
|
|
|
|
2010-07-23 15:55:52 +00:00
|
|
|
PlayerIdList::const_iterator i = showList.begin();
|
|
|
|
|
PlayerIdList::const_iterator end = showList.end();
|
2009-06-12 15:48:34 +00:00
|
|
|
|
2011-02-11 20:02:08 +00:00
|
|
|
while (i != end) {
|
2010-07-23 15:55:52 +00:00
|
|
|
boost::shared_ptr<PlayerInterface> tmpPlayer(curGame.getPlayerByUniqueId(*i));
|
2011-02-11 20:02:08 +00:00
|
|
|
if (tmpPlayer) {
|
2012-09-18 15:57:58 +02:00
|
|
|
PlayerResult *playerResult = netEndHand->add_playerresults();
|
2011-11-13 16:28:04 +00:00
|
|
|
SetPlayerResult(*playerResult, tmpPlayer, GAME_STATE_RIVER);
|
2010-07-23 15:55:52 +00:00
|
|
|
}
|
2009-06-19 20:48:57 +00:00
|
|
|
++i;
|
2009-06-12 15:48:34 +00:00
|
|
|
}
|
2013-06-29 16:23:10 +02:00
|
|
|
server->SendToAllPlayers(endHand, SessionData::Game | SessionData::Spectating);
|
2009-06-19 20:48:57 +00:00
|
|
|
}
|
2009-06-12 15:48:34 +00:00
|
|
|
|
2009-06-19 20:48:57 +00:00
|
|
|
// Remove disconnected players. This is the one and only place to do this.
|
|
|
|
|
server->RemoveDisconnectedPlayers();
|
2009-06-12 15:48:34 +00:00
|
|
|
|
2011-09-11 20:38:18 +00:00
|
|
|
// Update rankings of all remaining players
|
2010-08-28 14:34:02 +00:00
|
|
|
server->UpdateRankingMap();
|
|
|
|
|
|
2009-06-19 20:48:57 +00:00
|
|
|
// Start next hand - if enough players are left.
|
|
|
|
|
list<boost::shared_ptr<PlayerInterface> > playersWithCash = *curGame.getActivePlayerList();
|
|
|
|
|
playersWithCash.remove_if(boost::bind(&PlayerInterface::getMyCash, _1) < 1);
|
2009-06-12 15:48:34 +00:00
|
|
|
|
2011-02-11 20:02:08 +00:00
|
|
|
if (playersWithCash.empty()) {
|
2009-06-19 20:48:57 +00:00
|
|
|
// No more players left - restart.
|
|
|
|
|
server->SetState(SERVER_INITIAL_STATE::Instance());
|
2011-02-11 20:02:08 +00:00
|
|
|
} else if (playersWithCash.size() == 1) {
|
2010-07-22 22:18:56 +00:00
|
|
|
boost::shared_ptr<PlayerInterface> winnerPlayer = *(playersWithCash.begin());
|
2010-08-08 10:23:40 +00:00
|
|
|
server->InternalEndGame();
|
2010-07-22 22:18:56 +00:00
|
|
|
|
2009-06-19 20:48:57 +00:00
|
|
|
// View a dialog for a new game - delayed.
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().expires_from_now(
|
2014-07-27 18:09:19 +02:00
|
|
|
seconds(server->GetServerDelayTime().getNextGameDelay()));
|
2014-07-11 18:15:40 +02:00
|
|
|
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().async_wait(
|
2009-06-19 20:48:57 +00:00
|
|
|
boost::bind(
|
2010-07-22 22:18:56 +00:00
|
|
|
&ServerGameStateHand::TimerNextGame, this, boost::asio::placeholders::error, server, winnerPlayer->getMyUniqueID()));
|
2011-02-11 20:02:08 +00:00
|
|
|
} else {
|
2010-07-15 21:55:52 +00:00
|
|
|
server->SetState(ServerGameStateWaitNextHand::Instance());
|
2007-10-18 17:40:12 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateHand::TimerShowCards(const boost::system::error_code &ec, boost::shared_ptr<ServerGame> server)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
2011-02-11 20:02:08 +00:00
|
|
|
if (!ec && &server->GetState() == this) {
|
2009-06-12 15:48:34 +00:00
|
|
|
Game &curGame = server->GetGame();
|
|
|
|
|
SendNewRoundCards(*server, curGame, curGame.getCurrentHand()->getCurrentRound());
|
|
|
|
|
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().expires_from_now(
|
2014-03-29 16:13:53 +01:00
|
|
|
seconds(GetDealCardsDelaySec(*server)));
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().async_wait(
|
2009-06-12 15:48:34 +00:00
|
|
|
boost::bind(
|
|
|
|
|
&ServerGameStateHand::TimerLoop, this, boost::asio::placeholders::error, server));
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
2009-06-12 15:48:34 +00:00
|
|
|
}
|
2009-05-30 22:20:40 +00:00
|
|
|
|
2009-06-12 15:48:34 +00:00
|
|
|
void
|
|
|
|
|
ServerGameStateHand::TimerComputerAction(const boost::system::error_code &ec, boost::shared_ptr<ServerGame> server)
|
|
|
|
|
{
|
2011-02-11 20:02:08 +00:00
|
|
|
if (!ec && &server->GetState() == this) {
|
|
|
|
|
try {
|
2009-07-12 21:12:55 +00:00
|
|
|
boost::shared_ptr<PlayerInterface> curPlayer = server->GetGame().getCurrentPlayer();
|
|
|
|
|
if (!curPlayer)
|
|
|
|
|
throw ServerException(__FILE__, __LINE__, ERR_NET_NO_CURRENT_PLAYER, 0);
|
2009-05-30 22:20:40 +00:00
|
|
|
|
2009-07-12 21:12:55 +00:00
|
|
|
curPlayer->action();
|
|
|
|
|
SendPlayerAction(*server, curPlayer);
|
2009-06-19 20:48:57 +00:00
|
|
|
EngineLoop(server);
|
2011-02-11 20:02:08 +00:00
|
|
|
} catch (const PokerTHException &e) {
|
2009-07-12 21:12:55 +00:00
|
|
|
LOG_ERROR("Game " << server->GetId() << " - Computer timer exception: " << e.what());
|
2009-06-19 20:48:57 +00:00
|
|
|
server->RemoveAllSessions(); // Close this game on error.
|
|
|
|
|
}
|
2009-06-12 15:48:34 +00:00
|
|
|
}
|
|
|
|
|
}
|
2009-05-30 22:20:40 +00:00
|
|
|
|
2009-06-12 15:48:34 +00:00
|
|
|
void
|
|
|
|
|
ServerGameStateHand::TimerNextHand(const boost::system::error_code &ec, boost::shared_ptr<ServerGame> server)
|
|
|
|
|
{
|
2011-02-11 20:02:08 +00:00
|
|
|
if (!ec && &server->GetState() == this) {
|
2009-06-12 15:48:34 +00:00
|
|
|
StartNewHand(server);
|
|
|
|
|
TimerLoop(ec, server);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2010-07-22 22:18:56 +00:00
|
|
|
ServerGameStateHand::TimerNextGame(const boost::system::error_code &ec, boost::shared_ptr<ServerGame> server, unsigned winnerPlayerId)
|
2009-06-12 15:48:34 +00:00
|
|
|
{
|
2011-02-11 20:02:08 +00:00
|
|
|
if (!ec && &server->GetState() == this) {
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> endGame(new NetPacket);
|
|
|
|
|
endGame->GetMsg()->set_messagetype(PokerTHMessage::Type_EndOfGameMessage);
|
|
|
|
|
EndOfGameMessage *netEndGame = endGame->GetMsg()->mutable_endofgamemessage();
|
|
|
|
|
netEndGame->set_gameid(server->GetId());
|
|
|
|
|
netEndGame->set_winnerplayerid(winnerPlayerId);
|
2013-06-29 16:23:10 +02:00
|
|
|
server->SendToAllPlayers(endGame, SessionData::Game | SessionData::Spectating);
|
2009-06-12 15:48:34 +00:00
|
|
|
|
2010-07-22 22:18:56 +00:00
|
|
|
// Wait for the start of a new game.
|
2011-02-06 13:17:07 +00:00
|
|
|
server->RemoveAutoLeavePlayers();
|
2010-07-22 22:18:56 +00:00
|
|
|
server->ResetComputerPlayerList();
|
|
|
|
|
server->GetLobbyThread().NotifyReopeningGame(server->GetId());
|
|
|
|
|
server->SetState(ServerGameStateInit::Instance());
|
2009-06-12 15:48:34 +00:00
|
|
|
}
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2009-05-31 20:14:46 +00:00
|
|
|
ServerGameStateHand::GetDealCardsDelaySec(ServerGame &server)
|
2009-05-30 22:20:40 +00:00
|
|
|
{
|
2009-05-31 13:17:02 +00:00
|
|
|
Game &curGame = server.GetGame();
|
2014-07-27 18:09:19 +02:00
|
|
|
int allInDelay = curGame.getCurrentHand()->getAllInCondition() ? server.GetServerDelayTime().getDealAddAllInDelay() : 0;
|
2009-05-30 22:20:40 +00:00
|
|
|
int delay = 0;
|
|
|
|
|
|
2011-02-11 20:02:08 +00:00
|
|
|
switch(curGame.getCurrentHand()->getCurrentRound()) {
|
|
|
|
|
case GAME_STATE_FLOP:
|
2014-07-27 18:09:19 +02:00
|
|
|
delay = server.GetServerDelayTime().getDealFlopCardsDelay();
|
2011-02-11 20:02:08 +00:00
|
|
|
break;
|
|
|
|
|
case GAME_STATE_TURN:
|
2014-07-27 18:09:19 +02:00
|
|
|
delay = server.GetServerDelayTime().getDealTurnCardsDelay() + allInDelay;
|
2011-02-11 20:02:08 +00:00
|
|
|
break;
|
|
|
|
|
case GAME_STATE_RIVER:
|
2014-07-27 18:09:19 +02:00
|
|
|
delay = server.GetServerDelayTime().getDealRiverCardsDelay();
|
2011-02-11 20:02:08 +00:00
|
|
|
break;
|
2011-10-23 12:02:38 +00:00
|
|
|
default:
|
|
|
|
|
break;
|
2009-05-30 22:20:40 +00:00
|
|
|
}
|
|
|
|
|
return delay;
|
2007-10-18 17:40:12 +00:00
|
|
|
}
|
|
|
|
|
|
2009-06-07 08:51:43 +00:00
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateHand::StartNewHand(boost::shared_ptr<ServerGame> server)
|
2009-06-07 08:51:43 +00:00
|
|
|
{
|
2009-06-12 15:48:34 +00:00
|
|
|
Game &curGame = server->GetGame();
|
2011-10-03 09:53:50 +00:00
|
|
|
|
2011-12-27 09:35:14 +00:00
|
|
|
// Reactivate players which were previously inactive.
|
2011-12-21 20:56:41 +00:00
|
|
|
ReactivatePlayers(server);
|
|
|
|
|
|
2011-09-11 20:38:18 +00:00
|
|
|
// Initialize rejoining players.
|
2011-10-23 09:13:04 +00:00
|
|
|
// This has to be done before initialising the new hand, because there are side effects.
|
|
|
|
|
InitRejoiningPlayers(server);
|
2009-06-07 08:51:43 +00:00
|
|
|
|
2013-06-29 16:23:10 +02:00
|
|
|
// Initialize new spectators.
|
|
|
|
|
InitNewSpectators(server);
|
|
|
|
|
|
2011-12-27 09:35:14 +00:00
|
|
|
// Kick inactive players.
|
|
|
|
|
CheckPlayerTimeouts(server);
|
|
|
|
|
|
2011-10-03 09:53:50 +00:00
|
|
|
// Initialize hand.
|
|
|
|
|
curGame.initHand();
|
|
|
|
|
|
2009-06-07 08:51:43 +00:00
|
|
|
// HACK: Skip GUI notification run
|
|
|
|
|
curGame.getCurrentHand()->getFlop()->skipFirstRunGui();
|
|
|
|
|
curGame.getCurrentHand()->getTurn()->skipFirstRunGui();
|
|
|
|
|
curGame.getCurrentHand()->getRiver()->skipFirstRunGui();
|
|
|
|
|
|
|
|
|
|
// Consider all players, even inactive.
|
|
|
|
|
PlayerListIterator i = curGame.getSeatsList()->begin();
|
|
|
|
|
PlayerListIterator end = curGame.getSeatsList()->end();
|
|
|
|
|
|
|
|
|
|
// Send cards to all players.
|
2011-02-11 20:02:08 +00:00
|
|
|
while (i != end) {
|
2011-12-11 19:37:51 +00:00
|
|
|
// Also send to inactive players.
|
2009-06-07 08:51:43 +00:00
|
|
|
boost::shared_ptr<PlayerInterface> tmpPlayer = *i;
|
2011-03-10 20:55:46 +00:00
|
|
|
boost::shared_ptr<SessionData> tmpSession = server->GetSessionManager().GetSessionByUniquePlayerId(tmpPlayer->getMyUniqueID());
|
2011-12-11 19:37:51 +00:00
|
|
|
if (tmpSession) {
|
2009-06-07 08:51:43 +00:00
|
|
|
int cards[2];
|
2010-09-04 11:56:40 +00:00
|
|
|
bool errorFlag = false;
|
2014-05-26 12:41:21 +02:00
|
|
|
tmpPlayer->getMyHoleCards(cards);
|
2009-06-07 08:51:43 +00:00
|
|
|
|
2013-06-29 16:23:10 +02:00
|
|
|
boost::shared_ptr<NetPacket> notifyCards = CreateNetPacketHandStart(*server);
|
2012-09-18 15:57:58 +02:00
|
|
|
HandStartMessage *netHandStart = notifyCards->GetMsg()->mutable_handstartmessage();
|
2011-03-10 20:55:46 +00:00
|
|
|
string tmpPassword(tmpSession->AuthGetPassword());
|
2011-02-11 20:02:08 +00:00
|
|
|
if (tmpPassword.empty()) { // encrypt only if password is present
|
2012-09-18 15:57:58 +02:00
|
|
|
HandStartMessage::PlainCards *plainCards = netHandStart->mutable_plaincards();
|
|
|
|
|
plainCards->set_plaincard1(cards[0]);
|
|
|
|
|
plainCards->set_plaincard2(cards[1]);
|
2011-02-11 20:02:08 +00:00
|
|
|
} else {
|
2010-09-04 11:56:40 +00:00
|
|
|
ostringstream cardDataStream;
|
|
|
|
|
vector<unsigned char> tmpCipher;
|
|
|
|
|
cardDataStream
|
|
|
|
|
<< tmpPlayer->getMyUniqueID() << " "
|
|
|
|
|
<< server->GetId() << " "
|
|
|
|
|
<< curGame.getCurrentHandID() << " "
|
|
|
|
|
<< cards[0] << " "
|
|
|
|
|
<< cards[1];
|
|
|
|
|
if (CryptHelper::AES128Encrypt((const unsigned char *)tmpPassword.c_str(),
|
2011-02-11 20:02:08 +00:00
|
|
|
(unsigned)tmpPassword.size(),
|
|
|
|
|
cardDataStream.str(),
|
|
|
|
|
tmpCipher)
|
|
|
|
|
&& !tmpCipher.empty()) {
|
2012-09-18 15:57:58 +02:00
|
|
|
netHandStart->set_encryptedcards((const char *)&tmpCipher[0], tmpCipher.size());
|
2011-02-11 20:02:08 +00:00
|
|
|
} else {
|
2010-09-04 11:56:40 +00:00
|
|
|
server->RemovePlayer(tmpPlayer->getMyUniqueID(), ERR_SOCK_INVALID_STATE);
|
|
|
|
|
errorFlag = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-12-21 20:56:41 +00:00
|
|
|
|
2011-02-11 20:02:08 +00:00
|
|
|
if (!errorFlag) {
|
2011-03-10 20:55:46 +00:00
|
|
|
server->GetLobbyThread().GetSender().Send(tmpSession, notifyCards);
|
2010-09-04 11:56:40 +00:00
|
|
|
}
|
2009-06-07 08:51:43 +00:00
|
|
|
}
|
|
|
|
|
++i;
|
|
|
|
|
}
|
2013-06-29 16:23:10 +02:00
|
|
|
server->SendToAllPlayers(CreateNetPacketHandStart(*server), SessionData::Spectating);
|
2009-06-07 08:51:43 +00:00
|
|
|
|
|
|
|
|
// Start hand.
|
|
|
|
|
curGame.startHand();
|
|
|
|
|
|
|
|
|
|
// Auto small blind / big blind at the beginning of hand.
|
|
|
|
|
i = curGame.getActivePlayerList()->begin();
|
|
|
|
|
end = curGame.getActivePlayerList()->end();
|
|
|
|
|
|
2011-02-11 20:02:08 +00:00
|
|
|
while (i != end) {
|
2009-06-07 08:51:43 +00:00
|
|
|
boost::shared_ptr<PlayerInterface> tmpPlayer = *i;
|
2011-02-11 20:02:08 +00:00
|
|
|
if (tmpPlayer->getMyButton() == BUTTON_SMALL_BLIND) {
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> notifySmallBlind(new NetPacket);
|
|
|
|
|
notifySmallBlind->GetMsg()->set_messagetype(PokerTHMessage::Type_PlayersActionDoneMessage);
|
|
|
|
|
PlayersActionDoneMessage *netSmallBlind = notifySmallBlind->GetMsg()->mutable_playersactiondonemessage();
|
|
|
|
|
netSmallBlind->set_gameid(server->GetId());
|
2012-09-23 23:19:53 +02:00
|
|
|
netSmallBlind->set_gamestate(netStatePreflopSmallBlind);
|
2012-09-18 15:57:58 +02:00
|
|
|
netSmallBlind->set_playerid(tmpPlayer->getMyUniqueID());
|
|
|
|
|
netSmallBlind->set_playeraction(static_cast<NetPlayerAction>(tmpPlayer->getMyAction()));
|
|
|
|
|
netSmallBlind->set_totalplayerbet(tmpPlayer->getMySet());
|
|
|
|
|
netSmallBlind->set_playermoney(tmpPlayer->getMyCash());
|
|
|
|
|
netSmallBlind->set_highestset(server->GetGame().getCurrentHand()->getCurrentBeRo()->getHighestSet());
|
|
|
|
|
netSmallBlind->set_minimumraise(server->GetGame().getCurrentHand()->getCurrentBeRo()->getMinimumRaise());
|
2013-06-29 16:23:10 +02:00
|
|
|
server->SendToAllPlayers(notifySmallBlind, SessionData::Game | SessionData::Spectating);
|
2009-06-07 08:51:43 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i = curGame.getActivePlayerList()->begin();
|
|
|
|
|
end = curGame.getActivePlayerList()->end();
|
2011-02-11 20:02:08 +00:00
|
|
|
while (i != end) {
|
2009-06-07 08:51:43 +00:00
|
|
|
boost::shared_ptr<PlayerInterface> tmpPlayer = *i;
|
2011-02-11 20:02:08 +00:00
|
|
|
if (tmpPlayer->getMyButton() == BUTTON_BIG_BLIND) {
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> notifyBigBlind(new NetPacket);
|
|
|
|
|
notifyBigBlind->GetMsg()->set_messagetype(PokerTHMessage::Type_PlayersActionDoneMessage);
|
|
|
|
|
PlayersActionDoneMessage *netBigBlind = notifyBigBlind->GetMsg()->mutable_playersactiondonemessage();
|
|
|
|
|
netBigBlind->set_gameid(server->GetId());
|
2012-09-23 23:19:53 +02:00
|
|
|
netBigBlind->set_gamestate(netStatePreflopBigBlind);
|
2012-09-18 15:57:58 +02:00
|
|
|
netBigBlind->set_playerid(tmpPlayer->getMyUniqueID());
|
|
|
|
|
netBigBlind->set_playeraction(static_cast<NetPlayerAction>(tmpPlayer->getMyAction()));
|
|
|
|
|
netBigBlind->set_totalplayerbet(tmpPlayer->getMySet());
|
|
|
|
|
netBigBlind->set_playermoney(tmpPlayer->getMyCash());
|
|
|
|
|
netBigBlind->set_highestset(server->GetGame().getCurrentHand()->getCurrentBeRo()->getHighestSet());
|
|
|
|
|
netBigBlind->set_minimumraise(server->GetGame().getCurrentHand()->getCurrentBeRo()->getMinimumRaise());
|
2013-06-29 16:23:10 +02:00
|
|
|
server->SendToAllPlayers(notifyBigBlind, SessionData::Game | SessionData::Spectating);
|
2009-06-07 08:51:43 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-21 20:56:41 +00:00
|
|
|
void
|
|
|
|
|
ServerGameStateHand::CheckPlayerTimeouts(boost::shared_ptr<ServerGame> server)
|
|
|
|
|
{
|
2011-12-23 17:23:56 +00:00
|
|
|
// Check timeout.
|
|
|
|
|
int actionTimeout = server->GetGameData().playerActionTimeoutSec;
|
|
|
|
|
if (actionTimeout) {
|
2011-12-29 10:55:27 +00:00
|
|
|
// Consider all active players.
|
|
|
|
|
PlayerListIterator i = server->GetGame().getActivePlayerList()->begin();
|
|
|
|
|
PlayerListIterator end = server->GetGame().getActivePlayerList()->end();
|
2011-12-21 20:56:41 +00:00
|
|
|
|
2011-12-29 10:55:27 +00:00
|
|
|
// Check timeouts of players.
|
2011-12-23 17:23:56 +00:00
|
|
|
while (i != end) {
|
|
|
|
|
boost::shared_ptr<PlayerInterface> tmpPlayer = *i;
|
|
|
|
|
if (tmpPlayer->getMyType() == PLAYER_TYPE_HUMAN
|
2012-01-05 20:54:27 +00:00
|
|
|
&& (int)tmpPlayer->getTimeSecSinceLastRemoteAction() >= actionTimeout * SERVER_GAME_AUTOFOLD_TIMEOUT_FACTOR) {
|
2011-12-21 20:56:41 +00:00
|
|
|
if (tmpPlayer->isSessionActive()) {
|
|
|
|
|
tmpPlayer->setIsSessionActive(false);
|
|
|
|
|
boost::shared_ptr<SessionData> session = server->GetSessionManager().GetSessionByUniquePlayerId(tmpPlayer->getMyUniqueID());
|
|
|
|
|
if (session) {
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_TimeoutWarningMessage);
|
|
|
|
|
TimeoutWarningMessage *netWarning = packet->GetMsg()->mutable_timeoutwarningmessage();
|
|
|
|
|
netWarning->set_timeoutreason(TimeoutWarningMessage::timeoutKickAfterAutofold);
|
|
|
|
|
netWarning->set_remainingseconds(actionTimeout * SERVER_GAME_FORCED_TIMEOUT_FACTOR - tmpPlayer->getTimeSecSinceLastRemoteAction());
|
2011-12-21 20:56:41 +00:00
|
|
|
server->GetLobbyThread().GetSender().Send(session, packet);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ((int)tmpPlayer->getTimeSecSinceLastRemoteAction() >= actionTimeout * SERVER_GAME_FORCED_TIMEOUT_FACTOR) {
|
|
|
|
|
server->KickPlayer(tmpPlayer->getMyUniqueID());
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-12-23 17:23:56 +00:00
|
|
|
++i;
|
2011-12-21 20:56:41 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerGameStateHand::ReactivatePlayers(boost::shared_ptr<ServerGame> server)
|
|
|
|
|
{
|
|
|
|
|
PlayerIdList reactivateIdList(server->GetAndResetReactivatePlayers());
|
|
|
|
|
PlayerIdList::iterator i = reactivateIdList.begin();
|
|
|
|
|
PlayerIdList::iterator end = reactivateIdList.end();
|
|
|
|
|
while (i != end) {
|
|
|
|
|
boost::shared_ptr<PlayerInterface> tmpPlayer(server->GetGame().getPlayerByUniqueId(*i));
|
2011-12-26 17:21:35 +00:00
|
|
|
if (tmpPlayer) {
|
|
|
|
|
tmpPlayer->markRemoteAction();
|
|
|
|
|
tmpPlayer->setIsSessionActive(true);
|
|
|
|
|
}
|
2011-12-21 20:56:41 +00:00
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-23 09:13:04 +00:00
|
|
|
void
|
|
|
|
|
ServerGameStateHand::InitRejoiningPlayers(boost::shared_ptr<ServerGame> server)
|
|
|
|
|
{
|
|
|
|
|
PlayerIdList rejoinIdList(server->GetAndResetRejoinPlayers());
|
|
|
|
|
PlayerIdList::iterator i = rejoinIdList.begin();
|
|
|
|
|
PlayerIdList::iterator end = rejoinIdList.end();
|
|
|
|
|
while (i != end) {
|
|
|
|
|
boost::shared_ptr<SessionData> session(server->GetSessionManager().GetSessionByUniquePlayerId(*i));
|
|
|
|
|
if (session && session->GetPlayerData()) {
|
|
|
|
|
PerformRejoin(server, session);
|
|
|
|
|
}
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-29 16:23:10 +02:00
|
|
|
void
|
|
|
|
|
ServerGameStateHand::InitNewSpectators(boost::shared_ptr<ServerGame> server)
|
|
|
|
|
{
|
|
|
|
|
PlayerIdList spectatorIdList(server->GetAndResetNewSpectators());
|
|
|
|
|
PlayerIdList::iterator i = spectatorIdList.begin();
|
|
|
|
|
PlayerIdList::iterator end = spectatorIdList.end();
|
|
|
|
|
while (i != end) {
|
|
|
|
|
boost::shared_ptr<SessionData> session(server->GetSessionManager().GetSessionByUniquePlayerId(*i));
|
|
|
|
|
if (session && session->GetPlayerData()) {
|
2013-08-10 16:29:15 +02:00
|
|
|
session->SetState(SessionData::Spectating);
|
2013-06-29 16:23:10 +02:00
|
|
|
SendGameData(server, session);
|
|
|
|
|
}
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-10-23 09:13:04 +00:00
|
|
|
void
|
|
|
|
|
ServerGameStateHand::PerformRejoin(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
|
|
|
|
|
{
|
|
|
|
|
Game &curGame = server->GetGame();
|
|
|
|
|
// Set new player id.
|
|
|
|
|
boost::shared_ptr<PlayerInterface> rejoinPlayer = curGame.getPlayerByName(session->GetPlayerData()->GetName());
|
|
|
|
|
if (rejoinPlayer) {
|
|
|
|
|
// Notify other clients about id change.
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_PlayerIdChangedMessage);
|
|
|
|
|
PlayerIdChangedMessage *netIdChanged = packet->GetMsg()->mutable_playeridchangedmessage();
|
|
|
|
|
netIdChanged->set_oldplayerid(rejoinPlayer->getMyUniqueID());
|
|
|
|
|
netIdChanged->set_newplayerid(session->GetPlayerData()->GetUniqueId());
|
2013-09-01 18:09:15 +02:00
|
|
|
server->SendToAllButOnePlayers(packet, session->GetId(), SessionData::Game | SessionData::Spectating | SessionData::SpectatorWaiting);
|
2011-10-23 09:13:04 +00:00
|
|
|
|
|
|
|
|
// Update the dealer, if necessary.
|
|
|
|
|
curGame.replaceDealer(rejoinPlayer->getMyUniqueID(), session->GetPlayerData()->GetUniqueId());
|
2011-12-27 20:44:16 +00:00
|
|
|
// Update the ranking map.
|
|
|
|
|
server->ReplaceRankingPlayer(rejoinPlayer->getMyUniqueID(), session->GetPlayerData()->GetUniqueId());
|
2011-10-23 09:13:04 +00:00
|
|
|
// Change the Id in the poker engine.
|
|
|
|
|
rejoinPlayer->setMyUniqueID(session->GetPlayerData()->GetUniqueId());
|
|
|
|
|
rejoinPlayer->setMyGuid(session->GetPlayerData()->GetGuid());
|
2011-12-27 09:35:14 +00:00
|
|
|
rejoinPlayer->markRemoteAction();
|
2011-12-11 19:37:51 +00:00
|
|
|
rejoinPlayer->setIsSessionActive(true);
|
2013-06-29 16:23:10 +02:00
|
|
|
SendGameData(server, session);
|
2011-10-23 09:13:04 +00:00
|
|
|
} else {
|
|
|
|
|
server->SessionError(session, ERR_SOCK_INVALID_STATE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-29 16:23:10 +02:00
|
|
|
void
|
|
|
|
|
ServerGameStateHand::SendGameData(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session)
|
|
|
|
|
{
|
|
|
|
|
Game &curGame = server->GetGame();
|
|
|
|
|
// Send game start notification to rejoining client.
|
|
|
|
|
boost::shared_ptr<NetPacket> packet(new NetPacket);
|
|
|
|
|
packet->GetMsg()->set_messagetype(PokerTHMessage::Type_GameStartRejoinMessage);
|
|
|
|
|
GameStartRejoinMessage *netGameStart = packet->GetMsg()->mutable_gamestartrejoinmessage();
|
|
|
|
|
netGameStart->set_gameid(server->GetId());
|
|
|
|
|
netGameStart->set_startdealerplayerid(curGame.getDealerPosition());
|
|
|
|
|
netGameStart->set_handnum(curGame.getCurrentHandID());
|
|
|
|
|
PlayerListIterator player_i = curGame.getSeatsList()->begin();
|
|
|
|
|
PlayerListIterator player_end = curGame.getSeatsList()->end();
|
|
|
|
|
int player_count = 0;
|
|
|
|
|
while (player_i != player_end && player_count < server->GetStartData().numberOfPlayers) {
|
|
|
|
|
boost::shared_ptr<PlayerInterface> tmpPlayer = *player_i;
|
|
|
|
|
GameStartRejoinMessage::RejoinPlayerData *playerSlot = netGameStart->add_rejoinplayerdata();
|
|
|
|
|
playerSlot->set_playerid(tmpPlayer->getMyUniqueID());
|
|
|
|
|
playerSlot->set_playermoney(tmpPlayer->getMyCash());
|
|
|
|
|
++player_i;
|
|
|
|
|
++player_count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
server->GetLobbyThread().GetSender().Send(session, packet);
|
|
|
|
|
}
|
|
|
|
|
|
2007-10-18 17:40:12 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
2009-05-31 13:17:02 +00:00
|
|
|
ServerGameStateWaitPlayerAction ServerGameStateWaitPlayerAction::s_state;
|
|
|
|
|
|
|
|
|
|
ServerGameStateWaitPlayerAction &
|
|
|
|
|
ServerGameStateWaitPlayerAction::Instance()
|
|
|
|
|
{
|
|
|
|
|
return s_state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ServerGameStateWaitPlayerAction::ServerGameStateWaitPlayerAction()
|
|
|
|
|
{
|
2007-10-18 17:40:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ServerGameStateWaitPlayerAction::~ServerGameStateWaitPlayerAction()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-30 22:20:40 +00:00
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateWaitPlayerAction::Enter(boost::shared_ptr<ServerGame> server)
|
2009-05-31 13:17:02 +00:00
|
|
|
{
|
2011-02-11 20:02:08 +00:00
|
|
|
if (server->GetGameData().playerActionTimeoutSec > 0) { // zero means unlimited thinking time
|
2011-02-11 12:59:42 +00:00
|
|
|
#ifdef POKERTH_SERVER_TEST
|
2014-07-27 18:09:19 +02:00
|
|
|
int timeoutSec = server->GetServerDelayTime().getPlayerTimeoutAddDelay();
|
2014-07-11 18:15:40 +02:00
|
|
|
#else
|
2014-07-27 18:09:19 +02:00
|
|
|
int timeoutSec = server->GetServerDelayTime().getPlayerTimeoutAddDelay() + server->GetGameData().playerActionTimeoutSec;
|
2009-05-31 13:17:02 +00:00
|
|
|
#endif
|
|
|
|
|
|
2014-03-29 16:13:53 +01:00
|
|
|
server->GetStateTimer1().expires_from_now(seconds(timeoutSec));
|
2011-02-06 10:37:40 +00:00
|
|
|
server->GetStateTimer1().async_wait(
|
|
|
|
|
boost::bind(
|
|
|
|
|
&ServerGameStateWaitPlayerAction::TimerTimeout, this, boost::asio::placeholders::error, server));
|
|
|
|
|
}
|
2009-05-31 13:17:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateWaitPlayerAction::Exit(boost::shared_ptr<ServerGame> server)
|
2009-05-31 13:17:02 +00:00
|
|
|
{
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().cancel();
|
2009-05-31 13:17:02 +00:00
|
|
|
}
|
|
|
|
|
|
2009-06-20 18:41:03 +00:00
|
|
|
void
|
2011-03-10 20:55:46 +00:00
|
|
|
ServerGameStateWaitPlayerAction::InternalProcessPacket(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet)
|
2007-10-18 17:40:12 +00:00
|
|
|
{
|
2011-12-27 10:11:15 +00:00
|
|
|
AbstractServerGameStateRunning::InternalProcessPacket(server, session, packet);
|
|
|
|
|
|
2012-09-18 15:57:58 +02:00
|
|
|
if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_MyActionRequestMessage) {
|
|
|
|
|
MyActionRequestMessage *netMyAction = packet->GetMsg()->mutable_myactionrequestmessage();
|
2007-10-18 17:40:12 +00:00
|
|
|
|
2009-08-02 15:11:40 +00:00
|
|
|
// TODO consider game id.
|
2009-06-12 15:48:34 +00:00
|
|
|
Game &curGame = server->GetGame();
|
2011-03-10 20:55:46 +00:00
|
|
|
boost::shared_ptr<PlayerInterface> tmpPlayer = curGame.getPlayerByUniqueId(session->GetPlayerData()->GetUniqueId());
|
|
|
|
|
if (!tmpPlayer)
|
2007-10-18 20:36:49 +00:00
|
|
|
throw ServerException(__FILE__, __LINE__, ERR_NET_UNKNOWN_PLAYER_ID, 0);
|
2007-10-18 17:40:12 +00:00
|
|
|
|
|
|
|
|
// Check whether this is the correct round.
|
|
|
|
|
PlayerActionCode code = ACTION_CODE_VALID;
|
2012-09-20 22:14:17 +02:00
|
|
|
if (curGame.getCurrentHand()->getCurrentRound() != static_cast<GameState>(netMyAction->gamestate()))
|
2007-10-18 17:40:12 +00:00
|
|
|
code = ACTION_CODE_INVALID_STATE;
|
|
|
|
|
|
|
|
|
|
// Check whether this is the correct player.
|
2009-06-12 15:48:34 +00:00
|
|
|
boost::shared_ptr<PlayerInterface> curPlayer = server->GetGame().getCurrentPlayer();
|
2007-10-18 17:40:12 +00:00
|
|
|
if (code == ACTION_CODE_VALID
|
2011-02-11 20:02:08 +00:00
|
|
|
&& (curPlayer->getMyUniqueID() != tmpPlayer->getMyUniqueID())) {
|
2007-10-18 17:40:12 +00:00
|
|
|
code = ACTION_CODE_NOT_YOUR_TURN;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-25 21:11:05 +00:00
|
|
|
// If the client omitted some values, fill them in.
|
2012-09-23 23:19:53 +02:00
|
|
|
if (netMyAction->myaction() == netActionCall && netMyAction->myrelativebet() == 0) {
|
2008-12-25 21:11:05 +00:00
|
|
|
if (curGame.getCurrentHand()->getCurrentBeRo()->getHighestSet() >= tmpPlayer->getMySet() + tmpPlayer->getMyCash())
|
2012-09-23 23:19:53 +02:00
|
|
|
netMyAction->set_myaction(netActionAllIn);
|
2008-12-25 21:11:05 +00:00
|
|
|
else
|
2012-09-18 15:57:58 +02:00
|
|
|
netMyAction->set_myrelativebet(curGame.getCurrentHand()->getCurrentBeRo()->getHighestSet() - tmpPlayer->getMySet());
|
2008-12-25 21:11:05 +00:00
|
|
|
}
|
2012-09-23 23:19:53 +02:00
|
|
|
if (netMyAction->myaction() == netActionAllIn && netMyAction->myrelativebet() == 0)
|
2012-09-18 15:57:58 +02:00
|
|
|
netMyAction->set_myrelativebet(tmpPlayer->getMyCash());
|
2008-12-25 21:11:05 +00:00
|
|
|
|
2007-10-18 17:40:12 +00:00
|
|
|
// Check whether the action is valid.
|
|
|
|
|
if (code == ACTION_CODE_VALID
|
2011-02-11 20:02:08 +00:00
|
|
|
&& (tmpPlayer->checkMyAction(
|
2012-09-18 15:57:58 +02:00
|
|
|
netMyAction->myaction(),
|
|
|
|
|
netMyAction->myrelativebet(),
|
2011-02-11 20:02:08 +00:00
|
|
|
curGame.getCurrentHand()->getCurrentBeRo()->getHighestSet(),
|
|
|
|
|
curGame.getCurrentHand()->getCurrentBeRo()->getMinimumRaise(),
|
|
|
|
|
curGame.getCurrentHand()->getSmallBlind()) != 0)) {
|
2007-10-18 17:40:12 +00:00
|
|
|
code = ACTION_CODE_NOT_ALLOWED;
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-11 20:02:08 +00:00
|
|
|
if (code == ACTION_CODE_VALID) {
|
2011-12-16 22:39:24 +00:00
|
|
|
tmpPlayer->setIsSessionActive(true);
|
|
|
|
|
tmpPlayer->markRemoteAction();
|
2012-09-18 15:57:58 +02:00
|
|
|
PerformPlayerAction(*server, tmpPlayer, static_cast<PlayerAction>(netMyAction->myaction()), netMyAction->myrelativebet());
|
2009-06-12 15:48:34 +00:00
|
|
|
server->SetState(ServerGameStateHand::Instance());
|
2011-02-11 20:02:08 +00:00
|
|
|
} else {
|
2007-10-18 17:40:12 +00:00
|
|
|
// Send reject message.
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> reject(new NetPacket);
|
|
|
|
|
reject->GetMsg()->set_messagetype(PokerTHMessage::Type_YourActionRejectedMessage);
|
|
|
|
|
YourActionRejectedMessage *netActionRejected = reject->GetMsg()->mutable_youractionrejectedmessage();
|
|
|
|
|
netActionRejected->set_gameid(server->GetId());
|
|
|
|
|
netActionRejected->set_gamestate(netMyAction->gamestate());
|
|
|
|
|
netActionRejected->set_youraction(netMyAction->myaction());
|
|
|
|
|
netActionRejected->set_yourrelativebet(netMyAction->myrelativebet());
|
|
|
|
|
netActionRejected->set_rejectionreason(static_cast<YourActionRejectedMessage::RejectionReason>(code));
|
2011-03-10 20:55:46 +00:00
|
|
|
server->GetLobbyThread().GetSender().Send(session, reject);
|
2007-10-18 17:40:12 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2009-06-12 15:48:34 +00:00
|
|
|
ServerGameStateWaitPlayerAction::TimerTimeout(const boost::system::error_code &ec, boost::shared_ptr<ServerGame> server)
|
2007-10-18 17:40:12 +00:00
|
|
|
{
|
2011-02-11 20:02:08 +00:00
|
|
|
if (!ec && &server->GetState() == this) {
|
|
|
|
|
try {
|
2009-06-19 20:48:57 +00:00
|
|
|
Game &curGame = server->GetGame();
|
|
|
|
|
// Retrieve current player.
|
|
|
|
|
boost::shared_ptr<PlayerInterface> curPlayer = curGame.getCurrentPlayer();
|
2010-09-05 14:33:34 +00:00
|
|
|
if (!curPlayer)
|
2009-06-19 20:48:57 +00:00
|
|
|
throw ServerException(__FILE__, __LINE__, ERR_NET_NO_CURRENT_PLAYER, 0);
|
2007-10-18 17:40:12 +00:00
|
|
|
|
2009-06-19 20:48:57 +00:00
|
|
|
// Player did not act fast enough. Act for him.
|
|
|
|
|
if (curGame.getCurrentHand()->getCurrentBeRo()->getHighestSet() == curPlayer->getMySet())
|
|
|
|
|
PerformPlayerAction(*server, curPlayer, PLAYER_ACTION_CHECK, 0);
|
|
|
|
|
else
|
|
|
|
|
PerformPlayerAction(*server, curPlayer, PLAYER_ACTION_FOLD, 0);
|
2007-10-18 17:40:12 +00:00
|
|
|
|
2009-06-19 20:48:57 +00:00
|
|
|
server->SetState(ServerGameStateHand::Instance());
|
2011-02-11 20:02:08 +00:00
|
|
|
} catch (const PokerTHException &e) {
|
2009-07-12 21:12:55 +00:00
|
|
|
LOG_ERROR("Game " << server->GetId() << " - Player timer exception: " << e.what());
|
2009-06-19 20:48:57 +00:00
|
|
|
server->RemoveAllSessions(); // Close this game on error.
|
|
|
|
|
}
|
2009-06-12 15:48:34 +00:00
|
|
|
}
|
2007-10-18 17:40:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
2010-07-15 21:55:52 +00:00
|
|
|
|
|
|
|
|
ServerGameStateWaitNextHand ServerGameStateWaitNextHand::s_state;
|
|
|
|
|
|
|
|
|
|
ServerGameStateWaitNextHand &
|
|
|
|
|
ServerGameStateWaitNextHand::Instance()
|
|
|
|
|
{
|
|
|
|
|
return s_state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ServerGameStateWaitNextHand::ServerGameStateWaitNextHand()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ServerGameStateWaitNextHand::~ServerGameStateWaitNextHand()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerGameStateWaitNextHand::Enter(boost::shared_ptr<ServerGame> server)
|
|
|
|
|
{
|
2011-02-11 12:59:42 +00:00
|
|
|
#ifdef POKERTH_SERVER_TEST
|
2010-07-15 21:55:52 +00:00
|
|
|
int timeoutSec = 0;
|
|
|
|
|
#else
|
|
|
|
|
int timeoutSec = server->GetGameData().delayBetweenHandsSec;
|
|
|
|
|
#endif
|
|
|
|
|
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().expires_from_now(
|
2014-03-29 16:13:53 +01:00
|
|
|
seconds(timeoutSec));
|
2010-07-15 21:55:52 +00:00
|
|
|
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().async_wait(
|
2010-07-15 21:55:52 +00:00
|
|
|
boost::bind(
|
|
|
|
|
&ServerGameStateWaitNextHand::TimerTimeout, this, boost::asio::placeholders::error, server));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerGameStateWaitNextHand::Exit(boost::shared_ptr<ServerGame> server)
|
|
|
|
|
{
|
2010-09-04 20:08:40 +00:00
|
|
|
server->GetStateTimer1().cancel();
|
2010-07-15 21:55:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2011-03-10 20:55:46 +00:00
|
|
|
ServerGameStateWaitNextHand::InternalProcessPacket(boost::shared_ptr<ServerGame> server, boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet)
|
2010-07-15 21:55:52 +00:00
|
|
|
{
|
2011-12-27 10:11:15 +00:00
|
|
|
AbstractServerGameStateRunning::InternalProcessPacket(server, session, packet);
|
|
|
|
|
|
2012-09-18 15:57:58 +02:00
|
|
|
if (packet->GetMsg()->messagetype() == PokerTHMessage::Type_ShowMyCardsRequestMessage) {
|
2010-07-17 21:11:12 +00:00
|
|
|
Game &curGame = server->GetGame();
|
2012-09-18 15:57:58 +02:00
|
|
|
boost::shared_ptr<NetPacket> show(new NetPacket);
|
|
|
|
|
show->GetMsg()->set_messagetype(PokerTHMessage::Type_AfterHandShowCardsMessage);
|
2010-07-17 21:11:12 +00:00
|
|
|
|
2012-09-18 15:57:58 +02:00
|
|
|
AfterHandShowCardsMessage *netShowCards = show->GetMsg()->mutable_afterhandshowcardsmessage();
|
2011-03-10 20:55:46 +00:00
|
|
|
boost::shared_ptr<PlayerInterface> tmpPlayer(curGame.getPlayerByUniqueId(session->GetPlayerData()->GetUniqueId()));
|
2011-02-11 20:02:08 +00:00
|
|
|
if (tmpPlayer) {
|
2012-09-18 15:57:58 +02:00
|
|
|
SetPlayerResult(*netShowCards->mutable_playerresult(), tmpPlayer, curGame.getCurrentHand()->getRoundBeforePostRiver());
|
2013-06-29 16:23:10 +02:00
|
|
|
server->SendToAllPlayers(show, SessionData::Game | SessionData::Spectating);
|
2010-07-18 11:11:27 +00:00
|
|
|
}
|
2010-07-15 21:55:52 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ServerGameStateWaitNextHand::TimerTimeout(const boost::system::error_code &ec, boost::shared_ptr<ServerGame> server)
|
|
|
|
|
{
|
2011-02-11 20:02:08 +00:00
|
|
|
if (!ec && &server->GetState() == this) {
|
2010-07-15 21:55:52 +00:00
|
|
|
ServerGameStateHand::StartNewHand(server);
|
|
|
|
|
server->SetState(ServerGameStateHand::Instance());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
2009-06-15 22:34:07 +00:00
|
|
|
ServerGameStateFinal ServerGameStateFinal::s_state;
|
|
|
|
|
|
|
|
|
|
ServerGameStateFinal &
|
|
|
|
|
ServerGameStateFinal::Instance()
|
|
|
|
|
{
|
|
|
|
|
return s_state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|