Added error handling for networking stuff. Now checking the player action.

This commit is contained in:
lotodore
2007-10-10 22:21:24 +00:00
parent de0f16a6fc
commit 253778bf30
15 changed files with 176 additions and 85 deletions
+7 -6
View File
@@ -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;
+30 -7
View File
@@ -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;
+58 -19
View File
@@ -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;
+6 -3
View File
@@ -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
}
}