From 95e5ee47cc583c7a95721207cfbf3ec2b998d910 Mon Sep 17 00:00:00 2001 From: lotodore Date: Mon, 20 Aug 2007 22:55:39 +0000 Subject: [PATCH] Fixed multithreading issues when creating/joining a game. Sessions are now queued. --- docs/net_protocol.txt | 71 +++++++------- src/net/common/netpacket.cpp | 132 +++++++-------------------- src/net/common/servergamestate.cpp | 43 +++++---- src/net/common/servergamethread.cpp | 21 ++++- src/net/common/serverlobbythread.cpp | 38 ++------ src/net/netpacket.h | 27 +----- src/net/servergamestate.h | 8 +- src/net/servergamethread.h | 9 +- 8 files changed, 130 insertions(+), 219 deletions(-) diff --git a/docs/net_protocol.txt b/docs/net_protocol.txt index b4fe26c0..c925ff30 100644 --- a/docs/net_protocol.txt +++ b/docs/net_protocol.txt @@ -1,4 +1,5 @@ Changelog: +08-20-2007: Create Game is answered by Join Game Ack. 08-14-2007: Supporting multiple games per server. Player id is now 32 bit to avoid collisions. 08-02-2007: Added new requests for game start and kick player. @@ -140,26 +141,12 @@ Client Request: Create Game | +-------------------------------+ / | padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +(answer will be join game ack) Proposed GUI Speed: 1-11 Player Action Timeout: # seconds -Player Flags: - 0x01 set: Player is human - 0x02 set: Player is admin for this game - - -Server Reply: Create Game Ack - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 6 | Message Length = 8 | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Game ID | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -(also implies that the client successfully joined the game) Client Request: Join Game @@ -167,7 +154,7 @@ Client Request: Join Game 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 7 | Message Length | + | Message Type = 6 | Message Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Game ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -185,13 +172,15 @@ Server Reply: Join Game Ack 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 8 | Message Length = 20 | + | Message Type = 7 | Message Length = 24 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Max Number of Players | Small Blind | + | Game ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Hands before raise | Proposed GUI Speed | + | Player Rights | Max Number of Players | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Player Action Timeout | Reserved | + | Small Blind | Hands before raise | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Proposed GUI Speed | Player Action Timeout | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Start Money | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -201,17 +190,23 @@ Server Notification: Player Joined 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 9 | Message Length | + | Message Type = 8 | Message Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Player ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Player Flags | Player Name Length | + | Player Flags | Player Rights | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Player Name Length | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | \ \ Player Name (UTF-8) / | +-------------------------------+ / | padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +Player Flags: + 0x01 set: Player is human +Player Rights: + 0x01 set: Player is admin for this game Server Notification: Player Left @@ -219,7 +214,7 @@ Server Notification: Player Left 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 10 | Message Length = 8 | + | Message Type = 9 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Player ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -230,7 +225,7 @@ Client Request: Kick Player 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 11 | Message Length = 8 | + | Message Type = 10 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Player ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -241,7 +236,7 @@ Client Request: Start Event 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 12 | Message Length = 4 | + | Message Type = 11 | Message Length = 4 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -250,7 +245,7 @@ Server Notification: Game Start 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 13 | Message Length | + | Message Type = 12 | Message Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Start Dealer Player Id | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -281,7 +276,7 @@ Server Notification: Hand Start 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 14 | Message Length = 8 | + | Message Type = 13 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Your 1st Card | Your 2nd Card | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -295,7 +290,7 @@ Server Request/Notification: Player's Turn 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 15 | Message Length = 8 | + | Message Type = 14 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Player ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -314,7 +309,7 @@ Client Reply/Request: Player's Action 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 16 | Message Length = 12 | + | Message Type = 15 | Message Length = 12 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Game State | Player Action | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -339,7 +334,7 @@ Server Notification: Player's Action Done 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 17 | Message Length = 20 | + | Message Type = 16 | Message Length = 20 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Player ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -360,7 +355,7 @@ Server Reply: Player's Action Rejected 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 18 | Message Length = 16 | + | Message Type = 17 | Message Length = 16 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Game State | Player Action | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -388,7 +383,7 @@ Server Notification: Deal Flop Cards 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 19 | Message Length = 12 | + | Message Type = 18 | Message Length = 12 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Flop 1st Card | Flop 2nd Card | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -401,7 +396,7 @@ Server Notification: Deal Turn Card 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 20 | Message Length = 8 | + | Message Type = 19 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Turn Card | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -412,7 +407,7 @@ Server Notification: Deal River Card 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 21 | Message Length = 8 | + | Message Type = 20 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | River Card | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -423,7 +418,7 @@ Server Notification: All In Show Cards 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 22 | Message Length | + | Message Type = 21 | Message Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Number Of PlayerCards Records | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -445,7 +440,7 @@ Server Notification: End Of Hand Show Cards 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 23 | Message Length | + | Message Type = 22 | Message Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Number Of PlayerResult Records | Reserved | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -479,7 +474,7 @@ Server Notification: End Of Hand Hide Cards 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 24 | Message Length = 16 | + | Message Type = 23 | Message Length = 16 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Player ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -494,7 +489,7 @@ Server Notification: End Of Game 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Message Type = 25 | Message Length = 8 | + | Message Type = 24 | Message Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Winner Player Id | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ diff --git a/src/net/common/netpacket.cpp b/src/net/common/netpacket.cpp index 4e7e2c77..53d1fd10 100644 --- a/src/net/common/netpacket.cpp +++ b/src/net/common/netpacket.cpp @@ -32,26 +32,25 @@ using namespace std; #define NET_TYPE_GAME_LIST_NEW 0x0003 #define NET_TYPE_GAME_LIST_UPDATE 0x0004 #define NET_TYPE_CREATE_GAME 0x0005 -#define NET_TYPE_CREATE_GAME_ACK 0x0006 -#define NET_TYPE_JOIN_GAME 0x0007 -#define NET_TYPE_JOIN_GAME_ACK 0x0008 -#define NET_TYPE_PLAYER_JOINED 0x0009 -#define NET_TYPE_PLAYER_LEFT 0x000A -#define NET_TYPE_KICK_PLAYER 0x000B -#define NET_TYPE_START_EVENT 0x000C -#define NET_TYPE_GAME_START 0x000D -#define NET_TYPE_HAND_START 0x000E -#define NET_TYPE_PLAYERS_TURN 0x000F -#define NET_TYPE_PLAYERS_ACTION 0x0010 -#define NET_TYPE_PLAYERS_ACTION_DONE 0x0011 -#define NET_TYPE_PLAYERS_ACTION_REJECTED 0x0012 -#define NET_TYPE_DEAL_FLOP_CARDS 0x0013 -#define NET_TYPE_DEAL_TURN_CARD 0x0014 -#define NET_TYPE_DEAL_RIVER_CARD 0x0015 -#define NET_TYPE_ALL_IN_SHOW_CARDS 0x0016 -#define NET_TYPE_END_OF_HAND_SHOW_CARDS 0x0017 -#define NET_TYPE_END_OF_HAND_HIDE_CARDS 0x0018 -#define NET_TYPE_END_OF_GAME 0x0019 +#define NET_TYPE_JOIN_GAME 0x0006 +#define NET_TYPE_JOIN_GAME_ACK 0x0007 +#define NET_TYPE_PLAYER_JOINED 0x0008 +#define NET_TYPE_PLAYER_LEFT 0x0009 +#define NET_TYPE_KICK_PLAYER 0x000A +#define NET_TYPE_START_EVENT 0x000B +#define NET_TYPE_GAME_START 0x000C +#define NET_TYPE_HAND_START 0x000D +#define NET_TYPE_PLAYERS_TURN 0x000E +#define NET_TYPE_PLAYERS_ACTION 0x000F +#define NET_TYPE_PLAYERS_ACTION_DONE 0x0010 +#define NET_TYPE_PLAYERS_ACTION_REJECTED 0x0011 +#define NET_TYPE_DEAL_FLOP_CARDS 0x0012 +#define NET_TYPE_DEAL_TURN_CARD 0x0013 +#define NET_TYPE_DEAL_RIVER_CARD 0x0014 +#define NET_TYPE_ALL_IN_SHOW_CARDS 0x0015 +#define NET_TYPE_END_OF_HAND_SHOW_CARDS 0x0016 +#define NET_TYPE_END_OF_HAND_HIDE_CARDS 0x0017 +#define NET_TYPE_END_OF_GAME 0x0018 #define NET_TYPE_SEND_CHAT_TEXT 0x0200 #define NET_TYPE_CHAT_TEXT 0x0201 @@ -133,12 +132,6 @@ struct GCC_PACKED NetPacketCreateGameData u_int32_t startMoney; }; -struct GCC_PACKED NetPacketCreateGameAckData -{ - NetPacketHeader head; - u_int32_t gameId; -}; - struct GCC_PACKED NetPacketJoinGameData { NetPacketHeader head; @@ -150,12 +143,13 @@ struct GCC_PACKED NetPacketJoinGameData struct GCC_PACKED NetPacketJoinGameAckData { NetPacketHeader head; + u_int32_t gameId; + u_int16_t playerRights; u_int16_t maxNumberOfPlayers; u_int16_t smallBlind; u_int16_t handsBeforeRaise; u_int16_t proposedGuiSpeed; u_int16_t playerActionTimeout; - u_int16_t reserved; u_int32_t startMoney; }; @@ -164,7 +158,9 @@ struct GCC_PACKED NetPacketPlayerJoinedData NetPacketHeader head; u_int32_t playerId; u_int16_t playerFlags; + u_int16_t playerRights; u_int16_t playerNameLength; + u_int16_t reserved; }; struct GCC_PACKED NetPacketPlayerLeftData @@ -384,9 +380,6 @@ NetPacket::Create(char *data, unsigned &dataSize) case NET_TYPE_CREATE_GAME: tmpPacket = boost::shared_ptr(new NetPacketCreateGame); break; - case NET_TYPE_CREATE_GAME_ACK: - tmpPacket = boost::shared_ptr(new NetPacketCreateGameAck); - break; case NET_TYPE_JOIN_GAME: tmpPacket = boost::shared_ptr(new NetPacketJoinGame); break; @@ -567,12 +560,6 @@ NetPacket::ToNetPacketCreateGame() const return NULL; } -const NetPacketCreateGameAck * -NetPacket::ToNetPacketCreateGameAck() const -{ - return NULL; -} - const NetPacketJoinGame * NetPacket::ToNetPacketJoinGame() const { @@ -1212,62 +1199,6 @@ NetPacketCreateGame::InternalCheck(const NetPacketHeader* data) const //----------------------------------------------------------------------------- -NetPacketCreateGameAck::NetPacketCreateGameAck() -: NetPacket(NET_TYPE_CREATE_GAME_ACK, sizeof(NetPacketCreateGameAckData), sizeof(NetPacketCreateGameAckData)) -{ -} - -NetPacketCreateGameAck::~NetPacketCreateGameAck() -{ -} - -boost::shared_ptr -NetPacketCreateGameAck::Clone() const -{ - boost::shared_ptr newPacket(new NetPacketCreateGameAck); - try - { - newPacket->SetRawData(GetRawData()); - } catch (const NetException &) - { - // Need to return the new packet anyway. - } - return newPacket; -} - -void -NetPacketCreateGameAck::SetData(const NetPacketCreateGameAck::Data &inData) -{ - NetPacketCreateGameAckData *tmpData = (NetPacketCreateGameAckData *)GetRawData(); - - tmpData->gameId = htonl(inData.gameId); - - // Check the packet - just in case. - Check(GetRawData()); -} - -void -NetPacketCreateGameAck::GetData(NetPacketCreateGameAck::Data &outData) const -{ - NetPacketCreateGameAckData *tmpData = (NetPacketCreateGameAckData *)GetRawData(); - - outData.gameId = ntohl(tmpData->gameId); -} - -const NetPacketCreateGameAck * -NetPacketCreateGameAck::ToNetPacketCreateGameAck() const -{ - return this; -} - -void -NetPacketCreateGameAck::InternalCheck(const NetPacketHeader* data) const -{ - // Nothing to do. -} - -//----------------------------------------------------------------------------- - NetPacketJoinGame::NetPacketJoinGame() : NetPacket(NET_TYPE_JOIN_GAME, sizeof(NetPacketJoinGameData), MAX_PACKET_SIZE) { @@ -1388,6 +1319,8 @@ NetPacketJoinGameAck::SetData(const NetPacketJoinGameAck::Data &inData) NetPacketJoinGameAckData *tmpData = (NetPacketJoinGameAckData *)GetRawData(); // Set the data. + tmpData->gameId = htonl(inData.gameId); + tmpData->playerRights = htons(inData.prights); tmpData->maxNumberOfPlayers = htons(inData.gameData.maxNumberOfPlayers); tmpData->smallBlind = htons(inData.gameData.smallBlind); tmpData->handsBeforeRaise = htons(inData.gameData.handsBeforeRaise); @@ -1405,6 +1338,8 @@ NetPacketJoinGameAck::GetData(NetPacketJoinGameAck::Data &outData) const // We assume that the data is valid. Validity has already been checked. NetPacketJoinGameAckData *tmpData = (NetPacketJoinGameAckData *)GetRawData(); + outData.gameId = ntohl(tmpData->gameId); + outData.prights = static_cast(ntohs(tmpData->playerRights)); outData.gameData.maxNumberOfPlayers = ntohs(tmpData->maxNumberOfPlayers); outData.gameData.smallBlind = ntohs(tmpData->smallBlind); outData.gameData.handsBeforeRaise = ntohs(tmpData->handsBeforeRaise); @@ -1478,15 +1413,10 @@ NetPacketPlayerJoined::SetData(const NetPacketPlayerJoined::Data &inData) NetPacketPlayerJoinedData *tmpData = (NetPacketPlayerJoinedData *)GetRawData(); - u_int16_t tmpPlayerFlags = 0; - if (inData.ptype == PLAYER_TYPE_HUMAN) - tmpPlayerFlags |= NET_PLAYER_FLAG_HUMAN; - if (inData.prights == PLAYER_RIGHTS_ADMIN) - tmpPlayerFlags |= NET_PLAYER_FLAG_ADMIN; - // Set the data. tmpData->playerId = htonl(inData.playerId); - tmpData->playerFlags = htons(tmpPlayerFlags); + tmpData->playerFlags = htons(inData.ptype); + tmpData->playerRights = htons(inData.prights); tmpData->playerNameLength = htons(playerNameLen); char *namePtr = (char *)tmpData + sizeof(NetPacketPlayerJoinedData); memcpy(namePtr, inData.playerName.c_str(), playerNameLen); @@ -1502,8 +1432,8 @@ NetPacketPlayerJoined::GetData(NetPacketPlayerJoined::Data &outData) const NetPacketPlayerJoinedData *tmpData = (NetPacketPlayerJoinedData *)GetRawData(); outData.playerId = ntohl(tmpData->playerId); - outData.ptype = (ntohs(tmpData->playerFlags) & NET_PLAYER_FLAG_HUMAN) ? PLAYER_TYPE_HUMAN : PLAYER_TYPE_COMPUTER; - outData.prights = (ntohs(tmpData->playerFlags) & NET_PLAYER_FLAG_ADMIN) ? PLAYER_RIGHTS_ADMIN : PLAYER_RIGHTS_NORMAL; + outData.ptype = static_cast(ntohs(tmpData->playerFlags)); + outData.prights = static_cast(ntohs(tmpData->playerRights)); char *namePtr = (char *)tmpData + sizeof(NetPacketPlayerJoinedData); outData.playerName = string(namePtr, ntohs(tmpData->playerNameLength)); } diff --git a/src/net/common/servergamestate.cpp b/src/net/common/servergamestate.cpp index c58ef872..9d46be33 100644 --- a/src/net/common/servergamestate.cpp +++ b/src/net/common/servergamestate.cpp @@ -215,10 +215,9 @@ ServerGameStateInit::~ServerGameStateInit() { } -bool +void ServerGameStateInit::HandleNewSession(ServerGameThread &server, SessionWrapper session) { - bool retVal = false; if (session.sessionData.get() && session.playerData.get()) { size_t curNumPlayers = server.GetCurNumberOfPlayers(); @@ -235,29 +234,35 @@ ServerGameStateInit::HandleNewSession(ServerGameThread &server, SessionWrapper s // First player is admin. session.playerData->SetRights(PLAYER_RIGHTS_ADMIN); } - else - { - // Send notifications for connected players to client. - PlayerDataList tmpPlayerList = server.GetSessionManager().GetPlayerDataList(); - PlayerDataList::iterator player_i = tmpPlayerList.begin(); - PlayerDataList::iterator player_end = tmpPlayerList.end(); - while (player_i != player_end) - { - server.GetSender().Send(session.sessionData->GetSocket(), CreateNetPacketPlayerJoined(*(*player_i))); - ++player_i; - } - // Send "Player Joined" to other fully connected clients. - server.SendToAllPlayers(CreateNetPacketPlayerJoined(*session.playerData)); + // Send ack to client. + boost::shared_ptr joinGameAck(new NetPacketJoinGameAck); + NetPacketJoinGameAck::Data joinGameAckData; + joinGameAckData.gameId = server.GetId(); + joinGameAckData.prights = session.playerData->GetRights(); + joinGameAckData.gameData = server.GetGameData(); + static_cast(joinGameAck.get())->SetData(joinGameAckData); + server.GetSender().Send(session.sessionData->GetSocket(), joinGameAck); + + // Send notifications for connected players to client. + PlayerDataList tmpPlayerList = server.GetSessionManager().GetPlayerDataList(); + PlayerDataList::iterator player_i = tmpPlayerList.begin(); + PlayerDataList::iterator player_end = tmpPlayerList.end(); + while (player_i != player_end) + { + server.GetSender().Send(session.sessionData->GetSocket(), CreateNetPacketPlayerJoined(*(*player_i))); + ++player_i; } + + // Send "Player Joined" to other fully connected clients. + server.SendToAllPlayers(CreateNetPacketPlayerJoined(*session.playerData)); + // Session is now in game state. session.sessionData->SetState(SessionData::Game); // Accept session. server.GetSessionManager().AddSession(session); - retVal = true; } } - return retVal; } int @@ -324,11 +329,11 @@ AbstractServerGameStateRunning::~AbstractServerGameStateRunning() { } -bool +void AbstractServerGameStateRunning::HandleNewSession(ServerGameThread &server, SessionWrapper session) { // Do not accept new sessions in this state. - return false; + // TODO } //----------------------------------------------------------------------------- diff --git a/src/net/common/servergamethread.cpp b/src/net/common/servergamethread.cpp index 702830ff..3dc3c959 100644 --- a/src/net/common/servergamethread.cpp +++ b/src/net/common/servergamethread.cpp @@ -56,7 +56,6 @@ ServerGameThread::ServerGameThread(ServerLobbyThread &lobbyThread, u_int32_t id, m_senderCallback.reset(new ServerSenderCallback(*this)); m_sender.reset(new SenderThread(GetSenderCallback())); m_receiver.reset(new ReceiverHelper); - SetState(SERVER_INITIAL_STATE::Instance()); } ServerGameThread::~ServerGameThread() @@ -82,10 +81,12 @@ ServerGameThread::GetName() const return m_name; } -bool +void ServerGameThread::AddSession(SessionWrapper session) { - return GetState().HandleNewSession(*this, session); + // Must be thread safe. + boost::mutex::scoped_lock lock(m_sessionQueueMutex); + m_sessionQueue.push_back(session); } GameState @@ -110,6 +111,20 @@ ServerGameThread::Main() { while (!ShouldTerminate()) { + { + // Handle one new 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()) + GetState().HandleNewSession(*this, tmpSession); + } // Process current state. GetState().Process(*this); } diff --git a/src/net/common/serverlobbythread.cpp b/src/net/common/serverlobbythread.cpp index eb23d461..eed16fda 100644 --- a/src/net/common/serverlobbythread.cpp +++ b/src/net/common/serverlobbythread.cpp @@ -265,25 +265,16 @@ ServerLobbyThread::HandleNetPacketCreateGame(SessionWrapper session, const NetPa new ServerGameThread(*this, GetNextGameId(), createGameData.gameName, GetGui(), m_playerConfig)); game->Init(createGameData.password, createGameData.gameData); + // Remove session from the lobby. + m_sessionManager.RemoveSession(session.sessionData->GetSocket()); // Add session to the game. - if (game->AddSession(session)) - { - // Remove session from the lobby. - m_sessionManager.RemoveSession(session.sessionData->GetSocket()); + game->AddSession(session); - // Add game to list. - m_gameMap.insert(GameMap::value_type(game->GetId(), game)); + // Add game to list. + m_gameMap.insert(GameMap::value_type(game->GetId(), game)); - // Start the game. - game->Run(); - - // Send ack to client. - boost::shared_ptr createGameAck(new NetPacketCreateGameAck); - NetPacketCreateGameAck::Data createGameAckData; - createGameAckData.gameId = game->GetId(); - static_cast(createGameAck.get())->SetData(createGameAckData); - GetSender().Send(session.sessionData->GetSocket(), createGameAck); - } + // Start the game. + game->Run(); } void @@ -301,19 +292,10 @@ ServerLobbyThread::HandleNetPacketJoinGame(SessionWrapper session, const NetPack ServerGameThread &game = *pos->second; if (game.CheckPassword(joinGameData.password)) { + // Remove session from the lobby. + m_sessionManager.RemoveSession(session.sessionData->GetSocket()); // Add session to the game. - if (game.AddSession(session)) - { - // Remove session from the lobby. - m_sessionManager.RemoveSession(session.sessionData->GetSocket()); - - // Send ack to client. - boost::shared_ptr joinGameAck(new NetPacketJoinGameAck); - NetPacketJoinGameAck::Data joinGameAckData; - joinGameAckData.gameData = game.GetGameData(); - static_cast(joinGameAck.get())->SetData(joinGameAckData); - GetSender().Send(session.sessionData->GetSocket(), joinGameAck); - } + game.AddSession(session); } } } diff --git a/src/net/netpacket.h b/src/net/netpacket.h index 647d65c3..a2786059 100644 --- a/src/net/netpacket.h +++ b/src/net/netpacket.h @@ -45,7 +45,6 @@ class NetPacketInitAck; class NetPacketGameListNew; class NetPacketGameListUpdate; class NetPacketCreateGame; -class NetPacketCreateGameAck; class NetPacketJoinGame; class NetPacketJoinGameAck; class NetPacketPlayerJoined; @@ -91,7 +90,6 @@ public: virtual const NetPacketGameListNew *ToNetPacketGameListNew() const; virtual const NetPacketGameListUpdate *ToNetPacketGameListUpdate() const; virtual const NetPacketCreateGame *ToNetPacketCreateGame() const; - virtual const NetPacketCreateGameAck *ToNetPacketCreateGameAck() const; virtual const NetPacketJoinGame *ToNetPacketJoinGame() const; virtual const NetPacketJoinGameAck *ToNetPacketJoinGameAck() const; virtual const NetPacketPlayerJoined *ToNetPacketPlayerJoined() const; @@ -253,29 +251,6 @@ protected: virtual void InternalCheck(const NetPacketHeader* data) const; }; -class NetPacketCreateGameAck : public NetPacket -{ -public: - struct Data - { - u_int32_t gameId; - }; - - NetPacketCreateGameAck(); - virtual ~NetPacketCreateGameAck(); - - virtual boost::shared_ptr Clone() const; - - void SetData(const Data &inData); - void GetData(Data &outData) const; - - virtual const NetPacketCreateGameAck *ToNetPacketCreateGameAck() const; - -protected: - - virtual void InternalCheck(const NetPacketHeader* data) const; -}; - class NetPacketJoinGame : public NetPacket { public: @@ -305,7 +280,9 @@ class NetPacketJoinGameAck : public NetPacket public: struct Data { + u_int32_t gameId; GameData gameData; + PlayerRights prights; }; NetPacketJoinGameAck(); diff --git a/src/net/servergamestate.h b/src/net/servergamestate.h index 9af09362..23c7042d 100644 --- a/src/net/servergamestate.h +++ b/src/net/servergamestate.h @@ -46,8 +46,8 @@ public: // Initialize after switching to this state. virtual void Init() = 0; - // Handling of a new TCP connection. - virtual bool HandleNewSession(ServerGameThread &server, SessionWrapper session) = 0; + // Handling of a new session. + virtual void HandleNewSession(ServerGameThread &server, SessionWrapper session) = 0; // Main processing function of the current state. virtual int Process(ServerGameThread &server) = 0; @@ -95,7 +95,7 @@ public: virtual ~AbstractServerGameStateRunning(); // Reject new connections. - virtual bool HandleNewSession(ServerGameThread &server, SessionWrapper session); + virtual void HandleNewSession(ServerGameThread &server, SessionWrapper session); protected: @@ -113,7 +113,7 @@ public: virtual void Init() {} // - virtual bool HandleNewSession(ServerGameThread &server, SessionWrapper session); + virtual void HandleNewSession(ServerGameThread &server, SessionWrapper session); protected: diff --git a/src/net/servergamethread.h b/src/net/servergamethread.h index cafae817..8b6bb94a 100644 --- a/src/net/servergamethread.h +++ b/src/net/servergamethread.h @@ -25,6 +25,8 @@ #include #include +#include + #define GAME_THREAD_TERMINATE_TIMEOUT 200 @@ -48,7 +50,7 @@ public: u_int32_t GetId() const; const std::string &GetName() const; - bool AddSession(SessionWrapper session); + void AddSession(SessionWrapper session); ServerCallback &GetCallback(); GameState GetCurRound() const; @@ -60,6 +62,8 @@ public: protected: + typedef std::deque SessionQueue; + // Main function of the thread. virtual void Main(); @@ -101,6 +105,9 @@ protected: private: + SessionQueue m_sessionQueue; + mutable boost::mutex m_sessionQueueMutex; + SessionManager m_sessionManager; PlayerDataList m_computerPlayers;