Added error handling for networking stuff. Now checking the player action.
This commit is contained in:
@@ -555,14 +555,15 @@ ClientStateWaitSession::InternalProcess(ClientThread &client, boost::shared_ptr<
|
||||
packet->ToNetPacketRetrieveAvatar()->GetData(retrieveAvatarData);
|
||||
|
||||
NetPacketList tmpList;
|
||||
if (client.GetAvatarManager().AvatarFileToNetPackets(
|
||||
int avatarError = client.GetAvatarManager().AvatarFileToNetPackets(
|
||||
client.GetContext().GetAvatarFile(),
|
||||
retrieveAvatarData.requestId,
|
||||
tmpList))
|
||||
{
|
||||
tmpList);
|
||||
|
||||
if (!avatarError)
|
||||
client.GetSender().SendLowPrio(client.GetContext().GetSocket(), tmpList);
|
||||
}
|
||||
// TODO handle error
|
||||
else
|
||||
throw NetException(avatarError, 0);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
@@ -716,7 +717,7 @@ ClientStateSynchronizeStart::Process(ClientThread &client)
|
||||
}
|
||||
|
||||
int
|
||||
ClientStateSynchronizeStart::InternalProcess(ClientThread &client, boost::shared_ptr<NetPacket> packet)
|
||||
ClientStateSynchronizeStart::InternalProcess(ClientThread &/*client*/, boost::shared_ptr<NetPacket> packet)
|
||||
{
|
||||
int retVal = MSG_SOCK_INTERNAL_PENDING;
|
||||
|
||||
|
||||
@@ -100,6 +100,9 @@ using namespace std;
|
||||
#define NET_ERR_INIT_INVALID_PASSWORD 0x0004
|
||||
#define NET_ERR_INIT_PLAYER_NAME_IN_USE 0x0005
|
||||
#define NET_ERR_INIT_INVALID_PLAYER_NAME 0x0006
|
||||
#define NET_ERR_AVATAR_TOO_LARGE 0x0010
|
||||
#define NET_ERR_AVATAR_WRONG_SIZE 0x0011
|
||||
#define NET_ERR_JOIN_GAME_UNKNOWN_GAME 0x0020
|
||||
#define NET_ERR_GENERAL_INVALID_PACKET 0xFF01
|
||||
#define NET_ERR_GENERAL_INVALID_STATE 0xFF02
|
||||
#define NET_ERR_GENERAL_PLAYER_KICKED 0xFF03
|
||||
@@ -3200,9 +3203,7 @@ NetPacketPlayersActionRejected::SetData(const NetPacketPlayersActionRejected::Da
|
||||
tmpData->gameState = htons(inData.gameState);
|
||||
tmpData->playerAction = htons(inData.playerAction);
|
||||
tmpData->playerBet = htonl(inData.playerBet);
|
||||
|
||||
// TODO: set rejection reason
|
||||
tmpData->rejectionReason = htons(0);
|
||||
tmpData->rejectionReason = htons(inData.rejectionReason);
|
||||
|
||||
// Check the packet - just in case.
|
||||
Check(GetRawData());
|
||||
@@ -3216,8 +3217,7 @@ NetPacketPlayersActionRejected::GetData(NetPacketPlayersActionRejected::Data &ou
|
||||
outData.gameState = static_cast<GameState>(ntohs(tmpData->gameState));
|
||||
outData.playerAction = static_cast<PlayerAction>(ntohs(tmpData->playerAction));
|
||||
outData.playerBet = ntohl(tmpData->playerBet);
|
||||
|
||||
// TODO: set rejection reason
|
||||
outData.rejectionReason = static_cast<PlayerActionCode>(ntohs(tmpData->rejectionReason));
|
||||
}
|
||||
|
||||
const NetPacketPlayersActionRejected *
|
||||
@@ -3240,7 +3240,10 @@ NetPacketPlayersActionRejected::InternalCheck(const NetPacketHeader* data) const
|
||||
{
|
||||
throw NetException(ERR_SOCK_INVALID_PACKET, 0);
|
||||
}
|
||||
// TODO: check rejection reason
|
||||
if (!ntohs(tmpData->rejectionReason))
|
||||
{
|
||||
throw NetException(ERR_SOCK_INVALID_PACKET, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -4097,7 +4100,17 @@ NetPacketError::SetData(const NetPacketError::Data &inData)
|
||||
case ERR_NET_INVALID_PLAYER_NAME :
|
||||
tmpData->errorReason = htons(NET_ERR_INIT_INVALID_PLAYER_NAME);
|
||||
break;
|
||||
// General Errors.
|
||||
case ERR_NET_AVATAR_TOO_LARGE :
|
||||
tmpData->errorReason = htons(NET_ERR_AVATAR_TOO_LARGE);
|
||||
break;
|
||||
case ERR_NET_WRONG_AVATAR_SIZE :
|
||||
tmpData->errorReason = htons(NET_ERR_AVATAR_WRONG_SIZE);
|
||||
break;
|
||||
case ERR_NET_UNKNOWN_GAME :
|
||||
tmpData->errorReason = htons(NET_ERR_JOIN_GAME_UNKNOWN_GAME);
|
||||
break;
|
||||
|
||||
// General Errors.
|
||||
case ERR_SOCK_INVALID_PACKET :
|
||||
tmpData->errorReason = htons(NET_ERR_GENERAL_INVALID_PACKET);
|
||||
break;
|
||||
@@ -4139,6 +4152,16 @@ NetPacketError::GetData(NetPacketError::Data &outData) const
|
||||
case NET_ERR_INIT_INVALID_PLAYER_NAME :
|
||||
outData.errorCode = ERR_NET_INVALID_PLAYER_NAME;
|
||||
break;
|
||||
case NET_ERR_AVATAR_TOO_LARGE :
|
||||
outData.errorCode = ERR_NET_AVATAR_TOO_LARGE;
|
||||
break;
|
||||
case NET_ERR_AVATAR_WRONG_SIZE :
|
||||
outData.errorCode = ERR_NET_WRONG_AVATAR_SIZE;
|
||||
break;
|
||||
case NET_ERR_JOIN_GAME_UNKNOWN_GAME :
|
||||
outData.errorCode = ERR_NET_UNKNOWN_GAME;
|
||||
break;
|
||||
|
||||
// General Errors.
|
||||
case NET_ERR_GENERAL_INVALID_PACKET :
|
||||
outData.errorCode = ERR_SOCK_INVALID_PACKET;
|
||||
|
||||
@@ -683,8 +683,10 @@ ServerGameStateStartRound::Process(ServerGameThread &server)
|
||||
|
||||
// Retrieve current player.
|
||||
boost::shared_ptr<PlayerInterface> curPlayer = curGame.getCurrentPlayer();
|
||||
assert(curPlayer.get()); // TODO throw exception
|
||||
assert(curPlayer->getMyActiveStatus()); // TODO throw exception
|
||||
if (!curPlayer.get())
|
||||
throw NetException(ERR_NET_NO_CURRENT_PLAYER, 0);
|
||||
if (!curPlayer->getMyActiveStatus())
|
||||
throw NetException(ERR_NET_PLAYER_NOT_ACTIVE, 0);
|
||||
|
||||
boost::shared_ptr<NetPacket> notification(new NetPacketPlayersTurn);
|
||||
NetPacketPlayersTurn::Data playersTurnData;
|
||||
@@ -707,7 +709,6 @@ ServerGameStateStartRound::Process(ServerGameThread &server)
|
||||
// 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 (nonFoldPlayers.empty()) TODO throw exception
|
||||
|
||||
if (nonFoldPlayers.size() == 1)
|
||||
{
|
||||
@@ -813,20 +814,20 @@ ServerGameStateWaitPlayerAction::Process(ServerGameThread &server)
|
||||
{
|
||||
int retVal;
|
||||
|
||||
boost::shared_ptr<PlayerInterface> tmpPlayer = server.GetGame().getCurrentPlayer();
|
||||
assert(tmpPlayer.get());
|
||||
assert(!tmpPlayer->getMyName().empty());
|
||||
boost::shared_ptr<PlayerInterface> curPlayer = server.GetGame().getCurrentPlayer();
|
||||
if (!curPlayer.get())
|
||||
throw NetException(ERR_NET_NO_CURRENT_PLAYER, 0);
|
||||
|
||||
// If the player is computer controlled, let the engine act.
|
||||
if (tmpPlayer->getMyType() == PLAYER_TYPE_COMPUTER)
|
||||
if (curPlayer->getMyType() == PLAYER_TYPE_COMPUTER)
|
||||
{
|
||||
server.SetState(ServerGameStateComputerAction::Instance());
|
||||
retVal = MSG_SOCK_INTERNAL_PENDING;
|
||||
}
|
||||
// If the player we are waiting for left, continue without him.
|
||||
else if (!server.GetSessionManager().IsPlayerConnected(tmpPlayer->getMyName()))
|
||||
else if (!server.GetSessionManager().IsPlayerConnected(curPlayer->getMyName()))
|
||||
{
|
||||
PerformPlayerAction(server, tmpPlayer, PLAYER_ACTION_FOLD, 0);
|
||||
PerformPlayerAction(server, curPlayer, PLAYER_ACTION_FOLD, 0);
|
||||
|
||||
server.SetState(ServerGameStateStartRound::Instance());
|
||||
retVal = MSG_NET_GAME_SERVER_ACTION;
|
||||
@@ -834,10 +835,10 @@ ServerGameStateWaitPlayerAction::Process(ServerGameThread &server)
|
||||
else if (GetTimer().elapsed().total_seconds() >= server.GetGameData().playerActionTimeoutSec + SERVER_PLAYER_TIMEOUT_ADD_DELAY_SEC)
|
||||
{
|
||||
// Player did not act fast enough. Act for him.
|
||||
if (server.GetGame().getCurrentHand()->getCurrentBeRo()->getHighestSet() == tmpPlayer->getMySet())
|
||||
PerformPlayerAction(server, tmpPlayer, PLAYER_ACTION_CHECK, 0);
|
||||
if (server.GetGame().getCurrentHand()->getCurrentBeRo()->getHighestSet() == curPlayer->getMySet())
|
||||
PerformPlayerAction(server, curPlayer, PLAYER_ACTION_CHECK, 0);
|
||||
else
|
||||
PerformPlayerAction(server, tmpPlayer, PLAYER_ACTION_FOLD, 0);
|
||||
PerformPlayerAction(server, curPlayer, PLAYER_ACTION_FOLD, 0);
|
||||
|
||||
server.SetState(ServerGameStateStartRound::Instance());
|
||||
retVal = MSG_NET_GAME_SERVER_ACTION;
|
||||
@@ -857,17 +858,55 @@ ServerGameStateWaitPlayerAction::InternalProcess(ServerGameThread &server, Sessi
|
||||
{
|
||||
NetPacketPlayersAction::Data actionData;
|
||||
packet->ToNetPacketPlayersAction()->GetData(actionData);
|
||||
|
||||
|
||||
Game &curGame = server.GetGame();
|
||||
boost::shared_ptr<PlayerInterface> tmpPlayer = curGame.getPlayerByUniqueId(session.playerData->GetUniqueId());
|
||||
assert(tmpPlayer.get()); // TODO throw exception
|
||||
// TODO: check whether this is the correct player
|
||||
// TODO: check game state
|
||||
if (!tmpPlayer.get())
|
||||
throw NetException(ERR_NET_UNKNOWN_PLAYER_ID, 0);
|
||||
|
||||
PerformPlayerAction(server, tmpPlayer, actionData.playerAction, actionData.playerBet);
|
||||
// Check whether this is the correct round.
|
||||
PlayerActionCode code = ACTION_CODE_VALID;
|
||||
if (curGame.getCurrentHand()->getActualRound() != actionData.gameState)
|
||||
code = ACTION_CODE_INVALID_STATE;
|
||||
|
||||
server.SetState(ServerGameStateStartRound::Instance());
|
||||
retVal = MSG_NET_GAME_SERVER_ACTION;
|
||||
// Check whether this is the correct player.
|
||||
boost::shared_ptr<PlayerInterface> curPlayer = server.GetGame().getCurrentPlayer();
|
||||
if (code == ACTION_CODE_VALID
|
||||
&& (curPlayer->getMyUniqueID() != tmpPlayer->getMyUniqueID()))
|
||||
{
|
||||
code = ACTION_CODE_NOT_YOUR_TURN;
|
||||
}
|
||||
|
||||
// Check whether the action is valid.
|
||||
if (code == ACTION_CODE_VALID
|
||||
&& (tmpPlayer->checkMyAction(
|
||||
actionData.playerAction,
|
||||
actionData.playerBet,
|
||||
curGame.getCurrentHand()->getCurrentBeRo()->getHighestSet(),
|
||||
curGame.getCurrentHand()->getCurrentBeRo()->getMinimumRaise(),
|
||||
curGame.getCurrentHand()->getSmallBlind()) != 0))
|
||||
{
|
||||
code = ACTION_CODE_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
if (code == ACTION_CODE_VALID)
|
||||
{
|
||||
PerformPlayerAction(server, tmpPlayer, actionData.playerAction, actionData.playerBet);
|
||||
server.SetState(ServerGameStateStartRound::Instance());
|
||||
retVal = MSG_NET_GAME_SERVER_ACTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send reject message.
|
||||
boost::shared_ptr<NetPacket> reject(new NetPacketPlayersActionRejected);
|
||||
NetPacketPlayersActionRejected::Data rejectData;
|
||||
rejectData.gameState = actionData.gameState;
|
||||
rejectData.playerAction = actionData.playerAction;
|
||||
rejectData.playerBet = actionData.playerBet;
|
||||
rejectData.rejectionReason = code;
|
||||
static_cast<NetPacketPlayersActionRejected *>(reject.get())->SetData(rejectData);
|
||||
server.GetSender().Send(session.sessionData->GetSocket(), reject);
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
|
||||
@@ -414,7 +414,8 @@ ServerLobbyThread::HandleNetPacketAvatarHeader(SessionWrapper session, const Net
|
||||
// Session is now receiving an avatar.
|
||||
session.sessionData->SetState(SessionData::ReceivingAvatar);
|
||||
}
|
||||
// TODO error handling
|
||||
else
|
||||
SessionError(session, ERR_NET_AVATAR_TOO_LARGE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,7 +436,7 @@ ServerLobbyThread::HandleNetPacketAvatarFile(SessionWrapper session, const NetPa
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::HandleNetPacketAvatarEnd(SessionWrapper session, const NetPacketAvatarEnd &tmpPacket)
|
||||
ServerLobbyThread::HandleNetPacketAvatarEnd(SessionWrapper session, const NetPacketAvatarEnd &/*tmpPacket*/)
|
||||
{
|
||||
if (session.playerData.get())
|
||||
{
|
||||
@@ -453,7 +454,8 @@ ServerLobbyThread::HandleNetPacketAvatarEnd(SessionWrapper session, const NetPac
|
||||
// Init finished - start session.
|
||||
EstablishSession(session);
|
||||
}
|
||||
// TODO error handling
|
||||
else
|
||||
SessionError(session, ERR_NET_WRONG_AVATAR_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -505,6 +507,7 @@ ServerLobbyThread::HandleNetPacketRetrieveAvatar(SessionWrapper session, const N
|
||||
NetPacketList tmpPackets;
|
||||
if (GetAvatarManager().AvatarFileToNetPackets(tmpFile, request.requestId, tmpPackets))
|
||||
GetSender().SendLowPrio(session.sessionData->GetSocket(), tmpPackets);
|
||||
// TODO handle error
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user