Major redesign: The game can not be left without disconnecting from the server. This happens if a player is kicked, if he wishes to leave, or for other reasons. Error packets from the server will always cause a disconnect, however.
If joining a game fails, there is a proper failure packet now.
This commit is contained in:
@@ -387,6 +387,15 @@ AbstractClientStateReceiving::Process(ClientThread &client)
|
||||
tmpPacket->ToNetPacketPlayerInfo()->GetData(infoData);
|
||||
client.SetPlayerInfo(infoData.playerId, infoData.playerInfo);
|
||||
}
|
||||
else if (tmpPacket->ToNetPacketRemovedFromGame())
|
||||
{
|
||||
NetPacketRemovedFromGame::Data removedData;
|
||||
tmpPacket->ToNetPacketRemovedFromGame()->GetData(removedData);
|
||||
client.ClearPlayerDataList();
|
||||
client.ClearGameInfoMap();
|
||||
client.GetCallback().SignalNetClientRemovedFromGame(removedData.removeReason);
|
||||
client.SetState(ClientStateWaitJoin::Instance());
|
||||
}
|
||||
else if (tmpPacket->ToNetPacketError())
|
||||
{
|
||||
// Server reported an error.
|
||||
@@ -545,6 +554,13 @@ ClientStateWaitJoin::InternalProcess(ClientThread &client, boost::shared_ptr<Net
|
||||
client.SetState(ClientStateWaitGame::Instance());
|
||||
retVal = MSG_NET_GAME_CLIENT_JOIN;
|
||||
}
|
||||
else if (packet->ToNetPacketJoinGameFailed())
|
||||
{
|
||||
// Failed to join a game.
|
||||
NetPacketJoinGameFailed::Data joinGameFailedData;
|
||||
packet->ToNetPacketJoinGameFailed()->GetData(joinGameFailedData);
|
||||
client.GetCallback().SignalNetClientNotification(joinGameFailedData.failureCode);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@@ -97,6 +97,14 @@ ClientThread::SendKickPlayer(unsigned playerId)
|
||||
m_outPacketList.push_back(request);
|
||||
}
|
||||
|
||||
void
|
||||
ClientThread::SendLeaveCurrentGame()
|
||||
{
|
||||
boost::shared_ptr<NetPacket> request(new NetPacketLeaveCurrentGame);
|
||||
boost::mutex::scoped_lock lock(m_outPacketListMutex);
|
||||
m_outPacketList.push_back(request);
|
||||
}
|
||||
|
||||
void
|
||||
ClientThread::SendStartEvent(bool fillUpWithCpuPlayers)
|
||||
{
|
||||
@@ -507,6 +515,12 @@ ClientThread::RemovePlayerData(unsigned playerId)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientThread::ClearPlayerDataList()
|
||||
{
|
||||
m_playerDataList.clear();
|
||||
}
|
||||
|
||||
void
|
||||
ClientThread::MapPlayerDataList()
|
||||
{
|
||||
@@ -692,6 +706,13 @@ ClientThread::ModifyGameInfoRemovePlayer(unsigned gameId, unsigned playerId)
|
||||
GetCallback().SignalNetClientGameListPlayerLeft(gameId, playerId);
|
||||
}
|
||||
|
||||
void
|
||||
ClientThread::ClearGameInfoMap()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_gameInfoMapMutex);
|
||||
m_gameInfoMap.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
ClientThread::IsSessionEstablished() const
|
||||
{
|
||||
|
||||
+315
-48
@@ -38,24 +38,27 @@ using namespace std;
|
||||
#define NET_TYPE_CREATE_GAME 0x0009
|
||||
#define NET_TYPE_JOIN_GAME 0x000A
|
||||
#define NET_TYPE_JOIN_GAME_ACK 0x000B
|
||||
#define NET_TYPE_PLAYER_JOINED 0x000C
|
||||
#define NET_TYPE_PLAYER_LEFT 0x000D
|
||||
#define NET_TYPE_KICK_PLAYER 0x000E
|
||||
#define NET_TYPE_LEAVE_CURRENT_GAME 0x000F
|
||||
#define NET_TYPE_START_EVENT 0x0010
|
||||
#define NET_TYPE_GAME_START 0x0011
|
||||
#define NET_TYPE_HAND_START 0x0012
|
||||
#define NET_TYPE_PLAYERS_TURN 0x0013
|
||||
#define NET_TYPE_PLAYERS_ACTION 0x0014
|
||||
#define NET_TYPE_PLAYERS_ACTION_DONE 0x0015
|
||||
#define NET_TYPE_PLAYERS_ACTION_REJECTED 0x0016
|
||||
#define NET_TYPE_DEAL_FLOP_CARDS 0x0017
|
||||
#define NET_TYPE_DEAL_TURN_CARD 0x0018
|
||||
#define NET_TYPE_DEAL_RIVER_CARD 0x0019
|
||||
#define NET_TYPE_ALL_IN_SHOW_CARDS 0x001A
|
||||
#define NET_TYPE_END_OF_HAND_SHOW_CARDS 0x001B
|
||||
#define NET_TYPE_END_OF_HAND_HIDE_CARDS 0x001C
|
||||
#define NET_TYPE_END_OF_GAME 0x001D
|
||||
#define NET_TYPE_JOIN_GAME_FAILED 0x000C
|
||||
#define NET_TYPE_PLAYER_JOINED 0x000D
|
||||
#define NET_TYPE_PLAYER_LEFT 0x000E
|
||||
#define NET_TYPE_KICK_PLAYER 0x000F
|
||||
#define NET_TYPE_LEAVE_CURRENT_GAME 0x0010
|
||||
#define NET_TYPE_START_EVENT 0x0011
|
||||
#define NET_TYPE_GAME_START 0x0012
|
||||
#define NET_TYPE_HAND_START 0x0013
|
||||
#define NET_TYPE_PLAYERS_TURN 0x0014
|
||||
#define NET_TYPE_PLAYERS_ACTION 0x0015
|
||||
#define NET_TYPE_PLAYERS_ACTION_DONE 0x0016
|
||||
#define NET_TYPE_PLAYERS_ACTION_REJECTED 0x0017
|
||||
#define NET_TYPE_DEAL_FLOP_CARDS 0x0018
|
||||
#define NET_TYPE_DEAL_TURN_CARD 0x0019
|
||||
#define NET_TYPE_DEAL_RIVER_CARD 0x001A
|
||||
#define NET_TYPE_ALL_IN_SHOW_CARDS 0x001B
|
||||
#define NET_TYPE_END_OF_HAND_SHOW_CARDS 0x001C
|
||||
#define NET_TYPE_END_OF_HAND_HIDE_CARDS 0x001D
|
||||
#define NET_TYPE_END_OF_GAME 0x001E
|
||||
|
||||
#define NET_TYPE_REMOVED_FROM_GAME 0x0100
|
||||
|
||||
#define NET_TYPE_SEND_CHAT_TEXT 0x0200
|
||||
#define NET_TYPE_CHAT_TEXT 0x0201
|
||||
@@ -69,12 +72,26 @@ using namespace std;
|
||||
|
||||
#define NET_START_FLAG_FILL_WITH_CPU_PLAYERS 0x01
|
||||
|
||||
#define NET_ERR_JOIN_GAME_VERSION_NOT_SUPPORTED 0x0001
|
||||
#define NET_ERR_JOIN_GAME_SERVER_FULL 0x0002
|
||||
#define NET_ERR_JOIN_GAME_ALREADY_RUNNING 0x0003
|
||||
#define NET_ERR_JOIN_GAME_INVALID_PASSWORD 0x0004
|
||||
#define NET_ERR_JOIN_GAME_PLAYER_NAME_IN_USE 0x0005
|
||||
#define NET_ERR_JOIN_GAME_INVALID_PLAYER_NAME 0x0006
|
||||
// Reasons why join game failed.
|
||||
#define NET_JOIN_FAILED_GAME_FULL 0x0001
|
||||
#define NET_JOIN_FAILED_GAME_ALREADY_RUNNING 0x0002
|
||||
#define NET_JOIN_FAILED_INVALID_PASSWORD 0x0003
|
||||
#define NET_JOIN_FAILED_OTHER 0xFFFF
|
||||
|
||||
// Reasons for being removed from a game.
|
||||
#define NET_REMOVED_ON_REQUEST 0x0000
|
||||
#define NET_REMOVED_GAME_FULL 0x0001
|
||||
#define NET_REMOVED_GAME_ALREADY_RUNNING 0x0002
|
||||
#define NET_REMOVED_KICKED 0x0003
|
||||
#define NET_REMOVED_OTHER_REASON 0xFFFF
|
||||
|
||||
// Internal error codes.
|
||||
#define NET_ERR_RESERVED 0x0000
|
||||
#define NET_ERR_INIT_VERSION_NOT_SUPPORTED 0x0001
|
||||
#define NET_ERR_INIT_SERVER_FULL 0x0002
|
||||
#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_GENERAL_INVALID_PACKET 0xFF01
|
||||
#define NET_ERR_GENERAL_INVALID_STATE 0xFF02
|
||||
#define NET_ERR_GENERAL_PLAYER_KICKED 0xFF03
|
||||
@@ -199,6 +216,13 @@ struct GCC_PACKED NetPacketJoinGameAckData
|
||||
u_int32_t startMoney;
|
||||
};
|
||||
|
||||
struct GCC_PACKED NetPacketJoinGameFailedData
|
||||
{
|
||||
NetPacketHeader head;
|
||||
u_int16_t failureReason;
|
||||
u_int16_t reserved;
|
||||
};
|
||||
|
||||
struct GCC_PACKED NetPacketPlayerJoinedData
|
||||
{
|
||||
NetPacketHeader head;
|
||||
@@ -362,6 +386,13 @@ struct GCC_PACKED NetPacketEndOfGameData
|
||||
u_int32_t winnerPlayerId;
|
||||
};
|
||||
|
||||
struct GCC_PACKED NetPacketRemovedFromGameData
|
||||
{
|
||||
NetPacketHeader head;
|
||||
u_int16_t removeReason;
|
||||
u_int16_t reserved;
|
||||
};
|
||||
|
||||
struct GCC_PACKED NetPacketSendChatTextData
|
||||
{
|
||||
NetPacketHeader head;
|
||||
@@ -380,7 +411,7 @@ struct GCC_PACKED NetPacketChatTextData
|
||||
struct GCC_PACKED NetPacketErrorData
|
||||
{
|
||||
NetPacketHeader head;
|
||||
u_int16_t reason;
|
||||
u_int16_t errorReason;
|
||||
u_int16_t reserved;
|
||||
};
|
||||
|
||||
@@ -450,6 +481,9 @@ NetPacket::Create(char *data, unsigned &dataSize)
|
||||
case NET_TYPE_JOIN_GAME_ACK:
|
||||
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketJoinGameAck);
|
||||
break;
|
||||
case NET_TYPE_JOIN_GAME_FAILED:
|
||||
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketJoinGameFailed);
|
||||
break;
|
||||
case NET_TYPE_PLAYER_JOINED:
|
||||
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketPlayerJoined);
|
||||
break;
|
||||
@@ -459,6 +493,9 @@ NetPacket::Create(char *data, unsigned &dataSize)
|
||||
case NET_TYPE_KICK_PLAYER:
|
||||
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketKickPlayer);
|
||||
break;
|
||||
case NET_TYPE_LEAVE_CURRENT_GAME:
|
||||
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketLeaveCurrentGame);
|
||||
break;
|
||||
case NET_TYPE_START_EVENT:
|
||||
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketStartEvent);
|
||||
break;
|
||||
@@ -501,6 +538,9 @@ NetPacket::Create(char *data, unsigned &dataSize)
|
||||
case NET_TYPE_END_OF_GAME:
|
||||
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketEndOfGame);
|
||||
break;
|
||||
case NET_TYPE_REMOVED_FROM_GAME:
|
||||
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketRemovedFromGame);
|
||||
break;
|
||||
case NET_TYPE_SEND_CHAT_TEXT:
|
||||
tmpPacket = boost::shared_ptr<NetPacket>(new NetPacketSendChatText);
|
||||
break;
|
||||
@@ -660,6 +700,12 @@ NetPacket::ToNetPacketJoinGameAck() const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const NetPacketJoinGameFailed *
|
||||
NetPacket::ToNetPacketJoinGameFailed() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const NetPacketPlayerJoined *
|
||||
NetPacket::ToNetPacketPlayerJoined() const
|
||||
{
|
||||
@@ -678,6 +724,12 @@ NetPacket::ToNetPacketKickPlayer() const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const NetPacketLeaveCurrentGame *
|
||||
NetPacket::ToNetPacketLeaveCurrentGame() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const NetPacketStartEvent *
|
||||
NetPacket::ToNetPacketStartEvent() const
|
||||
{
|
||||
@@ -762,6 +814,12 @@ NetPacket::ToNetPacketEndOfGame() const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const NetPacketRemovedFromGame *
|
||||
NetPacket::ToNetPacketRemovedFromGame() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const NetPacketSendChatText *
|
||||
NetPacket::ToNetPacketSendChatText() const
|
||||
{
|
||||
@@ -1776,6 +1834,92 @@ NetPacketJoinGameAck::InternalCheck(const NetPacketHeader* data) const
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NetPacketJoinGameFailed::NetPacketJoinGameFailed()
|
||||
: NetPacket(NET_TYPE_JOIN_GAME_FAILED, sizeof(NetPacketJoinGameFailedData), sizeof(NetPacketJoinGameFailedData))
|
||||
{
|
||||
}
|
||||
|
||||
NetPacketJoinGameFailed::~NetPacketJoinGameFailed()
|
||||
{
|
||||
}
|
||||
|
||||
boost::shared_ptr<NetPacket>
|
||||
NetPacketJoinGameFailed::Clone() const
|
||||
{
|
||||
boost::shared_ptr<NetPacket> newPacket(new NetPacketJoinGameFailed);
|
||||
try
|
||||
{
|
||||
newPacket->SetRawData(GetRawData());
|
||||
} catch (const NetException &)
|
||||
{
|
||||
// Need to return the new packet anyway.
|
||||
}
|
||||
return newPacket;
|
||||
}
|
||||
|
||||
void
|
||||
NetPacketJoinGameFailed::SetData(const NetPacketJoinGameFailed::Data &inData)
|
||||
{
|
||||
NetPacketJoinGameFailedData *tmpData = (NetPacketJoinGameFailedData *)GetRawData();
|
||||
|
||||
switch (inData.failureCode)
|
||||
{
|
||||
// Join Game Errors.
|
||||
case NTF_NET_JOIN_GAME_FULL :
|
||||
tmpData->failureReason = htons(NET_JOIN_FAILED_GAME_FULL);
|
||||
break;
|
||||
case NTF_NET_JOIN_ALREADY_RUNNING :
|
||||
tmpData->failureReason = htons(NET_JOIN_FAILED_GAME_ALREADY_RUNNING);
|
||||
break;
|
||||
case NTF_NET_JOIN_INVALID_PASSWORD :
|
||||
tmpData->failureReason = htons(NET_JOIN_FAILED_INVALID_PASSWORD);
|
||||
break;
|
||||
default :
|
||||
tmpData->failureReason = htons(NET_JOIN_FAILED_OTHER);
|
||||
break;
|
||||
}
|
||||
|
||||
// Check the packet - just in case.
|
||||
Check(GetRawData());
|
||||
}
|
||||
|
||||
void
|
||||
NetPacketJoinGameFailed::GetData(NetPacketJoinGameFailed::Data &outData) const
|
||||
{
|
||||
NetPacketJoinGameFailedData *tmpData = (NetPacketJoinGameFailedData *)GetRawData();
|
||||
|
||||
switch (ntohs(tmpData->failureReason))
|
||||
{
|
||||
// Join Game Errors.
|
||||
case NET_JOIN_FAILED_GAME_FULL :
|
||||
outData.failureCode = NTF_NET_JOIN_GAME_FULL;
|
||||
break;
|
||||
case NET_JOIN_FAILED_GAME_ALREADY_RUNNING :
|
||||
outData.failureCode = NTF_NET_JOIN_ALREADY_RUNNING;
|
||||
break;
|
||||
case NET_JOIN_FAILED_INVALID_PASSWORD :
|
||||
outData.failureCode = NTF_NET_JOIN_INVALID_PASSWORD;
|
||||
break;
|
||||
default :
|
||||
outData.failureCode = NTF_NET_INTERNAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const NetPacketJoinGameFailed *
|
||||
NetPacketJoinGameFailed::ToNetPacketJoinGameFailed() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
NetPacketJoinGameFailed::InternalCheck(const NetPacketHeader*) const
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NetPacketPlayerJoined::NetPacketPlayerJoined()
|
||||
: NetPacket(NET_TYPE_PLAYER_JOINED, sizeof(NetPacketPlayerJoinedData), sizeof(NetPacketPlayerJoinedData))
|
||||
{
|
||||
@@ -1952,6 +2096,43 @@ NetPacketKickPlayer::InternalCheck(const NetPacketHeader*) const
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NetPacketLeaveCurrentGame::NetPacketLeaveCurrentGame()
|
||||
: NetPacket(NET_TYPE_LEAVE_CURRENT_GAME, sizeof(NetPacketLeaveCurrentGame), sizeof(NetPacketLeaveCurrentGame))
|
||||
{
|
||||
}
|
||||
|
||||
NetPacketLeaveCurrentGame::~NetPacketLeaveCurrentGame()
|
||||
{
|
||||
}
|
||||
|
||||
boost::shared_ptr<NetPacket>
|
||||
NetPacketLeaveCurrentGame::Clone() const
|
||||
{
|
||||
boost::shared_ptr<NetPacket> newPacket(new NetPacketLeaveCurrentGame);
|
||||
try
|
||||
{
|
||||
newPacket->SetRawData(GetRawData());
|
||||
} catch (const NetException &)
|
||||
{
|
||||
// Need to return the new packet anyway.
|
||||
}
|
||||
return newPacket;
|
||||
}
|
||||
|
||||
const NetPacketLeaveCurrentGame *
|
||||
NetPacketLeaveCurrentGame::ToNetPacketLeaveCurrentGame() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
NetPacketLeaveCurrentGame::InternalCheck(const NetPacketHeader*) const
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NetPacketStartEvent::NetPacketStartEvent()
|
||||
: NetPacket(NET_TYPE_START_EVENT, sizeof(NetPacketStartEventData), sizeof(NetPacketStartEventData))
|
||||
{
|
||||
@@ -3000,6 +3181,97 @@ NetPacketEndOfGame::InternalCheck(const NetPacketHeader*) const
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NetPacketRemovedFromGame::NetPacketRemovedFromGame()
|
||||
: NetPacket(NET_TYPE_REMOVED_FROM_GAME, sizeof(NetPacketRemovedFromGameData), sizeof(NetPacketRemovedFromGameData))
|
||||
{
|
||||
}
|
||||
|
||||
NetPacketRemovedFromGame::~NetPacketRemovedFromGame()
|
||||
{
|
||||
}
|
||||
|
||||
boost::shared_ptr<NetPacket>
|
||||
NetPacketRemovedFromGame::Clone() const
|
||||
{
|
||||
boost::shared_ptr<NetPacket> newPacket(new NetPacketRemovedFromGame);
|
||||
try
|
||||
{
|
||||
newPacket->SetRawData(GetRawData());
|
||||
} catch (const NetException &)
|
||||
{
|
||||
// Need to return the new packet anyway.
|
||||
}
|
||||
return newPacket;
|
||||
}
|
||||
|
||||
void
|
||||
NetPacketRemovedFromGame::SetData(const NetPacketRemovedFromGame::Data &inData)
|
||||
{
|
||||
NetPacketRemovedFromGameData *tmpData = (NetPacketRemovedFromGameData *)GetRawData();
|
||||
|
||||
switch (inData.removeReason)
|
||||
{
|
||||
case NTF_NET_REMOVED_ON_REQUEST :
|
||||
tmpData->removeReason = htons(NET_REMOVED_ON_REQUEST);
|
||||
break;
|
||||
case NTF_NET_REMOVED_GAME_FULL :
|
||||
tmpData->removeReason = htons(NET_REMOVED_GAME_FULL);
|
||||
break;
|
||||
case NTF_NET_REMOVED_ALREADY_RUNNING :
|
||||
tmpData->removeReason = htons(NET_REMOVED_GAME_ALREADY_RUNNING);
|
||||
break;
|
||||
case NTF_NET_REMOVED_KICKED :
|
||||
tmpData->removeReason = htons(NET_REMOVED_KICKED);
|
||||
break;
|
||||
default :
|
||||
tmpData->removeReason = htons(NET_REMOVED_OTHER_REASON);
|
||||
break;
|
||||
}
|
||||
|
||||
// Check the packet - just in case.
|
||||
Check(GetRawData());
|
||||
}
|
||||
|
||||
void
|
||||
NetPacketRemovedFromGame::GetData(NetPacketRemovedFromGame::Data &outData) const
|
||||
{
|
||||
NetPacketRemovedFromGameData *tmpData = (NetPacketRemovedFromGameData *)GetRawData();
|
||||
|
||||
switch (ntohs(tmpData->removeReason))
|
||||
{
|
||||
// Removed Errors.
|
||||
case NET_REMOVED_ON_REQUEST :
|
||||
outData.removeReason = NTF_NET_REMOVED_ON_REQUEST;
|
||||
break;
|
||||
case NET_REMOVED_GAME_FULL :
|
||||
outData.removeReason = NTF_NET_REMOVED_GAME_FULL;
|
||||
break;
|
||||
case NET_REMOVED_GAME_ALREADY_RUNNING :
|
||||
outData.removeReason = NTF_NET_REMOVED_ALREADY_RUNNING;
|
||||
break;
|
||||
case NET_REMOVED_KICKED :
|
||||
outData.removeReason = NTF_NET_REMOVED_KICKED;
|
||||
break;
|
||||
default :
|
||||
outData.removeReason = NTF_NET_INTERNAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const NetPacketRemovedFromGame *
|
||||
NetPacketRemovedFromGame::ToNetPacketRemovedFromGame() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
NetPacketRemovedFromGame::InternalCheck(const NetPacketHeader*) const
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NetPacketSendChatText::NetPacketSendChatText()
|
||||
: NetPacket(NET_TYPE_SEND_CHAT_TEXT, sizeof(NetPacketSendChatTextData), MAX_PACKET_SIZE)
|
||||
{
|
||||
@@ -3176,6 +3448,7 @@ NetPacketChatText::InternalCheck(const NetPacketHeader* data) const
|
||||
}
|
||||
// No more checks required - this packet is sent by the server.
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NetPacketError::NetPacketError()
|
||||
@@ -3208,37 +3481,34 @@ NetPacketError::SetData(const NetPacketError::Data &inData)
|
||||
|
||||
switch (inData.errorCode)
|
||||
{
|
||||
// Join Game Errors.
|
||||
// Init Errors.
|
||||
case ERR_NET_VERSION_NOT_SUPPORTED :
|
||||
tmpData->reason = htons(NET_ERR_JOIN_GAME_VERSION_NOT_SUPPORTED);
|
||||
tmpData->errorReason = htons(NET_ERR_INIT_VERSION_NOT_SUPPORTED);
|
||||
break;
|
||||
case ERR_NET_SERVER_FULL :
|
||||
tmpData->reason = htons(NET_ERR_JOIN_GAME_SERVER_FULL);
|
||||
break;
|
||||
case ERR_NET_GAME_ALREADY_RUNNING :
|
||||
tmpData->reason = htons(NET_ERR_JOIN_GAME_ALREADY_RUNNING);
|
||||
tmpData->errorReason = htons(NET_ERR_INIT_SERVER_FULL);
|
||||
break;
|
||||
case ERR_NET_INVALID_PASSWORD :
|
||||
tmpData->reason = htons(NET_ERR_JOIN_GAME_INVALID_PASSWORD);
|
||||
tmpData->errorReason = htons(NET_ERR_INIT_INVALID_PASSWORD);
|
||||
break;
|
||||
case ERR_NET_PLAYER_NAME_IN_USE :
|
||||
tmpData->reason = htons(NET_ERR_JOIN_GAME_PLAYER_NAME_IN_USE);
|
||||
tmpData->errorReason = htons(NET_ERR_INIT_PLAYER_NAME_IN_USE);
|
||||
break;
|
||||
case ERR_NET_INVALID_PLAYER_NAME :
|
||||
tmpData->reason = htons(NET_ERR_JOIN_GAME_INVALID_PLAYER_NAME);
|
||||
tmpData->errorReason = htons(NET_ERR_INIT_INVALID_PLAYER_NAME);
|
||||
break;
|
||||
// General Errors.
|
||||
case ERR_SOCK_INVALID_PACKET :
|
||||
tmpData->reason = htons(NET_ERR_GENERAL_INVALID_PACKET);
|
||||
tmpData->errorReason = htons(NET_ERR_GENERAL_INVALID_PACKET);
|
||||
break;
|
||||
case ERR_SOCK_INVALID_STATE :
|
||||
tmpData->reason = htons(NET_ERR_GENERAL_INVALID_STATE);
|
||||
tmpData->errorReason = htons(NET_ERR_GENERAL_INVALID_STATE);
|
||||
break;
|
||||
case ERR_NET_PLAYER_KICKED :
|
||||
tmpData->reason = htons(NET_ERR_GENERAL_PLAYER_KICKED);
|
||||
tmpData->errorReason = htons(NET_ERR_GENERAL_PLAYER_KICKED);
|
||||
break;
|
||||
default :
|
||||
tmpData->reason = htons(NET_ERR_OTHER);
|
||||
tmpData->errorReason = htons(NET_ERR_OTHER);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3251,25 +3521,22 @@ NetPacketError::GetData(NetPacketError::Data &outData) const
|
||||
{
|
||||
NetPacketErrorData *tmpData = (NetPacketErrorData *)GetRawData();
|
||||
|
||||
switch (ntohs(tmpData->reason))
|
||||
switch (ntohs(tmpData->errorReason))
|
||||
{
|
||||
// Join Game Errors.
|
||||
case NET_ERR_JOIN_GAME_VERSION_NOT_SUPPORTED :
|
||||
// Init Errors.
|
||||
case NET_ERR_INIT_VERSION_NOT_SUPPORTED :
|
||||
outData.errorCode = ERR_NET_VERSION_NOT_SUPPORTED;
|
||||
break;
|
||||
case NET_ERR_JOIN_GAME_SERVER_FULL :
|
||||
case NET_ERR_INIT_SERVER_FULL :
|
||||
outData.errorCode = ERR_NET_SERVER_FULL;
|
||||
break;
|
||||
case NET_ERR_JOIN_GAME_ALREADY_RUNNING :
|
||||
outData.errorCode = ERR_NET_GAME_ALREADY_RUNNING;
|
||||
break;
|
||||
case NET_ERR_JOIN_GAME_INVALID_PASSWORD :
|
||||
case NET_ERR_INIT_INVALID_PASSWORD :
|
||||
outData.errorCode = ERR_NET_INVALID_PASSWORD;
|
||||
break;
|
||||
case NET_ERR_JOIN_GAME_PLAYER_NAME_IN_USE :
|
||||
case NET_ERR_INIT_PLAYER_NAME_IN_USE :
|
||||
outData.errorCode = ERR_NET_PLAYER_NAME_IN_USE;
|
||||
break;
|
||||
case NET_ERR_JOIN_GAME_INVALID_PLAYER_NAME :
|
||||
case NET_ERR_INIT_INVALID_PLAYER_NAME :
|
||||
outData.errorCode = ERR_NET_INVALID_PLAYER_NAME;
|
||||
break;
|
||||
// General Errors.
|
||||
|
||||
@@ -142,7 +142,7 @@ AbstractServerGameStateReceiving::Process(ServerGameThread &server)
|
||||
packet = server.GetReceiver().Recv(session.sessionData->GetSocket(), session.sessionData->GetReceiveBuffer());
|
||||
} catch (const NetException &)
|
||||
{
|
||||
server.CloseSessionDelayed(session);
|
||||
server.RemoveSession(session);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@@ -167,6 +167,10 @@ AbstractServerGameStateReceiving::Process(ServerGameThread &server)
|
||||
server.GetSender().Send(session.sessionData->GetSocket(), info);
|
||||
}
|
||||
}
|
||||
else if (packet->ToNetPacketLeaveCurrentGame())
|
||||
{
|
||||
server.MoveSessionToLobby(session, NTF_NET_REMOVED_ON_REQUEST);
|
||||
}
|
||||
// Chat text is always allowed.
|
||||
else if (packet->ToNetPacketSendChatText())
|
||||
{
|
||||
@@ -243,7 +247,7 @@ ServerGameStateInit::HandleNewSession(ServerGameThread &server, SessionWrapper s
|
||||
// Check the number of players.
|
||||
if (curNumPlayers >= (size_t)server.GetGameData().maxNumberOfPlayers)
|
||||
{
|
||||
server.SessionError(session, ERR_NET_SERVER_FULL);
|
||||
server.MoveSessionToLobby(session, NTF_NET_REMOVED_GAME_FULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -359,7 +363,7 @@ void
|
||||
AbstractServerGameStateRunning::HandleNewSession(ServerGameThread &server, SessionWrapper session)
|
||||
{
|
||||
// Do not accept new sessions in this state.
|
||||
server.SessionError(session, ERR_NET_GAME_ALREADY_RUNNING);
|
||||
server.MoveSessionToLobby(session, NTF_NET_REMOVED_ALREADY_RUNNING);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -185,7 +185,7 @@ void
|
||||
ServerGameThread::InternalKickPlayer(unsigned playerId)
|
||||
{
|
||||
SessionWrapper tmpSession = GetSessionManager().GetSessionByUniquePlayerId(playerId);
|
||||
SessionError(tmpSession, ERR_NET_PLAYER_KICKED);
|
||||
MoveSessionToLobby(tmpSession, NTF_NET_REMOVED_KICKED);
|
||||
}
|
||||
|
||||
PlayerDataList
|
||||
@@ -262,18 +262,9 @@ ServerGameThread::ResetComputerPlayerList()
|
||||
}
|
||||
|
||||
void
|
||||
ServerGameThread::SessionError(SessionWrapper session, int errorCode)
|
||||
{
|
||||
if (session.sessionData.get())
|
||||
{
|
||||
SendError(session.sessionData->GetSocket(), errorCode);
|
||||
CloseSessionDelayed(session);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServerGameThread::CloseSessionDelayed(SessionWrapper session)
|
||||
ServerGameThread::RemoveSession(SessionWrapper session)
|
||||
{
|
||||
assert(session.sessionData.get());
|
||||
GetSessionManager().RemoveSession(session.sessionData->GetSocket());
|
||||
|
||||
boost::shared_ptr<PlayerData> tmpPlayerData = session.playerData;
|
||||
@@ -285,26 +276,24 @@ ServerGameThread::CloseSessionDelayed(SessionWrapper session)
|
||||
thisPlayerLeftData.playerId = tmpPlayerData->GetUniqueId();
|
||||
static_cast<NetPacketPlayerLeft *>(thisPlayerLeft.get())->SetData(thisPlayerLeftData);
|
||||
GetSessionManager().SendToAllSessions(GetSender(), thisPlayerLeft, SessionData::Game);
|
||||
|
||||
GetLobbyThread().NotifyPlayerLeftGame(GetId(), session.playerData->GetUniqueId());
|
||||
}
|
||||
|
||||
GetLobbyThread().CloseSessionDelayed(session);
|
||||
GetLobbyThread().NotifyPlayerLeftGame(GetId(), session.playerData->GetUniqueId());
|
||||
}
|
||||
|
||||
void
|
||||
ServerGameThread::SendError(SOCKET s, int errorCode)
|
||||
ServerGameThread::SessionError(SessionWrapper session, int errorCode)
|
||||
{
|
||||
boost::shared_ptr<NetPacket> packet(new NetPacketError);
|
||||
NetPacketError::Data errorData;
|
||||
errorData.errorCode = errorCode;
|
||||
static_cast<NetPacketError *>(packet.get())->SetData(errorData);
|
||||
GetSender().Send(s, packet);
|
||||
assert(session.sessionData.get());
|
||||
RemoveSession(session);
|
||||
GetLobbyThread().SessionError(session, errorCode);
|
||||
}
|
||||
|
||||
void
|
||||
ServerGameThread::RejectSession(SessionWrapper session)
|
||||
ServerGameThread::MoveSessionToLobby(SessionWrapper session, int reason)
|
||||
{
|
||||
// TODO
|
||||
RemoveSession(session);
|
||||
GetLobbyThread().ReAddSession(session, reason);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -80,6 +80,19 @@ ServerLobbyThread::AddConnection(boost::shared_ptr<ConnectData> data)
|
||||
m_connectQueue.push_back(data);
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::ReAddSession(SessionWrapper session, int reason)
|
||||
{
|
||||
boost::shared_ptr<NetPacket> packet(new NetPacketRemovedFromGame);
|
||||
NetPacketRemovedFromGame::Data removedData;
|
||||
removedData.removeReason = reason;
|
||||
static_cast<NetPacketRemovedFromGame *>(packet.get())->SetData(removedData);
|
||||
GetSender().Send(session.sessionData->GetSocket(), packet);
|
||||
|
||||
boost::mutex::scoped_lock lock(m_sessionQueueMutex);
|
||||
m_sessionQueue.push_back(session);
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::CloseSessionDelayed(SessionWrapper session)
|
||||
{
|
||||
@@ -160,6 +173,20 @@ ServerLobbyThread::Main()
|
||||
if (tmpData.get())
|
||||
HandleNewConnection(tmpData);
|
||||
}
|
||||
{
|
||||
// Handle one incoming session at a time.
|
||||
SessionWrapper tmpSession;
|
||||
{
|
||||
boost::mutex::scoped_lock lock(m_sessionQueueMutex);
|
||||
if (!m_sessionQueue.empty())
|
||||
{
|
||||
tmpSession = m_sessionQueue.front();
|
||||
m_sessionQueue.pop_front();
|
||||
}
|
||||
}
|
||||
if (tmpSession.sessionData.get() && tmpSession.playerData.get())
|
||||
HandleNewSession(tmpSession);
|
||||
}
|
||||
// Process loop.
|
||||
ProcessLoop();
|
||||
// Close sessions.
|
||||
@@ -197,7 +224,7 @@ ServerLobbyThread::ProcessLoop()
|
||||
} catch (const NetException &)
|
||||
{
|
||||
// On error: Close this session.
|
||||
CloseSessionDelayed(session);
|
||||
m_sessionManager.RemoveSession(session.sessionData->GetSocket());
|
||||
return;
|
||||
}
|
||||
if (packet.get())
|
||||
@@ -279,13 +306,7 @@ ServerLobbyThread::HandleNetPacketInit(SessionWrapper session, const NetPacketIn
|
||||
GetSender().Send(session.sessionData->GetSocket(), initAck);
|
||||
|
||||
// Send the game list to the client.
|
||||
GameMap::const_iterator game_i = m_gameMap.begin();
|
||||
GameMap::const_iterator game_end = m_gameMap.end();
|
||||
while (game_i != game_end)
|
||||
{
|
||||
GetSender().Send(session.sessionData->GetSocket(), CreateNetPacketGameListNew(*game_i->second));
|
||||
++game_i;
|
||||
}
|
||||
SendGameList(session.sessionData->GetSocket());
|
||||
|
||||
// Set player data for session.
|
||||
m_sessionManager.SetSessionPlayerData(session.sessionData->GetSocket(), tmpPlayerData);
|
||||
@@ -378,7 +399,7 @@ ServerLobbyThread::HandleNetPacketJoinGame(SessionWrapper session, const NetPack
|
||||
}
|
||||
else
|
||||
{
|
||||
SessionError(session, ERR_NET_INVALID_PASSWORD);
|
||||
SendJoinGameFailed(session.sessionData->GetSocket(), NTF_NET_JOIN_INVALID_PASSWORD);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -485,6 +506,35 @@ ServerLobbyThread::HandleNewConnection(boost::shared_ptr<ConnectData> connData)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::HandleNewSession(SessionWrapper session)
|
||||
{
|
||||
if (m_sessionManager.GetRawSessionCount() <= SERVER_MAX_NUM_SESSIONS)
|
||||
{
|
||||
// This session has been temporarily stored - check if no
|
||||
// one else got the player name during that time.
|
||||
if (!m_sessionManager.IsPlayerConnected(session.playerData->GetName()))
|
||||
{
|
||||
// Send the list of games.
|
||||
SendGameList(session.sessionData->GetSocket());
|
||||
// Set state (back) to established.
|
||||
session.sessionData->SetState(SessionData::Established);
|
||||
// Add session to lobby list.
|
||||
m_sessionManager.AddSession(session);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Gracefully close this session.
|
||||
SessionError(session, ERR_NET_PLAYER_NAME_IN_USE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Gracefully close this session.
|
||||
SessionError(session, ERR_NET_SERVER_FULL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::CleanupConnectQueue()
|
||||
{
|
||||
@@ -514,6 +564,28 @@ ServerLobbyThread::SendError(SOCKET s, int errorCode)
|
||||
GetSender().Send(s, packet);
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::SendJoinGameFailed(SOCKET s, int reason)
|
||||
{
|
||||
boost::shared_ptr<NetPacket> packet(new NetPacketJoinGameFailed);
|
||||
NetPacketJoinGameFailed::Data failedData;
|
||||
failedData.failureCode = reason;
|
||||
static_cast<NetPacketJoinGameFailed *>(packet.get())->SetData(failedData);
|
||||
GetSender().Send(s, packet);
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::SendGameList(SOCKET s)
|
||||
{
|
||||
GameMap::const_iterator game_i = m_gameMap.begin();
|
||||
GameMap::const_iterator game_end = m_gameMap.end();
|
||||
while (game_i != game_end)
|
||||
{
|
||||
GetSender().Send(s, CreateNetPacketGameListNew(*game_i->second));
|
||||
++game_i;
|
||||
}
|
||||
}
|
||||
|
||||
ServerCallback &
|
||||
ServerLobbyThread::GetCallback()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user