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
+6 -11
View File
@@ -587,17 +587,9 @@ Server Reply: Player's Action Rejected
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Rejection Reason: Rejection Reason:
0x0001 - Fold makes no sense. 0x0001 - Invalid Game State.
0x0002 - Check not allowed. 0x0002 - Not your turn.
0x0003 - Call not allowed. 0x0003 - Action not allowed.
0x0004 - Bet not allowed.
0x0005 - Raise not allowed.
0x0006 - All in not allowed.
0x0007 - Invalid game state.
0x0008 - Invalid bet for this game state.
0x0009 - Bet too small.
0x0010 - Bet too large.
0xFFFF - Other reason
Server Notification: Deal Flop Cards Server Notification: Deal Flop Cards
@@ -787,6 +779,9 @@ Error Reason:
0x0004 - Init - Invalid Password 0x0004 - Init - Invalid Password
0x0005 - Init - Player Name already in use 0x0005 - Init - Player Name already in use
0x0006 - Init - Invalid Player Name 0x0006 - Init - Invalid Player Name
0x0010 - Avatar - Too large
0x0011 - Avatar - Wrong size
0x0020 - Join Game - Unknown Game
0xFF01 - General Error - Invalid packet 0xFF01 - General Error - Invalid packet
0xFF02 - General Error - Invalid state 0xFF02 - General Error - Invalid state
0xFF03 - General Error - Kicked from the server 0xFF03 - General Error - Kicked from the server
+1 -1
View File
@@ -45,7 +45,7 @@ public:
boost::shared_ptr<AvatarFileState> OpenAvatarFileForChunkRead(const std::string &fileName, unsigned &outFileSize, AvatarFileType &outFileType); boost::shared_ptr<AvatarFileState> OpenAvatarFileForChunkRead(const std::string &fileName, unsigned &outFileSize, AvatarFileType &outFileType);
unsigned ChunkReadAvatarFile(boost::shared_ptr<AvatarFileState> fileState, unsigned char *data, unsigned chunkSize); unsigned ChunkReadAvatarFile(boost::shared_ptr<AvatarFileState> fileState, unsigned char *data, unsigned chunkSize);
bool AvatarFileToNetPackets(const std::string &fileName, unsigned requestId, NetPacketList &packets); int AvatarFileToNetPackets(const std::string &fileName, unsigned requestId, NetPacketList &packets);
bool GetHashForAvatar(const std::string &fileName, MD5Buf &md5buf) const; bool GetHashForAvatar(const std::string &fileName, MD5Buf &md5buf) const;
bool GetAvatarFileName(const MD5Buf &md5buf, std::string &fileName) const; bool GetAvatarFileName(const MD5Buf &md5buf, std::string &fileName) const;
+24 -14
View File
@@ -22,6 +22,7 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/lambda/lambda.hpp> #include <boost/lambda/lambda.hpp>
#include <openssl/md5.h> #include <openssl/md5.h>
#include <net/socket_msg.h>
#include <fstream> #include <fstream>
#include <cstring> #include <cstring>
@@ -52,20 +53,25 @@ AvatarManager::~AvatarManager()
bool bool
AvatarManager::Init(const std::string &dataDir, const std::string &cacheDir) AvatarManager::Init(const std::string &dataDir, const std::string &cacheDir)
{ {
bool retVal = true;
bool tmpRet;
{ {
boost::mutex::scoped_lock lock(m_cacheDirMutex); boost::mutex::scoped_lock lock(m_cacheDirMutex);
m_cacheDir = cacheDir; m_cacheDir = cacheDir;
} }
{ {
boost::mutex::scoped_lock lock(m_avatarsMutex); boost::mutex::scoped_lock lock(m_avatarsMutex);
InternalReadDirectory(dataDir + "gfx/avatars/default/people/", m_avatars); tmpRet = InternalReadDirectory(dataDir + "gfx/avatars/default/people/", m_avatars);
InternalReadDirectory(dataDir + "gfx/avatars/default/misc/", m_avatars); retVal = retVal && tmpRet;
tmpRet = InternalReadDirectory(dataDir + "gfx/avatars/default/misc/", m_avatars);
retVal = retVal && tmpRet;
} }
{ {
boost::mutex::scoped_lock lock(m_cachedAvatarsMutex); boost::mutex::scoped_lock lock(m_cachedAvatarsMutex);
InternalReadDirectory(cacheDir, m_cachedAvatars); tmpRet = InternalReadDirectory(cacheDir, m_cachedAvatars);
retVal = retVal && tmpRet;
} }
return true; // TODO handle errors return retVal;
} }
boost::shared_ptr<AvatarFileState> boost::shared_ptr<AvatarFileState>
@@ -126,10 +132,10 @@ AvatarManager::ChunkReadAvatarFile(boost::shared_ptr<AvatarFileState> fileState,
return retVal; return retVal;
} }
bool int
AvatarManager::AvatarFileToNetPackets(const string &fileName, unsigned requestId, NetPacketList &packets) AvatarManager::AvatarFileToNetPackets(const string &fileName, unsigned requestId, NetPacketList &packets)
{ {
bool retVal = false; int retVal = ERR_NET_INVALID_AVATAR_FILE;
unsigned fileSize; unsigned fileSize;
AvatarFileType fileType; AvatarFileType fileType;
boost::shared_ptr<AvatarFileState> tmpState = OpenAvatarFileForChunkRead(fileName, fileSize, fileType); boost::shared_ptr<AvatarFileState> tmpState = OpenAvatarFileForChunkRead(fileName, fileSize, fileType);
@@ -160,15 +166,19 @@ AvatarManager::AvatarFileToNetPackets(const string &fileName, unsigned requestId
packets.push_back(avatarFile); packets.push_back(avatarFile);
} }
} while (numBytes); } while (numBytes);
// TODO error handling if numBytes != totalBytesRead
boost::shared_ptr<NetPacket> avatarEnd(new NetPacketAvatarEnd); if (fileSize != totalBytesRead)
NetPacketAvatarEnd::Data avatarEndData; retVal = ERR_NET_WRONG_AVATAR_SIZE;
avatarEndData.requestId = requestId; else
static_cast<NetPacketAvatarEnd *>(avatarEnd.get())->SetData(avatarEndData); {
packets.push_back(avatarEnd); boost::shared_ptr<NetPacket> avatarEnd(new NetPacketAvatarEnd);
retVal = true; NetPacketAvatarEnd::Data avatarEndData;
avatarEndData.requestId = requestId;
static_cast<NetPacketAvatarEnd *>(avatarEnd.get())->SetData(avatarEndData);
packets.push_back(avatarEnd);
retVal = 0;
}
} }
// else TODO error handling
return retVal; return retVal;
} }
+8 -8
View File
@@ -994,41 +994,41 @@ void LocalPlayer::action() {
// cout << "playerID in action(): " << (*(actualHand->getCurrentBeRo()->getCurrentPlayersTurnIt()))->getMyID() << endl; // cout << "playerID in action(): " << (*(actualHand->getCurrentBeRo()->getCurrentPlayersTurnIt()))->getMyID() << endl;
} }
int LocalPlayer::checkMyAction(int targetAction, int targetBet, int alreadySet, int myCash, int highestSet, int minimumRaise, int smallBlind) { int LocalPlayer::checkMyAction(int targetAction, int targetBet, int highestSet, int minimumRaise, int smallBlind) {
switch(targetAction) { switch(targetAction) {
case PLAYER_ACTION_FOLD: { case PLAYER_ACTION_FOLD: {
return 0; return 0;
} break; } break;
case PLAYER_ACTION_CHECK: { case PLAYER_ACTION_CHECK: {
if(alreadySet == highestSet) { if(getMySet() == highestSet) {
return 0; return 0;
} }
} break; } break;
case PLAYER_ACTION_CALL: { case PLAYER_ACTION_CALL: {
if(alreadySet < highestSet && targetBet <= myCash) { if(getMySet() < highestSet && targetBet <= getMyCash()) {
// not all in // not all in
if(myCash + alreadySet >= highestSet && targetBet == highestSet - alreadySet) { if(getMyCash() + getMySet() >= highestSet && targetBet == highestSet - getMySet()) {
return 0; return 0;
} }
// all in // all in
if(myCash + alreadySet <= highestSet) { if(getMyCash() + getMySet() <= highestSet) {
return 0; return 0;
} }
} }
} break; } break;
case PLAYER_ACTION_BET: { case PLAYER_ACTION_BET: {
if(highestSet == 0 && targetBet <= myCash && targetBet >= 2*smallBlind) { if(highestSet == 0 && targetBet <= getMyCash() && targetBet >= 2*smallBlind) {
return 0; return 0;
} }
} break; } break;
case PLAYER_ACTION_RAISE: { case PLAYER_ACTION_RAISE: {
if(highestSet > 0 && targetBet >= minimumRaise && targetBet <= myCash) { if(highestSet > 0 && targetBet >= minimumRaise && targetBet <= getMyCash()) {
return 0; return 0;
} }
} break; } break;
case PLAYER_ACTION_ALLIN: { case PLAYER_ACTION_ALLIN: {
if(targetBet == myCash) { if(targetBet == getMyCash()) {
return 0; return 0;
} }
} break; } break;
+1 -1
View File
@@ -151,7 +151,7 @@ public:
void action(); void action();
int checkMyAction(int targetAction, int targetBet, int alreadySet, int myCash, int highestSet, int minimumRaise, int smallBlind); int checkMyAction(int targetAction, int targetBet, int highestSet, int minimumRaise, int smallBlind);
void preflopEngine(); void preflopEngine();
void flopEngine(); void flopEngine();
@@ -395,6 +395,11 @@ ClientPlayer::action()
{ {
} }
int
ClientPlayer::checkMyAction(int /*targetAction*/, int /*targetBet*/, int /*highestSet*/, int /*minimumRaise*/, int /*smallBlind*/)
{
return 0;
}
void void
ClientPlayer::preflopEngine() ClientPlayer::preflopEngine()
+1
View File
@@ -105,6 +105,7 @@ public:
bool getMyWinnerState() const; bool getMyWinnerState() const;
void action(); void action();
int checkMyAction(int targetAction, int targetBet, int highestSet, int minimumRaise, int smallBlind);
void preflopEngine(); void preflopEngine();
void flopEngine(); void flopEngine();
+1
View File
@@ -102,6 +102,7 @@ public:
virtual bool getMyWinnerState() const =0; virtual bool getMyWinnerState() const =0;
virtual void action() =0; virtual void action() =0;
virtual int checkMyAction(int targetAction, int targetBet, int highestSet, int minimumRaise, int smallBlind) = 0;
virtual void preflopEngine() =0; virtual void preflopEngine() =0;
virtual void flopEngine() =0; virtual void flopEngine() =0;
+9
View File
@@ -46,6 +46,15 @@ enum PlayerAction {
PLAYER_ACTION_RAISE, PLAYER_ACTION_RAISE,
PLAYER_ACTION_ALLIN }; PLAYER_ACTION_ALLIN };
enum PlayerActionCode
{
ACTION_CODE_VALID = 0,
ACTION_CODE_INVALID_STATE,
ACTION_CODE_NOT_YOUR_TURN,
ACTION_CODE_NOT_ALLOWED
};
enum Button { enum Button {
BUTTON_NONE = 0, BUTTON_NONE = 0,
BUTTON_DEALER, BUTTON_DEALER,
+7 -6
View File
@@ -555,14 +555,15 @@ ClientStateWaitSession::InternalProcess(ClientThread &client, boost::shared_ptr<
packet->ToNetPacketRetrieveAvatar()->GetData(retrieveAvatarData); packet->ToNetPacketRetrieveAvatar()->GetData(retrieveAvatarData);
NetPacketList tmpList; NetPacketList tmpList;
if (client.GetAvatarManager().AvatarFileToNetPackets( int avatarError = client.GetAvatarManager().AvatarFileToNetPackets(
client.GetContext().GetAvatarFile(), client.GetContext().GetAvatarFile(),
retrieveAvatarData.requestId, retrieveAvatarData.requestId,
tmpList)) tmpList);
{
if (!avatarError)
client.GetSender().SendLowPrio(client.GetContext().GetSocket(), tmpList); client.GetSender().SendLowPrio(client.GetContext().GetSocket(), tmpList);
} else
// TODO handle error throw NetException(avatarError, 0);
} }
return retVal; return retVal;
@@ -716,7 +717,7 @@ ClientStateSynchronizeStart::Process(ClientThread &client)
} }
int 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; 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_INVALID_PASSWORD 0x0004
#define NET_ERR_INIT_PLAYER_NAME_IN_USE 0x0005 #define NET_ERR_INIT_PLAYER_NAME_IN_USE 0x0005
#define NET_ERR_INIT_INVALID_PLAYER_NAME 0x0006 #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_PACKET 0xFF01
#define NET_ERR_GENERAL_INVALID_STATE 0xFF02 #define NET_ERR_GENERAL_INVALID_STATE 0xFF02
#define NET_ERR_GENERAL_PLAYER_KICKED 0xFF03 #define NET_ERR_GENERAL_PLAYER_KICKED 0xFF03
@@ -3200,9 +3203,7 @@ NetPacketPlayersActionRejected::SetData(const NetPacketPlayersActionRejected::Da
tmpData->gameState = htons(inData.gameState); tmpData->gameState = htons(inData.gameState);
tmpData->playerAction = htons(inData.playerAction); tmpData->playerAction = htons(inData.playerAction);
tmpData->playerBet = htonl(inData.playerBet); tmpData->playerBet = htonl(inData.playerBet);
tmpData->rejectionReason = htons(inData.rejectionReason);
// TODO: set rejection reason
tmpData->rejectionReason = htons(0);
// Check the packet - just in case. // Check the packet - just in case.
Check(GetRawData()); Check(GetRawData());
@@ -3216,8 +3217,7 @@ NetPacketPlayersActionRejected::GetData(NetPacketPlayersActionRejected::Data &ou
outData.gameState = static_cast<GameState>(ntohs(tmpData->gameState)); outData.gameState = static_cast<GameState>(ntohs(tmpData->gameState));
outData.playerAction = static_cast<PlayerAction>(ntohs(tmpData->playerAction)); outData.playerAction = static_cast<PlayerAction>(ntohs(tmpData->playerAction));
outData.playerBet = ntohl(tmpData->playerBet); outData.playerBet = ntohl(tmpData->playerBet);
outData.rejectionReason = static_cast<PlayerActionCode>(ntohs(tmpData->rejectionReason));
// TODO: set rejection reason
} }
const NetPacketPlayersActionRejected * const NetPacketPlayersActionRejected *
@@ -3240,7 +3240,10 @@ NetPacketPlayersActionRejected::InternalCheck(const NetPacketHeader* data) const
{ {
throw NetException(ERR_SOCK_INVALID_PACKET, 0); 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 : case ERR_NET_INVALID_PLAYER_NAME :
tmpData->errorReason = htons(NET_ERR_INIT_INVALID_PLAYER_NAME); tmpData->errorReason = htons(NET_ERR_INIT_INVALID_PLAYER_NAME);
break; 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 : case ERR_SOCK_INVALID_PACKET :
tmpData->errorReason = htons(NET_ERR_GENERAL_INVALID_PACKET); tmpData->errorReason = htons(NET_ERR_GENERAL_INVALID_PACKET);
break; break;
@@ -4139,6 +4152,16 @@ NetPacketError::GetData(NetPacketError::Data &outData) const
case NET_ERR_INIT_INVALID_PLAYER_NAME : case NET_ERR_INIT_INVALID_PLAYER_NAME :
outData.errorCode = ERR_NET_INVALID_PLAYER_NAME; outData.errorCode = ERR_NET_INVALID_PLAYER_NAME;
break; 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. // General Errors.
case NET_ERR_GENERAL_INVALID_PACKET : case NET_ERR_GENERAL_INVALID_PACKET :
outData.errorCode = ERR_SOCK_INVALID_PACKET; outData.errorCode = ERR_SOCK_INVALID_PACKET;
+57 -18
View File
@@ -683,8 +683,10 @@ ServerGameStateStartRound::Process(ServerGameThread &server)
// Retrieve current player. // Retrieve current player.
boost::shared_ptr<PlayerInterface> curPlayer = curGame.getCurrentPlayer(); boost::shared_ptr<PlayerInterface> curPlayer = curGame.getCurrentPlayer();
assert(curPlayer.get()); // TODO throw exception if (!curPlayer.get())
assert(curPlayer->getMyActiveStatus()); // TODO throw exception 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); boost::shared_ptr<NetPacket> notification(new NetPacketPlayersTurn);
NetPacketPlayersTurn::Data playersTurnData; 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. // Retrieve non-fold players. If only one player is left, no cards are shown.
list<boost::shared_ptr<PlayerInterface> > nonFoldPlayers = *curGame.getActivePlayerList(); list<boost::shared_ptr<PlayerInterface> > nonFoldPlayers = *curGame.getActivePlayerList();
nonFoldPlayers.remove_if(boost::bind(&PlayerInterface::getMyAction, _1) == PLAYER_ACTION_FOLD); nonFoldPlayers.remove_if(boost::bind(&PlayerInterface::getMyAction, _1) == PLAYER_ACTION_FOLD);
// if (nonFoldPlayers.empty()) TODO throw exception
if (nonFoldPlayers.size() == 1) if (nonFoldPlayers.size() == 1)
{ {
@@ -813,20 +814,20 @@ ServerGameStateWaitPlayerAction::Process(ServerGameThread &server)
{ {
int retVal; int retVal;
boost::shared_ptr<PlayerInterface> tmpPlayer = server.GetGame().getCurrentPlayer(); boost::shared_ptr<PlayerInterface> curPlayer = server.GetGame().getCurrentPlayer();
assert(tmpPlayer.get()); if (!curPlayer.get())
assert(!tmpPlayer->getMyName().empty()); throw NetException(ERR_NET_NO_CURRENT_PLAYER, 0);
// If the player is computer controlled, let the engine act. // 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()); server.SetState(ServerGameStateComputerAction::Instance());
retVal = MSG_SOCK_INTERNAL_PENDING; retVal = MSG_SOCK_INTERNAL_PENDING;
} }
// If the player we are waiting for left, continue without him. // 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()); server.SetState(ServerGameStateStartRound::Instance());
retVal = MSG_NET_GAME_SERVER_ACTION; 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) else if (GetTimer().elapsed().total_seconds() >= server.GetGameData().playerActionTimeoutSec + SERVER_PLAYER_TIMEOUT_ADD_DELAY_SEC)
{ {
// Player did not act fast enough. Act for him. // Player did not act fast enough. Act for him.
if (server.GetGame().getCurrentHand()->getCurrentBeRo()->getHighestSet() == tmpPlayer->getMySet()) if (server.GetGame().getCurrentHand()->getCurrentBeRo()->getHighestSet() == curPlayer->getMySet())
PerformPlayerAction(server, tmpPlayer, PLAYER_ACTION_CHECK, 0); PerformPlayerAction(server, curPlayer, PLAYER_ACTION_CHECK, 0);
else else
PerformPlayerAction(server, tmpPlayer, PLAYER_ACTION_FOLD, 0); PerformPlayerAction(server, curPlayer, PLAYER_ACTION_FOLD, 0);
server.SetState(ServerGameStateStartRound::Instance()); server.SetState(ServerGameStateStartRound::Instance());
retVal = MSG_NET_GAME_SERVER_ACTION; retVal = MSG_NET_GAME_SERVER_ACTION;
@@ -860,14 +861,52 @@ ServerGameStateWaitPlayerAction::InternalProcess(ServerGameThread &server, Sessi
Game &curGame = server.GetGame(); Game &curGame = server.GetGame();
boost::shared_ptr<PlayerInterface> tmpPlayer = curGame.getPlayerByUniqueId(session.playerData->GetUniqueId()); boost::shared_ptr<PlayerInterface> tmpPlayer = curGame.getPlayerByUniqueId(session.playerData->GetUniqueId());
assert(tmpPlayer.get()); // TODO throw exception if (!tmpPlayer.get())
// TODO: check whether this is the correct player throw NetException(ERR_NET_UNKNOWN_PLAYER_ID, 0);
// TODO: check game state
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()); // Check whether this is the correct player.
retVal = MSG_NET_GAME_SERVER_ACTION; 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; return retVal;
+6 -3
View File
@@ -414,7 +414,8 @@ ServerLobbyThread::HandleNetPacketAvatarHeader(SessionWrapper session, const Net
// Session is now receiving an avatar. // Session is now receiving an avatar.
session.sessionData->SetState(SessionData::ReceivingAvatar); 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 void
ServerLobbyThread::HandleNetPacketAvatarEnd(SessionWrapper session, const NetPacketAvatarEnd &tmpPacket) ServerLobbyThread::HandleNetPacketAvatarEnd(SessionWrapper session, const NetPacketAvatarEnd &/*tmpPacket*/)
{ {
if (session.playerData.get()) if (session.playerData.get())
{ {
@@ -453,7 +454,8 @@ ServerLobbyThread::HandleNetPacketAvatarEnd(SessionWrapper session, const NetPac
// Init finished - start session. // Init finished - start session.
EstablishSession(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; NetPacketList tmpPackets;
if (GetAvatarManager().AvatarFileToNetPackets(tmpFile, request.requestId, tmpPackets)) if (GetAvatarManager().AvatarFileToNetPackets(tmpFile, request.requestId, tmpPackets))
GetSender().SendLowPrio(session.sessionData->GetSocket(), tmpPackets); GetSender().SendLowPrio(session.sessionData->GetSocket(), tmpPackets);
// TODO handle error
} }
} }
+4 -4
View File
@@ -839,10 +839,10 @@ public:
struct Data struct Data
{ {
GameState gameState; GameState gameState;
PlayerAction playerAction; PlayerAction playerAction;
u_int32_t playerBet; u_int32_t playerBet;
int rejectionReason; PlayerActionCode rejectionReason;
}; };
NetPacketPlayersActionRejected(); NetPacketPlayersActionRejected();
+12 -8
View File
@@ -54,14 +54,18 @@
#define ERR_NET_UNKNOWN_GAME 110 #define ERR_NET_UNKNOWN_GAME 110
#define ERR_NET_INVALID_CHAT_TEXT 111 #define ERR_NET_INVALID_CHAT_TEXT 111
#define ERR_NET_UNKNOWN_PLAYER_ID 112 #define ERR_NET_UNKNOWN_PLAYER_ID 112
#define ERR_NET_INVALID_ROUND 113 #define ERR_NET_NO_CURRENT_PLAYER 113
#define ERR_NET_PLAYER_KICKED 114 #define ERR_NET_PLAYER_NOT_ACTIVE 114
#define ERR_NET_INVALID_PLAYER_COUNT 115 #define ERR_NET_INVALID_ROUND 115
#define ERR_NET_TOO_MANY_MANUAL_BLINDS 116 #define ERR_NET_PLAYER_KICKED 116
#define ERR_NET_BUF_INVALID_SIZE 117 #define ERR_NET_INVALID_PLAYER_COUNT 117
#define ERR_NET_INVALID_REQUEST_ID 118 #define ERR_NET_TOO_MANY_MANUAL_BLINDS 118
#define ERR_NET_WRONG_AVATAR_SIZE 119 #define ERR_NET_INVALID_AVATAR_FILE 119
#define ERR_NET_START_TIMEOUT 120 #define ERR_NET_AVATAR_TOO_LARGE 120
#define ERR_NET_BUF_INVALID_SIZE 121
#define ERR_NET_INVALID_REQUEST_ID 122
#define ERR_NET_WRONG_AVATAR_SIZE 123
#define ERR_NET_START_TIMEOUT 124
#define ERR_IRC_INTERNAL 151 #define ERR_IRC_INTERNAL 151
#define ERR_IRC_CONNECT_FAILED 152 #define ERR_IRC_CONNECT_FAILED 152